diff --git a/pipelined/config/rv64fp/wally-config.vh b/pipelined/config/rv64fp/wally-config.vh index cc8d1b2b..8f13b2e3 100644 --- a/pipelined/config/rv64fp/wally-config.vh +++ b/pipelined/config/rv64fp/wally-config.vh @@ -32,7 +32,7 @@ `define DESIGN_COMPILER 0 // RV32 or RV64: XLEN = 32 or 64 -`define XLEN 32 +`define XLEN 64 // IEEE 754 compliance `define IEEE754 0 diff --git a/pipelined/src/fpu/divshiftcalc.sv b/pipelined/src/fpu/divshiftcalc.sv index 51698590..2d722618 100644 --- a/pipelined/src/fpu/divshiftcalc.sv +++ b/pipelined/src/fpu/divshiftcalc.sv @@ -11,7 +11,7 @@ module divshiftcalc( output logic [`NE+1:0] DivDenormShift ); logic [`NE+1:0] NormShift; - logic [`NE+1:0] Nf, NfPlus1; + logic [`NE+1:0] Nf; // is the result denromalized // if the exponent is 1 then the result needs to be normalized then the result is denormalizes @@ -19,51 +19,25 @@ module divshiftcalc( // select the proper fraction lengnth if (`FPSIZES == 1) begin assign Nf = (`NE+2)'(`NF); - assign NfPlus1 = (`NE+2)'(`NF+1); end else if (`FPSIZES == 2) begin assign Nf = FmtM ? (`NE+2)'(`NF) : (`NE+2)'(`NF1); - assign NfPlus1 = FmtM ? (`NE+2)'(`NF+1) : (`NE+2)'(`NF1+1); end else if (`FPSIZES == 3) begin always_comb case (FmtM) - `FMT: begin - Nf = (`NE+2)'(`NF); - NfPlus1 = (`NE+2)'(`NF+1); - end - `FMT1: begin - Nf = (`NE+2)'(`NF1); - NfPlus1 = (`NE+2)'(`NF1+1); - end - `FMT2: begin - Nf = (`NE+2)'(`NF2); - NfPlus1 = (`NE+2)'(`NF2+1); - end - default: begin - Nf = 1'bx; - NfPlus1 = 1'bx; - end + `FMT: Nf = (`NE+2)'(`NF); + `FMT1: Nf = (`NE+2)'(`NF1); + `FMT2: Nf = (`NE+2)'(`NF2); + default: Nf = 1'bx; endcase end else if (`FPSIZES == 4) begin always_comb case (FmtM) - 2'h3: begin - Nf = (`NE+2)'(`Q_NF); - NfPlus1 = (`NE+2)'(`Q_NF+1); - end - 2'h1: begin - Nf = (`NE+2)'(`D_NF); - NfPlus1 = (`NE+2)'(`D_NF+1); - end - 2'h0: begin - Nf = (`NE+2)'(`S_NF); - NfPlus1 = (`NE+2)'(`S_NF+1); - end - 2'h2: begin - Nf = (`NE+2)'(`H_NF); - NfPlus1 = (`NE+2)'(`H_NF+1); - end + 2'h3: Nf = (`NE+2)'(`Q_NF); + 2'h1: Nf = (`NE+2)'(`D_NF); + 2'h0: Nf = (`NE+2)'(`S_NF); + 2'h2: Nf = (`NE+2)'(`H_NF); endcase end // if the result is denormalized diff --git a/pipelined/src/fpu/fma.sv b/pipelined/src/fpu/fma.sv index 8f5fccf4..2b524592 100644 --- a/pipelined/src/fpu/fma.sv +++ b/pipelined/src/fpu/fma.sv @@ -30,27 +30,27 @@ `include "wally-config.vh" module fma( - input logic XSgnE, YSgnE, ZSgnE, // input's signs - input logic [`NE-1:0] XExpE, YExpE, ZExpE, // biased exponents in B(NE.0) format - input logic [`NF:0] XManE, YManE, ZManE, // fractions in U(0.NF) format + input logic Xs, Ys, Zs, // input's signs + input logic [`NE-1:0] Xe, Ye, Ze, // input's biased exponents in B(NE.0) format + input logic [`NF:0] Xm, Ym, Zm, // input's significands in U(0.NF) format input logic XZeroE, YZeroE, ZZeroE, // is the input zero input logic [2:0] FOpCtrlE, // 000 = fmadd (X*Y)+Z, 001 = fmsub (X*Y)-Z, 010 = fnmsub -(X*Y)+Z, 011 = fnmadd -(X*Y)-Z, 100 = fmul (X*Y) input logic [`FMTBITS-1:0] FmtE, // precision 1 = double 0 = single - output logic [`NE+1:0] ProdExpE, // X exponent + Y exponent - bias in B(NE+2.0) format; adds 2 bits to allow for size of number and negative sign + output logic [`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 output logic AddendStickyE, // sticky bit that is calculated during alignment output logic KillProdE, // set the product to zero before addition if the product is too small to matter - output logic [3*`NF+5:0] SumE, // the positive sum + output logic [3*`NF+5:0] Sm, // the positive sum output logic NegSumE, // was the sum negitive - output logic InvZE, // intert Z + output logic InvA, // intert Z output logic ZSgnEffE, // the modified Z sign - output logic PSgnE, // the product's sign + output logic Ps, // the product's sign output logic [$clog2(3*`NF+7)-1:0] FmaNormCntE // normalization shift cnt ); - logic [2*`NF+1:0] ProdManE; // 1.X frac * 1.Y frac in U(2.2Nf) format - logic [3*`NF+5:0] AlignedAddendE; // Z aligned for addition in U(NF+5.2NF+1) - logic [3*`NF+6:0] AlignedAddendInv; // aligned addend possibly inverted - logic [2*`NF+1:0] ProdManKilled; // the product's mantissa possibly killed + logic [2*`NF+1:0] Pm; // the product's significand in U(2.2Nf) format + logic [3*`NF+5:0] Am; // Z aligned for addition in U(NF+5.2NF+1) + logic [3*`NF+6:0] AmInv; // aligned addend possibly inverted + logic [2*`NF+1:0] PmKilled; // the product's mantissa possibly killed logic [3*`NF+6:0] PreSum, NegPreSum; // positive and negitve versions of the sum /////////////////////////////////////////////////////////////////////////////// // Calculate the product @@ -62,43 +62,40 @@ module fma( // calculate the product's exponent - expadd expadd(.FmtE, .XExpE, .YExpE, .XZeroE, .YZeroE, .ProdExpE); + expadd expadd(.FmtE, .Xe, .Ye, .XZeroE, .YZeroE, .Pe); // multiplication of the mantissa's - mult mult(.XManE, .YManE, .ProdManE); + mult mult(.Xm, .Ym, .Pm); /////////////////////////////////////////////////////////////////////////////// // Alignment shifter /////////////////////////////////////////////////////////////////////////////// - align align(.ZExpE, .ZManE, .XZeroE, .YZeroE, .ZZeroE, .XExpE, .YExpE, - .AlignedAddendE, .AddendStickyE, .KillProdE); + align align(.Ze, .Zm, .XZeroE, .YZeroE, .ZZeroE, .Xe, .Ye, + .Am, .AddendStickyE, .KillProdE); // calculate the signs and take the opperation into account - sign sign(.FOpCtrlE, .XSgnE, .YSgnE, .ZSgnE, .PSgnE, .ZSgnEffE); + sign sign(.FOpCtrlE, .Xs, .Ys, .Zs, .Ps, .ZSgnEffE); // /////////////////////////////////////////////////////////////////////////////// // // Addition/LZA // /////////////////////////////////////////////////////////////////////////////// - add add(.AlignedAddendE, .ProdManE, .PSgnE, .ZSgnEffE, .KillProdE, .AlignedAddendInv, .ProdManKilled, .NegSumE, .PreSum, .NegPreSum, .InvZE, .XZeroE, .YZeroE); + add add(.Am, .Pm, .Ps, .ZSgnEffE, .KillProdE, .AmInv, .PmKilled, .NegSumE, .PreSum, .NegPreSum, .InvA, .XZeroE, .YZeroE, .Sm); - loa loa(.A(AlignedAddendInv+{(3*`NF+6)'(0),InvZE}), .P(ProdManKilled), .FmaNormCntE); - - // Choose the positive sum and accompanying LZA result. - assign SumE = NegSumE ? NegPreSum[3*`NF+5:0] : PreSum[3*`NF+5:0]; + loa loa(.A(AmInv+{(3*`NF+6)'(0),InvA}), .P(PmKilled), .FmaNormCntE); endmodule module expadd( input logic [`FMTBITS-1:0] FmtE, // precision - input logic [`NE-1:0] XExpE, YExpE, // input exponents + input logic [`NE-1:0] Xe, Ye, // input exponents input logic XZeroE, YZeroE, // are the inputs zero - output logic [`NE+1:0] ProdExpE // product's exponent B^(1023)NE+2 + output logic [`NE+1:0] Pe // product's exponent B^(1023)NE+2 ); // kill the exponent if the product is zero - either X or Y is 0 - assign ProdExpE = ({2'b0, XExpE} + {2'b0, YExpE} - {2'b0, (`NE)'(`BIAS)})&{`NE+2{~(XZeroE|YZeroE)}}; + assign Pe = ({2'b0, Xe} + {2'b0, Ye} - {2'b0, (`NE)'(`BIAS)})&{`NE+2{~(XZeroE|YZeroE)}}; endmodule @@ -107,10 +104,10 @@ endmodule module mult( - input logic [`NF:0] XManE, YManE, - output logic [2*`NF+1:0] ProdManE + input logic [`NF:0] Xm, Ym, + output logic [2*`NF+1:0] Pm ); - assign ProdManE = XManE * YManE; + assign Pm = Xm * Ym; endmodule @@ -122,8 +119,8 @@ endmodule module sign( input logic [2:0] FOpCtrlE, // precision - input logic XSgnE, YSgnE, ZSgnE, // are the inputs denormalized - output logic PSgnE, // the product's sign - takes opperation into account + input logic Xs, Ys, Zs, // are the inputs denormalized + output logic Ps, // the product's sign - takes opperation into account output logic ZSgnEffE // Z sign used in fma - takes opperation into account ); @@ -131,9 +128,9 @@ module sign( // Negate product's sign if FNMADD or FNMSUB // flip is negation opperation - assign PSgnE = XSgnE ^ YSgnE ^ (FOpCtrlE[1]&~FOpCtrlE[2]); + assign Ps = Xs ^ Ys ^ (FOpCtrlE[1]&~FOpCtrlE[2]); // flip if subtraction - assign ZSgnEffE = ZSgnE^FOpCtrlE[0]; + assign ZSgnEffE = Zs^FOpCtrlE[0]; endmodule @@ -145,10 +142,10 @@ endmodule module align( - input logic [`NE-1:0] XExpE, YExpE, ZExpE, // biased exponents in B(NE.0) format - input logic [`NF:0] ZManE, // fractions in U(0.NF) format] + input logic [`NE-1:0] Xe, Ye, Ze, // biased exponents in B(NE.0) format + input logic [`NF:0] Zm, // fractions in U(0.NF) format] input logic XZeroE, YZeroE, ZZeroE, // is the input zero - output logic [3*`NF+5:0] AlignedAddendE, // Z aligned for addition in U(NF+5.2NF+1) + output logic [3*`NF+5:0] Am, // Z aligned for addition in U(NF+5.2NF+1) output logic AddendStickyE, // Sticky bit calculated from the aliged addend output logic KillProdE // should the product be set to zero ); @@ -156,6 +153,7 @@ module align( logic [`NE+1:0] AlignCnt; // how far to shift the addend to align with the product in Q(NE+2.0) format logic [4*`NF+5:0] ZManShifted; // output of the alignment shifter including sticky bits U(NF+5.3NF+1) logic [4*`NF+5:0] ZManPreShifted; // input to the alignment shifter U(NF+5.3NF+1) + logic KillZ; /////////////////////////////////////////////////////////////////////////////// // Alignment shifter @@ -164,15 +162,19 @@ module align( // determine the shift count for alignment // - negitive means Z is larger, so shift Z left // - positive means the product is larger, so shift Z right - // This could have been done using ProdExpE, but AlignCnt is on the critical path so we replicate logic for speed - assign AlignCnt = XZeroE|YZeroE ? -(`NE+2)'($unsigned(1)) : {2'b0, XExpE} + {2'b0, YExpE} - {2'b0, (`NE)'(`BIAS)} + (`NE+2)'(`NF)+3 - {2'b0, ZExpE}; + // This could have been done using Pe, but AlignCnt is on the critical path so we replicate logic for speed + assign AlignCnt = {2'b0, Xe} + {2'b0, Ye} - {2'b0, (`NE)'(`BIAS)} + (`NE+2)'(`NF+3) - {2'b0, Ze}; // Defualt Addition without shifting // | 54'b0 | 106'b(product) | 2'b0 | // | addnend | // the 1'b0 before the added is because the product's mantissa has two bits before the binary point (xx.xxxxxxxxxx...) - assign ZManPreShifted = {ZManE,(3*`NF+5)'(0)}; + assign ZManPreShifted = {Zm,(3*`NF+5)'(0)}; + + assign KillProdE = AlignCnt[`NE+1]|XZeroE|YZeroE; + assign KillZ = $signed(AlignCnt)>$signed((`NE+2)'(3)*(`NE+2)'(`NF)+(`NE+2)'(5)); + always_comb begin @@ -180,34 +182,31 @@ module align( // | 54'b0 | 106'b(product) | 2'b0 | // | addnend | - if ($signed(AlignCnt) < $signed((`NE+2)'(0))) begin - KillProdE = 1; + if (KillProdE) begin ZManShifted = ZManPreShifted; AddendStickyE = ~(XZeroE|YZeroE); - // If the Addend is shifted right - // | 54'b0 | 106'b(product) | 2'b0 | - // | addnend | - end else if ($signed(AlignCnt)<=$signed((`NE+2)'(3)*(`NE+2)'(`NF)+(`NE+2)'(5))) begin - KillProdE = 0; - ZManShifted = ZManPreShifted >> AlignCnt; - AddendStickyE = |(ZManShifted[`NF-1:0]); - // If the addend is too small to effect the addition // - The addend has to shift two past the end of the addend to be considered too small // - The 2 extra bits are needed for rounding // | 54'b0 | 106'b(product) | 2'b0 | // | addnend | - end else begin - KillProdE = 0; + end else if (KillZ) begin ZManShifted = 0; AddendStickyE = ~ZZeroE; + // If the Addend is shifted right + // | 54'b0 | 106'b(product) | 2'b0 | + // | addnend | + end else begin + ZManShifted = ZManPreShifted >> AlignCnt; + AddendStickyE = |(ZManShifted[`NF-1:0]); + end end - assign AlignedAddendE = ZManShifted[4*`NF+5:`NF]; + assign Am = ZManShifted[4*`NF+5:`NF]; endmodule @@ -218,15 +217,16 @@ endmodule module add( - input logic [3*`NF+5:0] AlignedAddendE, // Z aligned for addition in U(NF+5.2NF+1) - input logic [2*`NF+1:0] ProdManE, // the product's mantissa - input logic PSgnE, ZSgnEffE,// the product and modified Z signs + input logic [3*`NF+5:0] Am, // Z aligned for addition in U(NF+5.2NF+1) + input logic [2*`NF+1:0] Pm, // the product's mantissa + input logic Ps, ZSgnEffE,// the product and modified Z signs input logic KillProdE, // should the product be set to 0 input logic XZeroE, YZeroE, // is the input zero - output logic [3*`NF+6:0] AlignedAddendInv, // aligned addend possibly inverted - output logic [2*`NF+1:0] ProdManKilled, // the product's mantissa possibly killed + output logic [3*`NF+6:0] AmInv, // aligned addend possibly inverted + output logic [2*`NF+1:0] PmKilled, // the product's mantissa possibly killed output logic NegSumE, // was the sum negitive - output logic InvZE, // do you invert Z + output logic InvA, // do you invert Z + output logic [3*`NF+5:0] Sm, // the positive sum output logic [3*`NF+6:0] PreSum, NegPreSum// possibly negitive sum ); @@ -237,23 +237,25 @@ module add( // Negate Z when doing one of the following opperations: // -prod + Z // prod - Z - assign InvZE = ZSgnEffE ^ PSgnE; + assign InvA = ZSgnEffE ^ Ps; // Choose an inverted or non-inverted addend - the one has to be added now for the LZA - assign AlignedAddendInv = InvZE ? {1'b1, ~AlignedAddendE} : {1'b0, AlignedAddendE}; + assign AmInv = InvA ? {1'b1, ~Am} : {1'b0, Am}; // Kill the product if the product is too small to effect the addition (determined in fma1.sv) - assign ProdManKilled = ProdManE&{2*`NF+2{~KillProdE}}; + assign PmKilled = Pm&{2*`NF+2{~KillProdE}}; // Do the addition // - calculate a positive and negitive sum in parallel - assign PreSum = AlignedAddendInv + {{`NF+3{1'b0}}, ProdManKilled, 2'b0} + {{3*`NF+6{1'b0}}, InvZE}; - assign NegPreSum = XZeroE|YZeroE|KillProdE ? {1'b0, AlignedAddendE} : {1'b0, AlignedAddendE} + {{`NF+3{1'b1}}, ~ProdManKilled, 2'b0} + {(3*`NF+7)'(4)}; + assign PreSum = {{`NF+3{1'b0}}, PmKilled, 2'b0} + AmInv + {{3*`NF+6{1'b0}}, InvA}; + assign NegPreSum = {1'b0, Am} + {{`NF+3{1'b1}}, ~PmKilled, 2'b0} + {(3*`NF+7)'(4)}; // Is the sum negitive assign NegSumE = PreSum[3*`NF+6]; + // Choose the positive sum and accompanying LZA result. + assign Sm = NegSumE ? NegPreSum[3*`NF+5:0] : PreSum[3*`NF+5:0]; endmodule diff --git a/pipelined/src/fpu/fmashiftcalc.sv b/pipelined/src/fpu/fmashiftcalc.sv index 2a241728..727d26e0 100644 --- a/pipelined/src/fpu/fmashiftcalc.sv +++ b/pipelined/src/fpu/fmashiftcalc.sv @@ -27,7 +27,7 @@ module fmashiftcalc( // calculate the sum's exponent assign NormSumExp = KillProdM ? {2'b0, ZExpM[`NE-1:1], ZExpM[0]&~ZDenormM} : ProdExpM + -{{`NE+2-$unsigned($clog2(3*`NF+7)){1'b0}}, FmaNormCntM} - 1 + (`NE+2)'(`NF+4); - //convert the sum's exponent into the propper percision + //convert the sum's exponent into the proper percision if (`FPSIZES == 1) begin assign ConvNormSumExp = NormSumExp; @@ -105,7 +105,7 @@ module fmashiftcalc( 2'h1: PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero; 2'h0: PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero; 2'h2: PreResultDenorm = Sum3LEZ & Sum3GEFL & ~SumZero; - endcase + endcase // *** remove checking to see if it's underflowed and only check for less than zero for denorm checking end end diff --git a/pipelined/src/fpu/fpu.sv b/pipelined/src/fpu/fpu.sv index 25b39d69..7cf10901 100755 --- a/pipelined/src/fpu/fpu.sv +++ b/pipelined/src/fpu/fpu.sv @@ -110,7 +110,7 @@ module fpu ( logic [`NE+1:0] ProdExpE, ProdExpM; logic AddendStickyE, AddendStickyM; logic KillProdE, KillProdM; - logic InvZE, InvZM; + logic InvAE, InvAM; logic NegSumE, NegSumM; logic ZSgnEffE, ZSgnEffM; logic PSgnE, PSgnM; @@ -249,10 +249,10 @@ module fpu ( .XZeroE, .YZeroE, .ZZeroE, .XInfE, .YInfE, .ZInfE, .XExpMaxE); // fma - does multiply, add, and multiply-add instructions - fma fma (.XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, - .XManE, .YManE, .ZManE, .XZeroE, .YZeroE, .ZZeroE, - .FOpCtrlE, .FmtE, .SumE, .NegSumE, .InvZE, .FmaNormCntE, - .ZSgnEffE, .PSgnE, .ProdExpE, .AddendStickyE, .KillProdE); + fma fma (.Xs(XSgnE), .Ys(YSgnE), .Zs(ZSgnE), .Xe(XExpE), .Ye(YExpE), .Ze(ZExpE), + .Xm(XManE), .Ym(YManE), .Zm(ZManE), .XZeroE, .YZeroE, .ZZeroE, + .FOpCtrlE, .FmtE, .Sm(SumE), .NegSumE, .InvA(InvAE), .FmaNormCntE, + .ZSgnEffE, .Ps(PSgnE), .Pe(ProdExpE), .AddendStickyE, .KillProdE); // fpdivsqrt using Goldschmidt's iteration if(`FLEN == 64) begin @@ -351,8 +351,8 @@ module fpu ( flopenrc #(3*`NF+6) EMRegFma2(clk, reset, FlushM, ~StallM, SumE, SumM); flopenrc #(`NE+2) EMRegFma3(clk, reset, FlushM, ~StallM, ProdExpE, ProdExpM); flopenrc #($clog2(3*`NF+7)+6) EMRegFma4(clk, reset, FlushM, ~StallM, - {AddendStickyE, KillProdE, InvZE, FmaNormCntE, NegSumE, ZSgnEffE, PSgnE}, - {AddendStickyM, KillProdM, InvZM, FmaNormCntM, NegSumM, ZSgnEffM, PSgnM}); + {AddendStickyE, KillProdE, InvAE, FmaNormCntE, NegSumE, ZSgnEffE, PSgnE}, + {AddendStickyM, KillProdM, InvAM, FmaNormCntM, NegSumM, ZSgnEffM, PSgnM}); flopenrc #(`NE+`LOGCVTLEN+`CVTLEN+4) EMRegCvt(clk, reset, FlushM, ~StallM, {CvtCalcExpE, CvtShiftAmtE, CvtResDenormUfE, CvtResSgnE, IntZeroE, CvtLzcInE}, {CvtCalcExpM, CvtShiftAmtM, CvtResDenormUfM, CvtResSgnM, IntZeroM, CvtLzcInM}); @@ -374,7 +374,7 @@ module fpu ( postprocess postprocess(.XSgnM, .YSgnM, .ZExpM, .XManM, .YManM, .ZManM, .FrmM, .FmtM, .ProdExpM, .EarlyTermShiftDiv2M, .AddendStickyM, .KillProdM, .XZeroM, .YZeroM, .ZZeroM, .XInfM, .YInfM, .Quot, .ZInfM, .XNaNM, .YNaNM, .ZNaNM, .XSNaNM, .YSNaNM, .ZSNaNM, .SumM, .DivCalcExpM, - .NegSumM, .InvZM, .ZDenormM, .ZSgnEffM, .PSgnM, .FOpCtrlM, .FmaNormCntM, .DivNegStickyM, + .NegSumM, .InvZM(InvAM), .ZDenormM, .ZSgnEffM, .PSgnM, .FOpCtrlM, .FmaNormCntM, .DivNegStickyM, .CvtCalcExpM, .CvtResDenormUfM,.CvtShiftAmtM, .CvtResSgnM, .FWriteIntM, .DivStickyM, .CvtLzcInM, .IntZeroM, .PostProcSelM, .PostProcResM, .PostProcFlgM, .FCvtIntResM); diff --git a/pipelined/src/fpu/postprocess.sv b/pipelined/src/fpu/postprocess.sv index 20cea2b6..c81a896e 100644 --- a/pipelined/src/fpu/postprocess.sv +++ b/pipelined/src/fpu/postprocess.sv @@ -109,6 +109,7 @@ module postprocess( // conversion signals logic [`CVTLEN+`NF:0] CvtShiftIn; // number to be shifted logic [1:0] NegResMSBS; + logic [`XLEN+1:0] NegRes; logic CvtResUf; // readability signals logic Mult; // multiply opperation @@ -166,7 +167,7 @@ module postprocess( ShiftAmt = {{$clog2(`NORMSHIFTSZ)-$clog2(`CVTLEN+1){1'b0}}, CvtShiftAmtM}; ShiftIn = {CvtShiftIn, {`NORMSHIFTSZ-`CVTLEN-`NF-1{1'b0}}}; end - 2'b01: begin //div ***prob can take out + 2'b01: begin //div ShiftAmt = DivShiftAmt; ShiftIn = DivShiftIn; end @@ -201,9 +202,11 @@ module postprocess( // Sign calculation /////////////////////////////////////////////////////////////////////////////// - resultsign resultsign(.FrmM, .PSgnM, .ZSgnEffM, .InvZM, .SumExp, .Round, .Sticky, - .FmaOp, .DivOp, .CvtOp, .ZInfM, .InfIn, .NegSumM, .SumZero, .Mult, - .XSgnM, .YSgnM, .CvtResSgnM, .RoundSgn, .ResSgn); + resultsign resultsign(.FrmM, .PSgnM, .ZSgnEffM, .SumExp, .Round, .Sticky, + .FmaOp, .ZInfM, .InfIn, .SumZero, .Mult, .RoundSgn, .ResSgn); + + roundsign roundsign(.PSgnM, .ZSgnEffM, .InvZM, .FmaOp, .DivOp, .CvtOp, .NegSumM, + .XSgnM, .YSgnM, .CvtResSgnM, .RoundSgn); /////////////////////////////////////////////////////////////////////////////// // Flags @@ -219,10 +222,11 @@ module postprocess( // Select the result /////////////////////////////////////////////////////////////////////////////// - resultselect resultselect(.XSgnM, .ZExpM, .XManM, .YManM, .ZManM, .ZDenormM, .ZZeroM, .XZeroM, .IntInvalid, - .IntZeroM, .FrmM, .OutFmt, .AddendStickyM, .KillProdM, .XNaNM, .YNaNM, .ZNaNM, .RoundAdd, .CvtResUf, - .NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .NegResMSBS, + negateintres negateintres(.XSgnM, .Shifted, .Signed, .Int64, .Plus1, .NegResMSBS, .NegRes); + resultselect resultselect(.XSgnM, .XManM, .YManM, .ZManM, .XZeroM, .IntInvalid, + .IntZeroM, .FrmM, .OutFmt, .XNaNM, .YNaNM, .ZNaNM, .CvtResUf, + .NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .NegRes, .XInfM, .YInfM, .DivOp, - .DivByZero, .FullResExp, .Shifted, .CvtCalcExpM, .ResSgn, .ResExp, .ResFrac, .PostProcResM, .FCvtIntResM); + .DivByZero, .FullResExp, .CvtCalcExpM, .ResSgn, .ResExp, .ResFrac, .PostProcResM, .FCvtIntResM); endmodule diff --git a/pipelined/src/fpu/resultselect.sv b/pipelined/src/fpu/resultselect.sv index 50ef1b6b..b87c9548 100644 --- a/pipelined/src/fpu/resultselect.sv +++ b/pipelined/src/fpu/resultselect.sv @@ -1,45 +1,38 @@ `include "wally-config.vh" module resultselect( - input logic XSgnM, // input signs - input logic [`NE-1:0] ZExpM, // input exponents - input logic [`NF:0] XManM, YManM, ZManM, // input mantissas - input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN - input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude - input logic [`FMTBITS-1:0] OutFmt, // output format - input logic InfIn, - input logic XInfM, YInfM, - input logic XZeroM, ZZeroM, - input logic IntZeroM, - input logic NaNIn, - input logic IntToFp, - input logic Int64, - input logic Signed, - input logic CvtOp, - input logic DivOp, - input logic FmaOp, - input logic [`NORMSHIFTSZ-1:0] Shifted, // is the sum zero - input logic Plus1, - input logic DivByZero, - input logic [`NE:0] CvtCalcExpM, // the calculated expoent - input logic AddendStickyM, // sticky bit that is calculated during alignment - input logic KillProdM, // set the product to zero before addition if the product is too small to matter - input logic ZDenormM, // is the original precision denormalized - input logic ResSgn, // the res's sign - input logic [`FLEN:0] RoundAdd, // how much to add to the res - input logic IntInvalid, Invalid, Overflow, // flags - input logic CvtResUf, - input logic [`NE-1:0] ResExp, // Res exponent - input logic [`NE+1:0] FullResExp, // Res exponent - input logic [`NF-1:0] ResFrac, // Res fraction - output logic [`FLEN-1:0] PostProcResM, // final res - output logic [1:0] NegResMSBS, - output logic [`XLEN-1:0] FCvtIntResM // final res + input logic XSgnM, // input signs + input logic [`NF:0] XManM, YManM, ZManM, // input mantissas + input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN + input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude + input logic [`FMTBITS-1:0] OutFmt, // output format + input logic InfIn, + input logic XInfM, YInfM, + input logic XZeroM, + input logic IntZeroM, + input logic NaNIn, + input logic IntToFp, + input logic Int64, + input logic Signed, + input logic CvtOp, + input logic DivOp, + input logic FmaOp, + input logic Plus1, + input logic DivByZero, + input logic [`NE:0] CvtCalcExpM, // the calculated expoent + input logic ResSgn, // the res's sign + input logic IntInvalid, Invalid, Overflow, // flags + input logic CvtResUf, + input logic [`NE-1:0] ResExp, // Res exponent + input logic [`NE+1:0] FullResExp, // Res exponent + input logic [`NF-1:0] ResFrac, // Res fraction + input logic [`XLEN+1:0] NegRes, // the negation of the result + output logic [`FLEN-1:0] PostProcResM, // final res + output logic [`XLEN-1:0] FCvtIntResM // final res ); logic [`FLEN-1:0] XNaNRes, YNaNRes, ZNaNRes, InvalidRes, OfRes, UfRes, NormRes; // possible results logic OfResMax; logic [`XLEN-1:0] OfIntRes; // the overflow result for integer output - logic [`XLEN+1:0] NegRes; // the negation of the result logic KillRes; logic SelOfRes; @@ -254,13 +247,7 @@ module resultselect( Int64 ? {1'b0, {`XLEN-1{1'b1}}} : {{`XLEN-32{1'b0}}, 1'b0, {31{1'b1}}} : // signed positive XSgnM&~XNaNM ? {`XLEN{1'b0}} : // unsigned negitive {`XLEN{1'b1}};// unsigned positive - - // round and negate the positive res if needed - assign NegRes = XSgnM ? -({2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1}) : {2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1}; - - //*** false critical path probably - assign NegResMSBS = Signed ? Int64 ? NegRes[`XLEN:`XLEN-1] : NegRes[32:31] : - Int64 ? NegRes[`XLEN+1:`XLEN] : NegRes[33:32]; + // select the integer output // - if the input is invalid (out of bounds NaN or Inf) then output overflow res diff --git a/pipelined/src/fpu/resultsign.sv b/pipelined/src/fpu/resultsign.sv index 9a76cf8f..fe085d46 100644 --- a/pipelined/src/fpu/resultsign.sv +++ b/pipelined/src/fpu/resultsign.sv @@ -3,31 +3,21 @@ module resultsign( input logic [2:0] FrmM, input logic PSgnM, ZSgnEffM, - input logic InvZM, - input logic XSgnM, - input logic YSgnM, input logic ZInfM, input logic InfIn, - input logic NegSumM, input logic FmaOp, - input logic DivOp, - input logic CvtOp, input logic [`NE+1:0] SumExp, input logic SumZero, input logic Mult, input logic Round, input logic Sticky, - input logic CvtResSgnM, - output logic RoundSgn, + input logic RoundSgn, output logic ResSgn ); logic ZeroSgn; logic InfSgn; - logic FmaResSgn; - logic FmaResSgnTmp; logic Underflow; - logic DivSgn; // logic ResultSgnTmp; // Determine the sign if the sum is zero @@ -42,14 +32,7 @@ module resultsign( // if p - z is the Sum negitive // if -p + z is the Sum positive // if -p - z then the Sum is negitive - assign FmaResSgnTmp = InvZM&(ZSgnEffM)&NegSumM | InvZM&PSgnM&~NegSumM | (ZSgnEffM&PSgnM); assign InfSgn = ZInfM ? ZSgnEffM : PSgnM; - assign FmaResSgn = InfIn ? InfSgn : SumZero ? ZeroSgn : FmaResSgnTmp; - - assign DivSgn = XSgnM^YSgnM; - - // Sign for rounding calulation - assign RoundSgn = (FmaResSgnTmp&FmaOp) | (CvtResSgnM&CvtOp) | (DivSgn&DivOp); - assign ResSgn = (FmaResSgn&FmaOp) | (CvtResSgnM&CvtOp) | (DivSgn&DivOp); + assign ResSgn = InfIn&FmaOp ? InfSgn : SumZero&FmaOp ? ZeroSgn : RoundSgn; endmodule \ No newline at end of file diff --git a/pipelined/testbench/testbench-fp.sv b/pipelined/testbench/testbench-fp.sv index bbe04597..1fc35525 100644 --- a/pipelined/testbench/testbench-fp.sv +++ b/pipelined/testbench/testbench-fp.sv @@ -61,15 +61,15 @@ module testbenchfp; // in-between FMA signals logic Mult; - logic [`NE+1:0] ProdExpE; + logic [`NE+1:0] Pe; logic AddendStickyE; logic KillProdE; logic [$clog2(3*`NF+7)-1:0] FmaNormCntE; - logic [3*`NF+5:0] SumE; + logic [3*`NF+5:0] Sm; logic InvZE; logic NegSumE; logic ZSgnEffE; - logic PSgnE; + logic Ps; logic DivSticky; logic DivNegSticky; logic [`NE+1:0] DivCalcExp; @@ -637,12 +637,12 @@ module testbenchfp; /////////////////////////////////////////////////////////////////////////////////////////////// // instantiate devices under test - fma fma(.XSgnE(XSgn), .YSgnE(YSgn), .ZSgnE(ZSgn), - .XExpE(XExp), .YExpE(YExp), .ZExpE(ZExp), - .XManE(XMan), .YManE(YMan), .ZManE(ZMan), + fma fma(.Xs(XSgn), .Ys(YSgn), .Zs(ZSgn), + .Xe(XExp), .Ye(YExp), .Ze(ZExp), + .Xm(XMan), .Ym(YMan), .Zm(ZMan), .XZeroE(XZero), .YZeroE(YZero), .ZZeroE(ZZero), - .FOpCtrlE(OpCtrlVal), .FmtE(ModFmt), .SumE, .NegSumE, .InvZE, .FmaNormCntE, .ZSgnEffE, .PSgnE, - .ProdExpE, .AddendStickyE, .KillProdE); + .FOpCtrlE(OpCtrlVal), .FmtE(ModFmt), .Sm, .NegSumE, .InvZE, .FmaNormCntE, .ZSgnEffE, .Ps, + .Pe, .AddendStickyE, .KillProdE); postprocess postprocess(.XSgnM(XSgn), .YSgnM(YSgn), .PostProcSelM(UnitVal[1:0]), .ZExpM(ZExp), .ZDenormM(ZDenorm), .FOpCtrlM(OpCtrlVal), .Quot, .DivCalcExpM(DivCalcExp), @@ -651,8 +651,8 @@ module testbenchfp; .XZeroM(XZero), .YZeroM(YZero), .ZZeroM(ZZero), .CvtShiftAmtM(CvtShiftAmtE), .XInfM(XInf), .YInfM(YInf), .ZInfM(ZInf), .CvtResSgnM(CvtResSgnE), .FWriteIntM(WriteIntVal), .XSNaNM(XSNaN), .YSNaNM(YSNaN), .ZSNaNM(ZSNaN), .CvtLzcInM(CvtLzcInE), .IntZeroM(IntZeroE), - .KillProdM(KillProdE), .AddendStickyM(AddendStickyE), .ProdExpM(ProdExpE), - .SumM(SumE), .NegSumM(NegSumE), .InvZM(InvZE), .FmaNormCntM(FmaNormCntE), .EarlyTermShiftDiv2M(EarlyTermShiftDiv2), .ZSgnEffM(ZSgnEffE), .PSgnM(PSgnE), .FmtM(ModFmt), .FrmM(FrmVal), + .KillProdM(KillProdE), .AddendStickyM(AddendStickyE), .ProdExpM(Pe), + .SumM(Sm), .NegSumM(NegSumE), .InvZM(InvZE), .FmaNormCntM(FmaNormCntE), .EarlyTermShiftDiv2M(EarlyTermShiftDiv2), .ZSgnEffM(ZSgnEffE), .PSgnM(Ps), .FmtM(ModFmt), .FrmM(FrmVal), .PostProcFlgM(Flg), .PostProcResM(FpRes), .FCvtIntResM(IntRes)); fcvt fcvt (.XSgnE(XSgn), .XExpE(XExp), .XManE(XMan), .ForwardedSrcAE(SrcA), .FWriteIntE(WriteIntVal),