Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21335 Discussions

Cyclone V GT 5CGTFD9D5F27C7N PLL can not lock to 50 MHz oscillator

Vilius_Z
Beginner
231 Views

Hi,

I am an absolute beginner doing my baby steps in digital design with FPGAs, but I have some general electronics knowledge background. So excuse me for lack of common FPGA sense that someone might take for granted...

I am learning the VHDL and FPGA logic on a Terasic Cyclone V OpenVINO board. I have successfully wrote a led blink program using the embedded 50 MHz oscillator as a source. Now I want to step up  and experiment with clocks a little bit incorporating a PLL.

I have made a PLL setup using  Quartus IP catalog ,,PLL Intel FPGA IP" for integer PLL, stepping 50 MHz reference clock to 500 MHz, normal operation mode, locked clk output enabled. Datasheet of my chip says that 550 MHz maximum global clock is allowed, so at least at this point I am not violating anything...

Main problem is that when I add the generated PLL file component to my main vhdl file and replace the rising_edge(CLK) to rising_edge(pll_clk) led does not blink at all. After some research, I added additional logic to make a 3 second initial delay to give the PLL time to stabilize. Also added the 50 MHz oscillator and PLL clock synchronization process. 

You could think that my code got too complicated for such a simple task, but replacing  rising_edge(CLK) with rising_edge(pll_clk) or rising_edge(pll_clk_sync) still makes or breaks the deal in the latest code version that I provide down bellow. So at least I know the additional logic is not causing the decisive problem. 

Any ideas about this problem? Thank you in advance.

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

--Ctrl+Q to comment
--Ctrl+Shift+Q to uncomment

entity Logic is --Entity is like GPIO initialization
	port(
	 LED: OUT std_logic; --Output LED
	 CLK: IN std_logic --This will be mapped to 50 MHz clock
		);
end Logic; --or end entity

architecture example of Logic is --Architecture is like variable initialization

	--components are entities of another design files that could be used explicitly. Similar to includes in C
	--Signals are like logic variables, they can map components outputs to this exact design inputs.
	component PLL_0002 is
		port (
			refclk   : in  std_logic := 'X'; 
			outclk_0 : out std_logic;
			locked   : out std_logic -- PLL lock status			
		);
	end component PLL_0002;
	
	
 
	signal s_led:std_logic := '0';
	signal pll_clk: std_logic;
	signal pll_locked: std_logic;
	signal pll_clk_sync: std_logic := '0';
	signal pll_lock_delay_done: std_logic:= '0';
	
	begin
		
	-- Instantiate PLL
		pll_inst: PLL_0002
			port map (
				refclk   => CLK,
				outclk_0 => pll_clk,
				locked => pll_locked
					);
-----------------------------------------------------------------------------------					
	process(CLK)	
		variable delay_counter: unsigned(27 downto 0) := (others => '0');	
		begin
			 if rising_edge(CLK) then
				  if delay_counter = 150_000_000 then  -- 3 seconds (50 MHz * 3)
						delay_counter := (others => '0');  -- Reset counter
						pll_lock_delay_done <= '1';
				  else
						delay_counter := delay_counter + 1;  -- Increment counter
				  end if;
			 end if;
	end process;
-----------------------------------------------------------------------------------
	process(CLK) --Sync PLL clock with 50 MHz oscillator
		begin
			if rising_edge(CLK) then
				pll_clk_sync <= pll_clk;
			end if;
	end process;		
-----------------------------------------------------------------------------------			
	process(pll_clk_sync) --Toggle led from PLL clock
		variable counter: unsigned(26 downto 0) := (others => '0');
		 begin
		 if rising_edge(CLK) then
			  if pll_locked = '1' and pll_lock_delay_done = '1' then
					if counter = 125_000_000 then
						 counter := (others => '0'); -- Reset counter
						 s_led <= not s_led; -- Toggle LED
					else
						 counter := counter + 1;
					end if;
			  end if;
		 end if;
	 end process;
------------------------------------------------------------------------------------	 
    LED <= s_led; -- Output LED state

end architecture; --or end Logic

 



0 Kudos
3 Replies
sstrell
Honored Contributor III
192 Views

Your sensitivity lists are pointing to CLK instead of pll_clk.  Should be

process (pll_clk)

and then use rising_edge(pll_clk)

 

0 Kudos
lixy
Employee
162 Views

Hi,

I could not understand what you would like to implement with this part of your code.

 

process(CLK) --Sync PLL clock with 50 MHz oscillator

begin

if rising_edge(CLK) then

pll_clk_sync <= pll_clk;

end if;

end process;

 

From here, it looks like you are trying to sample pll_clk (500MHz) with a slower clock CLK (50MHz).

From an example below, if there's phase shift between two clocks, because the frequency of the pll_clk is 10 times that of the CLK, you can see that at every rising edge of CLK, the value of pll_clk is always the same, which means the pll_clk_sync won't change.

lixy_1-1740133123607.png

Another example below is when the phase difference between two clocks precisely aligns their rising/falling edges, at every rising edge of CLK, the pll_clk is also at an edge, so that the sampling value for pll_clk_sync could be an uncertain value. This is a big risk.

lixy_0-1740133107538.png

 

Best Regards,

Xiaoyan

 

0 Kudos
Vilius_Z
Beginner
109 Views

I was trying to synchronize the PLL clock with my 50 MHz oscillator clock, but at some point I understood that it was completely wrong and unnecessary. Anyway, first advise to change process sensitivity list solved my problem. Thank you for your help.

0 Kudos
Reply