Merge pull request #467 from davidharrishmc/main

Sanity in FDIVSQRT bit counts
This commit is contained in:
Rose Thompson 2023-11-11 16:37:25 -08:00 committed by GitHub
commit 4c2a9c7bab
13 changed files with 111 additions and 113 deletions

View File

@ -93,20 +93,20 @@ localparam NF2 = ((F_SUPPORTED & (LEN1 != S_LEN)) ? S_NF : H_NF);
localparam FMT2 = ((F_SUPPORTED & (LEN1 != S_LEN)) ? 2'd0 : 2'd2); localparam FMT2 = ((F_SUPPORTED & (LEN1 != S_LEN)) ? 2'd0 : 2'd2);
localparam BIAS2 = ((F_SUPPORTED & (LEN1 != S_LEN)) ? S_BIAS : H_BIAS); localparam BIAS2 = ((F_SUPPORTED & (LEN1 != S_LEN)) ? S_BIAS : H_BIAS);
// intermediate division parameters not directly used in Divider // divider r and rk (bits per digit, bits per cycle)
localparam FPDIVN = NF+3; // length of floating-point inputs: Ns + 2 = Nf + 3 for 1 integer bit, Nf fracitonal bits, 2 extra bits to shift sqrt into [1/4, 1)] localparam LOGR = $clog2(RADIX); // r = log(R) bits per digit
localparam DIVN = ((FPDIVN<XLEN) & IDIV_ON_FPU) ? XLEN : FPDIVN+3; // standard length of input: max(XLEN, NF+2) *** localparam RK = LOGR*DIVCOPIES; // r*k bits per cycle generated
// intermediate division parameters not directly used in fdivsqrt hardware
localparam FPDIVMINb = NF + 3; // minimum length of fractional part: Nf result bits + guard and round bits + 1 extra bit because square root could be shifted right *** explain better
localparam DIVMINb = ((FPDIVMINb<XLEN) & IDIV_ON_FPU) ? XLEN : FPDIVMINb; // minimum fractional bits b = max(XLEN, FPDIVMINb)
localparam RESBITS = DIVMINb + LOGR; // number of bits in a result: r integer + b fractional
// division constants // division constants
localparam FPDUR = (RESBITS-1)/RK + 1 ; // ceiling((r+b)/rk)
// *** define NF+2, justify, use in DIVN localparam DIVb = FPDUR*RK - LOGR; // divsqrt fractional bits, so total number of bits is a multiple of rk after r integer bits
localparam LOGR = $clog2(RADIX); // r = log(R) localparam DURLEN = $clog2(FPDUR); // enough bits to count the duration
localparam RK = LOGR*DIVCOPIES; // r*k bits per cycle generated localparam DIVBLEN = $clog2(DIVb); // enough bits to count number of fractional bits
//localparam FPDUR = (DIVN+1)/RK + 1 + (RADIX/4); // *** relate to algorithm for rest of these
localparam FPDUR = (DIVN+LOGR-1)/RK + 1 ; // ceiling((DIVN+LOGR)/RK)
localparam DURLEN = $clog2(FPDUR+1);
localparam DIVb = FPDUR*RK - 1; // canonical fdiv size (b)
localparam DIVBLEN = $clog2(DIVb+2)-1; // *** where is 2 coming from?
// largest length in IEU/FPU // largest length in IEU/FPU
localparam CVTLEN = ((NF<XLEN) ? (XLEN) : (NF)); // max(XLEN, NF) localparam CVTLEN = ((NF<XLEN) ? (XLEN) : (NF)); // max(XLEN, NF)
@ -114,7 +114,7 @@ localparam LLEN = (($unsigned(FLEN)<$unsigned(XLEN)) ? ($unsigned(XLEN)) : ($uns
localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1)); localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1));
localparam NORMSHIFTSZ = (((CVTLEN+NF+1)>(DIVb + 1 +NF+1) & (CVTLEN+NF+1)>(3*NF+6)) ? (CVTLEN+NF+1) : ((DIVb + 1 +NF+1) > (3*NF+6) ? (DIVb + 1 +NF+1) : (3*NF+6))); localparam NORMSHIFTSZ = (((CVTLEN+NF+1)>(DIVb + 1 +NF+1) & (CVTLEN+NF+1)>(3*NF+6)) ? (CVTLEN+NF+1) : ((DIVb + 1 +NF+1) > (3*NF+6) ? (DIVb + 1 +NF+1) : (3*NF+6)));
localparam LOGNORMSHIFTSZ = ($clog2(NORMSHIFTSZ)); localparam LOGNORMSHIFTSZ = ($clog2(NORMSHIFTSZ));
localparam CORRSHIFTSZ = (((CVTLEN+NF+1)>(DIVb + 1 +NF+1) & (CVTLEN+NF+1)>(3*NF+6)) ? (CVTLEN+NF+1) : ((DIVN+1+NF) > (3*NF+4) ? (DIVN+1+NF) : (3*NF+4))); localparam CORRSHIFTSZ = (((CVTLEN+NF+1)>(DIVb + 1 +NF+1) & (CVTLEN+NF+1)>(3*NF+6)) ? (CVTLEN+NF+1) : ((DIVMINb+1+NF) > (3*NF+4) ? (DIVMINb+1+NF) : (3*NF+4)));
// Disable spurious Verilator warnings // Disable spurious Verilator warnings

