Métodos de acceso de registro uvm (16)

Reimpreso:

Traducción: https://blog.csdn.net/zhajio/article/details/80731435

Original: http://cluelogic.com/2013/02/uvm-tutorial-for-candy-lovers-register-access-methods/

 

La capa de abstracción de registro (RAL) de UVM proporciona varios métodos para acceder a los registros. Este artículo explicará cómo funciona el método de acceso de registro. En Register Abstraction, presentamos una descripción general de RAL y explicamos cómo definir registros. En este artículo, presentaremos cómo acceder a los registros.

Propiedades de uvm_reg_field

Antes de sumergirse en los métodos de acceso de registro, veamos cómo almacenar valores de registro. Como se muestra en la abstracción de registro, uvm_reg_field es la capa de abstracción de registro más baja que representa los bits del registro. uvm_reg_field usa múltiples atributos para almacenar varios valores de campo de registro:

  • m_reset ["HARD"] almacena el valor de restablecimiento completo (restablecimiento completo). Tenga en cuenta que m_reset es una matriz asociativa con una tecla de reinicio.
  • m_mirrored almacena lo que creemos que debería almacenarse en el diseño bajo prueba (DUT).
  • m_desired almacena el valor que queremos establecer en el DUT.
  • value almacena el valor a muestrear en la cobertura funcional, o restringe el valor cuando el campo es aleatorio.

Tenga en cuenta que entre estos atributos, solo el atributo de valor es público. Los otros atributos son locales, por lo que no podemos acceder a ellos directamente desde fuera de la clase. Más adelante le mostraremos cómo acceder a estas propiedades locales utilizando métodos de acceso de registro.

  

 

                                               Propiedades de uvm_reg_field

configurar ()

Lo primero que hacemos después de crear uvm_reg_field es configurarlo. En la abstracción del registro, configuramos el campo de sabor de la siguiente manera. Tenga en cuenta que en Registro de abstracción, definimos el campo de sabor como "WO" (solo escritura), pero aquí lo definimos como "RW" (lectura / escritura) para hacer este campo más general.

flavour = uvm_reg_field :: type_id :: create ( " flavour " ); 
taste.configure (.parent (this), 
                  .size ( 3     ), 
                  .lsb_pos ( 0     ), 
                  .access ( " RW " ), 
                  .volatile ( 0     ), 
                  .reset ( 0     ), 
                  .has_reset ( 1     ), 
                  .is_rand) ( 1     )
                  .individually_accessible ( 0     ));

Si el parámetro has_reset es 1, el valor del parámetro de reinicio se considerará como el valor de reinicio "HARD". Si el valor has_reset es 0, se ignorará el valor de restablecimiento. El valor de reinicio debe coincidir con el estado de reinicio del DUT. Si desea modificar el valor de reinicio después de la configuración, puede usar el método set_reset ().

flavour.set_reset (.value ( 0 ), .kind ( " HARD " )); // kind == "HARD" por defecto

 

                                               Cómo funcionan los métodos configure () y set_reset ()

Reiniciar()

Si existe m_reset [kind], el método reset () restablecerá los atributos del campo de registro. El tipo predeterminado es "DURO". Si m_reset [kind] no existe, el método reset () no hace nada. Tenga en cuenta que el método reset () no restablece los registros en el DUT. Solo restablece los atributos del objeto de campo de registro.

sabor.reset (.kind ( " DURO " )); // kind == "HARD" por defecto

 

                                 Cómo funciona el método reset ()

conjunto()

El método set () establece el valor esperado del campo de registro. El método set () no establece el valor en el valor del registro en el DUT. Solo establece el valor en el atributo de valor de los objetos m_desired y de campo de registro. Para establecer realmente el valor en un registro en el DUT, use el método write () o update (). Estos métodos se explicarán más adelante.

sabor.set (.value ( 1 ));

 

 

obtener()

El método get () obtiene el valor esperado del campo de registro. El método get () no obtiene el valor del registro en el DUT. Solo obtiene el valor del atributo m_desired. Para obtener realmente el valor del DUT, use el método read () o mirror (). Estos métodos se explicarán más adelante. Similar al método get (), hay dos captadores para acceder a las propiedades locales. get_reset () recupera el valor del atributo m_reset [kind], y el método get_mirrored_value () recupera el valor del atributo m_mirrored.

uvm_reg_data_t desired_value = flavour.get (); 
uvm_reg_data_t reset_value     = flavour.get_reset (.kind ( " HARD " )); // kind == "HARD" por defecto 
uvm_reg_data_t mirrored_value = flavour.get_mirrored_value ();

 

 

aleatorizar ()

El método randomize () es un método SystemVerilog. Aleatoriza el atributo de valor de un objeto de campo de registro. Después de la aleatorización, el método post_randomize () copia el valor del atributo de valor en el atributo m_desired. Tenga en cuenta que si el modo rand_mode del atributo value está desactivado, el método pre_randomize () copiará el valor de m_desired en el atributo value.

afirmar (flavour.randomize ());

 

 

escribir()

El método write () en realidad escribe un valor en el DUT.

estado de uvm_status_e; 
flavour.write (.status (estado), .value ( 1 ));

El método write () implica múltiples pasos.

  1. Cree un objeto uvm_reg_item correspondiente a la operación de escritura.
  2. uvm_reg_adapter convierte operaciones de escritura en transacciones de bus correspondientes.
  3. uvm_driver realiza transacciones de bus al DUT.
  4. uvm_monitor captura las transacciones del bus.
  5. uvm_reg_predictor requiere uvm_reg_adapter para convertir las transacciones de bus en las operaciones de registro correspondientes.
  6. La operación de registro se convierte a uvm_reg_item.
  7. uvm_reg_item se utiliza para actualizar el valor, los atributos m_mirrored y m_desired.

