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_7s_pll.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, Karl Kurbjun and Carl Ribbing
5
//    Date:             7/30/2014
6
//    Design Name:      PLLE2 DRP
7
//    Module Name:      plle2_drp_func.h
8
//    Version:          2.00
9
//    Target Devices:   7 Series || PLL
10
//    Tool versions:    2014.3
11
//    Description:      This header provides the functions necessary to  
12
//                      calculate the DRP register values for the V6 PLL.
13
//                      Updated for CR663854.
14
// 
15
//    Disclaimer:  XILINX IS PROVIDING THIS DESIGN, CODE, OR
16
//                 INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
17
//                 PROGRAMS AND SOLUTIONS FOR XILINX DEVICES.  BY
18
//                 PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
19
//                 ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
20
//                 APPLICATION OR STANDARD, XILINX IS MAKING NO
21
//                 REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
22
//                 FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE
23
//                 RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY
24
//                 REQUIRE FOR YOUR IMPLEMENTATION.  XILINX
25
//                 EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH
26
//                 RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION,
27
//                 INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
28
//                 REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
29
//                 FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES
30
//                 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31
//                 PURPOSE.
32
// 
33
//                 (c) Copyright 2009-2010 Xilinx, Inc.
34
//                 All rights reserved.
35
// 
36
///////////////////////////////////////////////////////////////////////////////
37
 
38
// These are user functions that should not be modified.  Changes to the defines
39
// or code within the functions may alter the accuracy of the calculations.
40
 
41
// Define debug to provide extra messages durring elaboration
42
//`define DEBUG 1
43
 
44
// FRAC_PRECISION describes the width of the fractional portion of the fixed
45
//    point numbers.  These should not be modified, they are for development 
46
//    only
47
`define FRAC_PRECISION  10
48
// FIXED_WIDTH describes the total size for fixed point calculations(int+frac).
49
// Warning: L.50 and below will not calculate properly with FIXED_WIDTHs 
50
//    greater than 32
51
`define FIXED_WIDTH     32
52
 
53
// This function takes a fixed point number and rounds it to the nearest
54
//    fractional precision bit.
55
function [`FIXED_WIDTH:1] round_frac
56
   (
57
      // Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number
58
      input [`FIXED_WIDTH:1] decimal,
59
 
60
      // This describes the precision of the fraction, for example a value
61
      //    of 1 would modify the fractional so that instead of being a .16
62
      //    fractional, it would be a .1 (rounded to the nearest 0.5 in turn)
63
      input [`FIXED_WIDTH:1] precision
64
   );
65
 
66
   begin
67
 
68
`ifdef DEBUG
69
      $display("round_frac - decimal: %h, precision: %h", decimal, precision);
70
`endif
71
      // If the fractional precision bit is high then round up
72
      if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin
73
         round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision));
74
      end else begin
75
         round_frac = decimal;
76
      end
77
`ifdef DEBUG
78
      $display("round_frac: %h", round_frac);
79
`endif
80
   end
81
endfunction
82
 
83
// This function calculates high_time, low_time, w_edge, and no_count
84
//    of a non-fractional counter based on the divide and duty cycle
85
//
86
// NOTE: high_time and low_time are returned as integers between 0 and 63 
87
//    inclusive.  64 should equal 6'b000000 (in other words it is okay to 
88
//    ignore the overflow)
89
function [13:0] mmcm_pll_divider
90
   (
91
      input [7:0] divide,        // Max divide is 128
92
      input [31:0] duty_cycle    // Duty cycle is multiplied by 100,000
93
   );
94
 
95
   reg [`FIXED_WIDTH:1]    duty_cycle_fix;
96
 
97
   // High/Low time is initially calculated with a wider integer to prevent a
98
   // calculation error when it overflows to 64.
99
   reg [6:0]               high_time;
100
   reg [6:0]               low_time;
101
   reg                     w_edge;
102
   reg                     no_count;
103
 
