SDVD/design/low_freq_clock_gen.sv
Waylon Cude 927437e12c
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
Fixup to get main demo working
This adds some unnecessary stuff into the debug core  that I used to
troubleshoot. There are like 5 bugfixes here. Especially of note is the
low freq clock gen, I was trying to use modulo like you would do in a
computer program but it was too slow, so I had to move the logic around
a bunch.
2025-05-26 22:52:14 -07:00

57 lines
1.5 KiB
Systemverilog

`include "sdvd_defs.sv"
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
// 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