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] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : fifo
3
-- Project    : 
4
-------------------------------------------------------------------------------
5
-- File       : fifo_ram.vhd
6
-- Author     : 
7
-- Company    : 
8
-- Created    : 2005-05-26
9
-- Last update: 2005-05-31
10
-- Platform   : 
11
-- Standard   : VHDL'87
12
-------------------------------------------------------------------------------
13
-- Description: fifo implemented with dual port RAM with asynchronous read
14
-------------------------------------------------------------------------------
15
-- Copyright (c) 2005 
16
-------------------------------------------------------------------------------
17
-- Revisions  :
18
-- Date        Version  Author  Description
19
-- 2005-05-26  1.0      penttin5        Created
20
-------------------------------------------------------------------------------
21
--
22
-- NOTE! Precision RTL synthesisis 2004c.45 doesn't infer the RAM with
23
--       asynchronous read for Stratix 1 S40F780C5.
24
--       Quartus II 4.2 infers RAM with asynchronic read but gives old RAM value
25
--       when reading and writing simultaneusly to/from same address.
26
--       That doesn't matter because FIFO doesn't read and write in the same
27
--       address at the same time.
28
--
29
-------------------------------------------------------------------------------
30
 
31
library ieee;
32
use ieee.std_logic_1164.all;
33
use ieee.std_logic_arith.all;
34
use ieee.std_logic_unsigned.all;
35
 
36
entity fifo is
37
 
38
  generic (
39
    data_width_g : integer := 0;
40
    depth_g      : integer := 0
41
    );
42
 
43
  port (
44
    clk       : in  std_logic;
45
    rst_n     : in  std_logic;
46
    data_in   : in  std_logic_vector (data_width_g-1 downto 0);
47
    we_in     : in  std_logic;
48
    one_p_out : out std_logic;
49
    full_out  : out std_logic;
50
    data_out  : out std_logic_vector (data_width_g-1 downto 0);
51
    re_in     : in  std_logic;
52
    empty_out : out std_logic;
53
    one_d_out : out std_logic
54
    );
55
 
56
end fifo;
57
 
58
architecture rtl of fifo is
59
 
60
  component dual_ram_async_read
61
    generic (
62
      ram_width : integer := 0;
63
      ram_depth : integer := 0);
64
    port
65
      (
66
        clock1        : in  std_logic;
67
        clock2        : in  std_logic;
68
        data          : in  std_logic_vector(0 to ram_width - 1);
69
        write_address : in  integer range 0 to ram_depth - 1;
70
        read_address  : in  integer range 0 to ram_depth - 1;
71
        we            : in  std_logic;
72
        q             : out std_logic_vector(0 to ram_width - 1)
73
        );
74
  end component;  -- dual_ram_async_read
75
 
76
  signal write_address_r    : integer range 0 to depth_g - 1;
77
  signal read_address_r     : integer range 0 to depth_g - 1;
78
  signal write_read_count_r : integer range 0 to depth_g;
79
  signal ram_data_out_i     : std_logic_vector(0 to data_width_g - 1);
80
  signal we_ram             : std_logic;
81
  attribute dont_touch : boolean;
82
  attribute dont_touch of gen_dual_ram: label is true;
83
begin  -- rtl
84
 
85
  gen_dual_ram : dual_ram_async_read
86
    generic map (
87
      ram_width => data_width_g,
88
      ram_depth => depth_g
89
      )
90
    port map (
91
      clock1        => clk,
92
      clock2        => clk,
93
      data          => data_in,
94
      write_address => write_address_r,
95
      read_address  => read_address_r,
96
      we            => we_ram,
97
      q             => ram_data_out_i
98
      );
99
 
100
  -- write to fifo when write enabled and fifo not full
101
  we_ram <= we_in when write_read_count_r /= depth_g
102
            else '0';
103
 
104
  data_out <= ram_data_out_i;
105
 
106
  one_d_out <= '1' when write_read_count_r = 1 else
107
               '0';
108
  one_p_out <= '1' when write_read_count_r = depth_g - 1 else
109
               '0';
110
  empty_out <= '1' when write_read_count_r = 0 else
111
               '0';
112
  full_out <= '1' when write_read_count_r = depth_g else
113
              '0';
114
 
115
  -----------------------------------------------------------------------------
116
  -- Update read and write addresses
117
  -----------------------------------------------------------------------------
118
  fifo_read_and_write : process (clk, rst_n)
119
 
120
  begin  -- process fifo_read_and_write
121
 
122
    if rst_n = '0' then                 -- asynchronous reset (active low)
123
      write_read_count_r <= 0;
124
      read_address_r     <= 0;
125
      write_address_r    <= 0;
126
    elsif clk'event and clk = '1' then  -- rising clock edge
127
 
128
      -- read if re_in = '1' and fifo not empty or
129
      --         simultaneus read and write and fifo full
130
      if re_in = '1' and ((we_in = '0' and write_read_count_r /= 0)
131
                          or (we_in = '1' and write_read_count_r = depth_g)) then
132
        write_read_count_r <= write_read_count_r - 1;
133
        if read_address_r = depth_g - 1 then
134
          read_address_r <= 0;
135
        else
136
          read_address_r <= read_address_r + 1;
137
        end if;
138
        write_address_r <= write_address_r;
139
 
140
      -- write if we_in = '1' and fifo not full or
141
      --          simultaneus read and write and fifo empty
142
      elsif we_in = '1' and ((re_in = '0' and write_read_count_r /= depth_g)
143
                             or (re_in = '1' and write_read_count_r = 0)) then
144
        write_read_count_r <= write_read_count_r + 1;
145
        read_address_r     <= read_address_r;
146
        if write_address_r = depth_g - 1 then
147
          write_address_r <= 0;
148
        else
149
          write_address_r <= write_address_r + 1;
150
        end if;
151
 
152
      -- write and read at the same time if re_in = '1' and we_in = '1' and
153
      -- fifo not empty or full
154
      elsif re_in = '1' and we_in = '1' and write_read_count_r /= depth_g and write_read_count_r /= 0 then
155
        write_read_count_r <= write_read_count_r;
156
        if read_address_r = depth_g - 1 then
157
          read_address_r <= 0;
158
        else
159
          read_address_r <= read_address_r + 1;
160
        end if;
161
        if write_address_r = depth_g - 1 then
162
          write_address_r <= 0;
163
        else
164
          write_address_r <= write_address_r + 1;
165
        end if;
166
      else
167
        write_read_count_r <= write_read_count_r;
168
        read_address_r     <= read_address_r;
169
        write_address_r    <= write_address_r;
170
      end if;
171
    end if;
172
  end process fifo_read_and_write;
173
 
174
end rtl;

powered by: WebSVN 2.1.0

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