104
   reg [`FIXED_WIDTH:1]    temp;
105
 
106
   begin
107
      // Duty Cycle must be between 0 and 1,000
108
      if(duty_cycle <=0 || duty_cycle >= 100000) begin
109
         $display("ERROR: duty_cycle: %d is invalid", duty_cycle);
110
         $finish;
111
      end
112
 
113
      // Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point
114
      duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000;
115
 
116
`ifdef DEBUG
117
      $display("duty_cycle_fix: %h", duty_cycle_fix);
118
`endif
119
 
120
      // If the divide is 1 nothing needs to be set except the no_count bit.
121
      //    Other values are dummies
122
      if(divide == 7'h01) begin
123
         high_time   = 7'h01;
124
         w_edge      = 1'b0;
125
         low_time    = 7'h01;
126
         no_count    = 1'b1;
127
      end else begin
128
         temp = round_frac(duty_cycle_fix*divide, 1);
129
 
130
         // comes from above round_frac
131
         high_time   = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1];
132
         // If the duty cycle * divide rounded is .5 or greater then this bit
133
         //    is set.
134
         w_edge      = temp[`FRAC_PRECISION]; // comes from round_frac
135
 
136
         // If the high time comes out to 0, it needs to be set to at least 1
137
         // and w_edge set to 0
138
         if(high_time == 7'h00) begin
139
            high_time   = 7'h01;
140
            w_edge      = 1'b0;
141
         end
142
 
143
         if(high_time == divide) begin
144
            high_time   = divide - 1;
145
            w_edge      = 1'b1;
146
         end
147
 
148
         // Calculate low_time based on the divide setting and set no_count to
149
         //    0 as it is only used when divide is 1.
150
         low_time    = divide - high_time;
151
         no_count    = 1'b0;
152
      end
153
 
154
      // Set the return value.
155
      mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]};
156
   end
157
endfunction
158
 
159
// This function calculates mx, delay_time, and phase_mux 
160
//  of a non-fractional counter based on the divide and phase
161
//
162
// NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux
163
//    is used.
164
function [10:0] mmcm_pll_phase
165
   (
166
      // divide must be an integer (use fractional if not)
167
      //  assumed that divide already checked to be valid
168
      input [7:0] divide, // Max divide is 128
169
 
170
      // Phase is given in degrees (-360,000 to 360,000)
171
      input signed [31:0] phase
172
   );
173
 
174
   reg [`FIXED_WIDTH:1] phase_in_cycles;
175
   reg [`FIXED_WIDTH:1] phase_fixed;
176
   reg [1:0]            mx;
177
   reg [5:0]            delay_time;
178
   reg [2:0]            phase_mux;
179
 
