[otbn] Teach ISS to generate errors on call stack under/overflow

This is a reasonably large patch because the ISS didn't do any
handling of architectural errors before. We now define a special
exception type (Alert) in the Python and raise it if something goes
wrong. If that happens, it gets caught in OTBNSim.step(), which tells
the state to throw away any changes that were in flight and then to
come to a screeching halt.

The commit also comes with two simple ISS tests, to check that we stop
properly on underflow or overflow. Since the RTL doesn't support this
yet, we'll get mismatches for code that triggers the error (but
hopefully we don't actually have any such code in our testing at the
moment).

Finally, we add the new enum item to the DIF.

Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/hw/ip/otbn/dv/otbnsim/sim/insn.py b/hw/ip/otbn/dv/otbnsim/sim/insn.py
index 5f4ad37..c36791d 100644
--- a/hw/ip/otbn/dv/otbnsim/sim/insn.py
+++ b/hw/ip/otbn/dv/otbnsim/sim/insn.py
@@ -308,15 +308,8 @@
         pass
 
     def execute(self, state: OTBNState) -> None:
-        # INTR_STATE is the interrupt state register. Bit 0 (which is being
-        # set) is the 'done' flag.
-        state.ext_regs.set_bits('INTR_STATE', 1 << 0)
-        # STATUS is a status register. Bit 0 (being cleared) is the 'busy' flag
-        state.ext_regs.clear_bits('STATUS', 1 << 0)
-
-        # As well as the external register, clear an internal 'running' flag to
-        # tell the simulation to stop.
-        state.running = False
+        # Set INTR_STATE.done and STATUS, reflecting the fact we've stopped.
+        state.stop(None)
 
 
 class LOOP(OTBNInsn):