View File

@ -67,7 +67,7 @@ module fdivsqrt import cvw::*; #(parameter cvw_t P) (
// Integer div/rem signals // Integer div/rem signals
logic BZeroM; // Denominator is zero logic BZeroM; // Denominator is zero
logic IntDivM; // Integer operation logic IntDivM; // Integer operation
logic [P.DIVBLEN:0] IntNormShiftM; // Integer normalizatoin shift amount logic [P.DIVBLEN-1:0] IntNormShiftM; // Integer normalizatoin shift amount
logic ALTBM, AsM, BsM, W64M; // Special handling for postprocessor logic ALTBM, AsM, BsM, W64M; // Special handling for postprocessor
logic [P.XLEN-1:0] AM; // Original Numerator for postprocessor logic [P.XLEN-1:0] AM; // Original Numerator for postprocessor
logic ISpecialCaseE; // Integer div/remainder special cases logic ISpecialCaseE; // Integer div/remainder special cases

View File

@ -30,16 +30,11 @@ module fdivsqrtcycles import cvw::*; #(parameter cvw_t P) (
input logic [P.FMTBITS-1:0] FmtE, input logic [P.FMTBITS-1:0] FmtE,
input logic SqrtE, input logic SqrtE,
input logic IntDivE, input logic IntDivE,
input logic [P.DIVBLEN:0] IntResultBitsE, input logic [P.DIVBLEN-1:0] IntResultBitsE,
output logic [P.DURLEN-1:0] CyclesE output logic [P.DURLEN-1:0] CyclesE
); );
logic [P.DURLEN+1:0] Nf, FPResultBitsE; // number of fractional bits logic [P.DIVBLEN-1:0] Nf, FPResultBitsE, ResultBitsE; // number of fractional (result) bits
logic [P.DIVBLEN:0] ResultBitsE; // number of result bits;
// DIVN = P.NF+3
// NS = NF + 1
// N = NS or NS+2 for div/sqrt.
/* verilator lint_off WIDTH */ /* verilator lint_off WIDTH */
if (P.FPSIZES == 1) if (P.FPSIZES == 1)
@ -75,7 +70,7 @@ module fdivsqrtcycles import cvw::*; #(parameter cvw_t P) (
// The datapath produces rk bits per cycle, so Cycles = ceil (ResultBitsE / rk) // The datapath produces rk bits per cycle, so Cycles = ceil (ResultBitsE / rk)
always_comb begin always_comb begin
if (SqrtE) FPResultBitsE = Nf + 2 + 0; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2 *** unclear why it works with just +1 and +0 rather than +2; is it related to DIVCOPIES logic below? if (SqrtE) FPResultBitsE = Nf + 2 + 0; // Nf + two fractional bits for round/guard; integer bit implicit
else FPResultBitsE = Nf + 2 + P.LOGR; // Nf + two fractional bits for round/guard + integer bits - try this when placing results in msbs else FPResultBitsE = Nf + 2 + P.LOGR; // Nf + two fractional bits for round/guard + integer bits - try this when placing results in msbs
if (P.IDIV_ON_FPU) ResultBitsE = IntDivE ? IntResultBitsE : FPResultBitsE; if (P.IDIV_ON_FPU) ResultBitsE = IntDivE ? IntResultBitsE : FPResultBitsE;

View File

