fdivsqrt comment improvements

This commit is contained in:
David Harris 2023-11-12 06:15:47 -08:00
parent 4c2a9c7bab
commit 002034845a
9 changed files with 40 additions and 52 deletions

View File

@ -28,11 +28,11 @@
module fdivsqrtexpcalc import cvw::*; #(parameter cvw_t P) ( module fdivsqrtexpcalc import cvw::*; #(parameter cvw_t P) (
input logic [P.FMTBITS-1:0] Fmt, input logic [P.FMTBITS-1:0] Fmt,
input logic [P.NE-1:0] Xe, Ye, input logic [P.NE-1:0] Xe, Ye, // input exponents
input logic Sqrt, input logic Sqrt,
input logic XZero, input logic XZero,
input logic [P.DIVBLEN-1:0] ell, m, input logic [P.DIVBLEN-1:0] ell, m, // number of leading 0s in Xe and Ye
output logic [P.NE+1:0] Ue output logic [P.NE+1:0] Ue // result exponent
); );
logic [P.NE-2:0] Bias; logic [P.NE-2:0] Bias;
@ -40,6 +40,8 @@ module fdivsqrtexpcalc import cvw::*; #(parameter cvw_t P) (
logic [P.NE+1:0] SExp; logic [P.NE+1:0] SExp;
logic [P.NE+1:0] DExp; logic [P.NE+1:0] DExp;
// Determine exponent bias according to the format
if (P.FPSIZES == 1) begin if (P.FPSIZES == 1) begin
assign Bias = (P.NE-1)'(P.BIAS); assign Bias = (P.NE-1)'(P.BIAS);

View File

@ -28,12 +28,12 @@
module fdivsqrtfgen2 import cvw::*; #(parameter cvw_t P) ( module fdivsqrtfgen2 import cvw::*; #(parameter cvw_t P) (
input logic up, uz, input logic up, uz,
input logic [P.DIVb+3:0] C, U, UM, input logic [P.DIVb+3:0] C, U, UM, // Q4.DIVb (extended from shorter forms)
output logic [P.DIVb+3:0] F output logic [P.DIVb+3:0] F // Q4.DIVb
); );
logic [P.DIVb+3:0] FP, FN, FZ; logic [P.DIVb+3:0] FP, FN, FZ; // Q4.DIVb
// Generate for both positive and negative bits // Generate for both positive and negative quotient digits
assign FP = ~(U << 1) & C; assign FP = ~(U << 1) & C;
assign FN = (UM << 1) | (C & ~(C << 2)); assign FN = (UM << 1) | (C & ~(C << 2));
assign FZ = '0; assign FZ = '0;

View File

@ -27,14 +27,14 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module fdivsqrtfgen4 import cvw::*; #(parameter cvw_t P) ( module fdivsqrtfgen4 import cvw::*; #(parameter cvw_t P) (
input logic [3:0] udigit, input logic [3:0] udigit, // {2, 1, -1, -2}; all cold for zero
input logic [P.DIVb+3:0] C, U, UM, input logic [P.DIVb+3:0] C, U, UM, // Q4.DIVb (extended from shorter forms)
output logic [P.DIVb+3:0] F output logic [P.DIVb+3:0] F // Q4.DIVb
); );
logic [P.DIVb+3:0] F2, F1, F0, FN1, FN2; logic [P.DIVb+3:0] F2, F1, F0, FN1, FN2; // Q4.DIVb
// Generate for both positive and negative bits // Generate for both positive and negative digits
assign F2 = (~U << 2) & (C << 2); assign F2 = (~U << 2) & (C << 2); //
assign F1 = ~(U << 1) & C; assign F1 = ~(U << 1) & C;
assign F0 = '0; assign F0 = '0;
assign FN1 = (UM << 1) | (C & ~(C << 3)); assign FN1 = (UM << 1) | (C & ~(C << 3));

View File

@ -57,7 +57,7 @@ module fdivsqrtfsm import cvw::*; #(parameter cvw_t P) (
// terminate immediately on special cases // terminate immediately on special cases
assign FSpecialCaseE = XZeroE | XInfE | XNaNE | (XsE&SqrtE) | (YZeroE | YInfE | YNaNE)&~SqrtE; assign FSpecialCaseE = XZeroE | XInfE | XNaNE | (XsE&SqrtE) | (YZeroE | YInfE | YNaNE)&~SqrtE;
if (P.IDIV_ON_FPU) assign SpecialCaseE = IntDivE ? ISpecialCaseE : FSpecialCaseE; if (P.IDIV_ON_FPU) assign SpecialCaseE = IntDivE ? ISpecialCaseE : FSpecialCaseE;
else assign SpecialCaseE = FSpecialCaseE; else assign SpecialCaseE = FSpecialCaseE;
flopenr #(1) SpecialCaseReg(clk, reset, IFDivStartE, SpecialCaseE, SpecialCaseM); // save SpecialCase for checking in fdivsqrtpostproc flopenr #(1) SpecialCaseReg(clk, reset, IFDivStartE, SpecialCaseE, SpecialCaseM); // save SpecialCase for checking in fdivsqrtpostproc
always_ff @(posedge clk) begin always_ff @(posedge clk) begin

