Skip to main content

Verilua xmake.lua 编写指南

Verilua 的 HVL(硬件验证语言)和 WAL(波形分析语言)工程使用 xmake 作为构建系统。每个验证项目都必须包含一个 xmake.lua 文件,用于定义目标、源文件、仿真后端和运行时配置。

重要说明:在 HVL 模式下,Verilua 会自动为您生成一个 testbench(默认名为 tb_top.sv),该 testbench 会例化您的顶层设计、提供时钟和复位生成、导出 DPI 接口等。您通常不需要手动编写 testbench。在 WAL 模式下,无需生成 testbench。


1. 基本结构

HVL 模式(硬件验证)

target("my_test", function()
add_rules("verilua")
add_toolchains("@verilator") -- 仿真后端
add_files("src/design.v") -- RTL 文件
set_values("verilua.top", "Design") -- DUT 顶层模块名
set_values("verilua.lua_main", "src/main.lua") -- Lua 入口脚本
end)

WAL 模式(波形分析)

target("wave_analysis", function()
add_rules("verilua")
add_toolchains("@wave_vpi") -- 波形分析后端
add_files("path/to/waveform.vcd") -- 波形文件
set_values("verilua.top", "tb_top") -- 波形文件中的顶层模块名;若由 Verilua HVL 生成,常见为 tb_top
set_values("verilua.lua_main", "analyze.lua")
end)
  • target("..."):定义一个构建目标,名称可任意。

  • add_rules("verilua")必须,引入 Verilua 的构建规则。

  • add_toolchains("@..."):指定后端,HVL 常用 @verilator@iverilog@vcs@xcelium;WAL 必须使用 @wave_vpi

  • add_files(...):HVL 中通常添加 RTL 文件,以及需要参与工程管理的 Lua/C/C++ 文件;WAL 中添加波形文件和需要复用的 Lua 模块。verilua.lua_main 指向的 Lua 入口脚本不需要额外放进 add_files(...)。WAL 模式支持 .vcd.fst.fsdb 三种波形格式,且只能添加一个波形文件,添加多个会报错。

    add_files 支持 xmake 的通配符(glob)写法,例如 add_files("rtl/*.sv")add_files("src/**/*.v"),便于批量添加同一目录或多个子目录下的源文件。

    路径拼接建议:在 xmake.lua 中如果需要拼接路径,建议使用 xmake 内置的 path.join(...) 而非手动字符串拼接(如 "dir/" .. file)。path.join 会自动处理跨平台的路径分隔符差异:

    add_files(path.join("src", "design.v"))
    set_values("verilua.lua_main", path.join("tb", "main.lua"))
  • set_values("verilua.top", "...")必须

    • HVL 中填写 DUT 顶层模块名,Verilua 会据此生成 testbench。
    • WAL 中填写波形文件中的顶层模块名;如果波形由 Verilua HVL 生成,通常是 tb_top
  • set_values("verilua.lua_main", "...")必须,Lua 入口脚本。


2. 必要参数

参数HVL 说明WAL 说明
add_rules("verilua")必须必须
add_toolchains("@...")指定仿真器必须为 @wave_vpi
set_values("verilua.top", "...")DUT 顶层模块名波形顶层模块名
set_values("verilua.lua_main", "...")Lua 主脚本Lua 主脚本
add_files(...)RTL + 可选 Lua/C/C++1 个波形文件 + 可选 Lua

3. 常用可选参数

3.1 通用配置

参数类型默认值说明
set_values("verilua.user_cfg", "<file>")string-指定用户自定义 Lua 配置文件;其返回表的字段会合并到运行期全局 cfg
set_values("verilua.build_dir_name", "<name>")stringverilua.top构建目录名称(位于 build/<sim>/ 下)
set_values("verilua.build_dir_path", "<path>")stringbuild/<sim>构建目录的父路径

3.2 仿真器专用标志