@ -31,7 +31,7 @@ module fdivsqrtexpcalc import cvw::*; #(parameter cvw_t P) (
input logic [P.NE-1:0] Xe, Ye, input logic [P.NE-1:0] Xe, Ye,
input logic Sqrt, input logic Sqrt,
input logic XZero, input logic XZero,
input logic [P.DIVBLEN:0] ell, m, input logic [P.DIVBLEN-1:0] ell, m,
output logic [P.NE+1:0] Ue output logic [P.NE+1:0] Ue
); );

View File

@ -31,31 +31,31 @@ module fdivsqrtiter import cvw::*; #(parameter cvw_t P) (
input logic IFDivStartE, input logic IFDivStartE,
input logic FDivBusyE, input logic FDivBusyE,
input logic SqrtE, input logic SqrtE,
input logic [P.DIVb+3:0] X, D, input logic [P.DIVb+3:0] X, D, // Q4.DIVb
output logic [P.DIVb:0] FirstU, FirstUM, output logic [P.DIVb:0] FirstU, FirstUM, // U1.DIVb
output logic [P.DIVb+1:0] FirstC, output logic [P.DIVb+1:0] FirstC, // Q2.DIVb
output logic Firstun, output logic Firstun,
output logic [P.DIVb+3:0] FirstWS, FirstWC output logic [P.DIVb+3:0] FirstWS, FirstWC // Q4.DIVb
); );
/* verilator lint_off UNOPTFLAT */ /* verilator lint_off UNOPTFLAT */
logic [P.DIVb+3:0] WSNext[P.DIVCOPIES-1:0]; // Q4.b logic [P.DIVb+3:0] WSNext[P.DIVCOPIES-1:0]; // Q4.DIVb
logic [P.DIVb+3:0] WCNext[P.DIVCOPIES-1:0]; // Q4.b logic [P.DIVb+3:0] WCNext[P.DIVCOPIES-1:0]; // Q4.DIVb
logic [P.DIVb+3:0] WS[P.DIVCOPIES:0]; // Q4.b logic [P.DIVb+3:0] WS[P.DIVCOPIES:0]; // Q4.DIVb
logic [P.DIVb+3:0] WC[P.DIVCOPIES:0]; // Q4.b logic [P.DIVb+3:0] WC[P.DIVCOPIES:0]; // Q4.DIVb
logic [P.DIVb:0] U[P.DIVCOPIES:0]; // U1.b logic [P.DIVb:0] U[P.DIVCOPIES:0]; // U1.DIVb
logic [P.DIVb:0] UM[P.DIVCOPIES:0]; // U1.b logic [P.DIVb:0] UM[P.DIVCOPIES:0]; // U1.DIVb
logic [P.DIVb:0] UNext[P.DIVCOPIES-1:0]; // U1.b logic [P.DIVb:0] UNext[P.DIVCOPIES-1:0]; // U1.DIVb
logic [P.DIVb:0] UMNext[P.DIVCOPIES-1:0]; // U1.b logic [P.DIVb:0] UMNext[P.DIVCOPIES-1:0]; // U1.DIVb
logic [P.DIVb+1:0] C[P.DIVCOPIES:0]; // Q2.b logic [P.DIVb+1:0] C[P.DIVCOPIES:0]; // Q2.DIVb
logic [P.DIVb+1:0] initC; // Q2.b logic [P.DIVb+1:0] initC; // Q2.DIVb
logic [P.DIVCOPIES-1:0] un; logic [P.DIVCOPIES-1:0] un;
logic [P.DIVb+3:0] WSN, WCN; // Q4.b logic [P.DIVb+3:0] WSN, WCN; // Q4.DIVb
logic [P.DIVb+3:0] DBar, D2, DBar2; // Q4.b logic [P.DIVb+3:0] DBar, D2, DBar2; // Q4.DIVb
logic [P.DIVb+1:0] NextC; logic [P.DIVb+1:0] NextC; // Q2.DIVb
logic [P.DIVb:0] UMux, UMMux; logic [P.DIVb:0] UMux, UMMux; // U1.DIVb
logic [P.DIVb:0] initU, initUM; logic [P.DIVb:0] initU, initUM; // U1.DIVb
/* verilator lint_on UNOPTFLAT */ /* verilator lint_on UNOPTFLAT */
// Top Muxes and Registers // Top Muxes and Registers

View File

