User Tools


This is an old revision of the document!


Sp20 - Arithmetic

In this lab you will implement a two's complement binary adder and demonstrate the ability to perform binary addition, inversion, and subtraction.

Learning Outcomes

  • Implement two's complement addition and subtraction
  • Develop a hierarchical design with three levels of hierarchy
  • Validate the circuit with a testbench

Preliminary

In this lab exercise you will be performing two's complement addition and subtraction. You will also be performing sign-extension on 8-bit numbers to generate 9-bit numbers. Answer the following questions to demonstrate your understanding of two's complement representation, sign extension, addition, and subtraction. You may want to refer to Chapter 9 of the textbook as you complete this laboratory.

Determine the decimal value for the following eight-bit two's complement binary numbers:

  • 10000100
  • 00011001
  • 01100111
  • 10100100

Extend each of the following numbers to nine bits using sign-extension: (Note that sign extension is described in section 3.3.1 of the textbook)

  • 10000100
  • 00011001
  • 01100111
  • 10100100

Negate each of the two's complement numbers from the previous question. (Note that negating two's complement numbers is described in section 3.3.2 of the textbook)

Perform addition with the following two's complement numbers: (Note that addition of two's complement numbers is described in section 3.3.3 of the textbook)

1)   110000100
   + 110011001
   
2)   001100100
   + 000011001

3)   001100111
   + 000100100

4)   001100111
   + 110100100

Perform subtraction of the following two's complement numbers. To do this, negate the second number and perform two's complement addition as described in section 3.3.4 of the textbook.

1)   110000100
   - 110011001
   
2)   001100100
   - 000011001

3)   001100111
   - 000100100

4)   001100111
   - 110100100

Exercises

Exercise #1 - 9-bit Binary Adder

In this first exercise, you will create a 9-bit two's complement full adder for implementing arithmetic. You will do this with two SystemVerilog files:

  1. A single-bit full adder module (FullAdd.sv)
  2. A multi-bit adder that combines nine single-bit adders (Add9.sv)

1-bit Full Adder

Start by creating a new Vivado project for this lab. Make sure you follow the steps in red to properly configure the error messages in your project. Next, create an empty SystemVerilog file named “FullAdd.sv” and add the following ports to this module as described in the table below:

Module Name: FullAdd
Port Name Direction Width Function
a Input 1 'A' operand input
b Input 1 'B' operand input
cin Input 1 Carry in
s Output 1 Sum output
co Output 1 Carry out output

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 1) 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.

# Simulate a=0, b=0, cin=0 for 10 ns
add_force a 0
add_force b 0
add_force cin 0
run 10 ns

# Simulate a=1, b=1, cin=1 for 10 ns
add_force a 1
add_force b 1
add_force cin 1
run 10 ns

Attach a PDF of your full adder SystemVerilog code

Include a copy of your full adder TCL simulation script in your lab report.

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.

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:

Module Name: Add9
Port Name Direction Width Function
a Input 9 'A' operand input
b Input 9 'B' operand input
cin Input 1 Carry in
s Output 9 Sum output
co Output 1 Carry out of last stage

After creating the empty module, create the needed local wires (you will need some, figure out where), and insert 9 instances of your FullAdd module into your Add9 module (as described in Section 9.1 of the textbook and as shown in the figure below). You should use the .port(wire) way of mapping ports on instances to your wires (see Program 11.1.2 in the textbook). Note that the co output of your Add9 is the carry-out of the last FullAdd instance.

Simulate the behavior of your 9-bit adder by creating a TCL script of your own. Provide at least two input conditions to test your adder. Rather than assigning each bit of an input with a single TCL command, you can assign all 9 bits of an input with a single “add_force” command as shown in the following example:

add_force a 11000101

Read the following tutorial. This tutorial contains additional examples and instruction for creating TCL files.

Include a copy of your 9-bit adder TCL file in your lab report.

Exercise 1 Pass-off: Show a TA your simulation for your Add9 module and explain how you know your circuit is correct. Also, show that your tcl script for the FullAdd module tested all possible combinations.

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.

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.

