library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity recv_mux is generic ( BUFF_COUNT : integer := 16; BUFF_BITS : integer := 4 -- 2^4 = 16 ); port ( rd_clk : in std_logic; rd_buff : in std_logic_vector (BUFF_BITS - 1 downto 0); rd_en : in std_logic; rd_data : out std_logic_vector (63 downto 0) := (others => '0'); rd_length : out std_logic_vector (8 downto 0) := (others => '0'); rd_valid : out std_logic_vector (BUFF_COUNT - 1 downto 0) := (others => '0'); wr_clk : in std_logic; wr_en : in std_logic; wr_data : in std_logic_vector (63 downto 0); wr_done : in std_logic; wr_accept : out std_logic := '0' ); end recv_mux; architecture arch of recv_mux is type rd_data_t is array (0 to BUFF_COUNT - 1) of std_logic_vector(63 downto 0); type rd_length_t is array (0 to BUFF_COUNT - 1) of std_logic_vector(8 downto 0); signal wr_en_i : std_logic_vector(BUFF_COUNT - 1 downto 0) := (others => '0'); signal wr_done_i : std_logic_vector(BUFF_COUNT - 1 downto 0) := (others => '0'); signal wr_accept_i : std_logic_vector(BUFF_COUNT - 1 downto 0) := (others => '0'); signal wr_buff : integer range 0 to BUFF_COUNT - 1 := 0; signal rd_en_i : std_logic_vector(BUFF_COUNT - 1 downto 0) := (others => '0'); signal rd_data_i : rd_data_t := (others => (others => '0')); signal rd_length_i : rd_length_t := (others => (others => '0')); signal rd_buff_i : integer range 0 to BUFF_COUNT - 1 := 0; begin rd_buff_i <= to_integer(unsigned(rd_buff)); recv_gen: for i in 0 to BUFF_COUNT - 1 generate recv_buff : entity work.buff port map ( wr_clk => wr_clk, wr_en => wr_en_i(i), wr_data => wr_data, wr_done => wr_done_i(i), wr_accept => wr_accept_i(i), rd_clk => rd_clk, rd_en => rd_en_i(i), rd_data => rd_data_i(i), rd_length => rd_length_i(i), rd_valid => rd_valid(i) ); wr_en_i(i) <= wr_en when wr_buff = i else '0'; wr_done_i(i) <= wr_done when wr_buff = i else '0'; rd_en_i(i) <= rd_en when rd_buff_i = i else '0'; end generate recv_gen; rd_data <= rd_data_i(rd_buff_i); rd_length <= rd_length_i(rd_buff_i); wr_accept <= wr_accept_i(wr_buff); process (wr_clk) variable tmp_buff : integer range 0 to BUFF_COUNT - 1; begin if rising_edge(wr_clk) then if wr_accept_i(wr_buff) = '0' then for i in 0 to BUFF_COUNT - 1 loop tmp_buff := (i + wr_buff) mod BUFF_COUNT; if wr_accept_i(tmp_buff) = '1' then wr_buff <= tmp_buff; exit; end if; end loop; end if; end if; end process; end arch;