OpenCores
URL https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.storage/] [fifos/] [fifo/] [1.0/] [vhd/] [fifo.vhd] - Rev 145

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- File        : fifo.vhdl
-- Description : General fifo buffer
-- Author      : Erno Salminen
-- e-mail      : erno.salminen@tut.fi
-- Project     : 
-- Design      : 
-- Date        : 29.04.2002
-- Modified    : 30.04.2002 Vesa Lahtinen Optimized for synthesis
--
-- 15.12.04     ES: names changed
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--  This file is part of Transaction Generator.
--
--  Transaction Generator is free software: you can redistribute it and/or modify
--  it under the terms of the Lesser GNU General Public License as published by
--  the Free Software Foundation, either version 3 of the License, or
--  (at your option) any later version.
--
--  Transaction Generator is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--  Lesser GNU General Public License for more details.
--
--  You should have received a copy of the Lesser GNU General Public License
--  along with Transaction Generator.  If not, see <http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
entity fifo is
 
  generic (
    data_width_g :    integer := 32;
    depth_g      :    integer := 5
    );
  port (
    clk          : in std_logic;
    rst_n        : in std_logic;
 
    data_in   : in  std_logic_vector (data_width_g-1 downto 0);
    we_in     : in  std_logic;
    full_out  : out std_logic;
    one_p_out : out std_logic;
 
    re_in     : in  std_logic;
    data_out  : out std_logic_vector (data_width_g-1 downto 0);
    empty_out : out std_logic;
    one_d_out : out std_logic
    );
 
end fifo;
 
architecture behavioral of fifo is
 
 
  -- Registers
  signal full_r        : std_logic;
  signal empty_r       : std_logic;
  signal one_d_r       : std_logic;
  signal one_p_r       : std_logic;
  --signal data_amount_r : std_logic_vector (depth_g-1 downto 0);
  signal data_amount_r : std_logic_vector (16-1 downto 0);
 
  signal in_ptr_r  : integer range 0 to depth_g-1;
  signal out_ptr_r : integer range 0 to depth_g-1;
 
  type data_arr_type is array (depth_g-1 downto 0) of std_logic_vector (data_width_g-1 downto 0);
  signal fifo_buffer_r : data_arr_type;
 
 
begin  -- behavioral
 
  -- Continuous assignments
  -- Assigns register values to outputs
  full_out  <= full_r;
  empty_out <= empty_r;
  one_d_out <= one_d_r;
  one_p_out <= one_p_r;
  data_out  <= fifo_buffer_r (out_ptr_r);   -- mux at output!
  -- Note! There is some old value in data output when fifo is empty.
 
 
Main : process (clk, rst_n)
begin  -- process Main
  if rst_n = '0' then                   -- asynchronous reset (active low)
 
    -- Reset all registers
    -- Fifo is empty at first
    full_r        <= '0';
    empty_r       <= '1';
    one_d_r       <= '0';
    in_ptr_r      <= 0;
    out_ptr_r     <= 0;
    data_amount_r <= (others => '0');
 
    if depth_g =1 then                    -- 30.07
      one_p_r <= '1';
    else
      one_p_r <= '0';      
    end if;
 
    for i in 0 to depth_g-1 loop
      fifo_buffer_r (i) <= (others => '0');
    end loop;  -- i
 
  elsif clk'event and clk = '1' then    -- rising clock edge
 
 
    -- 1) Write data to fifo
    if we_in = '1' and re_in = '0' then
 
      if full_r = '0' then
        empty_r                <= '0';
        if (in_ptr_r = (depth_g-1)) then
          in_ptr_r               <= 0;
        else
          in_ptr_r               <= in_ptr_r + 1;
        end if;
        out_ptr_r                <= out_ptr_r;
        data_amount_r          <= data_amount_r +1;
        fifo_buffer_r (in_ptr_r) <= data_in;
 
        -- Check if the fifo is getting full
        if data_amount_r + 2 = depth_g then
          full_r  <= '0';
          one_p_r <= '1';
        elsif data_amount_r +1 = depth_g then
          full_r  <= '1';
          one_p_r <= '0';
        else
          full_r  <= '0';
          one_p_r <= '0';
        end if;
 
        -- If fifo was empty, it has now one data 
        if empty_r = '1' then
          one_d_r <= '1';
        else
          one_d_r <= '0';
        end if;
 
      else
