forked from https://gitlab.com/asmir.abdulahovic/nix-xilinx - Adapted to run newer vivado versions
This repo is a collection of files that should help Nix and NixOS users install Xilinx’s software tools - Vivado & Vitis imperatively.
This includes the necessary packages containing the necessary linkers to install & run the full software suite.
Like any other distro user, you should first go to your Xilinx account at:
https://www.xilinx.com/support/download.html and download the installation
.tar file. To extract run tar xvf FPGA*.tar To run this installer, you must enter in the shell.
(DO NOT TRY TO RUN THE .BIN YOU WILL NOT HAVE A GOOD TIME)
This tarball is rather large after extraction. Make sure you have roughly 300 GB to spare. (don’t worry, you can delete the zip and download folder later)
Installing vivado using .bin sucks install the full tarball and install directly in the command line.
./xsetup -b ConfigGen
Go to ~/.Xilinx/install_config.txt and edit the configuration file
Here is an example of what I have as my config as I need a certain Vivado tool for my specific FPGA.
#### Vivado ML Standard Install Configuration #### Edition=Vivado ML Standard Product=Vivado # Path where AMD FPGAs & Adaptive SoCs software will be installed. Destination=/home/kaitotlex/Xilinx # Choose the Products/Devices the you would like to install. Modules=xcv80:0,Zynq UltraScale+ MPSoCs:1,Kintex UltraScale+ FPGAs:0,Virtex UltraScale+ 58G FPGAs:0,xcve2202:0,Vitis Model Composer(A toolbox for Simulink):1,Artix-7 FPGAs:0,Install devices for Alveo and edge acceleration platforms:0,Vitis Embedded Development:0,xcvm1102:0,Zynq-7000 All Programmable SoC:0,xcve2002:0,Virtex UltraScale+ HBM FPGAs:0,Spartan UltraScale+:0,xcve2302:0,Vitis Networking P4:0,Kintex UltraScale FPGAs:0,Power Design Manager (PDM):0,Virtex UltraScale+ FPGAs:0,Artix UltraScale+ FPGAs:0,Spartan-7 FPGAs:0,DocNav:1,Versal RF Series ES1:0,Install Devices for Kria SOMs and Starter Kits:0,xcve2102:0,Kintex-7 FPGAs:0 # Choose the post install scripts you'd like to run as part of the finalization step. Please note that some of these scripts may require user interaction during runtime. InstallOptions=Acquire or Manage a License Key:0 ## Shortcuts and File associations ## # Choose whether Start menu/Application menu shortcuts will be created or not. CreateProgramGroupShortcuts=1 # Choose the name of the Start menu/Application menu shortcut. This setting will be ignored if you choose NOT to create shortcuts. ProgramGroupFolder=AMD Adaptive SoC and FPGA Tools # Choose whether shortcuts will be created for All users or just the Current user. Shortcuts can be created for all users only if you run the installer as administrator. CreateShortcutsForAllUsers=0 # Choose whether shortcuts will be created on the desktop or not. CreateDesktopShortcuts=1 # Choose whether file associations will be created or not. CreateFileAssociation=1
Then, run ./xsetup -a XilinxEULA,3rdPartyEULA,WebTalkTerms -b Install -c $HOME/.Xilinx/install_config.txt to install the entire application.
With what was done now, you can run vivado / vitis from the command line with:
nix run github:MIT-OpenCompute/xilinx-flake#vivado
Use nix search github:MIT-OpenCompute/xilinx-flake to view all other packages defined.
It’s likely you’d like to make the FHS environment survive garbage collections and add a desktop launcher to your system. To do that you can follow one of the following paths according to your setup.
inputs = {
# ...
nix-xilinx = {
# Recommended if you also override the default nixpkgs flake, common among
# nixos-unstable users:
#inputs.nixpkgs.follows = "nixpkgs";
url = "github:MIT-OpenCompute/xilinx-flake";
};
# ...
outputs = { self, nixpkgs, nix-xilinx }:
let
flake-overlays = [
nix-xilinx.overlay
];
in {
nixosConfigurations = (
HOSTNAME = nixpkgs.lib.nixosSystem {
modules = [ (import ./configuration.nix flake-overlays) ]
};
};
};
};And in ./configuration.nix:
# All overlays given by flakes
flake-overlays:
{ config, pkgs, options, lib, ... }:
{
nixpkgs.overlays = [
(
final: prev: {
# Your own overlays...
}
)
] ++ flake-overlays;
}The following setup should also fit flake NixOS users.
Add to your configration.nix (untested, but should work):
nixpkgs.overlays = let
nix-xilinx = import (builtins.fetchTarball "https://gitlab.com/doronbehar/nix-xilinx/-/archive/master/nix-xilinx-master.tar.gz");
in [
nix-xilinx.overlay
(
final: prev: {
# Your own overlays...
}
)
];Some people may wish to not install xilinx' tools globally, and only making it
part of the buildInputs of their project. Usually this paradigm follows along
with direnv
shell.nix
/ flake.nix setup. For
example you can create in your project a shell.nix, or define devShell in
your flake.nix similarly to this:
{ pkgs, nix-xilinx }:
pkgs.mkShell {
buildInputs = (with nix-xilinx.packages.x86_64-linux; [
vivado
vitis
]);
# Define some probably useful environment variables
shellHook = nix-xilinx.shellHooksCommon;
}Note that xilinx' tools still need to be installed in a user-writeable location
for this shellHook to work, as explained here.
This flake also ships a NixOS module that runs the standard Xilinx server daemons as systemd services. Server machines can expose Vivado’s hardware-manager, floating-license, and ChipScope capabilities to the network without installing a full desktop environment.
The three services map directly to what Xilinx ships:
| Service | Default port | Purpose |
|---|---|---|
|
3121 TCP |
JTAG hardware target server. Remote Vivado Hardware Manager sessions connect
here to program and debug FPGAs. This is the same daemon you launch with
|
|
27000 TCP + vendor port |
FlexLM floating licence server. Clients set
|
|
3042 TCP |
ChipScope / ILA analysis server. Used by Vivado Hardware Manager for in-system logic analysis over a network connection. |
# flake.nix on the server machine
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
xilinx-flake.url = "github:MIT-OpenCompute/xilinx-flake";
};
outputs = { self, nixpkgs, xilinx-flake }: {
nixosConfigurations.my-fpga-server = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
xilinx-flake.nixosModules.vivado-server
./configuration.nix
];
};
};
}Add the following to the server’s configuration.nix (or any imported module):
services.vivadoServer = {
enable = true;
# Path to the Xilinx imperative installation on this machine
installDir = "/opt/Xilinx";
version = "2025.2"; # must match the installed release directory
# hw_server — remote JTAG / Hardware Manager
hwServer = {
enable = true;
port = 3121; # Xilinx default, clients expect this
openFirewall = true;
};
# lmgrd — floating licence server
licenseServer = {
enable = true;
port = 27000; # FlexLM default
vendorPort = 27001; # must match "VENDOR xilinxd port=27001" in the .lic
licenseFile = /etc/xilinx/Xilinx.lic;
openFirewall = true;
};
# cs_server — ChipScope / ILA (optional)
csServer = {
enable = true;
port = 3042;
openFirewall = true;
};
# remoteRuns — SSH host for "Launch runs on remote hosts"
remoteRuns = {
enable = true;
# Paste the SSH public key from each client workstation that will
# submit synthesis / implementation jobs via the Vivado dialog.
authorizedKeys = [
"ssh-ed25519 AAAA... engineer@workstation"
];
# This directory is what you enter in Vivado's "Configure Hosts"
# dialog under "Remote working directory".
workDir = "/var/lib/vivado-remote";
# "@localhost" works when licenseServer.enable = true on this machine.
licenseFile = "@localhost";
openFirewall = true; # opens port 22 if not already open
};
# hdlBuild — CLI batch build host for the ichika workflow
# (see "ichika CLI workflow" section below)
hdlBuild = {
enable = true;
# Paste the SSH public key from each developer's machine.
authorizedKeys = [
"ssh-ed25519 AAAA... dev@laptop"
];
workDir = "/var/lib/vivado-remote";
licenseFile = "@localhost"; # omit or null if no local license server
openFirewall = true;
};
};|
Note
|
installDir must point to a Xilinx installation already present on the
server’s filesystem. The Nix module does not install Vivado — follow the
Install section above to perform the imperative installation first, then
point this option at the result.
|
After the server is running, configure client machines:
# Connect Vivado Hardware Manager to a remote hw_server
# In Vivado Tcl console or batch script:
open_hw_manager
connect_hw_server -url my-fpga-server:3121
# Point all Vivado instances at the floating licence server
export XILINXD_LICENSE_FILE=@my-fpga-serverThis corresponds to the "Launch runs on remote hosts" option in Vivado’s Run Settings dialog (Flow → Run Settings or right-click a run in the Design Runs panel).
-
Generate an SSH key pair on the client workstation if you do not already have one:
ssh-keygen -t ed25519 -f ~/.ssh/id_vivado_remote
-
Add the public key (
~/.ssh/id_vivado_remote.pub) toservices.vivadoServer.remoteRuns.authorizedKeysin the server’s NixOS configuration and rebuild. -
In Vivado, open Tools → Options → Remote Hosts (or click Configure Hosts in the Launch Runs dialog) and add a new host:
Field Value Hostname
my-fpga-server(or IP address)Username
vivado(value ofservices.vivadoServer.user)SSH private key
~/.ssh/id_vivado_remoteRemote Vivado installation
Leave blank — the module puts
vivadoin PATH automaticallyRemote working directory
Value of
services.vivadoServer.remoteRuns.workDir(default:/var/lib/vivado-remote) -
Select Launch runs on remote hosts in the Run Settings dialog, choose the host you configured, and click OK. Vivado will SSH into the server and run synthesis/implementation in batch mode there; results are copied back automatically.
|
Note
|
Vivado invokes the remote command as bash --login -c "vivado -mode
batch …". The module injects the FHS-wrapped vivado binary into PATH
via /etc/profile.d/xilinx-remote-runs.sh, which is sourced by all login
shells including non-interactive SSH sessions initiated this way.
|
The ichika flake (github:kaitotlex/ichika) provides a lightweight
alternative to the Vivado GUI remote-run workflow. Developers write HDL in
any editor, and a pair of nix run commands handle all communication with
the build server — no Vivado GUI required on the client machine.
Enable services.vivadoServer.hdlBuild as shown in the configuration
example above and rebuild the server:
nixos-rebuild switchThe module will:
-
Create or update the
vivadosystem user with a login shell. -
Install the provided SSH public keys as
authorized_keys. -
Place a FHS-wrapped
vivadobinary in PATH for all login shells. -
Create the build working directory (
workDir).
From any HDL project directory, initialise an ichika-aware flake:
nix flake init -t github:kaitotlex/ichikaEdit the generated flake.nix to set your top module name, FPGA part
string, RTL source directories, and server address:
hdlApps = ichika.lib.makeHdlApps {
inherit pkgs;
top = "my_top"; # Verilog top module
part = "xczu3eg-sfvc784-1-e"; # FPGA part string
rtlDirs = [ "rtl" ]; # relative dirs rsync'd from $PWD
serverLocal = "10.0.0.228"; # LAN IP
# serverDns = "build.example.com"; # optional public DNS name
};Or add ichika to an existing project’s flake inputs and call makeHdlApps
inside eachDefaultSystem.
# Run synthesis only (useful for checking for synthesis errors quickly)
nix run .#synthesize
# Run the full pipeline: synthesis → opt → place → route → bitstream
# Copies <top>.bit to the current directory when done
nix run .#run-implBoth commands rsync whatever is currently in the configured rtlDirs on
disk — no nix build is required to pick up source edits.
# Default: uses serverLocal (LAN IP)
nix run .#run-impl
# Override with an explicit address
ICHIKA_SERVER=build.example.com nix run .#run-impl
# Use serverDns (if configured in the flake)
ICHIKA_USE_DNS=1 nix run .#run-impl| Option | Default | Description |
|---|---|---|
|
|
Enable the SSH-based CLI batch build host. |
|
|
SSH public keys for developer machines submitting ichika builds. |
|
|
Base directory for per-project build artifacts. ichika creates a sub-directory per top module name here. |
|
|
|
|
|
Opens SSH port 22 in the firewall. Shared with |
Because hw_server, lmgrd, and cs_server all speak raw TCP (not HTTP),
nginx must be configured with the stream module to proxy them. This is
useful for TLS termination, access control, or exposing a single public IP.
In NixOS, services.nginx.streamConfig appends raw nginx config inside the
stream {} block:
services.nginx = {
enable = true;
# The stream block is separate from the http block.
streamConfig = ''
# hw_server — Vivado Hardware Manager remote target
upstream xilinx_hw {
server 127.0.0.1:3121;
}
server {
listen 3121;
proxy_pass xilinx_hw;
proxy_timeout 1d; # synthesis runs can be long
proxy_connect_timeout 10s;
}
# lmgrd — FlexLM licence daemon
upstream xilinx_lic {
server 127.0.0.1:27000;
}
server {
listen 27000;
proxy_pass xilinx_lic;
}
# lmgrd vendor daemon (xilinxd) — must match vendorPort option
upstream xilinx_vendor {
server 127.0.0.1:27001;
}
server {
listen 27001;
proxy_pass xilinx_vendor;
}
# cs_server — ChipScope / ILA
upstream xilinx_cs {
server 127.0.0.1:3042;
}
server {
listen 3042;
proxy_pass xilinx_cs;
}
'';
};
# Ensure nginx can bind the non-HTTP ports
networking.firewall.allowedTCPPorts = [ 3121 27000 27001 3042 ];|
Note
|
When using nginx as a TCP proxy for lmgrd, both the lmgrd port
(27000) and the vendor daemon port (27001) must be proxied. FlexLM clients
make two separate connections — one to lmgrd to locate the vendor daemon, and
a second directly to the vendor daemon port.
|
This repository is mostly copy paste from nix-matlab.