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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- File        : fifo.vhdl
3
-- Description : General fifo buffer
4
-- Author      : Erno Salminen
5
-- e-mail      : erno.salminen@tut.fi
6
-- Project     : 
7
-- Design      : 
8
-- Date        : 29.04.2002
9
-- Modified    : 30.04.2002 Vesa Lahtinen Optimized for synthesis
10
--
11
-- 15.12.04     ES: names changed
12
-------------------------------------------------------------------------------
13
-------------------------------------------------------------------------------
14
--  This file is part of Transaction Generator.
15
--
16
--  Transaction Generator is free software: you can redistribute it and/or modify
17
--  it under the terms of the Lesser GNU General Public License as published by
18
--  the Free Software Foundation, either version 3 of the License, or
19
--  (at your option) any later version.
20
--
21
--  Transaction Generator is distributed in the hope that it will be useful,
22
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
23
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
--  Lesser GNU General Public License for more details.
25
--
26
--  You should have received a copy of the Lesser GNU General Public License
27
--  along with Transaction Generator.  If not, see <http://www.gnu.org/licenses/>.
28
-------------------------------------------------------------------------------
29
library ieee;
30
use ieee.std_logic_1164.all;
31
use ieee.std_logic_arith.all;
32
use ieee.std_logic_unsigned.all;
33
 
34
entity fifo is
35
 
36
  generic (
37
    data_width_g :    integer := 32;
38
    depth_g      :    integer := 5
39
    );
40
  port (
41
    clk          : in std_logic;
42
    rst_n        : in std_logic;
43
 
44
    data_in   : in  std_logic_vector (data_width_g-1 downto 0);
45
    we_in     : in  std_logic;
46
    full_out  : out std_logic;
47
    one_p_out : out std_logic;
48
 
49
    re_in     : in  std_logic;
50
    data_out  : out std_logic_vector (data_width_g-1 downto 0);
51
    empty_out : out std_logic;
52
    one_d_out : out std_logic
53
    );
54
 
55
end fifo;
56
 
57
architecture behavioral of fifo is
58
 
59
 
60
  -- Registers
61
  signal full_r        : std_logic;
62
  signal empty_r       : std_logic;
63
  signal one_d_r       : std_logic;
64
  signal one_p_r       : std_logic;
65
  --signal data_amount_r : std_logic_vector (depth_g-1 downto 0);
66
  signal data_amount_r : std_logic_vector (16-1 downto 0);
67
 
68
  signal in_ptr_r  : integer range 0 to depth_g-1;
69
  signal out_ptr_r : integer range 0 to depth_g-1;
70
 
71
  type data_arr_type is array (depth_g-1 downto 0) of std_logic_vector (data_width_g-1 downto 0);
72
  signal fifo_buffer_r : data_arr_type;
73
 
74
 
75
begin  -- behavioral
76
 
77
  -- Continuous assignments
78
  -- Assigns register values to outputs
79
  full_out  <= full_r;
80
  empty_out <= empty_r;
81
  one_d_out <= one_d_r;
82
  one_p_out <= one_p_r;
83
  data_out  <= fifo_buffer_r (out_ptr_r);   -- mux at output!
84
  -- Note! There is some old value in data output when fifo is empty.
85
 
86
 
87
Main : process (clk, rst_n)
88
begin  -- process Main
89
  if rst_n = '0' then                   -- asynchronous reset (active low)
90
 
91
    -- Reset all registers
92
    -- Fifo is empty at first
93
    full_r        <= '0';
94
    empty_r       <= '1';
95
    one_d_r       <= '0';
96
    in_ptr_r      <= 0;
97
    out_ptr_r     <= 0;
98
    data_amount_r <= (others => '0');
99
 
100
    if depth_g =1 then                    -- 30.07
101
      one_p_r <= '1';
102
    else
103
      one_p_r <= '0';
104
    end if;
105
 
106
    for i in 0 to depth_g-1 loop
107
      fifo_buffer_r (i) <= (others => '0');
108
    end loop;  -- i
109
 
110
  elsif clk'event and clk = '1' then    -- rising clock edge
111
 
112
 
113
    -- 1) Write data to fifo
114
    if we_in = '1' and re_in = '0' then
115
 
116
      if full_r = '0' then
117
        empty_r                <= '0';
118
        if (in_ptr_r = (depth_g-1)) then
119
          in_ptr_r               <= 0;
120
        else
121
          in_ptr_r               <= in_ptr_r + 1;
122
        end if;
123
        out_ptr_r                <= out_ptr_r;
124
        data_amount_r          <= data_amount_r +1;
125
        fifo_buffer_r (in_ptr_r) <= data_in;
126
 
127
        -- Check if the fifo is getting full
128
        if data_amount_r + 2 = depth_g then
129
          full_r  <= '0';
130
          one_p_r <= '1';
131
        elsif data_amount_r +1 = depth_g then
132
          full_r  <= '1';
133
          one_p_r <= '0';
134
        else
135
          full_r  <= '0';
136
          one_p_r <= '0';
137
        end if;
138
 
139
        -- If fifo was empty, it has now one data 
140
        if empty_r = '1' then
141
          one_d_r <= '1';
142
        else
143
          one_d_r <= '0';
144
        end if;
145
 
146
      else
147
--         in_ptr_r      <= in_ptr_r;
148
--         out_ptr_r     <= out_ptr_r;
149
--         full_r        <= full_r;
150
--         empty_r       <= empty_r;
151
--         fifo_buffer_r <= fifo_buffer_r;
152
--         data_amount_r <= data_amount_r;
153
--         one_d_r       <= one_d_r;
154
--         one_p_r       <= one_p_r;
155
      end if;
