library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity fifo is generic ( DEPTH : positive := 1024 ); port ( aclr : in std_logic; clock : in std_logic; sclr : in std_logic; data : in std_logic_vector( 31 downto 0 ); rdreq : in std_logic; wrreq : in std_logic; empty : out std_logic; full : out std_logic; q : out std_logic_vector( 31 downto 0 ); usedw : out std_logic_vector( 9 downto 0 ) ); end entity fifo; architecture rtl of fifo is type Operation is ( OPERATION_IDLE, OPERATION_CLEAR, OPERATION_READ, OPERATION_WRITE, OPERATION_READ_WRITE ); signal is_empty : boolean; signal is_full : boolean; signal is_read : boolean; signal is_write : boolean; signal is_read_write : boolean; signal next_operation : Operation; signal fifo_data : work.reg32.RegArray( 0 to DEPTH - 1 ); signal write_index : integer range 0 to DEPTH - 1; signal read_index : integer range 0 to DEPTH - 1; signal item_count : integer range 0 to DEPTH; function increment_with_overflow( value : integer; max : integer ) return integer is begin if ( value < max - 1 ) then return value + 1; end if; return 0; end function increment_with_overflow; begin c_is_empty: is_empty <= item_count = 0; c_is_full: is_full <= item_count = DEPTH; c_is_read: is_read <= rdreq = '1' and not is_empty; c_is_write: is_write <= wrreq = '1' and not is_full; c_is_read_write: is_read_write <= is_read and is_write; c_next_operation: next_operation <= OPERATION_CLEAR when sclr else OPERATION_READ_WRITE when is_read_write else OPERATION_READ when is_read else OPERATION_WRITE when is_write else OPERATION_IDLE; sync: process( clock, aclr ) is begin if ( aclr = '1' ) then write_index <= 0; read_index <= 0; item_count <= 0; elsif ( rising_edge( clock ) ) then case next_operation is when OPERATION_IDLE => null; when OPERATION_CLEAR => write_index <= 0; read_index <= 0; item_count <= 0; when OPERATION_READ => item_count <= item_count - 1; read_index <= increment_with_overflow( read_index, DEPTH ); when OPERATION_WRITE => fifo_data( write_index ) <= data; item_count <= item_count + 1; write_index <= increment_with_overflow( write_index, DEPTH ); when OPERATION_READ_WRITE => read_index <= increment_with_overflow( read_index, DEPTH ); fifo_data( write_index ) <= data; write_index <= increment_with_overflow( write_index, DEPTH ); end case; end if; end process; c_assign_q: q <= data when ( is_empty and is_write ) else fifo_data( read_index ); c_assign_usedw: usedw <= std_logic_vector( to_unsigned( item_count, usedw'length ) ); full <= '1' when is_full else '0'; empty <= '1' when is_empty else '0'; end architecture rtl;