Skip to content

Commit

Permalink
Set ASYNC_REG on 2sync flops and tweak constraints
Browse files Browse the repository at this point in the history
Do as the tool requests and set ASYNC_REG on the registers within
the 2-stage synchroniser CDC primitive. This should add implicit timing
exceptions, prevent dangerous optimisations, and supposedly apply
special PnR rules to reduce the MTBF from metastability.
Remove now-redundant explicit false_path.

Improve nearby comments while making changes.
  • Loading branch information
elliotb-lowrisc authored and GregAC committed Nov 1, 2024
1 parent ae3afd4 commit 30affb9
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 14 deletions.
16 changes: 14 additions & 2 deletions data/pins_sonata.xdc
Original file line number Diff line number Diff line change
Expand Up @@ -315,12 +315,24 @@ set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS18 } [get_ports { hype
set_property IOB TRUE [get_cells -hier -filter {NAME =~ */hbmc_ctrl_inst/cs_n_reg}]
set_property IOB TRUE [get_cells -hier -filter {NAME =~ */hbmc_ctrl_inst/reset_n_reg}]

## Voltage and bistream
## Voltage and bitstream
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]

# Primitives
## Clock-Domain Crossing (CDC) primitives.
# Set DONT_TOUCH on CDC primitives to prevent pin or boundary changes that
# could make it difficult to find and apply timing exceptions to them or
# perform CDC/RDC analysis on them later.
# May be able to be downgraded to KEEP_HIERARCHY, but play it safe for now.
set_property DONT_TOUCH TRUE [get_cells -hier -filter {ORIG_REF_NAME == prim_flop_2sync}]
set_property DONT_TOUCH TRUE [get_cells -hier -filter {ORIG_REF_NAME == prim_fifo_async}]
set_property DONT_TOUCH TRUE [get_cells -hier -filter {ORIG_REF_NAME == prim_fifo_async_simple}]
# Set ASYNC_REG on the flops our flop-based CDC synchronisers to get
# special place&route to reduce the MTBF from metastability, to prevent
# dangerous optimisations, and to infer D-pin timing exceptions.
# See the ASYNC_REG sections of UG901 or UG912 for details.
set sync_cells [get_cells -hier -filter {ORIG_REF_NAME == prim_flop_2sync}]
set sync_clk_in [get_pins -of $sync_cells -filter {REF_PIN_NAME == clk_i}]
set sync_flops [all_fanout -flat -only_cells -endpoints_only $sync_clk_in]
set_property ASYNC_REG TRUE $sync_flops
19 changes: 7 additions & 12 deletions data/synth_timing.xdc
Original file line number Diff line number Diff line change
Expand Up @@ -687,25 +687,17 @@ set_false_path -to [get_ports hyperram_cs]
set_false_path -to [get_ports hyperram_nrst]

## prim_flop_2sync
# Set false_path timing exceptions on 2-stage synchroniser inputs.
# Target the inputs because the flops inside are clocked by the destination.
#
# Reliant on the hierarchical pin names of the synchronisers remaining
# unchanged during synthesis due to use of DONT_TOUCH or KEEP_HIERARCHY.
set sync_cells [get_cells -hier -filter {ORIG_REF_NAME == prim_flop_2sync}]
set sync_pins [get_pins -filter {REF_PIN_NAME =~ d_i*} -of $sync_cells]
# Filter out any that do not have a real timing path (fail to find leaf cell).
set sync_endpoints [filter [all_fanout -endpoints_only -flat $sync_pins] IS_LEAF]
set_false_path -to $sync_endpoints
# Explicit false_path not needed so long as ASYNC_REG property is correctly
# set on the underlying flops earlier in the flow.

## prim_fifo_async and prim_fifo_async_simple
# Set false_path timing exceptions on asynchronous fifo outputs.
# Target the outputs because the storage elements are clocked by the source
# clock domain (but made safe to read from the destination clock domain
# thanks to the gray-coded read/write pointers and surrounding logic).
#
# Reliant on the hierarchical pin names of the async fifos remaining
# unchanged during synthesis due to use of DONT_TOUCH or KEEP_HIERARCHY.
# Reliant on the hierarchical pin names used here remaining unchanged during
# synthesis by setting DONT_TOUCH or KEEP_HIERARCHY earlier in the flow.
set async_fifo_cells [get_cells -hier -regexp -filter {ORIG_REF_NAME =~ {prim_fifo_async(_simple)?}}]
set async_fifo_pins [get_pins -filter {REF_PIN_NAME =~ rdata_o*} -of $async_fifo_cells]
set async_fifo_startpoints [all_fanin -startpoints_only -flat $async_fifo_pins]
Expand All @@ -717,6 +709,9 @@ set_false_path -from $async_fifo_startpoints -through $async_fifo_pins

## Reset async-assert sync-deassert CDC - async path to synchroniser reset pins
# Use max_delay rather than false_path to avoid big skew between clock domains.
#
# Reliant on the hierarchical pin names used here remaining unchanged during
# synthesis by setting DONT_TOUCH or KEEP_HIERARCHY earlier in the flow.
set rst_sync_cells [get_cells u_rst_sync/* -filter {ORIG_REF_NAME == prim_flop_2sync}]
set rst_sync_pins [get_pins -filter {REF_PIN_NAME =~ rst_ni} -of $rst_sync_cells]
# Filter out any that do not have a real timing path (fail to find leaf cell).
Expand Down

0 comments on commit 30affb9

Please sign in to comment.