動態數組
動態數組,和名字的字面解釋一樣,可以動態調整空間大小的數組,動態數組在編譯時不指定空間的大小,只有在程序運行是才分配空間,這也就要求在代碼中需要 new[ ] 來設定動態數組的空間大小。
1.1 動態數組的聲明方法:
data_type array_name [];
1.2 動態數組的三種內置方法:
new[]操作符用來設置或改變數組的尺寸。
integer addr[]; // 聲明動態數組 addr = new[100]; // 產生具有100個元素的數組 ... // 加倍數組的尺寸,但保留以前的值。 addr = new[200](addr);
size()內建方法返回數組的當前尺寸。
int j = addr.size; addr = new[addr.size()*4] (addr); // 將addr數組的尺寸擴大為4倍
delete()內建方法清空數組的所有元素以便產生一個空數組(零尺寸)。
int ab [] = new[N]; // 產生一個尺寸為N的臨時數組 // 使用ab ab.delete; // 刪除數據內容 $display("%d", ab.size); // 打印0
1.3動態數組的使用示例:
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
關聯數組
關聯數組:保存稀疏型的數據。與其他數組不同的是,關聯數組有利於使用零散的存儲空間,如下圖所示,關聯數組存儲數據並不是連續的存儲空間。當集合的尺寸是未知的或者數據空間緊缺的時候,聯合數組則是更好的選擇。聯合數組在使用之前不會分配任何存儲空間,並且索引表達式不再被限制成integral表達式,而是可以具有任何數據類型。
2.1關聯數組的聲明:
integer i_array[*]; // 整數關聯數組(未指定索引) bit [20:0] array_b[string]; // 21位向量的關聯數組,使用字符串類型作為索引 event ev_array[myClass]; // 事件類型的關聯數組,使用類myClass索引
2.2關聯數組的內置方法:
num()方法返回關聯數組中條目的數目。如果數組是空數組,那么它返回0。
int imem[*]; imem[2'b3] = 1; imem[16'hffff] = 2; imem[4'b1000] = 3; $display("%0d entries\n", imem.num); // 打印"3 entries"
delete()方法刪除特定索引的條目。如果試圖刪除的條目不存在,該方法不會發布警告信息。 如果沒有指定索引,delete()方法刪除數組的所有元素。
int map[string]; map["hello"] = 1; map["sad"] = 2; map["world"] = 3; map.delete("sad"); // 從"map"中刪除索引為"sad"的條目 map.delete; // 刪除關聯數組"map"中的所有條目
exists()函數檢查對於指定數組中是否存在指定索引的元素。如果元素存在則返回1,否則返回0。
if (map.exists("hello")) map["hello"] += 1; else map["hello"] = 0;
first()方法將指定的索引變量賦值為關聯數組中第一個(最小的)索引的值。如果數組是空的則返回0,否則返回1。
string s; if (map.first(s)) $display("First entry is : map[%s] = %0d\n", s, map[s]);
last()方法將指定的索引變量賦值為關聯數組中最后一個(最大的)索引的值。如果數組是空的則返回0,否則返回1。
string s; if (map.last(s)) $display("Last entry is : map[%s] = %0d\n", s, map[s]);
next()方法尋找索引值大於指定索引的條目。如果存在下一個條目,索引變量被賦值為下一個條目的索引,並且函數返回1。否則,索引不會發生變化,函數返回0。
string s; if (map.first(s)) do $display("%s : %d\n", s, map[s]); while (map.next(s));
prev()函數尋找索引小於指定索引的條目。如果存在前一個條目,索引變量被賦值為前一個條目的索引,並且函數返回1。否則,索引不會發生變化,並且函數返回0。
string s; if (map.last(s)) do $display("%s : %d\n", s, map[s]); while (map.prev(s));
2.3關聯數組使用示例:
initial begin bit [63:0] assoc[int],idx =1; // Initialize widely scatteredvalues repeat (64) begin assoc[idx] =idx; idx = idx << 1; end // Step through all index values withforeach foreach (assoc[i]) $display("assoc[%h]= %h", i, assoc[i]); // Step through all index values withfunctions if (assoc.first(idx)) begin // Get first index do $display("assoc[%h]=%h",idx, assoc[idx]); while (assoc.next(idx)); // Get next index end // Find and delete the first element assoc.first(idx); assoc.delete(idx); $display("The array now has %0delements", assoc.num); end
隊列
隊列是一個相同元素的可變尺寸的有序集合。隊列能夠以常量時間訪問它的所有元素,也能夠以常量時間在隊列的尾部和頭部插入和刪除元素。隊列中的每一個元素都通過一個序號來標識,這個序號代表了元素在隊列內的位置,0代表第一個元素,$代表最后一個元素。隊列類似於一個一維的非壓縮數組,它可以自動地增長和縮減。因此,與數組一樣,隊列可以使用索引、串聯、分片、相等操作符進行處理。
3.1隊列的聲明
byte q1[$]; // 一個字節隊列 string names[$] = {"Bob"}; // 具有一個元素的字符串隊列 integer Q[$] = {3, 2, 7}; // 一個被初始化成三個元素的整數隊列 bit q2[$:255]; // 一個最大尺寸為256的位隊列
3.2隊列的內置方法
size()方法返回隊列中元素的數目。如果隊列是空的,它返回0。
for (int j=0; j<q.size; j++) $display(q[j]);
insert()方法在指定的索引位置插入指定的元素。
Q.insert(i, e)等效於Q = {Q[0:i-1], e, Q[i,$]}
delete()方法刪除指定索引位置的元素。
Q.delete(i)等價於Q = {Q[0:i-1], Q[i+1,$]}
pop_front()方法刪除並返回隊列的第一個元素。
e = Q.pop_front()等價於:e = Q[0]; Q = Q[1,$]
pop_back()方法刪除並返回隊列的最后一個元素。
e = Q.pop_back()等價於:e = Q[$]; Q = Q[0,$-1]
push_front()方法在隊列的前端插入指定的元素。
Q.push_front(e)等價於:Q = {e, Q}
push_back()方法在隊列的尾部插入指定的元素。
Q.push_back(e)等價於:Q = {Q, e}
3.3隊列的使用示例:
int j = 1; int q[$] = {3,4}; //隊列的常量不需要使用單引號' int q2[$]= {0,2,5}; initial begin q2.insert(1,j); //{0,1,2,5}在2之前插入1 q2.insert(3,q); //{0,1,2,3,4,5}在q2中插入一個隊列 q2.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(); //{}刪除整個隊列