@ -5,67 +5,89 @@ Library UNISIM;
use UNISIM.vcomponents.all;
use UNISIM.vcomponents.all;
entity clock_generator is
entity clock_generator is
generic (
generic (
clk_period_hz : positive := 100000000);
CLK_INPUT_HZ : positive := 100000000;
port (
CLK_OUTPUT_HZ : positive := 100000000
ext_clk : in std_logic;
);
pll_rst_in : in std_logic;
port (
pll_clk_out : out std_logic;
ext_clk : in std_logic;
pll_locked_out : out std_logic);
pll_rst_in : in std_logic;
pll_clk_out : out std_logic;
pll_locked_out : out std_logic);
end entity clock_generator;
end entity clock_generator;
architecture rtl of clock_generator is
architecture rtl of clock_generator is
signal clkfb : std_ulogic;
signal clkfb : std_ulogic;
type pll_settings_t is record
clkin_period : real range 0.000 to 52.631;
clkfbout_mult : integer range 2 to 64;
clkout_divide : integer range 1 to 128;
divclk_divide : integer range 1 to 56;
force_rst : std_ulogic;
end record;
type pll_settings_t is record
function gen_pll_settings (
clkin_period : real range 0.000 to 52.631;
constant input_hz : positive;
clkfbout_mult : integer range 2 to 64;
constant output_hz : positive)
clkout_divide : integer range 1 to 128;
return pll_settings_t is
divclk_divide : integer range 1 to 56;
end record;
function gen_pll_settings (
constant bad_settings : pll_settings_t :=
constant freq_hz : positive)
(clkin_period => 0.0,
return pll_settings_t is
clkfbout_mult => 2,
begin
clkout_divide => 1,
if freq_hz = 100000000 then
divclk_divide => 1,
return (clkin_period => 10.0,
force_rst => '1');
clkfbout_mult => 16,
begin
clkout_divide => 32,
case input_hz is
divclk_divide => 1);
when 100000000 =>
else
case output_hz is
report "Unsupported input frequency" severity failure;
when 100000000 =>
-- return (clkin_period => 0.0,
return (clkin_period => 10.0,
-- clkfbout_mult => 0,
clkfbout_mult => 16,
-- clkout_divide => 0,
clkout_divide => 16,
-- divclk_divide => 0);
divclk_divide => 1,
end if;
force_rst => '0');
end function gen_pll_settings;
when 50000000 =>
return (clkin_period => 10.0,
clkfbout_mult => 16,
clkout_divide => 32,
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_period_hz);
constant pll_settings : pll_settings_t := gen_pll_settings(clk_input_hz,
clk_output_hz);
begin
begin
pll : PLLE2_BASE
pll : PLLE2_BASE
generic map (
generic map (
BANDWIDTH => "OPTIMIZED",
BANDWIDTH => "OPTIMIZED",
CLKFBOUT_MULT => pll_settings.clkfbout_mult,
CLKFBOUT_MULT => pll_settings.clkfbout_mult,
CLKIN1_PERIOD => pll_settings.clkin_period,
CLKIN1_PERIOD => pll_settings.clkin_period,
CLKOUT0_DIVIDE => pll_settings.clkout_divide,
CLKOUT0_DIVIDE => pll_settings.clkout_divide,
DIVCLK_DIVIDE => pll_settings.divclk_divide,
DIVCLK_DIVIDE => pll_settings.divclk_divide,
STARTUP_WAIT => "FALSE")
STARTUP_WAIT => "FALSE")
port map (
port map (
CLKOUT0 => pll_clk_out,
CLKOUT0 => pll_clk_out,
CLKOUT1 => open,
CLKOUT1 => open,
CLKOUT2 => open,
CLKOUT2 => open,
CLKOUT3 => open,
CLKOUT3 => open,
CLKOUT4 => open,
CLKOUT4 => open,
CLKOUT5 => open,
CLKOUT5 => open,
CLKFBOUT => clkfb,
CLKFBOUT => clkfb,
LOCKED => pll_locked_out,
LOCKED => pll_locked_out,
CLKIN1 => ext_clk,
CLKIN1 => ext_clk,
PWRDWN => '0',
PWRDWN => '0',
RST => pll_rst_in,
RST => pll_rst_in or pll_settings.force_rst,
CLKFBIN => clkfb);
CLKFBIN => clkfb);
end architecture rtl;
end architecture rtl;