-- -- Async Auto MUX -- -- Round robin port selection, no sync -- -- -- change log: -- 2012-07-31 - moved to t_llbus type, at last library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library utils; use utils.pkg_types.all; entity ll_automux is generic( LEVELS : integer := 2 ); port( -- locallink interfaces --in lls_i : in t_llsrc_array ((2**LEVELS)-1 downto 0); lld_o : out std_logic_vector ((2**LEVELS)-1 downto 0); --out lls_o : out t_llsrc; lld_i : in std_logic; -- infrastructure rst : in std_logic; clk : in std_logic ); -- Declarations end ll_automux ; -- architecture rtl of ll_automux is constant PORTS : integer := 2**LEVELS; type states is( WaitEOF, Idle); signal state, nstate : states; signal sel : std_logic_vector(LEVELS-1 downto 0); signal sel_int : integer range 0 to (PORTS-1); signal sel_inc : std_logic; signal src_rdy_in : std_logic_vector(PORTS-1 downto 0); --signal sof_in : std_logic_vector(PORTS-1 downto 0); signal eof_in : std_logic_vector(PORTS-1 downto 0); signal dst_rdy_out : std_logic_vector(PORTS-1 downto 0); begin deconstructed_sigs_gen : for n in 0 to (PORTS-1) generate src_rdy_in(n) <= lls_i(n).src_rdy; --sof_in(n) <= lls_i(n).sof; eof_in(n) <= lls_i(n).eof; lld_o(n) <= dst_rdy_out(n); end generate; lls_o.src_rdy <= lls_i(sel_int).src_rdy; lls_o.sof <= lls_i(sel_int).sof; lls_o.eof <= lls_i(sel_int).eof; lls_o.data <= lls_i(sel_int).data; -- SM Clocked ------------------------------------------------------- prc_sm_clocked : process(clk) begin if rising_edge(clk) then if (rst = '1') then state <= Idle; else state <= nstate; end if; end if; end process; -- SM Async ------------------------------------------------------- prc_sm_async : process(state, src_rdy_in, eof_in, lld_i, sel_int) begin -- defaults nstate <= Idle; dst_rdy_out <= (others => '0'); case state is when Idle => nstate <= Idle; sel_inc <= '1'; dst_rdy_out(sel_int) <= '1'; -- *** new 2015 if (src_rdy_in(sel_int) = '1') then dst_rdy_out(sel_int) <= '0'; -- *** new 2015 sel_inc <= '0'; nstate <= WaitEOF; end if; when WaitEOF => nstate <= WaitEOF; sel_inc <= '0'; if (lld_i = '1') then dst_rdy_out(sel_int) <= '1'; if (eof_in(sel_int) = '1') then nstate <= Idle; end if; end if; end case; end process; -- Port select counter -- this is simple round-robin prc_port_sel_counter : process(clk) begin if rising_edge(clk) then if (rst = '1') then sel <= (others => '0'); elsif (sel_inc = '1') then sel <= sel + '1'; end if; end if; end process; sel_int <= conv_integer(sel); end architecture rtl;