OpenCores
URL https://opencores.org/ocsvn/aes-128-ecb-encoder/aes-128-ecb-encoder/trunk

Subversion Repositories aes-128-ecb-encoder

[/] [aes-128-ecb-encoder/] [trunk/] [fpga/] [aes128_ecb_2017/] [aes128_ecb.srcs/] [sources_1/] [ip/] [clk_gen/] [mmcm_pll_drp_func_us_mmcm.vh] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 vv_gulyaev
///////////////////////////////////////////////////////////////////////////////
2
//    
3
//    Company:          Xilinx
4
//    Engineer:         Jim Tatsukawa
5
//    Date:             7/30/2014
6
//    Design Name:      MMCME2 DRP
7
//    Module Name:      mmcme2_drp_func.h
8
//    Version:          1.04
9
//    Target Devices:   UltraScale Architecture || MMCM 
10
//    Tool versions:    2014.3
11
//    Description:      This header provides the functions necessary to  
12
//                      calculate the DRP register values for the V6 MMCM.
13
//                      
14
//      Revision Notes: 3/22 - Updating lookup_low/lookup_high (CR)
15
//                              4/13 - Fractional divide function in mmcm_frac_count_calc function. CRS610807
16
// 
17
//    Disclaimer:  XILINX IS PROVIDING THIS DESIGN, CODE, OR
18
//                 INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
19
//                 PROGRAMS AND SOLUTIONS FOR XILINX DEVICES.  BY
20
//                 PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
21
//                 ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
22
//                 APPLICATION OR STANDARD, XILINX IS MAKING NO
23
//                 REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
24
//                 FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE
25
//                 RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY
26
//                 REQUIRE FOR YOUR IMPLEMENTATION.  XILINX
27
//                 EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH
28
//                 RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION,
29
//                 INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
30
//                 REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
31
//                 FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES
32
//                 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33
//                 PURPOSE.
34
// 
35
//                 (c) Copyright 2009-2010 Xilinx, Inc.
36
//                 All rights reserved.
37
// 
38
///////////////////////////////////////////////////////////////////////////////
39
 
40
// These are user functions that should not be modified.  Changes to the defines
41
// or code within the functions may alter the accuracy of the calculations.
42
 
43
// Define debug to provide extra messages durring elaboration
44
//`define DEBUG 1
45
 
46
// FRAC_PRECISION describes the width of the fractional portion of the fixed
47
//    point numbers.  These should not be modified, they are for development 
48
//    only
49
`define FRAC_PRECISION  10
50
// FIXED_WIDTH describes the total size for fixed point calculations(int+frac).
51
// Warning: L.50 and below will not calculate properly with FIXED_WIDTHs 
52
//    greater than 32
53
`define FIXED_WIDTH     32
54
 
55
// This function takes a fixed point number and rounds it to the nearest
56
//    fractional precision bit.
57
function [`FIXED_WIDTH:1] round_frac
58
   (
59
      // Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number
60
      input [`FIXED_WIDTH:1] decimal,
61
 
62
      // This describes the precision of the fraction, for example a value
63
      //    of 1 would modify the fractional so that instead of being a .16
64
      //    fractional, it would be a .1 (rounded to the nearest 0.5 in turn)
65
      input [`FIXED_WIDTH:1] precision
66
   );
67
 
68
   begin
69
 
70
   `ifdef DEBUG
71
      $display("round_frac - decimal: %h, precision: %h", decimal, precision);
72
   `endif
73
      // If the fractional precision bit is high then round up
74
      if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin
75
         round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision));
76
      end else begin
77
         round_frac = decimal;
78
      end
79
   `ifdef DEBUG
80
      $display("round_frac: %h", round_frac);
81
   `endif
82
   end
83
endfunction
84
 
85
// This function calculates high_time, low_time, w_edge, and no_count
86
//    of a non-fractional counter based on the divide and duty cycle
87
//
88
// NOTE: high_time and low_time are returned as integers between 0 and 63 
89
//    inclusive.  64 should equal 6'b000000 (in other words it is okay to 
90
//    ignore the overflow)
91
function [13:0] mmcm_pll_divider
92
   (
93
      input [7:0] divide,        // Max divide is 128
94
      input [31:0] duty_cycle    // Duty cycle is multiplied by 100,000
95
   );
96
 
97
   reg [`FIXED_WIDTH:1]    duty_cycle_fix;
