{"id":347,"date":"2015-01-30T10:03:08","date_gmt":"2015-01-30T18:03:08","guid":{"rendered":"http:\/\/www.beyond-circuits.com\/wordpress\/?page_id=347"},"modified":"2016-07-05T14:56:39","modified_gmt":"2016-07-05T22:56:39","slug":"tutorial8","status":"publish","type":"page","link":"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial8\/","title":{"rendered":"Tutorial 8: Stopwatch"},"content":{"rendered":"<p>In this tutorial, we will build on our counter from the last tutorial to add the ability to start, stop, and reset the time counter. Essentially, we&#8217;re going to make a stopwatch.<\/p>\n<h1>Adding the Buttons<\/h1>\n<p>The ZedBoard has five pushbutton inputs that go to the FPGA. There are two additional pushbuttons, which are for use by the ARM processor that cannot be used by the FPGA fabric. We need to declare the button inputs to the module. We can do this either as five separate inputs or a 5-bit bus. I prefer the bus method.<\/p>\n<p>Just add the following to the port list:<\/p>\n<pre><code>input [4:0] btn,<\/code><\/pre>\n<p>Also, it can be nice to refer to the buttons symbolically as well, so I added the following wire definitions too.<\/p>\n<pre><code>  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<\/code><\/pre>\n<p>Of course, we\u00a0need to add the design constraints to declare the IO type and which pin the inputs are connected to. Modify the <b>top.xdc<\/b> file to add the following lines:<\/p>\n<pre><code>set_property IOSTANDARD LVCMOS25 [get_ports btn]\r\nset_property PACKAGE_PIN P16 [get_ports {btn[4]}]\r\nset_property PACKAGE_PIN R16 [get_ports {btn[3]}]\r\nset_property PACKAGE_PIN R18 [get_ports {btn[2]}]\r\nset_property PACKAGE_PIN T18 [get_ports {btn[1]}]\r\nset_property PACKAGE_PIN N15 [get_ports {btn[0]}]\r\n<\/code><\/pre>\n<p>Next, we&#8217;ll need to look at the buttons. I am going to choose the left button to reset the counter, the center button to stop the counter, and the right button to start the counter. When the button is pressed, the corresponding input value goes high. When the button is released, the button goes low again.<\/p>\n<p>First, we&#8217;ll need some logic to\u00a0detect the rising edge of a button.<\/p>\n<h2>Detecting the Rising Edge<\/h2>\n<p><a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/01\/Tutorial8_sch1.png\"><img loading=\"lazy\" decoding=\"async\" class=\" size-medium wp-image-352 alignright\" src=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/01\/Tutorial8_sch1-300x76.png\" alt=\"Tutorial8_sch1\" width=\"300\" height=\"76\" srcset=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/01\/Tutorial8_sch1-300x76.png 300w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/01\/Tutorial8_sch1-1000x254.png 1000w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/01\/Tutorial8_sch1-500x126.png 500w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/01\/Tutorial8_sch1.png 1008w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>An important thing to note is that the button can be pressed at any time, so it&#8217;s impossible to say when the signal will arrive with respect to the clock. This type of signal is referred to as <em>asynchronous<\/em>. It is critically important for your design reliability that you deal with any asynchronous signals by bringing them on chip, then immediately sampling them in a <span style=\"text-decoration: underline;\">single<\/span> flip-flop. This way, you&#8217;ll synchronize the signal to your clock domain. Once we&#8217;ve synchronized the button input, we can start looking to see if the button has risen. The schematic will help to illustrate what we are looking for.<\/p>\n<p>Here is the Verilog code that implements the schematic:<\/p>\n<pre><code>  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<\/code><\/pre>\n<p>The first line declares a 2-bit register. We then define the register to be set top its value shifted left by one and the button input shifted in. The curly-braces indicate that the values within are to be concatenated together to form a wider bus. So the expression on the right has a width of three bits. This is then assigned back into the 2-bit shift register. This has the effect of setting bit zero of the shift register to the button input and bit one of the shift register to the previous value for bit zero.<\/p>\n<p>We could code the assignment to <em>btnl_rise<\/em> like this:<\/p>\n<pre><code>wire btnl_rise = btnl_shift[0] &amp; ~btnl_shift[1];<\/code><\/pre>\n<p>However,\u00a0I think the comparison to 2&#8217;b01 is much cleaner and better indicates to the reader what you&#8217;re really looking for.<\/p>\n<p>Go ahead and add code for the center and right buttons.<\/p>\n<h1>Starting and Stopping the Count<\/h1>\n<p>To start and stop the counter we just need to start and stop time. The thing that really does that in our design is the counter <em>count<\/em>. It just counts up to <em>ms_limit<\/em>-1, then wraps back to zero. It also generates the millisecond pulse signal <em>ms_pulse<\/em>. To get the counter to stop and start, we create a <em>count_enable<\/em> signal. This will initially be set to zero, and will then go high when <em>btnr_rise<\/em> occurs, and low when <em>btnc_rise<\/em> occurs.<\/p>\n<pre><code>  reg count_enable = 0;\r\n  always @(posedge clk)\r\n    if (btnr_rise)\r\n      count_enable &lt;= 1;\r\n    else if (btnc_rise)\r\n      count_enable &lt;= 0;\r\n<\/code><\/pre>\n<p>Now,\u00a0we modify the counter to hold whenever the enable signal is not active. Like this:<\/p>\n<pre><code>  integer count = 0;\r\n  wire ms_pulse = count == ms_limit-1;\r\n  always @(posedge clk)\r\n    if (count_enable)\r\n      if (ms_pulse)\r\n\tcount &lt;= 0;\r\n      else\r\n\tcount &lt;= count+1;\r\n<\/code><\/pre>\n<p>Go ahead and build the design and try it out. Can you start and stop the counter? There seems to be a bug. Can you figure out what it is? In case you didn&#8217;t actually try the design, the symptom is that you only see one digit displayed when the counter is stopped. Why is that?<\/p>\n<h2>Seeing Both Digits Again<\/h2>\n<p>If we stop the counter then we also stop the <em>ssdcat<\/em> output which lets us control both digits, causing our bug. What should we do? Simple: use another counter for that function. We could just duplicate the millisecond counter we had before and use that, but I want to try\u00a0something a little more efficient. The exact frequency for the <em>ssdcat<\/em> signal isn&#8217;t all that important: it only needs to be above about 60Hz and below 1kHz. Let&#8217;s use a counter which naturally wraps, and then not explicitly do a comparison to <em>ms_limit<\/em> to make it wrap early. Then, we&#8217;ll just use the most significant bit of the counter for the <em>ssdcat<\/em> output. How many bits should we use? Well, since\u00a0<em>ms_limit<\/em> is 100,000 in the FPGA and we can represent that in 17 bits, a 17-bit counter should work.<\/p>\n<p>Not so fast there. Remember,\u00a0<em>ms_limit<\/em> is a parameter. In our test bench we set it at\u00a0a much smaller number (100). If we use the real milliseconds in our simulation, which runs at a 1000x faster rate, then our <em>ssdcat<\/em> signal will hardly change at all in the simulation. So we should use our parameter for <em>ms_limit<\/em> in some way for this counter as well. The solution is to just make the counter big enough to count to the next higher power of two after <em>ms_limit<\/em>. Or, in other words, the number of bits for our counter should be the log of <em>ms_limit<\/em>. Here&#8217;s the code.<\/p>\n<pre><code>  reg [0:$clog2(ms_limit)-1] ssdcat_count = 0;\r\n  always @(posedge clk)\r\n    ssdcat_count &lt;= ssdcat_count+1;\r\n  \r\n  initial ssdcat = 0;\r\n  always @(posedge clk)\r\n    ssdcat &lt;= ssdcat_count[0];\r\n<\/code><\/pre>\n<p>Notice how, in the declaration for <em>ssdcat_count<\/em>, the bit width specification is the reverse of\u00a0what we normally do. A lot of people are confused as to what it means when you do this, but it is actually quite simple. When you specify a width for a bus in Verilog, the number before the colon is the number you are giving to the most significant bit, and the number after the colon is the number you are giving to the least significant bit. In this case, I am specifying that the most significant bit of the counter <em>ssdcat_count<\/em> is zero. This is convenient because later on, I want to assign the most significant bit to <em>ssdcat<\/em>. If I\u00a0do it this way, I can change the size of <em>ssdcat_count<\/em> later, and I won&#8217;t have to change the reference to the most significant bit\u2013 it will always be zero, no matter what the width is. Actually, we&#8217;re going to need to change the references in the <b>switch<\/b> statement that generates <em>digit<\/em> to use <em>ssdcat_count[0]<\/em> now, instead of <em>ssdcat_pre<\/em> which we have replaced.<\/p>\n<p>Let&#8217;s try the design out again.<\/p>\n<h1>Adding the Clear Button<\/h1>\n<p>To add the &#8220;clear&#8221; button, we obviously need to clear our counter. That&#8217;s pretty easy:<\/p>\n<pre><code>  integer count = 0;\r\n  wire ms_pulse = count == ms_limit-1;\r\n  always @(posedge clk)\r\n    if (btnl_rise)\r\n      count &lt;= 0;\r\n    else if (count_enable)\r\n      if (ms_pulse)\r\n\tcount &lt;= 0;\r\n      else\r\n\tcount &lt;= count+1;\r\n<\/code><\/pre>\n<p>However,\u00a0that doesn&#8217;t really do what we want. We&#8217;ll also need to clear the BCD digits. Let&#8217;s modify our <em>bcd_digit<\/em> module to add a reset signal. Add an input port called <em>reset<\/em>, then add the test for <em>reset<\/em> and clear the digit value when the <em>reset<\/em> input is high. Here is what I have:<\/p>\n<pre><code>  always @(posedge clk)\r\n    if (reset)\r\n      digit &lt;= 0;\r\n    else if (carry_in)\r\n      if (carry_out)\r\n\tdigit &lt;= 0;\r\n      else\r\n\tdigit &lt;= digit+1;\r\n<\/code><\/pre>\n<p>Now,\u00a0we just need to pass the <em>btnl_rise<em> signal <\/em><\/em>into the <em>bcd_digit<\/em> module. Let&#8217;s do that now. However, did you\u00a0notice how the nine instances of bcd_digit are almost all the same? We can use a Verilog <b>generate<\/b> construct to simplify these instantiations. The <b>generate<\/b> construct allows you to instantiate the <em>bcd_digit<\/em> modules inside a <b>for<\/b> loop. Here&#8217;s what it looks like:<\/p>\n<pre><code>  genvar i;\r\n  generate\r\n    for (i=0; i&lt;num_digits; i=i+1)\r\n      bcd_digit #(10) bcd_digit\r\n\t(\r\n\t .clk(clk),\r\n\t .carry_in(carry[i]),\r\n\t .reset(btnl_rise),\r\n\t .digit(time_digits[i*4+:4]),\r\n\t .carry_out(carry[i+1])\r\n\t );\r\n  endgenerate\r\n<\/code><\/pre>\n<p>The <b>genvar<\/b> statement declares a variable <em>i<\/em> that we will use in the generate for loop. The generate block is started with the keyword <b>generate<\/b>,\u00a0and concluded with the keyword <b>endgenerate<\/b>. We&#8217;ll use a for loop to iterate <em>num_digits<\/em> times, and inside the loop, we instantiate the <em>bcd_digit<\/em> module. Also, note the new syntax for selecting the part of <em>time_digits<\/em> we want the instance to drive. The syntax is <em>vector<\/em><b>[<\/b><em>bit<\/em><b>+:<\/b><em>width<\/em><b>]<\/b>. This syntax allows you to dynamically get to a part of a bus. In our case, the bit is given by the expression <em>i*4<\/em>, and the width is <em>4<\/em>. Why not just use the expression <code>time_digits[i*4+3:i*4],<\/code> you might ask? The answer is a little esoteric. Still, it&#8217;s worth explaining. Doing this type of selection only really makes sense when the width of the selection is constant. That is, it can&#8217;t change for a given set of parameters or local parameters. The simulator and synthesis tool must be able to figure out what the number is when the design is compiled, and it can&#8217;t change after that. The bit selection can be dynamic. By specifying a bit and a width, you allow the compiler to understand whether\u00a0the width is actually static. If you tell it i*4+3 and i*4, then the compiler would have to somehow figure out that (i*4+3)-(i*4) is equal to 3 for all possible values of <em>i<\/em>, so therefore the width must always be 4. It is just too difficult to write a compiler that can figure this out in all possible cases. So, because of this, we have the alternative syntax.<\/p>\n<p>There are, however, two issues with this code. The first is that we exceed the bounds of the carry signal when <em>i<\/em> has the value 8. We&#8217;ll try to drive the carry out, which is unused, into <em>carry[9]<\/em>, which\u00a0doesn&#8217;t exist. Before, we had simply left this unconnected. The simplest solution is to just declare <em>carry<\/em> to be one bit wider. So its declaration changes to this:<\/p>\n<pre><code>  wire [num_digits:0] carry;<\/code><\/pre>\n<p>That was easy. Here&#8217;s our next issue: two of our digits need a parameter value of six, not 10. How do we do that? My solution is to declare a <b>localparam<\/b> value, which indicates which digits should wrap at 10 and which should wrap at six. Now, we can use this parameter inside the for loop. Then we change the instantiation of <em>bcd_digit<\/em> to be a little smarter.<\/p>\n<pre><code>  localparam wrap_at_six = 9'b001010000;\r\n\r\n  genvar i;\r\n  generate\r\n    for (i=0; i&lt;num_digits; i=i+1)\r\n      bcd_digit #(wrap_at_six[i] ? 6 : 10) bcd_digit\r\n\t(\r\n\t .clk(clk),\r\n\t .carry_in(carry[i]),\r\n\t .reset(btnl_rise),\r\n\t .digit(time_digits[i*4+:4]),\r\n\t .carry_out(carry[i+1])\r\n\t );\r\n  endgenerate<\/code><\/pre>\n<h1>Files<\/h1>\n<p>Here are the 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\/tutorial8\/top.v\">top.v<\/a><\/li>\n<li><a title=\"bcd_digit.v\" href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/tutorials\/tutorial8\/bcd_digit.v\">bcd_digit.v<\/a><\/li>\n<li><a title=\"top.xdc\" href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/tutorials\/tutorial8\/top.xdc\">top.xdc<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, we will build on our counter from the last tutorial to add the ability to start, stop, and reset the time counter. Essentially, we&#8217;re going to make a stopwatch. Adding the Buttons The ZedBoard has five pushbutton &hellip; <a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial8\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":226,"menu_order":8,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-347","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/347","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=347"}],"version-history":[{"count":20,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/347\/revisions"}],"predecessor-version":[{"id":993,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/347\/revisions\/993"}],"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=347"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}