相关文章
Verilog基础:表达式位宽的确定(位宽拓展)
Verilog基础:表达式符号的确定
Verilog基础:数据类型
Verilog基础:位宽拓展和有符号数运算的联系
Verilog基础:case、casex、casez语句
Verilog基础:casex和full_case、parallel_case的使用
Verilog基础:表达式中的整数常量(integer)
目录
4.function的声明和调用
4.1 function的声明
4.2 function的返回值
4.3 function的调用
4.4 function的规则
4.5 常数函数
function的用途就是返回一个值,然后把他用在表达式中(即作为操作数使用)。
function的声明的语法如下:
function声明的说明:
1、第一种是Verilog-1995的语法,输入参数和函数内项目都在function_identifier;后面声明。
2、第二种是Verilog-2001的语法,输入参数在function_identifier();括号内部声明,而函数内项目在function_identifier();后面声明,这是ANSI-C风格的声明。
3、函数内项目包括各种类型的变量(reg[signed]、integer、time、real、realtime)、事件声明、本地参数声明和参数声明。
4、没有使用automatic的function是静态的(Static),所有在function中声明的输入参数和函数内项目都是静态分配内存的,对于所有并发执行的同一个function,他们是共享的。
5、使用automatic的function是动态的,可重入的,仿真器为每个并发执行的function动态地分配内存。
6、function_range_or_type用于声明返回值的类型,它是可选的。如果没有说明,那么默认返回1位标量;如果说明,则返回值的类型可以是:[range][signed]、integer、time、realtime、real。
7、function应至少有一个input参数。
在定义function时,同时在function内部隐含地声明了一个和function名字一样的变量。他默认是1位的reg,或是用function_range_or_type指定的。当function返回时,就把这个变量返回。
函数调用被当做表达式中的操作数使用。函数调用时,输入参数的计算顺序是不定的。
与task相比,function有许多限制,下面是function的使用规则。
1、function的定义不能包含任何时序控制的语句,即不能包含#、@和wait。因为function的参数输入,计算、返回都是在一个time-step完成的。
2、function不能使能task,因为task中可能含有时序控制。
3、function至少包含一个input参数。
4、function不能包含任何output和inout参数。
5、function中不能使用非阻塞赋值(<=),不能使用过程连续赋值。
6、function内不能触发命名事件。
常数函数是Verilog-2001标准新加的,用于在elaboration时计算复杂的的值。常数函数要求综合和仿真工具在编译时就计算出函数的返回值。
常数函数对IP开发非常重要,目的是允许设计人员为一个模块添加local parameters,这些local parameters是在模块实例化时传递的参数得来的。
让我们考虑一个简单的RAM模型,为了使这个模型参数化,我们需要地址的宽度、存储的深度和数据的宽度。数据的宽度必须传递给模型,但对于地址的宽度和存储的深度,就只需要传递一个即可。如果传递地址的宽度,那么存储的深度可以通过常数函数计算出来;如果传递存储的深度,则地址的宽度可以通过常数函数计算出来。
为了让工具厂商更加接受常数函数,Verilog标准化组织(Verilog Standard Group,VSG)在常数函数上加了明显的约束,而在常规函数上就没有这些约束。常数函数是常规函数的子集,具有以下的要求。
1、常数函数不能包含层次引用。
2、常数函数在调用模块内定义,且参数是常数。
3、常数函数能调用参数为常数表达式的系统函数,而不能调用其他系统函数。
4、常数函数将忽略系统任务。
5、任何常数函数会使用到的parameters都要提前定义。
6、常数函数使用的parameters不能直接或间接被defparam影响。
7、不能在generate块中声明常数函数。