4

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 !

user3821562
  • 41
  • 1
  • 3
  • 3
    See the last picture here: http://www.asic-world.com/tidbits/metastablity.html – Ari Jul 09 '14 at 17:48
  • 2
    This also explains it. http://www.sunburst-design.com/papers/CummingsSNUG2008Boston_CDC.pdf – Greg Jul 09 '14 at 17:51
  • The debouncer does two things: 1) Synchronize the external asynchronous input to the internal clock, and 2) Remove the bounce from an physical button. The synchronization is handled with the double flip-flops, where you can find detailed descriptions through links in the other comments. – Morten Zilmer Jul 09 '14 at 18:04
  • As this question is mainly about electronics (debouncing) it should probably be moved to [ElectronicsSE](http://electronics.stackexchange.com/) although likely is a duplicate. Verilog question are welcomed on stackoverflow but should be about writing verilog not hardware requirements. – Morgan Jul 09 '14 at 19:13
  • The comments in the code should already answer that question. "// First use two flip-flops to synchronize the PB signal the "clk" clock domain" ... – andrsmllr Jul 11 '14 at 09:02
  • 1
    This is NOT about debouncing, it is about metastability. – Will Jul 15 '14 at 11:17

1 Answers1

1

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

Razko
  • 551
  • 2
  • 7