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_ram.vhd] - Rev 145

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- Title      : fifo
-- Project    : 
-------------------------------------------------------------------------------
-- File       : fifo_ram.vhd
-- Author     : 
-- Company    : 
-- Created    : 2005-05-26
-- Last update: 2005-05-31
-- Platform   : 
-- Standard   : VHDL'87
-------------------------------------------------------------------------------
-- Description: fifo implemented with dual port RAM with asynchronous read
-------------------------------------------------------------------------------
-- Copyright (c) 2005 
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2005-05-26  1.0      penttin5        Created
-------------------------------------------------------------------------------
--
-- NOTE! Precision RTL synthesisis 2004c.45 doesn't infer the RAM with
--       asynchronous read for Stratix 1 S40F780C5.
--       Quartus II 4.2 infers RAM with asynchronic read but gives old RAM value
--       when reading and writing simultaneusly to/from same address.
--       That doesn't matter because FIFO doesn't read and write in the same
--       address at the same time.
--
-------------------------------------------------------------------------------
 
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 := 0;
    depth_g      : integer := 0
    );
 
  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;
    one_p_out : out std_logic;
    full_out  : out std_logic;
    data_out  : out std_logic_vector (data_width_g-1 downto 0);
    re_in     : in  std_logic;
    empty_out : out std_logic;
    one_d_out : out std_logic
    );
 
end fifo;
 
architecture rtl of fifo is
 
  component dual_ram_async_read
    generic (
      ram_width : integer := 0;
      ram_depth : integer := 0);
    port
      (
        clock1        : in  std_logic;
        clock2        : in  std_logic;
        data          : in  std_logic_vector(0 to ram_width - 1);
        write_address : in  integer range 0 to ram_depth - 1;
        read_address  : in  integer range 0 to ram_depth - 1;
        we            : in  std_logic;
        q             : out std_logic_vector(0 to ram_width - 1)
        );
  end component;  -- dual_ram_async_read
 
  signal write_address_r    : integer range 0 to depth_g - 1;
  signal read_address_r     : integer range 0 to depth_g - 1;
  signal write_read_count_r : integer range 0 to depth_g;
  signal ram_data_out_i     : std_logic_vector(0 to data_width_g - 1);
  signal we_ram             : std_logic;
  attribute dont_touch : boolean;
  attribute dont_touch of gen_dual_ram: label is true;
begin  -- rtl
 
  gen_dual_ram : dual_ram_async_read
    generic map (
      ram_width => data_width_g,
      ram_depth => depth_g
      )
    port map (
      clock1        => clk,
      clock2        => clk,
      data          => data_in,
      write_address => write_address_r,
      read_address  => read_address_r,
      we            => we_ram,
      q             => ram_data_out_i
      );
 
  -- write to fifo when write enabled and fifo not full
  we_ram <= we_in when write_read_count_r /= depth_g
            else '0';
 
  data_out <= ram_data_out_i;
 
  one_d_out <= '1' when write_read_count_r = 1 else
               '0';
  one_p_out <= '1' when write_read_count_r = depth_g - 1 else
               '0';
  empty_out <= '1' when write_read_count_r = 0 else
               '0';
  full_out <= '1' when write_read_count_r = depth_g else
              '0';
 
  -----------------------------------------------------------------------------
  -- Update read and write addresses
  -----------------------------------------------------------------------------
  fifo_read_and_write : process (clk, rst_n)
 
  begin  -- process fifo_read_and_write
 
    if rst_n = '0' then                 -- asynchronous reset (active low)
      write_read_count_r <= 0;
      read_address_r     <= 0;
      write_address_r    <= 0;
    elsif clk'event and clk = '1' then  -- rising clock edge
 
      -- read if re_in = '1' and fifo not empty or
      --         simultaneus read and write and fifo full
      if re_in = '1' and ((we_in = '0' and write_read_count_r /= 0)
                          or (we_in = '1' and write_read_count_r = depth_g)) then
        write_read_count_r <= write_read_count_r - 1;
        if read_address_r = depth_g - 1 then
          read_address_r <= 0;
        else
          read_address_r <= read_address_r + 1;
        end if;
        write_address_r <= write_address_r;
 
      -- write if we_in = '1' and fifo not full or
      --          simultaneus read and write and fifo empty
      elsif we_in = '1' and ((re_in = '0' and write_read_count_r /= depth_g)
                             or (re_in = '1' and write_read_count_r = 0)) then
        write_read_count_r <= write_read_count_r + 1;
        read_address_r     <= read_address_r;
        if write_address_r = depth_g - 1 then
          write_address_r <= 0;
        else
          write_address_r <= write_address_r + 1;
        end if;
 
      -- write and read at the same time if re_in = '1' and we_in = '1' and
      -- fifo not empty or full
      elsif re_in = '1' and we_in = '1' and write_read_count_r /= depth_g and write_read_count_r /= 0 then
        write_read_count_r <= write_read_count_r;
        if read_address_r = depth_g - 1 then
          read_address_r <= 0;
        else
          read_address_r <= read_address_r + 1;
        end if;
        if write_address_r = depth_g - 1 then
          write_address_r <= 0;
        else
          write_address_r <= write_address_r + 1;
        end if;
      else
        write_read_count_r <= write_read_count_r;
        read_address_r     <= read_address_r;
        write_address_r    <= write_address_r;
      end if;
    end if;
  end process fifo_read_and_write;
 
end rtl;
 

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.