summaryrefslogtreecommitdiff
path: root/netfpga10g/hdl/recv_mux.vhd
diff options
context:
space:
mode:
Diffstat (limited to 'netfpga10g/hdl/recv_mux.vhd')
-rw-r--r--netfpga10g/hdl/recv_mux.vhd86
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;
+