前言

将 NixOS 作为 IC/FPGA 设计开发的主力操作系统时,最令人头疼的问题之一,便是许多商业 EDA 工具往往无法直接兼容。这类工具通常版本较旧、更新缓慢,对基础运行库(如 glibclibstdc++ 等)的版本极其敏感。一旦使用较新的系统库,就难免遭遇“符号未定义”或段错误等问题,导致在较新的 Linux 发行版上安装与运行这些工具变得异常困难。

参考 Chisel-nix 项目的思路,我拓展出了 xilinx-nix 项目,打造一个能够在 NixOS 环境下顺畅运行 Xilinx 设计套件,并可联合 Synopsys VCS/Verdi 进行仿真的开发平台。

与 Chisel-nix 中创新性地将 Verilator/VCS 集成到 Chisel 仿真流程、并通过 Rust 进行高层次仿真的方式不同,xilinx-nix 目前仍沿用经典的 Verilator/VCS 编译仿真流程——用户可自行编写测试平台文件并放置于指定目录,再传入仿真环境。这种方式更贴近传统硬件设计习惯,也可作为理解与过渡到 Chisel-nix 那种高度集成化仿真模式的参考。

本项目参考了 Chisel-nix 项目的目录框架、vcs 的环境和使用以及 vcs 的脚本(vcs-fhs-env.nixvcs.nixvcs-wrapper.sh

安装

此处提供的 Nix 配置专门用于构建 安装环境

在安装 Xilinx 或 Synopsys 工具时,您只需通过该脚本处理安装程序的依赖问题。若遇到报错,可根据提示增补缺失的系统包,即可顺利运行下载器或安装向导。在 xilinx-nix 中提供了两个 Nix 安装环境文件。

  • xilinx_fhs_install.nix:涵盖了 Xilinx 2024.1 下载器及安装程序所需的核心依赖。
  • vcs_fhs_install.nix:涵盖了运行 SynopsysInstaller 所需的核心依赖,支持根据实际安装版本灵活调整依赖包。

使用方法(在 NixOS 或已安装 Nix 的系统中):

1
2
3
4
# 进入 Xilinx 安装环境
nix-shell xilinx_fhs_install.nix
# 进入 Synopsys 安装环境
nix-shell vcs_fhs_install.nix

软件版本说明

  • NixOS: 25.11
  • Xilinx Vivado: 2024.1(从官网下载Linux版安装器)
  • Synopsys VCS: 2023.03-SP2(根据Xilinx UG900文档中支持的仿真器版本)
  • Synopsys Verdi: 2023版本(建议不低于VCS版本,其他版本未测试)

学习资源

准备工作

在开始之前,请确保你的安装目录已按以下结构组织好相关文件。这些文件包括了 Synopsys Installer、SCL 授权工具、VCS/Verdi 安装包以及 Nix 配置文件(Nix 文件在 github 仓库里,Xilinx 下载器官方网站下载 Linux 版本,其余的在网盘链接内)。

1
2
3
4
5
6
7
8
9
10
11
12
13
.
├── installer/ # Synopsys 安装程序
│ ├── SynopsysInstaller_v5.8.run
│ └── ...
├── scl/ # SCL (Synopsys Common Licensing)
│ └── 2021.03/
├── vcs_all_vU-2023.03-SP2/ # VCS 源码包
├── verdi_vV-2023.12-SP2/ # Verdi 源码包
├── 1patch # 补丁工具
├── scl_keygen/ # License 生成器 (Windows 可执行文件)
├── FPGAs_AdaptiveSoCs_Unified_2024.1_0522_2023_Lin64.bin # Xilinx 安装包
├── vcs_fhs_install.nix # VCS 的 Nix FHS 配置文件
└── xilinx_fhs_install.nix # Xilinx 的 Nix FHS 配置文件

安装 Synopsys VCS & Verdi

启动 Nix FHS Shell

由于 EDA 工具对系统库(如 libGL, libX11)有极其复杂的依赖,我们使用 vcs_fhs_install.nix 构造一个模拟传统 Linux 目录结构的 Shell 环境:

1
nix-shell vcs_fhs_install.nix

首次运行会下载大量依赖包,请确保网络环境畅通。 当所需依赖包都下载完之后即可进入 nix-shell 环境。
alt text

关于安装路径的建议

强烈建议将软件安装在 /opt/synopsys 下,而非用户家目录 (~/)。

原因分析:
xilinx-nixchisel-nix 的配置中,通常会包含路径自检逻辑。如果你尝试安装在 $HOME 下,Nix 在构建 Derivation 时,由于 nixbld 用户没有权限读取权限为 700 的用户目录,会导致如下报错:

1
env VC_STATIC_HOME='...' points to unknown location

这个报错来源于 xilinx-nix/vcs-fhs-env.nixprofile 中写的那行自检代码:

1
[ ! -e "${vcStaticHome}" ] && echo "env VC_STATIC_HOME='${vcStaticHome}' points to unknown location" && exit 1

虽然设置了 __noChroot = truesandbox = relaxed,但这只是允许 Nix 访问外部路径,并不意味着它有权限读取私有家目录。Nix 的构建是由系统用户 nixbld1, nixbld2 等执行,在 NixOS 上,用户家目录(/home/$usrname)的权限默认通常是 700(仅自己可见)。你可以开放用户家目录的读取权限,这样操作会导致一些安全问题,推荐还是把 synopsys 安装到 /opt/... 文件下。

在 chisel-nix 和 xilinx-nix 中都采用了__noChroot=true,Nix 的构建默认是在严格隔离的沙盒中进行的(无网络、无法访问 /usr 等)。但 VCS 在编译的时候需要连接 License Server 检查许可证。如果关在沙盒里会报错,所以要开启这个属性。

而开启这个属性需要 NixOS 25.11 用户在configuration. Nix中设置nix. Settings. Sandbox="relaxed"

#### 执行安装程序 **1. 初始化 Installer** 进入 installer 目录并运行命令:
1
./SynopsysInstaller_v5.8.run

当提示安装目录时,输入 . 安装在当前目录即可。
alt text

2. 运行 setup.sh
安装完之后会在本地目录出现一个 setup.sh 脚本,运行这个脚本就可以安装 vcs 和 verdi 到指定文件目录下。图中的步骤需要输入源文件地址,这个指的是 Synopsys 安装包的地址(vcs_all_vU-2023.03-SP2 的地址)。
alt text

下一个步骤就是填写你的安装地址,这里填写的是 /opt/synopsys,剩下的步骤就是一路 next 到安装完成即可,verdi 的安装步骤和 vcs 一样,这里不多说。

alt text

最后将下载的 scl 文件夹移动到安装目录即可。网盘链接里面附带的 Synopsys.dat 我已经试过,不能使用。建议还是按照破解流程走一遍,生成一份 license。

破解与 License 生成

运行 1patch

nix-shell环境中,对所有安装好的组件执行 patch。注意权限不足时需使用 sudo(或在 shell 中以 root 运行):

1
2
3
4
chmod +x 1patch
./1patch -ecc /opt/synopsys/vcs/U-2023.03-SP2
./1patch -ecc /opt/synopsys/verdi/V-2023.12-SP2
./1patch -ecc /opt/synopsys/scl/2021.03

生成 License (Wine)

由于 scl_keygen.exe 是 Windows 程序,我们需要在 Nix 中临时调用 Wine(是一个允许类 Unix 操作系统在 X Window System 运行 Microsoft Windows 程式的软件):

1
2
nix-shell -p wine
wine scl_keygen.exe

alt text

出现 Synopsys License Generator 窗口,即运行成功。这里需要填写 HostidHostname 以及 port (27000),linux 执行命令:

1
2
ip address  # 查看mac地址,mac地址就是hostid
hostname # 查看hostname

点击 Generate 就会在本目录下生成一个 Synopsys.dat 文件,将该文件放置在 /opt/synopsys/scl 目录下。

注意:需要修改 Synopsys.dat 文件中的 snsplmd 路径为你的路径。

alt text

到此,vcs 和 verdi 已经安装完毕。

安装 Xilinx Vivado/Vitis 2024.1

Xilinx 的安装过程相对独立,但体积庞大,建议预留足够的磁盘空间。确保在 Xilinx 官网上下载了 FPGAs_AdaptiveSoCs_Unified_2024.1_0522_2023_Lin64.bin 文件之后,输入 Shell 命令:

1
2
3
4
5
6
# 进入 xilinx 安装环境
nix-shell xilinx_fhs_install.nix
# 给下载器添加运行权限
chmod +775 ./FPGAs_AdaptiveSoCs_Unified_2024.1_0522_2023_Lin64.bin
# 运行下载器
./FPGAs_AdaptiveSoCs_Unified_2024.1_0522_2023_Lin64.bin

进入 xilinx 的安装环境,给下载器添加运行权限之后就可以运行,安装步骤与 windows 上的操作类似。

xilinx 环境比较简单,xilinx_fhs_env 环境即可安装与运行,安装完成在 .bashrc (.zshrc ) 文件中添加环境变量,同理为了之后在 xilinx-nix 中运行 xilinx,必须要安装在 /opt/.. 文件目录下:

1
2
3
4
5
6
# Xilinx
# 在 xilinx-nix 中需要用到 xilinx 的安装路径
export XILINX_STATIC_HOME=/opt/Xilinx
source /opt/Xilinx/Vitis/2024.1/settings64.sh
source /opt/Xilinx/Vivado/2024.1/settings64.sh
source /opt/Xilinx/Vitis_HLS/2024.1/settings64.sh

环境配置参考了 nix-environment 中的 xilinx-vitis: https://github.com/nix-community/nix-environments/tree/master/envs/xilinx-vitis

Xilinx-nix

在集成电路(IC)设计领域,环境配置往往比设计本身更令人头疼。Synopsys VCS 或 Xilinx 这些商业软件通常具有以下特征:

  • 依赖极其陈旧:为了稳定性,许多工具仍依赖十年前的 libncurses5 或特定的 libpng 版本。
  • 硬编码路径:大量脚本依赖 /bin/bash 或特定的 FHS 目录结构。
  • 版本冲突:VCS 和 vivado 的依赖库版本不兼容

传统的解决方案是使用虚拟机或配置复杂的 Docker 镜像。但虚拟机性能损耗大,Docker 处理 GUI(X11/OpenGL)转发又非常繁琐。Xilinx-nix 通过 Nix 这一声明式包管理器,为 EDA 工具构建一个既能享受宿主机性能,又能完全隔离依赖的框架。


FHS 虚拟环境 (buildFHSEnv)

采用 Nix 的 buildFHSEnv 方案解决Nix 的结构标准与 EDA 工具要求的 FHS(文件系统层次结构标准)的问题。

vcs-fhs-env.nix 中:

1
2
3
4
5
6
nixpkgsSrcs = fetchFromGitHub {
owner = "NixOS";
repo = "nixpkgs";
rev = "c374d94f1536013ca8e92341b540eba4c22f9c62"; # 锁定特定版本
hash = "sha256-Z/ELQhrSd7bMzTO8r7NZgi9g5emh+aRKoCdaAv5fiO0=";
};

闭源工具链 (如 VCS) 不会随系统滚动更新。如果宿主机的 Glibc 升级到了 2.39, 而 VCS 支持 2.31, 仿真就会崩溃。通过 锁定 Nixpkgs 的 Git 提交哈希,可以将整个运行环境“冻结”在一个可验证的时间点,确保库版本长期稳定。这一设计思路主要参考了 Chisel-nix,并在此基础上扩展到了 Xilinx + Synopsys 工具链。

xilinx-fhs-env.nix 中,不仅需要包含 xilinx 的环境变量,还需要包含 VCS 和 Verdi 工具的环境变量,防止后续生成 xilinx 编译库以及联合仿真时出现的环境问题。

如果想要单独使用 VCS/Verdi 或者 Xilinx 工具可以输入以下命令进入 Shell 环境:

1
2
nix develop --impure
vcs-fhs-env/xilinx-fhs-env # 进入 vcs 开发环境或者 xilinx 开发环境

Verdi 查看波形脚本

Chisel-nix 中提供了 VCS 的脚本,在此基础上我拓展了 Verdi 的使用。用户在终端输入 nix build .#demo.verdi --impure,脚本就会自动从默认结果目录抓取最新的设计和波形,然后在兼容的虚拟环境里为你打开 Verdi 界面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!@shell@

# default result directory
_RESULT_DIR="demo-sim-result/result"

if [ ! -d "$_RESULT_DIR" ]; then
echo "Error: Result directory $_RESULT_DIR not found. Run simulation first."
exit 1
fi

# find the first .daidir and .fsdb file in the result directory
_DAIDIR=$(ls -d $_RESULT_DIR/*.daidir 2>/dev/null | head -n 1)
_FSDB=$(ls $_RESULT_DIR/*.fsdb 2>/dev/null | head -n 1)

if [ -z "$_DAIDIR" ]; then
echo "Error: No .daidir found in $_RESULT_DIR"
exit 1
fi

# create the Verdi command
_VERDI_CMD="verdi -dbdir $_DAIDIR"
if [ -n "$_FSDB" ]; then
_VERDI_CMD="$_VERDI_CMD -ssf $_FSDB"
fi

echo "[nix-verdi] Opening: $_VERDI_CMD"

# enter FHS environment to execute
exec "@vcsFhsEnv@" -c "$_VERDI_CMD $@"

自动化 Xilinx 仿真库编译

在使用 VCS 仿真任何 Xilinx IP 之前,必须先编译 Xilinx Simulation Libraries
这个过程如果通过 Vivado GUI 手动操作:

  • 步骤繁琐
  • 编译时间长
  • 完全不可复现

在 demo/xilinx-simlib.nix 中,用 Nix Derivation 封装 Simlib 编译流程:

  • 自动生成 gen_lib.tcl
  • 在 FHS 环境中调用 vivado -mode batch
  • 将编译好的仿真库 持久化到 Nix Store
1
nix build '.#xilinx-simlib' --impure
Vivado 的 `settings64.sh` 会污染当前 shell 环境,导致即便在 nix 中固定了 GCC 9,运行时仍可能使用宿主机 GCC。 而 Xilinx 仿真库编译严格要求 GCC 9.2,这会导致部分库编译失败。 该问题仍在修复中。

一键式 Vivado-VCS 联合仿真

demo/vivado-sim.nix 中,定义了 run-sim 脚本,它自动化了以下链路:

  1. 工程创建:调用 Vivado 运行 setup_vcs_verdi.tcl
  2. 脚本修补:Vivado 生成的 shell 脚本通常硬编码了/bin/sh,我们会自动将其 Patch 为 Nix 环境下的 bash 并赋予执行权限。
  3. 三部曲执行:在 vcs-fhs-env 环境下依次运行 compile.sh -> elaborate.sh -> simulate.sh
  4. 波形查看:通过 view-waves 命令,自动查找生成的 .fsdb 文件并挂载 daidir 启动 Verdi。
1
2
3
# 在 shell 中只需两步
nix run '.#demo.vivado-sim-run' # 自动化编译并跑仿真
nix run '.#demo.vivado-view-waves' # 自动打开 Verdi 看波形

在 xilinx-nix 中给出的 demo 是一个使用 vivado IP 的测试文件,里面使用了 xilinx 的 clk_wiz 的 IP,对应的 setup_vcs_verdi.tcl 是一个创建 vivado 工程->创建 IP->生成脚本的示例工程。如果要使用其他的 FPGA 配置,需要自己修改 create_project 部分和 IP setting 部分。

SpinalHDL 硬件描述与自动化生成 (v1.1 新特性)

v1.1 版本中,xilinx-nix 引入了对 SpinalHDL 的深度集成。SpinalHDL 允许工程师使用 Scala 这种高层语言进行硬件描述,但其传统的开发痛点在于 JVM 生态复杂的依赖管理(SBT/Ivy/Coursier),在没有网络或环境隔离的服务器上经常因无法下载依赖而构建失败。但是 SpinalHDL 相比 Chisel 构建较为简单,没有 MLIR 等中间编译步骤,并经常使用 sbt 工具进行构建。

通过集成 sbt-derivation,我们将 SpinalHDL 的构建逻辑纳入了 Nix 的管理:

  1. 依赖锁定:通过 depsSha256 锁定 Scala 项目的所有依赖库。即使在离线环境下,只要 Nix Store 中存在缓存,即可实现确定性的 RTL 生成。
  2. 无缝对接仿真:通过 .#demo.spinal 生成的 Verilog 源码会自动带有 filelist.f,可以直接被后续的 .#demo.vcs.#demo.verilated 消费,实现了从高级抽象语言到商业仿真器的全闭环。

spinal-rtl.nix 中,我们定义了如下构建逻辑:

1
2
3
4
5
6
7
buildPhase = ''
export HOME=$(pwd)
echo "[nix] Generating Verilog for ${target}..."
sbt ${lib.concatStringsSep " " sbtFlags} \
-Dsbt.offline=true \
"set fork := false; runMain ${target}.MyTopLevelVerilog"
'';

使用指南

本项目通过 Overlay 机制扩展了 nixpkgs。你可以通过 .#demo.<attr> 构建不同的组件。

1. 基础 RTL 仿真

使用源代码目录下的 Verilog 文件进行仿真:

目标 (Attribute) 描述
.#demo.rtl 收集源码并生成 filelist.f
.#demo.verilated 使用 Verilator 编译的仿真器可执行文件
.#demo.vcs 使用 VCS 编译的仿真器 (Standalone)
.#demo.vcs-trace 启用 FSDB 波形追踪的 VCS 仿真器
.#demo.verdi 打开交互式 Verdi 查看波形
构建示例:
1
2
3
nix build '.#demo.rtl' --impure # 运行编译之前一定要先运行该步骤
nix run '.#demo.vcs-trace' --impure -- +dump-start=0 +dump-end=10000 +wave-path=trace
nix run '.#demo.verdi' --impure

2. Xilinx 仿真流

针对包含 Xilinx IP 的工程,使用自动化流水线:

  • 编译 Xilinx 仿真库

    1
    nix build '.#xilinx-simlib' --impure # 有 bug 正在修改
    1
    2
    3
    nix develop --impure 
    xilinx-fhs-env
    vivado -mode batch -notrace -eval "compile_simlib -simulator vcs -family all -library all -directory ./simlib_dir"
  • 运行 Vivado-VCS 联合仿真

    1
    2
    nix run '.#demo.vivado-sim-run' --impure     # 自动化:Vivado生成脚本 -> 脚本修复 -> VCS编译仿真
    nix run '.#demo.vivado-view-waves' --impure # 自动查找最新的 .fsdb 文件并启动 Verdi

3. FHS 环境交互

如果你需要手动运行 Vivado 或 Verdi 命令,可以进入特定的 FHS 环境,在 nix develop 模式下输入:

1
2
xilinx-fhs-env -c "vivado"
vcs-fhs-env -c "verdi"

3. SpinalHDL 开发流

需要在default.nix中修改是使用经典 rtl 仿真还是 spinal-rtl 仿真,其他流程与基础 rtl 仿真相同。

更新依赖

若需更新 Nixpkgs,运行:

1
nix flake update

格式化代码

本项目集成了 treefmt,支持 Nix 和 Verilog 格式化:

1
nix fmt

清理文件

通过 git clean 清理 .gitignore 中忽略的文件及目录,会删除 Xilinx 编译库目录:

1
nix build .#clean