Merge pull request #77 from antonblanchard/timing
[microwatt.git] / fpga / clk_gen_plle2.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3
4 Library UNISIM;
5 use UNISIM.vcomponents.all;
6
7 entity clock_generator is
8 generic (
9 CLK_INPUT_HZ : positive := 100000000;
10 CLK_OUTPUT_HZ : positive := 100000000
11 );
12 port (
13 ext_clk : in std_logic;
14 pll_rst_in : in std_logic;
15 pll_clk_out : out std_logic;
16 pll_locked_out : out std_logic);
17 end entity clock_generator;
18
19 architecture rtl of clock_generator is
20 signal clkfb : std_ulogic;
21
22 type pll_settings_t is record
23 clkin_period : real range 0.000 to 52.631;
24 clkfbout_mult : integer range 2 to 64;
25 clkout_divide : integer range 1 to 128;
26 divclk_divide : integer range 1 to 56;
27 force_rst : std_ulogic;
28 end record;
29
30 function gen_pll_settings (
31 constant input_hz : positive;
32 constant output_hz : positive)
33 return pll_settings_t is
34
35 constant bad_settings : pll_settings_t :=
36 (clkin_period => 0.0,
37 clkfbout_mult => 2,
38 clkout_divide => 1,
39 divclk_divide => 1,
40 force_rst => '1');
41 begin
42 case input_hz is
43 when 100000000 =>
44 case output_hz is
45 when 100000000 =>
46 return (clkin_period => 10.0,
47 clkfbout_mult => 16,
48 clkout_divide => 16,
49 divclk_divide => 1,
50 force_rst => '0');
51 when 50000000 =>
52 return (clkin_period => 10.0,
53 clkfbout_mult => 16,
54 clkout_divide => 32,
55 divclk_divide => 1,
56 force_rst => '0');
57 when others =>
58 report "Unsupported output frequency" severity failure;
59 return bad_settings;
60 end case;
61 when others =>
62 report "Unsupported input frequency" severity failure;
63 return bad_settings;
64 end case;
65 end function gen_pll_settings;
66
67 constant pll_settings : pll_settings_t := gen_pll_settings(clk_input_hz,
68 clk_output_hz);
69 begin
70
71 pll : PLLE2_BASE
72 generic map (
73 BANDWIDTH => "OPTIMIZED",
74 CLKFBOUT_MULT => pll_settings.clkfbout_mult,
75 CLKIN1_PERIOD => pll_settings.clkin_period,
76 CLKOUT0_DIVIDE => pll_settings.clkout_divide,
77 DIVCLK_DIVIDE => pll_settings.divclk_divide,
78 STARTUP_WAIT => "FALSE")
79 port map (
80 CLKOUT0 => pll_clk_out,
81 CLKOUT1 => open,
82 CLKOUT2 => open,
83 CLKOUT3 => open,
84 CLKOUT4 => open,
85 CLKOUT5 => open,
86 CLKFBOUT => clkfb,
87 LOCKED => pll_locked_out,
88 CLKIN1 => ext_clk,
89 PWRDWN => '0',
90 RST => pll_rst_in or pll_settings.force_rst,
91 CLKFBIN => clkfb);
92
93 end architecture rtl;