SystemVerilog学习笔记4 ---《变量范围、lifetime、static和automatic》

先明确下基本的概念

  • block:块。一些关键字组成的一个范围区间,就叫做块。如 module … endmodue / task … endtask / begin … end / fork … join
  • static lifetime:存活于整个仿真过程

1. 变量的范围(scope )

  • module、interface、program、checker都提供了一个本地(local)的命名空间用于变量的声明。不同 block中命名同名的变量并不会冲突。
  • 通过在building block中import package,可以共享package的声明空间(declaration space)。
  • 引用一个变量时,会一层层往上找,找不到就会出错,找得到就没问题,但是可能想要的层次不对。
  • 声明在module、program、interface、checker、task、function块外的变量的范围覆盖整个编译单元,即全局

【1】 下图中有四处声明了变量“a”并赋值,在begin…end块中,找到了a,故打印结果为1
在这里插入图片描述

【2】注释掉initial块中的声明,则在begin…end外围,my_top内查找变量a,故打印结果为2(可以看到my_top块中的声明的优先级是高于package中的
在这里插入图片描述

【3】 注释掉module中的声明,则找到了package,故打印结果为3
在这里插入图片描述

【4】 注释掉package中的声明,结果报错,显示找不到a,这说明了两个module中的变量是不相关的
在这里插入图片描述

【5】在块的外围声明变量int a=5;发现打印结果为5。
在这里插入图片描述

2. 变量的声明周期(lifetime)

  • 声明在module、program、interface、checker、task、function块外的变量的范围可以到整个编译单元,并且是static lifetime
    例如上例5
    对,你没看错,checker ... endchecker也是一个block
  • 声明在module、program、interface、checker内,但是在task、process(begin…end等)、function外的变量,是局部范围,并且是static lifetime
    例如上例2
  • 声明在 static task、function、block的变量是局部范围的。default to static lifetime,其中的变量可以被automatic关键字显示地声明,那么将 have the lifetime of the call or block(随用随生成)
  • 声明在 automatic task、function、block的变量是局部范围的。default to the lifetime of the call or block。其中的变量默认为automatic,但是可以被关键字static显示地声明,则have a static lifetime

2.1 总结

(1) scope和lifetime主要看变量在哪个“块”中声明,如果不在module、program、interface、checker、task、function中声明,则就是在最外层,所以范围就是全局的,是static lifetime
(2) 如果在module、program、interface、checker内,但是是在这些块中的task、function、process块外的,范围是局部的,是static lifetime
(3)在task、function、block中的则范围是局部的。lifetime默认与这些块是static/automatic一致,但是也可以对变量进行加static/automatic关键字进行显示声明,则lifetime与申明时加的关键字一致。

2.2 一个例子

在这里插入图片描述

3. 变量的初始化

  • static变量在整个仿真时间内存在,所以static变量只会在仿真初期进行一次初始化。
  • automatic变量是随时调用随时产生,所以每次调用时就会执行初始化
    在这里插入图片描述

4. 变量的存储

  • static变量是静态分配的,被存放在固定位置
  • automatic变量被存储在堆栈中
  • 当多个线程调用同一个任务中的静态变量时,由于静态变量使用静态存储区,所以不同线程之间会串用这些静态变量

【程序1说明】 下图中 task show()默认为static,repeat(5)时,共调用五次,起了五个线程,但是每个线程都阻塞在wait(a==6);不会有打印。继续往下执行,#10后,再起一个线程,此时传入给task show()的a的值为6。调用的6次show()中,因为show()为static,所以show()中的a为static,为同一静态存储区,所以前面五个线程现在a也为6了,故会打印6次。
所有调用static show()函数的线程,show()函数中的a都是同一个。
在这里插入图片描述

【程序2说明】 当将program声明为program automatic my_program;(或者声明 task automatic show(input int a); ),则为automatic,6个线程中的a为不同的存储区。故只有最后一个会打印,前面5个线程会一直阻塞在wait(==6);但整个initial 已经到底了,故仿真自动结束了。
所有调用automatic show()函数的线程,show()函数中的a都是独立的
在这里插入图片描述

5. for循环的循环变量

  • for循环中的循环变量默认就是automatic。例如:在program 中声明的for循环,不管program是static还是automatic,for的循环变量都为 automatic。
    在这里插入图片描述
program my_program;
	initial begin
		for(int i=0,i<3;i++) begin   //i为automatic
			automatic int k = i;     //k为automatic,所以 automatic才能赋值给automatic
			...
		end
	end
endprogram
program automatic my_program;
	initial begin
		for(int i=0,i<3;i++) begin   //i为automatic
			int k = i;     //k为automatic,所以 automatic才能赋值给automatic
			...
		end
	end
endprogram
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值