Skip to content

Commit

Permalink
axi_dmac: Limit number of bursts on the source side
Browse files Browse the repository at this point in the history
Currently the source side of the DMAC can issue requests for up to
2*FIFO_SIZE-1 bursts even though there is only room for FIFO_SIZE bursts in
the store and forward memory.

This can problematic for memory mapped buses. If the data is not read fast
enough from the DMAC back-pressure will propagate through the whole system
memory subsystem and can cause significant performance penalty or even a
deadlock halting the whole system.

To avoid this make sure that not more that than what fits into the
store-and-forward memory is requested by throttling the request ID based
on how much room is available in the memory.

Signed-off-by: Lars-Peter Clausen <[email protected]>
  • Loading branch information
larsclausen authored and Lars-Peter Clausen committed Jul 3, 2018
1 parent d80175d commit 7d643e2
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
4 changes: 4 additions & 0 deletions library/axi_dmac/axi_dmac_burst_memory.v
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ module axi_dmac_burst_memory #(
input [DATA_WIDTH_SRC-1:0] src_data,
input src_data_last,

output [ID_WIDTH-1:0] src_data_request_id,

input dest_clk,
input dest_reset,

Expand Down Expand Up @@ -159,6 +161,8 @@ assign src_beat = src_mem_data_valid & src_mem_data_ready;
assign src_last_beat = src_beat & src_mem_data_last;
assign src_waddr = {src_id_reduced,src_beat_counter};

assign src_data_request_id = src_dest_id;

always @(*) begin
if (src_last_beat == 1'b1) begin
src_id_next <= inc_id(src_id);
Expand Down
43 changes: 40 additions & 3 deletions library/axi_dmac/request_arb.v
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ wire [1:0] src_response_resp;
*/

wire [ID_WIDTH-1:0] src_request_id;
reg [ID_WIDTH-1:0] src_throttled_request_id;
wire [ID_WIDTH-1:0] src_data_request_id;
wire [ID_WIDTH-1:0] src_response_id;

wire src_valid;
Expand Down Expand Up @@ -542,7 +544,7 @@ dmac_src_mm_axi #(
.response_resp(src_response_resp),
*/

.request_id(src_request_id),
.request_id(src_throttled_request_id),
.response_id(src_response_id),
.address_id(src_address_id),
.data_id(src_data_id),
Expand Down Expand Up @@ -615,7 +617,7 @@ dmac_src_axi_stream #(
.req_sync_transfer_start(src_req_sync_transfer_start),
.req_xlast(src_req_xlast),

.request_id(src_request_id),
.request_id(src_throttled_request_id),
.response_id(src_response_id),

.eot(src_eot),
Expand Down Expand Up @@ -671,7 +673,7 @@ dmac_src_fifo_inf #(
.req_last_burst_length(src_req_last_burst_length),
.req_sync_transfer_start(src_req_sync_transfer_start),

.request_id(src_request_id),
.request_id(src_throttled_request_id),
.response_id(src_response_id),

.eot(src_eot),
Expand Down Expand Up @@ -705,6 +707,39 @@ sync_bits #(
.out(src_request_id)
);

`include "inc_id.h"

function compare_id;
input [ID_WIDTH-1:0] a;
input [ID_WIDTH-1:0] b;
begin
compare_id = a[ID_WIDTH-1] == b[ID_WIDTH-1];
if (ID_WIDTH >= 2) begin
if (a[ID_WIDTH-2] == b[ID_WIDTH-2]) begin
compare_id = 1'b1;
end
end
if (ID_WIDTH >= 3) begin
if (a[ID_WIDTH-3:0] != b[ID_WIDTH-3:0]) begin
compare_id = 1'b1;
end
end
end
endfunction

/*
* Make sure that we do not request more data than what fits into the
* store-and-forward burst memory.
*/
always @(posedge src_clk) begin
if (src_resetn == 1'b0) begin
src_throttled_request_id <= 'h00;
end else if (src_throttled_request_id != src_request_id &&
compare_id(src_throttled_request_id, src_data_request_id)) begin
src_throttled_request_id <= inc_id(src_throttled_request_id);
end
end

sync_bits #(
.NUM_OF_BITS(ID_WIDTH),
.ASYNC_CLK(ASYNC_CLK_DEST_REQ)
Expand Down Expand Up @@ -744,6 +779,8 @@ axi_dmac_burst_memory #(
.src_data(src_fifo_data),
.src_data_last(src_fifo_last),

.src_data_request_id(src_data_request_id),

.dest_clk(dest_clk),
.dest_reset(~dest_resetn),
.dest_data_valid(dest_fifo_valid),
Expand Down

0 comments on commit 7d643e2

Please sign in to comment.