Update google_riscv-dv to google/riscv-dv@e63c542 (#587)

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

* Add pmp configuration object (Udi Jonnalagadda)
* add path for the prebuilt document (google/riscv-dv#469) (taoliug)
* Update document for directed assembly/C test (google/riscv-dv#467)
  (taoliug)
* Fix broken document link (google/riscv-dv#466) (taoliug)
* Add a runtime option to fix stack pointer (google/riscv-dv#465)
  (taoliug)
* Fix LR/SC instruction issue for RV32A (google/riscv-dv#464)
  (taoliug)

Signed-off-by: Udi <udij@google.com>
This commit is contained in:
udinator 2020-02-06 11:03:22 -08:00 committed by GitHub
parent 3f0b730d57
commit 2be7413ac8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 286 additions and 37 deletions

View file

@ -9,6 +9,6 @@
upstream:
{
url: https://github.com/google/riscv-dv
rev: f7e35d7939a27ae17b0481eb070e9a36ea335d1f
rev: e63c5427b0bf543aebb9c62bba8217065b029a76
}
}

View file

@ -64,7 +64,11 @@ cov --help
## Document
To understand how to setup and customize the generator, please check the full document under docs directory. You can use the makefile to generate the document. [HTML preview](https://htmlpreview.github.io/?https://github.com/google/riscv-dv/blob/master/docs/build/singlehtml/index.html#document-index)
To understand how to setup and customize the generator, please check the full
document under docs directory. You can use the makefile to generate the
document. [HTML
preview](https://htmlpreview.github.io/?https://github.com/google/riscv-dv/blob/master/docs/build/singlehtml/index.html#document-index).
You can find the prebuilt document under docs/build/singlehtml/index.html
## External contributions and collaborations

View file

@ -110,9 +110,38 @@ Test list in `YAML format`_
.. _YAML format: https://github.com/google/riscv-dv/blob/master/yaml/base_testlist.yaml
.. note:: To automatically generate CSR tests without having to explicitly run the
script, include `riscv_csr_test` in the testlist as shown in the example YAML
file above.
You can also add directed assembly/C test in the testlist
.. code-block:: yaml
- test: riscv_single_c_test
description: >
single c test entry
iterations: 1
c_test: sample_c.c
- test: riscv_c_regression_test
description: >
Run all c tests under the given directory
iterations: 1
c_test: c_test_directory
gcc_opts:
# Some custom gcc options
- test: riscv_single_asm_test
description: >
single assembly test entry
iterations: 1
asm_test: sample_asm.S
- test: riscv_asm_regression_test
description: >
Run all assembly tests under the given directory
iterations: 1
asm_test: assembly_test_directory
gcc_opts:
# Some custom gcc options
Runtime options of the generator
--------------------------------

View file

@ -50,5 +50,5 @@ in parallel::
# Split the run to process 5 CSV at a time, and run with LSF
cov --dir out/spike_sim --lsf_cmd "bsub ....." -bz 5
.. _riscv_core_setting.sv: https://github.com/google/riscv-dv/blob/master/setting/riscv_core_setting.sv
.. _riscv_core_setting.sv: https://github.com/google/riscv-dv/blob/master/target/rv32imc/riscv_core_setting.sv

View file

@ -64,7 +64,7 @@ Currently three ISS are supported, the default ISS is spike. You can install any
one of below to run ISS simulation.
1. - `spike`_ setup
- Follow the `spike steps`_ to build spike
- Follow the instructions to build spike
- Build spike with "--enable-commitlog"
- Set environment variable SPIKE_PATH to the directory of the spike binary
2. - `riscv-ovpsim`_ setup
@ -76,8 +76,7 @@ one of below to run ISS simulation.
- Follow the `sail-riscv steps`_ to install sail-riscv
- Set environment variable SAIL_RISCV to the path of sail-riscv binary
.. _spike: https://github.com/riscv/riscv-isa-sim#
.. _spike steps: https://github.com/riscv/riscv-isa-sim#build-steps
.. _spike: https://github.com/riscv/riscv-isa-sim
.. _riscv-ovpsim: https://github.com/riscv/riscv-ovpsim
.. _whisper: https://github.com/westerndigitalcorporation/swerv-ISS
.. _sail-riscv: https://github.com/rems-project/sail-riscv
@ -180,7 +179,7 @@ real RISC-V processor::
run --test=riscv_rand_instr_test --iss=spike,sail
Run directed assembly/C tests
---------------------------
-----------------------------
Sometimes it might be useful to run some hand-coded assembly/C tests to hit some
corner cases::

View file

@ -68,6 +68,18 @@
`DV_CHECK_FATAL(std::randomize(VAR_), MSG_, ID_, with { WITH_C_ })
`endif
// Shorthand for common this.randomize(foo) + fatal check
`ifndef DV_CHECK_MEMBER_RANDOMIZE_FATAL
`define DV_CHECK_MEMBER_RANDOMIZE_FATAL(VAR_, MSG_="Randomization failed!", ID_=`gfn) \
`DV_CHECK_FATAL(this.randomize(VAR_), MSG_, ID_)
`endif
// Shorthand for common this.randomize(foo) with { } + fatal check
`ifndef DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL
`define DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(VAR_, C_, MSG_="Randomization failed!", ID_=`gfn) \
`DV_CHECK_FATAL(this.randomize(VAR_) with {C_}, MSG_, ID_)
`endif
// for vector processing
`ifndef VECTOR_INCLUDE
`define VECTOR_INCLUDE(VCE_INC) \

View file

@ -85,8 +85,18 @@ class riscv_lr_sc_instr_stream extends riscv_amo_base_instr_stream;
endfunction
virtual function void gen_amo_instr();
lr_instr = riscv_instr::get_rand_instr(.include_instr({LR_W, LR_D}));
sc_instr = riscv_instr::get_rand_instr(.include_instr({SC_W, SC_D}));
riscv_instr_name_t allowed_lr_instr[];
riscv_instr_name_t allowed_sc_instr[];
if (RV32A inside {supported_isa}) begin
allowed_lr_instr = {LR_W};
allowed_sc_instr = {SC_W};
end
if (RV64A inside {supported_isa}) begin
allowed_lr_instr = {allowed_lr_instr, LR_D};
allowed_sc_instr = {allowed_sc_instr, SC_D};
end
lr_instr = riscv_instr::get_rand_instr(.include_instr({allowed_lr_instr}));
sc_instr = riscv_instr::get_rand_instr(.include_instr({allowed_sc_instr}));
`DV_CHECK_RANDOMIZE_WITH_FATAL(lr_instr,
rs1 == rs1_reg;
if (reserved_rd.size() > 0) {

View file

@ -525,6 +525,8 @@ class riscv_asm_program_gen extends uvm_object;
end
// Setup trap vector register
trap_vector_init();
// Setup PMP CSRs
setup_pmp();
// Initialize PTE (link page table based on their real physical address)
if(cfg.virtual_addr_translation_on) begin
page_table_list.process_page_table(instr);
@ -592,6 +594,16 @@ class riscv_asm_program_gen extends uvm_object;
gen_section("mepc_setup", instr);
endfunction
// Setup PMP CSR configuration
virtual function void setup_pmp();
string instr[$];
if (riscv_instr_pkg::support_pmp) begin
cfg.pmp_cfg.setup_pmp();
cfg.pmp_cfg.gen_pmp_instr(instr, cfg.scratch_reg);
gen_section("pmp_setup", instr);
end
endfunction
//---------------------------------------------------------------------------------------
// Privileged CSR setup for interrupt and exception handling and delegation
//---------------------------------------------------------------------------------------

View file

@ -91,6 +91,9 @@ class riscv_instr_gen_config extends uvm_object;
// Vector extension setting
rand riscv_vector_cfg vector_cfg;
// PMP configuration settings
rand riscv_pmp_cfg pmp_cfg;
//-----------------------------------------------------------------------------
// User space memory region and stack setting
//-----------------------------------------------------------------------------
@ -145,6 +148,8 @@ class riscv_instr_gen_config extends uvm_object;
bit enable_unaligned_load_store;
int illegal_instr_ratio;
int hint_instr_ratio;
// Use SP as stack pointer
bit fix_sp;
// Directed boot privileged mode, u, m, s
string boot_mode_opts;
int enable_page_table_exception;
@ -225,7 +230,6 @@ class riscv_instr_gen_config extends uvm_object;
int dist_control_mode;
int unsigned category_dist[riscv_instr_category_t];
uvm_cmdline_processor inst;
constraint default_c {
sub_program_instr_cnt.size() == num_of_sub_program;
@ -354,6 +358,9 @@ class riscv_instr_gen_config extends uvm_object;
}
constraint sp_tp_c {
if (fix_sp) {
sp == SP;
}
sp != tp;
!(sp inside {GP, RA, ZERO});
!(tp inside {GP, RA, ZERO});
@ -415,6 +422,7 @@ class riscv_instr_gen_config extends uvm_object;
`uvm_field_int(no_dret, UVM_DEFAULT)
`uvm_field_int(no_fence, UVM_DEFAULT)
`uvm_field_int(no_wfi, UVM_DEFAULT)
`uvm_field_int(fix_sp, UVM_DEFAULT)
`uvm_field_int(enable_unaligned_load_store, UVM_DEFAULT)
`uvm_field_int(illegal_instr_ratio, UVM_DEFAULT)
`uvm_field_int(hint_instr_ratio, UVM_DEFAULT)
@ -468,6 +476,7 @@ class riscv_instr_gen_config extends uvm_object;
get_bool_arg_value("+no_branch_jump=", no_branch_jump);
get_bool_arg_value("+no_load_store=", no_load_store);
get_bool_arg_value("+no_csr_instr=", no_csr_instr);
get_bool_arg_value("+fix_sp=", fix_sp);
get_bool_arg_value("+enable_illegal_csr_instruction=", enable_illegal_csr_instruction);
get_bool_arg_value("+enable_access_invalid_csr_level=", enable_access_invalid_csr_level);
get_bool_arg_value("+enable_misaligned_instr=", enable_misaligned_instr);
@ -533,6 +542,8 @@ class riscv_instr_gen_config extends uvm_object;
disable_compressed_instr = 1;
end
vector_cfg = riscv_vector_cfg::type_id::create("vector_cfg");
pmp_cfg = riscv_pmp_cfg::type_id::create("pmp_cfg");
pmp_cfg.rand_mode(pmp_cfg.pmp_randomize);
setup_instr_distribution();
get_invalid_priv_lvl_csr();
endfunction
@ -660,28 +671,4 @@ class riscv_instr_gen_config extends uvm_object;
end
endfunction
// Get an integer argument from comand line
function void get_int_arg_value(string cmdline_str, ref int val);
string s;
if(inst.get_arg_value(cmdline_str, s)) begin
val = s.atoi();
end
endfunction
// Get a bool argument from comand line
function void get_bool_arg_value(string cmdline_str, ref bit val);
string s;
if(inst.get_arg_value(cmdline_str, s)) begin
val = s.atobin();
end
endfunction
// Get a hex argument from command line
function void get_hex_arg_value(string cmdline_str, ref int val);
string s;
if(inst.get_arg_value(cmdline_str, s)) begin
val = s.atohex();
end
endfunction
endclass

View file

@ -26,6 +26,8 @@ package riscv_instr_pkg;
`define include_file(f) `include `"f`"
uvm_cmdline_processor inst;
// Data section setting
typedef struct {
string name;
@ -33,6 +35,26 @@ package riscv_instr_pkg;
bit [2:0] xwr; // Excutable,Writable,Readale
} mem_region_t;
// PMP address matching mode
typedef enum bit [1:0] {
OFF = 2'b00,
TOR = 2'b01,
NA4 = 2'b10,
NAPOT = 2'b11
} pmp_addr_mode_t;
// PMP configuration register layout
// This configuration struct includes the pmp address for simplicity
typedef struct{
rand bit l;
bit [1:0] zero;
rand pmp_addr_mode_t a;
rand bit x;
rand bit w;
rand bit r;
rand bit [33:0] addr;
} pmp_cfg_reg_t;
typedef enum bit [3:0] {
BARE = 4'b0000,
SV32 = 4'b0001,
@ -1069,6 +1091,30 @@ package riscv_instr_pkg;
end
endfunction
// Get an integer argument from comand line
function automatic void get_int_arg_value(string cmdline_str, ref int val);
string s;
if(inst.get_arg_value(cmdline_str, s)) begin
val = s.atoi();
end
endfunction
// Get a bool argument from comand line
function automatic void get_bool_arg_value(string cmdline_str, ref bit val);
string s;
if(inst.get_arg_value(cmdline_str, s)) begin
val = s.atobin();
end
endfunction
// Get a hex argument from command line
function automatic void get_hex_arg_value(string cmdline_str, ref int val);
string s;
if(inst.get_arg_value(cmdline_str, s)) begin
val = s.atohex();
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};
@ -1081,6 +1127,7 @@ package riscv_instr_pkg;
};
`include "riscv_vector_cfg.sv"
`include "riscv_pmp_cfg.sv"
typedef class riscv_instr;
`include "riscv_instr_gen_config.sv"
`include "isa/riscv_instr.sv"

View file

@ -0,0 +1,131 @@
/*
* Copyright 2020 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.
*/
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)
rand int pmp_granularity = 0;
// enable bit for pmp randomization
bit pmp_randomize = 0;
// pmp CSR configurations
rand pmp_cfg_reg_t pmp_cfg[];
// used to parse addr_mode configuration from cmdline
typedef uvm_enum_wrapper#(pmp_addr_mode_t) addr_mode_wrapper;
pmp_addr_mode_t addr_mode;
`uvm_object_utils_begin(riscv_pmp_cfg)
`uvm_field_int(pmp_num_regions, UVM_DEFAULT)
`uvm_field_int(pmp_granularity, UVM_DEFAULT)
`uvm_object_utils_end
// constraints
constraint sanity_c {
pmp_num_regions inside {[1 : 16]};
pmp_granularity inside {[0 : XLEN + 3]};
}
// TODO(udinator) move these constraints to post_randomize() to save performance
constraint xwr_c {
foreach (pmp_cfg[i]) {
!(pmp_cfg[i].w && !pmp_cfg[i].r);
}
}
constraint grain_addr_mode_c {
foreach (pmp_cfg[i]) {
(pmp_granularity >= 1) -> (pmp_cfg[i].a != NA4);
}
}
function new(string name = "");
string s;
super.new(name);
get_bool_arg_value("+pmp_randomize=", pmp_randomize);
pmp_cfg = new[pmp_num_regions];
if (!pmp_randomize) begin
set_defaults();
end
endfunction
// TODO(udinator) partition address space to map to all active pmp_addr CSRs
// TODO(udinator) set pmp address defaults
function void set_defaults();
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 = 34'h3FFFFFFFF;
end
endfunction
function void setup_pmp();
string pmp_region;
get_int_arg_value("+pmp_num_regions=", pmp_num_regions);
get_int_arg_value("+pmp_granularity=", pmp_granularity);
// TODO(udinator) - parse the pmp configuration values
endfunction
// This function parses the pmp_cfg[] array to generate the actual instructions to set up
// the PMP CSR registers.
// 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);
int cfg_per_csr = XLEN / 4;
bit [XLEN - 1 : 0] pmp_word;
bit [XLEN - 1 : 0] cfg_bitmask;
bit [7 : 0] cfg_byte;
riscv_instr_pkg::privileged_reg_t base_pmp_addr = PMPADDR0;
riscv_instr_pkg::privileged_reg_t base_pmpcfg_addr = PMPCFG0;
int pmp_id;
foreach (pmp_cfg[i]) begin
// TODO(udijnator) 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};
`uvm_info(`gfn, $sformatf("cfg_byte: 0x%0x", cfg_byte), UVM_DEBUG)
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;
//TODO (udinator) - add rv64 support for pmpaddr writes
instr.push_back($sformatf("li x%0d, 0x%0x", scratch_reg, pmp_cfg[i].addr[XLEN + 1 : 2]));
instr.push_back($sformatf("csrw 0x%0x, x%0d", base_pmp_addr + i, scratch_reg));
// short circuit if end of 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("csrw 0x%0x, x%0d",
base_pmpcfg_addr + pmp_id),
scratch_reg));
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("csrw 0x%0x, x%0d",
base_pmpcfg_addr + pmp_id),
scratch_reg));
pmp_word = 0;
end
end
endfunction
endclass

