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).