Systemverilog (Libro Verde) Capítulo 5-Clases y objetos (3) Herencia de clase

En OOP, asignamos valores a subclases o agregamos nuevas funciones a través de la herencia:

class cat;
    protected color_t color;
    local bit is_good;
    function set_good(bit s);
        this.is_good = s;
    endfunction
endclass

/声明黑猫类/
class black_cat extends cat;
    function new();
        this.color = BLACK;
    endfunction
endclass

/声明白猫类/
class while_cat extends cat;
    function new();
        this.color = WHITE;
    endfunction
endclass

black_cat bk;    
white_cat wt;    

initial begin
    bk = new();    //初始化黑猫对象
    wt = new();    //初始化白猫对象
    bk.set_good(1);
    wt.set_good(1);
end

En el proceso de verificación, dividimos la responsabilidad de cada componente para aclarar las tareas de cada componente, por lo que se crea un entorno simple.

Caso 1: para la transmisión de datos, esperamos encapsular los datos en la clase, porque la clase puede encapsular muchos datos y métodos.

class Transaction;
    rand bit [31:0] src, dst, data[8];    //随机变量
    bit [31:0]    crc                     //二次处理后的成员变量
    virtual function void calc_crc();
        crc = src^dst^data.xor;
    endfunction
    
    virtual function void display(input string prefix="");
        $display("%sTr: src=%h, dst=%h, crc=%h",prefix,src, dst, crc);
    endfunction
endclass

Sin embargo, en este momento necesitamos agregar nuevas funciones basadas en esta clase base para generar un nuevo tipo. En este momento, puede considerar implementar esta función a través de la herencia.

class BadTr extends Transaction;
    rand bit bad_crc;
    virtual function void calc_crc;
        super.calc_crc();            //计算好的CRC值
        if (bad_crc) crc = ~crc;     //CRC值取反
    endfunction

    virtual function void display(input string prefix="");
        $write("%sBadTr: bad_crc = %b, ", prefix, bad_crc);
        super.display();
    endfunction
endclass : BadTr

Se han redefinido nuevas variables miembro y métodos miembro en la subclase, y no hay relación entre los métodos miembros recién definidos y el método original.

Super implementa métodos de subclase para heredar de métodos de superclase. La función super.calc_crc () puede implementar la llamada a la función en la clase principal y luego agregar el método de subclase. En su interior están indexados por el mismo nombre que la clase padre de Super .

Sin embargo, si desea indexar variables en la clase primaria

Caso 2: en el entorno de verificación, hay clases similares trans y una clase de iniciador stm_ini. En la prueba, se usan dos subclases test_wr y test_rd heredadas de basic_test para iniciar pruebas de escritura y lectura en el DUT, respectivamente.

class basic_test;
    int def = 100;    //成员变量赋予默认值
    int fin;
    task test(stm_ini ini);
        $display("basic_test::tset");
    endtask
    function new(int val);
    endfunction
endclass


class test_wr extends basic_test;
    function new();
        super.new(def);
        $display("test_wr::new");
    endfunction

task test(stm_ini ini);
    super.test(ini);
    $display("tast_wr::test");
endtask
endclass

 

class basic_test;
    int def = 100;    //成员变量赋予默认值
    int fin;
    task test(stm_ini ini);
        $display("basic_test::tset");
    endtask
    function new(int val);
    endfunction
endclass


class test_rd extends basic_test;
    function new();
        super.new(def);
        $display("test_rd::new");
    endfunction
task test(stm_ini ini);
    super.test(ini);
    $display("tast_rd::test");
endtask
endclass

 Cuando la subclase define la nueva función, primero debe llamar a la nueva función de la clase padre --- super.new (). Si la nueva función principal no tiene parámetros, se omite la llamada y se puede agregar super.new automáticamente cuando se compila el sistema. 

Al observar el orden de creación e inicialización de objetos, los usuarios deben prestar atención a las reglas:

 

Para problemas de cobertura de miembros:

class basic_test;
    int def = 100;    //成员变量赋予默认值
    int fin;
    task test(stm_ini ini);
        $display("basic_test::tset");
    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

Se crea un objeto de subclase, ¿cuál es el valor def de la llamada al objeto de subclase? 200

El valor asignado a la manija subclase de la clase padre , a través de la clase padre para def índice ¿Cuánto? 100

Tanto los manejadores de clase primaria como secundaria apuntan a objetos, pero el manejador de clase secundaria apunta a un rango más amplio, y la clase primaria solo puede acceder a parte de las variables y métodos miembros de la clase primaria. 

Acceso a subclase:

wr.def: acceder a las variables de la subclase

wr.super.def: accede a las variables de la clase padre a través de la subclase

Obtenga un identificador de clase principal, el identificador puede apuntar a un objeto de subclase (después de haber sido asignado por un objeto de subclase) también puede apuntar al objeto de clase principal. Sin embargo, solo se puede acceder a los miembros de la clase padre en el objeto de subclase.

 

Sin embargo, no puede asignar la clase principal al objeto de clase secundaria y se informará un error en el momento de la compilación . El valor predeterminado es ejecutar según el peor de los casos durante la compilación. El identificador de la clase principal solo se puede convertir en un identificador de subclase

$ cast (T, S) corre.

Si no hay def en la subclase, a través del índice de objeto de subclase: wr.def, encontrará que no hay un valor de variable de miembro def en la subclase, y luego volverá a acceder al mismo nombre def = 100 en la clase padre.

En este momento, el acceso a t.def en la clase padre solo puede acceder a 100.

El def en super.new (def) en la subclase llama al def en la subclase, y el orden de búsqueda prioritario es de cerca a lejos .

Si define wr = new (); t = new (); en el programa, se definen dos objetos, luego wr apunta al objeto de la subclase y t apunta al objeto de la clase padre. Cuando llame a variables y funciones miembro, solo llame desde su propia clase. En este momento, usar $ cast (T, S) para asignar la clase principal a la clase secundaria también está mal . Las clases grandes pueden restringir el acceso (las subclases pueden acceder a la clase principal), pero las clases pequeñas no pueden acceder a la clase grande (la clase principal no se puede asignar a la subclase).

 

Publicado 14 artículos originales · ganó 10 · vistas 20,000 +

Supongo que te gusta

Origin blog.csdn.net/Jay_who/article/details/105597794
Recomendado
Clasificación