library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity clock_gen is generic ( rst_width : integer := 32 -- width of the reset pulse in clk40-cycles -- valid : 0..63 ); port ( CLK40i : in std_logic; -- 40MHz clock input from DCS board rst_req : in std_logic; -- async reset request clk40 : out std_logic; clk40_90 : out std_logic; clk40_180 : out std_logic; clk40_270 : out std_logic; clk80 : out std_logic; clk80_180 : out std_logic; clk_scsn : out std_logic; rst_scsn : out std_logic; rst_scsn_n : out std_logic; -- ps_adjust : in std_logic_vector(1 downto 0); -- ps_state : out std_logic_vector(9 downto 0); clk40_ps : out std_logic; -- 40 MHz clock with phase shift clk40_ps_180 : out std_logic; -- 40 MHz clock with phase shift (inverted) rst40 : out std_logic; rst40_n : out std_logic; rst80 : out std_logic ); end clock_gen; architecture behav of clock_gen is component pll40_40d_80 is port(POWERDOWN : in std_logic; -- active high CLKA : in std_logic; -- input clock 40 MHz LOCK : out std_logic; -- locked GLA : out std_logic; -- 40 MHz GLB : out std_logic; -- 40 MHz 90 deg GLC : out std_logic) ; -- 80 MHz end component; signal clk40_i : std_logic; signal clk40_90_i : std_logic; signal clk80_i : std_logic; -- signal ps_adjust_r : std_logic_vector(ps_adjust'range); -- signal ps_en : std_logic; -- signal ps_value : std_logic_vector(8 downto 0); -- signal ps_done : std_logic; signal rst_master : std_logic; signal rst_cnt : std_logic_vector(5 downto 0); signal rst_pulse_width : std_logic_vector(5 downto 0); signal locked : std_logic; begin -- default clk40 <= clk40_i; clk40_90 <= clk40_90_i; clk40_180 <= not clk40_i; clk40_270 <= not clk40_90_i; clk80 <= clk80_i; clk80_180 <= not clk80_i; clk40_ps <= clk40_i; clk40_ps_180 <= not clk40_i; clk_scsn <= clk40_i; rst_scsn <= rst_master; rst_scsn_n <= not rst_master; ipll: pll40_40d_80 port map( POWERDOWN => '0', CLKA => clk40i, LOCK => locked, GLA => clk40_i, GLB => clk40_90_i, GLC => clk80_i ); -- -- Reset pulse generation rst_pulse_width <= conv_std_logic_vector( rst_width, rst_pulse_width'length ); process (clk40_i, rst_req, locked) begin if rst_req = '1' or locked = '0' then rst_master <= '1'; rst_cnt <= ( others => '0' ); elsif rising_edge( clk40_i) then if rst_cnt = rst_pulse_width then rst_master <= '0'; rst_cnt <= rst_cnt; else rst_cnt <= rst_cnt + '1'; rst_master <= '1'; end if; end if; end process; -- -- Output mapping -- ps_state(8 downto 0) <= ps_value; -- clk40, clk120 and clk80 are phase locked => no synchronizers rst40 <= rst_master; rst40_n <= not rst_master; rst80 <= rst_master; end;