[otbn] Make stalling more explicit in instruction definitions This is prompted by the fact that we couldn't properly model things like faulting calls to BN.LID. We need to do some of the instruction body on the first cycle (to spot that an address is bogus). However, we can't run everything on the first cycle. For example accesses of the RND WSR/CSR can't do their work until the data is available, and this data isn't supplied by the Python simulator. Solve the problem by splitting the execution over multiple calls to the execute() method, using Python's "yield" statement to cause the stall. Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/hw/ip/otbn/doc/isa.md b/hw/ip/otbn/doc/isa.md index 0c267e2..3d6dc8a 100644 --- a/hw/ip/otbn/doc/isa.md +++ b/hw/ip/otbn/doc/isa.md
@@ -61,6 +61,9 @@ Memory stores are represented as `DMEM.store_u32(addr, value)` and `DMEM.store_u256(addr, value)`. In all cases, memory values are interpreted as unsigned integers and, as for register accesses, the instruction descriptions are written to ensure that any value stored to memory is representable. +Some instructions can stall for one or more cycles (those instructions that access memory, CSRs or WSRs). +To represent this precisely in the pseudo-code, and the simulator reference model, such instructions execute a `yield` statement to stall the processor for a cycle. + There are a few other helper functions, defined here to avoid having to inline their bodies into each instruction. ```python3 def from_2s_complement(n: int) -> int: