diff --git a/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv b/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv index 71bffd5ba..ee84c5326 100644 --- a/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv +++ b/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv @@ -68,11 +68,11 @@ module fdivsqrt( logic [`DIVBLEN:0] nE, nM, mM; logic NegQuotM, ALTBM, AsM, W64M; logic DivStartE; - logic [`XLEN-1:0] ForwardedSrcAM; + logic [`XLEN-1:0] AM; fdivsqrtpreproc fdivsqrtpreproc( .clk, .IFDivStartE, .Xm(XmE), .QeM, .Xe(XeE), .Fmt(FmtE), .Ye(YeE), - .Sqrt(SqrtE), .Ym(YmE), .XZeroE, .X, .DPreproc, .ForwardedSrcAM, .MDUM, .W64M, + .Sqrt(SqrtE), .Ym(YmE), .XZeroE, .X, .DPreproc, .AM, .MDUM, .W64M, .nE, .nM, .mM, .NegQuotM, .ALTBM, .AZeroM, .BZeroM, .AZeroE, .BZeroE, .AsM, .ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .MDUE, .W64E); fdivsqrtfsm fdivsqrtfsm( @@ -88,7 +88,7 @@ module fdivsqrt( fdivsqrtpostproc fdivsqrtpostproc( .clk, .reset, .StallM, .WS, .WC, .D, .FirstU, .FirstUM, .FirstC, .SqrtE, .Firstun, - .SqrtM, .SpecialCaseM, .RemOpM(Funct3M[1]), .ForwardedSrcAM, + .SqrtM, .SpecialCaseM, .RemOpM(Funct3M[1]), .AM, .nM, .ALTBM, .mM, .BZeroM, .AsM, .NegQuotM, .W64M, .QmM, .WZeroE, .DivSM, .FPIntDivResultM); endmodule \ No newline at end of file diff --git a/pipelined/src/fpu/fdivsqrt/fdivsqrtexpcalc.sv b/pipelined/src/fpu/fdivsqrt/fdivsqrtexpcalc.sv index fe95c50da..bba177c50 100644 --- a/pipelined/src/fpu/fdivsqrt/fdivsqrtexpcalc.sv +++ b/pipelined/src/fpu/fdivsqrt/fdivsqrtexpcalc.sv @@ -34,7 +34,7 @@ module fdivsqrtexpcalc( input logic [`FMTBITS-1:0] Fmt, input logic [`NE-1:0] Xe, Ye, input logic Sqrt, - input logic XZeroE, + input logic XZero, input logic [`DIVBLEN:0] ell, m, output logic [`NE+1:0] Qe ); @@ -70,7 +70,7 @@ module fdivsqrtexpcalc( assign SXExp = {2'b0, Xe} - {{(`NE+1-`DIVBLEN){1'b0}}, ell} - (`NE+2)'(`BIAS); assign SExp = {SXExp[`NE+1], SXExp[`NE+1:1]} + {2'b0, Bias}; // correct exponent for denormalized input's normalization shifts - assign DExp = ({2'b0, Xe} - {{(`NE+1-`DIVBLEN){1'b0}}, ell} - {2'b0, Ye} + {{(`NE+1-`DIVBLEN){1'b0}}, m} + {3'b0, Bias}) & {`NE+2{~XZeroE}}; + assign DExp = ({2'b0, Xe} - {{(`NE+1-`DIVBLEN){1'b0}}, ell} - {2'b0, Ye} + {{(`NE+1-`DIVBLEN){1'b0}}, m} + {3'b0, Bias}) & {`NE+2{~XZero}}; assign Qe = Sqrt ? SExp : DExp; endmodule diff --git a/pipelined/src/fpu/fdivsqrt/fdivsqrtpostproc.sv b/pipelined/src/fpu/fdivsqrt/fdivsqrtpostproc.sv index e776ceb60..8bedd3841 100644 --- a/pipelined/src/fpu/fdivsqrt/fdivsqrtpostproc.sv +++ b/pipelined/src/fpu/fdivsqrt/fdivsqrtpostproc.sv @@ -39,7 +39,7 @@ module fdivsqrtpostproc( input logic [`DIVb+1:0] FirstC, input logic SqrtE, input logic Firstun, SqrtM, SpecialCaseM, NegQuotM, - input logic [`XLEN-1:0] ForwardedSrcAM, + input logic [`XLEN-1:0] AM, input logic RemOpM, ALTBM, BZeroM, AsM, W64M, input logic [`DIVBLEN:0] nM, mM, output logic [`DIVb:0] QmM, @@ -130,7 +130,7 @@ module fdivsqrtpostproc( always_comb if (ALTBM) begin IntQuotM = '0; - IntRemM = {{(`DIVb-`XLEN+4){1'b0}}, ForwardedSrcAM}; + IntRemM = {{(`DIVb-`XLEN+4){1'b0}}, AM}; end else begin logic [`DIVb+3:0] PreIntQuotM; if (WZeroM) begin @@ -170,7 +170,7 @@ module fdivsqrtpostproc( // 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 + assign SpecialFPIntDivResultM = BZeroM ? (RemOpM ? AM : {(`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 diff --git a/pipelined/src/fpu/fdivsqrt/fdivsqrtpreproc.sv b/pipelined/src/fpu/fdivsqrt/fdivsqrtpreproc.sv index f2355ef48..b3f42a7c4 100644 --- a/pipelined/src/fpu/fdivsqrt/fdivsqrtpreproc.sv +++ b/pipelined/src/fpu/fdivsqrt/fdivsqrtpreproc.sv @@ -47,7 +47,7 @@ module fdivsqrtpreproc ( output logic [`NE+1:0] QeM, output logic [`DIVb+3:0] X, output logic [`DIVb-1:0] DPreproc, - output logic [`XLEN-1:0] ForwardedSrcAM + output logic [`XLEN-1:0] AM ); logic [`DIVb-1:0] XPreproc; @@ -56,9 +56,6 @@ module fdivsqrtpreproc ( logic [`NE+1:0] QeE; // Intdiv signals logic [`DIVb-1:0] IFNormLenX, IFNormLenD; - logic [`XLEN-1:0] PosA, PosB; - logic AsE, BsE, ALTBE, NegQuotE; - logic [`XLEN-1:0] A64, B64, A64Src; logic [`DIVBLEN:0] mE; logic [`DIVBLEN:0] ZeroDiff, IntBits, RightShiftX; logic [`DIVBLEN:0] pPlusr, pPrCeil, p, ell; @@ -70,36 +67,47 @@ module fdivsqrtpreproc ( // cout the number of leading zeros if (`IDIV_ON_FPU) begin - // *** why !FUnct3E + logic signedDiv; + logic AsE, BsE, ALTBE, NegQuotE; + logic [`XLEN-1:0] AE, BE; + logic [`XLEN-1:0] PosA, PosB; + // Extract inputs, signs, zero, depending on W64 mode if applicable + assign signedDiv = ~Funct3E[0]; if (`XLEN==64) begin // 64-bit, supports W64 - assign AsE = ~Funct3E[0] & (W64E ? ForwardedSrcAE[31] : ForwardedSrcAE[`XLEN-1]); - assign BsE = ~Funct3E[0] & (W64E ? ForwardedSrcBE[31] : ForwardedSrcBE[`XLEN-1]); - assign A64 = W64E ? {{(`XLEN-32){AsE}}, ForwardedSrcAE[31:0]} : ForwardedSrcAE; // *** rename this - assign B64 = W64E ? {{(`XLEN-32){BsE}}, ForwardedSrcBE[31:0]} : ForwardedSrcBE; -// assign A64Src = W64E ? {{(`XLEN-32){ForwardedSrcAE[31]}}, ForwardedSrcAE[31:0]} : ForwardedSrcAE; + assign AsE = signedDiv & (W64E ? ForwardedSrcAE[31] : ForwardedSrcAE[`XLEN-1]); + assign BsE = signedDiv & (W64E ? ForwardedSrcBE[31] : ForwardedSrcBE[`XLEN-1]); + assign AE = W64E ? {{(`XLEN-32){AsE}}, ForwardedSrcAE[31:0]} : ForwardedSrcAE; + assign BE = W64E ? {{(`XLEN-32){BsE}}, ForwardedSrcBE[31:0]} : ForwardedSrcBE; assign AZeroE = W64E ? ~(|ForwardedSrcAE[31:0]) : ~(|ForwardedSrcAE); assign BZeroE = W64E ? ~(|ForwardedSrcBE[31:0]) : ~(|ForwardedSrcBE); end else begin // 32 bits only - assign AsE = ~Funct3E[0] & ForwardedSrcAE[`XLEN-1]; - assign BsE = ~Funct3E[0] & ForwardedSrcBE[`XLEN-1]; - assign A64 = ForwardedSrcAE; - assign B64 = ForwardedSrcBE; -// assign A64Src = ForwardedSrcAE; + assign AsE = signedDiv & ForwardedSrcAE[`XLEN-1]; + assign BsE = signedDiv & ForwardedSrcBE[`XLEN-1]; + assign AE = ForwardedSrcAE; + assign BE = ForwardedSrcBE; assign AZeroE = ~(|ForwardedSrcAE); assign BZeroE = ~(|ForwardedSrcBE); end + // Quotient is negative assign NegQuotE = (AsE ^ BsE) & MDUE; - assign PosA = AsE ? -A64 : A64; - assign PosB = BsE ? -B64 : B64; + // Force inputs to be postiive + assign PosA = AsE ? -AE : AE; + assign PosB = BsE ? -BE : BE; + // Select integer or floating point inputs + 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}}}; + + // Difference in number of leading zeros assign ZeroDiff = mE - ell; assign ALTBE = ZeroDiff[`DIVBLEN]; // A less than B assign p = ALTBE ? '0 : ZeroDiff; /* verilator lint_off WIDTH */ + // right shift amount to complete in discrete number of steps assign pPlusr = (`DIVBLEN)'(`LOGR) + p; assign pPrTrunc = pPlusr % `RK; assign pPrCeil = (pPlusr >> `LOGRK) + {{`DIVBLEN{1'b0}}, |(pPrTrunc)}; @@ -108,8 +116,8 @@ module fdivsqrtpreproc ( assign RightShiftX = ((`DIVBLEN)'(`RK) - 1) - (IntBits % `RK); /* verilator lint_on WIDTH */ + // Selet integer or floating-point operands assign NumZeroE = MDUE ? AZeroE : XZeroE; - assign X = MDUE ? DivX >> RightShiftX : PreShiftX; // pipeline registers @@ -122,22 +130,24 @@ module fdivsqrtpreproc ( flopen #(1) azeroreg(clk, IFDivStartE, AZeroE, AZeroM); flopen #(1) bzeroreg(clk, IFDivStartE, BZeroE, BZeroM); flopen #(1) asignreg(clk, IFDivStartE, AsE, AsM); -// flopen #(`XLEN) srcareg(clk, IFDivStartE, A64Src, ForwardedSrcAM); - flopen #(`XLEN) srcareg(clk, IFDivStartE, A64, ForwardedSrcAM); + flopen #(`XLEN) srcareg(clk, IFDivStartE, AE, AM); end else begin + assign IFNormLenX = {Xm, {(`DIVb-`NF-1){1'b0}}}; + assign IFNormLenD = {Ym, {(`DIVb-`NF-1){1'b0}}}; assign NumZeroE = XZeroE; assign X = PreShiftX; end - 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}}}; + // count leading zeros for denorm FP and to normalize integer inputs 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 + // Normalization shift + assign XPreproc = IFNormLenX << (ell + {{`DIVBLEN{1'b0}}, 1'b1}); + assign DPreproc = IFNormLenD << (mE + {{`DIVBLEN{1'b0}}, 1'b1}); + // append leading 1 (for nonzero inputs) and zero-extend 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}; @@ -145,19 +155,9 @@ module fdivsqrtpreproc ( if (`RADIX == 2) assign PreShiftX = Sqrt ? {3'b111, SqrtX} : DivX; else assign PreShiftX = Sqrt ? {2'b11, SqrtX, 1'b0} : DivX; - fdivsqrtexpcalc expcalc(.Fmt, .Xe, .Ye, .Sqrt, .XZeroE, .ell, .m(mE), .Qe(QeE)); - - // radix 2 radix 4 - // 1 copies DIVLEN+2 DIVLEN+2/2 - // 2 copies DIVLEN+2/2 DIVLEN+2/2*2 - // 4 copies DIVLEN+2/4 DIVLEN+2/2*4 - // 8 copies DIVLEN+2/8 DIVLEN+2/2*8 - - // DIVRESLEN = DIVLEN or DIVLEN+2 - // r = 1 or 2 - // DIVRESLEN/(r*`DIVCOPIES) + // Floating-point exponent + fdivsqrtexpcalc expcalc(.Fmt, .Xe, .Ye, .Sqrt, .XZero(XZeroE), .ell, .m(mE), .Qe(QeE)); flopen #(`NE+2) expreg(clk, IFDivStartE, QeE, QeM); - endmodule