Skip to content

Commit

Permalink
Merge pull request openhwgroup#1044 from strichmo/strichmo/pr/rvfi_mu…
Browse files Browse the repository at this point in the history
…lti_bit_trap

bus error test fixes and incorporate multi-bit traps
  • Loading branch information
MikeOpenHWGroup committed Dec 3, 2021
2 parents c8592f1 + 03d6fdc commit 7d0b850
Show file tree
Hide file tree
Showing 16 changed files with 201 additions and 52 deletions.
16 changes: 14 additions & 2 deletions cv32e40x/env/corev-dv/cv32e40x_debug_rom_gen.sv
Expand Up @@ -148,12 +148,24 @@ class cv32e40x_debug_rom_gen extends riscv_debug_rom_gen;
endfunction : gen_program

virtual function void gen_debug_exception_handler();

cv32e40x_instr_gen_config cfg_corev;

// CORE-V Addition
// Cast CORE-V derived handle to enable fetching core-v config fields
`DV_CHECK($cast(cfg_corev, cfg))

// Insert section info so linker can place
// debug exception code at the correct adress
instr_stream.push_back(".section .debugger_exception, \"ax\"");
//super.gen_debug_exception_handler();

str = {"ebreak"};
if (cfg_corev.exit_on_debug_exception) begin
str = {"la x1, test_done", "jr x1"};
end
else begin
str = {"ebreak"};
end

gen_section($sformatf("%0sdebug_exception", hart_prefix(hart)), str);

// Insert section info to place remaining code in the
Expand Down
3 changes: 3 additions & 0 deletions cv32e40x/env/corev-dv/cv32e40x_instr_gen_config.sv
Expand Up @@ -27,6 +27,7 @@ class cv32e40x_instr_gen_config extends riscv_instr_gen_config;
// External config control (plusarg) to enable/disable fast_interrupt handlers
bit enable_fast_interrupt_handler;
bit enable_pma;
bit exit_on_debug_exception;
cv32e40x_pma_cfg pma_cfg;

// Knob to set zero fast interrupt handler
Expand Down Expand Up @@ -91,13 +92,15 @@ class cv32e40x_instr_gen_config extends riscv_instr_gen_config;
`uvm_field_int(enable_fast_interrupt_handler, UVM_DEFAULT)
`uvm_field_int(use_fast_intr_handler, UVM_DEFAULT)
`uvm_field_int(enable_pma, UVM_DEFAULT)
`uvm_field_int(exit_on_debug_exception, UVM_DEFAULT)
`uvm_object_utils_end

function new(string name="");
super.new(name);

get_bool_arg_value("+enable_fast_interrupt_handler=", enable_fast_interrupt_handler);
get_bool_arg_value("+enable_pma=", enable_pma);
get_bool_arg_value("+exit_on_debug_exception=", exit_on_debug_exception);

if (enable_pma) begin
pma_cfg = cv32e40x_pma_cfg::type_id::create("pma_cfg");
Expand Down
24 changes: 17 additions & 7 deletions cv32e40x/env/uvme/uvme_cv32e40x_cfg.sv
Expand Up @@ -32,6 +32,7 @@ class uvme_cv32e40x_cfg_c extends uvma_core_cntrl_cfg_c;
bit obi_memory_instr_one_shot_err_enabled = 0;
bit obi_memory_data_random_err_enabled = 0;
bit obi_memory_data_one_shot_err_enabled = 0;
rand bit buserr_scoreboarding_enabled = 1;

