Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
17 years ago

Can a PLL be implemented in a CPLD

Hi,

I would like to use an external VCXO and I guess amplifier/filter to sync a 10MHz clk to a GPS 1 HZ signal. Can anyone suggest if this is possible and if so where would I start looking for information.

Cheers.

7 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Basically, you have to design the PLL according to your requirements. A CPLD can make the digital part of it. Because of the huge frequency ratio, I guess that a digital PLL, using a Sigma-Delta DAC to control the VCXO may be meaningful, particularly if your intending low phase noise.

    It's mainly a matter of good system design, the type of utilized digital logic is of secondary importance to my opinion. And it's almost clear, that the PLL components present in most FPGA are of no use for this application.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Not long ago I designed a phase comparator in stratix II for an external PLL. The phase comparator sends charge pump pulses(of different duty cycles) and it worked. This phase comparator is certainly implementable in CPLD

    My clocks were not that far apart but you can get a counter to divide yours.

    If you are interested in this phase comparator I can post the design
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi FvM,

    Thanks for the reply,

    My maths level is just short of Laplace and Fourier but I'm learning.

    --- Quote Start ---

    It's mainly a matter of good system design, the type of utilized digital logic is of secondary importance to my opinion. And it's almost clear, that the PLL components present in most FPGA are of no use for this application.

    --- Quote End ---

    Can you recommend a reference for good PLL system design??
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Kaz,

    Thanks , that would be good. I assume you used an RC filter to integrate? /average the pulses.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    My design of the phase comparator is based on this basic idea:

    clk1 sets a flipflop to ‘1’ at its edge.

    clk2 sets another flipflop to ‘1’ at its edge

    both flipflops are then reset asynchronously by their ANDed output (after some delay).

    Thus the duration of each Q pulse will indicate the distance between edges of the two clks.

    In practice you don’t need to check each and every clk edge as this may be excessive leading to a swing effect, you can choose how often by using counters. These counters will also help detect the lock state.The value of counters is implementation dependant according to clk ratio and your low pass filter..

    In my case the ratio was 2 and I used two counters:

    0 ~ 7 on fast clk

    0 ~ 3 on slow clk

    cp_p & cp_n are the Q outputs of flipflops and used for the charge pump. (Adjust it’s sense as required).

    cp_p_d & cp_n_d are the delayed version for reset(I used wiring to bidirectional IO and back)

    Rememebr to use fast io registers for Q outputs

    your clk ratio is too high and you may need to play around for best counting and filter cutoff

    The following code section may help

    ------------------------------------------------------------------------------------------------------------

    process -- counter on clk1

    begin

    wait until clk1 = ‘1’

    clk1_cnt <= clk1_cnt + 1;

    end process;

    process -- counter on clk2

    begin

    wait until clk2 = ‘1’

    clk2_cnt <= clk2_cnt + 1;

    end process;

    process (clk1, clr) -- clk1 flip-flop

    begin

    if (clr = '1') then

    cp_n <= '0';

    elsif rising_edge (clk1) then

    if (clk1_cnt = 7) then

    cp_n <= '1';

    end if;

    end if;

    end process;

    process (clk2, clr) -- clk2 flip-flop

    begin

    if (clr = '1') then

    cp_p <= '0';

    elsif rising_edge (clk2) then

    if (clk2_cnt = 3) then

    cp_p <= '1';

    end if;

    end if;

    end process;

    -- reset when both outputs are high

    clr <= cp_p_d and cp_n_d;

    -- PLL lock detector

    process

    begin

    wait until clk1 = ‘1’;

    if (clk2_cnt = 3) then

    if (clk1_cnt = 7) or (clk1_cnt = 0) then

    locked <= '1';

    else

    locked <= '0';

    end if;

    end if;

    end process ;

    -----------------------------------

    good luck
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    Not being a VHDL expert, does the following look accurate to you.

    use library ieee;

    use ieee.std_logic_1164.all;

    use ieee.std_logic_unsigned.all;

    -----------------------------------------

    entity PhaseDetector is

    port(

    clk1 : in STD_LOGIC;

    clk2 : in STD_LOGIC;

    cp_n_d : in STD_LOGIC;-- delayed??

    cp_p_d : in STD_LOGIC;-- delayed??

    cp_n : inout STD_LOGIC;

    cp_p : inout STD_LOGIC;

    locked : out STD_LOGIC

    );

    end PhaseDetector;

    architecture behav of PhaseDetector is

    signal clr : STD_LOGIC ;

    signal clk1_cnt: integer range 0 to 255; -- clk1 counter

    signal clk2_cnt: integer range 0 to 7; -- clk2 counter

    begin

    process -- counter on clk1

    begin

    wait until clk1 = '1';-- clk1 is VCXO signal

    clk1_cnt <= clk1_cnt + 1;

    end process;

    process -- counter on clk2

    begin

    wait until clk2 = '1'; -- clk2 is PPS signal

    clk2_cnt <= clk2_cnt + 1;

    end process;

    process (clk1,clr) -- clk1 flip-flop

    begin

    if (clr = '1') then

    cp_n <= '0';

    elsif rising_edge (clk1) then

    if (clk1_cnt = 7) then -- adjustment value

    cp_n <= '1';

    end if;

    end if;

    end process;

    process (clk2,clr) -- clk2 flip-flop

    begin

    if (clr = '1') then

    cp_p <= '0';

    elsif rising_edge (clk2) then

    if (clk2_cnt = 3) then -- adjustment value

    cp_p <= '1';

    end if;

    end if;

    end process;

    -- reset when both outputs are high

    clr <= cp_p and cp_n;

    -- PLL lock detector

    process

    begin

    if (clk2_cnt = 3) then

    if (clk1_cnt = 7) or (clk1_cnt = 0) then

    locked <= '1';

    else

    locked <= '0';

    end if;

    end if;

    end process ;

    end behav;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    There are two issues here, one related to actual design and the other related to vhdl

    1) your fast clk is 10MHz, slow is 1Hz. So without doubt your ratio is very high. You need to look at edge of clk1Hz and compare it with clk10MHz only when both edges are expected to lock. i.e. if slow counter is 0~3 then fast counter will be 0~(2^26-1).

    So only when reaching maximum counts you need to drive the relevant flipflops.(max count = 3 or 40 million-1)

    Clearly the design will take 4 sec per test so you expect the lock to take few seconds, unless you have means of multiplying clk1Hz(FPGA PLL can do that).

    2) The code:

    you can reduce the ports to:

    port(

    clk1 : in STD_LOGIC;

    clk2 : in STD_LOGIC;

    cp_n : inout STD_LOGIC;

    cp_p : inout STD_LOGIC;

    locked : out STD_LOGIC

    );

    you declare the delay nodes internally and you must drive them then use them in the AND statement.

    cp_n_d <= cp_n;

    cp_p_d <= cp_p;

    clr <= cp_n_d and cp_p_d;

    your flipflop drive is ok except for count values. So is the detection logic;

    Always check at the extremes of your counters(not my counters)

    Good luck