UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Adventurer
Adventurer
4,428 Views
Registered: ‎04-23-2014

Constraining asynchronous FIFO

Jump to solution

I have several clock domain crossing in my design for which I have been using the AXI4-Stream Clock Converter IP. I'm trying to replace this IP with an asynchronous FIFO in order to keep my code portable and to be able to configure my code without using IP Integrator.

 

I have found the following code for an asynchronous FIFO online, which follows the recommendations of a Xilinx article:

http://www.asic-world.com/examples/vhdl/asyn_fifo.html

 

Unfortunately I can't seem to get the constraints right. For the read and write pointer (and some other generated leaf cells) vivado doesn't infer the clock. So I added a bunch of create_generated_clock constraints using a divider of 1 and the read or write clock as source.

 

I have then experimented with setting asynchronous clock groups and false path constraints on these generated clocks but I just end up receiving lots of timing violations.

 

Also I get multiple_clock warnings for the status register, but I guess this is OK. I have tried setting the ASYNC_REG property for the status register but that didn't do anything.

 

Does anyone have a suggestion on what constraints to use in this case?

 

I think the relevant part of the linked code is this:

 

 115    --'Quadrant selectors' logic:
 116     process (pNextWordToWrite, pNextWordToRead)
 117         variable set_status_bit0 :std_logic;
 118         variable set_status_bit1 :std_logic;
 119         variable rst_status_bit0 :std_logic;
 120         variable rst_status_bit1 :std_logic;
 121     begin
 122         set_status_bit0 := pNextWordToWrite(ADDR_WIDTH-2) xnor pNextWordToRead(ADDR_WIDTH-1);
 123         set_status_bit1 := pNextWordToWrite(ADDR_WIDTH-1) xor  pNextWordToRead(ADDR_WIDTH-2);
 124         Set_Status <= set_status_bit0 and set_status_bit1;
 125         
 126         rst_status_bit0 := pNextWordToWrite(ADDR_WIDTH-2) xor  pNextWordToRead(ADDR_WIDTH-1);
 127         rst_status_bit1 := pNextWordToWrite(ADDR_WIDTH-1) xnor pNextWordToRead(ADDR_WIDTH-2);
 128         Rst_Status      <= rst_status_bit0 and rst_status_bit1;
 129     end process;
 130     
 131    --'Status' latch logic:
 132     process (Set_Status, Rst_Status, Clear_in) begin
133 if (Rst_Status = '1' or Clear_in = '1') then 134 Status <= '0'; --Going 'Empty'. 135 elsif (Set_Status = '1') then 136 Status <= '1'; --Going 'Full'. 137 end if; 138 end process;

 

pNextWordToWrite and pNextWordToRead are timed by two different clocks.

 

Thanks

0 Kudos
1 Solution

Accepted Solutions
Historian
Historian
7,920 Views
Registered: ‎01-23-2009

Re: Constraining asynchronous FIFO

Jump to solution

I haven't fully analyzed the RTL code, but I would not recommend it - it uses several "bad" design practices:

  - It uses a latch

  - It uses the asynchronous preset/clear inputs of flip-flops for part of its functionality

 

(You say it follows the recommendations of a Xilinx article, but these would all not be recommended by Xilinx).

 

It is possible to design a "generic" clock crossing FIFO without using any of these

  - infer the RAM

  - use Gray counts for bringing addresses between domains

  - use standard "two back to back flip-flop" synchronizers (with the ASYNC_REG property set) to move the Gray coded read pointer into the write domain (for generating full) and the Gray coded write pointer into the read domain (for generating empty)

 

Its your choice as to whether you want to actually have only Gray coded pointer (and actually access the RAM in a Gray order), or have binary pointers which are converted to and from Gray as you do the clock crossing (be sure to register the outputs of your bin2gray before the synchronizer).

 

As for constraints, the Gray code clock crossers should be constrained with

 

set_max_delay -datapath_only -from <gray register on read domain> -to <synchronizer on write domain> <period of read clock>

set_max_delay -datapath_only -from <gray register on write domain> -to <synchronizer on read domain> <period of write clock>

 

That should be all that is necessary (with the possible addition of some stuff for reset).

 

Avrum

5 Replies
Xilinx Employee
Xilinx Employee
4,418 Views
Registered: ‎08-01-2008

Re: Constraining asynchronous FIFO

Jump to solution
use xilinx FIFO generator IP. IP provide constraints file as well

https://www.xilinx.com/support/documentation/ip_documentation/fifo_generator/v12_0/pg057-fifo-generator.pdf

For other constraint refer this guide
https://www.xilinx.com/support/documentation/sw_manuals/xilinx2016_2/ug903-vivado-using-constraints.pdf
Thanks and Regards
Balkrishan
--------------------------------------------------------------------------------------------
Please mark the post as an answer "Accept as solution" in case it helped resolve your query.
Give kudos in case a post in case it guided to the solution.
0 Kudos
Explorer
Explorer
4,401 Views
Registered: ‎11-25-2015

Re: Constraining asynchronous FIFO

Jump to solution

@cone83

 

ASYNC_REG prevents X-propagation during simulation and also tells the tool to place them closely. It has nothing to do with multiple clock definitions.  Can you share your current constraints and timing report to help you with the violations?

 

Regards,

Sravanthi

0 Kudos
Historian
Historian
7,921 Views
Registered: ‎01-23-2009

Re: Constraining asynchronous FIFO

Jump to solution

I haven't fully analyzed the RTL code, but I would not recommend it - it uses several "bad" design practices:

  - It uses a latch

  - It uses the asynchronous preset/clear inputs of flip-flops for part of its functionality

 

(You say it follows the recommendations of a Xilinx article, but these would all not be recommended by Xilinx).

 

It is possible to design a "generic" clock crossing FIFO without using any of these

  - infer the RAM

  - use Gray counts for bringing addresses between domains

  - use standard "two back to back flip-flop" synchronizers (with the ASYNC_REG property set) to move the Gray coded read pointer into the write domain (for generating full) and the Gray coded write pointer into the read domain (for generating empty)

 

Its your choice as to whether you want to actually have only Gray coded pointer (and actually access the RAM in a Gray order), or have binary pointers which are converted to and from Gray as you do the clock crossing (be sure to register the outputs of your bin2gray before the synchronizer).

 

As for constraints, the Gray code clock crossers should be constrained with

 

set_max_delay -datapath_only -from <gray register on read domain> -to <synchronizer on write domain> <period of read clock>

set_max_delay -datapath_only -from <gray register on write domain> -to <synchronizer on read domain> <period of write clock>

 

That should be all that is necessary (with the possible addition of some stuff for reset).

 

Avrum

Adventurer
Adventurer
4,369 Views
Registered: ‎04-23-2014

Re: Constraining asynchronous FIFO

Jump to solution

Thank you so much for the feedback. I have had another look around and I found another free async FIFO implementation at https://github.com/alexforencich/verilog-axis

This one synthesizes out of the box with minimal constraints. So I'll be using this one, even though I'm not very happy with mixing Verilog code into my VHDL project.

0 Kudos
Adventurer
Adventurer
4,365 Views
Registered: ‎04-23-2014

Re: Constraining asynchronous FIFO

Jump to solution
0 Kudos