静态和自动变量

静态和自动变量

自动变量–也可以称为动态变量,主要是用来描述在测试程序、抽象系统级、交易级或总线功能模型中的验证程序。自动变量的另一个用途就是编写可重入的任务,当一个任务的前一次调用仍然在执行时,可以再次对其调用。
自动变量也允许编写递归函数–函数调用其自身。含有自动变量的任务或者函数的每次调用,都建立新的变量储存空间,当访问结束后,空间被释放。

function automatic int b_add (int lo,hi);
	int mid = (lo + hi + 1) >> 1;
	if(lo + 1 != hi)
		return (b_add(lo,(mid - 1)) + b_add(mid,hi));
	else
		return (array[lo] + array[hi]);
endfunction

在Verilog中,通过声明整个任务或者函数是自动的,来声明自动变量。自动任务或函数中的所有变量都是动态的。
SystemVerilog加入了静态和自动变量声明
SystemVerilog增加了声明静态和自动变量的能力。SystemVerilog增加了一个static关键字,允许任何变量被显性地声明为static或者automatic。这个声明时变量声明的一部分,可以出现在任务、函数、begin …end块或者fork…join块中。注意在module一级声明的变量不能显示声明为static或者automatic。在模块级,所有变量都是静态的。

//在一个静态函数中显式地声明自动变量
function int count_ones (input [31:0] data);
	automatic logic [31:0] count = 0;
	automatic logic [31:0] temp = data;
	for (int i = 0; i <= 32 ; i++)
	begin
		if(temp[0]) count ++;
		temp >> 1;
	end
	return count;
endfunction
//在一个自动任务中显式地声明一个静态变量
typedef struct packed{...} packet_t;
 	task automatic check_results
	(input packet_t sent, received,
	output int total_errors
	);
	static int error_count;
	...
	if(sent !== received) error_count++;
	total_error = error_count;
endtask

在模块、begin…end块、fork…join块以及非自动的任务和函数中,所有的储存方式都缺省为静态的,除了被显式地声明为动态的。如果一个任务和函数被声明为自动的,则所有的储存方式默认为自动的,除非被显式地声明为静态的。

静态变量和自动变量的初始化
Verilog变量的内嵌(in-line)变量初始化
Verilog只允许在模块级声明进行内嵌初始化,在任务、函数、begin…end块及fork…join块中声明的变量不能在声明时志初始值。
SystemVerilog的内嵌初始化
初始化静态和自动变量
SystemVerilog对Verilog进行了扩展,在任务、函数声明的变量可以有内嵌初始值。
在非自动任务和函数声明的变量默认是静态的。内嵌初始值将在仿真开始前进行一次赋值。对任务或者函数的再次调用不会重新初始化变量。

注意:在任务或函数中初始化静态变量是不可综合的,可能在某些工具中不支持

静态变量只初始化一次

//在一个静态函数中显式地声明自动变量
function int count_ones (input [31:0] data);
	 logic [31:0] count = 0;  //只初始化一次
	 logic [31:0] temp = data; //只初始化一次
	for (int i = 0; i <= 32 ; i++)
	begin
		if(temp[0]) count ++;
		temp >> 1;
	end
	return count;
endfunction

自动变量每次调用时都只初始化
在非自动任务和函数中显式地声明为自动的变量在每次任务和函数调用时都会动态地创建,调用完毕会动态地释放。函数或任务每次调用都会对内嵌初始值赋值。

function int count_ones (input [31:0] data);
	automatic logic [31:0] count = 0;
	automatic logic [31:0] temp = data;
	for (int i = 0; i <= 32 ; i++)
	begin
		if(temp[0]) count ++;
		temp >> 1;
	end
	return count;
endfunction

在自动任务和函数声明的变量默认是自动的。每次进入任务和函数时,都会为变量动态地创建储存区,调用完毕释放。每次调用任务或函数时,内嵌初始值都会被赋值。

如果想使硬件模型中的自动变量是可综合的,则它只能用于表示暂时储存–不会传送到任务、函数或过程块的外部。

注意:静态变量初始化是不可综合的,动态变量初始化是可综合的。
用const限定词声明的变量的内嵌初始值也是可综合的

静态和自动变量的使用原则
(1)在always和initial块中,如果无内嵌初始化则使用静态变量,而需要内嵌初始化的使用自动变量。使用带内嵌初始化的变量,所表现的行为最直观,因为过程块每次被重新执行,自动变量都会重新初始化。
(2)如果一个任务和函数会是可重入的,则应该设成自动的。变量也应该是自动的,除非有特殊的原因需要在两次调用之间保持变量的值。一个简单的例子,如果需要用一个变量来记录任务或者函数被调用的次数,则这个变量应该是静态的。
(3)如果一个任务和函数用来描述硬件的独立部分,并且不是可重入的,那么应该把它声明为静态的,任务和函数中的所有变量也应该是静态的。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

傻童:CPU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值