Skip to content

Instantly share code, notes, and snippets.

@wdevore
Created September 20, 2019 17:51
Show Gist options
  • Save wdevore/911b3b1c4e8e646b662d729b809a5f4d to your computer and use it in GitHub Desktop.
Save wdevore/911b3b1c4e8e646b662d729b809a5f4d to your computer and use it in GitHub Desktop.
Verilog Pulse FSM for debouncing. Use a .pcf for tinyFPGA-B2.
// FSM Event based debounce circuit - top.v
//
// The FSM should be reset prior to usage.
// "c" or clock should be around 100Hz = 10ms cycle or 5ms period.
//
// An excerpt from "FSB Based Digital Design Using Verilog" Chp 9.
//
// To see this verilog in action you will need at least 10 LEDs or a 10-bit
// bargraph and 2 switches.
// Your FPGA breakout board will need 12-14 pins available.
// --------------------------------------------------------------------------
// An async switch debouncer FSM
// --------------------------------------------------------------------------
module pulse_fsm (
input S, // Active High
input C,
input Reset,
output Pulse
);
wire A; // Event cell = ((/B & S & /C) | (A & /B) | (A & C)) & Reset
wire B; // Event cell = ((A & C) | (A & B) | (B & S)) & Reset
wire BNot;
wire CNot;
wire a1, a2, a3;
wire b1, b2, b3;
// Note: some toolchains will issue "logic loops" as warnings. There are
// 6 of them in this module.
not N1(BNot, B);
not N2(CNot, C);
and And1(a1, S, CNot, BNot, Reset);
and And2(a2, BNot, A, Reset);
and And3(a3, C, A, Reset);
or Or1(A, a1, a2, a3);
and And4(b1, A, C, Reset);
and And5(b2, A, B, Reset);
and And6(b3, B, S, Reset);
or Or2(B, b1, b2, b3);
// Output signal
and And7(Pulse, A, B);
endmodule
// --------------------------------------------------------------------------
// Main module
// --------------------------------------------------------------------------
module top (
output pin1_usb_dp,// USB pull-up enable, set low to disable
output pin2_usb_dn,
input pin3_clk_16mhz, // 16 MHz on-board clock
// pins 13-4 should be connected to 10 LEDs
output pin13,
output pin12,
output pin11,
output pin10,
output pin9,
output pin8,
output pin7,
output pin6,
output pin5,
output pin4,
input pin14_sdo, // Button input: Active High
input pin17_ss, // Reset button: Active Low
output pin15_sdi, // Control clock. Provided for visual inspection.
output pin16_sck // Pulse output used to drive FSM
);
reg [22:0] clk_1hz_counter = 23'b0; // Hz clock generation counter
reg clk_cyc = 1'b0; // Hz clock
reg[9:0] shift = 1; // 4 bit shift register that shifts at each button press
reg direction = 0; // Initial direction is from pin4 to pin7
reg[3:0] counter = 0;
// 100Hz gives a 10ms/5ms cycle/period
// 50Hz gives a 20ms/10ms cycle/period
// 25Hz gives a 40ms/20ms cycle/period
// 10Hz gives a 100ms/50ms cycle/period
localparam FREQUENCY = 23'd50;
// Debouncer for pin14 input button
pulse_fsm debounce(.S(pin14_sdo), .C(clk_cyc), .Reset(pin17_ss), .Pulse(pin16_sck));
// Clock divder and generator
always @(posedge pin3_clk_16mhz) begin
if (clk_1hz_counter < 23'd7_999_999)
clk_1hz_counter <= clk_1hz_counter + FREQUENCY;
else begin
clk_1hz_counter <= 23'b0;
clk_cyc <= ~clk_cyc;
end
end
// Ping/Pong effect, driven by pulse output of the debouncer FSM
always @(posedge pin16_sck) begin
if (counter == 9) begin
direction = ~direction;
counter = 0;
end
// Shift active LED
if (direction == 0) begin
shift <= shift << 1;
end
else begin
shift <= shift >> 1;
end
counter <= #1 counter + 1;
end
// Route to pins
assign
pin13 = shift[9],
pin12 = shift[8],
pin11 = shift[7],
pin10 = shift[6],
pin9 = shift[5],
pin8 = shift[4],
pin7 = shift[3],
pin6 = shift[2],
pin5 = shift[1],
pin4 = shift[0];
// Convenience for visual inspection.
assign pin15_sdi = clk_cyc;
assign
pin1_usb_dp = 1'b0,
pin2_usb_dn = 1'b0;
endmodule // top
@wdevore
Copy link
Author

wdevore commented Sep 20, 2019

Logic diagram

Pulse FSM

@wdevore
Copy link
Author

wdevore commented Sep 20, 2019

Test circuit
Pulse FSM

@wdevore
Copy link
Author

wdevore commented Sep 20, 2019

Video in action

fsm_debounce

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment