SV_數據類型


數據類型

SV新特性:對比VERILOG

  • 2值邏輯:提高性能,減少內存使用;
  • 隊列,動態數組,關聯數組:減少內存使用,內建搜索和排序函數;
  • unions 和 packed;
  • class 和 structures
  • string
  • enumerated

賦值

  • 賦全值(全0,全1,全x,全z)時,可以忽略位寬
  • 注意verilog賦全1時,不能忽略位寬,也不能忽略進制。
// verilog
parameter SIZE=64;
logic [SIZE-1:0] data;
data=`b0;
data=`bz;
data=`bx;
data=64'hFFFFFFFFFFFFFFFF;


//sv
parameter SIZE=64;
logic [SIZE-1:0] data;
data=`0;
data=`z;
data=`x;
data=`1;

4值邏輯

  • 4值邏輯:0,1,x, z
  • integer,  logic,  reg,  net_type(例如wire,  tri)

logic

  • 支持連續賦值,門邏輯和模塊;
  • 不支持多驅動,(例如:雙向端口,inout,只能用wire不能用logic);
  • 可以替代VERILOG中的reg類型

2值邏輯

  • bit, byte, shortint, int, longint
  • 2值邏輯:0和1;z和x 會轉換成0
  • 提升仿真性能和減少內存使用
  • 不適用於DUT,因為DUT識別z和x,但是2值邏輯將會轉換為0
類型 描述 例子
bit unsigned bit b;  bit [31:0] b32;
byte 8 bits, signed byte b8; (-128~127)
shortint 16 bits, signed shortint s;
int 32 bits, signed int i;
longint 64 bits, signed longint l;

 

2值邏輯和4值邏輯

  • 仿真時,4值邏輯默認為x,2值邏輯默認為0
  • 2值邏輯變量不能代表一個未初始化的狀態
  • 4值邏輯可以賦值給2值邏輯變量,x和z會轉化成0
  • 使用$isunknown() check任何bit是x或z,如果表達式任何一個bit是z或x,返回1;if($isunknown(iport)==1);

有符號和無符號

  • 有符號: byte,  shortint,  int,  longint,  integer
  • 無符號:    bit,  logic,  reg,  net-type(例如wire,   tri)

數據類型轉換

靜態轉換

  • 在轉換的表達式前加上單引號即可
  • 不會対轉換值做檢查,如果轉換失敗,無從得知
  • 在編譯的時候做檢查
  • 有符號轉換成無符號: unsigned'(signed_vec)

動態轉換

  • 在仿真的時候做檢查
  • $cast(tgt, src)

顯示轉換

  • 靜態轉換和動態轉化都需要操作符號或者系統函數介入

隱式轉換

  • 不需要進行轉換的一些操作

定寬數組

  • 支持多維數組
  • 超過邊界寫將會被忽略,超過邊界讀將會返回x,2值邏輯也是返回x;
  • byte,int, shortint,都是存儲在一個32位的空間中
  • longint存儲在兩個32位的空間中
  • 默認為unpacked數組

語法

type name [constant];  type  name  [0: constant];

int array[20];                     // 元素:0-19
int array[64:83];                  // 元素:64-83
logic [31:0] data [1024];        // 元素: 0-1023, 32位寬

int array1 [4]=`{3,2,4,1};   

