Divsqrt cleanup: change Q to U, commenting code

This commit is contained in:
David Harris 2023-11-10 11:21:02 -08:00
parent 953c53d065
commit 255873a50c
10 changed files with 74 additions and 61 deletions

View File

@ -45,8 +45,8 @@ module fdivsqrt import cvw::*; #(parameter cvw_t P) (
input logic IntDivE, W64E,
output logic DivStickyM,
output logic FDivBusyE, IFDivStartE, FDivDoneE,
output logic [P.NE+1:0] QeM,
output logic [P.DIVb:0] QmM,
output logic [P.NE+1:0] UeM, // Exponent result
output logic [P.DIVb:0] UmM, // Significand result
output logic [P.XLEN-1:0] FIntDivResultM
);
@ -74,7 +74,7 @@ module fdivsqrt import cvw::*; #(parameter cvw_t P) (
fdivsqrtpreproc #(P) fdivsqrtpreproc( // Preprocessor
.clk, .IFDivStartE, .Xm(XmE), .Ym(YmE), .Xe(XeE), .Ye(YeE),
.FmtE, .SqrtE, .XZeroE, .Funct3E, .QeM, .X, .D, .CyclesE,
.FmtE, .SqrtE, .XZeroE, .Funct3E, .UeM, .X, .D, .CyclesE,
// Int-specific
.ForwardedSrcAE, .ForwardedSrcBE, .IntDivE, .W64E, .ISpecialCaseE,
.BZeroM, .nM, .mM, .AM,
@ -94,7 +94,7 @@ module fdivsqrt import cvw::*; #(parameter cvw_t P) (
fdivsqrtpostproc #(P) fdivsqrtpostproc( // Postprocessor
.clk, .reset, .StallM, .WS, .WC, .D, .FirstU, .FirstUM, .FirstC,
.SqrtE, .Firstun, .SqrtM, .SpecialCaseM,
.QmM, .WZeroE, .DivStickyM,
.UmM, .WZeroE, .DivStickyM,
// Int-specific
.nM, .mM, .ALTBM, .AsM, .BsM, .BZeroM, .W64M, .RemOpM(Funct3M[1]), .AM,
.FIntDivResultM);

View File

@ -68,7 +68,7 @@ module fdivsqrtcycles import cvw::*; #(parameter cvw_t P) (
if (SqrtE) fbits = Nf + 2 + 1; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2 *** unclear why it works with just +1; is it related to DIVCOPIES logic below?
// if (SqrtE) fbits = Nf + 2 + 2; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2
else fbits = Nf + 2 + P.LOGR; // Nf + two fractional bits for round/guard + integer bits - try this when placing results in msbs
if (P.IDIV_ON_FPU) CyclesE = IntDivE ? ((nE + 1)/P.DIVCOPIES) : (fbits + (P.LOGR*P.DIVCOPIES)-1)/(P.LOGR*P.DIVCOPIES);
if (P.IDIV_ON_FPU) CyclesE = IntDivE ? ((nE + 1)/P.DIVCOPIES) : (fbits -1)/(P.RK) + 1;
else CyclesE = (fbits + (P.LOGR*P.DIVCOPIES)-1)/(P.LOGR*P.DIVCOPIES);
end
/* verilator lint_on WIDTH */

View File

