[otbn] Added sparse FSM encoding
Signed-off-by: Vladimir Rozic <vrozic@lowrisc.org>
diff --git a/hw/ip/otbn/rtl/otbn_controller.sv b/hw/ip/otbn/rtl/otbn_controller.sv
index 5e2fd16..8eb1f41 100644
--- a/hw/ip/otbn/rtl/otbn_controller.sv
+++ b/hw/ip/otbn/rtl/otbn_controller.sv
@@ -138,6 +138,8 @@
input logic illegal_bus_access_i,
input logic lifecycle_escalation_i,
input logic software_errs_fatal_i,
+ input logic start_stop_state_error_i,
+ input logic otbn_scramble_state_error_i,
input logic [1:0] sideload_key_shares_valid_i,
@@ -157,6 +159,7 @@
logic recoverable_err;
logic done_complete;
logic executing;
+ logic state_error;
logic insn_fetch_req_valid_raw;
logic [ImemAddrWidth-1:0] insn_fetch_req_addr_last;
@@ -304,7 +307,8 @@
err_bits_en = 1'b0;
prefetch_en_o = 1'b0;
- // TODO: Harden state machine
+ state_error = 1'b0;
+
unique case (state_q)
OtbnStateHalt: begin
if (start_i) begin
@@ -370,7 +374,9 @@
insn_fetch_req_valid_raw = 1'b0;
state_d = OtbnStateLocked;
end
- default: ;
+ default: begin
+ state_error = 1'b1;
+ end
endcase
// On any error immediately halt, either going to OtbnStateLocked or OtbnStateHalt depending on
@@ -427,7 +433,8 @@
assign err_bits.fatal_software = software_err & software_errs_fatal_i;
assign err_bits.lifecycle_escalation = lifecycle_escalation_i;
assign err_bits.illegal_bus_access = illegal_bus_access_i;
- assign err_bits.bad_internal_state = 0;
+ assign err_bits.bad_internal_state = start_stop_state_error_i | state_error |
+ otbn_scramble_state_error_i;
assign err_bits.bus_intg_violation = bus_intg_violation_i;
assign err_bits.reg_intg_violation = rf_base_rd_data_err_i | rf_bignum_rd_data_err_i;
assign err_bits.dmem_intg_violation = lsu_rdata_err_i;
@@ -459,6 +466,7 @@
assign fatal_err = |{err_bits.fatal_software,
err_bits.lifecycle_escalation,
err_bits.illegal_bus_access,
+ err_bits.bad_internal_state ,
err_bits.bus_intg_violation,
err_bits.reg_intg_violation,
err_bits.dmem_intg_violation,
@@ -511,13 +519,20 @@
`ASSERT(NoStallOnBranch,
insn_valid_i & insn_dec_shared_i.branch_insn |-> state_q != OtbnStateStall)
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- state_q <= OtbnStateHalt;
- end else begin
- state_q <= state_d;
- end
- end
+ // This primitive is used to place a size-only constraint on the
+ // flops in order to prevent FSM state encoding optimizations.
+ logic [StateControllerWidth-1:0] state_raw_q;
+ assign state_q = otbn_state_e'(state_raw_q);
+ prim_sparse_fsm_flop #(
+ .StateEnumT(otbn_state_e),
+ .Width(StateControllerWidth),
+ .ResetValue(StateControllerWidth'(OtbnStateHalt))
+ ) u_state_regs (
+ .clk_i,
+ .rst_ni,
+ .state_i ( state_d ),
+ .state_o ( state_raw_q )
+ );
assign insn_cnt_clear = state_reset_i | (state_q == OtbnStateLocked) | insn_cnt_clear_i;