Lesson 3: 4-bit adder

In this lab, you will use ISE to build hierarchical logic circuits handling unsigned integers by assembling basic logic gates. You will verify by simulation then by execution on the board that the functionality of the circuits effectively match your specifications. It is always via the interactive interface Isim, the simulation tool available with ISE, that you will program the simulation. Running on the board reuses the concepts introduced in the previous two lessons.

Your first calculator - a 4-bit adder

A combinatorial circuit allows to produce one or more bit values ​​from the input signals. When we give a meaning to this binary coding, electronic circuit produces without explicit knowledge, information that can be much more complex than "0" or "1". The assembly of several signals allows to represent a set of values ​​whose cardinality is exponential in fonction of the number of signals. With 4 signal outputs, you can represent a set of 16 elements. One of the most intuitive sets remains a subset of unsigned integers as we've used in the lab 1. With 4 bits you represented 0 1 2 3 ... E F. The same assembly signals could also represent a set of EC countries: France, Belgium, .... Poland. I stress the fact that it is your responsibility to give meaning to the results produced by your system, for example by reading the LEDs of your board with a certain interpretation of their meaning.

Required knowledge

Logic gates, Boolean algebra.

Objectives

In this lab, you will use ISE to build hierarchical logic circuits handling unsigned integers by assembling basic logic gates. You will verify by simulation then by execution on the board that the functionality of the circuits effectively match your specifications. It is always via the interactive interface Isim, the simulation tool available with ISE, that you will program the simulation. Running on the board reuses the concepts introduced in the previous two lessons.

The project

You will design a system able to calculate the sum of two integers coded on 4 bits. The addition is obviously done in binary, but it is closely similar to the decimal addition you did on a blackboard in primary school. You align the two numbers of your addition and start from the left by adding the two numbers of the units. This addition potentially produces a carry that needs to be taken into account during the addition of tens etc. ... In binary, one must be able to add two binary signals, but also three binary signals in order to take into account the carry which can be produced by the previous calculation. That's what you're going to build step by step. Each step will be simulated and validated on the Nexys boards.

A half-adder

A half-adder (the meaning of the name will be understood later) performs addition of two bits a and b and produces the sum s and a carry c. Here is the truth tables of s and c.

You begin to get used, you'll start by creating a project TP3 via File> New Project.

Figure 30 project creation

Add a schematic file to your, Project> New Source named toplevel that will contain successive versions of your circuit.

Figure 31 toplevel creation

The file toplevel.sch is then available as the root of your design, we will come back to it later. The first step is to create a symbol demiadd. As for toplevel, add a new source Project> New Source of type schematic to the project. In the relevant window, you can enter the half-adder circuit with the required logic gates, wires and I/O Markers: a, b inputs and s and c outputs. Once saved, you have to create your own symbol directly in Design Utilities.

Figure 32 demiadd circuit

Always start with the simulation!

Even for such a simple circuit the component by component simulation remains a good design practice. Thus, I suggest you to start Isim simulator on demiadd and to verify that the 4 combinations of a and b lead to the expected results on s and c.

Figure 33 Launch demiadd simulation

Figure 34 simulation results of demiadd

Once the simulation is correct, go back to the Implementation mode and create the associated symbol by Create Schematic Symbol.

Verification on the card

You could directly instantiate demiadd on the board. I suggest instead to pass through an instantiation of demiadd in toplevel where there will be specified the input/output ports related to the Nexys boards. Start with the ports. Create two vertical bus named switches(7:0) and led(7:0). Place the component symbol demiadd between the two buses. Finally with the Add Bus Tap button, you'll be able to connect the wires of the switch and led buses to the 4 ports of demiadd. I remind you of the procedure: Click the Add Bus Tap button, select the bus to which you want to connect by clicking on it a first time. You may change the name of the wire net name and finally click the port (or other bus) which you want to connect to this Bus Tap. You have to be careful in these connections, return to Lesson 1 if necessary. Finally we need to create the two I/O Markers on the switches and led buses. You should get the following diagram.

Figure 35 Toplevel for halfadder

You still have to create the UCF file. I suggest you get the one of Lab 1. To do this in Project> Add Copy of Source, select the file S3.ucf from your ​​TP1 project. Go for the implementation mode, S3.ucf ​​appears in the hierarchy of toplevel. without forgetting the JTAG positioning, you are ready for synthesis by Generate Programming File.

!!!! Process "Translate" failed: I forgot to tell you to clean the sevenseg and anodes ports in S3.ucf​​, these are the ports that are not defined in your design here. So either you comment the lines using the button on the ISE editor, or you set the option Allow Unmatched LOC Constraints in the Process Properties of Implement Design (Right click to open the contextual menu). Instead, use the second option and retry the compilation.

Figure 36 Positioning Unmatched Loc Constraints

!!!! Process "Generate Programming File" failed: still other errors! By clicking on the Errors tab of the console (below), we get the error messages. ISE can not actually produce a value for the LEDs 2-7 that are not associated with any signal. You'll have to modify your circuit. I suggest you put these six leds to 0.

Add between the two buses a constant symbol that can be found in the General symbols library. The default value is xFFFFFFFF, so you have to position it to b000000. A first double-click on the symbol of this constant will allow you to change ffffffff to 000000 and then confirm with OK.

Figure 37 Forcing constant value to b000000

Secondly we must re-open the previous dialog box, this time select Cvalue then click on the Edit Traits button. This time a new window opens, simply specify 2 Binary as the base and 6 bits as the length. ISE 12.4 does not seem to change these arguments in one phasis …

Figure 38 Constant: length and base