@ -27,21 +27,21 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module fdivsqrtpostproc import cvw::*; #(parameter cvw_t P) ( module fdivsqrtpostproc import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
input logic StallM, input logic StallM,
input logic [P.DIVb+3:0] WS, WC, input logic [P.DIVb+3:0] WS, WC, // Q4.DIVb
input logic [P.DIVb+3:0] D, input logic [P.DIVb+3:0] D, // Q4.DIVb
input logic [P.DIVb:0] FirstU, FirstUM, input logic [P.DIVb:0] FirstU, FirstUM, // U1.DIVb
input logic [P.DIVb+1:0] FirstC, input logic [P.DIVb+1:0] FirstC, // Q2.DIVb
input logic SqrtE, input logic SqrtE,
input logic Firstun, SqrtM, SpecialCaseM, input logic Firstun, SqrtM, SpecialCaseM,
input logic [P.XLEN-1:0] AM, input logic [P.XLEN-1:0] AM, // U/Q(XLEN.0)
input logic RemOpM, ALTBM, BZeroM, AsM, BsM, W64M, input logic RemOpM, ALTBM, BZeroM, AsM, BsM, W64M,
input logic [P.DIVBLEN:0] IntNormShiftM, input logic [P.DIVBLEN-1:0] IntNormShiftM,
output logic [P.DIVb:0] UmM, // result significand output logic [P.DIVb:0] UmM, // U1.DIVb result significand
output logic WZeroE, output logic WZeroE,
output logic DivStickyM, output logic DivStickyM,
output logic [P.XLEN-1:0] FIntDivResultM output logic [P.XLEN-1:0] FIntDivResultM // U/Q(XLEN.0)
); );
logic [P.DIVb+3:0] W, Sum; logic [P.DIVb+3:0] W, Sum;

View File

