[otbn,dv] Report IMEM fetch errors more helpfully in OTBN tracer

If we've seen an IMEM fetch error, this changes the trace from
something like

    E PC: 0x00000b10, insn: 0x84d72c7b

to something like

    E PC: 0x00000b10, insn: ??

Since the IMEM rdata is known to be bogus at this point, we don't
really want to display it. This also makes things easier on the ISS
side, where we don't need to model changes to the bits themselves
that are caused by 1- or 2-bit injected errors.

This patch also makes sure that we always print out an 'E' line.
Before, it was either 'E' or 'S', depending on whether the current
instruction was stalled or not. (Which would be very finicky to model
in the ISS and not really do anything useful).

Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/hw/ip/otbn/dv/tracer/rtl/otbn_trace_if.sv b/hw/ip/otbn/dv/tracer/rtl/otbn_trace_if.sv
index 35bef3c..3f9e301 100644
--- a/hw/ip/otbn/dv/tracer/rtl/otbn_trace_if.sv
+++ b/hw/ip/otbn/dv/tracer/rtl/otbn_trace_if.sv
@@ -52,6 +52,7 @@
   input logic [31:0]              insn_fetch_resp_data,
   input logic [ImemAddrWidth-1:0] insn_fetch_resp_addr,
   input logic                     insn_fetch_resp_valid,
+  input logic                     insn_fetch_err,
 
   input logic                         dmem_req_o,
   input logic                         dmem_write_o,
@@ -86,10 +87,10 @@
   logic [31:0] insn_data;
   logic        insn_stall;
 
-  assign insn_valid = insn_fetch_resp_valid;
-  assign insn_addr  = {{(32-ImemAddrWidth){1'b0}}, insn_fetch_resp_addr};
-  assign insn_data  = insn_fetch_resp_data;
-  assign insn_stall = u_otbn_core.u_otbn_controller.state_d == OtbnStateStall;
+  assign insn_valid     = insn_fetch_resp_valid;
+  assign insn_addr      = {{(32-ImemAddrWidth){1'b0}}, insn_fetch_resp_addr};
+  assign insn_data      = insn_fetch_resp_data;
+  assign insn_stall     = u_otbn_core.u_otbn_controller.state_d == OtbnStateStall;
 
   logic [31:0] rf_base_rd_data_a;
   logic [31:0] rf_base_rd_data_b;
diff --git a/hw/ip/otbn/dv/tracer/rtl/otbn_tracer.sv b/hw/ip/otbn/dv/tracer/rtl/otbn_tracer.sv
index 5c931be..a67bcaa 100644
--- a/hw/ip/otbn/dv/tracer/rtl/otbn_tracer.sv
+++ b/hw/ip/otbn/dv/tracer/rtl/otbn_tracer.sv
@@ -189,9 +189,17 @@
 
   function automatic void trace_insn();
     if (otbn_trace.insn_valid) begin
-      output_trace(otbn_trace.insn_stall ? InsnStallPrefix : InsnExecutePrefix,
-                   $sformatf("PC: 0x%08x, insn: 0x%08x", otbn_trace.insn_addr,
-                             otbn_trace.insn_data));
+      if (otbn_trace.insn_fetch_err) begin
+        // This means that we've seen an IMEM integrity error. Squash the reported instruction bits
+        // and ignore any stall: this will be the last cycle of the instruction either way.
+        output_trace(InsnExecutePrefix,
+                     $sformatf("PC: 0x%08x, insn: ??", otbn_trace.insn_addr));
+      end else begin
+        // We have a valid instruction, either stalled or completing its execution
+        output_trace(otbn_trace.insn_stall ? InsnStallPrefix : InsnExecutePrefix,
+                     $sformatf("PC: 0x%08x, insn: 0x%08x", otbn_trace.insn_addr,
+                               otbn_trace.insn_data));
+      end
     end
   endfunction