use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
+--------------------------------------------------------------------------------
+-- This is a behavioral model of FIFO (Fisrt In First Out) memory.
+--
+-- All operations (except for reset) are synchronous to 'clk' rising edges.
+-- Reset makes fifo empty but actually does not change the content of memory.
+--
+-- The generic parameter 'width' determines the width of address vector used to
+-- access memory and so the size of memory.
+--
+-- When overflow occurs, the 'overflow' flag is set to 1 and the least recent
+-- data is rewritten by new data.
+--
+-- Underflow is not handled currently and causes misfunction.
+--------------------------------------------------------------------------------
+
entity fifo is
generic (
width : integer := 2
port (
clk : in std_logic;
reset : in std_logic;
- we : in std_logic;
- re : in std_logic;
+ we : in std_logic; -- write enable
+ re : in std_logic; -- read enable
+ clear_ow : in std_logic; -- clear overflow flag
d_in : in std_logic_vector (7 downto 0);
d_out : out std_logic_vector (7 downto 0);
- full : out std_logic;
- hfull : out std_logic;
- empty : out std_logic;
- overflow : out std_logic
+ full : out std_logic; -- fifo is full
+ hfull : out std_logic; -- fifo is half full
+ empty : out std_logic; -- fifo is empty
+ overflow : out std_logic := '0'
);
end fifo;
signal memory : mem_t;
- signal read_addr : mem_addr_t;
- signal write_addr : mem_addr_t;
+ signal read_addr : mem_addr_t := (others => '0');
+ signal write_addr : mem_addr_t := (others => '0');
- signal length : std_logic_vector (width downto 0);
+ signal length : std_logic_vector (width downto 0) := (others => '0');
signal full_s : std_logic;
begin
+ -- Handling of overflow output signal and internal length signal, storing
+ -- the number of occupied memory positions.
process (clk, reset)
begin
- if (reset = '1') then
- length <= (others => '0');
- overflow <= '0';
-
- elsif (rising_edge(clk)) then
- if ((re = '1') and (we = '0')) then
- length <= length - 1;
- elsif ((re = '0') and (we = '1')) then
- if (full_s = '1') then
- overflow <= '1';
- else
- length <= length + 1;
+ if (rising_edge(clk)) then
+ if (reset = '1') then
+ length <= (others => '0');
+ overflow <= '0';
+
+ else
+ if ((re = '1') and (we = '0')) then
+ length <= length - 1;
+ elsif ((re = '0') and (we = '1')) then
+ if (full_s = '1') then
+ overflow <= '1';
+ else
+ length <= length + 1;
+ end if;
+ end if;
+
+ if (clear_ow = '1') then
+ overflow <= '0';
end if;
end if;
end if;
end process;
+ -- Handling of address registers and writing to memory.
process (clk, reset)
begin
if (reset = '1') then