blob: 6439deb070c1a7beae20482a499e2c2d72175ed2 [file] [log] [blame]
/*
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package riscv_instr_pkg;
`include "dv_defines.svh"
`include "riscv_defines.svh"
`include "uvm_macros.svh"
import uvm_pkg::*;
import riscv_signature_pkg::*;
`define include_file(f) `include `"f`"
// Data section setting
typedef struct {
string name;
int unsigned size_in_bytes;
bit [2:0] xwr; // Excutable,Writable,Readale
} mem_region_t;
typedef enum bit [3:0] {
BARE = 4'b0000,
SV32 = 4'b0001,
SV39 = 4'b1000,
SV48 = 4'b1001,
SV57 = 4'b1010,
SV64 = 4'b1011
} satp_mode_t;
typedef enum bit [2:0] {
RNE = 3'b000,
RTZ = 3'b001,
RDN = 3'b010,
RUP = 3'b011,
RMM = 3'b100
} f_rounding_mode_t;
typedef enum bit [1:0] {
DIRECT = 2'b00,
VECTORED = 2'b01
} mtvec_mode_t;
typedef enum bit [2:0] {
IMM, // Signed immediate
UIMM, // Unsigned immediate
NZUIMM, // Non-zero unsigned immediate
NZIMM // Non-zero signed immediate
} imm_t;
// Privileged mode
typedef enum bit [1:0] {
USER_MODE = 2'b00,
SUPERVISOR_MODE = 2'b01,
RESERVED_MODE = 2'b10,
MACHINE_MODE = 2'b11
} privileged_mode_t;
typedef enum bit [4:0] {
RV32I,
RV64I,
RV32M,
RV64M,
RV32A,
RV64A,
RV32F,
RV32FC,
RV64F,
RV32D,
RV32DC,
RV64D,
RV32C,
RV64C,
RV128I,
RV128C
} riscv_instr_group_t;
typedef enum {
// RV32I instructions
LUI,
AUIPC,
JAL,
JALR,
BEQ,
BNE,
BLT,
BGE,
BLTU,
BGEU,
LB,
LH,
LW,
LBU,
LHU,
SB,
SH,
SW,
ADDI,
SLTI,
SLTIU,
XORI,
ORI,
ANDI,
SLLI,
SRLI,
SRAI,
ADD,
SUB,
SLL,
SLT,
SLTU,
XOR,
SRL,
SRA,
OR,
AND,
NOP,
FENCE,
FENCE_I,
ECALL,
EBREAK,
CSRRW,
CSRRS,
CSRRC,
CSRRWI,
CSRRSI,
CSRRCI,
// RV32M instructions
MUL,
MULH,
MULHSU,
MULHU,
DIV,
DIVU,
REM,
REMU,
// RV64M instructions
MULW,
DIVW,
DIVUW,
REMW,
REMUW,
// RV32F instructions
FLW,
FSW,
FMADD_S,
FMSUB_S,
FNMSUB_S,
FNMADD_S,
FADD_S,
FSUB_S,
FMUL_S,
FDIV_S,
FSQRT_S,
FSGNJ_S,
FSGNJN_S,
FSGNJX_S,
FMIN_S,
FMAX_S,
FCVT_W_S,
FCVT_WU_S,
FMV_X_W,
FEQ_S,
FLT_S,
FLE_S,
FCLASS_S,
FCVT_S_W,
FCVT_S_WU,
FMV_W_X,
// RV64F instruction
FCVT_L_S,
FCVT_LU_S,
FCVT_S_L,
FCVT_S_LU,
// RV32D instructions
FLD,
FSD,
FMADD_D,
FMSUB_D,
FNMSUB_D,
FNMADD_D,
FADD_D,
FSUB_D,
FMUL_D,
FDIV_D,
FSQRT_D,
FSGNJ_D,
FSGNJN_D,
FSGNJX_D,
FMIN_D,
FMAX_D,
FCVT_S_D,
FCVT_D_S,
FEQ_D,
FLT_D,
FLE_D,
FCLASS_D,
FCVT_W_D,
FCVT_WU_D,
FCVT_D_W,
FCVT_D_WU,
// RV64D
FCVT_L_D,
FCVT_LU_D,
FMV_X_D,
FCVT_D_L,
FCVT_D_LU,
FMV_D_X,
// RV64I
LWU,
LD,
SD,
ADDIW,
SLLIW,
SRLIW,
SRAIW,
ADDW,
SUBW,
SLLW,
SRLW,
SRAW,
// RV32C
C_LW,
C_SW,
C_LWSP,
C_SWSP,
C_ADDI4SPN,
C_ADDI,
C_LI,
C_ADDI16SP,
C_LUI,
C_SRLI,
C_SRAI,
C_ANDI,
C_SUB,
C_XOR,
C_OR,
C_AND,
C_BEQZ,
C_BNEZ,
C_SLLI,
C_MV,
C_EBREAK,
C_ADD,
C_NOP,
C_J,
C_JAL,
C_JR,
C_JALR,
// RV64C
C_ADDIW,
C_SUBW,
C_ADDW,
C_LD,
C_SD,
C_LDSP,
C_SDSP,
// RV128C
C_SRLI64,
C_SRAI64,
C_SLLI64,
C_LQ,
C_SQ,
C_LQSP,
C_SQSP,
// RV32FC
C_FLW,
C_FSW,
C_FLWSP,
C_FSWSP,
// RV32DC
C_FLD,
C_FSD,
C_FLDSP,
C_FSDSP,
// RV32A
LR_W,
SC_W,
AMOSWAP_W,
AMOADD_W,
AMOAND_W,
AMOOR_W,
AMOXOR_W,
AMOMIN_W,
AMOMAX_W,
AMOMINU_W,
AMOMAXU_W,
// RV64A
LR_D,
SC_D,
AMOSWAP_D,
AMOADD_D,
AMOAND_D,
AMOOR_D,
AMOXOR_D,
AMOMIN_D,
AMOMAX_D,
AMOMINU_D,
AMOMAXU_D,
// Supervisor instruction
DRET,
MRET,
URET,
SRET,
WFI,
SFENCE_VMA,
// You can add other instructions here
INVALID_INSTR
} riscv_instr_name_t;
// Maximum virtual address bits used by the program
parameter MAX_USED_VADDR_BITS = 30;
typedef enum bit [4:0] {
ZERO = 5'b00000,
RA, SP, GP, TP, T0, T1, T2, S0, S1, A0, A1, A2, A3, A4, A5, A6, A7,
S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, T3, T4, T5, T6
} riscv_reg_t;
typedef enum bit [4:0] {
F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15,
F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, F31
} riscv_fpr_t;
typedef enum bit [3:0] {
J_FORMAT = 0,
U_FORMAT,
I_FORMAT,
B_FORMAT,
R_FORMAT,
S_FORMAT,
R4_FORMAT,
CI_FORMAT,
CB_FORMAT,
CJ_FORMAT,
CR_FORMAT,
CA_FORMAT,
CL_FORMAT,
CS_FORMAT,
CSS_FORMAT,
CIW_FORMAT
} riscv_instr_format_t;
typedef enum bit [3:0] {
LOAD = 0,
STORE,
SHIFT,
ARITHMETIC,
LOGICAL,
COMPARE,
BRANCH,
JUMP,
SYNCH,
SYSTEM,
COUNTER,
CSR,
CHANGELEVEL,
TRAP,
INTERRUPT,
AMO
} riscv_instr_category_t;
typedef bit [11:0] riscv_csr_t;
typedef enum bit [11:0] {
// User mode register
USTATUS = 'h000, // User status
UIE = 'h004, // User interrupt-enable register
UTVEC = 'h005, // User trap-handler base address
USCRATCH = 'h040, // Scratch register for user trap handlers
UEPC = 'h041, // User exception program counter
UCAUSE = 'h042, // User trap cause
UTVAL = 'h043, // User bad address or instruction
UIP = 'h044, // User interrupt pending
FFLAGS = 'h001, // Floating-Point Accrued Exceptions
FRM = 'h002, // Floating-Point Dynamic Rounding Mode
FCSR = 'h003, // Floating-Point Control/Status Register (FRM + FFLAGS)
CYCLE = 'hC00, // Cycle counter for RDCYCLE instruction
TIME = 'hC01, // Timer for RDTIME instruction
INSTRET = 'hC02, // Instructions-retired counter for RDINSTRET instruction
HPMCOUNTER3 = 'hC03, // Performance-monitoring counter
HPMCOUNTER4 = 'hC04, // Performance-monitoring counter
HPMCOUNTER5 = 'hC05, // Performance-monitoring counter
HPMCOUNTER6 = 'hC06, // Performance-monitoring counter
HPMCOUNTER7 = 'hC07, // Performance-monitoring counter
HPMCOUNTER8 = 'hC08, // Performance-monitoring counter
HPMCOUNTER9 = 'hC09, // Performance-monitoring counter
HPMCOUNTER10 = 'hC0A, // Performance-monitoring counter
HPMCOUNTER11 = 'hC0B, // Performance-monitoring counter
HPMCOUNTER12 = 'hC0C, // Performance-monitoring counter
HPMCOUNTER13 = 'hC0D, // Performance-monitoring counter
HPMCOUNTER14 = 'hC0E, // Performance-monitoring counter
HPMCOUNTER15 = 'hC0F, // Performance-monitoring counter
HPMCOUNTER16 = 'hC10, // Performance-monitoring counter
HPMCOUNTER17 = 'hC11, // Performance-monitoring counter
HPMCOUNTER18 = 'hC12, // Performance-monitoring counter
HPMCOUNTER19 = 'hC13, // Performance-monitoring counter
HPMCOUNTER20 = 'hC14, // Performance-monitoring counter
HPMCOUNTER21 = 'hC15, // Performance-monitoring counter
HPMCOUNTER22 = 'hC16, // Performance-monitoring counter
HPMCOUNTER23 = 'hC17, // Performance-monitoring counter
HPMCOUNTER24 = 'hC18, // Performance-monitoring counter
HPMCOUNTER25 = 'hC19, // Performance-monitoring counter
HPMCOUNTER26 = 'hC1A, // Performance-monitoring counter
HPMCOUNTER27 = 'hC1B, // Performance-monitoring counter
HPMCOUNTER28 = 'hC1C, // Performance-monitoring counter
HPMCOUNTER29 = 'hC1D, // Performance-monitoring counter
HPMCOUNTER30 = 'hC1E, // Performance-monitoring counter
HPMCOUNTER31 = 'hC1F, // Performance-monitoring counter
CYCLEH = 'hC80, // Upper 32 bits of CYCLE, RV32I only
TIMEH = 'hC81, // Upper 32 bits of TIME, RV32I only
INSTRETH = 'hC82, // Upper 32 bits of INSTRET, RV32I only
HPMCOUNTER3H = 'hC83, // Upper 32 bits of HPMCOUNTER3, RV32I only
HPMCOUNTER4H = 'hC84, // Upper 32 bits of HPMCOUNTER4, RV32I only
HPMCOUNTER5H = 'hC85, // Upper 32 bits of HPMCOUNTER5, RV32I only
HPMCOUNTER6H = 'hC86, // Upper 32 bits of HPMCOUNTER6, RV32I only
HPMCOUNTER7H = 'hC87, // Upper 32 bits of HPMCOUNTER7, RV32I only
HPMCOUNTER8H = 'hC88, // Upper 32 bits of HPMCOUNTER8, RV32I only
HPMCOUNTER9H = 'hC89, // Upper 32 bits of HPMCOUNTER9, RV32I only
HPMCOUNTER10H = 'hC8A, // Upper 32 bits of HPMCOUNTER10, RV32I only
HPMCOUNTER11H = 'hC8B, // Upper 32 bits of HPMCOUNTER11, RV32I only
HPMCOUNTER12H = 'hC8C, // Upper 32 bits of HPMCOUNTER12, RV32I only
HPMCOUNTER13H = 'hC8D, // Upper 32 bits of HPMCOUNTER13, RV32I only
HPMCOUNTER14H = 'hC8E, // Upper 32 bits of HPMCOUNTER14, RV32I only
HPMCOUNTER15H = 'hC8F, // Upper 32 bits of HPMCOUNTER15, RV32I only
HPMCOUNTER16H = 'hC90, // Upper 32 bits of HPMCOUNTER16, RV32I only
HPMCOUNTER17H = 'hC91, // Upper 32 bits of HPMCOUNTER17, RV32I only
HPMCOUNTER18H = 'hC92, // Upper 32 bits of HPMCOUNTER18, RV32I only
HPMCOUNTER19H = 'hC93, // Upper 32 bits of HPMCOUNTER19, RV32I only
HPMCOUNTER20H = 'hC94, // Upper 32 bits of HPMCOUNTER20, RV32I only
HPMCOUNTER21H = 'hC95, // Upper 32 bits of HPMCOUNTER21, RV32I only
HPMCOUNTER22H = 'hC96, // Upper 32 bits of HPMCOUNTER22, RV32I only
HPMCOUNTER23H = 'hC97, // Upper 32 bits of HPMCOUNTER23, RV32I only
HPMCOUNTER24H = 'hC98, // Upper 32 bits of HPMCOUNTER24, RV32I only
HPMCOUNTER25H = 'hC99, // Upper 32 bits of HPMCOUNTER25, RV32I only
HPMCOUNTER26H = 'hC9A, // Upper 32 bits of HPMCOUNTER26, RV32I only
HPMCOUNTER27H = 'hC9B, // Upper 32 bits of HPMCOUNTER27, RV32I only
HPMCOUNTER28H = 'hC9C, // Upper 32 bits of HPMCOUNTER28, RV32I only
HPMCOUNTER29H = 'hC9D, // Upper 32 bits of HPMCOUNTER29, RV32I only
HPMCOUNTER30H = 'hC9E, // Upper 32 bits of HPMCOUNTER30, RV32I only
HPMCOUNTER31H = 'hC9F, // Upper 32 bits of HPMCOUNTER31, RV32I only
// Supervisor mode register
SSTATUS = 'h100, // Supervisor status
SEDELEG = 'h102, // Supervisor exception delegation register
SIDELEG = 'h103, // Supervisor interrupt delegation register
SIE = 'h104, // Supervisor interrupt-enable register
STVEC = 'h105, // Supervisor trap-handler base address
SCOUNTEREN = 'h106, // Supervisor counter enable
SSCRATCH = 'h140, // Scratch register for supervisor trap handlers
SEPC = 'h141, // Supervisor exception program counter
SCAUSE = 'h142, // Supervisor trap cause
STVAL = 'h143, // Supervisor bad address or instruction
SIP = 'h144, // Supervisor interrupt pending
SATP = 'h180, // Supervisor address translation and protection
// Machine mode register
MVENDORID = 'hF11, // Vendor ID
MARCHID = 'hF12, // Architecture ID
MIMPID = 'hF13, // Implementation ID
MHARTID = 'hF14, // Hardware thread ID
MSTATUS = 'h300, // Machine status
MISA = 'h301, // ISA and extensions
MEDELEG = 'h302, // Machine exception delegation register
MIDELEG = 'h303, // Machine interrupt delegation register
MIE = 'h304, // Machine interrupt-enable register
MTVEC = 'h305, // Machine trap-handler base address
MCOUNTEREN = 'h306, // Machine counter enable
MSCRATCH = 'h340, // Scratch register for machine trap handlers
MEPC = 'h341, // Machine exception program counter
MCAUSE = 'h342, // Machine trap cause
MTVAL = 'h343, // Machine bad address or instruction
MIP = 'h344, // Machine interrupt pending
PMPCFG0 = 'h3A0, // Physical memory protection configuration
PMPCFG1 = 'h3A1, // Physical memory protection configuration, RV32 only
PMPCFG2 = 'h3A2, // Physical memory protection configuration
PMPCFG3 = 'h3A3, // Physical memory protection configuration, RV32 only
PMPADDR0 = 'h3B0, // Physical memory protection address register
PMPADDR1 = 'h3B1, // Physical memory protection address register
PMPADDR2 = 'h3B2, // Physical memory protection address register
PMPADDR3 = 'h3B3, // Physical memory protection address register
PMPADDR4 = 'h3B4, // Physical memory protection address register
PMPADDR5 = 'h3B5, // Physical memory protection address register
PMPADDR6 = 'h3B6, // Physical memory protection address register
PMPADDR7 = 'h3B7, // Physical memory protection address register
PMPADDR8 = 'h3B8, // Physical memory protection address register
PMPADDR9 = 'h3B9, // Physical memory protection address register
PMPADDR10 = 'h3BA, // Physical memory protection address register
PMPADDR11 = 'h3BB, // Physical memory protection address register
PMPADDR12 = 'h3BC, // Physical memory protection address register
PMPADDR13 = 'h3BD, // Physical memory protection address register
PMPADDR14 = 'h3BE, // Physical memory protection address register
PMPADDR15 = 'h3BF, // Physical memory protection address register
MCYCLE = 'hB00, // Machine cycle counter
MINSTRET = 'hB02, // Machine instructions-retired counter
MHPMCOUNTER3 = 'hB03, // Machine performance-monitoring counter
MHPMCOUNTER4 = 'hB04, // Machine performance-monitoring counter
MHPMCOUNTER5 = 'hB05, // Machine performance-monitoring counter
MHPMCOUNTER6 = 'hB06, // Machine performance-monitoring counter
MHPMCOUNTER7 = 'hB07, // Machine performance-monitoring counter
MHPMCOUNTER8 = 'hB08, // Machine performance-monitoring counter
MHPMCOUNTER9 = 'hB09, // Machine performance-monitoring counter
MHPMCOUNTER10 = 'hB0A, // Machine performance-monitoring counter
MHPMCOUNTER11 = 'hB0B, // Machine performance-monitoring counter
MHPMCOUNTER12 = 'hB0C, // Machine performance-monitoring counter
MHPMCOUNTER13 = 'hB0D, // Machine performance-monitoring counter
MHPMCOUNTER14 = 'hB0E, // Machine performance-monitoring counter
MHPMCOUNTER15 = 'hB0F, // Machine performance-monitoring counter
MHPMCOUNTER16 = 'hB10, // Machine performance-monitoring counter
MHPMCOUNTER17 = 'hB11, // Machine performance-monitoring counter
MHPMCOUNTER18 = 'hB12, // Machine performance-monitoring counter
MHPMCOUNTER19 = 'hB13, // Machine performance-monitoring counter
MHPMCOUNTER20 = 'hB14, // Machine performance-monitoring counter
MHPMCOUNTER21 = 'hB15, // Machine performance-monitoring counter
MHPMCOUNTER22 = 'hB16, // Machine performance-monitoring counter
MHPMCOUNTER23 = 'hB17, // Machine performance-monitoring counter
MHPMCOUNTER24 = 'hB18, // Machine performance-monitoring counter
MHPMCOUNTER25 = 'hB19, // Machine performance-monitoring counter
MHPMCOUNTER26 = 'hB1A, // Machine performance-monitoring counter
MHPMCOUNTER27 = 'hB1B, // Machine performance-monitoring counter
MHPMCOUNTER28 = 'hB1C, // Machine performance-monitoring counter
MHPMCOUNTER29 = 'hB1D, // Machine performance-monitoring counter
MHPMCOUNTER30 = 'hB1E, // Machine performance-monitoring counter
MHPMCOUNTER31 = 'hB1F, // Machine performance-monitoring counter
MCYCLEH = 'hB80, // Upper 32 bits of MCYCLE, RV32I only
MINSTRETH = 'hB82, // Upper 32 bits of MINSTRET, RV32I only
MHPMCOUNTER3H = 'hB83, // Upper 32 bits of HPMCOUNTER3, RV32I only
MHPMCOUNTER4H = 'hB84, // Upper 32 bits of HPMCOUNTER4, RV32I only
MHPMCOUNTER5H = 'hB85, // Upper 32 bits of HPMCOUNTER5, RV32I only
MHPMCOUNTER6H = 'hB86, // Upper 32 bits of HPMCOUNTER6, RV32I only
MHPMCOUNTER7H = 'hB87, // Upper 32 bits of HPMCOUNTER7, RV32I only
MHPMCOUNTER8H = 'hB88, // Upper 32 bits of HPMCOUNTER8, RV32I only
MHPMCOUNTER9H = 'hB89, // Upper 32 bits of HPMCOUNTER9, RV32I only
MHPMCOUNTER10H = 'hB8A, // Upper 32 bits of HPMCOUNTER10, RV32I only
MHPMCOUNTER11H = 'hB8B, // Upper 32 bits of HPMCOUNTER11, RV32I only
MHPMCOUNTER12H = 'hB8C, // Upper 32 bits of HPMCOUNTER12, RV32I only
MHPMCOUNTER13H = 'hB8D, // Upper 32 bits of HPMCOUNTER13, RV32I only
MHPMCOUNTER14H = 'hB8E, // Upper 32 bits of HPMCOUNTER14, RV32I only
MHPMCOUNTER15H = 'hB8F, // Upper 32 bits of HPMCOUNTER15, RV32I only
MHPMCOUNTER16H = 'hB90, // Upper 32 bits of HPMCOUNTER16, RV32I only
MHPMCOUNTER17H = 'hB91, // Upper 32 bits of HPMCOUNTER17, RV32I only
MHPMCOUNTER18H = 'hB92, // Upper 32 bits of HPMCOUNTER18, RV32I only
MHPMCOUNTER19H = 'hB93, // Upper 32 bits of HPMCOUNTER19, RV32I only
MHPMCOUNTER20H = 'hB94, // Upper 32 bits of HPMCOUNTER20, RV32I only
MHPMCOUNTER21H = 'hB95, // Upper 32 bits of HPMCOUNTER21, RV32I only
MHPMCOUNTER22H = 'hB96, // Upper 32 bits of HPMCOUNTER22, RV32I only
MHPMCOUNTER23H = 'hB97, // Upper 32 bits of HPMCOUNTER23, RV32I only
MHPMCOUNTER24H = 'hB98, // Upper 32 bits of HPMCOUNTER24, RV32I only
MHPMCOUNTER25H = 'hB99, // Upper 32 bits of HPMCOUNTER25, RV32I only
MHPMCOUNTER26H = 'hB9A, // Upper 32 bits of HPMCOUNTER26, RV32I only
MHPMCOUNTER27H = 'hB9B, // Upper 32 bits of HPMCOUNTER27, RV32I only
MHPMCOUNTER28H = 'hB9C, // Upper 32 bits of HPMCOUNTER28, RV32I only
MHPMCOUNTER29H = 'hB9D, // Upper 32 bits of HPMCOUNTER29, RV32I only
MHPMCOUNTER30H = 'hB9E, // Upper 32 bits of HPMCOUNTER30, RV32I only
MHPMCOUNTER31H = 'hB9F, // Upper 32 bits of HPMCOUNTER31, RV32I only
MCOUNTINHIBIT = 'h320, // Machine counter-inhibit register
MHPMEVENT3 = 'h323, // Machine performance-monitoring event selector
MHPMEVENT4 = 'h324, // Machine performance-monitoring event selector
MHPMEVENT5 = 'h325, // Machine performance-monitoring event selector
MHPMEVENT6 = 'h326, // Machine performance-monitoring event selector
MHPMEVENT7 = 'h327, // Machine performance-monitoring event selector
MHPMEVENT8 = 'h328, // Machine performance-monitoring event selector
MHPMEVENT9 = 'h329, // Machine performance-monitoring event selector
MHPMEVENT10 = 'h32A, // Machine performance-monitoring event selector
MHPMEVENT11 = 'h32B, // Machine performance-monitoring event selector
MHPMEVENT12 = 'h32C, // Machine performance-monitoring event selector
MHPMEVENT13 = 'h32D, // Machine performance-monitoring event selector
MHPMEVENT14 = 'h32E, // Machine performance-monitoring event selector
MHPMEVENT15 = 'h32F, // Machine performance-monitoring event selector
MHPMEVENT16 = 'h330, // Machine performance-monitoring event selector
MHPMEVENT17 = 'h331, // Machine performance-monitoring event selector
MHPMEVENT18 = 'h332, // Machine performance-monitoring event selector
MHPMEVENT19 = 'h333, // Machine performance-monitoring event selector
MHPMEVENT20 = 'h334, // Machine performance-monitoring event selector
MHPMEVENT21 = 'h335, // Machine performance-monitoring event selector
MHPMEVENT22 = 'h336, // Machine performance-monitoring event selector
MHPMEVENT23 = 'h337, // Machine performance-monitoring event selector
MHPMEVENT24 = 'h338, // Machine performance-monitoring event selector
MHPMEVENT25 = 'h339, // Machine performance-monitoring event selector
MHPMEVENT26 = 'h33A, // Machine performance-monitoring event selector
MHPMEVENT27 = 'h33B, // Machine performance-monitoring event selector
MHPMEVENT28 = 'h33C, // Machine performance-monitoring event selector
MHPMEVENT29 = 'h33D, // Machine performance-monitoring event selector
MHPMEVENT30 = 'h33E, // Machine performance-monitoring event selector
MHPMEVENT31 = 'h33F, // Machine performance-monitoring event selector
TSELECT = 'h7A0, // Debug/Trace trigger register select
TDATA1 = 'h7A1, // First Debug/Trace trigger data register
TDATA2 = 'h7A2, // Second Debug/Trace trigger data register
TDATA3 = 'h7A3, // Third Debug/Trace trigger data register
DCSR = 'h7B0, // Debug control and status register
DPC = 'h7B1, // Debug PC
DSCRATCH0 = 'h7B2, // Debug scratch register
DSCRATCH1 = 'h7B3 // Debug scratch register
} privileged_reg_t;
typedef enum bit [5:0] {
RSVD, // Reserved field
MXL, // mis.mxl
EXTENSION, // mis.extension
MODE, // satp.mode
ASID, // satp.asid
PPN // satp.ppn
} privileged_reg_fld_t;
typedef enum bit [1:0] {
M_LEVEL = 2'b11, // Machine mode
S_LEVEL = 2'b01, // Supervisor mode
U_LEVEL = 2'b00 // User mode
} privileged_level_t;
typedef enum bit [1:0] {
WPRI, // Reserved Writes Preserve Values, Reads Ignore Value
WLRL, // Write/Read Only Legal Values
WARL // Write Any Values, Reads Legal Values
} reg_field_access_t;
//Pseudo instructions
typedef enum bit [7:0] {
LI = 0,
LA
} riscv_pseudo_instr_name_t;
// Data pattern of the memory model
typedef enum bit [1:0] {
RAND_DATA = 0,
ALL_ZERO,
INCR_VAL
} data_pattern_t;
typedef enum bit [2:0] {
NEXT_LEVEL_PAGE = 3'b000, // Pointer to next level of page table.
READ_ONLY_PAGE = 3'b001, // Read-only page.
READ_WRITE_PAGE = 3'b011, // Read-write page.
EXECUTE_ONLY_PAGE = 3'b100, // Execute-only page.
READ_EXECUTE_PAGE = 3'b101, // Read-execute page.
R_W_EXECUTE_PAGE = 3'b111 // Read-write-execute page
} pte_permission_t;
typedef enum bit [3:0] {
U_SOFTWARE_INTR = 4'h0,
S_SOFTWARE_INTR = 4'h1,
M_SOFTWARE_INTR = 4'h3,
U_TIMER_INTR = 4'h4,
S_TIMER_INTR = 4'h5,
M_TIMER_INTR = 4'h7,
U_EXTERNAL_INTR = 4'h8,
S_EXTERNAL_INTR = 4'h9,
M_EXTERNAL_INTR = 4'hB
} interrupt_cause_t;
typedef enum bit [3:0] {
INSTRUCTION_ADDRESS_MISALIGNED = 4'h0,
INSTRUCTION_ACCESS_FAULT = 4'h1,
ILLEGAL_INSTRUCTION = 4'h2,
BREAKPOINT = 4'h3,
LOAD_ADDRESS_MISALIGNED = 4'h4,
LOAD_ACCESS_FAULT = 4'h5,
STORE_AMO_ADDRESS_MISALIGNED = 4'h6,
STORE_AMO_ACCESS_FAULT = 4'h7,
ECALL_UMODE = 4'h8,
ECALL_SMODE = 4'h9,
ECALL_MMODE = 4'hB,
INSTRUCTION_PAGE_FAULT = 4'hC,
LOAD_PAGE_FAULT = 4'hD,
STORE_AMO_PAGE_FAULT = 4'hF
} exception_cause_t;
typedef enum int {
MISA_EXT_A = 0,
MISA_EXT_B,
MISA_EXT_C,
MISA_EXT_D,
MISA_EXT_E,
MISA_EXT_F,
MISA_EXT_G,
MISA_EXT_H,
MISA_EXT_I,
MISA_EXT_J,
MISA_EXT_K,
MISA_EXT_L,
MISA_EXT_M,
MISA_EXT_N,
MISA_EXT_O,
MISA_EXT_P,
MISA_EXT_Q,
MISA_EXT_R,
MISA_EXT_S,
MISA_EXT_T,
MISA_EXT_U,
MISA_EXT_V,
MISA_EXT_W,
MISA_EXT_X,
MISA_EXT_Y,
MISA_EXT_Z
} misa_ext_t;
typedef enum bit [1:0] {
NO_HAZARD,
RAW_HAZARD,
WAR_HAZARD,
WAW_HAZARD
} hazard_e;
`include "riscv_core_setting.sv"
typedef bit [15:0] program_id_t;
// xSTATUS bit mask
parameter bit [XLEN - 1 : 0] MPRV_BIT_MASK = 'h1 << 17;
parameter bit [XLEN - 1 : 0] SUM_BIT_MASK = 'h1 << 18;
parameter bit [XLEN - 1 : 0] MPP_BIT_MASK = 'h3 << 11;
parameter IMM25_WIDTH = 25;
parameter IMM12_WIDTH = 12;
parameter INSTR_WIDTH = 32;
parameter DATA_WIDTH = 32;
// Parameters for output assembly program formatting
parameter MAX_INSTR_STR_LEN = 11;
parameter LABEL_STR_LEN = 18;
// Parameter for program generation
parameter MAX_CALLSTACK_DEPTH = 20;
parameter MAX_SUB_PROGRAM_CNT = 20;
parameter MAX_CALL_PER_FUNC = 5;
string indent = {LABEL_STR_LEN{" "}};
// Format the string to a fixed length
function automatic string format_string(string str, int len = 10);
string formatted_str;
formatted_str = {len{" "}};
if(len < str.len()) return str;
formatted_str = {str, formatted_str.substr(0, len - str.len() - 1)};
return formatted_str;
endfunction
// Print the data in the following format
// 0xabcd, 0x1234, 0x3334 ...
function automatic string format_data(bit [7:0] data[], int unsigned byte_per_group = 4);
string str;
int cnt;
str = "0x";
foreach(data[i]) begin
if((i % byte_per_group == 0) && (i != data.size() - 1) && (i != 0)) begin
str = {str, ", 0x"};
end
str = {str, $sformatf("%2x", data[i])};
end
return str;
endfunction
// Get the instr name enum from a string
function automatic riscv_instr_name_t get_instr_name(string str);
riscv_instr_name_t instr = instr.first;
forever begin
if(str.toupper() == instr.name()) begin
return instr;
end
if(instr == instr.last) begin
return INVALID_INSTR;
end
instr = instr.next;
end
endfunction
// Push general purpose register to stack, this is needed before trap handling
function automatic void push_gpr_to_kernel_stack(privileged_reg_t status,
privileged_reg_t scratch,
bit mprv,
riscv_reg_t sp,
riscv_reg_t tp,
ref string instr[$]);
string store_instr = (XLEN == 32) ? "sw" : "sd";
if (scratch inside {implemented_csr}) begin
// Use kernal stack for handling exceptions
// Save the user mode stack pointer to the scratch register
instr.push_back($sformatf("csrrw x%0d, 0x%0x, x%0d", sp, scratch, sp));
// Move TP to SP
instr.push_back($sformatf("add x%0d, x%0d, zero", sp, tp));
end
// If MPRV is set and MPP is S/U mode, it means the address translation and memory protection
// for load/store instruction is the same as the mode indicated by MPP. In this case, we
// need to use the virtual address to access the kernel stack.
if((status == MSTATUS) && (SATP_MODE != BARE)) begin
// We temporarily use tp to check mstatus to avoid changing other GPR. The value of sp has
// been saved to xScratch and can be restored later.
if(mprv) begin
instr.push_back($sformatf("csrr x%0d, 0x%0x // MSTATUS", tp, status));
instr.push_back($sformatf("srli x%0d, x%0d, 11", tp, tp)); // Move MPP to bit 0
instr.push_back($sformatf("andi x%0d, x%0d, 0x3", tp, tp)); // keep the MPP bits
instr.push_back($sformatf("xori x%0d, x%0d, 0x3", tp, tp)); // Check if MPP equals to M-mode('b11)
instr.push_back($sformatf("bnez x%0d, 1f", tp)); // Use physical address for kernel SP
// Use virtual address for stack pointer
instr.push_back($sformatf("slli x%0d, x%0d, %0d", sp, sp, XLEN - MAX_USED_VADDR_BITS));
instr.push_back($sformatf("srli x%0d, x%0d, %0d", sp, sp, XLEN - MAX_USED_VADDR_BITS));
end
end
// Reserve space from kernel stack to save all 32 GPR except for x0
instr.push_back($sformatf("1: addi x%0d, x%0d, -%0d", sp, sp, 31 * (XLEN/8)));
// Push all GPRs to kernel stack
for(int i = 1; i < 32; i++) begin
instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, i, i * (XLEN/8), sp));
end
endfunction
// Pop general purpose register from stack, this is needed before returning to user program
function automatic void pop_gpr_from_kernel_stack(privileged_reg_t status,
privileged_reg_t scratch,
bit mprv,
riscv_reg_t sp,
riscv_reg_t tp,
ref string instr[$]);
string load_instr = (XLEN == 32) ? "lw" : "ld";
// Pop user mode GPRs from kernel stack
for(int i = 1; i < 32; i++) begin
instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, i, i * (XLEN/8), sp));
end
// Restore kernel stack pointer
instr.push_back($sformatf("addi x%0d, x%0d, %0d", sp, sp, 31 * (XLEN/8)));
if (scratch inside {implemented_csr}) begin
// Move SP to TP
instr.push_back($sformatf("add x%0d, x%0d, zero", tp, sp));
// Restore user mode stack pointer
instr.push_back($sformatf("csrrw x%0d, 0x%0x, x%0d", sp, scratch, sp));
end
endfunction
riscv_reg_t all_gpr[] = {ZERO, RA, SP, GP, TP, T0, T1, T2, S0, S1, A0,
A1, A2, A3, A4, A5, A6, A7, S2, S3, S4, S5, S6,
S7, S8, S9, S10, S11, T3, T4, T5, T6};
riscv_reg_t compressed_gpr[] = {S0, S1, A0, A1, A2, A3, A4, A5};
`include "riscv_instr_base.sv"
`include "riscv_instr_gen_config.sv"
`include "riscv_illegal_instr.sv"
`include "riscv_reg.sv"
`include "riscv_privil_reg.sv"
`include "riscv_page_table_entry.sv"
`include "riscv_page_table_exception_cfg.sv"
`include "riscv_page_table.sv"
`include "riscv_page_table_list.sv"
`include "riscv_privileged_common_seq.sv"
`include "riscv_callstack_gen.sv"
`include "riscv_data_page_gen.sv"
`include "riscv_rand_instr.sv"
`include "riscv_instr_stream.sv"
`include "riscv_loop_instr.sv"
`include "riscv_directed_instr_lib.sv"
`include "riscv_load_store_instr_lib.sv"
`include "riscv_amo_instr_lib.sv"
`include "riscv_instr_sequence.sv"
`include "riscv_asm_program_gen.sv"
`include "riscv_instr_cov_item.sv"
`include "riscv_instr_cover_group.sv"
`include "user_extension.svh"
endpackage