Module Name: arithmetic_top
Port Name Direction Width Function
sw Input 16 Switches (sw[15:8] = A input, sw[7:0] = B)
btnl Input 1 Left Button (Zero left operand)
btnr Input 1 Right Button (negation of right operand)
led Output 9 LED signals (result)

Before instancing your Add9.sv module, you will need to create the logic for its 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.

A block diagram of the overall design is shown below.

A description of the additional logic you are to implement is as follows. But, first, note that you do not need to create a new module declaration for the block marked “Logic” in the above diagram. It is just drawn that way to encapsulate all the logic you are going to need to create.

  • Switches sw[15:8] from the nexys4 board are interpreted as a twos-complement number and will be used as the left operand for addition/subtraction.
  • Switches sw[7:0] are also interpreted as a two's-complement number and will be used as the right operand for addition/subtraction.
  • The a and b inputs to your Add9.sv module are nine bits. But, you only have 8 bit inputs fromthe switches. You will need to sign extend both of the 8-bit inputs from the switches into 9-bit value for use by your Add9.sv module. Do you remember how to sign-extend a 2's complement number? In SystemVerilog you can use an assign statement to concat some of the original 8 bits into a 9 bit quantity and assign it to a new local signal you have declared with the logic keyword.
  • Under normal conditions (no buttons pressed), the two operands will be added together.
  • When the left button (btnl) is pressed, you need to zero out the left operand. Once again, this will require that you declare a new local signal using the logic keyword and use an assign statement to do the zeroing out.
  • When the right button (btnr) is pressed, you will need to perform a two's complement negation (see 3.3.2 of the book) of the right operand, which will cause the adder to compute left + -right. These two functions will be described in more detail below.

Subtraction

You must design your circuit so that you can perform subtraction, left minus right, when the right button is pressed. To perform subtraction, you simply need to perform a two's complement negation of the right operand. This involves two steps as described in section 9.2 of the textbook:

  1. Each bit of the right operand is XOR'd with the btnr signal before being connected to the Full Adder
  2. The carry-in of the first stage of the Full Adder should be set to a '1' when btnr is pressed (and '0' otherwise)

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'.

You can implement this conditional inverting and forcing the cin to a '1' using a couple of assign statements to and some local signals declared using the logic keyword.

Zeroing The **left** Operand

In addition to subtraction, you must design your circuit so that you can zero the left operand when the left button (btnl) is pressed. Do this by ANDing each bit of the left 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. Use an assign statement and local signal for this.

With the two buttons your top-level circuit should implement the following four functions:

btnr btnl Function
0 0 Addition (left+right)
0 1 Pass right (0+right)
1 0 Subtraction (left-right)
1 1 Pass -right (0-right)

Putting it all together

Now, 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 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.

In total, your top module should include:

  1. Logic for zeroing the left operand
  2. Logic for negating the right operand
  3. An instance of your nine-bit adder correctly connected to the previous logic elements and to the LEDs as outputs.

Simulating with a Testbench

Simulating your logic is very important and there are a variety of techniques you can use to simulate your modules. TCL files are a good way to find errors by providing simple scripts with a few test cases and can be used to find obvious problems early in the simulation phase. However, it is difficult to fully test complex digital circuits with TCL files.

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 tb_arithmetic.v file and simulate your module with this testbench. Read through the 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 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?

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!!!

Copy the testbench output from the TCL console to your lab report to show that there were no 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.

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 creating and 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 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.

Once you have added the XDC file to your project, synthesize your project.

Provide a summary of your synthesis warnings.

Perform the Running the Implementation Design Step step.

Summarize the size of your circuit (LUTs and I/Os).

Perform the Running the bitgen Design Step step. Download your circuit and verify that it works as expected.

Exercise #3 Pass-Off: No specific pass-off, just answer the questions above.

Final Passoff

Show a TA your circuit working on the Nexys4 board for final passoff. Answer any and all questions he might ask.

Final Questions

Attach PDF for your Add9 module to Learning Suite. (Make sure your SystemVerilog conforms to the lab SystemVerilog coding standards).

Attach PDF for your arithmetic_top module to Learning Suite.

How many hours did you work on the lab?

Provide any suggestions for improving this lab in the future.

Personal Exploration

There is no personal exploration for this lab.


TA Notes and Feedback

1)
Page 92