1. Summary
In this project, I built circuits using gate-level design and VHDL to improve the efficiency of the designing process. For the main tasks, I created a circuit that takes in 4 bits and drives a 7 segment display for the hexadecimal characters and implemented a binary adder. To test my design, I used the board. In the extensions, I also improved my circuits to perform subtraction and 2's complement numbers addition.
2. Tasks
1) 7-Segment Display Driver
For the first task, I made a Quartus project called hexDisplay and created a circuit that takes in four bits and drives a 7 segment display for the hexadecimal characters 0-9, A-F.
To design the circuit, I drew the following diagrams to figure out how to use a 7-segment display consisting of seven individual bars to create each number or letter.
Based on the position and index of each bar in a 7-segment display, I made a truth table, as shown below.
Decimal | Hex | Binary | Y0 | Y1 | Y2 | Y3 | Y4 | Y5 | Y6 |
0 | 0 | 0000 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
1 | 1 | 0001 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
2 | 2 | 0010 | 1 | 1 | 0 | 1 | 1 | 0 | 1 |
3 | 3 | 0011 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
4 | 4 | 0100 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
5 | 5 | 0101 | 1 | 0 | 1 | 1 | 0 | 1 | 1 |
6 | 6 | 0110 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
7 | 7 | 0111 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
8 | 8 | 1000 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
9 | 9 | 1001 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
10 | A | 1010 | 1 | 1 | 1 | 0 | 1 | 1 | 1 |
11 | B | 1011 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
12 | C | 1100 | 1 | 0 | 0 | 1 | 1 | 1 | 0 |
13 | D | 1101 | 0 | 1 | 1 | 1 | 1 | 0 | 1 |
14 | E | 1110 | 1 | 0 | 0 | 1 | 1 | 1 | 1 |
15 | F | 1111 | 1 | 0 | 0 | 0 | 1 | 1 | 1 |
My circuit would light up the proper segments to display a hexadecimal number when given the corresponding 4-bit binary integer value as input.
By default, the red light of each bar is on when it is 0 and is off when it is 1.
I created a sevenSegDriver VHDL file based on the truth table and then created a symbol so that I could add it to my hexDisplay.bdf.
I used an 8-bit counter to drive two 7-segment displays which required two of my 7-segment display driver--sevenSegDriver.
My circuit looks like this:
I tested the result using the board:
It increments by one every time I press the button and can display hexadecimal numbers from 00 up to FF.
2) Add Two Numbers
The second task was to implement an unsigned adder. I made another Quartus project called addIt and created a circuit that takes in two 4-bit binary numbers--A and B and outputs their sum as a 5-bit binary number--C.
In my VHDL file, I made inputs the type unsigned.
The circuit takes in two 4-bit inputs, converts the two 4-bit inputs into 5-bit signals, executes the addition, and displays the 5-bit output on the board's 7-segment display as two hexadecimal digits, of which the most significant digit is always a 0 or 1.
In my VHDL file adder, given two vector signals A and B that are type UNSIGNED (3 downto 0), I used a statement C <= ('0' & A) + ('0' & B) to make A and B 5-bit numbers by concatenation, add them together, and assign them to a signal of type UNSIGNED (4 downto 0)--C.
Then I created a symbol for the file so that I could add it to my circuit.
The final circuit design:
Testing using the board:
I used the 8 switches (SW[9]--SW[5] and SW[3]--SW[0]) on the board to control the two inputs.
3. Extensions
1) Adjust your circuit and demonstrate it works for 2's complement numbers.
For my first extension, I made an adder that works for 2's complement numbers.
For 2's complement numbers, the most significant bit is the sign bit.
To keep the sign bit of output, I sign-extended each summand to 5 bits by copying the sign bit into the most significant bit position in my VHDL file twosCompDriver.
An example of 2's complement numbers addition is shown in the table below:
.
The red bit is the sign bit and is indicated by HEX[1] on the board.
My final circuit design:
Testing using the board:
Example 1:
0100 (decimal 4) + 0001 (decimal 1) = hex 05 (decimal 5)
- 0100 + 0001 -> 05 is equivalent to 4 + 1 = 5 in decimal
Example 2:
1000 (-8) + 0010 (2) = 1A ( -16 + 10 = -6)
- 1000 + 0010 -> 1A is equivalent to -8 + 2 = -6 in decimal
Example 3:
1111 (-1) + 1111 (-1) = 1E (-16 + 14 = -2)
- 1111 + 1111 -> 1E is equivalent to -1 + -1 = -2 in decimal
Example 4:
1110 (-2) + 1110 (-2) = 1C (-16 + 12 = -4)
- 1110 + 1110 -> 1C is equivalent to -2 + -2 = -4 in decimal
2) Add functionality to your second circuit so it can execute operations other than addition. Use the pushbuttons to control the operation.
For my second extension, I implemented an adder-subtractor.
In the VHDL file--adderSubtractor.vhd, I added an input signal--subtract–that controls whether the operation is addition or subtraction. If the pushbutton is not pressed(when it is 1), the two numbers A and B get added. When the pushbutton is pressed (which is 0), the operation becomes A - B.
My circuit design:
Testing using the board:
The leftmost 4 toggle switches (SW[9] to SW[6]) represent the minuend A and the rightmost 4 switches (SW[3] to SW[0]) represent the subtrahend B. The subtract signal is controlled by the leftmost pushbutton (pushbotton[3]). When I press the button, the circuit performs subtraction. At other times, it performs addition.
3) Create a circuit that takes in an 8-bit binary integer and returns three 4-bit values that represent the appropriate decimal representation.
In threeDecimal.vhd, I used A to represent the first 4 bits of the 8-bit binary integer and B to represent the following 4 bits. I also made three 4-bit outputs–ones, tens, hundreds–that store the three digits in the ones, tens, hundreds places of the output decimal value.
Additionally, I created integer signals to facilitate the type conversions.
Firstly, I converted the 4-bit binary integers A and B to two decimal values and then got C in decimal which represents the hexadecimal value "AB".
For example, given the input 10100011, A would be 1010 (decimal 10), B would be 0011 (decimal 3). The hexadecimal representation "AB" would be A3. Applying hexadecimal arithmetic, I could get C = 10 * 16 + 3 = 163.
Secondly, I used MOD to get the respective digits in the ones, tens, and hundreds places, stored in integer signals--onesVal, tensVal, and hundredsVal.
Finally, I converted the three integers to binary values by type casting.
My circuit design:
Testing using the board:
Example 1:
The input 1010 0011 (hex A3) returns 0001 0110 0011 (decimal 163).
Example 2:
The input 1101 0111 (hex D7) returns 0001 0011 0111 (decimal 215).
4. Reflection
At the end of the project, I became more familiar with digital design components and realized how VHDL could save time when designing circuits. It was important to understand what the ‘1’s and ‘0’s control since it was easy to flip them and get the opposite result. Additionally, I did find the 2’s complement numbers adder hard to figure out at first.
5. Credit
Di Luo
Jiyao Chen
Mike Zheng
Allen Ma
http://www.bitweenie.com/listings/vhdl-type-conversion/