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