在这里插入图片描述

Verilating

… 威尔逊-斯奈德版权所有 2003-2023。
… SPDX 许可证标识符: 仅限 LGPL-3.0 或 Artistic-2.0


验证


Verilator 可通过五种主要方式使用:

  • 使用 --cc 或 :vlopt:-sc 选项,Verilator 将分别把设计翻译成 C++ 或 SystemC 代码。 将设计分别翻译成 C++ 或 SystemC 代码。 参见 :ref:C++ 和 SystemC 生成

  • 使用 --lint-only 选项时,Verilator 将对设计进行校验以检查是否有警告,但通常不会对设计进行校验。检查警告,但通常不会创建任何输出文件。

  • 使用--xml-only 选项时,Verilator 将创建 XML 输出文件。输出,这些输出可用于其他用户设计的工具。 参见发行版中的 docs/xml.rst

  • 使用-E 选项时,Verilator 将根据 IEEE 预处理规则对代码进行预处理。预处理规则对代码进行预处理,并将输出写入标准输出。这对于向其他工具提供信息和调试"`define "语句如何展开非常有用。

C++ 和 SystemC 生成

Verilator 会使用
选项将 SystemVerilog 设计翻译为 C++,或使用 :vlopt:-cc 选项将其翻译为 SystemC。

使用这些选项时

  1. Verilator 会读取输入的 Verilog 代码并确定所有 “顶级模块”,即未在其他单元下作为实例使用的模块或程序。如果使用 --top-module,则会确定顶层模块,并移除所有其他顶层模块。则会删除所有其他顶层模块;否则会发出MULTITOP 警告。

  2. Verilator 会将 C++/SystemC 代码写入输出文件的--Mdir 选项指定的目录,默认为 “obj_dir”。前缀是用--prefix 设置的,或者默认为顶层模块的名称。顶部模块的名称。

  3. 如果使用 --exe,Verilator 会创建 makefile 以生成仿真可执行文件。 模拟可执行文件,否则会创建 makefile 以生成一个存档 (.a) 包含对象。

  4. 如果使用了 --build 选项,则会调用GNU Make CMake 来构建模型。

建好模型后,通常会运行它,参见 模拟

分层校验

大型设计可能需要很长时间(如 10 多分钟)和大量内存(如 100 多 GB)来进行验证。 在分层模式下,用户手动选择一些大的在分层模式下,用户手动选择一些大型低层结构块,将其从大型设计中分离出来。例如,一个内核可能是从一个多内核SoC 设计中分离出来的层次块。
Verilator 以分层模式在整个 SoC 上运行。 Verilator 将创建两个模型,一个用于 CPU 层次块,另一个用于 SoC。 SoC 的 Verilated 代码将自动调用 CPU Verilated 模型。
当前的分层校验基于 :vlopt:--lib-create。每个分层模块都会被校验到一个库中。分层模块的用户模块的用户模块将看到一个由 :vlopt:--lib-create 生成的小封装器。

使用方法

用户需要将一个或多个中等大小的模块标记为层次结构块。
标记一个模块有两种方法:

  • 在 HDL 代码中写入 /*verilator&32;hier_block*/ 元注释。

  • Configuration Files 中添加 hier_block 行。

然后向 Verilator 传递 --hierarchical 选项。

编译过程与不使用分层模式时相同。

make -C obj_dir -f Vtop_module_name.mk

限制条件

层次结构块有一些限制,包括

  • 层次结构块不能使用点(.)模块或其他层次结构块。

  • 无法跟踪模块中的信号。

  • 无法在层次块边界使用 Modport。

  • 仿真速度可能不如平面编译快。所有模块都是全局调度。

  • 如果在分层模型中生成时钟,并将其传递到另一个分层模型中,生成的时钟可能无法正常工作。生成的时钟如果在分层模型中生成并传入另一个分层模型或顶层模块,可能无法正常工作。

  • 分层模块中不允许延迟。

