|  | // Copyright lowRISC contributors. | 
|  | // Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
|  | // SPDX-License-Identifier: Apache-2.0 | 
|  | { name: "sram_ctrl", | 
|  | clock_primary: "clk_i", | 
|  | other_clock_list: [ | 
|  | "clk_otp_i", // OTP clock | 
|  | ], | 
|  | reset_primary: "rst_ni", | 
|  | other_reset_list: [ | 
|  | "rst_otp_ni" // OTP reset | 
|  | ] | 
|  |  | 
|  | bus_device: "tlul", | 
|  | bus_host: "none", | 
|  |  | 
|  | /////////////////////////// | 
|  | // Interrupts and Alerts // | 
|  | /////////////////////////// | 
|  |  | 
|  | alert_list: [ | 
|  | { name: "fatal_parity_error", | 
|  | desc: "An uncorrectable parity error has occurred in the SRAM." | 
|  | } | 
|  | ], | 
|  |  | 
|  | //////////////// | 
|  | // 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: "64", | 
|  | randtype:  "data", // randomize randcount databits | 
|  | } | 
|  | ] | 
|  |  | 
|  | ///////////////////////////// | 
|  | // Intermodule Connections // | 
|  | ///////////////////////////// | 
|  |  | 
|  | inter_signal_list: [ | 
|  | // Key request to OTP | 
|  | { struct:  "sram_otp_key" | 
|  | type:    "req_rsp" | 
|  | name:    "sram_otp_key" | 
|  | act:     "req" | 
|  | default: "'0" | 
|  | package: "otp_ctrl_pkg" | 
|  | } | 
|  | // Interface with SRAM scrambling wrapper | 
|  | { struct:  "sram_scr" | 
|  | type:    "req_rsp" | 
|  | name:    "sram_scr" | 
|  | act:     "req" | 
|  | default: "'0" | 
|  | package: "sram_ctrl_pkg" | 
|  | } | 
|  | // Broadcast from LC | 
|  | { struct:  "lc_tx" | 
|  | type:    "uni" | 
|  | name:    "lc_escalate_en" | 
|  | act:     "rcv" | 
|  | default: "lc_ctrl_pkg::Off" | 
|  | package: "lc_ctrl_pkg" | 
|  | } | 
|  | ] // inter_signal_list | 
|  |  | 
|  | regwidth: "32", | 
|  | registers: [ | 
|  |  | 
|  | //////////////////////// | 
|  | // Ctrl / Status CSRs // | 
|  | //////////////////////// | 
|  |  | 
|  | { name: "STATUS", | 
|  | desc: "SRAM status register.", | 
|  | swaccess: "ro", | 
|  | hwaccess: "hwo", | 
|  | hwqe:     "false", | 
|  | hwext:    "true", | 
|  | fields: [ | 
|  | { bits: "0" | 
|  | name: "ERROR" | 
|  | desc: ''' | 
|  | Set to 1 if an uncorrectable parity error has occurred in the SRAM macro. | 
|  | The address of the faulty access is exposed in the !!ERROR_ADDRESS register | 
|  | for debugging purposes. This is an unrecoverable error condition and causes | 
|  | the SRAM controller to continuously send out fatal_parity_error alerts. | 
|  | The error bit is sticky and can only be cleared via a reset. | 
|  | ''' | 
|  | } | 
|  | { bits: "1" | 
|  | 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. | 
|  | ''' | 
|  | } | 
|  | { bits: "2" | 
|  | 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. | 
|  | ''' | 
|  | } | 
|  | { bits: "3" | 
|  | 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. | 
|  | ''' | 
|  | } | 
|  | ] | 
|  | } | 
|  | { name: "CTRL_REGWEN", | 
|  | desc: "Lock register for control register.", | 
|  | swaccess: "rw1c", | 
|  | 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", | 
|  | hwext:    "true", | 
|  | regwen:   "CTRL_REGWEN" | 
|  | 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. | 
|  | ''' | 
|  | } | 
|  | ] | 
|  | } | 
|  |  | 
|  | { name: "ERROR_ADDRESS", | 
|  | desc: "Error address register.", | 
|  | swaccess: "ro", | 
|  | hwaccess: "hwo", | 
|  | hwqe:     "false", | 
|  | hwext:    "false", | 
|  | fields: [ | 
|  | { bits: "31:0" | 
|  | name: "ADDRESS" | 
|  | desc: ''' | 
|  | Contains the byte address of the last parity error. | 
|  | ''' | 
|  | } | 
|  | ] | 
|  | } | 
|  | ], | 
|  | } |