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_dynamic.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_dynamic.vhd
6
-- Author     : 
7
-- Company    : 
8
-- Created    : 2005-05-26
9
-- Last update: 2006-03-02
10
-- Platform   : 
11
-- Standard   : VHDL'87
12
-------------------------------------------------------------------------------
13
-- Description: Fifo w/dynamic depth implemented with dual port RAM
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! generic depth_g is the maximum depth of fifo
23
-- NOTE! Precision RTL synthesisis 2004c.45 doesn't infer the RAM with
24
--       asynchronous read for Stratix 1 S40F780C5.
25
--       Quartus II 4.2 infers RAM with asynchronic read but gives old RAM
26
--       value when reading and writing simultaneusly to/from same address.
27
--       That doesn't matter because FIFO doesn't read and write in the same
28
--       address at the same time.
29
--
30
-------------------------------------------------------------------------------
31
 
32
library ieee;
33
use ieee.std_logic_1164.all;
34
use ieee.std_logic_arith.all;
35
use ieee.std_logic_unsigned.all;
36
 
37
entity fifo is
38
 
39
  generic (
40
    data_width_g : integer := 32;
41
    depth_g      : integer := 10        -- this is the maximum depth of fifo!
42
    );
43
 
44
  port (
45
    clk       : in  std_logic;
46
    rst_n     : in  std_logic;
47
    data_in   : in  std_logic_vector (data_width_g-1 downto 0);
48
    we_in     : in  std_logic;
49
    one_p_out : out std_logic;
50
    full_out  : out std_logic;
51
    data_out  : out std_logic_vector (data_width_g-1 downto 0);
52
    re_in     : in  std_logic;
53
    empty_out : out std_logic;
54
    one_d_out : out std_logic
55
    );
56
 
57
end fifo;
58
 
59
architecture rtl of fifo is
60
 
61
  -- this is the configuration RAM which holds the
62
  -- dynamic depth value at address 0
63
  component conf_ram
64
    port (
65
      address : in  std_logic_vector(3 downto 0);
66
      clock   : in  std_logic;
67
      q       : out std_logic_vector(7 downto 0)
68
      );
69
  end component;
70
 
71
  component dual_ram_async_read
72
    generic (
73
      ram_width : integer := 0;
74
      ram_depth : integer := 0);
75
    port
76
      (
77
        clock1        : in  std_logic;
78
        clock2        : in  std_logic;
79
        data          : in  std_logic_vector(0 to ram_width - 1);
80
        write_address : in  integer range 0 to ram_depth - 1;
81
        read_address  : in  integer range 0 to ram_depth - 1;
82
        we            : in  std_logic;
83
        q             : out std_logic_vector(0 to ram_width - 1)
84
        );
85
  end component;  -- dual_ram_async_read
86
 
87
  signal write_address_r    : integer range 0 to depth_g - 1;
88
  signal read_address_r     : integer range 0 to depth_g - 1;
89
  signal write_read_count_r : integer range 0 to depth_g;
90
  signal ram_data_out_i     : std_logic_vector(0 to data_width_g - 1);
91
  signal we_ram             : std_logic;
92
 
93
  signal conf_ram_addr       : std_logic_vector(3 downto 0);
94
  signal depth_from_conf_ram : std_logic_vector(7 downto 0);
95
  signal dynamic_depth_r     : integer range 0 to depth_g;
96
  signal full_out_r          : std_logic;
97
 
98
begin  -- rtl
99
 
100
  conf_ram_inst : conf_ram
101
    port map (
102
      address => (others => '0'),
103
      clock   => clk,
104
      q       => depth_from_conf_ram
105
      );
106
 
107
  gen_dual_ram : dual_ram_async_read
108
    generic map (
109
      ram_width => data_width_g,
110
      ram_depth => depth_g
111
      )
112
    port map (
113
      clock1        => clk,
114
      clock2        => clk,
115
      data          => data_in,
116
      write_address => write_address_r,
117
      read_address  => read_address_r,
118
      we            => we_ram,
119
      q             => ram_data_out_i
120
      );
121
 
122
  full_out <= full_out_r;
123
  -- write to fifo when write enabled and fifo not full
124
  we_ram <= we_in when full_out_r = '0'--write_read_count_r < dynamic_depth_r
125
            else '0';
126
 
127
  data_out <= ram_data_out_i;
128
 
129
--  one_d_out <= '1' when write_read_count_r = 1 else
130
--               '0';
131
--  one_p_out <= '1' when write_read_count_r = dynamic_depth_r - 1 else
132
--               '0';
133
--  empty_out <= '1' when write_read_count_r = 0 else
134
--               '0';
135
--  full_out <= '1' when write_read_count_r >= dynamic_depth_r else
136
--              '0';
137
 
138
  update_flags: process (clk, rst_n)
139
  begin  -- process update_flags
140
    if rst_n = '0' then                 -- asynchronous reset (active low)
141
      one_d_out <= '0';
142
      one_p_out <= '0';
143
      empty_out <= '1';
144
      full_out_r  <= '0';
145
    elsif clk'event and clk = '1' then  -- rising clock edge
146
 
147
      if (we_in = '0' and re_in = '0' and write_read_count_r = 1) or
148
        (we_in = '1' and re_in = '1' and write_read_count_r = 1) or
149
        (we_in = '1' and re_in = '0' and write_read_count_r = 0) or
150
        (we_in = '0' and re_in = '1' and write_read_count_r = 2) then
