blob: b45476d1a514086955b9a4f9da7df12254aa5e21 [file] [log] [blame] [view]
Rupert Swarbrick83c6aef2020-11-19 13:02:58 +00001---
2title: OpenTitan Big Number Accelerator (OTBN) Instruction Set Architecture
3---
4
5This document describes the instruction set for OTBN.
Philipp Wagner07494a32021-03-18 15:59:57 +00006For more details about the processor itself, see the [OTBN Technical Specification]({{< relref "." >}}).
Rupert Swarbrick83c6aef2020-11-19 13:02:58 +00007In particular, this document assumes knowledge of the *Processor State* section from that guide.
8
9The instruction set is split into *base* and *big number* subsets.
10The base subset (described first) is similar to RISC-V's RV32I instruction set.
11It also includes a hardware call stack and hardware loop instructions.
12The big number subset is designed to operate on 256b WDRs.
13It doesn't include any control flow instructions, and just supports load/store, logical and arithmetic operations.
14
Rupert Swarbrickbd3d9ea2021-01-19 12:36:33 +000015In the instruction documentation that follows, each instruction has a syntax example.
16For example, the `SW` instruction has syntax:
17```
18 SW <grs2>, <offset>(<grs1>)
19```
20This means that it takes three operands, called `grs2`, `offset` and `grs1`.
21These operands are further documented in a table.
22Immediate operands like `offset` show their valid range of values.
23
Rupert Swarbrickbd3d9ea2021-01-19 12:36:33 +000024Below the table of operands is an encoding table.
25This shows how the 32 bits of the instruction word are filled in.
26Ranges of bits that map to an operand are named (in capitals) and those names are used in the operand table.
27For example, the `SW` instruction's `offset` operand is split across two ranges of bits (31:25 and 11:7) called `OFF_1` and `OFF_0`, respectively.
28
Rupert Swarbrickb4142bc2021-02-19 17:21:23 +000029# Pseudo-code for operation descriptions
30
31Each instruction has an Operation section.
32This is written in a Python-like pseudo-code, generated from the instruction set simulator (which can be found at `hw/ip/otbn/dv/otbnsim`).
33The code is generated from Python, but there are some extra changes made to aid readability.
34
35All instruction operands are considered to be in scope and have integer values.
36These values come from the encoded bits in the instruction and the operand table for the instruction describes exactly how they are decoded.
37Some operands are encoded PC-relative.
38Such an operand has its absolute value (an address) when it appears in the Operation section.
39
40Some state updates are represented as an assignment, but take effect at the end of the instruction.
41This includes register updates or jumps and branches (updating the PC).
42To denote this, we use the &#x21d0; symbol, reminiscent of Verilog's non-blocking assignment.
43
44The program counter (PC) is represented as a variable called `PC`.
45
46Machine registers are accessed with an array syntax.
47These arrays are:
48
49- `GPRs`: General purpose registers
50- `WDRs`: Wide data registers
51- `CSRs`: Control and status registers
52- `WSRs`: Wide special purpose registers
53
54Accesses to these arrays are as unsigned integers.
55The instruction descriptions are written to ensure that any value written to a register is representable.
56For example, a write to `GPRs[2]` will always have a non-negative value less than `1 << 32`.
57
58Memory accesses are represented as function calls.
59This is because the memory can be accessed on either the narrow or the wide side, which isn't easy to represent with an array syntax.
60Memory loads are represented as `DMEM.load_u32(addr)`, `DMEM.load_u256(addr)`.
61Memory stores are represented as `DMEM.store_u32(addr, value)` and `DMEM.store_u256(addr, value)`.
62In all cases, memory values are interpreted as unsigned integers and, as for register accesses, the instruction descriptions are written to ensure that any value stored to memory is representable.
63
Rupert Swarbrick6e287c32021-08-09 08:07:29 +010064Some instructions can stall for one or more cycles (those instructions that access memory, CSRs or WSRs).
65To represent this precisely in the pseudo-code, and the simulator reference model, such instructions execute a `yield` statement to stall the processor for a cycle.
66
Rupert Swarbrickb4142bc2021-02-19 17:21:23 +000067There are a few other helper functions, defined here to avoid having to inline their bodies into each instruction.
68```python3
69def from_2s_complement(n: int) -> int:
70 '''Interpret the bits of unsigned integer n as a 32-bit signed integer'''
71 assert 0 <= n < (1 << 32)
72 return n if n < (1 << 31) else n - (1 << 32)
73
74
75def to_2s_complement(n: int) -> int:
76 '''Interpret the bits of signed integer n as a 32-bit unsigned integer'''
77 assert -(1 << 31) <= n < (1 << 31)
78 return (1 << 32) + n if n < 0 else n
Rupert Swarbrick3c5d7642021-02-22 11:38:52 +000079
80def logical_byte_shift(value: int, shift_type: int, shift_bytes: int) -> int:
81 '''Logical shift value by shift_bytes to the left or right.
82
83 value should be an unsigned 256-bit value. shift_type should be 0 (shift
84 left) or 1 (shift right), matching the encoding of the big number
85 instructions. shift_bytes should be a non-negative number of bytes to shift
86 by.
87
88 Returns an unsigned 256-bit value, truncating on an overflowing left shift.
89
90 '''
91 mask256 = (1 << 256) - 1
92 assert 0 <= value <= mask256
93 assert 0 <= shift_type <= 1
94 assert 0 <= shift_bytes
95
96 shift_bits = 8 * shift_bytes
97 shifted = value << shift_bits if shift_type == 0 else value >> shift_bits
98 return shifted & mask256
Rupert Swarbrick98cc0512021-02-22 12:48:34 +000099
100def extract_quarter_word(value: int, qwsel: int) -> int:
101 '''Extract a 64-bit quarter word from a 256-bit value.'''
102 assert 0 <= value < (1 << 256)
103 assert 0 <= qwsel <= 3
104 return (value >> (qwsel * 64)) & ((1 << 64) - 1)
Rupert Swarbrickb4142bc2021-02-19 17:21:23 +0000105```
106
Rupert Swarbrick77cc4b32021-09-20 12:18:18 +0100107# Errors
108
109OTBN can detect various errors when it is operating.
110For details about OTBN's approach to error handling, see the [Errors section]({{< relref ".#design-details-errors" >}}) of the Technical Specification.
111The instruction descriptions below describe any software errors that executing the instruction can cause.
112These errors are listed explicitly and also appear in the pseudo-code description, where the code sets a bit in the `ERR_BITS` register with a call to `state.stop_at_end_of_cycle()`.
113
114Other errors are possible at runtime.
115Specifically, any instruction that reads from a GPR or WDR might detect a register integrity error.
116In this case, OTBN will set the `REG_INTG_VIOLATION` bit.
117Similarly, an instruction that loads from memory might detect a DMEM integrity error.
118In this case, OTBN will set the `DMEM_INTG_VIOLATION` bit.
119
120TODO:
121Specify interactions between these fatal errors and any other errors.
122In particular, how do they interact with instructions that could cause other errors as well?
123
Rupert Swarbrick83c6aef2020-11-19 13:02:58 +0000124<!-- Documentation for the instructions in the ISA. Generated from ../data/insns.yml. -->
125# Base Instruction Subset
126
127{{< otbn_isa base >}}
128
129# Big Number Instruction Subset
130
131{{< otbn_isa bignum >}}