Which simulator is correctly interpreting these nested macros?

I am trying to determine which of two simulators are doing “the right thing” with the following nested macro. Here’s a very simplified example:

`define FOO foo
`define BAR bar
`define JOIN_ME(__prefix,__name) __prefix``__name
`define JOINED `JOIN_ME(`FOO, `BAR)
`define JOINED_STR `"`JOINED`"

module macro_test ();
initial begin
    #1;
    $display("JOINED_STR: %s", `JOINED_STR);
end
endmodule

I have one simulator that displays:

JOINED_STR: foobar

While the other does the following:

JOINED_STR: `JOIN_ME(foo, bar)

Which is doing the right thing? Does the LRM have anything to say about such cases?

Thanks!

I believe the correct behavior is

JOINED_STR: foobar

The LRM says

The macro text and argument defaults may contain usages of other text macros. Such usages shall be substituted after the outer macro is substituted, not when it is defined.

and

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.

The LRM committee discussion that explicitly adds the fact that the string must expand the embedded macros can be found here: 404

In reply to dave_59:

Thank you very much Dave. What’s concerning to me is that the simulator in question doing the “wrong” thing appears to continue to do the wrong thing despite the LRM clearly stating this and having done so for many years from the dates in the LRM committee discussion.

So, tool bug then?

Also, is there a way to work around this that would be simulator agnostic in the meantime?

In reply to jkc120:

Difficult for me to suggest a workaround without knowing why you needed these nested macros in the first place.

In reply to dave_59:

Without going into too much detail (that I wouldn’t be permitted to post here anyway), basically I noticed this particular bug in the simulator due to this construct used in the testbench I was given:

define JOIN(__prefix,__name) __prefix``__name ... define TRACKER_SUFFIX .trk
define TRACKER_FILE JOIN(TEST_FILE,TRACKER_SUFFIX)
define TRACKER_FILE_STRING TRACKER_FILE

TRACKER_FILE_STRING is used later to write out the tracker .trk file, which should be test1.sv.trk for example, but with the one simulator we get files with: JOIN(test1.sv,.trk?)? instead of test1.sv.trk

Thanks!

In reply to jkc120:

How about

`define FOO foo
`define BAR bar
`define JOIN_ME(__prefix,__name) __prefix``__name
`define QUOTE(_me) `"_me`"
`define JOINED `JOIN_ME(`FOO, `BAR)
`define JOINED_STR `QUOTE(`JOINED)
 
module macro_test ();
initial begin
    #1;
    $display("JOINED_STR: %s", `JOINED_STR);
end
endmodule

In reply to dave_59:

Unfortunately, it still doesn’t work:

JOINED_STR: `JOIN_ME(foo, bar)

It seems this vendor’s simulator is simply not compliant to the LRM for `"

I guess at this point I have no recourse but to wait for them to fix the bug?

Thank you for your time!