Computer
Arithmetic
and
Verilog HDL
Fundamentals
Chapter 14
Floating-Point
Multiplication
Verilog Code
Figures
Page 619, Figure
14.4
//behavioral
floating-point multiplication
module
mul_flp (flp_a, flp_b, sign, exponent,
exp_unbiased, exp_sum, prod);
input
[31:0] flp_a, flp_b;
output sign;
output [7:0]
exponent, exp_unbiased;
output [8:0]
exp_sum;
output
[22:0] prod;
//variables
used in an always block are declared as registers
reg
sign_a, sign_b;
reg [7:0]
exp_a, exp_b;
reg [7:0]
exp_a_bias, exp_b_bias;
reg [8:0]
exp_sum;
reg
[22:0] fract_a, fract_b;
reg
[45:0] prod_dbl;
reg
[22:0] prod;
reg sign;
reg [7:0]
exponent, exp_unbiased;
//define
sign, exponent, and fraction
always
@ (flp_a or flp_b)
begin
sign_a = flp_a[31];
sign_b = flp_b[31];
exp_a = flp_a[30:23];
exp_b = flp_b[30:23];
fract_a = flp_a[22:0];
fract_b = flp_b[22:0];
//bias
exponents
exp_a_bias = exp_a + 8'b0111_1111;
exp_b_bias = exp_b + 8'b0111_1111;
//add
exponents
exp_sum = exp_a_bias + exp_b_bias;
//remove
one bias
exponent = exp_sum - 8'b0111_1111;
exp_unbiased = exponent - 8'b0111_1111;
//multiply
fractions
prod_dbl = fract_a * fract_b;
prod = prod_dbl[45:23];
//postnormalize
product
while
(prod[22] == 0)
begin
prod = prod << 1;
exp_unbiased = exp_unbiased - 1;
end
sign = sign_a ^ sign_b;
end
endmodule
//test
bench for floating-point multiplication
module
mul_flp_tb;
reg
[31:0] flp_a, flp_b;
wire sign;
wire [7:0]
exponent, exp_unbiased;
wire [8:0]
exp_sum;
wire
[22:0] prod;
//display
variables
initial
$monitor
("sign = %b, exp_biased = %b, exp_unbiased = %b,
prod = %b",
sign, exp_sum, exp_unbiased, prod);
//apply
input vectors
initial
begin
//+5
x +3 = +15
// s ----e---- --------------f-------------
#0 flp_a
= 32'b0_0000_0011_1010_0000_0000_0000_0000_000;
flp_b =
32'b0_0000_0010_1100_0000_0000_0000_0000_000;
//+6 x +4 = +24
// s ----e----
--------------f-------------
#10 flp_a
= 32'b0_0000_0011_1100_0000_0000_0000_0000_000;
flp_b =
32'b0_0000_0011_1000_0000_0000_0000_0000_000;
//-5 x +5 = -25
// s ----e----
--------------f-------------
#10 flp_a
= 32'b1_0000_0011_1010_0000_0000_0000_0000_000;
flp_b =
32'b0_0000_0011_1010_0000_0000_0000_0000_000;
//+7 x -5 = -35
// s ----e----
--------------f-------------
#10 flp_a
= 32'b0_0000_0011_1110_0000_0000_0000_0000_000;
flp_b =
32'b1_0000_0011_1010_0000_0000_0000_0000_000;
//+25 x +25 = +625
// s ----e----
--------------f-------------
#10 flp_a
= 32'b0_0000_0101_1100_1000_0000_0000_0000_000;
flp_b =
32'b0_0000_0101_1100_1000_0000_0000_0000_000;
//+76 x +55 = +4180
// s ----e---- --------------f-------------
#10 flp_a
= 32'b0_0000_0111_1001_1000_0000_0000_0000_000;
flp_b =
32'b0_0000_0110_1101_1100_0000_0000_0000_000;
//-48 x -17 = +816
// s ----e---- --------------f-------------
#10 flp_a
= 32'b1_0000_0110_1100_0000_0000_0000_0000_000;
flp_b =
32'b1_0000_0101_1000_1000_0000_0000_0000_000;
//+3724
x +853 = +3,176,572
// s ----e----
--------------f-------------
#10 flp_a
= 32'b0_0000_1100_1110_1000_1100_0000_0000_000;
flp_b =
32'b0_0000_1010_1101_0101_0100_0000_0000_000;
#10 $stop;
end
//instantiate
the module into the test bench
mul_flp
inst1 (
.flp_a(flp_a),
.flp_b(flp_b),
.sign(sign),
.exponent(exponent),
.exp_unbiased(exp_unbiased),
.exp_sum(exp_sum),
.prod(prod)
);
endmodule
Page 624, Figure
14.8
//behavioral
floating-point multiplication
module
mul_flp3 (flp_a, flp_b, start, sign, exponent,
exp_unbiased, cout, prod);
input
[31:0] flp_a, flp_b;
input
start;
output sign;
output [7:0]
exponent, exp_unbiased;
output cout;
output [45:0]
prod;
//variables
used in an always block are declared as registers
reg
sign_a, sign_b;
reg [7:0]
exp_a, exp_b;
reg [7:0]
exp_a_bias, exp_b_bias;
reg [7:0]
exp_sum;
reg
[22:0] fract_a, fract_b;
reg
[22:0] fract_b_reg;
reg sign;
reg [7:0]
exponent, exp_unbiased;
reg cout;
reg
[45:0] prod;
reg
[22:0] product;
reg [4:0]
count;
//define
sign, exponent, and fraction
always @
(flp_a or flp_b)
begin
sign_a
= flp_a[31];
sign_b = flp_b[31];
exp_a = flp_a[30:23];
exp_b = flp_b[30:23];
fract_a = flp_a[22:0];
fract_b = flp_b[22:0];
//bias
exponents
exp_a_bias = exp_a + 8'b0111_1111;
exp_b_bias = exp_b + 8'b0111_1111;
//add
exponents
exp_sum = exp_a_bias + exp_b_bias;
//remove
one bias
exponent = exp_sum - 8'b0111_1111;
exp_unbiased = exponent - 8'b0111_1111;
end
//multiply
fractions
always @ (posedge start)
begin
fract_b_reg
= fract_b;
prod = 0;
count = 5'b10111;
if
((fract_a != 0) && (fract_b != 0))
while
(count)
begin
{cout,
prod[45:23]} = (({23{fract_b_reg[0]}} &
fract_a)
+ prod[45:23]);
prod = {cout, prod[45:23],
prod[22:1]};
fract_b_reg = fract_b_reg
>> 1;
count = count - 1;
end
else
begin
sign
= 1'b0;
exp_unbiased = 8’h00;
prod = 0;
end
//postnormalize
result
if
(prod != 0)
while
(prod[45] == 0)
begin
prod
= prod << 1;
exp_unbiased = exp_unbiased - 1;
end
sign = sign_a ^ sign_b;
end
endmodule
//test
bench for floating-point multiplication
module
mul_flp3_tb;
reg
[31:0] flp_a, flp_b;
reg
start;
wire sign;
wire [7:0]
exponent, exp_unbiased;
wire [8:0]
exp_sum;
wire
[45:0] prod;
initial //display
variables
$monitor
("sign = %b, exp_unbiased = %b, prod = %b",
sign, exp_unbiased, prod);
//apply
input vectors
initial
begin
#0 start = 1'b0;
//+5 x +3 = +15
// s ----e----
--------------f-------------
flp_a =
32'b0_0000_0011_1010_0000_0000_0000_0000_000;
flp_b =
32'b0_0000_0010_1100_0000_0000_0000_0000_000;
#10 start
= 1'b1;
#10 start
= 1'b0;
//+6 x +4 = +24
// s ----e----
--------------f-------------
#10 flp_a
= 32'b0_0000_0011_1100_0000_0000_0000_0000_000;
flp_b =
32'b0_0000_0011_1000_0000_0000_0000_0000_000;
#10 start
= 1'b1;
#10 start
= 1'b0;
//-5 x +5 = -25
// s ----e----
--------------f-------------
#10 flp_a
= 32'b1_0000_0011_1010_0000_0000_0000_0000_000;
flp_b =
32'b0_0000_0011_1010_0000_0000_0000_0000_000;
#10 start
= 1'b1;
#10 start
= 1'b0;
//+7 x -5 = -35
// s ----e----
--------------f-------------
#10 flp_a
= 32'b0_0000_0011_1110_0000_0000_0000_0000_000;
flp_b =
32'b1_0000_0011_1010_0000_0000_0000_0000_000;
#10 start
= 1'b1;
#10 start
= 1'b0;
//+25 x +25 = +625
// s ----e----
--------------f-------------
#10 flp_a
= 32'b0_0000_0101_1100_1000_0000_0000_0000_000;
flp_b =
32'b0_0000_0101_1100_1000_0000_0000_0000_000;
#10 start
= 1'b1;
#10 start
= 1'b0;
//+76
x +55 = +4180
// s ----e----
--------------f-------------
#10 flp_a
= 32'b0_0000_0111_1001_1000_0000_0000_0000_000;
flp_b =
32'b0_0000_0110_1101_1100_0000_0000_0000_000;
#10 start
= 1'b1;
#10 start
= 1'b0;
//-48 x -17 = +816
// s ----e----
--------------f-------------
#10 flp_a
= 32'b1_0000_0110_1100_0000_0000_0000_0000_000;
flp_b =
32'b1_0000_0101_1000_1000_0000_0000_0000_000;
#10 start
= 1'b1;
#10 start
= 1'b0;
//+3724 x +853 = +3,176,572
// s ----e----
--------------f-------------
#10 flp_a
= 32'b0_0000_1100_1110_1000_1100_0000_0000_000;
flp_b =
32'b0_0000_1010_1101_0101_0100_0000_0000_000;
#10 start
= 1'b1;
#10 start
= 1'b0;
//0 x +853 = +0
// s ----e----
--------------f-------------
#10 flp_a
= 32'b0_0000_1100_0000_0000_0000_0000_0000_000;
flp_b = 32'b0_0000_1010_1101_0101_0100_0000_0000_000;
#10 start
= 1'b1;
#10 start
= 1'b0;
#20 $stop;
end
//instantiate
the module into the test bench
mul_flp3
inst1 (
.flp_a(flp_a),
.flp_b(flp_b),
.start(start),
.sign(sign),
.exponent(exponent),
.exp_unbiased(exp_unbiased),
.prod(prod)
);
endmodule
No comments:
Post a Comment