Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Strange behaviour of Standard dual-clock FIFO

Status
Not open for further replies.

Taki_comp

Member level 1
Joined
Dec 7, 2013
Messages
37
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,568
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

FIFO_problem.png

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

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
 

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;
 

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.
 
Thank you very much, I think it's much better if I implement my own FIFO
 

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?
 

I am trying to store video feed from dual-port memory inside it
 

Hi,

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

Klaus
 

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.
 

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
 

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.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top