SystemVerilog 語言部分(一)


一 數據類型

內建數據類型

verilog中,對於觸發器,鎖存器用reg類型,對於reg,會被綜合成register,latch

       wire,做連接

sv中,logic可以被綜合為reg或wire,logic如果在驗證環境,只會作為單純的變量進行賦值操作。

verilog & sv區別:

  verilog作為硬件描述語言,傾向於設計人員自身懂得所描述的電路中哪些變量應該實現為reg或是wire,但不利於后端綜合工具

  sv側重於驗證語言,引入logic只會作為單純的變量進行賦值操作,這些變量只屬於軟件環境構建

 

bit是二值邏輯:0 1

logic是四值邏輯:0 1 X Z

Q:為什么有了四值邏輯還要引入二值邏輯?

A:SV在開始做設計的時候,期望將硬件和軟件分開,四值在硬件設計,二值在軟件中

 

四值邏輯:integer(32),logic,reg,net-type

二值邏輯:byte(8bit),shortint,int(32),longint,bit

 

有符號類型: byte,shortint,int,longint,integer

無符號類型:bit, logic, reg, net-type(wire/tri)

note:用最高位來表征有無符號

在變量運算中,應該盡量避免兩種不一致的變量操作

將有符號變量轉換為無符號:unsigned'    屬於靜態轉換

動態轉換 $cast(tgt, src)  

對比:靜態轉換在編譯的時候做檢查,動態轉換在仿真的時候做檢查

靜態轉換和動態轉換均需要操作符號或者系統函數介入,統稱為顯式轉換

而不需要進行轉換的一些操作稱為隱式轉換

note:不同數據類型進行操作時應注意變量的:邏輯數據類型、符號類型、矢量位寬

 

軟件常用類型【定寬數組】

數組聲明

int lo_hi[0:15];     //16 ints [0] .. [15]

int c_style[16];       //16 ints [0] .. [15]

多維數組聲明和使用

int arr2 [0:7][0:3]; // 完整聲明

int arr3 [8][4];  //緊湊聲明

arr2[7][3] = 1;  //設置最后一個元素

初始化和賦值

int  ascend[4] = `{0, 1, 2, 3}; //對四個元素初始化

int  descend[5];

descend[0:2] = `{5, 6, 7}   //片段賦值操作

ascend = `{4{8}}   //四個值全部為8

descend = `{9, 8, default:-1 }      //{9,8,-1,-1,-1}

存儲空間考量

從實際硬件容量的角度出發,哪種方式存儲方式更小?

bit [3][7:0] b_pack;      //合並型

bit [7:0] b_unpack[3];    //非合並

 

 b_unpack 實際占用3個WORD存儲空間,但是b_pack則只會占據一個WORD存儲空間

note:當左邊也有維度,右邊也有維度聲明時,先考慮右邊維度

  對於unpack的數組,初始化和賦值“ ` ”要存在

Q:當b_pack和b_unpack用logic存儲時,實際占用的大小為:

A:b_pack有24bit,用logic 4值表示時,每個需要2bit,i.e. 48bit =2WORD

    b_unpack為3 *8,8位連續位,即3*16,其中16bit可以被一個WORD存儲,則需要3WORD

note:對於unpack的數組做初始化要有“ ` ”

for和foreach循環

initial begin

bit [31:0] src[5], dst[5];

for (int i=0; i< $size(src); i++)      //$size(src,default =1)

  src[i] = i;

foreach (dst[j]) begin

  dst[j] = src[j]*2

end

復制和比較    “==” / “!=”

 

軟件常用類型【動態數組】

定寬數組類型的寬度在編譯時就確定了,但是如果在程序運行時再確定數據的寬度需要使用【動態數組】

動態數組用的是非合並的存儲方式,合並數組和非合並數組之間不能直接賦值

特點:可以在仿真運行時靈活調解數組的大小即存儲量

 動態數組一開始聲明時,需要利用“[ ]”來聲明,而此時數組是空的,即0容量,其后使用new[ ]來分配空間,方括號中傳遞數組的寬度

此外,也可以在調用new[ ]時將數組名一並傳遞,將已有數組的值復制到新數組中

 

 d2和dyn是兩個地址空間,integer默認值是X

