fix(csr): add support non register interrupt pending (#465)
This PR adds support for non-register interrupts pending to copy the interrupt to NEMU. The interrupts come from Count overflow and Platform-Level Interrupt Controller such as PLIC, CLINT, IMSIC. Thus, we could diff xip csr registers.
This commit is contained in:
parent
a1b35f7fda
commit
d0c338cb42
|
@ -141,6 +141,7 @@ coherence via RefillTest.
|
|||
| `DiffL2TLBEvent` | L2 TLB operations | No |
|
||||
| `DiffRefillEvent` | Cache refill operations | No |
|
||||
| `DiffLrScEvent` | Executed LR/SC instructions | No |
|
||||
| `DiffNonRegInterruptPengingEvent` | Non-register interrupts pending | No |
|
||||
|
||||
The DiffTest framework comes with a simulation framework with some top-level IOs.
|
||||
They will be automatically created when calling `DifftestModule.finish(cpu: String)`.
|
||||
|
|
|
@ -301,6 +301,17 @@ class RunaheadRedirectEvent extends DifftestBaseBundle with HasValid {
|
|||
val checkpoint_id = UInt(64.W)
|
||||
}
|
||||
|
||||
class NonRegInterruptPendingEvent extends DifftestBaseBundle with HasValid {
|
||||
val platformIRPMeip = Bool()
|
||||
val platformIRPMtip = Bool()
|
||||
val platformIRPMsip = Bool()
|
||||
val platformIRPSeip = Bool()
|
||||
val platformIRPStip = Bool()
|
||||
val platformIRPVseip = Bool()
|
||||
val platformIRPVstip = Bool()
|
||||
val localCounterOverflowInterruptReq = Bool()
|
||||
}
|
||||
|
||||
class TraceInfo extends DifftestBaseBundle with HasValid {
|
||||
val in_replay = Bool()
|
||||
val trace_head = UInt(16.W)
|
||||
|
|
|
@ -405,6 +405,11 @@ class DiffRunaheadRedirectEvent extends RunaheadRedirectEvent with DifftestBundl
|
|||
override val desiredCppName: String = "runahead_redirect"
|
||||
}
|
||||
|
||||
class DiffNonRegInterruptPendingEvent extends NonRegInterruptPendingEvent with DifftestBundle {
|
||||
override val desiredCppName: String = "non_reg_interrupt_pending"
|
||||
|
||||
}
|
||||
|
||||
class DiffTraceInfo(config: GatewayConfig) extends TraceInfo with DifftestBundle {
|
||||
override val desiredCppName: String = "trace_info"
|
||||
|
||||
|
|
|
@ -316,6 +316,10 @@ int Difftest::step() {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DIFFTEST_NONREGINTERRUPTPENDINGEVENT
|
||||
do_non_reg_interrupt_pending();
|
||||
#endif
|
||||
|
||||
num_commit = 0; // reset num_commit this cycle to 0
|
||||
if (dut->event.valid) {
|
||||
// interrupt has a higher priority than exception
|
||||
|
@ -363,11 +367,6 @@ int Difftest::step() {
|
|||
state->record_group(dut->commit[0].pc, num_commit);
|
||||
}
|
||||
|
||||
// FIXME: the following code is dirty
|
||||
if (dut->csr.mip != proxy->csr.mip) { // Ignore difftest for MIP
|
||||
proxy->csr.mip = dut->csr.mip;
|
||||
}
|
||||
|
||||
if (apply_delayed_writeback()) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -1230,6 +1229,24 @@ void Difftest::raise_trap(int trapCode) {
|
|||
dut->trap.code = trapCode;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DIFFTEST_NONREGINTERRUPTPENDINGEVENT
|
||||
void Difftest::do_non_reg_interrupt_pending() {
|
||||
if (dut->non_reg_interrupt_pending.valid) {
|
||||
struct NonRegInterruptPending ip;
|
||||
ip.platformIRPMtip = dut->non_reg_interrupt_pending.platformIRPMtip;
|
||||
ip.platformIRPMeip = dut->non_reg_interrupt_pending.platformIRPMeip;
|
||||
ip.platformIRPMsip = dut->non_reg_interrupt_pending.platformIRPMsip;
|
||||
ip.platformIRPSeip = dut->non_reg_interrupt_pending.platformIRPSeip;
|
||||
ip.platformIRPStip = dut->non_reg_interrupt_pending.platformIRPStip;
|
||||
ip.platformIRPVseip = dut->non_reg_interrupt_pending.platformIRPVseip;
|
||||
ip.platformIRPVstip = dut->non_reg_interrupt_pending.platformIRPVstip;
|
||||
ip.localCounterOverflowInterruptReq = dut->non_reg_interrupt_pending.localCounterOverflowInterruptReq;
|
||||
|
||||
proxy->non_reg_interrupt_pending(ip);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void Difftest::display() {
|
||||
printf("\n============== In the last commit group ==============\n");
|
||||
printf("the first commit instr pc of DUT is 0x%016lx\nthe first commit instr pc of REF is 0x%016lx\n",
|
||||
|
|
|
@ -409,7 +409,9 @@ protected:
|
|||
int apply_delayed_writeback();
|
||||
|
||||
void raise_trap(int trapCode);
|
||||
|
||||
#ifdef CONFIG_DIFFTEST_NONREGINTERRUPTPENDINGEVENT
|
||||
void do_non_reg_interrupt_pending();
|
||||
#endif
|
||||
#ifdef CONFIG_DIFFTEST_REPLAY
|
||||
struct {
|
||||
bool in_replay = false;
|
||||
|
|
|
@ -145,7 +145,8 @@ public:
|
|||
f(ref_guided_exec, difftest_guided_exec, void, void*) \
|
||||
f(raise_nmi_intr, difftest_raise_nmi_intr, void, bool) \
|
||||
f(ref_virtual_interrupt_is_hvictl_inject, difftest_virtual_interrupt_is_hvictl_inject, void, bool) \
|
||||
f(disambiguation_state, difftest_disambiguation_state, int, )
|
||||
f(disambiguation_state, difftest_disambiguation_state, int, ) \
|
||||
f(ref_non_reg_interrupt_pending, difftest_non_reg_interrupt_pending, void, void*)
|
||||
|
||||
#define RefFunc(func, ret, ...) ret func(__VA_ARGS__)
|
||||
#define DeclRefFunc(this_func, dummy, ret, ...) RefFunc((*this_func), ret, __VA_ARGS__);
|
||||
|
@ -243,6 +244,12 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
inline void non_reg_interrupt_pending(struct NonRegInterruptPending &ip) {
|
||||
if (ref_non_reg_interrupt_pending) {
|
||||
ref_non_reg_interrupt_pending(&ip);
|
||||
}
|
||||
}
|
||||
|
||||
inline void guided_exec(struct ExecutionGuide &guide) {
|
||||
return ref_guided_exec ? ref_guided_exec(&guide) : ref_exec(1);
|
||||
}
|
||||
|
@ -342,6 +349,17 @@ struct ExecutionGuide {
|
|||
uint64_t jump_target;
|
||||
};
|
||||
|
||||
struct NonRegInterruptPending {
|
||||
bool platformIRPMtip;
|
||||
bool platformIRPMeip;
|
||||
bool platformIRPMsip;
|
||||
bool platformIRPSeip;
|
||||
bool platformIRPStip;
|
||||
bool platformIRPVseip;
|
||||
bool platformIRPVstip;
|
||||
bool localCounterOverflowInterruptReq;
|
||||
};
|
||||
|
||||
extern const char *difftest_ref_so;
|
||||
extern uint8_t *ref_golden_mem;
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ class DifftestTop extends Module {
|
|||
val difftest_runahead_event = DifftestModule(new DiffRunaheadEvent, dontCare = true)
|
||||
val difftest_runahead_commit_event = DifftestModule(new DiffRunaheadCommitEvent, dontCare = true)
|
||||
val difftest_runahead_redirect_event = DifftestModule(new DiffRunaheadRedirectEvent, dontCare = true)
|
||||
val difftest_non_reg_interrupt_pending_event = DifftestModule(new DiffNonRegInterruptPendingEvent, dontCare = true)
|
||||
|
||||
DifftestModule.finish("demo")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue