You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
4.0 KiB
VHDL
117 lines
4.0 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
|
|
Library UNISIM;
|
|
use UNISIM.vcomponents.all;
|
|
|
|
entity clock_generator is
|
|
generic (
|
|
CLK_INPUT_HZ : positive := 12000000;
|
|
CLK_OUTPUT_HZ : positive := 50000000
|
|
);
|
|
port (
|
|
ext_clk : in std_logic;
|
|
pll_rst_in : in std_logic;
|
|
pll_clk_out : out std_logic;
|
|
pll_locked_out : out std_logic);
|
|
end entity clock_generator;
|
|
|
|
architecture rtl of clock_generator is
|
|
signal clkfb : std_ulogic;
|
|
|
|
type pll_settings_t is record
|
|
clkin_period : real range 10.000 to 800.0;
|
|
clkfbout_mult : real range 2.0 to 64.0;
|
|
clkout_divide : real range 1.0 to 128.0;
|
|
divclk_divide : integer range 1 to 106;
|
|
force_rst : std_ulogic;
|
|
end record;
|
|
|
|
function gen_pll_settings (
|
|
constant input_hz : positive;
|
|
constant output_hz : positive)
|
|
return pll_settings_t is
|
|
|
|
constant bad_settings : pll_settings_t :=
|
|
(clkin_period => 0.0,
|
|
clkfbout_mult => 2.0,
|
|
clkout_divide => 1.0,
|
|
divclk_divide => 1,
|
|
force_rst => '1');
|
|
begin
|
|
case input_hz is
|
|
when 100000000 =>
|
|
case output_hz is
|
|
when 100000000 =>
|
|
return (clkin_period => 10.0,
|
|
clkfbout_mult => 16.0,
|
|
clkout_divide => 16.0,
|
|
divclk_divide => 1,
|
|
force_rst => '0');
|
|
when 50000000 =>
|
|
return (clkin_period => 10.0,
|
|
clkfbout_mult => 16.0,
|
|
clkout_divide => 32.0,
|
|
divclk_divide => 1,
|
|
force_rst => '0');
|
|
when others =>
|
|
report "Unsupported output frequency" severity failure;
|
|
return bad_settings;
|
|
end case;
|
|
when 12000000 =>
|
|
case output_hz is
|
|
when 100000000 =>
|
|
return (clkin_period => 83.33,
|
|
clkfbout_mult => 50.0,
|
|
clkout_divide => 6.0,
|
|
divclk_divide => 1,
|
|
force_rst => '0');
|
|
when 50000000 =>
|
|
return (clkin_period => 83.33,
|
|
clkfbout_mult => 50.0,
|
|
clkout_divide => 12.0,
|
|
divclk_divide => 1,
|
|
force_rst => '0');
|
|
when others =>
|
|
report "Unsupported output frequency" severity failure;
|
|
return bad_settings;
|
|
end case;
|
|
when others =>
|
|
report "Unsupported input frequency" severity failure;
|
|
return bad_settings;
|
|
end case;
|
|
end function gen_pll_settings;
|
|
|
|
constant pll_settings : pll_settings_t := gen_pll_settings(clk_input_hz,
|
|
clk_output_hz);
|
|
begin
|
|
pll : MMCME2_BASE
|
|
generic map (
|
|
BANDWIDTH => "OPTIMIZED",
|
|
CLKFBOUT_MULT_F => pll_settings.clkfbout_mult,
|
|
CLKIN1_PERIOD => pll_settings.clkin_period,
|
|
CLKOUT0_DIVIDE_F => pll_settings.clkout_divide,
|
|
DIVCLK_DIVIDE => pll_settings.divclk_divide,
|
|
STARTUP_WAIT => FALSE)
|
|
port map (
|
|
CLKFBOUT => clkfb,
|
|
CLKFBOUTB => open,
|
|
CLKOUT0 => pll_clk_out,
|
|
CLKOUT0B => open,
|
|
CLKOUT1 => open,
|
|
CLKOUT1B => open,
|
|
CLKOUT2 => open,
|
|
CLKOUT2B => open,
|
|
CLKOUT3 => open,
|
|
CLKOUT3B => open,
|
|
CLKOUT4 => open,
|
|
CLKOUT5 => open,
|
|
CLKOUT6 => open,
|
|
LOCKED => pll_locked_out,
|
|
CLKFBIN => clkfb,
|
|
CLKIN1 => ext_clk,
|
|
PWRDWN => '0',
|
|
RST => pll_rst_in or pll_settings.force_rst
|
|
);
|
|
end architecture rtl;
|