Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
P
Platform-independent core collection
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
18
Issues
18
List
Board
Labels
Milestones
Merge Requests
5
Merge Requests
5
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Platform-independent core collection
Commits
160e3d0c
Commit
160e3d0c
authored
May 31, 2023
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tools: (hopefully) improved CDC constraints generation script
parent
6582cbcd
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
178 additions
and
48 deletions
+178
-48
gc_reset_multi_aasd.xdc
modules/common/xdc/gc_reset_multi_aasd.xdc
+0
-5
gc_sync.xdc
modules/common/xdc/gc_sync.xdc
+0
-21
gc_sync_register.xdc
modules/common/xdc/gc_sync_register.xdc
+0
-22
generate_cdc_constraints.tcl
tools/generate_cdc_constraints.tcl
+178
-0
No files found.
modules/common/xdc/gc_reset_multi_aasd.xdc
deleted
100644 → 0
View file @
6582cbcd
# the "-quiet" option is added for the use case where this module is added to
# the project, but not instatiated (e.g. because of generic settings)
# in that case Vivado would throw critical warnings during P&$
set_false_path -quiet -to [get_pins -hierarchical *rst_chains_reg[*]/CLR]
modules/common/xdc/gc_sync.xdc
deleted
100644 → 0
View file @
6582cbcd
# Timing constrains for basic 1 bit synchroniser.
# In many cases this could be solved with simple set_false_path, but in some
# cases this module is used in more time-critical applications, eg. inferred FIFO.
# In that case it makes sense to apply some max_delay constraint.
#
# You can always override any of these max_delay constraints in your global XDC
# with set_false_path because it has the highest priority.
set clk [get_clocks -of_objects [get_ports clk_i]]
set clk_period [get_property PERIOD $clk]
# ATTENTION: we can't use "all_fanin" to find the source register because
# apparently this command doesn't traverse outside of scoped reference (even with -flat switch)
# This method won't work properly if there's a combinational path between a source and target FF;
# but in a proper CDC circuit it's forbidded to have logic between FFs anyway!
set dst_ff [get_pins sync_*.sync0_*/D]
set src_ff [get_cells -of_objects [get_pins -filter {IS_LEAF && DIRECTION == OUT} -of_objects [get_nets -segments -of_objects $dst_ff]]]
# We use -quiet switch, because otherwise Vivado will throw critical warning
# if module is not used in the project (e.g. due to generics)
set_max_delay $clk_period -quiet -datapath_only -from $src_ff -to $dst_ff
modules/common/xdc/gc_sync_register.xdc
deleted
100644 → 0
View file @
6582cbcd
# Timing constrains for basic bit vector synchroniser.
#
# This is similar to gc_sync, but vector synchronisation is usually more tricky.
# Usually you really want to limit bus skew and delay to one clock cycle.
#
# You can always override any of these max_delay constraints in your global XDC
# with set_false_path because it has the highest priority.
set clk [get_clocks -of_objects [get_ports clk_i]]
set clk_period [get_property PERIOD $clk]
# ATTENTION: we can't use "all_fanin" to find the source register because
# apparently this command doesn't traverse outside of scoped reference (even with -flat switch)
# This method won't work properly if there's a combinational path between a source and target FF;
# but in a proper CDC circuit it's forbidded to have logic between FFs anyway!
set dst_ff [get_pins sync0_*[*]/D]
set src_ff [get_cells -of_objects [get_pins -filter {IS_LEAF && DIRECTION == OUT} -of_objects [get_nets -segments -of_objects $dst_ff]]]
# We use -quiet switch, because otherwise Vivado will throw critical warning
# if module is not used in the project (e.g. due to generics)
set_max_delay $clk_period -quiet -datapath_only -from $src_ff -to $dst_ff
set_bus_skew $clk_period -quiet -from $src_ff -to $dst_ff
tools/generate_cdc_constraints.tcl
0 → 100644
View file @
160e3d0c
##-------------------------------------------------------------------------------
## CERN BE-CEM-EDL
## General Cores
## https://www.ohwr.org/projects/general-cores
##-------------------------------------------------------------------------------
##
## Tcl script to produce CDC (Clock Domain Crossing
)
constraints for the CDC primitives
## used in your Vivado design:
## - gc_sync
## - gc_sync_register
## - gc_reset_multi_aasd
##
## Instructions for use:
## - synthesize your design
## - open the synthesized design in Vivado
## - run this script (source generate_cdc_constraints.tcl
)
## - the result of operation is a file called "gencores_constraints.xdc". Add it
## to the project's sources.
## - note: you must rerun this script every time you change (add/remove/modify
)
## gencores's CDC primtives in your design.
## - enjoy and profit!
##
##-------------------------------------------------------------------------------
## Copyright CERN 2023
##-------------------------------------------------------------------------------
## This Source Code Form is subject to the terms of the Mozilla Public License,
## version 2.0. If a copy of the MPL was not distributed with this file, You can
## obtain one at https://mozilla.org/MPL/2.0/.
##-------------------------------------------------------------------------------
proc
generate_gc_sync_constraints
{
f_out
}
{
set the_cells
[
get_cells -hier -filter
{
REF_NAME=~gc_sync*
}
]
set count 0
foreach cell
$the
_cells
{
#skip gc_sync_ffs instances (as they contain a gc_sync inside
)
if
{[
string
first
"gc_sync_ffs"
[
get_property REF_NAME
[
get_cells
$cell
]]]
!= -1
}
{
puts
$f
_out
"#WARNING: skip gc_sync_ffs cell '
$cell
'"
continue
}
set dst_ff_clr
[
get_pins
"
$cell
/sync_*.sync*_*/CLR"
]
set dst_ff
[
get_pins
"
$cell
/sync_*.sync0_*/D"
]
if
{
"
$dst
_ff"
==
""
}
{
set dst_ff
[
get_pins -hier -filter
"name=~
$cell
/sync_*.sync0_*/D"
]
}
if
{
"
$dst
_ff_clr"
==
""
}
{
set dst_ff_clr
[
get_pins -hier -filter
"name=~
$cell
/sync_*.sync*_*/CLR"
]
}
if
{
"
$dst
_ff"
==
""
}
{
puts
$f
_out
"#WARNING: can't find destination FF for cell '
$cell
'"
continue
}
set clk
[
get_clocks -of_objects
[
get_pins -filter
{
REF_PIN_NAME=~clk_i*
}
-of
$cell
]
]
set src_cells
[
get_cells -of_objects
[
get_pins -filter
{
IS_LEAF && DIRECTION == OUT
}
-of_objects
[
get_nets -segments -of_objects
$dst
_ff
]]]
set src_ff
[
get_pins -filter
{
DIRECTION == OUT
}
-of_objects
$src
_cells
]
set clk_period
[
get_property PERIOD
[
lindex
$clk
0
]
]
puts
$f
_out
"#Cell:
$cell
, src
$src
_ff, dst
$dst
_ff, clock
$clk
, period
$clk
_period"
puts
$f
_out
"set_max_delay
$clk
_period -datapath_only -from {
$src
_ff } -to {
$dst
_ff }"
foreach clr_pin
$dst
_ff_clr
{
puts
$f
_out
"set_false_path -to {
$clr
_pin }"
}
incr count
}
return
$count
}
proc
generate_gc_sync_register_constraints
{
f_out
}
{
set the_cells
[
get_cells -hier -filter
{
REF_NAME=~gc_sync_register*
}
]
set count 0
foreach cell
$the
_cells
{
set dst_ff_clr
[
get_pins
"
$cell
/sync*_*
[
*
]
/CLR"
]
set dst_ff
[
get_pins
"
$cell
/sync0_*
[
*
]
/D"
]
if
{
"
$dst
_ff"
==
""
}
{
set dst_ff
[
get_pins -hier -filter
"name=~
$cell
/sync0_*
[
*
]
/D"
]
}
if
{
"
$dst
_ff_clr"
==
""
}
{
set dst_ff_clr
[
get_pins -hier -filter
"name=~
$cell
/sync*_*
[
*
]
/CLR"
]
}
puts
$dst
_ff
if
{
"
$dst
_ff"
==
""
}
{
puts
$f
_out
"#WARNING: can't find destination FF for cell '
$cell
'"
continue
}
set clk
[
get_clocks -of_objects
[
get_pins -filter
{
REF_PIN_NAME=~clk_i*
}
-of
$cell
]
]
set src_ff
[
get_cells -of_objects
[
get_pins -filter
{
IS_LEAF && DIRECTION == OUT
}
-of_objects
[
get_nets -segments -of_objects
$dst
_ff
]]]
set clk_period
[
get_property PERIOD
[
lindex
$clk
0
]
]
puts
"Cell:
$cell
, src
$src
_ff, dst
$dst
_ff, clock
$clk
, period
$clk
_period"
puts
$f
_out
"set_max_delay
$clk
_period -quiet -datapath_only -from {
$src
_ff } -to {
$dst
_ff }"
puts
$f
_out
"set_bus_skew
$clk
_period -quiet -from {
$src
_ff } -to {
$dst
_ff }"
foreach clr_pin
$dst
_ff_clr
{
puts
$f
_out
"set_false_path -to {
$clr
_pin }"
}
incr count
}
return
$count
}
proc
generate_gc_reset_multi_aasd_constraints
{
f_out
}
{
set the_cells
[
get_cells -hier -filter
{
REF_NAME=~gc_reset_multi_aasd*
}
]
set count 0
foreach cell
$the
_cells
{
set dst_ff_clr
[
get_pins
"
$cell
/*rst_chains_reg
[
*
]
/CLR"
]
if
{
"
$dst
_ff_clr"
==
""
}
{
set dst_ff_clr
[
get_pins -hier -filter
"name=~
$cell
/*rst_chains_reg
[
*
]
/CLR"
]
}
if
{
"
$dst
_ff_clr"
==
""
}
{
puts
$f
_out
"#WARNING: can't find destination FF CLR pin for cell '
$cell
'"
continue
}
foreach clr_pin
$dst
_ff_clr
{
puts
$f
_out
"set_false_path -to {
$clr
_pin }"
}
incr count
}
return
$count
}
proc
generate_gc_falsepath_waiver_constraints
{
f_out
}
{
set the_cells
[
get_cells -hier -filter
{
REF_NAME=~gc_falsepath_waiver*
}
]
set count 0
foreach cell
$the
_cells
{
set src_ff
[
get_pins
"
$cell
/in_i
[
*
]
"
]
if
{
"
$src
_ff"
==
""
}
{
set src_ff
[
get_pins -hier -filter
"name=~
$cell
/in_i
[
*
]
"
]
}
if
{
"
$src
_ff"
==
""
}
{
puts
$f
_out
"#WARNING: can't find source pin for '
$cell
'"
continue
}
foreach pin
$src
_ff
{
puts
$f
_out
"set_false_path -from {
$pin
}"
}
incr count
}
return
$count
}
set
f_out
[
open
"gencores_constraints.xdc"
w
]
set
n_gc_sync_cells
[
generate_gc_sync_constraints
$f
_out
]
set
n_gc_sync_register_cells
[
generate_gc_sync_register_constraints
$f
_out
]
set
n_gc_reset_multi_aasd_cells
[
generate_gc_reset_multi_aasd_constraints
$f
_out
]
#set n_gc_falsepath_waiver_cells [ generate_gc_falsepath_waiver_constraints $f_out
]
puts
"gencores CDC statistics: "
puts
" - gc_sync:
$n
_gc_sync_cells instances"
puts
" - gc_sync_register:
$n
_gc_sync_register_cells instances"
puts
" - gc_reset_multi_aasd:
$n
_gc_reset_multi_aasd_cells instances"
#puts " - gc_falsepath_waiver: $n_gc_falsepath_waiver_cells instances"
close
$f
_out
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment