OpenCores
URL https://opencores.org/ocsvn/socgen/socgen/trunk

Subversion Repositories socgen

[/] [socgen/] [trunk/] [tools/] [synthesys/] [targets/] [doc/] [Xilinx/] [DCM_SP.v] - Blame information for rev 130

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.