/Designs/HAM Constructions/SDRX02B/HDL/project_src/multiplexer_from_fifos.vhd
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;