Merge pull request #61 from DaveMcEwan/ppTests

Bugfixes for `preprocess()`, plus organise and extend tests.
This commit is contained in:
dalance 2022-08-01 12:11:45 +09:00 committed by GitHub
commit aabc9aa646
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
91 changed files with 1556 additions and 620 deletions

View File

@ -1446,8 +1446,6 @@ pub(crate) const KEYWORDS_1800_2017: &[&str] = &[
]; ];
pub(crate) const KEYWORDS_DIRECTIVE: &[&str] = &[ pub(crate) const KEYWORDS_DIRECTIVE: &[&str] = &[
"__FILE__",
"__LINE__",
"begin_keywords", "begin_keywords",
"celldefine", "celldefine",
"default_nettype", "default_nettype",

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
`begin_keywords "1364-2005" // use IEEE Std 1364-2005 Verilog keywords
interface if2 (); // ERROR: "interface" is not a keyword in 1364-2005
// This interface should pass the preprocessor, but not the main parser
// because the identifiers `interface` and `endinterface` are not reserved
// keywords in IEEE1364-2005.
endinterface // ERROR: "endinterface" is not a keyword in 1364-2005
`end_keywords

View File

@ -0,0 +1,8 @@
`begin_keywords "1364-2001"
module m2 ();
// "logic" is NOT a reserved keyword in IEEE1364-2001.
// This module should pass both the preprocessor, AND the main parser.
reg [63:0] logic;
endmodule
`end_keywords

View File

@ -0,0 +1,8 @@
`begin_keywords "1800-2005"
module m2 ();
// "logic" IS a reserved keyword in IEEE1800-2005.
// This module should pass both the preprocessor, but NOT the main parser.
reg [63:0] logic;
endmodule
`end_keywords

View File

@ -0,0 +1,10 @@
/* IEEE1800-2017 Clause 22.5.1 page 679
*/
`define max(a,b)((a) > (b) ? (a) : (b))
`define TOP(a,b) a + b
module m;
assign n = `max(p+q, r+s) ;
assign z = `TOP( `TOP(b,1), `TOP(42,a) );
endmodule

View File

@ -0,0 +1,7 @@
/* IEEE1800-2017 Clause 22.5.1 page 680
*/
`define append(f) f``_master
module `append(clock);
endmodule

View File

@ -1,3 +1,6 @@
/* IEEE1800-2017 Clause 22.5.1 page 680
*/
`define msg(x,y) `"x: `\`"y`\`"`" `define msg(x,y) `"x: `\`"y`\`"`"
module a; module a;

View File

@ -0,0 +1,13 @@
/* IEEE1800-2017 Clause 22.5.1 page 679
*/
module main;
`define HI Hello
`define LO "`HI, world"
`define H(x) "Hello, x"
initial begin
$display("`HI, world");
$display(`LO);
$display(`H(world));
end
endmodule

View File

@ -0,0 +1,25 @@
/* IEEE1800-2017 Clause 22.5.1 page 678
* NOTE: Illegal cases are not included in this testcase.
* NOTE: Use of EMPTY is suggested on page 679
*/
`define MACRO1(a=5,b="B",c) $display(a,,b,,c);
`define MACRO2(a=5, b, c="C") $display(a,,b,,c);
`define MACRO3(a=5, b=0, c="C") $display(a,,b,,c);
`define EMPTY
module m;
initial begin
`MACRO1 ( , 2, 3 )
`MACRO1 ( 1 , , 3 )
`MACRO1 ( , 2, )
`MACRO2 (1, , 3)
`MACRO2 (, 2, )
`MACRO2 (, 2)
`MACRO3 ( 1 )
`MACRO3 ( )
`MACRO3 (`EMPTY,`EMPTY,`EMPTY)
end
endmodule

View File

@ -0,0 +1,13 @@
/* IEEE1800-2017 Clause 22.5.1 page 677
* NOTE: Illegal cases are not included in this testcase.
*/
`define D(x,y) initial $display("start", x , y, "end");
module m;
`D( "msg1" , "msg2" )
`D( " msg1", )
`D(, "msg2 ")
`D(,)
`D( , )
endmodule

View File

@ -0,0 +1,13 @@
// IEEE1800-2017 Clause 22.10
// The directives `celldefine and `endcelldefine tag modules as cell modules.
// Cells are used by certain PLI routines and may be useful for applications
// such as delay calculations. It is advisable to pair each `celldefine with an
// `endcelldefine, but it is not required. The latest occurrence of either
// directive in the source controls whether modules are tagged as cell modules.
// More than one of these pairs may appear in a single source description.
// These directives may appear anywhere in the source description, but it is
// recommended that the directives be specified outside any design elements.
// The `resetall directive includes the effects of a `endcelldefine directive.
`celldefine
`endcelldefine
// This file should be emitted from the preprocessor unchanged.

View File

@ -0,0 +1,22 @@
// IEEE1800-2017 Clause 22.8
// The directive `default_nettype controls the net type created for implicit
// net declarations. It can be used only outside design elements. Multiple
// `default_nettype directives are allowed. The latest occurrence of this
// directive in the source controls the type of nets that will be implicitly
// declared.
// When no `default_nettype directive is present or if the `resetall directive
// is specified, implicit nets are of type wire. When the `default_nettype is
// set to none, all nets shall be explicitly declared. If a net is not
// explicitly declared, an error is generated.
`default_nettype wire // Comment immmediately after keyword+space
`default_nettype tri
`default_nettype tri0
`default_nettype tri1
`default_nettype wand
`default_nettype triand
`default_nettype wor
`default_nettype trior
`default_nettype trireg
`default_nettype uwire
`default_nettype none// Comment immmediately after keyword
// This file should be emitted from the preprocessor unchanged.

View File

@ -0,0 +1,8 @@
`begin_keywords "1364-2005" // use IEEE Std 1364-2005 Verilog keywords
interface if2 (); // ERROR: "interface" is not a keyword in 1364-2005
// This interface should pass the preprocessor, but not the main parser
// because the identifiers `interface` and `endinterface` are not reserved
// keywords in IEEE1364-2005.
endinterface // ERROR: "endinterface" is not a keyword in 1364-2005
`end_keywords

View File

@ -0,0 +1,8 @@
`begin_keywords "1364-2001"
module m2 ();
// "logic" is NOT a reserved keyword in IEEE1364-2001.
// This module should pass both the preprocessor, AND the main parser.
reg [63:0] logic;
endmodule
`end_keywords

View File

@ -0,0 +1,8 @@
`begin_keywords "1800-2005"
module m2 ();
// "logic" IS a reserved keyword in IEEE1800-2005.
// This module should pass both the preprocessor, but NOT the main parser.
reg [63:0] logic;
endmodule
`end_keywords

View File

@ -0,0 +1,10 @@
/* IEEE1800-2017 Clause 22.5.1 page 679
*/
`define max(a,b)((a) > (b) ? (a) : (b))
`define TOP(a,b) a + b
module m;
assign n = ((p+q) > (r+s) ? (p+q) : (r+s)) ;
assign z = b + 1 + 42 + a;
endmodule

View File

@ -0,0 +1,7 @@
/* IEEE1800-2017 Clause 22.5.1 page 680
*/
`define append(f) f``_master
module clock_master;
endmodule

View File

@ -0,0 +1,10 @@
/* IEEE1800-2017 Clause 22.5.1 page 680
*/
`define msg(x,y) `"x: `\`"y`\`"`"
module a;
initial begin
$display("left side: \"right side\"");
end
endmodule

View File

@ -0,0 +1,13 @@
/* IEEE1800-2017 Clause 22.5.1 page 679
*/
module main;
`define HI Hello
`define LO "`HI, world"
`define H(x) "Hello, x"
initial begin
$display("`HI, world");
$display("`HI, world");
$display("Hello, x");
end
endmodule

View File

@ -0,0 +1,25 @@
/* IEEE1800-2017 Clause 22.5.1 page 678
* NOTE: Illegal cases are not included in this testcase.
* NOTE: Use of EMPTY is suggested on page 679
*/
`define MACRO1(a=5,b="B",c) $display(a,,b,,c);
`define MACRO2(a=5, b, c="C") $display(a,,b,,c);
`define MACRO3(a=5, b=0, c="C") $display(a,,b,,c);
`define EMPTY
module m;
initial begin
$display(5,,2,,3);
$display(1,,"B",,3);
$display(5,,2,,);
$display(1,,,,3);
$display(5,,2,,"C");
$display(5,,2,,"C");
$display(1,,0,,"C");
$display(5,,0,,"C");
$display(,,,,);
end
endmodule

View File

@ -0,0 +1,13 @@
/* IEEE1800-2017 Clause 22.5.1 page 677
* NOTE: Illegal cases are not included in this testcase.
*/
`define D(x,y) initial $display("start", x , y, "end");
module m;
initial $display("start", "msg1" , "msg2", "end");
initial $display("start", " msg1" , , "end");
initial $display("start", , "msg2 ", "end");
initial $display("start", , , "end");
initial $display("start", , , "end");
endmodule

View File

@ -0,0 +1,3 @@
module a;
reg \`~!-_=+\|[]{};:'"",./<>? ;
endmodule

View File

@ -0,0 +1,5 @@
module A;
wire a = 1'b0;
endmodule

View File

@ -0,0 +1,7 @@
module and_op (a, b, c);
output a;
input b, c;
wire a = b & c;
endmodule

View File

@ -0,0 +1,7 @@
module and_op (a, b, c);
output a;
input b, c;
and a1 (a,b,c);
endmodule

View File

@ -0,0 +1,5 @@
// pragma translate_off
module A;
endmodule
// pragma translate_on

View File

@ -1,3 +1,3 @@
module and_op (a, b, c); module and_op (a, b, c);
`include "test2.svh"
endmodule endmodule

View File

@ -0,0 +1,8 @@
module and_op (a, b, c);
output a;
input b, c;
and a1 (a,b,c);
endmodule

View File

@ -0,0 +1,9 @@
// Based on last example of IEEE1800-2017 Clause 22.5.1, page 680.
`define APPEND_SVH(path) `"path.svh`"
module and_op (a, b, c);
output a;
input b, c;
and a1 (a,b,c);
endmodule

View File

@ -0,0 +1,8 @@
`define PATH "included.svh"
module and_op (a, b, c);
output a;
input b, c;
and a1 (a,b,c);
endmodule

View File

@ -0,0 +1,8 @@
module and_op (a, b, c);
output a;
input b, c;
and a1 (a,b,c);
// comment
endmodule

View File

@ -0,0 +1,9 @@
module and_op (a, b, c);
// a
output a;
input b, c;
and a1 (a,b,c);
endmodule

View File

@ -0,0 +1,15 @@
// __FILE__ = `__FILE__
// This block SHOULD be emitted from the preprocessor.
// Emitted instead.
// The following define should have no effect.
`define __FILE__ "FOO"
// The following undef should have no effect.
`undef __FILE__
// NOTE: Comparison against expected value are destined to fail in testcase.

View File

@ -0,0 +1,21 @@
// __LINE__ = `__LINE__
// This block SHOULD be emitted from the preprocessor.
// Emitted instead.
// The following define should have no effect.
`define __LINE__ -2
// The following undef should have no effect.
`undef __LINE__
module M;
initial
if (26 == 28) // Should be "26 == 28".
$display("PASS");
else if (28 == 28) // Should be "28 == 28".
$display("FAIL");
endmodule

View File

@ -0,0 +1,23 @@
// Macro with parameters with usage spread over multiple lines.
// Final line of macro is line14.
// Argument value `clk` is equal to its name.
// Argument value of exp contains matching brackets and parentheses.
// Bracketed value of msg is required to avoid being parsed as a parameterized
// macro instead of argumnts to $display.
// NOTE: Trailing whitespace is not exercised here, i.e. continuations
// immediately follow non-whitespace.
`define disp(clk, exp, msg)\
always @(posedge clk)\
if (exp) begin\
$display msg;\
end\
module M ();
always @(posedge clk)
if (!(a[i].b && c[i])) begin
$display ("xxx(()[]]{}}}", a[i].b, c[i]);
end
; // NOTE: Semi-colon is unnecessary.
endmodule

View File

@ -0,0 +1,6 @@
`define A aaa
module M;
aaa#() a0 (.*); // No trailing whitespace.
aaa #() a1 (.*); // Trailing 1 space.
aaa #() a2 (.*); // Trailing 2 spaces.
endmodule

View File

@ -0,0 +1,16 @@
/* IEEE1800-2017 Clause 22.5.1, page 676
If a one-line comment (that is, a comment specified with the characters //) is
included in the text, then the comment shall not become part of the substituted
text.
*/
// A has no comment
// B has a comment after 1 space
// C has a comment after 3 spaces
`define A 11
`define B 22 // Comment not included in macro, but whitespace before `//` is.
`define C 33 // Comment not included in macro, but whitespace before `//` is.
interface A #(p=11) (); endinterface
interface B #(p=22 ) (); endinterface
interface C #(p=33 ) (); endinterface

View File

@ -0,0 +1,17 @@
// Multi-line macro defined with 2 trailing spaces before initial continuation.
// First line has no trailing space, second has trailing space, third is end.
// Macro contains 2-space indent, so indented usage gets extra.
// Delimiters (``) used before and after arguments.
`define connect(NAME, INDEX = 0) \
assign NAME``_``INDEX``__x = NAME[INDEX].x;\
assign NAME``_``INDEX``__y = NAME[INDEX].y; \
assign NAME``_``INDEX``__z = NAME[INDEX].z;
module M ();
assign a_0__x = a[0].x;
assign a_0__y = a[0].y;
assign a_0__z = a[0].z;
assign a_1__x = a[1].x;
assign a_1__y = a[1].y;
assign a_1__z = a[1].z;
endmodule

View File

@ -0,0 +1,10 @@
`define A "aaa"
`define \B "bbb"
module M;
initial begin
$display("aaa");
$display("aaa" );
$display("bbb");
$display("bbb" );
end
endmodule

View File

@ -0,0 +1,19 @@
// Leading whitespace on 4 lines.
// initial \ Space before line continuation.
// begin\ No space before line continuation.
// $display(); // comment \ Continuation at end of comment.
// end
// NOTE: Trailing whitespace on lines ending `initial ` and `$display(); `.
`define A \
initial \
begin\
$display(); // comment \
end
module M;
initial
begin
$display();
end
endmodule

View File

@ -0,0 +1,20 @@
// IEEE1800-2017 Clause 22.5.2
// The directive `undef shall undefine the specified text macro if previously
// defined by a `define compiler directive within the compilation unit. An
// attempt to undefine a text macro that was not previously defined using a
// `define compiler directive can issue a warning.
`undef FOO
`undef FOO// Comment
`undef FOO // Comment
`define FOO foo
// AAA
// This block SHOULD be emitted from the preprocessor.
`undef FOO
// BBB
// This block SHOULD be emitted from the preprocessor.

View File

@ -0,0 +1,29 @@
// IEEE1800-2017 Clause 22.5.3
// The directive `undefineall directive shall undefine all text macros
// previously defined by `define compiler directives within the compilation
// unit. This directive takes no argument and may appear anywhere in the source
// description.
`undefineall
`undefineall// Comment
`undefineall // Comment
`define FOO foo
`define BAR bar
// AAA
// This block SHOULD be emitted from the preprocessor.
// BBB
// This block SHOULD be emitted from the preprocessor.
`undefineall
// CCC
// This block SHOULD be emitted from the preprocessor.
// DDD
// This block SHOULD be emitted from the preprocessor.

View File

@ -0,0 +1,10 @@
module and_op (a, b, c);
output a;
input b, c;
`ifdef behavioral
wire a = b & c;
`else
and a1 (a,b,c);
`endif
endmodule

View File

@ -1,3 +1,3 @@
module and_op (a, b, c); module and_op (a, b, c);
`include "test2.svh" // comment `include "included.svh"
endmodule endmodule

View File

@ -0,0 +1,3 @@
module and_op (a, b, c);
`include "included.svh"
endmodule

View File

@ -0,0 +1,5 @@
`define PATH included.svh
`define QUOTE(path) `"path`"
module and_op (a, b, c);
`include `QUOTE(`PATH)
endmodule

View File

@ -0,0 +1,5 @@
`define PATH included.svh
`define QUOTED_PATH `"`PATH`"
module and_op (a, b, c);
`include `QUOTED_PATH
endmodule

View File

@ -0,0 +1,5 @@
// Based on last example of IEEE1800-2017 Clause 22.5.1, page 680.
`define APPEND_SVH(path) `"path.svh`"
module and_op (a, b, c);
`include `APPEND_SVH(included)
endmodule

View File

@ -0,0 +1,4 @@
`define PATH "included.svh"
module and_op (a, b, c);
`include `PATH
endmodule

View File

@ -0,0 +1,3 @@
// foo
`include "include_recursive.svh"
// bar

View File

@ -0,0 +1,3 @@
module and_op (a, b, c);
`include "included.svh" // comment
endmodule

View File

@ -0,0 +1,3 @@
module and_op (a, b, c);
`include "included.svh" `include "included.svh"
endmodule

View File

@ -0,0 +1,2 @@
module and_op (a, b, c);
`include "included.svh" endmodule

View File

@ -1,4 +1,4 @@
module and_op (a, b, c); module and_op (a, b, c);
// a // a
`include "test2.svh" `include "included.svh"
endmodule endmodule

View File

@ -0,0 +1,50 @@
// IEEE1800-2017 Clause 22.14
// A pair of directives, `begin_keywords and `end_keywords, can be used to
// specify what identifiers are reserved as keywords within a block of source
// code, based on a specific version of IEEE Std 1364 or IEEE Std 1800.
// The `begin_keywords and `end_keywords directives only specify the set of
// identifiers that are reserved as keywords. The directives do not affect the
// semantics, tokens, and other aspects of the SystemVerilog language.
// The `begin_keywords and `end_keywords directives can only be specified
// outside a design element. The `begin_keywords directive affects all source
// code that follows the directive, even across source code file boundaries,
// until the matching `end_keywords directive or the end of the compilation
// unit. The results of these directives are not affected by the `resetall
// directive.
`begin_keywords "1800-2017"
`end_keywords
`begin_keywords "1800-2012"
`end_keywords
`begin_keywords "1800-2009"
`end_keywords
`begin_keywords "1800-2005"
`end_keywords
`begin_keywords "1364-2005"
`end_keywords
`begin_keywords "1364-2001"
`end_keywords
`begin_keywords "1364-2001-noconfig"
`end_keywords
`begin_keywords "1364-1995"
`end_keywords
// The `begin_keywords `end_keywords directive pair can be nested. Each nested
// pair is stacked so that when an `end_keywords directive is encountered, the
// implementation returns to using the version_ specifier that was in effect
// prior to the matching `begin_keywords directive.
`begin_keywords "1800-2017"
`begin_keywords "1800-2012"
`begin_keywords "1800-2009"
`begin_keywords "1800-2005"
`begin_keywords "1364-2005"
`begin_keywords "1364-2001"
`begin_keywords "1364-2001-noconfig"
`begin_keywords "1364-1995"
`end_keywords
`end_keywords
`end_keywords
`end_keywords
`end_keywords
`end_keywords
`end_keywords
`end_keywords
// This file should be emitted from the preprocessor unchanged.

View File

@ -0,0 +1,34 @@
// IEEE1800-2017 Clause 22.12
// The `line compiler directive can be used to specify the original source code
// line number and file name.
// This allows the location in the original file to be maintained if another
// process modifies the source. After the new line number and file name are
// specified, the compiler can correctly refer to the original source location.
// However, a tool is not required to produce `line directives. These
// directives are not intended to be inserted manually into the code, although
// they can be.
// The compiler shall maintain the current line number and file name of the
// file being compiled. The `line directive shall set the line number and file
// name of the following line to those specified in the directive.
// The directive can be specified anywhere within the SystemVerilog source
// description. However, only white space may appear on the same line as the
// `line directive. Comments are not allowed on the same line as a `line
// directive. All parameters in the `line directive are required. The results
// of this directive are not affected by the `resetall directive.
//
// The number parameter shall be a positive integer that specifies the new line
// number of the following text line. The filename parameter shall be a string
// literal that is treated as the new name of the file. The filename can also
// be a full or relative path name. The level parameter shall be 0, 1, or 2.
// The value 1 indicates that the following line is the first line after an
// include file has been entered. The value 2 indicates that the following
// line is the first line after an include file has been exited. The value
// 0 indicates any other line.
`line 3 "orig.v" 2
// This line is line 3 of orig.v after exiting include file
`line 999 "foo.sv" 2
`line 888 "foo.sv" 1
`line 777 "foo.sv" 0
// This file should be emitted from the preprocessor unchanged.

View File

@ -0,0 +1,24 @@
// __FILE__ = `__FILE__
`ifdef __FILE__
// This block SHOULD be emitted from the preprocessor.
`elsif UNDEFINED
// NOT emitted.
`endif
`ifndef __FILE__
// This block should NOT be emitted from the preprocessor.
// However, following (conditional) definition should make it through the
// preprocessor parsing stage without error.
`define __FILE__ "(null)"
`elsif UNDEFINED
// Emitted instead.
`endif
// The following define should have no effect.
`define __FILE__ "FOO"
// The following undef should have no effect.
`undef __FILE__
// NOTE: Comparison against expected value are destined to fail in testcase.

View File

@ -0,0 +1,30 @@
// __LINE__ = `__LINE__
`ifdef __LINE__
// This block SHOULD be emitted from the preprocessor.
`elsif UNDEFINED
// NOT emitted.
`endif
`ifndef __LINE__
// This block should NOT be emitted from the preprocessor.
// However, following (conditional) definition should make it through the
// preprocessor parsing stage without error.
`define __LINE__ -1
`elsif UNDEFINED
// Emitted instead.
`endif
// The following define should have no effect.
`define __LINE__ -2
// The following undef should have no effect.
`undef __LINE__
module M;
initial
if (`__LINE__ == 28) // Should be "26 == 28".
$display("PASS");
else if (`__LINE__ == 28) // Should be "28 == 28".
$display("FAIL");
endmodule

View File

@ -0,0 +1,23 @@
// Macro with parameters with usage spread over multiple lines.
// Final line of macro is line14.
// Argument value `clk` is equal to its name.
// Argument value of exp contains matching brackets and parentheses.
// Bracketed value of msg is required to avoid being parsed as a parameterized
// macro instead of argumnts to $display.
// NOTE: Trailing whitespace is not exercised here, i.e. continuations
// immediately follow non-whitespace.
`define disp(clk, exp, msg)\
always @(posedge clk)\
if (exp) begin\
$display msg;\
end\
module M ();
`disp(
clk,
!(a[i].b && c[i]),
("xxx(()[]]{}}}", a[i].b, c[i])
); // NOTE: Semi-colon is unnecessary.
endmodule

View File

@ -0,0 +1,6 @@
`define A aaa
module M;
`A#() a0 (.*); // No trailing whitespace.
`A #() a1 (.*); // Trailing 1 space.
`A #() a2 (.*); // Trailing 2 spaces.
endmodule

View File

@ -0,0 +1,16 @@
/* IEEE1800-2017 Clause 22.5.1, page 676
If a one-line comment (that is, a comment specified with the characters //) is
included in the text, then the comment shall not become part of the substituted
text.
*/
// A has no comment
// B has a comment after 1 space
// C has a comment after 3 spaces
`define A 11
`define B 22 // Comment not included in macro, but whitespace before `//` is.
`define C 33 // Comment not included in macro, but whitespace before `//` is.
interface A #(p=`A) (); endinterface
interface B #(p=`B) (); endinterface
interface C #(p=`C) (); endinterface

View File

@ -0,0 +1,13 @@
// Multi-line macro defined with 2 trailing spaces before initial continuation.
// First line has no trailing space, second has trailing space, third is end.
// Macro contains 2-space indent, so indented usage gets extra.
// Delimiters (``) used before and after arguments.
`define connect(NAME, INDEX = 0) \
assign NAME``_``INDEX``__x = NAME[INDEX].x;\
assign NAME``_``INDEX``__y = NAME[INDEX].y; \
assign NAME``_``INDEX``__z = NAME[INDEX].z;
module M ();
`connect(a)
`connect(a, 1)
endmodule

View File

@ -0,0 +1,10 @@
`define A "aaa"
`define \B "bbb"
module M;
initial begin
$display(`A);
$display(`\A );
$display(`B);
$display(`\B );
end
endmodule

View File

@ -0,0 +1,16 @@
// Leading whitespace on 4 lines.
// initial \ Space before line continuation.
// begin\ No space before line continuation.
// $display(); // comment \ Continuation at end of comment.
// end
// NOTE: Trailing whitespace on lines ending `initial ` and `$display(); `.
`define A \
initial \
begin\
$display(); // comment \
end
module M;
`A
endmodule

View File

@ -0,0 +1,46 @@
// IEEE1800-2017 Clause 22.11
// The `pragma directive is a structured specification that alters
// interpretation of the SystemVerilog source. The specification introduced by
// this directive is referred to as a pragma. The effect of pragmas other than
// those specified in this standard is implementation-specific.
`pragma foo
`pragma foo bar
`pragma foo bar,baz
`pragma foo bar, baz
// The reset and resetall pragmas shall restore the default values and state of
// pragma_keywords associated with the affected pragmas. These default values
// shall be the values that the tool defines before any SystemVerilog text has
// been processed. The reset pragma shall reset the state for all pragma_names
// that appear as pragma_keywords in the directive. The resetall pragma shall
// reset the state of all pragma_names recognized by the implementation.
`pragma reset bar
`pragma reset bar,baz
`pragma reset bar, baz
// Protected envelopes specify a region of text that shall be transformed prior
// to analysis by the source language processor. These regions of text are
// structured to provide the source language processor with the specification
// of the cryptographic algorithm, key, envelope attributes, and textual design
// data.
// The following example shows the use of the protect pragma to specify
// encryption of design data. The encryption method is a simple substitution
// cipher where each alphabetic character is replaced with the 13th character
// in alphabetic sequence, commonly referred to as "rot13." Nonalphabetic
// characters are not substituted. The following design data contain an
// encryption envelope that specifies the desired protection.
module secret (a, b);
input a;
output b;
`pragma protect encoding=(enctype="raw")
`pragma protect data_method="x-caesar", data_keyname="rot13", begin
`pragma protect runtime_license=(library="lic.so",feature="runSecret",entry="chk", match=42)
logic b;
initial begin
b = 0;
end
always begin
#5 b = a;
end
`pragma protect end
endmodule
// This file should be emitted from the preprocessor unchanged.

View File

@ -0,0 +1,16 @@
// IEEE1800-2017 Clause 22.3
// When `resetall compiler directive is encountered during compilation, all
// compiler directives are set to the default values. This is useful for
// ensuring that only directives that are desired in compiling a particular
// source file are active.
// The recommended usage is to place `resetall at the beginning of each source
// text file, followed immediately by the directives desired in the file.
// It shall be illegal for the `resetall directive to be specified within
// a design element.
// Not all compiler directives have a default value (e.g., `define and
// `include). Directives that do not have a default are not affected by
// `resetall.
`resetall // Comment
`resetall// Comment
`resetall
// This file should be emitted from the preprocessor unchanged.

View File

@ -1,2 +0,0 @@
module and_op (a, b, c);
`include "test2.svh" endmodule

View File

@ -1,6 +0,0 @@
module a;
initial begin
if (`__LINE__ == 0) begin
end
end
endmodule

View File

@ -1,3 +0,0 @@
`define NAME 42 // Comment
interface foo #(WIDTH = `NAME) ();
endinterface

View File

@ -1,4 +0,0 @@
`define MOD_INST u_mysubmod
module mymod;
mysubmod `MOD_INST ();
endmodule

View File

@ -1,10 +0,0 @@
module a;
`define HELLO0 "HELLO"
`define \HELLO1 "HELLO"
initial begin
$display(`HELLO0);
$display(`\HELLO0 );
$display(`HELLO1);
$display(`\HELLO1 );
end
endmodule

View File

@ -1,9 +0,0 @@
`define A \
initial begin // comment \
end
module test();
`A
endmodule

View File

@ -1,17 +0,0 @@
//top
`resetall
`timescale 10 us / 100 ns
`default_nettype wire
//first
`default_nettype none//middle
//last
`unconnected_drive pull0
`unconnected_drive pull1
`nounconnected_drive
`celldefine
`endcelldefine
`pragma foo
`pragma foo bar
`line 5 "foo" 0
`begin_keywords "1800-2017"
`end_keywords

View File

@ -1,10 +0,0 @@
`define connect(NAME, INDEX = 0) \
assign NAME``_``INDEX``__x = NAME[INDEX].x; \
assign NAME``_``INDEX``__y = NAME[INDEX].y;
module a ();
`connect(a)
`connect(a, 1)
endmodule

View File

@ -1,16 +0,0 @@
`define disp(clk, exp, msg) \
always @(posedge clk) begin \
if (!(exp)) begin \
$display msg; \
end \
end \
module a ();
`disp(
clk,
!(a[i].b && c[i]),
("xxx(()[]]{}}}", a[i].b, c[i])
);
endmodule

View File

@ -1,10 +0,0 @@
module a;
`define HI Hello
`define LO "`HI, world"
`define H(x) "Hello, x"
initial begin
$display("`HI, world");
$display(`LO);
$display(`H(world));
end
endmodule

View File

@ -1,3 +0,0 @@
module and_op (a, b, c);
`include "test2.svh" `include "test2.svh"
endmodule

View File

@ -0,0 +1,17 @@
// IEEE1800-2017 Clause 22.7
// This directive specifies the time unit and time precision of the design
// elements that follow it. The time unit is the unit of measurement for time
// values such as the simulation time and delay values.
// The `timescale compiler directive specifies the default unit of measurement
// for time and delay values and the degree of accuracy for delays in all
// design elements that follow this directive, and that do not have timeunit
// and timeprecision constructs specified within the design element, until
// another `timescale compiler directive is read.
// The integers in these arguments specify an order of magnitude for the size
// of the value; the valid integers are 1, 10, and 100.
// The character strings represent units of measurement; the valid character
// strings are s, ms, us, ns, ps, and fs.
`timescale 1 s / 10 ms
`timescale 10 us / 100 ns
`timescale 100 ps / 100 fs
// This file should be emitted from the preprocessor unchanged.

View File

@ -0,0 +1,13 @@
// IEEE1800-2017 Clause 22.9
// The directive `unconnected_drive takes one of two arguments - pull1 or
// pull 0. When pull1 is specified, unconnected ports are pulled down. It is
// advisable to pair each `unconnected_drive with a
// `nounconnected_drive, but it is not required. The latest occurrence of
// either directive in the source controls what happens to unconnected ports.
// These directives shall be specified outside the design element declarations.
// The `resetall directive includes the effects of a `nounconnected
// directive.
`unconnected_drive pull0
`unconnected_drive pull1
`nounconnected_drive
// This file should be emitted from the preprocessor unchanged.

View File

@ -0,0 +1,28 @@
// IEEE1800-2017 Clause 22.5.2
// The directive `undef shall undefine the specified text macro if previously
// defined by a `define compiler directive within the compilation unit. An
// attempt to undefine a text macro that was not previously defined using a
// `define compiler directive can issue a warning.
`undef FOO
`undef FOO// Comment
`undef FOO // Comment
`define FOO foo
`ifdef FOO
// AAA
// This block SHOULD be emitted from the preprocessor.
`endif
`ifndef FOO
// AAA
// This block should NOT be emitted from the preprocessor.
`endif
`undef FOO
`ifdef FOO
// BBB
// This block should NOT be emitted from the preprocessor.
`endif
`ifndef FOO
// BBB
// This block SHOULD be emitted from the preprocessor.
`endif

View File

@ -0,0 +1,45 @@
// IEEE1800-2017 Clause 22.5.3
// The directive `undefineall directive shall undefine all text macros
// previously defined by `define compiler directives within the compilation
// unit. This directive takes no argument and may appear anywhere in the source
// description.
`undefineall
`undefineall// Comment
`undefineall // Comment
`define FOO foo
`define BAR bar
`ifdef FOO
// AAA
// This block SHOULD be emitted from the preprocessor.
`endif
`ifndef FOO
// AAA
// This block should NOT be emitted from the preprocessor.
`endif
`ifdef BAR
// BBB
// This block SHOULD be emitted from the preprocessor.
`endif
`ifndef BAR
// BBB
// This block should NOT be emitted from the preprocessor.
`endif
`undefineall
`ifdef FOO
// CCC
// This block should NOT be emitted from the preprocessor.
`endif
`ifndef FOO
// CCC
// This block SHOULD be emitted from the preprocessor.
`endif
`ifdef BAR
// DDD
// This block should NOT be emitted from the preprocessor.
`endif
`ifndef BAR
// DDD
// This block SHOULD be emitted from the preprocessor.
`endif

View File

@ -62,7 +62,13 @@ fn main() {
let mut exit = 0; let mut exit = 0;
for path in &opt.files { for path in &opt.files {
if opt.pp { if opt.pp {
match preprocess(&path, &defines, &opt.includes, false, false) { match preprocess(
&path,
&defines,
&opt.includes,
false, // strip_comments
false, // ignore_include
) {
Ok((preprocessed_text, new_defines)) => { Ok((preprocessed_text, new_defines)) => {
println!("{}", preprocessed_text.text()); println!("{}", preprocessed_text.text());
defines = new_defines; defines = new_defines;

View File

@ -131,7 +131,13 @@ pub fn parse_sv<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
ignore_include: bool, ignore_include: bool,
allow_incomplete: bool, allow_incomplete: bool,
) -> Result<(SyntaxTree, Defines), Error> { ) -> Result<(SyntaxTree, Defines), Error> {
let (text, defines) = preprocess(path, pre_defines, include_paths, false, ignore_include)?; let (text, defines) = preprocess(
path,
pre_defines,
include_paths,
false, // strip_comments
ignore_include,
)?;
parse_sv_pp(text, defines, allow_incomplete) parse_sv_pp(text, defines, allow_incomplete)
} }
@ -188,8 +194,9 @@ pub fn parse_sv_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
pre_defines, pre_defines,
include_paths, include_paths,
ignore_include, ignore_include,
false, false, // strip_comments
0, 0, // resolve_depth
0, // include_depth
)?; )?;
parse_sv_pp(text, defines, allow_incomplete) parse_sv_pp(text, defines, allow_incomplete)
} }
@ -201,7 +208,13 @@ pub fn parse_lib<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
ignore_include: bool, ignore_include: bool,
allow_incomplete: bool, allow_incomplete: bool,
) -> Result<(SyntaxTree, Defines), Error> { ) -> Result<(SyntaxTree, Defines), Error> {
let (text, defines) = preprocess(path, pre_defines, include_paths, false, ignore_include)?; let (text, defines) = preprocess(
path,
pre_defines,
include_paths,
false, // strip_comments
ignore_include,
)?;
parse_lib_pp(text, defines, allow_incomplete) parse_lib_pp(text, defines, allow_incomplete)
} }
@ -219,8 +232,9 @@ pub fn parse_lib_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
pre_defines, pre_defines,
include_paths, include_paths,
ignore_include, ignore_include,
false, false, // strip_comments
0, 0, // resolve_depth
0, // include_depth
)?; )?;
parse_lib_pp(text, defines, allow_incomplete) parse_lib_pp(text, defines, allow_incomplete)
} }