SystemVerilog 第8章 面向对象编程高级技巧



8.1 继承简介

8.1.1 OOP术语

  • 属性(变量)
  • 方法(function&task)
  • 父类(原始类),子类(扩展类)
  • 基类(不从任何类继承)
  • 原型(包含返回值类型和参数列表在内的第一行)

8.1.2 transaction基类

class transaction;
	rand bit [31:0] src,dst,data;
	bit [31:0] crc;

	virtual function void calc_crc;
		crc = src^dst^data.xor;
	endfunction
endclass

8.1.3 类的继承

  • 子类可以直接访问父类中所有变量&方法
  • 子类可以用super调用父类的同名变量&方法
  • 不允许使用super.super.new()的方式多层调用
class badtr extends transaction;
	rand bit bad_crc;

	virtual function void calc_crc;
		super.calc_crc();
		if(bad_crc) crc = ~crc;
	endfunction
endclass

8.1.4 构造函数

  • 父类的new()有参数时,子类的new()中必须加一句super.new()并把参数传进去

8.1.5 driver

class driver;
	mailbox gen2drv;
	function new(input mailbox gen2drv);
		this.gen2drv = gen2drv;
	endfunction
	task main;
		transaction tr;
		forever begin
			gen2drv.get(tr);
			tr.calc_crc();
			@if.cb.src<=tr.src;
		end
	endtask
endclass

8.1.6 generator

class generator;
	mailbox gen2drv;
	transaction tr;
	function new(input mailbox gen2drv);
		this.gen2drv = gen2drv;
	endfunction
	task run;
		forever begin
			tr = new();
			assert(tr.randomize());
			gen2drv.put(tr);
		end
	endtask
endclass

8.2 蓝图模式

8.2.1 generator(蓝图模式)

  • 就是在generator中声明transaction基类的句柄blueprint,创建generator后在顶层将具体的子类事务对象传递给blueprint,然后调用generator.run()对blueprint进行随机化并发送
class generator;
	mailbox gen2drv;
	transaction blueprint;
	function new(input mailbox gen2drv);
		this.gen2drv = gen2drv;
		blueprint = new();
	endfunction
	task run;
		transaction tr;
		forever begin
			assert(blueprint.randomize());
			tr = blueprint.clone(); //blueprint只在run外声明了一个句柄,所以要把对象clone出来,不然下次run时就被覆盖了
			gen2drv.put(tr);
		end
	endtask
endclass

8.2.2 environment

  • environment实现:创建(create),运行(run),收尾(wrap-up)
class environment;
	generator gen;
	driver drv;
	mailbox gen2drv;
	function void build();
		gen2drv = new();
		gen = new(gen2drv);
		drv = new(gen2drv);
	endfunction
	task run();
		fork
			gen.run();
			drv.run();
		join_none
	endtask
	task wrap_up();
	//调用计分板&生成报告
	endtask
endclass

8.2.3 测试平台

program automatic test;
	environment env;
	initial begin
		env = new();
		env.build();
		begin
			badtr bad = new(); //将要发送的事务传给蓝图
			env.gen.blueprint = bad;
		end
		env.run();
		env.wrap_up();
	end
endprogram

8.3 类型转换

  • 向上类型转换:合法转换,直接parent=child
  • 向下类型转换:非法转换,当parent句柄实际指向的是child类型的对象时不是非法的,格式:$cast(child,parent)
  • 当把$cast(child,parent)当作task使用时(单独一句),转化失败会报错;当把$cast(child,parent)当作function使用时(当作if语句的参数),转化失败返回0但不报错

8.4 虚方法

  • 父类对象可以访问子类中的虚方法,使用virtual关键词
//父类
class transaction;
	...
	virtual function void calc_crc();
		...
	endfunction
endclass
//子类
class badtr extends transaction;
	...
	virtual function void calc_crc();//子类也可以不用再写virtual了
		...
	endfunction
endclass

8.5 对象的复制

  • 复制有两种:clone()和copy(),区别在于clone()=new()+copy()
//clone()
class transaction;
	rand bit [31:0] src, dst, data[8];
	bit [31:0] crc;
	virtual function transaction clone();
		clone = new();
		clone.src = src;
		clone.dst = dst;
		clone.data = data;
		clone.crc = crc;
	endfunction
endclass

//copy()
class transaction;
	rand bit [31:0] src, dst, data[8];
	bit [31:0] crc;
	virtual function copy(input transaction tr);
		this.src = tr.src;
		this.dst = tr.dst;
		this.data = tr.data;
		this.crc = tr.crc;
	endfunction
endclass

8.6 抽象类和虚方法

  • SV创建可以共享的基类方法有二
    ①抽象类: virtual声明的class
    ②纯虚方法: pure virtual声明的的方法原型
  • 抽象类不能直接实例化,只能被继承后并完善所有纯虚方法后才能实例化
  • 纯虚方法只能声明在抽象类,抽象类中可以pure virtual或virtual或普通方法

8.7 回调

  • 回调即在父类中定义一个virtual的空方法,然后子类需要的时候再调用重写添加功能

8.8 参数化类

  • 再class声明的时候在类名和参数列表之间添加#(type T)传入类型参数
  • 整数堆栈
class intstack;
	local int stack[100];
	local int top;
	function void push(input int i);
		stack[++top]=i;
	endfunction
	function int pop();
		return stack[top--];
	endfunction
endclass
  • 参数化的栈堆
class intstack#(type T=int);
	local T stack[100];
	local int top;
	function void push(input T i);
		stack[++top]=i;
	endfunction
	function int pop();
		return stack[top--];
	endfunction
endclass
  • 参数化蓝图模式generator
class generator#(type T=tr);
	mailbox gen2drv;
	T blueprint;
	function new(input mailbox gen2drv);
		this.gen2drv = gen2drv;
		blueprint = new();
	endfunction
	task run();
		T tr;
		forever begin
			assert(blueprint.randomize());
			tr = blueprint.copy();
			gen2drv.put(tr);
		end
	endtask
endclass
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值