-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
What happens when a src_fifo_inf to dest_axi_mm DMA transfer is initiated?
-
CPU writes DMA descriptor into registers
dest_addr
src_addr
length -
axi_dmac_regmap_requests waits until req_ready goes high and then submitts the request
-
request_generator creates a request_id
- it only takes some MSBs from req_length, LSBs that are the size of a burst are discarded
(.req_burst_count(req_length[DMA_LENGTH_WIDTH-1:BYTES_PER_BURST_WIDTH])) - it is started when request_generator and source are ready
(req_gen_valid = req_valid & req_req_gen_ready & req_src_ready) - checks if there is still space in the FIFO, if not it throttles
- checks if (response_id != id_next), if yes it generates an id for the next burst until no burst is left
- it only takes some MSBs from req_length, LSBs that are the size of a burst are discarded
-
src_fifo_inf also receives the request from axi_dmac_regmap_requests, but it only stores the
number of beats for the last burst (req_length[BYTES_PER_BURST_WIDTH-1:0])- it moves data from input (din) to output (fifo_data) without latency
- it signals end of burst with fifo_last
- the last burst is only as long as req_length[BYTES_PER_BURST_WIDTH-1:0]
-
output of src_fifo_inf is buffered in axi_register_slice and then fed into axi_dmac_burst_memory
- src_partial_burst is always 0 for src_fifo_inf
-
axi_dmac_burst_memory containts a FIFO that can store some bursts
- src_id is used as write index (src_id is not received from outside but generated inside
by incrementing it with every src_clk cycle) - dest_request_id (=src_id) is output and goes into the dest_axi_mm module
- src_beat_counter and dest_beat_counter are used to index the beat on the write and read side
- a new burst is generated on the output when de dest_data_request_id input goes one up
- dest_burst_valid = dest_data_request_id != dest_id_next
- dest_id is used as read index, it is incremented everytime (dest_burst_valid == 1'b1 && dest_burst_ready == 1'b1)
(dest_address_id comes from the dest_axi_mm module)
- src_id is used as write index (src_id is not received from outside but generated inside
-
dest_axi_mm received data from the burst memory and forwards it to the axi_mm interface.
Its main job is the creation of the write addresses with the adress_generator module.- the response_handler module inside creates a response id by incrementing everytime
when (bready == 1'b1 && bvalid == 1'b1)- the response_handler sets enabled output to 0 when all responses are received
if (request_id == id) enabled <= 1'b0; (enable input can override this)
- the response_handler sets enabled output to 0 when all responses are received
- The dest_axi_mm module uses the response_handler while the dest_axi_stream and dest_fifo_inf modules use the response_generator module.
Both modules are very similar, except that response_handler as an extra input input [1:0] bresp that is uses instead of the fixed response RESP_OKAY in the response_generator module.
- the response_handler module inside creates a response id by incrementing everytime
What happens when the source interface aborts a transfer? (can only happen for src_axi_stream!)
-
the src_axi interface signals an abort via the s_axi_last signal. It is detected in the data_mover module.
s_axi_last signal is only an indicator for an abort, if it is not the regular end of a burst.
In case of an abort, the data_mover generates a rewind request (rewind_req_data = {transfer_id,req_xlast_d,id_next}) -
the rewind interface goes into the request_generator (rewind_req_valid, rewind_req_data).
the request_generator then rewinds requests for bursts that are after the aborted burst and generates a completion request. -
the completion request goes into the response_manager. The response_manager waits until all "to_complete" transfers are
finished and then resumes normal operation