Skip to content

Commit cd03b71

Browse files
Split XDC into phys, synth timing, & impl timing
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.
1 parent c072edc commit cd03b71

File tree

5 files changed

+97
-57
lines changed

5 files changed

+97
-57
lines changed

data/impl_timing.xdc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
## Copyright lowRISC contributors.
2+
## Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
## SPDX-License-Identifier: Apache-2.0
4+
5+
# This file is for timing constraints to be applied *after* synthesis.
6+
# i.e. timing constraints on internal paths.
7+
8+
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*/*]]
9+
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*/*]]
10+
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*/*]]
11+
12+
# TODO: Want some general constraints that will setup appropriate false paths
13+
# for all CDC prims. An attempt is below but it isn't working yet.
14+
#set sync_cells [get_cells -hier -filter {ORIG_REF_NAME == prim_flop_2sync}]
15+
#
16+
#foreach sync_cell $sync_cells {
17+
# set sync_pins [get_pins -of [get_cells -hier -regexp $sync_cell/.*u_sync_1.*]]
18+
# if {[info exists endpoint_sync_pins_for_false_paths]} {
19+
# set endpoint_sync_pins_for_false_paths $sync_pins
20+
# } else {
21+
# lappend endpoint_sync_pins_for_false_paths $sync_pins
22+
# }
23+
#}
24+
#
25+
#set_false_path -to $endpoint_sync_pins_for_false_paths
26+
#
27+
#set async_fifo_cells [get_cells -hier -filter {ORIG_REF_NAME == prim_fifo_async}]
28+
#
29+
#foreach async_fifo_cell $async_fifo_cells {
30+
# set async_fifo_pins [get_pins -of [get_cells -hier -regexp $async_fifo_cell/.*storage.*]]
31+
# if {[info exists startpoint_fifo_async_pins_for_false_paths]} {
32+
# set startpoint_fifo_async_pins_for_false_paths $async_fifo_pins
33+
# } else {
34+
# lappend startpoint_fifo_async_pins_for_false_paths $async_fifo_pins
35+
# }
36+
#}
37+
#
38+
#set_false_path -from $startpoint_fifo_async_pins_for_false_paths

data/pins_sonata.xdc

Lines changed: 2 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,15 @@
22
## Licensed under the Apache License, Version 2.0, see LICENSE for details.
33
## SPDX-License-Identifier: Apache-2.0
44

5+
# This file is for physical constraints.
6+
57
# Using the names in the PCB design, they should match this file with a case-insensitive search:
68
# https://github.com/newaetech/sonata-pcb/tree/main
79

810
## Clocks
9-
create_clock -period 40.000 -name mainClk -waveform {0.000 20.000} [get_ports mainClk]
10-
create_clock -period 100.000 -name tck_i -waveform {0.000 50.000} [get_ports tck_i]
11-
1211
set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports mainClk];
1312
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets tck_i]
1413

15-
## Clock Domain Crossings
16-
set clks_sys_unbuf [get_clocks -of_objects [get_pin u_clkgen/pll/CLKOUT0]]
17-
set clks_usb_unbuf [get_clocks -of_objects [get_pin u_clkgen/pll/CLKOUT1]]
18-
19-
## Set asynchronous clock groups
20-
set_clock_groups -group ${clks_sys_unbuf} -group ${clks_usb_unbuf} -group mainClk -asynchronous
21-
2214
## Reset
2315
## PCB revision 0.3 and above
2416
set_property -dict { PACKAGE_PIN T5 IOSTANDARD LVCMOS33 } [get_ports {nrst}];
@@ -291,49 +283,3 @@ set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS18 } [get_ports { hype
291283
set_property CFGBVS VCCO [current_design]
292284
set_property CONFIG_VOLTAGE 3.3 [current_design]
293285
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
294-
295-
set_false_path -to [get_ports hyperram_ckp]
296-
set_false_path -to [get_ports hyperram_ckn]
297-
set_false_path -to [get_ports hyperram_rwds]
298-
set_false_path -to [get_ports hyperram_dq[*]]
299-
300-
# set input false path. dq[*] and rwds are supposed to
301-
# be fully asynchronous for the data recovery logic
302-
set_false_path -from [get_ports hyperram_rwds]
303-
set_false_path -from [get_ports hyperram_dq[*]]
304-
305-
# False path for 'hb_cs_n' and 'hb_reset_n'
306-
set_false_path -to [get_ports hyperram_cs]
307-
set_false_path -to [get_ports hyperram_nrst]
308-
309-
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*/*]]
310-
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*/*]]
311-
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*/*]]
312-
313-
# TODO: Want some general constraints that will setup appropriate false paths
314-
# for all CDC prims. An attempt is below but it isn't working yet.
315-
#set sync_cells [get_cells -hier -filter {ORIG_REF_NAME == prim_flop_2sync}]
316-
#
317-
#foreach sync_cell $sync_cells {
318-
# set sync_pins [get_pins -of [get_cells -hier -regexp $sync_cell/.*u_sync_1.*]]
319-
# if {[info exists endpoint_sync_pins_for_false_paths]} {
320-
# set endpoint_sync_pins_for_false_paths $sync_pins
321-
# } else {
322-
# lappend endpoint_sync_pins_for_false_paths $sync_pins
323-
# }
324-
#}
325-
#
326-
#set_false_path -to $endpoint_sync_pins_for_false_paths
327-
#
328-
#set async_fifo_cells [get_cells -hier -filter {ORIG_REF_NAME == prim_fifo_async}]
329-
#
330-
#foreach async_fifo_cell $async_fifo_cells {
331-
# set async_fifo_pins [get_pins -of [get_cells -hier -regexp $async_fifo_cell/.*storage.*]]
332-
# if {[info exists startpoint_fifo_async_pins_for_false_paths]} {
333-
# set startpoint_fifo_async_pins_for_false_paths $async_fifo_pins
334-
# } else {
335-
# lappend startpoint_fifo_async_pins_for_false_paths $async_fifo_pins
336-
# }
337-
#}
338-
#
339-
#set_false_path -from $startpoint_fifo_async_pins_for_false_paths

