Skip to main content

FPGA project controller for Vivado

Project description

xviv

PyPI PyPI - Python Version License: MIT Tests

CLI project controller for Vivado and Vitis. Describe your whole project in a project.toml, run everything from the terminal, keep the GUI for the parts that actually need it.

pip install xviv

Work in progress. xviv is being actively developed alongside a another project and the API is not stable. Commands, config keys, and behaviour can change between versions without notice. It works, but expect rough edges.


Vivado can be difficult to use in a team environment. Project files often contain absolute paths, block designs are hard to review cleanly in git, and automation usually depends on generated TCL scripts rather than a clean, reproducible CLI workflow. As a result, teams often end up either committing large amounts of generated project state or maintaining custom rebuild scripts to keep projects portable across machines and Vivado versions.

xviv takes a different approach. Instead of relying on generated project files, the entire build is described in a single config file: FPGA target, IP cores, block designs, RTL sources, synthesis runs, simulations, and embedded platform configuration. A clean clone is enough to reproduce the project, while the build directory itself remains fully gitignored.

For block designs, xviv exports re-runnable TCL snapshots that can be version-controlled and reviewed like normal source files. It also embeds git metadata directly into the generated bitstream using USR_ACCESS - bits [27:0] store the short commit SHA, while bit 28 indicates whether the working tree was dirty at build time. That makes it possible to trace any .bit file back to the exact source revision that produced it.

The goal was never to eliminate the Vivado GUI entirely. Tools like Edalize focus primarily on non-project automation flows, which can make some Vivado workflows - especially block design editing and IP packaging - less convenient. xviv instead automates the parts Vivado handles well through scripting, while still allowing developers to use the GUI when it is actually useful.


Install

pip install xviv

Requires Python 3.11+. Vivado and Vitis must be on your PATH (source settings64.sh), or set XVIV_VIVADO_SOURCE_SCRIPT and xviv will source it for you:

# .env at project root works too
XVIV_VIVADO_SOURCE_SCRIPT=/tools/Xilinx/Vivado/2024.1/settings64.sh

Optional: pyslang for SV wrapper generation.

For development:

pip install -e ".[dev]"
pre-commit install

Getting started

A minimal project for a bare RTL design:

# project.toml

[[fpga]]
name      = "main"
fpga_part = "xc7a200tfbg484-1"

[[design]]
name    = "top"
sources = ["srcs/rtl/**/*.sv"]

[[synth]]
design      = "top"
constraints = ["constraints/top.xdc"]
xviv synth --design top

That runs the full pipeline: synth → opt → place → phys_opt → route → bitstream. Checkpoints land in build/synth/top/checkpoints/. Open any of them with:

xviv open --dcp build/synth/top/checkpoints/route.dcp

project.toml

All sections are arrays of tables. A real project uses some combination of the following:

[[fpga]] - part number and optional board definition. The first entry is the default; later sections can override with fpga = "name".

[[design]] - RTL sources and top module for a synthesisable design.

[[ip]] - custom IP to package with the Vivado IP Packager. xviv handles the packaging and wires the IP repo into the project. Use [[wrapper]] alongside it if the IP has interface ports that need flattening (requires pyslang).

[[core]] - an instance of a catalog IP (Xilinx built-in or custom). Identified by a partial VLNV that resolves against the live catalog; tab completion works here.

[[bd]] - a block design. xviv creates it, opens the editor, and exports its state as a TCL snapshot under scripts/xviv/bd/. After that, create --bd <name> recreates it non-interactively from the snapshot on any machine.

[[synth]] - a synthesis run. Identified by one of design, bd, or core. Controls the full pipeline (which stages to run, incremental flows, directives, reports, output artifacts).

[[simulation]] - a simulation target. Backends: xsim (default) or verilator. Supports UVM (see [[uvm]] below), SDF back-annotation, post-synthesis and post-implementation modes.

[[uvm]] - a UVM test configuration attached to a [[simulation]]. Each entry defines a test name, verbosity, and version, letting you declare multiple UVM tests for the same simulation target.

