Hierarchical reference not allowed from within a package

Hi,

In a package i declared two classes, secong class is the extension of the first. i declared an empty task call sample_coverage() in the first class and overriding that sample_coverage() in the extended class.

Then i am getting an error as…

Error: /users/ramachar/jtag_proj/jtag_svtb/source/jtag_svtb_top/jtag_tb.sv(319): (vlog-7027) Hierarchical reference (‘sample_coverage’) not allowed from within a package.

You said you declared a virtual task in the first class, but I don’t see any declaration of sample_coverage in your my_driver class. You need to have a virtual task like this in you my_driver class:

virtual task sample_coverage();
endtask

-Kurt

Thanks Kurt…

i have updated the task in my_driver and i called that task too, now working…

but i am not able to get shift_dr value in my_scoreboard from my_driver.

Can you pls suggest me…

You should be able to just use shift_dr from within your scoreboard class, because it is inherited from my_driver, and it is not declared as local.

You do not need to put “super.shift_dr”, just shift_dr. When you extend a class, you get access to all of its non-local data members as if you declared them in the derived class.

-Kurt

No Kurt… i tried just shift_dr its not working so i tried super.shift_dr still not :(
I drive 1 to shift_dr from my_class, but i am not able to access that in its derived class my_scorebaord.

Kurt,
please find my code here…

class my_driver extends ovm_driver;

ovm_get_port #(my_transaction) get_port;  // For communication with stimulus generator

virtual jtag_if m_dut_if;                  // For access to the DUT interface
`ovm_component_utils(my_driver)
bit shift_dr;
function new(string name, ovm_component parent);
  super.new(name, parent);
  ovm_report_message("", "Called my_driver::new");
endfunction: new

function void build;
  super.build();
  ovm_report_message("", "Called my_driver::build");
  get_port = new("get_port", this);
endfunction : build

virtual task run;
sample_coverage();

  ovm_report_message("", "Called my_driver::run");
  forever
  begin
    my_transaction tx;
    #10
    get_port.get(tx);
    
    ovm_report_message("",$psprintf("Driving state = %s, serial data = %b",
                                    tx.TapState, tx.d_Tdi_reg));
    // initial value 
    //m_dut_if.Tdi = 0;
    shift_dr = 1; // 0
    if(tx.TapState == 0) // enum equivalent of update_ireg is 0
    begin
      m_dut_if.Tms    = 1;
      m_dut_if.Tdi    = 0;
      // TAP goes to the Reset state, with the following
      m_dut_if.Trst_n    = 0;
      @(posedge m_dut_if.Tclk);
      m_dut_if.Trst_n    = 1;
      // TAP goes to the Idle state, with the following
      m_dut_if.Tms    = 0;
      #300;
      // TAP goes to the DR Scan state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 1;
      // TAP goes to the IR Scan state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 1; // If 0, this goes to Capture DR
      // TAP goes to the Capture IR state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 0; 
      // TAP goes to the Shift IR state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 0; // If 1, this goes to Exit1 IR
      // Send the Serial in Data i.e., Tdi
      for(int i = 0; i <= 10; i++)
      begin
       @(posedge m_dut_if.Tclk) 
        m_dut_if.Tdi = tx.d_Tdi_reg[i];
      end
      // TAP goes to the Exit1 IR state, with the following
      //@(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 1; 
      // TAP goes to the Pause IR state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 0;
      #200;
      // TAP goes to the Exit2 IR state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 1; 
      // TAP goes to the Shift IR state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 0; 
      // Send the Serial in Data i.e., Tdi
      for(int i = 11; i <= 31; i++)
      begin
       @(posedge m_dut_if.Tclk) 
       m_dut_if.Tdi = tx.d_Tdi_reg[i];
      end
      // TAP goes to the Exit1 IR state, with the following
      //@(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 1; 
      // TAP goes to the Update IR state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 1; 
      // TAP goes back to the Idle state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 0; 
    end 
    else if(tx.TapState == 1) // enum equivalent of update_dreg is 1 
    begin
      m_dut_if.Tms    = 1;
      // TAP goes to the Reset state, with the following
      m_dut_if.Trst_n    = 0;
      @(posedge m_dut_if.Tclk);
      m_dut_if.Trst_n    = 1;
      // TAP goes to the Idle state, with the following
      m_dut_if.Tms    = 0;
      #300;
      // TAP goes to the DR Scan state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 1;
      // TAP goes to the Capture DR state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 0; 
      // TAP goes to the Shift DR state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 0; // If 1, this goes to Exit1 DR
      // To trigger the scoreboard checking
      shift_dr = 1;
      // Send the Serial in Data i.e., Tdi
      for(int i = 0; i <= 10; i++)
      begin
       @(posedge m_dut_if.Tclk) 
       m_dut_if.Tdi = tx.d_Tdi_reg[i];
      end
      // To trigger the scoreboard checking
      shift_dr = 1; // 0;
      // TAP goes to the Exit1 DR state, with the following
      //@(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 1; 
      // TAP goes to the Pause DR state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 0;
      #200;
      // TAP goes to the Exit2 DR state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 1; 
      // TAP goes to the Shift DR state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 0; 
      // To trigger the scoreboard checking
      shift_dr = 1;
      // Send the Serial in Data i.e., Tdi
      for(int i = 11; i <= 31; i++)
      begin
       @(posedge m_dut_if.Tclk) 
       m_dut_if.Tdi = tx.d_Tdi_reg[i];
      end
      // To trigger the scoreboard checking
      shift_dr = 1; // 0;
      // TAP goes to the Exit1 DR state, with the following
      //@(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 1; 
      // TAP goes to the Update DR state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 1; 
      // TAP goes back to the Idle state, with the following
      @(posedge m_dut_if.Tclk);
      m_dut_if.Tms    = 0; 
   end
  end
endtask: run
virtual task sample_coverage();
endtask

endclass: my_driver

// Scoreboard/Checker
class my_scoreboard extends my_driver;
`ovm_component_utils(my_scoreboard)
function new(string name = “my_scoreboard”, ovm_component parent = null);
super.new(name, parent);
ovm_report_message(“”, “Called my_scoreboard::new”);
endfunction: new
virtual task sample_coverage(); // run;
ovm_report_message(“”, “Entered scoreboard checking”);
forever
begin
//@(posedge shift_dr);
@(posedge m_dut_if.Tclk);
ovm_report_message(“”,$psprintf(“### shift_dr = %b”, shift_dr, $time));
while(shift_dr == 1)
begin
@(posedge m_dut_if.Tclk);
ovm_report_message(“”,$psprintf(“### shift_dr = %b”, shift_dr));
end
end
endtask: sample_coverage // run
endclass: my_scoreboard

When you say “it’s not working”, what do you mean?

You can surely access shift_dr from within sample_coverage in your scoreboard class. Are you getting an error about accessing it, or is the code just not working as you expect?

Examining your code, you call sample_coverage at the beginning of your run() task. Inside sample_coverage, you have a forever/begin/end loop, which tells me you will never leave the sample_coverage task, and any code inside run() that is after the call to sample_coverage will never be executed.

And, inside the sample_coverage() task, you have a while (shift_dr == 1) loop. When you call sample_coverage, shift_dr has its default value of 0, so this while loop is skipped.

Also, assuming that shift_dr is set to 1 before you call sample_coverage(), I don’t see any code that sets shift_dr to 0, so you will never exit the while() loop.

Unless you are getting an error about accessing shift_dr, I think we might be beyond your initial question about inheritance.

-Kurt

I have debugged and updated according to ur commenst, its working now as i desired. Thanks a lot man…

Hi Kurt,

I am also getting same error message. But it is because of following code written inside “package”

ovm_report_error(get_type_name(),"Invalid Command in get_enum_command");// Error
ovm_report_warning(get_type_name(),"Invalid Command in get_enum_command");// Error
ovm_report_error("PKG","Invalid Command in get_enum_command");// Error
ovm_report_warning("PKG","Invalid Command in get_enum_command");// Works fine

My end-results ovm_report_error can not be declared inside package, get_type_name can not be used within package.

Can you give any reasons for the same?:confused:

Thanks,
SS

get_type_name is not a global function. It is a virtual method that belongs to the ovm_object class, and as such is available to any descendant of ovm_object.

I don’t think the problem is that the function call is inside a package, I can’t tell from the code you specified, but I think it might be because you have the ovm_report_* calls in a function or task that is standalone (i.e. not part of a class derived from ovm_object).

If you do have these calls in some kind of utility function, you could pass the type name string as an argument to the function:

function void function_in_package(string type_name);
  ... 
 ovm_report_warning(type_name,"Message ....");
  ...
endfunction

You would then call the function from a method that is inside a class derived from ovm_object (e.g. the run() method in an ovm_threaded_component)

function_in_package(get_type_name());

If this does not help, please send more code with context to illustrate the error.

-Kurt

get_type_name is not a global function. It is a virtual method that belongs to the ovm_object class, and as such is available to any descendant of ovm_object.
I don’t think the problem is that the function call is inside a package, I can’t tell from the code you specified, but I think it might be because you have the ovm_report_* calls in a function or task that is standalone (i.e. not part of a class derived from ovm_object).

Thanks for your quick reply.

Seems to be appropiate reason for compiler error message. But still could not understand why line 2 cmpiles but line 1 doesn’t.

ovm_report_error("PKG","Invalid Command in get_enum_command");// Line 1 :Error
ovm_report_warning("PKG","Invalid Command in get_enum_command");// Line 2 :Works fine

My code snippet goes here:

package nvs_ex_sv_enum_trans_pkg;
  import ovm_pkg::*;

  //----------------------------------------------------------------------
  // Function    : get_enum_command
  // Description : This function maps the command type to the enumerated 
  //               command type
  //----------------------------------------------------------------------
   function command get_enum_command (bit [6:0] cmd);
     begin
       
       case(cmd)
	 7'h4A : get_enum_command = EX_CPLD         ;
	  default :
	   if(cmd[6:3] == 4'b0110)
	     get_enum_command = EX_MSG;
	   else if(cmd[6:3] == 4'b1110)
	     get_enum_command = EX_MSGD;
	   else
                    begin
// Compilation error here
//s ovm_report_error("ENUM_TRANS","Invalid Command in get_enum_command"); 

// Compiles fine
ovm_report_warning("ENUM_TRANS","Invalid Command in get_enum_command"); 

                     end
	 endcase // case (cmd)
      end
   endfunction // command

endpackage
////************************ END OF FILE *********************************

Thanks,
SS

Hi SS,

I tried compiling your package in Questa 6.3d and it compiles fine. (I had to create a typedef enum for the command type - I assume you have that somewhere in your package).

I agree it is strange that the error occurs on that line with the report_error, but not with the warning.

I seen several cases where the real problem is not actually on the line the compiler says, but is one or two lines earlier, but that would probably still be the case with the warning.

I noticed that the line with the error has an extra “s” after the comment. Is that “s” there when you uncomment the line?

-Kurt

Hi Kurt,

No, I usually add extra ‘s’ when commenting so that i can figure out that the code was commented by me and not my team member:cool:

Thanks for you continued support to OVM users

Thanks,
Saurabh