1.系统任务 $monitor
格式:
$monitor(p1,p2,….pn);
$monit0r;
$monitoron;
$monitoroff;
任务$monitor提供了监视和输出参数列表中的表达式或变量的功能。其参数列表中输出控制格式字符串和输出列表的规则和$display中一样。当启动一个带有一个或多个参数的$monitor任务时,仿真器则建立一个处理机制,使得每当参数列表中变量或表达式的值发生变化时,整个参数列表中的变量或表达式的值都输出显示。如果同一时刻,两个或多个参数的值发生变化则在该时刻只输出一次。但在$monitor中,参数可以是$time系统函数。
$monitoron和$monitoroff任务的作用是通过打开和关闭监控标志来控制监控任务$monitor的启动和停止,这样就可以控制$monitor的发生。其中$monitoroff任务用于关闭监控标志,停止监控任务$monitor,$monitoron则用来打开监控标志,启动监控任务$monitor。通常在通过调用$monitoron来启动$monitor时,不管$monitor参数列表中的值是否发生变化,总是立刻输出显示当前的时刻参数列表中的值,这用于在监视的初始时刻设定初始比较值。在默认情况下,控制标志在仿真的起始刻就已经打开了。在多模块调试的情况下,许多模块中都调用了$monitor,因为任何时刻只能有宇哥$monitor起作用,因此需配合$monitoron与$monitoroff使用,把需要监视的模块用$monitoron打开,在监视完毕后及时用$monitoroff关闭,以便把$monitor让给其他模块使用。$monitor与$display的不同处还在于$monitor往往在initial块中调用,只要不调用$monitoroff,$monitoron便不间断地对所设定的信号进行监视。
2.时间度量系统函数$time
(1)系统函数$time
$time可以返回一个64位的整数来表示的当前仿真时刻值。该时刻是以模块的仿真时间尺度为基准的。
(2)$realtime 系统函数
$realtime和$time的作用是一样的,只是$realtime返回的时间数字是一个实型数,该数字也是以时间尺度为基准的。
3.系统任务$finish
格式:
$finish;
$finish(n);
系统任务$finish的作用是退出仿真器。也可以带参数,根据参数的值输出不同的特征信息。
如果不带参数,默认$finish的参数树枝为1.
0 不输出任何信息;
1 输出当前仿真时刻和位置;
2 输出当前仿真时刻,位置和在仿真过程中所用memory及CPU的时间统计。
4.系统任务$stop
格式:
$stop;
$stop(n);
$stop任务的作用是把EDA工具置成暂停模式,在仿真环境下给出一个交互式的命令提示符,将控制权交给用户。这个任务可以带有参数表达式。
5.系统任务$readmemb和$readmemh
用来从文件中读取数据到存储器中。这两个系统任务可以在仿真的任意时刻被执行,格式:
(1)$readmemb("<数据文件名>",<存储器名>);
(2)$readmemb("<数据文件名>",<存储器名>,<起始地址>);
(3)$readmemb("<数据文件名>",<存储器名>,<起始地址>,<结束地址>);
(4)$readmemh("<数据文件名>",<存储器名>);
(5)$readmemh("<数据文件名>",<存储器名>,<起始地址>);
(6)$readmemh("<数据文件名>",<存储器名>,<起始地址>,<结束地址>);
在这两个系统任务中,被读取的数据文件的内容只能包含:空白位置(空格、换行、制表符(tab)和form-feeds),注释行(//形式的和形式的都允许)、二进制或十六进制的数字。
数字中不能包含位宽的说明和格式说明,对与$readmemb系统任务,每个数字必须是二进制数,对于$readmemh系统任务,每个数字必须是十六进制。数字中不定值x或X,高阻值z或Z和下划线的使用方法及代表的意义与一般VERILOG HDL程序的语法和用意一样
6.系统任务$random
这个系统函数提供了一个产生随机数的手段。当函数被调用时返回一个32位的随机数。他是一个带符号的整数。
$random一般用法是:$random%b,其中b>0。他给出一个范围在(-b+1):(b-1)中的随机数。
7.编译预处理
(1)宏定义`define
用一个指定的标识符来代表一个字符串,他的一般形式为:
`define标识符(宏名)字符串(宏内容)
这种方法可以以一个简单的的名字代替一个长的字符串,也可以用一个有含义的名字来代替没有含义的数字和符号。
说明:
1)宏名可以用大些字母也可以用小写字母。建议用大些!
2)`define命令可以出现在模块定义里面,也可以出现在模块定义外面。红名的有效范围为定义命令之后到原文结束,通常定义在模块外面,作为程序的一部分,在此程序有效。
3)在引用一定义的宏名时,必须在宏名的前面加上符号“`”,表示该名字是个经过宏定义的名字。
4)使用宏定义可以提高程序的可移植性和可读性。
5)宏定义是用宏名代替一个字符串,也就是做简单的置换,不做语法检查。预处理时照样带如,不管是否正确。只有在编译已被宏展开的源程序才报错。
6)宏定义不是Verilog语句,不必在行末加分号。如果加了分号会连分号一起进行置换。
7)在进行宏定义时,可以引用已定义的宏名,可以层层置换。
8)宏名和宏内容必须在同一行中进行声明。如果在宏内容中包含有注释行,注释行不会作为被置换的内容。
(2)“文件包含”处理`include
所谓“文件包含”处理是一个源文件可以将另外的源文件的全部内容包含进来,即另外的文件包含到本文件之中。
可以节省设计时间;可以将一些常用的的宏定义或任务组成一个文件夹,然后将这些宏定义包含到自己所写的源程序中。
说明:
1)一个`include命令只能指定一个被包含的文件,如果包含n个文件要用n个`include命令。
2)`include命令可以出现在Verilog源程序的任何地方,被包含的文件名可以是相对路径也可以是绝对路径。
3)可以将多个`include命令写在一行,在`include命令行,可以出现空格和注释行。
4)如果文件1包含文件2,文件2要用到文件3的内容,则在文件1用两个`include分别包含文件2和文件3,而且文件3应出现在文件2之前。
这样,文件1和文件2都可以用到文件3中的内容。在文件2中不必在用`include了。
5)在一个被包含文件中又可以包含另一个被包含的文件,即文件包含可以是嵌套的。
(3)时间尺度`timescale
`timescale命令用来说明跟在该命令后的模块的时间单位和时间精度。使用`timesale命令可以在同一个设计里面包含采用了不同的时间单位模块。
格式: `timesale<时间单位>/<时间精度>