Computer
Arithmetic
and
Verilog HDL
Fundamentals
Chapter 11
Decimal Division
Verilog Code
Figures
Page 532, Figure
11.2
//mixed-design
for bcd restoring division
module
div_bcd (a, b, start, rslt, cout_quot);
input [7:0]
a;
input [3:0]
b;
input
start;
output [7:0]
rslt;
output
cout_quot;
wire [3:0]
b_bar;
//define
internal registers
reg [3:0]
b_neg;
reg [7:0]
rslt;
reg [3:0]
count;
reg [3:0]
quot;
reg
cout_quot;
assign b_bar
= ~b;
always @
(b_bar)
b_neg = b_bar + 1;
always @ (posedge start)
begin
rslt
= a;
count = 4'b0100;
if
((a!=0) && (b!=0))
while
(count)
begin
rslt
= rslt << 1;
rslt = {(rslt[7:4] + b_neg),
rslt[3:0]};
if
(rslt[7] == 1) //restore
begin
rslt
= {(rslt[7:4]+b), rslt[3:1], 1'b0};
count = count - 1;
end
else //no
restore
begin
rslt
= {rslt[7:1], 1'b1};
count = count - 1;
end
end
if
(rslt[3:0] > 4'b1001) //convert to
bcd
{cout_quot, rslt[3:0]} = rslt[3:0] +
4'b0110;
else
cout_quot
= 1'b0;
end
endmodule
//test
bench for bcd restoring division
module
div_bcd_tb;
reg [7:0]
a;
reg [3:0]
b;
reg
start;
wire [7:0]
rslt;
wire
cout_quot;
//display
variables
initial
$monitor
("a=%b, b=%b, quot_tens=%b, quot_units=%b, rem=%b",
a, b, {{3{1'b0}}, cout_quot},
rslt[3:0], rslt[7:4]);
//apply
input vectors
initial
begin
#0 start = 1'b0;
//60 / 7; quot = 8, rem = 4
a = 8'b0011_1100; b = 4'b0111;
#10 start
= 1'b1;
#10 start
= 1'b0;
//13 / 5; quot = 2, rem = 3
#10 a
= 8'b0000_1101; b =
4'b0101;
#10 start
= 1'b1;
#10 start
= 1'b0;
//60 / 7; quot = 8, rem = 4
#10 a
= 8'b0011_1100; b =
4'b0111;
#10 start
= 1'b1;
#10 start
= 1'b0;
//82 / 6; quot = 13, rem = 4
#10 a
= 8'b0101_0010; b =
4'b0110;
#10 start
= 1'b1;
#10 start
= 1'b0;
//56 / 7; quot = 8, rem = 0
#10 a
= 8'b0011_1000; b =
4'b0111;
#10 start
= 1'b1;
#10 start
= 1'b0;
//100 / 7; quot = 14, rem = 2
#10 a
= 8'b0110_0100; b =
4'b0111;
#10 start
= 1'b1;
#10 start
= 1'b0;
//110
/ 7; quot = 15, rem = 5
#10 a
= 8'b0110_1110; b =
4'b0111;
#10 start
= 1'b1;
#10 start
= 1'b0;
//99 / 9; quot = 11, rem = 0
#10 a
= 8'b0110_0011; b = 4'b1001;
#10 start
= 1'b1;
#10 start
= 1'b0;
//99 / 8; quot = 12, rem = 3
#10 a
= 8'b0110_0011; b =
4'b1000;
#10 start
= 1'b1;
#10 start
= 1'b0;
//52 / 5; quot = 10, rem = 2
#10 a
= 8'b0011_0100; b =
4'b0101;
#10 start
= 1'b1;
#10 start
= 1'b0;
//0 / 5; quot = 0, rem = 0; invalid
dividend
#10 a
= 8'b0000_0000; b =
4'b0101;
#10 start
= 1'b1;
#10 start
= 1'b0;
//86 / 5; overflow; results are
indeterminate
#10 a
= 8'b0101_0110; b = 4'b0101;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 $stop;
end
//instantiate
the module into the test bench
div_bcd
inst1 (
.a(a),
.b(b),
.start(start),
.rslt(rslt),
.cout_quot(cout_quot)
);
endmodule
Page 541, Figure
11.8
//mixed-design
bcd restoring division using a multiplexor
module
div_bcd_mux (a, b, start, rslt, cout_quot);
input [7:0]
a; //dividend
input [3:0]
b; //divisor
input
start;
output [7:0]
rslt; //rslt[7:4] is rem;
rslt[3:0] is quot
output
cout_quot;
wire [3:0]
b_bar;
reg [3:0]
b_neg; //define internal
registers
reg [7:0]
rslt;
reg [3:0]
count;
reg [4:0]
sum;
reg cout,
cout_quot;
assign b_bar
= ~b; //1s complement of
divisor
always @
(b_bar)
b_neg = b_bar + 1; //2s complement of divisor
always @ (posedge start)
begin
rslt
= a;
count = 4'b0100;
if
((a!=0) && (b!=0))
while
(count)
begin
rslt
= rslt << 1;
sum = rslt[7:4] + b_neg;
cout = sum[4];
if
(cout == 0)
begin
rslt[0]
= cout; //q0 = cout
rslt[7:4] = rslt[7:4];
count = count -1;
end
else
begin
rslt[0]
= cout; //q0 = cout
rslt[7:4] = sum[3:0];
count = count - 1;
end
end
if
(rslt[3:0] > 4'b1001)
{cout_quot, rslt[3:0]} = rslt[3:0] +
4'b0110;
else
cout_quot = 1'b0;
end
endmodule
//test
bench for restoring division
module
div_bcd_mux_tb;
reg [7:0]
a;
reg [3:0]
b;
reg
start;
wire [7:0]
rslt;
wire
cout_quot;
//display
variables
initial
$monitor
("a=%b, b=%b, quot_tens=%b, quot_units=%b, rem=%b",
a, b, {{3{1'b0}}, cout_quot},
rslt[3:0], rslt[7:4]);
//apply
input vectors
initial
begin
#0 start = 1'b0;
//13 / 5; quot = 2, rem = 3
a = 8'b0000_1101; b = 4'b0101;
#10 start
= 1'b1;
#10 start
= 1'b0;
//60 / 7; quot = 8, rem = 4
#10 a
= 8'b0011_1100; b =
4'b0111;
#10 start
= 1'b1;
#10 start
= 1'b0;
//82
/ 6; quot = 13, rem = 4
#10 a
= 8'b0101_0010; b =
4'b0110;
#10 start
= 1'b1;
#10 start
= 1'b0;
//56 / 7; quot = 8, rem = 0
#10 a
= 8'b0011_1000; b =
4'b0111;
#10 start
= 1'b1;
#10 start
= 1'b0;
//100 / 7; quot = 14, rem = 2
#10 a
= 8'b0110_0100; b =
4'b0111;
#10 start
= 1'b1;
#10 start
= 1'b0;
//110 / 7; quot = 15, rem = 5
#10 a
= 8'b0110_1110; b =
4'b0111;
#10 start
= 1'b1;
#10 start
= 1'b0;
//99 / 9; quot = 11, rem = 0
#10 a
= 8'b0110_0011; b =
4'b1001;
#10 start
= 1'b1;
#10 start
= 1'b0;
//0 / 5; quot = 0, rem = 0; invalid
dividend
#10 a
= 8'b0000_0000; b =
4'b0101;
#10 start
= 1'b1;
#10 start
= 1'b0;
//86 / 5; overflow; results are
indeterminate
#10 a
= 8'b0101_0110; b =
4'b0101;
#10 start
= 1'b1;
#10 start
= 1'b0;
#10 $stop;
end
//instantiate
the module into the test bench
div_bcd_mux
inst1 (
.a(a),
.b(b),
.start(start),
.rslt(rslt),
.cout_quot(cout_quot)
);
endmodule
No comments:
Post a Comment