axi_dmac: Move sync transfer start logic to the data mover

The only two users of the data mover module both implement the same
sync-transfer-start logic. Move this into the data mover module to avoid
the duplicated code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
main
Lars-Peter Clausen 2018-05-28 12:32:18 +02:00 committed by Lars-Peter Clausen
parent 62969bd7ab
commit 92984dc802
3 changed files with 40 additions and 33 deletions

View File

@ -51,6 +51,7 @@ module dmac_data_mover #(
output s_axi_ready,
input s_axi_valid,
input [DATA_WIDTH-1:0] s_axi_data,
input s_axi_sync,
output m_axi_valid,
output [DATA_WIDTH-1:0] m_axi_data,
@ -58,7 +59,8 @@ module dmac_data_mover #(
input req_valid,
output req_ready,
input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length
input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length,
input req_sync_transfer_start
);
localparam BEAT_COUNTER_MAX = {BEATS_PER_BURST_WIDTH{1'b1}};
@ -75,6 +77,12 @@ reg active = 1'b0;
reg last_eot = 1'b0;
reg last_non_eot = 1'b0;
reg needs_sync = 1'b0;
wire has_sync = ~needs_sync | s_axi_sync;
wire s_axi_sync_valid = has_sync & s_axi_valid;
wire s_axi_beat = s_axi_sync_valid & s_axi_ready;
wire last_load;
wire last;
@ -85,13 +93,26 @@ assign response_id = id;
assign last = eot ? last_eot : last_non_eot;
assign s_axi_ready = pending_burst & active;
assign m_axi_valid = s_axi_valid & pending_burst & active;
assign m_axi_valid = s_axi_sync_valid & pending_burst & active;
assign m_axi_data = s_axi_data;
assign m_axi_last = last;
assign m_axi_eot = last & eot;
/*
* If req_sync_transfer_start is set all incoming beats will be skipped until
* one has s_axi_sync set. This will be the first beat that is passsed through.
*/
always @(posedge clk) begin
if (s_axi_beat == 1'b1)
needs_sync <= 1'b0;
end else if (req_ready == 1'b1) begin
needs_sync <= req_sync_transfer_start;
end
end
// 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 && eot;
assign last_load = s_axi_beat && last_eot && eot;
assign req_ready = last_load || ~active;
always @(posedge clk) begin
@ -99,7 +120,7 @@ always @(posedge clk) begin
last_eot <= req_last_burst_length == 'h0;
last_non_eot <= 1'b0;
beat_counter <= 'h1;
end else if (s_axi_ready && s_axi_valid) begin
end else if (s_axi_beat == 1'b1) begin
last_eot <= beat_counter == last_burst_length;
last_non_eot <= beat_counter == BEAT_COUNTER_MAX;
beat_counter <= beat_counter + 1'b1;
@ -123,7 +144,7 @@ end
always @(*)
begin
if (s_axi_ready == 1'b1 && s_axi_valid == 1'b1 && last == 1'b1)
if (s_axi_beat == 1'b1 && last == 1'b1)
id_next <= inc_id(id);
else
id_next <= id;

View File

@ -68,31 +68,20 @@ module dmac_src_axi_stream #(
input req_xlast
);
reg needs_sync = 1'b0;
reg transfer_abort = 1'b0;
reg req_xlast_d = 1'b0;
wire [S_AXIS_DATA_WIDTH-1:0] data;
wire sync = s_axis_user[0];
wire has_sync = ~needs_sync | sync;
wire data_valid;
wire data_ready;
wire fifo_eot;
assign enabled = enable;
assign data = transfer_abort == 1'b1 ? {S_AXIS_DATA_WIDTH{1'b0}} : s_axis_data;
assign data_valid = (s_axis_valid & has_sync) | transfer_abort;
assign data_valid = s_axis_valid | transfer_abort;
assign s_axis_ready = data_ready & ~transfer_abort;
always @(posedge s_axis_aclk)
begin
if (s_axis_valid && s_axis_ready && sync) begin
needs_sync <= 1'b0;
end else if (req_valid && req_ready) begin
needs_sync <= req_sync_transfer_start;
end
end
/*
* A 'last' on the external interface indicates the end of an packet. If such a
* 'last' indicator is observed before the end of the current transfer stop
@ -103,7 +92,7 @@ always @(posedge s_axis_aclk) begin
if (s_axis_aresetn == 1'b0) begin
transfer_abort <= 1'b0;
end else if (data_ready == 1'b1 && data_valid == 1'b1) begin
if (fifo_last == 1'b1 && eot == 1'b1 && req_xlast_d == 1'b1) begin
if (fifo_eot == 1'b1 && req_xlast_d == 1'b1) begin
transfer_abort <= 1'b0;
end else if (s_axis_last == 1'b1) begin
transfer_abort <= 1'b1;
@ -134,13 +123,17 @@ dmac_data_mover # (
.req_valid(req_valid),
.req_ready(req_ready),
.req_last_burst_length(req_last_burst_length),
.req_sync_transfer_start(req_sync_transfer_start),
.s_axi_ready(data_ready),
.s_axi_valid(data_valid),
.s_axi_data(data),
.s_axi_sync(s_axis_user[0]),
.m_axi_valid(fifo_valid),
.m_axi_data(fifo_data),
.m_axi_last(fifo_last)
.m_axi_last(fifo_last),
.m_axi_eot(fifo_eot)
);
endmodule

View File

@ -66,21 +66,11 @@ module dmac_src_fifo_inf #(
);
wire ready;
reg needs_sync = 1'b0;
wire has_sync = ~needs_sync | sync;
wire sync_valid = en & ready & has_sync;
wire valid;
assign enabled = enable;
always @(posedge clk)
begin
if (ready && en && sync) begin
needs_sync <= 1'b0;
end else if (req_valid && req_ready) begin
needs_sync <= req_sync_transfer_start;
end
end
assign valid = en & ready;
always @(posedge clk)
begin
@ -108,10 +98,13 @@ dmac_data_mover # (
.req_valid(req_valid),
.req_ready(req_ready),
.req_last_burst_length(req_last_burst_length),
.req_sync_transfer_start(req_sync_transer_start),
.s_axi_ready(ready),
.s_axi_valid(sync_valid),
.s_axi_valid(valid),
.s_axi_data(din),
.s_axi_sync(sync),
.m_axi_valid(fifo_valid),
.m_axi_data(fifo_data),
.m_axi_last(fifo_last)