1.1常用主要的基本数据类型列表
![](https://i-blog.csdnimg.cn/blog_migrate/1349cb4ef236ae8fb71f75db2a89d39c.png)
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