systemverilog--動態數組、關聯數組和隊列的區別


動態數組

動態數組,和名字的字面解釋一樣,可以動態調整空間大小的數組,動態數組在編譯時不指定空間的大小,只有在程序運行是才分配空間,這也就要求在代碼中需要 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();     //{}刪除整個隊列

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM