Fixup to get main demo working
ci/woodpecker/push/test-workflow Pipeline was successful

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.
This commit is contained in:
2025-05-26 22:52:14 -07:00
parent ec6ce08b21
commit 927437e12c
6 changed files with 505 additions and 394 deletions
+7
View File
@@ -0,0 +1,7 @@
//this interfaces with block ram
module audio_buffer(
input logic clk, reset,
);
+36 -25
View File
@@ -8,38 +8,49 @@ module low_freq_clock_gen(
output logic clk1k, clk10h, seconds_pulse
);
logic [$clog2(100_000_000):0] counter;
logic [$clog2(4000):0] seconds_counter;
logic clk4k;
// 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;
assign clk1k = (counter % (100_000_000/1000)) != 0;
assign clk10h = (counter % (100_000_000/10)) != 0;
assign clk4k = (counter % (100_000_000/4000)) != 0;
always_ff @(posedge clk) begin
// NOTE: This generates a pulse on the same clock cycle that reset is
// asserted. Is that bad??
if (reset)
counter <= 0;
// Roll the counter over back to zero every second
else if (counter == 99_999_999)
counter <= 0;
else
counter <= counter + 1;
// This logic handles the variable-speed seconds counter
if (reset) begin
counter <= num_cycles;
clk1k <= 0;
clk10h <= 0;
seconds_pulse <= 0;
seconds_counter <= 0;
clock_divider_counter <= 0;
end
else if (clk4k && seconds_counter >= 4000) begin
seconds_counter <= seconds_counter-4000;
seconds_pulse <= 1;
end
else if (clk4k) begin
seconds_pulse <= 0;
// At 4khz increment the seconds counter and output clocks
else if (counter == 0) begin
counter <= num_cycles;
seconds_counter <= seconds_counter + {9'b0, speed};
end
end
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
+8 -5
View File
@@ -3,7 +3,7 @@ import sdvd_defs::SPEED;
module nexys_a7_top(
input logic CLK100MHZ, CPU_RESETN,
input logic BTNC, BTNR,
output logic [7:0] CA,CB,CC,CD,CE,CF,CG,
output logic CA,CB,CC,CD,CE,CF,CG,
output logic [7:0] AN
);
@@ -18,9 +18,12 @@ SPEED speed;
// Map C{A-G} to an array of 7-segment displays
wire [6:0] segments [7:0];
for (genvar i = 0; i<8; i++) begin: segmentGenerate
assign {CG[i],CF[i],CE[i],CD[i],CC[i],CB[i],CA[i]} = segments[i];
end
wire [2:0] segment_mux_select;
// These segments are currently unused
assign segments[7] = 0;
assign segments[6] = 0;
assign {CA,CB,CC,CD,CE,CF,CG} = ~segments[segment_mux_select];
logic [$clog2(60)-1:0] seconds;
logic [$clog2(60)-1:0] minutes;
@@ -50,7 +53,7 @@ always_ff @(posedge seconds_pulse) begin
seconds <= seconds + 1;
end
display_anode_driver anodeDriver(clk_1khz,reset,AN);
display_anode_driver anodeDriver(clk_1khz,reset,AN,segment_mux_select);
seconds_display secondsSegment (seconds, segments[1], segments[0]);
seconds_display minutesSegment (minutes, segments[3], segments[2]);
+13 -4
View File
@@ -1,11 +1,20 @@
// NOTE: This expects to be driven with a 100khz clock
module display_anode_driver(input logic clk, input logic reset, output logic [7:0] AN);
module display_anode_driver(
input logic clk,
input logic reset,
output logic [7:0] AN,
output logic [2:0] mux_select);
// This is just a shift register that drives each anode individually
always_ff @(posedge clk) begin
if (reset)
AN <= 1;
else
if (reset) begin
AN <= '1 - 1;
mux_select <= 0;
end
else begin
AN <= {AN[6:0], AN[7]};
// Letting this overflow will automatically reset it
mux_select <= mux_select + 1;
end
end
endmodule