15. 強制類(lèi)型轉換 Verilog不能將一個(gè)值強制轉換成不同的數據類(lèi)型。SystemVerilog通過(guò)使用 int’ (2.0 * 3.0) // 將結果轉換為int類(lèi)型 mytype’ (foo) // 將foo轉換為mytype類(lèi)型 一個(gè)值還可以通過(guò)在強制轉換操作符前指定一個(gè)10進(jìn)制數來(lái)轉換成不同的向量寬度,例如: 17’ (x - 2) // 將結果轉換為17位寬度 也可以將結果轉換成有符號值,例如: signed’ (x) // 將x轉換為有符號值 16. 操作符 Verilog沒(méi)有C語(yǔ)言的遞增(++)和遞減(--)操作符。而SystemVerilog加入了幾個(gè)新的操作符: ++和--:遞增和遞減操作符; +=、-=、*=、/=、%=、&=、^=、|=、<<=、>>=、<<<=和>>>=賦值操作符; 17. 唯一性和優(yōu)先級決定語(yǔ)句 在Verilog中,如果沒(méi)有遵循嚴格的編碼風(fēng)格,它的if-else和case語(yǔ)句會(huì )在RTL仿真和RTL綜合間具有不一致的結果。如果沒(méi)有正確使用full_case和parallel_case綜合指令還會(huì )引起一些其它的錯誤。 SystemVerilog能夠顯式地指明什么時(shí)候一條決定語(yǔ)句的分支是唯一的,或者什么時(shí)候需要計算優(yōu)先級。我們可以在if或case關(guān)鍵字之前使用 unique或requires關(guān)鍵字。這些關(guān)鍵字可以向仿真器、綜合編譯器、以及其它工具指示我們期望的硬件類(lèi)型。工具使用這些信息來(lái)檢查if或 case語(yǔ)句是否正確建模了期望的邏輯。例如,如果使用unique限定了一個(gè)決定語(yǔ)句,那么在不希望的case值出現的時(shí)候仿真器就能夠發(fā)布一個(gè)警告信息。 bit [2:0] a; unique if ((a==0) || (a==1)) y = in1; else if (a==2) y = in2; else if (a==4) y = in3; // 值3、5、6、7會(huì )引起一個(gè)警告 priority if (a[2:1]==0) y = in1; // a是0或1 else if (a==0) y = in2; // a是2或3 else y = in3; // 如果a為其他的值 unique case (a) 0, 1: y = in1; 2: y = in2; 4: y = in3; endcase // 值3、5、6、7會(huì )引起一個(gè)警告 priority casez (a) 2’b00? : y = in1; // a是0或1 2’b0?? : y = in2; // a是2或3 default : y = in3; //如果a為其他的值 endcase 18. 底部檢測的循環(huán) Verilog包含for、while和repeat循環(huán),這幾個(gè)循環(huán)都是在循環(huán)的起始處檢測循環(huán)條件。SystemVerilog加入了一個(gè)do-while循環(huán),這種循環(huán)在執行語(yǔ)句的結尾處檢測循環(huán)條件。 19. 跳轉語(yǔ)句 在語(yǔ)句的執行過(guò)程中,C語(yǔ)言提供了幾種方式來(lái)跳轉到新的語(yǔ)句,包括:return、break、continue和goto。在Verilog中除了通過(guò)使用disable語(yǔ)句跳轉到語(yǔ)句組的尾部外,沒(méi)有提供任何其它跳轉語(yǔ)句。使用disable語(yǔ)句執行中止和繼續功能要求加入塊的名字,并且會(huì )產(chǎn)生不直觀(guān)的代碼。SystemVerilog加入了C語(yǔ)言的break和continue關(guān)鍵字,這兩個(gè)關(guān)鍵字不要求使用塊名字。另外,SystemVerilog還加入了一個(gè)return關(guān)鍵字,它可以用來(lái)在任何執行點(diǎn)上退出一個(gè)任務(wù)或函數。 break:退出一個(gè)循環(huán),與C語(yǔ)言相同; continue:跳轉到一個(gè)循環(huán)的尾部,與C語(yǔ)言相同; return 表達式:退出一個(gè)函數; return:退出一個(gè)任務(wù)或void類(lèi)型的函數。 SystemVerilog沒(méi)有包含C語(yǔ)言中的goto語(yǔ)句。 20. 塊名字和語(yǔ)句標簽 在Verilog中,我們可以通過(guò)在begin或fork關(guān)鍵字之后指定名字來(lái)為begin-end或fork-jion語(yǔ)句指定名字。這個(gè)指定的名字代表整個(gè)語(yǔ)句塊。SystemVerilog還允許在end或jion關(guān)鍵字之后指定一個(gè)匹配的塊名字。這種機制很容易將end或jion與對應的 begin或fork聯(lián)系起來(lái),尤其是在一個(gè)長(cháng)的塊或嵌套的塊中。塊結尾處的名字是可選的,但如果使用的話(huà),它必須與塊起始處的名字相同。例如: begin: foo// 在begin之后的塊名字 … fork: bar // 具有名字的嵌套的塊 … jion: bar // 必須具有相同的名字 … end: foo // 必須具有相同的名字 SystemVerilog還允許像C語(yǔ)言一樣為單個(gè)語(yǔ)句設置標簽。語(yǔ)句標簽放置在語(yǔ)句的前面,用來(lái)標識這條語(yǔ)句。例如: initial begin test1: read_enable = 0; … test2: for (i=0; i<=255; i++) … end 21. 對事件控制的增強 Verilog使用@標記來(lái)控制基于特定事件的執行流,SystemVerilog增強了@事件控制。 *有條件的事件控制 @標記的一個(gè)基本應用就是推斷一個(gè)具有使能輸入的鎖存器。下面的例子演示了一個(gè)鎖存器建模的基本風(fēng)格。 always @(data or en) if (en) y <= data; 這種編碼風(fēng)格對仿真來(lái)說(shuō)是效率低下的,因為即使在使能輸入無(wú)效的時(shí)候,數據輸入的每次改變都會(huì )觸發(fā)事件控制。 SystemVerilog在事件控制中加入了一個(gè)iff條件。只有iff條件為真的條件下,事件控制才會(huì )被觸發(fā)。通過(guò)將使能判斷移入到事件控制里面,使得只有在鎖存器輸出能夠改變的時(shí)候事件控制才會(huì )被觸發(fā)。例如: always @(a or en iff en==1) y <= a; * 事件控制中的表達式 Verilog允許在@事件控制列表中使用表達式,例如: always @((a * b)) always @(memory[address]) 在第一個(gè)例子中,是當操作數發(fā)生改變的時(shí)候還是只有當運算結果發(fā)生改變的時(shí)候才會(huì )觸發(fā)事件控制?在第二個(gè)例子中,是當memory的地址發(fā)生變化的時(shí)候還是只有當memory的值發(fā)生變化的時(shí)候才會(huì )觸發(fā)事件控制?當@事件控制中包含表達式的時(shí)候,IEEE Verilog標準允許仿真器進(jìn)行不同的優(yōu)化。這就可能導致在不同的仿真器間有不同的仿真結果,可能還會(huì )導致仿真與綜合之間的結果不一致。 SystemVerilog加入了一個(gè)changed關(guān)鍵字,在事件控制列表中它被用作一個(gè)修飾符。@(changed (表達式))能夠顯式地定義只有當表達式的結果發(fā)生改變的時(shí)候才會(huì )觸發(fā)事件控制。例如: always @(changed (a * b)) always @(changed memory[address]) * 事件控制中的賦值 Verilog不允許在事件控制中使用賦值。SystemVerilog允許在事件控制中使用賦值表達式。事件控制僅僅敏感于賦值表達式右側的變化。例如: always @(y = a * b) 22. 新的過(guò)程 Verilog使用always過(guò)程來(lái)表示時(shí)序邏輯、組合邏輯和鎖存邏輯的RTL模型。綜合工具和其它軟件工具必須根據過(guò)程起始處的事件控制列表以及過(guò)程內的語(yǔ)句來(lái)推斷always過(guò)程的意圖。這種推斷會(huì )導致仿真結果和綜合結果之間的不一致。SystemVerilog增加了三個(gè)新的過(guò)程來(lái)顯式地指示邏輯的意圖。 always_ff:表示時(shí)序邏輯的過(guò)程; always_comb:表示組合邏輯的過(guò)程; always_latch:表示鎖存邏輯的過(guò)程。 例如: always_comb @(a or b or sel) begin if (sel) y = a; else y = b; end 軟件工具能夠檢查事件控制敏感列表和過(guò)程的內容來(lái)保證邏輯的功能匹配過(guò)程的類(lèi)型。例如,工具能夠檢查一個(gè)always_comb過(guò)程能夠敏感過(guò)程內讀取的所有外部值,對邏輯的每一個(gè)分支的相同變量進(jìn)行賦值,并且檢查分支是否覆蓋了所有可能的條件。如果任何一個(gè)條件沒(méi)有滿(mǎn)足,軟件工具均會(huì )報告該過(guò)程沒(méi)有正確建模組合邏輯。 23. 動(dòng)態(tài)過(guò)程 Verilog通過(guò)使用fork-jion提供了一種靜態(tài)的并發(fā)過(guò)程。每一個(gè)分支都是一個(gè)分離的、并行的過(guò)程。fork-jion中任何語(yǔ)句的執行必須在組內的每一個(gè)過(guò)程完成后才會(huì )執行。例如: initial begin fork send_packet_task (1, 255, 0); send_packet_task (7, 128, 5); watch_result_task (1, 255, 0); watch_result_task (7, 128, 5); jion // 所有的任務(wù)必須完成后才會(huì )到達這里 end SystemVerilog通過(guò)process關(guān)鍵字加入了一個(gè)新的、動(dòng)態(tài)的過(guò)程。它為一個(gè)過(guò)程產(chǎn)生分支,然后繼續執行而無(wú)需等待其他過(guò)程完成。過(guò)程不會(huì )阻塞過(guò)程或任務(wù)內的語(yǔ)句執行。這種方式能夠建模多線(xiàn)程的過(guò)程。例如: initial begin process send_packet_task (1, 255, 0); process send_packet_task (7, 128, 5); process watch_result_task (1, 255, 0); process watch_result_task (7, 128, 5); end // 所有的過(guò)程并行運行 24. 任務(wù)和函數增強 SystemVerilog為Verilog的任務(wù)和函數作了幾個(gè)增強。 * 靜態(tài)和自動(dòng)的存儲 缺省情況下,在Verilog任務(wù)或函數內的所有存儲都是靜態(tài)的。Verilog-2001允許將任務(wù)和函數聲明成自動(dòng)的。在SystemVerilog 中:(1). 在一個(gè)靜態(tài)任務(wù)和函數內的特定數據可以顯式地聲明成自動(dòng)的。聲明成自動(dòng)的數據在塊中具有完整的生命周期,并且在任務(wù)和函數調用的入口處初始化;(2). 在一個(gè)自動(dòng)的任務(wù)或函數中的特定數據可以顯式地聲明成靜態(tài)的。自動(dòng)的任務(wù)或函數中聲明成靜態(tài)的數據在一個(gè)塊的本地范圍內具有靜態(tài)的生命周期。 * 從任何點(diǎn)返回 Verilog在一個(gè)任務(wù)或函數中執行到endtask或endfunction關(guān)鍵字的時(shí)候返回。函數的返回值是給函數名賦的最后一個(gè)值。SystemVerilog加入了一個(gè)return關(guān)鍵字,使用這個(gè)關(guān)鍵字,一個(gè)任務(wù)或函數可以在任何點(diǎn)上返回。 *多語(yǔ)句 Verilog要求一個(gè)任務(wù)或函數只具有一個(gè)語(yǔ)句或語(yǔ)句塊。多條語(yǔ)句必須組合到一個(gè)單一的begin-end或fork-jion塊中。 SystemVerilog去除了這種限制。因此,多條語(yǔ)句可以在一個(gè)任務(wù)或函數中列出而無(wú)需使用的begin-end或fork-jion。每有分組的語(yǔ)句就像在begin-end中一樣順序執行。我們還可以產(chǎn)生一個(gè)沒(méi)有語(yǔ)句的任務(wù)或函數定義。 *void函數 Verilog要求一個(gè)函數具有一個(gè)返回值,函數的調用接收這個(gè)返回值。 SystemVerilog加入了一個(gè)void數據類(lèi)型,這個(gè)數據類(lèi)型可以作為一個(gè)函數的返回值類(lèi)型。void函數可以像Verilog任務(wù)一樣進(jìn)行調用,而無(wú)需接收一個(gè)返回值。 void函數和任務(wù)的差別在于函數存在幾個(gè)限制,例如沒(méi)有時(shí)間控制等。 *函數的輸入和輸出 Verilog標準要求一個(gè)函數至少具有一個(gè)輸入并且函數只能具有輸入。SystemVerilog去除了這些限制。函數可以具有任意數目的輸入、輸出以及輸入輸出,也可以什么也沒(méi)有。 25. 連續賦值的增強 在Verilog中,連續賦值語(yǔ)句的左側只能是線(xiàn)網(wǎng)類(lèi)型,例如wire。連續賦值語(yǔ)句被認為是線(xiàn)網(wǎng)的驅動(dòng)源,而線(xiàn)網(wǎng)可以擁有任意數據的驅動(dòng)源。 SystemVerilog允許除reg類(lèi)型以外的任何數據類(lèi)型用于連續賦值語(yǔ)句的左側。與線(xiàn)網(wǎng)不同,所有其它數據類(lèi)型被限制為只能有一個(gè)連續賦值語(yǔ)句驅動(dòng)。為相同的變量混合使用連續賦值語(yǔ)句和過(guò)程賦值語(yǔ)句是不被允許的。 26. $bit系統函數 在Verilog中沒(méi)有類(lèi)似于C語(yǔ)言中sizeof的函數。SystemVerilog加入一個(gè)新的$bit內建函數。這個(gè)函數返回保存一個(gè)值所需的硬件位的數目(一個(gè)四態(tài)值要求一個(gè)硬件位),這個(gè)函數還可以用來(lái)確定一個(gè)結構體所代表的硬件位的數目。 27. `define的增強 SystemVerilog增強了`define編譯器指令的能力以便支持將字符串作為宏的參數。宏的文本字符串中可以包含一個(gè)隔離的引號,它的前面必須具有一個(gè)反勾號(`”),這就允許字符串中包含宏參數。宏文本可以在行的尾部包含一個(gè)反斜杠(’’)來(lái)表示在下一行繼續。如果宏文本字符串中包含反斜杠,則反斜杠應該被放在兩個(gè)反勾號之間,這樣它就不會(huì )被認為是Verilog轉義標識符的開(kāi)始。宏文本字符串還可以包含雙反勾號(``),它允許標識符能夠從參數中構建。這些增強使得`define指令更加靈活。例如:`include指令后可以緊跟一個(gè)宏名字來(lái)替代一個(gè)字符串。 `define f1 “../project_top/opcode_defines” `include `f1 28. 狀態(tài)機建模 SystemVerilog允許在更高的抽象層次上對狀態(tài)機建模。這些結構包括: *枚舉類(lèi)型 *一個(gè)特殊的state數據類(lèi)型; *一個(gè)遷移語(yǔ)句 *一個(gè)遷移操作符 29. 斷言 SystemVerilog中加入了斷言的功能來(lái)改善系統的驗證過(guò)程。 30. 結論 SystemVerilog為Verilog-2001標準提供了一系列的擴展。這些擴展使得大型設計的建模和驗證更加容易。 |