| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| { name: "otbn" |
| clocking: [ |
| {clock: "clk_i", reset: "rst_ni", idle: "idle_o", primary: true}, |
| {clock: "clk_edn_i", reset: "rst_edn_ni", idle: "idle_o"}, |
| {clock: "clk_otp_i", reset: "rst_otp_ni", idle: "idle_otp_o"} |
| ] |
| bus_interfaces: [ |
| { protocol: "tlul", direction: "device" } |
| ], |
| param_list: [ |
| { name: "Stub", |
| type: "bit", |
| default: "0", |
| desc: "Stub out the core of Otbn logic" |
| local: "false", |
| expose: "true" |
| }, |
| { name: "RegFile", |
| type: "otbn_pkg::regfile_e", |
| default: "otbn_pkg::RegFileFF", |
| desc: "Selection of the register file implementation. See otbn_pkg.sv." |
| local: "false", |
| expose: "true" |
| }, |
| { name: "RndCnstUrndLfsrSeed", |
| type: "otbn_pkg::urnd_lfsr_seed_t", |
| desc: ''' |
| Default seed of the PRNG used for URND. |
| ''' |
| randcount: "256", |
| randtype: "data" |
| }, |
| { name: "RndCnstUrndChunkLfsrPerm", |
| type: "otbn_pkg::urnd_chunk_lfsr_perm_t", |
| desc: ''' |
| Permutation applied to the LFSR chunks of the PRNG used for URND. |
| ''' |
| randcount: "64", |
| randtype: "perm" |
| }, |
| { name: "RndCnstOtbnKey", |
| type: "otp_ctrl_pkg::otbn_key_t", |
| desc: ''' |
| Compile-time random reset value for IMem/DMem scrambling key. |
| ''' |
| randcount: "128", |
| randtype: "data" |
| }, |
| { name: "RndCnstOtbnNonce", |
| type: "otp_ctrl_pkg::otbn_nonce_t", |
| desc: ''' |
| Compile-time random reset value for IMem/DMem scrambling nonce. |
| ''' |
| randcount: "64", |
| randtype: "data" |
| }, |
| ] |
| interrupt_list: [ |
| { name: "done" |
| desc: "OTBN has completed the operation" |
| } |
| ] |
| alert_list: [ |
| { name: "fatal" |
| desc: "A fatal error. Fatal alerts are non-recoverable and will be asserted until a hard reset." |
| } |
| { name: "recov" |
| desc: "A recoverable error. Just sent once (as the processor stops)." |
| } |
| ] |
| |
| inter_signal_list: [ |
| // Key request to OTP |
| { struct: "otbn_otp_key" |
| type: "req_rsp" |
| name: "otbn_otp_key" |
| act: "req" |
| default: "'0" |
| package: "otp_ctrl_pkg" |
| }, |
| // EDN interface for RND |
| { struct: "edn" |
| type: "req_rsp" |
| name: "edn_rnd" |
| act: "req" |
| package: "edn_pkg" |
| }, |
| |
| // EDN interface for URND |
| { struct: "edn" |
| type: "req_rsp" |
| name: "edn_urnd" |
| act: "req" |
| package: "edn_pkg" |
| }, |
| |
| // OTBN is not performing any operation and can be clock/power-gated. One |
| // idle for each clock domain (see assignments in "clocking" dictionary above). |
| { name: "idle", |
| type: "uni", |
| struct: "logic", |
| width: "1", |
| act: "req", |
| }, |
| { name: "idle_otp", |
| type: "uni", |
| struct: "logic", |
| width: "1", |
| act: "req", |
| }, |
| |
| // ram configuration |
| { struct: "ram_1p_cfg", |
| package: "prim_ram_1p_pkg", |
| type: "uni", |
| name: "ram_cfg", |
| act: "rcv" |
| }, |
| |
| // Lifecycle escalation |
| { struct: "lc_tx" |
| type: "uni" |
| name: "lc_escalate_en" |
| act: "rcv" |
| default: "lc_ctrl_pkg::Off" |
| package: "lc_ctrl_pkg" |
| }, |
| ], |
| |
| regwidth: "32" |
| registers: [ |
| { name: "CMD" |
| desc: "command register", |
| swaccess: "wo", |
| hwaccess: "hro", |
| hwext: "true", |
| hwqe: "true", |
| fields: [ |
| { bits: "7:0" |
| name: "cmd" |
| resval: 0, |
| desc: ''' |
| Initiates an OTBN operation. |
| |
| A command starts an OTBN operation. While performing the operation, |
| OTBN is busy; the !!STATUS register reflects that. |
| |
| All operations signal their completion by raising the done |
| interrupt; alternatively, software may poll the !!STATUS register. |
| |
| New commands are only accepted while OTBN is idle, as indicated |
| by the !!STATUS register. Writes while !!STATUS is not IDLE are |
| ignored. |
| |
| Unrecognized commands are ignored. |
| |
| <table> |
| <thead> |
| <tr> |
| <th>Value</th> |
| <th>Name</th> |
| <th>Description</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>0x01</td> |
| <td>EXECUTE</td> |
| <td> |
| Start the execution of the program stored in the |
| instruction memory, starting at address !!START_ADDR. |
| </td> |
| </tr> |
| <tr> |
| <td>0x02</td> |
| <td>SEC_WIPE_DMEM</td> |
| <td>Securely remove all contents from the data memory.</td> |
| </tr> |
| <tr> |
| <td>0x03</td> |
| <td>SEC_WIPE_IMEM</td> |
| <td> |
| Securely remove all contents from the instruction memory. |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| ''' |
| tags: [ |
| // Don't write this field in the automated CSR tests; the commands |
| // are tested in more controlled form. |
| "excl:CsrAllTests:CsrExclWrite" |
| ] |
| } |
| ], |
| } |
| { name: "STATUS", |
| desc: "Status", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| fields: [ |
| { bits: "7:0", |
| name: "status", |
| resval: 0, |
| // Note: Keep the list of status codes in sync with status_e in |
| // otbn_pkg.sv. |
| desc: ''' |
| Indicates the current state OTBN is in. |
| |
| All BUSY flags represent an operation started by a write to the |
| !!CMD register. |
| |
| <table> |
| <thead> |
| <tr> |
| <th>Value</th> |
| <th>Name</th> |
| <th>Description</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>0x00</td> |
| <td>IDLE</td> |
| <td>OTBN is not performing any action.</td> |
| </tr> |
| <tr> |
| <td>0x01</td> |
| <td>BUSY_EXECUTE</td> |
| <td>OTBN is executing software.</td> |
| </tr> |
| <tr> |
| <td>0x02</td> |
| <td>BUSY_SEC_WIPE_DMEM</td> |
| <td>OTBN is securely wiping the data memory.</td> |
| </tr> |
| <tr> |
| <td>0x03</td> |
| <td>BUSY_SEC_WIPE_IMEM</td> |
| <td>OTBN is securely wiping the instruction memory.</td> |
| </tr> |
| <tr> |
| <td>0xFF</td> |
| <td>LOCKED</td> |
| <td> |
| OTBN is locked as reaction to a fatal error, and must be |
| reset to unlock it again. See also the section on fatal |
| error handling. |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| ''' |
| } |
| ] |
| } // register : status |
| { name: "ERR_BITS", |
| desc: ''' |
| Description of an error detected during an operation. |
| |
| Refer to the section "List of Errors" for a detailed description of the |
| errors. |
| ''', |
| swaccess: "ro", |
| hwaccess: "hwo", |
| fields: [ |
| // Software errors |
| { bits: "0", |
| name: "bad_data_addr" |
| resval: 0, |
| desc: "A `BAD_DATA_ADDR` error was observed." |
| } |
| { bits: "1", |
| name: "bad_insn_addr" |
| resval: 0, |
| desc: "A `BAD_INSN_ADDR` error was observed." |
| } |
| { bits: "2", |
| resval: 0, |
| name: "call_stack" |
| desc: "A `CALL_STACK` error was observed." |
| } |
| { bits: "3", |
| resval: 0, |
| name: "illegal_insn" |
| desc: "An `ILLEGAL_INSN` error was observed." |
| } |
| { bits: "4", |
| name: "loop" |
| resval: 0, |
| desc: "A `LOOP` error was observed." |
| } |
| |
| // Fatal errors. Keep in sync with list in FATAL_ALERT_CAUSE. |
| { bits: "16", |
| name: "imem_intg_violation" |
| resval: 0, |
| desc: "A `IMEM_INTG_VIOLATION` error was observed." |
| } |
| { bits: "17", |
| name: "dmem_intg_violation" |
| resval: 0, |
| desc: "A `DMEM_INTG_VIOLATION` error was observed." |
| } |
| { bits: "18", |
| name: "reg_intg_violation" |
| resval: 0, |
| desc: "A `REG_INTG_VIOLATION` error was observed." |
| } |
| { bits: "19", |
| name: "bus_intg_violation" |
| resval: 0, |
| desc: "A `BUS_INTG_VIOLATION` error was observed." |
| } |
| { bits: "20", |
| name: "illegal_bus_access" |
| resval: 0, |
| desc: "An `ILLEGAL_BUS_ACCESS` error was observed." |
| } |
| { bits: "21", |
| name: "lifecycle_escalation" |
| resval: 0, |
| desc: "A `LIFECYCLE_ESCALATION` error was observed." |
| } |
| ] |
| } // register : err_bits |
| { name: "START_ADDR", |
| desc: "Start byte address in the instruction memory", |
| swaccess: "wo", |
| hwaccess: "hro", |
| fields: [ |
| { bits: "31:0", |
| name: "start_addr", |
| resval: 0, |
| desc: ''' |
| Byte address in the instruction memory OTBN starts to execute from |
| when instructed to do so by issuing the EXECUTE command. |
| ''' |
| } |
| ] |
| } // register : start_addr |
| { name: "FATAL_ALERT_CAUSE", |
| desc: ''' |
| Description of the error that caused a fatal alert. |
| |
| The bits of this register correspond to errors that can cause a fatal |
| alert. Software can read these bits to see what went wrong. Once set, |
| these bits cannot be cleared. |
| ''' |
| swaccess: "ro", |
| hwaccess: "hwo", |
| fields: [ |
| // Keep the list in sync with the fatal errors in ERR_BITS. |
| { bits: "0", |
| name: "imem_intg_violation", |
| resval: 0, |
| desc: "A `IMEM_INTG_VIOLATION` error was observed." |
| } |
| { bits: "1", |
| name: "dmem_intg_violation", |
| resval: 0, |
| desc: "A `DMEM_INTG_VIOLATION` error was observed." |
| } |
| { bits: "2", |
| name: "reg_intg_violation", |
| resval: 0, |
| desc: "A `REG_INTG_VIOLATION` error was observed." |
| } |
| { bits: "3", |
| name: "bus_intg_violation", |
| resval: 0, |
| desc: "A `BUS_INTG_VIOLATION` error was observed." |
| } |
| { bits: "4", |
| name: "illegal_bus_access" |
| resval: 0, |
| desc: "A `ILLEGAL_BUS_ACCESS` error was observed." |
| } |
| { bits: "5", |
| name: "lifecycle_escalation" |
| resval: 0, |
| desc: "A `LIFECYCLE_ESCALATION` error was observed." |
| } |
| ] |
| } // register : fatal_alert_cause |
| { name: "INSN_CNT", |
| desc: "Instruction Counter", |
| hwext: "true", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| fields: [ |
| { bits: "31:0", |
| name: "insn_cnt", |
| resval: 0, |
| desc: ''' |
| The number of instructions executed in the current or last OTBN run. |
| Saturates at 2^32-1. The counter is reset to zero when a new operation |
| is started. Instructions triggering an error do not count as being executed. |
| ''' |
| } |
| ] |
| } // register : insn_cnt |
| |
| // Give IMEM and DMEM 16 KiB address space, each, to allow for easy expansion |
| // of the actual IMEM and DMEM sizes without changing the address map. |
| { skipto: "0x4000" } |
| |
| // Imem size (given as `items` below) must be a power of two. |
| { window: { |
| name: "IMEM", |
| items: "1024", // 4 kB |
| swaccess: "rw", |
| data-intg-passthru: "true", |
| byte-write: "false", |
| desc: ''' |
| Instruction Memory. |
| |
| The instruction memory may only be accessed through this register while OTBN is idle, as indicated by the !!STATUS register. |
| Accesses while OTBN is not idle result in a fatal error, setting the fatal_illegal_bus_access error bit. |
| ''' |
| } |
| } |
| |
| { skipto: "0x8000" } |
| |
| // Dmem size (given as `items` below) must be a power of two. |
| { window: { |
| name: "DMEM", |
| items: "1024", // 4 kB |
| swaccess: "rw", |
| data-intg-passthru: "true", |
| byte-write: "false", |
| desc: ''' |
| Data Memory. |
| |
| The data memory may only be accessed through this register while OTBN is idle, as indicated by the !!STATUS register. |
| Accesses while OTBN is not idle result in a fatal error, setting the fatal_illegal_bus_access error bit. |
| ''' |
| } |
| } |
| ] |
| } |