SystemVerilog学习之路(2)— 内建数据类型
一、前言
SystemVerilog里的内建数据类型可以有两个分类,首先按逻辑数值类型分:
类别 | 可表示值 | 详细类型 |
---|---|---|
四值逻辑 | 0、1、X、Z | logic、reg、net-type(例如wire、tri)、integer |
二值逻辑 | 0、1 | bit、byte、shortint、int、longint |
如果按有符号类型分类,可分为如下所示,可以看到,除了integer
和bit
,和上面的分类是比较一致的
类别 | 详细类型 |
---|---|
有符号类型 | byte、shortint、int、longint、integer |
无符号类型 | bit 、logic、reg、net-type(例如wire、tri) |
另外对于不同的类型还有不同的矢量位宽,但是我们需要注意的是,对于四值逻辑变量,每一位是需要2个bit的存储位宽的。
位宽 | 详细类型 |
---|---|
1 | reg、logic、bit |
8 | byte |
16 | shortint |
32 | integer、int |
64 | longint |
二、符号类型
编写代码如下所示,我们分别声明三个8位的logic
、bit
和byte
类型的变量,然后将其值打印出来
module Hello;
logic [7:0] logic_val = 8'b1000_0000;
bit [7:0] bit_val = 8'b1000_0000;
byte byte_val = 8'b1000_0000;
initial begin
$display("@1: logic_val = %d", logic_val);
$display("@2: bit_val = %d", bit_val);
$display("@3: byte_val = %d", byte_val);
end
endmodule
仿真结果如下所示,因为bit
和logic
为无符号类型,所以最高位表示的也是有效值,所以他们的打印出来的值都为128
,然后byte
作为有符号类型,其最高位表示符号位,以补码表示其值即为-128
。
三、符号类型转换
编写代码如下所示,我们声明一个8位的有符号byte
类型的变量,一个9位的无符号bit
类型的变量,然后将8位有符号类型的变量赋值给9位无符号类型的变量,通过不同的赋值过程,然后将其值打印出来
module Hello;
byte signed_val = 8'b1000_0000;
bit [8:0] result_val;
initial begin
result_val = signed_val;
$display("@1: result_val = 'h%x", result_val);
result_val = unsigned'(signed_val);
$display("@2: result_val = 'h%x", result_val);
end
endmodule
仿真结果如下所示,首先通过result_val = signed_val
直接赋值方式的过程中,首先由于signed_val
为8位数据,会先转换为有符号的9位byte类型数据,有符号数进行位扩展,会在高位添1,即变为9'b1_1000_0000
,然后再赋值给9位无符号bit类型变量result_val
,由于result_val 为无符号类型,所以其打印值为9'h180
。
其次通过result_val = unsigned'(signed_val)
进行赋值的过程中,首先通过unsigned'()
转换为8为无符号数,其值即为8'h80
,然后再从8位到9位进行无符号数变量的位扩展,在高位添0,转换后其值为9'h080
。
上面result_val = unsigned'(signed_val);
语句中是进行了一次类型转换的,其转换方式称为静态转换
,即在需要转换的表达式前加上单引号即可,但该方式并不会对转换值做检查,有可能就会转换失败,所以与之对应的就有动态转换$cast(tag, src)
被经常用在转换操作中。静态转换和动态转换均需要操作符号或者系统函数的介入,所以都是显示转换
。静态转换如果出错会在编译时报错,而动态转换出错则要在仿真时才会报错。
而我们上面使用result_val = signed_val;
语句直接赋值的方式就属于隐式转换
。
四、值类型转换
编写代码如下所示,其中声明了一个4位的四值逻辑logic类型变量logic_val ,其值中有一位为x
即不定态,然后将其转换为3位的二值逻辑bit类型变量logic_val,分别打印其各自的值。
module Hello;
logic [3:0] logic_val = 'b111x;
bit [2:0] bit_val;
initial begin
$display("@1: logic_val = 'b%b", logic_val);
bit_val = logic_val;
$display("@2: bit_val = 'b%b", bit_val);
end
endmodule
运行仿真结果如下所示,可以看到,四值逻辑的x
转换为了二值逻辑的0
,事实上,对于四值逻辑里的x
和z
在转换为二值逻辑变量后都是为0
;