| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| { name: "sram_ctrl", |
| clocking: [ |
| {clock: "clk_i", reset: "rst_ni", primary: true}, |
| {clock: "clk_otp_i", reset: "rst_otp_ni"} |
| ] |
| |
| bus_interfaces: [ |
| { protocol: "tlul", direction: "device", name: "regs" } |
| { protocol: "tlul", direction: "device", name: "ram" }, |
| ], |
| |
| /////////////////////////// |
| // Interrupts and Alerts // |
| /////////////////////////// |
| |
| alert_list: [ |
| { name: "fatal_error", |
| desc: ''' |
| This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected, |
| or if the initialization mechanism has reached an invalid state. |
| ''' |
| } |
| ], |
| |
| //////////////// |
| // Parameters // |
| //////////////// |
| param_list: [ |
| { name: "RndCnstSramKey", |
| desc: "Compile-time random reset value for SRAM scrambling key.", |
| type: "otp_ctrl_pkg::sram_key_t" |
| randcount: "128", |
| randtype: "data", // randomize randcount databits |
| } |
| { name: "RndCnstSramNonce", |
| desc: "Compile-time random reset value for SRAM scrambling nonce.", |
| type: "otp_ctrl_pkg::sram_nonce_t" |
| randcount: "128", |
| randtype: "data", // randomize randcount databits |
| }, |
| { name: "RndCnstLfsrSeed", |
| desc: "Compile-time random bits for initial LFSR seed", |
| type: "sram_ctrl_pkg::lfsr_seed_t" |
| randcount: "32", |
| randtype: "data", // randomize randcount databits |
| } |
| { name: "RndCnstLfsrPerm", |
| desc: "Compile-time random permutation for LFSR output", |
| type: "sram_ctrl_pkg::lfsr_perm_t" |
| randcount: "32", |
| randtype: "perm", // random permutation for randcount elements |
| } |
| // This parameter is overridden by topgen to set the actual RAM size. |
| { name: "MemSizeRam", |
| desc: "Memory size of the RAM (in bytes).", |
| type: "int", |
| default: "0x1000" |
| }, |
| { name: "InstrExec", |
| desc: "Support execution from SRAM", |
| type: "bit", |
| local: "false", |
| expose: "true", |
| default: "1" |
| }, |
| ] |
| |
| ///////////////////////////// |
| // Intermodule Connections // |
| ///////////////////////////// |
| |
| inter_signal_list: [ |
| // Key request to OTP |
| { struct: "sram_otp_key" |
| type: "req_rsp" |
| name: "sram_otp_key" |
| act: "req" |
| package: "otp_ctrl_pkg" |
| }, |
| // SRAM attribute input |
| { struct: "ram_1p_cfg" |
| type: "uni" |
| name: "cfg" |
| act: "rcv" |
| default: "'0" |
| package: "prim_ram_1p_pkg" |
| }, |
| // Broadcast from LC |
| { struct: "lc_tx" |
| type: "uni" |
| name: "lc_escalate_en" |
| act: "rcv" |
| default: "lc_ctrl_pkg::Off" |
| package: "lc_ctrl_pkg" |
| }, |
| { struct: "lc_tx" |
| type: "uni" |
| name: "lc_hw_debug_en" |
| act: "rcv" |
| default: "lc_ctrl_pkg::Off" |
| package: "lc_ctrl_pkg" |
| }, |
| { struct: "mubi8", |
| type: "uni", |
| name: "otp_en_sram_ifetch", |
| act: "rcv", |
| package: "prim_mubi_pkg", |
| default: "prim_mubi_pkg::MuBi8False" |
| }, |
| ] |
| |
| regwidth: "32", |
| registers: { |
| regs: [ |
| //////////////////////// |
| // Ctrl / Status CSRs // |
| //////////////////////// |
| |
| { name: "STATUS", |
| desc: "SRAM status register.", |
| swaccess: "ro", |
| hwaccess: "hrw", |
| hwqe: "false", |
| fields: [ |
| { bits: "0" |
| name: "BUS_INTEG_ERROR" |
| desc: ''' |
| This bit is set to 1 if a fatal bus integrity fault is detected. |
| This error triggers a fatal_error alert. |
| This condition is terminal. |
| ''', |
| resval: 0, |
| } |
| { bits: "1" |
| name: "INIT_ERROR" |
| desc: ''' |
| This bit is set to 1 if a the initialization counter has reached an invalid state. |
| This error triggers a fatal_error alert. |
| This condition is terminal. |
| ''', |
| resval: 0, |
| } |
| { bits: "2" |
| name: "ESCALATED" |
| desc: ''' |
| Set to 1 if the sram controller has received an escalate request. |
| If this is set to 1, the scrambling keys have been reset to the default values |
| and all subsequent memory requests will be blocked. |
| This condition is terminal. |
| ''', |
| resval: 0, |
| } |
| { bits: "3" |
| name: "SCR_KEY_VALID" |
| desc: ''' |
| Set to 1 if a new scrambling key has been successfully obtained from OTP. |
| Note that if this is set to 0, the SRAM contents are still scrambled, but a |
| default all-zero key and nonce are used to do so. |
| ''', |
| resval: 0, |
| } |
| { bits: "4" |
| name: "SCR_KEY_SEED_VALID" |
| desc: ''' |
| Set to 1 if the scrambling key has been derived from a valid key seed in OTP. |
| If !!STATUS.SCR_KEY_VALID is set to 1, !!STATUS.SCR_KEY_SEED_VALID should be 1 |
| except for cases where the scrambling key seeds have not yet been provisioned to |
| OTP. In such a case, the scrambling key is still ephemeral (i.e., it is derived |
| using entropy from CSRNG), but a default all-zero value is used as the key seed. |
| ''', |
| resval: 0, |
| } |
| { bits: "5" |
| name: "INIT_DONE" |
| desc: ''' |
| Set to 1 if the hardware initialization triggered via !!CTRL.INIT has completed. |
| ''', |
| resval: 0, |
| } |
| ] |
| } |
| { name: "EXEC_REGWEN", |
| desc: "Lock register for execution enable register.", |
| swaccess: "rw0c", |
| hwaccess: "none", |
| fields: [ |
| { bits: "0" |
| desc: ''' |
| When cleared to zero, !!EXEC can not be written anymore. |
| ''', |
| resval: 1 |
| } |
| ] |
| } |
| { name: "EXEC", |
| desc: "Sram execution enable.", |
| swaccess: "rw", |
| hwaccess: "hro", |
| regwen: "EXEC_REGWEN" |
| fields: [ |
| { bits: "3:0", |
| name: "EN", |
| mubi: true, |
| desc: ''' |
| Write kMultiBitBool4True to this field to enable execution from SRAM. |
| Note that this register only takes effect if the EN_SRAM_IFETCH chicken switch |
| in the OTP HW_CFG partition is set to kMultiBitBool8True. Otherwise execution |
| from SRAM cannot be enabled via this register. |
| ''', |
| resval: false |
| }, |
| ] |
| }, |
| { name: "CTRL_REGWEN", |
| desc: "Lock register for control register.", |
| swaccess: "rw0c", |
| hwaccess: "none", |
| fields: [ |
| { bits: "0" |
| desc: ''' |
| When cleared to zero, !!CTRL can not be written anymore. |
| ''', |
| resval: 1 |
| } |
| ] |
| } |
| { name: "CTRL", |
| desc: "SRAM ctrl register.", |
| swaccess: "wo", |
| hwaccess: "hro", |
| hwqe: "true", |
| regwen: "CTRL_REGWEN" |
| tags: [// avoid writing to CTRL, as this will cause STATUS to be modified |
| "excl:CsrNonInitTests:CsrExclWrite"] |
| fields: [ |
| { bits: "0", |
| name: "RENEW_SCR_KEY", |
| desc: ''' |
| Write 1 to request a new scrambling key from OTP. After writing to this register, SRAM transactions will |
| be blocked until !!STATUS.SCR_KEY_VALID has been set to 1. If !!STATUS.SCR_KEY_VALID was already 1 |
| before triggering a key renewal, hardware will automatically clear that status bit such that software |
| can poll its status. Note that requesting a new scrambling key takes ~200 OTP cycles, which translates |
| to ~800 CPU cycles (OTP runs at 24MHz, CPU runs at 100MHz). Note that writing 1 to this register while |
| a key request is pending has no effect. |
| ''' |
| }, |
| { bits: "1", |
| name: "INIT", |
| desc: ''' |
| Write 1 to request memory init. |
| The init mechanism uses an LFSR that is seeded with a part of the nonce supplied when requesting a scrambling key. |
| Once seeded, the memory is initialized with pseudo-random data pulled from the LFSR. |
| ''' |
| }, |
| ] |
| }, |
| ], |
| |
| ram: [ |
| // no CSRs defined here. |
| ] |
| } |
| } |