[lc_ctrl] Fix transition command error checking
Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/hw/ip/lc_ctrl/rtl/lc_ctrl.sv b/hw/ip/lc_ctrl/rtl/lc_ctrl.sv
index 1f74a6c..cae7ae6 100644
--- a/hw/ip/lc_ctrl/rtl/lc_ctrl.sv
+++ b/hw/ip/lc_ctrl/rtl/lc_ctrl.sv
@@ -296,6 +296,7 @@
always_ff @(posedge clk_i or negedge rst_ni) begin : p_csrs
if (!rst_ni) begin
trans_success_q <= 1'b0;
+ trans_cnt_oflw_error_q <= 1'b0;
trans_invalid_error_q <= 1'b0;
token_invalid_error_q <= 1'b0;
flash_rma_error_q <= 1'b0;
diff --git a/hw/ip/lc_ctrl/rtl/lc_ctrl_fsm.sv b/hw/ip/lc_ctrl/rtl/lc_ctrl_fsm.sv
index 837e55c..9da0b3c 100644
--- a/hw/ip/lc_ctrl/rtl/lc_ctrl_fsm.sv
+++ b/hw/ip/lc_ctrl/rtl/lc_ctrl_fsm.sv
@@ -404,6 +404,7 @@
.lc_state_i ( lc_state_q ),
.lc_cnt_i ( lc_cnt_q ),
.dec_lc_state_i ( dec_lc_state_o ),
+ .fsm_state_i ( fsm_state_q ),
.trans_target_i,
.next_lc_state_o ( next_lc_state ),
.next_lc_cnt_o ( next_lc_cnt ),
diff --git a/hw/ip/lc_ctrl/rtl/lc_ctrl_state_transition.sv b/hw/ip/lc_ctrl/rtl/lc_ctrl_state_transition.sv
index 036f70b..a293171 100644
--- a/hw/ip/lc_ctrl/rtl/lc_ctrl_state_transition.sv
+++ b/hw/ip/lc_ctrl/rtl/lc_ctrl_state_transition.sv
@@ -11,6 +11,8 @@
// Life cycle state vector.
input lc_state_e lc_state_i,
input lc_cnt_e lc_cnt_i,
+ // Main FSM state.
+ input fsm_state_e fsm_state_i,
// Decoded lc state input
input dec_lc_state_e dec_lc_state_i,
// Transition target.
@@ -36,59 +38,63 @@
trans_cnt_oflw_error_o = 1'b0;
trans_invalid_error_o = 1'b0;
- // In this state, the life cycle counter is incremented.
- // Throw an error if the counter is already maxed out.
- unique case (lc_cnt_i)
- LcCntRaw: next_lc_cnt_o = LcCnt1;
- LcCnt1: next_lc_cnt_o = LcCnt2;
- LcCnt2: next_lc_cnt_o = LcCnt3;
- LcCnt3: next_lc_cnt_o = LcCnt4;
- LcCnt4: next_lc_cnt_o = LcCnt5;
- LcCnt5: next_lc_cnt_o = LcCnt6;
- LcCnt6: next_lc_cnt_o = LcCnt7;
- LcCnt7: next_lc_cnt_o = LcCnt8;
- LcCnt8: next_lc_cnt_o = LcCnt9;
- LcCnt9: next_lc_cnt_o = LcCnt10;
- LcCnt10: next_lc_cnt_o = LcCnt11;
- LcCnt11: next_lc_cnt_o = LcCnt12;
- LcCnt12: next_lc_cnt_o = LcCnt13;
- LcCnt13: next_lc_cnt_o = LcCnt14;
- LcCnt14: next_lc_cnt_o = LcCnt15;
- LcCnt15: next_lc_cnt_o = LcCnt16;
- LcCnt16: trans_cnt_oflw_error_o = 1'b1;
- default: trans_cnt_oflw_error_o = 1'b1;
- endcase // lc_cnt_i
+ if (fsm_state_i == CntIncrSt) begin
+ // In this state, the life cycle counter is incremented.
+ // Throw an error if the counter is already maxed out.
+ unique case (lc_cnt_i)
+ LcCntRaw: next_lc_cnt_o = LcCnt1;
+ LcCnt1: next_lc_cnt_o = LcCnt2;
+ LcCnt2: next_lc_cnt_o = LcCnt3;
+ LcCnt3: next_lc_cnt_o = LcCnt4;
+ LcCnt4: next_lc_cnt_o = LcCnt5;
+ LcCnt5: next_lc_cnt_o = LcCnt6;
+ LcCnt6: next_lc_cnt_o = LcCnt7;
+ LcCnt7: next_lc_cnt_o = LcCnt8;
+ LcCnt8: next_lc_cnt_o = LcCnt9;
+ LcCnt9: next_lc_cnt_o = LcCnt10;
+ LcCnt10: next_lc_cnt_o = LcCnt11;
+ LcCnt11: next_lc_cnt_o = LcCnt12;
+ LcCnt12: next_lc_cnt_o = LcCnt13;
+ LcCnt13: next_lc_cnt_o = LcCnt14;
+ LcCnt14: next_lc_cnt_o = LcCnt15;
+ LcCnt15: next_lc_cnt_o = LcCnt16;
+ LcCnt16: trans_cnt_oflw_error_o = 1'b1;
+ default: trans_cnt_oflw_error_o = 1'b1;
+ endcase // lc_cnt_i
+ end
- // Check that the decoded transition indexes are valid
- // before indexing the state transition matrix.
- if (dec_lc_state_i <= DecLcStScrap ||
- trans_target_i <= DecLcStScrap) begin
- // Check the state transition token matrix in order to see whether this
- // transition is valid. All transitions have a token index value different
- // from InvalidTokenIdx.
- if (TransTokenIdxMatrix[dec_lc_state_i][trans_target_i] != InvalidTokenIdx) begin
- // Encode the target state.
- unique case (trans_target_i)
- DecLcStRaw: next_lc_state_o = LcStRaw;
- DecLcStTestUnlocked0: next_lc_state_o = LcStTestUnlocked0;
- DecLcStTestLocked0: next_lc_state_o = LcStTestLocked0;
- DecLcStTestUnlocked1: next_lc_state_o = LcStTestUnlocked1;
- DecLcStTestLocked1: next_lc_state_o = LcStTestLocked1;
- DecLcStTestUnlocked2: next_lc_state_o = LcStTestUnlocked2;
- DecLcStTestLocked2: next_lc_state_o = LcStTestLocked2;
- DecLcStTestUnlocked3: next_lc_state_o = LcStTestUnlocked3;
- DecLcStDev: next_lc_state_o = LcStDev;
- DecLcStProd: next_lc_state_o = LcStProd;
- DecLcStProdEnd: next_lc_state_o = LcStProdEnd;
- DecLcStRma: next_lc_state_o = LcStRma;
- DecLcStScrap: next_lc_state_o = LcStScrap;
- default: ;
- endcase // trans_target_i
+ if (fsm_state_i inside {TransCheckSt, TokenCheck0St, TokenCheck1St}) begin
+ // Check that the decoded transition indexes are valid
+ // before indexing the state transition matrix.
+ if (dec_lc_state_i <= DecLcStScrap ||
+ trans_target_i <= DecLcStScrap) begin
+ // Check the state transition token matrix in order to see whether this
+ // transition is valid. All transitions have a token index value different
+ // from InvalidTokenIdx.
+ if (TransTokenIdxMatrix[dec_lc_state_i][trans_target_i] != InvalidTokenIdx) begin
+ // Encode the target state.
+ unique case (trans_target_i)
+ DecLcStRaw: next_lc_state_o = LcStRaw;
+ DecLcStTestUnlocked0: next_lc_state_o = LcStTestUnlocked0;
+ DecLcStTestLocked0: next_lc_state_o = LcStTestLocked0;
+ DecLcStTestUnlocked1: next_lc_state_o = LcStTestUnlocked1;
+ DecLcStTestLocked1: next_lc_state_o = LcStTestLocked1;
+ DecLcStTestUnlocked2: next_lc_state_o = LcStTestUnlocked2;
+ DecLcStTestLocked2: next_lc_state_o = LcStTestLocked2;
+ DecLcStTestUnlocked3: next_lc_state_o = LcStTestUnlocked3;
+ DecLcStDev: next_lc_state_o = LcStDev;
+ DecLcStProd: next_lc_state_o = LcStProd;
+ DecLcStProdEnd: next_lc_state_o = LcStProdEnd;
+ DecLcStRma: next_lc_state_o = LcStRma;
+ DecLcStScrap: next_lc_state_o = LcStScrap;
+ default: trans_invalid_error_o = 1'b1;
+ endcase // trans_target_i
+ end else begin
+ trans_invalid_error_o = 1'b1;
+ end
end else begin
trans_invalid_error_o = 1'b1;
end
- end else begin
- trans_invalid_error_o = 1'b1;
end
end