blob: 5aa1560e679dbe85ccbe9edce54820f9bac211ca [file] [log] [blame]
// 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: [
// 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; the commands
// are tested in more controlled form.
"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.
'''
}
],
}
{ name: "STATUS",
desc: "Status Register",
swaccess: "ro",
hwaccess: "hwo",
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 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>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 the section
"Reaction to Fatal Errors".
</td>
</tr>
</tbody>
</table>
'''
tags: [
// Don't write this field in the automated CSR tests. Despite this being RO for software
// (so you might think we couldn't write it), the csr_hw_reset test does write this by
// by default (using a backdoor access). The idea of that test is to write bogus values
// to registers, reset the block and then check that everything has its reset value.
// Doing this causes various assertions to fire and it isn't really necessary: we
// already have strong checks between this register and the output of the model.
"excl:CsrAllTests:CsrExclWrite"
]
}
]
}
{ 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.
''',
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."
}
{ bits: "22",
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: "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."
}
{ bits: "6",
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.
''',
hwext: "true",
swaccess: "ro",
hwaccess: "hwo",
fields: [
{ bits: "31:0",
name: "insn_cnt",
resval: 0,
desc: '''
The number of executed instructions.
'''
}
]
}
{ 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.
'''
swaccess: "rw",
hwaccess: "hrw",
fields: [
{ bits: "31:0",
name: "checksum",
resval: 0,
desc: "Checksum accumulator"
}
]
}
// 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: "1024", // 4 kB
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.
'''
}
}
]
}