SystemVerilog Data Types1

本文详细介绍了SystemVerilog中的各种数据类型,包括字符串、结构体、数组、枚举、动态数组、队列和类型定义等。文章还讨论了控制流结构如循环、条件语句,以及任务和函数的使用。此外,提到了类和对象的概念,包括继承、多态和构造函数的用法。最后,探讨了随机化在验证中的应用和约束的重要性。
摘要由CSDN通过智能技术生成

1.1常用主要的基本数据类型列表

1.2 备注的编写

// this is a one-line comment

/*this is a multiple line comment.
since this line is within the block comment symbols,it is a comment.
*/

/* Another multiple line comment
// A nested one-line comment inside a block comme
But a block comment cannot be nested in another b
*/

1.3 systemverilog 可存在的值

0

逻辑0

1

逻辑1

x or x

逻辑x可为1也可以为0

z or Z

逻辑Z 高阻态

1.4 浮点与指数

module tb;
    real pi;
    real freq;
    
    initial begin
        pi   = 3.14;
        freq = 1e6;
        $display("Value of pi = %f",pi);
        $display("Value of pi = %0.3f",pi);
        $display("Value of pi = %0d",freq); 
    end
endmodule

/*Simulation Log

Value of pi = 3.140000
Value of pi = 3.140
Value of freq = 1000000.000000

*/

1.2strings

1.2.1什么是系统Verilog字符串?

数据类型是字符的有序集合。变量的长度是集合中的字符数,这 些字符数可以具有动态长度,并且在模拟过程中会发生变化。字 符串变量表示字符串的方式与字符串文本不同。使用该变量时不 会发生截断。

string variable_name = [=initial_value]
/* 
variable_name 是有效的标识符,可选initial_value可以是字符串文本、空字符串的值 “” 或字符串数据类型表达式。如果在声明时未指定初始值,则变量默认为 “”,即空字符串文本。
*/

1.2.2 systemverilog中string示例

module tb;
 // Declare a string variable called "dialog" to
 // Initialize the variable to "Hello!"
 string dialog = "Hello!";
 initial begin
 // Display the string using %s string format
    $display ("%s", dialog);
 // Iterate through the string variable to ide
    foreach (dialog[i]) begin
       $display ("%s", dialog[i]);
    end
 end
endmodule
/*Simulation Log
Hello!
H
e
l
l
o
!

*/

1.2.3 基本字符串方法

moudle tb;
    string str = "hello world"
    initial begin
        string tmp;
        
        $display("str.len()= %0d", str.len());//11

        tmp = str;
        tmp.putc(3,"d");
        $display("str.putc(3,d)=%s,temp");//heldo world

        $display("str.get(2) = %s(%0d)",str.getc(2),str.getc(2));//
        
        $display("str.tolower() = %s",str.tolower());//hello world
        
        tmp = "hello world";
        $display("[tmp,str are same]str.compare = %0d",str.compare(tmp));//0
        tmp = "how are you!";
        $display("[tmp,str are differ]str.compare = %0d",str.compare(tmp));//-1

        tmp = "hello world";
        $display("[tmp is in lowercase]str.compare(tmp) = %0d",str.compare(tmp));//-1
        tmp = "hello word";
        $display("[tmp,str are same]str.compare(tmp) = %0d",str.compare(tmp));//1

        $display("str.substr(4,8) = %s",str.substr(4,8))// o wor
    end
endmodule

1.3 structure

1.3.1结构体的定义

结构体表示存储在一起的并通过结构变量引用的数据类型的集合,可以包含不同数据类型的元素,这些元素可以作为一个整体引用,也可以通过其名单单独引用,这与元素具有相同数据类型的数组完全不同。

1.3.2 语法

struct{
    [list of variables]
}struct_name;

1.3.3 unpacked structures

默认情况下,结构是unpacked,可以使用关键字进行定义,并且可以在大括号内提供成员声明列表,后跟结构名称。

mudule tb;
    struct{
        string fruit;
        int    count;
        byte   expiry;
    }st_fruit;
    
    initial begin
        st_fruit = '{"apple",4,5};
   
         $display ("st_fruit = %p", st_fruit);
            //st_fruit = '{fruit:"apple", count:4, expiry:'hf}
         st_fruit.fruit = "pineapple";
         st_fruit.expiry = 7;
         $display ("st_fruit = %p", st_fruit);
            //st_fruit = '{fruit:"pineapple", count:4, expiry:'h7}
         end
