Your cart is currently empty!
Learning Objectives The purpose of this lab is to investigate the fundamental synchronous logic elements: latches, ip- ops, 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…
The purpose of this lab is to investigate the fundamental synchronous logic elements: latches, ip- ops, 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.
Each lab is worth 4% of your nal grade, but you will be graded out of 8 marks for this lab, as follows.
You are required to complete the prelab for Part I of the lab as you would have prepared for Lab 1. Parts
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 TAs after you tested them yourselves.
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 speci c 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. For instance, this happens when you use the equal (=) sign to set an output value, but don’t specify what the output should be for all possible combinations of input values. The circuit assumes it has to retain a past value in those cases, creating a latch.
1
For example in the following code:
reg w;
always @( ∗ )
begin
i f ( x )                          // when x i s      t r u e ( i . e . , l o g i c 1)
w = 1 ;                  // w g e t s   s e t t o 1
end
w does not have a value speci ed when x is 0. In this instance a latch would be created. To x this code and create a proper combinational circuit, w should have a value speci ed for all possible values of inputs, meaning that the truth table for the logic function is fully speci ed. From now on, you should check your compilation log in Quartus and look out for warnings that latches have been created. An example warning message may look like this:
Warning (10240): Verilog HDL Always Construct warning at mymodule.v(9): inferring latch(es) for variable \w”, which holds its previous value in one or more paths through the always construct
The warning message clearly identi es that identi er w caused the latch to be created. It also points to the le (mymodule.v) and line number (9) where the o ending always block resides. In your code, the module name, identi er name, and line number will be di erent, of course. Note that this is a warning message (as opposed to an error or critical warning), so make sure that your lters in the Messages window are not set to hide warning messages. Message ltering can be achieved by clicking on the red circle (for error messages), yellow triangle (for warnings), and purple triangle (for critical warnings). The Messages window is usually situated at the bottom of the Quartus window. If you closed this window by mistake, you can enable it again by selecting View > Utility Windows > Messages.
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 signi cant bits of the resulting vector are lled-in with zeros. Doing (A << N) shifts A by N bits to the left; the N least signi cant bits of the resulting vector are lled-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 i s 3 ‘ b011 s h i f t e d r i g h t one b i t
//Â r e s u l t :Â a = 3 ‘ b001
assign b = a << c ; // b i s a s h i f t e d             l e f t one   b i t
//Â r e s u l t :Â b = 3 ‘ b010
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) on the protoboard (breadboard). Refer back to the Lab 1 handout for 7400 chips schematics, speci cations, and pin-out.
Figure 1: Circuit for a gated D latch.
Perform the following steps:
The most common storage element today is the edge-triggered D ip- op. One way to build an edge-triggered D ip- op 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 ip- op. The output of the master-slave ip- op changes on a clock edge, unlike the latch, which changes according to the level of the clock. For a positive edge-triggered ip- op, 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 ip- op is shown in Figure 2. This ip- op 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 ip- op. If q is declared as reg[7:0] q, then you get eight parallel ip- ops, which is called an 8-bit register. Of course, d should have the same width as q.
Â
always @( posedge c l o c k ) | // | T r i g g e r e d | e v e r y | time c l o c k r i s e s | ||||||||
// | Note | t h a t | c l o c k | i s | not | a | keyword | |||||
begin | ||||||||||||
i f ( r e s e t n == 1 ‘ b0 ) | // | When | r e s e t | n | i s | 0 | ||||||
// | Note | t h i s | i s | t e s t e d | on | e v e r y | r i s i n g c l o c k | e d g e | ||||
q <= 0 ; | // S e t q t o 0 . | |||||||||||
// | Note | t h a t | t h e | a s s i g n m e n t | u s e s | <= i n s t e a d | o f = | |||||
e l s e | // | When | r e s e t | n | i s | not | 0 | |||||
q <= d ; | // S t o r e t h e v a l u e o f d i n q | |||||||||||
end |
Figure 2: Verilog for a positive edge-triggered ip- op 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 opera-tor <= 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 or 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 that supports the eight operations 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-signi cant bits of the register output are to be connected to the B input of the ALU. Figure 4 shows the required connections.
always @( ∗ ) | // D e c l a r e | a l w a y s | b l o c k | ||||||||||||
begin | |||||||||||||||
case ( ALU function ) // S t a r t | o f t h e c a s e s t a t e m e n t | ||||||||||||||
0 : . . . | // | Make t h e | o u t p u t | e q u a l | t o A+1, u s i n g | t h e | adder | ||||||||
// | c i r c u i t | from Part I I | o f | Lab | 3 . | ||||||||||
1 : . . . | // | A + B | u s i n g | t h e | adder | from | Part | I I | o f Lab | 3 | |||||
2 : . . . | // A + B u s i n g t h e V e r i l o g ` +’ o p e r a t o r | ||||||||||||||
3 : . . . | // | A XOR B | i n | t h e l o w e r | f o u r | b i t s , | A OR B | i n | t h e upper f o u r b i t s | ||||||
4 : . . . | // | Output | 1 | ( 8 ‘ b00000001 ) | i f | any o f t h e 8 | b i t s | i n | |||||||
// | e i t h e r | A | or | B a r e h i g h , | and | 0 | ( 8 ‘ b00000000 ) | ||||||||
// | i f a l l | t h e | b i t s | a r e low ( use a | r e d u c t i o n OR | o p e r a t o r ) | |||||||||
5 : . . . | // L e f t s h i f t B by A b i t s | ||||||||||||||
6 : . . . | // R i g h t s h i f t B by A b i t s ( l o g i c a l r i g h t s h i f t ) | ||||||||||||||
7 : . . . | // A   B u s i n g t h e V e r i l o g ∗ o p e r a t o r | ||||||||||||||
default : . . . | // | D e f a u l t | c a s e ( i f | needed ) | |||||||||||
endcase | |||||||||||||||
end |
Figure 3: Pseudo-code for ALU.
Perform the following steps.
4
Data | |||||||
HEX Display | |||||||
4 | Signal A | 4 | Signal B | ||||
ALU
Register
8
HEX Display
LED Display
Figure 4: Simple ALU with register circuit for Part II.
In this part of the lab, you will create an 8-bit shift-register that has an optional arithmetic shift. A shift register is a collection of ip- ops that move values sequentially between each other on each clock edge. Figure 5 shows one bit of this shift-register. It contains a positive edge-triggered ip- op and two multiplexers. To create an 8-bits shift-register, you will use eight instances of the circuit in Figure 5 to design your 8-bit shift-register with optional arithmetic shift and parallel load as shown in Figure 6.
ShifterBit
load_val
in | 0 | |
1 | ||
shift
0
1
clk | ||
load_n | ||
Â
reset_n
reset_n
Figure 5: Single-bit shift-register
Shifter
8 | LoadVal | ||||||||
Load_n | ShifterBit | ShifterBit | ShifterBit | ||||||
ShiftRight | |||||||||
ASR | … | ||||||||
clk | |||||||||
reset_n | |||||||||
Q[7] | Q[1] | Q[0] |
Figure 6: 8-bit shift-register of Part III. None of internal connections are shown here.
When bits are shifted in this register, it means that the bits are copied to the next ip- op on the right. For example, to shift the bits right, each ip- op loads the value of the ip- op to its left when the clock edge occurs. In the right-shift, the ip- op 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 connected to load val input of ShifterBit instances. Likewise, create an 8-bit-wide output Q, which is the output of ShifterBit instances. The shift input of all eight instances of the circuit in Figure 5 should be connected to the single input ShiftRight. The same thing applies to load n, clock (clk), and reset n.
The in input of seven instances should be connected to the out port of the instance to its left. For the leftmost ShifterBit, you should design a circuit that will perform sign-extension when the signal ASR is high (arithmetic right shift) or load zeros if ASR is low (logic right shift). This special circuit is not shown in Figure 6.
6
Here is an example of the circuit operation:
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 |
 | : : : | |||||||
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: |
mux2to1 M1(
. x ( l o a d v a l ) ,
. y ( d a t a f r o m o t h e r
. s ( l o a d n ) ,
.m( d a t a t o d f f )
) ;
f l i p f l o p F0 (
. d ( d a t a t o d f f ) ,
. q ( out ) ,
. c l o c k ( c l k ) ,
. r e s e t n ( r e s e t n )
) ;
// i n s t a n t i a t e s 2nd m u l t i p l e x e r
// t h e   p a r a l l e l l o a d v a l u e
m u x ) ,
// o u t p u t s t o f l i p  f l o p
// i n s t a n t i a t e s         f l i p     f l o p
// i n p u t  t o f l i p  f l o p
// o u t p u t from f l i p   f l o p
// c l o c k  s i g n a l
// s y n c h r o n o u s          a c t i v e        low        r e s e t
Figure 7: Helper code snippet to implement one-bit shifter shown in Figure 5.
that you created in previous step. This Verilog module should match with the schematic in your prelab. Use SW7 0 as the inputs LoadVal7 0 and SW9 as a synchronous active low reset (reset n).
7
Use KEY1 as the Load n input, KEY2 as the ShiftRight input and KEY3 as the ASR input. Use KEY0 as the clock (clk). The outputs Q7 0 should be displayed on LEDR7 0. (PRELAB)
8