一、新的类型logic
SV语言将信号区分为“类型”和“数据类型”。
类型表示信号是变量或者线网。对于线网类型赋值只能用连续赋值语句(assign);而对于变量类型赋值可以使用连续赋值(assign)或者过程赋值(initial,always)。
数据类型则表示数据是四值逻辑还是二值逻辑。
SV语言相比于verilog语言,引入了新的类型logic,是一种无符号的四值逻辑类型,类型默认是变量,所以可以对其进行连续赋值(assign)或者是过程赋值(always,initial)。
但是当有多于一个驱动源的时候,或者设计模块端口是双向(inout)的时候用wire。
代码示例:
logic [2:0] a1;
logic [3:0] a2;
assign a1 = 5;
initial begin
$display("a1=%0d",a1);
end
initial begin
a2 = 10;
#1;
$display("a2=%0d",a2);
end
仿真结果:
a1=5
a2=10
二、二值逻辑和四值逻辑
SV语言还引入了二值逻辑(0和1),目的是将硬件和软件区分开。四值逻辑:0,1,x,z;二值逻辑:0,1。
四值逻辑类型:integer,logic,reg,net-type(例如wire)
二值逻辑类型:bit(1),byte(8),shortint(16),int(32),longint(64)
在仿真开始时,四值逻辑的初值是x,而二值逻辑的初值是0。 四值逻辑与二值逻辑的数据类型转换时,x和z会转换为0。
因为SV是更加注重验证的语言,所以有软件部分可以更好地进行仿真,比如在tb中需要模拟时钟信号,就可以使用二值逻辑的数据类型来模拟,因为时钟并不需要X和Z来驱动,这样可以减少占用内存。
代码示例:
logic [1:0] a1;//四值逻辑
bit b1;//二值逻辑
logic c1;//四值逻辑
bit d1;//二值逻辑
initial begin
$display("观察二者的仿真初值:a1=%0d,b1=%0d",a1,b1);
#10;
a1 = 2;
b1 = 1;
$display("观察二者赋值后的数值:a1=%0d,b1=%0d",a1,b1);
#10;
end
initial begin
d1 = 1;
$display("c1=%0d,d1=%0d",c1,d1);
#10;
d1 = c1;
$display("观察四值逻辑x转化为二值逻辑时数值:c1=%0d,d1=%0d",c1,d1);
end
仿真结果:
三、有符号和无符号
有符号类型:byte,shortint,int,longint,integer。
无符号类型:bit,logic,reg,net-type(例如wire)。
可以在有符号类型后添加unsigned来表示无符号类型,也可以在无符号类型后添加signed来表示有符号类型。
代码示例:
logic [7:0] a1 = 8'b1000_0000;
bit [7:0] b1 = 8'b1000_0000;
byte c1 = 8'b1000_0000;
initial begin
$display("a1=%0d,b1=%0d,c1=%0d",a1,b1,c1);
end
仿真结果:
a1=128,b1=128,c1=-128
四、静态转换和动态转换
静态转换:T'(src)
动态转换:$cast(t,src)
代码示例:
byte signed_vec = 8'b1000_0000;
bit [8:0] result_vec;
initial begin
result_vec = signed_vec ;
$display("1 result_vec = %0x",result_vec);
result_vec = unsigned'(signed_vec);
$display("2 result_vec = %0x",result_vec);
end
仿真结果:
1 result_vec = 180
2 result_vec = 80