User Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
labs:funwithregisters [2019/10/11 02:11]
nelson [Exercise 3]
labs:funwithregisters [2020/04/28 17:02] (current)
nelson old revision restored (2020/02/14 13:11)
Line 1: Line 1:
-====== ​Under Development: ​Fun With Registers ======+====== ​Lab 6 - Fun With Registers ====== 
 +=== Prof Brent Nelson ​===
  
 In this lab you will do some experimentation with flip flops to learn how they operate. ​ You will create a single-bit loadable register, a 4-bit loadable register, and a counter. In this lab you will do some experimentation with flip flops to learn how they operate. ​ You will create a single-bit loadable register, a 4-bit loadable register, and a counter.
Line 7: Line 8:
   * Create a sequential circuit using FDCE flip-flop primitives   * Create a sequential circuit using FDCE flip-flop primitives
   * Learn how to organize multiple flip-flops into a register   * Learn how to organize multiple flip-flops into a register
-  * Create a clearable counter+  * Create a clearable, incrementable 4-bit counter
  
 ===== Preliminary =====  ===== Preliminary ===== 
Line 17: Line 18:
 The SystemVerilog example below demonstrates how to instance a single FDCE flip-flop into a design: The SystemVerilog example below demonstrates how to instance a single FDCE flip-flop into a design:
 <​code>​ <​code>​
-FDCE my_ff (.Q(ff_output),​ .C(clk), .CE(1'​b1),​ .CLR(1'​b0),​ .D(ff_input));​+FDCE my_ff (.Q(ff_output),​ .C(CLK), .CE(1'​b1),​ .CLR(1'​b0),​ .D(ff_input));​
 </​code>​ </​code>​
 The example shown above assigns a constant zero to the CLR input and a constant one to the clock_enable since we will not use those functions. ​ As a result, what you are getting is basically a flip flop with a D input, a clock input (C), and a Q output. ​ NOTE: this is a rising edge triggered flip flop. The example shown above assigns a constant zero to the CLR input and a constant one to the clock_enable since we will not use those functions. ​ As a result, what you are getting is basically a flip flop with a D input, a clock input (C), and a Q output. ​ NOTE: this is a rising edge triggered flip flop.
Line 25: Line 26:
 ==== Exercise #1 - 1-Bit Register ==== ==== Exercise #1 - 1-Bit Register ====
  
-For this exercise you will create a 1-bit register. It is exactly the circuit in Figure 16.4 in the textbook. ​ Begin this exercise by creating an empty SystemVerilog module with the following name and ports.+For this exercise you will create a 1-bit register. It is exactly the circuit in Figure 16.4 in the textbook. ​ Begin this exercise by creating ​a new Vivado project and an empty SystemVerilog module with the following name and ports.
  
-^ Module Name: blinky ​^^^^+^ Module Name: funRegister ​^^^^
 ^ Port Name ^ Direction ^ Width ^ Function ^ ^ Port Name ^ Direction ^ Width ^ Function ^
-clk | Input | 1 | Clock input | +CLK | Input | 1 | Clock input | 
-| Input | 1 | Data to be loaded into register |+DIN | Input | 1 | Data to be loaded into register |
 | LOAD | Input | 1 | Control signal to cause register to load | | LOAD | Input | 1 | Control signal to cause register to load |
 | Q | Output | 1 | Register output | | Q | Output | 1 | Register output |
 +| NXT | Output | 1 | The input to the register (we want to monitor it as an output of this module.) |
  
