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_plus_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. Updated by Ralf Krueger
5
//    Date:             7/30/2014
6
//    Design Name:      MMCME4 DRP
7
//    Module Name:      mmcme4_drp_func.h
8
//    Version:          1.31
9
//    Target Devices:   UltraScale Plus Architecture
10
//    Tool versions:    2017.1
11
//    Description:      This header provides the functions necessary to  
12
//                      calculate the DRP register values for UltraScal+ 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
16
//              2/28/17 - Updated for Ultrascale Plus
17
// 
18
//    Disclaimer:  XILINX IS PROVIDING THIS DESIGN, CODE, OR
19
//                 INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
20
//                 PROGRAMS AND SOLUTIONS FOR XILINX DEVICES.  BY
21
//                 PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
22
//                 ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
23
//                 APPLICATION OR STANDARD, XILINX IS MAKING NO
24
//                 REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
25
//                 FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE
26
//                 RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY
27
//                 REQUIRE FOR YOUR IMPLEMENTATION.  XILINX
28
//                 EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH
29
//                 RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION,
30
//                 INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
31
//                 REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
32
//                 FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES
33
//                 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
34
//                 PURPOSE.
35
// 
36
//                 (c) Copyright 2009-2017 Xilinx, Inc.
37
//                 All rights reserved.
38
// 
39
///////////////////////////////////////////////////////////////////////////////
40
 
41
// These are user functions that should not be modified.  Changes to the defines
42
// or code within the functions may alter the accuracy of the calculations.
43
 
44
// Define debug to provide extra messages during elaboration
45
//`define DEBUG 1
46
 
47
// FRAC_PRECISION describes the width of the fractional portion of the fixed
48
// point numbers.  These should not be modified, they are for development 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_phase-divide:%d,phase:%d", divide, phase);
187
`endif
188
 
189
      if ((phase < -360000) || (phase > 360000)) begin
190
         $display("ERROR: phase of $phase is not between -360000 and 360000");
191
         $finish;
192
      end
193
 
194
      // If phase is less than 0, convert it to a positive phase shift
195
      // Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
196
      if(phase < 0) begin
197
         phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
198
      end else begin
199
         phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
200
      end
201
 
202
      // Put phase in terms of decimal number of vco clock cycles
203
      phase_in_cycles = ( phase_fixed * divide ) / 360;
204
 
205
`ifdef DEBUG
206
      $display("phase_in_cycles: %h", phase_in_cycles);
207
`endif
208
 
209
         temp  =  round_frac(phase_in_cycles, 3);
210
 
211
         // set mx to 2'b00 that the phase mux from the VCO is enabled
212
         mx                     =  2'b00;
213
         phase_mux      =  temp[`FRAC_PRECISION:`FRAC_PRECISION-2];
214
         delay_time     =  temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1];
215
 
216
   `ifdef DEBUG
217
      $display("temp: %h", temp);
