From 1ea7c01bb8d2f5ee13e6f924da19617d667c9973 Mon Sep 17 00:00:00 2001 From: Christos Choutouridis Date: Sun, 15 Jun 2025 15:58:59 +0300 Subject: [PATCH] A No-Pipeline version of fp_mult w/o top test bench --- fpu_mult.mpf | 32 +++++++----- sim/fp_mult_tb.sv | 67 ++++++++++++++++++------ src/exception_mult.sv | 118 ++++++++++++++++++++++++++++++++++++++++++ src/fp_mult.sv | 51 ++++++++++++++++-- src/round_modes.sv | 10 ++++ src/round_mult.sv | 20 +++---- 6 files changed, 256 insertions(+), 42 deletions(-) create mode 100644 src/exception_mult.sv create mode 100644 src/round_modes.sv diff --git a/fpu_mult.mpf b/fpu_mult.mpf index ce05394..371bd6e 100644 --- a/fpu_mult.mpf +++ b/fpu_mult.mpf @@ -2304,21 +2304,25 @@ suppress = 8780 ;an explanation can be had by running: verror 8780 Project_Version = 6 Project_DefaultLib = work Project_SortMethod = unused -Project_Files_Count = 7 -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 folder src last_compile 1749838823 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 2 dont_compile 0 cover_expr 0 cover_stmt 0 -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 folder {Top Level} last_compile 1749470139 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 0 cover_expr 0 dont_compile 0 cover_stmt 0 -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 cover_fsm 0 cover_branch 0 vlog_noload 0 folder sim last_compile 1749484994 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_Files_Count = 9 +Project_File_0 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/fp_mult_top.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_1 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/normalize_mult.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_2 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/round_modes.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_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 last_compile 1749844905 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 3 cover_expr 0 dont_compile 0 cover_stmt 0 -Project_File_4 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/normalize_mult_tb.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 1749840708 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 5 dont_compile 0 cover_expr 0 cover_stmt 0 -Project_File_5 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/fp_mult_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 folder sim last_compile 1749488181 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 4 cover_expr 0 dont_compile 0 cover_stmt 0 -Project_File_6 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/round_mult.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 cover_fsm 0 cover_branch 0 vlog_noload 0 folder src last_compile 1749844323 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_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_4 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/round_mult_tb.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_5 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/exception_mult.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_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_7 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/round_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_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_Sim_Count = 0 Project_Folder_Count = 2 Project_Folder_0 = src diff --git a/sim/fp_mult_tb.sv b/sim/fp_mult_tb.sv index 9f8c452..8d35bc6 100644 --- a/sim/fp_mult_tb.sv +++ b/sim/fp_mult_tb.sv @@ -7,16 +7,38 @@ module fp_mult_tb; 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_; + */ // DUT fp_mult dut ( .a(a), .b(b), - .rnd(rnd), + .round(rnd), .z(z), .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 @@ -29,35 +51,50 @@ module fp_mult_tb; string desc; } test_vector_t; - test_vector_t tests [11]; + test_vector_t tests [14]; initial begin $display("Starting fp_mult test...\n"); // Normal multiplication cases - tests[0] = '{32'h3f800000, 32'h40000000, 32'h40400000, "1.0 * 2.0 = 2.0"}; - tests[1] = '{32'h40400000, 32'h40400000, 32'h40c00000, "3.0 * 3.0 = 9.0"}; - tests[2] = '{32'hbf800000, 32'h40000000, 32'hc0400000, "-1.0 * 2.0 = -2.0"}; - tests[3] = '{32'h3f000000, 32'h3f000000, 32'h3e800000, "0.5 * 0.5 = 0.25"}; - tests[4] = '{32'h3f800000, 32'h00000000, 32'h00000000, "1.0 * 0.0 = 0.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[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[5] = '{32'h7f800000, 32'h3f800000, 32'h7f800000, "inf * 1.0 = inf"}; - tests[6] = '{32'hff800000, 32'h3f800000, 32'hff800000, "-inf * 1.0 = -inf"}; - tests[7] = '{32'h7fc00000, 32'h3f800000, 32'h7fc00000, "NaN * 1.0 = NaN"}; - tests[8] = '{32'h00800000, 32'h00800000, 32'h00000000, "denorm * denorm = underflow"}; - tests[9] = '{32'h7f7fffff, 32'h7f7fffff, 32'h7f800000, "max * max = inf (overflow)"}; - tests[10] = '{32'h00000000, 32'hff800000, 32'hffc00000, "0.0 * -inf = NaN"}; + 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"}; + rnd = 3'b000; // default round to nearest rst = 1; #10; rst = 0; #10; - for (int i = 0; i < 11; i++) begin + 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"); diff --git a/src/exception_mult.sv b/src/exception_mult.sv new file mode 100644 index 0000000..817cbf4 --- /dev/null +++ b/src/exception_mult.sv @@ -0,0 +1,118 @@ +/* + * + */ + +`include "round_modes.sv" + +module exception_mult ( + input logic [31:0] a, b, + input logic [31:0] z_calc, + input logic ovf, unf, inexact, + input logic [2:0] round, + output logic [31:0] z, + output logic zero_f, inf_f, nan_f, tiny_f, huge_f, inexact_f +); + + // === ENUM DECLARATION === + typedef enum logic [2:0] { + ZERO, + INF, + NORM, + MIN_NORM, + MAX_NORM + } interp_t; + + // === num_interp FUNCTION === + function interp_t num_interp(input logic [31:0] x); + automatic logic [7:0] exp = x[30:23]; + automatic logic [22:0] mant = x[22:0]; + + if (exp == 8'd255) + return INF; + else if (exp == 8'd0) + return ZERO; + else if (exp == 8'd1 && mant == 0) + return MIN_NORM; + else if (exp == 8'd254 && mant == 23'h7FFFFF) + return MAX_NORM; + else + return NORM; + endfunction + + // === z_num FUNCTION === + function logic [30:0] z_num(input interp_t kind); + case (kind) + ZERO: return 31'd0; + INF: return {8'd255, 23'd0}; + MIN_NORM: return {8'd1, 23'd0}; + MAX_NORM: return {8'd254, 23'h7FFFFF}; + default: return 31'd0; + endcase + endfunction + + // === MAIN LOGIC === + interp_t a_class, b_class; + logic sign; + + always_comb begin + a_class = num_interp(a); + b_class = num_interp(b); + sign = z_calc[31]; + + // Default flags + {zero_f, inf_f, nan_f, tiny_f, huge_f, inexact_f} = '0; + z = z_calc; + + case ({a_class, b_class}) + {ZERO, ZERO}, {ZERO, NORM}, {NORM, ZERO}: + begin + z = {sign, z_num(ZERO)}; + zero_f = 1; + end + + {ZERO, INF}, {INF, ZERO}: + begin + z = {1'b0, z_num(INF)}; + nan_f = 1; + end + + {INF, INF}, {NORM, INF}, {INF, NORM}: + begin + z = {sign, z_num(INF)}; + inf_f = 1; + end + + default: begin // {NORM, NORM} + if (ovf) begin + case (round) + RND_IEEE_NEAREST_EVEN: z = {sign, z_num(MAX_NORM)}; + RND_IEEE_ZERO: z = {sign, z_num(MAX_NORM)}; + RND_IEEE_PINF: z = (sign == 0) ? {1'b0, z_num(INF)} : {1'b1, z_num(MAX_NORM)}; + RND_IEEE_NINF: z = (sign == 1) ? {1'b1, z_num(INF)} : {1'b0, z_num(MAX_NORM)}; + RND_NEAR_UP: z = (sign == 0) ? {1'b1, z_num(INF)} : {1'b0, z_num(MIN_NORM)}; + RND_AWAY_ZERO: z = {sign, z_num(MAX_NORM)}; + default: z = {sign, z_num(MAX_NORM)}; + endcase + huge_f = 1; + end + else if (unf) begin + case (round) + RND_IEEE_NEAREST_EVEN: z = {sign, z_num(MIN_NORM)}; + RND_IEEE_ZERO: z = {sign, z_num(ZERO)}; + RND_IEEE_PINF: z = (sign == 0) ? {1'b0, z_num(MIN_NORM)} : {1'b1, z_num(ZERO)}; + RND_IEEE_NINF: z = (sign == 1) ? {1'b1, z_num(MIN_NORM)} : {1'b0, z_num(ZERO)}; + RND_NEAR_UP: z = (sign == 1) ? {1'b1, z_num(ZERO)} : {1'b0, z_num(MIN_NORM)}; + RND_AWAY_ZERO: z = {sign, z_num(MIN_NORM)}; + default: z = {sign, z_num(MIN_NORM)}; + endcase + tiny_f = 1; + end + inf_f = (z[30:0] == z_num(INF)); + zero_f = (z[30:0] == z_num(ZERO)); + inexact_f = inexact || ovf || unf; + end + endcase + end + +endmodule + diff --git a/src/fp_mult.sv b/src/fp_mult.sv index 7551515..1a478e1 100644 --- a/src/fp_mult.sv +++ b/src/fp_mult.sv @@ -9,6 +9,17 @@ module fp_mult ( output logic [7:0] status, // status flags (placeholder) input logic clk, 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 @@ -31,17 +42,20 @@ module fp_mult ( // === STEP 1: Floating point number sign calculation logic sign_res; assign sign_res = sign_a ^ sign_b; + //assign sign_res_ = sign_res; // DEBUG // === STEP 2,3. Exponent addition, Exponent subtraction of bias logic [9:0] exp_sum; always_comb begin exp_sum = exp_a + exp_b - 127; // apply bias + //exp_sum_ = exp_sum; // DEBUG end // === 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 @@ -57,8 +71,13 @@ module fp_mult ( .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 + // Ehhh... We dont do that here... // === STEP 7: Rounding logic [24:0] mant_post_rnd; @@ -68,6 +87,7 @@ module fp_mult ( round_mult round_inst ( .mantissa_in(mant_norm), .exponent_in(exp_norm), + .sign_in(sign_res), .guard_bit(guard), .sticky_bit(sticky), .round(round), @@ -75,13 +95,36 @@ module fp_mult ( .exponent_out(exp_post_rnd), .inexact(inexact) ); + //assign mant_post_rnd_ = mant_post_rnd; // DEBUG + //assign exp_post_rnd_ = exp_post_rnd; // DEBUG // === STEP 8: Exception handling + // overflow / underflow: + logic [31:0] z_calc; + logic ovf, unf; - assign z = {sign_res, exp_post_rnd[7:0], mant_post_rnd[22:0]}; - - // === STEP 6: Status flags (placeholder) === - assign status = 8'b00000000; + assign z_calc = {sign_res, exp_post_rnd[7:0], mant_post_rnd[22:0]}; + always_comb begin + ovf = (exp_post_rnd > 10'd254); // MAX normal exponent + unf = (exp_post_rnd < 10'd1); // MIN normal exponent + end + exception_mult exc_inst ( + .a(a), + .b(b), + .z_calc(z_calc), + .ovf(ovf), + .unf(unf), + .inexact(inexact), + .round(round), + .z(z), + .zero_f(status[0]), + .inf_f(status[1]), + .nan_f(status[2]), + .tiny_f(status[3]), + .huge_f(status[4]), + .inexact_f(status[5]) + ); + endmodule diff --git a/src/round_modes.sv b/src/round_modes.sv new file mode 100644 index 0000000..a1664ce --- /dev/null +++ b/src/round_modes.sv @@ -0,0 +1,10 @@ + +// round_modes.svh +typedef enum logic [2:0] { + RND_IEEE_NEAREST_EVEN = 3'd0, + RND_IEEE_ZERO = 3'd1, + RND_IEEE_PINF = 3'd2, + RND_IEEE_NINF = 3'd3, + RND_NEAR_UP = 3'd4, + RND_AWAY_ZERO = 3'd5 +} round_mode_t; diff --git a/src/round_mult.sv b/src/round_mult.sv index b7188c9..d0defbe 100644 --- a/src/round_mult.sv +++ b/src/round_mult.sv @@ -1,13 +1,15 @@ // round_mult.sv // Rounds a normalized mantissa +`include "round_modes.sv" + module round_mult ( input logic [22:0] mantissa_in, // Input mantissa (no implicit bit) input logic [9:0] exponent_in, // Input exponent + input logic sign_in, input logic guard_bit, input logic sticky_bit, - input logic sign_in, - input logic round, + input logic [2:0] round, output logic [24:0] mantissa_out, // Rounded mantissa (24bit + 1bit possible ovf) output logic [9:0] exponent_out, output logic inexact @@ -63,13 +65,13 @@ module round_mult ( inexact = guard_bit | sticky_bit; case (round) - default: IEEE_nearest_even(); - 0: IEEE_nearest_even(); - 1: IEEE_zero(); - 2: IEEE_pinf(); - 3: IEEE_ninf(); - 4: near_up(); - 5: away_zero(); + default: IEEE_nearest_even(); + RND_IEEE_NEAREST_EVEN: IEEE_nearest_even(); + RND_IEEE_ZERO: IEEE_zero(); + RND_IEEE_PINF: IEEE_pinf(); + RND_IEEE_NINF: IEEE_ninf(); + RND_NEAR_UP: near_up(); + RND_AWAY_ZERO: away_zero(); endcase // Post-rounding normalization (if overflow in mantissa)