Started parameterizing FMA

This commit is contained in:
David Harris 2024-05-13 14:01:36 -07:00
parent c2b9e326ca
commit 2dfada0687
4 changed files with 12 additions and 7 deletions

View File

@ -115,6 +115,9 @@ localparam CVTLEN = (ZFA_SUPPORTED & D_SUPPORTED) ? `max(BASECVTLEN, 32'd84) : B
localparam LLEN = `max($unsigned(FLEN), $unsigned(XLEN)); localparam LLEN = `max($unsigned(FLEN), $unsigned(XLEN));
localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1)); localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1));
// size of FMA output
localparam FMALEN = 3*NF + 6;
// NORMSHIFTSIZE is the bits out of the normalization shifter // NORMSHIFTSIZE is the bits out of the normalization shifter
// RV32F: max(32+23+1, 2(23)+4, 3(23)+6) = 3*23+6 = 75 // 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 // 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 // because NORMSHIFTSZ becomes limited by convert rather than divider
// The two extra bits are necessary because shiftcorrection dropped them for fcvt. // The two extra bits are necessary because shiftcorrection dropped them for fcvt.
// May be possible to remove these two bits by modifying shiftcorrection // 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+2), (DIVb + 1 + NF + 1)), (FMALEN + 2));
//localparam NORMSHIFTSZ = `max(`max((CVTLEN+NF+1), (DIVb + 1 + NF + 1)), (3*NF+8)); //localparam NORMSHIFTSZ = `max(`max((CVTLEN+NF+1), (DIVb + 1 + NF + 1)), (FMALEN + 2));
localparam LOGNORMSHIFTSZ = ($clog2(NORMSHIFTSZ)); // log_2(NORMSHIFTSZ) localparam LOGNORMSHIFTSZ = ($clog2(NORMSHIFTSZ)); // log_2(NORMSHIFTSZ)
localparam CORRSHIFTSZ = NORMSHIFTSZ-2; // Drop leading 2 integer bits localparam CORRSHIFTSZ = NORMSHIFTSZ-2; // Drop leading 2 integer bits

View File

@ -193,6 +193,7 @@ localparam cvw_t P = '{
CVTLEN : CVTLEN, CVTLEN : CVTLEN,
LLEN : LLEN, LLEN : LLEN,
LOGCVTLEN : LOGCVTLEN, LOGCVTLEN : LOGCVTLEN,
FMALEN : FMALEN,
NORMSHIFTSZ : NORMSHIFTSZ, NORMSHIFTSZ : NORMSHIFTSZ,
LOGNORMSHIFTSZ : LOGNORMSHIFTSZ, LOGNORMSHIFTSZ : LOGNORMSHIFTSZ,
CORRSHIFTSZ : CORRSHIFTSZ, CORRSHIFTSZ : CORRSHIFTSZ,

View File

@ -287,6 +287,7 @@ typedef struct packed {
int LOGCVTLEN; int LOGCVTLEN;
int NORMSHIFTSZ; int NORMSHIFTSZ;
int LOGNORMSHIFTSZ; int LOGNORMSHIFTSZ;
int FMALEN;
int CORRSHIFTSZ; int CORRSHIFTSZ;
// division constants // division constants

View File

@ -34,13 +34,13 @@ module fma import cvw::*; #(parameter cvw_t P) (
input logic XZero, YZero, ZZero, // is the input zero input logic XZero, YZero, ZZero, // is the input zero
input logic [2:0] OpCtrl, // operation control input logic [2:0] OpCtrl, // operation control
output logic ASticky, // sticky bit that is calculated during alignment 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 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 As, // the aligned addend's sign (modified Z sign for other operations)
output logic Ps, // the product's sign output logic Ps, // the product's sign
output logic Ss, // the sum's sign output logic Ss, // the sum's sign
output logic [P.NE+1:0] Se, // the sum's exponent 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: // OpCtrl:
@ -54,8 +54,8 @@ module fma import cvw::*; #(parameter cvw_t P) (
// 111 - sub // 111 - sub
logic [2*P.NF+1:0] Pm; // the product's significand in U(2.2Nf) format 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 [P.FMALEN-1: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] AmInv; // aligned addend's mantissa possibly inverted
logic [2*P.NF+1:0] PmKilled; // the product's mantissa possibly killed U(2.2Nf) 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 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 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); 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 endmodule