轉發自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