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;