Add Tercel PHY reset synchronization
[microwatt.git] / fpga / clk_gen_mcmm.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 := 12000000;
10 CLK_OUTPUT_HZ : positive := 50000000
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 10.000 to 800.0;
24 clkfbout_mult : real range 2.0 to 64.0;
25 clkout_divide : real range 1.0 to 128.0;
26 divclk_divide : integer range 1 to 106;
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.0,
38 clkout_divide => 1.0,
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.0,
48 clkout_divide => 16.0,
49 divclk_divide => 1,
50 force_rst => '0');
51 when 50000000 =>
52 return (clkin_period => 10.0,
53 clkfbout_mult => 16.0,
54 clkout_divide => 32.0,
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 12000000 =>
62 case output_hz is
63 when 100000000 =>
64 return (clkin_period => 83.33,
65 clkfbout_mult => 50.0,
66 clkout_divide => 6.0,
67 divclk_divide => 1,
68 force_rst => '0');
69 when 50000000 =>
70 return (clkin_period => 83.33,
71 clkfbout_mult => 50.0,
72 clkout_divide => 12.0,
73 divclk_divide => 1,
74 force_rst => '0');
75 when others =>
76 report "Unsupported output frequency" severity failure;
77 return bad_settings;
78 end case;
79 when others =>
80 report "Unsupported input frequency" severity failure;
81 return bad_settings;
82 end case;
83 end function gen_pll_settings;
84
85 constant pll_settings : pll_settings_t := gen_pll_settings(clk_input_hz,
86 clk_output_hz);
87 begin
88 pll : MMCME2_BASE
89 generic map (
90 BANDWIDTH => "OPTIMIZED",
91 CLKFBOUT_MULT_F => pll_settings.clkfbout_mult,
92 CLKIN1_PERIOD => pll_settings.clkin_period,
93 CLKOUT0_DIVIDE_F => pll_settings.clkout_divide,
94 DIVCLK_DIVIDE => pll_settings.divclk_divide,
95 STARTUP_WAIT => FALSE)
96 port map (
97 CLKFBOUT => clkfb,
98 CLKFBOUTB => open,
99 CLKOUT0 => pll_clk_out,
100 CLKOUT0B => open,
101 CLKOUT1 => open,
102 CLKOUT1B => open,
103 CLKOUT2 => open,
104 CLKOUT2B => open,
105 CLKOUT3 => open,
106 CLKOUT3B => open,
107 CLKOUT4 => open,
108 CLKOUT5 => open,
109 CLKOUT6 => open,
110 LOCKED => pll_locked_out,
111 CLKFBIN => clkfb,
112 CLKIN1 => ext_clk,
113 PWRDWN => '0',
114 RST => pll_rst_in or pll_settings.force_rst
115 );
116 end architecture rtl;