{"id":378,"date":"2015-02-06T08:35:37","date_gmt":"2015-02-06T16:35:37","guid":{"rendered":"http:\/\/www.beyond-circuits.com\/wordpress\/?page_id=378"},"modified":"2016-07-22T19:31:24","modified_gmt":"2016-07-23T03:31:24","slug":"tutorial9","status":"publish","type":"page","link":"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial9\/","title":{"rendered":"Tutorial 9: Measuring Button Bounce"},"content":{"rendered":"<p>Now that we have our top watch working, we&#8217;re all done, right?<\/p>\n<p>Not quite. Mechanical switches and buttons have a property called <em>bounce<\/em>. <em>Bounce<\/em>\u00a0means the switch won&#8217;t go cleanly from open to closed or vice versa. Instead, it\u00a0<em>bounces<\/em> between the two states for a little while. We just want to see a single rise or fall when the switch closes or opens.<a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/button_sch.png\"><img loading=\"lazy\" decoding=\"async\" class=\" size-medium wp-image-383 alignright\" src=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/button_sch-300x210.png\" alt=\"button_sch\" width=\"300\" height=\"210\" srcset=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/button_sch-300x210.png 300w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/button_sch.png 420w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>There are a number of ways to address the issue of switch bounce. These methods are referred to as <em>debouncing<\/em> the switch. In\u00a0ZedBoard, the designers placed 10K\u03a9 series resistors between the buttons\u00a0and the FPGA. This helps filter out some of the noise. However, is it\u00a0enough?<\/p>\n<p>Let&#8217;s construct a circuit which looks for pushbutton\u00a0bouncing on the ZedBoard.<\/p>\n<h1>Measuring Bounce<\/h1>\n<p>Here, we&#8217;re going to use the same module declaration and constraints as our previous tutorial. We&#8217;ll also use the logic to look for a rising edge on the pushbutton inputs, as well as adding signals to detect the falling edge as well. Then we&#8217;ll use the logic to drive the SSD output <em>ssd<\/em> and <em>ssdcat<\/em>. Here&#8217;s what I have for those parts of the design:<\/p>\n<pre><code>`timescale 1ns \/ 1ns\r\nmodule top\r\n  (\r\n   input clk,\r\n   input [7:0] switch,\r\n   input [4:0] btn,\r\n   output reg [7:0] led,\r\n   output reg [6:0] ssd,\r\n   output reg ssdcat\r\n   );\r\n\r\n  wire btnl = btn[0];\r\n  wire btnu = btn[1];\r\n  wire btnr = btn[2];\r\n  wire btnd = btn[3];\r\n  wire btnc = btn[4];\r\n\r\n  reg [1:0] btnl_shift;\r\n  always @(posedge clk)\r\n    btnl_shift &lt;= {btnl_shift,btnl};\r\n  wire btnl_rise = btnl_shift == 2'b01;\r\n  wire btnl_fall = btnl_shift == 2'b10;\r\n  \r\n  reg [1:0] btnc_shift;\r\n  always @(posedge clk)\r\n    btnc_shift &lt;= {btnc_shift,btnc};\r\n  wire btnc_rise = btnc_shift == 2'b01;\r\n  wire btnc_fall = btnc_shift == 2'b10;\r\n  \r\n  reg [1:0] btnr_shift;\r\n  always @(posedge clk)\r\n    btnr_shift &lt;= {btnr_shift,btnr};\r\n  wire btnr_rise = btnr_shift == 2'b01;\r\n  wire btnr_fall = btnr_shift == 2'b10;\r\n\r\n  wire [3:0]  digit;\r\n  always @(posedge clk)\r\n    case (digit)\r\n      0: ssd &lt;= 7'b1111110;\r\n      1: ssd &lt;= 7'b0110000;\r\n      2: ssd &lt;= 7'b1101101;\r\n      3: ssd &lt;= 7'b1111001;\r\n      4: ssd &lt;= 7'b0110011;\r\n      5: ssd &lt;= 7'b1011011;\r\n      6: ssd &lt;= 7'b1011111;\r\n      7: ssd &lt;= 7'b1110000;\r\n      8: ssd &lt;= 7'b1111111;\r\n      9: ssd &lt;= 7'b1110011;\r\n      10: ssd &lt;= 7'b1110111;\r\n      11: ssd &lt;= 7'b0011111;\r\n      12: ssd &lt;= 7'b1001110;\r\n      13: ssd &lt;= 7'b0111101;\r\n      14: ssd &lt;= 7'b1001111;\r\n      15: ssd &lt;= 7'b1000111;\r\n    endcase\r\n\r\n  reg [0:$clog2(ms_limit)-1] count = 0;\r\n  always @(posedge clk) count &lt;= count+1;\r\n  always @(posedge clk) ssdcat &lt;= count[0];\r\n<\/code><\/pre>\n<h1>Concept<\/h1>\n<p>We want to implement a counter that\u00a0counts for some period of time long enough for all the bouncing to finish. This timer will start whenever the button input rises or falls. It will stop if the button input bounces before the counter expires. The timer duration we&#8217;ll be using is 10ms\u2013 plenty of time for the switch to stop bouncing. Now, there are two timer values which we need to store. If the button input is rising and the button bounces, then we will see the input fall, then rise again. Conversely, if the input is falling, it will bounce high and then low again. This means we will also need to remember these two values. Here is the declaration of all this in Verilog:<\/p>\n<pre><code>  localparam bounce_limit = 10*ms_limit;\r\n  reg [$clog2(bounce_limit)-1:0] bounce_count = 0;\r\n  wire bounce_limit_reached = bounce_count == bounce_limit-1;\r\n  reg [$clog2(bounce_limit)-1:0] period0 = 0;\r\n  reg [$clog2(bounce_limit)-1:0] period1 = 0;\r\n<\/code><\/pre>\n<p>In addition, we need a flag to indicate that we have detected a bounce on either the rise or fall of the button input:<\/p>\n<pre><code>  reg triggered_rise = 0;\r\n  reg triggered_fall = 0;\r\n<\/code><\/pre>\n<h2>State Machine<\/h2>\n<p>To control the operation of the counters and the updating of the period registers, we&#8217;ll use a type of logic called a <em>state machine<\/em>. A state machine consists of a variable which holds a state value, a set of inputs, and a set of outputs or actions. The state machine may transition between states in response to different inputs. Usually, a state machine is represented in documentation by a state transition diagram. We need a state machine with four states. The state machine will use an <em>idle<\/em> state when looking for a button press. Once the button gets pressed, the state machines enters the <em>wait_1st<\/em>\u00a0and waits for a bounce. If the timer expires, then the state machine returns to the <em>idle<\/em>\u00a0state. Otherwise, if a transition is detected before the timer expires, the state machine stores the count value in <em>period0<\/em> and enters the <em>wait_2nd<\/em> state. In the <em>wait_2nd<\/em> state, the state machine waits for another transition of the button input. This input will happen because a transition within 10 ms is always\u00a0caused by a bounce, not the button being legitimately pressed and released. When the button transition takes place,\u00a0the state machine updates <em>period1<\/em> and enters the <em>triggered<\/em> state. The state machine lights an LED to indicate that a bounce was detected and then waits for a rising edge on the left button to reset the state machine and reenter the <em>idle<\/em> state. Here is the state transition diagram. <img loading=\"lazy\" decoding=\"async\" class=\"alignright wp-image-386 size-large\" src=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/StateDiagram-1024x566.png\" alt=\"StateDiagram\" width=\"584\" height=\"323\" srcset=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/StateDiagram-1024x566.png 1024w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/StateDiagram-300x166.png 300w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/StateDiagram-500x276.png 500w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/StateDiagram.png 1406w\" sizes=\"auto, (max-width: 584px) 100vw, 584px\" \/><\/p>\n<p>To code a state machine, we need to define the state variable first. I like to use an integer for FPGA coding, since it will always be large enough to hold all the states. The synthesis tool will re-encode the state values to be efficient for hardware, so it doesn&#8217;t really matter if you use an integer\u2013 you won&#8217;t be wasting any space in the FPGA. I also like to use <strong>localparam<\/strong> declarations of the states themselves. This lets me assign a symbolic value instead of\u00a0a number, which will make the code more readable. Let&#8217;s go ahead and do that now.<\/p>\n<pre><code>  localparam idle_state = 0;\r\n  localparam wait_1st_state = 1;\r\n  localparam wait_2nd_state = 2;\r\n  localparam triggered_state = 3;\r\n  integer state = idle_state;\r\n<\/code><\/pre>\n<p>Next we code an always block which contains a <strong>case<\/strong> statement which selects actions based on the current state.<\/p>\n<pre><code>  always @(posedge clk)\r\n    case(state)\r\n<\/code><\/pre>\n<p>We then have entries in the <strong>case<\/strong> statement for each state. This next part is pretty simple. Here is the entry for the <em>idle<\/em> state. When in the <em>idle<\/em> state we reset the bounce counter, the period counters and the triggered flags. If we detect an edge transition on the center button, we enter the <em>wait_1st<\/em> state. Here&#8217;s the code:<\/p>\n<pre><code>      idle_state:\r\n\tbegin\r\n\t  bounce_count &lt;= 0;\r\n\t  period0 &lt;= 0;\r\n\t  period1 &lt;= 0;\r\n\t  triggered_rise &lt;= 0;\r\n\t  triggered_fall &lt;= 0;\r\n\t  if (btnc_fall || btnc_rise)\r\n\t    begin\r\n\t      triggered_rise &lt;= btnc_rise;\r\n\t      triggered_fall &lt;= btnc_fall;\r\n\t      state &lt;= wait_1st_state;\r\n\t    end\r\n\tend\r\n<\/code><\/pre>\n<p>Once we&#8217;re in the <em>wait_1st<\/em> state, we&#8217;re going to increment the bounce count every clock, then test to see if we either have reached the bounce limit (in which case we go back to the idle state), or we detect another edge on the center button (in which case we record the current bounce count value in the <em>period0<\/em> register and enter the <em>wait_2nd<\/em> state).<\/p>\n<pre><code>      wait_1st_state:\r\n\tbegin\r\n\t  bounce_count &lt;= bounce_count+1;\r\n\t  if (bounce_limit_reached)\r\n\t    begin\r\n\t      state &lt;= idle_state;\r\n\t    end\r\n\t  else if (btnc_rise || btnc_fall)\r\n\t    begin\r\n\t      period0 &lt;= bounce_count;\r\n              bounce_count &lt;= 1;\r\n\t      state &lt;= wait_2nd_state;\r\n\t    end\r\n\tend\r\n<\/code><\/pre>\n<p>The <em>wait_2nd<\/em> state is pretty similar. The exception is that we don&#8217;t go back to idle on a timeout. The only way to exit is to detect an edge on the center button and enter the triggered state. We also update the <em>period1<\/em> register when this happens.<\/p>\n<pre><code>      wait_2nd_state:\r\n\tbegin\r\n\t  bounce_count &lt;= bounce_count+1;\r\n\t  if (btnc_rise || btnc_fall)\r\n\t    begin\r\n\t      period1 &lt;= bounce_count;\r\n\t      state &lt;= triggered_state;\r\n\t    end\r\n\tend\r\n<\/code><\/pre>\n<p>The final state is the <em>triggered<\/em> state. Here we just wait for the user to press the left button, whereupon we enter the idle state again.<\/p>\n<pre><code>      triggered_state:\r\n\tif (btnl_rise)\r\n\t  begin\r\n\t    state &lt;= idle_state;\r\n\t  end\r\n<\/code><\/pre>\n<p>Don&#8217;t forget to end the <strong>case<\/strong> statement with the <strong>encase<\/strong> keyword.<\/p>\n<h2>Simulation<\/h2>\n<p>Does it work so far? In order to tell, we should do some simulation. Let&#8217;s start a new test bench similar to the one we used before. Declare the module and the clock, inputs, and outputs to the <em>top<\/em> module. Remember, the inputs to the module should be declared as <strong>reg<\/strong> type signals and the outputs from the module should be <strong>wire<\/strong>. This is because the test bench is driving the module inputs and the <em>top<\/em> module is driving its outputs.<\/p>\n<p>Here is what I have for that:<\/p>\n<pre><code>`timescale 1ns \/ 1ns\r\nmodule bench;\r\n  reg clk = 1;\r\n  always #5 clk = ~clk;\r\n\r\n  reg [4:0] btn = 0;\r\n  reg [7:0] switch = 0;\r\n  wire [7:0] led;\r\n  wire \t     ssdcat;\r\n  wire [6:0] ssd;\r\n  \r\n  top #(.ms_limit(100)) top\r\n    (\r\n     .clk(clk),\r\n     .btn(btn),\r\n     .switch(switch),\r\n     .led(led),\r\n     .ssd(ssd),\r\n     .ssdcat(ssdcat)\r\n     );\r\n<\/code><\/pre>\n<p>Next, I&#8217;ll introduce you to the concept of a Verilog <strong>task<\/strong>. A task is just a procedural block with a name and a set of input and output values. You can only call a task in places where you can also put a <strong>begin<\/strong> <strong>end<\/strong> block. Tasks can be synthesizable, in which case all the RTL restrictions apply (like no # delays), or they can be used in test benches (in which case you can use all language features). Below is a task which presses a button with the possibility of bouncing. The task takes three input values: which button to press, how many clocks to wait before bouncing the button low, and how many clocks to wait before returning the button to the high position. Sometimes you don&#8217;t want the switch to bounce. In this case, you specify a zero for the bounce time. In all cases, the second bounce parameter specifies how long to wait to return the button to high after the bounce. If there is no bounce then this input is ignored. Here is the code:<\/p>\n<pre><code>  task press_button;\r\n    input integer button;\r\n    input integer bounce0;\r\n    input integer bounce1;\r\n    begin\r\n      btn[button] &lt;= 1;\r\n      if (bounce0 &gt; 0)\r\n\tbegin\r\n\t  repeat(bounce0) @(posedge clk);\r\n\t  btn[button] &lt;= 0;\r\n\t  repeat(bounce1) @(posedge clk);\r\n\t  btn[button] &lt;= 1;\r\n\tend\r\n    end\r\n  endtask\r\n<\/code><\/pre>\n<p>Note that the inputs and outputs of the task are syntactically different from module input and output ports. Why? I have no idea. Anyway, we now have a task to press a button. We also need a task to release a button. Go ahead and code that now. Call the task <em>release_button<\/em>.<\/p>\n<p>Now, the way I&#8217;ve coded things, the left button is <em>btw[0],<\/em> and the center button (which we are measuring for bouncing) is <em>btw[4]<\/em>. If our logic works correctly, we&#8217;ll need to use the left button to clear the state machine back to its\u00a0initial state. So, I have a task that will\u00a0press the left button. Since this button does not have the debounce state machine hooked to it, we can press it as fast as we want in simulation and not have the design think it is a button bounce. I&#8217;ll create a task called <em>clear_trigger<\/em> which will press and release the left button. Now, I can use the <em>press_button<\/em> and <em>release_button<\/em> tasks we defined earlier.<\/p>\n<pre><code>  task clear_trigger;\r\n    begin\r\n      press_button(0,0,0);\r\n      repeat (10) @(posedge clk);\r\n      release_button(0,0,0);\r\n      repeat (10) @(posedge clk);\r\n    end\r\n  endtask\r\n<\/code><\/pre>\n<p>Now we need to press the center button with some bounce, clear the trigger condition, release the button with some bounce, and clear that trigger condition. This will form the beginnings of a test. Here is what I have for that:<\/p>\n<pre><code>  initial\r\n    begin\r\n      repeat (10) @(posedge clk);\r\n\r\n      press_button(4,100,100);\r\n      repeat (10) @(posedge clk);\r\n      clear_trigger;\r\n      \r\n      release_button(4,100,100);\r\n      repeat (10) @(posedge clk);\r\n      clear_trigger;\r\n\r\n      repeat (10) @(posedge clk);\r\n      $finish;\r\n    end\r\n<\/code><\/pre>\n<p>The repeat statements just give the simulation enough time to let all the signals propagate through the design. Remember, it takes a few clocks for the logic to even see that the button was pressed, and then another clock or two to get the state machine to transition. In fact, the repeat clock cycle idiom is so common, I often define a task in my test bench called <em>spin<\/em> which simply takes the number of clocks as input and has a simple repeat statement that repeatedly waits the requested number of clock cycles. That way, rather than writing <code>repeat (10) @(posedge clk);<\/code>, I can just write <code>spin(10);<\/code>.<\/p>\n<p>Don&#8217;t forget to add the <strong>endmodule<\/strong> keyword at the end of the test bench.<\/p>\n<p>Go ahead and run your simulation. I added the signals <em>period0<\/em>, <em>period1<\/em>, <em>state<\/em>, and <em>bounce_count<\/em> from the <em>top<\/em> module with the radix set to unsigned decimal. Here is what my waveform looks like:<\/p>\n<p><a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/waveform1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-392\" src=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/waveform1-300x81.png\" alt=\"waveform1\" width=\"300\" height=\"81\" srcset=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/waveform1-300x81.png 300w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/waveform1-1024x277.png 1024w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/waveform1-500x135.png 500w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/waveform1.png 1177w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>I can see the correct period values in the waveform so everything looks good. Still, we&#8217;re not quite there yet. We don&#8217;t have any way to see the period registers in the real design. And we don&#8217;t have any way for the test to tell if it worked without looking into the <em>top<\/em> module. We will fix that in the next tutorial.<\/p>\n<p>Here are my files that I have for this tutorial.<\/p>\n<ul>\n<li><a title=\"top.v\" href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/tutorials\/tutorial9\/top.v\">top.v<\/a><\/li>\n<li><a title=\"bench.v\" href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/tutorials\/tutorial9\/bench.v\">bench.v<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Now that we have our top watch working, we&#8217;re all done, right? Not quite. Mechanical switches and buttons have a property called bounce. Bounce\u00a0means the switch won&#8217;t go cleanly from open to closed or vice versa. Instead, it\u00a0bounces between the &hellip; <a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial9\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":226,"menu_order":9,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-378","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/378","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/comments?post=378"}],"version-history":[{"count":17,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/378\/revisions"}],"predecessor-version":[{"id":1004,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/378\/revisions\/1004"}],"up":[{"embeddable":true,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/226"}],"wp:attachment":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/media?parent=378"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}