This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
labs:sp20_arithmetic [2020/04/22 14:05] nelson [Exercise #2 - Top-Level Design] |
labs:sp20_arithmetic [2020/05/14 13:08] (current) nelson |
||
---|---|---|---|
Line 18: | Line 18: | ||
* 10000100 | * 10000100 | ||
* 00011001 | * 00011001 | ||
- | * 01100111 | + | |
- | * 10100100 | + | |
<color red> | <color red> | ||
Extend each of the following numbers to nine bits using //sign-extension//: | Extend each of the following numbers to nine bits using //sign-extension//: | ||
Line 26: | Line 24: | ||
* 10000100 | * 10000100 | ||
* 00011001 | * 00011001 | ||
- | * 01100111 | + | |
- | * 10100100 | + | |
<color red> | <color red> | ||
Negate each of the two's complement numbers from the previous question. | Negate each of the two's complement numbers from the previous question. | ||
Line 44: | Line 40: | ||
2) 001100100 | 2) 001100100 | ||
+ 000011001 | + 000011001 | ||
- | |||
- | 3) 001100111 | ||
- | + 000100100 | ||
- | |||
- | 4) 001100111 | ||
- | + 110100100 | ||
</code> | </code> | ||
Line 62: | Line 52: | ||
2) 001100100 | 2) 001100100 | ||
- 000011001 | - 000011001 | ||
- | |||
- | 3) 001100111 | ||
- | - 000100100 | ||
- | |||
- | 4) 001100111 | ||
- | - 110100100 | ||
</code> | </code> | ||
Line 78: | Line 62: | ||
- A single-bit full adder module (FullAdd.sv) | - A single-bit full adder module (FullAdd.sv) | ||
- A multi-bit adder that combines nine single-bit adders (Add9.sv) | - A multi-bit adder that combines nine single-bit adders (Add9.sv) | ||
+ | |||
+ | This is a classical hierarchical design: you will create a simple 1-bit full adder module and you will then create a new module and instance 9 of your 1-bit adders inside it. | ||
+ | |||
=== 1-bit Full Adder === | === 1-bit Full Adder === | ||
Line 92: | Line 79: | ||
Once you have created the empty module with the ports outlined above, create the | Once you have created the empty module with the ports outlined above, create the | ||
- | single-bit **full adder** cell as shown in Figure 9.2 ((Page 92)) of the text. Like the diagram, your circuit should include a 3-input XOR gate, three 2-input AND gates, and a 3-input OR gate. **Note** that you must use //structural// SystemVerilog to create this full adder cell. Although there are easier ways to create adder circuits using dataflow SystemVerilog, you are required to use structural SystemVerilog for this lab. | + | single-bit **full adder** cell as shown in Figure 9.2 ((Page 92)) of the text. |
+ | Like the diagram, your circuit should include a 3-input XOR gate, three 2-input AND gates, and a 3-input OR gate. | ||
+ | **Note** that you must use //structural// SystemVerilog to create this full adder cell. | ||
+ | Although there are easier ways to create adder circuits using dataflow SystemVerilog, you are required to use structural SystemVerilog for this lab. | ||
- | Once you have created your circuit, simulate the full adder by testing all possible input conditions. Create a TCL file to provide the stimulus for this simulation. The TCL code below simulates two of the eight conditions. | + | And, remember, the coding standard says you must either use meaningful signal names or add comments to describe what the local signals you declare with the 'logic' keyword are. |
+ | For structural designs like this, coming up with meaningful signal names can be klunky (some students use names like aANDb, aANDcin, bANDcin, ...). In later labs | ||
+ | this can be come totally unwieldy. | ||
+ | You might just consider using comments like this: | ||
+ | |||
+ | <code> | ||
+ | // The outputs of the 3 AND gates in the full adder | ||
+ | logic a1, a2, a3; | ||
+ | </code> | ||
+ | |||
+ | Once you have created your circuit, simulate the full adder by testing all possible input conditions. | ||
+ | Create a TCL file to provide the stimulus for this simulation. The TCL code below simulates two of the eight conditions. | ||
<code> | <code> | ||
Line 110: | Line 111: | ||
</code> | </code> | ||
+ | <color red>Attach a PDF of your full adder SystemVerilog code</color>\\ | ||
<color red>Include a copy of your full adder TCL simulation script in your lab report.</color> | <color red>Include a copy of your full adder TCL simulation script in your lab report.</color> | ||
Line 116: | Line 118: | ||
=== 9-Bit Adder === | === 9-Bit Adder === | ||
- | Unlike the previous laboratory assignment, this laboratory will involve **hierarchy**. This is covered in-depth in Chapter 11, but will be briefly explained here. | + | As mentioned above, this lab will involve **hierarchy**. This is covered in-depth in Chapter 11, but will be briefly explained here. |
- | A circuit with hierarchy is a circuit that contains modules within modules. In many complex digital logic circuits there are many levels of hierarchy. In this circuit you will have three levels of hierarchy - your FullAdd, your Add9, and a top level module. For this exercise you will create the Add9 which will **instance** 9 FullAdd modules. Program 11.1.1 in your textbook gives an example of instancing modules. In this case, three "mux21" modules are instanced to build a "mux41" module. | + | A circuit with hierarchy is a circuit that contains modules within modules. |
+ | In many complex digital logic circuits there are many levels of hierarchy. | ||
+ | In this circuit you will have three levels of hierarchy - your FullAdd, your Add9, and a top level module. | ||
+ | For this exercise you will create the Add9 which will **instance** 9 FullAdd modules. | ||
+ | Program 11.1.1 in your textbook gives an example of instancing modules. | ||
+ | In this case, three "mux21" modules are instanced to build a "mux41" module. | ||
- | The next step in this exercise is to create a 9 bit ripple-carry adder. Create a new SystemVerilog file named Add9.sv and add the following ports as shown in the table below: | + | The next step in this exercise is to create a 9 bit ripple-carry adder. Create a new SystemVerilog |
+ | file named Add9.sv and add the following ports as shown in the table below: | ||
^ Module Name: Add9 ^^^^ | ^ Module Name: Add9 ^^^^ | ||
Line 153: | Line 161: | ||
==== Exercise #2 - Top-Level Design ==== | ==== Exercise #2 - Top-Level Design ==== | ||
- | For this exercise you will create a top-level design that instances your 9-bit adder and connects your adder to the switches and LEDs. The adder will have two input operands, **A** and **B** (driven by the switches) and you will also use some buttons to implement a number of different arithmetic operations. | + | For this exercise you will create a top-level design that instances your 9-bit adder and connects your adder to the switches and LEDs. |
Both operands will be interpreted as two's complement numbers. Begin your design by creating a top-level module with the following name and ports. | Both operands will be interpreted as two's complement numbers. Begin your design by creating a top-level module with the following name and ports. | ||
Line 160: | Line 168: | ||
^ Port Name ^ Direction ^ Width ^ Function ^ | ^ Port Name ^ Direction ^ Width ^ Function ^ | ||
| sw | Input | 16 | Switches (sw[15:8] = A input, sw[7:0] = B) | | | sw | Input | 16 | Switches (sw[15:8] = A input, sw[7:0] = B) | | ||
- | | btnl | Input | 1 | Left Button (Zero **A** operand) | | ||
- | | btnr | Input | 1 | Right Button (negation of **B** operand) | | ||
| led | Output | 9 | LED signals (result) | | | led | Output | 9 | LED signals (result) | | ||
- | Before instancing your Add9.sv module, you will need to create the logic for the **A** and **B** inputs to your module. The descriptions below will guide you through the process of designing this logic. After you create this logic, you will then instance your Add9.sv module. | + | **NOTE: the name of the module and of the ports are crucial - use what is in the table above. |
+ | The reason is that the testbench you will use below to prove your circuit works will rely on it being called 'arithmetic_top' and on the ports | ||
+ | having the names above. | ||
+ | And, just for uniformity sakes, call your file 'arithmetic_top.sv' - the convention is typically to have them be the same to minimize confusion.** | ||
A block diagram of the overall design is shown below. | A block diagram of the overall design is shown below. | ||
- | {{:labs:lab_4:img_0071.jpg|}} | + | {{:labs:lab_4:lab4top.png?6700|}} |
- | A description of the additional logic you are to implement is as follows. | + | This is different from how we did things in the last lab, why? If you recall, in the last lab you took a copy of the master .xdc file for the board, uncommented out the switches and lights you wanted to use and then changed the names of the signals mapped to those switches and lights so it would match your design (A, B, C, O1, O2, ...). This week's lab represents an alternate approach. Here, your top level SystemVerilog module will have names that match what is in the .xdc file and so all you have to do is uncomment the appropriate lines in the .xdc file. |
- | * Switches sw[15:8] from the nexys4 board are interpreted as a twos-complement number and will be used as the **A** operand for addition. Switches sw[7:0] are also interpreted as a two's-complement number and will be used as the **B** operand for addition. The inputs to your Add9.sv module are nine bits and you will need to sign extend both the 8-bit A and B inputs from the switches into 9-bit value for use by your Add9.sv module. | + | This has the advantage that your SystemVerilog code uses names like 'sw' and 'led' for the signal names, making it clear during the design and simulation stage just what signal is connected where to the board. |
+ | Importantly, it also has the benefit that you can put additional logic into this top level module. | ||
+ | In this case you will put logic into the top level module to do the sign extension of your two inputs. | ||
+ | How should you do that? There are two ways: (1) you could figure out how to sign extend as an expression that you pass to the Add9 instance you create or | ||
+ | (2) you could declare two new signals that are 9 bits wide, use 'assign' statements to sign extend your two inputs to those signals, | ||
+ | and then wire those new signals up to your Add9 module. Either way, you do not create a 'Sign extend' module - it is just some logic in your top module. | ||
- | Under normal conditions (no buttons pressed), the two operands will be added together using your 9-bit adder. When the left button (btnl) is pressed, you need to zero out the A operand. When the right button (btnr) is pressed, you will need to perform a two's complement negation (see 3.3.2) of the B operand, which will add A and a negative B. These two functions will be described in more detail below. | + | Also, the carry out of your adder is not used, but you do need to connect something to it. So, declare a wire in your top-level module and attach it to the carry out of your adder. |
- | + | But, do not connect it to anything else - the synthesis tool will recognize that it is unused and throw it away. | |
- | === Subtraction === | + | |
- | + | ||
- | You must design your circuit so that you can perform **subtraction**, A-B, when the right button is pressed. To perform subtraction, you simply need to perform a two's complement negation of the **B** operand. This involves two steps as described in section 9.2 of the textbook ((page 93)). | + | |
- | - each bit of the B operand is XOR'd with the btnr signal before being connected to the Full Adder | + | |
- | - the carry-in of the first stage of the Full Adder should be set to a '1' when btnr is pressed | + | |
- | + | ||
- | Your circuit will look much like Figure 9.4 in the text with the difference being that Figure 9.4 uses an inverted **addSub#** signal which subtracts when it is '0', while your circuit uses the **btnr** signal which subtracts when it is '1'. | + | |
- | + | ||
- | /* have them add an exercise to understand how this circuit works? | + | |
- | + | ||
- | ^ btnr ^ B ^ XOR ^ | + | |
- | | 0 | 0 | 0 (B) | | + | |
- | | 0 | 1 | 1 (B) | | + | |
- | | 1 | 0 | 1 (~B) | | + | |
- | | 1 | 1 | 0 (~B) | | + | |
- | + | ||
- | */ | + | |
- | + | ||
- | === Zeroing A === | + | |
- | + | ||
- | In addition to subtraction, you must design your circuit so that you can zero the **A** operand when the left button (btnl) is pressed. Note that the signals from the switches aren't being set to zero, rather we are modifying an intermediate signal. Do this by ANDing each bit of the **A** operand with ~btnl and connecting the result to your Add9 module. This way, when btnl = 0 the value of A will be passed to the Full Adder and when btnl = 1 nine zeroes will get passed instead. | + | |
- | + | ||
- | With the two buttons your top-level circuit should implement the following four functions: | + | |
- | + | ||
- | ^ btnr ^ btnl ^ Function ^ | + | |
- | | 0 | 0 | Addition (A+B) | | + | |
- | | 0 | 1 | Pass B (0+B) | | + | |
- | | 1 | 0 | Subtraction (A-B) | | + | |
- | | 1 | 1 | Pass -B (0-B) | | + | |
- | + | ||
- | === Putting it all together === | + | |
- | + | ||
- | Now you can instance your Add9.sv module into the top-level design. | + | |
- | The 'sum' output of your Add9.sv module should be attached directly to the 'led' outputs of your top-level circuit (this way, your result will visible on nine of the Nexys4 LEDs). The carry out of your adder is not used. Declare a wire in your top-level module and attach it to the carry out of your adder. Do not connect this wire to anything else - the synthesis tool will recognize that it is unused. | + | |
- | + | ||
- | In total, your top module should include: | + | |
- | - Logic for zeroing the **A** operand | + | |
- | - Logic for negating the **B** operand | + | |
- | - An instance of your nine-bit adder correctly connected to the previous logic elements and to the LEDs as outputs. | + | |
+ | Similarly, the carry in of your adder needs to be tied to a '0' value. You have two ways of doing this. | ||
+ | The first is to simply tie a 1'b0 as the carry in to your Add9 module when you instance it in 'arithmetic_top'. The second is to declare a wire for this purpose | ||
+ | and use an 'assign' statement to assign it to a constant '0' and then wire that signal into 'arithmetic_top'. | ||
+ | It is your choice of how to do this. | ||
=== Simulating with a Testbench === | === Simulating with a Testbench === | ||
Line 224: | Line 203: | ||
Digital circuits are often tested with special SystemVerilog modules called **testbenches**. Testbenches are SystemVerilog files that are used to //test// your circuit and are not used for designing new logic circuts. Testbenches are written differently than synthesizable SystemVerilog and are used to provide more thorough testing of digital circuits than is possible with TCL files. In this lab, and all future labs, you will be given a SystemVerilog testbench file that will test your circuit. | Digital circuits are often tested with special SystemVerilog modules called **testbenches**. Testbenches are SystemVerilog files that are used to //test// your circuit and are not used for designing new logic circuts. Testbenches are written differently than synthesizable SystemVerilog and are used to provide more thorough testing of digital circuits than is possible with TCL files. In this lab, and all future labs, you will be given a SystemVerilog testbench file that will test your circuit. | ||
- | When you have completed your top-level design and removed all syntax errors, simulate your design manually to convince yourself that your circuit is working properly. Once you believe your circuit is working properly, download the following {{ :labs:tb_arithmetic.v }} file and simulate your module with this testbench. Read through the [[tutorials:testbench_tutorial|testbench tutorial]] to learn how to add and use a testbench for your verification. The testbench will run automatically, but you might need additional run time for it to finish. To do this, simply type a "run all" command into the TCL command line. The simulation will stop when the testbench ends. | + | When you have completed your top-level design and removed all syntax errors, simulate your design manually to convince yourself that your circuit is working properly. Once you believe your circuit is working properly, download the following {{ :labs:tb_arithmetic.sv }} file and simulate your module with this testbench. Read through the [[tutorials:testbench_tutorial|testbench tutorial]] to learn how to add and use a testbench for your verification. The testbench will run automatically, but you might need additional run time for it to finish. To do this, simply type a "run all" command into the TCL command line. The simulation will stop when the testbench ends. |
+ | |||
+ | The testbench will simulate your circuit's operation to make sure that the output of your circuit is correct for each case. | ||
+ | The testbench will continue until it prints out a **Simulation done** message indicating the number of errors that were found. Make sure you have 0 | ||
+ | errors before proceeding to the next exercise. | ||
- | The testbench will simulate your circuit's four different modes of operation to make sure that the output of your circuit is correct for each case. The testbench will continue until it prints out a **Simulation done** message indicating the number of errors that were found. Make sure you have 0 errors before proceeding to the next exercise. | + | **What to do if it doesn't work? How do I debug it?** |
- | <color red>Copy the testbench output from the TCL console to your lab report. </color> | + | When you simulate a top-level module, all you see are the top level ports and top level local signals. What if you want to see signals inside a sub-module (like your 9-bit adder)? |
+ | * Once simulation is running, look in the left-center of the screen for a //Scope// tab. | ||
+ | * Click it | ||
+ | * You can now navigate the hierarchy to find the submodule you want to see the internal signals for. | ||
+ | * Drag that submodule into the bottom left of the waveform view window, below the other signal names. | ||
+ | * If you now re-run the simulation you will see all the submodule's signals as well, and should be able to nearly //instantly// figure out what signals are not doing what you want. This is infinitely better than guessing or just scratching your head... | ||
+ | * And, you can save this new waveform window for later use using the menu. DO IT!!! | ||
+ | <color green>Copy the testbench output from the TCL console to your lab report to show that there were no errors. </color> | ||
**Exercise 2 Pass-off:** Show a TA your top level code and explain how you connected the inputs to your Add9 module. Also, show that the testbench did not report any errors.\\ \\ | **Exercise 2 Pass-off:** Show a TA your top level code and explain how you connected the inputs to your Add9 module. Also, show that the testbench did not report any errors.\\ \\ | ||
Line 235: | Line 225: | ||
==== Exercise #3 - Synthesize, Implement and Download ==== | ==== Exercise #3 - Synthesize, Implement and Download ==== | ||
- | For this final exercise, you can proceed with the implementation and downloading of your design. Begin this process by [[tutorials:making_an_xdc_file|creating]] and [[tutorials:adding_an_xdc_file|adding]] an XDC constraints file. Your file should have entries for all 16 switches, two button inputs (btnr and btnl) and 9 led outputs. The easiest way to create this file is to start with the {{ :resources:nexys4_220.xdc|master .xdc}} file and modify it with the signals you will use by uncommenting the ports you use and making sure the port names and your top-level signal names match. | + | For this final exercise, you can proceed with the implementation and downloading of your design. Begin this process by [[tutorials:making_an_xdc_file|creating]] and [[tutorials:adding_an_xdc_file|adding]] an XDC constraints file. Your file should have entries for all 16 switches and 9 led outputs. |
+ | The easiest way to create this file is to start with the {{ :resources:nexys4_220.xdc|master .xdc}} file and modify it with the signals you will use by uncommenting the ports | ||
+ | you use and making sure the port names and your top-level signal names match (they should if you followed the instructions above). | ||
Once you have added the XDC file to your project, [[tutorials:synthesis|synthesize]] your project. | Once you have added the XDC file to your project, [[tutorials:synthesis|synthesize]] your project. | ||
Line 250: | Line 242: | ||
- | ===== Finally... ===== | + | ===== Final Passoff ===== |
+ | <color green> | ||
+ | Attach the link to a video (preferred) at some site like Youtube, Dropbox, etc. of your circuit working on the Nexys4 board for final passoff. Alternatively, attach the video itself if it will fit. | ||
+ | </color> | ||
- | Show a TA your circuit working on the Nexys4 board for final passoff. | + | <color green> |
+ | There are now some additions to the [[:verilog_coding_standards|Verilog Coding Standards]] regarding how to attach a video. Please follow them as you attach. | ||
+ | </color> | ||
- | <color red>How many hours did you work on the lab?</color> | + | <color green> |
+ | Show that it works for a variety of values. Show that all the bit positions work (don't just choose small numbers to add). For the 4 cases below, do the addition with multiple pairs of numbers for each case: | ||
+ | </color> | ||
- | <color red>Provide any suggestions for improving this lab in the future.</color> | + | - <color green>Add two positive numbers</color> |
+ | - <color green>Add a positive and a negative number</color> | ||
+ | - <color green>Add two negative numbers</color> | ||
+ | - <color green>Do an addition where the carry propagates all the way to the left position.</color> | ||
- | <color red>Submit your SystemVerilog modules using the code submission on Learning Suite.</color> (Make sure your SystemVerilog conforms to the lab SystemVerilog coding standards). | + | <color green> |
+ | In the end, if the TA is convinced that you have demonstrated that all parts of your adder work, you will get full credit. | ||
+ | </color> | ||
- | ===== Personal Exploration ===== | + | =====Final Questions===== |
+ | |||
+ | <color red>Attach PDF for your Add9 module to Learning Suite.</color> (Make sure your SystemVerilog conforms to the lab SystemVerilog coding standards). | ||
+ | |||
+ | <color red>Attach PDF for your arithmetic_top module to Learning Suite.</color> | ||
+ | |||
+ | <color red>How many hours did you work on the lab?</color> | ||
+ | |||
+ | <color red>Provide any suggestions for improving this lab in the future.</color> | ||
- | There is no personal exploration for this lab. | ||
/* | /* | ||
Line 295: | Line 306: | ||
---- | ---- | ||
+ | /* Problems helped with: | ||
+ | - Top level had pin (cout) which was not mapped to a board level port. | ||
+ | - Should have made it a local signal. | ||
+ | */ | ||
[[labs:ta:arithmetic|TA Notes and Feedback]] | [[labs:ta:arithmetic|TA Notes and Feedback]] |