This guide explains how to run synthesis, timing analysis, area analysis, and power analysis for Vortex across all supported back-ends: Xilinx (Vivado), Altera (Quartus), Yosys (open-source), and Synopsys Design Compiler.
- Design Configuration
- Generating SAIF Files
- Specifying SAIF_INST
- DUT Sub-Component Evaluation
- Xilinx (Vivado)
- Altera (Quartus)
- Yosys (Open-Source)
- Synopsys Design Compiler
- Understanding Power Reports
All synthesis flows accept a CONFIGS variable to customize the hardware design at build time. CONFIGS is a string of preprocessor macro definitions (-D flags) that control core count, cache hierarchy, extensions, and other parameters.
Common configuration flags (all parameters live in the VX_CFG_* namespace; see VX_config.toml at the repo root for the full list):
| Flag | Description |
|---|---|
-DVX_CFG_NUM_CLUSTERS=N |
Number of clusters |
-DVX_CFG_NUM_CORES=N |
Number of cores per cluster |
-DVX_CFG_NUM_WARPS=N |
Number of warps per core |
-DVX_CFG_NUM_THREADS=N |
Number of threads per warp |
-DVX_CFG_L2_ENABLE |
Enable shared L2 cache |
-DVX_CFG_L3_ENABLE |
Enable shared L3 cache |
-DVX_CFG_EXT_TCU_ENABLE |
Enable Tensor Core Unit |
-DVX_CFG_EXT_DXA_ENABLE |
Enable DXA extension |
-DVX_CFG_DCACHE_SIZE=N |
Set data cache size in bytes |
Example:
CONFIGS="-DVX_CFG_NUM_CLUSTERS=1 -DVX_CFG_NUM_CORES=4 -DVX_CFG_L2_ENABLE -DVX_CFG_EXT_TCU_ENABLE"CONFIGS may also carry Verilog parameter overrides as -G<NAME>=<value> alongside the -D macros. gen_sources.sh forwards these to repl_params.py, which rewrites the parameter's default in the top module's per-build copy (the source tree is untouched, so concurrent builds with different overrides stay isolated). gen_config ignores -G tokens, so no separate Makefile variable is needed.
This is mainly for the DUT unittest wrappers, whose knobs are Verilog parameters rather than VX_CFG_* macros — e.g. the cache wrapper's AMO_ENABLE and IS_LLC:
# LLC cache DUT, AMO disabled vs enabled (NT=NW=32)
CONFIGS="-DVX_CFG_NUM_THREADS=32 -DVX_CFG_NUM_WARPS=32 -GAMO_ENABLE=0 -GIS_LLC=1" PREFIX=amo0 make cache
CONFIGS="-DVX_CFG_NUM_THREADS=32 -DVX_CFG_NUM_WARPS=32 -GAMO_ENABLE=1 -GIS_LLC=1" PREFIX=amo1 make cacheAll flows also support the NUM_CORES Makefile shorthand which auto-selects a pre-defined cluster/core/L2 configuration:
NUM_CORES=4 # equivalent to -DVX_CFG_NUM_CLUSTERS=1 -DVX_CFG_NUM_CORES=4 -DVX_CFG_L2_ENABLE
NUM_CORES=16 # equivalent to -DVX_CFG_NUM_CLUSTERS=1 -DVX_CFG_NUM_CORES=16 -DVX_CFG_L2_ENABLE
NUM_CORES=32 # equivalent to -DVX_CFG_NUM_CLUSTERS=2 -DVX_CFG_NUM_CORES=16 -DVX_CFG_L2_ENABLEUse PREFIX=<unique_build_dir> to keep builds separate. Each flow creates a build directory derived from PREFIX so that multiple configurations can coexist without overwriting each other:
# Xilinx XRT: creates build_4c_<platform>_<target>/
PREFIX=build_4c NUM_CORES=4 make -C hw/syn/xilinx/xrt
# Synopsys: creates my_test_Vortex/
PREFIX=my_test make -C hw/syn/synopsys synthesisSAIF (Switching Activity Interchange Format) files capture signal toggle rates during simulation and are used to produce accurate power estimates. Vortex supports SAIF generation through its RTL simulators: rtlsim, opaesim, and xrtsim.
Build the simulator with SAIF tracing enabled, then run a workload:
# Build rtlsim with SAIF support
make -C sim/rtlsim SAIF=1
# Run a test application
make -C tests/regression/sgemm run-rtlsimThe SAIF file is written to trace.saif in the application directory.
The ci/blackbox.sh script provides a convenient wrapper:
./ci/blackbox.sh --driver=rtlsim --app=sgemm --cores=4 --l2cache --saifWhen --saif is passed, blackbox.sh:
- Builds the simulator with
SAIF=1 - Runs the application
- Copies the resulting
trace.saifto the current directory
Available drivers for SAIF generation:
| Driver | Simulator | Use Case |
|---|---|---|
rtlsim |
Verilator RTL sim | General-purpose RTL power analysis |
opaesim |
OPAE AFU simulator | Intel/Altera platform-specific analysis |
xrtsim |
XRT simulator | Xilinx platform-specific analysis |
When reading a SAIF file, the tool must strip the testbench hierarchy prefix from signal names so they align with the synthesized netlist. SAIF_INST specifies this prefix.
Typical values:
| Flow | SAIF_INST |
|---|---|
| Xilinx DUT | TOP.rtlsim_shim.vortex |
| Xilinx XRT | TOP.vortex_afu_shim.vortex_afu |
| Synopsys / Yosys | Instance path matching your simulation hierarchy |
The path does not have to be absolute. A module instance name works if the tool can resolve it unambiguously (find-first semantics).
If the SAIF root scope already matches the top module, leave SAIF_INST empty.
Both Xilinx and Altera provide DUT (Device Under Test) flows for synthesizing and analyzing sub-components in isolation, without the full platform wrapper. This is useful for evaluating individual units such as the TCU, FPU, cache, or a single core.
Located in hw/syn/xilinx/dut/. Available sub-component targets:
| Target | Module | Description |
|---|---|---|
unittest |
Unit tests | Basic block tests |
scope |
Scope analyzer | Debug scope |
mem_unit |
Memory unit | Memory subsystem |
lmem |
Local memory | Local/shared memory |
cache |
Cache | Cache subsystem |
fpu |
FPU | Floating-point unit |
tcu |
TCU | Tensor Core Unit |
dxa |
DXA | DXA extension |
core |
Core | Single core |
issue |
Issue unit | Instruction issue |
vortex |
Vortex | Full processor (no AFU wrapper) |
top |
Top | Full design with AFU |
cd hw/syn/xilinx/dut
# Synthesize the TCU in isolation
CONFIGS="-DVX_CFG_EXT_TCU_ENABLE" make tcu
# Synthesize a 4-core Vortex without the platform wrapper
CONFIGS="-DVX_CFG_NUM_CORES=4 -DVX_CFG_L2_ENABLE" make vortex
# Run power analysis on an existing tcu
make tcu-power SAIF_FILE=/path/to/trace.saif SAIF_INST=*.tensor_unitEach target creates its build under <target>/<BUILD_DIR>/ (e.g., tcu/build/).
Located in hw/syn/altera/dut/. Same set of sub-component targets as Xilinx. Requires the DEVICE_FAMILY variable and IP cache generation:
cd hw/syn/altera/dut
# Generate IP cache first (required for fpu, vortex, top)
make ip-gen
# Synthesize TCU for Arria 10
DEVICE_FAMILY=arria10 CONFIGS="-DVX_CFG_EXT_TCU_ENABLE" make tcu
# Synthesize a single core for Stratix 10
DEVICE_FAMILY=stratix10 make coreBuild directories include the device family: <target>/build_<device_family>/.
Located in hw/syn/xilinx/xrt/. Builds a complete Vitis xclbin for deployment on Xilinx FPGAs.
Supported platforms: Alveo U50, U55C, U200, U250, U280, Versal VCK5000.
cd hw/syn/xilinx/xrt
# Build a 4-core design for U280
PREFIX=build_4c NUM_CORES=4 TARGET=hw \
PLATFORM=xilinx_u280_gen3x16_xdma_1_202310_1 \
CONFIGS="-DVX_CFG_L2_ENABLE -DVX_CFG_DCACHE_SIZE=8192" \
make > build.log 2>&1 &Key variables:
| Variable | Default | Description |
|---|---|---|
PREFIX |
build$(XLEN) |
Build directory prefix |
TARGET |
hw |
hw for hardware, hw_emu for emulation |
PLATFORM |
(required) | Xilinx platform identifier |
NUM_CORES |
- | Shorthand for core configuration |
CONFIGS |
- | Additional design macros |
MAX_JOBS |
8 | Parallel Vivado jobs |
make power SAIF_FILE=/path/to/trace.saif SAIF_INST=TOP.vortex_afu_shim.vortex_afu BUILD_DIR=<build_dir>The script (hw/scripts/xilinx_power_analysis.tcl) resolves the post-implementation checkpoint from BUILD_DIR automatically.
XRT flow (under <BUILD_DIR>/):
| Report | Location | Content |
|---|---|---|
| Utilization | <BUILD_DIR>/bin/utilization.rpt |
LUTs, FFs, BRAM, DSP |
| Timing | <BUILD_DIR>/bin/timing.rpt |
Worst setup paths |
| Power (vectorless) | power_vectorless.rpt |
Baseline power estimate |
| Power (SAIF) | power_saif.rpt |
Activity-annotated power |
DUT flow (under <target>/<BUILD_DIR>/):
| Report | Location | Content |
|---|---|---|
| Post-synth utilization | post_synth_util.rpt |
Hierarchical resource usage |
| Post-impl utilization | post_impl_util.rpt |
Hierarchical resource usage after P&R |
| Timing | timing.rpt |
100 worst setup paths |
| Methodology | methodology.rpt |
Design rule checks |
| Clock utilization | clock_utilization.rpt |
Clock tree and register usage |
| RAM utilization | ram_utilization.rpt |
Detailed RAM/BRAM usage |
| Power (vectorless) | power_vectorless.rpt |
Baseline power |
| Power (VCD) | power_vcd.rpt |
VCD-annotated power (if VCD_FILE set) |
| Power (SAIF) | power_saif.rpt |
SAIF-annotated power (via make power) |
| DRC | drc.rpt |
Design rule violations |
| High fanout nets | high_fanout_nets.rpt |
Nets with >100 fanout |
- Fmax: Look in
timing.rptfor the worst negative slack (WNS). Fmax = 1 / (clock_period - WNS). - Total LUTs: In
post_impl_util.rpt, find the row forCLB LUTsorSlice LUTs. - Total DSPs: In
post_impl_util.rpt, find the row forDSPsorDSP48E2. - Total BRAM: In
post_impl_util.rpt, find the row forBlock RAM TileorRAMB36/RAMB18.
Located in hw/syn/altera/opae/. Builds AFU images for Intel OPAE platforms (Arria 10, Stratix 10).
cd hw/syn/altera/opae
# Full build: IP generation, setup, and synthesis
DEVICE_FAMILY=arria10 PREFIX=build_4c NUM_CORES=4 TARGET=fpga make
# For ASE simulation build
DEVICE_FAMILY=stratix10 TARGET=asesim makeKey variables:
| Variable | Default | Description |
|---|---|---|
DEVICE_FAMILY |
arria10 |
arria10 or stratix10 |
PREFIX |
build$(XLEN) |
Build directory prefix |
TARGET |
fpga |
fpga, asesim, or ase |
NUM_CORES |
- | Shorthand for core configuration |
CONFIGS |
- | Additional design macros |
Build directory: <PREFIX>_<device_family>_<target>_<num_cores>c/.
Altera power analysis uses Quartus PowerPlay with VCD-based toggle annotation:
# Located in hw/syn/altera/power_play.sh
quartus_pow --input_vcd=trace.vcd \
--vcd_filter_glitches=on \
--default_input_io_toggle_rate=10000transitions/s \
$ProjectNameReports are generated in the synthesis build directory by the Quartus report scripts.
Area reports (from report_area.tcl):
| Report | Content |
|---|---|
*.syn.area.resource_summary.csv |
Synthesis resource summary |
*.syn.area.resource_breakdown.csv |
Resource breakdown by entity |
*.syn.area.ram_summary.csv |
Synthesis RAM summary |
*.syn.area.stats.csv |
Post-synthesis netlist statistics |
*.fit.area.resource_summary.csv |
Fitter resource summary (post-P&R) |
*.fit.area.resource_breakdown.csv |
Fitter resource breakdown by entity |
*.fit.area.ram_summary.csv |
Fitter RAM summary |
*.fit.area.routing_summary.csv |
Routing utilization |
*.fit.area.routing_global.csv |
Global signal routing |
*.fit.area.routing_high_fanout.csv |
High fanout signal routing |
Timing reports (from analyze_timing.tcl):
| Report | Content |
|---|---|
*.fit.timing.summary.txt |
Summary with Fmax, setup/hold, clock summary |
*.fit.timing.setup.html |
Top 200 setup violation paths (with routing) |
*.fit.timing.hold.html |
Top 200 hold violation paths |
*.fit.timing.recovery.html |
Recovery timing paths |
*.fit.timing.removal.html |
Removal timing paths |
*.fit.timing.check_errors.html |
Timing DRC (no clock, multiple clock, loops) |
*.fit.timing.check_metastability.html |
Metastability report |
*.fit.timing_histogram.*.setup.html |
Per-clock setup slack histograms |
*.fit.timing.setup.bottlenecks.txt |
Bottleneck analysis (TNS, fanout, fanin) |
*.fit.timing.summary.fmax.csv |
Fmax summary (CSV) |
*.fit.timing.summary.setup.csv |
Setup summary (CSV) |
*.fit.timing.summary.hold.csv |
Hold summary (CSV) |
*.fit.timing.summary.multicorner.csv |
Multi-corner timing summary |
- Fmax: Open
*.fit.timing.summary.txtor*.fit.timing.summary.fmax.csv. The Fmax summary reports the restricted Fmax for each clock domain. - Total ALMs/LUTs: In
*.fit.area.resource_summary.csv, look forALMs needed(Stratix 10) orLogic utilization(Arria 10). - Total DSPs: In
*.fit.area.resource_summary.csv, look for theDSProw. - Total BRAM (M20K/M10K): In
*.fit.area.resource_summary.csv, look forM20K blocksorM10K blocks. Also see*.fit.area.ram_summary.csvfor detailed RAM usage by entity.
Located in hw/syn/yosys/. Uses Yosys for synthesis, optional ABC for technology mapping, and OpenSTA for static timing analysis.
cd hw/syn/yosys
# Synthesis only (generic gates)
PREFIX=test NUM_CORES=1 make synthesis
# Synthesis + technology mapping
PREFIX=test NUM_CORES=1 make techmap
# Full flow: synthesis + mapping + STA + power
PREFIX=test NUM_CORES=1 SAIF_FILE=/path/to/trace.saif SAIF_INST=<inst> make timingKey variables:
| Variable | Default | Description |
|---|---|---|
PREFIX |
build |
Build directory prefix |
TOP_LEVEL_ENTITY |
Vortex |
Top module name |
NUM_CORES |
- | Shorthand for core configuration |
CONFIGS |
- | Additional design macros |
CLOCK_FREQ |
800 | Target clock frequency in MHz |
DELAY_UNC |
0.02 | Clock uncertainty (fraction of period) |
DELAY_IO |
0.05 | I/O delay (fraction of period) |
LIB_TGT |
NanGate 15nm OCL | Liberty file for technology mapping |
SAIF_FILE |
- | SAIF file for power annotation |
SAIF_INST |
- | Instance path prefix to strip |
Build directory: <PREFIX>_<TOP_LEVEL_ENTITY>/ (e.g., test_Vortex/).
The flow uses sv2v to convert SystemVerilog sources to Verilog before feeding them to Yosys.
Yosys uses blackbox modules (VX_dp_ram_asic, VX_sp_ram_asic) for SRAM. The sram_cost.py script estimates SRAM area from the Yosys JSON netlist by inferring width and depth from port connectivity:
Area = (width x depth x SRAM_BIT_AREA) + SRAM_OVERHEAD
Defaults: SRAM_BIT_AREA=0.1 um^2/bit, SRAM_OVERHEAD=100.0 um^2. These can be overridden via environment variables.
All reports are under <BUILD_DIR>/reports/:
| Report | Content |
|---|---|
yosys.log |
Full Yosys synthesis log |
stat_lib.rpt |
Cell count and area (post-mapping, by liberty cell type) |
sram_area.rpt |
Estimated SRAM area breakdown |
sta.log |
OpenSTA timing log |
power.rpt |
Power estimate (vectorless or SAIF-annotated) |
power_hier.rpt |
Hierarchical power breakdown |
saif_unannotated.rpt |
Signals not covered by SAIF |
Netlists are written to <BUILD_DIR>/out/:
| File | Content |
|---|---|
<TOP>_syn.v |
Post-synthesis generic netlist |
<TOP>_mapped.v |
Post-mapping technology netlist |
<TOP>.json |
Yosys JSON netlist (used by sram_cost.py) |
- Total area: In
stat_lib.rpt, look forChip area for top module. Add the estimated SRAM area fromsram_area.rptfor the total. - Cell count: In
stat_lib.rpt, the per-cell-type breakdown shows gate counts. - Timing (WNS/TNS): In
sta.log, look for thereport_wnsandreport_tnsoutputs. Fmax = 1 / (target_period - WNS). - Power: In
power.rpt, look for total power.power_hier.rptbreaks it down by hierarchy.
Located in hw/syn/synopsys/. Uses Synopsys DC for ASIC synthesis with support for multiple technology libraries.
| LIB_TYPE | Technology | Path |
|---|---|---|
DEFAULT |
NanGate 15nm OCL | Bundled in hw/syn/libs/ |
ASAP7 |
ASAP7 7nm | /mnt/nas0/eda.libs/asap7/asap7sc7p5t_28/LIB/NLDM |
SAED14 |
SAED 14nm SLVT | /mnt/nas0/eda.libs/saed14/EDK_03_2025 |
cd hw/syn/synopsys
# Default library, 1 core
PREFIX=test make synthesis
# ASAP7 library, 4 cores, with SAIF power
PREFIX=test NUM_CORES=4 LIB_TYPE=ASAP7 \
SAIF_FILE=/path/to/trace.saif SAIF_INST=<inst> \
make synthesis
# Synthesis without SRAM macros (blackbox)
PREFIX=test make synthesis-nosram
# Synthesis with estimated SRAM area
PREFIX=test make synthesis-estsramKey variables:
| Variable | Default | Description |
|---|---|---|
PREFIX |
build |
Build directory prefix |
TOP_LEVEL_ENTITY |
Vortex |
Top module name |
NUM_CORES |
- | Shorthand for core configuration |
CONFIGS |
- | Additional design macros |
CLOCK_FREQ |
800 | Target frequency in MHz |
DELAY_UNC |
0.02 | Clock uncertainty (fraction of period) |
DELAY_IO |
0.05 | I/O delay (fraction of period) |
LIB_TYPE |
DEFAULT |
Technology library selection |
SAIF_FILE |
- | SAIF file for power annotation |
SAIF_INST |
- | Instance path prefix in SAIF |
Build directory: <PREFIX>_<TOP_LEVEL_ENTITY>/ (e.g., test_Vortex/).
synthesis: Full synthesis with generated SRAM wrappers from the technology library's SRAM.dbfiles. Requires the library to provide SRAM models.synthesis-nosram: Synthesis without any SRAM logic. RAM modules are inferred by DC.synthesis-estsram: BlackboxesVX_dp_ram_asicandVX_sp_ram_asic, then estimates their area from port dimensions (same approach as Yosys).
All reports are under <BUILD_DIR>/reports/:
| Report | Content |
|---|---|
area.rpt |
Hierarchical area breakdown |
qor.rpt |
Quality of Results summary (area, timing, utilization) |
timing_max.rpt |
Setup timing (50 worst paths, with nets/transitions/capacitance) |
timing_min.rpt |
Hold timing (50 worst paths) |
clock_skew.rpt |
Clock skew analysis |
constraints_violators.rpt |
All constraint violations |
check_design.rpt |
Pre-synthesis design checks |
power_active.rpt |
SAIF-annotated hierarchical power (if SAIF_FILE provided) |
power_vectorless.rpt |
Vectorless power estimate (if no SAIF_FILE) |
saif_annotation_coverage.rpt |
SAIF annotation coverage statistics |
Outputs are under <BUILD_DIR>/out/:
| File | Content |
|---|---|
<TOP>.mapped.ddc |
Synopsys binary netlist |
<TOP>.mapped.v |
Mapped gate-level Verilog |
<TOP>.mapped.sdf |
Standard Delay Format for back-annotation |
<TOP>.post_compile.sdc |
Post-compile timing constraints |
- Total area: In
area.rpt, look for the top-levelTotal cell area. The SRAM estimated area (if usingsynthesis-estsram) is printed in the build log asTotal Estimated SRAM Area. - Timing / Fmax: In
timing_max.rpt, the slack of the first path gives the worst negative slack (WNS). Fmax = 1 / (target_period - WNS). Also checkqor.rptfor a summary. - Power: In
power_active.rpt(with SAIF) orpower_vectorless.rpt(without), the hierarchical breakdown shows internal, switching, and leakage power per module. - Gate count: In
qor.rpt, look forDesign AreaandNumber of cells.
Power reports across all flows break down total power into similar categories. Understanding these helps identify optimization targets.
| Component | Description |
|---|---|
| Dynamic power | Power consumed by signal switching activity |
| Internal | Short-circuit current during output transitions within cells |
| Switching | Charging/discharging of interconnect and load capacitances |
| Static (leakage) power | Power consumed even when signals are not switching; due to sub-threshold and gate leakage currents |
Total Power = Dynamic (Internal + Switching) + Static (Leakage)
- Vectorless: The tool assumes a default toggle rate (typically 12.5%) and static probability (0.5) for all signals. Provides a rough baseline but can significantly over- or under-estimate actual power.
- SAIF/VCD-annotated: Uses real switching activity captured during simulation. Much more accurate for the specific workload simulated. Signals not covered by the SAIF/VCD fall back to the default toggle rate.
Always compare the vectorless and annotated reports to understand which modules differ most from the default assumption.
- Run a representative workload when generating SAIF files. Short or trivial tests will underestimate steady-state power.
- Check SAIF annotation coverage reports (
saif_annotation_coverage.rptin Synopsys,saif_unannotated.rptin Yosys) to ensure good signal coverage. - For Xilinx, the power report includes device-specific contributions (clocking, I/O, BRAM, DSP power) that are not present in ASIC flows.
- For hierarchical analysis, look at per-module power breakdowns to identify the most power-hungry blocks (e.g., caches, FPU, TCU).