// Agent cfg handles
rand uvma_isacov_cfg_c isacov_cfg;
Expand All @@ -50,6 +51,7 @@ class uvme_cv32e40x_cfg_c extends uvma_core_cntrl_cfg_c;
`uvm_field_enum(uvm_active_passive_enum, is_active , UVM_DEFAULT )
`uvm_field_int ( cov_model_enabled , UVM_DEFAULT )
`uvm_field_int ( trn_log_enabled , UVM_DEFAULT )
`uvm_field_int ( buserr_scoreboarding_enabled, UVM_DEFAULT )
`uvm_field_int ( sys_clk_period , UVM_DEFAULT | UVM_DEC)
`uvm_field_enum (cv32e40x_pkg::b_ext_e, b_ext , UVM_DEFAULT )
`uvm_field_int ( obi_memory_instr_random_err_enabled, UVM_DEFAULT )
Expand All @@ -70,12 +72,13 @@ class uvme_cv32e40x_cfg_c extends uvma_core_cntrl_cfg_c;
`uvm_object_utils_end

constraint defaults_cons {
soft enabled == 0;
soft is_active == UVM_PASSIVE;
soft scoreboarding_enabled == 1;
soft cov_model_enabled == 1;
soft trn_log_enabled == 1;
soft sys_clk_period == uvme_cv32e40x_sys_default_clk_period; // see uvme_cv32e40x_constants.sv
soft enabled == 0;
soft is_active == UVM_PASSIVE;
soft scoreboarding_enabled == 1;
soft cov_model_enabled == 1;
soft trn_log_enabled == 1;
soft sys_clk_period == uvme_cv32e40x_sys_default_clk_period; // see uvme_cv32e40x_constants.sv
soft buserr_scoreboarding_enabled == 1;
}

constraint cv32e40x_riscv_cons {
Expand Down Expand Up @@ -243,7 +246,8 @@ class uvme_cv32e40x_cfg_c extends uvma_core_cntrl_cfg_c;
}

if (!scoreboarding_enabled) {
pma_cfg.scoreboard_enabled == 0;
buserr_scoreboarding_enabled == 0;
pma_cfg.scoreboard_enabled == 0;
}
}

Expand Down Expand Up @@ -313,6 +317,11 @@ function uvme_cv32e40x_cfg_c::new(string name="uvme_cv32e40x_cfg");
trn_log_enabled = 0;
trn_log_enabled.rand_mode(0);
end
if ($test$plusargs("buserr_sb_disabled")) begin
buserr_scoreboarding_enabled = 0;
buserr_scoreboarding_enabled.rand_mode(0);
end

if ($test$plusargs("obi_memory_instr_random_err"))
obi_memory_instr_random_err_enabled = 1;
if ($test$plusargs("obi_memory_instr_one_shot_err"))
Expand Down Expand Up @@ -425,3 +434,4 @@ endfunction : configure_disable_csr_checks

