ModelSim仿真入门 (二)功能仿真

【时间:2013 年 11 月 16 日, 来源:本站原创, 作者:】

骏龙科技 程旭

 

本实验的目的就是在ModelSim环境下学习掌握该软件的一般仿真测试流程和仿真测试方法,另外学习编写简单的Test Bench程序并在ModelSim下进行调试。

实验步骤如下:

1.       打开ModelSim软件,如图1所示:

1 打开软件

2. 软件的启动画面如图2所示,进入界面后如图3所示:

2 软件的启动画面

3 软件进入后的画面

注意:如果是第一次使用软件,进入后会有一些诸如软件的欢迎画面等不相关的对话框,无须担心,直接关闭即可,亦可选择下次登陆时不显示。

3. 进入ModelSim主窗口后,选择File菜单下的“New→Project”,新建一个工程,在弹出的对话框中,给该工程命名并指定一个存放的路径,如图4所示:

4 新建工程

在这里,工程名和你的顶层文件名保持一致是推荐的做法。路径的注意事项已经说过,这里不再提及。默认的库名就是“work”,这个无需更改,点击“OK”即可。

4. 之后会弹出如图5的对话框,选择是新建一个文件还是添加已存在的文件,这两个都可以选择,假如事先编好了文件,就选择添加进来,假如没有就新建。在这里使用添加已有文件,在软件开始之前就编好所用的程序,这样比较方便些。软件自带的编辑环境不是很好,使用第三方的编辑工具是推荐的方法。建议使用UltraEditNotepad++这些专业的代码编辑软件。

UltraEdit偏重于功能的强大和丰富的用户可定制化特性,而Notepad++更加注重易用性。两者在普通功能上差异不是特别大,根据自己的喜好选择一款即可。

5 给工程中添加文件

在路径G:\FPGA_Project\ModelSim\counter8下新建两个文件,一个是counter8.v,一个是test_counter8.v,前者是我们的原始的设计文件,后者是其相应的仿真测试文件。在这个路径的Windows目录下,在空白处右键选择新建一个文本文档.TXT格式,然后在这个文件上右键选择UltraEditEdit with Notepad++就可以启动相应的代码编辑工具进行编辑了,保存的时候注意存成“.v”“.vhd”格式即可。

以下给出两个文件的代码:

第一个文件:

//-----------------------------------------------------

// DesignName : counter8

// FileName   : counter8.v

//Function    : 8 bits counter with asyncclear and sync load

//Coder       : Cheng xu

//-----------------------------------------------------

modulecounter8(

clk                                    ,

aclr                        ,

load                      ,

load_din             ,

dout

);

 

// Portdeclarations

input                               clk                          ;

input                               aclr              ;

input                               load            ;

input          [7:0] load_din   ;

 

output       [7:0] dout           ;

 

//InternalVariables

wire                      clk                          ;

wire                      aclr              ;

wire                      load            ;

wire [7:0] load_din   ;

wire [7:0] dout           ;

 

reg              [7:0] counter = 0        ;

 

//CodeStarts Here

always @(posedge clk or negedge aclr)

if(!aclr)

          counter <= 0;

else if(load == 1)

          counter <= load_din;

else

          counter <= counter + 1;

 

assigndout = counter;

 

endmodule

第二个文件:

//test_counter8.v