98
 
99
   // High/Low time is initially calculated with a wider integer to prevent a
100
   // calculation error when it overflows to 64.
101
   reg [6:0]               high_time;
102
   reg [6:0]               low_time;
103
   reg                     w_edge;
104
   reg                     no_count;
105
 
106
   reg [`FIXED_WIDTH:1]    temp;
107
 
108
   begin
109
      // Duty Cycle must be between 0 and 1,000
110
      if(duty_cycle <=0 || duty_cycle >= 100000) begin
111
         $display("ERROR: duty_cycle: %d is invalid", duty_cycle);
112
         $finish;
113
      end
114
 
115
      // Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point
116
      duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000;
117
 
118
   `ifdef DEBUG
119
      $display("duty_cycle_fix: %h", duty_cycle_fix);
120
   `endif
121
 
122
      // If the divide is 1 nothing needs to be set except the no_count bit.
123
      //    Other values are dummies
124
      if(divide == 7'h01) begin
125
         high_time   = 7'h01;
126
         w_edge      = 1'b0;
127
         low_time    = 7'h01;
128
         no_count    = 1'b1;
129
      end else begin
130
         temp = round_frac(duty_cycle_fix*divide, 1);
131
 
132
         // comes from above round_frac
133
         high_time   = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1];
134
         // If the duty cycle * divide rounded is .5 or greater then this bit
135
         //    is set.
136
         w_edge      = temp[`FRAC_PRECISION]; // comes from round_frac
137
 
138
         // If the high time comes out to 0, it needs to be set to at least 1
139
         // and w_edge set to 0
140
         if(high_time == 7'h00) begin
141
            high_time   = 7'h01;
142
            w_edge      = 1'b0;
143
         end
144
 
145
         if(high_time == divide) begin
146
            high_time   = divide - 1;
147
            w_edge      = 1'b1;
148
         end
149
 
150
         // Calculate low_time based on the divide setting and set no_count to
151
         //    0 as it is only used when divide is 1.
152
         low_time    = divide - high_time;
153
         no_count    = 1'b0;
154
      end
155
 
156
      // Set the return value.
157
      mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]};
158
   end
159
endfunction
160
 
161
// This function calculates mx, delay_time, and phase_mux 
162
//  of a non-fractional counter based on the divide and phase
163
//
164
// NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux
165
//    is used.
166
function [10:0] mmcm_pll_phase
167
   (
168
      // divide must be an integer (use fractional if not)
169
      //  assumed that divide already checked to be valid
170
      input [7:0] divide, // Max divide is 128
171
 
172
      // Phase is given in degrees (-360,000 to 360,000)
173
      input signed [31:0] phase
174
   );
175
 
176
   reg [`FIXED_WIDTH:1] phase_in_cycles;
177
   reg [`FIXED_WIDTH:1] phase_fixed;
178
   reg [1:0]            mx;
179
   reg [5:0]            delay_time;
180
   reg [2:0]            phase_mux;
181
 
