From c56dea1506043046319f60d4ae2a12f8ca9880f3 Mon Sep 17 00:00:00 2001 From: Christos Choutouridis Date: Fri, 13 Jun 2025 23:17:18 +0300 Subject: [PATCH] New normalize and round modules --- fpu_mult.mpf | 28 ++++++------- sim/normalize_mult_tb.sv | 56 ++++++++++++++------------ src/fp_mult.sv | 18 ++++----- src/normalize_mult.sv | 35 +++++----------- src/round_mult.sv | 86 +++++++++++++++++++++++++++++++--------- 5 files changed, 130 insertions(+), 93 deletions(-) diff --git a/fpu_mult.mpf b/fpu_mult.mpf index c7d9268..ce05394 100644 --- a/fpu_mult.mpf +++ b/fpu_mult.mpf @@ -2305,20 +2305,20 @@ Project_Version = 6 Project_DefaultLib = work Project_SortMethod = unused Project_Files_Count = 7 -Project_File_0 = /home/hoo2/Documents/HWDigSys-II/fpu_mult/sim/normalize_mult_tb.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 cover_fsm 0 cover_branch 0 vlog_noload 0 folder sim last_compile 1749493330 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 1 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 5 cover_expr 0 dont_compile 0 cover_stmt 0 -Project_File_1 = /home/hoo2/Documents/HWDigSys-II/fpu_mult/sim/fp_mult_tb.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 cover_fsm 0 cover_branch 0 vlog_noload 0 folder sim last_compile 1749488181 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_2 = /home/hoo2/Documents/HWDigSys-II/fpu_mult/src/round_mult.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 1749484998 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 4 dont_compile 0 cover_expr 0 cover_stmt 0 -Project_File_3 = /home/hoo2/Documents/HWDigSys-II/fpu_mult/fp_mult_top.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 1749470139 cover_fsm 0 cover_branch 0 vlog_noload 0 folder {Top Level} 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 2 cover_expr 0 dont_compile 0 cover_stmt 0 -Project_File_4 = /home/hoo2/Documents/HWDigSys-II/fpu_mult/src/normalize_mult.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 folder src last_compile 1749493030 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 1 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_5 = /home/hoo2/Documents/HWDigSys-II/fpu_mult/src/fp_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 1749492843 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_6 = /home/hoo2/Documents/HWDigSys-II/fpu_mult/sim/round_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 cover_fsm 0 cover_branch 0 vlog_noload 0 folder sim last_compile 1749484994 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 6 dont_compile 0 cover_expr 0 cover_stmt 0 +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_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_Sim_Count = 0 Project_Folder_Count = 2 Project_Folder_0 = src diff --git a/sim/normalize_mult_tb.sv b/sim/normalize_mult_tb.sv index 86ccc24..85b389a 100644 --- a/sim/normalize_mult_tb.sv +++ b/sim/normalize_mult_tb.sv @@ -18,44 +18,48 @@ module normalize_mult_tb; ); initial begin - integer i; - logic [47:0] mantissa_inputs [13]; - logic [9:0] exponent_inputs [13]; - logic [22:0] exp_mantissas [13]; - logic [9:0] exp_exponents [13]; - string exp_grs [13]; + logic [47:0] mantissa_inputs [8]; + logic [9:0] exponent_inputs [8]; + logic [22:0] exp_mantissas [8]; + logic [9:0] exp_exponents [8]; + logic exp_guard [8]; + logic exp_sticky [8]; + + string result; $display("Starting normalize_mult test...\n"); - mantissa_inputs[0] = 48'h800000000000; exponent_inputs[0] = 130; exp_mantissas[0] = 23'h400000; exp_exponents[0] = 131; exp_grs[0] = "0,0"; - mantissa_inputs[1] = 48'h400000000000; exponent_inputs[1] = 130; exp_mantissas[1] = 23'h400000; exp_exponents[1] = 130; exp_grs[1] = "0,0"; - mantissa_inputs[2] = 48'h200000000000; exponent_inputs[2] = 130; exp_mantissas[2] = 23'h400000; exp_exponents[2] = 129; exp_grs[2] = "0,0"; - mantissa_inputs[3] = 48'h000040000000; exponent_inputs[3] = 130; exp_mantissas[3] = 23'h400000; exp_exponents[3] = 114; exp_grs[3] = "0,0"; - mantissa_inputs[4] = 48'h000000000F00; exponent_inputs[4] = 130; exp_mantissas[4] = 23'h780000; exp_exponents[4] = 95; exp_grs[4] = "0,0"; - mantissa_inputs[5] = 48'h000000000000; exponent_inputs[5] = 130; exp_mantissas[5] = 23'h000000; exp_exponents[5] = 130; exp_grs[5] = "0,0"; - mantissa_inputs[6] = 48'h400000000080; exponent_inputs[6] = 130; exp_mantissas[6] = 23'h400000; exp_exponents[6] = 130; exp_grs[6] = "0,1"; - mantissa_inputs[7] = 48'h4000000000C0; exponent_inputs[7] = 130; exp_mantissas[7] = 23'h400000; exp_exponents[7] = 130; exp_grs[7] = "0,1"; - mantissa_inputs[8] = 48'h400000000089; exponent_inputs[8] = 130; exp_mantissas[8] = 23'h400000; exp_exponents[8] = 130; exp_grs[8] = "0,1"; - mantissa_inputs[9] = 48'h4000000000FF; exponent_inputs[9] = 130; exp_mantissas[9] = 23'h400000; exp_exponents[9] = 130; exp_grs[9] = "0,1"; - mantissa_inputs[10]= 48'h400000800000; exponent_inputs[10]= 130; exp_mantissas[10]=23'h400000; exp_exponents[10]=130; exp_grs[10]= "1,0"; - mantissa_inputs[11]= 48'h400000C00000; exponent_inputs[11]= 130; exp_mantissas[11]=23'h400000; exp_exponents[11]=130; exp_grs[11]= "1,1"; - mantissa_inputs[12]= 48'h800000000001; exponent_inputs[12]= 130; exp_mantissas[12]=23'h400000; exp_exponents[12]=131; exp_grs[12]= "0,1"; + mantissa_inputs[0] = 48'hC40000800000; exponent_inputs[0] = 130; exp_mantissas[0] = 23'h440000; exp_exponents[0] = 131; exp_guard[0] = 1; exp_sticky[0] = 0; + mantissa_inputs[1] = 48'h440000000080; exponent_inputs[1] = 130; exp_mantissas[1] = 23'h080000; exp_exponents[1] = 130; exp_guard[1] = 0; exp_sticky[1] = 1; + mantissa_inputs[2] = 48'h440000400080; exponent_inputs[2] = 130; exp_mantissas[2] = 23'h080000; exp_exponents[2] = 130; exp_guard[2] = 1; exp_sticky[2] = 1; - for (i = 0; i < 13; i++) begin + for (i = 0; i < 3; i++) begin mantissa_in = mantissa_inputs[i]; exponent_in = exponent_inputs[i]; - #10; - $display("[%0d] IN=%h | EXPECTED: OUT=%h EXP=%0d (G,S)=(%s) | OUT=%h EXP=%0d (G,S)=(%b,%b)", - i+1, - mantissa_in, + #5; + + if (mantissa_out === exp_mantissas[i] && + exponent_out === exp_exponents[i] && + guard_bit === exp_guard[i] && + sticky_bit === exp_sticky[i]) + result = "PASS"; + else + result = "FAIL"; + + $display("[%0d] IN=%h | EXP: mant=%h exp=%0d G=%0b S=%0b | OUT: mant=%h exp=%0d G=%0b S=%0b => %s", + i, + mantissa_inputs[i], exp_mantissas[i], exp_exponents[i], - exp_grs[i], + exp_guard[i], + exp_sticky[i], mantissa_out, exponent_out, - guard_bit, sticky_bit + guard_bit, + sticky_bit, + result ); end diff --git a/src/fp_mult.sv b/src/fp_mult.sv index 9d9976a..7551515 100644 --- a/src/fp_mult.sv +++ b/src/fp_mult.sv @@ -4,7 +4,7 @@ module fp_mult ( input logic [31:0] a, // input operand A input logic [31:0] b, // input operand B - input logic [2:0] rnd, // rounding mode + input logic [2:0] round, // rounding mode output logic [31:0] z, // result output logic [7:0] status, // status flags (placeholder) input logic clk, @@ -61,24 +61,24 @@ module fp_mult ( // === STEP 6: Pipeline stage // === STEP 7: Rounding - logic [22:0] mant_rounded; - logic [7:0] exp_rounded; + logic [24:0] mant_post_rnd; + logic [9:0] exp_post_rnd; + logic inexact; round_mult round_inst ( .mantissa_in(mant_norm), .exponent_in(exp_norm), .guard_bit(guard), - .round_bit(round), .sticky_bit(sticky), - .rnd(rnd), - .mantissa_out(mant_rounded), - .exponent_out(exp_rounded) + .round(round), + .mantissa_out(mant_post_rnd), + .exponent_out(exp_post_rnd), + .inexact(inexact) ); // === STEP 8: Exception handling - - assign z = {sign_res, exp_rounded, mant_rounded}; + assign z = {sign_res, exp_post_rnd[7:0], mant_post_rnd[22:0]}; // === STEP 6: Status flags (placeholder) === assign status = 8'b00000000; diff --git a/src/normalize_mult.sv b/src/normalize_mult.sv index 3144936..882319f 100644 --- a/src/normalize_mult.sv +++ b/src/normalize_mult.sv @@ -16,37 +16,20 @@ module normalize_mult ( logic [9:0] exponent_adj; logic sticky; - always_comb begin - // Default assignments - shift_amount = 0; - mant_shifted = mantissa_in; - exponent_adj = exponent_in; + always_comb begin if (mantissa_in[47] == 1'b1) begin - // Overflow: shift right by 1 and increment exponent - mant_shifted = mantissa_in >> 1; - exponent_adj = exponent_in + 1; - sticky = mantissa_in[0]; + exponent_out = exponent_in + 1; + mantissa_out = mantissa_in[46:24]; + guard_bit = mantissa_in[23]; + sticky_bit = | mantissa_in[22:0]; end else begin - // Normalize: shift left until MSB '1' is at bit 46 - for (int i = 0; i <= 46; i++) begin - if (mantissa_in[46 - i] == 1'b1) begin - shift_amount = i; - break; - end - end - mant_shifted = mantissa_in << shift_amount; - exponent_adj = exponent_in - shift_amount; - sticky = | mant_shifted[22:0]; // Sticky bit = OR of remaining bits + exponent_out = exponent_in; + mantissa_out = mantissa_in[45:23]; + guard_bit = mantissa_in[22]; + sticky_bit = | mantissa_in[21:0]; end - - // Extract normalized mantissa and rounding bits - mantissa_out = mant_shifted[46:24]; // Correct 23-bit mantissa - exponent_out = exponent_adj; - guard_bit = mant_shifted[23]; // Guard bit - sticky_bit = sticky; end - endmodule diff --git a/src/round_mult.sv b/src/round_mult.sv index 32cbe8f..b7188c9 100644 --- a/src/round_mult.sv +++ b/src/round_mult.sv @@ -1,38 +1,88 @@ // round_mult.sv -// Rounds a normalized mantissa using GRS bits (round to nearest, ties to even) +// Rounds a normalized mantissa module round_mult ( input logic [22:0] mantissa_in, // Input mantissa (no implicit bit) - input logic [7:0] exponent_in, // Input exponent + input logic [9:0] exponent_in, // Input exponent input logic guard_bit, - input logic round_bit, input logic sticky_bit, - output logic [22:0] mantissa_out, // Rounded mantissa - output logic [7:0] exponent_out // Adjusted exponent (if mantissa overflows) + input logic sign_in, + input logic round, + output logic [24:0] mantissa_out, // Rounded mantissa (24bit + 1bit possible ovf) + output logic [9:0] exponent_out, + output logic inexact ); - logic round_up; logic [23:0] mantissa_extended; - logic [23:0] mantissa_rounded; + logic [24:0] mantissa_rounded; + // === modes + task automatic IEEE_nearest_even(); + if (guard_bit && (sticky_bit || mantissa_extended[0])) begin + mantissa_rounded = mantissa_extended + 1; + end + endtask + + task automatic IEEE_zero(); + mantissa_rounded = mantissa_extended; + endtask + + task automatic IEEE_pinf(); + if (!sign_in && (guard_bit | sticky_bit)) begin + mantissa_rounded = mantissa_extended + 1; + end + endtask + + task automatic IEEE_ninf(); + if (sign_in && (guard_bit | sticky_bit)) begin + mantissa_rounded = mantissa_extended + 1; + end + endtask + + task automatic near_up(); + if (guard_bit) begin + mantissa_rounded = mantissa_extended + 1; + end + endtask + + task automatic away_zero(); + if (guard_bit | sticky_bit) begin + mantissa_rounded = mantissa_extended + 1; + end + endtask + + // + // ============================== + // always_comb begin // Concatenate implicit '1' at MSB - mantissa_extended = {1'b0, mantissa_in}; + mantissa_extended = {1'b1, mantissa_in}; - // Round to nearest, ties to even - round_up = 0; - if (guard_bit && (round_bit || sticky_bit || mantissa_in[0])) begin - round_up = 1; + mantissa_rounded = mantissa_extended; + exponent_out = exponent_in; + 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(); + endcase + + // Post-rounding normalization (if overflow in mantissa) + if (mantissa_rounded[24]) begin + mantissa_out = mantissa_rounded; + end else begin + mantissa_out = {1'b0, mantissa_rounded[23:0]}; end - mantissa_rounded = mantissa_extended + round_up; - - if (mantissa_rounded[23]) begin - // Overflow in rounding ? shift right and increment exponent - mantissa_out = mantissa_rounded[23:1]; + // Shift and increment exponent if overflowed to bit 24 + if (mantissa_rounded[24]) begin exponent_out = exponent_in + 1; end else begin - mantissa_out = mantissa_rounded[22:0]; exponent_out = exponent_in; end end