TCL API Reference
This page documents all TCL procedures provided by ruckus. Procedures are called from
your project’s ruckus.tcl file or from hook scripts.
For an explanation of $::DIR_PATH and the recursive loading model, see
The ruckus.tcl Recursive Loading Model.
Source-Loading Procedures
These procedures are defined in vivado/proc/code_loading.tcl.
Call them from your ruckus.tcl to populate the Vivado project with RTL, IP cores,
block designs, and constraints.
- loadSource()
loadSource [-path PATH] [-dir DIR] [-sim_only] [-lib LIBRARY] [-fileType TYPE]Add RTL source files to the Vivado project’s
sources_1fileset (orsim_1when-sim_onlyis given).- -path <path>
Absolute path to a single source file. Mutually exclusive with
-dir. Use$::DIR_PATHto construct the path relative to the currentruckus.tcl.
- -dir <dir>
Directory path. All supported files found in this directory are added. Mutually exclusive with
-path.
- -sim_only
Boolean flag. When present, files are added to the
sim_1fileset instead ofsources_1. Use for testbench files that should not be synthesised.
- -lib <library>
VHDL library name to assign to any
.vhdor.vhdlfiles loaded. Has no effect on Verilog or SystemVerilog files.
- -fileType <type>
Override the
FILE_TYPEproperty that Vivado assigns to loaded files.
Supported file extensions:
.vhd.vhdl.v.vh.sv.svh.dat.coe.mem.edif.dcpError behaviour: Calls
exit -1if the file is missing, the extension is unsupported, or both-pathand-dirare supplied.Note
If adding a
.dcpfile fails with a “Runs 36-335” error, ruckus prints a reminder to rungit lfs pull— large DCP files must be stored in Git LFS.Examples:
# Add a single HDL source file loadSource -path $::DIR_PATH/rtl/MyModule.vhd # Add all HDL sources in a directory loadSource -dir $::DIR_PATH/rtl/ # Add a simulation-only testbench loadSource -path $::DIR_PATH/tb/MyTb_tb.vhd -sim_only # Add a VHDL file and assign it to a named library loadSource -path $::DIR_PATH/rtl/surf/SurfPkg.vhd -lib surf
- loadIpCore()
loadIpCore [-path PATH] [-dir DIR]Import a Vivado IP core (
.xcior.xcix) into the project’ssources_1fileset viaimport_ip.- -path <path>
Absolute path to a single
.xcior.xcixfile.
- -dir <dir>
Directory path. All
.xci/.xcixfiles found there are imported.
The proc appends the resolved path(s) to the global
$::IP_LISTand$::IP_FILESvariables, which are used byBuildIpCores()later in the pipeline.Example:
loadIpCore -path $::DIR_PATH/ip/MyFifo.xci loadIpCore -dir $::DIR_PATH/ip/
- loadBlockDesign()
loadBlockDesign [-path PATH] [-dir DIR]Import or regenerate a Vivado block design (
.bdor.tcl).- -path <path>
Absolute path to a
.bdor.tclfile.
- -dir <dir>
Directory path. All
.bdand.tclfiles found there are processed.
``.bd`` files are imported via
import_files -norecurse.``.tcl`` files are sourced directly, regenerating the block design from script. Use the
.tclform when the block design is version-controlled as a script.The resolved
.bdpath is appended to$::BD_FILES.Example:
# Import a pre-built block design loadBlockDesign -path $::DIR_PATH/bd/system.bd # Regenerate a block design from its TCL script loadBlockDesign -path $::DIR_PATH/bd/system.tcl
- loadConstraints()
loadConstraints [-path PATH] [-dir DIR]Add timing or physical constraints to the project’s
constrs_1fileset.- -path <path>
Absolute path to a single
.xdcor.tclconstraint file.
- -dir <dir>
Directory path. All
.xdcand.tclfiles found there are added.
Example:
loadConstraints -path $::DIR_PATH/constraints/timing.xdc loadConstraints -dir $::DIR_PATH/constraints/
- loadNoCSolution()
loadNoCSolution -path PATHLock the
impl_1run to a pre-computed Versal NoC solution (.ncr) file by setting itsNOC_SOLUTION_FILEproperty.- -path <path>
Absolute path to a single
.ncrfile.
Used with Versal Segmented Configuration so that the NoC compiler reuses a locked solution and the static portion of the NoC (routing, QoS) stays identical between the static and dynamic partitions. No-op with a warning when the target is not Versal, so a shared device
ruckus.tclcan call it unconditionally. Hard error if-pathis missing, the file does not exist, or the file lacks a.ncrextension.Defined in
vivado/proc/code_loading.tcl.Example:
if { $::env(USE_SEGMENTED_CONFIG) != 0 } { loadNoCSolution -path $::DIR_PATH/bd/XilinxVek280NoC.ncr }
- loadRuckusTcl {filePath {flags ""}}
Recursively load a submodule’s
ruckus.tcl. This is the primary mechanism for composing firmware projects from multiple ruckus-aware modules.- Parameters:
filePath – Directory path containing the target
ruckus.tcl. Do not pass the file itself — ruckus appends/ruckus.tclinternally. Passing a file path (e.g.$::DIR_PATH/submodule/ruckus.tcl) will causeexit -1.flags – (Optional) Pass
"debug"to enable TCL tracing during the load. Omit or pass""for normal operation.
What it does:
Saves the current
$::DIR_PATHSets
$::DIR_PATHtofilePathSources
${filePath}/ruckus.tclRestores the original
$::DIR_PATHAppends
filePathto$::DIR_LIST
See The ruckus.tcl Recursive Loading Model for the full explanation of
$::DIR_PATHsemantics.Warning
Pass the directory, not the file.
loadRuckusTcl $::env(MODULES)/surfis correct.loadRuckusTcl $::env(MODULES)/surf/ruckus.tclwill fail withexit -1.Examples:
# Load a submodule (surf firmware library) loadRuckusTcl $::env(MODULES)/surf # Load with debug tracing enabled loadRuckusTcl $::env(MODULES)/surf "debug" # Load a subdirectory within the same project loadRuckusTcl $::DIR_PATH/shared
Vivado Pipeline Procedures
These procedures are called internally by ruckus during the Vivado build pipeline.
Users may call some of them from hook scripts or ruckus.tcl for project-level
control.
These procedures are defined in vivado/proc/.
- CheckVivadoVersion()
Check the active Vivado version against known-good and known-bad version lists.
- Returns:
Nothing on success. Raises
-code errorfor unsupported versions.
Checks
$::env(VIVADO_VERSION)against:Known-bad versions (2017.1, pre-2014.1) — raises an error.
Versions newer than 2025.2.0 — prints a warning (untested).
Defined in
vivado/proc/project_management.tcl. Called automatically at project open time fromvivado/project.tcl. Users may also call it fromruckus.tclto gate a project on a required Vivado version.Example:
# Call from ruckus.tcl for project-level version gating CheckVivadoVersion
- CheckTiming {{printTiming true}}
Evaluate implementation timing results and return pass/fail status.
- Parameters:
printTiming – (Optional, default
true) Whentrue, prints WNS/TNS/WHS/THS/TPWS/FAILED_NETS to stdout if timing failed.- Returns:
trueif timing passed or was overridden;falseif timing failed and no override is active.
Reads
STATS.*properties from theimpl_1run after route. Checks theTIG,TIG_SETUP,TIG_HOLD, andTIG_PULSEenvironment variables; if any override is set, a timing failure does not prevent bitstream generation.Defined in
vivado/proc/checking.tcl. Called internally frombuild.tclandpost_route.tcl. Thepost_route.tclTier-1 hook fires only whenCheckTimingreturnstrue.Example:
# Called with default printTiming=true (prints stats on failure) CheckTiming
- BuildIpCores()
Upgrade and synthesise all project IP cores.
- Returns:
Nothing.
Upgrades all IP cores in the project, then synthesises any whose synthesis run is stale. Uses
$::env(PARALLEL_SYNTH)parallel jobs.Defined in
vivado/proc/ip_management.tcl. Called automatically frombuild.tclbefore synthesis.Example:
BuildIpCores
- CreateFpgaBit()
Copy implementation output files to the
images/directory after a successful build.- Returns:
Nothing.
Copies output files according to output format variables:
.bitfile ifGEN_BIT_IMAGE!= 0Gzip of
.bitifGEN_BIT_IMAGE_GZIP!= 0.binfile ifGEN_BIN_IMAGE!= 0Gzip of
.binifGEN_BIN_IMAGE_GZIP!= 0
Calls
CreateXsaFile()andCreatePromMcs()internally.Defined in
vivado/proc/output_files.tcl. Not used for Versal devices (useCreateVersalOutputsinstead).Example:
CreateFpgaBit
- CreatePromMcs()
Generate an MCS PROM file if a
promgen.tclhook is present.- Returns:
Nothing.
Sources
$::env(PROJ_DIR)/vivado/promgen.tclif it exists; no-op otherwise. To customise MCS generation, createvivado/promgen.tclin your project directory.Defined in
vivado/proc/output_files.tcl. Called internally byCreateFpgaBit().Example:
CreatePromMcs
- CreateXsaFile()
Generate an XSA (or HDF) hardware platform file for embedded processor projects.
- Returns:
Nothing.
Generates a
.xsahardware platform file (Vivado 2019.2 and later) or.hdf(Vivado 2019.1 and older) whenGEN_XSA_IMAGE!= 0. Only relevant for projects containing embedded processors such as MicroBlaze.Defined in
vivado/proc/output_files.tcl. Called internally byCreateFpgaBit().Example:
CreateXsaFile
- EnableSegmentedConfig()
Enable Versal Segmented Configuration on the current project.
- Returns:
Nothing on success. Calls
exit -1for Vivado < 2025.1.
Sets
SEGMENTED_CONFIGURATION 1on the current project so thatwrite_device_imageemits two PDIs (<design>_boot.pdiand<design>_pld.pdi) instead of the standard single PDI. No-op with a warning when the target is not Versal. Hard error when the active Vivado version is older than 2025.1.Defined in
vivado/proc/SegmentedConfiguration.tcl. Called automatically fromvivado/properties.tclwhenUSE_SEGMENTED_CONFIG = 1is exported by the target Makefile (the recommended opt-in path — see How to Use Versal Segmented Configuration). Users do not normally call this directly.Example:
# Enabled implicitly by setting USE_SEGMENTED_CONFIG = 1 in the # target Makefile. Direct invocation is for advanced users only. EnableSegmentedConfig
- ExportSegmentedPdi()
Copy the Segmented Configuration PDIs to the
images/directory with the SLACIMAGENAMEsuffix convention.- Returns:
Nothing. Calls
exit -1if the expected boot/PLD PDIs are not found in the implementation directory.
Discovers the Vivado-emitted
*_boot.pdi(becomes<IMAGENAME>_static.pdi, feedsBOOT.BIN) and*_pld.pdi(becomes<IMAGENAME>_dynamic.pdi, the runtime-loadable artifact) underIMPL_DIR, copies both toIMAGES_DIRwhenGEN_PDI_IMAGE!= 0, and gzips them whenGEN_PDI_IMAGE_GZIP!= 0. Also emits.ltxand.xsato maintain parity with the single-PDI Versal path it replaces.Defined in
vivado/proc/SegmentedConfiguration.tcl. Called automatically fromvivado/build.tclwhenUSE_SEGMENTED_CONFIG = 1. Users do not normally call this directly.Example:
# Called implicitly during build.tcl when USE_SEGMENTED_CONFIG = 1. ExportSegmentedPdi
Icarus Verilog and Verilator Procedures
These procedures are defined in shared/verilog_proc.tcl and provide the
Vivado-free loadSource() and loadRuckusTcl() used by
system_iverilog.mk and system_verilator.mk; see
How to Simulate Verilog with Icarus Verilog and How to Simulate Verilog with Verilator.
The Vivado-free loadSource/loadRuckusTcl differ from the Vivado forms
documented above: only .v, .sv, .vh, and .svh extensions are
accepted (plus .vhd/.vhdl, which are collected separately and turned
into a hard error), -lib and -fileType are accepted but have no
effect, -sim_only is accepted and stripped, and there is no Vivado
fileset to add files to; sources accumulate in an ordered, deduplicated
in-memory filelist instead, written to disk by VerilogWriteFilelist().
- VerilogInitSources()
Reset the ordered source, include-dir, and VHDL-offender lists.
- Returns:
Nothing.
Called once at the start of
load_source_code.tcl, never at file scope: every loadedruckus.tcl(includingsurf/simlink/ruckus.tcl) re-sources$::env(RUCKUS_PROC_TCL)mid-load, and a file-scope reset would silently discard everything loaded before that point.Example:
VerilogInitSources
- VerilogAddFile {path}
Classify one file into the ordered source list, the include-dir list, or the VHDL offender list, deduplicating each by real path.
- Parameters:
path – Path to classify.
- Returns:
Nothing.
.v/.svfiles are appended to the ordered source list;.vh/.svhfiles contribute their directory to the include-dir list;.vhd/.vhdlfiles are appended to the VHDL offender list consumed byVerilogWriteFilelist()’s hard error. Called internally byloadSource().Example:
VerilogAddFile $::DIR_PATH/rtl/MyModule.sv
- VerilogWriteFilelist {filePath}
Write the ordered, deduplicated filelist consumed by
iverilog -c/verilator -f.- Parameters:
filePath – Output filelist path (
$(OUT_DIR)/$(PROJECT).f).- Returns:
Nothing on success. Calls
exit -1if any.vhd/.vhdlfile was loaded, or if no.v/.svsource was loaded.
Writes one
+incdir+<dir>line per collected include directory, followed by one line per ordered source path. Called at the end ofload_source_code.tcl, after the project’sruckus.tcltree has been loaded.Example:
VerilogWriteFilelist "$::env(OUT_DIR)/$::env(PROJECT).f"
- VerilogCheckTool {tool}
Resolve a tool on PATH or hard-error.
- Parameters:
tool – Executable name to resolve (e.g.
iverilog).- Returns:
The resolved binary path on success. Calls
exit -1with theVerilogCheckTool: ... not found in PATHbanner if the tool is not found.
Called by
load_source_code.tclfor each required tool and internally byVerilogCheckVersion()andVerilogSimLinkBuild().Example:
VerilogCheckTool iverilog-vpi
- VerilogCheckVersion {tool versionArg pattern floor}
Resolve a tool, run it to capture its version string, and hard-error below a floor.
- Parameters:
tool – Executable name to resolve and version-check.
versionArg – Argument that makes the tool print its version (e.g.
-Vforiverilog,--versionforverilator).pattern – Regular expression matching the version text, with one capture group.
floor – Minimum accepted
major.minorversion string.
- Returns:
Nothing on success. Calls
exit -1with theVerilogCheckVersion: ruckus requires <tool> <floor> or newerbanner when the found version is below the floor.
Compares the parsed
major.minorviaCompareTagsrather thanexpr, avoiding an octal-parse error on a minor version such as Verilator’s020. Called once at the start of each flow’sload_source_code.tcl, before any source is loaded.Example:
VerilogCheckVersion iverilog -V {Icarus Verilog version (\d+\.\d+)} 12.0
- VerilogSimLinkBuild {artifact}
Build the surf SimLink backend library in-tree, stage it in
$::env(OUT_DIR), and clean the surf tree.- Parameters:
artifact – Backend artifact filename to stage (
RogueSimLink.vpifor Icarus Verilog,libRogueSimLinkDpi.sofor Verilator).- Returns:
Nothing. Skips entirely (with a message) if no Rogue SimLink leaf is present in the written filelist. Calls
exit -1if the located backend directory has noMakefile,makefails, or the expected artifact is not produced.
Locates the backend directory by scanning the written filelist for a known Rogue leaf (
RogueTcpStream.sv,RogueTcpMemory.sv, orRogueSideBand.sv) and taking its directory, mirroring the VCS/xsim in-tree build/copy/clean pattern. CallsRogueCheckLibZmq()before building. Called from each flow’ssimlink.tclat the start ofmake build.Example:
VerilogSimLinkBuild RogueSimLink.vpi
See also
- Hook Script Reference
Hook script reference — covers all named hook points, when they fire, and which TCL variables are in scope. Relevant for users calling pipeline procs such as
CheckTiming()orCreateFpgaBit()from hook scripts.