在Verilog中,所有数据类型都是 4 值的,即可以表示 0、1、X 和 Z。但是,在 test benches 的中,不需要这些4态变量。例如,要计算数据包的数量,我们需要一个 2 值变量。因此,System Verilog 引入了一类新的 2 值变量,即 0 和 1。
数据类型列表
序号 | 数据类型 |
---|---|
1. | 4值类型 |
2. | 2值类型 |
3. | 数组 |
4. | 字符串 |
5. | 结构体和联合体 |
6. | 枚举 |
7. | 自定义类型 |
1. 有符号和无符号数字#
无符号数:无符号数的符号不使用任何标志,即无符号数只能存储正数。
无符号二进制数的范围从 0 到 ((2^n) - 1)
,n 表示位数。
有符号数:通过有符号数中的符号标志来区分正值和负值。有符号位的零有两种可能表示形式(正 (0) 和负 (1))。
有符号二进制数的范围从 -2^(n-1)
到 2^(n-1)-1
,n表示位数。
有符号二进制数在计算机系统中,一般用补码来表示:
有符号二进制数的补码:
- 正数的补码:与原码相同。 例如,+9的补码是00001001。
- 负数的补码:符号位为1,其余位为该数绝对值的原码按位取反;然后整个数加1。 例如,-7的补码:因为是负数,则符号位为“1”,整个为10000111;其余7位为-7的绝对值+7的原码 0000111按位取反为1111000;再加1,所以-7的补码是11111001。
已知一个数的补码,求原码:
- 如果补码的符号位为“0”,表示是一个正数,所以补码就是该数的原码。
- 如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位为1,其余各位取反,然后再整个数加1
有符号数和无符号数的示例
考虑 3 位,即 n =3,
- 无符号范围
0 到 (2^(n) - 1),即 0 到 7
无符号位二进制数 | 十进制值 |
---|---|
000 | 0 |
001 | 1 |
010 | 2 |
011 | 3 |
100 | 4 |
101 | 5 |
110 | 6 |
111 | 7 |
- 有符号范围
-2^(n-1) 到 2^(n-1)-1,即 -4 到 3
有符号位二进制数 | 十进制数 |
---|---|
000 | 0 |
001 | 1 |
010 | 2 |
011 | 3 |
100 | -4 |
101 | -3 |
110 | -2 |
111 | -1 |
在上面的例子中,最高位为符号位,最高位为 0 表示正,1 则表示负。
对于上面的 100,1 是符号位,表示负。先对 00 取反得到 11,然后加 1 得到 100,即 4。所以有符号数 100 是 -4。
**4 值数据类型列表 **
序号 | 数据类型 | 2值/4值 | 位 | 有符号/无符号 |
---|---|---|---|---|
1. | reg | 4 | >=1 | unsigned |
2. | wire | 4 | >=1 | unsigned |
3. | logic | 4 | >=1 | unsigned |
4. | integer | 4 | 32 | signed |
5. | time | 4 | 64 | unsigned |
6. | real | 4 | 64 | unsigned |
2. 4 值类型#
下面的表格列代表 4 种不同的状态。
状态 | 描述 |
---|---|
0 | 状态 0 |
1 | 状态 1 |
x or X | 未知状态 (与 reg 有关) |
z or Z | 高阻态 (与 wire 有关) |
2.1 reg#
reg 变量用于对锁存器、触发器和存储器等存储元件进行建模,它存储一个值并用于程序赋值。 reg 的默认值为 x。 reg 只能在过程块中赋值。
语法 :
reg variable_name;
2.2 wire#
连线是一种 Verilog 数据类型,用于连接元件以及连接由单个门或连续分配驱动的网络。导线的默认值为 z。
语法 :
wire variable_name;
2.3 tri#
tri 与 wire 是相同的数据类型,只是名称不同。tri 类型可用于多个 driver 驱动一个 net 的情况。wire 或 tri 上来自多个相同强度源的逻辑冲突会导致 x 值。
2.4 Logic#
Logic 类型是 4 值类型,可以取值 0、1、x 和 z。Logic 类型,可以用来代替 wire 和 reg,因为 wire 数据类型没有多个 driver。默认情况下 Logic 类型是无符号的,其初始值为 x。Logic 类型可以在过程块和连续赋值语句中赋值。
语法 :
logic variable_name;
示例:
logic [2:0] logic_data_type;
logic_data_type=3'b101;
2.5 integer#
integer 是 4 态数据类型,integer 可以是 0,1,x 和 z,表示 32 位有符号数。integer 的默认值为 x。integer 可以保存范围从 -2^31 到 (2^31)-1 的值。
语法 :
integer variable_name;
示例:
integer integer_data;
integer_data = 32'b11x0_101x_1xz0_0111;
2.6 time#
time 是用于模拟时间测量的特殊数据类型。它是 4 值类型,表示 64 位无符号整数,可以与 $time 系统函数结合使用来保存当前的仿真时间。
语法 :
time variable_name;
示例:
time time_data;
time_data = $time;
2.7 real#
real 数据类型以 64 位实数实现。real 可以用十进制记数法 (如 4.43) 或科学记数法 (如 42e8) 指定。 real 数据类型的默认值为 0。
语法 :
real variable_name;
示例:
real real_data;
real_data = 4.43;
3. 2 值类型#
2 值数据类型列表
序号 | 数据类型 | 2值/4值 | 位 | 有符号/无符号 |
---|---|---|---|---|
1. | bit | 2 | >=1 | unsigned |
2. | byte | 2 | 8 | signed |
3. | shortint | 2 | 16 | signed |
4. | int | 2 | 32 | signed |
5. | longint | 2 | 64 | signed |
3.1 bit#
bit 可以是 0 或 1,代表单个位。bit 数据类型的默认值为 0。
语法 :
bit variable_name;
示例:
bit single_data;
bit [3:0] multi_bit_data;
3.2 byte#
byte 可以是 0 或 1,表示 8 位有符号整数。byte 的默认值为0。
语法 :
byte variable_name;
示例:
byte byte_data;
3.3 shortint#
shortint 可以是 0 或 1,表示 16 位有符号整数。 shortint 的默认值为 0。
语法 :
shortint variable_name;
示例:
shortint shortint_data;
3.4 int#
int 是 2 state 数据类型,最常用于 TestBench。int 可以是 0 或 1,表示 32 位有符号整数。 int 的默认值是 0。
语法 :
int variable_name;
示例:
int int_data;
3.5 longint#
longint 可以是 0 或 1,表示 64 位有符号整数。 longint 的默认值为 0。
语法 :
longint variable_name;
示例:
longint longint_data;
4. 数据类型转换#
转换意味着将一种数据类型转换为另一种数据类型。
4.1 静态转换#
静态转换 : 转换发生在编译时。因此,不会出现任何运行时错误。静态转换仅适用于固定数据类型。它不适用于面向对象的编程概念。
语法 :
data_type'(variable or expression or value);
- integer to int
示例:
int_data = int'(integer_data);
- shortint to int and longint
示例:
int_data = int'(shortint_data);
longint_data = longint'(shortint_data);
- int to longint
示例:
longint_data = longint'(int_data);
- real to int
示例:
int_data = int'(real_data);
- real to time
示例:
time_data = time'(real_data);
- logic to byte
示例:
byte_data = byte'(logic_data);
- bit to byte
示例:
byte_data = byte'(bit_data);
4.2 动态转换#
动态转换 : 转换发生在运行时。如果转换无效,则会报告错误。动态转换用于将分配的值转换为通常无效的变量。 $cast 是系统方法。 $cast 可以是函数或任务。
语法 :
$cast(destination_variable, source_expression_or_variable);
5. 枚举 enum#
枚举数据类型定义一组命名值。
语法 :
enum enum_base_type(optional) {
<enum_name_declaration> = constant_expr(optional)...
}<enum_type_identifier>;
示例:
enum {MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
} days;
- 除非指定为其他类型,否则枚举类型存储为“int”类型。
- 此类型会自动为列表中的每个名称赋予唯一值。
- 值默认为“int”类型,从 0 开始,然后递增 1。
- 如果没有为名称指定值,它将获取列表中前一个名称的值并加 1。
枚举函数:
序号 | 函数 | 描述 |
---|---|---|
1 | first() | 返回枚举的第一个成员的值 |
2 | last() | 返回枚举最后一个成员的值 |
3 | next() | 返回枚举的下一个成员的值 |
4 | prev() | 返回枚举中前一个成员的值 |
5 | num() | 返回给定枚举中的元素数量 |
6 | name() | 返回给定枚举值的字符串表示形式 |
typedef 枚举数据类型
在 typedef 中可以给出类型名称,以便可以在许多地方使用相同的类型。在 typedef 中可以给出类型名称,以便可以在许多地方使用相同的类型。
语法 :
typedef enum enum_base_type(optional) {
<enum_name_declaration> = constant_expr(optional)...
} <enum_type_identifier>;
示例:
typedef enum {MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
} week_e;
week_e day;
6. String#
字符串类型是可变长度的有序字符集合。字符串的长度是集合中字符的数量。
语法:
string variable_name =initial_value;
示例::
string str = "Manipal";
- 字符串的内存空间是动态分配的。
- 字符串变量的索引应从 0 到 N–1(其中 N 是字符串的长度)进行编号,以便索引 0 是字符串的第一个(最左边)字符,索引 N–1 是最后一个(最右边)字符字符串的。
- 未初始化或空字符串用特殊值 "" 表示。空字符串的长度为 0。
字符串运算符列表
操作 | 操作符 | 描述 |
---|---|---|
等于 | str1==str2 | 如果两个字符串相等则返回 1,否则返回 0 |
不等 | str1!=str2 | 如果两个字符串不相等则返回 1,如果相等则返回 0 |
比较 | str1 < str2, str1 <= str2, str1 > str2, str1 >= str2 | 如果相应条件为 true,则返回 1;如果为 false,则返回 0 |
级联 | {str1, str2, …, strN} | 所有字符串将连接成一个结果字符串 |
复制 | {N{str}} | 将字符串复制 N 次 |
索引 | str[index] | 返回一个字节,即给定索引处的 ASCII 代码。如果给定索引超出范围,则返回 0 |
字符串函数一览表
函数 | 描述 |
---|---|
str.len() | 返回字符串的长度。 |
str.putc() | 修改字符串的一个字符 |
str.getc() | 返回一个字符。 |
str.tolower() | 返回字符串的小写字母。 |
str.toupper() | 返回字符串的大写字母。 |
str.compare(s) | 以 ascii 值形式返回字符串比较结果。 |
str.icompare(s) | 以 ascii 值的形式返回不区分大小写的字符串比较结果。 |
str.substr(i,j) | 返回主字符串的子字符串。 |