User Tools


This is an old revision of the document!


A PCRE internal error occured. This might be caused by a faulty plugin

====== ====== Stopwatch ====== In this lab you will create a digital stopwatch. As shown in the video below, the stopwatch will be displayed on the eight-digit seven-segment display. * Digits 7:6 will display minutes, digits 5:4 will display seconds, and digits 3:0 will display ten-thousandths of a second. * Switch 0 will start and stop the timer. * Button CPU_RESET will reset the timer. {{youtube>P_3wLuvT0Ws?rel=0&noborder&560x315}} =====Learning Outcomes===== * Create a sequential circuit using multiple counters. * Practice with SystemVerilog hierarchy and parameters. =====Preliminary===== === Seven Segment Controller=== Read about the [[resources:seven_seg|Seven Segment Controller]] module that is provided to you. The module cycles through the eight seven-segment digits, lighting up one at a time. * <color #ed1c24>Why doesn't the Seven Segment Controller just display all eight digits at the same time?</color> * <color #ed1c24>How long (in microseconds) is each digit illuminated for?</color> ===== Exercise 1: Modulus Counter ===== At the heart of your stopwatch will be a counter module for each of the eight digits. The counter should be a modulus counter, meaning it counts up to some predetermine value, then rolls over to 0 and continues counting. You will use a SystemVerilog ''parameter'', ''MOD_VALUE'' to indicate the modulus value. The counter should reach ''(MOD_VALUE-1)'' and then roll over to 0. This approach will allow us to use this module for digits that count 0-9, as well as digits that count 0-5. Consult the //Parameterization in Dataflow SystemVerilog// section in the textbook for an example on adding parameters to your SystemVerilog modules. {{ :labs:stopwatch:mod_counter.png?300 |}} ^ Module Name = mod_counter ^^^^ ^ Parameter ^ Default Value ^ Description ^^ | MOD_VALUE | 10 | Sets the modulus value of the counter. The counter will count from 0 up to (MOD_VALUE-1), then continue again at 0. || ^ Port Name ^ Direction ^ Width ^ Description ^ | clk | Input | 1 | 100 MHz Input Clock | | reset | Input | 1 | Reset | | increment | Input | 1 | When high, increment the counter value on the next clock edge. | | rolling_over | Output | 1 | High when the counter is about to roll-over (increment is high and counter is at the maximum value). | | count | Output | 4 | The counter value | What you need to do: * Create a Vivado project. * Write the SystemVerilog for the ''mod_counter'' module. * Create a tcl simulation script, and verify that your counter is working. Make sure your simulation is thorough; for example, check that the counter only counts when ''increment'' is high, and that the ''rolling_over'' output is high only in the appropriate condition. **Pass-Off:** Show the TA your simulation and explain how you tested the correctness of your module. ===== Exercise 2: Stopwatch Module ===== In this exercise you will create the stopwatch module which will consist of eight instances of your ''mod_counter'' module. Each of these instances will be responsible for generating the value for one digit of the display. Each ''rolling_over'' output is fed into the ''increment'' signal for the next most significant digit, as shown below. A counter is added to the module that rolls over every 0.0001s. When this counter rolls over, it should generate a **single cycle pulse** that is input to the ''increment'' signal for the least significant digit. The 0.0001s counter should increment every cycle that the ''run'' input is high, and reset to 0 if the ''reset'' input is high. Make sure you set the roll-over parameter for each of your ''mod_counter'' instances. The most significant two digits represent minutes, and the next two digits represent seconds; both should roll over at 59. The lower four digits represent fractions of a second, and should behave accordingly. <color #ed1c24>Given that the system clock is 100MHz, what value does your counter need to count to in order to roll over every 0.0001s?</color> ^ Module Name = stopwatch ^^^^ ^ Port Name ^ Direction ^ Width ^ Description ^ | clk | Input | 1 | 100 MHz Input Clock | | reset | Input | 1 | Active-high reset | | run | Input | 1 | High when timer should be running, 0 when stopped | | digit0 | Output | 4 | The value of the ten-thousandths of a second digit | | digit1 | Output | 4 | The value of the thousandths of a second digit | | digit2 | Output | 4 | The value of the hundredths of a second digit | | digit3 | Output | 4 | The value of the tenths of a second digit | | digit4 | Output | 4 | The value of the seconds digit | | digit5 | Output | 4 | The value of the tens of seconds digit | | digit6 | Output | 4 | The value of the minutes digit | | digit7 | Output | 4 | The value of the tens of minutes digit | {{ :labs:stopwatch:stopwatch.png?400 |}} Create a tcl simulation script to simulate the behavior of your ''stopwatch'' module. You will likely need to simulate for several milliseconds to check that the lower digits are functioning correctly. It will take too long to simulate the upper digits, so you will have to wait until next exercise to test it on the board. In your simulation, make sure to check that: * The digitX outputs increment appropriately. * Your least significant digit increments every 0.0001s. * The stopwatch only runs when the ''run'' input is high. * The digits roll over correctly. **Pass-Off:** Show the TA your simulation and explain how you tested the correctness of your module. ===== Exercise 3: Top-Level Module ===== In this exercise you will create the top-level module and test your stopwatch on the board. Create the top-level module as follows, and be sure to include an appropriate constraints file: ^ Module Name = stopwatch_top ^^^^ ^ Port Name ^ Direction ^ Width ^ Description ^ | clk | Input | 1 | 100 MHz Input Clock | | CPU_RESETN| Input | 1 | Active-low reset | | sw| Input | 1 | High when stopwatch should be running, 0 when stopped | | anode| Output | 8 | Seven-segment anode values, from Seven Segment Controller | | segment| Output | 8 |Seven-segment segment values, from Seven Segment Controller | Your top module should: * Instantiate both your ''stopwatch'' module, as well as a [[resources:seven_seg|SevenSegmentControl]] module. * Concatenate your digit values output from the ''stopwatch'' module and provide them to the ''dataIn'' input of the ''SevenSegmentControl''. * Turn on the appropriate decimal point. **Pass-off:** Show the TAs your stopwatch working on the board. =====Personal Exploration===== Here are some ideas for personal exploration in this laboratory: * Use additional switches to make your stopwatch run faster or slower than real-time. * In the first exercise, is the ''rolling_over'' output a mealy or moore-type output? Would the stopwatch work if the other type were used? What might be the advantages/disadvantages? * Modify your design to work as a countdown timer when sw1 is high, and a count-up timer when sw0 is low.