SystemVerilog的类型和数据类型(三)

  1. 如果一个多位的变量,要把它赋值全0,其实很容易,但是如果赋值全1,在verilog中必须要把所有位都要写全;但是在SystemVerilog中增强了该功能,不用指定进制就可以给所有位赋予相同的值。
// Verilog中必须全部写齐,如果位宽是参数,可以在例化的时候修改,那么就更麻烦了
wire [63:0] data1;
assign data1 = 64'hffff_ffff_ffff_ffff;
wire [127:0] data2;
assign data2 = 64'hffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff;
// 将data的所有位都赋予1,反引号后面是1
assign data = '1;
  1. SystemVerilog中的信号同时具有类型和数据类型。类型表示信号是线网还是变量,SV使用所有的Verilog变量类型,如reginteger(这两个有四态逻辑0,1,x,z),并且还增加了一些其他变量类型byteint(这两个是两态逻辑0,1),SV没有对Verilog的线网类型进行任何扩展。数据类型表示线网和变量的值的类型也就是有两态逻辑还是四态逻辑所有的线网类型只能是四态类型

下面这些是两态类型:

  • bit —— 1位两态整数
  • byte ——8位两态整数
  • shortint ——16位两态整数
  • int ——32位两态整数
  • longint ——64位两态整数
    当两态或四态数据类型
  1. 最常用的bit和logic,其实并不是变量类型,它们只是一个数据类型,表示信号具有两态逻辑还是四态逻辑。通常情况下,直接使用bit或logic,会默认认定它们是变量(类似于reg),也就叫隐式声明。但是也可以对它们进行显示声明,可以将他们显示声明为线网或者变量。
// 隐式声明,推断出一个四态和两态数据类型的变量
logic [63:0] addr1;
bit [63:0] addr2;
// 显示声明为变量
var logic [63:0] addr1;
var bit [63:0] addr2;
// 显示声明为线网
wire logic [63:0] addr1;
wire bit [63:0] addr2;
  1. 仿真时的初始值注意项:四态逻辑的变量,如reg,logic和integer的所有位缺省为逻辑值X,这些变量认为没有被初始化,直到赋值给变量第一个值之前它们的值都是不确定的。但是所有的两态逻辑变量的缺省值是0。给一个两态变量赋四态值是合法的,四态类型任何位的X或Z值赋给两态变量时对应位会转化为0。注意:综合后不能保证两态类型上电后是0。

  2. 在Verilog中,变量reg只能使用initial和always来赋值。但是SystemVerilog中的变量logic和bit可以在initial,always,always_comp,always_ff,always_latch,assign和模块/原语的output、inout端口。

  3. SystemVerilog变量缺省的存储方式完全向后兼容于Verilog。在module,begin end,fork join以及非自动的任务和函数中,所有变量的存储方式都缺省为静态的,除非被显示的声明为动态的。如果一个任务和函数被声明为自动的,则所有变量的存储方式默认为自动的,除非被显示的声明为静态的。

  4. Verilog只允许在模块级声明的变量进行内嵌初始化,在任务,函数,begin end,fork join中声明的变量不能在声明时赋初始值。SystemVerilog对Verilog进行了扩展,在任务,函数声明的变量可以有内嵌初始化。在非自动任务和函数中声明的变量默认是静态的。内嵌初始值在仿真开始前进行一次赋值。对任务函数的再次调用不会重新初始化变量。下面函数中的两个变量都是静态变量,它们只会初始化一次,再次调用不会再初始化了,变量temp初始化的值是0,而不是data,因为初始化是在仿真开始前。在自动任务和函数中声明的变量默认是自动的。每次进入任务和函数时,都会为变量动态地创建存储区,调用完毕释放。静态变量赋初始值只用于仿真,比如模块级变量

function int count_ones(input [31:0] data);
	logic [31:0] count = 0;	// 只初始化一次,下次调用时不会再次初始化
	logic [31:0] temp = data;	// 只初始化一次,temp第一次初始化时为0,而不是data的值,
								// 这是因为内嵌初始化发生在仿真开始前,而不是发生在函数调用时。
	for(int i=0; i <= 32; i++) begin
		......
	end
endfunction
// 自动函数里的变量自动变成动态变量
function automatic int count_ones(input [31:0] data);
	logic [31:0] count = 0;	// 默认为自动变量
	automatic logic [31:0] temp = data; // 指定为自动变量
	for(int i=0; i <= 32; i++) begin
		......
	end
endfunction
  1. 自动变量和静态变量的综合和使用指导:
  • 自动变量的动态存储既可以用于开发测试平台,也可以用来做硬件设计。要使自动变量可以综合,则它只能用于表示暂时存储——不会传送到任务,函数或过程块的外部。
  • 静态变量初始化是不可综合的,动态变量初始化是可综合的。所以不要给模块级的变量赋初始值
  • 在always和initial块中,如果无内嵌初始化则使用静态变量,而需要内嵌初始化的使用自动变量。过程块每次被重新执行,自动变量都会重新初始化。
  • 如果一个任务或函数会是可重入的,则应该设成自动的,变量也应该是自动的。
  • 如果一个任务或函数用来描述硬件的独立部分,并且不是可重入的,那么应该把它设置为静态的,里面的变量也应该是静态的。
  1. Verilog标准明确的表明,多个initial过程块的仿真次序是不确定的。
// i的赋值和j的赋值顺序不确定,所以j有可能是5,有可能是X
integer i;
integer j;
initial begin
	i = 5;
end
initial begin
	j = i;
end
// 这段代码看上去好像i先被赋值了5,然后j赋值了5
// 但是由于赋值顺序不确定,所以j的初始值有可能是5,有可能是X
integer i = 5;
integer j;
initial begin
	j = i;
end
// 下面的代码可以确保i先赋值5,然后j再赋值5
integer i;
integer j;
initial begin
	i = 5;
	j = i;
end
  1. SystemVerilog增强了变量的内嵌初始化:SV规定了所有内嵌初始化在仿真0时刻之前进行并且变量内嵌初始化不引发仿真事件。这就保证了如果initial或always过程块读取具有内嵌初始值的变量时取得正确的初始值。这个确定性的行为消除了Verilog中的不确定问题。
// 计数器模块的testbeanch
module test
	wire	[3:0] 	count;
	bit 			clock;
	bit				reset_n = 1;	// 初始化为1,在仿真0时刻之前就执行
	// 例化计数器模块
	counter dut(clock, reset_n, counter);
	
	always #5 clock = ~clock;
	
	initial begin
		reset_n = 0;	// 仿真0时刻,能确保复位信号产生下降沿的跳变
		#2
		reset_n = 1;
	end
endmodule
  1. const可以使任何变量声明为常数的能力。const常数的声明必须包含数据类型。任何数据类型,包括枚举类型和用户自定义类型,都可以被指定为一个const常数。
const logic [23:0] C1 = 7;	// 24位常数
const int C2 = 15;			// 32位常数
const real C3 = 3.14;		// 实数常数 
const C4 = 5;				// 错误,没有数据类型
  1. 静态强制转换会强制将一个表达式变为新的类型,而对转换后的值是否是新的类型所规定的有效值不做任何检查。比如下面代码,State当前值若是YELLOW,那么State+1就会产生越界值,在静态强制转换的使用中这种越界值是不会被发现的。动态强制转换对正要转换的值执行运行期检查。如果值越界,会报告出错信息,而且目标变量的值不会变化。
typedef enum {RED, GREEN, YELLOW} state_t;
state_t State, Next;
Next = state_t`(State + 1);	// 静态强制转换
$cast(Next, State + 1);		// 动态强制转换
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值