@ -42,7 +42,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
input logic IntDivE, W64E, input logic IntDivE, W64E,
output logic ISpecialCaseE, output logic ISpecialCaseE,
output logic [P.DURLEN-1:0] CyclesE, output logic [P.DURLEN-1:0] CyclesE,
output logic [P.DIVBLEN:0] IntNormShiftM, output logic [P.DIVBLEN-1:0] IntNormShiftM,
output logic ALTBM, IntDivM, W64M, output logic ALTBM, IntDivM, W64M,
output logic AsM, BsM, BZeroM, output logic AsM, BsM, BZeroM,
output logic [P.XLEN-1:0] AM output logic [P.XLEN-1:0] AM
@ -53,8 +53,8 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
logic [P.DIVb+3:0] DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed logic [P.DIVb+3:0] DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed
logic [P.NE+1:0] UeE; // Result Exponent (FP only) logic [P.NE+1:0] UeE; // Result Exponent (FP only)
logic [P.DIVb:0] IFX, IFD; // Correctly-sized inputs for iterator, selected from int or fp input logic [P.DIVb:0] IFX, IFD; // Correctly-sized inputs for iterator, selected from int or fp input
logic [P.DIVBLEN:0] mE, ell; // Leading zeros of inputs logic [P.DIVBLEN-1:0] mE, ell; // Leading zeros of inputs
logic [P.DIVBLEN:0] IntResultBitsE; // bits in integer result logic [P.DIVBLEN-1:0] IntResultBitsE; // bits in integer result
logic NumerZeroE; // Numerator is zero (X or A) logic NumerZeroE; // Numerator is zero (X or A)
logic AZeroE, BZeroE; // A or B is Zero for integer division logic AZeroE, BZeroE; // A or B is Zero for integer division
logic SignedDivE; // signed division logic SignedDivE; // signed division
@ -118,12 +118,12 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
if (P.IDIV_ON_FPU) begin:intrightshift // Int Supported if (P.IDIV_ON_FPU) begin:intrightshift // Int Supported
logic [P.DIVBLEN:0] ZeroDiff, p; logic [P.DIVBLEN-1:0] ZeroDiff, p;
// calculate number of fractional bits p // calculate number of fractional bits p
assign ZeroDiff = mE - ell; // Difference in number of leading zeros assign ZeroDiff = mE - ell; // Difference in number of leading zeros
assign ALTBE = ZeroDiff[P.DIVBLEN]; // A less than B (A has more leading zeros) assign ALTBE = ZeroDiff[P.DIVBLEN-1]; // A less than B (A has more leading zeros)
mux2 #(P.DIVBLEN+1) pmux(ZeroDiff, '0, ALTBE, p); mux2 #(P.DIVBLEN) pmux(ZeroDiff, '0, ALTBE, p);
/* verilator lint_off WIDTH */ /* verilator lint_off WIDTH */
assign IntResultBitsE = P.LOGR + p; // Total number of result bits (r integer bits plus p fractional bits) assign IntResultBitsE = P.LOGR + p; // Total number of result bits (r integer bits plus p fractional bits)
@ -192,7 +192,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
fdivsqrtcycles #(P) cyclecalc(.FmtE, .SqrtE, .IntDivE, .IntResultBitsE, .CyclesE); fdivsqrtcycles #(P) cyclecalc(.FmtE, .SqrtE, .IntDivE, .IntResultBitsE, .CyclesE);
if (P.IDIV_ON_FPU) begin:intpipelineregs if (P.IDIV_ON_FPU) begin:intpipelineregs
logic [P.DIVBLEN:0] IntDivNormShiftE, IntRemNormShiftE, IntNormShiftE; logic [P.DIVBLEN-1:0] IntDivNormShiftE, IntRemNormShiftE, IntNormShiftE;
logic RemOpE; logic RemOpE;
/* verilator lint_off WIDTH */ /* verilator lint_off WIDTH */
@ -200,7 +200,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
assign IntRemNormShiftE = mE + (P.DIVb-(P.XLEN-1)); // m + b - (N-1) for remainder normalization shift assign IntRemNormShiftE = mE + (P.DIVb-(P.XLEN-1)); // m + b - (N-1) for remainder normalization shift
/* verilator lint_on WIDTH */ /* verilator lint_on WIDTH */
assign RemOpE = Funct3E[1]; assign RemOpE = Funct3E[1];
mux2 #(P.DIVBLEN+1) normshiftmux(IntDivNormShiftE, IntRemNormShiftE, RemOpE, IntNormShiftE); mux2 #(P.DIVBLEN) normshiftmux(IntDivNormShiftE, IntRemNormShiftE, RemOpE, IntNormShiftE);
// pipeline registers // pipeline registers
flopen #(1) mdureg(clk, IFDivStartE, IntDivE, IntDivM); flopen #(1) mdureg(clk, IFDivStartE, IntDivE, IntDivM);
@ -208,7 +208,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
flopen #(1) bzeroreg(clk, IFDivStartE, BZeroE, BZeroM); flopen #(1) bzeroreg(clk, IFDivStartE, BZeroE, BZeroM);
flopen #(1) asignreg(clk, IFDivStartE, AsE, AsM); flopen #(1) asignreg(clk, IFDivStartE, AsE, AsM);
flopen #(1) bsignreg(clk, IFDivStartE, BsE, BsM); flopen #(1) bsignreg(clk, IFDivStartE, BsE, BsM);
flopen #(P.DIVBLEN+1) nsreg(clk, IFDivStartE, IntNormShiftE, IntNormShiftM); flopen #(P.DIVBLEN) nsreg(clk, IFDivStartE, IntNormShiftE, IntNormShiftM);
flopen #(P.XLEN) srcareg(clk, IFDivStartE, AE, AM); flopen #(P.XLEN) srcareg(clk, IFDivStartE, AE, AM);
if (P.XLEN==64) if (P.XLEN==64)
flopen #(1) w64reg(clk, IFDivStartE, W64E, W64M); flopen #(1) w64reg(clk, IFDivStartE, W64E, W64M);

View File

@ -27,9 +27,9 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module fdivsqrtqsel4cmp ( module fdivsqrtqsel4cmp (
input logic [2:0] Dmsbs, input logic [2:0] Dmsbs, // U0.3 fractional bits after implicit leading 1
input logic [4:0] Smsbs, input logic [4:0] Smsbs, // U1.4 leading bits of square root approximation
input logic [7:0] WSmsbs, WCmsbs, input logic [7:0] WSmsbs, WCmsbs, // Q4.4
input logic SqrtE, j1, input logic SqrtE, j1,
output logic [3:0] udigit output logic [3:0] udigit
); );

View File