-Note that in Figure 16.4 there is an unlabelled signal --- it is the output of the MUX (which is also the input to the flip flop).  ​So, declare a logic signal ​for that wire.  Then, instance one FDCE flip-flop as shown above. ​ Then, add either a single dataflow statement or an always_comb block to implement the MUX logic. You should now have logic which implements the MUX and have the MUX wired to the ports on the FDCE.   This is called a "​loadable register"​. ​ On each rising edge of clk, If LOAD is high, then the flip flop will load what is on its input. ​ On the other hand, if LOAD is low, then the flip flop will load its old value.+Note that in Figure 16.4 there is an unlabelled signal --- it is the 
 +output of the MUX (which is also the input to the flip flop).  ​Label it in your textbook with the name 
 +NXT.  It is 
 +the NXT signal ​in the table above.  ​It is the value the 
 +flip flop will load on the next edge of the CLK signal (and thus the 
 +name NXT).  We want to see it in our design and so we are bringing it out of the module as an ouput 
 +so we can watch it. 
 + 
 +Then, instance one FDCE flip-flop as shown above. ​ Then, add either a single dataflow statement or an always_comb block to implement the MUX logic. You should now have logic which implements the MUX and have the MUX wired to the ports on the FDCE.   This is called a "​loadable register"​. ​ On each rising edge of CLK, If LOAD is high, then the flip flop will load what is on its DIN input. ​ On the other hand, if LOAD is low, then the flip flop will load its old value.
  
 SANITY CHECK: your code should have approximately 5 lines. ​ If it has a lot more you are likely on the wrong track... SANITY CHECK: your code should have approximately 5 lines. ​ If it has a lot more you are likely on the wrong track...
Line 50: Line 60:
 # set inputs low # set inputs low
 add_force LOAD 0 add_force LOAD 0
-add_force ​0+add_force ​DIN 0
  
 # add oscillating clock input with 10ns period # add oscillating clock input with 10ns period
-add_force ​clk {0 0} {1 5ns} -repeat_every 10ns +add_force ​CLK {0 0} {1 5ns} -repeat_every 10ns
- +
-# run 2ns so that input changes below are not +
-# coincident with clock edges. ​ Otherwise, the  +
-# waveforms are hard to understand +
-run 2ns+
  
 # run 3 cycles before loading anything # run 3 cycles before loading anything
Line 68: Line 73:
 add_force LOAD 0 add_force LOAD 0
  
-# change ​and run some time+# change ​DIN and run some time
 # notice that the register doesn'​t # notice that the register doesn'​t
 # load this new value because # load this new value because
 # the load signal is low # the load signal is low
-add_force ​1+add_force ​DIN 1
 run 20ns run 20ns
  
Line 79: Line 84:
 run 10ns run 10ns
 add_force LOAD 0 add_force LOAD 0
-add_force ​0+add_force ​DIN 0
 run 10ns run 10ns
  
Line 86: Line 91:
 # the register load them # the register load them
 # on succeeding clock edges # on succeeding clock edges
-add_force ​1+add_force ​DIN 1
 run 10ns run 10ns
 add_force LOAD 1 add_force LOAD 1
 run 10ns run 10ns
-add_force ​0+add_force ​DIN 0
 run 10ns run 10ns
 run 10ns run 10ns
 run 10ns run 10ns
-add_force ​1+add_force ​DIN 1
 run 10ns run 10ns
 run 10ns run 10ns
-add_force ​0+add_force ​DIN 0
 </​code>​ </​code>​
  
Line 103: Line 108:
 **Exercise 1 Pass-off:** No need to pass off this.  Just make sure it works in simulation before you proceed.\\ \\  **Exercise 1 Pass-off:** No need to pass off this.  Just make sure it works in simulation before you proceed.\\ \\ 
  
-==== Exercise #2 - 4-bit Register ​File ====+==== Exercise #2 - 4-bit Register ====
  
 In this exercise, you will modify your register to be 4 bits wide as shown in Figure 16.5 In this exercise, you will modify your register to be 4 bits wide as shown in Figure 16.5
