1、概念域:
硬件世界:module-endmodule 、interface-endinterface
软件世界:program-endprogram、class-endclass
initial的使用域:initial过程块可以在module、interface和program中使用,对于过程块的书写用begin-end包裹住
always的使用域:always过程块的是用来描述硬件时序电路和组合电路的正确打开方式,因此只可以在module或者interface中使用
2、函数function
function可以在参数列表中指定input、output、onout和ref,可以返回数值后者不返回数值(void)
3.方法task
task无法通过return返回结果,只能通过output、inout或者ref的参数来返回,task可以内置耗时语句,而function却不可以,常见的耗时语句有@event、wait event 、#delay等等
函数function | 任务task |
不消耗仿真时间 | 消耗仿真时间 |
函数中不可以有控制仿真时间的语句 | 任务中可以有仿真时间的控制语句 |
可以通过return语句进行返回,如果不需要的话可以将函数设置为void类型 | 任务没有返回值,一般通过output信号直接输出 |
函数中至少包含一个参量进行传参 | 任务中可以没有输入输出 |
函数的调用可以以语句的一部分出现 | 任务的调用通过单独的一句话实现 |
函数可以调用函数,但是不能调用任务 | 任务可以调用任务也可以调用函数 |
4、子程序返回
Verilog必须有返回值,返回值通过函数名的赋值来完成,SV通过return语句实现一个返回值,如果返回的个数为多个的时候通过output来返回各种数值。但是需要注意的是通过return返回的的数值为非void型,通过return返回的数值为void型。
分析:声明一个自定义结构,但是三个变量都没有声明是什么类型,所以默认是input类型,所以当s赋值给t的时候,t是一个input类型,就会赋值失败。
5、动态数据和静态数据
如果数据被声明为automatic,那么进入该进程/方法的时候automatic变量会被创建,离开该该进程/方法的时候变量会被销毁,而static变量在仿真时候就会被创建,在进入进程/方法的时候,自身不会被销毁,而且可以被多个进程和方法所共用。
对于automatic方法,其内部的所有变量默认也是automatic,即伴随automatic方法的生命周期建立和销毁。 |
对于static方法,其内部的所有变量默认也是static类型。对于static变量,用户在声明变量时应该同时对其做初始化,而初始化只会伴随它的生命周期发生一-次,并不会随着方法调用被多次初始化。 |
对于automatic或者static方法,用户可以对其内部定义的变量做单个声明,使其类型被显式声明为automatic或者static。 |
在module、program、 interface、 task和function之 外声明的变量拥有静态的生命周期,即存在于整个仿真阶段,这同C定义的静态变量一致。 |
在module、interface和program内部声明, 且在task、 process或者function外部声明的变量也是static变量,且作用域在该块中。在module、program和interface中定义的task、 function默认都是static类型。 |
在过程块中(task、 function、 process) 定义的变量均跟随它的作用域,即过程块的类型。如果过程块为static, 则它们也默认为static,反之亦然。这些变量也可以由用户显式声明为automatic或者satic |
6、高级参数类型:
ref参数类型一般比以往的更好用,参数传递方式可以指定为引用而不是赋值;ref参数在任务里可以修改变量而且修改结果对调用他的函数是随时可见的。
const限定符限定了指针指向的内容是不可修改的,可以防止在task或者function中内部修了某个参数
7、时间值
时间单位和精度:和'timescale相比timeunit和timeprecision声明语句可以明确地为每个模块指明时间值。
时间参数:$timeformat可以使得代码在时间标度上更加清楚,$timeformat的四个参数分别为时间标度、小数点后的数据精度时间值之后的后缀字符串、显示数值的最小宽度
时间和变量:time类型的变量不能保存小数时延,real变量可以保存精确的数值