一般来说,每个类实例都有它自己的变量,也就是说类的内存空间是动态分配和释放的。同一个类的不同实例,即使变量名称相同,实际上也是不同的东西。
有时候,我们希望一些变量在一个类的所有实例中共享,那么在声明这个变量时就需要使用关键字static。
可以理解为静态属性隶属于这个类,而不是某个类的实例,这个静态属性的内存空间在编译时就已经完成了分配,而不需要等待类的实例化。
静态属性内存空间的分配在仿真时间0之前就已经完成了。
下面是一个在不同类实例之间共享的静态属性示例
module class_top( ); class base; static logic [31:0] data; //static property endclass : base base base1, base2; initial begin; base1 = new( ); base2 = new( ); base1.data = 32'h f00_f0f0; $display(base2.data = %h,base2.data); end initial #10 $fnish(2); endmodule
在这个例子中,我们将“data”声明为静态属性。然后,实例化为 base1 和 base2 。然后我们赋值“base1”实例中的“data”的值,并从“base2”实例访问。
仿真log:
base2.data = ff00f0f0$fnish at simulation time 10 v c s s i m u l a t i o n r e p o r t
从仿真log中可以看出,使用对象句柄“base1”赋值的属性,可以通过句柄“base2”访问到。这是因为“data”被声明为static,被所有实例共享。
如果把“static”去掉会发生什么?最终句柄“base2”访问的“data”值就是“xxxxxxxx”
下面是类中静态属性的最经典用法,统计这个类实例化了多少次?
module class_top( ); class packet; static int packet_cnt; function new( ); packet_cnt = packet_cnt+1; $display(from new ( ) :: packet_cnt = %0d,packet_cnt); endfunction endclass initial begin packet p1 = new; packet p2 = new; end endmodule
仿真log:
from new ( ) :: packet_cnt = 1from new ( ) :: packet_cnt = 2 v c s s i m u l a t i o n r e p o r t
在第二次实例化时,packet_cnt会在第一次实例化的基础上加1.
下面是展示静态属性和动态属性区别的一个例子:
class pcie;static int addr = 0; //static propertyint data = 0; //dynamic propertyfunction new ();addr++;data++;$display (addr=%0d data=%0d, addr, data);endfunctionendclassmodule tb;initial beginpcie p1, p2, p3;p1 = new ();p2 = new ();p3 = new ();endendmodule
仿真log:
addr=1 data=1addr=2 data=1addr=3 data=1 v c s s i m u l a t i o n r e p o r t
我们可以看到addr被声明为static,而data默认是automatic。所以每一次实例化时,addr都会在前一个实例化的基础上加1,而data则每次都是1(因为每个实例化都有自己的data内存分配)
下面再看一个相对绕一点的例子:
module class_top( ); class packet; static int packet_cnt; //static property int tag; //dynamic property function new( ); packet_cnt = packet_cnt+1; tag = packet_cnt; endfunction function void disp( ); $display(packet_cnt = %0d tag = %0d,packet_cnt, tag); endfunction endclass initial begin packet p1 = new; packet p2 = new; p1.disp; p2.disp; end endmodule
仿真log:
packet_cnt = 2 tag = 1packet_cnt = 2 tag = 2
我们在packet实例化两次(p1和p2)之后分别执行p1和p2的disp函数。
此时packet_cnt已经被加到2,所以最后打印的packet_cnt均为2,因为tag是automatic的,所以p1的tag为1,不被p2影响。
凌华科技发布网络安全平台CSA-7400,为行业提供了更稳定、可靠的解决方案
自动驾驶的芯片快速进入领域布局
什么是保护接地与保护接零?家用电器怎样才能不触电?
发光二极管工作原理 发光二极管正负极判断
7000美元!雄伟霸气的Optimus酒架
SystemVerilog中的静态属性
有人物联网参加中国国际工业博览会
固态电池的盈利前景巨大 但未来的路还需要时间磨练
万物皆可ChatGPT ChatGPT的iPhone时刻已到 ChatGPT概念厂商概述
奥飞声学刘端:回皖创业,用创新推动MEMS市场
宽带上网经常掉线是为什么,这其中有许多原因造成
世界顶尖高校博士人才到访比亚迪深圳全球总部
串口屏解决方案:大彩串口屏在电梯行业上的应用
诺基亚后置五摄怪兽级拍照手机开始发货,曝国行售价3599元
高压连接器的技术趋势以及市场预测
Google Flutter如何助力字节跳动跨平台开发
华为云桌面实现灵活云上办公、降本增效
榜上有名!望繁信科技荣登2023中国最具商业潜力榜
中兴Axon10Pro5G版王者荣耀下载速度实测视频公布 峰值速度接近120MB/s
在炼焦炉无线监控系统中GPRS无线通讯模块的应用介绍