sv语法中virtualmethod和purevirtualmethod理解,sv中的virtualmethod和cast,多态

sv语法中virtualmethod和purevirtualmethod理解

举例说明:

class A_base ;

  int s0 =2;

  int s1 =3;

 function print_s0()

    $disaplay("print s0 value is %d", s0)

 endfunction

 virtual function print_s1()

    $display("print s1 value is %d",s1)

 endfunction

endclass

class A extends A_base;

  int s0=5;

  int s1=7;

  function print_s0()

      $disaplay("print s0 value is %d", s0)

  endfunction

  virtual function print_s1()

      $display("print s1 value is %d",s1)

  endfunction

endclass

virtual class B_base extends A;

pure virtual task  M( );

task body():

...........

endtask

endclass

class B extends um B_base;

task M( );

endtask

endclass

class test_base;

  B  b;

   task build_phase()

  b=B::get_type_id::create("b");

   endtask

   task run_phase()

   b.start(vsqr):  

   endtask

endclass

A_base p1=new();

A p2=new();

initial begin

  p1.print_s0();// s0=2

  p1.print_s1(); //s1=3

  p1=p2;//p1 has a handle of A object.

  p1.print_s0();//s0=2

  p1.print_s1();//s1=7, so the function was the last derived function

  p2.print_s0();//s0=5

 p2.print_s1();//s1=7

end

Notes : 

1.  A_base object&A object的关系. A is derived from A_base, they are all newed, so they are both implemented. p1=p2 意味着p1 get a handle/vector(句柄) from A 实体.   virtual function in A_base and A means they are polymorphic(多态),the function used last is the last derived one(传递的最后一个function)

2. B_base为virtual.  这个叫abstract class. 特性是它被extend之后的,里面的task会被implemented或者override。在B_base 里面的pure virtual task M 在它的derived class B里面被implemented。这个是pure virtual的特性。

3. 关于virtual, sv里面的一段话: A virtual method shall override a method in all of its base classes, whereas a non-virtual method shall only override a method in that class and its descendants. One way to view this is that there is only one implementation of a virtual method per class hierarchy, and it is always the one in the latest derived class。

4. 关于pure virtual,sv里面的一段话: 

An object of an abstract class shall not be constructed directly. Its constructor may only be called indirectly through the chaining of constructor calls originating in an extended non-abstract object.


A virtual method in an abstract class may be declared as a prototype without providing an implementation.This is called a pure virtual method and shall be indicated with the keyword pure together with not providing a method body. An extended subclass may provide an implementation by overriding the pure virtual method with a virtual method having a method body.

5. 通过#4, 我们知道abstract class只能在后面的non-abstract object 调用的时候被启动。 也就是说test_base里面.start 实际上是调用的 abstract class里面的body.虽然写的是non-abstract 的handle(对象)b.start().  作用:丰富base class的框架,便于分清层次关系。

sv中的virtualmethod和cast,多态

举例说明

1. no virtual的情况
class A;
      rand int length;
      task psprint();
         $display("the length is 0d%d", length);
     endtask
    endclass
class B extends A;
     rand int width;
      task psprint();
       $display("the width is 0x%d", width);
        super.psprint();
     endtask
    endclass
class test;
    A a=new();
    B b=new();
    a. psprint();// value=random length
   b.psprint();//value=random length, random width
    a=b;//only a=b, it's called upcast.  
   a.psprint();// value=random length,此时看不到b里面的psprint()
endclass
只有a=b这种可能性,因为A是B的父类。
2. class里带virtual task的情况
class A;
      rand int length;
     virtual task psprint();
         $display("the length is 0d%d", length);
     endtask
    endclass
class B extends A;
     rand int width;
    virtual task psprint();
       $display("the width is 0x%d", width);
        super.psprint();
     endtask
     task reserve_state();
        psprint();
    endtask
    endclass
class test;
    A a=new();
    B b=new();
    a. psprint();// value=random length
   b.psprint();//value=random length, random width
    a=b;//only a=b, it's called upcast.  
   a.psprint();// value=random length,random width 此时可看到b里面的psprint()
endclass
带virtual意味着A和B都是带虚方法的类。虚方法使用时必须保证名字和传递的变量一致,此时传递的变量都为空。
3. 父类看不到子类的重定义方法
class B;
     rand int width;
     task psprint();
       $display("the width is 0x%d", width);
     endtask
     task reserve_state();
        psprint();
    endtask
 endclass
class C extends B;
      rand int hight;
      task psprint();
        $display("the hight is 0d%d", hight);
     endtask
   endclass
class test;
    B b=new();
    C c=new();
   b.psprint();//value=random width  
   c.psprint();// value=random hight 此时可看到b里面的psprint()
   c.reserve_state(); //value=random width, 子类调用父类的方法
endclass
子类调用父类的方法,需要子类中没有重写此方法,默认调用父类的。
4. cast的使用举例
  4-1
  father f;
  child c1,c2;
  f=c1;//f指向的对象是类型是child的子类对象c1
  $cast(c2,f)//cast成功,c2和c1具有相同的类型child。此时f又指向的子类对象c2.
         父类站的高,子类在底下。
        从父类向子类的转换称为向下类型转换 (即 child_handle = father_handle,直接这样复制是不行的)
        反之则称为向上类型转换(即 father_handle = handle_handle)
        $cast 则是用于向下类型转换。
       在向下类型转换时,只有当父类指针指向的对象和待转换的类型一致时,cast才会成功。
原文链接:https://blog.csdn.net/lbt_dvshare/article/details/105155525
4-2

枚举类型的缺省类型为双状态int,可以使用简单的赋值表达式把枚举类型变量的值直接赋值给非枚举变量 如int.但SV不允许在没有进行显示类型转换的情况下把int变量直接赋值给枚举变量。SV要求显式的类型转换的目的在于让你意识到可能的数据越界情况。

typedef enum bit[1:0] {RED=0,BLUE,GREEN} COLOR_E;

COLOR_E color,c2;

int c;

initial begin

    color = BLUE;   // 赋值一个已知的合法的值

    c = color;      // 将枚举变量赋值给int,此时为 1

    c = c+1;       // int型变量递增

   if(!$cast(color,c))     // 将整型显示转换回枚举类型,如果越界会报错

       $display("cast failed for c= ",c);   // c的值此时为2

   $display("Color is /%s",color,color.name());

   c++;                  // c的值为3,对于枚举类型已然越界

    c2 = COLOR_E'(c);       // 不做类型检查,下句c2.name()由于越界而打印不出

   $display("c2 is /$s",c2,c2.name());    // 打印:c2 is 3/

原文链接:https://blog.csdn.net/lbt_dvshare/article/details/105155525

4-3 竟然是自己调自己。看起来会用在基类里面的重载。

class transaction;

  virtual function transaction copy(input transaction to);

   if(to==null)

      copy = new();

   else 

      copy = to;

    copy.src = this.src;

    return copy;

  endfunction

endclass

class badtr extends transaction;

  virtual function transaction copy(input transaction to);

    badtr bad;

   if(to==null)

      bad = new();

   else 

     $cast(bad,to);

   super.copy(bad); 

   bad.bad_csm = this.bad_csm;

    return bad;

  endfunction

endclass

badtr b_tr1 = new();

badtr b_tr2 = new();

badtr b_tr3;

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值