3 stage pipeline and top test bench
This commit is contained in:
Regular → Executable
+45
-66
@@ -1,3 +1,4 @@
|
||||
|
||||
// sim/fp_mult_tb.sv
|
||||
`timescale 1ns/1ps
|
||||
|
||||
@@ -6,18 +7,8 @@ module fp_mult_tb;
|
||||
logic [31:0] a, b, z;
|
||||
logic [2:0] rnd;
|
||||
logic [7:0] status;
|
||||
logic clk = 0, rst = 0;
|
||||
/*
|
||||
// DEBUG signals
|
||||
logic sign_res_;
|
||||
logic [9:0] exp_sum_;
|
||||
logic [47:0] mant_prod_;
|
||||
logic [22:0] mant_norm_;
|
||||
logic [9:0] exp_norm_;
|
||||
logic guard_, sticky_;
|
||||
logic [24:0] mant_post_rnd_;
|
||||
logic [9:0] exp_post_rnd_;
|
||||
*/
|
||||
logic clk = 0, rst = 1;
|
||||
|
||||
// DUT
|
||||
fp_mult dut (
|
||||
.a(a),
|
||||
@@ -27,21 +18,10 @@ module fp_mult_tb;
|
||||
.status(status),
|
||||
.clk(clk),
|
||||
.rst(rst)
|
||||
/*
|
||||
// DEBUG signals
|
||||
.sign_res_(sign_res_),
|
||||
.exp_sum_(exp_sum_),
|
||||
.mant_prod_(mant_prod_),
|
||||
.mant_norm_(mant_norm_),
|
||||
.exp_norm_(exp_norm_),
|
||||
.guard_(guard_),
|
||||
.sticky_(sticky_),
|
||||
.mant_post_rnd_(mant_post_rnd_),
|
||||
.exp_post_rnd_(exp_post_rnd_)
|
||||
*/
|
||||
);
|
||||
|
||||
// Clock generation
|
||||
always #1 rst = 1;
|
||||
always #5 clk = ~clk;
|
||||
|
||||
typedef struct {
|
||||
@@ -50,59 +30,58 @@ module fp_mult_tb;
|
||||
logic [31:0] expected;
|
||||
string desc;
|
||||
} test_vector_t;
|
||||
int i =0, j=0;
|
||||
|
||||
test_vector_t tests [14];
|
||||
test_vector_t tests [20];
|
||||
|
||||
initial begin
|
||||
$display("Starting fp_mult test...\n");
|
||||
|
||||
// Normal multiplication cases
|
||||
tests[0] = '{32'h3f800000, 32'h40000000, 32'h40000000, "1.0 * 2.0 = 2.0"};
|
||||
tests[1] = '{32'h40400000, 32'h40400000, 32'h41100000, "3.0 * 3.0 = 9.0"};
|
||||
tests[2] = '{32'hc0400000, 32'h40400000, 32'hc1100000, "-3.0 * 3.0 = 9.0"};
|
||||
tests[3] = '{32'hbf800000, 32'h40000000, 32'hc0000000, "-1.0 * 2.0 = -2.0"};
|
||||
tests[4] = '{32'h3f000000, 32'h3f000000, 32'h3e800000, "0.5 * 0.5 = 0.25"};
|
||||
tests[5] = '{32'h3f800000, 32'h00000000, 32'h00000000, "1.0 * 0.0 = 0.0"};
|
||||
tests[6] = '{32'h42280000, 32'hc0e00000, 32'hc3930000, "42.0 * -7.0 = -294.0"};
|
||||
tests[7] = '{32'h414570a4, 32'hb8d1b717, 32'hbaa1be2b, "12.34 * -0.0001 = -0.001234"};
|
||||
// Test vectors
|
||||
tests[0] = '{32'h3f800000, 32'h40000000, 32'h40000000, "+1.0 * +2.0 = +2.0"};
|
||||
tests[1] = '{32'h40400000, 32'h40400000, 32'h41100000, "+3.0 * +3.0 = +9.0"};
|
||||
tests[2] = '{32'hc0400000, 32'h40400000, 32'hc1100000, "-3.0 * +3.0 = -9.0"};
|
||||
tests[3] = '{32'hbf800000, 32'h40000000, 32'hc0000000, "-1.0 * +2.0 = -2.0"};
|
||||
tests[4] = '{32'h3f000000, 32'h3f000000, 32'h3e800000, "+0.5 * +0.5 = +0.25"};
|
||||
tests[5] = '{32'h3f800000, 32'h00000000, 32'h00000000, "1.0 * +0.0 = +0.0"};
|
||||
tests[6] = '{32'h42280000, 32'hc0e00000, 32'hc3930000, "+42.0 * -7.0 = -294.0"};
|
||||
tests[7] = '{32'h414570a4, 32'hb8d1b717, 32'hbaa1be2b, "+12.34 * -0.0001 = -0.001234"};
|
||||
|
||||
// Corner cases (some may fail if not handled yet)
|
||||
tests[8] = '{32'h00000000, 32'h80000000, 32'h80000000, "0.0 * -0.0 = -0.0"};
|
||||
tests[9] = '{32'h3f800000, 32'h80000000, 32'h80000000, "1.0 * -0.0 = -0.0"};
|
||||
tests[10] = '{32'h7f800000, 32'h3f800000, 32'h7f800000, "inf * 1.0 = inf"};
|
||||
tests[11] = '{32'hff800000, 32'h7f800000, 32'hff800000, "-inf * inf = -inf"};
|
||||
tests[12] = '{32'h00000000, 32'h7f800000, 32'h7f800000, "0.0 * inf = inf - nan"};
|
||||
tests[13] = '{32'h80000000, 32'hff800000, 32'h7f800000, "-0.0 * -inf = inf - nan"};
|
||||
tests[8] = '{32'h00000000, 32'h00000000, 32'h00000000, "0.0 * 0.0 = 0.0"};
|
||||
tests[9] = '{32'h80000000, 32'h80000000, 32'h00000000, "-0.0 * -0.0 = 0.0"};
|
||||
tests[10] = '{32'h00000000, 32'h80000000, 32'h80000000, "0.0 * -0.0 = -0.0"};
|
||||
tests[11] = '{32'h3f800000, 32'h80000000, 32'h80000000, "1.0 * -0.0 = -0.0"};
|
||||
tests[12] = '{32'h7f800000, 32'h3f800000, 32'h7f800000, "inf * 1.0 = inf"};
|
||||
tests[13] = '{32'hff800000, 32'h3f800000, 32'hff800000, "-inf * 1.0 = -inf"};
|
||||
tests[14] = '{32'h7f800000, 32'hbf800000, 32'hff800000, "inf * -1.0 = -inf"};
|
||||
tests[15] = '{32'hff800000, 32'h7f800000, 32'hff800000, "-inf * inf = -inf"};
|
||||
tests[16] = '{32'hff800000, 32'hff800000, 32'h7f800000, "-inf * -inf = +inf"};
|
||||
tests[17] = '{32'h00000000, 32'h7f800000, 32'h7f800000, "0.0 * inf = inf"};
|
||||
tests[18] = '{32'h80000000, 32'hff800000, 32'h7f800000, "-0.0 * -inf = inf"};
|
||||
tests[19] = '{32'h00000000, 32'hff800000, 32'hff800000, "0.0 * -inf = -inf"};
|
||||
end
|
||||
|
||||
logic [31:0] z_pipe [2:0];
|
||||
|
||||
rnd = 3'b000; // default round to nearest
|
||||
rst = 1; #10;
|
||||
rst = 0; #10;
|
||||
always_ff @(negedge clk) begin
|
||||
z_pipe[2] <= z_pipe[1];
|
||||
z_pipe[1] <= z_pipe[0];
|
||||
z_pipe[0] <= z;
|
||||
|
||||
for (int i = 0; i < 14; i++) begin
|
||||
a = tests[i].a;
|
||||
b = tests[i].b;
|
||||
#20;
|
||||
$display("[%0d] %s", i+1, tests[i].desc);
|
||||
/*
|
||||
// DEBUG prints
|
||||
$display("fp_mult: sign bit = %h", sign_res_);
|
||||
$display("fp_mult: exp (pre norm) = %h", exp_sum_);
|
||||
$display("fp_mult: mant (pre norm) = %h", mant_prod_);
|
||||
$display("fp_mult: exp (norm) = %h", exp_norm_);
|
||||
$display("fp_mult: mant (norm) = %h", mant_norm_);
|
||||
$display("fp_mult: guard,sticky = %h,%h", guard_,sticky_);
|
||||
$display("fp_mult: exp (post rnd) = %h", exp_post_rnd_);
|
||||
$display("fp_mult: mant (post rnd) = %h", mant_post_rnd_);
|
||||
*/
|
||||
$display(" A=%h B=%h => Z=%h (expected %h) %s\n",
|
||||
a, b, z, tests[i].expected,
|
||||
(z === tests[i].expected) ? "PASS" : "FAIL");
|
||||
if (i >= 5) begin
|
||||
j = i - 5;
|
||||
$display("[%0d] %s", j+1, tests[j].desc);
|
||||
$display(" A=%h B=%h => Z=%h (expected %h) %s\n",
|
||||
tests[j].a, tests[j].b, z_pipe[0], tests[j].expected,
|
||||
(z_pipe[0] === tests[j].expected) ? "PASS" : "FAIL");
|
||||
end
|
||||
|
||||
$display("\nFinished fp_mult test.");
|
||||
$stop;
|
||||
a <= tests[i].a;
|
||||
b <= tests[i].b;
|
||||
i <= i + 1;
|
||||
|
||||
if (i == 19 + 5) $stop;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
endmodule
|
||||
|
||||
Executable
+89
@@ -0,0 +1,89 @@
|
||||
// sim/fp_mult_top_tb.sv
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module fp_mult_top_tb;
|
||||
|
||||
logic [31:0] a, b, z;
|
||||
logic [2:0] rnd;
|
||||
logic [7:0] status;
|
||||
logic clk = 0, rst = 1;
|
||||
|
||||
// DUT
|
||||
fp_mult_top dut (
|
||||
.a(a),
|
||||
.b(b),
|
||||
.rnd(rnd),
|
||||
.z(z),
|
||||
.status(status),
|
||||
.clk(clk),
|
||||
.rst(rst)
|
||||
);
|
||||
|
||||
// Clock generation
|
||||
always #1 rst = 1;
|
||||
always #5 clk = ~clk;
|
||||
|
||||
typedef struct {
|
||||
logic [31:0] a;
|
||||
logic [31:0] b;
|
||||
logic [31:0] expected;
|
||||
string desc;
|
||||
} test_vector_t;
|
||||
int i =0, j=0;
|
||||
|
||||
// Test vectors
|
||||
test_vector_t tests [20];
|
||||
|
||||
initial begin
|
||||
|
||||
$display("Starting fp_mult test...\n");
|
||||
|
||||
// Test cases
|
||||
tests[0] = '{32'h3f800000, 32'h40000000, 32'h40000000, "+1.0 * +2.0 = +2.0"};
|
||||
tests[1] = '{32'h40400000, 32'h40400000, 32'h41100000, "+3.0 * +3.0 = +9.0"};
|
||||
tests[2] = '{32'hc0400000, 32'h40400000, 32'hc1100000, "-3.0 * +3.0 = -9.0"};
|
||||
tests[3] = '{32'hbf800000, 32'h40000000, 32'hc0000000, "-1.0 * +2.0 = -2.0"};
|
||||
tests[4] = '{32'h3f000000, 32'h3f000000, 32'h3e800000, "+0.5 * +0.5 = +0.25"};
|
||||
tests[5] = '{32'h3f800000, 32'h00000000, 32'h00000000, "1.0 * +0.0 = +0.0"};
|
||||
tests[6] = '{32'h42280000, 32'hc0e00000, 32'hc3930000, "+42.0 * -7.0 = -294.0"};
|
||||
tests[7] = '{32'h414570a4, 32'hb8d1b717, 32'hbaa1be2b, "+12.34 * -0.0001 = -0.001234"};
|
||||
|
||||
tests[8] = '{32'h00000000, 32'h00000000, 32'h00000000, "0.0 * 0.0 = 0.0"};
|
||||
tests[9] = '{32'h80000000, 32'h80000000, 32'h00000000, "-0.0 * -0.0 = 0.0"};
|
||||
tests[10] = '{32'h00000000, 32'h80000000, 32'h80000000, "0.0 * -0.0 = -0.0"};
|
||||
tests[11] = '{32'h3f800000, 32'h80000000, 32'h80000000, "1.0 * -0.0 = -0.0"};
|
||||
tests[12] = '{32'h7f800000, 32'h3f800000, 32'h7f800000, "inf * 1.0 = inf"};
|
||||
tests[13] = '{32'hff800000, 32'h3f800000, 32'hff800000, "-inf * 1.0 = -inf"};
|
||||
tests[14] = '{32'h7f800000, 32'hbf800000, 32'hff800000, "inf * -1.0 = -inf"};
|
||||
tests[15] = '{32'hff800000, 32'h7f800000, 32'hff800000, "-inf * inf = -inf"};
|
||||
tests[16] = '{32'hff800000, 32'hff800000, 32'h7f800000, "-inf * -inf = +inf"};
|
||||
tests[17] = '{32'h00000000, 32'h7f800000, 32'h7f800000, "0.0 * inf = inf"};
|
||||
tests[18] = '{32'h80000000, 32'hff800000, 32'h7f800000, "-0.0 * -inf = inf"};
|
||||
tests[19] = '{32'h00000000, 32'hff800000, 32'hff800000, "0.0 * -inf = -inf"};
|
||||
|
||||
end
|
||||
|
||||
logic [31:0] z_pipe [2:0];
|
||||
|
||||
always_ff @(negedge clk) begin
|
||||
z_pipe[2] <= z_pipe[1];
|
||||
z_pipe[1] <= z_pipe[0];
|
||||
z_pipe[0] <= z;
|
||||
|
||||
if (i >= 7) begin
|
||||
j = i - 7;
|
||||
$display("[%0d] %s", j+1, tests[j].desc);
|
||||
$display(" A=%h B=%h => Z=%h (expected %h) %s\n",
|
||||
tests[j].a, tests[j].b, z_pipe[0], tests[j].expected,
|
||||
(z_pipe[0] == tests[j].expected) ? "PASS" : "FAIL");
|
||||
end
|
||||
|
||||
a <= tests[i].a;
|
||||
b <= tests[i].b;
|
||||
i <= i + 1;
|
||||
|
||||
if (i == 19 + 7) $stop;
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user