Hardware Design: SIE
Sign in or create your account | Project List | Help
Hardware Design: SIE Git Source Tree
Root/
Source at commit acf516e created 13 years 6 months ago. By Carlos Camargo, Fixing some examples, adding scripts for compiling xilinx libs with ghdl | |
---|---|
1 | // $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/DCM_SP.v,v 1.9.4.3 2007/04/11 20:30:19 yanx Exp $ |
2 | /////////////////////////////////////////////////////////////////////////////// |
3 | // Copyright (c) 1995/2004 Xilinx, Inc. |
4 | // All Right Reserved. |
5 | /////////////////////////////////////////////////////////////////////////////// |
6 | // ____ ____ |
7 | // / /\/ / |
8 | // /___/ \ / Vendor : Xilinx |
9 | // \ \ \/ Version : 9.2i (J.36) |
10 | // \ \ Description : Xilinx Function Simulation Library Component |
11 | // / / Digital Clock Manager |
12 | // /___/ /\ Filename : DCM_SP.v |
13 | // \ \ / \ Timestamp : |
14 | // \___\/\___\ |
15 | // |
16 | // Revision: |
17 | // 02/28/06 - Initial version. |
18 | // 05/09/06 - Add clkin_ps_mkup and clkin_ps_mkup_win for phase shifting (CR 229789). |
19 | // 06/14/06 - Add clkin_ps_mkup_flag for multiple cycle delays (CR233283). |
20 | // 07/21/06 - Change range of variable phase shifting to +/- integer of 20*(Period-3ns). |
21 | // Give warning not support initial phase shifting for variable phase shifting. |
22 | // (CR 235216). |
23 | // 09/22/06 - Add lock_period and lock_fb to clkfb_div block (CR 418722). |
24 | // 12/19/06 - Add clkfb_div_en for clkfb2x divider (CR431210). |
25 | // 04/06/07 - Enable the clock out in clock low time after reset in model |
26 | // clock_divide_by_2 (CR 437471). |
27 | // End Revision |
28 | |
29 | |
30 | `timescale 1 ps / 1 ps |
31 | |
32 | module DCM_SP ( |
33 | CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90, |
34 | CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE, STATUS, |
35 | CLKFB, CLKIN, DSSEN, PSCLK, PSEN, PSINCDEC, RST); |
36 | |
37 | parameter CLKDV_DIVIDE = 2.0; |
38 | parameter integer CLKFX_DIVIDE = 1; |
39 | parameter integer CLKFX_MULTIPLY = 4; |
40 | parameter CLKIN_DIVIDE_BY_2 = "FALSE"; |
41 | parameter CLKIN_PERIOD = 10.0; // non-simulatable |
42 | parameter CLKOUT_PHASE_SHIFT = "NONE"; |
43 | parameter CLK_FEEDBACK = "1X"; |
44 | parameter DESKEW_ADJUST = "SYSTEM_SYNCHRONOUS"; // non-simulatable |
45 | parameter DFS_FREQUENCY_MODE = "LOW"; |
46 | parameter DLL_FREQUENCY_MODE = "LOW"; |
47 | parameter DSS_MODE = "NONE"; // non-simulatable |
48 | parameter DUTY_CYCLE_CORRECTION = "TRUE"; |
49 | parameter FACTORY_JF = 16'hC080; // non-simulatable |
50 | parameter integer MAXPERCLKIN = 1000000; // non-modifiable simulation parameter |
51 | parameter integer MAXPERPSCLK = 100000000; // non-modifiable simulation parameter |
52 | parameter integer PHASE_SHIFT = 0; |
53 | parameter integer SIM_CLKIN_CYCLE_JITTER = 300; // non-modifiable simulation parameter |
54 | parameter integer SIM_CLKIN_PERIOD_JITTER = 1000; // non-modifiable simulation parameter |
55 | parameter STARTUP_WAIT = "FALSE"; // non-simulatable |
56 | |
57 | |
58 | localparam PS_STEP = 25; |
59 | |
60 | input CLKFB, CLKIN, DSSEN; |
61 | input PSCLK, PSEN, PSINCDEC, RST; |
62 | |
63 | output CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90; |
64 | output CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE; |
65 | output [7:0] STATUS; |
66 | |
67 | reg CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90; |
68 | reg CLKDV, CLKFX, CLKFX180; |
69 | |
70 | wire locked_out_out; |
71 | wire clkfb_in, clkin_in, dssen_in; |
72 | wire psclk_in, psen_in, psincdec_in, rst_in; |
73 | reg clk0_out; |
74 | reg clk2x_out, clkdv_out; |
75 | reg clkfx_out, clkfx180_en; |
76 | reg rst_flag; |
77 | reg locked_out, psdone_out, ps_overflow_out, ps_lock; |
78 | reg clkfb_div, clkfb_chk, clkfb_div_en; |
79 | integer clkdv_cnt; |
80 | |
81 | reg [1:0] clkfb_type; |
82 | reg [8:0] divide_type; |
83 | reg clkin_type; |
84 | reg [1:0] ps_type; |
85 | reg [3:0] deskew_adjust_mode; |
86 | reg dfs_mode_type; |
87 | reg dll_mode_type; |
88 | reg clk1x_type; |
89 | integer ps_in; |
90 | |
91 | reg lock_period, lock_delay, lock_clkin, lock_clkfb; |
92 | reg first_time_locked; |
93 | reg en_status; |
94 | reg ps_overflow_out_ext; |
95 | reg clkin_lost_out_ext; |
96 | reg clkfx_lost_out_ext; |
97 | reg [1:0] lock_out; |
98 | reg lock_out1_neg; |
99 | reg lock_fb, lock_ps, lock_ps_dly, lock_fb_dly, lock_fb_dly_tmp; |
100 | reg fb_delay_found; |
101 | reg clock_stopped; |
102 | reg clkin_chkin, clkfb_chkin; |
103 | |
104 | wire chk_enable, chk_rst; |
105 | wire clkin_div; |
106 | wire lock_period_pulse; |
107 | wire lock_period_dly, lock_period_dly1; |
108 | |
109 | reg clkin_ps, clkin_ps_tmp, clkin_ps_mkup, clkin_ps_mkup_win, clkin_ps_mkup_flag; |
110 | reg clkin_fb; |
111 | |
112 | time FINE_SHIFT_RANGE; |
113 | //time ps_delay, ps_delay_init, ps_delay_md, ps_delay_all, ps_max_range; |
114 | integer ps_delay, ps_delay_init, ps_delay_md, ps_delay_all, ps_max_range; |
115 | integer ps_delay_last; |
116 | integer ps_acc; |
117 | time clkin_edge; |
118 | time clkin_div_edge; |
119 | time clkin_ps_edge; |
120 | time delay_edge; |
121 | time clkin_period [2:0]; |
122 | time period; |
123 | integer period_int, period_int2, period_int3, period_ps_tmp; |
124 | time period_div; |
125 | integer period_orig_int; |
126 | time period_orig; |
127 | time period_ps; |
128 | time clkout_delay; |
129 | time fb_delay; |
130 | time period_fx, remain_fx; |
131 | time period_dv_high, period_dv_low; |
132 | time cycle_jitter, period_jitter; |
133 | |
134 | reg clkin_window, clkfb_window; |
135 | reg [2:0] rst_reg; |
136 | reg [12:0] numerator, denominator, gcd; |
137 | reg [23:0] i, n, d, p; |
138 | |
139 | reg notifier; |
140 | |
141 | initial begin |
142 | #1; |
143 | if ($realtime == 0) begin |
144 | $display ("Simulator Resolution Error : Simulator resolution is set to a value greater than 1 ps."); |
145 | $display ("In order to simulate the DCM_SP, the simulator resolution must be set to 1ps or smaller."); |
146 | $finish; |
147 | end |
148 | end |
149 | |
150 | initial begin |
151 | case (2.0) |
152 | 1.5 : divide_type = 'd3; |
153 | 2.0 : divide_type = 'd4; |
154 | 2.5 : divide_type = 'd5; |
155 | 3.0 : divide_type = 'd6; |
156 | 3.5 : divide_type = 'd7; |
157 | 4.0 : divide_type = 'd8; |
158 | 4.5 : divide_type = 'd9; |
159 | 5.0 : divide_type = 'd10; |
160 | 5.5 : divide_type = 'd11; |
161 | 6.0 : divide_type = 'd12; |
162 | 6.5 : divide_type = 'd13; |
163 | 7.0 : divide_type = 'd14; |
164 | 7.5 : divide_type = 'd15; |
165 | 8.0 : divide_type = 'd16; |
166 | 9.0 : divide_type = 'd18; |
167 | 10.0 : divide_type = 'd20; |
168 | 11.0 : divide_type = 'd22; |
169 | 12.0 : divide_type = 'd24; |
170 | 13.0 : divide_type = 'd26; |
171 | 14.0 : divide_type = 'd28; |
172 | 15.0 : divide_type = 'd30; |
173 | 16.0 : divide_type = 'd32; |
174 | default : begin |
175 | $display("Attribute Syntax Error : The attribute CLKDV_DIVIDE on DCM_SP instance %m is set to %0.1f. Legal values for this attribute are 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, or 16.0.", CLKDV_DIVIDE); |
176 | $finish; |
177 | end |
178 | endcase |
179 | |
180 | if ((CLKFX_DIVIDE <= 0) || (32 < CLKFX_DIVIDE)) begin |
181 | $display("Attribute Syntax Error : The attribute CLKFX_DIVIDE on DCM_SP instance %m is set to %d. Legal values for this attribute are 1 ... 32.", CLKFX_DIVIDE); |
182 | $finish; |
183 | end |
184 | |
185 | if ((CLKFX_MULTIPLY <= 1) || (32 < CLKFX_MULTIPLY)) begin |
186 | $display("Attribute Syntax Error : The attribute CLKFX_MULTIPLY on DCM_SP instance %m is set to %d. Legal values for this attribute are 2 ... 32.", CLKFX_MULTIPLY); |
187 | $finish; |
188 | end |
189 | |
190 | case (CLKIN_DIVIDE_BY_2) |
191 | "false" : clkin_type = 0; |
192 | "FALSE" : clkin_type = 0; |
193 | "true" : clkin_type = 1; |
194 | "TRUE" : clkin_type = 1; |
195 | default : begin |
196 | $display("Attribute Syntax Error : The attribute CLKIN_DIVIDE_BY_2 on DCM_SP instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", CLKIN_DIVIDE_BY_2); |
197 | $finish; |
198 | end |
199 | endcase |
200 | |
201 | case (CLKOUT_PHASE_SHIFT) |
202 | "NONE" : begin |
203 | ps_in = 256; |
204 | ps_type = 0; |
205 | end |
206 | "none" : begin |
207 | ps_in = 256; |
208 | ps_type = 0; |
209 | end |
210 | "FIXED" : begin |
211 | ps_in = PHASE_SHIFT + 256; |
212 | ps_type = 1; |
213 | end |
214 | "fixed" : begin |
215 | ps_in = PHASE_SHIFT + 256; |
216 | ps_type = 1; |
217 | end |
218 | "VARIABLE" : begin |
219 | ps_in = PHASE_SHIFT + 256; |
220 | ps_type = 2; |
221 | end |
222 | "variable" : begin |
223 | ps_in = PHASE_SHIFT + 256; |
224 | ps_type = 2; |
225 | if (PHASE_SHIFT != 0) |
226 | $display("Attribute Syntax Warning : The attribute PHASE_SHIFT on DCM_SP instance %m is set to %d. The maximum variable phase shift range is only valid when initial phase shift PHASE_SHIFT is zero.", PHASE_SHIFT); |
227 | end |
228 | default : begin |
229 | $display("Attribute Syntax Error : The attribute CLKOUT_PHASE_SHIFT on DCM_SP instance %m is set to %s. Legal values for this attribute are NONE, FIXED or VARIABLE.", CLKOUT_PHASE_SHIFT); |
230 | $finish; |
231 | end |
232 | endcase |
233 | |
234 | |
235 | case (CLK_FEEDBACK) |
236 | "none" : clkfb_type = 2'b00; |
237 | "NONE" : clkfb_type = 2'b00; |
238 | "1x" : clkfb_type = 2'b01; |
239 | "1X" : clkfb_type = 2'b01; |
240 | "2x" : clkfb_type = 2'b10; |
241 | "2X" : clkfb_type = 2'b10; |
242 | default : begin |
243 | $display("Attribute Syntax Error : The attribute CLK_FEEDBACK on DCM_SP instance %m is set to %s. Legal values for this attribute are NONE, 1X or 2X.", CLK_FEEDBACK); |
244 | $finish; |
245 | end |
246 | endcase |
247 | |
248 | case (DESKEW_ADJUST) |
249 | "source_synchronous" : deskew_adjust_mode = 8; |
250 | "SOURCE_SYNCHRONOUS" : deskew_adjust_mode = 8; |
251 | "system_synchronous" : deskew_adjust_mode = 11; |
252 | "SYSTEM_SYNCHRONOUS" : deskew_adjust_mode = 11; |
253 | "0" : deskew_adjust_mode = 0; |
254 | "1" : deskew_adjust_mode = 1; |
255 | "2" : deskew_adjust_mode = 2; |
256 | "3" : deskew_adjust_mode = 3; |
257 | "4" : deskew_adjust_mode = 4; |
258 | "5" : deskew_adjust_mode = 5; |
259 | "6" : deskew_adjust_mode = 6; |
260 | "7" : deskew_adjust_mode = 7; |
261 | "8" : deskew_adjust_mode = 8; |
262 | "9" : deskew_adjust_mode = 9; |
263 | "10" : deskew_adjust_mode = 10; |
264 | "11" : deskew_adjust_mode = 11; |
265 | "12" : deskew_adjust_mode = 12; |
266 | "13" : deskew_adjust_mode = 13; |
267 | "14" : deskew_adjust_mode = 14; |
268 | "15" : deskew_adjust_mode = 15; |
269 | default : begin |
270 | $display("Attribute Syntax Error : The attribute DESKEW_ADJUST on DCM_SP instance %m is set to %s. Legal values for this attribute are SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or 0 ... 15.", DESKEW_ADJUST); |
271 | $finish; |
272 | end |
273 | endcase |
274 | |
275 | case (DFS_FREQUENCY_MODE) |
276 | "high" : dfs_mode_type = 1; |
277 | "HIGH" : dfs_mode_type = 1; |
278 | "low" : dfs_mode_type = 0; |
279 | "LOW" : dfs_mode_type = 0; |
280 | default : begin |
281 | $display("Attribute Syntax Error : The attribute DFS_FREQUENCY_MODE on DCM_SP instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DFS_FREQUENCY_MODE); |
282 | $finish; |
283 | end |
284 | endcase |
285 | |
286 | period_jitter = SIM_CLKIN_PERIOD_JITTER; |
287 | cycle_jitter = SIM_CLKIN_CYCLE_JITTER; |
288 | |
289 | case (DLL_FREQUENCY_MODE) |
290 | "high" : dll_mode_type = 1; |
291 | "HIGH" : dll_mode_type = 1; |
292 | "low" : dll_mode_type = 0; |
293 | "LOW" : dll_mode_type = 0; |
294 | default : begin |
295 | $display("Attribute Syntax Error : The attribute DLL_FREQUENCY_MODE on DCM_SP instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DLL_FREQUENCY_MODE); |
296 | $finish; |
297 | end |
298 | endcase |
299 | |
300 | if ((dll_mode_type ==1) && (clkfb_type == 2'b10)) begin |
301 | $display("Attribute Syntax Error : The attributes DLL_FREQUENCY_MODE on DCM_SP instance %m is set to %s and CLK_FEEDBACK is set to %s. CLK_FEEDBACK 2X is not supported when DLL_FREQUENCY_MODE is HIGH.", DLL_FREQUENCY_MODE, CLK_FEEDBACK); |
302 | $finish; |
303 | end |
304 | |
305 | case (DSS_MODE) |
306 | "none" : ; |
307 | "NONE" : ; |
308 | default : begin |
309 | $display("Attribute Syntax Error : The attribute DSS_MODE on DCM_SP instance %m is set to %s. Legal values for this attribute is NONE.", DSS_MODE); |
310 | $finish; |
311 | end |
312 | endcase |
313 | |
314 | case (DUTY_CYCLE_CORRECTION) |
315 | "false" : clk1x_type = 0; |
316 | "FALSE" : clk1x_type = 0; |
317 | "true" : clk1x_type = 1; |
318 | "TRUE" : clk1x_type = 1; |
319 | default : begin |
320 | $display("Attribute Syntax Error : The attribute DUTY_CYCLE_CORRECTION on DCM_SP instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", DUTY_CYCLE_CORRECTION); |
321 | $finish; |
322 | end |
323 | endcase |
324 | |
325 | if ((PHASE_SHIFT < -255) || (PHASE_SHIFT > 255)) begin |
326 | $display("Attribute Syntax Error : The attribute PHASE_SHIFT on DCM_SP instance %m is set to %d. Legal values for this attribute are -255 ... 255.", PHASE_SHIFT); |
327 | $display("Error : PHASE_SHIFT = %d is not -255 ... 255.", PHASE_SHIFT); |
328 | $finish; |
329 | end |
330 | |
331 | case (STARTUP_WAIT) |
332 | "false" : ; |
333 | "FALSE" : ; |
334 | "true" : ; |
335 | "TRUE" : ; |
336 | default : begin |
337 | $display("Attribute Syntax Error : The attribute STARTUP_WAIT on DCM_SP instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", STARTUP_WAIT); |
338 | $finish; |
339 | end |
340 | endcase |
341 | end |
342 | |
343 | // |
344 | // fx parameters |
345 | // |
346 | |
347 | initial begin |
348 | gcd = 1; |
349 | for (i = 2; i <= CLKFX_MULTIPLY; i = i + 1) begin |
350 | if (((CLKFX_MULTIPLY % i) == 0) && ((CLKFX_DIVIDE % i) == 0)) |
351 | gcd = i; |
352 | end |
353 | numerator = CLKFX_MULTIPLY / gcd; |
354 | denominator = CLKFX_DIVIDE / gcd; |
355 | end |
356 | |
357 | // |
358 | // input wire delays |
359 | // |
360 | |
361 | buf b_clkin (clkin_in, CLKIN); |
362 | buf b_clkfb (clkfb_in, CLKFB); |
363 | buf b_dssen (dssen_in, DSSEN); |
364 | buf b_psclk (psclk_in, PSCLK); |
365 | buf b_psen (psen_in, PSEN); |
366 | buf b_psincdec (psincdec_in, PSINCDEC); |
367 | buf b_rst (rst_in, RST); |
368 | buf #100 b_LOCKED (LOCKED, locked_out_out); |
369 | buf #100 b_PSDONE (PSDONE, psdone_out); |
370 | buf b_ps_overflow (STATUS[0], ps_overflow_out_ext); |
371 | buf b_clkin_lost (STATUS[1], clkin_lost_out_ext); |
372 | buf b_clkfx_lost (STATUS[2], clkfx_lost_out_ext); |
373 | |
374 | assign STATUS[7:3] = 5'b0; |
375 | |
376 | dcm_sp_clock_divide_by_2 i_clock_divide_by_2 (clkin_in, clkin_type, clkin_div, rst_in); |
377 | |
378 | dcm_sp_maximum_period_check #("CLKIN", MAXPERCLKIN) i_max_clkin (clkin_in, rst_in); |
379 | dcm_sp_maximum_period_check #("PSCLK", MAXPERPSCLK) i_max_psclk (psclk_in, rst_in); |
380 | |
381 | dcm_sp_clock_lost i_clkin_lost (clkin_in, first_time_locked, clkin_lost_out, rst_in); |
382 | dcm_sp_clock_lost i_clkfx_lost (CLKFX, first_time_locked, clkfx_lost_out, rst_in); |
383 | |
384 | always @(rst_in or en_status or clkfx_lost_out or clkin_lost_out or ps_overflow_out) |
385 | if (rst_in == 1 || en_status == 0) begin |
386 | ps_overflow_out_ext = 0; |
387 | clkin_lost_out_ext = 0; |
388 | clkfx_lost_out_ext = 0; |
389 | end |
390 | else |
391 | begin |
392 | ps_overflow_out_ext = ps_overflow_out; |
393 | clkin_lost_out_ext = clkin_lost_out; |
394 | clkfx_lost_out_ext = clkfx_lost_out; |
395 | end |
396 | |
397 | always @(posedge rst_in or posedge LOCKED) |
398 | if (rst_in == 1) |
399 | en_status <= 0; |
400 | else |
401 | en_status <= 1; |
402 | |
403 | |
404 | always @(clkin_div) |
405 | clkin_ps_tmp <= #(ps_delay_md) clkin_div; |
406 | |
407 | always @(clkin_ps_tmp or clkin_ps_mkup or clkin_ps_mkup_win) |
408 | if (clkin_ps_mkup_win) |
409 | clkin_ps = clkin_ps_mkup; |
410 | else |
411 | clkin_ps = clkin_ps_tmp; |
412 | |
413 | always @(ps_delay_last or period_int or ps_delay) begin |
414 | period_int2 = 2 * period_int; |
415 | period_int3 = 3 * period_int; |
416 | if ((ps_delay_last >= period_int && ps_delay < period_int) || |
417 | (ps_delay_last >= period_int2 && ps_delay < period_int2) || |
418 | (ps_delay_last >= period_int3 && ps_delay < period_int3)) |
419 | clkin_ps_mkup_flag = 1; |
420 | else |
421 | clkin_ps_mkup_flag = 0; |
422 | end |
423 | |
424 | always @(posedge clkin_div or negedge clkin_div) begin |
425 | if (ps_type == 2'b10) begin |
426 | if ((ps_delay_last > 0 && ps_delay <= 0 ) || clkin_ps_mkup_flag == 1) begin |
427 | if (clkin_div) begin |
428 | clkin_ps_mkup_win <= 1; |
429 | clkin_ps_mkup <= 1; |
430 | #1; |
431 | @(negedge clkin_div) begin |
432 | clkin_ps_mkup_win <= 1; |
433 | clkin_ps_mkup <= 0; |
434 | end |
435 | end |
436 | else begin |
437 | clkin_ps_mkup_win <= 0; |
438 | clkin_ps_mkup <= 0; |
439 | #1; |
440 | @(posedge clkin_div) begin |
441 | clkin_ps_mkup_win <= 1; |
442 | clkin_ps_mkup <= 1; |
443 | end |
444 | @(negedge clkin_div) begin |
445 | clkin_ps_mkup_win <= 1; |
446 | clkin_ps_mkup <= 0; |
447 | end |
448 | end |
449 | end |
450 | else begin |
451 | clkin_ps_mkup_win <= 0; |
452 | clkin_ps_mkup <= 0; |
453 | end |
454 | ps_delay_last <= ps_delay; |
455 | end |
456 | end |
457 | |
458 | always @(clkin_ps or lock_fb) |
459 | clkin_fb = clkin_ps & lock_fb; |
460 | |
461 | always @(negedge clkfb_in or posedge rst_in) |
462 | if (rst_in) |
463 | clkfb_div_en <= 0; |
464 | else |
465 | if (lock_fb_dly && lock_period && lock_fb && ~clkin_ps) |
466 | clkfb_div_en <= 1; |
467 | |
468 | always @(posedge clkfb_in or posedge rst_in) |
469 | if (rst_in) |
470 | clkfb_div <= 0; |
471 | else |
472 | if (clkfb_div_en ) |
473 | clkfb_div <= ~clkfb_div; |
474 | |
475 | always @(clkfb_in or clkfb_div ) |
476 | if (clkfb_type == 2'b10 ) |
477 | clkfb_chk = clkfb_div; |
478 | else |
479 | clkfb_chk = clkfb_in & lock_fb_dly; |
480 | |
481 | always @(posedge clkin_fb or posedge chk_rst) |
482 | if (chk_rst) |
483 | clkin_chkin <= 0; |
484 | else |
485 | clkin_chkin <= 1; |
486 | |
487 | always @(posedge clkfb_chk or posedge chk_rst) |
488 | if (chk_rst) |
489 | clkfb_chkin <= 0; |
490 | else |
491 | clkfb_chkin <= 1; |
492 | |
493 | assign chk_rst = (rst_in==1 || clock_stopped==1 ) ? 1 : 0; |
494 | assign chk_enable = (clkin_chkin == 1 && clkfb_chkin == 1 && |
495 | lock_ps ==1 && lock_fb ==1 && lock_fb_dly == 1) ? 1 : 0; |
496 | |
497 | always @(posedge clkin_div or posedge rst_in) |
498 | if (rst_in) begin |
499 | period_div <= 0; |
500 | clkin_div_edge <= 0; |
501 | end |
502 | else |
503 | if ( clkin_div ==1 ) begin |
504 | clkin_div_edge <= $time; |
505 | if (($time - clkin_div_edge) <= (1.5 * period_div)) |
506 | period_div <= $time - clkin_div_edge; |
507 | else if ((period_div == 0) && (clkin_div_edge != 0)) |
508 | period_div <= $time - clkin_div_edge; |
509 | end |
510 | |
511 | always @(posedge clkin_ps or posedge rst_in) |
512 | if (rst_in) begin |
513 | period_ps <= 0; |
514 | clkin_ps_edge <= 0; |
515 | end |
516 | else |
517 | if (clkin_ps == 1 ) begin |
518 | clkin_ps_edge <= $time; |
519 | if (($time - clkin_ps_edge) <= (1.5 * period_ps)) |
520 | period_ps <= $time - clkin_ps_edge; |
521 | else if ((period_ps == 0) && (clkin_ps_edge != 0)) |
522 | period_ps <= $time - clkin_ps_edge; |
523 | end |
524 | |
525 | always @(posedge clkin_ps) begin |
526 | lock_ps <= lock_period; |
527 | lock_ps_dly <= lock_ps; |
528 | lock_fb <= lock_ps_dly; |
529 | lock_fb_dly_tmp <= lock_fb; |
530 | end |
531 | |
532 | always @(negedge clkin_ps or posedge rst_in) |
533 | if (rst_in) |
534 | lock_fb_dly <= 1'b0; |
535 | else |
536 | lock_fb_dly <= #(period/4) lock_fb_dly_tmp; |
537 | |
538 | |
539 | always @(period or fb_delay ) |
540 | if (fb_delay == 0) |
541 | clkout_delay = 0; |
542 | else |
543 | clkout_delay = period - fb_delay; |
544 | |
545 | // |
546 | // generate master reset signal |
547 | // |
548 | |
549 | always @(posedge clkin_in) begin |
550 | rst_reg[0] <= rst_in; |
551 | rst_reg[1] <= rst_reg[0] & rst_in; |
552 | rst_reg[2] <= rst_reg[1] & rst_reg[0] & rst_in; |
553 | end |
554 | |
555 | reg rst_tmp1, rst_tmp2; |
556 | initial |
557 | begin |
558 | rst_tmp1 = 0; |
559 | rst_tmp2 = 0; |
560 | rst_flag = 0; |
561 | end |
562 | |
563 | always @(rst_in) |
564 | begin |
565 | if (rst_in) |
566 | rst_flag = 0; |
567 | |
568 | rst_tmp1 = rst_in; |
569 | if (rst_tmp1 == 0 && rst_tmp2 == 1) begin |
570 | if ((rst_reg[2] & rst_reg[1] & rst_reg[0]) == 0) begin |
571 | rst_flag = 1; |
572 | $display("Input Error : RST on instance %m must be asserted for 3 CLKIN clock cycles."); |
573 | end |
574 | end |
575 | rst_tmp2 = rst_tmp1; |
576 | end |
577 | |
578 | initial begin |
579 | CLK0 = 0; |
580 | CLK180 = 0; |
581 | CLK270 = 0; |
582 | CLK2X = 0; |
583 | CLK2X180 = 0; |
584 | CLK90 = 0; |
585 | CLKDV = 0; |
586 | CLKFX = 0; |
587 | CLKFX180 = 0; |
588 | clk0_out = 0; |
589 | clk2x_out = 0; |
590 | clkdv_out = 0; |
591 | clkdv_cnt = 0; |
592 | clkfb_window = 0; |
593 | clkfx_out = 0; |
594 | clkfx180_en = 0; |
595 | clkin_div_edge = 0; |
596 | clkin_period[0] = 0; |
597 | clkin_period[1] = 0; |
598 | clkin_period[2] = 0; |
599 | clkin_edge = 0; |
600 | clkin_ps_edge = 0; |
601 | clkin_window = 0; |
602 | clkout_delay = 0; |
603 | clock_stopped = 1; |
604 | fb_delay = 0; |
605 | fb_delay_found = 0; |
606 | lock_clkfb = 0; |
607 | lock_clkin = 0; |
608 | lock_delay = 0; |
609 | lock_fb = 0; |
610 | lock_fb_dly = 0; |
611 | lock_out = 2'b00; |
612 | lock_out1_neg = 0; |
613 | lock_period = 0; |
614 | lock_ps = 0; |
615 | lock_ps_dly = 0; |
616 | locked_out = 0; |
617 | period = 0; |
618 | period_int = 0; |
619 | period_int2 = 0; |
620 | period_int3 = 0; |
621 | period_div = 0; |
622 | period_fx = 0; |
623 | period_orig = 0; |
624 | period_orig_int = 0; |
625 | period_ps = 0; |
626 | psdone_out = 0; |
627 | ps_delay = 0; |
628 | ps_delay_md = 0; |
629 | ps_delay_init = 0; |
630 | ps_acc = 0; |
631 | ps_delay_all = 0; |
632 | ps_lock = 0; |
633 | ps_overflow_out = 0; |
634 | ps_overflow_out_ext = 0; |
635 | clkin_lost_out_ext = 0; |
636 | clkfx_lost_out_ext = 0; |
637 | rst_reg = 3'b000; |
638 | first_time_locked = 0; |
639 | en_status = 0; |
640 | clkfb_div = 0; |
641 | clkin_chkin = 0; |
642 | clkfb_chkin = 0; |
643 | clkin_ps_mkup = 0; |
644 | clkin_ps_mkup_win = 0; |
645 | clkin_ps_mkup_flag = 0; |
646 | ps_delay_last = 0; |
647 | clkin_ps_tmp = 0; |
648 | end |
649 | |
650 | // RST less than 3 cycles, lock = x |
651 | |
652 | assign locked_out_out = (rst_flag) ? 1'bx : locked_out; |
653 | |
654 | // |
655 | // detect_first_time_locked |
656 | // |
657 | always @(posedge locked_out) |
658 | if (first_time_locked == 0) |
659 | first_time_locked <= 1; |
660 | |
661 | // |
662 | // phase shift parameters |
663 | // |
664 | |
665 | always @(posedge lock_period) |
666 | ps_delay_init <= ps_in * period_orig /256; |
667 | |
668 | |
669 | always @(period) begin |
670 | period_int = period; |
671 | if (clkin_type==1) |
672 | period_ps_tmp = 2 * period; |
673 | else |
674 | period_ps_tmp = period; |
675 | |
676 | if (period_ps_tmp > 3000) |
677 | ps_max_range = 20 * (period_ps_tmp - 3000)/1000; |
678 | else |
679 | ps_max_range = 0; |
680 | end |
681 | |
682 | always @(ps_delay or rst_in or period_int or lock_period) |
683 | if ( rst_in) |
684 | ps_delay_md = 0; |
685 | else if (lock_period) begin |
686 | ps_delay_md = period_int + ps_delay % period_int; |
687 | end |
688 | |
689 | always @(posedge psclk_in or posedge rst_in or posedge lock_period_pulse) |
690 | if (rst_in) begin |
691 | ps_delay <= 0; |
692 | ps_overflow_out <= 0; |
693 | ps_acc <= 0; |
694 | end |
695 | else if (lock_period_pulse) |
696 | ps_delay <= ps_delay_init; |
697 | else |
698 | if (ps_type == 2'b10) |
699 | if (psen_in) begin |
700 | if (ps_lock == 1) |
701 | $display(" Warning : Please wait for PSDONE signal before adjusting the Phase Shift."); |
702 | else if (lock_ps) begin |
703 | if (psincdec_in == 1) begin |
704 | if (ps_acc > ps_max_range) |
705 | ps_overflow_out <= 1; |
706 | else begin |
707 | ps_delay <= ps_delay + PS_STEP; |
708 | ps_acc <= ps_acc + 1; |
709 | ps_overflow_out <= 0; |
710 | end |
711 | ps_lock <= 1; |
712 | end |
713 | else if (psincdec_in == 0) begin |
714 | if (ps_acc < -ps_max_range) |
715 | ps_overflow_out <= 1; |
716 | else begin |
717 | ps_delay <= ps_delay - PS_STEP; |
718 | ps_acc <= ps_acc - 1; |
719 | ps_overflow_out <= 0; |
720 | end |
721 | ps_lock <= 1; |
722 | end |
723 | end |
724 | end |
725 | |
726 | always @(posedge ps_lock) begin |
727 | @(posedge clkin_ps) |
728 | @(posedge psclk_in) |
729 | @(posedge psclk_in) |
730 | @(posedge psclk_in) |
731 | psdone_out <= 1; |
732 | @(posedge psclk_in) |
733 | psdone_out <= 0; |
734 | ps_lock <= 0; |
735 | end |
736 | |
737 | // |
738 | // determine clock period |
739 | // |
740 | |
741 | always @(posedge clkin_div or negedge clkin_div or posedge rst_in) |
742 | if (rst_in == 1) begin |
743 | clkin_period[0] <= 0; |
744 | clkin_period[1] <= 0; |
745 | clkin_period[2] <= 0; |
746 | clkin_edge <= 0; |
747 | end |
748 | else |
749 | if (clkin_div == 1) begin |
750 | clkin_edge <= $time; |
751 | clkin_period[2] <= clkin_period[1]; |
752 | clkin_period[1] <= clkin_period[0]; |
753 | if (clkin_edge != 0) |
754 | clkin_period[0] <= $time - clkin_edge; |
755 | end |
756 | else if (clkin_div == 0) |
757 | if (lock_period == 1) |
758 | if (100000000 < clkin_period[0]/1000) |
759 | begin |
760 | end |
761 | else if ((period_orig * 2 < clkin_period[0]) && (clock_stopped == 0)) begin |
762 | clkin_period[0] <= clkin_period[1]; |
763 | end |
764 | |
765 | always @(negedge clkin_div or posedge rst_in) |
766 | if (rst_in == 1) begin |
767 | lock_period <= 0; |
768 | clock_stopped <= 1; |
769 | end |
770 | else begin |
771 | if (lock_period == 1'b0) begin |
772 | if ((clkin_period[0] != 0) && |
773 | (clkin_period[0] - cycle_jitter <= clkin_period[1]) && |
774 | (clkin_period[1] <= clkin_period[0] + cycle_jitter) && |
775 | (clkin_period[1] - cycle_jitter <= clkin_period[2]) && |
776 | (clkin_period[2] <= clkin_period[1] + cycle_jitter)) begin |
777 | lock_period <= 1; |
778 | period_orig <= (clkin_period[0] + |
779 | clkin_period[1] + |
780 | clkin_period[2]) / 3; |
781 | period <= clkin_period[0]; |
782 | end |
783 | end |
784 | else if (lock_period == 1'b1) begin |
785 | if (100000000 < (clkin_period[0] / 1000)) begin |
786 | $display(" Warning : CLKIN stopped toggling on instance %m exceeds %d ms. Current CLKIN Period = %1.3f ns.", 100, clkin_period[0] / 1000.0); |
787 | lock_period <= 0; |
788 | @(negedge rst_reg[2]); |
789 | end |
790 | else if ((period_orig * 2 < clkin_period[0]) && clock_stopped == 1'b0) begin |
791 | clock_stopped <= 1'b1; |
792 | end |
793 | else if ((clkin_period[0] < period_orig - period_jitter) || |
794 | (period_orig + period_jitter < clkin_period[0])) begin |
795 | $display(" Warning : Input Clock Period Jitter on instance %m exceeds %1.3f ns. Locked CLKIN Period = %1.3f. Current CLKIN Period = %1.3f.", period_jitter / 1000.0, period_orig / 1000.0, clkin_period[0] / 1000.0); |
796 | lock_period <= 0; |
797 | @(negedge rst_reg[2]); |
798 | end |
799 | else if ((clkin_period[0] < clkin_period[1] - cycle_jitter) || |
800 | (clkin_period[1] + cycle_jitter < clkin_period[0])) begin |
801 | $display(" Warning : Input Clock Cycle-Cycle Jitter on instance %m exceeds %1.3f ns. Previous CLKIN Period = %1.3f. Current CLKIN Period = %1.3f.", cycle_jitter / 1000.0, clkin_period[1] / 1000.0, clkin_period[0] / 1000.0); |
802 | lock_period <= 0; |
803 | @(negedge rst_reg[2]); |
804 | end |
805 | else begin |
806 | period <= clkin_period[0]; |
807 | clock_stopped <= 1'b0; |
808 | end |
809 | end |
810 | end |
811 | |
812 | assign #1 lock_period_dly1 = lock_period; |
813 | assign #(period/2) lock_period_dly = lock_period_dly1; |
814 | assign lock_period_pulse = (lock_period_dly1==1 && lock_period_dly==0) ? 1 : 0; |
815 | |
816 | // |
817 | // determine clock delay |
818 | // |
819 | |
820 | //always @(posedge lock_period or posedge rst_in) |
821 | always @(posedge lock_ps_dly or posedge rst_in) |
822 | if (rst_in) begin |
823 | fb_delay <= 0; |
824 | fb_delay_found <= 0; |
825 | end |
826 | else begin |
827 | if (lock_period && clkfb_type != 2'b00) begin |
828 | if (clkfb_type == 2'b01) begin |
829 | @(posedge CLK0 or rst_in) |
830 | delay_edge = $time; |
831 | end |
832 | else if (clkfb_type == 2'b10) begin |
833 | @(posedge CLK2X or rst_in) |
834 | delay_edge = $time; |
835 | end |
836 | @(posedge clkfb_in or rst_in) begin |
837 | fb_delay <= ($time - delay_edge) % period_orig; |
838 | fb_delay_found <= 1; |
839 | end |
840 | end |
841 | end |
842 | |
843 | // |
844 | // determine feedback lock |
845 | // |
846 | |
847 | always @(posedge clkfb_chk or posedge rst_in) |
848 | if (rst_in) |
849 | clkfb_window <= 0; |
850 | else begin |
851 | clkfb_window <= 1; |
852 | #cycle_jitter clkfb_window <= 0; |
853 | end |
854 | |
855 | always @(posedge clkin_fb or posedge rst_in) |
856 | if (rst_in) |
857 | clkin_window <= 0; |
858 | else begin |
859 | clkin_window <= 1; |
860 | #cycle_jitter clkin_window <= 0; |
861 | end |
862 | |
863 | always @(posedge clkin_fb or posedge rst_in) |
864 | if (rst_in) |
865 | lock_clkin <= 0; |
866 | else begin |
867 | #1 |
868 | if ((clkfb_window && fb_delay_found) || (clkin_lost_out == 1'b1 && lock_out[0]==1'b1)) |
869 | lock_clkin <= 1; |
870 | else |
871 | if (chk_enable==1) |
872 | lock_clkin <= 0; |
873 | end |
874 | |
875 | always @(posedge clkfb_chk or posedge rst_in) |
876 | if (rst_in) |
877 | lock_clkfb <= 0; |
878 | else begin |
879 | #1 |
880 | if ((clkin_window && fb_delay_found) || (clkin_lost_out == 1'b1 && lock_out[0]==1'b1)) |
881 | lock_clkfb <= 1; |
882 | else |
883 | if (chk_enable ==1) |
884 | lock_clkfb <= 0; |
885 | end |
886 | |
887 | always @(negedge clkin_fb or posedge rst_in) |
888 | if (rst_in) |
889 | lock_delay <= 0; |
890 | else |
891 | lock_delay <= lock_clkin || lock_clkfb; |
892 | |
893 | // |
894 | // generate lock signal |
895 | // |
896 | |
897 | always @(posedge clkin_ps or posedge rst_in) |
898 | if (rst_in) begin |
899 | lock_out <= 2'b0; |
900 | locked_out <=0; |
901 | end |
902 | else begin |
903 | if (clkfb_type == 2'b00) |
904 | lock_out[0] <= lock_period; |
905 | else |
906 | lock_out[0] <= lock_period & lock_delay & lock_fb; |
907 | lock_out[1] <= lock_out[0]; |
908 | locked_out <= lock_out[1]; |
909 | end |
910 | |
911 | always @(negedge clkin_ps or posedge rst_in) |
912 | if (rst_in) |
913 | lock_out1_neg <= 0; |
914 | else |
915 | lock_out1_neg <= lock_out[1]; |
916 | |
917 | |
918 | // |
919 | // generate the clk1x_out |
920 | // |
921 | |
922 | always @(posedge clkin_ps or negedge clkin_ps or posedge rst_in) |
923 | if (rst_in) |
924 | clk0_out <= 0; |
925 | else |
926 | if (clkin_ps ==1) |
927 | if (clk1x_type==1 && lock_out[0]) begin |
928 | clk0_out <= 1; |
929 | #(period / 2) |
930 | clk0_out <= 0; |
931 | end |
932 | else |
933 | clk0_out <= 1; |
934 | else |
935 | if (clkin_ps == 0 && ((clk1x_type && lock_out[0]) == 0 || (lock_out[0]== 1 && lock_out[1]== 0))) |
936 | clk0_out <= 0; |
937 | |
938 | // |
939 | // generate the clk2x_out |
940 | // |
941 | |
942 | always @(posedge clkin_ps or posedge rst_in) |
943 | if (rst_in) |
944 | clk2x_out <= 0; |
945 | else begin |
946 | clk2x_out <= 1; |
947 | #(period / 4) |
948 | clk2x_out <= 0; |
949 | #(period / 4) |
950 | clk2x_out <= 1; |
951 | #(period / 4) |
952 | clk2x_out <= 0; |
953 | end |
954 | |
955 | // |
956 | // generate the clkdv_out |
957 | // |
958 | |
959 | always @(posedge clkin_ps or negedge clkin_ps or posedge rst_in) |
960 | if (rst_in) begin |
961 | clkdv_out <= 1'b0; |
962 | clkdv_cnt <= 0; |
963 | end |
964 | else |
965 | if (lock_out1_neg) begin |
966 | if (clkdv_cnt >= divide_type -1) |
967 | clkdv_cnt <= 0; |
968 | else |
969 | clkdv_cnt <= clkdv_cnt + 1; |
970 | |
971 | if (clkdv_cnt < divide_type /2) |
972 | clkdv_out <= 1'b1; |
973 | else |
974 | if ( (divide_type[0] == 1'b1) && dll_mode_type == 1'b0) |
975 | clkdv_out <= #(period/4) 1'b0; |
976 | else |
977 | clkdv_out <= 1'b0; |
978 | end |
979 | |
980 | |
981 | // |
982 | // generate fx output signal |
983 | // |
984 | |
985 | always @(lock_period or period or denominator or numerator) begin |
986 | if (lock_period == 1'b1) begin |
987 | period_fx = (period * denominator) / (numerator * 2); |
988 | remain_fx = (period * denominator) % (numerator * 2); |
989 | end |
990 | end |
991 | |
992 | always @(posedge clkin_ps or posedge clkin_lost_out or posedge rst_in ) |
993 | if (rst_in == 1) |
994 | clkfx_out = 1'b0; |
995 | else if (clkin_lost_out == 1'b1 ) begin |
996 | if (locked_out == 1) |
997 | @(negedge rst_reg[2]); |
998 | end |
999 | else |
1000 | if (lock_out[1] == 1) begin |
1001 | clkfx_out = 1'b1; |
1002 | for (p = 0; p < (numerator * 2 - 1); p = p + 1) begin |
1003 | #(period_fx); |
1004 | if (p < remain_fx) |
1005 | #1; |
1006 | clkfx_out = !clkfx_out; |
1007 | end |
1008 | if (period_fx > (period / 2)) begin |
1009 | #(period_fx - (period / 2)); |
1010 | end |
1011 | end |
1012 | |
1013 | // |
1014 | // generate all output signal |
1015 | // |
1016 | |
1017 | always @(rst_in) |
1018 | if (rst_in) begin |
1019 | assign CLK0 = 0; |
1020 | assign CLK90 = 0; |
1021 | assign CLK180 = 0; |
1022 | assign CLK270 = 0; |
1023 | assign CLK2X = 0; |
1024 | assign CLK2X180 =0; |
1025 | assign CLKDV = 0; |
1026 | assign CLKFX = 0; |
1027 | assign CLKFX180 = 0; |
1028 | end |
1029 | else begin |
1030 | deassign CLK0; |
1031 | deassign CLK90; |
1032 | deassign CLK180; |
1033 | deassign CLK270; |
1034 | deassign CLK2X; |
1035 | deassign CLK2X180; |
1036 | deassign CLKDV; |
1037 | deassign CLKFX; |
1038 | deassign CLKFX180; |
1039 | end |
1040 | |
1041 | always @(clk0_out) begin |
1042 | CLK0 <= #(clkout_delay) clk0_out && (clkfb_type != 2'b00); |
1043 | CLK90 <= #(clkout_delay + period / 4) clk0_out && !dll_mode_type && (clkfb_type != 2'b00); |
1044 | CLK180 <= #(clkout_delay) ~clk0_out && (clkfb_type != 2'b00); |
1045 | CLK270 <= #(clkout_delay + period / 4) ~clk0_out && !dll_mode_type && (clkfb_type != 2'b00); |
1046 | end |
1047 | |
1048 | always @(clk2x_out) begin |
1049 | CLK2X <= #(clkout_delay) clk2x_out && !dll_mode_type && (clkfb_type != 2'b00); |
1050 | CLK2X180 <= #(clkout_delay) ~clk2x_out && !dll_mode_type && (clkfb_type != 2'b00); |
1051 | end |
1052 | |
1053 | always @(clkdv_out) |
1054 | CLKDV <= #(clkout_delay) clkdv_out && (clkfb_type != 2'b00); |
1055 | |
1056 | always @(clkfx_out ) |
1057 | CLKFX <= #(clkout_delay) clkfx_out; |
1058 | |
1059 | always @( clkfx_out or first_time_locked or locked_out) |
1060 | if ( ~first_time_locked) |
1061 | CLKFX180 = 0; |
1062 | else |
1063 | CLKFX180 <= #(clkout_delay) ~clkfx_out; |
1064 | |
1065 | |
1066 | endmodule |
1067 | |
1068 | ////////////////////////////////////////////////////// |
1069 | |
1070 | module dcm_sp_clock_divide_by_2 (clock, clock_type, clock_out, rst); |
1071 | input clock; |
1072 | input clock_type; |
1073 | input rst; |
1074 | output clock_out; |
1075 | |
1076 | reg clock_out; |
1077 | reg clock_div2; |
1078 | reg [2:0] rst_reg; |
1079 | wire clk_src; |
1080 | |
1081 | initial begin |
1082 | clock_out = 1'b0; |
1083 | clock_div2 = 1'b0; |
1084 | end |
1085 | |
1086 | always @(posedge clock) |
1087 | clock_div2 <= ~clock_div2; |
1088 | |
1089 | always @(posedge clock) begin |
1090 | rst_reg[0] <= rst; |
1091 | rst_reg[1] <= rst_reg[0] & rst; |
1092 | rst_reg[2] <= rst_reg[1] & rst_reg[0] & rst; |
1093 | end |
1094 | |
1095 | assign clk_src = (clock_type) ? clock_div2 : clock; |
1096 | |
1097 | always @(clk_src or rst or rst_reg) |
1098 | if (rst == 1'b0) |
1099 | clock_out = clk_src; |
1100 | else if (rst == 1'b1) begin |
1101 | clock_out = 1'b0; |
1102 | @(negedge rst_reg[2]); |
1103 | if (clk_src == 1'b1) |
1104 | @(negedge clk_src); |
1105 | end |
1106 | |
1107 | |
1108 | endmodule |
1109 | |
1110 | module dcm_sp_maximum_period_check (clock, rst); |
1111 | parameter clock_name = ""; |
1112 | parameter maximum_period = 0; |
1113 | input clock; |
1114 | input rst; |
1115 | |
1116 | time clock_edge; |
1117 | time clock_period; |
1118 | |
1119 | initial begin |
1120 | clock_edge = 0; |
1121 | clock_period = 0; |
1122 | end |
1123 | |
1124 | always @(posedge clock) begin |
1125 | clock_edge <= $time; |
1126 | // clock_period <= $time - clock_edge; |
1127 | clock_period = $time - clock_edge; |
1128 | if (clock_period > maximum_period ) begin |
1129 | if (rst == 0) |
1130 | $display(" Warning : Input clock period of %1.3f ns, on the %s port of instance %m exceeds allowed value of %1.3f ns at time %1.3f ns.", clock_period/1000.0, clock_name, maximum_period/1000.0, $time/1000.0); |
1131 | end |
1132 | end |
1133 | endmodule |
1134 | |
1135 | module dcm_sp_clock_lost (clock, enable, lost, rst); |
1136 | input clock; |
1137 | input enable; |
1138 | input rst; |
1139 | output lost; |
1140 | |
1141 | time clock_edge; |
1142 | reg [63:0] period; |
1143 | reg clock_low, clock_high; |
1144 | reg clock_posedge, clock_negedge; |
1145 | reg lost_r, lost_f, lost; |
1146 | reg clock_second_pos, clock_second_neg; |
1147 | |
1148 | initial begin |
1149 | clock_edge = 0; |
1150 | clock_high = 0; |
1151 | clock_low = 0; |
1152 | lost_r = 0; |
1153 | lost_f = 0; |
1154 | period = 0; |
1155 | clock_posedge = 0; |
1156 | clock_negedge = 0; |
1157 | clock_second_pos = 0; |
1158 | clock_second_neg = 0; |
1159 | end |
1160 | |
1161 | always @(posedge clock or posedge rst) |
1162 | if (rst==1) |
1163 | period <= 0; |
1164 | else begin |
1165 | clock_edge <= $time; |
1166 | if (period != 0 && (($time - clock_edge) <= (1.5 * period))) |
1167 | period <= $time - clock_edge; |
1168 | else if (period != 0 && (($time - clock_edge) > (1.5 * period))) |
1169 | period <= 0; |
1170 | else if ((period == 0) && (clock_edge != 0) && clock_second_pos == 1) |
1171 | period <= $time - clock_edge; |
1172 | end |
1173 | |
1174 | |
1175 | always @(posedge clock or posedge rst) |
1176 | if (rst) |
1177 | lost_r <= 0; |
1178 | else |
1179 | if (enable == 1 && clock_second_pos == 1) begin |
1180 | #1; |
1181 | if ( period != 0) |
1182 | lost_r <= 0; |
1183 | #((period * 9.1) / 10) |
1184 | if ((clock_low != 1'b1) && (clock_posedge != 1'b1) && rst == 0) |
1185 | lost_r <= 1; |
1186 | end |
1187 | |
1188 | always @(posedge clock or negedge clock or posedge rst) |
1189 | if (rst) begin |
1190 | clock_second_pos <= 0; |
1191 | clock_second_neg <= 0; |
1192 | end |
1193 | else if (clock) |
1194 | clock_second_pos <= 1; |
1195 | else if (~clock) |
1196 | clock_second_neg <= 1; |
1197 | |
1198 | always @(negedge clock or posedge rst) |
1199 | if (rst==1) begin |
1200 | lost_f <= 0; |
1201 | end |
1202 | else begin |
1203 | if (enable == 1 && clock_second_neg == 1) begin |
1204 | if ( period != 0) |
1205 | lost_f <= 0; |
1206 | #((period * 9.1) / 10) |
1207 | if ((clock_high != 1'b1) && (clock_negedge != 1'b1) && rst == 0) |
1208 | lost_f <= 1; |
1209 | end |
1210 | end |
1211 | |
1212 | always @( lost_r or lost_f or enable) |
1213 | begin |
1214 | if (enable == 1) |
1215 | lost = lost_r | lost_f; |
1216 | else |
1217 | lost = 0; |
1218 | end |
1219 | |
1220 | |
1221 | always @(posedge clock or negedge clock or posedge rst) |
1222 | if (rst==1) begin |
1223 | clock_low <= 1'b0; |
1224 | clock_high <= 1'b0; |
1225 | clock_posedge <= 1'b0; |
1226 | clock_negedge <= 1'b0; |
1227 | end |
1228 | else begin |
1229 | if (clock ==1) begin |
1230 | clock_low <= 1'b0; |
1231 | clock_high <= 1'b1; |
1232 | clock_posedge <= 1'b0; |
1233 | clock_negedge <= 1'b1; |
1234 | end |
1235 | else if (clock == 0) begin |
1236 | clock_low <= 1'b1; |
1237 | clock_high <= 1'b0; |
1238 | clock_posedge <= 1'b1; |
1239 | clock_negedge <= 1'b0; |
1240 | end |
1241 | end |
1242 | |
1243 | |
1244 | endmodule |
1245 |
Branches:
master