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