axi_dmac: Add support for zero latency transfer switching
Right now there is always a period of one clock cycle where we can not transfer any data when switching between two transfers. This patch modifies the data mover to allow for zero latency. This fixes problems on the FMCOMMS1 platform Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>main
parent
f07b74ecdd
commit
6da9c65a08
|
@ -58,7 +58,7 @@ module dmac_data_mover (
|
|||
output m_axi_last,
|
||||
|
||||
input req_valid,
|
||||
output reg req_ready,
|
||||
output req_ready,
|
||||
input [3:0] req_last_burst_length
|
||||
);
|
||||
|
||||
|
@ -72,20 +72,25 @@ reg [3:0] last_burst_length;
|
|||
reg [C_ID_WIDTH-1:0] id = 'h00;
|
||||
reg [C_ID_WIDTH-1:0] id_next;
|
||||
reg [3:0] beat_counter = 'h00;
|
||||
wire [3:0] beat_counter_next;
|
||||
wire last;
|
||||
wire last_load;
|
||||
reg pending_burst;
|
||||
reg active;
|
||||
|
||||
assign response_id = id;
|
||||
|
||||
assign beat_counter_next = s_axi_ready && s_axi_valid ? beat_counter + 1'b1 : beat_counter;
|
||||
assign last = beat_counter == (eot ? last_burst_length : 4'hf);
|
||||
|
||||
assign s_axi_ready = m_axi_ready & pending_burst & ~req_ready;
|
||||
assign m_axi_valid = s_axi_valid & pending_burst & ~req_ready;
|
||||
assign s_axi_ready = m_axi_ready & pending_burst & active;
|
||||
assign m_axi_valid = s_axi_valid & pending_burst & active;
|
||||
assign m_axi_data = s_axi_data;
|
||||
assign m_axi_last = last;
|
||||
|
||||
// If we want to support zero delay between transfers we have to assert
|
||||
// req_ready on the same cycle on which the last load happens.
|
||||
assign last_load = s_axi_ready && s_axi_valid && last && eot;
|
||||
assign req_ready = last_load || ~active;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
enabled <= 1'b0;
|
||||
|
@ -111,20 +116,31 @@ end
|
|||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
beat_counter <= 'h0;
|
||||
req_ready <= 1'b1;
|
||||
end else begin
|
||||
if (req_ready && req_valid) begin
|
||||
beat_counter <= 'h0;
|
||||
end else if (s_axi_ready && s_axi_valid) begin
|
||||
beat_counter <= beat_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (req_ready && req_valid) begin
|
||||
last_burst_length <= req_last_burst_length;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
active <= 1'b0;
|
||||
end else begin
|
||||
if (~enabled) begin
|
||||
req_ready <= 1'b1;
|
||||
end else if (req_ready) begin
|
||||
if (req_valid && enabled) begin
|
||||
last_burst_length <= req_last_burst_length;
|
||||
req_ready <= 1'b0;
|
||||
beat_counter <= 'h0;
|
||||
end
|
||||
end else if (s_axi_ready && s_axi_valid) begin
|
||||
if (last && eot)
|
||||
req_ready <= 1'b1;
|
||||
beat_counter <= beat_counter + 1'b1;
|
||||
active <= 1'b0;
|
||||
end else if (req_ready && req_valid) begin
|
||||
active <= 1'b1;
|
||||
end else if (last_load) begin
|
||||
active <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -141,6 +157,7 @@ end
|
|||
always @(posedge clk) begin
|
||||
if (resetn == 1'b0) begin
|
||||
id <= 'h0;
|
||||
pending_burst <= 1'b0;
|
||||
end else begin
|
||||
id <= id_next;
|
||||
pending_burst <= id_next != request_id;
|
||||
|
|
Loading…
Reference in New Issue