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 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.