@ -32,8 +32,9 @@ module fdivsqrtexpcalc import cvw::*; #(parameter cvw_t P) (
input logic Sqrt,
input logic XZero,
input logic [P.DIVBLEN:0] ell, m,
output logic [P.NE+1:0] Qe
output logic [P.NE+1:0] Ue
);
logic [P.NE-2:0] Bias;
logic [P.NE+1:0] SXExp;
logic [P.NE+1:0] SExp;
@ -63,10 +64,14 @@ module fdivsqrtexpcalc import cvw::*; #(parameter cvw_t P) (
2'h2: Bias = (P.NE-1)'(P.H_BIAS);
endcase
end
// Square root exponent = (Xe - l - bias) / 2 + bias; l accounts for subnorms
assign SXExp = {2'b0, Xe} - {{(P.NE+1-P.DIVBLEN){1'b0}}, ell} - (P.NE+2)'(P.BIAS);
assign SExp = {SXExp[P.NE+1], SXExp[P.NE+1:1]} + {2'b0, Bias};
// correct exponent for subnormal input's normalization shifts
// division exponent = (Xe-l) - (Ye-m) + bias; l and m account for subnorms
assign DExp = ({2'b0, Xe} - {{(P.NE+1-P.DIVBLEN){1'b0}}, ell} - {2'b0, Ye} + {{(P.NE+1-P.DIVBLEN){1'b0}}, m} + {3'b0, Bias});
assign Qe = Sqrt ? SExp : DExp;
// Select square root or division exponent
assign Ue = Sqrt ? SExp : DExp;
endmodule

View File

@ -38,14 +38,14 @@ module fdivsqrtpostproc import cvw::*; #(parameter cvw_t P) (
input logic [P.XLEN-1:0] AM,
input logic RemOpM, ALTBM, BZeroM, AsM, BsM, W64M,
input logic [P.DIVBLEN:0] nM, mM,
output logic [P.DIVb:0] QmM,
output logic [P.DIVb:0] UmM, // result significand
output logic WZeroE,
output logic DivStickyM,
output logic [P.XLEN-1:0] FIntDivResultM
);
logic [P.DIVb+3:0] W, Sum;
logic [P.DIVb:0] PreQmM;
logic [P.DIVb:0] PreUmM;
logic NegStickyM;
logic weq0E, WZeroM;
logic [P.XLEN-1:0] IntDivResultM;
@ -91,17 +91,17 @@ module fdivsqrtpostproc import cvw::*; #(parameter cvw_t P) (
// Determine if sticky bit is negative // *** look for ways to optimize this. Shift shouldn't be needed.
assign Sum = WC + WS;
assign NegStickyM = Sum[P.DIVb+3];
mux2 #(P.DIVb+1) preqmmux(FirstU, FirstUM, NegStickyM, PreQmM); // Select U or U-1 depending on negative sticky bit
mux2 #(P.DIVb+1) qmmux(PreQmM, (PreQmM << 1), SqrtM, QmM);
mux2 #(P.DIVb+1) preummux(FirstU, FirstUM, NegStickyM, PreUmM); // Select U or U-1 depending on negative sticky bit
mux2 #(P.DIVb+1) ummux(PreUmM, (PreUmM << 1), SqrtM, UmM);
// Integer quotient or remainder correctoin, normalization, and special cases
// Integer quotient or remainder correction, normalization, and special cases
if (P.IDIV_ON_FPU) begin:intpostproc // Int supported
logic [P.DIVBLEN:0] NormShiftM;
logic [P.DIVb+3:0] UnsignedQuotM, NormRemM, NormRemDM, NormQuotM;
logic signed [P.DIVb+3:0] PreResultM, PreIntResultM;
assign W = $signed(Sum) >>> P.LOGR;
assign UnsignedQuotM = {3'b000, PreQmM};
assign UnsignedQuotM = {3'b000, PreUmM};
// Integer remainder: sticky and sign correction muxes
assign NegQuotM = AsM ^ BsM; // Integer Quotient is negative

View File

@ -35,7 +35,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
input logic SqrtE,
input logic XZeroE,
input logic [2:0] Funct3E,
output logic [P.NE+1:0] QeM,
output logic [P.NE+1:0] UeM,
output logic [P.DIVb+3:0] X, D,
// Int-specific
input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
@ -48,10 +48,10 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
output logic [P.XLEN-1:0] AM
);
logic [P.DIVb:0] Xfract, Dfract;
logic [P.DIVb:0] Xnorm, Dnorm;
logic [P.DIVb:0] PreSqrtX;
logic [P.DIVb+3:0] DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed
logic [P.NE+1:0] QeE; // Quotient Exponent (FP only)
logic [P.NE+1:0] UeE; // Result Exponent (FP only)
logic [P.DIVb:0] IFX, IFD; // Correctly-sized inputs for iterator, selected from int or fp input
logic [P.DIVBLEN:0] mE, nE, ell; // Leading zeros of inputs
logic NumerZeroE; // Numerator is zero (X or A)
@ -106,9 +106,9 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
lzc #(P.DIVb+1) lzcX (IFX, ell);
lzc #(P.DIVb+1) lzcY (IFD, mE);
// Normalization shift: shift off leading one
assign Xfract = (IFX << ell);
assign Dfract = (IFD << mE);
// Normalization shift: shift leading one into most significant bit
assign Xnorm = (IFX << ell);
assign Dnorm = (IFD << mE);
//////////////////////////////////////////////////////
// Integer Right Shift to digit boundary
@ -133,10 +133,11 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
logic [P.LOGRK-1:0] IntTrunc, RightShiftX;
logic [P.DIVBLEN:0] TotalIntBits, IntSteps;
/* verilator lint_off WIDTH */
// n = k*ceil((r+p)/rk) - 1
assign TotalIntBits = P.LOGR + p; // Total number of result bits (r integer bits plus p fractional bits)
assign IntTrunc = TotalIntBits % P.RK; // Truncation check for ceiling operator
assign IntSteps = (TotalIntBits >> P.LOGRK) + |IntTrunc; // Number of steps for int div
assign nE = (IntSteps * P.DIVCOPIES) - 1; // Fractional digits
assign nE = (IntSteps * P.DIVCOPIES) - 1; // Fractional digits = total digits - 1 integer digit
assign RightShiftX = P.RK - 1 - ((TotalIntBits - 1) % P.RK); // Right shift amount
assign DivXShifted = DivX >> RightShiftX; // shift X by up to R*K-1 to complete in nE steps
/* verilator lint_on WIDTH */
@ -150,18 +151,25 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
//////////////////////////////////////////////////////
// Floating-Point Preprocessing
// append leading 1 (for nonzero inputs)
// Extend to Q4.b format
// shift square root to be in range [1/4, 1)
// Normalized numbers are shifted right by 1 if the exponent is odd
// Subnormal numbers have Xe = 0 and an unbiased exponent of 1-BIAS. They are shifted right if the number of leading zeros is odd.
// NOTE: there might be a discrepancy that X is never right shifted by 2. However
// it comes out in the wash and gives the right answer. Investigate later if possible.
// it comes out in the wash and gives the right answer. Investigate later if possible. ***
//////////////////////////////////////////////////////
assign DivX = {3'b000, Xfract};
assign DivX = {3'b000, Xnorm}; // Zero-extend numerator for division
// Sqrt is initialized on step one as R(X-1), so depends on Radix
mux2 #(P.DIVb+1) sqrtxmux(Xfract, {1'b0, Xfract[P.DIVb:1]}, (Xe[0] ^ ell[0]), PreSqrtX);
// If X = 0, then special case logic sets sqrt = 0 so this portion doesn't matter
// Otherwise, X has a leading 1 after possible normalization shift and is now in range [1, 2)
// Next X is shifted right by 1 or 2 bits to range [1/4, 1) and exponent will be adjusted accordingly to be even
// Now (X-1) is negative. Formed by placing all 1s in all four integer bits (in Q4.b) form, keeping X in fraciton bits
// Then multiply by R is left shift by r (1 or 2 for radix 2 or 4)
// For Radix 2, this gives 3 leading 1s, followed by the fraction bits
// For Radix 4, this gives 2 leading 1s, followed by the fraction bits (and a zero in the lsb)
mux2 #(P.DIVb+1) sqrtxmux(Xnorm, {1'b0, Xnorm[P.DIVb:1]}, (Xe[0] ^ ell[0]), PreSqrtX);
if (P.RADIX == 2) assign SqrtX = {3'b111, PreSqrtX};
else assign SqrtX = {2'b11, PreSqrtX, 1'b0};
mux2 #(P.DIVb+4) prexmux(DivX, SqrtX, SqrtE, PreShiftX);
@ -177,11 +185,11 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
end
// Divisior register
flopen #(P.DIVb+4) dreg(clk, IFDivStartE, {3'b000, Dfract}, D);
flopen #(P.DIVb+4) dreg(clk, IFDivStartE, {3'b000, Dnorm}, D);
// Floating-point exponent
fdivsqrtexpcalc #(P) expcalc(.Fmt(FmtE), .Xe, .Ye, .Sqrt(SqrtE), .XZero(XZeroE), .ell, .m(mE), .Qe(QeE));
flopen #(P.NE+2) expreg(clk, IFDivStartE, QeE, QeM);
fdivsqrtexpcalc #(P) expcalc(.Fmt(FmtE), .Xe, .Ye, .Sqrt(SqrtE), .XZero(XZeroE), .ell, .m(mE), .Ue(UeE));
flopen #(P.NE+2) expreg(clk, IFDivStartE, UeE, UeM);
// Number of FSM cycles (to FSM)
fdivsqrtcycles #(P) cyclecalc(.FmtE, .SqrtE, .IntDivE, .nE, .CyclesE);

View File

@ -133,8 +133,8 @@ module fpu import cvw::*; #(parameter cvw_t P) (
logic [P.XLEN-1:0] FCvtIntResM; // fcvt integer result (for IEU)
// divide signals
logic [P.DIVb:0] QmM; // fdivsqrt signifcand
logic [P.NE+1:0] QeM; // fdivsqrt exponent
logic [P.DIVb:0] UmM; // fdivsqrt signifcand
logic [P.NE+1:0] UeM; // fdivsqrt exponent
logic DivStickyM; // fdivsqrt sticky bit
logic FDivDoneE, IFDivStartE; // fdivsqrt control signals
logic [P.XLEN-1:0] FIntDivResultM; // fdivsqrt integer division result (for IEU)
@ -242,8 +242,8 @@ module fpu import cvw::*; #(parameter cvw_t P) (
fdivsqrt #(P) fdivsqrt(.clk, .reset, .FmtE, .XmE, .YmE, .XeE, .YeE, .SqrtE(OpCtrlE[0]), .SqrtM(OpCtrlM[0]),
.XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE, .FDivStartE, .IDivStartE, .XsE,
.ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .Funct3M, .IntDivE, .W64E,
.StallM, .FlushE, .DivStickyM, .FDivBusyE, .IFDivStartE, .FDivDoneE, .QeM,
.QmM, .FIntDivResultM);
.StallM, .FlushE, .DivStickyM, .FDivBusyE, .IFDivStartE, .FDivDoneE, .UeM,
.UmM, .FIntDivResultM);
// compare: fmin/fmax, flt/fle/feq
fcmp #(P) fcmp (.Fmt(FmtE), .OpCtrl(OpCtrlE), .Xs(XsE), .Ys(YsE), .Xe(XeE), .Ye(YeE),
@ -326,9 +326,9 @@ module fpu import cvw::*; #(parameter cvw_t P) (
//////////////////////////////////////////////////////////////////////////////////////////
postprocess #(P) postprocess(.Xs(XsM), .Ys(YsM), .Xm(XmM), .Ym(YmM), .Zm(ZmM), .Frm(FrmM), .Fmt(FmtM),
.FmaASticky(FmaAStickyM), .XZero(XZeroM), .YZero(YZeroM), .XInf(XInfM), .YInf(YInfM), .DivQm(QmM), .FmaSs(SsM),
.FmaASticky(FmaAStickyM), .XZero(XZeroM), .YZero(YZeroM), .XInf(XInfM), .YInf(YInfM), .DivUm(UmM), .FmaSs(SsM),
.ZInf(ZInfM), .XNaN(XNaNM), .YNaN(YNaNM), .ZNaN(ZNaNM), .XSNaN(XSNaNM), .YSNaN(YSNaNM), .ZSNaN(ZSNaNM),
.FmaSm(SmM), .DivQe(QeM), .FmaAs(AsM), .FmaPs(PsM), .OpCtrl(OpCtrlM), .FmaSCnt(SCntM), .FmaSe(SeM),
.FmaSm(SmM), .DivUe(UeM), .FmaAs(AsM), .FmaPs(PsM), .OpCtrl(OpCtrlM), .FmaSCnt(SCntM), .FmaSe(SeM),
.CvtCe(CeM), .CvtResSubnormUf(CvtResSubnormUfM),.CvtShiftAmt(CvtShiftAmtM), .CvtCs(CsM),
.ToInt(FWriteIntM), .DivSticky(DivStickyM), .CvtLzcIn(CvtLzcInM), .IntZero(IntZeroM),
.PostProcSel(PostProcSelM), .PostProcRes(PostProcResM), .PostProcFlg(PostProcFlgM), .FCvtIntRes(FCvtIntResM));

View File

@ -27,8 +27,8 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module divshiftcalc import cvw::*; #(parameter cvw_t P) (
input logic [P.DIVb:0] DivQm, // divsqrt significand
input logic [P.NE+1:0] DivQe, // divsqrt exponent
input logic [P.DIVb:0] DivUm, // divsqrt significand
input logic [P.NE+1:0] DivUe, // divsqrt exponent
output logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt, // divsqrt shift amount
output logic [P.NORMSHIFTSZ-1:0] DivShiftIn, // divsqrt shift input
output logic DivResSubnorm, // is the divsqrt result subnormal
@ -41,23 +41,23 @@ module divshiftcalc import cvw::*; #(parameter cvw_t P) (
// is the result subnormal
// if the exponent is 1 then the result needs to be normalized then the result is Subnormalizes
assign DivResSubnorm = DivQe[P.NE+1]|(~|DivQe[P.NE+1:0]);
assign DivResSubnorm = DivUe[P.NE+1]|(~|DivUe[P.NE+1:0]);
// if the result is subnormal
// 00000000x.xxxxxx... Exp = DivQe
// .00000000xxxxxxx... >> NF+1 Exp = DivQe+NF+1
// .00xxxxxxxxxxxxx... << DivQe+NF+1 Exp = +1
// 00000000x.xxxxxx... Exp = DivUe
// .00000000xxxxxxx... >> NF+1 Exp = DivUe+NF+1
// .00xxxxxxxxxxxxx... << DivUe+NF+1 Exp = +1
// .0000xxxxxxxxxxx... >> 1 Exp = 1
// Left shift amount = DivQe+NF+1-1
assign DivSubnormShift = (P.NE+2)'(P.NF)+DivQe;
// Left shift amount = DivUe+NF+1-1
assign DivSubnormShift = (P.NE+2)'(P.NF)+DivUe;
assign DivSubnormShiftPos = ~DivSubnormShift[P.NE+1];
// if the result is normalized
// 00000000x.xxxxxx... Exp = DivQe
// .00000000xxxxxxx... >> NF+1 Exp = DivQe+NF+1
// 00000000.xxxxxxx... << NF Exp = DivQe+1
// 00000000x.xxxxxx... << NF Exp = DivQe (extra shift done afterwards)
// 00000000xx.xxxxx... << 1? Exp = DivQe-1 (determined after)
// 00000000x.xxxxxx... Exp = DivUe
// .00000000xxxxxxx... >> NF+1 Exp = DivUe+NF+1
// 00000000.xxxxxxx... << NF Exp = DivUe+1
// 00000000x.xxxxxx... << NF Exp = DivUe (extra shift done afterwards)
// 00000000xx.xxxxx... << 1? Exp = DivUe-1 (determined after)
// inital Left shift amount = NF
// shift one more if the it's a minimally redundent radix 4 - one entire cycle needed for integer bit
assign NormShift = (P.LOGNORMSHIFTSZ)'(P.NF);
@ -68,5 +68,5 @@ module divshiftcalc import cvw::*; #(parameter cvw_t P) (
assign DivShiftAmt = DivResSubnorm ? DivSubnormShiftAmt : NormShift;
// pre-shift the divider result for normalization
assign DivShiftIn = {{P.NF{1'b0}}, DivQm, {P.NORMSHIFTSZ-P.DIVb-1-P.NF{1'b0}}};
assign DivShiftIn = {{P.NF{1'b0}}, DivUm, {P.NORMSHIFTSZ-P.DIVb-1-P.NF{1'b0}}};
endmodule

View File

@ -48,8 +48,8 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
input logic [$clog2(3*P.NF+5)-1:0] FmaSCnt, // the normalization shift count
//divide signals
input logic DivSticky, // divider sticky bit
input logic [P.NE+1:0] DivQe, // divsqrt exponent
input logic [P.DIVb:0] DivQm, // divsqrt significand
input logic [P.NE+1:0] DivUe, // divsqrt exponent
input logic [P.DIVb:0] DivUm, // divsqrt significand
// conversion signals
input logic CvtCs, // the result's sign
input logic [P.NE:0] CvtCe, // the calculated expoent
@ -91,7 +91,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
// division singals
logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shif amount
logic [P.NORMSHIFTSZ-1:0] DivShiftIn; // divsqrt shift input
logic [P.NE+1:0] Qe; // divsqrt corrected exponent after corretion shift
logic [P.NE+1:0] Ue; // divsqrt corrected exponent after corretion shift
logic DivByZero; // divide by zero flag
logic DivResSubnorm; // is the divsqrt result subnormal
logic DivSubnormShiftPos; // is the divsqrt subnorm shift amout positive (not underflowed)
@ -146,7 +146,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
fmashiftcalc #(P) fmashiftcalc(.FmaSm, .FmaSCnt, .Fmt, .NormSumExp, .FmaSe,
.FmaSZero, .FmaPreResultSubnorm, .FmaShiftAmt, .FmaShiftIn);
divshiftcalc #(P) divshiftcalc(.DivQe, .DivQm, .DivResSubnorm, .DivSubnormShiftPos, .DivShiftAmt, .DivShiftIn);
divshiftcalc #(P) divshiftcalc(.DivUe, .DivUm, .DivResSubnorm, .DivSubnormShiftPos, .DivShiftAmt, .DivShiftIn);
// select which unit's output to shift
always_comb
@ -174,7 +174,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
// correct for LZA/divsqrt error
shiftcorrection #(P) shiftcorrection(.FmaOp, .FmaPreResultSubnorm, .NormSumExp,
.DivResSubnorm, .DivSubnormShiftPos, .DivOp, .DivQe, .Qe, .FmaSZero, .Shifted, .FmaMe, .Mf);
.DivResSubnorm, .DivSubnormShiftPos, .DivOp, .DivUe, .Ue, .FmaSZero, .Shifted, .FmaMe, .Mf);
///////////////////////////////////////////////////////////////////////////////
// Rounding
@ -189,7 +189,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
// calulate result sign used in rounding unit
roundsign roundsign(.FmaOp, .DivOp, .CvtOp, .Sqrt, .FmaSs, .Xs, .Ys, .CvtCs, .Ms);
round #(P) round(.OutFmt, .Frm, .FmaASticky, .Plus1, .PostProcSel, .CvtCe, .Qe,
round #(P) round(.OutFmt, .Frm, .FmaASticky, .Plus1, .PostProcSel, .CvtCe, .Ue,
.Ms, .FmaMe, .FmaOp, .CvtOp, .CvtResSubnormUf, .Mf, .ToInt, .CvtResUf,
.DivSticky, .DivOp, .UfPlus1, .FullRe, .Rf, .Re, .Sticky, .Round, .Guard, .Me);

