编写第一个类(class)
在Transaction中有两个子程序:一个输出数据包地址的函数和一个计算循环冗余校验码函数
class Transaction;
bit [31:0] addr,crc,data[8];
function void display;
$display("Transaction:%h",addr);
endfunction : display
function void calc_crc;
crc = addr^data.xor;
endfunction : calc_crc
endclass:Transaction
OOP术语
(1)类(class):包含变量和子程序的基本构建块。Verilog中与之对应的是模块。
(2)对象(object): 类的一个实例。在Verilog中你需要实例化一个模块才能使用它。
(3)句柄(handle):指向对象的指针。在Verilog中,你通过实例名在模块外部引用信号和方法。一个OOP句柄就像一个对象的地址,但是它保存在一个只能指向单一数据类型的指针中。
(4)属性(property):存储数据的变量。在Verilog中就是寄存器(reg)或者线网(wire)类型的信号。
(5)方法(method):任务或者函数中操作变量的程序性代码。Verilog中除了initial和always块以外,还含有任务和函数。
(6)原型(prototype):程序的头,包括程序名、返回类型和参数列表。程序体则包含了执行代码。
创建新对象
Transaction tr; //声明一个句柄
tr = new(); //为对象分配一个空间
new函数也称为:“构造函数”,因为它创建对象,一如用木头和钉子建造你的房子。但是new函数不能有返回值,因为构造函数总是返回一个指向类的对象的句柄,其类型就是类本身。
//简单定义的new()函数
class Transaction;
logic [31:0] addr,crc,data[8];
function new;
addr = 3;
foreach (data[i])
data[i] = 5;
endfunction
endclass
class Transaction;
logic [31:0] addr,crc,data[8];
function new(logic [31:0] a = 3,d = 5);
addr = a;
foreach (data[i])
data[i] = d;
endfunction
endclass
module tb_test;
initial begin
Transaction tr;
tr = new(10);
$display("tr.addr = %0d\ntr.data = %0p",tr.addr,tr.data);
end
endmodule
# tr.addr = 10
# tr.data = 5 5 5 5 5 5 5 5
调用new()函数仅创建了一个对象,而new[ ]操作则建立一个含有多个元素的数组。new()可以使用参数设置对象的值,而new[ ]只需要一个数值来设置数组的大小。
为对象创建一个句柄
Transaction t1,t2; //声明两个句柄
t1 = new(); //为第一个Transaction对象分配地址
t2 = t1; //t1 和 t2都指向该对象
t1 = new(); //为第二个Transaction对象分配地址
垃圾回收是一种自动释放不在被引用的对象的过程。SV分辨对象不再被引用的办法就是记住指向他的句柄的数量,当最后一个句柄不再引用某个对象了,SV就释放该对象的空间。
Transaction t; //创建一个句柄
t = new (); //分配一个新的Transaction
t = new (); //分配第二个,并且释放第一个t
t = null; //解除分配第二个
使用对象
Transaction t1;
t1 = new();
t1.addr = 32'h42; //设置变量的值
t1.display(); //调用一个子程序
简单的静态变量
SV中可以在类中创建一个静态变量。该变量将被这个类的所有实例所共享,并且它的使用范围仅限于这个类。
class Transaction;
static int count = 0;
int id;
function new();
id = count++;
endfunction
endclass
module static_tb;
initial begin
Transaction t1,t2;
t1 = new();
$display("Second id = %0d,count = %0d",t1.id,t1.count);
t2 = new();
$display("Second id = %0d,count = %0d",t2.id,t2.count);
end
endmodule
# Second id = 0,count = 1
# Second id = 1,count = 2