From 2dfada06871644dbb0209526c5eebba5dd2604e9 Mon Sep 17 00:00:00 2001 From: David Harris Date: Mon, 13 May 2024 14:01:36 -0700 Subject: [PATCH] Started parameterizing FMA --- config/shared/config-shared.vh | 7 +++++-- config/shared/parameter-defs.vh | 1 + src/cvw.sv | 1 + src/fpu/fma/fma.sv | 10 +++++----- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/config/shared/config-shared.vh b/config/shared/config-shared.vh index 2401cada2..ae511e8c7 100644 --- a/config/shared/config-shared.vh +++ b/config/shared/config-shared.vh @@ -115,6 +115,9 @@ localparam CVTLEN = (ZFA_SUPPORTED & D_SUPPORTED) ? `max(BASECVTLEN, 32'd84) : B localparam LLEN = `max($unsigned(FLEN), $unsigned(XLEN)); localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1)); +// size of FMA output +localparam FMALEN = 3*NF + 6; + // NORMSHIFTSIZE is the bits out of the normalization shifter // RV32F: max(32+23+1, 2(23)+4, 3(23)+6) = 3*23+6 = 75 // RV64F: max(64+23+1, 64 + 23 + 2, 3*23+6) = 89 @@ -125,8 +128,8 @@ localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1)); // because NORMSHIFTSZ becomes limited by convert rather than divider // The two extra bits are necessary because shiftcorrection dropped them for fcvt. // May be possible to remove these two bits by modifying shiftcorrection -localparam NORMSHIFTSZ = `max(`max((CVTLEN+NF+1+2), (DIVb + 1 + NF + 1)), (3*NF+8)); -//localparam NORMSHIFTSZ = `max(`max((CVTLEN+NF+1), (DIVb + 1 + NF + 1)), (3*NF+8)); +localparam NORMSHIFTSZ = `max(`max((CVTLEN+NF+1+2), (DIVb + 1 + NF + 1)), (FMALEN + 2)); +//localparam NORMSHIFTSZ = `max(`max((CVTLEN+NF+1), (DIVb + 1 + NF + 1)), (FMALEN + 2)); localparam LOGNORMSHIFTSZ = ($clog2(NORMSHIFTSZ)); // log_2(NORMSHIFTSZ) localparam CORRSHIFTSZ = NORMSHIFTSZ-2; // Drop leading 2 integer bits diff --git a/config/shared/parameter-defs.vh b/config/shared/parameter-defs.vh index 96440490c..026794b4b 100644 --- a/config/shared/parameter-defs.vh +++ b/config/shared/parameter-defs.vh @@ -193,6 +193,7 @@ localparam cvw_t P = '{ CVTLEN : CVTLEN, LLEN : LLEN, LOGCVTLEN : LOGCVTLEN, + FMALEN : FMALEN, NORMSHIFTSZ : NORMSHIFTSZ, LOGNORMSHIFTSZ : LOGNORMSHIFTSZ, CORRSHIFTSZ : CORRSHIFTSZ, diff --git a/src/cvw.sv b/src/cvw.sv index 1f8e0a1c1..0a4cf1549 100644 --- a/src/cvw.sv +++ b/src/cvw.sv @@ -287,6 +287,7 @@ typedef struct packed { int LOGCVTLEN; int NORMSHIFTSZ; int LOGNORMSHIFTSZ; + int FMALEN; int CORRSHIFTSZ; // division constants diff --git a/src/fpu/fma/fma.sv b/src/fpu/fma/fma.sv index 3576b95df..8bf4d4cbb 100644 --- a/src/fpu/fma/fma.sv +++ b/src/fpu/fma/fma.sv @@ -34,13 +34,13 @@ module fma import cvw::*; #(parameter cvw_t P) ( input logic XZero, YZero, ZZero, // is the input zero input logic [2:0] OpCtrl, // operation control output logic ASticky, // sticky bit that is calculated during alignment - output logic [3*P.NF+5:0] Sm, // the positive sum's significand + output logic [P.FMALEN-1:0] Sm, // the positive sum's significand output logic InvA, // Was A inverted for effective subtraction (P-A or -P+A) output logic As, // the aligned addend's sign (modified Z sign for other operations) output logic Ps, // the product's sign output logic Ss, // the sum's sign output logic [P.NE+1:0] Se, // the sum's exponent - output logic [$clog2(3*P.NF+7)-1:0] SCnt // normalization shift count + output logic [$clog2(P.FMALEN+1)-1:0] SCnt // normalization shift count ); // OpCtrl: @@ -54,8 +54,8 @@ module fma import cvw::*; #(parameter cvw_t P) ( // 111 - sub logic [2*P.NF+1:0] Pm; // the product's significand in U(2.2Nf) format - logic [3*P.NF+5:0] Am; // addend aligned's mantissa for addition in U(NF+4.2NF) - logic [3*P.NF+5:0] AmInv; // aligned addend's mantissa possibly inverted + logic [P.FMALEN-1:0] Am; // addend aligned's mantissa for addition in U(NF+4.2NF) + logic [P.FMALEN-1:0] AmInv; // aligned addend's mantissa possibly inverted logic [2*P.NF+1:0] PmKilled; // the product's mantissa possibly killed U(2.2Nf) logic KillProd; // set the product to zero before addition if the product is too small to matter logic [P.NE+1:0] Pe; // the product's exponent B(NE+2.0) format; adds 2 bits to allow for size of number and negative sign @@ -89,6 +89,6 @@ module fma import cvw::*; #(parameter cvw_t P) ( fmaadd #(P) add(.Am, .Pm, .Ze, .Pe, .Ps, .KillProd, .ASticky, .AmInv, .PmKilled, .InvA, .Sm, .Se, .Ss); - fmalza #(3*P.NF+6, P.NF) lza(.A(AmInv), .Pm(PmKilled), .Cin(InvA & (~ASticky | KillProd)), .sub(InvA), .SCnt); + fmalza #(P.FMALEN, P.NF) lza(.A(AmInv), .Pm(PmKilled), .Cin(InvA & (~ASticky | KillProd)), .sub(InvA), .SCnt); endmodule