View File

@ -39,7 +39,7 @@ module round import cvw::*; #(parameter cvw_t P) (
// divsqrt
input logic DivOp, // is a division opperation being done
input logic DivSticky, // divsqrt sticky bit
input logic [P.NE+1:0] Qe, // the divsqrt calculated expoent
input logic [P.NE+1:0] Ue, // the divsqrt calculated expoent
// cvt
input logic CvtOp, // is a convert opperation being done
input logic ToInt, // is the cvt op a cvt to integer
@ -300,8 +300,8 @@ module round import cvw::*; #(parameter cvw_t P) (
case(PostProcSel)
2'b10: Me = FmaMe; // fma
2'b00: Me = {CvtCe[P.NE], CvtCe}&{P.NE+2{~CvtResSubnormUf|CvtResUf}}; // cvt
// 2'b01: Me = DivDone ? Qe : '0; // divide
2'b01: Me = Qe; // divide
// 2'b01: Me = DivDone ? Ue : '0; // divide
2'b01: Me = Ue; // divide
default: Me = '0;
endcase

View File

@ -31,7 +31,7 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
// divsqrt
input logic DivOp, // is it a divsqrt opperation
input logic DivResSubnorm, // is the divsqrt result subnormal
input logic [P.NE+1:0] DivQe, // the divsqrt result's exponent
input logic [P.NE+1:0] DivUe, // the divsqrt result's exponent
input logic DivSubnormShiftPos, // is the subnorm divider shift amount positive (ie not underflowed)
//fma
input logic FmaOp, // is it an fma opperation
@ -41,7 +41,7 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
// output
output logic [P.NE+1:0] FmaMe, // exponent of the normalized sum
output logic [P.CORRSHIFTSZ-1:0] Mf, // the shifted sum before LZA correction
output logic [P.NE+1:0] Qe // corrected exponent for divider
output logic [P.NE+1:0] Ue // corrected exponent for divider
);
logic [3*P.NF+3:0] CorrSumShifted; // the shifted sum after LZA correction
@ -61,7 +61,7 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
// correct the shifting of the divsqrt caused by producing a result in (2, .5] range
// condition: if the msb is 1 or the exponent was one, but the shifted quotent was < 1 (Subnorm)
assign LeftShiftQm = (LZAPlus1|(DivQe==1&~LZAPlus1));
assign LeftShiftQm = (LZAPlus1|(DivUe==1&~LZAPlus1));
assign CorrQm0 = Shifted[P.NORMSHIFTSZ-3:P.NORMSHIFTSZ-P.CORRSHIFTSZ-2];
assign CorrQm1 = Shifted[P.NORMSHIFTSZ-2:P.NORMSHIFTSZ-P.CORRSHIFTSZ-1];
mux2 #(P.CORRSHIFTSZ) divcorrmux(CorrQm0, CorrQm1, LeftShiftQm, CorrQmShifted);
@ -87,5 +87,5 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
// the quotent is in the range [.5,2) if there is no early termination
// if the quotent < 1 and not Subnormal then subtract 1 to account for the normalization shift
assign Qe = (DivResSubnorm & DivSubnormShiftPos) ? '0 : DivQe - {(P.NE+1)'(0), ~LZAPlus1};
assign Ue = (DivResSubnorm & DivSubnormShiftPos) ? '0 : DivUe - {(P.NE+1)'(0), ~LZAPlus1};
endmodule