学习目标:
SV绿皮书第五章:面向对象编程基础
学习内容:
1.简单的静态变量
class Transaction;
static int count=0; //已创建的对象的数目
int id; //实例的唯一标志
function new();
id=count++; //设置标志,count递增
endfunction
endclass
Transaction t1,t2;
initial begin
t1=new();
t2=new();
$display("Second id=%d,count=%d",t2.id,t2.count); //使用句柄来引用静态变量
$display("Second id=%d,count=%d",t2.id,Transaction::count); //类名加::即类作用域操作符
end
2.类中的静态方法可以声明并使用动态变量,但是不能使用类的动态成员变量
静态方法可以使用类的静态变量
3.如果没有指明访问类型,那么成员的默认类型是public,子类和外部均可以访问成员
如果指明了访问类型是protected,那么只有该类和子类可以访问成员,而外部无法访问
如果指明了访问类型是local,那么只有该类可以访问成员,子类和外部均无法访问
4.子类在定义new函数时,应该首先调用父类的new函数(super.new())。如果父类的new函数没有参数,则可以省略,系统在编译时会自动添加。
5.对象创建初始化顺序,有如下规则:
子类的实例对象在初始化时首先会调用父类的构造函数
当父类构造函数完成时,会将子类实例对象中的各个成员变量按照它们定义时显示的默认值初始化,如果没默认值则不被初始化
在成员变量默认值赋予后,才会最后进入用户定义的new函数中执行剩余的初始化代码
6.包的使用
package regs_pkg;
'include "regs_stm.sv"
'include "regs_mon.sv"
'include "regs_chk.sv"
'include "regs_env.sv"
endpackage
package arb_pkg;
'include "arb_stm.sv"
'include "arb_mon.sv"
'include "arb_chk.sv"
'include "arb_env.sv"
endpackage
module mcdf_tb;
import regs_pkg::*;
import arb_pkg::*;
regs_mon mon1=new();
arb_mon mon2=new();
endmodule
7.在类之外定义方法
class PCI_Tran
bit [31:0]addr,data; //使用实名
extern function void display();
endclass
function void PCI_Tran::display();
$display("@%0t:PCI:addr=%h,data=%h",$time,addr,data);
endfunction
8.如果在一个块内使用了一个未声明的变量,碰巧在程序块中有一个同名的变量,那么类就会使用程序块中的变量,不会给出警告。
program test;
int i; //程序级变量
class Bad;
logic [31:0]data[];
//调用该函数将会改变程序级的变量i
function void display;
//没有声明i
for(i=0;i<data.size;i++)
$display("data[%0d]=%x,i,data[i]);
endfunction
endclass
endprogram
如果你将类移到一个package中,类就看不到程序一级的变量了
package Mistake;
class Bad;
logic [31:0]data[];
//未定义i,不会被编译
function void display;
for(i=0;i<data.size;i++)
$display("data[%0d]=%x,i,data[i]);
endfunction
endclass
endpackage
9.编译一个类(包含一个尚未被定义的类时),你需要使用typedef语句声明被包含的类名,否则会引起错误
typedef class Statistics; //定义低级别类
class Transaction;
Staistics stats; //使用Staistics类
.....
endclass
class Statistics; //定义Staistics类
.....
endclass
10.在任务中修改句柄,要在方法的参数前加ref关键词
function void create(Transaction ref tr);
tr=new();
tr.addr=42;
...
endfunction
Transaction t;
initial begin
create(t); //创建一个transaction
$display(t.addr);
end
11.创建一个对象,并多次传送给设计,会导致错误
12.句柄数组
task generator();
transmit tarray[10];
foreach (tarray[i])
begin
tarray[i]=new(); //创建每一个对象
transmit(tarray[i]);
end
endtask
不存在“对象数组”的说法
13.对象的复制 P125-128
14.邮箱:一个能够延迟一个线程直到有新的数值加入的FIFO
问题:
学习时间:
早:9-11.30
中:15-17.30
晚:20.30-21.40