[[platform]] / [[app]] - Vitis embedded flow. platform generates a BSP from the XSA produced by synthesis; app scaffolds and builds a Vitis application against it. The properties key on [[platform]] lets you set BSP properties (e.g. CONFIG.stdout) directly from the toml.

[[formal]] - SymbiYosys formal verification target. Modes: bmc, prove, cover. Vivado not required.

The [project] table has two optional keys: build_dir (default: "build") and board_repo_paths.

A more complete example:

[project]
build_dir = "build"

[[fpga]]
name      = "main"
fpga_part = "xc7a200tfbg484-1"

[[ip]]
name    = "gamma_axi"
sources = ["srcs/ip/gamma_axi/**/*.sv"]

[[bd]]
name = "system"

[[synth]]
bd          = "system"
constraints = ["constraints/system.xdc"]
run_synth   = true
run_place   = true
run_route   = true

[[platform]]
name = "mb_platform"
bd   = "system"
cpu  = "microblaze_0"
os   = "standalone"

[platform.properties.CONFIG]
stdout = "mdm_1"
stdin  = "mdm_1"

[[app]]
name     = "firmware"
platform = "mb_platform"
template = "empty_application"

[[simulation]]
name    = "tb_gamma"
sources = ["srcs/sim/tb_gamma.sv", "srcs/rtl/**/*.sv"]
backend = "xsim"

[[uvm]]
simulation = "tb_gamma"
test       = "gamma_basic_test"
verbosity  = "UVM_MEDIUM"

[[formal]]
name    = "gamma_props"
top     = "gamma_axi"
mode    = "prove"
sources = ["srcs/ip/gamma_axi/gamma_axi.sv", "srcs/formal/gamma_axi_props.sv"]
depth   = 30

Commands

Working with IPs and BDs

# Create and package a custom IP
xviv create --ip gamma_axi
xviv edit   --ip gamma_axi          # opens IP Packager

# Create a block design from scratch (opens GUI)
xviv create --bd system

# Import from an existing TCL snapshot and open the editor
xviv create --bd system --source-file scripts/xviv/bd/system.tcl

# Just import and regenerate output products, no GUI
xviv create --bd system --no-generate

# After editing, generate output products
xviv generate --bd system

# Instantiate a catalog IP
xviv create --core clk_wiz_0
xviv edit   --core clk_wiz_0

# Search the IP catalog
xviv search axi4 dma

Synthesis

xviv synth --design top          # RTL design
xviv synth --bd     system       # block design
xviv synth --core   clk_wiz_0    # out-of-context IP core

# Resume from an existing checkpoint
xviv synth --design top --resume auto      # detect latest checkpoint automatically
xviv synth --design top --resume place     # resume from after place_design

# Control what gets embedded in the bitstream USR_ACCESS field
xviv synth --design top --usr-access-type git   # default: embeds git SHA

# Open a checkpoint (path tab-completes)
xviv open --dcp build/synth/system/checkpoints/route.dcp

By default, every synth run embeds the short git SHA into the bitstream USR_ACCESS field (bit 28 is set if the working tree was dirty). Fine-grained control is in project.toml: run_synth, run_place, run_route, incremental flows, directive overrides, reports, netlists.

Simulation

xviv simulate --target tb_gamma
xviv simulate --target tb_gamma --run 1000ns
xviv simulate --target tb_gamma --mode post_synth_functional

# Run a specific UVM test
xviv simulate --target tb_gamma --uvm gamma_basic_test

# Open the waveform DB without re-running
xviv open   --wdb tb_gamma
xviv reload --target tb_gamma    # hot-reload snapshot in a live xsim session

Available --mode values: default, post_synth_functional, post_synth_timing, post_impl_functional, post_impl_timing.

Embedded

xviv build --platform mb_platform
xviv build --app firmware
xviv build --app firmware --info    # print ELF section sizes after build

# Program with default FPGA and processor filters (xc7a* / MicroBlaze #0*)
xviv program --platform mb_platform --app firmware

# Explicit paths or custom target filters
xviv program --bitstream path/to/custom.bit --elf path/to/custom.elf
xviv program --platform mb_platform --fpga "xc7a35t*" --processor "MicroBlaze #0*"
xviv program --platform mb_platform --reset-duration 1000   # ms before loading ELF

