Based on lab and images provided from Dr. Phatak
Updated Oct 2021 Robucci
Model a comparator in Verilog and Learn to include naive delays in Verilog to see signal propagation along a combinational path in simulation
A comparator is an arithmetic device that determines the relative magnitude of two binary numbers and finds applications in numerous digital systems. In general, a comparator can perform a magnitude comparison of two words and in either straight binary or BCD codes. Three fully decoded decisions about the two words are made and are available at the outputs; that is
where if
then the comparator will generate three output signals as follows:
Example 2-bit comparator:
K-Maps of the comparator outputs:
Previously you learned about
A new skill we will learn today is to naively add delays to allow us to see signal propagation along a combinational path.
Actual delays are dependent on the type of gate, number of inputs (fan-in), and load (which is based on factors such as the number of gates being driven, also called fan-out). We will assume all gates have input-to-output propagation delay 1.
Examine compare code without and then with delays added to understand how to add delay in your Verilog Code. It will be added to the instantiations.
Example code without delay:
// Sum of Products, y=f(a,b,c) module sop_nodelay(a,b,c,y); input a,b,c; output logic y; logic a_n,b_n,c_n; not not00(a_n,a); not not01(b_n,b); not not02(c_n,c); and and00(p0, a, b); and and01(p1,b, c_n); or or00(y,p0,p1); endmodule
Since Verilog primitives don’t have any default delay, all internal signals and the output will appear to change at the same time in simulation. Realize that in previous labs that you were given modules (models of the physical ICs), that had embedded specifications of delay that could be enabled during simulation using the specify
flag. We are not using such IC modules here and instead using in-built Verilog primitives. You will now be explicitly specifying simulation delays within your own code.
To add the naive delay of 1 time unit to all gates, include #1
is added to the primitive instantiations as in the following module.
Also note the code that in on the first line:
`timescale 1ns / 100ps
This specifies that the default time unit and time resolution will be 1 ns, meaning that #1
will correspond to 1 ns. It also specifies the the time resolution is 100ps – so for instance #1.3
could be used to specify 1.3 ns, but #1.31
is also 1.3 ns. We will only use #1
for simplicity.
`timescale 1ns / 100ps // Sum of Products, y=f(a,b,c) module sop_naivedelay(y,a,b,c); input a,b,c; output logic y; logic a_n,b_n,c_n,p0,p1; not #1 not00(a_n,a); not #1 not01(b_n,b); not #1 not02(c_n,c); and #1 and00(p0, a, b); and #1 and01(p1,b, c_n); or #1 or00(y,p0,p1); endmodule
Here is a Testbench that you can use to perform the simulation and observe the signal propagation along a path:
`timescale 1ns / 100ps module sop_naivedelay_tb; // Variables for Testbench to drive DUT Inputs logic a_tb,b_tb,c_tb; // Nets from DUT outputs logic y_tb; // DUT (device under test // instantiate the module to test here: sop_naivedelay DUT (.y(y_tb),.a(a_tb),.b(b_tb),.c(c_tb)); initial begin $monitor($time, " TB: y=%1b,a=%1b,b=%1b,c=%1b DUT:a_n=%1b,b_n=%1b,c_n=%1b,p0=%1b,p1=%1b", y_tb,a_tb,b_tb,c_tb,DUT.a_n,DUT.b_n,DUT.c_n,DUT.p0,DUT.p1); //note use of hierarchical signal referencing DUT.01 $dumpfile("test.vcd"); $dumpvars(0,sop_naivedelay_tb); //// a_tb =0; b_tb=0; c_tb = 0; #10 a_tb =0; b_tb=0; c_tb = 1; #10 a_tb =0; b_tb=1; c_tb = 0; #10 a_tb =0; b_tb=1; c_tb = 1; #10 a_tb =1; b_tb=0; c_tb = 0; #10 a_tb =1; b_tb=0; c_tb = 1; #10 a_tb =1; b_tb=1; c_tb = 0; #10 a_tb =1; b_tb=1; c_tb = 1; #100; $finish; // can alternatively use $stop to // interact with the simulation instead of closing it. end endmodule
Here is the expected output. The input are changed at multiples of 10 ns.
Look affect of the input change at 20 ns.
The output of the NOT gate changes at 21 ns
The output of AND gate changes at 22 ns.
The output of the OR gate changes 23 ns.
0 TB: y=x,a=0,b=0,c=0 DUT:a_n=z,b_n=z,c_n=z,p0=z,p1=z
1 TB: y=x,a=0,b=0,c=0 DUT:a_n=1,b_n=1,c_n=1,p0=0,p1=0
2 TB: y=0,a=0,b=0,c=0 DUT:a_n=1,b_n=1,c_n=1,p0=0,p1=0
10 TB: y=0,a=0,b=0,c=1 DUT:a_n=1,b_n=1,c_n=1,p0=0,p1=0
11 TB: y=0,a=0,b=0,c=1 DUT:a_n=1,b_n=1,c_n=0,p0=0,p1=0
20 TB: y=0,a=0,b=1,c=0 DUT:a_n=1,b_n=1,c_n=0,p0=0,p1=0
21 TB: y=0,a=0,b=1,c=0 DUT:a_n=1,b_n=0,c_n=1,p0=0,p1=0
22 TB: y=0,a=0,b=1,c=0 DUT:a_n=1,b_n=0,c_n=1,p0=0,p1=1
23 TB: y=1,a=0,b=1,c=0 DUT:a_n=1,b_n=0,c_n=1,p0=0,p1=1
30 TB: y=1,a=0,b=1,c=1 DUT:a_n=1,b_n=0,c_n=1,p0=0,p1=1
31 TB: y=1,a=0,b=1,c=1 DUT:a_n=1,b_n=0,c_n=0,p0=0,p1=1
32 TB: y=1,a=0,b=1,c=1 DUT:a_n=1,b_n=0,c_n=0,p0=0,p1=0
33 TB: y=0,a=0,b=1,c=1 DUT:a_n=1,b_n=0,c_n=0,p0=0,p1=0
40 TB: y=0,a=1,b=0,c=0 DUT:a_n=1,b_n=0,c_n=0,p0=0,p1=0
41 TB: y=0,a=1,b=0,c=0 DUT:a_n=0,b_n=1,c_n=1,p0=0,p1=0
50 TB: y=0,a=1,b=0,c=1 DUT:a_n=0,b_n=1,c_n=1,p0=0,p1=0
51 TB: y=0,a=1,b=0,c=1 DUT:a_n=0,b_n=1,c_n=0,p0=0,p1=0
60 TB: y=0,a=1,b=1,c=0 DUT:a_n=0,b_n=1,c_n=0,p0=0,p1=0
61 TB: y=0,a=1,b=1,c=0 DUT:a_n=0,b_n=0,c_n=1,p0=1,p1=0
62 TB: y=1,a=1,b=1,c=0 DUT:a_n=0,b_n=0,c_n=1,p0=1,p1=1
70 TB: y=1,a=1,b=1,c=1 DUT:a_n=0,b_n=0,c_n=1,p0=1,p1=1
71 TB: y=1,a=1,b=1,c=1 DUT:a_n=0,b_n=0,c_n=0,p0=1,p1=1
72 TB: y=1,a=1,b=1,c=1 DUT:a_n=0,b_n=0,c_n=0,p0=1,p1=0
Done
These delays can also be explored visually in but dumping a vcd file and using a waveform viewer.
We will continue to learn to use hierarchical design, describing simple modules using Boolean expressions and simple gates, and then building more complex modules from the simpler ones. Let’s first explore describing a 1-bit cascade comparator like this one. Design a 1-bit comparator stage.
Complete the truth table for a 1-bit stage of a cascade comparator also explain why the first four sets of inputs are invalid.
Verilog code to be completed in-lab for 1-bit comparator:
module comparator1b (a_lt_b_out, a_eq_b_out, a_gt_B_out, a_lt_b_in, a_eq_b_in, a_gt_B_in, a, b) output logic a_lt_b_out, a_eq_b_out, a_gt_B_out, input a_lt_b_in, a_eq_b_in, a_gt_B_in, a, b; // define any other intermediate nodes here logic // instantiate Verilog primitives with naive unit delay endmodule
Make a Testbench and Demonstrate Operation
To make a 4-Bit cascaded comparator, connect the outputs of the 1-bit comparator as the
cascaded inputs of the next 1-Bit comparator.
4-Bit Cascaded Comparator:
Verilog code to be completed for 4-bit comparator:
module comparator4b ( a_lt_b_out, a_eq_b_out, a_gt_B_out, a_lt_b_in, a_eq_b_in, a_gt_B_in, a3,a2,a1,a0, b3,b2,b1,b0) output logic a_lt_b_out, a_eq_b_out, a_gt_B_out, input a_lt_b_in ,a_eq_b_in, a_gt_B_in, a3,a2,a1,a0,b3,b2,b1,b0; // define any other intermediate nodes here logic // instantiate 4 of comparator1b endmodule
Make a Testbench and Demonstrate Operation