75,Verilog-2005标准篇:函数调用

函数应至少有一个输入参数,其功能是返回一个值并用于表达式中,其语法定义如下所示:

函数定义应以关键字 function 开始,随后是可选的关键字 automatic,随后是可选的函数返回值的function_range_or_type,随后是函数名称,随后是分号或用括号括起来的函数端口列表,然后是分号,最后以关键字 endfunction 结束。如果指定的函数没有使用可选的 function_range_or_type,返回值默认为标量。如果使用 function_range_or_type,则应指定函数的返回值是real, integer, time, realtime,或范围为 [n:m] 位的矢量(可选带符号数)。

函数输入的声明方式同样有两种。第一种方法是在函数名称后加上分号,分号之后是一个或多个输入声明,可选择与block_item_declarations声明混合在一起,最后以endfunction 关键字。

第二种方法应包含函数名称、一个双括号和一个或多个输入声明,括号内声明以逗号分隔。在所有输入声明之后,应有一个分号,最后以endfunction 关键字。

下面的示例按第一种方式定义了一个名为 getbyte 的函数:

或者使用函数声明的第二种声明方式,函数可以定义如下:

函数定义隐含声明了一个与函数同名的函数内部变量。该变量要么默认为 1 位reg类型数据,要么与函数声明中指定的类型相同。函数定义通过将函数结果赋值给与函数同名的内部变量,来初始化函数的返回值。

换句话说,在函数内部有一个隐含的变量,它的名称是函数的名称,可以在函数内部的表达式中使用。因此,在函数作用域内声明另一个与函数同名的对象是非法的。

函数在被调用时只作为表达式中的一个操作数,如下例子所示:

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

函数使用起来比任务有更多限制,其使用规则如下

a) 函数定义不得包含任何时间控制语句,即任何包含 #@wait 的语句。

b) 函数不得调用任务。

c) 函数定义应至少包含一个input参数。

d) 函数定义中不得有声明为outputinout的参数。

e) 函数不得包含任何非阻塞赋值或过程连续赋值。

f) 函数不得被任何事件触发。

下例定义了一个返回整数值的阶乘函数,阶乘函数被迭代调用并打印结果:

module  tryfact;
// define the function
function automatic integer factorial;
input  [31:0] operand;
integer  i;
if (operand >= 2)
 factorial = factorial (operand - 1) * operand;
else
 factorial = 1;
endfunction
// test the function
integer  result;
integer  n;
initial begin
for (n = 0; n <= 7; n = n+1)  begin
 result = factorial(n);
 $display ("%0d factorial=%0d", n, result);
end
end
endmodule  // tryfact

上述代码的仿真结果如下:

0 factorial=1

1 factorial=1

2 factorial=2

3 factorial=6

4 factorial=24

5 factorial=120

6 factorial=720

7 factorial=5040

下面这个示例定义了一个名为 clogb2 的函数,它返回一个具有log2上限值的整数:

module  ram_model (address, write, chip_select, data);
   parameter  data_width = 8;
   parameter  ram_depth = 256;
   localparam  addr_width = clogb2(ram_depth);
   input  [addr_width - 1:0] address;
   input  write, chip_select;
   inout  [data_width - 1:0] data;
  //define the clogb2 function
   function integer clogb2;
     input  [31:0] value;
     begin
      value = value - 1;
       for  (clogb2 = 0; value > 0; clogb2 = clogb2 + 1)
         value = value >> 1;
     end
     endfunction
     reg  [data_width - 1:0] data_store[0:ram_depth - 1];
     //the rest of the ram model
endmodule

该 ram_model 的例化格式(已分配参数)如下:

ram_model #(32,421) ram_a0(a_addr,a_wr,a_cs,a_data);

点赞加关注博主(ID:FPGA小飞)的博文,咱们一起系统学习verilog最终标准IEEE Std 1364-2005吧!

  • 15
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值