Computer
Arithmetic
and
Verilog HDL
Fundamentals
Chapter 5
Fixed-Point
Subtraction
Verilog Code
Figures
Page
245, Figure 5.2
//structural
8-bit ripple-carry adder/subtractor
module
adder_subt_ripple8 (a, b, m, rslt, cout, ovfl);
input [7:0]
a, b;
input m;
output [7:0]
rslt, cout;
output ovfl;
//define
internal nets
wire net1,
net3, net5, net7,
net9, net11, net13, net15;
//instantiate
the xor and the full adder for FA0
xor inst1
(net1, b[0], m);
full_adder
inst2 (
.a(a[0]),
.b(net1),
.cin(m),
.sum(rslt[0]),
.cout(cout[0])
);
//instantiate
the xor and the full adder for FA1
xor inst3
(net3, b[1], m);
full_adder
inst4 (
.a(a[1]),
.b(net3),
.cin(cout[0]),
.sum(rslt[1]),
.cout(cout[1])
);
//instantiate
the xor and the full adder for FA2
xor inst5
(net5, b[2], m);
full_adder
inst6 (
.a(a[2]),
.b(net5),
.cin(cout[1]),
.sum(rslt[2]),
.cout(cout[2])
);
//instantiate
the xor and the full adder for FA3
xor
inst7 (net7, b[3], m);
full_adder
inst8 (
.a(a[3]),
.b(net7),
.cin(cout[2]),
.sum(rslt[3]),
.cout(cout[3])
);
//instantiate
the xor and the full adder for FA4
xor inst9
(net9, b[4], m);
full_adder
inst10 (
.a(a[4]),
.b(net9),
.cin(cout[3]),
.sum(rslt[4]),
.cout(cout[4])
);
//instantiate
the xor and the full adder for FA5
xor
inst11 (net11, b[5], m);
full_adder
inst12 (
.a(a[5]),
.b(net11),
.cin(cout[4]),
.sum(rslt[5]),
.cout(cout[5])
);
//instantiate
the xor and the full adder for FA6
xor
inst13 (net13, b[6], m);
full_adder
inst14 (
.a(a[6]),
.b(net13),
.cin(cout[5]),
.sum(rslt[6]),
.cout(cout[6])
);
//instantiate
the xor and the full adder for FA7
xor
inst15 (net15, b[7], m);
full_adder
inst16 (
.a(a[7]),
.b(net15),
.cin(cout[6]),
.sum(rslt[7]),
.cout(cout[7])
);
//instantiate
the xor gate to detect overflow
xor
inst17 (ovfl, cout[6], cout[7]);
endmodule
//test
bench for structural adder-subtractor
module
adder_subt_ripple8_tb;
reg [7:0]
a, b;
reg m;
wire [7:0]
rslt, cout;
wire ovfl;
initial //display
variables
$monitor
("a=%b, b=%b, m=%b, rslt=%b, ovfl=%b",
a, b, m, rslt, ovfl);
initial //apply
input vectors
begin
//addition
#0 a
= 8'b0000_0000; b =
8'b0000_0001; m = 1'b0;
#10 a
= 8'b0010_1101; b =
8'b1100_0101; m = 1'b0;
#10 a
= 8'b0000_0110; b =
8'b0000_0001; m = 1'b0;
#10 a
= 8'b0000_0101; b =
8'b0011_0001; m = 1'b0;
#10 a = 8'b1000_0000; b = 8'b0101_1100; m = 1'b0;
#10 a
= 8'b1110_1101; b =
8'b0101_0101; m = 1'b0;
#10 a
= 8'b1111_1111; b =
8'b1111_1111; m = 1'b0;
#10 a
= 8'b1111_1111; b =
8'b1111_0001; m = 1'b0;
//subtraction
#10 a
= 8'b0000_0000; b =
8'b0000_0001; m = 1'b1;
#10 a = 8'b0010_1101; b = 8'b0000_0101; m = 1'b1;
#10 a
= 8'b0000_0110; b =
8'b0000_0001; m = 1'b1;
#10 a
= 8'b0001_0101; b =
8'b0011_0001; m = 1'b1;
#10 a
= 8'b1000_0000; b =
8'b1001_1100; m = 1'b1;
#10 a
= 8'b1110_1101; b =
8'b0101_0101; m = 1'b1;
#10 a
= 8'b1111_1111; b =
8'b1111_1111; m = 1'b1;
#10 a
= 8'b1110_1111; b =
8'b1111_0001; m = 1'b1;
//overflow
#10 a
= 8'b0111_1111; b =
8'b0101_0101; m = 1'b0;
#10 a
= 8'b1010_1101; b =
8'b1011_0101; m = 1'b0;
#10 a
= 8'b0110_0110; b =
8'b1100_0001; m = 1'b1;
#10 a
= 8'b1000_0101; b =
8'b0010_0001; m = 1'b1;
#10 $stop;
end
//instantiate
the module into the test bench
adder_subt_ripple8
inst1 (
.a(a),
.b(b),
.m(m),
.rslt(rslt),
.cout(cout),
.ovfl(ovfl)
);
endmodule
Page 253, Figure 5.8
//dataflow
and built-in primitives for an
//8-bit
2s complementer for add and subtract
module
twos_compl_add_sub_8 (b, mode, rslt);
input [7:0]
b;
input mode;
output [7:0]
rslt;
assign
rslt[0] = b[0];
and inst1 (net1, b[0], mode);
xor inst2 (rslt[1], b[1], net1);
or inst3 (net3, b[1], b[0]);
and inst4 (net4, net3, mode);
xor inst5 (rslt[2], b[2], net4);
or inst6 (net6, b[2], net3);
and inst7 (net7, net6, mode);
xor inst8 (rslt[3], b[3], net7);
or inst9 (net9, b[3], net6);
and inst10
(net10, net9, mode);
xor inst11
(rslt[4], b[4], net10);
or inst12
(net12, b[4], net9);
and inst13
(net13, net12, mode);
xor inst14
(rslt[5], b[5], net13);
or inst15
(net15, b[5], net12);
and inst16
(net16, net15, mode);
xor inst17
(rslt[6], b[6], net16);
or inst18
(net18, b[6], net15);
and inst19
(net19, net18, mode);
xor inst20
(rslt[7], b[7], net19);
endmodule
//test
bench for 8-bit 2s complementer for add and sub
module
twos_compl_add_sub_8_tb;
reg [7:0]
b;
reg mode;
wire [7:0]
rslt;
//apply
input vectors and display variables
initial
begin:
apply_stimulus
reg
[9:0] invect;
for
(invect = 0; invect < 512; invect = invect + 1)
begin
{b,
mode} = invect [9:0];
#10 $display ("b = %b, mode = %b,
rslt = %b",
b, mode, rslt);
end
end
//instantiate
the module into the test bench
twos_compl_add_sub_8
inst1 (
.b(b),
.mode(mode),
.rslt(rslt)
);
endmodule
Page 260, Figure 5.13
//structural
and built-in primitives for an
//8-bit
carry lookahead adder/subtractor
module
add_sub_cla8 (a, b, mode, sum_diff, cout, ovfl);
input [7:0]
a, b;
input mode;
output [7:0]
sum_diff;
output cout,
ovfl;
//define
internal nets
wire [7:0]
rslt;
wire net3,
net5, net6, net7, net8,
net10, net11, net12, net13, net14,
net16, net17, net18, net19, net20,
net23, net24, net25, net26,
net28, net29, net30, net31, net32,
net34, net35, net36, net37, net38,
net39,
net41, net42, net43, net44, net45,
net46,
net48, net49;
//instantiate
the 2s complementer
twos_compl_add_sub_8
inst1 (
.b(b),
.mode(mode),
.rslt(rslt)
);
//----------------------------------------------
//instantiate
the logic for group 0
//----------------------------------------------
//instantiate
the logic for FA0 of group 0
full_adder
inst2 (
.a(a[0]),
.b(rslt[0]),
.cin(1'b0),
.sum(sum_diff[0])
);
//instantiate
the logic for FA1 of group 0
and inst3
(net3, a[0], rslt[0]); //g0
full_adder
inst4 (
.a(a[1]),
.b(rslt[1]),
.cin(net3),
.sum(sum_diff[1])
);
//instantiate
the logic for FA2 of group 0
and inst5
(net5, a[1], rslt[1]); //g1
xor inst6
(net6, a[1], rslt[1]); //p1
and inst7
(net7, net6, a[0], rslt[0]);
or inst8 (net8, net5, net7); //g1,p1,g0
full_adder
inst9 (
.a(a[2]),
.b(rslt[2]),
.cin(net8),
.sum(sum_diff[2])
);
//instantiate
the logic for FA3 of group 0
and inst10
(net10, a[2], rslt[2]); //g2
xor inst11
(net11, a[2], rslt[2]); //p2
and inst12
(net12, net11, a[1], rslt[1]); //p2,g1
and inst13
(net13, net11, net6, a[0], rslt[0]); //p2,p1,g0
or inst14
(net14, net10, net12, net13);//g2,p2,g1,p2,p1,g0
full_adder
inst15 (
.a(a[3]),
.b(rslt[3]),
.cin(net14),
.sum(sum_diff[3])
);
//instantiate
the logic for the carry from group 0 grp0_cy
and inst16 (net16, a[3], rslt[3]); //g3
xor inst17 (net17, a[3], rslt[3]); //p3
and inst18 (net18, net17, a[2], rslt[2]); //p3,g2
and inst19 (net19, net17, net11, a[1], rslt[1]);
//p3,p2,g1
and inst20 (net20, net17, net11, net6, a[0],
rslt[0]);
//p3,p2,p1,g0
or inst21 (grp0_cy, net16, net18, net19,
net20);
//g3,p3,g2,p3,p2,g1,p3,p2,p1,g0
//----------------------------------------------
//instantiate
the logic for group 1
//----------------------------------------------
//instantiate
the logic for FA4 of group 1
full_adder
inst22 (
.a(a[4]),
.b(rslt[4]),
.cin(grp0_cy),
.sum(sum_diff[4])
);
//instantiate
the logic for FA5 of group 1
and inst23
(net23, a[4], rslt[4]); //g4
xor inst24
(net24, a[4], rslt[4]); //p4
and inst25
(net25, net24, grp0_cy); //p4,grp0_cy
or inst26
(net26, net23, net25); //g4,p4,grp0_cy
full_adder
inst27 (
.a(a[5]),
.b(rslt[5]),
.cin(net26),
.sum(sum_diff[5])
);
//instantiate
the logic for FA6 of group 1
and inst28
(net28, a[5], rslt[5]); //g5
xor inst29
(net29, a[5], rslt[5]); //p5
and inst30
(net30, net29, a[4], rslt[4]); //p5,g4
and inst31
(net31, net29, net24, grp0_cy); //p5,p4,grp0_cy
or inst32
(net32, net28, net30, net31);
//g5,p5,g4,p5,p4,grp0_cy
full_adder
inst33 (
.a(a[6]),
.b(rslt[6]),
.cin(net32),
.sum(sum_diff[6])
);
//instantiate
the logic for FA7 of group 1
and inst34
(net34, a[6], rslt[6]); //g6
xor inst35
(net35, a[6], rslt[6]); //p6
and inst36
(net36, net35, a[5], rslt[5]); //p6,g5
and inst37
(net37, net35, net29, a[4], rslt[4]);
//p6,p5,g4
and inst38
(net38, net35, net29, net24, grp0_cy);
//p6,p5,p4,grp0_cy
or inst39
(net39, net34, net36, net37, net38);
//g6,p6,g5,p6,p5,g4,p6,p5,p4,grp0_cy
full_adder
inst40 (
.a(a[7]),
.b(rslt[7]),
.cin(net39),
.sum(sum_diff[7])
);
//instantiate
the logic for the carry from group 1 cout
and inst41
(net41, a[7], rslt[7]); //g7
xor inst42
(net42, a[7], rslt[7]); //p7
and inst43
(net43, net42, a[6], rslt[6]); //p7,g6
and inst44
(net44, net42, net35, a[5], rslt[5]);
//p7,p6,g5
and inst45
(net45, net42, net35, net29, a[4], rslt[4]);
//p7,p6,p5,g4
and inst46
(net46, net42, net35, net29, net24, grp0_cy);
//p7,p6,p5,p4,grp0_cy
or inst47
(cout, net41, net43, net44, net45, net46);
//g7,p7,g6,p7,p6,g5,p7,p6,p5,g4,p7,p6,p5,p4,grp0_cy
//--------------------------------------------------
//instantiate
the logic to detect overflow
//--------------------------------------------------
and inst48
(net48, a[7], rslt[7], ~sum_diff[7]);
and inst49
(net49, ~a[7], ~rslt[7], sum_diff[7]);
or inst50
(ovfl, net48, net49);
endmodule
Page 264, Figure 5.14
//test
bench for the 8-bit
//carry
lookahead adder/subtractor
module
add_sub_cla8_tb;
reg [7:0]
a, b;
reg mode;
wire [7:0]
sum_diff;
wire cout,
ovfl;
//display
variables
initial
$monitor
("a=%b, b=%b, mode=%b, sum_diff=%b, ovfl=%b",
a, b, mode, sum_diff, ovfl);
//apply
input vectors
initial
begin
#0 a = 8'b0000_0000; b = 8'b0000_0001; mode =
1'b0;
#10 a
= 8'b0000_0000; b = 8'b0000_0001; mode = 1'b1;
#10 a
= 8'b0000_0110; b = 8'b0000_0011; mode = 1'b0;
#10 a
= 8'b0000_0110; b = 8'b0000_0011; mode = 1'b1;
#10 a
= 8'b0000_1100; b = 8'b0000_0101; mode = 1'b0;
#10 a
= 8'b0000_1100; b = 8'b0000_0101; mode = 1'b1;
#10 a
= 8'b0000_0001; b = 8'b1111_1001; mode = 1'b0;
#10 a
= 8'b0000_0001; b = 8'b1111_1001; mode = 1'b1;
#10 a
= 8'b0000_0001; b = 8'b1000_0001; mode = 1'b0;
#10 a
= 8'b0000_0001; b = 8'b1000_0001; mode = 1'b1;
#10 a
= 8'b1111_0000; b = 8'b0000_0001; mode = 1'b0;
#10 a
= 8'b1111_0000; b = 8'b0000_0001; mode = 1'b1;
#10 a
= 8'b0110_1101; b = 8'b0100_0101; mode = 1'b0;
#10 a
= 8'b0010_1101; b = 8'b0000_0101; mode = 1'b1;
#10 a
= 8'b0000_0110; b = 8'b0000_0001; mode = 1'b0;
#10 a
= 8'b0000_0110; b = 8'b0000_0001; mode = 1'b1;
#10 a
= 8'b0001_0101; b = 8'b0011_0001; mode = 1'b0;
#10 a
= 8'b0001_0101; b = 8'b0011_0001; mode = 1'b1;
#10 a
= 8'b1000_0000; b = 8'b1001_1100; mode = 1'b0;
#10 a
= 8'b1000_0000; b = 8'b1001_1100; mode = 1'b1;
#10 a
= 8'b1110_1101; b = 8'b0101_0101; mode = 1'b0;
#10 a
= 8'b1110_1101; b = 8'b0101_0101; mode = 1'b1;
#10 a
= 8'b1111_1111; b = 8'b1111_1111; mode = 1'b0;
#10 a
= 8'b1111_1111; b = 8'b1111_1111; mode = 1'b1;
#10 a
= 8'b1110_1111; b = 8'b1111_0001; mode = 1'b0;
#10 a
= 8'b1110_1111; b = 8'b1111_0001; mode = 1'b1;
#10 a
= 8'b0111_1111; b = 8'b0101_0101; mode = 1'b0;
#10 a
= 8'b1010_1101; b = 8'b1011_0101; mode = 1'b1;
#10 a
= 8'b0110_0110; b = 8'b1100_0001; mode = 1'b0;
#10 a
= 8'b0110_0110; b = 8'b1100_0001; mode = 1'b1;
#10 a
= 8'b1000_0101; b = 8'b0010_0001; mode = 1'b0;
#10 a
= 8'b1000_0101; b = 8'b0010_0001; mode = 1'b1;
#10 a
= 8'b0111_0110; b = 8'b1101_0101; mode = 1'b0;
#10 a
= 8'b0111_0110; b = 8'b1101_0101; mode = 1'b1;
#10 a = 8'b0110_0111; b = 8'b1110_0111; mode =
1'b0;
#10 a
= 8'b0110_0111; b = 8'b1110_0111; mode = 1'b1;
#10 a
= 8'b1111_1111; b = 8'b1111_1111; mode = 1'b0;
#10 a
= 8'b1111_1111; b = 8'b1111_1111; mode = 1'b1;
#10 $stop;
end
//instantiate
the module into the test bench
add_sub_cla8
inst1 (
.a(a),
.b(b),
.mode(mode),
.sum_diff(sum_diff),
.cout(cout),
.ovfl(ovfl)
);
endmodule
Page 267, Figure 5.16
//behavioral
8-bit adder/subtractor
module
add_sub_bh (a, b, mode, rslt, ovfl);
input [7:0]
a, b;
input mode;
output [7:0]
rslt;
output ovfl;
wire [7:0]
a, b;
wire mode;
reg [7:0]
rslt;
reg ovfl;
reg [7:0]
neg_b = ~b + 1;
always @ (a or b or mode)
begin
//add
if
(mode == 0)
begin
rslt
= a + b;
ovfl
= (a[7] & b[7] & ~rslt[7]) |
~a[7] & ~b[7] &
rslt[7]);
end
//subtract
else
begin
rslt
= a + neg_b;
ovfl
= (a[7] & neg_b[7] & ~rslt[7]) |
(~a[7]
& ~neg_b[7] & rslt[7]);
end
end
endmodule
//test
bench for the 8-bit
//carry
lookahead adder/subtractor
module
add_sub_bh_tb;
reg [7:0]
a, b;
reg mode;
wire [7:0]
rslt;
wire ovfl;
//display
variables
initial
$monitor
("a=%b, b=%b, mode=%b, result=%b, ovfl=%b",
a, b, mode, rslt, ovfl);
//apply
input vectors
initial
begin
#0 a = 8'b0000_0000; b = 8'b0000_0001; mode =
1'b0;
#10 a
= 8'b0000_0000; b = 8'b0000_0001; mode = 1'b1;
#10 a
= 8'b0000_0110; b = 8'b0000_0011; mode = 1'b0;
#10 a
= 8'b0000_0110; b = 8'b0000_0011; mode = 1'b1;
#10 a
= 8'b0000_1100; b = 8'b0000_0101; mode = 1'b0;
#10 a
= 8'b0000_1100; b = 8'b0000_0101; mode = 1'b1;
#10 a
= 8'b0000_0001; b = 8'b1111_1001; mode = 1'b0;
#10 a
= 8'b0000_0001; b = 8'b1111_1001; mode = 1'b1;
#10 a
= 8'b0000_0001; b = 8'b1000_0001; mode = 1'b0;
#10 a
= 8'b0000_0001; b = 8'b1000_0001; mode = 1'b1;
#10 a
= 8'b1111_0000; b = 8'b0000_0001; mode = 1'b0;
#10 a
= 8'b1111_0000; b = 8'b0000_0001; mode = 1'b1;
#10 a
= 8'b0110_1101; b = 8'b0100_0101; mode = 1'b0;
#10 a
= 8'b0010_1101; b = 8'b0000_0101; mode = 1'b1;
#10 a
= 8'b0000_0110; b = 8'b0000_0001; mode = 1'b0;
#10 a
= 8'b0000_0110; b = 8'b0000_0001; mode = 1'b1;
#10 a
= 8'b0001_0101; b = 8'b0011_0001; mode = 1'b0;
#10 a
= 8'b0001_0101; b = 8'b0011_0001; mode = 1'b1;
#10 a
= 8'b1000_0000; b = 8'b1001_1100; mode = 1'b0;
#10 a
= 8'b1000_0000; b = 8'b1001_1100; mode = 1'b1;
#10 a
= 8'b1110_1101; b = 8'b0101_0101; mode = 1'b0;
#10 a
= 8'b1110_1101; b = 8'b0101_0101; mode = 1'b1;
#10 a
= 8'b1111_1111; b = 8'b1111_1111; mode = 1'b0;
#10 a
= 8'b1111_1111; b = 8'b1111_1111; mode = 1'b1;
#10 a
= 8'b1110_1111; b = 8'b1111_0001; mode = 1'b0;
#10 a
= 8'b1110_1111; b = 8'b1111_0001; mode = 1'b1;
#10 a
= 8'b0111_1111; b = 8'b0101_0101; mode = 1'b0;
#10 a
= 8'b1010_1101; b = 8'b1011_0101; mode = 1'b1;
#10 a
= 8'b0110_0110; b = 8'b1100_0001; mode =
1'b0;
#10 a = 8'b0110_0110; b = 8'b1100_0001; mode = 1'b1;
#10 a = 8'b1000_0101; b = 8'b0010_0001; mode = 1'b0;
#10 a = 8'b1000_0101; b = 8'b0010_0001; mode = 1'b1;
#10 a = 8'b0111_0110; b = 8'b1101_0101; mode = 1'b0;
#10 a = 8'b0111_0110; b = 8'b1101_0101; mode = 1'b1;
#10 a = 8'b0110_0111; b = 8'b1110_0111; mode = 1'b0;
#10 a = 8'b0110_0111; b = 8'b1110_0111; mode = 1'b1;
#10 a = 8'b1111_1111; b = 8'b1111_1111; mode = 1'b0;
#10 a = 8'b1111_1111; b = 8'b1111_1111; mode = 1'b1;
#10 $stop;
end
//instantiate
the module into the test bench
add_sub_bh
inst1 (
.a(a),
.b(b),
.mode(mode),
.rslt(rslt),
.ovfl(ovfl)
);
endmodule
Computer
Arithmetic
and
Verilog HDL
Fundamentals
Chapter 6
Fixed-Point
Multiplication
Verilog Code
Figures
Page 282, Figure
6.4
//behavioral
add-shift multiply
module
mul_add_shift3 (a, b, prod, start);
input [3:0]
a, b;
input
start;
output [7:0]
prod;
reg [7:0]
prod;
reg [3:0]
b_reg;
reg [3:0]
count;
always @ (posedge start)
begin
b_reg
= b;
prod = 0;
count = 4'b0100;
if ((a!=0) && (b!=0))
while
(count)
begin
prod
= {(({4{b_reg[0]}} & a)
+
prod[7:4]), prod[3:1]};
b_reg
= b_reg >> 1;
count
= count - 1;
end
end
endmodule
//test
bench for add-shift multiplier
module
mul_add_shift3_tb;
reg [3:0]
a, b;
reg
start;
wire [7:0]
prod;
//display
variables
initial
$monitor
("a = %b, b = %b, prod = %b",
a, b, prod);
//apply
input vectors
initial
begin
#0 start
= 1'b0;
a = 4'b0110; b = 4'b0110;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a
= 4'b0010; b = 4'b0110;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a
= 4'b0111; b = 4'b0101;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a = 4'b0111; b = 4'b0111;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a
= 4'b0101; b = 4'b0101;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a
= 4'b0111; b = 4'b0011;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a
= 4'b0100; b = 4'b0110;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 $stop;
end
//instantiate
the module into the test bench
mul_add_shift3
inst1 (
.a(a),
.b(b),
.prod(prod),
.start(start)
);
endmodule
Page 286, Figure
6.8
//behavioral
add-shift multiply
module
mul_add_shift5 (a, b, prod, start);
input [3:0]
a, b;
input
start;
output [7:0]
prod;
//define
internal registers
reg [7:0]
prod;
reg [3:0]
count;
always @ (posedge start)
begin
prod
[7:4] = 4'b0000;
prod [3:0] = b;
count = 4'b0100;
if ((a!=0) && (b!=0))
while
(count)
begin
if
(prod[0] == 1'b0)
begin
prod
= {prod[7], prod[7:1]};
count = count - 1;
end
else
begin
prod
= {a[3], (a + prod[7:4]), prod[3:1]};
count = count - 1;
end
end
end
endmodule
//test
bench for add-shift multiplier
module
mul_add_shift5_tb;
reg [3:0]
a, b;
reg start;
wire [7:0]
prod;
//display
variables
initial
$monitor
("a = %b, b = %b, prod = %b",
a, b, prod);
//apply
input vectors
initial
begin
#0 start = 1'b0;
a = 4'b0110; b = 4'b0110;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a
= 4'b0010; b = 4'b0110;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a
= 4'b0111; b = 4'b0101;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a
= 4'b0111; b = 4'b0111;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a
= 4'b1111; b = 4'b0111;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a
= 4'b1011; b = 4'b0111;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a
= 4'b1000; b = 4'b0001;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a = 4'b1010; b = 4'b0111;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a
= 4'b1101; b = 4'b0101;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a
= 4'b0100; b = 4'b0111;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 $stop;
end
//instantiate
the module into the test bench
mul_add_shift5
inst1 (
.a(a),
.b(b),
.prod(prod),
.start(start)
);
endmodule
Page 296, Figure 6.12
//mixed-design
for the Booth multiply algorithm
module
booth4 (a, b, prod);
input [7:0]
a, b;
output
[15:0] prod;
wire [7:0]
a, b;
wire
[15:0] prod;
wire [7:0]
a_bar;
//define
internal wires
wire
[15:0] a_ext_pos;
wire
[15:0] a_ext_neg;
//define
internal registers
reg [7:0]
a_neg;
reg
[15:0] pp1, pp2, pp3, pp4, pp5, pp6, pp7, pp8;
//test
b[1:0] --------------------------------------
assign a_bar
= ~a;
always @
(a_bar)
a_neg = a_bar + 1;
//define
16-bit multiplicand and 2s comp of multiplicand
assign
a_ext_pos = {{8{a[7]}}, a};
assign
a_ext_neg = {{8{a_neg[7]}}, a_neg};
always @ (b or a_ext_pos or a_ext_neg)
begin
case
(b[1:0])
2'b00 :
begin
pp1
= 16'h00;
pp2 = 16'h00;
end
2'b01
:
begin
pp1
= a_ext_neg;
pp2 = {{7{a[7]}}, a[7:0], 1'b0};
end
2'b10 :
begin
pp1
= 16'h00;
pp2 = {a_ext_neg[14:0], 1'b0};
end
2'b11 :
begin
pp1
= a_ext_neg;
pp2 = 16'h00;
end
endcase
end
//test
b[2:1] --------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
case
(b[2:1])
2'b00: pp3 = 16'h00;
2'b01: pp3 = {a_ext_pos[13:0], 2'b00};
2'b10: pp3 = {a_ext_neg[13:0], 2'b00};
2'b11: pp3 = 16'h00;
endcase
end
//test
b[3:2] --------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
case
(b[3:2])
2'b00: pp4 = 16'h00;
2'b01: pp4 = {a_ext_pos[12:0], 3'b000};
2'b10: pp4 = {a_ext_neg[12:0], 3'b000};
2'b11: pp4 = 16'h00;
endcase
end
//test
b[4:3] ---------------------------------------
always @ (b
or a_ext_pos or a_ext_neg)
begin
case
(b[4:3])
2'b00: pp5 = 16'h00;
2'b01: pp5 = {a_ext_pos[11:0],
4'b0000};
2'b10: pp5 = {a_ext_neg[11:0],
4'b0000};
2'b11: pp5 = 16'h00;
endcase
end
//test
b[5:4] ---------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
case
(b[5:4])
2'b00: pp6 = 16'h00;
2'b01: pp6 = {a_ext_pos[10:0],
5'b00000};
2'b10: pp6 = {a_ext_neg[10:0],
5'b00000};
2'b11: pp6 = 16'h00;
endcase
end
//test
b[6:5] ---------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
case
(b[6:5])
2'b00: pp7 = 16'h00;
2'b01: pp7 = {a_ext_pos[9:0],
6'b000000};
2'b10: pp7 = {a_ext_neg[9:0],
6'b000000};
2'b11: pp7 = 16'h00;
endcase
end
//test
b[7:6] ---------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
case
(b[7:6])
2'b00: pp8 = 16'h00;
2'b01: pp8 = {a_ext_pos[8:0],
7'b0000000};
2'b10: pp8 = {a_ext_neg[8:0],
7'b0000000};
2'b11: pp8 = 16'h00;
endcase
end
assign prod
= pp1 + pp2 + pp3 + pp4 + pp5 + pp6 + pp7 + pp8;
endmodule
//test
bench for booth algorithm
module
booth4_tb;
//registers
for inputs because they hold values
reg [7:0]
a, b;
wire
[15:0] prod;
//display
operands a, b, and product
initial
$monitor
("a = %b, b = %b, prod = %h", a, b, prod);
//apply
input vectors
initial
begin
//for
examples 6.6 through 6.10
#0 a
= 8'b0001_1011;
b = 8'b0111_1000;
#10 a
= 8'b1010_1101;
b = 8'b0011_1110;
#10 a
= 8'b0100_1010;
b = 8'b1101_1100;
#10 a
= 8'b1010_0010;
b = 8'b1101_1100;
#10 a
= 8'b0100_1110;
b = 8'b0010_1011;
//test
b[1:0] ---------------------------------------
#10 a
= 8'b1100_1100;
b = 8'b1100_1100;
#10 a
= 8'b1100_1100;
b = 8'b1100_1101;
#10 a
= 8'b1100_1100;
b = 8'b1100_1110;
#10 a
= 8'b1100_1100;
b = 8'b1100_1111;
//test
b[2:1] ---------------------------------------
#10 a
= 8'b0111_1111;
b = 8'b1011_1000;
#10 a
= 8'b1011_0011;
b = 8'b1100_1011;
#10 a
= 8'b0111_0000;
b = 8'b0111_0100;
#10 a
= 8'b0111_0000;
b = 8'b0111_0110;
//test
b[3:2] ---------------------------------------
#10 a
= 8'b0111_1111;
b = 8'b1011_0000;
#10 a
= 8'b1011_0011;
b = 8'b1100_0111;
#10 a
= 8'b0111_0000;
b = 8'b0111_1000;
#10 a
= 8'b0111_0000;
b = 8'b0111_1110;
//test
b[4:3] ---------------------------------------
#10 a
= 8'b0111_1111;
b = 8'b1010_0000;
#10 a
= 8'b1011_0011;
b = 8'b1100_1111;
#10 a
= 8'b0111_0000;
b = 8'b0111_0000;
#10 a
= 8'b0111_0000;
b = 8'b0111_1110;
//test
b[5:4] ---------------------------------------
#10 a
= 8'b0111_1111;
b = 8'b1000_0000;
#10 a
= 8'b1011_0011;
b = 8'b1101_1111;
#10 a
= 8'b0111_0000;
b = 8'b0110_0000;
#10 a
= 8'b0111_0000;
b = 8'b0111_1110;
//test
b[6:5] ---------------------------------------
#10 a = 8'b0111_1111;
b = 8'b1000_0000;
#10 a
= 8'b1011_0011;
b = 8'b1010_1111;
#10 a
= 8'b0111_0000;
b = 8'b0101_0000;
#10 a
= 8'b0111_0000;
b = 8'b0111_1110;
//test
b[7:6] ---------------------------------------
#10 a
= 8'b0111_1111;
b = 8'b0010_0000;
#10 a
= 8'b1011_0011;
b = 8'b0100_1111;
#10 a
= 8'b0111_0000;
b = 8'b1011_0000;
#10 a
= 8'b0111_0000;
b = 8'b1111_1110;
#10 $stop;
end
//instantiate
the module into the test bench
booth4
inst1 (
.a(a),
.b(b),
.prod(prod)
);
endmodule
Page 313, Figure
6.25
//behavioral
and dataflow for bit-pair multiplier
module
bit_pair (a, b, prod);
input [7:0]
a, b;
output
[15:0] prod;
wire [7:0]
a, b;
wire
[15:0] prod;
//define
internal wires
wire [7:0]
a_bar;
wire
[15:0] a_ext_pos; //positive
A with sign extension
wire
[15:0] a_ext_neg; //A
negated with sign extension
//define
internal registers
reg [7:0]
a_neg;
reg
[15:0] pp1, pp2, pp3, pp4; //partial
products
//1s
complement of A
assign a_bar
= ~a;
//2s
complement of A
always @
(a_bar)
a_neg = a_bar + 1;
//define
a_ext_pos and a_ext_neg
//extend
sign of positive A to 16 bits
assign
a_ext_pos = {{8{a[7]}}, a};
//extend
sign of negative A to 16 bits
assign
a_ext_neg = {{8{a_neg[7]}}, a_neg};
//test
b[1:0] ----------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
case
(b[1:0]) //test bits 1 and 0
with 0
2'b00: //(000) = 0 times multiplicand
pp1 = 16'h0000;
2'b01: //(010) = +1 times multiplicand
pp1 = a_ext_pos;
2'b10: //(100) = -2 times multiplicand
pp1 = {a_ext_neg[14:8],
a_neg, 1'b0};
2'b11: //(110) = -1 times multiplicand
pp1 = a_ext_neg;
endcase
end
//test
b[3:1] ---------------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
case
(b[3:1]) //test bits 3 and
2 with 1
3'b000: //0
times multiplicand
pp2 = 16'h0000;
3'b001: //+1
times multiplicand
pp2 = {a_ext_pos[13:0],
2'b00};
3'b010: //+1
times multiplicand
pp2 = {a_ext_pos[13:0],
2'b00};
3'b011: //+2
times multiplicand
pp2 = {a_ext_pos[12:0],
3'b000};
3'b100: //-2
times multiplicand
pp2 = {a_ext_neg[12:0],
3'b000};
3'b101: //-1
times multiplicand
pp2 = {a_ext_neg[13:0],
2'b00};
3'b110: //-1
times multiplicand
pp2 = {a_ext_neg[13:0],
2'b00};
3'b111: //0
times multiplicand
pp2 = 16'h0000;
endcase
end
//continued
on next page
//test
b[5:3] ---------------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
case
(b[5:3]) //test bits 5 and
4 with 3
3'b000: //0
times multiplicand
pp3 = 16'h0000;
3'b001: //+1
times multiplicand
pp3 = {a_ext_pos[11:0],
4'b0000};
3'b010: //+1
times multiplicand
pp3 = {a_ext_pos[11:0],
4'b0000};
3'b011: //+2
times multiplicand
pp3 = {a_ext_pos[10:0],
5'b00000};
3'b100: //-2
times multiplicand
pp3 = {a_ext_neg[10:0],
5'b00000};
3'b101: //-1
times multiplicand
pp3 = {a_ext_neg[11:0],
4'b0000};
3'b110: //-1
times multiplicand
pp3 = {a_ext_neg[11:0],
4'b0000};
3'b111: //0
times multiplicand
pp3 = 16'h0000;
endcase
end
//test
b[7:5] --------------------------------------------
always @ (b or a_ext_pos or a_ext_neg)
begin
case
(b[7:5]) //test bits 7 and
6 with 5
3'b000: //0
times multiplicand
pp4 = 16'h0000;
3'b001: //+1
times multiplicand
pp4 = {a_ext_pos[9:0],
6'b000000};
3'b010: //+1
times multiplicand
pp4 = {a_ext_pos[9:0],
6'b000000};
3'b011: //+2
times multiplicand
pp4 = {a_ext_pos[8:0],
7'b0000000};
3'b100: //-2
times multiplicand
pp4 = {a_ext_neg[8:0],
7'b0000000};
3'b101: //-1
times multiplicand
pp4 = {a_ext_neg[9:0],
6'b000000};
3'b110: //-1
times multiplicand
pp4 = {a_ext_neg[9:0],
6'b000000};
3'b111: //0
times multiplicand
pp4 = 16'h0000;
endcase
end
//define
product
assign prod
= pp1 + pp2 + pp3 + pp4;
endmodule
//test
bench for the bit-pair multiplier
module
bit_pair_tb;
reg [7:0]
a, b;
wire
[15:0] prod;
//display
operands a, b, and prod
initial
$monitor
("a = %b, b = %b, prod = %h", a, b, prod);
//apply
input vectors
initial
begin
#0 a = 8'b1100_0111; //a = -57
b = 8'b1010_1101; //b = -83 product = ffc7h
#10 a = 8'b0000_0110; //a = +6
b = 8'b1110_1000; //b = -24 product = ff70h
#10 a
= 8'b1110_1111; //a =
-17
b = 8'b0000_1001; //b = +9 product = ff67h
#10 a
= 8'b0001_0011; //a =
+19
b = 8'b0011_0110; //b = +54 product = 0402h
#10 a
= 8'b0001_1001; //a =
+25
b = 8'b0101_1000; //b = +88 product = 0898h
#10 a
= 8'b0001_1001; //a =
+25
b = 8'b0110_1110; //b = +110 product = 0abeh
#10 a
= 8'b0011_1101; //a =
+61
b
= 8'b1110_0011; //b =
-29 product = 1917h
#10 a
= 8'b1100_1111; //a =
-49
b = 8'b1110_0001; //b = -31 product = 05efh
#10 a
= 8'b1111_1111; //a = -1
b = 8'b1111_1111; //b = -1 product = 0001h
#10 a
= 8'b1111_1111; //a = -1
b = 8'b0000_0001; //b = +1 product = ffffh
#10 a
= 8'b1100_0111; //a =
-57
b = 8'b1000_1100; //b = -116 product = 19d4h
#10 a
= 8'b0011_1110; //a =
+62
b = 8'b0100_1000; //b = +72 product = 1170h
#10 $stop;
end
//instantiate
the module into the test bench
bit_pair
inst1 (
.a(a),
.b(b),
.prod(prod)
);
endmodule
Page 321, Figure
6.35
//dataflow
2-input and gate
module
and2_df (x1, x2, z1);
input x1,
x2;
output z1;
wire x1,
x2;
wire z1;
assign z1 =
x1 & x2;
endmodule
//dataflow
full adder
module
full_adder (a, b, cin, sum, cout);
//list
all inputs and outputs
input a, b,
cin;
output sum,
cout;
//define
wires
wire a, b,
cin;
wire sum,
cout;
//continuous
assign for dataflow
assign sum =
(a ^ b) ^ cin;
assign cout
= cin & (a ^ b) | (a & b);
endmodule
//structural
array multiplier 4 bits
module
array_mul4 (a, b, prod);
//define
inputs and outputs
input [3:0]
a, b;
output [7:0]
prod;
wire [3:0]
a, b;
wire [7:0]
prod;
//define
internal wires
wire net1,
net2, net3, net4, net5, net6, net7, net8,
net9, net10, net11, net12, net13,
net14, net15, net16,
net17, net18, net19, net20, net21, net22,
net23, net24,
net25, net26, net27, net28, net29,
net30, net31, net32;
//instantiate
the logic for product[0]
and2_df
inst1 (
.x1(a[0]),
.x2(b[0]),
.z1(prod[0]) //product[0]
);
//instantiate
the logic for product[1]
and2_df
inst2 (
.x1(a[1]),
.x2(b[0]),
.z1(net1)
);
and2_df
inst3 (
.x1(a[0]),
.x2(b[1]),
.z1(net2)
);
full_adder
inst4 (
.a(net1),
.b(net2),
.cin(1'b0),
.sum(prod[1]), //product[1]
.cout(net3)
);
//instantiate
the logic for product[2]
and2_df
inst5 (
.x1(a[2]),
.x2(b[0]),
.z1(net4)
);
and2_df
inst6 (
.x1(a[1]),
.x2(b[1]),
.z1(net5)
);
full_adder
inst7 (
.a(net4),
.b(net5),
.cin(1'b0),
.sum(net6),
.cout(net7)
);
and2_df
inst8 (
.x1(a[0]),
.x2(b[2]),
.z1(net8)
);
full_adder
inst9 (
.a(net6),
.b(net8),
.cin(net3),
.sum(prod[2]), //product[2]
.cout(net9)
);
//instantiate
the logic for product[3]
and2_df
inst10 (
.x1(a[3]),
.x2(b[0]),
.z1(net10)
);
and2_df
inst11 (
.x1(a[2]),
.x2(b[1]),
.z1(net11)
);
full_adder
inst12 (
.a(net10),
.b(net11),
.cin(1'b0),
.sum(net12),
.cout(net13)
);
and2_df
inst13 (
.x1(a[1]),
.x2(b[2]),
.z1(net14)
);
full_adder
inst14 (
.a(net12),
.b(net14),
.cin(net7),
.sum(net15),
.cout(net16)
);
and2_df
inst15 (
.x1(a[0]),
.x2(b[3]),
.z1(net17)
);
full_adder
inst16 (
.a(net15),
.b(net17),
.cin(net9),
.sum(prod[3]), //product[3]
.cout(net18)
);
//instantiate
the logic for product[4]
and2_df
inst17 (
.x1(a[3]),
.x2(b[1]),
.z1(net19)
);
and2_df
inst18 (
.x1(a[2]),
.x2(b[2]),
.z1(net20)
);
full_adder
inst19 (
.a(net19),
.b(net20),
.cin(net13),
.sum(net21),
.cout(net22)
);
and2_df
inst20 (
.x1(a[1]),
.x2(b[3]),
.z1(net23)
);
full_adder
inst21 (
.a(net21),
.b(net23),
.cin(net16),
.sum(net24),
.cout(net25)
);
full_adder
inst22 (
.a(net24),
.b(1'b0),
.cin(net18),
.sum(prod[4]), //product[4]
.cout(net26)
);
//instantiate
the logic for product[5]
and2_df
inst23 (
.x1(a[3]),
.x2(b[2]),
.z1(net27)
);
and2_df
inst24 (
.x1(a[2]),
.x2(b[3]),
.z1(net28)
);
full_adder
inst25 (
.a(net27),
.b(net28),
.cin(net22),
.sum(net29),
.cout(net30)
);
full_adder
inst26 (
.a(net29),
.b(net26),
.cin(net25),
.sum(prod[5]), //product[5]
.cout(net31)
);
//instantiate
the logic for product[6] and product[7]
and2_df
inst27 (
.x1(a[3]),
.x2(b[3]),
.z1(net32)
);
full_adder
inst28 (
.a(net32),
.b(net31),
.cin(net30),
.sum(prod[6]), //product[6]
.cout(prod[7]) //product[7]
);
endmodule
//test
bench for array multiplier 4 bits
module
array_mul4_tb;
reg [3:0]
a, b;
wire [7:0]
prod;
//apply
input vectors
initial
begin :
apply_stimulus
reg
[8:0] invect;
for
(invect=0; invect<256; invect=invect+1)
begin
{a,
b} = invect [8:0];
#10 $display ("a = %d, b = %d,
product = %d", a, b, prod);
end
end
//instantiate
the module into the test bench
array_mul4
inst1 (
.a(a),
.b(b),
.prod(prod)
);
endmodule
Page 331, Figure
6.41
//behavioral
multiplication table lookup
module
mul_table_lookup (a, b, start, prod);
input [7:0]
a;
input [8:0]
b;
input
start;
output
[19:0] prod;
//define
internal registers
reg
[19:0] prod;
reg [1:0]
count;
reg
[19:0] sum;
reg [8:0]
b_reg;
//define
memory size
//memory
is an array of eleven 8-bit registers
reg
[10:0] mpcnd_table [0:7];
//define
memory contents
//load
mpcnd_table from file mem.mpcnd
initial
begin
$readmemb
("mem.mpcnd", mpcnd_table);
end
always @ (posedge start)
begin
prod
[19:0] = 20'h00000;
count = 2'b11;
b_reg = b;
if
((a!=0) && (b!=0))
while
(count)
begin
sum
= {{mpcnd_table[b_reg[2:0]], 9'b0000_0000_0}
+ prod[19:0]};
prod = {{3{sum[19]}}, sum[19:3]};
b_reg = b_reg >> 3;
count = count - 1;
end
end
endmodule
//test
bench for multiplication using table lookup
module
mul_table_lookup_tb;
reg [7:0]
a;
reg [8:0]
b;
reg
start;
wire
[19:0] prod;
//display
variables
initial
$monitor
("a=%b, b=%b, prod=%b", a, b, prod);
//apply
input vectors
initial
begin
#0 start = 1'b0;
//6 x 1 = 6 = 00006h
a = 8'b0000_0110; b = 9'b0_0000_0001;
#10 start
= 1'b1;
#10 start
= 1'b0;
//6 x 11 = 66 = 00042h
#10 a
= 8'b0000_0110; b =
9'b0_0000_1011;
#10 start
= 1'b1;
#10 start
= 1'b0;
//6 x 6 = 36 = 00024h
#10 a
= 8'b0000_0110; b =
9'b0_0000_0110;
#10 start
= 1'b1;
#10 start
= 1'b0;
//6 x 46 = 276 = 00114h
#10 a
= 8'b0000_0110; b =
9'b0_0010_1110;
#10 start
= 1'b1;
#10 start
= 1'b0;
//6 x 159 = 954 = 003bah
#10 a
= 8'b0000_0110; b = 9'b0_1001_1111;
#10 start
= 1'b1;
#10 start
= 1'b0;
//6 x 170 = 1020 = 003fch
#10 a
= 8'b0000_0110; b = 9'b0_1010_1010;
#10 start
= 1'b1;
#10 start
= 1'b0;
//6 x 255 = 1530 = 005fah
#10 a
= 8'b0000_0110; b = 9'b0_1111_1111;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 $stop;
end
//instantiate
the module into the test bench
mul_table_lookup
inst1 (
.a(a),
.b(b),
.start(start),
.prod(prod)
);
endmodule
Page 336, Figure
6.45
//behavioral
multiplication table lookup
module
mul_table_lookup_neg (a, b, start, prod);
input [7:0]
a;
input [8:0]
b;
input
start;
output
[19:0] prod;
//define
internal registers
reg
[19:0] prod;
reg [1:0]
count;
reg
[19:0] sum;
reg [8:0]
b_reg;
//define
memory size
//memory
is an array of eight 8-bit registers
reg
[10:0] mpcnd_table [0:7];
//define
memory contents
//load
mpcnd_table from file mem.mpcnd
initial
begin
$readmemb
("mem.mpcnd", mpcnd_table);
end
always @ (posedge start)
begin
prod
[19:0] = 20'h00000;
count = 2'b11;
b_reg = b;
if
((a!=0) && (b!=0))
while
(count)
begin
sum
= {{mpcnd_table[b_reg[2:0]], 9'b0000_0000_0}
+ prod[19:0]};
prod = {{3{sum[19]}}, sum[19:3]};
b_reg = b_reg >> 3;
count = count - 1;
end
end
endmodule
//test
bench for multiplication using table lookup
module
mul_table_lookup_neg_tb;
reg [7:0]
a;
reg [8:0]
b;
reg
start;
wire
[19:0] prod;
//display
variables
initial
$monitor
("a=%b, b=%b, prod=%b", a, b, prod);
//apply
input vectors
initial
begin
//multiplicand
= -30
#0 start
= 1'b0;
//-30 x 1 = -30 = fffe2h
a = 8'b1110_0010; b = 9'b0_0000_0001;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 a
= 8'b1110_0010; b = 9'b0_0000_1011;
#10 start
= 1'b1;
#10 start
= 1'b0;
//-30 x 6 = -180 = fff4ch
#10 a
= 8'b1110_0010; b =
9'b0_0000_0110;
#10 start
= 1'b1;
#10 start
= 1'b0;
//-30 x 46 = -1380 = ffa9ch
#10 a
= 8'b1110_0010; b =
9'b0_0010_1110;
#10 start
= 1'b1;
#10 start
= 1'b0;
//-30 x 159 = -4770 = fed5eh
#10 a
= 8'b1110_0010; b =
9'b0_1001_1111;
#10 start
= 1'b1;
#10 start
= 1'b0;
//-30 x 170 = -5100 = fec14h
#10 a
= 8'b1110_0010; b =
9'b0_1010_1010;
#10 start
= 1'b1;
#10 start
= 1'b0;
//-30 x 255 = -7650 = fe21eh
#10 a
= 8'b1110_0010; b =
9'b0_1111_1111;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 $stop;
end
//instantiate
the module into the test bench
mul_table_lookup_neg
inst1 (
.a(a),
.b(b),
.start(start),
.prod(prod)
);
endmodule
Page 341, Figure
6.51
//behavioral
to add two operands
module
mem_mul (mpcnd, mplyr, prod);
//list
inputs and outputs
input [2:0]
mpcnd, mplyr;
output [5:0]
prod;
//list
wire and reg
wire [2:0]
mpcnd, mplyr;//mpcnd and mplyr to address 64 words
reg [5:0]
prod;
//define
memory size
//mem_mul
is an array of 64 six-bit registers
reg [5:0]
mem_mul [0:63];
//define
memory contents
//load
mem_mul from file opnds.mul
initial
begin
$readmemb
("opnds.mul", mem_mul);
end
//use
the operands to access the memory
always @
(mpcnd or mplyr)
begin
prod = mem_mul [{mpcnd, mplyr}];
end
endmodule
//test
bench for mem_mul module
module
mem_mul_tb;
reg [2:0]
mpcnd, mplyr;
wire [5:0]
prod;
//display
variables
initial
$monitor
("mpcnd = %b, mplyr = %b, prod = %b",
mpcnd, mplyr, prod);
//apply
input vectors for multiplicand and multiplier
initial
begin
#0 mpcnd = 3'b000; mplyr = 3'b011;
#10 mpcnd
= 3'b001; mplyr = 3'b001;
#10 mpcnd
= 3'b001; mplyr = 3'b011;
#10 mpcnd
= 3'b001; mplyr = 3'b100;
#10 mpcnd
= 3'b001; mplyr = 3'b111;
#10 mpcnd
= 3'b010; mplyr = 3'b101;
#10 mpcnd
= 3'b010; mplyr = 3'b111;
#10 mpcnd
= 3'b011; mplyr = 3'b011;
#10 mpcnd
= 3'b110; mplyr = 3'b111;
#10 mpcnd
= 3'b100; mplyr = 3'b010;
#10 mpcnd = 3'b100; mplyr = 3'b101;
#10 mpcnd
= 3'b100; mplyr = 3'b100;
#10 mpcnd
= 3'b101; mplyr = 3'b001;
#10 mpcnd
= 3'b101; mplyr = 3'b011;
#10 mpcnd
= 3'b101; mplyr = 3'b111;
#10 mpcnd
= 3'b110; mplyr = 3'b011;
#10 mpcnd
= 3'b110; mplyr = 3'b111;
#10 mpcnd
= 3'b111; mplyr = 3'b001;
#10 mpcnd
= 3'b111; mplyr = 3'b100;
#10 mpcnd
= 3'b111; mplyr = 3'b101;
#10 mpcnd
= 3'b111; mplyr = 3'b110;
#10 mpcnd
= 3'b111; mplyr = 3'b111;
#10 $stop;
end
mem_mul
inst1 ( //instantiate the module
.mpcnd(mpcnd),
.mplyr(mplyr),
.prod(prod)
);
endmodule
Page 346, Figure
6.57
//behavioral
add-shift multiply for multiple operands
module
mul_add_shift_multi (a, b1, b2, start1, start2,
prod8, prod12);
input [3:0]
a, b1, b2;
input
start1, start2;
output [7:0]
prod8;
output
[11:0] prod12;
//define
internal registers
reg [7:0]
prod8;
reg
[11:0] prod12;
reg [3:0]
count;
//design
the behavior for the 4 x 4 multiplier
always @ (posedge start1)
begin
prod8
[7:4] = 4'b0000;
prod8 [3:0] = b1;
count = 4'b0100;
if ((a!=0) && (b1!=0))
while
(count)
begin
if
(prod8[0] == 1'b0)
begin
prod8
= {prod8[7], prod8[7:1]};
count = count - 1;
end
else
begin
prod8
= {a[3], (a + prod8[7:4]),
prod8[3:1]};
count = count - 1;
end
end
end
//design
the behavior for the 8 x 4 multiplier
always @ (posedge start2)
begin
prod12
[11:4] = 8'b0000_0000;
prod12 [3:0] = b2;
count = 4'b0100;
if ((prod8!=0) && (b2!=0))
while
(count)
begin
if
(prod12[0] == 1'b0)
begin
prod12
= {prod12[11], prod12[11:1]};
count = count - 1;
end
else
begin
prod12
= {prod8[7],
(prod8 +
prod12[11:4]),
prod12[3:1]};
count = count - 1;
end
end
end
endmodule
//test
bench for add-shift multiplier
module
mul_add_shift_multi_tb;
reg [3:0]
a, b1, b2;
reg start1,
start2;
wire [7:0]
prod8;
wire
[11:0] prod12;
//display
variables
initial
$monitor
("a=%b, b1=%b, b2=%b, start1=%b, start2=%b,
prod8=%b, prod12=%b",
a, b1, b2, start1, start2, prod8,
prod12);
//apply
input vectors
initial
begin
#0 start1 = 1'b0;
start2 = 1'b0;
//7 x 7 x 2 = 98 (062h)
a=4'b0111; b1=4'b0111; b2=4'b0010;
#10 start1
= 1'b1;
#10 start1
= 1'b0;
#10 start2
= 1'b1;
#10 start2
= 1'b0;
//3 x 7 x 6 = 126 (07eh)
#10 a=4'b0011; b1=4'b0111; b2=
4'b0110;
#10 start1
= 1'b1;
#10 start1
= 1'b0;
#10 start2
= 1'b1;
#10 start2
= 1'b0;
//7
x 5 x 6 = 210 (0d2h)
#10 a=4'b0111; b1=4'b0101; b2=4'b0110;
#10 start1
= 1'b1;
#10 start1
= 1'b0;
#10 start2
= 1'b1;
#10 start2
= 1'b0;
//7 x 4 x 5 = 140 (08ch)
#10 a=4'b0111; b1=4'b0100; b2=4'b0101;
#10 start1
= 1'b1;
#10 start1
= 1'b0;
#10 start2
= 1'b1;
#10 start2
= 1'b0;
//-1 x 7 x 1 = -7 (ff9h)
#10 a=4'b1111; b1=4'b0111; b2=4'b0001;
#10 start1
= 1'b1;
#10 start1
= 1'b0;
#10 start2
= 1'b1;
#10 start2
= 1'b0;
//-5 x 6 x 1 = -30 (fe2h)
#10 a=4'b1011; b1=4'b0110; b2=4'b0001;
#10 start1
= 1'b1;
#10 start1
= 1'b0;
#10 start2
= 1'b1;
#10 start2
= 1'b0;
//-6 x 7 x 5 = -210 (f2eh)
#10 a=4'b1010; b1=4'b0111; b2=4'b0101;
#10 start1
= 1'b1;
#10 start1
= 1'b0;
#10 start2
= 1'b1;
#10 start2
= 1'b0;
//-4 x 7 x 3 = -84 (fach)
#10 a=4'b1100; b1=4'b0111; b2=4'b0011;
#10 start1
= 1'b1;
#10 start1
= 1'b0;
#10 start2
= 1'b1;
#10 start2
= 1'b0;
//-7
x 7 x 7 = -343 (ea9h)
#10 a=4'b1001; b1=4'b0111; b2=4'b0111;
#10 start1
= 1'b1;
#10 start1
= 1'b0;
#10 start2
= 1'b1;
#10 start2
= 1'b0;
#20 $stop;
end
//instantiate
the module into the test bench
mul_add_shift_multi
inst1 (
.a(a),
.b1(b1),
.b2(b2),
.start1(start1),
.start2(start2),
.prod8(prod8),
.prod12(prod12)
);
endmodule
No comments:
Post a Comment