array1 [0:2]=`{5,6,7};

array1=`{{3}, `{3{8}}};

int md [2][3] = `{`{0,1,2}, `{3,4,5}};                 

存儲空間:pack vs unpack

//  兩個變量都可以表示24bit的數據容量
//  b_pack只會占據 1 個 WORD 的存儲空間
//  b_unpack占據 3 個 WORD 的存儲空間
//  如果變量前后都有容量定義,右邊的維度高,即b_unpack的3的維度高

bit [3][7:0]  b_pack
bit [7:0]  b_unpack[3];

// logic是四值邏輯,即需要2bit
logic [3][7:0]   b_pack;       // 2 個WORD    2*8*3 
logic [7:0]   b_unpack[3];   //  3 個WORD    2*8=16, 1個WORD

    

數組復制和比較

  • 可以利用賦值符號  "="  直接進行數組的復制

  • 可以直接利用   "==" 或者  "!=" 來比較數組的內容,結果僅限於內容相同或者不相同

 動態數組

  •  定寬數組的寬度在編譯時就確定了;

  • 動態數組可以在仿真運行時靈活調節數組大小,即存儲量
// 動態數組在聲明時,需要使用  []  聲明,此時數組數組是空的,即0容量
// 使用new[]  來分配空間,在方括號中傳遞數組的寬度
// 也可以在調用 new[] 時將數組名傳遞,將已有的數組的值復制到新的數組中


initial begin: dynamic_array
  int dyn1[], dyn2[];
  
  dyn1 = new[5];         // 分配5個元素  
  dyn1 = '{1, 2, 3, 4};
  $display("dyn1 = %p", dyn1);
  // copp method option-1
  dyn2 = dyn1;           // 重新復制一份數據到dyn2,相當於深拷貝
  $display("dyn2 = %p", dyn2);
  $display("dyn2 size is %0d", dyn2.size());
  // copp method option-2
  dyn2 = new[dyn1.size()](dyn1);
  $display("dyn2 = %p", dyn2);
  $display("dyn2 size is %0d", dyn2.size());
  dyn2.delete();
  $display("dyn2 size is %0d", dyn2.size());
end

隊列 

  •  可以在任何地方添加或刪除元素,並且通過索引實現隊任一元素的訪問 
  • 使用美元符號聲明:[$],元素標號從0到$
  • 不需要使用new[] 去創建空間,一開始其空間為0
  • 使用 push_back 和 pop_front 結合實現FIFO的用法,還有push_front 和 pop_back
initial begin: queue_use
  int que1[$], que2[$];
 
  que1 = {10, 30, 40};            // 不需要使用單引號賦值
  $display("que1 = %p", que1);
  que2 = que1;
  $display("que2 = %p", que1);

  que1.insert(1, 20);
  $display("que1 = %p", que1);

  que1.delete(3);                     // delete que1[3]==40
  void'(que1.pop_front());         // pop que[0]==10
  $display("que1 = %p", que1);
  
  foreach(que1[i])
       $display(que1[i]);

  que1.delete();
  $display("que1 = %p", que1);

end            

 關聯數組

  • 用來保存稀疏矩陣的元素
initial begin: associate_array
  int id_score1[int], id_score2[int];     // key ID, value SCORE
  
  id_score1[101] = 111;
  id_score1[102] = 222;
  id_score1[103] = 333;

  // associate array copy
  id_score2 = id_score1;
  id_score2[101] = 101;
  id_score2[102] = 102;
  id_score2[103] = 103;

  foreach(id_score1[id]) begin
    $display("id_score1[%0d] = %0d", id, id_score1[id]);
  end
  foreach(id_score2[id]) begin
    $display("id_score2[%0d] = %0d", id, id_score2[id]);
  end

   if(id_score.first(idx)) begin
       do
           $display("id_score[%d]=%d", idx, id_score[idx]);
       while(id_score.next(idx));
   end

end    

結構體

  • 數據的集合
  • 使用struct語句創建
  • 結合typedef可以用來創建新的類型,並利用新類型來聲明更多的變量
struct {
              bit [7:0] r,g,b;
          }   pixel;                         // 創建一個pixel結構體  
         
typedef struct {
              bit [7:0] r,g,b;
          }   pixel_s;
pixel_s     my_pixel;    // 聲明變量
my_pixel = `{'h10, 'h10, 'h10};   // 賦值
 

枚舉

  • 可讀性和可維護性更好
  • 結合typedef使用
  • 枚舉類型可以直接賦值給整型: int a = INIT;
  • 整型不能直接賦值給枚舉類型,需要進行轉換
typedef enum {INIT,DECODE,IDLE}  fsmstate_e;

fsmstate_e pstate, nstate;   //  聲明自定義類型變量

case(pstate)
        IDLE: nstate = INIT
        INIT : nstate = DECODE;
        default:  nstate = IDLE;
endcase
$display("Next state is %s", nstate.name());

字符串(string)

  • SystemVerilog 包含一個string數據類型,它是一個可變尺寸、動態分配的字節數組。
  • SystemVerilog 還包含許多特殊的方法來對字符串進行操作。
    • string類型的變量可以從0到N-1(數組的最后一個元素)進行索引
    • 可以作用於一個特殊的空字符串:""
    • 從一個字符串讀取一個元素會產生一個字節
    • string類型變量的索引從字符串的左側開始排列,例如:對字符串"Hello World!",索引0對應"H",索引1對應"e",依此類推...
    • 如果在聲明中沒有指定初始值,變量會被初始化成空字符串("")
    • $sformatf()  函數: 格式化函數
    • $display()  函數: 打印函數
string s;
initial begin 
    s = "IEEE";
    $display (s.getc(0));      //顯示第0個字符: I

    $display (s.tolower());     //顯示小寫字符: ieee

    s.putc(s.len() - 1,"-");       //putc是替換,len() - 1是字符串最后一位,即將最后一位替換成“ -”

    s = {s,"P1800"};                 //字符串拼接 ->IEE-P1800

    $display(s.substr(2,5));         // 顯示第2-5位字符 ->E-P1
    //創建一個臨時字符串並將其打印
    my_log ($sformatf("%s,%5d",s,42));
end
task my_log (string message); //打印信息 $display ("@%0t:%s",$time,message); endtask

for循環

// $size 默認獲得最高的維度

initial begin
    bit        [31:0]  src[5],    dst[5];
    for(int i=0;i<$size(src); i++)
        src[i] = i;
end

foreach循環

//  自動創建變量j, 默認為最高維度
initial begin
    bit        [31:0]  src[5],    dst[5];
    foreach(dst[j])
        dst[j]  = j;
end    


免責聲明!

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



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