endmodule

    end

1.3.4需要对结构进行类型定义吗?

在上面的示例中只创建了一个变量,但如果需要创建具有相同成 分的多个结构变量,则最好通过 创建结构的用户定义数据类 型。然后st_fruit将成为数据类型,然后可用于创建该类型的变 量。

module tb;

    typedef struct {
         string fruit;
         int count;
         byte expiry;
    } st_fruit;
    initial begin
         st_fruit fruit1 = '{"apple", 4, 15};
         st_fruit fruit2;
    
         $display ("fruit1 = %p fruit2 = %p", fruit1,fruit2);
//fruit1 = '{fruit : "apple",count : 4,expiry : 'hf},fruit2 = '{fruit : "",count : 0,expiry : 'h0}
    
         fruit2 = fruit1;
         $display ("fruit1 = %p fruit2 = %p", fruit1,fruit2);
//fruit1 = '{fruit : "apple",count : 4,expiry : 'hf},fruit2 ='{fruit : "apple",count : 4,expiry : 'hf}
    
         fruit1.fruit = "orange";
         $display ("fruit1 = %p fruit2 = %p", fruit1,fruit2);
//fruit1 = '{fruit : "orange",count : 4,expiry : 'hf},fruit2 ='{fruit : "apple",count : 4,expiry : 'hf}
     end
endmodule

1.3.5填充结构

打包结构是一种将向量细分为字段的机制,这些字段可以作为成 员访问,并且打包在内存中没有间隙。结构中的第一个成员是最 重要的,后续成员按重要性降序排列。 结构使用关键字声明打包,默认情况下该关键字为无符号。

// Create a "packed" structure data type which is
// bit [7:0] ctrl_reg;
// ctrl_reg [0] represents en
// ctrl_reg [3:1] represents cfg
// ctrl_reg [7:4] represents mode
typedef struct packed {
                         bit [3:0] mode;
                         bit [2:0] cfg;
                         bit en;
                        } st_ctrl;
module tb;
     st_ctrl ctrl_reg;
     initial begin
 // Initialize packed structure variable
         ctrl_reg = '{4'ha, 3'h5, 1};
         $display ("ctrl_reg = %p", ctrl_reg);
 // Change packed structure member to somethin
         ctrl_reg.mode = 4'h3;
         $display ("ctrl_reg = %p", ctrl_reg);
 // Assign a packed value to the structure var
         ctrl_reg = 8'hfa;
         $display ("ctrl_reg = %p", ctrl_reg);
      end
endmodule

log:
/*
ctrl_reg = '{mode:'ha, cfg:'h5, en:'h1}
ctrl_reg = '{mode:'h3, cfg:'h5, en:'h1}
ctrl_reg = '{mode:'hf, cfg:'h5, en:'h0}
*/

1.4 初步了解array

array 是一个变量,用于在连续位置存储不同的值

module tb;
     // The following two representations of fixed
     // myFIFO and urFIFO have 8 locations where e
     // 0,1 | 0,2 | 0,3 | ... | 0,7
     int myFIFO [0:7];
     int urFIFO [8];
     // Multi-dimensional arrays
     // 0,0 | 0,1 | 0,2
     // 1,0 | 1,1 | 1,2
     int myArray [2][3];
     initial begin
         myFIFO[5] = 32'hface_cafe; // Assign value to location 5 in 1D array
         myArray [1][1] = 7;        // Assign to location 1,1 in 2D array
         // Iterate through each element in the arra
         foreach (myFIFO[i])
             $display ("myFIFO[%0d] = 0x%0h", i, myFIFO[i]);
         // Iterate through each element in the mult
         foreach (myArray[i])
             foreach (myArray[i][j])
                 $display ("myArray[%0d][%0d] = %0d", i, j,myArray[i][j]);
    end
endmodule

//Simulation Log
myFIFO[0] = 0x0
myFIFO[1] = 0x0
myFIFO[2] = 0x0
myFIFO[3] = 0x0
myFIFO[4] = 0x0
myFIFO[5] = 0xfacecafe
myFIFO[6] = 0x0
myFIFO[7] = 0x0
myArray[0][0] = 0
myArray[0][1] = 0
myArray[0][2] = 0
myArray[1][0] = 0
myArray[1][1] = 7
myArray[1][2] = 0

1.5 void data-type

指定为函数和任务的返回类型以指示没有返回值

function void display();
    $display("Am not going to return any value");
endfuction
task void display();
    #10 $display("Me neither");
