Verilog语法回顾--task和function

目录

任务(task)和函数(function)

task和function之间的不同点:

task的声明和使能:

task的声明:

task的内存使用和并发过程:

static task 和automatic task的对比:

disable语句:

function的声明和调用:

function的声明

function的返回值:

funtion的调用:

function的规则:


参考《Verilog 编程艺术》魏家明著

任务(task)和函数(function

既提供了从不同位置执行公共代码的能力,也提供了把大过程分为小过程的能力。

task和function之间的不同点:

1.function不能包含时序控制语句,只能在一个时间单位执行,而task就可以包含时序控制语句。

2.function不能调用task,而task可以调用function。

3.function至少有一个input类型的参数,不能有output和inout类型的参数,而task既可以没有参数,也可以有各种类型的参数。

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

5.function只能对输入值返回一个结果值,而task可以是支持各种用途,可以计算并返回多个结果值。对于task,只有使用output和inout,才能把结果传递回来。function可以在表达式中当作操作数使用,操作数的值就是function的返回值。

task的声明和使能:

task的使能,就是从一条包含有传进去的参数和用于接收结果的变量的调用语句,控制从调用的过程转到task。当task完成的时候,控制再传回调用的过程。所以如果task包含时序控制语句,那么调用task的时间和退出task的时间可以是不一样的。task能再使能其他task,没有数量的限制。不管调用了多少task,直到使能的task已经完成,控制才返回到调用的过程。

task的声明:

task [automatic] task_name (
	port_declaration port_name, port_name …,
	port_declaration port_name, port_name …
);
	local variable declarations;
	procedural_statement or statement_group;
endtask

 说明:

1.可以在task内声明各种类型的变量(reg[signed], integer, time, real, realtime);

2.没有使用automatic的task是静态的(Static),所有task的声明的参数和变量都是静态地分配,仿真器对所有并发执行地同一个task共享这些参数和变量。

3.使用automatic地task是可重入的,仿真器对每个并发执行的task动态地分配task声明的参数和变量。

task my_task (
	input a, b,
	inout c,
	output d, e
);
	begin
	…
	c = foo1;
	d = foo2;
	e = foo3;
	end
endtask

my_task(v, w, x, y, z);

说明:

task使能语句的参数(v, w, x, y, z)对应到task的参数(a,b,c,d,e)。

在task使能的时候,input和inout类型参数a,b和c分别接受由v,w和x传进来的值。

task执行的时候,task要把计算出来的值放到c,d和e中

task完成的时候,task要把c,d和e的值传递回x,y和z。

task的内存使用和并发过程:

 Verilog-1995的任务使用静态变量,这就意味着在第一次任务调用还在运行的时候,对这个任务再做第二次调用,那么这两此任务调用使用的是同样的静态变量,这就会给testbench带来严重的问题。

Verilog-2001对task和function做了扩充,增加了一个可选的属性automatic,每次在task或function调用时,局部变量要用的存储空间才被分配,这样就可以实现task和function的重入,重入就是在一个task和function执行期间,可以再次调用这个task或function。

static task 和automatic task的对比:

1.对于static task,他的所有参数和变量都是静态的,不管并发的使能task多少次。所谓静态是指,对于模块的每个实例,仿真器只在初始时为static task声明的参数和变量分配一次存储空间,然后就一直使用,在执行时不在分配。注意:对于模块的不同实例,每个static task还是要使用自己独立的存储空间。

2.static task中声明的变量,包括input,output和inout参数,会保持最后一次使用时候的值,在仿真0时刻,它们将初始化成默认值(x或0).

3.对于automatic task,当每次并发的使能它时,仿真器会为它的所有参数和变量分配新的存储空间。因为automatic task声明的参数和变量在task完成时要释放,所以task完成后就不能在使用它们。

4.automatic task中的变量,包括output参数,在使能的时候初始化成默认值(x或0),而input和inout参数则初始化为从表达式列表传进来的值。

disable语句:

disable语句提供了终止并发活动进程的能力,disable语句在处理意外情况时很有用,例如硬件中断或全局复位。

disable语句的用途:

1.提前结束task的执行。

2.终止命名块的执行。

3.跳出循环语句

4.忽略循环中的后续语句。

disable语句能够终止task或命名块的活动,说明如下:

1.在disable语句执行后,task或命名块就停止执行,然后位于task使能之后或位于命名块之后的语句开始执行。

2.如果task是嵌套的(例如,A使能B,B使能C),那么在disable一个task时,那么也disable所有被嵌套使能的task(例如,disable,那么A,B,C全都终止)

3.如果task被并发的使能多次,那么当一个task被disable时,所有使能的task全部被终止。

如果task被disable,那么下面的结果没有定义

1.从output和inout参数返回的结果

2.已经调度但是还没有执行的非阻塞赋值。

3.过程连续赋值(assign和force语句)

例子:

begin : block_name
	rega = regb;
	disable block_name;
	regc = rega;         // this assignment will never execute
end

例子:output和inout参数是不固定的,不相当于c语言的return

task proc_a;
begin
	…
	if (a == 0)
		disable proc_a;
	…
end
endtask

例子:output和inout参数的值会正确的返回,相当于c语言的return

task proc_a;
begin : block_proc_a
	…
	if (a == 0)
		disable block_proc_a;
	…
end
endtask

function的声明和调用:

function的用途就是要返回一个值,然后把它用在表达式中

function的声明

function [automatic] [function_range_or_type] function_name (
	port_declaration port_name, port_name,
	port_declaration port_name, port_name,
);
	local variable declarations;
	procedural_statement or statement_group;
endfunction

说明:

1.可以在function内声明各种类型的变量(reg[signed], integer, time, real, realtime);

2.没有使用automatic的function是静态的(Static),所有function的声明的参数和变量都是静态地分配,仿真器对所有并发执行地同一个function共享这些参数和变量。

3.使用automatic地function是可重入的,仿真器对每个并发执行的function动态地分配function声明的参数和变量。

4.function_range_or_type用于声明返回值的类型,它是可选的。如果没有声明,那么就认为返回值是1bit的标量;如果声明,那么返回值可以是这些类型:integer,time,realtime,用[n:m]表示的vector;

5.function至少应该有一个input参数。

例子:

function [7:0] getbyte (input [15:0] address);
begin
	…
	getbyte = result_expression;
end
endfunction

function的返回值:

在定义function时,同时在function内隐含的声明了一个与function名字一样的变量,它或者是一个1-bit的变量,或者是与function声明时的同样类型。function返回时,就是把这个变量返回。

funtion的调用:

函数调用被当作表达式中的操作数使用。函数调用时,参数的计算顺序没有定义。

例子:调用两次函数后,连接成一个word

word = contorl ? {getbyte(msbyte), getbyte(lsbyte)} : 0;

function的规则:

1.function的定义不能包含任何时间控制的语句,即不能包含#,@和wait

2.function不能使能task

3.function至少要包含一个input参数

4.function不能包含任何output和inout参数

5.function不能使用非阻塞赋值和过程连续赋值

6.function不能触发任何事件

  • 20
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值