- by 杜伟韬 中国传媒大学
- 批评指正敬请写信至 1024670978 AT QQ dot com
引言
ModelSim是我们在设计验证数字电路HDL代码时的常用工具, 硕士生CQ 同学毕业参加工作后, 反馈了来自集成电路工业界人士的宝贵建议, 认为在实验技能培养流程中应当重视脚本化的仿真流程。 工程实验课作为联系工业界和教育界的桥梁, 需要关注和重视工业界的流行趋势和意见建议, 由此决定在实验课程中添加本篇实验内容。
特此感谢CQ同学和微电子所的各位同仁, 祝愿CQ同学在工作中持续进步,取得更大的成绩。
关于脚本化仿真
当我们学习FPGA开发流程时, 最先接触的仿真流程是使用电路编译工具自带的波形仿真器。 这种方法的好处是简单直观, 容易快速上手。 但是对于复杂的电路, 会有更多的仿真需求, 比如能够设定复杂时序格式的激励数据, 或者 需要能够进行数据的自动对比分析,以及把仿真结果数据导出到文件系统使用其他的工具分析。
对于上述的复杂情况, 需要使用专门的HDL仿真器,比如 Cadence 的 Verilog-XL, Synopsys 的 VCS,以及 Mentor 的 ModelSim。
以ModelSim为例, 该工具可以支持GUI图形界面的操作, 建立仿真工程, 运行仿真, 这对于 初学者上手使用非常有利。 但是当熟悉了GUI流程之后, 我们仍需要了解基于脚本的ModelSim仿真流程, 这是因为ModelSim工具的脚本化流程:
- 可以更好的支持相对路径
- 能够更加精细的控制每一个项目文件的编译选项
- 所有的工程信息均以文本化的形式保存, 便于复制给其他的新建项目重用
关于本参考设计
本文提供了一个简单电路的脚本仿真的参考设计。 用于示范如何使用ModelSim命令行的方式来进行仿真。
目录和代码文件
- 目录 ./hdlsrc ,HDL源代码
- 文件 ./hdlsrc/dut.v ,测试平台代码,生成激励信号,例化待测模块
- 文件 ./hdlsrc/testbench.v , 待测模块,内部逻辑为加法器
- 目录 ./modelsim , ModelSim工程目录
- 文件 ./modelsim/build.do ,HDL代码编译脚本
- 文件 ./modelsim/compile.f ,HDL代码文件 列表文件
- 文件 ./modelsim/sim_quit.do, 退出仿真 脚本
- 文件 ./modelsim/sim_run.do, 运行仿真 脚本
- 上述的 "*.do" 文件, 其内部的语法格式为 TCL/TK 格式
- TCL/TK 是一种在EDA行业常用的解释型语言, 通常用来编写工具命令脚本。
编译过程
切换目录
- 启动ModelSim ,切换到 ./modelsim 目录,如下图
ModelSim切换目录
|
编译仿真文件
- 在ModelSim的命令行窗口, 键入命令 " do build.do"
- ModelSim 的命令行有自动补全功能, 不用敲完全部命令
- 命令行搜索到当前目录下存在 build.do 脚本文件会自动补全 , 如下图所示:
使用编译命令进行仿真编译
|
编译命令内容
- 编译命令 " do build.do " 的含义是, 执行当前目录下的 build.do 这个命令脚本
- 文件 build.do 内的内容为:
- vlib work ,在当前目录下创建一个叫做work的目录,在里面存放仿真数据文件
- vmap work ,把work目录下的数据文件映射为一个叫做work的仿真库
- vlog -f compile.f , 根据compile.f 的文件内容, 使用文件里的编译选项设定,把其中的Verilog文件编译为仿真执行代码
- 文件 compile.f的内容为:
- +incdir+../hdlsrc/
- ../hdlsrc/dut.v
- ../hdlsrc/testbench.v
- 其含义为, 添加包含的头文件目录 和 两个Verilog 源码文件
下图示意了 在Library 面板中, 生成的仿真库,work
编译生成仿真库
|
执行仿真
接下来, 使用命令 "do sim_run.do" , 执行当前命令下的 “sim_run.do” 脚本 ,启动仿真 由于ModelSim命令行带有补全功能, ModelSim命令行会自动搜索把 “sim”开头的命令都列出来供用户选择, 注意使用补全功能, 不用敲完全部命令, 仅键入“do sim_r” 然后 按下 Tab键, 命令行会自动补全成为 "do sim_run.do", 补全功能在脚本较多时非常使用。 如下图所示:
仿真启动命令
|
另外, ModelSim 的命令行也支持一些常用的UNIX命令和快捷键,例如
- ls :列出目录文件
- pwd:当前工作目录
- Ctrl-u : 清除当前输入行的字符
- cat 文件名: 把文本文件的内容打印到当前字符终端
查看 sim_run.do 的脚本内部, 其代码为
- vsim +nowarnTSCALE -lib work -c -novopt testbench
- 关键参数含义为
- +nowarnTSCALE 表示忽略没有timescale定义的文件,用之前的timescale替代
- -lib work 表示, 希望被仿真的库(lib)叫做work
- -c 表示从命令行启动仿真。 -novopt 表示仿真时不要优化中间变量,保持最大的信号可观测性
- testbench 是 被仿真的顶层 Verilog module 名称
仿真启动后, 如下图所示, 出现sim instance面板,以及仿真模块的层次关系和模块的信号名称:
仿真启动界面
|
在 sim instance面板, 先选择要调试的模块, 在Object面板中,选择要观察的信号,使用右键添加到WAV窗口中。 如下图:
选择信号添加波形
|
使用命令, "run -all" 运行仿真, 注意,这需要testbench代码配合, 即testbench代码中要有 $stop 系统调用,否则仿真不会停止。 详情请参考附录代码。
仿真运行完成后可以通过波形窗口观察信号仿真的波形结果, 如下图所示:
在波形窗口观察仿真信号结果
|
迭代调试
- 当发现了仿真结果错误后, 则需要重新修改代码,然后运行 “do build.do” 重新编译
- 运行 “restart” 命令 重新启动仿真
- 运行 “run -all” 命令, 执行仿真 观察结果
- 仿真完成后,使用 “quit -sim” 退出仿真
获取参考代码
本文提供的参考代码存放于以下位置
- https://github.com/DUWTLAB/Git_modelsim_script_LAB