刪除方法:也可以dyn = new[0]    /  dyn = `{ }

 

【隊列】

  • 結合了鏈表和數組的優點,可以在它的任何地方添加或刪除元素,並且通過索引實現對任一元素的訪問
  • 隊列的聲明是 [$]   隊列元素的標號從0到$
  • 隊列不需要new[ ]去創建空間(new[]只對動態數組使用),只需要使用隊列的方法為其增減元素,一開始空間為0
  • 隊列的一個簡單使用是通過自帶的push_back( )和pop_front( )結合來實現FIFO的用法

 note:數組中用size( ),mailbox中用num( )

 【關聯數組】

 關聯數組中index不是連續的,為此盡可能不要用for循環

 

 如果找不到第一個索引,說明第一個為空

【結構體】struct

note:verilog中沒有數據結構,sv中可以使用struct語句創建結構

只是一個數據的結合,通常是將若干相關變量組合到一個結構體中

用來創建一個新的類型 typedef,為此pixel_s是類型

第一行的pixel在這里是變量名 

 typedef在這里也可以替換為define,區別在於typedef創建的是類型,define是變量名

 

 note:數據是非合並型,采用`{ }方式,如果結構體用合並型,只需struct packed {bit [7:0] r, g, b} pixel

【枚舉類型】

 

 INIT,DECODE,IDLE默認是0,1,2

note:枚舉類型可以賦值給整型,INT = enum, 但是整型不能直接賦值給enum

【字符串】

 

字符串默認" " ,與null不同,null有且只用到句柄(對象)中,字符串中沒有null

note:verilog中沒有str,sv中str沒有"\0"

      數組的大小用.size(), str用 .len() - 1

 

二 過程塊和方法

硬件過程塊 initial和always

module/endmodule,interface/endinterface 可以被視為硬件世界

program/endprogram,class/endclass可以被視為軟件世界

  • always是為了描述硬件的行為
  • always中的@(event)敏感列表是為了模擬硬件信號的觸發行為
  • always過程塊是用來描述硬件時序電路和組合電路的正確打開方式,因此只可以在module或者interface中使用

note:不可以在always中初始化變量,可以在always中復位,而初始化變量是在軟件操作過程中,即可以在initial中

  •   initial只執行一次
  •   initial和always無法被延遲執行,在仿真一開始他們就會並行執行
  •   initial本身不可綜合,對於描述電路沒有任何幫助,不應該存在於硬件設計代碼中
  •   initial是為了測試而生的
  •   initial可以在module,interface和program中使用

note:sv中的class不允許出現initial和always

軟件方法  函數func

  • 可以在參數列表中指定輸入參數(input),輸出參數(output),輸入輸出參數(inout),或引用參數(ref)
  • 可以設置返回值或不設置返回值(void)
  • 默認數據類型是logic,eg input[7: 0]  addr
  • 可以傳參數也可以傳數組(作為形參)
  • 可以有返回值也可以沒有返回值(void function())
  • 在使用ref時,為了保護數據對象只能被讀取,不能被寫入,可以通過const來限定ref的聲明
  • 聲明參數時,默認方向是input

軟件方法  任務task

  • task無法通過return添加返回值
  • task可以置入耗時語句,包括@event, wait event, #delay
  • function不可以調用task,task可以調用function

變量生命周期

分為automatic(動態,局部變量)和static(靜態,全局變量)

  • func/task中的臨時變量,在方法調用結束后,自動釋放
  • 如果數據變量被聲明為automatic,進入該進程/方法后,automatic變量會被創建,離開該線程/方法后會被銷毀
  • 對於automatic方法,其內部所有變量內部默認也是automatic
  • 對於static方法,其內部所有變量內部默認也是static

note:沒有顯式注明動態還是靜態變量的情況下,默認是static

  • module,program,interface,task和func之外的變量擁有靜態的生命周期,即存在與整個仿真階段
  • class中默認是automatic
  • 在module, interface和program內部聲明,且在task,process或者func外部聲明的變量也是static

 

三 設計的例化和連接

 例化:

 

 

硬件和軟件的連接有且只能通過interface,硬件和硬件的連接可以通過端口,也可以通過interface

 


免責聲明!

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



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