------------------------------------------------------------------------------- -- -- File: ClockingRegs.vhd -- Author: Daniel Jepson; mods by Humberto Jimenez -- Original Project: N310; N32x -- 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 -- -- -- -- -- -- -- -- -- Reflects the locked status of the MMCM. '1' = locked. This bit is only valid -- when the MMCM reset is de-asserted. Read-only. -- -- -- -- -- 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. -- -- -- -- -- Controls the reset to the Radio Clock MMCM. Strobe this bit to assert the -- reset to the MMCM. Default is reset asserted. Write-only. -- -- -- -- -- -- -- Phase Shift for RadioClkMmcm. -- -- -- -- This bit should set after a shift operation successfully completes. -- Reading this register will clear this bit. Read-only. -- -- -- -- -- 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. -- -- -- -- -- 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. -- -- -- -- -- Read-only. -- -- -- -- -- -- -- -- -- -- Set to '1' to enable the clock. Default disabled = '0'. -- Do so ONLY after the MMCM is out of reset and locked! -- -- -- -- -- Set to '1' to enable the clock. Default disabled = '0'. -- Do so ONLY after the MMCM is out of reset and locked! -- -- -- -- -- Set to '1' to enable the clock. Default disabled = '0'. -- Do so ONLY after the MMCM is out of reset and locked! -- -- -- -- -- -- -- -- -- -- 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! -- -- -- -- -- -- -- --XmlParse xml_off