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 |
|