FPGA Central - World's 1st FPGA / CPLD Portal

FPGA Central

World's 1st FPGA Portal

 

Go Back   FPGA Groups > NewsGroup > VHDL

VHDL comp.lang.vhdl newsgroup / Usenet

Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 08-26-2004, 04:01 PM
ALuPin
Guest
 
Posts: n/a
Default FIFO full/empty

Hi everybody,

I have written some little code for a FIFO and I want
to know whether the signals "l_fifo_full" / "l_fifo_empty" are
correct generated.

I would appreciate your opinion.
Thanx in advance.

Here is the code


library ieee;

use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;


entity frame_fifo is
port( Reset : in std_logic;
Clk : in std_logic;
Data_in : in std_logic_vector(7 downto 0);
Data_in_valid : in std_logic;
Take_data_out : in std_logic;
Erase : in std_logic;
Fifo_full : out std_logic;
Fifo_empty : out std_logic;
Data_out : out std_logic_vector(7 downto 0);
Data_out_valid : out std_logic
);
end frame_fifo;


architecture rtl of frame_fifo is

signal l_fifo_full, next_l_fifo_full : std_logic;
signal l_fifo_empty, next_l_fifo_empty : std_logic;

signal l_data_out : std_logic_vector(7 downto 0);
signal l_data_out_valid : std_logic;

constant ROWS : integer := 16;
constant COLS : integer := 8;

type matrix_buffer is array(0 to ROWS-1, 0 to COLS-1) of std_logic;
signal l_write_array : matrix_buffer;

signal l_read_pointer : integer range 0 to ROWS-1;
signal l_rp_reg : integer range 0 to ROWS-1;
signal l_write_pointer : integer range 0 to ROWS-1;

signal l_wp_turn_around : std_logic;

begin

Fifo_full <= l_fifo_full;
Fifo_empty <= l_fifo_empty;
Data_out <= l_data_out;
Data_out_valid <= l_data_out_valid;

----------------------------------------------------------------------
----------------------------------------------------------------------
-- write FIFO
process(Reset, Clk)
begin
if Reset='1' then
l_write_array <= (others => (others => '0'));
l_write_pointer <= 0;

elsif rising_edge(Clk) then
l_write_array <= l_write_array;
l_write_pointer <= l_write_pointer;

if ((Data_in_valid='1') and (next_l_fifo_full='0')) then

l_write_array(l_write_pointer, 7) <= Data_in(7);
l_write_array(l_write_pointer, 6) <= Data_in(6);
l_write_array(l_write_pointer, 5) <= Data_in(5);
l_write_array(l_write_pointer, 4) <= Data_in(4);
l_write_array(l_write_pointer, 3) <= Data_in(3);
l_write_array(l_write_pointer, 2) <= Data_in(2);
l_write_array(l_write_pointer, 1) <= Data_in(1);
l_write_array(l_write_pointer, 0) <= Data_in(0);

end if;

if (l_fifo_full='1')) then
l_write_pointer <= 0;
end if;

end if;
end process;
----------------------------------------------------------------------
----------------------------------------------------------------------
-- read FIFO
process(Reset, Clk)
begin
if Reset='1' then
l_data_out <= (others => '0');
l_data_out_valid <= '0';
l_read_pointer <= 0;
l_rp_reg <= 0;

elsif rising_edge(Clk) then
l_data_out <= l_data_out;
l_data_out_valid <= '0';
l_read_pointer <= l_read_pointer;
l_rp_reg <= l_read_pointer;

if Take_data_out='1' then

l_data_out(7) <= l_write_array(l_read_pointer, 7);
l_data_out(6) <= l_write_array(l_read_pointer, 6);
l_data_out(5) <= l_write_array(l_read_pointer, 5);
l_data_out(4) <= l_write_array(l_read_pointer, 4);
l_data_out(3) <= l_write_array(l_read_pointer, 3);
l_data_out(2) <= l_write_array(l_read_pointer, 2);
l_data_out(1) <= l_write_array(l_read_pointer, 1);
l_data_out(0) <= l_write_array(l_read_pointer, 0);


l_data_out_valid <= '1';

end if;

if (l_fifo_full='1')) then
l_read_pointer <= 0;
end if;

end if;
end process;
----------------------------------------------------------------------
----------------------------------------------------------------------
-- FIFO full/empty
-- clk transitions
process(Reset, Clk)
begin
if Reset='1' then
l_fifo_full <= '0';
l_fifo_empty <= '0';

elsif rising_edge(Clk) then
l_fifo_full <= next_l_fifo_full;
l_fifo_empty <= next_l_fifo_empty;

