From 0ccd136c15f89ba5e3c14de999cfeadbb0eee99e Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Mon, 23 Feb 2026 00:45:49 -0800 Subject: [PATCH] cndm: Add support for Alveo U45N/SN1000 Signed-off-by: Alex Forencich --- src/cndm/board/Alveo/fpga/README.md | 6 + src/cndm/board/Alveo/fpga/fpga_AU45N/Makefile | 98 ++ .../board/Alveo/fpga/fpga_AU45N/config.tcl | 131 +++ .../board/Alveo/fpga/fpga_AU45N_10g/Makefile | 98 ++ .../Alveo/fpga/fpga_AU45N_10g/config.tcl | 131 +++ src/cndm/board/Alveo/fpga/fpga_au45n.xdc | 222 +++++ src/cndm/board/Alveo/fpga/rtl/fpga_au45n.sv | 895 ++++++++++++++++++ 7 files changed, 1581 insertions(+) create mode 100644 src/cndm/board/Alveo/fpga/fpga_AU45N/Makefile create mode 100644 src/cndm/board/Alveo/fpga/fpga_AU45N/config.tcl create mode 100644 src/cndm/board/Alveo/fpga/fpga_AU45N_10g/Makefile create mode 100644 src/cndm/board/Alveo/fpga/fpga_AU45N_10g/config.tcl create mode 100644 src/cndm/board/Alveo/fpga/fpga_au45n.xdc create mode 100644 src/cndm/board/Alveo/fpga/rtl/fpga_au45n.sv diff --git a/src/cndm/board/Alveo/fpga/README.md b/src/cndm/board/Alveo/fpga/README.md index 7bd6caf..df60303 100644 --- a/src/cndm/board/Alveo/fpga/README.md +++ b/src/cndm/board/Alveo/fpga/README.md @@ -11,6 +11,12 @@ This design targets the Xilinx Alveo series. ## Board details +* AU45N/SN1000 + * FPGA: xcu26-vsva1365-2LV-e + * USB UART: FTDI FT4232H (DMB-2) + * PCIe: gen 3 x16 (~128 Gbps) or dual bifurcated gen 4 x8 (~256 Gbps) + * Reference oscillator: 161.1328125 MHz from Si5394 + * 25GBASE-R PHY: Soft PCS with GTY transceivers * AU55C * FPGA: xcu55c-fsvh2892-2L-e * USB UART: FTDI FT4232H (2 onboard, all 3 via DMB-1) diff --git a/src/cndm/board/Alveo/fpga/fpga_AU45N/Makefile b/src/cndm/board/Alveo/fpga/fpga_AU45N/Makefile new file mode 100644 index 0000000..0cbeb88 --- /dev/null +++ b/src/cndm/board/Alveo/fpga/fpga_AU45N/Makefile @@ -0,0 +1,98 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025-2026 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +# FPGA settings +FPGA_PART = xcu26-vsva1365-2LV-e +FPGA_TOP = fpga +FPGA_ARCH = virtexuplus + +RTL_DIR = ../rtl +LIB_DIR = ../lib +TAXI_SRC_DIR = $(LIB_DIR)/taxi/src + +# Files for synthesis +SYN_FILES = $(RTL_DIR)/fpga_au45n.sv +SYN_FILES += $(RTL_DIR)/fpga_core.sv +SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f +SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f +SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f +SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv +SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f +SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f +SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f +SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv +SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv +SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv +SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f + +# XDC files +XDC_FILES = ../fpga_au45n.xdc +XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl +XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl +XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl +XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl +XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl +XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl +XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl + +# IP +IP_TCL_FILES = ../ip/pcie4c_uscale_plus_0.tcl +IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_25g_us_gty_25g_161.tcl + +# Configuration +CONFIG_TCL_FILES = ./config.tcl + +include ../common/vivado.mk + +program: $(PROJECT).bit + echo "open_hw_manager" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl + echo "exit" >> program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl + +$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit + echo "write_cfgmem -force -format mcs -size 256 -interface SPIx4 -loadbit {up 0x00000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl + echo "exit" >> generate_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ + for x in .mcs .prm; \ + do cp $*$$x rev/$*_rev$$COUNT$$x; \ + echo "Output: rev/$*_rev$$COUNT$$x"; done; + +flash: $(PROJECT).mcs $(PROJECT).prm + echo "open_hw_manager" > flash.tcl + echo "connect_hw_server" >> flash.tcl + echo "open_hw_target" >> flash.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu02g-spi-x1_x2_x4}] 0]" >> flash.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl + echo "program_hw_devices [current_hw_device]" >> flash.tcl + echo "refresh_hw_device [current_hw_device]" >> flash.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl + echo "boot_hw_device [current_hw_device]" >> flash.tcl + echo "exit" >> flash.tcl + vivado -nojournal -nolog -mode batch -source flash.tcl diff --git a/src/cndm/board/Alveo/fpga/fpga_AU45N/config.tcl b/src/cndm/board/Alveo/fpga/fpga_AU45N/config.tcl new file mode 100644 index 0000000..f62eb8a --- /dev/null +++ b/src/cndm/board/Alveo/fpga/fpga_AU45N/config.tcl @@ -0,0 +1,131 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025-2026 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set params [dict create] + +# collect build information +set build_date [clock seconds] +set git_hash 00000000 +set git_tag "" + +if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } { + puts "Error running git or project not under version control" +} + +if { [catch {set git_tag [exec git describe --tags HEAD]}] } { + puts "Error running git, project not under version control, or no tag found" +} + +puts "Build date: ${build_date}" +puts "Git hash: ${git_hash}" +puts "Git tag: ${git_tag}" + +if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } { + puts "Failed to extract version from git tag" + set tag_ver 0.0.1 +} + +puts "Tag version: ${tag_ver}" + +# FW and board IDs +set fpga_id [expr 0x4AD5093] +set fw_id [expr 0x0000C001] +set fw_ver $tag_ver +set board_vendor_id [expr 0x10ee] +set board_device_id [expr 0x902d] +set board_ver 1.0 +set release_info [expr 0x00000000] + +# PCIe IDs +set pcie_vendor_id [expr 0x1234] +set pcie_device_id [expr 0xC001] +set pcie_class_code [expr 0x020000] +set pcie_revision_id [expr 0x00] +set pcie_subsystem_device_id $board_device_id +set pcie_subsystem_vendor_id $board_vendor_id + +# FW ID +dict set params FPGA_ID [format "32'h%08x" $fpga_id] +dict set params FW_ID [format "32'h%08x" $fw_id] +dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0] +dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id] +dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0] +dict set params BUILD_DATE "32'd${build_date}" +dict set params GIT_HASH "32'h${git_hash}" +dict set params RELEASE_INFO [format "32'h%08x" $release_info] + +# PTP configuration +dict set params PTP_TS_EN "1" + +# AXI lite interface configuration (control) +dict set params AXIL_CTRL_DATA_W "32" +dict set params AXIL_CTRL_ADDR_W "24" + +# MAC configuration +dict set params CFG_LOW_LATENCY "1" +dict set params COMBINED_MAC_PCS "1" +dict set params MAC_DATA_W "64" + +# PCIe IP core settings +set pcie [get_ips pcie4c_uscale_plus_0] + +# configure BAR settings +proc configure_bar {pcie pf bar aperture} { + set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes} + for { set i 0 } { $i < [llength $size_list] } { incr i } { + set scale [lindex $size_list $i] + + if {$aperture > 0 && $aperture < ($i+1)*10} { + set size [expr 1 << $aperture - ($i*10)] + + puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)" + + set pcie_config [dict create] + + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true} + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory} + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true} + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true} + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size + + set_property -dict $pcie_config $pcie + + return + } + } + puts "${pcie} PF${pf} BAR${bar}: disabled" + set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie +} + +# Control BAR (BAR 0) +configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W] + +# PCIe IP core configuration +set pcie_config [dict create] + +# PCIe IDs +dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id] +dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id] +dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code] +dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id] +dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id] +dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id] + +# MSI +dict set pcie_config "CONFIG.pf0_msi_enabled" {true} + +set_property -dict $pcie_config $pcie + +# apply parameters to top-level +set param_list {} +dict for {name value} $params { + lappend param_list $name=$value +} + +set_property generic $param_list [get_filesets sources_1] diff --git a/src/cndm/board/Alveo/fpga/fpga_AU45N_10g/Makefile b/src/cndm/board/Alveo/fpga/fpga_AU45N_10g/Makefile new file mode 100644 index 0000000..9f21d2f --- /dev/null +++ b/src/cndm/board/Alveo/fpga/fpga_AU45N_10g/Makefile @@ -0,0 +1,98 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025-2026 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +# FPGA settings +FPGA_PART = xcu26-vsva1365-2LV-e +FPGA_TOP = fpga +FPGA_ARCH = virtexuplus + +RTL_DIR = ../rtl +LIB_DIR = ../lib +TAXI_SRC_DIR = $(LIB_DIR)/taxi/src + +# Files for synthesis +SYN_FILES = $(RTL_DIR)/fpga_au45n.sv +SYN_FILES += $(RTL_DIR)/fpga_core.sv +SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f +SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f +SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f +SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv +SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f +SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f +SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f +SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv +SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv +SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv +SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f + +# XDC files +XDC_FILES = ../fpga_au45n.xdc +XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl +XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl +XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl +XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl +XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl +XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl +XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl + +# IP +IP_TCL_FILES = ../ip/pcie4c_uscale_plus_0.tcl +IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_10g_us_gty_161.tcl + +# Configuration +CONFIG_TCL_FILES = ./config.tcl + +include ../common/vivado.mk + +program: $(PROJECT).bit + echo "open_hw_manager" > program.tcl + echo "connect_hw_server" >> program.tcl + echo "open_hw_target" >> program.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl + echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl + echo "program_hw_devices [current_hw_device]" >> program.tcl + echo "exit" >> program.tcl + vivado -nojournal -nolog -mode batch -source program.tcl + +$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit + echo "write_cfgmem -force -format mcs -size 256 -interface SPIx4 -loadbit {up 0x00000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl + echo "exit" >> generate_mcs.tcl + vivado -nojournal -nolog -mode batch -source generate_mcs.tcl + mkdir -p rev + COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.bit ]; \ + do COUNT=$$((COUNT+1)); done; \ + COUNT=$$((COUNT-1)); \ + for x in .mcs .prm; \ + do cp $*$$x rev/$*_rev$$COUNT$$x; \ + echo "Output: rev/$*_rev$$COUNT$$x"; done; + +flash: $(PROJECT).mcs $(PROJECT).prm + echo "open_hw_manager" > flash.tcl + echo "connect_hw_server" >> flash.tcl + echo "open_hw_target" >> flash.tcl + echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl + echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl + echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu02g-spi-x1_x2_x4}] 0]" >> flash.tcl + echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl + echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl + echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl + echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl + echo "program_hw_devices [current_hw_device]" >> flash.tcl + echo "refresh_hw_device [current_hw_device]" >> flash.tcl + echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl + echo "boot_hw_device [current_hw_device]" >> flash.tcl + echo "exit" >> flash.tcl + vivado -nojournal -nolog -mode batch -source flash.tcl diff --git a/src/cndm/board/Alveo/fpga/fpga_AU45N_10g/config.tcl b/src/cndm/board/Alveo/fpga/fpga_AU45N_10g/config.tcl new file mode 100644 index 0000000..7ca7e40 --- /dev/null +++ b/src/cndm/board/Alveo/fpga/fpga_AU45N_10g/config.tcl @@ -0,0 +1,131 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025-2026 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set params [dict create] + +# collect build information +set build_date [clock seconds] +set git_hash 00000000 +set git_tag "" + +if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } { + puts "Error running git or project not under version control" +} + +if { [catch {set git_tag [exec git describe --tags HEAD]}] } { + puts "Error running git, project not under version control, or no tag found" +} + +puts "Build date: ${build_date}" +puts "Git hash: ${git_hash}" +puts "Git tag: ${git_tag}" + +if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } { + puts "Failed to extract version from git tag" + set tag_ver 0.0.1 +} + +puts "Tag version: ${tag_ver}" + +# FW and board IDs +set fpga_id [expr 0x4AD5093] +set fw_id [expr 0x0000C001] +set fw_ver $tag_ver +set board_vendor_id [expr 0x10ee] +set board_device_id [expr 0x902d] +set board_ver 1.0 +set release_info [expr 0x00000000] + +# PCIe IDs +set pcie_vendor_id [expr 0x1234] +set pcie_device_id [expr 0xC001] +set pcie_class_code [expr 0x020000] +set pcie_revision_id [expr 0x00] +set pcie_subsystem_device_id $board_device_id +set pcie_subsystem_vendor_id $board_vendor_id + +# FW ID +dict set params FPGA_ID [format "32'h%08x" $fpga_id] +dict set params FW_ID [format "32'h%08x" $fw_id] +dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0] +dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id] +dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0] +dict set params BUILD_DATE "32'd${build_date}" +dict set params GIT_HASH "32'h${git_hash}" +dict set params RELEASE_INFO [format "32'h%08x" $release_info] + +# PTP configuration +dict set params PTP_TS_EN "1" + +# AXI lite interface configuration (control) +dict set params AXIL_CTRL_DATA_W "32" +dict set params AXIL_CTRL_ADDR_W "24" + +# MAC configuration +dict set params CFG_LOW_LATENCY "1" +dict set params COMBINED_MAC_PCS "1" +dict set params MAC_DATA_W "32" + +# PCIe IP core settings +set pcie [get_ips pcie4c_uscale_plus_0] + +# configure BAR settings +proc configure_bar {pcie pf bar aperture} { + set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes} + for { set i 0 } { $i < [llength $size_list] } { incr i } { + set scale [lindex $size_list $i] + + if {$aperture > 0 && $aperture < ($i+1)*10} { + set size [expr 1 << $aperture - ($i*10)] + + puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)" + + set pcie_config [dict create] + + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true} + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory} + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true} + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true} + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale + dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size + + set_property -dict $pcie_config $pcie + + return + } + } + puts "${pcie} PF${pf} BAR${bar}: disabled" + set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie +} + +# Control BAR (BAR 0) +configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W] + +# PCIe IP core configuration +set pcie_config [dict create] + +# PCIe IDs +dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id] +dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id] +dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code] +dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id] +dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id] +dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id] + +# MSI +dict set pcie_config "CONFIG.pf0_msi_enabled" {true} + +set_property -dict $pcie_config $pcie + +# apply parameters to top-level +set param_list {} +dict for {name value} $params { + lappend param_list $name=$value +} + +set_property generic $param_list [get_filesets sources_1] diff --git a/src/cndm/board/Alveo/fpga/fpga_au45n.xdc b/src/cndm/board/Alveo/fpga/fpga_au45n.xdc new file mode 100644 index 0000000..9571fc1 --- /dev/null +++ b/src/cndm/board/Alveo/fpga/fpga_au45n.xdc @@ -0,0 +1,222 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +# XDC constraints for the Xilinx Alveo U45N/SN1022 board +# part: xcu26-vsva1365-2LV-e + +# General configuration +set_property CFGBVS GND [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design] +set_property CONFIG_MODE SPIx4 [current_design] +set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] +set_property BITSTREAM.CONFIG.CONFIGRATE 72.9 [current_design] +set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design] +set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design] +set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design] +set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design] +set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design] + +# limit with auxiliary PCIe power input connected +set_operating_conditions -design_power_budget 160 + +# System clocks +# 300 MHz +#set_property -dict {LOC AK23 IOSTANDARD LVDS} [get_ports clk_300mhz_p] +#set_property -dict {LOC AL23 IOSTANDARD LVDS} [get_ports clk_300mhz_n] +#create_clock -period 10 -name clk_300mhz [get_ports clk_300mhz_p] + +# 300 MHz +#set_property -dict {LOC AN27 IOSTANDARD LVDS} [get_ports clk_ddr4_c0_p] +#set_property -dict {LOC AN28 IOSTANDARD LVDS} [get_ports clk_ddr4_c0_n] +#create_clock -period 10 -name clk_ddr4_c0 [get_ports clk_ddr4_c0_p] + +# 300 MHz +#set_property -dict {LOC H34 IOSTANDARD LVDS} [get_ports clk_ddr4_c1_p] +#set_property -dict {LOC H35 IOSTANDARD LVDS} [get_ports clk_ddr4_c1_n] +#create_clock -period 10 -name clk_ddr4_c1 [get_ports clk_ddr4_c1_p] + +# LEDs +set_property -dict {LOC AH24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {card_heart_bit}] +set_property -dict {LOC AL24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {card_status_led}] +set_property -dict {LOC AM23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_act[0]}] +set_property -dict {LOC AM22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_g[0]}] +set_property -dict {LOC AN23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_y[0]}] +set_property -dict {LOC AJ25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_act[1]}] +set_property -dict {LOC AH25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_g[1]}] +set_property -dict {LOC AN24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_y[1]}] + +set_false_path -to [get_ports {qsfp_led_act[*] qsfp_led_stat_g[*] qsfp_led_stat_y[*]}] +set_output_delay 0 [get_ports {qsfp_led_act[*] qsfp_led_stat_g[*] qsfp_led_stat_y[*]}] + +# UART (DMB-2 FT4232H channel CDBUS) +set_property -dict {LOC AP24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_txd] ;# DMB-2 U4.39 RXD CDBUS1 +set_property -dict {LOC AR24 IOSTANDARD LVCMOS18} [get_ports uart_rxd] ;# DMB-2 U4.38 TXD CDBUS0 + +set_false_path -to [get_ports {uart_txd}] +set_output_delay 0 [get_ports {uart_txd}] +set_false_path -from [get_ports {uart_rxd}] +set_input_delay 0 [get_ports {uart_rxd}] + +# BMC +#set_property -dict {LOC AM17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {suc_gpio[0]}] +#set_property -dict {LOC AL18 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {suc_gpio[1]}] +#set_property -dict {LOC AK21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {suc_uart_txd}] +#set_property -dict {LOC AJ21 IOSTANDARD LVCMOS18} [get_ports {suc_uart_rxd}] + +#set_false_path -to [get_ports {suc_uart_txd}] +#set_output_delay 0 [get_ports {suc_uart_txd}] +#set_false_path -from [get_ports {suc_gpio[*] suc_uart_rxd}] +#set_input_delay 0 [get_ports {suc_gpio[*] suc_uart_rxd}] + +# SI5394 (SI5394J-A-GM) +# IN0: 20 MHz TCXO +# OUT1: 161.1328125 MHz to QSFP GTM and GTY +# OUT2: 100 MHz to ... +# OUT3: 300 MHz to ... +#set_property -dict {LOC AN20 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {si5394_rst_b}] +#set_property -dict {LOC AH19 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {si5394_int_b}] +#set_property -dict {LOC AJ19 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {si5394_lol_b}] +#set_property -dict {LOC AJ20 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {si5394_los_b}] + +#set_false_path -to [get_ports {si5394_rst_b}] +#set_output_delay 0 [get_ports {si5394_rst_b}] +#set_false_path -from [get_ports {si5394_int_b si5394_lol_b si5394_los_b}] +#set_input_delay 0 [get_ports {si5394_int_b si5394_lol_b si5394_los_b}] + +# QSFP28 Interfaces +#set_property -dict {LOC A13} [get_ports {qsfp0_rx_p[0]}] ;# MGTMRXP0_234 GTM_DUAL_X0Y1 CH0 +#set_property -dict {LOC A12} [get_ports {qsfp0_rx_n[0]}] ;# MGTMRXN0_234 GTM_DUAL_X0Y1 CH0 +#set_property -dict {LOC C15} [get_ports {qsfp0_tx_p[0]}] ;# MGTMTXP0_234 GTM_DUAL_X0Y1 CH0 +#set_property -dict {LOC C14} [get_ports {qsfp0_tx_n[0]}] ;# MGTMTXN0_234 GTM_DUAL_X0Y1 CH0 +#set_property -dict {LOC A16} [get_ports {qsfp0_rx_p[1]}] ;# MGTMRXP1_234 GTM_DUAL_X0Y1 CH1 +#set_property -dict {LOC A15} [get_ports {qsfp0_rx_n[1]}] ;# MGTMRXN1_234 GTM_DUAL_X0Y1 CH1 +#set_property -dict {LOC C18} [get_ports {qsfp0_tx_p[1]}] ;# MGTMTXP1_234 GTM_DUAL_X0Y1 CH1 +#set_property -dict {LOC C17} [get_ports {qsfp0_tx_n[1]}] ;# MGTMTXN1_234 GTM_DUAL_X0Y1 CH1 +#set_property -dict {LOC A7 } [get_ports {qsfp0_rx_p[2]}] ;# MGTMRXP0_233 GTM_DUAL_X0Y0 CH0 +#set_property -dict {LOC A6 } [get_ports {qsfp0_rx_n[2]}] ;# MGTMRXN0_233 GTM_DUAL_X0Y0 CH0 +#set_property -dict {LOC C9 } [get_ports {qsfp0_tx_p[2]}] ;# MGTMTXP0_233 GTM_DUAL_X0Y0 CH0 +#set_property -dict {LOC C8 } [get_ports {qsfp0_tx_n[2]}] ;# MGTMTXN0_233 GTM_DUAL_X0Y0 CH0 +#set_property -dict {LOC A10} [get_ports {qsfp0_rx_p[3]}] ;# MGTMRXP1_233 GTM_DUAL_X0Y0 CH1 +#set_property -dict {LOC A9 } [get_ports {qsfp0_rx_n[3]}] ;# MGTMRXN1_233 GTM_DUAL_X0Y0 CH1 +#set_property -dict {LOC C12} [get_ports {qsfp0_tx_p[3]}] ;# MGTMTXP1_233 GTM_DUAL_X0Y0 CH1 +#set_property -dict {LOC C11} [get_ports {qsfp0_tx_n[3]}] ;# MGTMTXN1_233 GTM_DUAL_X0Y0 CH1 +#set_property -dict {LOC G10} [get_ports {qsfp0_mgt_refclk_0_p}] ;# MGTREFCLK0P_234 from SI5394 OUT1 via U16 +#set_property -dict {LOC G9 } [get_ports {qsfp0_mgt_refclk_0_n}] ;# MGTREFCLK0N_234 from SI5394 OUT1 via U16 +#set_property -dict {LOC J10} [get_ports {qsfp0_mgt_refclk_1_p}] ;# MGTREFCLK1P_233 from SI5394 OUT1 via U16 +#set_property -dict {LOC J9 } [get_ports {qsfp0_mgt_refclk_1_n}] ;# MGTREFCLK1N_233 from SI5394 OUT1 via U16 + +# 161.1328125 MHz MGT reference clock (SI5394 OUT1 via U16) +#create_clock -period 6.206 -name qsfp0_mgt_refclk_0 [get_ports {qsfp0_mgt_refclk_0_p}] +#create_clock -period 6.206 -name qsfp0_mgt_refclk_1 [get_ports {qsfp0_mgt_refclk_1_p}] + +set_property -dict {LOC K4} [get_ports {qsfp1_rx_p[0]}] ;# MGTYRXP0_231 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC K3} [get_ports {qsfp1_rx_n[0]}] ;# MGTYRXN0_231 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC J7} [get_ports {qsfp1_tx_p[0]}] ;# MGTYTXP0_231 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC J6} [get_ports {qsfp1_tx_n[0]}] ;# MGTYTXN0_231 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC J2} [get_ports {qsfp1_rx_p[1]}] ;# MGTYRXP1_231 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC J1} [get_ports {qsfp1_rx_n[1]}] ;# MGTYRXN1_231 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC H5} [get_ports {qsfp1_tx_p[1]}] ;# MGTYTXP1_231 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC H4} [get_ports {qsfp1_tx_n[1]}] ;# MGTYTXN1_231 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC G2} [get_ports {qsfp1_rx_p[2]}] ;# MGTYRXP2_231 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC G1} [get_ports {qsfp1_rx_n[2]}] ;# MGTYRXN2_231 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC G7} [get_ports {qsfp1_tx_p[2]}] ;# MGTYTXP2_231 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC G6} [get_ports {qsfp1_tx_n[2]}] ;# MGTYTXN2_231 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC E2} [get_ports {qsfp1_rx_p[3]}] ;# MGTYRXP3_231 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC E1} [get_ports {qsfp1_rx_n[3]}] ;# MGTYRXN3_231 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC F5} [get_ports {qsfp1_tx_p[3]}] ;# MGTYTXP3_231 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC F4} [get_ports {qsfp1_tx_n[3]}] ;# MGTYTXN3_231 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7 +set_property -dict {LOC P9} [get_ports {qsfp1_mgt_refclk_p}] ;# MGTREFCLK0P_231 from SI5394 OUT1 via U16 +set_property -dict {LOC P8} [get_ports {qsfp1_mgt_refclk_n}] ;# MGTREFCLK0N_231 from SI5394 OUT1 via U16 + +# 161.1328125 MHz MGT reference clock (SI5394 OUT1 via U16) +create_clock -period 6.206 -name qsfp1_mgt_refclk [get_ports {qsfp1_mgt_refclk_p}] + +# PCIe Interface +set_property -dict {LOC AF4 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AF3 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AD8 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AD7 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AG2 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AG1 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AE6 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AE5 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AJ2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AJ1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AG6 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AG5 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AK4 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AK3 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AH4 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AH3 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3 +set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AJ6 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AJ5 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AM4 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AM3 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AL6 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AL5 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AN6 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AN5 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AP4 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AP3 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2 +set_property -dict {LOC AT4 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AT3 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AP8 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AP7 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AU6 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AU5 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AR6 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AR5 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AT8 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AT7 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AR10} [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AR9 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AU10} [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AU9 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AT12} [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AT11} [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1 +set_property -dict {LOC AU14} [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0 +set_property -dict {LOC AU13} [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0 +set_property -dict {LOC AR14} [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0 +set_property -dict {LOC AR13} [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0 +set_property -dict {LOC AT16} [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0 +set_property -dict {LOC AT15} [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0 +set_property -dict {LOC AR18} [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0 +set_property -dict {LOC AR17} [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0 +set_property -dict {LOC AU18} [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0 +set_property -dict {LOC AU17} [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0 +set_property -dict {LOC AT20} [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0 +set_property -dict {LOC AT19} [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0 +set_property -dict {LOC AU22} [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0 +set_property -dict {LOC AU21} [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0 +set_property -dict {LOC AR22} [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0 +set_property -dict {LOC AR21} [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0 +#set_property -dict {LOC AF8 } [get_ports {pcie_refclk_0_p}] ;# MGTREFCLK0P_227 (for x8 bifurcated lanes 0-7) +#set_property -dict {LOC AF7 } [get_ports {pcie_refclk_0_n}] ;# MGTREFCLK0N_227 (for x8 bifurcated lanes 0-7) +#set_property -dict {LOC AE10} [get_ports {pcie_refclk_2_p}] ;# MGTREFCLK1P_227 (for async x8 bifurcated lanes 0-7) +#set_property -dict {LOC AE9 } [get_ports {pcie_refclk_2_n}] ;# MGTREFCLK1N_227 (for async x8 bifurcated lanes 0-7) +set_property -dict {LOC AL10} [get_ports {pcie_refclk_1_p}] ;# MGTREFCLK0P_225 (for x16 or x8 bifurcated lanes 8-16) +set_property -dict {LOC AL9 } [get_ports {pcie_refclk_1_n}] ;# MGTREFCLK0N_225 (for x16 or x8 bifurcated lanes 8-16) +#set_property -dict {LOC AK8 } [get_ports {pcie_refclk_3_p}] ;# MGTREFCLK1P_225 (for async x16 or x8 bifurcated lanes 8-16) +#set_property -dict {LOC AK7 } [get_ports {pcie_refclk_3_n}] ;# MGTREFCLK1N_225 (for async x16 or x8 bifurcated lanes 8-16) +set_property -dict {LOC AK18 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {pcie_reset_n}] + +# 100 MHz MGT reference clock +#create_clock -period 10 -name pcie_mgt_refclk_0 [get_ports {pcie_refclk_0_p}] +create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports {pcie_refclk_1_p}] +#create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports {pcie_refclk_2_p}] +#create_clock -period 10 -name pcie_mgt_refclk_3 [get_ports {pcie_refclk_3_p}] + +set_false_path -from [get_ports {pcie_reset_n}] +set_input_delay 0 [get_ports {pcie_reset_n}] diff --git a/src/cndm/board/Alveo/fpga/rtl/fpga_au45n.sv b/src/cndm/board/Alveo/fpga/rtl/fpga_au45n.sv new file mode 100644 index 0000000..096c886 --- /dev/null +++ b/src/cndm/board/Alveo/fpga/rtl/fpga_au45n.sv @@ -0,0 +1,895 @@ +// SPDX-License-Identifier: MIT +/* + +Copyright (c) 2014-2026 FPGA Ninja, LLC + +Authors: +- Alex Forencich + +*/ + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * FPGA top-level module + */ +module fpga # +( + // simulation (set to avoid vendor primitives) + parameter logic SIM = 1'b0, + // vendor ("GENERIC", "XILINX", "ALTERA") + parameter string VENDOR = "XILINX", + // device family + parameter string FAMILY = "virtexuplus", + + // Board configuration + parameter QSFP_CNT = 2, + parameter UART_CNT = 1, + + // FW ID + parameter FPGA_ID = 32'h4AD5093, + parameter FW_ID = 32'h0000C001, + parameter FW_VER = 32'h000_01_000, + parameter BOARD_ID = 32'h10ee_902d, + parameter BOARD_VER = 32'h001_00_000, + parameter BUILD_DATE = 32'd602976000, + parameter GIT_HASH = 32'h5f87c2e8, + parameter RELEASE_INFO = 32'h00000000, + + // PTP configuration + parameter logic PTP_TS_EN = 1'b1, + + // AXI lite interface configuration (control) + parameter AXIL_CTRL_DATA_W = 32, + parameter AXIL_CTRL_ADDR_W = 24, + + // MAC configuration + parameter logic CFG_LOW_LATENCY = 1'b1, + parameter logic COMBINED_MAC_PCS = 1'b1, + parameter MAC_DATA_W = 64 +) +( + /* + * GPIO + */ + output wire logic card_heart_bit, + output wire logic card_status_led, + output wire logic [QSFP_CNT-1:0] qsfp_led_act, + output wire logic [QSFP_CNT-1:0] qsfp_led_stat_g, + output wire logic [QSFP_CNT-1:0] qsfp_led_stat_y, + + /* + * UART + */ + output wire logic uart_txd, + input wire logic uart_rxd, + + /* + * Ethernet: QSFP28 + */ + // output wire logic qsfp0_tx_p[4], + // output wire logic qsfp0_tx_n[4], + // input wire logic qsfp0_rx_p[4], + // input wire logic qsfp0_rx_n[4], + // input wire logic qsfp0_mgt_refclk_0_p, + // input wire logic qsfp0_mgt_refclk_0_n, + // input wire logic qsfp0_mgt_refclk_1_p, + // input wire logic qsfp0_mgt_refclk_1_n, + + output wire logic qsfp1_tx_p[4], + output wire logic qsfp1_tx_n[4], + input wire logic qsfp1_rx_p[4], + input wire logic qsfp1_rx_n[4], + input wire logic qsfp1_mgt_refclk_p, + input wire logic qsfp1_mgt_refclk_n, + + /* + * PCIe + */ + input wire logic [15:0] pcie_rx_p, + input wire logic [15:0] pcie_rx_n, + output wire logic [15:0] pcie_tx_p, + output wire logic [15:0] pcie_tx_n, + input wire logic pcie_refclk_1_p, + input wire logic pcie_refclk_1_n, + input wire logic pcie_reset_n +); + +// Clock and reset +wire pcie_user_clk; +wire pcie_user_rst; + +wire clk_161mhz_ref_int; + +// Internal 125 MHz clock +wire clk_125mhz_mmcm_out; +wire clk_125mhz_int; +wire rst_125mhz_int; + +wire mmcm_rst = 1'b0; +wire mmcm_locked; +wire mmcm_clkfb; + +// MMCM instance +MMCME4_BASE #( + // 161.13 MHz input + .CLKIN1_PERIOD(6.206), + .REF_JITTER1(0.010), + // 161.13 MHz input / 11 = 14.65 MHz PFD (range 10 MHz to 500 MHz) + .DIVCLK_DIVIDE(11), + // 14.65 MHz PFD * 64 = 937.5 MHz VCO (range 800 MHz to 1600 MHz) + .CLKFBOUT_MULT_F(64), + .CLKFBOUT_PHASE(0), + // 937.5 MHz / 7.5 = 125 MHz, 0 degrees + .CLKOUT0_DIVIDE_F(7.5), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0), + // Not used + .CLKOUT1_DIVIDE(1), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0), + // Not used + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(0), + // Not used + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0), + // Not used + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0), + .CLKOUT4_CASCADE("FALSE"), + // Not used + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(0), + // Not used + .CLKOUT6_DIVIDE(1), + .CLKOUT6_DUTY_CYCLE(0.5), + .CLKOUT6_PHASE(0), + + // optimized bandwidth + .BANDWIDTH("OPTIMIZED"), + // don't wait for lock during startup + .STARTUP_WAIT("FALSE") +) +clk_mmcm_inst ( + // 161.13 MHz input + .CLKIN1(clk_161mhz_ref_int), + // direct clkfb feeback + .CLKFBIN(mmcm_clkfb), + .CLKFBOUT(mmcm_clkfb), + .CLKFBOUTB(), + // 125 MHz, 0 degrees + .CLKOUT0(clk_125mhz_mmcm_out), + .CLKOUT0B(), + // Not used + .CLKOUT1(), + .CLKOUT1B(), + // Not used + .CLKOUT2(), + .CLKOUT2B(), + // Not used + .CLKOUT3(), + .CLKOUT3B(), + // Not used + .CLKOUT4(), + // Not used + .CLKOUT5(), + // Not used + .CLKOUT6(), + // reset input + .RST(mmcm_rst), + // don't power down + .PWRDWN(1'b0), + // locked output + .LOCKED(mmcm_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_mmcm_out), + .O(clk_125mhz_int) +); + +taxi_sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~mmcm_locked), + .out(rst_125mhz_int) +); + +localparam PORT_CNT = QSFP_CNT; +localparam GTY_QUAD_CNT = 1; +localparam GTY_CNT = GTY_QUAD_CNT*4; +localparam GTY_CLK_CNT = GTY_QUAD_CNT; + +wire eth_gty_tx_p[GTY_CNT]; +wire eth_gty_tx_n[GTY_CNT]; +wire eth_gty_rx_p[GTY_CNT]; +wire eth_gty_rx_n[GTY_CNT]; +wire eth_gty_mgt_refclk_p[GTY_CLK_CNT]; +wire eth_gty_mgt_refclk_n[GTY_CLK_CNT]; +wire eth_gty_mgt_refclk_out[GTY_CLK_CNT]; + +assign qsfp1_tx_p = eth_gty_tx_p[4*0 +: 4]; +assign qsfp1_tx_n = eth_gty_tx_n[4*0 +: 4]; +assign eth_gty_rx_p[4*0 +: 4] = qsfp1_rx_p; +assign eth_gty_rx_n[4*0 +: 4] = qsfp1_rx_n; + +assign eth_gty_mgt_refclk_p[0] = qsfp1_mgt_refclk_p; +assign eth_gty_mgt_refclk_n[0] = qsfp1_mgt_refclk_n; + +assign clk_161mhz_ref_int = eth_gty_mgt_refclk_out[0]; + +// Flash +wire qspi_clk_int; +wire [3:0] qspi_dq_int; +wire [3:0] qspi_dq_i_int; +wire [3:0] qspi_dq_o_int; +wire [3:0] qspi_dq_oe_int; +wire qspi_cs_int; + +reg qspi_clk_reg; +reg [3:0] qspi_dq_o_reg; +reg [3:0] qspi_dq_oe_reg; +reg qspi_cs_reg; + +always_ff @(posedge pcie_user_clk) begin + qspi_clk_reg <= qspi_clk_int; + qspi_dq_o_reg <= qspi_dq_o_int; + qspi_dq_oe_reg <= qspi_dq_oe_int; + qspi_cs_reg <= qspi_cs_int; +end + +taxi_sync_signal #( + .WIDTH(8), + .N(2) +) +flash_sync_inst ( + .clk(pcie_user_clk), + .in({qspi_dq_int}), + .out({qspi_dq_i_int}) +); + +STARTUPE3 +startupe3_inst ( + .CFGCLK(), + .CFGMCLK(), + .DI(qspi_dq_int), + .DO(qspi_dq_o_reg), + .DTS(~qspi_dq_oe_reg), + .EOS(), + .FCSBO(qspi_cs_reg), + .FCSBTS(1'b0), + .GSR(1'b0), + .GTS(1'b0), + .KEYCLEARB(1'b1), + .PACK(1'b0), + .PREQ(), + .USRCCLKO(qspi_clk_reg), + .USRCCLKTS(1'b0), + .USRDONEO(1'b0), + .USRDONETS(1'b1) +); + +// FPGA boot +wire fpga_boot; +wire fpga_boot_sync; + +taxi_sync_signal #( + .WIDTH(1), + .N(2) +) +fpga_boot_sync_inst ( + .clk(clk_125mhz_int), + .in({fpga_boot}), + .out({fpga_boot_sync}) +); + +wire icap_avail; +logic [2:0] icap_state_reg = 0; +logic icap_csib_reg = 1'b1; +logic icap_rdwrb_reg = 1'b0; +logic [31:0] icap_di_reg = 32'hffffffff; + +wire [31:0] icap_di_rev; + +assign icap_di_rev[ 7] = icap_di_reg[ 0]; +assign icap_di_rev[ 6] = icap_di_reg[ 1]; +assign icap_di_rev[ 5] = icap_di_reg[ 2]; +assign icap_di_rev[ 4] = icap_di_reg[ 3]; +assign icap_di_rev[ 3] = icap_di_reg[ 4]; +assign icap_di_rev[ 2] = icap_di_reg[ 5]; +assign icap_di_rev[ 1] = icap_di_reg[ 6]; +assign icap_di_rev[ 0] = icap_di_reg[ 7]; + +assign icap_di_rev[15] = icap_di_reg[ 8]; +assign icap_di_rev[14] = icap_di_reg[ 9]; +assign icap_di_rev[13] = icap_di_reg[10]; +assign icap_di_rev[12] = icap_di_reg[11]; +assign icap_di_rev[11] = icap_di_reg[12]; +assign icap_di_rev[10] = icap_di_reg[13]; +assign icap_di_rev[ 9] = icap_di_reg[14]; +assign icap_di_rev[ 8] = icap_di_reg[15]; + +assign icap_di_rev[23] = icap_di_reg[16]; +assign icap_di_rev[22] = icap_di_reg[17]; +assign icap_di_rev[21] = icap_di_reg[18]; +assign icap_di_rev[20] = icap_di_reg[19]; +assign icap_di_rev[19] = icap_di_reg[20]; +assign icap_di_rev[18] = icap_di_reg[21]; +assign icap_di_rev[17] = icap_di_reg[22]; +assign icap_di_rev[16] = icap_di_reg[23]; + +assign icap_di_rev[31] = icap_di_reg[24]; +assign icap_di_rev[30] = icap_di_reg[25]; +assign icap_di_rev[29] = icap_di_reg[26]; +assign icap_di_rev[28] = icap_di_reg[27]; +assign icap_di_rev[27] = icap_di_reg[28]; +assign icap_di_rev[26] = icap_di_reg[29]; +assign icap_di_rev[25] = icap_di_reg[30]; +assign icap_di_rev[24] = icap_di_reg[31]; + +always_ff @(posedge clk_125mhz_int) begin + case (icap_state_reg) + 0: begin + icap_state_reg <= 0; + icap_csib_reg <= 1'b1; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'hffffffff; // dummy word + + if (fpga_boot_sync && icap_avail) begin + icap_state_reg <= 1; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'hffffffff; // dummy word + end + end + 1: begin + icap_state_reg <= 2; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'hAA995566; // sync word + end + 2: begin + icap_state_reg <= 3; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h20000000; // type 1 noop + end + 3: begin + icap_state_reg <= 4; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h30008001; // write 1 word to CMD + end + 4: begin + icap_state_reg <= 5; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h0000000F; // IPROG + end + 5: begin + icap_state_reg <= 0; + icap_csib_reg <= 1'b0; + icap_rdwrb_reg <= 1'b0; + icap_di_reg <= 32'h20000000; // type 1 noop + end + endcase +end + +ICAPE3 +icape3_inst ( + .AVAIL(icap_avail), + .CLK(clk_125mhz_int), + .CSIB(icap_csib_reg), + .I(icap_di_rev), + .O(), + .PRDONE(), + .PRERROR(), + .RDWRB(icap_rdwrb_reg) +); + +// PCIe +localparam AXIS_PCIE_DATA_W = 512; +localparam AXIS_PCIE_KEEP_W = (AXIS_PCIE_DATA_W/32); +localparam AXIS_PCIE_RC_USER_W = AXIS_PCIE_DATA_W < 512 ? 75 : 161; +localparam AXIS_PCIE_RQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 62 : 137; +localparam AXIS_PCIE_CQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 85 : 183; +localparam AXIS_PCIE_CC_USER_W = AXIS_PCIE_DATA_W < 512 ? 33 : 81; +localparam RC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 256; +localparam RQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512; +localparam CQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512; +localparam CC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512; + +localparam RQ_SEQ_NUM_W = AXIS_PCIE_RQ_USER_W == 60 ? 4 : 6; +localparam RQ_SEQ_NUM_EN = 1; + +localparam PCIE_TAG_CNT = AXIS_PCIE_RQ_USER_W == 60 ? 64 : 256; +localparam BAR0_APERTURE = 24; + +taxi_axis_if #( + .DATA_W(AXIS_PCIE_DATA_W), + .KEEP_EN(1), + .KEEP_W(AXIS_PCIE_KEEP_W), + .USER_EN(1), + .USER_W(AXIS_PCIE_CQ_USER_W) +) axis_pcie_cq(); + +taxi_axis_if #( + .DATA_W(AXIS_PCIE_DATA_W), + .KEEP_EN(1), + .KEEP_W(AXIS_PCIE_KEEP_W), + .USER_EN(1), + .USER_W(AXIS_PCIE_CC_USER_W) +) axis_pcie_cc(); + +taxi_axis_if #( + .DATA_W(AXIS_PCIE_DATA_W), + .KEEP_EN(1), + .KEEP_W(AXIS_PCIE_KEEP_W), + .USER_EN(1), + .USER_W(AXIS_PCIE_RQ_USER_W) +) axis_pcie_rq(); + +taxi_axis_if #( + .DATA_W(AXIS_PCIE_DATA_W), + .KEEP_EN(1), + .KEEP_W(AXIS_PCIE_KEEP_W), + .USER_EN(1), + .USER_W(AXIS_PCIE_RC_USER_W) +) axis_pcie_rc(); + +wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num0; +wire pcie_rq_seq_num_vld0; +wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num1; +wire pcie_rq_seq_num_vld1; + +wire [2:0] cfg_max_payload; +wire [2:0] cfg_max_read_req; +wire [3:0] cfg_rcb_status; + +wire [9:0] cfg_mgmt_addr; +wire [7:0] cfg_mgmt_function_number; +wire cfg_mgmt_write; +wire [31:0] cfg_mgmt_write_data; +wire [3:0] cfg_mgmt_byte_enable; +wire cfg_mgmt_read; +wire [31:0] cfg_mgmt_read_data; +wire cfg_mgmt_read_write_done; + +wire [7:0] cfg_fc_ph; +wire [11:0] cfg_fc_pd; +wire [7:0] cfg_fc_nph; +wire [11:0] cfg_fc_npd; +wire [7:0] cfg_fc_cplh; +wire [11:0] cfg_fc_cpld; +wire [2:0] cfg_fc_sel; + +wire cfg_ext_read_received; +wire cfg_ext_write_received; +wire [9:0] cfg_ext_register_number; +wire [7:0] cfg_ext_function_number; +wire [31:0] cfg_ext_write_data; +wire [3:0] cfg_ext_write_byte_enable; +wire [31:0] cfg_ext_read_data; +wire cfg_ext_read_data_valid; + +// wire [3:0] cfg_interrupt_msix_enable; +// wire [3:0] cfg_interrupt_msix_mask; +// wire [251:0] cfg_interrupt_msix_vf_enable; +// wire [251:0] cfg_interrupt_msix_vf_mask; +// wire [63:0] cfg_interrupt_msix_address; +// wire [31:0] cfg_interrupt_msix_data; +// wire cfg_interrupt_msix_int; +// wire [1:0] cfg_interrupt_msix_vec_pending; +// wire cfg_interrupt_msix_vec_pending_status; +// wire cfg_interrupt_msix_sent; +// wire cfg_interrupt_msix_fail; +// wire [7:0] cfg_interrupt_msi_function_number; + +wire [3:0] cfg_interrupt_msi_enable; +wire [11:0] cfg_interrupt_msi_mmenable; +wire cfg_interrupt_msi_mask_update; +wire [31:0] cfg_interrupt_msi_data; +wire [1:0] cfg_interrupt_msi_select; +wire [31:0] cfg_interrupt_msi_int; +wire [31:0] cfg_interrupt_msi_pending_status; +wire cfg_interrupt_msi_pending_status_data_enable; +wire [1:0] cfg_interrupt_msi_pending_status_function_num; +wire cfg_interrupt_msi_sent; +wire cfg_interrupt_msi_fail; +wire [2:0] cfg_interrupt_msi_attr; +wire cfg_interrupt_msi_tph_present; +wire [1:0] cfg_interrupt_msi_tph_type; +wire [7:0] cfg_interrupt_msi_tph_st_tag; +wire [7:0] cfg_interrupt_msi_function_number; + +wire stat_err_cor; +wire stat_err_uncor; + +wire pcie_sys_clk; +wire pcie_sys_clk_gt; + +IBUFDS_GTE4 #( + .REFCLK_HROW_CK_SEL(2'b00) +) +ibufds_gte4_pcie_refclk_inst ( + .I (pcie_refclk_1_p), + .IB (pcie_refclk_1_n), + .CEB (1'b0), + .O (pcie_sys_clk_gt), + .ODIV2 (pcie_sys_clk) +); + +pcie4c_uscale_plus_0 +pcie4c_uscale_plus_inst ( + .pci_exp_txn(pcie_tx_n), + .pci_exp_txp(pcie_tx_p), + .pci_exp_rxn(pcie_rx_n), + .pci_exp_rxp(pcie_rx_p), + .user_clk(pcie_user_clk), + .user_reset(pcie_user_rst), + .user_lnk_up(), + + .s_axis_rq_tdata(axis_pcie_rq.tdata), + .s_axis_rq_tkeep(axis_pcie_rq.tkeep), + .s_axis_rq_tlast(axis_pcie_rq.tlast), + .s_axis_rq_tready(axis_pcie_rq.tready), + .s_axis_rq_tuser(axis_pcie_rq.tuser), + .s_axis_rq_tvalid(axis_pcie_rq.tvalid), + + .m_axis_rc_tdata(axis_pcie_rc.tdata), + .m_axis_rc_tkeep(axis_pcie_rc.tkeep), + .m_axis_rc_tlast(axis_pcie_rc.tlast), + .m_axis_rc_tready(axis_pcie_rc.tready), + .m_axis_rc_tuser(axis_pcie_rc.tuser), + .m_axis_rc_tvalid(axis_pcie_rc.tvalid), + + .m_axis_cq_tdata(axis_pcie_cq.tdata), + .m_axis_cq_tkeep(axis_pcie_cq.tkeep), + .m_axis_cq_tlast(axis_pcie_cq.tlast), + .m_axis_cq_tready(axis_pcie_cq.tready), + .m_axis_cq_tuser(axis_pcie_cq.tuser), + .m_axis_cq_tvalid(axis_pcie_cq.tvalid), + + .s_axis_cc_tdata(axis_pcie_cc.tdata), + .s_axis_cc_tkeep(axis_pcie_cc.tkeep), + .s_axis_cc_tlast(axis_pcie_cc.tlast), + .s_axis_cc_tready(axis_pcie_cc.tready), + .s_axis_cc_tuser(axis_pcie_cc.tuser), + .s_axis_cc_tvalid(axis_pcie_cc.tvalid), + + .pcie_rq_seq_num0(pcie_rq_seq_num0), + .pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0), + .pcie_rq_seq_num1(pcie_rq_seq_num1), + .pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1), + .pcie_rq_tag0(), + .pcie_rq_tag1(), + .pcie_rq_tag_av(), + .pcie_rq_tag_vld0(), + .pcie_rq_tag_vld1(), + + .pcie_tfc_nph_av(), + .pcie_tfc_npd_av(), + + .pcie_cq_np_req(1'b1), + .pcie_cq_np_req_count(), + + .cfg_phy_link_down(), + .cfg_phy_link_status(), + .cfg_negotiated_width(), + .cfg_current_speed(), + .cfg_max_payload(cfg_max_payload), + .cfg_max_read_req(cfg_max_read_req), + .cfg_function_status(), + .cfg_function_power_state(), + .cfg_vf_status(), + .cfg_vf_power_state(), + .cfg_link_power_state(), + + .cfg_mgmt_addr(cfg_mgmt_addr), + .cfg_mgmt_function_number(cfg_mgmt_function_number), + .cfg_mgmt_write(cfg_mgmt_write), + .cfg_mgmt_write_data(cfg_mgmt_write_data), + .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), + .cfg_mgmt_read(cfg_mgmt_read), + .cfg_mgmt_read_data(cfg_mgmt_read_data), + .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), + .cfg_mgmt_debug_access(1'b0), + + .cfg_err_cor_out(), + .cfg_err_nonfatal_out(), + .cfg_err_fatal_out(), + .cfg_local_error_valid(), + .cfg_local_error_out(), + .cfg_ltssm_state(), + .cfg_rx_pm_state(), + .cfg_tx_pm_state(), + .cfg_rcb_status(cfg_rcb_status), + .cfg_obff_enable(), + .cfg_pl_status_change(), + .cfg_tph_requester_enable(), + .cfg_tph_st_mode(), + .cfg_vf_tph_requester_enable(), + .cfg_vf_tph_st_mode(), + + .cfg_msg_received(), + .cfg_msg_received_data(), + .cfg_msg_received_type(), + .cfg_msg_transmit(1'b0), + .cfg_msg_transmit_type(3'd0), + .cfg_msg_transmit_data(32'd0), + .cfg_msg_transmit_done(), + + .cfg_fc_ph(cfg_fc_ph), + .cfg_fc_pd(cfg_fc_pd), + .cfg_fc_nph(cfg_fc_nph), + .cfg_fc_npd(cfg_fc_npd), + .cfg_fc_cplh(cfg_fc_cplh), + .cfg_fc_cpld(cfg_fc_cpld), + .cfg_fc_sel(cfg_fc_sel), + + .cfg_dsn(64'd0), + + .cfg_bus_number(), + + .cfg_power_state_change_ack(1'b1), + .cfg_power_state_change_interrupt(), + + .cfg_err_cor_in(stat_err_cor), + .cfg_err_uncor_in(stat_err_uncor), + .cfg_flr_in_process(), + .cfg_flr_done(4'd0), + .cfg_vf_flr_in_process(), + .cfg_vf_flr_func_num(8'd0), + .cfg_vf_flr_done(8'd0), + + .cfg_link_training_enable(1'b1), + + .cfg_ext_read_received(cfg_ext_read_received), + .cfg_ext_write_received(cfg_ext_write_received), + .cfg_ext_register_number(cfg_ext_register_number), + .cfg_ext_function_number(cfg_ext_function_number), + .cfg_ext_write_data(cfg_ext_write_data), + .cfg_ext_write_byte_enable(cfg_ext_write_byte_enable), + .cfg_ext_read_data(cfg_ext_read_data), + .cfg_ext_read_data_valid(cfg_ext_read_data_valid), + + .cfg_interrupt_int(4'd0), + .cfg_interrupt_pending(4'd0), + .cfg_interrupt_sent(), + // .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable), + // .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask), + // .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable), + // .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask), + // .cfg_interrupt_msix_address(cfg_interrupt_msix_address), + // .cfg_interrupt_msix_data(cfg_interrupt_msix_data), + // .cfg_interrupt_msix_int(cfg_interrupt_msix_int), + // .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending), + // .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status), + // .cfg_interrupt_msi_sent(cfg_interrupt_msix_sent), + // .cfg_interrupt_msi_fail(cfg_interrupt_msix_fail), + // .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), + .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), + .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), + .cfg_interrupt_msi_data(cfg_interrupt_msi_data), + .cfg_interrupt_msi_select(cfg_interrupt_msi_select), + .cfg_interrupt_msi_int(cfg_interrupt_msi_int), + .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), + .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), + .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), + .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), + .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), + .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), + .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), + .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), + .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), + .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + .cfg_pm_aspm_l1_entry_reject(1'b0), + .cfg_pm_aspm_tx_l0s_entry_disable(1'b0), + + .cfg_hot_reset_out(), + + .cfg_config_space_enable(1'b1), + .cfg_req_pm_transition_l23_ready(1'b0), + .cfg_hot_reset_in(1'b0), + + .cfg_ds_port_number(8'd0), + .cfg_ds_bus_number(8'd0), + .cfg_ds_device_number(5'd0), + + .sys_clk(pcie_sys_clk), + .sys_clk_gt(pcie_sys_clk_gt), + .sys_reset(pcie_reset_n), + + .phy_rdy_out() +); + +wire uart_rxd_int[1]; +wire uart_txd_int[1]; + +assign uart_txd = uart_txd_int[0]; +assign uart_rxd_int[0] = uart_rxd; + +fpga_core #( + .SIM(SIM), + .VENDOR(VENDOR), + .FAMILY(FAMILY), + + // Board configuration + .SW_CNT(4), + .LED_CNT(2), + .UART_CNT(UART_CNT), + .PORT_CNT(PORT_CNT), + .GTY_QUAD_CNT(GTY_QUAD_CNT), + .GTY_CNT(GTY_CNT), + .GTY_CLK_CNT(GTY_CLK_CNT), + + // FW ID + .FPGA_ID(FPGA_ID), + .FW_ID(FW_ID), + .FW_VER(FW_VER), + .BOARD_ID(BOARD_ID), + .BOARD_VER(BOARD_VER), + .BUILD_DATE(BUILD_DATE), + .GIT_HASH(GIT_HASH), + .RELEASE_INFO(RELEASE_INFO), + + // PTP configuration + .PTP_TS_EN(PTP_TS_EN), + .PTP_CLK_PER_NS_NUM(1024), + .PTP_CLK_PER_NS_DENOM(165), + + // PCIe interface configuration + .RQ_SEQ_NUM_W(RQ_SEQ_NUM_W), + + // AXI lite interface configuration (control) + .AXIL_CTRL_DATA_W(AXIL_CTRL_DATA_W), + .AXIL_CTRL_ADDR_W(AXIL_CTRL_ADDR_W), + + // MAC configuration + .CFG_LOW_LATENCY(CFG_LOW_LATENCY), + .COMBINED_MAC_PCS(COMBINED_MAC_PCS), + .MAC_DATA_W(MAC_DATA_W) +) +core_inst ( + /* + * Clock: 125MHz + * Synchronous reset + */ + .clk_125mhz(clk_125mhz_int), + .rst_125mhz(rst_125mhz_int), + + /* + * GPIO + */ + .sw('0), + .led({card_heart_bit, card_status_led}), + .port_led_act(qsfp_led_act), + .port_led_stat_r(), + .port_led_stat_g(qsfp_led_stat_g), + .port_led_stat_b(), + .port_led_stat_y(qsfp_led_stat_y), + + /* + * UART + */ + .uart_txd(uart_txd_int), + .uart_rxd(uart_rxd_int), + + /* + * Ethernet + */ + .eth_gty_tx_p(eth_gty_tx_p), + .eth_gty_tx_n(eth_gty_tx_n), + .eth_gty_rx_p(eth_gty_rx_p), + .eth_gty_rx_n(eth_gty_rx_n), + .eth_gty_mgt_refclk_p(eth_gty_mgt_refclk_p), + .eth_gty_mgt_refclk_n(eth_gty_mgt_refclk_n), + .eth_gty_mgt_refclk_out(eth_gty_mgt_refclk_out), + + .eth_port_modsell(), + .eth_port_resetl(), + .eth_port_modprsl('0), + .eth_port_intl('0), + .eth_port_lpmode(), + + /* + * PCIe + */ + .pcie_clk(pcie_user_clk), + .pcie_rst(pcie_user_rst), + .s_axis_pcie_cq(axis_pcie_cq), + .m_axis_pcie_cc(axis_pcie_cc), + .m_axis_pcie_rq(axis_pcie_rq), + .s_axis_pcie_rc(axis_pcie_rc), + + .pcie_rq_seq_num0(pcie_rq_seq_num0), + .pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0), + .pcie_rq_seq_num1(pcie_rq_seq_num1), + .pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1), + + .cfg_max_payload(cfg_max_payload), + .cfg_max_read_req(cfg_max_read_req), + .cfg_rcb_status(cfg_rcb_status), + + .cfg_mgmt_addr(cfg_mgmt_addr), + .cfg_mgmt_function_number(cfg_mgmt_function_number), + .cfg_mgmt_write(cfg_mgmt_write), + .cfg_mgmt_write_data(cfg_mgmt_write_data), + .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), + .cfg_mgmt_read(cfg_mgmt_read), + .cfg_mgmt_read_data(cfg_mgmt_read_data), + .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), + + .cfg_fc_ph(cfg_fc_ph), + .cfg_fc_pd(cfg_fc_pd), + .cfg_fc_nph(cfg_fc_nph), + .cfg_fc_npd(cfg_fc_npd), + .cfg_fc_cplh(cfg_fc_cplh), + .cfg_fc_cpld(cfg_fc_cpld), + .cfg_fc_sel(cfg_fc_sel), + + .cfg_ext_read_received(cfg_ext_read_received), + .cfg_ext_write_received(cfg_ext_write_received), + .cfg_ext_register_number(cfg_ext_register_number), + .cfg_ext_function_number(cfg_ext_function_number), + .cfg_ext_write_data(cfg_ext_write_data), + .cfg_ext_write_byte_enable(cfg_ext_write_byte_enable), + .cfg_ext_read_data(cfg_ext_read_data), + .cfg_ext_read_data_valid(cfg_ext_read_data_valid), + + // .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable), + // .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask), + // .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable), + // .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask), + // .cfg_interrupt_msix_address(cfg_interrupt_msix_address), + // .cfg_interrupt_msix_data(cfg_interrupt_msix_data), + // .cfg_interrupt_msix_int(cfg_interrupt_msix_int), + // .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending), + // .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status), + // .cfg_interrupt_msix_sent(cfg_interrupt_msix_sent), + // .cfg_interrupt_msix_fail(cfg_interrupt_msix_fail), + // .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), + .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), + .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), + .cfg_interrupt_msi_data(cfg_interrupt_msi_data), + .cfg_interrupt_msi_select(cfg_interrupt_msi_select), + .cfg_interrupt_msi_int(cfg_interrupt_msi_int), + .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), + .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), + .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), + .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), + .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), + .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), + .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), + .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), + .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), + .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), + + /* + * QSPI flash + */ + .fpga_boot(fpga_boot), + .qspi_clk(qspi_clk_int), + .qspi_dq_i(qspi_dq_i_int), + .qspi_dq_o(qspi_dq_o_int), + .qspi_dq_oe(qspi_dq_oe_int), + .qspi_cs(qspi_cs_int) +); + +endmodule + +`resetall