Question

I am developing a SystemVerilog monitor that extends ovm_monitor and I'd like to know how to import the ovm macros that I am using. I am using:

`ovm_component_utils_begin
`ovm_field_string
`ovm_component_utils_end

I tried the following at the top of my file, both of which do not compile:

import ovm_pkg::ovm_monitor;
import ovm_pkg::ovm_macros;

and

import ovm_pkg::ovm_monitor;
`include "ovm_macros.svh"

VCS compile error:

Error-[SE] Syntax error
  Following verilog source has syntax error :
  "my_monitor.svh", 58 (expanding macro): token is '#'
  `ovm_component_utils_begin(my_monitor)
                                        ^

The following works, but I consider it bad practice to use * in the import statement:

import ovm_pkg::*
Was it helpful?

Solution

Importing with * is actually the best practice.

Importing with * makes all package contents visible but does not do the actual import until used. Importing a function by name immediately imports the function whether used or not (that is the inferior practice).

Users of OVM or UVM are instructed to never define any user-defined classes or macros using the "ovm_" prefix since future versions of OVM may add more ovm_classes or `ovm_macros, so importing OVM packages with * is safe.

If you were to import two packages with * and if both packages had the same function name defined, if your code does not use the function, there is no problem. If your code does require the function, prefix the function with pkg2::function_name, which again is the best practice.

Regards - Cliff Cummings - Verilog & SystemVerilog Guru

OTHER TIPS

It looks like there's a missing class definition for ovm_component_registry, among other things. I'm not a real user of OVM but it's extensive use of nested includes and macros means you'll likely need to look at the preprocessed output.

class top extends blah;



   typedef ovm_component_registry #(top,"top") type_id; 
           ^
   static function type_id get_type(); 
     return type_id::get(); 
   endfunction  

   const static string type_name = "top"; 
   virtual function string get_type_name (); 
     return type_name; 
   endfunction  

   static bit m_fields_checked = 0; 
   function void m_field_automation (ovm_object tmp_data__=null, 
                                     int what__=0, 
                                     string str__=""); 
   begin 
     top local_data__; /* Used for copy and compare */ 
     string string_aa_key; /* Used for associative array lookups */ 
     /* Check the fields if not already checked */ 
     if(what__ == OVM_CHECK_FIELDS) begin 
       if(! top::m_fields_checked) 
         top::m_fields_checked=1; 
       else 
         return; 
     end 
     /* Type is verified by ovm_object::compare() */ 
     super.m_field_automation(tmp_data__, what__, str__); 
     if(tmp_data__ != null) 
       /* Allow objects in same hierarchy to be copied/compared */ 
       if(!$cast(local_data__, tmp_data__)) return; 
     if(what__ == OVM_CHECK_FIELDS) begin 
       m_field_array.delete(); 
     end 

     end 
   endfunction(top)


endclass

This should be a comment on Adam12's response but I can't add comments.

@Victor Lyuboslavsky, If you don't want to use import ovm_pkg::*, you will have to look at the macro expansion, or the expanded code produced by the macro, and import the necessary identifiers, e.g. ovm_component_registry, ovm_object, OVM_CHECK_FIELDS (based on Adam12's answer).

However in future the ovm_component_utils_* or ovm_field_* macros could change to include more OVM identifiers and you would have to modify the code then to import these additional identifiers.

Unfortunately, there isn't a lot of choice about doing import ovm_pkg::*. The OVM doesn't fully qualify all of its names with the package name internally so it is almost impossible to get code to compile without it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top