218
   `endif
219
 
220
      // Setup the return value
221
      mmcm_pll_phase={mx, phase_mux, delay_time};
222
   end
223
endfunction
224
 
225
// This function takes the divide value and outputs the necessary lock values
226
function [39:0] mmcm_pll_lock_lookup
227
   (
228
      input [7:0] divide // Max M divide is 128 in UltrascalePlus
229
   );
230
 
231
   reg [5119:0]   lookup;
232
 
233
   begin
234
      lookup = {
235
         // This table is composed of:
236
         // LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
237
         40'b00110_00110_1111101000_1111101001_0000000001,      // M=1 (not allowed)
238
         40'b00110_00110_1111101000_1111101001_0000000001,      // M=2
239
         40'b01000_01000_1111101000_1111101001_0000000001,      // M=3
240
         40'b01011_01011_1111101000_1111101001_0000000001,      // M=4
241
         40'b01110_01110_1111101000_1111101001_0000000001,      // M=5
242
         40'b10001_10001_1111101000_1111101001_0000000001,      // M=6
243
         40'b10011_10011_1111101000_1111101001_0000000001,      // M=7
244
         40'b10110_10110_1111101000_1111101001_0000000001,
245
         40'b11001_11001_1111101000_1111101001_0000000001,
246
         40'b11100_11100_1111101000_1111101001_0000000001,
247
         40'b11111_11111_1110000100_1111101001_0000000001,
248
         40'b11111_11111_1100111001_1111101001_0000000001,
249
         40'b11111_11111_1011101110_1111101001_0000000001,
250
         40'b11111_11111_1010111100_1111101001_0000000001,
251
         40'b11111_11111_1010001010_1111101001_0000000001,
252
         40'b11111_11111_1001110001_1111101001_0000000001,
253
         40'b11111_11111_1000111111_1111101001_0000000001,
254
         40'b11111_11111_1000100110_1111101001_0000000001,
255
         40'b11111_11111_1000001101_1111101001_0000000001,
256
         40'b11111_11111_0111110100_1111101001_0000000001,
257
         40'b11111_11111_0111011011_1111101001_0000000001,
258
         40'b11111_11111_0111000010_1111101001_0000000001,
259
         40'b11111_11111_0110101001_1111101001_0000000001,
260
         40'b11111_11111_0110010000_1111101001_0000000001,
261
         40'b11111_11111_0110010000_1111101001_0000000001,
262
         40'b11111_11111_0101110111_1111101001_0000000001,
263
         40'b11111_11111_0101011110_1111101001_0000000001,
264
         40'b11111_11111_0101011110_1111101001_0000000001,
265
         40'b11111_11111_0101000101_1111101001_0000000001,
266
         40'b11111_11111_0101000101_1111101001_0000000001,
267
         40'b11111_11111_0100101100_1111101001_0000000001,
268
         40'b11111_11111_0100101100_1111101001_0000000001,
269
         40'b11111_11111_0100101100_1111101001_0000000001,
270
         40'b11111_11111_0100010011_1111101001_0000000001,
271
         40'b11111_11111_0100010011_1111101001_0000000001,
272
         40'b11111_11111_0100010011_1111101001_0000000001,
273
         40'b11111_11111_0011111010_1111101001_0000000001,
274
         40'b11111_11111_0011111010_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
         40'b11111_11111_0011111010_1111101001_0000000001,
304
         40'b11111_11111_0011111010_1111101001_0000000001,
305
         40'b11111_11111_0011111010_1111101001_0000000001,
306
         40'b11111_11111_0011111010_1111101001_0000000001,
307
         40'b11111_11111_0011111010_1111101001_0000000001,
308
         40'b11111_11111_0011111010_1111101001_0000000001,
309
         40'b11111_11111_0011111010_1111101001_0000000001,
310
         40'b11111_11111_0011111010_1111101001_0000000001,
311
         40'b11111_11111_0011111010_1111101001_0000000001,
312
         40'b11111_11111_0011111010_1111101001_0000000001,
313
         40'b11111_11111_0011111010_1111101001_0000000001,
314
         40'b11111_11111_0011111010_1111101001_0000000001,
315
         40'b11111_11111_0011111010_1111101001_0000000001,
316
         40'b11111_11111_0011111010_1111101001_0000000001,
317
         40'b11111_11111_0011111010_1111101001_0000000001,
318
         40'b11111_11111_0011111010_1111101001_0000000001,
319
         40'b11111_11111_0011111010_1111101001_0000000001,
320
         40'b11111_11111_0011111010_1111101001_0000000001,
321
         40'b11111_11111_0011111010_1111101001_0000000001,
322
         40'b11111_11111_0011111010_1111101001_0000000001,
323
         40'b11111_11111_0011111010_1111101001_0000000001,
324
         40'b11111_11111_0011111010_1111101001_0000000001,
325
         40'b11111_11111_0011111010_1111101001_0000000001,
326
         40'b11111_11111_0011111010_1111101001_0000000001,
327
         40'b11111_11111_0011111010_1111101001_0000000001,
328
         40'b11111_11111_0011111010_1111101001_0000000001,
329
         40'b11111_11111_0011111010_1111101001_0000000001,
330
         40'b11111_11111_0011111010_1111101001_0000000001,
331
         40'b11111_11111_0011111010_1111101001_0000000001,
332
         40'b11111_11111_0011111010_1111101001_0000000001,
333
         40'b11111_11111_0011111010_1111101001_0000000001,
334
         40'b11111_11111_0011111010_1111101001_0000000001,
335
         40'b11111_11111_0011111010_1111101001_0000000001,
336
         40'b11111_11111_0011111010_1111101001_0000000001,
337
         40'b11111_11111_0011111010_1111101001_0000000001,
338
         40'b11111_11111_0011111010_1111101001_0000000001,
339
         40'b11111_11111_0011111010_1111101001_0000000001,
340
         40'b11111_11111_0011111010_1111101001_0000000001,
341
         40'b11111_11111_0011111010_1111101001_0000000001,
342
         40'b11111_11111_0011111010_1111101001_0000000001,
343
         40'b11111_11111_0011111010_1111101001_0000000001,
344
         40'b11111_11111_0011111010_1111101001_0000000001,
345
         40'b11111_11111_0011111010_1111101001_0000000001,
346
         40'b11111_11111_0011111010_1111101001_0000000001,
347
         40'b11111_11111_0011111010_1111101001_0000000001,
348
         40'b11111_11111_0011111010_1111101001_0000000001,
349
         40'b11111_11111_0011111010_1111101001_0000000001,
350
         40'b11111_11111_0011111010_1111101001_0000000001,
351
         40'b11111_11111_0011111010_1111101001_0000000001,
352
         40'b11111_11111_0011111010_1111101001_0000000001,
353
         40'b11111_11111_0011111010_1111101001_0000000001,
354
         40'b11111_11111_0011111010_1111101001_0000000001,
355
         40'b11111_11111_0011111010_1111101001_0000000001,
356
         40'b11111_11111_0011111010_1111101001_0000000001,
357
         40'b11111_11111_0011111010_1111101001_0000000001,
358
         40'b11111_11111_0011111010_1111101001_0000000001,
359
         40'b11111_11111_0011111010_1111101001_0000000001,
360
         40'b11111_11111_0011111010_1111101001_0000000001,
361
         40'b11111_11111_0011111010_1111101001_0000000001,
362
         40'b11111_11111_0011111010_1111101001_0000000001,
363
         40'b11111_11111_0011111010_1111101001_0000000001,      // M=127
364
         40'b11111_11111_0011111010_1111101001_0000000001       // M=128
365
      };
366
 
367
      // Set lookup_entry with the explicit bits from lookup with a part select
368
      mmcm_pll_lock_lookup = lookup[ ((128-divide)*40) +: 40];
369
   `ifdef DEBUG
370
      $display("lock_lookup: %b", mmcm_pll_lock_lookup);
371
   `endif
372
   end
373
endfunction
374
 
375
// This function takes the divide value and the bandwidth setting of the MMCM
376
//  and outputs the digital filter settings necessary.
377
function [9:0] mmcm_pll_filter_lookup
378
   (
379
      input [7:0] divide, //  input [7:0] divide // Max M divide is 128 in UltraScalePlus
380
      input [8*9:0] BANDWIDTH
381
   );
382
 
383
   reg [1279:0] lookup_low;
384
   reg [1279:0] lookup_high;
385
 
386
   reg [9:0] lookup_entry;
387
 
388
   begin
389
      lookup_low = {
390
         // CP_RES_LFHF
391
        10'b0011_1111_11,    // M=1 - not legal
392
        10'b0011_1111_11,    // M=2
393
        10'b0011_1101_11,    // M=3
394
        10'b0011_0101_11,    // M=4
395
        10'b0011_1001_11,    // M=5
396
        10'b0011_1110_11,    // M=6
397
        10'b0011_1110_11,    // M=7
398
        10'b0011_0001_11,
399
        10'b0011_0110_11,
400
        10'b0011_0110_11,
401
        10'b0011_0110_11,
402
        10'b0011_1010_11,
403
        10'b0011_1010_11,
404
        10'b0011_1010_11,
405
        10'b0100_0110_11,
406
        10'b0011_1100_11,
407
        10'b1110_0110_11,
408
        10'b1111_0110_11,
409
        10'b1110_1010_11,
410
        10'b1110_1010_11,
411
        10'b1111_1010_11,
412
        10'b1111_1010_11,
413
        10'b1111_1010_11,
414
        10'b1111_1010_11,
415
        10'b1111_1010_11,
416
        10'b1101_1100_11,
417
        10'b1101_1100_11,
418
        10'b1101_1100_11,
419
        10'b1110_1100_11,
420
        10'b1110_1100_11,
421
        10'b1110_1100_11,
422
        10'b1111_1100_11,
423
        10'b1111_1100_11,
424
        10'b1111_1100_11,
425
        10'b1111_1100_11,
426
        10'b1111_1100_11,
427
        10'b1111_1100_11,
428
        10'b1110_0010_11,
429
        10'b1110_0010_11,
430
        10'b1110_0010_11,
431
        10'b1110_0010_11,
432
        10'b1111_0010_11,
433
        10'b1111_0010_11,
434
        10'b1111_0010_11,
435
        10'b1111_0010_11,
436
        10'b1111_0010_11,
437
        10'b1111_0010_11,
438
        10'b1111_0010_11,
439
        10'b1111_0010_11,
440
        10'b1111_0010_11,
441
        10'b1111_0010_11,
442
        10'b1111_0010_11,
443
        10'b1111_0010_11,
444
        10'b1111_0010_11,
445
        10'b1111_0010_11,
446
        10'b1111_0010_11,
447
        10'b1111_0010_11,
448
        10'b1111_0010_11,
449
        10'b1111_0010_11,
450
        10'b1111_0010_11,
451
        10'b1111_0010_11,
452
        10'b1111_0010_11,
453
        10'b1100_0100_11,
454
        10'b1100_0100_11,
455
        10'b1100_0100_11,
456
        10'b1100_0100_11,
457
        10'b1100_0100_11,
458
        10'b1100_0100_11,
459
        10'b1100_0100_11,
460
        10'b1100_0100_11,
461
        10'b1101_0100_11,
462
        10'b1101_0100_11,
463
        10'b1101_0100_11,
464
        10'b1101_0100_11,
465
        10'b1101_0100_11,
466
        10'b1101_0100_11,
467
        10'b1101_0100_11,
468
        10'b1110_0100_11,
469
        10'b1110_0100_11,
470
        10'b1110_0100_11,
471
        10'b1110_0100_11,
472
        10'b1110_0100_11,
473
        10'b1110_0100_11,
474
        10'b1110_0100_11,
475
        10'b1110_0100_11,
476
        10'b1111_0100_11,
477
        10'b1111_0100_11,
478
        10'b1111_0100_11,
479
        10'b1111_0100_11,
480
        10'b1111_0100_11,
481
        10'b1111_0100_11,
482
        10'b1111_0100_11,
483
        10'b1111_0100_11,
484
        10'b1111_0100_11,
485
        10'b1111_0100_11,
486
        10'b1111_0100_11,
487
        10'b1111_0100_11,
488
        10'b1111_0100_11,
489
        10'b1111_0100_11,
490
        10'b1111_0100_11,
491
        10'b1111_0100_11,
492
        10'b1111_0100_11,
493
        10'b1111_0100_11,
494
        10'b1111_0100_11,
495
        10'b1111_0100_11,
496
        10'b1111_0100_11,
497
        10'b1111_0100_11,
498
        10'b1111_0100_11,
499
        10'b1111_0100_11,
500
        10'b1111_0100_11,
501
        10'b1111_0100_11,
502
        10'b1111_0100_11,
503
        10'b1111_0100_11,
504
        10'b1111_0100_11,
505
        10'b1111_0100_11,
506
        10'b1111_0100_11,
507
        10'b1111_0100_11,
508
        10'b1111_0100_11,
509
        10'b1111_0100_11,
510
        10'b1101_1000_11,
511
        10'b1101_1000_11,
512
        10'b1101_1000_11,
513
        10'b1101_1000_11,
514
        10'b1101_1000_11,
515
        10'b1101_1000_11,
516
        10'b1101_1000_11,
517
        10'b1101_1000_11, // M=127
518
        10'b1101_1000_11  // M=128
519
};
520
 
521
      lookup_high = {
522
         // CP_RES_LFHF
523
       10'b0111_1111_11,    // M=1 - not legal
524
       10'b0111_1111_11,    // M=2
525
       10'b1110_1111_11,    // M=3
526
       10'b1111_1111_11,    // M=4
527
       10'b1111_1011_11,    // M=5
528
       10'b1111_1101_11,    // M=6
529
       10'b1111_0011_11,    // M=7
530
       10'b1110_0101_11,
531
       10'b1111_1001_11,
532
       10'b1111_1001_11,
533
       10'b1110_1110_11,
534
       10'b1111_1110_11,
535
       10'b1111_0001_11,
536
       10'b1111_0001_11,
537
       10'b1111_0001_11,
538
       10'b1110_0110_11,
539
       10'b1110_0110_11,
540
       10'b1111_0110_11,
541
       10'b1110_1010_11,
542
       10'b1110_1010_11,
543
       10'b1111_1010_11,
544
       10'b1111_1010_11,
545
       10'b1111_1010_11,
546
       10'b1111_1010_11,
547
       10'b1111_1010_11,
548
       10'b1101_1100_11,
549
       10'b1101_1100_11,
550
       10'b1101_1100_11,
551
       10'b1110_1100_11,
552
       10'b1110_1100_11,
553
       10'b1110_1100_11,
554
       10'b1111_1100_11,
555
       10'b1111_1100_11,
556
       10'b1111_1100_11,
557
       10'b1111_1100_11,
558
       10'b1111_1100_11,
559
       10'b1111_1100_11,
560
       10'b1110_0010_11,
561
       10'b1110_0010_11,
562
       10'b1110_0010_11,
563
       10'b1110_0010_11,
564
       10'b1111_0010_11,
565
       10'b1111_0010_11,
566
       10'b1111_0010_11,
567
       10'b1111_0010_11,
568
       10'b1111_0010_11,
569
       10'b1111_0010_11,
570
       10'b1111_0010_11,
571
       10'b1111_0010_11,
572
       10'b1111_0010_11,
573
       10'b1111_0010_11,
574
       10'b1111_0010_11,
575
       10'b1111_0010_11,
576
       10'b1111_0010_11,
577
       10'b1111_0010_11,
578
       10'b1111_0010_11,
579
       10'b1111_0010_11,
580
       10'b1111_0010_11,
581
       10'b1111_0010_11,
582
       10'b1111_0010_11,
583
       10'b1111_0010_11,
584
       10'b1111_0010_11,
585
       10'b1100_0100_11,
586
       10'b1100_0100_11,
587
       10'b1100_0100_11,
588
       10'b1100_0100_11,
589
       10'b1100_0100_11,
590
       10'b1100_0100_11,
591
       10'b1100_0100_11,
592
       10'b1100_0100_11,
593
       10'b1101_0100_11,
594
       10'b1101_0100_11,
595
       10'b1101_0100_11,
596
       10'b1101_0100_11,
597
       10'b1101_0100_11,
598
       10'b1101_0100_11,
599
       10'b1101_0100_11,
600
       10'b1110_0100_11,
601
       10'b1110_0100_11,
602
       10'b1110_0100_11,
603
       10'b1110_0100_11,
604
       10'b1110_0100_11,
605
       10'b1110_0100_11,
606
       10'b1110_0100_11,
607
       10'b1110_0100_11,
608
       10'b1111_0100_11,
609
       10'b1111_0100_11,
610
       10'b1111_0100_11,
611
       10'b1111_0100_11,
612
       10'b1111_0100_11,
613
       10'b1111_0100_11,
614
       10'b1111_0100_11,
615
       10'b1111_0100_11,
616
       10'b1111_0100_11,
617
       10'b1111_0100_11,
618
       10'b1111_0100_11,
619
       10'b1111_0100_11,
620
       10'b1111_0100_11,
621
       10'b1111_0100_11,
622
       10'b1111_0100_11,
623
       10'b1111_0100_11,
624
       10'b1111_0100_11,
625
       10'b1111_0100_11,
626
       10'b1111_0100_11,
627
       10'b1111_0100_11,
628
       10'b1111_0100_11,
629
       10'b1111_0100_11,
630
       10'b1111_0100_11,
631
       10'b1111_0100_11,
632
       10'b1111_0100_11,
633
       10'b1111_0100_11,
634
       10'b1111_0100_11,
635
       10'b1111_0100_11,
636
       10'b1111_0100_11,
637
       10'b1111_0100_11,
638
       10'b1111_0100_11,
639
       10'b1111_0100_11,
640
       10'b1111_0100_11,
641
       10'b1111_0100_11,
642
       10'b1101_1000_11,
643
       10'b1101_1000_11,
644
       10'b1101_1000_11,
645
       10'b1101_1000_11,
646
       10'b1101_1000_11,
647
       10'b1101_1000_11,
648
       10'b1101_1000_11,
649
       10'b1101_1000_11,
650
       10'b1101_1000_11     // M=128
651
};
652
 
653
      // Set lookup_entry with the explicit bits from lookup with a part select
654
      if(BANDWIDTH == "LOW") begin
655
         // Low Bandwidth
656
         mmcm_pll_filter_lookup = lookup_low[ ((128-divide)*10) +: 10];
657
      end else begin
658
         // High or optimized bandwidth
659
         mmcm_pll_filter_lookup = lookup_high[ ((128-divide)*10) +: 10];
660
      end
661
 
662
   `ifdef DEBUG
