Professional Documents
Culture Documents
Sequential Logic
Deanna Sessions
ECEN 248-511
TA: Priya Venkatas
Date: October 30, 2013
Objectives:
This lab is where we will learn about sequential logic circuits. This includes learning about
latches and flip-flops and adding the element of time delays into the circuit. This gets to a more
real-life application of the circuits because time delays end up being a large portion of intricate
circuits and it is important the proper information is at the right place at the right time. The
concept of a synchronous circuit has been talked about in previous labs, but we have not really
cared about time delay up until this point and now we will account for timing with a clock signal.
This lab also introduces our first technical usage of latches in which we include a clock and a
master-slave layout of the flip-flop circuit.
Design:
Below are all of the source codes from the lab with comments included:
//sr_latch.v
`timescale 1 ns/ 1 ps
`default_nettype none
module sr_latch( Q, notQ, En, S, R);
//outputs of Q and ~Q
//inputs of an enable bit, set, and reset
//internal wires
//internal wires
//d_flip_flop.v
`timescale 1 ns/ 1 ps
`default_nettype none
module d_flip_flop(Q, notQ, Clk, D);
//outputs of Q and ~Q
//inputs of a clock and data
//internal wires
//Master D Latch
//Slave D Latch
endmodule
//d_latch_behavioral
`timescale 1 ns/ 1 ps
`default_nettype none
module d_latch_behavioral(
output reg Q,
output wire notQ,
input wire D, En
);
always@(En or D)
if (En)
Q=D;
else
Q=Q;
//d_flip_flop_behavioral
`timescale 1 ns/ 1 ps
`default_nettype none
module d_flip_flop_behavioral(
output reg Q,
output wire notQ,
input wire D,
input wire Clk
);
always@(posedge Clk)
Q<=D;
wire Cin;
//internal wires
endmodule
//Full adder from previous lab
`timescale 1 ns/ 1 ps
`default_nettype none
module full_adder(S, Cout, A, B, Cin);
input wire A, B, Cin;
output wire S, Cout;
assign #6 S = A ^ B ^ Cin;
assign #4 andAB = A & B;
assign #4 andBCin = B & Cin;
assign #4 andACin = A & Cin;
assign #6 Cout = andAB | andBCin | andACin;
//XORed
//ANDed
//AND for BCin
//AND for ACin
//ORed together
endmodule
//adder_synchronous
`timescale 1 ns/ 1 ps
`default_nettype none
module adder_synchronous(Carry_reg, Sum_reg, Clk, A, B);
output reg Carry_reg;
output reg [1:0] Sum_reg;
//Outputs
//internal wires
endmodule
//adder_2bit_tb
`timescale 1ns / 1ps
module add_2bit_tb;//a test bench does not have any ports of its own!
/* Input nets */
reg [1:0] A; //these are regs because they are modified in
reg [1:0] B; //a behavioral block
/* Output nets */
wire [1:0] Sum; //these are wires because they will be driven
wire Carry;//by the inantiated module
/* Instantiate the Unit Under Test (UUT) */
adder_2bit uut ( //this is a different way
.A(A),
//to instantiate a module.
.B(B),
//the nice thing about this style
.Sum(Sum), //is that the order does not matter!
.Carry(Carry)//notice the ports are in a different order!
);
#25;
if({Carry, Sum} != 3'b101)//you could put your own message here
$display("Ah crap... something went wrong here...");
else
$display("Hey! The UUT passed this test vector...");
{A,B} = 4'b1100; //stimulate the inputs
#25;
if({Carry, Sum} != 3'b011)//you could put your own message here
$display("Ah crap... something went wrong here...");
else
$display("Hey! The UUT passed this test vector...");
{A,B} = 4'b1101; //stimulate the inputs
#25;
if({Carry, Sum} != 3'b100)//you could put your own message here
$display("Ah crap... something went wrong here...");
else
$display("Hey! The UUT passed this test vector...");
{A,B} = 4'b1110; //stimulate the inputs
#25;
if({Carry, Sum} != 3'b101)//you could put your own message here
$display("Ah crap... something went wrong here...");
else
$display("Hey! The UUT passed this test vector...");
{A,B} = 4'b1111; //stimulate the inputs
#25;
if({Carry, Sum} != 3'b110)//you could put your own message here
$display("Ah crap... something went wrong here...");
else
$display("Hey! The UUT passed this test vector...");
$stop;
end
endmodule
Results:
The results below are the waveforms that were created by running the source code found in the
design section with the test benches that had been previously made (some of which had to be
modified.) The bottom of the screen in each waveform demonstrates that all of the tests were
passed and the waveform itself displays the time delay that was being demonstrated in many of
the circuits. Each of the waveforms turned out much like I had expected and the circuits that
were run multiple times with different time delays proved to show the time delay accurately.
10
11
12
13
14
Conclusion:
Questions:
1. Source code shown in design section
2. Waveform diagrams shown in results section.
3. Questions throughout lab:
a. Now, change the 2 unit delays in your code to 4 units and run the test bench
again. Explain the results of the simulation.
Using the 4 ns delay caused the Q and notQ results to be delayed by 4ns instead
of 2 ns and the R, S, and En bits stayed the same as they were from the 2 ns
simulation. This makes sense because the inputs do not have the time delay
applied to them, the time delay comes through the circuit and the outputs are the
ones affected.
b. Simulate your D ip-op using the d ip op tb.v le in the course directory.
Add the internal nets within your D ip-op to the waveform and examine the
waveform after restarting the simulation. Do the latches behave as expected?
Why or why not?
The latches behave as expected when the internal nets have been added.
c. Compare the waveforms you captured from the behavioral Verilog
(d_latch_behavioral.v and d_flip_flop_behavioral.v) to those captured from the
structural Verilog. Are they different? If so, how?
The main difference is the time it took to start receiving data for Q and notQ. It
15
was significantly faster in the behavioral Verilog than it was in the structural
Verilog. Also, the D Latch had no time delay in the behavioral, but a significant
delay in the structural.
4. Compare the behavioral description of the synchronous adder found in the test
bench code with the combination of structural and dataflow Verilog you used in the
lab assignment. What are the advantages and disadvantages of each? Which to you
prefer and why?
The advantage to using the behavioral description is that it is very concise and to the
point because it uses one statement that then decides what kind of output it is going to be
rather than having to go through each specific answer and check it. In structural and
dataflow Verilog it is precise, but efficiency is lost because it has to read for each specific
output rather than just paying attention to the output behavior as a whole. I prefer
behavioral Verilog when it comes to this because it makes for nicer looking code that
works efficiently.
5. Based on the clock period you measured for your synchronous adder, what would
be the theoretical maximum clock rate? What would be the effect of increasing the
width of the adder on the clock rate? How might you improve the clock rate of the
design?
The timescale that the circuit can be reduced to and still work is 20 ns which works at a
50MHz clock rate. Increasing the width of the adder would cause the clock rate to drop
because it has to work with more inputs than previously and this would result in more of
a time delay which causes a drop in clock rate. Improving the clock rate of the design
would be best executed by decreasing the time delay in the circuit by simplifying the
circuit to less gates or by using gates with less time delay.
Student Feedback:
1. I liked that this lab was clear and to the point while also having enough questions in it
allowing for me to actually learn what I was doing. I feel like I am learning Verilog in an
efficient way and using the knowledge that I already have in order to build upon. It was
nice to see the differences between structural and behavioral circuits again and write my
own test bench parts.
2. Nothing about the lab manual was unclear.
3. Keep it exactly as it is. This lab works so nicely with the preceding labs.
16