3 stage pipeline and top test bench

This commit is contained in:
Christos Choutouridis 2025-06-15 20:21:30 +03:00
parent 1ea7c01bb8
commit d6c284c596
6 changed files with 279 additions and 183 deletions

View File

@ -11,7 +11,7 @@ module fp_mult_top (
logic [31:0] a1, b1; // Floating-Point numbers logic [31:0] a1, b1; // Floating-Point numbers
logic [2:0] rnd1; // Rounding signal logic [2:0] rnd1; // Rounding signal
logic [31:0] z1; // a ± b logic [31:0] z1; // a * b
logic [7:0] status1; // Status Flags logic [7:0] status1; // Status Flags
fp_mult multiplier(a1,b1,rnd1,z1,status1,clk,rst); fp_mult multiplier(a1,b1,rnd1,z1,status1,clk,rst);

View File

@ -2304,25 +2304,27 @@ suppress = 8780 ;an explanation can be had by running: verror 8780
Project_Version = 6 Project_Version = 6
Project_DefaultLib = work Project_DefaultLib = work
Project_SortMethod = unused Project_SortMethod = unused
Project_Files_Count = 9 Project_Files_Count = 10
Project_File_0 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/fp_mult_top.sv Project_File_0 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/normalize_mult.sv
Project_File_P_0 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 vlog_noload 0 folder {Top Level} last_compile 1749470139 cover_fsm 0 cover_branch 0 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 0 cover_expr 0 dont_compile 0 cover_stmt 0 Project_File_P_0 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 cover_branch 0 vlog_noload 0 folder src last_compile 1749838823 cover_fsm 0 vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 2 dont_compile 0 cover_expr 0 cover_stmt 0
Project_File_1 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/normalize_mult.sv Project_File_1 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/fp_mult_top.sv
Project_File_P_1 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 vlog_noload 0 folder src last_compile 1749838823 cover_fsm 0 cover_branch 0 vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 2 dont_compile 0 cover_expr 0 cover_stmt 0 Project_File_P_1 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 folder {Top Level} last_compile 1749997793 cover_fsm 0 cover_branch 0 vlog_noload 0 vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 0 dont_compile 0 cover_expr 0 cover_stmt 0
Project_File_2 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/round_modes.sv Project_File_2 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/round_mult_tb.sv
Project_File_P_2 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 folder src last_compile 1749985365 cover_fsm 0 cover_branch 0 vlog_noload 0 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 8 cover_expr 0 dont_compile 0 cover_stmt 0 Project_File_P_2 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 folder sim last_compile 1749484994 cover_fsm 0 cover_branch 0 vlog_noload 0 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 6 cover_expr 0 dont_compile 0 cover_stmt 0
Project_File_3 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/fp_mult.sv Project_File_3 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/fp_mult.sv
Project_File_P_3 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 vlog_noload 0 folder src last_compile 1749991254 cover_fsm 0 cover_branch 0 vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 3 dont_compile 0 cover_expr 0 cover_stmt 0 Project_File_P_3 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 cover_fsm 0 cover_branch 0 vlog_noload 0 folder src last_compile 1749998026 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 3 cover_expr 0 dont_compile 0 cover_stmt 0
Project_File_4 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/round_mult_tb.sv Project_File_4 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/round_modes.sv
Project_File_P_4 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 last_compile 1749484994 cover_fsm 0 cover_branch 0 vlog_noload 0 folder sim cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 6 cover_expr 0 dont_compile 0 cover_stmt 0 Project_File_P_4 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 vlog_noload 0 folder src last_compile 1749985365 cover_fsm 0 cover_branch 0 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 8 cover_expr 0 dont_compile 0 cover_stmt 0
Project_File_5 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/exception_mult.sv Project_File_5 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/fp_mult_top_tb.sv
Project_File_P_5 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 cover_fsm 0 cover_branch 0 vlog_noload 0 folder src last_compile 1749989714 vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 7 dont_compile 0 cover_expr 0 cover_stmt 0 Project_File_P_5 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 vlog_noload 0 folder sim last_compile 1750007782 cover_fsm 0 cover_branch 0 vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 9 dont_compile 0 cover_expr 0 cover_stmt 0
Project_File_6 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/normalize_mult_tb.sv Project_File_6 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/normalize_mult_tb.sv
Project_File_P_6 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 folder sim last_compile 1749840708 cover_fsm 0 cover_branch 0 vlog_noload 0 vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 5 dont_compile 0 cover_expr 0 cover_stmt 0 Project_File_P_6 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 vlog_noload 0 folder sim last_compile 1749840708 cover_fsm 0 cover_branch 0 vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 5 dont_compile 0 cover_expr 0 cover_stmt 0
Project_File_7 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/round_mult.sv Project_File_7 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/exception_mult.sv
Project_File_P_7 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 cover_fsm 0 cover_branch 0 vlog_noload 0 folder src last_compile 1749991129 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 1 cover_expr 0 dont_compile 0 cover_stmt 0 Project_File_P_7 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 cover_branch 0 vlog_noload 0 folder src last_compile 1750007927 cover_fsm 0 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 7 cover_expr 0 dont_compile 0 cover_stmt 0
Project_File_8 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/fp_mult_tb.sv Project_File_8 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/fp_mult_tb.sv
Project_File_P_8 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 last_compile 1749991928 cover_fsm 0 cover_branch 0 vlog_noload 0 folder sim vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 4 dont_compile 0 cover_expr 0 cover_stmt 0 Project_File_P_8 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 vlog_noload 0 folder sim last_compile 1750007807 cover_fsm 0 cover_branch 0 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 4 cover_expr 0 dont_compile 0 cover_stmt 0
Project_File_9 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/round_mult.sv
Project_File_P_9 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 last_compile 1749991129 cover_fsm 0 cover_branch 0 vlog_noload 0 folder src cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 1 cover_expr 0 dont_compile 0 cover_stmt 0
Project_Sim_Count = 0 Project_Sim_Count = 0
Project_Folder_Count = 2 Project_Folder_Count = 2
Project_Folder_0 = src Project_Folder_0 = src

111
sim/fp_mult_tb.sv Normal file → Executable file
View File

@ -1,3 +1,4 @@
// sim/fp_mult_tb.sv // sim/fp_mult_tb.sv
`timescale 1ns/1ps `timescale 1ns/1ps
@ -6,18 +7,8 @@ module fp_mult_tb;
logic [31:0] a, b, z; logic [31:0] a, b, z;
logic [2:0] rnd; logic [2:0] rnd;
logic [7:0] status; logic [7:0] status;
logic clk = 0, rst = 0; logic clk = 0, rst = 1;
/*
// 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_;
*/
// DUT // DUT
fp_mult dut ( fp_mult dut (
.a(a), .a(a),
@ -27,21 +18,10 @@ module fp_mult_tb;
.status(status), .status(status),
.clk(clk), .clk(clk),
.rst(rst) .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 // Clock generation
always #1 rst = 1;
always #5 clk = ~clk; always #5 clk = ~clk;
typedef struct { typedef struct {
@ -50,59 +30,58 @@ module fp_mult_tb;
logic [31:0] expected; logic [31:0] expected;
string desc; string desc;
} test_vector_t; } test_vector_t;
int i =0, j=0;
test_vector_t tests [14]; test_vector_t tests [20];
initial begin initial begin
$display("Starting fp_mult test...\n"); $display("Starting fp_mult test...\n");
// Normal multiplication cases // Test vectors
tests[0] = '{32'h3f800000, 32'h40000000, 32'h40000000, "1.0 * 2.0 = 2.0"}; 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[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[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[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[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[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[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[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'h00000000, 32'h00000000, "0.0 * 0.0 = 0.0"};
tests[8] = '{32'h00000000, 32'h80000000, 32'h80000000, "0.0 * -0.0 = -0.0"}; tests[9] = '{32'h80000000, 32'h80000000, 32'h00000000, "-0.0 * -0.0 = 0.0"};
tests[9] = '{32'h3f800000, 32'h80000000, 32'h80000000, "1.0 * -0.0 = -0.0"}; tests[10] = '{32'h00000000, 32'h80000000, 32'h80000000, "0.0 * -0.0 = -0.0"};
tests[10] = '{32'h7f800000, 32'h3f800000, 32'h7f800000, "inf * 1.0 = inf"}; tests[11] = '{32'h3f800000, 32'h80000000, 32'h80000000, "1.0 * -0.0 = -0.0"};
tests[11] = '{32'hff800000, 32'h7f800000, 32'hff800000, "-inf * inf = -inf"}; tests[12] = '{32'h7f800000, 32'h3f800000, 32'h7f800000, "inf * 1.0 = inf"};
tests[12] = '{32'h00000000, 32'h7f800000, 32'h7f800000, "0.0 * inf = inf - nan"}; tests[13] = '{32'hff800000, 32'h3f800000, 32'hff800000, "-inf * 1.0 = -inf"};
tests[13] = '{32'h80000000, 32'hff800000, 32'h7f800000, "-0.0 * -inf = inf - nan"}; 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 always_ff @(negedge clk) begin
rst = 1; #10; z_pipe[2] <= z_pipe[1];
rst = 0; #10; z_pipe[1] <= z_pipe[0];
z_pipe[0] <= z;
for (int i = 0; i < 14; i++) begin if (i >= 5) begin
a = tests[i].a; j = i - 5;
b = tests[i].b; $display("[%0d] %s", j+1, tests[j].desc);
#20; $display(" A=%h B=%h => Z=%h (expected %h) %s\n",
$display("[%0d] %s", i+1, tests[i].desc); tests[j].a, tests[j].b, z_pipe[0], tests[j].expected,
/* (z_pipe[0] === tests[j].expected) ? "PASS" : "FAIL");
// 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");
end end
$display("\nFinished fp_mult test."); a <= tests[i].a;
$stop; b <= tests[i].b;
i <= i + 1;
if (i == 19 + 5) $stop;
end end
endmodule
endmodule

89
sim/fp_mult_top_tb.sv Executable file
View File

@ -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

View File

@ -72,7 +72,7 @@ module exception_mult (
{ZERO, INF}, {INF, ZERO}: {ZERO, INF}, {INF, ZERO}:
begin begin
z = {1'b0, z_num(INF)}; z = {sign, z_num(INF)};
nan_f = 1; nan_f = 1;
end end

View File

@ -6,125 +6,151 @@ module fp_mult (
input logic [31:0] b, // input operand B input logic [31:0] b, // input operand B
input logic [2:0] round, // rounding mode input logic [2:0] round, // rounding mode
output logic [31:0] z, // result output logic [31:0] z, // result
output logic [7:0] status, // status flags (placeholder) output logic [7:0] status, // status flags
input logic clk, input logic clk,
input logic rst input logic rst
/*
// debug outputs
output logic sign_res_,
output logic [9:0] exp_sum_,
output logic [47:0] mant_prod_,
output logic [22:0] mant_norm_,
output logic [9:0] exp_norm_,
output logic guard_, sticky_,
output logic [24:0] mant_post_rnd_,
output logic [9:0] exp_post_rnd_
*/
); );
// === STEP 0: Parse inputs // Stage 0: Decode inputs
logic sign_a, sign_b; logic sign;
logic [7:0] exp_a, exp_b; logic [7:0] exp_a, exp_b;
logic [23:0] mant_a, mant_b; // includes hidden bit logic [23:0] mant_a, mant_b;
logic [47:0] s0_mantissa;
logic [9:0] s0_exponent;
always_comb begin always_comb begin
sign_a = a[31]; sign = a[31] ^ b[31];
sign_b = b[31]; exp_a = a[30:23];
exp_a = a[30:23]; exp_b = b[30:23];
exp_b = b[30:23]; s0_exponent = exp_a + exp_b - 127;
mant_a = (exp_a == 8'd0) ? {1'b0, a[22:0]} : {1'b1, a[22:0]};
mant_b = (exp_b == 8'd0) ? {1'b0, b[22:0]} : {1'b1, b[22:0]}; mant_a = (exp_a == 0) ? {1'b0, a[22:0]} : {1'b1, a[22:0]};
// ^ Add hiden leading '1' on normalized numbers mant_b = (exp_b == 0) ? {1'b0, b[22:0]} : {1'b1, b[22:0]};
// This will lead to always 24-bits mantissa internal representation s0_mantissa = mant_a * mant_b;
// for multiplication
end end
// === STEP 1: Floating point number sign calculation // === Stage 1: Normalize ===
logic sign_res; logic [47:0] s1_mant_in;
assign sign_res = sign_a ^ sign_b; logic [9:0] s1_exp_in;
//assign sign_res_ = sign_res; // DEBUG logic [22:0] s1_mant_out;
logic [9:0] s1_exp_out;
logic s1_guard_out, s1_sticky_out;
logic [31:0] s1_a, s1_b;
logic s1_sign;
// === STEP 2,3. Exponent addition, Exponent subtraction of bias normalize_mult normalize_inst (
logic [9:0] exp_sum; .mantissa_in(s1_mant_in),
always_comb begin .exponent_in(s1_exp_in),
exp_sum = exp_a + exp_b - 127; // apply bias .mantissa_out(s1_mant_out),
//exp_sum_ = exp_sum; // DEBUG .exponent_out(s1_exp_out),
end .guard_bit(s1_guard_out),
.sticky_bit(s1_sticky_out)
// === STEP 4: Mantissa multiplication (including leading ones)
logic [47:0] mant_prod;
always_comb begin
mant_prod = mant_a * mant_b;
//mant_prod_ = mant_prod; // DEBUG
end
// === STEP 5: Truncation and normalization
logic [22:0] mant_norm;
logic [9:0] exp_norm;
logic guard, sticky;
normalize_mult norm_inst (
.mantissa_in(mant_prod),
.exponent_in(exp_sum),
.mantissa_out(mant_norm),
.exponent_out(exp_norm),
.guard_bit(guard),
.sticky_bit(sticky)
); );
//assign mant_norm_ = mant_norm; // DEBUG
//assign exp_norm_ = exp_norm; // DEBUG
//assign guard_ = guard; // DEBUG
//assign sticky_ = sticky; // DEBUG
// === STEP 6: Pipeline stage always_ff @(posedge clk or negedge rst) begin
// Ehhh... We dont do that here... if (!rst) begin
s1_mant_in <= 0;
s1_exp_in <= 0;
s1_a <= 0;
s1_b <= 0;
s1_sign <= 0;
end else begin
s1_mant_in <= s0_mantissa;
s1_exp_in <= s0_exponent;
s1_a <= a;
s1_b <= b;
s1_sign <= sign;
end
end
// === STEP 7: Rounding // === Stage 2: Round ===
logic [24:0] mant_post_rnd; logic [22:0] s2_mant_in;
logic [9:0] exp_post_rnd; logic [9:0] s2_exp_in;
logic inexact; logic s2_guard_in, s2_sticky_in;
logic [31:0] s2_a, s2_b;
logic s2_sign;
logic [24:0] s2_mant_out;
logic [9:0] s2_exp_out;
logic s2_inexact;
round_mult round_inst ( round_mult round_inst (
.mantissa_in(mant_norm), .mantissa_in(s2_mant_in),
.exponent_in(exp_norm), .exponent_in(s2_exp_in),
.sign_in(sign_res), .sign_in(s2_sign),
.guard_bit(guard), .guard_bit(s2_guard_in),
.sticky_bit(sticky), .sticky_bit(s2_sticky_in),
.round(round), .round(round),
.mantissa_out(mant_post_rnd), .mantissa_out(s2_mant_out),
.exponent_out(exp_post_rnd), .exponent_out(s2_exp_out),
.inexact(inexact) .inexact(s2_inexact)
); );
//assign mant_post_rnd_ = mant_post_rnd; // DEBUG
//assign exp_post_rnd_ = exp_post_rnd; // DEBUG
// === STEP 8: Exception handling always_ff @(posedge clk or negedge rst) begin
// overflow / underflow: if (!rst) begin
logic [31:0] z_calc; s2_mant_in <= 0;
logic ovf, unf; s2_exp_in <= 0;
s2_guard_in <= 0;
assign z_calc = {sign_res, exp_post_rnd[7:0], mant_post_rnd[22:0]}; s2_sticky_in <= 0;
always_comb begin s2_a <= 0;
ovf = (exp_post_rnd > 10'd254); // MAX normal exponent s2_b <= 0;
unf = (exp_post_rnd < 10'd1); // MIN normal exponent s2_sign <= 0;
end else begin
s2_mant_in <= s1_mant_out;
s2_exp_in <= s1_exp_out;
s2_guard_in <= s1_guard_out;
s2_sticky_in <= s1_sticky_out;
s2_a <= s1_a;
s2_b <= s1_b;
s2_sign <= s1_sign;
end
end end
exception_mult exc_inst ( // === Stage 3: Exception Handling ===
.a(a), logic [31:0] s3_a, s3_b;
.b(b), logic [31:0] s3_z_calc_in;
.z_calc(z_calc), logic s3_ovf_in, s3_unf_in;
.ovf(ovf), logic s3_inexact;
.unf(unf), logic [31:0] s3_z_out;
.inexact(inexact), logic [7:0] s3_status_out;
exception_mult exception_handler (
.a(s3_a),
.b(s3_b),
.z_calc(s3_z_calc_in),
.ovf(s3_ovf_in),
.unf(s3_unf_in),
.inexact(s3_inexact),
.round(round), .round(round),
.z(z), .z(s3_z_out),
.zero_f(status[0]), .zero_f(s3_status_out[0]),
.inf_f(status[1]), .inf_f(s3_status_out[1]),
.nan_f(status[2]), .nan_f(s3_status_out[2]),
.tiny_f(status[3]), .tiny_f(s3_status_out[3]),
.huge_f(status[4]), .huge_f(s3_status_out[4]),
.inexact_f(status[5]) .inexact_f(s3_status_out[5])
); );
always_ff @(posedge clk or negedge rst) begin
if (!rst) begin
s3_a <= 0;
s3_b <= 0;
s3_z_calc_in <= 0;
s3_ovf_in <= 0;
s3_unf_in <= 0;
s3_inexact <= 0;
z <= 0;
status <= 0;
end else begin
s3_a <= s2_a;
s3_b <= s2_b;
s3_z_calc_in <= {s2_sign, s2_exp_out[7:0], s2_mant_out[22:0]};
s3_ovf_in <= (s2_exp_out > 8'd254);
s3_unf_in <= (s2_exp_out < 8'd1);
s3_inexact <= s2_inexact;
z <= s3_z_out;
status <= s3_status_out;
end
end
endmodule endmodule