diff options
Diffstat (limited to 'netfpga10g/hdl/recv_mux.vhd')
-rw-r--r-- | netfpga10g/hdl/recv_mux.vhd | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/netfpga10g/hdl/recv_mux.vhd b/netfpga10g/hdl/recv_mux.vhd new file mode 100644 index 0000000..42932af --- /dev/null +++ b/netfpga10g/hdl/recv_mux.vhd @@ -0,0 +1,86 @@ + +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; + |