library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; use work.lx_rocon_pkg.all; -- IRC bus interconnect entity bus_irc is port ( clk_i : in std_logic; reset_i : in std_logic; -- Data bus address_i : in std_logic_vector(4 downto 0); ce_i : in std_logic; data_i : in std_logic_vector(31 downto 0); data_o : out std_logic_vector(31 downto 0); -- bls_i : in std_logic_vector(3 downto 0); -- Signals for IRC irc_i : in IRC_INPUT_Array_Type(7 downto 0) ); end bus_irc; architecture Behavioral of bus_irc is constant num_irc_c : positive := 8; signal irc_o_s : IRC_OUTPUT_Array_Type(num_irc_c-1 downto 0); signal irc_count_s : IRC_COUNT_OUTPUT_Array_Type((num_irc_c-1) downto 0); signal reset_index_event_s : std_logic_vector(num_irc_c-1 downto 0); signal reset_index_event2_s : std_logic_vector(num_irc_c-1 downto 0); signal reset_ab_error_s : std_logic_vector(num_irc_c-1 downto 0); signal state_o_s : std_logic_vector(3 downto 0); signal state_o_r : std_logic_vector(3 downto 0); -- signal irc_en_s : std_logic; signal irc_bls_s : std_logic_vector(3 downto 0); signal irc_addr_s : std_logic_vector(3 downto 0); signal irc_data_s : std_logic_vector(31 downto 0); signal irc_out_s : std_logic; signal irc_out_r : std_logic; -- signal reset_reg_s : std_logic; signal reset_reg_r : std_logic; signal reset_reg_wr_s : std_logic; -- signal reset_s : std_logic; signal ce_r : std_logic; begin irc_generate: for i in 0 to num_irc_c-1 generate irc : irc_reader port map ( clk_i => clk_i, reset_i => reset_s, irc_i => irc_i(i), reset_index_event_i => reset_index_event_s(i), reset_index_event2_i => reset_index_event2_s(i), reset_ab_error_i => reset_ab_error_s(i), irc_o => irc_o_s(i) ); irc_count_s(i) <= irc_o_s(i).count; end generate; irc_proc : irc_proc_main generic map ( num_irc_g => num_irc_c ) port map ( clk_i => clk_i, reset_i => reset_s, -- IRC irc_i => irc_count_s, irc_index_reset_o => reset_index_event_s, -- BRAM mem_clk_i => clk_i, mem_en_i => irc_en_s, mem_we_i => irc_bls_s, mem_addr_i => irc_addr_s, mem_data_i => data_i, mem_data_o => irc_data_s ); reset_s <= reset_reg_r or reset_i; wire_in: process(ce_i, ce_r, reset_reg_r, bls_i, address_i, irc_data_s, data_i, irc_o_s) begin -- init values irc_en_s <= '0'; irc_out_s <= '0'; irc_bls_s <= (others => '0'); irc_addr_s <= (others => '0'); reset_ab_error_s <= (others => '0'); reset_index_event2_s <= (others => '0'); state_o_s <= (others => '0'); reset_reg_s <= '0'; reset_reg_wr_s <= '0'; -- Incoming bus request if ce_i = '1' then -- Mapping: -- 0 & axis & irc / index - (all read from bram) (R/W) -- 1 & axis & 0 - status register (R/W) -- 1 & 000 & 1 - reset if address_i(4) = '0' then irc_addr_s <= address_i(3 downto 0); irc_en_s <= '1'; irc_bls_s <= bls_i; irc_out_s <= '1'; -- Maybe these would be better to latch in ce_i cycle, -- and then just pass them elsif address_i(0) = '0' then state_o_s(0) <= irc_o_s(to_integer(unsigned(address_i(3 downto 1)))).state.mark; state_o_s(1) <= irc_o_s(to_integer(unsigned(address_i(3 downto 1)))).state.ab_error; state_o_s(2) <= irc_o_s(to_integer(unsigned(address_i(3 downto 1)))).state.index_event; state_o_s(3) <= irc_o_s(to_integer(unsigned(address_i(3 downto 1)))).state.index; if bls_i(0) = '1' then if data_i(1) = '1' then reset_ab_error_s(to_integer(unsigned(address_i(3 downto 1)))) <= '1'; end if; if data_i(2) = '1' then reset_index_event2_s(to_integer(unsigned(address_i(3 downto 1)))) <= '1'; end if; end if; elsif address_i = "10001" then if bls_i(0) = '1' then reset_reg_s <= data_i(0); reset_reg_wr_s <= '1'; else -- Ugh, hack :-) state_o_s(0) <= reset_reg_r; state_o_s(3 downto 1) <= (others => '0'); end if; end if; end if; end process; wire_out: process(ce_r, irc_data_s, irc_out_r, state_o_r) begin data_o <= (others => '0'); if ce_r = '1' then if irc_out_r = '1' then data_o <= irc_data_s; else data_o(3 downto 0) <= state_o_r; end if; end if; end process; update: process begin wait until clk_i'event and clk_i= '1'; ce_r <= ce_i; irc_out_r <= irc_out_s; state_o_r <= state_o_s; if reset_i = '1' then reset_reg_r <= '1'; elsif reset_reg_wr_s = '1' then reset_reg_r <= reset_reg_s; end if; end process; end Behavioral;