You still have to connect this constant by a Bus Tap to LED (7:2). The modification of the circuit should look like the following.

Figure 39 final toplevel

This time the toplevel.bit should be created. All warnings you may see are either from unused switches(7:2) wires, or S3.ucf ​​unused control lines.

Adder

Let us move to the next step, we need to be able to add two bits taking in consideration the carry. So we need to add 3 bits in order to get a result. The addition of 3 bits produces a result between b00 and b10. The bit on the right (less significant) is the result and named s, the bit to the left (most significant) is the carry and named cout, it will be used for the next addition. Two methods exist, either you produce the truth table of the two outputs s and cout as a function of the 3 inputs a, b and cin; or you use two successive half-adders. Of course it is the second that you choose, it allows reusability of demiadd already created. A first demiadd adds a and b, the second adds the result produced from the first to cin which comes to it from the carry of the previous operation. One and only one of the two demiadds can produce a carry, simply connect the two produced carries to an OR gate to generate the final output carry cout. Go ahead, create a Schematic New Source add1bit. Install two instances demiadd, the wires input and output, then the I/O Markers. Finally you can create add1bit symbol.

Figure 40 1 bit adder

In simulation mode, select add1bit and run the simulator Isim. You have 8 test cases which is still feasible case by case.

Figure 41 1 bit adder simulation

If the simulation is correct, you can program the board to realize one addition. Use the same toplevel where you have to remove the demiadd and replace it with an instance of add1bit. It must of course use a third switch tocontrol the input cin, I suggest you use the switches(2).

Figure 42 1 bit adder toplevel

Your hierarchic construction allows you to change nothing in S3.ucf ​​file. You can generate the toplevel.bit code and test it on the board.

Four bits adder

To add two 4-bit words a3a2a1a0 and b3b2b1b0, you need a demiadd for the first 2 bits a0 and b0, then 3 add1bit for the other bits. We build thus a cascade of add1bit components as necessary. I suggest you create a New Source add4bit of Schematic Type. Instantiate a demiadd and 3 add1bits one below the other. Then create two vertical buses a(3:0) and b(3:0) to the left of the components and s(3:0) to the right. Using Add Bus Tap in left orientation, select the bus and connect the Bus Tap a(3) to the third add1bit. The name of the wire automatically decreases to a(2), you can quickly connect your 4 wires to the bus a, repeat the procedure with bus b, then with bus s by changing the mode to right orientation. You still need to pass the carry from demiadd to the first add1bit, then to the second and finally to the third. A wire gets the last carry, name it cout. Finally, place the 4 I/O Markers for the three buses and the wire cout. Finally, you can generate the symbol.

Figure 43 4 bit adder

You can now simulate the circuit then execute it on the board.

Controlled simulation

To simulate all cases of your component, you would change 256 times the values ​​of a(3:0) and b(3:0) and then check the 256 results of s(3:0) on the timing diagram. It would quickly become tedious. You will therefore test some test cases that you think representative. Eventually you will make several simulations with different test cases. To simplify the task, I suggest you add to your project a tester program. ISE will help you. Create a New Source of type VHDL test bench, name it add4bit_tb. The first Next allows you to choose which component is associated with this test program, choose add4bit here.

Figure 44 Creating the test_bench program

Finish the creation and there ISE opens a new window on the add4bit_tb.vhd program that instantiates your add4bit component and leaves you free to choice the implementation of its architecture. In the code there is the simulation process tb that you need to program.

The VHDL process here can be compared to an infinite loop in which we initialize the input signals a and b, with active waiting points. I suggest a first simulation with the following code that must be copied before the wait. Then in simulation mode, run the Isim simulator on the add4bit_tb file.

Figure 45 add4bit : first test_bench

You can try a second simulation that tests two test cases:

Figure 46 add4bit : second test_bench

Verification on the board

We still have to instantiate your add4bit in the toplevel circuit. As previously add1bit should be removed as weel as the Bus Tap connected to the inputs and outputs of this component, then place an add4bit. I suggest you create a Bus Tap between switches(3:0) and a(3:0) and a second Bus Tap between switches(7:4) and b(3:0): the 4 switches on the right will be used to enter the value of a and the 4 leftmost switches this one of b. At the output, create a Bus Tap between Led(3:0) and s, and a second Bus Tap between led(4) and cout. The result of the addition will be displayed in binary code on the 5 leds on the right. We still have to calibrate our constant. Double click the constant and select cValue to launch Edit Traits. place here 3 for the length. It is then possible on the first menu to place the 000 chain as cvalue. Then recreate a Bus Tap from the constant to led(7:5). Here is the final circuit.

Figure 47 Toplevel for add4bit

Your turn: addition on a 7-segment display

I suggest you to print the result s on a hexadecimal viewer using the component you used in TP1. ISE can not make it alone, you'll have yourself to place an OBUF8 for the LED(7:0) I/O Marker. Indeed you must define a local bus myled(7:0). It can transmit data myled(3:0) to the display and also to OBUF8. I will guide you to achieve this.

    1. Add a copy of x7seg.vhd in your project.
    2. Create the symbol associated with this component.
    3. Place an instance in toplevel.
    4. Rename all led buses into myled.
    5. Remove the I/O Marker led (7:0).
    6. Place an OBUF8 on myled.
    7. Add a wire on the output OBUF8 named led (7:0).
    8. Replace the I/O Marker on this wire.
    9. Add the output buses to the x7seg output ports and I/O Markers with the same names as those used in the S3.ucf ​​file.
    10. Connect the 7seg input to the 4 wires of the myled bus that you want to display.
    11. Test on the board

.