119 lines
3.2 KiB
VHDL
Raw Normal View History

2023-10-31 07:47:27 +01:00
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;