博主最近刚开始学习FPGA设计,选用的开发语言是目前比较流行的Verilog,教材选用的是北京航空航天大学出版的《夏宇闻Verilog HDL数字系统设计教程》(第四版),这本书也是比较经典的一本教材,第四版是它的最新版本。在学习的过程中,博主对每一章的知识点进行了梳理,对其中重要的知识点(博主认为的)都做了归纳,当然也有些知识点被博主舍弃掉了。学习的过程中也存在一些没看太明白的地方,对于这些内容,有的没写在总结里,有的在总结里标注出了“存疑”二字,请各位读者阅读时留意。最后也欢迎各位读者指出文章中出现的错误!
目录
第六章 结构语句、系统任务、函数语句和显示系统任务
6.1结构说明语句
6.1.1 initial语句格式如下:
6.1.2 always语句格式如下:
6.2 task和function说明语句
6.2.1 task说明语句
6.2.2 function说明语句
6.2.3 自动(递归)函数
6.3 常用的系统任务
6.3.1 $display和$write任务
6.3.2 文件输出:存疑。
6.3.3 显示层次:
6.3.4 选通显示:
6.3.5 值变存储文件:
Verilog语言中的任何过程模块都从属与以下4种结构的说明语句
initial语句执行一次,而always语句则不断地重复活动着,直到仿真过程结束。
initial
begin
语句1;
语句2;
……
语句n;
End
initial常用与测试文件和虚拟模块的编写,用来产生仿真测试信号和设置信号记录等仿真环境
always <时序控制> <语句>
如果一个always语句没有时序控制,则这个语句将会使仿真器产生死锁。always的时序控制可以是沿触发也可以是电平触发。沿触发的always块常常用来描述时序行为,如有限状态机,通过综合工具转换为表示寄存器组合门级组合的组合逻辑结构;而电平触发的always块产长用来描述组合逻辑行为,通过综合工具转换为表示组合逻辑的门级逻辑和带锁存器的组合逻辑结构。
always块的OR事件控制:
由关键词“or”连接的多个事件名或者信号名组成的列表称为敏感列表,关键词“or”被用来表示这种关系,或者使用“,”来代替。此外,如果组合逻辑块的输入变量很多,Verilog提供另外两个特殊的符号:@*和@(*),它们都表示对其后面语句块中所有输入变量的变化是敏感的。
wait关键字表示的电平敏感时序控制:
例:always
wait (count_enable) #20 count=count+1;
task和function说明语句的不同点:
(1)任务的的定义 任务的定义语法如下:
task <任务名>;
<端口及数据类型声明语句>
<语句1>
<语句2>
……
<语句n>
endtask
(2)任务的调用及变量的传递
任务的调用:
<任务名>(端口1,端口2,端口3,……端口n);
函数的目的是返回一个用于表达式的值。
6.2.2.1 定义函数的语法:
function <返回值的类型或范围> (函数名);
<端口说明语句>
<变量类型说明语句>
begin
<语句>
……
end
endfuction
注:<返回值的类型或范围>这一项是可选项,如默认则返回值为一位寄存器类型数据。
还可以以C语言风格定义函数:
例:
//定义偶校验位计算函数,该函数采用ANSI C风格的变量声明
function calc_parity(input [31:0] address)
begin
//适当地设置输出值,使用隐含的内部寄存器calc_parity
calc_parity = ^address;
end
endfunction
6.2.2.2 从函数返回的值:
函数的定义蕴含声明了与函数同名的、函数内部的寄存器
6.2.2.3 函数的调用:
函数的调用时通过将函数作为表达式中的操作数来实现的。
调用格式如下:
<函数名>(<表达式>,…<表达式>)
6.2.2.4 函数的使用规则:
Verilog中的函数不能够进行递归调用的。设计模块中若某函数在两个不同的地方被同时并发调用,由于这两个调用同时对同一块地址空间进行操作,那么计算结果将是不确定的。
若在函数声明时使用了关键字automatic,那么该函数将成为自动的或可递归的,即仿真器为每一次函数调用动态地分配新的地址空间,每一个函数调用对各自的地址空间进行操作。因此,自动函数中声明的局部变量不能通过层次名进行访问。而自动函数本身可以通过层次名进行调用。
在定义时将automatic插入到function即可。
常量函数:
参数是常量的函数。
带符号函数:
带符号函数的返回值可以作为带符号数进行运算。
格式:
$display (p1,p2,……pn);
$write(p1,p2,……pn);
其中p1称为“格式控制”
$display自动地在输出后进行换行,$write则不是这样,如果想在一行里输出多个信息,可以使用$write。在$display和$write中,其输出格式控制是用双引号括起来的字符串,它包括以下两种信息:
注:
1. 打开文件
用法:$fopen(“<文件名>”);
用法:<文件句柄>=$fopen(“<文件名>”);
2. 写文件
用法:$fdisplay(<文件描述符>,p1,p2,……,pn);
$fmonitor(<文件描述符>,p1,p2,……,pn);
3. 关闭文件
用法:$fclose(<文件描述符>);
通过任何显示任务,比如$display、$write、$monitor或者$strobe任务中的%m选项的方式可以显示任何级别的层次。
$strobe与$display任务除了在执行顺序上有区别外,其余用法相同:$strobe总是在同时刻的其他赋值语句执行完成之后才执行的,而$display的执行顺序则是不确定的。$strobe的这种同步机制可以确保所有在同一时钟沿赋值的其他语句在执行完毕之后才显示数据。
值变存储文件(VCD)是一个ASCII文件,它包含仿真时间、范围与信号的定义以及仿真运行过程中信号值得变化信息。设计中的所有信号或者选定的信号集合在仿真过程中都可以被写入VCD文件。
Verilog提供了系统任务来选择要转储的模块实例或者模块实例信号($dumpvars),选择VCD文件的名称($dumpfile),选择转储过程的起点和终点($dumpon,$dumpoff),选择生成检测点($dumpall)。具体使用见教材P97。