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
parent
62969bd7ab
commit
92984dc802
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue