FPGA project controller for Vivado
Project description
xviv
FPGA project controller for Vivado. Drives Xilinx Vivado in non-project mode from a single project.toml configuration file - no GUI clicks, no .xpr files, no state drift.
Manages the full development lifecycle:
- IP packaging with automatic AXI interface inference
- Block Design creation and wrapper generation
- Synthesis -> placement -> routing -> bitstream in one command
- Standalone simulation via
xvlog/xelab/xsimwith live waveform reloading - SystemVerilog interface flattening for Vivado BD compatibility
Table of Contents
- Requirements
- Installation
- Project Structure
- Quick Start
- project.toml Reference
- Workflows
- xviv_wrap_top
- Command Reference
- License
1. Requirements
- Python 3.11+
- Xilinx Vivado 2024.1 (other versions likely work - set the path in
project.toml) pyslang- only required forxviv_wrap_top
2. Installation
Using a Virtual Environment
It is recommended to install xviv inside a .venv local to your project. This keeps the tool version pinned per-project and avoids polluting your system Python.
# Create and activate the venv
python -m venv .venv
source .venv/bin/activate # Linux / macOS
# .venv\Scripts\activate # Windows
# Install xviv
pip install git+https://github.com/you/xviv
# Verify
xviv --help
.venv/ is already listed in the template .gitignore - do not commit it.
From this point on, always activate the venv before running xviv:
source .venv/bin/activate
Updating xviv
pip install --upgrade git+https://github.com/you/xviv
pip re-fetches the latest commit from the repo and reinstalls.
To pin to a specific commit for reproducibility:
pip install git+https://github.com/you/xviv@abc1234
Where abc1234 is the commit hash. Useful once the tool is stable and you don't want surprises from upstream changes mid-project.
3. Project Structure
All paths are configurable in project.toml. The default layout:
my_project/
├── project.toml # Single source of truth for xviv
├── .venv/ # Local Python environment (not committed)
├── srcs/
│ ├── rtl/ # RTL sources (.sv, .v)
│ ├── sim/ # Simulation-only sources
│ └── constrs/ # XDC constraint files
├── scripts/
│ ├── ip/
│ │ └── my_ip_1.0.tcl # Generated IP hook (xviv ip-config)
│ ├── bd/
│ │ └── my_bd_1.0.tcl # Generated BD hook (xviv bd-config)
│ └── synth/
│ └── my_top.tcl # Generated synthesis hook (xviv synth-config)
└── build/ # All outputs land here (not committed)
├── ip/ # Packaged IP cores
├── bd/ # Block Design files
└── xviv/ # Simulation build artifacts
4. Quick Start
Create a project.toml in your project root:
[vivado]
path = "/opt/Xilinx/Vivado/2024.1"
max_threads = 20
mode = "batch"
[fpga]
part = "xc7z020clg400-1"
board_part = "tul.com.tw:pynq-z2:part0:1.0"
board_repo = "/path/to/vivado-boards/new/board_files"
[build]
dir = "build"
ip_repo = "build/ip"
bd_dir = "build/bd"
wrapper_dir = "srcs/rtl"
[sources]
rtl = ["srcs/rtl/**/*.sv", "srcs/rtl/**/*.v"]
sim = ["srcs/rtl/**/*.sv", "srcs/sim/**/*.sv"]
[[synthesis]]
top = "my_top"
hooks = "scripts/synth/my_top.tcl"
constrs = ["srcs/constrs/**/*.xdc"]
[[ip]]
name = "my_ip"
vendor = "user.org"
library = "user"
version = "1.0"
top = "my_ip"
hooks = "scripts/ip/my_ip_1.0.tcl"
[[bd]]
name = "my_bd"
hooks = "scripts/bd/my_bd_1.0.tcl"
5. project.toml Reference
[vivado]
| Key | Default | Description |
|---|---|---|
path |
/opt/Xilinx/Vivado/2024.1 |
Vivado installation root |
max_threads |
8 |
general.maxThreads Vivado parameter |
mode |
batch |
batch for scripted runs, tcl for interactive |
[fpga]
| Key | Required | Description |
|---|---|---|
part |
yes | FPGA part string e.g. xc7z020clg400-1 |
board_part |
no | Board part string for board presets |
board_repo |
no | Path to custom board files directory |
[build]
| Key | Default | Description |
|---|---|---|
dir |
build |
Root build output directory |
ip_repo |
build/ip |
Where packaged IPs are stored |
bd_dir |
build/bd |
Where Block Design outputs land |
wrapper_dir |
srcs/rtl |
Where generate-bd copies the BD wrapper |
[sources]
| Key | Description |
|---|---|
rtl |
Glob list of RTL sources added to synthesis and IP edit projects |
sim |
Glob list of sources compiled by xvlog for simulation |
[[ip]]
| Key | Default | Description |
|---|---|---|
name |
required | IP name |
vendor |
user.org |
IP vendor string |
library |
user |
IP library string |
version |
1.0 |
IP version string |
top |
same as name |
Top-level HDL module name |
hooks |
scripts/ip/<n>_<version>.tcl |
Path to the hook TCL file |
[[bd]]
| Key | Default | Description |
|---|---|---|
name |
required | Block Design name |
hooks |
scripts/bd/<n>_<version>.tcl |
Path to the hook TCL file |
[[synthesis]]
| Key | Description |
|---|---|
top |
Top module name |
hooks |
Path to the synthesis hook TCL file |
constrs |
Glob list of XDC constraint files for this target |
6. Workflows
IP Packaging
# Generate a hook file with stubs for all customisation points
xviv ip-config --ip my_ip
# Edit scripts/ip/my_ip_1.0.tcl, then package the IP
xviv create-ip --ip my_ip
# Reopen an existing IP in the Vivado GUI
xviv edit-ip --ip my_ip
The generated hook file exposes five procs:
| Proc | Purpose |
|---|---|
ipx_add_files |
Add your RTL sources to the IP edit project |
ipx_merge_changes |
Post-merge fixups |
ipx_infer_bus_interfaces |
Infer non-AXI bus standards |
ipx_add_params |
Reorder / group HDL parameters in the IP GUI |
ipx_add_memory_map |
Add custom memory maps |
AXI-Stream and AXI-MM interfaces are inferred automatically.
Block Design
# Generate a hook file
xviv bd-config --bd my_bd
# Edit scripts/bd/my_bd_1.0.tcl, then create the BD
xviv create-bd --bd my_bd
# Open an existing BD in the GUI for further edits
xviv edit-bd --bd my_bd
# Generate output products and copy the wrapper to wrapper_dir
xviv generate-bd --bd my_bd
Synthesis & Implementation
# Generate a hook file with lifecycle and report-flag procs
xviv synth-config --top my_top
# Full flow: synth -> place -> route -> bitstream -> XSA
xviv synthesis --top my_top
# Open any intermediate checkpoint in the GUI
xviv open-dcp --top my_top --dcp post_synth
xviv open-dcp --top my_top --dcp post_route
Outputs land in build/<top>/:
post_synth.dcp
post_place.dcp
post_route.dcp
my_top.bit
my_top.xsa
reports/
netlists/
The synthesis hook lets you skip report groups (useful during early development) and inject TCL at each stage:
proc report_synth {} { return 0 } # skip - speeds up iteration
proc report_place {} { return 1 }
proc report_route {} { return 1 }
proc report_netlists {} { return 0 }
proc synth_pre {} { } # before synth_design
proc synth_post {} { } # after synthesis, before placement
proc place_post {} { } # after placement, before routing
proc route_post {} { } # after routing, before bitstream
proc bitstream_post {} { } # after write_bitstream and write_hw_platform
Simulation
# Compile, elaborate, and optionally run headlessly
xviv elaborate --top my_tb
xviv elaborate --top my_tb --run "1000ns"
# With a DPI shared library
xviv elaborate --top my_tb --so my_dpi --dpi-lib ./build/libs
# Open the waveform database in the xsim GUI
xviv open-wdb --top my_tb
# Hot-reload waveform into an already-open xsim window (no window close)
xviv reload-wdb --top my_tb
Simulation artifacts land in build/xviv/<top>/.
Snapshots
A snapshot is the compiled simulation binary produced by xelab. You can open it directly for interactive simulation:
xviv open-snapshot --top my_tb
# Re-elaborate and reload into the open xsim window
xviv reload-snapshot --top my_tb
7. xviv_wrap_top
Vivado Block Design does not accept SystemVerilog interface ports. xviv_wrap_top parses your SV module with pyslang and generates a flat wrapper that expands every interface port into individual signals, suitable for IP packaging and BD instantiation.
xviv_wrap_top \
--top my_ip \
--wrapper-dir srcs/rtl \
srcs/rtl/my_ip.sv \
srcs/rtl/axi_stream_if.sv
Given a module with interface ports:
module my_ip (
input logic clk,
axi_stream_if.slave s_axis,
axi_stream_if.master m_axis
);
It generates my_ip_wrapper.sv with all interface signals flattened to plain ports and assign statements wiring them through. Use the wrapper as the IP top module in your [[ip]] config.
8. Command Reference
IP
| Command | Arguments | Description |
|---|---|---|
ip-config |
--ip <n> |
Generate a starter hook file |
create-ip |
--ip <n> |
Package the IP |
edit-ip |
--ip <n> |
Open IP in the Vivado GUI |
Block Design
| Command | Arguments | Description |
|---|---|---|
bd-config |
--bd <n> |
Generate a starter hook file |
create-bd |
--bd <n> |
Create the Block Design |
edit-bd |
--bd <n> |
Open BD in the Vivado GUI |
generate-bd |
--bd <n> |
Generate output products and copy wrapper |
Synthesis
| Command | Arguments | Description |
|---|---|---|
synth-config |
--top <module> |
Generate a starter hook file |
synthesis |
--top <module> |
Full implementation flow |
open-dcp |
--top <module> [--dcp post_synth] |
Open a checkpoint in the GUI |
Simulation
| Command | Arguments | Description |
|---|---|---|
elaborate |
--top <sim_top> [--run <time>] [--so <lib>] [--dpi-lib <dir>] |
Compile, elaborate, optionally run |
open-wdb |
--top <sim_top> |
Open waveform database in xsim GUI |
reload-wdb |
--top <sim_top> |
Hot-reload waveform into open xsim window |
open-snapshot |
--top <sim_top> |
Open simulation snapshot in xsim GUI |
reload-snapshot |
--top <sim_top> |
Re-run and reload into open xsim window |
Global Options
| Option | Default | Description |
|---|---|---|
--config / -c |
project.toml |
Project configuration file |
--log-file |
build/xviv/xviv.log |
Append debug log to file |
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file xviv-0.1.2.tar.gz.
File metadata
- Download URL: xviv-0.1.2.tar.gz
- Upload date:
- Size: 22.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e1f44f484d19e44bd88bab6fb91129e19ad514dd91a5471b18f293952926213
|
|
| MD5 |
d01968745231b4b1605957656bd6cafd
|
|
| BLAKE2b-256 |
94820d12e0fadee3f9f0ea6718f14515109e1a4d2e7e629777049179edbbb2e5
|
File details
Details for the file xviv-0.1.2-py3-none-any.whl.
File metadata
- Download URL: xviv-0.1.2-py3-none-any.whl
- Upload date:
- Size: 23.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
992c5553723118a0ce62b9d7e687d8bd3d97e641641670278cd0827cd85639be
|
|
| MD5 |
6f1fb246f579e8d4fceb1e1df2f15fc9
|
|
| BLAKE2b-256 |
3dcdfc5fa5558ffdc98ebef27ee2b42f505883bccacade922ad62196f371222a
|