Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 1 | // Copyright lowRISC contributors. |
| 2 | // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| 3 | // SPDX-License-Identifier: Apache-2.0 |
| 4 | // |
| 5 | // SRAM controller. |
| 6 | // |
| 7 | |
| 8 | `include "prim_assert.sv" |
| 9 | |
| 10 | module sram_ctrl |
Michael Schaffner | f473166 | 2020-12-17 15:39:05 -0800 | [diff] [blame] | 11 | import sram_ctrl_pkg::*; |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 12 | import sram_ctrl_reg_pkg::*; |
| 13 | #( |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 14 | // Number of words stored in the SRAM. |
| 15 | parameter int MemSizeRam = 32'h1000, |
Michael Schaffner | dc7c28d | 2020-12-21 12:48:15 -0800 | [diff] [blame] | 16 | // Enable asynchronous transitions on alerts. |
| 17 | parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}, |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 18 | // Enables the execute from SRAM feature. |
Timothy Chen | 15d98b7 | 2021-02-10 20:58:34 -0800 | [diff] [blame] | 19 | parameter bit InstrExec = 1, |
Michael Schaffner | f473166 | 2020-12-17 15:39:05 -0800 | [diff] [blame] | 20 | // Random netlist constants |
| 21 | parameter otp_ctrl_pkg::sram_key_t RndCnstSramKey = RndCnstSramKeyDefault, |
Timothy Chen | 95d23d9 | 2021-03-11 17:44:59 -0800 | [diff] [blame] | 22 | parameter otp_ctrl_pkg::sram_nonce_t RndCnstSramNonce = RndCnstSramNonceDefault, |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 23 | parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault, |
| 24 | parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 25 | ) ( |
| 26 | // SRAM Clock |
Michael Schaffner | 4d8199f | 2021-05-25 18:20:19 -0700 | [diff] [blame] | 27 | input logic clk_i, |
| 28 | input logic rst_ni, |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 29 | // OTP Clock (for key interface) |
Michael Schaffner | 4d8199f | 2021-05-25 18:20:19 -0700 | [diff] [blame] | 30 | input logic clk_otp_i, |
| 31 | input logic rst_otp_ni, |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 32 | // Bus Interface (device) for SRAM |
| 33 | input tlul_pkg::tl_h2d_t ram_tl_i, |
| 34 | output tlul_pkg::tl_d2h_t ram_tl_o, |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 35 | // Bus Interface (device) for CSRs |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 36 | input tlul_pkg::tl_h2d_t regs_tl_i, |
| 37 | output tlul_pkg::tl_d2h_t regs_tl_o, |
Michael Schaffner | dc7c28d | 2020-12-21 12:48:15 -0800 | [diff] [blame] | 38 | // Alert outputs. |
| 39 | input prim_alert_pkg::alert_rx_t [NumAlerts-1:0] alert_rx_i, |
| 40 | output prim_alert_pkg::alert_tx_t [NumAlerts-1:0] alert_tx_o, |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 41 | // Life-cycle escalation input (scraps the scrambling keys) |
Michael Schaffner | e8dea03 | 2022-01-21 22:23:23 -0800 | [diff] [blame] | 42 | // SEC_CM: LC_ESCALATE_EN.INTERSIG.MUBI |
Michael Schaffner | dc7c28d | 2020-12-21 12:48:15 -0800 | [diff] [blame] | 43 | input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, |
Michael Schaffner | e8dea03 | 2022-01-21 22:23:23 -0800 | [diff] [blame] | 44 | // SEC_CM: LC_HW_DEBUG_EN.INTERSIG.MUBI |
Timothy Chen | 15d98b7 | 2021-02-10 20:58:34 -0800 | [diff] [blame] | 45 | input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i, |
| 46 | // Otp configuration for sram execution |
Michael Schaffner | e8dea03 | 2022-01-21 22:23:23 -0800 | [diff] [blame] | 47 | // SEC_CM: EXEC.INTERSIG.MUBI |
Michael Schaffner | 9b32cd1 | 2021-10-29 14:44:24 -0700 | [diff] [blame] | 48 | input prim_mubi_pkg::mubi8_t otp_en_sram_ifetch_i, |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 49 | // Key request to OTP (running on clk_fixed) |
Michael Schaffner | c8323f0 | 2022-01-27 18:45:36 -0800 | [diff] [blame] | 50 | // SEC_CM: SCRAMBLE.KEY.SIDELOAD |
Michael Schaffner | dc7c28d | 2020-12-21 12:48:15 -0800 | [diff] [blame] | 51 | output otp_ctrl_pkg::sram_otp_key_req_t sram_otp_key_o, |
| 52 | input otp_ctrl_pkg::sram_otp_key_rsp_t sram_otp_key_i, |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 53 | // config |
| 54 | input prim_ram_1p_pkg::ram_1p_cfg_t cfg_i |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 55 | ); |
| 56 | |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 57 | // This is later on pruned to the correct width at the SRAM wrapper interface. |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 58 | parameter int unsigned Depth = MemSizeRam >> 2; |
| 59 | parameter int unsigned AddrWidth = prim_util_pkg::vbits(Depth); |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 60 | |
| 61 | `ASSERT_INIT(NonceWidthsLessThanSource_A, NonceWidth + LfsrWidth <= otp_ctrl_pkg::SramNonceWidth) |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 62 | |
Timothy Chen | 2308371 | 2022-01-19 11:12:52 -0800 | [diff] [blame] | 63 | |
| 64 | ///////////////////////////////////// |
| 65 | // Anchor incoming seeds and constants |
| 66 | ///////////////////////////////////// |
| 67 | localparam int TotalAnchorWidth = $bits(otp_ctrl_pkg::sram_key_t) + |
| 68 | $bits(otp_ctrl_pkg::sram_nonce_t); |
| 69 | |
| 70 | otp_ctrl_pkg::sram_key_t cnst_sram_key; |
| 71 | otp_ctrl_pkg::sram_nonce_t cnst_sram_nonce; |
| 72 | |
| 73 | prim_sec_anchor_buf #( |
| 74 | .Width(TotalAnchorWidth) |
| 75 | ) u_seed_anchor ( |
| 76 | .in_i({RndCnstSramKey, |
| 77 | RndCnstSramNonce}), |
| 78 | .out_o({cnst_sram_key, |
| 79 | cnst_sram_nonce}) |
| 80 | ); |
| 81 | |
| 82 | |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 83 | ////////////////////////// |
| 84 | // CSR Node and Mapping // |
| 85 | ////////////////////////// |
| 86 | |
Michael Schaffner | 2f8d204 | 2021-10-29 11:49:36 -0700 | [diff] [blame] | 87 | // We've got two bus interfaces in this module, hence two integ failure sources. |
| 88 | logic [1:0] bus_integ_error; |
| 89 | |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 90 | sram_ctrl_regs_reg2hw_t reg2hw; |
| 91 | sram_ctrl_regs_hw2reg_t hw2reg; |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 92 | |
Michael Schaffner | e8dea03 | 2022-01-21 22:23:23 -0800 | [diff] [blame] | 93 | // SEC_CM: CTRL.CONFIG.REGWEN |
| 94 | // SEC_CM: EXEC.CONFIG.REGWEN |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 95 | sram_ctrl_regs_reg_top u_reg_regs ( |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 96 | .clk_i, |
| 97 | .rst_ni, |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 98 | .tl_i (regs_tl_i), |
| 99 | .tl_o (regs_tl_o), |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 100 | .reg2hw, |
| 101 | .hw2reg, |
Michael Schaffner | 96625fb | 2022-01-13 20:45:17 -0800 | [diff] [blame] | 102 | // SEC_CM: BUS.INTEGRITY |
Michael Schaffner | 2f8d204 | 2021-10-29 11:49:36 -0700 | [diff] [blame] | 103 | .intg_err_o(bus_integ_error[0]), |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 104 | .devmode_i (1'b1) |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 105 | ); |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 106 | |
| 107 | // Key and attribute outputs to scrambling device |
| 108 | logic [otp_ctrl_pkg::SramKeyWidth-1:0] key_d, key_q; |
| 109 | logic [otp_ctrl_pkg::SramNonceWidth-1:0] nonce_d, nonce_q; |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 110 | |
Timothy Chen | 93e0438 | 2021-04-10 00:29:04 -0700 | [diff] [blame] | 111 | // tie-off unused nonce bits |
| 112 | if (otp_ctrl_pkg::SramNonceWidth > NonceWidth) begin : gen_nonce_tieoff |
| 113 | logic unused_nonce; |
| 114 | assign unused_nonce = ^nonce_q[otp_ctrl_pkg::SramNonceWidth-1:NonceWidth]; |
| 115 | end |
| 116 | |
Michael Schaffner | dc7c28d | 2020-12-21 12:48:15 -0800 | [diff] [blame] | 117 | ////////////////// |
| 118 | // Alert Sender // |
| 119 | ////////////////// |
| 120 | |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 121 | logic alert_test; |
| 122 | assign alert_test = reg2hw.alert_test.q & reg2hw.alert_test.qe; |
Michael Schaffner | dc7c28d | 2020-12-21 12:48:15 -0800 | [diff] [blame] | 123 | |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 124 | assign hw2reg.status.bus_integ_error.d = 1'b1; |
Michael Schaffner | 2f8d204 | 2021-10-29 11:49:36 -0700 | [diff] [blame] | 125 | assign hw2reg.status.bus_integ_error.de = |bus_integ_error; |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 126 | |
| 127 | logic init_error; |
| 128 | assign hw2reg.status.init_error.d = 1'b1; |
| 129 | assign hw2reg.status.init_error.de = init_error; |
Timothy Chen | 12cce14 | 2021-03-02 18:11:01 -0800 | [diff] [blame] | 130 | |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 131 | prim_alert_sender #( |
| 132 | .AsyncOn(AlertAsyncOn[0]), |
| 133 | .IsFatal(1) |
| 134 | ) u_prim_alert_sender_parity ( |
| 135 | .clk_i, |
| 136 | .rst_ni, |
Michael Schaffner | 2f8d204 | 2021-10-29 11:49:36 -0700 | [diff] [blame] | 137 | .alert_test_i ( alert_test ), |
| 138 | .alert_req_i ( |bus_integ_error | init_error ), |
| 139 | .alert_ack_o ( ), |
| 140 | .alert_state_o ( ), |
| 141 | .alert_rx_i ( alert_rx_i[0] ), |
| 142 | .alert_tx_o ( alert_tx_o[0] ) |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 143 | ); |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 144 | |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 145 | ///////////////////////// |
| 146 | // Escalation Triggers // |
| 147 | ///////////////////////// |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 148 | |
Cindy Chen | f309ea5 | 2021-04-01 18:16:57 -0700 | [diff] [blame] | 149 | lc_ctrl_pkg::lc_tx_t escalate_en; |
Michael Schaffner | 27e7017 | 2020-11-12 16:20:00 -0800 | [diff] [blame] | 150 | prim_lc_sync #( |
| 151 | .NumCopies (1) |
| 152 | ) u_prim_lc_sync ( |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 153 | .clk_i, |
| 154 | .rst_ni, |
Michael Schaffner | 27e7017 | 2020-11-12 16:20:00 -0800 | [diff] [blame] | 155 | .lc_en_i (lc_escalate_en_i), |
Srikrishna Iyer | 3d89242 | 2022-01-27 09:36:45 -0800 | [diff] [blame] | 156 | .lc_en_o ({escalate_en}) |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 157 | ); |
| 158 | |
Michael Schaffner | 96625fb | 2022-01-13 20:45:17 -0800 | [diff] [blame] | 159 | // SEC_CM: KEY.GLOBAL_ESC |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 160 | logic escalate; |
| 161 | assign escalate = (escalate_en != lc_ctrl_pkg::Off); |
| 162 | assign hw2reg.status.escalated.d = 1'b1; |
| 163 | assign hw2reg.status.escalated.de = escalate; |
| 164 | |
Michael Schaffner | 96625fb | 2022-01-13 20:45:17 -0800 | [diff] [blame] | 165 | // SEC_CM: KEY.LOCAL_ESC |
Michael Schaffner | d5faf88 | 2022-03-23 16:20:28 -0700 | [diff] [blame] | 166 | // Aggregate external and internal escalation sources. |
| 167 | // This is used on countermeasures further below (key reset and transaction blocking). |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 168 | logic local_esc; |
Srikrishna Iyer | 3d89242 | 2022-01-27 09:36:45 -0800 | [diff] [blame] | 169 | assign local_esc = escalate || |
| 170 | init_error || |
| 171 | |bus_integ_error || |
| 172 | reg2hw.status.escalated.q || |
| 173 | reg2hw.status.init_error.q || |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 174 | reg2hw.status.bus_integ_error.q; |
| 175 | |
| 176 | /////////////////////// |
| 177 | // HW Initialization // |
| 178 | /////////////////////// |
| 179 | |
| 180 | // A write to the init register reloads the LFSR seed, resets the init counter and |
| 181 | // sets init_q to flag a pending initialization request. |
| 182 | logic init_trig; |
| 183 | assign init_trig = reg2hw.ctrl.init.q & reg2hw.ctrl.init.qe; |
| 184 | |
Michael Schaffner | de25997 | 2021-12-14 14:32:26 -0800 | [diff] [blame] | 185 | logic init_d, init_q, init_done; |
| 186 | assign init_d = (init_done) ? 1'b0 : |
| 187 | (init_trig) ? 1'b1 : init_q; |
| 188 | |
| 189 | always_ff @(posedge clk_i or negedge rst_ni) begin : p_init_reg |
| 190 | if(!rst_ni) begin |
| 191 | init_q <= 1'b0; |
| 192 | end else begin |
| 193 | init_q <= init_d; |
| 194 | end |
| 195 | end |
| 196 | |
| 197 | // This waits until the scrambling keys are actually valid (this allows the SW to trigger |
| 198 | // key renewal and initialization at the same time). |
| 199 | logic init_req; |
| 200 | logic [AddrWidth-1:0] init_cnt; |
| 201 | logic key_req_pending_d, key_req_pending_q; |
| 202 | assign init_req = init_q & ~key_req_pending_q; |
| 203 | assign init_done = (init_cnt == AddrWidth'(Depth - 1)) & init_req; |
| 204 | |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 205 | // We employ two redundant counters to guard against FI attacks. |
| 206 | // If any of the two is glitched and the two counter states do not agree, |
| 207 | // we trigger an alert. |
Michael Schaffner | 96625fb | 2022-01-13 20:45:17 -0800 | [diff] [blame] | 208 | // SEC_CM: CTR.REDUN |
Michael Schaffner | de25997 | 2021-12-14 14:32:26 -0800 | [diff] [blame] | 209 | prim_count #( |
| 210 | .Width(AddrWidth), |
| 211 | .OutSelDnCnt(0), // count up |
| 212 | .CntStyle(prim_count_pkg::DupCnt) |
| 213 | ) u_prim_count ( |
| 214 | .clk_i, |
| 215 | .rst_ni, |
| 216 | .clr_i(init_trig), |
| 217 | .set_i(1'b0), |
| 218 | .set_cnt_i('0), |
| 219 | .en_i(init_req), |
| 220 | .step_i(AddrWidth'(1)), |
| 221 | .cnt_o(init_cnt), |
| 222 | .err_o(init_error) |
| 223 | ); |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 224 | |
| 225 | // Clear this bit on local escalation. |
Michael Schaffner | de25997 | 2021-12-14 14:32:26 -0800 | [diff] [blame] | 226 | assign hw2reg.status.init_done.d = init_done & ~init_trig & ~local_esc; |
| 227 | assign hw2reg.status.init_done.de = init_done | init_trig | local_esc; |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 228 | |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 229 | //////////////////////////// |
| 230 | // Scrambling Key Request // |
| 231 | //////////////////////////// |
| 232 | |
| 233 | // The scrambling key and nonce have to be requested from the OTP controller via a req/ack |
| 234 | // protocol. Since the OTP controller works in a different clock domain, we have to synchronize |
| 235 | // the req/ack protocol as described in more details here: |
| 236 | // https://docs.opentitan.org/hw/ip/otp_ctrl/doc/index.html#interfaces-to-sram-and-otbn-scramblers |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 237 | logic key_req, key_ack; |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 238 | assign key_req = reg2hw.ctrl.renew_scr_key.q & reg2hw.ctrl.renew_scr_key.qe; |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 239 | assign key_req_pending_d = (key_req) ? 1'b1 : |
| 240 | (key_ack) ? 1'b0 : key_req_pending_q; |
| 241 | |
Michael Schaffner | dc7c28d | 2020-12-21 12:48:15 -0800 | [diff] [blame] | 242 | // The SRAM scrambling wrapper will not accept any transactions while |
| 243 | // the key req is pending or if we have escalated. |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 244 | // Note that we're not using key_valid_q here, such that the SRAM can be used |
| 245 | // right after reset, where the keys are reset to the default netlist constant. |
| 246 | logic key_valid; |
| 247 | assign key_valid = ~(key_req_pending_q | reg2hw.status.escalated.q); |
Michael Schaffner | dc7c28d | 2020-12-21 12:48:15 -0800 | [diff] [blame] | 248 | |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 249 | // Clear this bit on local escalation. |
| 250 | assign hw2reg.status.scr_key_valid.d = key_ack & ~key_req & ~local_esc; |
| 251 | assign hw2reg.status.scr_key_valid.de = key_req | key_ack | local_esc; |
Timothy Chen | 95d23d9 | 2021-03-11 17:44:59 -0800 | [diff] [blame] | 252 | |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 253 | // Clear this bit on local escalation. |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 254 | logic key_seed_valid; |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 255 | assign hw2reg.status.scr_key_seed_valid.d = key_seed_valid & ~local_esc; |
| 256 | assign hw2reg.status.scr_key_seed_valid.de = key_ack | local_esc; |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 257 | |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 258 | always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs |
| 259 | if (!rst_ni) begin |
| 260 | key_req_pending_q <= 1'b0; |
Timothy Chen | 2308371 | 2022-01-19 11:12:52 -0800 | [diff] [blame] | 261 | // reset case does not use buffered values as the |
| 262 | // reset value will be directly encoded into flop types |
Michael Schaffner | f473166 | 2020-12-17 15:39:05 -0800 | [diff] [blame] | 263 | key_q <= RndCnstSramKey; |
| 264 | nonce_q <= RndCnstSramNonce; |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 265 | end else begin |
| 266 | key_req_pending_q <= key_req_pending_d; |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 267 | if (key_ack) begin |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 268 | key_q <= key_d; |
| 269 | nonce_q <= nonce_d; |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 270 | end |
Michael Schaffner | dc7c28d | 2020-12-21 12:48:15 -0800 | [diff] [blame] | 271 | // This scraps the keys. |
Michael Schaffner | 96625fb | 2022-01-13 20:45:17 -0800 | [diff] [blame] | 272 | // SEC_CM: KEY.GLOBAL_ESC |
| 273 | // SEC_CM: KEY.LOCAL_ESC |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 274 | if (local_esc) begin |
Timothy Chen | 2308371 | 2022-01-19 11:12:52 -0800 | [diff] [blame] | 275 | key_q <= cnst_sram_key; |
| 276 | nonce_q <= cnst_sram_nonce; |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 277 | end |
| 278 | end |
| 279 | end |
| 280 | |
Michael Schaffner | 028ba6b | 2021-01-07 16:00:40 -0800 | [diff] [blame] | 281 | prim_sync_reqack_data #( |
Udi Jonnalagadda | 68bae0e | 2021-01-28 13:05:21 -0800 | [diff] [blame] | 282 | .Width($bits(otp_ctrl_pkg::sram_otp_key_rsp_t)-1), |
| 283 | .DataSrc2Dst(1'b0) |
Michael Schaffner | 028ba6b | 2021-01-07 16:00:40 -0800 | [diff] [blame] | 284 | ) u_prim_sync_reqack_data ( |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 285 | .clk_src_i ( clk_i ), |
| 286 | .rst_src_ni ( rst_ni ), |
| 287 | .clk_dst_i ( clk_otp_i ), |
| 288 | .rst_dst_ni ( rst_otp_ni ), |
Pirmin Vogel | 231f772 | 2021-07-16 11:33:07 +0200 | [diff] [blame] | 289 | .req_chk_i ( 1'b1 ), |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 290 | .src_req_i ( key_req_pending_q ), |
| 291 | .src_ack_o ( key_ack ), |
| 292 | .dst_req_o ( sram_otp_key_o.req ), |
Michael Schaffner | 028ba6b | 2021-01-07 16:00:40 -0800 | [diff] [blame] | 293 | .dst_ack_i ( sram_otp_key_i.ack ), |
| 294 | .data_i ( {sram_otp_key_i.key, |
| 295 | sram_otp_key_i.nonce, |
| 296 | sram_otp_key_i.seed_valid} ), |
| 297 | .data_o ( {key_d, |
| 298 | nonce_d, |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 299 | key_seed_valid} ) |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 300 | ); |
| 301 | |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 302 | logic unused_csr_sigs; |
| 303 | assign unused_csr_sigs = ^{reg2hw.status.init_done.q, |
| 304 | reg2hw.status.scr_key_seed_valid.q}; |
| 305 | |
Timothy Chen | 15d98b7 | 2021-02-10 20:58:34 -0800 | [diff] [blame] | 306 | //////////////////// |
| 307 | // SRAM Execution // |
| 308 | //////////////////// |
| 309 | |
Weicai Yang | 5aaad4e | 2021-11-16 23:45:28 -0800 | [diff] [blame] | 310 | import prim_mubi_pkg::mubi4_t; |
Timothy Chen | 126c22a | 2021-09-30 15:51:46 -0700 | [diff] [blame] | 311 | import prim_mubi_pkg::MuBi4True; |
| 312 | import prim_mubi_pkg::MuBi4False; |
Michael Schaffner | 9b32cd1 | 2021-10-29 14:44:24 -0700 | [diff] [blame] | 313 | import prim_mubi_pkg::mubi8_test_true_strict; |
Timothy Chen | 126c22a | 2021-09-30 15:51:46 -0700 | [diff] [blame] | 314 | |
Weicai Yang | 5aaad4e | 2021-11-16 23:45:28 -0800 | [diff] [blame] | 315 | mubi4_t en_ifetch; |
Timothy Chen | 15d98b7 | 2021-02-10 20:58:34 -0800 | [diff] [blame] | 316 | if (InstrExec) begin : gen_instr_ctrl |
Weicai Yang | 5aaad4e | 2021-11-16 23:45:28 -0800 | [diff] [blame] | 317 | mubi4_t lc_ifetch_en; |
| 318 | mubi4_t reg_ifetch_en; |
Michael Schaffner | 96625fb | 2022-01-13 20:45:17 -0800 | [diff] [blame] | 319 | // SEC_CM: INSTR.BUS.LC_GATED |
Timothy Chen | 126c22a | 2021-09-30 15:51:46 -0700 | [diff] [blame] | 320 | assign lc_ifetch_en = (lc_hw_debug_en_i == lc_ctrl_pkg::On) ? MuBi4True : |
| 321 | MuBi4False; |
Michael Schaffner | e8dea03 | 2022-01-21 22:23:23 -0800 | [diff] [blame] | 322 | // SEC_CM: EXEC.CONFIG.MUBI |
Weicai Yang | 5aaad4e | 2021-11-16 23:45:28 -0800 | [diff] [blame] | 323 | assign reg_ifetch_en = mubi4_t'(reg2hw.exec.q); |
Michael Schaffner | e8dea03 | 2022-01-21 22:23:23 -0800 | [diff] [blame] | 324 | // SEC_CM: EXEC.INTERSIG.MUBI |
Michael Schaffner | 9b32cd1 | 2021-10-29 14:44:24 -0700 | [diff] [blame] | 325 | assign en_ifetch = (mubi8_test_true_strict(otp_en_sram_ifetch_i)) ? reg_ifetch_en : |
| 326 | lc_ifetch_en; |
Timothy Chen | 15d98b7 | 2021-02-10 20:58:34 -0800 | [diff] [blame] | 327 | end else begin : gen_tieoff |
Timothy Chen | 126c22a | 2021-09-30 15:51:46 -0700 | [diff] [blame] | 328 | assign en_ifetch = MuBi4False; |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 329 | |
| 330 | // tie off unused signals |
| 331 | logic unused_sigs; |
| 332 | assign unused_sigs = ^{lc_hw_debug_en_i, |
Timothy Chen | db70c37 | 2021-09-08 12:17:34 -0700 | [diff] [blame] | 333 | reg2hw.exec.q, |
| 334 | otp_en_sram_ifetch_i}; |
Timothy Chen | 15d98b7 | 2021-02-10 20:58:34 -0800 | [diff] [blame] | 335 | end |
| 336 | |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 337 | ///////////////////////// |
| 338 | // Initialization LFSR // |
| 339 | ///////////////////////// |
| 340 | |
| 341 | logic [LfsrWidth-1:0] lfsr_out; |
| 342 | prim_lfsr #( |
| 343 | .LfsrDw ( LfsrWidth ), |
| 344 | .EntropyDw ( LfsrWidth ), |
| 345 | .StateOutDw ( LfsrWidth ), |
| 346 | .DefaultSeed ( RndCnstLfsrSeed ), |
| 347 | .StatePermEn ( 1'b1 ), |
| 348 | .StatePerm ( RndCnstLfsrPerm ) |
| 349 | ) u_lfsr ( |
| 350 | .clk_i, |
| 351 | .rst_ni, |
Michael Schaffner | de25997 | 2021-12-14 14:32:26 -0800 | [diff] [blame] | 352 | .lfsr_en_i(init_req), |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 353 | .seed_en_i(init_trig), |
| 354 | .seed_i(nonce_q[NonceWidth +: LfsrWidth]), |
| 355 | .entropy_i('0), |
| 356 | .state_o(lfsr_out) |
| 357 | ); |
| 358 | |
| 359 | // Compute the correct integrity alongside for the pseudo-random initialization values. |
| 360 | logic [DataWidth - 1 :0] lfsr_out_integ; |
Michael Schaffner | e40dfbd | 2021-08-05 17:13:00 -0700 | [diff] [blame] | 361 | tlul_data_integ_enc u_tlul_data_integ_enc ( |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 362 | .data_i(lfsr_out), |
Michael Schaffner | e40dfbd | 2021-08-05 17:13:00 -0700 | [diff] [blame] | 363 | .data_intg_o(lfsr_out_integ) |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 364 | ); |
| 365 | |
| 366 | ///////////////////////////////// |
| 367 | // SRAM with scrambling device // |
| 368 | ///////////////////////////////// |
| 369 | |
| 370 | logic tlul_req, tlul_gnt, tlul_we; |
| 371 | logic [AddrWidth-1:0] tlul_addr; |
| 372 | logic [DataWidth-1:0] tlul_wdata, tlul_wmask; |
| 373 | |
| 374 | logic sram_intg_error, sram_req, sram_gnt, sram_we, sram_rvalid; |
| 375 | logic [AddrWidth-1:0] sram_addr; |
| 376 | logic [DataWidth-1:0] sram_wdata, sram_wmask, sram_rdata; |
| 377 | |
| 378 | tlul_adapter_sram #( |
| 379 | .SramAw(AddrWidth), |
| 380 | .SramDw(DataWidth - tlul_pkg::DataIntgWidth), |
| 381 | .Outstanding(2), |
| 382 | .ByteAccess(1), |
| 383 | .CmdIntgCheck(1), |
| 384 | .EnableRspIntgGen(1), |
| 385 | .EnableDataIntgGen(0), |
Michael Schaffner | 96625fb | 2022-01-13 20:45:17 -0800 | [diff] [blame] | 386 | .EnableDataIntgPt(1) // SEC_CM: MEM.INTEGRITY |
Michael Schaffner | e245f10 | 2021-08-25 16:23:08 -0700 | [diff] [blame] | 387 | ) u_tlul_adapter_sram ( |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 388 | .clk_i, |
| 389 | .rst_ni, |
| 390 | .tl_i (ram_tl_i), |
| 391 | .tl_o (ram_tl_o), |
| 392 | .en_ifetch_i (en_ifetch), |
| 393 | .req_o (tlul_req), |
| 394 | .req_type_o (), |
| 395 | .gnt_i (tlul_gnt), |
| 396 | .we_o (tlul_we), |
| 397 | .addr_o (tlul_addr), |
| 398 | .wdata_o (tlul_wdata), |
| 399 | .wmask_o (tlul_wmask), |
Michael Schaffner | 96625fb | 2022-01-13 20:45:17 -0800 | [diff] [blame] | 400 | // SEC_CM: BUS.INTEGRITY |
Michael Schaffner | 2f8d204 | 2021-10-29 11:49:36 -0700 | [diff] [blame] | 401 | .intg_error_o(bus_integ_error[1]), |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 402 | .rdata_i (sram_rdata), |
| 403 | .rvalid_i (sram_rvalid), |
| 404 | .rerror_i ('0) |
| 405 | ); |
| 406 | |
| 407 | // Interposing mux logic for initialization with pseudo random data. |
Michael Schaffner | 98e8210 | 2022-03-25 21:09:49 -0700 | [diff] [blame] | 408 | // TODO: use tlul_lc_gate for local_esc gating instead. |
| 409 | assign sram_req = tlul_req & ~local_esc | init_req; |
Michael Schaffner | df0596a | 2022-02-17 16:45:16 -0800 | [diff] [blame] | 410 | assign tlul_gnt = sram_gnt & ~init_req & ~local_esc; |
Michael Schaffner | de25997 | 2021-12-14 14:32:26 -0800 | [diff] [blame] | 411 | assign sram_we = tlul_we | init_req; |
| 412 | assign sram_intg_error = local_esc & ~init_req; |
| 413 | assign sram_addr = (init_req) ? init_cnt : tlul_addr; |
| 414 | assign sram_wdata = (init_req) ? lfsr_out_integ : tlul_wdata; |
| 415 | assign sram_wmask = (init_req) ? {DataWidth{1'b1}} : tlul_wmask; |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 416 | |
Michael Schaffner | 96625fb | 2022-01-13 20:45:17 -0800 | [diff] [blame] | 417 | // SEC_CM: MEM.SCRAMBLE, ADDR.SCRAMBLE |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 418 | prim_ram_1p_scr #( |
| 419 | .Width(DataWidth), |
| 420 | .Depth(Depth), |
| 421 | .EnableParity(0), |
| 422 | .DataBitsPerMask(DataWidth), |
| 423 | .DiffWidth(DataWidth) |
| 424 | ) u_prim_ram_1p_scr ( |
| 425 | .clk_i, |
| 426 | .rst_ni, |
| 427 | |
| 428 | .key_valid_i (key_valid), |
| 429 | .key_i (key_q), |
| 430 | .nonce_i (nonce_q[NonceWidth-1:0]), |
| 431 | |
| 432 | .req_i (sram_req), |
| 433 | .intg_error_i(sram_intg_error), |
| 434 | .gnt_o (sram_gnt), |
| 435 | .write_i (sram_we), |
| 436 | .addr_i (sram_addr), |
| 437 | .wdata_i (sram_wdata), |
| 438 | .wmask_i (sram_wmask), |
| 439 | .rdata_o (sram_rdata), |
| 440 | .rvalid_o (sram_rvalid), |
| 441 | .rerror_o ( ), |
| 442 | .raddr_o ( ), |
| 443 | .cfg_i |
| 444 | ); |
Timothy Chen | 15d98b7 | 2021-02-10 20:58:34 -0800 | [diff] [blame] | 445 | |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 446 | //////////////// |
| 447 | // Assertions // |
| 448 | //////////////// |
| 449 | |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 450 | `ASSERT_KNOWN(RegsTlOutKnown_A, regs_tl_o) |
Timothy Chen | 2cf0ca4 | 2022-05-05 08:58:55 -0700 | [diff] [blame] | 451 | `ASSERT_KNOWN(RamTlOutKnown_A, ram_tl_o.d_valid) |
| 452 | `ASSERT_KNOWN_IF(RamTlOutPayLoadKnown_A, ram_tl_o, ram_tl_o.d_valid) |
Michael Schaffner | dc7c28d | 2020-12-21 12:48:15 -0800 | [diff] [blame] | 453 | `ASSERT_KNOWN(AlertOutKnown_A, alert_tx_o) |
| 454 | `ASSERT_KNOWN(SramOtpKeyKnown_A, sram_otp_key_o) |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 455 | |
Michael Schaffner | de25997 | 2021-12-14 14:32:26 -0800 | [diff] [blame] | 456 | // Alert assertions for redundant counters. |
| 457 | `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntCheck_A, |
| 458 | u_prim_count, alert_tx_o[0]) |
| 459 | |
Michael Schaffner | 798906d | 2020-10-07 19:57:59 -0700 | [diff] [blame] | 460 | endmodule : sram_ctrl |