use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
-use work.mbl_pkg.all;
use work.lx_rocon_pkg.all;
-- IRC bus interconnect
clk_i : in std_logic;
reset_i : in std_logic;
-- Data bus
- address_i : in std_logic_vector(3 downto 0);
- next_ce_i : in std_logic;
+ 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(3 downto 0)
+ irc_i : in IRC_INPUT_Array_Type(7 downto 0)
);
end bus_irc;
architecture Behavioral of bus_irc is
- signal irc_o_s : IRC_OUTPUT_Array_Type(3 downto 0);
- signal reset_index_event_s : std_logic_vector(3 downto 0);
- signal reset_index_event2_s : std_logic_vector(3 downto 0);
- signal reset_ab_error_s : std_logic_vector(3 downto 0);
- signal state_o_s : std_logic_vector(2 downto 0);
- signal state_o_r : std_logic_vector(2 downto 0);
+ 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(2 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_wr_s : std_logic;
--
signal reset_s : std_logic;
- signal ce_s : std_logic;
-begin
-
-irc1 : irc_reader
- port map
- (
- clk_i => clk_i,
- reset_i => reset_s,
- irc_i => irc_i(0),
- reset_index_event_i => reset_index_event_s(0),
- reset_index_event2_i => reset_index_event2_s(0),
- reset_ab_error_i => reset_ab_error_s(0),
- irc_o => irc_o_s(0)
- );
-
-irc2 : irc_reader
- port map
- (
- clk_i => clk_i,
- reset_i => reset_s,
- irc_i => irc_i(1),
- reset_index_event_i => reset_index_event_s(1),
- reset_index_event2_i => reset_index_event2_s(1),
- reset_ab_error_i => reset_ab_error_s(1),
- irc_o => irc_o_s(1)
- );
+ signal ce_r : std_logic;
-irc3 : irc_reader
- port map
- (
- clk_i => clk_i,
- reset_i => reset_s,
- irc_i => irc_i(2),
- reset_index_event_i => reset_index_event_s(2),
- reset_index_event2_i => reset_index_event2_s(2),
- reset_ab_error_i => reset_ab_error_s(2),
- irc_o => irc_o_s(2)
- );
+begin
-irc4 : irc_reader
- port map
- (
- clk_i => clk_i,
- reset_i => reset_s,
- irc_i => irc_i(3),
- reset_index_event_i => reset_index_event_s(3),
- reset_index_event2_i => reset_index_event2_s(3),
- reset_ab_error_i => reset_ab_error_s(3),
- irc_o => irc_o_s(3)
- );
+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 => 4
+ num_irc_g => num_irc_c
)
port map
(
clk_i => clk_i,
reset_i => reset_s,
-- IRC
- irc_i(0) => irc_o_s(0).count,
- irc_i(1) => irc_o_s(1).count,
- irc_i(2) => irc_o_s(2).count,
- irc_i(3) => irc_o_s(3).count,
+ irc_i => irc_count_s,
irc_index_reset_o => reset_index_event_s,
-- BRAM
mem_clk_i => clk_i,
reset_s <= reset_reg_r or reset_i;
wire_in:
- process(next_ce_i, ce_s, reset_reg_s, bls_i, address_i, irc_data_s, data_i, irc_o_s)
+ process(ce_i, ce_r, reset_reg_r, bls_i, address_i, irc_data_s, data_i, irc_o_s)
begin
-- init values
irc_addr_s <= (others => '0');
reset_ab_error_s <= (others => '0');
reset_index_event2_s <= (others => '0');
- state_o_s <= (others => 'X');
+ state_o_s <= (others => '0');
reset_reg_s <= '0';
reset_reg_wr_s <= '0';
-- Incoming bus request
- if next_ce_i = '1' then
+ if ce_i = '1' then
-- Mapping:
-- 0 & axis & irc / index - (all read from bram) (R/W)
-- 1 & axis & 0 - status register (R/W)
- -- 1 & 00 & 1 - reset
- if address_i(3) = '0' then
+ -- 1 & 000 & 1 - reset
+ if address_i(4) = '0' then
- irc_addr_s <= address_i(2 downto 0);
+ 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 next_ce_i cycle,
+ -- Maybe these would be better to latch in ce_i cycle,
-- and then just pass them
elsif address_i(0) = '0' then
- case address_i(2 downto 1) is
- when "00" =>
- state_o_s(0) <= irc_o_s(0).state.mark;
- state_o_s(1) <= irc_o_s(0).state.ab_error;
- state_o_s(2) <= irc_o_s(0).state.index_event;
- when "01" =>
- state_o_s(0) <= irc_o_s(1).state.mark;
- state_o_s(1) <= irc_o_s(1).state.ab_error;
- state_o_s(2) <= irc_o_s(1).state.index_event;
- when "10" =>
- state_o_s(0) <= irc_o_s(2).state.mark;
- state_o_s(1) <= irc_o_s(2).state.ab_error;
- state_o_s(2) <= irc_o_s(2).state.index_event;
- when "11" =>
- state_o_s(0) <= irc_o_s(3).state.mark;
- state_o_s(1) <= irc_o_s(3).state.ab_error;
- state_o_s(2) <= irc_o_s(3).state.index_event;
- when others =>
- null;
- end case;
+ 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(2 downto 1)))) <= '1';
+ 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(2 downto 1)))) <= '1';
+ reset_index_event2_s(to_integer(unsigned(address_i(3 downto 1)))) <= '1';
end if;
end if;
- elsif address_i = "1001" then
+ 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_s;
- state_o_s(1) <= '0';
- state_o_s(2) <= '0';
+ state_o_s(0) <= reset_reg_r;
+ state_o_s(3 downto 1) <= (others => '0');
end if;
end if;
end process;
wire_out:
- process(ce_s, irc_data_s, irc_out_r, state_o_r)
+ process(ce_r, irc_data_s, irc_out_r, state_o_r)
begin
- data_o <= (others => 'X');
+ data_o <= (others => '0');
- if ce_s = '1' then
-
- if irc_out_r = '1' then
- data_o <= irc_data_s;
- else
- data_o(2 downto 0) <= state_o_r;
- end if;
-
- end if;
+ 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_s <= next_ce_i;
+ ce_r <= ce_i;
irc_out_r <= irc_out_s;
state_o_r <= state_o_s;