转发自https://blog.csdn.net/qq_33332955/article/details/107641152
目录
1. 定宽数组
Verilog要求在声明定宽数组时必须给出数组的上下界。Systemverilog中声明定宽数组时允许只给出数组宽度的便捷声明方式。
1.1 定宽数组的声明和初始化
- 可以用一个单引号加大括号来初始化数组,在大括号前标上重复次数可以对多个元素重复赋值;
-
int ascend[4];
-
ascend = '{0,1,2,3};
-
-
int array[2][3];
-
array = '{'{0,1,2},'{3,4,5}};
- 可以在大括号前标上重复次数来对多个元素重复赋值;
-
int descend;
-
descend = '{5{8}};//descend五个元素都是8
- 可以为没有显示赋值的元素指定一个缺省值。
descend = '{9,8,default:1}; // {9,8,1,1,1}
1.2 Packed array(合并数组)
- 一维的packed array也被称为Vector;
- 一个packed array被表示为一个连续的位集合。
- 数组大小定义的格式必须是[msb:lsb],而不是[size]。
例如:
bit[2:0] [7:0] array5;
在存储时是连续的:
1.3 Unpacked array
很多SystemVerilog仿真器在存放数组元素时使用32bit的字边界,所以byte,shortint和int都是存放在一个字中,而longint则存放在两个字中。
- 可以是任意数据类型;
- 定义数组大小在名字之后;
- 在存储上bit组是不连续的的。
eg:
bit[7:0] array4[2:0] 或 bit[7:0] array4[3]
在存储时:
注:合并数组和非合并数组可以混用,例如:
bit[3:0] [7:0] barray[3]; //合并:3x32比特
2. 动态数组(new)
SystemVerilog提供了动态数组类型,可以在仿真时分配空间或调整数组宽度,这样在仿真中就可以使用最小的存储量。动态数组在声明时使用空的下标[ ]。
定义:data_type array_name[ ];
function:
- new[ ] ——> allocates the storage.
- size() ——> returns the current size of a dynamic array.
- delete() ——> empties the array, resulting in a zero-sized array.
-
int dyn[], d2[]; //声明动态数组
-
-
initial begin
-
dyn = new[5]; //分配5个元素的空间内存
-
foreach(dyn[j]) dyn[j] = j;//对元素进行初始化
-
d2 = dyn; //复制一个动态数组,这是d2会自动调用new函数
-
d2[0] = 5; //修改复制值
-
$display(dyn[0],d2[0]); //显示数字(0和5)
-
dyn = new[20](dyn); //分配20个整数值并进行复制
-
dyn = new[100]; //分配100个新的整数值,旧值不复存在
-
dyn = dyn.delete(); //删除所有元素,此时数组大小为0
-
end
注:只要基本数据类型相同,定宽数组和动态数组之间就可以相互赋值。
- 元素个数相同的情况下,可以把动态数组的值复制到定宽数组;
- 当你把一个定宽数组复制给一个动态数组时,SystemVerilog会自动调用构造函数new[ ]来分配空间并复制数值。
3. 队列
队列与链表相似,可以在一个队列中的任何地方增加或删除元素,这类操作在性能上的损失比动态数组小很多,因为动态数组需要分配新的数组并复制所有元素的值。
定义: data_type queue_name[$];
队列分为两种:
- 第一种是bounded queue,定义了队列的上界;
- 第二种是unbounded queue,没有定义上界。
-
bit queue_1[$]; // queue of bits (unbound queue)
-
int queue_2[$]; // queue of int
-
byte queue_3[$:255]; // queue of byte (bounded queue with 256 entries)
-
string queue_4[$]; // queue of strings
队列的feature:
- 队列与数组相似,可以通过索引实现对任意元素的访问。
- 队列的元素是连续存放的,所以在队列的前面或后面存取数据非常方便。
- 在队列中间增加或删除元素需要对已经存在的数据进行搬移以便腾出空间。
- 可以把定宽数组或者动态数组的值复制给队列。
-
int j = 1;
-
int q[$] = {3,4}; //队列的常量不需要使用单引号'
-
int q2[$]= {0,2,5};
-
-
initial begin
-
q.insert(1,j); //{0,1,2,5}在2之前插入1
-
q.insert(3,q2); //{0,1,2,3,4,5}在q中插入一个队列
-
q.delete(1); //{0,2,3,4,5}删除第一个元素
-
-
//下面的操作执行速度很快
-
q.push_front(6);//{6,0,2,3,4,5}在队列前面插入
-
j = q.pop_back; //{6,0,2,3,4} j = 5
-
q.push_back(8); //{6,0,2,3,4,8}在队列末尾插入
-
j = q.pop_front;//{0,2,3,4,8} j = 6
-
foreach(q[i])begin
-
$display(q[i]);
-
end
-
q.delete(); //{}删除整个队列
-
end
4. 关联数组
SystemVerilog提供了关联数组类型,用来保存稀疏矩阵的元素。这意味着当你对一个非常大地址空间进行寻址时,SystemVerilog只为实际写入的元素分配空间。
语法: data_type array_name[index_type];
- 将内容存储在稀疏矩阵;
- 关联数组只有在使用时才分配存储空间;
- 关联数组为数组元素分配一个查找表,其中索引作为键。
-
int a_array1[*] ; // associative array of integer (unspecified index)
-
bit [31:0] a_array2[string]; // associative array of 32-bit, indexed by string
-
ev_array [myClass]; //associative array of event,indexed by class
Methods:
ethod | Description |
---|---|
.num() | 返回元素个数 |
.delete(index) | 删除index索引的键和值,如果不加index则删除所有键和值 |
.exists(index) | 检查index键是否在数组中 |
.first(var) | 将第一个键赋给var |
.last(var) | 将最后一个键赋给var |
.next(var) | 将下一个键赋给var,如果后面没有键,则返回最后一个键 |
.prev(var) | 将上一个键赋给var,如果前面没有键,则返回第一个键 |
5. 数组的方法
Systemverilog提供了很多数组的方法,例如searching、ordering和reduction(缩减),这些方法可用于任何一种非合并的数组类型,包括定宽数组、动态数组、队列和关联数组。其中这些方法会遍历数组的所有元素,然后用这些值去计算with指定的表达式。
语法:expression.array_method_name {attribute_instance} [(iterator_argument)] [with(expression)]
eg:tq = d.find_first(x) with( x==4)//在这里tq是一个队列
注:区别于randomize方法中的with。
- iterator_argument:重复参数指定用于with表达式的变量名字,如果不指定,默认值是item。其中iterator_argument的作用范围是with expression。(注:只指定iterator_argument,不指定with expression是不允许的。)
- 在条件语句with中,item被称为重复参数,它代表了数组中一个单独的元素。
5.1 数组定位方法
想要在非合并数组中查找数据,可以使用数组定位方法,数组定位方法会搜索满足expression的数组元素或者数组索引,这些方法的返回值通常是一个队列。
- 关联数组的索引定位返回一个与关联索引类型相同的队列(关联数组的索引为统配字符时不能用索引定位的方法);
- 除关联数组以外的数组索引定位返回一个int类型的队列;
- 如果没有元素满足with表达式或者数组是一个空数组,则返回一个空队列。
数组支持以下定位方法,这些定位方法必须带有with表达式:
—— find() | 返回所有满足with表达式的元素 |
—— find_index() | 返回所有满足with表达式的元素索引 |
—— find_first() | 返回满足with表达式的第一个元素 |
—— find_first_index() | 返回满足with表达式的第一个元素索引 |
—— find_last() | 返回满足with表达式的最后一个元素 |
—— find_last_index() | 返回满足with表达式的最后一个元素索引 |
注:qi = IA.find(x) //shall be an error
-
int arr[];
-
int q[$];
-
...
-
// find all items equal to their position (index)
-
q = arr.find with ( item == item.index );//数组元素的值与索引值相等
对于以下定位方法,with表达式可以省略:
—— max() | 返回最大元素组成的队列或者元素的表达式计算结果是最小值 |
—— min() | 返回最小元素组成的队列或者元素的表达式计算结果是最小值 |
—— unique() | 返回数组中具有唯一值的队列 |
—— unique_index() | 返回数组中具有唯一值的索引队列 |
eg:
-
string SA[10], qs[$];
-
int IA[int], qi[$];
-
-
// Find all items greater than 5
-
qi = IA.find( x ) with ( x > 5 );
-
qi = IA.find( x ); // shall be an error
-
-
// Find indices of all items equal to 3
-
qi = IA.find_index with ( item == 3 );
-
-
// Find first item equal to Bob
-
qs = SA.find_first with ( item == "Bob" );
-
-
// Find last item equal to Henry
-
qs = SA.find_last( y ) with ( y == "Henry" );
-
-
// Find index of last item greater than Z
-
qi = SA.find_last_index( s ) with ( s > "Z" );
-
-
// Find smallest item
-
qi = IA.min;
-
-
// Find string with largest numerical value
-
qs = SA.max with ( item.atoi );
-
-
// Find all unique string elements
-
qs = SA.unique;
-
-
// Find all unique strings in lowercase
-
qs = SA.unique( s ) with ( s.tolower );
5.2 数组的排序方法
SystemVerilog提供了可以改变数组中元素顺序的方法,可以对数组中的元素进行正排序、逆排序或者打乱数组中元素的顺序。关联数组除外。
排序方法的函数原型如下:
function void ordering_method (array_type iterator = item);
数组支持以下排序方法:
—— reverse() | 对数组中的元素进行逆排序,此方法不能与with条件语句一起使用。 |
—— sort() | 按升序对数组进行排序 |
—— rsort() | 按降序对数组进行排序 |
—— shuffle() | 按随机顺序对数组进行排序,此方法不能与with条件语句一起使用。 |
eg:
-
string s[] = { "hello", "sad", "world" };
-
s.reverse; // s becomes { "world", "sad", "hello" };
-
-
int q[$] = { 4, 5, 3, 1 };
-
q.sort; // q becomes { 1, 3, 4, 5 }
-
-
struct { byte red, green, blue; } c [512];
-
c.sort with ( item.red ); // sort c only using the red field
-
c.sort( x ) with ( {x.blue, x.green} ); // sort by blue then green
5.3 数组缩减
数组缩减方法是把一个数组缩减成一个值,这个值的类型与数组元素的类型相同,或者与with表达式值的类型相同。
缩减方法的函数原型如下:
function expression_or_array_type reduction_method (array_type iterator = item);
数组支持的缩减方法如下:
—— sum() | 返回所有数组元素的和,如果指定with表达式,则返回所有数组元素with表达式计算值的和。 |
—— product()积 | 返回所有数组元素的积,如果指定with表达式,则返回所有数组元素with表达式计算值的积。 |
—— and() | 返回所有数组元素的与,如果指定with表达式,则返回所有数组元素with表达式计算值的与。 |
—— or() | 返回所有数组元素的或,如果指定with表达式,则返回所有数组元素with表达式计算值的或。 |
—— xor() | 返回所有数组元素的或非,如果指定with表达式,则返回所有数组元素with表达式计算值的或非。 |
eg:
-
byte b[] = { 1, 2, 3, 4 };
-
int y;
-
y = b.sum ; // y becomes 10 => 1 + 2 + 3 + 4
-
y = b.product ; // y becomes 24 => 1 * 2 * 3 * 4
-
y = b.xor with ( item + 4 ); // y becomes 12 => 5 ^ 6 ^ 7 ^ 8
-
-
logic [7:0] m [2][2] = '{ '{5, 10}, '{15, 20} };
-
int y;
-
y = m.sum with (item.sum with (item)); // y becomes 50 => 5+10+15+20
-
-
logic bit_arr [1024];
-
int y;
-
y = bit_arr.sum with ( int'(item) ); // forces result to be 32-bit