View file

@ -39,6 +39,9 @@ mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
// supported
int max_interrupt_vector_num = 16;
// Physical memory protection support
bit support_pmp = 0;
// Debug mode support
bit support_debug_mode = 0;

View file

@ -39,6 +39,9 @@ mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
// supported
int max_interrupt_vector_num = 16;
// Physical memory protection support
bit support_pmp = 0;
// Debug mode support
bit support_debug_mode = 0;

View file

@ -39,6 +39,9 @@ mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
// supported
int max_interrupt_vector_num = 16;
// Physical memory protection support
bit support_pmp = 0;
// Debug mode support
bit support_debug_mode = 0;

View file

@ -39,6 +39,9 @@ mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
// supported
int max_interrupt_vector_num = 16;
// Physical memory protection support
bit support_pmp = 0;
// Debug mode support
bit support_debug_mode = 0;

View file

@ -39,6 +39,9 @@ mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
// supported
int max_interrupt_vector_num = 16;
// Physical memory protection support
bit support_pmp = 0;
// Debug mode support
bit support_debug_mode = 0;

View file

@ -39,6 +39,9 @@ mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
// supported
int max_interrupt_vector_num = 16;
// Physical memory protection support
bit support_pmp = 0;
// Debug mode support
bit support_debug_mode = 0;