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

powered by: WebSVN 2.1.0

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