An internal interrupt triggers an NMI. A single one is implemented, one
on integrity errors being seen in load data. This replaces a synchronous
exception on an integrity error which caused timing issues.
This groups the various different illegal instructions categories within
ibex_id_stage rather than spreading them between ibex_id_stage and
ibex_controller.
- Instruction addresses are now checked in the IF stage, after the cache
and after the prefetch buffer.
- To deal with unaligned instructions, the PMP logic checks the current
address and the next in parallel.
- The spec_branch timing hack has been removed as it's no longer
relevant with the PMP logic moved.
- Various updates made to the icache testbench to account for the
changes.
- Relates to #1471
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This adds some new `rvfi_ext` signals that are needed by the
co-simulation environment.
It also fixes/alters `rvfi_trap`. Previously it wouldn't work correctly
in various cases. Now it is fully functional, though it's meaning
includes more trap cases than the RVFI spec strictly includes. It is now
set for any instruction that produces a synchronous trap (everything bar
interrupts).
This matches the priority used in Spike.
This also fixes an issue in the DV where the priority of
external/software/timer interrupts wasn't calculated correctly.
Without this an instruction taking an exception will enter WB whilst
simultaneously remaining in ID. This didn't cause any known functional
issues as in the scenarios it occurred the RF write was disabled and the
WB stage eventually gets flushed. However it's still bad behaviour and
could lead to functional issues when RTL changes. It also eases the
co-simulation DV implementation.
This adds more instruction categories and corrects various issues in the
categorization code. Further cross coverage has been added including
illegal bins to remove bins that cannot occur.
The concept of using SVAs with cross coverage has been dropped. The
systemverilog scheduling model makes the concept unworkable.
This change will cause the ID stage to stall if there is a potential
debug mode entry until instructions in both ID and WB have completed.
This fixes an issue with incorrect behaviour around hardware breakpoints
and exceptions that could cause exception entry to be missed, hardware
breakpoints to be triggered incorrectly or missed entirely.
In addition single step control logic is altered to work correctly with
the new debug mode entry behaviour.
Prior to this change Ibex had multiple feedthrough paths from the data
memory interface to the instruction memory interface. This existed
because Ibex would hold off doing a instruction fetch for a jump or
branch if there was a outstanding memory request. It would wait for the
response to be available so either the jump or branch would occur or an
exception was taken.
With this change the branch or jump will speculatively begin the
instruction fetch whilst there is an outstanding memory request. Should
an exception result from the memory request the fetch will be discarded
and the exception taken as normal.
An alternative fix would not factor the data error response
(data_err_i) directly into the controller logic for branches and jumps.
With this option new stall cycles would be introduced anywhere a branch
or jump immediately follows a memory instruction which would have an
adverse impact on performance.
* `if` in `DBG_TAKEN_IF` is needless as the conditions it checks will be
true if controller enters `DBG_TAKEN_IF` state
* flop `enter_debug_mode` so `FLUSH` state looks at what
`enter_debug_mode` was when it was seen in `DECODE` state rather than
what it has become. In particular the controller could enter `FLUSH`
on the basis of performing a WFI then divert down the debug control
path due to a new debug request being raised. In this instance it is
preferable for the WFI to complete entering `SLEEP` before the debug
request wakes the core back up.
Xcelium 19.03 doesn't support the `->` (binary logical) operator, but
using `|->` (overlapping implication) is equivalent here and supported;
use this operator instead.
Fixes#1213
- Move various unused signal fixes from the waiver file to the rtl, so
that all tools can pick them up.
- Fix some oversize line issues.
- Fix some signed / unsigned casting issues.
- Remove some extraneous semicolons.
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
- If there is a request to enter debug mode (either due to a halt
request or single stepping mode) on the same cycle as an EBREAK
instruction, continue with the EBREAK and capture the ID PC rather
than the IF PC.
- relates to #1106
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
Currently in ibex_controller.sv when generating the ID of any fast
interrupts, irq_fast[5] is checked for twice.
This is a redundant line, and so this PR simply removes it.
Signed-off-by: Udi <udij@google.com>
This signal aimed to ensure loads/stores completed succesfully when an
interrupt or debug request appeared at the same time they were being
executed when the writeback stage is present. However other stall logic
suffices for this purpose (debug/interrupt will wait for instruction to
unstall in ID/EX which only happens once request has been sent out, then
first instruction of debug/interrupt handler will stall until load/store
response has been seen based on the generic stall logic for lsu requests
in the writeback stage).
With this signal in place debug single stepping was broken around loads
and stores.
Fixes#1029
- If an interrupt arrives at the same time as a load/store instruction
is in ID stage, the interrupt must wait until load/store completes.
Without the WB stage this happens naturally as the core stalls. With
the WB stage, we need to allow the load/store to progress to the WB
stage (and clear the ID stage) then hold back the interrupt until it
completes.
- Also cleaned up some lsu related stalling terms and signal naming.
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
When a potential exception occurs in ID/EX controller must wait for any
outstanding instruction in WB to complete before resolving it. The
instruction in WB may also have an exception which takes priority over
ID/EX.
Signed-off-by: Greg Chadwick <gac@lowrisc.org>
With the writeback stage enabled the controller can see a load or store
error from the writeback stage whilst seeing some other fault/exception
from ID/EX (e.g. an instruction fetch error). The writeback stage fault
must take priority, however without the writeback stage the
priortisation changes.
This introduces more explicit prioritisation logic for faults/exceptions
and gives the correct prioritisation for configurations both with and
without a writeback stage.
Fixes#912
Signed-off-by: Greg Chadwick <gac@lowrisc.org>
- Drive a speculative version of the branch signal into the IF stage to
drive address muxing
- The speculative signal is the same as the regular branch signal but
assumes all conditional branches are taken
- This breaks the timing path from branch condition calculation into
address muxing (and therefore PMP error calculation)
- When the branch is not taken, any external request we might otherwise
have made is suppressed
- This has a minor performance cost (0.8% without I$, ~0% with I$)
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
- The controller state machine could only progress to FLUSH to handle an
exception if instr_valid_i was set
- When the exception comes from a load/store in the Writeback stage, and
no new instruction has been driven into the ID stage, this could cause
exception to be missed
- The instr_valid_i qualification is therefore removed from the state
machine as all relevant signals inside that if block are already
qualified by instr_valid_i anyway
- Fixes#849
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
- Before this fix, the branch signal was qualified by the illegal
instruction signal and the illegal csr signal.
- This patch removes both of these since the decoder already masks
branches with illegal isntruction, and a branch cannot be a CSR op.
- This improves the worst path in the design significantly without the
branch target ALU.
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
mtval should record which half of the instruction caused the error
rather than just recording the PC.
An extra signal is added in the IF stage to indicate when an error is
caused by the second half of an unaligned instruction. This signal is
then used to increment the PC by 2 for mtval capture on an error.
Fixes#709
The third pipeline stage is a new writeback stage. Ibex can now be
configured as the original two stage design or the new three stage
design using the `WritebackStage` parameter in ibex_core. This defaults
to 0 (giving the original two stage design).
The three stage design is *EXPERIMENTAL*
In the three stage design all register write back occurs in the third,
final stage. This allows a cycle for responses to loads and stores so
when the memory system can respond in a single cycle there will be no
stall. This offers significant performance benefits.
Documentation of the three stage design is still to be written so
existing documentation applies to the two stage design only as various
aspects of Ibex behaviour will change in the three stage design.
Signed-off-by: Greg Chadwick <gac@lowrisc.org>
This commit modifies the `mip` CSR to not depend on the `mie` CSR. While
the values of both these CSRs are combined to decide whether an
interrupt shall be handled, the RISC-V spec does not state that the
content of of `mip` should depend on `mie`. This commit better aligns
Ibex with other open-source RISC-V cores.
This resolveslowRISC/ibex#567 reported by @pfmooney.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
prim_assert.sv is a file containing assertion macros (defines).
Previously, prim_assert.sv was compiled as normal SystemVerilog file.
This made the defines available for the whole compilation unit as soon
as they were defined. Since all cores using prim_assert depended (in
fusesoc) on the lowrisc:prim:assert core, prim_assert was always
compiled first, and the defines were visible in subsequent files.
All of that is only true if all files end up in one comilation unit. The
SV standard states that what makes up a compilation unit is
tool-defined, but also states that typically, passing multiple files (or
a file list/.f file) to a single tool invocation means that all files
end up in one compilation unit; if the tool is called multiple times,
then the files end up in separate compilation units.
Edalize (the fusesoc backend) doesn't guarantee either behavior, and so
it happens that for Vivado, Verilator, Cadence and Synopsys simulators,
all files are compiled into a single compilation unit. But for Riviera,
each file is a separate compilation unit.
To avoid relying on the definition of compilation units, and to do the
generally right thing (TM), this commit changes the code to always
include the prim_assert.sv file when it is used in a source file.
Include guards are introduced in the prim_assert.sv file to avoid
defining things twice.
This commit replaces all X assignments in the RTL with defined
values. In addition, SystemVerilog Assertions are added to catch
invalid signal values in simulation. A new file containing the
corresponding assertion macros is added as well.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
- Add the minimum amount of trigger system to support GDB hbreak
- Only a single trigger is implemented
- Only instruction address matching
- Only break into debug mode (no native debug)
- Fixes#382
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This commit reworks the generation of the `core_busy` signal used to
control the main clock gate of the core. Without this commit, the
controller generates a separate `first_fetch` signal only asserted in
the FIRST_FETCH state that directly controls `core_busy` and thus the
main clock gate. This is problematic as it introduces a feedback to
from the controller state into the clock.
This commit removes the problematic signal and changes the generation of
`ctrl_busy` in the FIRST_FETCH state of the controller. This signal is
now used to control the main clock gate in all states (previously all
except FIRST_FETCH) but it gets registered, thus it does not introduce
the feedback into the clock.
This resolveslowRISC/ibex#211.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
This commit removes a redundant for `ebrk_insn` in the `DBG_TAKEN_ID`
state. If this signal is not set, the controller does not enter this
state in the first place. This is not changing functional behavior,
but removes a `MISSING_ELSE` coverage hole reported by @udinator.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
This commit turns the last case in the exception handling if/else block
from an `else if` to an `else`. This is not changing functional
behavior as the same condition is checked previously, but removes a
`MISSING_ELSE` coverage hole reported by @udinator.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
When we single step over an instruction that causes an exception DPC
should be set to point to the exception handler (where we would have
gone were we not single stepping).