[otbn,rtl] Avoid a 1-cycle glitch in locking_o

The locking_o signal used to be computed as follows:

  assign locking_o = (state_d == OtbnStateLocked) & ~secure_wipe_running_i;

This used to use state_q, but 48e4bb6 changed to state_d to move it a
cycle earlier. Of course, this doesn't work properly because you end
up with a single cycle "glitch" where locking_o is asserted before the
secure wipe starts.

The problem is that you can't just assert secure_wipe_running_o in the
start/stop controller a cycle earlier because you end up with a
combinational loop (I tried!). This commit switches the start/stop
controller to a sort of req/ack interface where the controller asks to
start a secure wipe and the start/stop controller responds once it's
done.

Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/hw/ip/otbn/rtl/otbn_controller.sv b/hw/ip/otbn/rtl/otbn_controller.sv
index cbaddd8..5233085 100644
--- a/hw/ip/otbn/rtl/otbn_controller.sv
+++ b/hw/ip/otbn/rtl/otbn_controller.sv
@@ -136,8 +136,8 @@
   input  logic rnd_fips_err_i,
 
   // Secure Wipe
-  input  logic secure_wipe_running_i,
   output logic start_secure_wipe_o,
+  input  logic secure_wipe_done_i,
   input  logic sec_wipe_zero_i,
 
   input  logic        state_reset_i,
@@ -285,6 +285,15 @@
 
   logic [4:0] insn_bignum_rd_addr_a_q, insn_bignum_rd_addr_b_q, insn_bignum_wr_addr_q;
 
+  logic secure_wipe_running_q;
+  always_ff @(posedge clk_i or negedge rst_ni) begin
+    if (!rst_ni) begin
+      secure_wipe_running_q <= 1'b0;
+    end else begin
+      secure_wipe_running_q <= start_secure_wipe_o | (secure_wipe_running_q & ~secure_wipe_done_i);
+    end
+  end
+
   // Stall a cycle on loads to allow load data writeback to happen the following cycle. Stall not
   // required on stores as there is no response to deal with.
   assign mem_stall = lsu_load_req_raw;
@@ -310,8 +319,8 @@
   assign executing = (state_q == OtbnStateRun) ||
                      (state_q == OtbnStateStall);
 
-  assign locking_o = (state_d == OtbnStateLocked) & ~secure_wipe_running_i;
-  assign start_secure_wipe_o = executing & (done_complete | err) & ~secure_wipe_running_i;
+  assign locking_o = (state_d == OtbnStateLocked) & ~(start_secure_wipe_o | secure_wipe_running_q);
+  assign start_secure_wipe_o = executing & (done_complete | err) & ~secure_wipe_running_q;
 
   assign jump_or_branch = (insn_valid_i &
                            (insn_dec_shared_i.branch_insn | insn_dec_shared_i.jump_insn));