axi_dmac: patch for partial 2D transfer support
This patch addresses the following issue: In 2D mode when consecutive partial transfers occur, and the latter is very short, will interfere with the completion mechanism of the first transfer leading to uncompleted segments and unreported partial transfers.main
parent
68a5f2f86c
commit
5e1100ee77
|
@ -66,6 +66,7 @@ module axi_dmac_response_manager #(
|
|||
|
||||
// Interface to requester side
|
||||
input completion_req_valid,
|
||||
output reg completion_req_ready = 1'b1,
|
||||
input completion_req_last,
|
||||
input [1:0] completion_transfer_id
|
||||
);
|
||||
|
@ -104,6 +105,8 @@ wire [1:0] response_dest_resp;
|
|||
wire response_dest_resp_eot;
|
||||
wire [BYTES_PER_BURST_WIDTH-1:0] response_dest_data_burst_length;
|
||||
|
||||
wire completion_req;
|
||||
|
||||
reg [1:0] to_complete_count = 'h0;
|
||||
reg [1:0] transfer_id = 'h0;
|
||||
reg completion_req_last_found = 1'b0;
|
||||
|
@ -192,7 +195,11 @@ always @(*) begin
|
|||
end
|
||||
STATE_WRITE_RESPR: begin
|
||||
if (response_ready == 1'b1) begin
|
||||
nx_state = STATE_IDLE;
|
||||
if (|to_complete_count && transfer_id == completion_transfer_id) begin
|
||||
nx_state = STATE_ZERO_COMPL;
|
||||
end else begin
|
||||
nx_state = STATE_IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
STATE_ZERO_COMPL: begin
|
||||
|
@ -230,13 +237,26 @@ assign do_compl = (state == STATE_WRITE_ZRCMPL) && response_ready;
|
|||
always @(posedge req_clk) begin
|
||||
if (req_resetn == 1'b0) begin
|
||||
completion_req_last_found <= 1'b0;
|
||||
end else if (completion_req_valid) begin
|
||||
end else if (completion_req) begin
|
||||
completion_req_last_found <= completion_req_last;
|
||||
end else if (state ==STATE_ZERO_COMPL && ~(|to_complete_count)) begin
|
||||
completion_req_last_found <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// Once the last completion is received wit until all completions are done
|
||||
always @(posedge req_clk) begin
|
||||
if (req_resetn == 1'b0) begin
|
||||
completion_req_ready <= 1'b1;
|
||||
end else if (completion_req_valid && completion_req_last) begin
|
||||
completion_req_ready <= 1'b0;
|
||||
end else if (to_complete_count == 0) begin
|
||||
completion_req_ready <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
assign completion_req = completion_req_ready && completion_req_valid;
|
||||
|
||||
// Track transfers so we can tell when did the destination completed all its
|
||||
// transfers
|
||||
always @(posedge req_clk) begin
|
||||
|
@ -251,9 +271,9 @@ end
|
|||
always @(posedge req_clk) begin
|
||||
if (req_resetn == 1'b0) begin
|
||||
to_complete_count <= 'h0;
|
||||
end else if (completion_req_valid & ~do_compl) begin
|
||||
end else if (completion_req & ~do_compl) begin
|
||||
to_complete_count <= to_complete_count + 1;
|
||||
end else if (~completion_req_valid & do_compl) begin
|
||||
end else if (~completion_req & do_compl) begin
|
||||
to_complete_count <= to_complete_count - 1;
|
||||
end
|
||||
end
|
||||
|
|
|
@ -296,9 +296,11 @@ wire src_dest_valid_hs_masked;
|
|||
wire src_dest_ready_hs;
|
||||
|
||||
wire req_rewind_req_valid;
|
||||
wire req_rewind_req_ready;
|
||||
wire [ID_WIDTH+3-1:0] req_rewind_req_data;
|
||||
|
||||
wire completion_req_valid;
|
||||
wire completion_req_ready;
|
||||
wire completion_req_last;
|
||||
wire [1:0] completion_transfer_id;
|
||||
|
||||
|
@ -772,7 +774,7 @@ util_axis_fifo #(
|
|||
.m_axis_aclk(req_clk),
|
||||
.m_axis_aresetn(req_resetn),
|
||||
.m_axis_valid(req_rewind_req_valid),
|
||||
.m_axis_ready(1'b1),
|
||||
.m_axis_ready(req_rewind_req_ready),
|
||||
.m_axis_data(req_rewind_req_data),
|
||||
.m_axis_level()
|
||||
);
|
||||
|
@ -1137,12 +1139,14 @@ dmac_request_generator #(
|
|||
.response_id(response_id),
|
||||
|
||||
.rewind_req_valid(req_rewind_req_valid),
|
||||
.rewind_req_ready(req_rewind_req_ready),
|
||||
.rewind_req_data(req_rewind_req_data),
|
||||
.rewind_state(rewind_state),
|
||||
|
||||
.abort_req(abort_req),
|
||||
|
||||
.completion_req_valid(completion_req_valid),
|
||||
.completion_req_ready(completion_req_ready),
|
||||
.completion_req_last(completion_req_last),
|
||||
.completion_transfer_id(completion_transfer_id),
|
||||
|
||||
|
@ -1182,6 +1186,7 @@ axi_dmac_response_manager #(
|
|||
.response_ready(response_ready),
|
||||
|
||||
.completion_req_valid(completion_req_valid),
|
||||
.completion_req_ready(completion_req_ready),
|
||||
.completion_req_last(completion_req_last),
|
||||
.completion_transfer_id(completion_transfer_id)
|
||||
|
||||
|
|
|
@ -47,12 +47,14 @@ module dmac_request_generator #(
|
|||
input [ID_WIDTH-1:0] response_id,
|
||||
|
||||
input rewind_req_valid,
|
||||
output rewind_req_ready,
|
||||
input [ID_WIDTH+3-1:0] rewind_req_data,
|
||||
output rewind_state,
|
||||
|
||||
output abort_req,
|
||||
|
||||
output reg completion_req_valid = 1'b0,
|
||||
input completion_req_ready,
|
||||
output completion_req_last,
|
||||
output [1:0] completion_transfer_id,
|
||||
|
||||
|
@ -172,14 +174,14 @@ always @(*) begin
|
|||
nx_completion_req_valid = 0;
|
||||
case (state)
|
||||
STATE_IDLE: begin
|
||||
if (rewind_req_valid == 1'b1) begin
|
||||
if (rewind_req_valid == 1'b1 && rewind_req_ready == 1'b1) begin
|
||||
nx_state = STATE_REWIND_ID;
|
||||
end else if (req_valid == 1'b1) begin
|
||||
nx_state = STATE_GEN_ID;
|
||||
end
|
||||
end
|
||||
STATE_GEN_ID: begin
|
||||
if (rewind_req_valid == 1'b1) begin
|
||||
if (rewind_req_valid == 1'b1 && rewind_req_ready == 1'b1) begin
|
||||
nx_state = STATE_REWIND_ID;
|
||||
end else if (eot == 1'b1 && incr_en == 1'b1) begin
|
||||
nx_state = STATE_IDLE;
|
||||
|
@ -233,7 +235,7 @@ always @(posedge clk) begin
|
|||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rewind_req_valid == 1'b1) begin
|
||||
if (rewind_req_valid == 1'b1 && rewind_req_ready == 1'b1) begin
|
||||
{rew_transfer_id, rew_req_xlast, rew_id} <= rewind_req_data;
|
||||
end
|
||||
end
|
||||
|
@ -249,6 +251,7 @@ assign completion_req_last = cur_req_xlast;
|
|||
assign completion_transfer_id = rew_transfer_id;
|
||||
|
||||
assign rewind_state = (state == STATE_REWIND_ID);
|
||||
assign rewind_req_ready = completion_req_ready;
|
||||
|
||||
assign abort_req = (state == STATE_REWIND_ID) && !rew_req_xlast && !cur_req_xlast;
|
||||
|
||||
|
|
Loading…
Reference in New Issue