Commit 85a39483 authored by Andrey Filippov's avatar Andrey Filippov

mmcm/pll warppers

parent 407c39ca
...@@ -140,7 +140,7 @@ module phy_top #( ...@@ -140,7 +140,7 @@ module phy_top #(
.rst (rst), .rst (rst),
.dci_disable_dqs (dci_disable_dqs), // disable DCI termination during writes and idle for dqs .dci_disable_dqs (dci_disable_dqs), // disable DCI termination during writes and idle for dqs
.dci_disable_dq (dci_disable_dq), // disable DCI termination during writes and idle for dq and dm signals .dci_disable_dq (dci_disable_dq), // disable DCI termination during writes and idle for dq and dm signals
.din (din[31:0]), // parallel data to be sent out (4 bits per DG I/)) .din (din[31:0]), // parallel data to be sent out (4 bits per DQ I/O))
.din_dm (din_dm[3:0]), // parallel data to be sent out over DM .din_dm (din_dm[3:0]), // parallel data to be sent out over DM
.tin_dq (tin_dq[3:0]), // tristate for data out (sent out earlier than data!) and dm .tin_dq (tin_dq[3:0]), // tristate for data out (sent out earlier than data!) and dm
.din_dqs (din_dqs[3:0]), // parallel data to be sent out over DQS .din_dqs (din_dqs[3:0]), // parallel data to be sent out over DQS
...@@ -148,7 +148,7 @@ module phy_top #( ...@@ -148,7 +148,7 @@ module phy_top #(
.dout (dout[31:0]), // parallel data received from DDR3 memory, 4 bits per DQ I/O .dout (dout[31:0]), // parallel data received from DDR3 memory, 4 bits per DQ I/O
.dly_data (dly_data[7:0]), // delay value (3 LSB - fine delay) .dly_data (dly_data[7:0]), // delay value (3 LSB - fine delay)
.dly_addr (dly_addr[4:0]), // select which delay to program .dly_addr (dly_addr[4:0]), // select which delay to program
.ld_delay (ld_data_l), // load delay data to selected iodelayl (clk_iv synchronous) .ld_delay (ld_data_l), // load delay data to selected iodelayl (clk_div synchronous)
.set (set) // clk_div synchronous set all delays from previously loaded values .set (set) // clk_div synchronous set all delays from previously loaded values
); );
...@@ -172,7 +172,7 @@ module phy_top #( ...@@ -172,7 +172,7 @@ module phy_top #(
.rst (rst), .rst (rst),
.dci_disable_dqs (dci_disable_dqs), // disable DCI termination during writes and idle for dqs .dci_disable_dqs (dci_disable_dqs), // disable DCI termination during writes and idle for dqs
.dci_disable_dq (dci_disable_dq), // disable DCI termination during writes and idle for dq and dm signals .dci_disable_dq (dci_disable_dq), // disable DCI termination during writes and idle for dq and dm signals
.din (din[63:32]), // parallel data to be sent out (4 bits per DG I/)) .din (din[63:32]), // parallel data to be sent out (4 bits per DQ I/O))
.din_dm (din_dm[7:4]), // parallel data to be sent out over DM .din_dm (din_dm[7:4]), // parallel data to be sent out over DM
.tin_dq (tin_dq[7:4]), // tristate for data out (sent out earlier than data!) and dm .tin_dq (tin_dq[7:4]), // tristate for data out (sent out earlier than data!) and dm
.din_dqs (din_dqs[7:4]), // parallel data to be sent out over DQS .din_dqs (din_dqs[7:4]), // parallel data to be sent out over DQS
...@@ -180,7 +180,7 @@ module phy_top #( ...@@ -180,7 +180,7 @@ module phy_top #(
.dout (dout[63:32]), // parallel data received from DDR3 memory, 4 bits per DQ I/O .dout (dout[63:32]), // parallel data received from DDR3 memory, 4 bits per DQ I/O
.dly_data (dly_data[7:0]), // delay value (3 LSB - fine delay) .dly_data (dly_data[7:0]), // delay value (3 LSB - fine delay)
.dly_addr (dly_addr[4:0]), // select which delay to program .dly_addr (dly_addr[4:0]), // select which delay to program
.ld_delay (ld_data_h), // load delay data to selected iodelayl (clk_iv synchronous) .ld_delay (ld_data_h), // load delay data to selected iodelayl (clk_div synchronous)
.set (set) // clk_div synchronous set all delays from previously loaded values .set (set) // clk_div synchronous set all delays from previously loaded values
); );
......
...@@ -20,94 +20,168 @@ ...@@ -20,94 +20,168 @@
*******************************************************************************/ *******************************************************************************/
`timescale 1ns/1ps `timescale 1ns/1ps
module mmcm_adv( module mmcm_adv#(
parameter CLKIN1_PERIOD = 0.000, // input period in ns, 0..100.000 - MANDATORY, resolution down to 1 ps
parameter CLKIN2_PERIOD = 0.000, // input period in ns, 0..100.000 - MANDATORY, resolution down to 1 ps
parameter BANDWIDTH = "OPTIMIZED", //"OPTIMIZED", "HIGH","LOW"
parameter CLKFBOUT_MULT_F = 5.000, // 2.0 to 64.0 . Together with CLKOUT#_DIVIDE and DIVCLK_DIVIDE
parameter CLKFBOUT_PHASE = 0.000, // CLOCK FEEDBACK phase in degrees (3 significant digits, -360.000...+360.000)
parameter CLKOUT0_PHASE = 0.000, // CLOCK0 phase in degrees (3 significant digits, -360.000...+360.000)
parameter CLKOUT1_PHASE = 0.000, // Initial/static fine phase shift, 1/(56*Fvco) actual step
parameter CLKOUT2_PHASE = 0.000,
parameter CLKOUT3_PHASE = 0.000,
parameter CLKOUT4_PHASE = 0.000,
parameter CLKOUT5_PHASE = 0.000,
parameter CLKOUT6_PHASE = 0.000,
parameter CLKOUT0_DUTY_CYCLE= 0.5, // CLOCK 0 output duty factor, 3 significant digits
parameter CLKOUT1_DUTY_CYCLE= 0.5,
parameter CLKOUT2_DUTY_CYCLE= 0.5,
parameter CLKOUT3_DUTY_CYCLE= 0.5,
parameter CLKOUT4_DUTY_CYCLE= 0.5,
parameter CLKOUT5_DUTY_CYCLE= 0.5,
parameter CLKOUT6_DUTY_CYCLE= 0.5,
parameter CLKOUT4_CASCADE= "FALSE", // cascades the output6 divider to the input for output 4
parameter CLKFBOUT_USE_FINE_PS = "FALSE", // Enable variable fine pase shift. Enable 1/(56*Fvco) phase inceremnts, round-robin
parameter CLKOUT0_USE_FINE_PS = "FALSE", // Same fine phase shift for all outputs where this attribute is "TRUE"
parameter CLKOUT1_USE_FINE_PS = "FALSE", // Not compatible with fractional divide
parameter CLKOUT2_USE_FINE_PS = "FALSE",
parameter CLKOUT3_USE_FINE_PS = "FALSE",
parameter CLKOUT4_USE_FINE_PS = "FALSE",
parameter CLKOUT5_USE_FINE_PS = "FALSE",
parameter CLKOUT6_USE_FINE_PS = "FALSE",
parameter CLKOUT0_DIVIDE_F = 1.000, // CLK0 outout divide, floating 1.000..128.000
parameter CLKOUT1_DIVIDE = 1, // CLK1 outout divide, integer 1..128 (determins a phase step as a fraction of pi/4)
parameter CLKOUT2_DIVIDE = 1,
parameter CLKOUT3_DIVIDE = 1,
parameter CLKOUT4_DIVIDE = 1,
parameter CLKOUT5_DIVIDE = 1,
parameter CLKOUT6_DIVIDE = 1,
parameter COMPENSATION= "ZHOLD", // "ZHOLD",BUF_IN","EXTERNAL","INTERNAL
// ZHOLD - provide negative hold time on I/O registers
// INTERNAL - using internal compensation no deley is compensated
// EXTERNAL - external to the FPGA network is being compensated
// BUF_IN - no compensation when clock input is driveen by BUFG/BUFH/BUFR or GT
parameter DIVCLK_DIVIDE = 1, // Integer 1..106. Divides all outputs with respect to CLKIN
parameter REF_JITTER1 = 0.010, // Expectet jitter on CLKIN1 (0.000..0.999)
parameter REF_JITTER2 = 0.010,
parameter SS_EN = "FALSE", // Enables Spread Spectrum mode
parameter SS_MODE = "CENTER_HIGH",//"CENTER_HIGH","CENTER_LOW","DOWN_HIGH","DOWN_LOW"
parameter SS_MOD_PERIOD = 10000, // integer 4000-40000 - SS modulation period in ns
parameter STARTUP_WAIT = "FALSE" // Delays "DONE" signal until MMCM is locked
)
(
input clkin1, // General clock input
input clkin2, // Secondary clock input
input clkfbin, // Feedback clock input
input clkinsel, // Clock select input : 1 - clkin1, 0 - clkin2
input rst, // asynchronous reset input
input pwrdwn, // power down input
input psclk, // phase shift clock input
input psen, // phase shift enable input
input psincdec, // phase shift direction input (1 - increment, 0 - decrement)
output psdone, // phase shift done (12 clocks after psen
output clkout0, // output 0, HPC BUFR/BUFIO capable
output clkout1, // output 1, HPC BUFR/BUFIO capable
output clkout2, // output 2, HPC BUFR/BUFIO capable
output clkout3, // output 3, HPC BUFR/BUFIO capable
output clkout4, // output 4, HPC BUFR/BUFIO not capable
output clkout5, // output 5, HPC BUFR/BUFIO not capable
output clkout6, // output 6, HPC BUFR/BUFIO not capable
output clkout0b, // output 0, inverted
output clkout1b, // output 1, inverted
output clkout2b, // output 2, inverted
output clkout3b, // output 3, inverted
output clkfbout, // dedicate feedback output
output clkfboutb,// inverted feedback output
output locked // PLL locked output
); );
/* Instance template for module MMCME2_ADV */
MMCME2_ADV #( MMCME2_ADV #(
.BANDWIDTH("OPTIMIZED"), .BANDWIDTH (BANDWIDTH),
.CLKFBOUT_MULT_F(5.000), .CLKFBOUT_MULT_F (CLKFBOUT_MULT_F),
.CLKFBOUT_PHASE(0.000), .CLKFBOUT_PHASE (CLKFBOUT_PHASE),
.CLKFBOUT_USE_FINE_PS("FALSE"), .CLKFBOUT_USE_FINE_PS(CLKFBOUT_USE_FINE_PS),
.CLKIN1_PERIOD(0.000), .CLKIN1_PERIOD (CLKIN1_PERIOD),
.CLKIN2_PERIOD(0.000), .CLKIN2_PERIOD (CLKIN2_PERIOD),
.CLKOUT0_DIVIDE_F(1.000), .CLKOUT0_DIVIDE_F (CLKOUT0_DIVIDE_F),
.CLKOUT0_DUTY_CYCLE(0.500), .CLKOUT0_DUTY_CYCLE (CLKOUT0_DUTY_CYCLE),
.CLKOUT0_PHASE(0.000), .CLKOUT0_PHASE (CLKOUT0_PHASE),
.CLKOUT0_USE_FINE_PS("FALSE"), .CLKOUT0_USE_FINE_PS (CLKOUT0_USE_FINE_PS),
.CLKOUT1_DIVIDE(1), .CLKOUT1_DIVIDE (CLKOUT1_DIVIDE),
.CLKOUT1_DUTY_CYCLE(0.500), .CLKOUT1_DUTY_CYCLE (CLKOUT1_DUTY_CYCLE),
.CLKOUT1_PHASE(0.000), .CLKOUT1_PHASE (CLKOUT1_PHASE),
.CLKOUT1_USE_FINE_PS("FALSE"), .CLKOUT1_USE_FINE_PS (CLKOUT1_USE_FINE_PS),
.CLKOUT2_DIVIDE(1), .CLKOUT2_DIVIDE (CLKOUT2_DIVIDE),
.CLKOUT2_DUTY_CYCLE(0.500), .CLKOUT2_DUTY_CYCLE (CLKOUT2_DUTY_CYCLE),
.CLKOUT2_PHASE(0.000), .CLKOUT2_PHASE (CLKOUT2_PHASE),
.CLKOUT2_USE_FINE_PS("FALSE"), .CLKOUT2_USE_FINE_PS (CLKOUT2_USE_FINE_PS),
.CLKOUT3_DIVIDE(1), .CLKOUT3_DIVIDE (CLKOUT3_DIVIDE),
.CLKOUT3_DUTY_CYCLE(0.500), .CLKOUT3_DUTY_CYCLE (CLKOUT3_DUTY_CYCLE),
.CLKOUT3_PHASE(0.000), .CLKOUT3_PHASE (CLKOUT3_PHASE),
.CLKOUT3_USE_FINE_PS("FALSE"), .CLKOUT3_USE_FINE_PS (CLKOUT3_USE_FINE_PS),
.CLKOUT4_CASCADE("FALSE"), .CLKOUT4_CASCADE (CLKOUT4_CASCADE),
.CLKOUT4_DIVIDE(1), .CLKOUT4_DIVIDE (CLKOUT4_DIVIDE),
.CLKOUT4_DUTY_CYCLE(0.500), .CLKOUT4_DUTY_CYCLE (CLKOUT4_DUTY_CYCLE),
.CLKOUT4_PHASE(0.000), .CLKOUT4_PHASE (CLKOUT4_PHASE),
.CLKOUT4_USE_FINE_PS("FALSE"), .CLKOUT4_USE_FINE_PS (CLKOUT4_USE_FINE_PS),
.CLKOUT5_DIVIDE(1), .CLKOUT5_DIVIDE (CLKOUT5_DIVIDE),
.CLKOUT5_DUTY_CYCLE(0.500), .CLKOUT5_DUTY_CYCLE (CLKOUT5_DUTY_CYCLE),
.CLKOUT5_PHASE(0.000), .CLKOUT5_PHASE (CLKOUT5_PHASE),
.CLKOUT5_USE_FINE_PS("FALSE"), .CLKOUT5_USE_FINE_PS (CLKOUT5_USE_FINE_PS),
.CLKOUT6_DIVIDE(1), .CLKOUT6_DIVIDE (CLKOUT6_DIVIDE),
.CLKOUT6_DUTY_CYCLE(0.500), .CLKOUT6_DUTY_CYCLE (CLKOUT6_DUTY_CYCLE),
.CLKOUT6_PHASE(0.000), .CLKOUT6_PHASE (CLKOUT6_PHASE),
.CLKOUT6_USE_FINE_PS("FALSE"), .CLKOUT6_USE_FINE_PS (CLKOUT6_USE_FINE_PS),
.COMPENSATION("ZHOLD"), .COMPENSATION (COMPENSATION),
.DIVCLK_DIVIDE(1), .DIVCLK_DIVIDE (DIVCLK_DIVIDE),
.IS_CLKINSEL_INVERTED(1'b0), .IS_CLKINSEL_INVERTED (1'b0),
.IS_PSEN_INVERTED(1'b0), .IS_PSEN_INVERTED (1'b0),
.IS_PSINCDEC_INVERTED(1'b0), .IS_PSINCDEC_INVERTED (1'b0),
.IS_PWRDWN_INVERTED(1'b0), .IS_PWRDWN_INVERTED (1'b0),
.IS_RST_INVERTED(1'b0), .IS_RST_INVERTED (1'b0),
.REF_JITTER1(0.010), .REF_JITTER1 (REF_JITTER1),
.REF_JITTER2(0.010), .REF_JITTER2 (REF_JITTER2),
.SS_EN("FALSE"), .SS_EN (SS_EN),
.SS_MODE("CENTER_HIGH"), .SS_MODE (SS_MODE),
.SS_MOD_PERIOD(10000), .SS_MOD_PERIOD (SS_MOD_PERIOD),
.STARTUP_WAIT("FALSE") .STARTUP_WAIT (STARTUP_WAIT)
) MMCME2_ADV_i ( ) MMCME2_ADV_i (
.CLKFBOUT(), // output .CLKFBOUT (clkfbout), // output
.CLKFBOUTB(), // output .CLKFBOUTB (clkfboutb), // output
.CLKFBSTOPPED(), // output .CLKFBSTOPPED (), // output
.CLKINSTOPPED(), // output .CLKINSTOPPED (), // output
.CLKOUT0(), // output .CLKOUT0 (clkout0), // output
.CLKOUT0B(), // output .CLKOUT0B (clkout0b), // output
.CLKOUT1(), // output .CLKOUT1 (clkout1), // output
.CLKOUT1B(), // output .CLKOUT1B (clkout1b), // output
.CLKOUT2(), // output .CLKOUT2 (clkout2), // output
.CLKOUT2B(), // output .CLKOUT2B (clkout2b), // output
.CLKOUT3(), // output .CLKOUT3 (clkout3), // output
.CLKOUT3B(), // output .CLKOUT3B (clkout3b), // output
.CLKOUT4(), // output .CLKOUT4 (clkout4), // output
.CLKOUT5(), // output .CLKOUT5 (clkout5), // output
.CLKOUT6(), // output .CLKOUT6 (clkout6), // output
.DO(), // output[15:0] .DO (), // Dynamic reconfiguration output[15:0]
.DRDY(), // output .DRDY (), // Dynamic reconfiguration output
.LOCKED(), // output .LOCKED (locked), // output
.PSDONE(), // output .PSDONE (psdone), // output
.CLKFBIN(), // input .CLKFBIN (clkfbin), // input
.CLKIN1(), // input .CLKIN1 (clkin1), // input
.CLKIN2(), // input .CLKIN2 (clkin2), // input
.CLKINSEL(), // input .CLKINSEL (clkinsel), // input
.DADDR(), // input[6:0] .DADDR (7'b0), // Dynamic reconfiguration address (input[6:0])
.DCLK(), // input .DCLK (1'b0), // Dynamic reconfiguration clock input
.DEN(), // input .DEN (1'b0), // Dynamic reconfiguration enable input
.DI(), // input[15:0] .DI (16'b0), // Dynamic reconfiguration data (input[15:0])
.DWE(), // input .DWE (1'b0), // Dynamic reconfiguration Write Enable input
.PSCLK(), // input .PSCLK (psclk), // input
.PSEN(), // input .PSEN (psen), // input
.PSINCDEC(), // input .PSINCDEC (psincdec), // input
.PWRDWN(), // input .PWRDWN (pwrdwn), // input
.RST() // input .RST (rst) // input
); );
endmodule endmodule
/*******************************************************************************
* Module: mmcm_phase_cntr
* Date:2014-05-01
* Author: Andrey Filippov
* Description: MMCME2_ADV with phase counter, supporting absolute phase setting
*
* Copyright (c) 2014 Elphel, Inc.
* mmcm_phase_cntr.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mmcm_phase_cntr.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale 1ns/1ps
// all counters are two-clock cycle nets
module mmcm_phase_cntr#(
parameter PHASE_WIDTH= 8, // number of bits for te phase counter (depends on divisors)
parameter CLKIN_PERIOD = 0.000, // input period in ns, 0..100.000 - MANDATORY, resolution down to 1 ps
parameter BANDWIDTH = "OPTIMIZED", //"OPTIMIZED", "HIGH","LOW"
parameter CLKFBOUT_MULT_F = 5.000, // 2.0 to 64.0 . Together with CLKOUT#_DIVIDE and DIVCLK_DIVIDE
parameter CLKFBOUT_PHASE = 0.000, // CLOCK FEEDBACK phase in degrees (3 significant digits, -360.000...+360.000)
parameter CLKOUT0_PHASE = 0.000, // CLOCK0 phase in degrees (3 significant digits, -360.000...+360.000)
parameter CLKOUT1_PHASE = 0.000, // Initial/static fine phase shift, 1/(56*Fvco) actual step
parameter CLKOUT2_PHASE = 0.000,
parameter CLKOUT3_PHASE = 0.000,
parameter CLKOUT4_PHASE = 0.000,
parameter CLKOUT5_PHASE = 0.000,
parameter CLKOUT6_PHASE = 0.000,
parameter CLKOUT0_DUTY_CYCLE= 0.5, // CLOCK 0 output duty factor, 3 significant digits
parameter CLKOUT1_DUTY_CYCLE= 0.5,
parameter CLKOUT2_DUTY_CYCLE= 0.5,
parameter CLKOUT3_DUTY_CYCLE= 0.5,
parameter CLKOUT4_DUTY_CYCLE= 0.5,
parameter CLKOUT5_DUTY_CYCLE= 0.5,
parameter CLKOUT6_DUTY_CYCLE= 0.5,
parameter CLKOUT4_CASCADE= "FALSE", // cascades the output6 divider to the input for output 4
parameter CLKFBOUT_USE_FINE_PS = "FALSE", // Enable variable fine pase shift. Enable 1/(56*Fvco) phase inceremnts, round-robin
parameter CLKOUT0_USE_FINE_PS = "FALSE", // Same fine phase shift for all outputs where this attribute is "TRUE"
parameter CLKOUT1_USE_FINE_PS = "FALSE", // Not compatible with fractional divide
parameter CLKOUT2_USE_FINE_PS = "FALSE",
parameter CLKOUT3_USE_FINE_PS = "FALSE",
parameter CLKOUT4_USE_FINE_PS = "FALSE",
parameter CLKOUT5_USE_FINE_PS = "FALSE",
parameter CLKOUT6_USE_FINE_PS = "FALSE",
parameter CLKOUT0_DIVIDE_F = 1.000, // CLK0 outout divide, floating 1.000..128.000
parameter CLKOUT1_DIVIDE = 1, // CLK1 outout divide, integer 1..128 (determins a phase step as a fraction of pi/4)
parameter CLKOUT2_DIVIDE = 1,
parameter CLKOUT3_DIVIDE = 1,
parameter CLKOUT4_DIVIDE = 1,
parameter CLKOUT5_DIVIDE = 1,
parameter CLKOUT6_DIVIDE = 1,
parameter COMPENSATION= "ZHOLD", // "ZHOLD",BUF_IN","EXTERNAL","INTERNAL
// ZHOLD - provide negative hold time on I/O registers
// INTERNAL - using internal compensation no deley is compensated
// EXTERNAL - external to the FPGA network is being compensated
// BUF_IN - no compensation when clock input is driveen by BUFG/BUFH/BUFR or GT
parameter DIVCLK_DIVIDE = 1, // Integer 1..106. Divides all outputs with respect to CLKIN
parameter REF_JITTER1 = 0.010, // Expectet jitter on CLKIN1 (0.000..0.999)
parameter REF_JITTER2 = 0.010,
parameter SS_EN = "FALSE", // Enables Spread Spectrum mode
parameter SS_MODE = "CENTER_HIGH",//"CENTER_HIGH","CENTER_LOW","DOWN_HIGH","DOWN_LOW"
parameter SS_MOD_PERIOD = 10000, // integer 4000-40000 - SS modulation period in ns
parameter STARTUP_WAIT = "FALSE" // Delays "DONE" signal until MMCM is locked
)
(
input clkin, // General clock input
input clkfbin, // Feedback clock input
input rst, // asynchronous reset input
input pwrdwn, // power down input
input psclk, // phase shift clock input
input ps_we, // phase shift write eneble
input [PHASE_WIDTH-1:0] ps_din, // phase shift data input (2-s complement)
output ps_ready, // phase shift change finished
output reg [PHASE_WIDTH-1:0] ps_dout, // current phase shift value
output clkout0, // output 0, HPC BUFR/BUFIO capable
output clkout1, // output 1, HPC BUFR/BUFIO capable
output clkout2, // output 2, HPC BUFR/BUFIO capable
output clkout3, // output 3, HPC BUFR/BUFIO capable
output clkout4, // output 4, HPC BUFR/BUFIO not capable
output clkout5, // output 5, HPC BUFR/BUFIO not capable
output clkout6, // output 6, HPC BUFR/BUFIO not capable
output clkout0b, // output 0, inverted
output clkout1b, // output 1, inverted
output clkout2b, // output 2, inverted
output clkout3b, // output 3, inverted
output clkfbout, // dedicate feedback output
output clkfboutb,// inverted feedback output
output locked // PLL locked output
);
wire psen; // phase shift enable input
reg psincdec; // phase shift direction input (1 - increment, 0 - decrement)
wire psdone; // phase shift done (12 clocks after psen
reg [PHASE_WIDTH-1:0] ps_target;
reg ps_busy=0;
reg ps_start0, ps_start;
assign ps_ready=!ps_busy && locked && ps_start0 && ps_start;
assign psen=ps_start && (diff != 0);
wire [PHASE_WIDTH:0] diff= ps_target-ps_dout;
always @ (posedge psclk or posedge rst) begin
if (rst) ps_start0 <= 0;
else ps_start0 <= ps_we && ps_ready;
if (rst) ps_dout <= 0;
else if (psen && psincdec) ps_dout <= ps_dout +1;
else if (psen && !psincdec) ps_dout <= ps_dout -1;
if (rst) ps_target <= 0;
else if (ps_we && ps_ready) ps_target <= ps_din;
if (rst) ps_busy <= 1'b0;
else if (ps_start) ps_busy <= (diff!=0);
end
always @ (posedge psclk) begin
ps_start <= ps_start0 || psdone;
psincdec <= !diff[PHASE_WIDTH];
end
MMCME2_ADV #(
.BANDWIDTH (BANDWIDTH),
.CLKFBOUT_MULT_F (CLKFBOUT_MULT_F),
.CLKFBOUT_PHASE (CLKFBOUT_PHASE),
.CLKFBOUT_USE_FINE_PS(CLKFBOUT_USE_FINE_PS),
.CLKIN1_PERIOD (CLKIN_PERIOD),
.CLKIN2_PERIOD (0),
.CLKOUT0_DIVIDE_F (CLKOUT0_DIVIDE_F),
.CLKOUT0_DUTY_CYCLE (CLKOUT0_DUTY_CYCLE),
.CLKOUT0_PHASE (CLKOUT0_PHASE),
.CLKOUT0_USE_FINE_PS (CLKOUT0_USE_FINE_PS),
.CLKOUT1_DIVIDE (CLKOUT1_DIVIDE),
.CLKOUT1_DUTY_CYCLE (CLKOUT1_DUTY_CYCLE),
.CLKOUT1_PHASE (CLKOUT1_PHASE),
.CLKOUT1_USE_FINE_PS (CLKOUT1_USE_FINE_PS),
.CLKOUT2_DIVIDE (CLKOUT2_DIVIDE),
.CLKOUT2_DUTY_CYCLE (CLKOUT2_DUTY_CYCLE),
.CLKOUT2_PHASE (CLKOUT2_PHASE),
.CLKOUT2_USE_FINE_PS (CLKOUT2_USE_FINE_PS),
.CLKOUT3_DIVIDE (CLKOUT3_DIVIDE),
.CLKOUT3_DUTY_CYCLE (CLKOUT3_DUTY_CYCLE),
.CLKOUT3_PHASE (CLKOUT3_PHASE),
.CLKOUT3_USE_FINE_PS (CLKOUT3_USE_FINE_PS),
.CLKOUT4_CASCADE (CLKOUT4_CASCADE),
.CLKOUT4_DIVIDE (CLKOUT4_DIVIDE),
.CLKOUT4_DUTY_CYCLE (CLKOUT4_DUTY_CYCLE),
.CLKOUT4_PHASE (CLKOUT4_PHASE),
.CLKOUT4_USE_FINE_PS (CLKOUT4_USE_FINE_PS),
.CLKOUT5_DIVIDE (CLKOUT5_DIVIDE),
.CLKOUT5_DUTY_CYCLE (CLKOUT5_DUTY_CYCLE),
.CLKOUT5_PHASE (CLKOUT5_PHASE),
.CLKOUT5_USE_FINE_PS (CLKOUT5_USE_FINE_PS),
.CLKOUT6_DIVIDE (CLKOUT6_DIVIDE),
.CLKOUT6_DUTY_CYCLE (CLKOUT6_DUTY_CYCLE),
.CLKOUT6_PHASE (CLKOUT6_PHASE),
.CLKOUT6_USE_FINE_PS (CLKOUT6_USE_FINE_PS),
.COMPENSATION (COMPENSATION),
.DIVCLK_DIVIDE (DIVCLK_DIVIDE),
.IS_CLKINSEL_INVERTED (1'b0),
.IS_PSEN_INVERTED (1'b0),
.IS_PSINCDEC_INVERTED (1'b0),
.IS_PWRDWN_INVERTED (1'b0),
.IS_RST_INVERTED (1'b0),
.REF_JITTER1 (REF_JITTER1),
.REF_JITTER2 (REF_JITTER2),
.SS_EN (SS_EN),
.SS_MODE (SS_MODE),
.SS_MOD_PERIOD (SS_MOD_PERIOD),
.STARTUP_WAIT (STARTUP_WAIT)
) MMCME2_ADV_i (
.CLKFBOUT (clkfbout), // output
.CLKFBOUTB (clkfboutb), // output
.CLKFBSTOPPED (), // output
.CLKINSTOPPED (), // output
.CLKOUT0 (clkout0), // output
.CLKOUT0B (clkout0b), // output
.CLKOUT1 (clkout1), // output
.CLKOUT1B (clkout1b), // output
.CLKOUT2 (clkout2), // output
.CLKOUT2B (clkout2b), // output
.CLKOUT3 (clkout3), // output
.CLKOUT3B (clkout3b), // output
.CLKOUT4 (clkout4), // output
.CLKOUT5 (clkout5), // output
.CLKOUT6 (clkout6), // output
.DO (), // Dynamic reconfiguration output[15:0]
.DRDY (), // Dynamic reconfiguration output
.LOCKED (locked), // output
.PSDONE (psdone), // output
.CLKFBIN (clkfbin), // input
.CLKIN1 (clkin), // input
.CLKIN2 (1'b0), // input
.CLKINSEL (1'b1), // input Select CLKIN1
.DADDR (7'b0), // Dynamic reconfiguration address (input[6:0])
.DCLK (1'b0), // Dynamic reconfiguration clock input
.DEN (1'b0), // Dynamic reconfiguration enable input
.DI (16'b0), // Dynamic reconfiguration data (input[15:0])
.DWE (1'b0), // Dynamic reconfiguration Write Enable input
.PSCLK (psclk), // input
.PSEN (psen), // input
.PSINCDEC (psincdec), // input
.PWRDWN (pwrdwn), // input
.RST (rst) // input
);
endmodule
/*******************************************************************************
* Module: pll_base
* Date:2014-05-01
* Author: Andrey Filippov
* Description: PLLE2_BASE wrapper
*
* Copyright (c) 2014 Elphel, Inc.
* pll_base.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* pll_base.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale 1ns/1ps
module pll_base#(
parameter CLKIN_PERIOD = 0.000, // input period in ns, 0..100.000 - MANDATORY, resolution down to 1 ps
parameter BANDWIDTH = "OPTIMIZED", // "OPTIMIZED", "HIGH","LOW"
parameter CLKFBOUT_MULT = 1, // integer 1 to 64 . Together with CLKOUT#_DIVIDE and DIVCLK_DIVIDE
parameter CLKFBOUT_PHASE = 0.000, // CLOCK FEEDBACK phase in degrees (3 significant digits, -360.000...+360.000)
parameter CLKOUT0_PHASE = 0.000, // CLOCK0 phase in degrees (3 significant digits, -360.000...+360.000)
parameter CLKOUT1_PHASE = 0.000, // Initial/static fine phase shift, 1/(56*Fvco) actual step
parameter CLKOUT2_PHASE = 0.000,
parameter CLKOUT3_PHASE = 0.000,
parameter CLKOUT4_PHASE = 0.000,
parameter CLKOUT5_PHASE = 0.000,
parameter CLKOUT0_DUTY_CYCLE= 0.5, // CLOCK 0 output duty factor, 3 significant digits
parameter CLKOUT1_DUTY_CYCLE= 0.5,
parameter CLKOUT2_DUTY_CYCLE= 0.5,
parameter CLKOUT3_DUTY_CYCLE= 0.5,
parameter CLKOUT4_DUTY_CYCLE= 0.5,
parameter CLKOUT5_DUTY_CYCLE= 0.5,
parameter CLKOUT0_DIVIDE = 1, // CLK0 outout divide, integer 1..128
parameter CLKOUT1_DIVIDE = 1, // CLK1 outout divide, integer 1..128 (determins a phase step as a fraction of pi/4)
parameter CLKOUT2_DIVIDE = 1,
parameter CLKOUT3_DIVIDE = 1,
parameter CLKOUT4_DIVIDE = 1,
parameter CLKOUT5_DIVIDE = 1,
parameter DIVCLK_DIVIDE = 1, // Integer 1..106. Divides all outputs with respect to CLKIN
parameter REF_JITTER1 = 0.010, // Expectet jitter on CLKIN1 (0.000..0.999)
parameter STARTUP_WAIT = "FALSE" // Delays "DONE" signal until MMCM is locked
)
(
input clkin, // General clock input
input clkfbin, // Feedback clock input
input rst, // asynchronous reset input
input pwrdwn, // power down input
output clkout0, // output 0, HPC BUFR/BUFIO capable
output clkout1, // output 1, HPC BUFR/BUFIO capable
output clkout2, // output 2, HPC BUFR/BUFIO capable
output clkout3, // output 3, HPC BUFR/BUFIO capable
output clkout4, // output 4, HPC BUFR/BUFIO not capable
output clkout5, // output 5, HPC BUFR/BUFIO not capable
output clkfbout, // dedicate feedback output
output locked // PLL locked output
);
PLLE2_BASE #(
.BANDWIDTH (BANDWIDTH),
.CLKFBOUT_MULT (CLKFBOUT_MULT),
.CLKFBOUT_PHASE (CLKFBOUT_PHASE),
.CLKIN1_PERIOD (CLKIN_PERIOD),
.CLKOUT0_DIVIDE (CLKOUT0_DIVIDE),
.CLKOUT0_DUTY_CYCLE (CLKOUT0_DUTY_CYCLE),
.CLKOUT0_PHASE (CLKOUT0_PHASE),
.CLKOUT1_DIVIDE (CLKOUT1_DIVIDE),
.CLKOUT1_DUTY_CYCLE (CLKOUT1_DUTY_CYCLE),
.CLKOUT1_PHASE (CLKOUT1_PHASE),
.CLKOUT2_DIVIDE (CLKOUT2_DIVIDE),
.CLKOUT2_DUTY_CYCLE (CLKOUT2_DUTY_CYCLE),
.CLKOUT2_PHASE (CLKOUT2_PHASE),
.CLKOUT3_DIVIDE (CLKOUT3_DIVIDE),
.CLKOUT3_DUTY_CYCLE (CLKOUT3_DUTY_CYCLE),
.CLKOUT3_PHASE (CLKOUT3_PHASE),
.CLKOUT4_DIVIDE (CLKOUT4_DIVIDE),
.CLKOUT4_DUTY_CYCLE (CLKOUT4_DUTY_CYCLE),
.CLKOUT4_PHASE (CLKOUT4_PHASE),
.CLKOUT5_DIVIDE (CLKOUT5_DIVIDE),
.CLKOUT5_DUTY_CYCLE (CLKOUT5_DUTY_CYCLE),
.CLKOUT5_PHASE (CLKOUT5_PHASE),
.DIVCLK_DIVIDE (DIVCLK_DIVIDE),
.REF_JITTER1 (REF_JITTER1),
.STARTUP_WAIT (STARTUP_WAIT)
) PLLE2_BASE_i (
.CLKFBOUT (clkfbout), // output
.CLKOUT0 (clkout0), // output
.CLKOUT1 (clkout1), // output
.CLKOUT2 (clkout2), // output
.CLKOUT3 (clkout3), // output
.CLKOUT4 (clkout4), // output
.CLKOUT5 (clkout5), // output
.LOCKED (locked), // output
.CLKFBIN (clkfbin), // input
.CLKIN1 (clkin), // input
.PWRDWN (pwrdwn), // input
.RST (rst) // input
);
endmodule
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment