mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge pull request #467 from davidharrishmc/main
Sanity in FDIVSQRT bit counts
This commit is contained in:
commit
4c2a9c7bab
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
);
|
);
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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));
|
||||||
|
Loading…
Reference in New Issue
Block a user