Skip to main content

FPGA project controller for Vivado

Project description

xviv

xviv is a command-line project controller for AMD/Xilinx Vivado and Vitis workflows. It replaces the manual, GUI-driven FPGA development cycle with a declarative, reproducible, version-control-friendly build system driven by a single project.toml (or project.cue) configuration file.


Table of Contents


Features

  • Declarative project config — FPGA part, IP cores, block designs, synthesis targets, simulation targets, and embedded platforms all defined in one file.
  • CUE or TOML — validated CUE schemas (project.cue) or plain TOML (project.toml).
  • IP management — create, edit, and synthesise custom IP packaged in Vivado's IP catalog format. Optional SV wrapper generation via pyslang for interface-port flattening.
  • Block Design (BD) — create, edit, generate output products, export versioned TCL snapshots, and synthesise BDs without touching the GUI.
  • Full synthesis pipeline — synth → opt → place → phys-opt → route → bitstream, with incremental synthesis and incremental implementation support and per-stage hooks.
  • Simulation — compile with xvlog/xelab, run with xsim, open waveforms, and hot-reload snapshots over a FIFO control channel.
  • Embedded (MicroBlaze) — BSP generation, app scaffolding, build, FPGA programming, processor reset and status via xsct.
  • IP catalog search — full-text search across VLNV, display name, and description.
  • Shell autocompletionargcomplete-powered tab completion for every flag, including dynamic IP/BD/top names and VLNV strings from the live catalog.
  • Git-aware builds — SHA tag and dirty-state tracking embedded in bitstream USR_ACCESS and output filenames; diff patches captured for dirty builds.

Installation

pip install xviv

Requires Python 3.10+.
Optional: install cue to use .cue project files.
Optional: install pyslang for SV wrapper generation.

Vivado/Vitis must be installed separately. Point xviv at them via environment variables:

export XVIV_VIVADO_DIR=/opt/Xilinx/Vivado/2024.1
export XVIV_VITIS_DIR=/opt/Xilinx/Vitis/2024.1

Quick Start

# 1. Create project.toml in your project root
cat > project.toml <<'EOF'
[fpga.main]
part       = "xc7z020clg400-1"
board_part = "digilentinc.com:zedboard:part0:1.0"

[[synthesis]]
top = "top_design"
rtl = ["srcs/rtl/**/*.sv"]
xdc = ["constraints/top.xdc"]
EOF

# 3. Synthesise the top-level design
xviv synth --top top_design

# 4. Open the post-synthesis checkpoint
xviv open --dcp post_synth --top top_design

Configuration

xviv reads project.cue first, then falls back to project.toml. The --config / -c flag overrides this.

[fpga]

[fpga]
default = "main"          # which named target to use by default

[fpga.main]
part       = "xc7z020clg400-1"
board_part = "digilentinc.com:zedboard:part0:1.0"
board_repo = ""            # optional path to a custom board repo

[fpga.ooc]
part = "xc7z020clg400-1"  # a second named target for OOC synthesis

[vivado]

[vivado]
mode        = "batch"          # batch | tcl
max_threads = 8
hw_server   = "localhost:3121"

[vitis]

[vitis]
# path is read from $XVIV_VITIS_DIR; no explicit key needed

[build]

[build]
dir         = "build"
ip_repo     = "build/ip"
bd_dir      = "build/bd"
wrapper_dir = "build/wrapper"
core_dir    = "build/core"

[[ip]]

[[ip]]
name           = "my_ip"
vendor         = "user.org"
library        = "user"
version        = "1.0"
top            = "my_ip"          # HDL top module name
rtl            = ["srcs/rtl/**/*.sv"]
hooks          = "scripts/ip/my_ip_1.0.tcl"   # auto-generated path if omitted
create-wrapper = false            # true to auto-generate a flat SV wrapper

[[bd]]

[[bd]]
name       = "system"
hooks      = "scripts/bd/system_hooks.tcl"    # auto-generated if omitted
export_tcl = "scripts/bd/state/system.tcl"    # auto-generated if omitted
fpga       = ""                               # override fpga target

[[synthesis]]

[[synthesis]]
top              = "top_design"
ip               = ""              # IP name if this is an IP synth entry
bd               = ""              # BD name if this is a BD synth entry
rtl              = ["srcs/rtl/**/*.sv"]
xdc              = ["constraints/top.xdc"]
xdc_ooc          = []
fpga             = ""              # override fpga target
hooks            = "scripts/synth/top_design.tcl"

# Reporting
report_synth     = false
report_place     = false
report_route     = false
generate_netlist = false
out_of_context   = false

[[simulate]]

[[simulate]]
top = "tb_top"
rtl = ["srcs/sim/**/*.sv", "srcs/rtl/**/*.sv"]

[[platform]]

[[platform]]
name      = "zed_platform"
cpu       = "ps7_cortexa9_0"
os        = "standalone"
synth_top = "top_design"   # or: xsa = "path/to/manual.xsa"

[[app]]

[[app]]
name     = "hello_world"
platform = "zed_platform"
template = "hello_world"
src_dir  = "srcs/sw/hello_world"

Commands

create

xviv create --ip   <name>               # scaffold and package a custom IP
xviv create --bd   <name>               # create a new Block Design project
xviv create --core <name> --vlnv <vlnv> # instantiate a catalog IP into build/core
xviv create --platform <name>           # generate a BSP from an XSA
xviv create --app  <name> [--platform <p>] [--template <t>]

search

xviv search <query>     # search VLNV, display name, and description

edit

xviv edit --ip <name> [--nogui]
xviv edit --bd <name> [--nogui]

config

Generates a starter hooks TCL file for the named target. Safe to re-run only before the hooks file exists.

xviv config --ip  <name>
xviv config --bd  <name>
xviv config --top <name>

generate

xviv generate --bd <name>   # generate output products + Verilog wrapper

export

xviv export --bd <name>     # export BD as a versioned re-runnable TCL script

synth

xviv synth --ip  <name>
xviv synth --bd  <name> [--ooc-run]
xviv synth --top <name>

open

xviv open --dcp <stem> --top <name> [--nogui]   # open a .dcp checkpoint
xviv open --snapshot   --top <name>             # open post-sim waveform
xviv open --wdb        --top <name>             # open a .wdb waveform DB

elaborate

xviv elaborate --top <name> [--run <time>]   # compile + optionally run sim

simulate

xviv simulate --top <name> [--run <time>]

reload

xviv reload --snapshot --top <name>   # hot-reload xsim snapshot
xviv reload --wdb      --top <name>   # reload waveform DB

build

xviv build --platform <name>
xviv build --app      <name> [--info]

program

xviv program [--platform <name>] [--app <name>] [--elf <path>] [--bitstream <path>]

processor

xviv processor --reset
xviv processor --status

Shell Completion

Enable argcomplete system-wide:

activate-global-python-argcomplete

Or per-shell (bash):

eval "$(register-python-argcomplete xviv)"

Tab completion is context-aware: IP names, BD names, top names, DCP stems, VLNV strings, and platform/app names all complete dynamically from your project config and the live Vivado IP catalog.


Project Layout

A typical project using xviv looks like:

my_project/
├── project.toml
├── srcs/
│   ├── rtl/
│   │   └── *.sv
│   ├── sim/
│   │   └── *.sv
│   └── sw/
│       └── hello_world/
│           └── main.c
├── constraints/
│   └── top.xdc
├── scripts/
│   ├── ip/
│   │   └── my_ip_1.0.tcl     # generated by: xviv config --ip my_ip
│   ├── bd/
│   │   ├── system_hooks.tcl  # generated by: xviv config --bd system
│   │   └── state/
│   │       └── system.tcl    # generated by: xviv export --bd system
│   └── synth/
│       └── top_design.tcl    # generated by: xviv config --top top_design
└── build/                    # all outputs; safe to gitignore
    ├── ip/                   # packaged custom IPs
    ├── bd/                   # block design files
    ├── wrapper/              # generated SV wrappers
    ├── core/                 # instantiated catalog IP cores
    ├── elab/                 # simulation elaboration outputs
    ├── synth/                # synthesis checkpoints + bitstreams
    ├── bsp/                  # embedded BSPs
    ├── app/                  # embedded application builds
    └── xviv/                 # xviv logs and control FIFOs

License

See LICENSE for details.

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.6.tar.gz (59.0 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.6-py3-none-any.whl (75.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: xviv-0.2.6.tar.gz
  • Upload date:
  • Size: 59.0 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.6.tar.gz
Algorithm Hash digest
SHA256 b0b21e615ea9a981db8f4c27904caf1b111b007fb35ef901bc3546eb9220c15b
MD5 76b234267cacc46cbfc56fac26f3e270
BLAKE2b-256 9d03000f205a6954151f75ba9bf21064ab422ebd645ba14664ed77e7f43b30f9

See more details on using hashes here.

File details

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

File metadata

  • Download URL: xviv-0.2.6-py3-none-any.whl
  • Upload date:
  • Size: 75.5 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.6-py3-none-any.whl
Algorithm Hash digest
SHA256 52722a0a80b23de78eae5d8bc072360e6f67dbeccad1326412a9d455a36e8cee
MD5 018715f74f02984d7010a103416922ae
BLAKE2b-256 4175aea26b70f58fe94ce6566f9fa0ca1b0cde2e850d724c4b556a8afa17b5d3

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