[otbn] Zero insn_cnt when going into LOCKED state
This commit consists of several parts.
(1) In the RTL (otbn_controller.sv), we teach the instruction counter
to zero itself when in a locked state.
(2) At the top-level of the RTL (otbn.sv), we slightly change the
assertion that triggered this work in the first place. It was
checking that if the "d" of STATUS was locked then the instruction
count should be zero. Using |=> instead means that we check
against the (bus-visible) "q".
(3) Unfortunately, the DV code didn't match either! The cleanest way
to represent things seems to be to split the internal FSM to have
two different "just after execution" states. That means we can put
the "which way are we going?" logic in just one place.
Note that there's a bit of code duplication between the POST_EXEC
and LOCKING states in both state.py and sim.py. This is
intentional, because I think it's a bit easier to read this way.
The other option would be to have an if statement that applied to
both states, but then you'd need to inspect the state again inside
the branch to figure out the details of what you're doing.
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 9832808..4e35473 100644
--- a/hw/ip/otbn/rtl/otbn_controller.sv
+++ b/hw/ip/otbn/rtl/otbn_controller.sv
@@ -223,7 +223,6 @@
logic rf_a_indirect_err, rf_b_indirect_err, rf_d_indirect_err, rf_indirect_err;
- logic insn_cnt_en;
logic [31:0] insn_cnt_d, insn_cnt_q;
logic [4:0] ld_insn_bignum_wr_addr_q;
@@ -467,18 +466,26 @@
end
end
- assign insn_cnt_d = state_reset_i ? 32'd0 : (insn_cnt_q + 32'd1);
- assign insn_cnt_en = (insn_executing & ~stall & (insn_cnt_q != 32'hffffffff)) | state_reset_i;
- assign insn_cnt_o = insn_cnt_q;
+ always_comb begin
+ if (state_reset_i || state_q == OtbnStateLocked) begin
+ insn_cnt_d = 32'd0;
+ end else if (insn_executing & ~stall & (insn_cnt_q != 32'hffffffff)) begin
+ insn_cnt_d = insn_cnt_q + 32'd1;
+ end else begin
+ insn_cnt_d = insn_cnt_q;
+ end
+ end
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
insn_cnt_q <= 32'd0;
- end else if (insn_cnt_en) begin
+ end else begin
insn_cnt_q <= insn_cnt_d;
end
end
+ assign insn_cnt_o = insn_cnt_q;
+
assign loop_reset = state_reset_i | sec_wipe_zero_i;
otbn_loop_controller #(