blob: 730cf5db0870b19635c77e63ee8617d8fb3922ca [file] [log] [blame] [view]
# OTBN Tracer
The tracer consists of a module (`otbn_tracer.sv`) and an interface
(`otbn_trace_if.sv`). The interface is responsible for directly probing the
design and implementing any basic tracking logic that is required. The module
takes an instance of this interface and uses it to produce trace data.
Trace output is provided to the simulation environment by calling the
`accept_otbn_trace_string` function which is imported via DPI (the simulator
environment provides its implementation). Each call to
`accept_otbn_trace_string` provides a trace record and a cycle count. There is
at most one call per cycle. Further details are below.
A typical setup would bind an instantiation of `otbn_trace_if` and
`otbn_tracer` into `otbn_core` passing the `otbn_trace_if` instance into the
`otbn_tracer` instance. However this is no need for `otbn_tracer` to be bound
into `otbn_core` provided it is given a `otbn_trace_if` instance.
## Trace Format
Trace output is generated as a series of records. Every record has zero or more
*header lines*, followed by zero or more *body lines*. There is no fixed
ordering within the header lines or the body lines.
The type of any line can be identified by its first character. The possible
types for header lines are as follows:
- `S`: **Instruction stall**. An instruction is stalled.
- `E`: **Instruction execute**. An instruction completed its execution.
- `U`: **Wipe in progress**. OTBN is in the middle of an internal wipe.
- `V`: **Wipe complete**. An internal wipe has completed.
The possible types for body lines are:
- `<`: **Register read**: A register has been read.
- `>`: **Register write**: A register has been written.
- `R`: **Memory load**: A value has been loaded from memory.
- `W`: **Memory store**: A value has been stored to memory.
See the [sections below](#line-formats) for details of what information is in
the different lines.
A well-formed record has exactly one header line, but it's possible for the
tracer to generate other records if something goes wrong in the design. It is
not the tracer's responsibility to detect bugs; the simulation environment
should flag these as errors in a suitable way.
An instruction execution will be represented by zero or more `S` records,
followed by one `E` record that represents the retirement of the instruction.
The secure wipe phase at the end of OTBN's operation will be represented by
zero or more `U` records, followed by a final `V` record.
Whilst the tracer does not aim to detect bugs, there may be instances where the
signals it traces do something unexpected that requires special behaviour.
Where this happens, the string `"ERR"` will be placed somewhere in the line
that contains information about the unexpected signals. See information on
Memory Write (`W`) lines below for an example. `ERR` will not be present in
trace output for any other reason.
### Record examples
(The first line of each example illustrates the instruction being traced to aid the example and
is not part of the record)
Executing `BN.SID x26++, 0(x25)` at PC 0x00000158:
```
E PC: 0x00000158, insn: 0x01acd08b
< w20: 0x78fccc06_2228e9d6_89c9b54f_887cf14e_c79af825_69be57d4_fecd21a1_b9dd0141
< x25: 0x00000020
< x26: 0x00000014
> x26: 0x00000015
W [0x00000020]: 0x78fccc06_2228e9d6_89c9b54f_887cf14e_c79af825_69be57d4_fecd21a1_b9dd0141
```
Executing `BN.ADD w3, w1, w2` at PC 0x000000e8:
```
E PC: 0x000000e8, insn: 0x002081ab
< w01: 0x78fccc06_2228e9d6_89c9b54f_887cf14e_c79af825_69be586e_9866bb3b_53769ada
< w02: 0x99999999_99999999_99999999_99999999_99999999_99999999_99999999_99999999
> w03: 0x1296659f_bbc28370_23634ee9_22168ae8_613491bf_0357f208_320054d4_ed103473
> FLAGS0: {C: 1, M: 0, L: 1, Z: 0}
```
## Line formats
### Instruction Execute (`E`) and Stall (`S`) lines
These indicate that an instruction is executing or stalling. An 'E' line
indicates the instruction completed in the trace record's cycle. An instruction
that is stalled will first produce a record containing an 'S' line and will
produce a matching 'E' line in a future record on the cycle it unstalls and
finishes. The line provides the PC and raw instruction bits.
Instruction at 0x0000014c is 0x01800d13 and stalling (a future record will
contain a matching 'E' line):
```
S PC: 0x0000014c, insn: 0x01800d13
```
Instruction at 0x00000150 is 0x01acc10b is executing and will complete:
```
E PC: 0x00000150, insn: 0x01acc10b
```
### Secure wipe (`U` and `V`) lines
These indicate that a secure wipe operation is in progress. There is no other
information, so the line consists of a bare `U` or `V` character.
### Register Read (`<`) and Write (`>`) lines
These show data that has been read or written to either register files or
special purpose registers (such as ACC or the bignum side flags). The line
provides the register name and the data read/written
Register x26 was read and contained value 0x00000018:
```
< x26: 0x00000018
```
Register w24 had value
`0xcccccccc_bbbbbbbb_aaaaaaaa_facefeed_deadbeef_cafed00d_d0beb533_1234abcd`
written to it:
```
> w24: 0xcccccccc_bbbbbbbb_aaaaaaaa_facefeed_deadbeef_cafed00d_d0beb533_1234abcd
```
Accumulator had value
`0x00000000_00000000_00311bcb_5e157313_a2fd5453_c7eb58ce_1a1d070d_673963ce`
written to it:
```
> ACC: 0x00000000_00000000_00311bcb_5e157313_a2fd5453_c7eb58ce_1a1d070d_673963ce
```
Flag group 0 had value `{C: 1, M: 1, L: 1, Z: 0}` written to it:
```
> FLAGS0: {C: 1, M: 1, L: 1, Z: 0}
```
### Memory Read (`R`) and Write (`W`) lines
These indicate activity on the Dmem bus. The line provides the address and data
written/read. For a read the data is always WLEN bits and the address is WLEN
aligned (for an execution of LW only a 32-bit chunk of that data is required).
For a write the write mask is examined. Where the mask indicates a bignum side
write (BN.SID) full WLEN bit data is provided and the address is WLEN aligned.
Where the mask indicates a base side write (SW) only 32-bit data is provided and
the address is 32-bit aligned (giving the full address of the written chunk).
Address `0x00000040` was read and contained value
`0xcccccccc_bbbbbbbb_aaaaaaaa_facefeed_deadbeef_cafed00d_baadf00d_1234abcd`:
```
R [0x00000040]: 0xcccccccc_bbbbbbbb_aaaaaaaa_facefeed_deadbeef_cafed00d_baadf00d_1234abcd
```
Address `0x00000004` had value `0xd0beb533` written to it:
```
W [0x00000004]: 0xd0beb533
```
In the event of an OTBN bug that produces bad memory masks on writes (where the
write is neither to a full 256 bits nor a aligned 32-bit chunk), an error line
is produced giving the full mask and data
```
W [0x00000080]: Mask ERR Mask: 0xfffff800_0000ffff_ffffffff_00000000_00000000_00000000_00000000_00000000 Data: 0xcccccccc_bbbbbbbb_aaaaaaaa_facefeed_deadbeef_cafed00d_baadf00d_1234abcd
```
## Using with dvsim
To use this code, depend on the core file. If you're using dvsim,
you'll also need to include `otbn_tracer_sim_opts.hjson` in your
simulator configuration and add `"{tool}_otbn_tracer_build_opts"` to
the `en_build_modes` variable.