aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/top/n3xx/dboards/mg/db_ifc
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/top/n3xx/dboards/mg/db_ifc')
-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
10 files changed, 1841 insertions, 0 deletions
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;