Passing string name as input to macro but internally it represents the actual value. Is that Possible?

Hello !

  1. Wanted to create a simple macro which represents the repeated code as show below. Simple code for getting a virtual interface and its often repeated. Wanted to create a macro which represents the code so that can pass the necessary input to the macro to mimic the code.
`define GET_VIF_HDL(VARIABLE_NAME, VARIABLE_FIELD_NAME, VARIABLE_VALUE) \
 if (!uvm_config_db#(virtual ``VARIABLE_NAME``)::get(.cntxt(uvm_root::get()), .inst_name ("*"), .field_name(`"VARIABLE_FIELD_NAME`"), .value(``VARIABLE_VALUE``))) \
  `uvm_warning(get_full_name(), $psprintf("GET_VIF_HDL: Unable to find the Handle For: VARIABLE_NAME: %p, VARIABLE_FIELD_NAME: %p!\n", ``VARIABLE_NAME``, `"VARIABLE_FIELD_NAME`")) \
 else \
  `uvm_info(get_full_name(), $psprintf("GET_VIF_HDL: Received the Handle For: VARIABLE_NAME: %p, VARIABLE_FIELD_NAME: %p!\n", ``VARIABLE_NAME``, `"VARIABLE_FIELD_NAME`"), UVM_HIGH) \
  1. But when used inside any class by passing the interface name as VARIABLE_NAME during compilation it errors out saying, Undeclared Identifier as name is not visible in the respective area/context. But any reason why it’s throwing this error ? because expectation is the macro gets expanded with the passed in interface name and then gets compiled in the nxt step.

  2. If the above is not possible, is there any other way to pass in the VARIABLE_NAME as string input and internally gets used as actual value ? So that way it does’t look for the existence of variable in that scope.

Please drop in your comments / suggestions.

**Working Example With the Error Info:
**

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

`define GET_VIF_HDL(VARIABLE_NAME, VARIABLE_FIELD_NAME, VARIABLE_VALUE) \
 if (!uvm_config_db#(virtual ``VARIABLE_NAME``)::get(.cntxt(uvm_root::get()), .inst_name ("*"), .field_name(`"VARIABLE_FIELD_NAME`"), .value(``VARIABLE_VALUE``))) \
  `uvm_warning("CLASS", $psprintf("GET_VIF_HDL: Unable to find the Handle For: VARIABLE_NAME: %p, VARIABLE_FIELD_NAME: %p!\n", ``VARIABLE_NAME``, `"VARIABLE_FIELD_NAME`")) \
 else \
  `uvm_info("CLASS", $psprintf("GET_VIF_HDL: Received the Handle For: VARIABLE_NAME: %p, VARIABLE_FIELD_NAME: %p!\n", ``VARIABLE_NAME``, `"VARIABLE_FIELD_NAME`"), UVM_HIGH) \

interface abc_interface;
    logic what;
endinterface: abc_interface 

class simpleclass;
    virtual abc_interface        abc_vif;

    function get_vif();
    `GET_VIF_HDL(abc_interface, abc_vif, abc_vif)
    endfunction: get_vif
endclass: simpleclass

module simplertl;
   simpleclass   sc;
   abc_interface abc_if();

   initial begin 
    uvm_config_db #(virtual abc_interface)::set(null, "*", "abc_vif", abc_if);
   end

   initial begin
      sc = new();
      sc.get_vif();
   end
endmodule: simplertl

Error Message:
xmelab: *E,CUVUNF (./simplertl.sv,18|56): Hierarchical name component lookup failed for ‘abc_interface’ at ‘$unit_0x7a60dc18’.
`GET_VIF_HDL(abc_interface, abc_vif, abc_vif)

In reply to desperadorocks:

Your problem is your uvm_warning/error messages you have **VARIABLE_NAME** when you meant to turn it into a string with "**VARIABLE_NAME**". `` is for building identifiers with macro arguments as parts of it. `" is for build strings with macro arguments as part of it. From your example, it looks like your macro only needs two arguments, with VARIABLE_VALUE used to create both an identifier and a string.

import uvm_pkg::*;
`include "uvm_macros.svh"
 
`define GET_VIF_HDL(VARIABLE_NAME, VARIABLE_VALUE) \
if (!uvm_config_db#(virtual VARIABLE_NAME)::get(.cntxt(null), .inst_name ("*"), .field_name(`"VARIABLE_VALUE`"), .value(VARIABLE_VALUE))) \
   `uvm_warning("CLASS", $sformatf("GET_VIF_HDL: Unable to find the Handle For: VARIABLE_NAME: %s, VARIABLE_NAME: %s!\n", `"VARIABLE_VALUE`", `"VARIABLE_VALUE`")) \
 else \
   `uvm_info("CLASS", $sformatf("GET_VIF_HDL: Received the Handle For: VARIABLE_NAME: %s, VARIABLE_VALUE: %s!\n", `"VARIABLE_NAME`", `"VARIABLE_VALUE`"), UVM_LOW) \
 
interface abc_interface;
    logic what;
endinterface: abc_interface 
 
class simpleclass;
    virtual abc_interface        abc_vif;
 
    function void get_vif();
    `GET_VIF_HDL(abc_interface, abc_vif)
    endfunction: get_vif
endclass: simpleclass
 
module simplertl;
   simpleclass   sc;
   abc_interface abc_if();
 
   initial begin 
     uvm_config_db #(virtual abc_interface)::set(null, "*", "abc_vif", abc_if);
   end
 
   initial begin
      sc = new();
      sc.get_vif();
   end
endmodule: simplertl

In reply to dave_59:

Thanks a ton Dave for pointing it out ! Really appreciate that.