OpenCores
URL https://opencores.org/ocsvn/p9813_rgb_led_string_driver/p9813_rgb_led_string_driver/trunk

Subversion Repositories p9813_rgb_led_string_driver

[/] [p9813_rgb_led_string_driver/] [trunk/] [rtl/] [VHDL/] [fifo_pack.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jclaytons
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
 
5
package fifo_pack is
6
 
7
-- Component declarations not provided any more.
8
-- With VHDL '93 and newer, component declarations are allowed,
9
-- but not required.
10
--
11
-- Please to try direct instantiation instead, for example:
12
--
13
--   instance_name : entity work.entity_name(beh)
14
--
15
 
16
end fifo_pack;
17
 
18
 
19
--------------------------------------------------------------
20
-- SWISS ARMY FIFO with fill level output
21
--------------------------------------------------------------
22
-- Description:
23
--
24
-- This is the same as "fifo_with_fill_level" but it has been
25
-- coded to select whether Block RAMs or distributed RAMs are inferred.
26
--
27
-- Note : When USE_BRAM=0, the behavior when reading the FIFO is to
28
--        make read data available immediately during the clock cycle
29
--        in which fifo_rd_i='1'.  When USE_BRAM/=0, then an additional
30
--        clock cycle occurs following the fifo_rd_i pulse, before the
31
--        output data is available.
32
--        Please be aware of this.
33
--
34
--
35
 
36
library IEEE;
37
use IEEE.STD_LOGIC_1164.ALL;
38
use IEEE.NUMERIC_STD.ALL;
39
use IEEE.MATH_REAL.ALL;
40
 
41
library work;
42
use work.function_pack.all;
43
 
44
entity swiss_army_fifo is
45
    generic (
46
      USE_BRAM         : integer :=  1; -- Set to nonzero value for BRAM, zero for distributed RAM
47
      WIDTH            : integer :=  8;
48
      DEPTH            : integer :=  5;
49
      FILL_LEVEL_BITS  : integer :=  3; -- Should be at least int(floor(log2(DEPTH))+1.0)
50
      PF_FULL_POINT    : integer :=  3;
51
      PF_FLAG_POINT    : integer :=  2;
52
      PF_EMPTY_POINT   : integer :=  0
53
    );
54
    port (
55
      sys_rst_n       : in  std_logic; -- Asynchronous
56
      sys_clk         : in  std_logic;
57
      sys_clk_en      : in  std_logic;
58
 
59
      reset_i         : in  std_logic;  -- Synchronous
60
 
61
      fifo_wr_i       : in  std_logic;
62
      fifo_din        : in  unsigned(WIDTH-1 downto 0);
63
 
64
      fifo_rd_i       : in  std_logic;
65
      fifo_dout       : out unsigned(WIDTH-1 downto 0);
66
 
67
      fifo_fill_level : out unsigned(FILL_LEVEL_BITS-1 downto 0);
68
      fifo_full       : out std_logic;
69
      fifo_empty      : out std_logic;
70
      fifo_pf_full    : out std_logic;
71
      fifo_pf_flag    : out std_logic;
72
      fifo_pf_empty   : out std_logic
73
    );
74
end swiss_army_fifo;
75
 
76
architecture beh of swiss_army_fifo is
77
 
78
  -- Constants
79
  constant FLG_WIDTH : integer := bit_width(DEPTH); -- Bit Width of memory address.  Pointers are one bit wider,
80
                                                    -- so that fill_level can represent the full quantity of 
81
                                                    -- items stored in the FIFO.  This is important when DEPTH
82
                                                    -- is an even power of 2.
83
 
84
  -- Signal Declarations
85
  signal rd_row     : unsigned(FLG_WIDTH downto 0);
86
  signal wr_row     : unsigned(FLG_WIDTH downto 0);
87
  signal fill_level : unsigned(FLG_WIDTH downto 0);
88
  signal ram_we_a   : std_logic;
89
  signal ram_dout   : unsigned(WIDTH-1 downto 0);
90
 
91
  TYPE STATE_TYPE IS (st_empty, st_data, st_full);
92
  signal current_state : STATE_TYPE ;
93
 
94
  signal bram_dat_b : unsigned(WIDTH-1 downto 0);
95
 
96
BEGIN
97
 
98
  fifo_empty      <= '1' when (current_state=st_empty) else '0';
99
  fifo_full       <= '1' when (current_state=st_full)  else '0';
100
  fifo_pf_full    <= '1' when (fill_level>=PF_FULL_POINT or current_state=st_full) else '0';
101
  fifo_pf_flag    <= '1' when (fill_level>=PF_FLAG_POINT) else '0';
102
  fifo_pf_empty   <= '1' when (fill_level<=PF_EMPTY_POINT and current_state/=st_full) else '0';
103
  fifo_fill_level <= resize(fill_level,FILL_LEVEL_BITS);
104
 
105
-------------------------
106
-- The FIFO Fill Level
107
fill_level_proc: process(wr_row, rd_row, current_state)
108
  begin
109
    if (current_state=st_empty) then
110
      fill_level <= (others=>'0');
111
    elsif (wr_row>rd_row) then
112
      fill_level <= wr_row-rd_row;
113
    else
114
      fill_level <= DEPTH+(wr_row-rd_row);
115
    end if;
116
  end process;
117
 
118
-------------------------
119
-- The FIFO memory
120
 
121
-- Port A is the write side.
122
-- Port B is dedicated to reading only.
123
-- The hexfile is used to permit initialization of the RAM
124
 
125
  fifo_ram : entity work.swiss_army_ram(beh)
126
    generic map(
127
      USE_BRAM  => USE_BRAM,
128
      WRITETHRU => 0, -- Set to nonzero value for writethrough mode
129
      USE_FILE  => 0, -- Set to nonzero value to use INIT_FILE
130
      INIT_VAL  => 0,
131
      INIT_SEL  => 0, -- No generate loop here
132
      INIT_FILE => "foo.txt", -- ASCII hexadecimal init file name (not needed)
133
      FIL_WIDTH => 32, -- Bit width of init file lines
134
      ADR_WIDTH => FLG_WIDTH,
135
      DAT_WIDTH => WIDTH
136
    )
137
    port map (
138
       clk_a    => sys_clk,
139
       clk_b    => sys_clk,
140
 
141
       adr_a_i  => wr_row(FLG_WIDTH-1 downto 0),
142
       adr_b_i  => rd_row(FLG_WIDTH-1 downto 0),
143
 
144
       we_a_i   => ram_we_a,
145
       en_a_i   => sys_clk_en,
146
       dat_a_i  => fifo_din,
147
       dat_a_o  => open,
148
 
149
       we_b_i   => '0',
150
       en_b_i   => sys_clk_en,
151
       dat_b_i  => bram_dat_b,
152
       dat_b_o  => ram_dout
153
    );
154
 
155
  bram_dat_b <= (others=>'0');
156
  ram_we_a <= '1' when fifo_wr_i='1' and (current_state/=st_full or (current_state=st_full and fifo_rd_i='1')) else '0';
157
  fifo_dout <= ram_dout;
158
 
159
 
160
-------------------------
161
-- The FIFO state machine
162
  clocked : PROCESS(sys_clk, sys_rst_n)
163
 
164
  procedure do_write is
165
  begin
166
    if (wr_row=DEPTH-1) then  -- Roll buffer index for non-power-of-two
167
      wr_row <= (others=>'0');
168
    else
169
      wr_row<=wr_row+1;
170
    end if;
171
  end do_write;
172
 
173
  procedure do_read is
174
  begin
175
    if (rd_row=DEPTH-1) then  -- Roll buffer index for non-power-of-two
176
      rd_row <= (others=>'0');
177
    else
178
      rd_row<=rd_row+1;
179
    end if;
180
  end do_read;
181
 
182
  begin
183
    if (sys_rst_n = '0') then
184
      current_state <= st_empty;
185
      rd_row   <= (others=>'0');
186
      wr_row   <= (others=>'0');
187
 
188
    elsif (sys_clk'EVENT and sys_clk = '1') then
189
      if (sys_clk_en='1') then
190
        if (reset_i='1') then
191
          current_state <= st_empty;
192
          wr_row <= (others=>'0');
193
          rd_row <= (others=>'0');
194
        else
195
          case current_state is
196
 
197
          -- When empty, one can only read if also writing
198
          when st_empty =>
199
            if (fifo_wr_i='1') then
200
              do_write;
201
              if (fifo_rd_i='1') then
202
                do_read;
203
              else
204
                current_state<=st_data;
205
              end if;
206
            end if;
207
 
208
          when st_data =>
209
            if (fifo_wr_i='1') then
210
              do_write;
211
              if (fifo_rd_i='0' and fill_level=DEPTH-1) then
212
                current_state<=st_full;
213
              end if;
214
            end if;
215
            if (fifo_rd_i='1') then
216
              do_read;
217
              if (fifo_wr_i='0' and fill_level=1) then
218
                current_state<=st_empty;
219
              end if;
220
            end if;
221
 
222
          -- When full, one can only write if also reading
223
          when st_full =>
224
            if (fifo_rd_i='1') then
225
              do_read;
226
              if (fifo_wr_i='1') then
227
                do_write;
228
              else
229
                current_state<=st_data;
230
              end if;
231
            end if;
232
 
233
          when others => null;
234
          end case;
235
 
236
        end if;
237
      end if; -- sys_clk_en
238
    end if; -- sys_clk
239
  end process clocked;
240
 
241
 
242
end beh;
243
 
244
--------------------------------------------------------------
245
-- VALIDATION FIFO with fill level output
246
--------------------------------------------------------------
247
-- Description:
248
--
249
-- This is the same as "swiss_army_fifo" but it has been given
250
-- two head pointers.  One of them is used for loading new data,
251
-- and the other is used when the loaded data is to be validated,
252
-- and for tracking the number of validated data entries contained
253
-- within the FIFO.
254
--
255
-- This FIFO was envisioned for working with packetized data, where
256
-- a data validation check is available at the end of the packet, such
257
-- as a CRC field.
258
--
259
-- The principle at work here is that new data bytes are written
260
-- using head pointer A, but if at the end of the packet, the data
261
-- are deemed to be invalid, then head pointer A is "reset" back
262
-- to the last valid point, thereby neatly "throwing away" the
263
-- invalid data into the "bit bucket."  On the other hand, if the data are
264
-- deemed valid, then head pointer B is loaded to be equal to head
265
-- pointer A, thereby causing the entire validated packet to become
266
-- available for reading.
267
--
268
-- The read side of the FIFO only presents validated data for reading.
269
--
270
-- This situation gives rise to two sets of FIFO status outputs,
271
-- one set for each side of the FIFO.  Thus, there is a write fill
272
-- level, and a read fill level, each with full accoutrements.
273
--
274
-- The validation or invalidation is done by asserting the appropriate
275
-- signal during a write cycle.  If both signals are asserted at the
276
-- same time, the signals are ignored, and no validation or invalidation
277
-- is performed.
278
--
279
-- Validation or invalidation can be performed at any time.  If the data
280
-- already loaded into the FIFO are validated when the FIFO writing side is
281
-- full, then the reading side becomes full at that time.  However, no new
282
-- data can be written into the FIFO when it is full, for obvious reasons.
283
--
284
-- On the other hand, if the FIFO is not full, and a new data byte is being
285
-- written at the same time that an invalidation is being performed, then the
286
-- new data value is technically written into the FIFO RAM, but it can never
287
-- be read out of the storage since the pointers are updated at the same time,
288
-- effectively cutting the new data value out of the valid FIFO area.
289
-- This is as it should be, since the new data are technically considered
290
-- invalid in that case.
291
--
292
-- Further musings:
293
-- Because validation/invalidation can happen even when writes are not being
294
-- performed, one may consider the wr_dat_good_i and wr_dat_bad_i inputs as
295
-- synchronous FIFO pointer load commands.  Asserting wr_dat_good_i has the
296
-- effect of loading wr_row_b so that it is the same as wr_row_a.  Asserting
297
-- wr_dat_bad_i has the effect of keeping wr_row_b set to the current wr_row_a
298
-- value.
299
--
300
-- Thus, if one were to tie wr_dat_good_i to '1' and wr_dat_bad_i to '0', then
301
-- this "validation" FIFO operates identically to a regular FIFO, in which all
302
-- data are considered valid at the time they are written into the FIFO.
303
--
304
-- Note : When USE_BRAM=0, the behavior when reading the FIFO is to
305
--        make read data available immediately during the clock cycle
306
--        in which fifo_rd_i='1'.  When USE_BRAM/=0, then an additional
307
--        clock cycle occurs following the fifo_rd_i pulse, before the
308
--        output data is available.
309
--        Please be aware of this.
310
--
311
--
312
 
313
library IEEE;
314
use IEEE.STD_LOGIC_1164.ALL;
315
use IEEE.NUMERIC_STD.ALL;
316
use IEEE.MATH_REAL.ALL;
317
 
318
library work;
319
use work.function_pack.all;
320
 
321
  entity validation_fifo is
322
    generic(
323
      USE_BRAM        : integer :=  1; -- Set to nonzero value for BRAM, zero for distributed RAM
324
      WIDTH           : integer :=  8;
325
      DEPTH           : integer :=  5;
326
      FILL_LEVEL_BITS : integer :=  3; -- Should be at least int(floor(log2(DEPTH))+1.0)
327
      PF_FULL_POINT   : integer :=  3;
328
      PF_FLAG_POINT   : integer :=  2;
329
      PF_EMPTY_POINT  : integer :=  0
330
    );
331
    port (
332
      sys_rst_n       : in  std_logic; -- Asynchronous
333
      sys_clk         : in  std_logic;
334
      sys_clk_en      : in  std_logic;
335
 
336
      reset_i         : in  std_logic;  -- Synchronous
337
 
338
      -- Write Data Interface
339
      wr_i            : in  std_logic; -- Data loaded upon assertion
340
      wr_dat_good_i   : in  std_logic; -- FIFO data validated upon assertion
341
      wr_dat_bad_i    : in  std_logic; -- FIFO data invalidated upon assertion
342
      wr_dat_i        : in  unsigned(WIDTH-1 downto 0);
343
 
344
      -- Write Side Status
345
      wr_fill_level_o : out unsigned(FILL_LEVEL_BITS-1 downto 0);
346
      wr_full_o       : out std_logic;
347
      wr_empty_o      : out std_logic;
348
      wr_pf_full_o    : out std_logic;
349
      wr_pf_flag_o    : out std_logic;
350
      wr_pf_empty_o   : out std_logic;
351
 
352
      -- Read Data Interface (valid data only)
353
      rd_i            : in  std_logic;
354
      rd_dat_o        : out unsigned(WIDTH-1 downto 0);
355
 
356
      -- Read Side Status
357
      rd_fill_level_o : out unsigned(FILL_LEVEL_BITS-1 downto 0);
358
      rd_full_o       : out std_logic;
359
      rd_empty_o      : out std_logic;
360
      rd_pf_full_o    : out std_logic;
361
      rd_pf_flag_o    : out std_logic;
362
      rd_pf_empty_o   : out std_logic
363
    );
364
  end validation_fifo;
365
 
366
architecture beh of validation_fifo is
367
 
368
  -- Constants
369
  constant FLG_WIDTH : integer := bit_width(DEPTH); -- Bit Width of memory address.  Pointers are one bit wider,
370
                                                    -- so that fill_level can represent the full quantity of 
371
                                                    -- items stored in the FIFO.  This is important when DEPTH
372
                                                    -- is an even power of 2.
373
 
374
  -- Signal Declarations
375
  signal rd_row       : unsigned(FLG_WIDTH downto 0);
376
  signal wr_row_a     : unsigned(FLG_WIDTH downto 0);
377
  signal wr_row_b     : unsigned(FLG_WIDTH downto 0);
378
  signal fill_level_a : unsigned(FLG_WIDTH+1 downto 0);
379
  signal fill_level_b : unsigned(FLG_WIDTH+1 downto 0);
380
  signal ram_we_a     : std_logic;
381
  signal ram_dout     : unsigned(WIDTH-1 downto 0);
382
 
383
  TYPE STATE_TYPE IS (st_empty, st_data, st_full);
384
  signal current_state : STATE_TYPE ;
385
 
386
  signal bram_dat_b : unsigned(WIDTH-1 downto 0);
387
 
388
  signal fifo_level_a    : unsigned(FILL_LEVEL_BITS-1 downto 0);
389
  signal fifo_full_a     : std_logic;
390
  signal fifo_empty_a    : std_logic;
391
  signal fifo_pf_full_a  : std_logic;
392
  signal fifo_pf_flag_a  : std_logic;
393
  signal fifo_pf_empty_a : std_logic;
394
 
395
  signal fifo_level_b    : unsigned(FILL_LEVEL_BITS-1 downto 0);
396
  signal fifo_full_b     : std_logic;
397
  signal fifo_empty_b    : std_logic;
398
  signal fifo_pf_full_b  : std_logic;
399
  signal fifo_pf_flag_b  : std_logic;
400
  signal fifo_pf_empty_b : std_logic;
401
 
402
BEGIN
403
 
404
  fifo_level_a    <= resize(fill_level_a,FILL_LEVEL_BITS);
405
  fifo_full_a     <= '1' when (fill_level_a=DEPTH) else '0';
406
  fifo_empty_a    <= '1' when (fill_level_a=0) else '0';
407
  fifo_pf_full_a  <= '1' when (fill_level_a>=PF_FULL_POINT) else '0';
408
  fifo_pf_flag_a  <= '1' when (fill_level_a>=PF_FLAG_POINT) else '0';
409
  fifo_pf_empty_a <= '1' when (fill_level_a<=PF_EMPTY_POINT) else '0';
410
 
411
  fifo_level_b    <= resize(fill_level_b,FILL_LEVEL_BITS);
412
  fifo_full_b     <= '1' when (fill_level_b=DEPTH) else '0';
413
  fifo_empty_b    <= '1' when (fill_level_b=0) else '0';
414
  fifo_pf_full_b  <= '1' when (fill_level_b>=PF_FULL_POINT) else '0';
415
  fifo_pf_flag_b  <= '1' when (fill_level_b>=PF_FLAG_POINT) else '0';
416
  fifo_pf_empty_b <= '1' when (fill_level_b<=PF_EMPTY_POINT) else '0';
417
 
418
-------------------------
419
-- The FIFO Fill Level
420
fill_level_a <= (others=>'0') when wr_row_a=rd_row else
421
                ('0' & wr_row_a)-('0' & rd_row) when wr_row_a>rd_row else
422
                (2**(FLG_WIDTH+1))+(('0' & wr_row_a)-('0' & rd_row));
423
 
424
fill_level_b <= (others=>'0') when wr_row_b=rd_row else
425
                ('0' & wr_row_b)-('0' & rd_row) when wr_row_b>rd_row else
426
                (2**(FLG_WIDTH+1))+(('0' & wr_row_b)-('0' & rd_row));
427
 
428
-------------------------
429
-- The FIFO memory
430
 
431
-- Port A is the write side.
432
-- Port B is dedicated to reading only.
433
-- The hexfile is used to permit initialization of the RAM
434
 
435
  fifo_ram : entity work.swiss_army_ram(beh)
436
    generic map(
437
      USE_BRAM  => USE_BRAM,
438
      WRITETHRU => 0, -- Set to nonzero value for writethrough mode
439
      USE_FILE  => 0, -- Set to nonzero value to use INIT_FILE
440
      INIT_VAL  => 0,
441
      INIT_SEL  => 0, -- No generate loop here
442
      INIT_FILE => "foo.txt", -- ASCII hexadecimal init file name (not needed)
443
      FIL_WIDTH => 32, -- Bit width of init file lines
444
      ADR_WIDTH => FLG_WIDTH,
445
      DAT_WIDTH => WIDTH
446
    )
447
    port map (
448
       clk_a    => sys_clk,
449
       clk_b    => sys_clk,
450
 
451
       adr_a_i  => wr_row_a(FLG_WIDTH-1 downto 0),
452
       adr_b_i  => rd_row(FLG_WIDTH-1 downto 0),
453
 
454
       we_a_i   => ram_we_a,
455
       en_a_i   => sys_clk_en,
456
       dat_a_i  => wr_dat_i,
457
       dat_a_o  => open,
458
 
459
       we_b_i   => '0',
460
       en_b_i   => sys_clk_en,
461
       dat_b_i  => bram_dat_b,
462
       dat_b_o  => ram_dout
463
    );
464
 
465
  bram_dat_b <= (others=>'0');
466
  ram_we_a <= '1' when wr_i='1' and fifo_full_a='0' else '0';
467
  rd_dat_o <= ram_dout;
468
 
469
-------------------------
470
-- The FIFO writing process
471
  wr_proc : PROCESS(sys_clk, sys_rst_n)
472
  begin
473
    if (sys_rst_n = '0') then
474
      wr_row_a <= (others=>'0'); -- For unvalidated data
475
      wr_row_b <= (others=>'0'); -- For validated data
476
    elsif (sys_clk'event and sys_clk = '1') then
477
      if (sys_clk_en='1') then
478
        if (reset_i='1') then
479
          wr_row_a <= (others=>'0');
480
          wr_row_b <= (others=>'0');
481
        else
482
          if (wr_i='1') then
483
            if (fifo_full_a='1') then
484
              null; -- FIFO is full!  Don't do any writes.
485
              -- However, still handle validation/invalidation
486
              if (wr_dat_good_i='1' and wr_dat_bad_i='0') then
487
                wr_row_b <= wr_row_a;
488
              end if;
489
              if (wr_dat_bad_i='1' and wr_dat_good_i='0') then
490
                wr_row_a <= wr_row_b;
491
              end if;
492
            else
493
              wr_row_a <= wr_row_a+1;
494
              -- Handle data validation/invalidation during writes
495
              if (wr_dat_good_i='1' and wr_dat_bad_i='0') then
496
                wr_row_b <= wr_row_a+1;
497
              end if;
498
              if (wr_dat_bad_i='1' and wr_dat_good_i='0') then
499
                wr_row_a <= wr_row_b;
500
              end if;
501
            end if;
502
          else
503
            -- Handle validation/invalidation when not writing
504
            if (wr_dat_good_i='1' and wr_dat_bad_i='0') then
505
              wr_row_b <= wr_row_a;
506
            end if;
507
            if (wr_dat_bad_i='1' and wr_dat_good_i='0') then
508
              wr_row_a <= wr_row_b;
509
            end if;
510
          end if;
511
        end if;
512
      end if; -- wr_clk_en
513
    end if; -- sys_clk
514
  end process wr_proc;
515
 
516
-------------------------
517
-- The FIFO reading process
518
  rd_proc : PROCESS(sys_clk, sys_rst_n)
519
  begin
520
    if (sys_rst_n = '0') then
521
      rd_row <= (others=>'0');
522
    elsif (sys_clk'event and sys_clk = '1') then
523
      if (sys_clk_en='1') then
524
        if (reset_i='1') then
525
          rd_row <= (others=>'0');
526
        else
527
          if (rd_i='1') then
528
            if (fifo_empty_b='1') then
529
              null; -- FIFO is empty!  Don't read anything.
530
            else
531
              rd_row <= rd_row+1;
532
            end if;
533
          end if;
534
        end if;
535
      end if; -- rd_clk_en
536
    end if; -- sys_clk
537
  end process rd_proc;
538
 
539
-- Provide Output Status
540
  wr_fill_level_o <= fifo_level_a;
541
  wr_full_o       <= fifo_full_a;
542
  wr_empty_o      <= fifo_empty_a;
543
  wr_pf_full_o    <= fifo_pf_full_a;
544
  wr_pf_flag_o    <= fifo_pf_flag_a;
545
  wr_pf_empty_o   <= fifo_pf_empty_a;
546
 
547
  rd_fill_level_o <= fifo_level_b;
548
  rd_full_o       <= fifo_full_b;
549
  rd_empty_o      <= fifo_empty_b;
550
  rd_pf_full_o    <= fifo_pf_full_b;
551
  rd_pf_flag_o    <= fifo_pf_flag_b;
552
  rd_pf_empty_o   <= fifo_pf_empty_b;
553
 
554
end beh;
555
 
556
--------------------------------------------------------------
557
-- FIFO-LIFO with fill level output
558
--------------------------------------------------------------
559
--
560
-- Author: John Clayton
561
-- Update: Nov. 16, 2016 Copied "swiss_army_fifo" component, and revised it.
562
--
563
-- Description
564
-------------------------------------------------------------------------------
565
-- This is the same as "swiss_army_fifo" but it has been given the ability
566
-- to pull the last written data back out of the FIFO.  This is where the
567
-- "LIFO" function incides, since FIFO signifies "First In, First Out"
568
-- videlicet "LIFO" signifies "Last In, First Out."  The LIFO function is
569
-- also known as a hardware "stack."  The stack is a data structure known
570
-- to computer programmers in which a "push" operation adds a new data value
571
-- to the top of the stack, while a "pop" operation removes the most recently
572
-- added data value from the top of the stack.
573
--
574
-- Initially,about five minutes of coding effort was put into transmogrifying
575
-- the "fifo_pack" package into a new package, to be called "stack_pack."
576
-- However, it was soon realized by the author that stacks are much less
577
-- frequently needed as compared with FIFOs, and that furthermore adding a
578
-- LIFO function to a FIFO would be a simple task, not requiring a complete
579
-- rewrite of all the components in the fifo_pack.  Also, when using the
580
-- fifo_lifo as a simple stack or lifo, the fifo read port can be tied to
581
-- constant signals, which will result in the FIFO tail pointer being
582
-- "optimized out" of the design at synthesis time, resulting in a nice
583
-- compact LIFO only function.  The same optimization benefit is realized
584
-- with regard to the status signals, whenever they are not needed.
585
--
586
-- As with the swiss_army_fifo, this module is not well suited to crossing
587
-- from one clock domain to another.  For that purpose, there exist other,
588
-- more suitable FIFOs in the world.
589
--
590
-- Since this module retains characteristics of both a FIFO and a LIFO, it
591
-- can be used to implement a "leaky stack" where the older contents can be
592
-- emptied out.  Alternately, it can be used to implement a FIFO in which
593
-- elements of data which have been enqueued can be "uncommitted" and removed
594
-- even after they were written into the FIFO.
595
--
596
-- Ahh, yes, this brings us to the question of what priority is to be given
597
-- when a fifo_rd and lifo_rd are both requested at the same time...  Well,
598
-- in the event that there are at least two items in the FIFO, then both
599
-- operations can be performed simultaneously.  Also, if there is only one
600
-- item in the FIFO, but a write is being performed, then here again both
601
-- read operations can be performed simultaneously.  However, if only one item
602
-- exists inside the FIFO, and both reads are requested at the same time,
603
-- and there is no write proffered, then what is to be done?  The answer is
604
-- that one of the reads must be ignored, and the generic FIFO_RD_FIRST
605
-- determines the behavior.  If FIFO_RD_FIRST is non-zero, then the module
606
-- gives priority to the fifo_rd input.  Otherwise, the lifo_rd input is
607
-- acted upon.  Just as for the case of the plain FIFO, the user is
608
-- responsible for determining further error conditions based on the fill
609
-- level.
610
--
611
-- Note : When USE_BRAM=0, the behavior when reading the FIFO is to
612
--        make read data available immediately during the clock cycle
613
--        in which fifo_rd_i='1'.  When USE_BRAM/=0, then an additional
614
--        clock cycle occurs following the fifo_rd_i pulse, before the
615
--        output data is available.
616
--        Please be aware of this.
617
--
618
--
619
 
620
library IEEE;
621
use IEEE.STD_LOGIC_1164.ALL;
622
use IEEE.NUMERIC_STD.ALL;
623
use IEEE.MATH_REAL.ALL;
624
 
625
library work;
626
use work.function_pack.all;
627
 
628
entity fifo_lifo is
629
    generic(
630
      USE_BRAM         : integer :=  1; -- Set to nonzero value for BRAM, zero for distributed RAM
631
      FIFO_RD_FIRST    : integer :=  0; -- Set non-zero to have fifo_rd take priority for the single item reading case
632
      WIDTH            : integer :=  8;
633
      DEPTH            : integer :=  5;
634
      FILL_LEVEL_BITS  : integer :=  3; -- Should be at least int(floor(log2(DEPTH))+1.0)
635
      PF_FULL_POINT    : integer :=  3;
636
      PF_FLAG_POINT    : integer :=  2;
637
      PF_EMPTY_POINT   : integer :=  0
638
    );
639
    port (
640
      sys_rst_n       : in  std_logic; -- Asynchronous
641
      sys_clk         : in  std_logic;
642
      sys_clk_en      : in  std_logic;
643
 
644
      reset_i         : in std_logic;  -- Synchronous
645
 
646
      -- FIFO/LIFO data input
647
      fifo_wr_i       : in  std_logic;
648
      fifo_din        : in  unsigned(WIDTH-1 downto 0);
649
 
650
      -- LIFO data output
651
      lifo_rd_i       : in  std_logic;
652
      lifo_dout       : out unsigned(WIDTH-1 downto 0);
653
 
654
      -- FIFO data output
655
      fifo_rd_i       : in  std_logic;
656
      fifo_dout       : out unsigned(WIDTH-1 downto 0);
657
 
658
      -- FIFO/LIFO status
659
      fifo_fill_level : out unsigned(FILL_LEVEL_BITS-1 downto 0);
660
      fifo_full       : out std_logic;
661
      fifo_empty      : out std_logic;
662
      fifo_pf_full    : out std_logic;
663
      fifo_pf_flag    : out std_logic;
664
      fifo_pf_empty   : out std_logic
665
    );
666
  end fifo_lifo;
667
 
668
architecture beh of fifo_lifo is
669
 
670
  -- Constants
671
  constant FLG_WIDTH : integer := bit_width(DEPTH); -- Bit Width of memory address.  Pointers are one bit wider,
672
                                                    -- so that fill_level can represent the full quantity of 
673
                                                    -- items stored in the FIFO.  This is important when DEPTH
674
                                                    -- is an even power of 2.
675
 
676
  -- Signal Declarations
677
  signal rd_row     : unsigned(FLG_WIDTH downto 0);
678
  signal wr_row     : unsigned(FLG_WIDTH downto 0);
679
  signal lf_row     : unsigned(FLG_WIDTH downto 0); -- Used for LIFO read operations.
680
  signal ra_row     : unsigned(FLG_WIDTH downto 0); -- Selection between wr_row and lf_row.
681
  signal fill_level : unsigned(FLG_WIDTH downto 0);
682
  signal ram_we_a   : std_logic;
683
  signal ram_dout   : unsigned(WIDTH-1 downto 0);
684
 
685
  type STATE_TYPE IS (st_empty, st_data, st_full);
686
  signal current_state : STATE_TYPE ;
687
 
688
  signal bram_dat_b : unsigned(WIDTH-1 downto 0);
689
 
690
begin
691
 
692
  fifo_empty      <= '1' when (current_state=st_empty) else '0';
693
  fifo_full       <= '1' when (current_state=st_full)  else '0';
694
  fifo_pf_full    <= '1' when (fill_level>=PF_FULL_POINT or current_state=st_full) else '0';
695
  fifo_pf_flag    <= '1' when (fill_level>=PF_FLAG_POINT) else '0';
696
  fifo_pf_empty   <= '1' when (fill_level<=PF_EMPTY_POINT and current_state/=st_full) else '0';
697
  fifo_fill_level <= resize(fill_level,FILL_LEVEL_BITS);
698
 
699
-------------------------
700
-- The FIFO Fill Level
701
fill_level_proc: process(wr_row, rd_row, current_state)
702
  begin
703
    if (current_state=st_empty) then
704
      fill_level <= (others=>'0');
705
    elsif (wr_row>rd_row) then
706
      fill_level <= wr_row-rd_row;
707
    else
708
      fill_level <= DEPTH+(wr_row-rd_row);
709
    end if;
710
  end process;
711
 
712
-------------------------
713
-- The FIFO memory
714
 
715
-- Port A is the write side.
716
-- Port B is dedicated to reading only.
717
-- The hexfile is used to permit initialization of the RAM
718
 
719
  fifo_ram : entity work.swiss_army_ram(beh)
720
    generic map(
721
      USE_BRAM  => USE_BRAM,
722
      WRITETHRU => 1, -- Set to nonzero value for writethrough mode
723
      USE_FILE  => 0, -- Set to nonzero value to use INIT_FILE
724
      INIT_VAL  => 0,
725
      INIT_SEL  => 0, -- No generate loop here
726
      INIT_FILE => "foo.txt", -- ASCII hexadecimal init file name (not needed)
727
      FIL_WIDTH => 32, -- 4x the number of hex digits per line in INIT_FILE
728
      ADR_WIDTH => FLG_WIDTH,
729
      DAT_WIDTH => WIDTH
730
    )
731
    port map (
732
       clk_a    => sys_clk,
733
       clk_b    => sys_clk,
734
 
735
       adr_a_i  => ra_row(FLG_WIDTH-1 downto 0),
736
       adr_b_i  => rd_row(FLG_WIDTH-1 downto 0),
737
 
738
       we_a_i   => ram_we_a,
739
       en_a_i   => sys_clk_en,
740
       dat_a_i  => fifo_din,
741
       dat_a_o  => lifo_dout,
742
 
743
       we_b_i   => '0',
744
       en_b_i   => sys_clk_en,
745
       dat_b_i  => bram_dat_b,
746
       dat_b_o  => ram_dout
747
    );
748
  -- Select the appropriate write address
749
  -- This was done so that LIFO reads are ready all the time, but FIFO writes
750
  -- are still accomodated when requested.
751
  ra_row <= wr_row when fifo_wr_i='1' else lf_row;
752
 
753
  -- Formulate the lf_row address, which is one less than the wr_row, because
754
  -- the wr_row points to a "fresh" location with nothing in it, while the 
755
  -- lf_row selects the most recently written data item (the LI part of LIFO.)
756
  -- When the fifo_lifo is empty, this admittedly sets the lf_row pointing to
757
  -- the location in RAM which is before the tail pointer, so that a
758
  -- meaningless data word is output on the bus.  The alternative would be to
759
  -- add logic to output a known constant on the bus instead.
760
  lf_row <= wr_row-1;
761
 
762
 
763
  bram_dat_b <= (others=>'0');
764
  ram_we_a <= '1' when fifo_wr_i='1' and current_state/=st_full else
765
              '1' when fifo_wr_i='1' and current_state=st_full and fifo_rd_i='1' else
766
              '1' when fifo_wr_i='1' and current_state=st_full and lifo_rd_i='1' else
767
              '0';
768
  fifo_dout <= ram_dout;
769
 
770
 
771
-------------------------
772
-- The FIFO state machine
773
  clocked : process(sys_clk, sys_rst_n)
774
 
775
  procedure do_write is
776
  begin
777
    if (wr_row=DEPTH-1) then  -- Roll buffer index for non-power-of-two
778
      wr_row <= (others=>'0');
779
    else
780
      wr_row<=wr_row+1;
781
    end if;
782
  end do_write;
783
 
784
  procedure do_read is
785
  begin
786
    if (rd_row=DEPTH-1) then  -- Roll buffer index for non-power-of-two
787
      rd_row <= (others=>'0');
788
    else
789
      rd_row<=rd_row+1;
790
    end if;
791
  end do_read;
792
 
793
  begin
794
    if (sys_rst_n = '0') then
795
      current_state <= st_empty;
796
      rd_row   <= (others=>'0');
797
      wr_row   <= (others=>'0');
798
 
799
    elsif (sys_clk'EVENT and sys_clk = '1') then
800
      if (sys_clk_en='1') then
801
        if (reset_i='1') then
802
          current_state <= st_empty;
803
          wr_row <= (others=>'0');
804
          rd_row <= (others=>'0');
805
        else
806
          case current_state is
807
 
808
          -- When empty, one can only read if also writing
809
          when st_empty =>
810
            if (fifo_wr_i='1') then
811
              if (lifo_rd_i='0' and fifo_rd_i='0') then
812
                do_write;
813
                current_state <= st_data;
814
              elsif (lifo_rd_i='0' and fifo_rd_i='1') then
815
                do_read;
816
                do_write;
817
              elsif (lifo_rd_i='1' and fifo_rd_i='0') then
818
                -- Here, the wr_row remains unchanged.
819
                null;
820
              elsif (lifo_rd_i='1' and fifo_rd_i='1') then
821
                -- This is a condition in which one of the read requests
822
                -- must, of necessity, be ignored.
823
                if (FIFO_RD_FIRST/=0) then
824
                  do_write;
825
                  do_read;
826
                else
827
                  -- Here, the wr_row remains unchanged.
828
                  null;
829
                end if;
830
              end if;
831
            end if;
832
 
833
          when st_data =>
834
            -- As a coding choice, it has been decided to cut here with
835
            -- the fill level "analytical knife" first and then
836
            -- fully decode the read combinations as the second
837
            -- "analytical knife," making the treatment of writing the
838
            -- third "analytical knife" to be used.  Then, the fourth
839
            -- analytical knife is the treatment of FIFO_RD_FIRST.
840
            -- The same logic can, of course, also be coded up correctly
841
            -- by applying the same knives in a different order, do you
842
            -- know it?  BTW, the reference to analytical knives has been
843
            -- taken from Robert M. Pirsig's book
844
            -- "Zen and the Art of Motorcycle Maintenance."
845
            if (fill_level>1) then
846
              if (lifo_rd_i='0' and fifo_rd_i='0') then
847
                -- In this case can the full state be reached
848
                if (fifo_wr_i='1') then
849
                  do_write;
850
                  if (fill_level=DEPTH-1) then
851
                    current_state <= st_full;
852
                  end if;
853
                end if;
854
              elsif (lifo_rd_i='0' and fifo_rd_i='1') then
855
                if (fifo_wr_i='1') then
856
                  do_read;
857
                  do_write;
858
                else
859
                  do_read;
860
                end if;
861
              elsif (lifo_rd_i='1' and fifo_rd_i='0') then
862
                if (fifo_wr_i='1') then
863
                  null;
864
                else
865
                  wr_row <= wr_row-1;
866
                end if;
867
              elsif (lifo_rd_i='1' and fifo_rd_i='1') then
868
                if (fifo_wr_i='1') then
869
                  -- Here, the write and both reads get done, and the wr_row
870
                  -- remains unchanged.
871
                  do_read;
872
                else
873
                  wr_row <= wr_row-1;
874
                  do_read;
875
                end if;
876
              end if;
877
 
878
            elsif (fill_level=1) then
879
              if (lifo_rd_i='0' and fifo_rd_i='0') then
880
                if (fifo_wr_i='1') then
881
                  do_write;
882
                  if (fill_level=DEPTH-1) then
883
                    current_state <= st_full;
884
                  end if;
885
                end if;
886
              elsif (lifo_rd_i='0' and fifo_rd_i='1') then
887
                if (fifo_wr_i='1') then
888
                  do_read;
889
                  do_write;
890
                else
891
                  do_read;
892
                  current_state <= st_empty;
893
                end if;
894
              elsif (lifo_rd_i='1' and fifo_rd_i='0') then
895
                if (fifo_wr_i='1') then
896
                  null;
897
                else
898
                  wr_row <= wr_row-1;
899
                  current_state <= st_empty;
900
                end if;
901
              elsif (lifo_rd_i='1' and fifo_rd_i='1') then
902
                if (fifo_wr_i='1') then
903
                  -- Here, the write and both reads get done, and the wr_row
904
                  -- remains unchanged.
905
                  do_read;
906
                  current_state <= st_empty;
907
                else
908
                  -- This is a condition in which one of the read requests
909
                  -- must, of necessity, be ignored.
910
                  if (FIFO_RD_FIRST/=0) then
911
                    do_read;
912
                    current_state <= st_empty;
913
                  else
914
                    wr_row <= wr_row-1;
915
                    current_state <= st_empty;
916
                  end if;
917
                end if;
918
              end if;
919
            end if;
920
 
921
          -- When full, one can only write if also reading
922
          when st_full =>
923
            if (lifo_rd_i='0' and fifo_rd_i='0') then
924
              null;
925
            elsif (lifo_rd_i='0' and fifo_rd_i='1') then
926
              if (fifo_wr_i='1') then
927
                do_read;
928
                do_write;
929
              else
930
                do_read;
931
                current_state <= st_data;
932
              end if;
933
            elsif (lifo_rd_i='1' and fifo_rd_i='0') then
934
              -- Here, wr_row remains unchanged.
935
              -- Other logic makes the write happen, however.
936
              null;
937
            elsif (lifo_rd_i='1' and fifo_rd_i='1') then
938
              wr_row <= wr_row-1;
939
              do_read;
940
              current_state <= st_data;
941
            end if;
942
 
943
          when others => null;
944
          end case;
945
 
946
        end if;
947
      end if; -- sys_clk_en
948
    end if; -- sys_clk
949
  end process clocked;
950
 
951
 
952
end beh;
953
 

powered by: WebSVN 2.1.0

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