663
      $display("filter_lookup: %b", mmcm_pll_filter_lookup);
664
   `endif
665
   end
666
endfunction
667
 
668
// This function takes in the divide, phase, and duty cycle
669
// setting to calculate the upper and lower counter registers.
670
function [37:0] mmcm_pll_count_calc
671
   (
672
      input [7:0] divide, // Max divide is 128
673
      input signed [31:0] phase,
674
      input [31:0] duty_cycle // Multiplied by 100,000
675
   );
676
 
677
   reg [13:0] div_calc;
678
   reg [16:0] phase_calc;
679
 
680
   begin
681
   `ifdef DEBUG
682
      $display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d",
683
         divide, phase, duty_cycle);
684
   `endif
685
 
686
      // w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
687
      div_calc = mmcm_pll_divider(divide, duty_cycle);
688
      // mx[10:9], pm[8:6], dt[5:0]
689
      phase_calc = mmcm_pll_phase(divide, phase);
690
 
691
      // Return value is the upper and lower address of counter
692
      //    Upper address is:
693
      //       RESERVED    [31:26]
694
      //       MX          [25:24]
695
      //       EDGE        [23]
696
      //       NOCOUNT     [22]
697
      //       DELAY_TIME  [21:16]
698
      //    Lower Address is:
699
      //       PHASE_MUX   [15:13]
700
      //       RESERVED    [12]
701
      //       HIGH_TIME   [11:6]
702
      //       LOW_TIME    [5:0]
703
 
704
   `ifdef DEBUG