参数说明示例
add_values("verilator.flags", ...)Verilator 编译选项(HVL)add_values("verilator.flags", "--trace")
add_values("iverilog.flags", ...)Icarus 编译选项(HVL)add_values("iverilog.flags", "-g2012")
add_values("vcs.flags", ...)VCS 编译选项(HVL)add_values("vcs.flags", "-full64")
add_values("xcelium.flags", ...)Xcelium 编译选项(HVL)add_values("xcelium.flags", "-64bit")
add_values("verilator.run_flags", ...)Verilator 运行时参数add_values("verilator.run_flags", "+verilator+coverage")
set_values("verilator.run_prefix", ...)Verilator 运行时前缀(如 gdb --argsset_values("verilator.run_prefix", "gdb --args")
add_values("wave_vpi.run_flags", ...)wave_vpi 运行时参数(WAL)add_values("wave_vpi.run_flags", "--dump-journal")
set_values("wave_vpi.run_prefix", ...)wave_vpi 运行时前缀(WAL)set_values("wave_vpi.run_prefix", "gdb --args")

add_values vs set_values*.flags*.run_flags 系列参数请使用 add_values,它会追加到已有值;set_values 会覆盖,多次调用只保留最后一次的结果。*.run_prefix 是单值参数,用 set_values 即可。其他仿真器也有对应的 .run_flags.run_prefix。其中 .flags 主要用于 HVL 编译阶段,wave_vpi 没有单独的编译阶段,但支持自己的运行参数。

3.3 testbench 相关参数(HVL)

如果使用 Verilua 自动生成 testbench,除了 verilua.tb_gen_flags 之外,还可以直接控制 testbench 顶层名或切换到自定义 testbench:

参数说明示例
set_values("verilua.tb_top", "...")指定生成的 testbench 顶层模块名,默认是 tb_topset_values("verilua.tb_top", "my_tb")
set_values("verilua.tb_top_file", "...")使用自定义 testbench 文件替代自动生成的 testbenchset_values("verilua.tb_top_file", "tb/my_tb_top.sv")
set_values("verilua.not_gen_tb", "1")禁止自动生成 testbenchset_values("verilua.not_gen_tb", "1")

其中最常见的情况仍然是不改 verilua.tb_top,直接通过 verilua.tb_gen_flagstestbench_gen 传少量附加参数:

set_values("verilua.tb_gen_flags", "--clock-signal", "clk", "--period", "10")
-- 或追加
add_values("verilua.tb_gen_flags", "--verbose")

这里需要区分两个名字:

  • verilua.top:DUT 顶层模块名。
  • verilua.tb_top:生成的 testbench 顶层模块名,默认是 tb_top

更多 testbench_gen 参数请参考 testbench_gen 命令行参数


4. 构建与运行命令

在包含 xmake.lua 的目录下执行:

# 构建目标
xmake build -P . my_test

# 运行仿真(或波形分析)
xmake run -P . my_test

# 清理构建产物
xmake clean -P . my_test

-P . 指定当前目录为项目根目录,若已在项目根目录可省略。


5. 完整示例

5.1 HVL 基础示例(Verilator + 波形)

target("counter_test", function()
add_rules("verilua")
add_toolchains("@verilator")
add_files("src/Counter.v")
set_values("verilua.top", "Counter")
set_values("verilua.lua_main", "src/main.lua")
add_values("verilator.flags", "--trace", "--no-trace-top")
end)

5.2 HVL 多仿真器支持(通过环境变量选择)

target("multi_sim", function()
add_rules("verilua")
on_config(function(target)
local sim = os.getenv("SIM") or "verilator"
if sim == "iverilog" then
target:set("toolchains", "@iverilog")
elseif sim == "vcs" then
target:set("toolchains", "@vcs")
elseif sim == "xcelium" then
target:set("toolchains", "@xcelium")
elseif sim == "verilator" then
target:set("toolchains", "@verilator")
else
raise("unknown simulator: %s", sim)
end
end)
add_files("rtl/*.sv")
set_values("verilua.top", "Top")
set_values("verilua.lua_main", "tb/main.lua")
add_values("verilator.flags", "--trace")
end)

使用方式示例:

# 默认使用 verilator
xmake run -P . multi_sim

# 使用 iverilog
SIM=iverilog xmake run -P . multi_sim

# 使用 vcs
SIM=vcs xmake run -P . multi_sim

# 使用 xcelium
SIM=xcelium xmake run -P . multi_sim

如果您希望先单独构建,再运行,也可以这样写:

SIM=vcs xmake build -P . multi_sim
SIM=vcs xmake run -P . multi_sim

上面的 xmake.lua 会在配置阶段读取 SIM 环境变量,并自动切换到对应的 toolchain。如果没有设置 SIM,则默认使用 verilator;如果设置成了不支持的值,则会直接报错,避免静默回退到错误的后端。

5.3 WAL 波形分析示例

target("wave_analysis", function()
add_rules("verilua")
add_toolchains("@wave_vpi")
add_files("path/to/waveform.vcd")
set_values("verilua.top", "tb_top")
set_values("verilua.lua_main", "analyze.lua")
end)

其中 path/to/waveform.vcd 只是占位写法,实际使用时既可以写绝对路径,也可以写相对于 xmake.lua 的路径。支持的波形格式为 .vcd.fst.fsdb,每个 target 只能指定一个波形文件。

verilua.top 也不是固定必须写成 tb_top。如果波形是通过 Verilua 的 HVL 流程生成的,那么顶层通常是 tb_top;如果波形来自其他流程,则应填写该波形文件中的实际顶层模块名(例如 topDesign 等)。最直接的判断方法是用波形查看器打开文件,确认最外层层次名称。


6. 其他场景

这篇指南主要覆盖常用写法。对于一些低频或进阶场景,建议直接查 reference 文档:

6.1 添加 C/C++ 源文件(HVL)

对于需要 DPI-C 或 VPI 扩展的项目,可直接添加 C/C++ 文件:

add_files("src/dpi_funcs.cpp")

Verilua 会将这些文件交给对应后端参与构建。某些仿真器或特定场景下,您可能还需要补充额外的链接标志或仿真器参数;如果遇到这类情况,建议参考仓库中的实际示例(如 tests/test_dpic/xmake.lua)。


7. 常见问题

Q1:编译时报错 unknown toolchain A:请确保 add_toolchains 中使用了正确的名称(@verilator, @iverilog, @vcs, @xcelium, @wave_vpi),且对应工具已安装在 PATH 中。

Q2:波形文件未生成(HVL) A:检查 verilator.flags 是否包含 --trace--trace-fst,并在 Lua 中调用了 sim.dump_wave()

Q3:WAL 模式下找不到波形文件 A:add_files 中添加的波形文件路径必须是绝对路径或相对于 xmake.lua 的路径。确保文件存在。

Q4:Lua 脚本修改后是否需要重新编译? A:通常不需要。Lua 是解释执行的语言,修改 main.lua 或其他参与运行的 Lua 文件后,直接重新运行仿真即可。

例如,第一次先构建并运行:

xmake build -P . my_test
xmake run -P . my_test

之后如果您只修改了 Lua 脚本(例如 main.lua 或它 require 的其他 Lua 文件),通常只需要再次运行:

xmake run -P . my_test

只有在您修改了 RTL、C/C++ 文件,或变更了 xmake.lua 中的构建配置时,才通常需要重新构建。

Q5:WAL 模式下是否生成 testbench? A:不生成。WAL 模式直接读取波形文件,无需 RTL 仿真。


8. 相关文档