[otbn,dv] Teach ISS wrapper to handle resets

Without this, you get weird errors where OTBN gets resets half-way
through a stall and a consistency check in the OtbnTraceChecker gets
confused because it sees a stall at one address, followed by an
execution at another.

Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/hw/ip/otbn/dv/model/iss_wrapper.cc b/hw/ip/otbn/dv/model/iss_wrapper.cc
index b32504e..14542d0 100644
--- a/hw/ip/otbn/dv/model/iss_wrapper.cc
+++ b/hw/ip/otbn/dv/model/iss_wrapper.cc
@@ -381,6 +381,11 @@
   return mismatch ? -1 : (done ? 1 : 0);
 }
 
+void ISSWrapper::reset(bool gen_trace) {
+  if (gen_trace)
+    OtbnTraceChecker::get().Flush();
+}
+
 void ISSWrapper::get_regs(std::array<uint32_t, 32> *gprs,
                           std::array<u256_t, 32> *wdrs) {
   assert(gprs && wdrs);
diff --git a/hw/ip/otbn/dv/model/iss_wrapper.h b/hw/ip/otbn/dv/model/iss_wrapper.h
index 8cacc9a..b9b3f82 100644
--- a/hw/ip/otbn/dv/model/iss_wrapper.h
+++ b/hw/ip/otbn/dv/model/iss_wrapper.h
@@ -57,6 +57,12 @@
   // it's the value of the ERR_BITS register.
   int step(bool gen_trace);
 
+  // Reset simulation
+  //
+  // This doesn't actually send anything to the ISS, but instead tells
+  // the OtbnTraceChecker to clear out any partial instructions
+  void reset(bool gen_trace);
+
   // Get the current value of otbn.INSN_CNT. This should be called just after
   // step (but doesn't necessarily need to wait until the run has finished).
   uint32_t get_insn_cnt() const { return insn_cnt_; }
diff --git a/hw/ip/otbn/dv/model/otbn_core_model.sv b/hw/ip/otbn/dv/model/otbn_core_model.sv
index 0fbaaf7..e0311b1 100644
--- a/hw/ip/otbn/dv/model/otbn_core_model.sv
+++ b/hw/ip/otbn/dv/model/otbn_core_model.sv
@@ -52,7 +52,7 @@
                                                           string design_scope,
                                                           int unsigned imem_words,
                                                           int unsigned dmem_words);
-  import "DPI-C" function void otbn_model_destroy(chandle handle);
+  import "DPI-C" function void otbn_model_destroy(chandle model);
   import "DPI-C" context function
     int unsigned otbn_model_step(chandle          model,
                                  logic            start,
@@ -64,6 +64,7 @@
                                  inout bit [31:0] insn_cnt,
                                  inout bit [31:0] err_bits,
                                  inout bit [31:0] stop_pc);
+  import "DPI-C" function void otbn_model_reset(chandle model);
 
 
   localparam int ImemSizeWords = ImemSizeByte / 4;
@@ -116,7 +117,9 @@
 
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      // Clear status (stop running, and forget any errors and final PC)
+      if (status != 0) begin
+        otbn_model_reset(model_handle);
+      end
       status <= 0;
       raw_err_bits_q <= 0;
       stop_pc_q <= 0;
diff --git a/hw/ip/otbn/dv/model/otbn_model.cc b/hw/ip/otbn/dv/model/otbn_model.cc
index e6301a2..11b267a 100644
--- a/hw/ip/otbn/dv/model/otbn_model.cc
+++ b/hw/ip/otbn/dv/model/otbn_model.cc
@@ -660,3 +660,14 @@
 
   return status;
 }
+
+// Flush any information in the model
+extern "C" void otbn_model_reset(OtbnModel *model) {
+  assert(model);
+
+  ISSWrapper *iss = model->get_wrapper(false);
+  if (iss) {
+    bool check_rtl = (model->design_scope_.size() > 0);
+    iss->reset(check_rtl);
+  }
+}
diff --git a/hw/ip/otbn/dv/model/otbn_trace_checker.cc b/hw/ip/otbn/dv/model/otbn_trace_checker.cc
index 60b8fa8..7f6d8a1 100644
--- a/hw/ip/otbn/dv/model/otbn_trace_checker.cc
+++ b/hw/ip/otbn/dv/model/otbn_trace_checker.cc
@@ -176,6 +176,12 @@
   return MatchPair();
 }
 
+void OtbnTraceChecker::Flush() {
+  rtl_pending_ = false;
+  rtl_stall_ = false;
+  iss_pending_ = false;
+}
+
 bool OtbnTraceChecker::Finish() {
   assert(!(rtl_pending_ && iss_pending_));
   done_ = true;
diff --git a/hw/ip/otbn/dv/model/otbn_trace_checker.h b/hw/ip/otbn/dv/model/otbn_trace_checker.h
index 886c933..eed21f4 100644
--- a/hw/ip/otbn/dv/model/otbn_trace_checker.h
+++ b/hw/ip/otbn/dv/model/otbn_trace_checker.h
@@ -60,6 +60,10 @@
   // Prints an error message to stderr and returns false on mismatch.
   bool OnIssTrace(const std::vector<std::string> &lines);
 
+  // Flush any pending entries. We need to do this on reset, to handle
+  // the case where we reset the processor in the middle of a stall.
+  void Flush();
+
   // Call this when the ISS simulation completes an operation (on ECALL or
   // error).
   //