user3821562
user3821562

Reputation: 41

Why using two flip-flops instead of one in this Verilog HDL code?

This code is a button debouncer. But I can't understand why there are two flips flops :

reg PB_sync_0;  always @(posedge clk) PB_sync_0 <= ~PB;  // invert PB to make PB_sync_0 active high
reg PB_sync_1;  always @(posedge clk) PB_sync_1 <= PB_sync_0;

Why the autor of this code did not write this ?

reg PB_sync_1;  always @(posedge clk) PB_sync_1 <= ~PB;

Here is the full code:

module PushButton_Debouncer(
    input clk,
    input PB,  // "PB" is the glitchy, asynchronous to clk, active low push-button signal

    // from which we make three outputs, all synchronous to the clock
    output reg PB_state,  // 1 as long as the push-button is active (down)
    output PB_down,  // 1 for one clock cycle when the push-button goes down (i.e. just pushed)
    output PB_up   // 1 for one clock cycle when the push-button goes up (i.e. just released)
);

// First use two flip-flops to synchronize the PB signal the "clk" clock domain
reg PB_sync_0;  always @(posedge clk) PB_sync_0 <= ~PB;  // invert PB to make PB_sync_0 active high
reg PB_sync_1;  always @(posedge clk) PB_sync_1 <= PB_sync_0;

// Next declare a 16-bits counter
reg [15:0] PB_cnt;

// When the push-button is pushed or released, we increment the counter
// The counter has to be maxed out before we decide that the push-button state has changed

wire PB_idle = (PB_state==PB_sync_1);
wire PB_cnt_max = &PB_cnt;  // true when all bits of PB_cnt are 1's

always @(posedge clk)
if(PB_idle)
    PB_cnt <= 0;  // nothing's going on
else
begin
    PB_cnt <= PB_cnt + 16'd1;  // something's going on, increment the counter
    if(PB_cnt_max) PB_state <= ~PB_state;  // if the counter is maxed out, PB changed!
end

assign PB_down = ~PB_idle & PB_cnt_max & ~PB_state;
assign PB_up   = ~PB_idle & PB_cnt_max &  PB_state;
endmodule

Thanks !

Upvotes: 4

Views: 3852

Answers (1)

Razko
Razko

Reputation: 581

The autor of this code uses 2 flip-flops in order to synchronize PB signal into clk domain. As he mentioned in a comment "PB" is the glitchy, asynchronous to clk. Not synchronizing a signal on a clock domain transition may cause metastability in the system, as toolic referenced en.wikipedia.org/wiki/Metastability_in_electronics

Upvotes: 1

Related Questions