`timescale1ns/1ns                                               //注意最前面的符号是数字键“1”左边的//那个符号,不是单引号

moduletest_counter8;

reg                                   clk                          ;

reg                                   aclr              ;

reg                                   load            ;

reg              [7:0] load_din   ;

wire     [7:0]  dout           ;

 

initial

begin

          clk = 0;

          aclr = 1;

          load = 0;

          load_din = 0;

#120 aclr = 0;

#40             aclr = 1;

#20             load = 1;

          load_din = 100;

#20             load = 0;

#100 $stop;                      //可以不添加这个仿真结束的系统任务

end

always#10 clk = ~clk;

 

counter8U(

          .clk(clk),

          .aclr(aclr),

          .load(load),

          .load_din(load_din),

          .dout(dout)

          );

 

endmodule

这样,我们就在该工程路径下建立好了这两个文件。当然新建这两个文件的的工作可以是放在我们这个全部的工作开始之前进行的,无需等到第4个步骤开始的时候再进行。

5. 把刚才新建的文件添加到工程中去,点击“AddExisting Flie”后出现如下画面,如图6所示:

 

6 添加原始的待测试程序文件

 

点击“OK”后,继续添加另外一个测试文件,如图7所示:

7 添加仿真测试文件

之后点“OK”,再关闭“Add items to the Project”这个对话框。最简单的办法是一次同时添加两个文件,点击“Browse”之后,鼠标直接框选这两个文件,这样可以一次添加多个文件到ModelSim工程中。

6. 我们在软件的Project区域已经能看到我们添加的这两个文件了,如图8所示:

 

8 Project区域状态

 

我们下面就可以编译这两个文件了,这时候因为还没有编译文件,所以Status一栏显示的是两个问号。接着在这个Project区域单击鼠标右键,选择“Compile→Compile All”,把HDL源文件编译到当前工程的工作库当中去。如图9所示:

9 编译源文件和仿真测试文件

我们在软件下方的Transcript区域中假如看到如图10的字样,就说明编译通过了:

10 编译成功画面

注意中间的两个successful说明成功了。另外,我们在Project区域中的Status一栏中能够看见两个绿色的勾,这也是一种编译成功的提示。

7. 编译通过之后,在Project区域鼠标右键点击“Add to Project → Simulation Configuration”,如图11所示:

11 添加Simulation Configuration

在出现的Add SimulationConfiguration对话框的右下角打开OptimizationOptions,打开后切换到Options选项卡页面,在Optimization Level中选择Disable Optimizations,如图12所示:

12 关闭优化选项

点击OK确定之后返回Add Simulation Configuration对话框,在Optimization栏中关闭Enable Optimization,再展开work目录,选中Test Bench文件test_counter8,之后save保存。如图13所示:

13 关闭优化选项

此时会在Project区域出现一个仿真配置文件:Simulation 1,双击它就能进入仿真了,在重启ModelSim之后,还可以双击它进入仿真,比较方便。

注意:如果不关闭优化选项的话,有时候ModelSim软件会报错导致不能正常进行仿真。

8. 双击“Simulation 1”后进入仿真波形界面,在Object区域鼠标右键选择“Add → To Wave → Signals inRegion,把待仿真的信号添加入Wave窗口。如图14所示:

14 待仿真的信号添加入Wave窗口

9. 接着我们把wave窗口中的两个信号量改成无符号数显示,方便我们观察,在load_dindout上依次单击鼠标右键,按照图15的方法修改即可:

15 修改信号量为十进制模式

10. Transcript区域中的VSIM提示符后输入命令“run 1us”,把仿真的时间设置为1us。画面会出现我们这个测试文件的内容,还会有个箭头指向我们设置的仿真结束的命令行。实际可以在代码中不添加这个仿真结束的系统任务,我们输入的run1us命令就已经限定了仿真结束的时间在开始后的1个微秒。如图16所示。我们不管它,直接关掉这个文件,后显示的是我们的仿真波形,如图17所示:

16 开始仿真后出现的第一个画面

17 仿真波形文件

我们在这个波形画面上点一下鼠标的左键,这个时候工具栏上的放大缩小按钮被激活,放大镜中间带个加号那个是放大的,带减号的就是缩小的,我们把这个图形放大些来看看,或者点击wave窗口右上角的“+”按钮,即“ZOOM/UNZOOM WINDOW”,如图18所示:

18 功能仿真后的波形图

我们可以看到这个波形图就是按照我们编写的Test Bench文件来进行测试仿真的,这个8位的计数器在异步复位和同步加载的控制信号下工作完全符合我们的设计要求。

11. 仿真过程中如果发现设计不符合要求,此时可以打开UltraEditNotepad++对源文件进行修改,保存。再在ModelSimProject区域鼠标右键选择“Compile→Compile All”,重新编译源文件。之后在工具栏上点击Restart按钮,清除刚才的仿真波形数据,如图19红色箭头指向的这个图标:

19 清除仿真数据

再次在VSIM提示符后输入run 1us即可对修改后的代码进行仿真了。

12. 退出仿真时在Transcript区域的VSIM提示符后输入quit -sim就能退出仿真界面。

至此,基本的功能仿真测试流程就讲解完了。功能仿真,又叫前仿真,也是开发过程中最重要、最必不可少的一个环节。相对于前仿真来说,还有一个后仿真,也叫时序仿真。虽然时序仿真在大型开发和设计中用的很少,但是为了保持一个系列的文章的完整性,下一讲还是会对时序仿真做一下讲解。

我们要注意,大型设计中基本都是通过时序约束和时序分析的方法来确保FPGA设计的时序,因为不可能每修改一次代码就做一次时序仿真,这样会相当的费时费力,效率上完全不能满足快速开发的时间要求。通过时序约束和时序分析的方法来确保时序的优势在于,大规模的代码开发中,如果只是个别人修改了部分代码,那么他对自己修改的代码确保功能仿真正常即可合入整个的版本代码中去,时序问题都由大版本中的时序约束来保证,这样就极大地提高了开发效率。