@ -29,23 +29,23 @@
/* verilator lint_off UNOPTFLAT */ /* verilator lint_off UNOPTFLAT */
module fdivsqrtstage2 import cvw::*; #(parameter cvw_t P) ( module fdivsqrtstage2 import cvw::*; #(parameter cvw_t P) (
input logic [P.DIVb+3:0] D, DBar, input logic [P.DIVb+3:0] D, DBar, // Q4.DIVb
input logic [P.DIVb:0] U, UM, input logic [P.DIVb:0] U, UM, // U1.DIVb
input logic [P.DIVb+3:0] WS, WC, input logic [P.DIVb+3:0] WS, WC, // Q4.DIVb
input logic [P.DIVb+1:0] C, 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, output logic [P.DIVb+1:0] CNext, // Q2.DIVb
output logic [P.DIVb:0] UNext, UMNext, output logic [P.DIVb:0] UNext, UMNext, // U1.DIVb
output logic [P.DIVb+3:0] WSNext, WCNext output logic [P.DIVb+3:0] WSNext, WCNext // Q4.DIVb
); );
/* verilator lint_on UNOPTFLAT */ /* verilator lint_on UNOPTFLAT */
logic [P.DIVb+3:0] Dsel; logic [P.DIVb+3:0] Dsel; // Q4.DIVb
logic up, uz; logic up, uz;
logic [P.DIVb+3:0] F; logic [P.DIVb+3:0] F; // Q4.DIVb
logic [P.DIVb+3:0] AddIn; logic [P.DIVb+3:0] AddIn; // Q4.DIVb
logic [P.DIVb+3:0] WSA, WCA; logic [P.DIVb+3:0] WSA, WCA; // Q4.DIVb
// Qmient Selection logic // Qmient 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)

View File

@ -27,26 +27,26 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module fdivsqrtstage4 import cvw::*; #(parameter cvw_t P) ( module fdivsqrtstage4 import cvw::*; #(parameter cvw_t P) (
input logic [P.DIVb+3:0] D, DBar, D2, DBar2, input logic [P.DIVb+3:0] D, DBar, D2, DBar2, // Q4.DIVb
input logic [P.DIVb:0] U,UM, input logic [P.DIVb:0] U,UM, // U1.DIVb
input logic [P.DIVb+3:0] WS, WC, input logic [P.DIVb+3:0] WS, WC, // Q4.DIVb
input logic [P.DIVb+1:0] C, input logic [P.DIVb+1:0] C, // Q2.DIVb
input logic SqrtE, j1, input logic SqrtE, j1,
output logic [P.DIVb+1:0] CNext, output logic [P.DIVb+1:0] CNext, // Q2.DIVb
output logic un, output logic un,
output logic [P.DIVb:0] UNext, UMNext, output logic [P.DIVb:0] UNext, UMNext, // U1.DIVb
output logic [P.DIVb+3:0] WSNext, WCNext output logic [P.DIVb+3:0] WSNext, WCNext // Q4.DIVb
); );
logic [P.DIVb+3:0] Dsel; logic [P.DIVb+3:0] Dsel; // Q4.DIVb
logic [3:0] udigit; logic [3:0] udigit;
logic [P.DIVb+3:0] F; logic [P.DIVb+3:0] F; // Q4.DIVb
logic [P.DIVb+3:0] AddIn; logic [P.DIVb+3:0] AddIn; // Q4.DIVb
logic [4:0] Smsbs; logic [4:0] Smsbs;
logic [2:0] Dmsbs; logic [2:0] Dmsbs;
logic [7:0] WCmsbs, WSmsbs; logic [7:0] WCmsbs, WSmsbs;
logic CarryIn; logic CarryIn;
logic [P.DIVb+3:0] WSA, WCA; logic [P.DIVb+3:0] WSA, WCA; // Q4.DIVb
// Digit Selection logic // Digit Selection logic
// u encoding: // u encoding:
@ -55,10 +55,10 @@ module fdivsqrtstage4 import cvw::*; #(parameter cvw_t P) (
// 0000 = 0 // 0000 = 0
// 0010 = -1 // 0010 = -1
// 0001 = -2 // 0001 = -2
assign Smsbs = U[P.DIVb:P.DIVb-4]; assign Smsbs = U[P.DIVb:P.DIVb-4]; // U1.4 most significant bits of square root
assign Dmsbs = D[P.DIVb-1:P.DIVb-3]; assign Dmsbs = D[P.DIVb-1:P.DIVb-3]; // U0.3 most significant fractional bits of divisor after leading 1
assign WCmsbs = WC[P.DIVb+3:P.DIVb-4]; assign WCmsbs = WC[P.DIVb+3:P.DIVb-4]; // Q4.4 most significant bits of residual
assign WSmsbs = WS[P.DIVb+3:P.DIVb-4]; assign WSmsbs = WS[P.DIVb+3:P.DIVb-4]; // Q4.4 most significant bits of residual
fdivsqrtqsel4cmp qsel4(.Dmsbs, .Smsbs, .WSmsbs, .WCmsbs, .SqrtE, .j1, .udigit); fdivsqrtqsel4cmp qsel4(.Dmsbs, .Smsbs, .WSmsbs, .WCmsbs, .SqrtE, .j1, .udigit);
assign un = 1'b0; // unused for radix 4 assign un = 1'b0; // unused for radix 4

