release duifei_cmos_v1.0

the function of duifei_cmos is tested, add vio_rfcontrol initial value
This commit is contained in:
2023-04-01 15:40:28 +08:00
parent 2e92604bfb
commit 1ca0bbc06e
71 changed files with 31058 additions and 8927 deletions
@@ -1,283 +0,0 @@
`pragma protect begin_protected
`pragma protect version = 1
`pragma protect encrypt_agent = "XILINX"
`pragma protect encrypt_agent_info = "Xilinx Encryption Tool 2019.1"
`pragma protect key_keyowner = "Cadence Design Systems.", key_keyname = "cds_rsa_key", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 64)
`pragma protect key_block
GbQWy7xyRnDVKNEgu/syxcQSo3KIIWjSBPIwi/pSAYCe9sIQf1xA0ykhHf7s3r7GRWRS+sel+0Xx
XWe4lBDDrw==
`pragma protect key_keyowner = "Synopsys", key_keyname = "SNPS-VCS-RSA-2", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 128)
`pragma protect key_block
rLh670IEMVEjBamdsB+LhhoxrK6I5H9wfmPCOFqaLelJt08QWbH7WNvjIhNNz7hnkT7w+wDWT6AH
9ZJgOGPSJmj9pWoXHAojkkRBTIXpFT11+IDyFQ4FgN2TPXWILoYGY+uZG1GlGN7dsEIm5HUCUy2c
eVhT3XSIJDvufMyiJUc=
`pragma protect key_keyowner = "Aldec", key_keyname = "ALDEC15_001", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
KgKxjU+tI9TXRZLkaaosEf4JcTfzGtF82aOinFlVe78eUyHdMvwHHcKsxUKAjkhYW491bZ0jTKit
pNc3Ov7QvW8kjTq3JHFuCf7SmCYRrmElQv0XobTk6mnMb4khaXw9wTP8YMS0XAqk3Bksal+aKfvX
LL/afyM4UwBfiIb04ZgvhdOlp/dkCqWqZyDL2qVScyGrZcDCW3CCZTVQO29hqMLZP5S82keXpBv3
5J7nHHbQ3n4dxsRykYtJtwg7JDyqGHiwhj1HDtjhG+LX9ry1wy5YgvxrzSfKoouAeHCKXcG7TY0a
sz4nRUsC3Yg3/CybYyPjvVJDirIzWRzSD6l1DQ==
`pragma protect key_keyowner = "ATRENTA", key_keyname = "ATR-SG-2015-RSA-3", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
ItrqCM44kZl0WwWeSAjetSYD0fPwYZdVjFp5cRl5XZyoYOMWKCVEXncinM06x/MDVlkYiXgz2Xqn
6ui7jR7RwOKALvqoqdehIoXZUA/5yPMntFpxPcFIY1DonBI4CuMjhqCuB2RkxKNIco5Z7/QxCk49
MCUlvIFRd2MXM+zvhCRdja7e9blnwJEUETukq+EKuAwuR3+VN3uzCXsNtgBqMZa2CyM6Z60fStuc
v1eiDP/hxOimuSfsS7evakl5WMjgZuj4Jld1+y5hTOuPvw4+s3KIb2ejIH2r/I7ui7sWUZTah36a
4QexKWP16Ghv319FCz4KExZ6lY+7HuoO55lf4A==
`pragma protect key_keyowner = "Xilinx", key_keyname = "xilinxt_2019_02", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
FGUAaXx6dK7W5dgDUXY6j9xLpCHdbPvbaH+O+ozu9kcNjL5BJcGWnTdooAxaZdBsOZBvrVuXUU4v
ev5owQI9+5/+8aoXfeX2zZHp++ESqotCFj5ykw8BPjwCOCZz+tiV1Q8ISqf/NCuDNU2KJyvQUsFX
cOXAwCPvrI5SwQ04u9sVTaHwAuTuRw3j6nkt6BHWrjKpq9pUfNH4L04ag/tUGVpnlcSBGewN0ieC
xkzVV1mPCyCu/thxu0k0yda5pS/u3MFeC1N8rTrSsLEZMUiPYg/BwwWGT7D/s9FCMbbM2kyoUXpa
draqn+K8c06CQxLI+ieilCd38M25buwOc3ANjg==
`pragma protect key_keyowner = "Mentor Graphics Corporation", key_keyname = "MGC-VELOCE-RSA", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 128)
`pragma protect key_block
ucIv1ZvudBg6K9ubpyCObknzSo2JKwxETiac5kbTyw0xwj34bo+xJ/DnUCoAdEVHZcAwDc9Fhbhv
j5a7MwnHY+TpzDjhwdN75A97jOZ4V65wcuFErbH19OSacDchGykcwXCiaA5haDJK2hF1qPxu7TtO
R19uHYIhWP+7IpmjTiQ=
`pragma protect key_keyowner = "Mentor Graphics Corporation", key_keyname = "MGC-VERIF-SIM-RSA-2", key_method = "rsa"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256)
`pragma protect key_block
AI09c0Va0j6swrG6tMKXPaWcjMpXDnvuIze3bAe9Cj0tCXFumugM/pZL81X53kMwmKPvRCpTi8DM
kLLATubglrp6DudyaIY943skTmlH+as6fKaHODrTcy4CDIP4kKrok/7y1rBI6+YAfN3ZIW+45MiV
cHuhXHXxxXblzCT6obAZK5QUCP2qZKgO0jjI1RD7ZEJuS/mX5wkIAvOe8L1HBkyUsRq6Cu30W6u9
7VI3LOy7TZqb6Nix6Ok85ylO82KP12tdXY2IRivakKu4fdWQ6vc3ARiefSR0+RDmE/eZzhzQbt26
mf7t4ZoEITJYnmd5zcenAnw+6AO3fUwtTLT81Q==
`pragma protect data_method = "AES128-CBC"
`pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 12464)
`pragma protect data_block
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
hsEprM3gDA7yAWiwAy3nxW57jdofbM5LfU0HVc1mK3FN0pfA/Fg0HWk0RX6K1vbYorZ2YFYwkpIK
Spx8l1Y/4Kpd/0yvO9c4f8OcsEc6LfaQSV83l2H8v6NalHbhaZ2gKxmDZi/k03xDyL8v6GCn18bp
dB5LUUJUKbnsl6q5E9b8DkJqSnAaHRLJDnEvMp6EfGlpc52On3lCg0wI5XERerziamjcMH44VZfd
j8z1WUyHlyOSmkvZdJ66PfYWu5BxCG7hfdtSGROPtIxs36iLmesyYm4yHKwwbWgNIrLgra92DF2L
R6e0RM1WWkcJHei4v89Nmwym4k0dKMTX1HkfTogoprrdIyDYj4qMmeTqfl0U8pRehVs6/zy4x8HS
0V2+smFFQ/BZxLQ4eV8NHKeszc4kI6jJ3OCncsP57tfkE6TmVTtWKiimERISYB4KhUpblsbN6zyX
Bni5ezNwl9XdaBq9c90k+QQmaMGeyQbczdGy9ufcC269vB1FU5+a67Ew8h0jPAPeYHvsw4kGsTSh
xnhGNUHRuPoNmQYBjI2LztvnbGuoucUVntUi5quKpKAK1fOZerZTh+kr5PjaW0YlozpL5CtElvS3
eqqkVT8a5mdW+sWTxJxTjqronag0QACsSwbA9qurCW9IdcOO+0D7nzfIJIFrWKx+D71JhKNvOmUa
NmCy9l+wzdpcLs1zvS3o3zwEgUWOOHzITgzOxtDhIuBcJkg9lS+o5b+W+U9fplCbVFjYd5ZDa2sX
90/8XCJA0a9VcsSrh1LoO0V3YX80VWdNPY79OUOlqftl3rNXVXE=
`pragma protect end_protected
@@ -68,17 +68,17 @@ input clk;
output reg [0 : 0] probe_out0 = 'h0 ;
output reg [0 : 0] probe_out1 = 'h0 ;
output reg [15 : 0] probe_out2 = 'h0000 ;
output reg [15 : 0] probe_out2 = 'h05DC ;
output reg [7 : 0] probe_out3 = 'h00 ;
output reg [3 : 0] probe_out4 = 'h0 ;
output reg [3 : 0] probe_out5 = 'h0 ;
output reg [3 : 0] probe_out6 = 'h0 ;
output reg [3 : 0] probe_out7 = 'h0 ;
output reg [7 : 0] probe_out8 = 'h00 ;
output reg [7 : 0] probe_out9 = 'h00 ;
output reg [7 : 0] probe_out9 = 'h04 ;
output reg [15 : 0] probe_out10 = 'h0000 ;
output reg [15 : 0] probe_out11 = 'h0000 ;
output reg [15 : 0] probe_out12 = 'h0000 ;
output reg [15 : 0] probe_out12 = 'h1680 ;
endmodule
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
// Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
// --------------------------------------------------------------------------------
// Tool Version: Vivado v.2019.1.3 (lin64) Build 2644227 Wed Sep 4 09:44:18 MDT 2019
// Date : Thu Mar 30 16:42:42 2023
// Date : Sat Apr 1 15:00:25 2023
// Host : JOSH-ASUS-Z690 running 64-bit Ubuntu 20.04.6 LTS
// Command : write_verilog -force -mode synth_stub
// /home/josh/Workspace/vivado-git/projects/duifei/duifei_cmos/ip/managed_ip_project/managed_ip_project.runs/vio_rfcontrl_synth_1/vio_rfcontrl_stub.v
@@ -1,7 +1,7 @@
-- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
-- --------------------------------------------------------------------------------
-- Tool Version: Vivado v.2019.1.3 (lin64) Build 2644227 Wed Sep 4 09:44:18 MDT 2019
-- Date : Thu Mar 30 16:42:42 2023
-- Date : Sat Apr 1 15:00:25 2023
-- Host : JOSH-ASUS-Z690 running 64-bit Ubuntu 20.04.6 LTS
-- Command : write_vhdl -force -mode synth_stub
-- /home/josh/Workspace/vivado-git/projects/duifei/duifei_cmos/ip/managed_ip_project/managed_ip_project.runs/vio_rfcontrl_synth_1/vio_rfcontrl_stub.vhdl
@@ -1,671 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
// Company: Xilinx
// Engineer: Jim Tatsukawa, Karl Kurbjun and Carl Ribbing
// Date: 7/30/2014
// Design Name: MMCME2 DRP
// Module Name: mmcme2_drp_func.h
// Version: 1.04
// Target Devices: 7 Series || MMCM
// Tool versions: 2014.3
// Description: This header provides the functions necessary to
// calculate the DRP register values for the V6 MMCM.
//
// Revision Notes: 3/12 - Updating lookup_low/lookup_high (CR)
// 4/13 - Fractional divide function in mmcm_frac_count_calc function. CRS610807
//
// Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR
// INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
// PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY
// PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
// APPLICATION OR STANDARD, XILINX IS MAKING NO
// REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
// FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE
// RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY
// REQUIRE FOR YOUR IMPLEMENTATION. XILINX
// EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH
// RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION,
// INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
// REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE.
//
// (c) Copyright 2009-2010 Xilinx, Inc.
// All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
// These are user functions that should not be modified. Changes to the defines
// or code within the functions may alter the accuracy of the calculations.
// Define debug to provide extra messages durring elaboration
//`define DEBUG 1
// FRAC_PRECISION describes the width of the fractional portion of the fixed
// point numbers. These should not be modified, they are for development
// only
`define FRAC_PRECISION 10
// FIXED_WIDTH describes the total size for fixed point calculations(int+frac).
// Warning: L.50 and below will not calculate properly with FIXED_WIDTHs
// greater than 32
`define FIXED_WIDTH 32
// This function takes a fixed point number and rounds it to the nearest
// fractional precision bit.
function [`FIXED_WIDTH:1] round_frac
(
// Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number
input [`FIXED_WIDTH:1] decimal,
// This describes the precision of the fraction, for example a value
// of 1 would modify the fractional so that instead of being a .16
// fractional, it would be a .1 (rounded to the nearest 0.5 in turn)
input [`FIXED_WIDTH:1] precision
);
begin
`ifdef DEBUG
$display("round_frac - decimal: %h, precision: %h", decimal, precision);
`endif
// If the fractional precision bit is high then round up
if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin
round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision));
end else begin
round_frac = decimal;
end
`ifdef DEBUG
$display("round_frac: %h", round_frac);
`endif
end
endfunction
// This function calculates high_time, low_time, w_edge, and no_count
// of a non-fractional counter based on the divide and duty cycle
//
// NOTE: high_time and low_time are returned as integers between 0 and 63
// inclusive. 64 should equal 6'b000000 (in other words it is okay to
// ignore the overflow)
function [13:0] mmcm_pll_divider
(
input [7:0] divide, // Max divide is 128
input [31:0] duty_cycle // Duty cycle is multiplied by 100,000
);
reg [`FIXED_WIDTH:1] duty_cycle_fix;
// High/Low time is initially calculated with a wider integer to prevent a
// calculation error when it overflows to 64.
reg [6:0] high_time;
reg [6:0] low_time;
reg w_edge;
reg no_count;
reg [`FIXED_WIDTH:1] temp;
begin
// Duty Cycle must be between 0 and 1,000
if(duty_cycle <=0 || duty_cycle >= 100000) begin
`ifndef SYNTHESIS
$display("ERROR: duty_cycle: %d is invalid", duty_cycle);
`endif
$finish;
end
// Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point
duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000;
`ifdef DEBUG
$display("duty_cycle_fix: %h", duty_cycle_fix);
`endif
// If the divide is 1 nothing needs to be set except the no_count bit.
// Other values are dummies
if(divide == 7'h01) begin
high_time = 7'h01;
w_edge = 1'b0;
low_time = 7'h01;
no_count = 1'b1;
end else begin
temp = round_frac(duty_cycle_fix*divide, 1);
// comes from above round_frac
high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1];
// If the duty cycle * divide rounded is .5 or greater then this bit
// is set.
w_edge = temp[`FRAC_PRECISION]; // comes from round_frac
// If the high time comes out to 0, it needs to be set to at least 1
// and w_edge set to 0
if(high_time == 7'h00) begin
high_time = 7'h01;
w_edge = 1'b0;
end
if(high_time == divide) begin
high_time = divide - 1;
w_edge = 1'b1;
end
// Calculate low_time based on the divide setting and set no_count to
// 0 as it is only used when divide is 1.
low_time = divide - high_time;
no_count = 1'b0;
end
// Set the return value.
mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]};
end
endfunction
// This function calculates mx, delay_time, and phase_mux
// of a non-fractional counter based on the divide and phase
//
// NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux
// is used.
function [10:0] mmcm_pll_phase
(
// divide must be an integer (use fractional if not)
// assumed that divide already checked to be valid
input [7:0] divide, // Max divide is 128
// Phase is given in degrees (-360,000 to 360,000)
input signed [31:0] phase
);
reg [`FIXED_WIDTH:1] phase_in_cycles;
reg [`FIXED_WIDTH:1] phase_fixed;
reg [1:0] mx;
reg [5:0] delay_time;
reg [2:0] phase_mux;
reg [`FIXED_WIDTH:1] temp;
begin
`ifdef DEBUG
$display("mmcm_pll_phase-divide:%d,phase:%d",
divide, phase);
`endif
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// If phase is less than 0, convert it to a positive phase shift
// Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
if(phase < 0) begin
phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
end else begin
phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
end
// Put phase in terms of decimal number of vco clock cycles
phase_in_cycles = ( phase_fixed * divide ) / 360;
`ifdef DEBUG
$display("phase_in_cycles: %h", phase_in_cycles);
`endif
temp = round_frac(phase_in_cycles, 3);
// set mx to 2'b00 that the phase mux from the VCO is enabled
mx = 2'b00;
phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2];
delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1];
`ifdef DEBUG
$display("temp: %h", temp);
`endif
// Setup the return value
mmcm_pll_phase={mx, phase_mux, delay_time};
end
endfunction
// This function takes the divide value and outputs the necessary lock values
function [39:0] mmcm_pll_lock_lookup
(
input [6:0] divide // Max divide is 64
);
reg [2559:0] lookup;
begin
lookup = {
// This table is composed of:
// LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
40'b00110_00110_1111101000_1111101001_0000000001,
40'b00110_00110_1111101000_1111101001_0000000001,
40'b01000_01000_1111101000_1111101001_0000000001,
40'b01011_01011_1111101000_1111101001_0000000001,
40'b01110_01110_1111101000_1111101001_0000000001,
40'b10001_10001_1111101000_1111101001_0000000001,
40'b10011_10011_1111101000_1111101001_0000000001,
40'b10110_10110_1111101000_1111101001_0000000001,
40'b11001_11001_1111101000_1111101001_0000000001,
40'b11100_11100_1111101000_1111101001_0000000001,
40'b11111_11111_1110000100_1111101001_0000000001,
40'b11111_11111_1100111001_1111101001_0000000001,
40'b11111_11111_1011101110_1111101001_0000000001,
40'b11111_11111_1010111100_1111101001_0000000001,
40'b11111_11111_1010001010_1111101001_0000000001,
40'b11111_11111_1001110001_1111101001_0000000001,
40'b11111_11111_1000111111_1111101001_0000000001,
40'b11111_11111_1000100110_1111101001_0000000001,
40'b11111_11111_1000001101_1111101001_0000000001,
40'b11111_11111_0111110100_1111101001_0000000001,
40'b11111_11111_0111011011_1111101001_0000000001,
40'b11111_11111_0111000010_1111101001_0000000001,
40'b11111_11111_0110101001_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0101110111_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001
};
// Set lookup_entry with the explicit bits from lookup with a part select
mmcm_pll_lock_lookup = lookup[ ((64-divide)*40) +: 40];
`ifdef DEBUG
$display("lock_lookup: %b", mmcm_pll_lock_lookup);
`endif
end
endfunction
// This function takes the divide value and the bandwidth setting of the MMCM
// and outputs the digital filter settings necessary.
function [9:0] mmcm_pll_filter_lookup
(
input [6:0] divide, // Max divide is 64
input [8*9:0] BANDWIDTH
);
reg [639:0] lookup_low;
reg [639:0] lookup_high;
reg [9:0] lookup_entry;
begin
lookup_low = {
// CP_RES_LFHF
10'b0010_1111_00,
10'b0010_1111_00,
10'b0010_1111_00,
10'b0010_1111_00,
10'b0010_0111_00,
10'b0010_1011_00,
10'b0010_1101_00,
10'b0010_0011_00,
10'b0010_0101_00,
10'b0010_0101_00,
10'b0010_1001_00,
10'b0010_1110_00,
10'b0010_1110_00,
10'b0010_1110_00,
10'b0010_1110_00,
10'b0010_0001_00,
10'b0010_0001_00,
10'b0010_0001_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_1010_00,
10'b0010_1010_00,
10'b0010_1010_00,
10'b0010_1010_00,
10'b0010_1010_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00
};
lookup_high = {
// CP_RES_LFHF
10'b0010_1111_00,
10'b0100_1111_00,
10'b0101_1011_00,
10'b0111_0111_00,
10'b1101_0111_00,
10'b1110_1011_00,
10'b1110_1101_00,
10'b1111_0011_00,
10'b1110_0101_00,
10'b1111_0101_00,
10'b1111_1001_00,
10'b1101_0001_00,
10'b1111_1001_00,
10'b1111_1001_00,
10'b1111_1001_00,
10'b1111_1001_00,
10'b1111_0101_00,
10'b1111_0101_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b0101_1100_00,
10'b0101_1100_00,
10'b0101_1100_00,
10'b0101_1100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0011_0100_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0111_0001_00,
10'b0111_0001_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0110_0001_00,
10'b0110_0001_00,
10'b0101_0110_00,
10'b0101_0110_00,
10'b0101_0110_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0100_1010_00,
10'b0011_1100_00,
10'b0011_1100_00
};
// Set lookup_entry with the explicit bits from lookup with a part select
if(BANDWIDTH == "LOW") begin
// Low Bandwidth
mmcm_pll_filter_lookup = lookup_low[ ((64-divide)*10) +: 10];
end else begin
// High or optimized bandwidth
mmcm_pll_filter_lookup = lookup_high[ ((64-divide)*10) +: 10];
end
`ifdef DEBUG
$display("filter_lookup: %b", mmcm_pll_filter_lookup);
`endif
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
function [37:0] mmcm_pll_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle // Multiplied by 100,000
);
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
// w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
div_calc = mmcm_pll_divider(divide, duty_cycle);
// mx[10:9], pm[8:6], dt[5:0]
phase_calc = mmcm_pll_phase(divide, phase);
// Return value is the upper and lower address of counter
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
`ifdef DEBUG
$display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
div_calc[13], div_calc[12],
phase_calc[16:15], phase_calc[5:0], phase_calc[14:12]);
`endif
mmcm_pll_count_calc =
{
// Upper Address
6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
// Lower Address
phase_calc[8:6], 1'b0, div_calc[11:0]
};
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
// for fractional multiply/divide functions.
//
//
function [37:0] mmcm_frac_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle, // Multiplied by 1,000
input [9:0] frac // Multiplied by 1000
);
//Required for fractional divide calculations
reg [7:0] lt_frac;
reg [7:0] ht_frac;
reg /*[7:0]*/ wf_fall_frac;
reg /*[7:0]*/ wf_rise_frac;
reg [31:0] a;
reg [7:0] pm_rise_frac_filtered ;
reg [7:0] pm_fall_frac_filtered ;
reg [7:0] clkout0_divide_int;
reg [2:0] clkout0_divide_frac;
reg [7:0] even_part_high;
reg [7:0] even_part_low;
reg [7:0] odd;
reg [7:0] odd_and_frac;
reg [7:0] pm_fall;
reg [7:0] pm_rise;
reg [7:0] dt;
reg [7:0] dt_int;
reg [63:0] dt_calc;
reg [7:0] pm_rise_frac;
reg [7:0] pm_fall_frac;
reg [31:0] a_per_in_octets;
reg [31:0] a_phase_in_cycles;
parameter precision = 0.125;
reg [31:0] phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11
reg [31: 0] phase_pos;
reg [31: 0] phase_vco;
reg [31:0] temp;// changed to 31:0 from 32:1 jt 5/2/11
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
//convert phase to fixed
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// Return value is
// Transfer data
// RESERVED [37:36]
// FRAC_TIME [35:33]
// FRAC_WF_FALL [32]
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
clkout0_divide_frac = frac / 125;
clkout0_divide_int = divide;
even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2);
even_part_low = even_part_high;
odd = clkout0_divide_int - even_part_high - even_part_low;
odd_and_frac = (8*odd) + clkout0_divide_frac;
lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1)
ht_frac = even_part_low - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1)
pm_fall = {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2
pm_rise = 0; //0
wf_fall_frac = ((odd_and_frac >=2) && (odd_and_frac <=9)) || ((clkout0_divide_frac == 1) && (clkout0_divide_int == 2));//CRS610807
wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8);//IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0)
//Calculate phase in fractional cycles
a_per_in_octets = (8 * divide) + (frac / 125) ;
a_phase_in_cycles = (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors
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};
dt_calc = ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8)
dt = dt_calc[7:0];
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;
dt_int = dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt)
pm_fall_frac = pm_fall + pm_rise_frac;
pm_fall_frac_filtered = pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000};
div_calc = mmcm_pll_divider(divide, duty_cycle); //Use to determine edge[7], no count[6]
phase_calc = mmcm_pll_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]}
mmcm_frac_count_calc[37:0] =
{ 2'b00, pm_fall_frac_filtered[2:0], wf_fall_frac,
1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, phase_calc[10:9], div_calc[13:12], dt[5: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]
} ;
`ifdef DEBUG
$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);
`endif
end
endfunction
@@ -1,531 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
// Company: Xilinx
// Engineer: Jim Tatsukawa, Karl Kurbjun and Carl Ribbing
// Date: 7/30/2014
// Design Name: PLLE2 DRP
// Module Name: plle2_drp_func.h
// Version: 2.00
// Target Devices: 7 Series || PLL
// Tool versions: 2014.3
// Description: This header provides the functions necessary to
// calculate the DRP register values for the V6 PLL.
// Updated for CR663854.
//
// Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR
// INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
// PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY
// PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
// APPLICATION OR STANDARD, XILINX IS MAKING NO
// REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
// FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE
// RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY
// REQUIRE FOR YOUR IMPLEMENTATION. XILINX
// EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH
// RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION,
// INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
// REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE.
//
// (c) Copyright 2009-2010 Xilinx, Inc.
// All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
// These are user functions that should not be modified. Changes to the defines
// or code within the functions may alter the accuracy of the calculations.
// Define debug to provide extra messages durring elaboration
//`define DEBUG 1
// FRAC_PRECISION describes the width of the fractional portion of the fixed
// point numbers. These should not be modified, they are for development
// only
`define FRAC_PRECISION 10
// FIXED_WIDTH describes the total size for fixed point calculations(int+frac).
// Warning: L.50 and below will not calculate properly with FIXED_WIDTHs
// greater than 32
`define FIXED_WIDTH 32
// This function takes a fixed point number and rounds it to the nearest
// fractional precision bit.
function [`FIXED_WIDTH:1] round_frac
(
// Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number
input [`FIXED_WIDTH:1] decimal,
// This describes the precision of the fraction, for example a value
// of 1 would modify the fractional so that instead of being a .16
// fractional, it would be a .1 (rounded to the nearest 0.5 in turn)
input [`FIXED_WIDTH:1] precision
);
begin
`ifdef DEBUG
$display("round_frac - decimal: %h, precision: %h", decimal, precision);
`endif
// If the fractional precision bit is high then round up
if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin
round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision));
end else begin
round_frac = decimal;
end
`ifdef DEBUG
$display("round_frac: %h", round_frac);
`endif
end
endfunction
// This function calculates high_time, low_time, w_edge, and no_count
// of a non-fractional counter based on the divide and duty cycle
//
// NOTE: high_time and low_time are returned as integers between 0 and 63
// inclusive. 64 should equal 6'b000000 (in other words it is okay to
// ignore the overflow)
function [13:0] mmcm_pll_divider
(
input [7:0] divide, // Max divide is 128
input [31:0] duty_cycle // Duty cycle is multiplied by 100,000
);
reg [`FIXED_WIDTH:1] duty_cycle_fix;
// High/Low time is initially calculated with a wider integer to prevent a
// calculation error when it overflows to 64.
reg [6:0] high_time;
reg [6:0] low_time;
reg w_edge;
reg no_count;
reg [`FIXED_WIDTH:1] temp;
begin
// Duty Cycle must be between 0 and 1,000
if(duty_cycle <=0 || duty_cycle >= 100000) begin
`ifndef SYNTHESIS
$display("ERROR: duty_cycle: %d is invalid", duty_cycle);
`endif
$finish;
end
// Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point
duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000;
`ifdef DEBUG
$display("duty_cycle_fix: %h", duty_cycle_fix);
`endif
// If the divide is 1 nothing needs to be set except the no_count bit.
// Other values are dummies
if(divide == 7'h01) begin
high_time = 7'h01;
w_edge = 1'b0;
low_time = 7'h01;
no_count = 1'b1;
end else begin
temp = round_frac(duty_cycle_fix*divide, 1);
// comes from above round_frac
high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1];
// If the duty cycle * divide rounded is .5 or greater then this bit
// is set.
w_edge = temp[`FRAC_PRECISION]; // comes from round_frac
// If the high time comes out to 0, it needs to be set to at least 1
// and w_edge set to 0
if(high_time == 7'h00) begin
high_time = 7'h01;
w_edge = 1'b0;
end
if(high_time == divide) begin
high_time = divide - 1;
w_edge = 1'b1;
end
// Calculate low_time based on the divide setting and set no_count to
// 0 as it is only used when divide is 1.
low_time = divide - high_time;
no_count = 1'b0;
end
// Set the return value.
mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]};
end
endfunction
// This function calculates mx, delay_time, and phase_mux
// of a non-fractional counter based on the divide and phase
//
// NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux
// is used.
function [10:0] mmcm_pll_phase
(
// divide must be an integer (use fractional if not)
// assumed that divide already checked to be valid
input [7:0] divide, // Max divide is 128
// Phase is given in degrees (-360,000 to 360,000)
input signed [31:0] phase
);
reg [`FIXED_WIDTH:1] phase_in_cycles;
reg [`FIXED_WIDTH:1] phase_fixed;
reg [1:0] mx;
reg [5:0] delay_time;
reg [2:0] phase_mux;
reg [`FIXED_WIDTH:1] temp;
begin
`ifdef DEBUG
$display("mmcm_pll_phase-divide:%d,phase:%d",
divide, phase);
`endif
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// If phase is less than 0, convert it to a positive phase shift
// Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
if(phase < 0) begin
phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
end else begin
phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
end
// Put phase in terms of decimal number of vco clock cycles
phase_in_cycles = ( phase_fixed * divide ) / 360;
`ifdef DEBUG
$display("phase_in_cycles: %h", phase_in_cycles);
`endif
temp = round_frac(phase_in_cycles, 3);
// set mx to 2'b00 that the phase mux from the VCO is enabled
mx = 2'b00;
phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2];
delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1];
`ifdef DEBUG
$display("temp: %h", temp);
`endif
// Setup the return value
mmcm_pll_phase={mx, phase_mux, delay_time};
end
endfunction
// This function takes the divide value and outputs the necessary lock values
function [39:0] mmcm_pll_lock_lookup
(
input [6:0] divide // Max divide is 64
);
reg [2559:0] lookup;
begin
lookup = {
// This table is composed of:
// LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
40'b00110_00110_1111101000_1111101001_0000000001,
40'b00110_00110_1111101000_1111101001_0000000001,
40'b01000_01000_1111101000_1111101001_0000000001,
40'b01011_01011_1111101000_1111101001_0000000001,
40'b01110_01110_1111101000_1111101001_0000000001,
40'b10001_10001_1111101000_1111101001_0000000001,
40'b10011_10011_1111101000_1111101001_0000000001,
40'b10110_10110_1111101000_1111101001_0000000001,
40'b11001_11001_1111101000_1111101001_0000000001,
40'b11100_11100_1111101000_1111101001_0000000001,
40'b11111_11111_1110000100_1111101001_0000000001,
40'b11111_11111_1100111001_1111101001_0000000001,
40'b11111_11111_1011101110_1111101001_0000000001,
40'b11111_11111_1010111100_1111101001_0000000001,
40'b11111_11111_1010001010_1111101001_0000000001,
40'b11111_11111_1001110001_1111101001_0000000001,
40'b11111_11111_1000111111_1111101001_0000000001,
40'b11111_11111_1000100110_1111101001_0000000001,
40'b11111_11111_1000001101_1111101001_0000000001,
40'b11111_11111_0111110100_1111101001_0000000001,
40'b11111_11111_0111011011_1111101001_0000000001,
40'b11111_11111_0111000010_1111101001_0000000001,
40'b11111_11111_0110101001_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0101110111_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001
};
// Set lookup_entry with the explicit bits from lookup with a part select
mmcm_pll_lock_lookup = lookup[ ((64-divide)*40) +: 40];
`ifdef DEBUG
$display("lock_lookup: %b", mmcm_pll_lock_lookup);
`endif
end
endfunction
// This function takes the divide value and the bandwidth setting of the PLL
// and outputs the digital filter settings necessary.
function [9:0] mmcm_pll_filter_lookup
(
input [6:0] divide, // Max divide is 64
input [8*9:0] BANDWIDTH
);
reg [639:0] lookup_low;
reg [639:0] lookup_high;
reg [9:0] lookup_entry;
begin
lookup_low = {
// CP_RES_LFHF
10'b0010_1111_00,
10'b0010_1111_00,
10'b0010_0111_00,
10'b0010_1101_00,
10'b0010_0101_00,
10'b0010_0101_00,
10'b0010_1001_00,
10'b0010_1110_00,
10'b0010_1110_00,
10'b0010_0001_00,
10'b0010_0001_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_0110_00,
10'b0010_1010_00,
10'b0010_1010_00,
10'b0010_1010_00,
10'b0010_1010_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_1100_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0010_0010_00,
10'b0011_1100_00,
10'b0011_1100_00,
10'b0011_1100_00,
10'b0011_1100_00,
10'b0011_1100_00,
10'b0011_1100_00,
10'b0011_1100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00
};
lookup_high = {
// CP_RES_LFHF
10'b0011_0111_00,
10'b0011_0111_00,
10'b0101_1111_00,
10'b0111_1111_00,
10'b0111_1011_00,
10'b1101_0111_00,
10'b1110_1011_00,
10'b1110_1101_00,
10'b1111_1101_00,
10'b1111_0111_00,
10'b1111_1011_00,
10'b1111_1101_00,
10'b1111_0011_00,
10'b1110_0101_00,
10'b1111_0101_00,
10'b1111_0101_00,
10'b1111_0101_00,
10'b1111_0101_00,
10'b0111_0110_00,
10'b0111_0110_00,
10'b0111_0110_00,
10'b0111_0110_00,
10'b0101_1100_00,
10'b0101_1100_00,
10'b0101_1100_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b1100_0001_00,
10'b0100_0010_00,
10'b0100_0010_00,
10'b0100_0010_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0011_0100_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0010_1000_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0100_1100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00,
10'b0010_0100_00
};
// Set lookup_entry with the explicit bits from lookup with a part select
if(BANDWIDTH == "LOW") begin
// Low Bandwidth
mmcm_pll_filter_lookup = lookup_low[ ((64-divide)*10) +: 10];
end else begin
// High or optimized bandwidth
mmcm_pll_filter_lookup = lookup_high[ ((64-divide)*10) +: 10];
end
`ifdef DEBUG
$display("filter_lookup: %b", mmcm_pll_filter_lookup);
`endif
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
function [37:0] mmcm_pll_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle // Multiplied by 100,000
);
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
// w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
div_calc = mmcm_pll_divider(divide, duty_cycle);
// mx[10:9], pm[8:6], dt[5:0]
phase_calc = mmcm_pll_phase(divide, phase);
// Return value is the upper and lower address of counter
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
`ifdef DEBUG
$display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
div_calc[13], div_calc[12],
phase_calc[16:15], phase_calc[5:0], phase_calc[14:12]);
`endif
mmcm_pll_count_calc =
{
// Upper Address
6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
// Lower Address
phase_calc[8:6], 1'b0, div_calc[11:0]
};
end
endfunction
@@ -1,671 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
// Company: Xilinx
// Engineer: Jim Tatsukawa
// Date: 7/30/2014
// Design Name: MMCME2 DRP
// Module Name: mmcme2_drp_func.h
// Version: 1.04
// Target Devices: UltraScale Architecture || MMCM
// Tool versions: 2014.3
// Description: This header provides the functions necessary to
// calculate the DRP register values for the V6 MMCM.
//
// Revision Notes: 3/22 - Updating lookup_low/lookup_high (CR)
// 4/13 - Fractional divide function in mmcm_frac_count_calc function. CRS610807
//
// Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR
// INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
// PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY
// PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
// APPLICATION OR STANDARD, XILINX IS MAKING NO
// REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
// FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE
// RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY
// REQUIRE FOR YOUR IMPLEMENTATION. XILINX
// EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH
// RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION,
// INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
// REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE.
//
// (c) Copyright 2009-2010 Xilinx, Inc.
// All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
// These are user functions that should not be modified. Changes to the defines
// or code within the functions may alter the accuracy of the calculations.
// Define debug to provide extra messages durring elaboration
//`define DEBUG 1
// FRAC_PRECISION describes the width of the fractional portion of the fixed
// point numbers. These should not be modified, they are for development
// only
`define FRAC_PRECISION 10
// FIXED_WIDTH describes the total size for fixed point calculations(int+frac).
// Warning: L.50 and below will not calculate properly with FIXED_WIDTHs
// greater than 32
`define FIXED_WIDTH 32
// This function takes a fixed point number and rounds it to the nearest
// fractional precision bit.
function [`FIXED_WIDTH:1] round_frac
(
// Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number
input [`FIXED_WIDTH:1] decimal,
// This describes the precision of the fraction, for example a value
// of 1 would modify the fractional so that instead of being a .16
// fractional, it would be a .1 (rounded to the nearest 0.5 in turn)
input [`FIXED_WIDTH:1] precision
);
begin
`ifdef DEBUG
$display("round_frac - decimal: %h, precision: %h", decimal, precision);
`endif
// If the fractional precision bit is high then round up
if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin
round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision));
end else begin
round_frac = decimal;
end
`ifdef DEBUG
$display("round_frac: %h", round_frac);
`endif
end
endfunction
// This function calculates high_time, low_time, w_edge, and no_count
// of a non-fractional counter based on the divide and duty cycle
//
// NOTE: high_time and low_time are returned as integers between 0 and 63
// inclusive. 64 should equal 6'b000000 (in other words it is okay to
// ignore the overflow)
function [13:0] mmcm_pll_divider
(
input [7:0] divide, // Max divide is 128
input [31:0] duty_cycle // Duty cycle is multiplied by 100,000
);
reg [`FIXED_WIDTH:1] duty_cycle_fix;
// High/Low time is initially calculated with a wider integer to prevent a
// calculation error when it overflows to 64.
reg [6:0] high_time;
reg [6:0] low_time;
reg w_edge;
reg no_count;
reg [`FIXED_WIDTH:1] temp;
begin
// Duty Cycle must be between 0 and 1,000
if(duty_cycle <=0 || duty_cycle >= 100000) begin
`ifndef SYNTHESIS
$display("ERROR: duty_cycle: %d is invalid", duty_cycle);
`endif
$finish;
end
// Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point
duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000;
`ifdef DEBUG
$display("duty_cycle_fix: %h", duty_cycle_fix);
`endif
// If the divide is 1 nothing needs to be set except the no_count bit.
// Other values are dummies
if(divide == 7'h01) begin
high_time = 7'h01;
w_edge = 1'b0;
low_time = 7'h01;
no_count = 1'b1;
end else begin
temp = round_frac(duty_cycle_fix*divide, 1);
// comes from above round_frac
high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1];
// If the duty cycle * divide rounded is .5 or greater then this bit
// is set.
w_edge = temp[`FRAC_PRECISION]; // comes from round_frac
// If the high time comes out to 0, it needs to be set to at least 1
// and w_edge set to 0
if(high_time == 7'h00) begin
high_time = 7'h01;
w_edge = 1'b0;
end
if(high_time == divide) begin
high_time = divide - 1;
w_edge = 1'b1;
end
// Calculate low_time based on the divide setting and set no_count to
// 0 as it is only used when divide is 1.
low_time = divide - high_time;
no_count = 1'b0;
end
// Set the return value.
mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]};
end
endfunction
// This function calculates mx, delay_time, and phase_mux
// of a non-fractional counter based on the divide and phase
//
// NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux
// is used.
function [10:0] mmcm_pll_phase
(
// divide must be an integer (use fractional if not)
// assumed that divide already checked to be valid
input [7:0] divide, // Max divide is 128
// Phase is given in degrees (-360,000 to 360,000)
input signed [31:0] phase
);
reg [`FIXED_WIDTH:1] phase_in_cycles;
reg [`FIXED_WIDTH:1] phase_fixed;
reg [1:0] mx;
reg [5:0] delay_time;
reg [2:0] phase_mux;
reg [`FIXED_WIDTH:1] temp;
begin
`ifdef DEBUG
$display("mmcm_pll_phase-divide:%d,phase:%d",
divide, phase);
`endif
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// If phase is less than 0, convert it to a positive phase shift
// Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
if(phase < 0) begin
phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
end else begin
phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
end
// Put phase in terms of decimal number of vco clock cycles
phase_in_cycles = ( phase_fixed * divide ) / 360;
`ifdef DEBUG
$display("phase_in_cycles: %h", phase_in_cycles);
`endif
temp = round_frac(phase_in_cycles, 3);
// set mx to 2'b00 that the phase mux from the VCO is enabled
mx = 2'b00;
phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2];
delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1];
`ifdef DEBUG
$display("temp: %h", temp);
`endif
// Setup the return value
mmcm_pll_phase={mx, phase_mux, delay_time};
end
endfunction
// This function takes the divide value and outputs the necessary lock values
function [39:0] mmcm_pll_lock_lookup
(
input [6:0] divide // Max divide is 64
);
reg [2559:0] lookup;
begin
lookup = {
// This table is composed of:
// LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
40'b00110_00110_1111101000_1111101001_0000000001,
40'b00110_00110_1111101000_1111101001_0000000001,
40'b01000_01000_1111101000_1111101001_0000000001,
40'b01011_01011_1111101000_1111101001_0000000001,
40'b01110_01110_1111101000_1111101001_0000000001,
40'b10001_10001_1111101000_1111101001_0000000001,
40'b10011_10011_1111101000_1111101001_0000000001,
40'b10110_10110_1111101000_1111101001_0000000001,
40'b11001_11001_1111101000_1111101001_0000000001,
40'b11100_11100_1111101000_1111101001_0000000001,
40'b11111_11111_1110000100_1111101001_0000000001,
40'b11111_11111_1100111001_1111101001_0000000001,
40'b11111_11111_1011101110_1111101001_0000000001,
40'b11111_11111_1010111100_1111101001_0000000001,
40'b11111_11111_1010001010_1111101001_0000000001,
40'b11111_11111_1001110001_1111101001_0000000001,
40'b11111_11111_1000111111_1111101001_0000000001,
40'b11111_11111_1000100110_1111101001_0000000001,
40'b11111_11111_1000001101_1111101001_0000000001,
40'b11111_11111_0111110100_1111101001_0000000001,
40'b11111_11111_0111011011_1111101001_0000000001,
40'b11111_11111_0111000010_1111101001_0000000001,
40'b11111_11111_0110101001_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0101110111_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001
};
// Set lookup_entry with the explicit bits from lookup with a part select
mmcm_pll_lock_lookup = lookup[ ((64-divide)*40) +: 40];
`ifdef DEBUG
$display("lock_lookup: %b", mmcm_pll_lock_lookup);
`endif
end
endfunction
// This function takes the divide value and the bandwidth setting of the MMCM
// and outputs the digital filter settings necessary.
function [9:0] mmcm_pll_filter_lookup
(
input [6:0] divide, // Max divide is 64
input [8*9:0] BANDWIDTH
);
reg [639:0] lookup_low;
reg [639:0] lookup_high;
reg [9:0] lookup_entry;
begin
lookup_low = {
// CP_RES_LFHF
10'b0010_1111_11,
10'b0010_1111_11,
10'b0010_1111_11,
10'b0010_1111_11,
10'b0010_1111_11,
10'b0010_1111_11,
10'b0010_0111_11,
10'b0010_0111_11,
10'b0010_0111_11,
10'b0010_1101_11,
10'b0010_1101_11,
10'b0010_1101_11,
10'b0010_0011_11,
10'b0010_0101_11,
10'b0010_0101_11,
10'b0010_0101_11,
10'b0010_1001_11,
10'b0010_1001_11,
10'b0010_1110_11,
10'b0010_1110_11,
10'b0010_1110_11,
10'b0010_1110_11,
10'b0010_1110_11,
10'b0010_1110_11,
10'b0010_0001_11,
10'b0010_0001_11,
10'b0010_0001_11,
10'b0010_0001_11,
10'b0010_0001_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_0110_11,
10'b0010_1010_11,
10'b0010_1010_11,
10'b0010_1010_11,
10'b0010_1010_11,
10'b0010_1010_11,
10'b0010_1010_11,
10'b0010_1010_11,
10'b0010_1010_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11,
10'b0010_1100_11
};
lookup_high = {
// CP_RES_LFHF
10'b0010_1111_11,
10'b0010_1111_11,
10'b0010_1011_11,
10'b0011_1111_11,
10'b0100_1111_11,
10'b0100_1111_11,
10'b0101_1111_11,
10'b0110_1111_11,
10'b0111_1111_11,
10'b0111_1111_11,
10'b1100_1111_11,
10'b1101_1111_11,
10'b1110_1111_11,
10'b1111_1111_11,
10'b1111_1111_11,
10'b1110_0111_11,
10'b1110_1011_11,
10'b1111_0111_11,
10'b1111_1011_11,
10'b1111_1011_11,
10'b1110_1101_11,
10'b1111_1101_11,
10'b1111_1101_11,
10'b1111_0011_11,
10'b1111_0011_11,
10'b1111_0011_11,
10'b1110_0101_11,
10'b1110_0101_11,
10'b1110_0101_11,
10'b1111_0101_11,
10'b1111_0101_11,
10'b1111_0101_11,
10'b1111_1001_11,
10'b1111_1001_11,
10'b1111_1001_11,
10'b1111_1001_11,
10'b1111_1001_11,
10'b1110_1110_11,
10'b1110_1110_11,
10'b1110_1110_11,
10'b1110_1110_11,
10'b1111_1110_11,
10'b1111_1110_11,
10'b1111_1110_11,
10'b1111_1110_11,
10'b1111_1110_11,
10'b1111_1110_11,
10'b1111_1110_11,
10'b1110_0001_11,
10'b1110_0001_11,
10'b1110_0001_11,
10'b1110_0001_11,
10'b1110_0001_11,
10'b1100_0110_11,
10'b1100_0110_11,
10'b1100_0110_11,
10'b1100_0110_11,
10'b1100_0110_11,
10'b1100_0110_11,
10'b1100_0110_11,
10'b1100_1010_11,
10'b1100_1010_11,
10'b1100_1010_11,
10'b1100_1010_11
};
// Set lookup_entry with the explicit bits from lookup with a part select
if(BANDWIDTH == "LOW") begin
// Low Bandwidth
mmcm_pll_filter_lookup = lookup_low[ ((64-divide)*10) +: 10];
end else begin
// High or optimized bandwidth
mmcm_pll_filter_lookup = lookup_high[ ((64-divide)*10) +: 10];
end
`ifdef DEBUG
$display("filter_lookup: %b", mmcm_pll_filter_lookup);
`endif
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
function [37:0] mmcm_pll_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle // Multiplied by 100,000
);
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
// w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
div_calc = mmcm_pll_divider(divide, duty_cycle);
// mx[10:9], pm[8:6], dt[5:0]
phase_calc = mmcm_pll_phase(divide, phase);
// Return value is the upper and lower address of counter
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
`ifdef DEBUG
$display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
div_calc[13], div_calc[12],
phase_calc[16:15], phase_calc[5:0], phase_calc[14:12]);
`endif
mmcm_pll_count_calc =
{
// Upper Address
6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
// Lower Address
phase_calc[8:6], 1'b0, div_calc[11:0]
};
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
// for fractional multiply/divide functions.
//
//
function [37:0] mmcm_frac_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle, // Multiplied by 1,000
input [9:0] frac // Multiplied by 1000
);
//Required for fractional divide calculations
reg [7:0] lt_frac;
reg [7:0] ht_frac;
reg /*[7:0]*/ wf_fall_frac;
reg /*[7:0]*/ wf_rise_frac;
reg [31:0] a;
reg [7:0] pm_rise_frac_filtered ;
reg [7:0] pm_fall_frac_filtered ;
reg [7:0] clkout0_divide_int;
reg [2:0] clkout0_divide_frac;
reg [7:0] even_part_high;
reg [7:0] even_part_low;
reg [7:0] odd;
reg [7:0] odd_and_frac;
reg [7:0] pm_fall;
reg [7:0] pm_rise;
reg [7:0] dt;
reg [7:0] dt_int;
reg [63:0] dt_calc;
reg [7:0] pm_rise_frac;
reg [7:0] pm_fall_frac;
reg [31:0] a_per_in_octets;
reg [31:0] a_phase_in_cycles;
parameter precision = 0.125;
reg [31:0] phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11
reg [31: 0] phase_pos;
reg [31: 0] phase_vco;
reg [31:0] temp;// changed to 31:0 from 32:1 jt 5/2/11
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
//convert phase to fixed
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// Return value is
// Transfer data
// RESERVED [37:36]
// FRAC_TIME [35:33]
// FRAC_WF_FALL [32]
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
clkout0_divide_frac = frac / 125;
clkout0_divide_int = divide;
even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2);
even_part_low = even_part_high;
odd = clkout0_divide_int - even_part_high - even_part_low;
odd_and_frac = (8*odd) + clkout0_divide_frac;
lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1)
ht_frac = even_part_low - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1)
pm_fall = {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2
pm_rise = 0; //0
wf_fall_frac = ((odd_and_frac >=2) && (odd_and_frac <=9)) || ((clkout0_divide_frac == 1) && (clkout0_divide_int == 2));//CRS610807
wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8);//IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0)
//Calculate phase in fractional cycles
a_per_in_octets = (8 * divide) + (frac / 125) ;
a_phase_in_cycles = (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors
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};
dt_calc = ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8)
dt = dt_calc[7:0];
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;
dt_int = dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt)
pm_fall_frac = pm_fall + pm_rise_frac;
pm_fall_frac_filtered = pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000};
div_calc = mmcm_pll_divider(divide, duty_cycle); //Use to determine edge[7], no count[6]
phase_calc = mmcm_pll_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]}
mmcm_frac_count_calc[37:0] =
{ 2'b00, pm_fall_frac_filtered[2:0], wf_fall_frac,
1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, phase_calc[10:9], div_calc[13:12], dt[5: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]
} ;
`ifdef DEBUG
$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);
`endif
end
endfunction
@@ -1,530 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
// Company: Xilinx
// Engineer: Jim Tatsukawa
// Date: 6/15/2015
// Design Name: PLLE3 DRP
// Module Name: plle3_drp_func.h
// Version: 1.10
// Target Devices: UltraScale Architecture
// Tool versions: 2015.1
// Description: This header provides the functions necessary to
// calculate the DRP register values for the V6 PLL.
//
// Revision Notes: 8/11 - PLLE3 updated for PLLE3 file 4564419
// Revision Notes: 6/15 - pll_filter_lookup fixed for max M of 19
// PM_Rise bits have been removed for PLLE3
//
// Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR
// INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
// PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY
// PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
// APPLICATION OR STANDARD, XILINX IS MAKING NO
// REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
// FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE
// RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY
// REQUIRE FOR YOUR IMPLEMENTATION. XILINX
// EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH
// RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION,
// INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
// REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE.
//
// (c) Copyright 2009-2010 Xilinx, Inc.
// All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
// These are user functions that should not be modified. Changes to the defines
// or code within the functions may alter the accuracy of the calculations.
// Define debug to provide extra messages durring elaboration
//`define DEBUG 1
// FRAC_PRECISION describes the width of the fractional portion of the fixed
// point numbers. These should not be modified, they are for development
// only
`define FRAC_PRECISION 10
// FIXED_WIDTH describes the total size for fixed point calculations(int+frac).
// Warning: L.50 and below will not calculate properly with FIXED_WIDTHs
// greater than 32
`define FIXED_WIDTH 32
// This function takes a fixed point number and rounds it to the nearest
// fractional precision bit.
function [`FIXED_WIDTH:1] round_frac
(
// Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number
input [`FIXED_WIDTH:1] decimal,
// This describes the precision of the fraction, for example a value
// of 1 would modify the fractional so that instead of being a .16
// fractional, it would be a .1 (rounded to the nearest 0.5 in turn)
input [`FIXED_WIDTH:1] precision
);
begin
`ifdef DEBUG
$display("round_frac - decimal: %h, precision: %h", decimal, precision);
`endif
// If the fractional precision bit is high then round up
if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin
round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision));
end else begin
round_frac = decimal;
end
`ifdef DEBUG
$display("round_frac: %h", round_frac);
`endif
end
endfunction
// This function calculates high_time, low_time, w_edge, and no_count
// of a non-fractional counter based on the divide and duty cycle
//
// NOTE: high_time and low_time are returned as integers between 0 and 63
// inclusive. 64 should equal 6'b000000 (in other words it is okay to
// ignore the overflow)
function [13:0] mmcm_pll_divider
(
input [7:0] divide, // Max divide is 128
input [31:0] duty_cycle // Duty cycle is multiplied by 100,000
);
reg [`FIXED_WIDTH:1] duty_cycle_fix;
// High/Low time is initially calculated with a wider integer to prevent a
// calculation error when it overflows to 64.
reg [6:0] high_time;
reg [6:0] low_time;
reg w_edge;
reg no_count;
reg [`FIXED_WIDTH:1] temp;
begin
// Duty Cycle must be between 0 and 1,000
if(duty_cycle <=0 || duty_cycle >= 100000) begin
`ifndef SYNTHESIS
$display("ERROR: duty_cycle: %d is invalid", duty_cycle);
`endif
$finish;
end
// Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point
duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000;
`ifdef DEBUG
$display("duty_cycle_fix: %h", duty_cycle_fix);
`endif
// If the divide is 1 nothing needs to be set except the no_count bit.
// Other values are dummies
if(divide == 7'h01) begin
high_time = 7'h01;
w_edge = 1'b0;
low_time = 7'h01;
no_count = 1'b1;
end else begin
temp = round_frac(duty_cycle_fix*divide, 1);
// comes from above round_frac
high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1];
// If the duty cycle * divide rounded is .5 or greater then this bit
// is set.
w_edge = temp[`FRAC_PRECISION]; // comes from round_frac
// If the high time comes out to 0, it needs to be set to at least 1
// and w_edge set to 0
if(high_time == 7'h00) begin
high_time = 7'h01;
w_edge = 1'b0;
end
if(high_time == divide) begin
high_time = divide - 1;
w_edge = 1'b1;
end
// Calculate low_time based on the divide setting and set no_count to
// 0 as it is only used when divide is 1.
low_time = divide - high_time;
no_count = 1'b0;
end
// Set the return value.
mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]};
end
endfunction
// This function calculates mx, delay_time, and phase_mux
// of a non-fractional counter based on the divide and phase
//
// NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux
// is used.
function [10:0] mmcm_pll_phase
(
// divide must be an integer (use fractional if not)
// assumed that divide already checked to be valid
input [7:0] divide, // Max divide is 128
// Phase is given in degrees (-360,000 to 360,000)
input signed [31:0] phase
);
reg [`FIXED_WIDTH:1] phase_in_cycles;
reg [`FIXED_WIDTH:1] phase_fixed;
reg [1:0] mx;
reg [5:0] delay_time;
reg [2:0] phase_mux;
reg [`FIXED_WIDTH:1] temp;
begin
`ifdef DEBUG
$display("mmcm_pll_phase-divide:%d,phase:%d",
divide, phase);
`endif
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// If phase is less than 0, convert it to a positive phase shift
// Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
if(phase < 0) begin
phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
end else begin
phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
end
// Put phase in terms of decimal number of vco clock cycles
phase_in_cycles = ( phase_fixed * divide ) / 360;
`ifdef DEBUG
$display("phase_in_cycles: %h", phase_in_cycles);
`endif
temp = round_frac(phase_in_cycles, 3);
// set mx to 2'b00 that the phase mux from the VCO is enabled
mx = 2'b00;
phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2];
delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1];
`ifdef DEBUG
$display("temp: %h", temp);
`endif
// Setup the return value
mmcm_pll_phase={mx, phase_mux, delay_time};
end
endfunction
// This function takes the divide value and outputs the necessary lock values
function [39:0] mmcm_pll_lock_lookup
(
input [6:0] divide // Max divide is 64
);
reg [759:0] lookup;
begin
lookup = {
// This table is composed of:
// LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
40'b00110_00110_1111101000_1111101001_0000000001, //1
40'b00110_00110_1111101000_1111101001_0000000001, //2
40'b01000_01000_1111101000_1111101001_0000000001, //3
40'b01011_01011_1111101000_1111101001_0000000001, //4
40'b01110_01110_1111101000_1111101001_0000000001, //5
40'b10001_10001_1111101000_1111101001_0000000001, //6
40'b10011_10011_1111101000_1111101001_0000000001, //7
40'b10110_10110_1111101000_1111101001_0000000001, //8
40'b11001_11001_1111101000_1111101001_0000000001, //9
40'b11100_11100_1111101000_1111101001_0000000001, //10
40'b11111_11111_1110000100_1111101001_0000000001, //11
40'b11111_11111_1100111001_1111101001_0000000001, //12
40'b11111_11111_1011101110_1111101001_0000000001, //13
40'b11111_11111_1010111100_1111101001_0000000001, //14
40'b11111_11111_1010001010_1111101001_0000000001, //15
40'b11111_11111_1001110001_1111101001_0000000001, //16
40'b11111_11111_1000111111_1111101001_0000000001, //17
40'b11111_11111_1000100110_1111101001_0000000001, //18
40'b11111_11111_1000001101_1111101001_0000000001 //19
};
// Set lookup_entry with the explicit bits from lookup with a part select
mmcm_pll_lock_lookup = lookup[ ((19-divide)*40) +: 40];
`ifdef DEBUG
$display("lock_lookup: %b", mmcm_pll_lock_lookup);
`endif
end
endfunction
// This function takes the divide value and the bandwidth setting of the PLL
// and outputs the digital filter settings necessary. Removing bandwidth setting for PLLE3.
function [9:0] mmcm_pll_filter_lookup
(
input [6:0] divide // Max divide is 19
);
reg [639:0] lookup;
reg [9:0] lookup_entry;
begin
lookup = {
// CP_RES_LFHF
10'b0010_1111_01, //1
10'b0010_0011_11, //2
10'b0011_0011_11, //3
10'b0010_0001_11, //4
10'b0010_0110_11, //5
10'b0010_1010_11, //6
10'b0010_1010_11, //7
10'b0011_0110_11, //8
10'b0010_1100_11, //9
10'b0010_1100_11, //10
10'b0010_1100_11, //11
10'b0010_0010_11, //12
10'b0011_1100_11, //13
10'b0011_1100_11, //14
10'b0011_1100_11, //15
10'b0011_1100_11, //16
10'b0011_0010_11, //17
10'b0011_0010_11, //18
10'b0011_0010_11 //19
};
mmcm_pll_filter_lookup = lookup [ ((19-divide)*10) +: 10];
`ifdef DEBUG
$display("filter_lookup: %b", mmcm_pll_filter_lookup);
`endif
end
endfunction
// This function set the CLKOUTPHY divide settings to match
// the desired CLKOUTPHY_MODE setting. To create VCO_X2, then
// the CLKOUTPHY will be set to 2'b00 since the VCO is internally
// doubled and 2'b00 will represent divide by 1. Similarly "VCO" // will need to divide the doubled clock VCO clock frequency by // 2 therefore 2'b01 will match a divide by 2.And VCO_HALF will // need to divide the doubled VCO by 4, therefore 2'b10
function [9:0] mmcm_pll_clkoutphy_calc
(
input [8*9:0] CLKOUTPHY_MODE
);
if(CLKOUTPHY_MODE == "VCO_X2") begin
mmcm_pll_clkoutphy_calc= 2'b00;
end else if(CLKOUTPHY_MODE == "VCO") begin
mmcm_pll_clkoutphy_calc= 2'b01;
end else if(CLKOUTPHY_MODE == "CLKIN") begin
mmcm_pll_clkoutphy_calc= 2'b11;
end else begin // Assume "VCO_HALF"
mmcm_pll_clkoutphy_calc= 2'b10;
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
function [37:0] mmcm_pll_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle // Multiplied by 100,000
);
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
// w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
div_calc = mmcm_pll_divider(divide, duty_cycle);
// mx[10:9], pm[8:6], dt[5:0]
phase_calc = mmcm_pll_phase(divide, phase);
// Return value is the upper and lower address of counter
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
`ifdef DEBUG
$display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
div_calc[13], div_calc[12],
phase_calc[16:15], phase_calc[5:0], 3'b000);//Removed PM_Rise bits
`endif
mmcm_pll_count_calc =
{
// Upper Address
6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
// Lower Address
phase_calc[8:6], 1'b0, div_calc[11:0]
};
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
// for fractional multiply/divide functions.
//
//
function [37:0] mmcm_pll_frac_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle, // Multiplied by 1,000
input [9:0] frac // Multiplied by 1000
);
//Required for fractional divide calculations
reg [7:0] lt_frac;
reg [7:0] ht_frac;
reg /*[7:0]*/ wf_fall_frac;
reg /*[7:0]*/ wf_rise_frac;
reg [31:0] a;
reg [7:0] pm_rise_frac_filtered ;
reg [7:0] pm_fall_frac_filtered ;
reg [7:0] clkout0_divide_int;
reg [2:0] clkout0_divide_frac;
reg [7:0] even_part_high;
reg [7:0] even_part_low;
reg [7:0] odd;
reg [7:0] odd_and_frac;
reg [7:0] pm_fall;
reg [7:0] pm_rise;
reg [7:0] dt;
reg [7:0] dt_int;
reg [63:0] dt_calc;
reg [7:0] pm_rise_frac;
reg [7:0] pm_fall_frac;
reg [31:0] a_per_in_octets;
reg [31:0] a_phase_in_cycles;
parameter precision = 0.125;
reg [31:0] phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11
reg [31: 0] phase_pos;
reg [31: 0] phase_vco;
reg [31:0] temp;// changed to 31:0 from 32:1 jt 5/2/11
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_pll_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
//convert phase to fixed
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// Return value is
// Transfer data
// RESERVED [37:36]
// FRAC_TIME [35:33]
// FRAC_WF_FALL [32]
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
clkout0_divide_frac = frac / 125;
clkout0_divide_int = divide;
even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2);
even_part_low = even_part_high;
odd = clkout0_divide_int - even_part_high - even_part_low;
odd_and_frac = (8*odd) + clkout0_divide_frac;
lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1)
ht_frac = even_part_low - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1)
pm_fall = {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2
pm_rise = 0; //0
wf_fall_frac = (odd_and_frac >=2) && (odd_and_frac <=9);//IF(odd_and_frac>=2,IF(odd_and_frac <= 9,1,0),0)
wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8);//IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0)
//Calculate phase in fractional cycles
a_per_in_octets = (8 * divide) + (frac / 125) ;
a_phase_in_cycles = (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors
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};
dt_calc = ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8)
dt = dt_calc[7:0];
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;
dt_int = dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt)
pm_fall_frac = pm_fall + pm_rise_frac;
pm_fall_frac_filtered = pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000};
div_calc = mmcm_pll_divider(divide, duty_cycle); //Use to determine edge[7], no count[6]
phase_calc = mmcm_pll_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]}
mmcm_pll_frac_count_calc[37:0] =
{ 2'b00, pm_fall_frac_filtered[2:0], wf_fall_frac,
1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, phase_calc[10:9], div_calc[13:12], dt[5:0],
3'b000, 1'b0, ht_frac[5:0], lt_frac[5:0] //Removed PM_Rise bits
// 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]
} ;
`ifdef DEBUG
$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, 3'b000, ht_frac, lt_frac);
`endif
end
endfunction
@@ -1,861 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
// Company: Xilinx
// Engineer: Jim Tatsukawa. Updated by Ralf Krueger
// Date: 7/30/2014
// Design Name: MMCME4 DRP
// Module Name: mmcme4_drp_func.h
// Version: 1.31
// Target Devices: UltraScale Plus Architecture
// Tool versions: 2017.1
// Description: This header provides the functions necessary to
// calculate the DRP register values for UltraScal+ MMCM.
//
// Revision Notes: 3/22 - Updating lookup_low/lookup_high (CR)
// 4/13 - Fractional divide function in mmcm_frac_count_calc function
// 2/28/17 - Updated for Ultrascale Plus
//
// Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR
// INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
// PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY
// PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
// APPLICATION OR STANDARD, XILINX IS MAKING NO
// REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
// FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE
// RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY
// REQUIRE FOR YOUR IMPLEMENTATION. XILINX
// EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH
// RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION,
// INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
// REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE.
//
// (c) Copyright 2009-2017 Xilinx, Inc.
// All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
// These are user functions that should not be modified. Changes to the defines
// or code within the functions may alter the accuracy of the calculations.
// Define debug to provide extra messages during elaboration
//`define DEBUG 1
// FRAC_PRECISION describes the width of the fractional portion of the fixed
// point numbers. These should not be modified, they are for development only
`define FRAC_PRECISION 10
// FIXED_WIDTH describes the total size for fixed point calculations(int+frac).
// Warning: L.50 and below will not calculate properly with FIXED_WIDTHs
// greater than 32
`define FIXED_WIDTH 32
// This function takes a fixed point number and rounds it to the nearest
// fractional precision bit.
function [`FIXED_WIDTH:1] round_frac
(
// Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number
input [`FIXED_WIDTH:1] decimal,
// This describes the precision of the fraction, for example a value
// of 1 would modify the fractional so that instead of being a .16
// fractional, it would be a .1 (rounded to the nearest 0.5 in turn)
input [`FIXED_WIDTH:1] precision
);
begin
`ifdef DEBUG
$display("round_frac - decimal: %h, precision: %h", decimal, precision);
`endif
// If the fractional precision bit is high then round up
if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin
round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision));
end else begin
round_frac = decimal;
end
`ifdef DEBUG
$display("round_frac: %h", round_frac);
`endif
end
endfunction
// This function calculates high_time, low_time, w_edge, and no_count
// of a non-fractional counter based on the divide and duty cycle
//
// NOTE: high_time and low_time are returned as integers between 0 and 63
// inclusive. 64 should equal 6'b000000 (in other words it is okay to
// ignore the overflow)
function [13:0] mmcm_pll_divider
(
input [7:0] divide, // Max divide is 128
input [31:0] duty_cycle // Duty cycle is multiplied by 100,000
);
reg [`FIXED_WIDTH:1] duty_cycle_fix;
// High/Low time is initially calculated with a wider integer to prevent a
// calculation error when it overflows to 64.
reg [6:0] high_time;
reg [6:0] low_time;
reg w_edge;
reg no_count;
reg [`FIXED_WIDTH:1] temp;
begin
// Duty Cycle must be between 0 and 1,000
if(duty_cycle <=0 || duty_cycle >= 100000) begin
`ifndef SYNTHESIS
$display("ERROR: duty_cycle: %d is invalid", duty_cycle);
`endif
$finish;
end
// Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point
duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000;
`ifdef DEBUG
$display("duty_cycle_fix: %h", duty_cycle_fix);
`endif
// If the divide is 1 nothing needs to be set except the no_count bit.
// Other values are dummies
if(divide == 7'h01) begin
high_time = 7'h01;
w_edge = 1'b0;
low_time = 7'h01;
no_count = 1'b1;
end else begin
temp = round_frac(duty_cycle_fix*divide, 1);
// comes from above round_frac
high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1];
// If the duty cycle * divide rounded is .5 or greater then this bit
// is set.
w_edge = temp[`FRAC_PRECISION]; // comes from round_frac
// If the high time comes out to 0, it needs to be set to at least 1
// and w_edge set to 0
if(high_time == 7'h00) begin
high_time = 7'h01;
w_edge = 1'b0;
end
if(high_time == divide) begin
high_time = divide - 1;
w_edge = 1'b1;
end
// Calculate low_time based on the divide setting and set no_count to
// 0 as it is only used when divide is 1.
low_time = divide - high_time;
no_count = 1'b0;
end
// Set the return value.
mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]};
end
endfunction
// This function calculates mx, delay_time, and phase_mux
// of a non-fractional counter based on the divide and phase
//
// NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux
// is used.
function [10:0] mmcm_pll_phase
(
// divide must be an integer (use fractional if not)
// assumed that divide already checked to be valid
input [7:0] divide, // Max divide is 128
// Phase is given in degrees (-360,000 to 360,000)
input signed [31:0] phase
);
reg [`FIXED_WIDTH:1] phase_in_cycles;
reg [`FIXED_WIDTH:1] phase_fixed;
reg [1:0] mx;
reg [5:0] delay_time;
reg [2:0] phase_mux;
reg [`FIXED_WIDTH:1] temp;
begin
`ifdef DEBUG
$display("mmcm_phase-divide:%d,phase:%d", divide, phase);
`endif
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// If phase is less than 0, convert it to a positive phase shift
// Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
if(phase < 0) begin
phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
end else begin
phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
end
// Put phase in terms of decimal number of vco clock cycles
phase_in_cycles = ( phase_fixed * divide ) / 360;
`ifdef DEBUG
$display("phase_in_cycles: %h", phase_in_cycles);
`endif
temp = round_frac(phase_in_cycles, 3);
// set mx to 2'b00 that the phase mux from the VCO is enabled
mx = 2'b00;
phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2];
delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1];
`ifdef DEBUG
$display("temp: %h", temp);
`endif
// Setup the return value
mmcm_pll_phase={mx, phase_mux, delay_time};
end
endfunction
// This function takes the divide value and outputs the necessary lock values
function [39:0] mmcm_pll_lock_lookup
(
input [7:0] divide // Max M divide is 128 in UltrascalePlus
);
reg [5119:0] lookup;
begin
lookup = {
// This table is composed of:
// LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
40'b00110_00110_1111101000_1111101001_0000000001, // M=1 (not allowed)
40'b00110_00110_1111101000_1111101001_0000000001, // M=2
40'b01000_01000_1111101000_1111101001_0000000001, // M=3
40'b01011_01011_1111101000_1111101001_0000000001, // M=4
40'b01110_01110_1111101000_1111101001_0000000001, // M=5
40'b10001_10001_1111101000_1111101001_0000000001, // M=6
40'b10011_10011_1111101000_1111101001_0000000001, // M=7
40'b10110_10110_1111101000_1111101001_0000000001,
40'b11001_11001_1111101000_1111101001_0000000001,
40'b11100_11100_1111101000_1111101001_0000000001,
40'b11111_11111_1110000100_1111101001_0000000001,
40'b11111_11111_1100111001_1111101001_0000000001,
40'b11111_11111_1011101110_1111101001_0000000001,
40'b11111_11111_1010111100_1111101001_0000000001,
40'b11111_11111_1010001010_1111101001_0000000001,
40'b11111_11111_1001110001_1111101001_0000000001,
40'b11111_11111_1000111111_1111101001_0000000001,
40'b11111_11111_1000100110_1111101001_0000000001,
40'b11111_11111_1000001101_1111101001_0000000001,
40'b11111_11111_0111110100_1111101001_0000000001,
40'b11111_11111_0111011011_1111101001_0000000001,
40'b11111_11111_0111000010_1111101001_0000000001,
40'b11111_11111_0110101001_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0110010000_1111101001_0000000001,
40'b11111_11111_0101110111_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101011110_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0101000101_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100101100_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0100010011_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001,
40'b11111_11111_0011111010_1111101001_0000000001, // M=127
40'b11111_11111_0011111010_1111101001_0000000001 // M=128
};
// Set lookup_entry with the explicit bits from lookup with a part select
mmcm_pll_lock_lookup = lookup[ ((128-divide)*40) +: 40];
`ifdef DEBUG
$display("lock_lookup: %b", mmcm_pll_lock_lookup);
`endif
end
endfunction
// This function takes the divide value and the bandwidth setting of the MMCM
// and outputs the digital filter settings necessary.
function [9:0] mmcm_pll_filter_lookup
(
input [7:0] divide, // input [7:0] divide // Max M divide is 128 in UltraScalePlus
input [8*9:0] BANDWIDTH
);
reg [1279:0] lookup_low;
reg [1279:0] lookup_high;
reg [9:0] lookup_entry;
begin
lookup_low = {
// CP_RES_LFHF
10'b0011_1111_11, // M=1 - not legal
10'b0011_1111_11, // M=2
10'b0011_1101_11, // M=3
10'b0011_0101_11, // M=4
10'b0011_1001_11, // M=5
10'b0011_1110_11, // M=6
10'b0011_1110_11, // M=7
10'b0011_0001_11,
10'b0011_0110_11,
10'b0011_0110_11,
10'b0011_0110_11,
10'b0011_1010_11,
10'b0011_1010_11,
10'b0011_1010_11,
10'b0100_0110_11,
10'b0011_1100_11,
10'b1110_0110_11,
10'b1111_0110_11,
10'b1110_1010_11,
10'b1110_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1101_1100_11,
10'b1101_1100_11,
10'b1101_1100_11,
10'b1110_1100_11,
10'b1110_1100_11,
10'b1110_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1110_0010_11,
10'b1110_0010_11,
10'b1110_0010_11,
10'b1110_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11, // M=127
10'b1101_1000_11 // M=128
};
lookup_high = {
// CP_RES_LFHF
10'b0111_1111_11, // M=1 - not legal
10'b0111_1111_11, // M=2
10'b1110_1111_11, // M=3
10'b1111_1111_11, // M=4
10'b1111_1011_11, // M=5
10'b1111_1101_11, // M=6
10'b1111_0011_11, // M=7
10'b1110_0101_11,
10'b1111_1001_11,
10'b1111_1001_11,
10'b1110_1110_11,
10'b1111_1110_11,
10'b1111_0001_11,
10'b1111_0001_11,
10'b1111_0001_11,
10'b1110_0110_11,
10'b1110_0110_11,
10'b1111_0110_11,
10'b1110_1010_11,
10'b1110_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1111_1010_11,
10'b1101_1100_11,
10'b1101_1100_11,
10'b1101_1100_11,
10'b1110_1100_11,
10'b1110_1100_11,
10'b1110_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1111_1100_11,
10'b1110_0010_11,
10'b1110_0010_11,
10'b1110_0010_11,
10'b1110_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1111_0010_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1100_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1101_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1110_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1111_0100_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11,
10'b1101_1000_11 // M=128
};
// Set lookup_entry with the explicit bits from lookup with a part select
if(BANDWIDTH == "LOW") begin
// Low Bandwidth
mmcm_pll_filter_lookup = lookup_low[ ((128-divide)*10) +: 10];
end else begin
// High or optimized bandwidth
mmcm_pll_filter_lookup = lookup_high[ ((128-divide)*10) +: 10];
end
`ifdef DEBUG
$display("filter_lookup: %b", mmcm_pll_filter_lookup);
`endif
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
function [37:0] mmcm_pll_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle // Multiplied by 100,000
);
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_pll_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
// w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
div_calc = mmcm_pll_divider(divide, duty_cycle);
// mx[10:9], pm[8:6], dt[5:0]
phase_calc = mmcm_pll_phase(divide, phase);
// Return value is the upper and lower address of counter
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
`ifdef DEBUG
$display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
div_calc[13], div_calc[12],
phase_calc[16:15], phase_calc[5:0], phase_calc[14:12]);
`endif
mmcm_pll_count_calc =
{
// Upper Address
6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
// Lower Address
phase_calc[8:6], 1'b0, div_calc[11:0]
};
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
// for fractional multiply/divide functions.
//
//
function [37:0] mmcm_frac_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle, // Multiplied by 100,000. Not programmable in fractional
input [9:0] frac // Multiplied by 1000
);
//Required for fractional divide calculations
reg [7:0] lt_frac;
reg [7:0] ht_frac;
reg /*[7:0]*/ wf_fall_frac;
reg /*[7:0]*/ wf_rise_frac;
reg [31:0] a;
reg [7:0] pm_rise_frac_filtered ;
reg [7:0] pm_fall_frac_filtered ;
reg [7:0] clkout0_divide_int;
reg [2:0] clkout0_divide_frac;
reg [7:0] even_part_high;
reg [7:0] even_part_low;
reg [7:0] odd;
reg [7:0] odd_and_frac;
reg [7:0] pm_fall;
reg [7:0] pm_rise;
reg [7:0] dt;
reg [7:0] dt_int;
reg [63:0] dt_calc;
reg [7:0] pm_rise_frac;
reg [7:0] pm_fall_frac;
reg [31:0] a_per_in_octets;
reg [31:0] a_phase_in_cycles;
parameter precision = 0.125;
reg [31:0] phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11
reg [31: 0] phase_pos;
reg [31: 0] phase_vco;
reg [31:0] temp;// changed to 31:0 from 32:1 jt 5/2/11
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("mmcm_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
//convert phase to fixed
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// Return value is
// Transfer data
// RESERVED [37:36]
// FRAC_TIME [35:33]
// FRAC_WF_FALL [32]
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
clkout0_divide_frac = frac / 125;
clkout0_divide_int = divide;
even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2);
even_part_low = even_part_high;
odd = clkout0_divide_int - even_part_high - even_part_low;
odd_and_frac = (8*odd) + clkout0_divide_frac;
lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1)
ht_frac = even_part_low - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1)
pm_fall = {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2
pm_rise = 0; //0
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)
wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8); //IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0)
//Calculate phase in fractional cycles
a_per_in_octets = (8 * divide) + (frac / 125) ;
a_phase_in_cycles = (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors
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};
dt_calc = ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8)
dt = dt_calc[7:0];
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;
dt_int = dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt)
pm_fall_frac = pm_fall + pm_rise_frac;
pm_fall_frac_filtered = pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000};
div_calc = mmcm_pll_divider(divide, duty_cycle); //Use to determine edge[7], no count[6]
phase_calc = mmcm_pll_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]}
mmcm_frac_count_calc[37:0] =
{ 2'b00, pm_fall_frac_filtered[2:0], wf_fall_frac,
1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, phase_calc[10:9], 2'b00, dt[5: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]
} ;
`ifdef DEBUG
$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);
`endif
end
endfunction
@@ -1,536 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
// Company: Xilinx
// Engineer: Jim Tatsukawa, Ralf Krueger, updated for Ultrascale+
// Date: 6/15/2015
// Design Name: PLLE4 DRP
// Module Name: plle4_drp_func.h
// Version: 2.0
// Target Devices: UltraScale+ Architecture
// Tool versions: 2017.1
// Description: This header provides the functions necessary to
// calculate the DRP register values for the V6 PLL.
//
// Revision Notes: 8/11 - PLLE3 updated for PLLE3 file 4564419
// Revision Notes: 6/15 - pll_filter_lookup fixed for max M of 19
// M_Rise bits have been removed for PLLE3
// Revision Notes: 2/28/17 - pll_filter_lookup and CPRES updated for
// Ultrascale+ and for max M of 21
//
// Disclaimer: XILINX IS PROVIDING THIS DESIGN, CODE, OR
// INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
// PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY
// PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
// APPLICATION OR STANDARD, XILINX IS MAKING NO
// REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
// FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE
// RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY
// REQUIRE FOR YOUR IMPLEMENTATION. XILINX
// EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH
// RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION,
// INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
// REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE.
//
// (c) Copyright 2009-2017 Xilinx, Inc.
// All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
// These are user functions that should not be modified. Changes to the defines
// or code within the functions may alter the accuracy of the calculations.
// Define debug to provide extra messages durring elaboration
//`define DEBUG 1
// FRAC_PRECISION describes the width of the fractional portion of the fixed
// point numbers. These should not be modified, they are for development
// only
`define FRAC_PRECISION 10
// FIXED_WIDTH describes the total size for fixed point calculations(int+frac).
// Warning: L.50 and below will not calculate properly with FIXED_WIDTHs
// greater than 32
`define FIXED_WIDTH 32
// This function takes a fixed point number and rounds it to the nearest
// fractional precision bit.
function [`FIXED_WIDTH:1] round_frac
(
// Input is (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point number
input [`FIXED_WIDTH:1] decimal,
// This describes the precision of the fraction, for example a value
// of 1 would modify the fractional so that instead of being a .16
// fractional, it would be a .1 (rounded to the nearest 0.5 in turn)
input [`FIXED_WIDTH:1] precision
);
begin
`ifdef DEBUG
$display("round_frac - decimal: %h, precision: %h", decimal, precision);
`endif
// If the fractional precision bit is high then round up
if( decimal[(`FRAC_PRECISION-precision)] == 1'b1) begin
round_frac = decimal + (1'b1 << (`FRAC_PRECISION-precision));
end else begin
round_frac = decimal;
end
`ifdef DEBUG
$display("round_frac: %h", round_frac);
`endif
end
endfunction
// This function calculates high_time, low_time, w_edge, and no_count
// of a non-fractional counter based on the divide and duty cycle
//
// NOTE: high_time and low_time are returned as integers between 0 and 63
// inclusive. 64 should equal 6'b000000 (in other words it is okay to
// ignore the overflow)
function [13:0] mmcm_pll_divider
(
input [7:0] divide, // Max divide is 128
input [31:0] duty_cycle // Duty cycle is multiplied by 100,000
);
reg [`FIXED_WIDTH:1] duty_cycle_fix;
// High/Low time is initially calculated with a wider integer to prevent a
// calculation error when it overflows to 64.
reg [6:0] high_time;
reg [6:0] low_time;
reg w_edge;
reg no_count;
reg [`FIXED_WIDTH:1] temp;
begin
// Duty Cycle must be between 0 and 1,000
if(duty_cycle <=0 || duty_cycle >= 100000) begin
`ifndef SYNTHESIS
$display("ERROR: duty_cycle: %d is invalid", duty_cycle);
`endif
$finish;
end
// Convert to FIXED_WIDTH-FRAC_PRECISION.FRAC_PRECISION fixed point
duty_cycle_fix = (duty_cycle << `FRAC_PRECISION) / 100_000;
`ifdef DEBUG
$display("duty_cycle_fix: %h", duty_cycle_fix);
`endif
// If the divide is 1 nothing needs to be set except the no_count bit.
// Other values are dummies
if(divide == 7'h01) begin
high_time = 7'h01;
w_edge = 1'b0;
low_time = 7'h01;
no_count = 1'b1;
end else begin
temp = round_frac(duty_cycle_fix*divide, 1);
// comes from above round_frac
high_time = temp[`FRAC_PRECISION+7:`FRAC_PRECISION+1];
// If the duty cycle * divide rounded is .5 or greater then this bit
// is set.
w_edge = temp[`FRAC_PRECISION]; // comes from round_frac
// If the high time comes out to 0, it needs to be set to at least 1
// and w_edge set to 0
if(high_time == 7'h00) begin
high_time = 7'h01;
w_edge = 1'b0;
end
if(high_time == divide) begin
high_time = divide - 1;
w_edge = 1'b1;
end
// Calculate low_time based on the divide setting and set no_count to
// 0 as it is only used when divide is 1.
low_time = divide - high_time;
no_count = 1'b0;
end
// Set the return value.
mmcm_pll_divider = {w_edge,no_count,high_time[5:0],low_time[5:0]};
end
endfunction
// This function calculates mx, delay_time, and phase_mux
// of a non-fractional counter based on the divide and phase
//
// NOTE: The only valid value for the MX bits is 2'b00 to ensure the coarse mux
// is used.
function [10:0] mmcm_pll_phase
(
// divide must be an integer (use fractional if not)
// assumed that divide already checked to be valid
input [7:0] divide, // Max divide is 128
// Phase is given in degrees (-360,000 to 360,000)
input signed [31:0] phase
);
reg [`FIXED_WIDTH:1] phase_in_cycles;
reg [`FIXED_WIDTH:1] phase_fixed;
reg [1:0] mx;
reg [5:0] delay_time;
reg [2:0] phase_mux;
reg [`FIXED_WIDTH:1] temp;
begin
`ifdef DEBUG
$display("pll_phase-divide:%d,phase:%d",
divide, phase);
`endif
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// If phase is less than 0, convert it to a positive phase shift
// Convert to (FIXED_WIDTH-FRAC_PRECISION).FRAC_PRECISION fixed point
if(phase < 0) begin
phase_fixed = ( (phase + 360000) << `FRAC_PRECISION ) / 1000;
end else begin
phase_fixed = ( phase << `FRAC_PRECISION ) / 1000;
end
// Put phase in terms of decimal number of vco clock cycles
phase_in_cycles = ( phase_fixed * divide ) / 360;
`ifdef DEBUG
$display("phase_in_cycles: %h", phase_in_cycles);
`endif
temp = round_frac(phase_in_cycles, 3);
// set mx to 2'b00 that the phase mux from the VCO is enabled
mx = 2'b00;
phase_mux = temp[`FRAC_PRECISION:`FRAC_PRECISION-2];
delay_time = temp[`FRAC_PRECISION+6:`FRAC_PRECISION+1];
`ifdef DEBUG
$display("temp: %h", temp);
`endif
// Setup the return value
mmcm_pll_phase={mx, phase_mux, delay_time};
end
endfunction
// This function takes the divide value and outputs the necessary lock values
function [39:0] mmcm_pll_lock_lookup
(
input [6:0] divide // Max divide is 21
);
reg [839:0] lookup;
begin
lookup = {
// This table is composed of:
// LockRefDly_LockFBDly_LockCnt_LockSatHigh_UnlockCnt
40'b00110_00110_1111101000_1111101001_0000000001, //1 illegal in Ultrascale+
40'b00110_00110_1111101000_1111101001_0000000001, //2
40'b01000_01000_1111101000_1111101001_0000000001, //3
40'b01011_01011_1111101000_1111101001_0000000001, //4
40'b01110_01110_1111101000_1111101001_0000000001, //5
40'b10001_10001_1111101000_1111101001_0000000001, //6
40'b10011_10011_1111101000_1111101001_0000000001, //7
40'b10110_10110_1111101000_1111101001_0000000001, //8
40'b11001_11001_1111101000_1111101001_0000000001, //9
40'b11100_11100_1111101000_1111101001_0000000001, //10
40'b11111_11111_1110000100_1111101001_0000000001, //11
40'b11111_11111_1100111001_1111101001_0000000001, //12
40'b11111_11111_1011101110_1111101001_0000000001, //13
40'b11111_11111_1010111100_1111101001_0000000001, //14
40'b11111_11111_1010001010_1111101001_0000000001, //15
40'b11111_11111_1001110001_1111101001_0000000001, //16
40'b11111_11111_1000111111_1111101001_0000000001, //17
40'b11111_11111_1000100110_1111101001_0000000001, //18
40'b11111_11111_1000001101_1111101001_0000000001, //19
40'b11111_11111_0111110100_1111101001_0000000001, //20
40'b11111_11111_0111011011_1111101001_0000000001 //21
};
// Set lookup_entry with the explicit bits from lookup with a part select
mmcm_pll_lock_lookup = lookup[ ((21-divide)*40) +: 40];
`ifdef DEBUG
$display("lock_lookup: %b", pll_lock_lookup);
`endif
end
endfunction
// This function takes the divide value and the bandwidth setting of the PLL
// and outputs the digital filter settings necessary. Removing bandwidth setting for PLLE3.
function [9:0] mmcm_pll_filter_lookup
(
input [6:0] divide // Max divide is 21
);
reg [209:0] lookup;
reg [9:0] lookup_entry;
begin
lookup = {
// CP_RES_LFHF
10'b0011_0111_11, //1 not legal in Ultrascale+
10'b0011_0111_11, //2
10'b0011_0011_11, //3
10'b0011_1001_11, //4
10'b0011_0001_11, //5
10'b0100_1110_11, //6
10'b0011_0110_11, //7
10'b0011_1010_11, //8
10'b0111_1001_11, //9
10'b0111_1001_11, //10
10'b0101_0110_11, //11
10'b1100_0101_11, //12
10'b0101_1010_11, //13
10'b0110_0110_11, //14
10'b0110_1010_11, //15
10'b0111_0110_11, //16
10'b1111_0101_11, //17
10'b1100_0110_11, //18
10'b1110_0001_11, //19
10'b1101_0110_11, //20
10'b1111_0001_11 //21
};
mmcm_pll_filter_lookup = lookup [ ((21-divide)*10) +: 10];
`ifdef DEBUG
$display("filter_lookup: %b", pll_filter_lookup);
`endif
end
endfunction
// This function set the CLKOUTPHY divide settings to match
// the desired CLKOUTPHY_MODE setting. To create VCO_X2, then
// the CLKOUTPHY will be set to 2'b00 since the VCO is internally
// doubled and 2'b00 will represent divide by 1. Similarly "VCO"
// will need to divide the doubled clock VCO clock frequency by
// 2 therefore 2'b01 will match a divide by 2.And VCO_HALF will
// need to divide the doubled VCO by 4, therefore 2'b10
function [9:0] mmcm_pll_clkoutphy_calc
(
input [8*9:0] CLKOUTPHY_MODE
);
if(CLKOUTPHY_MODE == "VCO_X2") begin
mmcm_pll_clkoutphy_calc= 2'b00;
end else if(CLKOUTPHY_MODE == "VCO") begin
mmcm_pll_clkoutphy_calc= 2'b01;
end else if(CLKOUTPHY_MODE == "CLKIN") begin
mmcm_pll_clkoutphy_calc= 2'b11;
end else begin // Assume "VCO_HALF"
mmcm_pll_clkoutphy_calc= 2'b10;
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
function [37:0] mmcm_pll_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle // Multiplied by 100,000
);
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("pll_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
// w_edge[13], no_count[12], high_time[11:6], low_time[5:0]
div_calc = mmcm_pll_divider(divide, duty_cycle);
// mx[10:9], pm[8:6], dt[5:0]
phase_calc = mmcm_pll_phase(divide, phase);
// Return value is the upper and lower address of counter
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
`ifdef DEBUG
$display("div:%d dc:%d phase:%d ht:%d lt:%d ed:%d nc:%d mx:%d dt:%d pm:%d",
divide, duty_cycle, phase, div_calc[11:6], div_calc[5:0],
div_calc[13], div_calc[12],
phase_calc[16:15], phase_calc[5:0], 3'b000); //Removed PM_Rise bits
`endif
mmcm_pll_count_calc =
{
// Upper Address
6'h00, phase_calc[10:9], div_calc[13:12], phase_calc[5:0],
// Lower Address
phase_calc[8:6], 1'b0, div_calc[11:0]
};
end
endfunction
// This function takes in the divide, phase, and duty cycle
// setting to calculate the upper and lower counter registers.
// for fractional multiply/divide functions.
//
//
function [37:0] mmcm_pll_frac_count_calc
(
input [7:0] divide, // Max divide is 128
input signed [31:0] phase,
input [31:0] duty_cycle, // Multiplied by 1,000
input [9:0] frac // Multiplied by 1000
);
//Required for fractional divide calculations
reg [7:0] lt_frac;
reg [7:0] ht_frac;
reg /*[7:0]*/ wf_fall_frac;
reg /*[7:0]*/ wf_rise_frac;
reg [31:0] a;
reg [7:0] pm_rise_frac_filtered ;
reg [7:0] pm_fall_frac_filtered ;
reg [7:0] clkout0_divide_int;
reg [2:0] clkout0_divide_frac;
reg [7:0] even_part_high;
reg [7:0] even_part_low;
reg [7:0] odd;
reg [7:0] odd_and_frac;
reg [7:0] pm_fall;
reg [7:0] pm_rise;
reg [7:0] dt;
reg [7:0] dt_int;
reg [63:0] dt_calc;
reg [7:0] pm_rise_frac;
reg [7:0] pm_fall_frac;
reg [31:0] a_per_in_octets;
reg [31:0] a_phase_in_cycles;
parameter precision = 0.125;
reg [31:0] phase_fixed; // changed to 31:0 from 32:1 jt 5/2/11
reg [31: 0] phase_pos;
reg [31: 0] phase_vco;
reg [31:0] temp;// changed to 31:0 from 32:1 jt 5/2/11
reg [13:0] div_calc;
reg [16:0] phase_calc;
begin
`ifdef DEBUG
$display("pll_frac_count_calc- divide:%h, phase:%d, duty_cycle:%d",
divide, phase, duty_cycle);
`endif
//convert phase to fixed
if ((phase < -360000) || (phase > 360000)) begin
`ifndef SYNTHESIS
$display("ERROR: phase of $phase is not between -360000 and 360000");
`endif
$finish;
end
// Return value is
// Transfer data
// RESERVED [37:36]
// FRAC_TIME [35:33]
// FRAC_WF_FALL [32]
// Upper address is:
// RESERVED [31:26]
// MX [25:24]
// EDGE [23]
// NOCOUNT [22]
// DELAY_TIME [21:16]
// Lower Address is:
// PHASE_MUX [15:13]
// RESERVED [12]
// HIGH_TIME [11:6]
// LOW_TIME [5:0]
clkout0_divide_frac = frac / 125;
clkout0_divide_int = divide;
even_part_high = clkout0_divide_int >> 1;//$rtoi(clkout0_divide_int / 2);
even_part_low = even_part_high;
odd = clkout0_divide_int - even_part_high - even_part_low;
odd_and_frac = (8*odd) + clkout0_divide_frac;
lt_frac = even_part_high - (odd_and_frac <= 9);//IF(odd_and_frac>9,even_part_high, even_part_high - 1)
ht_frac = even_part_low - (odd_and_frac <= 8);//IF(odd_and_frac>8,even_part_low, even_part_low- 1)
pm_fall = {odd[6:0],2'b00} + {6'h00, clkout0_divide_frac[2:1]}; // using >> instead of clkout0_divide_frac / 2
pm_rise = 0; //0
wf_fall_frac = (odd_and_frac >=2) && (odd_and_frac <=9);//IF(odd_and_frac>=2,IF(odd_and_frac <= 9,1,0),0)
wf_rise_frac = (odd_and_frac >=1) && (odd_and_frac <=8);//IF(odd_and_frac>=1,IF(odd_and_frac <= 8,1,0),0)
//Calculate phase in fractional cycles
a_per_in_octets = (8 * divide) + (frac / 125) ;
a_phase_in_cycles = (phase+10) * a_per_in_octets / 360000 ;//Adding 1 due to rounding errors
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};
dt_calc = ((phase+10) * a_per_in_octets / 8 )/360000 ;//TRUNC(phase* divide / 360); //or_simply (a_per_in_octets / 8)
dt = dt_calc[7:0];
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;
dt_int = dt + (& pm_rise_frac[7:4]); //IF(pm_rise_overwriting>7,dt+1,dt)
pm_fall_frac = pm_fall + pm_rise_frac;
pm_fall_frac_filtered = pm_fall + pm_rise_frac - {pm_fall_frac[7:3], 3'b000};
div_calc = mmcm_pll_divider(divide, duty_cycle); //Use to determine edge[7], no count[6]
phase_calc = mmcm_pll_phase(divide, phase);// returns{mx[1:0], phase_mux[2:0], delay_time[5:0]}
mmcm_pll_frac_count_calc[37:0] =
{ 2'b00, pm_fall_frac_filtered[2:0], wf_fall_frac,
1'b0, clkout0_divide_frac[2:0], 1'b1, wf_rise_frac, phase_calc[10:9], div_calc[13:12], dt[5:0],
3'b000, 1'b0, ht_frac[5:0], lt_frac[5:0] //Removed PM_Rise bits
} ;
`ifdef DEBUG
$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, 3'b000, ht_frac, lt_frac);
`endif
end
endfunction
@@ -4,7 +4,7 @@
# README.txt: Please read the sections below to understand the steps required to
# run the exported script and information about the source files.
#
# Generated by export_simulation on Thu Mar 30 16:43:42 CST 2023
# Generated by export_simulation on Sat Apr 01 15:00:06 CST 2023
#
################################################################################
@@ -9,7 +9,7 @@
# directory, add the library logical mappings in the simulator setup file, create default
# 'do/prj' file, execute compilation, elaboration and simulation steps.
#
# Generated by Vivado on Thu Mar 30 16:43:42 CST 2023
# Generated by Vivado on Sat Apr 01 15:00:06 CST 2023
# SW Build 2644227 on Wed Sep 4 09:44:18 MDT 2019
#
# Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
@@ -4,7 +4,7 @@
# README.txt: Please read the sections below to understand the steps required to
# run the exported script and information about the source files.
#
# Generated by export_simulation on Thu Mar 30 16:43:42 CST 2023
# Generated by export_simulation on Sat Apr 01 15:00:06 CST 2023
#
################################################################################
@@ -9,7 +9,7 @@
# directory, add the library logical mappings in the simulator setup file, create default
# 'do/prj' file, execute compilation, elaboration and simulation steps.
#
# Generated by Vivado on Thu Mar 30 16:43:42 CST 2023
# Generated by Vivado on Sat Apr 01 15:00:06 CST 2023
# SW Build 2644227 on Wed Sep 4 09:44:18 MDT 2019
#
# Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
@@ -4,7 +4,7 @@
# README.txt: Please read the sections below to understand the steps required to
# run the exported script and information about the source files.
#
# Generated by export_simulation on Thu Mar 30 16:43:42 CST 2023
# Generated by export_simulation on Sat Apr 01 15:00:06 CST 2023
#
################################################################################
@@ -9,7 +9,7 @@
# directory, add the library logical mappings in the simulator setup file, create default
# 'do/prj' file, execute compilation, elaboration and simulation steps.
#
# Generated by Vivado on Thu Mar 30 16:43:42 CST 2023
# Generated by Vivado on Sat Apr 01 15:00:06 CST 2023
# SW Build 2644227 on Wed Sep 4 09:44:18 MDT 2019
#
# Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
@@ -4,7 +4,7 @@
# README.txt: Please read the sections below to understand the steps required to
# run the exported script and information about the source files.
#
# Generated by export_simulation on Thu Mar 30 16:43:42 CST 2023
# Generated by export_simulation on Sat Apr 01 15:00:06 CST 2023
#
################################################################################
@@ -9,7 +9,7 @@
# directory, add the library logical mappings in the simulator setup file, create default
# 'do/prj' file, execute compilation, elaboration and simulation steps.
#
# Generated by Vivado on Thu Mar 30 16:43:42 CST 2023
# Generated by Vivado on Sat Apr 01 15:00:06 CST 2023
# SW Build 2644227 on Wed Sep 4 09:44:18 MDT 2019
#
# Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
@@ -4,7 +4,7 @@
# README.txt: Please read the sections below to understand the steps required to
# run the exported script and information about the source files.
#
# Generated by export_simulation on Thu Mar 30 16:43:42 CST 2023
# Generated by export_simulation on Sat Apr 01 15:00:06 CST 2023
#
################################################################################
@@ -9,7 +9,7 @@
# directory, add the library logical mappings in the simulator setup file, create default
# 'do/prj' file, execute compilation, elaboration and simulation steps.
#
# Generated by Vivado on Thu Mar 30 16:43:42 CST 2023
# Generated by Vivado on Sat Apr 01 15:00:06 CST 2023
# SW Build 2644227 on Wed Sep 4 09:44:18 MDT 2019
#
# Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
@@ -4,7 +4,7 @@
# README.txt: Please read the sections below to understand the steps required to
# run the exported script and information about the source files.
#
# Generated by export_simulation on Thu Mar 30 16:43:42 CST 2023
# Generated by export_simulation on Sat Apr 01 15:00:06 CST 2023
#
################################################################################
@@ -9,7 +9,7 @@
# directory, add the library logical mappings in the simulator setup file, create default
# 'do/prj' file, execute compilation, elaboration and simulation steps.
#
# Generated by Vivado on Thu Mar 30 16:43:42 CST 2023
# Generated by Vivado on Sat Apr 01 15:00:06 CST 2023
# SW Build 2644227 on Wed Sep 4 09:44:18 MDT 2019
#
# Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
@@ -4,7 +4,7 @@
# README.txt: Please read the sections below to understand the steps required to
# run the exported script and information about the source files.
#
# Generated by export_simulation on Thu Mar 30 16:43:42 CST 2023
# Generated by export_simulation on Sat Apr 01 15:00:06 CST 2023
#
################################################################################
@@ -9,7 +9,7 @@
# directory, add the library logical mappings in the simulator setup file, create default
# 'do/prj' file, execute compilation, elaboration and simulation steps.
#
# Generated by Vivado on Thu Mar 30 16:43:42 CST 2023
# Generated by Vivado on Sat Apr 01 15:00:06 CST 2023
# SW Build 2644227 on Wed Sep 4 09:44:18 MDT 2019
#
# Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.
@@ -4,7 +4,7 @@
# README.txt: Please read the sections below to understand the steps required to
# run the exported script and information about the source files.
#
# Generated by export_simulation on Thu Mar 30 16:43:42 CST 2023
# Generated by export_simulation on Sat Apr 01 15:00:06 CST 2023
#
################################################################################
@@ -9,7 +9,7 @@
# directory, add the library logical mappings in the simulator setup file, create default
# 'do/prj' file, execute compilation, elaboration and simulation steps.
#
# Generated by Vivado on Thu Mar 30 16:43:42 CST 2023
# Generated by Vivado on Sat Apr 01 15:00:06 CST 2023
# SW Build 2644227 on Wed Sep 4 09:44:18 MDT 2019
#
# Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.