View File

@ -104,14 +104,14 @@ module fdivsqrtiter import cvw::*; #(parameter cvw_t P) (
for(i=0; $unsigned(i)<P.DIVCOPIES; i++) begin : iterations for(i=0; $unsigned(i)<P.DIVCOPIES; i++) begin : iterations
if (P.RADIX == 2) begin: stage if (P.RADIX == 2) begin: stage
fdivsqrtstage2 #(P) fdivsqrtstage(.D, .DBar, .SqrtE, fdivsqrtstage2 #(P) fdivsqrtstage(.D, .DBar, .SqrtE,
.WS(WS[i]), .WC(WC[i]), .WSNext(WSNext[i]), .WCNext(WCNext[i]), .WS(WS[i]), .WC(WC[i]), .WSNext(WSNext[i]), .WCNext(WCNext[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 else begin: stage end else begin: stage
logic j1; logic j1;
assign j1 = (i == 0 & ~C[0][P.DIVb-1]); assign j1 = (i == 0 & ~C[0][P.DIVb-1]);
fdivsqrtstage4 #(P) fdivsqrtstage(.D, .DBar, .D2, .DBar2, .SqrtE, .j1, fdivsqrtstage4 #(P) fdivsqrtstage(.D, .DBar, .D2, .DBar2, .SqrtE, .j1,
.WS(WS[i]), .WC(WC[i]), .WSNext(WSNext[i]), .WCNext(WCNext[i]), .WS(WS[i]), .WC(WC[i]), .WSNext(WSNext[i]), .WCNext(WCNext[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
assign WS[i+1] = WSNext[i]; assign WS[i+1] = WSNext[i];
assign WC[i+1] = WCNext[i]; assign WC[i+1] = WCNext[i];

View File

@ -29,17 +29,18 @@
module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) ( module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
input logic clk, input logic clk,
input logic IFDivStartE, input logic IFDivStartE,
input logic [P.NF:0] Xm, Ym, input logic [P.NF:0] Xm, Ym, // Floating-point significands
input logic [P.NE-1:0] Xe, Ye, input logic [P.NE-1:0] Xe, Ye, // Floating-point exponents
input logic [P.FMTBITS-1:0] FmtE, input logic [P.FMTBITS-1:0] FmtE,
input logic SqrtE, input logic SqrtE,
input logic XZeroE, input logic XZeroE,
input logic [2:0] Funct3E, input logic [2:0] Funct3E,
output logic [P.NE+1:0] UeM, output logic [P.NE+1:0] UeM, // biased exponent of result
output logic [P.DIVb+3:0] X, D, output logic [P.DIVb+3:0] X, D, // Q4.DIVb
// Int-specific // Int-specific
input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // U(XLEN.0) inputs from IEU
input logic IntDivE, W64E, input logic IntDivE, W64E,
// Outputs
output logic ISpecialCaseE, output logic ISpecialCaseE,
output logic [P.DURLEN-1:0] CyclesE, output logic [P.DURLEN-1:0] CyclesE,
output logic [P.DIVBLEN-1:0] IntNormShiftM, output logic [P.DIVBLEN-1:0] IntNormShiftM,

View File

@ -18,7 +18,7 @@
// except in compliance with the License, or, at your option, the Apache License version 2.0. You // except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at // may obtain a copy of the License at
// //
// https://solderpad.org/licenses/SHL-2.1/ // httWS://solderpad.org/licenses/SHL-2.1/
// //
// Unless required by applicable law or agreed to in writing, any work distributed under the // Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, // License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
@ -27,27 +27,18 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module fdivsqrtqsel2 ( module fdivsqrtqsel2 (
input logic [3:0] ps, pc, input logic [3:0] WS, WC,
output logic up, uz, un output logic up, uz, un
); );
logic [3:0] p, g;
logic magnitude, sign; logic magnitude, sign;
// The quotient selection logic is presented for simplicity, not assign magnitude = ~((WS[2]^WC[2]) & (WS[1]^WC[1]) &
// for efficiency. You can probably optimize your logic to (WS[0]^WC[0]));
// select the proper divisor with less delay. assign sign = (WS[3]^WC[3])^
(WS[2] & WC[2] | ((WS[2]^WC[2]) &
// Quotient equations from EE371 lecture notes 13-20 (WS[1]&WC[1] | ((WS[1]^WC[1]) &
assign p = ps ^ pc; (WS[0]&WC[0])))));
assign g = ps & pc;
assign magnitude = ~((ps[2]^pc[2]) & (ps[1]^pc[1]) &
(ps[0]^pc[0]));
assign sign = (ps[3]^pc[3])^
(ps[2] & pc[2] | ((ps[2]^pc[2]) &
(ps[1]&pc[1] | ((ps[1]^pc[1]) &
(ps[0]&pc[0])))));
// Produce digit = +1, 0, or -1 // Produce digit = +1, 0, or -1
assign up = magnitude & ~sign; assign up = magnitude & ~sign;

View File

@ -33,8 +33,8 @@ module fdivsqrtstage2 import cvw::*; #(parameter cvw_t P) (
input logic [P.DIVb:0] U, UM, // U1.DIVb input logic [P.DIVb:0] U, UM, // U1.DIVb
input logic [P.DIVb+3:0] WS, WC, // Q4.DIVb input logic [P.DIVb+3:0] WS, WC, // Q4.DIVb
input logic [P.DIVb+1:0] C, // Q2.DIVb input logic [P.DIVb+1:0] C, // Q2.DIVb
input logic SqrtE, input logic SqrtE,
output logic un, output logic un,
output logic [P.DIVb+1:0] CNext, // Q2.DIVb output logic [P.DIVb+1:0] CNext, // Q2.DIVb
output logic [P.DIVb:0] UNext, UMNext, // U1.DIVb output logic [P.DIVb:0] UNext, UMNext, // U1.DIVb
output logic [P.DIVb+3:0] WSNext, WCNext // Q4.DIVb output logic [P.DIVb+3:0] WSNext, WCNext // Q4.DIVb
@ -42,19 +42,13 @@ module fdivsqrtstage2 import cvw::*; #(parameter cvw_t P) (
/* verilator lint_on UNOPTFLAT */ /* verilator lint_on UNOPTFLAT */
logic [P.DIVb+3:0] Dsel; // Q4.DIVb logic [P.DIVb+3:0] Dsel; // Q4.DIVb
logic up, uz; logic up, uz;
logic [P.DIVb+3:0] F; // Q4.DIVb logic [P.DIVb+3:0] F; // Q4.DIVb
logic [P.DIVb+3:0] AddIn; // Q4.DIVb logic [P.DIVb+3:0] AddIn; // Q4.DIVb
logic [P.DIVb+3:0] WSA, WCA; // Q4.DIVb logic [P.DIVb+3:0] WSA, WCA; // Q4.DIVb
// Qmient Selection logic // Quotient Selection logic
// Given partial remainder, select digit of +1, 0, or -1 (up, uz, un) // Given partial remainder, select digit of +1, 0, or -1 (up, uz, un)
// q encoding:
// 1000 = +2
// 0100 = +1
// 0000 = 0
// 0010 = -1
// 0001 = -2
fdivsqrtqsel2 qsel2(WS[P.DIVb+3:P.DIVb], WC[P.DIVb+3:P.DIVb], up, uz, un); fdivsqrtqsel2 qsel2(WS[P.DIVb+3:P.DIVb], WC[P.DIVb+3:P.DIVb], up, uz, un);
// Sqrt F generation. Extend C, U, UM to Q4.k // Sqrt F generation. Extend C, U, UM to Q4.k
@ -66,7 +60,7 @@ module fdivsqrtstage2 import cvw::*; #(parameter cvw_t P) (
else if (uz) Dsel = '0; else if (uz) Dsel = '0;
else Dsel = D; // un else Dsel = D; // un
// Partial Product Generation // Residual Generation
// WSA, WCA = WS + WC - qD // WSA, WCA = WS + WC - qD
mux2 #(P.DIVb+4) addinmux(Dsel, F, SqrtE, AddIn); mux2 #(P.DIVb+4) addinmux(Dsel, F, SqrtE, AddIn);
csa #(P.DIVb+4) csa(WS, WC, AddIn, up&~SqrtE, WSA, WCA); csa #(P.DIVb+4) csa(WS, WC, AddIn, up&~SqrtE, WSA, WCA);