Skip to content

Commit

Permalink
axi_dmac: Move sync transfer start logic to the data mover
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
larsclausen authored and Lars-Peter Clausen committed Jul 3, 2018
1 parent 62969bd commit 92984dc
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 33 deletions.
31 changes: 26 additions & 5 deletions library/axi_dmac/data_mover.v
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,16 @@ 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,
output m_axi_last,

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}};
Expand All @@ -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;

Expand All @@ -85,21 +93,34 @@ 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
if (req_ready) 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;
Expand All @@ -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;
Expand Down
23 changes: 8 additions & 15 deletions library/axi_dmac/src_axi_stream.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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
19 changes: 6 additions & 13 deletions library/axi_dmac/src_fifo_inf.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 92984dc

Please sign in to comment.