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
Let’s go through below example to understand it in detail,
---------------------------------------------------------------------------
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module top(); | |
`define HI Hello | |
`define LO "`HI, world" | |
`define H(x) "Hello, x" | |
initial begin | |
$display("`HI, world"); | |
$display(`LO); | |
$display(`H(world)); | |
end | |
endmodule : top | |
//Output: | |
// `HI, world | |
// `HI, world | |
// Hello, x |
---------------------------------------------------------------------------
However a string literal can be
constructed by using a macro that takes an argument and including the quotes in
the macro by using `".
According to SystemVerilog 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.
---------------------------------------------------------------------------
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module top(); | |
`define HI Hello | |
// macro substitution | |
`define LO `"`HI, world`" | |
// argument substitution | |
`define H(x) `"Hello, x`" | |
initial begin | |
$display(`LO); | |
$display(`H(world)); | |
end | |
endmodule : top | |
//Output: | |
// Hello, world | |
// Hello, world |
---------------------------------------------------------------------------
Now what if you want to add double
quotes in string which is constructed using macro. SystemVerilog provides
support for that.
A `\`" indicates that the expansion should include the escape
sequence \".
Let’s go through example to see how
it works,
---------------------------------------------------------------------------
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module top(); | |
`define msg(x,y) `"x: `\`"y`\`"`" | |
initial begin | |
$display(`msg(left side,right side)); | |
// expands to | |
// $display("left side: \"right side\""); | |
end | |
endmodule : top | |
//Output: | |
// left side: "right side" |
---------------------------------------------------------------------------
SystemVerilog LRM also provides support to construct identifier from arguments using ``.
There are three places where we can substitute argument to construct identifier
1) Substitute argument in between something (neither at the end nor at the beginning of the identifier)
2) Prepend argument (at the beginning of the identifier)
2) Append argument (at the end of the identifier)
---------------------------------------------------------------------------
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module top(); | |
int unsigned pkt_tx_cnt; | |
int unsigned pkt_rx_cnt; | |
bit clock_master; | |
bit reset_master; | |
int unsigned count_a; | |
int unsigned count_b; | |
`define increment(dir) \ | |
pkt_``dir``_cnt = pkt_``dir``_cnt + 1; | |
`define set(sig, value) \ | |
sig``_master = value; | |
`define update_count(sel, value) \ | |
count_``sel = value; | |
initial begin | |
$display("pkt_tx_cnt:%0d, pkt_rx_cnt:%0d", pkt_tx_cnt, pkt_rx_cnt); | |
$display("clock_master:%b, reset_master:%b", clock_master, reset_master); | |
$display("count_a:%0d, count_b:%0d", count_a, count_b); | |
$display(); | |
`increment(tx) | |
`set(clock, 1) | |
`update_count(a, 5) | |
$display("pkt_tx_cnt:%0d, pkt_rx_cnt:%0d", pkt_tx_cnt, pkt_rx_cnt); | |
$display("clock_master:%b, reset_master:%b", clock_master, reset_master); | |
$display("count_a:%0d, count_b:%0d", count_a, count_b); | |
$display(); | |
`increment(rx) | |
`set(reset, 1) | |
`update_count(b, 7) | |
$display("pkt_tx_cnt:%0d, pkt_rx_cnt:%0d", pkt_tx_cnt, pkt_rx_cnt); | |
$display("clock_master:%b, reset_master:%b", clock_master, reset_master); | |
$display("count_a:%0d, count_b:%0d", count_a, count_b); | |
end | |
endmodule : top | |
//Output: | |
// pkt_tx_cnt:0, pkt_rx_cnt:0 | |
// clock_master:0, reset_master:0 | |
// count_a:0, count_b:0 | |
// pkt_tx_cnt:1, pkt_rx_cnt:0 | |
// clock_master:1, reset_master:0 | |
// count_a:5, count_b:0 | |
// pkt_tx_cnt:1, pkt_rx_cnt:1 | |
// clock_master:1, reset_master:1 | |
// count_a:5, count_b:7 |
---------------------------------------------------------------------------
Reference:
1) SystemVerilog 2012 LRM
I have macro, inside one more macro is there. meanwhile I am passing value from top macro to inner macro. I have argument in top macro, then I want to pass the same value into inner macro.is it possible.
ReplyDelete