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

1// $Header: /devl/xcs/repo/env/Databases/CAEInterfaces/verunilibs/data/unisims/DCM.v,v 1.28.4.3 2007/04/11 20:32:09 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 Functional Simulation Library Component
11// / / Digital Clock Manager
12// /___/ /\ Filename : DCM.v
13// \ \ / \ Timestamp : Thu Mar 25 16:42:15 PST 2004
14// \___\/\___\
15//
16// Revision:
17// 03/23/04 - Initial version.
18// 04/11/05 - Initial all output signals.
19// 05/06/05 - Use assign/deassign to reset all output clocks. CR 207692.
20// 05/11/05 - Add clkin alignment check control to remove the glitch when
21// clkin stopped. (CR207409).
22// 05/25/05 - Seperate clock_second_pos and neg to another process due to
23// wait caused unreset. Set fb_delay_found after fb_delay computed.
24// Enable clkfb_div after lock_fb high (CR 208771)
25// 07/05/05 - Use counter to generate clkdv_out to align with clk0_out. (CR211465).
26// Add lock_fb_dly to alignment check. (CR210755).
27// 07/25/05 - Set CLKIN_PERIOD default to 10.0ns to (CR 213190).
28// 12/22/05 - LOCKED = x when RST less than 3 clock cycles (CR 222795)
29// 01/12/06 - Add rst_in to period_div and period_ps block to handle clkin frequency
30// change case. (CR 221989).
31// 02/28/06 - Add integer and real to parameter declaration.
32// 09/22/06 - Add lock_period and lock_fb to clkfb_div block (CR418722).
33// 12/19/06 - Add clkfb_div_en for clkfb2x divider (CR431210).
34// 04/06/07 - Enable the clock out in clock low time after reset in model
35// clock_divide_by_2 (CR 437471).
36// End Revision
37
38
39`ifndef NEW_DCM
40
41`timescale 1 ps / 1 ps
42
43module DCM (
44    CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90,
45    CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE, STATUS,
46    CLKFB, CLKIN, DSSEN, PSCLK, PSEN, PSINCDEC, RST);
47
48parameter CLKDV_DIVIDE = 2.0;
49parameter integer CLKFX_DIVIDE = 1;
50parameter integer CLKFX_MULTIPLY = 4;
51parameter CLKIN_DIVIDE_BY_2 = "FALSE";
52parameter CLKIN_PERIOD = 10.0; // non-simulatable
53parameter CLKOUT_PHASE_SHIFT = "NONE";
54parameter CLK_FEEDBACK = "1X";
55parameter DESKEW_ADJUST = "SYSTEM_SYNCHRONOUS"; // non-simulatable
56parameter DFS_FREQUENCY_MODE = "LOW";
57parameter DLL_FREQUENCY_MODE = "LOW";
58parameter DSS_MODE = "NONE"; // non-simulatable
59parameter DUTY_CYCLE_CORRECTION = "TRUE";
60parameter FACTORY_JF = 16'hC080; // non-simulatable
61parameter integer MAXPERCLKIN = 1000000; // non-modifiable simulation parameter
62parameter integer MAXPERPSCLK = 100000000; // non-modifiable simulation parameter
63parameter integer PHASE_SHIFT = 0;
64parameter integer SIM_CLKIN_CYCLE_JITTER = 300; // non-modifiable simulation parameter
65parameter integer SIM_CLKIN_PERIOD_JITTER = 1000; // non-modifiable simulation parameter
66parameter STARTUP_WAIT = "FALSE"; // non-simulatable
67
68input CLKFB, CLKIN, DSSEN;
69input PSCLK, PSEN, PSINCDEC, RST;
70
71output CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90;
72output CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE;
73output [7:0] STATUS;
74
75reg CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90;
76reg CLKDV, CLKFX, CLKFX180;
77
78wire locked_out_out;
79wire clkfb_in, clkin_in, dssen_in;
80wire psclk_in, psen_in, psincdec_in, rst_in;
81reg clk0_out;
82reg clk2x_out, clkdv_out;
83reg clkfx_out, clkfx180_en;
84reg rst_flag;
85reg locked_out, psdone_out, ps_overflow_out, ps_lock;
86reg clkfb_div, clkfb_chk, clkfb_div_en;
87integer clkdv_cnt;
88
89reg [1:0] clkfb_type;
90reg [8:0] divide_type;
91reg clkin_type;
92reg [1:0] ps_type;
93reg [3:0] deskew_adjust_mode;
94reg dfs_mode_type;
95reg dll_mode_type;
96reg clk1x_type;
97integer ps_in, ps_in_ps;
98
99reg lock_period, lock_delay, lock_clkin, lock_clkfb;
100reg first_time_locked;
101reg en_status;
102reg ps_overflow_out_ext;
103reg clkin_lost_out_ext;
104reg clkfx_lost_out_ext;
105reg [1:0] lock_out;
106reg lock_out1_neg;
107reg lock_fb, lock_ps, lock_ps_dly, lock_fb_dly, lock_fb_dly_tmp;
108reg fb_delay_found;
109reg clock_stopped;
110reg clkin_chkin, clkfb_chkin;
111
112wire chk_enable, chk_rst;
113wire clkin_div;
114wire lock_period_pulse;
115wire lock_period_dly;
116
117reg clkin_ps;
118reg clkin_fb;
119
120time FINE_SHIFT_RANGE;
121time ps_delay;
122time clkin_edge;
123time clkin_div_edge;
124time clkin_ps_edge;
125time delay_edge;
126time clkin_period [2:0];
127time period;
128time period_div;
129time period_orig;
130time period_ps;
131time clkout_delay;
132time fb_delay;
133time period_fx, remain_fx;
134time period_dv_high, period_dv_low;
135time cycle_jitter, period_jitter;
136
137reg clkin_window, clkfb_window;
138reg [2:0] rst_reg;
139reg [12:0] numerator, denominator, gcd;
140reg [23:0] i, n, d, p;
141
142reg notifier;
143
144initial begin
145    #1;
146    if ($realtime == 0) begin
147    $display ("Simulator Resolution Error : Simulator resolution is set to a value greater than 1 ps.");
148    $display ("In order to simulate the DCM, the simulator resolution must be set to 1ps or smaller.");
149    $finish;
150    end
151end
152
153initial begin
154    case (CLKDV_DIVIDE)
155    1.5 : divide_type = 'd3;
156    2.0 : divide_type = 'd4;
157    2.5 : divide_type = 'd5;
158    3.0 : divide_type = 'd6;
159    3.5 : divide_type = 'd7;
160    4.0 : divide_type = 'd8;
161    4.5 : divide_type = 'd9;
162    5.0 : divide_type = 'd10;
163    5.5 : divide_type = 'd11;
164    6.0 : divide_type = 'd12;
165    6.5 : divide_type = 'd13;
166    7.0 : divide_type = 'd14;
167    7.5 : divide_type = 'd15;
168    8.0 : divide_type = 'd16;
169    9.0 : divide_type = 'd18;
170    10.0 : divide_type = 'd20;
171    11.0 : divide_type = 'd22;
172    12.0 : divide_type = 'd24;
173    13.0 : divide_type = 'd26;
174    14.0 : divide_type = 'd28;
175    15.0 : divide_type = 'd30;
176    16.0 : divide_type = 'd32;
177    default : begin
178        $display("Attribute Syntax Error : The attribute CLKDV_DIVIDE on DCM 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);
179        $finish;
180    end
181    endcase
182
183    if ((CLKFX_DIVIDE <= 0) || (32 < CLKFX_DIVIDE)) begin
184    $display("Attribute Syntax Error : The attribute CLKFX_DIVIDE on DCM instance %m is set to %d. Legal values for this attribute are 1 ... 32.", CLKFX_DIVIDE);
185    $finish;
186    end
187
188    if ((CLKFX_MULTIPLY <= 1) || (32 < CLKFX_MULTIPLY)) begin
189    $display("Attribute Syntax Error : The attribute CLKFX_MULTIPLY on DCM instance %m is set to %d. Legal values for this attribute are 2 ... 32.", CLKFX_MULTIPLY);
190    $finish;
191    end
192
193    case (CLKIN_DIVIDE_BY_2)
194    "false" : clkin_type = 0;
195    "FALSE" : clkin_type = 0;
196    "true" : clkin_type = 1;
197    "TRUE" : clkin_type = 1;
198    default : begin
199        $display("Attribute Syntax Error : The attribute CLKIN_DIVIDE_BY_2 on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", CLKIN_DIVIDE_BY_2);
200        $finish;
201    end
202    endcase
203
204    case (CLKOUT_PHASE_SHIFT)
205    "NONE" : begin
206             ps_in = 256;
207             ps_type = 0;
208             end
209    "none" : begin
210             ps_in = 256;
211             ps_type = 0;
212             end
213    "FIXED" : begin
214             ps_in = PHASE_SHIFT + 256;
215             ps_type = 1;
216             end
217    "fixed" : begin
218             ps_in = PHASE_SHIFT + 256;
219             ps_type = 1;
220             end
221    "VARIABLE" : begin
222             ps_in = PHASE_SHIFT + 256;
223             ps_type = 2;
224             end
225    "variable" : begin
226             ps_in = PHASE_SHIFT + 256;
227             ps_type = 2;
228             end
229    default : begin
230        $display("Attribute Syntax Error : The attribute CLKOUT_PHASE_SHIFT on DCM instance %m is set to %s. Legal values for this attribute are NONE, FIXED or VARIABLE.", CLKOUT_PHASE_SHIFT);
231        $finish;
232    end
233    endcase
234
235    ps_in_ps = ps_in;
236
237    case (CLK_FEEDBACK)
238    "none" : clkfb_type = 2'b00;
239    "NONE" : clkfb_type = 2'b00;
240    "1x" : clkfb_type = 2'b01;
241    "1X" : clkfb_type = 2'b01;
242    "2x" : clkfb_type = 2'b10;
243    "2X" : clkfb_type = 2'b10;
244    default : begin
245        $display("Attribute Syntax Error : The attribute CLK_FEEDBACK on DCM instance %m is set to %s. Legal values for this attribute are NONE, 1X or 2X.", CLK_FEEDBACK);
246        $finish;
247    end
248    endcase
249
250    case (DESKEW_ADJUST)
251    "source_synchronous" : deskew_adjust_mode = 8;
252    "SOURCE_SYNCHRONOUS" : deskew_adjust_mode = 8;
253    "system_synchronous" : deskew_adjust_mode = 11;
254    "SYSTEM_SYNCHRONOUS" : deskew_adjust_mode = 11;
255    "0" : deskew_adjust_mode = 0;
256    "1" : deskew_adjust_mode = 1;
257    "2" : deskew_adjust_mode = 2;
258    "3" : deskew_adjust_mode = 3;
259    "4" : deskew_adjust_mode = 4;
260    "5" : deskew_adjust_mode = 5;
261    "6" : deskew_adjust_mode = 6;
262    "7" : deskew_adjust_mode = 7;
263    "8" : deskew_adjust_mode = 8;
264    "9" : deskew_adjust_mode = 9;
265    "10" : deskew_adjust_mode = 10;
266    "11" : deskew_adjust_mode = 11;
267    "12" : deskew_adjust_mode = 12;
268    "13" : deskew_adjust_mode = 13;
269    "14" : deskew_adjust_mode = 14;
270    "15" : deskew_adjust_mode = 15;
271    default : begin
272        $display("Attribute Syntax Error : The attribute DESKEW_ADJUST on DCM instance %m is set to %s. Legal values for this attribute are SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or 0 ... 15.", DESKEW_ADJUST);
273        $finish;
274    end
275    endcase
276
277    case (DFS_FREQUENCY_MODE)
278    "high" : dfs_mode_type = 1;
279    "HIGH" : dfs_mode_type = 1;
280    "low" : dfs_mode_type = 0;
281    "LOW" : dfs_mode_type = 0;
282    default : begin
283        $display("Attribute Syntax Error : The attribute DFS_FREQUENCY_MODE on DCM instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DFS_FREQUENCY_MODE);
284        $finish;
285    end
286    endcase
287
288    period_jitter = SIM_CLKIN_PERIOD_JITTER;
289    cycle_jitter = SIM_CLKIN_CYCLE_JITTER;
290
291    case (DLL_FREQUENCY_MODE)
292    "high" : dll_mode_type = 1;
293    "HIGH" : dll_mode_type = 1;
294    "low" : dll_mode_type = 0;
295    "LOW" : dll_mode_type = 0;
296    default : begin
297        $display("Attribute Syntax Error : The attribute DLL_FREQUENCY_MODE on DCM instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DLL_FREQUENCY_MODE);
298        $finish;
299    end
300    endcase
301
302    if ((dll_mode_type ==1) && (clkfb_type == 2'b10)) begin
303        $display("Attribute Syntax Error : The attributes DLL_FREQUENCY_MODE on DCM 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);
304           $finish;
305    end
306
307    case (DSS_MODE)
308    "none" : ;
309    "NONE" : ;
310    default : begin
311        $display("Attribute Syntax Error : The attribute DSS_MODE on DCM instance %m is set to %s. Legal values for this attribute is NONE.", DSS_MODE);
312        $finish;
313    end
314    endcase
315
316    case (DUTY_CYCLE_CORRECTION)
317    "false" : clk1x_type = 0;
318    "FALSE" : clk1x_type = 0;
319    "true" : clk1x_type = 1;
320    "TRUE" : clk1x_type = 1;
321    default : begin
322        $display("Attribute Syntax Error : The attribute DUTY_CYCLE_CORRECTION on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", DUTY_CYCLE_CORRECTION);
323        $finish;
324    end
325    endcase
326
327    if ((PHASE_SHIFT < -255) || (PHASE_SHIFT > 255)) begin
328    $display("Attribute Syntax Error : The attribute PHASE_SHIFT on DCM instance %m is set to %d. Legal values for this attribute are -255 ... 255.", PHASE_SHIFT);
329    $display("Error : PHASE_SHIFT = %d is not -255 ... 255.", PHASE_SHIFT);
330    $finish;
331    end
332
333    case (STARTUP_WAIT)
334    "false" : ;
335    "FALSE" : ;
336    "true" : ;
337    "TRUE" : ;
338    default : begin
339        $display("Attribute Syntax Error : The attribute STARTUP_WAIT on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", STARTUP_WAIT);
340        $finish;
341    end
342    endcase
343end
344
345//
346// fx parameters
347//
348
349initial begin
350    gcd = 1;
351    for (i = 2; i <= CLKFX_MULTIPLY; i = i + 1) begin
352    if (((CLKFX_MULTIPLY % i) == 0) && ((CLKFX_DIVIDE % i) == 0))
353        gcd = i;
354    end
355    numerator = CLKFX_MULTIPLY / gcd;
356    denominator = CLKFX_DIVIDE / gcd;
357end
358
359//
360// input wire delays
361//
362
363buf b_clkin (clkin_in, CLKIN);
364buf b_clkfb (clkfb_in, CLKFB);
365buf b_dssen (dssen_in, DSSEN);
366buf b_psclk (psclk_in, PSCLK);
367buf b_psen (psen_in, PSEN);
368buf b_psincdec (psincdec_in, PSINCDEC);
369buf b_rst (rst_in, RST);
370buf #100 b_locked (LOCKED, locked_out_out);
371buf #100 b_psdone (PSDONE, psdone_out);
372buf b_ps_overflow (STATUS[0], ps_overflow_out_ext);
373buf b_clkin_lost (STATUS[1], clkin_lost_out_ext);
374buf b_clkfx_lost (STATUS[2], clkfx_lost_out_ext);
375
376assign STATUS[7:3] = 5'b0;
377
378dcm_clock_divide_by_2 i_clock_divide_by_2 (clkin_in, clkin_type, clkin_div, rst_in);
379
380dcm_maximum_period_check #("CLKIN", MAXPERCLKIN) i_max_clkin (clkin_in);
381dcm_maximum_period_check #("PSCLK", MAXPERPSCLK) i_max_psclk (psclk_in);
382
383dcm_clock_lost i_clkin_lost (clkin_in, first_time_locked, clkin_lost_out, rst_in);
384dcm_clock_lost i_clkfx_lost (CLKFX, first_time_locked, clkfx_lost_out, rst_in);
385
386always @(rst_in or en_status or clkfx_lost_out or clkin_lost_out or ps_overflow_out)
387   if (rst_in == 1 || en_status == 0) begin
388       ps_overflow_out_ext = 0;
389       clkin_lost_out_ext = 0;
390       clkfx_lost_out_ext = 0;
391    end
392   else
393   begin
394      ps_overflow_out_ext = ps_overflow_out;
395      clkin_lost_out_ext = clkin_lost_out;
396      clkfx_lost_out_ext = clkfx_lost_out;
397   end
398
399always @(posedge rst_in or posedge LOCKED)
400  if (rst_in == 1)
401      en_status <= 0;
402   else
403      en_status <= 1;
404
405
406always @(clkin_div)
407    clkin_ps <= #(ps_delay) clkin_div;
408
409always @(clkin_ps or lock_fb)
410    clkin_fb = clkin_ps & lock_fb;
411
412
413always @(negedge clkfb_in or posedge rst_in)
414    if (rst_in)
415        clkfb_div_en <= 0;
416    else
417       if (lock_fb_dly && lock_period && lock_fb && ~clkin_ps)
418          clkfb_div_en <= 1;
419
420always @(posedge clkfb_in or posedge rst_in)
421    if (rst_in)
422        clkfb_div <= 0;
423    else
424      if (clkfb_div_en )
425        clkfb_div <= ~clkfb_div;
426
427always @(clkfb_in or clkfb_div)
428    if (clkfb_type == 2'b10 )
429         clkfb_chk = clkfb_div;
430    else
431         clkfb_chk = clkfb_in & lock_fb_dly;
432
433always @(posedge clkin_fb or posedge chk_rst)
434    if (chk_rst)
435       clkin_chkin <= 0;
436    else
437       clkin_chkin <= 1;
438
439always @(posedge clkfb_chk or posedge chk_rst)
440    if (chk_rst)
441       clkfb_chkin <= 0;
442    else
443       clkfb_chkin <= 1;
444
445    assign chk_rst = (rst_in==1 || clock_stopped==1 ) ? 1 : 0;
446    assign chk_enable = (clkin_chkin == 1 && clkfb_chkin == 1 &&
447                         lock_ps ==1 && lock_fb ==1 && lock_fb_dly == 1) ? 1 : 0;
448
449always @(posedge clkin_div or posedge rst_in)
450  if (rst_in) begin
451     period_div <= 0;
452     clkin_div_edge <= 0;
453   end
454  else
455   if ( clkin_div ==1 ) begin
456      clkin_div_edge <= $time;
457      if (($time - clkin_div_edge) <= (1.5 * period_div))
458      period_div <= $time - clkin_div_edge;
459      else if ((period_div == 0) && (clkin_div_edge != 0))
460      period_div <= $time - clkin_div_edge;
461   end
462
463always @(posedge clkin_ps or posedge rst_in)
464  if (rst_in) begin
465        period_ps <= 0;
466        clkin_ps_edge <= 0;
467  end
468  else
469  if (clkin_ps == 1 ) begin
470    clkin_ps_edge <= $time;
471    if (($time - clkin_ps_edge) <= (1.5 * period_ps))
472    period_ps <= $time - clkin_ps_edge;
473    else if ((period_ps == 0) && (clkin_ps_edge != 0))
474    period_ps <= $time - clkin_ps_edge;
475 end
476
477always @(posedge clkin_ps) begin
478    lock_ps <= lock_period;
479    lock_ps_dly <= lock_ps;
480    lock_fb <= lock_ps_dly;
481    lock_fb_dly_tmp <= lock_fb;
482end
483
484always @(negedge clkin_ps or posedge rst_in)
485  if (rst_in)
486    lock_fb_dly <= 1'b0;
487  else
488// lock_fb_dly <= #(period/4) lock_fb_dly_tmp;
489    lock_fb_dly <= #(period * 0.75) lock_fb_dly_tmp;
490
491
492always @(period or fb_delay )
493  if (fb_delay == 0)
494    clkout_delay = 0;
495  else
496    clkout_delay = period - fb_delay;
497
498//
499// generate master reset signal
500//
501
502always @(posedge clkin_in) begin
503    rst_reg[0] <= rst_in;
504    rst_reg[1] <= rst_reg[0] & rst_in;
505    rst_reg[2] <= rst_reg[1] & rst_reg[0] & rst_in;
506end
507
508reg rst_tmp1, rst_tmp2;
509initial
510begin
511rst_tmp1 = 0;
512rst_tmp2 = 0;
513rst_flag = 0;
514end
515
516always @(rst_in)
517begin
518   if (rst_in)
519       rst_flag = 0;
520
521   rst_tmp1 = rst_in;
522   if (rst_tmp1 == 0 && rst_tmp2 == 1) begin
523      if ((rst_reg[2] & rst_reg[1] & rst_reg[0]) == 0) begin
524         rst_flag = 1;
525    $display("Input Error : RST on instance %m must be asserted for 3 CLKIN clock cycles.");
526      end
527   end
528   rst_tmp2 = rst_tmp1;
529end
530
531initial begin
532    CLK0 = 0;
533    CLK180 = 0;
534    CLK270 = 0;
535    CLK2X = 0;
536    CLK2X180 = 0;
537    CLK90 = 0;
538    CLKDV = 0;
539    CLKFX = 0;
540    CLKFX180 = 0;
541    clk0_out = 0;
542    clk2x_out = 0;
543    clkdv_out = 0;
544    clkdv_cnt = 0;
545    clkfb_window = 0;
546    clkfx_out = 0;
547    clkfx180_en = 0;
548    clkin_div_edge = 0;
549    clkin_period[0] = 0;
550    clkin_period[1] = 0;
551    clkin_period[2] = 0;
552    clkin_edge = 0;
553    clkin_ps_edge = 0;
554    clkin_window = 0;
555    clkout_delay = 0;
556    clock_stopped = 1;
557    fb_delay = 0;
558    fb_delay_found = 0;
559    lock_clkfb = 0;
560    lock_clkin = 0;
561    lock_delay = 0;
562    lock_fb = 0;
563    lock_fb_dly = 0;
564    lock_out = 2'b00;
565    lock_out1_neg = 0;
566    lock_period = 0;
567    lock_ps = 0;
568    lock_ps_dly = 0;
569    locked_out = 0;
570    period = 0;
571    period_div = 0;
572    period_fx = 0;
573    period_orig = 0;
574    period_ps = 0;
575    psdone_out = 0;
576    ps_delay = 0;
577    ps_lock = 0;
578    ps_overflow_out = 0;
579    ps_overflow_out_ext = 0;
580    clkin_lost_out_ext = 0;
581    clkfx_lost_out_ext = 0;
582    rst_reg = 3'b000;
583    first_time_locked = 0;
584    en_status = 0;
585    clkfb_div = 0;
586    clkin_chkin = 0;
587    clkfb_chkin = 0;
588end
589
590// RST less than 3 cycles, lock = x
591
592  assign locked_out_out = (rst_flag) ? 1'bx : locked_out;
593
594//
595// detect_first_time_locked
596//
597always @(posedge locked_out)
598  if (first_time_locked == 0)
599          first_time_locked <= 1;
600
601//
602// phase shift parameters
603//
604
605always @(posedge lock_period) begin
606    if (ps_type == 2'b01)
607    FINE_SHIFT_RANGE = 10000;
608    else if (ps_type == 2'b10)
609    FINE_SHIFT_RANGE = 5000;
610    if (PHASE_SHIFT > 0) begin
611    if ((ps_in * period_orig / 256) > period_orig + FINE_SHIFT_RANGE) begin
612        $display("Function Error : Instance %m Requested Phase Shift = PHASE_SHIFT * PERIOD / 256 = %d * %1.3f / 256 = %1.3f. This exceeds the FINE_SHIFT_RANGE of %1.3f ns.", PHASE_SHIFT, period_orig / 1000.0, PHASE_SHIFT * period_orig / 256 / 1000.0, FINE_SHIFT_RANGE / 1000.0);
613          $finish;
614    end
615    end
616    else if (PHASE_SHIFT < 0) begin
617    if ((period_orig > FINE_SHIFT_RANGE) &&
618        ((ps_in * period_orig / 256) < period_orig - FINE_SHIFT_RANGE)) begin
619        $display("Function Error : Instance %m Requested Phase Shift = PHASE_SHIFT * PERIOD / 256 = %d * %1.3f / 256 = %1.3f. This exceeds the FINE_SHIFT_RANGE of %1.3f ns.", PHASE_SHIFT, period_orig / 1000.0, -(PHASE_SHIFT) * period_orig / 256 / 1000.0, FINE_SHIFT_RANGE / 1000.0);
620          $finish;
621    end
622    end
623end
624
625always @(posedge lock_period_pulse or posedge rst_in or ps_in_ps)
626  if (rst_in) begin
627     ps_delay <= 0;
628  end
629  else if (lock_period_pulse) begin
630          ps_delay <= (ps_in * period_div / 256);
631  end
632  else begin
633    if (ps_type == 2'b10 && ps_lock ==1)
634     begin
635          ps_delay = (ps_in_ps * period_div / 256);
636     end
637  end
638
639
640always @(posedge psclk_in or rst_in)
641  if (rst_in) begin
642     ps_in_ps <= ps_in;
643     ps_overflow_out <= 0;
644  end
645  else begin
646    if (ps_type == 2'b10)
647    if (psen_in)
648        if (ps_lock == 1)
649          $display(" Warning : Please wait for PSDONE signal before adjusting the Phase Shift.");
650        else
651        if (psincdec_in == 1) begin
652        if (ps_in_ps == 511)
653            ps_overflow_out <= 1;
654        else if (((ps_in_ps + 1) * period_orig / 256) > period_orig + FINE_SHIFT_RANGE)
655            ps_overflow_out <= 1;
656        else begin
657            ps_in_ps <= ps_in_ps + 1;
658            ps_overflow_out <= 0;
659        end
660        ps_lock <= 1;
661        end
662        else if (psincdec_in == 0) begin
663        if (ps_in_ps == 1)
664            ps_overflow_out <= 1;
665        else if ((period_orig > FINE_SHIFT_RANGE) &&
666             (((ps_in_ps - 1) * period_orig / 256) < period_orig - FINE_SHIFT_RANGE))
667              ps_overflow_out <= 1;
668        else begin
669            ps_in_ps <= ps_in_ps - 1;
670            ps_overflow_out <= 0;
671        end
672        ps_lock <= 1;
673        end
674end
675
676always @(posedge ps_lock) begin
677    @(posedge clkin_ps)
678    @(posedge psclk_in)
679    @(posedge psclk_in)
680    @(posedge psclk_in)
681    psdone_out <= 1;
682    @(posedge psclk_in)
683    psdone_out <= 0;
684    ps_lock <= 0;
685end
686
687//
688// determine clock period
689//
690
691always @(posedge clkin_div or negedge clkin_div or posedge rst_in)
692  if (rst_in == 1) begin
693    clkin_period[0] <= 0;
694    clkin_period[1] <= 0;
695    clkin_period[2] <= 0;
696    clkin_edge <= 0;
697  end
698  else
699  if (clkin_div == 1) begin
700    clkin_edge <= $time;
701    clkin_period[2] <= clkin_period[1];
702    clkin_period[1] <= clkin_period[0];
703    if (clkin_edge != 0)
704    clkin_period[0] <= $time - clkin_edge;
705  end
706  else if (clkin_div == 0)
707      if (lock_period == 1)
708        if (100000000 < clkin_period[0]/1000)
709        begin
710        end
711        else if ((period_orig * 2 < clkin_period[0]) && (clock_stopped == 0)) begin
712          clkin_period[0] <= clkin_period[1];
713        end
714
715always @(negedge clkin_div or posedge rst_in)
716  if (rst_in == 1) begin
717      lock_period <= 0;
718      clock_stopped <= 1;
719  end
720  else begin
721    if (lock_period == 1'b0) begin
722    if ((clkin_period[0] != 0) &&
723        (clkin_period[0] - cycle_jitter <= clkin_period[1]) &&
724        (clkin_period[1] <= clkin_period[0] + cycle_jitter) &&
725        (clkin_period[1] - cycle_jitter <= clkin_period[2]) &&
726        (clkin_period[2] <= clkin_period[1] + cycle_jitter)) begin
727        lock_period <= 1;
728        period_orig <= (clkin_period[0] +
729                clkin_period[1] +
730                clkin_period[2]) / 3;
731        period <= clkin_period[0];
732    end
733    end
734    else if (lock_period == 1'b1) begin
735    if (100000000 < (clkin_period[0] / 1000)) begin
736        $display(" Warning : CLKIN stopped toggling on instance %m exceeds %d ms. Current CLKIN Period = %1.3f ns.", 100, clkin_period[0] / 1000.0);
737        lock_period <= 0;
738        @(negedge rst_reg[2]);
739    end
740    else if ((period_orig * 2 < clkin_period[0]) && clock_stopped == 1'b0) begin
741        clock_stopped <= 1'b1;
742    end
743    else if ((clkin_period[0] < period_orig - period_jitter) ||
744        (period_orig + period_jitter < clkin_period[0])) begin
745        $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);
746        lock_period <= 0;
747        @(negedge rst_reg[2]);
748    end
749    else if ((clkin_period[0] < clkin_period[1] - cycle_jitter) ||
750        (clkin_period[1] + cycle_jitter < clkin_period[0])) begin
751        $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);
752        lock_period <= 0;
753        @(negedge rst_reg[2]);
754    end
755    else begin
756        period <= clkin_period[0];
757        clock_stopped <= 1'b0;
758    end
759    end
760end
761
762  assign #(period/2) lock_period_dly = lock_period;
763  assign lock_period_pulse = (lock_period==1 && lock_period_dly==0) ? 1 : 0;
764
765//
766// determine clock delay
767//
768
769//always @(posedge lock_period or posedge rst_in)
770always @(posedge lock_ps_dly or posedge rst_in)
771  if (rst_in) begin
772    fb_delay <= 0;
773    fb_delay_found <= 0;
774  end
775  else begin
776    if (lock_period && clkfb_type != 2'b00) begin
777    if (clkfb_type == 2'b01) begin
778        @(posedge CLK0 or rst_in)
779        delay_edge = $time;
780    end
781    else if (clkfb_type == 2'b10) begin
782        @(posedge CLK2X or rst_in)
783        delay_edge = $time;
784    end
785    @(posedge clkfb_in or rst_in) begin
786     fb_delay <= ($time - delay_edge) % period_orig;
787         fb_delay_found <= 1;
788       end
789    end
790  end
791
792//
793// determine feedback lock
794//
795
796//always @(posedge clkfb_in or posedge rst_in)
797always @(posedge clkfb_chk or posedge rst_in)
798  if (rst_in)
799      clkfb_window <= 0;
800  else begin
801      clkfb_window <= 1;
802    #cycle_jitter clkfb_window <= 0;
803  end
804
805always @(posedge clkin_fb or posedge rst_in)
806  if (rst_in)
807      clkin_window <= 0;
808  else begin
809      clkin_window <= 1;
810    #cycle_jitter clkin_window <= 0;
811  end
812
813always @(posedge clkin_fb or posedge rst_in)
814  if (rst_in)
815     lock_clkin <= 0;
816  else begin
817    #1
818    if ((clkfb_window && fb_delay_found) || (clkin_lost_out == 1'b1 && lock_out[0]==1'b1))
819    lock_clkin <= 1;
820    else
821       if (chk_enable==1)
822     lock_clkin <= 0;
823  end
824
825always @(posedge clkfb_chk or posedge rst_in)
826  if (rst_in)
827    lock_clkfb <= 0;
828  else begin
829    #1
830    if ((clkin_window && fb_delay_found) || (clkin_lost_out == 1'b1 && lock_out[0]==1'b1))
831    lock_clkfb <= 1;
832    else
833       if (chk_enable ==1)
834    lock_clkfb <= 0;
835  end
836
837always @(negedge clkin_fb or posedge rst_in)
838  if (rst_in)
839    lock_delay <= 0;
840  else
841    lock_delay <= lock_clkin || lock_clkfb;
842
843//
844// generate lock signal
845//
846
847always @(posedge clkin_ps or posedge rst_in)
848  if (rst_in) begin
849      lock_out <= 2'b0;
850      locked_out <=0;
851  end
852  else begin
853    if (clkfb_type == 2'b00)
854    lock_out[0] <= lock_period;
855    else
856    lock_out[0] <= lock_period & lock_delay & lock_fb;
857    lock_out[1] <= lock_out[0];
858    locked_out <= lock_out[1];
859  end
860
861always @(negedge clkin_ps or posedge rst_in)
862  if (rst_in)
863    lock_out1_neg <= 0;
864  else
865    lock_out1_neg <= lock_out[1];
866
867
868//
869// generate the clk1x_out
870//
871
872always @(posedge clkin_ps or negedge clkin_ps or posedge rst_in)
873  if (rst_in)
874      clk0_out <= 0;
875  else
876    if (clkin_ps ==1)
877       if (clk1x_type==1 && lock_out[0]) begin
878          clk0_out <= 1;
879          #(period / 2)
880             clk0_out <= 0;
881       end
882       else
883          clk0_out <= 1;
884    else
885      if (clkin_ps == 0 && ((clk1x_type && lock_out[0]) == 0 || (lock_out[0]== 1 && lock_out[1]== 0)))
886          clk0_out <= 0;
887
888//
889// generate the clk2x_out
890//
891
892always @(posedge clkin_ps or posedge rst_in)
893  if (rst_in)
894     clk2x_out <= 0;
895  else begin
896    clk2x_out <= 1;
897    #(period / 4)
898    clk2x_out <= 0;
899    #(period / 4)
900    clk2x_out <= 1;
901    #(period / 4)
902    clk2x_out <= 0;
903 end
904
905//
906// generate the clkdv_out
907//
908
909always @(posedge clkin_ps or negedge clkin_ps or posedge rst_in)
910  if (rst_in) begin
911       clkdv_out <= 1'b0;
912       clkdv_cnt <= 0;
913  end
914  else
915    if (lock_out1_neg) begin
916      if (clkdv_cnt >= divide_type -1)
917           clkdv_cnt <= 0;
918      else
919           clkdv_cnt <= clkdv_cnt + 1;
920
921      if (clkdv_cnt < divide_type /2)
922          clkdv_out <= 1'b1;
923      else
924         if ( (divide_type[0] == 1'b1) && dll_mode_type == 1'b0)
925             clkdv_out <= #(period/4) 1'b0;
926         else
927            clkdv_out <= 1'b0;
928    end
929
930
931//
932// generate fx output signal
933//
934
935always @(lock_period or period or denominator or numerator) begin
936    if (lock_period == 1'b1) begin
937    period_fx = (period * denominator) / (numerator * 2);
938    remain_fx = (period * denominator) % (numerator * 2);
939    end
940end
941
942always @(posedge clkin_ps or posedge clkin_lost_out or posedge rst_in )
943    if (rst_in == 1)
944       clkfx_out = 1'b0;
945    else if (clkin_lost_out == 1'b1 ) begin
946           if (locked_out == 1)
947            @(negedge rst_reg[2]);
948        end
949    else
950      if (lock_out[1] == 1) begin
951    clkfx_out = 1'b1;
952    for (p = 0; p < (numerator * 2 - 1); p = p + 1) begin
953        #(period_fx);
954            if (p < remain_fx)
955                #1;
956        clkfx_out = !clkfx_out;
957    end
958    if (period_fx > (period / 2)) begin
959        #(period_fx - (period / 2));
960    end
961      end
962
963//
964// generate all output signal
965//
966
967always @(rst_in)
968if (rst_in) begin
969   assign CLK0 = 0;
970   assign CLK90 = 0;
971   assign CLK180 = 0;
972   assign CLK270 = 0;
973   assign CLK2X = 0;
974   assign CLK2X180 =0;
975   assign CLKDV = 0;
976   assign CLKFX = 0;
977   assign CLKFX180 = 0;
978end
979else begin
980   deassign CLK0;
981   deassign CLK90;
982   deassign CLK180;
983   deassign CLK270;
984   deassign CLK2X;
985   deassign CLK2X180;
986   deassign CLKDV;
987   deassign CLKFX;
988   deassign CLKFX180;
989end
990
991always @(clk0_out) begin
992    CLK0 <= #(clkout_delay) clk0_out && (clkfb_type != 2'b00);
993    CLK90 <= #(clkout_delay + period / 4) clk0_out && !dll_mode_type && (clkfb_type != 2'b00);
994    CLK180 <= #(clkout_delay) ~clk0_out && (clkfb_type != 2'b00);
995    CLK270 <= #(clkout_delay + period / 4) ~clk0_out && !dll_mode_type && (clkfb_type != 2'b00);
996  end
997
998always @(clk2x_out) begin
999    CLK2X <= #(clkout_delay) clk2x_out && !dll_mode_type && (clkfb_type != 2'b00);
1000     CLK2X180 <= #(clkout_delay) ~clk2x_out && !dll_mode_type && (clkfb_type != 2'b00);
1001end
1002
1003always @(clkdv_out)
1004    CLKDV <= #(clkout_delay) clkdv_out && (clkfb_type != 2'b00);
1005
1006always @(clkfx_out )
1007    CLKFX <= #(clkout_delay) clkfx_out;
1008
1009always @( clkfx_out or first_time_locked or locked_out)
1010  if ( ~first_time_locked)
1011     CLKFX180 = 0;
1012  else
1013     CLKFX180 <= #(clkout_delay) ~clkfx_out;
1014
1015
1016endmodule
1017
1018//////////////////////////////////////////////////////
1019
1020module dcm_clock_divide_by_2 (clock, clock_type, clock_out, rst);
1021input clock;
1022input clock_type;
1023input rst;
1024output clock_out;
1025
1026reg clock_out;
1027reg clock_div2;
1028reg [2:0] rst_reg;
1029
1030wire clk_src;
1031
1032initial begin
1033    clock_out = 1'b0;
1034    clock_div2 = 1'b0;
1035end
1036
1037always @(posedge clock)
1038    clock_div2 <= ~clock_div2;
1039
1040always @(posedge clock) begin
1041    rst_reg[0] <= rst;
1042    rst_reg[1] <= rst_reg[0] & rst;
1043    rst_reg[2] <= rst_reg[1] & rst_reg[0] & rst;
1044end
1045
1046assign clk_src = (clock_type) ? clock_div2 : clock;
1047
1048always @(clk_src or rst or rst_reg)
1049    if (rst == 1'b0)
1050        clock_out = clk_src;
1051    else if (rst == 1'b1) begin
1052        clock_out = 1'b0;
1053        @(negedge rst_reg[2]);
1054        if (clk_src == 1'b1)
1055          @(negedge clk_src);
1056    end
1057
1058
1059endmodule
1060
1061module dcm_maximum_period_check (clock);
1062parameter clock_name = "";
1063parameter maximum_period = 0;
1064input clock;
1065
1066time clock_edge;
1067time clock_period;
1068
1069initial begin
1070    clock_edge = 0;
1071    clock_period = 0;
1072end
1073
1074always @(posedge clock) begin
1075    clock_edge <= $time;
1076    clock_period <= $time - clock_edge;
1077    if (clock_period > maximum_period ) begin
1078    $display(" Warning : Input clock period of, %1.3f ns, on the %s port of instance %m exceeds allotted value of %1.3f ns at simulation time %1.3f ns.", clock_period/1000.0, clock_name, maximum_period/1000.0, $time/1000.0);
1079    end
1080end
1081endmodule
1082
1083module dcm_clock_lost (clock, enable, lost, rst);
1084input clock;
1085input enable;
1086input rst;
1087output lost;
1088
1089time clock_edge;
1090reg [63:0] period;
1091reg clock_low, clock_high;
1092reg clock_posedge, clock_negedge;
1093reg lost_r, lost_f, lost;
1094reg clock_second_pos, clock_second_neg;
1095
1096initial begin
1097    clock_edge = 0;
1098    clock_high = 0;
1099    clock_low = 0;
1100    lost_r = 0;
1101    lost_f = 0;
1102    period = 0;
1103    clock_posedge = 0;
1104    clock_negedge = 0;
1105    clock_second_pos = 0;
1106    clock_second_neg = 0;
1107end
1108
1109always @(posedge clock or posedge rst)
1110  if (rst==1)
1111    period <= 0;
1112  else begin
1113    clock_edge <= $time;
1114    if (period != 0 && (($time - clock_edge) <= (1.5 * period)))
1115        period <= $time - clock_edge;
1116    else if (period != 0 && (($time - clock_edge) > (1.5 * period)))
1117        period <= 0;
1118    else if ((period == 0) && (clock_edge != 0) && clock_second_pos == 1)
1119        period <= $time - clock_edge;
1120  end
1121
1122
1123always @(posedge clock or posedge rst)
1124  if (rst)
1125    lost_r <= 0;
1126  else
1127  if (enable == 1 && clock_second_pos == 1) begin
1128      #1;
1129      if ( period != 0)
1130         lost_r <= 0;
1131      #((period * 9.1) / 10)
1132      if ((clock_low != 1'b1) && (clock_posedge != 1'b1) && rst == 0)
1133        lost_r <= 1;
1134    end
1135
1136always @(posedge clock or negedge clock or posedge rst)
1137  if (rst) begin
1138     clock_second_pos <= 0;
1139     clock_second_neg <= 0;
1140  end
1141  else if (clock)
1142     clock_second_pos <= 1;
1143  else if (~clock)
1144     clock_second_neg <= 1;
1145
1146always @(negedge clock or posedge rst)
1147  if (rst==1) begin
1148     lost_f <= 0;
1149   end
1150   else begin
1151     if (enable == 1 && clock_second_neg == 1) begin
1152      if ( period != 0)
1153        lost_f <= 0;
1154      #((period * 9.1) / 10)
1155      if ((clock_high != 1'b1) && (clock_negedge != 1'b1) && rst == 0)
1156        lost_f <= 1;
1157    end
1158  end
1159
1160always @( lost_r or lost_f or enable)
1161begin
1162  if (enable == 1)
1163         lost = lost_r | lost_f;
1164  else
1165        lost = 0;
1166end
1167
1168
1169always @(posedge clock or negedge clock or posedge rst)
1170  if (rst==1) begin
1171           clock_low <= 1'b0;
1172           clock_high <= 1'b0;
1173           clock_posedge <= 1'b0;
1174           clock_negedge <= 1'b0;
1175  end
1176  else begin
1177    if (clock ==1) begin
1178           clock_low <= 1'b0;
1179           clock_high <= 1'b1;
1180           clock_posedge <= 1'b0;
1181           clock_negedge <= 1'b1;
1182    end
1183    else if (clock == 0) begin
1184           clock_low <= 1'b1;
1185           clock_high <= 1'b0;
1186           clock_posedge <= 1'b1;
1187           clock_negedge <= 1'b0;
1188    end
1189end
1190
1191
1192endmodule
1193
1194`else
1195
1196
1197`timescale 1 ps / 1 ps
1198
1199module DCM (
1200    CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90,
1201    CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE, STATUS,
1202    CLKFB, CLKIN, DSSEN, PSCLK, PSEN, PSINCDEC, RST);
1203
1204   parameter real CLKDV_DIVIDE = 2.0;
1205   parameter integer CLKFX_DIVIDE = 1;
1206   parameter integer CLKFX_MULTIPLY = 4;
1207   parameter CLKIN_DIVIDE_BY_2 = "FALSE";
1208   parameter real CLKIN_PERIOD = 10.0;
1209   parameter CLKOUT_PHASE_SHIFT = "NONE";
1210   parameter CLK_FEEDBACK = "1X";
1211   parameter DESKEW_ADJUST = "SYSTEM_SYNCHRONOUS";
1212   parameter DFS_FREQUENCY_MODE = "LOW";
1213   parameter DLL_FREQUENCY_MODE = "LOW";
1214   parameter DSS_MODE = "NONE";
1215   parameter DUTY_CYCLE_CORRECTION = "TRUE";
1216   parameter [15:0] FACTORY_JF = 16'hC080;
1217   parameter integer PHASE_SHIFT = 0;
1218   parameter STARTUP_WAIT = "FALSE";
1219
1220   input CLKFB, CLKIN, DSSEN;
1221   input PSCLK, PSEN, PSINCDEC, RST;
1222
1223   output CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90;
1224   output CLKDV, CLKFX, CLKFX180, LOCKED, PSDONE;
1225   output [7:0] STATUS;
1226
1227   
1228   reg CLK0, CLK180, CLK270, CLK2X, CLK2X180, CLK90;
1229   reg CLKDV, CLKFX, CLKFX180;
1230   reg LOCKED_out, PSDONE = 0;
1231   reg [7:0] STATUS = 8'b0;
1232   wire LOCKED;
1233
1234   reg [1:0] clkfb_type, ps_type;
1235   reg clkin_type, align, clkin_divide, fbsync = 0;
1236   reg [2:0] pos_shift, neg_shift;
1237   reg [2:0] pos_shift_st, neg_shift_st;
1238   reg [3:0] deskew_adjust_mode;
1239// reg [8:0] shift = 9'b0;
1240   reg [1:0] clkin_cnt, old_clkin_cnt;
1241   reg clkin_error;
1242   reg period_updated;
1243   reg clkin_cnt_en;
1244   reg rst_tmp, rst_done_fx, rst_done_dv;
1245
1246   integer shift;
1247
1248   realtime clk_period; // = (250*CLKIN_PERIOD);
1249   realtime clkfx_period; // = ((CLKIN_PERIOD*CLKFX_DIVIDE*1000)/(CLKFX_MULTIPLY*2));
1250   realtime shift_ammount; // = ((CLKIN_PERIOD*1000)/256);
1251   realtime clkdv_period; // = ((CLKIN_PERIOD*CLKDV_DIVIDE*1000)/2);
1252   realtime clkin_time1, clkin_time2, period_clkin;
1253
1254   time start_time, delay_time;
1255   
1256       
1257  initial begin
1258
1259   case (CLKIN_DIVIDE_BY_2)
1260        "false" : clkin_type <= 0;
1261        "FALSE" : clkin_type <= 0;
1262        "true" : clkin_type <= 1;
1263        "TRUE" : clkin_type <= 1;
1264        default : begin
1265            $display("Attribute Syntax Error : The attribute CLKIN_DIVIDE_BY_2 on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", CLKIN_DIVIDE_BY_2);
1266            $finish;
1267        end
1268    endcase
1269
1270    case (CLKDV_DIVIDE)
1271    1.5 : ;
1272    2.0 : ;
1273    2.5 : ;
1274    3.0 : ;
1275    3.5 : ;
1276    4.0 : ;
1277    4.5 : ;
1278    5.0 : ;
1279        5.5 : ;
1280    6.0 : ;
1281    6.5 : ;
1282    7.0 : ;
1283    7.5 : ;
1284    8.0 : ;
1285    9.0 : ;
1286    10.0 : ;
1287    11.0 : ;
1288    12.0 : ;
1289    13.0 : ;
1290    14.0 : ;
1291    15.0 : ;
1292    16.0 : ;
1293    default : begin
1294        $display("Attribute Syntax Error : The attribute CLKDV_DIVIDE on DCM 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);
1295        $finish;
1296    end
1297    endcase
1298
1299    if ((CLKFX_DIVIDE <= 0) || (32 < CLKFX_DIVIDE)) begin
1300    $display("Attribute Syntax Error : The attribute CLKFX_DIVIDE on DCM instance %m is set to %d. Legal values for this attribute are 1 ... 32.", CLKFX_DIVIDE);
1301    $finish;
1302    end
1303
1304    if ((CLKFX_MULTIPLY <= 1) || (32 < CLKFX_MULTIPLY)) begin
1305    $display("Attribute Syntax Error : The attribute CLKFX_MULTIPLY on DCM instance %m is set to %d. Legal values for this attribute are 2 ... 32.", CLKFX_MULTIPLY);
1306    $finish;
1307    end
1308
1309    case (CLKIN_DIVIDE_BY_2)
1310    "false" : clkin_divide <= 0;
1311    "FALSE" : clkin_divide <= 0;
1312    "true" : clkin_divide <= 1;
1313    "TRUE" : clkin_divide <= 1;
1314    default : begin
1315        $display("Attribute Syntax Error : The attribute CLKIN_DIVIDE_BY_2 on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", CLKIN_DIVIDE_BY_2);
1316        $finish;
1317    end
1318    endcase
1319
1320    case (CLKOUT_PHASE_SHIFT)
1321    "NONE" : ps_type <= 0;
1322    "none" : ps_type <= 0;
1323    "FIXED" : ps_type <= 1;
1324        "fixed" : ps_type <= 1;
1325        "VARIABLE" : ps_type <= 2;
1326        "variable" : ps_type <= 2;
1327    default : begin
1328        $display("Attribute Syntax Error : The attribute CLKOUT_PHASE_SHIFT on DCM instance %m is set to %s. Legal values for this attribute are NONE, FIXED or VARIABLE.", CLKOUT_PHASE_SHIFT);
1329        $finish;
1330    end
1331    endcase
1332
1333    case (CLK_FEEDBACK)
1334    "none" : clkfb_type <= 0;
1335    "NONE" : clkfb_type <= 0;
1336    "1x" : clkfb_type <= 1;
1337    "1X" : clkfb_type <= 1;
1338    "2x" : clkfb_type <= 2;
1339    "2X" : clkfb_type <= 2;
1340    default : begin
1341        $display("Attribute Syntax Error : The attribute CLK_FEEDBACK on DCM instance %m is set to %s. Legal values for this attribute are NONE, 1X or 2X.", CLK_FEEDBACK);
1342        $finish;
1343    end
1344    endcase
1345
1346    case (DESKEW_ADJUST)
1347    "source_synchronous" : deskew_adjust_mode <= 8;
1348    "SOURCE_SYNCHRONOUS" : deskew_adjust_mode <= 8;
1349    "system_synchronous" : deskew_adjust_mode <= 11;
1350    "SYSTEM_SYNCHRONOUS" : deskew_adjust_mode <= 11;
1351    "0" : deskew_adjust_mode <= 0;
1352    "1" : deskew_adjust_mode <= 1;
1353    "2" : deskew_adjust_mode <= 2;
1354    "3" : deskew_adjust_mode <= 3;
1355    "4" : deskew_adjust_mode <= 4;
1356    "5" : deskew_adjust_mode <= 5;
1357    "6" : deskew_adjust_mode <= 6;
1358    "7" : deskew_adjust_mode <= 7;
1359    "8" : deskew_adjust_mode <= 8;
1360    "9" : deskew_adjust_mode <= 9;
1361    "10" : deskew_adjust_mode <= 10;
1362    "11" : deskew_adjust_mode <= 11;
1363    "12" : deskew_adjust_mode <= 12;
1364    "13" : deskew_adjust_mode <= 13;
1365    "14" : deskew_adjust_mode <= 14;
1366    "15" : deskew_adjust_mode <= 15;
1367    default : begin
1368        $display("Attribute Syntax Error : The attribute DESKEW_ADJUST on DCM instance %m is set to %s. Legal values for this attribute are SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or 0 ... 15.", DESKEW_ADJUST);
1369        $finish;
1370    end
1371    endcase
1372
1373    case (DFS_FREQUENCY_MODE)
1374    "high" : ;
1375    "HIGH" : ;
1376    "low" : ;
1377    "LOW" : ;
1378    default : begin
1379        $display("Attribute Syntax Error : The attribute DFS_FREQUENCY_MODE on DCM instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DFS_FREQUENCY_MODE);
1380        $finish;
1381    end
1382    endcase
1383
1384    case (DLL_FREQUENCY_MODE)
1385    "high" : ;
1386    "HIGH" : ;
1387    "low" : ;
1388    "LOW" : ;
1389    default : begin
1390        $display("Attribute Syntax Error : The attribute DLL_FREQUENCY_MODE on DCM instance %m is set to %s. Legal values for this attribute are HIGH or LOW.", DLL_FREQUENCY_MODE);
1391        $finish;
1392    end
1393    endcase
1394
1395    case (DSS_MODE)
1396    "none" : ;
1397    "NONE" : ;
1398    default : begin
1399        $display("Attribute Syntax Error : The attribute DSS_MODE on DCM instance %m is set to %s. The legal value for this attribute is NONE.", DSS_MODE);
1400        $finish;
1401    end
1402    endcase
1403
1404    case (DUTY_CYCLE_CORRECTION)
1405    "false" : begin
1406        $display("Unsupported Attribute Error : The attribute DUTY_CYCLE_CORRECTION on DCM instance %m is set to %s which is not supported in this simulation model. The legal value of DUTY_CYCLE_CORRECTION for this model is TRUE.", DUTY_CYCLE_CORRECTION);
1407            $finish;
1408    end
1409    "FALSE" : begin
1410        $display("Unsupported Attribute Error : The attribute DUTY_CYCLE_CORRECTION on DCM instance %m is set to %s which is not supported in this simulation model. The legal value of DUTY_CYCLE_CORRECTION for this model is TRUE.", DUTY_CYCLE_CORRECTION);
1411            $finish;
1412    end
1413    "true" : ;
1414    "TRUE" : ;
1415    default : begin
1416        $display("Attribute Syntax Error : The attribute DUTY_CYCLE_CORRECTION on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", DUTY_CYCLE_CORRECTION);
1417        $finish;
1418    end
1419    endcase
1420
1421    if ((PHASE_SHIFT < -255) || (PHASE_SHIFT > 255)) begin
1422    $display("Attribute Syntax Error : The attribute PHASE_SHIFT on DCM instance %m is set to %d. Legal values for this attribute are -255 ... 255.", PHASE_SHIFT);
1423    $display("Error : PHASE_SHIFT = %d is not -255 ... 255.", PHASE_SHIFT);
1424    $finish;
1425    end
1426
1427    case (STARTUP_WAIT)
1428    "false" : ;
1429    "FALSE" : ;
1430    "true" : ;
1431    "TRUE" : ;
1432    default : begin
1433        $display("Attribute Syntax Error : The attribute STARTUP_WAIT on DCM instance %m is set to %s. Legal values for this attribute are TRUE or FALSE.", STARTUP_WAIT);
1434        $finish;
1435    end
1436    endcase
1437
1438
1439// if (CLKIN_PERIOD == 0.0) begin
1440// $display("Attribute Syntax Error : The attribute CLKIN_PERIOD on DCM instance %m must be defined to the value of the input clock period in nano-seconds");
1441// $finish;
1442// end
1443end
1444   
1445// always @(posedge RST) begin
1446// disable main_dcm;
1447// disable clkdv_dcm;
1448// disable clkfx_dcm;
1449// end
1450
1451   integer t;
1452
1453
1454   assign #100 LOCKED = LOCKED_out;
1455
1456   always begin: feedback_dcm
1457      fbsync = 0;
1458      wait (RST==0);
1459      wait (period_updated==1)
1460      @(posedge CLKFB);
1461      delay_time = $time - start_time;
1462      @(posedge CLKIN);
1463      #(((12*clk_period)-(delay_time)));
1464      fbsync = 1;
1465      wait (RST==1);
1466   end
1467
1468   always begin: main_dcm
1469      pos_shift[0] = 1'b0;
1470      neg_shift[0] = 1'b0;
1471      align = 0;
1472      LOCKED_out = 1'b0;
1473      period_updated = 0;
1474      clkin_cnt_en = 0;
1475      CLK0 = 1'b0;
1476      CLK90 = 1'b0;
1477      CLK180 = 1'b0;
1478      CLK270 = 1'b0;
1479      CLK2X = 1'b0;
1480      CLK2X180 = 1'b0;
1481      rst_tmp <= 1'b1;
1482      wait (RST==0);
1483      wait (rst_done_fx==1 );
1484      wait (rst_done_dv==1);
1485       rst_tmp <= 1'b0;
1486      @(posedge CLKIN);
1487      clkin_time1 = $time;
1488      @(posedge CLKIN);
1489      clkin_time2 = $time;
1490      period_clkin = clkin_time2 - clkin_time1;
1491      
1492      clk_period = (0.25*period_clkin);
1493      clkfx_period = ((period_clkin*CLKFX_DIVIDE)/(CLKFX_MULTIPLY*2));
1494      shift_ammount = ((period_clkin)/256);
1495      clkdv_period = ((period_clkin*CLKDV_DIVIDE)/2);
1496
1497      @(posedge CLKIN);
1498      period_updated = 1;
1499      start_time = $time;
1500      repeat (6) begin
1501         CLK0 = ~CLK0;
1502         CLK2X = ~CLK2X;
1503     #(clk_period);
1504     CLK2X = ~CLK2X;
1505     #(clk_period);
1506      end
1507      repeat (6) begin
1508         CLK0 = ~CLK0;
1509         CLK2X = ~CLK2X;
1510         #(clk_period);
1511         CLK2X = ~CLK2X;
1512         #(clk_period);
1513      end
1514      if (clkfb_type != 0)
1515     wait(fbsync==1);
1516      if (ps_type != 0)
1517    if (PHASE_SHIFT > 0)
1518      #((period_clkin*PHASE_SHIFT)/256);
1519    else if (PHASE_SHIFT < 0)
1520      #((period_clkin)-((period_clkin*PHASE_SHIFT)/256));
1521      align = 1;
1522      CLK0 = ~CLK0;
1523      CLK2X = ~CLK2X;
1524      #(clk_period);
1525      CLK90 = ~CLK90;
1526      CLK2X = ~CLK2X;
1527      CLK2X180 = ~CLK2X180;
1528      #(clk_period);
1529      repeat (7) begin
1530     CLK0 = ~CLK0;
1531     CLK180 = ~CLK180;
1532     CLK2X = ~CLK2X;
1533     CLK2X180 = ~CLK2X180;
1534     #(clk_period);
1535     CLK90 = ~CLK90;
1536     CLK2X = ~CLK2X;
1537     CLK2X180 = ~CLK2X180;
1538     CLK270 = ~CLK270;
1539     #(clk_period);
1540      end
1541      LOCKED_out = 1'b1;
1542      clkin_cnt_en = 1'b1;
1543// forever begin
1544      while (RST==0) begin
1545     CLK0 = ~CLK0;
1546     CLK180 = ~CLK180;
1547     CLK2X = ~CLK2X;
1548     CLK2X180 = ~CLK2X180;
1549     #(clk_period);
1550     CLK90 = ~CLK90;
1551     CLK270 = ~CLK270;
1552     CLK2X = ~CLK2X;
1553     CLK2X180 = ~CLK2X180;
1554         #(clk_period);
1555         CLK0 = ~CLK0;
1556         CLK180 = ~CLK180;
1557         CLK2X = ~CLK2X;
1558         CLK2X180 = ~CLK2X180;
1559         #(clk_period);
1560         CLK90 = ~CLK90;
1561         CLK270 = ~CLK270;
1562         CLK2X = ~CLK2X;
1563         CLK2X180 = ~CLK2X180;
1564     if (pos_shift_st[0]==1'b1 && pos_shift[0]==1'b0) begin
1565           #((clk_period)+shift_ammount);
1566// pos_shift[0] <= 1;
1567        pos_shift[0] = 1;
1568     end
1569     else if (neg_shift_st[0]==1'b1 && neg_shift[0]==1'b0) begin
1570       #((clk_period)-shift_ammount);
1571// neg_shift[0] <= 1;
1572        neg_shift[0] = 1;
1573     end
1574     else begin
1575           if (pos_shift_st[0] == 1'b0)
1576// pos_shift[0] <= 0;
1577               pos_shift[0] = 0;
1578           if (neg_shift_st[0] == 1'b0)
1579// neg_shift[0] <= 0;
1580               neg_shift[0] = 0;
1581       #(clk_period);
1582         end
1583     if (clkin_error)
1584       wait (0);
1585      end
1586   end
1587   
1588   always begin: clkfx_dcm
1589      pos_shift[1]=1'b0;
1590      neg_shift[1]=1'b0;
1591      CLKFX = 1'b0;
1592      CLKFX180 = 1'b0;
1593      rst_done_fx <= 1'b1;
1594// wait (RST==0);
1595      wait (rst_tmp==0 && RST==0);
1596      wait (LOCKED_out==1);
1597      rst_done_fx <= 1'b0;
1598      CLKFX = 1;
1599      CLKFX180 = 0;
1600// forever begin
1601      while (RST== 0 && rst_tmp==0) begin
1602         #(clkfx_period);
1603         CLKFX = ~CLKFX;
1604     CLKFX180 = ~CLKFX180;
1605     if (pos_shift_st[1]==1'b1 && pos_shift[1]==1'b0) begin
1606           #((clkfx_period)+shift_ammount);
1607        pos_shift[1] <= 1;
1608     end
1609     else if (neg_shift_st[1]==1'b1 && neg_shift[1]==1'b0) begin
1610       #((clkfx_period)-shift_ammount);
1611        neg_shift[1] <= 1;
1612     end
1613     else begin
1614           if (pos_shift_st[1] == 1'b0)
1615               pos_shift[1] <= 0;
1616           if (neg_shift_st[1] == 1'b0)
1617               neg_shift[1] <= 0;
1618       #(clkfx_period);
1619         end
1620         CLKFX = ~CLKFX;
1621     CLKFX180 = ~CLKFX180;
1622     if (clkin_error)
1623       wait(0);
1624      end
1625   end
1626   
1627   always begin: clkdv_dcm
1628      pos_shift[2] = 0;
1629      neg_shift[2] = 0;
1630      CLKDV = 1'b0;
1631      rst_done_dv <= 1'b1;
1632// wait (RST==0);
1633      wait (rst_tmp==0 && RST==0);
1634      wait (LOCKED_out==1);
1635      rst_done_dv <= 1'b0;
1636      CLKDV = ~CLKDV;
1637// forever begin
1638      while (RST==0 && rst_tmp==0) begin
1639     if (pos_shift_st[2]==1'b1 && pos_shift[2]==1'b0) begin
1640           #(clkdv_period+shift_ammount);
1641        pos_shift[2] = 1;
1642     end
1643     else if (neg_shift_st[2]==1'b1 && neg_shift[2]==1'b0) begin
1644       #(clkdv_period-shift_ammount);
1645        neg_shift[2] = 1;
1646     end
1647     else begin
1648            if (pos_shift_st[2] == 1'b0)
1649               pos_shift[2] <= 0;
1650            if (neg_shift_st[2] == 1'b0)
1651               neg_shift[2] <= 0;
1652        #(clkdv_period);
1653         end
1654     CLKDV = ~CLKDV;
1655     if (clkin_error)
1656       wait(0);
1657      end
1658   end
1659
1660   initial shift = 0;
1661
1662   always @(posedge PSCLK) begin: dps_dcm
1663      PSDONE <= 1'b0;
1664      if (ps_type==2) begin
1665    if (PSEN) begin
1666         if (pos_shift != 3'b000 || neg_shift != 3'b000)
1667             $display("Warning : Please wait for PSDONE signal before adjusting the Phase Shift. %m at time %t. ", $time);
1668         else begin
1669      if (PSINCDEC==1'b1 && pos_shift==3'b000) begin
1670        pos_shift_st <= 3'b111;
1671        shift = shift + 1;
1672            if (shift > 256)
1673               STATUS[0] <= 1;
1674            else
1675               STATUS[0] <= 0;
1676      end
1677          else if (PSINCDEC==1'b0 && neg_shift==3'b000) begin
1678        neg_shift_st <= 3'b111;
1679        shift = shift - 1;
1680            if (shift < -256)
1681               STATUS[0] <= 1;
1682            else
1683               STATUS[0] <= 0;
1684      end
1685         end
1686       end
1687       if (pos_shift==3'b111) begin
1688           pos_shift_st <= 3'b000;
1689           PSDONE <= 1'b1;
1690       end
1691       if (neg_shift==3'b111) begin
1692           neg_shift_st <= 3'b000;
1693           PSDONE <= 1'b1;
1694       end
1695     end
1696   end // block: dps_dcm
1697
1698
1699   always @(posedge CLKIN)
1700     if (RST) begin
1701    clkin_cnt <= 2'b00;
1702     end
1703     else begin
1704       if (clkin_cnt_en ==1)
1705            clkin_cnt <= clkin_cnt + 1;
1706     end
1707
1708   always @(posedge CLK0 or posedge RST) begin : status_dcm
1709   if (RST) begin
1710      old_clkin_cnt <= 0;
1711       clkin_error <= 1'b0;
1712   end
1713   else
1714      if (clkin_cnt_en== 1'b1) begin
1715      #1 clkin_error <= 1'b0;
1716      @(posedge CLK0);
1717      if (clkin_cnt == old_clkin_cnt) begin
1718// $display("Error: This DCM simulation for %m does not support the stopping of CLKIN or the use of frequecies to other than that specified for the CLKIN_PERIOD, %f.\nPlease use the standard DCM model to properly view this behavior.\nAll DCM outputs will be suspended until the DCM is reset.",CLKIN_PERIOD);
1719     $display("Error: This DCM simulation for %m does not support the stopping of CLKIN.\nPlease use the standard DCM model to properly view this behavior.\nAll DCM outputs will be suspended until the DCM is reset.");
1720     clkin_error <= 1;
1721     wait (RST==1);
1722      end
1723      else
1724    old_clkin_cnt <= clkin_cnt;
1725   end
1726  end
1727
1728
1729endmodule
1730
1731`endif
1732

Archive Download this file

Branches:
master



interactive