如何在 VHDL 测试平台中停止仿真
仿真完成后如何停止 VHDL 仿真器?有几种方法可以做到这一点。在本文中,我们将研究结束成功的测试台运行的最常见方法。
这里提供的 VHDL 代码是通用的,它应该可以在任何有能力的 VHDL 模拟器中工作。对于涉及Tcl的方法,我将列出ModelSim和Vivado模拟器的命令。
如果您安装了 ModelSim,您可以从本文下载一个包含四个不同测试平台的示例项目。在下面的表格中输入您的电子邮件地址以接收 Zip 文件!
使用完成 程序
VHDL 完成 procedure 是我最喜欢的停止 VHDL 测试平台的方法,该测试平台可以无错误地完成。您必须从 STD.ENV 包中导入“完成”,并且您必须在 VHDL-2008 或更高版本中编译测试平台才能使用它。
当我们到达 testbench sequencer 进程的最后一行时,下面的代码结束了模拟。
use std.env.finish; ... SEQUENCER_PROC : process begin -- Replace this line with your testbench logic wait until stop_condition; report "Calling 'finish'"; finish; end process;
注意完成 默认退出模拟。如果您在 GUI 版本中运行 ModelSim,会出现一个弹出窗口,上面写着“您确定要完成吗?”。如果点击是,ModelSim 将退出。
这可能不是你想要的。幸运的是,我们可以通过在 vsim 命令中添加“-onfinish stop”选项来防止这种行为,如下所示。通过这样做,完成 过程的行为方式与 stop 相同 我们将在本文的下一部分讨论该过程。
vsim -onfinish stop work.using_finish_tb
使用 finish 的优势 是您可以在批处理模式下模拟时使用默认行为。如果您使用脚本启动模拟,您希望在模拟完成后将控制权返回给调用脚本。
下面的示例显示了一个使用 finish 的测试平台 程序在 Linux 中以 ModelSim 批处理模式启动。测试台完成后,模拟器退出,在最后一行,我们又回到了 Linux shell。
jonas@ubuntu:~/stop_tb$ vsim -c -do 'vsim work.using_finish_tb; run -all' Reading pref.tcl # 10.5b # vsim work.using_finish_tb # vsim work.using_finish_tb # Start time: 22:58:31 on Jun 21,2020 # Loading std.standard # Loading std.env(body) # Loading work.using_finish_tb(sim) # run -all # ** Note: Calling 'finish' # Time: 1 ms Iteration: 0 Instance: /using_finish_tb # End time: 22:58:31 on Jun 21,2020, Elapsed time: 0:00:00 # Errors: 0, Warnings: 8 jonas@ubuntu:~/stop_tb$
VHDL 完成 程序在标准 ENV 包中定义。从下面的代码中我们可以看到,它有两种重载风格。有没有任何参数的版本,这是我一直使用的版本,还有一个将状态整数作为常量输入。
procedure FINISH (STATUS: INTEGER); procedure FINISH;
你会认为当从 Linux shell 调用时状态整数会成为退出代码,但事实并非如此,至少在 ModelSim 中不是这样。使用此状态码的问题在于它的作用取决于模拟器。 VHDL-2008 标准中的措辞是“STATUS 参数的值可以由主机模拟器以实现定义的方式使用 “。
但是,您可以使用 Tcl 命令 exit -code <value>
控制 ModelSim 中的 Linux 退出代码值 ,但那是另一回事了。
使用停止 程序
VHDL 停止 过程会导致模拟暂停。如果您想手动检查信号值甚至稍后继续仿真,这可能会很有用。模拟器将其视为断点。
下面的例子展示了如何导入和使用 stop 程序。
use std.env.stop; ... SEQUENCER_PROC : process begin -- Replace this line with your testbench logic wait until stop_condition; report "Calling 'stop'"; stop; end process;
使用 stop 的问题 在基于脚本的设置中,它不会退出模拟。 ModelSim 没有将控制权返回给调用者,而是打开了一个 Tcl 命令 shell,导致调用脚本无限期挂起。
下面的清单显示了运行使用 stop 的测试台的输出 批处理模式下的过程。模拟停止后,我们仍然在 ModelSim 中。要退出 Tcl shell,我们必须输入“exit”。
jonas@ubuntu:~/stop_tb$ vsim -c -do 'vsim work.using_stop_tb; run -all' Reading pref.tcl # 10.5b # vsim work.using_stop_tb # vsim work.using_stop_tb # Start time: 22:58:56 on Jun 21,2020 # Loading std.standard # Loading std.env(body) # Loading work.using_stop_tb(sim) # run -all # ** Note: Calling 'stop' # Time: 1 ms Iteration: 0 Instance: /using_stop_tb # Break in Process SEQUENCER_PROC at ~/stop_tb/src/using_stop_tb.vhd line 23 # Stopped at ~/stop_tb/src/using_stop_tb.vhd line 23 VSIM 3>
就像完成 程序,停止 需要 VHDL-2008 或更新版本。如下所示,存在该过程的重载版本。它需要一个整数状态值,但行为因模拟器而异。
procedure STOP (STATUS: INTEGER); procedure STOP;
使用断言 关键字
停止 VHDL 测试平台的故障安全和通用方法是创建断言失败。这是我在大学学习 VHDL 时有人教我结束模拟的第一种方式。
不需要额外的导入,它适用于所有 VHDL 版本。只要确保使用严重级别 failure ,如下例所示。
SEQUENCER_PROC : process begin -- Replace this line with your testbench logic wait until stop_condition; assert false report "Test: OK" severity failure; end process;
为什么我讨厌这种停止成功模拟的方式?
首先,从上面的示例中看到打印输出看起来很奇怪和令人困惑:
# ** Failure: Test: OK
它说这是一个“失败”,但同时测试是“OK”。那是因为 assert 语句应该指示错误情况,而不是模拟成功完成。
我能想到的另一个烦人的问题是,如果模拟成功了,就很难以编程方式找出。
大多数 VHDL 专业人员在某个时间点从脚本开始模拟,例如,作为更大的回归测试方案的一部分。如果测试台在没有错误的情况下也因断言失败而停止,我们不能将其用作确定 VHDL 模块健康状况的标记。
使用 Tcl
我要介绍的最后一种停止仿真的方法是结合使用 Tcl 和 VHDL。我们没有从 VHDL 文件中停止测试台,而是在该停止时设置了一个常规的 VHDL 信号。并且在此之前,我们将模拟器配置为监听此触发信号的变化。
另请阅读:
为什么需要学习 Tcl
看下面的例子,它设置了一个名为 stop_condition 的信号 当所有测试用例都完成时。
signal stop_condition : boolean; begin -- Replace this line with your DUT instantiation stop_condition <= not stop_condition after 1 ms; SEQUENCER_PROC : process begin -- Put your testbench logic here -- Pause this process forever after all tests are done wait; end process;
您可以通过一个 wait 让任何已完成其工作的测试平台进程进入睡眠状态 结束进程之前的声明 标签。这将阻止它重新启动。实际停止模拟的 Tcl 代码在不同的模拟器之间是不同的。
在模型模拟中
我们想要的是在 stop_condition 时停止测试台 VHDL 信号变为 true .我们可以通过在运行 VHDL 测试平台之前在 Tcl 中设置回调来做到这一点。
根据 ModelSim 命令参考手册,我们可以通过使用 Tcl when 来实现 命令。在下面的 Tcl 代码中,我们注册了这样一个回调,然后我们使用 run -all 启动模拟器 .
when {stop_condition} { stop echo "Test: OK" } run -all
请注意,大括号内的代码在回调发生之前不会运行。当 VHDL 代码更改 stop_condition 向 true 发出信号 ,模拟器会暂停并执行这两行。在示例中,我们停止模拟并将“Test:OK”打印到控制台。你也可以有一个 Tcl exit 那里的命令,这将退出模拟器,就像 VHDL finish 程序。
# vsim # Start time: 22:31:11 on Jun 22,2020 # Loading std.standard # Loading work.using_tcl_tb(sim) # Test: OK # Simulation stop requested.
上面的清单显示了当 Tcl / VHDL 测试台完成时打印到 ModelSim 控制台的输出。如果您想在电脑上试用,请使用下面的表格下载包含本文所有示例的 ModelSim 项目!
在 Vivado 中
根据 Vivado Design Suite Tcl 命令参考指南,我们可以使用 add_condition 注册 Tcl 回调 命令。下面的代码显示了之前讨论的 ModelSim 版本的 Xilinx 等效代码。
set sim_fileset sim_1 launch_simulation -simset [get_filesets $sim_fileset] add_condition -notrace stop_condition { stop puts "Test: OK" } run all
-notrace switch 防止回调函数中的代码行在执行时被回显到终端。我更喜欢控制台中没有多余的杂物。
下面的清单显示了在 Vivado 模拟器控制台中运行的模拟的摘录。
launch_simulation: ... add_condition -notrace stop_condition { stop puts "Test: OK" } condition8 run all Test: OK
最后的想法
如您所见,有许多方法可以终止 VHDL 仿真。但是,我唯一使用过的是 VHDL-2008 finish 程序。
目前所有的模拟器都支持VHDL-2008,2008不需要编译RTL代码,只需要编译testbench。 完成 procedure 是最便携的方法,它允许您在 GUI 模式下运行时停止模拟器,或者在批处理模式下运行时退出。正是我大部分时间想要的行为。
但是 Tcl 方法的一些优点超出了本文的范围。当您在 Tcl 回调中暂停了模拟器时,您可以做的不仅仅是停止模拟器并退出。您可以在回调中检查 VHDL 信号,甚至使用 Tcl 操作它们。那是使用 Tcl 进行验证。
VHDL