2024-03-14 21:07:15 +00:00
//max function
`define max(a,b) (((a) > (b)) ? (a) : (b))
2023-05-24 17:44:42 +00:00
// constants defining different privilege modes
// defined in Table 1.1 of the privileged spec
localparam M_MODE = (2'b11);
localparam S_MODE = (2'b01);
localparam U_MODE = (2'b00);
// Virtual Memory Constants
localparam VPN_SEGMENT_BITS = (XLEN == 32 ? 32'd10 : 32'd9);
localparam VPN_BITS = (XLEN==32 ? (2*VPN_SEGMENT_BITS) : (4*VPN_SEGMENT_BITS));
localparam PPN_BITS = (XLEN==32 ? 32'd22 : 32'd44);
localparam PA_BITS = (XLEN==32 ? 32'd34 : 32'd56);
localparam SVMODE_BITS = (XLEN==32 ? 32'd1 : 32'd4);
localparam ASID_BASE = (XLEN==32 ? 32'd22 : 32'd44);
localparam ASID_BITS = (XLEN==32 ? 32'd9 : 32'd16);
// constants to check SATP_MODE against
// defined in Table 4.3 of the privileged spec
localparam NO_TRANSLATE = 4'd0;
localparam SV32 = 4'd1;
localparam SV39 = 4'd8;
localparam SV48 = 4'd9;
// macros to define supported modes
localparam A_SUPPORTED = ((MISA >> 0) % 2 == 1);
localparam B_SUPPORTED = ((ZBA_SUPPORTED | ZBB_SUPPORTED | ZBC_SUPPORTED | ZBS_SUPPORTED));// not based on MISA
localparam C_SUPPORTED = ((MISA >> 2) % 2 == 1);
2023-10-30 16:56:17 +00:00
localparam COMPRESSED_SUPPORTED = C_SUPPORTED | ZCA_SUPPORTED;
2023-05-24 17:44:42 +00:00
localparam D_SUPPORTED = ((MISA >> 3) % 2 == 1);
localparam E_SUPPORTED = ((MISA >> 4) % 2 == 1);
localparam F_SUPPORTED = ((MISA >> 5) % 2 == 1);
localparam I_SUPPORTED = ((MISA >> 8) % 2 == 1);
2024-02-28 23:05:08 +00:00
localparam K_SUPPORTED = ((ZBKB_SUPPORTED | ZBKC_SUPPORTED | ZBKX_SUPPORTED | ZKND_SUPPORTED | ZKNE_SUPPORTED | ZKNH_SUPPORTED));
2023-05-24 17:44:42 +00:00
localparam M_SUPPORTED = ((MISA >> 12) % 2 == 1);
localparam Q_SUPPORTED = ((MISA >> 16) % 2 == 1);
localparam S_SUPPORTED = ((MISA >> 18) % 2 == 1);
localparam U_SUPPORTED = ((MISA >> 20) % 2 == 1);
// N-mode user-level interrupts are depricated per Andrew Waterman 1/13/21
// logarithm of XLEN, used for number of index bits to select
localparam LOG_XLEN = (XLEN == 32 ? 32'd5 : 32'd6);
// Number of 64 bit PMP Configuration Register entries (or pairs of 32 bit entries)
localparam PMPCFG_ENTRIES = (PMP_ENTRIES/32'd8);
// Floating point constants for Quad, Double, Single, and Half precisions
// Lim: I've made some of these 64 bit to avoid width warnings.
// If errors crop up, try downsizing back to 32.
localparam Q_LEN = 32'd128;
localparam Q_NE = 32'd15;
localparam Q_NF = 32'd112;
localparam Q_BIAS = 32'd16383;
localparam Q_FMT = 2'd3;
localparam D_LEN = 32'd64;
localparam D_NE = 32'd11;
localparam D_NF = 32'd52;
localparam D_BIAS = 32'd1023;
localparam D_FMT = 2'd1;
localparam S_LEN = 32'd32;
localparam S_NE = 32'd8;
localparam S_NF = 32'd23;
localparam S_BIAS = 32'd127;
localparam S_FMT = 2'd0;
localparam H_LEN = 32'd16;
localparam H_NE = 32'd5;
localparam H_NF = 32'd10;
localparam H_BIAS = 32'd15;
localparam H_FMT = 2'd2;
2024-01-16 01:48:41 +00:00
// Floating point length FLEN and number of exponent (NE) and fraction (NF) bits (for longest format supported)
localparam FLEN = Q_SUPPORTED ? Q_LEN : D_SUPPORTED ? D_LEN : S_LEN;
localparam NE = Q_SUPPORTED ? Q_NE : D_SUPPORTED ? D_NE : S_NE;
localparam NF = Q_SUPPORTED ? Q_NF : D_SUPPORTED ? D_NF : S_NF;
localparam FMT = Q_SUPPORTED ? 2'd3 : D_SUPPORTED ? 2'd1 : 2'd0;
localparam BIAS = Q_SUPPORTED ? Q_BIAS : D_SUPPORTED ? D_BIAS : S_BIAS;
2023-05-24 17:44:42 +00:00
// Floating point constants needed for FPU paramerterization
2024-01-16 01:48:41 +00:00
// LEN1/NE1/NF1/FNT1 is the size of the second longest supported format
localparam FPSIZES = (32)'(Q_SUPPORTED)+(32)'(D_SUPPORTED)+(32)'(F_SUPPORTED)+(32)'(ZFH_SUPPORTED);
localparam FMTBITS = (32)'(FPSIZES>=3)+1;
localparam LEN1 = (FLEN > D_LEN) ? D_LEN : (FLEN > S_LEN) ? S_LEN : H_LEN;
localparam NE1 = (FLEN > D_LEN) ? D_NE : (FLEN > S_LEN) ? S_NE : H_NE;
localparam NF1 = (FLEN > D_LEN) ? D_NF : (FLEN > S_LEN) ? S_NF : H_NF;
localparam FMT1 = (FLEN > D_LEN) ? 2'd1 : (FLEN > S_LEN) ? 2'd0 : 2'd2;
localparam BIAS1 = (FLEN > D_LEN) ? D_BIAS : (FLEN > S_LEN) ? S_BIAS : H_BIAS;
// LEN2 etc is the size of the third longest supported format
localparam LEN2 = (LEN1 > S_LEN) ? S_LEN : H_LEN;
localparam NE2 = (LEN1 > S_LEN) ? S_NE : H_NE;
localparam NF2 = (LEN1 > S_LEN) ? S_NF : H_NF;
localparam FMT2 = (LEN1 > S_LEN) ? 2'd0 : 2'd2;
localparam BIAS2 = (LEN1 > S_LEN) ? S_BIAS : H_BIAS;
2023-05-24 17:44:42 +00:00
2023-11-11 23:50:06 +00:00
// divider r and rk (bits per digit, bits per cycle)
localparam LOGR = $clog2(RADIX); // r = log(R) bits per digit
localparam RK = LOGR*DIVCOPIES; // r*k bits per cycle generated
2023-11-11 13:58:53 +00:00
2023-11-11 23:50:06 +00:00
// intermediate division parameters not directly used in fdivsqrt hardware
2024-03-03 19:17:51 +00:00
localparam FPDIVMINb = NF + 2; // minimum length of fractional part: Nf result bits + guard and round bits + 1 extra bit to allow sqrt being shifted right
2023-11-11 23:50:06 +00:00
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
2023-11-11 02:33:08 +00:00
2023-05-24 17:44:42 +00:00
// division constants
2023-11-11 23:50:06 +00:00
localparam FPDUR = (RESBITS-1)/RK + 1 ; // ceiling((r+b)/rk)
localparam DIVb = FPDUR*RK - LOGR; // divsqrt fractional bits, so total number of bits is a multiple of rk after r integer bits
localparam DURLEN = $clog2(FPDUR); // enough bits to count the duration
2024-02-01 04:03:14 +00:00
localparam DIVBLEN = $clog2(DIVb+1); // enough bits to count number of fractional bits + 1 integer bit
2023-11-11 13:58:53 +00:00
2023-05-24 17:44:42 +00:00
// largest length in IEU/FPU
2024-03-14 21:07:15 +00:00
localparam BASECVTLEN = `max(XLEN, NF); // convert length excluding Zfa fcvtmod.w.d
2024-04-17 03:57:49 +00:00
localparam CVTLEN = (ZFA_SUPPORTED & D_SUPPORTED) ? `max(BASECVTLEN, 32'd84) : BASECVTLEN; // fcvtmod.w.d needs at least 32+52 because a double with 52 fractional bits might be into upper bits of 32 bit word
2024-03-14 21:07:15 +00:00
localparam LLEN = `max($unsigned(FLEN), $unsigned(XLEN));
2023-05-24 17:44:42 +00:00
localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1));
2024-04-17 03:57:49 +00:00
// NORMSHIFTSIZE is the bits out of the normalization shifter
// RV32F: max(32+23+1, 2(23)+4, 3(23)+6) = 3*23+6 = 75
// RV64F: max(64+23+1, 64 + 23 + 2, 3*23+6) = 89
// RV64D: max(84+52+1, 64+52+2, 3*52+6) = 162
2024-05-10 20:42:52 +00:00
// *** DH 5/10/24 testbench_fp f_ieee_div_2_1_rv64gc cvtint was failing on
// with CVTLEN+NF+1. Changing to CVTLEN+NF+1+2 fixes failures
// This same failure occurred for any test with IDIV_ON_FPU = 0, FLEN=32, XLEN=64
// because NORMSHIFTSZ becomes limited by convert rather than divider
// Figure out why extra two bits are needed for convert (and only in testbench_fp, not Wally)
// Might be a testbench_fp issue
localparam NORMSHIFTSZ = `max(`max((CVTLEN+NF+1+2), (DIVb + 1 + NF + 1)), (3*NF+6));
2024-04-17 03:57:49 +00:00
localparam LOGNORMSHIFTSZ = ($clog2(NORMSHIFTSZ)); // log_2(NORMSHIFTSZ)
localparam CORRSHIFTSZ = NORMSHIFTSZ-2; // Drop leading 2 integer bits
2023-05-24 17:44:42 +00:00
// Disable spurious Verilator warnings
/* verilator lint_off STMTDLY */
/* verilator lint_off ASSIGNDLY */
2023-07-07 21:33:34 +00:00
/* verilator lint_off PINCONNECTEMPTY */