Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

async FIFO timing constraints for Vivado #6

Open
caryan opened this issue Dec 16, 2015 · 2 comments
Open

async FIFO timing constraints for Vivado #6

caryan opened this issue Dec 16, 2015 · 2 comments

Comments

@caryan
Copy link

caryan commented Dec 16, 2015

I'm not sure where these should be documented but it would be nice for the user to have a template to get the constraints right for Vivado. After, poking around in the FIFO from Xilinx and Xilinx forums, this works for me:

#grey coded counter synchronizers in  get a max_delay -datapath only
set wrclk [get_clocks -of_objects [get_ports input_clk]]
set rdclk [get_clocks -of_objects [get_ports output_clk]]
set_max_delay -from [get_cells fifo_inst/wr_ptr_gray_reg_reg[*]] -to [get_cells fifo_inst/wr_ptr_gray_sync1_reg_reg[*]] -datapath_only [get_property -min PERIOD $wrclk]
set_max_delay -from [get_cells fifo_inst/rd_ptr_gray_reg_reg[*]] -to [get_cells fifo_inst/rd_ptr_gray_sync1_reg_reg[*]] -datapath_only [get_property -min PERIOD $rdclk]

#set ASYNC_REG property for all registers in the grey code synchronizer chain
set_property ASYNC_REG TRUE [get_cells -regexp {fifo_inst/(wr|rd)_ptr_gray_sync[12]_reg_reg\[\d+\]}]

#ASYNC_REG property and false path to the reset synchronizer
set_property ASYNC_REG TRUE [get_cells -regexp {fifo_inst/(input|output)_rst_sync[123]_reg_reg}]
set_false_path -to [get_cells -regexp {fifo_inst/(input|output)_rst_sync[123]_reg_reg}]
set_false_path -from [get_cells fifo_inst/output_rst_sync1_reg_reg] -to [get_cells fifo_inst/input_rst_sync2_reg_reg]

@alexforencich
Copy link
Owner

Yeah, that sort of stuff should probably go in the readme somewhere. And possibly in an example design of some sort. What I do in ISE is constrain the top-level clocks and then let those constraints propagate down to the instances. That seems to be all that is necessary to make it work. However, Vivado may need a bit more.

@caryan
Copy link
Author

caryan commented Oct 11, 2016

FWIW I now use a tcl script for the Vivado constraints:

set async_fifos [get_cells -hier -filter {(ORIG_REF_NAME == axis_async_fifo || REF_NAME == axis_async_fifo || ORIG_REF_NAME == axis_async_frame_fifo || REF_NAME == axis_async_frame_fifo)}]

foreach fifo $async_fifos {
    puts $fifo
    # ASYNC_REG property on the reset synchronizer flip-flops
    set reset_ffs [get_cells -hier -regexp {.*/(in|out)put_rst_sync[123]_reg_reg} -filter "PARENT == $fifo"]
    set_property ASYNC_REG TRUE $reset_ffs

    # false path to reset pins on the reset synchronizer flip-flops
    set_false_path -to [get_pins -of_objects $reset_ffs -filter {IS_PRESET || IS_RESET}]

    # false path to the second stage reset synchronizer flip-flops data
    set_false_path -to [get_pins $fifo/input_rst_sync2_reg_reg/D]
    set_false_path -to [get_pins $fifo/output_rst_sync2_reg_reg/D]

    # max delayto 2ns to maximize metastability settle time
    set_max_delay -from [get_cells $fifo/input_rst_sync2_reg_reg] -to [get_cells $fifo/input_rst_sync3_reg_reg] 2
    set_max_delay -from [get_cells $fifo/output_rst_sync2_reg_reg] -to [get_cells $fifo/output_rst_sync3_reg_reg] 2

    # set ASYNC_REG property for all registers in the grey code synchronizer chain
    set_property ASYNC_REG TRUE [get_cells -hier -regexp {.*/(wr|rd)_ptr_gray_sync[12]_reg_reg\[\d+\]} -filter "PARENT == $fifo"]

    # extract write/read clocks from the grey code registers
    set read_clk [get_clocks -of_objects [get_pins $fifo/rd_ptr_reg_reg[0]/C]]
    set write_clk [get_clocks -of_objects [get_pins $fifo/wr_ptr_reg_reg[0]/C]]

    # rd_ptr_gray_sync is synchronized from the read clock to the write clock so
    # we use the read clock (launch clock) period to constrain the max_delay
    set_max_delay -from [get_cells $fifo/rd_ptr_gray_reg_reg[*]] -to [get_cells $fifo/rd_ptr_gray_sync1_reg_reg[*]] -datapath_only [get_property -min PERIOD $read_clk]
    # similarly we uuse the write clock period to constrain the max_delay for the wr_ptr_gray_sync
    set_max_delay -from [get_cells $fifo/wr_ptr_gray_reg_reg[*]] -to [get_cells $fifo/wr_ptr_gray_sync1_reg_reg[*]] -datapath_only [get_property -min PERIOD $write_clk]

    # for async_frame_fifos there are a few more status synchronization registers
    if {[string match [get_property ORIG_REF_NAME [get_cells $fifo]] axis_async_frame_fifo] || [string match [get_property REF_NAME [get_cells $fifo]] axis_async_frame_fifo]} {
        set status_sync_regs [get_cells -quiet -hier -regexp {.*/(?:overflow|bad_frame|good_frame)_sync[1234]_reg_reg} -filter "PARENT == $fifo"]
        foreach reg $status_sync_regs {
            set_property ASYNC_REG TRUE $reg
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants