Uvm_config_db report compile error

I just used the following code and met with a compile error

class cfg0 extends uvm_object; 
endclass

class C extends uvm_component; 
  cfg0 cfg0; 
  function void build_phase(uvm_phase phase);
  if(!uvm_config_db #(cfg0)::get(this, "", "cfg0", cfg0)
    $display("ERROR");
  endfunction 
endclass

The error message is:
Non-constant expression. The following expression should e a constant.

I doubt whether the error is due to name of class cfg0 which is same with object name.
I tried to change the “class cfg0” to “class cfg1”. It compile ok.
Can anyone explain this?

Thanks.

In reply to dmq0420:

Exactly, the type name and class object name must not have same name for setting/retrieving from config db.

In reply to mitesh.patel:

Could you elaborate why they should not have the same name?

In reply to dmq0420:

Your problem is here:

uvm_config_db #(<insert the class name here>)::get(this, "", "cfg0", cfg0)

In reply to chr_sue:

From my view, your code is same with mine.
Yours:

uvm_config_db #(<insert the class name here>)::get(this, "", "cfg0", cfg0)

Mine:

if(!uvm_config_db #(cfg0)::get(this, "", "cfg0", cfg0)

In reply to dmq0420:

I was reviewing you code on top. I see cfg0 is your class name. But I do not see an object of your class cfg0. You can only pass an object to the config_db.

The it has to be

if(!uvm_config_db #(cfg0)::get(this, "", "cfg0", <insert the object name of class cfg0 here>)

In reply to dmq0420:

Here, config db needs class type and class object for successful get as follow:

uvm_config_db #(<insert the class name here>)::get(this, "", "<insert string keyword here>", <insert an object name of the class here>)

And as per oops concept class object name must not be as same as the class name.

In reply to dmq0420:

I’m guessing your code is actually

class C extends uvm_component; 
  cfg0 cfg0;
  function void build_phase(uvm_phase phase);
  if(!uvm_config_db #(cfg0)::get(this, "", "cfg0", cfg0)
    $display("ERROR");
  endfunction 
endclass

By using the same name of the class type as the class variable, you are hiding the class type from further use in the class c. What you need is a different name.

class cfg0 extends uvm_object; 
endclass
 
class C extends uvm_component; 
  cfg0 cfg0_h;
  function void build_phase(uvm_phase phase);
  if(!uvm_config_db #(cfg0)::get(this, "", "cfg0_h", cfg0_h)
    $display("ERROR");
  endfunction 
endclass

In reply to dave_59:

Thanks Dave. Your code is exactly what I have.
I agree I’m hiding the class type. But I don’t know why I can’t use the same name for class type and object name. Actually I can’t find any description in the IEEE SystemVerilog standard about this.

In reply to dmq0420:

You certainly can use the same name for two different identifiers as long as they are in different local scopes. (Section 3.13). But the search rules for referencing an identifier within a scope (Section 23.9) says to pick up the most locally nested identifier name first. That’s what we mean by hiding the name.

If the class cfg0 was declared in a package, you could work around this by prefixing the package name.

package P1;
class cfg0 extends uvm_object; 
endclass
endpackage
package P2;
import P1::*;
class C extends uvm_component; 
  cfg0 cfg0;
  function void build_phase(uvm_phase phase);
  if(!uvm_config_db #(P1::cfg0)::get(this, "", "cfg0", cfg0)
    $display("ERROR");
  endfunction 
endclass

In reply to dave_59:

Thanks Dave. It did fix my issue.