在SystemVerilog中,我們知道可以使用動態(tài)數(shù)組實現(xiàn)數(shù)組元素個數(shù)的動態(tài)分配,即隨用隨分,其中元素在數(shù)組中的索引是連續(xù)的,但是如果要實現(xiàn)數(shù)組元素訪問時不采用連續(xù)索引的話,采用動態(tài)數(shù)組和定寬數(shù)組就不是很合適,容易造成空間的浪費,為此在SystemVerilog中引入了關(guān)聯(lián)數(shù)組(Associative Array),實現(xiàn)了一種查找表,該查找表的索引可以根據(jù)用戶需要指定,不限于整形,其內(nèi)存空間直到使用時才會分配,即只針對寫入的元素分配存儲空間,其使用方式類似于Perl等其他語言中的哈希結(jié)構(gòu)。
關(guān)聯(lián)數(shù)組與其他數(shù)組表面上的不同主要體現(xiàn)在數(shù)組的索引上,非關(guān)聯(lián)數(shù)組的索引一般都是整型變量,而關(guān)聯(lián)數(shù)組的索引可以是任何的數(shù)據(jù)類型。
下面我們將通過示例說明關(guān)聯(lián)數(shù)組是如何定義和常用的方法如何使用。
1 關(guān)聯(lián)數(shù)組的聲明格式
關(guān)聯(lián)數(shù)組采用在方括號中放置數(shù)據(jù)類型的形式來進行聲明,其格式如下:
data_type array_name [index_type];
其中
data_type :指定的是數(shù)組成員數(shù)據(jù)類型,可以是定寬數(shù)組允許的任何類型;
array_name:指定關(guān)聯(lián)數(shù)組的名字,符合標識符命名規(guī)則,當(dāng)然每個公司命名規(guī)范可能不一樣;
index_type:關(guān)聯(lián)數(shù)組索引的數(shù)據(jù)類型,如果指定了索引數(shù)據(jù)類型,那么對于數(shù)組元素訪問時索引就必須要匹配指定的索引數(shù)據(jù)類型。同時索引的類型也可以使用通配符,此時對于同一數(shù)組中元素索引時,索引的數(shù)據(jù)類型就可以不一樣;
下面主要針對不同的index_type和關(guān)聯(lián)數(shù)組中常用到的方法進行示例說明。
2 關(guān)聯(lián)數(shù)組不同的索引類型
2.1 index_type為string
【示例】
【仿真結(jié)果】
示例中定義了兩個數(shù)組,arr1數(shù)組的索引類型為string,數(shù)組中每個元素的類型為int,再給arr1初始化時,通過“鍵:值對”實現(xiàn)對應(yīng)元素的初始化,arr1[First]的值為’hAB,arr2[Second]的值為’hCD,在訪問arr1中的元素時,也可以如示例中通過索引“First”和“Second”來訪問。通過該示例,對于關(guān)聯(lián)數(shù)組中特定索引元素的空間分配賦值可以通過’{index:value} 方式實現(xiàn)。
2.2 index_type為class
【示例】
【仿真結(jié)果】
示例中,聲明的關(guān)聯(lián)數(shù)組arr的索引類型為packet(class),packet聲明了三個句柄,pkt1和pkt2都指向了創(chuàng)建的對象,pkt3為空句柄null,通過數(shù)組名.[句柄]的方式實現(xiàn)了對于特定句柄作為索引的數(shù)組元素的賦值操作。示例中,通過foreach遍歷數(shù)組中所有元素,通過仿真結(jié)果可以看到其中所有的賦值操作都賦值成功。這里有一點需要注意,盡管句柄pkt3為null,對其的賦值操作仍然是成功的,但是需要注意的是,如果再聲明一個pkt4空句柄,并且在“arr[pkt3] = ‘hC”之后給arr[pkt4]賦值為”’hD”,那么對arr[pkt3]中的值將會被覆蓋掉,這是因為pkt3和pkt4的值相同都是null,所以后續(xù)如果進行對數(shù)組的遍歷訪問操作,訪問的結(jié)果還是只能訪問到三個元素,而不是四個,即對于索引類型為class的關(guān)聯(lián)數(shù)組,關(guān)聯(lián)數(shù)組的索引句柄可以為null,且所有句柄值為null的數(shù)組元素指向同一個值。同時通過示例注意到,關(guān)聯(lián)數(shù)組中元素在使用foreach進行遍歷時,并不是按照數(shù)組元素初始化的順序進行輸出的,而是根據(jù)索引類型排列相對順序的。
2.3 index_type不能為4值邏輯變量
【示例】
【仿真結(jié)果】
示例中,L4_type為自定義的兩位logic類型,因為logic具有(0、1、x、z四種),數(shù)組arr的索引類型使用的就是L4_type,在給數(shù)組中元素進行初始化時,使用“2’hx”和“2’hz”作為索引,此時進行仿真時會產(chǎn)生提示信息(不同仿真工具產(chǎn)生的信息級別不同),通過foreach遍歷數(shù)組,數(shù)組中并不包含對于索引為“2’hx”和“2’hz”的數(shù)組元素,即關(guān)聯(lián)數(shù)組的數(shù)組索引不能為“x”和“z”。
2.4 index_type為*
如果index_type沒有指定類型,而是使用通配符“*”時,雖然貌似通配符可以匹配任何類型,但是在SystemVerilog中,此時的“通配符*”只能匹配任何的integral數(shù)據(jù)類型(參見IEEE1800-2017 6.11),對于其他非integral類型不能用于匹配!
【示例】
【仿真結(jié)果】
示例中,關(guān)聯(lián)數(shù)組arr聲明索引類型時使用了“*”,在initial塊中,將句柄pkt作為數(shù)組的索引進行賦值操作。對上述代碼編譯時仿真器報錯,這主要是因為class不屬于SystemVerilog中定義的integral類型。那么index_type為“*”的關(guān)聯(lián)數(shù)組中索引的類型是不是必須要一致呢?看下例。
【示例】
【仿真結(jié)果】
示例中,關(guān)聯(lián)數(shù)組arr在聲明時index_type為“*”,并且在通過不同類型的索引對數(shù)組arr中相應(yīng)元素進行了賦值操作,并且將這些元素通過不同類型的索引都打印了出了。雖然這些索引的類型不同,但是這些類型有一個共同點都屬于SystemVerilog中的integral類型,可見關(guān)聯(lián)數(shù)組的索引如果為“*”的話,在通過不同類型索引給數(shù)組元素賦值時,這些索引必須都是integral類型。
其實從一個側(cè)面可以體會到,SystemVerilog中所有的integral類型在某種程度上可以相互轉(zhuǎn)換,類似于C語言中的不同數(shù)據(jù)類型之間的自動轉(zhuǎn)換一樣。另外,可能有人會問,為什么對于這個數(shù)組打印消息是不使用foreach結(jié)構(gòu)呢?請看下例。
【示例】不能使用foreach結(jié)構(gòu)
【仿真結(jié)果】
示例中,關(guān)聯(lián)數(shù)組arr聲明時其中index_type使用了“*”,然后給arr中相關(guān)元素通過不同的索引類型進行了賦值初始化操作,最后企圖使用foreach遍歷arr時報錯,正如報錯信息顯示,當(dāng)關(guān)聯(lián)數(shù)組聲明時索引為“*”,那么該數(shù)組不能使用使用foreach對該數(shù)組進行遍歷。
3 關(guān)聯(lián)數(shù)組常用方法
關(guān)聯(lián)數(shù)組中在使用時常會使用一些內(nèi)建的方法,這些常用的方法如下表所示,
方法名 | 作用 |
num()/size() |
functionint num(); function int size(); 返回當(dāng)前數(shù)組元素個數(shù) |
delete(index) |
function void delete([input index]); 刪除指定索引的數(shù)組元素 |
exists(index) |
function int exists(input index); 檢查指定索引的數(shù)組元素是否存在,如果存在返回1,否則為0 |
first(var) |
function int first(ref index); 將數(shù)組第一個元素的索引賦給變量var |
last(var) |
function int last(ref index); 將數(shù)組最后一個元素的索引賦給變量var |
next(var) |
function int next(ref index); 將數(shù)組當(dāng)前元素的下一個元素的索引賦給變量var |
prev(var) |
function int prev(ref index); 將數(shù)組當(dāng)前元素的上一個元素的索引賦給變量var |
那么,關(guān)聯(lián)數(shù)組的這些方法如何使用呢?下面通過示例了解下。
【示例】num(),exists(),delete(index)
【仿真結(jié)果】
示例中,通過“數(shù)組名.num()”的方式獲取到當(dāng)前數(shù)組中元素的個數(shù)。然后通過foreach遍歷了數(shù)組中所有的元素。通過“數(shù)組名.exists(索引號)”的方式,可以檢測數(shù)組中是否存在指定索引的元素。
當(dāng)通過“數(shù)組名.delete(索引號)”的方式可以刪除數(shù)組中指定索引號的數(shù)組元素,示例中通過arr.delete(1)刪除了數(shù)組中索引號為“1”的元素后,再次調(diào)用arr.exists(1)檢查數(shù)組中是否還存在索引號為“1”的元素,通過仿真結(jié)果可以看到,數(shù)組中索引號為“1”的元素已經(jīng)被刪除。
這里需要注意,示例中使用的三個方法的格式分別是:“數(shù)組名.num()”、“數(shù)組名.exists(索引號)”和“數(shù)組名.delete(索引序號)”,其中delete后也可以不帶索引號,此時將會將整個數(shù)組“清空”!另外,在使用時一定要注意,關(guān)聯(lián)數(shù)組如果不對其進行任何有效寫入時,數(shù)組的大小時為0。、,即關(guān)聯(lián)數(shù)組在使用之前是不會耗費存儲空間的。
【示例】first(),next()
【仿真結(jié)果】
示例中,在initial過程塊中,首先通過“數(shù)組名.first(變量名)”的方式將數(shù)組arr中第一個(最小)索引的值賦給給定的索引變量temp(注意變量類型與數(shù)組索引類型一致),但是此時arr中沒有任何元素,所以此時通過數(shù)組名調(diào)用“arr.first(temp)”方法返回0,即輸出“1st entry does not exist!”。
通過for循環(huán)對數(shù)組進行初始化,之后再次“arr.first(temp)”,因為數(shù)組中有元素,所以first()方法返回非零,同時將初始化后數(shù)組中第一個(最小)索引賦值給temp。
然后通過“arr.next(temp)”獲取比給定的索引值(temp)大的最小索引值,如果存在下一項,則將下一項的索引賦給索引變量temp,因為給定的temp此時值為0,所以next()方法調(diào)用后,將數(shù)組下一個元素的索引賦給了變量temp,所以仿真結(jié)果此時輸出temp值變?yōu)榱?.示例的最后do...while()循環(huán)將first()和next()配合使用,有效地遍歷數(shù)組。
這里需要注意,示例中使用的方法的格式分別是:“數(shù)組名.first(索引變量)”和“數(shù)組名.next(索引變量)”。
【示例】
【仿真結(jié)果】
示例中,在initial過程塊中,首先通過for循環(huán)對數(shù)組進行初始化,之后執(zhí)行“arr.last(temp)”,因為數(shù)組中有元素,所以last()方法返回非零,同時將初始化后數(shù)組中最后(最大)索引賦值給temp。
然后通過“arr.prev(temp)”獲取比給定的索引值(temp)小的最大索引值,如果存在上一項,則將上一項的索引賦給索引變量temp,因為調(diào)用last(temp)方法后給temp的值為3,所以prev()方法調(diào)用后,將數(shù)組上一個元素的索引賦給了變量temp,所以仿真結(jié)果此時輸出索引為temp的數(shù)組元素的值輸出.示例的最后將last()和prev()配合使用可以有效地遍歷數(shù)組。
這里需要注意,示例中使用的方法的格式分別是:“數(shù)組名.last(索引變量)”和“數(shù)組名.prev(索引變量)”。
上述first()、next()、last()和prev()這些方法在使用的時候一定要注意,如果關(guān)聯(lián)數(shù)組索引類型為“*”的話,這些方法不能使用。
審核編輯:劉清
-
仿真器
+關(guān)注
關(guān)注
14文章
1027瀏覽量
84581 -
Verilog
+關(guān)注
關(guān)注
28文章
1363瀏覽量
111357 -
C語言
+關(guān)注
關(guān)注
180文章
7626瀏覽量
139550
原文標題:敲黑板,帶你了解SystemVerilog中的關(guān)聯(lián)數(shù)組
文章出處:【微信號:處芯積律,微信公眾號:處芯積律】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
轉(zhuǎn)一篇Systemverilog的一個牛人總結(jié)
求職寶典:寒武紀2019筆試題
PHP數(shù)組排序
基于社交網(wǎng)絡(luò)和關(guān)聯(lián)數(shù)據(jù)的服務(wù)網(wǎng)絡(luò)構(gòu)建方法

基于本體的軟件工程關(guān)聯(lián)數(shù)據(jù)的自動構(gòu)建

SystemVerilog中數(shù)組的賦值、索引和切片
SystemVerilog動態(tài)數(shù)組的大小更改展示
SystemVerilog中的關(guān)聯(lián)數(shù)組
SystemVerilog中可以嵌套的數(shù)據(jù)結(jié)構(gòu)
網(wǎng)絡(luò)和變量的未壓縮數(shù)組

使用SystemVerilog解決數(shù)組問題
一些有趣的數(shù)組相關(guān)的SystemVerilog約束
一些有趣的數(shù)組相關(guān)的SystemVerilog約束
隨機抽取SV數(shù)組中的一個元素方法實現(xiàn)

評論