From 374c49ff487c2723119f99f0aaf9a734e673800c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 20 Jul 2017 19:44:09 +0200 Subject: [PATCH] axi_dmac: axi_dmac_hw.tcl: Automatically detect clock domains Qsys allows to query to query the clock domain that is associated with a clock input of a peripheral. This allows to automatically detect whether the different clocks of the DMAC are asynchronous and CDC logic needs to be inserted or not. Auto-detection has the advantages that the configuration parameters don't need to be set manually and the optional configuration will be choose automatically. There is also less chance of error of leaving the settings in a wrong configuration when e.g. the clock domains change. In case the auto-detection should ever fail configuration options that provide a manual overwrite are added as well. Signed-off-by: Lars-Peter Clausen --- library/axi_dmac/axi_dmac_hw.tcl | 82 ++++++++++++++++++++ projects/adrv9371x/common/adrv9371x_qsys.tcl | 9 --- projects/arradio/common/arradio_qsys.tcl | 6 -- 3 files changed, 82 insertions(+), 15 deletions(-) diff --git a/library/axi_dmac/axi_dmac_hw.tcl b/library/axi_dmac/axi_dmac_hw.tcl index c3e9abd57..2a55519e8 100644 --- a/library/axi_dmac/axi_dmac_hw.tcl +++ b/library/axi_dmac/axi_dmac_hw.tcl @@ -10,6 +10,7 @@ set_module_property VERSION 1.0 set_module_property GROUP "Analog Devices" set_module_property DISPLAY_NAME axi_dmac set_module_property ELABORATION_CALLBACK axi_dmac_elaborate +set_module_property VALIDATION_CALLBACK axi_dmac_validate # files @@ -117,16 +118,56 @@ set_parameter_property SYNC_TRANSFER_START GROUP $group set group "Clock Domain Configuration" +add_parameter AUTO_ASYNC_CLK BOOLEAN 1 +set_parameter_property AUTO_ASYNC_CLK DISPLAY_NAME "Automatically Detect Clock Domains" +set_parameter_property AUTO_ASYNC_CLK HDL_PARAMETER false +set_parameter_property AUTO_ASYNC_CLK GROUP $group + foreach {p name} { \ ASYNC_CLK_REQ_SRC "Request and Source" \ ASYNC_CLK_SRC_DEST "Source and Destination" \ ASYNC_CLK_DEST_REQ "Destination and Request" \ } { + add_parameter ${p}_MANUAL INTEGER 1 + set_parameter_property ${p}_MANUAL DISPLAY_NAME [concat $name "Clock Asynchronous"] + set_parameter_property ${p}_MANUAL DISPLAY_HINT boolean + set_parameter_property ${p}_MANUAL HDL_PARAMETER false + set_parameter_property ${p}_MANUAL VISIBLE false + set_parameter_property ${p}_MANUAL GROUP $group + add_parameter $p INTEGER 1 set_parameter_property $p DISPLAY_NAME [concat $name "Clock Asynchronous"] set_parameter_property $p DISPLAY_HINT boolean set_parameter_property $p HDL_PARAMETER true + set_parameter_property $p DERIVED true + set_parameter_property $p GROUP $group +} + +add_parameter CLK_DOMAIN_REQ INTEGER +set_parameter_property CLK_DOMAIN_REQ HDL_PARAMETER false +set_parameter_property CLK_DOMAIN_REQ SYSTEM_INFO {CLOCK_DOMAIN s_axi_clock} +set_parameter_property CLK_DOMAIN_REQ VISIBLE false +set_parameter_property CLK_DOMAIN_REQ GROUP $group + +set src_clks { \ + {CLK_DOMAIN_SRC_AXI m_src_axi_clock} \ + {CLK_DOMAIN_SRC_SAXI if_s_axis_aclk} \ + {CLK_DOMAIN_SRC_FIFO if_fifo_wr_clk} \ +} + +set dest_clks { \ + {CLK_DOMAIN_DEST_AXI m_dest_axi_clock} \ + {CLK_DOMAIN_DEST_SAXI if_m_axis_aclk} \ + {CLK_DOMAIN_DEST_FIFO if_fifo_rd_clk} \ +} + +foreach domain [list {*}$src_clks {*}$dest_clks] { + lassign $domain p clk + add_parameter $p INTEGER + set_parameter_property $p HDL_PARAMETER false + set_parameter_property $p SYSTEM_INFO [list CLOCK_DOMAIN $clk] + set_parameter_property $p VISIBLE false set_parameter_property $p GROUP $group } @@ -145,6 +186,47 @@ set_interface_property interrupt_sender SVD_ADDRESS_GROUP "" add_interface_port interrupt_sender irq irq Output 1 +proc axi_dmac_validate {} { + set auto_clk [get_parameter_value AUTO_ASYNC_CLK] + set type_src [get_parameter_value DMA_TYPE_SRC] + set type_dest [get_parameter_value DMA_TYPE_DEST] + + if {$auto_clk == true} { + global src_clks dest_clks + + set req_domain [get_parameter_value CLK_DOMAIN_REQ] + set src_domain [get_parameter_value [lindex $src_clks $type_src 0]] + set dest_domain [get_parameter_value [lindex $dest_clks $type_dest 0]] + + if {$req_domain != 0 && $req_domain == $src_domain} { + set_parameter_value ASYNC_CLK_REQ_SRC 0 + } else { + set_parameter_value ASYNC_CLK_REQ_SRC 1 + } + + if {$src_domain != 0 && $src_domain == $dest_domain} { + set_parameter_value ASYNC_CLK_SRC_DEST 0 + } else { + set_parameter_value ASYNC_CLK_SRC_DEST 1 + } + + if {$dest_domain != 0 && $dest_domain == $req_domain} { + set_parameter_value ASYNC_CLK_DEST_REQ 0 + } else { + set_parameter_value ASYNC_CLK_DEST_REQ 1 + } + } else { + foreach p {ASYNC_CLK_REQ_SRC ASYNC_CLK_SRC_DEST ASYNC_CLK_DEST_REQ} { + set_parameter_value $p [get_parameter_value ${p}_MANUAL] + } + } + + foreach p {ASYNC_CLK_REQ_SRC ASYNC_CLK_SRC_DEST ASYNC_CLK_DEST_REQ} { + set_parameter_property ${p}_MANUAL VISIBLE [expr $auto_clk ? false : true] + set_parameter_property $p VISIBLE $auto_clk + } +} + # conditional interface proc axi_dmac_elaborate {} { diff --git a/projects/adrv9371x/common/adrv9371x_qsys.tcl b/projects/adrv9371x/common/adrv9371x_qsys.tcl index 82dcfbeaf..231cc7865 100644 --- a/projects/adrv9371x/common/adrv9371x_qsys.tcl +++ b/projects/adrv9371x/common/adrv9371x_qsys.tcl @@ -196,9 +196,6 @@ set_instance_parameter_value axi_ad9371_tx_dma {DMA_DATA_WIDTH_SRC} {128} set_instance_parameter_value axi_ad9371_tx_dma {DMA_DATA_WIDTH_DEST} {128} set_instance_parameter_value axi_ad9371_tx_dma {DMA_LENGTH_WIDTH} {24} set_instance_parameter_value axi_ad9371_tx_dma {DMA_2D_TRANSFER} {0} -set_instance_parameter_value axi_ad9371_tx_dma {ASYNC_CLK_REQ_SRC} {1} -set_instance_parameter_value axi_ad9371_tx_dma {ASYNC_CLK_SRC_DEST} {1} -set_instance_parameter_value axi_ad9371_tx_dma {ASYNC_CLK_DEST_REQ} {1} set_instance_parameter_value axi_ad9371_tx_dma {AXI_SLICE_DEST} {0} set_instance_parameter_value axi_ad9371_tx_dma {AXI_SLICE_SRC} {0} set_instance_parameter_value axi_ad9371_tx_dma {SYNC_TRANSFER_START} {0} @@ -225,9 +222,6 @@ set_instance_parameter_value axi_ad9371_rx_dma {DMA_DATA_WIDTH_SRC} {64} set_instance_parameter_value axi_ad9371_rx_dma {DMA_DATA_WIDTH_DEST} {128} set_instance_parameter_value axi_ad9371_rx_dma {DMA_LENGTH_WIDTH} {24} set_instance_parameter_value axi_ad9371_rx_dma {DMA_2D_TRANSFER} {0} -set_instance_parameter_value axi_ad9371_rx_dma {ASYNC_CLK_REQ_SRC} {1} -set_instance_parameter_value axi_ad9371_rx_dma {ASYNC_CLK_SRC_DEST} {1} -set_instance_parameter_value axi_ad9371_rx_dma {ASYNC_CLK_DEST_REQ} {1} set_instance_parameter_value axi_ad9371_rx_dma {AXI_SLICE_DEST} {0} set_instance_parameter_value axi_ad9371_rx_dma {AXI_SLICE_SRC} {0} set_instance_parameter_value axi_ad9371_rx_dma {SYNC_TRANSFER_START} {0} @@ -251,9 +245,6 @@ set_instance_parameter_value axi_ad9371_rx_os_dma {DMA_DATA_WIDTH_SRC} {64} set_instance_parameter_value axi_ad9371_rx_os_dma {DMA_DATA_WIDTH_DEST} {128} set_instance_parameter_value axi_ad9371_rx_os_dma {DMA_LENGTH_WIDTH} {24} set_instance_parameter_value axi_ad9371_rx_os_dma {DMA_2D_TRANSFER} {0} -set_instance_parameter_value axi_ad9371_rx_os_dma {ASYNC_CLK_REQ_SRC} {1} -set_instance_parameter_value axi_ad9371_rx_os_dma {ASYNC_CLK_SRC_DEST} {1} -set_instance_parameter_value axi_ad9371_rx_os_dma {ASYNC_CLK_DEST_REQ} {1} set_instance_parameter_value axi_ad9371_rx_os_dma {AXI_SLICE_DEST} {0} set_instance_parameter_value axi_ad9371_rx_os_dma {AXI_SLICE_SRC} {0} set_instance_parameter_value axi_ad9371_rx_os_dma {SYNC_TRANSFER_START} {0} diff --git a/projects/arradio/common/arradio_qsys.tcl b/projects/arradio/common/arradio_qsys.tcl index 809b6562d..15ce60694 100755 --- a/projects/arradio/common/arradio_qsys.tcl +++ b/projects/arradio/common/arradio_qsys.tcl @@ -85,9 +85,6 @@ set_instance_parameter_value axi_adc_dma {DMA_DATA_WIDTH_SRC} {64} set_instance_parameter_value axi_adc_dma {DMA_DATA_WIDTH_DEST} {64} set_instance_parameter_value axi_adc_dma {DMA_LENGTH_WIDTH} {24} set_instance_parameter_value axi_adc_dma {DMA_2D_TRANSFER} {0} -set_instance_parameter_value axi_adc_dma {ASYNC_CLK_REQ_SRC} {1} -set_instance_parameter_value axi_adc_dma {ASYNC_CLK_SRC_DEST} {1} -set_instance_parameter_value axi_adc_dma {ASYNC_CLK_DEST_REQ} {1} set_instance_parameter_value axi_adc_dma {AXI_SLICE_DEST} {0} set_instance_parameter_value axi_adc_dma {AXI_SLICE_SRC} {0} set_instance_parameter_value axi_adc_dma {SYNC_TRANSFER_START} {1} @@ -113,9 +110,6 @@ set_instance_parameter_value axi_dac_dma {DMA_DATA_WIDTH_SRC} {64} set_instance_parameter_value axi_dac_dma {DMA_DATA_WIDTH_DEST} {64} set_instance_parameter_value axi_dac_dma {DMA_LENGTH_WIDTH} {24} set_instance_parameter_value axi_dac_dma {DMA_2D_TRANSFER} {0} -set_instance_parameter_value axi_dac_dma {ASYNC_CLK_REQ_SRC} {1} -set_instance_parameter_value axi_dac_dma {ASYNC_CLK_SRC_DEST} {1} -set_instance_parameter_value axi_dac_dma {ASYNC_CLK_DEST_REQ} {1} set_instance_parameter_value axi_dac_dma {AXI_SLICE_DEST} {0} set_instance_parameter_value axi_dac_dma {AXI_SLICE_SRC} {0} set_instance_parameter_value axi_dac_dma {SYNC_TRANSFER_START} {0}