System Verilog提供兩組通用的數(shù)據(jù)類型:網(wǎng)絡(luò)和變量(nets 和 variables)。網(wǎng)絡(luò)和變量同時具有類型和數(shù)據(jù)類型特性。類型表示信號為網(wǎng)絡(luò)或變量,數(shù)據(jù)類型表示網(wǎng)絡(luò)或變量的值系統(tǒng),即2態(tài)或4態(tài)。為簡單起見,使用術(shù)語data type來表示信號的類型和數(shù)據(jù)類型。
軟件工具(如仿真器和綜合編譯器)使用數(shù)據(jù)類型來確定如何存儲數(shù)據(jù)和處理數(shù)據(jù)上的更改。數(shù)據(jù)類型影響操作,并在RTL建模中用于指示所需的硅行為。例如,數(shù)據(jù)類型用于確定加法器應(yīng)基于整數(shù)還是基于浮點,以及應(yīng)執(zhí)行有符號算術(shù)還是無符號算術(shù)。
網(wǎng)絡(luò)類型和變量類型
變量用作編程的臨時存儲。此臨時存儲用于仿真。實際的硅通常不需要相同的臨時存儲,這取決于使用變量的編程環(huán)境。SystemVerilog有幾種變量類型,將在第下節(jié)中討論。
網(wǎng)絡(luò)用于將設(shè)計塊連接在一起,網(wǎng)絡(luò)將數(shù)據(jù)值從源(稱為驅(qū)動程序)傳輸?shù)侥繕嘶蚪邮斩蓑?qū)動程序。SystemVerilog提供了幾種網(wǎng)絡(luò)類型,后面會對此進行了更詳細的討論。
兩態(tài)和四態(tài)數(shù)據(jù)類型(位和邏輯)
SystemVerilog變量可以是2態(tài)數(shù)據(jù)類型或4態(tài)數(shù)據(jù)類型。對于2態(tài),變量的每一位可以具有0或1的值,對于4態(tài),變量的每一位可以具有0、1、Z或X的值。SystemVerilog網(wǎng)絡(luò)只能是4態(tài)數(shù)據(jù)類型。關(guān)鍵字位定義變量為2態(tài)數(shù)據(jù)類型。關(guān)鍵字邏輯定義變量或網(wǎng)絡(luò)為4態(tài)數(shù)據(jù)類型。
變量類型
程序塊指定的左側(cè)需要變量。以下代碼示例中的信號總和和輸出必須是變量。
變量為仿真提供臨時存儲。
前面代碼段中的always_comb過程將執(zhí)行賦值語句sum=a+b;每次a或b改變值時。必須通過仿真器存儲sum的值,直到下一次a或b發(fā)生變化。類似地,always_ff過程將在時鐘的每個正邊緣執(zhí)行if-else決策語句。out的值必須在時鐘周期之間通過仿真器進行存儲。
仿真器所需的臨時存儲并不一定意味著實際硅需要存儲。前面代碼片段中的always_comb過程將在硅中作為組合邏輯實現(xiàn)。因此,總和的值將持續(xù)反映加法器的輸出,并且不需要任何類型的硬件存儲。另一方面,always_ff程序?qū)⒆鳛橛|發(fā)器在硅中實現(xiàn),觸發(fā)器是一種硬件存儲設(shè)備。
可綜合變量數(shù)據(jù)類型
通過同時指定類型和數(shù)據(jù)類型來聲明變量。類型可以顯式指定或隱式推斷,關(guān)鍵字var。
var關(guān)鍵字很少在實際SystemVeriIog代碼中使用。相反,var類型是從其他關(guān)鍵字和上下文推斷出來的。
SystemVerilog有幾個內(nèi)置變量數(shù)據(jù)類型的關(guān)鍵字。這些關(guān)鍵字推斷var邏輯(4態(tài))或var位(2態(tài))變量類型。幾個變量數(shù)據(jù)類型表示硅的行為,并且是可綜合的。表3-1列出了這些可綜合的數(shù)據(jù)類型。
表3-1:可綜合變量數(shù)據(jù)類型
類型 | 代表 |
---|---|
reg | 用戶定義向量大小的通用4態(tài)變量;等價于var logic |
logic | 通常推斷用戶定義向量大小的通用var logic 4態(tài)變量,模塊input/inout端口除外,在模塊input/inout端口上推斷wire logic |
integer | 32位4態(tài)狀態(tài)變量;等價于var logic [ 31: 0 ] |
bit | 具有用戶定義向量大小的通用2態(tài)var變量;如果未指定大小,則默認為1位大小 |
int | 32位2態(tài)變量;相當于var bit[31 0];綜合編譯器將int視為4態(tài)integer整數(shù)類型 |
byte | 8位2態(tài)變量;等效于var bit [ 7 : 0 ] |
shortint | 16位2態(tài)變量;等效于var bit [ 15: 0 ] |
longint | 64位2態(tài)變量;等效于var bit [ 63: 0 ] |
最佳做法準則3-3 |
---|
使用4態(tài)邏輯數(shù)據(jù)類型推斷RTL模型中的變量。不要在RTL模型中使用2態(tài)類型。本指南的一個例外是使用int類型聲明for-loop迭代中變量。 |
使用4態(tài)變量允許仿真器在實際硬件中的值不明確時使用X值。
上下文相關(guān)的邏輯數(shù)據(jù)類型。
在幾乎所有的上下文中,logic數(shù)據(jù)類型推斷出一個與reg相同的4態(tài)變量。關(guān)鍵字logic實際上不是變量類型,它是一種數(shù)據(jù)類型,表示網(wǎng)絡(luò)或變量可以有4態(tài)值。但是,當logic關(guān)鍵字單獨使用或與模塊輸出端口的聲明結(jié)合使用時,會推斷變量。當logic與input or inout端口的聲明結(jié)合使用時,如果logic不推斷變量,則會推斷網(wǎng)絡(luò)類型.
過時的reg數(shù)據(jù)類型
reg數(shù)據(jù)類型是原始Verilog語言遺留下來的過時數(shù)據(jù)類型。應(yīng)使用logic類型而不是reg。最初的Verilog語言使用reg數(shù)據(jù)類型作為通用變量。
不幸的是,關(guān)鍵字reg的使用是一個誤稱,它似乎是“register”的縮寫,寄存器是用觸發(fā)器構(gòu)建的硬件設(shè)備。實際上,使用reg變量與推斷的硬件之間沒有相關(guān)性。使用變量的上下文決定所表示的硬件是組合邏輯還是時序觸發(fā)器邏輯。使用logic代替reg有助于防止這種錯誤觀念,即硬件寄存器將被推斷
X值可能表示存在設(shè)計問題
當仿真過程中出現(xiàn)X值時,通常表明存在設(shè)計問題。會導(dǎo)致X值的某些類型的設(shè)計錯誤包括:
- 未復(fù)位或以其他方式初始化的寄存器。
- 在低功耗模式下未正確保持狀態(tài)的電路。
- 未連接的模塊輸入端口(未連接的輸入端口在高阻抗下浮動,當高阻抗值傳播到其他邏輯時,通常會產(chǎn)生X值)。
- 多驅(qū)動程序沖突(總線爭用)。具有未知結(jié)果的操作。
- 超出范圍的位選擇和數(shù)組索引。
- 建立或保持時間沖突。
在RTL模型中避免使用2態(tài)數(shù)據(jù)類型。
bit、byte、shortint、int和longint數(shù)據(jù)類型僅存儲2態(tài)值。這些類型不能表示高阻抗(Z值),也不能使用X值表示未初始化或未知的仿真條件。當使用2態(tài)數(shù)據(jù)類型時,不會出現(xiàn)指示潛在設(shè)計錯誤(如上面列表中的錯誤)的X值。由于2態(tài)數(shù)據(jù)類型只能有一個0或1值,因此在仿真過程中出現(xiàn)錯誤的設(shè)計可能會正常運行,這是不好的!使用2態(tài)變量的合適位置是驗證試驗臺中的隨機刺激。
不可綜合的變量類型
SystemVerilog有幾種主要用于驗證的變量類型,RTL綜合編譯器通常不支持這些類型。表3-2列出了這些額外的變量類型。這些數(shù)據(jù)類型沒有在本系列中任何要綜合的示例中使用。
表3-2:不可綜合的變量數(shù)據(jù)類型
類型 | 代表 |
---|---|
real | 雙精度浮點變量 |
shortreal | 單精度浮點變量 |
time | 具有timeunit和timeprecision屬性的64位無符號4態(tài)變量 |
realtime | 雙精度浮點變量;與real一模一樣 |
string | 可存儲8位ASCII字符字符串的字節(jié)類型的動態(tài)大小數(shù)組 |
event | 存儲仿真同步對象句柄的指針變量 |
class handle | 存儲類對象句柄的指針變量(聲明類型是類的名稱,而不是關(guān)鍵字類) |
chandle | 一個指針變量,用于存儲從SystemVerilog直接編程接口(DPI,Direct Programming Interface)傳遞到仿真中的指針 |
virtual interface | 存儲接口端口句柄的指針變量(interface關(guān)鍵字是可選的) |
上述的類型不代表在任何綜合器中都不可綜合,只代表了在大部分綜合器中不可綜合。
變量聲明規(guī)則
變量是通過同時指定類型和數(shù)據(jù)類型來聲明的,類型是關(guān)鍵字var,可以顯式指定或隱式推斷。
筆記 |
---|
在實際的SystemVeriIog代碼中很少使用var關(guān)鍵字。相反,var類型是從其他關(guān)鍵字和上下文推斷出來的 |
一些示例變量聲明:
logicv1//推斷varlogic(1位4態(tài)變量)
bit v2;//推斷var bit(1位2態(tài)變量)
integer
v3//推斷var
integer
(32位4態(tài)變量)
intv4//推斷varint(32位2態(tài)變量)
唯一需要var關(guān)鍵字的地方是將input 或者 inout端口聲明為4態(tài)變量時。如果未顯式聲明為變量,則這些端口方向?qū)⒛J為網(wǎng)絡(luò)類型,輸入端口很少需要是變量。
標量變量。標量變量是一個1位變量。reg, logic 和 bit數(shù)據(jù)類型默認為1位標量,
向量變量(packed arrays)。向量是連續(xù)位的數(shù)組。IEEE SystemVerilog標準將向量稱為包陣列(packed arrays)。該reg, logic and bit數(shù)據(jù)類型可以表示任意大小的向量:通過在方括號中指定位的范圍([]),后跟向量名稱來聲明向量的大小。范圍聲明為[最高有效位編號:最低有效位編號]。最高有效位(MSB)和最低有效位(LSB)可以是任意的數(shù)字,并且LSB可以小于或大于MSB。LSB為較小數(shù)字的向量范圍稱為小端點。LSB為較大數(shù)值的向量范圍稱為大端
logic[31:0]v9;//32位向量,小端邏輯
logic [1:32] v10;;//32位向量,大端邏輯
RTL建模中最常見的約定是小端邏輯,并使用0作為向量范圍的LSB。上述變量v9說明了這一慣例。本系列中的所有例子都使用了小端邏輯約定。
byte、shortint、int、longint和integer數(shù)據(jù)類型具有預(yù)定義的向量大小,如表3-1所述。預(yù)定義范圍為小端,LSB編號為位0。
有符號和無符號變量
在操作中,存儲在向量變量中的值可以被視為有符號或無符號。無符號變量僅存儲正值。有符號變量可以存儲正值和負值。SystemVerilog使用2的補碼表示負值。有符號變量的最高有效位是符號位。設(shè)置符號位時,向量的剩余位以二補形式表示負值。
默認情況下,reg、logic、bit和time數(shù)據(jù)類型是無符號變量,byte、shortint、int、integer和longint數(shù)據(jù)類型是有符號變量。可以通過將變量顯式聲明為有符號或無符號來更改此默認值。
常量位選擇和部分選擇
向量可以全部或部分引用。位選擇引用向量的單個位。位選擇使用向量名稱,后跟方括號中的位號([ ])部分選擇指向量的多個連續(xù)位。部分選擇使用向量名稱,后跟方括號中的一系列位號([ ])
部分選擇必須滿足兩個規(guī)則:位的范圍必須是連續(xù)的,并且部分選擇的endian必須與向量聲明的endian相同。位選擇或部分選擇的結(jié)果總是無符號的,即使完整變量是有符號的。
變量位選擇和部分選擇。前面代碼段中的位選擇使用了硬編碼位號。這稱為固定位選擇。位選擇的索引號也可以是變量。比如說。
零位選擇的起點也可以是可變的。零位選擇可以從變量起點遞增或遞減。選擇的總位數(shù)為固定范圍,可變部分選擇的形式為:
第二個問題:標記指示從起始點位號開始遞增。標記指示從起始點位號開始遞減。
下面的示例使用可變部分選擇來迭代32位向量的字節(jié)。
可變位和部分選擇是可綜合的。但是,前面說明變量位和部分選擇的代碼段不滿足某些綜合編譯器所需的其他RTL編碼限制。
帶有子字段的向量。通過使用兩組或多組方括號來定義向量范圍,可以使用子字段聲明向量。下面的代碼片段顯示了簡單32位向量和帶有子字段的32位向量之間的區(qū)別:
圖3-1說明了這兩種聲明的區(qū)別。
圖3-1:帶有子字段的向量
聲明:
第一個范圍[3 :0]定義向量中有多少子字段。在本例中,有四個子字段,索引為 b [ 0 ],b [ l ],b [ 2 ],和 b[3]。第二個范圍[7:0]定義了每個子字段的大小,在本例中為8位。圖3-1說明了簡單32位向量和細分為4字節(jié)的32位向量的布局。
細分向量的子字段可以使用單個索引而不是部分選擇來引用。下面的代碼片段演示了在向量b的字節(jié)之間循環(huán),并且更簡單,因為每個字節(jié)都是向量的一個子字段。
細分向量的位選擇需要多個索引-選擇向量b第三字節(jié)的位7編碼為:b[3][7]
最佳做法準則3-4 |
---|
當設(shè)計主要選擇整個向量或向量的單個位時,使用簡單的向量聲明;當設(shè)計經(jīng)常選擇向量的部分時,使用帶有子字段的向量,并且這些部分位于已知邊界上,例如字節(jié)或字邊界。 |
選擇向量的子字段而不是使用簡單向量的固定部分或可變部分,可以使代碼更易于編寫和維護。
變量分配規(guī)則
變量可以通過多種方式賦值:
- 作為過程賦值語句的左側(cè)(在always、always_comb、always_latch、always_ff或初始過程塊中,或在任務(wù)或函數(shù)中)。
- 作為連續(xù)賦值語句的左側(cè)(使用assign語句)。
- 作為賦值運算符的結(jié)果,例如++增量運算符。
- 作為模塊、任務(wù)或功能的輸入。
- 作為模塊實例、任務(wù)實例、功能實例或原語實例的輸出端口的連接。
變量只能由單個源分配。例如,如果變量從assign 連續(xù)賦值語句中,則在程序塊或模塊輸入端口中也為變量賦值是非法的。但是,對同一變量的任何數(shù)量的程序賦值都被視為一個源。要使以下代碼正常工作,此規(guī)則非常重要:
在RTL建模中,單個源變量賦值的語義限制非常重要,該限制有助于確保抽象RTL仿真行為和綜合后實現(xiàn)行為相同
always_ff,always_comb and always_latch程序塊進一步將對變量的程序賦值限制為僅在一個程序內(nèi),這強制了綜合編譯器的要求。同一過程中變量的多個賦值被視為單個驅(qū)動程序。
未初始化變量
在為變量指定值之前,變量未初始化。4態(tài)變量的未初始化值為X(所有位均設(shè)置為x)。2態(tài)變量的未初始化值為“0”(所有位均設(shè)置為0)。
在下面的示例中,直到clk的第一個正邊緣出現(xiàn),變量q才被初始化。作為一種4態(tài)邏輯類型,在第一個時鐘之前,q將有一個X值,此時q將被指定為0值或d值。如果clk的正邊緣沒有出現(xiàn),該X值可能表示設(shè)計問題,可能是由于時鐘選通或其他一些情況。
筆記 |
---|
未初始化的2態(tài)變量可以隱藏設(shè)計問題。未初始化的2態(tài)變量的值為0,這可能是一個合法的復(fù)位值。這可能會隱藏設(shè)計中復(fù)位邏輯的問題。 |
在線變量初始化
SystemVerilog允許在聲明變量時初始化變量,稱為在線初始化。例如:
在仿真開始時,變量的在線初始化只執(zhí)行一次.
一些FPGA設(shè)備可以編程,使寄存器在已知狀態(tài)下通電,而無需復(fù)位。在線變量初始化可用于仿真這些時序設(shè)備(如觸發(fā)器)的通電狀態(tài)。
筆記 |
---|
ASIC技術(shù)不支持在線變量初始化,某些FPGA技術(shù)可能支持在線變量初始化。 |
當針對不支持可編程通電狀態(tài)的設(shè)備時,綜合編譯器將:(a)不允許在線初始化,(b)忽略它-當忽略在線初始化時,RTL仿真行為和綜合門級實現(xiàn)可能不匹配,
最佳做法準則3-5 |
---|
僅在將作為FPGA實現(xiàn)的RTL模型中使用變量初始化,并且僅對觸發(fā)器的加電時建模。 |
對于ASIC設(shè)計,應(yīng)使用復(fù)位功能來初始化變量。不要使用在線初始化。對于FPGA設(shè)計,只有在確定RTL模型始終針對支持加電寄存器狀態(tài)的設(shè)備時,才使用在線初始化。在RTL模型中使用在線初始化有效地將模型鎖定為僅用于該類型FPGA設(shè)備。
最佳做法準則3-6 |
---|
僅在RTL模型中使用內(nèi)嵌變量初始化。不要使用初始過程初始化變量。 |
支持在線變量初始化的綜合編譯器和目標FPGA設(shè)備也允許使用初始過程對觸發(fā)器的通電值進行建模。
-
Verilog
+關(guān)注
關(guān)注
28文章
1335瀏覽量
109857 -
System
+關(guān)注
關(guān)注
0文章
164瀏覽量
36804 -
變量
+關(guān)注
關(guān)注
0文章
609瀏覽量
28288
發(fā)布評論請先 登錄
相關(guān)推薦
評論