entity clock_generator is
generic (
- clk_period_hz : positive := 12000000);
+ CLK_INPUT_HZ : positive := 12000000;
+ CLK_OUTPUT_HZ : positive := 50000000
+ );
port (
ext_clk : in std_logic;
pll_rst_in : in std_logic;
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 freq_hz : positive)
+ 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
- if freq_hz = 100000000 then
- return (clkin_period => 10.0,
- clkfbout_mult => 16.0,
- clkout_divide => 32.0,
- divclk_divide => 1);
- elsif freq_hz = 12000000 then
- return (clkin_period => 83.33,
- clkfbout_mult => 50.0,
- clkout_divide => 12.0,
- divclk_divide => 1);
- else
- report "Unsupported input frequency" severity failure;
- end if;
+ 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_period_hz);
+ constant pll_settings : pll_settings_t := gen_pll_settings(clk_input_hz,
+ clk_output_hz);
begin
pll : MMCME2_BASE
generic map (
CLKFBIN => clkfb,
CLKIN1 => ext_clk,
PWRDWN => '0',
- RST => pll_rst_in
+ RST => pll_rst_in or pll_settings.force_rst
);
end architecture rtl;
use UNISIM.vcomponents.all;
entity clock_generator is
- generic (
- clk_period_hz : positive := 100000000);
- port (
- ext_clk : in std_logic;
- pll_rst_in : in std_logic;
- pll_clk_out : out std_logic;
- pll_locked_out : out std_logic);
+ generic (
+ CLK_INPUT_HZ : positive := 100000000;
+ CLK_OUTPUT_HZ : positive := 100000000
+ );
+ 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;
- 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
- 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;
- end record;
+ function gen_pll_settings (
+ constant input_hz : positive;
+ constant output_hz : positive)
+ return pll_settings_t is
- function gen_pll_settings (
- constant freq_hz : positive)
- return pll_settings_t is
- begin
- if freq_hz = 100000000 then
- return (clkin_period => 10.0,
- clkfbout_mult => 16,
- clkout_divide => 32,
- divclk_divide => 1);
- else
- report "Unsupported input frequency" severity failure;
--- return (clkin_period => 0.0,
--- clkfbout_mult => 0,
--- clkout_divide => 0,
--- divclk_divide => 0);
- end if;
- end function gen_pll_settings;
+ constant bad_settings : pll_settings_t :=
+ (clkin_period => 0.0,
+ clkfbout_mult => 2,
+ clkout_divide => 1,
+ 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,
+ clkout_divide => 16,
+ divclk_divide => 1,
+ force_rst => '0');
+ 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
- pll : PLLE2_BASE
- generic map (
- BANDWIDTH => "OPTIMIZED",
- CLKFBOUT_MULT => pll_settings.clkfbout_mult,
- CLKIN1_PERIOD => pll_settings.clkin_period,
- CLKOUT0_DIVIDE => pll_settings.clkout_divide,
- DIVCLK_DIVIDE => pll_settings.divclk_divide,
- STARTUP_WAIT => "FALSE")
- port map (
- CLKOUT0 => pll_clk_out,
- CLKOUT1 => open,
- CLKOUT2 => open,
- CLKOUT3 => open,
- CLKOUT4 => open,
- CLKOUT5 => open,
- CLKFBOUT => clkfb,
- LOCKED => pll_locked_out,
- CLKIN1 => ext_clk,
- PWRDWN => '0',
- RST => pll_rst_in,
- CLKFBIN => clkfb);
+ pll : PLLE2_BASE
+ generic map (
+ BANDWIDTH => "OPTIMIZED",
+ CLKFBOUT_MULT => pll_settings.clkfbout_mult,
+ CLKIN1_PERIOD => pll_settings.clkin_period,
+ CLKOUT0_DIVIDE => pll_settings.clkout_divide,
+ DIVCLK_DIVIDE => pll_settings.divclk_divide,
+ STARTUP_WAIT => "FALSE")
+ port map (
+ CLKOUT0 => pll_clk_out,
+ CLKOUT1 => open,
+ CLKOUT2 => open,
+ CLKOUT3 => open,
+ CLKOUT4 => open,
+ CLKOUT5 => open,
+ CLKFBOUT => clkfb,
+ LOCKED => pll_locked_out,
+ CLKIN1 => ext_clk,
+ PWRDWN => '0',
+ RST => pll_rst_in or pll_settings.force_rst,
+ CLKFBIN => clkfb);
end architecture rtl;
nexys_a7:
default_tool: vivado
filesets: [core, nexys_a7, soc, fpga, debug_xilinx]
- parameters : [memory_size, ram_init_file]
+ parameters :
+ - memory_size
+ - ram_init_file
+ - clk_input
+ - clk_frequency
tools:
vivado: {part : xc7a100tcsg324-1}
toplevel : toplevel
nexys_video:
default_tool: vivado
filesets: [core, nexys_video, soc, fpga, debug_xilinx]
- parameters : [memory_size, ram_init_file]
+ parameters :
+ - memory_size
+ - ram_init_file
+ - clk_input
+ - clk_frequency
tools:
vivado: {part : xc7a200tsbg484-1}
toplevel : toplevel
arty_a7-35:
default_tool: vivado
filesets: [core, arty_a7, soc, fpga, debug_xilinx]
- parameters : [memory_size, ram_init_file]
+ parameters :
+ - memory_size
+ - ram_init_file
+ - clk_input
+ - clk_frequency
tools:
vivado: {part : xc7a35ticsg324-1L}
toplevel : toplevel
arty_a7-100:
default_tool: vivado
filesets: [core, arty_a7, soc, fpga, debug_xilinx]
- parameters : [memory_size, ram_init_file]
+ parameters :
+ - memory_size
+ - ram_init_file
+ - clk_input
+ - clk_frequency
tools:
vivado: {part : xc7a100ticsg324-1L}
toplevel : toplevel
cmod_a7-35:
default_tool: vivado
filesets: [core, cmod_a7-35, soc, fpga, debug_xilinx]
- parameters : [memory_size, ram_init_file, reset_low=false]
+ parameters :
+ - memory_size
+ - ram_init_file
+ - reset_low=false
+ - clk_input=12000000
tools:
vivado: {part : xc7a35tcpg236-1}
toplevel : toplevel
datatype : bool
description : External reset button polarity
paramtype : generic
+
+ clk_input:
+ datatype : int
+ description : Clock input frequency in HZ (for top-generic based boards)
+ paramtype : generic
+ default : 100000000
+
+ clk_frequency:
+ datatype : int
+ description : Generated system clock frequency in HZ (for top-generic based boards)
+ paramtype : generic
+ default : 50000000