编写好的程序,需要对其进行测试(仿真)。我们在之前的章节学习过图形界面的仿真。这一章,我们将学习如何进行文本形式的仿真。测试主要是用软件编写代码来生成预期的输入激励信号,这些激励信号将被连接到综合的电路输入端口上去,进而通过软件计算的方式,计算这些信号在综合电路里流动时的变化,以及输出端的信号响应。程序员会将输入输出的信号与心里预期要获得的结果进行比对,来判断测试的正确性。
关于测试,我们在之前的章节有涉及。下面,我们将系统的对测试的内容进行一些介绍。
测试最经常使用的就是initial语句。
例8.1:initial语句生成激励信号。
对应的波形如图8.1所示。分别在#100、#300、#400、#600和#800产生了波形的电平变化。
图8.1 仿真的波形图
例8.2:阻塞语句内延迟导致的信号生成。
图8.2是上面的语句产生的波形。
图8.2 仿真的波形图
上面这个例子,使用的是阻塞式的语句内延迟。阻塞式赋值语句表示上一句得执行完了才能轮到下一句执行。
例8.3:
图8.3是上面这几行语句产生的波形。
图8.3 仿真的波形图
上面这几行语句是非阻塞赋值的语句内延迟。阻塞式赋值语句表示下一句语句不用等到上一句执行完了才执行。也就是上一句语句的执行与否不阻碍下一条语句的执行。
我们在仿真测试的环境下经常会遇到要产生周期波形。周期波形的产生会有好几种方式。但是要记住下面几个关键点:
(1)如果使用了assign连续赋值语句,那么assign语句里被赋值的信号必须是线网类型;
(2)线网类型的信号初始值是z;
(3)initial语句里被赋值的信号必须是reg类型;(www.xing528.com)
(4)always语句里被赋值的信号一定要声明为reg类型。
建立在上面几个原则之上,所以我们之前有一个建立时钟的例子:
这个例子先对clk给一个初始值0,然后每10个时间单位翻一下并赋值给自己。
上面的例子是生成的时钟占空比为1:1的情况。如果想生成非1:1占空比的时钟,那么可以把always语句块里的语句改写一下,如下:
下面我们介绍如何使用循环语句来产生周期信号。先看一个错误的例子。
例8.4:一个错误的生成周期信号的forever循环语句。
这段代码在执行的过程中会告诉你一个错误:“line38expecting'end module',found'forever'”。line38是著者在运行的过程中forever所在的那一行的行号。为什么会显示仿真错误呢?上面这个例子里,initial语句结束后就是forever语句,表示这么写是认为initial语句和forever语句是同等级别的。这种做法是错的。因为你不能把forever语句作为和initial同等级的语句,这不合语法。你得把forever语句块放在initial语句块里,或者把forever语句块放在always语句块里才行。毕竟initial语句和always语句才是同等级的。看下面这个例子。
例8.5:一个正确的的生成周期信号的forever循环语句。
这个例子就是正确的,它把语句1放在了语句2之后,于是forever语句就成了initial语句块的一部分。它能生成一个周期为10个时间单位的in2周期信号。
例8.6:用while循环语句生成周期信号。
上面这个例子先定义了寄存器in1,并初始化in1为1,把in1用于while的循环条件。在仿真波形上可以看到in2为周期信号。这也是一个成功生成周期波形的例子。
例8.7:用repeat循环语句生成周期信号。
首先我们先取一个非常大的数,比如说100000。我们要把这个大数作为repeat循环的循环次数。通常来说,在一个仿真测试里,时钟周期10万个,已经足够用了。结合上面的这个例子,我们把while(in1)这条语句改为repeat(100000),如下所示:
把这段程序在ise集成开发环境里进行仿真,我们也可以得到一个周期为10个时间单位的in2周期信号。
类似的,我们也可以通过for循环语句生成周期信号,方法和之前的类似,就是让for循环里面的循环变量足够大,循环次数足够多。
如果想生成有限个数(个数明确)的周期信号,上面这几种循环也是可以的。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。