Verilog系列:不要随意new对象

”,同样类作为一种特殊的类型也存在着类似的问题.面对复杂的设计功能,验证平台的构建也越来越复杂,经常会遇到各种问题,其中经常遇到的一个典型问题就是构建测试平台时,部分类中在创建后其成员的数值与期望不符,但是检查语法结构都是正确的.本文将基于这个问题进行示例说明并给出一些建议.
【示例】
`timescale 1 ns / 1 ps
class cobj;
int data;
function new(int data);
    this.data = data;
endfunction
task void disp();
    $display(“The cobj data is %h”,data);
endtask
endclass    // cobj

class cobj1;
int data = 1;
cobj pt = new(data);
task void disp();
    pt.disp;
endtask
endclass    // cobj1

module top_tb;
cobj1 ptr;
initial begin
    ptr = new;
    ptr.disp;
end
endmodule    // top_tb

【仿真结果】

The cobj data is 00000001!

在cobj1实例化时,首先会初始化其中的属性成员,14行"cobj pt"在声明的同时进行了实例化操作,其中调用构造函数时传递的参数在13行已经声明并且赋值,所以此时传递给new的参数数值为"1".所以在23行实例化cobj1后在24行通过cobj1的disp调用cobj的disp后的输出结果如上述的仿真结果.虽然这个结果可能时期望的,但是这种用法存在一种潜在问题,如下例.

【示例】

`timescale 1 ns / 1 ps
class cobj;
int data;
function new(int data);
    this.data = data;
endfunction
task void disp();
    $display(“The cobj data is %h”,data);
endtask
endclass    // cobj

class cobj1;
cobj pt = new(data);
int data = 2;
task void disp();
    pt.disp;
endtask
endclass    // cobj1

module top_tb;
cobj1 ptr;
initial begin
    ptr = new;
    ptr.disp;
end
endmodule    // top_tb

【仿真结果】

The cobj data is 00000000!

此例相对于上例仅仅是交换了13行和14行执行语句的顺序,但是仿真结果已经完全不一样了.主要是因为13行执行时,data此时还没有被初始化,所以此时传递给new的data的值为data数值类型的默认值,即0.等到14行执行时,"cobj pt"已经完成实例化,其中的值已经不能再被改变(除非通过cobj中相关的方法进行修改).同时,这样的coding方式,有些编译器会认为是错误的.这里需要注意,虽然很多语言存在所谓的并行语句结构(例如fork...join等),但是实际上其中语句的执行是按照一种"微观"的顺序依次执行(可使用仿真器的调试功能观测到具体语句的执行顺序),所以在这个件的结构中语句的执行顺序对于对象的实例化都会产生巨大的影响,可以想象在复杂设计中产生的影响可能更加复杂.为此,为了确保对象实例化后能够获得期望的数值,建议任何成员的初始化在new函数中进行,同时一定要秉持先定义后使用的原则,不要让仿真器去"猜测"语句的执行顺序.

【示例】

`timescale 1 ns / 1 ps
class cobj;
int data;
function new(int data);
    this.data = data;
endfunction
task void disp();
    $display(“The cobj data is %h”,data);
endtask
endclass    // cobj

class cobj1;
int data;
cobj pt;
function new();
    data = 3;
    pt     = new(data);
endfunction
task void disp();
    pt.disp;
endtask
endclass    // cobj1

module top_tb;
cobj1 ptr;
initial begin
    ptr = new;
    ptr.disp;
end
endmodule    // top_tb

【仿真结果】

The cobj data is 00000003!

此例中将所有成员的初始化都在构造函数中进行,并且确保各种变量的使用秉持"先定义后使用"的原则,这样可以确保程序执行的结果时期望的,并且可以确保任何成员在使用时具有确定的属性。





全部评论

相关推荐

11-01 08:48
门头沟学院 C++
伤心的候选人在吵架:佬你不要的,能不能拿户口本证明过户给我。。球球了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务