xviv processor --reset
xviv processor --status

Formal

# Run a named target, or all targets if --target is omitted
xviv formal --target gamma_props
xviv formal

On failure, the counterexample trace path is printed with a gtkwave command ready to paste.

Every command accepts --dry-run to print the generated TCL without executing.


Shell completion

activate-global-python-argcomplete          # system-wide
eval "$(register-python-argcomplete xviv)"  # or per-shell (bash)

Completion is dynamic:

  • IP, BD, design, and simulation names come from project.toml
  • VLNV strings come from the live Vivado IP catalog with descriptions inline
  • DCP paths complete from the known checkpoint locations for each synth run
  • UVM test names filter to the selected simulation target
  • bitstream and ELF paths complete from known output locations.

Project layout

project/
├── project.toml
├── .env                      # optional: XVIV_VIVADO_SOURCE_SCRIPT=...
├── srcs/
│   ├── rtl/
│   ├── sim/
│   └── sw/
├── constraints/
├── scripts/
│   └── xviv/
│       └── bd/
│           └── system.tcl    # BD TCL snapshot - version control this
└── build/                    # gitignore everything here

scripts/xviv/ is the only generated directory that belongs in version control. Everything under build/ is reproducible.


Roadmap

Roughly in order of priority.

Near-term

  • DPI support - C/C++ testbenches that call into the simulator via DPI-C.
  • Configurable HSI targets - the FPGA part and processor target passed to hsi during BSP generation are currently driven by the [[platform]] properties dict; exposing typed config keys would be cleaner.
  • Subcore support for custom IPs - declare that a custom IP depends on another IP internally (e.g. a clk_wiz sub-core), so the packager carries the dependency correctly. BDs get automatic subcore tracking already; standalone IPs don't.

Feature additions

  • ILA / debug core insertion - add and configure Integrated Logic Analyzer cores during implementation, with an optional GUI mode for probe assignment.
  • QSPI flash programming - extend program to write bitstreams to QSPI flash over JTAG, not just direct FPGA configuration.
  • HLS support - bring Vitis HLS projects under the same project.toml and CLI. Synthesised HLS output would export as a first-class IP feeding directly into [[ip]] and the BD flow.
  • Dependency graph - graph command to print or visualise the full entity dependency tree (fpga → ip → core → bd → synth → platform → app).

Infrastructure

  • CI/CD - automatically run synthesis and validation from git push/PR events using xviv's CLI, typically on self-hosted infrastructure due to Vivado resource and licensing constraints.
  • Remote synthesis server - transparently dispatch synthesis jobs to a licensed network machine while preserving the same local xviv command workflow.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

xviv-0.2.7.tar.gz (87.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

xviv-0.2.7-py3-none-any.whl (72.2 kB view details)

Uploaded Python 3

File details

Details for the file xviv-0.2.7.tar.gz.

File metadata

  • Download URL: xviv-0.2.7.tar.gz
  • Upload date:
  • Size: 87.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for xviv-0.2.7.tar.gz
Algorithm Hash digest
SHA256 c1a46fe42168e2d8d5970b1f66efd32e37cb28f267eb256f71ca04c2b49b320d
MD5 71f5b0eb8e6f9b76d7dbdee9c9305561
BLAKE2b-256 e612d544bd31484ca2d025273513ef28d3ed8b6485e6e0cc94966fb1d7323d5f

See more details on using hashes here.

File details

Details for the file xviv-0.2.7-py3-none-any.whl.

File metadata

  • Download URL: xviv-0.2.7-py3-none-any.whl
  • Upload date:
  • Size: 72.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for xviv-0.2.7-py3-none-any.whl
Algorithm Hash digest
SHA256 e718f776cef492f0fc6211bb296350172a7b51b51bacee1aa44e65352bd79108
MD5 ea5e86637c3856d9a8a74c9d8ae2c8fc
BLAKE2b-256 1fa7d427f7eb07a335d61da7208aa1845ea95026c79a0cd9dec906f76b74d4ad

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page