zoukankan      html  css  js  c++  java
  • 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    
  • 相关阅读:
    登录页面上的验证码的生成
    数据库操作中使用事务进行提速
    Dotnet程序集自动生成版本号
    .NET与Java的Web Services相互调用(转)
    Struts配置
    C# WebService发布与调用方法(转)
    WinCE中C#WinForm利用Web Service查询数据库(转)
    C#打包
    VS2008快捷键大全
    这些话你懂吗?
  • 原文地址:https://www.cnblogs.com/gareth-yu/p/14200691.html
Copyright © 2011-2022 走看看