180
   reg [`FIXED_WIDTH:1] temp;
181
 
182
   begin
183
`ifdef DEBUG
184
      $display("mmcm_pll_phase-divide:%d,phase:%d",
185
         divide, phase);
186
`endif
187
 
188
      if ((phase < -360000) || (phase > 360000)) begin
189
         $display("ERROR: phase of $phase is not between -360000 and 360000");
190
         $finish;
191
      end
192
 
193
      // If phase is less than 0, convert it to a positive phase shift
194
      // Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
195
      if(phase < 0) begin
196
         phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
197
      end else begin
198
         phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
199
      end
200
 
201
      // Put phase in terms of decimal number of vco clock cycles
202
      phase_in_cycles = ( phase_fixed * divide ) / 360;
203
 
204
`ifdef DEBUG
205
      $display("phase_in_cycles: %h", phase_in_cycles);
206
`endif
207
 
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 [6:0] divide // Max divide is 64
229
   );
230
 
231
   reg [2559: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,
238
         40'b00110_00110_1111101000_1111101001_0000000001,
239
         40'b01000_01000_1111101000_1111101001_0000000001,
240
         40'b01011_01011_1111101000_1111101001_0000000001,
241
         40'b01110_01110_1111101000_1111101001_0000000001,
242
         40'b10001_10001_1111101000_1111101001_0000000001,
243
         40'b10011_10011_1111101000_1111101001_0000000001,
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
      };
302
 
303
      // Set lookup_entry with the explicit bits from lookup with a part select
304
      mmcm_pll_lock_lookup = lookup[ ((64-divide)*40) +: 40];
305
   `ifdef DEBUG
306
      $display("lock_lookup: %b", mmcm_pll_lock_lookup);
307
   `endif
308
   end
309
endfunction
310
 
311
// This function takes the divide value and the bandwidth setting of the PLL
312
//  and outputs the digital filter settings necessary.
313
function [9:0] mmcm_pll_filter_lookup
314
   (
315
      input [6:0] divide, // Max divide is 64
316
      input [8*9:0] BANDWIDTH
317
   );
318
 
319
   reg [639:0] lookup_low;
320
   reg [639:0] lookup_high;
321
 
322
   reg [9:0] lookup_entry;
323
 
324
   begin
325
      lookup_low = {
326
         // CP_RES_LFHF
327
         10'b0010_1111_00,
328
         10'b0010_1111_00,
329
         10'b0010_0111_00,
330
         10'b0010_1101_00,
331
         10'b0010_0101_00,
332
         10'b0010_0101_00,
333
         10'b0010_1001_00,
334
         10'b0010_1110_00,
335
         10'b0010_1110_00,
336
         10'b0010_0001_00,
337
         10'b0010_0001_00,
338
         10'b0010_0110_00,
339
         10'b0010_0110_00,
340
         10'b0010_0110_00,
341
         10'b0010_0110_00,
342
         10'b0010_1010_00,
343
         10'b0010_1010_00,
344
         10'b0010_1010_00,
345
         10'b0010_1010_00,
346
         10'b0010_1100_00,
347
         10'b0010_1100_00,
348
         10'b0010_1100_00,
349
         10'b0010_1100_00,
350
         10'b0010_1100_00,
351
         10'b0010_1100_00,
352
         10'b0010_1100_00,
353
         10'b0010_1100_00,
354
         10'b0010_1100_00,
355
         10'b0010_1100_00,
356
         10'b0010_1100_00,
357
         10'b0010_0010_00,
358
         10'b0010_0010_00,
359
         10'b0010_0010_00,
360
         10'b0010_0010_00,
361
         10'b0010_0010_00,
362
         10'b0010_0010_00,
363
         10'b0010_0010_00,
364
         10'b0010_0010_00,
365
         10'b0010_0010_00,
366
         10'b0010_0010_00,
367
         10'b0011_1100_00,
368
         10'b0011_1100_00,
369
         10'b0011_1100_00,
370
         10'b0011_1100_00,
371
         10'b0011_1100_00,
372
         10'b0011_1100_00,
373
         10'b0011_1100_00,
374
         10'b0010_0100_00,
375
         10'b0010_0100_00,
376
         10'b0010_0100_00,
377
         10'b0010_0100_00,
378
         10'b0010_0100_00,
379
         10'b0010_0100_00,
380
         10'b0010_0100_00,
381
         10'b0010_0100_00,
382
         10'b0010_0100_00,
383
         10'b0010_0100_00,
384
         10'b0010_0100_00,
385
         10'b0010_0100_00,
386
         10'b0010_0100_00,
387
         10'b0010_0100_00,
388
         10'b0010_0100_00,
389
         10'b0010_0100_00,
390
         10'b0010_0100_00
391
      };
392
 
393
      lookup_high = {
394
         // CP_RES_LFHF
395
         10'b0011_0111_00,
396
         10'b0011_0111_00,
397
         10'b0101_1111_00,
398
         10'b0111_1111_00,
399
         10'b0111_1011_00,
400
         10'b1101_0111_00,
401
         10'b1110_1011_00,
402
         10'b1110_1101_00,
403
         10'b1111_1101_00,
404
         10'b1111_0111_00,
405
         10'b1111_1011_00,
406
         10'b1111_1101_00,
407
         10'b1111_0011_00,
408
         10'b1110_0101_00,
409
         10'b1111_0101_00,
410
         10'b1111_0101_00,
411
         10'b1111_0101_00,
412
         10'b1111_0101_00,
413
         10'b0111_0110_00,
414
         10'b0111_0110_00,
415
         10'b0111_0110_00,
416
         10'b0111_0110_00,
417
         10'b0101_1100_00,
418
         10'b0101_1100_00,
419
         10'b0101_1100_00,
420
         10'b1100_0001_00,
421
         10'b1100_0001_00,
422
         10'b1100_0001_00,
423
         10'b1100_0001_00,
424
         10'b1100_0001_00,
425
         10'b1100_0001_00,
426
         10'b1100_0001_00,
427
         10'b1100_0001_00,
428
         10'b0100_0010_00,
429
         10'b0100_0010_00,
430
         10'b0100_0010_00,
431
         10'b0010_1000_00,
432
         10'b0010_1000_00,
433
         10'b0010_1000_00,
434
         10'b0011_0100_00,
435
         10'b0010_1000_00,
436
         10'b0010_1000_00,
437
         10'b0010_1000_00,
438
         10'b0010_1000_00,
439
         10'b0010_1000_00,
440
         10'b0010_1000_00,
441
         10'b0010_1000_00,
442
         10'b0010_1000_00,
443
         10'b0010_1000_00,
444
         10'b0010_1000_00,
445
         10'b0010_1000_00,
446
         10'b0010_1000_00,
447
         10'b0010_1000_00,
448
         10'b0100_1100_00,
449
         10'b0100_1100_00,
450
         10'b0100_1100_00,
451
         10'b0100_1100_00,
452
         10'b0100_1100_00,
453
         10'b0100_1100_00,
454
         10'b0100_1100_00,
455
         10'b0010_0100_00,
456
         10'b0010_0100_00,
457
         10'b0010_0100_00,
458
         10'b0010_0100_00
459
      };
460
 
461
      // Set lookup_entry with the explicit bits from lookup with a part select
462
      if(BANDWIDTH == "LOW") begin
463
         // Low Bandwidth
464
         mmcm_pll_filter_lookup = lookup_low[ ((64-divide)*10) +: 10];
465
      end else begin
466
         // High or optimized bandwidth
467
         mmcm_pll_filter_lookup = lookup_high[ ((64-divide)*10) +: 10];
468
      end
469
 
470
   `ifdef DEBUG
471
      $display("filter_lookup: %b", mmcm_pll_filter_lookup);
472
   `endif
473
   end
474
endfunction
475
 
476
// This function takes in the divide, phase, and duty cycle
477
// setting to calculate the upper and lower counter registers.
478
function [37:0] mmcm_pll_count_calc
479
   (
480
      input [7:0] divide, // Max divide is 128
481
      input signed [31:0] phase,
482
      input [31:0] duty_cycle // Multiplied by 100,000
483
   );
484
 
485
   reg [13:0] div_calc;
486
   reg [16:0] phase_calc;
487
 
488
   begin
489
   `ifdef DEBUG
490
      $display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d",
491
         divide, phase, duty_cycle);
492
`endif
493
 
494
      // w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
495
      div_calc = mmcm_pll_divider(divide, duty_cycle);
496
      // mx[10:9], pm[8:6], dt[5:0]
497
      phase_calc = mmcm_pll_phase(divide, phase);
498
 
499
      // Return value is the upper and lower address of counter
500
      //    Upper address is:
501
      //       RESERVED    [31:26]
502
      //       MX          [25:24]
503
      //       EDGE        [23]
504
      //       NOCOUNT     [22]
505
      //       DELAY_TIME  [21:16]
506
      //    Lower Address is:
507
      //       PHASE_MUX   [15:13]
508
      //       RESERVED    [12]
509
      //       HIGH_TIME   [11:6]
510
      //       LOW_TIME    [5:0]
511
 
512
`ifdef DEBUG
513
      $display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
514
         divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
515
         div_calc[13], div_calc[12],
516
         phase_calc[16:15], phase_calc[5:0], phase_calc[14:12]);
517
`endif
518
 
519
      mmcm_pll_count_calc =
520
         {
521
            // Upper Address
522
            6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
523
            // Lower Address
524
            phase_calc[8:6], 1'b0, div_calc[11:0]
525
         };
526
   end
527
endfunction

powered by: WebSVN 2.1.0

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