Added flops to preproc

This commit is contained in:
cturek 2022-12-02 20:31:08 +00:00
parent 3a07d56d33
commit 04ac350a29
3 changed files with 57 additions and 53 deletions

View File

@ -66,12 +66,13 @@ module fdivsqrt(
logic WZero; logic WZero;
logic SpecialCaseM; logic SpecialCaseM;
logic [`DIVBLEN:0] n, m; logic [`DIVBLEN:0] n, m;
logic OTFCSwap, ALTB, BZero, As; logic OTFCSwap, ALTBM, BZero, As;
logic DivStartE;
fdivsqrtpreproc fdivsqrtpreproc( fdivsqrtpreproc fdivsqrtpreproc(
.clk, .IFDivStartE, .Xm(XmE), .QeM, .Xe(XeE), .Fmt(FmtE), .Ye(YeE), .clk, .IFDivStartE, .Xm(XmE), .QeM, .Xe(XeE), .Fmt(FmtE), .Ye(YeE),
.Sqrt(SqrtE), .Ym(YmE), .XZero(XZeroE), .X, .Dpreproc, .Sqrt(SqrtE), .Ym(YmE), .XZero(XZeroE), .X, .Dpreproc,
.n, .m, .OTFCSwap, .ALTB, .BZero, .As, .n, .m, .OTFCSwap, .ALTBM, .BZero, .As,
.ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .Funct3M, .MDUE, .W64E); .ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .Funct3M, .MDUE, .W64E);
fdivsqrtfsm fdivsqrtfsm( fdivsqrtfsm fdivsqrtfsm(
.clk, .reset, .FmtE, .XsE, .SqrtE, .clk, .reset, .FmtE, .XsE, .SqrtE,
@ -85,7 +86,7 @@ module fdivsqrt(
.FDivBusyE); .FDivBusyE);
fdivsqrtpostproc fdivsqrtpostproc( fdivsqrtpostproc fdivsqrtpostproc(
.WS, .WC, .D, .FirstU, .FirstUM, .FirstC, .Firstun, .WS, .WC, .D, .FirstU, .FirstUM, .FirstC, .Firstun,
.SqrtM, .SpecialCaseM, .RemOp(Funct3E[1]), .ForwardedSrcAE, .SqrtM, .SpecialCaseM, .RemOpM(Funct3M[1]), .ForwardedSrcAE,
.MDUE, .n, .ALTB, .m, .BZero, .As, .n, .ALTBM, .m, .BZero, .As,
.QmM, .WZero, .DivSM); .QmM, .WZero, .DivSM);
endmodule endmodule

View File

@ -39,7 +39,7 @@ module fdivsqrtpostproc(
input logic SqrtM, input logic SqrtM,
input logic SpecialCaseM, input logic SpecialCaseM,
input logic [`XLEN-1:0] ForwardedSrcAE, input logic [`XLEN-1:0] ForwardedSrcAE,
input logic RemOp, MDUE, ALTB, BZero, As, input logic RemOpM, ALTBM, BZero, As,
input logic [`DIVBLEN:0] n, m, input logic [`DIVBLEN:0] n, m,
output logic [`DIVb:0] QmM, output logic [`DIVb:0] QmM,
output logic WZero, output logic WZero,
@ -48,12 +48,12 @@ module fdivsqrtpostproc(
logic [`DIVb+3:0] W, Sum, RemD; logic [`DIVb+3:0] W, Sum, RemD;
logic [`DIVb:0] PreQmM; logic [`DIVb:0] PreQmM;
logic NegSticky, PostInc; logic NegStickyM, PostIncM;
logic weq0; logic weq0;
logic [`DIVBLEN:0] NormShift; logic [`DIVBLEN:0] NormShiftM;
logic [`DIVb:0] IntQuot, NormQuot; logic [`DIVb:0] IntQuotM, NormQuotM;
logic [`DIVb+3:0] IntRem, NormRem; logic [`DIVb+3:0] IntRemM, NormRemM;
logic [`DIVb+3:0] PreResult, Result; logic [`DIVb+3:0] PreResultM, ResultM;
// check for early termination on an exact result. If the result is not exact, the sticky should be set // check for early termination on an exact result. If the result is not exact, the sticky should be set
aplusbeq0 #(`DIVb+4) wspluswceq0(WS, WC, weq0); aplusbeq0 #(`DIVb+4) wspluswceq0(WS, WC, weq0);
@ -77,66 +77,67 @@ module fdivsqrtpostproc(
// Determine if sticky bit is negative // Determine if sticky bit is negative
assign Sum = WC + WS; assign Sum = WC + WS;
assign W = $signed(Sum) >>> `LOGR; assign W = $signed(Sum) >>> `LOGR;
assign NegSticky = W[`DIVb+3]; assign NegStickyM = W[`DIVb+3];
assign RemD = {4'b0000, D, {(`DIVb-`DIVN+1){1'b0}}}; assign RemD = {4'b0000, D, {(`DIVb-`DIVN+1){1'b0}}};
// Integer division: sign handling for div and rem
always_comb always_comb
if (~As) if (~As)
if (NegSticky) begin if (NegStickyM) begin
NormQuot = FirstUM; NormQuotM = FirstUM;
NormRem = W + RemD; NormRemM = W + RemD;
PostInc = 0; PostIncM = 0;
end else begin end else begin
NormQuot = FirstU; NormQuotM = FirstU;
NormRem = W; NormRemM = W;
PostInc = 0; PostIncM = 0;
end end
else else
if (NegSticky | weq0) begin if (NegStickyM | weq0) begin
NormQuot = FirstU; NormQuotM = FirstU;
NormRem = W; NormRemM = W;
PostInc = 0; PostIncM = 0;
end else begin end else begin
NormQuot = FirstU; NormQuotM = FirstU;
NormRem = W - RemD; NormRemM = W - RemD;
PostInc = 1; PostIncM = 1;
end end
// Integer division: Special cases
always_comb always_comb
if(ALTB) begin if(ALTBM) begin
IntQuot = '0; IntQuotM = '0;
IntRem = {{(`DIVb-`XLEN+4){1'b0}}, ForwardedSrcAE}; IntRemM = {{(`DIVb-`XLEN+4){1'b0}}, ForwardedSrcAE};
end else if (BZero) begin end else if (BZero) begin
IntQuot = '1; IntQuotM = '1;
IntRem = {{(`DIVb-`XLEN+4){1'b0}}, ForwardedSrcAE}; IntRemM = {{(`DIVb-`XLEN+4){1'b0}}, ForwardedSrcAE};
end else if (WZero) begin end else if (WZero) begin
if (weq0) begin if (weq0) begin
IntQuot = FirstU; IntQuotM = FirstU;
IntRem = '0; IntRemM = '0;
end else begin end else begin
IntQuot = FirstUM; IntQuotM = FirstUM;
IntRem = '0; IntRemM = '0;
end end
end else begin end else begin
IntQuot = NormQuot; IntQuotM = NormQuotM;
IntRem = NormRem; IntRemM = NormRemM;
end end
always_comb always_comb
if (RemOp) begin if (RemOpM) begin
NormShift = (m + (`DIVBLEN)'(`DIVa)); NormShiftM = (m + (`DIVBLEN)'(`DIVa));
PreResult = IntRem; PreResultM = IntRemM;
end else begin end else begin
NormShift = ((`DIVBLEN)'(`DIVb) - (n << `LOGR)); NormShiftM = ((`DIVBLEN)'(`DIVb) - (n << `LOGR));
PreResult = {3'b000, IntQuot}; PreResultM = {3'b000, IntQuotM};
end 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 // 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
// *** Result is unused right now assign ResultM = ($signed(PreResultM) >>> NormShiftM) + {{(`DIVb+3){1'b0}}, (PostIncM & ~RemOpM)};
assign Result = ($signed(PreResult) >>> NormShift) + {{(`DIVb+3){1'b0}}, (PostInc & ~RemOp)};
assign PreQmM = NegSticky ? 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;
endmodule endmodule

View File

@ -42,7 +42,7 @@ module fdivsqrtpreproc (
input logic [2:0] Funct3E, Funct3M, input logic [2:0] Funct3E, Funct3M,
input logic MDUE, W64E, input logic MDUE, W64E,
output logic [`DIVBLEN:0] n, m, output logic [`DIVBLEN:0] n, m,
output logic OTFCSwap, ALTB, BZero, As, output logic OTFCSwap, ALTBM, BZero, As,
output logic [`NE+1:0] QeM, output logic [`NE+1:0] QeM,
output logic [`DIVb+3:0] X, output logic [`DIVb+3:0] X,
output logic [`DIVN-2:0] Dpreproc output logic [`DIVN-2:0] Dpreproc
@ -56,7 +56,7 @@ module fdivsqrtpreproc (
// Intdiv signals // Intdiv signals
logic [`DIVb-1:0] ZeroBufX, ZeroBufY; logic [`DIVb-1:0] ZeroBufX, ZeroBufY;
logic [`XLEN-1:0] PosA, PosB; logic [`XLEN-1:0] PosA, PosB;
logic Bs, OTFCSwapTemp; logic Bs, OTFCSwapTemp, ALTBE;
logic [`XLEN-1:0] A64, B64; logic [`XLEN-1:0] A64, B64;
logic [`DIVBLEN:0] Calcn, Calcm; logic [`DIVBLEN:0] Calcn, Calcm;
logic [`DIVBLEN:0] ZeroDiff, IntBits, RightShiftX; logic [`DIVBLEN:0] ZeroDiff, IntBits, RightShiftX;
@ -87,8 +87,8 @@ module fdivsqrtpreproc (
assign PreprocY = Ym[`NF-1:0]<<Calcm; assign PreprocY = Ym[`NF-1:0]<<Calcm;
assign ZeroDiff = Calcm - L; assign ZeroDiff = Calcm - L;
assign ALTB = ZeroDiff[`DIVBLEN]; // A less than B assign ALTBE = ZeroDiff[`DIVBLEN]; // A less than B
assign p = ALTB ? '0 : ZeroDiff; assign p = ALTBE ? '0 : ZeroDiff;
assign pPlusr = (`DIVBLEN)'(`LOGR) + p; assign pPlusr = (`DIVBLEN)'(`LOGR) + p;
assign pPrTrunc = pPlusr[`LOGRK-1:0]; assign pPrTrunc = pPlusr[`LOGRK-1:0];
@ -103,7 +103,7 @@ 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, {`DIVb-1-`NF{1'b0}}} : DivX; if (`RADIX == 2) assign PreShiftX = Sqrt ? {3'b111, SqrtX, {`DIVb-1-`NF{1'b0}}} : DivX;
else assign PreShiftX = Sqrt ? {2'b11, SqrtX, {`DIVb-1-`NF{1'b0}}, 1'b0} : DivX; else assign PreShiftX = Sqrt ? {2'b11, SqrtX, {`DIVb-1-`NF{1'b0}}, 1'b0} : DivX;
assign X = MDUE ? PreShiftX >> RightShiftX : PreShiftX; assign X = MDUE ? DivX >> RightShiftX : PreShiftX;
assign Dpreproc = {PreprocY, {`DIVN-1-`NF{1'b0}}}; assign Dpreproc = {PreprocY, {`DIVN-1-`NF{1'b0}}};
// radix 2 radix 4 // radix 2 radix 4
@ -115,10 +115,12 @@ module fdivsqrtpreproc (
// DIVRESLEN = DIVLEN or DIVLEN+2 // DIVRESLEN = DIVLEN or DIVLEN+2
// r = 1 or 2 // r = 1 or 2
// DIVRESLEN/(r*`DIVCOPIES) // DIVRESLEN/(r*`DIVCOPIES)
flopen #(`NE+2) expflop(clk, IFDivStartE, Qe, QeM);
flopen #(1) swapflop(clk, IFDivStartE, OTFCSwapTemp, OTFCSwap); flopen #(`NE+2) expreg(clk, IFDivStartE, Qe, QeM);
flopen #(`DIVBLEN+1) nflop(clk, IFDivStartE, Calcn, n); flopen #(1) swapreg(clk, IFDivStartE, OTFCSwapTemp, OTFCSwap);
flopen #(`DIVBLEN+1) mflop(clk, IFDivStartE, Calcm, m); flopen #(1) altbreg(clk, IFDivStartE, ALTBE, ALTBM);
flopen #(`DIVBLEN+1) nreg(clk, IFDivStartE, Calcn, n);
flopen #(`DIVBLEN+1) mreg(clk, IFDivStartE, Calcm, m);
expcalc expcalc(.Fmt, .Xe, .Ye, .Sqrt, .XZero, .L, .m(Calcm), .Qe); expcalc expcalc(.Fmt, .Xe, .Ye, .Sqrt, .XZero, .L, .m(Calcm), .Qe);
endmodule endmodule