| # TL-UL Protocol Checker | 
 |  | 
 | # TileLink-UL Protocol Checker | 
 |  | 
 |  | 
 | ## **Overview** | 
 |  | 
 | This document details the protocol checker | 
 | [tlul_assert.sv](https://github.com/lowRISC/opentitan/blob/master/hw/ip/tlul/rtl/tlul_assert.sv) | 
 | for TL-UL (TileLink Uncached Lightweight), based on | 
 | [TileLink specification version 1.7.1](https://sifive.cdn.prismic.io/sifive%2F57f93ecf-2c42-46f7-9818-bcdd7d39400a_tilelink-spec-1.7.1.pdf). | 
 |  | 
 | The next sections list the checks for each signal of TL-UL channels A and D. | 
 | More details: | 
 |  | 
 | *   The source fields (`a_source` and `d_source`) identify in-flight | 
 | transactions rather than physical agents. A single agent can use multiple | 
 | source IDs to track multiple outstanding transactions. See spec section 5.4 | 
 | "Source and Sink Identifiers" for more details. | 
 | *   The source fields are `TL_AIW` bits wide (defined in | 
 | [tlul_pkg.sv](https://github.com/lowRISC/opentitan/blob/master/hw/ip/tlul/rtl/tlul_pkg.sv)). | 
 | Therefore, there can be up to 2<sup>TL_AIW</sup> outstanding | 
 | requests at the same time. To keep track of these outstanding requests, the | 
 | protocol checker stores pending requests in the array `pend_req` of depth | 
 | `TL_AIW`, and removes them once their corresponding response has been received. | 
 | *   A request can be responded within the same cycle as the request message is | 
 | accepted. Therefore, in each clock cycle, the protocol checker first processes | 
 | requests and thereafter responses. | 
 | *   The package | 
 | [tlul_pkg.sv](https://github.com/lowRISC/opentitan/blob/master/hw/ip/tlul/rtl/tlul_pkg.sv) | 
 | defines the structs for channels A and D. | 
 | *   In below tables, "known" means that a signal should have a value other | 
 | than X. | 
 | * The protocol checker has a parameter `EndpointType` which can either be | 
 | `"Host"` or `"Device"`. The difference between the `"Host"` and `"Device"` | 
 | variant is that some of the properties are formulated as SV assumptions in the | 
 | former, whereas the same properties are formulated as SV assertions in the | 
 | latter (and vice versa).  The behavior of these two checkers in DV simulations | 
 | is identical, but in formal verification, this distinction is needed (otherwise | 
 | some of the assertions would have to be disabled). | 
 |  | 
 | ## **Request Channel (Channel A)** | 
 |  | 
 | Below table lists all channel A signals and their checks. | 
 | In `"Device"` mode some of these properties are assumptions (`_M` suffix) and in `"Host"` mode they are assertions (`_A` suffix). | 
 |  | 
 | <table> | 
 |   <tr> | 
 |    <td><strong>Signal</strong> | 
 |    </td> | 
 |    <td><strong>Checks </strong>(assertion name: description) | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>a_opcode | 
 |    </td> | 
 |    <td><strong>legalAOpcode_[M/A]</strong>: Only the following 3 opcodes are legal: | 
 | Get, PutFullData, PutPartialData. See spec section 6.2. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>a_param | 
 |    </td> | 
 |    <td><strong>legalAParam_[M/A]</strong>: This field is reserved, it must be 0. See | 
 | spec section 6.2. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>a_size | 
 |    </td> | 
 |    <td><strong>sizeMatchesMask_[M/A]</strong>: a_size can be calculated from a_mask | 
 | as follows: 2<sup>a_size</sup> must equal $countones(a_mask). See spec section | 
 | 4.6. | 
 | <p> | 
 | <strong>aKnown_A</strong>: Make sure it's not X when a_valid is high. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>a_source | 
 |    </td> | 
 |    <td><strong>pendingReqPerSrc_[M/A]</strong>: There should be no more | 
 | than one pending request per each source ID. See spec section 5.4. | 
 | <p> | 
 | <strong>aKnown_A</strong>: Make sure it's not X when a_valid is high. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>a_address | 
 |    </td> | 
 |    <td><strong>addrSizeAligned_[M/A]</strong>: a_address must be aligned to | 
 | a_size: a_address & ((1 << a_size) - 1) == 0. See spec section 4.6. | 
 | <p> | 
 | <strong>aKnown_A</strong>Make sure it's not X when a_valid is high. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>a_mask | 
 |    </td> | 
 |    <td><strong>contigMask_[M/A]</strong>: a_mask must be contiguous for Get | 
 | and PutFullData (but not for PutPartialData). See spec sections 4.6 and 6.2. | 
 | <p> | 
 | <strong>sizeMatchesMask_[M/A]</strong>: See a_size above. | 
 | <p> | 
 | <strong>aKnown_A</strong>Make sure it's not X when a_valid is high. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>a_data | 
 |    </td> | 
 |    <td><strong>aDataKnown_[M/A]</strong>: a_data should not be X for opcodes | 
 | PutFullData and PutPartialData (it can be X for Get). Bytes of a_data, whose | 
 | corresponding a_mask bits are 0, can be X. See spec section 4.6. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>a_user | 
 |    </td> | 
 |    <td><strong>aKnown_A</strong>Make sure it's not X when a_valid is high. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>a_valid | 
 |    </td> | 
 |    <td><strong>aKnown_A</strong>: Make sure it's not X (except during reset). | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>a_ready | 
 |    </td> | 
 |    <td><strong>aReadyKnown_A</strong>: Make sure it's not X (except during | 
 | reset). | 
 |    </td> | 
 |   </tr> | 
 | </table> | 
 |  | 
 | ## **Response Channel (Channel D)** | 
 |  | 
 | Below table lists all channel D signals and their checks. | 
 | In `"Device"` mode some of these properties are assertions (`_A` suffix) and in `"Host"` mode they are assumptions (`_M` suffix). | 
 |  | 
 | <table> | 
 |   <tr> | 
 |    <td><strong>Signal</strong> | 
 |    </td> | 
 |    <td><strong>Checks  </strong>(assertion name: description) | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>d_opcode | 
 |    </td> | 
 |    <td><strong>respOpcode_[A/M]</strong>: If the original request was Get, | 
 | then the corresponding response must be AccessAckData. Otherwise, the response | 
 | must be AccessAck. See spec section 6.2. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>d_param | 
 |    </td> | 
 |    <td><strong>legalDParam_[A/M]</strong>: This field is reserved, it must be 0. See | 
 | spec section 6.2. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>d_size | 
 |    </td> | 
 |    <td><strong>respSzEqReqSz_[A/M]</strong>: The response must have | 
 | the same size as the original request. See spec section 6.2. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>d_source | 
 |    </td> | 
 |    <td><strong>respMustHaveReq_[A/M]</strong>: For each response, there must have | 
 | been a corresponding request with the same source ID value. See spec section | 
 | 5.4. | 
 | <p> | 
 | <strong>noOutstandingReqsAtEndOfSim_A</strong>: Make sure that there are no | 
 | outstanding requests at the end of the simulation. | 
 | <p> | 
 | <strong>dKnown_A</strong>: Make sure it's not X when d_valid is high. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>d_sink | 
 |    </td> | 
 |    <td><strong>dKnown_A</strong>: Make sure it's not X when d_valid is high. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>d_data | 
 |    </td> | 
 |    <td><strong>dDataKnown_[A/M]</strong>: d_data should not be X for AccessAckData. | 
 | Bytes of d_data, whose corresponding mask bits of the original request are 0, | 
 | can be X. See spec section 4.6. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>d_error | 
 |    </td> | 
 |    <td><strong>dKnown_A</strong>Make sure it's not X when d_valid is high. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>d_user | 
 |    </td> | 
 |    <td><strong>dKnown_A</strong>Make sure it's not X when d_valid is high. | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>d_valid | 
 |    </td> | 
 |    <td><strong>dKnown_A</strong>: Make sure it's not X (except during reset). | 
 |    </td> | 
 |   </tr> | 
 |   <tr> | 
 |    <td>d_ready | 
 |    </td> | 
 |    <td><strong>dReadyKnown_A</strong>Make sure it's not X (except during | 
 | reset). | 
 |    </td> | 
 |   </tr> | 
 | </table> |