struct&class
相较于class(属性+方法),struct只是把数据放到一起。
因此,struct的功能较少,没有操作数据的方法。
总结:使用struct,不如在testbench中直接使用class。
一、结构体
我们知道一个菜包子是由好几种材料组成的,那么我们如何描述一个菜包子呢?
为了方便,我们使用struct结构体来描述。
struct baozi{
string name;
int weight;
int skin;
int filling;
int flavor;
}
可以看到它有五个数据成员,分别是:
string类型的名字name,比如“caibaozi"即代表菜包子
int型包子的重量weight,比如150即代表包子重量是150克
int型的面皮skin,比如0代表高筋面粉,1代表中筋面粉等
int型的馅料filling,比如0代表青菜,1代表萝卜丝等
int型的调料flavor,比如0代表酱油,1代表盐等
可以看到我们通过使用结构体将包子中的材料封装到了一起,即我们将数据成员封装到了一起。
struct只是把数据放到一起,没有操作数据的方法。
想要在程序中使用它,则必须使用typedef 创建一个新的类型
1. 使用typedef语句创建新的类型
基本格式:typedef 已有类型 自定义类型
一般自定义类型后面添加一个_t,方便区分。
typedef struct{int a;
byte b;
int c;
} struct_t;//定义新的变量类型
2. 对结构体进行初始化(赋值)
module top;
initial begin
typedef struct{int a;
byte b;
int c;
} struct_t;//定义新的变量类型
struct_t st;//变量声明(变量类型+变量名称)
st = '{32'haaaa_bbbb,
8'hcc,
32'hacac_acac}; //赋值方法1
//st.a=32'haaaa_adcd; 赋值方法2
$display("struct_a %h",st.a);
$display("struct_c %h",st.c);
end
endmodule
sim_report
module top;
initial begin
typedef struct{int a;
byte b;
int c;
} struct_t;
struct_t st;
st.a=32'haaaa_adcd;
$display("struct_a %h",st.a);
$display("struct_c %h",st.c);
end
endmodule
sim_report
二、class
下面要介绍的类(class)既提供了包子的材料又提供了做包子的方法。
1.创建对象(开辟新的内存空间,用来存放新的成员变量和方法)
Transaction tr;// 句柄声明
tr = new(); //创建对象(例化),并将其赋予句柄
//一个Transaction对象分配空间,同时初始化变量
2.构造函数:new( )
定义:new()是系统预定义的函数,不需要返回值
作用:用于创建类的对象和初始化变量(module里),还可以通过自定义new()将默认值设置成你想要的数值(class里)
class Transaction;
logic [31: 0] addr,crc, data[8];
function new(logic [31:0] a=3,d=5);
//构造函数new()的默认值 a=3;d=5
addr = a;
foreach(data[i])
data[i]=d;
$display("a is: %d", a);
$display("data array is: %p", data);
endfunction : new
endclass: Transaction
module top;
initial begin
Transaction tr;
tr=new(1,2);//创建类的对象和初始化变量,通过构造函数new()外部传入数值
end
endmodule
sim_report
class baozi;
string name;
int weight;
int skin;
int filling;
int flavor;
function new(string name,int weight);
this.name = name ;
this.weight = weight;
endfunction
//this.表示在当前类中查找
//通过function new将name和weight传递给类里面的成员变量,即输入端口的name和weight传递到类
function void make_baozi();
$display("A baozi is completed!");
$display("Baozi name is %s",name);
$display("Baoziweight is %d" ,weight);
$display("Baoziskin is %d",skin);
$display("Baozifilling is %d",filling) ;
$display("Baozi flavor is %d",flavor);
endfunction
endclass
module top;
baozi baozi_h;//句柄的声明
initial begin
baozi_h = new(.name("caibaozi") ,.weight(150)) ;
//构造函数,并在构造时完成传参
baozi_h.skin = 0;
baozi_h.filling = 1;
baozi_h.flavor = 0;
//通过句柄加点的方式给类的成员变量赋值
baozi_h.make_baozi();
end
endmodule : top
sim_report
3.在class之外定义方法(可读性强)
使用关键词extern,sv可以在一个class外定义task和function。
class baozi;
string name;
int weight;
int skin;
int filling;
int flavor;
extern function new(string name,int weight);
extern function void make_baozi();
endclass
function baozi::new(string name,int weight);
this.name = name ;//将参数传递给类里面的成员变量
this.weight = weight;
endfunction
//this.表示在当前类中查找
//通过function new将name和weight传递给类里面的成员变量,即输入端口的name和weight传递到类
function void baozi::make_baozi();
$display("A baozi is completed!");
$display("Baozi name is %s",name);
$display("Baoziweight is %d" ,weight);
$display("Baoziskin is %d",skin);
$display("Baozifilling is %d",filling) ;
$display("Baozi flavor is %d",flavor);
endfunction
module top;
baozi baozi_h;//句柄的声明
initial begin
baozi_h = new(.name("caibaozi") ,.weight(150)) ;//构造函数,并在构造时完成传参
baozi_h.skin = 0;
baozi_h.filling = 1;
baozi_h.flavor = 0;
//通过句柄加点的方式给类的成员变量赋值
baozi_h.make_baozi();
end
endmodule : top
sim_report
this.作用:是先在当前作用域内寻找,接着在上一级作用域(父类)内寻找,直到找到该变量为止