[otbn] Clear the call stack on start
This is for functional correctness only: we're planning a secure wipe
operation which will probably work a bit differently. But this means
that we can run binaries back to back even if they have unbalanced
uses of the x1 register, which was impossible before.
Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/hw/ip/otbn/dv/otbnsim/sim/gpr.py b/hw/ip/otbn/dv/otbnsim/sim/gpr.py
index 9d7898d..e2058c2 100644
--- a/hw/ip/otbn/dv/otbnsim/sim/gpr.py
+++ b/hw/ip/otbn/dv/otbnsim/sim/gpr.py
@@ -60,6 +60,11 @@
self.saw_read = False
super().abort()
+ def start(self) -> None:
+ '''Executed on start of operation.'''
+ self.stack = []
+ self.saw_read = False
+
class GPRs(RegFile):
'''The narrow OTBN register file'''
@@ -100,3 +105,7 @@
super().abort()
self._x1.abort()
self.err_flag = False
+
+ def start(self) -> None:
+ '''Executed on start of operation. Clears call stack.'''
+ self._x1.start()
diff --git a/hw/ip/otbn/dv/otbnsim/sim/state.py b/hw/ip/otbn/dv/otbnsim/sim/state.py
index 583ad99..80af4b4 100644
--- a/hw/ip/otbn/dv/otbnsim/sim/state.py
+++ b/hw/ip/otbn/dv/otbnsim/sim/state.py
@@ -168,10 +168,11 @@
self.pc = self.get_start_addr()
- # Reset CSRs, WSRs and loop stack
+ # Reset CSRs, WSRs, loop stack and call stack
self.csrs = CSRFile()
self.wsrs = WSRFile()
self.loop_stack = LoopStack()
+ self.gprs.start()
def get_start_addr(self) -> int:
'''Get the start address of the processor.
diff --git a/hw/ip/otbn/rtl/otbn_core.sv b/hw/ip/otbn/rtl/otbn_core.sv
index 2988988..99b8252 100644
--- a/hw/ip/otbn/rtl/otbn_core.sv
+++ b/hw/ip/otbn/rtl/otbn_core.sv
@@ -390,6 +390,8 @@
.clk_i,
.rst_ni,
+ .start_i,
+
.wr_addr_i (rf_base_wr_addr),
.wr_en_i (rf_base_wr_en),
.wr_data_no_intg_i (rf_base_wr_data_no_intg),
diff --git a/hw/ip/otbn/rtl/otbn_rf_base.sv b/hw/ip/otbn/rtl/otbn_rf_base.sv
index b61f98a..400893a 100644
--- a/hw/ip/otbn/rtl/otbn_rf_base.sv
+++ b/hw/ip/otbn/rtl/otbn_rf_base.sv
@@ -36,6 +36,8 @@
input logic clk_i,
input logic rst_ni,
+ input logic start_i,
+
input logic [4:0] wr_addr_i,
input logic wr_en_i,
input logic [31:0] wr_data_no_intg_i,
@@ -122,9 +124,7 @@
.full_o (stack_full),
- // TODO: Connect this up to the start signal, so that the call stack gets cleared at the start
- // of an operation.
- .clear_i (1'b0),
+ .clear_i (start_i),
.push_i (push_stack),
.push_data_i (wr_data_intg_mux_out),