pluto_hdl_adi/library/axi_dmac/axi_dmac_reset_manager.v

347 lines
10 KiB
Coq
Raw Normal View History

axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
// ***************************************************************************
// ***************************************************************************
// Copyright (C) 2014-2023 Analog Devices, Inc. All rights reserved.
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
// developed independently, and may be accompanied by separate and unique license
// terms.
//
// The user should read each of these license terms, and understand the
// freedoms and responsibilities that he or she has by using this source/core.
//
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE.
//
// Redistribution and use of source or resulting binaries, with or without modification
// of this file, are permitted under one of the following two license terms:
//
// 1. The GNU General Public License version 2 as published by the
// Free Software Foundation, which can be found in the top level directory
// of this repository (LICENSE_GPL2), and also online at:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// OR
//
// 2. An ADI specific BSD license, which can be found in the top level directory
// of this repository (LICENSE_ADIBSD), and also on-line at:
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
// This will allow to generate bit files and not release the source code,
// as long as it attaches to an ADI device.
//
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
module axi_dmac_reset_manager #(
parameter ASYNC_CLK_REQ_SRC = 1,
parameter ASYNC_CLK_SRC_DEST = 1,
axi_dmac: Add support for DMA Scatter-Gather This commit introduces a different interface to submit transfers, using DMA descriptors. The structure of the DMA descriptor is as follows: struct dma_desc { u32 flags, u32 id, u64 dest_addr, u64 src_addr, u64 next_sg_addr, u32 y_len, u32 x_len, u32 src_stride, u32 dst_stride, }; The 'flags' field currently offers two control bits: - bit 0: if set, the transfer will complete after this last descriptor is processed, and the DMA core will go back to idle state; if cleared, the next DMA descriptor pointed to by 'next_sg_addr' will be loaded. - bit 1: if set, an end-of-transfer interrupt will be raised after the memory segment pointed to by this descriptor has been transferred. The 'id' field corresponds to an identifier of the descriptor. The 'dest_addr' and 'src_addr' contain the destination and source addresses to use for the transfer, respectively. The 'x_len' field contains the number of bytes to transfer, minus one. The 'y_len', 'src_stride' and 'dst_stride' fields are only useful for 2D transfers, and should be set to zero if 2D transfers are not required. To start a transfer, the address of the first DMA descriptor must be written to register 0x47c and the HWDESC bit of CONTROL register must be set. The Scatter-Gather transfer is queued similarly to the simple transfers, by writing 1 in TRANSFER_SUBMIT. The Scatter-Gather interface has a dedicated AXI-MM bus configured for read transfers, with its own dedicated clock, which can be asynchronous. The Scatter-Gather reset is generated by the reset manager to reset the logic after completing any pending transactions on the bus. When the Scatter-Gather is enabled during runtime, the legacy cyclic functionality of the DMA is disabled. Signed-off-by: Ionut Podgoreanu <ionut.podgoreanu@analog.com>
2023-08-10 10:10:24 +00:00
parameter ASYNC_CLK_DEST_REQ = 1,
parameter ASYNC_CLK_REQ_SG = 1,
parameter DMA_SG_TRANSFER = 0
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
) (
input clk,
input resetn,
input ctrl_enable,
input ctrl_pause,
axi_dmac: Add support for DMA Scatter-Gather This commit introduces a different interface to submit transfers, using DMA descriptors. The structure of the DMA descriptor is as follows: struct dma_desc { u32 flags, u32 id, u64 dest_addr, u64 src_addr, u64 next_sg_addr, u32 y_len, u32 x_len, u32 src_stride, u32 dst_stride, }; The 'flags' field currently offers two control bits: - bit 0: if set, the transfer will complete after this last descriptor is processed, and the DMA core will go back to idle state; if cleared, the next DMA descriptor pointed to by 'next_sg_addr' will be loaded. - bit 1: if set, an end-of-transfer interrupt will be raised after the memory segment pointed to by this descriptor has been transferred. The 'id' field corresponds to an identifier of the descriptor. The 'dest_addr' and 'src_addr' contain the destination and source addresses to use for the transfer, respectively. The 'x_len' field contains the number of bytes to transfer, minus one. The 'y_len', 'src_stride' and 'dst_stride' fields are only useful for 2D transfers, and should be set to zero if 2D transfers are not required. To start a transfer, the address of the first DMA descriptor must be written to register 0x47c and the HWDESC bit of CONTROL register must be set. The Scatter-Gather transfer is queued similarly to the simple transfers, by writing 1 in TRANSFER_SUBMIT. The Scatter-Gather interface has a dedicated AXI-MM bus configured for read transfers, with its own dedicated clock, which can be asynchronous. The Scatter-Gather reset is generated by the reset manager to reset the logic after completing any pending transactions on the bus. When the Scatter-Gather is enabled during runtime, the legacy cyclic functionality of the DMA is disabled. Signed-off-by: Ionut Podgoreanu <ionut.podgoreanu@analog.com>
2023-08-10 10:10:24 +00:00
input ctrl_hwdesc,
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
output req_resetn,
output req_enable,
input req_enabled,
input dest_clk,
input dest_ext_resetn,
output dest_resetn,
output dest_enable,
input dest_enabled,
input src_clk,
input src_ext_resetn,
output src_resetn,
output src_enable,
input src_enabled,
axi_dmac: Add support for DMA Scatter-Gather This commit introduces a different interface to submit transfers, using DMA descriptors. The structure of the DMA descriptor is as follows: struct dma_desc { u32 flags, u32 id, u64 dest_addr, u64 src_addr, u64 next_sg_addr, u32 y_len, u32 x_len, u32 src_stride, u32 dst_stride, }; The 'flags' field currently offers two control bits: - bit 0: if set, the transfer will complete after this last descriptor is processed, and the DMA core will go back to idle state; if cleared, the next DMA descriptor pointed to by 'next_sg_addr' will be loaded. - bit 1: if set, an end-of-transfer interrupt will be raised after the memory segment pointed to by this descriptor has been transferred. The 'id' field corresponds to an identifier of the descriptor. The 'dest_addr' and 'src_addr' contain the destination and source addresses to use for the transfer, respectively. The 'x_len' field contains the number of bytes to transfer, minus one. The 'y_len', 'src_stride' and 'dst_stride' fields are only useful for 2D transfers, and should be set to zero if 2D transfers are not required. To start a transfer, the address of the first DMA descriptor must be written to register 0x47c and the HWDESC bit of CONTROL register must be set. The Scatter-Gather transfer is queued similarly to the simple transfers, by writing 1 in TRANSFER_SUBMIT. The Scatter-Gather interface has a dedicated AXI-MM bus configured for read transfers, with its own dedicated clock, which can be asynchronous. The Scatter-Gather reset is generated by the reset manager to reset the logic after completing any pending transactions on the bus. When the Scatter-Gather is enabled during runtime, the legacy cyclic functionality of the DMA is disabled. Signed-off-by: Ionut Podgoreanu <ionut.podgoreanu@analog.com>
2023-08-10 10:10:24 +00:00
input sg_clk,
input sg_ext_resetn,
output sg_resetn,
output sg_enable,
input sg_enabled,
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
output [11:0] dbg_status
);
/*
* TODO:
* If an external reset is asserted for a domain that domain will go into reset
* immediately. If a transfer is currently active the transfer will be aborted
* and other domains will be shutdown gracefully. The reset manager will stay in
* the shutdown state until all external resets have been de-asserted.
*/
localparam STATE_DO_RESET = 3'h0;
localparam STATE_RESET = 3'h1;
localparam STATE_DISABLED = 3'h2;
localparam STATE_STARTUP = 3'h3;
localparam STATE_ENABLED = 3'h4;
localparam STATE_SHUTDOWN = 3'h5;
reg [2:0] state = 3'b000;
reg needs_reset = 1'b0;
reg do_reset = 1'b0;
reg do_enable = 1'b0;
wire enabled_dest;
wire enabled_src;
axi_dmac: Add support for DMA Scatter-Gather This commit introduces a different interface to submit transfers, using DMA descriptors. The structure of the DMA descriptor is as follows: struct dma_desc { u32 flags, u32 id, u64 dest_addr, u64 src_addr, u64 next_sg_addr, u32 y_len, u32 x_len, u32 src_stride, u32 dst_stride, }; The 'flags' field currently offers two control bits: - bit 0: if set, the transfer will complete after this last descriptor is processed, and the DMA core will go back to idle state; if cleared, the next DMA descriptor pointed to by 'next_sg_addr' will be loaded. - bit 1: if set, an end-of-transfer interrupt will be raised after the memory segment pointed to by this descriptor has been transferred. The 'id' field corresponds to an identifier of the descriptor. The 'dest_addr' and 'src_addr' contain the destination and source addresses to use for the transfer, respectively. The 'x_len' field contains the number of bytes to transfer, minus one. The 'y_len', 'src_stride' and 'dst_stride' fields are only useful for 2D transfers, and should be set to zero if 2D transfers are not required. To start a transfer, the address of the first DMA descriptor must be written to register 0x47c and the HWDESC bit of CONTROL register must be set. The Scatter-Gather transfer is queued similarly to the simple transfers, by writing 1 in TRANSFER_SUBMIT. The Scatter-Gather interface has a dedicated AXI-MM bus configured for read transfers, with its own dedicated clock, which can be asynchronous. The Scatter-Gather reset is generated by the reset manager to reset the logic after completing any pending transactions on the bus. When the Scatter-Gather is enabled during runtime, the legacy cyclic functionality of the DMA is disabled. Signed-off-by: Ionut Podgoreanu <ionut.podgoreanu@analog.com>
2023-08-10 10:10:24 +00:00
wire enabled_sg;
wire enabled_all;
wire disabled_all;
axi_dmac: Add support for DMA Scatter-Gather This commit introduces a different interface to submit transfers, using DMA descriptors. The structure of the DMA descriptor is as follows: struct dma_desc { u32 flags, u32 id, u64 dest_addr, u64 src_addr, u64 next_sg_addr, u32 y_len, u32 x_len, u32 src_stride, u32 dst_stride, }; The 'flags' field currently offers two control bits: - bit 0: if set, the transfer will complete after this last descriptor is processed, and the DMA core will go back to idle state; if cleared, the next DMA descriptor pointed to by 'next_sg_addr' will be loaded. - bit 1: if set, an end-of-transfer interrupt will be raised after the memory segment pointed to by this descriptor has been transferred. The 'id' field corresponds to an identifier of the descriptor. The 'dest_addr' and 'src_addr' contain the destination and source addresses to use for the transfer, respectively. The 'x_len' field contains the number of bytes to transfer, minus one. The 'y_len', 'src_stride' and 'dst_stride' fields are only useful for 2D transfers, and should be set to zero if 2D transfers are not required. To start a transfer, the address of the first DMA descriptor must be written to register 0x47c and the HWDESC bit of CONTROL register must be set. The Scatter-Gather transfer is queued similarly to the simple transfers, by writing 1 in TRANSFER_SUBMIT. The Scatter-Gather interface has a dedicated AXI-MM bus configured for read transfers, with its own dedicated clock, which can be asynchronous. The Scatter-Gather reset is generated by the reset manager to reset the logic after completing any pending transactions on the bus. When the Scatter-Gather is enabled during runtime, the legacy cyclic functionality of the DMA is disabled. Signed-off-by: Ionut Podgoreanu <ionut.podgoreanu@analog.com>
2023-08-10 10:10:24 +00:00
generate if (DMA_SG_TRANSFER == 1) begin
assign enabled_all = req_enabled & enabled_src & enabled_dest & (enabled_sg | ~ctrl_hwdesc);
assign disabled_all = ~(req_enabled | enabled_src | enabled_dest | (enabled_sg & ctrl_hwdesc));
end else begin
assign enabled_all = req_enabled & enabled_src & enabled_dest;
assign disabled_all = ~(req_enabled | enabled_src | enabled_dest);
axi_dmac: Add support for DMA Scatter-Gather This commit introduces a different interface to submit transfers, using DMA descriptors. The structure of the DMA descriptor is as follows: struct dma_desc { u32 flags, u32 id, u64 dest_addr, u64 src_addr, u64 next_sg_addr, u32 y_len, u32 x_len, u32 src_stride, u32 dst_stride, }; The 'flags' field currently offers two control bits: - bit 0: if set, the transfer will complete after this last descriptor is processed, and the DMA core will go back to idle state; if cleared, the next DMA descriptor pointed to by 'next_sg_addr' will be loaded. - bit 1: if set, an end-of-transfer interrupt will be raised after the memory segment pointed to by this descriptor has been transferred. The 'id' field corresponds to an identifier of the descriptor. The 'dest_addr' and 'src_addr' contain the destination and source addresses to use for the transfer, respectively. The 'x_len' field contains the number of bytes to transfer, minus one. The 'y_len', 'src_stride' and 'dst_stride' fields are only useful for 2D transfers, and should be set to zero if 2D transfers are not required. To start a transfer, the address of the first DMA descriptor must be written to register 0x47c and the HWDESC bit of CONTROL register must be set. The Scatter-Gather transfer is queued similarly to the simple transfers, by writing 1 in TRANSFER_SUBMIT. The Scatter-Gather interface has a dedicated AXI-MM bus configured for read transfers, with its own dedicated clock, which can be asynchronous. The Scatter-Gather reset is generated by the reset manager to reset the logic after completing any pending transactions on the bus. When the Scatter-Gather is enabled during runtime, the legacy cyclic functionality of the DMA is disabled. Signed-off-by: Ionut Podgoreanu <ionut.podgoreanu@analog.com>
2023-08-10 10:10:24 +00:00
end endgenerate
assign req_enable = do_enable;
axi_dmac: Add support for DMA Scatter-Gather This commit introduces a different interface to submit transfers, using DMA descriptors. The structure of the DMA descriptor is as follows: struct dma_desc { u32 flags, u32 id, u64 dest_addr, u64 src_addr, u64 next_sg_addr, u32 y_len, u32 x_len, u32 src_stride, u32 dst_stride, }; The 'flags' field currently offers two control bits: - bit 0: if set, the transfer will complete after this last descriptor is processed, and the DMA core will go back to idle state; if cleared, the next DMA descriptor pointed to by 'next_sg_addr' will be loaded. - bit 1: if set, an end-of-transfer interrupt will be raised after the memory segment pointed to by this descriptor has been transferred. The 'id' field corresponds to an identifier of the descriptor. The 'dest_addr' and 'src_addr' contain the destination and source addresses to use for the transfer, respectively. The 'x_len' field contains the number of bytes to transfer, minus one. The 'y_len', 'src_stride' and 'dst_stride' fields are only useful for 2D transfers, and should be set to zero if 2D transfers are not required. To start a transfer, the address of the first DMA descriptor must be written to register 0x47c and the HWDESC bit of CONTROL register must be set. The Scatter-Gather transfer is queued similarly to the simple transfers, by writing 1 in TRANSFER_SUBMIT. The Scatter-Gather interface has a dedicated AXI-MM bus configured for read transfers, with its own dedicated clock, which can be asynchronous. The Scatter-Gather reset is generated by the reset manager to reset the logic after completing any pending transactions on the bus. When the Scatter-Gather is enabled during runtime, the legacy cyclic functionality of the DMA is disabled. Signed-off-by: Ionut Podgoreanu <ionut.podgoreanu@analog.com>
2023-08-10 10:10:24 +00:00
assign dbg_status = {needs_reset,req_resetn,src_resetn,dest_resetn,sg_resetn,req_enabled,enabled_src,enabled_dest,enabled_sg,state};
always @(posedge clk) begin
if (state == STATE_DO_RESET) begin
do_reset <= 1'b1;
end else begin
do_reset <= 1'b0;
end
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
end
always @(posedge clk) begin
if (state == STATE_STARTUP || state == STATE_ENABLED) begin
do_enable <= 1'b1;
end else begin
do_enable <= 1'b0;
end
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
end
/*
* If ctrl_enable goes from 1 to 0 a shutdown procedure is initiated. During the
* shutdown procedure all domains are signaled that a shutdown should occur. The
* domains will then complete any active transactions that are required to
* complete according to the interface semantics. Once a domain has completed
* its transactions it will indicate that it has been shutdown. Once all domains
* indicate that they have been disabled a reset pulse will be generated to all
* domains to clear all residual state. The reset pulse is long enough so that it
* is active in all domains for at least 4 clock cycles.
*
* Once the reset signal is de-asserted the DMA is in an idle state and can be
* enabled again. If the DMA receives a enable while it is performing a shutdown
* sequence it will only be re-enabled once the shutdown sequence has
* successfully completed.
*
* If ctrl_pause is asserted all domains will be disabled. But there will be no
* reset, so when the ctrl_pause signal is de-asserted again the DMA will resume
* with its previous state.
*
*/
/*
* If ctrl_enable goes low, even for a single clock cycle, we want to go through
* a full reset sequence. This might happen when the state machine is busy, e.g.
* going through a startup sequence. To avoid missing the event store it for
* later.
*/
always @(posedge clk) begin
if (state == STATE_RESET) begin
needs_reset <= 1'b0;
end else if (ctrl_enable == 1'b0) begin
needs_reset <= 1'b1;
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
end
end
always @(posedge clk) begin
if (resetn == 1'b0) begin
state <= STATE_DO_RESET;
end else begin
case (state)
STATE_DO_RESET: begin
state <= STATE_RESET;
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
end
STATE_RESET: begin
/*
* Wait for the reset sequence to complete. Stay in this state when
* ctrl_enable == 1'b0, otherwise we'd go through the reset sequence
* again and again.
*/
if (ctrl_enable == 1'b1 && req_resetn == 1'b1) begin
state <= STATE_DISABLED;
end
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
end
STATE_DISABLED: begin
if (needs_reset == 1'b1) begin
state <= STATE_DO_RESET;
end else if (ctrl_pause == 1'b0) begin
state <= STATE_STARTUP;
end
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
end
STATE_STARTUP: begin
/* Wait for all domains to be ready */
if (enabled_all == 1'b1) begin
state <= STATE_ENABLED;
end
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
end
STATE_ENABLED: begin
if (needs_reset == 1'b1 || ctrl_pause == 1'b1) begin
state <= STATE_SHUTDOWN;
end
end
STATE_SHUTDOWN: begin
/* Wait for all domains to complete outstanding transactions */
if (disabled_all == 1'b1) begin
state <= STATE_DISABLED;
end
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
end
endcase
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
end
end
/*
* Chain the reset through all clock domains. This makes sure that is asserted
* for at least 4 clock cycles of the slowest domain, no matter what. If
* successive domains have the same clock they'll share their reset signal.
*/
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
axi_dmac: Add support for DMA Scatter-Gather This commit introduces a different interface to submit transfers, using DMA descriptors. The structure of the DMA descriptor is as follows: struct dma_desc { u32 flags, u32 id, u64 dest_addr, u64 src_addr, u64 next_sg_addr, u32 y_len, u32 x_len, u32 src_stride, u32 dst_stride, }; The 'flags' field currently offers two control bits: - bit 0: if set, the transfer will complete after this last descriptor is processed, and the DMA core will go back to idle state; if cleared, the next DMA descriptor pointed to by 'next_sg_addr' will be loaded. - bit 1: if set, an end-of-transfer interrupt will be raised after the memory segment pointed to by this descriptor has been transferred. The 'id' field corresponds to an identifier of the descriptor. The 'dest_addr' and 'src_addr' contain the destination and source addresses to use for the transfer, respectively. The 'x_len' field contains the number of bytes to transfer, minus one. The 'y_len', 'src_stride' and 'dst_stride' fields are only useful for 2D transfers, and should be set to zero if 2D transfers are not required. To start a transfer, the address of the first DMA descriptor must be written to register 0x47c and the HWDESC bit of CONTROL register must be set. The Scatter-Gather transfer is queued similarly to the simple transfers, by writing 1 in TRANSFER_SUBMIT. The Scatter-Gather interface has a dedicated AXI-MM bus configured for read transfers, with its own dedicated clock, which can be asynchronous. The Scatter-Gather reset is generated by the reset manager to reset the logic after completing any pending transactions on the bus. When the Scatter-Gather is enabled during runtime, the legacy cyclic functionality of the DMA is disabled. Signed-off-by: Ionut Podgoreanu <ionut.podgoreanu@analog.com>
2023-08-10 10:10:24 +00:00
localparam NUM_RESET_LINKS = DMA_SG_TRANSFER ? 4 : 3;
localparam GEN_ASYNC_RESET = {
axi_dmac: Add support for DMA Scatter-Gather This commit introduces a different interface to submit transfers, using DMA descriptors. The structure of the DMA descriptor is as follows: struct dma_desc { u32 flags, u32 id, u64 dest_addr, u64 src_addr, u64 next_sg_addr, u32 y_len, u32 x_len, u32 src_stride, u32 dst_stride, }; The 'flags' field currently offers two control bits: - bit 0: if set, the transfer will complete after this last descriptor is processed, and the DMA core will go back to idle state; if cleared, the next DMA descriptor pointed to by 'next_sg_addr' will be loaded. - bit 1: if set, an end-of-transfer interrupt will be raised after the memory segment pointed to by this descriptor has been transferred. The 'id' field corresponds to an identifier of the descriptor. The 'dest_addr' and 'src_addr' contain the destination and source addresses to use for the transfer, respectively. The 'x_len' field contains the number of bytes to transfer, minus one. The 'y_len', 'src_stride' and 'dst_stride' fields are only useful for 2D transfers, and should be set to zero if 2D transfers are not required. To start a transfer, the address of the first DMA descriptor must be written to register 0x47c and the HWDESC bit of CONTROL register must be set. The Scatter-Gather transfer is queued similarly to the simple transfers, by writing 1 in TRANSFER_SUBMIT. The Scatter-Gather interface has a dedicated AXI-MM bus configured for read transfers, with its own dedicated clock, which can be asynchronous. The Scatter-Gather reset is generated by the reset manager to reset the logic after completing any pending transactions on the bus. When the Scatter-Gather is enabled during runtime, the legacy cyclic functionality of the DMA is disabled. Signed-off-by: Ionut Podgoreanu <ionut.podgoreanu@analog.com>
2023-08-10 10:10:24 +00:00
ASYNC_CLK_REQ_SG ? 1'b1 : 1'b0,
ASYNC_CLK_REQ_SRC ? 1'b1 : 1'b0,
ASYNC_CLK_SRC_DEST ? 1'b1 : 1'b0,
1'b1
};
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
axi_dmac: Add support for DMA Scatter-Gather This commit introduces a different interface to submit transfers, using DMA descriptors. The structure of the DMA descriptor is as follows: struct dma_desc { u32 flags, u32 id, u64 dest_addr, u64 src_addr, u64 next_sg_addr, u32 y_len, u32 x_len, u32 src_stride, u32 dst_stride, }; The 'flags' field currently offers two control bits: - bit 0: if set, the transfer will complete after this last descriptor is processed, and the DMA core will go back to idle state; if cleared, the next DMA descriptor pointed to by 'next_sg_addr' will be loaded. - bit 1: if set, an end-of-transfer interrupt will be raised after the memory segment pointed to by this descriptor has been transferred. The 'id' field corresponds to an identifier of the descriptor. The 'dest_addr' and 'src_addr' contain the destination and source addresses to use for the transfer, respectively. The 'x_len' field contains the number of bytes to transfer, minus one. The 'y_len', 'src_stride' and 'dst_stride' fields are only useful for 2D transfers, and should be set to zero if 2D transfers are not required. To start a transfer, the address of the first DMA descriptor must be written to register 0x47c and the HWDESC bit of CONTROL register must be set. The Scatter-Gather transfer is queued similarly to the simple transfers, by writing 1 in TRANSFER_SUBMIT. The Scatter-Gather interface has a dedicated AXI-MM bus configured for read transfers, with its own dedicated clock, which can be asynchronous. The Scatter-Gather reset is generated by the reset manager to reset the logic after completing any pending transactions on the bus. When the Scatter-Gather is enabled during runtime, the legacy cyclic functionality of the DMA is disabled. Signed-off-by: Ionut Podgoreanu <ionut.podgoreanu@analog.com>
2023-08-10 10:10:24 +00:00
wire [NUM_RESET_LINKS:0] reset_async_chain;
wire [NUM_RESET_LINKS:0] reset_sync_chain;
wire [3:0] reset_chain_clks = {sg_clk, clk, src_clk, dest_clk};
assign reset_async_chain[0] = 1'b0;
assign reset_sync_chain[0] = reset_async_chain[3];
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
generate
genvar i;
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
axi_dmac: Add support for DMA Scatter-Gather This commit introduces a different interface to submit transfers, using DMA descriptors. The structure of the DMA descriptor is as follows: struct dma_desc { u32 flags, u32 id, u64 dest_addr, u64 src_addr, u64 next_sg_addr, u32 y_len, u32 x_len, u32 src_stride, u32 dst_stride, }; The 'flags' field currently offers two control bits: - bit 0: if set, the transfer will complete after this last descriptor is processed, and the DMA core will go back to idle state; if cleared, the next DMA descriptor pointed to by 'next_sg_addr' will be loaded. - bit 1: if set, an end-of-transfer interrupt will be raised after the memory segment pointed to by this descriptor has been transferred. The 'id' field corresponds to an identifier of the descriptor. The 'dest_addr' and 'src_addr' contain the destination and source addresses to use for the transfer, respectively. The 'x_len' field contains the number of bytes to transfer, minus one. The 'y_len', 'src_stride' and 'dst_stride' fields are only useful for 2D transfers, and should be set to zero if 2D transfers are not required. To start a transfer, the address of the first DMA descriptor must be written to register 0x47c and the HWDESC bit of CONTROL register must be set. The Scatter-Gather transfer is queued similarly to the simple transfers, by writing 1 in TRANSFER_SUBMIT. The Scatter-Gather interface has a dedicated AXI-MM bus configured for read transfers, with its own dedicated clock, which can be asynchronous. The Scatter-Gather reset is generated by the reset manager to reset the logic after completing any pending transactions on the bus. When the Scatter-Gather is enabled during runtime, the legacy cyclic functionality of the DMA is disabled. Signed-off-by: Ionut Podgoreanu <ionut.podgoreanu@analog.com>
2023-08-10 10:10:24 +00:00
for (i = 0; i < NUM_RESET_LINKS; i = i + 1) begin: reset_gen
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
if (GEN_ASYNC_RESET[i] == 1'b1) begin
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
reg [3:0] reset_async = 4'b1111;
reg [1:0] reset_sync = 2'b11;
reg reset_sync_in = 1'b1;
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
always @(posedge reset_chain_clks[i] or posedge reset_sync_chain[i]) begin
if (reset_sync_chain[i] == 1'b1) begin
reset_sync_in <= 1'b1;
end else begin
reset_sync_in <= reset_async[0];
end
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
end
always @(posedge reset_chain_clks[i] or posedge do_reset) begin
if (do_reset == 1'b1) begin
reset_async <= 4'b1111;
end else begin
reset_async <= {reset_async_chain[i], reset_async[3:1]};
end
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
end
always @(posedge reset_chain_clks[i]) begin
reset_sync <= {reset_sync_in,reset_sync[1]};
end
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
assign reset_async_chain[i+1] = reset_async[0];
assign reset_sync_chain[i+1] = reset_sync[0];
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
end else begin
assign reset_async_chain[i+1] = reset_async_chain[i];
assign reset_sync_chain[i+1] = reset_sync_chain[i];
end
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
end
endgenerate
/* De-assertions in the opposite direction of the data flow: dest, src, request */
assign dest_resetn = ~reset_sync_chain[1];
assign src_resetn = ~reset_sync_chain[2];
assign req_resetn = ~reset_sync_chain[3];
axi_dmac: Add support for DMA Scatter-Gather This commit introduces a different interface to submit transfers, using DMA descriptors. The structure of the DMA descriptor is as follows: struct dma_desc { u32 flags, u32 id, u64 dest_addr, u64 src_addr, u64 next_sg_addr, u32 y_len, u32 x_len, u32 src_stride, u32 dst_stride, }; The 'flags' field currently offers two control bits: - bit 0: if set, the transfer will complete after this last descriptor is processed, and the DMA core will go back to idle state; if cleared, the next DMA descriptor pointed to by 'next_sg_addr' will be loaded. - bit 1: if set, an end-of-transfer interrupt will be raised after the memory segment pointed to by this descriptor has been transferred. The 'id' field corresponds to an identifier of the descriptor. The 'dest_addr' and 'src_addr' contain the destination and source addresses to use for the transfer, respectively. The 'x_len' field contains the number of bytes to transfer, minus one. The 'y_len', 'src_stride' and 'dst_stride' fields are only useful for 2D transfers, and should be set to zero if 2D transfers are not required. To start a transfer, the address of the first DMA descriptor must be written to register 0x47c and the HWDESC bit of CONTROL register must be set. The Scatter-Gather transfer is queued similarly to the simple transfers, by writing 1 in TRANSFER_SUBMIT. The Scatter-Gather interface has a dedicated AXI-MM bus configured for read transfers, with its own dedicated clock, which can be asynchronous. The Scatter-Gather reset is generated by the reset manager to reset the logic after completing any pending transactions on the bus. When the Scatter-Gather is enabled during runtime, the legacy cyclic functionality of the DMA is disabled. Signed-off-by: Ionut Podgoreanu <ionut.podgoreanu@analog.com>
2023-08-10 10:10:24 +00:00
generate if (DMA_SG_TRANSFER == 1) begin
assign sg_resetn = ~reset_sync_chain[4];
end else begin
assign sg_resetn = 1'b0;
end endgenerate
sync_bits #(
.NUM_OF_BITS (1),
.ASYNC_CLK (ASYNC_CLK_DEST_REQ)
) i_sync_control_dest (
.out_clk (dest_clk),
.out_resetn (1'b1),
.in_bits (do_enable),
.out_bits (dest_enable));
sync_bits #(
.NUM_OF_BITS (1),
.ASYNC_CLK (ASYNC_CLK_DEST_REQ)
) i_sync_status_dest (
.out_clk (clk),
.out_resetn (1'b1),
.in_bits (dest_enabled),
.out_bits (enabled_dest));
sync_bits #(
.NUM_OF_BITS (1),
.ASYNC_CLK (ASYNC_CLK_REQ_SRC)
) i_sync_control_src (
.out_clk (src_clk),
.out_resetn (1'b1),
.in_bits (do_enable),
.out_bits (src_enable));
sync_bits #(
.NUM_OF_BITS (1),
.ASYNC_CLK (ASYNC_CLK_REQ_SRC)
) i_sync_status_src (
.out_clk (clk),
.out_resetn (1'b1),
.in_bits (src_enabled),
.out_bits (enabled_src));
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
axi_dmac: Add support for DMA Scatter-Gather This commit introduces a different interface to submit transfers, using DMA descriptors. The structure of the DMA descriptor is as follows: struct dma_desc { u32 flags, u32 id, u64 dest_addr, u64 src_addr, u64 next_sg_addr, u32 y_len, u32 x_len, u32 src_stride, u32 dst_stride, }; The 'flags' field currently offers two control bits: - bit 0: if set, the transfer will complete after this last descriptor is processed, and the DMA core will go back to idle state; if cleared, the next DMA descriptor pointed to by 'next_sg_addr' will be loaded. - bit 1: if set, an end-of-transfer interrupt will be raised after the memory segment pointed to by this descriptor has been transferred. The 'id' field corresponds to an identifier of the descriptor. The 'dest_addr' and 'src_addr' contain the destination and source addresses to use for the transfer, respectively. The 'x_len' field contains the number of bytes to transfer, minus one. The 'y_len', 'src_stride' and 'dst_stride' fields are only useful for 2D transfers, and should be set to zero if 2D transfers are not required. To start a transfer, the address of the first DMA descriptor must be written to register 0x47c and the HWDESC bit of CONTROL register must be set. The Scatter-Gather transfer is queued similarly to the simple transfers, by writing 1 in TRANSFER_SUBMIT. The Scatter-Gather interface has a dedicated AXI-MM bus configured for read transfers, with its own dedicated clock, which can be asynchronous. The Scatter-Gather reset is generated by the reset manager to reset the logic after completing any pending transactions on the bus. When the Scatter-Gather is enabled during runtime, the legacy cyclic functionality of the DMA is disabled. Signed-off-by: Ionut Podgoreanu <ionut.podgoreanu@analog.com>
2023-08-10 10:10:24 +00:00
generate if (DMA_SG_TRANSFER == 1) begin
sync_bits #(
.NUM_OF_BITS (1),
.ASYNC_CLK (ASYNC_CLK_REQ_SG)
) i_sync_control_sg (
.out_clk (sg_clk),
.out_resetn (1'b1),
.in_bits (do_enable),
.out_bits (sg_enable));
sync_bits #(
.NUM_OF_BITS (1),
.ASYNC_CLK (ASYNC_CLK_REQ_SG)
) i_sync_status_sg (
.out_clk (clk),
.out_resetn (1'b1),
.in_bits (sg_enabled),
.out_bits (enabled_sg));
end else begin
assign sg_enable = 1'b0;
assign enabled_sg = 1'b0;
end endgenerate
axi_dmac: Rework transfer shutdown The DMAC allows a transfer to be aborted. When a transfer is aborted the DMAC shuts down as fast as possible while still completing any pending transactions as required by the protocol specifications of the port. E.g. for AXI-MM this means to complete all outstanding bursts. Once the DMAC has entered an idle state a special synchronization signal is send to all modules. This synchronization signal instructs them to flush the pipeline and remove any stale data and metadata associated with the aborted transfer. Once all data has been flushed the DMAC enters the shutdown state and is ready for the next transfer. In addition each module has a reset that resets the modules state and is used at system startup to bring them into a consistent state. Re-work the shutdown process to instead of flushing the pipeline re-use the startup reset signal also for shutdown. To manage the reset signal generation introduce the reset manager module. It contains a state machine that will assert the reset signals in the correct order and for the appropriate duration in case of a transfer shutdown. The reset signal is asserted in all domains until it has been asserted for at least 4 clock cycles in the slowest domain. This ensures that the reset signal is not de-asserted in the faster domains before the slower domains have had a chance to process the reset signal. In addition the reset signal is de-asserted in the opposite direction of the data flow. This ensures that the data sink is ready to receive data before the data source can start sending data. This simplifies the internal handshaking. This approach has multiple advantages. * Issuing a reset and removing all state takes less time than explicitly flushing one sample per clock cycle at a time. * It simplifies the logic in the faster clock domains at the expense of more complicated logic in the slower control clock domain. This allows for higher fMax on the data paths. * Less signals to synchronize from the control domain to the data domains The implementation of the pause mode has also slightly changed. Pause is now a simple disable of the data domains. When the transfer is resumed after a pause the data domains are re-enabled and continue at their previous state. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2017-09-21 14:02:44 +00:00
endmodule