hw2 Solution
hw2 Solution
(a) Sketch a gate-level schematic of the circuit described by the Verilog code below. [4 pts]
(b) Try to simplify the schematic by sharing gates when possible. [2 pts]
module circuit1(a, b, c, y z)
input a, b, c;
output y,z;
Solution:
Part (a):
a a
b b
c c
y
a a
b b
c c
a
b
y
a
b
Part (b):
y
b
(a) Sketch a gate-level schematic of the circuit described by the Verilog code below (using only
simple logic gates)
(b) Try to simplify the schematic by sharing gates and eliminating unnecessary gates.
(c) Write an equivalent implementation of circuit2 that uses the Verilog “case” construct.
module circuit2(a, y)
input [3:0] a;
output [1:0] y;
always @(*)
if (a[0]) y = 2'b11;
else if (a[1]) y=2'b10;
else if (a[2]) y=2'b01;
else if (a[3]) y=2'b00;
else y=a[1:0];
endmodule
Solution:
Part (a):
a[3] a
a[2]
a[1]
2
a[0] out
a[1:0] 0 2
0 2
2
00 1 0 b
2 2
01 1 0
2 2
s
10 1
2
y
11 1
Part (b):
2
a[1:0] 2
2
[0]
[0]
[1] 2
[0] [0]
[1] 2 2
a[3] a[2] [1] [1] 2
2
y
a[1]
a[0]
5 always @(*)
6 //Need to handle the precidence in the if/else
7 case(a)
8 //First if
18 //Second if
19 4'b0010: y = 2'b10; //The actual greycode
20 //4'b0110: y = 2'b10; Handled by default
21 //4'b1010: y = 2'b10; Handled by default
22 //4'b1110: y = 2'b10; Handled by default
23
24 //Third if
25 4'b0100: y = 2'b01; //The actual greycode
26 4'b1100: y = 2'b01;
27
28 //Fourth if
29 4'b1000: y = 2'b00; //The actual greycode
30 default: y = a[1:0];
31 endcase
32 endmodule
There is a more consise way of describing this circuit using a casez statement. The casez allows
you to specify don’t cares with ‘?’s in case statements.
5 always @(*)
6 //Need to handle the precidence in the if/else
7 casez(a)
8 //First if
9 4'b???1: y = 2'b11;
10 //Second if
11 4'b??10: y = 2'b10;
12 //Third if
13 4'b?100: y = 2'b01;
14 //Fourth if
15 4'b1000: y = 2'b00;
16 default: y = a[1:0];
17 endcase
18 endmodule
Solution:
Verilog Modules:
1 //Structural
2 module Decoder_strucural(
3 output x0,
4 output x1,
5 output x2,
6 output x3,
7 input a,
8 input b);
9
19 //Behavioral
20 module Decoder_behavioral(
21 output reg x0,
22 output reg x1,
23 output reg x2,
24 output reg x3,
25 input a,
26 input b);
27
38 endmodule
(a) Write a Verilog testbench that would instantiate and exhaustively test a 4-bit Gray-code to
binary-code converter. (Hint: you may use the generator presented in class.)
(b) Draw the gate-level circuit diagram of the 4-bit Grey-code to binary converter.
Solution:
Part (a): Verilog Module:
1 // From Slides
2 module gray2bin1 (bin, gray);
3 parameter SIZE = 8;
4 output [SIZE-1:0] bin;
5 input [SIZE-1:0] gray;
6
7 genvar i;
8
Verilog Testbench:
1 `timescale 1ns/1ns
2 module bin_gray_tester();
3 reg [3:0] in;
4 reg [3:0] out_bin2gray;
5 wire [3:0] out_gray2bin;
6 wire match;
7
8 reg fail;
9
10 initial in = 0;
11 initial fail = 0;
12
39 always #2 begin
40 in = in + 4'd1;
41 end
42
43 initial begin
44 $dumpfile("dump.vcd"); //Setup file dump (for waveform viewer)
45 $dumpvars; //Dump signals to dumpfile
46
47 #33
48 if(fail)
49 $display("Test FAIL");
50 else
51 $display("Test PASS");
52 $finish();
53 end
54
55 initial begin
56 #1
57 forever begin
58 $strobe("time: %4d, in: %b, out_bin2gray: %b, out_bin2gray: %b,
,→ match %b", $time, in, out_bin2gray, out_gray2bin, match);
59 #2;
60 end
61 end
62
63 initial begin
64 #1
65 forever begin
66 if(!match)
67 fail = 1;
68 #2;
69 end
70 end
71 endmodule
Another method is to use a binary to Gray-code converter to produce a series of gray codes.
These Gray-codes can be fed to our Gray-code to binary converter which should convert to the
origional binary number. The binary to Gray-code converter used here comes from Weste &
Harris pg 471.
15 genvar i;
16 generate
17 for(i = N-2; i>=0; i = i-1) begin:gray_chain
18 assign gray[i] = bin[i+1] ^ bin[i];
19 end
20 endgenerate
21 endmodule
1 `timescale 1ns/1ns
2 module bin_gray_tester();
3 reg [3:0] in;
4 wire [3:0] out_bin2gray;
5 wire [3:0] out_gray2bin;
6 wire match;
7
8 reg fail;
9
10 initial in = 0;
11 initial fail = 0;
12
19 always #2 begin
20 in = in + 4'd1;
21 end
22
23 initial begin
24 $dumpfile("dump.vcd"); //Setup file dump (for waveform viewer)
25 $dumpvars; //Dump signals to dumpfile
26
27 #33
28 if(fail)
29 $display("Test FAIL");
30 else
31 $display("Test PASS");
32 $finish();
33 end
34
35 initial begin
36 #1
37 forever begin
38 $strobe("time: %4d, in: %b, out_bin2gray: %b, out_bin2gray: %b,
,→ match %b", $time, in, out_bin2gray, out_gray2bin, match);
39 #2;
40 end
41 end
42
43 initial begin
44 #1
45 forever begin
46 if(!match)
47 fail = 1;
48 #2;
49 end
50 end
51 endmodule
Part (b):
b[3]
g[3]
b[2]
g[2]
b[1]
g[1]
b[0]
g[0]
Subtraction, for instance A-B, can be implemented as A+(-B). Therefore, any adder circuit can be
converted to a subtractor by converting B to its 2’s complement, defined as ∼B+1.
Write a structural Verilog module as follows: module add_sub(A, B, R, add) which produces
A+B if “add” is equal to 1 and produces A-B otherwise.
(hint, for an adder, the carry-in to the first stage provides an easy way to add 1 to the final result).
Solution:
Verilog Modules:
1 module full_adder (
2 input a,
3 input b,
4 input carry_in,
5 output sum,
6 output carry_out
7 );
8
9 wire aXORb;
10 xor(aXORb, a, b);
11 xor(sum, aXORb, carry_in);
12
13 wire carryAB;
14 and(carryAB, a, b);
15
16 wire carryCIN;
17 and(carryCIN, aXORb, carry_in);
18
22 module structural_adder_subtractor
23 #(parameter N=14)(
24 input [N-1:0] A,
25 input [N-1:0] B,
26 output [N-1:0] R,
27 input add);
28
34 genvar i;
35 generate
36 for(i = 0; i<N; i = i + 1) begin:adder_chain
37 xor(second_operand[i], B[i], ~add);
38
39 full_adder fa(.a(A[i]),
40 .b(second_operand[i]),
41 .carry_in(carry[i]),
42 .sum(R[i]),
43 .carry_out(carry[i+1]));
44 end
45 endgenerate
46
47 endmodule
(a) Write the Verilog description for a LUT3 (3 input LUT with 1 output) module. It will have 4
inputs. The first three are the single bit LUT inputs: a, b, c. The last input, F, specifies the
LUT function as an 8 bit number. For instance if F=8’h01, the LUT implements an AND
gate. If F = 8’h7F, it implements an OR gate.
(b) Using only the LUT3 module you created, write a LUT4 module using structural Verilog.
Solution:
Verilog Modules:
1 module lut3(
2 input a,
3 input b,
4 input c,
5 input [7:0] F,
6 output out);
7
20 module lut4(
21 input a,
22 input b,
23 input c,
24 input d,
25 input [15:0] F,
26 output out);
27 //Assuming d is the MSB of the input
28
33 //The lower half of F is when d is true. Within that half, the LSB is
,→ when a, b, c are true
34 lut3 f_true_lut(.a(a), .b(b), .c(c), .F(F[7:0]), .out(d_true_lut_out));
35
36 //The upper half of F is when d is false. Within that half, the LSB is
,→ when a, b, c are true
37 lut3 f_false_lut(.a(a), .b(b), .c(c), .F(F[15:8]),
,→ .out(d_false_lut_out));
38
Appendix
Solution:
Problem 2: Example Testbench:
1 `timescale 1ns/1ns
2 module citcuit2_tester();
3 reg [3:0] in;
4 wire [1:0] out_orig;
5 wire [1:0] out_case;
6
7 wire match;
8 reg fail;
9
10 initial in = 0;
11 initial fail = 0;
12
24 initial begin
25 $dumpfile("dump.vcd"); //Setup file dump (for waveform viewer)
26 $dumpvars; //Dump signals to dumpfile
27
28 #33
29 if(fail)
30 $display("Test FAIL");
31 else
32 $display("Test PASS");
33 $finish();
34 end
35
36 //Print
37 initial begin
38 #1
39 forever begin
40 $strobe("time: %4d, in: %b, out_orig: %b, out_case: %b, match %b",
,→ $time, in, out_orig, out_case, match);
41 #2;
42 end
43 end
44
55 endmodule
1 `timescale 1ns/1ns
2 module decoder_tester();
3 reg [1:0] in;
4
5 wire x0_stru;
6 wire x1_stru;
7 wire x2_stru;
8 wire x3_stru;
9 wire [3:0] out_stru;
10
11 wire x0_beha;
12 wire x1_beha;
13 wire x2_beha;
14 wire x3_beha;
15 wire [3:0] out_beha;
16
17 reg fail;
18 wire match;
19
20 initial in = 0;
21 initial fail = 0;
22
29
32 always #2 begin
33 in = in + 2'd1;
34 end
35
36 initial begin
37 $dumpfile("dump.vcd"); //Setup file dump (for waveform viewer)
38 $dumpvars; //Dump signals to dumpfile
39
40 #9
41 if(fail)
42 $display("Test FAIL");
43 else
44 $display("Test PASS");
45 $finish();
46 end
47
48 initial begin
49 #1
50 forever begin
51 $strobe("time: %4d, in: %b, out_stru: %b, out_beha: %b, match %b",
,→ $time, in, out_stru, out_beha, match);
52 #2;
53 end
54 end
55
56 initial begin
57 #1
58 forever begin
59 if(!match)
60 fail = 1;
61 #2;
62 end
63 end
64 endmodule
1 module behavioral_adder_subtractor
2 #(parameter N=14)(
3 input [N:0] A,
4 input [N:0] B,
5 output [N:0] R,
6 input add);
10 endmodule
11
12 `timescale 1ns/1ns
13 module adder_tester();
14 reg [6:0] in;
15
19 reg fail;
20 wire match;
21
22 initial in = 0;
23 initial fail = 0;
24
32
39 always #2 begin
40 in = in + 2'd1;
41 end
42
43 initial begin
44 $dumpfile("dump.vcd"); //Setup file dump (for waveform viewer)
45 $dumpvars; //Dump signals to dumpfile
46
47 #257
48 if(fail)
49 $display("Test FAIL");
50 else
51 $display("Test PASS");
52 $finish();
53 end
54
55 initial begin
56 #1
57 forever begin
58 $strobe("time: %4d, a: %2d, b: %2d, add: %b, out_stru: %2d,
,→ out_beha: %2d, match %b", $time, op_a, op_b, op_add, out_stru,
,→ out_beha, match);
59 #2;
60 end
61 end
62
63 initial begin
64 #1
65 forever begin
66 if(!match)
67 fail = 1;
68 #2;
69 end
70 end
71 endmodule
1 `timescale 1ns/1ns
2 module lut4_tester();
3 reg [5:0] in;
4
5 wire out_lut4;
6
7 reg fail;
8 wire match;
9
10 initial in = 0;
11 initial fail = 0;
12
13 wire op_a;
14 wire op_b;
15 wire op_c;
16 wire op_d;
17 wire [1:0] func_ind;
18
56 always #2 begin
57 in = in + 6'd1;
58 end
59
60 initial begin
61 $dumpfile("dump.vcd"); //Setup file dump (for waveform viewer)
62 $dumpvars; //Dump signals to dumpfile
63
64 #129
65 if(fail)
66 $display("Test FAIL");
67 else
68 $display("Test PASS");
69 $finish();
70 end
71
72 initial begin
73 #1
74 forever begin
75 $strobe("time: %4d, a: %b, b: %b, c: %b, d: %b, func_ind: %d, func:
,→ %b, out_lut4: %b, out_static: %b, match %b", $time, op_a, op_b,
,→ op_c, op_d, func_ind, func, out_lut4, out_static, match);
76 #2;
77 end
78 end
79
80 initial begin
81 #1
82 forever begin
83 if(!match)
84 fail = 1;
85 #2;
86 end
87 end
88 endmodule