Cyclone V GT 5CGTFD9D5F27C7N PLL can not lock to 50 MHz oscillator
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