Skip to content

Commit

Permalink
Split XDC into phys, synth timing, & impl timing
Browse files Browse the repository at this point in the history
Constraints such as false_paths cannot be applied
until after elaboration/synthesis, such as internal false paths.
Splitting the XDC into separate files should allow some constraints
to be read later than others, such as after synthesis.
Edalize/fusesoc do not seem to provide a direct mechanism for this,
but does allow a custom script to set the required Vivado properties.

The existing XDC is split into three files, based on advice in UG949:
"1 file for physical + 1 file for timing (synthesis) +
1 file for timing (implementation)."
The constraints themselves have been left unchanged for now.
  • Loading branch information
elliotb-lowrisc committed Aug 23, 2024
1 parent c072edc commit cd03b71
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 57 deletions.
38 changes: 38 additions & 0 deletions data/impl_timing.xdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
## Copyright lowRISC contributors.
## Licensed under the Apache License, Version 2.0, see LICENSE for details.
## SPDX-License-Identifier: Apache-2.0

# This file is for timing constraints to be applied *after* synthesis.
# i.e. timing constraints on internal paths.

set_false_path -from [get_pins -of [get_cells u_sonata_system/g_hyperram.u_hyperram/u_hbmc_tl_top/u_hbmc_cmd_fifo/*storage*/*]]
set_false_path -from [get_pins -of [get_cells u_sonata_system/g_hyperram.u_hyperram/u_hbmc_tl_top/hbmc_ufifo_inst/u_fifo/*storage*/*]]
set_false_path -from [get_pins -of [get_cells u_sonata_system/g_hyperram.u_hyperram/u_hbmc_tl_top/hbmc_dfifo_inst/u_fifo/*storage*/*]]

# TODO: Want some general constraints that will setup appropriate false paths
# for all CDC prims. An attempt is below but it isn't working yet.
#set sync_cells [get_cells -hier -filter {ORIG_REF_NAME == prim_flop_2sync}]
#
#foreach sync_cell $sync_cells {
# set sync_pins [get_pins -of [get_cells -hier -regexp $sync_cell/.*u_sync_1.*]]
# if {[info exists endpoint_sync_pins_for_false_paths]} {
# set endpoint_sync_pins_for_false_paths $sync_pins
# } else {
# lappend endpoint_sync_pins_for_false_paths $sync_pins
# }
#}
#
#set_false_path -to $endpoint_sync_pins_for_false_paths
#
#set async_fifo_cells [get_cells -hier -filter {ORIG_REF_NAME == prim_fifo_async}]
#
#foreach async_fifo_cell $async_fifo_cells {
# set async_fifo_pins [get_pins -of [get_cells -hier -regexp $async_fifo_cell/.*storage.*]]
# if {[info exists startpoint_fifo_async_pins_for_false_paths]} {
# set startpoint_fifo_async_pins_for_false_paths $async_fifo_pins
# } else {
# lappend startpoint_fifo_async_pins_for_false_paths $async_fifo_pins
# }
#}
#
#set_false_path -from $startpoint_fifo_async_pins_for_false_paths
58 changes: 2 additions & 56 deletions data/pins_sonata.xdc
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,15 @@
## Licensed under the Apache License, Version 2.0, see LICENSE for details.
## SPDX-License-Identifier: Apache-2.0

# This file is for physical constraints.

# Using the names in the PCB design, they should match this file with a case-insensitive search:
# https://github.com/newaetech/sonata-pcb/tree/main

## Clocks
create_clock -period 40.000 -name mainClk -waveform {0.000 20.000} [get_ports mainClk]
create_clock -period 100.000 -name tck_i -waveform {0.000 50.000} [get_ports tck_i]

set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports mainClk];
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets tck_i]

## Clock Domain Crossings
set clks_sys_unbuf [get_clocks -of_objects [get_pin u_clkgen/pll/CLKOUT0]]
set clks_usb_unbuf [get_clocks -of_objects [get_pin u_clkgen/pll/CLKOUT1]]

## Set asynchronous clock groups
set_clock_groups -group ${clks_sys_unbuf} -group ${clks_usb_unbuf} -group mainClk -asynchronous

