Description
The case statement, Adders and ALUs
1 Learning Objectives
In this lab you will design (a) multiplexers using the case statement, (b) a simple ripple-carry adder, and (c) an Arithmetic Logic Unit (ALU), a fundamental component of each processor. You will also gain more practice with hierarchical design in Verilog and with using binary and hexadecimal numbers.
2 Marking Scheme
This lab is also worth 4% of your final grade, but you will be graded out of 8 marks for this lab, as follows.
โข Prelab + Simulations: 3 marks
โข Part I (in-lab): 1 mark
โข Part II (in-lab): 1 mark
โข Part III (in-lab): 3 marks
3 Preparation Before the Lab
Carefully review the background section below, as well as the โPreparation Before the Labโ instructions in the Lab 2 handout.
You are required to complete Parts I to III of the lab by writing and testing your Verilog code. Include your schematics, Verilog code, and simulation outputs (printed screenshots) for Parts I to III in the prelab. You must simulate your circuit with ModelSim using reasonable test vectors written in the format described in Lab 2 and Lab 3 handouts. The term test vector simply refers to one combination of inputs that you will use to test your design. Each simulation should consist of multiple test vectors, sufficient to demonstrate that your design functions as intended.
In-lab Work
You are required to implement and test all of Parts I to III of the lab. You need to demonstrate all parts to the teaching assistants. As a reminder, the device name is 5CSEMA5F31C6 from the Cyclone V family.
4 Verilog Background
Representing Constants
Verilog has a specific notation for representing constants (i.e., literal values). The following code snippet creates a 1-bit wire named a, which is connected to ground (logic-0).
wire a ; assign a = 1 โb0 ;
The number before the single quote is a decimal number representing the bit width (i.e., the number of binary digits, also known as bits). It is 1 for a single wire, and higher for a bus (i.e., a collection of wires). The letter after the single quote is called the radix. Its possible values are letters b, d, h, or o to specify whether the value that follows is in binary (b), decimal (d), hexadecimal (h), or octal (o) notation. (Octal representation is rarely used.) Lastly, the value after the radix is the number in that numerical representation.
For example, 2โb10 corresponds to decimal number two, while 8โh1a (or 8โh1A) corresponds to decimal number 26. The latter is written in binary as 8โb0001_1010 and in decimal as 8โd26. Verilog allows you to use underscores to separate groups of bits to improve readability. Here we separated groups of 4-bits as they each correspond to a single hexadecimal digit. Note that underscore characters are optional.
Verilog Operators
This section presents various Verilog operators that you might find useful for this lab.
โข Arithmetic Operators: + (addition), – (subtraction), * (multiplication), / (division), % (remainder), ** (exponentiation).
โข Reduction Operators: These are unary operators that reduce a vector to a single bit value. The operators are: & (AND all bits), | (OR all bits), and ^ (XOR all bits). You can prepend ~ to any of these to get reduction NAND, NOR and XNOR operators respectively. An example of a reduction AND operation is & 3โb010 which is equivalent to an AND operation between all three bits of the value 3โb010, and will produce 1โb0. Similarly, & 3โb111 will produce 1โb1.
โข Concatenation: Verilog uses curly braces for concatenation. For example, {2โb01, 1โb1} will produce 3โb011. Concatenation can be used in both the left hand side, and the right hand side of an assignment statement.
โข Replication: {n{m}} will replicate n-times the value m. For example, {3{2โb01}} is equivalent to 6โb010101.
Advanced ModelSim commands
The wave.do file in Lab 2 contained simple ModelSim commands that forced a signal to logic 0 or logic 1 (e.g., force {SW[0]} 0), followed by run commands that ran the simulation for a predetermined number of nanoseconds before applying a different test vector. However this approach does not scale well as your designs become more complex and have more inputs. ModelSim allows you to apply a periodic signal to your simulationโs inputs which makes creation of test vectors much easier.
The format of a more advanced force command is the following:
force {<signal name>} <initial value> <initial time>, <new value> <new time>
โrepeat <repeat time> โcancel <cancel time>
This will set the signal name to initial value at initial time after the current time and will set it to new value after new time passed from the current time. This square wave will repeat repeat time after the current time and you can choose to cancel it at cancel time. In all cases, you can explicitly specify the time unit in your force command (e.g., by writing ns) after any time value. You can use shorthands -r and -c instead of -repeat and -cancel.
Here is an example of test vectors for two 1-bit inputs a and b. Notice that the square wave applied to b has twice the period of the square wave applied to a, thus modeling all four possible input combinations, the same way theyโd be present in a truth table.
force {a} 0 0 , 1 20 โrepeat 40
force {b} 0 0 ns , 1 40 ns โr 80
Also do not forget to use -timescale 1ns/1ns as an argument to the vlog command, as we did in the wave.do file provided in Lab 2. The -timescale switch tells ModelSim what the default time unit is when no unit is specified (first number), and what the smallest unit of time to simulate should be (second number).
5 Part I
For this part of the lab, you will learn how to use always blocks and case statements to design a 7-to-1 multiplexer.
An always block allows us to describe a circuit using behavioral style, using case and if statements. However, the circuit produced from this description still consists of basic logic gates.
The model Verilog code for a 7-to-1 multiplexer built using a case statement is shown below. The seven inputs are from the signals named Input[6:0]. The output is called Out, and it is declared as a reg type, as explained above. The select lines are called MuxSelect[2:0].
reg Out; // declare the output signal fro the always block
always @(โ) // declare always block
begin
case (MuxSelect [ 2 : 0 ] ) // start case statement
3 โb000 : Out = Input [ 0 ] ; // case 0
3 โb001 : Out = Input [ 1 ] ; // case 1
3 โb010 : Out = Input [ 2 ] ; // case 2
3 โb011 : . . . // case 3
3 โb100 : . . . // case 4
3 โb101 : . . . // case 5
3 โb110 : . . . // case 6
default : . . . // default case
endcase
end
The always block uses an asterisk in the sensitivity list to indicate that the block describes combinational logic, i.e., any logic where the outputs rely strictly on the inputs. We will learn more about combinational and sequential logic later in the course. For now, use the asterisk in the always block of a case statement as shown above.
Using SW 6โ0 as the data inputs and SW 9โ7 as the select signals, display on LEDR0 the output of a 7-to-1 multiplexer using the case statement style as shown above.
2. Write Verilog code for a 7-to-1 multiplexer, based on the template provided above. Use switches
SW 9โ7 on the DE1-SoC board as the MuxSelect inputs and switches SW 6โ0 as the Input data inputs. Connect the output to LEDR0. (PRELAB)
3. Simulate your circuit with ModelSim for different values of MuxSelect and Input. You must include a screenshot of the simulation output as part of your prelab. (PRELAB)
4. Create a new Quartus Prime project for your circuit. Make sure it is stored in your W: drive.
5. Compile the project.
6 Part II
Figure 1(a) shows a circuit for a full adder, which has the inputs a, b, and ci, and produces the outputs s and co. Parts b and c of the figure show a circuit symbol and truth table for the full adder, which produces the two-bit binary sum cos = a + b + ci. Please note that the + operator here means addition and not logic OR. Figure 1(d) shows how four instances of this full adder module can be used to design a circuit that adds two four-bit numbers. This type of circuit is called a ripple-carry adder, because of the way that the carry signals are passed from one full adder to the next. Write Verilog code that implements this circuit, as described below. Be sure to use what you learned about hierarchy in Lab 2.
a) Full adder circuit b) Full adder symbol
b a ci co
0 0 0
0 0 1 0 1 0
0 1 1 1 0 0
1 0 1
1 1 0 1 1 1 0
0
0
1
0 1
1
1
1 1
s b3 a3 c3 b2 a2 c2 b1 a1 c1 b0 a0 cin
0
1 1
0
0
0
c) Full adder truth table d) Four-bit ripple-carry adder circuit
Figure 1: A ripple-carry adder circuit.
Perform the following steps:
2. Write a Verilog module for the full adder subcircuit and write another Verilog module that instantiates four instances of this full adder. Name the input ports A, B and cin, and the output ports S and cout. Note: You should NOT use the arithmetic addition operator + in your Verilog implementation of the full-adder. Doing so will earn you 0 marks for this part. (PRELAB)
3. Simulate your 4-bit ripple-carry adder with ModelSim for intelligently chosen values of A and B and cin. You should include a screenshot of it in the prelab. Note that as circuits get more complicated, you will not be able to simulate or test all possible cases. This means that you can test only a subset. Here intelligently chosen means to find particular corner cases that exercise key aspects of the circuit. An example would be a pattern that shows that the carry signals are working. Be prepared to explain why your test cases are good enough. (PRELAB)
4. Create a new Quartus Prime project for the adder circuit. Make sure it is stored in your W: drive. In the new top-level module, use switches SW7โ4 and SW3โ0 to connect to inputs A and B respectively. Use SW8 for the carry-in, cin of the adder. Connect the outputs of the adder, cout and S, to the LEDs LEDR4 and LEDR3:0 respectively.
5. Compile the project.
6. In Quartus Prime, select Tools > Netlist Viewers > RTL Viewer and observe the circuit that got produced from your Verilog code. Try expanding modules in the diagram, and selecting different hierarchy levels in the Netlist Navigator on the left.
7 Part III
Using Part II from this lab and the HEX decoder from Lab 2 Part III, you will implement a simple Arithmetic Logic Unit (ALU). This ALU has two data inputs and can perform multiple operations on the data inputs such as addition, subtraction, logical operations, etc. The output of the ALU is selected by function inputs that specify the function to be performed by the ALU. The easiest way to build an ALU is to implement all required functions and connect the outputs of the functions to a multiplexer. Choose the output value for the ALU using the ALU function inputs to drive the multiplexer select lines. The output of the ALU will be displayed on the LEDs and HEX displays.
The following case statement pseudo code shows the operations that you should implement in the ALU, given the specified function value. The ALU has two 4-bit inputs, A and B and an 8-bit output, called ALUout[7:0]. Note that in some cases, the output will not require the full 8 bits so do something reasonable with the extra bits, such as making them 0 so that the value is still correct. Adding zeros in front of any positive number is called sign-extension, and does not change the value of the number.
Note that it is not permissible to enclose a module instantiation inside an always block. An always block is only used to describe one part of the circuit using behavioral style (e.g., using a case statement). If you want to connect inputs or outputs of an instance of a module to the circuit described using an always block, you should create a module instance outside the always block and use wires to connect the two circuits.
always @(โ) begin case (function) // declare always block
0: . . . // Make the output equal to A+1, using the adder // circuit from Part II of this Lab .
1: . . . // A + B using the adder from Part II of this lab
2: . . . // A + B using the Verilog โ +โ operator
3: . . . // A XOR B in the lower four b it s and A OR B in the
// upper four b it s
4: . . . // Output 1 (8 โ b00000001 ) i f any of the 8 bi ts in
// either A or B are high , and 0 (8 โ b00000000 )
// i f a l l the b its are low ( use a reduction OR operator )
5: . . . // Make the input appear at the output , with A in
// the most significant ( left โmost) four b it s and
// B in the least significant ( right โmost) bit s .
default : . . . // default case , output 0
endcase
end
Once youโve created this ALU module, the inputs and outputs of this ALU will need to be connected to the hardware on the DE1 board. Use the following for the ALU inputs and outputs:
โข The A and B inputs connect to switches SW 7โ4 and SW 3โ0 respectively.
โข Use KEY 2โ0 for the function inputs.
โข Display ALUout[7:0] in binary on LEDR7โ0;
โข Have HEX0 and HEX2 display the values of B and A respectively in hexadecimal and set HEX1 and HEX3 to 0.
โข HEX4 and HEX5 should display ALUout[3:0] and ALUout[7:4] respectively in hexadecimal.
Perform the following steps to complete the lab:
1. Draw a schematic showing your code structure with all wires, inputs and outputs labeled. Your schematic should contain a block diagram of your design showing any design hierarchy. You should show the multiplexer that is implied by the case statement for your ALU as well as all inputs to this multiplexer. Also show all connections to switches and LEDs. Be prepared to explain it to the
2. Write a Verilog module for the ALU including all inputs and outputs. (PRELAB)
3. Simulate your circuit with ModelSim for a variety of input settings, ensuring the output waveforms are correct. You must include screenshots of output waveforms as part of your prelab. (PRELAB) 4. Create a new Quartus Prime project for your circuit, and compile the project.
5. In Quartus Prime, select Tools > Netlist Viewers > RTL Viewer and observe the circuit that got produced from your Verilog code. Try expanding modules in the diagram, and selecting different hierarchy levels in the Netlist Navigator on the left.
Note: In your simulation, KEY3โ0 are inverted. Remember that the DE1-SoC board recognizes an unpressed pushbutton as a value of 1 and a pressed pushbutton as a 0.
Reviews
There are no reviews yet.