-of the textbook. ​ To do this the changes to your code are minimal: (a) make the and Q signals 4 bits wide in your module definition and (b) instance a total of 4 FDCE flip flops and wire them up like the one in Exercise #1.  If you have used a ?: operator or an if-then-else statement to describe your MUX you probably shouldn'​t even have to change the MUX code.  ​+of the textbook. ​ To do this the changes to your code are minimal: (a) 
 +make the DIN, NXT, and Q signals 4 bits wide in your module definition and (b) instance a total of 4 FDCE flip flops and wire them up like the one in Exercise #1.  If you have used a ?: operator or an if-then-else statement to describe your MUX you probably shouldn'​t even have to change the MUX code.  ​
  
-After creating your register, simulate it by modifying your original TCL script. The only changes that you should have to make are to change the 1 and 0 values you drive into to be more interesting numbers between 0000 and 1111.  ​+After creating your register, simulate it by modifying your original TCL script. The only changes that you should have to make are to change the 1 and 0 values you drive into DIN to be more interesting numbers between 0000 and 1111.  ​
  
-<color red>​Provide a copy of your TCL script you used to simulate the register ​file.</​color>​+<color red>​Provide a copy of your TCL script you used to simulate the 4-bit register.</​color>​
  
-**Exercise 2 Pass-off:** Show a TA your code for your 4-bit register and your simulation waveform. Show that your register loads 4-bit values from when LOAD=1 and keeps its old value otherwise.\\ \\ +**Exercise 2 Pass-off:** Show a TA your code for your 4-bit register 
 +and your simulation waveform. Show that your register loads 4-bit 
 +values from DIN when LOAD=1 and keeps its old value otherwise.  Also 
 +show that the NXT signal does indeed reflect what the output of the 
 +MUX value should be. \\ \\ 
  
  
-==== Exercise 3 ====+==== Exercise ​#3 ====
 We are now going to modify your 4-bit register to create a counter and use the counter to blink some lights. We are now going to modify your 4-bit register to create a counter and use the counter to blink some lights.
  
 In addition to making registers to hold values, another good use of registers is to create counters. ​ Figure 16.7 from the textbook shows such a counter. ​ It can be cleared and it can be incremented under control of the signals CLR and INC. In addition to making registers to hold values, another good use of registers is to create counters. ​ Figure 16.7 from the textbook shows such a counter. ​ It can be cleared and it can be incremented under control of the signals CLR and INC.
  
-^ Module Name: blinky ​^^^^+^ Module Name: funRegister ​^^^^
 ^ Port Name ^ Direction ^ Width ^ Function ^ ^ Port Name ^ Direction ^ Width ^ Function ^
-clk | Input | 1 | Clock input |+CLK | Input | 1 | Clock input |
 | CLR | Input | 1 | Clear control signal | | CLR | Input | 1 | Clear control signal |
 | INC | Input | 1 | Increment control signal | | INC | Input | 1 | Increment control signal |
 | Q | Output | 4 | 4 bits of counter'​s register | | Q | Output | 4 | 4 bits of counter'​s register |
 +| NXT | Output | 4 | the register'​s 4 input bits  |
  