endtask

1.6 实数到整数的转换

实数将通过将实数四舍五入到最接近的整数而不是截断它来转换为整数。如果小数部分正好为 0.5,它将从零四舍五入。可以使用强制转换或使用系统任务指定显式转换。直接将实值分配给整型也将舍入而不是截断。

int'(2.0 * 3.0)
shortint'({8'hab,8'hef})
integer  $rtoi(real_val)
real     $itor(int_val)

1.7 SystemVerilog logic and bit

1.7.1 四值逻辑数据类型

除了(0) 和(1) 之外,还可以具有未知 (X) 和高阻抗 (Z) 值的类型称为 4 值逻辑类型。请注意,只能在过程块中驱动,例如数据类型只能在语句中驱动。SystemVerilog 引入了一种新的 4 值状态数据类型,称为可以在过程块和连续语句中驱动。但是,需要将具有多个驱动程序的信号声明为网络类型,以便SystemVerilog可以解析最终值。

module tb;
    logic [3:0] my_data;
    logic en;
    initial begin
         $display ("my_data=0x%0h en=%0b", my_data, en);
         my_data = 4'hB;
         $display ("my_data=0x%0h en=%0b", my_data, en);
         #1;
         $display ("my_data=0x%0h en=%0b", my_data, en);
    end
    assign en = my_data[0];
endmodule
//Simulation Log
my_data=0xx en=x
my_data=0xb en=x
my_data=0xb en=1

1.7.2二值逻辑数据类型

在典型的验证测试平台中,在许多情况下,我们并不真正需要所有四个值(0,1,x,z),例如,在使用指定数据包长度的标头对网络数据包进行建模时。长度通常是一个数字,但不是 X 和Z.SystemVerilog添加了许多新的 2 态数据类型,这些数据类型只能存储并具有 0 或 1 的值。这将有助于更快的仿真,占用更少的内存,并且在某些设计风格中是首选。当 4 态值转换为 2 态值时,任何未知或高阻抗位都应转换为零。最重要的 2 态数据类型是测试平台中最常使用的数据类型。类型的变量可以是 0 或 1,表示单个bit。应提供从MSB到LSB的范围,以使其表示和存储多个位bit。

module tb;
     bit         var_a; // Declare a 1 bit variable of type 'bit'
     bit   [3:0] var_b; // Declare a 4 bit variable of type 'bit'
     logic [3:0] x_val; // Declare a 4 bit variable of type 'logic'

     initial begin
 // Initial value of "bit" data type is 0
         $display ("Initial value var_a=%0b var_b=0x%0h",var_a,var_b);
 
         var_a = 1;
         var_b = 4'hF;
         $display ("New values var_a=%0b var_b=0x%0h",var_a,var_b);
 
         var_b = 16'h481a;
         $display ("Truncated value: var_b=0x%0h", var_b);
 
         var_b = 4'b01zx;
         $display ("var_b = %b", var_b);
     end
endmodule
//Simulation Log
Initial value var_a=0 var_b=0x0
New values var_a=1 var_b=0xf
Truncated value: var_b=0xa
var_b = 0100

1.8 systemverilog 'integer' and 'byte'

除了Verilog支持的所有数据以外,systemverilog还具有许多其他二值逻辑数据类型,例如bit、int、logic、byte。

1.8.1 integer

整数是没有小数部分的数字,换句话说,它们是整数。SystemVerilog 有三种新的有符号数据类型来保存整数值,每种值具有不同的大小。最小的是 -32768最大的是 32767。可以使用关键字和 显式定义符号。它们也可以相互转换。

默认情况下,整数变量本质上是有符号的,因此可以同时保存正值和负值。

module tb;
     shortint var_a;
     int      var_b;
     longint  var_c;
    
     initial begin
         $display ("Sizes var_a=%0d var_b=%0d var_c=%0d",$bits(var_a),$bits(var_b),$bits(var_c));
         #1  var_a = 'h7FFF;
             var_b = 'h7FFF_FFFF;
             var_c = 'h7FFF_FFFF_FFFF_FFFF;
     
         #1  var_a += 1; 
             var_b += 1; 
             var_c += 1;
      end

     initial begin
         $monitor ("var_a=%0d var_b=%0d var_c=%0d",var_a,var_b,var_c);
     end

endmodule

//simulation log

Sizes var_a=16   var_b = 32           var_c = 64
var_a = 0        var_b = 0            var_c = 0
var_a = 32767    var_b = 2147483647   var_c = 9223372036854775807
var_a = -32768   var_b = -2147483648  var_c = -9223372036854775808

