1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
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;
|