## Reset
## PCB revision 0.3 and above
set_property -dict { PACKAGE_PIN T5 IOSTANDARD LVCMOS33 } [get_ports {nrst}];
Expand Down Expand Up @@ -291,49 +283,3 @@ set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS18 } [get_ports { hype
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]

set_false_path -to [get_ports hyperram_ckp]
set_false_path -to [get_ports hyperram_ckn]
set_false_path -to [get_ports hyperram_rwds]
set_false_path -to [get_ports hyperram_dq[*]]

# set input false path. dq[*] and rwds are supposed to
# be fully asynchronous for the data recovery logic
set_false_path -from [get_ports hyperram_rwds]
set_false_path -from [get_ports hyperram_dq[*]]

# False path for 'hb_cs_n' and 'hb_reset_n'
set_false_path -to [get_ports hyperram_cs]
set_false_path -to [get_ports hyperram_nrst]

set_false_path -from [get_pins -of [get_cells u_sonata_system/g_hyperram.u_hyperram/u_hbmc_tl_top/u_hbmc_cmd_fifo/*storage*/*]]
set_false_path -from [get_pins -of [get_cells u_sonata_system/g_hyperram.u_hyperram/u_hbmc_tl_top/hbmc_ufifo_inst/u_fifo/*storage*/*]]
set_false_path -from [get_pins -of [get_cells u_sonata_system/g_hyperram.u_hyperram/u_hbmc_tl_top/hbmc_dfifo_inst/u_fifo/*storage*/*]]

# TODO: Want some general constraints that will setup appropriate false paths
# for all CDC prims. An attempt is below but it isn't working yet.
#set sync_cells [get_cells -hier -filter {ORIG_REF_NAME == prim_flop_2sync}]
#
#foreach sync_cell $sync_cells {
# set sync_pins [get_pins -of [get_cells -hier -regexp $sync_cell/.*u_sync_1.*]]
# if {[info exists endpoint_sync_pins_for_false_paths]} {
# set endpoint_sync_pins_for_false_paths $sync_pins
# } else {
# lappend endpoint_sync_pins_for_false_paths $sync_pins
# }
#}
#
#set_false_path -to $endpoint_sync_pins_for_false_paths
#
#set async_fifo_cells [get_cells -hier -filter {ORIG_REF_NAME == prim_fifo_async}]
#
#foreach async_fifo_cell $async_fifo_cells {
# set async_fifo_pins [get_pins -of [get_cells -hier -regexp $async_fifo_cell/.*storage.*]]
# if {[info exists startpoint_fifo_async_pins_for_false_paths]} {
# set startpoint_fifo_async_pins_for_false_paths $async_fifo_pins
# } else {
# lappend startpoint_fifo_async_pins_for_false_paths $async_fifo_pins
# }
#}
#
#set_false_path -from $startpoint_fifo_async_pins_for_false_paths
32 changes: 32 additions & 0 deletions data/synth_timing.xdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## Copyright lowRISC contributors.
## Licensed under the Apache License, Version 2.0, see LICENSE for details.
## SPDX-License-Identifier: Apache-2.0

# This file is for timing constraints to be applied *before* synthesis.
# i.e. timing constraints on top-level ports.

## Clocks
create_clock -period 40.000 -name mainClk -waveform {0.000 20.000} [get_ports mainClk]
create_clock -period 100.000 -name tck_i -waveform {0.000 50.000} [get_ports tck_i]

## Clock Domain Crossings
set clks_sys_unbuf [get_clocks -of_objects [get_pin u_clkgen/pll/CLKOUT0]]
set clks_usb_unbuf [get_clocks -of_objects [get_pin u_clkgen/pll/CLKOUT1]]

## Set asynchronous clock groups
set_clock_groups -group ${clks_sys_unbuf} -group ${clks_usb_unbuf} -group mainClk -asynchronous

## HyperRAM
set_false_path -to [get_ports hyperram_ckp]
set_false_path -to [get_ports hyperram_ckn]
set_false_path -to [get_ports hyperram_rwds]
set_false_path -to [get_ports hyperram_dq[*]]

# set input false path. dq[*] and rwds are supposed to
# be fully asynchronous for the data recovery logic
set_false_path -from [get_ports hyperram_rwds]
set_false_path -from [get_ports hyperram_dq[*]]

# False path for 'hb_cs_n' and 'hb_reset_n'
set_false_path -to [get_ports hyperram_cs]
set_false_path -to [get_ports hyperram_nrst]
16 changes: 16 additions & 0 deletions flow/vivado_setup.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

## Vivado project custom configuration script
##
## For configuration not supported by fusesoc/edalize

# Configure when and how the post-synthesis timing XDC file is read.
# The `Tcl` `file_type` makes Vivado use the `-unmanaged` argument with
# `read_xdc`, which allows us to use commands such as `foreach`.
# The `used_in_synthesis` property makes Vivado delay reading the file
# until after synthesis, allowing internal paths to be specified.
# Note: `file_type` must be set before `used_in_synthesis`.
set_property file_type Tcl [get_files impl_timing.xdc]
set_property used_in_synthesis false [get_files impl_timing.xdc]
10 changes: 9 additions & 1 deletion sonata.core
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,16 @@ filesets:

files_constraints_sonata:
files:
- data/pins_sonata.xdc
# Per AMD advice (UG949):
- data/pins_sonata.xdc # 1 file for physical +
- data/synth_timing.xdc # 1 file for timing (synthesis) +
- data/impl_timing.xdc # 1 file for timing (implementation)
file_type: xdc

files_tcl:
files:
- flow/vivado_setup.tcl : { file_type: tclSource }

parameters:
# XXX: This parameter needs to be absolute, or relative to the *.runs/synth_1
# directory. It's best to pass it as absolute path when invoking fusesoc, e.g.
Expand Down Expand Up @@ -78,6 +85,7 @@ targets:
filesets_append:
- files_sonata
- files_constraints_sonata
- files_tcl
toplevel: top_sonata
tools:
vivado:
Expand Down

0 comments on commit cd03b71

Please sign in to comment.