# Strange behaviour of Standard dual-clock FIFO

Status
Not open for further replies.

#### Taki_comp

##### Member level 1
I'm using the Xilinx core generator to generate a dual-clock FIFO in standard read mode, the simulation in Isim shows a strange behaviour, the first two writings are skipped as indicated by the wr_data_count output

can somebody please tell me what are the possible reasons for such behaviour ?

#### KlausST

##### Super Moderator
Staff member
Hi,

I don't think it is a good idea for a simulation of a FIFO to have RD abd WR clock with synchronous edges.

Especially you read the FIFO before there is data in the FIFO.
It's like drinking from a glass before it is filled....or drinking from a glass what it is filled at the same time. Difficult.

--> do a WR first, then the FIFO should set a flag indicating that there is data in the FIFO, do a RD only when this flag is set.

Klaus

#### Taki_comp

##### Member level 1
I'm not sure i'm following you, but can you tell me why_data_count is incrementing even though rd_en = 0, this is my testbench code:
Code:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;

ENTITY FIFO_tb IS
END FIFO_tb;

ARCHITECTURE behavior OF FIFO_tb IS

-- Component Declaration for the Unit Under Test (UUT)

COMPONENT Asynch_FIFO
PORT(
rst : IN  std_logic;
wr_clk : IN  std_logic;
rd_clk : IN  std_logic;
din : IN  std_logic_vector(7 downto 0);
wr_en : IN  std_logic;
rd_en : IN  std_logic;
dout : OUT  std_logic_vector(7 downto 0);
full : OUT  std_logic;
empty : OUT  std_logic;
rd_data_count : OUT  std_logic_vector(7 downto 0);
wr_data_count : OUT  std_logic_vector(7 downto 0)
);
END COMPONENT;

--Inputs
signal rst : std_logic := '0';
signal wr_clk : std_logic := '0';
signal rd_clk : std_logic := '0';
signal din : std_logic_vector(7 downto 0) := (others => '0');
signal wr_en : std_logic := '0';
signal rd_en : std_logic := '0';

--Outputs
signal dout : std_logic_vector(7 downto 0);
signal full : std_logic;
signal empty : std_logic;
signal rd_data_count : std_logic_vector(7 downto 0);
signal wr_data_count : std_logic_vector(7 downto 0);

-- Clock period definitions
constant wr_clk_period : time := 10 ns;
constant rd_clk_period : time := 10 ns;

BEGIN

-- Instantiate the Unit Under Test (UUT)
uut: Asynch_FIFO PORT MAP (
rst => rst,
wr_clk => wr_clk,
rd_clk => rd_clk,
din => din,
wr_en => wr_en,
rd_en => rd_en,
dout => dout,
full => full,
empty => empty,
rd_data_count => rd_data_count,
wr_data_count => wr_data_count
);

-- Clock process definitions
wr_clk_process :process
begin
wr_clk <= '0';
wait for wr_clk_period/2;
wr_clk <= '1';
wait for wr_clk_period/2;
end process;

rd_clk_process :process
begin
rd_clk <= '0';
wait for rd_clk_period/2;
rd_clk <= '1';
wait for rd_clk_period/2;
end process;

-- Stimulus process
stim_proc: process
begin
RST <= '1';
wait for Wr_clk_period;
RST <= '0';
wait for Wr_clk_period;
for i in 0 to 255 loop
Wr_en <= '1';
wait for Wr_clk_period;
din <= din + 1;
end loop;
for i in 0 to 255 loop
Wr_en <= '0';
Rd_en <= '1';
wait for Rd_clk_period;
end loop;

-- insert stimulus here

wait;
end process;

END;

#### TrickyDicky

The count signals have a slight lag in their response, as they have to synchronise the addresses across the clock domains safely. You should only ever rely on a full/almost_full signals to prevent overflowing a FIFO. No writes are skipped - there is just a lag.
The read side data count will just be the same as the write side, delayed by a few clocks.

Taki_comp

### Taki_comp

Points: 2

#### Taki_comp

##### Member level 1
Thank you very much, I think it's much better if I implement my own FIFO

#### TrickyDicky

I think its much better if you DONT implement your own FIFO. The Xilinx DC Fifo has many many many more hours of usage and verification.
What are you trying to do with it?

#### Taki_comp

##### Member level 1
I am trying to store video feed from dual-port memory inside it

#### KlausST

##### Super Moderator
Staff member
Hi,

In short: don't read if FIFO is empty.

Klaus

#### TrickyDicky

Hi,

In short: don't read if FIFO is empty.

Klaus

If underflow protection is ON, then this is not a problem. It means for a bus Like AXIs or AvalonST, you can simply connect the tready to the read_enable, and the tvalid to not empty. No extra logic needed. And Vice-versa for the write side.

#### KlausST

##### Super Moderator
Staff member
Hi,

You are correct from the view if the FIFO, but the "reader" can't be sure if the data is valid or not.

And for the simulation: if there are RD and WR edges at the same time on an empty device you can't verify the function of the FIFO.
--> operate the FIFO according it's specifications.

Klaus

#### TrickyDicky

Hi,

You are correct from the view if the FIFO, but the "reader" can't be sure if the data is valid or not.

And for the simulation: if there are RD and WR edges at the same time on an empty device you can't verify the function of the FIFO.
--> operate the FIFO according it's specifications.

Klaus

Both the Altera and Xilinx fifo work basically the same (with read/write protect enabled) - if empty is asserted, then data is not valid. If empty = '0', then data is valid. It doesnt matter if you are reading or writing or not - you know you have no data if the fifo is empty, so you can just hold read_enable high until a word comes along. Internally the FIFO knows how full it is, so if the fifo is empty, reading and writing at the same time from an empty fifo have no effect, as it is empty, and propogating a word from the write side to the read side takes at least 1 clock.

This allows you to connect an AXIs bus directly to the FIFO.

Without read/write protect enabled, then yes, you are correct, and reading from an empty fifo is bad news.

Status
Not open for further replies.