`endif // __UVME_CV32E40X_CFG_SV__


13 changes: 9 additions & 4 deletions cv32e40x/env/uvme/uvme_cv32e40x_env.sv
Expand Up @@ -360,6 +360,9 @@ function void uvme_cv32e40x_env_c::create_env_components();
predictor = uvme_cv32e40x_prd_c::type_id::create("predictor", this);
sb = uvme_cv32e40x_sb_c::type_id::create("sb" , this);
core_sb = uvme_cv32e40x_core_sb_c::type_id::create("core_sb", this);
end

if (cfg.buserr_scoreboarding_enabled) begin
buserr_sb = uvme_cv32e40x_buserr_sb_c::type_id::create("buserr_sb", this);
end

Expand Down Expand Up @@ -402,10 +405,12 @@ function void uvme_cv32e40x_env_c::connect_scoreboard();
end

// Connect the bus error scoreboard
obi_memory_data_agent.mon_ap.connect(buserr_sb.obid);
obi_memory_instr_agent.mon_ap.connect(buserr_sb.obii);
foreach (rvfi_agent.instr_mon_ap[i]) begin
rvfi_agent.instr_mon_ap[i].connect(buserr_sb.rvfi);
if (cfg.buserr_scoreboarding_enabled) begin
obi_memory_data_agent.mon_ap.connect(buserr_sb.obid);
obi_memory_instr_agent.mon_ap.connect(buserr_sb.obii);
foreach (rvfi_agent.instr_mon_ap[i]) begin
rvfi_agent.instr_mon_ap[i].connect(buserr_sb.rvfi);
end
end

// Connect the PMA scoreboard
Expand Down
2 changes: 1 addition & 1 deletion cv32e40x/sim/Common.mk
Expand Up @@ -15,7 +15,7 @@ export SHELL = /bin/bash

CV_CORE_REPO ?= https://github.com/openhwgroup/cv32e40x
CV_CORE_BRANCH ?= master
CV_CORE_HASH ?= 5f1fc00073b4618d897582961140ac5bab5501b9
CV_CORE_HASH ?= af71c0ec7754fd87ce25335ef584de605aa68ca9
CV_CORE_TAG ?= none

RISCVDV_REPO ?= https://github.com/google/riscv-dv
Expand Down
2 changes: 1 addition & 1 deletion cv32e40x/tb/uvmt/uvmt_cv32e40x_tb.sv
Expand Up @@ -113,7 +113,7 @@ module uvmt_cv32e40x_tb;
.rvfi_valid(rvfi_i.rvfi_valid[0]),
.rvfi_order(rvfi_i.rvfi_order[uvma_rvfi_pkg::ORDER_WL*0+:uvma_rvfi_pkg::ORDER_WL]),
.rvfi_insn(rvfi_i.rvfi_insn[uvme_cv32e40x_pkg::ILEN*0+:uvme_cv32e40x_pkg::ILEN]),
.rvfi_trap(rvfi_i.rvfi_trap[0]),
.rvfi_trap(rvfi_i.rvfi_trap[11:0]),
.rvfi_halt(rvfi_i.rvfi_halt[0]),
.rvfi_intr(rvfi_i.rvfi_intr[0]),
.rvfi_dbg(rvfi_i.rvfi_dbg),
Expand Down
Expand Up @@ -4,8 +4,10 @@ name: corev_rand_data_obi_err
uvm_test: uvmt_$(CV_CORE_LC)_firmware_test_c
description: >
Random instruction test generated by corev-dv with random data bus errors
# FIXME:please remove the buserr_sb_disabled plusarg once fixes are made
plusargs: >
+random_fetch_toggle
+obi_memory_data_random_err_enabled
+obi_memory_data_one_shot_err_enabled
+gen_irq_noise
+buserr_sb_disabled
Expand Up @@ -2,9 +2,11 @@ name: corev_rand_data_obi_err_debug
uvm_test: uvmt_$(CV_CORE_LC)_firmware_test_c
description: >
Random instruction test generated by corev-dv with random data bus errors in debug mode
# FIXME:please remove the buserr_sb_disabled plusarg once fixes are made
plusargs: >
+random_fetch_toggle
+obi_memory_data_random_err_enabled
+obi_memory_data_one_shot_err_enabled
+gen_irq_noise
+gen_random_debug
+buserr_sb_disabled
Expand Up @@ -4,8 +4,10 @@ name: corev_rand_instr_obi_err
uvm_test: uvmt_$(CV_CORE_LC)_firmware_test_c
description: >
Random instruction test generated by corev-dv with random instruction bus errors
# FIXME:please remove the buserr_sb_disabled plusarg once fixes are made
plusargs: >
+random_fetch_toggle
+obi_memory_instr_random_err_enabled
+obi_memory_instr_one_shot_err_enabled
+gen_irq_noise
+buserr_sb_disabled
Expand Up @@ -24,3 +24,4 @@ plusargs: >
+set_dcsr_ebreak=0
+enable_debug_single_step=1
+gen_debug_section=1
+exit_on_debug_exception=1
Expand Up @@ -2,9 +2,11 @@ name: corev_rand_instr_obi_err_debug
uvm_test: uvmt_$(CV_CORE_LC)_firmware_test_c
description: >
Random instruction test generated by corev-dv with random instruction bus errors in debug mode
# FIXME:please remove the buserr_sb_disabled plusarg once fixes are made
plusargs: >
+random_fetch_toggle
+obi_memory_instr_random_err_enabled
+obi_memory_instr_one_shot_err_enabled
+gen_irq_noise
+gen_random_debug
+buserr_sb_disabled
65 changes: 60 additions & 5 deletions lib/uvm_agents/uvma_rvfi/seq/uvma_rvfi_instr_seq_item.sv
Expand Up @@ -28,13 +28,13 @@ class uvma_rvfi_instr_seq_item_c#(int ILEN=DEFAULT_ILEN,
rand bit [CYCLE_CNT_WL-1:0] cycle_cnt;
rand bit [ORDER_WL-1:0] order;
rand bit [ILEN-1:0] insn;
rand bit trap;
rand bit [TRAP_WL-1:0] trap;
rand bit halt;
rand bit dbg_mode;
rand bit [RVFI_DBG_WL-1:0] dbg;
rand bit intr;
rand uvma_rvfi_mode mode;
rand bit [IXL_WL-1:0] ixl;
rand bit [RVFI_DBG_WL-1:0] dbg;
rand bit dbg_mode;

rand bit insn_nmi;
rand bit insn_interrupt;
Expand Down Expand Up @@ -131,6 +131,31 @@ class uvma_rvfi_instr_seq_item_c#(int ILEN=DEFAULT_ILEN,
*/
extern function bit is_compressed_insn();

/**
* Decode if instruction is a trap
*/
extern function bit is_trap();

/*
* Decode if instruction is a synchronous trap with debug entry
*/
extern function bit is_debug_entry_trap();

/*
* Decode if instruction is a synchronous trap without debug entry
*/
extern function bit is_nondebug_entry_trap();

/*
* Retrieve trap cause field
*/
extern function bit [TRAP_CAUSE_WL-1:0] get_trap_cause();

/*
* Retrieve trap debug cause
*/
extern function bit [TRAP_DBG_CAUSE_WL-1:0] get_trap_debug_cause();

endclass : uvma_rvfi_instr_seq_item_c

`pragma protect begin
Expand All @@ -155,8 +180,8 @@ function string uvma_rvfi_instr_seq_item_c::convert2string();
convert2string = $sformatf("%s rd: x%0d = 0x%08x", convert2string, rd1_addr, rd1_wdata);
if (rd2_addr)
convert2string = $sformatf("%s rd2: x%0d = 0x%08x", convert2string, rd2_addr, rd2_wdata);
// if (trap)
// convert2string = $sformatf("%s TRAP", convert2string);
if (trap)
convert2string = $sformatf("%s TRAP %0d", convert2string, trap);
if (halt)
convert2string = $sformatf("%s HALT", convert2string);
if (insn_interrupt)
Expand Down Expand Up @@ -212,6 +237,36 @@ function bit uvma_rvfi_instr_seq_item_c::is_compressed_insn();

