Root/Examples/sram_gpio/logic/sim/unisims/DCM_SP.v

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
32module 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
37parameter CLKDV_DIVIDE = 2.0;
38parameter integer CLKFX_DIVIDE = 1;
39parameter integer CLKFX_MULTIPLY = 4;
40parameter CLKIN_DIVIDE_BY_2 = "FALSE";
41parameter CLKIN_PERIOD = 10.0; // non-simulatable
42parameter CLKOUT_PHASE_SHIFT = "NONE";
43parameter CLK_FEEDBACK = "1X";
44parameter DESKEW_ADJUST = "SYSTEM_SYNCHRONOUS"; // non-simulatable
45parameter DFS_FREQUENCY_MODE = "LOW";
46parameter DLL_FREQUENCY_MODE = "LOW";
47parameter DSS_MODE = "NONE"; // non-simulatable
48parameter DUTY_CYCLE_CORRECTION = "TRUE";
49parameter FACTORY_JF = 16'hC080; // non-simulatable
50parameter integer MAXPERCLKIN = 1000000; // non-modifiable simulation parameter
51parameter integer MAXPERPSCLK = 100000000; // non-modifiable simulation parameter
52parameter integer PHASE_SHIFT = 0;
53parameter integer SIM_CLKIN_CYCLE_JITTER = 300; // non-modifiable simulation parameter
54parameter integer SIM_CLKIN_PERIOD_JITTER = 1000; // non-modifiable simulation parameter
55parameter STARTUP_WAIT = "FALSE"; // non-simulatable
56
57
58localparam PS_STEP = 25;
59
60input CLKFB, CLKIN, DSSEN;
61input PSCLK, PSEN, PSINCDEC, RST;
62
63output CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90;
64output CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE;
65output [7:0] STATUS;
66
67reg CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90;
68reg CLKDV, CLKFX, CLKFX180;
69
70wire locked_out_out;
71wire clkfb_in, clkin_in, dssen_in;
72wire psclk_in, psen_in, psincdec_in, rst_in;
73reg clk0_out;
74reg clk2x_out, clkdv_out;
75reg clkfx_out, clkfx180_en;
76reg rst_flag;
77reg locked_out, psdone_out, ps_overflow_out, ps_lock;
78reg clkfb_div, clkfb_chk, clkfb_div_en;
79integer clkdv_cnt;
80
81reg [1:0] clkfb_type;
82reg [8:0] divide_type;
83reg clkin_type;
84reg [1:0] ps_type;
85reg [3:0] deskew_adjust_mode;
86reg dfs_mode_type;
87reg dll_mode_type;
88reg clk1x_type;
89integer ps_in;
90
91reg lock_period, lock_delay, lock_clkin, lock_clkfb;
92reg first_time_locked;
93reg en_status;
94reg ps_overflow_out_ext;
95reg clkin_lost_out_ext;
96reg clkfx_lost_out_ext;
97reg [1:0] lock_out;
98reg lock_out1_neg;
99reg lock_fb, lock_ps, lock_ps_dly, lock_fb_dly, lock_fb_dly_tmp;
100reg fb_delay_found;
101reg clock_stopped;
102reg clkin_chkin, clkfb_chkin;
103
104wire chk_enable, chk_rst;
105wire clkin_div;
106wire lock_period_pulse;
107wire lock_period_dly, lock_period_dly1;
108
109reg clkin_ps, clkin_ps_tmp, clkin_ps_mkup, clkin_ps_mkup_win, clkin_ps_mkup_flag;
110reg clkin_fb;
111
112time FINE_SHIFT_RANGE;
113//time ps_delay, ps_delay_init, ps_delay_md, ps_delay_all, ps_max_range;
114integer ps_delay, ps_delay_init, ps_delay_md, ps_delay_all, ps_max_range;
115integer ps_delay_last;
116integer ps_acc;
117time clkin_edge;
118time clkin_div_edge;
119time clkin_ps_edge;
120time delay_edge;
121time clkin_period [2:0];
122time period;
123integer period_int, period_int2, period_int3, period_ps_tmp;
124time period_div;
125integer period_orig_int;
126time period_orig;
127time period_ps;
128time clkout_delay;
129time fb_delay;
130time period_fx, remain_fx;
131time period_dv_high, period_dv_low;
132time cycle_jitter, period_jitter;
133
134reg clkin_window, clkfb_window;
135reg [2:0] rst_reg;
136reg [12:0] numerator, denominator, gcd;
137reg [23:0] i, n, d, p;
138
139reg notifier;
140
141initial 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
148end
149
150initial 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
341end
342
343//
344// fx parameters
345//
346
347initial 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;
355end
356
357//
358// input wire delays
359//
360
361buf b_clkin (clkin_in, CLKIN);
362buf b_clkfb (clkfb_in, CLKFB);
363buf b_dssen (dssen_in, DSSEN);
364buf b_psclk (psclk_in, PSCLK);
365buf b_psen (psen_in, PSEN);
366buf b_psincdec (psincdec_in, PSINCDEC);
367buf b_rst (rst_in, RST);
368buf #100 b_LOCKED (LOCKED, locked_out_out);
369buf #100 b_PSDONE (PSDONE, psdone_out);
370buf b_ps_overflow (STATUS[0], ps_overflow_out_ext);
371buf b_clkin_lost (STATUS[1], clkin_lost_out_ext);
372buf b_clkfx_lost (STATUS[2], clkfx_lost_out_ext);
373
374assign STATUS[7:3] = 5'b0;
375
376dcm_sp_clock_divide_by_2 i_clock_divide_by_2 (clkin_in, clkin_type, clkin_div, rst_in);
377
378dcm_sp_maximum_period_check #("CLKIN", MAXPERCLKIN) i_max_clkin (clkin_in, rst_in);
379dcm_sp_maximum_period_check #("PSCLK", MAXPERPSCLK) i_max_psclk (psclk_in, rst_in);
380
381dcm_sp_clock_lost i_clkin_lost (clkin_in, first_time_locked, clkin_lost_out, rst_in);
382dcm_sp_clock_lost i_clkfx_lost (CLKFX, first_time_locked, clkfx_lost_out, rst_in);
383
384always @(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
397always @(posedge rst_in or posedge LOCKED)
398  if (rst_in == 1)
399      en_status <= 0;
400   else
401      en_status <= 1;
402
403
404always @(clkin_div)
405    clkin_ps_tmp <= #(ps_delay_md) clkin_div;
406
407always @(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
413always @(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;
422end
423
424always @(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
456end
457
458always @(clkin_ps or lock_fb)
459    clkin_fb = clkin_ps & lock_fb;
460
461always @(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
468always @(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
475always @(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
481always @(posedge clkin_fb or posedge chk_rst)
482    if (chk_rst)
483       clkin_chkin <= 0;
484    else
485       clkin_chkin <= 1;
486
487always @(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
497always @(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
511always @(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
525always @(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;
530end
531
532always @(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
539always @(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
549always @(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;
553end
554
555reg rst_tmp1, rst_tmp2;
556initial
557begin
558rst_tmp1 = 0;
559rst_tmp2 = 0;
560rst_flag = 0;
561end
562
563always @(rst_in)
564begin
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;
576end
577
578initial 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;
648end
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//
657always @(posedge locked_out)
658  if (first_time_locked == 0)
659          first_time_locked <= 1;
660
661//
662// phase shift parameters
663//
664
665always @(posedge lock_period)
666    ps_delay_init <= ps_in * period_orig /256;
667
668
669always @(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;
680end
681
682always @(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
689always @(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
726always @(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;
735end
736
737//
738// determine clock period
739//
740
741always @(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
765always @(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
810end
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)
821always @(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
847always @(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
855always @(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
863always @(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
875always @(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
887always @(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
897always @(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
911always @(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
922always @(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
942always @(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
959always @(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
985always @(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
990end
991
992always @(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
1017always @(rst_in)
1018if (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;
1028end
1029else 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;
1039end
1040
1041always @(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
1048always @(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);
1051end
1052
1053always @(clkdv_out)
1054    CLKDV <= #(clkout_delay) clkdv_out && (clkfb_type != 2'b00);
1055
1056always @(clkfx_out )
1057    CLKFX <= #(clkout_delay) clkfx_out;
1058
1059always @( 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
1066endmodule
1067
1068//////////////////////////////////////////////////////
1069
1070module dcm_sp_clock_divide_by_2 (clock, clock_type, clock_out, rst);
1071input clock;
1072input clock_type;
1073input rst;
1074output clock_out;
1075
1076reg clock_out;
1077reg clock_div2;
1078reg [2:0] rst_reg;
1079wire clk_src;
1080
1081initial begin
1082    clock_out = 1'b0;
1083    clock_div2 = 1'b0;
1084end
1085
1086always @(posedge clock)
1087    clock_div2 <= ~clock_div2;
1088
1089always @(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;
1093end
1094
1095assign clk_src = (clock_type) ? clock_div2 : clock;
1096
1097always @(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
1108endmodule
1109
1110module dcm_sp_maximum_period_check (clock, rst);
1111parameter clock_name = "";
1112parameter maximum_period = 0;
1113input clock;
1114input rst;
1115
1116time clock_edge;
1117time clock_period;
1118
1119initial begin
1120    clock_edge = 0;
1121    clock_period = 0;
1122end
1123
1124always @(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
1132end
1133endmodule
1134
1135module dcm_sp_clock_lost (clock, enable, lost, rst);
1136input clock;
1137input enable;
1138input rst;
1139output lost;
1140
1141time clock_edge;
1142reg [63:0] period;
1143reg clock_low, clock_high;
1144reg clock_posedge, clock_negedge;
1145reg lost_r, lost_f, lost;
1146reg clock_second_pos, clock_second_neg;
1147
1148initial 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;
1159end
1160
1161always @(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
1175always @(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
1188always @(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
1198always @(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
1212always @( lost_r or lost_f or enable)
1213begin
1214  if (enable == 1)
1215         lost = lost_r | lost_f;
1216  else
1217        lost = 0;
1218end
1219
1220
1221always @(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
1241end
1242
1243
1244endmodule
1245

Archive Download this file

Branches:
master



interactive