Modelsim的版本比较多,一般是用功能最全的SE版,不建议用AE/ASE/XE等其它版本。
其中,AE/ASE是集成了Altera库的版本(仿真quartus的IP核,会轻松很多),XE是集成了Xilinx库的版本(仿真ISE的IP核,会轻松很多)。
QuestaSim其实就是Modelsim的扩展版,增加了System Verilog仿真的功能,除此之外,几乎没区别。这里以QuestaSim为例,介绍如何使用testbench来仿真HDL代码。
这里,不建议使用quartus或者ISE直接调用QuestaSim(问题多多),而是在QuestaSim下新建工程。
1、准备好HDL和testbench文件。
因为QuestaSim不支持原理图输入方式,所以,如果你的工程有原理图的话,一定要先转成HDL(在本博客的《彻底掌握Quartus》有介绍)。
然后,在Assignments->Settings。
设置好仿真工具,这里选Modelsim就可以了。
在Processing->Start->开始生成testbench模板。
细心的读者会看到上图写着Template,没错,就是模板,具体的激励还是得自己写的,别以为生成了tb文件就完事。
如果成功生成模板的话,会有如下字样显示。
在工程目录下,simulation\modelsim文件夹里,可以找到这个tb文件。
再把HDL文件和tb文件都拷贝在一个文件夹里面,如下图所示。
2、仿真。
新建工程。
填好工程名和工程目录。
添加已存在的文件(就刚才准备好的HDL文件和tb文件)。
这里Reference from current location是引用文件路径,而Copy to project directory是拷贝到工程目录,这里选择引用就可以了,因为上一步已经拷贝好了。
修改一下自动生成的testbench模板,让它能产生正确的激励。
如果HDL文件里面,用到reg型变量,就必须全部对它们赋初值。当然,这个初值是仿真时用的,不影响综合出来的电路。
随便右击一个文件,点击编译全部。
成功的话,会出现如下字样。如有错误,就要改到正确为止。
接下来,依次输入三条指令,如下图所示。(这里的命令,都可以点鼠标完成,但是建议大家用命令)
结果出来了,是个非冗余开方,用的是改进的不恢复余数算法。其中,D是被开方数,Q是商,R是余数。
开方的原理跟除法差不多,都是先上商,然后再逼进实际值。
这个算法是向左逼进,如果要算63的开平方,得到的是7,误差有点大。其中,迭代的次数越多,计算的结果越精确(余数的位数越长)。
sqrt(36)=6,结果正确。
sqrt(129)=11,结果正确(取整之后的结果)。
3、DO文件。
DO文件就是把刚才仿真时用的命令,打包成一个文件。比如,把刚才vsim,add wave,run三条命令,合成一条命令,大大简化操作。
同时DO文件支持TCL脚本,可以实现自动化仿真,比点鼠标要高效很多。
首先,新建一个DO文件。
把刚才的命令写上,这里用了set命令,把文件名改成变量,方便后面使用。保存DO文件的时候,记得要写.do后缀。
在控制台下面,用do dosim.do可以调用刚才那几条命令。
仿真的结果,跟刚才是一样的。
DO文件(force,clock等命令),同样可以实现testbench的功能,这个,看大家喜欢哪个就用哪个了。
更具体的DO文件,可以参考本博客的《Modelsim/QuestaSim教程——DO文件篇》。
4、其它问题。
a、为什么不能仿真quartus或者ISE自带的IP核?
某些IP是以.v或者.vhd文件的形式保存,如:quartus、diamond,用的时候,添加这些.v或者.vhd文件即可。
某些自带的IP核,一般不以HDL文件的形式保存,而是封装成库文件/网表文件(目的就是要收费和保护知识产权,同时还可以在底层做优化)。
用modelsim的SE版仿真这些IP的时候,需要添加库。而ASE/AE无需添加altera的库,XE就无需添加xilinx的库。但是ASE/AE/XE的仿真速度比SE要慢。
b、明明修改了tb/HDL文件,但是每次仿真的结果都一样?
修改了tb/HDL,就要重新编译,重新运行仿真。
c、testbench是否等同于验证?
不等同。testbench只是产生激励信号而已,一般不是用它来做验证。
验证需要验证的语言,如:system verilog、system C、openVera,目前用得比较多的是system verilog。
d、为什么不建议用quartus自带的qsim画波形来仿真?
用鼠标画波形当然简单,易学。但是复杂一点就不好操作了,而且画好的波形也不便于重复使用。
此外,qsim的仿真速度要比modelsim慢很多很多。
所以,还是建议用testbench+modelsim的方法来仿真,这是一劳永逸的方法。
e、为什么在wave窗口里看不到任何波形?
首先要编译代码,代码没问题的话,再用add wave *添加波形,最后再仿真,run一段时间才有波形。