end if;
end process;
----------------------------------------------------------------------
-- FIFO full/empty
process(l_fifo_full, l_fifo_empty, l_wp_turn_around, l_write_pointer,
l_read_pointer, l_rp_reg)
begin
next_l_fifo_full <= '0';
next_l_fifo_empty <= '0';

if ((l_wp_turn_around='1') and (l_write_pointer=l_read_pointer) and
(l_read_pointer=l_rp_reg)) then
next_l_fifo_full <= '1';
end if;

if ((l_read_pointer=l_write_pointer) and (l_read_pointer>0)) then
next_l_fifo_empty <= '1';
end if;

end process;
----------------------------------------------------------------------
----------------------------------------------------------------------
-- This signal indicates whether the write pointer has arrived at
-- the maximum value (ROWS-1) and turned back to zero
process(Reset, Clk)
begin
if Reset='1' then
l_wp_turn_around <= '0';

elsif rising_edge(Clk) then
l_wp_turn_around <= l_wp_turn_around;

if (l_write_pointer=ROWS-1) then
l_wp_turn_around <= '1';
elsif (Erase='1') then
l_wp_turn_around <= '0';
end if;

end if;
end process;
----------------------------------------------------------------------
----------------------------------------------------------------------

end rtl;
Reply With Quote
  #2 (permalink)  
Old 08-26-2004, 04:49 PM
Pieter Hulshoff
Guest
 
Posts: n/a
Default Re: FIFO full/empty

ALuPin wrote:

> I have written some little code for a FIFO and I want
> to know whether the signals "l_fifo_full" / "l_fifo_empty" are
> correct generated.


If I understand your code correctly, then I'd say: no. From what I
understand you have a FIFO with one clock, and a read/write enable. You use
the FIFO as an elastic store, running the read/write addresses from 0 to
ROW-1, and round.

Ok, before I dive into your code: please, please, please, please don't use
asynchronous resets. Ok, now that I got that off my chest I can comment on
your code without hurting myself.

> process(Reset, Clk)
> begin

<snip>
> if (l_fifo_full='1')) then
> l_write_pointer <= 0;
> end if;


Ok, I don't understand why you'd want to put your write pointer to 0 when
your fifo is full. Do you just want a reset situation whenever your fifo is
full? Or do you want to do this when you cause an overflow, which would
mean writing into the FIFO when it is full. In that case it should be moved
inside the write if.

> process(Reset, Clk)
> begin

<snip>
> if (l_fifo_full='1')) then
> l_read_pointer <= 0;
> end if;


Something similar here, though I'd expect you to reset the FIFO if you try
to read from an empty FIFO. In this case you should be checking for empty,
and place it within the read if construction.


> process(Reset, Clk)
> begin

<snip>
> elsif rising_edge(Clk) then
> l_fifo_full <= next_l_fifo_full;
> l_fifo_empty <= next_l_fifo_empty;


Why do you wish to delay these indications for 1 clock cycle? Wouldn't you
want to use this information as soon as it is available? The next signals
are already clocked as far as I could see.

> process(l_fifo_full, l_fifo_empty, l_wp_turn_around, l_write_pointer,
> l_read_pointer, l_rp_reg)
> begin

<snip>
> if ((l_wp_turn_around='1') and (l_write_pointer=l_read_pointer) and
> (l_read_pointer=l_rp_reg)) then
> next_l_fifo_full <= '1';
> end if;


You define the FIFO as full if you have a wrap around (why is this a
prerequisite?), your write pointer equals your read pointer, and you didn't
do a read action this time. What if you didn't have a read action nor a
write action? It could be that the FIFO was and still is empty?

> if ((l_read_pointer=l_write_pointer) and (l_read_pointer>0)) then
> next_l_fifo_empty <= '1';
> end if;


Why would the read pointer have to be > 0?

> process(Reset, Clk)
> begin

<snip>
> elsif (Erase='1') then
> l_wp_turn_around <= '0';
> end if;


This is the first time I see the erase used. Wouldn't you want to reset the
read and write pointers at such a time as well?

Regards,

Pieter Hulshoff

Reply With Quote
  #3 (permalink)  
Old 08-26-2004, 05:05 PM
Mike Treseler
Guest
 
Posts: n/a
Default Re: FIFO full/empty

ALuPin wrote:

> I have written some little code for a FIFO and I want
> to know whether the signals "l_fifo_full" / "l_fifo_empty" are
> correct generated.
> I would appreciate your opinion.


It's not a matter of opinion,
it's a matter of simulation.
Consider writing a testbench, and your
question will be answered.

-- Mike Treseler

Reply With Quote
  #4 (permalink)  
Old 08-26-2004, 06:31 PM
ivailokroumov
Guest
 
Posts: n/a
Default Re: FIFO full/empty

