2.5 任务、函数及预处理
任务 task
定义格式
task <task_name>; // 注意无端口列表 // 端口和数据类型声明语句; // 其他语句; endtask
调用格式
<task_name> (port1, port2, ......);
注意事项
任务调用时和定义时的端口变量应是一一对应的。
任务的定义与调用须在一个
module
模块内。定义任务时,没有端口名列表,但需要紧接着进行输入输出端口和数据类型的说明。任务在被调用时激活。任务调用与模块调用一样通过任务名调用实现,调用时,需列出端口名列表,端口名的排序和类型必须与任务定义中的相一致。
一个任务可调用别的任务和函数,可调用的任务和函数个数不限。
函数 function
定义格式
function <...> function_name; // ... 表示返回值位宽或类型说明 // 端口声明; // 局部变量定义; // 其他语句; endfunction
注意事项
<返回值位宽或类型说明>
是一个可选项,如果缺省,则返回值为1位寄存器类型的数据。函数的定义与调用须在一个
module
模块内。函数只允许有输入变量且必须至少有一个输入变量,输出变量由函数名本身担任,在定义函数时,需对函数名说明其类型和位宽。
定义函数时,没有端口名列表,但调用函数时,需列出端口名列表,端口名的排序和类型必须与定义时的相一致。这一点与任务相同。
函数可以出现在持续赋值
assign
的右端表达式中。函数不能调用任务,而任务可以调用别的任务和函数,且调用任务/函数个数不受限制。
任务与函数的比较
比较项目 |
任务 |
函数 |
---|---|---|
输入与输出 |
可有任意个各种类型的参数 |
至少有一个输入,不能将 |
调用方式 |
只能在过程语句中调用,不能在连续赋值语句 |
函数可作为表达式中的一个操作数来调用,在过程赋值和连续赋值语句中均可以调用 |
定时事件控制 |
支持 |
不支持 |
调用其他任务和函数 |
支持 |
可调用其他函数,不能调用其他任务 |
返回值 |
不支持 |
支持 |
编译预处理语句
Verilog允许在程序中使用特殊的编译向导(Compiler Directives)语句,在编译时,通常先对这些向导语句进行"预处理",然后再将预处理的结果和源程序一起进行编译。向导语句以符号`
开头,以区别于其它语句。比较常用的有 `define
, `include
和 `ifdef
、 `else
、 `endif
等。
`define
语句用于将一个简单的名字或标志符(或称为宏名)来代替一个复杂的名字或字符串。
`define <name> <string>
`include
语句文件包含语句,用于将一个文件全部包含到另一个文件中。
`include "filename"
一个
`include
语句只能指定一个被包含的文件。`include
语句可以出现在源程序的任何地方。被包含的文件若与包含文件不在同一个子目录下,必须指明其路径名。文件包含允许多重包含,比如文件1包含文件2,文件2又包含文件3等。