Update google_riscv-dv to google/riscv-dv@42264b7

Update code from upstream repository https://github.com/google/riscv-
dv to revision 42264b7782a10848935e995063c212893820e561

* fix pmp generation in bare program mode (Udi Jonnalagadda)
* Use literal instead array concatenation (Daniel Mlynek)
* fix access rights (Daniel Mlynek)
* fix in WA fo Aldec Riviera rand cannot be defined in packed struct
  (Daniel Mlynek)
* Fix ius compile error (Weicai Yang)
* fix pmp randomization to adhere to max offset (Udi Jonnalagadda)
* Add options to enable bitmanip by group (google/riscv-dv#532)
  (weicaiyang)
* [pmp] Relative addressing scheme to configure pmpaddr (google/riscv-
  dv#534) (udinator)
* redunant variable ALDEC_PATH removed (danielmlynek)
* riviera 2020.04 beta initial support (danielmlynek)
* Removed  system function call from the gen_section() function
  arguments list. (google/riscv-dv#531) (Dariusz Stachańczyk)
* Dynamic arrays declared as parameter changed to const variables.
  (google/riscv-dv#530) (danielmlynek)
* enhance pmp configuration to make safe region configurable (Udi
  Jonnalagadda)
* Fix a typo in riscvOVPsim (google/riscv-dv#529) (weicaiyang)

Signed-off-by: Udi <udij@google.com>
This commit is contained in:
Udi 2020-04-17 09:21:34 -07:00 committed by udinator
parent f8f68945c0
commit 2be109ecca
23 changed files with 275 additions and 112 deletions

View file

@ -9,6 +9,6 @@
upstream:
{
url: https://github.com/google/riscv-dv
rev: 76753158d940fffc53fbb92942ae5d1d768a7cdc
rev: 42264b7782a10848935e995063c212893820e561
}
}

View file

@ -11,6 +11,7 @@ include HANDSHAKE.md
include files.f
include qrun_option.f
include questa_sim.tcl
include riviera_sim.tcl
include run.py
include requirements.txt
include vcs.compile.option.f

View file

@ -26,8 +26,8 @@ processor verification. It currently supports the following features:
To be able to run the instruction generator, you need to have an RTL simulator
which supports SystemVerilog and UVM 1.2. This generator has been verified with
Synopsys VCS, Cadence Incisive/Xcelium, and Mentor Questa simulators. Please
make sure the EDA tool environment is properly setup before running the generator.
Synopsys VCS, Cadence Incisive/Xcelium, Mentor Questa, and Aldec Riviera-PRO simulators.
Please make sure the EDA tool environment is properly setup before running the generator.
### Install RISCV-DV

View file

@ -5,8 +5,8 @@ Prerequisites
To be able to run the instruction generator, you need to have an RTL simulator
which supports SystemVerilog and UVM 1.2. This generator has been verified with
Synopsys VCS, Cadence Incisive/Xcelium, and Mentor Questa simulators. Please
make sure the EDA tool environment is properly setup before running the generator.
Synopsys VCS, Cadence Incisive/Xcelium, Mentor Questa, and Aldec Riviera-PRO simulators.
Please make sure the EDA tool environment is properly setup before running the generator.
Install RISCV-DV
----------------
@ -109,6 +109,7 @@ You can specify the simulator by "-simulator" option::
run --test riscv_arithmetic_basic_test --simulator questa
run --test riscv_arithmetic_basic_test --simulator dsim
run --test riscv_arithmetic_basic_test --simulator qrun
run --test riscv_arithmetic_basic_test --simulator riviera
The complete test list can be found in `base testlist yaml`_. To run a full regression, simply use below command::

View file

@ -0,0 +1 @@
run -all; endsim; quit -force

View file

@ -96,7 +96,7 @@ def get_seed(seed):
"""
if seed >= 0:
return seed
return random.getrandbits(32)
return random.getrandbits(31)
def run_cmd(cmd, timeout_s = 999, exit_on_error = 1, check_return_code = True, debug_cmd = None):

View file

@ -470,6 +470,51 @@ class riscv_b_instr extends riscv_instr;
this.has_rs3 = rhs_.has_rs3;
endfunction : do_copy
virtual function bit is_supported(riscv_instr_gen_config cfg);
return cfg.enable_b_extension && (
(ZBB inside {cfg.enable_bitmanip_groups} && instr_name inside {
CLZ, CTZ, PCNT,
SLO, SLOI, SLOW, SLOIW,
SRO, SLOI, SROW, SLOIW,
MIN, MINU, MAX, MAXU,
ADDWU, ADDIWU, SUBWU,
ADDU_W, SUBU_W,
SLLIU_W,
ANDN, ORN,
XNOR, PACK, PACKW, PACKU, PACKUW, PACKH,
ROL, ROLW, ROR, RORW, RORI, RORIW
}) ||
(ZBS inside {cfg.enable_bitmanip_groups} && instr_name inside {
SBSET, SBSETW, SBSETI, SBSETIW,
SBCLR, SBCLRW, SBCLRI, SBCLRIW,
SBINV, SBINVW, SBINVI, SBINVIW,
SBEXT, SBEXTW, SBEXTI
}) ||
(ZBP inside {cfg.enable_bitmanip_groups} && instr_name inside {
GREV, GREVW, GREVI, GREVIW,
GORC, GORCW, GORCI, GORCIW,
SHFL, SHFLW, UNSHFL, UNSHFLW, SHFLI, UNSHFLI
}) ||
(ZBE inside {cfg.enable_bitmanip_groups} && instr_name inside {
BEXT, BEXTW,
BDEP, BDEPW
}) ||
(ZBF inside {cfg.enable_bitmanip_groups} && instr_name inside {BFP, BFPW}) ||
(ZBC inside {cfg.enable_bitmanip_groups} && instr_name inside {
CLMUL, CLMULW, CLMULH, CLMULHW, CLMULR, CLMULRW
}) ||
(ZBR inside {cfg.enable_bitmanip_groups} && instr_name inside {
CRC32_B, CRC32_H, CRC32_W, CRC32_D,
CRC32C_B, CRC32C_H, CRC32C_W, CRC32C_D
}) ||
(ZBM inside {cfg.enable_bitmanip_groups} && instr_name inside {
BMATOR, BMATXOR, BMATFLIP
}) ||
(ZBT inside {cfg.enable_bitmanip_groups} && instr_name inside {
CMOV, CMIX,
FSL, FSLW, FSR, FSRW, FSRI, FSRIW}));
endfunction
endclass

View file

@ -111,6 +111,7 @@ class riscv_instr extends uvm_object;
riscv_instr instr_inst;
if (instr_name inside {unsupported_instr}) continue;
instr_inst = create_instr(instr_name);
if (!instr_inst.is_supported(cfg)) continue;
instr_template[instr_name] = instr_inst;
// C_JAL is RV32C only instruction
if ((XLEN != 32) && (instr_name == C_JAL)) continue;
@ -123,9 +124,8 @@ class riscv_instr extends uvm_object;
!(cfg.disable_compressed_instr &&
(instr_inst.group inside {RV32C, RV64C, RV32DC, RV32FC, RV128C})) &&
!(!cfg.enable_floating_point &&
(instr_inst.group inside {RV32F, RV64F, RV32D, RV64D})) &&
!(!cfg.enable_b_extension &&
(instr_inst.group inside {RV32B, RV64B}))) begin
(instr_inst.group inside {RV32F, RV64F, RV32D, RV64D}))
) begin
instr_category[instr_inst.category].push_back(instr_name);
instr_group[instr_inst.group].push_back(instr_name);
instr_names.push_back(instr_name);
@ -135,6 +135,10 @@ class riscv_instr extends uvm_object;
create_csr_filter(cfg);
endfunction : create_instr_list
virtual function bit is_supported(riscv_instr_gen_config cfg);
return 1;
endfunction
static function void create_csr_filter(riscv_instr_gen_config cfg);
include_reg.delete();
exclude_reg.delete();

View file

@ -78,7 +78,7 @@ class riscv_asm_program_gen extends uvm_object;
gen_init_section(hart);
// If PMP is supported, we want to generate the associated trap handlers and the test_done
// section at the start of the program so we can allow access through the pmpcfg0 CSR
if (support_pmp) begin
if (support_pmp && !cfg.bare_program_mode) begin
gen_trap_handlers(hart);
// Ecall handler
gen_ecall_handler(hart);
@ -357,12 +357,13 @@ class riscv_asm_program_gen extends uvm_object;
// Generate the user stack section
virtual function void gen_stack_section(int hart);
string hart_prefix_string = hart_prefix(hart);
if (cfg.use_push_data_section) begin
instr_stream.push_back($sformatf(".pushsection .%0suser_stack,\"aw\",@progbits;",
hart_prefix(hart)));
hart_prefix_string));
end else begin
instr_stream.push_back($sformatf(".section .%0suser_stack,\"aw\",@progbits;",
hart_prefix(hart)));
hart_prefix_string));
end
if (SATP_MODE != BARE) begin
instr_stream.push_back(".align 12");
@ -382,12 +383,13 @@ class riscv_asm_program_gen extends uvm_object;
// The kernal stack is used to save user program context before executing exception handling
virtual function void gen_kernel_stack_section(int hart);
string hart_prefix_string = hart_prefix(hart);
if (cfg.use_push_data_section) begin
instr_stream.push_back($sformatf(".pushsection .%0skernel_stack,\"aw\",@progbits;",
hart_prefix(hart)));
hart_prefix_string));
end else begin
instr_stream.push_back($sformatf(".section .%0skernel_stack,\"aw\",@progbits;",
hart_prefix(hart)));
hart_prefix_string));
end
if (SATP_MODE != BARE) begin
instr_stream.push_back(".align 12");
@ -601,9 +603,10 @@ class riscv_asm_program_gen extends uvm_object;
virtual function void pre_enter_privileged_mode(int hart);
string instr[];
string str[$];
// Setup kerenal stack pointer
gen_section(get_label("kernel_sp", hart),
{$sformatf("la x%0d, %0skernel_stack_end", cfg.tp, hart_prefix(hart))});
str = {$sformatf("la x%0d, %0skernel_stack_end", cfg.tp, hart_prefix(hart))};
gen_section(get_label("kernel_sp", hart), str);
// Setup interrupt and exception delegation
if(!cfg.no_delegation && (cfg.init_privileged_mode != MACHINE_MODE)) begin
gen_delegation(hart);
@ -696,7 +699,7 @@ class riscv_asm_program_gen extends uvm_object;
string instr[$];
if (riscv_instr_pkg::support_pmp) begin
cfg.pmp_cfg.setup_pmp();
cfg.pmp_cfg.gen_pmp_instr(instr, cfg.scratch_reg);
cfg.pmp_cfg.gen_pmp_instr('{cfg.scratch_reg, cfg.gpr[0]}, instr);
gen_section(get_label("pmp_setup", hart), instr);
end
endfunction

View file

@ -77,7 +77,8 @@ class riscv_instr_gen_config extends uvm_object;
// Reserved register
// Reserved for various hardcoded routines
rand riscv_reg_t gpr[4];
// Used by any DCSR operations inside of the debug rom
// Used by any DCSR operations inside of the debug rom.
// Also used by the PMP generation.
rand riscv_reg_t scratch_reg;
// Use a random register for stack pointer/thread pointer
rand riscv_reg_t sp;
@ -239,6 +240,7 @@ class riscv_instr_gen_config extends uvm_object;
bit enable_vector_extension;
// Bit manipulation extension support
bit enable_b_extension;
b_ext_group_t enable_bitmanip_groups[] = {ZBB, ZBS, ZBP, ZBE, ZBF, ZBC, ZBR, ZBM, ZBT};
//-----------------------------------------------------------------------------
// Command line options for instruction distribution control
@ -483,11 +485,13 @@ class riscv_instr_gen_config extends uvm_object;
`uvm_field_int(enable_floating_point, UVM_DEFAULT)
`uvm_field_int(enable_vector_extension, UVM_DEFAULT)
`uvm_field_int(enable_b_extension, UVM_DEFAULT)
`uvm_field_array_enum(b_ext_group_t, enable_bitmanip_groups, UVM_DEFAULT)
`uvm_field_int(use_push_data_section, UVM_DEFAULT)
`uvm_object_utils_end
function new (string name = "");
string s;
riscv_instr_group_t march_isa[];
super.new(name);
init_delegation();
inst = uvm_cmdline_processor::get_inst();
@ -538,6 +542,8 @@ class riscv_instr_gen_config extends uvm_object;
get_bool_arg_value("+enable_floating_point=", enable_floating_point);
get_bool_arg_value("+enable_vector_extension=", enable_vector_extension);
get_bool_arg_value("+enable_b_extension=", enable_b_extension);
cmdline_enum_processor #(b_ext_group_t)::get_array_values("+enable_bitmanip_groups=",
enable_bitmanip_groups);
if(inst.get_arg_value("+boot_mode=", boot_mode_opts)) begin
`uvm_info(get_full_name(), $sformatf(
"Got boot mode option - %0s", boot_mode_opts), UVM_LOW)
@ -555,22 +561,9 @@ class riscv_instr_gen_config extends uvm_object;
riscv_instr_pkg::supported_privileged_mode.size()), UVM_LOW)
void'(inst.get_arg_value("+asm_test_suffix=", asm_test_suffix));
// Directed march list from the runtime options, ex. RV32I, RV32M etc.
void'(inst.get_arg_value("+march=", s));
if(s != "") begin
string cmdline_march_list[$];
riscv_instr_group_t march;
uvm_split_string(s, ",", cmdline_march_list);
riscv_instr_pkg::supported_isa.delete();
foreach(cmdline_march_list[i]) begin
if(uvm_enum_wrapper#(riscv_instr_group_t)::from_name(
cmdline_march_list[i].toupper(), march)) begin
riscv_instr_pkg::supported_isa.push_back(march);
end else begin
`uvm_fatal(get_full_name(), $sformatf(
"Invalid march %0s specified in command line", cmdline_march_list[i]))
end
end
end
cmdline_enum_processor #(riscv_instr_group_t)::get_array_values("+march=", march_isa);
if (march_isa.size != 0) riscv_instr_pkg::supported_isa = march_isa;
if (!(RV32C inside {supported_isa})) begin
disable_compressed_instr = 1;
end

View file

@ -1044,6 +1044,18 @@ package riscv_instr_pkg;
// PMP configuration register layout
// This configuration struct includes the pmp address for simplicity
// TODO (udinator) allow a full 34 bit address for rv32?
`ifdef _VCP //GRK958
typedef struct packed {
bit l;
bit [1:0] zero;
pmp_addr_mode_t a;
bit x;
bit w;
bit r;
// RV32: the pmpaddr is the top 32 bits of a 34 bit PMP address
// RV64: the pmpaddr is the top 54 bits of a 56 bit PMP address
bit [XLEN - 1 : 0] offset;
`else
typedef struct{
rand bit l;
bit [1:0] zero;
@ -1051,9 +1063,10 @@ package riscv_instr_pkg;
rand bit x;
rand bit w;
rand bit r;
// RV32: addr is the top 32 bits of a 34 bit PMP address
// RV64: addr is the top 54 bits of a 56 bit PMP address
rand bit [XLEN - 1 : 0] addr;
// RV32: the pmpaddr is the top 32 bits of a 34 bit PMP address
// RV64: the pmpaddr is the top 54 bits of a 56 bit PMP address
rand bit [XLEN - 1 : 0] offset;
`endif
} pmp_cfg_reg_t;
function automatic string hart_prefix(int hart = 0);
@ -1083,6 +1096,18 @@ package riscv_instr_pkg;
RoundToOdd
} vxrm_t;
typedef enum int {
ZBB,
ZBS,
ZBP,
ZBE,
ZBF,
ZBC,
ZBR,
ZBM,
ZBT
} b_ext_group_t;
`VECTOR_INCLUDE("riscv_instr_pkg_inc_variables.sv")
typedef bit [15:0] program_id_t;
@ -1234,6 +1259,28 @@ package riscv_instr_pkg;
end
endfunction
class cmdline_enum_processor #(parameter type T = riscv_instr_group_t);
static function void get_array_values(string cmdline_str, ref T vals[]);
string s;
void'(inst.get_arg_value(cmdline_str, s));
if(s != "") begin
string cmdline_list[$];
T value;
uvm_split_string(s, ",", cmdline_list);
vals = new[cmdline_list.size];
foreach (cmdline_list[i]) begin
if (uvm_enum_wrapper#(T)::from_name(
cmdline_list[i].toupper(), value)) begin
vals[i] = value;
end else begin
`uvm_fatal("riscv_instr_pkg", $sformatf(
"Invalid value (%0s) specified in command line: %0s", cmdline_list[i], cmdline_str))
end
end
end
endfunction
endclass
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};
@ -1248,6 +1295,7 @@ package riscv_instr_pkg;
`include "riscv_vector_cfg.sv"
`include "riscv_pmp_cfg.sv"
typedef class riscv_instr;
typedef class riscv_b_instr;
`include "riscv_instr_gen_config.sv"
`include "isa/riscv_instr.sv"
`include "isa/riscv_amo_instr.sv"

View file

@ -18,18 +18,26 @@ class riscv_pmp_cfg extends uvm_object;
// default to a single PMP region
rand int pmp_num_regions = 1;
// default to granularity of 0 (4 bytes grain)
int pmp_granularity = 0;
// enable bit for pmp randomization
bit pmp_randomize = 0;
// allow pmp randomization to cause address range overlap
bit pmp_allow_addr_overlap = 0;
// pmp CSR configurations
rand pmp_cfg_reg_t pmp_cfg[];
// PMP maximum address - used to set defaults
bit [XLEN - 1 : 0] pmp_max_address = {XLEN{1'b1}};
// PMP "minimum" address - the address written to pmpaddr0
// to create a "safe region", which contains important setup code,
// and cannot throw a PMP fault
bit [XLEN - 1 : 0] pmp_min_address = 0;
// This value is the address offset between the minimum and maximum pmpaddr
// CSR values.
// As pmpaddr0 will be set to the address of the <main> label, the address stored
// in pmpaddr0 added to this pmp_max_offset value will give the upper bound of the
// address range covered by the PMP address range.
// Can be manually configured from the command line.
bit [XLEN - 1 : 0] pmp_max_offset = {XLEN{1'b1}};
// used to parse addr_mode configuration from cmdline
typedef uvm_enum_wrapper#(pmp_addr_mode_t) addr_mode_wrapper;
@ -38,9 +46,13 @@ class riscv_pmp_cfg extends uvm_object;
`uvm_object_utils_begin(riscv_pmp_cfg)
`uvm_field_int(pmp_num_regions, UVM_DEFAULT)
`uvm_field_int(pmp_granularity, UVM_DEFAULT)
`uvm_field_int(pmp_max_offset, UVM_DEFAULT)
`uvm_object_utils_end
// constraints
/////////////////////////////////////////////////
// Constraints - apply when pmp_randomize is 1 //
/////////////////////////////////////////////////
constraint sanity_c {
pmp_num_regions inside {[1 : 16]};
pmp_granularity inside {[0 : XLEN + 3]};
@ -60,34 +72,40 @@ class riscv_pmp_cfg extends uvm_object;
}
}
constraint addr_range_c {
foreach (pmp_cfg[i]) {
// Offset of pmp_cfg[0] does not matter, since it will be set to <main>,
// so we do not constrain it here, as it will be overridden during generation
if (i != 0) {
pmp_cfg[i].offset inside {[1 : pmp_max_offset + 1]};
} else {
pmp_cfg[i].offset == 0;
}
}
}
constraint addr_overlapping_c {
foreach (pmp_cfg[i]) {
if (!pmp_allow_addr_overlap && i > 0) {
pmp_cfg[i].offset > pmp_cfg[i-1].offset;
}
}
}
function new(string name = "");
string s;
super.new(name);
inst = uvm_cmdline_processor::get_inst();
get_bool_arg_value("+pmp_randomize=", pmp_randomize);
get_bool_arg_value("+pmp_allow_addr_overlap=", pmp_allow_addr_overlap);
get_int_arg_value("+pmp_granularity=", pmp_granularity);
get_int_arg_value("+pmp_num_regions=", pmp_num_regions);
get_hex_arg_value("+pmp_max_address=", pmp_max_address);
get_hex_arg_value("+pmp_max_offset=", pmp_max_offset);
`uvm_info(`gfn, $sformatf("pmp max offset: 0x%0x", pmp_max_offset), UVM_LOW)
pmp_cfg = new[pmp_num_regions];
// As per privileged spec, the top 10 bits of a rv64 PMP address are all 0.
if (XLEN == 64) begin
pmp_max_address[XLEN - 1 : XLEN - 11] = 10'b0;
end
if (!pmp_randomize) begin
set_defaults();
setup_pmp();
end
endfunction
function void initialize(bit require_signature_addr);
// We want to set the "minimum" pmp address to just after the location of the <main>
// section of the program to allow all initialization routines to not be interrupted
// by PMP faults.
// The location of <main> itself will change depending on whether the handshaking
// mechanism is enabled or disabled, so we check if it is enabled and then
// round up the address of <main>.
pmp_min_address = (require_signature_addr) ? 'h80002910 : 'h80001580;
if (!pmp_randomize) begin
set_defaults();
setup_pmp();
@ -97,26 +115,29 @@ class riscv_pmp_cfg extends uvm_object;
// This will only get called if pmp_randomize is set, in which case we apply command line
// arguments after randomization
function void post_randomize();
`ifdef _VCP //GRK958
foreach(pmp_cfg[i]) pmp_cfg[i].zero = 2'b00;
`endif
setup_pmp();
endfunction
function void set_defaults();
`uvm_info(`gfn, $sformatf("MAX OFFSET: 0x%0x", pmp_max_offset), UVM_LOW)
foreach(pmp_cfg[i]) begin
pmp_cfg[i].l = 1'b0;
pmp_cfg[i].a = TOR;
pmp_cfg[i].x = 1'b1;
pmp_cfg[i].w = 1'b1;
pmp_cfg[i].r = 1'b1;
pmp_cfg[i].addr = (i == 0) ? pmp_min_address : assign_default_addr(pmp_num_regions, i);
pmp_cfg[i].l = 1'b0;
pmp_cfg[i].a = TOR;
pmp_cfg[i].x = 1'b1;
pmp_cfg[i].w = 1'b1;
pmp_cfg[i].r = 1'b1;
pmp_cfg[i].offset = assign_default_addr_offset(pmp_num_regions, i);
end
endfunction
// Helper function to break down
function bit [XLEN - 1 : 0] assign_default_addr(int num_regions, int index);
bit [XLEN - 1 : 0] total_addr_space, offset;
total_addr_space = pmp_max_address - pmp_min_address;
offset = total_addr_space / (num_regions - 1) * index;
return pmp_min_address + offset;
function bit [XLEN - 1 : 0] assign_default_addr_offset(int num_regions, int index);
bit [XLEN - 1 : 0] offset;
offset = pmp_max_offset / (num_regions - 1);
offset = offset * index;
return offset;
endfunction
function void setup_pmp();
@ -132,7 +153,7 @@ class riscv_pmp_cfg extends uvm_object;
end
endfunction
function void parse_pmp_config(string pmp_region, output pmp_cfg_reg_t pmp_cfg_reg);
function void parse_pmp_config(string pmp_region, ref pmp_cfg_reg_t pmp_cfg_reg);
string fields[$];
string field_vals[$];
string field_type;
@ -162,7 +183,7 @@ class riscv_pmp_cfg extends uvm_object;
"ADDR": begin
// Don't have to convert address to "PMP format" here,
// since it must be masked off in hardware
pmp_cfg_reg.addr = format_addr(field_val.atohex());
pmp_cfg_reg.offset = format_addr(field_val.atohex());
end
default: begin
`uvm_fatal(`gfn, $sformatf("%s, Invalid PMP configuration field name!", field_val))
@ -199,7 +220,7 @@ class riscv_pmp_cfg extends uvm_object;
// Since either 4 (in rv32) or 8 (in rv64) PMP configuration registers fit into one physical
// CSR, this function waits until it has reached this maximum to write to the physical CSR to
// save some extraneous instructions from being performed.
function void gen_pmp_instr(ref string instr[$], riscv_reg_t scratch_reg);
function void gen_pmp_instr(riscv_reg_t scratch_reg[2], ref string instr[$]);
int cfg_per_csr = XLEN / 8;
bit [XLEN - 1 : 0] pmp_word;
bit [XLEN - 1 : 0] cfg_bitmask;
@ -210,30 +231,50 @@ class riscv_pmp_cfg extends uvm_object;
foreach (pmp_cfg[i]) begin
// TODO(udinator) condense this calculations if possible
pmp_id = i / cfg_per_csr;
cfg_byte = {pmp_cfg[i].l, pmp_cfg[i].zero, pmp_cfg[i].a,
pmp_cfg[i].x, pmp_cfg[i].w, pmp_cfg[i].r};
if (i == 0) begin
cfg_byte = {1'b0, pmp_cfg[i].zero, TOR, 1'b1, 1'b1, 1'b1};
end else begin
cfg_byte = {pmp_cfg[i].l, pmp_cfg[i].zero, pmp_cfg[i].a,
pmp_cfg[i].x, pmp_cfg[i].w, pmp_cfg[i].r};
end
`uvm_info(`gfn, $sformatf("cfg_byte: 0x%0x", cfg_byte), UVM_DEBUG)
// First write to the appropriate pmpaddr CSR
cfg_bitmask = cfg_byte << ((i % cfg_per_csr) * 8);
`uvm_info(`gfn, $sformatf("cfg_bitmask: 0x%0x", cfg_bitmask), UVM_DEBUG)
pmp_word = pmp_word | cfg_bitmask;
`uvm_info(`gfn, $sformatf("pmp_word: 0x%0x", pmp_word), UVM_DEBUG)
cfg_bitmask = 0;
`uvm_info(`gfn, $sformatf("pmp_addr_%d: 0x%0x", i, pmp_cfg[i].addr), UVM_DEBUG)
instr.push_back($sformatf("li x%0d, 0x%0x", scratch_reg, pmp_cfg[i].addr));
instr.push_back($sformatf("csrw 0x%0x, x%0d", base_pmp_addr + i, scratch_reg));
// short circuit if end of list
if (i == 0) begin
// load the address of the <main> section into pmpaddr0
instr.push_back($sformatf("la x%0d, main", scratch_reg[0]));
instr.push_back($sformatf("srli x%0d, x%0d, 2", scratch_reg[0], scratch_reg[0]));
instr.push_back($sformatf("csrw 0x%0x, x%0d", base_pmp_addr + i, scratch_reg[0]));
`uvm_info(`gfn, "Loaded the address of <main> section into pmpaddr0", UVM_LOW)
end else begin
// Add the offset to the base address to get the other pmpaddr values
instr.push_back($sformatf("la x%0d, main", scratch_reg[0]));
instr.push_back($sformatf("li x%0d, 0x%0x", scratch_reg[1], pmp_cfg[i].offset));
instr.push_back($sformatf("add x%0d, x%0d, x%0d",
scratch_reg[0], scratch_reg[0], scratch_reg[1]));
instr.push_back($sformatf("srli x%0d, x%0d, 2", scratch_reg[0], scratch_reg[0]));
instr.push_back($sformatf("csrw 0x%0x, x%0d", base_pmp_addr + i, scratch_reg[0]));
`uvm_info(`gfn, $sformatf("Offset of pmp_addr_%d from pmpaddr0: 0x%0x",
i, pmp_cfg[i].offset), UVM_LOW)
end
// Now, check if we have to write to the appropriate pmpcfg CSR.
// Short circuit if we reach the end of the list
if (i == pmp_cfg.size() - 1) begin
instr.push_back($sformatf("li x%0d, 0x%0x", scratch_reg, pmp_word));
instr.push_back($sformatf("li x%0d, 0x%0x", scratch_reg[0], pmp_word));
instr.push_back($sformatf("csrw 0x%0x, x%0d",
base_pmpcfg_addr + pmp_id,
scratch_reg));
scratch_reg[0]));
return;
end else if ((i + 1) % cfg_per_csr == 0) begin
// if we've filled up pmp_word, write to the corresponding CSR
instr.push_back($sformatf("li x%0d, 0x%0x", scratch_reg, pmp_word));
instr.push_back($sformatf("li x%0d, 0x%0x", scratch_reg[0], pmp_word));
instr.push_back($sformatf("csrw 0x%0x, x%0d",
base_pmpcfg_addr + pmp_id,
scratch_reg));
scratch_reg[0]));
pmp_word = 0;
end
end

View file

@ -70,7 +70,7 @@ parameter int NUM_HARTS = 1;
`ifdef DSIM
privileged_reg_t implemented_csr[] = {
`else
parameter privileged_reg_t implemented_csr[] = {
const privileged_reg_t implemented_csr[] = {
`endif
// Machine mode mode CSR
MVENDORID, // Vendor ID
@ -96,7 +96,7 @@ parameter privileged_reg_t implemented_csr[] = {
`ifdef DSIM
interrupt_cause_t implemented_interrupt[] = {
`else
parameter interrupt_cause_t implemented_interrupt[] = {
const interrupt_cause_t implemented_interrupt[] = {
`endif
M_SOFTWARE_INTR,
M_TIMER_INTR,
@ -106,7 +106,7 @@ parameter interrupt_cause_t implemented_interrupt[] = {
`ifdef DSIM
exception_cause_t implemented_exception[] = {
`else
parameter exception_cause_t implemented_exception[] = {
const exception_cause_t implemented_exception[] = {
`endif
INSTRUCTION_ACCESS_FAULT,
ILLEGAL_INSTRUCTION,

View file

@ -71,7 +71,7 @@ parameter int NUM_HARTS = 2;
`ifdef DSIM
privileged_reg_t implemented_csr[] = {
`else
parameter privileged_reg_t implemented_csr[] = {
const privileged_reg_t implemented_csr[] = {
`endif
// Machine mode mode CSR
MVENDORID, // Vendor ID
@ -97,7 +97,7 @@ parameter privileged_reg_t implemented_csr[] = {
`ifdef DSIM
interrupt_cause_t implemented_interrupt[] = {
`else
parameter interrupt_cause_t implemented_interrupt[] = {
const interrupt_cause_t implemented_interrupt[] = {
`endif
M_SOFTWARE_INTR,
M_TIMER_INTR,
@ -107,7 +107,7 @@ parameter interrupt_cause_t implemented_interrupt[] = {
`ifdef DSIM
exception_cause_t implemented_exception[] = {
`else
parameter exception_cause_t implemented_exception[] = {
const exception_cause_t implemented_exception[] = {
`endif
INSTRUCTION_ACCESS_FAULT,
ILLEGAL_INSTRUCTION,

View file

@ -70,7 +70,7 @@ parameter int NUM_HARTS = 1;
`ifdef DSIM
privileged_reg_t implemented_csr[] = {
`else
parameter privileged_reg_t implemented_csr[] = {
const privileged_reg_t implemented_csr[] = {
`endif
// Machine mode mode CSR
MVENDORID, // Vendor ID
@ -96,7 +96,7 @@ parameter privileged_reg_t implemented_csr[] = {
`ifdef DSIM
interrupt_cause_t implemented_interrupt[] = {
`else
parameter interrupt_cause_t implemented_interrupt[] = {
const interrupt_cause_t implemented_interrupt[] = {
`endif
M_SOFTWARE_INTR,
M_TIMER_INTR,
@ -106,7 +106,7 @@ parameter interrupt_cause_t implemented_interrupt[] = {
`ifdef DSIM
exception_cause_t implemented_exception[] = {
`else
parameter exception_cause_t implemented_exception[] = {
const exception_cause_t implemented_exception[] = {
`endif
INSTRUCTION_ADDRESS_MISALIGNED,
INSTRUCTION_ACCESS_FAULT,

View file

@ -71,7 +71,7 @@ parameter int NUM_HARTS = 1;
`ifdef DSIM
privileged_reg_t implemented_csr[] = {
`else
parameter privileged_reg_t implemented_csr[] = {
const privileged_reg_t implemented_csr[] = {
`endif
// Machine mode mode CSR
MVENDORID, // Vendor ID
@ -97,7 +97,7 @@ parameter privileged_reg_t implemented_csr[] = {
`ifdef DSIM
interrupt_cause_t implemented_interrupt[] = {
`else
parameter interrupt_cause_t implemented_interrupt[] = {
const interrupt_cause_t implemented_interrupt[] = {
`endif
M_SOFTWARE_INTR,
M_TIMER_INTR,
@ -107,7 +107,7 @@ parameter interrupt_cause_t implemented_interrupt[] = {
`ifdef DSIM
exception_cause_t implemented_exception[] = {
`else
parameter exception_cause_t implemented_exception[] = {
const exception_cause_t implemented_exception[] = {
`endif
INSTRUCTION_ACCESS_FAULT,
ILLEGAL_INSTRUCTION,

View file

@ -1,6 +1,6 @@
# riscOVPsim configuration file converted from YAML
--variant RV32I
--override iscvOVPsim/cpu/add_Extensions=MCB
--override riscvOVPsim/cpu/add_Extensions=MCB
--override riscvOVPsim/cpu/misa_MXL=1
--override riscvOVPsim/cpu/misa_MXL_mask=0x0 # 0
--override riscvOVPsim/cpu/misa_Extensions_mask=0x0 # 0

View file

@ -71,7 +71,7 @@ parameter int NUM_HARTS = 1;
`ifdef DSIM
privileged_reg_t implemented_csr[] = {
`else
parameter privileged_reg_t implemented_csr[] = {
const privileged_reg_t implemented_csr[] = {
`endif
// Machine mode mode CSR
MVENDORID, // Vendor ID
@ -97,7 +97,7 @@ parameter privileged_reg_t implemented_csr[] = {
`ifdef DSIM
interrupt_cause_t implemented_interrupt[] = {
`else
parameter interrupt_cause_t implemented_interrupt[] = {
const interrupt_cause_t implemented_interrupt[] = {
`endif
M_SOFTWARE_INTR,
M_TIMER_INTR,
@ -107,7 +107,7 @@ parameter interrupt_cause_t implemented_interrupt[] = {
`ifdef DSIM
exception_cause_t implemented_exception[] = {
`else
parameter exception_cause_t implemented_exception[] = {
const exception_cause_t implemented_exception[] = {
`endif
INSTRUCTION_ACCESS_FAULT,
ILLEGAL_INSTRUCTION,

View file

@ -32,7 +32,6 @@
- import: <riscv_dv_root>/target/rv32imc/testlist.yaml
- test: riscv_b_ext_test
description: >
Random instruction test with b extension
@ -41,3 +40,13 @@
gen_opts: >
+enable_b_extension=1
rtl_test: core_base_test
- test: riscv_zbb_zbt_test
description: >
Random instruction test with zbb and zbt groups in b extension
iterations: 1
gen_test: riscv_rand_instr_test
gen_opts: >
+enable_b_extension=1
+enable_bitmanip_groups=zbb,zbt
rtl_test: core_base_test

View file

@ -71,7 +71,7 @@ parameter int NUM_HARTS = 1;
`ifdef DSIM
privileged_reg_t implemented_csr[] = {
`else
parameter privileged_reg_t implemented_csr[] = {
const privileged_reg_t implemented_csr[] = {
`endif
// User mode CSR
USTATUS, // User status
@ -123,7 +123,7 @@ parameter privileged_reg_t implemented_csr[] = {
`ifdef DSIM
interrupt_cause_t implemented_interrupt[] = {
`else
parameter interrupt_cause_t implemented_interrupt[] = {
const interrupt_cause_t implemented_interrupt[] = {
`endif
U_SOFTWARE_INTR,
S_SOFTWARE_INTR,
@ -139,7 +139,7 @@ parameter interrupt_cause_t implemented_interrupt[] = {
`ifdef DSIM
exception_cause_t implemented_exception[] = {
`else
parameter exception_cause_t implemented_exception[] = {
const exception_cause_t implemented_exception[] = {
`endif
INSTRUCTION_ACCESS_FAULT,
ILLEGAL_INSTRUCTION,

View file

@ -70,7 +70,7 @@ parameter int NUM_HARTS = 1;
`ifdef DSIM
privileged_reg_t implemented_csr[] = {
`else
parameter privileged_reg_t implemented_csr[] = {
const privileged_reg_t implemented_csr[] = {
`endif
// User mode CSR
USTATUS, // User status
@ -122,7 +122,7 @@ parameter privileged_reg_t implemented_csr[] = {
`ifdef DSIM
interrupt_cause_t implemented_interrupt[] = {
`else
parameter interrupt_cause_t implemented_interrupt[] = {
const interrupt_cause_t implemented_interrupt[] = {
`endif
U_SOFTWARE_INTR,
S_SOFTWARE_INTR,
@ -138,7 +138,7 @@ parameter interrupt_cause_t implemented_interrupt[] = {
`ifdef DSIM
exception_cause_t implemented_exception[] = {
`else
parameter exception_cause_t implemented_exception[] = {
const exception_cause_t implemented_exception[] = {
`endif
INSTRUCTION_ACCESS_FAULT,
ILLEGAL_INSTRUCTION,

View file

@ -71,7 +71,7 @@ parameter int NUM_HARTS = 1;
`ifdef DSIM
privileged_reg_t implemented_csr[] = {
`else
parameter privileged_reg_t implemented_csr[] = {
const privileged_reg_t implemented_csr[] = {
`endif
// Machine mode mode CSR
MVENDORID, // Vendor ID
@ -97,7 +97,7 @@ parameter privileged_reg_t implemented_csr[] = {
`ifdef DSIM
interrupt_cause_t implemented_interrupt[] = {
`else
parameter interrupt_cause_t implemented_interrupt[] = {
const interrupt_cause_t implemented_interrupt[] = {
`endif
M_SOFTWARE_INTR,
M_TIMER_INTR,
@ -107,7 +107,7 @@ parameter interrupt_cause_t implemented_interrupt[] = {
`ifdef DSIM
exception_cause_t implemented_exception[] = {
`else
parameter exception_cause_t implemented_exception[] = {
const exception_cause_t implemented_exception[] = {
`endif
INSTRUCTION_ACCESS_FAULT,
ILLEGAL_INSTRUCTION,

View file

@ -102,3 +102,20 @@
qrun -64 -simulate -snapshot design_opt -c <cov_opts> <sim_opts> -sv_seed <seed> -outdir <out>/qrun.out
cov_opts: >
-coverage -ucdb <out>/cov.ucdb
- tool: riviera
compile:
cmd:
- "vlib <out>/work"
- "vlog -work <out>/work
-uvmver 1.2
+define+UVM_REGEX_NO_DPI
+incdir+<setting>
+incdir+<user_extension>
-f <cwd>/files.f
<cmp_opts>"
sim:
cmd: >
vsim -c <sim_opts> -sv_seed <seed> <cov_opts> -do <cwd>/riviera_sim.tcl
cov_opts: >
-acdb_file <out>/cov.acdb