Verilog学习心得之三-----task与function的区别

task和function说明语句分别用来定义任务和函数。

---特点

1、利用任务和函数可以把一个很大的程序模块分解成许多小的任务和函数,便于理解和调用。

2、输入、输出和总线信号的值可以传入、传出任务和函数。

3、任务和函数往往还是在程序模块中在不同地方多次用到的相同的程序段。

4、学会使用task和function语句可以简化程序的结构,使程序明白易懂,是编写较大模型的基本功。

--task和function区别

1、function只能与主模块共用一个仿真时间单位,而task可以定义自己的仿真时间单位。

2、function不能包含task,task可以包含其它的task和function。

3、function至少有一个输入变量,而task可以没有或者有多个任意类型的变量。

4、function返回一个值,而task则不返回值。

--目的

function的目的是通过返回一个值来响应输入信号的值。

task能支持多种目的,能计算多个结果值,这些结果值之间能通过调用的task的输出或者总线端口输出。

--举例

Verilog中模块使用function时是把它当做表达式的操作符,这个操作就是这个函数的返回值。例如:定义一个task或者function对一个16位的字进行操作,让高字节与低字节互换,把它变为另一个字(假定这个任务或函数名为:switch_bytes)。

task返回的新字是通过输出端口的变量,因此16位字节互换任务的调用源码是:

switch_bytes(old_word,new_word);

function返回的新字是通过函数本身的返回值,因此16位字节互换任务的函数源码是:

new_word=switch_bytes(old_word);

函数switch_bytes把输入的old_word的字的高低字节互换后赋值给new_word。

--task说明

如果传给任务的变量值和任务完成后接收的结果已定义,就可以用一条语句启动任务。任务完成以后控制就传回启动过程。如果任务内部有定时控制,则启动的时间可以与控制返回的时间不同。任务可以启动其它任务,其它任务又可以启动其它任务,可以启动的任务数是没有限制的。只有当所有启动任务完成以后,控制才能返回。

1、任务的定义

任务:

task <task name>;
 <port and data type declare>;
 <statement 1>;
 <statement 2>;
 <statement 3>;
 ...
 endtask

这些声明语句的语法与模块定义的对应声明语句语法一致。

2、任务的调用及变量的传递

任务的调用:

<任务名> (端口1,端口2,端口3,...,端口n);

具体的例子:

module traffic_lights;
 reg clock;
 reg red;
 reg amber;
 reg green;
 
 parameter  on = 1, 
            off = 0,
            red_tics = 350,
            amber_tics = 30,
            green_tics = 200;

//交通灯初始化
 initial red=off;
 initial amber=off;
 initial green=off;
//交通灯控制时序
always begin
 red=on; //开红灯
 light(red,red_tics); //调用等待任务
 green=on; //开绿灯
 light(green,green_tics); //等待
 amber=on; //开黄灯
 light(amber,amber_tics); //等待
end
//定义交通灯开启时间的任务
task light(color,tics);
 output color;
 input[31:0] tics;

 begin
  repeat(tics) @(posedge clock);//等呆tics个时钟的上升沿
  color=off;//关灯
 end
endtask
//产生时钟脉冲的always块
always begin
 #100 clock=0;
 #100 clock=1;
end

endmodule

这个列子描述了一个简单的交通灯的时序控制,有它自己的时钟产生器。

--function说明

1、function定义

function <返回值的类型和范围> (函数名);

function <return type and scope> (function name);
<port define>
begin
 <statement>;
 ...
end
endfunction

下面举例如下:

function [7:0] getbyte;
 input [15:0] address;
 begin
  <说明语句> //从地址字中提取低字节的程序
  getbyte = result_expression;
 end
endfunction

2、函数的使用规则

a、函数定义不能包含任何的时间控制语句,即#、@或者wait;

b、函数不可启动任务;

c、定义函数时至少需要一个输入参量;

d、在函数的定义中,必须有一条赋值语句给函数中的一个内部变量赋以函数的结果值,该内部变量与函数具有相同的名字;

下面是一个例子

module tryfact;
 //函数定义------------------------------
function [31:0] factorial;
 input [3:0] operand;
 reg [3:0] index;
 begin
  factorial = operand ? 1 : 0;
  for(index = 2; index <= operand; index = index + 1)
  factorial = index * factorial;
 end
endfunction
//函数的测试----------------------------------
 reg [31:0] result;
 reg [3:0] n;
initial begin
 result = 1;
 for (n = 2; n < 9; n = n + 1) begin
  $display ("Partial result n = %d result = %d",n,result);
  result = n * factorial(n)/((n*2) + 1);
 end
 $display ("Finalresult = %d",result);
end
endmodule//模块结束


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页