Skip to content

Commit

Permalink
axi_dmac: wire destination descriptor through source
Browse files Browse the repository at this point in the history
Drive the descriptor from the source side to destination
so we can abort consecutive transfers in case TLAST asserts.

For AXIS count the length of the burst and pass that value to the
destination instead the programmed one. This is useful when the
streams aborts early by asserting the TLAST. We want to notify the
destination with the right number of beats received.

For FIFO source interface reuse the same logic due the small footprint
even if the stream does not got interrupted in that case.
For MM source interface wire the burst length from the request side to
destination.
  • Loading branch information
ronagyl committed Sep 7, 2018
1 parent 0e8515a commit 681b619
Show file tree
Hide file tree
Showing 9 changed files with 248 additions and 54 deletions.
32 changes: 29 additions & 3 deletions library/axi_dmac/address_generator.v
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,14 @@ module dmac_address_generator #(
input req_valid,
output reg req_ready,
input [DMA_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH] req_address,
input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length,

output reg [ID_WIDTH-1:0] id,
input [ID_WIDTH-1:0] request_id,

input bl_valid,
output reg bl_ready,
input [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length,

input eot,

input enable,
Expand Down Expand Up @@ -105,6 +108,12 @@ always @(posedge clk) begin
end
end

always @(posedge clk) begin
if (bl_valid == 1'b1 && bl_ready == 1'b1) begin
last_burst_len <= measured_last_burst_length;
end
end

always @(posedge clk) begin
if (addr_valid == 1'b0) begin
last <= eot;
Expand All @@ -119,12 +128,26 @@ end
always @(posedge clk) begin
if (req_ready == 1'b1) begin
address <= req_address;
last_burst_len <= req_last_burst_length;
end else if (addr_valid == 1'b1 && addr_ready == 1'b1) begin
address <= address + MAX_BEATS_PER_BURST;
end
end

always @(posedge clk) begin
if (resetn == 1'b0) begin
bl_ready <= 1'b1;
end else begin
if (bl_ready == 1'b1) begin
bl_ready <= ~bl_valid;
end else if (addr_valid == 1'b0 && eot == 1'b1) begin
// assert bl_ready only when the addr_valid asserts in the next cycle
if (id != request_id && enable == 1'b1) begin
bl_ready <= 1'b1;
end
end
end
end

always @(posedge clk) begin
if (resetn == 1'b0) begin
req_ready <= 1'b1;
Expand All @@ -136,7 +159,10 @@ always @(posedge clk) begin
addr_valid <= 1'b0;
req_ready <= last;
end else if (id != request_id && enable == 1'b1) begin
addr_valid <= 1'b1;
// if eot wait until the last_burst_len gets synced over
if (eot == 1'b0 || (eot == 1'b1 && bl_ready == 1'b0)) begin
addr_valid <= 1'b1;
end
end
end
end
Expand Down
53 changes: 35 additions & 18 deletions library/axi_dmac/axi_dmac_constr.ttcl
Original file line number Diff line number Diff line change
Expand Up @@ -78,24 +78,6 @@ set_false_path -quiet \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_sync_control_dest* && IS_SEQUENTIAL}]

set_max_delay -quiet -datapath_only \
-from $req_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_dest_req_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $req_clk]

set_max_delay -quiet -datapath_only \
-from $dest_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_dest_req_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $dest_clk]

set_max_delay -quiet -datapath_only \
-from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \
-filter {NAME =~ *i_dest_req_fifo* && IS_SEQUENTIAL}] \
-to $dest_clk \
[get_property -min PERIOD $dest_clk]

set_max_delay -quiet -datapath_only \
-from $dest_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
Expand Down Expand Up @@ -147,6 +129,41 @@ set_max_delay -quiet -datapath_only \
-to $dest_clk \
[get_property -min PERIOD $dest_clk]

set_max_delay -quiet -datapath_only \
-from $src_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_dest_req_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $src_clk]

set_max_delay -quiet -datapath_only \
-from $dest_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_dest_req_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $dest_clk]

set_max_delay -quiet -datapath_only \
-from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \
-filter {NAME =~ *i_dest_req_fifo* && IS_SEQUENTIAL}] \
-to $dest_clk \
[get_property -min PERIOD $dest_clk]

set_max_delay -quiet -datapath_only \
-from $src_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_src_dest_bl_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $src_clk]

set_max_delay -quiet -datapath_only \
-from $dest_clk \
-to [get_cells -quiet -hier *cdc_sync_stage1_reg* \
-filter {NAME =~ *i_src_dest_bl_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \
[get_property -min PERIOD $dest_clk]

set_max_delay -quiet -datapath_only \
-from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \
-filter {NAME =~ *i_src_dest_bl_fifo* && IS_SEQUENTIAL}] \
-to $dest_clk \
[get_property -min PERIOD $dest_clk]
<: } :>
# Reset signals
set_false_path -quiet \
Expand Down
22 changes: 22 additions & 0 deletions library/axi_dmac/data_mover.v
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ module dmac_data_mover #(
output [ID_WIDTH-1:0] response_id,
input eot,

output reg bl_valid = 'b0,
input bl_ready,
output reg [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length,

output xfer_req,

output s_axi_ready,
Expand All @@ -72,6 +76,7 @@ localparam BEAT_COUNTER_MAX = {BEATS_PER_BURST_WIDTH{1'b1}};

reg [BEATS_PER_BURST_WIDTH-1:0] last_burst_length = 'h00;
reg [BEATS_PER_BURST_WIDTH-1:0] beat_counter = 'h00;
reg [BEATS_PER_BURST_WIDTH-1:0] beat_counter_minus_one = 'h0;
reg [ID_WIDTH-1:0] id = 'h00;
reg [ID_WIDTH-1:0] id_next = 'h00;

Expand Down Expand Up @@ -168,6 +173,23 @@ always @(posedge clk) begin
last_burst_length <= req_last_burst_length;
end

always @(posedge clk) begin
if (req_ready) begin
beat_counter_minus_one <= 'h0;
end else if (m_axi_valid == 1'b1) begin
beat_counter_minus_one <= beat_counter;
end
end

always @(posedge clk) begin
if (last_load) begin
bl_valid <= 1'b1;
measured_last_burst_length <= beat_counter_minus_one;
end else if (bl_ready) begin
bl_valid <= 1'b0;
end
end

always @(posedge clk) begin
if (resetn == 1'b0) begin
active <= 1'b0;
Expand Down
10 changes: 8 additions & 2 deletions library/axi_dmac/dest_axi_mm.v
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ module dmac_dest_mm_axi #(
input req_valid,
output req_ready,
input [DMA_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH] req_address,
input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length,

input bl_valid,
output bl_ready,
input [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length,

input enable,
output enabled,
Expand Down Expand Up @@ -115,7 +118,10 @@ dmac_address_generator #(
.req_valid(req_valid),
.req_ready(req_ready),
.req_address(req_address),
.req_last_burst_length(req_last_burst_length),

.bl_valid(bl_valid),
.bl_ready(bl_ready),
.measured_last_burst_length(measured_last_burst_length),

.eot(address_eot),

Expand Down
1 change: 0 additions & 1 deletion library/axi_dmac/dest_axi_stream.v
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ module dmac_dest_axi_stream #(

input req_valid,
output req_ready,
input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length,
input req_xlast,

output response_valid,
Expand Down
Loading

0 comments on commit 681b619

Please sign in to comment.