diff options
| author | Jan Tuomi <jan@jantuomi.fi> | 2025-03-18 18:38:44 +0200 |
|---|---|---|
| committer | Jan Tuomi <jan@jantuomi.fi> | 2025-03-18 18:38:44 +0200 |
| commit | 69de37cdb25563f6cbd2a3c1a338b1e0dd47b3a4 (patch) | |
| tree | c1895044fd0051f919a989460be3ac39a6ab09b8 /atk16_fpga/foo.v | |
| parent | 06e8b8dbadf769507abf5368caee253ded139adc (diff) | |
Start reworking fpga impl
Diffstat (limited to 'atk16_fpga/foo.v')
| -rw-r--r-- | atk16_fpga/foo.v | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/atk16_fpga/foo.v b/atk16_fpga/foo.v new file mode 100644 index 0000000..f6ff33c --- /dev/null +++ b/atk16_fpga/foo.v @@ -0,0 +1,106 @@ +// Top-level module +module foo ( + LED1, + LED2, + BUT1, + BUT2, + SYSCLK +); + output LED1; + output LED2; + input BUT1; + input BUT2; + input SYSCLK; + + // 2-bit counter register + reg [1:0] val; + initial val = 2'b00; + + // Wires for debounced button signals + wire db_but1; + wire db_but2; + + // Instantiate debounce modules for each button. + // Adjust the DEBOUNCE_LIMIT parameter as needed based on SYSCLK frequency. + debounce #( + .DEBOUNCE_LIMIT(500000) + ) debounce_but1 ( + .clk(SYSCLK), + .button(BUT1), + .db_out(db_but1) + ); + + debounce #( + .DEBOUNCE_LIMIT(500000) + ) debounce_but2 ( + .clk(SYSCLK), + .button(BUT2), + .db_out(db_but2) + ); + + // Edge detection registers to trigger a single count change per button press. + reg prev_db_but1; + reg prev_db_but2; + initial begin + prev_db_but1 = 1'b0; + prev_db_but2 = 1'b0; + end + + // Drive LEDs from the counter bits. + assign LED1 = val[0]; + assign LED2 = val[1]; + + // Synchronous logic to detect rising edges and update counter. + always @(posedge SYSCLK) begin + // If a rising edge is detected on db_but1, increment the counter. + if (db_but1 && !prev_db_but1) val <= val + 1; + // Else, if a rising edge is detected on db_but2, decrement the counter. + else if (db_but2 && !prev_db_but2) val <= val - 1; + + // Store the current debounced states for edge detection on the next clock. + prev_db_but1 <= db_but1; + prev_db_but2 <= db_but2; + end + +endmodule + +// Debounce module written in plain Verilog. +module debounce ( + clk, + button, + db_out +); + parameter DEBOUNCE_LIMIT = 500000; // Adjust as needed for your clock frequency. + input clk; + input button; + output db_out; + reg db_out; + + reg [31:0] counter; // Counter width chosen to comfortably count up to DEBOUNCE_LIMIT. + reg button_sync; + + initial begin + counter = 32'd0; + db_out = 1'b0; + button_sync = 1'b0; + end + + always @(posedge clk) begin + // First, synchronize the raw button input to the clock domain. + button_sync <= button; + + // If the synchronized value equals the debounced output, + // reset the counter. + if (button_sync == db_out) counter <= 32'd0; + else begin + // Otherwise, increment the counter. + counter <= counter + 1; + // If the counter reaches the limit, update the debounced output. + if (counter >= DEBOUNCE_LIMIT) begin + db_out <= button_sync; + counter <= 32'd0; + end + end + end + +endmodule |