但支持以下用法:

  • 嵌套层次结构块。一个层次结构模块可以实例化其他层次结构模块。
    层次结构块可以实例化其他层次结构块。

  • 参数化层次结构块。层次结构块的参数可通过
    使用 #(.param_name(value)) 结构重载。

重叠编译和编译

在分层编译中,Verilator 需要运行 2 + N 次,其中 N 是分层块的数量。是层次结构块的数量。其中一次用于顶层模块、是指所有其他层次结构模块的封装器。 第二个是初始运行,搜索标记为/*verilator&32;hier_block*/ 元注释标记的模块,并创建一个计划和写入 {prefix}_hier.mk。 初始运行会在内部调用其他 N + 1 次运行,因此您不必关心这些 N + 1 次的运行。额外的 N 是每个层次块的 Verilator 运行次数。

如果-j {jobs} <-j>选项,则 Verilation 如果-j {jobs} <-j>选项,分级块的校验将并行运行。块的编译会并行运行。如果指定了 --build 选项,C++ 编译也会在分级块校验完成后立即运行。分层代码块进行校验。C++ 编译和其他同时运行。

交叉编译

Verilator 支持交叉编译 Verilated 代码。 这通常用于在 Linux 系统上运行 Verilator,生成 C++ 代码,然后在 Windows 系统上编译。在 Windows 上编译。

交叉编译最多涉及三个不同的操作系统。 编译系统是构建系统是配置和编译 Verilator 的地方,主机系统是运行目标系统则是编译 Verilator 代码并运行模拟的地方。和运行模拟的地方。

Verilator 要求构建系统和主机系统的类型必须相同。相同,但目标系统类型可能不同。 为支持这一点./configure 并在构建系统上制作 Verilator。 然后,在主机系统上运行在主机系统上运行 Verilator。 最后,Verilator 的输出可能会在不同的目标系统上编译。在不同的目标系统上编译。

为了支持这一点,Verilator 生成的所有文件都不会引用任何 configure 生成的特定于构建系统的文件,例如config.h(Verilator 将其更名为 config_package.h以减少混淆)。 这种方法的缺点是include/verilatedos.h必须自行检测目标系统的要求,而不是使用configure。而不是使用 configure。

目标系统可能还需要编辑 Makefile,而 Verilator 生成的简单
Verilator 生成的简单 Makefile 假定目标系统与编译系统是同一类型。

多线程

Verilator 支持多线程仿真模型。

使用 --threads 1 ,生成的模型是单线程的。但支持库是多线程安全的。这允许模型的不同实例在不同线程下运行。在不同的线程下运行。所有线程都由用户的C++ 测试平台负责。

使用 --threads {N} (其中 N 至少为 2),生成的模型将被设计为在不同的线程下运行。生成的模型将被设计为在 N 个线程上并行运行。调用 eval() 的线程将提供其中一个线程,而生成的模型将创建并管理其他 N-1 个线程。客户端不超量分配可用的 CPU 内核是客户的责任。在 CPU超量订阅的情况下,验证模型不会出现活锁或死锁;但是,性能会比线程和 CPU 内核比例适当时差很多。然而,你可以预期性能会比线程和 CPU 内核比例适当时差很多。