Tenga en cuenta que si el parámetro accesible individualmente es 0 al configurar el campo de registro, se escribirá todo el registro que contiene el campo, porque no se puede acceder al campo individualmente. En este caso, el valor m_mirrored se usará como valor de escritura para otros campos.

 

 

leer()

El método read () en realidad lee un valor de registro del DUT.

estado de uvm_status_e; 
valor de uvm_reg_data_t; 
 
flavour.read (.status (estado), .value (valor));

Similar al método write (), el método read () involucra múltiples pasos.

  1. Cree un objeto uvm_reg_item correspondiente a la operación de lectura.
  2. uvm_reg_adapter convierte las operaciones de lectura en las transacciones de bus correspondientes.
  3. uvm_driver realiza transacciones de bus al DUT.
  4. uvm_reg_apapter convierte transacciones de bus que leen datos en operaciones de registro.
  5. El método read () devuelve el valor de lectura a la persona que llama.
  6. Al mismo tiempo, uvm_monitor captura las transacciones del bus.
  7. uvm_reg_predictor requiere uvm_reg_adapter para convertir las transacciones de bus en las operaciones de registro correspondientes.
  8. La operación de registro se convierte a uvm_reg_item.
  9. uvm_reg_item se utiliza para actualizar el valor, los atributos m_mirrored y m_desired.

Tenga en cuenta que si el individually_accessible parámetro es 0 al configurar el campo de registro, se leerá todo el registro que contiene el campo. En este caso, el valor m_mirrored también se actualiza para otros campos.

 

 

actualizar()

El método update () en realidad escribe un valor de registro en el DUT. El método update () pertenece a la clase uvm_reg. La clase uvm_reg_field no tiene método update ().

estado de uvm_status_e; 
 
jb_recipe_reg.update (.status (estado));

La diferencia entre el método write () y el método update () es:

  • El método write () toma un valor como su parámetro, y el método update () usa el valor del atributo m_desired como el valor a escribir.
  • El método update () escribe este valor solo cuando m_mirrored y m_desired no son iguales.

 

 

El método update () llama internamente a write (.value (m_desired)). Por lo tanto, después de la actualización, el valor de m_mirrored también se actualiza.

 

 

espejo()

El método mirror () en realidad lee un registro del DUT.

estado de uvm_status_e; 
 
flavour.mirror (.status (estado), .check (UVM_CHECK));

La diferencia entre el método read () y el método mirror () es:

  • El método read () devuelve el valor de registro a la persona que llama, mientras que el método mirror () no devuelve el valor de registro. El método mirror () solo actualiza el valor del atributo m_mirrored.
  • Si el valor del parámetro de verificación es UVM_CHECK, el método mirror () compara el valor de lectura con m_desired.Tenga en cuenta que la documentación de la biblioteca de clases UVM establece que compara el valor de lectura con el valor reflejado, pero si mira la línea 2.944 de uvm_reg.svh de la base de código uvm-1.1c, en realidad se comparará con el valor deseado , No para valores reflejados.

11 de abril de 2014: la base de código uvm-1.1d ha corregido este problema. mirror () compara el valor de lectura con el valor de espejo. Si está interesado en esta solución, consulte la línea 2,951 de uvm_reg.svh. )

Otra advertencia sobre la verificación es que si el parámetro volátil se establece en 1 al configurar el campo de registro, el campo de registro no se verificará incluso si el parámetro de verificación se establece en UVM_CHECK. Esto se debe a que no podemos predecir el valor del campo de registro de manera determinista porque puede modificarse (volátil) en el DUT.

El método mirror () llama internamente al método do_read (). Este es el mismo método que se llama internamente desde el método read (). Por lo tanto, además del atributo m_mirrored, el método mirror () también actualiza el valor y el atributo m_desired.

 

 

predecir()

El método predict () actualiza el valor espejo.

sabor.predict (.value ( 1 ));

El método predict () también actualiza el valor y el atributo m_desired.

 

 

Resumen

La siguiente tabla resume cómo cada método actualiza las propiedades del objeto de campo de registro.

Método m_reset
["HARD"]
value m_desired m_mirrored Yo tengo
configure
(.reset(val),
.has_reset(1))
establecer el valor de val        
set_reset(val) establecer el valor de val        
reset()   copiar el valor de m_reset
["HARD"]
copiar el valor de m_reset
["HARD"]
copiar el valor de m_reset
["HARD"]
 
set(val)   establecer el valor de val establecer el valor de val    
get_reset() devolver el valor de m_reset
["HARD"]
       
get()     devolver el valor de m_desired    
get_mirrored_value()       devolver el valor de m_mirrored  
randomize()   aleatorizar copiar el valor de value    
write(.value(val))   establecer el valor de val establecer el valor de val establecer el valor de val escribe el valor de val
read(.value(val))   establecer el valor de lectura establecer el valor de lectura establecer el valor de lectura lee el registro
update()   establecer el valor de m_desired establecer el valor de m_desired establecer el valor de m_desired escribe el valor de m_desired
mirror()   establecer el valor de lectura establecer el valor de lectura establecer el valor de lectura lee el registro
predict
(.value(val))
  establecer el valor de val establecer el valor de val establecer el valor de val

 

En este artículo, solo presentamos la llamada entrevista de puerta de entrada. Introduciremos el acceso de puerta trasera en una publicación separada. Espero que este tutorial lo ayude a comprender cómo acceder a los registros.

 原文中有一些QA可以加深理解。

 

Supongo que te gusta

Origin www.cnblogs.com/zhiminyu/p/12706990.html
Recomendado
Clasificación