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.

Asychronous FIFO : read_data is not entirely in phase with read_ptr

Status
Not open for further replies.

promach

Advanced Member level 4
Joined
Feb 22, 2016
Messages
1,199
Helped
2
Reputation
4
Reaction score
5
Trophy points
1,318
Activity points
11,636
I am recently working on asychronous FIFO coding implementation.

However, I seem to have encountered a common issue with asynchronous FIFO where read_data signal is not really entirely in-phase with read_ptr signal.
For example, read_data could be 15 or 16 for the read_ptr of 9

Someone told me that read_data is only valid when the empty signal is 0 and is undefined/invalid otherwise.
It seems that I need to do some post-processing (using empty signal) on read_data output instead of modifying the logic inside the asynchronous FIFO ?

Is there really a way to keep read_data signal entirely in-phase with read_ptr signal within the asynchronous FIFO ?

Any idea/comments ?

afifo_read_data_issue.png
 
Last edited:

How are you trying to use this FIFO? are you simply using the external interface? is read_ptr available to you? The standard IO for any fifo would be rdata + empty/valid + rd_en/ack. What more do you really need? Why do you need to care about the read_ptr?
 

Your code is behaving as you wrote it.
Code:
assign read_data = fifo_data[read_ptr[ADDR_WIDTH-1:0]];
read_data is the output of a mux in concurrent code, it changes immediately when either read_ptr or the content of fifo_data is updated, that's what we see in the simulation.

Modeling FIFO RAM with asynchronous output makes only sense if supported by hardware.
--- Updated ---

Most recent FPGA families have dual port RAM with latched read address and thus can't synthesize this hardware description. Implementation would be only possible in logic cells registers.
 
Last edited:

> read_data is the output of a mux in concurrent code, it changes immediately when either read_ptr or the content of fifo_data is updated

Someone told me that this is unavoidable artifact of using asynchronous FIFO.

May I know if there is any other ways of dealing with the mentioned scenario where read_data could be 15 or 16 (for the read_ptr of 9) due to the reason that the fifo_data[9] is being written at the posedge of write_clk ?
 

Maybe you are using a different definition of "asynchronous FIFO". In my understanding, it's a FIFO transporting data between asynchronous clock domains. Your design has a read clock, I would expect that the read side of the dual port RAM is clocked by this clock.

Code:
    always @ (posedge read_clock)
    begin
        read_data <= fifo_data[read_ptr];
    end
--- Updated ---

I suspect however, that if the content of a RAM cell changes while you are accessing it, you also have a basic problem in the read logic. This must never happen, unless you overflow a FIFO without overflow protection.

Please apologize that I don't attempt to redesign your FIFO, just apply some basic comments.
 
Last edited:

I have confirmed that your suggestion above does not work when read_clk domain has a higher clock frequency compared to write_clk domain
 

I have confirmed that your suggestion above does not work when read_clk domain has a higher clock frequency compared to write_clk domain
Say it doesn't work in your present design. Didn't claim it should, just stated that industry standard async FIFO will read the dual port RAM synchronously.
 

The following seems to have the desired solution, in which I had merged into latest github version.

Code:
    always @(posedge read_clk)
    begin
        if(reset_rsync) read_data <= 0;
    
        else if(!empty) read_data <= fifo_data[read_ptr[ADDR_WIDTH-1:0]];  // passed verilator Warning-WIDTH
    end
 

Consider that reset and read enable might conflict with RAM inference requirements because not provided in target FPGA hardware.
 

Why is full being asserted when write_clk is slower than read_clk , and there are enough fifo storage entries ?

1640087351307.png
 

Hi,

You can find here a VHDL Asynchronous FIFO implementation that I designed two years ago.
Feel free to have a lock on it.

Regards.
 
Why is full being asserted when write_clk is slower than read_clk , and there are enough fifo storage entries ?
There are probably not enough entries considering the delay involved with cross domain sync. If the problem persists after increasing the number of entries, I'd suspect faulty full/empty logic.

Does your FIFO spec allow write in full respectively read in empty state?
 
I suspect that my full logic is still incorrect.

The attached testbench and waveform files are generated from https://symbiyosys.readthedocs.io/en/latest/index.html , and it had not yet triggered the phenomenon where the afifo verilog code failed in Modelsim as you have seen earlier.

1640231270420.png
 

Attachments

  • trace11.zip
    5.9 KB · Views: 95

Increasing the FIFO NUM_ENTRIES seems to have temporarily solved the issue, but I am still searching for a more permanent solution without the need of increasing NUM_ENTRIES

Now, I am facing STA setup timing issue and I did some modification which is supposed to help with setup timing, but instead it got worse. Why ?

Note: Search for this verilog code for the keyword STA_SETUP_ISSUE_WITH_READ_DOMAIN
--- Updated ---

There are probably not enough entries considering the delay involved with cross domain sync.

@FvM I got around this above quoted issue using some tricks which would ONLY work when write clock domain is slower than read clock domain. Any comments ?
 
Last edited:

Someone told me that I should only cross one changing bit of read_ptr_gray

Any idea how would I do this elegantly without introducing extra STA issues ?
I mean I need to identify which exact bit is the changing bit

Besides, I was also told that using both read_ptr_sync and read_en_sync to generate full logic will be flagged by Spyglass CDC tool.
 

Additional Notes:

1. should cross all bits of read_ptr_gray for full logic generation, and no CDC issues since read_ptr_gray is already gray-coded.

2. Remove read_en_sync to avoid CDC error associated with 'full' logic, but still able to solve the STA issue by choosing not to increase NUM_ENTRIES when full logic is now correctly implemented for certain corner simulation coverage case , taking into account the cycles delay brought by the FF synchronizer chain.


Please let me know if I miss anything else.

By the way, how would I further simplify this full signal logic and accommodate non-power-of-two values of NUM_ENTRIES ?
 
Last edited:

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top