用于构建模型的线程必须与调用代码:eval()的线程;这被称为 “eval 线程”。用于执行某些全局操作(如必须由 "主线程 "完成。在大多数情况下,评估线程和主线程是同一个线程(即用户的顶级 C++ 测试平台运行在单个但这并不是必须的。

在多线程模型中频繁使用 DPI 导入函数时,可能对性能有好处。模型中频繁使用 DPI 导入函数时,调整--instr-count-dpi 选项。这的假定执行时间,从而影响模型的分区。DPI 导入的假定执行时间。
当使用 --trace 来执行 VCD 跟踪时,VCD 跟踪的构建会使用相同的数来并行化。将使用--trace 时指定的线程数相同的线程并行构建 VCD 跟踪。使用--threads 指定的线程数并行地构建 VCD 跟踪,并在与模型相同的线程池上执行。--trace-threads 选项可以与 :vlopt:--trace-fst 一起使用以卸载使用多个线程的 FST 跟踪。如果在给出--trace-threads 选项的同时没有给出-trace-fst。则--trace-threads 将意味着--threads 1 ,即支持库将是线程安全的。
使用--trace-threads 0 ,跟踪转储将在主线程上产生。
将在主线程上生成跟踪转储。这将再次提供最高的单线程性能。
如果使用 --trace-threads {N} ,其中 N 至少为 1、将创建多达 N 个额外线程,并由跟踪文件管理(例如 VerilatedFstC)创建和管理多达 N 个额外线程,以卸载跟踪转储的构造。主线程线程将被释放,以尽快继续执行,但在执行过程中仍需要阻塞一些主线程。在捕获跟踪数据时,仍需要阻塞一些主线程。跟踪。FST 跟踪最多可使用 2 个卸载线程,因此不需要因此目前没有必要将 --trace-threads 设置为高于 2。

在运行多线程模型时,默认的 Linux 任务调度器通常会假定线程寿命很短,从而与模型背道而驰。它经常在同一物理内核中使用多个超线程来调度线程。物理内核内使用多个超线程调度线程。为获得最佳性能,请使用 numactl 程序来(当线程数符合要求时)在同一插座上选择唯一的物理内核。插座上选择唯一的物理内核。这同样适用于 :vlopt:-trace-threads

举例来说,如果使用--threads 4 ,我们会查阅

egrep 'processor|physical id|core id' /proc/cpuinfo

为了选择位于同一插槽(0)但具有不同物理核心的核心 0、1、2 和 3,可以执行以下操作(也可以使用 numactl --hardware 或 lscpu,但它们不显示超线程核心)。接着执行:

numactl -m 0 -C 0,1,2,3 -- verilated_executable_name

这将限制内存使用于插槽 0,并将线程限制于核心 0、1、2、3(假定在插槽 0 上),以优化性能。当然,如果你希望另一个模拟器使用,例如插槽 1,或者如果你使用不同数量的线程进行 Verilated 模拟,就需要调整这些设置。要查看实际使用的 CPU,可以使用 --prof-exec 参数。

多线程 Verilog 和库支持

$display/$stop/$finish 被延迟到 eval() 调用的末尾,以保持线程之间的顺序。这可能导致在 $stop 或 $finish 之后完成额外的任务。

如果使用 --coverage,覆盖例程是完全线程安全的。

如果使用 DPI,Verilator 假定纯 DPI 导入是线程安全的,平衡性能与安全性。参见 --threads-dpi。

如果使用 --savable,保存/恢复类不是多线程的,只能由 eval 线程调用。

如果使用 --sc,SystemC 内核不是线程安全的;因此,eval 线程和主线程必须相同。

如果使用 --trace,跟踪类必须在主线程中构造和调用。

如果使用 --vpi,由于 SystemVerilog VPI 没有被 IEEE 架构为多线程,Verilator 要求所有 VPI 调用只能从主线程进行。

GNU Make
Verilator 默认创建模型的 GNU Make makefile。当使用’–build’ 选项时,Verilator 将自动调用 make。

如果从 makefile 中调用 Verilator,’-MMD’ 选项将创建一个依赖文件,允许 Make 仅在输入 Verilog 文件更改时运行 Verilator。

CMake

Verilator 可以使用 CMake 运行,它负责运行 Verilator 并编译输出。在 examples/ 目录中有一个 CMake 示例。以下是一个构建示例 C++ 执行代码的最小 CMakeLists.txt。

project(cmake_example)
find_package(verilator HINTS $ENV{VERILATOR_ROOT})
add_executable(Vour sim_main.cpp)
verilate(Vour SOURCES our.v)

find_package 将自动查找已安装的 Verilator 副本,或者如果设置了 VERILATOR_ROOT,将使用本地构建。

推荐使用 CMake >= 3.12 和 Ninja 生成器,尽管其他组合也应该可以工作。要使用 CMake 进行构建,请切换到包含 CMakeLists.txt 的文件夹并运行:

mkdir build
cd build
cmake -GNinja ..
ninja

或者要使用系统默认生成器进行构建:

mkdir build
cd build
cmake ..
cmake --build .

如果正在构建示例,应该会有一个可执行文件可供运行:

./Vour

该包设置 CMake 变量 verilator_FOUND、VERILATOR_ROOT 和 VERILATOR_BIN 为适当的值,并创建一个 verilate() 函数。verilate() 将自动创建自定义命令以运行 Verilator,并将生成的 C++ 源代码添加到指定的目标中。

在 CMake 中进行 Verilate

verilate(target SOURCES source ... [TOP_MODULE top] [PREFIX name]
         [TRACE] [TRACE_FST] [SYSTEMC] [COVERAGE]
         [INCLUDE_DIRS dir ...] [OPT_SLOW ...] [OPT_FAST ...]
         [OPT_GLOBAL ..] [DIRECTORY dir] [THREADS num]
         [TRACE_THREADS num] [VERILATOR_ARGS ...])

小写和 … 应该被替换为参数;大写部分界定了参数,可以按任何顺序传递或者在可选时完全省略。

verilate(target …) 可以被多次调用,以将其他 Verilog 模块添加到可执行文件或库目标中。

在生成 Verilated SystemC 源代码时,应列出 SystemC 的包含目录并链接到 SystemC 库。

  • target
    由 add_executable 或 add_library 创建的目标的名称。

  • COVERAGE
    可选。如果存在,启用覆盖,等同于 “VERILATOR_ARGS –coverage”。

  • DIRECTORY
    可选。设置 Verilator 输出目录。最好使用默认值,以避免与其他文件发生冲突。

  • INCLUDE_DIRS
    可选。设置 Verilator 搜索的目录(与 -y 相同)。

  • OPT_SLOW
    可选。为慢路径设置编译器选项。您可能希望减少优化级别以提高对大型设计的编译时间。

  • OPT_FAST
    可选。为快速路径设置编译器选项。

  • OPT_GLOBAL
    可选。为 Verilated 模型使用的公共运行时库设置编译器选项。

  • PREFIX
    可选。设置 Verilator 输出前缀。默认为第一个源文件的名称前加上 “V”。在每次调用 verilate() 时必须是唯一的,因此如果使用不同参数多次构建模块,则有必要使用它。必须是有效的 C++ 标识符,即不包含空格,只包含字符 A-Z、a-z、0-9 或 _。

  • SOURCES
    Verilate 的 Verilog 文件列表。必须提供至少一个文件。

  • SYSTEMC
    可选。启用 SystemC 模式,默认为 C++(如果未指定)。

使用 CMake 支持的 Accellera 的 SystemC 时,CMake 目标可用于简化 SystemC 步骤。只有在 CMake 能够找到 SystemC 安装时才会起作用,可以通过在 CMake 配置期间设置 CMAKE_PREFIX_PATH 变量进行配置。

不要忘记为 Verilated 源代码设置与 SystemC 库相同的 C++ 标准。这可以使用 SYSTEMC_CXX_FLAGS 环境变量指定。

  • THREADS
    可选。启用多线程模型;参见 --threads。

  • TRACE_THREADS
    可选。启用多线程 FST 跟踪;参见 --trace-threads。

  • TOP_MODULE
    可选。设置顶层模块的名称。默认为 SOURCES 数组中第一个文件的名称。

  • TRACE
    可选。如果存在,启用 VCD 跟踪,等同于 “VERILATOR_ARGS –trace”。

  • TRACE_FST
    可选。如果存在,启用 FST 跟踪,等同于 “VER

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