Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions docs/library/axi_dmac/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -462,12 +462,12 @@ Transfer Tear-down
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Non-cyclic transfers stop once the programmed amount of data is transferred to
the destination. Cyclic transfers needs to be stopped with software intervention
by setting the ``ENABLE`` control bit to 0. In case if required, non cyclic
transfers can be interrupted in the same way. The transfer tear down is done
gracefully and is done at a burst resolution on MM interfaces and beat
resolution on non-MM interfaces. DMAC shuts down gracefully as fast as possible
while completing all in-progress MM transactions.
the destination. Cyclic transfers need to be stopped with software intervention
by setting the ``CYCLIC`` flag to 0. In case if required, cyclic and non cyclic
transfers can also be interrupted by setting the ``ENABLE`` control bit to 0. In
this case, the transfer tear down is done gracefully at a burst resolution on MM
interfaces and beat resolution on non-MM interfaces. DMAC shuts down gracefully
as fast as possible while completing all in-progress MM transactions.

Source side: For MM interface once the ``ENABLE`` bit de-asserts the DMAC won't
issue new requests towards the source interface but will wait until all pending
Expand Down Expand Up @@ -569,8 +569,9 @@ overhead.
A transfer is cyclic if the ``CYCLIC`` (``[0]``) bit of the ``FLAGS``
(``0x40C``) is set to 1 during transfer submission.

For cyclic transfers no end-of-transfer interrupts will be generated. To stop a
cyclic transfer the DMA channel must be disabled.
For cyclic transfers one start-of-transfer interrupt and one end-of-transfer
interrupt will be generated, marking the limits of the full transfer. To stop a
cyclic transfer the ``CYCLIC`` flag must be set to 0.

Any additional transfers that are submitted after the submission of a cyclic
transfer (and before stopping the cyclic transfer) will never be executed.
Expand Down
8 changes: 4 additions & 4 deletions docs/regmap/adi_regmap_dmac.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ RO
ENDFIELD

FIELD
[15:8] 0x00000005
[15:8] 0x00000006
VERSION_MINOR
RO
ENDFIELD

FIELD
[7:0] 0x00000064
[7:0] 0x00000061
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be time to let a go, and set the patch number to 0.
proposal #1831

VERSION_PATCH
RO
ENDFIELD
Expand Down Expand Up @@ -343,8 +343,8 @@ FIELD
CYCLIC
RW
Setting this field to 1 puts the DMA transfer into cyclic mode. In cyclic mode
the controller will re-start a transfer again once it has finished. In cyclic
mode no end-of-transfer interrupts will be generated.
the controller will re-start a transfer again once it has finished. Setting this
field to 0 ends the cyclic transfer.
If ``AUTORUN`` is set, the default value of the field is ``AUTORUN_FLAGS[0]``.
ENDFIELD

Expand Down
4 changes: 2 additions & 2 deletions library/axi_dmac/axi_dmac_regmap.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ***************************************************************************
// ***************************************************************************
// Copyright (C) 2014-2024 Analog Devices, Inc. All rights reserved.
// Copyright (C) 2014-2025 Analog Devices, Inc. All rights reserved.
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
Expand Down Expand Up @@ -147,7 +147,7 @@ module axi_dmac_regmap #(
input [31:0] dbg_ids1
);

localparam PCORE_VERSION = 'h00040564;
localparam PCORE_VERSION = 'h00040661;
localparam HAS_ADDR_HIGH = DMA_AXI_ADDR_WIDTH > 32;
localparam ADDR_LOW_MSB = HAS_ADDR_HIGH ? 31 : DMA_AXI_ADDR_WIDTH-1;

Expand Down
46 changes: 42 additions & 4 deletions library/axi_dmac/axi_dmac_regmap_request.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ***************************************************************************
// ***************************************************************************
// Copyright (C) 2018-2024 Analog Devices, Inc. All rights reserved.
// Copyright (C) 2018-2025 Analog Devices, Inc. All rights reserved.
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
Expand Down Expand Up @@ -155,12 +155,19 @@ module axi_dmac_regmap_request #(
reg [1:0] up_transfer_id_eot_d = 'h0;
wire up_bl_partial;

reg up_dma_cyclic_d = 1'b0;
wire cyclic_transfer_s;
wire request_valid_sot;
wire response_valid_eot;

assign request_dest_address = up_dma_dest_address;
assign request_src_address = up_dma_src_address;
assign request_x_length = up_dma_x_length;
assign request_sync_transfer_start = SYNC_TRANSFER_START ? 1'b1 : 1'b0;
assign request_last = up_dma_last;
assign request_cyclic = up_dma_cyclic;
assign request_valid_sot = up_dma_req_valid & up_dma_req_ready;
assign response_valid_eot = response_valid & response_ready & response_eot;

always @(posedge clk) begin
if (reset == 1'b1) begin
Expand All @@ -175,7 +182,7 @@ module axi_dmac_regmap_request #(
if (ctrl_enable == 1'b1) begin
if (up_wreq == 1'b1 && up_waddr == 9'h102) begin
up_dma_req_valid <= up_dma_req_valid | up_wdata[0];
end else if (up_sot == 1'b1) begin
end else if ((up_sot || up_dma_cyclic_d) && !up_dma_cyclic) begin
up_dma_req_valid <= 1'b0;
end
end else begin
Expand Down Expand Up @@ -353,9 +360,40 @@ module axi_dmac_regmap_request #(
end
endgenerate

generate
if (DMA_CYCLIC == 1) begin
// Cyclic transfer handling
reg [2:0] cyclic_queued = 3'h0;
wire [2:0] cyclic_queued_next;

assign cyclic_queued_next = (request_valid_sot && !response_valid_eot) ? cyclic_queued + 1'b1 :
(response_valid_eot && !request_valid_sot) ? cyclic_queued - 1'b1 :
cyclic_queued;
assign cyclic_transfer_s = (cyclic_queued != 3'h0) && (cyclic_queued_next != 3'h0);

always @(posedge clk) begin
if (ctrl_enable == 1'b0) begin
cyclic_queued <= 3'h0;
end else if (up_dma_cyclic == 1'b1 || cyclic_queued != 3'h0) begin
cyclic_queued <= cyclic_queued_next;
end
end
end else begin
assign cyclic_transfer_s = 1'b0;
end
endgenerate

always @(posedge clk) begin
if (ctrl_enable == 1'b0) begin
up_dma_cyclic_d <= 1'b0;
end else begin
up_dma_cyclic_d <= up_dma_cyclic;
end
end

// In cyclic mode the same transfer is submitted over and over again
assign up_sot = (up_dma_cyclic && !ctrl_hwdesc) ? 1'b0 : up_dma_req_valid & up_dma_req_ready;
assign up_eot = (up_dma_cyclic && !ctrl_hwdesc) ? 1'b0 : response_eot & response_valid & response_ready;
assign up_sot = (cyclic_transfer_s && !ctrl_hwdesc) ? 1'b0 : request_valid_sot;
assign up_eot = (cyclic_transfer_s && !ctrl_hwdesc) ? 1'b0 : response_valid_eot;

assign request_valid = up_dma_req_valid;
assign up_dma_req_ready = request_ready;
Expand Down
Loading