-- -- timing_io.vhd -- -- Timing Control and Test Generation -- -- -- Version 1.0 30/1/06 A.McCormick (Alpha Data) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_signed.all; use ieee.std_logic_arith.all; use ieee.std_logic_misc.all; library work; use work.common_interface.all; library UNISIM; use UNISIM.vcomponents.all; entity timing_io is port ( clk : in std_logic; rst : in std_logic; system_in : in std_logic_vector(system_width-1 downto 0); system_out : out std_logic_vector(system_width-1 downto 0); ten_mhz_clk : in std_logic; tbus_bplane :inout std_logic_vector(10 downto 1); tbus_header :inout std_logic_vector(10 downto 1); tbus_master :in std_logic_vector(10 downto 1); ten_mhz_clk_out : out std_logic; cycle_start_out : out std_logic; cycle_stop_out : out std_logic; cal_start_out : out std_logic; cal_stop_out : out std_logic; injection_out : out std_logic; hchange_out : out std_logic; fref_out : out std_logic); end timing_io; architecture rtl of timing_io is signal ten_mhz_reg : std_logic_vector(2 downto 0); signal timing_mux : std_logic_vector(7 downto 0); signal timing_assert : std_logic_vector(7 downto 0); signal timing_reg : std_logic_vector(31 downto 0); signal timing_mux10 : std_logic_vector(7 downto 0); signal timing_assert10 : std_logic_vector(7 downto 0); --signal ten_mhz_shift : std_logic_vector(24 downto 0) := "1111110000001111111000000"; -- generate poor 10MHz clock signal ten_mhz_clk_bg : std_logic; signal fref_counter : std_logic_vector(15 downto 0); signal fref_limit : std_logic_vector(15 downto 0); signal fref_int : std_logic; signal ten_mhz_int : std_logic; signal eighty_mhz_int : std_logic; signal ten_mhz_counter : std_logic_vector(2 downto 0) := "000"; signal cycle_start_in : std_logic; signal cycle_stop_in : std_logic; signal cal_start_in : std_logic; signal cal_stop_in : std_logic; signal injection_in : std_logic; signal hchange_in : std_logic; signal fref_in : std_logic; signal cycle_start_o : std_logic; signal cycle_stop_o : std_logic; signal cal_start_o : std_logic; signal cal_stop_o : std_logic; signal injection_o : std_logic; signal hchange_o : std_logic; signal fref_o : std_logic; signal cycle_start_bp : std_logic; signal cycle_stop_bp : std_logic; signal cal_start_bp : std_logic; signal cal_stop_bp : std_logic; signal injection_bp : std_logic; signal hchange_bp : std_logic; signal fref_bp : std_logic; signal cycle_start_hd : std_logic; signal cycle_stop_hd : std_logic; signal cal_start_hd : std_logic; signal cal_stop_hd : std_logic; signal injection_hd : std_logic; signal hchange_hd : std_logic; signal fref_hd : std_logic; signal master_bplane,master_header,slave_bplane,slave_header,use_bplane : std_logic; begin -- rtl cycle_start_in <= tbus_master(2); cycle_stop_in <= tbus_master(3); cal_start_in <= tbus_master(4); cal_stop_in <= tbus_master(5); injection_in <= tbus_master(6); hchange_in <= tbus_master(7); fref_in <= tbus_master(8); dcm0: dcm generic map ( clkfx_divide => 25, clkfx_multiply => 16, clk_feedback => "NONE") port map ( clkin => clk, clkfx => eighty_mhz_int, rst => rst, psclk => '0', psen => '0', psincdec => '0'); div_80Mhz_clk: process (eighty_mhz_int) begin -- process div_80Mhz_clk if eighty_mhz_int'event and eighty_mhz_int = '1' then -- rising clock edge ten_mhz_counter <= ten_mhz_counter+1; ten_mhz_int <= ten_mhz_counter(2); end if; end process div_80Mhz_clk; clk_buf0 : BUFGMUX port map ( S => timing_reg(8), I0 => ten_mhz_clk, I1 => ten_mhz_int, O => ten_mhz_clk_bg); -- Sample 10MHz clock to find safe time to change test signals sample_10mhz: process (clk, rst) begin -- process sample_10mhz if rst = '1' then -- asynchronous reset ten_mhz_reg <= (others => '0'); --ten_mhz_shift <= "1111110000001111111000000"; -- generate poor 10MHz clock -- from 125 timing_mux <= (others => '0'); timing_assert <= (others => '0'); fref_counter <= (others => '0'); fref_limit <= (others => '0'); master_bplane <= '0'; master_header <= '0'; slave_bplane <= '1'; slave_header <= '1'; use_bplane <= '0'; elsif clk'event and clk = '1' then -- rising clock edge ten_mhz_reg <= ten_mhz_reg(1 downto 0) & ten_mhz_clk_bg; --ten_mhz_shift <= ten_mhz_shift(23 downto 0) & ten_mhz_shift(24); -- Register Data to be converted to 10MHz, 2 clock cycles (16ns) -- after rising edge of 10MHz CLK if ten_mhz_reg(2) = '0' and ten_mhz_reg(1) = '1' then timing_mux <= timing_reg(15 downto 8); timing_assert <= timing_reg(7 downto 0); end if; fref_limit <= "0000" & timing_reg(27 downto 16); if OR_reduce(fref_counter) = '0' then fref_counter <= fref_limit; fref_int <= not fref_int; else fref_counter <= fref_counter-1; end if; master_bplane <= timing_reg(28); master_header <= timing_reg(29); use_bplane <= timing_reg(30); slave_bplane <= not master_bplane; slave_header <= not master_header; end if; end process sample_10mhz; -- Register timing signals and multiplex with test signals reg_timing: process (ten_mhz_clk_bg) begin -- process reg_timing if ten_mhz_clk_bg'event and ten_mhz_clk_bg = '1' then -- rising clock edge timing_mux10 <= timing_mux; timing_assert10 <= timing_assert; if timing_mux10(1) = '1' then cycle_start_o <= timing_assert10(1); else cycle_start_o <= cycle_start_in; end if; if timing_mux10(2) = '1' then cycle_stop_o <= timing_assert10(2); else cycle_stop_o <= cycle_stop_in; end if; if timing_mux10(3) = '1' then cal_start_o <= timing_assert10(3); else cal_start_o <= cal_start_in; end if; if timing_mux10(4) = '1' then cal_stop_o <= timing_assert10(4); else cal_stop_o <= cal_stop_in; end if; if timing_mux10(6) = '1' then hchange_o <= timing_assert10(6); else hchange_o <= hchange_in; end if; end if; end process reg_timing; -- Injection and FREF not synced to 10MHz injection_o <= injection_in when timing_mux10(5) = '0' else timing_assert10(5); fref_o <= fref_in when timing_mux10(7) = '0' else fref_int; creg0 : readable_control_register generic map ( width => 32, addr => 2) port map ( clk => clk, rst => rst, system_in => system_in, system_out => system_out, control_data => timing_reg, control_wstb => open); ten_mhz_clk_out <= ten_mhz_clk_bg; iob_bp1: IOBUF port map ( I => ten_mhz_clk_bg, IO => tbus_bplane(1), O => open, T => slave_bplane); iob_bp2: IOBUF port map ( I => cycle_start_o, IO => tbus_bplane(2), O => cycle_start_bp, T => slave_bplane); iob_bp3: IOBUF port map ( I => cycle_stop_o, IO => tbus_bplane(3), O => cycle_stop_bp, T => slave_bplane); iob_bp4: IOBUF port map ( I => cal_start_o, IO => tbus_bplane(4), O => cal_start_bp, T => slave_bplane); iob_bp5: IOBUF port map ( I => cal_stop_o, IO => tbus_bplane(5), O => cal_stop_bp, T => slave_bplane); iob_bp6: IOBUF port map ( I => injection_o, IO => tbus_bplane(6), O => injection_bp, T => slave_bplane); iob_bp7: IOBUF port map ( I => hchange_o, IO => tbus_bplane(7), O => hchange_bp, T => slave_bplane); iob_bp8: IOBUF port map ( I => fref_o, IO => tbus_bplane(8), O => fref_bp, T => slave_bplane); iob_hd1: IOBUF port map ( I => ten_mhz_clk_bg, IO => tbus_header(1), O => open, T => slave_header); iob_hd2: IOBUF port map ( I => cycle_start_o, IO => tbus_header(2), O => cycle_start_hd, T => slave_header); iob_hd3: IOBUF port map ( I => cycle_stop_o, IO => tbus_header(3), O => cycle_stop_hd, T => slave_header); iob_hd4: IOBUF port map ( I => cal_start_o, IO => tbus_header(4), O => cal_start_hd, T => slave_header); iob_hd5: IOBUF port map ( I => cal_stop_o, IO => tbus_header(5), O => cal_stop_hd, T => slave_header); iob_hd6: IOBUF port map ( I => injection_o, IO => tbus_header(6), O => injection_hd, T => slave_header); iob_hd7: IOBUF port map ( I => hchange_o, IO => tbus_header(7), O => hchange_hd, T => slave_header); iob_hd8: IOBUF port map ( I => fref_o, IO => tbus_header(8), O => fref_hd, T => slave_header); -- Select BPLANE or HEADER as INPUT cycle_start_out <= cycle_start_bp when use_bplane = '1' else cycle_start_hd; cycle_stop_out <= cycle_stop_bp when use_bplane = '1' else cycle_stop_hd; cal_start_out <= cal_start_bp when use_bplane = '1' else cal_start_hd; cal_stop_out <= cal_stop_bp when use_bplane = '1' else cal_stop_hd; injection_out <= injection_bp when use_bplane = '1' else injection_hd; hchange_out <= hchange_bp when use_bplane = '1' else hchange_hd; fref_out <= fref_bp when use_bplane = '1' else fref_hd; end rtl;