blob: b31932861f30c9eb7beeb9b98229170b64e47ab5 [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. Each record consists of a
number of lines that begin with a single character that identifies the category
of the line and relate to activity occurring in the cycle the record is
associated with. The format following that within the line depends upon the
category (see the XPrefix parameters below for the possible categories).
A record may start with an 'E' or 'S' (instruction execute or stall) line, then
has other lines. Ordering for the other lines is not guaranteed. A record will
never be empty. It is expected that all records begin with an 'E' or 'S' line. A
record without an 'E' or 'S' line indicates a bug in OTBN. It is not the
tracer's responsibility to detect bugs; the simulation environment should flag
these as errors in a suitable way.
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 '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
Indicates 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 producing a
matching 'E' line in a future record 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
```
### Register Read (`<`) and Write (`>`) lines
Indicates 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
Indicates 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.