如何在ModelSim中编写等价于VHDL‘wait until’的TCL脚本
VHDL仿真TCL脚本实现高效等待信号条件的方案
问题背景
我正在为VHDL仿真编写TCL脚本作为封装层,想要实现如下VHDL伪代码的等价功能:
Data <= SomeData; wait until (strobe = '1'); Data <= NewData;
我尝试通过编写TCL循环来检查strobe信号的值,但这种方式效率极低。另外我认为when语句也无法解决问题,请问有什么可行的解决方案?
以下是我编写的低效实现:
proc wait_until {sig val} { for {set i 0} {$i < 50} {incr i} { set dummy [examine -radix unsigned $sig] if {$dummy eq $val} { break } run 10 ns } }
调用方式:
wait_until strobe 1
高效解决方案
主流VHDL仿真器(如ModelSim/QuestaSim)都提供事件驱动的等待机制,完全不需要低效的轮询检查,以下是几种可行方案:
方案1:信号变化触发检查
改写wait_until过程,仅在目标信号发生变化时才检查值,避免固定步长空跑:
proc wait_until {sig val} { # 先检查当前值,避免不必要等待 if {[examine -radix unsigned $sig] eq $val} { return } # 循环等待信号变化并检查值 while {1} { wait on $sig if {[examine -radix unsigned $sig] eq $val} { break } } }
该版本仅在strobe信号更新时执行检查,效率远高于原轮询方案。
方案2:直接使用仿真器内置条件等待
部分仿真器支持简洁的条件等待语法,比如ModelSim可直接执行:
wait until {[examine strobe] == 1}
无需封装过程,直接用这条命令替代循环,完全规避轮询。
方案3:事件绑定触发动作(when命令)
利用when命令绑定信号满足条件时的动作,完全基于事件驱动,无需主动等待:
# 设置初始值 examine Data -value SomeData # 绑定strobe为1时的动作 when {[examine strobe] == 1} { examine Data -value NewData # 解除绑定防止重复触发 when -cancel [current when] } # 启动仿真直到事件触发 run -all
这是效率最高的实现方式之一,仅在目标事件发生时执行操作。
可选:添加超时机制
为避免无限等待,可给wait_until过程添加超时判断:
proc wait_until {sig val timeout_ns} { set start_time [current_time -ns] # 初始检查 if {[examine -radix unsigned $sig] eq $val} { return 1 } while {1} { wait on $sig if {[examine -radix unsigned $sig] eq $val} { return 1 } # 检查是否超时 set current_time [current_time -ns] if {($current_time - $start_time) >= $timeout_ns} { puts "Error: Wait timed out for $sig to reach $val" return 0 } } }
调用示例:wait_until strobe 1 500(超时时间500ns)
内容的提问来源于stack exchange,提问作者nsrdn
相关产品推荐
相关产品推荐

