1:函数只能与主模块共用同一个仿真时间单位,而任务能够定义本身的仿真时间单位;express
2:函数不能启动任务,而任务能启动其它任务和函数;函数
3:函数至少要有一个输入变量,而任务能够没有或有多个任何类型的变量;spa
4:函数返回一个值,而任务则不返回值。code
任务的定义:blog
task <任务名>;get
<端口及数据类型声明语句>input
<各个语句>it
endtaskio
若是传给任务的变量值和任务完成后接收结果的变量已经定义,就能够用一条语句启动任务,任务完成之后控制就传回启动过程。若是任务内部有定时控制,则启动的时间能够与控制返回的时间不一样。任务能够启动其它任务,其它任务又能够启动别的任务,能够启动的任务数是没有限制的。无论有多少任务启动,只有当全部的启动任务完成之后,控制才能返回。function
下面举例,交通灯,这个代码模块只是一个行为模块,不能综合成电路网表:
`timescale 10ns / 1ns module taskdemo; reg clock,red,amber,green; parameter on=1,off=0,red_tics=3,amber_tics=5,green_tics=6; initial red=off; initial amber=off; initial green=off; always begin red=on; light(.color(red),.tics(red_tics)); green=on; light(.color(green),.tics(green_tics)); amber=on; light(.color(amber),.tics(amber_tics)); end task light; `timescale 1ns / 100ps output color; input[31:0] tics; begin repeat(tics) @(posedge clock); color=off; end endtask always begin #1 clock=0; #1 clock=1; end endmodule
上面代码在task中又从新定义了仿真时间。仿真波形以下:
函数的定义:
function <返回值的类型或范围> (函数名);
<端口说明语句>
<变量类型说明语句>
begin
<语句>
end
endfunction
<返回值的类型或范围>这一项是可选项,若是默认则返回值为一位寄存器类型数据:
function [7:0] getbyte; input [15:0] address; begin <说明语句> getbyte = result_expression; //从地址字中取低字节,把结果赋予函数的返回字节 end endfunction
函数的定义蕴含声明了与函数同名的,函数内部的寄存器。若是<返回值的类型或范围>为默认,则这个寄存器是一位的,不然是与函数定义中<返回值的类型或范围>一致的寄存器。函数的定义把函数返回值所赋值寄存器的名称初始化为与函数同名的内部变量。上面的代码中说明了这个概念:getbyte被赋予的值就是函数的返回值。
函数调用形式:<函数名>(<表达式>,...<表达式>)
其中函数名做为确认符。下面的例子中,再次调用函数getbyte,把两次调用产生的值进行位拼接运算,以生成一个字:
word = control ? {getbyte(msbyte),getbyte(lsbyte)} : 0;
函数的使用规则:
1:函数的定义不能包含有任何的时间控制语句,即任何用#、@、或wait来标识的语句;
2:函数不能启动任务;
3:定义函数时至少要有一个输入参量;
4:在函数的定义中必须有一条赋值语句给函数中的一个内部变量赋以函数的结果值,该内部变量具备和函数名相同的名字;