路科验证学习笔记(V0_4)——用类封装随机化变量

  • SV的function与task

    • 联系
      • 参数列表均可以声明多个input、output、inout、ref。其中,input是从外部复制传入的形式参数;output是由被调用的方法产生复制传递给外部的形式参数;inout表示进入方法和退出方法分别复制;ref则类似指针。
      • inout和ref都可以使形式参数在方法中被调用,区别在于inout在方法结束时传到外部;ref在方法执行时直接修改参数并且作用于可以调用该参数的所有地方,无需等到方法执行结束。
    • 区别:
      • task无法用return返回,只能用output、inout、ref。
      • task可以内置耗时语句,function不可。常见的耗时语句:@event,#delay,wait(条件)。
      • task可以调function,反过来不行
  • automatic与static

    • 前者在其作用域声明周期结束时候被销毁回收存储空间,static在仿真任何时刻都可以被共享,不会被销毁直到仿真结束。
    • automatic方法中的变量默认也是automatic,随automatic方法生命周期建立和销毁。static方法中变量默认是static。但是也可以显示声明方法中的参数为不同于方法的属性。
    • 在module、program、interface、task、function之外声明的变量有静态生命周期,存在于整个仿真阶段。
    • 在module、program、interface内部,task、function外部声明的变量也是静态变量,作用于该module、program、interface。存在于整个仿真阶段。
    • 在module、program、interface中定义的task、function默认静态,为了让task、function,以及在其中声明的变量有统一的生命周期,可以在定义module、program、interface时定 automatic、static(默认是static)。在task、function定义的变量作用域位于本task、function内。
    • 若忘了声明某个变量,SV会到更高层的作用范围去寻找,直到找到匹配的变量声明。若两部分代码无意间共享使用了同名的变量,这一问题往往难以发现。原因在于忘了在最内层进行声明,从而限定作用域。全局变量声明和使用一定要谨慎。
  • 在SV中析构函数被弱化,只看到new()来创建trans,每一个trans被创建、使用完毕之后自动被析构掉,因为他不是验证结构的一部分。

  • 仿真的结构必须是从0时刻开始就有,伴随到仿真结束。比如Generator class、Driver class等。SV用类来构建验证结构。

  • 在验证工作中经常使用"virtual"关键字,下面列举该关键字应用场景。
    主要应用场景在virtual class,virtual interface 以及 virtual task/function。
    OOP三大特性(封装,继承,多态)中的 多态 在SystemVerilog中一般通过 “virtual” 关键字实现。
    通过virtual声明的类,接口,任务与函数,其本身自带一些方法或者函数。后续的例化或者扩展可以对原有的内容进行增加或者修改,从而实现同一函数不同方法的多种形态。

    1. virtual interface
      在interface定义时,如果不使用关键字 “virtual” 那么在多次调用该接口时,在其中的一个实例中对接口中某一信号的修改会影响其他实例接口;如果使用了 “virtual” 关键字,那么每个实例是独立的。
      习惯上在声明类的interface时均添加 "virtual"关键字。
    2. virtual task/function
      用于OOP思想的继承使用。当定义了virtual时,在子类中调用某task/function时,会先查找在子类中是否定义了该 task/function,如果子类没有定义,则在父类中查找。未定义virtual时,只在子类中查找,没有定义就是编译器报错。
      如果某一class会被继承,则用户定义的task/function(除new(),randomized(),per_randomize(),pose_randomize()外),都应该加上virtual关键字,以备后续扩展。
    3. virtual class
      抽象类一般用来定义类的格式、类的成员、类的参数等。抽象类不能被实例化,只能被扩展(重载)后实例化,用于在项目中定义一些标准的类。

    抽象类中的方法通常使用关键字 " pure virtual " 纯虚方法。同时OOP规定,只要class中存在一个没有被实现的pure function,就不允许例化这个class。

virtual class (抽象类):可以被扩展但是不能被直接例化,由抽象类扩展而来的类,只有在所以的虚拟方法都有实体的时候才能被例化。
pure virtual function(纯虚方法):没有实体的方法原型,相当于一个声明,只能在抽象类中定义。
  • this的使用方法:
    当使用一个变量名的时候,systemverilog将先在当前作用域内寻找,接着在上一级作用域内寻找,直到找到该变量为止。
function DriverBase::new(string name, virtual router_io.TB rtr_io);	//接口均添加 "virtual"关键字
  //TRACE_ON是一个 test program 的全局变量,可方便debug时控制打印信息
  if (TRACE_ON) $display("[TRACE]%t %s:%m", $realtime, name);
  this.name   = name;	//DriverBase类的 name = string name (子类 new 传来的)
  this.rtr_io = rtr_io;
endfunction
  • 防止class被多次编译
`ifndef INC_PACKET_SV	
`define INC_PACKET_SV
......
`endif
  • SV中复制现存对象给新对象:
 Packet pkt = new this.pkt2send;
		//1. new 创建新对象
		//2. 拷贝 this 所指的对象给新对象,也就是调用gen() 方法所产生的随机化的对象给新对象
		//3. 将 Packet pkt 句柄指向该新对象 
  • 在class外部写函数体的方法:
class Packet;
.......
extern function new(string name = "Packet");
endclass: Packet

function Packet::new(string name);
  //Lab 4 - Task 5, Step 2
  //
  //Inside new() assign class property name with string passed via argument
  //ToDo
  this.name = name;
endfunction: new
  • 全局变量是在所有函数体的外部定义的,程序的所在部分(甚至其它文件中的代码)都可以使用。全局变量不受作用域的影响(也就是说,全局变量的生命期一直到程序的结束)。如果在一个文件中使用 extern关键字来声明另一个文件中存在的全局变量,那么这个文件可以使用这个数据。
  • 在全局变量前加一个 static,使该变量只在这个源文件中可用。
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Arist9612

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值