151
        one_d_out <= '1';
152
      else
153
        one_d_out <= '0';
154
      end if;
155
 
156
      if (we_in = '0' and re_in = '0' and write_read_count_r = dynamic_depth_r - 1) or
157
        (we_in = '1' and re_in = '1' and write_read_count_r = dynamic_depth_r - 1) or
158
        (we_in = '1' and re_in = '0' and write_read_count_r = dynamic_depth_r - 2) or
159
        (we_in = '0' and re_in = '1' and write_read_count_r = dynamic_depth_r) then
160
 
161
        one_p_out <= '1';
162
      else
163
        one_p_out <= '0';
164
      end if;
165
 
166
      if (we_in = '0' and re_in = '0' and write_read_count_r = 0) or
167
        (we_in = '0' and re_in = '1' and write_read_count_r = 0) or
168
        (we_in = '0' and re_in = '1' and write_read_count_r = 1) then
169
 
170
        empty_out <= '1';
171
      else
172
        empty_out <= '0';
173
      end if;
174
 
175
      if (we_in = '0' and re_in = '0' and write_read_count_r = dynamic_depth_r) or
176
        (we_in = '1' and re_in = '0' and write_read_count_r = dynamic_depth_r) or
177
        (we_in = '1' and re_in = '0' and write_read_count_r = dynamic_depth_r - 1) or
178
        (write_read_count_r > dynamic_depth_r) then
179
 
180
        full_out_r <= '1';
181
      else
182
        full_out_r <= '0';
183
      end if;
184
 
185
    end if;
186
  end process update_flags;
187
 
188
  -----------------------------------------------------------------------------
189
  -- Update dynamic depth
190
  -----------------------------------------------------------------------------
191
  update_dynamic_depth_r : process (clk, rst_n)
192
  begin  -- process update_dynamic_depth_r
193
    if rst_n = '0' then                 -- asynchronous reset (active low)
194
      dynamic_depth_r <= depth_g;
195
      conf_ram_addr   <= (others => '0');
196
 
197
    elsif clk'event and clk = '1' then  -- rising clock edge
198
      conf_ram_addr <= (others => '0');
199
 
200
      if conv_integer(depth_from_conf_ram) > depth_g
201
        or depth_from_conf_ram =
202
 
203
        -- dynamic depth is bigger than maximum depth or
204
        -- it's not defined(zero) => Use the maximum depth
205
        conv_std_logic_vector(0, depth_from_conf_ram'length) then
206
        dynamic_depth_r <= depth_g;
207
 
208
      else
209
 
210
        -- update dynamic depth
211
        dynamic_depth_r <=
212
          conv_integer(depth_from_conf_ram);
213
      end if;
214
 
215
    end if;
216
  end process update_dynamic_depth_r;
217
 
218
  -----------------------------------------------------------------------------
219
  -- Update read and write addresses
220
  -----------------------------------------------------------------------------
221
  fifo_read_and_write : process (clk, rst_n)
222
 
223
  begin  -- process fifo_read_and_write
224
 
225
    if rst_n = '0' then                 -- asynchronous reset (active low)
226
      write_read_count_r <= 0;
227
      read_address_r     <= 0;
228
      write_address_r    <= 0;
229
 
230
    elsif clk'event and clk = '1' then  -- rising clock edge
231
 
232
      -- read if re_in = '1' and fifo not empty or
233
      --         simultaneus read and write and fifo full
234
      if re_in = '1' and ((we_in = '0' and write_read_count_r /= 0)
235
                          or (we_in = '1'
236
                              and write_read_count_r = dynamic_depth_r)) then
237
 
238
        write_read_count_r <= write_read_count_r - 1;
239
 
240
        if read_address_r = dynamic_depth_r - 1 then
241
          read_address_r <= 0;
242
        else
243
          read_address_r <= read_address_r + 1;
244
        end if;
245
        write_address_r <= write_address_r;
246
 
247
        -- write if we_in = '1' and fifo not full or
248
        --          simultaneus read and write and fifo empty
249
      elsif we_in = '1' and ((re_in = '0' and
250
                              write_read_count_r /= dynamic_depth_r)
251
                             or (re_in = '1' and write_read_count_r = 0)) then
252
        write_read_count_r <= write_read_count_r + 1;
253
        read_address_r     <= read_address_r;
254
        if write_address_r = dynamic_depth_r - 1 then
255
          write_address_r <= 0;
256
        else
257
          write_address_r <= write_address_r + 1;
258
        end if;
259
 
260
        -- write and read at the same time if re_in = '1' and we_in = '1' and
261
        -- fifo not empty or full
262
      elsif re_in = '1' and we_in = '1'
263
        and write_read_count_r /= dynamic_depth_r
264
        and write_read_count_r /= 0 then
265
        write_read_count_r <= write_read_count_r;
266
        if read_address_r = dynamic_depth_r - 1 then
267
          read_address_r <= 0;
268
        else
269
          read_address_r <= read_address_r + 1;
270
        end if;
271
        if write_address_r = dynamic_depth_r - 1 then
272
          write_address_r <= 0;
273
        else
274
          write_address_r <= write_address_r + 1;
275
        end if;
276
      else
277
        write_read_count_r <= write_read_count_r;
278
        read_address_r     <= read_address_r;
279
        write_address_r    <= write_address_r;
280
      end if;
281
    end if;
282
  end process fifo_read_and_write;
283
 
284
end rtl;

powered by: WebSVN 2.1.0

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