{"id":418,"date":"2015-02-08T11:36:11","date_gmt":"2015-02-08T19:36:11","guid":{"rendered":"http:\/\/www.beyond-circuits.com\/wordpress\/?page_id=418"},"modified":"2026-10-23T13:53:39","modified_gmt":"2026-10-23T21:53:39","slug":"tutorial11","status":"publish","type":"page","link":"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial11\/","title":{"rendered":"Tutorial 11: A Debounce Circuit"},"content":{"rendered":"<p>In this tutorial, we will design a switch debounce circuit, then test it using the design from <a title=\"Tutorial 10 \u2013 Completing the Bounce Measure Design\" href=\"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial10\/\">tutorial 10<\/a>.<\/p>\n<h1>The Debounce Module<\/h1>\n<p>Let&#8217;s design a module that will debounce a switch or push button. The module needs a clock and the switch signal as input and produces a debounced switch output, as well as switch rise and switch fall outputs. It will also take a parameter which indicates a bounce lockout period. The algorithm for the module just looks for a transition on the switch input and then locks the input in that state for the number of clocks specified by the parameter. Any bouncing by the switch during that time will be ignored by the circuit. Here is the module declaration:<\/p>\n<pre><code>`timescale 1ns \/ 1ns\r\nmodule debounce\r\n  #(\r\n    parameter bounce_limit = 1024\r\n    )\r\n  (\r\n   input clk,\r\n   input switch_in,\r\n   output reg switch_out,\r\n   output reg switch_rise,\r\n   output reg switch_fall\r\n   );\r\n<\/code><\/pre>\n<p>We will also need a counter variable called <em>bounce_count<\/em> for the timer. Here is the declaration for that:<\/p>\n<pre><code>  reg [$clog2(bounce_limit)-1:0] bounce_count = 0;\r\n<\/code><\/pre>\n<p>Next we synchronize the switch input as before in a two bit shift register. Here is the code for that:<\/p>\n<pre><code>  reg [1:0] switch_shift;\r\n  always @(posedge clk)\r\n    switch_shift &lt;= {switch_shift,switch_in};\r\n<\/code><\/pre>\n<p>Next, we&#8217;ll handle the actual debounce part of the design. Basically, we need an always block which does a couple things. First, if it sees the switch input rise or fall, it should start a timer. Second, while the timer is counting, it should ignore transitions on the switch input. And finally, if the timer is counting down it should decrement the timer. I have chosen to have the timer count down to zero in this example, but you could just as easily designed it to count up. Here is the always block:<\/p>\n<pre><code>  always @(posedge clk)\r\n    if (bounce_count == 0)\r\n      begin\r\n        switch_rise &lt;= switch_shift[1] &amp;&amp; !switch_out;\r\n        switch_fall &lt;= !switch_shift[1] &amp;&amp; switch_out;\r\n        switch_out &lt;= switch_shift[1];\r\n        if (switch_shift[1] != switch_out)\r\n          bounce_count &lt;= bounce_limit-1;\r\n      end\r\n    else\r\n      begin\r\n\tswitch_rise &lt;= 0;\r\n\tswitch_fall &lt;= 0;\r\n\tbounce_count &lt;= bounce_count-1;\r\n      end\r\n<\/code><\/pre>\n<p>Let&#8217;s walk through the code. There are basically two cases to consider. If the timer is not zero, then it is counting down and we just decrement the counter and set the rise and fall signals to zero. If it is not counting down but rather is zero, then we compare the synchronized input, <em>switch_shift<\/em> bit 1, with the current debounced output. If they differ the switch has changed, so we pulse <em>switch_rise<\/em> or <em>switch_fall<\/em>, copy the new value to <em>switch_out<\/em>, and set the timer to the <em>bounce_limit<\/em> minus 1.<\/p>\n<p><strong>Update (October 2026):<\/strong> The original version of this code looked for an edge in the shift register (<code>switch_shift == 2'b01<\/code>) and set <em>switch_out<\/em> from <em>switch_shift<\/em> bit 0. If the switch changed and changed back while the timer was running, for example a tap shorter than the debounce time, <em>switch_out<\/em> ended up correct but the matching <em>switch_fall<\/em> (or <em>switch_rise<\/em>) pulse was never generated. Comparing the input with <em>switch_out<\/em> instead of looking for an edge fixes that, because any difference left over when the timer expires is reported. It also uses bit 1 of the shift register, so the input goes through both synchronizer flip-flops. Thanks to Sam for the question that led to this.<\/p>\n<p>This is basically the switch debounce module. Don&#8217;t forget to add your <code>endmodule<\/code> statement at the end of your module.<\/p>\n<h1>Testing the Debounce Logic<\/h1>\n<p>Let&#8217;s test the debounce logic in our circuit from <a title=\"Tutorial 10 \u2013 Completing the Bounce Measure Design\" href=\"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial10\/\">tutorial 10<\/a>.<\/p>\n<p>We first need to instantiate our debounce module and hook it\u00a0up to the center button. Here is the code for that. Notice that I have chosen a 3ms debounce count which I deemed sufficient based on testing the previous design on my board.<\/p>\n<pre><code>  wire btnc_debounced;\r\n  debounce #(.bounce_limit(ms_limit*3)) db_bntc\r\n    (\r\n     .clk(clk),\r\n     .switch_in(btnc),\r\n     .switch_out(btnc_debounced),\r\n     .switch_rise(),\r\n     .switch_fall()\r\n     );\r\n<\/code><\/pre>\n<p>Then we will use the switch seven to select between debounced and non-debounced modes. To do this we modify the <em>btnc_shift<\/em> shift register to have a mux on its input which selects between the debounced and non-debounced center button based on the switch value. Here is the modified code for that:<\/p>\n<pre><code>  reg [1:0] btnc_shift;\r\n  always @(posedge clk)\r\n    btnc_shift &lt;= {btnc_shift,switch[7] ? btnc_debounced : btnc};\r\n<\/code><\/pre>\n<p>This is all we need to test out the debounce module on our board. Go ahead and build the design and program your board. Verify that you get the same behavior as before when switch seven in in the low position, then switch it high. Can you get the design to detect a bounce on the center button anymore?<\/p>\n<h1>One final improvement<\/h1>\n<p>Usually, you need to have a number of switch or button inputs in your design. You could instantiate one of our debounce modules for each one, but it would be better, in my opinion, to design the debounce module so that it can debounce more than one button. That way, you can connect a bunch of switch inputs to the module and have it debounce all of them. We can do this using the generate statement like we saw in <a title=\"Tutorial 8 \u2013 Stopwatch\" href=\"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial8\/\">tutorial 8<\/a>.<\/p>\n<p>All we need to do it to add a parameter called <em>width<\/em> which specifies how many switch inputs there are, then modify our module to wrap everything in a generate block. The generate block will use a <b>for<\/b> loop and rather than instantiating modules like before we will just use the code from the body of the module. We also need to turn the input and output ports into busses. Here is the new module declaration:<\/p>\n<pre><code>`timescale 1ns \/ 1ns\r\nmodule debounce\r\n  #(\r\n    parameter width = 1,\r\n    parameter bounce_limit = 1024\r\n    )\r\n  (\r\n   input clk,\r\n   input [width-1:0] switch_in,\r\n   output reg [width-1:0] switch_out,\r\n   output reg [width-1:0] switch_rise,\r\n   output reg [width-1:0] switch_fall\r\n   );\r\n<\/code><\/pre>\n<p>Did you notice how the switch inputs and outputs changed to busses? Later, when we use these interfaces, we need to make sure we index into them appropriately.<\/p>\n<p>Next we have our generate statement with a <b>for<\/b> loop. This <b>for<\/b> loop will iterate and build the debounce logic for each switch input bit.<\/p>\n<pre><code>  genvar  i;\r\n  generate\r\n    for (i=0; i&lt;width;i=i+1)\r\n      begin\r\n<\/code><\/pre>\n<p>Before you end the module, you need to end the generate for loop and the generate statement.<\/p>\n<pre><code>      end\r\n  endgenerate\r\n<\/code><\/pre>\n<p>Within the body of the generate for loop, we declare reg and wire signals as before. The generate for loop is run before synthesis or simulation actually happens. This phase of execution is known as <em>elaboration<\/em>. Think of this as a program that runs that generates your Verilog code before it goes in to the simulator or synthesis tool. The variables you declare within the for loop only have <em>scope<\/em> within that instance of the loop. For example, the <em>bounce_count<\/em> counter in iteration 0 of the loop is completely distinct from the <em>bounce_count<\/em> counter in iteration 1. If you run a simulation and look at the objects for the debounce module, you will see that each iteration of the for loop creates its own set of variables.<\/p>\n<p>Within the body of the generate for loop we need to change all occurrences of <em>switch_in<\/em>, <em>switch_out<\/em>, <em>switch_rise<\/em>, and <em>switch_fall<\/em> to <em>switch_in[i]<\/em>, <em>switch_out[i]<\/em>, <em>switch_rise[i]<\/em>, and <em>switch_fall[i]<\/em>.<\/p>\n<p>We will use this debounce module in future tutorials.<\/p>\n<p>Here are the files 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\/tutorial11\/top.v\">top.v<\/a><\/li>\n<li><a title=\"debounce.v\" href=\"https:\/\/www.beyond-circuits.com\/repos\/tutorial\/trunk\/rtl\/debounce.v\">debounce.v<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, we will design a switch debounce circuit, then test it using the design from tutorial 10. The Debounce Module Let&#8217;s design a module that will debounce a switch or push button. The module needs a clock and &hellip; <a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial11\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":226,"menu_order":11,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-418","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/418","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=418"}],"version-history":[{"count":14,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/418\/revisions"}],"predecessor-version":[{"id":1386,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/418\/revisions\/1386"}],"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=418"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}