在使用questasim或者modelsim仿真时,如果需要控制仿真时间长度,一般在vsim中使用 run xxxxms/us等命令。
但是有时候不好估计仿真多长时间才能得到所有希望观察的结果,这个时候可以在仿真tb文件中合适的位置加入-finish命令。不过仿真运行到这个位置时sim程序会提示退出,所以如果需要观察波形的话一般不使用这个命令。
下面还有一张方式可以控制questasim仿真时间:通过添加断点。
添加断点可以在vsim脚本中添加when { condition } { stop }命令行,例如
when -label 1 { tb/assertion_flag = 0 } { #设置断点条件 echo "assertion fail at @ [expr $now/1000] ns\n"; #设置断点处行为 stop; #停止仿真 }
上述代码是在仿真过程中检测断言的正确性,如果断言失败,则返回错误信息并停止仿真过程。
在vsim中添加的命令行遵循tcl脚本的语法,例如
[expr $now/1000]
这一句即是tcl脚本语言中的表达式替换操作,将当前时间ps换算为ns表示。
vsim中对断点的说明:
使用when可以添加断点(带上id号),而nowhen可以去掉指定label或id(两者实际一样)的breakpoint,或者全部的breakpoint。所以在使用when的时候,一般带上-id或者-label制定breakpoint的标记号,方便nowhen来随时取消。
扩展一下,为提高仿真自动化程度,可以,然后再新建一个script.do中加入各种questasim命令,如下所示:
1 #添加要观察的波形 2 add wave -noupdate /tb/U_TOP/U_PUMP_CTRL1/pump_photos_back_prim 3 add wave -noupdate /tb/U_TOP/U_PUMP_CTRL1/pump_photos_front_main 4 add wave -noupdate /tb/U_TOP/U_PUMP_CTRL1/pump_photos_front_prim 5 #设置breakpoint控制仿真长度 6 when -label 1 { tb/U_TOP/U_ACTIVE_VALVE1/valve_pwm = 1 } { nowhen 1; echo "bp1 reached at @ [expr $now/1000] ns\n" } ;#遇到此breakpoint时去掉此breakpoint,然后打印此时的时间(tcl语法),vsim中时间函数为$now,而不是$time 7 when -label 2 { tb/U_TOP/U_ACTIVE_VALVE1/active_valve_start_stage1 = 1 } { nowhen 2;echo "bp2 reached at @ [expr $now/1000] ns\n" } 8 when -label 3 { tb/U_TOP/U_ACTIVE_VALVE1/active_valve_stop = 1 } { echo "stop\n";stop } 9 #启动仿真 10 run -all 或者 run xxx ms/us
(在上述代码中只使用了when label **,因为之前尝试过when id**,好像没有作用。)
在仿真的simulate.bat中的vsim命令加入参数-do script.do
1 vlib work 2 3 gcc -c -ID:\questa_sim_10.1b\include -I ../sim/ -I. ../sim/wave.c ::调用DPI接口,使用GCC编译器编译使用的C语言文件 4 gcc -shared -Bsymbolic -o wave.dll wave.o -LD:\questa_sim_10.1b\win32 -lmtipli 5 vlog ../ip/emi/ddr/testbench/*.v -work work ::可以使用"*.v"来包含所有.v文件,避免一个一个手动输入文件名 6 vlog ../ip/emi/ddr/*.vo -work work 7 vlog -timescale "1ns/10ps" -sv -f s.f -work work 8 9 vsim -L work -L altera_libs -novopt -sv_lib wave work.tb -do script.do ::调用script.do来执行代码