endfunction : is_compressed_insn

function bit uvma_rvfi_instr_seq_item_c::is_trap();

return trap[TRAP_EXCP_LSB];

endfunction : is_trap

function bit uvma_rvfi_instr_seq_item_c::is_debug_entry_trap();

return trap[TRAP_DBG_ENTRY_LSB];

endfunction : is_debug_entry_trap

function bit uvma_rvfi_instr_seq_item_c::is_nondebug_entry_trap();

return trap[TRAP_NONDBG_ENTRY_LSB];

endfunction : is_nondebug_entry_trap

function bit [TRAP_CAUSE_WL-1:0] uvma_rvfi_instr_seq_item_c::get_trap_cause();

return trap[TRAP_CAUSE_LSB +: TRAP_CAUSE_WL];

endfunction : get_trap_cause

function bit [TRAP_DBG_CAUSE_WL-1:0] uvma_rvfi_instr_seq_item_c::get_trap_debug_cause();

return trap[TRAP_DBG_CAUSE_LSB +: TRAP_DBG_CAUSE_WL];

endfunction : get_trap_debug_cause

`pragma protect end


Expand Down
16 changes: 15 additions & 1 deletion lib/uvm_agents/uvma_rvfi/uvma_rvfi_constants.sv
Expand Up @@ -18,16 +18,30 @@
`ifndef __UVMA_RVFI_CONSTANTS_SV__
`define __UVMA_RVFI_CONSTANTS_SV__


// RVFI field widths
localparam ORDER_WL = 64;
localparam MODE_WL = 2;
localparam IXL_WL = 2;
localparam TRAP_WL = 12;
localparam GPR_ADDR_WL = 5;
localparam RVFI_DBG_WL = 3;
localparam CYCLE_CNT_WL = 32;

// Fields within TRAP
localparam TRAP_EXCP_LSB = 0;
localparam TRAP_EXCP_WL = 1;
localparam TRAP_NONDBG_ENTRY_LSB = 1;
localparam TRAP_NONDBG_ENTRY_WL = 1;
localparam TRAP_DBG_ENTRY_LSB = 2;
localparam TRAP_DBG_ENTRY_WL = 1;
localparam TRAP_CAUSE_LSB = 3;
localparam TRAP_CAUSE_WL = 6;
localparam TRAP_DBG_CAUSE_LSB = 9;
localparam TRAP_DBG_CAUSE_WL = 3;

localparam DEFAULT_ILEN = 32;
localparam DEFAULT_XLEN = 32;
localparam DEFAULT_NRET = 1;


`endif // __UVMA_RVFI_CONSTANTS_SV__
2 changes: 1 addition & 1 deletion lib/uvm_agents/uvma_rvfi/uvma_rvfi_instr_if.sv
Expand Up @@ -34,7 +34,7 @@ interface uvma_rvfi_instr_if
input rvfi_valid,
input [ORDER_WL-1:0] rvfi_order,
input [ILEN-1:0] rvfi_insn,
input rvfi_trap,
input [TRAP_WL-1:0] rvfi_trap,
input rvfi_halt,
input [RVFI_DBG_WL-1:0] rvfi_dbg,
input rvfi_dbg_mode,
Expand Down
10 changes: 6 additions & 4 deletions lib/uvm_agents/uvma_rvfi/uvma_rvfi_instr_mon.sv
Expand Up @@ -192,15 +192,16 @@ task uvma_rvfi_instr_mon_c::monitor_rvfi_instr();
mon_trn.insn_interrupt_id = { 1'b0, csr_mcause[XLEN-2:0] };
end
else if (mon_trn.intr) begin
bit [XLEN-1:0] csr_mcause = mon_trn.csrs["mcause"].get_csr_retirement_data();
//bit [XLEN-1:0] csr_mcause = mon_trn.csrs["mcause"].get_csr_retirement_data();
bit [XLEN-1:0] csr_mcause = mon_trn.csrs["mcause"].rdata;

if (csr_mcause[31]) begin
mon_trn.insn_interrupt = 1;
mon_trn.insn_interrupt_id = { 1'b0, csr_mcause[XLEN-2:0] };
end
end

// In debug mode, detect NMIP event
// In debug mode, detect NMIP event for a data bus error
if (cfg.nmi_handler_enabled &&
mon_trn.dbg_mode &&
!last_dcsr_nmip &&
Expand All @@ -211,9 +212,10 @@ task uvma_rvfi_instr_mon_c::monitor_rvfi_instr();

// Detect instruction bus fault
if (cfg.insn_bus_fault_enabled &&
mon_trn.trap &&
mon_trn.csrs["mcause"].get_csr_retirement_data() == cfg.insn_bus_fault_cause) begin
mon_trn.is_trap() &&
mon_trn.get_trap_cause() == cfg.insn_bus_fault_cause) begin
mon_trn.insn_bus_fault = 1;
`uvm_info("RVFIMON", $sformatf("Detected bus fault"), UVM_LOW)
end

last_dcsr_nmip = mon_trn.csrs["dcsr"].get_csr_retirement_data()[3];
Expand Down

0 comments on commit 7d0b850

Please sign in to comment.