SystemVerilog——任务和函数(Tasks and Functions)

SystemVerilog从Verilog继承了任务和函数功能。任务和函数是两种用来定义子程序的方式。如果子程序需要消耗仿真时间,使用任务,否者子程序消耗仿真时间为0,则使用函数。另外,函数可以有返回值,而任务没有。

SystemVerilog给任务和函数增加了新的语义特性. 这些新的特性对高级抽象建模非常重要:

  • 静态和自动作用域
  • 参数传递
  • 线程
  • 参数化函数

静态和自动作用域

 


Verilog中变量的作用域

Verilog中,任务和函数中局部定义的变量是静态作用域。因此,如果多次调用函数/任务,则此局部变量将在多个函数执行线程中共享。在递归函数以及任务中通过fork-join执行多线程的情况下发生。因此,Verilog的函数/任务仅仅只可能本地(native)递归。由于Verilog主要用来做RTL级的设计,递归函数不是必须的。

【【译者查资料,猜想本地递归是指函数调用中没有变量,仅仅只有函数自己和参数的运算,举例如下:

fibonacci (n) 
        if (n <2) return n
        else return fibonacci(n-1)+fibonacci(n-2)

】】

静态和自动作用域

Statically静态作用域变量被绑定到应用程序的数据存储区域(在这里是指仿真器). 此存储区域将被所有的线程所共享. 而另一方面对于自动变量,将映射到栈区存储区, 对同一个函数进行多次调用,自动变量将映射到栈中互补相同的区域。

For 对于行为级建模,递归和多线程基本上都需要。为此,SystemVerilog允许变量以自动作用域绑定。为了在函数/任务中使用自动绑定功能,函数/任务需要声明为automatic. 另外,所有在program块中声明的函数/任务缺省都是自动作用域的。如果在自动作用域子程序中仍然需要使用静态变量,那么必须使用static关键字显式声明此变量。注意在C/C++以及其他语言中,缺省就是这样的(类似program块中的样子: 缺省自动,显式声明静态)。

 

 

 

 

 


//Factorial using automatic binding

function automatic int unsigned factorial(int unsigned n);

  if (n = 1) return 1;

  else return n * factorial(n-1);

endfunction: factorial


参数传递


下面讲述使用函数的通用情况,大部分也是用于SystemVerilog的任务.

值传递

SystemVerilog中函数参数缺省是通过值传递,适用于所有的数据类型,包括容器类型。唯一一个例外是类对象,对象本身并没有绑定到变量描述符,描述符所绑定的是对象的句柄(类似C/C++中的指针). 当一个类实例(实际上是它的句柄)被传递的时候,句柄本身是值传递,但是,因为句柄仅仅是指向真实数据,所以,被参数指向的真实的对象就和函数(任务)内部看到的对象是一样的——等效于类对象看起来是通过引用来传递的.

SystemVerilog提供了一个ref关键字作为函数参数的前缀。当使用ref时,表明参数是使用引用传递,'ref'语法类似C++中的引用.

有两种情况下使用'ref'做参数比较有意义。第一种情况,由于函数只能有一个返回值(不考虑传统Verilog上的input/output参数端口声明),任务没有返回值。当函数需要返回多个值或者任务需要返回一个以上值的时候,通过引用传递就用得上。

第二种情况是运行效率的考虑。当大量的数据需要作为参数传递的时候,值传递效率很低。所有的数据需要在每次函数调用的时候被复制。如果参数使用'ref'前缀,可以不需要进行数据复制。但是这样会使得参数的数据容易被函数/任务中的代码修改。此危险可以通过声明ref参数为常量来解决.

 

 

 

 

 


// virtual base class
class xactn;
  // user functions
  virtual function void pack(ref bytes[]);
  virtual function void unpack(const ref bytes[]);
  // other function declarations omitted
endclass

 

 

 

 

函数参数中的缺省值

SystemVerilog允许给函数设置缺省值。如果没有给参数指定值,并且参数有缺省值,那么函数将使用参数的缺省值。此指定缺省值的语法和C++类似.


task void foo (int unsigned x, int unsigned y = 10);
  // the tasks implementation is not provided
endtask: foo

SystemVerilog提供了额外的特征,不像C++, SystemVerilog允许用户将使用指定值的参数放在使用缺省值的参数的后面。使用缺省的参数很简单的在函数调用的参数列表中不出现,后面指定值的参数放在一个逗号后面,此逗号在一个空格之后,表示没有相应的参数。


function void foo(int unsigned first = 1,

                                int unsigned second = 2,

                         int unsigned third = 3,

                         int unsigned fourth = 4);

  // function's code omitted

endfunction: foo

// foo函数的调用例子:

// 第3个和第4个参数使用缺省值

foo (10, 20);

// 第1个和第3个参数使用缺省值

foo ( ,20, ,40);

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值