mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-20 03:47:15 -04:00
[cosim] Correctly deal with checking top of range memory accesses
The cosimulation environment does not know if a memory access from spike is due to an instruction fetch or a data memory access. It uses a heuristic to differentiate the two. Any access between the PC and the PC + 8 is considered an instruction fetch. This heuristic did not correctly handle addresses at the top of the range where the PC + 8 calculation overflows. This commit fixes the top of range handling.
This commit is contained in:
parent
e784d27464
commit
65a7231a29
1 changed files with 9 additions and 11 deletions
|
@ -84,8 +84,9 @@ bool SpikeCosim::mmio_load(reg_t addr, size_t len, uint8_t *bytes) {
|
|||
bool dut_error = false;
|
||||
|
||||
// Incoming access may be an iside or dside access. Use PC to help determine
|
||||
// which.
|
||||
uint32_t pc = processor->get_state()->pc;
|
||||
// which. PC is 64 bits in spike, we only care about the bottom 32-bit so mask
|
||||
// off the top bits.
|
||||
uint64_t pc = processor->get_state()->pc & 0xffffffff;
|
||||
uint32_t aligned_addr = addr & 0xfffffffc;
|
||||
|
||||
if (pending_iside_error && (aligned_addr == pending_iside_err_addr)) {
|
||||
|
@ -93,17 +94,14 @@ bool SpikeCosim::mmio_load(reg_t addr, size_t len, uint8_t *bytes) {
|
|||
// assume it's an iside access and produce an error.
|
||||
pending_iside_error = false;
|
||||
dut_error = true;
|
||||
} else if (addr < pc || addr >= (pc + 8)) {
|
||||
} else {
|
||||
// Spike may attempt to access up to 8-bytes from the PC when fetching, so
|
||||
// only check as a dside access when it falls outside that range.
|
||||
// only check as a dside access when it falls outside that range
|
||||
bool in_iside_range = (addr >= pc && addr < pc + 8);
|
||||
|
||||
// Otherwise check if the aligned PC matches with the aligned address or an
|
||||
// incremented aligned PC (to capture the unaligned 4-byte instruction
|
||||
// case). Assume a successful iside access if either of these checks are
|
||||
// true, otherwise assume a dside access and check against DUT dside
|
||||
// accesses. If the RTL produced a bus error for the access, or the
|
||||
// checking failed produce a memory fault in spike.
|
||||
dut_error = (check_mem_access(false, addr, len, bytes) != kCheckMemOk);
|
||||
if (!in_iside_range) {
|
||||
dut_error = (check_mem_access(false, addr, len, bytes) != kCheckMemOk);
|
||||
}
|
||||
}
|
||||
|
||||
return !(bus_error || dut_error);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue