From 7650894bc432a7ed4545ab6ba2773b7c13b2fafb Mon Sep 17 00:00:00 2001 From: Torben Kalkhof Date: Mon, 9 May 2022 16:02:53 +0200 Subject: [PATCH 1/2] Add QDMA feature for Alveo cards This feature enables the Xilinx QDMA engine as alternative to BlueDMA. If the feature is enabled, following changes are made to the standard HW design: - Remove BlueDMA - Replace MSIX interrupt controller with adjusted IRQ controller for QDMA - Substitute PCIe DMA/Bridge with QDMA IP, and add specific IPs for control - Add Dummy Master for in_ic for compatibility with other plugins (and to make Vivado happy) No changes to the TLKM and API required since QDMA is used for the Versal platform as well. --- toolflow/vivado/common/common_ip.tcl | 1 + .../common/ip/AXIDummyMaster/component.xml | 753 ++++++++++++++++++ .../ip/AXIDummyMaster/src/AXIDummyMaster.v | 66 ++ .../xgui/AXIDummyMaster_v1_0.tcl | 10 + .../vivado/platform/AU250/plugins/qdma.tcl | 27 + toolflow/vivado/platform/AU280/AU280.tcl | 5 +- .../vivado/platform/AU280/plugins/qdma.tcl | 27 + .../vivado/platform/AU280/plugins/svm.tcl | 4 +- toolflow/vivado/platform/common/platform.tcl | 4 +- .../vivado/platform/pcie/plugins/qdma.tcl | 269 +++++++ 10 files changed, 1162 insertions(+), 4 deletions(-) create mode 100644 toolflow/vivado/common/ip/AXIDummyMaster/component.xml create mode 100644 toolflow/vivado/common/ip/AXIDummyMaster/src/AXIDummyMaster.v create mode 100644 toolflow/vivado/common/ip/AXIDummyMaster/xgui/AXIDummyMaster_v1_0.tcl create mode 100644 toolflow/vivado/platform/AU250/plugins/qdma.tcl create mode 100644 toolflow/vivado/platform/AU280/plugins/qdma.tcl create mode 100644 toolflow/vivado/platform/pcie/plugins/qdma.tcl diff --git a/toolflow/vivado/common/common_ip.tcl b/toolflow/vivado/common/common_ip.tcl index dcc40019..b9832aae 100644 --- a/toolflow/vivado/common/common_ip.tcl +++ b/toolflow/vivado/common/common_ip.tcl @@ -72,6 +72,7 @@ dict set stdcomps qdma_intr_ctrl vlnv "esa.informatik.tu-darmstadt.de: dict set stdcomps axi_generic_off vlnv "esa.informatik.tu-darmstadt.de:user:axi_generic_offset:0.1" dict set stdcomps axioffset_hbm vlnv "esa.informatik.tu-darmstadt.de:user:AXIOffsetHBM:1.0" dict set stdcomps sume_clock_prog vlnv "esa.informatik.tu-darmstadt.de:user:SumeClockProgrammer:1.0" +dict set stdcomps axi_dummy_master vlnv "esa.informatik.tu-darmstadt.de:user:AXIDummyMaster:1.0" dict set stdcomps dmi vlnv "esa.informatik.tu-darmstadt.de:user:DMI_rtl:1.0" dict set stdcomps axi_to_dmi vlnv "esa.informatik.tu-darmstadt.de:user:AXI_to_Dmi:1.0" dict set stdcomps tapasco_mmu vlnv "esa.informatik.tu-darmstadt.de:user:TapascoMMU:1.0" diff --git a/toolflow/vivado/common/ip/AXIDummyMaster/component.xml b/toolflow/vivado/common/ip/AXIDummyMaster/component.xml new file mode 100644 index 00000000..1b634052 --- /dev/null +++ b/toolflow/vivado/common/ip/AXIDummyMaster/component.xml @@ -0,0 +1,753 @@ + + + esa.informatik.tu-darmstadt.de + user + AXIDummyMaster + 1.0 + + + M_AXI + + + + + + + + + AWADDR + + + M_AXI_awaddr + + + + + AWPROT + + + M_AXI_awprot + + + + + AWVALID + + + M_AXI_awvalid + + + + + AWREADY + + + M_AXI_awready + + + + + WDATA + + + M_AXI_wdata + + + + + WSTRB + + + M_AXI_wstrb + + + + + WVALID + + + M_AXI_wvalid + + + + + WREADY + + + M_AXI_wready + + + + + BRESP + + + M_AXI_bresp + + + + + BVALID + + + M_AXI_bvalid + + + + + BREADY + + + M_AXI_bready + + + + + ARADDR + + + M_AXI_araddr + + + + + ARPROT + + + M_AXI_arprot + + + + + ARVALID + + + M_AXI_arvalid + + + + + ARREADY + + + M_AXI_arready + + + + + RDATA + + + M_AXI_rdata + + + + + RRESP + + + M_AXI_rresp + + + + + RVALID + + + M_AXI_rvalid + + + + + RREADY + + + M_AXI_rready + + + + + + M_AXI_aresetn + + + + + + + RST + + + M_AXI_aresetn + + + + + + POLARITY + ACTIVE_LOW + + + + + M_AXI_aclk + + + + + + + CLK + + + M_AXI_aclk + + + + + + ASSOCIATED_BUSIF + M_AXI + + + ASSOCIATED_RESET + M_AXI_aresetn + + + + + + + M_AXI + 4K + 32 + + + + + + xilinx_anylanguagesynthesis + Synthesis + :vivado.xilinx.com:synthesis + Verilog + AXIDummyMaster + + xilinx_anylanguagesynthesis_view_fileset + + + + viewChecksum + a52032dc + + + + + xilinx_anylanguagebehavioralsimulation + Simulation + :vivado.xilinx.com:simulation + Verilog + AXIDummyMaster + + xilinx_anylanguagebehavioralsimulation_view_fileset + + + + viewChecksum + a52032dc + + + + + xilinx_xpgui + UI Layout + :vivado.xilinx.com:xgui.ui + + xilinx_xpgui_view_fileset + + + + viewChecksum + f92e9879 + + + + + + + M_AXI_aclk + + in + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_aresetn + + in + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_arvalid + + out + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_arready + + in + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_araddr + + out + + 11 + 0 + + + + std_logic_vector + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_arprot + + out + + 2 + 0 + + + + std_logic_vector + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_rready + + out + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_rvalid + + in + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_rdata + + in + + 31 + 0 + + + + std_logic_vector + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_rresp + + in + + 1 + 0 + + + + std_logic_vector + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_awready + + in + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_awvalid + + out + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_awaddr + + out + + 11 + 0 + + + + std_logic_vector + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_awprot + + out + + 2 + 0 + + + + std_logic_vector + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_wready + + in + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_wvalid + + out + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_wdata + + out + + 31 + 0 + + + + std_logic_vector + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_wstrb + + out + + 3 + 0 + + + + std_logic_vector + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_bvalid + + in + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_bready + + out + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_bresp + + in + + 1 + 0 + + + + std_logic_vector + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + + + + choice_list_9d8b0d81 + ACTIVE_HIGH + ACTIVE_LOW + + + + + xilinx_anylanguagesynthesis_view_fileset + + src/AXIDummyMaster.v + verilogSource + CHECKSUM_a52032dc + + + + xilinx_anylanguagebehavioralsimulation_view_fileset + + src/AXIDummyMaster.v + verilogSource + + + + xilinx_xpgui_view_fileset + + xgui/AXIDummyMaster_v1_0.tcl + tclSource + CHECKSUM_f92e9879 + XGUI_VERSION_2 + + + + AXIDummyMaster + + + Component_Name + AXIDummyMaster_v1_0 + + + + + + virtex7 + qvirtex7 + versal + kintex7 + kintex7l + qkintex7 + qkintex7l + akintex7 + artix7 + artix7l + aartix7 + qartix7 + zynq + qzynq + azynq + spartan7 + aspartan7 + virtexu + zynquplus + virtexuplus + virtexuplusHBM + virtexuplus58g + kintexuplus + kintexu + + + /UserIP + + AXIDummyMaster + package_project + 2 + + user.org:user:AXIDummyMaster:1.0 + + 2021-09-30T12:15:36Z + + + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + /home/torben/Dokumente/Arbeit/QDMA/AXIDummyMaster + + + + 2020.2 + + + + + + + + diff --git a/toolflow/vivado/common/ip/AXIDummyMaster/src/AXIDummyMaster.v b/toolflow/vivado/common/ip/AXIDummyMaster/src/AXIDummyMaster.v new file mode 100644 index 00000000..598e563b --- /dev/null +++ b/toolflow/vivado/common/ip/AXIDummyMaster/src/AXIDummyMaster.v @@ -0,0 +1,66 @@ +module AXIDummyMaster(M_AXI_aclk, + M_AXI_aresetn, + M_AXI_arvalid, + M_AXI_arready, + M_AXI_araddr, + M_AXI_arprot, + M_AXI_rready, + M_AXI_rvalid, + M_AXI_rdata, + M_AXI_rresp, + M_AXI_awready, + M_AXI_awvalid, + M_AXI_awaddr, + M_AXI_awprot, + M_AXI_wready, + M_AXI_wvalid, + M_AXI_wdata, + M_AXI_wstrb, + M_AXI_bvalid, + M_AXI_bready, + M_AXI_bresp); + + input M_AXI_aclk; + input M_AXI_aresetn; + + output M_AXI_arvalid; + input M_AXI_arready; + output [11:0] M_AXI_araddr; + output [2:0] M_AXI_arprot; + + output M_AXI_rready; + input M_AXI_rvalid; + input [31:0] M_AXI_rdata; + input [1:0] M_AXI_rresp; + + input M_AXI_awready; + output M_AXI_awvalid; + output [11:0] M_AXI_awaddr; + output [2:0] M_AXI_awprot; + + input M_AXI_wready; + output M_AXI_wvalid; + output [31:0] M_AXI_wdata; + output [3:0] M_AXI_wstrb; + + input M_AXI_bvalid; + output M_AXI_bready; + input [1:0] M_AXI_bresp; + + assign M_AXI_arvalid = 0; + assign M_AXI_araddr = 0; + assign M_AXI_arprot = 0; + + assign M_AXI_rready = 1; + + assign M_AXI_awvalid = 0; + assign M_AXI_awaddr = 0; + assign M_AXI_awprot = 0; + + assign M_AXI_wvalid = 0; + assign M_AXI_wdata = 0; + assign M_AXI_wstrb = 0; + + assign M_AXI_bready = 1; +endmodule + diff --git a/toolflow/vivado/common/ip/AXIDummyMaster/xgui/AXIDummyMaster_v1_0.tcl b/toolflow/vivado/common/ip/AXIDummyMaster/xgui/AXIDummyMaster_v1_0.tcl new file mode 100644 index 00000000..0db18e9a --- /dev/null +++ b/toolflow/vivado/common/ip/AXIDummyMaster/xgui/AXIDummyMaster_v1_0.tcl @@ -0,0 +1,10 @@ +# Definitional proc to organize widgets for parameters. +proc init_gui { IPINST } { + ipgui::add_param $IPINST -name "Component_Name" + #Adding Page + ipgui::add_page $IPINST -name "Page 0" + + +} + + diff --git a/toolflow/vivado/platform/AU250/plugins/qdma.tcl b/toolflow/vivado/platform/AU250/plugins/qdma.tcl new file mode 100644 index 00000000..78aa9ac4 --- /dev/null +++ b/toolflow/vivado/platform/AU250/plugins/qdma.tcl @@ -0,0 +1,27 @@ +# Copyright (c) 2014-2022 Embedded Systems and Applications, TU Darmstadt. +# +# This file is part of TaPaSCo +# (see https://github.com/esa-tu-darmstadt/tapasco). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# + +namespace eval qdma { + + # Overwrite this function with true if platform supports QDMA + proc is_qdma_supported {} { + return true + } + +} diff --git a/toolflow/vivado/platform/AU280/AU280.tcl b/toolflow/vivado/platform/AU280/AU280.tcl index a8749941..08400545 100644 --- a/toolflow/vivado/platform/AU280/AU280.tcl +++ b/toolflow/vivado/platform/AU280/AU280.tcl @@ -177,12 +177,13 @@ namespace eval platform { insert_regslice "dma_migic" false "/memory/dma/m32_axi" "/memory/mig_ic/S00_AXI" "/memory/mem_clk" "/memory/mem_peripheral_aresetn" "/memory" insert_regslice "host_memctrl" true "/host/M_MEM_CTRL" "/memory/S_MEM_CTRL" "/clocks_and_resets/mem_clk" "/clocks_and_resets/mem_interconnect_aresetn" "" insert_regslice "arch_mem" false "/arch/M_MEM_0" "/memory/S_MEM_0" "/clocks_and_resets/design_clk" "/clocks_and_resets/design_interconnect_aresetn" "" - insert_regslice "host_dma" true "/host/M_DMA" "/memory/S_DMA" "/clocks_and_resets/host_clk" "/clocks_and_resets/host_interconnect_aresetn" "" - insert_regslice "dma_host" true "/memory/M_HOST" "/host/S_HOST" "/clocks_and_resets/host_clk" "/clocks_and_resets/host_interconnect_aresetn" "" + insert_regslice "host_dma" [expr {![tapasco::is_feature_enabled "QDMA"]}] "/host/M_DMA" "/memory/S_DMA" "/clocks_and_resets/host_clk" "/clocks_and_resets/host_interconnect_aresetn" "" + insert_regslice "dma_host" [expr {![tapasco::is_feature_enabled "QDMA"]}] "/memory/M_HOST" "/host/S_HOST" "/clocks_and_resets/host_clk" "/clocks_and_resets/host_interconnect_aresetn" "" insert_regslice "host_arch" true "/host/M_ARCH" "/arch/S_ARCH" "/clocks_and_resets/design_clk" "/clocks_and_resets/design_interconnect_aresetn" "" insert_regslice "l2_cache" [tapasco::is_feature_enabled "Cache"] "/memory/cache_l2_0/M0_AXI" "/memory/mig/C0_DDR4_S_AXI" "/clocks_and_resets/mem_clk" "/clocks_and_resets/mem_peripheral_aresetn" "/memory" insert_regslice "host_mmu" [tapasco::is_feature_enabled "SVM"] "/host/M_MMU" "/memory/S_MMU" "/clocks_and_resets/host_clk" "/clocks_and_resets/host_interconnect_aresetn" "" + insert_regslice "host_qdma" [tapasco::is_feature_enabled "QDMA"] "host/M_MEM_QDMA" "/memory/S_MEM_QDMA" "/clocks_and_resets/host_clk" "clocks_and_resets/host_interconnect_aresetn" "" if {[is_regslice_enabled "pe" false]} { set ips [get_bd_cells /arch/target_ip_*] diff --git a/toolflow/vivado/platform/AU280/plugins/qdma.tcl b/toolflow/vivado/platform/AU280/plugins/qdma.tcl new file mode 100644 index 00000000..78aa9ac4 --- /dev/null +++ b/toolflow/vivado/platform/AU280/plugins/qdma.tcl @@ -0,0 +1,27 @@ +# Copyright (c) 2014-2022 Embedded Systems and Applications, TU Darmstadt. +# +# This file is part of TaPaSCo +# (see https://github.com/esa-tu-darmstadt/tapasco). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# + +namespace eval qdma { + + # Overwrite this function with true if platform supports QDMA + proc is_qdma_supported {} { + return true + } + +} diff --git a/toolflow/vivado/platform/AU280/plugins/svm.tcl b/toolflow/vivado/platform/AU280/plugins/svm.tcl index 98ba748f..5f7d2daf 100644 --- a/toolflow/vivado/platform/AU280/plugins/svm.tcl +++ b/toolflow/vivado/platform/AU280/plugins/svm.tcl @@ -21,6 +21,8 @@ namespace eval svm { proc add_iommu {} { if {[tapasco::is_feature_enabled "SVM"]} { + puts "Adding IOMMU to memory subsystem..." + # add slave port to host subsystem current_bd_instance "/host" set m_mmu [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 "M_MMU"] @@ -83,5 +85,5 @@ namespace eval svm { } } -tapasco::register_plugin "platform::svm::add_iommu" "pre-wiring" +tapasco::register_plugin "platform::svm::add_iommu" "mid-subsystems" tapasco::register_plugin "platform::svm::addressmap" "post-address-map" diff --git a/toolflow/vivado/platform/common/platform.tcl b/toolflow/vivado/platform/common/platform.tcl index e655cccc..38ca6ee2 100644 --- a/toolflow/vivado/platform/common/platform.tcl +++ b/toolflow/vivado/platform/common/platform.tcl @@ -66,7 +66,7 @@ namespace eval platform { current_bd_instance $instance } - tapasco::call_plugins "pre-wiring" + tapasco::call_plugins "mid-subsystems" set sss [list $ss_intc] @@ -83,6 +83,8 @@ namespace eval platform { puts "Subsystem $name complete." } + tapasco::call_plugins "pre-wiring" + wire_subsystem_wires wire_subsystem_intfs addressmap::construct_address_map diff --git a/toolflow/vivado/platform/pcie/plugins/qdma.tcl b/toolflow/vivado/platform/pcie/plugins/qdma.tcl new file mode 100644 index 00000000..5bac96fb --- /dev/null +++ b/toolflow/vivado/platform/pcie/plugins/qdma.tcl @@ -0,0 +1,269 @@ +# Copyright (c) 2014-2022 Embedded Systems and Applications, TU Darmstadt. +# +# This file is part of TaPaSCo +# (see https://github.com/esa-tu-darmstadt/tapasco). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# + +namespace eval qdma { + + # Overwrite this function with true if platform supports QDMA + proc is_qdma_supported {} { + return false + } + + # substitute standard MSIX-controller with special QDMA interrupt controller + proc substitute_intr_ctrl {} { + puts "Removing interrupt controller..." + current_bd_instance "/intc" + + # delete standard interrupt controller + delete_bd_objs [get_bd_pins intr_PLATFORM_COMPONENT_DMA0_READ] \ + [get_bd_pins intr_PLATFORM_COMPONENT_DMA0_WRITE] \ + [get_bd_intf_pins M_MSIX] + delete_bd_objs [get_bd_nets design_clk_1] \ + [get_bd_nets design_peripheral_aresetn_1] \ + [get_bd_nets host_clk_1] \ + [get_bd_nets host_peripheral_aresetn_1] \ + [get_bd_nets int_cc_host_dout] + + if {[llength [get_bd_cells int_cc_design_merge]] > 0} { + delete_bd_objs [get_bd_nets int_cc_design_merge_dout] + } else { + delete_bd_objs [get_bd_nets int_cc_design_0_dout] + } + + delete_bd_objs [get_bd_intf_nets S_INTC_1] \ + [get_bd_intf_nets msix_intr_ctrl_msix] \ + [get_bd_cells msix_intr_ctrl] + + delete_bd_objs [get_bd_nets intr_PLATFORM_COMPONENT_DMA0_READ_1] \ + [get_bd_nets intr_PLATFORM_COMPONENT_DMA0_WRITE_1] \ + [get_bd_cells int_cc_host] + + # add new ports + set usr_irq [create_bd_intf_pin -mode Master -vlnv xilinx.com:display_eqdma:usr_irq_rtl:1.0 "usr_irq"] + set aclk [tapasco::subsystem::get_port "host" "clk"] + set p_aresetn [tapasco::subsystem::get_port "host" "rst" "peripheral" "resetn"] + set design_aclk [tapasco::subsystem::get_port "design" "clk"] + set design_aresetn [tapasco::subsystem::get_port "design" "rst" "peripheral" "resetn"] + + # add new interupt controller + set qdma_intr_ctrl [tapasco::ip::create_qdma_intr_ctrl "qdma_intr_ctrl"] + + # connect everything + connect_bd_net $aclk [get_bd_pins $qdma_intr_ctrl/S_AXI_aclk] + connect_bd_net $design_aclk [get_bd_pins $qdma_intr_ctrl/design_clk] + connect_bd_net $p_aresetn [get_bd_pins $qdma_intr_ctrl/S_AXI_aresetn] + connect_bd_net $design_aresetn [get_bd_pins $qdma_intr_ctrl/design_rst] + + connect_bd_intf_net [get_bd_intf_pins S_INTC] [get_bd_intf_pins $qdma_intr_ctrl/S_AXI] + connect_bd_intf_net [get_bd_intf_pins $qdma_intr_ctrl/usr_irq] $usr_irq + if {[llength [get_bd_cells int_cc_design_merge]] > 0} { + connect_bd_net [get_bd_pins int_cc_design_merge/dout] [get_bd_pins $qdma_intr_ctrl/interrupt_design] + } else { + connect_bd_net [get_bd_pins int_cc_design_0/dout] [get_bd_pins $qdma_intr_ctrl/interrupt_design] + } + + current_bd_instance + } + + proc remove_dma_engine {} { + puts "Removing BlueDMA engine..." + current_bd_instance "/memory" + delete_bd_objs [get_bd_intf_nets S_DMA_1] \ + [get_bd_intf_pins S_DMA] \ + [get_bd_intf_pins M_HOST] \ + [get_bd_pins intr_PLATFORM_COMPONENT_DMA0_WRITE] \ + [get_bd_pins intr_PLATFORM_COMPONENT_DMA0_READ] + delete_bd_objs [get_bd_intf_nets S_DMA_1] \ + [get_bd_intf_nets dma_m32_axi] \ + [get_bd_intf_nets dma_m64_axi] \ + [get_bd_nets host_peripheral_aresetn_1] \ + [get_bd_nets dma_IRQ_write] \ + [get_bd_nets dma_IRQ_read] \ + [get_bd_cells dma] + + # rename port to avoid naming conflicts in address map + set s_mem_qdma [create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 "S_MEM_QDMA"] + connect_bd_intf_net $s_mem_qdma [get_bd_intf_pins mig_ic/S00_AXI] + + current_bd_instance + } + + proc remove_pcie_block {} { + puts "Removing PCIe block..." + delete_bd_objs [get_bd_nets /pcie_perstn_1] \ + [get_bd_ports /pcie_perstn] \ + [get_bd_intf_nets /pcie_refclk_1] \ + [get_bd_intf_nets /host_pci_express_x16] \ + [get_bd_intf_ports /pcie_refclk] \ + [get_bd_intf_ports /pci_express_x16] + delete_bd_objs [get_bd_intf_nets Conn2] \ + [get_bd_intf_nets Conn1] \ + [get_bd_intf_pins pcie_refclk] \ + [get_bd_intf_pins pci_express_x16] \ + [get_bd_nets pcie_perstn_1] \ + [get_bd_pins pcie_perstn] \ + [get_bd_intf_nets S_HOST_1] \ + [get_bd_intf_pins S_HOST] \ + [get_bd_intf_nets S_MSIX_1] \ + [get_bd_intf_pins S_MSIX] + delete_bd_objs [get_bd_nets MSIxTranslator_m_cfg_interrupt_msix_address] \ + [get_bd_nets MSIxTranslator_m_cfg_interrupt_msix_data] \ + [get_bd_nets MSIxTranslator_m_cfg_interrupt_msix_int] \ + [get_bd_nets axi_pcie3_0_cfg_interrupt_msix_enable] \ + [get_bd_nets axi_pcie3_0_cfg_interrupt_msi_fail] \ + [get_bd_nets axi_pcie3_0_cfg_interrupt_msi_sent] \ + [get_bd_cells MSIxTranslator] + delete_bd_objs [get_bd_nets util_ds_buf_IBUF_DS_ODIV2] \ + [get_bd_nets util_ds_buf_IBUF_OUT] \ + [get_bd_cells util_ds_buf] + delete_bd_objs [get_bd_nets axi_pcie3_0_axi_aclk] \ + [get_bd_nets axi_pcie3_0_axi_aresetn] \ + [get_bd_intf_nets in_ic_M00_AXI] \ + [get_bd_intf_nets axi_pcie3_0_M_AXI_B] \ + [get_bd_cells axi_pcie3_0] + } + + # works for QDMA 4.0, overwrite for QDMA 3.0 + proc add_qdma_block {} { + puts "Adding QDMA block..." + set qdma [tapasco::ip::create_qdma qdma_0] + + apply_bd_automation -rule xilinx.com:bd_rule:qdma -config { axi_clk {Maximum Data Width} axi_intf {AXI_MM} bar_size {Disable} lane_width {X16} link_speed {8.0 GT/s (PCIe Gen 3)}} [get_bd_cells $qdma] + + set_property -dict [list CONFIG.axist_bypass_en {true} \ + CONFIG.dsc_byp_mode {Descriptor_bypass_and_internal} \ + CONFIG.pf0_bar0_type_qdma {AXI_Bridge_Master} \ + CONFIG.pf0_bar0_scale_qdma {Megabytes} \ + CONFIG.pf0_bar0_size_qdma {64} \ + CONFIG.pf0_bar2_type_qdma {DMA} \ + CONFIG.pf0_bar2_size_qdma {256} \ + CONFIG.pf1_bar0_type_qdma {AXI_Bridge_Master} \ + CONFIG.pf1_bar0_scale_qdma {Megabytes} \ + CONFIG.pf1_bar0_size_qdma {64} \ + CONFIG.pf1_bar2_type_qdma {DMA} \ + CONFIG.pf1_bar2_size_qdma {256} \ + CONFIG.pf2_bar0_type_qdma {AXI_Bridge_Master} \ + CONFIG.pf2_bar0_scale_qdma {Megabytes} \ + CONFIG.pf2_bar0_size_qdma {64} \ + CONFIG.pf2_bar2_type_qdma {DMA} \ + CONFIG.pf2_bar2_size_qdma {256} \ + CONFIG.pf3_bar0_type_qdma {AXI_Bridge_Master} \ + CONFIG.pf3_bar0_scale_qdma {Megabytes} \ + CONFIG.pf3_bar0_size_qdma {64} \ + CONFIG.pf3_bar2_type_qdma {DMA} \ + CONFIG.pf3_bar2_size_qdma {256} \ + CONFIG.csr_axilite_slave {false} \ + CONFIG.en_bridge_slv {true} \ + CONFIG.axibar_notranslate {true} \ + CONFIG.vdm_en {1} \ + CONFIG.pf0_device_id {7038} \ + CONFIG.PF0_MSIX_CAP_TABLE_SIZE_qdma {01F} \ + CONFIG.PF0_MSIX_CAP_TABLE_BIR_qdma {BAR_3:2} \ + CONFIG.PF1_MSIX_CAP_TABLE_BIR_qdma {BAR_3:2} \ + CONFIG.PF2_MSIX_CAP_TABLE_BIR_qdma {BAR_3:2} \ + CONFIG.PF3_MSIX_CAP_TABLE_BIR_qdma {BAR_3:2} \ + CONFIG.PF0_MSIX_CAP_PBA_BIR_qdma {BAR_3:2} \ + CONFIG.PF1_MSIX_CAP_PBA_BIR_qdma {BAR_3:2} \ + CONFIG.PF2_MSIX_CAP_PBA_BIR_qdma {BAR_3:2} \ + CONFIG.PF3_MSIX_CAP_PBA_BIR_qdma {BAR_3:2} \ + CONFIG.adv_int_usr {true} \ + CONFIG.en_pcie_drp {true}] $qdma + return $qdma + } + + proc substitute_pcie_block {} { + current_bd_instance "/host" + remove_pcie_block + + # create hierarchical ports + set m_mem_qdma [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 "M_MEM_QDMA"] + set s_desc_gen [create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 "S_DMA"] + set usr_irq [create_bd_intf_pin -mode Slave -vlnv xilinx.com:display_eqdma:usr_irq_rtl:1.0 "usr_irq"] + + set pcie_aclk_in [tapasco::subsystem::get_port "host" "clk"] + set pcie_p_aresetn [tapasco::subsystem::get_port "host" "rst" "peripheral" "resetn"] + + # add QDMA and custom configuration cores + set qdma [add_qdma_block] + set qdma_conf [tapasco::ip::create_qdma_configurator qdma_conf_0] + set desc_gen [tapasco::ip::create_qdma_desc_gen desc_gen_0] + set dummy_master [tapasco::ip::create_axi_dummy_master "dummy_master"] + + set out_ic [get_bd_cells out_ic] + set in_ic [get_bd_cells in_ic] + + # connect clock and reset signals + connect_bd_net $pcie_aclk_in [get_bd_pins $desc_gen/aclk] \ + [get_bd_pins $qdma_conf/clk] [get_bd_pins $qdma/drp_clk] \ + [get_bd_pins $dummy_master/M_AXI_aclk] + connect_bd_net $pcie_p_aresetn [get_bd_pins $desc_gen/resetn] \ + [get_bd_pins $qdma_conf/resetn] \ + [get_bd_pins $dummy_master/M_AXI_aresetn] + + connect_bd_net [get_bd_pins $qdma/axi_aclk] [get_bd_pins pcie_aclk] + connect_bd_net [get_bd_pins $qdma/axi_aresetn] [get_bd_pins pcie_aresetn] + + # create AXI connections + connect_bd_intf_net [get_bd_intf_pins $qdma/M_AXI_BRIDGE] \ + [get_bd_intf_pins -of_objects $out_ic -filter "VLNV == [tapasco::ip::get_vlnv aximm_intf] && MODE == Slave"] + connect_bd_intf_net [get_bd_intf_pins $qdma/M_AXI] $m_mem_qdma + connect_bd_intf_net [get_bd_intf_pins $dummy_master/M_AXI] [get_bd_intf_pins $in_ic/S00_AXI] + connect_bd_intf_net [get_bd_intf_pins -of_object $in_ic -filter { MODE == Master }] \ + [get_bd_intf_pins $qdma/S_AXI_BRIDGE] + connect_bd_intf_net $s_desc_gen [get_bd_intf_pins $desc_gen/S_AXI_CTRL] + + # connect remaining pins + connect_bd_intf_net [get_bd_intf_pins $qdma_conf/drp] [get_bd_intf_pins $qdma/drp] + connect_bd_intf_net [get_bd_intf_pins $qdma_conf/msix_vector_ctrl] [get_bd_intf_pins $qdma/msix_vector_ctrl] + connect_bd_net [get_bd_pins $qdma_conf/dma_resetn] [get_bd_pins $qdma/soft_reset_n] + connect_bd_net [get_bd_pins $desc_gen/trigger_reset_cycle] [get_bd_pins $qdma_conf/start_reset] + connect_bd_intf_net [get_bd_intf_pins $desc_gen/c2h_byp_in] [get_bd_intf_pins $qdma/c2h_byp_in_mm] + connect_bd_intf_net [get_bd_intf_pins $desc_gen/h2c_byp_in] [get_bd_intf_pins $qdma/h2c_byp_in_mm] + connect_bd_intf_net [get_bd_intf_pins $qdma/tm_dsc_sts] [get_bd_intf_pins $desc_gen/tm_dsc_sts] + connect_bd_intf_net [get_bd_intf_pins $qdma/qsts_out] [get_bd_intf_pins $desc_gen/qsts_out] + connect_bd_intf_net [get_bd_intf_pins $qdma/c2h_byp_out] [get_bd_intf_pins $desc_gen/c2h_byp_out] + connect_bd_intf_net [get_bd_intf_pins $qdma/h2c_byp_out] [get_bd_intf_pins $desc_gen/h2c_byp_out] + connect_bd_intf_net $usr_irq [get_bd_intf_pins $qdma/usr_irq] + + current_bd_instance + } + + # main function of feature calling subfunctions after each other + proc qdma_feature_top {} { + if {[tapasco::is_feature_enabled "QDMA"]} { + if {[is_qdma_supported]} { + substitute_intr_ctrl + remove_dma_engine + substitute_pcie_block + } else { + puts "ERROR: QDMA not supported by chosen platform..." + exit 1 + } + } + } + + proc addressmap {{args {}}} { + if {[tapasco::is_feature_enabled "QDMA"]} { + set args [lappend args "M_MEM_QDMA" [list 0 0 [expr "1 << 64"] ""]] + } + return $args + } +} + +tapasco::register_plugin "platform::qdma::qdma_feature_top" "pre-wiring" +tapasco::register_plugin "platform::qdma::addressmap" "post-address-map" From 939bffe797c9200dc8c0a6a139c1c46bb7cc049e Mon Sep 17 00:00:00 2001 From: Torben Kalkhof Date: Tue, 10 May 2022 09:42:38 +0200 Subject: [PATCH 2/2] Add QDMA feature to documentation --- documentation/tapasco-features.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/documentation/tapasco-features.md b/documentation/tapasco-features.md index 8a8f02ed..2249314f 100644 --- a/documentation/tapasco-features.md +++ b/documentation/tapasco-features.md @@ -141,4 +141,14 @@ If no value is given for a register slice (or for all), a default value is used. #### SVM -The Shared Virtual Memory (SVM) extensions is documented [here](tapasco-svm.md) \ No newline at end of file +The Shared Virtual Memory (SVM) extensions is documented [here](tapasco-svm.md) + +#### QDMA + +The Xilinx Queue DMA engine can be used alternatively to the TaPaSCo BlueDMA engine by adding `--features 'QDMA {enabled: true}'` to the `tapasco compose` call. + +### Alveo U250 + +#### QDMA + +See [Alveo U280](#alveo-u280).