705
      $display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
706
         divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
707
         div_calc[13], div_calc[12],
708
         phase_calc[16:15], phase_calc[5:0], phase_calc[14:12]);
709
   `endif
710
 
711
      mmcm_pll_count_calc =
712
         {
713
            // Upper Address
714
            6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
715
            // Lower Address
716
            phase_calc[8:6], 1'b0, div_calc[11:0]
717
         };
718
   end
719
endfunction
720
 
721
 
722
// This function takes in the divide, phase, and duty cycle
723
// setting to calculate the upper and lower counter registers.
724
// for fractional multiply/divide functions.
725
//
726
// 
727
function [37:0] mmcm_frac_count_calc
728
   (
729
      input [7:0] divide, // Max divide is 128
730
      input signed [31:0] phase,
731
      input [31:0] duty_cycle, // Multiplied by 100,000. Not programmable in fractional
732
      input [9:0] frac // Multiplied by 1000
733
   );
734
 
735
        //Required for fractional divide calculations
736
                          reg   [7:0]                    lt_frac;
737
                          reg   [7:0]                    ht_frac;
738
 
739
                          reg   /*[7:0]*/                       wf_fall_frac;
740
                          reg   /*[7:0]*/                       wf_rise_frac;
741
 
742
                          reg [31:0] a;
743
                          reg   [7:0]                    pm_rise_frac_filtered ;
744
                          reg   [7:0]                    pm_fall_frac_filtered ;
745
                          reg [7:0]                      clkout0_divide_int;
746
                          reg [2:0]                      clkout0_divide_frac;
747
                          reg   [7:0]                    even_part_high;
748
                          reg   [7:0]                    even_part_low;
749
 
750
                          reg   [7:0]                    odd;
751
                          reg   [7:0]                    odd_and_frac;
752
 
753
                          reg   [7:0]                    pm_fall;
754
                          reg   [7:0]                    pm_rise;
755
                          reg   [7:0]                    dt;
756
                          reg   [7:0]                    dt_int;
757
                          reg [63:0]             dt_calc;
758
 
759
                          reg   [7:0]                    pm_rise_frac;
760
                          reg   [7:0]                    pm_fall_frac;
761
 
762
                          reg [31:0] a_per_in_octets;
763
                          reg [31:0] a_phase_in_cycles;
764
 
765
                                parameter precision = 0.125;
766
 
767
                          reg [31:0] phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11
768
                          reg [31: 0] phase_pos;
769
                          reg [31: 0] phase_vco;
770
                          reg [31:0] temp;// changed to 31:0 from 32:1 jt 5/2/11
771
                          reg [13:0] div_calc;
772
                          reg [16:0] phase_calc;
773
 
774
   begin
775
        `ifdef DEBUG
