System Verilog 引进的新的数据类型,他们所具有的优点:
1. 双状态数据类型(bit, byte, shortint, int, longint):具有更好的性能,更低的内存消耗。
2. 队列(int a[$]),动态数组(int a[]),关联数组(int a[string]):减少内存消耗,且自带搜索和分类功能。
3. 类(class)和结构(struct):支持抽象的数据结构。
4. 联合结构和合并结构:允许对统一数据有多种视图(view)。
5. 字符串(string):支持内建的字符序列。
6. 枚举类型(enum):方便代码编写,增加代码可读性。(工程实践中经常使用)
1
思维导图
2
思维导图大纲
定宽数组
Verilog 中的定宽数组
Verilog-1995 只有一维定宽数组
Verilog-2001 引入多维定宽数组
声明和初始化
便捷声明方式:SV允许只给出数组宽度
int array[0:15];
int array[16];
多维定宽数组
通过在变量名后指定维度来创建
int array[0:7][0:3];
Verilog-2001 引入多维定宽数组
int array[8][3];
SV 引入的紧凑型声明
从越界地址处读取数据将得到缺省值
双状态数据类型缺省值:0
四状态数据类型缺省值:X
注:线网在没有驱动时输出为 Z
适用于所有数组类型,及地址中含有X或Z的情况,见示例1
定宽数组
动态数组
关联数组
队列
SV仿真器常使用32bit字边界存放数组元素
byte、shortint、int存放在一个字中
longint存放在两个字中
在非合并数组中,字的低位用于存放数据,高位不使用
SV 仿真器通常使用两个或两个以上连续的字来存放 logic 和 integer 等四状态类型,比存放双状态变量多占用一倍的空间。
常量数组
使用单引号和大括号来初始化数组
int array[4] = '{0,1,2,3};
array = '{4{8}};
array = '{default:1};
array = '{9, 8, default:1};
编译不通过,见示例2。
基本数组操作
for
与 C 语言使用方式一致
foreach
只需指定数组名并在数组名后的方括号中给出索引变量,SV 将自动按序遍历数组中所有的元素
foreach ( array[i] )
foreach ( array[i, j] )
自动声明索引变量i, j 且只在循环内有效
foreach 会遍历原始声明中的数组范围
对于数组 aa[6 : 2],foreach(aa[i]) 语句等同于 for(int i = 6; i >= 2; i--),见示例3。
$size(array): 返回数组宽度
在不使用循环情况下聚合比较和复制
聚合操作适用整个数组而不是单个元素
dst = src
比较只限于 等于或不等于 比较
(src[1:4] == dst[1:4] )? 1:0;
src[1:4]和dst[1:4]相当于产生了临时数组进行比较,见示例4
同时使用位下标和数组下标
工程实践中常用
合并数组
声明时,合并数组的位和数组大小作为数据类型的一部分必须在变量名左侧指定
合并数组既可以用作数组,也可以当成单独的数据
合并数组存储时是连续的比特集合,中间无空闲空间
bit [3:0][7:0] bytes;
四字节合并数组
一个字存放
可以混合使用合并与非合并数组
bit [3:0][7:0] bytes[3];
带三个合并数组的非合并数组
两个合并数组之间进行复制时,由于操作是以bit为单位进行的,所以数组维度不同也可以进行复制
bit [3:0][7:0] bytes;bit [7:0][3:0] bytes_n,见示例5
合并数组和非合并数组选择
当需要和标量进行相互转换,合并更优
任何数组都可以进行合并
@操作符只能用于标量或合并数组,即无法将非合并数组用于敏感信号
3
示例
例1:
[0 : 7] 为正序,[7 : 0] 为逆序。
越界访问返回缺省值,双状态数据类型返回0,四状态数据类型返回x,打印如下。
例2:
18 行报错如下。
例3:
未赋初值的数组默认值为 0 或 x。
foreach 会遍历原始声明中的数组范围,例子中对于数组 aa[6 : 2],foreach(aa[i]) 语句等同于 for(int i = 6; i >= 2; i--),打印如下。
例4:
划分数组时需要与声明时顺序一致,例如当划分 bb[0:1] 时,将无法通过编译。
数据比较必须是相同类型,不同类型即使值相同也不能通过编译,例如 aa 和 cc ,报错如下。
例5:
不同类型之间进行赋值,不会报编译错误,将进行隐式类型转换,打印如下。
领取专属 10元无门槛券
私享最新 技术干货