View File

@ -31,15 +31,15 @@
/////////////////////////////// ///////////////////////////////
module fdivsqrtuotfc2 import cvw::*; #(parameter cvw_t P) ( module fdivsqrtuotfc2 import cvw::*; #(parameter cvw_t P) (
input logic up, un, input logic up, un,
input logic [P.DIVb+1:0] C, input logic [P.DIVb+1:0] C, // Q2.DIVb
input logic [P.DIVb:0] U, UM, input logic [P.DIVb:0] U, UM, // U1.DIVb
output logic [P.DIVb:0] UNext, UMNext output logic [P.DIVb:0] UNext, UMNext // U1.DIVb
); );
// The on-the-fly converter transfers the divsqrt // The on-the-fly converter transfers the divsqrt
// bits to the quotient as they come. // bits to the quotient as they come.
logic [P.DIVb:0] K; logic [P.DIVb:0] K; // U1.DIVb one-hot
assign K = (C[P.DIVb:0] & ~(C[P.DIVb:0] << 1)); // Thermometer to one hot encoding assign K = (C[P.DIVb:0] & ~(C[P.DIVb:0] << 1)); // Thermometer to one hot encoding
always_comb begin always_comb begin
if (up) begin if (up) begin

View File

@ -28,15 +28,15 @@
module fdivsqrtuotfc4 import cvw::*; #(parameter cvw_t P) ( module fdivsqrtuotfc4 import cvw::*; #(parameter cvw_t P) (
input logic [3:0] udigit, input logic [3:0] udigit,
input logic [P.DIVb:0] U, UM, input logic [P.DIVb:0] U, UM, // U1.DIVb
input logic [P.DIVb:0] C, input logic [P.DIVb:0] C, // Q1.DIVb
output logic [P.DIVb:0] UNext, UMNext output logic [P.DIVb:0] UNext, UMNext // U1.DIVb
); );
// The on-the-fly converter transfers the square root // The on-the-fly converter transfers the square root
// bits to the quotient as they come. // bits to the quotient as they come.
// Use this otfc for division and square root. // Use this otfc for division and square root.
logic [P.DIVb:0] K1, K2, K3; logic [P.DIVb:0] K1, K2, K3; // U1.DIVb
assign K1 = (C&~(C << 1)); // K assign K1 = (C&~(C << 1)); // K
assign K2 = ((C << 1)&~(C << 2)); // 2K assign K2 = ((C << 1)&~(C << 2)); // 2K
assign K3 = (C & ~(C << 2)); // 3K assign K3 = (C & ~(C << 2)); // 3K

View File