182
   reg [`FIXED_WIDTH:1] temp;
183
 
184
   begin
185
`ifdef DEBUG
186
      $display("mmcm_pll_phase-divide:%d,phase:%d",
187
         divide, phase);
188
`endif
189
 
190
      if ((phase < -360000) || (phase > 360000)) begin
191
         $display("ERROR: phase of $phase is not between -360000 and 360000");
192
         $finish;
193
      end
194
 
195
      // If phase is less than 0, convert it to a positive phase shift
196
      // Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
197
      if(phase < 0) begin
198
         phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
199
      end else begin
200
         phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
201
      end
202
 
203
      // Put phase in terms of decimal number of vco clock cycles
204
      phase_in_cycles = ( phase_fixed * divide ) / 360;
205
 
206
`ifdef DEBUG
207
      $display("phase_in_cycles: %h", phase_in_cycles);
208
`endif
209
 
210
 
211
         temp  =  round_frac(phase_in_cycles, 3);
212
 
213
         // set mx to 2'b00 that the phase mux from the VCO is enabled
214
         mx                     =  2'b00;
215
         phase_mux      =  temp[`FRAC_PRECISION:`FRAC_PRECISION-2];
216
         delay_time     =  temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1];
217
 
218
   `ifdef DEBUG
219
      $display("temp: %h", temp);
220
   `endif
221
 
222
      // Setup the return value
223
      mmcm_pll_phase={mx, phase_mux, delay_time};
224
   end
225
endfunction
226
 
227
// This function takes the divide value and outputs the necessary lock values
228
function [39:0] mmcm_pll_lock_lookup
229
   (
230
      input [6:0] divide // Max divide is 64
231
   );
232
 
233
   reg [2559:0]   lookup;
234
 
235
   begin
236
      lookup = {
237
         // This table is composed of:
238
         // LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
239
         40'b00110_00110_1111101000_1111101001_0000000001,
240
         40'b00110_00110_1111101000_1111101001_0000000001,
241
         40'b01000_01000_1111101000_1111101001_0000000001,
242
         40'b01011_01011_1111101000_1111101001_0000000001,
243
         40'b01110_01110_1111101000_1111101001_0000000001,
244
         40'b10001_10001_1111101000_1111101001_0000000001,
245
         40'b10011_10011_1111101000_1111101001_0000000001,
246
         40'b10110_10110_1111101000_1111101001_0000000001,
247
         40'b11001_11001_1111101000_1111101001_0000000001,
248
         40'b11100_11100_1111101000_1111101001_0000000001,
249
         40'b11111_11111_1110000100_1111101001_0000000001,
250
         40'b11111_11111_1100111001_1111101001_0000000001,
251
         40'b11111_11111_1011101110_1111101001_0000000001,
252
         40'b11111_11111_1010111100_1111101001_0000000001,
253
         40'b11111_11111_1010001010_1111101001_0000000001,
254
         40'b11111_11111_1001110001_1111101001_0000000001,
255
         40'b11111_11111_1000111111_1111101001_0000000001,
256
         40'b11111_11111_1000100110_1111101001_0000000001,
257
         40'b11111_11111_1000001101_1111101001_0000000001,
258
         40'b11111_11111_0111110100_1111101001_0000000001,
259
         40'b11111_11111_0111011011_1111101001_0000000001,
260
         40'b11111_11111_0111000010_1111101001_0000000001,
261
         40'b11111_11111_0110101001_1111101001_0000000001,
262
         40'b11111_11111_0110010000_1111101001_0000000001,
263
         40'b11111_11111_0110010000_1111101001_0000000001,
264
         40'b11111_11111_0101110111_1111101001_0000000001,
265
         40'b11111_11111_0101011110_1111101001_0000000001,
266
         40'b11111_11111_0101011110_1111101001_0000000001,
267
         40'b11111_11111_0101000101_1111101001_0000000001,
268
         40'b11111_11111_0101000101_1111101001_0000000001,
269
         40'b11111_11111_0100101100_1111101001_0000000001,
270
         40'b11111_11111_0100101100_1111101001_0000000001,
271
         40'b11111_11111_0100101100_1111101001_0000000001,
272
         40'b11111_11111_0100010011_1111101001_0000000001,
273
         40'b11111_11111_0100010011_1111101001_0000000001,
274
         40'b11111_11111_0100010011_1111101001_0000000001,
275
         40'b11111_11111_0011111010_1111101001_0000000001,
276
         40'b11111_11111_0011111010_1111101001_0000000001,
277
         40'b11111_11111_0011111010_1111101001_0000000001,
278
         40'b11111_11111_0011111010_1111101001_0000000001,
279
         40'b11111_11111_0011111010_1111101001_0000000001,
280
         40'b11111_11111_0011111010_1111101001_0000000001,
281
         40'b11111_11111_0011111010_1111101001_0000000001,
282
         40'b11111_11111_0011111010_1111101001_0000000001,
283
         40'b11111_11111_0011111010_1111101001_0000000001,
284
         40'b11111_11111_0011111010_1111101001_0000000001,
285
         40'b11111_11111_0011111010_1111101001_0000000001,
286
         40'b11111_11111_0011111010_1111101001_0000000001,
287
         40'b11111_11111_0011111010_1111101001_0000000001,
288
         40'b11111_11111_0011111010_1111101001_0000000001,
289
         40'b11111_11111_0011111010_1111101001_0000000001,
290
         40'b11111_11111_0011111010_1111101001_0000000001,
291
         40'b11111_11111_0011111010_1111101001_0000000001,
292
         40'b11111_11111_0011111010_1111101001_0000000001,
293
         40'b11111_11111_0011111010_1111101001_0000000001,
294
         40'b11111_11111_0011111010_1111101001_0000000001,
295
         40'b11111_11111_0011111010_1111101001_0000000001,
296
         40'b11111_11111_0011111010_1111101001_0000000001,
297
         40'b11111_11111_0011111010_1111101001_0000000001,
298
         40'b11111_11111_0011111010_1111101001_0000000001,
299
         40'b11111_11111_0011111010_1111101001_0000000001,
300
         40'b11111_11111_0011111010_1111101001_0000000001,
301
         40'b11111_11111_0011111010_1111101001_0000000001,
302
         40'b11111_11111_0011111010_1111101001_0000000001
303
      };
304
 
305
      // Set lookup_entry with the explicit bits from lookup with a part select
306
      mmcm_pll_lock_lookup = lookup[ ((64-divide)*40) +: 40];
307
   `ifdef DEBUG
308
      $display("lock_lookup: %b", mmcm_pll_lock_lookup);
309
   `endif
310
   end
311
endfunction
312
 
313
// This function takes the divide value and the bandwidth setting of the MMCM
314
//  and outputs the digital filter settings necessary.
315
function [9:0] mmcm_pll_filter_lookup
316
   (
317
      input [6:0] divide, // Max divide is 64
318
      input [8*9:0] BANDWIDTH
319
   );
320
 
321
   reg [639:0] lookup_low;
322
   reg [639:0] lookup_high;
323
 
324
   reg [9:0] lookup_entry;
325
 
326
   begin
327
      lookup_low = {
328
         // CP_RES_LFHF
329
         10'b0010_1111_11,
330
         10'b0010_1111_11,
331
         10'b0010_1111_11,
332
         10'b0010_1111_11,
333
         10'b0010_1111_11,
334
         10'b0010_1111_11,
335
         10'b0010_0111_11,
336
         10'b0010_0111_11,
337
         10'b0010_0111_11,
338
         10'b0010_1101_11,
339
         10'b0010_1101_11,
340
         10'b0010_1101_11,
341
         10'b0010_0011_11,
342
         10'b0010_0101_11,
343
         10'b0010_0101_11,
344
         10'b0010_0101_11,
345
         10'b0010_1001_11,
346
         10'b0010_1001_11,
347
         10'b0010_1110_11,
348
         10'b0010_1110_11,
349
         10'b0010_1110_11,
350
         10'b0010_1110_11,
351
         10'b0010_1110_11,
352
         10'b0010_1110_11,
353
         10'b0010_0001_11,
354
         10'b0010_0001_11,
355
         10'b0010_0001_11,
356
         10'b0010_0001_11,
357
         10'b0010_0001_11,
358
         10'b0010_0110_11,
359
         10'b0010_0110_11,
360
         10'b0010_0110_11,
361
         10'b0010_0110_11,
362
         10'b0010_0110_11,
363
         10'b0010_0110_11,
364
         10'b0010_0110_11,
365
         10'b0010_0110_11,
366
         10'b0010_0110_11,
367
         10'b0010_0110_11,
368
         10'b0010_1010_11,
369
         10'b0010_1010_11,
370
         10'b0010_1010_11,
371
         10'b0010_1010_11,
372
         10'b0010_1010_11,
373
         10'b0010_1010_11,
374
         10'b0010_1010_11,
375
         10'b0010_1010_11,
376
         10'b0010_1100_11,
377
         10'b0010_1100_11,
378
         10'b0010_1100_11,
379
         10'b0010_1100_11,
380
         10'b0010_1100_11,
381
         10'b0010_1100_11,
382
         10'b0010_1100_11,
383
         10'b0010_1100_11,
384
         10'b0010_1100_11,
385
         10'b0010_1100_11,
386
         10'b0010_1100_11,
387
         10'b0010_1100_11,
388
         10'b0010_1100_11,
389
         10'b0010_1100_11,
390
         10'b0010_1100_11,
391
         10'b0010_1100_11,
392
         10'b0010_1100_11
393
      };
394
 
395
      lookup_high = {
396
         // CP_RES_LFHF
397
         10'b0010_1111_11,
398
         10'b0010_1111_11,
399
         10'b0010_1011_11,
400
         10'b0011_1111_11,
401
         10'b0100_1111_11,
402
         10'b0100_1111_11,
403
         10'b0101_1111_11,
404
         10'b0110_1111_11,
405
         10'b0111_1111_11,
406
         10'b0111_1111_11,
407
         10'b1100_1111_11,
408
         10'b1101_1111_11,
409
         10'b0001_1111_11,
410
         10'b1111_1111_11,
411
         10'b1111_1111_11,
412
         10'b1110_0111_11,
413
         10'b1110_1011_11,
414
         10'b1111_0111_11,
415
         10'b1111_1011_11,
416
         10'b1111_1011_11,
417
         10'b1110_1101_11,
418
         10'b1111_1101_11,
419
         10'b1111_1101_11,
420
         10'b1111_0011_11,
421
         10'b1111_0011_11,
422
         10'b1111_0011_11,
423
         10'b1110_0101_11,
424
         10'b1110_0101_11,
425
         10'b1110_0101_11,
426
         10'b1111_0101_11,
427
         10'b1111_0101_11,
428
         10'b1111_0101_11,
429
         10'b1111_1001_11,
430
         10'b1111_1001_11,
431
         10'b1111_1001_11,
432
         10'b1111_1001_11,
433
         10'b1111_1001_11,
434
         10'b1110_1110_11,
435
         10'b1110_1110_11,
436
         10'b1110_1110_11,
437
         10'b1110_1110_11,
438
         10'b1111_1110_11,
439
         10'b1111_1110_11,
440
         10'b1111_1110_11,
441
         10'b1111_1110_11,
442
         10'b1111_1110_11,
443
         10'b1111_1110_11,
444
         10'b1111_1110_11,
445
         10'b1110_0001_11,
446
         10'b1110_0001_11,
447
         10'b1110_0001_11,
448
         10'b1110_0001_11,
449
         10'b1110_0001_11,
450
         10'b1100_0110_11,
451
         10'b1100_0110_11,
452
         10'b1100_0110_11,
453
         10'b1100_0110_11,
454
         10'b1100_0110_11,
455
         10'b1100_0110_11,
456
         10'b1100_0110_11,
457
         10'b1100_1010_11,
458
         10'b1100_1010_11,
459
         10'b1100_1010_11,
460
         10'b1100_1010_11
461
      };
462
 
463
      // Set lookup_entry with the explicit bits from lookup with a part select
464
      if(BANDWIDTH == "LOW") begin
465
         // Low Bandwidth
466
         mmcm_pll_filter_lookup = lookup_low[ ((64-divide)*10) +: 10];
467
      end else begin
468
         // High or optimized bandwidth
469
         mmcm_pll_filter_lookup = lookup_high[ ((64-divide)*10) +: 10];
470
      end
471
 
472
   `ifdef DEBUG
473
      $display("filter_lookup: %b", mmcm_pll_filter_lookup);
474
   `endif
475
   end
476
endfunction
477
 
478
// This function takes in the divide, phase, and duty cycle
479
// setting to calculate the upper and lower counter registers.
480
function [37:0] mmcm_pll_count_calc
481
   (
482
      input [7:0] divide, // Max divide is 128
483
      input signed [31:0] phase,
484
      input [31:0] duty_cycle // Multiplied by 100,000
485
   );
486
 
487
   reg [13:0] div_calc;
488
   reg [16:0] phase_calc;
489
 
490
   begin
491
   `ifdef DEBUG
492
      $display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d",
493
         divide, phase, duty_cycle);
