blob: 40a3804289e6931613613da087c1a18e322e4d92 [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: [
{ 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.
'''
}
}
]
}