|  | # Load Store Unit | 
|  |  | 
|  |  | 
|  |  | 
|  | The Load Store Unit handles memory operations issued by the core. Functionally, | 
|  | it's purpose is to translate memory instructions into transactions on the | 
|  | appropriate subsystem. | 
|  |  | 
|  | ## Slots | 
|  |  | 
|  | The Kelvin LSU uses a concept called _slots_ to handle memory transactions. A | 
|  | slot is a data structure which manages the state of a single dispatched LSU | 
|  | operation and determines what memory transaction should be performed. At its | 
|  | core, there exists a table in each slot which tracks which part of the memory | 
|  | operation has been completed. | 
|  |  | 
|  | For example, below is the slot table for a word-store into address 0xDEADBEEF: | 
|  |  | 
|  | | Index | Active |   Address  | Data | | 
|  | | ----- | ------ | ---------- | ---- | | 
|  | |   0   |    1   | 0xDEADBEEF | 0x01 | | 
|  | |   1   |    1   | 0xDEADBEF0 | 0x23 | | 
|  | |   2   |    1   | 0xDEADBEF1 | 0x45 | | 
|  | |   3   |    1   | 0xDEADBEF2 | 0x67 | | 
|  | |   4   |    0   | 0xDEADBEF3 | 0x00 | | 
|  | ... | 
|  | |   n   |    0   | 0xDEADBEF3 | 0x00 | | 
|  |  | 
|  | Memory transactions over TCM or AXI busses will read/write data in the slot | 
|  | table and flip the active bits to 0 as they are made. | 
|  |  | 
|  | The typical lifetime of a slot is as follows: | 
|  |  | 
|  | 1) **Idle**: An idle slot will dequeue a LsuOperation from the command queue. | 
|  | Scalar operations will move directly into **Transfer Memory** while vector | 
|  | operations will go to the **Vector Update** state. | 
|  | 2) **Vector Update**: For vector operations masks, addresses (for indexed ops) | 
|  | and data (for store ops) need to be received from the RvvCore. This stage is | 
|  | bypassed for scalar operations. | 
|  | 3) **Transfer Memory**: While there are still active entries in the slot table, | 
|  | the active entry with the lowest "index" will be selected for a memory | 
|  | transaction. A scatter/gather unit will then select all other active entries | 
|  | (although not necessarily contiguous) that will be bundled with the transaction. | 
|  | The appropriate memory bus (ibus, dbus, ebus) will then be selected and a memory | 
|  | transaction will be conducted. When there are no active entries, the slot moves | 
|  | into the next state (**Writeback**). | 
|  | 4) **Writeback**: Once all memory transactions are completed, the result must | 
|  | be written back to register files. Additionally, vector stores are | 
|  | "acknowledged" back to the RvvCore. Scalar and floating point scores bypass this | 
|  | stage. Once writeback is completed, the slot moves back into the | 
|  | **Vector Update** state for LMUL > 1, or the **Idle** state. | 
|  |  | 
|  | Kelvin currently uses one "slot" in the LSU. In the future, multiple slots maybe | 
|  | added to allow multiple operations to partake in the same transaction. | 
|  |  | 
|  | ## Interfaces | 
|  |  | 
|  | ### LSU Command Interface | 
|  |  | 
|  | The LSU has a command interface coming from the dispatch unit and register file. | 
|  |  | 
|  | | Signal Name   | Type          | Description                                                   | | 
|  | | ------------- | ------------- | ------------------------------------------------------------- | | 
|  | | req.valid     | Bool          | If the LSU command is valid.                                  | | 
|  | | req.op        |               | The LSU operation to execute.                                 | | 
|  | | req.addr      | UInt(5)       | The RegFile address to write the result to for loads.         | | 
|  | | req.pc        | UInt(32)      | The PC of the LSU instruction. Use for fault reporting.       | | 
|  | | req.elemWidth | UInt(32)      | Used in the RVV only. The EEW for strided loads.              | | 
|  | | req.ready     | Bool (output) | If the command is accepted. Used in a ready-valid hand-shake. | | 
|  |  | 
|  | ### Bus Interfaces | 
|  |  | 
|  | | Signal Name | Type              | Description                                                       | | 
|  | | ----------- | ----------------- | ----------------------------------------------------------------- | | 
|  | | ibus.valid  | Bool              | If the ibus transaction is valid.                                 | | 
|  | | ibus.addr   | UInt(32)          | The address of the ibus transaction.                              | | 
|  | | ibus.rdata  | UInt(128) (input) | The data read from the ibus. Arrives one cycle after hand-shake.  | | 
|  | | ibus.ready  | Bool (input)      | If the transaction is accepted. Used in a ready-valid hand-shake. | | 
|  |  | 
|  | | Signal Name | Type              | Description                                                       | | 
|  | | ----------- | ----------------- | ----------------------------------------------------------------- | | 
|  | | dbus.valid  | Bool              | If the dbus transaction is valid.                                 | | 
|  | | dbus.addr   | UInt(32)          | The address of the dbus transaction.                              | | 
|  | | dbus.size   | UInt(5)           | The size of this transaction in bytes.                            | | 
|  | | dbus.pc     | UInt(32)          | The PC of the LSU instruction. Use for fault reporting.           | | 
|  | | dbus.rdata  | UInt(128) (input) | The data read from the dbus. Arrives one cycle after hand-shake.  | | 
|  | | dbus.wdata  | UInt(128)         | The data to write from the dbus.                                  | | 
|  | | dbus.wmask  | UInt(16)          | A byte write mask for this transaction.                           | | 
|  | | dbus.ready  | Bool (input)      | If the transaction is accepted. Used in a ready-valid hand-shake. | | 
|  |  | 
|  | | Signal Name      | Type              | Description                                                       | | 
|  | | ---------------- | ----------------- | ----------------------------------------------------------------- | | 
|  | | ebus.valid       | Bool              | If the ebus transaction is valid.                                 | | 
|  | | ebus.addr        | UInt(32)          | The address of the ebus transaction.                              | | 
|  | | ebus.size        | UInt(5)           | The size of this transaction in bytes.                            | | 
|  | | ebus.pc          | UInt(32)          | The PC of the LSU instruction. Use for fault reporting.           | | 
|  | | ebus.rdata       | UInt(128) (input) | The data read from the ebus. Arrives one cycle after hand-shake.  | | 
|  | | ebus.wdata       | UInt(128)         | The data to write from the ebus.                                  | | 
|  | | ebus.wmask       | UInt(16)          | A byte write mask for this transaction.                           | | 
|  | | ebus.ready       | Bool (input)      | If the transaction is accepted. Used in a ready-valid hand-shake. | | 
|  | | ebus.fault.valid | Bool (input)      | Raised if a fault occurs on the external bus.                     | | 
|  | | ebus.fault.write | Bool (input)      | If the fault occured on a write operation.                        | | 
|  | | ebus.fault.addr  | Bool (input)      | The address of the memory transaction when the fault occurred.    | | 
|  | | ebus.fault.epc   | Bool (input)      | The PC of the instruction that triggered the fault.               | | 
|  | | ebus.internal    | Bool              | Not used.                                                         | | 
|  |  | 
|  | ### Writeback Interfaces | 
|  |  | 
|  | | Signal Name | Type     | Description                                              | | 
|  | | ----------- | -------- | -------------------------------------------------------- | | 
|  | | rd.valid    | Bool     | If the writeback to the scalar regfile is valid.         | | 
|  | | rd.addr     | UInt(5)  | The address of the scalar register file to writeback to. | | 
|  | | rd.data     | UInt(32) | The data to write to the scalar register file.           | | 
|  |  | 
|  | | Signal Name     | Type     | Description                                                      | | 
|  | | --------------- | -------- | ---------------------------------------------------------------- | | 
|  | | rd_flt.valid    | Bool     | If the writeback to the floating point regfile is valid.         | | 
|  | | rd_flt.addr     | UInt(5)  | The address of the floating point register file to writeback to. | | 
|  | | rd_flt.data     | UInt(32) | The data to write to the floating point register file.           | | 
|  |  | 
|  | ### RVV Interfaces | 
|  |  | 
|  | For the RVVCore, the LSU contains the following interfaces: | 
|  |  | 
|  | | Signal Name            | Type              | Description                                                       | | 
|  | | ---------------------- | ----------------- | ----------------------------------------------------------------- | | 
|  | | rvv2lsu.valid          | Bool              | If the rvv2lsu transaction is valid.                              | | 
|  | | rvv2lsu.idx.valid      | Bool              | If there is valid index data from the vector register file.       | | 
|  | | rvv2lsu.idx.addr       | UInt(5)           | The address of the indices from the vector register file.         | | 
|  | | rvv2lsu.idx.data       | UInt(128)         | The indices from the vector register file index.                  | | 
|  | | rvv2lsu.vregfile.valid | UInt(128)         | If there is valid data from the vector register file.             | | 
|  | | rvv2lsu.vregfile.addr  | UInt(5)           | The address of the data from the vector register file.            | | 
|  | | rvv2lsu.vregfile.data  | UInt(128)         | The vector data to write back for this operation.                 | | 
|  | | rvv2lsu.mask           | UInt(16)          | A byte activity mask for this transaction.                        | | 
|  | | rvv2lsu.ready          | Bool (input)      | If the transaction is accepted. Used in a ready-valid hand-shake. | | 
|  |  | 
|  | | Signal Name    | Type              | Description                                                       | | 
|  | | -------------- | ----------------- | ----------------------------------------------------------------- | | 
|  | | lsu2rvv.valid  | Bool              | If the lsu2rvv transaction is valid.                              | | 
|  | | lsu2rvv.addr   | UInt(5)           | The destination vector register file index.                       | | 
|  | | lsu2rvv.data   | UInt(128)         | The vector data to write back for load operations.                | | 
|  | | lsu2rvv.last   | Bool              | If this transaction is a store or not.                            | | 
|  | | lsu2rvv.ready  | Bool (input)      | If the transaction is accepted. Used in a ready-valid hand-shake. | | 
|  |  |