{"id":396,"date":"2015-02-06T11:51:33","date_gmt":"2015-02-06T19:51:33","guid":{"rendered":"http:\/\/www.beyond-circuits.com\/wordpress\/?page_id=396"},"modified":"2016-07-22T19:42:01","modified_gmt":"2016-07-23T03:42:01","slug":"tutorial10","status":"publish","type":"page","link":"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial10\/","title":{"rendered":"Tutorial 10: Completing the Bounce Measure Design"},"content":{"rendered":"<p>In our last tutorial, we designed a circuit to detect and measure a button bounce. However, there was no way to see the debounce information outside the design. In this tutorial, we will add the ability to see the debounce information and create a self-checking test bench to verify our design.<\/p>\n<h1>Let&#8217;s See Some Output<\/h1>\n<p>One thing that would be really helpful is to know what is going on with the states. We have the <em>triggered_rise<\/em> and <em>triggered_fall<\/em> signals, which indicate that the state machine saw a button rise or a button fall. Once set, these signals will stay on until we return to the <em>idle<\/em> state. It would also be useful\u00a0to have a signal which indicate that the state machine is in the idle state. Let&#8217;s do that now:<\/p>\n<pre><code>wire waiting = state == idle_state;<\/code><\/pre>\n<p>Then we can take over the LED outputs to show us some status information. Like this:<\/p>\n<pre><code>  always @(posedge clk)\r\n    led &lt;= {btnc_fall,btnc_rise,waiting,triggered_fall,triggered_rise};\r\n<\/code><\/pre>\n<p>If you haven&#8217;t seen the syntax before, the curly braces tell Verilog to concatenate the signals inside the braces together. Basically, it places the signals into a larger bus. We&#8217;ll assign this bus to the <em>led<\/em> outputs. Our real challenge, however, is to display the values of the <em>period0<\/em> and <em>period1<\/em> registers. To do this, we will use the switches to look at different bytes within the values of the registers. This is similar to how the stopwatch could look at hundredths, seconds, minutes, and hours.<\/p>\n<p>We declare an 8-bit register called <em>ssd_byte<\/em> and use a case statement based on the switch inputs to select which part of the <em>pattern0<\/em> and <em>pattern1<\/em> registers we want to look at. Here&#8217;s my version:<\/p>\n<pre><code>  reg [7:0] ssd_byte;\r\n  always @(*)\r\n    case (1'b1)\r\n      switch[5]: ssd_byte = period1[$clog2(bounce_limit)-1:16];\r\n      switch[4]: ssd_byte = period1[15:8];\r\n      switch[3]: ssd_byte = period1[7:0];\r\n      switch[2]: ssd_byte = period0[$clog2(bounce_limit)-1:16];\r\n      switch[1]: ssd_byte = period0[15:8];\r\n      switch[0]: ssd_byte = period0[7:0];\r\n      default: ssd_byte = 0;\r\n    endcase\r\n<\/code><\/pre>\n<p>Notice how we need to limit the most significant byte of the period registers to <code>$clog2(bounce_limit)<\/code>. This is because the registers don&#8217;t have a full 24 bits of precision. If we were to use just <code>23:16<\/code>, the synthesis tool would complain that we\u00a0are indexing outside the range of the <em>period0<\/em> and <em>period1<\/em> registers. The simulator, on the other hand, doesn&#8217;t care if we do that.<\/p>\n<p>Now, we need to assign the digit signal based on the <em>ssd_byte<\/em> output from the switch statement. Also, note that we use the <em>count[0]<\/em> as the mux select to keep the <em>ssd<\/em> and <em>ssdcat<\/em> signals aligned. Like this:<\/p>\n<pre><code>  assign digit = count[0] ? ssd_byte[7:4] : ssd_byte[3:0];<\/code><\/pre>\n<p>Start a simulation and&#8230; it won&#8217;t compile. The problem is that we defined <em>bounce_limit<\/em> to be <code>10*ms_limit<\/code>. And in synthesis <em>ms_limit<\/em> is 100000, so <em>bounce_limit<\/em> is 10000000, and <code>$clog2(bounce_limit)<\/code> is 20. This gives the synthesis tool the range <code>19:16<\/code>, which is just great. However, in simulation we overrode the <em>ms_limit<\/em> parameter with a value of 100. This means that <em>bounce_limit<\/em> then has a value of 1000, and <code>$clog2(bounce_limit)<\/code> has a value of only 10. So, we are telling the simulator that it should index into the period registers with an index of <code>9:16<\/code>. This is backwards from the way we declared the registers, so we get an error.<\/p>\n<h2>One Minor Hitch<\/h2>\n<p>What to do? Ideally, what we want is to have the <em>ms_limit<\/em> parameter that the test bench can override for simulation purposes, and a second\u00a0<em>ms_limit<\/em> value which it doesn&#8217;t override. Then, we can use the non-overridden parameter to size our registers, and the overridden parameter to limit our counters. To do this, we\u00a0declare a new parameter that we will call <em>default_ms_limit<\/em> and set it to 100000, then use that parameter as the default value of the <em>ms_limit<\/em> parameter. So go back to the parameter list of the <em>top.v<\/em> file and change it to look like this:<\/p>\n<pre><code>  parameter default_ms_limit = 100000,\r\n  parameter ms_limit = default_ms_limit\r\n<\/code><\/pre>\n<p>Then modify your <em>bounce_limit<\/em> and period declarations to look like this:<\/p>\n<pre><code>  localparam bounce_milliseconds = 10;\r\n  localparam bounce_limit = bounce_milliseconds*ms_limit;\r\n  localparam default_bounce_limit = bounce_milliseconds*default_ms_limit;\r\n  reg [$clog2(default_bounce_limit)-1:0] bounce_count = 0;\r\n  wire bounce_limit_reached = bounce_count == bounce_limit-1;\r\n  reg [$clog2(default_bounce_limit)-1:0] period0 = 0;\r\n  reg [$clog2(default_bounce_limit)-1:0] period1 = 0;\r\n<\/code><\/pre>\n<p>Notice how I have made a new parameter called <em>bounce_milliseconds<\/em>, which defines the number of milliseconds we want the bounce counter to count. Then I used that parameter to define <em>bounce_limit<\/em> as before, but also used it to define a <em>default_bounce_limit<\/em> parameter. Then I used the <em>default_bounce_limit<\/em> parameter to define <em>bounce_count<\/em>, <em>period0<\/em>, and <em>period1<\/em>.<\/p>\n<p>Finally, I can modify the <strong>case<\/strong> statement to use the <em>default_bounce_limit<\/em> parameter which will not change between simulation and synthesis.<\/p>\n<pre><code>  reg [7:0] ssd_byte;\r\n  always @(*)\r\n    case (1'b1)\r\n      switch[5]: ssd_byte = period1[$clog2(default_bounce_limit)-1:16];\r\n      switch[4]: ssd_byte = period1[15:8];\r\n      switch[3]: ssd_byte = period1[7:0];\r\n      switch[2]: ssd_byte = period0[$clog2(default_bounce_limit)-1:16];\r\n      switch[1]: ssd_byte = period0[15:8];\r\n      switch[0]: ssd_byte = period0[7:0];\r\n      default: ssd_byte = 0;\r\n    endcase\r\n<\/code><\/pre>\n<h1>Simulation<\/h1>\n<p>Let&#8217;s get back to simulating our design. Now that we can see the digits of the period registers, we should be able to also verify that they match the way we bounced the button.<\/p>\n<p>As with our other test bench in Tutorial 6, we will need to recover the value of the digits from the seven segment display output from our FPGA. We use the same code as before:<\/p>\n<pre><code>  wire [7:0] digits;\r\n  ssd_digit PmodSSD0\r\n    (\r\n     .enable(~ssdcat),\r\n     .ssd(ssd),\r\n     .value(digits[3:0])\r\n     );\r\n  \r\n  ssd_digit PmodSSD1\r\n    (\r\n     .enable(ssdcat),\r\n     .ssd(ssd),\r\n     .value(digits[7:4])\r\n     );\r\n<\/code><\/pre>\n<p>Also, be sure to add the source to the <b>ssd_digit.v<\/b> file to your simulation. From th eProject Manager, select Add Sources to add a simulation source. Then select the module from Tutorial 6. Be sure to check the box indicating you want Vivado to copy the file into the project area.<\/p>\n<p>Next, we will create a task called <em>read_period<\/em> which can read the period registers. This task will do it the same way you&#8217;d do it on the actual FPGA board. To read <em>period0<\/em>, it flips switch 0 to look at the least significant byte, then switch 1 to look at the next byte, then switch 2 to look at the third byte. It then builds the final value from the three bytes. Let&#8217;s first just fill in the declaration of the task. Later we will fill in the body.<\/p>\n<p>The task will take an input indicating which period register to read, and produce an output which is the value of the register. Also, the task uses a local variable called <em>base<\/em> which stores the switch for the least significant byte for the desired period register. Here is the task declaration:<\/p>\n<pre><code>  task read_period;\r\n    input which;\r\n    output integer value;\r\n    integer base;\r\n    begin\r\n\r\n    end\r\n  endtask\r\n<\/code><\/pre>\n<p>For the body of the task (the part between <strong>begin<\/strong> and <strong>end<\/strong>), we first set the <em>base<\/em> variable to <code>3*which<\/code>. This will make it either 0 or 3. Then, we set the switches to zero, except the switch pointed to by base (0 or 3). Next\u00a0we need to wait for <em>ssdcat<\/em> to transition twice. This will either be low-to-high and then high-to-low, or high to low and then low to high. This makes sure that both of the <em>ssd_digit<\/em> modules get to latch the updated digits. Here is the code for reading the least significant byte:<\/p>\n<pre><code>      base = which*3;\r\n      switch &lt;= 0;\r\n      switch[base] &lt;= 1;\r\n      @(ssdcat);\r\n      @(ssdcat);\r\n      repeat (10) @(posedge clk);\r\n      value = digits;\r\n<\/code><\/pre>\n<p>Notice how we set all the bits of <em>switch<\/em> to zero, then set the one we want high on the following line. Then the line <code>@(ssdcat)<\/code> waits for a rising or falling edge on <em>ssdcat<\/em>. The same line again waits for another edge. This way, we are sure to see <em>ssdcat<\/em> transition high and low. Now, there&#8217;s a wait for ten clocks to allow the <em>ssd_digit<\/em> modules to update their outputs. Then, we set value equal to the <em>ssd_digit<\/em> modules <em>digits<\/em> output. Now let&#8217;s add the code to read the other digits:<\/p>\n<pre><code>      switch &lt;= 0;\r\n      switch[base+1] &lt;= 1;\r\n      @(ssdcat);\r\n      @(ssdcat);\r\n      repeat (10) @(posedge clk);\r\n      value = value | digits&lt;&lt;8;\r\n      switch &lt;= 0;\r\n      switch[base+2] &lt;= 1;\r\n      @(ssdcat);\r\n      @(ssdcat);\r\n      repeat (10) @(posedge clk);\r\n      value = value | digits&lt;&lt;16;\r\n<\/code><\/pre>\n<p>Now for the actual test code. First we need to declare a variable to hold the period values we read. Since there are two values I am going to use an array to hold them:<\/p>\n<pre><code>  integer period[1:0]<\/code><\/pre>\n<p>Then, we&#8217;ll use an <strong>initial<\/strong> block to make everything run. The block will have an initial waiting period to let everything get up and running. Then there&#8217;s a press of the center button with some bounce. Then another pause followed by reading the two period registers, and then we clear the trigger. I follow that with the same thing, but releasing the button. Then a final pause and we finish the simulation. Here is my code:<\/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      read_period(0,period[0]);\r\n      read_period(1,period[1]);\r\n      clear_trigger;\r\n      \r\n      release_button(4,200,50);\r\n      repeat (10) @(posedge clk);\r\n      read_period(0,period[0]);\r\n      read_period(1,period[1]);\r\n      clear_trigger;\r\n\r\n      repeat (10) @(posedge clk);\r\n      $finish;\r\n    end\r\n<\/code><\/pre>\n<p>If we run the simulation and add the signals of interest to the waveform I get the following:<\/p>\n<p><a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/waveform11.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-405\" src=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/waveform11-300x103.png\" alt=\"waveform1\" width=\"300\" height=\"103\" srcset=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/waveform11-300x103.png 300w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/waveform11-500x171.png 500w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/02\/waveform11.png 1003w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Notice how you can see the <em>period<\/em> array change to 100,100 around 10\u00b5s? That&#8217;s immediately before we clear the state machine. Then, right before the end of the simulation, we see it change again to 50,200. There isn&#8217;t room on the waveform to display the values, but you can see it in the <em>value<\/em> column to the left.<\/p>\n<h1>Self-Checking<\/h1>\n<p>To make a self-checking test, we first need to declare our number of errors and number of checks counters.<\/p>\n<pre><code>  integer num_checks = 0;\r\n  integer num_errors = 0;\r\n<\/code><\/pre>\n<p>Then, we want to declare a task which will perform a button press or release and checks that the measured bounce period matches the bounce periods the test used. We will call this task <em>test_button<\/em>. It&#8217;s\u00a0going to need variables to hold the expected and measured period values. Here is the task declaration with an empty body:<\/p>\n<pre><code>  task test_button;\r\n    input integer button;\r\n    integer period[1:0];\r\n    integer expected_period[1:0];\r\n    begin\r\n    end\r\n  endtask\r\n<\/code><\/pre>\n<p>In the body of the task, we need to set some expected values for the period registers. We will generate random values for these. The values must be less than the maximum of the bounce count in the <em>top<\/em> module. The best thing to do is to make use of the <em>bounce_limit<\/em> parameter in the <em>top<\/em> module. That way, if the parameter changes, our test bench will still be correct. This illustrates an important principal of only specifying a piece of information in one place. Here is that code:<\/p>\n<pre><code>      expected_period[0] = {$random}%(top.bounce_limit-10)+10;\r\n      expected_period[1] = {$random}%(top.bounce_limit-10)+10;\r\n<\/code><\/pre>\n<p>These two lines of code are just chock full of gems. First the term <code>top.bounce_limit<\/code> reaches into the <em>instance<\/em> called <em>top<\/em> and gets the value of its <em>bounce_limit<\/em> parameter. In general, we don&#8217;t want the test looking into the modules it is testing, because if you do a gate level simulation, all the internals are different. However, the parameters will never change so are OK to look at. You can also see that we call the <b>$random<\/b> function to return a random value. This function returns a 32-bit <em>signed<\/em> number. We will use the modulo operator <b>%<\/b> to reduce the value returned by <b>$random<\/b> down to something smaller. If we use the expression <code>a%b<\/code>, then the result is what you get when you divide <em>a<\/em> by <em>b<\/em> and take the remainder. I am looking for a random number between 10 and <em>top.bounce_limit<\/em>. In our simulation, this is between 10 and 999. So we take our random number and find the remainder when dividing by 990. This gives a number between 0 and 989. We then add 10 to that to get a value between 10 and 999. So why am I really using <code>{$random}<\/code> instead of just <code>$random<\/code>? The answer is that the modulo operator can do funny things when you give it a negative number. What is -7%10? Why 3 of course! Because 10*-1+3 = -7. A different computer might tell you -7 because 10*0-7 = -7. By placing a signed 32-bit value inside a concatenation, we get an unsigned 32-bit value. That way we don&#8217;t get any funny business.<\/p>\n<p>Next we need to press or release the button, depending on its current state. Here&#8217;s the code to do that:<\/p>\n<pre><code>      if (btn[button])\r\n\tbegin\r\n\t  release_button(button,expected_period[0],expected_period[1]);\r\n\t  wait(led[1]);\r\n\tend\r\n      else\r\n\tbegin\r\n\t  press_button(button,expected_period[0],expected_period[1]);\r\n\t  wait(led[0]);\r\n\tend\r\n<\/code><\/pre>\n<p>We include a <strong>wait<\/strong> statement which causes the simulator to wait until the appropriate LED lights up.<\/p>\n<p>Then we need to read the period values and compare them to the expected results:<\/p>\n<pre><code>      read_period(0,period[0]);\r\n      read_period(1,period[1]);\r\n      num_checks = num_checks+1;\r\n      if (period[0] != expected_period[0])\r\n\tbegin\r\n\t  $display(\"*** ERROR: period[0] value %0d does not match expected value of %0d\",\r\n\t\t   period[0],expected_period[0]);\r\n\t  num_errors = num_errors+1;\r\n\tend\r\n      num_checks = num_checks+1;\r\n      if (period[1] != expected_period[1])\r\n\tbegin\r\n\t  $display(\"*** ERROR: period[1] value %0d does not match expected value of %0d\",\r\n\t\t   period[1],expected_period[1]);\r\n\t  num_errors = num_errors+1;\r\n\tend\r\n<\/code><\/pre>\n<p>And finally, we need to clear the trigger condition by calling the <em>clear_trigger<\/em> task.<\/p>\n<pre><code>      clear_trigger;<\/code><\/pre>\n<h2>Overall Control<\/h2>\n<p>The actual initial block which says what to do is really quite simple. Here it is:<\/p>\n<pre><code>  initial\r\n    begin\r\n      repeat (10) @(posedge clk);\r\n      repeat (100) test_button(4);\r\n      repeat (10) @(posedge clk);\r\n      $display(\"Simulation complete at time %0fns.\",$realtime);\r\n      if (num_errors &gt; 0)\r\n\t$display(\"*** Simulation FAILED %0d\/%0d\",num_errors,num_checks);\r\n      else\r\n\t$display(\"*** Simulation PASSED %0d\/%0d\",num_errors,num_checks);\r\n      $finish;\r\n    end\r\n<\/code><\/pre>\n<p>When I run this, I see the magic results I am looking for:<\/p>\n<pre><code>Simulation complete at time 1796240.000000ns.\r\n*** Simulation PASSED 0\/200\r\n<\/code><\/pre>\n<p>If you look at the waveform, you get a pretty good idea of the level of activity you get with this test. To be thorough, we should probably also give some transitions where the button doesn&#8217;t bounce and make sure that case works as well\u2013 but I think you get the point.<\/p>\n<h1>Using the Design<\/h1>\n<p>Now build the design and download it to your board. What values to you get for the period counters? Does the button bounce more often when it is pressed or released? We are only investigating the first bounce. How would you modify the design to see if it bounces more than once? Is the 10ms bounce limit that we use for the bounce counter a good choice? Would it be safe to make it smaller?<\/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\/tutorial10\/top.v\">top.v<\/a><\/li>\n<li><a title=\"bench.v\" href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/tutorials\/tutorial10\/bench.v\">bench.v<\/a><\/li>\n<li><a title=\"ssd_digit.v\" href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/tutorials\/tutorial10\/ssd_digit.v\">ssd_digit.v<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In our last tutorial, we designed a circuit to detect and measure a button bounce. However, there was no way to see the debounce information outside the design. In this tutorial, we will add the ability to see the debounce &hellip; <a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial10\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":226,"menu_order":10,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-396","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/396","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=396"}],"version-history":[{"count":17,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/396\/revisions"}],"predecessor-version":[{"id":1006,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/396\/revisions\/1006"}],"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=396"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}