Greg Chadwick | 18a09cb | 2020-11-06 18:15:18 +0000 | [diff] [blame] | 1 | # OTBN Tracer |
| 2 | |
| 3 | The tracer consists of a module (`otbn_tracer.sv`) and an interface |
Rupert Swarbrick | ccb53f8 | 2020-12-16 16:55:43 +0000 | [diff] [blame] | 4 | (`otbn_trace_if.sv`). The interface is responsible for directly probing the |
Greg Chadwick | 18a09cb | 2020-11-06 18:15:18 +0000 | [diff] [blame] | 5 | design and implementing any basic tracking logic that is required. The module |
| 6 | takes an instance of this interface and uses it to produce trace data. |
| 7 | |
| 8 | Trace output is provided to the simulation environment by calling the |
| 9 | `accept_otbn_trace_string` function which is imported via DPI (the simulator |
| 10 | environment provides its implementation). Each call to |
| 11 | `accept_otbn_trace_string` provides a trace record and a cycle count. There is |
| 12 | at most one call per cycle. Further details are below. |
| 13 | |
Rupert Swarbrick | ccb53f8 | 2020-12-16 16:55:43 +0000 | [diff] [blame] | 14 | A typical setup would bind an instantiation of `otbn_trace_if` and |
| 15 | `otbn_tracer` into `otbn_core` passing the `otbn_trace_if` instance into the |
Greg Chadwick | 18a09cb | 2020-11-06 18:15:18 +0000 | [diff] [blame] | 16 | `otbn_tracer` instance. However this is no need for `otbn_tracer` to be bound |
Rupert Swarbrick | ccb53f8 | 2020-12-16 16:55:43 +0000 | [diff] [blame] | 17 | into `otbn_core` provided it is given a `otbn_trace_if` instance. |
Greg Chadwick | 18a09cb | 2020-11-06 18:15:18 +0000 | [diff] [blame] | 18 | |
| 19 | ## Trace Format |
| 20 | |
Rupert Swarbrick | 7245a18 | 2022-01-25 13:44:27 +0000 | [diff] [blame] | 21 | Trace output is generated as a series of records. Every record has zero or more |
| 22 | *header lines*, followed by zero or more *body lines*. There is no fixed |
| 23 | ordering within the header lines or the body lines. |
Greg Chadwick | 18a09cb | 2020-11-06 18:15:18 +0000 | [diff] [blame] | 24 | |
Rupert Swarbrick | 7245a18 | 2022-01-25 13:44:27 +0000 | [diff] [blame] | 25 | The type of any line can be identified by its first character. The possible |
| 26 | types for header lines are as follows: |
Greg Chadwick | 18a09cb | 2020-11-06 18:15:18 +0000 | [diff] [blame] | 27 | |
Rupert Swarbrick | 7245a18 | 2022-01-25 13:44:27 +0000 | [diff] [blame] | 28 | - `S`: **Instruction stall**. An instruction is stalled. |
| 29 | - `E`: **Instruction execute**. An instruction completed its execution. |
| 30 | - `U`: **Wipe in progress**. OTBN is in the middle of an internal wipe. |
| 31 | - `V`: **Wipe complete**. An internal wipe has completed. |
| 32 | |
| 33 | The possible types for body lines are: |
| 34 | |
| 35 | - `<`: **Register read**: A register has been read. |
| 36 | - `>`: **Register write**: A register has been written. |
| 37 | - `R`: **Memory load**: A value has been loaded from memory. |
| 38 | - `W`: **Memory store**: A value has been stored to memory. |
| 39 | |
| 40 | See the [sections below](#line-formats) for details of what information is in |
| 41 | the different lines. |
| 42 | |
| 43 | A well-formed record has exactly one header line, but it's possible for the |
| 44 | tracer to generate other records if something goes wrong in the design. It is |
| 45 | not the tracer's responsibility to detect bugs; the simulation environment |
| 46 | should flag these as errors in a suitable way. |
| 47 | |
| 48 | An instruction execution will be represented by zero or more `S` records, |
| 49 | followed by one `E` record that represents the retirement of the instruction. |
| 50 | The secure wipe phase at the end of OTBN's operation will be represented by |
| 51 | zero or more `U` records, followed by a final `V` record. |
| 52 | |
| 53 | Whilst the tracer does not aim to detect bugs, there may be instances where the |
| 54 | signals it traces do something unexpected that requires special behaviour. |
| 55 | Where this happens, the string `"ERR"` will be placed somewhere in the line |
| 56 | that contains information about the unexpected signals. See information on |
| 57 | Memory Write (`W`) lines below for an example. `ERR` will not be present in |
| 58 | trace output for any other reason. |
Greg Chadwick | 18a09cb | 2020-11-06 18:15:18 +0000 | [diff] [blame] | 59 | |
| 60 | ### Record examples |
| 61 | (The first line of each example illustrates the instruction being traced to aid the example and |
| 62 | is not part of the record) |
| 63 | |
| 64 | Executing `BN.SID x26++, 0(x25)` at PC 0x00000158: |
| 65 | ``` |
| 66 | E PC: 0x00000158, insn: 0x01acd08b |
| 67 | < w20: 0x78fccc06_2228e9d6_89c9b54f_887cf14e_c79af825_69be57d4_fecd21a1_b9dd0141 |
| 68 | < x25: 0x00000020 |
| 69 | < x26: 0x00000014 |
| 70 | > x26: 0x00000015 |
| 71 | W [0x00000020]: 0x78fccc06_2228e9d6_89c9b54f_887cf14e_c79af825_69be57d4_fecd21a1_b9dd0141 |
| 72 | ``` |
| 73 | |
| 74 | Executing `BN.ADD w3, w1, w2` at PC 0x000000e8: |
| 75 | ``` |
| 76 | E PC: 0x000000e8, insn: 0x002081ab |
| 77 | < w01: 0x78fccc06_2228e9d6_89c9b54f_887cf14e_c79af825_69be586e_9866bb3b_53769ada |
| 78 | < w02: 0x99999999_99999999_99999999_99999999_99999999_99999999_99999999_99999999 |
| 79 | > w03: 0x1296659f_bbc28370_23634ee9_22168ae8_613491bf_0357f208_320054d4_ed103473 |
| 80 | > FLAGS0: {C: 1, M: 0, L: 1, Z: 0} |
| 81 | ``` |
| 82 | |
| 83 | ## Line formats |
| 84 | |
| 85 | ### Instruction Execute (`E`) and Stall (`S`) lines |
| 86 | |
Rupert Swarbrick | 7245a18 | 2022-01-25 13:44:27 +0000 | [diff] [blame] | 87 | These indicate that an instruction is executing or stalling. An 'E' line |
| 88 | indicates the instruction completed in the trace record's cycle. An instruction |
| 89 | that is stalled will first produce a record containing an 'S' line and will |
| 90 | produce a matching 'E' line in a future record on the cycle it unstalls and |
| 91 | finishes. The line provides the PC and raw instruction bits. |
Greg Chadwick | 18a09cb | 2020-11-06 18:15:18 +0000 | [diff] [blame] | 92 | |
| 93 | Instruction at 0x0000014c is 0x01800d13 and stalling (a future record will |
| 94 | contain a matching 'E' line): |
| 95 | ``` |
| 96 | S PC: 0x0000014c, insn: 0x01800d13 |
| 97 | ``` |
| 98 | |
| 99 | Instruction at 0x00000150 is 0x01acc10b is executing and will complete: |
| 100 | ``` |
| 101 | E PC: 0x00000150, insn: 0x01acc10b |
| 102 | ``` |
| 103 | |
Rupert Swarbrick | 7245a18 | 2022-01-25 13:44:27 +0000 | [diff] [blame] | 104 | ### Secure wipe (`U` and `V`) lines |
| 105 | |
| 106 | These indicate that a secure wipe operation is in progress. There is no other |
| 107 | information, so the line consists of a bare `U` or `V` character. |
| 108 | |
Greg Chadwick | 18a09cb | 2020-11-06 18:15:18 +0000 | [diff] [blame] | 109 | ### Register Read (`<`) and Write (`>`) lines |
| 110 | |
Rupert Swarbrick | 7245a18 | 2022-01-25 13:44:27 +0000 | [diff] [blame] | 111 | These show data that has been read or written to either register files or |
| 112 | special purpose registers (such as ACC or the bignum side flags). The line |
| 113 | provides the register name and the data read/written |
Greg Chadwick | 18a09cb | 2020-11-06 18:15:18 +0000 | [diff] [blame] | 114 | |
| 115 | Register x26 was read and contained value 0x00000018: |
| 116 | ``` |
| 117 | < x26: 0x00000018 |
| 118 | ``` |
| 119 | |
| 120 | Register w24 had value |
| 121 | `0xcccccccc_bbbbbbbb_aaaaaaaa_facefeed_deadbeef_cafed00d_d0beb533_1234abcd` |
| 122 | written to it: |
| 123 | ``` |
| 124 | > w24: 0xcccccccc_bbbbbbbb_aaaaaaaa_facefeed_deadbeef_cafed00d_d0beb533_1234abcd |
| 125 | ``` |
| 126 | |
| 127 | Accumulator had value |
| 128 | `0x00000000_00000000_00311bcb_5e157313_a2fd5453_c7eb58ce_1a1d070d_673963ce` |
| 129 | written to it: |
| 130 | ``` |
| 131 | > ACC: 0x00000000_00000000_00311bcb_5e157313_a2fd5453_c7eb58ce_1a1d070d_673963ce |
| 132 | ``` |
| 133 | |
| 134 | Flag group 0 had value `{C: 1, M: 1, L: 1, Z: 0}` written to it: |
| 135 | ``` |
| 136 | > FLAGS0: {C: 1, M: 1, L: 1, Z: 0} |
| 137 | ``` |
| 138 | |
| 139 | ### Memory Read (`R`) and Write (`W`) lines |
| 140 | |
Rupert Swarbrick | 7245a18 | 2022-01-25 13:44:27 +0000 | [diff] [blame] | 141 | These indicate activity on the Dmem bus. The line provides the address and data |
Greg Chadwick | 18a09cb | 2020-11-06 18:15:18 +0000 | [diff] [blame] | 142 | written/read. For a read the data is always WLEN bits and the address is WLEN |
| 143 | aligned (for an execution of LW only a 32-bit chunk of that data is required). |
| 144 | For a write the write mask is examined. Where the mask indicates a bignum side |
| 145 | write (BN.SID) full WLEN bit data is provided and the address is WLEN aligned. |
| 146 | Where the mask indicates a base side write (SW) only 32-bit data is provided and |
| 147 | the address is 32-bit aligned (giving the full address of the written chunk). |
| 148 | |
| 149 | Address `0x00000040` was read and contained value |
| 150 | `0xcccccccc_bbbbbbbb_aaaaaaaa_facefeed_deadbeef_cafed00d_baadf00d_1234abcd`: |
| 151 | ``` |
| 152 | R [0x00000040]: 0xcccccccc_bbbbbbbb_aaaaaaaa_facefeed_deadbeef_cafed00d_baadf00d_1234abcd |
| 153 | ``` |
| 154 | |
| 155 | Address `0x00000004` had value `0xd0beb533` written to it: |
| 156 | ``` |
| 157 | W [0x00000004]: 0xd0beb533 |
| 158 | ``` |
| 159 | |
| 160 | In the event of an OTBN bug that produces bad memory masks on writes (where the |
| 161 | write is neither to a full 256 bits nor a aligned 32-bit chunk), an error line |
| 162 | is produced giving the full mask and data |
| 163 | ``` |
| 164 | W [0x00000080]: Mask ERR Mask: 0xfffff800_0000ffff_ffffffff_00000000_00000000_00000000_00000000_00000000 Data: 0xcccccccc_bbbbbbbb_aaaaaaaa_facefeed_deadbeef_cafed00d_baadf00d_1234abcd |
| 165 | ``` |
Rupert Swarbrick | 660baa9 | 2020-12-15 17:00:55 +0000 | [diff] [blame] | 166 | |
| 167 | ## Using with dvsim |
| 168 | |
| 169 | To use this code, depend on the core file. If you're using dvsim, |
| 170 | you'll also need to include `otbn_tracer_sim_opts.hjson` in your |
| 171 | simulator configuration and add `"{tool}_otbn_tracer_build_opts"` to |
| 172 | the `en_build_modes` variable. |