PLL frequency doubling but shouldn't - PLL frequency doubling but shouldn't
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!
Replies:
Re: PLL frequency doubling but shouldn't
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.
Replies:
Re: PLL frequency doubling but shouldn't
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.
Replies:
Re: PLL frequency doubling but shouldn't
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;
Replies:
Re: PLL frequency doubling but shouldn't
Hi, Can you please attach the piece of code showing connections from differential input pins to the PLL output? Regards - 2021-03-10
external_document