Skip to content

Commit 64e1843

Browse files
committed
[cosim] Cosim integration of internal NMI
This commit is mainly an extension to cosim environment to drive the newly introduced state variable `nmi_int` in Spike. This commit - Extends RVFI interface by a single bit (ext_nmi_int) - Configures cosim to set nmi_int inside Spike - Changes internals of SpikeCosim object to reflect internal NMI behaviour in Ibex. Namely producing an extra dside access. Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
1 parent bd68f07 commit 64e1843

16 files changed

+60
-3
lines changed

dv/cosim/cosim.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ class Cosim {
9595
// When an NMI is due to be taken that will occur at the next call of `step`.
9696
virtual void set_nmi(bool nmi) = 0;
9797

98+
// Set the state of the internal NMI (non-maskable interrupt) line.
99+
// Behaviour wise this is almost as same as external NMI case explained at
100+
// set_nmi method. Difference is that this one is a response from Ibex rather
101+
// than an input.
102+
virtual void set_nmi_int(bool nmi_int) = 0;
103+
98104
// Set the debug request.
99105
//
100106
// When set to true the core will enter debug mode at the next step

dv/cosim/cosim_dpi.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ void riscv_cosim_set_nmi(Cosim *cosim, svBit nmi) {
2828
cosim->set_nmi(nmi);
2929
}
3030

31+
void riscv_cosim_set_nmi_int(Cosim *cosim, svBit nmi_int) {
32+
assert(cosim);
33+
34+
cosim->set_nmi_int(nmi_int);
35+
}
3136
void riscv_cosim_set_debug_req(Cosim *cosim, svBit debug_req) {
3237
assert(cosim);
3338

dv/cosim/cosim_dpi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ int riscv_cosim_step(Cosim *cosim, const svBitVecVal *write_reg,
1717
svBit sync_trap);
1818
void riscv_cosim_set_mip(Cosim *cosim, const svBitVecVal *mip);
1919
void riscv_cosim_set_nmi(Cosim *cosim, svBit nmi);
20+
void riscv_cosim_set_nmi_int(Cosim *cosim, svBit nmi_int);
2021
void riscv_cosim_set_debug_req(Cosim *cosim, svBit debug_req);
2122
void riscv_cosim_set_mcycle(Cosim *cosim, svBitVecVal *mcycle);
2223
void riscv_cosim_set_csr(Cosim *cosim, const int csr_id,

dv/cosim/cosim_dpi.svh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import "DPI-C" function int riscv_cosim_step(chandle cosim_handle, bit [4:0] wri
1414
bit [31:0] write_reg_data, bit [31:0] pc, bit sync_trap);
1515
import "DPI-C" function void riscv_cosim_set_mip(chandle cosim_handle, bit [31:0] mip);
1616
import "DPI-C" function void riscv_cosim_set_nmi(chandle cosim_handle, bit nmi);
17+
import "DPI-C" function void riscv_cosim_set_nmi_int(chandle cosim_handle, bit nmi_int);
1718
import "DPI-C" function void riscv_cosim_set_debug_req(chandle cosim_handle, bit debug_req);
1819
import "DPI-C" function void riscv_cosim_set_mcycle(chandle cosim_handle, bit [63:0] mcycle);
1920
import "DPI-C" function void riscv_cosim_set_csr(chandle cosim_handle, int csr_id,

dv/cosim/spike_cosim.cc

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ bool SpikeCosim::step(uint32_t write_reg, uint32_t write_reg_data,
200200

201201
if (processor->get_state()->last_inst_pc == PC_INVALID) {
202202
if (!(processor->get_state()->mcause->read() & 0x80000000) ||
203-
processor->get_state()->debug_mode) { // (Async-Traps are disabled in debug mode)
203+
processor->get_state()->debug_mode) { // (Async-Traps are disabled in debug mode)
204204
// Spike encountered a synchronous trap
205205
pending_sync_exception = true;
206206

@@ -358,6 +358,12 @@ bool SpikeCosim::check_sync_trap(uint32_t write_reg,
358358
return false;
359359
}
360360

361+
// If we see an internal NMI, that means we receive an extra memory intf item.
362+
// Deleting that is necessary since next Load/Store would fail otherwise.
363+
if (processor->get_state()->mcause->read() == 0xFFFFFFE0) {
364+
pending_dside_accesses.erase(pending_dside_accesses.begin());
365+
}
366+
361367
// Errors may have been generated outside of step() (e.g. in
362368
// check_mem_access()), return false if there are any.
363369
if (errors.size() != 0) {
@@ -480,6 +486,20 @@ void SpikeCosim::set_nmi(bool nmi) {
480486
}
481487
}
482488

489+
void SpikeCosim::set_nmi_int(bool nmi_int) {
490+
if (nmi_int && !nmi_mode && !processor->get_state()->debug_mode) {
491+
processor->get_state()->nmi_int = true;
492+
nmi_mode = true;
493+
494+
// When NMI is set it is guaranteed NMI trap will be taken at the next step
495+
// so save CSR state for recoverable NMI to mstack now.
496+
mstack.mpp = get_field(processor->get_csr(CSR_MSTATUS), MSTATUS_MPP);
497+
mstack.mpie = get_field(processor->get_csr(CSR_MSTATUS), MSTATUS_MPIE);
498+
mstack.epc = processor->get_csr(CSR_MEPC);
499+
mstack.cause = processor->get_csr(CSR_MCAUSE);
500+
}
501+
}
502+
483503
void SpikeCosim::set_debug_req(bool debug_req) {
484504
processor->halt_request =
485505
debug_req ? processor_t::HR_REGULAR : processor_t::HR_NONE;

dv/cosim/spike_cosim.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class SpikeCosim : public simif_t, public Cosim {
102102
uint32_t initial_spike_pc);
103103
void set_mip(uint32_t mip) override;
104104
void set_nmi(bool nmi) override;
105+
void set_nmi_int(bool nmi_int) override;
105106
void set_debug_req(bool debug_req) override;
106107
void set_mcycle(uint64_t mcycle) override;
107108
void set_csr(const int csr_num, const uint32_t new_val) override;

dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_scoreboard.sv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ class ibex_cosim_scoreboard extends uvm_scoreboard;
122122
end
123123

124124
riscv_cosim_set_nmi(cosim_handle, rvfi_instr.nmi);
125+
riscv_cosim_set_nmi_int(cosim_handle, rvfi_instr.nmi_int);
125126
riscv_cosim_set_mip(cosim_handle, rvfi_instr.mip);
126127
riscv_cosim_set_debug_req(cosim_handle, rvfi_instr.debug_req);
127128
riscv_cosim_set_mcycle(cosim_handle, rvfi_instr.mcycle);

dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_monitor.sv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class ibex_rvfi_monitor extends uvm_monitor;
3838
trans_collected.order = vif.monitor_cb.order;
3939
trans_collected.mip = vif.monitor_cb.ext_mip;
4040
trans_collected.nmi = vif.monitor_cb.ext_nmi;
41+
trans_collected.nmi_int = vif.monitor_cb.ext_nmi_int;
4142
trans_collected.debug_req = vif.monitor_cb.ext_debug_req;
4243
trans_collected.mcycle = vif.monitor_cb.ext_mcycle;
4344
trans_collected.ic_scr_key_valid = vif.monitor_cb.ext_ic_scr_key_valid;

dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_seq_item.sv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class ibex_rvfi_seq_item extends uvm_sequence_item;
1010
bit [63:0] order;
1111
bit [31:0] mip;
1212
bit nmi;
13+
bit nmi_int;
1314
bit debug_req;
1415
bit [63:0] mcycle;
1516

@@ -25,6 +26,7 @@ class ibex_rvfi_seq_item extends uvm_sequence_item;
2526
`uvm_field_int (order, UVM_DEFAULT)
2627
`uvm_field_int (mip, UVM_DEFAULT)
2728
`uvm_field_int (nmi, UVM_DEFAULT)
29+
`uvm_field_int (nmi_int, UVM_DEFAULT)
2830
`uvm_field_int (debug_req, UVM_DEFAULT)
2931
`uvm_field_int (mcycle, UVM_DEFAULT)
3032
`uvm_field_sarray_int (mhpmcounters, UVM_DEFAULT)

dv/uvm/core_ibex/env/core_ibex_rvfi_if.sv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ interface core_ibex_rvfi_if(input logic clk);
2828
logic [31:0] mem_wdata;
2929
logic [31:0] ext_mip;
3030
logic ext_nmi;
31+
logic ext_nmi_int;
3132
logic [31:0] ext_debug_req;
3233
logic [63:0] ext_mcycle;
3334

@@ -61,6 +62,7 @@ interface core_ibex_rvfi_if(input logic clk);
6162
input mem_wdata;
6263
input ext_mip;
6364
input ext_nmi;
65+
input ext_nmi_int;
6466
input ext_debug_req;
6567
input ext_mcycle;
6668
input ext_mhpmcounters;

dv/uvm/core_ibex/tb/core_ibex_tb_top.sv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ module core_ibex_tb_top;
192192
assign rvfi_if.mem_wdata = dut.rvfi_mem_wdata;
193193
assign rvfi_if.ext_mip = dut.rvfi_ext_mip;
194194
assign rvfi_if.ext_nmi = dut.rvfi_ext_nmi;
195+
assign rvfi_if.ext_nmi_int = dut.rvfi_ext_nmi_int;
195196
assign rvfi_if.ext_debug_req = dut.rvfi_ext_debug_req;
196197
assign rvfi_if.ext_mcycle = dut.rvfi_ext_mcycle;
197198
assign rvfi_if.ext_mhpmcounters = dut.rvfi_ext_mhpmcounters;

dv/verilator/simple_system_cosim/ibex_simple_system_cosim_checker.sv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ module ibex_simple_system_cosim_checker #(
4343
always @(posedge clk_i) begin
4444
if (u_top.rvfi_valid) begin
4545
riscv_cosim_set_nmi(cosim_handle, u_top.rvfi_ext_nmi);
46+
riscv_cosim_set_nmi_int(cosim_handle, u_top.rvfi_ext_nmi_int);
4647
riscv_cosim_set_mip(cosim_handle, u_top.rvfi_ext_mip);
4748
riscv_cosim_set_debug_req(cosim_handle, u_top.rvfi_ext_debug_req);
4849
riscv_cosim_set_mcycle(cosim_handle, u_top.rvfi_ext_mcycle);

rtl/ibex_core.sv

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ module ibex_core import ibex_pkg::*; #(
138138
output logic [31:0] rvfi_mem_wdata,
139139
output logic [31:0] rvfi_ext_mip,
140140
output logic rvfi_ext_nmi,
141+
output logic rvfi_ext_nmi_int,
141142
output logic rvfi_ext_debug_req,
142143
output logic [63:0] rvfi_ext_mcycle,
143144
output logic [31:0] rvfi_ext_mhpmcounters [10],
@@ -1204,6 +1205,7 @@ module ibex_core import ibex_pkg::*; #(
12041205

12051206
logic new_debug_req;
12061207
logic new_nmi;
1208+
logic new_nmi_int;
12071209
logic new_irq;
12081210
ibex_pkg::irqs_t captured_mip;
12091211
logic captured_nmi;
@@ -1214,6 +1216,7 @@ module ibex_core import ibex_pkg::*; #(
12141216
// debug_req and MIP captured at IF -> ID transition so one extra stage
12151217
ibex_pkg::irqs_t rvfi_ext_stage_mip [RVFI_STAGES+1];
12161218
logic rvfi_ext_stage_nmi [RVFI_STAGES+1];
1219+
logic rvfi_ext_stage_nmi_int [RVFI_STAGES];
12171220
logic rvfi_ext_stage_debug_req [RVFI_STAGES+1];
12181221
logic [63:0] rvfi_ext_stage_mcycle [RVFI_STAGES];
12191222
logic [31:0] rvfi_ext_stage_mhpmcounters [RVFI_STAGES][10];
@@ -1262,6 +1265,7 @@ module ibex_core import ibex_pkg::*; #(
12621265
end
12631266

12641267
assign rvfi_ext_nmi = rvfi_ext_stage_nmi [RVFI_STAGES];
1268+
assign rvfi_ext_nmi_int = rvfi_ext_stage_nmi_int [RVFI_STAGES-1];
12651269
assign rvfi_ext_debug_req = rvfi_ext_stage_debug_req [RVFI_STAGES];
12661270
assign rvfi_ext_mcycle = rvfi_ext_stage_mcycle [RVFI_STAGES-1];
12671271
assign rvfi_ext_mhpmcounters = rvfi_ext_stage_mhpmcounters [RVFI_STAGES-1];
@@ -1291,7 +1295,7 @@ module ibex_core import ibex_pkg::*; #(
12911295
(rvfi_stage_valid[0] & ~rvfi_wb_done);
12921296
// Second stage is output stage so simple valid cycle after instruction leaves WB (and so has
12931297
// retired)
1294-
assign rvfi_stage_valid_d[1] = rvfi_wb_done;
1298+
assign rvfi_stage_valid_d[1] = rvfi_wb_done && !rvfi_ext_nmi_int;
12951299

12961300
// Signal new instruction in WB cycle after instruction leaves ID/EX (to enter WB)
12971301
logic rvfi_instr_new_wb_q;
@@ -1309,7 +1313,7 @@ module ibex_core import ibex_pkg::*; #(
13091313
end
13101314

13111315
assign rvfi_trap_id = id_stage_i.controller_i.id_exception_o;
1312-
assign rvfi_trap_wb = id_stage_i.controller_i.exc_req_lsu;
1316+
assign rvfi_trap_wb = id_stage_i.controller_i.exc_req_lsu | new_nmi_int;
13131317
// WB is instantly done in the tracking pipeline when a trap is progress through the pipeline
13141318
assign rvfi_wb_done = instr_done_wb | (rvfi_stage_valid[0] & rvfi_stage_trap[0]);
13151319
end else begin : gen_rvfi_no_wb_stage
@@ -1349,6 +1353,7 @@ module ibex_core import ibex_pkg::*; #(
13491353
// appropriately.
13501354
assign new_debug_req = (debug_req_i & ~debug_mode);
13511355
assign new_nmi = irq_nm_i & ~nmi_mode & ~debug_mode;
1356+
assign new_nmi_int = id_stage_i.mem_resp_intg_err & ~nmi_mode & ~debug_mode;
13521357
assign new_irq = irq_pending_o & csr_mstatus_mie & ~nmi_mode & ~debug_mode;
13531358

13541359
always_ff @(posedge clk_i or negedge rst_ni) begin
@@ -1423,6 +1428,7 @@ module ibex_core import ibex_pkg::*; #(
14231428
rvfi_stage_mem_addr[i] <= '0;
14241429
rvfi_ext_stage_mip[i+1] <= '0;
14251430
rvfi_ext_stage_nmi[i+1] <= '0;
1431+
rvfi_ext_stage_nmi_int[i] <= '0;
14261432
rvfi_ext_stage_debug_req[i+1] <= '0;
14271433
rvfi_ext_stage_mcycle[i] <= '0;
14281434
rvfi_ext_stage_mhpmcounters[i] <= '{10{'0}};
@@ -1458,6 +1464,7 @@ module ibex_core import ibex_pkg::*; #(
14581464
rvfi_stage_mem_addr[i] <= rvfi_mem_addr_d;
14591465
rvfi_ext_stage_mip[i+1] <= rvfi_ext_stage_mip[i];
14601466
rvfi_ext_stage_nmi[i+1] <= rvfi_ext_stage_nmi[i];
1467+
rvfi_ext_stage_nmi_int[i] <= '0;
14611468
rvfi_ext_stage_debug_req[i+1] <= rvfi_ext_stage_debug_req[i];
14621469
rvfi_ext_stage_mcycle[i] <= cs_registers_i.mcycle_counter_i.counter_val_o;
14631470
rvfi_ext_stage_ic_scr_key_valid[i] <= cs_registers_i.cpuctrlsts_ic_scr_key_valid_q;
@@ -1500,6 +1507,7 @@ module ibex_core import ibex_pkg::*; #(
15001507

15011508
rvfi_ext_stage_mip[i+1] <= rvfi_ext_stage_mip[i];
15021509
rvfi_ext_stage_nmi[i+1] <= rvfi_ext_stage_nmi[i];
1510+
rvfi_ext_stage_nmi_int[i] <= new_nmi_int;
15031511
rvfi_ext_stage_debug_req[i+1] <= rvfi_ext_stage_debug_req[i];
15041512
rvfi_ext_stage_mcycle[i] <= rvfi_ext_stage_mcycle[i-1];
15051513
rvfi_ext_stage_ic_scr_key_valid[i] <= rvfi_ext_stage_ic_scr_key_valid[i-1];

rtl/ibex_lockstep.sv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ module ibex_lockstep import ibex_pkg::*; #(
425425
.rvfi_mem_wdata (),
426426
.rvfi_ext_mip (),
427427
.rvfi_ext_nmi (),
428+
.rvfi_ext_nmi_int (),
428429
.rvfi_ext_debug_req (),
429430
.rvfi_ext_mcycle (),
430431
.rvfi_ext_mhpmcounters (),

rtl/ibex_top.sv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ module ibex_top import ibex_pkg::*; #(
118118
output logic [31:0] rvfi_mem_wdata,
119119
output logic [31:0] rvfi_ext_mip,
120120
output logic rvfi_ext_nmi,
121+
output logic rvfi_ext_nmi_int,
121122
output logic rvfi_ext_debug_req,
122123
output logic [63:0] rvfi_ext_mcycle,
123124
output logic [31:0] rvfi_ext_mhpmcounters [10],
@@ -366,6 +367,7 @@ module ibex_top import ibex_pkg::*; #(
366367
.rvfi_mem_wdata,
367368
.rvfi_ext_mip,
368369
.rvfi_ext_nmi,
370+
.rvfi_ext_nmi_int,
369371
.rvfi_ext_debug_req,
370372
.rvfi_ext_mcycle,
371373
.rvfi_ext_mhpmcounters,

rtl/ibex_top_tracing.sv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ module ibex_top_tracing import ibex_pkg::*; #(
121121
logic [31:0] rvfi_mem_wdata;
122122
logic [31:0] rvfi_ext_mip;
123123
logic rvfi_ext_nmi;
124+
logic rvfi_ext_nmi_int;
124125
logic rvfi_ext_debug_req;
125126
logic [63:0] rvfi_ext_mcycle;
126127

@@ -134,6 +135,7 @@ module ibex_top_tracing import ibex_pkg::*; #(
134135

135136
logic [31:0] unused_rvfi_ext_mip;
136137
logic unused_rvfi_ext_nmi;
138+
logic unused_rvfi_ext_nmi_int;
137139
logic unused_rvfi_ext_debug_req;
138140
logic [63:0] unused_rvfi_ext_mcycle;
139141
logic unused_rvfi_ext_ic_scr_key_valid;
@@ -142,6 +144,7 @@ module ibex_top_tracing import ibex_pkg::*; #(
142144
// them.
143145
assign unused_rvfi_ext_mip = rvfi_ext_mip;
144146
assign unused_rvfi_ext_nmi = rvfi_ext_nmi;
147+
assign unused_rvfi_ext_nmi_int = rvfi_ext_nmi_int;
145148
assign unused_rvfi_ext_debug_req = rvfi_ext_debug_req;
146149
assign unused_rvfi_ext_mcycle = rvfi_ext_mcycle;
147150
assign unused_perf_regs = rvfi_ext_mhpmcounters;
@@ -242,6 +245,7 @@ module ibex_top_tracing import ibex_pkg::*; #(
242245
.rvfi_mem_wdata,
243246
.rvfi_ext_mip,
244247
.rvfi_ext_nmi,
248+
.rvfi_ext_nmi_int,
245249
.rvfi_ext_debug_req,
246250
.rvfi_ext_mcycle,
247251
.rvfi_ext_mhpmcounters,

0 commit comments

Comments
 (0)