summaryrefslogtreecommitdiff
path: root/netfpga10g/hdl/recv_mux.vhd
blob: 42932af642b04acae9d3c60dc21ad8b323edee1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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;