[systemverilog]4_class/module_类的继承_成员覆盖_packet


1.class与module的异同
(1)
(2)
编译指的是run 0时刻前。对象是可以在编译时例化,即在run 0前就存在静态成员。

2.类的补充

3.类的继承
(1)关键字:extends
extends放在类名的子类名后,父类名前:
class 子类名 extends 父类名
(2)super:
在子类内,重新定义同名的父类函数,通过super来索引父类的同名函数。
super.父类函数名
(3)对象创建时初始化的顺序

4.成员覆盖
(1)在父类和子类里,可以定义相同名称的成员变量和方法(形式参数和返回类型也应该相同) ,而在引用时,也将按照 句柄类型来确定作用域
(2)例子
class basic_test;
int def = 100; //成员变量赋予默认值
int fin;
task test(stm_ini ini);
    $display ("basic test::test");
endtask
function new(int val);
...
endfunction 
endclass
//
class test_wr extends basic_test;
int def = 200;
function new();
    super.new (def);
    $display ("test wr::new");
    $display ("test wr: :super.def =%0d", super.def);
    $display ("test wr::this.def =%0d", this.def);
endfunction
...
endclass
//
module tb;
...
basic_test t;
test_wr wr;
initial begin 
    wr =new();
    t = wr;
    $display ("wr.def =%0d", wr.def) ;
    $display ("t.def =%0d", t.def) ;
end
  • wr.def和t.def的值分别是多少(200/100)(父类的句柄指向子类的对象时,作用域只能是父类);
  • wr=t;是不允许的,不允许直接父类句柄赋值给子类句柄。

5.句柄的传递
(1) 句柄可以作为形式参数通过方法来完成对象指针的传递,从外部传入方法内部。
(2)句柄也可以在方法内部首先完成修改,而后再由外部完成使用。
(3)例子
function void create(Transaction tr); //bug,missing ref
    tr =new(),
    tr. addr =100:
    // initialize other fields 
    ...
endfunction 
Transaction t;    //null
initial begin 
    cereate (t);
    t.addr =10;  //这一步就已经报错了,没有返回,t任然是null
    $display (t.addr);
end
最后显示的t.addr的数值为多少?(报错)
默认的是input,句柄悬空,没有返回值,解决方法:加inout;或者加ref。
(4)在程序执行时,可以在任何时刻为句柄创建新的对象,并将新的指针赋值给句柄。
task generate trans();
    Transaction t;
    Transaction fifo [$];
    t = new();
    for(int i=0; i<3; i++) begin
        t.addr =i << 2;
        fifo.push back (t);
    end 
    t=fifo.pop front();
endtask
t.addr的数值是多少?(8)
由于只例化了一个对象,所以最后句柄任然指向该对象的。for循环最后把addr改成了8;push back:从后面推;pop front:从前面取。

6.包(packet)的使用
(1) 概述
SV语言提供了一种在多个module, interface和program之中共享parameter, data, type, task, function, class等的方法,即利用package (包)的方式来实现。
如果用装修一个大房子(完整的验证环境)来看的话,我们喜欢将不同模块的类定义归整到不同的package中。
这么做的好处在于将一簇相关的类组织在了单一的命名空间(namespace)下,使得分属于不同模块验证环境的类来自于不同的package,这样便可以通过package来解决类的归属问题。
(2)语法
//packet定义
packet 包名
    ‘include “monitor.sv”
    ...
endpacket
(3)域名索引“::”操作符
如果我们将这些重名的类归属到不同的package中编译,不会发生重名的编译冲突。因为package是将命名空间分隔开来,这样如果要使用不同package中的同名类,他们只需要注明要使用哪一个package中的。利用操作符来显式指出所引用的类具体来自于哪一个package,这样便能很好地通过不同名的package来管理同名的类。
module mcdf_tb;
    regs_pkg: :monitor mon1 =new();
    arb_pkg: :monitor mon2 =new();
endmodule
(4)packet和library的区别
package更多的意义在于将软件(类、类型、方法等)封装在不同的命名空间中,以此来与全局的命名空间进行隔离。package需要额外定义,容纳各种数据、方法和类。
library是编译的产物,在没有介绍软件之前,硬件(module.interface, program)都会编译到库中,如果不指定编译库的话,会波编译进入默认的库中。从容纳的类型来看,库既可以容纳硬件类型,也可以容纳软件类型,例如类和方法,也包括package。
(5)包的命名规则
package regs_pkg;
    include "regs_stm,sv"
    include "regs_mon.sv" 
    include "regs_chk.sv" 
    include "regs_env.sv" 
endpackage 
Package arb_pkg;
    include "arb_stm.sv" 
    include "arb_mon.sv" 
    include "arb_chk. sv" 
    include "arb_env.sv" 
endpackage
module modf_tb;
    import regs_pkg::*;
    import arb_pkg::*;
    regs_mon monl= new();
    arb_mon mon2 = new();
endmodule
(6)总结

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值