fdivsqrt code cleanup

This commit is contained in:
David Harris 2022-10-09 03:37:27 -07:00
parent 382ccf74a5
commit 55e4911cf0
2 changed files with 33 additions and 35 deletions

View File

@ -55,7 +55,6 @@ module fdivsqrt(
// output logic [`XLEN-1:0] RemM, // output logic [`XLEN-1:0] RemM,
); );
logic [`DIVb+3:0] NextWSN, NextWCN;
logic [`DIVb+3:0] WS, WC; logic [`DIVb+3:0] WS, WC;
logic [`DIVb+3:0] X; logic [`DIVb+3:0] X;
logic [`DIVN-2:0] D; // U0.N-1 logic [`DIVN-2:0] D; // U0.N-1
@ -77,7 +76,7 @@ module fdivsqrt(
.XInfE, .YInfE, .WZero, .SpecialCaseM); .XInfE, .YInfE, .WZero, .SpecialCaseM);
fdivsqrtiter fdivsqrtiter( fdivsqrtiter fdivsqrtiter(
.clk, .Firstun, .D, .FirstU, .FirstUM, .FirstC, .SqrtE, .SqrtM, .clk, .Firstun, .D, .FirstU, .FirstUM, .FirstC, .SqrtE, .SqrtM,
.X,.Dpreproc, .FirstWS(WS), .FirstWC(WC), .NextWSN, .NextWCN, .X,.Dpreproc, .FirstWS(WS), .FirstWC(WC),
.DivStartE, .Xe(XeE), .Ye(YeE), .XZeroE, .YZeroE, .DivStartE, .Xe(XeE), .Ye(YeE), .XZeroE, .YZeroE,
.DivBusy); .DivBusy);
fdivsqrtpostproc fdivsqrtpostproc(.WS, .WC, .D, .FirstU, .FirstUM, .FirstC, .Firstun, .SqrtM, .SpecialCaseM, .QmM, .WZero, .DivSM); fdivsqrtpostproc fdivsqrtpostproc(.WS, .WC, .D, .FirstU, .FirstUM, .FirstC, .Firstun, .SqrtM, .SpecialCaseM, .QmM, .WZero, .DivSM);

View File

