Spartan 6 PLL ADV

From Tech
Jump to navigationJump to search

I couldn't find working sample VHDL files on how to make the PLL_ADV in Spartan 6 work. All I could find was this blog post, but that didn't simulate with CLKFBIN set to GND. So here is an instantiation (mostly copied from the link above) that:

  • sets CLKFEEDBACK=CLKFBOUT
  • from the 100MHz CLKIN, generates 500 and 50 MHZ CLKOUT

It does this by:

  • First, devides CLKIN by DIVCLK_DIVIDE=2, to generate 50MHz
  • Using CLKFBOUT_MULT=10, the VCO frequency becomes 50*10=500MHz
  • With CLKOUT0DIVIDE=1, the CLKOUT0 frequency is 500/1=500MHz
  • With CLKOUT1DIVIDE=1, the CLKOUT1 frequency is 500/10=500MHz

Overview of simulation Zoom in of first few clk periods

----------------------------------------------------------------------------------
--Copied from http://permalink.gmane.org/gmane.comp.hardware.opencores.leon-sparc/15037
--by Joost Witteveen
--
--Minimal PLL_ADV VHDL files (only simulation tested. Does it work in real too?)
--
----------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library UNISIM;
use UNISIM.VComponents.all;

--For dynamically changing DLL DCM values:
-- http://hamsterworks.co.nz/mediawiki/index.php/FreqSwitch

-- http://www.xilinx.com/support/documentation/application_notes/xapp879.pdf
-- http://www.xilinx.com/support/documentation/application_notes/xapp879.zip

entity main is
  port(
    clkin: in std_logic;
    clkout_0: out std_logic;
    clkout_1: out std_logic;
    clkout_2: out std_logic);
end main;

architecture Behavioral of main is
  signal gnd : std_logic :='0';
  signal reset: std_logic :='1';
  signal resetCount: unsigned(2 downto 0):="000";
  signal feedback: std_logic;
begin
 reset_process: process(clkin)
 begin
   if clkin'event and clkin='1' then
     if resetCount<5 then
       resetCount<=resetCount+1;
       reset<='1';
     else
       reset<='0'; --Reset goes low after 5 clock pulses (50ns)
     end if;
   end if;
 end process;
 PLL_ADV_inst : PLL_ADV
      generic map (
        BANDWIDTH             => "OPTIMIZED",
        CLKFBOUT_MULT         => 10,
        CLKFBOUT_PHASE        => 0.0,
        CLKIN1_PERIOD         => 10.0,
        CLKIN2_PERIOD         => 10.0,
        CLKOUT0_DIVIDE        => 1,
        CLKOUT0_DUTY_CYCLE    => 0.5,
        CLKOUT0_PHASE         => 0.000000,
        CLKOUT1_DIVIDE        => 1,
        CLKOUT1_DUTY_CYCLE    => 0.5,
        CLKOUT1_PHASE         => 180.000000,
        CLKOUT2_DIVIDE        => 5,
        CLKOUT2_DUTY_CYCLE    => 0.5,
        CLKOUT2_PHASE         => 0.000000,
        CLKOUT3_DIVIDE        => 10,
        CLKOUT3_DUTY_CYCLE    => 0.5,
        CLKOUT3_PHASE         => 180.000000,
        CLKOUT4_DIVIDE        => 1,
        CLKOUT4_DUTY_CYCLE    => 0.5,
        CLKOUT4_PHASE         => 0.000000,
        CLKOUT5_DIVIDE        => 1,
        CLKOUT5_DUTY_CYCLE    => 0.5,
        CLKOUT5_PHASE         => 0.000000,
        COMPENSATION          => "SYSTEM_SYNCHRONOUS",
        DIVCLK_DIVIDE         => 2,
        EN_REL                => false,
        PLL_PMCD_MODE         => false,
        REF_JITTER            => 0.100,
        RESET_ON_LOSS_OF_LOCK => false,
        RST_DEASSERT_CLK      => "CLKIN1",
        CLKOUT0_DESKEW_ADJUST => "NONE",
        CLKOUT1_DESKEW_ADJUST => "NONE",
        CLKOUT2_DESKEW_ADJUST => "NONE",
        CLKOUT3_DESKEW_ADJUST => "NONE",
        CLKOUT4_DESKEW_ADJUST => "PPC",
        CLKOUT5_DESKEW_ADJUST => "PPC",
        CLKFBOUT_DESKEW_ADJUST => "PPC"
        )
      port map (
        CLKFBDCM              => open,
        CLKFBOUT              => feedback,
        CLKOUT0               => clkout_0,
        CLKOUT1               => clkout_1,
        CLKOUT2               => clkout_2,
        CLKOUT3               => open,
        CLKOUT4               => open,
        CLKOUT5               => open,
        CLKOUTDCM0            => open,
        CLKOUTDCM1            => open,
        CLKOUTDCM2            => open,
        CLKOUTDCM3            => open,
        CLKOUTDCM4            => open,
        CLKOUTDCM5            => open,
        DO                    => open,
        DRDY                  => open,
        LOCKED                => open,
        CLKFBIN               => feedback,
        CLKIN1                => clkin,
        CLKIN2                => gnd, --clkin, 
        CLKINSEL              => '1', -- 1 selects CLKIN1, and 0 selects CLKIN2
        DADDR                 => "00000",
        DCLK                  => '0',
        DEN                   => '0',
        DI                    => "0000000000000000",
        DWE                   => '0',
        REL                   => '0',
        RST                   => reset    -- Asynchronous PLL reset
        );
end Behavioral;



With the following test bench:

--------------------------------------------------------------------------------
-- VHDL Test Bench (mostly) Created by ISE for module: main

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

ENTITY tb IS
END tb;
 
ARCHITECTURE behavior OF tb IS 
    COMPONENT main
    PORT(
         clkin : IN  std_logic;                
         clkout_0 : OUT  std_logic;
         clkout_1 : OUT  std_logic;
         clkout_2 : OUT  std_logic);
    END COMPONENT;

   --Input
   signal clkin : std_logic := '0';

   --Outputs
   signal clkout_0 : std_logic;
   signal clkout_1 : std_logic;
   signal clkout_2 : std_logic;

   -- Clock period definition
   constant clkin_period : time := 10 ns; --100MHz CLKIN

BEGIN
   uut: main PORT MAP (
          clkin => clkin,
          clkout_0 => clkout_0,
          clkout_1 => clkout_1,
          clkout_2 => clkout_2
        );

   -- Clock process definitions
   clkin1_process :process
   begin
		clkin <= '0';
		wait for clkin_period/2;
		clkin <= '1';
		wait for clkin_period/2;
   end process;

   stim_proc: process
   begin		
      wait;
   end process;
END;