user2400361
user2400361

Reputation: 169

Preventing argument substitution in Systemverilog text replacement macro

`define CONNECT(i) \
  some_mod inst1 (.i(i));

module test ();
 logic a;
 `CONNECT(a)
endmodule

In the CONNECT macro, how do I prevent a being swapped in for i in the ".i" portion of some_mod inst1 (.i(i));? I am looking for an expanded version like this:

module test ();
 logic a;
 some_mod inst1 (.i(a));
endmodule

instead of below version which is wrong

module test ();
 logic a;
 some_mod inst1 (.a(a));
endmodule

I understand I can either make some_mod's port name to be something other than i or change macro argument name from i to something else. I am just wondering if what I want to do is feasible at all.

Upvotes: 3

Views: 960

Answers (3)

toolic
toolic

Reputation: 62045

Since you already know all the port names of your some_mod module, you just need to choose a unique string for your macro. Assuming some_mod does not have a port named SIG:

`define CONNECT(SIG) \
  some_mod inst1 (.i(SIG));

UPDATE: To answer the new question: No, after referring to the IEEE Std 1800-2012, it is not feasible to selectively avoid some substitutions.

UPDATE 2: As Stan has demonstrated, there is a tricky solution; since it is not straightforward, it should be heavily commented.

Upvotes: 4

NiklasG
NiklasG

Reputation: 1

You can put double backticks (``) anywhere within words in macros, which splits the word in two in terms of macro substitution, but the `` itself is removed before further compillation.

So if the thing you wanted to prevent from substitution was more than a letter long, you could insert a `` somewhere (and make sure that neither half would then get substituted).

For a single letter word this won't work. Similar to Stan's answer (but I hope a bit more intuitive and better supported) you could `define i i and then use `i in your macro (polluting the global macro namespace with the `i macro ...).

Upvotes: 0

Stan
Stan

Reputation: 1237

You need to mark the locations that you don't want to substitute. While I'm not sure where this would be better than simply replacing the argument name (i.e. toolic's answer), it is possible to do so -- with a bit of creativity with default macro parameters. Let's say that you wanted to mark all places where 'i' shouldn't be replace with an underscore, then you would do the following:

`define CONNECT(i, _i=i) \
  some_mod inst1 (._i(i))

Since Verilog preprocessor only does one pass through the macro, it will replace all 'i' instances with your passed in value, and then change all '_i' instances into 'i'.

Upvotes: 2

Related Questions