| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| // |
| // Key manager date enable generation |
| // This is a redundant alternative to data_valid |
| |
| `include "prim_assert.sv" |
| |
| module keymgr_data_en_state |
| import keymgr_pkg::*; |
| import keymgr_reg_pkg::*; |
| ( |
| input clk_i, |
| input rst_ni, |
| |
| input adv_en_i, |
| input id_en_i, |
| input gen_en_i, |
| input op_done_i, |
| input op_start_i, |
| output logic data_en_o, |
| output logic fsm_err_o |
| ); |
| |
| // This is a separate data path from the FSM used to control the data_en_o output |
| // Hamming distance histogram: |
| // |
| // 0: -- |
| // 1: -- |
| // 2: -- |
| // 3: -- |
| // 4: -- |
| // 5: |||||||||||||||||||| (50.00%) |
| // 6: |||||||||||||||| (40.00%) |
| // 7: |||| (10.00%) |
| // 8: -- |
| // 9: -- |
| // 10: -- |
| // |
| // Minimum Hamming distance: 5 |
| // Maximum Hamming distance: 7 |
| // Minimum Hamming weight: 5 |
| // Maximum Hamming weight: 7 |
| // |
| localparam int DataStateWidth = 10; |
| typedef enum logic [DataStateWidth-1:0] { |
| StCtrlDataIdle = 10'b1001110111, |
| StCtrlDataEn = 10'b1110001011, |
| StCtrlDataDis = 10'b0110100110, |
| StCtrlDataWait = 10'b1010111000, |
| StCtrlDataInvalid = 10'b1111010100 |
| } state_e; |
| |
| state_e state_d, state_q; |
| |
| // SEC_CM: DATA.FSM.SPARSE |
| `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, StCtrlDataIdle) |
| |
| // The below control path is used for modulating the datapath to sideload and sw keys. |
| // This path is separate from the data_valid_o path, thus creating two separate attack points. |
| // The data is only enabled when a non-advance operation is invoked. |
| // When an advance operation is called, the data is disabled. It will stay disabled until an |
| // entire completion sequence is seen (op_done_o assert -> start_i de-assertion). |
| // When a generate operation is called, the data is enabled. However, any indication of this |
| // supposedly being an advance call will force the path to disable again. |
| always_comb begin |
| state_d = state_q; |
| data_en_o = 1'b0; |
| fsm_err_o = 1'b0; |
| unique case (state_q) |
| |
| StCtrlDataIdle: begin |
| if (adv_en_i) begin |
| state_d = StCtrlDataDis; |
| end else if (id_en_i || gen_en_i) begin |
| state_d = StCtrlDataEn; |
| end |
| end |
| |
| StCtrlDataEn: begin |
| data_en_o = 1'b1; |
| if (op_done_i) begin |
| state_d = StCtrlDataWait; |
| end else if (adv_en_i) begin |
| state_d = StCtrlDataDis; |
| end |
| end |
| |
| StCtrlDataDis: begin |
| if (op_done_i) begin |
| state_d = StCtrlDataWait; |
| end |
| end |
| |
| StCtrlDataWait: begin |
| if (!op_start_i) begin |
| state_d = StCtrlDataIdle; |
| end |
| end |
| |
| default: begin |
| fsm_err_o = 1'b1; |
| end |
| |
| |
| endcase // unique case (state_q) |
| end |
| |
| |
| endmodule // keymgr_data_en_state |