--         in_ptr_r      <= in_ptr_r;
--         out_ptr_r     <= out_ptr_r;
--         full_r        <= full_r;
--         empty_r       <= empty_r;
--         fifo_buffer_r <= fifo_buffer_r;
--         data_amount_r <= data_amount_r;
--         one_d_r       <= one_d_r;
--         one_p_r       <= one_p_r;
      end if;
 
 
    -- 2) Read data from fifo  
    elsif we_in = '0' and re_in = '1' then
 
      if empty_r = '0' then
        in_ptr_r        <= in_ptr_r;
        if (out_ptr_r = (depth_g-1)) then
          out_ptr_r     <= 0;
        else
          out_ptr_r     <= out_ptr_r + 1;
        end if;
        full_r        <= '0';
        data_amount_r <= data_amount_r -1;
 
        -- Debug
        -- fifo_buffer_r (out_ptr_r) <= (others => '1');
 
        -- Check if the fifo is getting empty
        if data_amount_r = 2 then
          empty_r <= '0';
          one_d_r <= '1';
        elsif data_amount_r = 1 then
          empty_r <= '1';
          one_d_r <= '0';
        else
          empty_r <= '0';
          one_d_r <= '0';
        end if;
 
        -- If fifo was full, it is no more 
        if full_r = '1' then
          one_p_r <= '1';
        else
          one_p_r <= '0';
        end if;
 
      else
--         in_ptr_r      <= in_ptr_r;
--         out_ptr_r     <= out_ptr_r;
--         full_r        <= full_r;
--         empty_r       <= empty_r;
--         fifo_buffer_r <= fifo_buffer_r;
--         data_amount_r <= data_amount_r;
--         one_d_r       <= one_d_r;
--         one_p_r       <= one_p_r;
      end if;
 
 
    -- 3) Write and read at the same time  
    elsif we_in = '1' and re_in = '1' then
 
 
      if full_r = '0' and empty_r = '0' then
        if (in_ptr_r = (depth_g-1)) then
          in_ptr_r    <= 0;
        else
          in_ptr_r    <= in_ptr_r + 1;
        end if;
        if (out_ptr_r = (depth_g-1)) then
          out_ptr_r   <= 0;
        else
          out_ptr_r   <= out_ptr_r + 1;
        end if;
        full_r        <= '0';
        empty_r       <= '0';
        data_amount_r <= data_amount_r;
        one_d_r       <= one_d_r;
        one_p_r       <= one_p_r;
 
        fifo_buffer_r (in_ptr_r)  <= data_in;
        -- fifo_buffer_r (out_ptr_r) <= (others => '1');  --debug
 
 
      elsif full_r = '1' and empty_r = '0' then
        -- Fifo is full, only reading is possible
        in_ptr_r        <= in_ptr_r;
        if (out_ptr_r = (depth_g-1)) then
          out_ptr_r     <= 0;
        else
          out_ptr_r     <= out_ptr_r + 1;
        end if;
        full_r        <= '0';
        one_p_r       <= '1';
        --fifo_buffer_r (out_ptr_r) <= (others => '1');  -- Debug
        data_amount_r <= data_amount_r -1;
 
        -- Check if the fifo is getting empty
        if data_amount_r = 2 then
          empty_r <= '0';
          one_d_r <= '1';
        elsif data_amount_r = 1 then
          empty_r <= '1';
          one_d_r <= '0';
        else
          empty_r <= '0';
          one_d_r <= '0';
        end if;
 
 
      elsif full_r = '0' and empty_r = '1' then
        -- Fifo is empty, only writing is possible
        if (in_ptr_r = (depth_g-1)) then
          in_ptr_r               <= 0;
        else
          in_ptr_r               <= in_ptr_r + 1;
        end if;
        out_ptr_r                <= out_ptr_r;
        empty_r                  <= '0';
        one_d_r                  <= '1';
        fifo_buffer_r (in_ptr_r) <= data_in;
        data_amount_r            <= data_amount_r +1;
 
        -- Check if the fifo is getting full
        if data_amount_r + 2 = depth_g then
          full_r  <= '0';
          one_p_r <= '1';
        elsif data_amount_r +1 = depth_g then
          full_r  <= '1';
          one_p_r <= '0';
        else
          full_r  <= '0';
          one_p_r <= '0';
        end if;
 
 
      -- 4) Do nothing, fifo remains idle 
      else
 
--         in_ptr_r      <= in_ptr_r;
--         out_ptr_r     <= out_ptr_r;
--         full_r        <= full_r;
--         empty_r       <= empty_r;
--         fifo_buffer_r <= fifo_buffer_r;
--         data_amount_r <= data_amount_r;
--         one_d_r       <= one_d_r;
--         one_p_r       <= one_p_r;
      end if;
 
    else
      -- Fifo is idle
--       in_ptr_r      <= in_ptr_r;
--       out_ptr_r     <= out_ptr_r;
--       full_r        <= full_r;
--       empty_r       <= empty_r;
--       fifo_buffer_r <= fifo_buffer_r;
--       data_amount_r <= data_amount_r;
--       one_d_r       <= one_d_r;
--       one_p_r       <= one_p_r;
    end if;
 
  end if;
end process Main;
 
end behavioral;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.