-Modify your module definition to now reflect this (erase the old stuff).  That is, do the following:+Modify your design ​(erase the old stuff you don't need and add the new stuff):
  
   * Change your module definition to reflect the signals in the table above.   * Change your module definition to reflect the signals in the table above.
-  * Create combinational logic using a ?: assignment ​which implements ​the MUX of Figure 16.7 in the textbook.+  * Create combinational logic using either ​a ?: dataflow ​assignment ​or an always_comb if statement to implement ​the MUX of Figure 16.7 in the textbook.
   * Wire the MUX up to the register'​s input and output wires.   * Wire the MUX up to the register'​s input and output wires.
  
 Modify your TCL script from above to exercise the counter. ​ First, clear the counter and then increment for a few cycles. ​ Then, clear it again and then increment it 20 or so cycles. ​ Raise and lower INC as you do this to observe that it only counts on rising clock edges where INC is true.  Finally, increment it enough times so that it then rolls back over to 0. Modify your TCL script from above to exercise the counter. ​ First, clear the counter and then increment for a few cycles. ​ Then, clear it again and then increment it 20 or so cycles. ​ Raise and lower INC as you do this to observe that it only counts on rising clock edges where INC is true.  Finally, increment it enough times so that it then rolls back over to 0.
  
-**Exercise 3 Pass-off:** Show a TA your code for your 4-bit counter and your simulation waveform. Show that your counter works as desired.\\ \\ +<color red>​Provide a copy of your TCL script you used to simulate the counter.</​color>​ 
 + 
 +**Exercise 3 Pass-off:** Show a TA your code for your 4-bit counter 
 +and your simulation waveform. Show that your counter works as 
 +desired.  Also show that the value of NXT is what you would expect.\\ \\ 
  
 ==== Exercise #4: Synthesize, Implement, and Test in Hardware ==== ==== Exercise #4: Synthesize, Implement, and Test in Hardware ====
-You are almost ​ready to synthesize, implement, and test in hardware.  ​However, before doing so there is one more thing that must be done.  In simulation it was easy to raise INC high for one clock cycle and then lower it again to get the counter to increment by just one.  When you download your circuit to the board and then push the INC button you will end up holding it down for millions of clock cycles. ​ Thus, each time you push the button in real life it will increment many many times. ​ To fix this, we need to condition the signal.+You are now ready to test your counter ​in hardware.  ​
  
-The figure below shows what we want.  Notice that each time the INC button signal goes from high to low, the CleanInc signal pulses ​for exactly one clock cycle.  ​This is what we want.  However, you don't know enough ​to design the circuit ​to do this and so one has been made available to you.  It has the following interface:+First, ​we need to create an XDC file for your design to declare ​the 
 +pin numbers ​for each top-level port of the design.  ​Below are the pins 
 +you should tie up and what to tie them to:
  
-^ Module Name: clean ^^^^ 
 ^ Port Name ^ Direction ^ Width ^ Function ^ ^ Port Name ^ Direction ^ Width ^ Function ^
-clk | Input | 1 | Clock input +CLK | Input | 1 | Tie to the center button (btnc) ​
-| Input | 1 | The button signal ​+CLR | Input | 1 | Tie to switch 0 
-bo Output ​| 1 | The cleaned up button signal (CleanInc in the waveform above) ​+INC Input | 1 | Tie to switch 1 
-| Q | Output | 4 | 4 bits of counter'​s register ​|+| Q | Output | 4 | Tie to led3-led0 | 
 +| NXT | Output ​| 4 | Tie to led11-led8 ​|
  
-You can get the file here.  ​Add it to your project.+**Note**: ​ Your constraints ​file will instruct Vivado to connect the ''​CLK''​ to a button; however, Vivado knows that this is not a true clock pin and will report an error.  ​In order to ignore this, you will need to add the following line to your constraints file, which you can add immediately after the constraint that connects ''​CLK''​ to the button:
  
-Now, instance it like this:+''​set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets CLK_IBUF];''​
  
-  clean C0(.clk(clk).b(INC).bo(CleanInc));​ +Even with this inserted you will get a Critical Warningwhich you can ignore ​(at least it is now a warning and not an error).
-   +
-Finally, you need to replace where you directly wired the INC signal up above to the MUX select line with the CleanInc signal. ​ The resulting ​ circuit should look like this:+
  
-Note that in this step we will NOT create ​top-level module ​What ​you just created IS your top level module.  ​So now create an XDC file for your design to declare ​the pin numbers for each top-level port of the design.+Perform the steps of Synthesis, Implementation,​ and Bitstream 
 +Generation. Download your design and demonstrate ​that it is working 
 +properly. ​ When you turn on CLR you should immediately see that NXT is 
 +0.  When you then push the CLK button the flip flop will actually load 
 +that value and will become ​0 and you will see that on the LEDs. 
 +Then, when you then deassert CLR and assert INC you should see that NXT 
 +becomes Q+1.  ​When you then push the CLK button you should see the 
 +counter increment and then immediately NXT will become the new value 
 +of 1 plus the new Q value.
  
