mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-20 03:47:15 -04:00
[dv] Update testbench to use new 'pre_val' MIP
The 'pre_val' MIP addresses the scenario where MIP changes as an instruction is excuting, this means a CSR instruction can observe a different MIP from the one that decides whether or not that instruction will be interrupted.
This commit is contained in:
parent
3964804815
commit
e784d27464
16 changed files with 68 additions and 38 deletions
|
@ -87,7 +87,7 @@ class Cosim {
|
|||
//
|
||||
// At the next call of `step`, the MIP value will take effect (i.e. if it's a
|
||||
// new interrupt that is enabled it will step straight to that handler).
|
||||
virtual void set_mip(uint32_t mip) = 0;
|
||||
virtual void set_mip(uint32_t pre_mip, uint32_t post_mip) = 0;
|
||||
|
||||
// Set the state of the NMI (non-maskable interrupt) line.
|
||||
//
|
||||
|
|
|
@ -19,10 +19,10 @@ int riscv_cosim_step(Cosim *cosim, const svBitVecVal *write_reg,
|
|||
: 0;
|
||||
}
|
||||
|
||||
void riscv_cosim_set_mip(Cosim *cosim, const svBitVecVal *mip) {
|
||||
void riscv_cosim_set_mip(Cosim *cosim, const svBitVecVal *pre_mip, const svBitVecVal *post_mip) {
|
||||
assert(cosim);
|
||||
|
||||
cosim->set_mip(mip[0]);
|
||||
cosim->set_mip(pre_mip[0], post_mip[0]);
|
||||
}
|
||||
|
||||
void riscv_cosim_set_nmi(Cosim *cosim, svBit nmi) {
|
||||
|
|
|
@ -15,7 +15,7 @@ extern "C" {
|
|||
int riscv_cosim_step(Cosim *cosim, const svBitVecVal *write_reg,
|
||||
const svBitVecVal *write_reg_data, const svBitVecVal *pc,
|
||||
svBit sync_trap, svBit suppress_reg_write);
|
||||
void riscv_cosim_set_mip(Cosim *cosim, const svBitVecVal *mip);
|
||||
void riscv_cosim_set_mip(Cosim *cosim, const svBitVecVal *pre_mip, const svBitVecVal *post_mip);
|
||||
void riscv_cosim_set_nmi(Cosim *cosim, svBit nmi);
|
||||
void riscv_cosim_set_nmi_int(Cosim *cosim, svBit nmi_int);
|
||||
void riscv_cosim_set_debug_req(Cosim *cosim, svBit debug_req);
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
|
||||
import "DPI-C" function int riscv_cosim_step(chandle cosim_handle, bit [4:0] write_reg,
|
||||
bit [31:0] write_reg_data, bit [31:0] pc, bit sync_trap, bit suppress_reg_write);
|
||||
import "DPI-C" function void riscv_cosim_set_mip(chandle cosim_handle, bit [31:0] mip);
|
||||
import "DPI-C" function void riscv_cosim_set_mip(chandle cosim_handle, bit [31:0] pre_mip,
|
||||
bit [31:0] post_mip);
|
||||
import "DPI-C" function void riscv_cosim_set_nmi(chandle cosim_handle, bit nmi);
|
||||
import "DPI-C" function void riscv_cosim_set_nmi_int(chandle cosim_handle, bit nmi_int);
|
||||
import "DPI-C" function void riscv_cosim_set_debug_req(chandle cosim_handle, bit debug_req);
|
||||
|
|
|
@ -584,11 +584,12 @@ void SpikeCosim::initial_proc_setup(uint32_t start_pc, uint32_t start_mtvec,
|
|||
}
|
||||
}
|
||||
|
||||
void SpikeCosim::set_mip(uint32_t mip) {
|
||||
uint32_t new_mip = mip;
|
||||
void SpikeCosim::set_mip(uint32_t pre_mip, uint32_t post_mip) {
|
||||
uint32_t new_mip = pre_mip;
|
||||
uint32_t old_mip = processor->get_state()->mip->read();
|
||||
|
||||
processor->get_state()->mip->write_with_mask(0xffffffff, mip);
|
||||
processor->get_state()->mip->write_with_mask(0xffffffff, post_mip);
|
||||
processor->get_state()->mip->write_pre_val(pre_mip);
|
||||
|
||||
if (processor->get_state()->debug_mode ||
|
||||
(processor->halt_request == processor_t::HR_REGULAR) ||
|
||||
|
|
|
@ -125,7 +125,7 @@ class SpikeCosim : public simif_t, public Cosim {
|
|||
uint32_t dut_pc, bool suppress_reg_write);
|
||||
bool check_sync_trap(uint32_t write_reg, uint32_t pc,
|
||||
uint32_t initial_spike_pc);
|
||||
void set_mip(uint32_t mip) override;
|
||||
void set_mip(uint32_t pre_mip, uint32_t post_mip) override;
|
||||
void set_nmi(bool nmi) override;
|
||||
void set_nmi_int(bool nmi_int) override;
|
||||
void set_debug_req(bool debug_req) override;
|
||||
|
|
|
@ -120,7 +120,7 @@ class ibex_cosim_scoreboard extends uvm_scoreboard;
|
|||
// cosim with interrupt information and loop back to await the next item.
|
||||
riscv_cosim_set_nmi(cosim_handle, rvfi_instr.nmi);
|
||||
riscv_cosim_set_nmi_int(cosim_handle, rvfi_instr.nmi_int);
|
||||
riscv_cosim_set_mip(cosim_handle, rvfi_instr.mip);
|
||||
riscv_cosim_set_mip(cosim_handle, rvfi_instr.pre_mip, rvfi_instr.pre_mip);
|
||||
|
||||
continue;
|
||||
end
|
||||
|
@ -145,7 +145,7 @@ class ibex_cosim_scoreboard extends uvm_scoreboard;
|
|||
riscv_cosim_set_debug_req(cosim_handle, rvfi_instr.debug_req);
|
||||
riscv_cosim_set_nmi(cosim_handle, rvfi_instr.nmi);
|
||||
riscv_cosim_set_nmi_int(cosim_handle, rvfi_instr.nmi_int);
|
||||
riscv_cosim_set_mip(cosim_handle, rvfi_instr.mip);
|
||||
riscv_cosim_set_mip(cosim_handle, rvfi_instr.pre_mip, rvfi_instr.post_mip);
|
||||
riscv_cosim_set_mcycle(cosim_handle, rvfi_instr.mcycle);
|
||||
|
||||
// Set performance counters through a pseudo-backdoor write
|
||||
|
|
|
@ -37,7 +37,8 @@ class ibex_rvfi_monitor extends uvm_monitor;
|
|||
trans_collected.rd_addr = vif.monitor_cb.rd_addr;
|
||||
trans_collected.rd_wdata = vif.monitor_cb.rd_wdata;
|
||||
trans_collected.order = vif.monitor_cb.order;
|
||||
trans_collected.mip = vif.monitor_cb.ext_mip;
|
||||
trans_collected.pre_mip = vif.monitor_cb.ext_pre_mip;
|
||||
trans_collected.post_mip = vif.monitor_cb.ext_post_mip;
|
||||
trans_collected.nmi = vif.monitor_cb.ext_nmi;
|
||||
trans_collected.nmi_int = vif.monitor_cb.ext_nmi_int;
|
||||
trans_collected.debug_req = vif.monitor_cb.ext_debug_req;
|
||||
|
|
|
@ -9,7 +9,8 @@ class ibex_rvfi_seq_item extends uvm_sequence_item;
|
|||
bit [4:0] rd_addr;
|
||||
bit [31:0] rd_wdata;
|
||||
bit [63:0] order;
|
||||
bit [31:0] mip;
|
||||
bit [31:0] pre_mip;
|
||||
bit [31:0] post_mip;
|
||||
bit nmi;
|
||||
bit nmi_int;
|
||||
bit debug_req;
|
||||
|
@ -26,7 +27,8 @@ class ibex_rvfi_seq_item extends uvm_sequence_item;
|
|||
`uvm_field_int (rd_addr, UVM_DEFAULT)
|
||||
`uvm_field_int (rd_wdata, UVM_DEFAULT)
|
||||
`uvm_field_int (order, UVM_DEFAULT)
|
||||
`uvm_field_int (mip, UVM_DEFAULT)
|
||||
`uvm_field_int (pre_mip, UVM_DEFAULT)
|
||||
`uvm_field_int (post_mip, UVM_DEFAULT)
|
||||
`uvm_field_int (nmi, UVM_DEFAULT)
|
||||
`uvm_field_int (nmi_int, UVM_DEFAULT)
|
||||
`uvm_field_int (debug_req, UVM_DEFAULT)
|
||||
|
|
6
dv/uvm/core_ibex/env/core_ibex_rvfi_if.sv
vendored
6
dv/uvm/core_ibex/env/core_ibex_rvfi_if.sv
vendored
|
@ -26,7 +26,8 @@ interface core_ibex_rvfi_if(input logic clk);
|
|||
logic [3:0] mem_wmask;
|
||||
logic [31:0] mem_rdata;
|
||||
logic [31:0] mem_wdata;
|
||||
logic [31:0] ext_mip;
|
||||
logic [31:0] ext_pre_mip;
|
||||
logic [31:0] ext_post_mip;
|
||||
logic ext_nmi;
|
||||
logic ext_nmi_int;
|
||||
logic [31:0] ext_debug_req;
|
||||
|
@ -62,7 +63,8 @@ interface core_ibex_rvfi_if(input logic clk);
|
|||
input mem_wmask;
|
||||
input mem_rdata;
|
||||
input mem_wdata;
|
||||
input ext_mip;
|
||||
input ext_pre_mip;
|
||||
input ext_post_mip;
|
||||
input ext_nmi;
|
||||
input ext_nmi_int;
|
||||
input ext_debug_req;
|
||||
|
|
|
@ -202,7 +202,8 @@ module core_ibex_tb_top;
|
|||
assign rvfi_if.mem_rmask = dut.rvfi_mem_rmask;
|
||||
assign rvfi_if.mem_rdata = dut.rvfi_mem_rdata;
|
||||
assign rvfi_if.mem_wdata = dut.rvfi_mem_wdata;
|
||||
assign rvfi_if.ext_mip = dut.rvfi_ext_mip;
|
||||
assign rvfi_if.ext_pre_mip = dut.rvfi_ext_pre_mip;
|
||||
assign rvfi_if.ext_post_mip = dut.rvfi_ext_post_mip;
|
||||
assign rvfi_if.ext_nmi = dut.rvfi_ext_nmi;
|
||||
assign rvfi_if.ext_nmi_int = dut.rvfi_ext_nmi_int;
|
||||
assign rvfi_if.ext_debug_req = dut.rvfi_ext_debug_req;
|
||||
|
|
|
@ -44,7 +44,7 @@ module ibex_simple_system_cosim_checker #(
|
|||
if (u_top.rvfi_valid) begin
|
||||
riscv_cosim_set_nmi(cosim_handle, u_top.rvfi_ext_nmi);
|
||||
riscv_cosim_set_nmi_int(cosim_handle, u_top.rvfi_ext_nmi_int);
|
||||
riscv_cosim_set_mip(cosim_handle, u_top.rvfi_ext_mip);
|
||||
riscv_cosim_set_mip(cosim_handle, u_top.rvfi_ext_pre_mip, u_top.rvfi_ext_post_mip);
|
||||
riscv_cosim_set_debug_req(cosim_handle, u_top.rvfi_ext_debug_req);
|
||||
riscv_cosim_set_mcycle(cosim_handle, u_top.rvfi_ext_mcycle);
|
||||
for (int i=0; i < 10; i++) begin
|
||||
|
|
|
@ -141,7 +141,8 @@ module ibex_core import ibex_pkg::*; #(
|
|||
output logic [ 3:0] rvfi_mem_wmask,
|
||||
output logic [31:0] rvfi_mem_rdata,
|
||||
output logic [31:0] rvfi_mem_wdata,
|
||||
output logic [31:0] rvfi_ext_mip,
|
||||
output logic [31:0] rvfi_ext_pre_mip,
|
||||
output logic [31:0] rvfi_ext_post_mip,
|
||||
output logic rvfi_ext_nmi,
|
||||
output logic rvfi_ext_nmi_int,
|
||||
output logic rvfi_ext_debug_req,
|
||||
|
@ -1283,7 +1284,8 @@ module ibex_core import ibex_pkg::*; #(
|
|||
|
||||
// RVFI extension for co-simulation support
|
||||
// debug_req and MIP captured at IF -> ID transition so one extra stage
|
||||
ibex_pkg::irqs_t rvfi_ext_stage_mip [RVFI_STAGES+1];
|
||||
ibex_pkg::irqs_t rvfi_ext_stage_pre_mip [RVFI_STAGES+1];
|
||||
ibex_pkg::irqs_t rvfi_ext_stage_post_mip [RVFI_STAGES];
|
||||
logic rvfi_ext_stage_nmi [RVFI_STAGES+1];
|
||||
logic rvfi_ext_stage_nmi_int [RVFI_STAGES+1];
|
||||
logic rvfi_ext_stage_debug_req [RVFI_STAGES+1];
|
||||
|
@ -1328,11 +1330,21 @@ module ibex_core import ibex_pkg::*; #(
|
|||
always_comb begin
|
||||
// Use always_comb instead of continuous assign so first assign can set 0 as default everywhere
|
||||
// that is overridden by more specific settings.
|
||||
rvfi_ext_mip = '0;
|
||||
rvfi_ext_mip[CSR_MSIX_BIT] = rvfi_ext_stage_mip[RVFI_STAGES].irq_software;
|
||||
rvfi_ext_mip[CSR_MTIX_BIT] = rvfi_ext_stage_mip[RVFI_STAGES].irq_timer;
|
||||
rvfi_ext_mip[CSR_MEIX_BIT] = rvfi_ext_stage_mip[RVFI_STAGES].irq_external;
|
||||
rvfi_ext_mip[CSR_MFIX_BIT_HIGH:CSR_MFIX_BIT_LOW] = rvfi_ext_stage_mip[RVFI_STAGES].irq_fast;
|
||||
rvfi_ext_pre_mip = '0;
|
||||
rvfi_ext_pre_mip[CSR_MSIX_BIT] = rvfi_ext_stage_pre_mip[RVFI_STAGES].irq_software;
|
||||
rvfi_ext_pre_mip[CSR_MTIX_BIT] = rvfi_ext_stage_pre_mip[RVFI_STAGES].irq_timer;
|
||||
rvfi_ext_pre_mip[CSR_MEIX_BIT] = rvfi_ext_stage_pre_mip[RVFI_STAGES].irq_external;
|
||||
|
||||
rvfi_ext_pre_mip[CSR_MFIX_BIT_HIGH:CSR_MFIX_BIT_LOW] =
|
||||
rvfi_ext_stage_pre_mip[RVFI_STAGES].irq_fast;
|
||||
|
||||
rvfi_ext_post_mip = '0;
|
||||
rvfi_ext_post_mip[CSR_MSIX_BIT] = rvfi_ext_stage_post_mip[RVFI_STAGES-1].irq_software;
|
||||
rvfi_ext_post_mip[CSR_MTIX_BIT] = rvfi_ext_stage_post_mip[RVFI_STAGES-1].irq_timer;
|
||||
rvfi_ext_post_mip[CSR_MEIX_BIT] = rvfi_ext_stage_post_mip[RVFI_STAGES-1].irq_external;
|
||||
|
||||
rvfi_ext_post_mip[CSR_MFIX_BIT_HIGH:CSR_MFIX_BIT_LOW] =
|
||||
rvfi_ext_stage_post_mip[RVFI_STAGES-1].irq_fast;
|
||||
end
|
||||
|
||||
assign rvfi_ext_nmi = rvfi_ext_stage_nmi [RVFI_STAGES];
|
||||
|
@ -1487,12 +1499,12 @@ module ibex_core import ibex_pkg::*; #(
|
|||
// the DV environment will see if a trap should have been taken but wasn't.
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
rvfi_ext_stage_mip[0] <= '0;
|
||||
rvfi_ext_stage_pre_mip[0] <= '0;
|
||||
rvfi_ext_stage_nmi[0] <= '0;
|
||||
rvfi_ext_stage_nmi_int[0] <= '0;
|
||||
rvfi_ext_stage_debug_req[0] <= '0;
|
||||
end else if ((if_stage_i.instr_valid_id_d & if_stage_i.instr_new_id_d) | rvfi_irq_valid) begin
|
||||
rvfi_ext_stage_mip[0] <= instr_valid_id | ~captured_valid ? cs_registers_i.mip :
|
||||
rvfi_ext_stage_pre_mip[0] <= instr_valid_id | ~captured_valid ? cs_registers_i.mip :
|
||||
captured_mip;
|
||||
rvfi_ext_stage_nmi[0] <= instr_valid_id | ~captured_valid ? irq_nm_i :
|
||||
captured_nmi;
|
||||
|
@ -1553,7 +1565,8 @@ module ibex_core import ibex_pkg::*; #(
|
|||
rvfi_stage_mem_rdata[i] <= '0;
|
||||
rvfi_stage_mem_wdata[i] <= '0;
|
||||
rvfi_stage_mem_addr[i] <= '0;
|
||||
rvfi_ext_stage_mip[i+1] <= '0;
|
||||
rvfi_ext_stage_pre_mip[i+1] <= '0;
|
||||
rvfi_ext_stage_post_mip[i] <= '0;
|
||||
rvfi_ext_stage_nmi[i+1] <= '0;
|
||||
rvfi_ext_stage_nmi_int[i+1] <= '0;
|
||||
rvfi_ext_stage_debug_req[i+1] <= '0;
|
||||
|
@ -1567,7 +1580,7 @@ module ibex_core import ibex_pkg::*; #(
|
|||
|
||||
if (i == 0) begin
|
||||
if (rvfi_id_done) begin
|
||||
rvfi_stage_halt[i] <= '0;
|
||||
rvfi_stage_halt[i] <= '0;
|
||||
rvfi_stage_trap[i] <= rvfi_trap_id;
|
||||
rvfi_stage_intr[i] <= rvfi_intr_d;
|
||||
rvfi_stage_order[i] <= rvfi_stage_order_d;
|
||||
|
@ -1605,7 +1618,8 @@ module ibex_core import ibex_pkg::*; #(
|
|||
// providing information along with a retired instruction. Move these up the rvfi pipeline
|
||||
// for both cases.
|
||||
if (rvfi_id_done | rvfi_ext_stage_irq_valid[i]) begin
|
||||
rvfi_ext_stage_mip[i+1] <= rvfi_ext_stage_mip[i];
|
||||
rvfi_ext_stage_pre_mip[i+1] <= rvfi_ext_stage_pre_mip[i];
|
||||
rvfi_ext_stage_post_mip[i] <= cs_registers_i.mip;
|
||||
rvfi_ext_stage_nmi[i+1] <= rvfi_ext_stage_nmi[i];
|
||||
rvfi_ext_stage_nmi_int[i+1] <= rvfi_ext_stage_nmi_int[i];
|
||||
rvfi_ext_stage_debug_req[i+1] <= rvfi_ext_stage_debug_req[i];
|
||||
|
@ -1652,7 +1666,8 @@ module ibex_core import ibex_pkg::*; #(
|
|||
// providing information along with a retired instruction. Move these up the rvfi pipeline
|
||||
// for both cases.
|
||||
if (rvfi_wb_done | rvfi_ext_stage_irq_valid[i]) begin
|
||||
rvfi_ext_stage_mip[i+1] <= rvfi_ext_stage_mip[i];
|
||||
rvfi_ext_stage_pre_mip[i+1] <= rvfi_ext_stage_pre_mip[i];
|
||||
rvfi_ext_stage_post_mip[i] <= rvfi_ext_stage_post_mip[i-1];
|
||||
rvfi_ext_stage_nmi[i+1] <= rvfi_ext_stage_nmi[i];
|
||||
rvfi_ext_stage_nmi_int[i+1] <= rvfi_ext_stage_nmi_int[i];
|
||||
rvfi_ext_stage_debug_req[i+1] <= rvfi_ext_stage_debug_req[i];
|
||||
|
|
|
@ -455,7 +455,8 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
.rvfi_mem_wmask (),
|
||||
.rvfi_mem_rdata (),
|
||||
.rvfi_mem_wdata (),
|
||||
.rvfi_ext_mip (),
|
||||
.rvfi_ext_pre_mip (),
|
||||
.rvfi_ext_post_mip (),
|
||||
.rvfi_ext_nmi (),
|
||||
.rvfi_ext_nmi_int (),
|
||||
.rvfi_ext_debug_req (),
|
||||
|
|
|
@ -117,7 +117,8 @@ module ibex_top import ibex_pkg::*; #(
|
|||
output logic [ 3:0] rvfi_mem_wmask,
|
||||
output logic [31:0] rvfi_mem_rdata,
|
||||
output logic [31:0] rvfi_mem_wdata,
|
||||
output logic [31:0] rvfi_ext_mip,
|
||||
output logic [31:0] rvfi_ext_pre_mip,
|
||||
output logic [31:0] rvfi_ext_post_mip,
|
||||
output logic rvfi_ext_nmi,
|
||||
output logic rvfi_ext_nmi_int,
|
||||
output logic rvfi_ext_debug_req,
|
||||
|
@ -390,7 +391,8 @@ module ibex_top import ibex_pkg::*; #(
|
|||
.rvfi_mem_wmask,
|
||||
.rvfi_mem_rdata,
|
||||
.rvfi_mem_wdata,
|
||||
.rvfi_ext_mip,
|
||||
.rvfi_ext_pre_mip,
|
||||
.rvfi_ext_post_mip,
|
||||
.rvfi_ext_nmi,
|
||||
.rvfi_ext_nmi_int,
|
||||
.rvfi_ext_debug_req,
|
||||
|
|
|
@ -119,7 +119,8 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
logic [ 3:0] rvfi_mem_wmask;
|
||||
logic [31:0] rvfi_mem_rdata;
|
||||
logic [31:0] rvfi_mem_wdata;
|
||||
logic [31:0] rvfi_ext_mip;
|
||||
logic [31:0] rvfi_ext_pre_mip;
|
||||
logic [31:0] rvfi_ext_post_mip;
|
||||
logic rvfi_ext_nmi;
|
||||
logic rvfi_ext_nmi_int;
|
||||
logic rvfi_ext_debug_req;
|
||||
|
@ -136,7 +137,8 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
logic [31:0] unused_perf_regsh [10];
|
||||
|
||||
|
||||
logic [31:0] unused_rvfi_ext_mip;
|
||||
logic [31:0] unused_rvfi_ext_pre_mip;
|
||||
logic [31:0] unused_rvfi_ext_post_mip;
|
||||
logic unused_rvfi_ext_nmi;
|
||||
logic unused_rvfi_ext_nmi_int;
|
||||
logic unused_rvfi_ext_debug_req;
|
||||
|
@ -148,7 +150,8 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
|
||||
// Tracer doesn't use these signals, though other modules may probe down into tracer to observe
|
||||
// them.
|
||||
assign unused_rvfi_ext_mip = rvfi_ext_mip;
|
||||
assign unused_rvfi_ext_pre_mip = rvfi_ext_pre_mip;
|
||||
assign unused_rvfi_ext_post_mip = rvfi_ext_post_mip;
|
||||
assign unused_rvfi_ext_nmi = rvfi_ext_nmi;
|
||||
assign unused_rvfi_ext_nmi_int = rvfi_ext_nmi_int;
|
||||
assign unused_rvfi_ext_debug_req = rvfi_ext_debug_req;
|
||||
|
@ -252,7 +255,8 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
.rvfi_mem_wmask,
|
||||
.rvfi_mem_rdata,
|
||||
.rvfi_mem_wdata,
|
||||
.rvfi_ext_mip,
|
||||
.rvfi_ext_pre_mip,
|
||||
.rvfi_ext_post_mip,
|
||||
.rvfi_ext_nmi,
|
||||
.rvfi_ext_nmi_int,
|
||||
.rvfi_ext_debug_req,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue