Load-Store Unit

rtl/ibex_load_store_unit.sv

The Load-Store Unit (LSU) of the core takes care of accessing the data memory. Loads and stores of words (32 bit), half words (16 bit) and bytes (8 bit) are supported.

Any load or store will stall the ID/EX stage for at least a cycle to await the response (whether that is awaiting load data or a response indicating whether an error has been seen for a store).

Data-Side Memory Interface

Signals that are used by the LSU:

Signal

Direction

Description

data_req_o

output

Request valid, must stay high until data_gnt_i is high for one cycle

data_addr_o[31:0]

output

Address, word aligned

data_we_o

output

Write Enable, high for writes, low for reads. Sent together with data_req_o

data_be_o[3:0]

output

Byte Enable. Is set for the bytes to write/read, sent together with data_req_o

data_wdata_o[31:0]

output

Data to be written to memory, sent together with data_req_o

data_gnt_i

input

The other side accepted the request. Outputs may change in the next cycle.

data_rvalid_i

input

data_err_i and data_rdata_i hold valid data when data_rvalid_i is high. This signal will be high for exactly one cycle per request.

data_err_i

input

Error response from the bus or the memory: request cannot be handled. High in case of an error.

data_rdata_i[31:0]

input

Data read from memory

Misaligned Accesses

The LSU is able to handle misaligned memory accesses, meaning accesses that are not aligned on natural word boundaries. However, it does so by performing two separate word-aligned accesses. This means that at least two cycles are needed for misaligned loads and stores.

If an error response is received for the first transaction, the second transaction will still be issued. The second transaction will then follow the normal bus protocol, but its response/data will be ignored. If a new load/store request is received while waiting for an abandoned second part to complete, it will not be serviced until the state machine returns to IDLE.

Protocol

The protocol that is used by the LSU to communicate with a memory works as follows:

  1. The LSU provides a valid address in data_addr_o and sets data_req_o high. In the case of a store, the LSU also sets data_we_o high and configures data_be_o and data_wdata_o. The memory then answers with a data_gnt_i set high as soon as it is ready to serve the request. This may happen in the same cycle as the request was sent or any number of cycles later.

  2. After receiving a grant, the address may be changed in the next cycle by the LSU. In addition, the data_wdata_o, data_we_o and data_be_o signals may be changed as it is assumed that the memory has already processed and stored that information.

  3. The memory answers with a data_rvalid_i set high for exactly one cycle to signal the response from the bus or the memory using data_err_i and data_rdata_i (during the very same cycle). This may happen one or more cycles after the grant has been received. If data_err_i is low, the request could successfully be handled at the destination and in the case of a load, data_rdata_i contains valid data. If data_err_i is high, an error occurred in the memory system and the core will raise an exception.

  4. When multiple granted requests are outstanding, it is assumed that the memory requests will be kept in-order and one data_rvalid_i will be signalled for each of them, in the order they were issued.

Figure 7, Figure 8 and Figure 9 show example-timing diagrams of the protocol.

_images/wavedrom-c1af9ee5-c884-4422-a140-751d86ff0e63.svg

Figure 7 Basic Memory Transaction

_images/wavedrom-c1ddf27b-b282-45fd-86dd-b5585ac5507a.svg

Figure 8 Back-to-back Memory Transaction

_images/wavedrom-2c5723dc-1466-4e0c-8304-06fc6cb24673.svg

Figure 9 Slow Response Memory Transaction