我们将在上面的示例中声明的变量更改类型

module tb;
     shortint  unsigned var_a;
     int       unsigned var_b;
     longint   unsigned var_c;

     initial begin
         $display ("Sizes var_a=%0d var_b=%0d var_c=%0d",$bits(var_a),$bits(var_b),$bits(var_c));
             #1 
             var_a = 'hFFFF;
             var_b = 'hFFFF_FFFF;
             var_c = 'hFFFF_FFFF_FFFF_FFFF;
             #1 
             var_a += 1; 
             var_b += 1; 
             var_c += 1;
      end
     
     initial begin
         $monitor ("var_a=%0d var_b=%0d var_c=%0d",var_a,var_b,var_c);
     end

endmodule
//simulation log
Sizes var_a=16 var_b=32 var_c=64
var_a=0 var_b=0 var_c=0
var_a=65535 var_b=4294967295 var_c=18446744073709551615
var_a=0 var_b=0 var_c=0

1.8.2 bit

module tb;
     byte            s_byte;
     byte  unsigned  u_byte;
     initial begin
         $display ("Size s_byte=%0d, u_byte=%0d", $bit(s_byte),$bit(u_byte))
      
         #1 s_byte = 'h7F;
         u_byte = 'h7F;
 
         #1 s_byte += 1;
         u_byte += 1;
 
         #1 u_byte = 'hFF;
 
         #1 u_byte += 1;
     end
     initial begin
         $monitor ("[%0t ns] s_byte=%0d u_byte=%0d", $time,s_byte,$u_byte);
     end
endmodule

//simulation log
Size   s_byte=8,   u_byte=8
[0 ns] s_byte=0    u_byte=0
[1 ns] s_byte=127  u_byte=127
[2 ns] s_byte=-128 u_byte=128
[3 ns] s_byte=-128 u_byte=255
[4 ns] s_byte=-128 u_byte=0

1.9 枚举类型

枚举类型定义一组命名值。在下面的示例中, light_* 是一个枚举变量,可以存储三个可能的值 (0, 1, 2) 之一。默认情况下,枚举列表中的名字获取值 0,其余名称获取增量值,如 1 和2。用户可以为任何枚举名称分配任何整数值。如果任何名称没有分配的值,则它会自动采用以前名称的递增值。请注意,枚举名称不能以数字开头!

enum {RED, YELLOW, GREEN} 
enum bit[1:0] {RED, YELLOW, GREEN}

enum {RED=3, YELLOW, GREEN} 
enum {RED = 4, YELLOW = 9, GREEN} 
enum {RED = 2, YELLOW, GREEN = 3} 
enum bit[0:0] {RED, YELLOW, GREEN} 

enum {1WAY, 2TIMES, SIXPACK=6} e_formula; 
enum {ONEWAY, TIMES2, SIXPACK=6} e_formula; 

1.9.1如何定义新的枚举数据类型?

可以创建自定义数据类型,以便可以使用相同的数据类型来声明其他变量。

module tb;
    typedef enum {TRUE, FALSE} e_true_false;
    initial begin
        e_true_false answer;
        answer = TRUE;
        $display ("answer = %s", answer.name);//answer = TRUE
    end
endmodule

1.9.2 为什么使用枚举类型?

对比两段代码,枚举类型使得代码更加简单易读。

bit [1:0] light;
light = 2'b00; 
// 00 stands for - is it RED, YELLOW or GREEN ?
if (light == 2'b00)
————————————————————————————————————————————————
typedef enum {RED, YELLOW, GREEN} e_light;
e_light light;
light = RED; // Initialize light to RED
if (light == RED)
————————————————————————————————————————————————

1.9.3枚举类型的范围

module tb;
     // name : The next number will be associated with name starting from 0
     // GREEN = 0, YELLOW = 1, RED = 2, BLUE = 3
     typedef enum {GREEN, YELLOW, RED, BLUE} color_set_1;
     // name = C : Associates the constant C to name
     // MAGENTA = 2, VIOLET = 7, PURPLE = 8, PINK = 9
     typedef enum {MAGENTA=2, VIOLET=7, PURPLE, PINK} color_set_2;
     // name[N] : Generates N named constants : name
     // BLACK0 = 0, BLACK1 = 1, BLACK2 = 2, BLACK3 =
     typedef enum {BLACK[4]} colo
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值