Description
Latches, Flip-flops, and Registers
Learning Objectives
The purpose of this exercise is to investigate the fundamental synchronous logic elements: latches, flip-flops, and registers. In this lab you will build a gated D-Latch with the 7400 logic chips and write Verilog to create a registered ALU and a shift register.
Marking Scheme
Each lab is worth 4% of your final grade, but you will be graded out of 8 marks for this lab, as follows.
• Prelab: 3 marks
• Part I (in-lab): 1 mark
• Part II (in-lab): 2 mark
• Part III (in-lab): 2 marks
Preparation Before the Lab
You are required to complete the prelab for Part I of the lab as you would have prepared for Lab 1. Parts II and III of the lab require you to write and test your Verilog code. Show your schematics, Verilog, and simulations for Parts I to III to the teaching assistants. You must simulate your circuits with ModelSim (using reasonable test vectors using ModelSim scripts).
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.
Latches in Verilog
In modern digital circuit design, latches are rarely used, and only in very special circumstances. On FPGAs especially, we seldom use latches except in very specific designs. Most of the time, if we create a latch in Verilog in a design for an FPGA, we have created the latch in error. To explore the behaviour of latches, in this lab you will create a latch using only the 7400 logic chips. In Verilog, when we use always @(*) to create combinational logic, we sometimes inadvertently create latches. These latches are created when there is an identifier inside an always block that appears on the left side of the equal (=) sign, but does not have a value specified for all possible combinations of all input values.
For example in the following code:
reg w; always @(*) begin
if (x) // when x is true (i.e., logic 1)
w = 1;
end // w gets set to 1
Shift Operators in Verilog
Verilog has the following two logic shift operators: (a) Logic Right Shift operator (>>) and (b) Logic Left Shift operator (<<). Doing (A >> N) shifts A by N bits to the right; the N most significant bits of the resulting vector are filled-in with zeros. Doing (A << N) shifts A by N bits to the left; the N least significant bits of the resulting vector are filled-in with zeros. As with any combinational circuit A and N are inputs to the circuit and the shifted result is the output.
Here is a Verilog snippet that uses these two operators:
wire [2:0] a, b; wire c;
assign c = 1’b1; assign a = (3’b011 >> 1’b1); // a is 3’b001 assign b = a << c; // b is 3’b010
Part I
Figure 1 shows the circuit for a gated D latch. In this part, you will build the gated D latch using the 7400 chips (as in Lab 1) and the protoboard (breadboard). Refer back to the Lab 1 handout for the specifications of the 7400 chips.
Figure 1: Circuit for a gated D latch.
Perform the following steps:
1. In your lab book, draw a schematic of the gated D latch using interconnected 7400-series chips. For this exercise you are allowed to use NAND gates. Recall from Lab 1 what a gate-level schematic looks like. (PRELAB)
2. Build the gated D latch using the chips and protoboard. Use switches to control the clock (Clk) and D input. Use lights (LEDs) to make Qa and Qb visible. Don’t forget to hook up the power and ground on all of your chips!
3. Study the behaviour of the latch for different D and clock (Clk) settings.
Part II
The most common storage element today is the edge-triggered D flip-flop. One way to build an edge-triggered D flip-flop is to connect two D latches in series, such that the two D latches use opposite levels of the clock for gating the latch. This is called a master-slave flip-flop. The output of the master-slave flip-flop changes on a clock edge, unlike the latch, which changes according to the level of the clock. For a positive edge-triggered flip-flop, the output changes when the clock edge rises, i.e., when clock transitions from 0 to 1. The Verilog code for a positive edge-triggered flip-flop is shown in Figure 2. This flip-flop also has an active-low, synchronous reset, meaning that the reset only happens when reset n is 0 on the rising clock edge. If q is declared as reg q, then you get a single flip-flop. If q is declared as reg[7:0] q, then you get eight parallel flip-flops, which is called an 8-bit register. Of course, d should have the same width as q.
always @(posedge clock) begin // Triggered every time clock rises. Note that clock is not a keyword
if (reset n == 1’b0) // when reset n is 0 (note this is tested on every rising clock edge)
q <= 0; // q is set to 0. Note that the assignment uses <= instead of =.
else // when reset n is not 0
q <= d; end // value of d passes through to output q
Figure 2: Verilog for a positive edge-triggered flip-flop with active-low, synchronous reset1.
Note that all assignment statements in the aforementioned code use <= instead of =. From now on you should use the assignment operator = only for combinational circuits, and the assignment operator <= for sequential circuits. Sequential circuits are circuits where the output relies not just on the current combination of inputs, but also on the prior state of the circuit (i.e., its prior input sequence). Combinational circuits are described using assign statements and always @(*) blocks, while sequential circuits are described using always @(posedge…) and always @(negedge…) blocks. Note that you can place multiple statements inside of an if-else statement if you enclose such statements inside of a begin-end block.
Starting with the circuit you built for Lab 3 Part III build an ALU with the eight operations as shown in the pseudo-code in Figure 3. The output of the ALU is to be stored in an 8-bit register and the four least-significant bits of the register output are to be connected to the B input of the ALU. Figure 4 shows the required connections.
always @(*) // declare always block begin case (ALU function) // start case statement
0: Make the inputs appear at the output, with A in the most significant four bits and B in the least significant four bits.
1: A + B using the adder from Lab 3 Part II
2: A + B using the Verilog ‘+’ operator
3: A XOR B in the lower four bits and A OR B in the upper four bits
4: Output 1 (8’b00000001) if at least 1 of the 8 bits in the two inputs is 1 using a single OR operation
5: Left shift B by A bits
6: Right shift B by A bits (logical right shift) 7: A × B using the Verilog ‘*’ operator default: … // default case (if needed)
endcase end
Figure 3: Pseudo-code for ALU.
Perform the following steps.
1. Create a Verilog module for the simple ALU with register. Use the code in Figure 2 as the model for your register code. Connect the Data input of your ALU to switches SW3−0. Connect KEY0 to the Clock input for the register, SW9 to reset n and use SW7−5 for the ALU function inputs. Display the outputs on LEDR7−0; have HEX0 display the value of Data in hexadecimal and set HEX , HEX2 and HEX3 to display value 0 or alternatively blank (all segments off). HEX4 and HEX5 should display the least-significant and most-significant four bits of Register respectively, also in hexadecimal. (PRELAB)
3. Create a new Quartus Prime project for your circuit. Make sure it is stored in your W: drive. Make sure to select the correct FPGA device (5CSEMA5F31C6) and import the pin assignments.
4. Compile the project.
5. Download the compiled circuit into the FPGA chip. Test the functionality of the circuit.
Part III
In this part of the lab, you will create an 8-bit right-shift register that has an optional arithmetic shift. A shift register is a collection of flip-flops that move values sequentially between each other on each clock edge. Figure 5 shows one bit of our right-shift register. It contains a positive edge-triggered flip-flop and several multiplexers. To accommodate 8-bits, you will use eight instances of the circuit in Figure 5 to design your right-shift register with optional arithmetic shift and parallel load as shown in Figure 6.
When bits are shifted in this register, it means that the bits are copied to the next flip-flop on the right. For example, to shift the bits right, each flip-flop loads the value of the flip-flop to its left when the clock edge occurs. In the right-shift, the flip-flop at the left end of the register has no left neighbour. One option is to load a zero, but what if the value in the register is signed? In this case we should perform sign-extension. When we perform the sign-extension, this shift operation is called an Arithmetic Shift Right (ASR).
In the Shifter module, create an 8-bit-wide register input LoadVal, whose individual wires are tied to each loadval input of each ShifterBit instance. Likewise, create an 8-bit-wide output Q, whose individual wires stem from each out port of each ShifterBit instance. The shift input of all eight instances of the circuit in Figure 5 should be tied to the single input ShiftRight. The load n input of all eight instances should be tied to the input Load n. This allows an 8-bit value to be loaded into all eight flip-flops on the same clock cycle. The clk input of all eight instances should be tied to the single input clk. Likewise for reset n. The in input of all eight instances, should be connected to the out port of the instance to its left, because when you want to shift the bits right, you have to use the bit from the left – except for the leftmost ShifterBit instance. In this special case, you should design a circuit that will perform sign-extension when the signal ASR is high (arithmetic right shift) and will load zeros if ASR is low (logic right shift). This special circuit is not shown in the figures below.
ShifterBit
Figure 5: Sub-circuit for Part III.
Figure 6: Shifter circuit for Part III. All required internal connections are not shown.
Here is an example of the circuit operation:
1. When Load n = 0, the value on LoadVal is stored in the flip-flops on the next positive clock edge (i.e., parallel load behaviour).
2. When Load n = 1, ShiftRight = 1 and ASR = 0 the bits of the register shift to the right on each positive clock edge. Assuming that the initial value in the flip-flops at cycle 0 is A, with bits A7 through A0, the values in the two subsequent cycles would be:
Q[7] Q[6] Q[5] Q[4] Q[3] Q[2] Q[1] Q[0]
Cycle 0: A7 A6 A5 A4 A3 A2 A1 A0
Cycle 1: 0 A7 A6 A5 A4 A3 A2 A1
Cycle 2: 0 0 A7 A6 A5 A4 A3 A2
…
3. When Load n = 1, ShiftRight = 1 and ASR = 1 the bits of the register shift to the right on each positive clock edge but the most significant bit is replicated. This is called an Arithmetic shift right:
Q[7] Q[6] Q[5] Q[4] Q[3] Q[2] Q[1] Q[0]
Cycle 0: A7 A6 A5 A4 A3 A2 A1 A0
Cycle 1: A7 A7 A6 A5 A4 A3 A2 A1
Cycle 2: A7 A7 A7 A6 A5 A4 A3 A2
…
Do the following steps:
1. What is the behaviour of the 8-bit shift register shown in Figure 6 when Load n = 1 and ShiftRight = 0? Briefly explain. (PRELAB)
2. Draw a schematic for the 8-bit shift register shown in Figure 6 including the necessary connections. Your schematic should contain eight instances of the sub-circuit in Figure 5 and all the wiring required to implement the desired behaviour. Label the signals on your schematic with the same names you will use in your Verilog code. (PRELAB)
3. Starting with the code in Figure 2 for a flip-flop, use this D flip-flop with instances of the mux2to1 module from Lab 2 to build the sub-circuit shown in Figure 5. To get you started, Figure 7 is a sample of hierarchical code showing the D flip-flop with one of the 2-to-1 multiplexers connected to it. (PRELAB)
mux2to1 M1( // instantiates 2nd multiplexer
.x(load val) // the parallel load value
.y(data from other mux)
.s(load n)
.m(data to dff) // outputs to flip-flop
);
flipflop F0( // instantiates flip-flop
.d(data to dff) // input to flip-flop
.q(out) // output from flip-flop
.clock(clk) // clock signal
.reset n(reset n) // synchronous active low reset
);
Figure 7: Part of the code for the sub-circuit in Figure 5.
4. Write a Verilog module for the shift register that instantiates eight instances of your Verilog module for Figure 5. This Verilog module should match with the schematic in your lab book. Use SW7−0 as the inputs LoadVal7−0 and SW9 as a synchronous active low reset. Use KEY1 as the Load n input, KEY2 as the ShiftRight input and KEY3 as the ASR input. Use KEY0 as the clock. The outputs Q7−0 should be displayed on the LEDs (LEDR7−0). (PRELAB)
5. Compile your Verilog code and simulate the design with ModelSim. In your simulation, you should perform the reset operation on the first clock cycle, then do a parallel load of your register on the next cycle. Finally, clock the register for several cycles to demonstrate both types of shifts. (NOTE: If you do not perform a reset first, your simulation will not work! Try simulating without doing reset first and see what happens. Can you explain the results?) You are strongly encouraged to complete this step before coming to the lab. However, simulations for this part will not be marked as part of your prelab. They will be marked as part of your in-lab work.
6. Create a new Quartus Prime project for your circuit. Make sure it is stored in your W: drive. Make sure to select the correct FPGA device (5CSEMA5F31C6) and import the pin assignments.
7. Compile the project.
8. Download your circuit on the DE1-SoC board.
9. Test the functionality of your shift register.
Reviews
There are no reviews yet.