aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/top/n3xx/dboards/mg
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/top/n3xx/dboards/mg')
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/Makefile.srcs34
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/cpld/Makefile22
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/cpld/PkgMgCpld.vhd424
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/cpld/PkgSetup.vhd259
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/cpld/Timing.sdc160
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/cpld/TopCpld.qpf31
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/cpld/TopCpld.qsf313
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/cpld/TopCpld.vhd1228
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/db0_pins.xdc156
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/db1_pins.xdc156
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/db_ifc/ClockingRegs.vhd345
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/db_ifc/DaughterboardRegs.vhd116
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/db_ifc/DbCore.vhd562
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/db_ifc/Jesd204bXcvrCore.edfbin0 -> 216640 bytes
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/db_ifc/Jesd204bXcvrCore_stub.vhd56
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgClockingRegMap.vhd107
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgDaughterboardRegMap.vhd56
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgJesdConfig.vhd234
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgMgPersonality.vhd61
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/db_ifc/RadioClocking.vhd304
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/db_timing.xdc347
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/doc/CPLD.md2
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/doc/mg_timing.xlsxbin0 -> 525021 bytes
-rw-r--r--fpga/usrp3/top/n3xx/dboards/mg/n3xx.v3915
24 files changed, 8888 insertions, 0 deletions
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/Makefile.srcs b/fpga/usrp3/top/n3xx/dboards/mg/Makefile.srcs
new file mode 100644
index 000000000..85bb60752
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/Makefile.srcs
@@ -0,0 +1,34 @@
+#
+# Copyright 2017 Ettus Research LLC
+#
+
+##################################################
+# DB IFC Sources
+##################################################
+MAGNESIUM_DB_SRCS = $(abspath $(addprefix $(BASE_DIR)/n3xx/dboards/mg/db_ifc/, \
+DbCore.vhd \
+DaughterboardRegs.vhd \
+ClockingRegs.vhd \
+PkgMgPersonality.vhd \
+PkgDaughterboardRegMap.vhd \
+PkgClockingRegMap.vhd \
+PkgJesdConfig.vhd \
+RadioClocking.vhd \
+Jesd204bXcvrCore.edf \
+))
+
+MAGNESIUM_TOP_SRCS = $(abspath $(addprefix $(BASE_DIR)/n3xx/dboards/mg/, \
+n3xx.v \
+))
+
+MAGNESIUM_DB_TIMING_XDC = $(abspath $(addprefix $(BASE_DIR)/n3xx/dboards/mg/, \
+db_timing.xdc \
+))
+
+MAGNESIUM_DB0_XDC = $(abspath $(addprefix $(BASE_DIR)/n3xx/dboards/mg/, \
+db0_pins.xdc \
+))
+
+MAGNESIUM_DB1_XDC = $(abspath $(addprefix $(BASE_DIR)/n3xx/dboards/mg/, \
+db1_pins.xdc \
+))
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/cpld/Makefile b/fpga/usrp3/top/n3xx/dboards/mg/cpld/Makefile
new file mode 100644
index 000000000..3fbb7d3bb
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/cpld/Makefile
@@ -0,0 +1,22 @@
+#
+# Copyright 2018 Ettus Research, a National Instruments Company
+#
+
+.PHONY: all clean
+
+SRCS=TopCpld.qpf TopCpld.qsf Timing.sdc PkgMgCpld.vhd PkgSetup.vhd TopCpld.vhd
+
+all: output_files/TopCpld.svf
+
+cpld-magnesium-revc.svf: output_files/TopCpld.pof
+ quartus_cpf --convert --frequency 10.0MHz --voltage 3.3 --operation p $? $@
+
+output_files/TopCpld.pof: $(SRCS)
+ quartus_map TopCpld
+ quartus_fit TopCpld
+ quartus_asm TopCpld
+ quartus_sta TopCpld
+
+clean:
+ rm -rf db incremental_db output_files simulation cpld-magnesium-revc.svf
+
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/cpld/PkgMgCpld.vhd b/fpga/usrp3/top/n3xx/dboards/mg/cpld/PkgMgCpld.vhd
new file mode 100644
index 000000000..327183bea
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/cpld/PkgMgCpld.vhd
@@ -0,0 +1,424 @@
+-------------------------------------------------------------------------------
+--
+-- File: PkgMgCpld.vhd
+-- Author: Autogenerated by XmlParse
+-- Original Project: --
+-- Date: --
+--
+-------------------------------------------------------------------------------
+-- Copyright 2016-2017 Ettus Research, A National Instruments Company
+-- SPDX-License-Identifier: GPL-3.0
+-------------------------------------------------------------------------------
+--
+-- Purpose:
+-- The constants in this file are autogenerated by XmlParse and should
+-- be used by testbench code to access specific register fields.
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+package PkgMgCpld is
+
+--===============================================================================
+-- A numerically ordered list of registers and their VHDL source files
+--===============================================================================
+
+ -- SignatureReg : 0x0 (TopCpld.vhd)
+ -- MinorRevReg : 0x1 (TopCpld.vhd)
+ -- MajorRevReg : 0x2 (TopCpld.vhd)
+ -- BuildCodeLSB : 0x3 (TopCpld.vhd)
+ -- BuildCodeMSB : 0x4 (TopCpld.vhd)
+ -- Scratch : 0x5 (TopCpld.vhd)
+ -- CpldControl : 0x10 (TopCpld.vhd)
+ -- LmkControl : 0x11 (TopCpld.vhd)
+ -- LoStatus : 0x12 (TopCpld.vhd)
+ -- MykonosControl : 0x13 (TopCpld.vhd)
+ -- PlScratch : 0x40 (TopCpld.vhd)
+ -- PlCpldControl : 0x41 (TopCpld.vhd)
+ -- TxCh1_Idle : 0x50 (TopCpld.vhd)
+ -- RxCh1_0_Idle : 0x51 (TopCpld.vhd)
+ -- RxCh1_1_Idle : 0x52 (TopCpld.vhd)
+ -- TxCh1_TxOn : 0x53 (TopCpld.vhd)
+ -- RxCh1_0_RxOn : 0x54 (TopCpld.vhd)
+ -- RxCh1_1_RxOn : 0x55 (TopCpld.vhd)
+ -- TxCh2_Idle : 0x60 (TopCpld.vhd)
+ -- RxCh2_0_Idle : 0x61 (TopCpld.vhd)
+ -- RxCh2_1_Idle : 0x62 (TopCpld.vhd)
+ -- TxCh2_TxOn : 0x63 (TopCpld.vhd)
+ -- RxCh2_0_RxOn : 0x64 (TopCpld.vhd)
+ -- RxCh2_1_RxOn : 0x65 (TopCpld.vhd)
+
+--===============================================================================
+-- RegTypes
+--===============================================================================
+
+--===============================================================================
+-- Register Group PsSpi_CpldRegisters
+--===============================================================================
+
+ -- SignatureReg Register (from TopCpld.vhd)
+ constant kSignatureReg : integer := 16#0#; -- Register Offset
+ constant kSignatureRegSize: integer := 16; -- register width in bits
+ constant kSignatureRegMask : std_logic_vector(15 downto 0) := X"ffff";
+ constant kProductSignatureSize : integer := 16; --SignatureReg:ProductSignature
+ constant kProductSignatureMsb : integer := 15; --SignatureReg:ProductSignature
+ constant kProductSignature : integer := 0; --SignatureReg:ProductSignature
+
+ -- MinorRevReg Register (from TopCpld.vhd)
+ constant kMinorRevReg : integer := 16#1#; -- Register Offset
+ constant kMinorRevRegSize: integer := 16; -- register width in bits
+ constant kMinorRevRegMask : std_logic_vector(15 downto 0) := X"ffff";
+ constant kCpldMinorRevisionSize : integer := 16; --MinorRevReg:CpldMinorRevision
+ constant kCpldMinorRevisionMsb : integer := 15; --MinorRevReg:CpldMinorRevision
+ constant kCpldMinorRevision : integer := 0; --MinorRevReg:CpldMinorRevision
+
+ -- MajorRevReg Register (from TopCpld.vhd)
+ constant kMajorRevReg : integer := 16#2#; -- Register Offset
+ constant kMajorRevRegSize: integer := 16; -- register width in bits
+ constant kMajorRevRegMask : std_logic_vector(15 downto 0) := X"ffff";
+ constant kCpldMajorRevisionSize : integer := 16; --MajorRevReg:CpldMajorRevision
+ constant kCpldMajorRevisionMsb : integer := 15; --MajorRevReg:CpldMajorRevision
+ constant kCpldMajorRevision : integer := 0; --MajorRevReg:CpldMajorRevision
+
+ -- BuildCodeLSB Register (from TopCpld.vhd)
+ constant kBuildCodeLSB : integer := 16#3#; -- Register Offset
+ constant kBuildCodeLSBSize: integer := 16; -- register width in bits
+ constant kBuildCodeLSBMask : std_logic_vector(15 downto 0) := X"ffff";
+ constant kBuildCodeHHSize : integer := 8; --BuildCodeLSB:BuildCodeHH
+ constant kBuildCodeHHMsb : integer := 7; --BuildCodeLSB:BuildCodeHH
+ constant kBuildCodeHH : integer := 0; --BuildCodeLSB:BuildCodeHH
+ constant kBuildCodeDDSize : integer := 8; --BuildCodeLSB:BuildCodeDD
+ constant kBuildCodeDDMsb : integer := 15; --BuildCodeLSB:BuildCodeDD
+ constant kBuildCodeDD : integer := 8; --BuildCodeLSB:BuildCodeDD
+
+ -- BuildCodeMSB Register (from TopCpld.vhd)
+ constant kBuildCodeMSB : integer := 16#4#; -- Register Offset
+ constant kBuildCodeMSBSize: integer := 16; -- register width in bits
+ constant kBuildCodeMSBMask : std_logic_vector(15 downto 0) := X"ffff";
+ constant kBuildCodeMMSize : integer := 8; --BuildCodeMSB:BuildCodeMM
+ constant kBuildCodeMMMsb : integer := 7; --BuildCodeMSB:BuildCodeMM
+ constant kBuildCodeMM : integer := 0; --BuildCodeMSB:BuildCodeMM
+ constant kBuildCodeYYSize : integer := 8; --BuildCodeMSB:BuildCodeYY
+ constant kBuildCodeYYMsb : integer := 15; --BuildCodeMSB:BuildCodeYY
+ constant kBuildCodeYY : integer := 8; --BuildCodeMSB:BuildCodeYY
+
+ -- Scratch Register (from TopCpld.vhd)
+ constant kScratch : integer := 16#5#; -- Register Offset
+ constant kScratchSize: integer := 16; -- register width in bits
+ constant kScratchMask : std_logic_vector(15 downto 0) := X"ffff";
+ constant kScratchValSize : integer := 16; --Scratch:ScratchVal
+ constant kScratchValMsb : integer := 15; --Scratch:ScratchVal
+ constant kScratchVal : integer := 0; --Scratch:ScratchVal
+
+ -- CpldControl Register (from TopCpld.vhd)
+ constant kCpldControl : integer := 16#10#; -- Register Offset
+ constant kCpldControlSize: integer := 16; -- register width in bits
+ constant kCpldControlMask : std_logic_vector(15 downto 0) := X"0001";
+ constant kCpldResetSize : integer := 1; --CpldControl:CpldReset
+ constant kCpldResetMsb : integer := 0; --CpldControl:CpldReset
+ constant kCpldReset : integer := 0; --CpldControl:CpldReset
+
+ -- LmkControl Register (from TopCpld.vhd)
+ constant kLmkControl : integer := 16#11#; -- Register Offset
+ constant kLmkControlSize: integer := 16; -- register width in bits
+ constant kLmkControlMask : std_logic_vector(15 downto 0) := X"0010";
+ constant kVcxoControlSize : integer := 1; --LmkControl:VcxoControl
+ constant kVcxoControlMsb : integer := 4; --LmkControl:VcxoControl
+ constant kVcxoControl : integer := 4; --LmkControl:VcxoControl
+
+ -- LoStatus Register (from TopCpld.vhd)
+ constant kLoStatus : integer := 16#12#; -- Register Offset
+ constant kLoStatusSize: integer := 16; -- register width in bits
+ constant kLoStatusMask : std_logic_vector(15 downto 0) := X"0011";
+ constant kRxLoLockDetectSize : integer := 1; --LoStatus:RxLoLockDetect
+ constant kRxLoLockDetectMsb : integer := 0; --LoStatus:RxLoLockDetect
+ constant kRxLoLockDetect : integer := 0; --LoStatus:RxLoLockDetect
+ constant kTxLoLockDetectSize : integer := 1; --LoStatus:TxLoLockDetect
+ constant kTxLoLockDetectMsb : integer := 4; --LoStatus:TxLoLockDetect
+ constant kTxLoLockDetect : integer := 4; --LoStatus:TxLoLockDetect
+
+ -- MykonosControl Register (from TopCpld.vhd)
+ constant kMykonosControl : integer := 16#13#; -- Register Offset
+ constant kMykonosControlSize: integer := 16; -- register width in bits
+ constant kMykonosControlMask : std_logic_vector(15 downto 0) := X"0001";
+ constant kMykonosResetSize : integer := 1; --MykonosControl:MykonosReset
+ constant kMykonosResetMsb : integer := 0; --MykonosControl:MykonosReset
+ constant kMykonosReset : integer := 0; --MykonosControl:MykonosReset
+
+--===============================================================================
+-- Register Group PlSpi_FrontEndControl
+--===============================================================================
+
+ -- Enumerated type Rx1Switch1
+ constant kRx1Switch1Size : integer := 4;
+ constant kTxRxInput : integer := 0; -- Rx1Switch1:TxRxInput
+ constant kRxLoCalInput : integer := 1; -- Rx1Switch1:RxLoCalInput
+ constant kTrxSwitchOutput : integer := 2; -- Rx1Switch1:TrxSwitchOutput
+ constant kRx2Input : integer := 3; -- Rx1Switch1:Rx2Input
+
+ -- Enumerated type Rx1Switch2
+ constant kRx1Switch2Size : integer := 4;
+ constant kShutdownSw2 : integer := 0; -- Rx1Switch2:ShutdownSw2
+ constant kLowerFilterBankToSwitch3 : integer := 1; -- Rx1Switch2:LowerFilterBankToSwitch3
+ constant kBypassPathToSwitch6 : integer := 2; -- Rx1Switch2:BypassPathToSwitch6
+ constant kUpperFilterBankToSwitch4 : integer := 3; -- Rx1Switch2:UpperFilterBankToSwitch4
+
+ -- Enumerated type Rx1Switch3
+ constant kRx1Switch3Size : integer := 7;
+ constant kFilter2100x2850MHz : integer := 0; -- Rx1Switch3:Filter2100x2850MHz
+ constant kFilter0490LpMHz : integer := 1; -- Rx1Switch3:Filter0490LpMHz
+ constant kFilter1600x2250MHz : integer := 2; -- Rx1Switch3:Filter1600x2250MHz
+ constant kFilter0440x0530MHz : integer := 4; -- Rx1Switch3:Filter0440x0530MHz
+ constant kFilter0650x1000MHz : integer := 5; -- Rx1Switch3:Filter0650x1000MHz
+ constant kFilter1100x1575MHz : integer := 6; -- Rx1Switch3:Filter1100x1575MHz
+ constant kShutdownSw3 : integer := 7; -- Rx1Switch3:ShutdownSw3
+
+ -- Enumerated type Rx1Switch4
+ constant kRx1Switch4Size : integer := 3;
+ constant kFilter2100x2850MHzFrom : integer := 1; -- Rx1Switch4:Filter2100x2850MHzFrom
+ constant kFilter1600x2250MHzFrom : integer := 2; -- Rx1Switch4:Filter1600x2250MHzFrom
+ constant kFilter2700HpMHz : integer := 4; -- Rx1Switch4:Filter2700HpMHz
+
+ -- Enumerated type Rx1Switch5
+ constant kRx1Switch5Size : integer := 4;
+ constant kFilter0440x0530MHzFrom : integer := 1; -- Rx1Switch5:Filter0440x0530MHzFrom
+ constant kFilter1100x1575MHzFrom : integer := 2; -- Rx1Switch5:Filter1100x1575MHzFrom
+ constant kFilter0490LpMHzFrom : integer := 4; -- Rx1Switch5:Filter0490LpMHzFrom
+ constant kFilter0650x1000MHzFrom : integer := 8; -- Rx1Switch5:Filter0650x1000MHzFrom
+
+ -- Enumerated type Rx1Switch6
+ constant kRx1Switch6Size : integer := 3;
+ constant kLowerFilterBankFromSwitch5 : integer := 1; -- Rx1Switch6:LowerFilterBankFromSwitch5
+ constant kUpperFilterBankFromSwitch4 : integer := 2; -- Rx1Switch6:UpperFilterBankFromSwitch4
+ constant kBypassPathFromSwitch2 : integer := 4; -- Rx1Switch6:BypassPathFromSwitch2
+
+ -- Enumerated type TrxSwitch
+ constant kTrxSwitchSize : integer := 4;
+ constant kFromLowerFilterBankTxSw1 : integer := 0; -- TrxSwitch:FromLowerFilterBankTxSw1
+ constant kFromTxUpperFilterBankLp6400MHz : integer := 1; -- TrxSwitch:FromTxUpperFilterBankLp6400MHz
+ constant kRxChannelPath : integer := 2; -- TrxSwitch:RxChannelPath
+ constant kBypassPathToTxSw3 : integer := 3; -- TrxSwitch:BypassPathToTxSw3
+
+ -- Enumerated type TxSwitch1
+ constant kTxSwitch1Size : integer := 4;
+ constant kShutdownTxSw1 : integer := 0; -- TxSwitch1:ShutdownTxSw1
+ constant kFromTxFilterLp1700MHz : integer := 1; -- TxSwitch1:FromTxFilterLp1700MHz
+ constant kFromTxFilterLp3400MHz : integer := 2; -- TxSwitch1:FromTxFilterLp3400MHz
+ constant kFromTxFilterLp0800MHz : integer := 3; -- TxSwitch1:FromTxFilterLp0800MHz
+
+ -- Enumerated type TxSwitch2
+ constant kTxSwitch2Size : integer := 4;
+ constant kToTxFilterLp3400MHz : integer := 1; -- TxSwitch2:ToTxFilterLp3400MHz
+ constant kToTxFilterLp1700MHz : integer := 2; -- TxSwitch2:ToTxFilterLp1700MHz
+ constant kToTxFilterLp0800MHz : integer := 4; -- TxSwitch2:ToTxFilterLp0800MHz
+ constant kToTxFilterLp6400MHz : integer := 8; -- TxSwitch2:ToTxFilterLp6400MHz
+
+ -- Enumerated type TxSwitch3
+ constant kTxSwitch3Size : integer := 2;
+ constant kToTxFilterBanks : integer := 0; -- TxSwitch3:ToTxFilterBanks
+ constant kBypassPathToTrxSw : integer := 1; -- TxSwitch3:BypassPathToTrxSw
+
+ -- PlScratch Register (from TopCpld.vhd)
+ constant kPlScratch : integer := 16#40#; -- Register Offset
+ constant kPlScratchSize: integer := 16; -- register width in bits
+ constant kPlScratchMask : std_logic_vector(15 downto 0) := X"ffff";
+ constant kPlScratchValSize : integer := 16; --PlScratch:PlScratchVal
+ constant kPlScratchValMsb : integer := 15; --PlScratch:PlScratchVal
+ constant kPlScratchVal : integer := 0; --PlScratch:PlScratchVal
+
+ -- PlCpldControl Register (from TopCpld.vhd)
+ constant kPlCpldControl : integer := 16#41#; -- Register Offset
+ constant kPlCpldControlSize: integer := 16; -- register width in bits
+ constant kPlCpldControlMask : std_logic_vector(15 downto 0) := X"0001";
+ constant kPlCpldResetSize : integer := 1; --PlCpldControl:PlCpldReset
+ constant kPlCpldResetMsb : integer := 0; --PlCpldControl:PlCpldReset
+ constant kPlCpldReset : integer := 0; --PlCpldControl:PlCpldReset
+
+ -- TxCh1_Idle Register (from TopCpld.vhd)
+ constant kTxCh1_Idle : integer := 16#50#; -- Register Offset
+ constant kTxCh1_IdleSize: integer := 16; -- register width in bits
+ constant kTxCh1_IdleMask : std_logic_vector(15 downto 0) := X"7fff";
+ constant kCh1TxSw1Size : integer := 2; --TxCh1_Idle:Ch1TxSw1
+ constant kCh1TxSw1Msb : integer := 1; --TxCh1_Idle:Ch1TxSw1
+ constant kCh1TxSw1 : integer := 0; --TxCh1_Idle:Ch1TxSw1
+ constant kCh1TxSw2Size : integer := 4; --TxCh1_Idle:Ch1TxSw2
+ constant kCh1TxSw2Msb : integer := 5; --TxCh1_Idle:Ch1TxSw2
+ constant kCh1TxSw2 : integer := 2; --TxCh1_Idle:Ch1TxSw2
+ constant kCh1TxSw3Size : integer := 1; --TxCh1_Idle:Ch1TxSw3
+ constant kCh1TxSw3Msb : integer := 6; --TxCh1_Idle:Ch1TxSw3
+ constant kCh1TxSw3 : integer := 6; --TxCh1_Idle:Ch1TxSw3
+ constant kCh1TxLowbandMixerPathSelectSize : integer := 1; --TxCh1_Idle:Ch1TxLowbandMixerPathSelect
+ constant kCh1TxLowbandMixerPathSelectMsb : integer := 7; --TxCh1_Idle:Ch1TxLowbandMixerPathSelect
+ constant kCh1TxLowbandMixerPathSelect : integer := 7; --TxCh1_Idle:Ch1TxLowbandMixerPathSelect
+ constant kCh1TxMixerEnSize : integer := 1; --TxCh1_Idle:Ch1TxMixerEn
+ constant kCh1TxMixerEnMsb : integer := 8; --TxCh1_Idle:Ch1TxMixerEn
+ constant kCh1TxMixerEn : integer := 8; --TxCh1_Idle:Ch1TxMixerEn
+ constant kCh1TxAmpEnSize : integer := 1; --TxCh1_Idle:Ch1TxAmpEn
+ constant kCh1TxAmpEnMsb : integer := 9; --TxCh1_Idle:Ch1TxAmpEn
+ constant kCh1TxAmpEn : integer := 9; --TxCh1_Idle:Ch1TxAmpEn
+ constant kCh1TxPaEnSize : integer := 1; --TxCh1_Idle:Ch1TxPaEn
+ constant kCh1TxPaEnMsb : integer := 10; --TxCh1_Idle:Ch1TxPaEn
+ constant kCh1TxPaEn : integer := 10; --TxCh1_Idle:Ch1TxPaEn
+ constant kCh1SwTrxSize : integer := 2; --TxCh1_Idle:Ch1SwTrx
+ constant kCh1SwTrxMsb : integer := 12; --TxCh1_Idle:Ch1SwTrx
+ constant kCh1SwTrx : integer := 11; --TxCh1_Idle:Ch1SwTrx
+ constant kCh1TxLedSize : integer := 1; --TxCh1_Idle:Ch1TxLed
+ constant kCh1TxLedMsb : integer := 13; --TxCh1_Idle:Ch1TxLed
+ constant kCh1TxLed : integer := 13; --TxCh1_Idle:Ch1TxLed
+ constant kCh1MykEnTxSize : integer := 1; --TxCh1_Idle:Ch1MykEnTx
+ constant kCh1MykEnTxMsb : integer := 14; --TxCh1_Idle:Ch1MykEnTx
+ constant kCh1MykEnTx : integer := 14; --TxCh1_Idle:Ch1MykEnTx
+
+ -- RxCh1_0_Idle Register (from TopCpld.vhd)
+ constant kRxCh1_0_Idle : integer := 16#51#; -- Register Offset
+ constant kRxCh1_0_IdleSize: integer := 16; -- register width in bits
+ constant kRxCh1_0_IdleMask : std_logic_vector(15 downto 0) := X"3fff";
+ constant kCh1RxSw1Size : integer := 2; --RxCh1_0_Idle:Ch1RxSw1
+ constant kCh1RxSw1Msb : integer := 1; --RxCh1_0_Idle:Ch1RxSw1
+ constant kCh1RxSw1 : integer := 0; --RxCh1_0_Idle:Ch1RxSw1
+ constant kCh1RxSw2Size : integer := 2; --RxCh1_0_Idle:Ch1RxSw2
+ constant kCh1RxSw2Msb : integer := 3; --RxCh1_0_Idle:Ch1RxSw2
+ constant kCh1RxSw2 : integer := 2; --RxCh1_0_Idle:Ch1RxSw2
+ constant kCh1RxSw3Size : integer := 3; --RxCh1_0_Idle:Ch1RxSw3
+ constant kCh1RxSw3Msb : integer := 6; --RxCh1_0_Idle:Ch1RxSw3
+ constant kCh1RxSw3 : integer := 4; --RxCh1_0_Idle:Ch1RxSw3
+ constant kCh1RxSw4Size : integer := 3; --RxCh1_0_Idle:Ch1RxSw4
+ constant kCh1RxSw4Msb : integer := 9; --RxCh1_0_Idle:Ch1RxSw4
+ constant kCh1RxSw4 : integer := 7; --RxCh1_0_Idle:Ch1RxSw4
+ constant kCh1RxSw5Size : integer := 4; --RxCh1_0_Idle:Ch1RxSw5
+ constant kCh1RxSw5Msb : integer := 13; --RxCh1_0_Idle:Ch1RxSw5
+ constant kCh1RxSw5 : integer := 10; --RxCh1_0_Idle:Ch1RxSw5
+
+ -- RxCh1_1_Idle Register (from TopCpld.vhd)
+ constant kRxCh1_1_Idle : integer := 16#52#; -- Register Offset
+ constant kRxCh1_1_IdleSize: integer := 16; -- register width in bits
+ constant kRxCh1_1_IdleMask : std_logic_vector(15 downto 0) := X"07ff";
+ constant kCh1RxSw6Size : integer := 3; --RxCh1_1_Idle:Ch1RxSw6
+ constant kCh1RxSw6Msb : integer := 2; --RxCh1_1_Idle:Ch1RxSw6
+ constant kCh1RxSw6 : integer := 0; --RxCh1_1_Idle:Ch1RxSw6
+ constant kCh1RxLowbandMixerPathSelectSize : integer := 1; --RxCh1_1_Idle:Ch1RxLowbandMixerPathSelect
+ constant kCh1RxLowbandMixerPathSelectMsb : integer := 3; --RxCh1_1_Idle:Ch1RxLowbandMixerPathSelect
+ constant kCh1RxLowbandMixerPathSelect : integer := 3; --RxCh1_1_Idle:Ch1RxLowbandMixerPathSelect
+ constant kCh1RxMixerEnSize : integer := 1; --RxCh1_1_Idle:Ch1RxMixerEn
+ constant kCh1RxMixerEnMsb : integer := 4; --RxCh1_1_Idle:Ch1RxMixerEn
+ constant kCh1RxMixerEn : integer := 4; --RxCh1_1_Idle:Ch1RxMixerEn
+ constant kCh1RxAmpEnSize : integer := 1; --RxCh1_1_Idle:Ch1RxAmpEn
+ constant kCh1RxAmpEnMsb : integer := 5; --RxCh1_1_Idle:Ch1RxAmpEn
+ constant kCh1RxAmpEn : integer := 5; --RxCh1_1_Idle:Ch1RxAmpEn
+ constant kCh1RxLna1EnSize : integer := 1; --RxCh1_1_Idle:Ch1RxLna1En
+ constant kCh1RxLna1EnMsb : integer := 6; --RxCh1_1_Idle:Ch1RxLna1En
+ constant kCh1RxLna1En : integer := 6; --RxCh1_1_Idle:Ch1RxLna1En
+ constant kCh1RxLna2EnSize : integer := 1; --RxCh1_1_Idle:Ch1RxLna2En
+ constant kCh1RxLna2EnMsb : integer := 7; --RxCh1_1_Idle:Ch1RxLna2En
+ constant kCh1RxLna2En : integer := 7; --RxCh1_1_Idle:Ch1RxLna2En
+ constant kCh1Rx2LedSize : integer := 1; --RxCh1_1_Idle:Ch1Rx2Led
+ constant kCh1Rx2LedMsb : integer := 8; --RxCh1_1_Idle:Ch1Rx2Led
+ constant kCh1Rx2Led : integer := 8; --RxCh1_1_Idle:Ch1Rx2Led
+ constant kCh1RxLedSize : integer := 1; --RxCh1_1_Idle:Ch1RxLed
+ constant kCh1RxLedMsb : integer := 9; --RxCh1_1_Idle:Ch1RxLed
+ constant kCh1RxLed : integer := 9; --RxCh1_1_Idle:Ch1RxLed
+ constant kCh1MykEnRxSize : integer := 1; --RxCh1_1_Idle:Ch1MykEnRx
+ constant kCh1MykEnRxMsb : integer := 10; --RxCh1_1_Idle:Ch1MykEnRx
+ constant kCh1MykEnRx : integer := 10; --RxCh1_1_Idle:Ch1MykEnRx
+
+ -- TxCh1_TxOn Register (from TopCpld.vhd)
+ constant kTxCh1_TxOn : integer := 16#53#; -- Register Offset
+ constant kTxCh1_TxOnSize: integer := 16; -- register width in bits
+ constant kTxCh1_TxOnMask : std_logic_vector(15 downto 0) := X"0000";
+
+ -- RxCh1_0_RxOn Register (from TopCpld.vhd)
+ constant kRxCh1_0_RxOn : integer := 16#54#; -- Register Offset
+ constant kRxCh1_0_RxOnSize: integer := 16; -- register width in bits
+ constant kRxCh1_0_RxOnMask : std_logic_vector(15 downto 0) := X"0000";
+
+ -- RxCh1_1_RxOn Register (from TopCpld.vhd)
+ constant kRxCh1_1_RxOn : integer := 16#55#; -- Register Offset
+ constant kRxCh1_1_RxOnSize: integer := 16; -- register width in bits
+ constant kRxCh1_1_RxOnMask : std_logic_vector(15 downto 0) := X"0000";
+
+ -- TxCh2_Idle Register (from TopCpld.vhd)
+ constant kTxCh2_Idle : integer := 16#60#; -- Register Offset
+ constant kTxCh2_IdleSize: integer := 16; -- register width in bits
+ constant kTxCh2_IdleMask : std_logic_vector(15 downto 0) := X"0000";
+
+ -- RxCh2_0_Idle Register (from TopCpld.vhd)
+ constant kRxCh2_0_Idle : integer := 16#61#; -- Register Offset
+ constant kRxCh2_0_IdleSize: integer := 16; -- register width in bits
+ constant kRxCh2_0_IdleMask : std_logic_vector(15 downto 0) := X"0000";
+
+ -- RxCh2_1_Idle Register (from TopCpld.vhd)
+ constant kRxCh2_1_Idle : integer := 16#62#; -- Register Offset
+ constant kRxCh2_1_IdleSize: integer := 16; -- register width in bits
+ constant kRxCh2_1_IdleMask : std_logic_vector(15 downto 0) := X"0000";
+
+ -- TxCh2_TxOn Register (from TopCpld.vhd)
+ constant kTxCh2_TxOn : integer := 16#63#; -- Register Offset
+ constant kTxCh2_TxOnSize: integer := 16; -- register width in bits
+ constant kTxCh2_TxOnMask : std_logic_vector(15 downto 0) := X"0000";
+
+ -- RxCh2_0_RxOn Register (from TopCpld.vhd)
+ constant kRxCh2_0_RxOn : integer := 16#64#; -- Register Offset
+ constant kRxCh2_0_RxOnSize: integer := 16; -- register width in bits
+ constant kRxCh2_0_RxOnMask : std_logic_vector(15 downto 0) := X"0000";
+
+ -- RxCh2_1_RxOn Register (from TopCpld.vhd)
+ constant kRxCh2_1_RxOn : integer := 16#65#; -- Register Offset
+ constant kRxCh2_1_RxOnSize: integer := 16; -- register width in bits
+ constant kRxCh2_1_RxOnMask : std_logic_vector(15 downto 0) := X"0000";
+
+end package;
+
+package body PkgMgCpld is
+
+ -- function kSignatureRegRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kMinorRevRegRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kMajorRevRegRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kBuildCodeLSBRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kBuildCodeMSBRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kScratchRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kCpldControlRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kLmkControlRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kLoStatusRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kMykonosControlRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kPlScratchRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kPlCpldControlRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kTxCh1_IdleRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kRxCh1_0_IdleRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kRxCh1_1_IdleRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kTxCh1_TxOnRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kRxCh1_0_RxOnRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kRxCh1_1_RxOnRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kTxCh2_IdleRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kRxCh2_0_IdleRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kRxCh2_1_IdleRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kTxCh2_TxOnRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kRxCh2_0_RxOnRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kRxCh2_1_RxOnRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+end package body;
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/cpld/PkgSetup.vhd b/fpga/usrp3/top/n3xx/dboards/mg/cpld/PkgSetup.vhd
new file mode 100644
index 000000000..e19358912
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/cpld/PkgSetup.vhd
@@ -0,0 +1,259 @@
+-------------------------------------------------------------------------------
+--
+-- File: PkgSetup.vhd
+-- Author: Daniel Jepson
+-- Original Project: N310
+-- Date: 22 September 2017
+--
+-------------------------------------------------------------------------------
+-- Copyright 2016-2017 Ettus Research, A National Instruments Company
+-- SPDX-License-Identifier: GPL-3.0
+-------------------------------------------------------------------------------
+--
+-- Purpose:
+--
+-- Default values for front end config and CPLD constants.
+--
+-- Contains the revision constants that must be bumped when the CPLD is updated.
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+library work;
+ use work.PkgMgCpld.all;
+
+package PkgSetup is
+
+
+ constant kRdWtWidth : integer := 1;
+ constant kAddrWidth : integer := 7;
+ constant kDataWidth : integer := 16;
+ constant kTotalWidth : integer := kRdWtWidth + kAddrWidth + kDataWidth;
+
+ subtype InterfaceData_t is std_logic_vector(kDataWidth-1 downto 0);
+
+ constant kSignature : InterfaceData_t := x"CAFE";
+
+
+ -- UPDATE THESE REVISIONS when making changes to the CPLD -----------------------------
+ -- ------------------------------------------------------------------------------------
+ constant kMinorRev : InterfaceData_t := std_logic_vector(to_unsigned(0,kDataWidth));
+ constant kMajorRev : InterfaceData_t := std_logic_vector(to_unsigned(5,kDataWidth));
+ -- Currently just the timestamp of the build time/date: yymmddhh
+ constant kBuildCode : std_logic_vector(31 downto 0) := X"18010408";
+
+
+ function kTxChDefault return InterfaceData_t;
+ function kTxChDefaultRun return InterfaceData_t;
+ function kRxChDefault0 return InterfaceData_t;
+ function kRxChDefault1 return InterfaceData_t;
+ function kRxChDefault0Run return InterfaceData_t;
+ function kRxChDefault1Run return InterfaceData_t;
+
+ function Tx2Switch2Mod(kCh1Val : std_logic_vector) return std_logic_vector;
+ function Tx2TrxMod (kCh1Val : std_logic_vector) return std_logic_vector;
+
+ function Rx2Switch1Mod(kCh1Val : std_logic_vector) return std_logic_vector;
+ function Rx2Switch2Mod(kCh1Val : std_logic_vector) return std_logic_vector;
+ function Rx2Switch3Mod(kCh1Val : std_logic_vector) return std_logic_vector;
+ function Rx2Switch4Mod(kCh1Val : std_logic_vector) return std_logic_vector;
+ function Rx2Switch5Mod(kCh1Val : std_logic_vector) return std_logic_vector;
+ function Rx2Switch6Mod(kCh1Val : std_logic_vector) return std_logic_vector;
+
+
+end package;
+
+package body PkgSetup is
+
+ function kTxChDefault return InterfaceData_t is
+ variable RetVal : InterfaceData_t := (others => '0');
+ begin
+ RetVal(kCh1SwTrxMsb downto kCh1SwTrx) := std_logic_vector(to_unsigned(kFromLowerFilterBankTxSw1, kCh1SwTrxSize));
+ RetVal(kCh1TxSw1Msb downto kCh1TxSw1) := std_logic_vector(to_unsigned(kShutdownTxSw1, kCh1TxSw1Size));
+ RetVal(kCh1TxSw2Msb downto kCh1TxSw2) := std_logic_vector(to_unsigned(kToTxFilterLp3400MHz, kCh1TxSw2Size));
+ RetVal(kCh1TxSw3 downto kCh1TxSw3) := std_logic_vector(to_unsigned(kToTxFilterBanks, kCh1TxSw3Size));
+ RetVal(kCh1TxLowbandMixerPathSelect) := '0';
+ RetVal(kCh1TxMixerEn) := '0';
+ RetVal(kCh1TxAmpEn) := '0';
+ RetVal(kCh1TxPaEn) := '0';
+ RetVal(kCh1TxLed) := '0';
+ RetVal(kCh1MykEnTx) := '1';
+ return RetVal;
+ end kTxChDefault;
+
+ function kTxChDefaultRun return InterfaceData_t is
+ variable RetVal : InterfaceData_t := (others => '0');
+ begin
+ RetVal(kCh1SwTrxMsb downto kCh1SwTrx) := std_logic_vector(to_unsigned(kFromLowerFilterBankTxSw1, kCh1SwTrxSize));
+ RetVal(kCh1TxSw1Msb downto kCh1TxSw1) := std_logic_vector(to_unsigned(kFromTxFilterLp3400MHz, kCh1TxSw1Size));
+ RetVal(kCh1TxSw2Msb downto kCh1TxSw2) := std_logic_vector(to_unsigned(kToTxFilterLp3400MHz, kCh1TxSw2Size));
+ RetVal(kCh1TxSw3 downto kCh1TxSw3) := std_logic_vector(to_unsigned(kToTxFilterBanks, kCh1TxSw3Size));
+ RetVal(kCh1TxLowbandMixerPathSelect) := '0';
+ RetVal(kCh1TxMixerEn) := '0';
+ RetVal(kCh1TxAmpEn) := '1';
+ RetVal(kCh1TxPaEn) := '1';
+ RetVal(kCh1TxLed) := '1';
+ RetVal(kCh1MykEnTx) := '1';
+ return RetVal;
+ end kTxChDefaultRun;
+
+
+
+
+ function kRxChDefault0 return InterfaceData_t is
+ variable RetVal : InterfaceData_t := (others => '0');
+ begin
+ RetVal(kCh1RxSw1Msb downto kCh1RxSw1) := std_logic_vector(to_unsigned(kRx2Input, kCh1RxSw1Size));
+ RetVal(kCh1RxSw2Msb downto kCh1RxSw2) := std_logic_vector(to_unsigned(kShutdownSw2, kCh1RxSw2Size));
+ RetVal(kCh1RxSw3Msb downto kCh1RxSw3) := std_logic_vector(to_unsigned(kShutdownSw3, kCh1RxSw3Size));
+ RetVal(kCh1RxSw4Msb downto kCh1RxSw4) := std_logic_vector(to_unsigned(kFilter2100x2850MHzFrom, kCh1RxSw4Size));
+ RetVal(kCh1RxSw5Msb downto kCh1RxSw5) := std_logic_vector(to_unsigned(kFilter0490LpMHzFrom, kCh1RxSw5Size));
+ return RetVal;
+ end kRxChDefault0;
+
+ function kRxChDefault1 return InterfaceData_t is
+ variable RetVal : InterfaceData_t := (others => '0');
+ begin
+ RetVal(kCh1RxSw6Msb downto kCh1RxSw6) := std_logic_vector(to_unsigned(kUpperFilterBankFromSwitch4, kCh1RxSw6Size));
+ RetVal(kCh1RxLowbandMixerPathSelect) := '0';
+ RetVal(kCh1RxMixerEn) := '0';
+ RetVal(kCh1RxAmpEn) := '0';
+ RetVal(kCh1RxLna1En) := '0';
+ RetVal(kCh1RxLna2En) := '0';
+ RetVal(kCh1Rx2Led) := '0';
+ RetVal(kCh1RxLed) := '0';
+ RetVal(kCh1MykEnRx) := '1';
+ return RetVal;
+ end kRxChDefault1;
+
+ function kRxChDefault0Run return InterfaceData_t is
+ variable RetVal : InterfaceData_t := (others => '0');
+ begin
+ RetVal(kCh1RxSw1Msb downto kCh1RxSw1) := std_logic_vector(to_unsigned(kRx2Input, kCh1RxSw1Size));
+ RetVal(kCh1RxSw2Msb downto kCh1RxSw2) := std_logic_vector(to_unsigned(kLowerFilterBankToSwitch3, kCh1RxSw2Size));
+ RetVal(kCh1RxSw3Msb downto kCh1RxSw3) := std_logic_vector(to_unsigned(kFilter2100x2850MHz, kCh1RxSw3Size));
+ RetVal(kCh1RxSw4Msb downto kCh1RxSw4) := std_logic_vector(to_unsigned(kFilter2100x2850MHzFrom, kCh1RxSw4Size));
+ RetVal(kCh1RxSw5Msb downto kCh1RxSw5) := std_logic_vector(to_unsigned(kFilter0490LpMHzFrom, kCh1RxSw5Size));
+ return RetVal;
+ end kRxChDefault0Run;
+
+ function kRxChDefault1Run return InterfaceData_t is
+ variable RetVal : InterfaceData_t := (others => '0');
+ begin
+ RetVal(kCh1RxSw6Msb downto kCh1RxSw6) := std_logic_vector(to_unsigned(kUpperFilterBankFromSwitch4, kCh1RxSw6Size));
+ RetVal(kCh1RxLowbandMixerPathSelect) := '0';
+ RetVal(kCh1RxMixerEn) := '0';
+ RetVal(kCh1RxAmpEn) := '1';
+ RetVal(kCh1RxLna1En) := '1';
+ RetVal(kCh1RxLna2En) := '1';
+ RetVal(kCh1Rx2Led) := '1'; -- turn on a LED for grins
+ RetVal(kCh1RxLed) := '0';
+ RetVal(kCh1MykEnRx) := '1';
+ return RetVal;
+ end kRxChDefault1Run;
+
+
+
+
+
+
+ function Tx2Switch2Mod(kCh1Val : std_logic_vector) return std_logic_vector is
+ variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
+ begin
+ -- Encoding for this switch is one-hot, so we just flip around the bits here.
+ RetVal(kCh1Val'low + 0) := kCh1Val(kCh1Val'low + 0);
+ RetVal(kCh1Val'low + 3) := kCh1Val(kCh1Val'low + 1);
+ RetVal(kCh1Val'low + 1) := kCh1Val(kCh1Val'low + 2);
+ RetVal(kCh1Val'low + 2) := kCh1Val(kCh1Val'low + 3);
+ return RetVal;
+ end Tx2Switch2Mod;
+
+ function Tx2TrxMod(kCh1Val : std_logic_vector) return std_logic_vector is
+ variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
+ begin
+ if kCh1Val = "00" then RetVal := "00";
+ elsif kCh1Val = "01" then RetVal := "10";
+ elsif kCh1Val = "10" then RetVal := "01";
+ elsif kCh1Val = "11" then RetVal := "11";
+ else RetVal := "00"; end if;
+ return RetVal;
+ end Tx2TrxMod;
+
+
+
+ function Rx2Switch1Mod(kCh1Val : std_logic_vector) return std_logic_vector is
+ variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
+ begin
+ -- Encoding for this switch is binary, so we need to mux.
+ if kCh1Val = "00" then RetVal := "01";
+ elsif kCh1Val = "01" then RetVal := "00";
+ elsif kCh1Val = "10" then RetVal := "11";
+ elsif kCh1Val = "11" then RetVal := "10";
+ else RetVal := "00"; end if;
+ return RetVal;
+ end Rx2Switch1Mod;
+
+ function Rx2Switch2Mod(kCh1Val : std_logic_vector) return std_logic_vector is
+ variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
+ begin
+ -- Encoding for this switch is binary, so we need to mux.
+ if kCh1Val = "00" then RetVal := "00";
+ elsif kCh1Val = "01" then RetVal := "11";
+ elsif kCh1Val = "10" then RetVal := "10";
+ elsif kCh1Val = "11" then RetVal := "01";
+ else RetVal := "00"; end if;
+ return RetVal;
+ end Rx2Switch2Mod;
+
+ function Rx2Switch3Mod(kCh1Val : std_logic_vector) return std_logic_vector is
+ variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
+ begin
+ -- Encoding for this switch is binary, so we need to mux.
+ if kCh1Val = "000" then RetVal := "100";
+ elsif kCh1Val = "001" then RetVal := "101";
+ elsif kCh1Val = "010" then RetVal := "110";
+ elsif kCh1Val = "011" then RetVal := "011";
+ elsif kCh1Val = "100" then RetVal := "001";
+ elsif kCh1Val = "101" then RetVal := "000";
+ elsif kCh1Val = "110" then RetVal := "010";
+ elsif kCh1Val = "111" then RetVal := "111";
+ else RetVal := "000"; end if;
+ return RetVal;
+ end Rx2Switch3Mod;
+
+ function Rx2Switch4Mod(kCh1Val : std_logic_vector) return std_logic_vector is
+ variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
+ begin
+ -- Encoding for this switch is one-hot, so we just flip around the bits here.
+ RetVal(kCh1Val'low + 2) := kCh1Val(kCh1Val'low + 0);
+ RetVal(kCh1Val'low + 1) := kCh1Val(kCh1Val'low + 1);
+ RetVal(kCh1Val'low + 0) := kCh1Val(kCh1Val'low + 2);
+ return RetVal;
+ end Rx2Switch4Mod;
+
+ function Rx2Switch5Mod(kCh1Val : std_logic_vector) return std_logic_vector is
+ variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
+ begin
+ -- Encoding for this switch is one-hot, so we just flip around the bits here.
+ RetVal(kCh1Val'low + 1) := kCh1Val(kCh1Val'low + 0);
+ RetVal(kCh1Val'low + 0) := kCh1Val(kCh1Val'low + 1);
+ RetVal(kCh1Val'low + 3) := kCh1Val(kCh1Val'low + 2);
+ RetVal(kCh1Val'low + 2) := kCh1Val(kCh1Val'low + 3);
+ return RetVal;
+ end Rx2Switch5Mod;
+
+ function Rx2Switch6Mod(kCh1Val : std_logic_vector) return std_logic_vector is
+ variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
+ begin
+ -- Encoding for this switch is one-hot, so we just flip around the bits here.
+ RetVal(kCh1Val'low + 2) := kCh1Val(kCh1Val'low + 0);
+ RetVal(kCh1Val'low + 1) := kCh1Val(kCh1Val'low + 1);
+ RetVal(kCh1Val'low + 0) := kCh1Val(kCh1Val'low + 2);
+ return RetVal;
+ end Rx2Switch6Mod;
+
+
+end package body; \ No newline at end of file
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/cpld/Timing.sdc b/fpga/usrp3/top/n3xx/dboards/mg/cpld/Timing.sdc
new file mode 100644
index 000000000..496814662
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/cpld/Timing.sdc
@@ -0,0 +1,160 @@
+#
+# Copyright 2017 Ettus Research, A National Instruments Company
+# SPDX-License-Identifier: LGPL-3.0
+#
+
+# All the magic numbers come from the "/n3xx/dboards/mg/doc/mg_timing.xlsx" timing
+# analysis spreadsheet. Analysis should be re-performed every time a board rev occurs
+# that affects the CPLD interfaces.
+
+## PS Slave Constraints #################################################################
+# - PsClk Rate
+# - PsClk to SDI
+# - PsClk to LE (sync and async paths)
+# - PsClk to SDO
+
+# Maximum 4 MHz clock rate! This is heavily limited by the read data turnaround time...
+# and could be up to 20 MHz if only performing writes.
+create_clock -name PsClk -period 250 [get_ports {PsSpiSck}]
+
+# SDI is both registered in the CPLD and used as a direct passthrough. First constrain
+# the input delay on the local paths inside the CPLD. Passthrough constraints
+# are handled elsewhere.
+
+set PsSdiInputDelayMax 22.303
+set PsSdiInputDelayMin -19.019
+
+# SDI is driven from the PS on the falling edge of the Clk. Worst-case data-clock skew
+# is around +/-20ns due to FPGA routing delays and board buffering. Complete timing
+# analysis is performed and recorded elsewhere.
+set_input_delay -clock PsClk -max $PsSdiInputDelayMax [get_ports sPsSpiSdi] -clock_fall
+set_input_delay -clock PsClk -min $PsSdiInputDelayMin [get_ports sPsSpiSdi] -clock_fall
+
+# For the CPLD Cs_n, the latch enable is used both as an asynchronous reset and
+# synchronously to latch data. First, constrain the overall input delay for sync use.
+# Technically, Cs_n is asserted and de-asserted many nanoseconds before the clock arrives
+# but we still constrain it identically to the SDI in case something goes amiss.
+set_input_delay -clock PsClk -max $PsSdiInputDelayMax [get_ports sPsSpiLe] -clock_fall
+set_input_delay -clock PsClk -min $PsSdiInputDelayMin [get_ports sPsSpiLe] -clock_fall
+# Then set a false path only on the async reset flops.
+set_false_path -from [get_ports {sPsSpiLe}] -to [get_pins sPsMosiIndex[*]|*]
+set_false_path -from [get_ports {sPsSpiLe}] -to [get_pins sPsMisoIndex[*]|*]
+
+# Constrain MISO as snugly as possible through the CPLD without making the tools work
+# too hard. At a 200 ns period, this sets the clock-to-out for the CPLD at [10, 65]ns.
+# Math for Max = T_clk/2 - 60 = 250/2 - 60 = 65 ns.
+set PsSdoOutputDelayMax 60
+set PsSdoOutputDelayMin -10
+
+set_output_delay -clock PsClk -max $PsSdoOutputDelayMax [get_ports sPsSpiSdo]
+set_output_delay -clock PsClk -min $PsSdoOutputDelayMin [get_ports sPsSpiSdo]
+
+
+
+## PL Slave Constraints #################################################################
+# - PlClk Rate
+# - PlClk to SDI
+# - PlClk to LE (sync and async paths)
+# - PlClk to SDO
+
+# Maximum 5 MHz clock rate!
+create_clock -name PlClk -period 200 [get_ports {PlSpiSck}]
+
+# SDI is both registered in the CPLD and used as a direct passthrough. First constrain
+# the input delay on the local paths inside the CPLD. Passthrough constraints
+# are handled elsewhere.
+
+set PlSdiInputDelayMax 10.445
+set PlSdiInputDelayMin -10.378
+
+# SDI is driven from the FPGA on the falling edge of the Clk. Worst-case data-clock skew
+# is around +/-10ns. Complete timing analysis is performed and recorded elsewhere.
+set_input_delay -clock PlClk -max $PlSdiInputDelayMax [get_ports lPlSpiSdi] -clock_fall
+set_input_delay -clock PlClk -min $PlSdiInputDelayMin [get_ports lPlSpiSdi] -clock_fall
+
+# For the CPLD Cs_n, the latch enable is used both as an asynchronous reset and
+# synchronously to latch data. First, constrain the overall input delay for sync use.
+# Technically, Cs_n is asserted and de-asserted many nanoseconds before the clock arrives
+# but we still constrain it identically to the SDI in case something goes amiss.
+set_input_delay -clock PlClk -max $PlSdiInputDelayMax [get_ports lPlSpiLe] -clock_fall
+set_input_delay -clock PlClk -min $PlSdiInputDelayMin [get_ports lPlSpiLe] -clock_fall
+# Then set a false path only on the async reset flops.
+set_false_path -from [get_ports {lPlSpiLe}] -to [get_pins {lPlMosiIndex[*]|*}]
+set_false_path -from [get_ports {lPlSpiLe}] -to [get_pins {lPlMisoIndex[*]|*}]
+
+# Constrain MISO as snugly as possible through the CPLD without making the tools work
+# too hard. At a 200 ns period, this sets the clock-to-out for the CPLD at [10, 65]ns.
+# Math for Max = T_clk/2 - 35 = 200/2 - 35 = 65 ns.
+set PlSdoOutputDelayMax 35
+set PlSdoOutputDelayMin -10
+
+set_output_delay -clock PlClk -max $PlSdoOutputDelayMax [get_ports lPlSpiSdo]
+set_output_delay -clock PlClk -min $PlSdoOutputDelayMin [get_ports lPlSpiSdo]
+
+
+
+## Passthrough Constraints ##############################################################
+# - LMK SYNC
+# - PlClk/PsClk passthrough
+# - SDI passthrough for both
+# - SDO return mux passthrough for both
+# - Cs_n passthrough for both
+
+# LMK Sync Passthrough: constrain min and max delays for output
+set_max_delay -from [get_ports {aPlSpiAddr[2]}] -to [get_ports {aLmkSync}] 17
+set_min_delay -from [get_ports {aPlSpiAddr[2]}] -to [get_ports {aLmkSync}] 2
+
+# SPI Passthroughs: constrain min and max delays for outputs and inputs.
+# Since the SDI ports have input delays pre-defined above, we have to remove those from
+# the delay analysis here by adding the input delay to the constraint.
+# Similarly, for the SDO pins add the output delay to the constraint.
+set SpiMaxDelay 25
+set SpiMinDelay 5
+
+# PS
+set_max_delay -to [get_ports {aDacDin aLmkSpiSdio}] [expr $PsSdiInputDelayMax + $SpiMaxDelay]
+set_min_delay -to [get_ports {aDacDin aLmkSpiSdio}] [expr $PsSdiInputDelayMin + $SpiMinDelay]
+set_max_delay -to [get_ports {aDacSync_n aLmkSpiCs_n}] $SpiMaxDelay
+set_min_delay -to [get_ports {aDacSync_n aLmkSpiCs_n}] $SpiMinDelay
+set_max_delay -to [get_ports {aDacSck aLmkSpiSck}] $SpiMaxDelay
+set_min_delay -to [get_ports {aDacSck aLmkSpiSck}] $SpiMinDelay
+set_max_delay -from [get_ports {aLmkClkinSel*}] [expr $SpiMaxDelay + $PsSdoOutputDelayMax]
+set_min_delay -from [get_ports {aLmkClkinSel*}] [expr $SpiMinDelay + $PsSdoOutputDelayMin]
+
+# PL
+set_max_delay -to [get_ports {aRxLoDin aTxLoDin}] [expr $PlSdiInputDelayMax + $SpiMaxDelay]
+set_min_delay -to [get_ports {aRxLoDin aTxLoDin}] [expr $PlSdiInputDelayMin + $SpiMinDelay]
+set_max_delay -to [get_ports {aRxLoCs_n aTxLoCs_n}] $SpiMaxDelay
+set_min_delay -to [get_ports {aRxLoCs_n aTxLoCs_n}] $SpiMinDelay
+set_max_delay -to [get_ports {aRxLoSck aTxLoSck}] $SpiMaxDelay
+set_min_delay -to [get_ports {aRxLoSck aTxLoSck}] $SpiMinDelay
+set_max_delay -from [get_ports {aTxLoMuxOut aRxLoMuxOut}] [expr $SpiMaxDelay + $PlSdoOutputDelayMax]
+set_min_delay -from [get_ports {aTxLoMuxOut aRxLoMuxOut}] [expr $SpiMinDelay + $PlSdoOutputDelayMin]
+
+
+
+## Async Inputs #########################################################################
+# aLmkStatus2 aRxLoLockDetect aTxLoLockDetect
+set_false_path -from [get_ports {aRxLoLockDetect}]
+set_false_path -from [get_ports {aTxLoLockDetect}]
+
+
+
+## Async Outputs ########################################################################
+# aMkReset_n aVcxoCtrl
+set_false_path -to [get_ports {aMkReset_n}]
+set_false_path -to [get_ports {aVcxoCtrl}]
+
+
+
+## Sync Front End Outputs ###############################################################
+# All we need to do here is constrain for maximum path delay from the aAtr(Rx|Tx)(1|2)
+# control bits toggling to the outputs for aCh1* and aCh2* toggling. Just in case the
+# user attempts to write the ATR while it's in use, we also constrain from the flops
+# to the pins... which covers all paths... so just to -to option is needed.
+set_max_delay -to [get_ports {aCh1* aCh2* aMk*x*En}] 40
+set_min_delay -to [get_ports {aCh1* aCh2* aMk*x*En}] 5
+
+# We don't care about the LED timing whatsoever. Let's not have them clogging up our
+# precious timing paths.
+set_false_path -to [get_ports {aCh*Led*}]
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/cpld/TopCpld.qpf b/fpga/usrp3/top/n3xx/dboards/mg/cpld/TopCpld.qpf
new file mode 100644
index 000000000..e16aaf0af
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/cpld/TopCpld.qpf
@@ -0,0 +1,31 @@
+# -------------------------------------------------------------------------- #
+#
+# Copyright (C) 2017 Intel Corporation. All rights reserved.
+# Your use of Intel Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Intel Program License
+# Subscription Agreement, the Intel Quartus Prime License Agreement,
+# the Intel MegaCore Function License Agreement, or other
+# applicable license agreement, including, without limitation,
+# that your use is for the sole purpose of programming logic
+# devices manufactured by Intel and sold by Intel or its
+# authorized distributors. Please refer to the applicable
+# agreement for further details.
+#
+# -------------------------------------------------------------------------- #
+#
+# Quartus Prime
+# Version 16.1.2 Build 203 01/18/2017 SJ Standard Edition
+# Date created = 14:51:27 February 24, 2017
+#
+# -------------------------------------------------------------------------- #
+
+QUARTUS_VERSION = "16.1"
+DATE = "14:51:27 February 24, 2017"
+
+# Revisions
+
+PROJECT_REVISION = "TopCpld"
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/cpld/TopCpld.qsf b/fpga/usrp3/top/n3xx/dboards/mg/cpld/TopCpld.qsf
new file mode 100644
index 000000000..64238c87a
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/cpld/TopCpld.qsf
@@ -0,0 +1,313 @@
+# -------------------------------------------------------------------------- #
+#
+# Copyright (C) 2017 Intel Corporation. All rights reserved.
+# Your use of Intel Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Intel Program License
+# Subscription Agreement, the Intel Quartus Prime License Agreement,
+# the Intel MegaCore Function License Agreement, or other
+# applicable license agreement, including, without limitation,
+# that your use is for the sole purpose of programming logic
+# devices manufactured by Intel and sold by Intel or its
+# authorized distributors. Please refer to the applicable
+# agreement for further details.
+#
+# -------------------------------------------------------------------------- #
+#
+# Quartus Prime
+# Version 16.1.2 Build 203 01/18/2017 SJ Standard Edition
+# Date created = 14:51:27 February 24, 2017
+#
+# -------------------------------------------------------------------------- #
+#
+# Notes:
+#
+# 1) The default values for assignments are stored in the file:
+# TopCpld_assignment_defaults.qdf
+# If this file doesn't exist, see file:
+# assignment_defaults.qdf
+#
+# 2) Altera recommends that you do not modify this file. This
+# file is updated automatically by the Quartus Prime software
+# and any changes you make may be lost or overwritten.
+#
+# -------------------------------------------------------------------------- #
+
+
+set_global_assignment -name FAMILY "MAX V"
+set_global_assignment -name DEVICE 5M570ZF256I5
+set_global_assignment -name ORIGINAL_QUARTUS_VERSION 16.1.2
+set_global_assignment -name PROJECT_CREATION_TIME_DATE "14:51:27 FEBRUARY 24, 2017"
+set_global_assignment -name LAST_QUARTUS_VERSION "16.1.2 Lite Edition"
+set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
+set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40"
+set_global_assignment -name MAX_CORE_JUNCTION_TEMP 125
+set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR "-1"
+set_global_assignment -name SDC_FILE Timing.sdc
+set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "NO HEAT SINK WITH STILL AIR"
+set_global_assignment -name AUTO_RESTART_CONFIGURATION OFF
+set_global_assignment -name ENABLE_OCT_DONE OFF
+set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF
+set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF
+set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "PASSIVE SERIAL"
+set_global_assignment -name USE_CONFIGURATION_DEVICE ON
+set_global_assignment -name GENERATE_SVF_FILE ON
+set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS OFF
+set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED"
+
+set_location_assignment PIN_C3 -to aCh2RxSw4[0]
+set_location_assignment PIN_C2 -to aCh2TxPaEn
+set_location_assignment PIN_D3 -to aCh2RxSw6[0]
+set_location_assignment PIN_D1 -to aCh2RxSw4[1]
+set_location_assignment PIN_D2 -to aCh2TxSw3
+set_location_assignment PIN_E1 -to aCh2RxSw4[2]
+set_location_assignment PIN_E4 -to aCh2RxSw7[1]
+set_location_assignment PIN_F2 -to aCh2RxSw6[1]
+set_location_assignment PIN_E3 -to aCh2RxSw7[0]
+set_location_assignment PIN_F1 -to aCh2RxSw5[0]
+set_location_assignment PIN_E2 -to aCh2RxSw5[1]
+set_location_assignment PIN_G2 -to aCh2RxSw5[3]
+set_location_assignment PIN_F3 -to aCh2TxSw4[0]
+set_location_assignment PIN_G1 -to aCh2RxSw6[2]
+set_location_assignment PIN_G3 -to aCh2TxSw4[1]
+set_location_assignment PIN_H2 -to aCh2TxAmpEn
+set_location_assignment PIN_H1 -to aCh2RxSw5[2]
+set_location_assignment PIN_J1 -to aCh2TxMixerEn
+set_location_assignment PIN_H5 -to aLoSpiSync
+set_location_assignment PIN_J2 -to aCh2RxMixerEn
+#set_location_assignment PIN_L3 -to aLmkSpiSdio
+set_location_assignment PIN_K1 -to aCh2TxSw5[1]
+set_location_assignment PIN_K2 -to aCh2TxSw5[0]
+set_location_assignment PIN_M2 -to aLmkSpiSdio
+set_location_assignment PIN_L1 -to aCh2RxSw8[0]
+set_location_assignment PIN_M3 -to lPlSpiSdi
+set_location_assignment PIN_L2 -to aCh2RxSw8[1]
+set_location_assignment PIN_M1 -to aCh2RxAmpEn
+set_location_assignment PIN_N2 -to aLmkSpiSck
+set_location_assignment PIN_N1 -to aLmkSpiCs_n
+set_location_assignment PIN_N3 -to PlSpiSck
+# set_location_assignment PIN_P2 -to lPlSpiLe
+set_location_assignment PIN_R3 -to aMkReset_n
+set_location_assignment PIN_R1 -to lPlSpiLe
+set_location_assignment PIN_T2 -to aLmkSync
+set_location_assignment PIN_R4 -to aVcxoCtrl
+set_location_assignment PIN_T4 -to aDacDin
+set_location_assignment PIN_T5 -to aDacSync_n
+set_location_assignment PIN_R6 -to aPlSpiAddr[2]
+set_location_assignment PIN_R5 -to aDacSck
+set_location_assignment PIN_T6 -to aPlSpiAddr[1]
+set_location_assignment PIN_R7 -to aLmkClkinSel[0]
+set_location_assignment PIN_T7 -to lPlSpiSdo
+set_location_assignment PIN_P8 -to sPsSpiLe
+set_location_assignment PIN_R8 -to aPsSpiAddr[1]
+set_location_assignment PIN_P9 -to aPlSpiAddr[0]
+set_location_assignment PIN_T8 -to PsSpiSck
+set_location_assignment PIN_T9 -to aPsSpiAddr[0]
+set_location_assignment PIN_R9 -to sPsSpiSdi
+set_location_assignment PIN_P10 -to aAtrRx1
+set_location_assignment PIN_T10 -to sPsSpiSdo
+set_location_assignment PIN_P11 -to aAtrTx2
+set_location_assignment PIN_R10 -to aRxLoLockDetect
+set_location_assignment PIN_R12 -to aRxLoSck
+set_location_assignment PIN_T11 -to aTxLoLockDetect
+set_location_assignment PIN_P12 -to aAtrRx2
+set_location_assignment PIN_R11 -to aRxLoDin
+set_location_assignment PIN_T12 -to aRxLoCs_n
+set_location_assignment PIN_R13 -to aTxLoDin
+set_location_assignment PIN_T13 -to aRxLoMuxOut
+set_location_assignment PIN_P13 -to aAtrTx1
+set_location_assignment PIN_T15 -to aTxLoSck
+set_location_assignment PIN_R14 -to aTxLoCs_n
+set_location_assignment PIN_R16 -to aTxLoMuxOut
+set_location_assignment PIN_P14 -to aMkTx1En
+set_location_assignment PIN_N15 -to aMkRx2En
+set_location_assignment PIN_P15 -to aMkRx1En
+set_location_assignment PIN_N16 -to aMkTx2En
+set_location_assignment PIN_K15 -to aCh1TxSw5[1]
+set_location_assignment PIN_L14 -to aCh1RxMixerEn
+set_location_assignment PIN_K16 -to aCh1TxMixerEn
+set_location_assignment PIN_K14 -to aCh1RxSw8[0]
+set_location_assignment PIN_J15 -to aCh1TxAmpEn
+set_location_assignment PIN_J14 -to aCh1RxSw8[1]
+set_location_assignment PIN_J16 -to aCh1TxSw5[0]
+set_location_assignment PIN_H14 -to aCh1RxAmpEn
+set_location_assignment PIN_H16 -to aCh1TxSw4[0]
+set_location_assignment PIN_G14 -to aCh1TxSw4[1]
+set_location_assignment PIN_H15 -to aCh1RxSw5[1]
+set_location_assignment PIN_F14 -to aCh1RxSw7[1]
+set_location_assignment PIN_G16 -to aCh1RxSw5[0]
+set_location_assignment PIN_G15 -to aCh1RxSw4[0]
+set_location_assignment PIN_E14 -to aCh1RxSw6[1]
+set_location_assignment PIN_F16 -to aCh1RxSw2[1]
+set_location_assignment PIN_E13 -to aCh1RxSw7[0]
+set_location_assignment PIN_F15 -to aCh1RxSw2[0]
+set_location_assignment PIN_D14 -to aCh1RxSw6[2]
+set_location_assignment PIN_E16 -to aCh1RxSw6[0]
+set_location_assignment PIN_E15 -to aCh1TxSw3
+set_location_assignment PIN_C15 -to aCh1RxSw5[2]
+set_location_assignment PIN_D16 -to aCh1TxPaEn
+set_location_assignment PIN_C14 -to aCh1RxSw4[1]
+set_location_assignment PIN_D15 -to aCh1RxSw5[3]
+set_location_assignment PIN_B14 -to aCh1TxSw2[3]
+set_location_assignment PIN_B16 -to aCh1RxLna2En
+set_location_assignment PIN_C13 -to aCh1RxSw4[2]
+set_location_assignment PIN_A15 -to aCh1TxSw2[2]
+set_location_assignment PIN_B13 -to aCh1TxSw2[1]
+set_location_assignment PIN_A13 -to aCh1TxSw2[0]
+set_location_assignment PIN_C12 -to aCh1RxSw1[0]
+set_location_assignment PIN_B12 -to aCh1TxSw1[0]
+set_location_assignment PIN_D12 -to aCh1RxSw1[1]
+set_location_assignment PIN_A12 -to aCh1TxSw1[1]
+set_location_assignment PIN_C11 -to aCh1LedTx
+set_location_assignment PIN_B11 -to aCh1RxLna1En
+set_location_assignment PIN_D11 -to aCh2RxSw1[1]
+set_location_assignment PIN_A11 -to aCh1RxSw3[2]
+set_location_assignment PIN_C10 -to aCh1LedRx
+set_location_assignment PIN_B10 -to aCh1RxSw3[1]
+set_location_assignment PIN_C9 -to aCh1LedRx2
+set_location_assignment PIN_A10 -to aCh1RxSw3[0]
+set_location_assignment PIN_C8 -to aCh2LedRx2
+set_location_assignment PIN_B9 -to aCh1SwTrx[1]
+set_location_assignment PIN_A9 -to aCh1SwTrx[0]
+set_location_assignment PIN_A8 -to aCh2SwTrx[0]
+set_location_assignment PIN_C7 -to aCh2RxSw3[0]
+set_location_assignment PIN_B8 -to aCh2SwTrx[1]
+set_location_assignment PIN_C6 -to aCh2LedRx
+set_location_assignment PIN_A7 -to aCh2RxSw3[1]
+set_location_assignment PIN_B5 -to aCh2TxSw1[0]
+set_location_assignment PIN_C5 -to aCh2RxSw1[0]
+set_location_assignment PIN_A6 -to aCh2TxSw1[1]
+set_location_assignment PIN_D5 -to aCh2LedTx
+set_location_assignment PIN_B6 -to aCh2RxSw3[2]
+set_location_assignment PIN_B4 -to aCh2RxLna2En
+set_location_assignment PIN_A5 -to aCh2RxLna1En
+set_location_assignment PIN_C4 -to aCh2RxSw2[0]
+set_location_assignment PIN_A4 -to aCh2TxSw2[1]
+set_location_assignment PIN_D4 -to aCh2RxSw2[1]
+set_location_assignment PIN_A2 -to aCh2TxSw2[3]
+set_location_assignment PIN_B3 -to aCh2TxSw2[0]
+set_location_assignment PIN_B1 -to aCh2TxSw2[2]
+
+set_global_assignment -name DEVICE_FILTER_PACKAGE FBGA
+set_global_assignment -name DEVICE_FILTER_PIN_COUNT 256
+set_global_assignment -name GENERATE_JAM_FILE ON
+set_global_assignment -name GENERATE_JBC_FILE ON
+set_global_assignment -name RESERVE_ALL_UNUSED_PINS_NO_OUTPUT_GND "AS INPUT TRI-STATED"
+set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT"
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw4[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxPaEn
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw6[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw4[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw3
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw7[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw4[2]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw6[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw7[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw5[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw5[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw4[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw5[3]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw6[2]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw4[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxAmpEn
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw5[2]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxMixerEn
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxMixerEn
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw5[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw5[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aLmkSpiSdio
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw8[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw8[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxAmpEn
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aLmkSpiSck
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aLmkSpiCs_n
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aMkReset_n
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aLmkSync
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aVcxoCtrl
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aDacDin
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aDacSync_n
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aDacSck
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to lPlSpiSdo
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to sPsSpiSdo
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aRxLoSck
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aRxLoDin
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aRxLoCs_n
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aTxLoDin
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aTxLoSck
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aTxLoCs_n
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aMkTx1En
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aMkRx2En
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aMkRx1En
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aMkTx2En
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxMixerEn
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw5[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxMixerEn
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw8[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxAmpEn
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw8[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw5[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxAmpEn
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw4[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw4[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw5[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw7[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw4[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw5[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw6[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw2[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw7[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw2[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw6[2]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw6[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw3
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw5[2]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxPaEn
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw4[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw5[3]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw2[3]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw4[2]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxLna2En
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw2[2]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw2[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw2[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw1[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw1[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw1[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw1[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1LedTx
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxLna1En
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw1[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw3[2]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1LedRx
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw3[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1LedRx2
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw3[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2LedRx2
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1SwTrx[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1SwTrx[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2SwTrx[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw3[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2SwTrx[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2LedRx
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw3[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw1[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw1[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw1[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2LedTx
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw3[2]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxLna2En
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxLna1En
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw2[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw2[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw2[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw2[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw2[3]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw2[2]
+set_global_assignment -name SEED 11
+set_global_assignment -name VHDL_FILE PkgMgCpld.vhd
+set_global_assignment -name VHDL_FILE PkgSetup.vhd
+set_global_assignment -name VHDL_FILE TopCpld.vhd
+set_global_assignment -name TOP_LEVEL_ENTITY TopCpld
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/cpld/TopCpld.vhd b/fpga/usrp3/top/n3xx/dboards/mg/cpld/TopCpld.vhd
new file mode 100644
index 000000000..4e3488f54
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/cpld/TopCpld.vhd
@@ -0,0 +1,1228 @@
+-------------------------------------------------------------------------------
+--
+-- File: TopCpld.vhd
+-- Author: Daniel Jepson
+-- Original Project: N310
+-- Date: 24 October 2016
+--
+-------------------------------------------------------------------------------
+-- Copyright 2016-2017 Ettus Research, A National Instruments Company
+-- SPDX-License-Identifier: GPL-3.0
+-------------------------------------------------------------------------------
+--
+-- Purpose:
+--
+-- Top level file for the Magnesium CPLD.
+--
+-- This file instantiates two SPI slave ports. One slave port comes from the PS
+-- of the motherboard Zynq. It has three slave select pins, mapped as follows:
+-- sPlsSpiLe = CPLD Internal Registers
+-- aPsSpiAddr(0) = LMK Endpoint
+-- aPsSpiAddr(1) = Phase DAC Endpoint
+--
+-- The other slave port comes from the PL of the motherboard Zynq. It also has
+-- three slave select pins:
+-- lPlSpiLe = CPLD Internal Registers
+-- aPlSpiAddr(0) = TX Lowband LO
+-- aPlSpiAddr(1) = RX Lowband LO
+--
+-- The final address line for the PL slave is used as a passthrough for the LMK
+-- SYNC pin.
+--
+--
+-- For either SPI interface, the CPLD has internal registers that can be addressed
+-- whenever the appropriate slave select is driven asserted. These register groups
+-- are completely independent from one another, meaning the PS SPI interface cannot
+-- access the PL registers, and vice-versa.
+--
+-- See the register interface XML at the bottom of this file for details on how
+-- each SPI port is expected to be driven, and for the register maps for the PS
+-- and PL slaves.
+--
+--
+-- BUMPING THE REVISION:
+-- In PkgSetup the kMinorRev and kMajorRev are defined. Whenever a change
+-- is made to the CPLD, no matter how small, bump the kMinorRev value. If this change
+-- breaks compatibility with current HW or SW drivers, increment the kMajorRev value
+-- and reset the kMinorRev to zero. Similarly, there is a constant to define the build
+-- code, kBuildCode. Currently this is simply the year, month, day, and hour the CPLD is
+-- built, but could be user-definable.
+--
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+ use ieee.math_real.all;
+
+library work;
+ use work.PkgMgCpld.all;
+ use work.PkgSetup.all;
+
+entity TopCpld is
+ port(
+
+ -- SPI Port Incoming from FPGA --
+ PlSpiSck : in std_logic;
+ lPlSpiSdi : in std_logic;
+ lPlSpiSdo : out std_logic;
+ lPlSpiLe : in std_logic;
+ aPlSpiAddr : in std_logic_vector(2 downto 0);
+
+ -- SPI Port Incoming from PS --
+ PsSpiSck : in std_logic;
+ sPsSpiSdi : in std_logic;
+ sPsSpiSdo : out std_logic;
+ sPsSpiLe : in std_logic;
+ aPsSpiAddr : in std_logic_vector(1 downto 0);
+
+ -- ATR bits from FPGA --
+ aAtrRx1 : in std_logic;
+ aAtrRx2 : in std_logic;
+ aAtrTx1 : in std_logic;
+ aAtrTx2 : in std_logic;
+
+ -- Ch 1 TX (15 bits) --
+ aCh1LedTx : out std_logic;
+
+ aCh1TxPaEn : out std_logic;
+ aCh1TxAmpEn : out std_logic;
+ aCh1TxMixerEn : out std_logic;
+
+ aCh1TxSw1 : out std_logic_vector(1 downto 0);
+ aCh1TxSw2 : out std_logic_vector(3 downto 0);
+ aCh1TxSw3 : out std_logic;
+ aCh1TxSw4 : out std_logic_vector(1 downto 0);
+ aCh1TxSw5 : out std_logic_vector(1 downto 0);
+
+ -- Ch 1 RX (29 bits) --
+ aCh1LedRx : out std_logic;
+ aCh1LedRx2 : out std_logic;
+
+ aCh1RxAmpEn : out std_logic;
+ aCh1RxMixerEn : out std_logic;
+ aCh1RxLna1En : out std_logic;
+ aCh1RxLna2En : out std_logic;
+ aCh1SwTrx : out std_logic_vector(1 downto 0);
+
+ aCh1RxSw1 : out std_logic_vector(1 downto 0);
+ aCh1RxSw2 : out std_logic_vector(1 downto 0);
+ aCh1RxSw3 : out std_logic_vector(2 downto 0);
+ aCh1RxSw4 : out std_logic_vector(2 downto 0);
+ aCh1RxSw5 : out std_logic_vector(3 downto 0);
+ aCh1RxSw6 : out std_logic_vector(2 downto 0);
+ aCh1RxSw7 : out std_logic_vector(1 downto 0);
+ aCh1RxSw8 : out std_logic_vector(1 downto 0);
+
+ -- Ch 2 TX --
+ aCh2LedTx : out std_logic;
+
+ aCh2TxPaEn : out std_logic;
+ aCh2TxAmpEn : out std_logic;
+ aCh2TxMixerEn : out std_logic;
+
+ aCh2TxSw1 : out std_logic_vector(1 downto 0);
+ aCh2TxSw2 : out std_logic_vector(3 downto 0);
+ aCh2TxSw3 : out std_logic;
+ aCh2TxSw4 : out std_logic_vector(1 downto 0);
+ aCh2TxSw5 : out std_logic_vector(1 downto 0);
+
+ -- Ch 2 RX --
+ aCh2LedRx : out std_logic;
+ aCh2LedRx2 : out std_logic;
+
+ aCh2RxAmpEn : out std_logic;
+ aCh2RxMixerEn : out std_logic;
+ aCh2RxLna1En : out std_logic;
+ aCh2RxLna2En : out std_logic;
+ aCh2SwTrx : out std_logic_vector(1 downto 0);
+
+ aCh2RxSw1 : out std_logic_vector(1 downto 0);
+ aCh2RxSw2 : out std_logic_vector(1 downto 0);
+ aCh2RxSw3 : out std_logic_vector(2 downto 0);
+ aCh2RxSw4 : out std_logic_vector(2 downto 0);
+ aCh2RxSw5 : out std_logic_vector(3 downto 0);
+ aCh2RxSw6 : out std_logic_vector(2 downto 0);
+ aCh2RxSw7 : out std_logic_vector(1 downto 0);
+ aCh2RxSw8 : out std_logic_vector(1 downto 0);
+
+ -- LMK --
+ aLmkSpiSdio : out std_logic;
+ aLmkSpiSck : out std_logic;
+ aLmkSpiCs_n : out std_logic;
+ aLmkClkinSel : in std_logic_vector(0 downto 0); -- SDO
+ aLmkSync : out std_logic; -- direct connect to aPlSpiAddr(2)
+
+ -- Phase DAC --
+ aDacDin : out std_logic;
+ aDacSync_n : out std_logic;
+ aDacSck : out std_logic;
+ aVcxoCtrl : out std_logic; -- @PS-REG-WR
+
+ -- RX and TX LOs -- (timed)
+ aLoSpiSync : in std_logic; -- Clock! (unused atm, only for reclocking
+ aRxLoSck : out std_logic; -- the SPI bus if needed for sync)
+ aRxLoDin : out std_logic;
+ aRxLoCs_n : out std_logic;
+ aRxLoMuxOut : in std_logic;
+ aRxLoLockDetect : in std_logic; -- @PS-REG-RD
+ aTxLoSck : out std_logic;
+ aTxLoDin : out std_logic;
+ aTxLoCs_n : out std_logic;
+ aTxLoMuxOut : in std_logic;
+ aTxLoLockDetect : in std_logic; -- @PS-REG-RD
+
+ -- Mykonos Interface --
+ aMkReset_n : out std_logic; -- @PS-REG-WR
+ aMkRx1En : out std_logic;
+ aMkRx2En : out std_logic;
+ aMkTx1En : out std_logic;
+ aMkTx2En : out std_logic
+
+ );
+end TopCpld;
+
+
+architecture RTL of TopCpld is
+
+ -- PS MOSI
+ signal sCpldPsSpiActive : boolean;
+ signal sPsMosiIndex : unsigned(integer(ceil(log2(real(kTotalWidth)))) downto 0);
+ signal sPsMosiBuffer : InterfaceData_t := (others => '0');
+ signal sPsRd : boolean := false;
+ signal sPsRegAddr : unsigned(kAddrWidth-1 downto 0) := (others => '0');
+
+ -- PS MISO
+ signal sPsCpldMiso : std_logic;
+ signal sPsMisoIndex : unsigned(integer(ceil(log2(real(kTotalWidth)))) downto 0);
+ signal sPsMisoBuffer : std_logic_vector(kTotalWidth-1 downto 0);
+
+ -- PS Register Signals
+ signal aRxLoLockDetect_ms, sRxLoLockDetect,
+ aTxLoLockDetect_ms, sTxLoLockDetect : std_logic := '0';
+ signal sReset : boolean := false;
+ signal sScratchVal : InterfaceData_t := (others => '0');
+ signal sVcxoControl : std_logic := '1';
+ signal sMykonosReset : std_logic := '0';
+
+ -- PL MOSI
+ signal lCpldPlSpiActive : boolean;
+ signal lPlMosiIndex : unsigned(integer(ceil(log2(real(kTotalWidth)))) downto 0);
+ signal lPlMosiBuffer : InterfaceData_t := (others => '0');
+ signal lPlRd : boolean := false;
+ signal lPlRegAddr : unsigned(kAddrWidth-1 downto 0) := (others => '0');
+
+ -- PL MISO
+ signal lPlCpldMiso : std_logic;
+ signal lPlMisoIndex : unsigned(integer(ceil(log2(real(kTotalWidth)))) downto 0);
+ signal lPlMisoBuffer : std_logic_vector(kTotalWidth-1 downto 0);
+
+ -- PL Register Signals
+ signal lScratchVal : InterfaceData_t := (others => '0');
+ signal lReset : boolean := false;
+
+ -- See PkgSetup for each Default definition.
+ signal lTxCh1IdleReg : InterfaceData_t := kTxChDefault;
+ signal lTxCh2IdleReg : InterfaceData_t := kTxChDefault;
+
+ signal lTxCh1TxOnReg : InterfaceData_t := kTxChDefaultRun;
+ signal lTxCh2TxOnReg : InterfaceData_t := kTxChDefaultRun;
+
+ signal lRxCh1_0IdleReg : InterfaceData_t := kRxChDefault0;
+ signal lRxCh1_1IdleReg : InterfaceData_t := kRxChDefault1;
+ signal lRxCh2_0IdleReg : InterfaceData_t := kRxChDefault0;
+ signal lRxCh2_1IdleReg : InterfaceData_t := kRxChDefault1;
+
+ signal lRxCh1_0RxOnReg : InterfaceData_t := kRxChDefault0Run;
+ signal lRxCh1_1RxOnReg : InterfaceData_t := kRxChDefault1Run;
+ signal lRxCh2_0RxOnReg : InterfaceData_t := kRxChDefault0Run;
+ signal lRxCh2_1RxOnReg : InterfaceData_t := kRxChDefault1Run;
+
+ signal lTxCh1 : InterfaceData_t;
+ signal lTxCh2 : InterfaceData_t;
+ signal lRxCh1_0 : InterfaceData_t;
+ signal lRxCh1_1 : InterfaceData_t;
+ signal lRxCh2_0 : InterfaceData_t;
+ signal lRxCh2_1 : InterfaceData_t;
+
+begin
+
+
+ -- Direct Pass-through Pins : ---------------------------------------------------------
+ -- ------------------------------------------------------------------------------------
+
+ -- LMK SYNC assignment for direct passthrough to LMK from SPI Addr line.
+ aLmkSync <= aPlSpiAddr(2);
+
+
+
+ -- PS SPI Interface : -----------------------------------------------------------------
+ -- Composed of a few modules:
+ -- 1) PsMosiIndex - generate pointer for MOSI Buffer
+ -- 2) PsMosiBuffer - actually implement the buffer, only when the CPLD is targeted.
+ -- 3) PsMosiProcessing - process the MOSI data: sort into Rd/!Wt, Address, and Data.
+ -- This process works on the falling edge of the clock to register the pieces
+ -- of the MOSI packet as they are complete. The final falling edge registers
+ -- the data into the individual registers, so it is critical that the clock idle
+ -- LOW after the transaction is complete such that this final falling edge occurs.
+ -- 4) PsMisoBuffer - generate pointer for the MISO buffer. The buffer itself is
+ -- completely async.
+ -- 5) PsMisoBufferMux - Mux all the register data back into the MISO buffer.
+ -- 6) StatusSynchronizer - double-synchronizers for status bits from the LMK and LOs.
+ -- ------------------------------------------------------------------------------------
+
+ -- Decode the PS SPI Address bits... which are actually going to be used as individual
+ -- chip selects coming from the PS.
+ sCpldPsSpiActive <= sPsSpiLe = '0';
+ aLmkSpiCs_n <= aPsSpiAddr(0);
+ aDacSync_n <= aPsSpiAddr(1);
+
+ -- Assign the remainder of the SPI lines to the LMK and DAC.
+ aLmkSpiSck <= PsSpiSck;
+ aLmkSpiSdio <= sPsSpiSdi;
+ aDacSck <= PsSpiSck;
+ aDacDin <= sPsSpiSdi;
+
+ -- Output mux for data back to the FPGA (PS core). The LMK and CPLD are the only
+ -- endpoints that have readback enabled.
+ sPsSpiSdo <= aLmkClkinSel(0) when aPsSpiAddr(0) = '0' else
+ sPsCpldMiso;
+
+
+
+ -- Use the LE signal (Cs_n) as the asynchronous reset to the shift register counter.
+ -- LE will hold the counter in reset until this endpoint is targeted, when it will
+ -- release the reset (long before the clock toggles) and allow the shift operation
+ -- to begin.
+ --
+ -- !!! SAFE COUNTER STARTUP!!!
+ -- This counter starts safely from reset because the PsSpiSck will not start toggling
+ -- until long after the asynchronous reset (sCpldPsSpiActive) de-asserts. Similarly,
+ -- the reset will only assert long after the last clock edge is received.
+ PsMosiIndex : process(PsSpiSck, sCpldPsSpiActive)
+ begin
+ if not sCpldPsSpiActive then
+ sPsMosiIndex <= (others => '0');
+ elsif rising_edge(PsSpiSck) then
+ sPsMosiIndex <= sPsMosiIndex + 1;
+ end if;
+ end process PsMosiIndex;
+
+
+ -- Shift in SDI (MOSI) data from the PS on the rising edge of the clock. Only use
+ -- synchronous resets from here on out.
+ PsMosiBuffer : process(PsSpiSck)
+ begin
+ if rising_edge(PsSpiSck) then
+ if sReset then
+ sPsMosiBuffer <= (others => '0');
+ else
+ if sCpldPsSpiActive then
+ sPsMosiBuffer <= sPsMosiBuffer(sPsMosiBuffer'high-1 downto 0) & sPsSpiSdi; -- left shift
+ end if;
+ end if;
+ end if;
+ end process PsMosiBuffer;
+
+
+ -- As portions of the command and data packets become available, register them here
+ -- using the falling edge of the PS SPI clock.
+ PsMosiProcessing : process(PsSpiSck)
+ begin
+ if falling_edge(PsSpiSck) then
+ if sReset then
+ -- sReset is intentionally self-clearing. It clears on the first falling edge of
+ -- the next SPI transaction after it is set. Logic on the first rising edge of
+ -- that next transaction is therefore held in reset. This will not matter
+ -- as long as SW follows the recommended reset procedure (writing a '1' to reset
+ -- then writing a '0'), since the first bit of the transaction is '0' for a
+ -- write operation.
+ sReset <= false;
+ sScratchVal <= (others => '0');
+ sVcxoControl <= '1';
+ sMykonosReset <= '0';
+ sPsRd <= false;
+ sPsRegAddr <= (others => '0');
+ else
+ -- After the first bit is captured, we can determine if it is a write or read.
+ if (sPsMosiIndex = (kRdWtWidth)) then
+ sPsRd <= sPsMosiBuffer(0) = '1';
+ end if;
+
+ -- After the entire command word is captured, the address is ready for capture.
+ if (sPsMosiIndex = (kAddrWidth + kRdWtWidth)) then
+ sPsRegAddr <= unsigned(sPsMosiBuffer(kAddrWidth - 1 downto 0));
+ end if;
+
+ -- And finally after the entire transaction is complete we can save off the data
+ -- on the final falling edge of the SPI clock into it's appropriate place, based
+ -- off the address value captured above.
+ if (sPsMosiIndex = kTotalWidth) and (not sPsRd) then
+
+ -- ----------------------------------------------------------------------------
+ -- Assign writable register values here! --------------------------------------
+ -- ----------------------------------------------------------------------------
+ if (sPsRegAddr = kScratch) then
+ sScratchVal <= sPsMosiBuffer;
+ end if;
+
+ if (sPsRegAddr = kCpldControl) then
+ sReset <= sPsMosiBuffer(kCpldReset) = '1';
+ end if;
+
+ if (sPsRegAddr = kLmkControl) then
+ sVcxoControl <= sPsMosiBuffer(kVcxoControl);
+ end if;
+
+ if (sPsRegAddr = kMykonosControl) then
+ sMykonosReset <= sPsMosiBuffer(kMykonosReset);
+ end if;
+
+ end if;
+ end if;
+ end if;
+ end process PsMosiProcessing;
+
+
+ -- Send MISO back to FPGA (PS) on the falling edge as well.
+ --
+ -- !!! SAFE COUNTER STARTUP!!!
+ -- This counter starts safely from reset because the PsSpiSck will not start toggling
+ -- until long after the asynchronous reset (sCpldPsSpiActive) de-asserts. Similarly,
+ -- the reset will only assert long after the last clock edge is received.
+ PsMisoBuffer : process(PsSpiSck, sCpldPsSpiActive)
+ begin
+ if not sCpldPsSpiActive then
+ sPsMisoIndex <= to_unsigned(kTotalWidth-1, sPsMisoIndex'length);
+ elsif falling_edge(PsSpiSck) then
+ if sPsMisoIndex > 0 then
+ sPsMisoIndex <= sPsMisoIndex - 1;
+ end if;
+ end if;
+ end process PsMisoBuffer;
+
+ sPsCpldMiso <= sPsMisoBuffer(to_integer(sPsMisoIndex));
+
+
+ -- Mux the register data from the CPLD back to the FPGA.
+ PsMisoBufferMux : process(sPsRegAddr, sScratchVal, sVcxoControl,
+ sTxLoLockDetect, sRxLoLockDetect, sMykonosReset)
+ begin
+ sPsMisoBuffer <= (others => '0');
+ case to_integer(sPsRegAddr) is
+ when kSignatureReg => sPsMisoBuffer(kDataWidth-1 downto 0) <= kSignature;
+ when kMinorRevReg => sPsMisoBuffer(kDataWidth-1 downto 0) <= kMinorRev;
+ when kMajorRevReg => sPsMisoBuffer(kDataWidth-1 downto 0) <= kMajorRev;
+ when kBuildCodeLSB => sPsMisoBuffer(kDataWidth-1 downto 0) <= kBuildCode(15 downto 0);
+ when kBuildCodeMSB => sPsMisoBuffer(kDataWidth-1 downto 0) <= kBuildCode(31 downto 16);
+ when kScratch => sPsMisoBuffer(kDataWidth-1 downto 0) <= sScratchVal;
+ when kLmkControl => sPsMisoBuffer(kVcxoControl) <= sVcxoControl;
+ when kLoStatus => sPsMisoBuffer(kTxLoLockDetect) <= sTxLoLockDetect;
+ sPsMisoBuffer(kRxLoLockDetect) <= sRxLoLockDetect;
+ when kMykonosControl => sPsMisoBuffer(kMykonosReset) <= sMykonosReset;
+ when others => sPsMisoBuffer(kDataWidth-1 downto 0) <= (others => '0');
+ end case;
+ end process PsMisoBufferMux;
+
+
+ -- Double-synchronize the async inputs to the PS clock domain. However, this clock
+ -- isn't toggling all the time. Whenever it is toggling, let's capture these bits.
+ StatusSynchronizer : process(PsSpiSck)
+ begin
+ if rising_edge(PsSpiSck) then
+ aRxLoLockDetect_ms <= aRxLoLockDetect;
+ sRxLoLockDetect <= aRxLoLockDetect_ms;
+
+ aTxLoLockDetect_ms <= aTxLoLockDetect;
+ sTxLoLockDetect <= aTxLoLockDetect_ms;
+ end if;
+ end process;
+
+
+ -- PS SPI locals to outputs.
+ aVcxoCtrl <= sVcxoControl;
+ aMkReset_n <= not sMykonosReset;
+
+
+
+ -- PL SPI Interface : -----------------------------------------------------------------
+ -- Composed of a few modules:
+ -- 1) PlMosiIndex - generate pointer for MOSI Buffer
+ -- 2) PlMosiBuffer - actually implement the buffer, only when the CPLD is targeted.
+ -- 3) PlMosiProcessing - process the MOSI data: sort into Rd/!Wt, Address, and Data.
+ -- This process works on the falling edge of the clock to register the pieces
+ -- of the MOSI packet as they are complete. The final falling edge registers
+ -- the data into the individual registers, so it is critical that the clock idle
+ -- LOW after the transaction is complete such that this final falling edge occurs.
+ -- 4) PlMisoBuffer - generate pointer for the MISO buffer. The buffer itself is
+ -- completely async.
+ -- 5) PlMisoBufferMux - Mux all the register data back into the MISO buffer.
+ -- 6) StatusSynchronizer - double-synchronizers for status bits from the LMK and LOs.
+ -- ------------------------------------------------------------------------------------
+
+ -- Decode the PL SPI Address bits... which are actually going to be used as individual
+ -- chip selects coming from the PL.
+ lCpldPlSpiActive <= lPlSpiLe = '0';
+ aTxLoCs_n <= aPlSpiAddr(0);
+ aRxLoCs_n <= aPlSpiAddr(1);
+
+ -- Assign the remainder of the SPI lines to the LOs.
+ aRxLoSck <= PlSpiSck;
+ aRxLoDin <= lPlSpiSdi;
+ aTxLoSck <= PlSpiSck;
+ aTxLoDin <= lPlSpiSdi;
+
+ -- Output mux for data back to the FPGA (PL core). The LMK and CPLD are the only
+ -- endpoints that have readback enabled.
+ lPlSpiSdo <= aTxLoMuxOut when aPlSpiAddr(0) = '0' else
+ aRxLoMuxOut when aPlSpiAddr(1) = '0' else
+ lPlCpldMiso;
+
+
+
+ -- Use the LE signal (Cs_n) as the asynchronous reset to the shift register counter.
+ -- LE will hold the counter in reset until this endpoint is targeted, when it will
+ -- release the reset (long before the clock toggles) and allow the shift operation
+ -- to begin.
+ --
+ -- !!! SAFE COUNTER STARTUP!!!
+ -- This counter starts safely from reset because the PlSpiSck will not start toggling
+ -- until long after the asynchronous reset (lCpldPlSpiActive) de-asserts. Similarly,
+ -- the reset will only assert long after the last clock edge is received.
+ PlMosiIndex : process(PlSpiSck, lCpldPlSpiActive)
+ begin
+ if not lCpldPlSpiActive then
+ lPlMosiIndex <= (others => '0');
+ elsif rising_edge(PlSpiSck) then
+ lPlMosiIndex <= lPlMosiIndex + 1;
+ end if;
+ end process PlMosiIndex;
+
+
+ -- Shift in SDI (MOSI) data from the PL on the rising edge of the clock. Only use
+ -- synchronous resets from here on out.
+ PlMosiBuffer : process(PlSpiSck)
+ begin
+ if rising_edge(PlSpiSck) then
+ if lReset then
+ lPlMosiBuffer <= (others => '0');
+ else
+ if lCpldPlSpiActive then
+ lPlMosiBuffer <= lPlMosiBuffer(lPlMosiBuffer'high-1 downto 0) & lPlSpiSdi; -- left shift
+ end if;
+ end if;
+ end if;
+ end process PlMosiBuffer;
+
+
+ -- As portions of the command and data packets become available, register them here
+ -- using the falling edge of the PL SPI clock.
+ PlMosiProcessing : process(PlSpiSck)
+ begin
+ if falling_edge(PlSpiSck) then
+ if lReset then
+ -- lReset is intentionally self-clearing. It clears on the first falling edge of
+ -- the next SPI transaction after it is set. Logic on the first rising edge of
+ -- that next transaction is therefore held in reset. This will not matter
+ -- as long as SW follows the recommended reset procedure (writing a '1' to reset
+ -- then writing a '0'), since the first bit of the transaction is '0' for a
+ -- write operation.
+ lReset <= false;
+ lScratchVal <= (others => '0');
+ lTxCh1IdleReg <= kTxChDefault;
+ lTxCh1TxOnReg <= kTxChDefault;
+ lTxCh2IdleReg <= kTxChDefault;
+ lTxCh2TxOnReg <= kTxChDefault;
+ lRxCh1_0IdleReg <= kRxChDefault0;
+ lRxCh1_1IdleReg <= kRxChDefault1;
+ lRxCh1_0RxOnReg <= kRxChDefault0;
+ lRxCh1_1RxOnReg <= kRxChDefault1;
+ lRxCh2_0IdleReg <= kRxChDefault0;
+ lRxCh2_1IdleReg <= kRxChDefault1;
+ lRxCh2_0RxOnReg <= kRxChDefault0;
+ lRxCh2_1RxOnReg <= kRxChDefault1;
+ lPlRd <= false;
+ lPlRegAddr <= (others => '0');
+ else
+ -- After the first bit is captured, we can determine if it is a write or read.
+ if (lPlMosiIndex = (kRdWtWidth)) then
+ lPlRd <= lPlMosiBuffer(0) = '1';
+ end if;
+
+ -- After the entire command word is captured, the address is ready for capture.
+ if (lPlMosiIndex = (kAddrWidth + kRdWtWidth)) then
+ lPlRegAddr <= unsigned(lPlMosiBuffer(kAddrWidth - 1 downto 0));
+ end if;
+
+ -- And finally after the entire transaction is complete we can save off the data
+ -- on the final falling edge of the SPI clock into it's appropriate place, based
+ -- off the address value captured above.
+ if (lPlMosiIndex = kTotalWidth) and (not lPlRd) then
+
+ -- ----------------------------------------------------------------------------
+ -- Assign writable register values here! --------------------------------------
+ -- ----------------------------------------------------------------------------
+ if (lPlRegAddr = kPlScratch) then
+ lScratchVal <= lPlMosiBuffer;
+ end if;
+
+ if (lPlRegAddr = kPlCpldControl) then
+ lReset <= lPlMosiBuffer(kCpldReset) = '1';
+ end if;
+
+ if (lPlRegAddr = kTxCh1_Idle) then
+ lTxCh1IdleReg <= lPlMosiBuffer;
+ end if;
+ if (lPlRegAddr = kTxCh1_TxOn) then
+ lTxCh1TxOnReg <= lPlMosiBuffer;
+ end if;
+ if (lPlRegAddr = kTxCh2_Idle) then
+ lTxCh2IdleReg <= lPlMosiBuffer;
+ end if;
+ if (lPlRegAddr = kTxCh2_TxOn) then
+ lTxCh2TxOnReg <= lPlMosiBuffer;
+ end if;
+
+ if (lPlRegAddr = kRxCh1_0_Idle) then
+ lRxCh1_0IdleReg <= lPlMosiBuffer;
+ end if;
+ if (lPlRegAddr = kRxCh1_1_Idle) then
+ lRxCh1_1IdleReg <= lPlMosiBuffer;
+ end if;
+ if (lPlRegAddr = kRxCh1_0_RxOn) then
+ lRxCh1_0RxOnReg <= lPlMosiBuffer;
+ end if;
+ if (lPlRegAddr = kRxCh1_1_RxOn) then
+ lRxCh1_1RxOnReg <= lPlMosiBuffer;
+ end if;
+
+ if (lPlRegAddr = kRxCh2_0_Idle) then
+ lRxCh2_0IdleReg <= lPlMosiBuffer;
+ end if;
+ if (lPlRegAddr = kRxCh2_1_Idle) then
+ lRxCh2_1IdleReg <= lPlMosiBuffer;
+ end if;
+ if (lPlRegAddr = kRxCh2_0_RxOn) then
+ lRxCh2_0RxOnReg <= lPlMosiBuffer;
+ end if;
+ if (lPlRegAddr = kRxCh2_1_RxOn) then
+ lRxCh2_1RxOnReg <= lPlMosiBuffer;
+ end if;
+
+ end if;
+ end if;
+ end if;
+ end process PlMosiProcessing;
+
+
+ -- Send MISO back to FPGA (PL) on the falling edge as well.
+ --
+ -- !!! SAFE COUNTER STARTUP!!!
+ -- This counter starts safely from reset because the PlSpiSck will not start toggling
+ -- until long after the asynchronous reset (lCpldPlSpiActive) de-asserts. Similarly,
+ -- the reset will only assert long after the last clock edge is received.
+ PlMisoBuffer : process(PlSpiSck, lCpldPlSpiActive)
+ begin
+ if not lCpldPlSpiActive then
+ lPlMisoIndex <= to_unsigned(kTotalWidth-1, lPlMisoIndex'length);
+ elsif falling_edge(PlSpiSck) then
+ if lPlMisoIndex > 0 then
+ lPlMisoIndex <= lPlMisoIndex - 1;
+ end if;
+ end if;
+ end process PlMisoBuffer;
+
+ lPlCpldMiso <= lPlMisoBuffer(to_integer(lPlMisoIndex));
+
+
+ -- Mux the register data from the CPLD back to the FPGA.
+ PlMisoBufferMux : process(lPlRegAddr, lScratchVal, lTxCh1IdleReg, lTxCh1TxOnReg,
+ lTxCh2IdleReg, lTxCh2TxOnReg, lRxCh1_0IdleReg,
+ lRxCh1_1IdleReg, lRxCh1_0RxOnReg, lRxCh1_1RxOnReg,
+ lRxCh2_0IdleReg, lRxCh2_1IdleReg, lRxCh2_0RxOnReg,
+ lRxCh2_1RxOnReg)
+ begin
+ lPlMisoBuffer <= (others => '0');
+ case to_integer(lPlRegAddr) is
+ when kPlScratch => lPlMisoBuffer(kDataWidth-1 downto 0) <= lScratchVal;
+ when kTxCh1_Idle => lPlMisoBuffer(kDataWidth-1 downto 0) <= lTxCh1IdleReg;
+ when kTxCh1_TxOn => lPlMisoBuffer(kDataWidth-1 downto 0) <= lTxCh1TxOnReg;
+ when kTxCh2_Idle => lPlMisoBuffer(kDataWidth-1 downto 0) <= lTxCh2IdleReg;
+ when kTxCh2_TxOn => lPlMisoBuffer(kDataWidth-1 downto 0) <= lTxCh2TxOnReg;
+ when kRxCh1_0_Idle => lPlMisoBuffer(kDataWidth-1 downto 0) <= lRxCh1_0IdleReg;
+ when kRxCh1_1_Idle => lPlMisoBuffer(kDataWidth-1 downto 0) <= lRxCh1_1IdleReg;
+ when kRxCh1_0_RxOn => lPlMisoBuffer(kDataWidth-1 downto 0) <= lRxCh1_0RxOnReg;
+ when kRxCh1_1_RxOn => lPlMisoBuffer(kDataWidth-1 downto 0) <= lRxCh1_1RxOnReg;
+ when kRxCh2_0_Idle => lPlMisoBuffer(kDataWidth-1 downto 0) <= lRxCh2_0IdleReg;
+ when kRxCh2_1_Idle => lPlMisoBuffer(kDataWidth-1 downto 0) <= lRxCh2_1IdleReg;
+ when kRxCh2_0_RxOn => lPlMisoBuffer(kDataWidth-1 downto 0) <= lRxCh2_0RxOnReg;
+ when kRxCh2_1_RxOn => lPlMisoBuffer(kDataWidth-1 downto 0) <= lRxCh2_1RxOnReg;
+ when others => lPlMisoBuffer(kDataWidth-1 downto 0) <= (others => '0');
+ end case;
+ end process PlMisoBufferMux;
+
+
+ -- Use the ATR bits to mux the output values.
+ lTxCh1 <= lTxCh1IdleReg when aAtrTx1 = '0' else lTxCh1TxOnReg;
+ lTxCh2 <= lTxCh2IdleReg when aAtrTx2 = '0' else lTxCh2TxOnReg;
+
+ lRxCh1_0 <= lRxCh1_0IdleReg when aAtrRx1 = '0' else lRxCh1_0RxOnReg;
+ lRxCh1_1 <= lRxCh1_1IdleReg when aAtrRx1 = '0' else lRxCh1_1RxOnReg;
+ lRxCh2_0 <= lRxCh2_0IdleReg when aAtrRx2 = '0' else lRxCh2_0RxOnReg;
+ lRxCh2_1 <= lRxCh2_1IdleReg when aAtrRx2 = '0' else lRxCh2_1RxOnReg;
+
+ -- PL SPI locals to outputs. All the register values are set for Channel 1. Channel 2
+ -- values are mixed around here in order for the same register settings to work for
+ -- Channel 1 and Channel 2, even though Ch2 switch configuration is different in HW.
+ aCh1LedTx <= lTxCh1(kCh1TxLed);
+ aCh1TxPaEn <= lTxCh1(kCh1TxPaEn);
+ aCh1TxAmpEn <= lTxCh1(kCh1TxAmpEn);
+ aCh1TxMixerEn <= lTxCh1(kCh1TxMixerEn);
+ aCh1TxSw1 <= lTxCh1(kCh1TxSw1Msb downto kCh1TxSw1);
+ aCh1TxSw2 <= lTxCh1(kCh1TxSw2Msb downto kCh1TxSw2);
+ aCh1TxSw3 <= lTxCh1(kCh1TxSw3);
+ aCh1TxSw4 <= "01" when lTxCh1(kCh1TxLowbandMixerPathSelect) = '1' else "10";
+ aCh1TxSw5 <= "10" when lTxCh1(kCh1TxLowbandMixerPathSelect) = '1' else "01";
+ aCh1SwTrx <= lTxCh1(kCh1SwTrxMsb downto kCh1SwTrx);
+ aMkTx1En <= lTxCh1(kCh1MykEnTx);
+
+ aCh2LedTx <= lTxCh2(kCh1TxLed);
+ aCh2TxPaEn <= lTxCh2(kCh1TxPaEn);
+ aCh2TxAmpEn <= lTxCh2(kCh1TxAmpEn);
+ aCh2TxMixerEn <= lTxCh2(kCh1TxMixerEn);
+ aCh2TxSw1 <= lTxCh2(kCh1TxSw1Msb downto kCh1TxSw1);
+ aCh2TxSw2 <= Tx2Switch2Mod(lTxCh2(kCh1TxSw2Msb downto kCh1TxSw2));
+ aCh2TxSw3 <= lTxCh2(kCh1TxSw3);
+ aCh2TxSw4 <= "10" when lTxCh2(kCh1TxLowbandMixerPathSelect) = '1' else "01";
+ aCh2TxSw5 <= "01" when lTxCh2(kCh1TxLowbandMixerPathSelect) = '1' else "10";
+ aCh2SwTrx <= Tx2TrxMod(lTxCh2(kCh1SwTrxMsb downto kCh1SwTrx));
+ aMkTx2En <= lTxCh2(kCh1MykEnTx);
+
+ aCh1RxSw1 <= lRxCh1_0(kCh1RxSw1Msb downto kCh1RxSw1);
+ aCh1RxSw2 <= lRxCh1_0(kCh1RxSw2Msb downto kCh1RxSw2);
+ aCh1RxSw3 <= lRxCh1_0(kCh1RxSw3Msb downto kCh1RxSw3);
+ aCh1RxSw4 <= lRxCh1_0(kCh1RxSw4Msb downto kCh1RxSw4);
+ aCh1RxSw5 <= lRxCh1_0(kCh1RxSw5Msb downto kCh1RxSw5);
+ aCh1RxSw6 <= lRxCh1_1(kCh1RxSw6Msb downto kCh1RxSw6);
+ aCh1RxSw7 <= "01" when lRxCh1_1(kCh1RxLowbandMixerPathSelect) = '1' else "10";
+ aCh1RxSw8 <= "01" when lRxCh1_1(kCh1RxLowbandMixerPathSelect) = '1' else "10";
+ aCh1LedRx <= lRxCh1_1(kCh1RxLed) and not lTxCh1(kCh1TxLed);
+ aCh1LedRx2 <= lRxCh1_1(kCh1Rx2Led);
+ aCh1RxAmpEn <= lRxCh1_1(kCh1RxAmpEn);
+ aCh1RxMixerEn <= lRxCh1_1(kCh1RxMixerEn);
+ aCh1RxLna1En <= lRxCh1_1(kCh1RxLna1En);
+ aCh1RxLna2En <= lRxCh1_1(kCh1RxLna2En);
+ aMkRx1En <= lRxCh1_1(kCh1MykEnRx);
+
+ aCh2RxSw1 <= Rx2Switch1Mod(lRxCh2_0(kCh1RxSw1Msb downto kCh1RxSw1));
+ aCh2RxSw2 <= Rx2Switch2Mod(lRxCh2_0(kCh1RxSw2Msb downto kCh1RxSw2));
+ aCh2RxSw3 <= Rx2Switch3Mod(lRxCh2_0(kCh1RxSw3Msb downto kCh1RxSw3));
+ aCh2RxSw4 <= Rx2Switch4Mod(lRxCh2_0(kCh1RxSw4Msb downto kCh1RxSw4));
+ aCh2RxSw5 <= Rx2Switch5Mod(lRxCh2_0(kCh1RxSw5Msb downto kCh1RxSw5));
+ aCh2RxSw6 <= Rx2Switch6Mod(lRxCh2_1(kCh1RxSw6Msb downto kCh1RxSw6));
+ aCh2RxSw7 <= "10" when lRxCh2_1(kCh1RxLowbandMixerPathSelect) = '1' else "01";
+ aCh2RxSw8 <= "10" when lRxCh2_1(kCh1RxLowbandMixerPathSelect) = '1' else "01";
+ aCh2LedRx <= lRxCh2_1(kCh1RxLed) and not lTxCh2(kCh1TxLed);
+ aCh2LedRx2 <= lRxCh2_1(kCh1Rx2Led);
+ aCh2RxAmpEn <= lRxCh2_1(kCh1RxAmpEn);
+ aCh2RxMixerEn <= lRxCh2_1(kCh1RxMixerEn);
+ aCh2RxLna1En <= lRxCh2_1(kCh1RxLna1En);
+ aCh2RxLna2En <= lRxCh2_1(kCh1RxLna2En);
+ aMkRx2En <= lRxCh2_1(kCh1MykEnRx);
+
+
+end RTL;
+
+
+
+
+--XmlParse xml_on
+--<top name="MgCpld"></top>
+--<regmap name="MgCpld">
+-- <group name="PsSpi_CpldRegisters" order="1">
+--
+-- <info>
+-- These registers are accessed via the PS SPI interface to the CPLD. They are all
+-- internal to the CPLD. The SPI format is 24 bits total. On MOSI, shift (msb first)
+-- Rd/!Wt | Addr(6:0) | Data(15:0) (lsb). The SPI clock {b}MUST{/b} idle LOW before
+-- and after the transaction. CPOL=CPHA=0. To access these registers, use the chip
+-- select line named "CPLD-PS-SPI-SLE-33" as an active-low select.
+-- </info>
+--
+-- <register name="SignatureReg" size="16" offset="0x00" attributes="Readable">
+-- <info>
+-- This register contains the device signature.
+-- </info>
+-- <bitfield name="ProductSignature" range="15..0">
+-- <info>
+-- Represents the product family name/number. This field reads back as
+-- 0xCAFE.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- <register name="MinorRevReg" size="16" offset="0x01" attributes="Readable">
+-- <info>
+-- This register contains the device revision numeric code.
+-- </info>
+-- <bitfield name="CpldMinorRevision" range="15..0">
+-- <info>
+-- Contains minor revision code (0,1,2,...).
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- <register name="MajorRevReg" size="16" offset="0x02" attributes="Readable">
+-- <info>
+-- This register contains the major revision value.
+-- </info>
+-- <bitfield name="CpldMajorRevision" range="15..0">
+-- <info>
+-- Contains major revision code.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- <register name="BuildCodeLSB" size="16" offset="0x03" attributes="Readable">
+-- <info>
+-- Build code... right now it's the date it was built. LSB in this register.
+-- </info>
+-- <bitfield name="BuildCodeHH" range="7..0">
+-- <info>
+-- Contains build code hour code.
+-- </info>
+-- </bitfield>
+-- <bitfield name="BuildCodeDD" range="15..8">
+-- <info>
+-- Contains build code day code.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- <register name="BuildCodeMSB" size="16" offset="0x04" attributes="Readable">
+-- <info>
+-- Build code... right now it's the date it was built. MSB in this register.
+-- </info>
+-- <bitfield name="BuildCodeMM" range="7..0">
+-- <info>
+-- Contains build code month code.
+-- </info>
+-- </bitfield>
+-- <bitfield name="BuildCodeYY" range="15..8">
+-- <info>
+-- Contains build code revision year code.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- <register name="Scratch" size="16" offset="0x05" attributes="Readable|Writable">
+-- <info>
+-- </info>
+-- <bitfield name="ScratchVal" range="15..0">
+-- <info>
+-- Contains scratch value for testing. The state of this register has
+-- no effect on any other operation in the CPLD.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+--
+-- <register name="CpldControl" size="16" offset="0x10" attributes="Writable">
+-- <info>
+-- </info>
+-- <bitfield name="CpldReset" range="0">
+-- <info>
+-- Asserting this bit resets all the CPLD logic.
+-- This reset will return all registers on the PS SPI interface to their default
+-- state! To use this reset correctly, first write CpldReset to '1', then write
+-- it to '0'. Registers will be reset on the _falling_ edge of CpldReset.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+--
+-- <register name="LmkControl" size="16" offset="0x11" attributes="Readable|Writable">
+-- <info>
+-- </info>
+-- <bitfield name="VcxoControl" range="4">
+-- <info>
+-- Setting this bit to '0' will allow the Phase DAC to exclusively control the
+-- VCXO voltage. Defaults to '1', which allows the Phase DAC to adjust the
+-- voltage (but the LMK still has control as well).
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- <register name="LoStatus" size="16" offset="0x12" attributes="Readable">
+-- <info>
+-- </info>
+-- <bitfield name="RxLoLockDetect" range="0" attributes="Readable">
+-- <info>
+-- Live lock detect status from the RX LO.
+-- </info>
+-- </bitfield>
+-- <bitfield name="TxLoLockDetect" range="4" attributes="Readable">
+-- <info>
+-- Live lock detect status from the TX LO.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- <register name="MykonosControl" size="16" offset="0x13" attributes="Readable|Writable">
+-- <info>
+-- </info>
+-- <bitfield name="MykonosReset" range="0">
+-- <info>
+-- Drives the Mykonos hard reset line. Defaults to de-asserted. Write a '1' to
+-- assert the reset, and a '0' to de-assert.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- </group>
+--
+--
+--
+-- <group name="PlSpi_FrontEndControl" order="2">
+--
+-- <info>
+-- These registers are accessed via the PL SPI interface to the CPLD. They are all
+-- internal to the CPLD. The SPI format is 24 bits total. On MOSI, shift (msb first)
+-- Rd/!Wt | Addr(6:0) | Data(15:0) (lsb). The SPI clock {b}MUST{/b} idle LOW before
+-- and after the transaction. CPOL=CPHA=0. To access these registers, use the chip
+-- select line named "CPLD-PL-SPI-LE-25" as an active-low select. {br}{br}
+--
+-- The ATR bits ultimately control which of these registers actually control
+-- the RF front end.
+-- </info>
+--
+-- <register name="PlScratch" size="16" offset="0x40" attributes="Readable|Writable">
+-- <bitfield name="PlScratchVal" range="15..0">
+-- <info>
+-- Contains scratch value for testing. The state of this register has no effect
+-- on any other operation in the CPLD.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- <register name="PlCpldControl" size="16" offset="0x41" attributes="Writable">
+-- <info>
+-- </info>
+-- <bitfield name="PlCpldReset" range="0">
+-- <info>
+-- Asserting this bit resets all the CPLD logic on the PL SPI interface.
+-- This reset will return all registers to their default state! To use this
+-- reset correctly, first write PlCpldReset to '1', then write it to '0'.
+-- Registers will be reset on the _falling_ edge of PlCpldReset.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+--
+--
+-- <enumeratedtype name="TrxSwitch">
+-- <value name="FromLowerFilterBankTxSw1" integer="0"/>
+-- <value name="FromTxUpperFilterBankLp6400MHz" integer="1"/>
+-- <value name="RxChannelPath" integer="2"/>
+-- <value name="BypassPathToTxSw3" integer="3"/>
+-- </enumeratedtype>
+--
+-- <enumeratedtype name="TxSwitch1">
+-- <value name="ShutdownTxSw1" integer="0"/>
+-- <value name="FromTxFilterLp1700MHz" integer="1"/>
+-- <value name="FromTxFilterLp3400MHz" integer="2"/>
+-- <value name="FromTxFilterLp0800MHz" integer="3"/>
+-- </enumeratedtype>
+--
+-- <enumeratedtype name="TxSwitch2">
+-- <value name="ToTxFilterLp3400MHz" integer="1"/>
+-- <value name="ToTxFilterLp1700MHz" integer="2"/>
+-- <value name="ToTxFilterLp0800MHz" integer="4"/>
+-- <value name="ToTxFilterLp6400MHz" integer="8"/>
+-- </enumeratedtype>
+--
+-- <enumeratedtype name="TxSwitch3">
+-- <value name="ToTxFilterBanks" integer="0"/>
+-- <value name="BypassPathToTrxSw" integer="1"/>
+-- </enumeratedtype>
+--
+--
+-- <register name="TxCh1_Idle" size="16" offset="0x50" attributes="Readable|Writable">
+-- <info>
+-- Load this register with the front-end configuration for channel TX 1 when the
+-- ATR bits are configured: TX = 0, RX = don't-care.
+-- </info>
+-- <bitfield name="Ch1TxSw1" type="TxSwitch1" range="1..0">
+-- <info>
+-- Controls Switch 1. Filter bank receive switch.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1TxSw2" type="TxSwitch2" range="5..2">
+-- <info>
+-- Controls Switch 2. Filter bank distribution switch.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1TxSw3" type="TxSwitch3" range="6">
+-- <info>
+-- Controls Switch 3. Bypasses the filter bank and PA, or doesn't.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1TxLowbandMixerPathSelect" range="7">
+-- <info>
+-- Controls Switches 4 and 5. Write a '1' to select the Lowband Mixer path.
+-- Writing '0' will select the bypass path around the mixer. Default is '0'. Note:
+-- Individual control over these switches was removed as an optimization to
+-- allow all TX controls to fit in one 16 bit register.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1TxMixerEn" range="8">
+-- <info>
+-- Write a '1' to enable the lowband mixer. Note that Ch1TxLowbandMixerPathSelect
+-- must be properly configured to select the mixer path.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1TxAmpEn" range="9">
+-- <info>
+-- Write a '1' to enable the TX path Amp in between TX switches 3 and 4. The path
+-- (from Mykonos) is: TxSw4 -> Amp -> DSA -> TxSw3.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1TxPaEn" range="10">
+-- <info>
+-- Write a '1' to enable the TX path PA in between TX switches 2 and 3.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1SwTrx" type="TrxSwitch" range="12..11">
+-- <info>
+-- TRX switch control.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1TxLed" range="13">
+-- <info>
+-- Red/Green combo LED for the TRX channel.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1MykEnTx" range="14">
+-- <info>
+-- Drives the Mykonos input port TX1_ENABLE.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- <register name="TxCh1_TxOn" size="16" offset="0x53" attributes="Readable|Writable">
+-- <info>
+-- Load this register with the front-end configuration for channel TX 1 when the
+-- ATR bits are configured: TX = 1, RX = don't-care. The bitfields are the same
+-- as for the Tx1_Off register.
+-- </info>
+-- </register>
+--
+-- <register name="TxCh2_Idle" size="16" offset="0x60" attributes="Readable|Writable">
+-- <info>
+-- Load this register with the front-end configuration for channel TX 2 when the
+-- ATR bits are configured: TX = 0, RX = don't-care. The bitfields are the same
+-- as for the Tx1_Off register.
+-- </info>
+-- </register>
+--
+-- <register name="TxCh2_TxOn" size="16" offset="0x63" attributes="Readable|Writable">
+-- <info>
+-- Load this register with the front-end configuration for channel TX 2 when the
+-- ATR bits are configured: TX = 1, RX = don't-care. The bitfields are the same
+-- as for the Tx1_Off register.
+-- </info>
+-- </register>
+--
+--
+-- <enumeratedtype name="Rx1Switch1">
+-- <value name="TxRxInput" integer="0"/>
+-- <value name="RxLoCalInput" integer="1"/>
+-- <value name="TrxSwitchOutput" integer="2"/>
+-- <value name="Rx2Input" integer="3"/>
+-- </enumeratedtype>
+--
+-- <enumeratedtype name="Rx1Switch2">
+-- <value name="ShutdownSw2" integer="0"/>
+-- <value name="LowerFilterBankToSwitch3" integer="1"/>
+-- <value name="BypassPathToSwitch6" integer="2"/>
+-- <value name="UpperFilterBankToSwitch4" integer="3"/>
+-- </enumeratedtype>
+--
+-- <enumeratedtype name="Rx1Switch3">
+-- <value name="Filter2100x2850MHz" integer="0"/>
+-- <value name="Filter0490LpMHz" integer="1"/>
+-- <value name="Filter1600x2250MHz" integer="2"/>
+-- <value name="Filter0440x0530MHz" integer="4"/>
+-- <value name="Filter0650x1000MHz" integer="5"/>
+-- <value name="Filter1100x1575MHz" integer="6"/>
+-- <value name="ShutdownSw3" integer="7"/>
+-- </enumeratedtype>
+--
+-- <enumeratedtype name="Rx1Switch4">
+-- <value name="Filter2100x2850MHzFrom" integer="1"/>
+-- <value name="Filter1600x2250MHzFrom" integer="2"/>
+-- <value name="Filter2700HpMHz" integer="4"/>
+-- </enumeratedtype>
+--
+-- <enumeratedtype name="Rx1Switch5">
+-- <value name="Filter0440x0530MHzFrom" integer="1"/>
+-- <value name="Filter1100x1575MHzFrom" integer="2"/>
+-- <value name="Filter0490LpMHzFrom" integer="4"/>
+-- <value name="Filter0650x1000MHzFrom" integer="8"/>
+-- </enumeratedtype>
+--
+-- <enumeratedtype name="Rx1Switch6">
+-- <value name="LowerFilterBankFromSwitch5" integer="1"/>
+-- <value name="UpperFilterBankFromSwitch4" integer="2"/>
+-- <value name="BypassPathFromSwitch2" integer="4"/>
+-- </enumeratedtype>
+--
+--
+--
+-- <register name="RxCh1_0_Idle" size="16" offset="0x51" attributes="Readable|Writable">
+-- <info>
+-- Load this register with the front-end configuration for channel RX 1 when the
+-- ATR bits are configured: TX = don't-care, RX = 0.
+-- </info>
+-- <bitfield name="Ch1RxSw1" type="Rx1Switch1" range="1..0">
+-- <info>
+-- Controls Switch 1. Selects between the cal, bypass, RX2, and TRX paths.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1RxSw2" type="Rx1Switch2" range="3..2">
+-- <info>
+-- Controls Switch 2. First filter switch. Selects between bypass path and
+-- the upper/lower filter banks.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1RxSw3" type="Rx1Switch3" range="6..4">
+-- <info>
+-- Controls Switch 3. Lower filter bank transmit switch.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1RxSw4" type="Rx1Switch4" range="9..7">
+-- <info>
+-- Controls Switch 4. Upper filter bank receive switch.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1RxSw5" type="Rx1Switch5" range="13..10">
+-- <info>
+-- Controls Switch 5. Lower filter bank receive switch.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- <register name="RxCh1_1_Idle" size="16" offset="0x52" attributes="Readable|Writable">
+-- <info>
+-- Load this register with the front-end configuration for channel RX 1 when the
+-- ATR bits are configured: TX = don't-care, RX = 0.
+-- </info>
+-- <bitfield name="Ch1RxSw6" type="Rx1Switch6" range="2..0">
+-- <info>
+-- Controls Switch 6. Selects between the upper and lower filter banks and
+-- bypass path.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1RxLowbandMixerPathSelect" range="3">
+-- <info>
+-- Controls Switches 7 and 8. Write a '1' to select the Lowband Mixer path.
+-- Writing '0' will select the bypass path around the mixer. Default is '0'. Note:
+-- Individual control over these switches was removed as an optimization to
+-- allow all TX controls to fit in one 16 bit register... so the same was done
+-- for the RX path for continuity.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1RxMixerEn" range="4">
+-- <info>
+-- Write a '1' to enable the lowband mixer. Note that Ch1RxLowbandMixerPathSelect
+-- must be properly configured to select the mixer path.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1RxAmpEn" range="5">
+-- <info>
+-- Write a '1' to enable the RX path Amp directly before the Mykonos inputs.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1RxLna1En" range="6">
+-- <info>
+-- Write a '1' to enable the RX path LNA1 between RxSw4 and RxSw6.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1RxLna2En" range="7">
+-- <info>
+-- Write a '1' to enable the RX path LNA2 between RxSw5 and RxSw6.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1Rx2Led" range="8">
+-- <info>
+-- Green LED for RX2 channel.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1RxLed" range="9">
+-- <info>
+-- Red/Green combo LED for the TRX channel.
+-- </info>
+-- </bitfield>
+-- <bitfield name="Ch1MykEnRx" range="10">
+-- <info>
+-- Drives the Mykonos input port RX1_ENABLE.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- <register name="RxCh1_0_RxOn" size="16" offset="0x54" attributes="Readable|Writable">
+-- <info>
+-- Load this register with the front-end configuration for channel RX 1 when the
+-- ATR bits are configured: TX = don't-care, RX = 1. The bitfields are the same
+-- as for the RxCh1_0_Idle register.
+-- </info>
+-- </register>
+--
+-- <register name="RxCh1_1_RxOn" size="16" offset="0x55" attributes="Readable|Writable">
+-- <info>
+-- Load this register with the front-end configuration for channel RX 1 when the
+-- ATR bits are configured: TX = don't-care, RX = 1. The bitfields are the same
+-- as for the RxCh1_1_Idle register.
+-- </info>
+-- </register>
+--
+-- <register name="RxCh2_0_Idle" size="16" offset="0x61" attributes="Readable|Writable">
+-- <info>
+-- Load this register with the front-end configuration for channel RX 2 when the
+-- ATR bits are configured: TX = don't-care, RX = 0. The bitfields are the same
+-- as for the RxCh1_0_Idle register.
+-- </info>
+-- </register>
+--
+-- <register name="RxCh2_1_Idle" size="16" offset="0x62" attributes="Readable|Writable">
+-- <info>
+-- Load this register with the front-end configuration for channel RX 2 when the
+-- ATR bits are configured: TX = don't-care, RX = 0. The bitfields are the same
+-- as for the RxCh1_1_Idle register.
+-- </info>
+-- </register>
+--
+-- <register name="RxCh2_0_RxOn" size="16" offset="0x64" attributes="Readable|Writable">
+-- <info>
+-- Load this register with the front-end configuration for channel RX 2 when the
+-- ATR bits are configured: TX = don't-care, RX = 1. The bitfields are the same
+-- as for the RxCh1_0_Idle register.
+-- </info>
+-- </register>
+--
+-- <register name="RxCh2_1_RxOn" size="16" offset="0x65" attributes="Readable|Writable">
+-- <info>
+-- Load this register with the front-end configuration for channel RX 2 when the
+-- ATR bits are configured: TX = don't-care, RX = 1. The bitfields are the same
+-- as for the RxCh1_1_Idle register.
+-- </info>
+-- </register>
+--
+-- </group>
+--
+--</regmap>
+--XmlParse xml_off
+
+
+
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/db0_pins.xdc b/fpga/usrp3/top/n3xx/dboards/mg/db0_pins.xdc
new file mode 100644
index 000000000..b89183a2e
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/db0_pins.xdc
@@ -0,0 +1,156 @@
+#
+# Copyright 2017 Ettus Research, A National Instruments Company
+# SPDX-License-Identifier: LGPL-3.0
+#
+# Daughterboard Pin Definitions for the N310.
+#
+
+## TDC : ################################################################################
+## Bank 10, 2.5V (DB A)
+#########################################################################################
+
+set_property PACKAGE_PIN AB15 [get_ports {UNUSED_PIN_TDCA_0}]
+set_property PACKAGE_PIN AB14 [get_ports {UNUSED_PIN_TDCA_1}]
+set_property PACKAGE_PIN AB16 [get_ports {UNUSED_PIN_TDCA_2}]
+set_property PACKAGE_PIN AB17 [get_ports {UNUSED_PIN_TDCA_3}]
+set_property IOSTANDARD LVCMOS25 [get_ports {UNUSED_PIN_TDCA_*}]
+set_property IOB TRUE [get_ports {UNUSED_PIN_TDCA_*}]
+
+## USRP IO A : ##########################################################################
+## Banks 10/33
+#########################################################################################
+
+## HP GPIO, Bank 33, 1.8V
+
+set_property PACKAGE_PIN G1 [get_ports {DBA_CPLD_PS_SPI_LE}]
+set_property PACKAGE_PIN H2 [get_ports {DBA_CPLD_PS_SPI_SCLK}]
+set_property PACKAGE_PIN D1 [get_ports {DBA_CH1_TX_DSA_DATA[5]}]
+# set_property PACKAGE_PIN E1 [get_ports {nc}]
+set_property PACKAGE_PIN H1 [get_ports {DBA_CPLD_PS_SPI_ADDR[0]}]
+set_property PACKAGE_PIN J1 [get_ports {DBA_CPLD_PS_SPI_ADDR[1]}]
+set_property PACKAGE_PIN A5 [get_ports {DBA_CH1_TX_DSA_DATA[3]}]
+set_property PACKAGE_PIN A4 [get_ports {DBA_CH1_TX_DSA_DATA[4]}]
+set_property PACKAGE_PIN F5 [get_ports {DBA_CPLD_PS_SPI_SDO}]
+set_property PACKAGE_PIN E5 [get_ports {DBA_CPLD_PS_SPI_SDI}]
+set_property PACKAGE_PIN E3 [get_ports {DBA_CH1_RX_DSA_DATA[0]}]
+set_property PACKAGE_PIN E2 [get_ports {DBA_CH1_RX_DSA_DATA[1]}]
+set_property PACKAGE_PIN A3 [get_ports {DBA_CH1_TX_DSA_DATA[2]}]
+set_property PACKAGE_PIN A2 [get_ports {DBA_CH1_TX_DSA_DATA[1]}]
+set_property PACKAGE_PIN K1 [get_ports {DBA_ATR_RX_1}]
+set_property PACKAGE_PIN L1 [get_ports {DBA_ATR_TX_2}]
+set_property PACKAGE_PIN C4 [get_ports {DBA_CH1_TX_DSA_DATA[0]}]
+set_property PACKAGE_PIN C3 [get_ports {DBA_CH1_RX_DSA_DATA[5]}]
+set_property PACKAGE_PIN F4 [get_ports {DBA_ATR_TX_1}]
+set_property PACKAGE_PIN F3 [get_ports {DBA_ATR_RX_2}]
+# set_property PACKAGE_PIN B1 [get_ports {nc}]
+set_property PACKAGE_PIN B2 [get_ports {DBA_CH1_RX_DSA_DATA[3]}]
+set_property PACKAGE_PIN C1 [get_ports {DBA_CH1_RX_DSA_DATA[4]}]
+set_property PACKAGE_PIN C2 [get_ports {DBA_CH1_RX_DSA_DATA[2]}]
+
+## HR GPIO, Bank 10, 2.5V
+
+set_property PACKAGE_PIN AG12 [get_ports {DBA_MYK_SYNC_IN_n}]
+set_property PACKAGE_PIN AH12 [get_ports {DBA_CPLD_PL_SPI_ADDR[0]}]
+set_property PACKAGE_PIN AJ13 [get_ports {DBA_MYK_SPI_SDO}]
+set_property PACKAGE_PIN AJ14 [get_ports {DBA_MYK_SPI_SDIO}]
+set_property PACKAGE_PIN AG15 [get_ports {DBA_CPLD_PL_SPI_ADDR[1]}]
+set_property PACKAGE_PIN AF15 [get_ports {DBA_CH2_TX_DSA_DATA[5]}]
+set_property PACKAGE_PIN AH13 [get_ports {DBA_CPLD_JTAG_TDI}]
+set_property PACKAGE_PIN AH14 [get_ports {DBA_CPLD_JTAG_TDO}]
+set_property PACKAGE_PIN AK15 [get_ports {DBA_MYK_GPIO_1}]
+set_property PACKAGE_PIN AJ15 [get_ports {DBA_MYK_GPIO_4}]
+set_property PACKAGE_PIN AH16 [get_ports {DBA_CH2_TX_DSA_DATA[4]}]
+set_property PACKAGE_PIN AH17 [get_ports {DBA_CH2_TX_DSA_DATA[3]}]
+set_property PACKAGE_PIN AE12 [get_ports {DBA_MYK_SYNC_OUT_n}]
+set_property PACKAGE_PIN AF12 [get_ports {DBA_CPLD_PL_SPI_SDO}]
+set_property PACKAGE_PIN AK12 [get_ports {DBA_MYK_GPIO_13}]
+set_property PACKAGE_PIN AK13 [get_ports {DBA_MYK_GPIO_0}]
+set_property PACKAGE_PIN AK16 [get_ports {DBA_MYK_INTRQ}]
+set_property PACKAGE_PIN AJ16 [get_ports {DBA_CH2_TX_DSA_DATA[2]}]
+set_property PACKAGE_PIN AH18 [get_ports {DBA_CH2_TX_DSA_DATA[0]}]
+set_property PACKAGE_PIN AJ18 [get_ports {DBA_CH2_TX_DSA_DATA[1]}]
+set_property PACKAGE_PIN AF14 [get_ports {DBA_FPGA_CLK_P}]
+set_property PACKAGE_PIN AG14 [get_ports {DBA_FPGA_CLK_N}]
+set_property PACKAGE_PIN AG17 [get_ports {DBA_FPGA_SYSREF_P}]
+set_property PACKAGE_PIN AG16 [get_ports {DBA_FPGA_SYSREF_N}]
+set_property PACKAGE_PIN AD15 [get_ports {DBA_CH2_RX_DSA_DATA[3]}]
+set_property PACKAGE_PIN AD16 [get_ports {DBA_CH2_RX_DSA_DATA[5]}]
+set_property PACKAGE_PIN AE13 [get_ports {DBA_CPLD_JTAG_TMS}]
+set_property PACKAGE_PIN AF13 [get_ports {DBA_CPLD_JTAG_TCK}]
+set_property PACKAGE_PIN AE15 [get_ports {DBA_MYK_GPIO_15}]
+set_property PACKAGE_PIN AE16 [get_ports {DBA_MYK_SPI_CS_n}]
+set_property PACKAGE_PIN AF17 [get_ports {DBA_CH2_RX_DSA_DATA[1]}]
+set_property PACKAGE_PIN AF18 [get_ports {DBA_CH2_RX_DSA_DATA[2]}]
+set_property PACKAGE_PIN AC16 [get_ports {DBA_CPLD_PL_SPI_LE}]
+set_property PACKAGE_PIN AC17 [get_ports {DBA_CPLD_PL_SPI_SDI}]
+set_property PACKAGE_PIN AD13 [get_ports {DBA_MYK_GPIO_12}]
+set_property PACKAGE_PIN AD14 [get_ports {DBA_MYK_GPIO_14}]
+set_property PACKAGE_PIN AE17 [get_ports {DBA_MYK_SPI_SCLK}]
+set_property PACKAGE_PIN AE18 [get_ports {DBA_MYK_GPIO_3}]
+set_property PACKAGE_PIN AB12 [get_ports {DBA_CH2_RX_DSA_DATA[0]}]
+set_property PACKAGE_PIN AC12 [get_ports {DBA_CH2_RX_DSA_DATA[4]}]
+set_property PACKAGE_PIN AC13 [get_ports {DBA_CPLD_PL_SPI_ADDR[2]}]
+set_property PACKAGE_PIN AC14 [get_ports {DBA_CPLD_PL_SPI_SCLK}]
+
+# set_property PACKAGE_PIN AB25 [get_ports {DBA_SWITCHER_CLOCK}]
+# set_property IOSTANDARD LVCMOS33 [get_ports {DBA_SWITCHER_CLOCK}]
+# set_property DRIVE 4 [get_ports {DBA_SWITCHER_CLOCK}]
+# set_property SLEW SLOW [get_ports {DBA_SWITCHER_CLOCK}]
+
+# During SI measurements with default drive strength, many of the FPGA-driven lines to
+# the DB were showing high over/undershoot. Therefore for single-ended lines to the DBs
+# we are decreasing the drive strength to the minimum value (4mA) and explicitly
+# declaring the (default) slew rate as SLOW.
+
+set UsrpIoAHpPinsSe [get_ports {DBA_CPLD_PS_* \
+ DBA_CH1_* \
+ DBA_ATR*}]
+set_property IOSTANDARD LVCMOS18 $UsrpIoAHpPinsSe
+set_property DRIVE 4 $UsrpIoAHpPinsSe
+set_property SLEW SLOW $UsrpIoAHpPinsSe
+
+set UsrpIoAHrPinsSe [get_ports {DBA_MYK_SPI_* \
+ DBA_MYK_INTRQ \
+ DBA_MYK_SYNC* \
+ DBA_MYK_GPIO* \
+ DBA_CPLD_PL_* \
+ DBA_CPLD_JTAG_* \
+ DBA_CH2*}]
+set_property IOSTANDARD LVCMOS25 $UsrpIoAHrPinsSe
+set_property DRIVE 4 $UsrpIoAHrPinsSe
+set_property SLEW SLOW $UsrpIoAHrPinsSe
+
+set UsrpIoAHrPinsDiff [get_ports {DBA_FPGA_CLK_* \
+ DBA_FPGA_SYSREF_*}]
+set_property IOSTANDARD LVDS_25 $UsrpIoAHrPinsDiff
+set_property DIFF_TERM TRUE $UsrpIoAHrPinsDiff
+
+# Do not allow the DSA lines to float... give them a weak pull if undriven.
+set_property PULLUP TRUE [get_ports {DBA_CH*_*X_DSA_DATA[*]}]
+
+
+### MGTs, Bank 112
+
+set_property PACKAGE_PIN N8 [get_ports {USRPIO_A_MGTCLK_P}]
+set_property PACKAGE_PIN N7 [get_ports {USRPIO_A_MGTCLK_N}]
+
+# This mapping uses the TX pins as the "master" and mimics RX off of them so Vivado
+# places the transceivers in the correct places. The mixup in lanes is accounted for
+# in the Mykonos lane crossbar settings.
+set_property PACKAGE_PIN V6 [get_ports {USRPIO_A_RX_P[0]}]
+set_property PACKAGE_PIN V5 [get_ports {USRPIO_A_RX_N[0]}]
+set_property PACKAGE_PIN U4 [get_ports {USRPIO_A_RX_P[1]}]
+set_property PACKAGE_PIN U3 [get_ports {USRPIO_A_RX_N[1]}]
+set_property PACKAGE_PIN T6 [get_ports {USRPIO_A_RX_P[2]}]
+set_property PACKAGE_PIN T5 [get_ports {USRPIO_A_RX_N[2]}]
+set_property PACKAGE_PIN P6 [get_ports {USRPIO_A_RX_P[3]}]
+set_property PACKAGE_PIN P5 [get_ports {USRPIO_A_RX_N[3]}]
+
+set_property PACKAGE_PIN T2 [get_ports {USRPIO_A_TX_P[0]}]
+set_property PACKAGE_PIN T1 [get_ports {USRPIO_A_TX_N[0]}]
+set_property PACKAGE_PIN R4 [get_ports {USRPIO_A_TX_P[1]}]
+set_property PACKAGE_PIN R3 [get_ports {USRPIO_A_TX_N[1]}]
+set_property PACKAGE_PIN P2 [get_ports {USRPIO_A_TX_P[2]}]
+set_property PACKAGE_PIN P1 [get_ports {USRPIO_A_TX_N[2]}]
+set_property PACKAGE_PIN N4 [get_ports {USRPIO_A_TX_P[3]}]
+set_property PACKAGE_PIN N3 [get_ports {USRPIO_A_TX_N[3]}]
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/db1_pins.xdc b/fpga/usrp3/top/n3xx/dboards/mg/db1_pins.xdc
new file mode 100644
index 000000000..f95051ba7
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/db1_pins.xdc
@@ -0,0 +1,156 @@
+#
+# Copyright 2017 Ettus Research, A National Instruments Company
+# SPDX-License-Identifier: LGPL-3.0
+#
+# Daughterboard Pin Definitions for the N310.
+#
+
+## TDC : ################################################################################
+## Bank 11, 2.5V (DB B)
+#########################################################################################
+
+set_property PACKAGE_PIN W21 [get_ports {UNUSED_PIN_TDCB_0}]
+set_property PACKAGE_PIN Y21 [get_ports {UNUSED_PIN_TDCB_1}]
+set_property PACKAGE_PIN Y22 [get_ports {UNUSED_PIN_TDCB_2}]
+set_property PACKAGE_PIN Y23 [get_ports {UNUSED_PIN_TDCB_3}]
+set_property IOSTANDARD LVCMOS25 [get_ports {UNUSED_PIN_TDCB_*}]
+set_property IOB TRUE [get_ports {UNUSED_PIN_TDCB_*}]
+
+### USRP IO B : #########################################################################
+## Bank 11/33
+#########################################################################################
+
+## HP GPIO, Bank 33, 1.8V
+
+set_property PACKAGE_PIN J4 [get_ports {DBB_CPLD_PS_SPI_LE}]
+set_property PACKAGE_PIN J3 [get_ports {DBB_CPLD_PS_SPI_SCLK}]
+set_property PACKAGE_PIN D4 [get_ports {DBB_CH1_TX_DSA_DATA[5]}]
+# set_property PACKAGE_PIN D3 [get_ports {nc}]
+set_property PACKAGE_PIN K2 [get_ports {DBB_CPLD_PS_SPI_ADDR[0]}]
+set_property PACKAGE_PIN K3 [get_ports {DBB_CPLD_PS_SPI_ADDR[1]}]
+set_property PACKAGE_PIN B5 [get_ports {DBB_CH1_TX_DSA_DATA[3]}]
+set_property PACKAGE_PIN B4 [get_ports {DBB_CH1_TX_DSA_DATA[4]}]
+set_property PACKAGE_PIN G5 [get_ports {DBB_CPLD_PS_SPI_SDO}]
+set_property PACKAGE_PIN G4 [get_ports {DBB_CPLD_PS_SPI_SDI}]
+set_property PACKAGE_PIN J5 [get_ports {DBB_CH1_RX_DSA_DATA[0]}]
+set_property PACKAGE_PIN K5 [get_ports {DBB_CH1_RX_DSA_DATA[1]}]
+set_property PACKAGE_PIN D5 [get_ports {DBB_CH1_TX_DSA_DATA[2]}]
+set_property PACKAGE_PIN E6 [get_ports {DBB_CH1_TX_DSA_DATA[1]}]
+set_property PACKAGE_PIN L3 [get_ports {DBB_ATR_RX_1}]
+set_property PACKAGE_PIN L2 [get_ports {DBB_ATR_TX_2}]
+set_property PACKAGE_PIN G6 [get_ports {DBB_CH1_TX_DSA_DATA[0]}]
+set_property PACKAGE_PIN H6 [get_ports {DBB_CH1_RX_DSA_DATA[5]}]
+set_property PACKAGE_PIN H4 [get_ports {DBB_ATR_TX_1}]
+set_property PACKAGE_PIN H3 [get_ports {DBB_ATR_RX_2}]
+# set_property PACKAGE_PIN F2 [get_ports {nc}]
+set_property PACKAGE_PIN G2 [get_ports {DBB_CH1_RX_DSA_DATA[3]}]
+set_property PACKAGE_PIN J6 [get_ports {DBB_CH1_RX_DSA_DATA[4]}]
+set_property PACKAGE_PIN K6 [get_ports {DBB_CH1_RX_DSA_DATA[2]}]
+
+## HR GPIO, Bank 10, 2.5V
+
+set_property PACKAGE_PIN AK17 [get_ports {DBB_MYK_SYNC_IN_n}]
+set_property PACKAGE_PIN AK18 [get_ports {DBB_CPLD_PL_SPI_ADDR[0]}]
+set_property PACKAGE_PIN AK21 [get_ports {DBB_MYK_SPI_SDO}]
+set_property PACKAGE_PIN AJ21 [get_ports {DBB_MYK_SPI_SDIO}]
+set_property PACKAGE_PIN AF19 [get_ports {DBB_CPLD_PL_SPI_ADDR[1]}]
+set_property PACKAGE_PIN AG19 [get_ports {DBB_CH2_TX_DSA_DATA[5]}]
+set_property PACKAGE_PIN AH19 [get_ports {DBB_CPLD_JTAG_TDI}]
+set_property PACKAGE_PIN AJ19 [get_ports {DBB_CPLD_JTAG_TDO}]
+set_property PACKAGE_PIN AK22 [get_ports {DBB_MYK_GPIO_1}]
+set_property PACKAGE_PIN AK23 [get_ports {DBB_MYK_GPIO_4}]
+set_property PACKAGE_PIN AF20 [get_ports {DBB_CH2_TX_DSA_DATA[4]}]
+set_property PACKAGE_PIN AG20 [get_ports {DBB_CH2_TX_DSA_DATA[3]}]
+set_property PACKAGE_PIN AF23 [get_ports {DBB_MYK_SYNC_OUT_n}]
+set_property PACKAGE_PIN AF24 [get_ports {DBB_CPLD_PL_SPI_SDO}]
+set_property PACKAGE_PIN AK20 [get_ports {DBB_MYK_GPIO_13}]
+set_property PACKAGE_PIN AJ20 [get_ports {DBB_MYK_GPIO_0}]
+set_property PACKAGE_PIN AJ23 [get_ports {DBB_MYK_INTRQ}]
+set_property PACKAGE_PIN AJ24 [get_ports {DBB_CH2_TX_DSA_DATA[2]}]
+set_property PACKAGE_PIN AG24 [get_ports {DBB_CH2_TX_DSA_DATA[0]}]
+set_property PACKAGE_PIN AG25 [get_ports {DBB_CH2_TX_DSA_DATA[1]}]
+set_property PACKAGE_PIN AG21 [get_ports {DBB_FPGA_CLK_P}]
+set_property PACKAGE_PIN AH21 [get_ports {DBB_FPGA_CLK_N}]
+set_property PACKAGE_PIN AE22 [get_ports {DBB_FPGA_SYSREF_P}]
+set_property PACKAGE_PIN AF22 [get_ports {DBB_FPGA_SYSREF_N}]
+set_property PACKAGE_PIN AJ25 [get_ports {DBB_CH2_RX_DSA_DATA[3]}]
+set_property PACKAGE_PIN AK25 [get_ports {DBB_CH2_RX_DSA_DATA[5]}]
+set_property PACKAGE_PIN AB21 [get_ports {DBB_CPLD_JTAG_TMS}]
+set_property PACKAGE_PIN AB22 [get_ports {DBB_CPLD_JTAG_TCK}]
+set_property PACKAGE_PIN AD23 [get_ports {DBB_MYK_GPIO_15}]
+set_property PACKAGE_PIN AE23 [get_ports {DBB_MYK_SPI_CS_n}]
+set_property PACKAGE_PIN AB24 [get_ports {DBB_CH2_RX_DSA_DATA[1]}]
+set_property PACKAGE_PIN AA24 [get_ports {DBB_CH2_RX_DSA_DATA[2]}]
+set_property PACKAGE_PIN AG22 [get_ports {DBB_CPLD_PL_SPI_LE}]
+set_property PACKAGE_PIN AH22 [get_ports {DBB_CPLD_PL_SPI_SDI}]
+set_property PACKAGE_PIN AD21 [get_ports {DBB_MYK_GPIO_12}]
+set_property PACKAGE_PIN AE21 [get_ports {DBB_MYK_GPIO_14}]
+set_property PACKAGE_PIN AC22 [get_ports {DBB_MYK_SPI_SCLK}]
+set_property PACKAGE_PIN AC23 [get_ports {DBB_MYK_GPIO_3}]
+set_property PACKAGE_PIN AC24 [get_ports {DBB_CH2_RX_DSA_DATA[0]}]
+set_property PACKAGE_PIN AD24 [get_ports {DBB_CH2_RX_DSA_DATA[4]}]
+set_property PACKAGE_PIN AH23 [get_ports {DBB_CPLD_PL_SPI_ADDR[2]}]
+set_property PACKAGE_PIN AH24 [get_ports {DBB_CPLD_PL_SPI_SCLK}]
+
+# set_property PACKAGE_PIN AA25 [get_ports DBB_SWITCHER_CLOCK]
+# set_property IOSTANDARD LVCMOS33 [get_ports DBB_SWITCHER_CLOCK]
+# set_property DRIVE 4 [get_ports DBB_SWITCHER_CLOCK]
+# set_property SLEW SLOW [get_ports DBB_SWITCHER_CLOCK]
+
+# During SI measurements with default drive strength, many of the FPGA-driven lines to
+# the DB were showing high over/undershoot. Therefore for single-ended lines to the DBs
+# we are decreasing the drive strength to the minimum value (4mA) and explicitly
+# declaring the (default) slew rate as SLOW.
+
+set UsrpIoBHpPinsSe [get_ports {DBB_CPLD_PS_* \
+ DBB_CH1_* \
+ DBB_ATR*}]
+set_property IOSTANDARD LVCMOS18 $UsrpIoBHpPinsSe
+set_property DRIVE 4 $UsrpIoBHpPinsSe
+set_property SLEW SLOW $UsrpIoBHpPinsSe
+
+set UsrpIoBHrPinsSe [get_ports {DBB_MYK_SPI_* \
+ DBB_MYK_INTRQ \
+ DBB_MYK_SYNC* \
+ DBB_MYK_GPIO* \
+ DBB_CPLD_PL_* \
+ DBB_CPLD_JTAG_* \
+ DBB_CH2*}]
+set_property IOSTANDARD LVCMOS25 $UsrpIoBHrPinsSe
+set_property DRIVE 4 $UsrpIoBHrPinsSe
+set_property SLEW SLOW $UsrpIoBHrPinsSe
+
+set UsrpIoBHrPinsDiff [get_ports {DBB_FPGA_CLK_* \
+ DBB_FPGA_SYSREF_*}]
+set_property IOSTANDARD LVDS_25 $UsrpIoBHrPinsDiff
+set_property DIFF_TERM TRUE $UsrpIoBHrPinsDiff
+
+# Do not allow the DSA lines to float... give them a weak pull if undriven.
+set_property PULLUP TRUE [get_ports {DBB_CH*_*X_DSA_DATA[*]}]
+
+
+### MGTs, Bank 112
+
+set_property PACKAGE_PIN W8 [get_ports {USRPIO_B_MGTCLK_P}]
+set_property PACKAGE_PIN W7 [get_ports {USRPIO_B_MGTCLK_N}]
+
+# This mapping uses the TX pins as the "master" and mimics RX off of them so Vivado
+# places the transceivers in the correct places. The mixup in lanes is accounted for
+# in the Mykonos lane crossbar settings.
+set_property PACKAGE_PIN AC4 [get_ports {USRPIO_B_RX_P[0]}]
+set_property PACKAGE_PIN AC3 [get_ports {USRPIO_B_RX_N[0]}]
+set_property PACKAGE_PIN AB6 [get_ports {USRPIO_B_RX_P[1]}]
+set_property PACKAGE_PIN AB5 [get_ports {USRPIO_B_RX_N[1]}]
+set_property PACKAGE_PIN Y6 [get_ports {USRPIO_B_RX_P[2]}]
+set_property PACKAGE_PIN Y5 [get_ports {USRPIO_B_RX_N[2]}]
+set_property PACKAGE_PIN AA4 [get_ports {USRPIO_B_RX_P[3]}]
+set_property PACKAGE_PIN AA3 [get_ports {USRPIO_B_RX_N[3]}]
+
+set_property PACKAGE_PIN AB2 [get_ports {USRPIO_B_TX_P[0]}]
+set_property PACKAGE_PIN AB1 [get_ports {USRPIO_B_TX_N[0]}]
+set_property PACKAGE_PIN Y2 [get_ports {USRPIO_B_TX_P[1]}]
+set_property PACKAGE_PIN Y1 [get_ports {USRPIO_B_TX_N[1]}]
+set_property PACKAGE_PIN W4 [get_ports {USRPIO_B_TX_P[2]}]
+set_property PACKAGE_PIN W3 [get_ports {USRPIO_B_TX_N[2]}]
+set_property PACKAGE_PIN V2 [get_ports {USRPIO_B_TX_P[3]}]
+set_property PACKAGE_PIN V1 [get_ports {USRPIO_B_TX_N[3]}]
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/ClockingRegs.vhd b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/ClockingRegs.vhd
new file mode 100644
index 000000000..ffaa64f68
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/ClockingRegs.vhd
@@ -0,0 +1,345 @@
+-------------------------------------------------------------------------------
+--
+-- File: ClockingRegs.vhd
+-- Author: Daniel Jepson
+-- Original Project: N310
+-- Date: 17 March 2016
+--
+-------------------------------------------------------------------------------
+-- Copyright 2016-2018 Ettus Research, A National Instruments Company
+-- SPDX-License-Identifier: LGPL-3.0
+-------------------------------------------------------------------------------
+--
+-- Purpose:
+--
+-- Register access to the control/status bits and interfaces for the
+-- RadioClocking module.
+--
+-- XML register definition is included below the module.
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+
+library work;
+ use work.PkgClockingRegMap.all;
+ use work.PkgRegs.all;
+
+
+entity ClockingRegs is
+ port(
+ -- Async reset. Can be tied low if desired.
+ aReset : in boolean;
+ -- Sync reset... used in the same places as the async one.
+ bReset : in boolean;
+ -- Register Bus Clock -- this module connects the BusClk to PsClk, so it's limited
+ -- to 200 MHz!
+ BusClk : in std_logic;
+
+ bRegPortOut : out RegPortOut_t;
+ bRegPortIn : in RegPortIn_t;
+
+ -- Phase shift interface to the RadioClkMmcm.
+ -- There is a reset crossing here between the MMCM reset and aReset. The outgoing
+ -- crossing is safe because (a) the enable signal driven to the MMCM is a strobe-only
+ -- signal and (b) this interface should only be used when the MMCM is not in reset
+ -- (SW waits for the MMCM to be out of reset and locked before using this interface).
+ -- The only input signal, pPsDone, is double-synced in this file before being used.
+ -- This is OK (even though it is a strobe signal) because there is only a reset
+ -- crossing and not a clock domain crossing.
+ pPsInc : out std_logic;
+ pPsEn : out std_logic;
+ pPsDone : in std_logic;
+
+ -- PsClk is driven directly by BusClk, so p = b in the logic below!
+ PsClk : out std_logic;
+
+ -- Sync reset strobes from the register bus to the RadioClkMmcm.
+ bRadioClkMmcmReset : out std_logic;
+ -- Status of RadioClk MMCM lock to register bus.
+ aRadioClksValid : in std_logic;
+
+ bRadioClk1xEnabled : out std_logic;
+ bRadioClk2xEnabled : out std_logic;
+ bRadioClk3xEnabled : out std_logic;
+
+ bJesdRefClkPresent : in std_logic
+ );
+end ClockingRegs;
+
+
+architecture RTL of ClockingRegs is
+
+ --vhook_sigstart
+ --vhook_sigend
+
+ signal bRadioClkMmcmResetInt : std_logic := '1';
+
+ signal bRegPortOutLcl : RegPortOut_t := kRegPortOutZero;
+
+ signal bPsDone,
+ bPsEn,
+ bPsInc,
+ pPsDoneDs_ms,
+ pPsDoneDs : std_logic := '0';
+
+ signal bRadioClk1xEnabledInt,
+ bRadioClk2xEnabledInt,
+ bRadioClk3xEnabledInt,
+ bRadioClksValid_ms,
+ bRadioClksValid : std_logic := '0';
+
+ attribute ASYNC_REG : string;
+ attribute ASYNC_REG of bRadioClksValid_ms : signal is "true";
+ attribute ASYNC_REG of bRadioClksValid : signal is "true";
+ attribute ASYNC_REG of pPsDoneDs_ms : signal is "true";
+ attribute ASYNC_REG of pPsDoneDs : signal is "true";
+
+begin
+
+ -- Locals to outputs.
+ PsClk <= BusClk;
+ pPsInc <= bPsInc;
+ pPsEn <= bPsEn;
+
+ bRadioClkMmcmReset <= bRadioClkMmcmResetInt;
+
+ bRadioClk1xEnabled <= bRadioClk1xEnabledInt;
+ bRadioClk2xEnabled <= bRadioClk2xEnabledInt;
+ bRadioClk3xEnabled <= bRadioClk3xEnabledInt;
+
+
+ -- Write Registers : ------------------------------------------------------------------
+ -- ------------------------------------------------------------------------------------
+ WriteRegisters: process(aReset, BusClk)
+ begin
+ if aReset then
+ bRadioClkMmcmResetInt <= '1';
+ bPsInc <= '0';
+ bPsEn <= '0';
+ bRadioClk1xEnabledInt <= '0';
+ bRadioClk2xEnabledInt <= '0';
+ bRadioClk3xEnabledInt <= '0';
+ elsif rising_edge(BusClk) then
+
+ if bReset then
+ bRadioClkMmcmResetInt <= '1';
+ bPsInc <= '0';
+ bPsEn <= '0';
+ bRadioClk1xEnabledInt <= '0';
+ bRadioClk2xEnabledInt <= '0';
+ bRadioClk3xEnabledInt <= '0';
+ else
+ -- Clear strobe
+ bPsEn <= '0';
+
+ if RegWrite(kPhaseShiftControl, bRegPortIn) then
+ if bRegPortIn.Data(kPsInc) = '1' then
+ bPsInc <= '1';
+ bPsEn <= '1';
+ elsif bRegPortIn.Data(kPsDec) = '1' then
+ bPsInc <= '0';
+ bPsEn <= '1';
+ end if;
+ end if;
+
+ if RegWrite(kRadioClkMmcm, bRegPortIn) then
+ -- Set/Clear pair
+ if bRegPortIn.Data(kRadioClkMmcmResetSet) = '1' then
+ bRadioClkMmcmResetInt <= '1';
+ elsif bRegPortIn.Data(kRadioClkMmcmResetClear) = '1' then
+ bRadioClkMmcmResetInt <= '0';
+ end if;
+ end if;
+
+ if RegWrite(kRadioClkEnables, bRegPortIn) then
+ bRadioClk1xEnabledInt <= bRegPortIn.Data(kRadioClk1xEnabled);
+ bRadioClk2xEnabledInt <= bRegPortIn.Data(kRadioClk2xEnabled);
+ bRadioClk3xEnabledInt <= bRegPortIn.Data(kRadioClk3xEnabled);
+ end if;
+
+ end if;
+ end if;
+ end process WriteRegisters;
+
+
+ DoubleSyncs : process (aReset, BusClk)
+ begin
+ if aReset then
+ bRadioClksValid_ms <= '0';
+ bRadioClksValid <= '0';
+ pPsDoneDs_ms <= '0';
+ pPsDoneDs <= '0';
+ elsif rising_edge(BusClk) then
+ -- No sync reset on double-syncs (however there are default assignments above)!
+ bRadioClksValid_ms <= aRadioClksValid;
+ bRadioClksValid <= bRadioClksValid_ms;
+ pPsDoneDs_ms <= pPsDone;
+ pPsDoneDs <= pPsDoneDs_ms;
+ end if;
+ end process;
+
+
+ -- Read Registers : -------------------------------------------------------------------
+ -- ------------------------------------------------------------------------------------
+ ReadRegisters: process(aReset, BusClk)
+ begin
+ if aReset then
+ bRegPortOutLcl <= kRegPortOutZero;
+ bPsDone <= '0';
+ elsif rising_edge(BusClk) then
+
+ if bReset then
+ bRegPortOutLcl <= kRegPortOutZero;
+ bPsDone <= '0';
+ else
+ -- Deassert strobes
+ bRegPortOutLcl.Data <= kRegPortDataZero;
+
+ -- All of these transactions only take one clock cycle, so we do not have to
+ -- de-assert the Ready signal (ever).
+ bRegPortOutLcl.Ready <= true;
+
+ -- Process the returned data from the phase shifter in the MMCM. Note that even
+ -- though the prefixes are different (p and b), we drive the PsClk from the BusClk
+ -- so this "crossing" is actually safe. Whenever the Done signal asserts (pPsDone -
+ -- pay attention to the prefix!) from the MMCM, we set a sticky bit to tell SW
+ -- that the shift operation is complete.
+ --
+ -- However, if pPsDone asserts at the same time that SW tries to read the register,
+ -- we should accurately report that the operation is indeed complete and then NOT
+ -- store the sticky (since it has already been read by SW). If a read does not come
+ -- through at the same time pPsDone is asserted, then we store the done state as a
+ -- sticky, bPsDone, which is only cleared by a read to this register.
+ if RegRead(kPhaseShiftControl, bRegPortIn) then
+ -- The phase shift is always enabled for the feedback clock in RadioClocking.vhd
+ bRegPortOutLcl.Data(kPsEnabledForFdbClk) <= '1';
+ bRegPortOutLcl.Data(kPsDone) <= bPsDone or pPsDoneDs;
+ bPsDone <= '0';
+ elsif pPsDoneDs = '1' then
+ bPsDone <= '1';
+ end if;
+
+ if RegRead(kRadioClkMmcm, bRegPortIn) then
+ bRegPortOutLcl.Data(kRadioClkMmcmLocked) <= bRadioClksValid;
+ end if;
+
+ if RegRead(kRadioClkEnables, bRegPortIn) then
+ bRegPortOutLcl.Data(kRadioClk1xEnabled) <= bRadioClk1xEnabledInt;
+ bRegPortOutLcl.Data(kRadioClk2xEnabled) <= bRadioClk2xEnabledInt;
+ bRegPortOutLcl.Data(kRadioClk3xEnabled) <= bRadioClk3xEnabledInt;
+ end if;
+
+ if RegRead(kMgtRefClkStatus, bRegPortIn) then
+ bRegPortOutLcl.Data(kJesdRefClkPresent) <= bJesdRefClkPresent;
+ end if;
+
+ end if;
+ end if;
+ end process ReadRegisters;
+
+ -- Local to output
+ bRegPortOut <= bRegPortOutLcl;
+
+
+end RTL;
+
+
+--XmlParse xml_on
+--<regmap name="ClockingRegMap">
+-- <group name="ClockingRegs">
+--
+-- <register name="RadioClkMmcm" size="32" offset="0x20" attributes="Readable|Writable">
+-- <info>
+-- </info>
+-- <bitfield name="RadioClkMmcmLocked" range="4">
+-- <info>
+-- Reflects the locked status of the MMCM. '1' = locked. This bit is only valid
+-- when the MMCM reset is de-asserted. Read-only.
+-- </info>
+-- </bitfield>
+-- <bitfield name="RadioClkMmcmResetClear" range="1" attributes="Strobe">
+-- <info>
+-- Controls the reset to the Radio Clock MMCM. Strobe this bit to de-assert the
+-- reset to the MMCM. Default is reset asserted. Write-only.
+-- </info>
+-- </bitfield>
+-- <bitfield name="RadioClkMmcmResetSet" range="0" attributes="Strobe">
+-- <info>
+-- Controls the reset to the Radio Clock MMCM. Strobe this bit to assert the
+-- reset to the MMCM. Default is reset asserted. Write-only.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- <register name="PhaseShiftControl" size="32" offset="0x24" attributes="Readable|Writable">
+-- <info>
+-- Phase Shift for RadioClkMmcm.
+-- </info>
+-- <bitfield name="PsDone" range="28">
+-- <info>
+-- This bit should set after a shift operation successfully completes.
+-- Reading this register will clear this bit. Read-only.
+-- </info>
+-- </bitfield>
+-- <bitfield name="PsInc" range="0" attributes="Strobe">
+-- <info>
+-- Strobe this bit to increment the phase. This bit is self-clearing and will
+-- always return '0' when read. If PsInc and PsDec are asserted together,
+-- the phase will increment.
+-- </info>
+-- </bitfield>
+-- <bitfield name="PsDec" range="4" attributes="Strobe">
+-- <info>
+-- Strobe this bit to decrement the phase. This bit is self-clearing and will
+-- always return '0' when read. If PsInc and PsDec are asserted together,
+-- the phase will increment.
+-- </info>
+-- </bitfield>
+-- <bitfield name="PsEnabledForFdbClk" range="16">
+-- <info>
+-- Read-only.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- <register name="RadioClkEnables" size="32" offset="0x28" attributes="Readable|Writable">
+-- <info>
+-- </info>
+-- <bitfield name="RadioClk3xEnabled" range="8">
+-- <info>
+-- Set to '1' to enable the clock. Default disabled = '0'.
+-- Do so ONLY after the MMCM is out of reset and locked!
+-- </info>
+-- </bitfield>
+-- <bitfield name="RadioClk2xEnabled" range="4">
+-- <info>
+-- Set to '1' to enable the clock. Default disabled = '0'.
+-- Do so ONLY after the MMCM is out of reset and locked!
+-- </info>
+-- </bitfield>
+-- <bitfield name="RadioClk1xEnabled" range="0">
+-- <info>
+-- Set to '1' to enable the clock. Default disabled = '0'.
+-- Do so ONLY after the MMCM is out of reset and locked!
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- <register name="MgtRefClkStatus" size="32" offset="0x30" attributes="Readable">
+-- <info>
+-- </info>
+-- <bitfield name="JesdRefClkPresent" range="0">
+-- <info>
+-- Live indicator of the MGT Reference Clock toggling and within expected
+-- frequency limits. If this bit is de-asserted, then the JESD204b core will
+-- not function correctly!
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- </group>
+--
+--</regmap>
+--XmlParse xml_off
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/DaughterboardRegs.vhd b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/DaughterboardRegs.vhd
new file mode 100644
index 000000000..7f8ef388a
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/DaughterboardRegs.vhd
@@ -0,0 +1,116 @@
+-------------------------------------------------------------------------------
+--
+-- File: DaughterboardRegs.vhd
+-- Author: Daniel Jepson
+-- Original Project: N310
+-- Date: 27 April 2016
+--
+-------------------------------------------------------------------------------
+-- Copyright 2016-2018 Ettus Research, A National Instruments Company
+-- SPDX-License-Identifier: LGPL-3.0
+-------------------------------------------------------------------------------
+--
+-- Purpose:
+--
+-- Register interface to the semi-static control lines for the Mg
+-- Daughterboard.
+--
+-- XML register definition is included below the module.
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+
+library work;
+ use work.PkgDaughterboardRegMap.all;
+ use work.PkgRegs.all;
+
+
+entity DaughterboardRegs is
+ port(
+ -- Async reset. Can be tied low if desired.
+ aReset : in boolean;
+ -- Sync reset... used in the same places as the async one.
+ bReset : in boolean;
+ BusClk : in std_logic;
+
+ bRegPortOut : out RegPortOut_t;
+ bRegPortIn : in RegPortIn_t;
+
+ -- Slot and DB ID values. These should be tied to constants!
+ kDbId : in std_logic_vector(15 downto 0);
+ kSlotId : in std_logic
+
+ );
+end DaughterboardRegs;
+
+
+architecture RTL of DaughterboardRegs is
+
+ --vhook_sigstart
+ --vhook_sigend
+
+ signal bRegPortOutLcl : RegPortOut_t := kRegPortOutZero;
+
+begin
+
+
+ -- Read Registers : -------------------------------------------------------------------
+ -- ------------------------------------------------------------------------------------
+ ReadRegisters: process(aReset, BusClk)
+ begin
+ if aReset then
+ bRegPortOutLcl <= kRegPortOutZero;
+ elsif rising_edge(BusClk) then
+ if bReset then
+ bRegPortOutLcl <= kRegPortOutZero;
+ else
+ -- De-assert strobes
+ bRegPortOutLcl.Data <= kRegPortDataZero;
+
+ -- All of these transactions only take one clock cycle, so we do not have to
+ -- de-assert the Ready signal (ever).
+ bRegPortOutLcl.Ready <= true;
+
+ if RegRead(kDaughterboardId, bRegPortIn) then
+ bRegPortOutLcl.Data(kDbIdValMsb downto kDbIdVal) <= kDbId;
+ bRegPortOutLcl.Data(kSlotIdVal) <= kSlotId;
+ end if;
+
+ end if;
+ end if;
+ end process ReadRegisters;
+
+ -- Local to output
+ bRegPortOut <= bRegPortOutLcl;
+
+
+end RTL;
+
+
+--XmlParse xml_on
+--<regmap name="DaughterboardRegMap">
+-- <group name="StaticControl" order="1">
+--
+-- <register name="DaughterboardId" size="32" offset="0x30" attributes="Readable">
+-- <info>
+-- </info>
+-- <bitfield name="DbIdVal" range="15..0">
+-- <info>
+-- ID for the DB with which this file is designed to communicate. Matches the DB
+-- EEPROM ID.
+-- </info>
+-- </bitfield>
+-- <bitfield name="SlotIdVal" range="16">
+-- <info>
+-- ID for the Slot this module controls. Options are 0 and 1 for the N310 MB.
+-- </info>
+-- </bitfield>
+-- </register>
+--
+-- </group>
+--
+--
+--</regmap>
+--XmlParse xml_off
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/DbCore.vhd b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/DbCore.vhd
new file mode 100644
index 000000000..e1369ec00
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/DbCore.vhd
@@ -0,0 +1,562 @@
+-------------------------------------------------------------------------------
+--
+-- File: DbCore.vhd
+-- Author: Daniel Jepson
+-- Original Project: N310
+-- Date: 12 April 2017
+--
+-------------------------------------------------------------------------------
+-- Copyright 2017-2018 Ettus Research, A National Instruments Company
+-- SPDX-License-Identifier: LGPL-3.0
+-------------------------------------------------------------------------------
+--
+-- Purpose:
+--
+-- Wrapper file for Daughterboard Control. This includes the semi-static control
+-- and status registers, clocking, synchronization, and JESD204B cores.
+--
+-- There is no version register for the plain-text files here.
+-- Version control for the Sync and JESD204B cores is internal to the netlists.
+--
+-- The resets for this core are almost entirely local and/or synchronous.
+-- bBusReset is a Synchronous reset on the BusClk domain that resets all of the
+-- registers connected to the RegPort, as well as any other stray registers
+-- connected to the BusClk. All other resets are local to the modules they touch.
+-- No other reset drives all modules universally.
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+library work;
+ use work.PkgMgPersonality.all;
+ use work.PkgRegs.all;
+ use work.PkgJesdConfig.all;
+
+
+entity DbCore is
+ generic(
+ -- Set to '1' to include the White Rabbit TDC.
+ kInclWhiteRabbitTdc : std_logic := '0'
+ );
+ port(
+
+ -- Resets --
+ -- Synchronous Reset for the BusClk domain (mainly for the RegPort)
+ bBusReset : in std_logic;
+
+ -- Clocks --
+ -- Register Bus Clock (any frequency)
+ BusClk : in std_logic;
+ -- Always-on at 40 MHz
+ Clk40 : in std_logic;
+ -- Super secret crazy awesome measurement clock at weird frequencies.
+ MeasClk : in std_logic;
+ -- FPGA Sample Clock from DB LMK
+ FpgaClk_p : in std_logic;
+ FpgaClk_n : in std_logic;
+
+ -- Sample Clock Sharing. The clocks generated in this module are exported out to the
+ -- top level so they can be shared amongst daughterboards. Therefore they must be
+ -- driven back into the SampleClk*x inputs at a higher level in order for this module
+ -- to work correctly. There are a few isolated cases where SampleClk*xOut is used
+ -- directly in this module, and those are documented below.
+ SampleClk1xOut : out std_logic;
+ SampleClk1x : in std_logic;
+ SampleClk2xOut : out std_logic;
+ SampleClk2x : in std_logic;
+
+
+ -- Register Ports --
+ --
+ -- Only synchronous resets can be used for these ports!
+ bRegPortInFlat : in std_logic_vector(49 downto 0);
+ bRegPortOutFlat : out std_logic_vector(33 downto 0);
+
+ -- Slot ID value. This should be tied to a constant!
+ kSlotId : in std_logic;
+
+
+ -- SYSREF --
+ --
+ -- SYSREF direct from the LMK
+ sSysRefFpgaLvds_p,
+ sSysRefFpgaLvds_n : in std_logic;
+ -- SYNC directly to the LMK
+ aLmkSync : out std_logic;
+
+
+ -- JESD Signals --
+ --
+ -- GTX Sample Clock Reference Input. Direct connect to FPGA pins.
+ JesdRefClk_p,
+ JesdRefClk_n : in std_logic;
+
+ -- ADC JESD PHY Interface. Direct connect to FPGA pins.
+ aAdcRx_p,
+ aAdcRx_n : in std_logic_vector(3 downto 0);
+ aSyncAdcOut_n : out std_logic;
+
+ -- DAC JESD PHY Interface. Direct connect to FPGA pins.
+ aDacTx_p,
+ aDacTx_n : out std_logic_vector(3 downto 0);
+ aSyncDacIn_n : in std_logic;
+
+
+ -- Data Pipes to/from the DACs/ADCs --
+ --
+ -- - Data is presented as one sample per cycle.
+ -- - sAdcDataValid asserts when ADC data is valid.
+ -- - sDacReadyForInput asserts when DAC data is ready to be received.
+ --
+ -- Reset Crossings:
+ -- The ADC data and valid outputs are synchronously cleared before the asynchronous
+ -- reset is asserted--preventing any reset crossing issues here between the RX
+ -- (internal to the core) reset and the no-reset domain of RFNoC.
+ --
+ -- The DAC samples should be zeros on reset de-assertion due to RFI being de-asserted
+ -- in reset. If they are not zeros, then it is still OK because data is ignored until
+ -- RFI is asserted. DAC RFI is double-synchronized to protect against the reset
+ -- crossing. This is safe to do because it simply delays the output of RFI by two
+ -- cycles on the assertion edge, and as long as reset is held for more than two
+ -- cycles, the de-assertion edge of RFI should come long before the TX module is
+ -- taken out of reset.
+ sAdcDataValid : out std_logic;
+ sAdcDataSamples0I : out std_logic_vector(15 downto 0);
+ sAdcDataSamples0Q : out std_logic_vector(15 downto 0);
+ sAdcDataSamples1I : out std_logic_vector(15 downto 0);
+ sAdcDataSamples1Q : out std_logic_vector(15 downto 0);
+ sDacReadyForInput : out std_logic;
+ sDacDataSamples0I : in std_logic_vector(15 downto 0);
+ sDacDataSamples0Q : in std_logic_vector(15 downto 0);
+ sDacDataSamples1I : in std_logic_vector(15 downto 0);
+ sDacDataSamples1Q : in std_logic_vector(15 downto 0);
+
+
+ -- RefClk & Timing & Sync --
+ RefClk : in std_logic;
+ rPpsPulse : in std_logic;
+ rGatedPulseToPin : inout std_logic; -- straight to pin
+ sGatedPulseToPin : inout std_logic; -- straight to pin
+ sPps : out std_logic;
+ sPpsToIob : out std_logic;
+
+ -- White Rabbit Timing & Sync --
+ WrRefClk : in std_logic;
+ rWrPpsPulse : in std_logic;
+ rWrGatedPulseToPin : inout std_logic; -- straight to pin
+ sWrGatedPulseToPin : inout std_logic; -- straight to pin
+ aPpsSfpSel : in std_logic_vector(1 downto 0);
+
+
+ -- Debug for JESD
+ sAdcSync : out std_logic;
+ sDacSync : out std_logic;
+ sSysRef : out std_logic;
+
+ -- Debug for Timing & Sync
+ rRpTransfer : out std_logic;
+ sSpTransfer : out std_logic;
+ rWrRpTransfer : out std_logic;
+ sWrSpTransfer : out std_logic
+ );
+
+end DbCore;
+
+
+architecture RTL of DbCore is
+
+ component Jesd204bXcvrCore
+ port (
+ bBusReset : in STD_LOGIC;
+ BusClk : in STD_LOGIC;
+ ReliableClk40 : in STD_LOGIC;
+ FpgaClk1x : in STD_LOGIC;
+ FpgaClk2x : in STD_LOGIC;
+ bFpgaClksStable : in STD_LOGIC;
+ bRegPortInFlat : in STD_LOGIC_VECTOR(49 downto 0);
+ bRegPortOutFlat : out STD_LOGIC_VECTOR(33 downto 0);
+ aLmkSync : out STD_LOGIC;
+ cSysRefFpgaLvds_p : in STD_LOGIC;
+ cSysRefFpgaLvds_n : in STD_LOGIC;
+ fSysRef : out STD_LOGIC;
+ CaptureSysRefClk : in STD_LOGIC;
+ JesdRefClk_p : in STD_LOGIC;
+ JesdRefClk_n : in STD_LOGIC;
+ bJesdRefClkPresent : out STD_LOGIC;
+ aAdcRx_p : in STD_LOGIC_VECTOR(3 downto 0);
+ aAdcRx_n : in STD_LOGIC_VECTOR(3 downto 0);
+ aSyncAdcOut_n : out STD_LOGIC;
+ aDacTx_p : out STD_LOGIC_VECTOR(3 downto 0);
+ aDacTx_n : out STD_LOGIC_VECTOR(3 downto 0);
+ aSyncDacIn_n : in STD_LOGIC;
+ fAdc0DataFlat : out STD_LOGIC_VECTOR(31 downto 0);
+ fAdc1DataFlat : out STD_LOGIC_VECTOR(31 downto 0);
+ fDac0DataFlat : in STD_LOGIC_VECTOR(31 downto 0);
+ fDac1DataFlat : in STD_LOGIC_VECTOR(31 downto 0);
+ fAdcDataValid : out STD_LOGIC;
+ fDacReadyForInput : out STD_LOGIC;
+ aDacSync : out STD_LOGIC;
+ aAdcSync : out STD_LOGIC);
+ end component;
+
+ function to_Boolean (s : std_ulogic) return boolean is
+ begin
+ return (To_X01(s)='1');
+ end to_Boolean;
+
+ function to_StdLogic(b : boolean) return std_ulogic is
+ begin
+ if b then
+ return '1';
+ else
+ return '0';
+ end if;
+ end to_StdLogic;
+
+ --vhook_sigstart
+ signal aAdcSync: STD_LOGIC;
+ signal aDacSync: STD_LOGIC;
+ signal bClockingRegPortOut: RegPortOut_t;
+ signal bDbRegPortOut: RegPortOut_t;
+ signal bFpgaClksStable: STD_LOGIC;
+ signal bJesdCoreRegPortInFlat: STD_LOGIC_VECTOR(49 downto 0);
+ signal bJesdCoreRegPortOutFlat: STD_LOGIC_VECTOR(33 downto 0);
+ signal bJesdRefClkPresent: STD_LOGIC;
+ signal bRadioClk1xEnabled: std_logic;
+ signal bRadioClk2xEnabled: std_logic;
+ signal bRadioClk3xEnabled: std_logic;
+ signal bRadioClkMmcmReset: std_logic;
+ signal bRadioClksValid: std_logic;
+ signal pPsDone: std_logic;
+ signal pPsEn: std_logic;
+ signal pPsInc: std_logic;
+ signal PsClk: std_logic;
+ signal sAdc0DataFlat: STD_LOGIC_VECTOR(31 downto 0);
+ signal sAdc1DataFlat: STD_LOGIC_VECTOR(31 downto 0);
+ signal SampleClk1xOutLcl: std_logic;
+ signal sDac0DataFlat: STD_LOGIC_VECTOR(31 downto 0);
+ signal sDac1DataFlat: STD_LOGIC_VECTOR(31 downto 0);
+ signal sDacReadyForInputAsyncReset: STD_LOGIC;
+ signal sRegPps: std_logic;
+ signal sSysRefAsyncReset: STD_LOGIC;
+ signal sWrPps: std_logic;
+ --vhook_sigend
+
+ signal bJesdRegPortInGrp, bSyncRegPortIn, bWrSyncRegPortIn, bRegPortIn : RegPortIn_t;
+ signal bJesdRegPortOut, bSyncRegPortOut, bWrSyncRegPortOut, bRegPortOut : RegPortOut_t;
+
+ signal sDacReadyForInput_ms, sDacReadyForInputLcl,
+ sDacSync_ms, sDacSyncLcl,
+ sAdcSync_ms, sAdcSyncLcl,
+ sSysRef_ms, sSysRefLcl : std_logic := '0';
+
+ signal sAdc0Data, sAdc1Data : AdcData_t;
+ signal sDac0Data, sDac1Data : DacData_t;
+
+ signal sPpsSfpSel_ms, sPpsSfpSel : std_logic_vector(1 downto 0) := (others => '0');
+ signal sUseWrTdcPps : boolean := false;
+ signal sPpsInt, sPpsMuxed : std_logic := '0';
+
+ attribute ASYNC_REG : string;
+ attribute ASYNC_REG of sDacReadyForInput_ms : signal is "true";
+ attribute ASYNC_REG of sDacReadyForInputLcl : signal is "true";
+ attribute ASYNC_REG of sDacSync_ms : signal is "true";
+ attribute ASYNC_REG of sDacSyncLcl : signal is "true";
+ attribute ASYNC_REG of sAdcSync_ms : signal is "true";
+ attribute ASYNC_REG of sAdcSyncLcl : signal is "true";
+ attribute ASYNC_REG of sSysRef_ms : signal is "true";
+ attribute ASYNC_REG of sSysRefLcl : signal is "true";
+ attribute ASYNC_REG of sPpsSfpSel_ms : signal is "true";
+ attribute ASYNC_REG of sPpsSfpSel : signal is "true";
+
+begin
+
+ bRegPortOutFlat <= Flatten(bRegPortOut);
+ bRegPortIn <= Unflatten(bRegPortInFlat);
+
+
+ -- Combine return RegPorts.
+ bRegPortOut <= bJesdRegPortOut
+ + bClockingRegPortOut
+ + bSyncRegPortOut + bWrSyncRegPortOut
+ + bDbRegPortOut;
+
+
+ -- Clocking : -------------------------------------------------------------------------
+ -- Automatically export the Sample Clocks and only use the incoming clocks in the
+ -- remainder of the logic. For a single module, the clocks must be looped back
+ -- in at a higher level!
+ -- ------------------------------------------------------------------------------------
+
+ --vhook_e RadioClocking
+ --vhook_a aReset false
+ --vhook_a bReset to_boolean(bBusReset)
+ --vhook_a RadioClk1x SampleClk1xOutLcl
+ --vhook_a RadioClk2x SampleClk2xOut
+ --vhook_a RadioClk3x open
+ RadioClockingx: entity work.RadioClocking (rtl)
+ port map (
+ aReset => false, --in boolean
+ bReset => to_boolean(bBusReset), --in boolean
+ BusClk => BusClk, --in std_logic
+ bRadioClkMmcmReset => bRadioClkMmcmReset, --in std_logic
+ bRadioClksValid => bRadioClksValid, --out std_logic
+ bRadioClk1xEnabled => bRadioClk1xEnabled, --in std_logic
+ bRadioClk2xEnabled => bRadioClk2xEnabled, --in std_logic
+ bRadioClk3xEnabled => bRadioClk3xEnabled, --in std_logic
+ pPsInc => pPsInc, --in std_logic
+ pPsEn => pPsEn, --in std_logic
+ PsClk => PsClk, --in std_logic
+ pPsDone => pPsDone, --out std_logic
+ FpgaClk_n => FpgaClk_n, --in std_logic
+ FpgaClk_p => FpgaClk_p, --in std_logic
+ RadioClk1x => SampleClk1xOutLcl, --out std_logic
+ RadioClk2x => SampleClk2xOut, --out std_logic
+ RadioClk3x => open); --out std_logic
+
+ -- We need an internal copy of SampleClk1x for the TDC, since we don't want to try
+ -- and align the other DB's clock accidentally.
+ SampleClk1xOut <= SampleClk1xOutLcl;
+
+ --vhook_e ClockingRegs
+ --vhook_a aReset false
+ --vhook_a bReset to_boolean(bBusReset)
+ --vhook_a bRegPortOut bClockingRegPortOut
+ --vhook_a aRadioClksValid bRadioClksValid
+ ClockingRegsx: entity work.ClockingRegs (RTL)
+ port map (
+ aReset => false, --in boolean
+ bReset => to_boolean(bBusReset), --in boolean
+ BusClk => BusClk, --in std_logic
+ bRegPortOut => bClockingRegPortOut, --out RegPortOut_t
+ bRegPortIn => bRegPortIn, --in RegPortIn_t
+ pPsInc => pPsInc, --out std_logic
+ pPsEn => pPsEn, --out std_logic
+ pPsDone => pPsDone, --in std_logic
+ PsClk => PsClk, --out std_logic
+ bRadioClkMmcmReset => bRadioClkMmcmReset, --out std_logic
+ aRadioClksValid => bRadioClksValid, --in std_logic
+ bRadioClk1xEnabled => bRadioClk1xEnabled, --out std_logic
+ bRadioClk2xEnabled => bRadioClk2xEnabled, --out std_logic
+ bRadioClk3xEnabled => bRadioClk3xEnabled, --out std_logic
+ bJesdRefClkPresent => bJesdRefClkPresent); --in std_logic
+
+
+
+ -- JESD204B : -------------------------------------------------------------------------
+ -- ------------------------------------------------------------------------------------
+
+ bJesdRegPortInGrp <= Mask(RegPortIn => bRegPortIn,
+ kRegisterOffset => kJesdRegGroupInDbRegs); -- 0x2000 to 0x3FFC
+
+ -- Expand/compress the RegPort for moving through the netlist boundary.
+ bJesdRegPortOut <= Unflatten(bJesdCoreRegPortOutFlat);
+ bJesdCoreRegPortInFlat <= Flatten(bJesdRegPortInGrp);
+
+ --vhook Jesd204bXcvrCore
+ --vhook_a bRegPortInFlat bJesdCoreRegPortInFlat
+ --vhook_a bRegPortOutFlat bJesdCoreRegPortOutFlat
+ --vhook_a FpgaClk1x SampleClk1x
+ --vhook_a FpgaClk2x SampleClk2x
+ --vhook_a ReliableClk40 Clk40
+ --vhook_a CaptureSysRefClk SampleClk1xOutLcl
+ --vhook_a cSysRefFpgaLvds_p sSysRefFpgaLvds_p
+ --vhook_a cSysRefFpgaLvds_n sSysRefFpgaLvds_n
+ --vhook_a fSysRef sSysRefAsyncReset
+ --vhook_a fDacReadyForInput sDacReadyForInputAsyncReset
+ --vhook_a {^f(.*)} s$1
+ Jesd204bXcvrCorex: Jesd204bXcvrCore
+ port map (
+ bBusReset => bBusReset, --in STD_LOGIC
+ BusClk => BusClk, --in STD_LOGIC
+ ReliableClk40 => Clk40, --in STD_LOGIC
+ FpgaClk1x => SampleClk1x, --in STD_LOGIC
+ FpgaClk2x => SampleClk2x, --in STD_LOGIC
+ bFpgaClksStable => bFpgaClksStable, --in STD_LOGIC
+ bRegPortInFlat => bJesdCoreRegPortInFlat, --in STD_LOGIC_VECTOR(49:0)
+ bRegPortOutFlat => bJesdCoreRegPortOutFlat, --out STD_LOGIC_VECTOR(33:0)
+ aLmkSync => aLmkSync, --out STD_LOGIC
+ cSysRefFpgaLvds_p => sSysRefFpgaLvds_p, --in STD_LOGIC
+ cSysRefFpgaLvds_n => sSysRefFpgaLvds_n, --in STD_LOGIC
+ fSysRef => sSysRefAsyncReset, --out STD_LOGIC
+ CaptureSysRefClk => SampleClk1xOutLcl, --in STD_LOGIC
+ JesdRefClk_p => JesdRefClk_p, --in STD_LOGIC
+ JesdRefClk_n => JesdRefClk_n, --in STD_LOGIC
+ bJesdRefClkPresent => bJesdRefClkPresent, --out STD_LOGIC
+ aAdcRx_p => aAdcRx_p, --in STD_LOGIC_VECTOR(3:0)
+ aAdcRx_n => aAdcRx_n, --in STD_LOGIC_VECTOR(3:0)
+ aSyncAdcOut_n => aSyncAdcOut_n, --out STD_LOGIC
+ aDacTx_p => aDacTx_p, --out STD_LOGIC_VECTOR(3:0)
+ aDacTx_n => aDacTx_n, --out STD_LOGIC_VECTOR(3:0)
+ aSyncDacIn_n => aSyncDacIn_n, --in STD_LOGIC
+ fAdc0DataFlat => sAdc0DataFlat, --out STD_LOGIC_VECTOR(31:0)
+ fAdc1DataFlat => sAdc1DataFlat, --out STD_LOGIC_VECTOR(31:0)
+ fDac0DataFlat => sDac0DataFlat, --in STD_LOGIC_VECTOR(31:0)
+ fDac1DataFlat => sDac1DataFlat, --in STD_LOGIC_VECTOR(31:0)
+ fAdcDataValid => sAdcDataValid, --out STD_LOGIC
+ fDacReadyForInput => sDacReadyForInputAsyncReset, --out STD_LOGIC
+ aDacSync => aDacSync, --out STD_LOGIC
+ aAdcSync => aAdcSync); --out STD_LOGIC
+
+ JesdDoubleSyncToNoResetSampleClk : process (SampleClk1x)
+ begin
+ if rising_edge(SampleClk1x) then
+ sDacReadyForInput_ms <= sDacReadyForInputAsyncReset;
+ sDacReadyForInputLcl <= sDacReadyForInput_ms;
+ -- No clock crossing here -- just reset, although the prefix declares otherwise...
+ sDacSync_ms <= aDacSync;
+ sDacSyncLcl <= sDacSync_ms;
+ sAdcSync_ms <= aAdcSync;
+ sAdcSyncLcl <= sAdcSync_ms;
+ sSysRef_ms <= sSysRefAsyncReset;
+ sSysRefLcl <= sSysRef_ms;
+ end if;
+ end process;
+
+ -- Locals to outputs.
+ sDacReadyForInput <= sDacReadyForInputLcl;
+ sDacSync <= sDacSyncLcl;
+ sAdcSync <= sAdcSyncLcl;
+ sSysRef <= sSysRefLcl;
+
+ -- Just combine the first two enables, since they're the ones that are used for JESD.
+ -- No reset crossing here, since bFpgaClksStable is only received by a no-reset domain
+ -- and the MGTs directly.
+ bFpgaClksStable <= bRadioClksValid and bRadioClk1xEnabled and bRadioClk2xEnabled;
+
+ -- Compress/expand the flat data types from the netlist and route to top level.
+ sAdc0Data <= Unflatten(sAdc0DataFlat);
+ sAdc1Data <= Unflatten(sAdc1DataFlat);
+ sDac0DataFlat <= Flatten(sDac0Data);
+ sDac1DataFlat <= Flatten(sDac1Data);
+
+ sAdcDataSamples0I <= sAdc0Data.I;
+ sAdcDataSamples0Q <= sAdc0Data.Q;
+ sAdcDataSamples1I <= sAdc1Data.I;
+ sAdcDataSamples1Q <= sAdc1Data.Q;
+
+ sDac0Data.I <= sDacDataSamples0I;
+ sDac0Data.Q <= sDacDataSamples0Q;
+ sDac1Data.I <= sDacDataSamples1I;
+ sDac1Data.Q <= sDacDataSamples1Q;
+
+
+ -- Timing and Sync : ------------------------------------------------------------------
+ -- ------------------------------------------------------------------------------------
+
+ bSyncRegPortIn <= Mask(RegPortIn => bRegPortIn,
+ kRegisterOffset => kTdc0OffsetsInEndpoint); -- 0x0200
+
+ --vhook_e TdcWrapper
+ --vhook_# Use the local copy of the SampleClock, since we want the TDC to measure the
+ --vhook_# clock offset for this daughterboard, not the global SampleClock.
+ --vhook_a SampleClk SampleClk1xOutLcl
+ --vhook_a sPpsPulse sRegPps
+ TdcWrapperx: entity work.TdcWrapper (struct)
+ port map (
+ BusClk => BusClk, --in std_logic
+ bBusReset => bBusReset, --in std_logic
+ RefClk => RefClk, --in std_logic
+ SampleClk => SampleClk1xOutLcl, --in std_logic
+ MeasClk => MeasClk, --in std_logic
+ bSyncRegPortOut => bSyncRegPortOut, --out RegPortOut_t
+ bSyncRegPortIn => bSyncRegPortIn, --in RegPortIn_t
+ rPpsPulse => rPpsPulse, --in std_logic
+ sPpsPulse => sRegPps, --out std_logic
+ rRpTransfer => rRpTransfer, --out std_logic
+ sSpTransfer => sSpTransfer, --out std_logic
+ rGatedPulseToPin => rGatedPulseToPin, --inout std_logic
+ sGatedPulseToPin => sGatedPulseToPin); --inout std_logic
+
+ WrTdcGen: if kInclWhiteRabbitTdc = '1' generate
+ bWrSyncRegPortIn <= Mask(RegPortIn => bRegPortIn,
+ kRegisterOffset => kTdc1OffsetsInEndpoint); -- 0x0400
+
+ --vhook_e TdcWrapper WrTdcWrapperx
+ --vhook_# Use the local copy of the SampleClock, since we want the TDC to measure the
+ --vhook_# clock offset for this daughterboard, not the global SampleClock.
+ --vhook_a bSyncRegPortIn bWrSyncRegPortIn
+ --vhook_a bSyncRegPortOut bWrSyncRegPortOut
+ --vhook_a SampleClk SampleClk1xOutLcl
+ --vhook_a RefClk WrRefClk
+ --vhook_a rPpsPulse rWrPpsPulse
+ --vhook_a sPpsPulse sWrPps
+ --vhook_a rRpTransfer rWrRpTransfer
+ --vhook_a sSpTransfer sWrSpTransfer
+ --vhook_a rGatedPulseToPin rWrGatedPulseToPin
+ --vhook_a sGatedPulseToPin sWrGatedPulseToPin
+ WrTdcWrapperx: entity work.TdcWrapper (struct)
+ port map (
+ BusClk => BusClk, --in std_logic
+ bBusReset => bBusReset, --in std_logic
+ RefClk => WrRefClk, --in std_logic
+ SampleClk => SampleClk1xOutLcl, --in std_logic
+ MeasClk => MeasClk, --in std_logic
+ bSyncRegPortOut => bWrSyncRegPortOut, --out RegPortOut_t
+ bSyncRegPortIn => bWrSyncRegPortIn, --in RegPortIn_t
+ rPpsPulse => rWrPpsPulse, --in std_logic
+ sPpsPulse => sWrPps, --out std_logic
+ rRpTransfer => rWrRpTransfer, --out std_logic
+ sSpTransfer => sWrSpTransfer, --out std_logic
+ rGatedPulseToPin => rWrGatedPulseToPin, --inout std_logic
+ sGatedPulseToPin => sWrGatedPulseToPin); --inout std_logic
+ end generate WrTdcGen;
+
+ WrTdcNotGen: if kInclWhiteRabbitTdc = '0' generate
+ bWrSyncRegPortOut <= kRegPortOutZero;
+ sWrPps <= '0';
+ rWrRpTransfer <= '0';
+ sWrSpTransfer <= '0';
+ rWrGatedPulseToPin <= '0';
+ sWrGatedPulseToPin <= '0';
+ end generate WrTdcNotGen;
+
+ -- Mux the output PPS based on the SFP selection bits. Encoding is one-hot, with zero
+ -- also a valid state. Regardless of whether the user selects SFP0 or SFP1 as the time
+ -- source, there is only one White Rabbit TDC, so '01' and '10' are equivalent.
+ -- '00': Use the PPS output from the "regular" TDC.
+ -- '01': Use the PPS output from the "white rabbit" TDC.
+ -- '10': Use the PPS output from the "white rabbit" TDC.
+ PpsOutputMux : process (SampleClk1xOutLcl)
+ begin
+ if rising_edge(SampleClk1xOutLcl) then
+ -- Double-sync the control bits to the Sample Clock domain.
+ sPpsSfpSel_ms <= aPpsSfpSel;
+ sPpsSfpSel <= sPpsSfpSel_ms;
+
+ -- OR the control bits together to produce a single override enable for the WR TDC.
+ sUseWrTdcPps <= to_boolean(sPpsSfpSel(0) or sPpsSfpSel(1));
+
+ -- Flop the outputs. One flop for the PPS output IOB, the other for use internally.
+ sPpsInt <= sPpsMuxed;
+ end if;
+ end process PpsOutputMux;
+
+ sPpsMuxed <= sWrPps when sUseWrTdcPps else sRegPps;
+ sPps <= sPpsInt;
+ sPpsToIob <= sPpsMuxed; -- No added flop here since there's an IOB outside this module.
+
+ -- Daughterboard Control : ------------------------------------------------------------
+ -- ------------------------------------------------------------------------------------
+
+ --vhook_e DaughterboardRegs
+ --vhook_# Tying this low is safe because the sync reset is used inside DaughterboardRegs.
+ --vhook_a aReset false
+ --vhook_a bReset to_boolean(bBusReset)
+ --vhook_a bRegPortOut bDbRegPortOut
+ --vhook_a kDbId std_logic_vector(to_unsigned(16#150#,16))
+ DaughterboardRegsx: entity work.DaughterboardRegs (RTL)
+ port map (
+ aReset => false, --in boolean
+ bReset => to_boolean(bBusReset), --in boolean
+ BusClk => BusClk, --in std_logic
+ bRegPortOut => bDbRegPortOut, --out RegPortOut_t
+ bRegPortIn => bRegPortIn, --in RegPortIn_t
+ kDbId => std_logic_vector(to_unsigned(16#150#,16)), --in std_logic_vector(15:0)
+ kSlotId => kSlotId); --in std_logic
+
+
+end RTL;
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/Jesd204bXcvrCore.edf b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/Jesd204bXcvrCore.edf
new file mode 100644
index 000000000..27619d2a0
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/Jesd204bXcvrCore.edf
Binary files differ
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/Jesd204bXcvrCore_stub.vhd b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/Jesd204bXcvrCore_stub.vhd
new file mode 100644
index 000000000..84c461d26
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/Jesd204bXcvrCore_stub.vhd
@@ -0,0 +1,56 @@
+-- Copyright 1986-2015 Xilinx, Inc. All Rights Reserved.
+-- --------------------------------------------------------------------------------
+-- Tool Version: Vivado v.2015.4.2 (win64) Build 1494164 Fri Feb 26 04:18:56 MST 2016
+-- Date : Wed Jan 10 10:53:33 2018
+-- Host : djepson-lt running 64-bit major release (build 9200)
+-- Command : write_vhdl -mode synth_stub -force -file ./Jesd204bXcvrCore_stub.vhd
+-- Design : Jesd204bXcvrCore
+-- Purpose : Stub declaration of top-level module interface
+-- Device : xc7z100ffg900-2
+-- --------------------------------------------------------------------------------
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+
+entity Jesd204bXcvrCore is
+ Port (
+ bBusReset : in STD_LOGIC;
+ BusClk : in STD_LOGIC;
+ ReliableClk40 : in STD_LOGIC;
+ FpgaClk1x : in STD_LOGIC;
+ FpgaClk2x : in STD_LOGIC;
+ bFpgaClksStable : in STD_LOGIC;
+ bRegPortInFlat : in STD_LOGIC_VECTOR ( 49 downto 0 );
+ bRegPortOutFlat : out STD_LOGIC_VECTOR ( 33 downto 0 );
+ aLmkSync : out STD_LOGIC;
+ cSysRefFpgaLvds_p : in STD_LOGIC;
+ cSysRefFpgaLvds_n : in STD_LOGIC;
+ fSysRef : out STD_LOGIC;
+ CaptureSysRefClk : in STD_LOGIC;
+ JesdRefClk_p : in STD_LOGIC;
+ JesdRefClk_n : in STD_LOGIC;
+ bJesdRefClkPresent : out STD_LOGIC;
+ aAdcRx_p : in STD_LOGIC_VECTOR ( 3 downto 0 );
+ aAdcRx_n : in STD_LOGIC_VECTOR ( 3 downto 0 );
+ aSyncAdcOut_n : out STD_LOGIC;
+ aDacTx_p : out STD_LOGIC_VECTOR ( 3 downto 0 );
+ aDacTx_n : out STD_LOGIC_VECTOR ( 3 downto 0 );
+ aSyncDacIn_n : in STD_LOGIC;
+ fAdc0DataFlat : out STD_LOGIC_VECTOR ( 31 downto 0 );
+ fAdc1DataFlat : out STD_LOGIC_VECTOR ( 31 downto 0 );
+ fDac0DataFlat : in STD_LOGIC_VECTOR ( 31 downto 0 );
+ fDac1DataFlat : in STD_LOGIC_VECTOR ( 31 downto 0 );
+ fAdcDataValid : out STD_LOGIC;
+ fDacReadyForInput : out STD_LOGIC;
+ aDacSync : out STD_LOGIC;
+ aAdcSync : out STD_LOGIC
+ );
+
+end Jesd204bXcvrCore;
+
+architecture stub of Jesd204bXcvrCore is
+attribute syn_black_box : boolean;
+attribute black_box_pad_pin : string;
+attribute syn_black_box of stub : architecture is true;
+attribute black_box_pad_pin of stub : architecture is "bBusReset,BusClk,ReliableClk40,FpgaClk1x,FpgaClk2x,bFpgaClksStable,bRegPortInFlat[49:0],bRegPortOutFlat[33:0],aLmkSync,cSysRefFpgaLvds_p,cSysRefFpgaLvds_n,fSysRef,CaptureSysRefClk,JesdRefClk_p,JesdRefClk_n,bJesdRefClkPresent,aAdcRx_p[3:0],aAdcRx_n[3:0],aSyncAdcOut_n,aDacTx_p[3:0],aDacTx_n[3:0],aSyncDacIn_n,fAdc0DataFlat[31:0],fAdc1DataFlat[31:0],fDac0DataFlat[31:0],fDac1DataFlat[31:0],fAdcDataValid,fDacReadyForInput,aDacSync,aAdcSync";
+begin
+end;
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgClockingRegMap.vhd b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgClockingRegMap.vhd
new file mode 100644
index 000000000..03b95c100
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgClockingRegMap.vhd
@@ -0,0 +1,107 @@
+-------------------------------------------------------------------------------
+--
+-- File: PkgClockingRegMap.vhd
+-- Author: Autogenerated by XmlParse
+-- Original Project: --
+-- Date: --
+--
+-------------------------------------------------------------------------------
+-- Copyright 2017 Ettus Research, A National Instruments Company
+-- SPDX-License-Identifier: LGPL-3.0
+-------------------------------------------------------------------------------
+--
+-- Purpose:
+-- The constants in this file are autogenerated by XmlParse and should
+-- be used by testbench code to access specific register fields.
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+package PkgClockingRegMap is
+
+--===============================================================================
+-- A numerically ordered list of registers and their VHDL source files
+--===============================================================================
+
+ -- RadioClkMmcm : 0x20 (ClockingRegs.vhd)
+ -- PhaseShiftControl : 0x24 (ClockingRegs.vhd)
+ -- RadioClkEnables : 0x28 (ClockingRegs.vhd)
+ -- MgtRefClkStatus : 0x30 (ClockingRegs.vhd)
+
+--===============================================================================
+-- RegTypes
+--===============================================================================
+
+--===============================================================================
+-- Register Group ClockingRegs
+--===============================================================================
+
+ -- RadioClkMmcm Register (from ClockingRegs.vhd)
+ constant kRadioClkMmcm : integer := 16#20#; -- Register Offset
+ constant kRadioClkMmcmSize: integer := 32; -- register width in bits
+ constant kRadioClkMmcmMask : std_logic_vector(31 downto 0) := X"00000013";
+ constant kRadioClkMmcmResetSetSize : integer := 1; --RadioClkMmcm:RadioClkMmcmResetSet
+ constant kRadioClkMmcmResetSetMsb : integer := 0; --RadioClkMmcm:RadioClkMmcmResetSet
+ constant kRadioClkMmcmResetSet : integer := 0; --RadioClkMmcm:RadioClkMmcmResetSet
+ constant kRadioClkMmcmResetClearSize : integer := 1; --RadioClkMmcm:RadioClkMmcmResetClear
+ constant kRadioClkMmcmResetClearMsb : integer := 1; --RadioClkMmcm:RadioClkMmcmResetClear
+ constant kRadioClkMmcmResetClear : integer := 1; --RadioClkMmcm:RadioClkMmcmResetClear
+ constant kRadioClkMmcmLockedSize : integer := 1; --RadioClkMmcm:RadioClkMmcmLocked
+ constant kRadioClkMmcmLockedMsb : integer := 4; --RadioClkMmcm:RadioClkMmcmLocked
+ constant kRadioClkMmcmLocked : integer := 4; --RadioClkMmcm:RadioClkMmcmLocked
+
+ -- PhaseShiftControl Register (from ClockingRegs.vhd)
+ constant kPhaseShiftControl : integer := 16#24#; -- Register Offset
+ constant kPhaseShiftControlSize: integer := 32; -- register width in bits
+ constant kPhaseShiftControlMask : std_logic_vector(31 downto 0) := X"10010011";
+ constant kPsIncSize : integer := 1; --PhaseShiftControl:PsInc
+ constant kPsIncMsb : integer := 0; --PhaseShiftControl:PsInc
+ constant kPsInc : integer := 0; --PhaseShiftControl:PsInc
+ constant kPsDecSize : integer := 1; --PhaseShiftControl:PsDec
+ constant kPsDecMsb : integer := 4; --PhaseShiftControl:PsDec
+ constant kPsDec : integer := 4; --PhaseShiftControl:PsDec
+ constant kPsEnabledForFdbClkSize : integer := 1; --PhaseShiftControl:PsEnabledForFdbClk
+ constant kPsEnabledForFdbClkMsb : integer := 16; --PhaseShiftControl:PsEnabledForFdbClk
+ constant kPsEnabledForFdbClk : integer := 16; --PhaseShiftControl:PsEnabledForFdbClk
+ constant kPsDoneSize : integer := 1; --PhaseShiftControl:PsDone
+ constant kPsDoneMsb : integer := 28; --PhaseShiftControl:PsDone
+ constant kPsDone : integer := 28; --PhaseShiftControl:PsDone
+
+ -- RadioClkEnables Register (from ClockingRegs.vhd)
+ constant kRadioClkEnables : integer := 16#28#; -- Register Offset
+ constant kRadioClkEnablesSize: integer := 32; -- register width in bits
+ constant kRadioClkEnablesMask : std_logic_vector(31 downto 0) := X"00000111";
+ constant kRadioClk1xEnabledSize : integer := 1; --RadioClkEnables:RadioClk1xEnabled
+ constant kRadioClk1xEnabledMsb : integer := 0; --RadioClkEnables:RadioClk1xEnabled
+ constant kRadioClk1xEnabled : integer := 0; --RadioClkEnables:RadioClk1xEnabled
+ constant kRadioClk2xEnabledSize : integer := 1; --RadioClkEnables:RadioClk2xEnabled
+ constant kRadioClk2xEnabledMsb : integer := 4; --RadioClkEnables:RadioClk2xEnabled
+ constant kRadioClk2xEnabled : integer := 4; --RadioClkEnables:RadioClk2xEnabled
+ constant kRadioClk3xEnabledSize : integer := 1; --RadioClkEnables:RadioClk3xEnabled
+ constant kRadioClk3xEnabledMsb : integer := 8; --RadioClkEnables:RadioClk3xEnabled
+ constant kRadioClk3xEnabled : integer := 8; --RadioClkEnables:RadioClk3xEnabled
+
+ -- MgtRefClkStatus Register (from ClockingRegs.vhd)
+ constant kMgtRefClkStatus : integer := 16#30#; -- Register Offset
+ constant kMgtRefClkStatusSize: integer := 32; -- register width in bits
+ constant kMgtRefClkStatusMask : std_logic_vector(31 downto 0) := X"00000001";
+ constant kJesdRefClkPresentSize : integer := 1; --MgtRefClkStatus:JesdRefClkPresent
+ constant kJesdRefClkPresentMsb : integer := 0; --MgtRefClkStatus:JesdRefClkPresent
+ constant kJesdRefClkPresent : integer := 0; --MgtRefClkStatus:JesdRefClkPresent
+
+end package;
+
+package body PkgClockingRegMap is
+
+ -- function kRadioClkMmcmRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kPhaseShiftControlRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kRadioClkEnablesRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+ -- function kMgtRefClkStatusRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+end package body;
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgDaughterboardRegMap.vhd b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgDaughterboardRegMap.vhd
new file mode 100644
index 000000000..06708cde3
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgDaughterboardRegMap.vhd
@@ -0,0 +1,56 @@
+-------------------------------------------------------------------------------
+--
+-- File: PkgDaughterboardRegMap.vhd
+-- Author: Autogenerated by XmlParse
+-- Original Project: --
+-- Date: --
+--
+-------------------------------------------------------------------------------
+-- Copyright 2017 Ettus Research, A National Instruments Company
+-- SPDX-License-Identifier: LGPL-3.0
+-------------------------------------------------------------------------------
+--
+-- Purpose:
+-- The constants in this file are autogenerated by XmlParse and should
+-- be used by testbench code to access specific register fields.
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+package PkgDaughterboardRegMap is
+
+--===============================================================================
+-- A numerically ordered list of registers and their VHDL source files
+--===============================================================================
+
+ -- DaughterboardId : 0x630 (DaughterboardRegs.vhd)
+
+--===============================================================================
+-- RegTypes
+--===============================================================================
+
+--===============================================================================
+-- Register Group StaticControl
+--===============================================================================
+
+ -- DaughterboardId Register (from DaughterboardRegs.vhd)
+ constant kDaughterboardId : integer := 16#630#; -- Register Offset
+ constant kDaughterboardIdSize: integer := 32; -- register width in bits
+ constant kDaughterboardIdMask : std_logic_vector(31 downto 0) := X"0001ffff";
+ constant kDbIdValSize : integer := 16; --DaughterboardId:DbIdVal
+ constant kDbIdValMsb : integer := 15; --DaughterboardId:DbIdVal
+ constant kDbIdVal : integer := 0; --DaughterboardId:DbIdVal
+ constant kSlotIdValSize : integer := 1; --DaughterboardId:SlotIdVal
+ constant kSlotIdValMsb : integer := 16; --DaughterboardId:SlotIdVal
+ constant kSlotIdVal : integer := 16; --DaughterboardId:SlotIdVal
+
+end package;
+
+package body PkgDaughterboardRegMap is
+
+ -- function kDaughterboardIdRec not implemented because PkgXReg in this project does not support XReg2_t.
+
+end package body;
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgJesdConfig.vhd b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgJesdConfig.vhd
new file mode 100644
index 000000000..c0f5244b5
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgJesdConfig.vhd
@@ -0,0 +1,234 @@
+-------------------------------------------------------------------------------
+--
+-- File: PkgJesdConfig.vhd
+-- Author: National Instruments
+-- Original Project: NI 5840
+-- Date: 11 March 2016
+--
+-------------------------------------------------------------------------------
+-- Copyright 2016-2018 Ettus Research, A National Instruments Company
+-- SPDX-License-Identifier: LGPL-3.0
+-------------------------------------------------------------------------------
+--
+-- Purpose: JESD204B setup constants and functions. These constants are shared
+-- between RX and TX JESD cores.
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+library work;
+ use work.PkgRegs.all;
+
+
+package PkgJesdConfig is
+
+ -- "JESD" in ASCII - with the core number 0 or 1 on the LSb.
+ constant kJesdSignature : std_logic_vector(31 downto 0) := x"4a455344";
+
+ -- Register endpoints
+ constant kJesdDrpRegsInEndpoint : RegOffset_t := (kOffset => 16#0800#, -- 0x2800 to
+ kWidth => 16#0800#); -- 0x2FFF
+
+ -- Selects the UsrClk2 for the transceivers. For 64-bit wide transceivers, the
+ -- UsrClk = 2*UserClk2 frequency. For 32-bit wide transceivers, UsrClk = UserClk2
+ -- frequency. This is a generalization, the clock ratio should be confirmed based on
+ -- the transceiver configuration.
+ -- The N310 transceivers use the single rate reference, hence = false.
+ constant kDoubleRateUsrClk : boolean := false;
+
+ -- For the N310, all lanes are in one quad and we use the QPLL.
+ constant kJesdUseQpll : boolean := true;
+
+ constant kAdcDataWidth : integer := 16; -- ADC data width in bits
+ constant kDacDataWidth : integer := 16; -- DAC data width in bits
+ constant kSamplesPerCycle : integer := 1; -- Number of samples per SampleClk1x
+
+ constant kGtxDrpAddrWidth : natural := 9;
+ constant kQpllDrpAddrWidth : natural := 8;
+ -- Max supported number of lanes
+ constant kMaxNumLanes : natural := 4;
+ -- Max supported number of quads (normally there is 1 quad per 4 lanes but disconnect
+ -- the definitions to allow quad sharing)
+ constant kMaxNumQuads : natural := 1;
+
+
+ -- JESD shared setup - LMFS = 4421, HD = 0
+ constant kNumLanes : natural := 4; -- L
+ constant kNumConvs : positive := 4; -- M
+ constant kOctetsPerFrame : natural := 2; -- F
+ constant kDacJesdSamplesPerCycle : integer := 1; -- S
+ constant kOctetsPerLane : natural := 2; -- MGT data is kOctetsPerLane*8 = 16 bits wide
+ constant kNumQuads : natural := kNumLanes/4; -- 4 lanes per quad
+ constant kHighDensity : boolean := false; -- HD
+ constant kConvResBits : positive := kDacDataWidth-2; -- Converter resolution in bits
+ constant kConvSampleBits : positive := kDacDataWidth; -- Sample Length in bits
+ constant kInitLaneAlignCnt : positive := 4;
+ constant kFramesPerMulti : natural := 20; -- K
+
+ -- In the N310 case we are one SPC, so this value is simply the number of frames
+ -- (samples) per multiframe.
+ constant kUserClksPerMulti : integer := kFramesPerMulti;
+
+
+ type NaturalVector is array ( natural range <>) of natural;
+
+ -- The PCB connections are as follows:
+ --
+ -- Transceiver MGT Channel ADC Lane DAC Lane
+ -- *********** *********** ******** ********
+ -- GT0: X0Y8 0 0 0
+ -- GT1: X0Y9 1 1 1
+ -- GT2: X0Y10 2 2 2
+ -- GT3: X0Y11 3 3 3
+ constant kRxLaneIndices : NaturalVector(kNumLanes - 1 downto 0) :=
+ (
+ -- MGT => ADC (in above table)
+ 0 => 0,
+ 1 => 1,
+ 2 => 2,
+ 3 => 3
+ );
+
+ constant kTxLaneIndices : NaturalVector(kNumLanes - 1 downto 0) :=
+ (
+ -- MGT => DAC lane
+ 0 => 0,
+ 1 => 1,
+ 2 => 2,
+ 3 => 3
+ );
+
+ constant kLaneToQuadMap : NaturalVector(kNumLanes - 1 downto 0) :=
+ (
+ -- All lanes are in one quad
+ 0 => 0,
+ 1 => 0,
+ 2 => 0,
+ 3 => 0
+ );
+
+
+ -- The master transceiver channel for channel bonding. E(kMasterBondingChannel)
+ -- must have the highest value decrementing to b"000" for that last channels to bond.
+ constant kMasterBondingChannel : integer := 1;
+
+ -- Channel bonding occurs when a master detects a K-char sequence and aligns its
+ -- internal FIFO to the start of this sequence. A signal is then generated to other
+ -- slave transceivers that cause them to bond to the sequence - this bonding signal is
+ -- cascaded from master to slave to slave to slave, etc where each slave must know how
+ -- many levels to the master there are. The last slave to bond must be at level b"000"
+ -- and the master is at the highest level; the number of levels in the sequence is
+ -- governed by the size of the transceiver FIFO (see the Xilinx user guides for more
+ -- information).
+ type BondLevels_t is array(0 to kNumLanes - 1) of std_logic_vector(2 downto 0);
+ constant kBondLevel : BondLevels_t := (
+ 0 => b"000", -- Control from 1
+ 1 => b"001", -- Master
+ 2 => b"000", -- Control from 1
+ 3 => b"000" -- Control from 1
+ );
+
+ -- Option to pipeline stages to improve timing, if needed
+ constant kPipelineDetectCharsStage : boolean := false;
+ constant kPipelineCharReplStage : boolean := false;
+
+
+ -- ADC & DAC Data Types
+ --
+
+ -- ADC Words from JESD204B RX Core. The array is 4 elements wide to accommodate the
+ -- I & Q elements from both RX channels.
+ subtype AdcWord_t is std_logic_vector(kAdcDataWidth - 1 downto 0);
+ type AdcWordArray_t is array(4 - 1 downto 0) of AdcWord_t;
+
+ -- Data types for manipulation and presentation to outside world.
+ type AdcData_t is record
+ I : std_logic_vector(kAdcDataWidth - 1 downto 0);
+ Q : std_logic_vector(kAdcDataWidth - 1 downto 0);
+ end record;
+
+ type DacData_t is record
+ I : std_logic_vector(kDacDataWidth - 1 downto 0);
+ Q : std_logic_vector(kDacDataWidth - 1 downto 0);
+ end record;
+
+
+ -- Flattened data types for passing into and out of pre-synthesized components.
+ subtype AdcDataFlat_t is std_logic_vector(2*kAdcDataWidth - 1 downto 0);
+ subtype DacDataFlat_t is std_logic_vector(2*kDacDataWidth - 1 downto 0);
+
+ -- Functions to convert to/from types defined above.
+ function Flatten (AdcData : AdcData_t) return AdcDataFlat_t;
+ function Unflatten(AdcData : AdcDataFlat_t) return AdcData_t;
+
+ function Flatten (DacData : DacData_t) return DacDataFlat_t;
+ function Unflatten(DacData : DacDataFlat_t) return DacData_t;
+
+
+end package;
+
+
+package body PkgJesdConfig is
+
+
+
+
+
+ -- Flattens AdcData_t to AdcDataFlat_t
+ function Flatten (AdcData : AdcData_t) return AdcDataFlat_t
+ is
+ variable ReturnVar : AdcDataFlat_t;
+ begin
+ ReturnVar := (others => '0');
+ -- MSB is I
+ ReturnVar := AdcData.I & AdcData.Q;
+ return ReturnVar;
+ end function Flatten;
+
+
+ -- UnFlattens AdcDataFlat_t to AdcData_t
+ function Unflatten(AdcData : AdcDataFlat_t) return AdcData_t
+ is
+ variable ReturnVar : AdcData_t;
+ begin
+ ReturnVar := (others => (others => '0'));
+ -- MSB is I
+ ReturnVar.I := AdcData(2*kAdcDataWidth - 1 downto kAdcDataWidth);
+ ReturnVar.Q := AdcData( kAdcDataWidth - 1 downto 0);
+ return ReturnVar;
+ end function Unflatten;
+
+
+
+ -- Flattens DacData_t to DacDataFlat_t
+ function Flatten (DacData : DacData_t) return DacDataFlat_t
+ is
+ variable ReturnVar : DacDataFlat_t;
+ begin
+ ReturnVar := (others => '0');
+ -- MSB is I
+ ReturnVar := DacData.I & DacData.Q;
+ return ReturnVar;
+ end function Flatten;
+
+
+ -- UnFlattens DacDataFlat_t to DacData_t
+ function Unflatten(DacData : DacDataFlat_t) return DacData_t
+ is
+ variable ReturnVar : DacData_t;
+ begin
+ ReturnVar := (others => (others => '0'));
+ -- MSB is I
+ ReturnVar.I := DacData(2*kDacDataWidth - 1 downto kDacDataWidth);
+ ReturnVar.Q := DacData( kDacDataWidth - 1 downto 0);
+ return ReturnVar;
+ end function Unflatten;
+
+
+
+
+
+end package body; \ No newline at end of file
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgMgPersonality.vhd b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgMgPersonality.vhd
new file mode 100644
index 000000000..904653a8e
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/PkgMgPersonality.vhd
@@ -0,0 +1,61 @@
+-------------------------------------------------------------------------------
+--
+-- File: PkgMgPersonality.vhd
+-- Author: National Instruments
+-- Original Project: N310
+-- Date: 13 April 2017
+--
+-------------------------------------------------------------------------------
+-- Copyright 2017 Ettus Research, A National Instruments Company
+-- SPDX-License-Identifier: LGPL-3.0
+-------------------------------------------------------------------------------
+--
+-- Purpose: This package contains constants and helpful functions that enable
+-- the FPGA to be compiled with different features.
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+library work;
+ use work.PkgRegs.all;
+
+
+package PkgMgPersonality is
+
+
+ -- RegPort Address Definitions : ------------------------------------------------------
+ --
+ -- DB Regs ...
+ --
+ -- Clocking Offset: 0x 000 Width: 0x 200
+ -- Tdco0 Offset: 0x 200 Width: 0x 200
+ -- Tdco1 Offset: 0x 400 Width: 0x 200
+ -- Daughterboard Ctrl Offset: 0x 600 Width: 0x 200
+ -- Total: 0x2000
+ -- JESD 2x - A Offset: 0x2000 Width: 0x1000
+ -- JESD 2x - B Offset: 0x3000 Width: 0x1000
+ -- Total: 0x4000
+ -- Total: 0x8000 for two DBs
+ -- ------------------------------------------------------------------------------------
+
+ -- A single RegPort runs to the JESD204B Core.
+ constant kJesdRegGroupInDbRegs : RegOffset_t := (kOffset => 16#2000#, -- 0x2000 to
+ kWidth => 16#1000#); -- 0x2FFF
+
+ -- DB Regs : --------------------------------------------------------------------------
+ constant kClockingOffsetInEndpoint : RegOffset_t := (kOffset => 16#0000#, -- 0x0000 to
+ kWidth => 16#0200#); -- 0x01FF
+ constant kTdc0OffsetsInEndpoint : RegOffset_t := (kOffset => 16#0200#, -- 0x0200 to
+ kWidth => 16#0200#); -- 0x03FF
+ constant kTdc1OffsetsInEndpoint : RegOffset_t := (kOffset => 16#0400#, -- 0x0400 to
+ kWidth => 16#0200#); -- 0x05FF
+ constant kDaughterboardOffsetInEndpoint : RegOffset_t := (kOffset => 16#0600#, -- 0x0600 to
+ kWidth => 16#0200#); -- 0x07FF
+
+
+
+
+end package PkgMgPersonality;
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/RadioClocking.vhd b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/RadioClocking.vhd
new file mode 100644
index 000000000..ee0da9f84
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/db_ifc/RadioClocking.vhd
@@ -0,0 +1,304 @@
+-------------------------------------------------------------------------------
+--
+-- File: RadioClocking.vhd
+-- Author: Daniel Jepson
+-- Original Project: N310
+-- Date: 22 February 2016
+--
+-------------------------------------------------------------------------------
+-- Copyright 2016-2018 Ettus Research, A National Instruments Company
+-- SPDX-License-Identifier: LGPL-3.0
+-------------------------------------------------------------------------------
+--
+-- Purpose:
+--
+-- Instantiates a MMCM to produce 1x, 2x, and 3x versions of the Radio Clock
+-- coming from the FPGA input pin. Handles all the buffering for the input clock.
+-- Additionally allows the clocks to be turned on and off, and phase shifted.
+--
+-- NOTE: This module hard-codes the MMCM settings for a SPECIFIC clock rate!
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+
+library unisim;
+ use unisim.vcomponents.all;
+
+
+entity RadioClocking is
+ port (
+ -- Async reset. Can be tied low if desired.
+ aReset : in boolean;
+ -- Sync reset... used in the same places as the async one.
+ bReset : in boolean;
+
+ -- Should be a always-on clock
+ BusClk : in std_logic;
+
+ -- Sync reset to the RadioClkMmcm.
+ bRadioClkMmcmReset : in std_logic;
+
+ -- Locked indication from the RadioClkMmcm in BusClk and aReset domains.
+ bRadioClksValid : out std_logic;
+
+ bRadioClk1xEnabled : in std_logic;
+ bRadioClk2xEnabled : in std_logic;
+ bRadioClk3xEnabled : in std_logic;
+
+ -- Phase shift interface for the RadioClkMmcm. PsClk must be <= 200 MHz.
+ pPsInc : in std_logic;
+ pPsEn : in std_logic;
+ PsClk : in std_logic;
+ pPsDone : out std_logic;
+
+ -- Straight from pins. Buffer included in here.
+ FpgaClk_n : in std_logic;
+ FpgaClk_p : in std_logic;
+
+ RadioClk1x : out std_logic;
+ RadioClk2x : out std_logic;
+ RadioClk3x : out std_logic
+
+ );
+end RadioClocking;
+
+
+architecture rtl of RadioClocking is
+
+ --vhook_sigstart
+ signal RadioClk1xLcl: std_logic;
+ signal RadioClk1xPll: std_logic;
+ signal RadioClk2xLcl: std_logic;
+ signal RadioClk2xPll: std_logic;
+ signal RadioClk3xLcl: std_logic;
+ signal RadioClk3xPll: std_logic;
+ --vhook_sigend
+
+ signal RadioClkMmcmFeedbackIn,
+ RadioClkMmcmFeedbackOut,
+ FpgaClkSE,
+ aRadioClkMmcmLocked : std_logic;
+
+ signal bRadioClkMmcmLocked_ms,
+ bRadioClkMmcmLocked,
+ bEnableRadioClkBufgOutputs,
+ bEnableRadioClk1xBufgOutput,
+ bEnableRadioClk2xBufgOutput,
+ bEnableRadioClk3xBufgOutput : std_logic := '0';
+
+ signal aRadioClkMmcmResetInternal : std_logic := '1';
+
+ attribute ASYNC_REG : string;
+ attribute ASYNC_REG of bRadioClkMmcmLocked_ms : signal is "true";
+ attribute ASYNC_REG of bRadioClkMmcmLocked : signal is "true";
+
+begin
+
+ -- Radio Clock Buffering : ------------------------------------------------------------
+ --
+ -- ------------------------------------------------------------------------------------
+ --vhook_i IBUFDS FpgaClkIbufg hidegeneric=true
+ --vhook_a I FpgaClk_p
+ --vhook_a IB FpgaClk_n
+ --vhook_a O FpgaClkSE
+ FpgaClkIbufg: IBUFDS
+ port map (
+ O => FpgaClkSE, --out std_ulogic
+ I => FpgaClk_p, --in std_ulogic
+ IB => FpgaClk_n); --in std_ulogic
+
+ ResetDelay : process(aReset, BusClk)
+ begin
+ if aReset then
+ aRadioClkMmcmResetInternal <= '1';
+ elsif rising_edge(BusClk) then
+ if bReset then
+ aRadioClkMmcmResetInternal <= '1';
+ else
+ -- Delay by 1 to allow the BUFGs to turn off before the MMCM is reset.
+ aRadioClkMmcmResetInternal <= bRadioClkMmcmReset;
+ end if;
+ end if;
+ end process ResetDelay;
+
+
+ RadioClkMmcm: MMCME2_ADV
+ generic map(
+ COMPENSATION => "ZHOLD",
+ BANDWIDTH => "OPTIMIZED",
+ CLKFBOUT_MULT_F => 6.000, -- Feedback
+ CLKOUT0_DIVIDE_F => 6.000, -- Data Clock 1x, RadioClk1xPll
+ CLKOUT1_DIVIDE => 3, -- Data Clock 2x, RadioClk2xPll
+ CLKOUT2_DIVIDE => 2, -- Data Clock 3x, RadioClk3xPll
+ CLKOUT3_DIVIDE => 1, -- unused
+ CLKOUT4_DIVIDE => 1, -- unused
+ CLKOUT5_DIVIDE => 1, -- unused
+ CLKOUT6_DIVIDE => 1, -- unused
+ CLKFBOUT_PHASE => 0.000, -- Feedback
+ CLKOUT0_PHASE => 0.000, -- Data Clock 1x
+ CLKOUT1_PHASE => 0.000, -- Data Clock 2x
+ CLKOUT2_PHASE => 0.000, -- Data Clock 3x
+ CLKOUT3_PHASE => 0.000, -- unused
+ CLKOUT4_PHASE => 0.000, -- unused
+ CLKOUT5_PHASE => 0.000, -- unused
+ CLKOUT6_PHASE => 0.000, -- unused
+ CLKOUT0_DUTY_CYCLE => 0.500,
+ CLKOUT1_DUTY_CYCLE => 0.500,
+ CLKOUT2_DUTY_CYCLE => 0.500,
+ CLKOUT3_DUTY_CYCLE => 0.500,
+ CLKOUT4_DUTY_CYCLE => 0.500,
+ CLKOUT5_DUTY_CYCLE => 0.500,
+ CLKOUT6_DUTY_CYCLE => 0.500,
+ DIVCLK_DIVIDE => 1,
+ REF_JITTER1 => 0.010,
+ CLKIN1_PERIOD => 6.510, -- 153.6 MHz max
+ CLKFBOUT_USE_FINE_PS => true,
+ CLKOUT0_USE_FINE_PS => false,
+ CLKOUT1_USE_FINE_PS => false,
+ CLKOUT2_USE_FINE_PS => false,
+ CLKOUT3_USE_FINE_PS => false,
+ CLKOUT4_USE_FINE_PS => false,
+ CLKOUT5_USE_FINE_PS => false,
+ CLKOUT6_USE_FINE_PS => false,
+ STARTUP_WAIT => false,
+ CLKOUT4_CASCADE => false)
+ port map (
+ CLKINSEL => '1',
+ CLKIN1 => FpgaClkSE,
+ CLKIN2 => '0',
+ CLKFBIN => RadioClkMmcmFeedbackIn,
+ RST => aRadioClkMmcmResetInternal,
+ PWRDWN => '0',
+ DADDR => (others => '0'),
+ DI => (others => '0'),
+ DWE => '0',
+ DEN => '0',
+ DCLK => '0',
+ DO => open,
+ DRDY => open,
+ PSINCDEC => pPsInc,
+ PSEN => pPsEn,
+ PSCLK => PsClk,
+ PSDONE => pPsDone,
+ CLKOUT0 => RadioClk1xPll,
+ CLKOUT0B => open,
+ CLKOUT1 => RadioClk2xPll,
+ CLKOUT1B => open,
+ CLKOUT2 => RadioClk3xPll,
+ CLKOUT2B => open,
+ CLKOUT3 => open,
+ CLKOUT3B => open,
+ CLKOUT4 => open,
+ CLKOUT5 => open,
+ CLKOUT6 => open,
+ CLKFBOUT => RadioClkMmcmFeedbackOut,
+ CLKFBOUTB => open,
+ LOCKED => aRadioClkMmcmLocked,
+ CLKINSTOPPED => open,
+ CLKFBSTOPPED => open);
+
+ RadioClkMmcmFeedbackBufg: BUFG
+ port map (
+ I => RadioClkMmcmFeedbackOut,
+ O => RadioClkMmcmFeedbackIn
+ );
+
+
+ -- Only enable the WRAPBUFGs when the MMCM is locked. If the MMCM is ever placed in
+ -- reset, we turn off the clocks one cycle before the asynchronous version
+ -- (aRadioClkMmcmResetInternal) reaches the MMCM inputs in order to prevent
+ -- output glitches.
+ CombineEnablesForBuffers : process(aReset, BusClk)
+ begin
+ if aReset then
+ bRadioClkMmcmLocked_ms <= '0';
+ bRadioClkMmcmLocked <= '0';
+ bEnableRadioClk1xBufgOutput <= '0';
+ bEnableRadioClk2xBufgOutput <= '0';
+ bEnableRadioClk3xBufgOutput <= '0';
+ bEnableRadioClkBufgOutputs <= '0';
+ elsif rising_edge(BusClk) then
+ if bReset then
+ bRadioClkMmcmLocked_ms <= '0';
+ bRadioClkMmcmLocked <= '0';
+ bEnableRadioClk1xBufgOutput <= '0';
+ bEnableRadioClk2xBufgOutput <= '0';
+ bEnableRadioClk3xBufgOutput <= '0';
+ bEnableRadioClkBufgOutputs <= '0';
+ else
+ bRadioClkMmcmLocked_ms <= aRadioClkMmcmLocked;
+ bRadioClkMmcmLocked <= bRadioClkMmcmLocked_ms;
+
+ bEnableRadioClkBufgOutputs <= bRadioClkMmcmLocked and
+ not bRadioClkMmcmReset;
+ bEnableRadioClk1xBufgOutput <= bRadioClk1xEnabled and bEnableRadioClkBufgOutputs;
+ bEnableRadioClk2xBufgOutput <= bRadioClk2xEnabled and bEnableRadioClkBufgOutputs;
+ bEnableRadioClk3xBufgOutput <= bRadioClk3xEnabled and bEnableRadioClkBufgOutputs;
+ end if;
+ end if;
+ end process CombineEnablesForBuffers;
+
+ bRadioClksValid <= bEnableRadioClkBufgOutputs;
+
+ --vhook_e WrapBufg RadioClk1xBuf
+ --vhook_a kEnableByDefault false
+ --vhook_a kIgnore false
+ --vhook_a kEnableIsAsync true
+ --vhook_a ClkIn RadioClk1xPll
+ --vhook_a aCe bEnableRadioClk1xBufgOutput
+ --vhook_a ClkOut RadioClk1xLcl
+ RadioClk1xBuf: entity work.WrapBufg (rtl)
+ generic map (
+ kEnableByDefault => false, --boolean:=false
+ kIgnore => false, --boolean:=false
+ kEnableIsAsync => true) --boolean:=false
+ port map (
+ ClkIn => RadioClk1xPll, --in std_logic
+ aCe => bEnableRadioClk1xBufgOutput, --in std_logic
+ ClkOut => RadioClk1xLcl); --out std_logic
+
+ --vhook_e WrapBufg RadioClk2xBuf
+ --vhook_a kEnableByDefault false
+ --vhook_a kIgnore false
+ --vhook_a kEnableIsAsync true
+ --vhook_a ClkIn RadioClk2xPll
+ --vhook_a aCe bEnableRadioClk2xBufgOutput
+ --vhook_a ClkOut RadioClk2xLcl
+ RadioClk2xBuf: entity work.WrapBufg (rtl)
+ generic map (
+ kEnableByDefault => false, --boolean:=false
+ kIgnore => false, --boolean:=false
+ kEnableIsAsync => true) --boolean:=false
+ port map (
+ ClkIn => RadioClk2xPll, --in std_logic
+ aCe => bEnableRadioClk2xBufgOutput, --in std_logic
+ ClkOut => RadioClk2xLcl); --out std_logic
+
+ --vhook_e WrapBufg RadioClk3xBuf
+ --vhook_a kEnableByDefault false
+ --vhook_a kIgnore false
+ --vhook_a kEnableIsAsync true
+ --vhook_a ClkIn RadioClk3xPll
+ --vhook_a aCe bEnableRadioClk3xBufgOutput
+ --vhook_a ClkOut RadioClk3xLcl
+ RadioClk3xBuf: entity work.WrapBufg (rtl)
+ generic map (
+ kEnableByDefault => false, --boolean:=false
+ kIgnore => false, --boolean:=false
+ kEnableIsAsync => true) --boolean:=false
+ port map (
+ ClkIn => RadioClk3xPll, --in std_logic
+ aCe => bEnableRadioClk3xBufgOutput, --in std_logic
+ ClkOut => RadioClk3xLcl); --out std_logic
+
+
+ -- Assign outputs from locals.
+ RadioClk1x <= RadioClk1xLcl;
+ RadioClk2x <= RadioClk2xLcl;
+ RadioClk3x <= RadioClk3xLcl;
+
+
+
+end rtl;
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/db_timing.xdc b/fpga/usrp3/top/n3xx/dboards/mg/db_timing.xdc
new file mode 100644
index 000000000..142ba9ab4
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/db_timing.xdc
@@ -0,0 +1,347 @@
+#
+# Copyright 2017 Ettus Research, A National Instruments Company
+# SPDX-License-Identifier: LGPL-3.0
+#
+# Timing analysis is performed in "/n3xx/dboards/mg/doc/mg_timing.xlsx". See
+# the spreadsheet for more details and explanations.
+
+#*******************************************************************************
+## Daughterboard Clocks
+
+# 122.88, 125, and 153.6 MHz Sample Clocks are allowable. Constrain the paths to the max
+# rate in order to support all rates in a single FPGA image.
+set SAMPLE_CLK_PERIOD 6.510
+create_clock -name fpga_clk_a -period $SAMPLE_CLK_PERIOD [get_ports DBA_FPGA_CLK_P]
+create_clock -name fpga_clk_b -period $SAMPLE_CLK_PERIOD [get_ports DBB_FPGA_CLK_P]
+create_clock -name mgt_clk_dba -period $SAMPLE_CLK_PERIOD [get_ports USRPIO_A_MGTCLK_P]
+create_clock -name mgt_clk_dbb -period $SAMPLE_CLK_PERIOD [get_ports USRPIO_B_MGTCLK_P]
+
+# The Radio Clocks coming from the DBs are synchronized together (at the ADCs) to a
+# typical value of less than 100ps. To give ourselves and Vivado some margin, we claim
+# here that the DB-B Radio Clock can arrive 500ps before or after the DB-A clock at
+# the FPGA (note that the trace lengths of the Radio Clocks coming from the DBs to the
+# FPGA are about 0.5" different, thereby incurring ~80ps of additional skew at the FPGA).
+# There is one spot in the FPGA where we cross domains between the DB-A and
+# DB-B clock, so we must ensure that Vivado can analyze that path safely.
+set FPGA_CLK_EARLY -0.5
+set FPGA_CLK_LATE 0.5
+set_clock_latency -source -early $FPGA_CLK_EARLY [get_clocks fpga_clk_b]
+set_clock_latency -source -late $FPGA_CLK_LATE [get_clocks fpga_clk_b]
+
+# Virtual clocks for constraining I/O (used below)
+create_clock -name fpga_clk_a_v -period $SAMPLE_CLK_PERIOD
+create_clock -name fpga_clk_b_v -period $SAMPLE_CLK_PERIOD
+
+# The set_clock_latency constraints set on fpga_clk_b are problematic when used with
+# I/O timing, since the analyzer gives us a double-hit on the latency. One workaround
+# (used here) is to simply swap the early and late times for the virtual clock so that
+# it cancels out the source latency during analysis. I tested this by setting the
+# early and late numbers to zero and then their actual value, running timing reports
+# on each. The slack report matches for both cases, showing that the reversed early/late
+# numbers on the virtual clock zero out the latency effects on the actual clock.
+#
+# Note this is not a problem for the fpga_clk_a, since no latency is added. So only apply
+# it to fpga_clk_b_v.
+set_clock_latency -source -early $FPGA_CLK_LATE [get_clocks fpga_clk_b_v]
+set_clock_latency -source -late $FPGA_CLK_EARLY [get_clocks fpga_clk_b_v]
+
+
+
+#*******************************************************************************
+## Aliases for auto-generated clocks
+
+create_generated_clock -name radio_clk_fb [get_pins {dba_core/RadioClockingx/RadioClkMmcm/CLKFBOUT}]
+create_generated_clock -name radio_clk [get_pins {dba_core/RadioClockingx/RadioClkMmcm/CLKOUT0}]
+create_generated_clock -name radio_clk_2x [get_pins {dba_core/RadioClockingx/RadioClkMmcm/CLKOUT1}]
+
+create_generated_clock -name radio_clk_b_fb [get_pins {dbb_core/RadioClockingx/RadioClkMmcm/CLKFBOUT}]
+create_generated_clock -name radio_clk_b [get_pins {dbb_core/RadioClockingx/RadioClkMmcm/CLKOUT0}]
+create_generated_clock -name radio_clk_b_2x [get_pins {dbb_core/RadioClockingx/RadioClkMmcm/CLKOUT1}]
+
+
+
+#*******************************************************************************
+## Generated clocks for output busses to the daughterboard
+#
+# These clock definitions need to come above the set_clock_groups commands below to work!
+
+# Define clocks on the PL SPI clock output pins for both DBs. Actual divider values are
+# set by SW at run-time. Divider values are 123, 125, or 154 based on what radio clock
+# rate is set. To be ultra-conservative (which still provides 10s of ns of slack), we
+# set an over-constrained divider value of 50.
+set PL_SPI_DIVIDE_VAL 50
+set PL_SPI_CLK_A [get_ports DBA_CPLD_PL_SPI_SCLK]
+create_generated_clock -name pl_spi_clk_a \
+ -source [get_pins [all_fanin -flat -only_cells -startpoints_only $PL_SPI_CLK_A]/C] \
+ -divide_by $PL_SPI_DIVIDE_VAL $PL_SPI_CLK_A
+set PL_SPI_CLK_B [get_ports DBB_CPLD_PL_SPI_SCLK]
+create_generated_clock -name pl_spi_clk_b \
+ -source [get_pins [all_fanin -flat -only_cells -startpoints_only $PL_SPI_CLK_B]/C] \
+ -divide_by $PL_SPI_DIVIDE_VAL $PL_SPI_CLK_B
+
+# Define one of the outputs of each bus as a clock (even though it isn't a clock). This
+# allows us to constrain the overall bus skew with respect to one of the bus outputs.
+# See the remainder of this constraint below for more details.
+set DSA_CLK [get_ports {DBA_CH1_RX_DSA_DATA[0]}]
+create_generated_clock -name dsa_bus_clk \
+ -source [get_pins [all_fanin -flat -only_cells -startpoints_only $DSA_CLK]/C] \
+ -divide_by 2 $DSA_CLK
+
+set ATR_CLK [get_ports DBA_ATR_RX_1]
+create_generated_clock -name atr_bus_clk \
+ -source [get_pins [all_fanin -flat -only_cells -startpoints_only $ATR_CLK]/C] \
+ -divide_by 2 $ATR_CLK
+
+# Interface Unused
+# set MGPIO_CLK [get_ports DBA_MYK_GPIO_0]
+# create_generated_clock -name myk_gpio_bus_clk \
+ # -source [get_pins [all_fanin -flat -only_cells -startpoints_only [get_ports $MGPIO_CLK]]/C] \
+ # -divide_by 2 [get_ports $MGPIO_CLK]
+
+
+
+#*******************************************************************************
+## Asynchronous clock groups
+
+# MGT reference clocks are also async to everything.
+set_clock_groups -asynchronous -group [get_clocks mgt_clk_dba -include_generated_clocks]
+set_clock_groups -asynchronous -group [get_clocks mgt_clk_dbb -include_generated_clocks]
+
+# fpga_clk_a and fpga_clk_b are related to one another after synchronization.
+# However, we do need to declare that these clocks (both a and b) and their children
+# are async to the remainder of the design. Use the wildcard at the end to grab the
+# virtual clock as well as the real ones.
+set_clock_groups -asynchronous -group [get_clocks {fpga_clk_a* fpga_clk_b*} -include_generated_clocks]
+
+
+
+#*******************************************************************************
+## PS SPI: since these lines all come from the PS and I don't have access to the
+# driving clock (or anything for that matter), I'm left with constraining the maximum
+# and minimum delay on these lines, per a Xilinx AR:
+# https://www.xilinx.com/support/answers/62122.html
+set CPLD_SPI_OUTS [get_ports {DB*_CPLD_PS_SPI_SCLK \
+ DB*_CPLD_PS_SPI_SDI \
+ DB*_CPLD_PS_SPI_LE \
+ DB*_CPLD_PS_SPI_ADDR[0] \
+ DB*_CPLD_PS_SPI_ADDR[1]}]
+
+set_max_delay 12.0 -to $CPLD_SPI_OUTS
+set_min_delay 3.0 -to $CPLD_SPI_OUTS
+
+set MYK_SPI_OUTS [get_ports {DB*_MYK_SPI_SCLK \
+ DB*_MYK_SPI_SDIO \
+ DB*_MYK_SPI_CS_n}]
+
+set_max_delay 14.0 -to $MYK_SPI_OUTS
+set_min_delay 3.0 -to $MYK_SPI_OUTS
+
+# report_timing -to $CPLD_SPI_OUTS -max_paths 20 -delay_type min_max -name CpldSpiOutTiming
+# report_timing -to $MYK_SPI_OUTS -max_paths 20 -delay_type min_max -name MykSpiOutTiming
+
+set MIN_IN_DELAY 2.0
+set MAX_IN_DELAY 10.0
+
+set PS_SPI_INPUTS_0 [get_pins -hierarchical -filter {NAME =~ "*/PS7_i/EMIOSPI0MI"}]
+set PS_SPI_INPUTS_1 [get_pins -hierarchical -filter {NAME =~ "*/PS7_i/EMIOSPI1MI"}]
+
+set_max_delay $MAX_IN_DELAY -to $PS_SPI_INPUTS_0
+set_min_delay $MIN_IN_DELAY -to $PS_SPI_INPUTS_0
+set_max_delay $MAX_IN_DELAY -to $PS_SPI_INPUTS_1
+set_min_delay $MIN_IN_DELAY -to $PS_SPI_INPUTS_1
+
+# report_timing -to $PS_SPI_INPUTS_0 -max_paths 30 -delay_type min_max -nworst 30 -name Spi0InTiming
+# report_timing -to $PS_SPI_INPUTS_1 -max_paths 30 -delay_type min_max -nworst 30 -name Spi1InTiming
+
+
+
+#*******************************************************************************
+## PL SPI to the CPLD
+#
+# All of these lines are driven or received from flops in simple_spi_core. The CPLD
+# calculations assume the FPGA has less than 20 ns of skew between the SCK and
+# SDI/CS_n. Pretty easy constraint to write! See above for the clock definition.
+# Do this for DBA and DBB independently.
+set MAX_SKEW 20.0
+set SETUP_SKEW [expr {$MAX_SKEW / 2}]
+set HOLD_SKEW [expr {$MAX_SKEW / 2}]
+# Do not set the output delay constraint on the clock line!
+set PORT_LIST_A [get_ports {DBA_CPLD_PL_SPI_LE \
+ DBA_CPLD_PL_SPI_SDI \
+ DBA_CPLD_PL_SPI_ADDR[0] \
+ DBA_CPLD_PL_SPI_ADDR[1]}]
+set PORT_LIST_B [get_ports {DBB_CPLD_PL_SPI_LE \
+ DBB_CPLD_PL_SPI_SDI \
+ DBB_CPLD_PL_SPI_ADDR[0] \
+ DBB_CPLD_PL_SPI_ADDR[1]}]
+# Then add the output delay on each of the ports.
+set_output_delay -clock [get_clocks pl_spi_clk_a] -max -$SETUP_SKEW $PORT_LIST_A
+set_output_delay -add_delay -clock_fall -clock [get_clocks pl_spi_clk_a] -max -$SETUP_SKEW $PORT_LIST_A
+set_output_delay -clock [get_clocks pl_spi_clk_a] -min $HOLD_SKEW $PORT_LIST_A
+set_output_delay -add_delay -clock_fall -clock [get_clocks pl_spi_clk_a] -min $HOLD_SKEW $PORT_LIST_A
+set_output_delay -clock [get_clocks pl_spi_clk_b] -max -$SETUP_SKEW $PORT_LIST_B
+set_output_delay -add_delay -clock_fall -clock [get_clocks pl_spi_clk_b] -max -$SETUP_SKEW $PORT_LIST_B
+set_output_delay -clock [get_clocks pl_spi_clk_b] -min $HOLD_SKEW $PORT_LIST_B
+set_output_delay -add_delay -clock_fall -clock [get_clocks pl_spi_clk_b] -min $HOLD_SKEW $PORT_LIST_B
+# Finally, make both the setup and hold checks use the same launching and latching edges.
+set_multicycle_path -setup -from [get_clocks radio_clk] -to [get_clocks pl_spi_clk_a] -start 0
+set_multicycle_path -hold -from [get_clocks radio_clk] -to [get_clocks pl_spi_clk_a] -1
+set_multicycle_path -setup -from [get_clocks radio_clk] -to [get_clocks pl_spi_clk_b] -start 0
+set_multicycle_path -hold -from [get_clocks radio_clk] -to [get_clocks pl_spi_clk_b] -1
+
+# For SDO input timing (MISO), we need to look at the CPLD's constraints on turnaround
+# time plus any board propagation delay.
+set MISO_INPUT_A [get_ports DBA_CPLD_PL_SPI_SDO]
+set MISO_INPUT_B [get_ports DBB_CPLD_PL_SPI_SDO]
+set_input_delay -clock [get_clocks pl_spi_clk_a] -clock_fall -max 68.041 $MISO_INPUT_A
+set_input_delay -clock [get_clocks pl_spi_clk_a] -clock_fall -min 12.218 $MISO_INPUT_A
+set_input_delay -clock [get_clocks pl_spi_clk_b] -clock_fall -max 68.041 $MISO_INPUT_B
+set_input_delay -clock [get_clocks pl_spi_clk_b] -clock_fall -min 12.218 $MISO_INPUT_B
+# Since the input delay span is clearly more than a period of the radio_clk, we need to
+# add a multicycle path here as well to define the clock divider ratio. The MISO data
+# is driven on the falling edge of the SPI clock and captured on the rising edge, so we
+# only have one half of a SPI clock cycle for our setup. Hold is left alone and is OK
+# as-is due to the delays in the CPLD and board.
+set SETUP_CYCLES [expr {$PL_SPI_DIVIDE_VAL / 2}]
+set HOLD_CYCLES 0
+set_multicycle_path -setup -from [get_clocks pl_spi_clk_a] -through $MISO_INPUT_A \
+ $SETUP_CYCLES
+set_multicycle_path -hold -from [get_clocks pl_spi_clk_a] -through $MISO_INPUT_A -end \
+ [expr {$SETUP_CYCLES + $HOLD_CYCLES - 1}]
+set_multicycle_path -setup -from [get_clocks pl_spi_clk_b] -through $MISO_INPUT_B \
+ $SETUP_CYCLES
+set_multicycle_path -hold -from [get_clocks pl_spi_clk_b] -through $MISO_INPUT_B -end \
+ [expr {$SETUP_CYCLES + $HOLD_CYCLES - 1}]
+
+# One of the PL_SPI_ADDR lines is used instead for the LMK SYNC strobe. This line is
+# driven asynchronously.
+set_output_delay -clock [get_clocks async_out_clk] 0.000 [get_ports DB*_CPLD_PL_SPI_ADDR[2]]
+set_max_delay -to [get_ports DB*_CPLD_PL_SPI_ADDR[2]] 50.000
+set_min_delay -to [get_ports DB*_CPLD_PL_SPI_ADDR[2]] 0.000
+
+
+
+#*******************************************************************************
+## DSA Bus
+# The DSA controls are driven from the DB-A radio clock. Although they are received async
+# at the DSAs, they should be tightly constrained in the FPGA to arrive as closely as
+# possible. The best way to do this is a skew constraint across all the bits.
+set MAX_SKEW 2.5
+set SETUP_SKEW [expr {($MAX_SKEW / 2)+0.5}]
+set HOLD_SKEW [expr {($MAX_SKEW / 2)-0.5}]
+set PORT_LIST [get_ports {DB*_CH*_*X_DSA_DATA[*]}]
+# Then add the output delay on each of the ports.
+set_output_delay -clock [get_clocks dsa_bus_clk] -max -$SETUP_SKEW $PORT_LIST
+set_output_delay -add_delay -clock_fall -clock [get_clocks dsa_bus_clk] -max -$SETUP_SKEW $PORT_LIST
+set_output_delay -clock [get_clocks dsa_bus_clk] -min $HOLD_SKEW $PORT_LIST
+set_output_delay -add_delay -clock_fall -clock [get_clocks dsa_bus_clk] -min $HOLD_SKEW $PORT_LIST
+# Finally, make both the setup and hold checks use the same launching and latching edges.
+# The clock, which is essentially one of the data lines, should arrive at the pin
+# +/- MAX_DELAY compared to the other data lines, so setup and hold checks need to be
+# relative to the SAME edges for both the clock and the data.
+set_multicycle_path -setup -from [get_clocks radio_clk] -to [get_clocks dsa_bus_clk] -start 0
+set_multicycle_path -hold -from [get_clocks radio_clk] -to [get_clocks dsa_bus_clk] -1
+# Remove analysis from the output "clock" pin. There are ways to do this using TCL, but
+# they aren't supported in XDC files... so we do it the old fashioned way.
+set_output_delay -clock [get_clocks async_out_clk] 0.000 $DSA_CLK
+set_max_delay -to $DSA_CLK 50.000
+set_min_delay -to $DSA_CLK 0.000
+
+
+
+#*******************************************************************************
+## ATR Bus
+# The ATR bits are driven from the DB-A radio clock. Although they are received async in
+# the CPLD, they should be tightly constrained in the FPGA to avoid any race conditions.
+# The best way to do this is a skew constraint across all the bits.
+set MAX_SKEW 2.5
+set SETUP_SKEW [expr {($MAX_SKEW / 2)+0.5}]
+set HOLD_SKEW [expr {($MAX_SKEW / 2)-0.5}]
+set PORT_LIST [get_ports DB*_ATR_*X_*]
+# Then add the output delay on each of the ports.
+set_output_delay -clock [get_clocks atr_bus_clk] -max -$SETUP_SKEW $PORT_LIST
+set_output_delay -add_delay -clock_fall -clock [get_clocks atr_bus_clk] -max -$SETUP_SKEW $PORT_LIST
+set_output_delay -clock [get_clocks atr_bus_clk] -min $HOLD_SKEW $PORT_LIST
+set_output_delay -add_delay -clock_fall -clock [get_clocks atr_bus_clk] -min $HOLD_SKEW $PORT_LIST
+# Finally, make both the setup and hold checks use the same launching and latching edges.
+set_multicycle_path -setup -to [get_clocks atr_bus_clk] -start 0
+set_multicycle_path -hold -to [get_clocks atr_bus_clk] -1
+# Remove analysis from the output "clock" pin. There are ways to do this using TCL, but
+# they aren't supported in XDC files... so we do it the old fashioned way.
+set_output_delay -clock [get_clocks async_out_clk] 0.000 $ATR_CLK
+set_max_delay -to $ATR_CLK 50.000
+set_min_delay -to $ATR_CLK 0.000
+
+
+
+#*******************************************************************************
+## Mykonos Ports
+# Mykonos GPIO is driven from the DB-A radio clock. Although they are received async in
+# Mykonos, they should be tightly constrained in the FPGA to avoid any race conditions.
+# The best way to do this is a skew constraint across all the bits.
+# set MAX_SKEW 2.5
+# set SETUP_SKEW [expr {($MAX_SKEW / 2)+0.5}]
+# set HOLD_SKEW [expr {($MAX_SKEW / 2)-0.5}]
+# set PORT_LIST [get_ports DB*_ATR_*X_*]
+# # Then add the output delay on each of the ports.
+# set_output_delay -clock [get_clocks myk_gpio_bus_clk] -max -$SETUP_SKEW $PORT_LIST
+# set_output_delay -add_delay -clock_fall -clock [get_clocks myk_gpio_bus_clk] -max -$SETUP_SKEW $PORT_LIST
+# set_output_delay -clock [get_clocks myk_gpio_bus_clk] -min $HOLD_SKEW $PORT_LIST
+# set_output_delay -add_delay -clock_fall -clock [get_clocks myk_gpio_bus_clk] -min $HOLD_SKEW $PORT_LIST
+# # Finally, make both the setup and hold checks use the same launching and latching edges.
+# set_multicycle_path -setup -to [get_clocks myk_gpio_bus_clk] -start 0
+# set_multicycle_path -hold -to [get_clocks myk_gpio_bus_clk] -1
+# # Remove analysis from the output "clock" pin. There are ways to do this using TCL, but
+# # they aren't supported in XDC files... so we do it the old fashioned way.
+# set_output_delay -clock [get_clocks async_out_clk] 0.000 $MGPIO_CLK
+# set_max_delay -to $MGPIO_CLK 50.000
+# set_min_delay -to $MGPIO_CLK 0.000
+
+# Mykonos Interrupt is received asynchronously, and driven directly to the PS.
+set_input_delay -clock [get_clocks async_in_clk] 0.000 [get_ports DB*_MYK_INTRQ]
+set_max_delay -from [get_ports DB*_MYK_INTRQ] 50.000
+set_min_delay -from [get_ports DB*_MYK_INTRQ] 0.000
+
+
+
+#*******************************************************************************
+## SYSREF/SYNC JESD Timing
+#
+# SYNC is async, SYSREF is tightly timed.
+
+# The SYNC output for both DBs is governed by the JESD cores, which are solely driven by
+# DB-A clock... but it is an asynchronous signal so we use the async_out_clk.
+set_output_delay -clock [get_clocks async_out_clk] 0.000 [get_ports DB*_MYK_SYNC_IN_n]
+set_max_delay -to [get_ports DB*_MYK_SYNC_IN_n] 50.000
+set_min_delay -to [get_ports DB*_MYK_SYNC_IN_n] 0.000
+
+# The SYNC input for both DBs is received by the DB-A clock inside the JESD cores... but
+# again, it is asynchronous and therefore uses the async_in_clk.
+set_input_delay -clock [get_clocks async_in_clk] 0.000 [get_ports DB*_MYK_SYNC_OUT_n]
+set_max_delay -from [get_ports DB*_MYK_SYNC_OUT_n] 50.000
+set_min_delay -from [get_ports DB*_MYK_SYNC_OUT_n] 0.000
+
+# SYSREF is driven by the LMK directly to the FPGA. Timing analysis was performed once
+# for the worst-case numbers across both DBs to produce one set of numbers for both DBs.
+# Since we easily meet setup and hold in Vivado, then this is an acceptable approach.
+# SYSREF is captured by the local clock from each DB, so we have two sets of constraints.
+set_input_delay -clock fpga_clk_a_v -min -0.906 [get_ports DBA_FPGA_SYSREF_*]
+set_input_delay -clock fpga_clk_a_v -max 0.646 [get_ports DBA_FPGA_SYSREF_*]
+
+set_input_delay -clock fpga_clk_b_v -min -0.906 [get_ports DBB_FPGA_SYSREF_*]
+set_input_delay -clock fpga_clk_b_v -max 0.646 [get_ports DBB_FPGA_SYSREF_*]
+
+
+
+#*******************************************************************************
+## PPS Timing
+
+# Due to the N3xx synchronization and clocking structure, the PPS output is driven from
+# the Sample Clock domain instead of the input Reference Clock. Constrain the output as
+# tightly as possible to accurately mimic the internal Sample Clock timing.
+set SETUP_SKEW 2.0
+set HOLD_SKEW -0.5
+set_output_delay -clock [get_clocks fpga_clk_a_v] -max -$SETUP_SKEW [get_ports REF_1PPS_OUT]
+set_output_delay -clock [get_clocks fpga_clk_a_v] -min $HOLD_SKEW [get_ports REF_1PPS_OUT]
+set_multicycle_path -setup -to [get_ports REF_1PPS_OUT] -start 0
+set_multicycle_path -hold -to [get_ports REF_1PPS_OUT] -1
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/doc/CPLD.md b/fpga/usrp3/top/n3xx/dboards/mg/doc/CPLD.md
new file mode 100644
index 000000000..2071c46ba
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/doc/CPLD.md
@@ -0,0 +1,2 @@
+Timing closure of the CPLD design relies on the pre-set seed value. The build
+requires Quartus 16.1.2.
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/doc/mg_timing.xlsx b/fpga/usrp3/top/n3xx/dboards/mg/doc/mg_timing.xlsx
new file mode 100644
index 000000000..c4ad8ac5c
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/doc/mg_timing.xlsx
Binary files differ
diff --git a/fpga/usrp3/top/n3xx/dboards/mg/n3xx.v b/fpga/usrp3/top/n3xx/dboards/mg/n3xx.v
new file mode 100644
index 000000000..32fa84153
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/dboards/mg/n3xx.v
@@ -0,0 +1,3915 @@
+///////////////////////////////////////////////////////////////////
+///
+// Copyright 2016-2019 Ettus Research, A National Instruments Brand
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// Module: n3xx
+// Description:
+// Top Level for N3xx devices
+//
+//////////////////////////////////////////////////////////////////////
+
+module n3xx (
+ inout [11:0] FPGA_GPIO,
+
+ input FPGA_REFCLK_P,
+ input FPGA_REFCLK_N,
+ input REF_1PPS_IN,
+ input NETCLK_REF_P,
+ input NETCLK_REF_N,
+ //input REF_1PPS_IN_MGMT,
+ output REF_1PPS_OUT,
+
+ //TDC
+ inout UNUSED_PIN_TDCA_0,
+ inout UNUSED_PIN_TDCA_1,
+ inout UNUSED_PIN_TDCA_2,
+ inout UNUSED_PIN_TDCA_3,
+ inout UNUSED_PIN_TDCB_0,
+ inout UNUSED_PIN_TDCB_1,
+ inout UNUSED_PIN_TDCB_2,
+ inout UNUSED_PIN_TDCB_3,
+
+`ifdef NPIO_LANES
+ input NPIO_RX0_P,
+ input NPIO_RX0_N,
+ output NPIO_TX0_P,
+ output NPIO_TX0_N,
+ input NPIO_RX1_P,
+ input NPIO_RX1_N,
+ output NPIO_TX1_P,
+ output NPIO_TX1_N,
+`endif
+`ifdef QSFP_LANES
+ input [`QSFP_LANES-1:0] QSFP_RX_P,
+ input [`QSFP_LANES-1:0] QSFP_RX_N,
+ output [`QSFP_LANES-1:0] QSFP_TX_P,
+ output [`QSFP_LANES-1:0] QSFP_TX_N,
+ output QSFP_RESET_B,
+ output QSFP_LED,
+ output QSFP_MODSEL_B,
+ output QSFP_LPMODE,
+ input QSFP_PRESENT_B,
+ input QSFP_INT_B,
+ inout QSFP_I2C_SCL,
+ inout QSFP_I2C_SDA,
+`endif
+ //TODO: Uncomment when connected here
+ //input NPIO_0_RXSYNC_0_P, NPIO_0_RXSYNC_1_P,
+ //input NPIO_0_RXSYNC_0_N, NPIO_0_RXSYNC_1_N,
+ //output NPIO_0_TXSYNC_0_P, NPIO_0_TXSYNC_1_P,
+ //output NPIO_0_TXSYNC_0_N, NPIO_0_TXSYNC_1_N,
+ //input NPIO_1_RXSYNC_0_P, NPIO_1_RXSYNC_1_P,
+ //input NPIO_1_RXSYNC_0_N, NPIO_1_RXSYNC_1_N,
+ //output NPIO_1_TXSYNC_0_P, NPIO_1_TXSYNC_1_P,
+ //output NPIO_1_TXSYNC_0_N, NPIO_1_TXSYNC_1_N,
+ //input NPIO_2_RXSYNC_0_P, NPIO_2_RXSYNC_1_P,
+ //input NPIO_2_RXSYNC_0_N, NPIO_2_RXSYNC_1_N,
+ //output NPIO_2_TXSYNC_0_P, NPIO_2_TXSYNC_1_P,
+ //output NPIO_2_TXSYNC_0_N, NPIO_2_TXSYNC_1_N,
+
+ //GPS
+ input GPS_1PPS,
+ //input GPS_1PPS_RAW,
+
+ //Misc
+ input ENET0_CLK125,
+ //inout ENET0_PTP,
+ //output ENET0_PTP_DIR,
+ //inout ATSHA204_SDA,
+ input FPGA_PL_RESETN, // TODO: Add to reset logic
+ // output reg [1:0] FPGA_TEST,
+ //input PWR_CLK_FPGA, // TODO: check direction
+ input FPGA_PUDC_B,
+
+ //White Rabbit
+ input WB_20MHZ_P,
+ input WB_20MHZ_N,
+ output WB_DAC_DIN,
+ output WB_DAC_NCLR,
+ output WB_DAC_NLDAC,
+ output WB_DAC_NSYNC,
+ output WB_DAC_SCLK,
+
+ //LEDS
+ output PANEL_LED_GPS,
+ output PANEL_LED_LINK,
+ output PANEL_LED_PPS,
+ output PANEL_LED_REF,
+
+ // ARM Connections (PS)
+ inout [53:0] MIO,
+ inout PS_SRSTB,
+ inout PS_CLK,
+ inout PS_PORB,
+ inout DDR_Clk,
+ inout DDR_Clk_n,
+ inout DDR_CKE,
+ inout DDR_CS_n,
+ inout DDR_RAS_n,
+ inout DDR_CAS_n,
+ inout DDR_WEB,
+ inout [2:0] DDR_BankAddr,
+ inout [14:0] DDR_Addr,
+ inout DDR_ODT,
+ inout DDR_DRSTB,
+ inout [31:0] DDR_DQ,
+ inout [3:0] DDR_DM,
+ inout [3:0] DDR_DQS,
+ inout [3:0] DDR_DQS_n,
+ inout DDR_VRP,
+ inout DDR_VRN,
+
+
+ ///////////////////////////////////
+ //
+ // High Speed SPF+ signals and clocking
+ //
+ ///////////////////////////////////
+
+ // These clock inputs must always be enabled with a buffer regardless of the build
+ // target to avoid damage to the FPGA.
+ input NETCLK_P,
+ input NETCLK_N,
+ input MGT156MHZ_CLK1_P,
+ input MGT156MHZ_CLK1_N,
+
+ input SFP_0_RX_P, input SFP_0_RX_N,
+ output SFP_0_TX_P, output SFP_0_TX_N,
+ input SFP_1_RX_P, input SFP_1_RX_N,
+ output SFP_1_TX_P, output SFP_1_TX_N,
+
+
+ ///////////////////////////////////
+ //
+ // DRAM Interface
+ //
+ ///////////////////////////////////
+ inout [31:0] ddr3_dq, // Data pins. Input for Reads, Output for Writes.
+ inout [3:0] ddr3_dqs_n, // Data Strobes. Input for Reads, Output for Writes.
+ inout [3:0] ddr3_dqs_p,
+ //
+ output [15:0] ddr3_addr, // Address
+ output [2:0] ddr3_ba, // Bank Address
+ output ddr3_ras_n, // Row Address Strobe.
+ output ddr3_cas_n, // Column address select
+ output ddr3_we_n, // Write Enable
+ output ddr3_reset_n, // SDRAM reset pin.
+ output [0:0] ddr3_ck_p, // Differential clock
+ output [0:0] ddr3_ck_n,
+ output [0:0] ddr3_cke, // Clock Enable
+ output [0:0] ddr3_cs_n, // Chip Select
+ output [3:0] ddr3_dm, // Data Mask [3] = UDM.U26, [2] = LDM.U26, ...
+ output [0:0] ddr3_odt, // On-Die termination enable.
+ //
+ input sys_clk_p, // Differential
+ input sys_clk_n, // 100MHz clock source to generate DDR3 clocking.
+
+
+ ///////////////////////////////////
+ //
+ // Supporting I/O for SPF+ interfaces
+ // (non high speed stuff)
+ //
+ ///////////////////////////////////
+
+ //SFP+ 0, Slow Speed, Bank 13 3.3V
+ input SFP_0_I2C_NPRESENT,
+ output SFP_0_LED_A,
+ output SFP_0_LED_B,
+ input SFP_0_LOS,
+ output SFP_0_RS0,
+ output SFP_0_RS1,
+ output SFP_0_TXDISABLE,
+ input SFP_0_TXFAULT,
+
+ //SFP+ 1, Slow Speed, Bank 13 3.3V
+ //input SFP_1_I2C_NPRESENT,
+ output SFP_1_LED_A,
+ output SFP_1_LED_B,
+ input SFP_1_LOS,
+ output SFP_1_RS0,
+ output SFP_1_RS1,
+ output SFP_1_TXDISABLE,
+ input SFP_1_TXFAULT,
+
+ //USRP IO A
+ output DBA_CPLD_PS_SPI_SCLK,
+ output DBA_CPLD_PS_SPI_LE,
+ output DBA_CPLD_PS_SPI_SDI,
+ input DBA_CPLD_PS_SPI_SDO,
+ output [1:0] DBA_CPLD_PS_SPI_ADDR,
+
+ output DBA_ATR_RX_1,
+ output DBA_ATR_RX_2,
+ output DBA_ATR_TX_1,
+ output DBA_ATR_TX_2,
+
+ output [5:0] DBA_CH1_TX_DSA_DATA,
+ output [5:0] DBA_CH1_RX_DSA_DATA,
+ output [5:0] DBA_CH2_TX_DSA_DATA,
+ output [5:0] DBA_CH2_RX_DSA_DATA,
+
+ output DBA_CPLD_PL_SPI_SCLK,
+ output DBA_CPLD_PL_SPI_LE,
+ output DBA_CPLD_PL_SPI_SDI,
+ input DBA_CPLD_PL_SPI_SDO,
+ output [2:0] DBA_CPLD_PL_SPI_ADDR,
+
+ output DBA_MYK_SPI_SCLK,
+ output DBA_MYK_SPI_CS_n,
+ input DBA_MYK_SPI_SDO,
+ output DBA_MYK_SPI_SDIO,
+ input DBA_MYK_INTRQ,
+
+ output DBA_MYK_SYNC_IN_n,
+ input DBA_MYK_SYNC_OUT_n,
+
+ inout DBA_CPLD_JTAG_TCK,
+ inout DBA_CPLD_JTAG_TMS,
+ inout DBA_CPLD_JTAG_TDI,
+ input DBA_CPLD_JTAG_TDO,
+
+ output DBA_MYK_GPIO_0,
+ output DBA_MYK_GPIO_1,
+ output DBA_MYK_GPIO_3,
+ output DBA_MYK_GPIO_4,
+ output DBA_MYK_GPIO_12,
+ output DBA_MYK_GPIO_13,
+ output DBA_MYK_GPIO_14,
+ output DBA_MYK_GPIO_15,
+
+ input DBA_FPGA_CLK_P,
+ input DBA_FPGA_CLK_N,
+ input DBA_FPGA_SYSREF_P,
+ input DBA_FPGA_SYSREF_N,
+
+ input USRPIO_A_MGTCLK_P,
+ input USRPIO_A_MGTCLK_N,
+
+ input [3:0] USRPIO_A_RX_P,
+ input [3:0] USRPIO_A_RX_N,
+ output [3:0] USRPIO_A_TX_P,
+ output [3:0] USRPIO_A_TX_N
+
+`ifndef N300
+ //USRP IO B
+ ,output DBB_CPLD_PS_SPI_SCLK,
+ output DBB_CPLD_PS_SPI_LE,
+ output DBB_CPLD_PS_SPI_SDI,
+ input DBB_CPLD_PS_SPI_SDO,
+ output [1:0] DBB_CPLD_PS_SPI_ADDR,
+
+ output DBB_ATR_RX_1,
+ output DBB_ATR_RX_2,
+ output DBB_ATR_TX_1,
+ output DBB_ATR_TX_2,
+
+ output [5:0] DBB_CH1_TX_DSA_DATA,
+ output [5:0] DBB_CH1_RX_DSA_DATA,
+ output [5:0] DBB_CH2_TX_DSA_DATA,
+ output [5:0] DBB_CH2_RX_DSA_DATA,
+
+ output DBB_CPLD_PL_SPI_SCLK,
+ output DBB_CPLD_PL_SPI_LE,
+ output DBB_CPLD_PL_SPI_SDI,
+ input DBB_CPLD_PL_SPI_SDO,
+ output [2:0] DBB_CPLD_PL_SPI_ADDR,
+
+ output DBB_MYK_SPI_SCLK,
+ output DBB_MYK_SPI_CS_n,
+ input DBB_MYK_SPI_SDO,
+ output DBB_MYK_SPI_SDIO,
+ input DBB_MYK_INTRQ,
+
+ output DBB_MYK_SYNC_IN_n,
+ input DBB_MYK_SYNC_OUT_n,
+
+ inout DBB_CPLD_JTAG_TCK,
+ inout DBB_CPLD_JTAG_TMS,
+ inout DBB_CPLD_JTAG_TDI,
+ input DBB_CPLD_JTAG_TDO,
+
+ output DBB_MYK_GPIO_0,
+ output DBB_MYK_GPIO_1,
+ output DBB_MYK_GPIO_3,
+ output DBB_MYK_GPIO_4,
+ output DBB_MYK_GPIO_12,
+ output DBB_MYK_GPIO_13,
+ output DBB_MYK_GPIO_14,
+ output DBB_MYK_GPIO_15,
+
+ input DBB_FPGA_CLK_P,
+ input DBB_FPGA_CLK_N,
+ input DBB_FPGA_SYSREF_P,
+ input DBB_FPGA_SYSREF_N,
+
+ input USRPIO_B_MGTCLK_P,
+ input USRPIO_B_MGTCLK_N,
+
+ input [3:0] USRPIO_B_RX_P,
+ input [3:0] USRPIO_B_RX_N,
+ output [3:0] USRPIO_B_TX_P,
+ output [3:0] USRPIO_B_TX_N
+`endif
+);
+
+ localparam N_AXILITE_SLAVES = 4;
+ localparam REG_AWIDTH = 14; // log2(0x4000)
+ localparam QSFP_REG_AWIDTH = 17; // log2(0x20000)
+ localparam REG_DWIDTH = 32;
+ localparam FP_GPIO_OFFSET = 32;
+ localparam FP_GPIO_WIDTH = 12;
+
+`ifdef N310
+ localparam NUM_RADIOS = 2;
+ localparam NUM_CHANNELS_PER_RADIO = 2;
+ localparam NUM_DBOARDS = 2;
+`elsif N300
+ localparam NUM_RADIOS = 1;
+ localparam NUM_CHANNELS_PER_RADIO = 2;
+ localparam NUM_DBOARDS = 1;
+`endif
+ localparam NUM_CHANNELS = NUM_RADIOS * NUM_CHANNELS_PER_RADIO;
+ localparam [15:0] RFNOC_PROTOVER = {8'd1, 8'd0};
+
+ // Internal connections to PS
+ // HP0 -- High Performance port 0, FPGA is the master
+ wire [5:0] S_AXI_HP0_AWID;
+ wire [31:0] S_AXI_HP0_AWADDR;
+ wire [2:0] S_AXI_HP0_AWPROT;
+ wire S_AXI_HP0_AWVALID;
+ wire S_AXI_HP0_AWREADY;
+ wire [63:0] S_AXI_HP0_WDATA;
+ wire [7:0] S_AXI_HP0_WSTRB;
+ wire S_AXI_HP0_WVALID;
+ wire S_AXI_HP0_WREADY;
+ wire [1:0] S_AXI_HP0_BRESP;
+ wire S_AXI_HP0_BVALID;
+ wire S_AXI_HP0_BREADY;
+ wire [5:0] S_AXI_HP0_ARID;
+ wire [31:0] S_AXI_HP0_ARADDR;
+ wire [2:0] S_AXI_HP0_ARPROT;
+ wire S_AXI_HP0_ARVALID;
+ wire S_AXI_HP0_ARREADY;
+ wire [63:0] S_AXI_HP0_RDATA;
+ wire [1:0] S_AXI_HP0_RRESP;
+ wire S_AXI_HP0_RVALID;
+ wire S_AXI_HP0_RREADY;
+ wire S_AXI_HP0_RLAST;
+ wire [3:0] S_AXI_HP0_ARCACHE;
+ wire [7:0] S_AXI_HP0_AWLEN;
+ wire [2:0] S_AXI_HP0_AWSIZE;
+ wire [1:0] S_AXI_HP0_AWBURST;
+ wire [3:0] S_AXI_HP0_AWCACHE;
+ wire S_AXI_HP0_WLAST;
+ wire [7:0] S_AXI_HP0_ARLEN;
+ wire [1:0] S_AXI_HP0_ARBURST;
+ wire [2:0] S_AXI_HP0_ARSIZE;
+
+ // GP0 -- General Purpose port 0, FPGA is the master
+ wire [4:0] S_AXI_GP0_AWID;
+ wire [31:0] S_AXI_GP0_AWADDR;
+ wire [2:0] S_AXI_GP0_AWPROT;
+ wire S_AXI_GP0_AWVALID;
+ wire S_AXI_GP0_AWREADY;
+ wire [31:0] S_AXI_GP0_WDATA;
+ wire [3:0] S_AXI_GP0_WSTRB;
+ wire S_AXI_GP0_WVALID;
+ wire S_AXI_GP0_WREADY;
+ wire [1:0] S_AXI_GP0_BRESP;
+ wire S_AXI_GP0_BVALID;
+ wire S_AXI_GP0_BREADY;
+ wire [4:0] S_AXI_GP0_ARID;
+ wire [31:0] S_AXI_GP0_ARADDR;
+ wire [2:0] S_AXI_GP0_ARPROT;
+ wire S_AXI_GP0_ARVALID;
+ wire S_AXI_GP0_ARREADY;
+ wire [31:0] S_AXI_GP0_RDATA;
+ wire [1:0] S_AXI_GP0_RRESP;
+ wire S_AXI_GP0_RVALID;
+ wire S_AXI_GP0_RREADY;
+ wire S_AXI_GP0_RLAST;
+ wire [3:0] S_AXI_GP0_ARCACHE;
+ wire [7:0] S_AXI_GP0_AWLEN;
+ wire [2:0] S_AXI_GP0_AWSIZE;
+ wire [1:0] S_AXI_GP0_AWBURST;
+ wire [3:0] S_AXI_GP0_AWCACHE;
+ wire S_AXI_GP0_WLAST;
+ wire [7:0] S_AXI_GP0_ARLEN;
+ wire [1:0] S_AXI_GP0_ARBURST;
+ wire [2:0] S_AXI_GP0_ARSIZE;
+
+ // HP1 -- High Performance port 1, FPGA is the master
+ wire [5:0] S_AXI_HP1_AWID;
+ wire [31:0] S_AXI_HP1_AWADDR;
+ wire [2:0] S_AXI_HP1_AWPROT;
+ wire S_AXI_HP1_AWVALID;
+ wire S_AXI_HP1_AWREADY;
+ wire [63:0] S_AXI_HP1_WDATA;
+ wire [7:0] S_AXI_HP1_WSTRB;
+ wire S_AXI_HP1_WVALID;
+ wire S_AXI_HP1_WREADY;
+ wire [1:0] S_AXI_HP1_BRESP;
+ wire S_AXI_HP1_BVALID;
+ wire S_AXI_HP1_BREADY;
+ wire [5:0] S_AXI_HP1_ARID;
+ wire [31:0] S_AXI_HP1_ARADDR;
+ wire [2:0] S_AXI_HP1_ARPROT;
+ wire S_AXI_HP1_ARVALID;
+ wire S_AXI_HP1_ARREADY;
+ wire [63:0] S_AXI_HP1_RDATA;
+ wire [1:0] S_AXI_HP1_RRESP;
+ wire S_AXI_HP1_RVALID;
+ wire S_AXI_HP1_RREADY;
+ wire S_AXI_HP1_RLAST;
+ wire [3:0] S_AXI_HP1_ARCACHE;
+ wire [7:0] S_AXI_HP1_AWLEN;
+ wire [2:0] S_AXI_HP1_AWSIZE;
+ wire [1:0] S_AXI_HP1_AWBURST;
+ wire [3:0] S_AXI_HP1_AWCACHE;
+ wire S_AXI_HP1_WLAST;
+ wire [7:0] S_AXI_HP1_ARLEN;
+ wire [1:0] S_AXI_HP1_ARBURST;
+ wire [2:0] S_AXI_HP1_ARSIZE;
+
+ // GP1 -- General Purpose port 1, FPGA is the master
+ wire [4:0] S_AXI_GP1_AWID;
+ wire [31:0] S_AXI_GP1_AWADDR;
+ wire [2:0] S_AXI_GP1_AWPROT;
+ wire S_AXI_GP1_AWVALID;
+ wire S_AXI_GP1_AWREADY;
+ wire [31:0] S_AXI_GP1_WDATA;
+ wire [3:0] S_AXI_GP1_WSTRB;
+ wire S_AXI_GP1_WVALID;
+ wire S_AXI_GP1_WREADY;
+ wire [1:0] S_AXI_GP1_BRESP;
+ wire S_AXI_GP1_BVALID;
+ wire S_AXI_GP1_BREADY;
+ wire [4:0] S_AXI_GP1_ARID;
+ wire [31:0] S_AXI_GP1_ARADDR;
+ wire [2:0] S_AXI_GP1_ARPROT;
+ wire S_AXI_GP1_ARVALID;
+ wire S_AXI_GP1_ARREADY;
+ wire [31:0] S_AXI_GP1_RDATA;
+ wire [1:0] S_AXI_GP1_RRESP;
+ wire S_AXI_GP1_RVALID;
+ wire S_AXI_GP1_RREADY;
+ wire S_AXI_GP1_RLAST;
+ wire [3:0] S_AXI_GP1_ARCACHE;
+ wire [7:0] S_AXI_GP1_AWLEN;
+ wire [2:0] S_AXI_GP1_AWSIZE;
+ wire [1:0] S_AXI_GP1_AWBURST;
+ wire [3:0] S_AXI_GP1_AWCACHE;
+ wire S_AXI_GP1_WLAST;
+ wire [7:0] S_AXI_GP1_ARLEN;
+ wire [1:0] S_AXI_GP1_ARBURST;
+ wire [2:0] S_AXI_GP1_ARSIZE;
+
+ // GP0 -- General Purpose port 0, FPGA is the slave
+ wire M_AXI_GP0_ARVALID;
+ wire M_AXI_GP0_AWVALID;
+ wire M_AXI_GP0_BREADY;
+ wire M_AXI_GP0_RREADY;
+ wire M_AXI_GP0_WVALID;
+ wire [11:0] M_AXI_GP0_ARID;
+ wire [11:0] M_AXI_GP0_AWID;
+ wire [11:0] M_AXI_GP0_WID;
+ wire [31:0] M_AXI_GP0_ARADDR;
+ wire [31:0] M_AXI_GP0_AWADDR;
+ wire [31:0] M_AXI_GP0_WDATA;
+ wire [3:0] M_AXI_GP0_WSTRB;
+ wire M_AXI_GP0_ARREADY;
+ wire M_AXI_GP0_AWREADY;
+ wire M_AXI_GP0_BVALID;
+ wire M_AXI_GP0_RLAST;
+ wire M_AXI_GP0_RVALID;
+ wire M_AXI_GP0_WREADY;
+ wire [1:0] M_AXI_GP0_BRESP;
+ wire [1:0] M_AXI_GP0_RRESP;
+ wire [31:0] M_AXI_GP0_RDATA;
+
+ wire M_AXI_ETH_DMA0_ARVALID;
+ wire M_AXI_ETH_DMA0_AWVALID;
+ wire M_AXI_ETH_DMA0_BREADY;
+ wire M_AXI_ETH_DMA0_RREADY;
+ wire M_AXI_ETH_DMA0_WVALID;
+ wire [11:0] M_AXI_ETH_DMA0_ARID;
+ wire [11:0] M_AXI_ETH_DMA0_AWID;
+ wire [11:0] M_AXI_ETH_DMA0_WID;
+ wire [31:0] M_AXI_ETH_DMA0_ARADDR;
+ wire [31:0] M_AXI_ETH_DMA0_AWADDR;
+ wire [31:0] M_AXI_ETH_DMA0_WDATA;
+ wire [3:0] M_AXI_ETH_DMA0_WSTRB;
+ wire M_AXI_ETH_DMA0_ARREADY;
+ wire M_AXI_ETH_DMA0_AWREADY;
+ wire M_AXI_ETH_DMA0_BVALID;
+ wire M_AXI_ETH_DMA0_RLAST;
+ wire M_AXI_ETH_DMA0_RVALID;
+ wire M_AXI_ETH_DMA0_WREADY;
+ wire [1:0] M_AXI_ETH_DMA0_BRESP;
+ wire [1:0] M_AXI_ETH_DMA0_RRESP;
+ wire [31:0] M_AXI_ETH_DMA0_RDATA;
+
+ wire M_AXI_NET0_ARVALID;
+ wire M_AXI_NET0_AWVALID;
+ wire M_AXI_NET0_BREADY;
+ wire M_AXI_NET0_RREADY;
+ wire M_AXI_NET0_WVALID;
+ wire [11:0] M_AXI_NET0_ARID;
+ wire [11:0] M_AXI_NET0_AWID;
+ wire [11:0] M_AXI_NET0_WID;
+ wire [31:0] M_AXI_NET0_ARADDR;
+ wire [31:0] M_AXI_NET0_AWADDR;
+ wire [31:0] M_AXI_NET0_WDATA;
+ wire [3:0] M_AXI_NET0_WSTRB;
+ wire M_AXI_NET0_ARREADY;
+ wire M_AXI_NET0_AWREADY;
+ wire M_AXI_NET0_BVALID;
+ wire M_AXI_NET0_RLAST;
+ wire M_AXI_NET0_RVALID;
+ wire M_AXI_NET0_WREADY;
+ wire [1:0] M_AXI_NET0_BRESP;
+ wire [1:0] M_AXI_NET0_RRESP;
+ wire [31:0] M_AXI_NET0_RDATA;
+
+ wire M_AXI_ETH_DMA1_ARVALID;
+ wire M_AXI_ETH_DMA1_AWVALID;
+ wire M_AXI_ETH_DMA1_BREADY;
+ wire M_AXI_ETH_DMA1_RREADY;
+ wire M_AXI_ETH_DMA1_WVALID;
+ wire [11:0] M_AXI_ETH_DMA1_ARID;
+ wire [11:0] M_AXI_ETH_DMA1_AWID;
+ wire [11:0] M_AXI_ETH_DMA1_WID;
+ wire [31:0] M_AXI_ETH_DMA1_ARADDR;
+ wire [31:0] M_AXI_ETH_DMA1_AWADDR;
+ wire [31:0] M_AXI_ETH_DMA1_WDATA;
+ wire [3:0] M_AXI_ETH_DMA1_WSTRB;
+ wire M_AXI_ETH_DMA1_ARREADY;
+ wire M_AXI_ETH_DMA1_AWREADY;
+ wire M_AXI_ETH_DMA1_BVALID;
+ wire M_AXI_ETH_DMA1_RLAST;
+ wire M_AXI_ETH_DMA1_RVALID;
+ wire M_AXI_ETH_DMA1_WREADY;
+ wire [1:0] M_AXI_ETH_DMA1_BRESP;
+ wire [1:0] M_AXI_ETH_DMA1_RRESP;
+ wire [31:0] M_AXI_ETH_DMA1_RDATA;
+
+ wire M_AXI_NET1_ARVALID;
+ wire M_AXI_NET1_AWVALID;
+ wire M_AXI_NET1_BREADY;
+ wire M_AXI_NET1_RREADY;
+ wire M_AXI_NET1_WVALID;
+ wire [11:0] M_AXI_NET1_ARID;
+ wire [11:0] M_AXI_NET1_AWID;
+ wire [11:0] M_AXI_NET1_WID;
+ wire [31:0] M_AXI_NET1_ARADDR;
+ wire [31:0] M_AXI_NET1_AWADDR;
+ wire [31:0] M_AXI_NET1_WDATA;
+ wire [3:0] M_AXI_NET1_WSTRB;
+ wire M_AXI_NET1_ARREADY;
+ wire M_AXI_NET1_AWREADY;
+ wire M_AXI_NET1_BVALID;
+ wire M_AXI_NET1_RLAST;
+ wire M_AXI_NET1_RVALID;
+ wire M_AXI_NET1_WREADY;
+ wire [1:0] M_AXI_NET1_BRESP;
+ wire [1:0] M_AXI_NET1_RRESP;
+ wire [31:0] M_AXI_NET1_RDATA;
+
+ wire M_AXI_NET2_ARVALID;
+ wire M_AXI_NET2_AWVALID;
+ wire M_AXI_NET2_BREADY;
+ wire M_AXI_NET2_RREADY;
+ wire M_AXI_NET2_WVALID;
+ wire [11:0] M_AXI_NET2_ARID;
+ wire [11:0] M_AXI_NET2_AWID;
+ wire [11:0] M_AXI_NET2_WID;
+ wire [31:0] M_AXI_NET2_ARADDR;
+ wire [31:0] M_AXI_NET2_AWADDR;
+ wire [31:0] M_AXI_NET2_WDATA;
+ wire [3:0] M_AXI_NET2_WSTRB;
+ wire M_AXI_NET2_ARREADY;
+ wire M_AXI_NET2_AWREADY;
+ wire M_AXI_NET2_BVALID;
+ wire M_AXI_NET2_RLAST;
+ wire M_AXI_NET2_RVALID;
+ wire M_AXI_NET2_WREADY;
+ wire [1:0] M_AXI_NET2_BRESP;
+ wire [1:0] M_AXI_NET2_RRESP;
+ wire [31:0] M_AXI_NET2_RDATA;
+
+ wire M_AXI_XBAR_ARVALID;
+ wire M_AXI_XBAR_AWVALID;
+ wire M_AXI_XBAR_BREADY;
+ wire M_AXI_XBAR_RREADY;
+ wire M_AXI_XBAR_WVALID;
+ wire [11:0] M_AXI_XBAR_ARID;
+ wire [11:0] M_AXI_XBAR_AWID;
+ wire [11:0] M_AXI_XBAR_WID;
+ wire [31:0] M_AXI_XBAR_ARADDR;
+ wire [31:0] M_AXI_XBAR_AWADDR;
+ wire [31:0] M_AXI_XBAR_WDATA;
+ wire [3:0] M_AXI_XBAR_WSTRB;
+ wire M_AXI_XBAR_ARREADY;
+ wire M_AXI_XBAR_AWREADY;
+ wire M_AXI_XBAR_BVALID;
+ wire M_AXI_XBAR_RLAST;
+ wire M_AXI_XBAR_RVALID;
+ wire M_AXI_XBAR_WREADY;
+ wire [1:0] M_AXI_XBAR_BRESP;
+ wire [1:0] M_AXI_XBAR_RRESP;
+ wire [31:0] M_AXI_XBAR_RDATA;
+
+ wire M_AXI_JESD0_ARVALID;
+ wire M_AXI_JESD0_AWVALID;
+ wire M_AXI_JESD0_BREADY;
+ wire M_AXI_JESD0_RREADY;
+ wire M_AXI_JESD0_WVALID;
+ wire [11:0] M_AXI_JESD0_ARID;
+ wire [11:0] M_AXI_JESD0_AWID;
+ wire [11:0] M_AXI_JESD0_WID;
+ wire [31:0] M_AXI_JESD0_ARADDR;
+ wire [31:0] M_AXI_JESD0_AWADDR;
+ wire [31:0] M_AXI_JESD0_WDATA;
+ wire [3:0] M_AXI_JESD0_WSTRB;
+ wire M_AXI_JESD0_ARREADY;
+ wire M_AXI_JESD0_AWREADY;
+ wire M_AXI_JESD0_BVALID;
+ wire M_AXI_JESD0_RLAST;
+ wire M_AXI_JESD0_RVALID;
+ wire M_AXI_JESD0_WREADY;
+ wire [1:0] M_AXI_JESD0_BRESP;
+ wire [1:0] M_AXI_JESD0_RRESP;
+ wire [31:0] M_AXI_JESD0_RDATA;
+
+ wire M_AXI_JESD1_ARVALID;
+ wire M_AXI_JESD1_AWVALID;
+ wire M_AXI_JESD1_BREADY;
+ wire M_AXI_JESD1_RREADY;
+ wire M_AXI_JESD1_WVALID;
+ wire [11:0] M_AXI_JESD1_ARID;
+ wire [11:0] M_AXI_JESD1_AWID;
+ wire [11:0] M_AXI_JESD1_WID;
+ wire [31:0] M_AXI_JESD1_ARADDR;
+ wire [31:0] M_AXI_JESD1_AWADDR;
+ wire [31:0] M_AXI_JESD1_WDATA;
+ wire [3:0] M_AXI_JESD1_WSTRB;
+ wire M_AXI_JESD1_ARREADY;
+ wire M_AXI_JESD1_AWREADY;
+ wire M_AXI_JESD1_BVALID;
+ wire M_AXI_JESD1_RLAST;
+ wire M_AXI_JESD1_RVALID;
+ wire M_AXI_JESD1_WREADY;
+ wire [1:0] M_AXI_JESD1_BRESP;
+ wire [1:0] M_AXI_JESD1_RRESP;
+ wire [31:0] M_AXI_JESD1_RDATA;
+
+ // White Rabbit
+ wire wr_uart_txd;
+ wire wr_uart_rxd;
+ wire pps_wr_refclk;
+ wire wr_ref_clk;
+
+ // AXI bus from PS to WR Core
+ wire m_axi_wr_clk;
+ wire [31:0] m_axi_wr_araddr;
+ wire [0:0] m_axi_wr_arready;
+ wire [0:0] m_axi_wr_arvalid;
+ wire [31:0] m_axi_wr_awaddr;
+ wire [0:0] m_axi_wr_awready;
+ wire [0:0] m_axi_wr_awvalid;
+ wire [0:0] m_axi_wr_bready;
+ wire [1:0] m_axi_wr_bresp;
+ wire [0:0] m_axi_wr_bvalid;
+ wire [31:0] m_axi_wr_rdata;
+ wire [0:0] m_axi_wr_rready;
+ wire [1:0] m_axi_wr_rresp;
+ wire [0:0] m_axi_wr_rvalid;
+ wire [31:0] m_axi_wr_wdata;
+ wire [0:0] m_axi_wr_wready;
+ wire [3:0] m_axi_wr_wstrb;
+ wire [0:0] m_axi_wr_wvalid;
+
+ wire [63:0] ps_gpio_out;
+ wire [63:0] ps_gpio_in;
+ wire [63:0] ps_gpio_tri;
+
+ wire [15:0] IRQ_F2P;
+ wire FCLK_CLK0;
+ wire FCLK_CLK1;
+ wire FCLK_CLK2;
+ wire FCLK_CLK3;
+ wire clk100;
+ wire clk40;
+ wire meas_clk_ref;
+ wire bus_clk;
+ wire gige_refclk;
+ wire gige_refclk_bufg;
+ wire xgige_refclk;
+ wire xgige_clk156;
+ wire xgige_dclk;
+
+ wire global_rst;
+ wire radio_rst;
+ wire bus_rst;
+ wire FCLK_RESET0_N;
+ wire clk40_rst;
+ wire clk40_rstn;
+
+ wire [1:0] USB0_PORT_INDCTL;
+ wire USB0_VBUS_PWRSELECT;
+ wire USB0_VBUS_PWRFAULT;
+
+ wire ref_clk;
+ wire wr_refclk_buf;
+ wire netclk_buf;
+ wire meas_clk;
+ wire ddr3_dma_clk;
+ wire meas_clk_reset;
+ wire meas_clk_locked;
+ wire enable_ref_clk_async;
+ wire pps_radioclk1x_iob;
+ wire pps_radioclk1x;
+ wire [3:0] pps_select;
+ wire pps_out_enb;
+ wire [1:0] pps_select_sfp;
+ wire pps_refclk;
+ wire export_pps_radioclk;
+ wire radio_clk;
+ wire radio_clk_2x;
+
+ wire qsfp_sda_i;
+ wire qsfp_sda_o;
+ wire qsfp_sda_t;
+ wire qsfp_scl_i;
+ wire qsfp_scl_o;
+ wire qsfp_scl_t;
+
+ /////////////////////////////////////////////////////////////////////
+ //
+ // Resets
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ // Global synchronous reset, on the bus_clk domain. De-asserts after 85
+ // bus_clk cycles. Asserted by default.
+ por_gen por_gen(.clk(bus_clk), .reset_out(global_rst));
+
+ // Synchronous reset for the radio_clk domain, based on the global_rst.
+ reset_sync radio_reset_gen (
+ .clk(radio_clk),
+ .reset_in(global_rst),
+ .reset_out(radio_rst)
+ );
+
+ // Synchronous reset for the bus_clk domain, based on the global_rst.
+ reset_sync bus_reset_gen (
+ .clk(bus_clk),
+ .reset_in(global_rst),
+ .reset_out(bus_rst)
+ );
+
+
+ // PS-based Resets //
+ //
+ // Synchronous reset for the clk40 domain. This is derived from the PS reset 0.
+ reset_sync clk40_reset_gen (
+ .clk(clk40),
+ .reset_in(~FCLK_RESET0_N),
+ .reset_out(clk40_rst)
+ );
+ // Invert for various modules.
+ assign clk40_rstn = ~clk40_rst;
+
+
+ /////////////////////////////////////////////////////////////////////
+ //
+ // Timing
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ // Clocks from the PS
+ //
+ // These clocks appear to have BUFGs already instantiated by the ip generator.
+ // Simply rename them here for clarity.
+ // FCLK_CLK0 : 100 MHz
+ // FCLK_CLK1 : 40 MHz
+ // FCLK_CLK2 : 166.6667 MHz
+ // FCLK_CLK3 : 200 MHz
+ assign clk100 = FCLK_CLK0;
+ assign clk40 = FCLK_CLK1;
+ assign meas_clk_ref = FCLK_CLK2;
+ assign bus_clk = FCLK_CLK3;
+
+ //If bus_clk freq ever changes, update this paramter accordingly.
+ localparam BUS_CLK_RATE = 32'd200000000; //200 MHz bus_clk rate.
+
+ n3xx_clocking n3xx_clocking_i (
+ .enable_ref_clk_async(enable_ref_clk_async),
+ .FPGA_REFCLK_P(FPGA_REFCLK_P),
+ .FPGA_REFCLK_N(FPGA_REFCLK_N),
+ .ref_clk(ref_clk),
+ .WB_20MHz_P(WB_20MHZ_P),
+ .WB_20MHz_N(WB_20MHZ_N),
+ .wr_refclk_buf(wr_refclk_buf),
+ .NETCLK_REF_P(NETCLK_REF_P),
+ .NETCLK_REF_N(NETCLK_REF_N),
+ .netclk_buf(netclk_buf),
+ .NETCLK_P(NETCLK_P),
+ .NETCLK_N(NETCLK_N),
+ .gige_refclk_buf(gige_refclk),
+ .MGT156MHZ_CLK1_P(MGT156MHZ_CLK1_P),
+ .MGT156MHZ_CLK1_N(MGT156MHZ_CLK1_N),
+ .xgige_refclk_buf(xgige_refclk),
+ .misc_clks_ref(meas_clk_ref),
+ .meas_clk(meas_clk),
+ .ddr3_dma_clk(ddr3_dma_clk),
+ .misc_clks_reset(meas_clk_reset),
+ .misc_clks_locked(meas_clk_locked),
+ .ext_pps_from_pin(REF_1PPS_IN),
+ .gps_pps_from_pin(GPS_1PPS),
+ .pps_select(pps_select),
+ .pps_refclk(pps_refclk)
+ );
+
+ // Drive the rear panel connector with another controllable copy of the post-TDC PPS
+ // that SW can enable/disable. The user is free to hack this to be whatever
+ // they desire. Flop the PPS signal one more time in order that it can be packed into
+ // an IOB. This extra flop stage matches the additional flop inside DbCore to allow
+ // pps_radioclk1x and pps_out_radioclk to be in sync with one another.
+ synchronizer #(
+ .FALSE_PATH_TO_IN(0)
+ ) pps_export_dsync (
+ .clk(radio_clk), .rst(1'b0), .in(pps_out_enb), .out(export_pps_radioclk)
+ );
+
+ // The radio_clk rate is between [122.88M, 250M] for all known N3xx variants,
+ // resulting in approximately [8ns, 4ns] periods. To pulse-extend the PPS output,
+ // we create a 25 bit-wide counter, creating ~[.262s, .131s] long output high pulses,
+ // variable depending on our radio_clk rate. Create two of the same output signal
+ // in order that the PPS_OUT gets packed into an IOB for tight timing.
+ reg [24:0] pps_out_count = 'b0;
+ reg pps_out_radioclk = 1'b0;
+ reg pps_led_radioclk = 1'b0;
+
+ always @(posedge radio_clk) begin
+ if (export_pps_radioclk) begin
+ if (pps_radioclk1x_iob) begin
+ pps_out_radioclk <= 1'b1;
+ pps_led_radioclk <= 1'b1;
+ pps_out_count <= {25{1'b1}};
+ end else begin
+ if (pps_out_count > 0) begin
+ pps_out_count <= pps_out_count - 1'b1;
+ end else begin
+ pps_out_radioclk <= 1'b0;
+ pps_led_radioclk <= 1'b0;
+ end
+ end
+ end else begin
+ pps_out_radioclk <= 1'b0;
+ pps_led_radioclk <= 1'b0;
+ end
+ end
+ // Local to output.
+ assign REF_1PPS_OUT = pps_out_radioclk;
+ assign PANEL_LED_PPS = pps_led_radioclk;
+
+ /////////////////////////////////////////////////////////////////////
+ //
+ // SFP, QSFP and NPIO MGT Connections
+ //
+ //////////////////////////////////////////////////////////////////////
+ wire reg_wr_req_npio;
+ wire [REG_AWIDTH-1:0] reg_wr_addr_npio;
+ wire [REG_DWIDTH-1:0] reg_wr_data_npio;
+ wire reg_rd_req_npio;
+ wire [REG_AWIDTH-1:0] reg_rd_addr_npio;
+ wire reg_rd_resp_npio, reg_rd_resp_npio0, reg_rd_resp_npio1;
+ wire [REG_DWIDTH-1:0] reg_rd_data_npio, reg_rd_data_npio0, reg_rd_data_npio1;
+
+ localparam NPIO_REG_BASE = 14'h0200;
+
+ regport_resp_mux #(
+ .WIDTH (REG_DWIDTH),
+ .NUM_SLAVES (2)
+ ) npio_resp_mux_i(
+ .clk(bus_clk), .reset(bus_rst),
+ .sla_rd_resp({reg_rd_resp_npio0, reg_rd_resp_npio1}),
+ .sla_rd_data({reg_rd_data_npio0, reg_rd_data_npio1}),
+ .mst_rd_resp(reg_rd_resp_npio), .mst_rd_data(reg_rd_data_npio)
+ );
+
+ //--------------------------------------------------------------
+ // SFP/MGT Reference Clocks
+ //--------------------------------------------------------------
+
+ // We support the HG, XG, XA, AA targets, all of which require
+ // the 156.25MHz reference clock. Instantiate it here.
+ ten_gige_phy_clk_gen xgige_clk_gen_i (
+ .refclk_ibuf(xgige_refclk),
+ .clk156(xgige_clk156),
+ .dclk(xgige_dclk)
+ );
+
+ wire qpllreset;
+ wire qpllreset_sfp0, qpllreset_sfp1, qpllreset_npio0, qpllreset_npio1;
+ wire qplllock;
+ wire qplloutclk;
+ wire qplloutrefclk;
+
+ // We reuse this GT_COMMON wrapper for both ethernet and Aurora because
+ // the behavior is identical
+ ten_gig_eth_pcs_pma_gt_common # (
+ .WRAPPER_SIM_GTRESET_SPEEDUP("TRUE") //Does not affect hardware
+ ) ten_gig_eth_pcs_pma_gt_common_block (
+ .refclk(xgige_refclk),
+ .qpllreset(qpllreset), //from 2nd sfp
+ .qplllock(qplllock),
+ .qplloutclk(qplloutclk),
+ .qplloutrefclk(qplloutrefclk),
+ .qpllrefclksel(3'b101 /*GTSOUTHREFCLK0*/)
+ );
+
+ // The quad's QPLL should reset if any of the channels request it
+ // This should never really happen because we are not changing the reference clock
+ // source for the QPLL.
+ assign qpllreset = qpllreset_sfp0 | qpllreset_sfp1 | qpllreset_npio0 | qpllreset_npio1;
+
+ // Use the 156.25MHz reference clock for Aurora
+ wire aurora_refclk = xgige_refclk;
+ wire aurora_clk156 = xgige_clk156;
+ wire aurora_init_clk = xgige_dclk;
+
+ // White Rabbit and 1GbE both use the same clocking
+`ifdef SFP0_1GBE
+ `define SFP0_WR_1GBE
+`endif
+`ifdef SFP0_WR
+ `define SFP0_WR_1GBE
+`endif
+
+`ifdef SFP0_WR_1GBE
+ // HG and WX targets require the 1GbE clock support
+ BUFG bufg_gige_refclk_i (
+ .I(gige_refclk),
+ .O(gige_refclk_bufg)
+ );
+ assign SFP_0_RS0 = 1'b0;
+ assign SFP_0_RS1 = 1'b0;
+`else
+ assign SFP_0_RS0 = 1'b1;
+ assign SFP_0_RS1 = 1'b1;
+`endif
+
+ // SFP 1 is always set to run at ~10Gbps rates.
+ assign SFP_1_RS0 = 1'b1;
+ assign SFP_1_RS1 = 1'b1;
+
+ // SFP port specific reference clocks
+ wire sfp0_gt_refclk, sfp1_gt_refclk;
+ wire sfp0_gb_refclk, sfp1_gb_refclk;
+ wire sfp0_misc_clk, sfp1_misc_clk;
+
+`ifdef SFP0_10GBE
+ assign sfp0_gt_refclk = xgige_refclk;
+ assign sfp0_gb_refclk = xgige_clk156;
+ assign sfp0_misc_clk = xgige_dclk;
+`endif
+`ifdef SFP0_WR_1GBE
+ assign sfp0_gt_refclk = gige_refclk;
+ assign sfp0_gb_refclk = gige_refclk_bufg;
+ assign sfp0_misc_clk = gige_refclk_bufg;
+`endif
+`ifdef SFP0_AURORA
+ assign sfp0_gt_refclk = aurora_refclk;
+ assign sfp0_gb_refclk = aurora_clk156;
+ assign sfp0_misc_clk = aurora_init_clk;
+`endif
+
+`ifdef SFP1_10GBE
+ assign sfp1_gt_refclk = xgige_refclk;
+ assign sfp1_gb_refclk = xgige_clk156;
+ assign sfp1_misc_clk = xgige_dclk;
+`endif
+`ifdef SFP1_1GBE
+ assign sfp1_gt_refclk = gige_refclk;
+ assign sfp1_gb_refclk = gige_refclk_bufg;
+ assign sfp1_misc_clk = gige_refclk_bufg;
+`endif
+`ifdef SFP1_AURORA
+ assign sfp1_gt_refclk = aurora_refclk;
+ assign sfp1_gb_refclk = aurora_clk156;
+ assign sfp1_misc_clk = aurora_init_clk;
+`endif
+
+ // Instantiate Aurora MMCM if either of the SFPs
+ // or NPIOs are Aurora
+ wire au_tx_clk;
+ wire au_mmcm_reset;
+ wire au_user_clk;
+ wire au_sync_clk;
+ wire au_mmcm_locked;
+ wire sfp0_tx_out_clk, sfp1_tx_out_clk;
+ wire sfp0_gt_pll_lock, sfp1_gt_pll_lock;
+ wire npio0_tx_out_clk, npio1_tx_out_clk;
+ wire npio0_gt_pll_lock, npio1_gt_pll_lock;
+
+ //NOTE: need to declare one of these defines in order to enable Aurora on
+ //any SFP or NPIO lane.
+`ifdef SFP1_AURORA
+ `define SFP_AU_MMCM
+ assign au_tx_clk = sfp1_tx_out_clk;
+ assign au_mmcm_reset = ~sfp1_gt_pll_lock;
+`elsif NPIO0
+ `define SFP_AU_MMCM
+ assign au_tx_clk = npio0_tx_out_clk;
+ assign au_mmcm_reset = ~npio0_gt_pll_lock;
+`elsif NPIO1
+ `define SFP_AU_MMCM
+ assign au_tx_clk = npio1_tx_out_clk;
+ assign au_mmcm_reset = ~npio1_gt_pll_lock;
+`endif
+
+
+`ifdef SFP_AU_MMCM
+ aurora_phy_mmcm au_phy_mmcm_i (
+ .aurora_tx_clk_unbuf(au_tx_clk),
+ .mmcm_reset(au_mmcm_reset),
+ .user_clk(au_user_clk),
+ .sync_clk(au_sync_clk),
+ .mmcm_locked(au_mmcm_locked)
+ );
+`else
+ assign au_user_clk = 1'b0;
+ assign au_sync_clk = 1'b0;
+ assign au_mmcm_locked = 1'b0;
+`endif
+
+ //--------------------------------------------------------------
+ // NPIO-QSFP MGT Lanes (Example loopback config)
+ //--------------------------------------------------------------
+
+`ifdef QSFP_LANES
+ localparam NUM_QSFP_LANES = `QSFP_LANES;
+
+ // QSFP wires to the ARM core and the crossbar
+ // These will only be connected if QSFP is 2x10 GbE
+ wire [NUM_QSFP_LANES*64-1:0] arm_eth_qsfp_tx_tdata_b;
+ wire [NUM_QSFP_LANES-1:0] arm_eth_qsfp_tx_tvalid_b;
+ wire [NUM_QSFP_LANES-1:0] arm_eth_qsfp_tx_tlast_b;
+ wire [NUM_QSFP_LANES-1:0] arm_eth_qsfp_tx_tready_b;
+ wire [NUM_QSFP_LANES*4-1:0] arm_eth_qsfp_tx_tuser_b;
+ wire [NUM_QSFP_LANES*8-1:0] arm_eth_qsfp_tx_tkeep_b;
+
+ wire [NUM_QSFP_LANES*64-1:0] arm_eth_qsfp_rx_tdata_b;
+ wire [NUM_QSFP_LANES-1:0] arm_eth_qsfp_rx_tvalid_b;
+ wire [NUM_QSFP_LANES-1:0] arm_eth_qsfp_rx_tlast_b;
+ wire [NUM_QSFP_LANES-1:0] arm_eth_qsfp_rx_tready_b;
+ wire [NUM_QSFP_LANES*4-1:0] arm_eth_qsfp_rx_tuser_b;
+ wire [NUM_QSFP_LANES*8-1:0] arm_eth_qsfp_rx_tkeep_b;
+
+ wire [NUM_QSFP_LANES*64-1:0] v2e_qsfp_tdata;
+ wire [NUM_QSFP_LANES-1:0] v2e_qsfp_tlast;
+ wire [NUM_QSFP_LANES-1:0] v2e_qsfp_tvalid;
+ wire [NUM_QSFP_LANES-1:0] v2e_qsfp_tready;
+
+ wire [NUM_QSFP_LANES*64-1:0] e2v_qsfp_tdata;
+ wire [NUM_QSFP_LANES-1:0] e2v_qsfp_tlast;
+ wire [NUM_QSFP_LANES-1:0] e2v_qsfp_tvalid;
+ wire [NUM_QSFP_LANES-1:0] e2v_qsfp_tready;
+
+ wire [NUM_QSFP_LANES-1:0] qsfp_link_up;
+
+ // QSFP quad's specific reference clocks
+ wire qsfp_gt_refclk;
+ wire qsfp_gb_refclk;
+ wire qsfp_misc_clk;
+
+ wire qsfp_qplloutclk;
+ wire qsfp_qplloutrefclk;
+ wire qsfp_qplllock;
+ wire qsfp_qpllreset;
+
+ wire qsfp_gt_tx_out_clk;
+ wire qsfp_gt_pll_lock;
+
+ wire qsfp_au_user_clk;
+ wire qsfp_au_sync_clk;
+ wire qsfp_au_mmcm_locked;
+
+
+`ifdef QSFP_10GBE
+ assign qsfp_gt_refclk = xgige_refclk;
+ assign qsfp_gb_refclk = xgige_clk156;
+ assign qsfp_misc_clk = xgige_dclk;
+`endif
+`ifdef QSFP_AURORA
+ assign qsfp_gt_refclk = aurora_refclk;
+ assign qsfp_gb_refclk = aurora_clk156;
+ assign qsfp_misc_clk = aurora_init_clk;
+`endif
+
+ // We reuse this GT_COMMON wrapper for both ethernet and Aurora because
+ // the behavior is identical
+ ten_gig_eth_pcs_pma_gt_common # (
+ .WRAPPER_SIM_GTRESET_SPEEDUP("TRUE") //Does not affect hardware
+ ) qsfp_gt_common_block (
+ .refclk(xgige_refclk),
+ .qpllreset(qsfp_qpllreset),
+ .qplllock(qsfp_qplllock),
+ .qplloutclk(qsfp_qplloutclk),
+ .qplloutrefclk(qsfp_qplloutrefclk),
+ .qpllrefclksel(3'b001 /*GTREFCLK0*/)
+ );
+
+ `ifdef QSFP_AURORA
+ aurora_phy_mmcm aurora_phy_mmcm (
+ .aurora_tx_clk_unbuf(qsfp_gt_tx_out_clk),
+ .mmcm_reset(~qsfp_gt_pll_lock),
+ .user_clk(qsfp_au_user_clk),
+ .sync_clk(qsfp_au_sync_clk),
+ .mmcm_locked(qsfp_au_mmcm_locked)
+ );
+ `else
+ assign qsfp_au_user_clk = 1'b0;
+ assign qsfp_au_sync_clk = 1'b0;
+ assign qsfp_au_mmcm_locked = 1'b0;
+ `endif
+
+ n3xx_mgt_channel_wrapper #(
+ `ifdef QSFP_10GBE
+ .PROTOCOL ("10GbE"),
+ .MDIO_EN (1'b1),
+ .MDIO_PHYADDR (5'd4),
+ `elsif QSFP_AURORA
+ .PROTOCOL ("Aurora"),
+ .MDIO_EN (1'b0),
+ `endif
+ .LANES (NUM_QSFP_LANES),
+ .PORTNUM_BASE (4),
+ .REG_DWIDTH (REG_DWIDTH),
+ .REG_AWIDTH (QSFP_REG_AWIDTH)
+ ) qsfp_wrapper_i (
+ .areset (global_rst),
+ .gt_refclk (qsfp_gt_refclk),
+ .gb_refclk (qsfp_gb_refclk),
+ .misc_clk (qsfp_misc_clk),
+ .user_clk (qsfp_au_user_clk),
+ .sync_clk (qsfp_au_sync_clk),
+ .gt_tx_out_clk_unbuf(qsfp_gt_tx_out_clk),
+
+ .bus_clk (bus_clk),
+ .bus_rst (bus_rst),
+
+ // GT Common
+ .qpllrefclklost (),
+ .qplllock (qsfp_qplllock),
+ .qplloutclk (qsfp_qplloutclk),
+ .qplloutrefclk (qsfp_qplloutrefclk),
+ .qpllreset (qsfp_qpllreset),
+
+ // Aurora MMCM
+ .mmcm_locked (qsfp_au_mmcm_locked),
+ .gt_pll_lock (qsfp_gt_pll_lock),
+
+ .txp (QSFP_TX_P),
+ .txn (QSFP_TX_N),
+ .rxp (QSFP_RX_P),
+ .rxn (QSFP_RX_N),
+
+ .mod_present_n (QSFP_PRESENT_B),
+ .mod_rxlos (1'b0),
+ .mod_tx_fault (1'b0),
+ .mod_tx_disable (),
+ .mod_int_n (QSFP_INT_B),
+ .mod_reset_n (QSFP_RESET_B),
+ .mod_lpmode (QSFP_LPMODE),
+ .mod_sel_n (QSFP_MODSEL_B),
+
+ // Clock and reset
+ .s_axi_aclk (clk40),
+ .s_axi_aresetn (clk40_rstn),
+ // AXI4-Lite: Write address port (domain: s_axi_aclk)
+ .s_axi_awaddr (M_AXI_NET2_AWADDR[QSFP_REG_AWIDTH-1:0]),
+ .s_axi_awvalid (M_AXI_NET2_AWVALID),
+ .s_axi_awready (M_AXI_NET2_AWREADY),
+ // AXI4-Lite: Write data port (domain: s_axi_aclk)
+ .s_axi_wdata (M_AXI_NET2_WDATA),
+ .s_axi_wstrb (M_AXI_NET2_WSTRB),
+ .s_axi_wvalid (M_AXI_NET2_WVALID),
+ .s_axi_wready (M_AXI_NET2_WREADY),
+ // AXI4-Lite: Write response port (domain: s_axi_aclk)
+ .s_axi_bresp (M_AXI_NET2_BRESP),
+ .s_axi_bvalid (M_AXI_NET2_BVALID),
+ .s_axi_bready (M_AXI_NET2_BREADY),
+ // AXI4-Lite: Read address port (domain: s_axi_aclk)
+ .s_axi_araddr (M_AXI_NET2_ARADDR[QSFP_REG_AWIDTH-1:0]),
+ .s_axi_arvalid (M_AXI_NET2_ARVALID),
+ .s_axi_arready (M_AXI_NET2_ARREADY),
+ // AXI4-Lite: Read data port (domain: s_axi_aclk)
+ .s_axi_rdata (M_AXI_NET2_RDATA),
+ .s_axi_rresp (M_AXI_NET2_RRESP),
+ .s_axi_rvalid (M_AXI_NET2_RVALID),
+ .s_axi_rready (M_AXI_NET2_RREADY),
+
+ // Ethernet to Vita
+ .e2v_tdata (e2v_qsfp_tdata),
+ .e2v_tlast (e2v_qsfp_tlast),
+ .e2v_tvalid (e2v_qsfp_tvalid),
+ .e2v_tready (e2v_qsfp_tready),
+
+ // Vita to Ethernet
+ .v2e_tdata (v2e_qsfp_tdata),
+ .v2e_tlast (v2e_qsfp_tlast),
+ .v2e_tvalid (v2e_qsfp_tvalid),
+ .v2e_tready (v2e_qsfp_tready),
+
+ // Ethernet to CPU
+ .e2c_tdata (arm_eth_qsfp_rx_tdata_b),
+ .e2c_tkeep (arm_eth_qsfp_rx_tkeep_b),
+ .e2c_tlast (arm_eth_qsfp_rx_tlast_b),
+ .e2c_tvalid (arm_eth_qsfp_rx_tvalid_b),
+ .e2c_tready (arm_eth_qsfp_rx_tready_b),
+
+ // CPU to Ethernet
+ .c2e_tdata (arm_eth_qsfp_tx_tdata_b),
+ .c2e_tkeep (arm_eth_qsfp_tx_tkeep_b),
+ .c2e_tlast (arm_eth_qsfp_tx_tlast_b),
+ .c2e_tvalid (arm_eth_qsfp_tx_tvalid_b),
+ .c2e_tready (arm_eth_qsfp_tx_tready_b),
+
+ // Sideband White Rabbit Control
+ .wr_reset_n (1'b1),
+ .wr_refclk (1'b0),
+
+ .wr_dac_sclk (),
+ .wr_dac_din (),
+ .wr_dac_clr_n (),
+ .wr_dac_cs_n (),
+ .wr_dac_ldac_n (),
+
+ .wr_eeprom_scl_o(),
+ .wr_eeprom_scl_i(1'b0),
+ .wr_eeprom_sda_o(),
+ .wr_eeprom_sda_i(1'b0),
+
+ .wr_uart_rx (1'b0),
+ .wr_uart_tx (),
+
+ .mod_pps (),
+ .mod_refclk (),
+
+ // WR AXI Control
+ .wr_axi_aclk (),
+ .wr_axi_aresetn (1'b1),
+ .wr_axi_awaddr (),
+ .wr_axi_awvalid (),
+ .wr_axi_awready (),
+ .wr_axi_wdata (),
+ .wr_axi_wstrb (),
+ .wr_axi_wvalid (),
+ .wr_axi_wready (),
+ .wr_axi_bresp (),
+ .wr_axi_bvalid (),
+ .wr_axi_bready (),
+ .wr_axi_araddr (),
+ .wr_axi_arvalid (),
+ .wr_axi_arready (),
+ .wr_axi_rdata (),
+ .wr_axi_rresp (),
+ .wr_axi_rvalid (),
+ .wr_axi_rready (),
+ .wr_axi_rlast (),
+
+ .port_info (),
+ .device_id (device_id),
+
+ .link_up (qsfp_link_up),
+ .activity ()
+ );
+
+ assign QSFP_I2C_SCL = qsfp_scl_t ? 1'bz : qsfp_scl_o;
+ assign qsfp_scl_i = QSFP_I2C_SCL;
+ assign QSFP_I2C_SDA = qsfp_sda_t ? 1'bz : qsfp_sda_o;
+ assign qsfp_sda_i = QSFP_I2C_SDA;
+
+ assign QSFP_LED = |qsfp_link_up;
+`else
+
+ axi_dummy #(
+ .DEC_ERR(1'b0)
+ ) inst_axi_dummy_qsfp (
+ .s_axi_aclk(bus_clk),
+ .s_axi_areset(bus_rst),
+
+ .s_axi_awaddr(M_AXI_NET2_AWADDR),
+ .s_axi_awvalid(M_AXI_NET2_AWVALID),
+ .s_axi_awready(M_AXI_NET2_AWREADY),
+
+ .s_axi_wdata(M_AXI_NET2_WDATA),
+ .s_axi_wvalid(M_AXI_NET2_WVALID),
+ .s_axi_wready(M_AXI_NET2_WREADY),
+
+ .s_axi_bresp(M_AXI_NET2_BRESP),
+ .s_axi_bvalid(M_AXI_NET2_BVALID),
+ .s_axi_bready(M_AXI_NET2_BREADY),
+
+ .s_axi_araddr(M_AXI_NET2_ARADDR),
+ .s_axi_arvalid(M_AXI_NET2_ARVALID),
+ .s_axi_arready(M_AXI_NET2_ARREADY),
+
+ .s_axi_rdata(M_AXI_NET2_RDATA),
+ .s_axi_rresp(M_AXI_NET2_RRESP),
+ .s_axi_rvalid(M_AXI_NET2_RVALID),
+ .s_axi_rready(M_AXI_NET2_RREADY)
+
+ );
+
+ assign qsfp_scl_i = qsfp_scl_t ? 1'b1 : qsfp_scl_o;
+ assign qsfp_sda_i = qsfp_sda_t ? 1'b1 : qsfp_sda_o;
+
+`endif
+
+ //--------------------------------------------------------------
+ // NPIO MGT Lanes (Example loopback config)
+ //--------------------------------------------------------------
+
+`ifdef NPIO_LANES
+
+ wire [127:0] npio_loopback_tdata;
+ wire [1:0] npio_loopback_tvalid;
+ wire [1:0] npio_loopback_tready;
+ wire [1:0] npio_loopback_tlast;
+
+ n3xx_mgt_io_core #(
+ .PROTOCOL ("Aurora"),
+ .REG_BASE (NPIO_REG_BASE + 14'h00),
+ .REG_DWIDTH (REG_DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64)
+ .REG_AWIDTH (REG_AWIDTH), // Width of the address bus
+ .PORTNUM (8'd2),
+ .MDIO_EN (0)
+ ) npio_ln_0_i (
+ .areset (global_rst),
+ .gt_refclk (aurora_refclk),
+ .gb_refclk (aurora_clk156),
+ .misc_clk (aurora_init_clk),
+ .user_clk (au_user_clk),
+ .sync_clk (au_sync_clk),
+ .gt_tx_out_clk_unbuf(npio0_tx_out_clk),
+
+ .bus_clk (bus_clk),//clk for status reg reads to mdio interface
+ .bus_rst (bus_rst),
+ .qpllreset (qpllreset_npio0),
+ .qplloutclk (qplloutclk),
+ .qplloutrefclk (qplloutrefclk),
+ .qplllock (qplllock),
+ .qpllrefclklost (),
+
+ .rxp (NPIO_RX0_P),
+ .rxn (NPIO_RX0_N),
+ .txp (NPIO_TX0_P),
+ .txn (NPIO_TX0_N),
+
+ .sfpp_rxlos (1'b0),
+ .sfpp_tx_fault (1'b0),
+
+ //RegPort
+ .reg_wr_req (reg_wr_req_npio),
+ .reg_wr_addr (reg_wr_addr_npio),
+ .reg_wr_data (reg_wr_data_npio),
+ .reg_rd_req (reg_rd_req_npio),
+ .reg_rd_addr (reg_rd_addr_npio),
+ .reg_rd_resp (reg_rd_resp_npio0),
+ .reg_rd_data (reg_rd_data_npio0),
+
+ //DATA (loopback mode)
+ .s_axis_tdata (npio_loopback_tdata[63:0]), //Data to aurora core
+ .s_axis_tuser (4'b0),
+ .s_axis_tvalid (npio_loopback_tvalid[0]),
+ .s_axis_tlast (npio_loopback_tlast[0]),
+ .s_axis_tready (npio_loopback_tready[0]),
+ .m_axis_tdata (npio_loopback_tdata[63:0]), //Data from aurora core
+ .m_axis_tuser (),
+ .m_axis_tvalid (npio_loopback_tvalid[0]),
+ .m_axis_tlast (npio_loopback_tlast[0]),
+ .m_axis_tready (npio_loopback_tready[0]),
+
+ .mmcm_locked (au_mmcm_locked),
+ .gt_pll_lock (npio0_gt_pll_lock)
+ );
+
+ n3xx_mgt_io_core #(
+ .PROTOCOL ("Aurora"),
+ .REG_BASE (NPIO_REG_BASE + 14'h40),
+ .REG_DWIDTH (REG_DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64)
+ .REG_AWIDTH (REG_AWIDTH), // Width of the address bus
+ .PORTNUM (8'd3),
+ .MDIO_EN (0)
+ ) npio_ln_1_i (
+ .areset (global_rst),
+ .gt_refclk (aurora_refclk),
+ .gb_refclk (aurora_clk156),
+ .misc_clk (aurora_init_clk),
+ .user_clk (au_user_clk),
+ .sync_clk (au_sync_clk),
+ .gt_tx_out_clk_unbuf(npio1_tx_out_clk),
+
+ .bus_clk (bus_clk),//clk for status reg reads to mdio interface
+ .bus_rst (bus_rst),
+ .qpllreset (qpllreset_npio1),
+ .qplloutclk (qplloutclk),
+ .qplloutrefclk (qplloutrefclk),
+ .qplllock (qplllock),
+ .qpllrefclklost (),
+
+ .rxp (NPIO_RX1_P),
+ .rxn (NPIO_RX1_N),
+ .txp (NPIO_TX1_P),
+ .txn (NPIO_TX1_N),
+
+ .sfpp_rxlos (1'b0),
+ .sfpp_tx_fault (1'b0),
+
+ //RegPort
+ .reg_wr_req (reg_wr_req_npio),
+ .reg_wr_addr (reg_wr_addr_npio),
+ .reg_wr_data (reg_wr_data_npio),
+ .reg_rd_req (reg_rd_req_npio),
+ .reg_rd_addr (reg_rd_addr_npio),
+ .reg_rd_resp (reg_rd_resp_npio1),
+ .reg_rd_data (reg_rd_data_npio1),
+
+ //DATA (loopback mode)
+ .s_axis_tdata (npio_loopback_tdata[127:64]), //Data to aurora core
+ .s_axis_tuser (4'b0),
+ .s_axis_tvalid (npio_loopback_tvalid[1]),
+ .s_axis_tlast (npio_loopback_tlast[1]),
+ .s_axis_tready (npio_loopback_tready[1]),
+ .m_axis_tdata (npio_loopback_tdata[127:64]), //Data from aurora core
+ .m_axis_tuser (),
+ .m_axis_tvalid (npio_loopback_tvalid[1]),
+ .m_axis_tlast (npio_loopback_tlast[1]),
+ .m_axis_tready (npio_loopback_tready[1]),
+
+ .mmcm_locked (au_mmcm_locked),
+ .gt_pll_lock (npio1_gt_pll_lock)
+ );
+
+`else
+
+ assign reg_rd_resp_npio0 = 1'b0;
+ assign reg_rd_data_npio0 = 'h0;
+ assign reg_rd_resp_npio1 = 1'b0;
+ assign reg_rd_data_npio1 = 'h0;
+ assign npio0_gt_pll_lock = 1'b1;
+ assign npio1_gt_pll_lock = 1'b1;
+ assign qpllreset_npio0 = 1'b0;
+ assign qpllreset_npio1 = 1'b0;
+
+`endif
+
+
+ // ARM ethernet 0 bridge signals
+ wire [63:0] arm_eth0_tx_tdata;
+ wire arm_eth0_tx_tvalid;
+ wire arm_eth0_tx_tlast;
+ wire arm_eth0_tx_tready;
+ wire [3:0] arm_eth0_tx_tuser;
+ wire [7:0] arm_eth0_tx_tkeep;
+
+ wire [63:0] arm_eth0_tx_tdata_b;
+ wire arm_eth0_tx_tvalid_b;
+ wire arm_eth0_tx_tlast_b;
+ wire arm_eth0_tx_tready_b;
+ wire [3:0] arm_eth0_tx_tuser_b;
+ wire [7:0] arm_eth0_tx_tkeep_b;
+
+ wire [63:0] arm_eth_sfp0_tx_tdata_b;
+ wire arm_eth_sfp0_tx_tvalid_b;
+ wire arm_eth_sfp0_tx_tlast_b;
+ wire arm_eth_sfp0_tx_tready_b;
+ wire [3:0] arm_eth_sfp0_tx_tuser_b;
+ wire [7:0] arm_eth_sfp0_tx_tkeep_b;
+
+ wire [63:0] arm_eth0_rx_tdata;
+ wire arm_eth0_rx_tvalid;
+ wire arm_eth0_rx_tlast;
+ wire arm_eth0_rx_tready;
+ wire [3:0] arm_eth0_rx_tuser;
+ wire [7:0] arm_eth0_rx_tkeep;
+
+ wire [63:0] arm_eth0_rx_tdata_b;
+ wire arm_eth0_rx_tvalid_b;
+ wire arm_eth0_rx_tlast_b;
+ wire arm_eth0_rx_tready_b;
+ wire [3:0] arm_eth0_rx_tuser_b;
+ wire [7:0] arm_eth0_rx_tkeep_b;
+
+ wire [63:0] arm_eth_sfp0_rx_tdata_b;
+ wire arm_eth_sfp0_rx_tvalid_b;
+ wire arm_eth_sfp0_rx_tlast_b;
+ wire arm_eth_sfp0_rx_tready_b;
+ wire [3:0] arm_eth_sfp0_rx_tuser_b;
+ wire [7:0] arm_eth_sfp0_rx_tkeep_b;
+
+ wire arm_eth0_rx_irq;
+ wire arm_eth0_tx_irq;
+
+ // ARM ethernet 1 bridge signals
+ wire [63:0] arm_eth1_tx_tdata;
+ wire arm_eth1_tx_tvalid;
+ wire arm_eth1_tx_tlast;
+ wire arm_eth1_tx_tready;
+ wire [3:0] arm_eth1_tx_tuser;
+ wire [7:0] arm_eth1_tx_tkeep;
+
+ wire [63:0] arm_eth1_tx_tdata_b;
+ wire arm_eth1_tx_tvalid_b;
+ wire arm_eth1_tx_tlast_b;
+ wire arm_eth1_tx_tready_b;
+ wire [3:0] arm_eth1_tx_tuser_b;
+ wire [7:0] arm_eth1_tx_tkeep_b;
+
+ wire [63:0] arm_eth_sfp1_tx_tdata_b;
+ wire arm_eth_sfp1_tx_tvalid_b;
+ wire arm_eth_sfp1_tx_tlast_b;
+ wire arm_eth_sfp1_tx_tready_b;
+ wire [3:0] arm_eth_sfp1_tx_tuser_b;
+ wire [7:0] arm_eth_sfp1_tx_tkeep_b;
+
+ wire [63:0] arm_eth1_rx_tdata;
+ wire arm_eth1_rx_tvalid;
+ wire arm_eth1_rx_tlast;
+ wire arm_eth1_rx_tready;
+ wire [3:0] arm_eth1_rx_tuser;
+ wire [7:0] arm_eth1_rx_tkeep;
+
+ wire [63:0] arm_eth1_rx_tdata_b;
+ wire arm_eth1_rx_tvalid_b;
+ wire arm_eth1_rx_tlast_b;
+ wire arm_eth1_rx_tready_b;
+ wire [3:0] arm_eth1_rx_tuser_b;
+ wire [7:0] arm_eth1_rx_tkeep_b;
+
+ wire [63:0] arm_eth_sfp1_rx_tdata_b;
+ wire arm_eth_sfp1_rx_tvalid_b;
+ wire arm_eth_sfp1_rx_tlast_b;
+ wire arm_eth_sfp1_rx_tready_b;
+ wire [3:0] arm_eth_sfp1_rx_tuser_b;
+ wire [7:0] arm_eth_sfp1_rx_tkeep_b;
+
+ wire arm_eth1_tx_irq;
+ wire arm_eth1_rx_irq;
+
+ // Vita to Ethernet
+ wire [63:0] v2e0_tdata;
+ wire v2e0_tlast;
+ wire v2e0_tvalid;
+ wire v2e0_tready;
+
+ wire [63:0] v2e1_tdata;
+ wire v2e1_tlast;
+ wire v2e1_tvalid;
+ wire v2e1_tready;
+
+ wire [63:0] v2e_sfp0_tdata;
+ wire v2e_sfp0_tlast;
+ wire v2e_sfp0_tvalid;
+ wire v2e_sfp0_tready;
+
+ wire [63:0] v2e_sfp1_tdata;
+ wire v2e_sfp1_tlast;
+ wire v2e_sfp1_tvalid;
+ wire v2e_sfp1_tready;
+
+ // Ethernet to Vita
+ wire [63:0] e2v0_tdata;
+ wire e2v0_tlast;
+ wire e2v0_tvalid;
+ wire e2v0_tready;
+
+ wire [63:0] e2v1_tdata;
+ wire e2v1_tlast;
+ wire e2v1_tvalid;
+ wire e2v1_tready;
+
+ wire [63:0] e2v_sfp0_tdata;
+ wire e2v_sfp0_tlast;
+ wire e2v_sfp0_tvalid;
+ wire e2v_sfp0_tready;
+
+ wire [63:0] e2v_sfp1_tdata;
+ wire e2v_sfp1_tlast;
+ wire e2v_sfp1_tvalid;
+ wire e2v_sfp1_tready;
+
+ // Ethernet crossover
+ wire [63:0] e01_tdata, e10_tdata;
+ wire [3:0] e01_tuser, e10_tuser;
+ wire e01_tlast, e01_tvalid, e01_tready;
+ wire e10_tlast, e10_tvalid, e10_tready;
+
+
+ // DMA xport adapter to PS
+ wire [63:0] m_axis_dma_tdata;
+ wire [3:0] m_axis_dma_tuser;
+ wire m_axis_dma_tlast;
+ wire m_axis_dma_tready;
+ wire m_axis_dma_tvalid;
+
+ wire [63:0] s_axis_dma_tdata;
+ wire [3:0] s_axis_dma_tdest;
+ wire s_axis_dma_tlast;
+ wire s_axis_dma_tready;
+ wire s_axis_dma_tvalid;
+
+ // Misc
+ wire [31:0] sfp_port0_info;
+ wire [31:0] sfp_port1_info;
+ wire sfp0_link_up, sfp1_link_up;
+ wire [15:0] device_id;
+
+ /////////////////////////////////////////////////////////////////////
+ //
+ // SFP Wrapper 0: Network Interface (1/10G or Aurora)
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ n3xx_mgt_channel_wrapper #(
+ .LANES(1),
+ `ifdef SFP0_10GBE
+ .PROTOCOL("10GbE"),
+ .MDIO_EN(1'b1),
+ .MDIO_PHYADDR(5'd4), // PHYADDR must match the "reg" property for PHY in DTS file
+ `elsif SFP0_AURORA
+ .PROTOCOL("Aurora"),
+ .MDIO_EN(1'b0),
+ `elsif SFP0_1GBE
+ .PROTOCOL("1GbE"),
+ .MDIO_EN(1'b1),
+ .MDIO_PHYADDR(5'd4), // PHYADDR must match the "reg" property for PHY in DTS file
+ `elsif SFP0_WR
+ .PROTOCOL("WhiteRabbit"),
+ .MDIO_EN(1'b0),
+ `endif
+ .REG_DWIDTH(REG_DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64)
+ .REG_AWIDTH(REG_AWIDTH), // Width of the address bus
+ .PORTNUM_BASE(8'd0)
+ ) sfp_wrapper_0 (
+ .areset(global_rst),
+ .gt_refclk(sfp0_gt_refclk),
+ .gb_refclk(sfp0_gb_refclk),
+ .misc_clk(sfp0_misc_clk),
+ .user_clk(au_user_clk),
+ .sync_clk(au_sync_clk),
+ .gt_tx_out_clk_unbuf(sfp0_tx_out_clk),
+
+ .bus_rst(bus_rst),
+ .bus_clk(bus_clk),
+
+ .qpllreset(qpllreset_sfp0),
+ .qplllock(qplllock),
+ .qplloutclk(qplloutclk),
+ .qplloutrefclk(qplloutrefclk),
+ .qpllrefclklost(),
+
+ .mmcm_locked(au_mmcm_locked),
+ .gt_pll_lock(sfp0_gt_pll_lock),
+
+ .txp(SFP_0_TX_P),
+ .txn(SFP_0_TX_N),
+ .rxp(SFP_0_RX_P),
+ .rxn(SFP_0_RX_N),
+
+ .mod_present_n(SFP_0_I2C_NPRESENT),
+ .mod_rxlos(SFP_0_LOS),
+ .mod_tx_fault(SFP_0_TXFAULT),
+ .mod_tx_disable(SFP_0_TXDISABLE),
+
+ // Clock and reset
+ .s_axi_aclk(clk40),
+ .s_axi_aresetn(clk40_rstn),
+ // AXI4-Lite: Write address port (domain: s_axi_aclk)
+ .s_axi_awaddr(M_AXI_NET0_AWADDR[REG_AWIDTH-1:0]),
+ .s_axi_awvalid(M_AXI_NET0_AWVALID),
+ .s_axi_awready(M_AXI_NET0_AWREADY),
+ // AXI4-Lite: Write data port (domain: s_axi_aclk)
+ .s_axi_wdata(M_AXI_NET0_WDATA),
+ .s_axi_wstrb(M_AXI_NET0_WSTRB),
+ .s_axi_wvalid(M_AXI_NET0_WVALID),
+ .s_axi_wready(M_AXI_NET0_WREADY),
+ // AXI4-Lite: Write response port (domain: s_axi_aclk)
+ .s_axi_bresp(M_AXI_NET0_BRESP),
+ .s_axi_bvalid(M_AXI_NET0_BVALID),
+ .s_axi_bready(M_AXI_NET0_BREADY),
+ // AXI4-Lite: Read address port (domain: s_axi_aclk)
+ .s_axi_araddr(M_AXI_NET0_ARADDR[REG_AWIDTH-1:0]),
+ .s_axi_arvalid(M_AXI_NET0_ARVALID),
+ .s_axi_arready(M_AXI_NET0_ARREADY),
+ // AXI4-Lite: Read data port (domain: s_axi_aclk)
+ .s_axi_rdata(M_AXI_NET0_RDATA),
+ .s_axi_rresp(M_AXI_NET0_RRESP),
+ .s_axi_rvalid(M_AXI_NET0_RVALID),
+ .s_axi_rready(M_AXI_NET0_RREADY),
+
+ // Ethernet to Vita
+ .e2v_tdata(e2v_sfp0_tdata),
+ .e2v_tlast(e2v_sfp0_tlast),
+ .e2v_tvalid(e2v_sfp0_tvalid),
+ .e2v_tready(e2v_sfp0_tready),
+
+ // Vita to Ethernet
+ .v2e_tdata(v2e_sfp0_tdata),
+ .v2e_tlast(v2e_sfp0_tlast),
+ .v2e_tvalid(v2e_sfp0_tvalid),
+ .v2e_tready(v2e_sfp0_tready),
+
+ // Ethernet to CPU
+ .e2c_tdata(arm_eth_sfp0_rx_tdata_b),
+ .e2c_tkeep(arm_eth_sfp0_rx_tkeep_b),
+ .e2c_tlast(arm_eth_sfp0_rx_tlast_b),
+ .e2c_tvalid(arm_eth_sfp0_rx_tvalid_b),
+ .e2c_tready(arm_eth_sfp0_rx_tready_b),
+
+ // CPU to Ethernet
+ .c2e_tdata(arm_eth_sfp0_tx_tdata_b),
+ .c2e_tkeep(arm_eth_sfp0_tx_tkeep_b),
+ .c2e_tlast(arm_eth_sfp0_tx_tlast_b),
+ .c2e_tvalid(arm_eth_sfp0_tx_tvalid_b),
+ .c2e_tready(arm_eth_sfp0_tx_tready_b),
+
+ // White Rabbit Specific
+`ifdef SFP0_WR
+ .wr_reset_n (~ps_gpio_out[48]), // reset for WR only
+ .wr_refclk (wr_refclk_buf),
+ .wr_dac_sclk (WB_DAC_SCLK),
+ .wr_dac_din (WB_DAC_DIN),
+ .wr_dac_clr_n (WB_DAC_NCLR),
+ .wr_dac_cs_n (WB_DAC_NSYNC),
+ .wr_dac_ldac_n(WB_DAC_NLDAC),
+ .wr_eeprom_scl_o(), // storage for delay characterization
+ .wr_eeprom_scl_i(1'b0), // temp
+ .wr_eeprom_sda_o(),
+ .wr_eeprom_sda_i(1'b0), // temp
+ .wr_uart_rx(wr_uart_rxd), // to/from PS
+ .wr_uart_tx(wr_uart_txd),
+ .mod_pps(pps_wr_refclk), // out, reference clock and pps
+ .mod_refclk(wr_ref_clk),
+ // WR Slave Port to PS
+ .wr_axi_aclk(m_axi_wr_clk), // out to PS
+ .wr_axi_aresetn(1'b1), // in
+ .wr_axi_awaddr(m_axi_wr_awaddr),
+ .wr_axi_awvalid(m_axi_wr_awvalid),
+ .wr_axi_awready(m_axi_wr_awready),
+ .wr_axi_wdata(m_axi_wr_wdata),
+ .wr_axi_wstrb(m_axi_wr_wstrb),
+ .wr_axi_wvalid(m_axi_wr_wvalid),
+ .wr_axi_wready(m_axi_wr_wready),
+ .wr_axi_bresp(m_axi_wr_bresp),
+ .wr_axi_bvalid(m_axi_wr_bvalid),
+ .wr_axi_bready(m_axi_wr_bready),
+ .wr_axi_araddr(m_axi_wr_araddr),
+ .wr_axi_arvalid(m_axi_wr_arvalid),
+ .wr_axi_arready(m_axi_wr_arready),
+ .wr_axi_rdata(m_axi_wr_rdata),
+ .wr_axi_rresp(m_axi_wr_rresp),
+ .wr_axi_rvalid(m_axi_wr_rvalid),
+ .wr_axi_rready(m_axi_wr_rready),
+ .wr_axi_rlast(),
+`else
+ .wr_reset_n(1'b1),
+ .wr_refclk(1'b0),
+ .wr_eeprom_scl_i(1'b0),
+ .wr_eeprom_sda_i(1'b0),
+ .wr_uart_rx(1'b0),
+`endif
+
+ // Misc
+ .port_info(sfp_port0_info),
+ .device_id(device_id),
+
+ // LED
+ .link_up(sfp0_link_up),
+ .activity(SFP_0_LED_A)
+ );
+
+ assign ps_gpio_in[60] = ps_gpio_tri[60] ? sfp0_link_up : ps_gpio_out[60];
+ assign SFP_0_LED_B = sfp0_link_up;
+
+`ifndef SFP0_WR
+ assign WB_DAC_SCLK = 1'b0;
+ assign WB_DAC_DIN = 1'b0;
+ assign WB_DAC_NCLR = 1'b1;
+ assign WB_DAC_NSYNC = 1'b1;
+ assign WB_DAC_NLDAC = 1'b1;
+ assign pps_wr_refclk = 1'b0;
+ assign wr_ref_clk = 1'b0;
+`endif
+
+
+ /////////////////////////////////////////////////////////////////////
+ //
+ // SFP Wrapper 1: Network Interface (1/10G or Aurora)
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ n3xx_mgt_channel_wrapper #(
+ .LANES(1),
+ `ifdef SFP1_10GBE
+ .PROTOCOL("10GbE"),
+ .MDIO_EN(1'b1),
+ .MDIO_PHYADDR(5'd4), // PHYADDR must match the "reg" property for PHY in DTS file
+ `elsif SFP1_AURORA
+ .PROTOCOL("Aurora"),
+ .MDIO_EN(1'b0),
+ `endif
+ .REG_DWIDTH(REG_DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64)
+ .REG_AWIDTH(REG_AWIDTH), // Width of the address bus
+ .PORTNUM_BASE(8'd1)
+ ) sfp_wrapper_1 (
+ .areset(global_rst),
+
+ .gt_refclk(sfp1_gt_refclk),
+ .gb_refclk(sfp1_gb_refclk),
+ .misc_clk(sfp1_misc_clk),
+ .user_clk(au_user_clk),
+ .sync_clk(au_sync_clk),
+ .gt_tx_out_clk_unbuf(sfp1_tx_out_clk),
+
+ .bus_rst(bus_rst),
+ .bus_clk(bus_clk),
+
+ .qpllreset(qpllreset_sfp1),
+ .qplllock(qplllock),
+ .qplloutclk(qplloutclk),
+ .qplloutrefclk(qplloutrefclk),
+ .qpllrefclklost(),
+
+ .mmcm_locked(au_mmcm_locked),
+ .gt_pll_lock(sfp1_gt_pll_lock),
+
+ .txp(SFP_1_TX_P),
+ .txn(SFP_1_TX_N),
+ .rxp(SFP_1_RX_P),
+ .rxn(SFP_1_RX_N),
+
+ .mod_rxlos(SFP_1_LOS),
+ .mod_tx_fault(SFP_1_TXFAULT),
+ .mod_tx_disable(SFP_1_TXDISABLE),
+
+ // Clock and reset
+ .s_axi_aclk(clk40),
+ .s_axi_aresetn(clk40_rstn),
+ // AXI4-Lite: Write address port (domain: s_axi_aclk)
+ .s_axi_awaddr(M_AXI_NET1_AWADDR[REG_AWIDTH-1:0]),
+ .s_axi_awvalid(M_AXI_NET1_AWVALID),
+ .s_axi_awready(M_AXI_NET1_AWREADY),
+ // AXI4-Lite: Write data port (domain: s_axi_aclk)
+ .s_axi_wdata(M_AXI_NET1_WDATA),
+ .s_axi_wstrb(M_AXI_NET1_WSTRB),
+ .s_axi_wvalid(M_AXI_NET1_WVALID),
+ .s_axi_wready(M_AXI_NET1_WREADY),
+ // AXI4-Lite: Write response port (domain: s_axi_aclk)
+ .s_axi_bresp(M_AXI_NET1_BRESP),
+ .s_axi_bvalid(M_AXI_NET1_BVALID),
+ .s_axi_bready(M_AXI_NET1_BREADY),
+ // AXI4-Lite: Read address port (domain: s_axi_aclk)
+ .s_axi_araddr(M_AXI_NET1_ARADDR[REG_AWIDTH-1:0]),
+ .s_axi_arvalid(M_AXI_NET1_ARVALID),
+ .s_axi_arready(M_AXI_NET1_ARREADY),
+ // AXI4-Lite: Read data port (domain: s_axi_aclk)
+ .s_axi_rdata(M_AXI_NET1_RDATA),
+ .s_axi_rresp(M_AXI_NET1_RRESP),
+ .s_axi_rvalid(M_AXI_NET1_RVALID),
+ .s_axi_rready(M_AXI_NET1_RREADY),
+
+ // Ethernet to Vita
+ .e2v_tdata(e2v_sfp1_tdata),
+ .e2v_tlast(e2v_sfp1_tlast),
+ .e2v_tvalid(e2v_sfp1_tvalid),
+ .e2v_tready(e2v_sfp1_tready),
+
+ // Vita to Ethernet
+ .v2e_tdata(v2e_sfp1_tdata),
+ .v2e_tlast(v2e_sfp1_tlast),
+ .v2e_tvalid(v2e_sfp1_tvalid),
+ .v2e_tready(v2e_sfp1_tready),
+
+ // Ethernet to CPU
+ .e2c_tdata(arm_eth_sfp1_rx_tdata_b),
+ .e2c_tkeep(arm_eth_sfp1_rx_tkeep_b),
+ .e2c_tlast(arm_eth_sfp1_rx_tlast_b),
+ .e2c_tvalid(arm_eth_sfp1_rx_tvalid_b),
+ .e2c_tready(arm_eth_sfp1_rx_tready_b),
+
+ // CPU to Ethernet
+ .c2e_tdata(arm_eth_sfp1_tx_tdata_b),
+ .c2e_tkeep(arm_eth_sfp1_tx_tkeep_b),
+ .c2e_tlast(arm_eth_sfp1_tx_tlast_b),
+ .c2e_tvalid(arm_eth_sfp1_tx_tvalid_b),
+ .c2e_tready(arm_eth_sfp1_tx_tready_b),
+
+ // Misc
+ .port_info(sfp_port1_info),
+ .device_id(device_id),
+
+ // LED
+ .link_up(sfp1_link_up),
+ .activity(SFP_1_LED_A)
+ );
+
+ assign ps_gpio_in[61] = ps_gpio_tri[61] ? sfp1_link_up : ps_gpio_out[61];
+ assign SFP_1_LED_B = sfp1_link_up;
+
+ /////////////////////////////////////////////////////////////////////
+ //
+ // Ethernet DMA 0
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ assign IRQ_F2P[0] = arm_eth0_rx_irq;
+ assign IRQ_F2P[1] = arm_eth0_tx_irq;
+
+ assign {S_AXI_HP0_AWID, S_AXI_HP0_ARID} = 12'd0;
+ assign {S_AXI_GP0_AWID, S_AXI_GP0_ARID} = 10'd0;
+
+`ifdef QSFP_10GBE
+ // QSFP+ lanes connect to DMA engines and crossbar
+ // Connect first QSFP+ 10 GbE port to a DMA engine (and the PS/ARM)
+ assign arm_eth_qsfp_tx_tdata_b[0*64 +: 64] = arm_eth0_tx_tdata_b;
+ assign arm_eth_qsfp_tx_tvalid_b[0] = arm_eth0_tx_tvalid_b;
+ assign arm_eth_qsfp_tx_tlast_b[0] = arm_eth0_tx_tlast_b;
+ assign arm_eth0_tx_tready_b = arm_eth_qsfp_tx_tready_b[0];
+ assign arm_eth_qsfp_tx_tuser_b[0*4 +: 4] = arm_eth0_tx_tuser_b;
+ assign arm_eth_qsfp_tx_tkeep_b[0*8 +: 8] = arm_eth0_tx_tkeep_b;
+
+ assign arm_eth0_rx_tdata_b = arm_eth_qsfp_rx_tdata_b[0*64 +: 64];
+ assign arm_eth0_rx_tvalid_b = arm_eth_qsfp_rx_tvalid_b[0];
+ assign arm_eth0_rx_tlast_b = arm_eth_qsfp_rx_tlast_b[0];
+ assign arm_eth_qsfp_rx_tready_b[0] = arm_eth0_rx_tready_b;
+ assign arm_eth0_rx_tuser_b = arm_eth_qsfp_rx_tuser_b[0*4 +: 4];
+ assign arm_eth0_rx_tkeep_b = arm_eth_qsfp_rx_tkeep_b[0*8 +: 8];
+
+ // Connect first QSFP+ 10 GbE port to the crossbar
+ assign v2e_qsfp_tdata[0*64 +: 64] = v2e0_tdata;
+ assign v2e_qsfp_tlast[0] = v2e0_tlast;
+ assign v2e_qsfp_tvalid[0] = v2e0_tvalid;
+ assign v2e0_tready = v2e_qsfp_tready[0];
+
+ assign e2v0_tdata = e2v_qsfp_tdata[0*64 +: 64];
+ assign e2v0_tlast = e2v_qsfp_tlast[0];
+ assign e2v0_tvalid = e2v_qsfp_tvalid[0];
+ assign e2v_qsfp_tready[0] = e2v0_tready;
+
+ // Connect second QSFP+ 10 GbE port to a DMA engine (and the PS/ARM)
+ assign arm_eth_qsfp_tx_tdata_b[1*64 +: 64] = arm_eth1_tx_tdata_b;
+ assign arm_eth_qsfp_tx_tvalid_b[1] = arm_eth1_tx_tvalid_b;
+ assign arm_eth_qsfp_tx_tlast_b[1] = arm_eth1_tx_tlast_b;
+ assign arm_eth1_tx_tready_b = arm_eth_qsfp_tx_tready_b[1];
+ assign arm_eth_qsfp_tx_tuser_b[1*4 +: 4] = arm_eth1_tx_tuser_b;
+ assign arm_eth_qsfp_tx_tkeep_b[1*8 +: 8] = arm_eth1_tx_tkeep_b;
+
+ assign arm_eth1_rx_tdata_b = arm_eth_qsfp_rx_tdata_b[1*64 +: 64];
+ assign arm_eth1_rx_tvalid_b = arm_eth_qsfp_rx_tvalid_b[1];
+ assign arm_eth1_rx_tlast_b = arm_eth_qsfp_rx_tlast_b[1];
+ assign arm_eth_qsfp_rx_tready_b[1] = arm_eth1_rx_tready_b;
+ assign arm_eth1_rx_tuser_b = arm_eth_qsfp_rx_tuser_b[1*4 +: 4];
+ assign arm_eth1_rx_tkeep_b = arm_eth_qsfp_rx_tkeep_b[1*8 +: 8];
+
+ // Connect second QSFP+ 10 GbE port to the crossbar
+ assign v2e_qsfp_tdata[1*64 +: 64] = v2e1_tdata;
+ assign v2e_qsfp_tlast[1] = v2e1_tlast;
+ assign v2e_qsfp_tvalid[1] = v2e1_tvalid;
+ assign v2e1_tready = v2e_qsfp_tready[1];
+
+ assign e2v1_tdata = e2v_qsfp_tdata[1*64 +: 64];
+ assign e2v1_tlast = e2v_qsfp_tlast[1];
+ assign e2v1_tvalid = e2v_qsfp_tvalid[1];
+ assign e2v_qsfp_tready[1] = e2v1_tready;
+`else
+ // SFP+ ports connects to DMA engines and crossbar
+ // Connect first SFP+ 10 GbE port to a DMA engine (and the PS/ARM)
+ assign arm_eth_sfp0_tx_tdata_b = arm_eth0_tx_tdata_b;
+ assign arm_eth_sfp0_tx_tvalid_b = arm_eth0_tx_tvalid_b;
+ assign arm_eth_sfp0_tx_tlast_b = arm_eth0_tx_tlast_b;
+ assign arm_eth0_tx_tready_b = arm_eth_sfp0_tx_tready_b;
+ assign arm_eth_sfp0_tx_tuser_b = arm_eth0_tx_tuser_b;
+ assign arm_eth_sfp0_tx_tkeep_b = arm_eth0_tx_tkeep_b;
+
+ assign arm_eth0_rx_tdata_b = arm_eth_sfp0_rx_tdata_b;
+ assign arm_eth0_rx_tvalid_b = arm_eth_sfp0_rx_tvalid_b;
+ assign arm_eth0_rx_tlast_b = arm_eth_sfp0_rx_tlast_b;
+ assign arm_eth_sfp0_rx_tready_b = arm_eth0_rx_tready_b;
+ assign arm_eth0_rx_tuser_b = arm_eth_sfp0_rx_tuser_b;
+ assign arm_eth0_rx_tkeep_b = arm_eth_sfp0_rx_tkeep_b;
+
+ // Connect first SFP+ 10 GbE port to the crossbar
+ assign v2e_sfp0_tdata = v2e0_tdata;
+ assign v2e_sfp0_tlast = v2e0_tlast;
+ assign v2e_sfp0_tvalid = v2e0_tvalid;
+ assign v2e0_tready = v2e_sfp0_tready;
+
+ assign e2v0_tdata = e2v_sfp0_tdata;
+ assign e2v0_tlast = e2v_sfp0_tlast;
+ assign e2v0_tvalid = e2v_sfp0_tvalid;
+ assign e2v_sfp0_tready = e2v0_tready;
+
+ // Connect second SFP+ 10 GbE port to a DMA engine (and the PS/ARM)
+ assign arm_eth_sfp1_tx_tdata_b = arm_eth1_tx_tdata_b;
+ assign arm_eth_sfp1_tx_tvalid_b = arm_eth1_tx_tvalid_b;
+ assign arm_eth_sfp1_tx_tlast_b = arm_eth1_tx_tlast_b;
+ assign arm_eth1_tx_tready_b = arm_eth_sfp1_tx_tready_b;
+ assign arm_eth_sfp1_tx_tuser_b = arm_eth1_tx_tuser_b;
+ assign arm_eth_sfp1_tx_tkeep_b = arm_eth1_tx_tkeep_b;
+
+ assign arm_eth1_rx_tdata_b = arm_eth_sfp1_rx_tdata_b;
+ assign arm_eth1_rx_tvalid_b = arm_eth_sfp1_rx_tvalid_b;
+ assign arm_eth1_rx_tlast_b = arm_eth_sfp1_rx_tlast_b;
+ assign arm_eth_sfp1_rx_tready_b = arm_eth1_rx_tready_b;
+ assign arm_eth1_rx_tuser_b = arm_eth_sfp1_rx_tuser_b;
+ assign arm_eth1_rx_tkeep_b = arm_eth_sfp1_rx_tkeep_b;
+
+ // Connect first SFP+ 10 GbE port to the crossbar
+ assign v2e_sfp1_tdata = v2e1_tdata;
+ assign v2e_sfp1_tlast = v2e1_tlast;
+ assign v2e_sfp1_tvalid = v2e1_tvalid;
+ assign v2e1_tready = v2e_sfp1_tready;
+
+ assign e2v1_tdata = e2v_sfp1_tdata;
+ assign e2v1_tlast = e2v_sfp1_tlast;
+ assign e2v1_tvalid = e2v_sfp1_tvalid;
+ assign e2v_sfp1_tready = e2v1_tready;
+
+ // Don't actually instantiate DMA engines if protocols can't use them
+ `ifdef SFP0_AURORA
+ `define NO_ETH_DMA_0
+ `elsif SFP0_WR
+ `define NO_ETH_DMA_0
+ `endif
+
+ `ifdef SFP1_AURORA
+ `define NO_ETH_DMA_1
+ `endif
+`endif
+
+`ifdef NO_ETH_DMA_0
+ //If inst Aurora, tie off each axi/axi-lite interface
+ axi_dummy #(
+ .DEC_ERR(1'b0)
+ ) inst_axi_dummy_sfp0_eth_dma (
+ .s_axi_aclk(bus_clk),
+ .s_axi_areset(bus_rst),
+
+ .s_axi_awaddr(M_AXI_ETH_DMA0_AWADDR),
+ .s_axi_awvalid(M_AXI_ETH_DMA0_AWVALID),
+ .s_axi_awready(M_AXI_ETH_DMA0_AWREADY),
+
+ .s_axi_wdata(M_AXI_ETH_DMA0_WDATA),
+ .s_axi_wvalid(M_AXI_ETH_DMA0_WVALID),
+ .s_axi_wready(M_AXI_ETH_DMA0_WREADY),
+
+ .s_axi_bresp(M_AXI_ETH_DMA0_BRESP),
+ .s_axi_bvalid(M_AXI_ETH_DMA0_BVALID),
+ .s_axi_bready(M_AXI_ETH_DMA0_BREADY),
+
+ .s_axi_araddr(M_AXI_ETH_DMA0_ARADDR),
+ .s_axi_arvalid(M_AXI_ETH_DMA0_ARVALID),
+ .s_axi_arready(M_AXI_ETH_DMA0_ARREADY),
+
+ .s_axi_rdata(M_AXI_ETH_DMA0_RDATA),
+ .s_axi_rresp(M_AXI_ETH_DMA0_RRESP),
+ .s_axi_rvalid(M_AXI_ETH_DMA0_RVALID),
+ .s_axi_rready(M_AXI_ETH_DMA0_RREADY)
+
+ );
+ //S_AXI_GP0 outputs from axi_eth_dma, so needs some sort of controller/tie off
+ assign S_AXI_GP0_AWADDR = 32'h0;
+ assign S_AXI_GP0_AWLEN = 8'h0;
+ assign S_AXI_GP0_AWSIZE = 4'h0;
+ assign S_AXI_GP0_AWBURST = 3'h0;
+ assign S_AXI_GP0_AWPROT = 3'h0;
+ assign S_AXI_GP0_AWCACHE = 4'h0;
+ assign S_AXI_GP0_AWVALID = 1'b0;
+ //S_AXI_GP0_AWREADY output from PS
+ assign S_AXI_GP0_WDATA = 32'h0;
+ assign S_AXI_GP0_WSTRB = 4'h0;
+ assign S_AXI_GP0_WLAST = 1'b0;
+ assign S_AXI_GP0_WVALID = 1'b0;
+ //S_AXI_GP0_WREADY output from PS
+ //S_AXI_GP0_BRESP
+ //S_AXI_GP0_BVALID
+ assign S_AXI_GP0_BREADY = 1'b1;
+ assign S_AXI_GP0_ARADDR = 32'h0;
+ assign S_AXI_GP0_ARLEN = 8'h0;
+ assign S_AXI_GP0_ARSIZE = 3'h0;
+ assign S_AXI_GP0_ARBURST = 2'h0;
+ assign S_AXI_GP0_ARPROT = 3'h0;
+ assign S_AXI_GP0_ARCACHE = 4'h0;
+ assign S_AXI_GP0_ARVALID = 1'b0;
+ //S_AXI_GP0_ARREADY
+ //S_AXI_GP0_RDATA
+ //S_AXI_GP0_RRESP
+ //S_AXI_GP0_RLAST
+ //S_AXI_GP0_RVALID
+ assign S_AXI_GP0_RREADY = 1'b1;
+
+ //S_AXI_HP0 from axi_eth_dma
+ assign S_AXI_HP0_ARADDR = 32'h0;
+ assign S_AXI_HP0_ARLEN = 8'h0;
+ assign S_AXI_HP0_ARSIZE = 3'h0;
+ assign S_AXI_HP0_ARBURST = 2'h0;
+ assign S_AXI_HP0_ARPROT = 3'h0;
+ assign S_AXI_HP0_ARCACHE = 4'h0;
+ assign S_AXI_HP0_ARVALID = 1'b0;
+ //S_AXI_HP0_ARREADY
+ //S_AXI_HP0_RDATA
+ //S_AXI_HP0_RRESP
+ //S_AXI_HP0_RLAST
+ //S_AXI_HP0_RVALID
+ assign S_AXI_HP0_RREADY = 1'b1;
+ assign S_AXI_HP0_AWADDR = 32'h0;
+ assign S_AXI_HP0_AWLEN = 8'h0;
+ assign S_AXI_HP0_AWSIZE = 3'h0;
+ assign S_AXI_HP0_AWBURST = 2'h0;
+ assign S_AXI_HP0_AWPROT = 3'h0;
+ assign S_AXI_HP0_AWCACHE = 4'h0;
+ assign S_AXI_HP0_AWVALID = 1'b0;
+ //S_AXI_HP0_AWREADY
+ assign S_AXI_HP0_WDATA = 64'h0;
+ assign S_AXI_HP0_WSTRB = 8'h0;
+ assign S_AXI_HP0_WLAST = 1'b0;
+ assign S_AXI_HP0_WVALID = 1'b0;
+ //S_AXI_HP0_WREADY
+ //S_AXI_HP0_BRESP
+ //S_AXI_HP0_BVALID
+ assign S_AXI_HP0_BREADY = 1'b1;
+
+`else
+
+ axi_eth_dma inst_axi_eth_dma0 (
+ .s_axi_lite_aclk(clk40),
+ .m_axi_sg_aclk(clk40),
+ .m_axi_mm2s_aclk(clk40),
+ .m_axi_s2mm_aclk(clk40),
+ .axi_resetn(clk40_rstn),
+
+ .s_axi_lite_awaddr(M_AXI_ETH_DMA0_AWADDR),
+ .s_axi_lite_awvalid(M_AXI_ETH_DMA0_AWVALID),
+ .s_axi_lite_awready(M_AXI_ETH_DMA0_AWREADY),
+
+ .s_axi_lite_wdata(M_AXI_ETH_DMA0_WDATA),
+ .s_axi_lite_wvalid(M_AXI_ETH_DMA0_WVALID),
+ .s_axi_lite_wready(M_AXI_ETH_DMA0_WREADY),
+
+ .s_axi_lite_bresp(M_AXI_ETH_DMA0_BRESP),
+ .s_axi_lite_bvalid(M_AXI_ETH_DMA0_BVALID),
+ .s_axi_lite_bready(M_AXI_ETH_DMA0_BREADY),
+
+ .s_axi_lite_araddr(M_AXI_ETH_DMA0_ARADDR),
+ .s_axi_lite_arvalid(M_AXI_ETH_DMA0_ARVALID),
+ .s_axi_lite_arready(M_AXI_ETH_DMA0_ARREADY),
+
+ .s_axi_lite_rdata(M_AXI_ETH_DMA0_RDATA),
+ .s_axi_lite_rresp(M_AXI_ETH_DMA0_RRESP),
+ .s_axi_lite_rvalid(M_AXI_ETH_DMA0_RVALID),
+ .s_axi_lite_rready(M_AXI_ETH_DMA0_RREADY),
+
+ .m_axi_sg_awaddr(S_AXI_GP0_AWADDR),
+ .m_axi_sg_awlen(S_AXI_GP0_AWLEN),
+ .m_axi_sg_awsize(S_AXI_GP0_AWSIZE),
+ .m_axi_sg_awburst(S_AXI_GP0_AWBURST),
+ .m_axi_sg_awprot(S_AXI_GP0_AWPROT),
+ .m_axi_sg_awcache(S_AXI_GP0_AWCACHE),
+ .m_axi_sg_awvalid(S_AXI_GP0_AWVALID),
+ .m_axi_sg_awready(S_AXI_GP0_AWREADY),
+ .m_axi_sg_wdata(S_AXI_GP0_WDATA),
+ .m_axi_sg_wstrb(S_AXI_GP0_WSTRB),
+ .m_axi_sg_wlast(S_AXI_GP0_WLAST),
+ .m_axi_sg_wvalid(S_AXI_GP0_WVALID),
+ .m_axi_sg_wready(S_AXI_GP0_WREADY),
+ .m_axi_sg_bresp(S_AXI_GP0_BRESP),
+ .m_axi_sg_bvalid(S_AXI_GP0_BVALID),
+ .m_axi_sg_bready(S_AXI_GP0_BREADY),
+ .m_axi_sg_araddr(S_AXI_GP0_ARADDR),
+ .m_axi_sg_arlen(S_AXI_GP0_ARLEN),
+ .m_axi_sg_arsize(S_AXI_GP0_ARSIZE),
+ .m_axi_sg_arburst(S_AXI_GP0_ARBURST),
+ .m_axi_sg_arprot(S_AXI_GP0_ARPROT),
+ .m_axi_sg_arcache(S_AXI_GP0_ARCACHE),
+ .m_axi_sg_arvalid(S_AXI_GP0_ARVALID),
+ .m_axi_sg_arready(S_AXI_GP0_ARREADY),
+ .m_axi_sg_rdata(S_AXI_GP0_RDATA),
+ .m_axi_sg_rresp(S_AXI_GP0_RRESP),
+ .m_axi_sg_rlast(S_AXI_GP0_RLAST),
+ .m_axi_sg_rvalid(S_AXI_GP0_RVALID),
+ .m_axi_sg_rready(S_AXI_GP0_RREADY),
+
+ .m_axi_mm2s_araddr(S_AXI_HP0_ARADDR),
+ .m_axi_mm2s_arlen(S_AXI_HP0_ARLEN),
+ .m_axi_mm2s_arsize(S_AXI_HP0_ARSIZE),
+ .m_axi_mm2s_arburst(S_AXI_HP0_ARBURST),
+ .m_axi_mm2s_arprot(S_AXI_HP0_ARPROT),
+ .m_axi_mm2s_arcache(S_AXI_HP0_ARCACHE),
+ .m_axi_mm2s_arvalid(S_AXI_HP0_ARVALID),
+ .m_axi_mm2s_arready(S_AXI_HP0_ARREADY),
+ .m_axi_mm2s_rdata(S_AXI_HP0_RDATA),
+ .m_axi_mm2s_rresp(S_AXI_HP0_RRESP),
+ .m_axi_mm2s_rlast(S_AXI_HP0_RLAST),
+ .m_axi_mm2s_rvalid(S_AXI_HP0_RVALID),
+ .m_axi_mm2s_rready(S_AXI_HP0_RREADY),
+
+ .mm2s_prmry_reset_out_n(),
+ .m_axis_mm2s_tdata(arm_eth0_tx_tdata),
+ .m_axis_mm2s_tkeep(arm_eth0_tx_tkeep),
+ .m_axis_mm2s_tvalid(arm_eth0_tx_tvalid),
+ .m_axis_mm2s_tready(arm_eth0_tx_tready),
+ .m_axis_mm2s_tlast(arm_eth0_tx_tlast),
+
+ .m_axi_s2mm_awaddr(S_AXI_HP0_AWADDR),
+ .m_axi_s2mm_awlen(S_AXI_HP0_AWLEN),
+ .m_axi_s2mm_awsize(S_AXI_HP0_AWSIZE),
+ .m_axi_s2mm_awburst(S_AXI_HP0_AWBURST),
+ .m_axi_s2mm_awprot(S_AXI_HP0_AWPROT),
+ .m_axi_s2mm_awcache(S_AXI_HP0_AWCACHE),
+ .m_axi_s2mm_awvalid(S_AXI_HP0_AWVALID),
+ .m_axi_s2mm_awready(S_AXI_HP0_AWREADY),
+ .m_axi_s2mm_wdata(S_AXI_HP0_WDATA),
+ .m_axi_s2mm_wstrb(S_AXI_HP0_WSTRB),
+ .m_axi_s2mm_wlast(S_AXI_HP0_WLAST),
+ .m_axi_s2mm_wvalid(S_AXI_HP0_WVALID),
+ .m_axi_s2mm_wready(S_AXI_HP0_WREADY),
+ .m_axi_s2mm_bresp(S_AXI_HP0_BRESP),
+ .m_axi_s2mm_bvalid(S_AXI_HP0_BVALID),
+ .m_axi_s2mm_bready(S_AXI_HP0_BREADY),
+
+ .s2mm_prmry_reset_out_n(),
+ .s_axis_s2mm_tdata(arm_eth0_rx_tdata),
+ .s_axis_s2mm_tkeep(arm_eth0_rx_tkeep),
+ .s_axis_s2mm_tvalid(arm_eth0_rx_tvalid),
+ .s_axis_s2mm_tready(arm_eth0_rx_tready),
+ .s_axis_s2mm_tlast(arm_eth0_rx_tlast),
+
+ .mm2s_introut(arm_eth0_tx_irq),
+ .s2mm_introut(arm_eth0_rx_irq),
+ .axi_dma_tstvec()
+ );
+
+ axi_fifo_2clk #(
+ .WIDTH(1+8+64),
+ .SIZE(5)
+ ) eth_tx_0_fifo_2clk_i (
+ .reset(clk40_rst),
+ .i_aclk(clk40),
+ .i_tdata({arm_eth0_tx_tlast, arm_eth0_tx_tkeep, arm_eth0_tx_tdata}),
+ .i_tvalid(arm_eth0_tx_tvalid),
+ .i_tready(arm_eth0_tx_tready),
+ .o_aclk(bus_clk),
+ .o_tdata({arm_eth0_tx_tlast_b, arm_eth0_tx_tkeep_b, arm_eth0_tx_tdata_b}),
+ .o_tvalid(arm_eth0_tx_tvalid_b),
+ .o_tready(arm_eth0_tx_tready_b)
+ );
+
+ axi_fifo_2clk #(
+ .WIDTH(1+8+64),
+ .SIZE(5)
+ ) eth_rx_0_fifo_2clk_i (
+ .reset(bus_rst),
+ .i_aclk(bus_clk),
+ .i_tdata({arm_eth0_rx_tlast_b, arm_eth0_rx_tkeep_b, arm_eth0_rx_tdata_b}),
+ .i_tvalid(arm_eth0_rx_tvalid_b),
+ .i_tready(arm_eth0_rx_tready_b),
+ .o_aclk(clk40),
+ .o_tdata({arm_eth0_rx_tlast, arm_eth0_rx_tkeep, arm_eth0_rx_tdata}),
+ .o_tvalid(arm_eth0_rx_tvalid),
+ .o_tready(arm_eth0_rx_tready)
+ );
+
+`endif
+
+ /////////////////////////////////////////////////////////////////////
+ //
+ // Ethernet DMA 1
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ assign IRQ_F2P[2] = arm_eth1_rx_irq;
+ assign IRQ_F2P[3] = arm_eth1_tx_irq;
+
+ assign {S_AXI_HP1_AWID, S_AXI_HP1_ARID} = 12'd0;
+ assign {S_AXI_GP1_AWID, S_AXI_GP1_ARID} = 10'd0;
+
+`ifdef NO_ETH_DMA_1
+ //If inst Aurora, tie off each axi/axi-lite interface
+ axi_dummy #(.DEC_ERR(1'b0)) inst_axi_dummy_sfp1_eth_dma
+ (
+ .s_axi_aclk(bus_clk),
+ .s_axi_areset(bus_rst),
+
+ .s_axi_awaddr(M_AXI_ETH_DMA1_AWADDR),
+ .s_axi_awvalid(M_AXI_ETH_DMA1_AWVALID),
+ .s_axi_awready(M_AXI_ETH_DMA1_AWREADY),
+
+ .s_axi_wdata(M_AXI_ETH_DMA1_WDATA),
+ .s_axi_wvalid(M_AXI_ETH_DMA1_WVALID),
+ .s_axi_wready(M_AXI_ETH_DMA1_WREADY),
+
+ .s_axi_bresp(M_AXI_ETH_DMA1_BRESP),
+ .s_axi_bvalid(M_AXI_ETH_DMA1_BVALID),
+ .s_axi_bready(M_AXI_ETH_DMA1_BREADY),
+
+ .s_axi_araddr(M_AXI_ETH_DMA1_ARADDR),
+ .s_axi_arvalid(M_AXI_ETH_DMA1_ARVALID),
+ .s_axi_arready(M_AXI_ETH_DMA1_ARREADY),
+
+ .s_axi_rdata(M_AXI_ETH_DMA1_RDATA),
+ .s_axi_rresp(M_AXI_ETH_DMA1_RRESP),
+ .s_axi_rvalid(M_AXI_ETH_DMA1_RVALID),
+ .s_axi_rready(M_AXI_ETH_DMA1_RREADY)
+
+ );
+ //S_AXI_GP0 outputs from axi_eth_dma, so needs some sort of controller/tie off
+ assign S_AXI_GP1_AWADDR = 32'h0;
+ assign S_AXI_GP1_AWLEN = 8'h0;
+ assign S_AXI_GP1_AWSIZE = 4'h0;
+ assign S_AXI_GP1_AWBURST = 3'h0;
+ assign S_AXI_GP1_AWPROT = 3'h0;
+ assign S_AXI_GP1_AWCACHE = 4'h0;
+ assign S_AXI_GP1_AWVALID = 1'b0;
+ //S_AXI_GP1_AWREADY output from PS
+ assign S_AXI_GP1_WDATA = 32'h0;
+ assign S_AXI_GP1_WSTRB = 4'h0;
+ assign S_AXI_GP1_WLAST = 1'b0;
+ assign S_AXI_GP1_WVALID = 1'b0;
+ //S_AXI_GP1_WREADY output from PS
+ //S_AXI_GP1_BRESP
+ //S_AXI_GP1_BVALID
+ assign S_AXI_GP1_BREADY = 1'b1;
+ assign S_AXI_GP1_ARADDR = 32'h0;
+ assign S_AXI_GP1_ARLEN = 8'h0;
+ assign S_AXI_GP1_ARSIZE = 3'h0;
+ assign S_AXI_GP1_ARBURST = 2'h0;
+ assign S_AXI_GP1_ARPROT = 3'h0;
+ assign S_AXI_GP1_ARCACHE = 4'h0;
+ assign S_AXI_GP1_ARVALID = 1'b0;
+ //S_AXI_GP1_ARREADY
+ //S_AXI_GP1_RDATA
+ //S_AXI_GP1_RRESP
+ //S_AXI_GP1_RLAST
+ //S_AXI_GP1_RVALID
+ assign S_AXI_GP1_RREADY = 1'b1;
+
+ //S_AXI_HP0 from axi_eth_dma
+ assign S_AXI_HP1_ARADDR = 32'h0;
+ assign S_AXI_HP1_ARLEN = 8'h0;
+ assign S_AXI_HP1_ARSIZE = 3'h0;
+ assign S_AXI_HP1_ARBURST = 2'h0;
+ assign S_AXI_HP1_ARPROT = 3'h0;
+ assign S_AXI_HP1_ARCACHE = 4'h0;
+ assign S_AXI_HP1_ARVALID = 1'b0;
+ //S_AXI_HP1_ARREADY
+ //S_AXI_HP1_RDATA
+ //S_AXI_HP1_RRESP
+ //S_AXI_HP1_RLAST
+ //S_AXI_HP1_RVALID
+ assign S_AXI_HP1_RREADY = 1'b1;
+ assign S_AXI_HP1_AWADDR = 32'h0;
+ assign S_AXI_HP1_AWLEN = 8'h0;
+ assign S_AXI_HP1_AWSIZE = 3'h0;
+ assign S_AXI_HP1_AWBURST = 2'h0;
+ assign S_AXI_HP1_AWPROT = 3'h0;
+ assign S_AXI_HP1_AWCACHE = 4'h0;
+ assign S_AXI_HP1_AWVALID = 1'b0;
+ //S_AXI_HP1_AWREADY
+ assign S_AXI_HP1_WDATA = 64'h0;
+ assign S_AXI_HP1_WSTRB = 8'h0;
+ assign S_AXI_HP1_WLAST = 1'b0;
+ assign S_AXI_HP1_WVALID = 1'b0;
+ //S_AXI_HP1_WREADY
+ //S_AXI_HP1_BRESP
+ //S_AXI_HP1_BVALID
+ assign S_AXI_HP1_BREADY = 1'b1;
+
+`else
+
+ axi_eth_dma inst_axi_eth_dma1 (
+ .s_axi_lite_aclk(clk40),
+ .m_axi_sg_aclk(clk40),
+ .m_axi_mm2s_aclk(clk40),
+ .m_axi_s2mm_aclk(clk40),
+ .axi_resetn(clk40_rstn),
+
+ .s_axi_lite_awaddr(M_AXI_ETH_DMA1_AWADDR),
+ .s_axi_lite_awvalid(M_AXI_ETH_DMA1_AWVALID),
+ .s_axi_lite_awready(M_AXI_ETH_DMA1_AWREADY),
+
+ .s_axi_lite_wdata(M_AXI_ETH_DMA1_WDATA),
+ .s_axi_lite_wvalid(M_AXI_ETH_DMA1_WVALID),
+ .s_axi_lite_wready(M_AXI_ETH_DMA1_WREADY),
+
+ .s_axi_lite_bresp(M_AXI_ETH_DMA1_BRESP),
+ .s_axi_lite_bvalid(M_AXI_ETH_DMA1_BVALID),
+ .s_axi_lite_bready(M_AXI_ETH_DMA1_BREADY),
+
+ .s_axi_lite_araddr(M_AXI_ETH_DMA1_ARADDR),
+ .s_axi_lite_arvalid(M_AXI_ETH_DMA1_ARVALID),
+ .s_axi_lite_arready(M_AXI_ETH_DMA1_ARREADY),
+
+ .s_axi_lite_rdata(M_AXI_ETH_DMA1_RDATA),
+ .s_axi_lite_rresp(M_AXI_ETH_DMA1_RRESP),
+ .s_axi_lite_rvalid(M_AXI_ETH_DMA1_RVALID),
+ .s_axi_lite_rready(M_AXI_ETH_DMA1_RREADY),
+
+ .m_axi_sg_awaddr(S_AXI_GP1_AWADDR),
+ .m_axi_sg_awlen(S_AXI_GP1_AWLEN),
+ .m_axi_sg_awsize(S_AXI_GP1_AWSIZE),
+ .m_axi_sg_awburst(S_AXI_GP1_AWBURST),
+ .m_axi_sg_awprot(S_AXI_GP1_AWPROT),
+ .m_axi_sg_awcache(S_AXI_GP1_AWCACHE),
+ .m_axi_sg_awvalid(S_AXI_GP1_AWVALID),
+ .m_axi_sg_awready(S_AXI_GP1_AWREADY),
+ .m_axi_sg_wdata(S_AXI_GP1_WDATA),
+ .m_axi_sg_wstrb(S_AXI_GP1_WSTRB),
+ .m_axi_sg_wlast(S_AXI_GP1_WLAST),
+ .m_axi_sg_wvalid(S_AXI_GP1_WVALID),
+ .m_axi_sg_wready(S_AXI_GP1_WREADY),
+ .m_axi_sg_bresp(S_AXI_GP1_BRESP),
+ .m_axi_sg_bvalid(S_AXI_GP1_BVALID),
+ .m_axi_sg_bready(S_AXI_GP1_BREADY),
+ .m_axi_sg_araddr(S_AXI_GP1_ARADDR),
+ .m_axi_sg_arlen(S_AXI_GP1_ARLEN),
+ .m_axi_sg_arsize(S_AXI_GP1_ARSIZE),
+ .m_axi_sg_arburst(S_AXI_GP1_ARBURST),
+ .m_axi_sg_arprot(S_AXI_GP1_ARPROT),
+ .m_axi_sg_arcache(S_AXI_GP1_ARCACHE),
+ .m_axi_sg_arvalid(S_AXI_GP1_ARVALID),
+ .m_axi_sg_arready(S_AXI_GP1_ARREADY),
+ .m_axi_sg_rdata(S_AXI_GP1_RDATA),
+ .m_axi_sg_rresp(S_AXI_GP1_RRESP),
+ .m_axi_sg_rlast(S_AXI_GP1_RLAST),
+ .m_axi_sg_rvalid(S_AXI_GP1_RVALID),
+ .m_axi_sg_rready(S_AXI_GP1_RREADY),
+
+ .m_axi_mm2s_araddr(S_AXI_HP1_ARADDR),
+ .m_axi_mm2s_arlen(S_AXI_HP1_ARLEN),
+ .m_axi_mm2s_arsize(S_AXI_HP1_ARSIZE),
+ .m_axi_mm2s_arburst(S_AXI_HP1_ARBURST),
+ .m_axi_mm2s_arprot(S_AXI_HP1_ARPROT),
+ .m_axi_mm2s_arcache(S_AXI_HP1_ARCACHE),
+ .m_axi_mm2s_arvalid(S_AXI_HP1_ARVALID),
+ .m_axi_mm2s_arready(S_AXI_HP1_ARREADY),
+ .m_axi_mm2s_rdata(S_AXI_HP1_RDATA),
+ .m_axi_mm2s_rresp(S_AXI_HP1_RRESP),
+ .m_axi_mm2s_rlast(S_AXI_HP1_RLAST),
+ .m_axi_mm2s_rvalid(S_AXI_HP1_RVALID),
+ .m_axi_mm2s_rready(S_AXI_HP1_RREADY),
+
+ .mm2s_prmry_reset_out_n(),
+ .m_axis_mm2s_tdata(arm_eth1_tx_tdata),
+ .m_axis_mm2s_tkeep(arm_eth1_tx_tkeep),
+ .m_axis_mm2s_tvalid(arm_eth1_tx_tvalid),
+ .m_axis_mm2s_tready(arm_eth1_tx_tready),
+ .m_axis_mm2s_tlast(arm_eth1_tx_tlast),
+
+ .m_axi_s2mm_awaddr(S_AXI_HP1_AWADDR),
+ .m_axi_s2mm_awlen(S_AXI_HP1_AWLEN),
+ .m_axi_s2mm_awsize(S_AXI_HP1_AWSIZE),
+ .m_axi_s2mm_awburst(S_AXI_HP1_AWBURST),
+ .m_axi_s2mm_awprot(S_AXI_HP1_AWPROT),
+ .m_axi_s2mm_awcache(S_AXI_HP1_AWCACHE),
+ .m_axi_s2mm_awvalid(S_AXI_HP1_AWVALID),
+ .m_axi_s2mm_awready(S_AXI_HP1_AWREADY),
+ .m_axi_s2mm_wdata(S_AXI_HP1_WDATA),
+ .m_axi_s2mm_wstrb(S_AXI_HP1_WSTRB),
+ .m_axi_s2mm_wlast(S_AXI_HP1_WLAST),
+ .m_axi_s2mm_wvalid(S_AXI_HP1_WVALID),
+ .m_axi_s2mm_wready(S_AXI_HP1_WREADY),
+ .m_axi_s2mm_bresp(S_AXI_HP1_BRESP),
+ .m_axi_s2mm_bvalid(S_AXI_HP1_BVALID),
+ .m_axi_s2mm_bready(S_AXI_HP1_BREADY),
+
+ .s2mm_prmry_reset_out_n(),
+ .s_axis_s2mm_tdata(arm_eth1_rx_tdata),
+ .s_axis_s2mm_tkeep(arm_eth1_rx_tkeep),
+ .s_axis_s2mm_tvalid(arm_eth1_rx_tvalid),
+ .s_axis_s2mm_tready(arm_eth1_rx_tready),
+ .s_axis_s2mm_tlast(arm_eth1_rx_tlast),
+
+ .mm2s_introut(arm_eth1_tx_irq),
+ .s2mm_introut(arm_eth1_rx_irq),
+ .axi_dma_tstvec()
+ );
+
+ axi_fifo_2clk #(
+ .WIDTH(1+8+64),
+ .SIZE(5)
+ ) eth_tx_1_fifo_2clk_i (
+ .reset(clk40_rst),
+ .i_aclk(clk40),
+ .i_tdata({arm_eth1_tx_tlast, arm_eth1_tx_tkeep, arm_eth1_tx_tdata}),
+ .i_tvalid(arm_eth1_tx_tvalid),
+ .i_tready(arm_eth1_tx_tready),
+ .o_aclk(bus_clk),
+ .o_tdata({arm_eth1_tx_tlast_b, arm_eth1_tx_tkeep_b, arm_eth1_tx_tdata_b}),
+ .o_tvalid(arm_eth1_tx_tvalid_b),
+ .o_tready(arm_eth1_tx_tready_b)
+ );
+
+ axi_fifo_2clk #(
+ .WIDTH(1+8+64),
+ .SIZE(5)
+ ) eth_rx_1_fifo_2clk_i (
+ .reset(bus_rst),
+ .i_aclk(bus_clk),
+ .i_tdata({arm_eth1_rx_tlast_b, arm_eth1_rx_tkeep_b, arm_eth1_rx_tdata_b}),
+ .i_tvalid(arm_eth1_rx_tvalid_b),
+ .i_tready(arm_eth1_rx_tready_b),
+ .o_aclk(clk40),
+ .o_tdata({arm_eth1_rx_tlast, arm_eth1_rx_tkeep, arm_eth1_rx_tdata}),
+ .o_tvalid(arm_eth1_rx_tvalid),
+ .o_tready(arm_eth1_rx_tready)
+ );
+`endif
+
+ /////////////////////////////////////////////////////////////////////
+ //
+ // Processing System
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ wire spi0_sclk;
+ wire spi0_mosi;
+ wire spi0_miso;
+ wire spi0_ss0;
+ wire spi0_ss1;
+ wire spi0_ss2;
+ wire spi1_sclk;
+ wire spi1_mosi;
+ wire spi1_miso;
+ wire spi1_ss0;
+ wire spi1_ss1;
+ wire spi1_ss2;
+
+ assign ps_gpio_in[10] = DBA_MYK_INTRQ;
+`ifndef N300
+ assign ps_gpio_in[11] = DBB_MYK_INTRQ;
+`else
+ assign ps_gpio_in[11] = 1'b0;
+`endif
+
+ // Processing System
+ n310_ps_bd inst_n310_ps (
+ .SPI0_SCLK_I(1'b0),
+ .SPI0_SCLK_O(spi0_sclk),
+ .SPI0_SCLK_T(),
+ .SPI0_MOSI_I(1'b0),
+ .SPI0_MOSI_O(spi0_mosi),
+ .SPI0_MOSI_T(),
+ .SPI0_MISO_I(spi0_miso),
+ .SPI0_MISO_O(),
+ .SPI0_MISO_T(),
+ .SPI0_SS_I(1'b1),
+ .SPI0_SS_O(spi0_ss0),
+ .SPI0_SS1_O(spi0_ss1),
+ .SPI0_SS2_O(spi0_ss2),
+ .SPI0_SS_T(),
+
+ `ifndef N300
+ .SPI1_SCLK_I(1'b0),
+ .SPI1_SCLK_O(spi1_sclk),
+ .SPI1_SCLK_T(),
+ .SPI1_MOSI_I(1'b0),
+ .SPI1_MOSI_O(spi1_mosi),
+ .SPI1_MOSI_T(),
+ .SPI1_MISO_I(spi1_miso),
+ .SPI1_MISO_O(),
+ .SPI1_MISO_T(),
+ .SPI1_SS_I(1'b1),
+ .SPI1_SS_O(spi1_ss0),
+ .SPI1_SS1_O(spi1_ss1),
+ .SPI1_SS2_O(spi1_ss2),
+ .SPI1_SS_T(),
+ `else
+ .SPI1_SCLK_I(1'b0),
+ .SPI1_SCLK_O(),
+ .SPI1_SCLK_T(),
+ .SPI1_MOSI_I(1'b0),
+ .SPI1_MOSI_O(),
+ .SPI1_MOSI_T(),
+ .SPI1_MISO_I(1'b0),
+ .SPI1_MISO_O(),
+ .SPI1_MISO_T(),
+ .SPI1_SS_I(1'b1),
+ .SPI1_SS_O(),
+ .SPI1_SS1_O(),
+ .SPI1_SS2_O(),
+ .SPI1_SS_T(),
+ `endif
+
+ .bus_clk(bus_clk),
+ .bus_rstn(~bus_rst),
+ .clk40(clk40),
+ .clk40_rstn(clk40_rstn),
+
+ .M_AXI_ETH_DMA0_araddr(M_AXI_ETH_DMA0_ARADDR),
+ .M_AXI_ETH_DMA0_arprot(),
+ .M_AXI_ETH_DMA0_arready(M_AXI_ETH_DMA0_ARREADY),
+ .M_AXI_ETH_DMA0_arvalid(M_AXI_ETH_DMA0_ARVALID),
+
+ .M_AXI_ETH_DMA0_awaddr(M_AXI_ETH_DMA0_AWADDR),
+ .M_AXI_ETH_DMA0_awprot(),
+ .M_AXI_ETH_DMA0_awready(M_AXI_ETH_DMA0_AWREADY),
+ .M_AXI_ETH_DMA0_awvalid(M_AXI_ETH_DMA0_AWVALID),
+
+ .M_AXI_ETH_DMA0_wdata(M_AXI_ETH_DMA0_WDATA),
+ .M_AXI_ETH_DMA0_wready(M_AXI_ETH_DMA0_WREADY),
+ .M_AXI_ETH_DMA0_wstrb(M_AXI_ETH_DMA0_WSTRB),
+ .M_AXI_ETH_DMA0_wvalid(M_AXI_ETH_DMA0_WVALID),
+
+ .M_AXI_ETH_DMA0_rdata(M_AXI_ETH_DMA0_RDATA),
+ .M_AXI_ETH_DMA0_rready(M_AXI_ETH_DMA0_RREADY),
+ .M_AXI_ETH_DMA0_rresp(M_AXI_ETH_DMA0_RRESP),
+ .M_AXI_ETH_DMA0_rvalid(M_AXI_ETH_DMA0_RVALID),
+
+ .M_AXI_ETH_DMA0_bready(M_AXI_ETH_DMA0_BREADY),
+ .M_AXI_ETH_DMA0_bresp(M_AXI_ETH_DMA0_BRESP),
+ .M_AXI_ETH_DMA0_bvalid(M_AXI_ETH_DMA0_BVALID),
+
+ .M_AXI_ETH_DMA1_araddr(M_AXI_ETH_DMA1_ARADDR),
+ .M_AXI_ETH_DMA1_arprot(),
+ .M_AXI_ETH_DMA1_arready(M_AXI_ETH_DMA1_ARREADY),
+ .M_AXI_ETH_DMA1_arvalid(M_AXI_ETH_DMA1_ARVALID),
+
+ .M_AXI_ETH_DMA1_awaddr(M_AXI_ETH_DMA1_AWADDR),
+ .M_AXI_ETH_DMA1_awprot(),
+ .M_AXI_ETH_DMA1_awready(M_AXI_ETH_DMA1_AWREADY),
+ .M_AXI_ETH_DMA1_awvalid(M_AXI_ETH_DMA1_AWVALID),
+
+ .M_AXI_ETH_DMA1_bready(M_AXI_ETH_DMA1_BREADY),
+ .M_AXI_ETH_DMA1_bresp(M_AXI_ETH_DMA1_BRESP),
+ .M_AXI_ETH_DMA1_bvalid(M_AXI_ETH_DMA1_BVALID),
+
+ .M_AXI_ETH_DMA1_rdata(M_AXI_ETH_DMA1_RDATA),
+ .M_AXI_ETH_DMA1_rready(M_AXI_ETH_DMA1_RREADY),
+ .M_AXI_ETH_DMA1_rresp(M_AXI_ETH_DMA1_RRESP),
+ .M_AXI_ETH_DMA1_rvalid(M_AXI_ETH_DMA1_RVALID),
+
+ .M_AXI_ETH_DMA1_wdata(M_AXI_ETH_DMA1_WDATA),
+ .M_AXI_ETH_DMA1_wready(M_AXI_ETH_DMA1_WREADY),
+ .M_AXI_ETH_DMA1_wstrb(M_AXI_ETH_DMA1_WSTRB),
+ .M_AXI_ETH_DMA1_wvalid(M_AXI_ETH_DMA1_WVALID),
+
+ .M_AXI_JESD0_araddr(M_AXI_JESD0_ARADDR),
+ .M_AXI_JESD0_arprot(),
+ .M_AXI_JESD0_arready(M_AXI_JESD0_ARREADY),
+ .M_AXI_JESD0_arvalid(M_AXI_JESD0_ARVALID),
+
+ .M_AXI_JESD0_awaddr(M_AXI_JESD0_AWADDR),
+ .M_AXI_JESD0_awprot(),
+ .M_AXI_JESD0_awready(M_AXI_JESD0_AWREADY),
+ .M_AXI_JESD0_awvalid(M_AXI_JESD0_AWVALID),
+
+ .M_AXI_JESD0_bready(M_AXI_JESD0_BREADY),
+ .M_AXI_JESD0_bresp(M_AXI_JESD0_BRESP),
+ .M_AXI_JESD0_bvalid(M_AXI_JESD0_BVALID),
+
+ .M_AXI_JESD0_rdata(M_AXI_JESD0_RDATA),
+ .M_AXI_JESD0_rready(M_AXI_JESD0_RREADY),
+ .M_AXI_JESD0_rresp(M_AXI_JESD0_RRESP),
+ .M_AXI_JESD0_rvalid(M_AXI_JESD0_RVALID),
+
+ .M_AXI_JESD0_wdata(M_AXI_JESD0_WDATA),
+ .M_AXI_JESD0_wready(M_AXI_JESD0_WREADY),
+ .M_AXI_JESD0_wstrb(M_AXI_JESD0_WSTRB),
+ .M_AXI_JESD0_wvalid(M_AXI_JESD0_WVALID),
+
+ .M_AXI_JESD1_araddr(M_AXI_JESD1_ARADDR),
+ .M_AXI_JESD1_arprot(),
+ .M_AXI_JESD1_arready(M_AXI_JESD1_ARREADY),
+ .M_AXI_JESD1_arvalid(M_AXI_JESD1_ARVALID),
+
+ .M_AXI_JESD1_awaddr(M_AXI_JESD1_AWADDR),
+ .M_AXI_JESD1_awprot(),
+ .M_AXI_JESD1_awready(M_AXI_JESD1_AWREADY),
+ .M_AXI_JESD1_awvalid(M_AXI_JESD1_AWVALID),
+
+ .M_AXI_JESD1_bready(M_AXI_JESD1_BREADY),
+ .M_AXI_JESD1_bresp(M_AXI_JESD1_BRESP),
+ .M_AXI_JESD1_bvalid(M_AXI_JESD1_BVALID),
+
+ .M_AXI_JESD1_rdata(M_AXI_JESD1_RDATA),
+ .M_AXI_JESD1_rready(M_AXI_JESD1_RREADY),
+ .M_AXI_JESD1_rresp(M_AXI_JESD1_RRESP),
+ .M_AXI_JESD1_rvalid(M_AXI_JESD1_RVALID),
+
+ .M_AXI_JESD1_wdata(M_AXI_JESD1_WDATA),
+ .M_AXI_JESD1_wready(M_AXI_JESD1_WREADY),
+ .M_AXI_JESD1_wstrb(M_AXI_JESD1_WSTRB),
+ .M_AXI_JESD1_wvalid(M_AXI_JESD1_WVALID),
+
+ .M_AXI_NET0_araddr(M_AXI_NET0_ARADDR),
+ .M_AXI_NET0_arprot(),
+ .M_AXI_NET0_arready(M_AXI_NET0_ARREADY),
+ .M_AXI_NET0_arvalid(M_AXI_NET0_ARVALID),
+
+ .M_AXI_NET0_awaddr(M_AXI_NET0_AWADDR),
+ .M_AXI_NET0_awprot(),
+ .M_AXI_NET0_awready(M_AXI_NET0_AWREADY),
+ .M_AXI_NET0_awvalid(M_AXI_NET0_AWVALID),
+
+ .M_AXI_NET0_bready(M_AXI_NET0_BREADY),
+ .M_AXI_NET0_bresp(M_AXI_NET0_BRESP),
+ .M_AXI_NET0_bvalid(M_AXI_NET0_BVALID),
+
+ .M_AXI_NET0_rdata(M_AXI_NET0_RDATA),
+ .M_AXI_NET0_rready(M_AXI_NET0_RREADY),
+ .M_AXI_NET0_rresp(M_AXI_NET0_RRESP),
+ .M_AXI_NET0_rvalid(M_AXI_NET0_RVALID),
+
+ .M_AXI_NET0_wdata(M_AXI_NET0_WDATA),
+ .M_AXI_NET0_wready(M_AXI_NET0_WREADY),
+ .M_AXI_NET0_wstrb(M_AXI_NET0_WSTRB),
+ .M_AXI_NET0_wvalid(M_AXI_NET0_WVALID),
+
+ .M_AXI_NET1_araddr(M_AXI_NET1_ARADDR),
+ .M_AXI_NET1_arprot(),
+ .M_AXI_NET1_arready(M_AXI_NET1_ARREADY),
+ .M_AXI_NET1_arvalid(M_AXI_NET1_ARVALID),
+
+ .M_AXI_NET1_awaddr(M_AXI_NET1_AWADDR),
+ .M_AXI_NET1_awprot(),
+ .M_AXI_NET1_awready(M_AXI_NET1_AWREADY),
+ .M_AXI_NET1_awvalid(M_AXI_NET1_AWVALID),
+
+ .M_AXI_NET1_bready(M_AXI_NET1_BREADY),
+ .M_AXI_NET1_bresp(M_AXI_NET1_BRESP),
+ .M_AXI_NET1_bvalid(M_AXI_NET1_BVALID),
+
+ .M_AXI_NET1_rdata(M_AXI_NET1_RDATA),
+ .M_AXI_NET1_rready(M_AXI_NET1_RREADY),
+ .M_AXI_NET1_rresp(M_AXI_NET1_RRESP),
+ .M_AXI_NET1_rvalid(M_AXI_NET1_RVALID),
+
+ .M_AXI_NET1_wdata(M_AXI_NET1_WDATA),
+ .M_AXI_NET1_wready(M_AXI_NET1_WREADY),
+ .M_AXI_NET1_wstrb(M_AXI_NET1_WSTRB),
+ .M_AXI_NET1_wvalid(M_AXI_NET1_WVALID),
+
+ .M_AXI_NET2_araddr(M_AXI_NET2_ARADDR),
+ .M_AXI_NET2_arprot(),
+ .M_AXI_NET2_arready(M_AXI_NET2_ARREADY),
+ .M_AXI_NET2_arvalid(M_AXI_NET2_ARVALID),
+
+ .M_AXI_NET2_awaddr(M_AXI_NET2_AWADDR),
+ .M_AXI_NET2_awprot(),
+ .M_AXI_NET2_awready(M_AXI_NET2_AWREADY),
+ .M_AXI_NET2_awvalid(M_AXI_NET2_AWVALID),
+
+ .M_AXI_NET2_bready(M_AXI_NET2_BREADY),
+ .M_AXI_NET2_bresp(M_AXI_NET2_BRESP),
+ .M_AXI_NET2_bvalid(M_AXI_NET2_BVALID),
+
+ .M_AXI_NET2_rdata(M_AXI_NET2_RDATA),
+ .M_AXI_NET2_rready(M_AXI_NET2_RREADY),
+ .M_AXI_NET2_rresp(M_AXI_NET2_RRESP),
+ .M_AXI_NET2_rvalid(M_AXI_NET2_RVALID),
+
+ .M_AXI_NET2_wdata(M_AXI_NET2_WDATA),
+ .M_AXI_NET2_wready(M_AXI_NET2_WREADY),
+ .M_AXI_NET2_wstrb(M_AXI_NET2_WSTRB),
+ .M_AXI_NET2_wvalid(M_AXI_NET2_WVALID),
+
+ .M_AXI_WR_CLK(m_axi_wr_clk),
+ .M_AXI_WR_RSTn(1'b1),
+ .M_AXI_WR_araddr(m_axi_wr_araddr),
+ .M_AXI_WR_arready(m_axi_wr_arready),
+ .M_AXI_WR_arvalid(m_axi_wr_arvalid),
+ .M_AXI_WR_awaddr(m_axi_wr_awaddr),
+ .M_AXI_WR_awready(m_axi_wr_awready),
+ .M_AXI_WR_awvalid(m_axi_wr_awvalid),
+ .M_AXI_WR_bready(m_axi_wr_bready),
+ .M_AXI_WR_bresp(m_axi_wr_bresp),
+ .M_AXI_WR_bvalid(m_axi_wr_bvalid),
+ .M_AXI_WR_rdata(m_axi_wr_rdata),
+ .M_AXI_WR_rready(m_axi_wr_rready),
+ .M_AXI_WR_rresp(m_axi_wr_rresp),
+ .M_AXI_WR_rvalid(m_axi_wr_rvalid),
+ .M_AXI_WR_wdata(m_axi_wr_wdata),
+ .M_AXI_WR_wready(m_axi_wr_wready),
+ .M_AXI_WR_wstrb(m_axi_wr_wstrb),
+ .M_AXI_WR_wvalid(m_axi_wr_wvalid),
+
+ .M_AXI_XBAR_araddr(M_AXI_XBAR_ARADDR),
+ .M_AXI_XBAR_arprot(),
+ .M_AXI_XBAR_arready(M_AXI_XBAR_ARREADY),
+ .M_AXI_XBAR_arvalid(M_AXI_XBAR_ARVALID),
+
+ .M_AXI_XBAR_awaddr(M_AXI_XBAR_AWADDR),
+ .M_AXI_XBAR_awprot(),
+ .M_AXI_XBAR_awready(M_AXI_XBAR_AWREADY),
+ .M_AXI_XBAR_awvalid(M_AXI_XBAR_AWVALID),
+
+ .M_AXI_XBAR_bready(M_AXI_XBAR_BREADY),
+ .M_AXI_XBAR_bresp(M_AXI_XBAR_BRESP),
+ .M_AXI_XBAR_bvalid(M_AXI_XBAR_BVALID),
+
+ .M_AXI_XBAR_rdata(M_AXI_XBAR_RDATA),
+ .M_AXI_XBAR_rready(M_AXI_XBAR_RREADY),
+ .M_AXI_XBAR_rresp(M_AXI_XBAR_RRESP),
+ .M_AXI_XBAR_rvalid(M_AXI_XBAR_RVALID),
+
+ .M_AXI_XBAR_wdata(M_AXI_XBAR_WDATA),
+ .M_AXI_XBAR_wready(M_AXI_XBAR_WREADY),
+ .M_AXI_XBAR_wstrb(M_AXI_XBAR_WSTRB),
+ .M_AXI_XBAR_wvalid(M_AXI_XBAR_WVALID),
+
+ .S_AXI_GP0_ACLK(clk40),
+ .S_AXI_GP0_ARESETN(clk40_rstn),
+ .S_AXI_GP0_araddr(S_AXI_GP0_ARADDR),
+ .S_AXI_GP0_arburst(S_AXI_GP0_ARBURST),
+ .S_AXI_GP0_arcache(S_AXI_GP0_ARCACHE),
+ .S_AXI_GP0_arid(S_AXI_GP0_ARID),
+ .S_AXI_GP0_arlen(S_AXI_GP0_ARLEN),
+ .S_AXI_GP0_arlock(1'b0),
+ .S_AXI_GP0_arprot(S_AXI_GP0_ARPROT),
+ .S_AXI_GP0_arqos(4'b0000),
+ .S_AXI_GP0_arready(S_AXI_GP0_ARREADY),
+ .S_AXI_GP0_arsize(S_AXI_GP0_ARSIZE),
+ .S_AXI_GP0_arvalid(S_AXI_GP0_ARVALID),
+ .S_AXI_GP0_awaddr(S_AXI_GP0_AWADDR),
+ .S_AXI_GP0_awburst(S_AXI_GP0_AWBURST),
+ .S_AXI_GP0_awcache(S_AXI_GP0_AWCACHE),
+ .S_AXI_GP0_awid(S_AXI_GP0_AWID),
+ .S_AXI_GP0_awlen(S_AXI_GP0_AWLEN),
+ .S_AXI_GP0_awlock(1'b0),
+ .S_AXI_GP0_awprot(S_AXI_GP0_AWPROT),
+ .S_AXI_GP0_awqos(4'b0000),
+ .S_AXI_GP0_awregion(4'b0000),
+ .S_AXI_GP0_awready(S_AXI_GP0_AWREADY),
+ .S_AXI_GP0_awsize(S_AXI_GP0_AWSIZE),
+ .S_AXI_GP0_awvalid(S_AXI_GP0_AWVALID),
+ .S_AXI_GP0_bid(),
+ .S_AXI_GP0_bready(S_AXI_GP0_BREADY),
+ .S_AXI_GP0_bresp(S_AXI_GP0_BRESP),
+ .S_AXI_GP0_bvalid(S_AXI_GP0_BVALID),
+ .S_AXI_GP0_rdata(S_AXI_GP0_RDATA),
+ .S_AXI_GP0_rid(),
+ .S_AXI_GP0_rlast(S_AXI_GP0_RLAST),
+ .S_AXI_GP0_rready(S_AXI_GP0_RREADY),
+ .S_AXI_GP0_rresp(S_AXI_GP0_RRESP),
+ .S_AXI_GP0_rvalid(S_AXI_GP0_RVALID),
+ .S_AXI_GP0_wdata(S_AXI_GP0_WDATA),
+ .S_AXI_GP0_wlast(S_AXI_GP0_WLAST),
+ .S_AXI_GP0_wready(S_AXI_GP0_WREADY),
+ .S_AXI_GP0_wstrb(S_AXI_GP0_WSTRB),
+ .S_AXI_GP0_wvalid(S_AXI_GP0_WVALID),
+
+ .S_AXI_GP1_ACLK(clk40),
+ .S_AXI_GP1_ARESETN(clk40_rstn),
+ .S_AXI_GP1_araddr(S_AXI_GP1_ARADDR),
+ .S_AXI_GP1_arburst(S_AXI_GP1_ARBURST),
+ .S_AXI_GP1_arcache(S_AXI_GP1_ARCACHE),
+ .S_AXI_GP1_arid(S_AXI_GP1_ARID),
+ .S_AXI_GP1_arlen(S_AXI_GP1_ARLEN),
+ .S_AXI_GP1_arlock(1'b0),
+ .S_AXI_GP1_arprot(S_AXI_GP1_ARPROT),
+ .S_AXI_GP1_arqos(4'b000),
+ .S_AXI_GP1_arready(S_AXI_GP1_ARREADY),
+ .S_AXI_GP1_arsize(S_AXI_GP1_ARSIZE),
+ .S_AXI_GP1_arvalid(S_AXI_GP1_ARVALID),
+ .S_AXI_GP1_awaddr(S_AXI_GP1_AWADDR),
+ .S_AXI_GP1_awburst(S_AXI_GP1_AWBURST),
+ .S_AXI_GP1_awcache(S_AXI_GP1_AWCACHE),
+ .S_AXI_GP1_awid(S_AXI_GP1_AWID),
+ .S_AXI_GP1_awlen(S_AXI_GP1_AWLEN),
+ .S_AXI_GP1_awlock(1'b0),
+ .S_AXI_GP1_awprot(S_AXI_GP1_AWPROT),
+ .S_AXI_GP1_awqos(4'b0000),
+ .S_AXI_GP1_awregion(4'b0000),
+ .S_AXI_GP1_awready(S_AXI_GP1_AWREADY),
+ .S_AXI_GP1_awsize(S_AXI_GP1_AWSIZE),
+ .S_AXI_GP1_awvalid(S_AXI_GP1_AWVALID),
+ .S_AXI_GP1_bid(),
+ .S_AXI_GP1_bready(S_AXI_GP1_BREADY),
+ .S_AXI_GP1_bresp(S_AXI_GP1_BRESP),
+ .S_AXI_GP1_bvalid(S_AXI_GP1_BVALID),
+ .S_AXI_GP1_rdata(S_AXI_GP1_RDATA),
+ .S_AXI_GP1_rid(),
+ .S_AXI_GP1_rlast(S_AXI_GP1_RLAST),
+ .S_AXI_GP1_rready(S_AXI_GP1_RREADY),
+ .S_AXI_GP1_rresp(S_AXI_GP1_RRESP),
+ .S_AXI_GP1_rvalid(S_AXI_GP1_RVALID),
+ .S_AXI_GP1_wdata(S_AXI_GP1_WDATA),
+ .S_AXI_GP1_wlast(S_AXI_GP1_WLAST),
+ .S_AXI_GP1_wready(S_AXI_GP1_WREADY),
+ .S_AXI_GP1_wstrb(S_AXI_GP1_WSTRB),
+ .S_AXI_GP1_wvalid(S_AXI_GP1_WVALID),
+
+ .S_AXI_HP0_ACLK(clk40),
+ .S_AXI_HP0_ARESETN(clk40_rstn),
+ .S_AXI_HP0_araddr(S_AXI_HP0_ARADDR),
+ .S_AXI_HP0_arburst(S_AXI_HP0_ARBURST),
+ .S_AXI_HP0_arcache(S_AXI_HP0_ARCACHE),
+ .S_AXI_HP0_arid(S_AXI_HP0_ARID),
+ .S_AXI_HP0_arlen(S_AXI_HP0_ARLEN),
+ .S_AXI_HP0_arlock(1'b0),
+ .S_AXI_HP0_arprot(S_AXI_HP0_ARPROT),
+ .S_AXI_HP0_arqos(4'b0000),
+ .S_AXI_HP0_arready(S_AXI_HP0_ARREADY),
+ .S_AXI_HP0_arsize(S_AXI_HP0_ARSIZE),
+ .S_AXI_HP0_arvalid(S_AXI_HP0_ARVALID),
+ .S_AXI_HP0_awaddr(S_AXI_HP0_AWADDR),
+ .S_AXI_HP0_awburst(S_AXI_HP0_AWBURST),
+ .S_AXI_HP0_awcache(S_AXI_HP0_AWCACHE),
+ .S_AXI_HP0_awid(S_AXI_HP0_AWID),
+ .S_AXI_HP0_awlen(S_AXI_HP0_AWLEN),
+ .S_AXI_HP0_awlock(1'b0),
+ .S_AXI_HP0_awprot(S_AXI_HP0_AWPROT),
+ .S_AXI_HP0_awqos(4'b0000),
+ .S_AXI_HP0_awready(S_AXI_HP0_AWREADY),
+ .S_AXI_HP0_awsize(S_AXI_HP0_AWSIZE),
+ .S_AXI_HP0_awvalid(S_AXI_HP0_AWVALID),
+ .S_AXI_HP0_bid(),
+ .S_AXI_HP0_bready(S_AXI_HP0_BREADY),
+ .S_AXI_HP0_bresp(S_AXI_HP0_BRESP),
+ .S_AXI_HP0_bvalid(S_AXI_HP0_BVALID),
+ .S_AXI_HP0_rdata(S_AXI_HP0_RDATA),
+ .S_AXI_HP0_rid(),
+ .S_AXI_HP0_rlast(S_AXI_HP0_RLAST),
+ .S_AXI_HP0_rready(S_AXI_HP0_RREADY),
+ .S_AXI_HP0_rresp(S_AXI_HP0_RRESP),
+ .S_AXI_HP0_rvalid(S_AXI_HP0_RVALID),
+ .S_AXI_HP0_wdata(S_AXI_HP0_WDATA),
+ .S_AXI_HP0_wlast(S_AXI_HP0_WLAST),
+ .S_AXI_HP0_wready(S_AXI_HP0_WREADY),
+ .S_AXI_HP0_wstrb(S_AXI_HP0_WSTRB),
+ .S_AXI_HP0_wvalid(S_AXI_HP0_WVALID),
+
+ .S_AXI_HP1_ACLK(clk40),
+ .S_AXI_HP1_ARESETN(clk40_rstn),
+ .S_AXI_HP1_araddr(S_AXI_HP1_ARADDR),
+ .S_AXI_HP1_arburst(S_AXI_HP1_ARBURST),
+ .S_AXI_HP1_arcache(S_AXI_HP1_ARCACHE),
+ .S_AXI_HP1_arid(S_AXI_HP1_ARID),
+ .S_AXI_HP1_arlen(S_AXI_HP1_ARLEN),
+ .S_AXI_HP1_arlock(1'b0),
+ .S_AXI_HP1_arprot(S_AXI_HP1_ARPROT),
+ .S_AXI_HP1_arqos(4'b0000),
+ .S_AXI_HP1_arready(S_AXI_HP1_ARREADY),
+ .S_AXI_HP1_arsize(S_AXI_HP1_ARSIZE),
+ .S_AXI_HP1_arvalid(S_AXI_HP1_ARVALID),
+ .S_AXI_HP1_awaddr(S_AXI_HP1_AWADDR),
+ .S_AXI_HP1_awburst(S_AXI_HP1_AWBURST),
+ .S_AXI_HP1_awcache(S_AXI_HP1_AWCACHE),
+ .S_AXI_HP1_awid(S_AXI_HP1_AWID),
+ .S_AXI_HP1_awlen(S_AXI_HP1_AWLEN),
+ .S_AXI_HP1_awlock(1'b0),
+ .S_AXI_HP1_awprot(S_AXI_HP1_AWPROT),
+ .S_AXI_HP1_awqos(4'b0000),
+ .S_AXI_HP1_awready(S_AXI_HP1_AWREADY),
+ .S_AXI_HP1_awsize(S_AXI_HP1_AWSIZE),
+ .S_AXI_HP1_awvalid(S_AXI_HP1_AWVALID),
+ .S_AXI_HP1_bid(),
+ .S_AXI_HP1_bready(S_AXI_HP1_BREADY),
+ .S_AXI_HP1_bresp(S_AXI_HP1_BRESP),
+ .S_AXI_HP1_bvalid(S_AXI_HP1_BVALID),
+ .S_AXI_HP1_rdata(S_AXI_HP1_RDATA),
+ .S_AXI_HP1_rid(),
+ .S_AXI_HP1_rlast(S_AXI_HP1_RLAST),
+ .S_AXI_HP1_rready(S_AXI_HP1_RREADY),
+ .S_AXI_HP1_rresp(S_AXI_HP1_RRESP),
+ .S_AXI_HP1_rvalid(S_AXI_HP1_RVALID),
+ .S_AXI_HP1_wdata(S_AXI_HP1_WDATA),
+ .S_AXI_HP1_wlast(S_AXI_HP1_WLAST),
+ .S_AXI_HP1_wready(S_AXI_HP1_WREADY),
+ .S_AXI_HP1_wstrb(S_AXI_HP1_WSTRB),
+ .S_AXI_HP1_wvalid(S_AXI_HP1_WVALID),
+
+ // ARM DMA
+ .s_axis_dma_tdata(s_axis_dma_tdata),
+ .s_axis_dma_tdest(s_axis_dma_tdest),
+ .s_axis_dma_tlast(s_axis_dma_tlast),
+ .s_axis_dma_tready(s_axis_dma_tready),
+ .s_axis_dma_tvalid(s_axis_dma_tvalid),
+ .m_axis_dma_tdata(m_axis_dma_tdata),
+ .m_axis_dma_tuser(m_axis_dma_tuser),
+ .m_axis_dma_tlast(m_axis_dma_tlast),
+ .m_axis_dma_tready(m_axis_dma_tready),
+ .m_axis_dma_tvalid(m_axis_dma_tvalid),
+
+ // Misc Interrupts, GPIO, clk
+ .IRQ_F2P(IRQ_F2P),
+
+ .GPIO_0_tri_i(ps_gpio_in),
+ .GPIO_0_tri_o(ps_gpio_out),
+ .GPIO_0_tri_t(ps_gpio_tri),
+
+ .JTAG0_TCK(DBA_CPLD_JTAG_TCK),
+ .JTAG0_TMS(DBA_CPLD_JTAG_TMS),
+ .JTAG0_TDI(DBA_CPLD_JTAG_TDI),
+ .JTAG0_TDO(DBA_CPLD_JTAG_TDO),
+
+ `ifndef N300
+ .JTAG1_TCK(DBB_CPLD_JTAG_TCK),
+ .JTAG1_TMS(DBB_CPLD_JTAG_TMS),
+ .JTAG1_TDI(DBB_CPLD_JTAG_TDI),
+ .JTAG1_TDO(DBB_CPLD_JTAG_TDO),
+ `else
+ .JTAG1_TCK(),
+ .JTAG1_TMS(),
+ .JTAG1_TDI(),
+ .JTAG1_TDO('b0),
+ `endif
+
+ .FCLK_CLK0(FCLK_CLK0),
+ .FCLK_RESET0_N(FCLK_RESET0_N),
+ .FCLK_CLK1(FCLK_CLK1),
+ .FCLK_RESET1_N(),
+ .FCLK_CLK2(FCLK_CLK2),
+ .FCLK_RESET2_N(),
+ .FCLK_CLK3(FCLK_CLK3),
+ .FCLK_RESET3_N(),
+
+ .WR_UART_txd(wr_uart_rxd), // rx <-> tx
+ .WR_UART_rxd(wr_uart_txd), // rx <-> tx
+
+ .qsfp_sda_i(qsfp_sda_i),
+ .qsfp_sda_o(qsfp_sda_o),
+ .qsfp_sda_t(qsfp_sda_t),
+ .qsfp_scl_i(qsfp_scl_i),
+ .qsfp_scl_o(qsfp_scl_o),
+ .qsfp_scl_t(qsfp_scl_t),
+
+ .USBIND_0_port_indctl(),
+ .USBIND_0_vbus_pwrfault(),
+ .USBIND_0_vbus_pwrselect(),
+
+ // Outward connections to the pins
+ .MIO(MIO),
+ .DDR_cas_n(DDR_CAS_n),
+ .DDR_cke(DDR_CKE),
+ .DDR_ck_n(DDR_Clk_n),
+ .DDR_ck_p(DDR_Clk),
+ .DDR_cs_n(DDR_CS_n),
+ .DDR_reset_n(DDR_DRSTB),
+ .DDR_odt(DDR_ODT),
+ .DDR_ras_n(DDR_RAS_n),
+ .DDR_we_n(DDR_WEB),
+ .DDR_ba(DDR_BankAddr),
+ .DDR_addr(DDR_Addr),
+ .DDR_VRN(DDR_VRN),
+ .DDR_VRP(DDR_VRP),
+ .DDR_dm(DDR_DM),
+ .DDR_dq(DDR_DQ),
+ .DDR_dqs_n(DDR_DQS_n),
+ .DDR_dqs_p(DDR_DQS),
+ .PS_SRSTB(PS_SRSTB),
+ .PS_CLK(PS_CLK),
+ .PS_PORB(PS_PORB)
+ );
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ //
+ // Xilinx DDR3 Controller and PHY.
+ //
+ ///////////////////////////////////////////////////////////////////////////////////
+
+ wire ddr3_axi_clk; // 1/4 DDR external clock rate (200MHz)
+ wire ddr3_axi_rst; // Synchronized to ddr_sys_clk
+ wire ddr3_running; // DRAM calibration complete.
+ wire [11:0] device_temp;
+
+ // Slave Interface Write Address Ports
+ wire [3:0] ddr3_axi_awid;
+ wire [31:0] ddr3_axi_awaddr;
+ wire [7:0] ddr3_axi_awlen;
+ wire [2:0] ddr3_axi_awsize;
+ wire [1:0] ddr3_axi_awburst;
+ wire [0:0] ddr3_axi_awlock;
+ wire [3:0] ddr3_axi_awcache;
+ wire [2:0] ddr3_axi_awprot;
+ wire [3:0] ddr3_axi_awqos;
+ wire ddr3_axi_awvalid;
+ wire ddr3_axi_awready;
+ // Slave Interface Write Data Ports
+ wire [255:0] ddr3_axi_wdata;
+ wire [31:0] ddr3_axi_wstrb;
+ wire ddr3_axi_wlast;
+ wire ddr3_axi_wvalid;
+ wire ddr3_axi_wready;
+ // Slave Interface Write Response Ports
+ wire ddr3_axi_bready;
+ wire [3:0] ddr3_axi_bid;
+ wire [1:0] ddr3_axi_bresp;
+ wire ddr3_axi_bvalid;
+ // Slave Interface Read Address Ports
+ wire [3:0] ddr3_axi_arid;
+ wire [31:0] ddr3_axi_araddr;
+ wire [7:0] ddr3_axi_arlen;
+ wire [2:0] ddr3_axi_arsize;
+ wire [1:0] ddr3_axi_arburst;
+ wire [0:0] ddr3_axi_arlock;
+ wire [3:0] ddr3_axi_arcache;
+ wire [2:0] ddr3_axi_arprot;
+ wire [3:0] ddr3_axi_arqos;
+ wire ddr3_axi_arvalid;
+ wire ddr3_axi_arready;
+ // Slave Interface Read Data Ports
+ wire ddr3_axi_rready;
+ wire [3:0] ddr3_axi_rid;
+ wire [255:0] ddr3_axi_rdata;
+ wire [1:0] ddr3_axi_rresp;
+ wire ddr3_axi_rlast;
+ wire ddr3_axi_rvalid;
+
+ reg ddr3_axi_rst_reg_n;
+
+ // Copied this reset circuit from example design.
+ always @(posedge ddr3_axi_clk)
+ ddr3_axi_rst_reg_n <= ~ddr3_axi_rst;
+
+
+ // Instantiate the DDR3 MIG core
+ //
+ // The top-level IP block has no parameters defined for some reason.
+ // Most of configurable parameters are hard-coded in the mig so get
+ // some additional knobs we pull those out into verilog headers.
+ //
+ // Synthesis params: ip/ddr3_32bit/ddr3_32bit_mig_parameters.vh
+ // Simulation params: ip/ddr3_32bit/ddr3_32bit_mig_sim_parameters.vh
+
+ ddr3_32bit u_ddr3_32bit (
+ // Memory interface ports
+ .ddr3_addr (ddr3_addr),
+ .ddr3_ba (ddr3_ba),
+ .ddr3_cas_n (ddr3_cas_n),
+ .ddr3_ck_n (ddr3_ck_n),
+ .ddr3_ck_p (ddr3_ck_p),
+ .ddr3_cke (ddr3_cke),
+ .ddr3_ras_n (ddr3_ras_n),
+ .ddr3_reset_n (ddr3_reset_n),
+ .ddr3_we_n (ddr3_we_n),
+ .ddr3_dq (ddr3_dq),
+ .ddr3_dqs_n (ddr3_dqs_n),
+ .ddr3_dqs_p (ddr3_dqs_p),
+ .init_calib_complete (ddr3_running),
+ .device_temp_i (device_temp),
+
+ .ddr3_cs_n (ddr3_cs_n),
+ .ddr3_dm (ddr3_dm),
+ .ddr3_odt (ddr3_odt),
+ // Application interface ports
+ .ui_clk (ddr3_axi_clk), // 200Hz clock out
+ .ui_clk_sync_rst (ddr3_axi_rst), // Active high Reset signal synchronised to 200 MHz.
+ .aresetn (ddr3_axi_rst_reg_n),
+ .app_sr_req (1'b0),
+ .app_sr_active (),
+ .app_ref_req (1'b0),
+ .app_ref_ack (),
+ .app_zq_req (1'b0),
+ .app_zq_ack (),
+ // Slave Interface Write Address Ports
+ .s_axi_awid (ddr3_axi_awid),
+ .s_axi_awaddr (ddr3_axi_awaddr),
+ .s_axi_awlen (ddr3_axi_awlen),
+ .s_axi_awsize (ddr3_axi_awsize),
+ .s_axi_awburst (ddr3_axi_awburst),
+ .s_axi_awlock (ddr3_axi_awlock),
+ .s_axi_awcache (ddr3_axi_awcache),
+ .s_axi_awprot (ddr3_axi_awprot),
+ .s_axi_awqos (ddr3_axi_awqos),
+ .s_axi_awvalid (ddr3_axi_awvalid),
+ .s_axi_awready (ddr3_axi_awready),
+ // Slave Interface Write Data Ports
+ .s_axi_wdata (ddr3_axi_wdata),
+ .s_axi_wstrb (ddr3_axi_wstrb),
+ .s_axi_wlast (ddr3_axi_wlast),
+ .s_axi_wvalid (ddr3_axi_wvalid),
+ .s_axi_wready (ddr3_axi_wready),
+ // Slave Interface Write Response Ports
+ .s_axi_bid (ddr3_axi_bid),
+ .s_axi_bresp (ddr3_axi_bresp),
+ .s_axi_bvalid (ddr3_axi_bvalid),
+ .s_axi_bready (ddr3_axi_bready),
+ // Slave Interface Read Address Ports
+ .s_axi_arid (ddr3_axi_arid),
+ .s_axi_araddr (ddr3_axi_araddr),
+ .s_axi_arlen (ddr3_axi_arlen),
+ .s_axi_arsize (ddr3_axi_arsize),
+ .s_axi_arburst (ddr3_axi_arburst),
+ .s_axi_arlock (ddr3_axi_arlock),
+ .s_axi_arcache (ddr3_axi_arcache),
+ .s_axi_arprot (ddr3_axi_arprot),
+ .s_axi_arqos (ddr3_axi_arqos),
+ .s_axi_arvalid (ddr3_axi_arvalid),
+ .s_axi_arready (ddr3_axi_arready),
+ // Slave Interface Read Data Ports
+ .s_axi_rid (ddr3_axi_rid),
+ .s_axi_rdata (ddr3_axi_rdata),
+ .s_axi_rresp (ddr3_axi_rresp),
+ .s_axi_rlast (ddr3_axi_rlast),
+ .s_axi_rvalid (ddr3_axi_rvalid),
+ .s_axi_rready (ddr3_axi_rready),
+ // System Clock Ports
+ .sys_clk_p (sys_clk_p),
+ .sys_clk_n (sys_clk_n),
+ .clk_ref_i (bus_clk),
+
+ .sys_rst (~global_rst) // IJB. Poorly named active low. Should change RST_ACT_LOW.
+ );
+
+ // Temperature monitor module
+ mig_7series_v4_2_tempmon #(
+ .TEMP_MON_CONTROL("INTERNAL"),
+ .XADC_CLK_PERIOD(5000 /* 200MHz clock period in ps */)
+ ) tempmon_i (
+ .clk(bus_clk), .xadc_clk(bus_clk), .rst(bus_rst),
+ .device_temp_i(12'd0 /* ignored */), .device_temp(device_temp)
+ );
+
+ ///////////////////////////////////////////////////////
+ //
+ // DB PS SPI Connections
+ //
+ ///////////////////////////////////////////////////////
+ wire [NUM_CHANNELS-1:0] rx_atr;
+ wire [NUM_CHANNELS-1:0] tx_atr;
+ (* IOB = "true" *) reg [NUM_CHANNELS-1:0] rx_atr_reg;
+ (* IOB = "true" *) reg [NUM_CHANNELS-1:0] tx_atr_reg;
+
+ // Radio GPIO control for DSA
+ wire [16*NUM_CHANNELS-1:0] db_gpio_out;
+ wire [16*NUM_CHANNELS-1:0] db_gpio_ddr;
+ wire [16*NUM_CHANNELS-1:0] db_gpio_in;
+ wire [16*NUM_CHANNELS-1:0] db_gpio_fab;
+
+ // DB A SPI Connections
+ wire cpld_a_cs_n;
+ wire lmk_a_cs_n;
+ wire dac_a_cs_n;
+ wire myk_a_cs_n;
+
+ // Split out the SCLK and MOSI data to Mykonos and the CPLD.
+ assign DBA_CPLD_PS_SPI_SCLK = spi0_sclk;
+ assign DBA_CPLD_PS_SPI_SDI = spi0_mosi;
+
+ assign DBA_MYK_SPI_SCLK = spi0_sclk;
+ assign DBA_MYK_SPI_SDIO = spi0_mosi;
+ // Assign individual chip selects from PS SPI MASTER 0.
+ assign cpld_a_cs_n = spi0_ss0;
+ assign lmk_a_cs_n = spi0_ss1;
+ assign dac_a_cs_n = ps_gpio_out[8]; // DAC select driven through GPIO.
+ assign myk_a_cs_n = spi0_ss2;
+
+ // Returned data mux from the SPI interfaces.
+ assign spi0_miso = ~myk_a_cs_n ? DBA_MYK_SPI_SDO : // From Mykonos
+ DBA_CPLD_PS_SPI_SDO;
+
+ // For the PS SPI connection to the CPLD, we use the LE and ADDR lines as individual
+ // chip selects for the CPLD endpoint as well as the LMK and DAC endpoints.
+ // LE = CPLD
+ // ADDR[0] = LMK
+ // ADDR[1] = DAC
+ assign DBA_CPLD_PS_SPI_LE = cpld_a_cs_n;
+ assign DBA_CPLD_PS_SPI_ADDR[0] = lmk_a_cs_n;
+ assign DBA_CPLD_PS_SPI_ADDR[1] = dac_a_cs_n;
+ assign DBA_MYK_SPI_CS_n = myk_a_cs_n;
+
+ // Instantiate DSA registers in the IOB
+ (* IOB = "true" *) reg [5:0] dsa_tx1_a_out_iob, dsa_rx1_a_out_iob;
+ (* IOB = "true" *) reg [5:0] dsa_tx2_a_out_iob, dsa_rx2_a_out_iob;
+ always @(posedge radio_clk) begin
+ dsa_tx1_a_out_iob <= db_gpio_out[16*0+11:16*0+6];
+ dsa_rx1_a_out_iob <= db_gpio_out[16*0+5:16*0+0];
+ dsa_tx2_a_out_iob <= db_gpio_out[16*1+11:16*1+6];
+ dsa_rx2_a_out_iob <= db_gpio_out[16*1+5:16*1+0];
+ end
+
+ assign DBA_CH1_TX_DSA_DATA = dsa_tx1_a_out_iob;
+ assign DBA_CH1_RX_DSA_DATA = dsa_rx1_a_out_iob;
+ assign DBA_CH2_TX_DSA_DATA = dsa_tx2_a_out_iob;
+ assign DBA_CH2_RX_DSA_DATA = dsa_rx2_a_out_iob;
+
+ assign DBA_ATR_RX_1 = rx_atr_reg[0];
+ assign DBA_ATR_RX_2 = rx_atr_reg[1];
+ assign DBA_ATR_TX_1 = tx_atr_reg[0];
+ assign DBA_ATR_TX_2 = tx_atr_reg[1];
+
+ assign DBA_MYK_GPIO_0 = 1'b0;
+ assign DBA_MYK_GPIO_1 = 1'b0;
+ assign DBA_MYK_GPIO_3 = 1'b0;
+ assign DBA_MYK_GPIO_4 = 1'b0;
+ assign DBA_MYK_GPIO_12 = 1'b0;
+ assign DBA_MYK_GPIO_13 = 1'b0;
+ assign DBA_MYK_GPIO_14 = 1'b0;
+ assign DBA_MYK_GPIO_15 = 1'b0;
+
+`ifndef N300
+
+ // DB B SPI Connections
+ wire cpld_b_cs_n;
+ wire lmk_b_cs_n;
+ wire dac_b_cs_n;
+ wire myk_b_cs_n;
+
+ // Split out the SCLK and MOSI data to Mykonos and the CPLD.
+ assign DBB_CPLD_PS_SPI_SCLK = spi1_sclk;
+ assign DBB_CPLD_PS_SPI_SDI = spi1_mosi;
+
+ assign DBB_MYK_SPI_SCLK = spi1_sclk;
+ assign DBB_MYK_SPI_SDIO = spi1_mosi;
+
+ // Assign individual chip selects from PS SPI MASTER 1.
+ assign cpld_b_cs_n = spi1_ss0;
+ assign lmk_b_cs_n = spi1_ss1;
+ assign dac_b_cs_n = ps_gpio_out[9]; // DAC select driven through GPIO.
+ assign myk_b_cs_n = spi1_ss2;
+
+ // Returned data mux from the SPI interfaces.
+ assign spi1_miso = ~myk_b_cs_n ? DBB_MYK_SPI_SDO : // From Mykonos
+ DBB_CPLD_PS_SPI_SDO;
+
+ // For the PS SPI connection to the CPLD, we use the LE and ADDR lines as individual
+ // chip selects for the CPLD endpoint as well as the LMK and DAC endpoints.
+ // LE = CPLD
+ // ADDR[0] = LMK
+ // ADDR[1] = DAC
+ assign DBB_CPLD_PS_SPI_LE = cpld_b_cs_n;
+ assign DBB_CPLD_PS_SPI_ADDR[0] = lmk_b_cs_n;
+ assign DBB_CPLD_PS_SPI_ADDR[1] = dac_b_cs_n;
+ assign DBB_MYK_SPI_CS_n = myk_b_cs_n;
+
+ // Instantiate DSA registers in the IOB
+ (* IOB = "true" *) reg [5:0] dsa_tx1_b_out_iob, dsa_rx1_b_out_iob;
+ (* IOB = "true" *) reg [5:0] dsa_tx2_b_out_iob, dsa_rx2_b_out_iob;
+ always @(posedge radio_clk) begin
+ dsa_tx1_b_out_iob <= db_gpio_out[16*2+11:16*2+6];
+ dsa_rx1_b_out_iob <= db_gpio_out[16*2+5:16*2+0];
+ dsa_tx2_b_out_iob <= db_gpio_out[16*3+11:16*3+6];
+ dsa_rx2_b_out_iob <= db_gpio_out[16*3+5:16*3+0];
+ end
+
+ assign DBB_CH1_TX_DSA_DATA = dsa_tx1_b_out_iob;
+ assign DBB_CH1_RX_DSA_DATA = dsa_rx1_b_out_iob;
+ assign DBB_CH2_TX_DSA_DATA = dsa_tx2_b_out_iob;
+ assign DBB_CH2_RX_DSA_DATA = dsa_rx2_b_out_iob;
+
+ assign DBB_ATR_RX_1 = rx_atr_reg[2];
+ assign DBB_ATR_RX_2 = rx_atr_reg[3];
+ assign DBB_ATR_TX_1 = tx_atr_reg[2];
+ assign DBB_ATR_TX_2 = tx_atr_reg[3];
+
+ assign DBB_MYK_GPIO_0 = 1'b0;
+ assign DBB_MYK_GPIO_1 = 1'b0;
+ assign DBB_MYK_GPIO_3 = 1'b0;
+ assign DBB_MYK_GPIO_4 = 1'b0;
+ assign DBB_MYK_GPIO_12 = 1'b0;
+ assign DBB_MYK_GPIO_13 = 1'b0;
+ assign DBB_MYK_GPIO_14 = 1'b0;
+ assign DBB_MYK_GPIO_15 = 1'b0;
+
+`endif
+
+ ///////////////////////////////////////////////////////
+ //
+ // N3xx CORE
+ //
+ ///////////////////////////////////////////////////////
+
+ wire [31:0] rx[NUM_CHANNELS-1:0];
+ wire [31:0] tx[NUM_CHANNELS-1:0];
+ wire [32*NUM_CHANNELS-1:0] rx_flat;
+ wire [32*NUM_CHANNELS-1:0] tx_flat;
+
+ wire [NUM_CHANNELS-1:0] rx_stb;
+ wire [NUM_CHANNELS-1:0] tx_stb;
+
+ wire [31:0] build_datestamp;
+
+ genvar i;
+ generate
+ for (i = 0; i < NUM_CHANNELS; i = i + 1) begin
+ // Radio Data
+ assign rx_flat[32*i+31:32*i] = rx[i];
+ assign tx[i] = tx_flat[32*i+31:32*i];
+ end
+ endgenerate
+
+ USR_ACCESSE2 usr_access_i (
+ .DATA(build_datestamp), .CFGCLK(), .DATAVALID()
+ );
+
+ n3xx_core #(
+ .REG_AWIDTH(14),
+ .BUS_CLK_RATE(BUS_CLK_RATE),
+ .FP_GPIO_WIDTH(FP_GPIO_WIDTH),
+ .NUM_CHANNELS_PER_RADIO(NUM_CHANNELS_PER_RADIO),
+ .NUM_CHANNELS(NUM_CHANNELS),
+ .NUM_DBOARDS(NUM_DBOARDS),
+ `ifdef USE_REPLAY
+ .USE_REPLAY(1)
+ `else
+ .USE_REPLAY(0)
+ `endif
+ ) n3xx_core(
+ // Clocks and resets
+ `ifdef NO_DB
+ .radio_clk(bus_clk),
+ .radio_rst(bus_rst),
+ `else
+ .radio_clk(radio_clk),
+ .radio_rst(radio_rst),
+ `endif
+ .bus_clk(bus_clk),
+ .bus_rst(bus_rst),
+ .ddr3_dma_clk(ddr3_dma_clk),
+ .clk40(clk40),
+
+ // Clocking and PPS Controls/Indicators
+ .pps(pps_radioclk1x),
+ .pps_select(pps_select),
+ .pps_out_enb(pps_out_enb),
+ .pps_select_sfp(pps_select_sfp),
+ .ref_clk_reset(),
+ .meas_clk_reset(meas_clk_reset),
+ .ref_clk_locked(1'b1),
+ .meas_clk_locked(meas_clk_locked),
+ .enable_ref_clk_async(enable_ref_clk_async),
+
+ .s_axi_aclk(clk40),
+ .s_axi_aresetn(clk40_rstn),
+ // AXI4-Lite: Write address port (domain: s_axi_aclk)
+ .s_axi_awaddr(M_AXI_XBAR_AWADDR),
+ .s_axi_awvalid(M_AXI_XBAR_AWVALID),
+ .s_axi_awready(M_AXI_XBAR_AWREADY),
+ // AXI4-Lite: Write data port (domain: s_axi_aclk)
+ .s_axi_wdata(M_AXI_XBAR_WDATA),
+ .s_axi_wstrb(M_AXI_XBAR_WSTRB),
+ .s_axi_wvalid(M_AXI_XBAR_WVALID),
+ .s_axi_wready(M_AXI_XBAR_WREADY),
+ // AXI4-Lite: Write response port (domain: s_axi_aclk)
+ .s_axi_bresp(M_AXI_XBAR_BRESP),
+ .s_axi_bvalid(M_AXI_XBAR_BVALID),
+ .s_axi_bready(M_AXI_XBAR_BREADY),
+ // AXI4-Lite: Read address port (domain: s_axi_aclk)
+ .s_axi_araddr(M_AXI_XBAR_ARADDR),
+ .s_axi_arvalid(M_AXI_XBAR_ARVALID),
+ .s_axi_arready(M_AXI_XBAR_ARREADY),
+ // AXI4-Lite: Read data port (domain: s_axi_aclk)
+ .s_axi_rdata(M_AXI_XBAR_RDATA),
+ .s_axi_rresp(M_AXI_XBAR_RRESP),
+ .s_axi_rvalid(M_AXI_XBAR_RVALID),
+ .s_axi_rready(M_AXI_XBAR_RREADY),
+ // ps gpio source
+ .ps_gpio_tri(ps_gpio_tri[FP_GPIO_WIDTH+FP_GPIO_OFFSET-1:FP_GPIO_OFFSET]),
+ .ps_gpio_out(ps_gpio_out[FP_GPIO_WIDTH+FP_GPIO_OFFSET-1:FP_GPIO_OFFSET]),
+ .ps_gpio_in(ps_gpio_in[FP_GPIO_WIDTH+FP_GPIO_OFFSET-1:FP_GPIO_OFFSET]),
+ // FP_GPIO
+ .fp_gpio_inout(FPGA_GPIO),
+ // Radio ATR
+ .rx_atr(rx_atr),
+ .tx_atr(tx_atr),
+ // Radio GPIO DSA
+ .db_gpio_out_flat(db_gpio_out),
+ .db_gpio_in_flat(db_gpio_in),
+ .db_gpio_ddr_flat(db_gpio_ddr),
+ .db_gpio_fab_flat(db_gpio_fab),
+ // Radio Strobes
+ .rx_stb(rx_stb),
+ .tx_stb(tx_stb),
+ // Radio Data
+ .rx(rx_flat),
+ .tx(tx_flat),
+ // CPLD RX_LO TX_LO SPI
+ `ifndef N300
+ .sclk_flat({DBB_CPLD_PL_SPI_SCLK,
+ DBA_CPLD_PL_SPI_SCLK}),
+ .sen_flat({5'b0,DBB_CPLD_PL_SPI_ADDR[1],DBB_CPLD_PL_SPI_ADDR[0],DBB_CPLD_PL_SPI_LE,
+ 5'b0,DBA_CPLD_PL_SPI_ADDR[1],DBA_CPLD_PL_SPI_ADDR[0],DBA_CPLD_PL_SPI_LE}),
+ .mosi_flat({DBB_CPLD_PL_SPI_SDI,
+ DBA_CPLD_PL_SPI_SDI}),
+ .miso_flat({DBB_CPLD_PL_SPI_SDO,
+ DBA_CPLD_PL_SPI_SDO}),
+ `else
+ .sclk_flat(DBA_CPLD_PL_SPI_SCLK),
+ .sen_flat({5'b0,DBA_CPLD_PL_SPI_ADDR[1],DBA_CPLD_PL_SPI_ADDR[0],DBA_CPLD_PL_SPI_LE}),
+ .mosi_flat(DBA_CPLD_PL_SPI_SDI),
+ .miso_flat(DBA_CPLD_PL_SPI_SDO),
+ `endif
+ // DRAM signals
+ .ddr3_axi_clk (ddr3_axi_clk),
+ .ddr3_axi_rst (ddr3_axi_rst),
+ .ddr3_running (ddr3_running),
+ // Slave Interface Write Address Ports
+ .ddr3_axi_awid (ddr3_axi_awid),
+ .ddr3_axi_awaddr (ddr3_axi_awaddr),
+ .ddr3_axi_awlen (ddr3_axi_awlen),
+ .ddr3_axi_awsize (ddr3_axi_awsize),
+ .ddr3_axi_awburst (ddr3_axi_awburst),
+ .ddr3_axi_awlock (ddr3_axi_awlock),
+ .ddr3_axi_awcache (ddr3_axi_awcache),
+ .ddr3_axi_awprot (ddr3_axi_awprot),
+ .ddr3_axi_awqos (ddr3_axi_awqos),
+ .ddr3_axi_awvalid (ddr3_axi_awvalid),
+ .ddr3_axi_awready (ddr3_axi_awready),
+ // Slave Interface Write Data Ports
+ .ddr3_axi_wdata (ddr3_axi_wdata),
+ .ddr3_axi_wstrb (ddr3_axi_wstrb),
+ .ddr3_axi_wlast (ddr3_axi_wlast),
+ .ddr3_axi_wvalid (ddr3_axi_wvalid),
+ .ddr3_axi_wready (ddr3_axi_wready),
+ // Slave Interface Write Response Ports
+ .ddr3_axi_bid (ddr3_axi_bid),
+ .ddr3_axi_bresp (ddr3_axi_bresp),
+ .ddr3_axi_bvalid (ddr3_axi_bvalid),
+ .ddr3_axi_bready (ddr3_axi_bready),
+ // Slave Interface Read Address Ports
+ .ddr3_axi_arid (ddr3_axi_arid),
+ .ddr3_axi_araddr (ddr3_axi_araddr),
+ .ddr3_axi_arlen (ddr3_axi_arlen),
+ .ddr3_axi_arsize (ddr3_axi_arsize),
+ .ddr3_axi_arburst (ddr3_axi_arburst),
+ .ddr3_axi_arlock (ddr3_axi_arlock),
+ .ddr3_axi_arcache (ddr3_axi_arcache),
+ .ddr3_axi_arprot (ddr3_axi_arprot),
+ .ddr3_axi_arqos (ddr3_axi_arqos),
+ .ddr3_axi_arvalid (ddr3_axi_arvalid),
+ .ddr3_axi_arready (ddr3_axi_arready),
+ // Slave Interface Read Data Ports
+ .ddr3_axi_rid (ddr3_axi_rid),
+ .ddr3_axi_rdata (ddr3_axi_rdata),
+ .ddr3_axi_rresp (ddr3_axi_rresp),
+ .ddr3_axi_rlast (ddr3_axi_rlast),
+ .ddr3_axi_rvalid (ddr3_axi_rvalid),
+ .ddr3_axi_rready (ddr3_axi_rready),
+
+ // DMA to PS
+ .m_dma_tdata(s_axis_dma_tdata),
+ .m_dma_tdest(s_axis_dma_tdest),
+ .m_dma_tlast(s_axis_dma_tlast),
+ .m_dma_tready(s_axis_dma_tready),
+ .m_dma_tvalid(s_axis_dma_tvalid),
+
+ .s_dma_tdata(m_axis_dma_tdata),
+ .s_dma_tuser(m_axis_dma_tuser),
+ .s_dma_tlast(m_axis_dma_tlast),
+ .s_dma_tready(m_axis_dma_tready),
+ .s_dma_tvalid(m_axis_dma_tvalid),
+
+ // VITA to Ethernet
+ .v2e0_tdata(v2e0_tdata),
+ .v2e0_tvalid(v2e0_tvalid),
+ .v2e0_tlast(v2e0_tlast),
+ .v2e0_tready(v2e0_tready),
+
+ .v2e1_tdata(v2e1_tdata),
+ .v2e1_tlast(v2e1_tlast),
+ .v2e1_tvalid(v2e1_tvalid),
+ .v2e1_tready(v2e1_tready),
+
+ // Ethernet to VITA
+ .e2v0_tdata(e2v0_tdata),
+ .e2v0_tlast(e2v0_tlast),
+ .e2v0_tvalid(e2v0_tvalid),
+ .e2v0_tready(e2v0_tready),
+
+ .e2v1_tdata(e2v1_tdata),
+ .e2v1_tlast(e2v1_tlast),
+ .e2v1_tvalid(e2v1_tvalid),
+ .e2v1_tready(e2v1_tready),
+
+ //regport interface to npio
+ .reg_wr_req_npio(reg_wr_req_npio),
+ .reg_wr_addr_npio(reg_wr_addr_npio),
+ .reg_wr_data_npio(reg_wr_data_npio),
+ .reg_rd_req_npio(reg_rd_req_npio),
+ .reg_rd_addr_npio(reg_rd_addr_npio),
+ .reg_rd_resp_npio(reg_rd_resp_npio),
+ .reg_rd_data_npio(reg_rd_data_npio),
+
+ .build_datestamp(build_datestamp),
+ .xadc_readback({20'h0, device_temp}),
+ .sfp_ports_info({sfp_port1_info, sfp_port0_info}),
+ .device_id(device_id)
+ );
+
+ // Register the ATR bits once between sending them out to the CPLD to avoid
+ // glitches on the outputs!
+ always @(posedge radio_clk) begin
+ rx_atr_reg <= rx_atr;
+ tx_atr_reg <= tx_atr;
+ end
+
+ // //////////////////////////////////////////////////////////////////////
+ //
+ // Daughterboard Cores
+ //
+ // //////////////////////////////////////////////////////////////////////
+
+ wire [49:0] bRegPortInFlatA;
+ wire [33:0] bRegPortOutFlatA;
+ wire rx_a_valid;
+ wire tx_a_rfi;
+`ifndef N300
+ wire [49:0] bRegPortInFlatB;
+ wire [33:0] bRegPortOutFlatB;
+ wire rx_b_valid;
+ wire tx_b_rfi;
+`endif
+
+`ifdef BUILD_WR
+ localparam INCL_WR_TDC = 1'b1;
+`else
+ localparam INCL_WR_TDC = 1'b0;
+`endif
+
+ wire reg_portA_rd;
+ wire reg_portA_wr;
+ wire [14-1:0] reg_portA_addr;
+ wire [32-1:0] reg_portA_wr_data;
+ wire [32-1:0] reg_portA_rd_data;
+ wire reg_portA_ready;
+ wire validA_unused;
+
+ assign bRegPortInFlatA = {2'b0, reg_portA_addr, reg_portA_wr_data, reg_portA_rd, reg_portA_wr};
+ assign {reg_portA_rd_data, validA_unused, reg_portA_ready} = bRegPortOutFlatA;
+
+ DbCore #(
+ .kInclWhiteRabbitTdc(INCL_WR_TDC)
+ ) dba_core (
+ .bBusReset(clk40_rst), //in std_logic
+ .BusClk(clk40), //in std_logic
+ .Clk40(clk40), //in std_logic
+ .MeasClk(meas_clk), //in std_logic
+ .FpgaClk_p(DBA_FPGA_CLK_P), //in std_logic
+ .FpgaClk_n(DBA_FPGA_CLK_N), //in std_logic
+ .SampleClk1xOut(radio_clk), //out std_logic
+ .SampleClk1x(radio_clk), //in std_logic
+ .SampleClk2xOut(radio_clk_2x), //out std_logic
+ .SampleClk2x(radio_clk_2x), //in std_logic
+ .bRegPortInFlat(bRegPortInFlatA), //in std_logic_vector(49:0)
+ .bRegPortOutFlat(bRegPortOutFlatA), //out std_logic_vector(33:0)
+ .kSlotId(1'b0), //in std_logic
+ .sSysRefFpgaLvds_p(DBA_FPGA_SYSREF_P), //in std_logic
+ .sSysRefFpgaLvds_n(DBA_FPGA_SYSREF_N), //in std_logic
+ .aLmkSync(DBA_CPLD_PL_SPI_ADDR[2]), //out std_logic
+ .JesdRefClk_p(USRPIO_A_MGTCLK_P), //in std_logic
+ .JesdRefClk_n(USRPIO_A_MGTCLK_N), //in std_logic
+ .aAdcRx_p(USRPIO_A_RX_P), //in std_logic_vector(3:0)
+ .aAdcRx_n(USRPIO_A_RX_N), //in std_logic_vector(3:0)
+ .aSyncAdcOut_n(DBA_MYK_SYNC_IN_n), //out std_logic
+ .aDacTx_p(USRPIO_A_TX_P), //out std_logic_vector(3:0)
+ .aDacTx_n(USRPIO_A_TX_N), //out std_logic_vector(3:0)
+ .aSyncDacIn_n(DBA_MYK_SYNC_OUT_n), //in std_logic
+ .sAdcDataValid(rx_a_valid), //out std_logic
+ .sAdcDataSamples0I(rx[0][31:16]), //out std_logic_vector(15:0)
+ .sAdcDataSamples0Q(rx[0][15:0]), //out std_logic_vector(15:0)
+ .sAdcDataSamples1I(rx[1][31:16]), //out std_logic_vector(15:0)
+ .sAdcDataSamples1Q(rx[1][15:0]), //out std_logic_vector(15:0)
+ .sDacReadyForInput(tx_a_rfi), //out std_logic
+ .sDacDataSamples0I(tx[0][31:16]), //in std_logic_vector(15:0)
+ .sDacDataSamples0Q(tx[0][15:0]), //in std_logic_vector(15:0)
+ .sDacDataSamples1I(tx[1][31:16]), //in std_logic_vector(15:0)
+ .sDacDataSamples1Q(tx[1][15:0]), //in std_logic_vector(15:0)
+ .RefClk(ref_clk), //in std_logic
+ .rPpsPulse(pps_refclk), //in std_logic
+ .rGatedPulseToPin(UNUSED_PIN_TDCA_0), //inout std_logic
+ .sGatedPulseToPin(UNUSED_PIN_TDCA_1), //inout std_logic
+ .sPps(pps_radioclk1x), //out std_logic
+ .sPpsToIob(pps_radioclk1x_iob), //out std_logic
+ .WrRefClk(wr_ref_clk), //in std_logic
+ .rWrPpsPulse(pps_wr_refclk), //in std_logic
+ .rWrGatedPulseToPin(UNUSED_PIN_TDCA_2), //inout std_logic
+ .sWrGatedPulseToPin(UNUSED_PIN_TDCA_3), //inout std_logic
+ .aPpsSfpSel(pps_select_sfp), //out std_logic_vector(1:0)
+ .sAdcSync(), //out std_logic
+ .sDacSync(), //out std_logic
+ .sSysRef(), //out std_logic
+ .rRpTransfer(), //out std_logic
+ .sSpTransfer(), //out std_logic
+ .rWrRpTransfer(), //out std_logic
+ .sWrSpTransfer() //out std_logic
+ );
+
+ assign rx_stb[0] = rx_a_valid;
+ assign rx_stb[1] = rx_a_valid;
+ assign tx_stb[0] = tx_a_rfi;
+ assign tx_stb[1] = tx_a_rfi;
+
+ axil_to_ni_regport #(
+ .RP_DWIDTH (32),
+ .RP_AWIDTH (14),
+ .TIMEOUT (512)
+ ) ni_regportA_inst (
+ // Clock and reset
+ .s_axi_aclk (clk40),
+ .s_axi_areset (clk40_rst),
+ // AXI4-Lite: Write address port (domain: s_axi_aclk)
+ .s_axi_awaddr(M_AXI_JESD0_AWADDR),
+ .s_axi_awvalid(M_AXI_JESD0_AWVALID),
+ .s_axi_awready(M_AXI_JESD0_AWREADY),
+ // AXI4-Lite: Write data port (domain: s_axi_aclk)
+ .s_axi_wdata(M_AXI_JESD0_WDATA),
+ .s_axi_wstrb(M_AXI_JESD0_WSTRB),
+ .s_axi_wvalid(M_AXI_JESD0_WVALID),
+ .s_axi_wready(M_AXI_JESD0_WREADY),
+ // AXI4-Lite: Write response port (domain: s_axi_aclk)
+ .s_axi_bresp(M_AXI_JESD0_BRESP),
+ .s_axi_bvalid(M_AXI_JESD0_BVALID),
+ .s_axi_bready(M_AXI_JESD0_BREADY),
+ // AXI4-Lite: Read address port (domain: s_axi_aclk)
+ .s_axi_araddr(M_AXI_JESD0_ARADDR),
+ .s_axi_arvalid(M_AXI_JESD0_ARVALID),
+ .s_axi_arready(M_AXI_JESD0_ARREADY),
+ // AXI4-Lite: Read data port (domain: s_axi_aclk)
+ .s_axi_rdata(M_AXI_JESD0_RDATA),
+ .s_axi_rresp(M_AXI_JESD0_RRESP),
+ .s_axi_rvalid(M_AXI_JESD0_RVALID),
+ .s_axi_rready(M_AXI_JESD0_RREADY),
+ // Register port
+ .reg_port_in_rd (reg_portA_rd),
+ .reg_port_in_wt (reg_portA_wr),
+ .reg_port_in_addr (reg_portA_addr),
+ .reg_port_in_data (reg_portA_wr_data),
+ .reg_port_out_data (reg_portA_rd_data),
+ .reg_port_out_ready(reg_portA_ready)
+ );
+
+`ifndef N300
+ wire reg_portB_rd;
+ wire reg_portB_wr;
+ wire [14-1:0] reg_portB_addr;
+ wire [32-1:0] reg_portB_wr_data;
+ wire [32-1:0] reg_portB_rd_data;
+ wire reg_portB_ready;
+ wire validB_unused;
+
+ assign bRegPortInFlatB = {2'b0, reg_portB_addr, reg_portB_wr_data, reg_portB_rd, reg_portB_wr};
+ assign {reg_portB_rd_data, validB_unused, reg_portB_ready} = bRegPortOutFlatB;
+
+ DbCore #(
+ .kInclWhiteRabbitTdc(INCL_WR_TDC)
+ ) dbb_core (
+ .bBusReset(clk40_rst), //in std_logic
+ .BusClk(clk40), //in std_logic
+ .Clk40(clk40), //in std_logic
+ .MeasClk(meas_clk), //in std_logic
+ .FpgaClk_p(DBB_FPGA_CLK_P), //in std_logic
+ .FpgaClk_n(DBB_FPGA_CLK_N), //in std_logic
+ .SampleClk1xOut(), //out std_logic
+ .SampleClk1x(radio_clk), //in std_logic
+ .SampleClk2xOut(), //out std_logic
+ .SampleClk2x(radio_clk_2x), //in std_logic
+ .bRegPortInFlat(bRegPortInFlatB), //in std_logic_vector(49:0)
+ .bRegPortOutFlat(bRegPortOutFlatB), //out std_logic_vector(33:0)
+ .kSlotId(1'b1), //in std_logic
+ .sSysRefFpgaLvds_p(DBB_FPGA_SYSREF_P), //in std_logic
+ .sSysRefFpgaLvds_n(DBB_FPGA_SYSREF_N), //in std_logic
+ .aLmkSync(DBB_CPLD_PL_SPI_ADDR[2]), //out std_logic
+ .JesdRefClk_p(USRPIO_B_MGTCLK_P), //in std_logic
+ .JesdRefClk_n(USRPIO_B_MGTCLK_N), //in std_logic
+ .aAdcRx_p(USRPIO_B_RX_P), //in std_logic_vector(3:0)
+ .aAdcRx_n(USRPIO_B_RX_N), //in std_logic_vector(3:0)
+ .aSyncAdcOut_n(DBB_MYK_SYNC_IN_n), //out std_logic
+ .aDacTx_p(USRPIO_B_TX_P), //out std_logic_vector(3:0)
+ .aDacTx_n(USRPIO_B_TX_N), //out std_logic_vector(3:0)
+ .aSyncDacIn_n(DBB_MYK_SYNC_OUT_n), //in std_logic
+ .sAdcDataValid(rx_b_valid), //out std_logic
+ .sAdcDataSamples0I(rx[2][31:16]), //out std_logic_vector(15:0)
+ .sAdcDataSamples0Q(rx[2][15:0]), //out std_logic_vector(15:0)
+ .sAdcDataSamples1I(rx[3][31:16]), //out std_logic_vector(15:0)
+ .sAdcDataSamples1Q(rx[3][15:0]), //out std_logic_vector(15:0)
+ .sDacReadyForInput(tx_b_rfi), //out std_logic
+ .sDacDataSamples0I(tx[2][31:16]), //in std_logic_vector(15:0)
+ .sDacDataSamples0Q(tx[2][15:0]), //in std_logic_vector(15:0)
+ .sDacDataSamples1I(tx[3][31:16]), //in std_logic_vector(15:0)
+ .sDacDataSamples1Q(tx[3][15:0]), //in std_logic_vector(15:0)
+ .RefClk(ref_clk), //in std_logic
+ .rPpsPulse(pps_refclk), //in std_logic
+ .rGatedPulseToPin(UNUSED_PIN_TDCB_0), //inout std_logic
+ .sGatedPulseToPin(UNUSED_PIN_TDCB_1), //inout std_logic
+ .sPps(), //out std_logic
+ .sPpsToIob(), //out std_logic
+ .WrRefClk(wr_ref_clk), //in std_logic
+ .rWrPpsPulse(pps_wr_refclk), //in std_logic
+ .rWrGatedPulseToPin(UNUSED_PIN_TDCB_2), //inout std_logic
+ .sWrGatedPulseToPin(UNUSED_PIN_TDCB_3), //inout std_logic
+ .aPpsSfpSel(2'b0), //out std_logic_vector(1:0)
+ .sAdcSync(), //out std_logic
+ .sDacSync(), //out std_logic
+ .sSysRef(), //out std_logic
+ .rRpTransfer(), //out std_logic
+ .sSpTransfer(), //out std_logic
+ .rWrRpTransfer(), //out std_logic
+ .sWrSpTransfer() //out std_logic
+ );
+
+ assign rx_stb[2] = rx_b_valid;
+ assign rx_stb[3] = rx_b_valid;
+ assign tx_stb[2] = tx_b_rfi;
+ assign tx_stb[3] = tx_b_rfi;
+
+ axil_to_ni_regport #(
+ .RP_DWIDTH (32),
+ .RP_AWIDTH (14),
+ .TIMEOUT (512)
+ ) ni_regportB_inst (
+ // Clock and reset
+ .s_axi_aclk (clk40),
+ .s_axi_areset (clk40_rst),
+ // AXI4-Lite: Write address port (domain: s_axi_aclk)
+ .s_axi_awaddr(M_AXI_JESD1_AWADDR),
+ .s_axi_awvalid(M_AXI_JESD1_AWVALID),
+ .s_axi_awready(M_AXI_JESD1_AWREADY),
+ // AXI4-Lite: Write data port (domain: s_axi_aclk)
+ .s_axi_wdata(M_AXI_JESD1_WDATA),
+ .s_axi_wstrb(M_AXI_JESD1_WSTRB),
+ .s_axi_wvalid(M_AXI_JESD1_WVALID),
+ .s_axi_wready(M_AXI_JESD1_WREADY),
+ // AXI4-Lite: Write response port (domain: s_axi_aclk)
+ .s_axi_bresp(M_AXI_JESD1_BRESP),
+ .s_axi_bvalid(M_AXI_JESD1_BVALID),
+ .s_axi_bready(M_AXI_JESD1_BREADY),
+ // AXI4-Lite: Read address port (domain: s_axi_aclk)
+ .s_axi_araddr(M_AXI_JESD1_ARADDR),
+ .s_axi_arvalid(M_AXI_JESD1_ARVALID),
+ .s_axi_arready(M_AXI_JESD1_ARREADY),
+ // AXI4-Lite: Read data port (domain: s_axi_aclk)
+ .s_axi_rdata (M_AXI_JESD1_RDATA),
+ .s_axi_rresp (M_AXI_JESD1_RRESP),
+ .s_axi_rvalid (M_AXI_JESD1_RVALID),
+ .s_axi_rready (M_AXI_JESD1_RREADY),
+ // Register port
+ .reg_port_in_rd (reg_portB_rd),
+ .reg_port_in_wt (reg_portB_wr),
+ .reg_port_in_addr (reg_portB_addr),
+ .reg_port_in_data (reg_portB_wr_data),
+ .reg_port_out_data (reg_portB_rd_data),
+ .reg_port_out_ready(reg_portB_ready)
+ );
+`else
+ // Tie off second daughterboard interface
+ axi_dummy #(
+ .DEC_ERR(1'b0)
+ ) inst_axi_dummy_dbb_core (
+ // Clock and reset
+ .s_axi_aclk (clk40),
+ .s_axi_areset (clk40_rst),
+ // AXI4-Lite: Write address port (domain: s_axi_aclk)
+ .s_axi_awaddr(M_AXI_JESD1_AWADDR),
+ .s_axi_awvalid(M_AXI_JESD1_AWVALID),
+ .s_axi_awready(M_AXI_JESD1_AWREADY),
+ // AXI4-Lite: Write data port (domain: s_axi_aclk)
+ .s_axi_wdata(M_AXI_JESD1_WDATA),
+ .s_axi_wstrb(M_AXI_JESD1_WSTRB),
+ .s_axi_wvalid(M_AXI_JESD1_WVALID),
+ .s_axi_wready(M_AXI_JESD1_WREADY),
+ // AXI4-Lite: Write response port (domain: s_axi_aclk)
+ .s_axi_bresp(M_AXI_JESD1_BRESP),
+ .s_axi_bvalid(M_AXI_JESD1_BVALID),
+ .s_axi_bready(M_AXI_JESD1_BREADY),
+ // AXI4-Lite: Read address port (domain: s_axi_aclk)
+ .s_axi_araddr(M_AXI_JESD1_ARADDR),
+ .s_axi_arvalid(M_AXI_JESD1_ARVALID),
+ .s_axi_arready(M_AXI_JESD1_ARREADY),
+ // AXI4-Lite: Read data port (domain: s_axi_aclk)
+ .s_axi_rdata (M_AXI_JESD1_RDATA),
+ .s_axi_rresp (M_AXI_JESD1_RRESP),
+ .s_axi_rvalid (M_AXI_JESD1_RVALID),
+ .s_axi_rready (M_AXI_JESD1_RREADY)
+ );
+
+`endif
+
+ // //////////////////////////////////////////////////////////////////////
+ //
+ // LEDS
+ //
+ // //////////////////////////////////////////////////////////////////////
+
+ assign PANEL_LED_LINK = ps_gpio_out[45];
+ assign PANEL_LED_REF = ps_gpio_out[46];
+ assign PANEL_LED_GPS = ps_gpio_out[47];
+
+
+ /////////////////////////////////////////////////////////////////////
+ //
+ // PUDC Workaround
+ //
+ //////////////////////////////////////////////////////////////////////
+ // This is a workaround for a silicon bug in Series 7 FPGA where a
+ // race condition with the reading of PUDC during the erase of the FPGA
+ // image cause glitches on output IO pins.
+ //
+ // Workaround:
+ // - Define the PUDC pin in the XDC file with a pullup.
+ // - Implements an IBUF on the PUDC input and make sure that it does
+ // not get optimized out.
+ (* dont_touch = "true" *) wire fpga_pudc_b_buf;
+ IBUF pudc_ibuf_i (
+ .I(FPGA_PUDC_B),
+ .O(fpga_pudc_b_buf));
+
+endmodule