494
   `endif
495
 
496
      // w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
497
      div_calc = mmcm_pll_divider(divide, duty_cycle);
498
      // mx[10:9], pm[8:6], dt[5:0]
499
      phase_calc = mmcm_pll_phase(divide, phase);
500
 
501
      // Return value is the upper and lower address of counter
502
      //    Upper address is:
503
      //       RESERVED    [31:26]
504
      //       MX          [25:24]
505
      //       EDGE        [23]
506
      //       NOCOUNT     [22]
507
      //       DELAY_TIME  [21:16]
508
      //    Lower Address is:
509
      //       PHASE_MUX   [15:13]
510
      //       RESERVED    [12]
511
      //       HIGH_TIME   [11:6]
512
      //       LOW_TIME    [5:0]
513
 
514
   `ifdef DEBUG
515
      $display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
516
         divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
517
         div_calc[13], div_calc[12],
518
         phase_calc[16:15], phase_calc[5:0], phase_calc[14:12]);
519
   `endif
520
 
521
      mmcm_pll_count_calc =
522
         {
523
            // Upper Address
524
            6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
525
            // Lower Address
526
            phase_calc[8:6], 1'b0, div_calc[11:0]
527
         };
528
   end
529
endfunction
530
 
531
 
532
// This function takes in the divide, phase, and duty cycle
533
// setting to calculate the upper and lower counter registers.
534
// for fractional multiply/divide functions.
535
//
536
// 
537
function [37:0] mmcm_frac_count_calc
538
   (
539
      input [7:0] divide, // Max divide is 128
540
      input signed [31:0] phase,
541
      input [31:0] duty_cycle, // Multiplied by 1,000
542
      input [9:0] frac // Multiplied by 1000
543
   );
544
 
545
        //Required for fractional divide calculations
546
                          reg   [7:0]                    lt_frac;
547
                          reg   [7:0]                    ht_frac;
548
 
549
                          reg   /*[7:0]*/                       wf_fall_frac;
550
                          reg   /*[7:0]*/                       wf_rise_frac;
551
 
552
                          reg [31:0] a;
553
                          reg   [7:0]                    pm_rise_frac_filtered ;
554
                          reg   [7:0]                    pm_fall_frac_filtered ;
555
                          reg [7:0]                      clkout0_divide_int;
556
                          reg [2:0]                      clkout0_divide_frac;
557
                          reg   [7:0]                    even_part_high;
558
                          reg   [7:0]                    even_part_low;
559
                          reg  [15:0]     drp_reg1;
560
                          reg  [15:0]     drp_reg2;
561
                          reg  [5:0]     drp_regshared;
562
 
563
                          reg   [7:0]                    odd;
564
                          reg   [7:0]                    odd_and_frac;
565
 
566
                          reg   [7:0]                    pm_fall;
567
                          reg   [7:0]                    pm_rise;
568
                          reg   [7:0]                    dt;
569
                          reg   [7:0]                    dt_int;
570
                          reg [63:0]             dt_calc;
571
 
572
                          reg   [7:0]                    pm_rise_frac;
573
                          reg   [7:0]                    pm_fall_frac;
574
 
575
                          reg [31:0] a_per_in_octets;
576
                          reg [31:0] a_phase_in_cycles;
577
 
578
                                parameter precision = 0.125;
579
 
580
                          reg [31:0] phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11
581
                          reg [31: 0] phase_pos;
582
                          reg [31: 0] phase_vco;
583
                          reg [31:0] temp;// changed to 31:0 from 32:1 jt 5/2/11
584
                          reg [13:0] div_calc;
585
                          reg [16:0] phase_calc;
586
 
587
   begin
588
        `ifdef DEBUG
