veripool / verilog-perl

Verilog parser, preprocessor, and related tools for the Verilog-Perl package
https://www.veripool.org/verilog-perl
Artistic License 2.0
121 stars 34 forks source link

Incorrect macro expansion with combination of `", ``, and embedded macro usage #1668

Closed martinwhitaker closed 4 years ago

martinwhitaker commented 4 years ago

Background: I'm trying to fix the handling of SV macro expansion in Icarus Verilog, so this is an artificial test case designed to explore what other simulators do. The code is

`define PREFIX_        my_prefix_
`define SUFFIX          my_suffix

`define PREFIX_SUFFIX   my_prefix_suffix

`define name1           `PREFIX``_```SUFFIX
`define name2(p,s)      p``_``s 
`define name3(p)        ```p``_SUFFIX

`define stringify(text) `"text`"

module test();

initial begin  
  $display(`stringify(`name1));
  $display(`stringify(`name2(`PREFIX, `SUFFIX)));
  $display(`stringify(`name3(PREFIX)));
  $finish;
end

endmodule

The output is

module test();

initial begin
  $display(`PREFIX_my_suffix"");
  $display(`PREFIX_my_suffix"");
  $display("my_prefix_suffix");
  $finish;
end

endmodule

whereas I expect

module test();

initial begin
  $display("my_prefix_my_suffix");
  $display("my_prefix_my_suffix");
  $display("my_prefix_suffix");
  $finish;
end

endmodule

If I replace

`define PREFIX_        my_prefix_

with

`define PREFIX         my_prefix

the output is

module test();

initial begin
  $display("my_prefix_my_suffix");
  $display("my_prefix_my_suffix");
  $display("my_prefix_SUFFIX");
  $finish;
end

endmodule

which although it contradicts a strict reading of the IEEE standard, does at least generate compilable code.

wsnyder commented 4 years ago

I think what it does is consistent with several commercial simulators (another gives an error). IEEE doesn't really cover a lot of these corner cases, UVM tends to be a good test. You should also see my paper https://www.veripool.org/papers/Preproc_Good_Evil_SNUGBos10_paper.pdf and also the preprocessor tests in Verilog Perl and better, in test_regress/t of Verilator.

martinwhitaker commented 4 years ago

Sorry, but no other simulator gets the stringification wrong as shown in the first output.

wsnyder commented 4 years ago

This is what I got from one:

`PREFIX_my_suffix
`name2(`PREFIX, my_suffix)
`name3(PREFIX)

Results differ, which is part of my point of that paper, that it isn't standardized.

martinwhitaker commented 4 years ago

You're missing my point. In the first case, regardless of how the macro expansion is handled, the double quotes should enclose the resulting text, not come after it.

I realise there's a lot of variation in how the macro expansion is handled, and I think your solution is a good one. I'm inclined to mimic it in Icarus Verilog.

wsnyder commented 4 years ago

Yes, I was misreading what you saw as wrong. I pushed a fix to stringify undefined macros, ditto for Verilator (which BTW has the same preprocessor but additional features and tests so you may prefer using that.) Thanks for your report.