diff --git a/library/axi_dmac/data_mover.v b/library/axi_dmac/data_mover.v index b76a8dc4a..6255013fd 100644 --- a/library/axi_dmac/data_mover.v +++ b/library/axi_dmac/data_mover.v @@ -37,7 +37,8 @@ module dmac_data_mover #( parameter ID_WIDTH = 3, parameter DATA_WIDTH = 64, - parameter BEATS_PER_BURST_WIDTH = 4) ( + parameter BEATS_PER_BURST_WIDTH = 4, + parameter ALLOW_ABORT = 0) ( input clk, input resetn, @@ -51,6 +52,7 @@ module dmac_data_mover #( output s_axi_ready, input s_axi_valid, input [DATA_WIDTH-1:0] s_axi_data, + input s_axi_last, input s_axi_sync, output m_axi_valid, @@ -60,7 +62,8 @@ module dmac_data_mover #( input req_valid, output req_ready, input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length, - input req_sync_transfer_start + input req_sync_transfer_start, + input req_xlast ); localparam BEAT_COUNTER_MAX = {BEATS_PER_BURST_WIDTH{1'b1}}; @@ -81,7 +84,7 @@ 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 transfer_abort_s; wire last_load; wire last; @@ -92,18 +95,51 @@ 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_sync_valid & pending_burst & active; -assign m_axi_data = s_axi_data; +assign s_axi_ready = (pending_burst & active) & ~transfer_abort_s; +assign m_axi_valid = (s_axi_sync_valid | transfer_abort_s) & pending_burst & active; +assign m_axi_data = transfer_abort_s == 1'b1 ? {DATA_WIDTH{1'b0}} : s_axi_data; assign m_axi_last = last; -assign m_axi_eot = last & eot; + +generate if (ALLOW_ABORT == 1) begin + reg transfer_abort = 1'b0; + reg req_xlast_d = 1'b0; + + /* + * 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 + * accepting data on the external interface and complete the current transfer by + * writing zeros to the buffer. + */ + always @(posedge clk) begin + if (resetn == 1'b0) begin + transfer_abort <= 1'b0; + end else if (m_axi_valid == 1'b1) begin + if (last == 1'b1 && eot == 1'b1 && req_xlast_d == 1'b1) begin + transfer_abort <= 1'b0; + end else if (s_axi_last == 1'b1) begin + transfer_abort <= 1'b1; + end + end + end + + always @(posedge clk) begin + if (req_ready == 1'b1) begin + req_xlast_d <= req_xlast; + end + end + + assign transfer_abort_s = transfer_abort; + +end else begin + assign transfer_abort_s = 1'b0; +end endgenerate /* * 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) + if (m_axi_valid == 1'b1) begin needs_sync <= 1'b0; end else if (req_ready == 1'b1) begin needs_sync <= req_sync_transfer_start; @@ -112,7 +148,7 @@ 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_beat && last_eot && eot; +assign last_load = m_axi_valid && last_eot && eot; assign req_ready = last_load || ~active; always @(posedge clk) begin @@ -120,7 +156,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_beat == 1'b1) begin + end else if (m_axi_valid == 1'b1) begin last_eot <= beat_counter == last_burst_length; last_non_eot <= beat_counter == BEAT_COUNTER_MAX; beat_counter <= beat_counter + 1'b1; @@ -144,7 +180,7 @@ end always @(*) begin - if (s_axi_beat == 1'b1 && last == 1'b1) + if (m_axi_valid == 1'b1 && last == 1'b1) id_next <= inc_id(id); else id_next <= id; diff --git a/library/axi_dmac/src_axi_stream.v b/library/axi_dmac/src_axi_stream.v index 132e63136..7ed016668 100644 --- a/library/axi_dmac/src_axi_stream.v +++ b/library/axi_dmac/src_axi_stream.v @@ -68,48 +68,13 @@ module dmac_src_axi_stream #( input req_xlast ); -reg transfer_abort = 1'b0; -reg req_xlast_d = 1'b0; - -wire [S_AXIS_DATA_WIDTH-1:0] data; -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 | transfer_abort; -assign s_axis_ready = data_ready & ~transfer_abort; - -/* - * 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 - * accepting data on the external interface and complete the current transfer by - * writing zeros to the buffer. - */ -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_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; - end - end -end - -always @(posedge s_axis_aclk) begin - if(req_ready == 1'b1) begin - req_xlast_d <= req_xlast; - end -end - dmac_data_mover # ( .ID_WIDTH(ID_WIDTH), .DATA_WIDTH(S_AXIS_DATA_WIDTH), - .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH) + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH), + .ALLOW_ABORT(1) ) i_data_mover ( .clk(s_axis_aclk), .resetn(s_axis_aresetn), @@ -124,16 +89,17 @@ dmac_data_mover # ( .req_ready(req_ready), .req_last_burst_length(req_last_burst_length), .req_sync_transfer_start(req_sync_transfer_start), + .req_xlast(req_xlast), - .s_axi_ready(data_ready), - .s_axi_valid(data_valid), - .s_axi_data(data), + .s_axi_valid(s_axis_valid), + .s_axi_ready(s_axis_ready), + .s_axi_data(s_axis_data), + .s_axi_last(s_axis_last), .s_axi_sync(s_axis_user[0]), .m_axi_valid(fifo_valid), .m_axi_data(fifo_data), - .m_axi_last(fifo_last), - .m_axi_eot(fifo_eot) + .m_axi_last(fifo_last) ); endmodule diff --git a/library/axi_dmac/src_fifo_inf.v b/library/axi_dmac/src_fifo_inf.v index bcc68602c..c8c7146c1 100644 --- a/library/axi_dmac/src_fifo_inf.v +++ b/library/axi_dmac/src_fifo_inf.v @@ -98,12 +98,14 @@ 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), + .req_sync_transfer_start(req_sync_transfer_start), + .req_xlast(1'b0), .s_axi_ready(ready), .s_axi_valid(valid), .s_axi_data(din), .s_axi_sync(sync), + .s_axi_last(1'b0), .m_axi_valid(fifo_valid), .m_axi_data(fifo_data),