- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your sensitivity lists are pointing to CLK instead of pll_clk. Should be
process (pll_clk)
and then use rising_edge(pll_clk)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.
Best Regards,
Xiaoyan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page