systemverilog class

看中文版的《systemverilog验证》,总感觉云里雾里。尝试看看官方systemverilog教程,主要是因为页数少。
systemverilog官方文档,是《SystemVerilog 3.1a Language Reference Manual Accellera’s Extensions to Verilog®》。关键词是:SystemVerilog Accellera。建议不要看cadence、synopsys、mentor的文档;但是后续可以参考。

overview

tips

类的数据,叫属性;
类的function/task,叫方法;

codes

class Packet ; 
   //data or class properties 
   bit [3:0] command; 
   bit [40:0] address;
   bit [4:0]  master_id;
   integer    time_requested;
   integer    time_issued;
   integer    status;

   // initialization 
   function new();
      command = IDLE;
      address = 41’b0;
      master_id = 5’bx; 
   endfunction // new

   // methods 
   // public access entry points 
   task clean(); 
      command = 0; address = 0; master_id = 5’bx; 
   endtask
   task issue_request( intdelay );
      // send request to bus 
   endtask
   function integer current_status();
      current_status = status; 
   endfunction
endclass

objects(class instance)

tips

类的实例化,跟vhdl类似;但是跟verilog实例化不一样。是分两步骤完成的。
1. 类的声明;
2. 类的实例化;也叫构造函数,new。
3. 父类,又叫超类。所以,继承类里访问父类的属性时,会用super.new这样的方式。

codes

Packet p; // declare a variable of class Packet 
p = new; // initialize variable to a new allocated object of the class Packet
class Packet;
   integer command;

   function new();
      command = IDLE; 
   endfunction
endclass

静态变量

特点:
1. 静态变量,是父类和相关子类的共享变量。类的默认变量,一般都是非静态变量,是独立的,不可共享的;也就是说,静态变量是共用一片存储空间,只要父类或者相关子类对这个静态变量赋值,后续操作,都是基于变化后的变量进行操作的。个人理解,静态变量是全局变量;非静态变量是私有变量。
2. 静态变量的访问,只需要声明类;而不需要构造函数,即实例化。

classPacket ;
static integerfileId = $fopen( "data", "r" );
Packet p;
c = $fgetc( p.fileID );

静态方法

类似静态变量。
1. 能够被当前类及子类访问;存储空间是共享的。
2. 类只需要声明,不需要实例化;即可访问这个类中的静态方法。
3. 静态方法,不能访问非静态变量(以及非静态class属性和非静态方法)。
4. 静态方法,不能设置为虚拟方法,virtual。

class id;
   static int current = 0;
   static function int next_id();
      next_id = ++current; // OK to access static class property
   endfunction
endclass

this

  1. this只能应用于非静态的class method;
  2. this的用法,不太常用;但是很必要。一般是下述例子会用到;因为class的变量和function的变量是一样名称,用this.x来表示class的变量。
class Demo ;
   integer x;
   function new(integer x) 
      this.x = x;
   endfunction
endclass

Assignment, re-naming and copying

注意下述两段代码的不同点。
1. 代码段1,只实例化了一个object;
2. 代码段2,实例化了两个object;p2复制了p1的class属性,包括变量和instance handles

Packet p1;
Packet p2;
p1 = new;
p2 = p1;
Packet p1;
Packet p2;
p1 = new;
p2 = new p1;

下例的行为,导致类A的变量j,成为共享变量。如果没有B b2 = new b1;,而是B b2 = new;
那么类A的变量j和类B的变量a.j,应该是独立的。—此为个人理解,还未验证。

class A ;
  integer j = 5; 
endclass
classB ;
  integer i = 1;
  A a = new;
endclass
function integer test;
   B b1 = new; // Create an object of class B
   B b2 = new b1; // Create an object that is a copy of b1
   b2.i = 10; // i is changed in b2, but not in b1
   b2.a.j = 50; // change a.j, shared by both b1 and b2
   test = b1.i; // test is set to 1 (b1.i has not changed)
   test = b1.a.j; // test is set to 50 (a.j has changed)
endfunction

Inheritance and subclasses

虚拟方法

  1. 虚拟方法,可以支持method的override;方法名称一样的话,距离越近,方法名称一致的方法最优调用(注意,方法必须全部声明为virtual)。
  2. 方法未定义为虚拟属性;那么调用的方法,是基类的方法;而不是距离最近的类方法。
class BasePacket;
   int A = 1;
   int B = 2;
   function void printA;
      $display("BasePacket::A is %d", A);
   endfunction : printA
   virtual function void printB;
      $display("BasePacket::B is %d", B);
   endfunction : printB
endclass : BasePacket

class My_Packet extends BasePacket;
   int A = 3;
   int B = 4;
   function void printA;
      $display("My_Packet::A is %d", A);
   endfunction: printA
   virtual function void printB;
      $display("My_Packet::B is %d", B);
   endfunction : printB
endclass : My_Packet

BasePacket P1 = new;
My_Packet P2 = new;
initial begin
   P1.printA; // displays 'BasePacket::A is 1'
   P1.printB; // displays 'BasePacket::B is 2'
   P1 = P2; // P1 has a handle to a My_packet object
   P1.printA; // displays 'BasePacket::A is 1'
   P1.printB; // displays 'My_Packet::B is 4' – latest    derived method
   P2.printA; // displays 'My_Packet::A is 3'
   P2.printB; // displays 'My_Packet::B is 4'
end

纯虚方法

在父类里定义个方法的原型,没有内容。
具体实际需求,不清楚。

多态

多态的概念引入,针对的是类的句柄可以改变吧?!这个是个人理解,待确认。

假设:
1. 基类是BasePacket,子类是EtherPacket、TokenPacket、GPSPacket。
2. 另外子类,有virtual方法,send、receive、print。

BasePacket packets[100];
EtherPacket ep = new; // extends BasePacket
TokenPacket tp = new; // extends BasePacket
GPSPacket gp = new; // extends EtherPacket
packets[0] = ep;
packets[1] = tp;
packets[2] = gp;

经过如上假设和代码设计,packets[1].send()访问的是TokenPacket类的send方法。

Class scope resolution operator ::

class Outer;
   int outerProp;
   local int outerLocalProp;
   static int outerStaticProp;
   static local int outerLocalStaticProp;
   class Inner;
      function void innerMethod(Outer h);
         outerStaticProp = 0;
         // Legal, same as Outer::outerStaticProp
         outerLocalStaticProp = 0;
         // Legal, nested classes may access local's in outer class
         outerProp = 0;
         // Illegal, unqualified access to non-static outer
         h.outerProp = 0;
         // Legal, qualified access.
         h.outerLocalProp = 0;
         // Legal, qualified access and locals to outer class allowed.
      endfunction
   endclass
endclass
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值