变量初始化的确定性
變量初始化的確定性
SystemVerilog初始化順序
SystemVerilog標準增強了變量的內嵌初始化。SystemVerilog規定所有內嵌初始化先于仿真時刻0執行的事件。這就保證了如果Initial或者always過程塊讀取具有內嵌初始值的變量時取得正確的初始值,這個確定行為消除了Verilog標準中的不確定性。
使用增強的SystemVerilog進行的仿真結果完全包含在允許的、但不確定的使用Verilog進行的仿真結果中,
logic resetN = 0; //聲明并初始化reset always@(posedge clock ,negedge resetN)if(!resetN) count <= 0; //reset低電平有效else count <= count + 1;SystemVerilog中是仿真器在激活always過程塊之前,先進行resetN的初始化。此后,仍然在0仿真時刻,當always塊被激活后,它會等待下一個時鐘上升沿或resetN下降沿。因為resetN的初始化已經發生了,計數器在0時刻不會被觸發,而是等待下一個時鐘上升沿或者resetN下降沿。
時序邏輯的異步輸入初始化
--在仿真時刻0,使用兩態數據類型施加復位 module counter (input wire clock,resetN,output logic[15:0] count ); always@(posedge clock,negedge resetN)if(!resetN) count <= 0; //reset低電平有效else count <= count + 1; endmodulemodule test; wire [15:0] count; bit clock; bit resetN = 1;//resetN初始化無效值 counter dut(clock,resetN,count); always #10 clock = ~clock; initial beginresetN = 0;//在0時刻插入低電平有效的復位#2 resetN = 1; //在clock上升沿之前去除復位$display("\n count = %0d(expect 0)\n",count);#1 $finish; end endmodule在上面的例子中,計數器有一個異步的復位輸入。這個復位低電平有效,也就是在resetN跳變為0時,計數器會被復位。為了在仿真時刻0時對計數器進行復位,resetN輸入必須跳變為邏輯0。如果resetN被聲明為一個兩態的數據類型,例如bit。如上面的測試平臺例子,其缺省初始值是邏輯0。測試平臺中的第一個測試是通過將resetN置為0來插入復位。第一個測試不會引發對resetN的仿真事件,因此counter模塊的敏感列表不會因resetN的變化而觸發過程塊對counter復位。
為保證resetN置為0時resetN發生變化,resetN的帶內嵌初始化聲明為邏輯1–復位無效狀態
SystemVerilog內嵌變量初始化的確定性可以保證0仿真時刻事件的發生順序。如果變量使用內嵌初始化設成無效狀態,然后使用initial或者always過程塊置為有效狀態,SystemVerilog就保證了內嵌初始化先發生,然后才進行過程塊初始化賦值。
強制類型裝換
SystemVerilog加入強制數據類型轉換的能力。強制類型轉換不同于在賦值時轉變為數值。使用強制類型轉換,不用賦值,在一個表達式內,一個數值就可以轉換成一個新的類型。
(1)靜態轉換(編譯時轉換)
靜態強制轉換和錯誤檢測
靜態強制轉換操作符是一種編譯時的轉換。要強制轉換的表達式在運行時總會被轉換,而不會檢查要轉換的表達式是否在要轉換成的類型的合法范圍內。因此,必須注意不能將非法值賦給變量。
(2)動態強制類型轉換
上面描述的SystemVerilog強制類型轉換是一種編譯時轉換,轉換操作總會運行,而不會檢測結果的有效性。如果需要進一步的檢驗,SystemVerilog提供一個新的系統函數$cast,這是動態的,在運行時進行待轉換數值的檢查。
系統函數 $cast有兩個變量,一個目標函數和一個源變量
$cast試圖將源表達式賦給目標變量。如果賦值是無效的,將會報告一個運行時錯誤,并且目標變量保持不變。
將real類型轉換成int類型,而實數太大,沒有辦法用int來描述
將一個數值轉換成枚舉類型,而它不在枚舉類型的合法值列表中
$cast也可作為任務被調用
$cast可以作為系統函數調用,它會返回一個狀態標志來顯示強制類型轉換成功與否。如果轉換成功, $cast返回1,;如果不成功, $cast函數返回0,并且不改變目標變量。作為函數調用時,不報告運行時錯誤。
靜態的編譯時強制轉換操作是可綜合的。綜合工具可能不支持動態的$cast系統函數。一般情況下,系統任務和系統函數不是一種可綜合的結構。用于綜合的更好的編碼方式是使用靜態強制轉換操作符進行強制類型轉換。
常數
parameter是一個可用確立(elaboration)時使用defparam或者內嵌參數重定義進行重新定義的常數。 specparam是一個可以在確立時從SDF文件中重定義的常數。 localparam是確立期常數,不能重定義。但是它的值可以基于其他常數。常數負層次引用值不合法
常數不允許在自動任務和函數中
SystemVerilog加入了將任何變量聲明為常數的能力–使用const關鍵字。const形式的常數知道確立完成后才被賦值。因為const常量在確立后才獲得值,因此一個const常數可以:
- 在自動任務和函數等動態環境中聲明
- 被賦予一個線網或變量值而非常數表達式
- 被賦予一個對象值,這個值可以在任何設計層次定義。
const常數的聲明必須包含數據類型
const logic[23:0] c1 = 7; //24為常數 const int c2 = 15; //32位常數 const real c3 = 3.14; // 實數常數 const c4 = 5; //錯誤,沒有數據類型const可以用在自動任務和函數中。
一個const常數實質是一個只能被初始化的變量。因為const形式的常數是在運行期間確定數值而不是確立期。一個const常數可以在自動任務和函數中聲明,也可以在模塊、靜態任務和函數中聲明。在begin…end塊和fork…join塊中聲明的變量也可以聲明為一個常數變量。
總結
- 上一篇: QQ 音乐内测 12.0.5 版本,可以
- 下一篇: 关于数组的内容