Difference between revisions of "Spartan 6 PLL ADV"

From Tech
Jump to navigationJump to search
Line 1: Line 1:
 
I couldn't find working sample VHDL files on how to make the PLL_ADV in Spartan 6 work.
 
I couldn't find working sample VHDL files on how to make the PLL_ADV in Spartan 6 work.
 
All I could find was [http://permalink.gmane.org/gmane.comp.hardware.opencores.leon-sparc/15037 this blog post], but that
 
All I could find was [http://permalink.gmane.org/gmane.comp.hardware.opencores.leon-sparc/15037 this blog post], but that
didn't simulate with CLKFBIN set to GND. So here is a copy that at least simulats for me:
+
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
  +
 
<nowiki>----------------------------------------------------------------------------------
 
<nowiki>----------------------------------------------------------------------------------
 
--Copied from http://permalink.gmane.org/gmane.comp.hardware.opencores.leon-sparc/15037
 
--Copied from http://permalink.gmane.org/gmane.comp.hardware.opencores.leon-sparc/15037
Line 20: Line 29:
 
entity main is
 
entity main is
 
port(
 
port(
clkin_1: in std_logic;
+
clkin: in std_logic;
 
clkout_0: out std_logic;
 
clkout_0: out std_logic;
 
clkout_1: out std_logic;
 
clkout_1: out std_logic;
clkout_2: out std_logic;
+
clkout_2: out std_logic);
sigout: out std_logic
 
);
 
 
 
end main;
 
end main;
   
Line 33: Line 39:
 
signal reset: std_logic :='1';
 
signal reset: std_logic :='1';
 
signal resetCount: unsigned(2 downto 0):="000";
 
signal resetCount: unsigned(2 downto 0):="000";
 
signal feedback: std_logic;
 
begin
 
begin
reset_process: process(clkin_1)
+
reset_process: process(clkin)
 
begin
 
begin
if clkin_1'event and clkin_1='1' then
+
if clkin'event and clkin='1' then
 
if resetCount<5 then
 
if resetCount<5 then
 
resetCount<=resetCount+1;
 
resetCount<=resetCount+1;
sigout<='1';
 
 
reset<='1';
 
reset<='1';
 
else
 
else
reset<='0';
+
reset<='0'; --Reset goes low after 5 clock pulses (50ns)
sigout<='0';
 
 
end if;
 
end if;
 
end if;
 
end if;
Line 50: Line 55:
 
generic map (
 
generic map (
 
BANDWIDTH => "OPTIMIZED",
 
BANDWIDTH => "OPTIMIZED",
CLKFBOUT_MULT => 4,
+
CLKFBOUT_MULT => 10,
 
CLKFBOUT_PHASE => 0.0,
 
CLKFBOUT_PHASE => 0.0,
 
CLKIN1_PERIOD => 10.1,
 
CLKIN1_PERIOD => 10.1,
Line 60: Line 65:
 
CLKOUT1_DUTY_CYCLE => 0.5,
 
CLKOUT1_DUTY_CYCLE => 0.5,
 
CLKOUT1_PHASE => 180.000000,
 
CLKOUT1_PHASE => 180.000000,
CLKOUT2_DIVIDE => 4,
+
CLKOUT2_DIVIDE => 5,
 
CLKOUT2_DUTY_CYCLE => 0.5,
 
CLKOUT2_DUTY_CYCLE => 0.5,
 
CLKOUT2_PHASE => 0.000000,
 
CLKOUT2_PHASE => 0.000000,
CLKOUT3_DIVIDE => 4,
+
CLKOUT3_DIVIDE => 10,
 
CLKOUT3_DUTY_CYCLE => 0.5,
 
CLKOUT3_DUTY_CYCLE => 0.5,
 
CLKOUT3_PHASE => 180.000000,
 
CLKOUT3_PHASE => 180.000000,
Line 73: Line 78:
 
CLKOUT5_PHASE => 0.000000,
 
CLKOUT5_PHASE => 0.000000,
 
COMPENSATION => "SYSTEM_SYNCHRONOUS",
 
COMPENSATION => "SYSTEM_SYNCHRONOUS",
DIVCLK_DIVIDE => 1,
+
DIVCLK_DIVIDE => 2,
 
EN_REL => false,
 
EN_REL => false,
 
PLL_PMCD_MODE => false,
 
PLL_PMCD_MODE => false,
Line 89: Line 94:
 
port map (
 
port map (
 
CLKFBDCM => open,
 
CLKFBDCM => open,
CLKFBOUT => open,
+
CLKFBOUT => feedback,
 
CLKOUT0 => clkout_0,
 
CLKOUT0 => clkout_0,
 
CLKOUT1 => clkout_1,
 
CLKOUT1 => clkout_1,
Line 105: Line 110:
 
DRDY => open,
 
DRDY => open,
 
LOCKED => open,
 
LOCKED => open,
CLKFBIN => clkin_1,
+
CLKFBIN => feedback,
CLKIN1 => clkin_1,
+
CLKIN1 => clkin,
CLKIN2 => gnd, --clkin_1,
+
CLKIN2 => gnd, --clkin,
 
CLKINSEL => '1', -- 1 selects CLKIN1, and 0 selects CLKIN2
 
CLKINSEL => '1', -- 1 selects CLKIN1, and 0 selects CLKIN2
 
DADDR => "00000",
 
DADDR => "00000",
Line 117: Line 122:
 
RST => reset -- Asynchronous PLL reset
 
RST => reset -- Asynchronous PLL reset
 
);
 
);
 
 
end Behavioral;
 
end Behavioral;
  +
  +
 
</nowiki>
 
</nowiki>
   
 
With the following test bench:
 
With the following test bench:
   
 
<nowiki>--------------------------------------------------------------------------------
<nowiki>
 
 
-- VHDL Test Bench (mostly) Created by ISE for module: main
--
 
-- VHDL Test Bench Created by ISE for module: main
 
   
--------------------------------------------------------------------------------
 
 
LIBRARY ieee;
 
LIBRARY ieee;
 
USE ieee.std_logic_1164.ALL;
 
USE ieee.std_logic_1164.ALL;
  +
 
-- Uncomment the following library declaration if using
 
-- arithmetic functions with Signed or Unsigned values
 
--USE ieee.numeric_std.ALL;
 
 
 
ENTITY tb IS
 
ENTITY tb IS
 
END tb;
 
END tb;
 
 
 
ARCHITECTURE behavior OF tb IS
 
ARCHITECTURE behavior OF tb IS
 
-- Component Declaration for the Unit Under Test (UUT)
 
 
 
COMPONENT main
 
COMPONENT main
 
PORT(
 
PORT(
clkin_1 : IN std_logic;
+
clkin : IN std_logic;
 
clkout_0 : OUT std_logic;
 
clkout_0 : OUT std_logic;
 
clkout_1 : OUT std_logic;
 
clkout_1 : OUT std_logic;
clkout_2 : OUT std_logic;
+
clkout_2 : OUT std_logic);
sigout : OUT std_logic
 
);
 
 
END COMPONENT;
 
END COMPONENT;
 
   
--Inputs
+
--Input
signal clkin_1 : std_logic := '0';
+
signal clkin : std_logic := '0';
   
--Outputs
+
--Outputs
 
signal clkout_0 : std_logic;
 
signal clkout_0 : std_logic;
 
signal clkout_1 : std_logic;
 
signal clkout_1 : std_logic;
 
signal clkout_2 : std_logic;
 
signal clkout_2 : std_logic;
signal sigout : std_logic;
 
   
-- Clock period definitions
+
-- Clock period definition
constant clkin1_period : time := 10 ns;
+
constant clkin_period : time := 10 ns; --100MHz CLKIN
   
 
BEGIN
 
BEGIN
 
-- Instantiate the Unit Under Test (UUT)
 
 
uut: main PORT MAP (
 
uut: main PORT MAP (
clkin_1 => clkin_1,
+
clkin => clkin,
 
clkout_0 => clkout_0,
 
clkout_0 => clkout_0,
 
clkout_1 => clkout_1,
 
clkout_1 => clkout_1,
clkout_2 => clkout_2,
+
clkout_2 => clkout_2
sigout => sigout
 
 
);
 
);
   
Line 179: Line 169:
 
clkin1_process :process
 
clkin1_process :process
 
begin
 
begin
clkin_1 <= '0';
+
clkin <= '0';
wait for clkin1_period/2;
+
wait for clkin_period/2;
clkin_1 <= '1';
+
clkin <= '1';
wait for clkin1_period/2;
+
wait for clkin_period/2;
 
end process;
 
end process;
   
 
stim_proc: process
 
stim_proc: process
 
begin
 
begin
wait for 100 ns;
 
 
wait;
 
wait;
 
end process;
 
end process;
 
 
END;
 
END;
 
</nowiki>
 
</nowiki>

Revision as of 22:27, 12 February 2014

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
----------------------------------------------------------------------------------
--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
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.1,
        CLKIN2_PERIOD         => 10.1,
        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;