776
                        $display("mmcm_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d",
777
                                divide, phase, duty_cycle);
778
        `endif
779
 
780
   //convert phase to fixed
781
   if ((phase < -360000) || (phase > 360000)) begin
782
      $display("ERROR: phase of $phase is not between -360000 and 360000");
783
      $finish;
784
   end
785
 
786
 
787
      // Return value is
788
      //    Transfer data
789
      //       RESERVED     [37:36]
790
      //       FRAC_TIME    [35:33]
791
      //       FRAC_WF_FALL [32]
792
      //    Upper address is:
793
      //       RESERVED     [31:26]
794
      //       MX           [25:24]
795
      //       EDGE         [23]
796
      //       NOCOUNT      [22]
797
      //       DELAY_TIME   [21:16]
798
      //    Lower Address is:
799
      //       PHASE_MUX    [15:13]
800
      //       RESERVED     [12]
801
      //       HIGH_TIME    [11:6]
802
      //       LOW_TIME     [5:0]
803
 
804
 
805
 
806
        clkout0_divide_frac = frac / 125;
807
        clkout0_divide_int = divide;
808
 
809
        even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2);
810
        even_part_low = even_part_high;
811
 
812
        odd = clkout0_divide_int - even_part_high - even_part_low;
813
        odd_and_frac = (8*odd) + clkout0_divide_frac;
814
 
815
        lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1)
816
        ht_frac = even_part_low  - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1)
817
 
818
        pm_fall =  {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2 
819
        pm_rise = 0; //0
820
 
821
        wf_fall_frac = ((odd_and_frac >=2) && (odd_and_frac <=9)) || (clkout0_divide_int == 2 && clkout0_divide_frac == 1);   //IF(odd_and_frac>=2,IF(odd_and_frac <= 9,1,0),0)
822
        wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8);    //IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0)
823
 
824
 
825
 
826
        //Calculate phase in fractional cycles
827
        a_per_in_octets         = (8 * divide) + (frac / 125) ;
828
        a_phase_in_cycles       = (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors
829
        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};
830
 
831
        dt_calc         = ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8)
832
        dt      = dt_calc[7:0];
833
 
834
        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;
835
 
836
        dt_int                  = dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt)
837
        pm_fall_frac            = pm_fall + pm_rise_frac;
838
        pm_fall_frac_filtered   = pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000};
839
 
840
        div_calc        = mmcm_pll_divider(divide, duty_cycle); //Use to determine edge[7], no count[6]
841
        phase_calc      = mmcm_pll_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]}
842
 
843
      mmcm_frac_count_calc[37:0] =
844
         {              2'b00, pm_fall_frac_filtered[2:0], wf_fall_frac,
845
                        1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, phase_calc[10:9], 2'b00, dt[5:0],
846
                        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]
847
                } ;
848
 
849
   `ifdef DEBUG
850
      $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);
851
   `endif
852
 
853
   end
854
endfunction
855
 

powered by: WebSVN 2.1.0

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