- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey!
I'm using a PLL on Cyclone 10 LP to create a clock with the same frequency, but shifting the phase. The PLL works fine in simulation when I create a clock and feed it straight into the PLL. However, I need to have it working with a differential clock. So, I'm simulating a differential clock and feeding it through the differential input buffer (ALTIOBUF). Now for some reason the PLL doubles the clock's frequency. Image shown below. Is this an error with Modelsim, or how could I solve this issue?
I'd presume this issue arises due to the signal being undefined when they cross?
Thanks in advance!
- Tags:
- pll
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Joossss,
Thanks for your code!
I was able to reproduce the issue that you mentioned.
In the screen shot that you had shared, the output of the LVDS_CLK_inst (buffer) is not clean. There are some red lines ('X') on the buffer output. Same happened in my code as well (see signal /top_tb/dut/clk_in) . Result was that the PLL output was double the input clock.
Then in the test bench, instead of using the procedure clk_gen, I drove the differential clock inputs using simple process.
SIGNAL clk_in_p : STD_LOGIC := '1';
SIGNAL clk_in_n : STD_LOGIC := '0';
PROCESS
BEGIN
clk_in_p <= not clk_in_p;
clk_in_n <= not clk_in_n;
WAIT FOR 6.6666 ns;
END PROCESS;
With this the buffer output was clean and the PLL generated the output as expected. See the screen shot.
May be due to the 'procedure' there is an delta delay added to the input signals and they are not phase aligned to each other, so the buffer output is not clean.
That impacted the PLL output as well.
Regards.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Can you please attach the piece of code showing connections from differential input pins to the PLL output?
Regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yeah sure.
The VHDL code:
ntity PLL_TEST is
Port (LVDS_Clk_p, LVDS_Clk_n : in std_logic_vector(0 downto 0);
clk : in std_logic;
step, updown : in std_logic; -- step must be applied for atleast two cycles.
cntsel : in std_logic_vector(2 downto 0) -- "000" all counters, "001" M counter?, "010" c0 ... "110" c4
--data : out std_logic_vector(15 downto 0)
);
end PLL_TEST;
architecture rtl of PLL_TEST is
component IOBUF_Differential_1
port(
datain : in std_logic_Vector(0 downto 0);
datain_b : in std_logic_vector(0 downto 0);
dataout : out std_logic_vector(0 downto 0)
);
end component IOBUF_Differential_1;
component PLL
port(
areset : in std_logic;
inclk0 : in std_logic;
phasecounterselect : in std_logic_vector(2 downto 0);
phasestep : in std_logic;
phaseupdown : in std_logic;
scanclk : in std_logic;
c0 : out std_logic;
locked : out std_logic;
phasedone : out std_logic
);
end component PLL;
signal pll_clk : std_logic;
signal pll_lock : std_logic;
signal rst : std_logic := '0';
signal pll_phasedone : std_logic;
signal LVDS_Clk : std_logic_vector(0 downto 0);
begin
LVDS_CLK_inst : IOBUF_Differential_1 PORT MAP(
datain => LVDS_Clk_P,
datain_b => LVDS_Clk_N,
dataout => LVDS_Clk
);
PLL_CLK_inst : PLL PORT MAP (
areset => rst,
inclk0 => lvds_clk(0),
phasecounterselect => cntsel,
phasestep => step,
phaseupdown => updown,
scanclk => clk,
c0 => pll_clk,
locked => pll_lock,
phasedone => pll_phasedone
);
end rtl;
And just in case the TB code as well:
architecture TB of PLL_TEST_TB is
signal clk_50 : std_logic := '1';
signal lvds_clk_p, lvds_clk_n : std_logic_vector(0 downto 0) := "1";
signal step, updown : std_logic := '0';
signal cntsel : std_logic_vector (2 downto 0) := "010";
-- Procedure for clock generation
procedure clk_gen(signal clk : out std_logic; constant FREQ : real; constant DELAY : real) is
constant PERIOD : time := 1 sec / FREQ; -- Full period
constant HIGH_TIME : time := PERIOD / 2; -- High time
constant LOW_TIME : time := PERIOD - HIGH_TIME; -- Low time; always >= HIGH_TIME
constant DELAYE : time := DELAY * 1 ns;
begin
-- Check the arguments
assert (HIGH_TIME /= 0 fs) report "clk_plain: High time is zero; time resolution to large for frequency" severity FAILURE;
-- Generate a clock cycle
wait for DELAYE;
loop
clk <= '1';
wait for HIGH_TIME;
clk <= '0';
wait for LOW_TIME;
end loop;
end procedure;
begin
-- Clock generation with concurrent procedure call
clk_gen(clk_50, 50.0e6, 0.0e0);
clk_gen(lvds_clk_p(0), 150.0e6, 0.0e0);
clk_gen(lvds_clk_n(0), 150.0e6, 0.0e0);
--Instantiante UUT
UUT: entity work.PLL_TEST
port map(
lvds_clk_p => lvds_clk_p,
lvds_clk_n => lvds_clk_n,
clk => clk_50,
step => step,
updown => updown,
cntsel => cntsel
);
Testing : process is
begin
wait for 30 ns;
wait until rising_edge(clk_50);
updown <= '1';
wait until rising_edge(clk_50);
step <= '1';
wait until rising_edge(clk_50);
wait until rising_edge(clk_50);
step <= '0';
wait until rising_edge(clk_50);
step <= '1';
wait until rising_edge(clk_50);
wait until rising_edge(clk_50);
step <= '0';
wait until rising_edge(clk_50);
step <= '1';
wait until rising_edge(clk_50);
wait until rising_edge(clk_50);
step <= '0';
wait until rising_edge(clk_50);
updown <= '0';
wait for 100 ns;
assert false report "Test Complete" severity failure;
end process Testing;
end architecture TB;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Joossss,
Thanks for your code!
I was able to reproduce the issue that you mentioned.
In the screen shot that you had shared, the output of the LVDS_CLK_inst (buffer) is not clean. There are some red lines ('X') on the buffer output. Same happened in my code as well (see signal /top_tb/dut/clk_in) . Result was that the PLL output was double the input clock.
Then in the test bench, instead of using the procedure clk_gen, I drove the differential clock inputs using simple process.
SIGNAL clk_in_p : STD_LOGIC := '1';
SIGNAL clk_in_n : STD_LOGIC := '0';
PROCESS
BEGIN
clk_in_p <= not clk_in_p;
clk_in_n <= not clk_in_n;
WAIT FOR 6.6666 ns;
END PROCESS;
With this the buffer output was clean and the PLL generated the output as expected. See the screen shot.
May be due to the 'procedure' there is an delta delay added to the input signals and they are not phase aligned to each other, so the buffer output is not clean.
That impacted the PLL output as well.
Regards.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey!
Thanks this works indeed, I only tried to use this process, because I tried to solve the same issue with it, by introducing delays into one of the lines, because before this I used
lvds_clk_p <= not lvds_clk_p after 3.3 ns;
lvds_clk_n <= not lvds_clk_p; -- 150 MHz
and this also didn't work.
Anyway, thanks for solving the issue.

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