forked from Github_Repos/cvw
idiv passing radix 2, four copies
This commit is contained in:
commit
ef360f0539
@ -77,12 +77,12 @@ module fdivsqrt(
|
|||||||
.ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .MDUE, .W64E);
|
.ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .MDUE, .W64E);
|
||||||
fdivsqrtfsm fdivsqrtfsm(
|
fdivsqrtfsm fdivsqrtfsm(
|
||||||
.clk, .reset, .FmtE, .XsE, .SqrtE, .nE,
|
.clk, .reset, .FmtE, .XsE, .SqrtE, .nE,
|
||||||
.FDivBusyE, .FDivStartE, .IDivStartE, .IFDivStartE, .FDivDoneE, .StallM, .FlushE, /*.DivDone, */
|
.FDivBusyE, .FDivStartE, .IDivStartE, .IFDivStartE, .FDivDoneE, .StallM, .FlushE,
|
||||||
.XZeroE, .YZeroE, .AZeroE, .BZeroE,
|
.XZeroE, .YZeroE, .AZeroE, .BZeroE,
|
||||||
.XNaNE, .YNaNE, .MDUE,
|
.XNaNE, .YNaNE, .MDUE,
|
||||||
.XInfE, .YInfE, .WZeroE, .SpecialCaseM);
|
.XInfE, .YInfE, .WZeroE, .SpecialCaseM);
|
||||||
fdivsqrtiter fdivsqrtiter(
|
fdivsqrtiter fdivsqrtiter(
|
||||||
.clk, .Firstun, .D, .FirstU, .FirstUM, .FirstC, .SqrtE, // .SqrtM,
|
.clk, .Firstun, .D, .FirstU, .FirstUM, .FirstC, .SqrtE,
|
||||||
.X,.DPreproc, .FirstWS(WS), .FirstWC(WC),
|
.X,.DPreproc, .FirstWS(WS), .FirstWC(WC),
|
||||||
.IFDivStartE, .FDivBusyE);
|
.IFDivStartE, .FDivBusyE);
|
||||||
fdivsqrtpostproc fdivsqrtpostproc(
|
fdivsqrtpostproc fdivsqrtpostproc(
|
||||||
|
@ -98,79 +98,80 @@ module fdivsqrtpostproc(
|
|||||||
|
|
||||||
// Determine if sticky bit is negative // *** look for ways to optimize this. Shift shouldn't be needed.
|
// Determine if sticky bit is negative // *** look for ways to optimize this. Shift shouldn't be needed.
|
||||||
assign Sum = WC + WS;
|
assign Sum = WC + WS;
|
||||||
assign W = $signed(Sum) >>> `LOGR;
|
assign NegStickyM = Sum[`DIVb+3];
|
||||||
assign NegStickyM = W[`DIVb+3];
|
|
||||||
assign DM = {4'b0001, D};
|
|
||||||
|
|
||||||
// *** put conditionals on integer division hardware, move to its own module
|
|
||||||
|
|
||||||
// Integer division: sign handling for div and rem
|
|
||||||
always_comb
|
|
||||||
if (~AsM)
|
|
||||||
if (NegStickyM) begin
|
|
||||||
NormQuotM = FirstUM;
|
|
||||||
NormRemM = W + DM;
|
|
||||||
end else begin
|
|
||||||
NormQuotM = FirstU;
|
|
||||||
NormRemM = W;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if (NegStickyM) begin
|
|
||||||
NormQuotM = FirstUM;
|
|
||||||
NormRemM = -(W + DM);
|
|
||||||
end else begin
|
|
||||||
NormQuotM = FirstU;
|
|
||||||
NormRemM = -W;
|
|
||||||
end
|
|
||||||
|
|
||||||
// Integer division: Special cases
|
|
||||||
always_comb
|
|
||||||
if (ALTBM) begin
|
|
||||||
IntQuotM = '0;
|
|
||||||
IntRemM = {{(`DIVb-`XLEN+4){1'b0}}, ForwardedSrcAM};
|
|
||||||
end else begin
|
|
||||||
logic [`DIVb+3:0] PreIntQuotM;
|
|
||||||
if (WZeroM) begin
|
|
||||||
if (weq0M) begin
|
|
||||||
PreIntQuotM = {3'b000, FirstU};
|
|
||||||
IntRemM = '0;
|
|
||||||
end else begin
|
|
||||||
PreIntQuotM = {3'b000, FirstUM};
|
|
||||||
IntRemM = '0;
|
|
||||||
end
|
|
||||||
end else begin
|
|
||||||
PreIntQuotM = {3'b000, NormQuotM};
|
|
||||||
IntRemM = NormRemM;
|
|
||||||
end
|
|
||||||
// flip sign if necessary
|
|
||||||
if (NegQuotM) IntQuotM = -PreIntQuotM;
|
|
||||||
else IntQuotM = PreIntQuotM;
|
|
||||||
end
|
|
||||||
|
|
||||||
always_comb
|
|
||||||
if (RemOpM) begin
|
|
||||||
NormShiftM = ALTBM ? '0 : (mM + (`DIVBLEN+1)'(`DIVa)); // no postshift if forwarding input A to remainder
|
|
||||||
PreResultM = IntRemM;
|
|
||||||
end else begin
|
|
||||||
NormShiftM = ((`DIVBLEN+1)'(`DIVb) - (nM * (`DIVBLEN+1)'(`LOGR)));
|
|
||||||
PreResultM = IntQuotM;
|
|
||||||
/*
|
|
||||||
if (~ALTBM & NegQuotM) begin
|
|
||||||
PreResultM = {3'b111, -IntQuotM};
|
|
||||||
end else begin
|
|
||||||
PreResultM = {3'b000, IntQuotM};
|
|
||||||
end*/
|
|
||||||
//PreResultM = {IntQuotM[`DIVb], IntQuotM[`DIVb], IntQuotM[`DIVb], IntQuotM}; // Suspicious Sign Extender
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
// division takes the result from the next cycle, which is shifted to the left one more time so the square root also needs to be shifted
|
|
||||||
|
|
||||||
assign PreFPIntDivResultM = $signed(PreResultM >>> NormShiftM);
|
|
||||||
assign SpecialFPIntDivResultM = BZeroM ? (RemOpM ? ForwardedSrcAM : {(`XLEN){1'b1}}) : PreFPIntDivResultM[`XLEN-1:0]; // special cases
|
|
||||||
// *** conditional on RV64
|
|
||||||
assign FPIntDivResultM = (W64M ? {{(`XLEN-32){SpecialFPIntDivResultM[31]}}, SpecialFPIntDivResultM[31:0]} : SpecialFPIntDivResultM[`XLEN-1:0]); // Sign extending in case of W64
|
|
||||||
|
|
||||||
assign PreQmM = NegStickyM ? FirstUM : FirstU; // Select U or U-1 depending on negative sticky bit
|
assign PreQmM = NegStickyM ? FirstUM : FirstU; // Select U or U-1 depending on negative sticky bit
|
||||||
assign QmM = SqrtM ? (PreQmM << 1) : PreQmM;
|
assign QmM = SqrtM ? (PreQmM << 1) : PreQmM;
|
||||||
|
|
||||||
|
if (`IDIV_ON_FPU) begin
|
||||||
|
assign W = $signed(Sum) >>> `LOGR;
|
||||||
|
assign DM = {4'b0001, D};
|
||||||
|
|
||||||
|
// Integer division: sign handling for div and rem
|
||||||
|
always_comb
|
||||||
|
if (~AsM)
|
||||||
|
if (NegStickyM) begin
|
||||||
|
NormQuotM = FirstUM;
|
||||||
|
NormRemM = W + DM;
|
||||||
|
end else begin
|
||||||
|
NormQuotM = FirstU;
|
||||||
|
NormRemM = W;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (NegStickyM) begin
|
||||||
|
NormQuotM = FirstUM;
|
||||||
|
NormRemM = -(W + DM);
|
||||||
|
end else begin
|
||||||
|
NormQuotM = FirstU;
|
||||||
|
NormRemM = -W;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Integer division: Special cases
|
||||||
|
always_comb
|
||||||
|
if (ALTBM) begin
|
||||||
|
IntQuotM = '0;
|
||||||
|
IntRemM = {{(`DIVb-`XLEN+4){1'b0}}, ForwardedSrcAM};
|
||||||
|
end else begin
|
||||||
|
logic [`DIVb+3:0] PreIntQuotM;
|
||||||
|
if (WZeroM) begin
|
||||||
|
if (weq0M) begin
|
||||||
|
PreIntQuotM = {3'b000, FirstU};
|
||||||
|
IntRemM = '0;
|
||||||
|
end else begin
|
||||||
|
PreIntQuotM = {3'b000, FirstUM};
|
||||||
|
IntRemM = '0;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
PreIntQuotM = {3'b000, NormQuotM};
|
||||||
|
IntRemM = NormRemM;
|
||||||
|
end
|
||||||
|
// flip sign if necessary
|
||||||
|
if (NegQuotM) IntQuotM = -PreIntQuotM;
|
||||||
|
else IntQuotM = PreIntQuotM;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb
|
||||||
|
if (RemOpM) begin
|
||||||
|
NormShiftM = ALTBM ? '0 : (mM + (`DIVBLEN+1)'(`DIVa)); // no postshift if forwarding input A to remainder
|
||||||
|
PreResultM = IntRemM;
|
||||||
|
end else begin
|
||||||
|
NormShiftM = ((`DIVBLEN+1)'(`DIVb) - (nM * (`DIVBLEN+1)'(`LOGR)));
|
||||||
|
PreResultM = IntQuotM;
|
||||||
|
/*
|
||||||
|
if (~ALTBM & NegQuotM) begin
|
||||||
|
PreResultM = {3'b111, -IntQuotM};
|
||||||
|
end else begin
|
||||||
|
PreResultM = {3'b000, IntQuotM};
|
||||||
|
end*/
|
||||||
|
//PreResultM = {IntQuotM[`DIVb], IntQuotM[`DIVb], IntQuotM[`DIVb], IntQuotM}; // Suspicious Sign Extender
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// division takes the result from the next cycle, which is shifted to the left one more time so the square root also needs to be shifted
|
||||||
|
|
||||||
|
assign PreFPIntDivResultM = $signed(PreResultM >>> NormShiftM);
|
||||||
|
assign SpecialFPIntDivResultM = BZeroM ? (RemOpM ? ForwardedSrcAM : {(`XLEN){1'b1}}) : PreFPIntDivResultM[`XLEN-1:0]; // special cases
|
||||||
|
// *** conditional on RV64
|
||||||
|
assign FPIntDivResultM = (W64M ? {{(`XLEN-32){SpecialFPIntDivResultM[31]}}, SpecialFPIntDivResultM[31:0]} : SpecialFPIntDivResultM[`XLEN-1:0]); // Sign extending in case of W64
|
||||||
|
end
|
||||||
endmodule
|
endmodule
|
@ -69,20 +69,53 @@ module fdivsqrtpreproc (
|
|||||||
// ***can probably merge X LZC with conversion
|
// ***can probably merge X LZC with conversion
|
||||||
// cout the number of leading zeros
|
// cout the number of leading zeros
|
||||||
|
|
||||||
// *** W64 muxes conditional on RV64
|
if (`IDIV_ON_FPU) begin
|
||||||
// *** why !FUnct3E
|
// *** W64 muxes conditional on RV64
|
||||||
assign AsE = ~Funct3E[0] & (W64E ? ForwardedSrcAE[31] : ForwardedSrcAE[`XLEN-1]);
|
// *** why !FUnct3E
|
||||||
assign BsE = ~Funct3E[0] & (W64E ? ForwardedSrcBE[31] : ForwardedSrcBE[`XLEN-1]);
|
assign AsE = ~Funct3E[0] & (W64E ? ForwardedSrcAE[31] : ForwardedSrcAE[`XLEN-1]);
|
||||||
assign A64 = W64E ? {{(`XLEN-32){AsE}}, ForwardedSrcAE[31:0]} : ForwardedSrcAE;
|
assign BsE = ~Funct3E[0] & (W64E ? ForwardedSrcBE[31] : ForwardedSrcBE[`XLEN-1]);
|
||||||
assign B64 = W64E ? {{(`XLEN-32){BsE}}, ForwardedSrcBE[31:0]} : ForwardedSrcBE;
|
assign A64 = W64E ? {{(`XLEN-32){AsE}}, ForwardedSrcAE[31:0]} : ForwardedSrcAE;
|
||||||
assign A64Src = W64E ? {{(`XLEN-32){ForwardedSrcAE[31]}}, ForwardedSrcAE[31:0]} : ForwardedSrcAE;
|
assign B64 = W64E ? {{(`XLEN-32){BsE}}, ForwardedSrcBE[31:0]} : ForwardedSrcBE;
|
||||||
|
assign A64Src = W64E ? {{(`XLEN-32){ForwardedSrcAE[31]}}, ForwardedSrcAE[31:0]} : ForwardedSrcAE;
|
||||||
|
|
||||||
assign NegQuotE = (AsE ^ BsE) & MDUE;
|
assign NegQuotE = (AsE ^ BsE) & MDUE;
|
||||||
|
|
||||||
assign PosA = AsE ? -A64 : A64;
|
assign PosA = AsE ? -A64 : A64;
|
||||||
assign PosB = BsE ? -B64 : B64;
|
assign PosB = BsE ? -B64 : B64;
|
||||||
assign AZeroE = W64E ? ~(|ForwardedSrcAE[31:0]) : ~(|ForwardedSrcAE);
|
assign AZeroE = W64E ? ~(|ForwardedSrcAE[31:0]) : ~(|ForwardedSrcAE);
|
||||||
assign BZeroE = W64E ? ~(|ForwardedSrcBE[31:0]) : ~(|ForwardedSrcBE);
|
assign BZeroE = W64E ? ~(|ForwardedSrcBE[31:0]) : ~(|ForwardedSrcBE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
assign IFNormLenX = MDUE ? {PosA, {(`DIVb-`XLEN){1'b0}}} : {Xm, {(`DIVb-`NF-1){1'b0}}};
|
||||||
|
assign IFNormLenD = MDUE ? {PosB, {(`DIVb-`XLEN){1'b0}}} : {Ym, {(`DIVb-`NF-1){1'b0}}};
|
||||||
|
lzc #(`DIVb) lzcX (IFNormLenX, ell);
|
||||||
|
lzc #(`DIVb) lzcY (IFNormLenD, mE);
|
||||||
|
|
||||||
|
assign XPreproc = IFNormLenX << (ell + {{`DIVBLEN{1'b0}}, 1'b1}); // had issue with (`DIVBLEN+1)'(~MDUE) so using this instead
|
||||||
|
assign DPreproc = IFNormLenD << (mE + {{`DIVBLEN{1'b0}}, 1'b1}); // replaced ~MDUE with 1 bc we always want that extra left shift
|
||||||
|
*/
|
||||||
|
assign ZeroDiff = mE - ell;
|
||||||
|
assign ALTBE = ZeroDiff[`DIVBLEN]; // A less than B
|
||||||
|
assign p = ALTBE ? '0 : ZeroDiff;
|
||||||
|
|
||||||
|
/* verilator lint_off WIDTH */
|
||||||
|
assign pPlusr = (`DIVBLEN)'(`LOGR) + p;
|
||||||
|
assign pPrTrunc = pPlusr % `RK;
|
||||||
|
//assign pPrTrunc = (`LOGRK == 0) ? 0 : pPlusr[`LOGRK-1:0];
|
||||||
|
assign pPrCeil = (pPlusr >> `LOGRK) + {{`DIVBLEN{1'b0}}, |(pPrTrunc)};
|
||||||
|
assign nE = (pPrCeil * (`DIVBLEN+1)'(`DIVCOPIES)) - {{(`DIVBLEN){1'b0}}, 1'b1};
|
||||||
|
assign IntBits = (`DIVBLEN)'(`LOGR) + p - {{(`DIVBLEN){1'b0}}, 1'b1};
|
||||||
|
assign RightShiftX = ((`DIVBLEN)'(`RK) - 1) - (IntBits % `RK);
|
||||||
|
//assign RightShiftX = (`LOGRK == 0) ? 0 : ((`DIVBLEN)'(`RK) - 1) - {{(`DIVBLEN - `RK){1'b0}}, IntBits[`LOGRK-1:0]};
|
||||||
|
/* verilator lint_on WIDTH */
|
||||||
|
|
||||||
|
assign NumZeroE = MDUE ? AZeroE : XZeroE;
|
||||||
|
|
||||||
|
assign X = MDUE ? DivX >> RightShiftX : PreShiftX;
|
||||||
|
end else begin
|
||||||
|
assign NumZeroE = XZeroE;
|
||||||
|
assign X = PreShiftX;
|
||||||
|
end
|
||||||
|
|
||||||
assign IFNormLenX = MDUE ? {PosA, {(`DIVb-`XLEN){1'b0}}} : {Xm, {(`DIVb-`NF-1){1'b0}}};
|
assign IFNormLenX = MDUE ? {PosA, {(`DIVb-`XLEN){1'b0}}} : {Xm, {(`DIVb-`NF-1){1'b0}}};
|
||||||
assign IFNormLenD = MDUE ? {PosB, {(`DIVb-`XLEN){1'b0}}} : {Ym, {(`DIVb-`NF-1){1'b0}}};
|
assign IFNormLenD = MDUE ? {PosB, {(`DIVb-`XLEN){1'b0}}} : {Ym, {(`DIVb-`NF-1){1'b0}}};
|
||||||
@ -92,22 +125,6 @@ module fdivsqrtpreproc (
|
|||||||
assign XPreproc = IFNormLenX << (ell + {{`DIVBLEN{1'b0}}, 1'b1}); // had issue with (`DIVBLEN+1)'(~MDUE) so using this instead
|
assign XPreproc = IFNormLenX << (ell + {{`DIVBLEN{1'b0}}, 1'b1}); // had issue with (`DIVBLEN+1)'(~MDUE) so using this instead
|
||||||
assign DPreproc = IFNormLenD << (mE + {{`DIVBLEN{1'b0}}, 1'b1}); // replaced ~MDUE with 1 bc we always want that extra left shift
|
assign DPreproc = IFNormLenD << (mE + {{`DIVBLEN{1'b0}}, 1'b1}); // replaced ~MDUE with 1 bc we always want that extra left shift
|
||||||
|
|
||||||
assign ZeroDiff = mE - ell;
|
|
||||||
assign ALTBE = ZeroDiff[`DIVBLEN]; // A less than B
|
|
||||||
assign p = ALTBE ? '0 : ZeroDiff;
|
|
||||||
|
|
||||||
/* verilator lint_off WIDTH */
|
|
||||||
assign pPlusr = (`DIVBLEN)'(`LOGR) + p;
|
|
||||||
assign pPrTrunc = pPlusr % `RK;
|
|
||||||
//assign pPrTrunc = (`LOGRK == 0) ? 0 : pPlusr[`LOGRK-1:0];
|
|
||||||
assign pPrCeil = (pPlusr >> `LOGRK) + {{`DIVBLEN{1'b0}}, |(pPrTrunc)};
|
|
||||||
assign nE = (pPrCeil * (`DIVBLEN+1)'(`DIVCOPIES)) - {{(`DIVBLEN){1'b0}}, 1'b1};
|
|
||||||
assign IntBits = (`DIVBLEN)'(`LOGR) + p - {{(`DIVBLEN){1'b0}}, 1'b1};
|
|
||||||
assign RightShiftX = ((`DIVBLEN)'(`RK) - 1) - (IntBits % `RK);
|
|
||||||
//assign RightShiftX = (`LOGRK == 0) ? 0 : ((`DIVBLEN)'(`RK) - 1) - {{(`DIVBLEN - `RK){1'b0}}, IntBits[`LOGRK-1:0]};
|
|
||||||
/* verilator lint_on WIDTH */
|
|
||||||
|
|
||||||
assign NumZeroE = MDUE ? AZeroE : XZeroE;
|
|
||||||
|
|
||||||
assign SqrtX = (Xe[0]^ell[0]) ? {1'b0, ~NumZeroE, XPreproc[`DIVb-1:1]} : {~NumZeroE, XPreproc}; // Bottom bit of XPreproc is always zero because DIVb is larger than XLEN and NF
|
assign SqrtX = (Xe[0]^ell[0]) ? {1'b0, ~NumZeroE, XPreproc[`DIVb-1:1]} : {~NumZeroE, XPreproc}; // Bottom bit of XPreproc is always zero because DIVb is larger than XLEN and NF
|
||||||
assign DivX = {3'b000, ~NumZeroE, XPreproc};
|
assign DivX = {3'b000, ~NumZeroE, XPreproc};
|
||||||
@ -115,7 +132,6 @@ module fdivsqrtpreproc (
|
|||||||
// *** explain why X is shifted between radices (initial assignment of WS=RX)
|
// *** explain why X is shifted between radices (initial assignment of WS=RX)
|
||||||
if (`RADIX == 2) assign PreShiftX = Sqrt ? {3'b111, SqrtX} : DivX;
|
if (`RADIX == 2) assign PreShiftX = Sqrt ? {3'b111, SqrtX} : DivX;
|
||||||
else assign PreShiftX = Sqrt ? {2'b11, SqrtX, 1'b0} : DivX;
|
else assign PreShiftX = Sqrt ? {2'b11, SqrtX, 1'b0} : DivX;
|
||||||
assign X = MDUE ? DivX >> RightShiftX : PreShiftX;
|
|
||||||
|
|
||||||
fdivsqrtexpcalc expcalc(.Fmt, .Xe, .Ye, .Sqrt, .XZeroE, .ell, .m(mE), .Qe(QeE));
|
fdivsqrtexpcalc expcalc(.Fmt, .Xe, .Ye, .Sqrt, .XZeroE, .ell, .m(mE), .Qe(QeE));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user