博主最近刚开始学习FPGA设计,选用的开发语言是目前比较流行的Verilog,教材选用的是北京航空航天大学出版的《夏宇闻Verilog HDL数字系统设计教程》(第四版),这本书也是比较经典的一本教材,第四版是它的最新版本。在学习的过程中,博主对每一章的知识点进行了梳理,对其中重要的知识点(博主认为的)都做了归纳,当然也有些知识点被博主舍弃掉了。学习的过程中也存在一些没看太明白的地方,对于这些内容,有的没写在总结里,有的在总结里标注出了“存疑”二字,请各位读者阅读时留意。最后也欢迎各位读者指出文章中出现的错误!
目录
7.7.4 条件编译命令`ifdef、`else、`endif
第七章 调试用系统任务和常用编译预处理语句
7.1 系统任务$monitor
格式:
$monitor(p1,p2,……pn);
$monitor;
$monitoron;
$monitoroff;
$monitor提供了监控和输出参数列表中的表达式或变量值的功能。在$monitor中,参数可以是$time系统函数。“,,”代表一个空参数,在输出时显示为空格。在多模块调试的情况下,许多模块都调用了$monitor,因任任何时刻只能有一个$monitor起作用,因此需配合$monitoron和$monitoroff使用。不能在always过程块中调用$monitor。
7.2 时间度量系统函数$time
$time返回一个64位的整数来表示当前的仿真时刻值。该时刻是以模块的仿真时间尺度位基准的。$time输出的总是时间尺度的倍数,且总是输出整数。
$realtime和$time的作用是一样的,只是$realtime返回的数字是一个实型数,该数字也是一时间尺度位基准的。
7.3 系统任务$finish
格式:
$finish;
$finish(n);
系统任务$finish的作用是退出仿真器,返回主操作系统。如果不带参数,默认$finish的参数值为1。
各种参数代表的含义:
0 不输出任何信息;
1 输出当前仿真时刻和位置;
2 输出当前仿真时刻、位置和在仿真过程中所用的memory及cpu时间统计。
7.4 系统停止任务$stop
格式:
$stop;
$stop(n);
$stop任务的作用是是把EDA工具(例如仿真器)置成暂停模式,参数越大,输出的信息越多。
7.5 系统任务$readmemb和$readmemh
$readmemb和$readmemh用来从文件中读数据到存储器中,这两个系统任务可以在仿真的任意时刻被执行使用,其格式共有以下六种:
- readmemb(“<数据文件名>,<存储器名>”);
- readmemb(“<数据文件名>,<存储器名>,<起始地址>”);
- readmemb(“<数据文件名>,<存储器名>,<起始地址>,<结束地址>”);
- readmemh(“<数据文件名>,<存储器名>”);
- readmemh(“<数据文件名>,<存储器名>,<起始地址>”);
- readmemh(“<数据文件名>,<存储器名>,<起始地址>,<结束地址>”);
在这两个系统任务中,被读取的数据文件的内容只能包含:空白位置(空格、换行、制表(tab)和from-feeds),注释行(//形式的和/*…*/形式的都允许)、二进制和十六进制数字。数字中不能包含位宽说明和格式说明,对于$readmemb系统任务,每个数字必须是二进制数字,对于$readmemh系统任务,每个数字必须是十六进制数字。每个数字的存放地址值可以在数据文件中进行说明,@后跟上十六进制数:@hh…h
7.6 系统任务$random
这个系统函数提供了一个产生随机数的手段。当函数被调用时返回一个32位随机数。$random的一般用法是:$random%b,其中b>0。它给出了一个在(-b+1):(b-1)中的随机数。
例:
reg[23:0] rand;
rand=$random%60;
上面的例子给出了一个范围在-59到59之间的随机数,下面的例子通过位并接操作产生一个值在0~59之间的数:
例
reg[23:0] rand;
rand={$random}%60;
利用这个系统函数可以产生随机脉冲序列或宽度随机的脉冲序列,以用于电路的测试。
7.7 预编译处理
7.7.1 宏定义`define
用一个指定的标识符(即名字)来代表一个字符串(宏内容),它的一般形式为:
`define标识符(宏名)字符串(宏内容)
例 `define signal string
在编译预处理时将宏名替换成字符串的过程称为“宏展开”,`define命令可以出现在模块定义里面,也可以出现在模块定义外面,宏名有效范围为定义命令之后到原文件结束。通常,`define命令写在模块定义的外面,作为程序的一部分,在此程序内有效。
宏定义是用宏名代替一个字符串,也就是做简单的置换,不做语法检查。预处理时照样带入,不管含义是否正确,只有在编译已被展开后的源程序时才会报错。宏定义不是Verilog HDL语句,不必在行末加分号,如果加了分号会连分号一起进行置换。
7.7.2 “文件包含”处理`include
所谓“文件包含”处理是一个源文件可以将另一源文件的全部内容包含进来,即将另外的文件包含到本文件之中。其一般形式为:
`include“文件名”
如果文件1包含文件2,而文件2要用到文件3的内容,则可以在文件1用两个`include命令分别包含文件2和文件3,而且文件3应出现在文件2之前。
7.7.3 时间尺度`timescale
`timescale命令的格式如下:
`timescale<时间单位>/<时间精度>
时间单位参量是用来定义模块中仿真时间和延迟时间的基准单位,时间精度参量是用来声明该模块的仿真时间精确程度的。时间精度不能大于时间单位值。
当多个带不同`timescale定义的模块包含在一起时只有最后一个起作用。
7.7.4 条件编译命令`ifdef、`else、`endif
条件编译命令有以下几种格式:
(1)`ifdef(标识符)
程序段1
`else
程序段2
`endif
(2)`ifdef(标识符)
程序段1
`endif
条件编译命令可以用编译命令:`ifdef、`ifndef、`else、`endif实现,`ifdef语句中不允许使用布尔表达式(指的是不允许在(标识符)位置使用布尔表达式)。