• SV--对象拷贝、参数化的类


    1 对象拷贝

    •    对于拷贝(copy), 对象的拷贝要比其它SV的变量类型都让人“当心”。
    •    因为就SV普通的变量拷贝而言,只需要通过赋值操作符”=”就足够了。
    •    而对象的拷贝则无法通过“=”来实现,因为这—操作是句柄的赋值,而不是对象的拷贝。

    1.1句柄拷贝 

    1. class basic_test;
    2. int fin;
    3. int def= 100;
    4. function new();
    5. $display{"basic_test::new");
    6. endfunction
    7. task test()
    8. $display ("basic_test::test");
    9. endtask
    10. endclass
    11. class test_wr extends basic_test;
    12. int def= 200;
    13. function new();
    14. super.new();
    15. $display("test_wr::new");
    16. endfunction
    17. test_wr h;
    18. initial begin
    19. wr = new();
    20. h = wr;
    21. $display ("wr.def = %0d", wr.def);
    22. $display ("h.def =%0d",h.def);
    23. h.def = 300;
    24. $display("wr.def =%0d",wr.def);
    25. $display ("h.def =%0d",h.def);
    26. end

     输出结果:
    # wr.def = 200 
    # h.def = 200 
    # wr.def = 300 
    # h.def = 300 

    •    在h=wr之后,由于是句柄的赋值,所以h. def = 300的操作,实际上是对这两个句柄指向的共同对象做的成员变量赋值。所以,从最终打印的结果可以看出,wr.def与t.def的值相同。

    1.2对象拷贝 

     •    那么如果要拷贝对象,指的是首先创建一个新的对象(开辟新的空间),再将目标对象的成员变量值拷贝给新对象的成员,这就使得新对象与目标对象的成员变量数值保持一致,即完成了对象的拷贝(成员变量的拷贝)。
    •    初学者需要区别句柄拷贝与对象拷贝的区别。

    1. class basic test;
    2. ...
    3. virtual function void copy_data(basic_test t);
    4. t.def= def;
    5. t.fin= fin;
    6. endfunction
    7. virtual function basic_test;
    8. basic_test t= new(0);
    9. copy_data(t);
    10. return t;
    11. endfunction
    12. endclass
    13. class test_wr extends basic_test;
    14. ...
    15. function void copy_data(basic_test t);
    16. test_wr h;
    17. super.copy_data(t);
    18. $cast(h,t);
    19. h.def = def;
    20. endfunction
    21. function basic_test copy();
    22. test_wr t= new();
    23. copy_data(t);
    24. return t;
    25. endfunction
    26. endclass
    27. module tb;
    28. ...
    29. test_wr wr;
    30. test wr h;
    31. initial begin
    32. wr = new();
    33. $cast(h, wr.copy());
    34. $display("wr.def = %0d", wr.def);
    35. $display("h.def = %0d", h.def);
    36. h.def = 300;
    37. $display("wr.def = %0d", wr.def);
    38. $display("h.def = %0d", h.def);
    39. end
    40. ...
    41. endmodule

     输出结果:
    # wr.def = 200

    # h.def = 200

    # wr.def = 200

    # h.def = 300 

    总结: 

    •    将成员拷贝函数copy_data()和新对象生成函数copy()分为两个方法, 这样使得子类继承和方法复用较为容易。
    •    为了保证父类和子类的成员均可以完成拷贝, 将拷贝方法声明为虚方法, 且遵循只拷贝该类的域成员的原则, 父类的成员拷贝应由父类的拷贝方法完成。
    •    在实现copy data()过程中应该注意句柄的类型转换, 保证转换后的句柄可以访问类成员变量。

    2.参数化的类 

    •   参数化的使用是为了提高代码的复用率。

    •   无论是设计还是验证,如果代码会被更多的人使用或者被更多的项目所采用,那么就需要考虑使用参数来提高复用率。

    •   参数的使用越合理,后期维护的成本就会相应降低。
    •   在硬件设计中,参数往往是整形,例如端口数目或者位宽。

    •   在验证环境中,参数的使用更加灵活,可以使用各种类型来做类定义时的参数。

    •   在SV中可以为类增加若干个数据类型参数,并在声明类句柄的时候指定类型。

    •   SV的类参数化近似于c++中的模板。

    1. class mailbox;
    2. local int queue[$];
    3. task put(input int i);
    4. queue.push_back(i);
    5. endtask
    6. task get(ref int o);
    7. wait(queue.size()>0) ;
    8. o=queue.pop_front();
    9. endtask
    10. task peek( ref int o);
    11. wait(queue.size()>O);
    12. o=queue[O];
    13. endtask
    14. endclass

     •    这个简化的mailbox的问题 在于它只能用于操作整数类型。
     •    如果要存储real类型,或者某一个类的句柄,那么就得复制该类,然后将数据类型由int类型转换为real类型或者某一个类的类型。

     •    这样将导致类的快速增长,而且是重复代码的大规模增长,代码维护将变得冗长乏味而且还容易出错。

    1. lass mailbox #(type T=int);
    2. local T queue[$];
    3. task put(input T i);
    4. queue.push_back(i);
    5. endtask
    6. task get( ref T o);
    7. wait (queue. size()>0);
    8. o=queue.pop_front();
    9. endtask
    10. task peek( ref T o);
    11. wait(queue.size()>0);
    12. o=queue[O];
    13. endtask
    14. endclass
    15. initial begin
    16. real o;
    17. mailbox #(real) mb; //创建一个存储real类型的mailbox
    18. mb = new();
    19. for(int i=O; i
    20. mb.put(i*2.0); //将real值存储入mb
    21. for(int i=O; i
    22. mb.get(o); //从mb取出real值
    23. end

     •    在类定义时添加参数#(type T=int), 这表示后期类在声明变量时如果不指定参数类型则默认采用int类型。
    •    将原代码int用参数T来代替。
    •    参数化的类将可以在后期例化时使用不同的参数, 以此来存储不同的数据类型。

  • 相关阅读:
    2000-2020上市公司全要素生产率LP方法含原始数据和Stata代码
    普中51单片机学习(DS1302)
    Linus Torvalds 宣布:Linux 5.18 第一个候选版本 (RC)公开测试普遍可用
    C语言程序-猜数字for
    研报精选 | 麦肯锡《业务流程自动化成功的必要条件》精要解读
    Item-Based Recommendations with Hadoop
    pt29django教程
    pem文件类解析
    【Gopher 学个函数】边学边练,简单为 Go 上个分
    Debian12系统下LAMP环境中Nubuilder4.5的安装
  • 原文地址:https://blog.csdn.net/weixin_45680021/article/details/126196129