03. Método de cobertura UVM

1. Mecanismo de fábrica: anulación

  • El mecanismo de anulación puede reemplazar el tipo original por otro tipo nuevo.
  • Después de sobrescribir, la fábrica creará la solicitud original para crear el tipo original para crear un nuevo tipo de reemplazo.
    1. No es necesario modificar el código original, asegurando así la encapsulación del código original.
    2. El nuevo tipo de reemplazo debe ser compatible con el tipo reemplazado; de lo contrario, las asignaciones de identificadores posteriores fallarán, por lo que se utiliza la herencia.

             Como se muestra en la figura anterior, si solo modifica el drv usted mismo, el drv en los proyectos de otras personas seguirá siendo el original. Entonces sobrescriba drv con drv2.

  • Es muy conveniente realizar modificaciones de nivel superior, lo que permite una configuración flexible; por ejemplo, se pueden usar subclases para anular la clase principal original y se pueden usar diferentes objetos para modificar el comportamiento de su código.
  • Para implementar funciones anuladas, es necesario registrar tanto el tipo original como el nuevo .
  • Cuando se usa create() para crear un objeto , la fábrica verifica si el tipo original se sobrescribe y, de ser así, crea un objeto del nuevo tipo y, si no, crea un objeto del tipo original.
  • Cuando se produce una anulación, se puede utilizar "anulación de tipo" o "anulación de instancia" . "Cobertura de tipos" significa que todos los tipos originales bajo la jerarquía UVM se reemplazan por tipos cubiertos. "Anulación de instancia" significa que en algunos lugares el tipo original será reemplazado por el tipo de anulación.
     

2. Método de cobertura

set_type_override()

static function void set_type_override(uvm_object_wrapper override_type, bit replace=1);

uvm_object_wrapper override_type
Este no es el identificador de una instancia específica, sino en realidad el identificador de una clase registrada cuando está registrada en la fábrica. Utilice new_type::get_type() para encontrarlo.

bit replace=1
1: Si ya existe una superposición, la nueva superposición reemplazará a la anterior.
0: Si ya existe una anulación, la anulación no tendrá efecto.

set_type_override()
Esta es una función estática que se utiliza para reemplazar el tipo antiguo con un tipo nuevo.

Uso orig_type::type_id :: set_type_override (new_type::get_type())

set_inst_override() anula la instancia concreta

static function void set_inst_override(uvm_object_wrapper override_type, string inst_path, uvm_component parent=null);

cadena inst_path
apunta a la cadena de ruta de la estructura del componente

Si uvm_component parent=null
es el valor predeterminado, significa que el contenido de inst_path se usa como una ruta absoluta. Si se pasa un valor, {parent.get_full_name(), '.', inst_path} se usa como la ruta de destino.

set_inst_override()
Esta es una función estática, utilizada orig_type::type_id::set_inst_override(new_type::get_type(),"orig_inst_path")

Cabe señalar que existe más de una clase que proporciona funciones relacionadas con la anulación; sin embargo, los nombres y las listas de parámetros pueden variar. Por lo tanto, es necesario implementar el reemplazo de tipos, y hay más de una forma: puede llamar a la función de anulación a través de orig_type :: type_id, también puede llamarla directamente en el dominio de uvm_component o usar uvm_factory para realizar la anulación.
 

3. Ejemplo de cobertura

module factory_override;
	import uvm_pkg::*;
	`include "uvm_macros.svh"

	class comp1 extends uvm_component;
		`uvm_component_utils(comp1)
		
		function new(string name="comp1", uvm_component parent=null);
			super.new(name, parent);
			$display($sformatf("comp1::%s is created", name));
		endfunction

		virtual function void hello(string name);
			$display($sformatf("comp1::%s said hello!", name));
		endfunction
	endclass

	class comp2 extends comp1;
		`uvm_component_utils(comp2)
	
		function new(string name="comp2", uvm_component parent=null);
			super.new(name, parent);
			$display($sformatf("comp2::%s is created", name));
		endfunction

		function void hello(string name);
			$display($sformatf("comp2::%s said hello!", name));
		endfunction
	endclass

	comp1 c1, c2;
	initial begin
		comp1::type_id::set_type_override(comp2::get_type());
		c1 = new("c1");
		c2 = comp1::type_id::create("c2", null);
		c1.hello("c1");
		c2.hello("c2");
	end
endmodule

Enfoque: métodos virtuales y herencia.

Resultados de la simulación:

Tanto c1 como c2 son tipos comp1, pero c1 es creado por la función new(), así que llame a c1.hello() para imprimir comp1::c1 dijo ¡hola!, y c2 es creado por la fábrica, llame a c2.hello() para imprimir comp2::c2 ¡saluda!. Esto muestra que set_type_override() afecta los objetos creados por la fábrica, y la fábrica realizará el reemplazo de tipos.

solo ejecutamos

initial begin
		comp1::type_id::set_type_override(comp2::get_type());
		c2 = comp1::type_id::create("c2", null);
end

Ejecute la simulación y observe el registro impreso.

Se puede ver que cuando el objeto c2 se crea a través de fábrica, el tipo comp1 será sobrescrito por el tipo comp2, pero aún se llamará al nuevo() de comp1 para imprimir comp1::c2 dijo ¡hola!, y luego el Se llamará a la función new() de comp2 para imprimir comp2 ::c2 dijo ¡hola!. Entonces, después de tener la información del diccionario de tipos de registro y la cola de tipos de superposición, cuando se crea c2 a través de la fábrica, verificará si el tipo creado ha sido anulado y, si se anula, obtendrá la información del tipo de superposición de uvm_default_factory::m_type_overrides.

comp1::type_id::set_type_override(comp2::get_type()) hace que comp2 cubra el tipo comp1 y luego crea los objetos c1 y c2. Puede ver en el resultado que el tipo de c1 sigue siendo comp1 y c2 El tipo se convierte comp2, lo que significa que el mecanismo de anulación de la fábrica solo afectará a los objetos registrados y creados por la fábrica. Por lo tanto, la cobertura de tipos de type_id::create() y factory puede realizar el reemplazo flexible del tipo de objeto durante la creación de instancias. Antes de crear una instancia de c2, el tipo de comp1 debe reemplazarse primero por comp2. Solo después de que se complete el reemplazo del tipo, la fábrica puede seleccionar el tipo correcto en la instanciación posterior. Después de que se produzca el reemplazo de tipo, si el código original no se actualiza, el tipo del identificador c2 sigue siendo comp1, pero apunta a un objeto de tipo comp2, lo que requiere que comp2 sea una subclase de comp1. Solo de esta manera , el mango El apuntamiento es seguro y legal. Cuando c2 llama al método hello(), dado que primero es de tipo comp1, verificará comp1::hello(), y debido a que el método se especifica como una función virtual en el momento de la definición, esto pasa la llamada al método de polimorfismo. , y gira Se llama a la función comp2::hello(), por lo que el resultado impreso es comp2::c2 ¡dijo hola!
 

Suplemento: A través de este sitio web, hay más de 300 clases de UVM, ¡y cualquier clase puede descubrir qué métodos tiene! 

 

Supongo que te gusta

Origin blog.csdn.net/Arvin_ing/article/details/127564145
Recomendado
Clasificación