summaryrefslogtreecommitdiff
path: root/netfpga10g/hdl/send_mux.vhd
blob: 8d9f667168af79b5648330e72a4b03ac8c6439b6 (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

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity send_mux is
generic (
        BUFF_COUNT : integer := 16;
        BUFF_BITS : integer := 4 -- 2^4 = 16
);
    Port ( wr_clk : in  STD_LOGIC;
           wr_buff : in  STD_LOGIC_VECTOR (BUFF_BITS - 1 downto 0);
           wr_en : in  STD_LOGIC;
           wr_data : in  STD_LOGIC_VECTOR (63 downto 0);
           wr_done : in  STD_LOGIC;
           wr_cancel : in  STD_LOGIC_VECTOR (BUFF_COUNT - 1 downto 0);
           wr_accept : out  STD_LOGIC_VECTOR (BUFF_COUNT - 1 downto 0) := (others => '0');
           rd_clk : in  STD_LOGIC;
           rd_en : in  STD_LOGIC;
           rd_data : out  STD_LOGIC_VECTOR (63 downto 0) := (others => '0');
           rd_valid : out  STD_LOGIC := '0');
end send_mux;

architecture arch of send_mux is
        type rd_data_t is array (0 to BUFF_COUNT - 1) of std_logic_vector(63 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 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_valid_i : std_logic_vector(BUFF_COUNT - 1 downto 0) := (others => '0');
        signal rd_buff : integer range 0 to BUFF_COUNT - 1 := 0;
begin
        send_gen: for i in 0 to BUFF_COUNT - 1 generate
                send_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_cancel => wr_cancel(i),
                        wr_accept => wr_accept(i),

                        rd_clk => rd_clk,
                        rd_en => rd_en_i(i),
                        rd_data => rd_data_i(i),
                        rd_length => open,
                        rd_valid => rd_valid_i(i)
                );
                
                wr_en_i(i) <= wr_en when to_integer(unsigned(wr_buff)) = i else '0';
                wr_done_i(i) <= wr_done when to_integer(unsigned(wr_buff)) = i else '0';
                
                rd_en_i(i) <= rd_en when rd_buff = i else '0';
        end generate send_gen;
        
        rd_data <= rd_data_i(rd_buff);
        rd_valid <= rd_valid_i(rd_buff);
        
        process (rd_clk)
                variable tmp_buff : integer range 0 to BUFF_COUNT - 1;
        begin
                if rising_edge(rd_clk) then
                        if rd_valid_i(rd_buff) = '0' then
                                for i in 0 to BUFF_COUNT - 1 loop
                                        tmp_buff := (i + rd_buff) mod BUFF_COUNT;
                                        
                                        if rd_valid_i(tmp_buff) = '1' then
                                                rd_buff <= tmp_buff;
                                                exit;
                                        end if;
                                end loop;
                        end if;
                end if;
        end process;
end arch;