數字IC驗證——SystemVerilog基本語法

SV和Verilog的語法類似,和C/C++也有些共性,基本SV可包含Verilog的所有規則,本文會在以下博文內容外做補充,若有相異處下文會特意指出。Verilog語法可參考該鏈接第1大節。鏈接:https://blog.csdn.net/qq_39815222/article/details/89601331

1. 數據類型

  1. 二值邏輯和四值邏輯
    編碼時一定要注意操作符左右兩側的符號類型要一致
    二值邏輯:包括 bit, byte, shortint, int, longint等,均爲有符號類型(bit除外);這些類型的值只包含{0,1},目的是模擬計算機驗證環境,提高仿真性能,節約空間。若有四值邏輯數給其賦值,x,z會默認被賦值爲0,因此二值邏輯數要遠離DUT
    四值邏輯:包括logic, integer, reg, wire等,均爲無符號變量(integer除外);目的是模擬外部物理世界
  2. logic
    用法既拓展了傳統的reg型,也可以像wire那樣連線,但既然被應用在驗證場景中,因此無需關心對應的邏輯是否被綜合爲寄存器還是線網,只需作爲簡單的變量賦值即可。
    注意:當含有多驅動(multi-drive)的場景是必須使用wire型。
  3. 動態數組和聯合數組
    int  array[];               //動態數組,compile時長度不確定,simulation時長度確定
    array = new[20];      //new分配空間

    logic [31:0] array[*];    //聯合數組,目的是節約空間
  4. 隊列
    概念類似C語言裏的隊列,用法也類似,可自由插入刪除數據,
    shortint  queue[$] = { 1,2,3 }
    queue.insert(1,7);    //{1,7,2,3}
    queue.delete(1);      //{1,2,3}
    queue.push_front(6);   //{6,1,2,3}
    queue.push_back(7);   //{6,1,2,3,7}
    j = queue.pop_front;    //{1,2,3,7}    同理pop_back
  5. 結構體
    類似C語言裏的結構體,包括概念和用法
  6. 枚舉
    enum logic [1:0] {...} state;  //可定義z,x狀態

2. 語句

  • 循環語句
    循環語句用於控制執行語句的執行次數,用於在仿真代碼中生成仿真激勵信號。

for(int i=0; i<=5; i++)...           //for循環,相較於verilog,i可以內部定義,且作爲局部變量,作用範圍只限於for循環
while(i<5) begin...end    //while循環,同樣存在do...while()
foreach(src[i])                //foreach循環,和for功能類似,但foreach多了可編譯的功能,及判斷條件裏可有變量
       src[i] = i;      

  • randomize()
    隨機函數

class1 example1 = new;  
if( example1.randomize() == 1)...

  • 一些關鍵詞
  1. automatic... ref...
    用在function/task賦值
    function automatic void f1( ref data )  //此處data和外部定義的data共用同一物理地址,因此兩值同時變化
    endfunction                                         //若希望內部值的改變不影響外部值的改變,可在內部定義爲const ref data
  2. automatic和static
    automatic變量類似於軟件中的局部變量,在它的作用域生命結束時被銷燬回收存儲空間
    static變量若在仿真開始時被創建,在進程執行過程中自身不會被銷燬,且會被多個進程共享。
  3. inside
    if((a==1)||(a==2)||(a==3)) 等價於if( a inside {1,2,3})
  4. time
    描述時間,單位爲timescale定義的精度
  5. rand
    rand隨機化比較常用
    rand bit [7:0] data1;     //data1值取0-255中的任意數
    randc bit [7:0] data2;   //data2取0-255中任意值,但每次取值都不一樣,只限於bit和enum類型
    constraint range1{                       //約束data1範圍 
           data1>100; data1<200;
           data1>data2; }         
  6. dist { value1 := weight1   value2 :/ weight2 }
    劃分權重,用在隨機化操作中
    [1:2]:=40;   //每個數權重都是40
    [1:2]:/40;    //每個數權重是20
  7. solve...before...
    用在隨機數產生時,constraint魔窟啊裏面
    solve y before x    //先產生x,再產生y
  8. semaphores
    創建對象可複用
  9. mailbox
    創建一個信箱,使通信數據在不同process交換,可理解成fifo
  • 一些符號及搭配
  1. 通配符 .*
    可以把相同名字的net和port連在一起
    test   test1( .a(a), .b(b), .c(c) );      //或者 test   test1( .a, .b, .c );  
    等同於   test t1( .* );
  2. ==? / !=?
    判斷符號兩邊是否像相等或不等,x,z處做通配處理
  3. ++
    SV裏面可以用自增符
  4. 'value 賦值
    data0 = 'x                //SV中賦值可無需添加b,o,h等代表進制的符號
    data1 = '1               //SV中可給某個值賦值全1,注意Verilog中不行
  5. int'( value)
    強制類型轉換,int也可以是其他數據類型或unsigned,signed
  6. value1'( value2 )
    位寬強制轉換,value1是位寬值
  7. ##
    延遲一個時鐘週期
  8. |->
    在當前時鐘週期

3. 語句塊

  • program
    program可以將設計和驗證的調度區域通過顯式的方式來安排。

該語句塊可在module直接被例化,語句塊裏面不能出現和硬件相關的過程語句和實例(如always,module等),但是可以有initial,task等塊,program與二者的關係類似於C語言裏的C文件與主函數,子函數的關係。

program內部定義的變量賦值的方式應該採用阻塞賦值,在驅動外部的硬件信號時應該使用非阻塞賦值。
$exit()強制結束該系統函數所在的program

program execute_test
initial begin
...
end
task task1()
...
endtask
endprogram

  • clocking Block
    爲了避免冒險競爭,通常會把clk驅動的同步信號封裝在一個模塊裏,由interface調用。
  • interface
    接口作爲中間將stimulator / monitor和DUT連接,可以集合多個信號,簡化連接,方便調用。
    interface可以包含過程語句(always和initial)和連續賦值語句
    interface可以定義輸入輸出端口,若接口對不同連接模塊的方向不同,可以將端口定義在modpot中

interface signal_test( input bit clk );                //定義
     logic [1:0] A, B;
     logic reset;
    clocking dram @( posedge clk)
           input #1ps A;
           input #5    
           output #6 B;
     endclocking
     modport user1( output A, input  B, reset);  //聲明的端口可以在不同的modport裏定義爲不同的輸入輸出模式
     modport user2( clocking cb, input reset);    //調用clocking,port輸入輸出和user1不一樣
endinterface

always #5 clk = ~clk;
signal_test.user1  signal1(clk);                     //聲明user1模式
signal_temp signal2( .A(signal1.A), ......);     //interface互相直接連接
test test1( signal1 );                                      //interface與module連接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章