I have a preprocessor macro that represents a hierarchical path into my design.
Example:
`define HPATH top.chip.block
I need to construct a string which holds the value of `HPATH
, so in my example the string should equal top.chip.block
.
Is there a way to construct such a string?
None of the following attempts worked:
string hpath;
hpath = "`HPATH"; // Results in hpath = "`HPATH"
hpath = \"``HPATH\"; // Doesn't compile
hpath = `HPATH; // Doesn't compile
I want hpath
to be equivalent to doing this assignment hpath = "top.chip.block"
, but by using `HPATH
instead of specifying the path again.
I cannot use %m
because I need the string within my top-level UVM environment, not within a module.
A little more background: the reason I want to do this is because I am using backdoor register access in the UVM class library. The backdoor API requires setting the hdl_path to the blocks within the design, as a string. I already have `defines for the hierarchical paths and am trying to reuse those when specifying the hdl_paths so I don't have the same path defined twice. My testbench will use both the hierarchical path and the string path.
We can create two or more than two strings in macro, then simply write them one after another to convert them into a concatenated string. The syntax is like below: #define STR1 "str1" #define STR2 " str2" #define STR3 STR1 STR2 //it will concatenate str1 and str2.
If you want to stringify the result of expansion of a macro argument, you have to use two levels of macros. s is stringified when it is used in str , so it is not macro-expanded first. But s is an ordinary argument to xstr , so it is completely macro-expanded before xstr itself is expanded (see Argument Prescan).
This is called token pasting or token concatenation. The ' ## ' preprocessing operator performs token pasting. When a macro is expanded, the two tokens on either side of each ' ## ' operator are combined into a single token, which then replaces the ' ## ' and the two original tokens in the macro expansion.
Macros allow you to write commonly used PL/I code in a way that hides implementation details and the data that is manipulated and exposes only the operations. In contrast with a generalized subroutine, macros allow generation of only the code that is needed for each individual use.
It's not possible to use a `define macro within a string literal. According to the SystemVerilog LRM:
Macro substitution and argument substitution shall not occur within string literals.
However a string literal can be constructed by using a macro that takes an argument and including the quotes in the macro by using ``"`.
Again, from the LRM:
An `" overrides the usual lexical meaning of " and indicates that the expansion shall include the quotation mark, substitution of actual arguments, and expansions of embedded macros. This allows string literals to be constructed from macro arguments.
So this works:
`define STRINGIFY(x) `"x`"
`define HPATH top.chip.block
string hpath = `STRINGIFY(`HPATH);
$display(hpath); // Output: "top.chip.block"
The example code can be run here: http://www.edaplayground.com/s/4/879
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With