When encountering certain illegal compressed instructions, incorrect instruction information was displayed. Now, illegal instructions can be printed correctly.
This removes several assertions from `ibex_controller`. They aimed to
ensure that controller behaviour was correct on exception behaviour
(e.g. ensuring that a pending interrupt will actually trigger an
interrupt). However they've proved to be flaky and hard to maintain with
multiple edge cases needing to be accounted for.
The co-simulation checking in functional verification will catch the
same issues these assertions catch. The assertions (when working
correctly) would cause a failure directly when the bug happens which
makes debugging easier. However they've added significant effort in
regression triage due to their many false failures so it's not worth the
maintenance burden.
Within formal they don't really add any value now we have the full
end-to-end formal flow.
This fixes#2193, an issue that meant bit clears in PMP related CSRs
didn't immediately apply to an instruction already in the fetch stage
due to a lack of a pipeline flush.
With this change the pipeline will flush in that scenario, fixing the
issue. It now flushes the pipeline on all CSR modifications as this
makes the pipeline more resliant against similar issues in the future
(where the list of CSRs to flush on should have been updated but
wasn't).
Previously the ibex_cs_registers module received the CSR address via the
operand muxes. This has been observed to cause timing issues in some
cases. The CSR address is always read from the same bits of the
instruction so there's no need to go via the operand muxes. With this
change the relevant instruction bits are fed straight out of the decoder
and into the ibex_cs_registers module.
This assertion wasn't quite correct if SecureIbex is false because it
was checking for the magic IbexMuBiOn value instead of just looking at
the bottom bit.
Fixes#2249.
These were noticed by someone responding to issue #2230. I think the
author's original logic was to point out that there's a path from e.g.
raddr_a_i to rdata_a_o which doesn't depend on any clock, so is
"asynchronous".
But that's the same in the other modes and also for the other register
file implementations, which don't have analogous comments.
Drop these ones.
The RISC-V Debug Specification (current release 1.0.0-rc4) in Section
A.2 states that the PMP must not disallow accesses to addresses of the
Debug Module when the hart is in debug mode, regardless of how the PMP
is configured. This commit changes the PMP accordingly.
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
Although the current code isn't wrong as far as I can tell, it would be
better to initialize the lognest_name_length variable when it is
declared to avoid a build warning with older Verilator versions.
When targeting Xilinx FPGAs, we utilize a DSP for counters
with a width of less than 49-bit. In this case, a sync. reset
is needed. However, currently, there is a bug in the RTL
where also a sync. reset is used for the non-DSP counters
on the FPGA.
Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
If the counter width is >= 49, we do not use a DSP on the FPGA.
Then, we should use an asynchronous reset to initialize the counter.
This bug was detected when enabling the lockstep for the CW340. A
lockstep mismatch happend as the mcycle counters of the main and
shadow core did not match due to this bug.
Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
We have been using GitHub Actions for some time now, both for public CI
and private CI, and it seems to be functioning well.
Signed-off-by: Gary Guo <gary.guo@lowrisc.org>
We should use `WordZeroVal` instead of `0` for reads from register `x0` in the
FPGA register file.
This bug was discovered when enabling the `RegFileECC` parameter. When this is
enabled, the core performs ECC checks, expecting that `WordZeroVal` is returned
for `x0`. Else, we get a major alert.
FixeslowRISC/opentitan#25146
Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
- Move background to its own layer
- Make font sizes consistent
- Fix icache and pc background
Previously the background was morphed around the text, this makes it a
background again.
- Remove redundant rectangle
The instruction memory interface had two rectangles, one black and one
purple. I removed the purple one that was bleeding through in the
corners.
- Instruction fetch alignment
The Instruction fetch block was not the same height and was not top
aligned with the other blocks.
- Align text with boxes
This essentially aligns all the text insides the blocks
- Standardize lines as 0.265mm
The lines between blocks and the ones making the triangular shapes were
mostly 0.265mm with a few exceptions.
- Stroke width of block outlines same
Made all the stroke widths for all the blocks 0.5mm. I've made the outer
box a nice round 1.0mm.
- Use lowRISC colors
E0384F for the background (including the start of the gradient)
A21F4F for the outside line
- Alignment of in/out arrows
Many of these arrows were not aligned, this improves that alignment.
- Add white background to instr inf
Instruction memory interface lost its white background when the purple
outline was removed. This commits adds it back in.
- Use Liberation Sans everywhere
Exo 2 is not supported natively in browsers and there was no easy way to
embed fonts in SVG where Inkscape knew about it.
- Fade to white, not transparent
- PMP check font is now smaller
- Add background to debug request input
- Make text under prefetcher bigger so it is rendered on GitHub
- Execute text is now its own block so that it is rendered on GitHub
The previous code here was a bit too hacky, so implement a solution that
directly follows the suggestion in the Cadence support article.
An example was also added to make it clear what this transformation is
achieving.
Add some more typehints, and cleanup names.
Signed-off-by: Harry Callahan <hcallahan@lowrisc.org>
By using top-level straps for the PMP reset configuration its
easier to implement different reset configurations if there are
multiple Ibex cores in the system.
Signed-off-by: Robert Schilling <rschilling@rivosinc.com>
It appears that VCS require expression after `iff` to be wrapped inside
parenthesis otherwise it will complain about syntax error.
This should fix the weekly VCS regression.
Signed-off-by: Gary Guo <gary.guo@lowrisc.org>
Prior to this commit an ECC failure on the incoming data memory response
factored directly into the outputs for the instruction memory
interfaces. This existed due to a desire to take an NMI on an ECC
failure as soon as possible but causes timing issues so it has been
altered.
Now rather than directly raise the NMI the same cycle the assertion of
'irq_nm_int' is delayed by a cycle which breaks the feedthrough path.
Previously the riscv_rf_intg_test skipped certain scenarios where an ECC
error from the register file should trigger an alert. This change stops
it from skipping those scenarios.
A spurious response is one that isn't associated with any on-going
request. With this new feature the memory agent can generate them
randomly when the interface is idle (i.e. there are no outstanding
requests).
This test injects a fault into different MuBi encoded signals within
the prim_ram_1p_scr and prim_ram_1p_adv and checks whether a fatal
alert is triggered.
I have excluded the addr_match signal from FI as its encoding
is not directly checked. If the signal was a MuBi True, a
fault into it is treated by the mubi4_and_hi as a False.
If the signal was a MuBi False, a fault into it is treated
by the mubi4_and_hi also as a False. Hence, no address
collision occurs and the holding register is not returned.
This PR is based on #2182 and closes#2173.
Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
When an interrupt is raised the Ibex controller will move from the
DECODE state to the IRQ_TAKEN state when it chooses to handle the
interrupt. When in IRQ_TAKEN it's possible for the interrupt state to
change again which aborts the interrupt entry. This leads to mis-matches
against cosim.
This change adds a warning to flag up cases where this has occurred to
enable quick triage of failures related to this scenario.
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.
The 'pre_val' MIP addresses the scenario where MIP changes as an
instruction is excuting, this means a CSR instruction can observe a
different MIP from the one that decides whether or not that instruction
will be interrupted.
Where an access is unaligned Ibex splits it into two transactions, each
of which undergoes a PMP check. It is possible for the first half to
fail a PMP check and the second to succeed and hence produce a request
on the memory interface.
In Spike it accesses memory byte by byte and if it encounters a PMP
error for a particular byte it won't try any further bytes.
This results in a mis-match between Ibex and spike when an unaligned
transaction is split across two PMP regions, one of which allows the
access and the other doesn't. Ibex generates a transaction and spike
doesn't producing an error.
This adds a fixup into the co-simulation environment. It detects when we
have an access that fails PMP that is misaligned. Where this has
resulted in Ibex producing a memory request that spike would not we
remove it from the list of memory requests to check after checking that
the request passes PMP within spike.
Previous code working with clocking blocks synced to the raw clock
event. Instead they should sync to the clocking block event. This
ensures the values being read are the latest values rather than a cycle
old.
In particular for ibex_mem_intf_agent this meant it was unable to
produce a single cycle response to any memory transaction. With this fix
these are now observed.
Update code from upstream repository
https://github.com/lowRISC/opentitan to revision
d268f271f4f75aeb8f3bf9624a497ae5bfb9c47e
* [rtl] MuBi encoding of iCache memory ctrl signals (Pascal Nasahl)
* [sram_ctrl] Add readback feature (Pascal Nasahl)
* [fpv] Tweak report headers to match Jasper version (Rupert
Swarbrick)
* [prim_pad_wrapper,rtl] Change input enable to active-high (Andreas
Kurth)
* [hmac/rtl] Wait for digest of complete block when stopping (Martin
Velay)
* [prim_sha2_pad,rtl] Signal msg feed complete also when stopping
(Andreas Kurth)
* [prim_sha2_pad,rtl] Go to idle (without padding) when told to stop
(Andreas Kurth)
* [prim_sha2_pad,rtl] Refactor comparison on tx_count and msg len into
signal (Andreas Kurth)
* [prim_sha2_pad,rtl] Fix setting of digest mode when continuing
(Andreas Kurth)
* [hmac/prim_2,rtl] Do not clear redundant digest values (Ghada
Dessouky)
* [prim,fpv] Tweak how a parameter gets used in some assertions
(Rupert Swarbrick)
* [prim,fpv] Fix trivial lint warning in prim_fifo_sync_assert_fpv
(Rupert Swarbrick)
* [prim,rtl] Fix trivial lint warning in prim_fifo_sync (Rupert
Swarbrick)
* Launcher Modification (Youming Lu)
* [top_earlgrey,pinmux] Add input disable attribute for non-manual
pads (Andreas Kurth)
* [dv] Add more prints to bit bash sequence (Rupert Swarbrick)
* [ipgen,flash_ctrl] Fix core files (Guillermo Maturana)
* [prim,rtl] Avoid unnecessary check in prim_esc_receiver.sv (Rupert
Swarbrick)
* [prim,fpv] Use PossibleActions param in prim_esc_receiver (Rupert
Swarbrick)
* [prim_diff_decode] Use `prim_xnor2` to detect integrity issue
(Andreas Kurth)
* [prim] Fix typo'd loop increment (James Wainwright)
* [hmac/prim_sha2,rtl] Implement SW error for invalid HMAC config
(Ghada Dessouky)
* [rom] Remove real and fake key targets. (Miguel Osorio)
* [prim_sha2,rtl/dv] Fix secret value wiping (Ghada Dessouky)
* [prim,rtl,fpv] Fix typo in assertion in prim_alert_receiver (Rupert
Swarbrick)
* [fpv,prim] Drop prim_count_expected_failure.hjson (Rupert Swarbrick)
* [fpv,prim] Generalise from DecrNeverTrue to listing possible actions
(Rupert Swarbrick)
* [prim,fpv] Correct assertions for commit_i input (Rupert Swarbrick)
* [prim,fpv] Rephrase some "backwards" assertions in prim_count
(Rupert Swarbrick)
* [prim,fpv] Properly "waive" some unreachable prim_count assertions
(Rupert Swarbrick)
* [prim,fpv] Fix width of FPV variable in prim_arbiter_ppc.sv (Rupert
Swarbrick)
* [prim,fpv] Rephrase prim_count error assertions (Rupert Swarbrick)
* [prim,fpv] Fix port list in prim_count_tb (Rupert Swarbrick)
* [prim_ram_1p_scr] Align documentation with actual implementation
(Pirmin Vogel)
* [prim, rom_ctrl] Increase number of PRINCE rounds for improved
security (Pirmin Vogel)
* [prim,fpv] Make file structure slightly clearer (Rupert Swarbrick)
* [prim,fpv] Shorten a variable name (prim_hier -> hier) (Rupert
Swarbrick)
* [prim,fpv] Tidy up and document some FPV macros (Rupert Swarbrick)
* [dvsim,lint] Fix bug in duplicate detection in lint parser (Rupert
Swarbrick)
* [rtl,comments] Fix some comments (Guillermo Maturana)
* [dv,prim] Clarification of reset behavior (Adrian Lees)
* [ast] Add dependency in fileset_partner to select correct ast_pkg
(Sharon Topaz)
* [prim,fpv] Only allow unconstrained counters in prim_count FPV
(Rupert Swarbrick)
* [dvsim] Split and rename Modes.py (Rupert Swarbrick)
* [prim,dv] Tweak ASSERT_FINAL to be a no-op if FPV enabled (Rupert
Swarbrick)
* [prim,tlul,rtl] Explicitly cast a "1" to specific number of bits
(Rupert Swarbrick)
* [dvsim] Fix plurals in type names in Modes.py (Rupert Swarbrick)
* [dvsim] Move find_mode and find_and_merge_modes out of Modes class
(Rupert Swarbrick)
* [dvsim] Die more cleanly on an invalid use of merge_mode (Rupert
Swarbrick)
* [dvsim] Get rid of "mname" field in Modes.py (Rupert Swarbrick)
* [dvsim] Simplify named attribute lookup in Modes.py (Rupert
Swarbrick)
* [dvsim] Get rid of pretty print magic in Modes.py (Rupert Swarbrick)
* [dvsim] Strengthen typing and simplify printing for modes in SimCfg
(Rupert Swarbrick)
* [dvsim] Slightly tidy up SimCfg._print_list (Rupert Swarbrick)
* [dvsim] Get rid of an unused dictionary in OneShotCfg.py (Rupert
Swarbrick)
* Add the project name to the copyright header (Michael Munday)
* Fix or waive Python lint errors and warnings (Pirmin Vogel)
* Remove trailing whitespaces (Pirmin Vogel)
* [dv,mem_bkdr] Fix handling of multiple tiles in sram (Guillermo
Maturana)
* [hmac] Coding style and minor fixes (Ghada Dessouky)
* [dv] Remove phase argument from monitor's collect_trans (Rupert
Swarbrick)
* [prim_fifo_sync_cnt] Minor code cleanup (Andreas Kurth)
* [dv,mem_bkdr] Fix digest calculation for hw_cfg0 (Guillermo
Maturana)
* [prim_fifo_sync_cnt] Fix signedness of Depth parameter (Andreas
Kurth)
* [prim_fifo_sync] Keep wraparound pointers contained within
`prim_fifo_sync_cnt` (Andreas Kurth)
* [prim_fifo_sync] Move pointer and depth calculation to
`prim_fifo_sync_cnt` (Andreas Kurth)
* [prim_fifo_sync] Remove out-commented RTL code (Andreas Kurth)
* [prim_fifo_sync_cnt] Improve module and parameter documentation
(Andreas Kurth)
* [lint] Demote licence warning in AscentLint parser (Rupert
Swarbrick)
* Revert "[dv] Remove phase argument from monitor's collect_trans"
(Rupert Swarbrick)
* [dv] Fix parameter types in dv_base_mubi_cov.sv (Rupert Swarbrick)
* [dv] Remove phase argument from monitor's collect_trans (Rupert
Swarbrick)
* [dv, xcelium] Use detachable reports to avoid CORS (Elliot Baptist)
* [otp_ctrl] Add fuse for late debug enable mechanism (Michael
Schaffner)
* [prim] Add support for MuBi's up to 32bit (Michael Schaffner)
* [otp_ctrl] Increase Hamming distance in OTP commands (Michael
Schaffner)
* [dv] Add checks to set_freq_*hz (Rupert Swarbrick)
* [dv] Fix more timeout comments with wrong units (Elliot Baptist)
* Make .core files pass FuseSoC 2 schema validator (Olof Kindgren)
* [dvsim] Run deepcopy to work around memory usage bug (Rupert
Swarbrick)
* [dvsim] Make global_val handling a bit clearer (Rupert Swarbrick)
* [prim_sha2,rtl] Add key_length type and change type encodings (Ghada
Dessouky)
* [dv,sram_ctrl] Fix a few failing tests (Guillermo Maturana)
* [topgen] Add field to specify status IRQ default behavior (Michael
Schaffner)
* [dv] Update clear_all_interrupts to support status type (Michael
Schaffner)
Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
With this change all memory responses are only acted on if Ibex is
expecting them for all secure configurations. Previously an error
response that was injected onto the bus would trigger an exception that
shouldn't occur (in particular breaking the functioning of the multiply
state machine). In addition for configurations without the writeback
stage an injected load data response could trigger an incorrect write to
the register file.
This is only applied to the secure configurations, non-secure
configurations assume correct adherence to the bus protocol meaning a
response will only be seen if a request is outstanding.
This parameter allows integrators controlling the number of PRINCE
half rounds in the scrambled ICache SRAM primitives, e.g., to balance
timing impact and security guarantees.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
This sets the C++ standard that's being used for a compiler that's
building a Verilator simulation. Recent versions of Verilator (since
5.020) require the compiler to be in C++14 mode, so passing -std=c++11
breaks the build with them.
Looking at history, -std=c++14 has been supported since GCC
6.1 (released in 2016), so I don't think this argument is going to
cause any tooling problems.
We are switching to use non-root GitHub action runners, which need
sudo for global package installation.
Signed-off-by: Gary Guo <gary.guo@lowrisc.org>
The DV flow is expecting log files to be produced with a particular file
name, without it the reporting mechanisms do not work correctly. This
adds VCS log output to a named rather rather than just capturing stdout.
Previously some $value$plusargs calls weren't explictly specifying a
format for a number to read from the plusarg. Under some simulators this
is acceptable under others it generates an error.
An instruction stall on a FENCE.I had been mistakenly placed in an
illegal bin. A FENCE.I acts much like a branch or jump so can produce
instruction stalls just as those instructions can.
It's possible for a TestRunResult to contain an entry that has a path to
a build/run artifact but for that to be None rather than an actual path.
This causes the collect_results.py script to fail.
With this change such paths will be described as 'MISSING' in the
regression log instead.
When SpikeCosim is getting destructed a SIGSEGV was observed on CentOS
7. The root cause hasn't been identified other than it relates to the
deletion of `isa_parser_t`, potentially some kind of use after free
error.
This is an (optional) hacky workaround that simply never deletes the
`isa_parser_t` pointer in SpikeCosim. As in practise this occurs at the
end of simulation when the process is terminating the memory leak is of
little consequence.
Longer term this issue should be investigated and properly fixed.
Fixes two issues observed on CentOS 7 during testbench compile
- pkg-config doesn't behave properly when it receives multiple flags
- riscv-fesvr library needs to be included in build
The latest version of `prim_count` from OpenTitan introduces a
`commit_i` input. To retain the behaviour of the previous `prim_count`
this should be set to a constant 1.
The `cnt_next_o` output has been renamed to `cnt_after_commit_o`.
Modify tracer to use the appropriate read/write masks when logging
load/store traffic from the Load Store Unit.
Signed-off-by: Adrian Lees <a.lees@lowrisc.org>
Return an error signal to the host if an address request
does not match any device.
Previously a decode failure would match against the first
device, which in the Ibex Demo System happens to be
the SRAM.
Currently, the dual-core lockstep FI mitigation is enabled/disabled
using a single bit.
For transient bit-flips, this is not problematic, as one bit-flip
into this signal and one bit into the Ibex is required to threaten
the security of the system.
However, a permanent stuck-at-0 fault could disable the lockstep
completely by targeting this signal. Then, only a single, additional
fault (transient or permanent) is required.
This PR enhances the FI resilience of the Ibex lockstep by encoding
this single bit into a ibex_mubi_t signal, i.e., a 4-bit multi-bit
signal.
Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
To be consistent between projects, this PR updates the Verilator
version to 4.210, which is also used by OpenTitan. The reason for
this change is that in #2129 Verilator linting issues occured
that did not occur in OpenTitan.
Closes#2131.
Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
The private CI works by using workflow dispatch to trigger a CI on
another repository.
Pending status checks are created before calling the dispatch to
indicate their queued status before they are picked up in private CI,
and also serves to block merge group from success.
Signed-off-by: Gary Guo <gary.guo@lowrisc.org>
As described in #20715, a single fault-induced bit-flip inside the
register file could change which of the register file value is
provided to Ibex.
This PR fixes this issue by (i) encoding raddr_a/b to one-hot
encoded signals, (ii) checking these signals for faults, and
(iii) using an one-hot encoded MUX to select which register file
value is forwarded to rdata_a/b.
Area increases by ~1% (Yosys + Nangate45 synthesis).
I conducted a formal fault injection verification at the Yosys
netlist to ensure that the issue really is fixed.
Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
Currently, the verification documentation recommends to using
ibex-cosim-v0.3. However, this version of spike causes some
compilation issues on my side:
"class "processor_t" has no member "set_mhpm_counter_num"
when calling "make" in dv/uvm/core_ibex/.
This issue occurs when using the latest pre-build lowrisc toolchain
"20231205-1" or "20230427-1".
When using ibex-cosim-v0.5 DV works.
Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
`distutils` is deprecated and will generate warnings when used.
Replace it with packaging.version instead.
pip3 command line invocation is replaced with importlib.metadata,
which removes dependency on pip3 being present.
Signed-off-by: Gary Guo <gary.guo@lowrisc.org>
This change updates the GitHub actions workflows to run on PR updates
and within the GitHub merge queue, but not on the push to the master
branch.
Because we use merge queues, the re-run for the master branch would be
redundant.
Signed-off-by: James Wainwright <james.wainwright@lowrisc.org>
Recent versions of Verilator complain about the code that was there
because the csr_pmp_cfg argument clashes with a name in ibex_core.sv.
What's more, they mean different things! In ibex_core.sv, it was the
PMP configuration for the entire core. In the functions, it's the PMP
configuration for a single region. This patch adds a "region_" prefix
to the names, which fixes both the Verilator warning and my confusion!
Update code from upstream repository
https://github.com/lowRISC/opentitan to revision
e6a0e9a1363d33789283ea6ba3c4d94d41f2dee5
* [dvsim] fix seed in json report (Gary Guo)
* [prim_prince,rtl] Split data_state array into two pieces (Rupert
Swarbrick)
* [prim_prince] Move the split_var verilator hint to prim_cipher.vlt
(Rupert Swarbrick)
* [bazel] Use the new rules for building ROMs (Chris Frantz)
* [hw,rtl,prim] Switch AND/OR for Mubi W1S/W1C (Robert Schilling)
* [util] Error out if secure_prng seed is less than 256 bits (Vladimir
Rozic)
* [dv] Update dv_sim to support sram new targets (Miguel Osorio)
* [flash_ctrl,dv] update expected double bit error set (Jaedon Kim)
* [bazel] Update the binary/test rules for building ROMs (Chris
Frantz)
* [bazel] Prepare `dvsim` to work with the new rules (Chris Frantz)
* [mubi,gen] Fix comments (Guillermo Maturana)
* [reggen] Add mubi support SWAccess that sets/clears a reg (Robert
Schilling)
* [doc] Fixing a few typos in xoshiro PRNG documentation (Vladimir
Rozic)
* [doc] Testplan's are now generated as markdown. (Hugo McNally)
* [bazel,dvsim] Prevent dvsim from (trying to) copy irrelevant files
(Amaury Pouly)
* [doc] Moved badges over to using hosted images (Hugo McNally)
* [doc] Fixed links to the getting started section. (Hugo McNally)
* [dvsim] Avoid checking for gsutil when we just need gcloud (Rupert
Swarbrick)
* [dvsim] Simplify the code that copies files up to GCP (Rupert
Swarbrick)
* [dvsim] Use new results_server methods to list cleanly (Rupert
Swarbrick)
* [dvsim] Wrap logic to move "latest" directory into results_server.py
(Rupert Swarbrick)
* [dvsim] Add an object representing connections to results server
(Rupert Swarbrick)
* [dv/cov] Fix coverage handling in some common items (Guillermo
Maturana)
* [prim] Convert prim_clock_div to abtract (Alexander Williams)
* [dv/top-level] Fix sram data integrity error injection (Guillermo
Maturana)
* [tools,vcs] Make flops use the sampled value of data to avoid races
(Guillermo Maturana)
* [prim lfsr] Replace randomize() calls with $urandom in prim_lfsr_tb
(Vladimir Rozic)
* [doc] Update LFSR coeffs descriprion. (Vladimir Rozic)
* [prim_lfsr] Remove redundant list of LFSR_COEFF (Vladimir Rozic)
* [dv/top-level] Harden chip_sw_data_integrity_escalation (Guillermo
Maturana)
* [otbn,dv] Wait more carefully for secure wipes in vseqs (Rupert
Swarbrick)
* [doc,report] Fix the dvsim report links to the testplans (Harry
Callahan)
* [doc] Add the block-dashboards to the primative page (Harry
Callahan)
* [prim_subreg] Fix RC access corner case (Michael Schaffner)
* [prim_lc_dec] Fix Xcelium compile error (Michael Schaffner)
* [misc] Use lc_tx_t testing functions at endpoints (Michael
Schaffner)
Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
The keys in this file get incorporated into the FlowCfg object that
represents a simulation or similar. Adding a spurious key won't cause
any problems, but we actually need it for the next commit, which grabs
the current version of dvsim from OpenTitan. That version of dvsim
expects the "book" key to have been set in common_project_cfg.hjson.
Splitting the two commits like this should make it a bit more obvious
where things have come from.
The existing code wanted to open file_handle as a trace file if
necessary and then use it on that clock cycle. So it (sensibly) used a
blocking assignment.
Verilator now warns about blocking assignments to globals in
"sequential logic processes" (the always_ff that is driving
everything). This is sort of easy to fix: just use an "always" block!
This commit looks slightly more involved because I've changed things
to pass the file handle to printbuffer_dumpline as an argument. It
makes the state update (where we open the file handle) a little easier
to follow.
Update code from upstream repository
https://github.com/chipsalliance/riscv-dv to revision
71666ebacd69266b1abb7cdbad5e1897ce5884e6
* Fixes to support RV32 (Maciej Kurc)
* Extend CI matrix (Eryk Szpotanski)
* Add pyflow test (Grzegorz Placzek)
* Allow the CI to run from any branch and any PR (Maciej Kurc)
* [pmp] Remove MSECCFG reads from trap handler when Smepmp is disabled
(Marno van der Maas)
Signed-off-by: Greg Chadwick <gac@lowrisc.org>
The gen_csr_test.py script provided by RISC-V DV doesn't work with
version 4.0 and upwards of the bitstring library. This patch pins it to
3.1.9 to avoid the issue.
With the latest versions of all python packages in
python-requirements.txt ibex_cmd.py was seeing a run-time type error.
Data from a YAML file that had previously always been a string could now
be an int as well. This alters the code to allow the int to work.
It turns out that we use split_var in the code, which was added in
version 4.030 (and several bugs were fixed in following versions).
Change the minimum required version to match what we're using in
CI (and presumably works!)
This was triggered by issue #2080.
This shouldn't change the behaviour when it works. On a failure, we
now print out a bit more about what's going on.
When asked to do something impossible now, I think the output is a bit
clearer. For example, if you try to run riscv_bitmanip_full_test with
an OpenTitan configuration (which doesn't have full bitmanip), the
warning message is now:
WARNING:ibex_cmd:Rejecting test: riscv_bitmanip_full_test. It specifies rtl_params of ['ibex_pkg::RV32BFull'], which doesn't contain the expected 'ibex_pkg::RV32BOTEarlGrey'.
(The following stuff that appears is a bit messy, but at least the
first line is now clearer!)
The recent versions of Verible that I've tried die when they are given
an empty waiver file. The error message is "Fatal error: Broken waiver
config handle". I can't see a way to add a comment ("// No waiver" or
similar), so I think the best way to keep everything alive is to
delete the empty file.
The background of the Icache block was a not-well-fitted path that was
causing the background to seep through. This commit updates that
background to more tightly align with the lines and letters.
The background was originally a gradient background on the right
together with a solid background on the left. This caused some
distortion on closer inspection. This commit changes it to have one
background that is a gradient from left to right.
Running the verible linter and adding review comments to the pull
request previously had to be done in two stages:
1. Triggered on the pull request - prepare config and waiver files as
artifacts.
2. Running on the repo's HEAD - run Verible and add review comments.
This was required because Actions running in the context of the pull
request did not have write permissions to add comments to pull requests.
This is now possible with the `pull_request_target` event, which
triggers when pull requests change, but runs in the context of the
repo's HEAD and has the permissions to create comments.
See lowRISC/ibex#1427 and
chipsalliance/verible-linter-action#31 for details.
Signed-off-by: James Wainwright <james.wainwright@lowrisc.org>
Update code from upstream repository
https://github.com/chipsalliance/riscv-dv to revision
08b12066b34c9728f706e45098ba502a36d7ca59
Signed-off-by: Marno van der Maas <mvdmaas+git@lowrisc.org>
Update code from upstream repository https://github.com/lowrisc/riscv-
isa-sim to revision a4b823a1c7a260b532e1aa41b4d929e9634a7222
* Remove personal paths from Makefile (Marno van der Maas)
* Remove trailing whitespace (Marno van der Maas)
Signed-off-by: Marno van der Maas <mvdmaas+git@lowrisc.org>
Update code from upstream repository https://github.com/lowrisc/riscv-
isa-sim to revision a7c5d5d830e4095aa86580579efc46335fbc2f80
Signed-off-by: Marno van der Maas <mvdmaas+git@lowrisc.org>
This initialisation causes Xcelium to complain about multiple drivers
for the variable. Which is rather confusing, but we don't actually
need to initialise it: the variable will be X at the start of time, so
the logic that stops the simulation if it gets big won't fire until
after reset anyway.
The ibex_top_tracing module takes a ram_cfg_i for something to pass
through to the RAM. Use the named zero (RAM_1P_CFG_DEFAULT) instead of
building it by hand: now we get the right width.
This helps hit more coverage more reliably in particular for the
priv_mode_irq_cross cross coverage.
A better fix would adjust riscv_mem_intg_error_test to utilize U mode
more but it's a quick test for run so this suffices for now.
Not doing so causes VCS to spit out a warning message. The intention
seems to be that the initial call to $value$plusargs will evaluate to
true and will put the value that was assigned into the
disable_pmp_exception_handler variable, which then gets checked.
The previous version doesn't make sense if you read the classes in
exactly the order they are defined in the file. It turns out that this
is what VCS did: oops! Fortunately, the fix is pretty trivial: declare
the classes the other way around.
The previous code caused VCS to complain that the "with" clause didn't
use any of the constituent coverpoints. I *think* that VCS wasn't
understanding that cp_interrupt_taken[5:4] does indeed depend on
cp_interrupt_taken (concentrating on core_ibex_fcov_if for
concreteness).
Fortunately, the check is easy to express a different way. There, we
were just asking that the top two bits are zero. Another way to say
that is "if I shift everything else off the bottom, the result is
zero". So we say it that way.
This causes VCS to spit out an error because it's not technically
allowed in SystemVerilog. The only things that we needed to import
seems to have been the CSR_MHPMCOUNTER3* names. We can just refer to
them explicitly.
Other code tries to pick up things like DATA_WIDTH through this agent
package, that it imports. That doesn't seem unreasonable, but VCS
complains because we're not re-exporting it here.
Some code we've got in Ibex uses some stuff we added to Spike last
October. That, in turn, is now tagged in our riscv-isa-sim repository
as ibex-cosim-v0.5. Update the version requirement here to match.
It seems that typeguard now spots if env happens to be None. We can
just relax things: we're only using env by passing it through to
subprocess.run, which handles a None env in the expected way.
We ended up with the Unicode fix twice because of two colliding PR
merges. We only need one copy of the -CFLAGS argument, and VCS
generates a rather strange message about an unknown argument if you
use it twice. Fortunately, it's easy to fix once you've worked out how
to get the system to print out what it's doing.
Cairo libraries are required for a python dependency.
New RTD config introduced to fix build errors introduced by new urllib.
We need to ensure the docs a built on a modern ubuntu with a
sufficiently new python (see
https://github.com/readthedocs/readthedocs.org/issues/10290).
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.
An IRQ asserting then deasserting when not explictly cleared by an
interrupt handler can lead to RTL/cosim mismatches in some cases.
Increasing the delay here minimises those instances.
- rvfi_trap now correctly handled for writeback
- issue created to track coverpoint for pmpcfg reserved bits writes.
- flush pipe on debug CSR writes is reasonable
With funny CI environments, the locale might not be set properly, making perl complain. The version check will fail then. I believe it is sufficient to check for the tool version, stderr can be ignored safely, if I am not missing something.
The `pcount_enable` function can be used to selectively enable
performance counters only for a specific code segment. For example:
```c
pcount_enable(0);
pcount_reset();
pcount_enable(1);
/* code to be measured */
pcount_enable(0);
```
The `pcount_enable` function consists of a single CSR instruction, so
the overhead and thus the impact on the measurement is potentially low.
When the function is called, however, many instructions have to be
executed in addition to the single CSR instruction, which influences
measurements.
This commit moves the `pcount_enable` function to the
`simple_system_common.h` header file and declares it as `inline` (and
`static`, to prevent link-time collisions when the header file is
included in multiple compilation units). This helps the compiler inline
the function even without LTO.
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
This commit introduces the use of a pydantic model to validate the
data used to define directed tests. 'pydantic' is a python data validation
and settings management library which allows for structured data to be
checked against 'pydantic models'. In this case, we define a 'model' for
how we expect the directed-test yaml to look, including fields and datatypes,
and then validate that the imported file matches this expectation.
In effect, it allows the checking of the data to be seperated from its use.
dv/uvm/core_ibex/scripts/directed_test_schema.py defines the pydantic model,
and provides a function 'import_model()' to check the file-contents and
return a valid dictionary of the structured data.
* First implementation of a directed_test framework, which aims to re-use as much
as possible from the existing riscvdv generation
* Fixed directed test flow to cleanly end the test
* clang-format is off for assembly header files
This commit adds two assertions in `ibex_top` to ensure that the
scramble key is correctly applied to the icache scrambled memory
primitives. Those assertions previously existed in the module that
instantiated Ibex in OpenTitan, but the reference into the generate
loops was problematic for some EDA tools; see lowRISC/opentitan#17155.
Additionally, the assertions previously used the input scramble key
(`scramble_key_i`) even though they tolerated a delay after which the
input scramble key was not necessarily valid anymore (i.e.,
`scramble_key_valid_i` could go low and `scramble_key_i` could take any
value). This mistake has been corrected by sampling the input scramble
key for the assertions when it is valid and using the sampled value in
the comparison of the assertions. This problem surfaced in the DV
environment of Ibex (but not in OpenTitan), where multiple tests
(including `riscv_rand_instr_test`, `riscv_mem_error_test`, and
`riscv_multiple_interrupt_test`) failed; these tests now pass.
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
Starting with setuptools version 66.0.0, legacy package version names
such as 0.23ubuntu1 are no longer supported. Since some of our
Python dependencies use this format, we pin the setuptools version to
the last version before this change. This unblocks CI and gives us time
to upgrade/rebase our dependencies.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
Previously, it was possible to glitch data_rvalid_i at the interconnect
level and if the data integrity bits happened to be valid, Ibex would
write the current data_rdata_i into the register file even if it wasn't
doing a load. Since the glitch is inserted at the interconnect level,
both the main and the shadow core are affected equally.
This commit changes the WB stage to only forward the LSU write enable,
which is generated from data_rvalid_i, when Ibex is actually waiting for
an interconnect response for a load instruction. This substantially
narrows down the window for attacks at the interconnect level.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
Xprop is a simulation feature that improves the SV semantics when
conditions contain 'X values. Change RTL or DV code to enable more xprop
instrumentation.
This addresses lowRISC/opentitan#16791 and some of
lowRISC/opentitan#16723.
Signed-off-by: Guillermo Maturana <maturana@google.com>
It randomly writes to fields of cpuctrlsts to enable and disable data
independent timing, dummy instruction insertion and the icache. This is
used in riscv_debug_basic_test and riscv_single_interrupt_test to see
interrupts and debug requests when dummy instruction insertion and data
independent timing is enabled.
Update code from upstream repository https://github.com/google/riscv-
dv to revision 68ab8230c52ec66b393c04394aef4d6082ee53b4
* [pmp] Ensure MML PMP configurations don't dominate. (Greg Chadwick)
* [pmp] Add option to constrain addresses to stay in 32-bit space
(Greg Chadwick)
* randomizing mstatus.MIE when priv mode is lower than machine (Saad
Khalid)
Signed-off-by: Greg Chadwick <gac@lowrisc.org>
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.
This helps reduce repetition in the CI yaml in preparation for adding
more directed tests.
This is a very basic script and will be replaced by a more complete
system at a later point.
cov_merge.tcl has been patched so the Ibex regression can pass through
coverage directories via a file. However this breaks dvsim based flows,
in particular the icache coverage merge.
This patch checks to see if the file is provided, if not it uses the
original merge method that's compatible with dvsim.
The new instruction stream randomly chooses a NAPOT PMP region and emits
a store or load which will cross the boundary of that region at either
the top or the bottom.
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.
This refactors the code to avoid a -1 index access that caused no issues
in functional verification but caused lint errors and is problematic for
formal tools.
Fixes#1799
Coverpoints for priv modes with interrupts and mstatus.MIE, and with exceptions.
Also, fixed a checker for scenarios when interrupt is taken from lower priv modes.
Signed-off-by: Saad Khalid <saad.khalid@lowrisc.org>
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>
This enables the sequence to corrupt the integrity on write responses
should it choose to. Previously the driver would always produce correct
integrity.
This will prevent seeing mismatches right at the end of our test.
Before this change, mem_error_test could inject error at the store
instruction in which we finish up the test, resulting with mismatches
with Spike and Ibex on the instructions after finishing.
Also do the same prevention for signature_addr as well, since we also
don't want to corrupt that memory transaction too.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
This commit addresses the integrity part of #1759 by verifying that a
glitch on the data or tag response from the instruction cache raises a
minor alert by the core (if the data/tag returned from the cache is used
by the core).
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>
This commit addresses the integrity checking part of #1756 by verifying
that a glitch on the data read from the register file raises a major
alert by the core (if the data read from the register file is used by
the core).
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>
This is necessary because after the upcoming update of `lowrisc_ip`,
`prim_util_pkg` will depend on `INC_ASSERT`, which is defined in
`dv_assert.sv`.
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
The `-access rw` option allows Xcelium to access signals in the design
(e.g., with `uvm_hdl_read` or `uvm_hdl_force`) without having to dump
waves (which substantially increases the run time). See [1] for the
background discussion.
[1]: https://github.com/lowRISC/ibex/pull/1879#issuecomment-1300216022
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
Tidy up merge_cov.py to use metadata / pathlib
The 'imc' tool can accept a list of coverage databases as arguments on the
command line, or a '-runfile' argument can point to a file containing a list of
the databases, one entry per line.
Switch to use the file-method, as too many iterations leads to exceeding the
maximium length of arguments to the shell.
This commit addresses #1755 by verifying that a glitch on the PC of Ibex
raises an internal major alert in the core.
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
This commit adds a directed instruction stream to riscv_pmp_full_random_test
To inject random writes to MSECCFG register.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
Memory errors trigger the same exception as PMP failures. For this test
we simply need to return to the failing instructions rather than the
more complex handling from the PMP exception handler.
Previously there was a single dummy_instr_id_o signal from ibex_core
which the register file used to determine if it could write to the zero
register (which reads as zero always for real instructions). However a
write occurs in the writeback stage so this signal was not asserted
correctly.
This adds a dummy_instr_wb_o signal to control the write to zero
register. dummy_instr_id_o remains as it's still employed for register
reads for dummy instructions.
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.
When DCSR is set such that ebreak will enter debug mode we were getting
cosim mismatches. This was because Ibex produces the ebreak on the RVFI
interface and spike effectively skips right over it and executes the
first instruction of the debug handler immediately. Traps have similar
but not identical behaviour so we need a special case in the step
function to handle this.
The recent change to add the fetch_enable sequence in to every regression
can very-rarely cause the 3000 cycle timeout for the irq_stimulus check to fail.
This only happens with a large randomized length of the fetch being disabled,
and long latency for memory accesses.
Increase this timeout.
Overrides some riscv-dv classes to create a custom debug_rom for this test,
which is used to setup the breakpoint registers.
I have found it difficult to get stimulus of this hardware feature without
a more directed test. Improvements or ideas are welcome here.
Test-specific timeout of 5min within which I see >90% pass rate.
Adding this behaviour to ibex_asm_program_gen allows all test to benefit
from the option of jumping directly to these label. Previously, ECALL was
used to provide a single path to this code.
Previously it was asserted when an instruction in ID would cause an
exception but an earlier instruction in WB also causes an exception
which takes priority.
This didn't cause a functional bug as the `id_exception_o` signal was
used in a single place ORed with `wb_exception_o`. However it was
confusing behaviour and could cause killed instructions to appear on the
RVFI causing false cosim mismatches.
Update code from upstream repository https://github.com/google/riscv-
dv to revision be9c75fe6911504c0e6e9b89dc2a7766e367c500
* Reserve one extra word when pushing GPRs to kernel stack (Harry
Callahan)
* Store user-stack-pointer on kernel stack when pushing/popping GPRs
(Harry Callahan)
Signed-off-by: Harry Callahan <hcallahan@lowrisc.org>
It is illegal to see an execution/read/write denied while in Machine
mode if MML is disabled. Add this combination to our illegal bin list.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
It was triggered only on the debug wakeup actually occurring, so in
particular would never capture debug activity around entering sleep. Now
it just considers if there's something that would trigger debug wakeup.
This cross wasn't much use as many of the transitions it was crossing
with instruction types only occur when the pipeline is empty (so there's
no instruction type to check).
The remaining interesting cases are already covered by other crosses
(e.g. `debug_if_entry_instr_cross` and `pipe_flush_instr_cross`).
Also adds an assertion to check the pipe is empty when we transition to
IRQ_TAKEN (we need this condition to hold to ensure we don't need extra
coverage for instruction types on this transition).
When in the FLUSH state we cannot have `csr_pipe_flush` set as it
depends upon `instr_executing` being set (within `ibex_id_stage`) and
that is only set in the DECODE stage.
Add 180s timeout for pmp_full_random tests (this sees a reasonable pass-rate)
Tweaked to latest api for double_fault detector
Squashed changes from Marno's ongoing work:
[pmp] Adjust full random PMP to use random memory addresses
[pmp] Enable double fault detecter for MML read only test
[dv,pmp] Add double fault pass flag
[dv,pmp] Different parameters for pmp full random test
This coverpoint does not make sense. The hardware breakpoint is
triggered as the instruction moves into the ID/EX stage so it never has
a chance to take an exception (it effectively never begins executing).
We should only indicate an ebreak debug cause if an ebreak leads to a
debug entry (otherwise when single stepping over an ebreak that traps to
an exception we incorrectly enter debug mode with an ebreak cause).
Update code from upstream repository https://github.com/google/riscv-
dv to revision ada58fc57a6bc1265e6c261b0f468a79c946a640
* [pmp] Fix plusarg detection for MML and MMWP (Marno van der Maas)
* [pmp] Add missing line return (Marno van der Maas)
* [pmp] Improve formatting of PMP addresses for debug (Marno van der
Maas)
* [pmp] Add a register for loop counter in PMP traps instead of
mscratch (Marno van der Maas)
* [pmp] Add illegal TOR and NAPOT address mode constraints (Marno van
der Maas)
* [pmp] Try to skip instruction if no PMP match and in MMWP (Marno van
der Maas)
* [pmp] Store and load faults caused by locked PMP regions now skip to
next instruction (Marno van der Maas)
* [pmp] Check for MML before modifying PMP entry in trap handler
(Marno van der Maas)
* [pmp] Allow already configured addresses to be overwritten with
plusargs (Marno van der Maas)
* [pmp] Use kernel_inst_end for end of code entry (Marno van der Maas)
* [pmp] Add end of kernel stack to stack entry (Marno van der Maas)
* [pmp] Put signature and stack in last PMP entries (Marno van der
Maas)
Signed-off-by: Harry Callahan <hcallahan@lowrisc.org>
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>
Previously if a dummy instruction entered the pipeline whilst it
wouldn't make RVFI stage 0 valid, it would make RVFI stage 1 valid.
Now stage 1 can only become valid if stage 0 was valid.
Use a DPI call to unix 'date' to implement a wall-clock timeout entirely within
a simulation. This allows the UVM environment to gracefully end when the
threshold is reached, and for things like logs and coverage databases to be
generated correctly.
Previously, a process-level timeout was used, which gave the running simulation
no time to commit any logs/databases to disk before ending. Hence we would not
gather any coverage from timed-out tests.
A plusarg 'test_timeout_s' can be specified to each test to set the timeout. The
default timeout is 1800s.
Adding the key 'timeout_s' to the testlist.yaml file for each test
now sets the timeout for all iterations of that test. Value in seconds.
e.g.
Set all iterations of the pmp_full_random test to have a 10s timeout.
```
- test: riscv_pmp_full_random_test
timeout_s: 10
```
Give the sequence a handle to the cosim_agent, upon which it can call a method
to update the cosim memory model directly.
This required a small restructure of the mem_intf packages to prevent a circular dependency.
Reading uninit DMEM returns a random value.
Reading uninit IMEM returns returns {2{C.unimp}}.
Inserting intg errors upon uninit accesses is now gated with a plusarg
"+enable_bad_intg_on_uninit_access=1"
Fix missing update of the rtl mem_model when returning random data.
Update code from upstream repository https://github.com/google/riscv-
dv to revision e0eae9e0ca69770c519c82c48421005f65521eac
* [sv] Explicit type casting for VCS compability (Canberk Topal)
Signed-off-by: Canberk Topal <ctopal@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.
Previously the time over which fetch enable was disabled was randomized
at the start of the sequence and kept constant throught. Now it is
randomized for every `send_req`.
Stop generating FetchEnableOn as a possible fetch_enable value to set
and use the SecureIbex parameter to decide if full randomisation off all
of the non FetchEnableOn MUBI values if needed or we just always switch
between FetchEnableOn/FetchEnableOff
Tweaks the default min/max delay values for how long fetch remains
disabled.
Previously `fetch_enable_i` only controlled the request going into the
instruction fetch stage. Due to buffering in the prefetch queue and
icache when this request is dropped it's possible for multiple
instructions to still be available for the ID/EX stage to consume. So
when `fetch_enable_i` was set to off you would get a 'soft stop'. Some
finite number of instructions may still execute and Ibex would come to
an eventual halt.
Now `fetch_enable_i` also gates the instruction moving between the fetch
stage and the ID/EX stage. This gives a 'hard stop' where once fetch is
disabled Ibex comes to an immediate halt.
This commit changes when we cath the debug causes. Since debug_cause_o
only gets latched when `csr_save_cause_o` is high, it would work if
we change the cause with a mux that is connected to the input signals.
Resolves#1772
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
Previously Ibex signalled a major alert on an integrity error (where
incoming read data doesn't match its integrity bits) for both read and
write responses. This was removed as the data part of a response to a
write is ignored.
This brings it back in a more measured way. This provides a little extra
fault injection hardening as an attacker glitching the memory bus will
generate an alert on both read and write responses.
This test doesn't actually check the performance counters, it just runs
a random instruction test and dumps the performance counters at the end
for some final checking. That checking does not exist. The test is
currently broken as well so just remove it as it adds nothing to the
regression.
Update code from upstream repository https://github.com/google/riscv-
dv to revision c6acc1897429f5245cc89b2ecee2e3eefdefd18d
* Add plusarg to enable ECALL insn in main randomized body (Harry
Callahan)
Signed-off-by: Harry Callahan <hcallahan@lowrisc.org>
This commit adds another field in SpikeCosim class so that Spike
can hardcode the correct event registers.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
Previously it was sourced from the OpenSUSE build service. This has
produced some reliability issues. Downloading pre-built binaries from a
GCP bucket should improve things.
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.
This builds upon the cosimulation environment to allow us to rip-out all the
existing checking from the test, and instead focus on generating good stimulus
to hit all our coverage points.
Make use of the riscv-dv changes to insert ecall into the main test body, now
that we have a different mechanism for ending the test.
Allow illegal instructions, csr instructions, ebreak, etc. which the previous
brittle checking paradigms could not handle.
This commit adds a new field to the trr (test-run-result) structured data
that records the failure_mode of a testcase. If the test failed due to a
timeout, print a small addendum {T} to each log-line in the summary.
eg.
23.33% PASS 7 PASSED, 23 FAILED
riscv_debug_basic_test.21259: PASS
riscv_debug_basic_test.21260: FAILED {T}
riscv_debug_basic_test.21261: PASS
riscv_debug_basic_test.21262: FAILED {T}
riscv_debug_basic_test.21263: FAILED {T}
riscv_debug_instr_test.21259: FAILED {T}
riscv_debug_instr_test.21260: FAILED {T}
riscv_debug_instr_test.21261: FAILED {T}
riscv_debug_instr_test.21262: PASS
riscv_debug_instr_test.21263: FAILED {T}
riscv_dret_test.21259: FAILED
riscv_dret_test.21260: FAILED
riscv_dret_test.21261: FAILED {T}
Observing the spec change:
RISC-V Debug Support Version 1.0.0-STABLE
1.2.1.4 New Features from 0.13 to 1.0
> 8. Move scontext, renaming original to mscontext, and create hcontext. #535
MSCONTEXT is a backwards-compatible alias to SCONTEXT
In Ibex, SCONTEXT is a read-only zero register. Hence MSCONTEXT has the same behaviour.
Previously it had two packed dimensions. In general we prefer the use of
unpacked arrays for this kind of usage. In particular this had an impact
on trace viewing in GTKWave, the two dimensions were flattened into a
single large bus which made determining individual register values
tricky.
core_ibex_directed_test has a 'disable fork' that was killing processes
that were running sequences. Another part of the testbench waits for
those sequences to finish. When this 'disable fork' happens too early
the sequences are killed before they finish so the testbench never
terminated and times out. Instead ensure the sequences have finished
before doing the 'disable fork'.
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.
Referring to specific parts of a specific version of the specification
can be brittle as all of these references need to be updated when we
shift specification versions. It's also redundant it should be generally
understood Ibex implements the RISC-V specifications and many lines
could have comments that point to the part of the specification they are
implementing. Rather than having a few of these for no particular reason
easier to just remove them all.
This is specification change between the v1.11 and v1.12 privileged
architectures. Previously mprv wasn't altered on mret. Now if returning
to a privilege level other than M mode mprv must be cleared.
This adds the following CSRs to support the v1.12 priviledged spec.
- MSTATUSH
- MCONFIGPTR
- MENVCFG
- MENVCFGH
MCONFIGPTR is read only and has its value provided by a ibex_pkg
parameter CSR_MCONFIGPTR_VALUE which is set to 0. Implementors can alter
this value if needed.
All the other CSRs ignore writes and read as 0.
RISCV-DV by default sets up some PMP regions. This leads to PMP failures
within riscv_mem_error_test which it isn't expecting. Suppress the PMP
setup to prevent this issue.
Spike has a hack that decrements mcycle/minstret when written.
Previously this was not handled correctly by cosim. As we can only write
32 bits at a time two writes must be used and incremented to counteract
the decrementing handled carefully.
The prior system of using a patch to alter the riscv_dv_setting.sv file
has been removed and replaced with a mako templating based approach.
Fixes#1787
- Increase iterations to 20 because double faults are less likely.
- Remove restriction on MPRV randomization.
Signed-off-by: Marno van der Maas <mvdmaas+git@lowrisc.org>
Update code from upstream repository https://github.com/google/riscv-
dv to revision 68e3bcac7293ac79067f0d8196bb973bd7c889cf
* [pmp] Remove restriction on using NAPOT when granularity = 0 (Marno
van der Maas)
* [pmp] Add PMP entries for data in case of MML or MMWP (Marno van der
Maas)
* [pmp] Add already_configured flag to skip address in PMP routine
(Marno van der Maas)
* [pmp] Fix constraint and CSR write test in MML mode (Marno van der
Maas)
* [pmp] Use random address instead of offset for full random test
(Marno van der Maas)
* [pmp] Allow specifying address zero in `+pmp_region_%0d` (Marno van
der Maas)
* [pmp] Randomizing entry for instructions for PMP randomization
(Marno van der Maas)
* [lint] Remove trailing whitespace (Marno van der Maas)
* Tweak CSR constraints for more even read/write distribution (Greg
Chadwick)
* [lint] Replace tabs with spaces (Marno van der Maas)
* [pmp] No PMP exception handler when no PMP support (Greg Chadwick)
* Expand CSR instruction constraint functionality (Greg Chadwick)
* Refactor CSR instruction into their own class (Greg Chadwick)
Signed-off-by: Marno van der Maas <mvdmaas+git@lowrisc.org>
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.
As well as completely removing the existing non-cosim flow, this commit
significantly refactors the build system to be less reliant on the makefile.
While we still use the Makefile, it is relegated to only providing scheduling
and dependency calculations between the different build steps.
This is possible by moving all of the build metadata into a file on-disk, which
is populated at the start of a new regression, then read and written to by the
different scripts executing the build. Each build step only needs to be passed
the location of this metadata at the top-level, and it can then import all
the information it requires to calculate and perform the next build stage.
This allows better observability into the build, as it is trivial to add new
data to this file, which is also provided as a human-readable yaml version.
It should also allow easier integration into different build systems, as the
dependency on Make is much weaker.
The file metadata.py and test_run_result.py contain the definitions for
these metadata objects. metadata.py defines an object for the whole
regression, while test_run_result.py defines objects for each individual test
performed.
The file riscvdv_interface.py has been created to better isolate the interface
with that project.
The file setup_imports.py has been created to centralize the importing of
python modules from other projects (riscvdv/ot_lowrisc_ip etc.).
Existing python code has been tidied to better conform to PEP8 standard
formatting, and to be more python in general such as using pathlib.Path.
We're seeing many timeouts in this test. This is causing issues for the
nightly regression. Keep the test in so we're aware of any major issues
with it but with far fewer timeouts to help keep the regression healthy.
We'll revisit the required iterations once we've sorted out the issues
with the test.
This refactors the invalidation control logic into an explicit state
machine. The top-level icache_invalid_o signal is also removed.
Replaced with an explicit scramble key request instead.
This has all been done to better deal with corner cases around a new
invalidation being requested whilst another is still going on.
Previously there was a bug wher an invalidation request in the final
cycle of an ongoing invalidation didn't restart the invalidation but did
rotate the scrambling key producing an ECC failure and an alert.
This test is generated differently to all the others, as it exclusively uses a
python script.
The easiest way to make this work with the new test_done signature address is to
detect it as a special case and pass it the new address. The handshaking is only
used for ending the test, so the original address does not matter.
Use the address (signature_addr - 0x4) for a TEST_PASS handshake.
Create new mem_seq_item subscriber port for test_done functionality.
By creating a new, distinct port and subscribing to all incoming memory items,
the existing wait_for_mem_txn() can be used with minor modifications to be
able to choose the port to wait on as an argument to the task.
Because the wait_for_mem_txn() implementation currently uses get() to pop the
latest item from the item_collected queue, having two different forked processes
that both await on this queue is not possible. The simplest solution is to
create a new, seperate port which also subscribes to the sequence_items
broadcast by the mem_if monitor.
Signed-off-by: Harry Callahan <hcallahan@lowrisc.org>
The following changes are made:
- For unimplemented counters corresponding bits in MCOUNTINHIBIT read as
0 not 1
- For MHPMEVENTx we start at x = 3 with the first bit set (0-2
MHPMEVENTx CSRs do not exist)
- When writing an invalid privilege mode to MSTATUS.MPP/DCSR.PRV default
to U rather than M mode.
These new behaviours remain spec compliant and match spike.
Initially the 'B' bit was going to be used to indicate the presence of
the bit-manipulation extension. Now that has been seperated into
multiple smaller extensions the 'B' MISA bit isn't being used and
remains a reserved bit that should read as 0.
For the RV32B configurations where we implement non ratified
bit-manipulation extensions we must set the 'X' bit.
These changes matche the behaviour of spike.
This extends our memory range to be between 0 and
0xFFFF_FFFF. This is needed because in the case of
no match between UVM memory model and spike memory
model, we see a mismatch.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
After vendoring the new changes to the prim IP:
- Reorder `ibex_dv.f` to reflect the dependency on `prim_assert.sv`
- Disable assertion for register file prim onehot check.
Signed-off-by: Marno van der Maas <mvdmaas+git@lowrisc.org>
As Greg pointed out:
When we have an instruction in ID/EX that writes a PMP register that
update gets written to the CSR the same cycle the next instruction
moves from IF to ID/EX with it's PMP check done with the old value.
The solution is to flush the pipeline when we get a PMP CSR write.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
The relevant page [Debug Spec v1.0.0-STABLE, p.53] gives the following
priorities for resolving multiple concurrent reasons for entering debug mode....
DCSR.cause : Explains why Debug Mode was entered.
When there are multiple reasons to enter Debug Mode in a single cycle,
hardware should set cause to the cause with the highest priority.
1: An ebreak instruction was executed. (priority 3)
2: A Trigger Module trigger fired with action=1. (priority 4)
3: The debugger requested entry to Debug Mode using haltreq. (priority 1)
4: The hart single stepped because step was set. (priority 0, lowest)
5: The hart halted directly out of reset due to resethaltreq. (priority 2)
It is also acceptable to report 3 when this happens.
6: The hart halted because it’s part of a halt group. (priority 5, highest)
Harts may report 3 for this cause instead.
Other values are reserved for future use.
Added a patch for riscv_core_setting.sv, which is applied for the small
and experimental-branch-predictor configs.
Signed-off-by: Marno van der Maas <mvdmaas+git@lowrisc.org>
fixup
- Enable epmp in riscv_core_settings.sv
- Bump CI and Spike version in `ci/vars.yml`
- Enable full random PMP test
- Create tests for machine mode lockdown (MML)
- Code execute only, rest read/write
- All regions execute only
- All regions read only
- Create test for machine mode whitelist policy (MMWP)
- Create test for rule lock bypass (RLB)
Signed-off-by: Marno van der Maas <mvdmaas+git@lowrisc.org>
Update code from upstream repository https://github.com/google/riscv-
dv to revision 808fb162d66de5dd0dd2b45fd0b8d1fb1bf170f6
* [scripts] Improve WARL support in gen_csr_test (Greg Chadwick)
* [scripts] Refactor gen_csr_test (Greg Chadwick)
* Allow for WFI in User Mode (Canberk Topal)
* [Smepmp] Fixes `gen_pmp_instr` when MML and MMWP are enabled (Marno
van der Maas)
* Fix typo in mseccfg_reg_t class (aneels3)
* Fixgoogle/riscv-dv#819 (aneels3)
* lib.py, launch process in new session to fix timeout issue (Yannick
Casamatta)
Signed-off-by: Marno van der Maas <mvdmaas+git@lowrisc.org>
This commit sets two different riscv-dv knob to make sure we hit
some holes in our coverpoints.
Activating `enable_timer_irq` for everytime we enable other
interrupts makes sure that we respond to it just like we respond
to other interrupts.
Setting tw=0 makes it so that we would allow WFI in user mode. We
were already randomizing it but for some certain tests, we actually
want to be in a sleep state, which wouldn't happen if tw=0 in user
mode.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
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>
In ePMP spec, it specifies as:
```
Executing code with Machine mode privileges is only possible from memory
regions with a matching Mmode-only rule or a locked Shared-Region rule
with executable privileges. Executing code from a region without a
matching rule or with a matching S/U-mode-only rule is denied.
```
This change provides that.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
This commit makes sure that different IRQs are collected in a single
`fcov_irqs` bus correctly. Also changes nmi_taken coverpoint to catch
interrupt taken case for NMI types from the same bus.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
Some aspects of the memory response are only relevant to reads. This
introduces outstanding request tracking so we know which outstanding
requests are reads and applies X checks appropriately.
Fixes#1645
This commit fixes how we catch an instruction at WB stage. Before this fix
we were effectively checking opcode of decoded instruction instead.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
The riscv_csr_test does not use cosim but was failing due to lack of a
cosim log. This option skips the stage of pass/fail determination that
looks for that log.
This adds a couple of missing fields to cpuctrl and comments out mcause.
mcause will be added back once RISC-V DV has been updated to support
WARL fields properly.
Interrupts are disabled in Debug Mode (Sdext 4.1.2), and simultaneously
registers, including MCAUSE, are not updated by exceptions (Sdext 4.1.3),
so reading MCAUSE[31] after an exception (eg. invalid instruction) in
debug_mode may still report the previous cause (which could be an interrupt).
Seperate concerns so the flow of stepping spike and checking against
the ibex RVFI data is clearer. One 'step' of either system produces
different amounts of progress, and this conditional-checking-and-stepping
is needed to tie up the flows.
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>
We already have a clocking block inside dut_if. This commit uses it
to avoid a race condition that happens when `instr_valid_i` goes high
while `ecall_insn_i` goes low.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
We were not being able to hit the bin because in order to do that
we needed to have a posedge clk when the condition happened. Now,
we are latching the condition to register it after we wake up from
sleep.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
Adds some signal to the load store unit to catch when we have the
fetch error signals from both first and second part of the misaligned
load/store access cases.
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>
Includes coverpoints for:
- Hardware trigger point matches
- Debug simple step entrance in controller
- Seeing different insns while single stepping
Also updates on coverage plan to fill up missing mentions of
coverpoints/crosses
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
- mtval is a bit more useful for double fault situations
as on the second exception we can still "remember" the
data address and PC of the first exception.
Signed-off-by: Timothy Chen <timothytim@google.com>
Update code from upstream repository https://github.com/google/riscv-
dv to revision 0b2b3d65ce8fdff4de8974d1f328a90d6c1db5dd
* [epmp] Add support for mseccfg CSR (Pirmin Vogel)
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
If you call the read() function on the memory model with an
uninitialised word, it generates a UVM error.
This is reasonable for data memory (where we never want to read
something without an architectural value) but is not reasonable for
IMEM, where Ibex runs ahead. Squash the error in this case, but force
bad integrity for the fetch to make sure we see something explode.
Convert `prim_generic_buf` to Verilog as well.
Also, replace 'prim_buf' with 'prim_generic_buf' whenever we see a
`prim_buf` in a generated Verilog file.
Fixes#1557
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
This works with versions ibex-cosim-v0.2 and ibex-cosim-v0.3. The latter
version is required to support the mseccfg CSR added with ePMP.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
This makes use of functions in a way that enables us to use `priv_lvl`
dependent logic in the DV environment.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
I was previously just dumping them to /dev/null because the
code always worked but... predictably I was wrong! Write them
somewhere more useful for debug.
This allows us to model stuff more closely. This depends on Spike
version ibex-cosim-v0.2 (which is rebased onto a master branch commit
supporting these more specific ISA strings).
Don't yet tear out the old logfile-comparision code, add a new path for the
cosim flow.
This uses the existing riscv-dv functions to parse the cosim logfile, as it is
fundamentally still generated by spike so should be checked for errors.
This is a continuation of PR's #1613 and #1575 work.
If cosim in enabled, we need to pass the appropriate flags to the eda tool for
it to link against the precompiled ISS when building the testbench.
This commit assembles the appropriate flags using pkg-config to query the
SPIKE_ISS build, then uses the scripts_lib.subst_vars() method to populate the
templated commands in the yaml.
The eda tools have different requirements for consuming the flags, so massage
them into the appropriate shape on the python side.
Updated the parameters with respect to top_earlgrey.hjson in OpenTitan
repository. For other builds, kept the previously undeclared parameters
as their default values.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
This used to work by dumping a Makefile fragment, reading it back in,
and then passing the relevant options through to the RTL compile and
run scripts.
This commit switches things around so that the RTL compile and run
scripts just look up the options when they need them.
No functional change, but the point is that we can vendor this into
OpenTitan where dvsim can load up the Python library and get something
sensible without having to call a subprocess and mess around with
string parsing.
I don't quite understand why I thought this was needed: perhaps some
holdover from riscv-dv expecting files to be a certain shape? Anyway,
no need to keep it now.
This isn't how riscv-dv wants to work! So we do a rather nasty hack in
run-instr-gen.py and rewrite the paths that come out of riscv-dv on
the fly.
Note that we don't move the instruction generator build vars to
something like $(OUT-DIR)/instr_gen/.build.vars.mk. The problem is
that the dumping of these variables runs as part of evaluating the
rule that builds the instruction generator (before the rule actually
runs). The end result is that you would end up writing them to the
directory and then immediately deleting the directory, causing
spurious rebuilds.
This reverts commit 1f57795: these options are needed for plumbing
Ibex configs through. I've got a follow-up that does this more neatly,
but that depends on some other scripting changes so let's revert the
breakage for now.
This reverts commit 014b544: these options are needed for plumbing
Ibex configs through. I've got a follow-up that does this more neatly,
but that depends on some other scripting changes so let's revert the
breakage for now.
Also, update the copyright notice to be lowRISC: we've rewritten
pretty much the entire file, so I don't think it really makes sense to
describe it as copyright Google any more.
While we're at it, we slightly simplify the plumbing for Xcelium,
which means we don't have to export any Xcelium-specific environment
variables from the Makefile any more.
This kind of existed already, but this tweaks things so that it's the
same shape as the other scripts we're adding and (hopefully) the
Python gets a bit cleaner.
This is a bit of an overlap with the existing sim.log files that we're
creating (which contain slightly more information), but it turns out
that if you don't say anything then you get an xrun.log in the current
working directory.
This functional code coverage section has hierarchical paths, which will
break certain synthesis and lint flows.
Signed-off-by: Michael Schaffner <msf@google.com>
This didn't quite work properly for Xcelium (giving strings with an
embedded space: '-define IBEX_CFG_RV32M=ibex_pkg::RV32MSingleCycle').
It turned out not to matter because we were evaluating one time too
often in the shell, but we're about to stop doing that.
It turns out that there aren't many changes needed, but we need to be
able to point at a prim directory that might not be inside
vendor/lowrisc_ip: put that path in an environment variable and pass
it from core_ibex/Makefile. That way, a caller on the OpenTitan side
can just override the corresponding variable and everything works.
Commit f49f452f2 greatly tidied up the file, which is nice, but also
introduced some whitespace around the first argument to vars-prereq.
In Make, this causes chaos!
In particular, we ended up checking whether a variable called
something like "$(last- gen -vars-loaded)" was defined. It isn't,
but $(last-gen-vars-loaded) is.
Call strip in the vars-prereq function to get rid of the whitespace at
the "entry point" for all this machinery.
This is the first such script, but the idea is that we're going to
move a bunch of logic out of the Makefile and into Python scripts
where things are a bit easier to understand.
This isn't supposed to be something that people update manually.
Remove it from instr-gen-build-var-deps, since it's not something that
should ever change under our feet.
We're not using this and I strongly doubt that it actually works. Drop
the technical debt: we can always put something back in if we need to
in future.
Some commands utilise a logfile argument, while others capture the stdstreams
into a file. Discard the stdout/stderr when a logfile argument is used.
This keeps the logs readable.
This commmit enables parallelism of more steps of the dv process by capturing
the commands generated by the riscv-dv tool, then populating and executing a
sub-makefile. This allows us to have parallelism at the level of the makefile
jobserver.
Seperated instr_gen build and run steps
A python script construct_makefile.py is used to capture the raw output commands
and construct a trivial makefile for each stage.
This commit also renames some of the helper variables and stamps for consistency.
- Every line in a recipe must start with a tab, except wrapping lines of dependencies.
- Wrapping dependencies of a target use only spaces. Use two spaces by default.
Vivado gives synthesis error complaining about assignment of irq_nm_int_cause to '0 by saying it is an enum type.
Change the assignment to NMI_INT_CAUSE_ECC, which is defined to 5'b0 in ibex_pkg.sv
The prefetch buffer and icache both treat the branch_i and
branch_mispredict_i signals identically, so it's a bit cleaner to pull
that treatment up into ibex_if_stage.sv
This commit doesn't change the modules below: it just passes zeros for
the "mispredict" version. Removing those ports will be done in a
follow-up commit.
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.
It turned out that with the default value of 1, Vivado infers a separate
18 Kbit BRAM instance for each bit of the 32-bit word for the FPGA
examples. This can be very wasteful in terms of resource utilization
especially for smaller configurations.
As our examples don't use ECC or parity and mainly target simualation
and FPGA, it's better to use a value of 8 for the DataBitsPerMask
parameter. Vivado will then not distribute words across different BRAM
instances which results in more efficient FPGA resource utilization.
For a detailed analysis and explanation, please refer to
lowRISC/Ibex#1587.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
Update code from upstream repository https://github.com/google/riscv-
dv to revision cb4295f9ce5da2881d7746015a6105adb8f09071
* Update list search (Matthew Ballance)
* Trap and report exceptions encountered in sub-processes and
propagate error back (Matthew Ballance)
* Workaround fix for loop test colon issue (aneels3)
* Fix typo (aneels3)
* Add support for RV64AFD (aneels3)
* Fix typo (aneels3)
* Update README.md (aneels3)
* Add support for sub_programs (aneels3)
* fix issue with imm value for 64 bit instr (aneels3)
* Allow for underscores and capital letters in ISA for ISS (Pirmin
Vogel)
* implement rv64i (shrujal20)
* Add support for RV32FD coverage (aneels3)
* Integrate random seed for pyflow (aneels3)
* Add riscv_loop_test (ShraddhaDevaiya)
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
This is necessary for having VCS support with simple system example.
Because in the ibex_simple_system_main.cc we are including some
Verilator exclusive header files.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
This commit adds ibex_icache_ram_if to connect between DUT and tag /
data RAMs.
This interface injects 1 or 2 bit error on rdata if enable_ecc_errors
bit is set. It also checks that ecc_err_o pin is asserted by DUT
whenever an ecc error is injected.
ibex_icache_ecc_vseq and ibex_icache_base_vseq have been modified to
inject ecc errors through the ram interface.
Fixes a bug where both Xcelium and Python open the same sim.log file and race to
write the simulation results into it. This change makes Python the sole writer of this
file using the captured stdout/stderr from the subprocess.run call in
run_rtl.py.
This bug was also previously present for VCS but was fixed in 90ff7ca6c.
Added coverpoint and cross names to relevant plan entries so plan is up
to date with implemented coverage. Also some minor changes to remove
plan entries that are no longer required.
This groups the various different illegal instructions categories within
ibex_id_stage rather than spreading them between ibex_id_stage and
ibex_controller.
This commit removes extra hierarchy of ic_top inside icache TB and moves
the scrambling request generation logic and instantiation of data and
tag RAMs to tb.
This commit adds a new scrambling agent to drive scrambling key and
valid to the data and tag memory interfaces.
Update lowrisc_ip to lowRISC/opentitan@7c4f8b3fd
Update code from upstream repository
https://github.com/lowRISC/opentitan to revision
7c4f8b3fde4bb625ac3330ff52d3f66507190fe5
Signed-off-by: Prajwala Puttappa <prajwalaputtappa@lowrisc.org>
Earlier the design supported single clock cycle error responses from PMP
block whenever a read was done from blocked memory. Now there is at
least one clock cycle delay after the request has been granted for the
error to be asserted. Therefore, this commit removes the support for
single clock cycle PMP error response.
Update code from upstream repository
https://github.com/lowRISC/opentitan to revision
7c4f8b3fde4bb625ac3330ff52d3f66507190fe5
Please note that we're adding push_pull_agent for the first time in this
commit.
Signed-off-by: Prajwala Puttappa <prajwalaputtappa@lowrisc.org>
There was issue with rtespect to calculating number of instructions per
word and this commit fixes that issue.
Number of instructions per word = 1/4*1 + 3/4(1/4*3/2 + 3/4*2) = 53/32.
Earlier th5s was calculated as 7/4.
Ideal window length needed to calculate fetch ratio percentage is
calculated as 53/32*C*2 = 848. Earlier it was calculated to be 300.
Previously integrity checks for incoming memory reads and integrity
generation for outgoing memory writes were handled within ibex_lockstep
and weren't duplicated.
This moves the integrity checks and generation into the core so they are
replicated and checked as part of the lockstep mechanism.
Additionally it generates a bus error on any memory integrity check
failure. This will result in Ibex taking an exception if any data read
or instruction fetch has bad integrity.
Ibex has a top-level `fetch_enable_i` input. When set to on (noting it's a multi-bit signal for
security hardening though only the bottom bit is looked at for non secure ibex) Ibex executes
normally. When set to off Ibex will stop executing. Randomly toggling it should have no functional
effect on Ibex's behaviour.
The fetch enable sequence will randomly toggle the value of `fetch_enable_i` with a configurable
bias between the 'On' value and all other values.
This commit adds functionalty to the memory response agent to make delays more
configurable.
There are two delays
- Delay between req and gnt
- Delay between gnt and rvalid
For each of these delays we have three modes:
* Fully random delay
* Fixed delay
* Biased delay. Randomised delays but allow biasing towards 0 delay, to give a mix of runs with back
to back transfers with no delay and some with delays.
Signed-off-by: Prajwala Puttappa <prajwalaputtappa@lowrisc.org>
Added an independent base test with following capabilities:
* chooses between single run, multiples runs or infinite runs (existing sequence
does this via the `num_of_interations` variable).
* interval between runs can be fixed or random, with 0 delay between runs possible.
For random intervals there should be a way to bias them more towards 0 delay
(e.g. specify 75% of delays should 0 with the rest randomly chosen).
Added an interrupt sequence that inherits from the above base sequence.
It has following capabilities:
* chooses the number of interrupts to raise
* specifies the interval between interrupt being raised and dropped
* a mask to specify interrupts that shouldn't be raised.
Added a debug sequence with the only functionality to specify the interval between
the debug request being raised and dropped
Added a sequence to corrupt instruction and data memory.
Signed-off-by: Prajwala Puttappa <prajwalaputtappa@lowrisc.org>
This is triggered by the fact that if the ICache parameter is false
then we don't instantiate the ibex_icache module. For verilator
simulations, the module is then discarded entirely, which means that
its two DPI functions are not defined. That's unfortunate because
we're also compiling the code in scrambled_ecc32_mem_area.cc, which
expects the functions to be defined.
The obvious solution (don't include scrambled_ecc32_mem_area.cc if you
don't have an icache) isn't easy to do, because FuseSoc doesn't
currently allow us to use parameters to configure its dependency
tree (see fusesoc issue 438 for a discussion).
The super-clever solution that I came up with before(!) was to declare
these symbols as weak in the C++ code. That way, we can do a runtime
check to make sure that no-one is silly enough to call them without an
icache, but everything will still build properly either way.
Unfortunately, that doesn't work well with xcelium simulations.
Xcelium turns out to compile all the C++ code into one .so library and
generate functions for exported DPI functions in another. These two
solibs then get loaded at runtime with dlopen(). But this doesn't work
with weak symbols: in fact, it seems you end up with the C++ version
every time. Boo!
So let's be stupider about it and define (bogus) versions of the DPI
functions in this case. Fortunately, both of them are designed to
return zero on failure so we can just return zero and needn't worry
too much.
The idea is that when this lands, we can revert the OpenTitan change
that switched the C++ code to using weak symbols and Xcelium
simulations will start working.
Defining agent configuration for any agent is a standard UVM flow and is
a cleaner flow for defining delay between driving sequence items,
passing virtual interface etc.
Agent configuration has been added to the existing agent to make delay
configuration more flexible in the future.
Signed-off-by: Prajwala Puttappa <prajwalaputtappa@lowrisc.org>
When the icache is enabled and data independent timing is required
variable fetch latency due to cache hit or miss may introduce
undesirable timing behaviour. This adds explicit mention of this to the
documentation.
A sufficiently agressive optimiser may optimise these away as under
normal functioning they effectively don't do anything. They are purely
to detect the presence of induced faults.
We're going to want to make a couple more releases of Spike, cleaving
a bit closer to the upstream repository. Let's be explicit about which
version people should get.
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.
We can now point at a single version of Spike (the "ibex_cosim"
branch, until we've managed to upstream things properly). And ditch
the OVPsim stuff: that's not going to be supported again any time
soon.
This will only have an effect on our private CI, which picks up this
spike build from the toolnas. The build is the ibex_cosim branch,
which contains the stuff we need for the recent cosim support. It's
also new enough to support the v1.0+0.93 bitmanip flavour that we
support in the RTL.
This commit includes switching to a scrambling RAM primitive for
ICache data and tag RAMs. Also introduces minor changes to ICache
to handle scrambling key valid signal.
It also includes a minor bug fix regarding not initializing
`fill_way_q` signal without ResetAll parameter. When the parameter
is not set and we have our first hit right after ICache enables,
the signal hangs.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
RV32BOTEarlGrey selects the Zba, Zbb, Zbc, Zbs sub-extensions from
v.1.0.0 of the bitmanip spec and the Zbf, Zbp, Zbr, Zbt sub-extensions
from draft v.0.93. Zbe (bcompress/bdecompress) is supported by RV32BFull
only.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
- 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>
The icache uses a single bit to signify an error. This could either be a
PMP error or a fetch error. Add extra probing so the testbench can
differentiate between the two cases.
Update code from upstream repository https://github.com/google/riscv-
dv to revision 605301400555c235564f9336cc5fc220af7e951c
* [style] Break long lines in newly added files (Michael Schaffner)
Signed-off-by: Michael Schaffner <msf@google.com>
This invovles the following changes:
- Rename pcnt to cpop
- Switch encoding of max and minu
- Remove rev from Balanced version, only available in Full version via
grev (Zbp)
- Include sext.b/h (previously in Zb_tmp)
- Remove slo[i] and sro[i] from Balanced version, only available in Full
version (Zbp)
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
This change is related to the bitmanip draft version 0.94. It's needed
as in draft version 0.93 as well as in version 1.00 sbext from Zbs
changes to bext, leading to two completely different instructions having
the same name.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
Update code from upstream repository
https://github.com/lowRISC/opentitan to revision
34ba5e45f9af7d8ca6c9bdae8bd11eeeeb669d6c
* [dv] Add new ECC code options to mem_bkdr_util (Michael Schaffner)
* [secded_gen] Define and generate inverted ECC enc/dec modules
(Michael Schaffner)
* [dv] Only run registers through one csr_rw sequence at once (Rupert
Swarbrick)
* [alert_handler] Minor lint fix (Michael Schaffner)
* [prim_clock_div] Fix minor Verilator lint warning (Michael
Schaffner)
* [dvsim/lint] Make message reporting more flexible (Michael
Schaffner)
* [lint] Unify lint parser scripts (Michael Schaffner)
* [rom_cntrl, dv] Test to verify successful rom check (Prajwala
Puttappa)
* [dv, dv_macros] Enhance `DV_GET_ENUM_PLUSARG` macro (Srikrishna
Iyer)
* [sram/dv] Fix mem data check (Weicai Yang)
* [prim] Add flop wrapper for sparse fsm (Timothy Chen)
* [flash_ctrl] Make data / metadata memories a single entry (Timothy
Chen)
* [dv] Teach encrypt/decrypt_sram_data to support OTBN (Rupert
Swarbrick)
Signed-off-by: Michael Schaffner <msf@google.com>
Add support for the Zba extension added in v0.93 of the bit manipulation
specification (unchanged in v1.0.0). The new instructions added are:
- sh1add: rd = (rs1 << 1) + rs2
- sh2add: rd = (rs1 << 2) + rs2
- sh3add: rd = (rs1 << 3) + rs2
The instructions are single cycle and have been implemented using the
adder in the ALU.
Signed-off-by: Michael Munday <mike.munday@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.
Newer versions of sv2v carry through elaboration system tasks like
$fatal. ibex_top_tracing uses $fatal, but isn't actually used in the
syn_yosys flow. By using -defer, unused modules like ibex_top_tracing
are not elaborated in Yosys.
When the writeback stage is present the retired instruction counter
(minstret) and the retired compressed instruction counter could see an
off by one error when an instruction was in the writeback stage when
reading the counters. With this fix the ID stage observes the
incremented value of the counters when an instruction that would
increment them is in writeback.
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.
Previously the monitor would emit write transactions the cycle the
request is seen and emit read transactions the cycle the response is
seen. This allowed later write transactions to be emitted before earlier
reads (where a new write transaction is started the cycle a read
response returns).
Now both read and write transactions are emitted when their response is
seen.
In addition the error field from the response is copied into the
transaction.
Extra bits are added alongside read/write data for the instruction and
data buses to facilitate data integrity checking.
Ibex testbench extended to generate the expected bits.
All other top-levels modified to add the new signals (which are mostly
ignored).
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
Previously the raw incremented address was used which is the calculated
address + 4. This is confusing as it refers to a byte that wouldn't be
accessed (e.g. a lw at 0x8000009e which faults on the access to
0x8000000a0, would report an mtval of 0x8000000a2). With this change
mtval will refer to the first byte on the other half of the word
boundary the unaligned access crosses.
Random constants are sent through the hierarchy as parameters in-line
with other OpenTitan modules.
Further detail on this mechanism can be found in lowrisc/opentitan#2229
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
mseccfg and mseccfgh have changed their addresses. This updates to the
newly allocated values.
The ePMP specification is now available as a versioned PDF,
documentation is updated to point to that removing the local PDF copy.
This commit adds power analysis scripts to the Arty A7
example design. They can be used by setting the newly
added `FPGAPowerAnalysis` parameter to 1.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
1-Port RAM is removed because of both execution and performance
issues. CLKIN1_PERIOD parameter is defined in clkgen module
for Vivado simulations.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
This commit updates link.ld RAM length to include max BRAM capacity
for Arty A7-35. It also changes coremark makefile to include a .vmem
output, which then can be used for FPGA implementations.
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
A minor change to use the Width parameter of prim_buf. No functional
impact but stops the hierarchy from being cluttered with hundreds of
generate contexts in the top level.
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This parameter forces a reset of all registers inside the core. This is
required to guarantee a common starting point for lockstep and thus
prevent spurious lockstep failure alerts.
Another minor change in this commit rearranges the writeback stage
multiplexing to gate incoming lsu write data when not valid. This stops
any X values from the data bus propagating to the register file
signalling (and thus to the lockstep comparison) which would cause the
lockstep alert to be X. It has the side effect of possibly reducing
power consumption in the register file.
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This invocation would break:
make -C examples/sw/led/ CC=/opt/lowrisc-toolchain-gcc-rv32imc-20210412-1/bin/riscv32-unknown-elf-gcc
because the "-gcc" occurence inside the directory name would also be replaced.
Fix by first deriving CROSS_COMPILE from CC, then conditionally build other tool file names/paths.
Signed-off-by: Leon Woestenberg <leon@sidebranch.com>
We're already redirecting stdout to sim.log in run_rtl.py. Specifying
'-l' as well meant that VCS opened sim.log in a separate FD.
Suprisingly enough, this mostly worked, but not always! Just write
once :-)
This commits adds a yaml based intermediate format for test results.
compare.py serialises a TestRunResult (a named tuple type) into this
format for each test run it checks. collect_results.py reads them all
back in to produce reports.
Three reports are output:
- regr.log - plain text report much like the one previously produced
- regr_junit.xml, regr_junit_merged.xml - JUnit report format, the
_merged version batches together multiple tests to appear to be a
single test case under a test suite. This gives better results with
Azure's JUnit reporting.
This signal used to be a one shot enable out of reset. We need an option
to pause execution for OpenTitan, so fetch_enable is extended to cover
that.
The signal is already driven low by the testbench at the end of test.
This is moved after the performance counter reads to ensure they can
complete.
Fixes#1105
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
Fix the reset polarity in the irq driver (clears irq signals to zero
on reset rather than them being x) plus remove an unused signal.
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
The test loops around waiting for the core to sleep then sending
interrupts to wake it. In some cases, the sequence sends an interrupt
that isn't enabled. It never gets back to try again with a new interrupt
since the test is waiting to see wfi first. This change removes that
requirement since it is redundant anyway (have to see wfi to sleep).
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
Commit 700f29b changed things so that details of the various tests
that ran ended up in separate files. This is nice (and important for
running things in parallel), but isn't massively helpful if you use
regr.log to understand what happened from a CI run!
This patch adds the logs again, splitting them up so that failing
tests come before passing ones (since you usually just care about the
failures).
This allows run.py to pass ISA options through to Spike. This relates to
the failure in #1369 (test inserts a bitmanip instruction which Spike
interprets as valid but the core treats as invalid depending on config).
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
The CSR tests don't currently support multiple configurations
(see #1333). Since the OpenTitan configuration is the only one currently
being run, update this file to pass with that for now.
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
With data-independent timing enabled and BranchTargetALU configured,
branches will stall for a cycle causing an illegal value to be decoded
for the B Operand. No functional impact of this, but an assertion fires
so we might as well tie it off properly.
Fixes#1367
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
In tests with multiple resets, these signals could hold onto spurious
values through reset (since the clock is also gated) which caused
assertion failures on resumption.
Fixes#1368
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This patch teaches Make which tests we're actually running (via the
list_tests.py script), which means that we can compare the ISS and RTL
results in parallel rather than serially.
There's a bit of duplicated code (both list_tests.py and sim.py
currently contain the code to get a list of tests and then filter by
Ibex configuration), but this should go away with a later patch that
runs the RTL simulations in parallel in a similar way.
Note: This might seem a little silly: trace comparison takes way less
time than the RTL simulation! The point is that it's probably easier
to work "from the bottom" than to start by parallelising the
simulations themselves.
This makes path calculations a bit easier when it comes to loading
stuff up for comparison (allowing us to move more into the Makefile).
Long-term, it might also allow us to change how we track things
entirely, getting rid of the start-seed part of the output directory
structure.
The prim_buf.sv file in Ibex is a manual copy of a file which is
typically auto-generated by FuseSoC/primgen. However, Ibex DV doesn't
yet run FuseSoC, and we provide a pregenerated copy instead. The
auto-generated file and its copy got out of sync. Fix that by adding the
new Width parameter.
These changes match newer versions of Riviera. They work for all
versions >= 2020.04. Ibex itself only compiles successfully with
version 2021.04, so there's no need to maintain command-line
compatibility with older versions.
This adds the configuration instantiated in Opentitan and adds
missing prim support to allow the TB to run that configuration.
Resolves#1362
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
Certain synthesis tools like DC are very smart at optimizing away redundant logic.
Hence, we have to insert an optimization barrier at the IOs of the lockstep Ibex.
This is achieved by manually buffering each bit using prim_buf.
Our Xilinx and DC synthesis flows make sure that these buffers cannot be optimized
away using keep attributes (Vivado) and size_only constraints (DC).
Signed-off-by: Michael Schaffner <msf@google.com>
The value of `misa` will change depending on whether M or B are enabled.
The presence and read values of other CSRs may also depend upon the Ibex
configuration. A fix is required to allow riscv_csr_test to deal with
different CSR descriptions for different Ibex configurations. For now
just comment out `misa` from the descriptions file to enable
riscv_csr_test to run on a wider range of configurations.
1. Missing prim_assert in ibex_top.sv (more of an rtl bug but only found
in running synthesis scripts)
2. Write out the pre-mapped netlist before mapping latches
Relates to #1335
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
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.
The read enables should only be asserted where an actual RF read will
occur. Where there is an illegal instruction or a fetch error the raw
decoder signals might still be asserted but should be squashed before
they become the true enable signals.
csr_op_en_i signals whether or not the CSR access will actually happen,
but whether an illegal write is being can be determined with just the
address and access type. This change will improve timing and avoid
circular logic that might occur from the use of the illegal_csr_write
signal.
When the simulator terminates with an error code that is reported as a
test failure and the regression continues. A new check for a plain
'Error' message is required to catch simulator reported errors that
don't become a UVM_FATAL or UVM_ERROR message (e.g. hitting an illegal
coverage bin). Previously any such simulation error would kill the whole
regression.
Note that the alert output is tied off for now until an option is added
to reset all registers (otherwise there will be X propagation).
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This commit creates a new top level wrapping the core, register file and
icache RAMs. The tracing top level is also renamed to ibex_top_tracing
to match. This new top level is intended to enable a dual core lockstep
implementation of Ibex.
There are no functional changes in this commit, only wiring.
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
No functional change. These parameters are effectively fixed. Moving
them to the pkg eases top-level wiring of RAM signals.
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This signal is used to gate several assertions related to
unknown/invalid selector signals. We want to be sure to catch any X
values entering the compressed decoder and ultimately ID.
This is related to lowRISC/Ibex#540.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
This comes from OpenTitan and can't currently be vendored in
properly (because it doesn't live in its own directory). We'll sort
that out eventually but, for now, copy in some recent changes by hand.
Update code from upstream repository
https://github.com/lowRISC/opentitan to revision
f29a0f7a7115e03fba734b1c00691c253aceb07e. The list of OpenTitan
changes that are merged in appears at the bottom of the commit.
There are some manual changes needed to adapt the code to work with
these changes.
- The ICache monitors need some extra types to adapt to the (rather
odd) data model that the OpenTitan dv_lib code now uses, where a
monitor needs to know an agent's associated sequence type.
- Verilator simulations now use MemArea slightly differently
OpenTitan changes:
* [dv] Allow monitor items to have different types from sequence items
(Rupert Swarbrick)
* [dvsim] Fix primary_cfg handling (Srikrishna Iyer)
* [dvsim] Deal with non unicode chars in log files (Srikrishna Iyer)
* [dvsim] Added common build fail patterns (Srikrishna Iyer)
* [dvsim] Minot cleanup to the lint flow (Srikrishna Iyer)
* [dvsim] Minor cleanups to to formal flow (Srikrishna Iyer)
* [dvsim] Fixes to UNR and cov analysis flows (Srikrishna Iyer)
* [dvsim] Very minor cleanup of Deploy class (Srikrishna Iyer)
* [dvsim] LsfLauncher report early errors as F (Srikrishna Iyer)
* [dvsim] Minor fix in clean_odirs function (Srikrishna Iyer)
* [chip dv] Set +sw_images as comma-separated list (Srikrishna Iyer)
* [flash_ctrl] Split tl intefaces for flash_ctrl and prim_flash_cfg
(Timothy Chen)
* [keymgr] Fix input value checks (Timothy Chen)
* [formal/script] Update generic formal flow naming from `fpv` to
`formal` (Cindy Chen)
* [top, prim] Address wmask and data width mismatch issue (Timothy
Chen)
* [dvsim] Add GUI mode for running simulations (Srikrishna Iyer)
* [dv] Fix reg backdoor (Weicai Yang)
* [dpi] Make an "ECC32" flavour of MemArea (Rupert Swarbrick)
* [uvmdvgen] Fix has_interrupts in env_cfg (Cindy Chen)
* [dvsim] Keep dependencies list (Srikrishna Iyer)
* [prim_prince] Reverse the k0||k1 mapping to match with the paper
(Michael Schaffner)
* [dvsim] Fix printing of last 10 lines (Srikrishna Iyer)
* [primgen] Minor fix to enable types with underscores (Michael
Schaffner)
* [dvsim] Prevent command echo suppression (Srikrishna Iyer)
* [dvsim] Spot fixes for LSF and internal launcher (Srikrishna Iyer)
* [sva] csr assertion dependency update (Cindy Chen)
* [memutil] Change DpiMemUtil so that it no longer owns MemAreas
(Rupert Swarbrick)
* [memutil] Factor out MemArea as a class (Rupert Swarbrick)
* [prim] Split out PRESENT and PRINCE support from prim:all (Rupert
Swarbrick)
* [fpv/otp_ctrl] Disable assertions due to lc_esc_en (Cindy Chen)
* [prim_prince] Annotate some arrays to avoid UNOPTFLAT warnings
(Rupert Swarbrick)
* [top] Hook up latest ast ports and complete a few other integration
(Timothy Chen)
* Eliminate `#pragma once` in favor of include guards (Chris Frantz)
* [sw,dv] Update headers to pass fix_include_guards.py (Alex Bradbury)
* [xbar/dv] Fix assertion error due to short reset (Weicai Yang)
* [sram] Add memory initialization (Timothy Chen)
* [uvmdvgen] Update links in checklist template (Philipp Wagner)
* [dv/uvmdvgen] Add comment for testplan (Cindy Chen)
* [dv/top_earlgrey] chip csr_aliasing timeout (Cindy Chen)
* [dvsim] Cosmetic updates to launcher methods (Srikrishna Iyer)
* [dv] Update csr_wr to support field write (Weicai Yang)
* [dv/common] Fix regression warnings (Cindy Chen)
* [dv] Get blocks with multiple device interfaces working with chip DV
(Rupert Swarbrick)
* [doc] Use relative links in Hjson-related shortcodes (Philipp
Wagner)
* [dvsim] minor enhancement to clean_odir (Srikrishna Iyer)
* [dvsim] Statically display jobs' status (Srikrishna Iyer)
* [dvsim] Do weighted scheduling of jobs (Srikrishna Iyer)
* [dvsim] Schedule jobs by dependency (Srikrishna Iyer)
* [dv] Xcelium UNR typo (Srikrishna Iyer)
* [dvsim] Implement LsfLauncher (Srikrishna Iyer)
* [dv/chip] solve same_csr_outstanding_timeout (Cindy Chen)
* [dv] make dv_base_agent work for high-level agent (Weicai Yang)
* [tools/dv] added UNR flow for xcelium (Rasmus Madsen)
* [prim] Split prim:subreg out of prim:all (Rupert Swarbrick)
* [prim] Split prim_alert_* out of prim:all (Rupert Swarbrick)
* [prim] Split out fifos into a prim_fifo core (Rupert Swarbrick)
* [prim] Split out arbiters into a prim_arbiter core (Rupert
Swarbrick)
* [prim] Make prim:flop_2sync depend on prim:flop (Rupert Swarbrick)
Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
`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 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.
this test is arbitrarily failing in regressions on a Spike timeout,
temporarily remove this to avoid blocking.
@udinator to fix this in the near future.
Signed-off-by: Udi Jonnalagadda <udij@google.com>
Changes the ECC granularity in the data RAMs from 64bit to 32bit. This
is to align with an upcoming change in bus ECC. Relates to
lowRISC/opentitan#5450
Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This PR adds functionality to filter out tests during regressions for a
particular config.
e.g. if a full regression is kicked off using the `small` config, we
don't want to attempt to run any PMP and bitmanip tests as the RTL
parameter-set will not support it.
To do this, a new YAML field called `rtl_params` is added to relevant
test entries, to indicate what parameters (if any) are required to be
able to run the particular test, along with the required value of said
parameters.
`sim.py` will then parse this field (if it exists), and using
information from `ibex_configs.yaml` pertaining to the current config,
will remove tests from being run on-the-fly.
This also gives us the convenient side effect of not having to re-run
instruction generation if there is a parameter/config mismatch, we can
just rerun the RTL compilation and simulation stages safely.
Signed-off-by: Udi Jonnalagadda <udij@google.com>
This commit adds the MCOUNTEREN CSR as required by the RISC-V spec.
The register is defined as WARL. At the moment, Ibex doesn't enable U-mode
access to the performance montiors. Consequently, writes to the register are
ignored and it reads as zero which is okay according to the spec.
This resolveslowRISC/Ibex#1278 .
Currently, the `cov` step in the DV Makefile will only merge coverage
databases emitted directly from Ibex simulations, and will not pick up
any coverage databases generated by the RISCV-DV functional coverage
flow.
This PR updates the `gen_cov()` function in `sim.py` to recursively
search for any generated coverage directories and then merges them all.
Resultant coverage reports include all code coverage, Ibex functional
coverage, and RISCV-DV functional coverage.
The coverage-related targets in the Makefile have also been renamed to
improve clarity.
Signed-off-by: Udi Jonnalagadda <udij@google.com>
Anyone who needs to disassemble their generated ELF can probably just
call objdump directly and the precise set of flags have already
confused at least one potential contributor[1].
We're keeping the canned objdump command for "engineers that know
where to look" because some have said they find it useful. Run it with
e.g.
make -C examples/sw/simple_system/hello_test disassemble
[1] https://github.com/lowRISC/ibex/issues/1263
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.
We were using the old html_context which has been deprecated
for a while. This PR switches to html_css_files instead.
See sphinx-doc/sphinx#8885 for more information.
The UVM log should be checked for failures before attempting to process
the core trace log. A simulation failure could mean the trace log
doesn't exist and is is preferable to report the simulation error from
the log rather than trace not found as a failure cause.
Update code from upstream repository https://github.com/google/riscv-
dv to revision 0b625258549e733082c12e5dc749f05aefb07d5a
* Add a knob to use rounding mode from the instruction (google/riscv-
dv#767) (taoliug)
* Add rounding mode support for floating point arithmetic instructions
(google/riscv-dv#766) (taoliug)
* Fix syntax issue (google/riscv-dv#765) (taoliug)
* Add riscv_amo_instr (aneels3)
* convert string to enum type (ishita71)
* Remove unintended errors in the coverage flow (google/riscv-dv#757)
(taoliug)
* Fix c_test handling in the YAML testlist (google/riscv-dv#756)
(taoliug)
* Add support for new Spike trace format (google/riscv-dv#755) (Daniel
Bates)
* Fixgoogle/riscv-dv#751 for floating point coverage (Weicai Yang)
* Fix issues with implemented TODO's (aneels3)
* fix randomize_gpr (aneels3)
* Add file riscv_b_instr.py (ishita71)
* add std_randomize todo (pvipsyash)
* Add todo for floating_point test (ShraddhaDevaiya)
* Add scripts to integrate with Metrics regression platform (Aimee
Sutton)
Includes a fix to dv/uvm/core_ibex/sim.py to use `asm_test` rather than
`asm_tests` due to changes in RISCV-DV
Signed-off-by: Greg Chadwick <gac@lowrisc.org>
The assembly for the CSR test is generated by a script from RISCV-DV. A
.org directive is required to put the generated code at the correct
start address for the instantiated Ibex core.
riscv_interrupt_instr_test and riscv_debug_instr_test aim to produce
interrupt and debug requests once per unique instruction they've seen.
One exception to this is WFI instructions, as these always require an
interrupt or debug request to wake the core. This fixes two timeout
issues with WFI instructions.
1. The return value of `decode_instruction` is used to determine whether
an instruction should have an interrupt or debug request generated
for it. For WFI this must always happen or the test will hang.
2. Before calling check_stimulus in a test the testbench waits for 50
clock cycles. For the riscv_interrupt_instr_test and
riscv_debug_instr_test if a WFI is executed during these 50 cycles
the test will hang. This adds a check to see if the core has gone to
sleep in those tests and if so sends interrupt/debug stimulus to wake
it up.
The `driver_tick` DPI call drove inputs directly but was being scheduled
in an undefined order with other always_ff blocks. This results in a
race condition where some always_ff blocks see old inputs and others see
new in the same clock tick. Instead use values from `driver_tick` to
perform NBA updates and avoid the race condition.
This implemements the RISC-V Trusted Execution Environment (TEE) working
group proposal 'PMP Enhancements for memory access and execution
prevention on Machine mode'. The proposal is awaiting ratification and
is not expected to change beyond minor tweaks before it becomes part of
the RISC-V priviledged specification.
No seperate 'classic' PMP only mode is provided as different PMP
behaviour only occurs when the MSECCFG CSR is written to. This CSR is
introduced by the proposal and has no specified function in the current
RISC-V priviledged specification.
* Handle missing log files with error messages rather than terminating
on unhandled exceptions
* Output potential failure causes from sim log file into regression log
* Alter per test output to make it clearer what line corresponds to what
test
* Only output [PASSED] or [FAILED] a single time per test
* Don't output [PASSED] where sim log is good but ISS comparison is not
In UVM 1.2, at least, uvm_component (a base class of
core_ibex_base_test) still has a method called run(). Ironically, this
has been renamed to "run_phase" to avoid conflicting with user names,
but the old-style phase names still exist at the moment.
Rename our copy of the phase object to cur_run_phase, which doesn't
conflict. Also, set it back to null at the end of the run_phase()
task. We shouldn't ever use it afterwards, and it's probably a good
idea to explode with a null object error if we do.
The previous code contained
wait (dut_vif.dut_cb.priv_mode === select_mode())
and VCS warns that this wait block will only trigger on changes to
explicit arguments. That is, if the in_nested_trap field changes, so
the return value of the select_mode() method would change to match
priv_mode, the wait statement won't finish.
This patch explicitly stores a snapshot of the value of select_mode()
just before the wait line. I think this is the intended behaviour, and
will no longer trigger warnings from VCS.
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.
I wonder whether we could use some form of quoting to allow
"32'h8000_0000" to get through Riviera's TCL, but we don't have any
way to test, so let's go with the easy option.
This should match what's going on a bit more accurately. The link to
OVPsim now points at the (free of cost) commercial tool: riscv-ovpsim
doesn't support the bitmanip specification that we're using at the
moment.
The -Wwarn-IMPERFECTSCH flag is suggested in the Verilator docs (to
help spot if we get a clock gating hint wrong). The waiver is no
longer needed because we now add the relevant hint in the
RTL (vendored in prim_generic_clock_gating.sv from OpenTitan).
The previous change was wrong: it was trying to define a signal with
DbgHwNumLen bits that contained DbgHwBreakNum - 1. Unfortunately, '1
is *not* the same as a zero-extended version of 1'b1.
DbgHwBreakNum - 1 is an int, so generates a warning if it's assigned
to tselect_d (of type logic [DbgHwNumLen-1:0]). Explicitly generate
the value we need as a localparam.
This lint warning doesn't appear by default in the Ibex repository,
because DbgTriggerEn is disabled. It does, however, appear in
OpenTitan because we enable it there.
- name:Lint Verilog source files with Verilator for ${{ inputs.ibex_config }}
shell:bash
run:|
set +e
fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_top_tracing $IBEX_CONFIG_OPTS
if [ $? != 0 ]; then
echo -n "::error::"
echo "Verilog lint failed. Run 'fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_top_tracing $IBEX_CONFIG_OPTS' to check and fix all errors."
exit 1
fi
- name:Lint Verilog source files with Verible Verilog Lint for ${{ inputs.ibex_config }}
shell:bash
run:|
set +e
fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_top_tracing $IBEX_CONFIG_OPTS
if [ $? != 0 ]; then
echo -n "::error::"
echo "Verilog lint failed. Run 'fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_top_tracing $IBEX_CONFIG_OPTS' to check and fix all errors."
exit 1
fi
- name:Run RISC-V Compliance test for Ibex RV32IMC for ${{ inputs.ibex_config }}
shell:bash
run:|
set +e
# Build simulation model of Ibex
fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_riscv_compliance $IBEX_CONFIG_OPTS
if [ $? != 0 ]; then
echo -n "::error::"
echo "Unable to build Verilator model of Ibex for compliance testing."
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
# GitHub Actions CI build configuration
name:Ibex CI
on:
push:
tags:
- "*"
merge_group:
types:
- checks_requested
pull_request:
branches:
- "*"
# Note: All tests run as part of one job to avoid copying intermediate build
# artifacts around (e.g. Verilator and toolchain builds). Once more builds/tests
# are added, we need to re-evaluate this decision to parallelize jobs and
# improve end-to-end CI times.
jobs:
lint_dv:
name:Run quality checks (Lint and DV)
runs-on:ubuntu-22.04
steps:
- uses:actions/checkout@v4
with:
# Fetch all history so that we can run git diff on the base branch
fetch-depth:0
- name:Setup environment variables
run:|
# Filter out empty lines or comments
grep -v '^\(#\|$\)' ci/vars.env >> $GITHUB_ENV
- name:Install build dependencies
run:|
ci/install-build-deps.sh
- name:Display environment
run:|
echo $PATH
python3 --version
echo -n "fusesoc "
fusesoc --version
verilator --version
riscv32-unknown-elf-gcc --version
verible-verilog-lint --version
# Verible format is experimental so only run on default config for now,
# will eventually become part of the per-config CI
- name:Format all source code with Verible format (experimental)
run:|
set +e
fusesoc --cores-root . run --no-export --target=format --tool=veribleformat lowrisc:ibex:ibex_top_tracing
if [ $? != 0 ]; then
echo -n "::error::"
echo "Verilog format with Verible failed. Run 'fusesoc --cores-root . run --no-export --target=format --tool=veribleformat lowrisc:ibex:ibex_top_tracing' to check and fix all errors."
echo "This flow is currently experimental and failures can be ignored."
fi
# Show diff of what verilog_format would have changed, and then revert.
git diff --no-pager
git reset --hard HEAD
continue-on-error:true
- name:Use clang-format to check C/C++ coding style
# This check is not idempotent, but checks changes to a base branch.
# Build CoreMark without performance counter dump for co-simulation testing
make -C ./examples/sw/benchmarks/coremark SUPPRESS_PCOUNT_DUMP=1
make -C ./examples/sw/simple_system/pmp_smoke_test
make -C ./examples/sw/simple_system/dit_test
make -C ./examples/sw/simple_system/dummy_instr_test
# Run Ibex RTL CI per supported configuration
- name:Run Ibex RTL CI for small configuration
uses:./.github/actions/ibex-rtl-ci-steps
with:
ibex_config:small
- name:Run Ibex RTL CI for opentitan configuration
uses:./.github/actions/ibex-rtl-ci-steps
with:
ibex_config:opentitan
- name:Run Ibex RTL CI for maxperf configuration
uses:./.github/actions/ibex-rtl-ci-steps
with:
ibex_config:maxperf
- name:Run Ibex RTL CI for maxperf-pmp-bmbalanced configuration
uses:./.github/actions/ibex-rtl-ci-steps
with:
ibex_config:maxperf-pmp-bmbalanced
- name:Run Ibex RTL CI for maxperf-pmp-bmfull configuration
uses:./.github/actions/ibex-rtl-ci-steps
with:
ibex_config:maxperf-pmp-bmfull
- name:Run Ibex RTL CI for experimental-branch-predictor configuration
uses:./.github/actions/ibex-rtl-ci-steps
with:
ibex_config:experimental-branch-predictor
# Run lint on simple system
- name:Run Verilator lint on simple system
run:|
set +e
fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_simple_system
if [ $? != 0 ]; then
echo -n "::error::"
echo "Verilog lint with Verilator failed. Run 'fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_simple_system' to check and fix all errors."
exit 1
fi
- name:Run Verible lint on simple system
run:|
set +e
fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_simple_system
if [ $? != 0 ]; then
echo -n "::error::"
echo "Verilog lint with Verible failed. Run 'fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_simple_system' to check and fix all errors."
| Verification status | Red | Green | Green | Green |
Notes:
* Performance numbers are based on CoreMark running on the Ibex Simple System [platform](examples/simple_system/README.md).
Note that different ISAs (use of B and C extensions) give the best results for different configurations.
See the [Benchmarks README](examples/sw/benchmarks/README.md) for more information.
The "maxperf-pmp-bmfull" configuration sets a `SpecBranch` parameter in `ibex_core.sv`; this helps timing but has a small negative performance impact.
* Yosys synthesis area numbers are based on the Ibex basic synthesis [flow](syn/README.md) using the latch-based register file.
* Commercial synthesis area numbers are a rough estimate of what might be achievable with a commercial synthesis flow and technology library.
* For comparison, the original "Zero-riscy" core yields an area of 23.14kGE using our Yosys synthesis flow.
@ -42,8 +47,8 @@ Notes:
Amber indicates that some verification has been performed, but the configuration is still experimental.
Red indicates a configuration with minimal/no verification.
Users must make their own assessment of verification readiness for any tapeout.
* v0.92 of the RISC-V Bit Manipulation Extension is supported.
This is *not ratified* and there may be changes for the v1.0 ratified version.
* v.1.0.0 of the RISC-V Bit-Manipulation Extension is supported as well as the remaining sub-extensions of draft v.0.93 of the bitmanip spec.
The latter are *not ratified* and there may be changes before ratification.
See [Standards Compliance](https://ibex-core.readthedocs.io/en/latest/01_overview/compliance.html) in the Ibex documentation for more information.
## Documentation
@ -52,6 +57,17 @@ The Ibex user manual can be
[read online at ReadTheDocs](https://ibex-core.readthedocs.io/en/latest/). It is also contained in
the `doc` folder of this repository.
## Examples
The Ibex repository includes [Simple System](examples/simple_system/README.md).
This is an intentionally simple integration of Ibex with a basic system that targets simulation.
It is intended to provide an easy way to get bare metal binaries running on Ibex in simulation.
A more complete example can be found in the [Ibex Demo System repository](https://github.com/lowrisc/ibex-demo-system).
In particular it includes a integration of the [PULP RISC-V debug module](https://github.com/pulp-platform/riscv-dbg).
It targets the [Arty A7 FPGA board from Digilent](https://digilent.com/shop/arty-a7-artix-7-fpga-development-board/) and supports debugging via OpenOCD and GDB over USB (no external JTAG probe required).
The Ibex Demo System is maintained by lowRISC but is not an official part of Ibex.
## Contributing
We highly appreciate community contributions. To ease our work of reviewing your contributions,
@ -69,7 +85,7 @@ When contributing SystemVerilog source code, please try to be consistent and adh
The lowRISC team and Ibex community (including the OpenTitan partnership) take security issues seriously.
We appreciate all efforts to find security vulnerabilities in Ibex and ask that responsible disclosure is practiced should you discover a potential vulnerability.
As Ibex and in particular its secure configuration was developed as part of [OpenTitan](https://www.github.com/lowrisc/opentitan) contact [security@opentitan.org](mailto:security@opentitan.org) to report any security issues and do not open a public issue.
[security@opentitan.org](mailto:security@opentitan.org) will advise on the coordinated vulnerability disclosure (CVD) procedure.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
# Azure Pipelines CI build configuration
# Documentation at https://aka.ms/yaml
variables:
- template:ci/vars.yml
trigger:
batch:true
branches:
include:
- '*'
tags:
include:
- '*'
pr:
branches:
include:
- '*'
# Note: All tests run as part of one job to avoid copying intermediate build
# artifacts around (e.g. Verilator and toolchain builds). Once more builds/tests
# are added, we need to re-evaluate this decision to parallelize jobs and
# improve end-to-end CI times.
jobs:
- job:lint_dv
displayName:Run quality checks (Lint and DV)
pool:
vmImage:"ubuntu-18.04"
steps:
- bash:|
ci/install-build-deps.sh
displayName:Install build dependencies
- bash:|
echo $PATH
python3 --version
echo -n "fusesoc "
fusesoc --version
verilator --version
riscv32-unknown-elf-gcc --version
verible-verilog-lint --version
displayName:Display environment
# Verible format is experimental so only run on default config for now,
# will eventually become part of the per-config CI
- bash:|
fusesoc --cores-root . run --no-export --target=format --tool=veribleformat lowrisc:ibex:ibex_core_tracing
if [ $? != 0 ]; then
echo -n "##vso[task.logissue type=error]"
echo "Verilog format with Verible failed. Run 'fusesoc --cores-root . run --no-export --target=format --tool=veribleformat lowrisc:ibex:ibex_core_tracing' to check and fix all errors."
echo "This flow is currently experimental and failures can be ignored."
fi
# Show diff of what verilog_format would have changed, and then revert.
git diff
git reset --hard HEAD
continueOnError:true
displayName:Format all source code with Verible format (experimental)
# Note: Try to keep the list of configurations in sync with the one used
# in Private CI.
- small
- experimental-maxperf-pmp
- experimental-maxperf-pmp-bmfull
- experimental-maxperf-pmp-bmfull-icache
- experimental-branch-predictor
# Run lint on simple system
- bash:|
fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_simple_system
if [ $? != 0 ]; then
echo -n "##vso[task.logissue type=error]"
echo "Verilog lint with Verilator failed. Run 'fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_simple_system' to check and fix all errors."
exit 1
fi
displayName:Run Verilator lint on simple system
- bash:|
fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_simple_system
if [ $? != 0 ]; then
echo -n "##vso[task.logissue type=error]"
echo "Verilog lint with Verible failed. Run 'fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_simple_system' to check and fix all errors."
displayName:Test and display fusesoc config for ${{ config }}
- bash:|
fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_core_tracing $IBEX_CONFIG_OPTS
if [ $? != 0 ]; then
echo -n "##vso[task.logissue type=error]"
echo "Verilog lint failed. Run 'fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_core_tracing $IBEX_CONFIG_OPTS' to check and fix all errors."
exit 1
fi
displayName:Lint Verilog source files with Verilator for ${{ config }}
- bash:|
fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_core_tracing $IBEX_CONFIG_OPTS
if [ $? != 0 ]; then
echo -n "##vso[task.logissue type=error]"
echo "Verilog lint failed. Run 'fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_core_tracing $IBEX_CONFIG_OPTS' to check and fix all errors."
exit 1
fi
displayName:Lint Verilog source files with Verible Verilog Lint for ${{ config }}
- bash:|
# Build simulation model of Ibex
fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_riscv_compliance $IBEX_CONFIG_OPTS
if [ $? != 0 ]; then
echo -n "##vso[task.logissue type=error]"
echo "Unable to build Verilator model of Ibex for compliance testing."
@ -5,10 +5,11 @@ Ibex is a standards-compliant 32 bit RISC-V processor.
It follows these specifications:
* `RISC-V Instruction Set Manual, Volume I: User-Level ISA, document version 20190608-Base-Ratified (June 8, 2019) <https://github.com/riscv/riscv-isa-manual/releases/download/Ratified-IMFDQC-and-Priv-v1.11/riscv-spec-20190608.pdf>`_
* `RISC-V Instruction Set Manual, Volume II: Privileged Architecture, document version 20190608-Base-Ratified (June 8, 2019) <https://github.com/riscv/riscv-isa-manual/releases/download/Ratified-IMFDQC-and-Priv-v1.11/riscv-privileged-20190608.pdf>`_.
Ibex implements the Machine ISA version 1.11.
* `RISC-V Instruction Set Manual, Volume II: Privileged Architecture, document version 20211203 (December 4, 2021) <https://github.com/riscv/riscv-isa-manual/releases/download/Priv-v1.12/riscv-privileged-20211203.pdf>`_.
Ibex implements the Machine ISA version 1.12.
* `RISC-V External Debug Support, version 0.13.2 <https://content.riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf>`_
* `RISC-V Bit Manipulation Extension, version 0.92 (draft from November 8, 2019) <https://github.com/riscv/riscv-bitmanip/blob/master/bitmanip-0.92.pdf>`_
* `RISC-V Bit-Manipulation Extension, version 1.0.0 <https://github.com/riscv/riscv-bitmanip/releases/download/1.0.0/bitmanip-1.0.0-38-g865e7a7.pdf>`_ and `version 0.93 (draft from January 10, 2021) <https://github.com/riscv/riscv-bitmanip/blob/master/bitmanip-0.93.pdf>`_
* `PMP Enhancements for memory access and execution prevention on Machine mode (Smepmp) version 1.0 <https://github.com/riscv/riscv-tee/blob/191b563b08b31cc2974d604a3b670d8666a2e093/Smepmp/Smepmp.pdf>`_
Many features in the RISC-V specification are optional, and Ibex can be parametrized to enable or disable some of them.
@ -34,8 +35,8 @@ In addition, the following instruction set extensions are available.
- 2.0
- optional
* - **B**: Draft Extension for Bit Manipulation Instructions
- 0.92[#B_draft]_
* - **B**: Standard Extension for Bit-Manipulation Instructions
- 1.0.0 + 0.93[#B_draft]_
- optional
* - **Zicsr**: Control and Status Register Instructions
@ -46,8 +47,11 @@ In addition, the following instruction set extensions are available.
- 2.0
- always enabled
Most content of the RISC-V privileged specification is optional.
Ibex currently supports the following features according to the RISC-V Privileged Specification, version 1.11.
* - **Smepmp** - PMP Enhancements for memory access and execution prevention on Machine mode
- 1.0
- always enabled in configurations with PMP see :ref:`PMP Enhancements<pmp-enhancements>`
Ibex currently supports the following features according to the RISC-V Privileged Specification, version 1.12.
* M-Mode and U-Mode
* All CSRs listed in :ref:`cs-registers`
@ -56,7 +60,9 @@ Ibex currently supports the following features according to the RISC-V Privilege
..rubric:: Footnotes
..[#B_draft] Note that while Ibex fully implements draft version 0.92 of the RISC-V Bit Manipulation Extension, this extension may change before being ratified as a standard by the RISC-V Foundation.
..[#B_draft] Ibex fully implements the ratified version 1.0.0 of the RISC-V Bit-Manipulation Extension including the Zba, Zbb, Zbc and Zbs sub-extensions.
In addition, Ibex also supports the remaining Zbe, Zbf, Zbp, Zbr and Zbt sub-extensions as defined in draft version 0.93 of the RISC-V Bit-Manipulation Extension.
Note that the latter sub-extensions may change before being ratified as a standard by the RISC-V Foundation.
Ibex will be updated to match future versions of the specification.
Prior to ratification this may involve backwards incompatible changes.
Additionally, neither GCC or Clang have committed to maintaining support upstream for unratified versions of the specification.
The whole design is completely synchronous and uses positive-edge triggered flip-flops, except for the register file, which can be implemented either with latches or with flip-flops.
See :ref:`register-file` for more details.
The core occupies an area of roughly 24 kGE when using the latch-based register file and implementing the RV32IMC ISA, or 16 kGE when implementing the RV32EC ISA.
Ibex is verified using a :ref:`UVM based testbench<verification>` that employs a :ref:`co-simulation methodology<cosim>` to cross-check Ibex execution against an ISS reference model (`Spike <https://github.com/lowRISC/riscv-isa-sim>`_).
The testbench runs binaries built from source produced by the `RISC-DV <https://github.com/chipsalliance/riscv-dv>`_ random instruction generator.
Additional stimulus is provided in the form of randomized memory timings, memory errors, interrupts and debug requests by the testbench.
A comprehensive :ref:`testplan<testplan>` and :ref:`coverage plan<coverage-plan>` are implemented.
Verification Status
-------------------
Ibex has a large number of parameters resulting in a large number of possible configurations.
The configuration space is too large to fully verify the design for all possible parameter sets.
To manage this complexity regressions runs and verification closure target a number of :ref:`supported configurations<ibex-config>`.
Current verification closure effort is focussed on the ``opentitan`` configuration and is the only configuration with nightly regression runs.
Verification maturity is tracked via :ref:`verification_stages` that are `defined by the OpenTitan project <https://opentitan.org/book/doc/project_governance/development_stages.html#hardware-verification-stages-v>`_.
Ibex has achieved **V2S** for the `opentitan` configuration, broadly this means verification is almost complete (over 90% code and functional coverage hit with over 90% regression pass rate with test plan and coverage plan fully implemented) but not yet closed.
Nightly regression results, including a coverage summary and details of test failures, for the ``opentitan`` Ibex configuration are published at https://ibex.reports.lowrisc.org/opentitan/latest/report.html. Below is a summary of these results:
The ``ibex_top`` module has a large number of top-level parameters which configure the core (see :ref:`core-integration`).
This gives rise to a huge number of possible Ibex core configurations.
To manage this complexity a number of named configurations is provided in the :file:`ibex_configs.yml` file.
A subset of these are 'supported configurations' which are the focus of verification and development activities.
Configuration Tool
------------------
A tool :file:`util/ibex_config.py` is provided to work with the named configurations.
This tool provides command line options to set Ibex parameters for various EDA tools for a named configuration.
Various Ibex flows (e.g. the DV flow) use this tool internally and can be provided with a configuration name from :file:`util/ibex_config.py` to work with.
Here is an example of using the configuration tool to get the FuseSoC options required to build the ``opentitan`` configuration.
..code-block:: bash
# Request FuseSoC options required to build the 'opentitan' Ibex configuration.
For further information about using the tool check the help provided on the command line.
..code-block:: bash
# Get help on using ibex_config.py
./util/ibex_config.py -h
Supported Configurations
------------------------
The current set of supported configurations are:
* ``small`` - RV32IMC with two stage pipeline and 3 cycle multiplier
* ``opentitan`` - The configuration used by the `OpenTitan <www.opentitan.org>`_ project
* ``maxperf`` - RV32IMC with three stage pipeline and single cycle multiplier, maximum performance (using stable features) configuration.
* ``maxperf-pmp-bmbalanced`` - ``maxperf`` configuration with PMP and the 'balanced' bit-manipulation configuration (:ref:`core-integration` for details).
To make use of Ibex it has to be integrated as described in :ref:`core-integration`.
There are two examples that demonstrate Ibex usage.
FPGA
----
The first is 'Simple System' and is part of the Ibex repository.
It demonstrates a minimal system connecting Ibex to some memory with a timer peripheral and is targeted at simulation.
A minimal example for the `Arty A7 <https://reference.digilentinc.com/reference/programmable-logic/arty-a7/start>`_ FPGA Development board is provided.
In this example Ibex is directly linked to a SRAM memory instance.
Four LEDs from the board are connected to the data bus and are updated each time when a word is written.
The memory is separated into a instruction and data section.
The instructions memory is initialized at synthesis time by reading the output from the software build.
The software writes to the data section the complementary lower for bits of a word every second resulting in blinking LEDs.
The second is the `'Ibex Demo System' <https://www.github.com/lowrisc/ibex-demo-system>`_ which is a separate repository.
It is targeted at FPGA implementation and contains some extra peripherals along with a RISC-V debug module integration.
Simple System
-------------
Simple system is built via FuseSoC.
Verilator is the primary simulator it is designed for, though other simulators are also supported (such as VCS).
Its aim is to make running a binary against Ibex RTL, obtaining an instruction trace, wave trace and any other simulation outputs as simple as possible along with demonstrating basic Ibex integration.
See the `Simple System README <https://github.com/lowRISC/ibex/tree/master/examples/simple_system>`_ for more information.
There is an extended version of simple system which adds co-simulation checking.
This cross-checks every instruction execution against a RISC-V ISS.
It is the same co-simulation method used by our full DV environment but enables its use in a far simpler setup.
The simple system co-simulation setup is compatible with Verilator (unlike our full DV environment).
See :ref:`cosim` for more information.
Find the description of how to build and program the Arty board in ``examples/fpga/artya7/README.md``.
This page discusses initial steps and requirements to start using Ibex in your design.
The Ibex repository contains all the RTL needed to simulate and synthesize an Ibex core.
`FuseSoC <https://github.com/olofk/fusesoc>`_ core files list the RTL files required to build Ibex (see :file:`ibex_core.core`).
The core itself is contained in the :file:`rtl/` directory, though it utilizes some primitives found in the :file:`vendor/lowrisc_ip/` directory.
These primitives come from the `OpenTitan <https://github.com/lowrisc/opentitan>`_ project but are copied into the Ibex repository so the RTL has no external dependencies.
You may wish to replace these primitives with your own and some are only required for specific configurations.
See :ref:`integration-prims` for more information.
Register File
-------------
There are several paths to follow depending on what you wish to accomplish:
Ibex comes with three different register file implementations that can be selected using the enumerated parameter ``RegFile`` defined in :file:`rtl/ibex_pkg.sv`.
Depending on the target technology, either the flip-flop-based ("ibex_pkg::RegFileFF", default), the latch-based ("ibex_pkg::RegFileLatch") or an FPGA-targeted ("ibex_pkg::RegFileFPGA") implementation should be selected.
For more information about the three register file implementations and their trade-offs, check out :ref:`register-file`.
* See :ref:`examples` for a basic simulation setup running the core in isolation and a simple FPGA system.
* See :ref:`verification` to begin working with the DV flow.
* See :ref:`core-integration` to integrate the Ibex core into your own design.
* See :ref:`integration-fusesoc-files` for information on how to get a complete RTL file listing to build Ibex for use outside of FuseSoC based flows.
The main module is named ``ibex_core`` and can be found in ``ibex_core.sv``.
Below, the instantiation template is given and the parameters and interfaces are described.
The main module is named ``ibex_top`` and can be found in ``ibex_top.sv``.
Note that the core logic is split-out from the register file and RAMs under ``ibex_top``.
This is to facilitate a dual-core lockstep implementation (see :ref:`security`).
Register File
-------------
Ibex comes with three different register file implementations that can be selected using the enumerated parameter ``RegFile`` defined in :file:`rtl/ibex_pkg.sv`.
Depending on the target technology, either the flip-flop-based ("ibex_pkg::RegFileFF", default), the latch-based ("ibex_pkg::RegFileLatch") or an FPGA-targeted ("ibex_pkg::RegFileFPGA") implementation should be selected.
For more information about the three register file implementations and their trade-offs, check out :ref:`register-file`.
Identification CSRs
-------------------
The RISC-V Privileged Architecture specifies several read-only CSRs that identify the vendor and micro-architecture of a CPU.
These are ``mvendorid``, ``marchid`` and ``mimpid``.
The fixed, read-only values for these CSRs are defined in :file:`rtl/ibex_pkg.sv`.
Implementers should carefully consider appropriate values for these registers.
Ibex, as an open source implementation, has an assigned architecture ID (``marchid``) of 22.
(Allocations are specified in `marchid.md of the riscv-isa-manual repository <https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md>`_.)
If significant changes are made to the micro-architecture a different architecture ID should be used.
The vendor ID and implementation ID (``mvendorid`` and ``mimpid``) both read as 0 by default, meaning non-implemented.
Implementers may wish to use other values here.
Please see the RISC-V Privileged Architecture specification for more details on what these IDs represent and how they should be chosen.
.._integration-prims:
Primitives
----------
Ibex uses a number of primitive modules (that are held outside the :file:`rtl/` which contains the Ibex RTL).
Full implementations of these primitives are provided in the Ibex repository but implementors may wish to provide their own implementations.
Some of the primitives are only used for specific Ibex configurations so can be ignored/removed if you're not using one of those configurations.
The mandatory primitives (used by all configurations) are:
* ``prim_buf`` - A buffer, used to ensure security critical logic isn't optimized out in synthesis (by applying suitable constraints to prim_buf).
In configurations where ``SecureIbex == 0`` it must exist but can be implemented as a straight passthrough.
* ``prim_clock_gating`` - A clock gate.
The configuration dependent primitives are:
* ``prim_clock_mux2`` - A clock mux, used by the lockstep duplicate core.
Required where ``SecureIbex == 1``.
* ``prim_flop`` - A flip flop, used to ensure security critical logic isn't optimized out in synthesis (by applying suitable constraints to prim_flop).
Required where ``SecureIbex == 1``.
* ``prim_ram_1p`` - A single ported RAM.
Required where ``ICache == 1``.
* ``prim_ram_1p_scr`` - A single ported RAM which scrambles its contents with cryptographic primitives.
Required where ``ICache == 1`` and ``SecureIbex == 1``.
* ``prim_lfsr`` - Linear feedback shift register, used for pseudo random number generation for dummy instruction insertion.
Required where ``SecureIbex == 1``.
* ``prim_onehot_check`` - Checks a onehot signal is correct, for detecting fault injection attacks.
Required where ``SecureIbex == 1``.
* ``prim_secded_X`` - Various primitives to encode and decode SECDED (single error correct, double error detect) error detection and correction codes.
Required where ``SecureIbex == 1``.
Primitives exclusively used by other primitives:
* ``prim_present`` / ``prim_prince`` / ``prim_subst_perm`` - Cryptographic primitives used by ``prim_ram_1p_scr``.
* ``prim_ram_1p_adv`` - Wrapper around ``prim_ram_1p`` that adds support for ECC, used by ``prim_ram_1p_scr``.
.._integration-fusesoc-files:
RTL File List
-------------
Ibex flows use `FuseSoC <https://github.com/olofk/fusesoc>`_ to gather needed RTL files and run builds.
If you want to use Ibex without FuseSoC the following FuseSoC command will copy all the needed files into a build directory.
..code-block:: bash
fusesoc --cores-root . run --target=lint --setup --build-root ./build/ibex_out lowrisc:ibex:ibex_top
FuseSoC uses Python and it can be installed using pip.
..code-block:: bash
pip3 install -U -r python-requirements.txt
Ibex uses a `custom fork of FuseSoC <https://github.com/lowRISC/fusesoc/tree/ot>`_, so you must install it via this method rather than installing FuseSoC separately.
The RTL will be in :file:`./build/ibex_out/src` which is further divided into different sub-directories.
A file list containing paths to all of the RTL files can be found in :file:`./build/ibex_out/ibex-verilator/lowrisc_ibex_ibex_top_0.1.vc`.
@ -8,9 +8,10 @@ The following tools are known to work with the RTL code of Ibex.
Please `file an issue <https://github.com/lowRISC/ibex/issues>`_ if you experience problems with any of the listed tools, or if you have successfully used a tool with Ibex which is not listed here.
- Synopsys Design Compiler
- Xilinx Vivado
- Cadence Genus
- Xilinx Vivado, version |tool_requirements.vivado| and up.
- Verilator, version |tool_requirements.verilator| and up.
- Synopsys VCS
- Synopsys VCS, version at least |tool_requirements.vcs|.
- Cadence Incisive/Xcelium
- Mentor Questa
- Aldec Riviera Pro
@ -18,6 +19,10 @@ Please `file an issue <https://github.com/lowRISC/ibex/issues>`_ if you experien
To run the UVM testbench a RTL simulator which supports SystemVerilog and UVM 1.2 is required.
The `documentation of riscv-dv <https://github.com/google/riscv-dv#prerequisites>`_ contains a list of supported simulators.
To compile code that runs on Ibex, you'll need a RISC-V toolchain.
This isn't part of the core as such, but is necessary for verification.
See the :doc:`Verification <../03_reference/verification>` section of the Reference Guide for more details about which toolchains the project currently uses for testing.
A co-simulation system is provided that can run in either the Ibex UVM DV environment or with Simple System.
This system runs a RISC-V ISS (currently only Spike is supported) in lockstep with an Ibex core.
All instructions executed by Ibex and memory transactions generated are checked against the behaviour of the ISS.
This system supports memory errors, interrupt and debug requests which are observed in the RTL simulation and forwarded to the ISS so the ISS and RTL remain in sync.
The system uses a generic interface to allow support of multiple ISSes.
Only VCS is supported as a simulator, though no VCS specific functionality is required so adding support for another simulator should be straight-forward.
To run the co-simulation system, a particular version of Spike is required (see the Setup and Usage section, below).
The RISC-V Formal Interface (RVFI) is used to provide information about retired instructions and instructions that produce synchronous traps for checking.
The RVFI has been extended to provide interrupt and debug information and the value of various CSRs that are harder to model (e.g. ``mcycle``).
These extended signals have the prefix ``rvfi_ext``
Setup and Usage
---------------
Clone the `lowRISC fork of Spike <https://github.com/lowRISC/riscv-isa-sim>`_ and check out the ``ibex-cosim-v0.5`` tag.
Other, later, versions called ``ibex-cosim-v*`` may also work but there's no guarantee of backwards compatibility.
Follow the Spike build instructions to build and install Spike.
The ``--enable-commitlog`` and ``--enable-misaligned`` options must be passed to ``configure``.
We recommend using a custom install location (using ``--prefix=<path>`` with ``configure``) to avoid cluttering system directories.
Note that, if you do this, you will also need to add an entry to ``PKG_CONFIG_PATH`` so that ``pkg-config`` can tell us how to build against the installed Spike libraries.
To build/run the UVM DV environment with the co-simulator, add the ``COSIM=1`` argument to the make command.
To build Simple System with the co-simulator, build the ``lowrisc:ibex:ibex_simple_system_cosim`` core.
The co-simulation system uses DPI calls to link the DV and ISS sides together.
A C++ interface is defined in ``dv/cosim/cosim.h`` with a DPI wrapper provided by ``dv/cosim/cosim_dpi.cc`` and ``dv/cosim/cosim_dpi.h``.
A ``chandle``, which points to some class instance that implements the interface, must be provided by the DV environment.
All the co-simulation DPI calls take this ``chandle`` as a first argument.
The details below discuss the C++ interface.
The DPI version of the interface is almost identical, with all functions prefaced with ``riscv_cosim`` and taking a ``chandle`` of the co-simulation instance to use.
The core function of the co-simulation interface is the ``step`` function:
``step`` takes arguments giving the PC of the most recently retired or synchronously trapping instruction in the DUT along with details of any register write that occurred.
Where ``step`` is provided with a retired (successfully executed) instruction it steps the ISS by one instruction and checks it executed the same instruction, with the same register write result, as the DUT.
When ``step`` is provided with an instruction that produces a synchronous trap, it checks the ISS also traps on the same instruction but does not step to the next executed instruction.
That instruction will be the first instruction of the trap handler and will be checked/stepped by the next call to ``step`` when it retires from the DUT.
Any data memory accesses that the ISS produces during the ``step`` are checked against observed DUT memory accesses.
``step`` returns false if any checks have failed.
If any errors occur during the step they can be accessed via ``get_errors`` which returns a vector of error messages.
For the DPI interface errors are accessed using ``riscv_cosim_get_num_errors`` and ``riscv_cosim_get_error``.
When errors have been checked they can be cleared with ``clear_errors``.
Trap Handling
^^^^^^^^^^^^^
Traps are separated into two categories, synchronous and asynchronous.
Synchronous traps are caused by a particular instruction's execution (e.g. an illegal instruction).
Asynchronous traps are caused by external interrupts.
Note that in Ibex error responses to both loads and store produce a synchronous trap so the co-simulation system has the same behaviour.
A synchronous trap is associated with a particular instruction and prevents that instruction from completing its execution.
That instruction doesn't retire, but is still made visible on the RVFI.
The ``rvfi_trap`` signal is asserted for an instruction that causes a synchronous trap.
As described above ``step`` should be called for any instruction that causes a synchronous trap to check the trap is also seen by the ISS.
An asynchronous trap can be seen as occurring between instructions and as such doesn't have an associated instruction, nothing will be seen on RVFI with ``rvfi_trap`` set.
The co-simulation system will immediately take any pending asynchronous trap when ``step`` is called, expecting the instruction checked with ``step`` to be the first instruction of the trap handler.
While a debug request is not strictly an asynchronous trap (it doesn't use the same exception handling mechanism), they work identically to asynchronous traps for the co-simulation system.
When a debug request is pending when ``step`` is called the co-simulation will expect the instruction checked by ``step`` to be the first instruction of the debug handler.
Interrupts and Debug Requests
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The DV environment must observe any incoming interrupts and debug requests generated by the testbench and notify the co-simulation system of them using ``set_mip``, ``set_debug_req`` and ``set_nmi``.
An interrupt or debug request will take immediate effect at the next ``step`` (if architecturally required to do so).
The DV environment is responsible for determining when to call ``set_mip``, ``set_debug_req`` and ``set_nmi`` to ensure a RTL and co-simulation match.
The state of the incoming interrupts and debug request is sampled when an instruction moves from IF to ID/EX.
The sampled state is tracked with the rest of the RVFI pipeline and used to call ``set_mip``, ``set_debug_req`` and ``set_nmi`` when the instruction is output by the RVFI.
A complication occurs when more than one interrupt or debug requests occur between individual instruction fetches.
One interrupt or debug request may take priority over another when they all occur together but when they occur in time is important as well.
If interrupt and debug request notification is associated exclusively with retired instructions the co-simulation system cannot correctly prioritise multiple interrupts and debug requests.
To deal with this the RVFI can also signal an interrupt event not associated with an instruction by setting ``rvfi_ext_irq_valid`` without setting ``rvfi_valid``.
When this is set the interrupt related RVFI signals are valid and provide the interrupt state.
The RVFI is used in this way, as opposed to a separate notification interface, so the interrupt notifications are ordered relative to the retired instructions.
See the comments in :file:`rtl/ibex_core.sv`, around the ``new_debug_req``, ``new_nmi``, ``new_irq`` and ``rvfi_irq_valid`` signals for further details.
Memory Access Checking and Bus Errors
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The co-simulation system must be informed of all Dside accesses performed by the RTL using ``notify_dside_access``.
See :file:`dv/cosim/cosim.h` for further details.
As Ibex doesn't perform speculative Dside memory accesses, all notified accesses are expected to match with accesses performed by the ISS in the same order they are notified.
Accesses notified via ``notify_dside_access`` can specify they saw an error response, the co-simulation system will produce the appropriate trap when the ISS attempts to access the address that saw the error.
Accesses must be notified before they occur in the ISS for the access matching and trapping on errors to work.
Iside accesses from Ibex can be speculative, so there is no simple link between accesses produced by the RTL and the accesses performed by the ISS for the Iside.
This means no direct checking of Iside accesses is done, however errors on the Iside accesses that result in an instruction fault trap need to be notified to the co-simulation system.
``set_iside_error`` does this, it is provided with the address that saw the bus error and it should be called immediately before the ``step`` that will process the trap.
The co-simulation system will produce an instruction fault trap if it attempts to access the provided error address in the ``step`` call following the ``set_iside_error`` call.
Two methods are available for dealing with bus errors on the Iside, they differ in where they probe.
One probes on the external instr_X memory interface, the other probes internally within the IF stage.
The probe used is selected by the ``probe_imem_for_err`` field of the ``core_ibex_cosim_cfg`` structure.
When set external probing is used, otherwise internal probing is used.
Both probe points look for addresses that have seen bus errors.
If an instruction entering ID/EX fetches from an address that has seen a bus error (as recorded by one of the probing methods) its ``rvfi_order_id`` is recorded.
When a faulting instruction is reported on the RVFI and its ``rvfi_order_id`` matches a recorded faulting one ``set_iside_error`` is called with the faulting address before the next ``step``.
The external interface probe should be used when it is guaranteed that a bus error to address A on the external interface results in a fetch error the next time an instruction with address A is observed entering the ID/EX stage (providing no successful access to A has occurred in the mean time).
Otherwise the internal probe should be used.
When Ibex is used with the prefetch buffer this guarantee holds and the external probe can be used.
When Ibex is used with the instruction cache this guarantee does not hold and the internal probe must be used.
Care should be taken when using the internal probe as it will miss any bug that causes instruction faults to be ignored by the prefetch buffer or ICache (or whatever else has been used in place of these by a custom implementation).
In the case of the Ibex ICache a separate testbench ensures instruction faults are dealt with appropriately within the ICache.
Branch prediction hasn't yet been considered, this will add more coverage points and alter some others
Introduction
------------
Ibex functional coverage is split into two major categories:
* Architectural coverage - which is concerned with instructions being executed and exercising various features of the RISC-V architecture (e.g. PMP) and does not consider the details of how this execution occurs.
* Microarchitectural coverage - which is concerned with the specifics of the RTL operation, ensuring interesting corner cases are seen along with various micro-architectural events (e.g. the different kinds of stall) and combinations of them.
Architectural coverage is not Ibex specific. It can be determined directly from a trace of executed instructions and is handled by RISCV-DV, details can be found in the `RISCV-DV documentation <https://htmlpreview.github.io/?https://github.com/google/riscv-dv/blob/master/docs/build/singlehtml/index.html#document-coverage_model>`_.
Microarchitectural coverage will probe the Ibex RTL directly and is described here.
There is some inevitable overlap between architectural and microarchitectural coverage but we aim to minimise it.
Coverage Implementation
-----------------------
All coverpoints and cross coverage defined below is associated with a name ``cp_name``.
This is the name of the coverpoint or cross that implements the described coverage.
Coverage is implemented in two files; :file:`dv/uvm/core_ibex/fcov/core_ibex_pmp_fcov_if.sv` for PMP related coverage and :file:`dv/uvm/core_ibex/fcov/core_ibex_fcov_if.sv` for everything else.
Microarchitectural Events and Behaviour
---------------------------------------
Below are lists of specific things from the microarchitecture that will be included in functional coverage.
Each of the points listed below must be covered.
This will be further combined using cross coverage which is described in the section below.
Instructions
^^^^^^^^^^^^
Categories
""""""""""
``cp_id_instr_category``
Instructions can be grouped into a number of categories.
Each category exercises different data and control paths in the core.
For example the ``ADD`` and ``SUB`` instructions are in the same category as they are almost identical for the microarchitecture (both read two registers and write to one, both feed operands to the ALU and take their result from it, both have the same response to interrupts etc; the only difference is the ALU operation).
Instructions can be compressed or uncompressed but that isn't factored into the instruction categories below (excepting for illegal instructions).
The decompression occurs in the IF stage and is invisible to the ID/EX stage so isn't relevant for instruction execution.
A separate set of category-agnostic compressed instruction behaviour is considered instead.
An instruction category is sampled at the ID/EX stage (which is where all the varying behaviours actually occur).
Some categories are just a single instruction, which is named without further description.
* **ALU** - All of the reg/reg reg/imm instructions that use the ALU.
This is any RISC-V instruction with an opcode of ``7'b0010011`` or ``7'b0110011`` (``ibex_pkg::OPCODE_OP`` and ``ibex_pkg::OPCODE_OP_IMM``) other than the ``MUL*`` and ``DIV*`` family of instructions (from RV32M).
* **Mul** - Any ``MUL*`` instruction (from RV32M).
* **Div** - Any ``DIV*`` instruction (from RV32M).
* **Branch** - Any ``B*`` family branch instruction.
* **Jump** - ``JAL``/``JALR``
* **Load** - Any ``L*`` family load instruction.
* **Store** - Any ``S*`` family load instruction.
* **CSRAccess** - Any instruction from Zicsr.
* **EBreakDbg**/**EBreakExc** - An ``EBREAK`` instruction that either enters debug mode (Dbg) or causes an exception (Exc).
Which occurs depends upon the setting of ``dcsr.ebreakm`` / ``dcsr.ebreaku`` combined with the privilege level of executed instruction.
* **ECall** - ``ECALL`` is an environment call used for escalation of privilege.
* **MRet** - ``MRET`` return out of M-mode
* **DRet** - ``DRET`` ruturn from debug mode.
* **WFI** - wait for interrupt.
* **Fence** - ``FENCE`` memory fence on the data side.
* **FetchError** - Any instruction that saw a fetch error.
* **CompressedIllegal** - Any compressed instruction with an illegal encoding.
* **UncompressedIllegal** - Any uncompressed instruction with an illegal encoding.
* **CSRIllegal** - Any instruction attempting a CSR access that is not allowed.
* **PrivIllegal** - Illegal due to privilege level or being in/out of debug mode.
* **OtherIllegal** - Any other instruction that raises an Illegal instruction exception that isn't in the other categories.
* **None** - No instruction in ID/EX stage.
Stalls
""""""
``cp_stall_type_id``
Not all instructions can see all kinds of stalls.
A stall category is sampled at the ID/EX stage only (as stalls in IF and WB don't break down into categories).
* **Instr** - A stall caused by a multi-cycle instruction.
This can be seen by instructions from categories:
* **MUL**
* **DIV**
* **Branch**
* **Jump**
* **LdHz** - A load hazard, the instruction in ID/EX depends upon the result of a load that is awaiting a response in writeback.
This can be seen by instructions from categories:
* **ALU**
* **Mul**
* **Div**
* **Branch**
* **Jump**
* **Load**
* **Store**
* **CSRAccess**
* **Mem** - Memory stall, the instruction in ID/EX is awaiting a prior memory request to complete before it can begin (to allow precise interrupts on a memory error response). This can be seen for all instruction categories
Privilege Level
"""""""""""""""
Ibex can operate at either the M (machine) or U (user) privilege levels.
Different aspects of the Ibex microarchitecture can be using different privilege levels at once.
* ``cp_priv_mode_id`` - Privilege level of ID/EX stage instruction.
* ``cp_priv_mode_lsu`` - Privilege level of LSU operation (ID/EX privilege level modified by ``mstatus.mprv`` and ``mstatus.mpp`` settings).
Note that the privilege level of the instruction in WB isn't retained by the microarchitecture and is not relevant to coverage.
The privilege level of the IF instruction is effectively unknown.
The instruction is checked when moving from IF to ID/EX against the ID stage privilege level to check if execution is permitted by PMP.
Any instruction that reaches WB can be considered bound to retire and any relevant checks and functionality altered by the privilege mode is dealt with at an earlier stage.
Hazards
"""""""
Ibex hazards all occur in the interaction between the ID and EX stage.
* RAW Reg - Read after write hazard, instruction in ID/EX reads a register that writeback is writing.
Split into two versions:
* RAW load - Instruction in ID/EX reading from destination of load in writeback.
Produces a stall (Category LdHz) and shouldn't forward data.
Covered by ``cp_stall_type_id``
* ``cp_wb_reg_no_load_hz`` - Instruction in writeback isn't a load.
Handled with data forwarding and no stall.
* RAW Load/Store bytes - Load with bytes overlapping a store immediately before it.
Covered by ``cp_mem_raw_hz``
State Specific Behaviour
""""""""""""""""""""""""
Some instructions will behave differently depending upon the state of the processor (e.g. the privilege level the instruction executes at, CSR settings or whether the processor is in debug mode).
* Instruction illegal in U Mode.
* ``cp_mret_in_umode`` - ``MRET``
* ``cp_wfi_in_umode`` - ``WFI``
* Read and write to M-mode CSR - Covered by crosses ``csr_write_priv_cross`` and ``csr_read_only_priv_cross```
* Debug mode instructions (cover execution in and out of debug mode).
* ``DRET``
* ``csr_read_only_debug_cross``, ``csr_write_debug_cross`` - Access to debug CSRs.
* ``dcsr``
* ``dpc``
* ``dscratch0``
* ``dscratch1``
* Access to trigger CSRs (also possible in M mode: cover execution in M mode, debug mode and U mode).
Covered by ``csr_read_only_debug_cross``, ``csr_write_debug_cross``, ``csr_read_only_priv_cross``, ``csr_write_priv_cross``.
* ``tselect``
* ``tdata1``
* ``tdata2``
* ``tdata3``
* Loads/stores with ``mstatus.mprv`` set and unset.
Covered by ``mprv_effect_cross``
* EBreak behaviour in U/M mode with different ``dcsr.ebreakm`` / ``dcsr.ebreaku`` settings.
Covered by ``priv_mode_instr_cross``
* ``cp_single_step_instr`` - Single step over every instruction category
Pipeline State
^^^^^^^^^^^^^^
Each pipeline stage has some associated state.
* ``cp_if_stage_state`` - IF stage full and fetching, full and idle, empty and fetching, or empty and idle.
General IF stage full and stalled uninteresting as will only occur when ID stage is full and stalled.
* ``cp_wb_stage_state`` - WB stage full and stalled, full and unstalled, or empty
* ``cp_id_stage_state`` - ID stage full and stalled, full and unstalled, or empty.
* Controller (within ID stage) state machine states
* ``cp_controller_fsm`` - Possible transitions between these states.
* ``RESET`` -> ``BOOT_SET``
* ``BOOT_SET`` -> ``FIRST_FETCH``
* ``FIRST_FETCH`` -> ``DECODE``
* ``FIRST_FETCH`` -> ``IRQ_TAKEN``
* ``FIRST_FETCH`` -> ``DBG_TAKEN_IF``
* ``DECODE`` -> ``FLUSH``
* ``DECODE`` -> ``DBG_TAKEN_IF``
* ``DECODE`` -> ``IRQ_TAKEN``
* ``IRQ_TAKEN`` -> ``DECODE``
* ``DBG_TAKEN_IF`` -> ``DECODE``
* ``DBG_TAKEN_ID`` -> ``DECODE``
* ``FLUSH`` -> ``DECODE``
* ``FLUSH`` -> ``DBG_TAKEN_ID``
* ``FLUSH`` -> ``WAIT_SLEEP``
* ``FLUSH`` -> ``DBG_TAKEN_IF``
* ``WAIT_SLEEP`` -> ``SLEEP``
* ``SLEEP`` -> ``FIRST_FETCH``
Exceptions/Interrupts/Debug
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Exceptions, interrupts and debug entry can all cause control flow changes combined with CSR writes and privilege level changes and work quite similarly within the controller but not identically.
Furthermore they can all occur together and must be appropriately prioritised (consider an instruction with hardware trigger point matching it, that causes some exception and an interrupt is raised the cycle it enters the ID/EX stage).
* Exception from instruction fetch error (covered by the **FetchError** instruction category).
* ``pmp_iside_mode_cross`` - Exception from instruction PMP violation.
* Exception from illegal instruction (covered by the illegal instruction categories).
* ``cp_ls_error_exception`` - Exception from memory fetch error.
* ``cp_ls_pmp_exception`` - Load store unit exception from PMP.
* ``pmp_dside_mode_cross`` - Exception from memory access PMP violation.
* Unaligned memory access
* ``misaligned_insn_bus_err_cross``, ``misaligned_data_bus_err_cross`` - Cover all error and no error scenarios for memory fetch error; first access saw error, second
access saw error, neither access saw error
* Interrupt raised/taken.
* ``cp_interrupt_taken`` - Interrupt raised/taken for each available interrupt line.
For cross coverage, the precise interrupt that's raised/taken is not relevant and it only needs to be grouped by NMI vs non-NMI.
This is done by using ``cp_nmi_taken`` coverpoint in the crosses.
* ``interrupt_taken_instr_cross`` - Interrupt raised/taken the first cycle an instruction is in ID/EX or some other cycle the instruction is in ID/EX.
* ``cp_debug_req`` - External debug request.
* ``cp_single_step_taken`` - Instruction executed when debug single step enabled.
* ``cp_single_step_exception`` - Single step over an instruction that takes an exception.
* ``cp_debug_mode`` - Ibex operating in debug mode.
* ``cp_debug_wakeup`` - Ibex wakes up after being halted from debug request.
* ``irq_wfi_cross``, ``debug_wfi_cross`` - Debug and Interrupt whilst sleeping with WFI
* Cover with global interrupts enabled and disabled
* Cover with specific interrupt enabled and disabled (Should exit sleep when
interrupt is enabled but global interrupts set to disabled, should continue
sleeping when both are disabled).
Continuing to sleep in the case explained above is covered by ``cp_irq_continue_sleep``, otherwise the behaviour is captured in ``irq_wfi_cross``
* Debug and interrupt occurring whilst entering WFI
* Covering period between WFI entering ID/EX stage and going into sleep
Covered by bin ``enter_sleep`` of ``cp_controller_fsm_sleep`` that is used by ``irq_wfi_cross`` and ``debug_wfi_cross``.
* ``cp_double_fault`` - Double fault
PMP
^^^
* ``cp_region_mode`` - Each region configured with different matching modes.
* Off
* TOR
* NA4
* NAPOT
* ``cp_napot_addr_modes`` - When NAPOT is enabled check that each address mode is seen at least once.
* ``cp_region_priv_bits`` - Each region configured with all possible permissions including locked/unlocked.
* Different permissions with MML enabled and disabled, separate cover points for R/W/X/L values with and without MML.
* Access fail & pass.
* ``misaligned_lsu_access_cross`` - All combinations of unaligned access split across a boundary, both halves pass, neither pass, just the first passes, just the second passes.
* Two possible boundary splits; across a 32-bit boundary within a region or a boundary between PMP regions.
* ``pmp_instr_edge_cross`` - Compressed instruction access (16-bit) passes PMP but 32-bit access at same address crosses PMP region boundary.
* Each field of mssecfg enabled/disabled, as well as written to using a CSR write, with relevant functionality tested.
* RLB - rule locking bypass.
* ``cp_edit_locked_pmpcfg``, ``cp_edit_locked_pmpaddr`` - Modify locked region with RLB set.
* ``rlb_csr_cross`` - Try to enable RLB when RLB is disabled and locked regions present.
* MMWP - machine mode whitelist policy.
* ``pmp_dside/iside/iside2_nomatch_cross`` - M-mode access fail due to not matching any PMP regions.
* ``mmwp_csr_cross`` - Try to disable when enabled.
* MML - machine mode lockdown policy.
* ``mml_sticky_cross`` - Try to disable when enabled.
* Access close to PMP region modification that allows/disallows that access.
* ``pmp_wr_exec_region`` - Explores behaviour around adding executable regions when MML is enabled.
Cross of current region configuration with region configuration that is being written and RLB setting.
It only considers regions that aren't currently executable with writes attempted to make them executable.
Non MML configurations are not sampled.
CSRs
^^^^
Basic read/write functionality must be tested on all implemented CSRs.
* ``cp_csr_read_only`` - Read from CSR, there is also ``cp_csr_invalid_read_only`` for illegal CSRs.
* ``cp_csr_write`` - Write to CSR, there is also ``cp_csr_invalid_write`` for illegal CSRs.
* Write to read only CSR.
Covered by ensuring ``cp_csr_write`` is seen for read-only CSRs
* ``cp_warl_check_CSRNAME`` - Write illegal/unsupported value to WARL field for CSR named ``CSRNAME``.
* ``csr_read_only_priv_cross``, ``csr_write_priv_cross``, ``csr_read_only_debug_cross``, ``csr_write_debug_cross`` - Crosses of reads and writes to CSRs from different privilege levels/debug mode.
* Access to CSR disallowed due to privilege levels/debug mode
Covered by ensuring within the crosses
CSRs addresses do not need to be crossed with the variety of CSR instructions as these all use the same basic read & write interface into ``ibex_cs_registers``.
Coverage of the above points will be sampled at the ``ibex_cs_registers`` interface (as opposed to sampling CSR instructions).
Security Countermeasures
^^^^^^^^^^^^^^^^^^^^^^^^
For more detail about each security countermeasure in Ibex see :ref:`security`
* ``cp_pc_mismatch_err`` - PC mismatch error seen.
The :ref:`security features Ibex implements <security>` are given specific security countermeasure names in OpenTitan (see 'Security Countermeasures' in the `Comportability Definition and Specification <https://opentitan.org/book/doc/contributing/hw/comportability/index.html#security-countermeasures>`_ documentation section).
The mapping between security countermeasures and coverpoints that demonstrate it being used is given below.
* ``cp_fetch_enable`` - Fetch enabled and disabled via top-level ``fetch_enable_i`` input.
Cross Coverage
--------------
Much of the more complex behaviour lies at the combination of the individual microarchitectural behaviours above.
Cross coverage is used to capture that.
Crosses listed below are ones that don't already fit into the above categories.
There are some broad crosses containing many bins aiming to capture all combinations of some generalised behaviours as well as some more specific ones to capture all combinations of behaviours focused on a particular area.
Cross coverage will be intentionally broad.
Where it is proving hard to hit particular bins they will be reviewed in more detail to determine if they're impossible to hit or if simply hard to hit and whether hitting them provides meaningful gains to verification quality.
Excluded bins will either become illegal bins (where they are impossible to hit, so a failure will be seen if they are hit) or ignore bins (where they don't factor into coverage statistics).
There must be a documented reason a particular bin is added to the illegal or ignore bins.
* ``pipe_cross`` - Instruction Categories x Pipeline stage states across IF, ID/EX and WB
* Covers all possibilities of instruction combinations that could fill the pipeline. State only for IF/WB suffices to cover this as all the interesting per instruction behaviour occurs in ID/EX.
* All bins containing instruction categories other than **None** ignored when ID/EX stage is empty.
* ``priv_mode_instr_cross`` - Instructions Categories x ID/EX Privilege level
* ``stall_cross`` - Instruction Categories x Stall Categories
* Illegal bins will be used to exclude instruction and stall categories that cannot occur.
* ``wb_reg_no_load_hz_instr_cross`` - Instruction Categories x Hazards
* ``stall_cross`` covers the RAW load hazard (as it produces a LdHz stall).
* RAW hazard between load/store requires no cross coverage as it's only seen for load and store instructions so the single coverpoint suffices.
* ``debug_instruction_cross`` - Instruction Categories x Debug Mode
* ``controller_instr_cross`` - Instruction Categories x Controller state transitions of interest
* ``interrupt_taken_instr_cross``, ``debug_entry_if_instr_cross``, ``pipe_flush_instr_cross`` - Interrupt taken/Debug mode entry/Pipe flush x instruction unstalled x instruction category
* Three separate cross coverage groups: one for interrupt, debug and pipe flush.
* Covers all instruction categories being interrupted/entering debug mode/flushing the pipeline both where this occurs during a stall and when it occurs just when they've unstalled.
* ``exception_stall_instr_cross`` - PMP exception x load/store error exception x instruction category x stall type x unstalled x irq pending x debug req
* Large cross to cover all possibilities of combinations between interrupt, debug and exceptions for all instruction categories across all stall behaviours.
* ``pmp_iside_priv_bits_cross``, ``pmp_iside2_priv_bits_cross``, ``pmp_dside_priv_bits_cross``, PMP regions x permissions x access fail/pass x privilege level
* Three crosses, one for each PMP channel (instruction, instruction 2 and data).
* ``dummy_instr_config_cross`` - Dummy Instruction Type x Dummy Instruction Insertion Frequency to explore all possible configurations.
* ``rf_ecc_err_cross`` - ECC Error on Port A x ECC Error on Port B to explore all possible combinations of reported ECC errors.
* ``debug_req_dummy_instr_{if,id,wb}_stage_cross`` - The IF, ID/EX, or WB stage handles a dummy instruction while a debug request arrives.
* ``irq_pending_dummy_instr_{if,id,wb}_stage_cross`` - The IF, ID/EX, or WB stage handles a dummy instruction while an IRQ is pending.
``mseccfg`` is specified in the Trusted Execution Environment (TEE) working group proposal `PMP Enhancements for memory access and execution prevention on Machine mode (Smepmp) version 0.9.3 <https://github.com/riscv/riscv-tee/blob/61455747230a26002d741f64879dd78cc9689323/Smepmp/Smepmp.pdf>`_, which gives the full details of it's functionality including the new PMP behaviour when ``mseccfg.MML`` is set.
Note that the reset value means PMP behavior out of reset matches the RISC-V Privileged Architecture.
A write to ``mseccfg`` is required to change it.
Note ``mseccfgh`` reads as all 0s and ignores all writes.
Any access to ``mseccfg`` or ``mseccfgh`` when using an Ibex configuration without PMP (``PMPEnable`` is 0) will trigger an illegal instruction exception.
.._csr-tselect:
Trigger Select Register (tselect)
@ -491,8 +526,8 @@ Reset Value: ``0x0000_0000``
Scratch register to be used by the debug module.
Accessible in Debug Mode only.
CPU Control Register (cpuctrl)
------------------------------
CPU Control and Status Register (cpuctrlsts)
--------------------------------------------
CSR Address: ``0x7C0``
@ -505,6 +540,21 @@ Other bit fields read as zero.
Ibex offers support for execution-based debug according to the `RISC-V Debug Specification <https://riscv.org/specifications/debug-specification/>`_, version 0.13.
Ibex offers support for execution-based debug according to the `RISC-V Debug Specification <https://github.com/riscv/riscv-debug-spec/blob/0.13-test-release/riscv-debug-spec.pdf>`_, version 0.13.
@ -50,7 +50,8 @@ To enable interrupts, both the global interrupt enable (MIE) bit in the ``mstatu
For more information, see the :ref:`cs-registers` documentation.
If multiple interrupts are pending, they are handled in the priority order defined by the RISC-V Privileged Specification, version 1.11 (see Machine Interrupt Registers, Section 3.1.9).
The highest priority is given to the interrupt with the highest ID, except for timer interrupts, which have the lowest priority.
The fast interrupts have a platform defined priority.
In Ibex they take priority over all other interrupts and between fast interrupts the highest priority is given to the interrupt with the lowest ID.
The NMI is enabled independent of the values in the ``mstatus`` and ``mie`` CSRs, and it is not visible through the ``mip`` CSR.
It has interrupt ID 31, i.e., it has the highest priority of all interrupts and the core jumps to the trap-handler base address (in ``mtvec``) plus 0x7C to handle the NMI.
@ -62,6 +63,32 @@ It is assumed that the interrupt handler signals completion of the handling rout
In Debug Mode, all interrupts including the NMI are ignored independent of ``mstatus``.MIE and the content of the ``mie`` CSR.
.._internal-interrupts:
Internal Interrupts
-------------------
Some events produce an 'internal interrupt'.
An internal interrupt produces an NMI (using the same vector as the external NMI) with ``mcause`` and ``mtval`` being set to indicate the cause of the internal interrupt.
The external NMI takes priority over all internal interrupts.
Entering the handler for an internal interrupt automatically clears the internal interrupt.
Internal interrupts are considered to be non-recoverable in general.
Specific details of how an internal interrupt relates to the event that triggers it are listed below.
Given these details it may be possible for software to recover from an internal interrupt under specific circumstances.
The possible ``mcause`` values for an internal interrupt are listed below:
@ -98,6 +125,9 @@ Ibex can trigger an exception due to the following exception causes:
The illegal instruction exception, instruction access fault, LSU error exceptions and ECALL instruction exceptions cannot be disabled and are always active.
Note that Ibex cannot generated an 'instruction address misaligned' exception as all configurations implement the 'C' extension.
Under the RISC-V architecture it is simply not possible to branch or otherwise start executing from a PC that isn't 16-bit aligned.
So with 'C' implemented all possible PCs are appropriately aligned.
Nested Interrupt/Exception Handling
-----------------------------------
@ -147,3 +177,19 @@ The purpose of the nonstandard ``mstack`` CSRs in Ibex is only to support recove
These CSRs are not accessible by software.
While handling an NMI, all interrupts are ignored independent of ``mstatus``.MIE.
Nested NMIs are not supported.
.._double-fault-detect:
Double Fault Detection
----------------------
Ibex has a mechanism to detect when a double fault has occurred.
A double fault is defined as a synchronous exception occurring whilst handling a previous synchronous exception.
The ``cpuctrl`` custom CSR has fields to provide software visibility and access to this mechanism.
When a synchronous exception occurs, Ibex sets ``cpuctrl``.sync_exception_seen.
Ibex clears ``cpuctrl``.sync_exception_seen when ``mret`` is executed.
If a synchronous exception occurs whilst ``cpuctrl``.sync_exception_seen is set, a double fault has been detected.
When a double fault is detected, the ``double_fault_seen_o`` output is asserted for one cycle and ``cpuctrl``.double_fault_seen is set.
Note that writing the ``cpuctrl``.double_fault_seen field has no effect on the ``double_fault_seen_o`` output.
If ICacheScramble parameter is enabled, all RAM primitives are replaced with scrambling RAM primitive.
For more information about how scrambling works internally (see :file:`vendor/lowrisc_ip/ip/prim/doc/prim_ram_1p_scr.md`).
Interface for receiving scrambling key follows req / ack protocol.
Ibex first requests a new ephemeral key by asserting the request (``scramble_req_o``) and when a fresh valid key is indicated by ``scramble_key_valid_i``, it deasserts the request.
Note that in current implementation, it is assumed req/ack protocol is synchronized before arriving to Ibex top level.
.._icache-scramble-key:
Scramble Key Renewal
^^^^^^^^^^^^^^^^^^^^
To get a new scrambling key execute a FENCE.I instruction.
With a new scrambling key the existing cache contents are effectively corrupt and will be invalidated by the FENCE.I.
Following a FENCE.I cache lookups will always miss until the invalidation is complete.
This allows CPU fetch and execution to continue using direct memory accesses whilst the scramble key request and cache invalidation proceeds in the background.
Should a second FENCE.I be executed before the first invalidation completes there are two possibilities
1. The request for a new scramble key is still in progress.
As a new request cannot begin whilst one is in progress the FENCE.I is ignored.
2. The request for a new scramble key has completed and the invalidation is in progress.
The invalidation stops and a new scramble key requested and the process starts over.
To guarantee a new scramble key ensure the ``ic_scr_key_valid`` bit in the ``cpuctrlsts`` CSR is set before executing the FENCE.I instruction.
Sub Unit Description
--------------------
@ -158,6 +184,8 @@ The remaining data from hits is buffered in the fill buffer data storage and sup
To deal with misalignment caused by compressed instructions, there is a 16bit skid buffer to store the upper halfword.
.._icache-ecc:
Cache ECC protection
^^^^^^^^^^^^^^^^^^^^
@ -187,6 +215,7 @@ Any error (single or double bit) in any RAM will effectively cancel a cache hit
The request which observed an error will fetch it's data from the main instruction memory as normal for a cache miss.
The cache index and way (or ways) with errors are stored in IC1, and a cache write is forced the next cycle to invalidate that line.
Lookup requests will be blocked in IC0 while the invalidation write is performed.
If an ECC error is seen a minor alert will be signaled.
Cache invalidation
^^^^^^^^^^^^^^^^^^
@ -204,7 +233,7 @@ This isn't an attempt to describe the cache's performance characteristics.
The I$ has a single clock (``clk_i``) and asynchronous reset (``rst_ni``).
Data is requested from the instruction memory with the ports prefixed by ``instr_``. These work as described in :ref:`instruction-fetch`.
Note that there's one extra port on the I$, which doesn't appear at the ``ibex_core`` top-level.
Note that there's one extra port on the I$, which doesn't appear at the ``ibex_top`` top-level.
This is ``instr_pmp_err_i``.
If the PMP block disallows a fetch for a certain address, it will squash the outgoing memory request entirely and set ``instr_pmp_err_i``.
If that happens, the cache drops ``instr_req_o`` and stops making any further requests for that cache line.
The Arithmetic Logic Logic (ALU) is a purely combinational block that implements operations required for the Integer Computational Instructions and the comparison operations required for the Control Transfer Instructions in the RV32I RISC-V Specification.
The Arithmetic Logic Unit (ALU) is a purely combinational block that implements operations required for the Integer Computational Instructions and the comparison operations required for the Control Transfer Instructions in the RV32I RISC-V Specification.
Other blocks use the ALU for the following tasks:
* Mult/Div uses it to perform addition as part of the multiplication and division algorithms
@ -64,46 +64,45 @@ Other blocks use the ALU for the following tasks:
* It computes memory addresses for loads and stores with a Reg + Imm calculation
* The LSU uses it to increment addresses when performing two accesses to handle an unaligned access
BitManipulation Extension
Support for the `RISC-V Bit Manipulation Extension (draft version 0.92 from November 8, 2019) <https://github.com/riscv/riscv-bitmanip/blob/master/bitmanip-0.92.pdf>`_ is optional. [#B_draft]_
Bit-Manipulation Extension
Support for the `RISC-V Bit-Manipulation Extension version 1.0.0 <https://github.com/riscv/riscv-bitmanip/releases/download/1.0.0/bitmanip-1.0.0-38-g865e7a7.pdf>`_ and `draft version 0.93 from January 10, 2021 <https://github.com/riscv/riscv-bitmanip/blob/master/bitmanip-0.93.pdf>`_ is optional. [#B_draft]_
It can be enabled via the enumerated parameter ``RV32B`` defined in :file:`rtl/ibex_pkg.sv`.
By default, this parameter is set to "ibex_pkg::RV32BNone" to disable the bitmanipulation extension.
By default, this parameter is set to "ibex_pkg::RV32BNone" to disable the bit-manipulation extension.
There are two versions of the bit manipulation extension available:
The balanced implementation comprises a set of sub-extensions aiming for good benefits at a reasonable area overhead.
There are three versions of the bit-manipulation extension available:
The balanced version comprises a set of sub-extensions aiming for good benefits at a reasonable area overhead.
It can be selected by setting the ``RV32B`` parameter to "ibex_pkg::RV32BBalanced".
The full implementation comprises all 32 bit instructions defined in the extension.
This version can be selected by setting the ``RV32B`` parameter to "ibex_pkg::RV32BFull".
The following table lists the implemented instructions in each version.
The OTEarlGrey version comprises all sub-extensions except for the Zbe.
This version can be selected by setting the ``RV32B`` parameter to "ibex_pkg::RV32BOTEarlGrey".
The full version comprises all sub-extensions and can be selected by setting the ``RV32B`` parameter to "ibex_pkg::RV32BFull".
The following table gives an overview of which sub-extensions are implemented in each version and of which instructions are implemented as multi-cycle instructions.
Multi-cycle instructions are completed in 2 cycles.
All remaining instructions complete in a single cycle.
The implementation of the B-extension comes with an area overhead of 1.8 to 3.0 kGE for the balanced version and 6.0 to 8.7 kGE for the full version.
That corresponds to an approximate percentage increase in area of 9 to 14 % and 25 to 30 % for the balanced and full versions respectively.
The ranges correspond to synthesis results generated using relaxed and maximum frequency targets respectively.
The designs have been synthesized using Synopsys Design Compiler targeting TSMC 65 nm technology.
The implementation of the Bit-Manipulation Extension comes with an area overhead of 2.7 kGE for the balanced version, 6.1 kGE for the OTEarlGrey version, and 7.5 kGE for the full version.
These numbers were obtained by synthesizing the design with Yosys and relaxed timing constraints.
.._mult-div:
@ -173,11 +172,9 @@ See :ref:`load-store-unit` for more details.
..rubric:: Footnotes
..[#B_draft] Ibex fully implements draft version 0.92 of the RISC-V Bit Manipulation Extension.
This extension may change before being ratified as a standard by the RISC-V Foundation.
..[#B_draft] Ibex fully implements the ratified version 1.0.0 of the RISC-V Bit-Manipulation Extension including the Zba, Zbb, Zbc and Zbs sub-extensions.
In addition, Ibex also supports the remaining Zbe, Zbf, Zbp, Zbr and Zbt sub-extensions as defined in draft version 0.93 of the RISC-V Bit-Manipulation Extension.
Note that the latter sub-extensions may change before being ratified as a standard by the RISC-V Foundation.
Ibex will be updated to match future versions of the specification.
Prior to ratification this may involve backwards incompatible changes.
Additionally, neither GCC or Clang have committed to maintaining support upstream for unratified versions of the specification.
..[#B_zb_tmp] The sign-extend instructions `sext.b/sext.h` are defined but not unambiguously categorized in draft version 0.92 of the extension.
Temporarily, they have been assigned a separate Z-extension (Zb_tmp) both in Ibex and the RISCV-DV random instruction generator used to verify the bit manipulation instructions in Ibex.
The core can optionally generate and verify check bits sent alongside the data for memory accesses.
Checkbits are generated and checked using an inverted 39/32 Hsaio code (see :file:`vendor/lowrisc_ip/ip/prim/rtl/prim_secded_inv_39_32_enc.sv`).
An :ref:`internal interrupt<internal-interrupts>` will be generated and a bus major alert signalled if there is a mismatch.
Where load data has bad checkbits the write to the load's destination register will be suppressed.
Ibex checks the integrity against the response data for both loads and stores.
For stores the response data is otherwise ignored so the data can be any value provided the integrity is valid (``data_rdata_intg_i`` must match with ``data_rdata_i``).
It is recommended for write responses some fixed value is placed on ``data_rdata_i`` and ``data_rdata_intg_i`` by the memory system Ibex is connected to in configurations where integrity is used.
This feature is only used if the core is configured with the SecureIbex parameter set.
For all other configurations, the integrity signals can be ignored.
The Physical Memory Protection (PMP) unit implements region-based memory access checking in-accordance with the RISC-V Privileged Specification, version 1.11.
The Physical Memory Protection (PMP) unit implements region-based memory access checking in-accordance with the RISC-V Privileged Specification, version 1.12 and implements the `PMP Enhancements for memory access and execution prevention on Machine mode (Smepmp) version 1.0 <https://github.com/riscv/riscv-tee/blob/191b563b08b31cc2974d604a3b670d8666a2e093/Smepmp/Smepmp.pdf>`_ extension.
The following configuration parameters are available to control PMP checking:
The PMP granularity parameter is used to reduce the size of the address matching comparators by increasing the minimum region size.
When the granularity is greater than zero, NA4 mode is not available and will be treated as OFF mode.
.._pmp-enhancements:
PMP Enhancements
----------------
These are described in more detail in `PMP Enhancements for memory access and execution prevention on Machine mode (Smepmp) version 1.0 <https://github.com/riscv/riscv-tee/blob/191b563b08b31cc2974d604a3b670d8666a2e093/Smepmp/Smepmp.pdf>`_.
If Ibex is configured to include PMP (PMPEnable is not zero) the PMP enhancements are always included.
Use of the enhanced behavior is optional, if no writes to ``mseccfg`` occur PMP behavior will remain exactly as if Smepmp was not implemented.
The enhancements add:
* A new CSR ``mseccfg`` providing functionality to allow locked regions to be modified and to implement default deny for M-mode accesses.
* New PMP region configurations which are U-Mode or M-Mode accessible only with varying read/write/execute settings along with some shared U and M mode accessible configurations.
These new configurations supersede the original ones and are enabled via ``mseccfg``.
Custom Reset Values
-------------------
By default all PMP CSRs (include ``mseccfg``) are reset to 0.
Some applications may want other reset values.
Default reset values are defined in :file:`ibex_pkg.sv`.
An implementation can either modify this file or pass custom reset values as a module parameter.
Debug Mode
----------
In debug mode, the PMP allows all accesses to addresses of the Debug Module, as defined by the `DmBaseAddr` and `DmAddrMask` module parameters.
This is mandated by the RISC-V Debug Specification (v1.0.0).
@ -9,8 +9,9 @@ All features are runtime configurable via bits in the **cpuctrl** custom CSR.
Outputs
-------
Ibex has two alert outputs for signalling security issues.
The major alert (**alert_major_o**) indicates a critical security issue from which the core cannot recover.
Ibex has three alert outputs for signalling security issues.
The internal major alert (**alert_major_internal_o**) indicates a critical security issue from which the core cannot recover which was detected internally in `ibex_top`.
The bus major alert (**alert_major_internal_o**) indicates a critical security issue from which the core cannot recover which was detected on incoming bus data.
The minor alert (**alert_minor_o**) indicates potential security issues which can be monitored over time by a system.
Data Independent Timing
@ -21,10 +22,20 @@ This makes it more difficult for an external observer to infer secret data by ob
In Ibex, most instructions already execute independent of their input operands.
When data-independent timing is enabled:
* Branches execute identically regardless of their taken/not-taken status
* Early completion of multiplication by zero/one is removed
* Early completion of divide by zero is removed
Note that data memory operations to unaligned addresses might result in multiple bus accesses being made.
This in turn could expose information about the address as a timing side-channel.
It is therefore recommended to stick to aligned memory accesses when using this feature for critical code regions.
When Ibex is configured to use an instruction cache, stalls on instruction fetch can see variable latency (depending on whether or not they hit in the cache).
Software that has need of data independent timing may wish to disable the instruction cache to avoid this or to carefully analyse execution to determine if variable latency introduced by the cache causes unacceptable leakage.
The instruction cache is controlled by the **icache_enable** bit in the **cpuctrl** register.
Precise details of fetch timing will depend upon the memory system Ibex is connected to.
Dummy Instruction Insertion
---------------------------
@ -49,18 +60,51 @@ The frequency of injected instructions can be tuned via the **dummy_instr_mask**
Other values of **dummy_instr_mask** are legal, but will have a less predictable impact.
The interval between instruction insertion is randomized in the core using an LFSR.
The initial seed and output permutation for this LFSR can be set using parameters from the top-level of Ibex.
Sofware can periodically re-seed this LFSR with true random numbers (if available) via the **secureseed** CSR.
This will make the insertion interval of dummy instructions much harder for an attacker to predict.
Note that the dummy instruction feature inserts multiply and divide instructions.
The core must be configured with a multiplier (`RV32M != ibex_pkg::RV32MNone`) or errors will occur using this feature.
Bus integrity checking
----------------------
Extra signals are available alongside the instruction and data side memory channels to support bus integrity checking.
When the SecureIbex parameter is set, incoming data will be checked against the supplied checkbits.
An :ref:`internal interrupt<internal-interrupts>` will be generated and a bus major alert signalled if there is a mismatch.
Where load data has bad checkbits the write to the load's destination register will be suppressed.
Write data can be checked against the supplied checkbits at its destination to confirm integrity.
Register file ECC
-----------------
When Ibex is configured with the SecureIbex parameter, ECC checking is added to all reads of the register file.
This can be useful to detect fault injection attacks since the register file covers a reasonably large area.
No attempt is made to correct detected errors, but an external alert is raised for the system to take action.
No attempt is made to correct detected errors, but an internal major alert is signaled for the system to take action.
Register file write enable glitch detection
-------------------------------------------
When Ibex is configured with the SecureIbex parameter, the write enable signal into the register file is checked to be one-hot.
This can be useful to detect fault injection attacks.
No attempt is made to correct detected errors, but an internal major alert is signaled for the system to take action.
Register file read addresses glitch detection
-------------------------------------------
When Ibex is configured with the SecureIbex parameter, the read addresses provided to the register file are converted to one-hot encoded signals, and a one-hot encoded MUX is used to select the register to read from.
By using one-hot encoding checkers, glitches in the one-hot encoded signals are detected.
Bit-flips inside the plain read addresses before the one-hot conversion happens are detected by the dual core lockstep.
This can be useful to detect fault injection attacks.
No attempt is made to correct detected errors, but an internal major alert is signaled for the system to take action.
ICache ECC
----------
The ICache can be configured with ECC protection.
When an ECC error is detected a minor alert is signaled.
See :ref:`icache-ecc` for more information.
Hardened PC
-----------
@ -68,11 +112,22 @@ Hardened PC
This adds a check that the PC driven from the IF stage has not been modified.
A check is asserted that the current IF stage PC equals the previous PC plus the correct increment.
The check is disabled after branches and after reset.
If a mismatch is detected, a major alert is signaled.
If a mismatch is detected, an internal major alert is signaled.
Shadow CSRs
-----------
Certain critical CSRs (`mstatus`, `mtvec`, `cpuctrl`, `pmpcfg` and `pmpaddr`) have extra glitch detection enabled.
This creates a second copy of the register which stores a complemented version of the main CSR data.
A constant check is made that the two copies are consistent, and a major alert is signalled if not.
A constant check is made that the two copies are consistent, and an internal major alert is signalled if not.
Note that this feature is not currently used when the SecureIbex parameter is set due to overlap with dual core lockstep.
Dual core lockstep
------------------
This configuration option instantiates a second copy of the core logic, referred to as the shadow core.
The shadow core executes using a delayed version of all inputs supplied to the main core.
All outputs of the shadow core are compared against a delayed version of the outputs of the main core.
Any mismatch between the two sets of outputs will trigger an internal major alert.
Note that the register file and icache RAMs are not duplicated since these units are covered by ECC protection.
This testplan is a work in progress still being implemented so this document may not match the implemented verification in the repository.
Test Plan
=========
Goals
-----
* Verify compliance with all the RISC-V specifications Ibex supports.
* Verify Ibex's security hardening features.
* Ensure correct functionality is maintained across all possible behaviours of external interfaces (interrupts, memory responses, debug requests etc).
* Hit all functional coverage points, described in :ref:`coverage-plan`.
Testbench Architecture
----------------------
..figure:: images/tb2.svg
:alt:Testbench Architecture
Architecture of the UVM testbench for Ibex core
Ibex utilises a co-simulation checking approach described in detail in :ref:`cosim`.
With the co-simulation system all instructions Ibex executes and all external events such as an interrupts or memory errors are fed to a golden model.
The results of every instruction execution and every memory access are crossed checked against the golden model with any mismatches resulting in a test failure.
The aim is to check all possible externally observable behaviours of ``ibex_top`` against the golden model.
The golden model used is the `Spike RISC-V ISS <https://github.com/riscv-software-src/riscv-isa-sim>`_.
The testbench uses UVM.
It consists of 3 agents:
Co-simulation Agent:
This has multiple monitors.
One monitors the RVFI interface which provides details of retired instructions.
The other monitors relate to fetched instructions and instruction memory errors; more details are provided in :ref:`coverage-plan`.
Additionally it connects to the monitor of the Memory Interface Agent for the instruction and data side via analysis ports.
The monitored transactions are used by a scoreboard to provide information to the co-simulation system allowing it to step the golden model and check its execution and memory activity against Ibex's behaviour.
Memory Interface Agent
This provides a driver and a monitor for the :ref:`Ibex Memory Interface Protocol<lsu-protocol>`.
The driver provides fully randomised and configurable timings for responses and randomisation of error responses.
Two agents are instantiated; one for the data memory interface the other for the instruction memory interface.
Read data for memory responses is provided from a backing memory; write requests update the contents of the backing memory.
This is separate from the memory used by the golden model in the co-simulation agent.
The contents of these two memories will be identical unless there is a mismatch resulting in a failure.
The backing memory is held in a memory model as a separate UVM component.
The two agents use the same backing memory so they have a coherent view of memory.
IRQ Agent
This provides a driver and a monitor for the IRQ interface.
It provides randomised interrupt stimulus to Ibex when a test requests it.
Constraints can be used to control types of interrupts generated (e.g. NMI or not) and whether multiple interrupts should be raised together.
Debug and reset signals are a single wire each so do not have a dedicated agent.
Instead any sequence that wishes to use them will directly manipulate them via a virtual interface
The testbench instantiates the agents described above along with the memory model used by both the data and instruction side memory agents.
A test consists of executing a pre-built binary (which is loaded into the memory model at the start of the test via backdoor accesses) along with configuring agents to provide appropriate stimulus for the test.
Some tests may use the agents to generate stimulus at particular times (e.g. interrupts).
A test may perform additional checking on top of the co-simulation golden model comparison where appropriate (e.g. ensuring a raised interrupt has caused an exception).
Stimulus Strategy
-----------------
Stimulus falls into two categories:
* Instructions to execute: These are generated by the `RISC-V DV random instruction <https://github.com/google/riscv-dv>`_ generator and provided to the testbench via a raw binary file.
* Activity on external interfaces.
Instructions are generated ahead of time so the test has no control over them at run time.
All external interfaces have their stimulus generated at run time so can be controlled by the test.
It is the responsibility of the regression run environment to ensure generated instructions are matched with appropriate tests (e.g. ensuring an exception handler is present where interrupts are expected).
Stimulus generation will use a coverage based approach.
Stimulus is developed based upon the :ref:`coverage-plan`.
Where coverage is not being hit stimulus will be added to hit it.
Tests
-----
As with stimulus, test sequence development uses a coverage based approach.
Tests will be added such that all coverage in the :ref:`coverage-plan` can be hit.
Not all the details of specific tests will be documented here.
The test list (`dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml <https://github.com/lowRISC/ibex/blob/master/dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml>`_), provides an exhaustive list of all tests along with a brief description of what the test does.
A test will execute a binary whilst running zero or more sequences that provide stimulus to external interfaces of ``ibex_top``.
As the memory interfaces are all driven by Ibex, with any testbench generated activity in response to a request from Ibex, they do not require explicit sequences run by the test.
Instead the test can configure the randomisation of memory delays as it wishes.
Memory errors can be configured to always occur in statically defined areas of the memory map or a sequence can be used to inject them via the memory interface agent.
The following sequences are available for tests to use.
Each sequence is derived from a base sequence which provides controls to repeat the sequence at fixed or random internals, forever or after a random number of repeats.
Full details can be found in `dv/uvm/core_ibex/tests/core_ibex_seq_lib.sv <https://github.com/lowRISC/ibex/blob/master/dv/uvm/core_ibex/tests/core_ibex_seq_lib.sv>`_.
* ``irq_raise_seq`` - Raises one or more interrupts.
The testbench binary can write to a special memory location to acknowledge the interrupt and cause it to drop.
Alternatively the testbench can drop it after a given amount of time.
* ``debug_seq`` - Raises the external debug request.
The testbench binary can write to a special memory location to acknowledge the request and cause it to drop.
Alternatively the testbench can drop it after a given amount of time.
* ``mem_error_seq`` - Injects a memory error in either the instruction side or data side, so the next access results in an error response.
The module ``ibex_tracer`` can be used to create a log of the executed instructions.
It is used by ``ibex_core_tracing`` which forwards the `RVFI signals <https://github.com/SymbioticEDA/riscv-formal/blob/master/docs/rvfi.md>`_ to the tracer (see also :ref:`rvfi`).
It is used by ``ibex_top_tracing`` which forwards the `RVFI signals <https://github.com/SymbioticEDA/riscv-formal/blob/master/docs/rvfi.md>`_ to the tracer (see also :ref:`rvfi`).
@ -17,6 +19,14 @@ At a high level, this testbench uses the open source `RISCV-DV random instructio
simple memory model, stimulates the Ibex core to run this program in memory, and then compares the
core trace log against a golden model ISS trace log to check for correctness of execution.
Verification maturity is tracked via :ref:`verification_stages` that are `defined by the OpenTitan project <https://opentitan.org/book/doc/project_governance/development_stages.html#hardware-verification-stages-v>`_.
Ibex has achieved **V2S** for the ``opentitan`` configuration, broadly this means verification almost complete (over 90% code and functional coverage hit with over 90% regression pass rate with test plan and coverage plan fully implemented) but not yet closed.
Nightly regression results, including a coverage summary and details of test failures, for the ``opentitan`` Ibex configuration are published at https://ibex.reports.lowrisc.org/opentitan/latest/report.html. Below is a summary of these results:
In order to run the co-simulation flow, you'll need:
- A SystemVerilog simulator that supports UVM.
The flow is currently tested with VCS.
- A RISC-V instruction set simulator, such as Spike_ or OVPsim_.
Note that when building Spike the ``--enable-commitlog`` and ``--enable-misaligned`` options must be passed to the ``configure`` script.
- The Spike RISC-V instruction set simulator
lowRISC maintains a `lowRISC-specific Spike fork <LRSpike_>`_, needed to model:
+ Cosimulation (needed for verification)
+ Some custom CSRs
+ Custom NMI behavior
Ibex verification should work with the Spike version that named ``ibex_cosim``.
Spike must be built with the ``--enable-commitlog`` and ``--enable-misaligned`` options.
``--enable-commitlog`` is needed to produce log output to track the instructions that were executed.
``--enable-misaligned`` tells Spike to simulate a core that handles misaligned accesses in hardware (rather than jumping to a trap handler).
If it is desired to simulate the core with the Icache enabled, a `lowRISC-specific branch of Spike <https://github.com/lowRISC/riscv-isa-sim/tree/ibex>`_ must be used.
Ibex supports v0.92 of the Bitmanip specification.
The ``master`` branch of Spike_ and OVPSim_ may support a different version.
It is recommended the `lowRISC-specific branch of Spike <https://github.com/lowRISC/riscv-isa-sim/tree/ibex>`_ is used when using a configuration with Bitmanip to ensure the simulated version of the Bitmanip specification matches with the RTL implemented version.
Note that Ibex used to support the commercial OVPsim simulator.
This is not currently possible because OVPsim doesn't support the co-simulation approach that we use.
- A working RISC-V toolchain (to compile / assemble the generated programs before simulating them).
Either download a `pre-built toolchain <riscv-toolchain-releases_>`_ (quicker) or download and build the `RISC-V GNU compiler toolchain <riscv-toolchain-source_>`_.
For the latter, the Bitmanip patches have to be manually installed to enable support for the Bitmanip draft extension.
For further information, checkout the `Bitmanip Extension on GitHub <bitmanip_>`_ and `how we create the pre-built toolchains <bitmanip-patches_>`_.
@ -115,16 +135,12 @@ to tell the RISCV-DV code where to find them:
Ibex is being verified as part of the `OpenTitan <https://www.opentitan.org>`_ project and follows the `verification stages used in OpenTitan <https://opentitan.org/book/doc/project_governance/development_stages.html#hardware-verification-stages-v>`_.
The current verification stage of the 'opentitan' configuration of Ibex is **V2S**.
The full definition of V2S can be found at the `OpenTitan V2 <https://opentitan.org/book/doc/project_governance/checklist/index.html#v2>`_ and `OpenTitan V2S <https://opentitan.org/book/doc/project_governance/checklist/index.html#v2s>`_ checklists.
Other Ibex configurations do not have a formal verification stage at present.
| Tests | SIM_ALL_TESTS_PASSING | Complete | Note the ``riscv_assorted_traps_interrupts_debug`` test sees many failures (but does have some seeds that pass). |
| | | | The test attempts to generally combine many different stimuli and under OpenTitan classification would be considered a V3 test. |
| Regression | SIM_NIGHTLY_REGRESSION_V2 | Complete | Regression run in GitHub Actions only accessible to OpenTitan members. |
| | | | Publicly viewable reports on the `OpenTitan regression dashboard <https://reports.opentitan.org/hw/top_earlgrey/dv/summary/latest/report.html>`_ are planned for V3. |
**PMP Testing Note**: A large number of iterations of ``pmp_full_random_test`` are required to meet coverage goals and timed out tests must be included in the coverage collection.
This is because of the large cross bins for PMP that aim to explore the full space of possible behaviour.
The current strategy of random generation is very inefficient at exploring this space.
It is also complex to write a randomly generated test that can deal with all possible scenarios without hitting a double faulting or time out scenarios (e.g. consider a random configuration that gives you no executable regions and ePMP modes like machine mode lockdown and machine mode whitelist policy).
Co-simulation checking is enabled when this test is run (as it is for all block level verification tests) so would detect any incorrect behaviour.
From investigation we are confident the time-outs seen are simply badly performing tests (e.g. very slowly working its way through an instruction block with no execute permissions by attempting to execute one instruction, faulting, trying the next and getting the same result over and over).
For future work we will explore more efficient strategies for exploring this space as well as employing formal methods to achieve full verification closure.
The :ref:`security features Ibex implements <security>` are given specific security countermeasure names in OpenTitan (see 'Security Countermeasures' in the `Comportability Definition and Specification <https://opentitan.org/book/doc/contributing/hw/comportability/index.html#security-countermeasures>`_ documentation section).
Each countermeasure has a test that exercises it.
The mapping between countermeasures and tests is given below
| SCRAMBLE.KEY.SIDELOAD | ``riscv_rand_instr_test`` in Ibex DV. |
| | This test executes ``FENCE.I`` which rotates the scramble key. |
| | The ``rv_core_ibex_icache_invalidate_test`` OpenTitan top-level test covers assertions within the OpenTitan specific ``rv_core_ibex`` wrapper that check that a ``FENCE.I`` results in an icache scramble key request and that the returned key is correctly supplied to the scrambling memory primitives. |
| CORE.DATA_REG_SW.SCA | ``dit_test`` directed test run against simple system cosimulation. |
| | The test runs functions that whose timing is data dependent with data independent timing disabled. |
| | It passes where the runs with data independent timing enabled all execute in the same amount of time and the runs without it enabled take different amounts of time. |
| ICACHE.MEM.SCRAMBLE | No explicit testing, the scrambling memory primitive is seperately verified within OpenTitan. |
| | Assertions in the OpenTitan specific ``rv_core_ibex`` wrapper ensure a newly requested scramble key is correctly applied to the scrambling memories. |
| | The ``rv_core_ibex_icache_invalidate_test`` OpenTitan top-level test covers assertions within the OpenTitan specific ``rv_core_ibex`` wrapper that check that a ``FENCE.I`` results in an icache scramble key request and that the returned key is correctly supplied to the scrambling memory primitives. |
@ -25,10 +25,8 @@ The concierge duties rotate between several core developers on a weekly basis.
You can find today's concierge on duty in a `public calendar <https://calendar.google.com/calendar/embed?src=lowrisc.org_s0pdodkddnggdp40jusjij27h4%40group.calendar.google.com>`_.
For detailed documention on how Ibex's verification works, please have a look at [the dedicated documentation page](https://ibex-core.readthedocs.io/en/latest/03_reference/verification.html).
This README provides a quick start guide to get things running.
## Prerequisites
You need to have Xcelium available on your machine.
You can check whether you have it available by running: `xrun --verison`
You also need Spike to be able to compare to in the cosimulation.
We use a lowRISC specific Spike which you can find [on its own GitHub page](https://github.com/lowRISC/riscv-isa-sim/tree/ibex_cosim).
Some quick build instructions from within the `riscv-isa-sim` repo:
You will need the [RISC-V toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain).
You'll need to add this to your path and then also set the following environment variables:
```bash
export RISCV_GCC=riscv32-unknown-elf-gcc
export RISCV_OBJCOPY=riscv32-unknown-elf-objcopy
```
## Running tests
To run tests you can make variations of the following command, where you replace `$TEST_NAME` with the test (or a series of comma-separated tests) that you would like to run as specified in `dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml`:
```bash
make --keep-going IBEX_CONFIG=opentitan SIMULATOR=xlm ISS=spike ITERATIONS=1 SEED=1 TEST=$TEST_NAME WAVES=0 COV=0