data/synth_timing.xdc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
## Copyright lowRISC contributors.
2+
## Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
## SPDX-License-Identifier: Apache-2.0
4+
5+
# This file is for timing constraints to be applied *before* synthesis.
6+
# i.e. timing constraints on top-level ports.
7+
8+
## Clocks
9+
create_clock -period 40.000 -name mainClk -waveform {0.000 20.000} [get_ports mainClk]
10+
create_clock -period 100.000 -name tck_i -waveform {0.000 50.000} [get_ports tck_i]
11+
12+
## Clock Domain Crossings
13+
set clks_sys_unbuf [get_clocks -of_objects [get_pin u_clkgen/pll/CLKOUT0]]
14+
set clks_usb_unbuf [get_clocks -of_objects [get_pin u_clkgen/pll/CLKOUT1]]
15+
16+
## Set asynchronous clock groups
17+
set_clock_groups -group ${clks_sys_unbuf} -group ${clks_usb_unbuf} -group mainClk -asynchronous
18+
19+
## HyperRAM
20+
set_false_path -to [get_ports hyperram_ckp]
21+
set_false_path -to [get_ports hyperram_ckn]
22+
set_false_path -to [get_ports hyperram_rwds]
23+
set_false_path -to [get_ports hyperram_dq[*]]
24+
25+
# set input false path. dq[*] and rwds are supposed to
26+
# be fully asynchronous for the data recovery logic
27+
set_false_path -from [get_ports hyperram_rwds]
28+
set_false_path -from [get_ports hyperram_dq[*]]
29+
30+
# False path for 'hb_cs_n' and 'hb_reset_n'
31+
set_false_path -to [get_ports hyperram_cs]
32+
set_false_path -to [get_ports hyperram_nrst]

flow/vivado_setup.tcl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copyright lowRISC contributors.
2+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
## Vivado project custom configuration script
6+
##
7+
## For configuration not supported by fusesoc/edalize
8+
9+
# Configure when and how the post-synthesis timing XDC file is read.
10+
# The `Tcl` `file_type` makes Vivado use the `-unmanaged` argument with
11+
# `read_xdc`, which allows us to use commands such as `foreach`.
12+
# The `used_in_synthesis` property makes Vivado delay reading the file
13+
# until after synthesis, allowing internal paths to be specified.
14+
# Note: `file_type` must be set before `used_in_synthesis`.
15+
set_property file_type Tcl [get_files impl_timing.xdc]
16+
set_property used_in_synthesis false [get_files impl_timing.xdc]

sonata.core

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,16 @@ filesets:
3535

3636
files_constraints_sonata:
3737
files:
38-
- data/pins_sonata.xdc
38+
# Per AMD advice (UG949):
39+
- data/pins_sonata.xdc # 1 file for physical +
40+
- data/synth_timing.xdc # 1 file for timing (synthesis) +
41+
- data/impl_timing.xdc # 1 file for timing (implementation)
3942
file_type: xdc
4043

44+
files_tcl:
45+
files:
46+
- flow/vivado_setup.tcl : { file_type: tclSource }
47+
4148
parameters:
4249
# XXX: This parameter needs to be absolute, or relative to the *.runs/synth_1
4350
# directory. It's best to pass it as absolute path when invoking fusesoc, e.g.
@@ -78,6 +85,7 @@ targets:
7885
filesets_append:
7986
- files_sonata
8087
- files_constraints_sonata
88+
- files_tcl
8189
toplevel: top_sonata
8290
tools:
8391
vivado:

0 commit comments

Comments
 (0)