task和function
task和function具备将程序中反复使用的语句结构聚合起来的能力,功能类似于C语言的子函数,通过task和function语句结构 来替代重复性大的语句可以有效简化程序结构。
任务和函数具备将程序中的反复被用的语句结构聚合起来的能力,因此其功能类似于C 语言的子程序。通过任务和函数语句结构来替代重复性大的语句可以有效地简化程序结构。
从另一方面看,利用任务和函数可以把一个大的程序模块分解成许多小的任务和函数,以利调试。任务和函数语句的关键字分别是 task 和 function。
task 可以被其他模块外部调用。 端口在定义模块的时候定义
- 任务(task)定义语句格式
端口及数据类型声明语句
begin 过程语句; end
endtask
- 任务调用格式
任务,任务定义中,关键词 task
和 endtask
间的内容即被定义的任务,其任务名是标志当前定义任务的名称标识符。
任务中的过程语句是顺序语句,若有多条,需用块语句括起来。还应注意,任务语句中不能出现由 always
或initial
引导的过程语句结构。
显然,在任务中无法描述时序电路,可综合的任务语句结构只能描述组合电路。
任务调用语句表述较简单,即任务名旁标注端口表即可。但应注意,任务调用时和定义时的端口变量的位置应该一一对应。
例子:
input S;
input[3:0] C1,D1,C2,D2;
//端口定义数目不受限制
output[3:0] D;
reg[3:0] out1,out2;
//任务定义,任务名CMP,此行不能出现端口定义语句
task CMP;
//注意任务端口名的排序
input[3:0] A,B;
output[3:0] DOUT;
begin
//任务过程语句描述一个比较电路
if (A>B) DOUT=A;
else DOUT=B;
//在任务结构中可以调用其他任务或函数,甚至自身
end
//任务定义结束
endtask
//主程序过程开始
always@(*) begin
//调用一次任务。任务调用语句只能出现在过程结构中
CMP(C1,D1,out1);
//第二次调用任务
CMP(C2,D2,out2);
end
assign D=S?out1:out2;
endmodule
function
输入端口说明,其他类型变量定义;
begin 过程语句;end
endfunction
- 函数调用语句格式
函数名是定义函数的名称,对函数的调用就是通过此名称完成的。函数调用的返回值就是通过函数名变量传递给函数调用语句的。
函数中的功能描述语句与任务一样都是过程语句,因此函数的调用只能放在主程序的过程结构中
同时,与任务相同,函数中的语句也不能出现由always
或initial
引导的过程语句结构,从而函数描述的可综合的逻辑结构也只能是组合电路。endfunction
是函数定义的结束语句。
函数的调用是通过将函数作为表达式中的操作数来实现的。
//定义一个函数名为GP的函数,GP同时作为位宽为3的输出参数
function[2:0] GP;
//M定义为此函数的输入值,位宽是4
input[3:0] M;
reg[2:0] CNT,N;
begin
CNT=0;
//for 循环语句
for(N=0;N<=3;N=N+1)
if(M[N]==1)
//含1的位个数累加
CNT=CNT+1;
GP=CNT;
end
endfunction
//主程序输入A或非缩位,若为1则输出函数计数结果
assign OUT=(~|A)?0:GP(A);
endmodule