Update google_riscv-dv to google/riscv-dv@6bd3233 (#617)

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

* VCS compile option fix (Udi Jonnalagadda)
* Improve pmp config object - enable cmdline args (Udi Jonnalagadda)
* Fix ovpsim setting (google/riscv-dv#478) (taoliug)
* IUS - enable rand structs in simulation (google/riscv-dv#477)
  (udinator)
* fix macro definition compile issue (Udi Jonnalagadda)
* add ISS command line options (google/riscv-dv#474) (udinator)
* Add style check (Weicai Yang)

Signed-off-by: Udi <udij@google.com>
This commit is contained in:
udinator 2020-02-20 15:07:12 -08:00 committed by GitHub
parent 77c93f1e54
commit f98cd607af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 340 additions and 99 deletions

View file

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

View file

@ -62,6 +62,17 @@ run --help
cov --help
```
Use below command to install Verible, which is the tool to check Verilog style
```bash
verilog_style/build-verible.sh
```
This is the command to run Verilog style check. It's recommended to run and clean up
all the style violations before submit a PR
```bash
verilog_style/run.sh
```
## Document
To understand how to setup and customize the generator, please check the full

View file

@ -534,8 +534,8 @@ def run_c_from_dir(c_test_dir, iss_yaml, isa, mabi, gcc_opts, iss,
logging.error("No c test(*.c) found under %s" % c_test_dir)
def iss_sim(test_list, output_dir, iss_list, iss_yaml, isa,
setting_dir, timeout_s, debug_cmd):
def iss_sim(test_list, output_dir, iss_list, iss_yaml, iss_opts,
isa, setting_dir, timeout_s, debug_cmd):
"""Run ISS simulation with the generated test program
Args:
@ -543,6 +543,7 @@ def iss_sim(test_list, output_dir, iss_list, iss_yaml, isa,
output_dir : Output directory of the ELF files
iss_list : List of instruction set simulators
iss_yaml : ISS configuration file in YAML format
iss_opts : ISS command line options
isa : ISA variant passed to the ISS
setting_dir : Generator setting directory
timeout_s : Timeout limit in seconds
@ -562,6 +563,9 @@ def iss_sim(test_list, output_dir, iss_list, iss_yaml, isa,
elf = prefix + ".o"
log = ("%s/%s.%d.log" % (log_dir, test['test'], i))
cmd = get_iss_cmd(base_cmd, elf, log)
if 'iss_opts' in test:
cmd += ' '
cmd += test['iss_opts']
logging.info("Running %s sim: %s" % (iss, elf))
if iss == "ovpsim":
run_cmd(cmd, timeout_s, check_return_code=False, debug_cmd = debug_cmd)
@ -687,6 +691,8 @@ def setup_parser():
help="Generator timeout limit in seconds")
parser.add_argument("--end_signature_addr", type=str, default="0",
help="Address that privileged CSR test writes to at EOT")
parser.add_argument("--iss_opts", type=str, default="",
help="Any ISS command line arguments")
parser.add_argument("--iss_timeout", type=int, default=10,
help="ISS sim timeout limit in seconds")
parser.add_argument("--iss_yaml", type=str, default="",
@ -924,7 +930,7 @@ def main():
# Run ISS simulation
if args.steps == "all" or re.match(".*iss_sim.*", args.steps):
iss_sim(matched_list, output_dir, args.iss, args.iss_yaml,
iss_sim(matched_list, output_dir, args.iss, args.iss_yaml, args.iss_opts,
args.isa, args.core_setting_dir, args.iss_timeout, args.debug)
# Compare ISS simulation result

View file

@ -261,7 +261,7 @@ class riscv_compressed_instr extends riscv_instr;
binary = $sformatf("%4h", {get_func3(), imm[11], imm[4], imm[9:8],
imm[10], imm[6], imm[7], imm[3:1], imm[5], get_c_opcode()});
C_ADDI16SP:
binary = $sformatf("%4h", {get_func3(), imm[9], 5'b10,
binary = $sformatf("%4h", {get_func3(), imm[9], 5'b00010,
imm[4], imm[6], imm[8:7], imm[5], get_c_opcode()});
C_LUI:
binary = $sformatf("%4h", {get_func3(), imm[5], rd, imm[4:0], get_c_opcode()});

View file

@ -554,13 +554,13 @@ class riscv_instr extends uvm_object;
else if(instr_name == ECALL)
binary = $sformatf("%8h", {get_func7(), 18'b0, get_opcode()});
else if(instr_name inside {URET, SRET, MRET})
binary = $sformatf("%8h", {get_func7(), 5'b10, 13'b0, get_opcode()});
binary = $sformatf("%8h", {get_func7(), 5'b00010, 13'b0, get_opcode()});
else if(instr_name inside {DRET})
binary = $sformatf("%8h", {get_func7(), 5'b10010, 13'b0, get_opcode()});
else if(instr_name == EBREAK)
binary = $sformatf("%8h", {get_func7(), 5'b01, 13'b0, get_opcode()});
binary = $sformatf("%8h", {get_func7(), 5'd1, 13'b0, get_opcode()});
else if(instr_name == WFI)
binary = $sformatf("%8h", {get_func7(), 5'b101, 13'b0, get_opcode()});
binary = $sformatf("%8h", {get_func7(), 5'b00101, 13'b0, get_opcode()});
else
binary = $sformatf("%8h", {imm[11:0], rs1, get_func3(), rd, get_opcode()});
end

View file

@ -555,11 +555,14 @@ class riscv_asm_program_gen extends uvm_object;
// is complete, for any initial state analysis
case(riscv_instr_pkg::supported_privileged_mode[i])
SUPERVISOR_MODE: begin
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR), .csr(SSTATUS));
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR), .csr(SIE));
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR),
.csr(SSTATUS));
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR),
.csr(SIE));
end
USER_MODE: begin
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR), .csr(USTATUS));
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR),
.csr(USTATUS));
gen_signature_handshake(.instr(csr_handshake), .signature_type(WRITE_CSR), .csr(UIE));
end
endcase
@ -744,15 +747,15 @@ class riscv_asm_program_gen extends uvm_object;
// Push user mode GPR to kernel stack before executing exception handling, this is to avoid
// exception handling routine modify user program state unexpectedly
push_gpr_to_kernel_stack(status, scratch, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
// Checking xStatus can be optional if ISS (like spike) has different implementation of certain
// fields compared with the RTL processor.
// Checking xStatus can be optional if ISS (like spike) has different implementation of
// certain fields compared with the RTL processor.
if (cfg.check_xstatus) begin
instr = {instr, $sformatf("csrr x%0d, 0x%0x # %0s", cfg.gpr[0], status, status.name())};
end
instr = {instr,
// Use scratch CSR to save a GPR value
// Check if the exception is caused by an interrupt, if yes, jump to interrupt handler
// Interrupt is indicated by xCause[XLEN-1]
// Check if the exception is caused by an interrupt, if yes, jump to interrupt
// handler Interrupt is indicated by xCause[XLEN-1]
$sformatf("csrr x%0d, 0x%0x # %0s", cfg.gpr[0], cause, cause.name()),
$sformatf("srli x%0d, x%0d, %0d", cfg.gpr[0], cfg.gpr[0], XLEN-1),
$sformatf("bne x%0d, x0, %0smode_intr_handler", cfg.gpr[0], mode)};
@ -833,7 +836,8 @@ class riscv_asm_program_gen extends uvm_object;
for (int i = 1; i < max_interrupt_vector_num; i++) begin
string intr_handler[$];
push_gpr_to_kernel_stack(status, scratch, cfg.mstatus_mprv, cfg.sp, cfg.tp, intr_handler);
gen_signature_handshake(.instr(intr_handler), .signature_type(CORE_STATUS), .core_status(HANDLING_IRQ));
gen_signature_handshake(.instr(intr_handler), .signature_type(CORE_STATUS),
.core_status(HANDLING_IRQ));
intr_handler = {intr_handler,
$sformatf("csrr x%0d, 0x%0x # %0s", cfg.gpr[0], cause, cause.name()),
// Terminate the test if xCause[31] != 0 (indicating exception)
@ -1193,7 +1197,8 @@ class riscv_asm_program_gen extends uvm_object;
virtual function void add_directed_instr_stream(string name, int unsigned ratio);
directed_instr_stream_ratio[name] = ratio;
`uvm_info(`gfn, $sformatf("Adding directed instruction stream:%0s ratio:%0d/1000", name, ratio), UVM_LOW)
`uvm_info(`gfn, $sformatf("Adding directed instruction stream:%0s ratio:%0d/1000", name, ratio),
UVM_LOW)
endfunction
virtual function void get_directed_instr_stream();

View file

@ -82,7 +82,7 @@ class riscv_debug_rom_gen extends riscv_asm_program_gen;
format_section(debug_main);
gen_sub_program(sub_program, sub_program_name,
cfg.num_debug_sub_program, 1'b1, "debug_sub");
main_program = riscv_instr_sequence::type_id::create("debug_program");
main_program = riscv_instr_sequence::type_id::create("main_program");
main_program.instr_cnt = cfg.debug_program_instr_cnt;
main_program.is_debug_program = 1;
main_program.cfg = cfg;

View file

@ -320,12 +320,12 @@ class riscv_illegal_instr extends uvm_object;
constraint illegal_func7_c {
if (!compressed) {
if (exception == kIllegalFunc7) {
!(func7 inside {7'b0, 7'b0100000, 7'b1});
if (opcode == 7'b001001) { // SLLI, SRLI, SRAI
!(func7[6:1] inside {6'b0, 6'b010000});
!(func7 inside {7'd0, 7'b0100000, 7'd1});
if (opcode == 7'b0001001) { // SLLI, SRLI, SRAI
!(func7[6:1] inside {6'd0, 6'b010000});
}
} else {
func7 inside {7'b0, 7'b0100000, 7'b1};
func7 inside {7'd0, 7'b0100000, 7'd1};
}
}
}

View file

@ -73,7 +73,8 @@ class riscv_instr_cov_item extends riscv_instr;
mem_addr = rs1_value + imm;
unaligned_mem_access = is_unaligned_mem_access();
if (unaligned_mem_access) begin
`uvm_info(`gfn, $sformatf("Unaligned: %0s, mem_addr:%0x", instr_name.name(), mem_addr), UVM_HIGH)
`uvm_info(`gfn, $sformatf("Unaligned: %0s, mem_addr:%0x", instr_name.name(), mem_addr),
UVM_HIGH)
end
end
if (category == LOGICAL) begin

View file

@ -245,8 +245,8 @@ class riscv_instr_gen_config extends uvm_object;
enable_sfence == 1'b1;
(init_privileged_mode != SUPERVISOR_MODE) || (mstatus_tvm == 1'b1);
} else {
(init_privileged_mode != SUPERVISOR_MODE || !riscv_instr_pkg::support_sfence || mstatus_tvm || no_fence)
-> (enable_sfence == 1'b0);
(init_privileged_mode != SUPERVISOR_MODE || !riscv_instr_pkg::support_sfence || mstatus_tvm
|| no_fence) -> (enable_sfence == 1'b0);
}
}
@ -640,7 +640,8 @@ class riscv_instr_gen_config extends uvm_object;
end
endfunction
// Populate invalid_priv_mode_csrs with the main implemented CSRs for each supported privilege mode
// Populate invalid_priv_mode_csrs with the main implemented CSRs for each supported privilege
// mode
// TODO(udi) - include performance/pmp/trigger CSRs?
virtual function void get_invalid_priv_lvl_csr();
string invalid_lvl[$];

View file

@ -35,26 +35,6 @@ 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,
@ -522,7 +502,7 @@ package riscv_instr_pkg;
} riscv_instr_name_t;
// Maximum virtual address bits used by the program
parameter MAX_USED_VADDR_BITS = 30;
parameter int MAX_USED_VADDR_BITS = 30;
typedef enum bit [4:0] {
ZERO = 5'b00000,
@ -951,6 +931,29 @@ package riscv_instr_pkg;
`include "riscv_core_setting.sv"
// 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
// TODO (udinator) allow a full 34 bit address for rv32?
typedef struct{
rand bit l;
bit [1:0] zero;
rand pmp_addr_mode_t a;
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;
} pmp_cfg_reg_t;
typedef struct packed {
bit ill;
bit [XLEN-2:7] reserved;
@ -975,19 +978,19 @@ package riscv_instr_pkg;
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;
parameter int IMM25_WIDTH = 25;
parameter int IMM12_WIDTH = 12;
parameter int INSTR_WIDTH = 32;
parameter int DATA_WIDTH = 32;
// Parameters for output assembly program formatting
parameter MAX_INSTR_STR_LEN = 11;
parameter LABEL_STR_LEN = 18;
parameter int MAX_INSTR_STR_LEN = 11;
parameter int 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;
parameter int MAX_CALLSTACK_DEPTH = 20;
parameter int MAX_SUB_PROGRAM_CNT = 20;
parameter int MAX_CALL_PER_FUNC = 5;
string indent = {LABEL_STR_LEN{" "}};
@ -1054,7 +1057,8 @@ package riscv_instr_pkg;
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)
// Check if MPP equals to M-mode('b11)
instr.push_back($sformatf("xori x%0d, x%0d, 0x3", tp, tp));
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));

View file

@ -23,16 +23,16 @@
class riscv_page_table_entry#(satp_mode_t MODE = SV39) extends uvm_object;
// Note that only SV32, SV39, SV48 are supported
parameter PPN0_WIDTH = (MODE == SV32) ? 10 : 9;
parameter PPN1_WIDTH = (MODE == SV32) ? 12 : 9;
parameter PPN2_WIDTH = (MODE == SV39) ? 26 : ((MODE == SV48) ? 9 : 1);
parameter PPN3_WIDTH = (MODE == SV48) ? 9 : 1;
parameter RSVD_WIDTH = (MODE == SV32) ? 1 : 10;
parameter VPN_WIDTH = (MODE == SV32) ? 10 : 9;
parameter int PPN0_WIDTH = (MODE == SV32) ? 10 : 9;
parameter int PPN1_WIDTH = (MODE == SV32) ? 12 : 9;
parameter int PPN2_WIDTH = (MODE == SV39) ? 26 : ((MODE == SV48) ? 9 : 1);
parameter int PPN3_WIDTH = (MODE == SV48) ? 9 : 1;
parameter int RSVD_WIDTH = (MODE == SV32) ? 1 : 10;
parameter int VPN_WIDTH = (MODE == SV32) ? 10 : 9;
// Spare bits in virtual address = XLEN - used virtual address bits
parameter VADDR_SPARE = (MODE == SV32) ? 0 : (MODE == SV39) ? 25 : 16;
parameter int VADDR_SPARE = (MODE == SV32) ? 0 : (MODE == SV39) ? 25 : 16;
// Virtual address bit width
parameter VADDR_WIDTH = (MODE == SV32) ? 31 : (MODE == SV39) ? 38 : 48;
parameter int VADDR_WIDTH = (MODE == SV32) ? 31 : (MODE == SV39) ? 38 : 48;
rand bit v; // PTE is valid
rand pte_permission_t xwr; // PTE execute-write-read permission

View file

@ -27,11 +27,11 @@
class riscv_page_table_list#(satp_mode_t MODE = SV39) extends uvm_object;
localparam PTE_SIZE = XLEN / 8;
localparam PTE_CNT = 4096 / PTE_SIZE;
localparam PAGE_LEVEL = (MODE == SV32) ? 2 : ((MODE == SV39) ? 3 : 4);
localparam LINK_PTE_PER_TABLE = 2;
localparam SUPER_LEAF_PTE_PER_TABLE = 2;
localparam int PteSize = XLEN / 8;
localparam int PteCnt = 4096 / PteSize;
localparam int PageLevel = (MODE == SV32) ? 2 : ((MODE == SV39) ? 3 : 4);
localparam int LinkPtePerTable = 2;
localparam int SuperLeafPtePerTable = 2;
satp_mode_t mode = MODE;
@ -92,7 +92,7 @@ class riscv_page_table_list#(satp_mode_t MODE = SV39) extends uvm_object;
exception_cfg = riscv_page_table_exception_cfg::type_id::create("exception_cfg");
valid_leaf_pte = riscv_page_table_entry#(MODE)::type_id::create("valid_leaf_pte");
valid_link_pte = riscv_page_table_entry#(MODE)::type_id::create("valid_link_pte");
valid_data_leaf_pte = riscv_page_table_entry#(MODE)::type_id::create("valid_link_pte");
valid_data_leaf_pte = riscv_page_table_entry#(MODE)::type_id::create("valid_data_leaf_pte");
illegal_pte = riscv_page_table_entry#(MODE)::type_id::create("illegal_pte");
endfunction
@ -101,8 +101,8 @@ class riscv_page_table_list#(satp_mode_t MODE = SV39) extends uvm_object;
// higher level page table, only PTE[0] and PTE[1] is non-leaf PTE, all other PTEs are leaf
// PTE. All leaf PTE should have PPN map to the real physical address of the instruction
// or data. For non-leaf PTE, the PPN should map to the physical address of the next PTE.
// Take SV39 for example: (PTE_SIZE = 8B)
// Table size is 4KB, PTE_SIZE=8B, entry count = 4K/8 = 512
// Take SV39 for example: (PteSize = 8B)
// Table size is 4KB, PteSize=8B, entry count = 4K/8 = 512
// Level 2: Root table, 2 entries, PTE[0] and PTE[1] is non-leaf PTE, PTE[2] is leaf PTE, all
// other PTEs are invalid, totalling 1 page table with 3 PTEs at this level.
// Level 1: Two page tables, map to PTE[0] and PTE[1] of the root table.
@ -130,10 +130,10 @@ class riscv_page_table_list#(satp_mode_t MODE = SV39) extends uvm_object;
foreach(page_table[i].pte[j]) begin
if(page_table[i].level > 0) begin
// Superpage
if (j < LINK_PTE_PER_TABLE) begin
if (j < LinkPtePerTable) begin
// First few super pages are link PTE to the next level
$cast(page_table[i].pte[j], valid_link_pte.clone());
end else if (j < SUPER_LEAF_PTE_PER_TABLE + LINK_PTE_PER_TABLE) begin
end else if (j < SuperLeafPtePerTable + LinkPtePerTable) begin
// Non-link superpage table entry
$cast(page_table[i].pte[j], valid_leaf_pte.clone());
end else begin
@ -405,9 +405,9 @@ class riscv_page_table_list#(satp_mode_t MODE = SV39) extends uvm_object;
endfunction
virtual function void default_page_table_setting();
num_of_page_table = new[PAGE_LEVEL];
num_of_page_table = new[PageLevel];
foreach(num_of_page_table[i]) begin
num_of_page_table[i] = LINK_PTE_PER_TABLE ** (PAGE_LEVEL - i - 1);
num_of_page_table[i] = LinkPtePerTable ** (PageLevel - i - 1);
end
endfunction
@ -415,7 +415,7 @@ class riscv_page_table_list#(satp_mode_t MODE = SV39) extends uvm_object;
page_table = new[num_of_page_table.sum()];
foreach(page_table[i]) begin
page_table[i] = riscv_page_table#(MODE)::type_id::create($sformatf("page_table_%0d",i));
page_table[i].init_page_table(PTE_CNT);
page_table[i].init_page_table(PteCnt);
page_table[i].table_id = i;
page_table[i].level = get_level(i);
end
@ -441,8 +441,8 @@ class riscv_page_table_list#(satp_mode_t MODE = SV39) extends uvm_object;
instr = {instr, $sformatf("la x%0d, page_table_%0d+2048 # Process PT_%0d",
cfg.gpr[1], i, i)};
foreach(page_table[i].pte[j]) begin
if(j >= SUPER_LEAF_PTE_PER_TABLE) continue;
pte_addr_offset = (j * PTE_SIZE) - 2048;
if(j >= SuperLeafPtePerTable) continue;
pte_addr_offset = (j * PteSize) - 2048;
`uvm_info(`gfn, $sformatf("Processing PT_%0d_PTE_%0d, v = %0d, level = %0d",
i, j, page_table[i].pte[j].v, page_table[i].level), UVM_LOW)
if(page_table[i].pte[j].xwr == NEXT_LEVEL_PAGE) begin
@ -531,14 +531,14 @@ class riscv_page_table_list#(satp_mode_t MODE = SV39) extends uvm_object;
// If you want to create custom page table topology, override the below tasks to specify the
// level and parent of each table.
virtual function int get_level(int table_id);
for(int level = PAGE_LEVEL - 1; level >= 0; level--) begin
for(int level = PageLevel - 1; level >= 0; level--) begin
if(table_id < num_of_page_table[level]) return level;
table_id -= num_of_page_table[level];
end
endfunction
virtual function int get_child_table_id(int table_id, int pte_id);
return table_id * LINK_PTE_PER_TABLE + pte_id + 1;
return table_id * LinkPtePerTable + pte_id + 1;
endfunction
endclass

View file

@ -19,11 +19,14 @@ 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;
int pmp_granularity = 0;
// enable bit for pmp randomization
bit pmp_randomize = 0;
// pmp CSR configurations
rand pmp_cfg_reg_t pmp_cfg[];
// PMP maximum address - used to set defaults
// TODO(udinator) - make this address configurable?
bit [XLEN - 1 : 0] pmp_max_address = {XLEN{1'b1}};
// used to parse addr_mode configuration from cmdline
typedef uvm_enum_wrapper#(pmp_addr_mode_t) addr_mode_wrapper;
@ -40,7 +43,8 @@ class riscv_pmp_cfg extends uvm_object;
pmp_granularity inside {[0 : XLEN + 3]};
}
// TODO(udinator) move these constraints to post_randomize() to save performance
// TODO(udinator) more address constraints?
// TODO(udinator) move to posts_randomize() if lower performance
constraint xwr_c {
foreach (pmp_cfg[i]) {
!(pmp_cfg[i].w && !pmp_cfg[i].r);
@ -56,15 +60,27 @@ class riscv_pmp_cfg extends uvm_object;
function new(string name = "");
string s;
super.new(name);
inst = uvm_cmdline_processor::get_inst();
get_bool_arg_value("+pmp_randomize=", pmp_randomize);
get_int_arg_value("+pmp_granularity=", pmp_granularity);
get_int_arg_value("+pmp_num_regions=", pmp_num_regions);
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
// TODO(udinator) partition address space to map to all active pmp_addr CSRs
// TODO(udinator) set pmp address defaults
// This will only get called if pmp_randomize is set, in which case we apply command line
// arguments after randomization
function void post_randomize();
setup_pmp();
endfunction
function void set_defaults();
foreach(pmp_cfg[i]) begin
pmp_cfg[i].l = 1'b0;
@ -72,15 +88,86 @@ class riscv_pmp_cfg extends uvm_object;
pmp_cfg[i].x = 1'b1;
pmp_cfg[i].w = 1'b1;
pmp_cfg[i].r = 1'b1;
pmp_cfg[i].addr = 34'h3FFFFFFFF;
pmp_cfg[i].addr = assign_default_addr(pmp_num_regions, i + 1);
end
endfunction
// Helper function to break down
function bit [XLEN - 1 : 0] assign_default_addr(int num_regions, int index);
return pmp_max_address / num_regions * index;
endfunction
function void setup_pmp();
string arg_name;
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
foreach (pmp_cfg[i]) begin
arg_name = $sformatf("+pmp_region_%0d=", i);
if (inst.get_arg_value(arg_name, pmp_region)) begin
parse_pmp_config(pmp_region, pmp_cfg[i]);
`uvm_info(`gfn, $sformatf("Configured pmp_cfg[%0d] from command line: %p", i, pmp_cfg[i]), UVM_LOW)
end
end
endfunction
function void parse_pmp_config(string pmp_region, ref pmp_cfg_reg_t pmp_cfg_reg);
string fields[$];
string field_vals[$];
string field_type;
string field_val;
uvm_split_string(pmp_region, ",", fields);
foreach (fields[i]) begin
uvm_split_string(fields[i], ":", field_vals);
field_type = field_vals.pop_front();
field_val = field_vals.pop_front();
case (field_type)
"L": begin
pmp_cfg_reg.l = field_val.atobin();
end
"A": begin
`DV_CHECK(addr_mode_wrapper::from_name(field_val, addr_mode))
pmp_cfg_reg.a = addr_mode;
end
"X": begin
pmp_cfg_reg.x = field_val.atobin();
end
"W": begin
pmp_cfg_reg.w = field_val.atobin();
end
"R": begin
pmp_cfg_reg.r = field_val.atobin();
end
"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());
end
default: begin
`uvm_fatal(`gfn, $sformatf("%s, Invalid PMP configuration field name!", field_val))
end
endcase
end
endfunction
function bit [XLEN - 1 : 0] format_addr(bit [XLEN - 1 : 0] addr);
// For all ISAs, pmpaddr CSRs do not include the bottom two bits of the input address
bit [XLEN - 1 : 0] shifted_addr;
shifted_addr = addr >> 2; case (XLEN)
// RV32 - pmpaddr is bits [33:2] of the whole 34 bit address
// Return the input address right-shifted by 2 bits
32: begin
return shifted_addr;
end
// RV64 - pmpaddr is bits [55:2] of the whole 56 bit address, prepended by 10'b0
// Return {10'b0, shifted_addr[53:0]}
64: begin
return {10'b0, shifted_addr[53:0]};
end
endcase
endfunction
// TODO(udinator) - implement function to return hardware masked pmpaddr "representation"
function bit [XLEN - 1 : 0] convert_addr2pmp(bit [XLEN - 1 : 0] addr);
`uvm_info(`gfn, "Placeholder function, need to implement", UVM_LOW)
endfunction
// This function parses the pmp_cfg[] array to generate the actual instructions to set up
@ -97,7 +184,7 @@ class riscv_pmp_cfg extends uvm_object;
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
// 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};
@ -107,8 +194,8 @@ class riscv_pmp_cfg extends uvm_object;
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]));
`uvm_info(`gfn, $sformatf("pmp_addr: 0x%0x", 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 == pmp_cfg.size() - 1) begin

View file

@ -1,5 +1,5 @@
# riscOVPsim configuration file converted from YAML
--variant RV64I
--variant RVB64I
--override riscvOVPsim/cpu/add_Extensions=MC
--override riscvOVPsim/cpu/misa_MXL=2
--override riscvOVPsim/cpu/misa_MXL_mask=0x0 # 0
@ -17,3 +17,6 @@
--override riscvOVPsim/cpu/time_undefined=T
--override riscvOVPsim/cpu/reset_address=0x80000000
--override riscvOVPsim/cpu/simulateexceptions=T
--override riscvOVPsim/cpu/defaultsemihost=F
--override riscvOVPsim/cpu/wfi_is_nop=T
--exitonsymbol _exit

View file

@ -1,5 +1,5 @@
# riscOVPsim configuration file converted from YAML
--variant RV32I
--variant RVB32I
--override riscvOVPsim/cpu/misa_MXL=1
--override riscvOVPsim/cpu/misa_MXL_mask=0x0 # 0
--override riscvOVPsim/cpu/misa_Extensions_mask=0x0 # 0
@ -16,3 +16,6 @@
--override riscvOVPsim/cpu/time_undefined=T
--override riscvOVPsim/cpu/reset_address=0x80000000
--override riscvOVPsim/cpu/simulateexceptions=T
--override riscvOVPsim/cpu/defaultsemihost=F
--override riscvOVPsim/cpu/wfi_is_nop=T
--exitonsymbol _exit

View file

@ -1,5 +1,5 @@
# riscOVPsim configuration file converted from YAML
--variant RV32I
--variant RVB32I
--override riscvOVPsim/cpu/add_Extensions=MC
--override riscvOVPsim/cpu/misa_MXL=1
--override riscvOVPsim/cpu/misa_MXL_mask=0x0 # 0
@ -17,3 +17,6 @@
--override riscvOVPsim/cpu/time_undefined=T
--override riscvOVPsim/cpu/reset_address=0x80000000
--override riscvOVPsim/cpu/simulateexceptions=T
--override riscvOVPsim/cpu/defaultsemihost=F
--override riscvOVPsim/cpu/wfi_is_nop=T
--exitonsymbol _exit

View file

@ -53,3 +53,14 @@
+hint_instr_ratio=5
rtl_test: core_base_test
- test: riscv_pmp_test
description: >
Provide some PMP configuration parameters, and setup PMP CSRs appropriately
iterations: 2
gen_test: riscv_rand_instr_test
gen_opts: >
+pmp_randomize=0
+pmp_num_regions=1
+pmp_granularity=1
+pmp_region_0=L:0,A:NAPOT,X=1,W=1,R=1,ADDR=0x090000000
rtl_test: core_base_test

View file

@ -16,3 +16,6 @@
--override riscvOVPsim/cpu/time_undefined=T
--override riscvOVPsim/cpu/reset_address=0x80000000
--override riscvOVPsim/cpu/simulateexceptions=T
--override riscvOVPsim/cpu/defaultsemihost=F
--override riscvOVPsim/cpu/wfi_is_nop=T
--exitonsymbol _exit

View file

@ -17,3 +17,6 @@
--override riscvOVPsim/cpu/time_undefined=T
--override riscvOVPsim/cpu/reset_address=0x80000000
--override riscvOVPsim/cpu/simulateexceptions=T
--override riscvOVPsim/cpu/defaultsemihost=F
--override riscvOVPsim/cpu/wfi_is_nop=T
--exitonsymbol _exit

View file

@ -1,5 +1,5 @@
# riscOVPsim configuration file converted from YAML
--variant RV64I
--variant RVB64I
--override riscvOVPsim/cpu/add_Extensions=MC
--override riscvOVPsim/cpu/misa_MXL=2
--override riscvOVPsim/cpu/misa_MXL_mask=0x0 # 0
@ -17,3 +17,6 @@
--override riscvOVPsim/cpu/time_undefined=T
--override riscvOVPsim/cpu/reset_address=0x80000000
--override riscvOVPsim/cpu/simulateexceptions=T
--override riscvOVPsim/cpu/defaultsemihost=F
--override riscvOVPsim/cpu/wfi_is_nop=T
--exitonsymbol _exit

View file

@ -0,0 +1,68 @@
#!/bin/bash
#
# Copyright 2019 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.
VERIBLE_VERSION=03c7102ab8ed63037159f479ce17b3487401f082
INSTALL_DIR=/tools/verible
# this requires the bazel build system and GCC7
# see https://docs.bazel.build/versions/master/install-ubuntu.html
echo "checking whether bazel is installed..."
if which bazel; then
echo "OK"
else
echo "bazel is not installed. installing bazel..."
sudo apt install curl -y
curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" \
| sudo tee /etc/apt/sources.list.d/bazel.list
sudo apt update && sudo apt install bazel -y
fi
# upgrade to GCC7
# TODO: check whether we need to maintain the default symlinks here
# for gcc -> GCC-5* such that other tools still work.
echo "checking whether GCC7 is installed..."
if which gcc-7; then
echo "OK"
else
echo "Error: GCC7 is not installed. Exit and Verible isn't installed"
exit 0
fi
# get verible and install under /tools/verible
# note: you may add $INSTALL_DIR to the PATH, but it is not
# required for the run scripts to work.
echo "Installing Verible ($VERIBLE_VERSION)..."
mkdir -p build && cd build
git clone https://github.com/google/verible.git
cd verible
git pull origin master
git checkout $VERIBLE_VERSION
bazel build --cxxopt='-std=c++17' //...
bazel test --cxxopt='-std=c++17' //...
sudo mkdir -p $INSTALL_DIR
sudo install bazel-bin/verilog/tools/syntax/verilog_syntax $INSTALL_DIR
sudo install bazel-bin/verilog/tools/formatter/verilog_format $INSTALL_DIR
sudo install bazel-bin/verilog/tools/lint/verilog_lint $INSTALL_DIR
echo "done"

View file

@ -0,0 +1,10 @@
# Current Verible can not support some syntax used in following files. List them here to exclude
# from Verilog style check
# tool does not support macro very well. Issue at github.com/google/verible/issues/102
riscv_instr_cover_group.sv
riscv_instr_pkg.sv
# tool does not support included file very well. Issue at github.com/google/verible/issues/178
riscv_custom_instr_enum.sv
# tool bug. Issue at github.com/google/verible/issues/172
riscv_instr_stream.sv
riscv_reg.sv

19
vendor/google_riscv-dv/verilog_style/run.sh vendored Executable file
View file

@ -0,0 +1,19 @@
#!/bin/bash
#
# Copyright 2019 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.
find src/ -type f \( -name "*.sv" -o -name "*.svh" \) \
| grep -vFf ./verilog_style/exclude_filelist.f \
| xargs /tools/verible/verilog_lint --rules=-macro-name-style

View file

@ -23,7 +23,6 @@
<path_var>/riscvOVPsim.exe
--controlfile <cfg_path>/riscvOVPsim.ic
--objfilenoentry <elf>
--override riscvOVPsim/cpu/PMP_registers=0
--override riscvOVPsim/cpu/simulateexceptions=T
--trace --tracechange --traceshowicount --tracemode --traceregs
--finishafter 1000000

View file

@ -20,6 +20,7 @@
+incdir+<user_extension>
-f <cwd>/files.f -full64
-l <out>/compile.log
-LDFLAGS '-Wl,--no-as-needed'
-Mdir=<out>/vcs_simv.csrc
-o <out>/vcs_simv <cmp_opts> <cov_opts> "
cov_opts: >
@ -42,7 +43,7 @@
-l <out>/compile.log <cmp_opts>"
sim:
cmd: >
irun -R <sim_opts> -svseed <seed>
irun -R <sim_opts> -svseed <seed> -svrnc rand_struct
- tool: questa
compile: