[otbn,dv] Properly mirror STATUS reg from ISS to SystemVerilog
Also, mirror all the other registers in a slightly less ad-hoc fashion
in ISSWrapper.
There's a bit of churn in the model connection, because we were using
a signal called "status" to mean "the current state of the model".
This signal is now called model_state.
The status_o signal isn't actually connected in the UVM or Verilator
testbenches yet (so doesn't really do anything): this will be
connected in a subsequent commit.
Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/hw/ip/otbn/dv/memutil/sv_utils.h b/hw/ip/otbn/dv/memutil/sv_utils.h
index 5e453a6..2b480b9 100644
--- a/hw/ip/otbn/dv/memutil/sv_utils.h
+++ b/hw/ip/otbn/dv/memutil/sv_utils.h
@@ -6,6 +6,15 @@
#include <svdpi.h>
+// Utility function that packs a uint8_t into a SystemVerilog bit vector that
+// represents a "bit [7:0]"
+inline void set_sv_u8(svBitVecVal *dst, uint8_t src) {
+ for (int i = 0; i < 8; ++i) {
+ svBit bit = (src >> i) & 1;
+ svPutBitselBit(dst, i, bit);
+ }
+}
+
// Utility function that packs a uint32_t into a SystemVerilog bit vector that
// represents a "bit [31:0]"
inline void set_sv_u32(svBitVecVal *dst, uint32_t src) {
diff --git a/hw/ip/otbn/dv/model/iss_wrapper.cc b/hw/ip/otbn/dv/model/iss_wrapper.cc
index e8cec8c..9a70d9d 100644
--- a/hw/ip/otbn/dv/model/iss_wrapper.cc
+++ b/hw/ip/otbn/dv/model/iss_wrapper.cc
@@ -193,10 +193,13 @@
}
// Read through trace output (in the lines argument) to pick up any write to
-// the named CSR register. If there is no such write, return default_val.
-static uint32_t read_ext_reg(const std::string ®_name,
- const std::vector<std::string> &lines,
- uint32_t default_val) {
+// the named CSR register, updating *dest. If there is no such write and
+// required is true, returns false. Otherwise returns true.
+static bool read_ext_reg(const std::string ®_name,
+ const std::vector<std::string> &lines, uint32_t *dest,
+ bool required) {
+ assert(dest);
+
// We're interested in lines that show an update to the external register
// called reg_name. These look something like this:
//
@@ -204,7 +207,8 @@
std::regex re("! otbn\\." + reg_name + ": 0x([0-9a-f]{8})");
std::smatch match;
- uint32_t val = default_val;
+ uint32_t val = 0;
+ bool found = false;
for (const auto &line : lines) {
if (std::regex_match(line, match, re)) {
@@ -212,11 +216,17 @@
// that we can safely parse them to a uint32_t without risking a parse
// failure or overflow.
assert(match.size() == 2);
- val = (uint32_t)strtoul(match[1].str().c_str(), nullptr, 16);
+ *dest = (uint32_t)strtoul(match[1].str().c_str(), nullptr, 16);
+ found = true;
}
}
- return val;
+ if (required && !found) {
+ std::cerr << "ERROR: Expected register `" << reg_name
+ << "' not found in output.";
+ return false;
+ }
+ return true;
}
static std::string wlen_val_to_hex_str(uint32_t val[8]) {
@@ -230,8 +240,7 @@
return oss.str();
}
-ISSWrapper::ISSWrapper()
- : tmpdir(new TmpDir()), insn_cnt_(0), err_bits_(0), stop_pc_(0) {
+ISSWrapper::ISSWrapper() : tmpdir(new TmpDir()) {
std::string model_path(find_otbn_model());
// We want two pipes: one for writing to the child process, and the other for
@@ -347,13 +356,16 @@
<< "\n";
run_command(oss.str(), nullptr);
- // "Reset" our mirror of INSN_CNT. This gets zeroed on this cycle in the
- // Python model, but the text-based interface doesn't expose the change (and
- // doing so would require some complicated rejigging). We'll get valid
- // numbers as soon as an instruction executes, but zeroing here avoids having
- // an old number for the stall cycles at the start of the second and
- // subsequent runs.
- insn_cnt_ = 0;
+ // Zero our mirror of INSN_CNT. This gets zeroed on this cycle in the Python
+ // model, but the text-based interface doesn't expose the change (and doing
+ // so would require some complicated rejigging). We'll get valid numbers as
+ // soon as an instruction executes, but zeroing here avoids having an old
+ // number for the stall cycles at the start of the second and subsequent
+ // runs.
+ mirrored_.insn_cnt = 0;
+
+ // Set our mirror of STATUS to BUSY_EXECUTE (= 1).
+ mirrored_.status = 1;
}
void ISSWrapper::edn_rnd_data(uint32_t edn_rnd_data[8]) {
@@ -368,30 +380,30 @@
int ISSWrapper::step(bool gen_trace) {
std::vector<std::string> lines;
- bool mismatch = false;
+ bool error = false;
run_command("step\n", &lines);
if (gen_trace) {
- mismatch = !OtbnTraceChecker::get().OnIssTrace(lines);
+ error = !OtbnTraceChecker::get().OnIssTrace(lines);
}
- // The busy flag is bit 0 of the STATUS register, so is cleared on this cycle
- // if we see a write that sets the value to an even number.
- bool done = (read_ext_reg("STATUS", lines, 1) & 1) == 0;
+ // Try to read STATUS, which is written when execution ends. Execution has
+ // finished if status_ is either 0 (IDLE) or 0xff (LOCKED)
+ read_ext_reg("STATUS", lines, &mirrored_.status, false);
+ bool done = (mirrored_.status == 0) || (mirrored_.status == 0xff);
- // Always try to read INSN_CNT. On failure, don't update it (this
- // happens on stall cycles)
- insn_cnt_ = read_ext_reg("INSN_CNT", lines, insn_cnt_);
+ // Always try to read INSN_CNT
+ read_ext_reg("INSN_CNT", lines, &mirrored_.insn_cnt, false);
// If we've just finished, try to read ERR_BITS and STOP_PC, storing
// them into fields on this structure. The caller will retrieve them
// after we've returned.
if (done) {
- err_bits_ = read_ext_reg("ERR_BITS", lines, 0);
- stop_pc_ = read_ext_reg("STOP_PC", lines, 0);
+ error |= !read_ext_reg("ERR_BITS", lines, &mirrored_.err_bits, true);
+ error |= !read_ext_reg("STOP_PC", lines, &mirrored_.stop_pc, true);
}
- return mismatch ? -1 : (done ? 1 : 0);
+ return error ? -1 : (done ? 1 : 0);
}
void ISSWrapper::reset(bool gen_trace) {
diff --git a/hw/ip/otbn/dv/model/iss_wrapper.h b/hw/ip/otbn/dv/model/iss_wrapper.h
index 01965b9..713863c 100644
--- a/hw/ip/otbn/dv/model/iss_wrapper.h
+++ b/hw/ip/otbn/dv/model/iss_wrapper.h
@@ -15,6 +15,21 @@
// Forward declaration (the implementation is private in iss_wrapper.cc)
struct TmpDir;
+// OTBN has some externally visible CSRs that can be updated by hardware
+// (without explicit writes from software). The ISSWrapper mirrors the ISS's
+// versions of these registers in this structure.
+class MirroredRegs {
+ public:
+ MirroredRegs() : status(0), insn_cnt(0), err_bits(0), stop_pc(0) {}
+
+ uint32_t status;
+ uint32_t insn_cnt;
+ uint32_t err_bits;
+
+ // The final PC from the most recent run
+ uint32_t stop_pc;
+};
+
// An object wrapping the ISS subprocess.
struct ISSWrapper {
// A 256-bit unsigned integer value, stored in "LSB order". Thus, words[0]
@@ -49,37 +64,29 @@
// Signal URND reseed at beginning of execution is complete
void edn_urnd_reseed_complete();
- // Run simulation for a single cycle. Returns a pair (ret_code, err_bits).
+ // Run simulation for a single cycle.
//
- // If gen_trace is true, pass trace data to the (singleton)
- // OtbnTraceChecker object.
+ // If gen_trace is true, pass trace data to the (singleton) OtbnTraceChecker
+ // object.
//
- // ret_code describes the state of the simulation. It is 1 if the simulation
- // just stopped (on ECALL or an architectural error); it is 0 if the
- // simulation is still running. It is -1 if something went wrong (such as a
- // trace mismatch).
+ // The return code describes the state of the simulation. It is 1 if the
+ // simulation just stopped (on ECALL or an architectural error); it is 0 if
+ // the simulation is still running. It is -1 if something went wrong (such as
+ // a trace mismatch).
//
- // err_bits is zero unless the simulation just came to a halt, in which case
- // it's the value of the ERR_BITS register.
+ // Updates mirrored versions of STATUS and INSN_CNT registers. If execution
+ // finishes (so we return 1), also updates mirrored versions of ERR_BITS and
+ // the final PC (see get_stop_pc()).
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
+ // This doesn't actually send anything to the ISS, but instead tells the
+ // OtbnTraceChecker to clear out any partial instructions. It also resets
+ // mirrored registers to their initial states.
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_; }
-
- // Get the err_bits from a run that's just finished. This should be
- // called just after step() returns 1.
- uint32_t get_err_bits() const { return err_bits_; }
-
- // Get the final PC from a run that's just finished. This should be
- // called just after step() returns 1.
- uint32_t get_stop_pc() const { return stop_pc_; }
+ const MirroredRegs &get_mirrored() const { return mirrored_; }
// Read contents of the register file
void get_regs(std::array<uint32_t, 32> *gprs, std::array<u256_t, 32> *wdrs);
@@ -109,13 +116,8 @@
// A temporary directory for communicating with the child process
std::unique_ptr<TmpDir> tmpdir;
- // INSN_CNT for the current run if there is one, or the previous run if
- // there's no current one.
- uint32_t insn_cnt_;
-
- // ERR_BITS and STOP_PC values from a run that's just finished.
- uint32_t err_bits_;
- uint32_t stop_pc_;
+ // Mirrored copies of registers
+ MirroredRegs mirrored_;
};
#endif // OPENTITAN_HW_IP_OTBN_DV_MODEL_ISS_WRAPPER_H_
diff --git a/hw/ip/otbn/dv/model/otbn_core_model.sv b/hw/ip/otbn/dv/model/otbn_core_model.sv
index 55ac0e9..222e751 100644
--- a/hw/ip/otbn/dv/model/otbn_core_model.sv
+++ b/hw/ip/otbn/dv/model/otbn_core_model.sv
@@ -40,6 +40,7 @@
input logic [WLEN-1:0] edn_rnd_data_i,
input logic edn_urnd_data_valid_i, // URND reseed from EDN is valid
+ output bit [7:0] status_o, // STATUS register
output bit [31:0] insn_cnt_o, // INSN_CNT register
output bit err_o // something went wrong
@@ -58,13 +59,13 @@
otbn_model_destroy(model_handle);
end
- // A packed "status" value. This gets assigned by DPI function calls that need to update both
- // whether we're running and also error flags at the same time. The contents are magic simulation
- // values, so get initialized before reset (to avoid stopping the simulation before it even
- // starts).
- int unsigned status = 0;
+ // A packed set of bits representing the state of the model. This gets assigned by DPI function
+ // calls that need to update both whether we're running and also error flags at the same time. The
+ // contents are magic simulation values, so get initialized before reset (to avoid stopping the
+ // simulation before it even starts).
+ int unsigned model_state = 0;
- // Extract particular bits of the status value.
+ // Extract particular bits of the model_state value.
//
// [0] running: The ISS is currently running
// [1] check_due: The ISS just finished but still needs to check results
@@ -72,45 +73,51 @@
// [3] failed_cmp: The consistency check at the end of run failed.
bit failed_cmp, failed_step, check_due, running;
- assign {failed_cmp, failed_step, check_due, running} = status[3:0];
+ assign {failed_cmp, failed_step, check_due, running} = model_state[3:0];
- bit [31:0] raw_err_bits_d, raw_err_bits_q;
- bit unused_raw_err_bits;
-
- bit [31:0] stop_pc_d, stop_pc_q;
+ bit [7:0] status_d, status_q;
bit [31:0] insn_cnt_d, insn_cnt_q;
+ bit [31:0] raw_err_bits_d, raw_err_bits_q;
+ bit [31:0] stop_pc_d, stop_pc_q;
+
+ bit unused_raw_err_bits;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
- if (status != 0) begin
+ if (model_state != 0) begin
otbn_model_reset(model_handle);
end
- status <= 0;
+ model_state <= 0;
+ status_q <= 0;
+ insn_cnt_q <= 0;
raw_err_bits_q <= 0;
stop_pc_q <= 0;
- insn_cnt_q <= 0;
end else begin
if (start_i | running | check_due) begin
- status <= otbn_model_step(model_handle,
- start_i,
- status,
- edn_rnd_data_valid_i, edn_rnd_data_i,
- edn_urnd_data_valid_i,
- insn_cnt_d,
- raw_err_bits_d,
- stop_pc_d);
+ model_state <= otbn_model_step(model_handle,
+ start_i,
+ model_state,
+ edn_rnd_data_valid_i, edn_rnd_data_i,
+ edn_urnd_data_valid_i,
+ status_d,
+ insn_cnt_d,
+ raw_err_bits_d,
+ stop_pc_d);
+ status_q <= status_d;
+ insn_cnt_q <= insn_cnt_d;
raw_err_bits_q <= raw_err_bits_d;
stop_pc_q <= stop_pc_d;
- insn_cnt_q <= insn_cnt_d;
end else begin
// If we're not running and we're not being told to start, there's nothing to do.
end
end
end
- assign err_bits_o = raw_err_bits_q[$bits(err_bits_t)-1:0];
assign unused_raw_err_bits = ^raw_err_bits_q[31:$bits(err_bits_t)];
+ assign err_bits_o = raw_err_bits_q[$bits(err_bits_t)-1:0];
+
+ assign status_o = status_q;
assign insn_cnt_o = insn_cnt_q;
// Track negedges of running_q and expose that as a "done" output.
diff --git a/hw/ip/otbn/dv/model/otbn_model.cc b/hw/ip/otbn/dv/model/otbn_model.cc
index 581b8e7..9fb7347 100644
--- a/hw/ip/otbn/dv/model/otbn_model.cc
+++ b/hw/ip/otbn/dv/model/otbn_model.cc
@@ -252,10 +252,11 @@
int OtbnModel::step(svLogic edn_rnd_data_valid,
svLogicVecVal *edn_rnd_data, /* logic [255:0] */
svLogic edn_urnd_data_valid,
+ svBitVecVal *status /* bit [7:0] */,
svBitVecVal *insn_cnt /* bit [31:0] */,
svBitVecVal *err_bits /* bit [31:0] */,
svBitVecVal *stop_pc /* bit [31:0] */) {
- assert(err_bits);
+ assert(edn_rnd_data && err_bits && insn_cnt && err_bits && stop_pc);
ISSWrapper *iss = ensure_wrapper();
if (!iss)
@@ -282,15 +283,25 @@
return -1;
case 1:
- // The simulation has stopped. Fill in insn_cnt, err_bits and stop_pc.
- set_sv_u32(insn_cnt, iss->get_insn_cnt());
- set_sv_u32(err_bits, iss->get_err_bits());
- set_sv_u32(stop_pc, iss->get_stop_pc());
+ // The simulation has stopped. Fill in status, insn_cnt, err_bits and
+ // stop_pc. Note that status should never have anything in its top 24
+ // bits.
+ if (iss->get_mirrored().status >> 8) {
+ throw std::runtime_error("STATUS register had non-empty top bits.");
+ }
+ set_sv_u8(status, iss->get_mirrored().status);
+ set_sv_u32(insn_cnt, iss->get_mirrored().insn_cnt);
+ set_sv_u32(err_bits, iss->get_mirrored().err_bits);
+ set_sv_u32(stop_pc, iss->get_mirrored().stop_pc);
return 1;
case 0:
- // The simulation is still running. Update insn_cnt.
- set_sv_u32(insn_cnt, iss->get_insn_cnt());
+ // The simulation is still running. Update status and insn_cnt.
+ if (iss->get_mirrored().status >> 8) {
+ throw std::runtime_error("STATUS register had non-empty top bits.");
+ }
+ set_sv_u8(status, iss->get_mirrored().status);
+ set_sv_u32(insn_cnt, iss->get_mirrored().insn_cnt);
return 0;
default:
@@ -537,18 +548,19 @@
void otbn_model_destroy(OtbnModel *model) { delete model; }
-unsigned otbn_model_step(OtbnModel *model, svLogic start, unsigned status,
+unsigned otbn_model_step(OtbnModel *model, svLogic start, unsigned model_state,
svLogic edn_rnd_data_valid,
svLogicVecVal *edn_rnd_data, /* logic [255:0] */
svLogic edn_urnd_data_valid,
+ svBitVecVal *status /* bit [7:0] */,
svBitVecVal *insn_cnt /* bit [31:0] */,
svBitVecVal *err_bits /* bit [31:0] */,
svBitVecVal *stop_pc /* bit [31:0] */) {
- assert(model && insn_cnt && err_bits && stop_pc);
+ assert(model && status && insn_cnt && err_bits && stop_pc);
// Run model checks if needed. This usually happens just after an operation
// has finished.
- if (model->has_rtl() && (status & CHECK_DUE_BIT)) {
+ if (model->has_rtl() && (model_state & CHECK_DUE_BIT)) {
switch (model->check()) {
case 1:
// Match (success)
@@ -556,14 +568,14 @@
case 0:
// Mismatch
- status |= FAILED_CMP_BIT;
+ model_state |= FAILED_CMP_BIT;
break;
default:
// Something went wrong
- return (status & ~RUNNING_BIT) | FAILED_STEP_BIT;
+ return (model_state & ~RUNNING_BIT) | FAILED_STEP_BIT;
}
- status &= ~CHECK_DUE_BIT;
+ model_state &= ~CHECK_DUE_BIT;
}
assert(!is_xz(start));
@@ -573,39 +585,39 @@
switch (model->start()) {
case 0:
// All good
- status |= RUNNING_BIT;
+ model_state |= RUNNING_BIT;
break;
default:
// Something went wrong.
- return (status & ~RUNNING_BIT) | FAILED_STEP_BIT;
+ return (model_state & ~RUNNING_BIT) | FAILED_STEP_BIT;
}
}
// If the model isn't running, there's nothing more to do.
- if (!(status & RUNNING_BIT))
- return status;
+ if (!(model_state & RUNNING_BIT))
+ return model_state;
// Step the model once
switch (model->step(edn_rnd_data_valid, edn_rnd_data, edn_urnd_data_valid,
- insn_cnt, err_bits, stop_pc)) {
+ status, insn_cnt, err_bits, stop_pc)) {
case 0:
// Still running: no change
break;
case 1:
// Finished
- status = (status & ~RUNNING_BIT) | CHECK_DUE_BIT;
+ model_state = (model_state & ~RUNNING_BIT) | CHECK_DUE_BIT;
break;
default:
// Something went wrong
- return (status & ~RUNNING_BIT) | FAILED_STEP_BIT;
+ return (model_state & ~RUNNING_BIT) | FAILED_STEP_BIT;
}
// If we're still running, there's nothing more to do.
- if (status & RUNNING_BIT)
- return status;
+ if (model_state & RUNNING_BIT)
+ return model_state;
// If we've just stopped running and there's no RTL, load the contents of
// DMEM back from the ISS
@@ -617,11 +629,11 @@
default:
// Failed to load DMEM
- return (status & ~RUNNING_BIT) | FAILED_STEP_BIT;
+ return (model_state & ~RUNNING_BIT) | FAILED_STEP_BIT;
}
}
- return status;
+ return model_state;
}
void otbn_model_reset(OtbnModel *model) {
diff --git a/hw/ip/otbn/dv/model/otbn_model.h b/hw/ip/otbn/dv/model/otbn_model.h
index 889e871..c3d6c88 100644
--- a/hw/ip/otbn/dv/model/otbn_model.h
+++ b/hw/ip/otbn/dv/model/otbn_model.h
@@ -38,7 +38,8 @@
// checker. If the model has finished, writes otbn.ERR_BITS to *err_bits.
int step(svLogic edn_rnd_data_valid,
svLogicVecVal *edn_rnd_data, /* logic [255:0] */
- svLogic edn_urnd_data_valid, svBitVecVal *insn_cnt /* bit [31:0] */,
+ svLogic edn_urnd_data_valid, svBitVecVal *status /* bit [7:0] */,
+ svBitVecVal *insn_cnt /* bit [31:0] */,
svBitVecVal *err_bits /* bit [31:0] */,
svBitVecVal *stop_pc /* bit [31:0] */);
diff --git a/hw/ip/otbn/dv/model/otbn_model_dpi.h b/hw/ip/otbn/dv/model/otbn_model_dpi.h
index 3031b28..33b7d45 100644
--- a/hw/ip/otbn/dv/model/otbn_model_dpi.h
+++ b/hw/ip/otbn/dv/model/otbn_model_dpi.h
@@ -25,7 +25,7 @@
// The main entry point to the OTBN model, exported from here and used in
// otbn_core_model.sv.
//
-// This communicates state with otbn_core_model.sv through the status
+// This communicates state with otbn_core_model.sv through the model_state
// parameter, which has the following bits:
//
// Bit 0: running True if the model is currently running
@@ -34,9 +34,9 @@
// Bit 3: failed_cmp Consistency check at end of run failed
//
// The otbn_model_step function should only be called when either the model is
-// running (bit 0 of status), has a check due (bit 1 of status), or when start
-// is asserted. At other times, it will return immediately (but wastes a DPI
-// call).
+// running (bit 0 of model_state), has a check due (bit 1 of model_state), or
+// when start is asserted. At other times, it will return immediately (but
+// wastes a DPI call).
//
// If the model is running and start is false, otbn_model_step steps the ISS by
// a single cycle. If something goes wrong, it will set failed_step to true and
@@ -54,10 +54,11 @@
//
// If start is true, we start the model and then step once (as described
// above).
-unsigned otbn_model_step(OtbnModel *model, svLogic start, unsigned status,
+unsigned otbn_model_step(OtbnModel *model, svLogic start, unsigned model_state,
svLogic edn_rnd_data_valid,
svLogicVecVal *edn_rnd_data, /* logic [255:0] */
svLogic edn_urnd_data_valid,
+ svBitVecVal *status /* bit [7:0] */,
svBitVecVal *insn_cnt /* bit [31:0] */,
svBitVecVal *err_bits /* bit [31:0] */,
svBitVecVal *stop_pc /* bit [31:0] */);
diff --git a/hw/ip/otbn/dv/model/otbn_model_pkg.sv b/hw/ip/otbn/dv/model/otbn_model_pkg.sv
index 028d03e..eb927d4 100644
--- a/hw/ip/otbn/dv/model/otbn_model_pkg.sv
+++ b/hw/ip/otbn/dv/model/otbn_model_pkg.sv
@@ -19,10 +19,11 @@
import "DPI-C" context function
int unsigned otbn_model_step(chandle model,
logic start,
- int unsigned status,
+ int unsigned model_state,
logic edn_rnd_data_valid,
logic [WLEN-1:0] edn_rnd_data,
logic edn_urnd_data_valid,
+ inout bit [7:0] status,
inout bit [31:0] insn_cnt,
inout bit [31:0] err_bits,
inout bit [31:0] stop_pc);
diff --git a/hw/ip/otbn/dv/uvm/tb.sv b/hw/ip/otbn/dv/uvm/tb.sv
index ea63270..3ba5021 100644
--- a/hw/ip/otbn/dv/uvm/tb.sv
+++ b/hw/ip/otbn/dv/uvm/tb.sv
@@ -191,7 +191,9 @@
.edn_rnd_data_i (dut.edn_rnd_data),
.edn_urnd_data_valid_i (edn_urnd_data_valid),
+ .status_o (),
.insn_cnt_o (model_insn_cnt),
+
.err_o (model_if.err)
);
diff --git a/hw/ip/otbn/dv/verilator/otbn_top_sim.sv b/hw/ip/otbn/dv/verilator/otbn_top_sim.sv
index 8f803ba..f230473 100644
--- a/hw/ip/otbn/dv/verilator/otbn_top_sim.sv
+++ b/hw/ip/otbn/dv/verilator/otbn_top_sim.sv
@@ -290,6 +290,7 @@
.edn_rnd_data_i ( edn_rnd_data ),
.edn_urnd_data_valid_i ( edn_urnd_data_valid ),
+ .status_o (),
.insn_cnt_o ( otbn_model_insn_cnt ),
.err_o ( otbn_model_err )