Michael Schaffner | 86c0e32 | 2020-10-07 19:56:32 -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 |
Michael Schaffner | 2608b59 | 2023-01-13 14:12:48 -0800 | [diff] [blame] | 4 | { |
| 5 | name: "sram_ctrl", |
Andreas Kurth | 6211349 | 2023-02-13 14:50:22 +0100 | [diff] [blame] | 6 | human_name: "SRAM Controller", |
Andreas Kurth | 218294b | 2023-02-07 19:03:35 +0100 | [diff] [blame] | 7 | one_line_desc: "Interfacing on-chip SRAM blocks with system bus, supports lightweight scrambling, integrity and secure wipe", |
Andreas Kurth | f8500c0 | 2023-02-10 11:40:59 +0100 | [diff] [blame] | 8 | one_paragraph_desc: ''' |
Andreas Kurth | 6211349 | 2023-02-13 14:50:22 +0100 | [diff] [blame] | 9 | SRAM Controller instantiates on-chip SRAM and makes it accessible through the TileLink on-chip interconnect. |
| 10 | SRAM Controller includes a lightweight scrambling mechanism based on the PRINCE cipher to reduce the attack surface on the confidentiality and integrity of data stored in the SRAM. |
| 11 | For end-to-end data integrity protection, SRAM Controller stores the integrity bits alongside data words in memory and raises an alert if it detects an integrity fault. |
| 12 | SRAM Controller contains an LFSR-based initialization mechanism that overwrites the entire SRAM with pseudorandom data. |
Andreas Kurth | f8500c0 | 2023-02-10 11:40:59 +0100 | [diff] [blame] | 13 | ''' |
Michael Schaffner | 2608b59 | 2023-01-13 14:12:48 -0800 | [diff] [blame] | 14 | design_spec: "../doc", |
| 15 | dv_doc: "../doc/dv", |
| 16 | hw_checklist: "../doc/checklist", |
| 17 | sw_checklist: "/sw/device/lib/dif/dif_sram_ctrl", |
| 18 | version: "1.0", |
| 19 | life_stage: "L1", |
| 20 | design_stage: "D3", |
| 21 | verification_stage: "V2S", |
| 22 | dif_stage: "S2", |
Rupert Swarbrick | d0cbfad | 2021-06-29 17:04:51 +0100 | [diff] [blame] | 23 | clocking: [ |
| 24 | {clock: "clk_i", reset: "rst_ni", primary: true}, |
| 25 | {clock: "clk_otp_i", reset: "rst_otp_ni"} |
Michael Schaffner | 86c0e32 | 2020-10-07 19:56:32 -0700 | [diff] [blame] | 26 | ] |
| 27 | |
Rupert Swarbrick | 6c83129 | 2021-02-25 17:08:53 +0000 | [diff] [blame] | 28 | bus_interfaces: [ |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 29 | { protocol: "tlul", direction: "device", name: "regs" } |
| 30 | { protocol: "tlul", direction: "device", name: "ram" }, |
Rupert Swarbrick | 6c83129 | 2021-02-25 17:08:53 +0000 | [diff] [blame] | 31 | ], |
Michael Schaffner | 86c0e32 | 2020-10-07 19:56:32 -0700 | [diff] [blame] | 32 | |
| 33 | /////////////////////////// |
| 34 | // Interrupts and Alerts // |
| 35 | /////////////////////////// |
| 36 | |
Michael Schaffner | dc7c28d | 2020-12-21 12:48:15 -0800 | [diff] [blame] | 37 | alert_list: [ |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 38 | { name: "fatal_error", |
| 39 | desc: ''' |
| 40 | This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected, |
| 41 | or if the initialization mechanism has reached an invalid state. |
| 42 | ''' |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 43 | } |
Michael Schaffner | 86c0e32 | 2020-10-07 19:56:32 -0700 | [diff] [blame] | 44 | ], |
| 45 | |
| 46 | //////////////// |
| 47 | // Parameters // |
| 48 | //////////////// |
| 49 | param_list: [ |
Michael Schaffner | f473166 | 2020-12-17 15:39:05 -0800 | [diff] [blame] | 50 | { name: "RndCnstSramKey", |
| 51 | desc: "Compile-time random reset value for SRAM scrambling key.", |
| 52 | type: "otp_ctrl_pkg::sram_key_t" |
| 53 | randcount: "128", |
| 54 | randtype: "data", // randomize randcount databits |
| 55 | } |
| 56 | { name: "RndCnstSramNonce", |
| 57 | desc: "Compile-time random reset value for SRAM scrambling nonce.", |
| 58 | type: "otp_ctrl_pkg::sram_nonce_t" |
Timothy Chen | 95d23d9 | 2021-03-11 17:44:59 -0800 | [diff] [blame] | 59 | randcount: "128", |
Michael Schaffner | f473166 | 2020-12-17 15:39:05 -0800 | [diff] [blame] | 60 | randtype: "data", // randomize randcount databits |
Timothy Chen | 15d98b7 | 2021-02-10 20:58:34 -0800 | [diff] [blame] | 61 | }, |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 62 | { name: "RndCnstLfsrSeed", |
| 63 | desc: "Compile-time random bits for initial LFSR seed", |
| 64 | type: "sram_ctrl_pkg::lfsr_seed_t" |
| 65 | randcount: "32", |
| 66 | randtype: "data", // randomize randcount databits |
| 67 | } |
| 68 | { name: "RndCnstLfsrPerm", |
Timothy Chen | 95d23d9 | 2021-03-11 17:44:59 -0800 | [diff] [blame] | 69 | desc: "Compile-time random permutation for LFSR output", |
| 70 | type: "sram_ctrl_pkg::lfsr_perm_t" |
| 71 | randcount: "32", |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 72 | randtype: "perm", // random permutation for randcount elements |
| 73 | } |
| 74 | // This parameter is overridden by topgen to set the actual RAM size. |
| 75 | { name: "MemSizeRam", |
| 76 | desc: "Memory size of the RAM (in bytes).", |
| 77 | type: "int", |
| 78 | default: "0x1000" |
Timothy Chen | 95d23d9 | 2021-03-11 17:44:59 -0800 | [diff] [blame] | 79 | }, |
Timothy Chen | 15d98b7 | 2021-02-10 20:58:34 -0800 | [diff] [blame] | 80 | { name: "InstrExec", |
| 81 | desc: "Support execution from SRAM", |
| 82 | type: "bit", |
| 83 | local: "false", |
| 84 | expose: "true", |
| 85 | default: "1" |
| 86 | }, |
Michael Schaffner | 86c0e32 | 2020-10-07 19:56:32 -0700 | [diff] [blame] | 87 | ] |
| 88 | |
| 89 | ///////////////////////////// |
| 90 | // Intermodule Connections // |
| 91 | ///////////////////////////// |
| 92 | |
| 93 | inter_signal_list: [ |
| 94 | // Key request to OTP |
| 95 | { struct: "sram_otp_key" |
| 96 | type: "req_rsp" |
| 97 | name: "sram_otp_key" |
| 98 | act: "req" |
Michael Schaffner | 86c0e32 | 2020-10-07 19:56:32 -0700 | [diff] [blame] | 99 | package: "otp_ctrl_pkg" |
Timothy Chen | 15d98b7 | 2021-02-10 20:58:34 -0800 | [diff] [blame] | 100 | }, |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 101 | // SRAM attribute input |
| 102 | { struct: "ram_1p_cfg" |
| 103 | type: "uni" |
| 104 | name: "cfg" |
| 105 | act: "rcv" |
Michael Schaffner | dc7c28d | 2020-12-21 12:48:15 -0800 | [diff] [blame] | 106 | default: "'0" |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 107 | package: "prim_ram_1p_pkg" |
Timothy Chen | 95d23d9 | 2021-03-11 17:44:59 -0800 | [diff] [blame] | 108 | }, |
Michael Schaffner | dc7c28d | 2020-12-21 12:48:15 -0800 | [diff] [blame] | 109 | // Broadcast from LC |
| 110 | { struct: "lc_tx" |
| 111 | type: "uni" |
| 112 | name: "lc_escalate_en" |
| 113 | act: "rcv" |
| 114 | default: "lc_ctrl_pkg::Off" |
| 115 | package: "lc_ctrl_pkg" |
Timothy Chen | 15d98b7 | 2021-02-10 20:58:34 -0800 | [diff] [blame] | 116 | }, |
| 117 | { struct: "lc_tx" |
| 118 | type: "uni" |
| 119 | name: "lc_hw_debug_en" |
| 120 | act: "rcv" |
| 121 | default: "lc_ctrl_pkg::Off" |
| 122 | package: "lc_ctrl_pkg" |
| 123 | }, |
Michael Schaffner | 9b32cd1 | 2021-10-29 14:44:24 -0700 | [diff] [blame] | 124 | { struct: "mubi8", |
Timothy Chen | 15d98b7 | 2021-02-10 20:58:34 -0800 | [diff] [blame] | 125 | type: "uni", |
Michael Schaffner | 4d8199f | 2021-05-25 18:20:19 -0700 | [diff] [blame] | 126 | name: "otp_en_sram_ifetch", |
Timothy Chen | 15d98b7 | 2021-02-10 20:58:34 -0800 | [diff] [blame] | 127 | act: "rcv", |
Michael Schaffner | 9b32cd1 | 2021-10-29 14:44:24 -0700 | [diff] [blame] | 128 | package: "prim_mubi_pkg", |
| 129 | default: "prim_mubi_pkg::MuBi8False" |
Timothy Chen | 15d98b7 | 2021-02-10 20:58:34 -0800 | [diff] [blame] | 130 | }, |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 131 | ] |
Michael Schaffner | 86c0e32 | 2020-10-07 19:56:32 -0700 | [diff] [blame] | 132 | |
Michael Schaffner | 1762693 | 2021-12-13 09:10:43 -0800 | [diff] [blame] | 133 | ///////////////////// |
| 134 | // Countermeasures // |
| 135 | ///////////////////// |
| 136 | |
| 137 | countermeasures: [ |
| 138 | { name: "BUS.INTEGRITY", |
| 139 | desc: "End-to-end bus integrity scheme." |
| 140 | } |
Michael Schaffner | e8dea03 | 2022-01-21 22:23:23 -0800 | [diff] [blame] | 141 | { name: "CTRL.CONFIG.REGWEN", |
| 142 | desc: "The SRAM control register is protected by a REGWEN." |
| 143 | } |
| 144 | { name: "EXEC.CONFIG.REGWEN", |
| 145 | desc: "The SRAM execution enable register is protected by a REGWEN." |
| 146 | } |
| 147 | { name: "EXEC.CONFIG.MUBI", |
| 148 | desc: "The SRAM execution enable register is multibit encoded." |
| 149 | } |
| 150 | { name: "EXEC.INTERSIG.MUBI", |
| 151 | desc: "The SRAM execution enable signal coming from OTP is multibit encoded." |
| 152 | } |
| 153 | { name: "LC_ESCALATE_EN.INTERSIG.MUBI", |
| 154 | desc: "The life cycle escalation enable signal is multibit encoded." |
| 155 | } |
| 156 | { name: "LC_HW_DEBUG_EN.INTERSIG.MUBI", |
| 157 | desc: "The life cycle hardware debug enable signal is multibit encoded." |
| 158 | } |
Michael Schaffner | aec2cdd | 2021-12-24 08:00:29 -0800 | [diff] [blame] | 159 | { name: "MEM.INTEGRITY", |
| 160 | desc: "End-to-end data/memory integrity scheme." |
| 161 | } |
| 162 | { name: "MEM.SCRAMBLE", |
| 163 | desc: "Data is scrambled with a keyed reduced-round PRINCE cipher in CTR mode." |
| 164 | } |
| 165 | { name: "ADDR.SCRAMBLE", |
| 166 | desc: "Address is scrambled with a keyed lightweight permutation/diffusion function." |
| 167 | } |
| 168 | { name: "INSTR.BUS.LC_GATED", |
| 169 | desc: "Prevent code execution from SRAM in non-test lifecycle states." |
| 170 | } |
Michael Schaffner | fe8458e | 2022-12-08 19:02:44 -0800 | [diff] [blame] | 171 | { name: "RAM_TL_LC_GATE.FSM.SPARSE", |
| 172 | desc: "The control FSM inside the TL-UL gating primitive is sparsely encoded." |
| 173 | } |
Michael Schaffner | aec2cdd | 2021-12-24 08:00:29 -0800 | [diff] [blame] | 174 | { name: "KEY.GLOBAL_ESC", |
Michael Schaffner | d1364a4 | 2022-02-23 17:19:46 -0800 | [diff] [blame] | 175 | desc: "Scrambling key and nonce are reset to a fixed value upon escalation, and bus transactions going to the memory will be blocked." |
Michael Schaffner | aec2cdd | 2021-12-24 08:00:29 -0800 | [diff] [blame] | 176 | } |
| 177 | { name: "KEY.LOCAL_ESC", |
Michael Schaffner | d1364a4 | 2022-02-23 17:19:46 -0800 | [diff] [blame] | 178 | desc: "Scrambling key and nonce are reset to a fixed value upon local escalation due to bus integrity or counter errors, and bus transactions going to the memory will be blocked." |
Michael Schaffner | aec2cdd | 2021-12-24 08:00:29 -0800 | [diff] [blame] | 179 | } |
Michael Schaffner | d8deadc | 2022-07-20 14:48:10 -0700 | [diff] [blame] | 180 | { name: "INIT.CTR.REDUN", |
Michael Schaffner | aec2cdd | 2021-12-24 08:00:29 -0800 | [diff] [blame] | 181 | desc: "The initialization counter is duplicated." |
| 182 | } |
Michael Schaffner | c8323f0 | 2022-01-27 18:45:36 -0800 | [diff] [blame] | 183 | { name: "SCRAMBLE.KEY.SIDELOAD", |
| 184 | desc: "The scrambling key is sideloaded from OTP and thus unreadable by SW." |
| 185 | } |
Michael Schaffner | d8deadc | 2022-07-20 14:48:10 -0700 | [diff] [blame] | 186 | { name: "TLUL_FIFO.CTR.REDUN", |
| 187 | desc: "The TL-UL response FIFO pointers are implemented with duplicate counters." |
| 188 | } |
Michael Schaffner | 1762693 | 2021-12-13 09:10:43 -0800 | [diff] [blame] | 189 | ] |
| 190 | |
Michael Schaffner | 86c0e32 | 2020-10-07 19:56:32 -0700 | [diff] [blame] | 191 | regwidth: "32", |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 192 | registers: { |
| 193 | regs: [ |
| 194 | //////////////////////// |
| 195 | // Ctrl / Status CSRs // |
| 196 | //////////////////////// |
Michael Schaffner | 86c0e32 | 2020-10-07 19:56:32 -0700 | [diff] [blame] | 197 | |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 198 | { name: "STATUS", |
| 199 | desc: "SRAM status register.", |
| 200 | swaccess: "ro", |
| 201 | hwaccess: "hrw", |
| 202 | hwqe: "false", |
| 203 | fields: [ |
| 204 | { bits: "0" |
| 205 | name: "BUS_INTEG_ERROR" |
| 206 | desc: ''' |
| 207 | This bit is set to 1 if a fatal bus integrity fault is detected. |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 208 | This error triggers a fatal_error alert. |
| 209 | This condition is terminal. |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 210 | ''', |
| 211 | resval: 0, |
| 212 | } |
| 213 | { bits: "1" |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 214 | name: "INIT_ERROR" |
| 215 | desc: ''' |
| 216 | This bit is set to 1 if a the initialization counter has reached an invalid state. |
| 217 | This error triggers a fatal_error alert. |
| 218 | This condition is terminal. |
| 219 | ''', |
| 220 | resval: 0, |
| 221 | } |
| 222 | { bits: "2" |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 223 | name: "ESCALATED" |
| 224 | desc: ''' |
| 225 | Set to 1 if the sram controller has received an escalate request. |
| 226 | If this is set to 1, the scrambling keys have been reset to the default values |
| 227 | and all subsequent memory requests will be blocked. |
| 228 | This condition is terminal. |
| 229 | ''', |
| 230 | resval: 0, |
| 231 | } |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 232 | { bits: "3" |
Timothy Chen | 050b98c | 2022-03-02 15:00:19 -0800 | [diff] [blame] | 233 | hwaccess: "hwo", |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 234 | name: "SCR_KEY_VALID" |
| 235 | desc: ''' |
| 236 | Set to 1 if a new scrambling key has been successfully obtained from OTP. |
| 237 | Note that if this is set to 0, the SRAM contents are still scrambled, but a |
| 238 | default all-zero key and nonce are used to do so. |
| 239 | ''', |
| 240 | resval: 0, |
| 241 | } |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 242 | { bits: "4" |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 243 | name: "SCR_KEY_SEED_VALID" |
| 244 | desc: ''' |
| 245 | Set to 1 if the scrambling key has been derived from a valid key seed in OTP. |
| 246 | If !!STATUS.SCR_KEY_VALID is set to 1, !!STATUS.SCR_KEY_SEED_VALID should be 1 |
| 247 | except for cases where the scrambling key seeds have not yet been provisioned to |
| 248 | OTP. In such a case, the scrambling key is still ephemeral (i.e., it is derived |
| 249 | using entropy from CSRNG), but a default all-zero value is used as the key seed. |
| 250 | ''', |
| 251 | resval: 0, |
| 252 | } |
Michael Schaffner | 5c21925 | 2021-08-11 11:53:10 -0700 | [diff] [blame] | 253 | { bits: "5" |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 254 | name: "INIT_DONE" |
| 255 | desc: ''' |
| 256 | Set to 1 if the hardware initialization triggered via !!CTRL.INIT has completed. |
| 257 | ''', |
| 258 | resval: 0, |
| 259 | } |
| 260 | ] |
| 261 | } |
| 262 | { name: "EXEC_REGWEN", |
| 263 | desc: "Lock register for execution enable register.", |
| 264 | swaccess: "rw0c", |
| 265 | hwaccess: "none", |
| 266 | fields: [ |
| 267 | { bits: "0" |
| 268 | desc: ''' |
| 269 | When cleared to zero, !!EXEC can not be written anymore. |
| 270 | ''', |
| 271 | resval: 1 |
| 272 | } |
| 273 | ] |
| 274 | } |
| 275 | { name: "EXEC", |
| 276 | desc: "Sram execution enable.", |
| 277 | swaccess: "rw", |
| 278 | hwaccess: "hro", |
| 279 | regwen: "EXEC_REGWEN" |
| 280 | fields: [ |
Timothy Chen | 126c22a | 2021-09-30 15:51:46 -0700 | [diff] [blame] | 281 | { bits: "3:0", |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 282 | name: "EN", |
Timothy Chen | 126c22a | 2021-09-30 15:51:46 -0700 | [diff] [blame] | 283 | mubi: true, |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 284 | desc: ''' |
Silvestrs Timofejevs | 19b727d | 2021-11-09 11:48:06 +0000 | [diff] [blame] | 285 | Write kMultiBitBool4True to this field to enable execution from SRAM. |
Michael Schaffner | 1d09fe6 | 2022-01-10 08:57:46 -0800 | [diff] [blame] | 286 | Note that this register only takes effect if the EN_SRAM_IFETCH switch |
Silvestrs Timofejevs | 19b727d | 2021-11-09 11:48:06 +0000 | [diff] [blame] | 287 | in the OTP HW_CFG partition is set to kMultiBitBool8True. Otherwise execution |
| 288 | from SRAM cannot be enabled via this register. |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 289 | ''', |
Timothy Chen | 126c22a | 2021-09-30 15:51:46 -0700 | [diff] [blame] | 290 | resval: false |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 291 | }, |
| 292 | ] |
| 293 | }, |
| 294 | { name: "CTRL_REGWEN", |
| 295 | desc: "Lock register for control register.", |
| 296 | swaccess: "rw0c", |
| 297 | hwaccess: "none", |
| 298 | fields: [ |
| 299 | { bits: "0" |
| 300 | desc: ''' |
| 301 | When cleared to zero, !!CTRL can not be written anymore. |
| 302 | ''', |
| 303 | resval: 1 |
| 304 | } |
| 305 | ] |
| 306 | } |
| 307 | { name: "CTRL", |
| 308 | desc: "SRAM ctrl register.", |
| 309 | swaccess: "wo", |
| 310 | hwaccess: "hro", |
| 311 | hwqe: "true", |
| 312 | regwen: "CTRL_REGWEN" |
| 313 | tags: [// avoid writing to CTRL, as this will cause STATUS to be modified |
| 314 | "excl:CsrNonInitTests:CsrExclWrite"] |
| 315 | fields: [ |
| 316 | { bits: "0", |
| 317 | name: "RENEW_SCR_KEY", |
| 318 | desc: ''' |
| 319 | Write 1 to request a new scrambling key from OTP. After writing to this register, SRAM transactions will |
| 320 | be blocked until !!STATUS.SCR_KEY_VALID has been set to 1. If !!STATUS.SCR_KEY_VALID was already 1 |
| 321 | before triggering a key renewal, hardware will automatically clear that status bit such that software |
| 322 | can poll its status. Note that requesting a new scrambling key takes ~200 OTP cycles, which translates |
| 323 | to ~800 CPU cycles (OTP runs at 24MHz, CPU runs at 100MHz). Note that writing 1 to this register while |
| 324 | a key request is pending has no effect. |
| 325 | ''' |
| 326 | }, |
| 327 | { bits: "1", |
| 328 | name: "INIT", |
| 329 | desc: ''' |
| 330 | Write 1 to request memory init. |
| 331 | The init mechanism uses an LFSR that is seeded with a part of the nonce supplied when requesting a scrambling key. |
| 332 | Once seeded, the memory is initialized with pseudo-random data pulled from the LFSR. |
Michael Schaffner | 87ea23e | 2023-01-06 19:01:47 +0100 | [diff] [blame] | 333 | Note that !!CTRL.RENEW_SCR_KEY takes priority when writing 1 to both !!CTRL.RENEW_SCR_KEY and !!CTRL.INIT with the same write transaction. |
Michael Schaffner | de25997 | 2021-12-14 14:32:26 -0800 | [diff] [blame] | 334 | This means that the key request will complete first, followed by SRAM initialization. |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 335 | ''' |
| 336 | }, |
| 337 | ] |
| 338 | }, |
| 339 | ], |
Michael Schaffner | 86c0e32 | 2020-10-07 19:56:32 -0700 | [diff] [blame] | 340 | |
Michael Schaffner | 4e7114e | 2021-07-02 17:57:11 -0700 | [diff] [blame] | 341 | ram: [ |
| 342 | // no CSRs defined here. |
| 343 | ] |
| 344 | } |
Michael Schaffner | 86c0e32 | 2020-10-07 19:56:32 -0700 | [diff] [blame] | 345 | } |