Rev Author Line No. Line
3641 kaklik 1 --------------------------------------------
2 -- Multiplexer from FIFOs
3 --
4 -- Waits until all i_valid signals are asserted. Then, if i_full == '0', cycles through all inputs and puts them to output.
5 -- If at that time i_full == '1', all the inputs are discarded.
6  
7 library ieee;
8 use ieee.std_logic_1164.all;
9  
10  
11 entity multiplexer_from_fifos is
12 generic
13 ( G_NUM_CHANNELS : natural := 2; -- number of channels
14 G_DATA_WIDTH : natural := 32 -- data width of individual packets
15 );
16 port (
17  
18 clk : in std_logic;
19 rst : in std_logic;
20  
21 -- input side
22 i_data : in std_logic_vector( G_DATA_WIDTH*G_NUM_CHANNELS - 1 downto 0 );
23 i_valid : in std_logic_vector( G_NUM_CHANNELS - 1 downto 0 );
24 o_rden : out std_logic_vector( G_NUM_CHANNELS - 1 downto 0 );
25  
26 -- output side
27 o_data : out std_logic_vector( G_DATA_WIDTH - 1 downto 0 );
28 o_valid : out std_logic;
29 i_full : in std_logic
30  
31 );
32 end multiplexer_from_fifos;
33  
34 architecture behavioral of multiplexer_from_fifos is
35  
36 subtype t_counter is natural range 0 to G_NUM_CHANNELS;
37 signal s_counter : t_counter := 0;
38  
39 signal s_all_i_valid : std_logic;
40 signal s_drop_data : std_logic;
41  
42 begin
43  
44 assert( G_NUM_CHANNELS > 1 ) report "The number of channels must be higher than 1." severity failure;
45  
46 s_all_i_valid <= '1' when i_valid = ( i_valid'range => '1' ) else
47 '0';
48  
49  
50 counter_process : process( clk )
51 begin
52 if( rising_edge( clk ) ) then
53 s_drop_data <= '0';
54 if( rst = '1' ) then
55 -- reset
56 s_counter <= 0;
57 elsif( s_counter = 0 and s_all_i_valid = '1' and i_full = '0' and s_drop_data = '0' ) then
58 -- counter is stopped, i_data have new data and the following FIFO is ready to receive.
59 -- start the counter.
60 s_counter <= 1;
61 elsif( s_counter = 0 and s_all_i_valid = '1' and i_full = '1' ) then
62 -- discard the complete set of data because the following FIFO is full.
63 s_drop_data <= '1';
64 elsif( s_counter > 0 and s_counter < t_counter'high ) then
65 -- the counter is running and is somewhere in between, just increase the value.
66 s_counter <= s_counter + 1;
67 elsif( s_counter = t_counter'high and s_all_i_valid = '1' and i_full = '0' ) then
68 -- the counter has reached maximum value and there are new data waiting
69 -- start the counter right away
70 s_counter <= 1;
71 else
72 -- stop the counter
73 s_counter <= 0;
74 end if;
75 end if;
76 end process;
77  
78 ----------------------------------------------
79 -- OUTPUT SIGNALS:
80 o_data <= i_data( G_DATA_WIDTH*s_counter - 1 downto G_DATA_WIDTH*s_counter - G_DATA_WIDTH ) when s_counter > 0 and rst = '0' else
81 ( others => '0' );
82 o_valid <= i_valid( s_counter - 1 ) when s_counter > 0 and rst = '0' else
83 '0';
84 o_rden_gen : for i in 0 to G_NUM_CHANNELS - 1 generate
85 o_rden(i) <= '1' when ( s_counter = i + 1 or s_drop_data = '1' ) and i_valid(i) = '1' else
86 '0';
87 end generate;
88 ----------------------------------------------
89  
90  
91 end architecture;
92