@ -41,7 +41,6 @@ module fdivsqrtiter(
input logic [`DIVb+3:0] X, input logic [`DIVb+3:0] X,
input logic [`DIVN-2:0] Dpreproc, input logic [`DIVN-2:0] Dpreproc,
output logic [`DIVN-2:0] D, // U0.N-1 output logic [`DIVN-2:0] D, // U0.N-1
output logic [`DIVb+3:0] NextWSN, NextWCN,
output logic [`DIVb:0] FirstU, FirstUM, output logic [`DIVb:0] FirstU, FirstUM,
output logic [`DIVb+1:0] FirstC, output logic [`DIVb+1:0] FirstC,
output logic Firstun, output logic Firstun,
@ -58,10 +57,10 @@ module fdivsqrtiter(
/* verilator lint_off UNOPTFLAT */ /* verilator lint_off UNOPTFLAT */
logic [`DIVb+3:0] WSA[`DIVCOPIES-1:0]; // Q4.b logic [`DIVb+3:0] WSA[`DIVCOPIES-1:0]; // Q4.b
logic [`DIVb+3:0] WCA[`DIVCOPIES-1:0]; // Q4.b logic [`DIVb+3:0] WCA[`DIVCOPIES-1:0]; // Q4.b
logic [`DIVb+3:0] WS[`DIVCOPIES-1:0]; // Q4.b logic [`DIVb+3:0] WS[`DIVCOPIES:0]; // Q4.b
logic [`DIVb+3:0] WC[`DIVCOPIES-1:0]; // Q4.b logic [`DIVb+3:0] WC[`DIVCOPIES:0]; // Q4.b
logic [`DIVb:0] U[`DIVCOPIES-1:0]; // U1.b logic [`DIVb:0] U[`DIVCOPIES:0]; // U1.b
logic [`DIVb:0] UM[`DIVCOPIES-1:0];// 1.b logic [`DIVb:0] UM[`DIVCOPIES:0];// 1.b
logic [`DIVb:0] UNext[`DIVCOPIES-1:0];// U1.b logic [`DIVb:0] UNext[`DIVCOPIES-1:0];// U1.b
logic [`DIVb:0] UMNext[`DIVCOPIES-1:0];// U1.b logic [`DIVb:0] UMNext[`DIVCOPIES-1:0];// U1.b
logic [`DIVb+1:0] C[`DIVCOPIES:0]; // Q2.b logic [`DIVb+1:0] C[`DIVCOPIES:0]; // Q2.b
@ -85,25 +84,33 @@ module fdivsqrtiter(
// - otherwise load WSA into the flipflop // - otherwise load WSA into the flipflop
// - the assumed one is added to D since it's always normalized (and X/0 is a special case handeled by result selection) // - the assumed one is added to D since it's always normalized (and X/0 is a special case handeled by result selection)
// - XZeroE is used as the assumed one to avoid creating a sticky bit - all other numbers are normalized // - XZeroE is used as the assumed one to avoid creating a sticky bit - all other numbers are normalized
assign NextWSN = WSA[`DIVCOPIES-1] << `LOGR;
assign NextWCN = WCA[`DIVCOPIES-1] << `LOGR; // Residual WS/SC registers/initializaiton mux
mux2 #(`DIVb+4) wsmux(WS[`DIVCOPIES], X, DivStartE, WSN);
// Initialize C to -1 for sqrt and -R for division mux2 #(`DIVb+4) wcmux(WC[`DIVCOPIES], '0, DivStartE, WCN);
logic [1:0] initCSqrt, initCDiv2, initCDiv4, initCUpper;
assign initCSqrt = 2'b11; // -1
assign initCDiv2 = 2'b10; // -2
assign initCDiv4 = 2'b00; // -4
assign initCUpper = SqrtE ? initCSqrt : (`RADIX == 4) ? initCDiv4 : initCDiv2;
assign initC = {initCUpper, {`DIVb{1'b0}}};
mux2 #(`DIVb+4) wsmux(NextWSN, X, DivStartE, WSN);
flopen #(`DIVb+4) wsflop(clk, DivStartE|DivBusy, WSN, WS[0]); flopen #(`DIVb+4) wsflop(clk, DivStartE|DivBusy, WSN, WS[0]);
mux2 #(`DIVb+4) wcmux(NextWCN, '0, DivStartE, WCN);
flopen #(`DIVb+4) wcflop(clk, DivStartE|DivBusy, WCN, WC[0]); flopen #(`DIVb+4) wcflop(clk, DivStartE|DivBusy, WCN, WC[0]);
flopen #(`DIVN-1) dflop(clk, DivStartE, Dpreproc, D);
// UOTFC Result U and UM registers/initialization mux
// Initialize U to 1.0 and UM to 0 for square root; U to 0 and UM to -1 for division
assign initU = SqrtE ? {1'b1, {(`DIVb){1'b0}}} : 0;
assign initUM = SqrtE ? 0 : {1'b1, {(`DIVb){1'b0}}};
mux2 #(`DIVb+1) Umux(UNext[`DIVCOPIES-1], initU, DivStartE, UMux);
mux2 #(`DIVb+1) UMmux(UMNext[`DIVCOPIES-1], initUM, DivStartE, UMMux);
flopen #(`DIVb+1) UReg(clk, DivStartE|DivBusy, UMux, U[0]);
flopen #(`DIVb+1) UMReg(clk, DivStartE|DivBusy, UMMux, UM[0]);
// C register/initialization mux
// Initialize C to -1 for sqrt and -R for division
logic [1:0] initCUpper;
assign initCUpper = SqrtE ? 2'b11 : (`RADIX == 4) ? 2'b00 : 2'b10;
assign initC = {initCUpper, {`DIVb{1'b0}}};
mux2 #(`DIVb+2) Cmux(C[`DIVCOPIES], initC, DivStartE, CMux); mux2 #(`DIVb+2) Cmux(C[`DIVCOPIES], initC, DivStartE, CMux);
flopen #(`DIVb+2) cflop(clk, DivStartE|DivBusy, CMux, C[0]); flopen #(`DIVb+2) cflop(clk, DivStartE|DivBusy, CMux, C[0]);
// Divisior register
flopen #(`DIVN-1) dflop(clk, DivStartE, Dpreproc, D);
// Divisor Selections // Divisor Selections
// - choose the negitive version of what's being selected // - choose the negitive version of what's being selected
// - D is only the fraction // - D is only the fraction
@ -113,6 +120,7 @@ module fdivsqrtiter(
assign D2 = {2'b0, 1'b1, D, {`DIVb+2-`DIVN{1'b0}}}; assign D2 = {2'b0, 1'b1, D, {`DIVb+2-`DIVN{1'b0}}};
end end
// k=DIVCOPIES of the recurrence logic
genvar i; genvar i;
generate generate
for(i=0; $unsigned(i)<`DIVCOPIES; i++) begin : interations for(i=0; $unsigned(i)<`DIVCOPIES; i++) begin : interations
@ -127,23 +135,14 @@ module fdivsqrtiter(
.WS(WS[i]), .WC(WC[i]), .WSA(WSA[i]), .WCA(WCA[i]), .WS(WS[i]), .WC(WC[i]), .WSA(WSA[i]), .WCA(WCA[i]),
.C(C[i]), .U(U[i]), .UM(UM[i]), .CNext(C[i+1]), .UNext(UNext[i]), .UMNext(UMNext[i]), .un(un[i])); .C(C[i]), .U(U[i]), .UM(UM[i]), .CNext(C[i+1]), .UNext(UNext[i]), .UMNext(UMNext[i]), .un(un[i]));
end end
if(i<(`DIVCOPIES-1)) begin assign WS[i+1] = WSA[i] << `LOGR;
assign WS[i+1] = WSA[i] << `LOGR; assign WC[i+1] = WCA[i] << `LOGR;
assign WC[i+1] = WCA[i] << `LOGR; assign U[i+1] = UNext[i];
assign U[i+1] = UNext[i]; assign UM[i+1] = UMNext[i];
assign UM[i+1] = UMNext[i];
end
end end
endgenerate endgenerate
// Initialize U to 1.0 and UM to 0 for square root; U to 0 and UM to -1 for division // Send values from start of cycle for postprocessing
assign initU = SqrtE ? {1'b1, {(`DIVb){1'b0}}} : 0;
assign initUM = SqrtE ? 0 : {1'b1, {(`DIVb){1'b0}}};
mux2 #(`DIVb+1) Umux(UNext[`DIVCOPIES-1], initU, DivStartE, UMux);
mux2 #(`DIVb+1) UMmux(UMNext[`DIVCOPIES-1], initUM, DivStartE, UMMux);
flopen #(`DIVb+1) UReg(clk, DivStartE|DivBusy, UMux, U[0]);
flopen #(`DIVb+1) UMReg(clk, DivStartE|DivBusy, UMMux, UM[0]);
assign FirstWS = WS[0]; assign FirstWS = WS[0];
assign FirstWC = WC[0]; assign FirstWC = WC[0];
assign FirstU = U[0]; assign FirstU = U[0];