Spartan 6 PLL ADV
From Tech
Jump to navigationJump to searchI 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
----------------------------------------------------------------------------------
--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;

