天天看点

2020-08-26 system verilog学习笔记

8 OOP技巧

1、 类的继承,如果父类构造函数无参数和返回类型,则子类扩展类不需要构造函数,如只继承变量类和方法

2、 父类的方法定义成虚方法,这样就可以再扩展类中重定义

3、 子程序的原型prototype是指明了参数列表和返回类型的第一行。

4、 当启动扩展类的时候,构造函数new:如果基类里有参数,那么扩展类必须有一个构造函数new(var),并且必须再构造函数第一行调用基类的构造函数super.new(input int var);

5、声明一个虚方法,这样svhi查看存储再tr中的对象类型,并且以此选取恰当的方法或访问正确的对象类型。如果对象是父类类型,那么调用父类方法

6、蓝图模式:想要构建一个事务发生器得时候,不需要知道怎样建立各种类型得事务,只需要能够根据给定得事务建立一个类似的新事务。

构建并使用一个对象:

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      

任务run创建了一个书屋并立即随机化该值。这意味着该transaction 使用默认 所有约束。若要修改约束,只能修改transaction类,不符合验证准则;并且gen只使用了transaction对象,因此无法使用扩展对象,所以只能将tr得创建和初始化分开。

先构建一个对象的blueprint,然后修改他的约束,甚至使用一个扩展对象替换它。当随机化这个blueprint的时候,就会赋予想要的随机值。接着赋值这个对象,发给下游transaction。修改bluprint对象就是修改摸具。

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.copy();
        gen2drv.put(tr);
    end
endtask
endclass
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


program automatic test;
Environment env;
initial begin
    env=new();
    env.build();
    begin
        BadTr=new();
        env.gen.blueprint=bad;
    end
    env.run();
    env.wrap_up();//清理内存
end
endprogr      

为了注入错误,将tr对象转换为扩展类badtr对象,再创建和运行环境阶段完成,改变蓝图。

7、 类型转换和虚方法

bad=new();构建扩展类对象


tr=bad;子类将句柄赋值给父类,父类句柄指向子类对象可行


tr.src//基类对象成员src可见


tr.display;//BadTr::display


tr=new();


bad=tr;子类句柄指向父类对象;


bad.bad_crc//不可行,基类对象不可见bad_crc
//-------
$cast(bad,tr);//检查tr指向的对象类型,如果是子类独享,那么赋值会成功,      

8、 virtual方法

sv会根据对象类型来决定调用什么方法,句柄tr指向子类对象,那么会调用子类的方法。

如果不加virtual,会根据句柄类型调用方法,可能调用出错

继续阅读