| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| { |
| name: "otbn", |
| human_name: "OpenTitan Big Number Accelerator", |
| one_line_desc: "Programmable coprocessor for asymmetric cryptography with SCA and FI countermeasures", |
| one_paragraph_desc: ''' |
| OpenTitan Big Number Accelerator (OTBN) is a programmable coprocessor for asymmetric cryptographic algorithms such as RSA or elliptic curve cryptography (ECC). |
| Such algorithms are dominated by wide integer arithmetic, which are executed on OTBN's 256-bit-wide data path. |
| The data OTBN processes is often security sensitive, and OTBN is designed to reduce the attack surface by |
| (1) keeping the instruction set and the processor design as simple as possible to aid verification, |
| (2) minimizing control flow and clearly separating it from data flow, |
| (3) limiting OTBN's instruction fetch and data memory accesses to separate, dedicated on-chip memories, |
| (4) giving OTBN software direct access to cryptographically secure random numbers, |
| and (5) implementing various hardware countermeasures to deter side-channel analysis (SCA) and fault injection (FI) attacks. |
| ''' |
| design_spec: "../doc", |
| dv_doc: "../doc/dv", |
| hw_checklist: "../doc/checklist", |
| sw_checklist: "/sw/device/lib/dif/dif_otbn" |
| revisions: [ |
| { |
| version: "0.1", |
| life_stage: "L1", |
| design_stage: "D1", |
| verification_stage: "V1", |
| dif_stage: "S1", |
| commit_id: "a46be154ebbcb7b0d5e310b5510a4ac700adc9df", |
| notes: "" |
| }, |
| { |
| version: "1.0", |
| life_stage: "L1", |
| design_stage: "D2S", |
| verification_stage: "V2S", |
| dif_stage: "S2", |
| commit_id: "a6b908283fccba3f8b6b44052c6ad87276dc21e8", |
| notes: "" |
| }, |
| ] |
| 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: "RndCnstUrndPrngSeed", |
| type: "otbn_pkg::urnd_prng_seed_t", |
| desc: ''' |
| Default seed of the PRNG used for URND. |
| ''' |
| randcount: "256", |
| randtype: "data" |
| }, |
| { name: "SecMuteUrnd" |
| type: "bit" |
| default: "0" |
| desc: ''' |
| If enabled (1), URND is advanced only when data is needed. |
| Disabled (0) by default. |
| Useful for SCA measurements only. |
| ''' |
| local: "false" |
| expose: "true" |
| } |
| { name: "SecSkipUrndReseedAtStart" |
| type: "bit" |
| default: "0" |
| desc: ''' |
| If enabled (1), URND reseed is skipped at the start of an operation. |
| Disabled (0) by default. |
| Useful for SCA measurements only. |
| ''' |
| local: "false" |
| expose: "true" |
| } |
| { 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. |
| { name: "idle", |
| type: "uni", |
| struct: "mubi4", |
| width: "1", |
| act: "req", |
| package: "prim_mubi_pkg" |
| }, |
| |
| // 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" |
| }, |
| |
| // Lifecycle RMA request and acknowledge |
| { struct: "lc_tx" |
| type: "uni" |
| name: "lc_rma_req" |
| act: "rcv" |
| default: "lc_ctrl_pkg::Off" |
| package: "lc_ctrl_pkg" |
| }, |
| |
| { struct: "lc_tx" |
| type: "uni" |
| name: "lc_rma_ack" |
| act: "req" |
| default: "lc_ctrl_pkg::Off" |
| package: "lc_ctrl_pkg" |
| }, |
| |
| // Key sideload |
| { struct: "otbn_key_req" |
| type: "uni" |
| name: "keymgr_key" |
| act: "rcv" |
| package: "keymgr_pkg" |
| }, |
| ], |
| countermeasures: [ |
| { name: "MEM.SCRAMBLE", |
| desc: "Both the imem and dmem are scrambled by using prim_ram_1p_scr." |
| } |
| { name: "DATA.MEM.INTEGRITY", |
| desc: ''' |
| Dmem is protected with ECC integrity. |
| This is carried through to OTBN's register file. |
| ''' |
| } |
| { name: "INSTRUCTION.MEM.INTEGRITY", |
| desc: ''' |
| Imem is protected with ECC integrity. |
| This is carried through into OTBN's execute stage. |
| ''' |
| } |
| { name: "BUS.INTEGRITY", |
| desc: "End-to-end bus integrity scheme." |
| } |
| { name: "CONTROLLER.FSM.GLOBAL_ESC", |
| desc: "The controller FSM moves to a terminal error state upon global escalation." |
| } |
| { name: "CONTROLLER.FSM.LOCAL_ESC", |
| desc: ''' |
| The controller FSM moves to a terminal error state upon local escalation. |
| Can be triggered by CONTROLLER.FSM.SPARSE, SCRAMBLE_CTRL.FSM.SPARSE, and START_STOP_CTRL.FSM.SPARSE. |
| ''' |
| } |
| { name: "CONTROLLER.FSM.SPARSE", |
| desc: "The controller FSM uses a sparse state encoding." |
| } |
| { name: "SCRAMBLE.KEY.SIDELOAD", |
| desc: "The scrambling key is sideloaded from OTP and thus unreadable by SW." |
| } |
| { name: "SCRAMBLE_CTRL.FSM.LOCAL_ESC", |
| desc: ''' |
| The scramble control FSM moves to a terminal error state upon local escalation. |
| Can be triggered by SCRAMBLE_CTRL.FSM.SPARSE. |
| ''' |
| } |
| { name: "SCRAMBLE_CTRL.FSM.SPARSE", |
| desc: "The scramble control FSM uses a sparse state encoding." |
| } |
| { name: "START_STOP_CTRL.FSM.GLOBAL_ESC", |
| desc: "The start-stop control FSM moves to a terminal error state upon global escalation." |
| } |
| { name: "START_STOP_CTRL.FSM.LOCAL_ESC", |
| desc: ''' |
| The start-stop control FSM moves to a terminal error state upon local escalation. |
| Can be triggered by START_STOP_CTRL.FSM.SPARSE. |
| ''' |
| } |
| { name: "START_STOP_CTRL.FSM.SPARSE", |
| desc: "The start-stop control FSM uses a sparse state encoding." |
| } |
| { name: "DATA_REG_SW.SCA", |
| desc: "Blanking of bignum data paths when unused by the executing instruction." |
| } |
| { name: "CTRL.REDUN", |
| desc: ''' |
| Check pre-decoded control matches separately decoded control from main decoder. |
| This includes control signals used for blanking, pushing/popping the call stack, controlling loop and branch/jump instructions, as well as the actual branch target. |
| ''' |
| } |
| { name: "PC.CTRL_FLOW.REDUN", |
| desc: ''' |
| Check prefetch stage PC and execute stage PC match. |
| The prefetch stage and execute stage store their PC's separately and have separate increment calculations. |
| ''' |
| } |
| { name: "RND.BUS.CONSISTENCY", |
| desc: "Comparison on successive bus values received over the EDN RND interface." |
| } |
| { name: "RND.RNG.DIGEST", |
| desc: "Checking that the random numbers received over the EDN RND interface have not been generated from entropy that failed the FIPS health checks in the entropy source." |
| } |
| { name: "RF_BASE.DATA_REG_SW.INTEGRITY" |
| desc: "Register file is protected with ECC integrity." |
| } |
| { name: "RF_BASE.DATA_REG_SW.GLITCH_DETECT" |
| desc: ''' |
| This countermeasure checks for spurious write-enable signals on the register file by monitoring the one-hot0 property of the individual write-enable strobes. |
| ''' |
| } |
| { name: "STACK_WR_PTR.CTR.REDUN" |
| desc: ''' |
| The write pointer of the stack (used for calls and loops) is redundant. |
| If the two instances of the counter mismatch, an error is emitted. |
| ''' |
| } |
| { name: "RF_BIGNUM.DATA_REG_SW.INTEGRITY" |
| desc: "Register file is protected with ECC integrity." |
| } |
| { name: "RF_BIGNUM.DATA_REG_SW.GLITCH_DETECT" |
| desc: "This countermeasure checks for spurious write-enable signals on the register file by monitoring the one-hot0 property of the individual write-enable strobes." |
| } |
| { name: "LOOP_STACK.CTR.REDUN" |
| desc: "The iteration counter of each entry in the loop step uses cross counts via prim_count." |
| } |
| { name: "LOOP_STACK.ADDR.INTEGRITY" |
| desc: "Loop start and end address on the loop stack are protected with ECC integrity." |
| } |
| { name: "CALL_STACK.ADDR.INTEGRITY" |
| desc: "Call stack entries are protected with ECC integrity." |
| } |
| { name: "START_STOP_CTRL.STATE.CONSISTENCY" |
| desc: ''' |
| The secure wipe handshake between otbn_controller and |
| otbn_start_stop_control uses a level-based req/ack interface. At the |
| otbn_controller end, there is a check for unexpected acks. In |
| otbn_start_stop_control, there is a check for secure wipe requests when |
| we aren't in a state that allows it, and also a check for if the |
| request drops at an unexpected time. |
| ''' |
| } |
| { name: "DATA.MEM.SEC_WIPE" |
| desc: ''' |
| Rotate the scrambling key, effectively wiping the dmem. |
| Initiated on command, upon fatal errors and before RMA entry. |
| ''' |
| } |
| { name: "INSTRUCTION.MEM.SEC_WIPE" |
| desc: ''' |
| Rotate the scrambling key, effectively wiping the imem. |
| Initiated on command, upon fatal errors and before RMA entry. |
| ''' |
| } |
| { name: "DATA_REG_SW.SEC_WIPE" |
| desc: ''' |
| Securely wipe programmer visible OTBN register (GPRs, WDRs, CSRs, WSRs) state with random data. |
| Initiated after reset, at the end of any OTBN operation, upon recoverable and fatal errors, and before RMA entry. |
| ''' |
| } |
| { name: "WRITE.MEM.INTEGRITY" |
| desc: ''' |
| A software visible checksum is calculated for all dmem and imem writes |
| ''' |
| } |
| { name: "CTRL_FLOW.COUNT" |
| desc: "A software visible count of instructions executed" |
| } |
| { name: "CTRL_FLOW.SCA" |
| desc: ''' |
| OTBN architecture does not have any data dependent timing behaviour |
| ''' |
| } |
| { name: "DATA.MEM.SW_NOACCESS" |
| desc: "A portion of DMEM is invisible to CPU software" |
| } |
| { name: "KEY.SIDELOAD" |
| desc: "Keys can be sideloaded without exposing them to the CPU" |
| } |
| { name: "TLUL_FIFO.CTR.REDUN", |
| desc: "The TL-UL response FIFO pointers are implemented with duplicate counters." |
| } |
| ] |
| |
| regwidth: "32" |
| registers: [ |
| // The magic values for EXECUTE, SEC_WIPE_DMEM and SEC_WIPE_IMEM in the CMD |
| // register below were generated with the sparse-fsm-encode.py script: |
| // |
| // util/design/sparse-fsm-encode.py -d 4 -m 3 -n 8 --avoid-zero -s 1 |
| // |
| // and have a hamming distance of at least 4 from one another and the zero |
| // word. |
| { name: "CMD" |
| desc: ''' |
| Command Register |
| |
| A command initiates 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. |
| |
| Writes are ignored if OTBN is not idle. |
| Unrecognized commands are ignored. |
| ''', |
| swaccess: "wo", |
| hwaccess: "hro", |
| hwext: "true", |
| hwqe: "true", |
| fields: [ |
| { bits: "7:0" |
| name: "cmd" |
| resval: 0, |
| desc: ''' |
| The operation to perform. |
| |
| <table> |
| <thead> |
| <tr> |
| <th>Value</th> |
| <th>Name</th> |
| <th>Description</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>0xd8</td> |
| <td>EXECUTE</td> |
| <td> |
| Starts the execution of the program stored in the |
| instruction memory, starting at address zero. |
| </td> |
| </tr> |
| <tr> |
| <td>0xc3</td> |
| <td>SEC_WIPE_DMEM</td> |
| <td>Securely removes all contents from the data memory.</td> |
| </tr> |
| <tr> |
| <td>0x1e</td> |
| <td>SEC_WIPE_IMEM</td> |
| <td> |
| Securely removes all contents from the instruction memory. |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| ''' |
| tags: [ |
| // Don't write this field in the automated CSR tests: it would |
| // start an operation! |
| "excl:CsrAllTests:CsrExclWrite" |
| ] |
| } |
| ], |
| } |
| { name: "CTRL", |
| desc: "Control Register", |
| hwext: "true", |
| swaccess: "rw", |
| hwaccess: "hrw", |
| hwqe: "true", |
| fields: [ |
| { bits: "0", |
| name: "software_errs_fatal", |
| resval: 0, |
| desc: ''' |
| Controls the reaction to software errors. |
| |
| When set software errors produce fatal errors, rather than |
| recoverable errors. |
| |
| Writes are ignored if OTBN is not idle. |
| ''' |
| } |
| ], |
| tags: [ |
| // Don't write this register in the automated CSR tests, because those |
| // tests are not aware whether OTBN is idle or not. If OTBN is not idle, |
| // it ignores the write and the test would fail. |
| "excl:CsrAllTests:CsrExclWrite" |
| ] |
| } |
| { name: "STATUS", |
| desc: "Status Register", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| fields: [ |
| { bits: "7:0", |
| name: "status", |
| resval: "0x04", |
| // Note: Keep the list of status codes in sync with status_e in |
| // otbn_pkg.sv. |
| desc: ''' |
| Indicates the current operational state OTBN is in. |
| |
| All BUSY values 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 idle: it is not performing any action.</td> |
| </tr> |
| <tr> |
| <td>0x01</td> |
| <td>BUSY_EXECUTE</td> |
| <td>OTBN is busy executing software.</td> |
| </tr> |
| <tr> |
| <td>0x02</td> |
| <td>BUSY_SEC_WIPE_DMEM</td> |
| <td>OTBN is busy securely wiping the data memory.</td> |
| </tr> |
| <tr> |
| <td>0x03</td> |
| <td>BUSY_SEC_WIPE_IMEM</td> |
| <td>OTBN is busy securely wiping the instruction memory.</td> |
| </tr> |
| <tr> |
| <td>0x04</td> |
| <td>BUSY_SEC_WIPE_INT</td> |
| <td>OTBN is busy securely wiping the internal state.</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 |
| "Reaction to Fatal Errors". |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| ''' |
| tags: [ |
| // Exclude this field from the automated CSR tests. The register model does not know |
| // OTBN automatically transitions from the reset state to `IDLE` as it completes the |
| // initial secure wipe of the internal state. |
| "excl:CsrAllTests:CsrExclAll" |
| ] |
| } |
| ] |
| } |
| { name: "ERR_BITS", |
| desc: ''' |
| Operation Result Register |
| |
| Describes the errors detected during an operation. |
| |
| Refer to the "List of Errors" section for a detailed description of the |
| errors. |
| |
| The host CPU can clear this register when OTBN is not running, |
| by writing any value. Write attempts while OTBN is running are ignored. |
| ''', |
| swaccess: "rw", |
| hwaccess: "hrw", |
| hwext: "true", |
| hwqe: "true", |
| tags: [ |
| // Don't use this register in the automated CSR tests. Its behaviour is |
| // "write any value to clear", which we don't model in those tests. |
| "excl:CsrAllTests:CsrExclWrite" |
| ], |
| 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." |
| } |
| { bits: "5", |
| name: "key_invalid" |
| resval: 0, |
| desc: "A `KEY_INVALID` error was observed." |
| } |
| |
| // Recoverable errors |
| { bits: "6", |
| name: "rnd_rep_chk_fail" |
| resval: 0, |
| desc: "An `RND_REP_CHK_FAIL` error was observed." |
| } |
| { bits: "7", |
| name: "rnd_fips_chk_fail" |
| resval: 0, |
| desc: "An `RND_FIPS_CHK_FAIL` 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: "bad_internal_state", |
| resval: 0, |
| desc: "A `BAD_INTERNAL_STATE` error was observed." |
| } |
| { bits: "21", |
| name: "illegal_bus_access" |
| resval: 0, |
| desc: "An `ILLEGAL_BUS_ACCESS` error was observed." |
| } |
| { bits: "22", |
| name: "lifecycle_escalation" |
| resval: 0, |
| desc: "A `LIFECYCLE_ESCALATION` error was observed." |
| } |
| { bits: "23", |
| name: "fatal_software" |
| resval: 0, |
| desc: "A `FATAL_SOFTWARE` error was observed." |
| } |
| ] |
| } |
| { name: "FATAL_ALERT_CAUSE", |
| desc: ''' |
| Fatal Alert Cause Register |
| |
| Describes any errors that led to a fatal alert. |
| A fatal error puts OTBN in locked state; the value of this register |
| does not change until OTBN is reset. |
| |
| Refer to the "List of Errors" section for a detailed description of the |
| errors. |
| ''' |
| 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: "bad_internal_state", |
| resval: 0, |
| desc: "A `BAD_INTERNAL_STATE` error was observed." |
| } |
| { bits: "5", |
| name: "illegal_bus_access" |
| resval: 0, |
| desc: "A `ILLEGAL_BUS_ACCESS` error was observed." |
| } |
| { bits: "6", |
| name: "lifecycle_escalation" |
| resval: 0, |
| desc: "A `LIFECYCLE_ESCALATION` error was observed." |
| } |
| { bits: "7", |
| name: "fatal_software" |
| resval: 0, |
| desc: "A `FATAL_SOFTWARE` error was observed." |
| } |
| ] |
| } |
| { name: "INSN_CNT", |
| desc: ''' |
| Instruction Count Register |
| |
| Returns the number of instructions executed in the current or last |
| operation. The counter saturates at 2^32-1 and is reset to 0 at the |
| start of a new operation. |
| |
| Only the EXECUTE operation counts instructions; for all other operations |
| this register remains at 0. Instructions triggering an error do not |
| count towards the total. |
| |
| Always reads as 0 if OTBN is locked. |
| |
| The host CPU can clear this register when OTBN is not running, |
| by writing any value. Write attempts while OTBN is running are ignored. |
| ''', |
| swaccess: "rw", |
| hwaccess: "hrw", |
| hwext: "true", |
| hwqe: "true", |
| fields: [ |
| { bits: "31:0", |
| name: "insn_cnt", |
| resval: 0, |
| desc: ''' |
| The number of executed instructions. |
| ''' |
| tags: [ |
| // Don't write this field in the automated CSR tests. Like |
| // ERR_BITS, its behaviour is "write any value to clear", which we |
| // don't model in those tests. |
| "excl:CsrAllTests:CsrExclWrite" |
| ] |
| } |
| ] |
| } |
| { name: "LOAD_CHECKSUM", |
| desc: ''' |
| A 32-bit CRC checksum of data written to memory |
| |
| See the "Memory Load Integrity" section of the manual for full details. |
| ''' |
| hwext: "true", |
| hwqe: "true", |
| swaccess: "rw", |
| hwaccess: "hrw", |
| fields: [ |
| { bits: "31:0", |
| name: "checksum", |
| resval: 0, |
| desc: "Checksum accumulator" |
| } |
| ] |
| tags: [ |
| // Don't read this field in any of the automated CSR tests (they |
| // will predict the value wrongly because they don't know that it |
| // updates on memory writes). |
| "excl:CsrAllTests:CsrExclAll" |
| ] |
| } |
| |
| // 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 Access |
| |
| The instruction memory may only be accessed through this window |
| while OTBN is idle. |
| |
| If OTBN is busy or locked, read accesses return 0 and write accesses |
| are ignored. |
| If OTBN is busy, any access additionally triggers an |
| ILLEGAL_BUS_ACCESS fatal error. |
| ''' |
| } |
| } |
| |
| { skipto: "0x8000" } |
| |
| // Dmem size (given as `items` below) must be a power of two. |
| { window: { |
| name: "DMEM", |
| items: "768", // 3 kB visible over the bus (1 kB scratch) |
| unusual: "true", // Needed to avoid an error because of the non-power-of-two size |
| swaccess: "rw", |
| data-intg-passthru: "true", |
| byte-write: "false", |
| desc: ''' |
| Data Memory Access |
| |
| The data memory may only be accessed through this window while OTBN |
| is idle. |
| |
| If OTBN is busy or locked, read accesses return 0 and write accesses |
| are ignored. |
| If OTBN is busy, any access additionally triggers an |
| ILLEGAL_BUS_ACCESS fatal error. |
| |
| Note that DMEM is actually 4kiB in size, but only the first 3kiB of |
| the memory is visible through this register interface. |
| ''' |
| } |
| } |
| ] |
| } |