156
 
157
 
158
    -- 2) Read data from fifo  
159
    elsif we_in = '0' and re_in = '1' then
160
 
161
      if empty_r = '0' then
162
        in_ptr_r        <= in_ptr_r;
163
        if (out_ptr_r = (depth_g-1)) then
164
          out_ptr_r     <= 0;
165
        else
166
          out_ptr_r     <= out_ptr_r + 1;
167
        end if;
168
        full_r        <= '0';
169
        data_amount_r <= data_amount_r -1;
170
 
171
        -- Debug
172
        -- fifo_buffer_r (out_ptr_r) <= (others => '1');
173
 
174
        -- Check if the fifo is getting empty
175
        if data_amount_r = 2 then
176
          empty_r <= '0';
177
          one_d_r <= '1';
178
        elsif data_amount_r = 1 then
179
          empty_r <= '1';
180
          one_d_r <= '0';
181
        else
182
          empty_r <= '0';
183
          one_d_r <= '0';
184
        end if;
185
 
186
        -- If fifo was full, it is no more 
187
        if full_r = '1' then
188
          one_p_r <= '1';
189
        else
190
          one_p_r <= '0';
191
        end if;
192
 
193
      else
194
--         in_ptr_r      <= in_ptr_r;
195
--         out_ptr_r     <= out_ptr_r;
196
--         full_r        <= full_r;
197
--         empty_r       <= empty_r;
198
--         fifo_buffer_r <= fifo_buffer_r;
199
--         data_amount_r <= data_amount_r;
200
--         one_d_r       <= one_d_r;
201
--         one_p_r       <= one_p_r;
202
      end if;
203
 
204
 
205
    -- 3) Write and read at the same time  
206
    elsif we_in = '1' and re_in = '1' then
207
 
208
 
209
      if full_r = '0' and empty_r = '0' then
210
        if (in_ptr_r = (depth_g-1)) then
211
          in_ptr_r    <= 0;
212
        else
213
          in_ptr_r    <= in_ptr_r + 1;
214
        end if;
215
        if (out_ptr_r = (depth_g-1)) then
216
          out_ptr_r   <= 0;
217
        else
218
          out_ptr_r   <= out_ptr_r + 1;
219
        end if;
220
        full_r        <= '0';
221
        empty_r       <= '0';
222
        data_amount_r <= data_amount_r;
223
        one_d_r       <= one_d_r;
224
        one_p_r       <= one_p_r;
225
 
226
        fifo_buffer_r (in_ptr_r)  <= data_in;
227
        -- fifo_buffer_r (out_ptr_r) <= (others => '1');  --debug
228
 
229
 
230
      elsif full_r = '1' and empty_r = '0' then
231
        -- Fifo is full, only reading is possible
232
        in_ptr_r        <= in_ptr_r;
233
        if (out_ptr_r = (depth_g-1)) then
234
          out_ptr_r     <= 0;
235
        else
236
          out_ptr_r     <= out_ptr_r + 1;
237
        end if;
238
        full_r        <= '0';
239
        one_p_r       <= '1';
240
        --fifo_buffer_r (out_ptr_r) <= (others => '1');  -- Debug
241
        data_amount_r <= data_amount_r -1;
242
 
243
        -- Check if the fifo is getting empty
244
        if data_amount_r = 2 then
245
          empty_r <= '0';
246
          one_d_r <= '1';
247
        elsif data_amount_r = 1 then
248
          empty_r <= '1';
249
          one_d_r <= '0';
250
        else
251
          empty_r <= '0';
252
          one_d_r <= '0';
253
        end if;
254
 
255
 
256
      elsif full_r = '0' and empty_r = '1' then
257
        -- Fifo is empty, only writing is possible
258
        if (in_ptr_r = (depth_g-1)) then
259
          in_ptr_r               <= 0;
260
        else
261
          in_ptr_r               <= in_ptr_r + 1;
262
        end if;
263
        out_ptr_r                <= out_ptr_r;
264
        empty_r                  <= '0';
265
        one_d_r                  <= '1';
266
        fifo_buffer_r (in_ptr_r) <= data_in;
267
        data_amount_r            <= data_amount_r +1;
268
 
269
        -- Check if the fifo is getting full
270
        if data_amount_r + 2 = depth_g then
271
          full_r  <= '0';
272
          one_p_r <= '1';
273
        elsif data_amount_r +1 = depth_g then
274
          full_r  <= '1';
275
          one_p_r <= '0';
276
        else
277
          full_r  <= '0';
278
          one_p_r <= '0';
279
        end if;
280
 
281
 
282
      -- 4) Do nothing, fifo remains idle 
283
      else
284
 
285
--         in_ptr_r      <= in_ptr_r;
286
--         out_ptr_r     <= out_ptr_r;
287
--         full_r        <= full_r;
288
--         empty_r       <= empty_r;
289
--         fifo_buffer_r <= fifo_buffer_r;
290
--         data_amount_r <= data_amount_r;
291
--         one_d_r       <= one_d_r;
292
--         one_p_r       <= one_p_r;
293
      end if;
294
 
295
    else
296
      -- Fifo is idle
297
--       in_ptr_r      <= in_ptr_r;
298
--       out_ptr_r     <= out_ptr_r;
299
--       full_r        <= full_r;
300
--       empty_r       <= empty_r;
301
--       fifo_buffer_r <= fifo_buffer_r;
302
--       data_amount_r <= data_amount_r;
303
--       one_d_r       <= one_d_r;
304
--       one_p_r       <= one_p_r;
305
    end if;
306
 
307
  end if;
308
end process Main;
309
 
310
end behavioral;

powered by: WebSVN 2.1.0

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