-This lab is the first time you will be attaching ​clock signalYou will need **create_clock** command ​to declare ​the frequency of the clock (this is so the tools know what they are dealing with and ensure that the circuitry they produce can run at that rate)These commands ​are available in the master XDC file and can be used by uncommenting it in your project-specific XDC file+NOTE: This is the only lab where we will tie the CLK input to button  
- +In all later labs it will be tied to 100MHz input to the FPGA. 
-<code TCL> +You may notice that, in actuality, your counter may increment more than once when you 
-set_property ​-dict { PACKAGE_PIN E3    IOSTANDARD LVCMOS33 } [get_ports { clk }]; #​IO_L12P_T1_MRCC_35 Sch=clk100mhz +push the CLK button. ​ Why?  It is because we have tied the CLK input to a button. 
-create_clock ​-add -name sys_clk_pin ​-period 10.00 -waveform {5} [get_ports {clk}]; +In the real-world buttons and switches 
-</​code>​ +don't transition cleanly from open to closed or from closed to open. 
- +As they are opening or closing they may "​bounce",​ meaning they may 
-In addition, tie the CLR and INC signals to two different push buttons and tie the Q output bits to leds 3-0. From previous labs you should know how to do this.   +open and close rapidly ​in succession Thus, when you push your CLK 
- +button the circuit might actually get multiple clock edges like this: 
-Perform the steps of Synthesis, Implementation, ​and Bitstream Generation. Download ​your design and demonstrate that it is working properly.  ​When you push CLR the count should go to 0.  ​When you push INC the counter should increment once.  ​Experiment with your counter long enough ​to convince yourself ​it really works.+0-1-0-1-0-1-0.  ​In that case your circuit would see 3 rising clock 
 +edges and your counter would increment by 3.  ​At other times it might 
 +just go 0-1-0 and your counter will increment by 1.  Experiment with it 
 +to see just how "​bouncy"​ the button ​is on the board you are using.  ​It 
 +might be pretty bad or it might hardly ever bounce.  ​In a later lab we 
 +will design a circuit to clean up the button output by ignoring the 
 +bouncing.  ​But, for now we have to live with it.
  
 AWESOME! ​ You have designed your first sequential circuit. AWESOME! ​ You have designed your first sequential circuit.
Line 176: Line 205:
  
 Pass off your laboratory by demonstrating the following to the TA: Pass off your laboratory by demonstrating the following to the TA:
-  * Pass off Exercise ​3 (and show it working on the board)+  * Pass off Exercise ​4 by showing ​it working on the board
  
 <color red>How many hours did you work on the lab?</​color>​ <color red>How many hours did you work on the lab?</​color>​
Line 185: Line 214:
 ===== Personal Exploration ===== ===== Personal Exploration =====
  
-Here are some ideas for personal exploration in this laboratory:+Choose one of the following ​for personal exploration in this laboratory:
   * Make your counter wider and wire up to additional LEDs.   * Make your counter wider and wire up to additional LEDs.
-  * Wire in a copy of your 7-segment decoder from last week and have the 4-bit counter value displayed on the 7-segment display. ​ By the way, this is way cooler than just making your counter wider...+  * Wire in a copy of your 7-segment decoder from last week and have the 4-bit counter value displayed on the 7-segment display. ​ By the way, this is way cooler than just making your counter wider... ​ :-)
  
 <color red>​Describe your personal exploration activities.</​color>​ <color red>​Describe your personal exploration activities.</​color>​
Line 223: Line 252:
  
 [[labs:​ta:​registerfile|TA Notes and Feedback]] [[labs:​ta:​registerfile|TA Notes and Feedback]]
 +