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/] [synch_fifos/] [1.0/] [vhd/] [fifo_casev5.vhd] - Rev 145

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- File        : fifo_casev5.vhdl
-- Description : Fifo buffer for hibi interface
-- Author      : Ari Kulmala
-- Date        : 10.06.2003
-- Modified    : 18.06.2003 - Re-wrote the way output control signals are
--                            assigned
--
--
-- Detailed description:
-- -Input and Output always from the same register
--   -> input-buffer is shifted whenever write occurs
--   -> when read, a mux chooses which value to load to the output next
--      (the oldest)
--
-- !NOTE! isn't tested as one-length FIFO. doesn't probably work. (vector
-- length (1 downto 2) ...
--
-- !NOTE!
-- * Output is zero when empty.
-------------------------------------------------------------------------------
 
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
 
 
entity fifo is
 
  generic (
    width : integer := 0;
    depth : integer := 0);
 
  port (
    Clk            : in  std_logic;
    Rst_n          : in  std_logic;     -- Active low
    Data_In        : in  std_logic_vector (width-1 downto 0);
    Write_Enable   : in  std_logic;
    One_Place_Left : out std_logic;
    Full           : out std_logic;
    Data_Out       : out std_logic_vector (width-1 downto 0);
    Read_Enable    : in  std_logic;
    Empty          : out std_logic;
    One_Data_Left  : out std_logic
    );
 
end fifo;
 
 
architecture behavioral of fifo is
 
  -- range is this so that one can use data_amount directly to indexing
  type reg is array (depth downto 2) of std_logic_vector
    (width-1 downto 0);
  signal input_buffer       : reg;
  -- Registers
  signal Full_reg           : std_logic;
  signal Empty_reg          : std_logic;
  signal One_Data_Left_reg  : std_logic;
  signal One_Place_Left_reg : std_logic;
  signal Data_amount        : integer range 0 to depth;
 
 
  signal WR : std_logic_vector ( 1 downto 0);
 
begin  -- behavioral
 
  -- Continuous assignments
  -- Assigns register values to outputs
  Full           <= Full_reg;
  Empty          <= Empty_reg;
  One_Data_Left  <= One_Data_Left_reg;
  One_Place_Left <= One_Place_Left_reg;
  -- Concurrent assignment
  WR <= Write_Enable & Read_Enable;
 
 
 
  process (Clk, rst_n)
  begin  -- process
    if rst_n = '0' then                   -- asynchronous reset (active low)
      for i in depth downto 2 loop
        input_buffer(i) <= (others => '0');
      end loop;  -- i
      Data_out           <= (others => '0');
 
      Data_Amount        <= 0;
      Empty_reg          <= '1';
      One_Data_Left_reg  <= '0';
      One_Place_Left_reg <= '0';
      Full_reg           <= '0';
 
    elsif Clk'event and Clk = '1' then    -- rising clock edge
 
      case WR is
        when "01"                        =>
          -- Read data
          if Data_amount = 0 then
            -- empty
            Data_amount       <= Data_amount;
            Empty_reg         <= '1';
            One_Data_Left_reg <= '0';
          elsif Data_amount = 1 then
            -- 1 data
            Data_out          <= (others => '0');
            Data_amount       <= Data_amount-1;
            Empty_reg         <= '1';
            One_Data_Left_reg <= '0';
          elsif Data_amount = 2 then
            Data_out          <= input_buffer(Data_amount);
            Data_amount       <= Data_amount-1;
            Empty_reg         <= '0';
            One_Data_Left_reg <= '1';
          else
            Data_out          <= input_buffer(Data_amount);
            Data_amount       <= Data_amount-1;
            One_Data_Left_reg <= '0';
            Empty_reg         <= '0';
          end if;
 
          -- Fifo's getting emptier          
          if Data_amount = depth-1 then
            One_Place_Left_reg <= '0';
            Full_reg           <= '0';
          elsif Data_amount = depth then
            One_Place_Left_reg <= '1';
            Full_reg           <= '0';
          else
            One_Place_Left_reg <= '0';
            Full_reg           <= '0';
          end if;
 
 
        when "10" =>
          -- Write Data
          if Data_amount = 0 then
            Data_out            <= Data_In;
            Data_amount         <= Data_amount+1;
          elsif Data_amount = depth then
            input_buffer        <= input_buffer;
          else
            for i in depth-1 downto 2 loop
              input_buffer(i+1) <= input_buffer(i);
            end loop;  -- i
            input_buffer(2)     <= Data_In;
            Data_amount         <= Data_amount+1;
          end if;
 
          -- define the values for output control signals          
          if Data_amount = 0 then 
            Empty_reg          <= '0';
            One_Data_Left_reg  <= '1';
            Full_reg           <= '0';
            One_Place_Left_reg <= '0';
          elsif Data_amount = 1 then  
            Empty_reg          <= '0';
            One_Data_Left_reg  <= '0';
            Full_reg           <= '0';
            One_Place_Left_reg <= '0';
          elsif Data_amount = depth-2 then
            Empty_reg          <= '0';
            One_Data_Left_reg  <= '0';
            Full_reg           <= '0';
            One_Place_Left_reg <= '1';
          elsif Data_amount = depth-1 then
            Empty_reg          <= '0';
            One_Data_Left_reg  <= '0';
            Full_reg           <= '1';
            One_Place_Left_reg <= '0';
          else
            Empty_reg          <= Empty_reg;
            One_Data_Left_reg  <= One_Data_Left_reg;
            Full_reg           <= Full_reg;
            One_Place_Left_reg <= One_Place_Left_reg;
          end if;
 
        when "11" =>
          -- Read and Write concurrently
 
          if Data_amount = 0 then
            -- can only write
            Data_out           <= Data_in;
            Empty_reg          <= '0';
            One_Data_Left_reg  <= '1';
            Full_reg           <= '0';
            One_Place_Left_reg <= '0';
            Data_amount <= Data_amount+1;
 
          elsif Data_amount = 1 then
            Data_out           <= Data_In;
            Empty_reg          <= '0';
            One_Data_Left_reg  <= '1';
            Full_reg           <= '0';
            One_Place_Left_reg <= '0';
 
          elsif Data_amount = depth then
            -- cannot write if full, just read
            Data_out            <= input_buffer (Data_amount);
            Data_amount         <= Data_amount-1;
            Empty_reg           <= '0';
            One_Data_Left_reg   <= '0';
            Full_reg            <= '0';
            One_Place_Left_reg  <= '1';
          else
            Data_out            <= input_buffer (Data_amount);
            for i in depth-1 downto 2 loop
              input_buffer(i+1) <= input_buffer(i);
            end loop;  -- i
            input_buffer(2)     <= Data_In;
            Empty_reg           <= Empty_reg;
            One_Data_Left_reg   <= One_Data_Left_reg;
            Full_reg            <= Full_reg;
            One_Place_Left_reg  <= One_Place_Left_reg;
          end if;
 
        when others =>
          -- Do nothing, write and read low
          input_buffer       <= input_buffer;
          Data_amount        <= Data_amount;
          Empty_reg          <= Empty_reg;
          One_Data_Left_reg  <= One_Data_Left_reg;
          Full_reg           <= Full_reg;
          One_Place_Left_reg <= One_Place_Left_reg;
 
      end case;
    end if; --synchronous
  end process;
 
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.