/****
 * low_freq_clock_gen.sv - Generates different clock frequencies to drive
 *                         different state machines and different parts of
 *                         the design. 
 *
 * @author: Waylon Cude, Dilanthi Prentice
 * @date: 6/12/2025
 * */
//Define used because verilator needs it but vivado is samrt enough not to
`ifdef VERILATOR
    `include "sdvd_defs.sv"
`endif
import sdvd_defs::SPEED;
// Takes in a 100MHz clock and generates the very low freq signals needed
// for driving the control logic
module low_freq_clock_gen(
    input logic clk, reset,
    input SPEED speed,
    output logic clk1k, clk10h, seconds_pulse
);

// Hardcoded to be 1,000,000/4,000 (25,000)
// Relying on constant maths makes it the wrong size
localparam num_cycles = 25_000;

logic [$clog2(num_cycles):0] counter;
logic [$clog2(4000):0] seconds_counter;
logic [$clog2(4000):0] clock_divider_counter;


always_ff @(posedge clk) begin
    if (reset) begin
        counter <= num_cycles;
        clk1k <= 0;
        clk10h <= 0;
        seconds_pulse <= 0;
        seconds_counter <= 0;
        clock_divider_counter <= 0;
    end
    // At 4khz increment the seconds counter and output clocks
    else if (counter == 0) begin
        counter <= num_cycles;
        seconds_counter <= seconds_counter + {9'b0, speed};
        clock_divider_counter <= clock_divider_counter + 1;
        if (seconds_counter >= 4000) begin
            seconds_counter <= seconds_counter-4000;
            // Should we flop it or pulse at 100MHz?
            seconds_pulse <= 1;
        end
        else
            seconds_pulse <= 0;

        if (clock_divider_counter == 4000)
            clock_divider_counter <= 0;

        // Generate output clocks
        if (clock_divider_counter % 4 == 0)
            clk1k <= ~clk1k;
        if (clock_divider_counter % 400 == 0)
            clk10h <= ~clk10h;
        end
    else
        counter <= counter - 1;

end
    
endmodule
