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.
		
		
		
		
		
			
		
			
				
	
	
		
			118 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			VHDL
		
	
			
		
		
	
	
			118 lines
		
	
	
		
			3.9 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 := 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;
 | |
| 
 | |
|     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;
 | |
| 
 | |
|     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,
 | |
|              clkout_divide => 1,
 | |
|              divclk_divide => 1,
 | |
|              force_rst     => '1');
 | |
|     begin
 | |
|         case input_hz is
 | |
|         when 200000000 =>
 | |
|             case output_hz is
 | |
|             when 100000000 =>
 | |
|                 return (clkin_period  => 5.0,
 | |
|                         clkfbout_mult => 8,
 | |
|                         clkout_divide => 16,
 | |
|                         divclk_divide => 1,
 | |
|                         force_rst     => '0');
 | |
|             when others =>
 | |
|                 report "Unsupported output frequency" severity failure;
 | |
|                 return bad_settings;
 | |
|             end case;
 | |
|         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 50000000 =>
 | |
|             case output_hz is
 | |
|             when 100000000 =>
 | |
|                 return (clkin_period  => 20.0,
 | |
|                         clkfbout_mult => 32,
 | |
|                         clkout_divide => 16,
 | |
|                         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 : 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;
 |