Verilog之function使用说明

来源:互联网 发布:淘宝新政策 编辑:程序博客网 时间:2024/06/06 04:01


1.function的定义

<span style="font-size:14px;">function [range] function_name;     input_declaration     other_declarations     procedural_statement endfunction</span>
(1)函数通过关键词 function 和 endfunction 定义;

(2)不允许输出端口声明(包括输出和双向端口) ;但可以有多个输入端口;

(3)[range]参数指定函数返回值的类型或位宽,是一个可选项,若没有指定,默认缺省值为宽度 1 比特的寄存器数据

(4)function_name为所定义函数的名称,对函数的调用也是通过函数名完成的,并在函数结构体内部代表一个内部变函数调用的返回值就是通过函数名变量传递给调用语句。函数定义在函数内部会隐式定义一个寄存器变量,该寄存器变量和函数同名并且位宽也一致。函数通过在函数定义中对该寄存器的显式赋值来返回函数计算结果

(5)input_declaration 为各个输入端口的位宽和类型进行说明,在函数定义中至少要有一个输入端口


注意事项:

(1)函数定义只能在模块中完成,不能出现在过程块中;

(2)函数至少要有一个输入端口;不能包含输出端口和双向端口;

(3) 在函数结构中, 不能使用任何形式的时间控制语句 (#、 wait 等) , 也不能使用 disable中止语句;

(4)函数定义结构体中不能出现过程块语句(always 语句);

(5)函数内部可以调用函数,但不能调用任务

2.函数的调用

    func_name(expr1, expr2, ........., exprN),

    expr1, expr2, ......exprN是传递给函数的输入参数列表,该输入参数列表的顺序必须与函数定义时声明其输入的顺序相同.


  在函数调用中,有下列几点需要注意: 
  (1)函数调用可以在过程块中完成,也可以在 assign 这样的连续赋值语句中出现。 
  (2)函数调用语句不能单独作为一条语句出现,只能作为赋值语句的右端操作数

     如果task或者function在不同地方并发调用,则它们使用同一组变量个内存地址,存在冲突产生错误。为避免错误,声明时在task和function后面加上automatic 关键字。如:task automatic task_id ........ endtask

调用例子:

在过程语句always模块内调用,

`timescale 1ns / 100psmodule lfsr (clk, ena, nReset, rst, q);//// parameters//parameter [3:0] TAPS   = 8;                // number of flip-flops in LFSR//// inputs & outputs//input clk;                                 // master clockinput ena;                                 // clock enableinput nReset;                              // asynchronous active low resetinput rst;                                 // synchronous active high resetoutput [TAPS:1] q;                         // LFSR outputreg [TAPS:1] q;//// Module body//function lsb;   input [TAPS-1:0] q;   case (TAPS)       2: lsb = ~q[0];       3: lsb = q[3] ^ q[2];       4: lsb = q[4] ^ q[3];       5: lsb = q[5] ^ q[3];       6: lsb = q[6] ^ q[5];       7: lsb = q[7] ^ q[6];       8: lsb = q[8] ^ q[6] ^ q[5] ^ q[4];       9: lsb = q[9] ^ q[5];      10: lsb = q[10] ^ q[7];      11: lsb = q[11] ^ q[9];      12: lsb = q[12] ^ q[6] ^ q[4] ^ q[1];      13: lsb = q[13] ^ q[4] ^ q[3] ^ q[1];      14: lsb = q[14] ^ q[5] ^ q[3] ^ q[1];      15: lsb = q[15] ^ q[14];      16: lsb = q[16] ^ q[15] ^ q[13] ^ q[4];   endcaseendfunctionalways @(posedge clk or negedge nReset)  if (~nReset)q <= #1 0;  else if (rst)q <= #1 0;  else if (ena)q <= #1 {q[TAPS-1:1], lsb(q)};endmodule



0 0