SystemVerilog继承、聚合类和父函数调用

问题描述 投票:0回答:1

我在 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
oop verilog system-verilog fpga modelsim
1个回答
0
投票

需要在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
© www.soinside.com 2019 - 2024. All rights reserved.