Previously any changes in interrupt state or debug requests were
strictly associated with retired instructions. This causes cosim
mismatches where a lower priority interrupt occurs in time before a
higher priority interrupt or debug request but between instruction
fetches/retirements so both the low and high priority interrupts are
signalled with the instruction retirement.
This introduces a way for the RVFI to signal an interrupt has occurred
that isn't associated with an instruction retirement to allow the cosim
to see the seperation in time between different interrupts and debug
requests and hence model behaviour correctly.
This is used in riscv_pmp_full_random_test as some executions of that
test run very slowly. These are still valuable so the timeout is used to
ensure they don't take too long but still result in a pass.
When a writeback exception occurs when the instruction in ID/EX has seen
an instruction fetch error we need to ensure that error doesn't get
notified to cosim. This requires watching for a writeback exception and
removing the latest iside error from the queue if needed.
When Ibex does a load that receives data with bad integrity it
suppresses the write to the destination register. The implements
matching functionality for cosim.
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
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
This test picks between inserting an integrity error or a bus error
to the response in the case of a memory request from Ibex. Introduces
a control knob `enable_mem_intg_err` which can control the rate of
having integrity errors per request.
This commit also disables checking for double fault alerts in the
scoreboard because they're expected to be seen while simulating and
they don't cause infinite loop problems because every time a memory
response is requested the error causing part is just randomized.
That means Ibex trying to execute same instruction again would have
a chance to succeed this time.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
These functions are alternatives to `uvm_hdl_read()` when that function
is not available (e.g., when signals are otherwise optimized away such
as when not dumping waves) and the probe functions are apparently much
faster than `uvm_hdl_read()`, which seems to be implemented as foreign
function.
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
These functions are alternatives to `uvm_hdl_read()` when that function
is not available (e.g., when signals are otherwise optimized away such
as when not dumping waves) and the probe functions are apparently much
faster than `uvm_hdl_read()`, which seems to be implemented as foreign
function.
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
Move the handling of resets to the routine core_ibex_base_test::handle_reset,
which sequences the resets of different testbench components to ensure that
everything comes back up in the right sequence after a reset stimulus.
This commit protects the core_busy_o signal using a multi-bit encoding
to reduce the chances of an adversary for glitching this signal to low,
thereby putting the core to sleep and e.g. not handling an alert.
Without this commit, the glitch would only be detected once both the
main core and the shadow core wake up again and the comparison of the
core_busy_o signals continues.
This resolveslowRISC/Ibex#1827.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
Add a plusargs "+is_double_fault_detected_fatal" to the top-level cfg,
which is set to 1 by default.
Set the default for the "+enable_double_fault_detector" to 1.
Add a new scoreboard component to the core_ibex uvm environment, which contains
a double_fault detector task. This uses the top-level output
'double_fault_seen_o' to count the number of total and consecutive double_faults
seen with a test. A helper task allows the base_test to wait upon each of these
counters reaching the configured thresholds, and then to end the test early with
a passing result.
The default thresholds are 100 for consecutive faults, and 1000 for total faults.
The double_fault detector is disabled by default.
A plusarg '+enable_double_fault_detector=1' enables the checker.
This commit enables it for only the 'pmp_full_random_test', as that is a useful
test candidate to begin with.
This addresses a current testbench issue where asserting debug_req_i close to
when single_stepping over an instruction causes an incorrect 'cause' to be
recorded within DCSR.
The ic_scr_key_valid field indicates whether the ICache scrambling key
is valid.
CPUCTRL is also renamed CPUCTRLSTS as it contains both control and
status bits.
We are running with cosim by default now, and no longer support COSIM=0. Hence
this option and all downstream conditional paths are no longer required.
This allows us to actually use Icache in our tests beecause
before this commit key_valid was tied to 0 which means everytime
we receive a FENCE.I instruction, we wouldn't be able to successfully
flag inval_done. Which means we weren't probably using ICache correctly.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
Extends RVFI connections further to include 30 mhpmcounterX registers.
Sets them up before every cosim step to let Spike know their real values.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
- Adds comments for quicker explanation of test and library functionality
- Refactor types and naming of control knob signals for clarity
- Move constraints from MEMBER to CLASS for more flexibility
- Add missing license header
Signed-off-by: Harry Callahan <hcallahan@lowrisc.org>
This is to allow more consistent signalling in systems that integrate
Ibex (e.g. OpenTitan) so bus integrity errors external to Ibex and one's
detected within Ibex can be fed into the same alert whilst seperating
out Ibex's various internal alert causes.
`no_nmi` in irq_raise_seq and irq_raise_single_seq would always cause an
NMI to be raised if it was set. This alters it to have the same
behaviour as `no_fast`. Setting `no_nmi` prevents an NMI from being
produced by the sequences, leaving it clears allows an NMI to be
produced but doesn't force it. This allows tests which can deal with NMI
along with other IRQs to fully randomise IRQs.
A new `irq_raise_nmi_seq` is provided for tests that specifically want
an NMI.
This silences VCS warnings about the DUT having missing port
connections. It doesn't add any actual testing for these signals.
The patch also re-orders the signals to match the order in
ibex_core_tracing.sv, to make it easier to spot what's going on by
eye.
Testbench computation of next PC when single stepping was broken. A
branch may stall before branch_set is asserted and this wasn't being
taken into account. Where the branch target ALU is present branch_set
can be set on the first cycle of the branch so this bug wasn't apparent.
Even with the branch target ALU the branch may stall awaiting the result
of a load when the writeback stage is present.
To make matters more complicated for a jump the PC being jumped to is
only available when jump_set is asserted which happens whilst the jump
instruction is stalling.
This alters the riscv_debug_single_step_test so when waiting for a
single step it looks for either a branch_set or jump_set signal being
asserted. Otherwise it waits until the instruction has unstalled. This
should give correct behaviour in all scenarios (potentially further
thought required where exceptions and interrupts occur).
Fixes#1167
Signed-off-by: Greg Chadwick <gac@lowrisc.org>
As pointed out by @tomroberts-lowrisc in #983, the current
implementation of riscv_debug_single_step_test cannot handle
single-stepping over instructions that change the PC.
This PR aims to introduce this functionality, utilizing the
new instr_monitor_if.
Now, if the core single-steps onto a branch/jump instruction, the
testbench will log the new target PC and compare it against the actual
target address stored in `dpc`.
"Normal" instructions are checked as usual by incrementing the
instruction's PC by either 2 or 4 (depending whether it is compressed)
and comparing that against `dpc`.
This PR modifies the Ibex DV environment to use request/response
terminology instead of the current outdated naming scheme.
These changes are purely aesthetic.
As a result of lowRISC/opentitan#2405 and lowRISC/ibex#928 (reporting
that interrupts that came in while a load instruction was in the ID
stage caused some incorrect behavior in Ibex), this PR adds some new
directed interrupt and debug tests to check that the core behaves
properly during execution of each supported instruction when some
external irq/debug stimulus comes in.
To do this, we use the two new functions `decode_instr(...)` and
`decode_compressed_instr(...)` in `core_ibex_test_list.sv` to "decode"
every instruction that the `core_ibex_instr_monitor_if` sees in the ID
stage of the pipeline. Once the testbench decodes an instruction that
we have not seen before, it can then drive interrupt or debug stimulus
into the core.
Once any given instruction has been detected by the testbench (and
stimulus driven), it will no longer drive stimulus if this instruction
is seen in the decode pipeline (e.g. if we have previously detected a
`c.addi` instruction in the ID stage and have driven irq/debug stimulus,
we will no longer drive stimulus if we see another `c.addi` instruction,
no matter the operands). This is to avoid driving irq/debug stimulus
after every single instruction as this will add a huge unwanted amount
of simulation latency.
A few notes:
- We drive irq/debug stimulus into the core every time we see a
`wfi` instruction, as otherwise we will timeout as the core waits
infinitely for some stimulus from the outside world.
- We ignore some system-level instructions (ebreak/mret/dret) and
illegal instructionsfor now, as driving stimulus during these
instructions will result in a nested trap, which requires special
handling.
- The interrupt agent was modified slightly to drive stimulus by
default on the falling edge of the clock, so this way we can "catch"
instructions that are in the ID pipeline for only a single cycle.
- The duration for which the testbench raises `debug_req_i` for the core
is also increased to avoid edge cases where we lower the debug line
too early (e.g. while long multicycle instructions like `div` are
executing in the ID stage).
This PR adds clocking blocks to all major Ibex interfaces and updates
all corresponding interface accesses to use these clocking blocks.
A few notes:
- `ibex_mem_intf` has two driver clocking blocks, one for host side and
one for device side.
This is because our Ibex testbench currently provides both host and
device agents for both I/D interfaces (of course we only use the
reactive device agents in the main testbench).
- `csr_if` and `dut_if` only have one clocking block each, as all
signals in each will only be either sampled or driven, never both.
- Some utility tasks have been added to some interfaces to wait for a
specified number of clock cycles.