From 2aa43848f50f532650e821b75cc661aeb1d5cd6d Mon Sep 17 00:00:00 2001 From: David Harris Date: Sun, 9 Oct 2022 03:37:27 -0700 Subject: [PATCH] fdivsqrt code cleanup --- pipelined/src/fpu/fdivsqrt/fdivsqrt.sv | 3 +- pipelined/src/fpu/fdivsqrt/fdivsqrtiter.sv | 65 +++++++++++----------- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv b/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv index 19679aa55..9af93fb37 100644 --- a/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv +++ b/pipelined/src/fpu/fdivsqrt/fdivsqrt.sv @@ -55,7 +55,6 @@ module fdivsqrt( // output logic [`XLEN-1:0] RemM, ); - logic [`DIVb+3:0] NextWSN, NextWCN; logic [`DIVb+3:0] WS, WC; logic [`DIVb+3:0] X; logic [`DIVN-2:0] D; // U0.N-1 @@ -77,7 +76,7 @@ module fdivsqrt( .XInfE, .YInfE, .WZero, .SpecialCaseM); fdivsqrtiter fdivsqrtiter( .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, .DivBusy); fdivsqrtpostproc fdivsqrtpostproc(.WS, .WC, .D, .FirstU, .FirstUM, .FirstC, .Firstun, .SqrtM, .SpecialCaseM, .QmM, .WZero, .DivSM); diff --git a/pipelined/src/fpu/fdivsqrt/fdivsqrtiter.sv b/pipelined/src/fpu/fdivsqrt/fdivsqrtiter.sv index d13d706f4..5e22be3ee 100644 --- a/pipelined/src/fpu/fdivsqrt/fdivsqrtiter.sv +++ b/pipelined/src/fpu/fdivsqrt/fdivsqrtiter.sv @@ -41,7 +41,6 @@ module fdivsqrtiter( input logic [`DIVb+3:0] X, input logic [`DIVN-2:0] Dpreproc, 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+1:0] FirstC, output logic Firstun, @@ -58,10 +57,10 @@ module fdivsqrtiter( /* verilator lint_off UNOPTFLAT */ logic [`DIVb+3:0] WSA[`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] WC[`DIVCOPIES-1:0]; // Q4.b - logic [`DIVb:0] U[`DIVCOPIES-1:0]; // U1.b - logic [`DIVb:0] UM[`DIVCOPIES-1:0];// 1.b + logic [`DIVb+3:0] WS[`DIVCOPIES:0]; // Q4.b + logic [`DIVb+3:0] WC[`DIVCOPIES:0]; // Q4.b + logic [`DIVb:0] U[`DIVCOPIES:0]; // U1.b + logic [`DIVb:0] UM[`DIVCOPIES:0];// 1.b logic [`DIVb:0] UNext[`DIVCOPIES-1:0];// U1.b logic [`DIVb:0] UMNext[`DIVCOPIES-1:0];// U1.b logic [`DIVb+1:0] C[`DIVCOPIES:0]; // Q2.b @@ -85,25 +84,33 @@ module fdivsqrtiter( // - 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) // - 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; - - // Initialize C to -1 for sqrt and -R for division - 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); + + // Residual WS/SC registers/initializaiton mux + mux2 #(`DIVb+4) wsmux(WS[`DIVCOPIES], X, DivStartE, WSN); + mux2 #(`DIVb+4) wcmux(WC[`DIVCOPIES], '0, DivStartE, WCN); 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 #(`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); flopen #(`DIVb+2) cflop(clk, DivStartE|DivBusy, CMux, C[0]); + // Divisior register + flopen #(`DIVN-1) dflop(clk, DivStartE, Dpreproc, D); + // Divisor Selections // - choose the negitive version of what's being selected // - D is only the fraction @@ -113,6 +120,7 @@ module fdivsqrtiter( assign D2 = {2'b0, 1'b1, D, {`DIVb+2-`DIVN{1'b0}}}; end + // k=DIVCOPIES of the recurrence logic genvar i; generate 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]), .C(C[i]), .U(U[i]), .UM(UM[i]), .CNext(C[i+1]), .UNext(UNext[i]), .UMNext(UMNext[i]), .un(un[i])); end - if(i<(`DIVCOPIES-1)) begin - assign WS[i+1] = WSA[i] << `LOGR; - assign WC[i+1] = WCA[i] << `LOGR; - assign U[i+1] = UNext[i]; - assign UM[i+1] = UMNext[i]; - end + assign WS[i+1] = WSA[i] << `LOGR; + assign WC[i+1] = WCA[i] << `LOGR; + assign U[i+1] = UNext[i]; + assign UM[i+1] = UMNext[i]; end endgenerate - // 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]); - + // Send values from start of cycle for postprocessing assign FirstWS = WS[0]; assign FirstWC = WC[0]; assign FirstU = U[0];