1------------------------------------------------------------------------------- 2-- 3-- File: DbCore.vhd 4-- Author: Daniel Jepson; mods by Humberto Jimenez 5-- Original Project: N310; N320 6-- Date: 12 April 2017 7-- 8------------------------------------------------------------------------------- 9-- Copyright 2017-2018 Ettus Research, A National Instruments Company 10-- SPDX-License-Identifier: LGPL-3.0 11------------------------------------------------------------------------------- 12-- 13-- Purpose: 14-- 15-- Wrapper file for Daughterboard Control. This includes the semi-static control 16-- and status registers, clocking, synchronization, and JESD204B cores. 17-- 18-- There is no version register for the plain-text files here. 19-- Version control for the Sync and JESD204B cores is internal to the netlists. 20-- 21-- The resets for this core are almost entirely local and/or synchronous. 22-- bBusReset is a Synchronous reset on the BusClk domain that resets all of the 23-- registers connected to the RegPort, as well as any other stray registers 24-- connected to the BusClk. All other resets are local to the modules they touch. 25-- No other reset drives all modules universally. 26-- 27------------------------------------------------------------------------------- 28 29library ieee; 30 use ieee.std_logic_1164.all; 31 use ieee.numeric_std.all; 32 33library work; 34 use work.PkgRhPersonality.all; 35 use work.PkgRegs.all; 36 use work.PkgJesdConfig.all; 37 use work.PkgAdcDacInterfaceTypes.all; 38 39 40entity DbCore is 41 generic( 42 -- Set to '1' to include the White Rabbit TDC. 43 kInclWhiteRabbitTdc : std_logic := '0' 44 ); 45 port( 46 47 -- Resets -- 48 -- Synchronous Reset for the BusClk domain (mainly for the RegPort) 49 bBusReset : in std_logic; 50 51 -- Clocks -- 52 -- Register Bus Clock (any frequency) 53 BusClk : in std_logic; 54 -- Always-on at 40 MHz 55 Clk40 : in std_logic; 56 -- Super secret crazy awesome measurement clock at weird frequencies. 57 MeasClk : in std_logic; 58 -- FPGA Sample Clock from DB LMK 59 FpgaClk_p : in std_logic; 60 FpgaClk_n : in std_logic; 61 62 -- Sample Clock Sharing. The clocks generated in this module are exported out to the 63 -- top level so they can be shared amongst daughterboards. Therefore they must be 64 -- driven back into the SampleClk*x inputs at a higher level in order for this module 65 -- to work correctly. There are a few isolated cases where SampleClk*xOut is used 66 -- directly in this module, and those are documented below. 67 SampleClk1xOut : out std_logic; 68 SampleClk1x : in std_logic; 69 SampleClk2xOut : out std_logic; 70 SampleClk2x : in std_logic; 71 72 73 -- Register Ports -- 74 -- 75 -- Only synchronous resets can be used for these ports! 76 bRegPortInFlat : in std_logic_vector(49 downto 0); 77 bRegPortOutFlat : out std_logic_vector(33 downto 0); 78 79 -- Slot ID value. This should be tied to a constant! 80 kSlotId : in std_logic; 81 82 83 -- SYSREF -- 84 -- 85 -- SYSREF direct from the LMK 86 sSysRefFpgaLvds_p, 87 sSysRefFpgaLvds_n : in std_logic; 88 -- SYNC directly to the LMK 89 aLmkSync : out std_logic; 90 91 92 -- JESD Signals -- 93 -- 94 -- GTX Sample Clock Reference Input. Direct connect to FPGA pins. 95 JesdRefClk_p, 96 JesdRefClk_n : in std_logic; 97 98 -- ADC JESD PHY Interface. Direct connect to FPGA pins. 99 aAdcRx_p, 100 aAdcRx_n : in std_logic_vector(3 downto 0); 101 aSyncAdcOut_n : out std_logic; 102 103 -- DAC JESD PHY Interface. Direct connect to FPGA pins. 104 aDacTx_p, 105 aDacTx_n : out std_logic_vector(3 downto 0); 106 aSyncDacIn_n : in std_logic; 107 108 109 -- Data Pipes to/from the DACs/ADCs -- 110 -- 111 -- - Data is presented as two samples per cycle. 112 -- - sAdcDataValid asserts when ADC data is valid. 113 -- - sDacReadyForInput asserts when DAC data is ready to be received. 114 -- 115 -- Reset Crossings: 116 -- The ADC data and valid outputs are synchronously cleared before the asynchronous 117 -- reset is asserted--preventing any reset crossing issues here between the RX 118 -- (internal to the core) reset and the no-reset domain of RFNoC. 119 -- 120 -- The DAC samples should be zeros on reset de-assertion due to RFI being de-asserted 121 -- in reset. If they are not zeros, then it is still OK because data is ignored until 122 -- RFI is asserted. DAC RFI is double-synchronized to protect against the reset 123 -- crossing. This is safe to do because it simply delays the output of RFI by two 124 -- cycles on the assertion edge, and as long as reset is held for more than two 125 -- cycles, the de-assertion edge of RFI should come long before the TX module is 126 -- taken out of reset. 127 128 -- Supporting 2 samples per clk cycle. 129 sAdcDataValid : out std_logic; 130 sAdcDataSample0I : out std_logic_vector(15 downto 0); 131 sAdcDataSample0Q : out std_logic_vector(15 downto 0); 132 sAdcDataSample1I : out std_logic_vector(15 downto 0); 133 sAdcDataSample1Q : out std_logic_vector(15 downto 0); 134 -- 135 sDacReadyForInput : out std_logic; 136 sDacDataSample0I : in std_logic_vector(15 downto 0); 137 sDacDataSample0Q : in std_logic_vector(15 downto 0); 138 sDacDataSample1I : in std_logic_vector(15 downto 0); 139 sDacDataSample1Q : in std_logic_vector(15 downto 0); 140 141 142 -- RefClk & Timing & Sync -- 143 RefClk : in std_logic; 144 rPpsPulse : in std_logic; 145 rGatedPulseToPin : inout std_logic; -- straight to pin 146 sGatedPulseToPin : inout std_logic; -- straight to pin 147 sPps : out std_logic; 148 sPpsToIob : out std_logic; 149 150 -- White Rabbit Timing & Sync -- 151 WrRefClk : in std_logic; 152 rWrPpsPulse : in std_logic; 153 rWrGatedPulseToPin : inout std_logic; -- straight to pin 154 sWrGatedPulseToPin : inout std_logic; -- straight to pin 155 aPpsSfpSel : in std_logic_vector(1 downto 0); 156 157 -- Debug for JESD 158 sAdcSync : out std_logic; 159 sDacSync : out std_logic; 160 sSysRef : out std_logic; 161 162 -- Debug for Timing & Sync 163 rRpTransfer : out std_logic; 164 sSpTransfer : out std_logic; 165 rWrRpTransfer : out std_logic; 166 sWrSpTransfer : out std_logic 167 ); 168 169end DbCore; 170 171 172architecture RTL of DbCore is 173 174 component Jesd204bXcvrCore 175 port ( 176 bBusReset : in STD_LOGIC; 177 BusClk : in STD_LOGIC; 178 ReliableClk40 : in STD_LOGIC; 179 FpgaClk1x : in STD_LOGIC; 180 FpgaClk2x : in STD_LOGIC; 181 bFpgaClksStable : in STD_LOGIC; 182 JesdRefClk_p : in STD_LOGIC; 183 JesdRefClk_n : in STD_LOGIC; 184 bJesdRefClkPresent : out STD_LOGIC; 185 aLmkSync : out STD_LOGIC; 186 bRegPortInFlat : in STD_LOGIC_VECTOR(49 downto 0); 187 bRegPortOutFlat : out STD_LOGIC_VECTOR(33 downto 0); 188 CaptureSysRefClk : in STD_LOGIC; 189 cSysRefFpgaLvds_p : in STD_LOGIC; 190 cSysRefFpgaLvds_n : in STD_LOGIC; 191 fSysRef : out STD_LOGIC; 192 aAdcRx_p : in STD_LOGIC_VECTOR(3 downto 0); 193 aAdcRx_n : in STD_LOGIC_VECTOR(3 downto 0); 194 aSyncAdcOut_n : out STD_LOGIC; 195 aDacTx_p : out STD_LOGIC_VECTOR(3 downto 0); 196 aDacTx_n : out STD_LOGIC_VECTOR(3 downto 0); 197 aSyncDacIn_n : in STD_LOGIC; 198 fAdcDataFlatter : out STD_LOGIC_VECTOR(63 downto 0); 199 fDacDataFlatter : in STD_LOGIC_VECTOR(63 downto 0); 200 fAdcDataValid : out STD_LOGIC; 201 fDacReadyForInput : out STD_LOGIC; 202 aDacSync : out STD_LOGIC; 203 aAdcSync : out STD_LOGIC); 204 end component; 205 206 function to_Boolean (s : std_ulogic) return boolean is 207 begin 208 return (To_X01(s)='1'); 209 end to_Boolean; 210 211 function to_StdLogic(b : boolean) return std_ulogic is 212 begin 213 if b then 214 return '1'; 215 else 216 return '0'; 217 end if; 218 end to_StdLogic; 219 220 --vhook_sigstart 221 signal aAdcSync: STD_LOGIC; 222 signal aDacSync: STD_LOGIC; 223 signal bClockingRegPortOut: RegPortOut_t; 224 signal bDbRegPortOut: RegPortOut_t; 225 signal bFpgaClksStable: STD_LOGIC; 226 signal bJesdCoreRegPortInFlat: STD_LOGIC_VECTOR(49 downto 0); 227 signal bJesdCoreRegPortOutFlat: STD_LOGIC_VECTOR(33 downto 0); 228 signal bJesdRefClkPresent: STD_LOGIC; 229 signal bRadioClk1xEnabled: std_logic; 230 signal bRadioClk2xEnabled: std_logic; 231 signal bRadioClk3xEnabled: std_logic; 232 signal bRadioClkMmcmReset: std_logic; 233 signal bRadioClksValid: std_logic; 234 signal pPsDone: std_logic; 235 signal pPsEn: std_logic; 236 signal pPsInc: std_logic; 237 signal PsClk: std_logic; 238 signal sAdcDataFlatter: STD_LOGIC_VECTOR(63 downto 0); 239 signal SampleClk1xOutLcl: std_logic; 240 signal sDacDataFlatter: STD_LOGIC_VECTOR(63 downto 0); 241 signal sDacReadyForInputAsyncReset: STD_LOGIC; 242 signal sRegPps: std_logic; 243 signal sSysRefAsyncReset: STD_LOGIC; 244 signal sWrPps: std_logic; 245 --vhook_sigend 246 247 signal bJesdRegPortInGrp, bSyncRegPortIn, bWrSyncRegPortIn, bRegPortIn : RegPortIn_t; 248 signal bJesdRegPortOut, bSyncRegPortOut, bWrSyncRegPortOut, bRegPortOut : RegPortOut_t; 249 250 signal sDacReadyForInput_ms, sDacReadyForInputLcl, 251 sDacSync_ms, sDacSyncLcl, 252 sAdcSync_ms, sAdcSyncLcl, 253 sSysRef_ms, sSysRefLcl : std_logic := '0'; 254 255 signal sAdcDataAry : AdcDataAry_t; 256 signal sDacDataAry : DacDataAry_t; 257 258 signal sPpsSfpSel_ms, sPpsSfpSel : std_logic_vector(1 downto 0) := (others => '0'); 259 signal sUseWrTdcPps : boolean := false; 260 signal sPpsInt, sPpsMuxed : std_logic := '0'; 261 262 attribute ASYNC_REG : string; 263 attribute ASYNC_REG of sDacReadyForInput_ms : signal is "true"; 264 attribute ASYNC_REG of sDacReadyForInputLcl : signal is "true"; 265 attribute ASYNC_REG of sDacSync_ms : signal is "true"; 266 attribute ASYNC_REG of sDacSyncLcl : signal is "true"; 267 attribute ASYNC_REG of sAdcSync_ms : signal is "true"; 268 attribute ASYNC_REG of sAdcSyncLcl : signal is "true"; 269 attribute ASYNC_REG of sSysRef_ms : signal is "true"; 270 attribute ASYNC_REG of sSysRefLcl : signal is "true"; 271 attribute ASYNC_REG of sPpsSfpSel_ms : signal is "true"; 272 attribute ASYNC_REG of sPpsSfpSel : signal is "true"; 273 274begin 275 276 bRegPortOutFlat <= Flatten(bRegPortOut); 277 bRegPortIn <= Unflatten(bRegPortInFlat); 278 279 280 -- Combine return RegPorts. 281 bRegPortOut <= bJesdRegPortOut 282 + bClockingRegPortOut 283 + bSyncRegPortOut + bWrSyncRegPortOut 284 + bDbRegPortOut; 285 286 287 -- Clocking : ------------------------------------------------------------------------- 288 -- Automatically export the Sample Clocks and only use the incoming clocks in the 289 -- remainder of the logic. For a single module, the clocks must be looped back 290 -- in at a higher level! 291 -- ------------------------------------------------------------------------------------ 292 293 --vhook_e RadioClocking 294 --vhook_a aReset false 295 --vhook_a bReset to_boolean(bBusReset) 296 --vhook_a RadioClk1x SampleClk1xOutLcl 297 --vhook_a RadioClk2x SampleClk2xOut 298 --vhook_a RadioClk3x open 299 RadioClockingx: entity work.RadioClocking (rtl) 300 port map ( 301 aReset => false, --in boolean 302 bReset => to_boolean(bBusReset), --in boolean 303 BusClk => BusClk, --in std_logic 304 bRadioClkMmcmReset => bRadioClkMmcmReset, --in std_logic 305 bRadioClksValid => bRadioClksValid, --out std_logic 306 bRadioClk1xEnabled => bRadioClk1xEnabled, --in std_logic 307 bRadioClk2xEnabled => bRadioClk2xEnabled, --in std_logic 308 bRadioClk3xEnabled => bRadioClk3xEnabled, --in std_logic 309 pPsInc => pPsInc, --in std_logic 310 pPsEn => pPsEn, --in std_logic 311 PsClk => PsClk, --in std_logic 312 pPsDone => pPsDone, --out std_logic 313 FpgaClk_n => FpgaClk_n, --in std_logic 314 FpgaClk_p => FpgaClk_p, --in std_logic 315 RadioClk1x => SampleClk1xOutLcl, --out std_logic 316 RadioClk2x => SampleClk2xOut, --out std_logic 317 RadioClk3x => open); --out std_logic 318 319 -- We need an internal copy of SampleClk1x for the TDC, since we don't want to try 320 -- and align the other DB's clock accidentally. 321 SampleClk1xOut <= SampleClk1xOutLcl; 322 323 --vhook_e ClockingRegs 324 --vhook_a aReset false 325 --vhook_a bReset to_boolean(bBusReset) 326 --vhook_a bRegPortOut bClockingRegPortOut 327 --vhook_a aRadioClksValid bRadioClksValid 328 ClockingRegsx: entity work.ClockingRegs (RTL) 329 port map ( 330 aReset => false, --in boolean 331 bReset => to_boolean(bBusReset), --in boolean 332 BusClk => BusClk, --in std_logic 333 bRegPortOut => bClockingRegPortOut, --out RegPortOut_t 334 bRegPortIn => bRegPortIn, --in RegPortIn_t 335 pPsInc => pPsInc, --out std_logic 336 pPsEn => pPsEn, --out std_logic 337 pPsDone => pPsDone, --in std_logic 338 PsClk => PsClk, --out std_logic 339 bRadioClkMmcmReset => bRadioClkMmcmReset, --out std_logic 340 aRadioClksValid => bRadioClksValid, --in std_logic 341 bRadioClk1xEnabled => bRadioClk1xEnabled, --out std_logic 342 bRadioClk2xEnabled => bRadioClk2xEnabled, --out std_logic 343 bRadioClk3xEnabled => bRadioClk3xEnabled, --out std_logic 344 bJesdRefClkPresent => bJesdRefClkPresent); --in std_logic 345 346 347 348 -- JESD204B : ------------------------------------------------------------------------- 349 -- ------------------------------------------------------------------------------------ 350 351 bJesdRegPortInGrp <= Mask(RegPortIn => bRegPortIn, 352 kRegisterOffset => kJesdRegGroupInDbRegs); -- 0x2000 to 0x3FFC 353 354 -- Expand/compress the RegPort for moving through the netlist boundary. 355 bJesdRegPortOut <= Unflatten(bJesdCoreRegPortOutFlat); 356 bJesdCoreRegPortInFlat <= Flatten(bJesdRegPortInGrp); 357 358 359 --vhook Jesd204bXcvrCore 360 --vhook_a bRegPortInFlat bJesdCoreRegPortInFlat 361 --vhook_a bRegPortOutFlat bJesdCoreRegPortOutFlat 362 --vhook_a FpgaClk1x SampleClk1x 363 --vhook_a FpgaClk2x SampleClk2x 364 --vhook_a ReliableClk40 Clk40 365 --vhook_a CaptureSysRefClk SampleClk1xOutLcl 366 --vhook_a cSysRefFpgaLvds_p sSysRefFpgaLvds_p 367 --vhook_a cSysRefFpgaLvds_n sSysRefFpgaLvds_n 368 --vhook_a fSysRef sSysRefAsyncReset 369 --vhook_a fDacReadyForInput sDacReadyForInputAsyncReset 370 --vhook_a {^f(.*)} s$1 371 Jesd204bXcvrCorex: Jesd204bXcvrCore 372 port map ( 373 bBusReset => bBusReset, --in STD_LOGIC 374 BusClk => BusClk, --in STD_LOGIC 375 ReliableClk40 => Clk40, --in STD_LOGIC 376 FpgaClk1x => SampleClk1x, --in STD_LOGIC 377 FpgaClk2x => SampleClk2x, --in STD_LOGIC 378 bFpgaClksStable => bFpgaClksStable, --in STD_LOGIC 379 JesdRefClk_p => JesdRefClk_p, --in STD_LOGIC 380 JesdRefClk_n => JesdRefClk_n, --in STD_LOGIC 381 bJesdRefClkPresent => bJesdRefClkPresent, --out STD_LOGIC 382 aLmkSync => aLmkSync, --out STD_LOGIC 383 bRegPortInFlat => bJesdCoreRegPortInFlat, --in STD_LOGIC_VECTOR(49:0) 384 bRegPortOutFlat => bJesdCoreRegPortOutFlat, --out STD_LOGIC_VECTOR(33:0) 385 CaptureSysRefClk => SampleClk1xOutLcl, --in STD_LOGIC 386 cSysRefFpgaLvds_p => sSysRefFpgaLvds_p, --in STD_LOGIC 387 cSysRefFpgaLvds_n => sSysRefFpgaLvds_n, --in STD_LOGIC 388 fSysRef => sSysRefAsyncReset, --out STD_LOGIC 389 aAdcRx_p => aAdcRx_p, --in STD_LOGIC_VECTOR(3:0) 390 aAdcRx_n => aAdcRx_n, --in STD_LOGIC_VECTOR(3:0) 391 aSyncAdcOut_n => aSyncAdcOut_n, --out STD_LOGIC 392 aDacTx_p => aDacTx_p, --out STD_LOGIC_VECTOR(3:0) 393 aDacTx_n => aDacTx_n, --out STD_LOGIC_VECTOR(3:0) 394 aSyncDacIn_n => aSyncDacIn_n, --in STD_LOGIC 395 fAdcDataFlatter => sAdcDataFlatter, --out STD_LOGIC_VECTOR(63:0) 396 fDacDataFlatter => sDacDataFlatter, --in STD_LOGIC_VECTOR(63:0) 397 fAdcDataValid => sAdcDataValid, --out STD_LOGIC 398 fDacReadyForInput => sDacReadyForInputAsyncReset, --out STD_LOGIC 399 aDacSync => aDacSync, --out STD_LOGIC 400 aAdcSync => aAdcSync); --out STD_LOGIC 401 402 403 JesdDoubleSyncToNoResetSampleClk : process (SampleClk1x) 404 begin 405 if rising_edge(SampleClk1x) then 406 sDacReadyForInput_ms <= sDacReadyForInputAsyncReset; 407 sDacReadyForInputLcl <= sDacReadyForInput_ms; 408 -- No clock crossing here -- just reset, although the prefix declares otherwise... 409 sDacSync_ms <= aDacSync; 410 sDacSyncLcl <= sDacSync_ms; 411 sAdcSync_ms <= aAdcSync; 412 sAdcSyncLcl <= sAdcSync_ms; 413 sSysRef_ms <= sSysRefAsyncReset; 414 sSysRefLcl <= sSysRef_ms; 415 end if; 416 end process; 417 418 -- Locals to outputs. 419 sDacReadyForInput <= sDacReadyForInputLcl; 420 sDacSync <= sDacSyncLcl; 421 sAdcSync <= sAdcSyncLcl; 422 sSysRef <= sSysRefLcl; 423 424 -- Just combine the first two enables, since they're the ones that are used for JESD. 425 -- No reset crossing here, since bFpgaClksStable is only received by a no-reset domain 426 -- and the MGTs directly. 427 bFpgaClksStable <= bRadioClksValid and bRadioClk1xEnabled and bRadioClk2xEnabled; 428 429 -- Compress/expand the flat data types from the netlist and route to top level. 430 sAdcDataAry <= Unflatten(sAdcDataFlatter); 431 sDacDataFlatter <= Flatten(sDacDataAry); 432 433 -- Data mapping using the array types. 434 sAdcDataSample0I <= (sAdcDataAry(0).Data.I & sAdcDataAry(0).Over.I & sAdcDataAry(0).CBit1.I); 435 sAdcDataSample0Q <= (sAdcDataAry(0).Data.Q & sAdcDataAry(0).Over.Q & sAdcDataAry(0).CBit1.Q); 436 sAdcDataSample1I <= (sAdcDataAry(1).Data.I & sAdcDataAry(1).Over.I & sAdcDataAry(1).CBit1.I); 437 sAdcDataSample1Q <= (sAdcDataAry(1).Data.Q & sAdcDataAry(1).Over.Q & sAdcDataAry(1).CBit1.Q); 438 -- 439 sDacDataAry(0).Data.I <= sDacDataSample0I; 440 sDacDataAry(0).Data.Q <= sDacDataSample0Q; 441 sDacDataAry(1).Data.I <= sDacDataSample1I; 442 sDacDataAry(1).Data.Q <= sDacDataSample1Q; 443 444 445 -- Timing and Sync : ------------------------------------------------------------------ 446 -- ------------------------------------------------------------------------------------ 447 448 bSyncRegPortIn <= Mask(RegPortIn => bRegPortIn, 449 kRegisterOffset => kTdc0OffsetsInEndpoint); -- 0x0200 450 451 --vhook_e TdcWrapper 452 --vhook_# Use the local copy of the SampleClock, since we want the TDC to measure the 453 --vhook_# clock offset for this daughterboard, not the global SampleClock. 454 --vhook_a SampleClk SampleClk1xOutLcl 455 --vhook_a sPpsPulse sRegPps 456 TdcWrapperx: entity work.TdcWrapper (struct) 457 port map ( 458 BusClk => BusClk, --in std_logic 459 bBusReset => bBusReset, --in std_logic 460 RefClk => RefClk, --in std_logic 461 SampleClk => SampleClk1xOutLcl, --in std_logic 462 MeasClk => MeasClk, --in std_logic 463 bSyncRegPortOut => bSyncRegPortOut, --out RegPortOut_t 464 bSyncRegPortIn => bSyncRegPortIn, --in RegPortIn_t 465 rPpsPulse => rPpsPulse, --in std_logic 466 sPpsPulse => sRegPps, --out std_logic 467 rRpTransfer => rRpTransfer, --out std_logic 468 sSpTransfer => sSpTransfer, --out std_logic 469 rGatedPulseToPin => rGatedPulseToPin, --inout std_logic 470 sGatedPulseToPin => sGatedPulseToPin); --inout std_logic 471 472 WrTdcGen: if kInclWhiteRabbitTdc = '1' generate 473 bWrSyncRegPortIn <= Mask(RegPortIn => bRegPortIn, 474 kRegisterOffset => kTdc1OffsetsInEndpoint); -- 0x0400 475 476 --vhook_e TdcWrapper WrTdcWrapperx 477 --vhook_# Use the local copy of the SampleClock, since we want the TDC to measure the 478 --vhook_# clock offset for this daughterboard, not the global SampleClock. 479 --vhook_a bSyncRegPortIn bWrSyncRegPortIn 480 --vhook_a bSyncRegPortOut bWrSyncRegPortOut 481 --vhook_a SampleClk SampleClk1xOutLcl 482 --vhook_a RefClk WrRefClk 483 --vhook_a rPpsPulse rWrPpsPulse 484 --vhook_a sPpsPulse sWrPps 485 --vhook_a rRpTransfer rWrRpTransfer 486 --vhook_a sSpTransfer sWrSpTransfer 487 --vhook_a rGatedPulseToPin rWrGatedPulseToPin 488 --vhook_a sGatedPulseToPin sWrGatedPulseToPin 489 WrTdcWrapperx: entity work.TdcWrapper (struct) 490 port map ( 491 BusClk => BusClk, --in std_logic 492 bBusReset => bBusReset, --in std_logic 493 RefClk => WrRefClk, --in std_logic 494 SampleClk => SampleClk1xOutLcl, --in std_logic 495 MeasClk => MeasClk, --in std_logic 496 bSyncRegPortOut => bWrSyncRegPortOut, --out RegPortOut_t 497 bSyncRegPortIn => bWrSyncRegPortIn, --in RegPortIn_t 498 rPpsPulse => rWrPpsPulse, --in std_logic 499 sPpsPulse => sWrPps, --out std_logic 500 rRpTransfer => rWrRpTransfer, --out std_logic 501 sSpTransfer => sWrSpTransfer, --out std_logic 502 rGatedPulseToPin => rWrGatedPulseToPin, --inout std_logic 503 sGatedPulseToPin => sWrGatedPulseToPin); --inout std_logic 504 end generate WrTdcGen; 505 506 WrTdcNotGen: if kInclWhiteRabbitTdc = '0' generate 507 bWrSyncRegPortOut <= kRegPortOutZero; 508 sWrPps <= '0'; 509 rWrRpTransfer <= '0'; 510 sWrSpTransfer <= '0'; 511 rWrGatedPulseToPin <= '0'; 512 sWrGatedPulseToPin <= '0'; 513 end generate WrTdcNotGen; 514 515 -- Mux the output PPS based on the SFP selection bits. Encoding is one-hot, with zero 516 -- also a valid state. Regardless of whether the user selects SFP0 or SFP1 as the time 517 -- source, there is only one White Rabbit TDC, so '01' and '10' are equivalent. 518 -- '00': Use the PPS output from the "regular" TDC. 519 -- '01': Use the PPS output from the "white rabbit" TDC. 520 -- '10': Use the PPS output from the "white rabbit" TDC. 521 PpsOutputMux : process (SampleClk1xOutLcl) 522 begin 523 if rising_edge(SampleClk1xOutLcl) then 524 -- Double-sync the control bits to the Sample Clock domain. 525 sPpsSfpSel_ms <= aPpsSfpSel; 526 sPpsSfpSel <= sPpsSfpSel_ms; 527 528 -- OR the control bits together to produce a single override enable for the WR TDC. 529 sUseWrTdcPps <= to_boolean(sPpsSfpSel(0) or sPpsSfpSel(1)); 530 531 -- Flop the outputs. One flop for the PPS output IOB, the other for use internally. 532 sPpsInt <= sPpsMuxed; 533 end if; 534 end process PpsOutputMux; 535 536 sPpsMuxed <= sWrPps when sUseWrTdcPps else sRegPps; 537 sPps <= sPpsInt; 538 sPpsToIob <= sPpsMuxed; -- No added flop here since there's an IOB outside this module. 539 540 541 -- Daughterboard Control : ------------------------------------------------------------ 542 -- ------------------------------------------------------------------------------------ 543 544 --vhook_e DaughterboardRegs 545 --vhook_# Tying this low is safe because the sync reset is used inside DaughterboardRegs. 546 --vhook_a aReset false 547 --vhook_a bReset to_boolean(bBusReset) 548 --vhook_a bRegPortOut bDbRegPortOut 549 --vhook_a kDbId std_logic_vector(to_unsigned(kDbId,kDbIdSize)) 550 DaughterboardRegsx: entity work.DaughterboardRegs (RTL) 551 port map ( 552 aReset => false, --in boolean 553 bReset => to_boolean(bBusReset), --in boolean 554 BusClk => BusClk, --in std_logic 555 bRegPortOut => bDbRegPortOut, --out RegPortOut_t 556 bRegPortIn => bRegPortIn, --in RegPortIn_t 557 kDbId => std_logic_vector(to_unsigned(kDbId,kDbIdSize)), --in std_logic_vector(15:0) 558 kSlotId => kSlotId); --in std_logic 559 560 561 562 563end RTL; 564