Difference between revisions of "Spartan 6 PLL ADV"
From Tech
Jump to navigationJump to search (Created page with "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-spa...") |
|||
| (4 intermediate revisions by the same user not shown) | |||
| 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 |
+ | 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 |
||
| + | |||
| + | [[File:PLL ADV-01-overview.png|Overview of simulation]] |
||
| + | [[File:PLL ADV-01-zoom.png|Zoom in of first few clk periods]] |
||
<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 18: | Line 29: | ||
--For dynamically changing DLL DCM values: |
--For dynamically changing DLL DCM values: |
||
-- http://hamsterworks.co.nz/mediawiki/index.php/FreqSwitch |
-- 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 |
entity main is |
||
port( |
port( |
||
| − | + | 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 34: | Line 45: | ||
signal reset: std_logic :='1'; |
signal reset: std_logic :='1'; |
||
signal resetCount: unsigned(2 downto 0):="000"; |
signal resetCount: unsigned(2 downto 0):="000"; |
||
| ⚫ | |||
begin |
begin |
||
| − | reset_process: process( |
+ | reset_process: process(clkin) |
begin |
begin |
||
| − | if |
+ | 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 51: | Line 61: | ||
generic map ( |
generic map ( |
||
BANDWIDTH => "OPTIMIZED", |
BANDWIDTH => "OPTIMIZED", |
||
| − | CLKFBOUT_MULT => |
+ | CLKFBOUT_MULT => 10, |
CLKFBOUT_PHASE => 0.0, |
CLKFBOUT_PHASE => 0.0, |
||
| − | CLKIN1_PERIOD => 10. |
+ | CLKIN1_PERIOD => 10.0, |
| − | CLKIN2_PERIOD => 10. |
+ | CLKIN2_PERIOD => 10.0, |
CLKOUT0_DIVIDE => 1, |
CLKOUT0_DIVIDE => 1, |
||
CLKOUT0_DUTY_CYCLE => 0.5, |
CLKOUT0_DUTY_CYCLE => 0.5, |
||
| Line 61: | Line 71: | ||
CLKOUT1_DUTY_CYCLE => 0.5, |
CLKOUT1_DUTY_CYCLE => 0.5, |
||
CLKOUT1_PHASE => 180.000000, |
CLKOUT1_PHASE => 180.000000, |
||
| − | CLKOUT2_DIVIDE => |
+ | CLKOUT2_DIVIDE => 5, |
CLKOUT2_DUTY_CYCLE => 0.5, |
CLKOUT2_DUTY_CYCLE => 0.5, |
||
CLKOUT2_PHASE => 0.000000, |
CLKOUT2_PHASE => 0.000000, |
||
| − | CLKOUT3_DIVIDE => |
+ | CLKOUT3_DIVIDE => 10, |
CLKOUT3_DUTY_CYCLE => 0.5, |
CLKOUT3_DUTY_CYCLE => 0.5, |
||
CLKOUT3_PHASE => 180.000000, |
CLKOUT3_PHASE => 180.000000, |
||
| Line 74: | Line 84: | ||
CLKOUT5_PHASE => 0.000000, |
CLKOUT5_PHASE => 0.000000, |
||
COMPENSATION => "SYSTEM_SYNCHRONOUS", |
COMPENSATION => "SYSTEM_SYNCHRONOUS", |
||
| − | DIVCLK_DIVIDE => |
+ | DIVCLK_DIVIDE => 2, |
EN_REL => false, |
EN_REL => false, |
||
PLL_PMCD_MODE => false, |
PLL_PMCD_MODE => false, |
||
| Line 90: | Line 100: | ||
port map ( |
port map ( |
||
CLKFBDCM => open, |
CLKFBDCM => open, |
||
| − | CLKFBOUT => |
+ | CLKFBOUT => feedback, |
CLKOUT0 => clkout_0, |
CLKOUT0 => clkout_0, |
||
CLKOUT1 => clkout_1, |
CLKOUT1 => clkout_1, |
||
| Line 106: | Line 116: | ||
DRDY => open, |
DRDY => open, |
||
LOCKED => open, |
LOCKED => open, |
||
| − | CLKFBIN => |
+ | CLKFBIN => feedback, |
| − | CLKIN1 => |
+ | CLKIN1 => clkin, |
| − | CLKIN2 => gnd, -- |
+ | 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 118: | Line 128: | ||
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> |
||
| ⚫ | |||
| − | -- |
||
| ⚫ | |||
| ⚫ | |||
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 : 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; |
||
| − | |||
| − | -- |
+ | --Input |
| − | signal |
+ | signal clkin : std_logic := '0'; |
| − | + | --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 |
+ | -- Clock period definition |
| − | constant |
+ | 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 => 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 180: | Line 175: | ||
clkin1_process :process |
clkin1_process :process |
||
begin |
begin |
||
| − | + | clkin <= '0'; |
|
| − | wait for |
+ | wait for clkin_period/2; |
| − | + | clkin <= '1'; |
|
| − | wait for |
+ | 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> |
||
Latest revision as of 19:47, 22 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
-- 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;