589
                        $display("mmcm_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d",
590
                                divide, phase, duty_cycle);
591
        `endif
592
 
593
   //convert phase to fixed
594
   if ((phase < -360000) || (phase > 360000)) begin
595
      $display("ERROR: phase of $phase is not between -360000 and 360000");
596
      $finish;
597
   end
598
 
599
 
600
      // Return value is
601
      //    Transfer data
602
      //       RESERVED     [37:36]
603
      //       FRAC_TIME    [35:33]
604
      //       FRAC_WF_FALL [32]
605
      //    Upper address is:
606
      //       RESERVED     [31:26]
607
      //       MX           [25:24]
608
      //       EDGE         [23]
609
      //       NOCOUNT      [22]
610
      //       DELAY_TIME   [21:16]
611
      //    Lower Address is:
612
      //       PHASE_MUX    [15:13]
613
      //       RESERVED     [12]
614
      //       HIGH_TIME    [11:6]
615
      //       LOW_TIME     [5:0]
616
 
617
 
618
 
619
        clkout0_divide_frac = frac / 125;
620
        clkout0_divide_int = divide;
621
 
622
        even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2);
623
        even_part_low = even_part_high;
624
 
625
        odd = clkout0_divide_int - even_part_high - even_part_low;
626
        odd_and_frac = (8*odd) + clkout0_divide_frac;
627
 
628
        lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1)
629
        ht_frac = even_part_low  - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1)
630
 
631
        pm_fall =  {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2 
632
        pm_rise = 0; //0
633
 
634
        wf_fall_frac = ((odd_and_frac >=2) && (odd_and_frac <=9)) || ((clkout0_divide_frac == 1) && (clkout0_divide_int == 2));//CRS610807
635
        wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8);//IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0)
636
 
637
 
638
 
639
        //Calculate phase in fractional cycles
640
        a_per_in_octets         = (8 * divide) + (frac / 125) ;
641
        a_phase_in_cycles       = (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors
642
        pm_rise_frac            = (a_phase_in_cycles[7:0] ==8'h00)?8'h00:a_phase_in_cycles[7:0] - {a_phase_in_cycles[7:3],3'b000};
643
 
644
        dt_calc         = ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8)
645
        dt      = dt_calc[7:0];
646
 
647
        pm_rise_frac_filtered = (pm_rise_frac >=8) ? (pm_rise_frac ) - 8: pm_rise_frac ;                                //((phase_fixed * (divide + frac / 1000)) / 360) - {pm_rise_frac[7:3],3'b000};//$rtoi(clkout0_phase * clkout0_divide / 45);//a;
648
 
649
        dt_int                  = dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt)
650
        pm_fall_frac            = pm_fall + pm_rise_frac;
651
        pm_fall_frac_filtered   = pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000};
652
 
653
        div_calc        = mmcm_pll_divider(divide, duty_cycle); //Use to determine edge[7], no count[6]
654
        phase_calc      = mmcm_pll_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]}
655
 
656
 
657
      drp_regshared[5:0] = { 2'b00, pm_fall_frac_filtered[2:0], wf_fall_frac};
658
      drp_reg2[15:0] = { 1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, 4'h0, dt[5:0] };
659
      drp_reg1[15:0] = { pm_rise_frac_filtered[2], pm_rise_frac_filtered[1], pm_rise_frac_filtered[0], 1'b0, ht_frac[5:0], lt_frac[5:0] };
660
      mmcm_frac_count_calc[37:0] =   {drp_regshared, drp_reg2, drp_reg1} ;
661
 
662
 
663
   `ifdef DEBUG
664
      $display("-%d.%d p%d>>  :DADDR_9_15 frac30to28.frac_en.wf_r_frac.dt:%b%d%d_%b:DADDR_7_13 pm_f_frac_filtered_29to27.wf_f_frac_26:%b%d:DADDR_8_14.pm_r_frac_filt_15to13.ht_frac.lt_frac:%b%b%b:", divide, frac, phase, clkout0_divide_frac, 1, wf_rise_frac, dt, pm_fall_frac_filtered, wf_fall_frac, pm_rise_frac_filtered, ht_frac, lt_frac);
665
   `endif
666
 
667
   end
668
endfunction
669
 

powered by: WebSVN 2.1.0

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