我在 SV 中调用 super.func() 时遇到问题。
我有三个主要课程:
class_C 扩展 class_B;
class_B 扩展 class_A;
类_A;
我有三个配置(聚合)类:
内部_C 扩展内部_B;
内部_B 扩展内部_A;
内部_A;
当我从 clacc_C 调用打印 self 指针和指向相应内部类的指针的函数链时,我收到正常的 self 指针,而 inner_B 和 inner_A 则为 null。
为什么我会从 SV 那里得到这样的行为?如何解决这个问题?
模拟器 - Questa 2021.1 这是用于说明问题的代码示例:
package test_pkg;
// base config
class inner_A;
int val_0_min;
int val_0_max;
function new();
endfunction : new
endclass : inner_A
// base class
class class_A;
inner_A in_A_h;
rand int val_0;
constraint constr_0 {
val_0 inside {[in_A_h.val_0_min : in_A_h.val_0_max]};
}
function void print();
$display("val_0 = %0d", val_0);
// next string give an error: Fatal: (SIGSEGV) Bad handle or reference.
//$display("val_0_min = %0d, val_0_max = %0d",
// in_A_h.val_0_min, in_A_h.val_0_max);
$display("pointer_0 this %m = ", this);
$display("pointer_0 in_A_h %m = ", in_A_h);
endfunction : print
function new();
endfunction : new
endclass : class_A
// first inheritance
class inner_B extends inner_A;
int val_1_min;
int val_1_max;
function new();
super.new();
endfunction : new
endclass : inner_B
class class_B extends class_A;
inner_B in_B_h;
rand int val_1;
constraint constr_1 {
val_1 inside {[in_B_h.val_1_min : in_B_h.val_1_max]};
}
function void print();
super.print();
$display("val_1 = %0d", val_1);
// next string give an error: Fatal: (SIGSEGV) Bad handle or reference.
//$display("val_1_min = %0d, val_1_max = %0d, val_0_min = %0d, val_0_max = %0d",
// in_B_h.val_1_min, in_B_h.val_1_max, in_B_h.val_0_min, in_B_h.val_0_max);
$display("pointer_1 this %m = ", this);
$display("pointer_1 in_B_h %m = ", in_B_h);
endfunction : print
function new();
super.new();
endfunction : new
endclass : class_B
// second inheritance
class inner_C extends inner_B;
int val_2_min;
int val_2_max;
function new();
super.new();
endfunction : new
endclass : inner_C
class class_C extends class_B;
inner_C in_C_h;
rand int val_2;
constraint constr_2 {
val_2 inside {[in_C_h.val_2_min : in_C_h.val_2_max]};
}
function void print();
super.print();
$display("val_2 = %0d", val_2);
$display("val_2_min = %0d, val_2_max = %0d, val_1_min = %0d, val_1_max = %0d, val_0_min = %0d, val_0_max = %0d",
in_C_h.val_2_min, in_C_h.val_2_max, in_C_h.val_1_min, in_C_h.val_1_max, in_C_h.val_0_min, in_C_h.val_0_max);
$display("pointer_2 this %m = ", this);
$display("pointer_2 in_C_h %m = ", in_C_h);
endfunction : print
function new();
super.new();
endfunction : new
endclass : class_C
endpackage : test_pkg
module DUT
import test_pkg::*;
();
inner_C in_C_h;
class_C C_h;
class_B B_h;
class_A A_h;
initial begin
in_C_h = new();
in_C_h.val_2_min = 20;
in_C_h.val_2_max = 30;
in_C_h.val_1_min = 10;
in_C_h.val_1_max = 20;
in_C_h.val_0_min = 1;
in_C_h.val_0_max = 10;
B_h = new();
A_h = new();
C_h = new();
C_h.in_C_h = in_C_h;
if (!C_h.randomize()) begin
$error("randomization failed"); // $fatal();
end
// print all data by the print() chain
$display("\n\tprint from C");
C_h.print();
// cast to parent and print only parent content
$display("\n\tprint from B");
if (!$cast(B_h, C_h)) begin
$fatal();
end
B_h.print();
$display("\n\tprint from A");
if (!$cast(A_h, B_h)) begin
$fatal();
end
A_h.print();
end
endmodule : DUT
需要在Class_A和Class_B中分别构造in_A_h和in_B_h。
以下修改解决了问题。
package test_pkg;
// base config
class inner_A;
int val_0_min;
int val_0_max;
function new();
endfunction : new
endclass : inner_A
// base class
class class_A;
inner_A in_A_h;
rand int val_0;
constraint constr_0 {
val_0 inside {[in_A_h.val_0_min : in_A_h.val_0_max]};
}
function void print();
$display("val_0 = %0d", val_0);
// next string give an error: Fatal: (SIGSEGV) Bad handle or reference.
//$display("val_0_min = %0d, val_0_max = %0d",
// in_A_h.val_0_min, in_A_h.val_0_max);
$display("pointer_0 this %m = ", this);
$display("pointer_0 in_A_h %m = ", in_A_h);
endfunction : print
function new();
//construct in_A_h
in_A_h = new();
endfunction : new
endclass : class_A
// first inheritance
class inner_B extends inner_A;
int val_1_min;
int val_1_max;
function new();
super.new();
endfunction : new
endclass : inner_B
class class_B extends class_A;
inner_B in_B_h;
rand int val_1;
constraint constr_1 {
val_1 inside {[in_B_h.val_1_min : in_B_h.val_1_max]};
}
function void print();
super.print();
$display("val_1 = %0d", val_1);
// next string give an error: Fatal: (SIGSEGV) Bad handle or reference.
//$display("val_1_min = %0d, val_1_max = %0d, val_0_min = %0d, val_0_max = %0d",
// in_B_h.val_1_min, in_B_h.val_1_max, in_B_h.val_0_min, in_B_h.val_0_max);
$display("pointer_1 this %m = ", this);
$display("pointer_1 in_B_h %m = ", in_B_h);
endfunction : print
function new();
super.new();
//construct in_B_h
in_B_h = new();
endfunction : new
endclass : class_B
// second inheritance
class inner_C extends inner_B;
int val_2_min;
int val_2_max;
function new();
super.new();
endfunction : new
endclass : inner_C
class class_C extends class_B;
inner_C in_C_h;
rand int val_2;
constraint constr_2 {
val_2 inside {[in_C_h.val_2_min : in_C_h.val_2_max]};
}
function void print();
super.print();
$display("val_2 = %0d", val_2);
$display("val_2_min = %0d, val_2_max = %0d, val_1_min = %0d, val_1_max = %0d, val_0_min = %0d, val_0_max = %0d",
in_C_h.val_2_min, in_C_h.val_2_max, in_C_h.val_1_min, in_C_h.val_1_max, in_C_h.val_0_min, in_C_h.val_0_max);
$display("pointer_2 this %m = ", this);
$display("pointer_2 in_C_h %m = ", in_C_h);
endfunction : print
function new();
super.new();
endfunction : new
endclass : class_C
endpackage : test_pkg
module DUT
import test_pkg::*;
();
inner_C in_C_h;
class_C C_h;
class_B B_h;
class_A A_h;
initial begin
in_C_h = new();
in_C_h.val_2_min = 20;
in_C_h.val_2_max = 30;
in_C_h.val_1_min = 10;
in_C_h.val_1_max = 20;
in_C_h.val_0_min = 1;
in_C_h.val_0_max = 10;
B_h = new();
A_h = new();
C_h = new();
C_h.in_C_h = in_C_h;
if (!C_h.randomize()) begin
$error("randomization failed"); // $fatal();
end
// print all data by the print() chain
$display("\n\tprint from C");
C_h.print();
// cast to parent and print only parent content
$display("\n\tprint from B");
if (!$cast(B_h, C_h)) begin
$fatal();
end
B_h.print();
$display("\n\tprint from A");
if (!$cast(A_h, B_h)) begin
$fatal();
end
A_h.print();
end
endmodule : DUT