This passes the unmodified TestRIG routine for CHERI Control Flow, which is very promising indeed!
There are some cases that are not covered there, but a lot is covered.
Despite the name, we can end up having a pending_straddle at an "even"
PC (and thus an "odd" pc_start). In this case, we would erroneously
treat it as if pc_start were "even", effectively shifting all the
instruction parcels along by one and duplicating the first one, since
the first element of the parcels vector will be a copy of the straddle's
parcel itself. Instead, we should just ignore pending_straddle when
determining where to start in the parcels vector, as the two are
completely independent, and no longer hard-code that the straddle is
merged with element 0.
This can happen if we predict that the first half of an uncompressed
instruction is a taken branch. We will have the instruction bytes
available, but not the prediction information, so still have to do a
normal Fetch3 redirect in the same manner as an unaligned uncompressed
instruction. We could perhaps special-case with a fast-path (or query
the predictor directly in Fetch3), but it should hit in the TLB and L1
cache, and is probably not common enough to warrant the complexity.
The FreeRTOS-based netboot loader trips up on this as it overwrites
itself with the payload, and thus all the branch prediction still has
many taken branch entries, most of which will not be correct.
Each instruction carries its own PC by this point, so it just duplicates
the PC of the first item in the vector. Moreover, when including a
pending straddle at the head, the PC value was not set to the previous
half's, ie PC-2. We keep pred_next_pc as that's used to determine where
the bundle is predicted to go next, and the duplication avoids having to
dynamically index the vector based on the number of instructions fed to
decode.
We should not use a mkRegU for rg_pending_n_items, as otherwise there is
a chance the epochs for rg_pending_f32d happen to match depending on the
uninitialised values. Instead ensure we always reset with no pending
items.
This includes replacing register read values with nullCap if reading x0, which is generally necessary.
This is more-or-less using a new mechanism which shouldn't actually be necessary if the default value in the register file is nullCap.
(In RVFI_DII, we initialise with the almightyCap instead.)
If we never look at the second instruction in the FIFO from the fetch
unit when successfully renaming the first, we do not end up setting
debug_step and thus we will not halt on the next instruction but some
time later. Instead, check for single-stepping at the end of renaming
the first instruction.
This required makeing the Exception type wider by one.
The actual "inBounds" check is currently implemented in the reorder buffer rows, which duplicates the logic ~80 times (number of outstanding instructions), which isn't ideal, but it's using the quick in-bounds check that only compares the mantissa-sized things.
Also move to SetAddrUnsafe, as is traditional for setting the address of PCC where we do proper checks on branches so we really only have the possibility of executing off the end of the length, and therefore cannot become unrepresentable.
This includes renaming Fifo.bsv to Fifos.bsv to account for a case insensitive file system which confuses this library with FIFO.bsv.
Also this includes an update of the verilator flags that are needed for modern verilator.
Finally, some verilator flag changes for building with LLVM.