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