任务与函数
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(笔记)Verilog之五:任务、函数及其他
2010年01月12日星期二11:08
在verilog中,用户可以定义任务和函数,而且它还内置了一些系统任务和系统函数用于实现某些特定的操作。此外,本章还将介绍一些语法概念,如层次结构、VCD文件和信号强度等。
5.1 任务
任务就是一段封装在“task-endtask”之间的程序。任务是通过调用来执行的,而且只有在调用时才执行,如果定义了任务,但是在整个过程中都没有调用它,那么这个任务是不会执行的。调用某个任务时可能需要它处理某些数据并返回操作结果,所以任务应当有接收数据的输入端和返回数据的输出端。另外,任务可以彼此调用,而且任务内还可以调用函数。
注意:任务是不可综合的,它只能用于仿真。
5.1.1 任务定义
任务定义的形式如下:
task task_id
[declaration]
procedural_statement
endtask
其中,task_id是任务名;可选项declaration是端口声明语句和变量声明语句,任务接收输入值和返回输出值就是通过此处声明的端口进行的;
procedural_statement是一段用来完成这个任务操作的过程语句,如果过程语句多于一条,应将其放在语句块内。
5.1.2 任务调用
任务调用语句可以在initial语句和always语句中使用,其语法形式如下:
task_id[(expr1, expr2, ........, exprN)];
task_id是要调用的任务名,expr1, expr2, ........是参数列表。参数列表给出传入任务的数据(进入任务的输入端)和接收返回结果的变量(从任务的输出端接收返回结果),任务调用语句中参数列表的顺序必须与任务定义中的端口声明顺序相同。任务调用语句是过程性语句,所以任务调用中接收返回数据的变量必须是寄存器类型。来看下例:
module Has_Task;
parameter MAXBITS = 8;
task Reverse_Bits;
input [MAXBITS-1:0] Din;
output [MAXBITS-1:0] Dout;
integer K;
begin
for(K=0; K Dout[MAXBITS-K] = Din[K]; end endtask end module 下面调用Reverse_Bits的代码: reg[MAXBITS-1:0] Reg_X, New_Reg; Reverse_Bits(Reg_X, New_Reg); 其中,Reg_X的值作为输入数据送到任务的输入端Din,任务的返回值从其输出端Dout输出并交给New_Reg,在寄存器new_reg中得到返回值。 调用任务时,可以引用任务声明所在的模块内定义的任何变量。 任务内可以带有时序控制,如时延。但要注意,任务的输出值必须等到整个任务的全部语句都执行完之后才能返回。 5.2函数 和任务一样,verilog的函数也是一段可以完成特定操作的程序,这段程序处于关键词“function-endfunction”之间。函数与任务的不同之处在于:·函数只能返回一个值,而任务可以有多个返回值; ·函数一经调用就必须立即执行,其内部不能包含任何时序控制,而任务内部可 以有时序控制; ·函数可以调用函数,但是不能调用任务,而任务即可以调用任务也可以调用函数; ·函数至少有一个输入,而任务可以没有输入端。 5.2.1 函数定义 函数定义和任务定义一样,可以出现在模块内的任何位置,其形式如下: function [range] function_id; input_declaration other_declarations procedural_statement endfunction 这里的range用于指定函数的取值范围,是可选项,若没有指定,默认缺省值为1。 module Function_Example; parameter MAXBITS = 8; function [MAXBITS-1:0] Reverse_Bits; input [MAXBITS-1:0] Din; integer K; begin for(K=0; K Reverse_Bits[MAXBITS-K] = Din[K]; end endfunction endmodule 注意到没有,函数的定义中并没有声明输出,那么函数执行得到的结果如何返回呢?事实上,函数定义时,在函数内部已经隐性的声明了一个寄存器变量,该寄存器变量与函数名同名并且取值范围也相同。那么函数如何通过这个寄存器返回值?注意上例中的“Rever_Bits[MAXBITS-K] = Din[K];”这条语句,就是通过这条语句把Din[K]的值赋给寄存器Reverse_Bits[MAXBITS-K],同时也实现了值的返回。 5.2.2 函数调用 和任务一样,函数也是在被调用时才被执行的,调用函数的语句形式如下: func_id(expr1, expr2, ........., exprN) 其中,func_id是要调用的函数名,expr1, expr2, ......exprN是传递给函数的输入参数列表,该输入参数列表的顺序必须与函数定义时声明其输入的顺序相同。 reg[MAXBITS-1:0] New_Reg, Reg_X; New_Reg = Reverse_Bits(Reg_X); 与任务相似,在函数内部声明的所有寄存器都是静态的,当函数被调用时,这些寄存器的值不能被改变。 5.3 系统任务和函数 verilog提供了一些已经定义好的任务和函数,即系统任务和系统函数,通过直接调用这些系统任务或系统函数可以方便的完成某些操作。 这些系统任务和系统函数可以分为以下几类: ·显示任务 ·文件输入/输出任务 ·时间标度任务 ·仿真控制任务 ·时序验证任务 ·PLA建模任务 ·随即建模任务