diff --git a/pipelined/src/fpu/flags.sv b/pipelined/src/fpu/flags.sv index ff6495dd..a425ad9b 100644 --- a/pipelined/src/fpu/flags.sv +++ b/pipelined/src/fpu/flags.sv @@ -4,7 +4,7 @@ module flags( input logic XSgnM, input logic XSNaNM, YSNaNM, ZSNaNM, // inputs are signaling NaNs input logic XInfM, YInfM, ZInfM, // inputs are infinity - input logic Plus1, + input logic Plus1, input logic InfIn, // is a Inf input being used input logic XZeroM, YZeroM, // inputs are zero input logic XNaNM, YNaNM, // inputs are NaN @@ -25,7 +25,7 @@ module flags( input logic ZSgnEffM, PSgnM, // the product and modified Z signs input logic Round, UfLSBRes, Sticky, UfPlus1, // bits used to determine rounding output logic DivByZero, - output logic IntInvalid, Invalid, Overflow, Underflow, // flags used to select the res + output logic IntInvalid, Invalid, Overflow, // flags used to select the res output logic [4:0] PostProcFlgM // flags ); logic SigNaN; // is an input a signaling NaN @@ -34,6 +34,7 @@ module flags( logic IntInexact; // integer inexact flag logic FmaInvalid; // integer invalid flag logic DivInvalid; // integer invalid flag + logic Underflow; // Underflow flag logic ResExpGteMax; // is the result greater than or equal to the maximum floating point expoent logic ShiftGtIntSz; // is the shift greater than the the integer size (use ResExp to account for possible roundning "shift") diff --git a/pipelined/src/fpu/lzacorrection.sv b/pipelined/src/fpu/lzacorrection.sv index e5a2d5c3..a7a8143e 100644 --- a/pipelined/src/fpu/lzacorrection.sv +++ b/pipelined/src/fpu/lzacorrection.sv @@ -1,24 +1,24 @@ `include "wally-config.vh" module lzacorrection( - input logic [`NORMSHIFTSZ-1:0] Shifted, // the shifted sum before LZA correction - input logic FmaOp, - input logic DivOp, - input logic DivResDenorm, - input logic [`NE+1:0] DivCalcExpM, - input logic [`NE+1:0] DivDenormShift, - input logic [`NE+1:0] ConvNormSumExp, // exponent of the normalized sum not taking into account denormal or zero results - input logic PreResultDenorm, // is the result denormalized - calculated before LZA corection - input logic KillProdM, // is the product set to zero - input logic SumZero, - output logic [`CORRSHIFTSZ-1:0] CorrShifted, // the shifted sum before LZA correction - output logic [`NE+1:0] CorrDivExp, - output logic [`NE+1:0] SumExp // exponent of the normalized sum + input logic [`NORMSHIFTSZ-1:0] Shifted, // the shifted sum before LZA correction + input logic FmaOp, + input logic DivOp, + input logic DivResDenorm, + input logic [`NE+1:0] DivCalcExpM, + input logic [`NE+1:0] DivDenormShift, + input logic [`NE+1:0] ConvNormSumExp, // exponent of the normalized sum not taking into account denormal or zero results + input logic PreResultDenorm, // is the result denormalized - calculated before LZA corection + input logic KillProdM, // is the product set to zero + input logic SumZero, + output logic [`CORRSHIFTSZ-1:0] CorrShifted, // the shifted sum before LZA correction + output logic [`NE+1:0] CorrDivExp, + output logic [`NE+1:0] SumExp // exponent of the normalized sum ); - logic [3*`NF+5:0] CorrSumShifted; // the shifted sum after LZA correction - logic [`CORRSHIFTSZ:0] CorrQuotShifted; - logic ResDenorm; // is the result denormalized - logic LZAPlus1, LZAPlus2; // add one or two to the sum's exponent due to LZA correction + logic [3*`NF+5:0] CorrSumShifted; // the shifted sum after LZA correction + logic [`CORRSHIFTSZ:0] CorrQuotShifted; + logic ResDenorm; // is the result denormalized + logic LZAPlus1, LZAPlus2; // add one or two to the sum's exponent due to LZA correction // LZA correction assign LZAPlus1 = Shifted[`NORMSHIFTSZ-2]; diff --git a/pipelined/src/fpu/postprocess.sv b/pipelined/src/fpu/postprocess.sv index ab06a940..20cea2b6 100644 --- a/pipelined/src/fpu/postprocess.sv +++ b/pipelined/src/fpu/postprocess.sv @@ -30,101 +30,109 @@ `include "wally-config.vh" module postprocess( + // general signals input logic XSgnM, YSgnM, // input signs - input logic [`NE-1:0] ZExpM, // input exponents - input logic [`NF:0] XManM, YManM, ZManM, // input mantissas - 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] FmtM, // precision 1 = double 0 = single - input logic [`NE+1:0] ProdExpM, // X exponent + Y exponent - bias - 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 [`NE-1:0] ZExpM, // input exponents + input logic [`NF:0] XManM, YManM, ZManM, // input mantissas + 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] FmtM, // precision 1 = double 0 = single + input logic [2:0] FOpCtrlM, // choose which opperation (look below for values) input logic XZeroM, YZeroM, ZZeroM, // inputs are zero input logic XInfM, YInfM, ZInfM, // inputs are infinity input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN input logic XSNaNM, YSNaNM, ZSNaNM, // inputs are signaling NaNs - input logic [3*`NF+5:0] SumM, // the positive sum + input logic ZDenormM, // is the original precision denormalized + input logic [1:0] PostProcSelM, // select result to be written to fp register + //fma signals + input logic [`NE+1:0] ProdExpM, // X exponent + Y exponent - bias + 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 [3*`NF+5:0] SumM, // the positive sum input logic NegSumM, // was the sum negitive input logic InvZM, // do you invert Z - input logic ZDenormM, // is the original precision denormalized input logic ZSgnEffM, // the modified Z sign - depends on instruction input logic PSgnM, // the product's sign - input logic [2:0] FOpCtrlM, // choose which opperation (look below for values) - input logic [$clog2(`DIVLEN/2+3)-1:0] EarlyTermShiftDiv2M, - input logic [$clog2(3*`NF+7)-1:0] FmaNormCntM, // the normalization shift count - input logic [`NE:0] CvtCalcExpM, // the calculated expoent - input logic [`NE+1:0] DivCalcExpM, // the calculated expoent - input logic CvtResDenormUfM, - input logic DivStickyM, - input logic DivNegStickyM, - input logic [`LOGCVTLEN-1:0] CvtShiftAmtM, // how much to shift by - input logic CvtResSgnM, // the result's sign - input logic FWriteIntM, // is fp->int (since it's writting to the integer register) - input logic [`CVTLEN-1:0] CvtLzcInM, // input to the Leading Zero Counter (priority encoder) - input logic IntZeroM, // is the input zero - input logic [1:0] PostProcSelM, // select result to be written to fp register - input logic [`DIVLEN+2:0] Quot, - output logic [`FLEN-1:0] PostProcResM, // FMA final result - output logic [4:0] PostProcFlgM, - output logic [`XLEN-1:0] FCvtIntResM // the int conversion result + input logic [$clog2(3*`NF+7)-1:0] FmaNormCntM, // the normalization shift count + //divide signals + input logic [$clog2(`DIVLEN/2+3)-1:0] EarlyTermShiftDiv2M, + input logic [`NE+1:0] DivCalcExpM, // the calculated expoent + input logic DivStickyM, + input logic DivNegStickyM, + input logic [`DIVLEN+2:0] Quot, + // conversion signals + input logic [`NE:0] CvtCalcExpM, // the calculated expoent + input logic CvtResDenormUfM, + input logic [`LOGCVTLEN-1:0] CvtShiftAmtM, // how much to shift by + input logic CvtResSgnM, // the result's sign + input logic FWriteIntM, // is fp->int (since it's writting to the integer register) + input logic [`CVTLEN-1:0] CvtLzcInM, // input to the Leading Zero Counter (priority encoder) + input logic IntZeroM, // is the input zero + // final results + output logic [`FLEN-1:0] PostProcResM, // FMA final result + output logic [4:0] PostProcFlgM, + output logic [`XLEN-1:0] FCvtIntResM // the int conversion result ); - - - logic [`NF-1:0] ResFrac; // Result fraction - logic [`NE-1:0] ResExp; // Result exponent - logic [`CORRSHIFTSZ-1:0] CorrShifted; // the shifted sum before LZA correction - logic [`NE+1:0] SumExp; // exponent of the normalized sum - logic [`NE+1:0] FullResExp; // ResExp with bits to determine sign and overflow - logic SumZero; // is the sum zero - logic Sticky; // Sticky bit - logic [3*`NF+8:0] FmaShiftIn; // is the sum zero - logic UfPlus1; // do you add one (for determining underflow flag) - logic Round; // bits needed to determine rounding - logic [`CVTLEN+`NF:0] CvtShiftIn; // number to be shifted - logic Mult; // multiply opperation - logic [`FLEN:0] RoundAdd; // how much to add to the result - logic [`NE+1:0] ConvNormSumExp; // exponent of the normalized sum not taking into account denormal or zero results - logic PreResultDenorm; // is the result denormalized - calculated before LZA corection - logic [$clog2(3*`NF+7)-1:0] FmaShiftAmt; // normalization shift count - logic [$clog2(`NORMSHIFTSZ)-1:0] ShiftAmt; // normalization shift count - logic [$clog2(`NORMSHIFTSZ)-1:0] DivShiftAmt; - logic [`NORMSHIFTSZ-1:0] ShiftIn; // is the sum zero - logic [`NORMSHIFTSZ-1:0] DivShiftIn; - logic [`NORMSHIFTSZ-1:0] Shifted; // the shifted result - logic Plus1; // add one to the final result? - logic IntInvalid, Overflow, Underflow, Invalid; // flags - logic Signed; // is the opperation with a signed integer? - logic Int64; // is the integer 64 bits? - logic IntToFp; // is the opperation an int->fp conversion? - logic ToInt; // is the opperation an fp->int conversion? + // general signals + logic [`NF-1:0] ResFrac; // Result fraction + logic [`NE-1:0] ResExp; // Result exponent + logic [`CORRSHIFTSZ-1:0] CorrShifted; // corectly shifted fraction + logic [`NE+1:0] FullResExp; // ResExp with bits to determine sign and overflow + logic Sticky; // Sticky bit + logic UfPlus1; // do you add one (for determining underflow flag) + logic Round; // bits needed to determine rounding + logic [`FLEN:0] RoundAdd; // how much to add to the result + logic [$clog2(`NORMSHIFTSZ)-1:0] ShiftAmt; // normalization shift count + logic [`NORMSHIFTSZ-1:0] ShiftIn; // is the sum zero + logic [`NORMSHIFTSZ-1:0] Shifted; // the shifted result + logic Plus1; // add one to the final result? + logic IntInvalid, Overflow, Invalid; // flags logic [`NE+1:0] RoundExp; - logic [`NE+1:0] CorrDivExp; - logic [1:0] NegResMSBS; - logic CvtOp; - logic FmaOp; - logic CvtResUf; - logic DivOp; - logic InfIn; logic ResSgn; logic RoundSgn; - logic NaNIn; - logic DivByZero; logic UfLSBRes; - logic Sqrt; logic [`FMTBITS-1:0] OutFmt; + // fma signals + logic [`NE+1:0] SumExp; // exponent of the normalized sum + logic SumZero; // is the sum zero + logic [3*`NF+8:0] FmaShiftIn; // is the sum zero + logic [`NE+1:0] ConvNormSumExp; // exponent of the normalized sum not taking into account denormal or zero results + logic PreResultDenorm; // is the result denormalized - calculated before LZA corection + logic [$clog2(3*`NF+7)-1:0] FmaShiftAmt; // normalization shift count + // division singals + logic [$clog2(`NORMSHIFTSZ)-1:0] DivShiftAmt; + logic [`NORMSHIFTSZ-1:0] DivShiftIn; + logic [`NE+1:0] CorrDivExp; + logic DivByZero; logic DivResDenorm; logic [`NE+1:0] DivDenormShift; + // conversion signals + logic [`CVTLEN+`NF:0] CvtShiftIn; // number to be shifted + logic [1:0] NegResMSBS; + logic CvtResUf; + // readability signals + logic Mult; // multiply opperation + logic Int64; // is the integer 64 bits? + logic Signed; // is the opperation with a signed integer? + logic IntToFp; // is the opperation an int->fp conversion? + logic ToInt; // is the opperation an fp->int conversion? + logic CvtOp; + logic FmaOp; + logic DivOp; + logic InfIn; + logic NaNIn; + logic Sqrt; // signals to help readability - assign Signed = FOpCtrlM[0]; - assign Int64 = FOpCtrlM[1]; - assign IntToFp = FOpCtrlM[2]; - assign ToInt = FWriteIntM; + assign Signed = FOpCtrlM[0]; + assign Int64 = FOpCtrlM[1]; + assign IntToFp = FOpCtrlM[2]; + assign ToInt = FWriteIntM; assign Mult = FOpCtrlM[2]&~FOpCtrlM[1]&~FOpCtrlM[0]; assign CvtOp = (PostProcSelM == 2'b00); assign FmaOp = (PostProcSelM == 2'b10); assign DivOp = (PostProcSelM == 2'b01); - assign Sqrt = FOpCtrlM[0]; + assign Sqrt = FOpCtrlM[0]; // is there an input of infinity or NaN being used assign InfIn = (XInfM&~(IntToFp&CvtOp))|(YInfM&~CvtOp)|(ZInfM&FmaOp); @@ -205,7 +213,7 @@ module postprocess( .XSgnM, .Sqrt, .ToInt, .IntToFp, .Int64, .Signed, .OutFmt, .CvtCalcExpM, .XNaNM, .YNaNM, .NaNIn, .ZSgnEffM, .PSgnM, .Round, .IntInvalid, .DivByZero, .UfLSBRes, .Sticky, .UfPlus1, .CvtOp, .DivOp, .FmaOp, .FullResExp, .Plus1, - .RoundExp, .NegResMSBS, .Invalid, .Overflow, .Underflow, .PostProcFlgM); + .RoundExp, .NegResMSBS, .Invalid, .Overflow, .PostProcFlgM); /////////////////////////////////////////////////////////////////////////////// // Select the result diff --git a/pipelined/src/fpu/resultselect.sv b/pipelined/src/fpu/resultselect.sv index d6d15e46..50ef1b6b 100644 --- a/pipelined/src/fpu/resultselect.sv +++ b/pipelined/src/fpu/resultselect.sv @@ -4,29 +4,27 @@ 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, - input logic YInfM, - input logic DivOp, - input logic XZeroM, + 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 [`NORMSHIFTSZ-1:0] Shifted, // is the sum zero + 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 XNaNM, YNaNM, ZNaNM, // inputs are NaN input logic ZDenormM, // is the original precision denormalized - input logic ZZeroM, 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 diff --git a/pipelined/src/fpu/round.sv b/pipelined/src/fpu/round.sv index 7d415311..532e1729 100644 --- a/pipelined/src/fpu/round.sv +++ b/pipelined/src/fpu/round.sv @@ -8,42 +8,42 @@ `define XLENPOS ((`XLEN>`NF) ? 1 : (`XLEN>`NF1) ? 2 : 3) module round( - input logic [`FMTBITS-1:0] OutFmt, // precision 1 = double 0 = single - input logic [2:0] FrmM, // rounding mode - input logic FmaOp, - input logic DivOp, - input logic [1:0] PostProcSelM, - input logic CvtResDenormUfM, - input logic ToInt, - input logic CvtOp, - input logic CvtResUf, - input logic [`CORRSHIFTSZ-1:0] CorrShifted, - input logic AddendStickyM, // addend's sticky bit - input logic ZZeroM, // is Z zero - input logic InvZM, // invert Z - input logic [`NE+1:0] SumExp, // exponent of the normalized sum - input logic RoundSgn, // the result's sign - input logic [`NE:0] CvtCalcExpM, // the calculated expoent - input logic [`NE+1:0] CorrDivExp, // the calculated expoent - input logic DivStickyM, // sticky bit - input logic DivNegStickyM, - output logic UfPlus1, // do you add or subtract on from the result - output logic [`NE+1:0] FullResExp, // ResExp with bits to determine sign and overflow - output logic [`NF-1:0] ResFrac, // Result fraction - output logic [`NE-1:0] ResExp, // Result exponent - output logic Sticky, // sticky bit - output logic [`NE+1:0] RoundExp, - output logic Plus1, - output logic [`FLEN:0] RoundAdd, // how much to add to the result - output logic Round, UfLSBRes // bits needed to calculate rounding + input logic [`FMTBITS-1:0] OutFmt, // precision 1 = double 0 = single + input logic [2:0] FrmM, // rounding mode + input logic FmaOp, + input logic DivOp, + input logic CvtOp, + input logic ToInt, + input logic [1:0] PostProcSelM, + input logic CvtResDenormUfM, + input logic CvtResUf, + input logic [`CORRSHIFTSZ-1:0] CorrShifted, + input logic AddendStickyM, // addend's sticky bit + input logic ZZeroM, // is Z zero + input logic InvZM, // invert Z + input logic [`NE+1:0] SumExp, // exponent of the normalized sum + input logic RoundSgn, // the result's sign + input logic [`NE:0] CvtCalcExpM, // the calculated expoent + input logic [`NE+1:0] CorrDivExp, // the calculated expoent + input logic DivStickyM, // sticky bit + input logic DivNegStickyM, + output logic UfPlus1, // do you add or subtract on from the result + output logic [`NE+1:0] FullResExp, // ResExp with bits to determine sign and overflow + output logic [`NF-1:0] ResFrac, // Result fraction + output logic [`NE-1:0] ResExp, // Result exponent + output logic Sticky, // sticky bit + output logic [`NE+1:0] RoundExp, + output logic Plus1, + output logic [`FLEN:0] RoundAdd, // how much to add to the result + output logic Round, UfLSBRes // bits needed to calculate rounding ); logic LSBRes; // bit used for rounding - least significant bit of the normalized sum logic SubBySmallNum, UfSubBySmallNum; // was there supposed to be a subtraction by a small number logic UfCalcPlus1, CalcMinus1, Minus1; // do you add or subtract on from the result - logic NormSumSticky; // normalized sum's sticky bit - logic UfSticky; // sticky bit for underlow calculation + logic NormSumSticky; // normalized sum's sticky bit + logic UfSticky; // sticky bit for underlow calculation logic [`NF-1:0] RoundFrac; - logic FpRes, IntRes; + logic FpRes, IntRes; logic UfRound; logic FpRound, FpLSBRes, FpUfRound; logic CalcPlus1, FpPlus1;