@ -115,8 +115,8 @@ module testbenchfp;
logic FlushE; logic FlushE;
logic IFDivStartE; logic IFDivStartE;
logic FDivDoneE; logic FDivDoneE;
logic [P.NE+1:0] QeM; logic [P.NE+1:0] UeM;
logic [P.DIVb:0] QmM; logic [P.DIVb:0] UmM;
logic [P.XLEN-1:0] FIntDivResultM; logic [P.XLEN-1:0] FIntDivResultM;
logic ResMatch; // Check if result match logic ResMatch; // Check if result match
logic FlagMatch; // Check if IEEE flags match logic FlagMatch; // Check if IEEE flags match
@ -145,9 +145,12 @@ module testbenchfp;
initial begin initial begin
// Information displayed for user on what is simulating // Information displayed for user on what is simulating
$display("\nThe start of simulation..."); //$display("\nThe start of simulation...");
$display("This simulation for TEST is %s", TEST); //$display("This simulation for TEST is %s", TEST);
$display("This simulation for TEST is of the operand size of %s", TEST_SIZE); //$display("This simulation for TEST is of the operand size of %s", TEST_SIZE);
// $display("FPDUR %d %d DIVN %d LOGR %d RK %d RADIX %d DURLEN %d", FPDUR, DIVN, LOGR, RK, RADIX, DURLEN);
if (P.Q_SUPPORTED & (TEST_SIZE == "QP" | TEST_SIZE == "all")) begin // if Quad percision is supported if (P.Q_SUPPORTED & (TEST_SIZE == "QP" | TEST_SIZE == "all")) begin // if Quad percision is supported
if (TEST === "cvtint" | TEST === "all") begin // if testing integer conversion if (TEST === "cvtint" | TEST === "all") begin // if testing integer conversion
// add the 128-bit cvtint tests to the to-be-tested list // add the 128-bit cvtint tests to the to-be-tested list
@ -649,7 +652,7 @@ module testbenchfp;
string tt0; string tt0;
tt0 = $psprintf("%s", Tests[TestNum]); tt0 = $psprintf("%s", Tests[TestNum]);
testname = {pp, tt0}; testname = {pp, tt0};
$display("Here you are %s", testname); //$display("Here you are %s", testname);
$display("\n\nRunning %s vectors ", Tests[TestNum]); $display("\n\nRunning %s vectors ", Tests[TestNum]);
$readmemh(testname, TestVectors); $readmemh(testname, TestVectors);
// set the test index to 0 // set the test index to 0
@ -705,7 +708,7 @@ module testbenchfp;
end end
postprocess #(P) postprocess(.Xs(Xs), .Ys(Ys), .PostProcSel(UnitVal[1:0]), postprocess #(P) postprocess(.Xs(Xs), .Ys(Ys), .PostProcSel(UnitVal[1:0]),
.OpCtrl(OpCtrlVal), .DivQm(Quot), .DivQe(DivCalcExp), .OpCtrl(OpCtrlVal), .DivUm(Quot), .DivUe(DivCalcExp),
.Xm(Xm), .Ym(Ym), .Zm(Zm), .CvtCe(CvtCalcExpE), .DivSticky(DivSticky), .FmaSs(Ss), .Xm(Xm), .Ym(Ym), .Zm(Zm), .CvtCe(CvtCalcExpE), .DivSticky(DivSticky), .FmaSs(Ss),
.XNaN(XNaN), .YNaN(YNaN), .ZNaN(ZNaN), .CvtResSubnormUf(CvtResSubnormUfE), .XNaN(XNaN), .YNaN(YNaN), .ZNaN(ZNaN), .CvtResSubnormUf(CvtResSubnormUfE),
.XZero(XZero), .YZero(YZero), .CvtShiftAmt(CvtShiftAmtE), .XZero(XZero), .YZero(YZero), .CvtShiftAmt(CvtShiftAmtE),
@ -734,8 +737,8 @@ module testbenchfp;
.XInfE(XInf), .YInfE(YInf), .XZeroE(XZero), .YZeroE(YZero), .XInfE(XInf), .YInfE(YInf), .XZeroE(XZero), .YZeroE(YZero),
.XNaNE(XNaN), .YNaNE(YNaN), .XNaNE(XNaN), .YNaNE(YNaN),
.FDivStartE(DivStart), .IDivStartE(1'b0), .W64E(1'b0), .FDivStartE(DivStart), .IDivStartE(1'b0), .W64E(1'b0),
.StallM(1'b0), .DivStickyM(DivSticky), .FDivBusyE, .QeM(DivCalcExp), .StallM(1'b0), .DivStickyM(DivSticky), .FDivBusyE, .UeM(DivCalcExp),
.QmM(Quot), .UmM(Quot),
.FlushE(1'b0), .ForwardedSrcAE('0), .ForwardedSrcBE('0), .Funct3M(Funct3M), .FlushE(1'b0), .ForwardedSrcAE('0), .ForwardedSrcBE('0), .Funct3M(Funct3M),
.Funct3E(Funct3E), .IntDivE(1'b0), .FIntDivResultM(FIntDivResultM), .Funct3E(Funct3E), .IntDivE(1'b0), .FIntDivResultM(FIntDivResultM),
.FDivDoneE(FDivDoneE), .IFDivStartE(IFDivStartE)); .FDivDoneE(FDivDoneE), .IFDivStartE(IFDivStartE));