Computer
ArithmeticandVerilog HDL
Fundamentals
Chapter 16
Additional
Floating-Point Topics
Verilog Code
Figures
PS: IF YOU NEED ANY BOOK,NOTES,PROJECT,LAB EXPERIMENT ANYTHING RELATED TO ENGINEERING JUST REPLY ME ON THE COMMENT SECTION
Page 657, Figure
16.7
//behavioral
floating-point adder-based rounding
module
mem_flp_add_based_round (fract_a, rslt);
//list
inputs and outputs
input [5:0]
fract_a;
output [4:0]
rslt;
//list
wire and reg
wire [5:0]
fract_a;
reg [4:0]
rslt;
//define
memory size
//mem_round
is an array of 64 5-bit registers
reg [4:0]
mem_round [0:63];
//define
memory contents
//load
mem_round from file fract.round
initial
begin
$readmemb
("fract.round", mem_round);
end
//use
the fraction fract_a to access the memory
always @
(fract_a)
begin
rslt
= mem_round [fract_a];
end
endmodule
//test
bench for floating-point adder-based rounding
module
mem_flp_add_based_round_tb;
//inputs
are reg and outputs are wire for test benches
reg [5:0]
fract_a;
wire [4:0]
rslt;
//display
variables
initial
$monitor
("fraction = %b, rounded result = %b",
fract_a, rslt);
//apply
input vectors for fraction
initial
begin
#0 fract_a = 6'b00000_1;
#10 fract_a
= 6'b00000_0;
#10 fract_a
= 6'b00110_0;
#10 fract_a
= 6'b00110_1;
#10 fract_a
= 6'b01011_0;
#10 fract_a
= 6'b01011_1;
#10 fract_a
= 6'b01111_0;
#10 fract_a
= 6'b01111_1;
#10 fract_a
= 6'b10011_0;
#10 fract_a
= 6'b10011_1;
#10 fract_a
= 6'b10111_0;
#10 fract_a
= 6'b10111_1;
#10 fract_a
= 6'b11011_0;
#10 fract_a
= 6'b11011_1;
#10 fract_a
= 6'b11110_0;
#10 fract_a
= 6'b11110_1;
#10 $stop;
end
//instantiate
the module into the test bench
mem_flp_add_based_round
inst1 (
.fract_a(fract_a),
.rslt(rslt)
);
endmodule
Page 665, Figure
16.14
//dataflow
for floating-point adder-based rounding
module
adder_based_round_df (x, rslt);
input [1:6]
x;
output [4:0]
rslt;
//define
internal wires
wire net1,
net2, net3, net4, net5, net6, net7,
net8, net9, net10, net11, net12,
net13,
net14, net15, net16, net17, net18,
net19;
//define
logic for rslt[4]
assign net1
= x[2] & x[3] & x[4] & x[5] & x[6],
rslt[4] = x[1] | net1;
//define
logic for rslt[3]
assign net2
= x[1] & x[2],
net3 = x[2] & ~x[3],
net4 = x[2] & ~x[5],
net5 = x[2] & ~x[6],
net6 = x[2] & ~x[4],
net7 = ~x[2] & x[3] & x[4]
& x[5] & x[6],
rslt[3] = net2 | net3 | net4 | net5
| net6 | net7;
//define
logic for rslt[2]
assign net8
= x[3] & ~x[4],
net9 = x[3] & ~x[6],
net10 = x[3] & ~x[5],
net11 = x[1] & x[2] & x[3],
net12 = ~x[3] & x[4] & x[5]
& x[6],
rslt[2] = net8 | net9 | net10 |
net11 | net12;
//define
logic for rslt[1]
assign net13
= x[4] & ~x[5],
net14 = x[4] & ~x[6],
net15 = ~x[4] & x[5] & x[6],
net16 = x[1] & x[2] & x[3]
& x[4],
rslt[1] = net13 | net14 | net15 |
net16;
//define
logic for rslt[0]
assign net17
= ~x[5] & x[6],
net18 = x[5] & ~x[6],
net19 = x[1] & x[2] & x[3]
& x[4] & x[5],
rslt[0] = net17 | net18 | net19;
endmodule
//test
bench for floating-point adder-based rounding
module
adder_based_round_df_tb;
reg [1:6]
x;
wire [4:0]
rslt;
//display
variables
initial
$monitor
("fraction = %b, rounded result = %b", x, rslt);
initial //apply
input vectors for fraction
begin
#0 x
= 6'b00000_1;
#10 x
= 6'b00000_0;
#10 x
= 6'b00110_0;
#10 x
= 6'b00110_1;
#10 x
= 6'b01011_0;
#10 x
= 6'b01011_1;
#10 x
= 6'b01111_0;
#10 x
= 6'b01111_1;
#10 x
= 6'b10011_0;
#10 x
= 6'b10011_1;
#10 x
= 6'b10111_0;
#10 x
= 6'b10111_1;
#10 x
= 6'b11011_0;
#10 x
= 6'b11011_1;
#10 x
= 6'b11110_0;
#10 x
= 6'b11110_1;
#10 $stop;
end
//instantiate
the module into the test bench
adder_based_round_df
inst1 (
.x(x),
.rslt(rslt)
);
endmodule
Page 669 Figure 16.19
//behavioral
adder-based rounding
module
adder_based_round_bh2 (flp_a, flp_b, sign, exponent,
exp_unbiased,
sum);
input
[15:0] flp_a, flp_b;
output
[10:3] sum;
output sign;
output [3:0]
exponent, exp_unbiased;
//variables
used in an always block are declared as registers
reg
sign_a, sign_b;
reg [3:0]
exp_a, exp_b;
reg [3:0]
exp_a_bias, exp_b_bias;
reg
[10:3] fract_a, fract_b;
reg [2:0]
guard_a, guard_b;
reg [3:0]
ctr_align;
reg
[10:3] sum;
reg sign;
reg [3:0]
exponent, exp_unbiased;
reg cout;
always @
(flp_a or flp_b)
begin
sign_a
= flp_a[15];
sign_b = flp_b[15];
exp_a = flp_a[14:11];
exp_b = flp_b[14:11];
fract_a = flp_a[10:3];
fract_b = flp_b[10:3];
guard_a = flp_a[2:0];
guard_b = flp_b[2:0];
//bias
exponents
exp_a_bias = exp_a + 4'b0111;
exp_b_bias = exp_b + 4'b0111;
//align
fractions
if
(exp_a_bias < exp_b_bias)
ctr_align = exp_b_bias - exp_a_bias;
while
(ctr_align)
begin
{fract_a,
guard_a} = {fract_a, guard_a} >> 1;
exp_a_bias = exp_a_bias + 1;
ctr_align = ctr_align - 1;
end
if
(exp_b_bias < exp_a_bias)
ctr_align = exp_a_bias - exp_b_bias;
while
(ctr_align)
begin
{fract_b,
guard_b} = {fract_b, guard_b} >> 1;
exp_b_bias = exp_b_bias + 1;
ctr_align = ctr_align - 1;
end
//add
fractions
{cout, sum[10:3]} = fract_a[10:3] +
fract_b[10:3];
//execute
adder-based rounding
if
((guard_a[2] | guard_b[2]) == 1)
sum[10:3] = sum[10:3] + 8'b0000_0001;
//normalize
result
if
(cout == 1)
begin
{cout, sum[10:3]} = {cout,
sum[10:3]} >> 1;
exp_b_bias = exp_b_bias + 1;
end
sign = sign_a;
exponent = exp_b_bias;
exp_unbiased = exp_b_bias - 4'b0111;
end
endmodule
//test
bench for behavioral adder-based rounding
module
adder_based_round_bh2_tb;
reg
[15:0] flp_a, flp_b;
wire
[10:3] sum;
wire sign;
wire [3:0]
exponent, exp_unbiased;
//display
variables
initial
$monitor
("sign=%b, exp_biased=%b, exp_unbiased=%b, sum=%b",
sign, exponent, exp_unbiased,
sum[10:3]);
//apply
input vectors
initial
begin
//+12
+ +35 = +47
// s --e- ------f------
#0 flp_a
= 16'b0_0100_1100_0000_000;
flp_b = 16'b0_0110_1000_1100_000;
//+26 + +20 = +46
// s --e- ------f------
#10 flp_a
= 16'b0_0101_1101_0000_000;
flp_b = 16'b0_0101_1010_0000_000;
//+26.5 + +4.375 = +30.875
// s --e- ------f------
#10 flp_a
= 16'b0_0101_1101_0100_000;
flp_b = 16'b0_0011_1000_1100_000;
//+11
+ +34 = +45
// s --e- ------f------
#10 flp_a
= 16'b0_0100_1011_0000_000;
flp_b = 16'b0_0110_1000_1000_000;
//+58.2500 + +9.4375 = +67.6875
// s --e- ------f------
#10 flp_a
= 16'b0_0110_1110_1001_000;
flp_b = 16'b0_0100_1001_0111_000;
//+50.2500 + +9.4375 = +59.6875
// s --e- ------f------
#10 flp_a
= 16'b0_0110_1100_1001_000;
flp_b = 16'b0_0100_1001_0111_000;
//+51.2500 + +11.0625 = +62.3125
// s --e- ------f------
#10 flp_a
= 16'b0_0110_1100_1101_000;
flp_b = 16'b0_0100_1011_0001_000;
//+12.75000 + +4.34375 = +17.09375
// s --e- ------f------
#10 flp_a
= 16'b0_0100_1100_1100_000;
flp_b = 16'b0_0011_1000_1011_000;
#10 $stop;
end
//instantiate
the module into the test bench
adder_based_round_bh2
inst1 (
.flp_a(flp_a),
.flp_b(flp_b),
.sum(sum),
.sign(sign),
.exponent(exponent),
.exp_unbiased(exp_unbiased)
);
endmodule
Page 675, Figure
16.24
//behavioral
truncation, adder-based, von neumann rounding
module
trunc_add_von_round (flp_a, flp_b, sign, exponent,
exp_unbiased, sum, sum_trunc,
sum_add, sum_von);
input
[15:0] flp_a, flp_b;
output
[10:3] sum, sum_trunc, sum_add, sum_von;
output sign;
output [3:0]
exponent, exp_unbiased;
//variables
used in an always block are declared as registers
reg
sign_a, sign_b;
reg [3:0]
exp_a, exp_b;
reg [3:0]
exp_a_bias, exp_b_bias;
reg
[10:3] fract_a, fract_b;
reg [2:0]
guard_a, guard_b;
reg [3:0]
ctr_align;
reg
[10:3] sum, sum_trunc, sum_add, sum_von;
reg sign;
reg [3:0]
exponent, exp_unbiased;
reg cout;
always @
(flp_a or flp_b)
begin
sign_a
= flp_a[15];
sign_b = flp_b[15];
exp_a = flp_a[14:11];
exp_b = flp_b[14:11];
fract_a = flp_a[10:3];
fract_b = flp_b[10:3];
guard_a = flp_a[2:0];
guard_b = flp_b[2:0];
//bias
exponents
exp_a_bias = exp_a + 4'b0111;
exp_b_bias = exp_b + 4'b0111;
if
(exp_a_bias < exp_b_bias) //align
fractions
ctr_align = exp_b_bias - exp_a_bias;
while
(ctr_align)
begin
{fract_a, guard_a} = {fract_a,
guard_a} >> 1;
exp_a_bias = exp_a_bias + 1;
ctr_align = ctr_align - 1;
end
if
(exp_b_bias < exp_a_bias)
ctr_align = exp_a_bias - exp_b_bias;
while
(ctr_align)
begin
{fract_b, guard_b} = {fract_b,
guard_b} >> 1;
exp_b_bias = exp_b_bias + 1;
ctr_align = ctr_align - 1;
end
//add
fractions
{cout, sum[10:3]} = fract_a[10:3] +
fract_b[10:3];
if
(cout == 1) //postnormalize
result
begin
{cout, sum[10:3]} = {cout,
sum[10:3]} >> 1;
exp_b_bias = exp_b_bias + 1;
end
//execute
truncation rounding
sum_trunc = sum[10:3];
//execute
adder-based rounding
if
((guard_a[2] == 1) | (guard_b[2] == 1))
sum_add = sum[10:3] + 8'b0000_0001;
else
sum_add
= sum[10:3];
//execute
von neumann rounding
if
((guard_a != 3'b000) | (guard_b != 3'b000))
sum_von = {sum[10:4], 1'b1};
else
sum_von = sum[10:3];
sign = sign_a;
exponent = exp_b_bias;
exp_unbiased = exp_b_bias - 4'b0111;
end
endmodule
//test
bench for truncation, adder-based, von neumann rounding
module trunc_add_von_round_tb;
reg
[15:0] flp_a, flp_b;
wire
[10:3] sum, sum_trunc, sum_add, sum_von;
wire sign;
wire [3:0]
exponent, exp_unbiased;
//display
variables
initial
$monitor
("sign=%b, exp_unbiased=%b, sum_trunc=%b,
sum_add=%b, sum_von=%b",
sign, exp_unbiased, sum_trunc,
sum_add, sum_von);
//apply
input vectors
initial
begin
//(+63.500) + (+7.875) = +71.375
// s --e- ------f------
#0 flp_a
= 16'b0_0110_1111_1110_000;
flp_b = 16'b0_0011_1111_1100_000;
//(+35) + (+12) = +47
// s --e- ------f------
#10 flp_a
= 16'b0_0110_1000_1100_000;
flp_b = 16'b0_0100_1100_0000_000;
//(+26.5)
+ (+4.375) = +30.875
// s --e- ------f------
#10 flp_a
= 16'b0_0101_1101_0100_000;
flp_b = 16'b0_0011_1000_1100_000;
//(+58.2500) + (+9.4375) = +67.6875
// s --e- ------f------
#10 flp_a
= 16'b0_0110_1110_1001_000;
flp_b = 16'b0_0100_1001_0111_000;
//(+50.2500) + (+9.4375) = +59.6875
// s --e- ------f------
#10 flp_a
= 16'b0_0110_1100_1001_000;
flp_b = 16'b0_0100_1001_0111_000;
//(+12.75000) + (+4.34375) =
+17.09375
// s --e- ------f------
#10 flp_a
= 16'b0_0100_1100_1100_000;
flp_b = 16'b0_0011_1000_1011_000;
//(+51.2500) + (+11.0625) = +62.3125
// s --e- ------f------
#10 flp_a
= 16'b0_0110_1100_1101_000;
flp_b = 16'b0_0100_1011_0001_000;
//(+42.250) + (+9.875) = +52.125
// s --e- ------f------
#10 flp_a
= 16'b0_0110_1010_1001_000;
flp_b = 16'b0_0100_1001_0111_000;
#10 $stop;
end
//instantiate
the module into the test bench
trunc_add_von_round
inst1 (
.flp_a(flp_a),
.flp_b(flp_b),
.sum(sum),
.sum_trunc(sum_trunc),
.sum_add(sum_add),
.sum_von(sum_von),
.sign(sign),
.exponent(exponent),
.exp_unbiased(exp_unbiased)
);
endmodule
No comments:
Post a Comment