# # Copyright (C) 2017 Jens Korinth, TU Darmstadt # # This file is part of Tapasco (TPC). # # Tapasco 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. # # Tapasco 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 Tapasco. If not, see . # # @file vc709.tcl # @brief VC709 platform implementation. # @author J. Korinth, TU Darmstadt (jk@esa.tu-darmstadt.de) # @author J. A. Hofmann, TU Darmstadt (jah@esa.tu-darmstadt.de) # namespace eval platform { namespace export create namespace export max_masters namespace export create_subsystem_clocks_and_resets namespace export create_subsystem_host namespace export create_subsystem_memory namespace export create_subsystem_intc namespace export create_subsystem_tapasco # scan plugin directory foreach f [glob -nocomplain -directory "$::env(TAPASCO_HOME)/platform/vc709/plugins" "*.tcl"] { source -notrace $f } proc max_masters {} { return [list 128] } proc get_address_map {{pe_base ""}} { set max32 [expr "1 << 32"] set max64 [expr "1 << 64"] if {$pe_base == ""} { set pe_base [get_pe_base_address] } set peam [::arch::get_address_map $pe_base] puts "Computing addresses for masters ..." foreach m [::tapasco::get_aximm_interfaces [get_bd_cells -filter "PATH !~ [::tapasco::subsystem::get arch]/*"]] { switch -glob [get_property NAME $m] { "M_DMA" { foreach {base stride range} [list 0x00300000 0x10000 0 ] {} } "M_INTC" { foreach {base stride range} [list 0x00400000 0x10000 0 ] {} } "M_MSIX" { foreach {base stride range} [list 0x00500000 0x10000 $max64] {} } "M_TAPASCO" { foreach {base stride range} [list 0x02800000 0 0 ] {} } "M_HOST" { foreach {base stride range} [list 0 0 $max64] {} } "M_ARCH" { set base "skip" } default { foreach {base stride range} [list 0 0 0] {} } } if {$base != "skip"} { set peam [assign_address $peam $m $base $stride $range] } } return $peam } # Setup the clock network. proc platform_connect_clock {clock_pin} { puts "Connecting clocks ..." set clk_inputs [get_bd_pins -of_objects [get_bd_cells -filter {NAME != "mig_7series_0" && NAME != "proc_sys_reset_0"&& NAME != "axi_pcie3_0" && NAME != "pcie_ic"}] -filter { TYPE == "clk" && DIR == "I" && NAME != "refclk"}] connect_bd_net $clock_pin $clk_inputs } # Create interrupt controller subsystem: # Consists of AXI_INTC IP cores (as many as required), which are connected by an internal # AXI Interconnect (S_AXI port), as well as an PCIe interrupt controller IP which can be # connected to the PCIe bridge (required ports external). # @param irqs List of the interrupts from the threadpool. proc create_subsystem_intc {} { set irqs [arch::get_irqs] puts "Connecting [llength $irqs] interrupts .." # create hierarchical ports set s_axi [create_bd_intf_pin -mode Slave -vlnv [tapasco::ip::get_vlnv "aximm_intf"] "S_INTC"] set aclk [tapasco::subsystem::get_port "host" "clk"] set ic_aresetn [tapasco::subsystem::get_port "host" "rst" "interconnect"] set p_aresetn [tapasco::subsystem::get_port "host" "rst" "peripheral" "resetn"] set dma_irq_read [create_bd_pin -type "intr" -dir I "dma_irq_read"] set dma_irq_write [create_bd_pin -type "intr" -dir I "dma_irq_write"] set msix_fail [create_bd_pin -dir "I" "msix_fail"] set msix_sent [create_bd_pin -dir "I" "msix_sent"] set msix_enable [create_bd_pin -from 3 -to 0 -dir "I" "msix_enable"] set msix_mask [create_bd_pin -from 3 -to 0 -dir "I" "msix_mask"] set msix_data [create_bd_pin -from 31 -to 0 -dir "O" "msix_data"] set msix_addr [create_bd_pin -from 63 -to 0 -dir "O" "msix_addr"] set msix_int [create_bd_pin -dir "O" "msix_int"] set m_axi [create_bd_intf_pin -mode Master -vlnv [tapasco::ip::get_vlnv "aximm_intf"] "M_MSIX"] set num_irqs 132 set num_irqs_threadpools 128 set irq_concat_ss [tapasco::ip::create_xlconcat "interrupt_concat" 6] set irq_unused [tapasco::ip::create_constant "irq_unused" 4 0] # create MSIX interrupt controller set msix_intr_ctrl [tapasco::ip::create_msix_intr_ctrl "msix_intr_ctrl"] connect_bd_net [get_bd_pin -of_objects $irq_concat_ss -filter {NAME == "dout"}] [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "interrupt"}] connect_bd_intf_net [get_bd_intf_pins -of_objects $msix_intr_ctrl -filter {NAME == "M_AXI"}] $m_axi connect_bd_net [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "cfg_interrupt_msix_address"}] $msix_addr connect_bd_net [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "cfg_interrupt_msix_data"}] $msix_data connect_bd_net [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "cfg_interrupt_msix_int"}] $msix_int connect_bd_net $msix_sent [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "cfg_interrupt_msix_sent"}] connect_bd_net $msix_fail [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "cfg_interrupt_msix_fail"}] connect_bd_net $msix_enable [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "cfg_interrupt_msix_enable"}] connect_bd_net $msix_mask [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "cfg_interrupt_msix_mask"}] connect_bd_net $dma_irq_read [get_bd_pin -of_objects $irq_concat_ss -filter {NAME == "In0"}] connect_bd_net $dma_irq_write [get_bd_pin -of_objects $irq_concat_ss -filter {NAME == "In1"}] puts "Unused Interrupts: 2, 3 are tied to 0" connect_bd_net [get_bd_pin -of_object $irq_unused -filter {NAME == "dout"}] [get_bd_pin -of_objects $irq_concat_ss -filter {NAME == "In1"}] for {set i 0} {$i < 4} {incr i} { set port [create_bd_pin -from 127 -to 0 -dir I -type intr "intr_$i"] connect_bd_net $port [get_bd_pin $irq_concat_ss/[format "In%d" [expr "$i + 2"]]] } # connect internal clocks connect_bd_net $aclk [get_bd_pins -of_objects [get_bd_cells -filter {VLNV !~ "*:tapasco:*"}] -filter {TYPE == "clk" && DIR == "I"}] # connect internal interconnect resets set ic_resets [get_bd_pins -of_objects [get_bd_cells -filter {VLNV =~ "*:axi_interconnect:*"}] -filter {NAME == "ARESETN"}] if {[llength $ic_resets] > 0} { connect_bd_net $ic_aresetn $ic_resets } # connect internal peripheral resets set p_resets [get_bd_pins -of_objects [get_bd_cells -filter {VLNV !~ "*:tapasco:*"}] -filter {TYPE == rst && DIR == I && NAME != "ARESETN"}] puts "connect_bd_net $p_aresetn $p_resets" connect_bd_net $p_aresetn $p_resets # connect S_AXI connect_bd_intf_net $s_axi [get_bd_intf_pins -of_objects $msix_intr_ctrl -filter {NAME == "S_AXI"}] } # Creates the memory subsystem consisting of MIG core for DDR RAM, # and a Dual DMA engine which is connected to the MIG and has an # external 64bit M_AXI channel toward PCIe. proc create_subsystem_memory {} { # create hierarchical interface ports set s_axi_mem [create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 "S_MEM_0"] set m_axi_mem [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 "M_HOST"] set s_axi_ddma [create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 "S_DMA"] # create hierarchical ports: clocks set ddr_aclk [create_bd_pin -type "clk" -dir "O" "ddr_aclk"] set design_clk [create_bd_pin -type "clk" -dir "O" "design_aclk"] set pcie_aclk [tapasco::subsystem::get_port "host" "clk"] set design_aclk [tapasco::subsystem::get_port "design" "clk"] # create hierarchical ports: resets set ddr_aresetn [create_bd_pin -type "rst" -dir "O" "ddr_aresetn"] set design_aresetn [create_bd_pin -type "rst" -dir "O" "design_aresetn"] set pcie_p_aresetn [tapasco::subsystem::get_port "host" "rst" "peripheral" "resetn"] set ddr_ic_aresetn [tapasco::subsystem::get_port "mem" "rst" "interconnect"] set ddr_p_aresetn [tapasco::subsystem::get_port "mem" "rst" "peripheral" "resetn"] set design_p_aresetn [tapasco::subsystem::get_port "design" "rst" "peripheral" "resetn"] set irq_read [create_bd_pin -type "intr" -dir "O" "dma_irq_read"] set irq_write [create_bd_pin -type "intr" -dir "O" "dma_irq_write"] # create instances of cores: MIG core, dual DMA, system cache set mig [create_mig_core "mig"] set dual_dma [tapasco::ip::create_dualdma "dual_dma"] set mig_ic [tapasco::ip::create_axi_ic "mig_ic" 2 1] set_property -dict [list \ CONFIG.S01_HAS_DATA_FIFO {2} ] $mig_ic # FIXME this belongs into a plugin set cache_en [tapasco::is_feature_enabled "Cache"] if {$cache_en} { set cf [tapasco::get_feature "Cache"] puts "Platform configured w/L2 Cache, implementing ..." set cache [tapasco::ip::create_axi_cache "cache_l2" 1 \ [dict get [tapasco::get_feature "Cache"] "size"] \ [dict get [tapasco::get_feature "Cache"] "associativity"]] # connect mig_ic master to cache_l2 connect_bd_intf_net [get_bd_intf_pins mig_ic/M00_AXI] [get_bd_intf_pins $cache/S0_AXI_GEN] # connect cache_l2 to MIG connect_bd_intf_net [get_bd_intf_pins $cache/M_AXI] [get_bd_intf_pins mig/S_AXI] } { puts "Platform configured w/o L2 Cache" # no cache - connect directly to MIG connect_bd_intf_net [get_bd_intf_pins mig_ic/M00_AXI] [get_bd_intf_pins mig/S_AXI] } # AXI connections: # connect dual dma 32bit to mig_ic connect_bd_intf_net [get_bd_intf_pins dual_dma/M32_AXI] [get_bd_intf_pins mig_ic/S00_AXI] # connect dual DMA 64bit to external port connect_bd_intf_net [get_bd_intf_pins dual_dma/M64_AXI] $m_axi_mem # connect second mig_ic slave to external port connect_bd_intf_net $s_axi_mem [get_bd_intf_pins mig_ic/S01_AXI] # connect dual DMA S_AXI to external port connect_bd_intf_net $s_axi_ddma [get_bd_intf_pins dual_dma/S_AXI] # connect PCIe clock and reset connect_bd_net $pcie_aclk [get_bd_pins dual_dma/m64_axi_aclk] [get_bd_pins dual_dma/s_axi_aclk] connect_bd_net $pcie_p_aresetn [get_bd_pins dual_dma/m64_axi_aresetn] [get_bd_pins dual_dma/s_axi_aresetn] # connect DDR clock and reset set ddr_clk [get_bd_pins mig/ui_clk] connect_bd_net [tapasco::subsystem::get_port "mem" "clk"] \ [get_bd_pins mig_ic/ACLK] \ [get_bd_pins mig_ic/M00_ACLK] \ [get_bd_pins mig_ic/S00_ACLK] \ [get_bd_pins dual_dma/m32_axi_aclk] connect_bd_net $ddr_ic_aresetn [get_bd_pins mig_ic/ARESETN] connect_bd_net $ddr_p_aresetn \ [get_bd_pins mig_ic/M00_ARESETN] \ [get_bd_pins mig_ic/S00_ARESETN] \ [get_bd_pins dual_dma/m32_axi_aresetn] \ [get_bd_pins mig/aresetn] # connect external DDR clk/rst output ports connect_bd_net [get_bd_pins mig/ui_clk_sync_rst] $ddr_aresetn $design_aresetn connect_bd_net $ddr_clk $ddr_aclk # connect internal design clk/rst connect_bd_net $design_aclk [get_bd_pins mig_ic/S01_ACLK] connect_bd_net $design_p_aresetn [get_bd_pins mig_ic/S01_ARESETN] # connect external design clk set ext_design_clk [get_bd_pins mig/ui_clk] if {[tapasco::get_design_frequency] != [tapasco::get_mem_frequency]} { set ext_design_clk [get_bd_pins mig/ui_addn_clk_0] } connect_bd_net $ext_design_clk $design_clk # FIXME belongs into plugin # connect cache clk/rst if configured if {$cache_en} { connect_bd_net $ddr_clk [get_bd_pins $cache/ACLK] connect_bd_net $ddr_p_aresetn [get_bd_pins $cache/ARESETN] } # connect IRQ if {[tapasco::is_platform_feature_enabled "BlueDMA"]} { connect_bd_net [get_bd_pins dual_dma/IRQ_read] $irq_read connect_bd_net [get_bd_pins dual_dma/IRQ_write] $irq_write } else { connect_bd_net [get_bd_pins dual_dma/IRQ] $irq_read } } proc create_subsystem_host {} { puts "Creating PCIe subsystem ..." # create hierarchical ports set s_axi [create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 "S_HOST"] set s_msix [create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 "S_MSIX"] set m_arch [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 "M_ARCH"] set m_intc [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 "M_INTC"] set m_tapasco [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 "M_TAPASCO"] set m_dma [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 "M_DMA"] set pcie_aclk [create_bd_pin -type "clk" -dir "O" "pcie_aclk"] set pcie_aresetn [create_bd_pin -type "rst" -dir "O" "pcie_aresetn"] set msix_fail [create_bd_pin -dir "O" "msix_fail"] set msix_sent [create_bd_pin -dir "O" "msix_sent"] set msix_enable [create_bd_pin -from 3 -to 0 -dir "O" "msix_enable"] set msix_mask [create_bd_pin -from 3 -to 0 -dir "O" "msix_mask"] set msix_data [create_bd_pin -from 31 -to 0 -dir "I" "msix_data"] set msix_addr [create_bd_pin -from 63 -to 0 -dir "I" "msix_addr"] set msix_int [create_bd_pin -dir "I" "msix_int"] # create instances of cores: PCIe core, mm_to_lite set pcie [create_pcie_core] set mm_to_lite_proto [tapasco::ip::create_proto_conv "mm_to_lite_proto" "AXI4" "AXI4LITE"] set mm_to_lite_slice_before [tapasco::ip::create_axi_reg_slice "mm_to_lite_slice_before"] set mm_to_lite_slice_mid [tapasco::ip::create_axi_reg_slice "mm_to_lite_slice_mid"] set mm_to_lite_slice_after [tapasco::ip::create_axi_reg_slice "mm_to_lite_slice_after"] set mm_to_lite_dwidth [tapasco::ip::create_dwidth_conv "mm_to_lite_dwidth" 256] # connect PCIe slave to external port #connect_bd_intf_net $s_axi [get_bd_intf_pins axi_pcie3_0/S_AXI] # connect PCIe master to external port connect_bd_intf_net [get_bd_intf_pins axi_pcie3_0/M_AXI] [get_bd_intf_pins mm_to_lite_slice_before/S_AXI] # connect mm_to_lite datawidth converter to protocol converter connect_bd_intf_net [get_bd_intf_pins mm_to_lite_slice_before/M_AXI] [get_bd_intf_pins mm_to_lite_dwidth/S_AXI] connect_bd_intf_net [get_bd_intf_pins mm_to_lite_dwidth/M_AXI] [get_bd_intf_pins mm_to_lite_slice_mid/S_AXI] connect_bd_intf_net [get_bd_intf_pins mm_to_lite_slice_mid/M_AXI] [get_bd_intf_pins mm_to_lite_proto/S_AXI] connect_bd_intf_net [get_bd_intf_pins mm_to_lite_proto/M_AXI] [get_bd_intf_pins mm_to_lite_slice_after/S_AXI] # FIXME are the default settings for the IC ok? set out_ic [tapasco::ip::create_axi_ic "out_ic" 1 4] connect_bd_intf_net [get_bd_intf_pins mm_to_lite_slice_after/M_AXI] \ [get_bd_intf_pins -of_objects $out_ic -filter "VLNV == [tapasco::ip::get_vlnv aximm_intf] && MODE == Slave"] set in_ic [tapasco::ip::create_axi_ic "in_ic" 2 1] connect_bd_intf_net [get_bd_intf_pins S_HOST] [get_bd_intf_pins $in_ic/S00_AXI] connect_bd_intf_net [get_bd_intf_pins S_MSIX] [get_bd_intf_pins $in_ic/S01_AXI] connect_bd_intf_net [get_bd_intf_pins -of_object $in_ic -filter { MODE == Master }] \ [get_bd_intf_pins $pcie/S_AXI] connect_bd_intf_net [get_bd_intf_pins -of_objects $out_ic -filter {NAME == M00_AXI}] $m_arch connect_bd_intf_net [get_bd_intf_pins -of_objects $out_ic -filter {NAME == M01_AXI}] $m_intc connect_bd_intf_net [get_bd_intf_pins -of_objects $out_ic -filter {NAME == M02_AXI}] $m_tapasco connect_bd_intf_net [get_bd_intf_pins -of_objects $out_ic -filter {NAME == M03_AXI}] $m_dma connect_bd_net [tapasco::subsystem::get_port "host" "clk"] \ [get_bd_pins $out_ic/ACLK] \ [get_bd_pins -of_objects $out_ic -filter {NAME =~ S0* && TYPE == clk}] \ [get_bd_pins -of_objects $out_ic -filter {NAME =~ M01_* && TYPE == clk}] \ [get_bd_pins -of_objects $out_ic -filter {NAME =~ M03_* && TYPE == clk}] \ [get_bd_pins -of_objects $in_ic -filter {TYPE == clk}] connect_bd_net [tapasco::subsystem::get_port "design" "clk"] \ [get_bd_pins -of_objects $out_ic -filter {NAME =~ M00_* && TYPE == clk}] \ [get_bd_pins -of_objects $out_ic -filter {NAME =~ M02_* && TYPE == clk}] connect_bd_net [tapasco::subsystem::get_port "host" "rst" "peripheral" "resetn"] \ [get_bd_pins $out_ic/ARESETN] \ [get_bd_pins -of_objects $out_ic -filter {NAME =~ S0* && TYPE == rst}] \ [get_bd_pins -of_objects $out_ic -filter {NAME =~ M01_* && TYPE == rst}] \ [get_bd_pins -of_objects $out_ic -filter {NAME =~ M03_* && TYPE == rst}] \ [get_bd_pins -of_objects $in_ic -filter {TYPE == rst}] connect_bd_net [tapasco::subsystem::get_port "design" "rst" "peripheral" "resetn"] \ [get_bd_pins -of_objects $out_ic -filter {NAME =~ M00_* && TYPE == rst}] \ [get_bd_pins -of_objects $out_ic -filter {NAME =~ M02_* && TYPE == rst}] set version [lindex [split [get_property VLNV [get_bd_cells axi_pcie3_0]] :] end] if {[expr "$version < 3.0"]} { # connect axi_ctl_aclk (unused) to axi_aclk connect_bd_net [get_bd_pins axi_pcie3_0/axi_aclk] [get_bd_pins axi_pcie3_0/axi_ctl_aclk] } # connect msix signals to external ports connect_bd_net [get_bd_pins axi_pcie3_0/cfg_interrupt_msix_enable] $msix_enable connect_bd_net [get_bd_pins axi_pcie3_0/cfg_interrupt_msix_mask] $msix_mask connect_bd_net [get_bd_pins axi_pcie3_0/cfg_interrupt_msix_fail] $msix_fail connect_bd_net [get_bd_pins axi_pcie3_0/cfg_interrupt_msix_sent] $msix_sent connect_bd_net $msix_addr [get_bd_pins axi_pcie3_0/cfg_interrupt_msix_address] connect_bd_net $msix_data [get_bd_pins axi_pcie3_0/cfg_interrupt_msix_data] connect_bd_net $msix_int [get_bd_pins axi_pcie3_0/cfg_interrupt_msix_int] # forward PCIe clock to external ports connect_bd_net [get_bd_pins axi_pcie3_0/axi_aclk] $pcie_aclk connect_bd_net [tapasco::subsystem::get_port "host" "clk"] \ [get_bd_pins mm_to_lite_dwidth/s_axi_aclk] \ [get_bd_pins mm_to_lite_proto/aclk] \ [get_bd_pins mm_to_lite_slice_before/aclk] \ [get_bd_pins mm_to_lite_slice_mid/aclk] \ [get_bd_pins mm_to_lite_slice_after/aclk] connect_bd_net [get_bd_pins axi_pcie3_0/axi_aresetn] $pcie_aresetn connect_bd_net [tapasco::subsystem::get_port "host" "rst" "peripheral" "resetn"] \ [get_bd_pins mm_to_lite_dwidth/s_axi_aresetn] \ [get_bd_pins mm_to_lite_proto/aresetn] \ [get_bd_pins mm_to_lite_slice_before/aresetn] \ [get_bd_pins mm_to_lite_slice_mid/aresetn] \ [get_bd_pins mm_to_lite_slice_after/aresetn] } proc create_subsystem_clocks_and_resets {} { # create ports set pcie_clk [create_bd_pin -type "clk" -dir "I" "pcie_aclk"] set pcie_aresetn [create_bd_pin -type "rst" -dir "I" "pcie_aresetn"] set ddr_clk [create_bd_pin -type "clk" -dir "I" "ddr_aclk"] set ddr_clk_aresetn [create_bd_pin -type "rst" -dir "I" "ddr_aresetn"] set design_clk [create_bd_pin -type "clk" -dir "I" "design_aclk"] set design_clk_aresetn [create_bd_pin -type "rst" -dir "I" "design_aresetn"] # create reset generator set host_rst_gen [tapasco::ip::create_rst_gen "host_rst_gen"] set design_rst_gen [tapasco::ip::create_rst_gen "design_rst_gen"] set mem_rst_gen [tapasco::ip::create_rst_gen "mem_rst_gen"] # connect external ports connect_bd_net $pcie_clk [get_bd_pins $host_rst_gen/slowest_sync_clk] [tapasco::subsystem::get_port "host" "clk"] connect_bd_net $pcie_aresetn [get_bd_pins $host_rst_gen/ext_reset_in] connect_bd_net $ddr_clk [get_bd_pins $mem_rst_gen/slowest_sync_clk] [tapasco::subsystem::get_port "mem" "clk"] connect_bd_net $ddr_clk_aresetn [get_bd_pins $mem_rst_gen/ext_reset_in] connect_bd_net $design_clk [get_bd_pins $design_rst_gen/slowest_sync_clk] [tapasco::subsystem::get_port "design" "clk"] connect_bd_net $design_clk_aresetn [get_bd_pins $design_rst_gen/ext_reset_in] # connect to clock reset master connect_bd_net [get_bd_pins $host_rst_gen/peripheral_aresetn] [tapasco::subsystem::get_port "host" "rst" "peripheral" "resetn"] connect_bd_net [get_bd_pins $host_rst_gen/peripheral_reset] [tapasco::subsystem::get_port "host" "rst" "peripheral" "reset"] connect_bd_net [get_bd_pins $host_rst_gen/interconnect_aresetn] [tapasco::subsystem::get_port "host" "rst" "interconnect"] connect_bd_net [get_bd_pins $design_rst_gen/peripheral_aresetn] [tapasco::subsystem::get_port "design" "rst" "peripheral" "resetn"] connect_bd_net [get_bd_pins $design_rst_gen/peripheral_reset] [tapasco::subsystem::get_port "design" "rst" "peripheral" "reset"] connect_bd_net [get_bd_pins $design_rst_gen/interconnect_aresetn] [tapasco::subsystem::get_port "design" "rst" "interconnect"] connect_bd_net [get_bd_pins $mem_rst_gen/peripheral_aresetn] [tapasco::subsystem::get_port "mem" "rst" "peripheral" "resetn"] connect_bd_net [get_bd_pins $mem_rst_gen/peripheral_reset] [tapasco::subsystem::get_port "mem" "rst" "peripheral" "reset"] connect_bd_net [get_bd_pins $mem_rst_gen/interconnect_aresetn] [tapasco::subsystem::get_port "mem" "rst" "interconnect"] } proc create_mig_core {name} { puts "Creating MIG core for DDR ..." # create ports set ddr3_sdram_socket_j1 [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddrx_rtl:1.0 ddr3_sdram_socket_j1 ] set sys_diff_clock [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 sys_diff_clock ] set_property -dict [ list CONFIG.FREQ_HZ {100000000} ] $sys_diff_clock set reset [ create_bd_port -dir I -type rst reset ] set_property -dict [ list CONFIG.POLARITY {ACTIVE_HIGH} ] $reset # create the IP core itself set mig_7series_0 [tapasco::ip::create_mig_core $name] # generate the PRJ File for MIG set str_mig_folder [get_property IP_DIR [ get_ips [ get_property CONFIG.Component_Name $mig_7series_0 ] ] ] set str_mig_file_name mig_a.prj set str_mig_file_path ${str_mig_folder}/${str_mig_file_name} write_mig_file_design_1_mig_7series_0_0 $str_mig_file_path # set MIG properties set_property -dict [ list CONFIG.BOARD_MIG_PARAM {ddr3_sdram_socket_j1} CONFIG.MIG_DONT_TOUCH_PARAM {Custom} CONFIG.RESET_BOARD_INTERFACE {reset} CONFIG.XML_INPUT_FILE {mig_a.prj} ] $mig_7series_0 # connect wires connect_bd_intf_net $ddr3_sdram_socket_j1 [get_bd_intf_pins $name/DDR3] connect_bd_intf_net $sys_diff_clock [get_bd_intf_pins $name/SYS_CLK] connect_bd_net $reset [get_bd_pins $name/sys_rst] return $mig_7series_0 } proc create_pcie_core {} { puts "Creating AXI PCIe Gen3 bridge ..." # create ports set pcie_7x_mgt [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:pcie_7x_mgt_rtl:1.0 pcie_7x_mgt ] set IBUF_DS_N [ create_bd_port -dir I -from 0 -to 0 IBUF_DS_N ] set IBUF_DS_P [ create_bd_port -dir I -from 0 -to 0 IBUF_DS_P ] set pcie_perst [ create_bd_port -dir I -type rst pcie_perst ] set_property -dict [ list CONFIG.POLARITY {ACTIVE_LOW} ] $pcie_perst # create PCIe core set axi_pcie3_0 [tapasco::ip::create_axi_pcie3_0 "axi_pcie3_0"] set pcie_properties [list \ CONFIG.SYS_RST_N_BOARD_INTERFACE {pcie_perst} \ CONFIG.axi_data_width {256_bit} \ CONFIG.pcie_blk_locn {X0Y1} \ CONFIG.pf0_bar0_64bit {true} \ CONFIG.pf0_bar0_scale {Megabytes} \ CONFIG.pf0_bar0_size {64} \ CONFIG.pf0_device_id {7038} \ CONFIG.pl_link_cap_max_link_width {X8} \ CONFIG.pipe_sim {true} \ CONFIG.comp_timeout {50ms} \ CONFIG.pl_link_cap_max_link_speed {8.0_GT/s} \ CONFIG.axisten_freq {250} \ CONFIG.axi_addr_width {64} \ CONFIG.pf0_msi_enabled {false} \ CONFIG.pf0_msix_enabled {true} \ CONFIG.pf0_msix_cap_table_size {83} \ CONFIG.pf0_msix_cap_table_offset {500000} \ CONFIG.pf0_msix_cap_pba_offset {508000} \ CONFIG.comp_timeout {50ms} \ CONFIG.pf0_interrupt_pin {NONE} \ CONFIG.c_s_axi_supports_narrow_burst {false} \ ] # enable ATS/PRI (if platform feature is set) if {[tapasco::is_feature_enabled "ATS-PRI"]} { puts " ATS/PRI support is enabled" lappend pcie_properties \ CONFIG.c_ats_enable {true} \ CONFIG.c_pri_enable {true} \ } set_property -dict $pcie_properties $axi_pcie3_0 # create refclk_ibuf set refclk_ibuf [ create_bd_cell -type ip -vlnv xilinx.com:ip:util_ds_buf:2.1 refclk_ibuf ] set_property -dict [ list CONFIG.C_BUF_TYPE {IBUFDSGTE} ] $refclk_ibuf # connect wires connect_bd_intf_net $pcie_7x_mgt [get_bd_intf_pins axi_pcie3_0/pcie_7x_mgt] connect_bd_net $IBUF_DS_N [get_bd_pins refclk_ibuf/IBUF_DS_N] connect_bd_net $IBUF_DS_P [get_bd_pins refclk_ibuf/IBUF_DS_P] connect_bd_net $pcie_perst [get_bd_pins axi_pcie3_0/sys_rst_n] connect_bd_net [get_bd_pins axi_pcie3_0/refclk] [get_bd_pins refclk_ibuf/IBUF_OUT] # create constraints file for GTX transceivers set constraints_fn "[get_property DIRECTORY [current_project]]/pcie.xdc" set constraints_file [open $constraints_fn w+] puts $constraints_file "set_property LOC IBUFDS_GTE2_X1Y11 \[get_cells {system_i/PCIe/refclk_ibuf/U0/USE_IBUFDS_GTE2.GEN_IBUFDS_GTE2[0].IBUFDS_GTE2_I}\]" close $constraints_file read_xdc $constraints_fn return $axi_pcie3_0 } proc get_pe_base_address {} { return 0x02000000 } ################################################################## # MIG PRJ FILE TCL PROCs ################################################################## proc write_mig_file_design_1_mig_7series_0_0 { str_mig_prj_filepath } { set freq [tapasco::get_design_frequency] set div [format "%1.3f" [expr "800.0 / $freq"]] set rf [format "%3.2f" [expr "800.0 / $div"]] puts " target frequency: $freq, divisor: $div, approx. frequency: $rf" if {$freq > 800} { puts "ERROR - invalid design frequency $freq!" exit 1 } set clock_line " $div" if {$freq == 200} { set clock_en_line { 0} } { set clock_en_line { 1} } set mig_prj_file [open $str_mig_prj_filepath w+] puts $mig_prj_file {} puts $mig_prj_file {} puts $mig_prj_file { design_1_mig_7series_0_0} puts $mig_prj_file { 1} puts $mig_prj_file { 1} puts $mig_prj_file { OFF} puts $mig_prj_file { 1024} puts $mig_prj_file { ON} puts $mig_prj_file { Enabled} puts $mig_prj_file { xc7vx690t-ffg1761/-2} puts $mig_prj_file { 2.3} puts $mig_prj_file { Differential} puts $mig_prj_file { Use System Clock} puts $mig_prj_file { ACTIVE HIGH} puts $mig_prj_file { FALSE} puts $mig_prj_file { 0} puts $mig_prj_file { 50 Ohms} puts $mig_prj_file { 1} puts $mig_prj_file { } puts $mig_prj_file { DDR3_SDRAM/SODIMMs/MT8KTF51264HZ-1G9} puts $mig_prj_file { 1250} puts $mig_prj_file { 2.0V} puts $mig_prj_file { 4:1} puts $mig_prj_file { 200} puts $mig_prj_file $clock_en_line puts $mig_prj_file { 800} puts $mig_prj_file $clock_line puts $mig_prj_file { 1} puts $mig_prj_file { 1} puts $mig_prj_file { 1} puts $mig_prj_file { 1} puts $mig_prj_file { 64} puts $mig_prj_file { 1} puts $mig_prj_file { 1} puts $mig_prj_file { Disabled} puts $mig_prj_file { Normal} puts $mig_prj_file { FALSE} puts $mig_prj_file { } puts $mig_prj_file { 16} puts $mig_prj_file { 10} puts $mig_prj_file { 3} puts $mig_prj_file { 1.5V} puts $mig_prj_file { 4294967296} puts $mig_prj_file { BANK_ROW_COLUMN} puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file { 8 - Fixed} puts $mig_prj_file { Sequential} puts $mig_prj_file { 11} puts $mig_prj_file { Normal} puts $mig_prj_file { No} puts $mig_prj_file { Slow Exit} puts $mig_prj_file { Enable} puts $mig_prj_file { RZQ/7} puts $mig_prj_file { Disable} puts $mig_prj_file { Enable} puts $mig_prj_file { RZQ/6} puts $mig_prj_file { 0} puts $mig_prj_file { Disabled} puts $mig_prj_file { Enabled} puts $mig_prj_file { Output Buffer Enabled} puts $mig_prj_file { Full Array} puts $mig_prj_file { 8} puts $mig_prj_file { Enabled} puts $mig_prj_file { Normal} puts $mig_prj_file { Dynamic ODT off} puts $mig_prj_file { AXI} puts $mig_prj_file { } puts $mig_prj_file { RD_PRI_REG} puts $mig_prj_file { 32} puts $mig_prj_file { 512} puts $mig_prj_file { 1} puts $mig_prj_file { 0} puts $mig_prj_file { } puts $mig_prj_file { } puts $mig_prj_file {} close $mig_prj_file } # End of write_mig_file_design_1_mig_7series_0_0() }