Hi ALuPin, I saw your code and i guess that its can be writen more compact.
I'm not sure that your logic is totaly corectly. Do you really to specify
RESET in different process? If you'd put this signal in sample process and
make code more readable you will fine the answer of your question. My
opinion is that these signals are incorrectly defined. I can't understand
what actually you do when comein ERASE comand. Would you tell me, what is
going to happen if your FIFO is half fill in and ERASE going to be "1"?
Are you going to erase all cells of your FIFO.?
On the end rearange your cade and do it more readable and simple. But
:-)) I'm agree withMike Treseler, going to simulate and you will see youg
correctnes ir incorrectness
Best Regards:
Ivaylo Krumov

Reply With Quote
  #5 (permalink)  
Old 08-29-2004, 10:45 AM
valentin tihomirov
Guest
 
Posts: n/a
Default Re: FIFO full/empty

Here is code I've written about a year ago. It looks much simpler.

entity FIFO_CELL is
generic (
WIDTH : Integer := 8
);
port (
CLK : in std_logic;
RST : in std_logic;
EN : in std_logic;
Write: in std_logic; -- Writing puse from provider
Ack: out std_logic; -- signal to provider on Write, '1' set when not Avail
Read: in std_logic; -- Cleaning pulse from consumer
Avail: out std_logic; -- not full flag
DIN: in std_logic_vector(WIDTH-1 downto 0);
DOUT: out std_logic_vector(WIDTH-1 downto 0)
);
end FIFO_CELL;


-- signal passes through the cell if next cell in the chain is empty
architecture ADVANCED of FIFO_CELL is
--signal AvailReg: std_logic;
signal Data: std_logic_vector(WIDTH-1 downto 0);
signal Empty, Cleaning: std_logic;
begin

Cleaning <= Empty or Read; -- empty next cycle

CLOCK : process(Clk, RST)
begin

if RST = '1' then
Empty <= '1';
elsif Rising_Edge(Clk) and EN = '1' then

Empty <= ((not Write) and Cleaning) or (Empty and Read);

if Cleaning = '1' then
Data <= DIN;
end if;

end if; -- CLK

end process;

Ack <= Write and Cleaning;
Avail <= not Empty or Write;
DOUT <= DIN when (Write and Empty) = '1' else Data;


end ADVANCED;






--cascade FIFO_CELLs into a n-DEPTH chain.
-- data consumed from the first cell and written into the first free cell.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity FIFO is
generic (
WIDTH : Integer := 8;
DEPTH : Integer := 4
);
port (
CLK : in std_logic;
RST : in std_logic;
EN : in std_logic;
Write: in std_logic; -- Writeing puse
Ack: out std_logic; -- '1' set on Write (if not Avail), Readed on accept
Read: in std_logic; -- Cleaning pulse
Avail: out std_logic; -- flag
DIN: in std_logic_vector(WIDTH-1 downto 0);
DOUT: out std_logic_vector(WIDTH-1 downto 0)
);
end FIFO;


architecture RTL of FIFO is
type TARRAY is array (0 to DEPTH) of std_logic_vector (WIDTH-1 downto 0);
signal WR : STD_LOGIC_VECTOR(0 to DEPTH);
signal RD : STD_LOGIC_VECTOR(0 to DEPTH);
signal DATA : TARRAY;
begin

VECTOR: for I in 0 to DEPTH-1 generate

FIFO_CELL : entity work.FIFO_CELL(ADVANCED)
generic map (
WIDTH => WIDTH
)
port map (
Clk => Clk,
RST => RST,
EN => EN,
Write => WR(I),
Ack => RD(I),
Read => RD(I+1),
Avail => WR(I+1),

--todo: replace this
DIN => DATA(I),
DOUT => DATA(I+1)
);

end generate;

WR(0) <= Write;
Ack <= RD(0);
Avail <= WR(DEPTH);
RD(DEPTH) <= Read;
Data(0) <= DIN;
DOUT <= Data(DEPTH);

end RTL;


Reply With Quote
Reply

Bookmarks


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Asynchronous FIFO and almost empty - bug? [email protected] FPGA 9 12-03-2007 08:20 AM
Fifo Block-RAM Xilinx ISE - port empty zlotawy FPGA 0 11-24-2007 10:23 AM
FIFO Full logix - V4 motty FPGA 2 07-23-2007 01:55 PM
FPGA : Async FIFO, Programmable full bijoy FPGA 28 12-19-2006 09:29 PM
test (empty) Channing Wen FPGA 0 09-14-2004 05:31 PM


All times are GMT +1. The time now is 11:57 AM.


Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0
Copyright 2008 @ FPGA Central. All rights reserved