0,0 → 1,92 |
-------------------------------------------- |
-- Multiplexer from FIFOs |
-- |
-- Waits until all i_valid signals are asserted. Then, if i_full == '0', cycles through all inputs and puts them to output. |
-- If at that time i_full == '1', all the inputs are discarded. |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
|
entity multiplexer_from_fifos is |
generic |
( G_NUM_CHANNELS : natural := 2; -- number of channels |
G_DATA_WIDTH : natural := 32 -- data width of individual packets |
); |
port ( |
|
clk : in std_logic; |
rst : in std_logic; |
|
-- input side |
i_data : in std_logic_vector( G_DATA_WIDTH*G_NUM_CHANNELS - 1 downto 0 ); |
i_valid : in std_logic_vector( G_NUM_CHANNELS - 1 downto 0 ); |
o_rden : out std_logic_vector( G_NUM_CHANNELS - 1 downto 0 ); |
|
-- output side |
o_data : out std_logic_vector( G_DATA_WIDTH - 1 downto 0 ); |
o_valid : out std_logic; |
i_full : in std_logic |
|
); |
end multiplexer_from_fifos; |
|
architecture behavioral of multiplexer_from_fifos is |
|
subtype t_counter is natural range 0 to G_NUM_CHANNELS; |
signal s_counter : t_counter := 0; |
|
signal s_all_i_valid : std_logic; |
signal s_drop_data : std_logic; |
|
begin |
|
assert( G_NUM_CHANNELS > 1 ) report "The number of channels must be higher than 1." severity failure; |
|
s_all_i_valid <= '1' when i_valid = ( i_valid'range => '1' ) else |
'0'; |
|
|
counter_process : process( clk ) |
begin |
if( rising_edge( clk ) ) then |
s_drop_data <= '0'; |
if( rst = '1' ) then |
-- reset |
s_counter <= 0; |
elsif( s_counter = 0 and s_all_i_valid = '1' and i_full = '0' and s_drop_data = '0' ) then |
-- counter is stopped, i_data have new data and the following FIFO is ready to receive. |
-- start the counter. |
s_counter <= 1; |
elsif( s_counter = 0 and s_all_i_valid = '1' and i_full = '1' ) then |
-- discard the complete set of data because the following FIFO is full. |
s_drop_data <= '1'; |
elsif( s_counter > 0 and s_counter < t_counter'high ) then |
-- the counter is running and is somewhere in between, just increase the value. |
s_counter <= s_counter + 1; |
elsif( s_counter = t_counter'high and s_all_i_valid = '1' and i_full = '0' ) then |
-- the counter has reached maximum value and there are new data waiting |
-- start the counter right away |
s_counter <= 1; |
else |
-- stop the counter |
s_counter <= 0; |
end if; |
end if; |
end process; |
|
---------------------------------------------- |
-- OUTPUT SIGNALS: |
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 |
( others => '0' ); |
o_valid <= i_valid( s_counter - 1 ) when s_counter > 0 and rst = '0' else |
'0'; |
o_rden_gen : for i in 0 to G_NUM_CHANNELS - 1 generate |
o_rden(i) <= '1' when ( s_counter = i + 1 or s_drop_data = '1' ) and i_valid(i) = '1' else |
'0'; |
end generate; |
---------------------------------------------- |
|
|
end architecture; |
|