diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index da5afeb57..be9be73ff 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -16,7 +16,7 @@ ci:
autoupdate_commit_msg: "chore: update pre-commit hooks"
autofix_commit_msg: "style: pre-commit fixes"
-exclude: grammar.md
+exclude: '^grammar(_sdf)?.md$'
repos:
# Standard hooks
diff --git a/bindings/python/CompBindings.cpp b/bindings/python/CompBindings.cpp
index e4160d460..b5d09cad1 100644
--- a/bindings/python/CompBindings.cpp
+++ b/bindings/python/CompBindings.cpp
@@ -209,6 +209,7 @@ void registerCompilation(py::module_& m) {
.def("addSearchExtension", &SourceLoader::addSearchExtension, "extension"_a)
.def("addLibraryMaps", &SourceLoader::addLibraryMaps, "pattern"_a, "basePath"_a,
"optionBag"_a)
+ .def("addSDFFiles", &SourceLoader::addSDFFiles, "pattern"_a, "basePath"_a, "optionBag"_a)
.def("addSeparateUnit", &SourceLoader::addSeparateUnit, "filePatterns"_a, "includePaths"_a,
"defines"_a, "libraryName"_a)
.def("loadSources", &SourceLoader::loadSources)
diff --git a/docs/grammar.md b/docs/grammar.md
index 0f5572c13..06633a0e2 100644
--- a/docs/grammar.md
+++ b/docs/grammar.md
@@ -1,1977 +1,1977 @@
# SystemVerilog
## A.1 Source text
### A.1.1 Library source text
-library\_text ::= \{ [library_description](#library_description) }
-library\_description ::=
- [library_declaration](#library_declaration)
- \| [include_statement](#include_statement)
- \| [config_declaration](#config_declaration)
- \| `;`
-library\_declaration ::=
- [library](#library) [library_identifier](#library_identifier) [file_path_spec](#file_path_spec) \{ `,` [file_path_spec](#file_path_spec) }
- \[ `-`[incdir](#incdir) [file_path_spec](#file_path_spec) \{ `,` [file_path_spec](#file_path_spec) } ] `;`
-include\_statement ::= [include](#include) [file_path_spec](#file_path_spec) `;`
+library\_text ::= \{ [library_description](#library_description) }
+library\_description ::=
+ [library_declaration](#library_declaration)
+ \| [include_statement](#include_statement)
+ \| [config_declaration](#config_declaration)
+ \| `;`
+library\_declaration ::=
+ [library](#library) [library_identifier](#library_identifier) [file_path_spec](#file_path_spec) \{ `,` [file_path_spec](#file_path_spec) }
+ \[ `-`[incdir](#incdir) [file_path_spec](#file_path_spec) \{ `,` [file_path_spec](#file_path_spec) } ] `;`
+include\_statement ::= [include](#include) [file_path_spec](#file_path_spec) `;`
### A.1.2 SystemVerilog source text
-source\_text ::= \[ [timeunits_declaration](#timeunits_declaration) ] \{ [description](#description) }
-description ::=
- [module_declaration](#module_declaration)
- \| [udp_declaration](#udp_declaration)
- \| [interface_declaration](#interface_declaration)
- \| [program_declaration](#program_declaration)
- \| [package_declaration](#package_declaration)
- \| \{ [attribute_instance](#attribute_instance) } [package_item](#package_item)
- \| \{ [attribute_instance](#attribute_instance) } [bind_directive](#bind_directive)
- \| [config_declaration](#config_declaration)
-module\_nonansi\_header ::=
- \{ [attribute_instance](#attribute_instance) } [module_keyword](#module_keyword) \[ [lifetime](#lifetime) ] [module_identifier](#module_identifier)
- \{ [package_import_declaration](#package_import_declaration) } \[ [parameter_port_list](#parameter_port_list) ] [list_of_ports](#list_of_ports) `;`
-module\_ansi\_header ::=
- \{ [attribute_instance](#attribute_instance) } [module_keyword](#module_keyword) \[ [lifetime](#lifetime) ] [module_identifier](#module_identifier)
- \{ [package_import_declaration](#package_import_declaration) }[1](#1) \[ [parameter_port_list](#parameter_port_list) ] \[ [list_of_port_declarations](#list_of_port_declarations) ] `;`
-module\_declaration ::=
- [module_nonansi_header](#module_nonansi_header)
- \[ [timeunits_declaration](#timeunits_declaration) ] \{ [module_item](#module_item) }
- [endmodule](#endmodule) \[ `:` [module_identifier](#module_identifier) ]
- \| [module_ansi_header](#module_ansi_header)
- \[ [timeunits_declaration](#timeunits_declaration) ] \{ [non_port_module_item](#non_port_module_item) }
- [endmodule](#endmodule) \[ `:` [module_identifier](#module_identifier) ]
- \| \{ [attribute_instance](#attribute_instance) } [module_keyword](#module_keyword) \[ [lifetime](#lifetime) ] [module_identifier](#module_identifier) `(` `.` `*` `)` `;`
- \[ [timeunits_declaration](#timeunits_declaration) ] \{ [module_item](#module_item) }
- [endmodule](#endmodule) \[ `:` [module_identifier](#module_identifier) ]
- \| [extern](#extern) [module_nonansi_header](#module_nonansi_header)
- \| [extern](#extern) [module_ansi_header](#module_ansi_header)
-module\_keyword ::= [module](#module) \| [macromodule](#macromodule)
-interface\_declaration ::=
- [interface_nonansi_header](#interface_nonansi_header)
- \[ [timeunits_declaration](#timeunits_declaration) ] \{ [interface_item](#interface_item) }
- [endinterface](#endinterface) \[ `:` [interface_identifier](#interface_identifier) ]
- \| [interface_ansi_header](#interface_ansi_header)
- \[ [timeunits_declaration](#timeunits_declaration) ] \{ [non_port_interface_item](#non_port_interface_item) }
- [endinterface](#endinterface) \[ `:` [interface_identifier](#interface_identifier) ]
- \| \{ [attribute_instance](#attribute_instance) } [interface](#interface) [interface_identifier](#interface_identifier) `(` `.` `*` `)` `;`
- \[ [timeunits_declaration](#timeunits_declaration) ] \{ [interface_item](#interface_item) }
- [endinterface](#endinterface) \[ `:` [interface_identifier](#interface_identifier) ]
- \| [extern](#extern) [interface_nonansi_header](#interface_nonansi_header)
- \| [extern](#extern) [interface_ansi_header](#interface_ansi_header)
-interface\_nonansi\_header ::=
- \{ [attribute_instance](#attribute_instance) } [interface](#interface) \[ [lifetime](#lifetime) ] [interface_identifier](#interface_identifier)
- \{ [package_import_declaration](#package_import_declaration) } \[ [parameter_port_list](#parameter_port_list) ] [list_of_ports](#list_of_ports) `;`
-interface\_ansi\_header ::=
- \{ [attribute_instance](#attribute_instance) } [interface](#interface) \[ [lifetime](#lifetime) ] [interface_identifier](#interface_identifier)
- \{ [package_import_declaration](#package_import_declaration) }[1](#1) \[ [parameter_port_list](#parameter_port_list) ] \[ [list_of_port_declarations](#list_of_port_declarations) ] `;`
-program\_declaration ::=
- [program_nonansi_header](#program_nonansi_header)
- \[ [timeunits_declaration](#timeunits_declaration) ] \{ [program_item](#program_item) }
- [endprogram](#endprogram) \[ `:` [program_identifier](#program_identifier) ]
- \| [program_ansi_header](#program_ansi_header)
- \[ [timeunits_declaration](#timeunits_declaration) ] \{ [non_port_program_item](#non_port_program_item) }
- [endprogram](#endprogram) \[ `:` [program_identifier](#program_identifier) ]
- \| \{ [attribute_instance](#attribute_instance) } [program](#program) [program_identifier](#program_identifier) `(` `.` `*` `)` `;`
- \[ [timeunits_declaration](#timeunits_declaration) ] \{ [program_item](#program_item) }
- [endprogram](#endprogram) \[ `:` [program_identifier](#program_identifier) ]
- \| [extern](#extern) [program_nonansi_header](#program_nonansi_header)
- \| [extern](#extern) [program_ansi_header](#program_ansi_header)
-program\_nonansi\_header ::=
- \{ [attribute_instance](#attribute_instance) } [program](#program) \[ [lifetime](#lifetime) ] [program_identifier](#program_identifier)
- \{ [package_import_declaration](#package_import_declaration) } \[ [parameter_port_list](#parameter_port_list) ] [list_of_ports](#list_of_ports) `;`
-program\_ansi\_header ::=
- \{ [attribute_instance](#attribute_instance) } [program](#program) \[ [lifetime](#lifetime) ] [program_identifier](#program_identifier)
- \{ [package_import_declaration](#package_import_declaration) }[1](#1) \[ [parameter_port_list](#parameter_port_list) ] \[ [list_of_port_declarations](#list_of_port_declarations) ] `;`
-checker\_declaration ::=
- [checker](#checker) [checker_identifier](#checker_identifier) \[ `(` \[ [checker_port_list](#checker_port_list) ] `)` ] `;`
- \{ \{ [attribute_instance](#attribute_instance) } [checker_or_generate_item](#checker_or_generate_item) }
- [endchecker](#endchecker) \[ `:` [checker_identifier](#checker_identifier) ]
-class\_declaration ::=
- \[ [virtual](#virtual) ] [class](#class) \[ [final_specifier](#final_specifier) ] [class_identifier](#class_identifier) \[ [parameter_port_list](#parameter_port_list) ]
- \[ [extends](#extends) [class_type](#class_type) \[ `(` \[ [list_of_arguments](#list_of_arguments) \| [default](#default) ] `)` ] ]
- \[ [implements](#implements) [interface_class_type](#interface_class_type) \{ `,` [interface_class_type](#interface_class_type) } ] `;`
- \{ [class_item](#class_item) }
- [endclass](#endclass) \[ `:` [class_identifier](#class_identifier) ]
-interface\_class\_declaration ::=
- [interface](#interface) [class](#class) [class_identifier](#class_identifier) \[ [parameter_port_list](#parameter_port_list) ]
- \[ [extends](#extends) [interface_class_type](#interface_class_type) \{ `,` [interface_class_type](#interface_class_type) } ] `;`
- \{ [interface_class_item](#interface_class_item) }
- [endclass](#endclass) \[ `:` [class_identifier](#class_identifier) ]
-package\_declaration ::=
- \{ [attribute_instance](#attribute_instance) } [package](#package) \[ [lifetime](#lifetime) ] [package_identifier](#package_identifier) `;`
- \[ [timeunits_declaration](#timeunits_declaration) ] \{ \{ [attribute_instance](#attribute_instance) } [package_item](#package_item) }
- [endpackage](#endpackage) \[ `:` [package_identifier](#package_identifier) ]
-timeunits\_declaration ::=
- [timeunit](#timeunit) [time_literal](#time_literal) \[ `/` [time_literal](#time_literal) ] `;`
- \| [timeprecision](#timeprecision) [time_literal](#time_literal) `;`
- \| [timeunit](#timeunit) [time_literal](#time_literal) `;` [timeprecision](#timeprecision) [time_literal](#time_literal) `;`
- \| [timeprecision](#timeprecision) [time_literal](#time_literal) `;` [timeunit](#timeunit) [time_literal](#time_literal) `;`
+source\_text ::= \[ [timeunits_declaration](#timeunits_declaration) ] \{ [description](#description) }
+description ::=
+ [module_declaration](#module_declaration)
+ \| [udp_declaration](#udp_declaration)
+ \| [interface_declaration](#interface_declaration)
+ \| [program_declaration](#program_declaration)
+ \| [package_declaration](#package_declaration)
+ \| \{ [attribute_instance](#attribute_instance) } [package_item](#package_item)
+ \| \{ [attribute_instance](#attribute_instance) } [bind_directive](#bind_directive)
+ \| [config_declaration](#config_declaration)
+module\_nonansi\_header ::=
+ \{ [attribute_instance](#attribute_instance) } [module_keyword](#module_keyword) \[ [lifetime](#lifetime) ] [module_identifier](#module_identifier)
+ \{ [package_import_declaration](#package_import_declaration) } \[ [parameter_port_list](#parameter_port_list) ] [list_of_ports](#list_of_ports) `;`
+module\_ansi\_header ::=
+ \{ [attribute_instance](#attribute_instance) } [module_keyword](#module_keyword) \[ [lifetime](#lifetime) ] [module_identifier](#module_identifier)
+ \{ [package_import_declaration](#package_import_declaration) }[1](#1) \[ [parameter_port_list](#parameter_port_list) ] \[ [list_of_port_declarations](#list_of_port_declarations) ] `;`
+module\_declaration ::=
+ [module_nonansi_header](#module_nonansi_header)
+ \[ [timeunits_declaration](#timeunits_declaration) ] \{ [module_item](#module_item) }
+ [endmodule](#endmodule) \[ `:` [module_identifier](#module_identifier) ]
+ \| [module_ansi_header](#module_ansi_header)
+ \[ [timeunits_declaration](#timeunits_declaration) ] \{ [non_port_module_item](#non_port_module_item) }
+ [endmodule](#endmodule) \[ `:` [module_identifier](#module_identifier) ]
+ \| \{ [attribute_instance](#attribute_instance) } [module_keyword](#module_keyword) \[ [lifetime](#lifetime) ] [module_identifier](#module_identifier) `(` `.` `*` `)` `;`
+ \[ [timeunits_declaration](#timeunits_declaration) ] \{ [module_item](#module_item) }
+ [endmodule](#endmodule) \[ `:` [module_identifier](#module_identifier) ]
+ \| [extern](#extern) [module_nonansi_header](#module_nonansi_header)
+ \| [extern](#extern) [module_ansi_header](#module_ansi_header)
+module\_keyword ::= [module](#module) \| [macromodule](#macromodule)
+interface\_declaration ::=
+ [interface_nonansi_header](#interface_nonansi_header)
+ \[ [timeunits_declaration](#timeunits_declaration) ] \{ [interface_item](#interface_item) }
+ [endinterface](#endinterface) \[ `:` [interface_identifier](#interface_identifier) ]
+ \| [interface_ansi_header](#interface_ansi_header)
+ \[ [timeunits_declaration](#timeunits_declaration) ] \{ [non_port_interface_item](#non_port_interface_item) }
+ [endinterface](#endinterface) \[ `:` [interface_identifier](#interface_identifier) ]
+ \| \{ [attribute_instance](#attribute_instance) } [interface](#interface) [interface_identifier](#interface_identifier) `(` `.` `*` `)` `;`
+ \[ [timeunits_declaration](#timeunits_declaration) ] \{ [interface_item](#interface_item) }
+ [endinterface](#endinterface) \[ `:` [interface_identifier](#interface_identifier) ]
+ \| [extern](#extern) [interface_nonansi_header](#interface_nonansi_header)
+ \| [extern](#extern) [interface_ansi_header](#interface_ansi_header)
+interface\_nonansi\_header ::=
+ \{ [attribute_instance](#attribute_instance) } [interface](#interface) \[ [lifetime](#lifetime) ] [interface_identifier](#interface_identifier)
+ \{ [package_import_declaration](#package_import_declaration) } \[ [parameter_port_list](#parameter_port_list) ] [list_of_ports](#list_of_ports) `;`
+interface\_ansi\_header ::=
+ \{ [attribute_instance](#attribute_instance) } [interface](#interface) \[ [lifetime](#lifetime) ] [interface_identifier](#interface_identifier)
+ \{ [package_import_declaration](#package_import_declaration) }[1](#1) \[ [parameter_port_list](#parameter_port_list) ] \[ [list_of_port_declarations](#list_of_port_declarations) ] `;`
+program\_declaration ::=
+ [program_nonansi_header](#program_nonansi_header)
+ \[ [timeunits_declaration](#timeunits_declaration) ] \{ [program_item](#program_item) }
+ [endprogram](#endprogram) \[ `:` [program_identifier](#program_identifier) ]
+ \| [program_ansi_header](#program_ansi_header)
+ \[ [timeunits_declaration](#timeunits_declaration) ] \{ [non_port_program_item](#non_port_program_item) }
+ [endprogram](#endprogram) \[ `:` [program_identifier](#program_identifier) ]
+ \| \{ [attribute_instance](#attribute_instance) } [program](#program) [program_identifier](#program_identifier) `(` `.` `*` `)` `;`
+ \[ [timeunits_declaration](#timeunits_declaration) ] \{ [program_item](#program_item) }
+ [endprogram](#endprogram) \[ `:` [program_identifier](#program_identifier) ]
+ \| [extern](#extern) [program_nonansi_header](#program_nonansi_header)
+ \| [extern](#extern) [program_ansi_header](#program_ansi_header)
+program\_nonansi\_header ::=
+ \{ [attribute_instance](#attribute_instance) } [program](#program) \[ [lifetime](#lifetime) ] [program_identifier](#program_identifier)
+ \{ [package_import_declaration](#package_import_declaration) } \[ [parameter_port_list](#parameter_port_list) ] [list_of_ports](#list_of_ports) `;`
+program\_ansi\_header ::=
+ \{ [attribute_instance](#attribute_instance) } [program](#program) \[ [lifetime](#lifetime) ] [program_identifier](#program_identifier)
+ \{ [package_import_declaration](#package_import_declaration) }[1](#1) \[ [parameter_port_list](#parameter_port_list) ] \[ [list_of_port_declarations](#list_of_port_declarations) ] `;`
+checker\_declaration ::=
+ [checker](#checker) [checker_identifier](#checker_identifier) \[ `(` \[ [checker_port_list](#checker_port_list) ] `)` ] `;`
+ \{ \{ [attribute_instance](#attribute_instance) } [checker_or_generate_item](#checker_or_generate_item) }
+ [endchecker](#endchecker) \[ `:` [checker_identifier](#checker_identifier) ]
+class\_declaration ::=
+ \[ [virtual](#virtual) ] [class](#class) \[ [final_specifier](#final_specifier) ] [class_identifier](#class_identifier) \[ [parameter_port_list](#parameter_port_list) ]
+ \[ [extends](#extends) [class_type](#class_type) \[ `(` \[ [list_of_arguments](#list_of_arguments) \| [default](#default) ] `)` ] ]
+ \[ [implements](#implements) [interface_class_type](#interface_class_type) \{ `,` [interface_class_type](#interface_class_type) } ] `;`
+ \{ [class_item](#class_item) }
+ [endclass](#endclass) \[ `:` [class_identifier](#class_identifier) ]
+interface\_class\_declaration ::=
+ [interface](#interface) [class](#class) [class_identifier](#class_identifier) \[ [parameter_port_list](#parameter_port_list) ]
+ \[ [extends](#extends) [interface_class_type](#interface_class_type) \{ `,` [interface_class_type](#interface_class_type) } ] `;`
+ \{ [interface_class_item](#interface_class_item) }
+ [endclass](#endclass) \[ `:` [class_identifier](#class_identifier) ]
+package\_declaration ::=
+ \{ [attribute_instance](#attribute_instance) } [package](#package) \[ [lifetime](#lifetime) ] [package_identifier](#package_identifier) `;`
+ \[ [timeunits_declaration](#timeunits_declaration) ] \{ \{ [attribute_instance](#attribute_instance) } [package_item](#package_item) }
+ [endpackage](#endpackage) \[ `:` [package_identifier](#package_identifier) ]
+timeunits\_declaration ::=
+ [timeunit](#timeunit) [time_literal](#time_literal) \[ `/` [time_literal](#time_literal) ] `;`
+ \| [timeprecision](#timeprecision) [time_literal](#time_literal) `;`
+ \| [timeunit](#timeunit) [time_literal](#time_literal) `;` [timeprecision](#timeprecision) [time_literal](#time_literal) `;`
+ \| [timeprecision](#timeprecision) [time_literal](#time_literal) `;` [timeunit](#timeunit) [time_literal](#time_literal) `;`
### A.1.3 Module parameters and ports
-parameter\_port\_list ::=
- `#` `(` [list_of_param_assignments](#list_of_param_assignments) \{ `,` [parameter_port_declaration](#parameter_port_declaration) } `)`
- \| `#` `(` [parameter_port_declaration](#parameter_port_declaration) \{ `,` [parameter_port_declaration](#parameter_port_declaration) } `)`
- \| `#(` `)`
-parameter\_port\_declaration ::=
- [parameter_declaration](#parameter_declaration)
- \| [local_parameter_declaration](#local_parameter_declaration)
- \| [data_type](#data_type) [list_of_param_assignments](#list_of_param_assignments)
- \| [type_parameter_declaration](#type_parameter_declaration)
-list\_of\_ports ::= `(` [port](#port) \{ `,` [port](#port) } `)`
-list\_of\_port\_declarations2 ::=
- `(` \[ \{ [attribute_instance](#attribute_instance) } [ansi_port_declaration](#ansi_port_declaration) \{ `,` \{ [attribute_instance](#attribute_instance) } [ansi_port_declaration](#ansi_port_declaration) } ] `)`
-port\_declaration ::=
- \{ [attribute_instance](#attribute_instance) } [inout_declaration](#inout_declaration)
- \| \{ [attribute_instance](#attribute_instance) } [input_declaration](#input_declaration)
- \| \{ [attribute_instance](#attribute_instance) } [output_declaration](#output_declaration)
- \| \{ [attribute_instance](#attribute_instance) } [ref_declaration](#ref_declaration)
- \| \{ [attribute_instance](#attribute_instance) } [interface_port_declaration](#interface_port_declaration)
-port ::=
- \[ [port_expression](#port_expression) ]
- \| `.` [port_identifier](#port_identifier) `(` \[ [port_expression](#port_expression) ] `)`
-port\_expression ::=
- [port_reference](#port_reference)
- \| \{ [port_reference](#port_reference) \{ `,` [port_reference](#port_reference) } }
-port\_reference ::= [port_identifier](#port_identifier) [constant_select](#constant_select)
-port\_direction ::= [input](#input) \| [output](#output) \| [inout](#inout) \| [ref](#ref)
-net\_port\_header ::= \[ [port_direction](#port_direction) ] [net_port_type](#net_port_type)
-variable\_port\_header ::= \[ [port_direction](#port_direction) ] [variable_port_type](#variable_port_type)
-interface\_port\_header ::=
- [interface_identifier](#interface_identifier) \[ `.` [modport_identifier](#modport_identifier) ]
- \| [interface](#interface) \[ `.` [modport_identifier](#modport_identifier) ]
-ansi\_port\_declaration ::=
- \[ [net_port_header](#net_port_header) \| [interface_port_header](#interface_port_header) ] [port_identifier](#port_identifier) \{ [unpacked_dimension](#unpacked_dimension) }
- \[ `=` [constant_expression](#constant_expression) ]
- \| \[ [variable_port_header](#variable_port_header) ] [port_identifier](#port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [constant_expression](#constant_expression) ]
- \| \[ [port_direction](#port_direction) ] `.` [port_identifier](#port_identifier) `(` \[ [expression](#expression) ] `)`
+parameter\_port\_list ::=
+ `#` `(` [list_of_param_assignments](#list_of_param_assignments) \{ `,` [parameter_port_declaration](#parameter_port_declaration) } `)`
+ \| `#` `(` [parameter_port_declaration](#parameter_port_declaration) \{ `,` [parameter_port_declaration](#parameter_port_declaration) } `)`
+ \| `#(` `)`
+parameter\_port\_declaration ::=
+ [parameter_declaration](#parameter_declaration)
+ \| [local_parameter_declaration](#local_parameter_declaration)
+ \| [data_type](#data_type) [list_of_param_assignments](#list_of_param_assignments)
+ \| [type_parameter_declaration](#type_parameter_declaration)
+list\_of\_ports ::= `(` [port](#port) \{ `,` [port](#port) } `)`
+list\_of\_port\_declarations2 ::=
+ `(` \[ \{ [attribute_instance](#attribute_instance) } [ansi_port_declaration](#ansi_port_declaration) \{ `,` \{ [attribute_instance](#attribute_instance) } [ansi_port_declaration](#ansi_port_declaration) } ] `)`
+port\_declaration ::=
+ \{ [attribute_instance](#attribute_instance) } [inout_declaration](#inout_declaration)
+ \| \{ [attribute_instance](#attribute_instance) } [input_declaration](#input_declaration)
+ \| \{ [attribute_instance](#attribute_instance) } [output_declaration](#output_declaration)
+ \| \{ [attribute_instance](#attribute_instance) } [ref_declaration](#ref_declaration)
+ \| \{ [attribute_instance](#attribute_instance) } [interface_port_declaration](#interface_port_declaration)
+port ::=
+ \[ [port_expression](#port_expression) ]
+ \| `.` [port_identifier](#port_identifier) `(` \[ [port_expression](#port_expression) ] `)`
+port\_expression ::=
+ [port_reference](#port_reference)
+ \| \{ [port_reference](#port_reference) \{ `,` [port_reference](#port_reference) } }
+port\_reference ::= [port_identifier](#port_identifier) [constant_select](#constant_select)
+port\_direction ::= [input](#input) \| [output](#output) \| [inout](#inout) \| [ref](#ref)
+net\_port\_header ::= \[ [port_direction](#port_direction) ] [net_port_type](#net_port_type)
+variable\_port\_header ::= \[ [port_direction](#port_direction) ] [variable_port_type](#variable_port_type)
+interface\_port\_header ::=
+ [interface_identifier](#interface_identifier) \[ `.` [modport_identifier](#modport_identifier) ]
+ \| [interface](#interface) \[ `.` [modport_identifier](#modport_identifier) ]
+ansi\_port\_declaration ::=
+ \[ [net_port_header](#net_port_header) \| [interface_port_header](#interface_port_header) ] [port_identifier](#port_identifier) \{ [unpacked_dimension](#unpacked_dimension) }
+ \[ `=` [constant_expression](#constant_expression) ]
+ \| \[ [variable_port_header](#variable_port_header) ] [port_identifier](#port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [constant_expression](#constant_expression) ]
+ \| \[ [port_direction](#port_direction) ] `.` [port_identifier](#port_identifier) `(` \[ [expression](#expression) ] `)`
### A.1.4 Module items
-severity\_system\_task ::=
- `$`[fatal](#fatal) \[ `(` [finish_number](#finish_number) `[,` [list_of_arguments](#list_of_arguments) ] `)` ] `;`
- \| `$`[error](#error) \[ `(` \[ [list_of_arguments](#list_of_arguments) ] `)` ] `;`
- \| `$`[warning](#warning) \[ `(` \[ [list_of_arguments](#list_of_arguments) ] `)` ] `;`
- \| `$`[info](#info) \[ `(` \[ [list_of_arguments](#list_of_arguments) ] `)` ] `;`
-finish\_number ::= [0](#0) \| [1](#1) \| [2](#2)
-elaboration\_severity\_system\_task ::= [severity_system_task](#severity_system_task)
-module\_common\_item ::=
- [module_or_generate_item_declaration](#module_or_generate_item_declaration)
- \| [interface_instantiation](#interface_instantiation)
- \| [program_instantiation](#program_instantiation)
- \| [assertion_item](#assertion_item)
- \| [bind_directive](#bind_directive)
- \| [continuous_assign](#continuous_assign)
- \| [net_alias](#net_alias)
- \| [initial_construct](#initial_construct)
- \| [final_construct](#final_construct)
- \| [always_construct](#always_construct)
- \| [loop_generate_construct](#loop_generate_construct)
- \| [conditional_generate_construct](#conditional_generate_construct)
- \| [elaboration_severity_system_task](#elaboration_severity_system_task)
-module\_item ::=
- [port_declaration](#port_declaration) `;`
- \| [non_port_module_item](#non_port_module_item)
-module\_or\_generate\_item ::=
- \{ [attribute_instance](#attribute_instance) } [parameter_override](#parameter_override)
- \| \{ [attribute_instance](#attribute_instance) } [gate_instantiation](#gate_instantiation)
- \| \{ [attribute_instance](#attribute_instance) } [udp_instantiation](#udp_instantiation)
- \| \{ [attribute_instance](#attribute_instance) } [module_instantiation](#module_instantiation)
- \| \{ [attribute_instance](#attribute_instance) } [module_common_item](#module_common_item)
-module\_or\_generate\_item\_declaration ::=
- [package_or_generate_item_declaration](#package_or_generate_item_declaration)
- \| [genvar_declaration](#genvar_declaration)
- \| [clocking_declaration](#clocking_declaration)
- \| [default](#default) [clocking](#clocking) [clocking_identifier](#clocking_identifier) `;`
- \| [default](#default) [disable](#disable) [iff](#iff) [expression_or_dist](#expression_or_dist) `;`
-non\_port\_module\_item ::=
- [generate_region](#generate_region)
- \| [module_or_generate_item](#module_or_generate_item)
- \| [specify_block](#specify_block)
- \| \{ [attribute_instance](#attribute_instance) } [specparam_declaration](#specparam_declaration)
- \| [program_declaration](#program_declaration)
- \| [module_declaration](#module_declaration)
- \| [interface_declaration](#interface_declaration)
- \| [timeunits_declaration3](#timeunits_declaration3)
-parameter\_override ::= [defparam](#defparam) [list_of_defparam_assignments](#list_of_defparam_assignments) `;`
-bind\_directive4 ::=
- [bind](#bind) [bind_target_scope](#bind_target_scope) \[ `:` [bind_target_instance_list](#bind_target_instance_list) ] [bind_instantiation](#bind_instantiation) `;`
- \| [bind](#bind) [bind_target_instance](#bind_target_instance) [bind_instantiation](#bind_instantiation) `;`
-bind\_target\_scope ::=
- [module_identifier](#module_identifier)
- \| [interface_identifier](#interface_identifier)
-bind\_target\_instance ::= [hierarchical_identifier](#hierarchical_identifier) [constant_bit_select](#constant_bit_select)
-bind\_target\_instance\_list ::= [bind_target_instance](#bind_target_instance) \{ `,` [bind_target_instance](#bind_target_instance) }
-bind\_instantiation ::=
- [program_instantiation](#program_instantiation)
- \| [module_instantiation](#module_instantiation)
- \| [interface_instantiation](#interface_instantiation)
- \| [checker_instantiation](#checker_instantiation)
+severity\_system\_task ::=
+ `$`[fatal](#fatal) \[ `(` [finish_number](#finish_number) `[,` [list_of_arguments](#list_of_arguments) ] `)` ] `;`
+ \| `$`[error](#error) \[ `(` \[ [list_of_arguments](#list_of_arguments) ] `)` ] `;`
+ \| `$`[warning](#warning) \[ `(` \[ [list_of_arguments](#list_of_arguments) ] `)` ] `;`
+ \| `$`[info](#info) \[ `(` \[ [list_of_arguments](#list_of_arguments) ] `)` ] `;`
+finish\_number ::= [0](#0) \| [1](#1) \| [2](#2)
+elaboration\_severity\_system\_task ::= [severity_system_task](#severity_system_task)
+module\_common\_item ::=
+ [module_or_generate_item_declaration](#module_or_generate_item_declaration)
+ \| [interface_instantiation](#interface_instantiation)
+ \| [program_instantiation](#program_instantiation)
+ \| [assertion_item](#assertion_item)
+ \| [bind_directive](#bind_directive)
+ \| [continuous_assign](#continuous_assign)
+ \| [net_alias](#net_alias)
+ \| [initial_construct](#initial_construct)
+ \| [final_construct](#final_construct)
+ \| [always_construct](#always_construct)
+ \| [loop_generate_construct](#loop_generate_construct)
+ \| [conditional_generate_construct](#conditional_generate_construct)
+ \| [elaboration_severity_system_task](#elaboration_severity_system_task)
+module\_item ::=
+ [port_declaration](#port_declaration) `;`
+ \| [non_port_module_item](#non_port_module_item)
+module\_or\_generate\_item ::=
+ \{ [attribute_instance](#attribute_instance) } [parameter_override](#parameter_override)
+ \| \{ [attribute_instance](#attribute_instance) } [gate_instantiation](#gate_instantiation)
+ \| \{ [attribute_instance](#attribute_instance) } [udp_instantiation](#udp_instantiation)
+ \| \{ [attribute_instance](#attribute_instance) } [module_instantiation](#module_instantiation)
+ \| \{ [attribute_instance](#attribute_instance) } [module_common_item](#module_common_item)
+module\_or\_generate\_item\_declaration ::=
+ [package_or_generate_item_declaration](#package_or_generate_item_declaration)
+ \| [genvar_declaration](#genvar_declaration)
+ \| [clocking_declaration](#clocking_declaration)
+ \| [default](#default) [clocking](#clocking) [clocking_identifier](#clocking_identifier) `;`
+ \| [default](#default) [disable](#disable) [iff](#iff) [expression_or_dist](#expression_or_dist) `;`
+non\_port\_module\_item ::=
+ [generate_region](#generate_region)
+ \| [module_or_generate_item](#module_or_generate_item)
+ \| [specify_block](#specify_block)
+ \| \{ [attribute_instance](#attribute_instance) } [specparam_declaration](#specparam_declaration)
+ \| [program_declaration](#program_declaration)
+ \| [module_declaration](#module_declaration)
+ \| [interface_declaration](#interface_declaration)
+ \| [timeunits_declaration3](#timeunits_declaration3)
+parameter\_override ::= [defparam](#defparam) [list_of_defparam_assignments](#list_of_defparam_assignments) `;`
+bind\_directive4 ::=
+ [bind](#bind) [bind_target_scope](#bind_target_scope) \[ `:` [bind_target_instance_list](#bind_target_instance_list) ] [bind_instantiation](#bind_instantiation) `;`
+ \| [bind](#bind) [bind_target_instance](#bind_target_instance) [bind_instantiation](#bind_instantiation) `;`
+bind\_target\_scope ::=
+ [module_identifier](#module_identifier)
+ \| [interface_identifier](#interface_identifier)
+bind\_target\_instance ::= [hierarchical_identifier](#hierarchical_identifier) [constant_bit_select](#constant_bit_select)
+bind\_target\_instance\_list ::= [bind_target_instance](#bind_target_instance) \{ `,` [bind_target_instance](#bind_target_instance) }
+bind\_instantiation ::=
+ [program_instantiation](#program_instantiation)
+ \| [module_instantiation](#module_instantiation)
+ \| [interface_instantiation](#interface_instantiation)
+ \| [checker_instantiation](#checker_instantiation)
### A.1.5 Configuration source text
-config\_declaration ::=
- [config](#config) [config_identifier](#config_identifier) `;`
- \{ [local_parameter_declaration](#local_parameter_declaration) `;` }
- [design_statement](#design_statement)
- \{ [config_rule_statement](#config_rule_statement) }
- [endconfig](#endconfig) \[ `:` [config_identifier](#config_identifier) ]
-design\_statement ::= [design](#design) \{ \[ [library_identifier](#library_identifier) `.` ] [cell_identifier](#cell_identifier) } `;`
-config\_rule\_statement ::=
- [default_clause](#default_clause) [liblist_clause](#liblist_clause) `;`
- \| [inst_clause](#inst_clause) [liblist_clause](#liblist_clause) `;`
- \| [inst_clause](#inst_clause) [use_clause](#use_clause) `;`
- \| [cell_clause](#cell_clause) [liblist_clause](#liblist_clause) `;`
- \| [cell_clause](#cell_clause) [use_clause](#use_clause) `;`
-default\_clause ::= [default](#default)
-inst\_clause ::= [instance](#instance) [inst_name](#inst_name)
-inst\_name ::= [topmodule_identifier](#topmodule_identifier) \{ `.` [instance_identifier](#instance_identifier) }
-cell\_clause ::= [cell](#cell) \[ [library_identifier](#library_identifier) `.` ] [cell_identifier](#cell_identifier)
-liblist\_clause ::= [liblist](#liblist) \{ [library_identifier](#library_identifier) }
-use\_clause ::=
- [use](#use) \[ [library_identifier](#library_identifier) `.` ] [cell_identifier](#cell_identifier) \[ `:` [config](#config) ]
- \| [use](#use) [named_parameter_assignment](#named_parameter_assignment) \{ `,` [named_parameter_assignment](#named_parameter_assignment) } \[ `:` [config](#config) ]
- \| [use](#use) \[ [library_identifier](#library_identifier) `.` ] [cell_identifier](#cell_identifier) [named_parameter_assignment](#named_parameter_assignment)
- \{ `,` [named_parameter_assignment](#named_parameter_assignment) } \[ `:` [config](#config) ]
+config\_declaration ::=
+ [config](#config) [config_identifier](#config_identifier) `;`
+ \{ [local_parameter_declaration](#local_parameter_declaration) `;` }
+ [design_statement](#design_statement)
+ \{ [config_rule_statement](#config_rule_statement) }
+ [endconfig](#endconfig) \[ `:` [config_identifier](#config_identifier) ]
+design\_statement ::= [design](#design) \{ \[ [library_identifier](#library_identifier) `.` ] [cell_identifier](#cell_identifier) } `;`
+config\_rule\_statement ::=
+ [default_clause](#default_clause) [liblist_clause](#liblist_clause) `;`
+ \| [inst_clause](#inst_clause) [liblist_clause](#liblist_clause) `;`
+ \| [inst_clause](#inst_clause) [use_clause](#use_clause) `;`
+ \| [cell_clause](#cell_clause) [liblist_clause](#liblist_clause) `;`
+ \| [cell_clause](#cell_clause) [use_clause](#use_clause) `;`
+default\_clause ::= [default](#default)
+inst\_clause ::= [instance](#instance) [inst_name](#inst_name)
+inst\_name ::= [topmodule_identifier](#topmodule_identifier) \{ `.` [instance_identifier](#instance_identifier) }
+cell\_clause ::= [cell](#cell) \[ [library_identifier](#library_identifier) `.` ] [cell_identifier](#cell_identifier)
+liblist\_clause ::= [liblist](#liblist) \{ [library_identifier](#library_identifier) }
+use\_clause ::=
+ [use](#use) \[ [library_identifier](#library_identifier) `.` ] [cell_identifier](#cell_identifier) \[ `:` [config](#config) ]
+ \| [use](#use) [named_parameter_assignment](#named_parameter_assignment) \{ `,` [named_parameter_assignment](#named_parameter_assignment) } \[ `:` [config](#config) ]
+ \| [use](#use) \[ [library_identifier](#library_identifier) `.` ] [cell_identifier](#cell_identifier) [named_parameter_assignment](#named_parameter_assignment)
+ \{ `,` [named_parameter_assignment](#named_parameter_assignment) } \[ `:` [config](#config) ]
### A.1.6 Interface items
-interface\_or\_generate\_item ::=
- \{ [attribute_instance](#attribute_instance) } [module_common_item](#module_common_item)
- \| \{ [attribute_instance](#attribute_instance) } [extern_tf_declaration](#extern_tf_declaration)
-extern\_tf\_declaration ::=
- [extern](#extern) [method_prototype](#method_prototype) `;`
- \| [extern](#extern) [forkjoin](#forkjoin) [task_prototype](#task_prototype) `;`
-interface\_item ::=
- [port_declaration](#port_declaration) `;`
- \| [non_port_interface_item](#non_port_interface_item)
-non\_port\_interface\_item ::=
- [generate_region](#generate_region)
- \| [interface_or_generate_item](#interface_or_generate_item)
- \| [program_declaration](#program_declaration)
- \| [modport_declaration](#modport_declaration)
- \| [interface_declaration](#interface_declaration)
- \| [timeunits_declaration3](#timeunits_declaration3)
+interface\_or\_generate\_item ::=
+ \{ [attribute_instance](#attribute_instance) } [module_common_item](#module_common_item)
+ \| \{ [attribute_instance](#attribute_instance) } [extern_tf_declaration](#extern_tf_declaration)
+extern\_tf\_declaration ::=
+ [extern](#extern) [method_prototype](#method_prototype) `;`
+ \| [extern](#extern) [forkjoin](#forkjoin) [task_prototype](#task_prototype) `;`
+interface\_item ::=
+ [port_declaration](#port_declaration) `;`
+ \| [non_port_interface_item](#non_port_interface_item)
+non\_port\_interface\_item ::=
+ [generate_region](#generate_region)
+ \| [interface_or_generate_item](#interface_or_generate_item)
+ \| [program_declaration](#program_declaration)
+ \| [modport_declaration](#modport_declaration)
+ \| [interface_declaration](#interface_declaration)
+ \| [timeunits_declaration3](#timeunits_declaration3)
### A.1.7 Program items
-program\_item ::=
- [port_declaration](#port_declaration) `;`
- \| [non_port_program_item](#non_port_program_item)
-non\_port\_program\_item ::=
- \{ [attribute_instance](#attribute_instance) } [continuous_assign](#continuous_assign)
- \| \{ [attribute_instance](#attribute_instance) } [module_or_generate_item_declaration](#module_or_generate_item_declaration)
- \| \{ [attribute_instance](#attribute_instance) } [initial_construct](#initial_construct)
- \| \{ [attribute_instance](#attribute_instance) } [final_construct](#final_construct)
- \| \{ [attribute_instance](#attribute_instance) } [concurrent_assertion_item](#concurrent_assertion_item)
- \| [timeunits_declaration3](#timeunits_declaration3)
- \| [program_generate_item](#program_generate_item)
-program\_generate\_item5 ::=
- [loop_generate_construct](#loop_generate_construct)
- \| [conditional_generate_construct](#conditional_generate_construct)
- \| [generate_region](#generate_region)
- \| [elaboration_severity_system_task](#elaboration_severity_system_task)
+program\_item ::=
+ [port_declaration](#port_declaration) `;`
+ \| [non_port_program_item](#non_port_program_item)
+non\_port\_program\_item ::=
+ \{ [attribute_instance](#attribute_instance) } [continuous_assign](#continuous_assign)
+ \| \{ [attribute_instance](#attribute_instance) } [module_or_generate_item_declaration](#module_or_generate_item_declaration)
+ \| \{ [attribute_instance](#attribute_instance) } [initial_construct](#initial_construct)
+ \| \{ [attribute_instance](#attribute_instance) } [final_construct](#final_construct)
+ \| \{ [attribute_instance](#attribute_instance) } [concurrent_assertion_item](#concurrent_assertion_item)
+ \| [timeunits_declaration3](#timeunits_declaration3)
+ \| [program_generate_item](#program_generate_item)
+program\_generate\_item5 ::=
+ [loop_generate_construct](#loop_generate_construct)
+ \| [conditional_generate_construct](#conditional_generate_construct)
+ \| [generate_region](#generate_region)
+ \| [elaboration_severity_system_task](#elaboration_severity_system_task)
### A.1.8 Checker items
-checker\_port\_list ::= [checker_port_item](#checker_port_item) \{ `,` [checker_port_item](#checker_port_item) }
-checker\_port\_item ::=
- \{ [attribute_instance](#attribute_instance) } \[ [checker_port_direction](#checker_port_direction) ] [property_formal_type](#property_formal_type) [formal_port_identifier](#formal_port_identifier)
- \{ [variable_dimension](#variable_dimension) } \[ `=` [property_actual_arg](#property_actual_arg) ]
-checker\_port\_direction ::= [input](#input) \| [output](#output)
-checker\_or\_generate\_item ::=
- [checker_or_generate_item_declaration](#checker_or_generate_item_declaration)
- \| [initial_construct](#initial_construct)
- \| [always_construct](#always_construct)
- \| [final_construct](#final_construct)
- \| [assertion_item](#assertion_item)
- \| [continuous_assign](#continuous_assign)
- \| [checker_generate_item](#checker_generate_item)
-checker\_or\_generate\_item\_declaration ::=
- \[ [rand](#rand) ] [data_declaration](#data_declaration)
- \| [function_declaration](#function_declaration)
- \| [checker_declaration](#checker_declaration)
- \| [assertion_item_declaration](#assertion_item_declaration)
- \| [covergroup_declaration](#covergroup_declaration)
- \| [genvar_declaration](#genvar_declaration)
- \| [clocking_declaration](#clocking_declaration)
- \| [default](#default) [clocking](#clocking) [clocking_identifier](#clocking_identifier) `;`
- \| [default](#default) [disable](#disable) [iff](#iff) [expression_or_dist](#expression_or_dist) `;`
- \| `;`
-checker\_generate\_item6 ::=
- [loop_generate_construct](#loop_generate_construct)
- \| [conditional_generate_construct](#conditional_generate_construct)
- \| [generate_region](#generate_region)
- \| [elaboration_severity_system_task](#elaboration_severity_system_task)
+checker\_port\_list ::= [checker_port_item](#checker_port_item) \{ `,` [checker_port_item](#checker_port_item) }
+checker\_port\_item ::=
+ \{ [attribute_instance](#attribute_instance) } \[ [checker_port_direction](#checker_port_direction) ] [property_formal_type](#property_formal_type) [formal_port_identifier](#formal_port_identifier)
+ \{ [variable_dimension](#variable_dimension) } \[ `=` [property_actual_arg](#property_actual_arg) ]
+checker\_port\_direction ::= [input](#input) \| [output](#output)
+checker\_or\_generate\_item ::=
+ [checker_or_generate_item_declaration](#checker_or_generate_item_declaration)
+ \| [initial_construct](#initial_construct)
+ \| [always_construct](#always_construct)
+ \| [final_construct](#final_construct)
+ \| [assertion_item](#assertion_item)
+ \| [continuous_assign](#continuous_assign)
+ \| [checker_generate_item](#checker_generate_item)
+checker\_or\_generate\_item\_declaration ::=
+ \[ [rand](#rand) ] [data_declaration](#data_declaration)
+ \| [function_declaration](#function_declaration)
+ \| [checker_declaration](#checker_declaration)
+ \| [assertion_item_declaration](#assertion_item_declaration)
+ \| [covergroup_declaration](#covergroup_declaration)
+ \| [genvar_declaration](#genvar_declaration)
+ \| [clocking_declaration](#clocking_declaration)
+ \| [default](#default) [clocking](#clocking) [clocking_identifier](#clocking_identifier) `;`
+ \| [default](#default) [disable](#disable) [iff](#iff) [expression_or_dist](#expression_or_dist) `;`
+ \| `;`
+checker\_generate\_item6 ::=
+ [loop_generate_construct](#loop_generate_construct)
+ \| [conditional_generate_construct](#conditional_generate_construct)
+ \| [generate_region](#generate_region)
+ \| [elaboration_severity_system_task](#elaboration_severity_system_task)
### A.1.9 Class items
-class\_item ::=
- \{ [attribute_instance](#attribute_instance) } [class_property](#class_property)
- \| \{ [attribute_instance](#attribute_instance) } [class_method](#class_method)
- \| \{ [attribute_instance](#attribute_instance) } [class_constraint](#class_constraint)
- \| \{ [attribute_instance](#attribute_instance) } [class_declaration](#class_declaration)
- \| \{ [attribute_instance](#attribute_instance) } [interface_class_declaration](#interface_class_declaration)
- \| \{ [attribute_instance](#attribute_instance) } [covergroup_declaration](#covergroup_declaration)
- \| [local_parameter_declaration](#local_parameter_declaration) `;`
- \| [parameter_declaration7](#parameter_declaration7) `;`
- \| `;`
-class\_property ::=
- \{ [property_qualifier](#property_qualifier) } [data_declaration](#data_declaration)
- \| [const](#const) \{ [class_item_qualifier](#class_item_qualifier) } [data_type](#data_type) [const_identifier](#const_identifier) \[ `=` [constant_expression](#constant_expression) ] `;`
-class\_method ::=
- \{ [method_qualifier](#method_qualifier) } [task_declaration](#task_declaration)
- \| \{ [method_qualifier](#method_qualifier) } [function_declaration](#function_declaration)
- \| [pure](#pure) [virtual](#virtual) \{ [class_item_qualifier](#class_item_qualifier) } [method_prototype8](#method_prototype8) `;`
- \| [extern](#extern) \{ [method_qualifier](#method_qualifier) } [method_prototype](#method_prototype) `;`
- \| \{ [method_qualifier](#method_qualifier) } [class_constructor_declaration](#class_constructor_declaration)
- \| [extern](#extern) \{ [method_qualifier](#method_qualifier) } [class_constructor_prototype](#class_constructor_prototype)
-class\_constructor\_declaration ::=
- [function](#function) \[ [class_scope](#class_scope) ] [new](#new) \[ `(` \[ [class_constructor_arg_list](#class_constructor_arg_list) ] `)` ] `;`
- \{ [block_item_declaration](#block_item_declaration) }
- \[ [super](#super) `.` [new](#new) \[ `(` \[ [list_of_arguments](#list_of_arguments) \| [default](#default) ] `)` ] `;` ]
- \{ [function_statement_or_null](#function_statement_or_null) }
- [endfunction](#endfunction) \[ `:` [new](#new) ]
-class\_constructor\_prototype ::= [function](#function) [new](#new) \[ `(` \[ [class_constructor_arg_list](#class_constructor_arg_list) ] `)` ] `;`
-class\_constructor\_arg\_list ::= [class_constructor_arg](#class_constructor_arg) \{ `,` [class_constructor_arg](#class_constructor_arg) }[9](#9)
-class\_constructor\_arg ::= [tf_port_item](#tf_port_item) \| [default](#default)
-interface\_class\_item ::=
- [type_declaration](#type_declaration)
- \| \{ [attribute_instance](#attribute_instance) } [interface_class_method](#interface_class_method)
- \| [local_parameter_declaration](#local_parameter_declaration) `;`
- \| [parameter_declaration7](#parameter_declaration7) `;`
- \| `;`
-interface\_class\_method ::= [pure](#pure) [virtual](#virtual) [method_prototype](#method_prototype) `;`
-class\_constraint ::=
- [constraint_prototype](#constraint_prototype)
- \| [constraint_declaration](#constraint_declaration)
-class\_item\_qualifier10 ::= [static](#static) \| [protected](#protected) \| [local](#local)
-property\_qualifier10 ::=
- [random_qualifier](#random_qualifier)
- \| [class_item_qualifier](#class_item_qualifier)
-random\_qualifier10 ::= [rand](#rand) \| [randc](#randc)
-method\_qualifier10 ::=
- \[ [pure](#pure) ] [virtual](#virtual)
- \| [class_item_qualifier](#class_item_qualifier)
-method\_prototype ::=
- [task_prototype](#task_prototype)
- \| [function_prototype](#function_prototype)
+class\_item ::=
+ \{ [attribute_instance](#attribute_instance) } [class_property](#class_property)
+ \| \{ [attribute_instance](#attribute_instance) } [class_method](#class_method)
+ \| \{ [attribute_instance](#attribute_instance) } [class_constraint](#class_constraint)
+ \| \{ [attribute_instance](#attribute_instance) } [class_declaration](#class_declaration)
+ \| \{ [attribute_instance](#attribute_instance) } [interface_class_declaration](#interface_class_declaration)
+ \| \{ [attribute_instance](#attribute_instance) } [covergroup_declaration](#covergroup_declaration)
+ \| [local_parameter_declaration](#local_parameter_declaration) `;`
+ \| [parameter_declaration7](#parameter_declaration7) `;`
+ \| `;`
+class\_property ::=
+ \{ [property_qualifier](#property_qualifier) } [data_declaration](#data_declaration)
+ \| [const](#const) \{ [class_item_qualifier](#class_item_qualifier) } [data_type](#data_type) [const_identifier](#const_identifier) \[ `=` [constant_expression](#constant_expression) ] `;`
+class\_method ::=
+ \{ [method_qualifier](#method_qualifier) } [task_declaration](#task_declaration)
+ \| \{ [method_qualifier](#method_qualifier) } [function_declaration](#function_declaration)
+ \| [pure](#pure) [virtual](#virtual) \{ [class_item_qualifier](#class_item_qualifier) } [method_prototype8](#method_prototype8) `;`
+ \| [extern](#extern) \{ [method_qualifier](#method_qualifier) } [method_prototype](#method_prototype) `;`
+ \| \{ [method_qualifier](#method_qualifier) } [class_constructor_declaration](#class_constructor_declaration)
+ \| [extern](#extern) \{ [method_qualifier](#method_qualifier) } [class_constructor_prototype](#class_constructor_prototype)
+class\_constructor\_declaration ::=
+ [function](#function) \[ [class_scope](#class_scope) ] [new](#new) \[ `(` \[ [class_constructor_arg_list](#class_constructor_arg_list) ] `)` ] `;`
+ \{ [block_item_declaration](#block_item_declaration) }
+ \[ [super](#super) `.` [new](#new) \[ `(` \[ [list_of_arguments](#list_of_arguments) \| [default](#default) ] `)` ] `;` ]
+ \{ [function_statement_or_null](#function_statement_or_null) }
+ [endfunction](#endfunction) \[ `:` [new](#new) ]
+class\_constructor\_prototype ::= [function](#function) [new](#new) \[ `(` \[ [class_constructor_arg_list](#class_constructor_arg_list) ] `)` ] `;`
+class\_constructor\_arg\_list ::= [class_constructor_arg](#class_constructor_arg) \{ `,` [class_constructor_arg](#class_constructor_arg) }[9](#9)
+class\_constructor\_arg ::= [tf_port_item](#tf_port_item) \| [default](#default)
+interface\_class\_item ::=
+ [type_declaration](#type_declaration)
+ \| \{ [attribute_instance](#attribute_instance) } [interface_class_method](#interface_class_method)
+ \| [local_parameter_declaration](#local_parameter_declaration) `;`
+ \| [parameter_declaration7](#parameter_declaration7) `;`
+ \| `;`
+interface\_class\_method ::= [pure](#pure) [virtual](#virtual) [method_prototype](#method_prototype) `;`
+class\_constraint ::=
+ [constraint_prototype](#constraint_prototype)
+ \| [constraint_declaration](#constraint_declaration)
+class\_item\_qualifier10 ::= [static](#static) \| [protected](#protected) \| [local](#local)
+property\_qualifier10 ::=
+ [random_qualifier](#random_qualifier)
+ \| [class_item_qualifier](#class_item_qualifier)
+random\_qualifier10 ::= [rand](#rand) \| [randc](#randc)
+method\_qualifier10 ::=
+ \[ [pure](#pure) ] [virtual](#virtual)
+ \| [class_item_qualifier](#class_item_qualifier)
+method\_prototype ::=
+ [task_prototype](#task_prototype)
+ \| [function_prototype](#function_prototype)
### A.1.10 Constraints
-constraint\_declaration ::=
- \[ [static](#static) ] [constraint](#constraint) \[ [dynamic_override_specifiers](#dynamic_override_specifiers) ][11](#11) [constraint_identifier](#constraint_identifier) [constraint_block](#constraint_block)
-constraint\_block ::= \{ \{ [constraint_block_item](#constraint_block_item) } }
-constraint\_block\_item ::=
- [solve](#solve) [solve_before_list](#solve_before_list) [before](#before) [solve_before_list](#solve_before_list) `;`
- \| [constraint_expression](#constraint_expression)
-solve\_before\_list ::= [constraint_primary](#constraint_primary) \{ `,` [constraint_primary](#constraint_primary) }
-constraint\_primary ::= \[ [implicit_class_handle](#implicit_class_handle) `.` \| [class_scope](#class_scope) ] [hierarchical_identifier](#hierarchical_identifier) [select](#select) \[ `(` `)` ][12](#12)
-constraint\_expression ::=
- \[ [soft](#soft) ] [expression_or_dist](#expression_or_dist) `;`
- \| [uniqueness_constraint](#uniqueness_constraint) `;`
- \| [expression](#expression) [â](#â)`€“>` [constraint_set](#constraint_set)
- \| [if](#if) `(` [expression](#expression) `)` [constraint_set](#constraint_set) \[ [else](#else) [constraint_set](#constraint_set) ]
- \| [foreach](#foreach) `(` [ps_or_hierarchical_array_identifier](#ps_or_hierarchical_array_identifier) \[ [loop_variables](#loop_variables) ] `)` [constraint_set](#constraint_set)
- \| [disable](#disable) [soft](#soft) [constraint_primary](#constraint_primary) `;`
-uniqueness\_constraint ::= [unique](#unique) \{ [range_list13](#range_list13) }
-constraint\_set ::=
- [constraint_expression](#constraint_expression)
- \| \{ \{ [constraint_expression](#constraint_expression) } }
-expression\_or\_dist ::= [expression](#expression) \[ [dist](#dist) \{ [dist_list](#dist_list) } ]
-dist\_list ::= [dist_item](#dist_item) \{ `,` [dist_item](#dist_item) }
-dist\_item ::=
- [value_range](#value_range) \[ [dist_weight](#dist_weight) ]
- \| [default](#default) `:/` [expression](#expression)
-dist\_weight ::=
- `:=` [expression](#expression)
- \| `:/` [expression](#expression)
-constraint\_prototype ::=
- \[ [constraint_prototype_qualifier](#constraint_prototype_qualifier) ] \[ [static](#static) ] [constraint](#constraint) \[ [dynamic_override_specifiers](#dynamic_override_specifiers) ][8](#8)`,`[11](#11)
- [constraint_identifier](#constraint_identifier) `;`
-constraint\_prototype\_qualifier ::= [extern](#extern) \| [pure](#pure)
-extern\_constraint\_declaration ::=
- \[ [static](#static) ] [constraint](#constraint) \[ [dynamic_override_specifiers](#dynamic_override_specifiers) ][11](#11) [class_scope](#class_scope) [constraint_identifier](#constraint_identifier)
- [constraint_block](#constraint_block)
+constraint\_declaration ::=
+ \[ [static](#static) ] [constraint](#constraint) \[ [dynamic_override_specifiers](#dynamic_override_specifiers) ][11](#11) [constraint_identifier](#constraint_identifier) [constraint_block](#constraint_block)
+constraint\_block ::= \{ \{ [constraint_block_item](#constraint_block_item) } }
+constraint\_block\_item ::=
+ [solve](#solve) [solve_before_list](#solve_before_list) [before](#before) [solve_before_list](#solve_before_list) `;`
+ \| [constraint_expression](#constraint_expression)
+solve\_before\_list ::= [constraint_primary](#constraint_primary) \{ `,` [constraint_primary](#constraint_primary) }
+constraint\_primary ::= \[ [implicit_class_handle](#implicit_class_handle) `.` \| [class_scope](#class_scope) ] [hierarchical_identifier](#hierarchical_identifier) [select](#select) \[ `(` `)` ][12](#12)
+constraint\_expression ::=
+ \[ [soft](#soft) ] [expression_or_dist](#expression_or_dist) `;`
+ \| [uniqueness_constraint](#uniqueness_constraint) `;`
+ \| [expression](#expression) [â](#â)`€“>` [constraint_set](#constraint_set)
+ \| [if](#if) `(` [expression](#expression) `)` [constraint_set](#constraint_set) \[ [else](#else) [constraint_set](#constraint_set) ]
+ \| [foreach](#foreach) `(` [ps_or_hierarchical_array_identifier](#ps_or_hierarchical_array_identifier) \[ [loop_variables](#loop_variables) ] `)` [constraint_set](#constraint_set)
+ \| [disable](#disable) [soft](#soft) [constraint_primary](#constraint_primary) `;`
+uniqueness\_constraint ::= [unique](#unique) \{ [range_list13](#range_list13) }
+constraint\_set ::=
+ [constraint_expression](#constraint_expression)
+ \| \{ \{ [constraint_expression](#constraint_expression) } }
+expression\_or\_dist ::= [expression](#expression) \[ [dist](#dist) \{ [dist_list](#dist_list) } ]
+dist\_list ::= [dist_item](#dist_item) \{ `,` [dist_item](#dist_item) }
+dist\_item ::=
+ [value_range](#value_range) \[ [dist_weight](#dist_weight) ]
+ \| [default](#default) `:/` [expression](#expression)
+dist\_weight ::=
+ `:=` [expression](#expression)
+ \| `:/` [expression](#expression)
+constraint\_prototype ::=
+ \[ [constraint_prototype_qualifier](#constraint_prototype_qualifier) ] \[ [static](#static) ] [constraint](#constraint) \[ [dynamic_override_specifiers](#dynamic_override_specifiers) ][8](#8)`,`[11](#11)
+ [constraint_identifier](#constraint_identifier) `;`
+constraint\_prototype\_qualifier ::= [extern](#extern) \| [pure](#pure)
+extern\_constraint\_declaration ::=
+ \[ [static](#static) ] [constraint](#constraint) \[ [dynamic_override_specifiers](#dynamic_override_specifiers) ][11](#11) [class_scope](#class_scope) [constraint_identifier](#constraint_identifier)
+ [constraint_block](#constraint_block)
### A.1.11 Package items
-package\_item ::=
- [package_or_generate_item_declaration](#package_or_generate_item_declaration)
- \| [anonymous_program](#anonymous_program)
- \| [package_export_declaration](#package_export_declaration)
- \| [timeunits_declaration3](#timeunits_declaration3)
-package\_or\_generate\_item\_declaration ::=
- [net_declaration](#net_declaration)
- \| [data_declaration](#data_declaration)
- \| [task_declaration](#task_declaration)
- \| [function_declaration](#function_declaration)
- \| [checker_declaration](#checker_declaration)
- \| [dpi_import_export](#dpi_import_export)
- \| [extern_constraint_declaration](#extern_constraint_declaration)
- \| [class_declaration](#class_declaration)
- \| [interface_class_declaration](#interface_class_declaration)
- \| [class_constructor_declaration](#class_constructor_declaration)
- \| [local_parameter_declaration](#local_parameter_declaration) `;`
- \| [parameter_declaration](#parameter_declaration) `;`
- \| [covergroup_declaration](#covergroup_declaration)
- \| [assertion_item_declaration](#assertion_item_declaration)
- \| `;`
-anonymous\_program ::= [program](#program) `;` \{ [anonymous_program_item](#anonymous_program_item) } [endprogram](#endprogram)
-anonymous\_program\_item ::=
- [task_declaration](#task_declaration)
- \| [function_declaration](#function_declaration)
- \| [class_declaration](#class_declaration)
- \| [interface_class_declaration](#interface_class_declaration)
- \| [covergroup_declaration](#covergroup_declaration)
- \| [class_constructor_declaration](#class_constructor_declaration)
- \| `;`
+package\_item ::=
+ [package_or_generate_item_declaration](#package_or_generate_item_declaration)
+ \| [anonymous_program](#anonymous_program)
+ \| [package_export_declaration](#package_export_declaration)
+ \| [timeunits_declaration3](#timeunits_declaration3)
+package\_or\_generate\_item\_declaration ::=
+ [net_declaration](#net_declaration)
+ \| [data_declaration](#data_declaration)
+ \| [task_declaration](#task_declaration)
+ \| [function_declaration](#function_declaration)
+ \| [checker_declaration](#checker_declaration)
+ \| [dpi_import_export](#dpi_import_export)
+ \| [extern_constraint_declaration](#extern_constraint_declaration)
+ \| [class_declaration](#class_declaration)
+ \| [interface_class_declaration](#interface_class_declaration)
+ \| [class_constructor_declaration](#class_constructor_declaration)
+ \| [local_parameter_declaration](#local_parameter_declaration) `;`
+ \| [parameter_declaration](#parameter_declaration) `;`
+ \| [covergroup_declaration](#covergroup_declaration)
+ \| [assertion_item_declaration](#assertion_item_declaration)
+ \| `;`
+anonymous\_program ::= [program](#program) `;` \{ [anonymous_program_item](#anonymous_program_item) } [endprogram](#endprogram)
+anonymous\_program\_item ::=
+ [task_declaration](#task_declaration)
+ \| [function_declaration](#function_declaration)
+ \| [class_declaration](#class_declaration)
+ \| [interface_class_declaration](#interface_class_declaration)
+ \| [covergroup_declaration](#covergroup_declaration)
+ \| [class_constructor_declaration](#class_constructor_declaration)
+ \| `;`
## A.2 Declarations
### A.2.1 Declaration types
#### A.2.1.1 Module parameter declarations
-local\_parameter\_declaration ::=
- [localparam](#localparam) [data_type_or_implicit](#data_type_or_implicit) [list_of_param_assignments](#list_of_param_assignments)
- \| [localparam](#localparam) [type_parameter_declaration](#type_parameter_declaration)
-parameter\_declaration ::=
- [parameter](#parameter) [data_type_or_implicit](#data_type_or_implicit) [list_of_param_assignments](#list_of_param_assignments)
- \| [parameter](#parameter) [type_parameter_declaration](#type_parameter_declaration)
-type\_parameter\_declaration ::= [type](#type) \[ [forward_type](#forward_type) ] [list_of_type_assignments](#list_of_type_assignments)
-specparam\_declaration ::= [specparam](#specparam) \[ [packed_dimension](#packed_dimension) ] [list_of_specparam_assignments](#list_of_specparam_assignments) `;`
+local\_parameter\_declaration ::=
+ [localparam](#localparam) [data_type_or_implicit](#data_type_or_implicit) [list_of_param_assignments](#list_of_param_assignments)
+ \| [localparam](#localparam) [type_parameter_declaration](#type_parameter_declaration)
+parameter\_declaration ::=
+ [parameter](#parameter) [data_type_or_implicit](#data_type_or_implicit) [list_of_param_assignments](#list_of_param_assignments)
+ \| [parameter](#parameter) [type_parameter_declaration](#type_parameter_declaration)
+type\_parameter\_declaration ::= [type](#type) \[ [forward_type](#forward_type) ] [list_of_type_assignments](#list_of_type_assignments)
+specparam\_declaration ::= [specparam](#specparam) \[ [packed_dimension](#packed_dimension) ] [list_of_specparam_assignments](#list_of_specparam_assignments) `;`
#### A.2.1.2 Port declarations
-inout\_declaration ::=
- [inout](#inout) [net_port_type](#net_port_type) [list_of_port_identifiers](#list_of_port_identifiers)
-input\_declaration ::=
- [input](#input) [net_port_type](#net_port_type) [list_of_port_identifiers](#list_of_port_identifiers)
- \| [input](#input) [variable_port_type](#variable_port_type) [list_of_variable_identifiers](#list_of_variable_identifiers)
-output\_declaration ::=
- [output](#output) [net_port_type](#net_port_type) [list_of_port_identifiers](#list_of_port_identifiers)
- \| [output](#output) [variable_port_type](#variable_port_type) [list_of_variable_port_identifiers](#list_of_variable_port_identifiers)
-interface\_port\_declaration ::=
- [interface_identifier](#interface_identifier) [list_of_interface_identifiers](#list_of_interface_identifiers)
- \| [interface_identifier](#interface_identifier) `.` [modport_identifier](#modport_identifier) [list_of_interface_identifiers](#list_of_interface_identifiers)
-ref\_declaration ::=
- [ref](#ref) [variable_port_type](#variable_port_type) [list_of_variable_identifiers](#list_of_variable_identifiers)
+inout\_declaration ::=
+ [inout](#inout) [net_port_type](#net_port_type) [list_of_port_identifiers](#list_of_port_identifiers)
+input\_declaration ::=
+ [input](#input) [net_port_type](#net_port_type) [list_of_port_identifiers](#list_of_port_identifiers)
+ \| [input](#input) [variable_port_type](#variable_port_type) [list_of_variable_identifiers](#list_of_variable_identifiers)
+output\_declaration ::=
+ [output](#output) [net_port_type](#net_port_type) [list_of_port_identifiers](#list_of_port_identifiers)
+ \| [output](#output) [variable_port_type](#variable_port_type) [list_of_variable_port_identifiers](#list_of_variable_port_identifiers)
+interface\_port\_declaration ::=
+ [interface_identifier](#interface_identifier) [list_of_interface_identifiers](#list_of_interface_identifiers)
+ \| [interface_identifier](#interface_identifier) `.` [modport_identifier](#modport_identifier) [list_of_interface_identifiers](#list_of_interface_identifiers)
+ref\_declaration ::=
+ [ref](#ref) [variable_port_type](#variable_port_type) [list_of_variable_identifiers](#list_of_variable_identifiers)
#### A.2.1.3 Type declarations
-data\_declaration ::=
- \[ [const](#const) ] \[ [var](#var) ] \[ [lifetime](#lifetime) ] [data_type_or_implicit](#data_type_or_implicit) [list_of_variable_decl_assignments](#list_of_variable_decl_assignments) `;`[14](#14)
- \| [type_declaration](#type_declaration)
- \| [package_import_declaration15](#package_import_declaration15)
- \| [nettype_declaration](#nettype_declaration)
-package\_import\_declaration ::=
- [import](#import) [package_import_item](#package_import_item) \{ `,` [package_import_item](#package_import_item) } `;`
-package\_export\_declaration ::=
- [export](#export) `*::*` `;`
- \| [export](#export) [package_import_item](#package_import_item) \{ `,` [package_import_item](#package_import_item) } `;`
-package\_import\_item ::=
- [package_identifier](#package_identifier) `::` [identifier](#identifier)
- \| [package_identifier](#package_identifier) `::` `*`
-genvar\_declaration ::= [genvar](#genvar) [list_of_genvar_identifiers](#list_of_genvar_identifiers) `;`
-net\_declaration16 ::=
- [net_type](#net_type) \[ [drive_strength](#drive_strength) \| [charge_strength](#charge_strength) ] \[ [vectored](#vectored) \| [scalared](#scalared) ]
- [data_type_or_implicit](#data_type_or_implicit) \[ [delay3](#delay3) ] [list_of_net_decl_assignments](#list_of_net_decl_assignments) `;`
- \| [nettype_identifier](#nettype_identifier) \[ [delay_control](#delay_control) ] [list_of_net_decl_assignments](#list_of_net_decl_assignments) `;`
- \| [interconnect](#interconnect) [implicit_data_type](#implicit_data_type) \[ `#` [delay_value](#delay_value) ]
- [net_identifier](#net_identifier) \{ [unpacked_dimension](#unpacked_dimension) } \[ `,` [net_identifier](#net_identifier) \{ [unpacked_dimension](#unpacked_dimension) } ] `;`
-type\_declaration ::=
- [typedef](#typedef) [data_type_or_incomplete_class_scoped_type](#data_type_or_incomplete_class_scoped_type) [type_identifier](#type_identifier) \{ [variable_dimension](#variable_dimension) } `;`
- \| [typedef](#typedef) [interface_port_identifier](#interface_port_identifier) [constant_bit_select](#constant_bit_select) `.` [type_identifier](#type_identifier) [type_identifier](#type_identifier) `;`
- \| [typedef](#typedef) \[ [forward_type](#forward_type) ] [type_identifier](#type_identifier) `;`
-forward\_type ::= [enum](#enum) \| [struct](#struct) \| [union](#union) \| [class](#class) \| [interface](#interface) [class](#class)
-nettype\_declaration ::=
- [nettype](#nettype) [data_type](#data_type) [nettype_identifier](#nettype_identifier) \[ [with](#with) \[ [package_scope](#package_scope) \| [class_scope](#class_scope) ] [tf_identifier](#tf_identifier) ] `;`
- \| [nettype](#nettype) \[ [package_scope](#package_scope) \| [class_scope](#class_scope) ] [nettype_identifier](#nettype_identifier) [nettype_identifier](#nettype_identifier) `;`
-lifetime ::= [static](#static) \| [automatic](#automatic)
+data\_declaration ::=
+ \[ [const](#const) ] \[ [var](#var) ] \[ [lifetime](#lifetime) ] [data_type_or_implicit](#data_type_or_implicit) [list_of_variable_decl_assignments](#list_of_variable_decl_assignments) `;`[14](#14)
+ \| [type_declaration](#type_declaration)
+ \| [package_import_declaration15](#package_import_declaration15)
+ \| [nettype_declaration](#nettype_declaration)
+package\_import\_declaration ::=
+ [import](#import) [package_import_item](#package_import_item) \{ `,` [package_import_item](#package_import_item) } `;`
+package\_export\_declaration ::=
+ [export](#export) `*::*` `;`
+ \| [export](#export) [package_import_item](#package_import_item) \{ `,` [package_import_item](#package_import_item) } `;`
+package\_import\_item ::=
+ [package_identifier](#package_identifier) `::` [identifier](#identifier)
+ \| [package_identifier](#package_identifier) `::` `*`
+genvar\_declaration ::= [genvar](#genvar) [list_of_genvar_identifiers](#list_of_genvar_identifiers) `;`
+net\_declaration16 ::=
+ [net_type](#net_type) \[ [drive_strength](#drive_strength) \| [charge_strength](#charge_strength) ] \[ [vectored](#vectored) \| [scalared](#scalared) ]
+ [data_type_or_implicit](#data_type_or_implicit) \[ [delay3](#delay3) ] [list_of_net_decl_assignments](#list_of_net_decl_assignments) `;`
+ \| [nettype_identifier](#nettype_identifier) \[ [delay_control](#delay_control) ] [list_of_net_decl_assignments](#list_of_net_decl_assignments) `;`
+ \| [interconnect](#interconnect) [implicit_data_type](#implicit_data_type) \[ `#` [delay_value](#delay_value) ]
+ [net_identifier](#net_identifier) \{ [unpacked_dimension](#unpacked_dimension) } \[ `,` [net_identifier](#net_identifier) \{ [unpacked_dimension](#unpacked_dimension) } ] `;`
+type\_declaration ::=
+ [typedef](#typedef) [data_type_or_incomplete_class_scoped_type](#data_type_or_incomplete_class_scoped_type) [type_identifier](#type_identifier) \{ [variable_dimension](#variable_dimension) } `;`
+ \| [typedef](#typedef) [interface_port_identifier](#interface_port_identifier) [constant_bit_select](#constant_bit_select) `.` [type_identifier](#type_identifier) [type_identifier](#type_identifier) `;`
+ \| [typedef](#typedef) \[ [forward_type](#forward_type) ] [type_identifier](#type_identifier) `;`
+forward\_type ::= [enum](#enum) \| [struct](#struct) \| [union](#union) \| [class](#class) \| [interface](#interface) [class](#class)
+nettype\_declaration ::=
+ [nettype](#nettype) [data_type](#data_type) [nettype_identifier](#nettype_identifier) \[ [with](#with) \[ [package_scope](#package_scope) \| [class_scope](#class_scope) ] [tf_identifier](#tf_identifier) ] `;`
+ \| [nettype](#nettype) \[ [package_scope](#package_scope) \| [class_scope](#class_scope) ] [nettype_identifier](#nettype_identifier) [nettype_identifier](#nettype_identifier) `;`
+lifetime ::= [static](#static) \| [automatic](#automatic)
### A.2.2 Declaration data types
#### A.2.2.1 Net and variable types
-casting\_type ::=
- [simple_type](#simple_type)
- \| [constant_primary](#constant_primary)
- \| [signing](#signing)
- \| [string](#string)
- \| [const](#const)
-data\_type ::=
- [integer_vector_type](#integer_vector_type) \[ [signing](#signing) ] \{ [packed_dimension](#packed_dimension) }
- \| [integer_atom_type](#integer_atom_type) \[ [signing](#signing) ]
- \| [non_integer_type](#non_integer_type)
- \| [struct_union](#struct_union) \[ [packed](#packed) \[ [signing](#signing) ] ] \{ [struct_union_member](#struct_union_member) \{ [struct_union_member](#struct_union_member) } }
- \{ [packed_dimension](#packed_dimension) }[17](#17)
- \| [enum](#enum) \[ [enum_base_type](#enum_base_type) ] \{ [enum_name_declaration](#enum_name_declaration) \{ `,` [enum_name_declaration](#enum_name_declaration) } }
- \{ [packed_dimension](#packed_dimension) }
- \| [string](#string)
- \| [chandle](#chandle)
- \| [virtual](#virtual) \[ [interface](#interface) ] [interface_identifier](#interface_identifier) \[ [parameter_value_assignment](#parameter_value_assignment) ] \[ `.` [modport_identifier](#modport_identifier) ]
- \| \[ [class_scope](#class_scope) \| [package_scope](#package_scope) ] [type_identifier](#type_identifier) \{ [packed_dimension](#packed_dimension) }
- \| [class_type](#class_type)
- \| [event](#event)
- \| [ps_covergroup_identifier](#ps_covergroup_identifier)
- \| [type_reference18](#type_reference18)
-data\_type\_or\_implicit ::=
- [data_type](#data_type)
- \| [implicit_data_type](#implicit_data_type)
-implicit\_data\_type ::= \[ [signing](#signing) ] \{ [packed_dimension](#packed_dimension) }
-enum\_base\_type ::=
- [integer_atom_type](#integer_atom_type) \[ [signing](#signing) ]
- \| [integer_vector_type](#integer_vector_type) \[ [signing](#signing) ] \[ [packed_dimension](#packed_dimension) ]
- \| [type_identifier](#type_identifier) \[ [packed_dimension](#packed_dimension) ][19](#19)
-enum\_name\_declaration ::=
- [enum_identifier](#enum_identifier) \[ \[ [integral_number](#integral_number) \[ `:` [integral_number](#integral_number) ] ] ] \[ `=` [constant_expression](#constant_expression) ]
-class\_scope ::= [class_type](#class_type) `::`
-class\_type ::=
- [ps_class_identifier](#ps_class_identifier) \[ [parameter_value_assignment](#parameter_value_assignment) ]
- \{ `::` [class_identifier](#class_identifier) \[ [parameter_value_assignment](#parameter_value_assignment) ] }
-interface\_class\_type ::= [ps_class_identifier](#ps_class_identifier) \[ [parameter_value_assignment](#parameter_value_assignment) ]
-integer\_type ::=
- [integer_vector_type](#integer_vector_type)
- \| [integer_atom_type](#integer_atom_type)
-integer\_atom\_type ::= [byte](#byte) \| [shortint](#shortint) \| [int](#int) \| [longint](#longint) \| [integer](#integer) \| [time](#time)
-integer\_vector\_type ::= [bit](#bit) \| [logic](#logic) \| [reg](#reg)
-non\_integer\_type ::= [shortreal](#shortreal) \| [real](#real) \| [realtime](#realtime)
-net\_type ::=
- [supply0](#supply0) \| [supply1](#supply1) \| [tri](#tri) \| [triand](#triand) \| [trior](#trior) \| [trireg](#trireg) \| [tri0](#tri0) \| [tri1](#tri1) \| [uwire](#uwire) \| [wire](#wire) \| [wand](#wand) \| [wor](#wor)
-net\_port\_type ::=
- \[ [net_type](#net_type) ] [data_type_or_implicit](#data_type_or_implicit)
- \| [nettype_identifier](#nettype_identifier)
- \| [interconnect](#interconnect) [implicit_data_type](#implicit_data_type)
-variable\_port\_type ::= [var_data_type](#var_data_type)
-var\_data\_type ::=
- [data_type](#data_type)
- \| [var](#var) [data_type_or_implicit](#data_type_or_implicit)
-signing ::= [signed](#signed) \| [unsigned](#unsigned)
-simple\_type ::=
- [integer_type](#integer_type)
- \| [non_integer_type](#non_integer_type)
- \| [ps_type_identifier](#ps_type_identifier)
- \| [ps_parameter_identifier](#ps_parameter_identifier)
-struct\_union ::=
- [struct](#struct)
- \| [union](#union) \[ [soft](#soft) \| [tagged](#tagged) ]
-struct\_union\_member20 ::=
- \{ [attribute_instance](#attribute_instance) } \[ [random_qualifier](#random_qualifier) ] [data_type_or_void](#data_type_or_void) [list_of_variable_decl_assignments](#list_of_variable_decl_assignments) `;`
-data\_type\_or\_void ::=
- [data_type](#data_type)
- \| [void](#void)
-type\_reference ::=
- [type](#type) `(` [expression21](#expression21) `)`
- \| [type](#type) `(` [data_type_or_incomplete_class_scoped_type](#data_type_or_incomplete_class_scoped_type) `)`
-data\_type\_or\_incomplete\_class\_scoped\_type ::=
- [data_type](#data_type)
- \| [incomplete_class_scoped_type](#incomplete_class_scoped_type)
- [incomplete_class_scoped_type](#incomplete_class_scoped_type) `::` `=`
- [type_identifier](#type_identifier) `::` [type_identifier_or_class_type](#type_identifier_or_class_type)
- \| [incomplete_class_scoped_type](#incomplete_class_scoped_type) `::` [type_identifier_or_class_type](#type_identifier_or_class_type)
-type\_identifier\_or\_class\_type ::=
- [type_identifier](#type_identifier)
- \| [class_type](#class_type)
+casting\_type ::=
+ [simple_type](#simple_type)
+ \| [constant_primary](#constant_primary)
+ \| [signing](#signing)
+ \| [string](#string)
+ \| [const](#const)
+data\_type ::=
+ [integer_vector_type](#integer_vector_type) \[ [signing](#signing) ] \{ [packed_dimension](#packed_dimension) }
+ \| [integer_atom_type](#integer_atom_type) \[ [signing](#signing) ]
+ \| [non_integer_type](#non_integer_type)
+ \| [struct_union](#struct_union) \[ [packed](#packed) \[ [signing](#signing) ] ] \{ [struct_union_member](#struct_union_member) \{ [struct_union_member](#struct_union_member) } }
+ \{ [packed_dimension](#packed_dimension) }[17](#17)
+ \| [enum](#enum) \[ [enum_base_type](#enum_base_type) ] \{ [enum_name_declaration](#enum_name_declaration) \{ `,` [enum_name_declaration](#enum_name_declaration) } }
+ \{ [packed_dimension](#packed_dimension) }
+ \| [string](#string)
+ \| [chandle](#chandle)
+ \| [virtual](#virtual) \[ [interface](#interface) ] [interface_identifier](#interface_identifier) \[ [parameter_value_assignment](#parameter_value_assignment) ] \[ `.` [modport_identifier](#modport_identifier) ]
+ \| \[ [class_scope](#class_scope) \| [package_scope](#package_scope) ] [type_identifier](#type_identifier) \{ [packed_dimension](#packed_dimension) }
+ \| [class_type](#class_type)
+ \| [event](#event)
+ \| [ps_covergroup_identifier](#ps_covergroup_identifier)
+ \| [type_reference18](#type_reference18)
+data\_type\_or\_implicit ::=
+ [data_type](#data_type)
+ \| [implicit_data_type](#implicit_data_type)
+implicit\_data\_type ::= \[ [signing](#signing) ] \{ [packed_dimension](#packed_dimension) }
+enum\_base\_type ::=
+ [integer_atom_type](#integer_atom_type) \[ [signing](#signing) ]
+ \| [integer_vector_type](#integer_vector_type) \[ [signing](#signing) ] \[ [packed_dimension](#packed_dimension) ]
+ \| [type_identifier](#type_identifier) \[ [packed_dimension](#packed_dimension) ][19](#19)
+enum\_name\_declaration ::=
+ [enum_identifier](#enum_identifier) \[ \[ [integral_number](#integral_number) \[ `:` [integral_number](#integral_number) ] ] ] \[ `=` [constant_expression](#constant_expression) ]
+class\_scope ::= [class_type](#class_type) `::`
+class\_type ::=
+ [ps_class_identifier](#ps_class_identifier) \[ [parameter_value_assignment](#parameter_value_assignment) ]
+ \{ `::` [class_identifier](#class_identifier) \[ [parameter_value_assignment](#parameter_value_assignment) ] }
+interface\_class\_type ::= [ps_class_identifier](#ps_class_identifier) \[ [parameter_value_assignment](#parameter_value_assignment) ]
+integer\_type ::=
+ [integer_vector_type](#integer_vector_type)
+ \| [integer_atom_type](#integer_atom_type)
+integer\_atom\_type ::= [byte](#byte) \| [shortint](#shortint) \| [int](#int) \| [longint](#longint) \| [integer](#integer) \| [time](#time)
+integer\_vector\_type ::= [bit](#bit) \| [logic](#logic) \| [reg](#reg)
+non\_integer\_type ::= [shortreal](#shortreal) \| [real](#real) \| [realtime](#realtime)
+net\_type ::=
+ [supply0](#supply0) \| [supply1](#supply1) \| [tri](#tri) \| [triand](#triand) \| [trior](#trior) \| [trireg](#trireg) \| [tri0](#tri0) \| [tri1](#tri1) \| [uwire](#uwire) \| [wire](#wire) \| [wand](#wand) \| [wor](#wor)
+net\_port\_type ::=
+ \[ [net_type](#net_type) ] [data_type_or_implicit](#data_type_or_implicit)
+ \| [nettype_identifier](#nettype_identifier)
+ \| [interconnect](#interconnect) [implicit_data_type](#implicit_data_type)
+variable\_port\_type ::= [var_data_type](#var_data_type)
+var\_data\_type ::=
+ [data_type](#data_type)
+ \| [var](#var) [data_type_or_implicit](#data_type_or_implicit)
+signing ::= [signed](#signed) \| [unsigned](#unsigned)
+simple\_type ::=
+ [integer_type](#integer_type)
+ \| [non_integer_type](#non_integer_type)
+ \| [ps_type_identifier](#ps_type_identifier)
+ \| [ps_parameter_identifier](#ps_parameter_identifier)
+struct\_union ::=
+ [struct](#struct)
+ \| [union](#union) \[ [soft](#soft) \| [tagged](#tagged) ]
+struct\_union\_member20 ::=
+ \{ [attribute_instance](#attribute_instance) } \[ [random_qualifier](#random_qualifier) ] [data_type_or_void](#data_type_or_void) [list_of_variable_decl_assignments](#list_of_variable_decl_assignments) `;`
+data\_type\_or\_void ::=
+ [data_type](#data_type)
+ \| [void](#void)
+type\_reference ::=
+ [type](#type) `(` [expression21](#expression21) `)`
+ \| [type](#type) `(` [data_type_or_incomplete_class_scoped_type](#data_type_or_incomplete_class_scoped_type) `)`
+data\_type\_or\_incomplete\_class\_scoped\_type ::=
+ [data_type](#data_type)
+ \| [incomplete_class_scoped_type](#incomplete_class_scoped_type)
+ [incomplete_class_scoped_type](#incomplete_class_scoped_type) `::` `=`
+ [type_identifier](#type_identifier) `::` [type_identifier_or_class_type](#type_identifier_or_class_type)
+ \| [incomplete_class_scoped_type](#incomplete_class_scoped_type) `::` [type_identifier_or_class_type](#type_identifier_or_class_type)
+type\_identifier\_or\_class\_type ::=
+ [type_identifier](#type_identifier)
+ \| [class_type](#class_type)
#### A.2.2.2 Strengths
-drive\_strength ::=
- `(` [strength0](#strength0) `,` [strength1](#strength1) `)`
- \| `(` [strength1](#strength1) `,` [strength0](#strength0) `)`
- \| `(` [strength0](#strength0) `,` [highz1](#highz1) `)`
- \| `(` [strength1](#strength1) `,` [highz0](#highz0) `)`
- \| `(` [highz0](#highz0) `,` [strength1](#strength1) `)`
- \| `(` [highz1](#highz1) `,` [strength0](#strength0) `)`
-strength0 ::= [supply0](#supply0) \| [strong0](#strong0) \| [pull0](#pull0) \| [weak0](#weak0)
-strength1 ::= [supply1](#supply1) \| [strong1](#strong1) \| [pull1](#pull1) \| [weak1](#weak1)
-charge\_strength ::= `(` [small](#small) `)` \| `(` [medium](#medium) `)` \| `(` [large](#large) `)`
+drive\_strength ::=
+ `(` [strength0](#strength0) `,` [strength1](#strength1) `)`
+ \| `(` [strength1](#strength1) `,` [strength0](#strength0) `)`
+ \| `(` [strength0](#strength0) `,` [highz1](#highz1) `)`
+ \| `(` [strength1](#strength1) `,` [highz0](#highz0) `)`
+ \| `(` [highz0](#highz0) `,` [strength1](#strength1) `)`
+ \| `(` [highz1](#highz1) `,` [strength0](#strength0) `)`
+strength0 ::= [supply0](#supply0) \| [strong0](#strong0) \| [pull0](#pull0) \| [weak0](#weak0)
+strength1 ::= [supply1](#supply1) \| [strong1](#strong1) \| [pull1](#pull1) \| [weak1](#weak1)
+charge\_strength ::= `(` [small](#small) `)` \| `(` [medium](#medium) `)` \| `(` [large](#large) `)`
#### A.2.2.3 Delays
-delay2 ::=
- `#` [delay_value](#delay_value)
- \| `#` `(` [mintypmax_expression](#mintypmax_expression) \[ `,` [mintypmax_expression](#mintypmax_expression) ] `)`
-delay3 ::=
- `#` [delay_value](#delay_value)
- \| `#` `(` [mintypmax_expression](#mintypmax_expression) \[ `,` [mintypmax_expression](#mintypmax_expression) \[ `,` [mintypmax_expression](#mintypmax_expression) ] ] `)`
-delay\_value ::=
- [unsigned_number](#unsigned_number)
- \| [real_number](#real_number)
- \| [ps_identifier](#ps_identifier)
- \| [time_literal](#time_literal)
- \| [1step](#1step)
+delay2 ::=
+ `#` [delay_value](#delay_value)
+ \| `#` `(` [mintypmax_expression](#mintypmax_expression) \[ `,` [mintypmax_expression](#mintypmax_expression) ] `)`
+delay3 ::=
+ `#` [delay_value](#delay_value)
+ \| `#` `(` [mintypmax_expression](#mintypmax_expression) \[ `,` [mintypmax_expression](#mintypmax_expression) \[ `,` [mintypmax_expression](#mintypmax_expression) ] ] `)`
+delay\_value ::=
+ [unsigned_number](#unsigned_number)
+ \| [real_number](#real_number)
+ \| [ps_identifier](#ps_identifier)
+ \| [time_literal](#time_literal)
+ \| [1step](#1step)
### A.2.3 Declaration lists
-list\_of\_defparam\_assignments ::= [defparam_assignment](#defparam_assignment) \{ `,` [defparam_assignment](#defparam_assignment) }
-list\_of\_genvar\_identifiers ::= [genvar_identifier](#genvar_identifier) \{ `,` [genvar_identifier](#genvar_identifier) }
-list\_of\_interface\_identifiers ::=
- [interface_identifier](#interface_identifier) \{ [unpacked_dimension](#unpacked_dimension) } \{ `,` [interface_identifier](#interface_identifier) \{ [unpacked_dimension](#unpacked_dimension) } }
-list\_of\_net\_decl\_assignments ::= [net_decl_assignment](#net_decl_assignment) \{ `,` [net_decl_assignment](#net_decl_assignment) }
-list\_of\_param\_assignments ::= [param_assignment](#param_assignment) \{ `,` [param_assignment](#param_assignment) }
-list\_of\_port\_identifiers ::=
- [port_identifier](#port_identifier) \{ [unpacked_dimension](#unpacked_dimension) } \{ `,` [port_identifier](#port_identifier) \{ [unpacked_dimension](#unpacked_dimension) } }
-list\_of\_udp\_port\_identifiers ::= [port_identifier](#port_identifier) \{ `,` [port_identifier](#port_identifier) }
-list\_of\_specparam\_assignments ::= [specparam_assignment](#specparam_assignment) \{ `,` [specparam_assignment](#specparam_assignment) }
-list\_of\_tf\_variable\_identifiers ::=
- [port_identifier](#port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [expression](#expression) ]
- \{ `,` [port_identifier](#port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [expression](#expression) ] }
-list\_of\_type\_assignments ::= [type_assignment](#type_assignment) \{ `,` [type_assignment](#type_assignment) }
-list\_of\_variable\_decl\_assignments ::= [variable_decl_assignment](#variable_decl_assignment) \{ `,` [variable_decl_assignment](#variable_decl_assignment) }
-list\_of\_variable\_identifiers ::=
- [variable_identifier](#variable_identifier) \{ [variable_dimension](#variable_dimension) } \{ `,` [variable_identifier](#variable_identifier) \{ [variable_dimension](#variable_dimension) } }
-list\_of\_variable\_port\_identifiers ::=
- [port_identifier](#port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [constant_expression](#constant_expression) ]
- \{ `,` [port_identifier](#port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [constant_expression](#constant_expression) ] }
+list\_of\_defparam\_assignments ::= [defparam_assignment](#defparam_assignment) \{ `,` [defparam_assignment](#defparam_assignment) }
+list\_of\_genvar\_identifiers ::= [genvar_identifier](#genvar_identifier) \{ `,` [genvar_identifier](#genvar_identifier) }
+list\_of\_interface\_identifiers ::=
+ [interface_identifier](#interface_identifier) \{ [unpacked_dimension](#unpacked_dimension) } \{ `,` [interface_identifier](#interface_identifier) \{ [unpacked_dimension](#unpacked_dimension) } }
+list\_of\_net\_decl\_assignments ::= [net_decl_assignment](#net_decl_assignment) \{ `,` [net_decl_assignment](#net_decl_assignment) }
+list\_of\_param\_assignments ::= [param_assignment](#param_assignment) \{ `,` [param_assignment](#param_assignment) }
+list\_of\_port\_identifiers ::=
+ [port_identifier](#port_identifier) \{ [unpacked_dimension](#unpacked_dimension) } \{ `,` [port_identifier](#port_identifier) \{ [unpacked_dimension](#unpacked_dimension) } }
+list\_of\_udp\_port\_identifiers ::= [port_identifier](#port_identifier) \{ `,` [port_identifier](#port_identifier) }
+list\_of\_specparam\_assignments ::= [specparam_assignment](#specparam_assignment) \{ `,` [specparam_assignment](#specparam_assignment) }
+list\_of\_tf\_variable\_identifiers ::=
+ [port_identifier](#port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [expression](#expression) ]
+ \{ `,` [port_identifier](#port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [expression](#expression) ] }
+list\_of\_type\_assignments ::= [type_assignment](#type_assignment) \{ `,` [type_assignment](#type_assignment) }
+list\_of\_variable\_decl\_assignments ::= [variable_decl_assignment](#variable_decl_assignment) \{ `,` [variable_decl_assignment](#variable_decl_assignment) }
+list\_of\_variable\_identifiers ::=
+ [variable_identifier](#variable_identifier) \{ [variable_dimension](#variable_dimension) } \{ `,` [variable_identifier](#variable_identifier) \{ [variable_dimension](#variable_dimension) } }
+list\_of\_variable\_port\_identifiers ::=
+ [port_identifier](#port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [constant_expression](#constant_expression) ]
+ \{ `,` [port_identifier](#port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [constant_expression](#constant_expression) ] }
### A.2.4 Declaration assignments
-defparam\_assignment ::= [hierarchical_parameter_identifier](#hierarchical_parameter_identifier) `=` [constant_mintypmax_expression](#constant_mintypmax_expression)
-net\_decl\_assignment ::= [net_identifier](#net_identifier) \{ [unpacked_dimension](#unpacked_dimension) } \[ `=` [expression](#expression) ]
-param\_assignment ::= [parameter_identifier](#parameter_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [constant_param_expression](#constant_param_expression) ][22](#22)
-specparam\_assignment ::=
- [specparam_identifier](#specparam_identifier) `=` [constant_mintypmax_expression](#constant_mintypmax_expression)
- \| [pulse_control_specparam](#pulse_control_specparam)
-pulse\_control\_specparam ::=
- [PATHPULSE](#PATHPULSE)`$` `=` `(` [reject_limit_value](#reject_limit_value) \[ `,` [error_limit_value](#error_limit_value) ] `)`
- \| [PATHPULSE](#PATHPULSE)`$`[specify_input_terminal_descriptor](#specify_input_terminal_descriptor)`$`[specify_output_terminal_descriptor](#specify_output_terminal_descriptor)
- `=` `(` [reject_limit_value](#reject_limit_value) \[ `,` [error_limit_value](#error_limit_value) ] `)`
-error\_limit\_value ::= [limit_value](#limit_value)
-reject\_limit\_value ::= [limit_value](#limit_value)
-limit\_value ::= [constant_mintypmax_expression](#constant_mintypmax_expression)
-type\_assignment ::= [type_identifier](#type_identifier) \[ `=` [data_type_or_incomplete_class_scoped_type](#data_type_or_incomplete_class_scoped_type) ][22](#22)
-variable\_decl\_assignment ::=
- [variable_identifier](#variable_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [expression](#expression) ]
- \| [dynamic_array_variable_identifier](#dynamic_array_variable_identifier) [unsized_dimension](#unsized_dimension) \{ [variable_dimension](#variable_dimension) }
- \[ `=` [dynamic_array_new](#dynamic_array_new) ]
- \| [class_variable_identifier](#class_variable_identifier) \[ `=` [class_new](#class_new) ]
-class\_new23 ::=
- \[ [class_scope](#class_scope) ] [new](#new) \[ `(` [list_of_arguments](#list_of_arguments) `)` ]
- \| [new](#new) [expression](#expression)
-dynamic\_array\_new ::= [new](#new) \[ [expression](#expression) ] \[ `(` [expression](#expression) `)` ]
+defparam\_assignment ::= [hierarchical_parameter_identifier](#hierarchical_parameter_identifier) `=` [constant_mintypmax_expression](#constant_mintypmax_expression)
+net\_decl\_assignment ::= [net_identifier](#net_identifier) \{ [unpacked_dimension](#unpacked_dimension) } \[ `=` [expression](#expression) ]
+param\_assignment ::= [parameter_identifier](#parameter_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [constant_param_expression](#constant_param_expression) ][22](#22)
+specparam\_assignment ::=
+ [specparam_identifier](#specparam_identifier) `=` [constant_mintypmax_expression](#constant_mintypmax_expression)
+ \| [pulse_control_specparam](#pulse_control_specparam)
+pulse\_control\_specparam ::=
+ [PATHPULSE](#PATHPULSE)`$` `=` `(` [reject_limit_value](#reject_limit_value) \[ `,` [error_limit_value](#error_limit_value) ] `)`
+ \| [PATHPULSE](#PATHPULSE)`$`[specify_input_terminal_descriptor](#specify_input_terminal_descriptor)`$`[specify_output_terminal_descriptor](#specify_output_terminal_descriptor)
+ `=` `(` [reject_limit_value](#reject_limit_value) \[ `,` [error_limit_value](#error_limit_value) ] `)`
+error\_limit\_value ::= [limit_value](#limit_value)
+reject\_limit\_value ::= [limit_value](#limit_value)
+limit\_value ::= [constant_mintypmax_expression](#constant_mintypmax_expression)
+type\_assignment ::= [type_identifier](#type_identifier) \[ `=` [data_type_or_incomplete_class_scoped_type](#data_type_or_incomplete_class_scoped_type) ][22](#22)
+variable\_decl\_assignment ::=
+ [variable_identifier](#variable_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [expression](#expression) ]
+ \| [dynamic_array_variable_identifier](#dynamic_array_variable_identifier) [unsized_dimension](#unsized_dimension) \{ [variable_dimension](#variable_dimension) }
+ \[ `=` [dynamic_array_new](#dynamic_array_new) ]
+ \| [class_variable_identifier](#class_variable_identifier) \[ `=` [class_new](#class_new) ]
+class\_new23 ::=
+ \[ [class_scope](#class_scope) ] [new](#new) \[ `(` [list_of_arguments](#list_of_arguments) `)` ]
+ \| [new](#new) [expression](#expression)
+dynamic\_array\_new ::= [new](#new) \[ [expression](#expression) ] \[ `(` [expression](#expression) `)` ]
### A.2.5 Declaration ranges
-unpacked\_dimension ::=
- \[ [constant_range](#constant_range) ]
- \| \[ [constant_expression](#constant_expression) ]
-packed\_dimension24 ::=
- \[ [constant_range](#constant_range) ]
- \| [unsized_dimension](#unsized_dimension)
-associative\_dimension ::=
- \[ [data_type](#data_type) ]
- \| \[ `*` ]
-variable\_dimension ::=
- [unsized_dimension](#unsized_dimension)
- \| [unpacked_dimension](#unpacked_dimension)
- \| [associative_dimension](#associative_dimension)
- \| [queue_dimension](#queue_dimension)
-queue\_dimension ::= \[ `$` \[ `:` [constant_expression](#constant_expression) ] ]
-unsized\_dimension ::= \[ ]
+unpacked\_dimension ::=
+ \[ [constant_range](#constant_range) ]
+ \| \[ [constant_expression](#constant_expression) ]
+packed\_dimension24 ::=
+ \[ [constant_range](#constant_range) ]
+ \| [unsized_dimension](#unsized_dimension)
+associative\_dimension ::=
+ \[ [data_type](#data_type) ]
+ \| \[ `*` ]
+variable\_dimension ::=
+ [unsized_dimension](#unsized_dimension)
+ \| [unpacked_dimension](#unpacked_dimension)
+ \| [associative_dimension](#associative_dimension)
+ \| [queue_dimension](#queue_dimension)
+queue\_dimension ::= \[ `$` \[ `:` [constant_expression](#constant_expression) ] ]
+unsized\_dimension ::= \[ ]
### A.2.6 Function declarations
-function\_data\_type\_or\_implicit ::=
- [data_type_or_void](#data_type_or_void)
- \| [implicit_data_type](#implicit_data_type)
-function\_declaration ::=
- [function](#function) \[ [dynamic_override_specifiers](#dynamic_override_specifiers) ][25](#25) \[ [lifetime](#lifetime) ] [function_body_declaration](#function_body_declaration)
-function\_body\_declaration ::=
- [function_data_type_or_implicit](#function_data_type_or_implicit)
- \[ [interface_identifier](#interface_identifier) `.` \| [class_scope](#class_scope) ] [function_identifier](#function_identifier) `;`
- \{ [tf_item_declaration](#tf_item_declaration) }
- \{ [function_statement_or_null](#function_statement_or_null) }
- [endfunction](#endfunction) \[ `:` [function_identifier](#function_identifier) ]
- \| [function_data_type_or_implicit](#function_data_type_or_implicit)
- \[ [interface_identifier](#interface_identifier) `.` \| [class_scope](#class_scope) ] [function_identifier](#function_identifier) `(` \[ [tf_port_list](#tf_port_list) ] `)` `;`
- \{ [block_item_declaration](#block_item_declaration) }
- \{ [function_statement_or_null](#function_statement_or_null) }
- [endfunction](#endfunction) \[ `:` [function_identifier](#function_identifier) ]
-function\_prototype ::=
- [function](#function) \[ [dynamic_override_specifiers](#dynamic_override_specifiers) ][25](#25) [data_type_or_void](#data_type_or_void) [function_identifier](#function_identifier)
- \[ `(` \[ [tf_port_list](#tf_port_list) ] `)` ]
-dpi\_import\_export ::=
- [import](#import) [dpi_spec_string](#dpi_spec_string) \[ [dpi_function_import_property](#dpi_function_import_property) ] \[ [c_identifier](#c_identifier) `=` ] [dpi_function_proto](#dpi_function_proto) `;`
- \| [import](#import) [dpi_spec_string](#dpi_spec_string) \[ [dpi_task_import_property](#dpi_task_import_property) ] \[ [c_identifier](#c_identifier) `=` ] [dpi_task_proto](#dpi_task_proto) `;`
- \| [export](#export) [dpi_spec_string](#dpi_spec_string) \[ [c_identifier](#c_identifier) `=` ] [function](#function) [function_identifier](#function_identifier) `;`
- \| [export](#export) [dpi_spec_string](#dpi_spec_string) \[ [c_identifier](#c_identifier) `=` ] [task](#task) [task_identifier](#task_identifier) `;`
-dpi\_spec\_string ::= `"`[DPI](#DPI)`-`[C](#C)`"` \| `"`[DPI](#DPI)`"`
-dpi\_function\_import\_property ::= [context](#context) \| [pure](#pure)
-dpi\_task\_import\_property ::= [context](#context)
- [dpi_function_proto26](#dpi_function_proto26)`,`
-27 ::= [function_prototype](#function_prototype)
-dpi\_task\_proto27 ::= [task_prototype](#task_prototype)
+function\_data\_type\_or\_implicit ::=
+ [data_type_or_void](#data_type_or_void)
+ \| [implicit_data_type](#implicit_data_type)
+function\_declaration ::=
+ [function](#function) \[ [dynamic_override_specifiers](#dynamic_override_specifiers) ][25](#25) \[ [lifetime](#lifetime) ] [function_body_declaration](#function_body_declaration)
+function\_body\_declaration ::=
+ [function_data_type_or_implicit](#function_data_type_or_implicit)
+ \[ [interface_identifier](#interface_identifier) `.` \| [class_scope](#class_scope) ] [function_identifier](#function_identifier) `;`
+ \{ [tf_item_declaration](#tf_item_declaration) }
+ \{ [function_statement_or_null](#function_statement_or_null) }
+ [endfunction](#endfunction) \[ `:` [function_identifier](#function_identifier) ]
+ \| [function_data_type_or_implicit](#function_data_type_or_implicit)
+ \[ [interface_identifier](#interface_identifier) `.` \| [class_scope](#class_scope) ] [function_identifier](#function_identifier) `(` \[ [tf_port_list](#tf_port_list) ] `)` `;`
+ \{ [block_item_declaration](#block_item_declaration) }
+ \{ [function_statement_or_null](#function_statement_or_null) }
+ [endfunction](#endfunction) \[ `:` [function_identifier](#function_identifier) ]
+function\_prototype ::=
+ [function](#function) \[ [dynamic_override_specifiers](#dynamic_override_specifiers) ][25](#25) [data_type_or_void](#data_type_or_void) [function_identifier](#function_identifier)
+ \[ `(` \[ [tf_port_list](#tf_port_list) ] `)` ]
+dpi\_import\_export ::=
+ [import](#import) [dpi_spec_string](#dpi_spec_string) \[ [dpi_function_import_property](#dpi_function_import_property) ] \[ [c_identifier](#c_identifier) `=` ] [dpi_function_proto](#dpi_function_proto) `;`
+ \| [import](#import) [dpi_spec_string](#dpi_spec_string) \[ [dpi_task_import_property](#dpi_task_import_property) ] \[ [c_identifier](#c_identifier) `=` ] [dpi_task_proto](#dpi_task_proto) `;`
+ \| [export](#export) [dpi_spec_string](#dpi_spec_string) \[ [c_identifier](#c_identifier) `=` ] [function](#function) [function_identifier](#function_identifier) `;`
+ \| [export](#export) [dpi_spec_string](#dpi_spec_string) \[ [c_identifier](#c_identifier) `=` ] [task](#task) [task_identifier](#task_identifier) `;`
+dpi\_spec\_string ::= `"`[DPI](#DPI)`-`[C](#C)`"` \| `"`[DPI](#DPI)`"`
+dpi\_function\_import\_property ::= [context](#context) \| [pure](#pure)
+dpi\_task\_import\_property ::= [context](#context)
+ [dpi_function_proto26](#dpi_function_proto26)`,`
+27 ::= [function_prototype](#function_prototype)
+dpi\_task\_proto27 ::= [task_prototype](#task_prototype)
### A.2.7 Task declarations
-task\_declaration ::= [task](#task) \[ [dynamic_override_specifiers](#dynamic_override_specifiers) ][25](#25) \[ [lifetime](#lifetime) ] [task_body_declaration](#task_body_declaration)
-task\_body\_declaration ::=
- \[ [interface_identifier](#interface_identifier) `.` \| [class_scope](#class_scope) ] [task_identifier](#task_identifier) `;`
- \{ [tf_item_declaration](#tf_item_declaration) }
- \{ [statement_or_null](#statement_or_null) }
- [endtask](#endtask) \[ `:` [task_identifier](#task_identifier) ]
- \| \[ [interface_identifier](#interface_identifier) `.` \| [class_scope](#class_scope) ] [task_identifier](#task_identifier) `(` \[ [tf_port_list](#tf_port_list) ] `)` `;`
- \{ [block_item_declaration](#block_item_declaration) }
- \{ [statement_or_null](#statement_or_null) }
- [endtask](#endtask) \[ `:` [task_identifier](#task_identifier) ]
-tf\_item\_declaration ::=
- [block_item_declaration](#block_item_declaration)
- \| [tf_port_declaration](#tf_port_declaration)
-tf\_port\_list ::= [tf_port_item](#tf_port_item) \{ `,` [tf_port_item](#tf_port_item) }
-tf\_port\_item28 ::=
- \{ [attribute_instance](#attribute_instance) } \[ [tf_port_direction](#tf_port_direction) ] \[ [var](#var) ] [data_type_or_implicit](#data_type_or_implicit)
- \[ [port_identifier](#port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [expression](#expression) ] ]
-tf\_port\_direction ::=
- [port_direction](#port_direction)
- \| \[ [const](#const) ] [ref](#ref) \[ [static](#static) ]
-tf\_port\_declaration ::=
- \{ [attribute_instance](#attribute_instance) } [tf_port_direction](#tf_port_direction) \[ [var](#var) ] [data_type_or_implicit](#data_type_or_implicit) [list_of_tf_variable_identifiers](#list_of_tf_variable_identifiers) `;`
-task\_prototype ::= [task](#task) \[ [dynamic_override_specifiers](#dynamic_override_specifiers) ][25](#25) [task_identifier](#task_identifier) \[ `(` \[ [tf_port_list](#tf_port_list) ] `)` ]
-dynamic\_override\_specifiers ::= \[ [initial_or_extends_specifier](#initial_or_extends_specifier) ] \[ [final_specifier](#final_specifier) ]
-initial\_or\_extends\_specifier ::=
- `:` [initial](#initial)
- \| `:` [extends](#extends)
-final\_specifier ::= `:` [final](#final)
+task\_declaration ::= [task](#task) \[ [dynamic_override_specifiers](#dynamic_override_specifiers) ][25](#25) \[ [lifetime](#lifetime) ] [task_body_declaration](#task_body_declaration)
+task\_body\_declaration ::=
+ \[ [interface_identifier](#interface_identifier) `.` \| [class_scope](#class_scope) ] [task_identifier](#task_identifier) `;`
+ \{ [tf_item_declaration](#tf_item_declaration) }
+ \{ [statement_or_null](#statement_or_null) }
+ [endtask](#endtask) \[ `:` [task_identifier](#task_identifier) ]
+ \| \[ [interface_identifier](#interface_identifier) `.` \| [class_scope](#class_scope) ] [task_identifier](#task_identifier) `(` \[ [tf_port_list](#tf_port_list) ] `)` `;`
+ \{ [block_item_declaration](#block_item_declaration) }
+ \{ [statement_or_null](#statement_or_null) }
+ [endtask](#endtask) \[ `:` [task_identifier](#task_identifier) ]
+tf\_item\_declaration ::=
+ [block_item_declaration](#block_item_declaration)
+ \| [tf_port_declaration](#tf_port_declaration)
+tf\_port\_list ::= [tf_port_item](#tf_port_item) \{ `,` [tf_port_item](#tf_port_item) }
+tf\_port\_item28 ::=
+ \{ [attribute_instance](#attribute_instance) } \[ [tf_port_direction](#tf_port_direction) ] \[ [var](#var) ] [data_type_or_implicit](#data_type_or_implicit)
+ \[ [port_identifier](#port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [expression](#expression) ] ]
+tf\_port\_direction ::=
+ [port_direction](#port_direction)
+ \| \[ [const](#const) ] [ref](#ref) \[ [static](#static) ]
+tf\_port\_declaration ::=
+ \{ [attribute_instance](#attribute_instance) } [tf_port_direction](#tf_port_direction) \[ [var](#var) ] [data_type_or_implicit](#data_type_or_implicit) [list_of_tf_variable_identifiers](#list_of_tf_variable_identifiers) `;`
+task\_prototype ::= [task](#task) \[ [dynamic_override_specifiers](#dynamic_override_specifiers) ][25](#25) [task_identifier](#task_identifier) \[ `(` \[ [tf_port_list](#tf_port_list) ] `)` ]
+dynamic\_override\_specifiers ::= \[ [initial_or_extends_specifier](#initial_or_extends_specifier) ] \[ [final_specifier](#final_specifier) ]
+initial\_or\_extends\_specifier ::=
+ `:` [initial](#initial)
+ \| `:` [extends](#extends)
+final\_specifier ::= `:` [final](#final)
### A.2.8 Block item declarations
-block\_item\_declaration ::=
- \{ [attribute_instance](#attribute_instance) } [data_declaration](#data_declaration)
- \| \{ [attribute_instance](#attribute_instance) } [local_parameter_declaration](#local_parameter_declaration) `;`
- \| \{ [attribute_instance](#attribute_instance) } [parameter_declaration](#parameter_declaration) `;`
- \| \{ [attribute_instance](#attribute_instance) } [let_declaration](#let_declaration)
+block\_item\_declaration ::=
+ \{ [attribute_instance](#attribute_instance) } [data_declaration](#data_declaration)
+ \| \{ [attribute_instance](#attribute_instance) } [local_parameter_declaration](#local_parameter_declaration) `;`
+ \| \{ [attribute_instance](#attribute_instance) } [parameter_declaration](#parameter_declaration) `;`
+ \| \{ [attribute_instance](#attribute_instance) } [let_declaration](#let_declaration)
### A.2.9 Interface declarations
-modport\_declaration ::= [modport](#modport) [modport_item](#modport_item) \{ `,` [modport_item](#modport_item) } `;`
-modport\_item ::= [modport_identifier](#modport_identifier) `(` [modport_ports_declaration](#modport_ports_declaration) \{ `,` [modport_ports_declaration](#modport_ports_declaration) } `)`
-modport\_ports\_declaration ::=
- \{ [attribute_instance](#attribute_instance) } [modport_simple_ports_declaration](#modport_simple_ports_declaration)
- \| \{ [attribute_instance](#attribute_instance) } [modport_tf_ports_declaration](#modport_tf_ports_declaration)
- \| \{ [attribute_instance](#attribute_instance) } [modport_clocking_declaration](#modport_clocking_declaration)
-modport\_clocking\_declaration ::= [clocking](#clocking) [clocking_identifier](#clocking_identifier)
-modport\_simple\_ports\_declaration ::= [port_direction](#port_direction) [modport_simple_port](#modport_simple_port) \{ `,` [modport_simple_port](#modport_simple_port) }
-modport\_simple\_port ::=
- [port_identifier](#port_identifier)
- \| `.` [port_identifier](#port_identifier) `(` \[ [expression](#expression) ] `)`
-modport\_tf\_ports\_declaration ::= [import_export](#import_export) [modport_tf_port](#modport_tf_port) \{ `,` [modport_tf_port](#modport_tf_port) }
-modport\_tf\_port ::=
- [method_prototype](#method_prototype)
- \| [tf_identifier](#tf_identifier)
-import\_export ::= [import](#import) \| [export](#export)
+modport\_declaration ::= [modport](#modport) [modport_item](#modport_item) \{ `,` [modport_item](#modport_item) } `;`
+modport\_item ::= [modport_identifier](#modport_identifier) `(` [modport_ports_declaration](#modport_ports_declaration) \{ `,` [modport_ports_declaration](#modport_ports_declaration) } `)`
+modport\_ports\_declaration ::=
+ \{ [attribute_instance](#attribute_instance) } [modport_simple_ports_declaration](#modport_simple_ports_declaration)
+ \| \{ [attribute_instance](#attribute_instance) } [modport_tf_ports_declaration](#modport_tf_ports_declaration)
+ \| \{ [attribute_instance](#attribute_instance) } [modport_clocking_declaration](#modport_clocking_declaration)
+modport\_clocking\_declaration ::= [clocking](#clocking) [clocking_identifier](#clocking_identifier)
+modport\_simple\_ports\_declaration ::= [port_direction](#port_direction) [modport_simple_port](#modport_simple_port) \{ `,` [modport_simple_port](#modport_simple_port) }
+modport\_simple\_port ::=
+ [port_identifier](#port_identifier)
+ \| `.` [port_identifier](#port_identifier) `(` \[ [expression](#expression) ] `)`
+modport\_tf\_ports\_declaration ::= [import_export](#import_export) [modport_tf_port](#modport_tf_port) \{ `,` [modport_tf_port](#modport_tf_port) }
+modport\_tf\_port ::=
+ [method_prototype](#method_prototype)
+ \| [tf_identifier](#tf_identifier)
+import\_export ::= [import](#import) \| [export](#export)
### A.2.10 Assertion declarations
-concurrent\_assertion\_item ::=
- \[ [block_identifier](#block_identifier) `:` ] [concurrent_assertion_statement](#concurrent_assertion_statement)
- \| [checker_instantiation](#checker_instantiation)
-concurrent\_assertion\_statement ::=
- [assert_property_statement](#assert_property_statement)
- \| [assume_property_statement](#assume_property_statement)
- \| [cover_property_statement](#cover_property_statement)
- \| [cover_sequence_statement](#cover_sequence_statement)
- \| [restrict_property_statement](#restrict_property_statement)
-assert\_property\_statement ::=
- [assert](#assert) [property](#property) `(` [property_spec](#property_spec) `)` [action_block](#action_block)
-assume\_property\_statement ::=
- [assume](#assume) [property](#property) `(` [property_spec](#property_spec) `)` [action_block](#action_block)
-cover\_property\_statement ::=
- [cover](#cover) [property](#property) `(` [property_spec](#property_spec) `)` [statement_or_null](#statement_or_null)
-expect\_property\_statement ::=
- [expect](#expect) `(` [property_spec](#property_spec) `)` [action_block](#action_block)
-cover\_sequence\_statement ::=
- [cover](#cover) [sequence](#sequence) `(` \[ [clocking_event](#clocking_event) ] \[ [disable](#disable) [iff](#iff) `(` [expression_or_dist](#expression_or_dist) `)` ] [sequence_expr](#sequence_expr) `)`
- [statement_or_null](#statement_or_null)
-restrict\_property\_statement ::=
- [restrict](#restrict) [property](#property) `(` [property_spec](#property_spec) `)` `;`
-property\_instance ::= [ps_or_hierarchical_property_identifier](#ps_or_hierarchical_property_identifier) \[ `(` \[ [property_list_of_arguments](#property_list_of_arguments) ] `)` ]
-property\_list\_of\_arguments ::=
- \[ [property_actual_arg](#property_actual_arg) ] \{ `,` \[ [property_actual_arg](#property_actual_arg) ] } \{ `,` `.` [identifier](#identifier) `(` \[ [property_actual_arg](#property_actual_arg) ] `)` }
- \| `.` [identifier](#identifier) `(` \[ [property_actual_arg](#property_actual_arg) ] `)` \{ `,` `.` [identifier](#identifier) `(` \[ [property_actual_arg](#property_actual_arg) ] `)` }
-property\_actual\_arg ::=
- [property_expr](#property_expr)
- \| [sequence_actual_arg](#sequence_actual_arg)
-assertion\_item\_declaration ::=
- [property_declaration](#property_declaration)
- \| [sequence_declaration](#sequence_declaration)
- \| [let_declaration](#let_declaration)
-property\_declaration ::=
- [property](#property) [property_identifier](#property_identifier) \[ `(` \[ [property_port_list](#property_port_list) ] `)` ] `;`
- \{ [assertion_variable_declaration](#assertion_variable_declaration) }
- [property_spec](#property_spec) \[ `;` ]
- [endproperty](#endproperty) \[ `:` [property_identifier](#property_identifier) ]
-property\_port\_list ::= [property_port_item](#property_port_item) \{ `,` [property_port_item](#property_port_item) }
-property\_port\_item ::=
- \{ [attribute_instance](#attribute_instance) } \[ [local](#local) \[ [property_lvar_port_direction](#property_lvar_port_direction) ] ] [property_formal_type](#property_formal_type)
- [formal_port_identifier](#formal_port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [property_actual_arg](#property_actual_arg) ]
-property\_lvar\_port\_direction ::= [input](#input)
-property\_formal\_type ::=
- [sequence_formal_type](#sequence_formal_type)
- \| [property](#property)
-property\_spec ::= \[ [clocking_event](#clocking_event) ] \[ [disable](#disable) [iff](#iff) `(` [expression_or_dist](#expression_or_dist) `)` ] [property_expr](#property_expr)
-property\_expr ::=
- [sequence_expr](#sequence_expr)
- \| [strong](#strong) `(` [sequence_expr](#sequence_expr) `)`
- \| [weak](#weak) `(` [sequence_expr](#sequence_expr) `)`
- \| `(` [property_expr](#property_expr) `)`
- \| [not](#not) [property_expr](#property_expr)
- \| [property_expr](#property_expr) [or](#or) [property_expr](#property_expr)
- \| [property_expr](#property_expr) [and](#and) [property_expr](#property_expr)
- \| [sequence_expr](#sequence_expr) `|->` [property_expr](#property_expr)
- \| [sequence_expr](#sequence_expr) `|=>` [property_expr](#property_expr)
- \| [if](#if) `(` [expression_or_dist](#expression_or_dist) `)` [property_expr](#property_expr) \[ [else](#else) [property_expr](#property_expr) ]
- \| [case](#case) `(` [expression_or_dist](#expression_or_dist) `)` [property_case_item](#property_case_item) \{ [property_case_item](#property_case_item) } [endcase](#endcase)
- \| [sequence_expr](#sequence_expr) `#-#` [property_expr](#property_expr)
- \| [sequence_expr](#sequence_expr) `#=#` [property_expr](#property_expr)
- \| [nexttime](#nexttime) [property_expr](#property_expr)
- \| [nexttime](#nexttime) \[ [constant_expression](#constant_expression) ] [property_expr](#property_expr)
- \| [s_nexttime](#s_nexttime) [property_expr](#property_expr)
- \| [s_nexttime](#s_nexttime) \[ [constant_expression](#constant_expression) ] [property_expr](#property_expr)
- \| [always](#always) [property_expr](#property_expr)
- \| [always](#always) \[ [cycle_delay_const_range_expression](#cycle_delay_const_range_expression) ] [property_expr](#property_expr)
- \| [s_always](#s_always) \[ [constant_range](#constant_range) ] [property_expr](#property_expr)
- \| [s_eventually](#s_eventually) [property_expr](#property_expr)
- \| [eventually](#eventually) \[ [constant_range](#constant_range) ] [property_expr](#property_expr)
- \| [s_eventually](#s_eventually) \[ [cycle_delay_const_range_expression](#cycle_delay_const_range_expression) ] [property_expr](#property_expr)
- \| [property_expr](#property_expr) [until](#until) [property_expr](#property_expr)
- \| [property_expr](#property_expr) [s_until](#s_until) [property_expr](#property_expr)
- \| [property_expr](#property_expr) [until_with](#until_with) [property_expr](#property_expr)
- \| [property_expr](#property_expr) [s_until_with](#s_until_with) [property_expr](#property_expr)
- \| [property_expr](#property_expr) [implies](#implies) [property_expr](#property_expr)
- \| [property_expr](#property_expr) [iff](#iff) [property_expr](#property_expr)
- \| [accept_on](#accept_on) `(` [expression_or_dist](#expression_or_dist) `)` [property_expr](#property_expr)
- \| [reject_on](#reject_on) `(` [expression_or_dist](#expression_or_dist) `)` [property_expr](#property_expr)
- \| [sync_accept_on](#sync_accept_on) `(` [expression_or_dist](#expression_or_dist) `)` [property_expr](#property_expr)
- \| [sync_reject_on](#sync_reject_on) `(` [expression_or_dist](#expression_or_dist) `)` [property_expr](#property_expr)
- \| [property_instance](#property_instance)
- \| [clocking_event](#clocking_event) [property_expr](#property_expr)
-property\_case\_item ::=
- [expression_or_dist](#expression_or_dist) \{ `,` [expression_or_dist](#expression_or_dist) } `:` [property_expr](#property_expr) `;`
- \| [default](#default) \[ `:` ] [property_expr](#property_expr) `;`
-sequence\_declaration ::=
- [sequence](#sequence) [sequence_identifier](#sequence_identifier) \[ `(` \[ [sequence_port_list](#sequence_port_list) ] `)` ] `;`
- \{ [assertion_variable_declaration](#assertion_variable_declaration) }
- [sequence_expr](#sequence_expr) \[ `;` ]
- [endsequence](#endsequence) \[ `:` [sequence_identifier](#sequence_identifier) ]
-sequence\_port\_list ::= [sequence_port_item](#sequence_port_item) \{ `,` [sequence_port_item](#sequence_port_item) }
-sequence\_port\_item ::=
- \{ [attribute_instance](#attribute_instance) } \[ [local](#local) \[ [sequence_lvar_port_direction](#sequence_lvar_port_direction) ] ] [sequence_formal_type](#sequence_formal_type)
- [formal_port_identifier](#formal_port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [sequence_actual_arg](#sequence_actual_arg) ]
-sequence\_lvar\_port\_direction ::= [input](#input) \| [inout](#inout) \| [output](#output)
-sequence\_formal\_type ::=
- [data_type_or_implicit](#data_type_or_implicit)
- \| [sequence](#sequence)
- \| [untyped](#untyped)
-sequence\_expr ::=
- [cycle_delay_range](#cycle_delay_range) [sequence_expr](#sequence_expr) \{ [cycle_delay_range](#cycle_delay_range) [sequence_expr](#sequence_expr) }
- \| [sequence_expr](#sequence_expr) [cycle_delay_range](#cycle_delay_range) [sequence_expr](#sequence_expr) \{ [cycle_delay_range](#cycle_delay_range) [sequence_expr](#sequence_expr) }
- \| [expression_or_dist](#expression_or_dist) \[ [boolean_abbrev](#boolean_abbrev) ]
- \| [sequence_instance](#sequence_instance) \[ [sequence_abbrev](#sequence_abbrev) ]
- \| `(` [sequence_expr](#sequence_expr) \{ `,` [sequence_match_item](#sequence_match_item) } `)` \[ [sequence_abbrev](#sequence_abbrev) ]
- \| [sequence_expr](#sequence_expr) [and](#and) [sequence_expr](#sequence_expr)
- \| [sequence_expr](#sequence_expr) [intersect](#intersect) [sequence_expr](#sequence_expr)
- \| [sequence_expr](#sequence_expr) [or](#or) [sequence_expr](#sequence_expr)
- \| [first_match](#first_match) `(` [sequence_expr](#sequence_expr) \{ `,` [sequence_match_item](#sequence_match_item) } `)`
- \| [expression_or_dist](#expression_or_dist) [throughout](#throughout) [sequence_expr](#sequence_expr)
- \| [sequence_expr](#sequence_expr) [within](#within) [sequence_expr](#sequence_expr)
- \| [clocking_event](#clocking_event) [sequence_expr](#sequence_expr)
-cycle\_delay\_range ::=
- `##` [constant_primary](#constant_primary)
- \| `##` \[ [cycle_delay_const_range_expression](#cycle_delay_const_range_expression) ]
- \| `##[*]`
- \| `##[+]`
-sequence\_method\_call ::= [sequence_instance](#sequence_instance) `.` [method_identifier](#method_identifier)
-sequence\_match\_item ::=
- [operator_assignment](#operator_assignment)
- \| [inc_or_dec_expression](#inc_or_dec_expression)
- \| [subroutine_call](#subroutine_call)
-sequence\_instance ::= [ps_or_hierarchical_sequence_identifier](#ps_or_hierarchical_sequence_identifier) \[ `(` \[ [sequence_list_of_arguments](#sequence_list_of_arguments) ] `)` ]
-sequence\_list\_of\_arguments ::=
- \[ [sequence_actual_arg](#sequence_actual_arg) ] \{ `,` \[ [sequence_actual_arg](#sequence_actual_arg) ] } \{ `,` `.` [identifier](#identifier) `(` \[ [sequence_actual_arg](#sequence_actual_arg) ] `)` }
- \| `.` [identifier](#identifier) `(` \[ [sequence_actual_arg](#sequence_actual_arg) ] `)` \{ `,` `.` [identifier](#identifier) `(` \[ [sequence_actual_arg](#sequence_actual_arg) ] `)` }
-sequence\_actual\_arg ::=
- [event_expression](#event_expression)
- \| [sequence_expr](#sequence_expr)
- \| `$`
-boolean\_abbrev ::=
- [consecutive_repetition](#consecutive_repetition)
- \| [nonconsecutive_repetition](#nonconsecutive_repetition)
- \| [goto_repetition](#goto_repetition)
-sequence\_abbrev ::= [consecutive_repetition](#consecutive_repetition)
-consecutive\_repetition ::=
- `[*` [const_or_range_expression](#const_or_range_expression) ]
- \| `[*]`
- \| `[+]`
-nonconsecutive\_repetition ::= `[=` [const_or_range_expression](#const_or_range_expression) ]
-goto\_repetition ::= `[->` [const_or_range_expression](#const_or_range_expression) ]
-const\_or\_range\_expression ::=
- [constant_expression](#constant_expression)
- \| [cycle_delay_const_range_expression](#cycle_delay_const_range_expression)
-cycle\_delay\_const\_range\_expression ::=
- [constant_expression](#constant_expression) `:` [constant_expression](#constant_expression)
- \| [constant_expression](#constant_expression) `:` `$`
-assertion\_variable\_declaration ::= [var_data_type](#var_data_type) [list_of_variable_decl_assignments](#list_of_variable_decl_assignments) `;`
+concurrent\_assertion\_item ::=
+ \[ [block_identifier](#block_identifier) `:` ] [concurrent_assertion_statement](#concurrent_assertion_statement)
+ \| [checker_instantiation](#checker_instantiation)
+concurrent\_assertion\_statement ::=
+ [assert_property_statement](#assert_property_statement)
+ \| [assume_property_statement](#assume_property_statement)
+ \| [cover_property_statement](#cover_property_statement)
+ \| [cover_sequence_statement](#cover_sequence_statement)
+ \| [restrict_property_statement](#restrict_property_statement)
+assert\_property\_statement ::=
+ [assert](#assert) [property](#property) `(` [property_spec](#property_spec) `)` [action_block](#action_block)
+assume\_property\_statement ::=
+ [assume](#assume) [property](#property) `(` [property_spec](#property_spec) `)` [action_block](#action_block)
+cover\_property\_statement ::=
+ [cover](#cover) [property](#property) `(` [property_spec](#property_spec) `)` [statement_or_null](#statement_or_null)
+expect\_property\_statement ::=
+ [expect](#expect) `(` [property_spec](#property_spec) `)` [action_block](#action_block)
+cover\_sequence\_statement ::=
+ [cover](#cover) [sequence](#sequence) `(` \[ [clocking_event](#clocking_event) ] \[ [disable](#disable) [iff](#iff) `(` [expression_or_dist](#expression_or_dist) `)` ] [sequence_expr](#sequence_expr) `)`
+ [statement_or_null](#statement_or_null)
+restrict\_property\_statement ::=
+ [restrict](#restrict) [property](#property) `(` [property_spec](#property_spec) `)` `;`
+property\_instance ::= [ps_or_hierarchical_property_identifier](#ps_or_hierarchical_property_identifier) \[ `(` \[ [property_list_of_arguments](#property_list_of_arguments) ] `)` ]
+property\_list\_of\_arguments ::=
+ \[ [property_actual_arg](#property_actual_arg) ] \{ `,` \[ [property_actual_arg](#property_actual_arg) ] } \{ `,` `.` [identifier](#identifier) `(` \[ [property_actual_arg](#property_actual_arg) ] `)` }
+ \| `.` [identifier](#identifier) `(` \[ [property_actual_arg](#property_actual_arg) ] `)` \{ `,` `.` [identifier](#identifier) `(` \[ [property_actual_arg](#property_actual_arg) ] `)` }
+property\_actual\_arg ::=
+ [property_expr](#property_expr)
+ \| [sequence_actual_arg](#sequence_actual_arg)
+assertion\_item\_declaration ::=
+ [property_declaration](#property_declaration)
+ \| [sequence_declaration](#sequence_declaration)
+ \| [let_declaration](#let_declaration)
+property\_declaration ::=
+ [property](#property) [property_identifier](#property_identifier) \[ `(` \[ [property_port_list](#property_port_list) ] `)` ] `;`
+ \{ [assertion_variable_declaration](#assertion_variable_declaration) }
+ [property_spec](#property_spec) \[ `;` ]
+ [endproperty](#endproperty) \[ `:` [property_identifier](#property_identifier) ]
+property\_port\_list ::= [property_port_item](#property_port_item) \{ `,` [property_port_item](#property_port_item) }
+property\_port\_item ::=
+ \{ [attribute_instance](#attribute_instance) } \[ [local](#local) \[ [property_lvar_port_direction](#property_lvar_port_direction) ] ] [property_formal_type](#property_formal_type)
+ [formal_port_identifier](#formal_port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [property_actual_arg](#property_actual_arg) ]
+property\_lvar\_port\_direction ::= [input](#input)
+property\_formal\_type ::=
+ [sequence_formal_type](#sequence_formal_type)
+ \| [property](#property)
+property\_spec ::= \[ [clocking_event](#clocking_event) ] \[ [disable](#disable) [iff](#iff) `(` [expression_or_dist](#expression_or_dist) `)` ] [property_expr](#property_expr)
+property\_expr ::=
+ [sequence_expr](#sequence_expr)
+ \| [strong](#strong) `(` [sequence_expr](#sequence_expr) `)`
+ \| [weak](#weak) `(` [sequence_expr](#sequence_expr) `)`
+ \| `(` [property_expr](#property_expr) `)`
+ \| [not](#not) [property_expr](#property_expr)
+ \| [property_expr](#property_expr) [or](#or) [property_expr](#property_expr)
+ \| [property_expr](#property_expr) [and](#and) [property_expr](#property_expr)
+ \| [sequence_expr](#sequence_expr) `|->` [property_expr](#property_expr)
+ \| [sequence_expr](#sequence_expr) `|=>` [property_expr](#property_expr)
+ \| [if](#if) `(` [expression_or_dist](#expression_or_dist) `)` [property_expr](#property_expr) \[ [else](#else) [property_expr](#property_expr) ]
+ \| [case](#case) `(` [expression_or_dist](#expression_or_dist) `)` [property_case_item](#property_case_item) \{ [property_case_item](#property_case_item) } [endcase](#endcase)
+ \| [sequence_expr](#sequence_expr) `#-#` [property_expr](#property_expr)
+ \| [sequence_expr](#sequence_expr) `#=#` [property_expr](#property_expr)
+ \| [nexttime](#nexttime) [property_expr](#property_expr)
+ \| [nexttime](#nexttime) \[ [constant_expression](#constant_expression) ] [property_expr](#property_expr)
+ \| [s_nexttime](#s_nexttime) [property_expr](#property_expr)
+ \| [s_nexttime](#s_nexttime) \[ [constant_expression](#constant_expression) ] [property_expr](#property_expr)
+ \| [always](#always) [property_expr](#property_expr)
+ \| [always](#always) \[ [cycle_delay_const_range_expression](#cycle_delay_const_range_expression) ] [property_expr](#property_expr)
+ \| [s_always](#s_always) \[ [constant_range](#constant_range) ] [property_expr](#property_expr)
+ \| [s_eventually](#s_eventually) [property_expr](#property_expr)
+ \| [eventually](#eventually) \[ [constant_range](#constant_range) ] [property_expr](#property_expr)
+ \| [s_eventually](#s_eventually) \[ [cycle_delay_const_range_expression](#cycle_delay_const_range_expression) ] [property_expr](#property_expr)
+ \| [property_expr](#property_expr) [until](#until) [property_expr](#property_expr)
+ \| [property_expr](#property_expr) [s_until](#s_until) [property_expr](#property_expr)
+ \| [property_expr](#property_expr) [until_with](#until_with) [property_expr](#property_expr)
+ \| [property_expr](#property_expr) [s_until_with](#s_until_with) [property_expr](#property_expr)
+ \| [property_expr](#property_expr) [implies](#implies) [property_expr](#property_expr)
+ \| [property_expr](#property_expr) [iff](#iff) [property_expr](#property_expr)
+ \| [accept_on](#accept_on) `(` [expression_or_dist](#expression_or_dist) `)` [property_expr](#property_expr)
+ \| [reject_on](#reject_on) `(` [expression_or_dist](#expression_or_dist) `)` [property_expr](#property_expr)
+ \| [sync_accept_on](#sync_accept_on) `(` [expression_or_dist](#expression_or_dist) `)` [property_expr](#property_expr)
+ \| [sync_reject_on](#sync_reject_on) `(` [expression_or_dist](#expression_or_dist) `)` [property_expr](#property_expr)
+ \| [property_instance](#property_instance)
+ \| [clocking_event](#clocking_event) [property_expr](#property_expr)
+property\_case\_item ::=
+ [expression_or_dist](#expression_or_dist) \{ `,` [expression_or_dist](#expression_or_dist) } `:` [property_expr](#property_expr) `;`
+ \| [default](#default) \[ `:` ] [property_expr](#property_expr) `;`
+sequence\_declaration ::=
+ [sequence](#sequence) [sequence_identifier](#sequence_identifier) \[ `(` \[ [sequence_port_list](#sequence_port_list) ] `)` ] `;`
+ \{ [assertion_variable_declaration](#assertion_variable_declaration) }
+ [sequence_expr](#sequence_expr) \[ `;` ]
+ [endsequence](#endsequence) \[ `:` [sequence_identifier](#sequence_identifier) ]
+sequence\_port\_list ::= [sequence_port_item](#sequence_port_item) \{ `,` [sequence_port_item](#sequence_port_item) }
+sequence\_port\_item ::=
+ \{ [attribute_instance](#attribute_instance) } \[ [local](#local) \[ [sequence_lvar_port_direction](#sequence_lvar_port_direction) ] ] [sequence_formal_type](#sequence_formal_type)
+ [formal_port_identifier](#formal_port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [sequence_actual_arg](#sequence_actual_arg) ]
+sequence\_lvar\_port\_direction ::= [input](#input) \| [inout](#inout) \| [output](#output)
+sequence\_formal\_type ::=
+ [data_type_or_implicit](#data_type_or_implicit)
+ \| [sequence](#sequence)
+ \| [untyped](#untyped)
+sequence\_expr ::=
+ [cycle_delay_range](#cycle_delay_range) [sequence_expr](#sequence_expr) \{ [cycle_delay_range](#cycle_delay_range) [sequence_expr](#sequence_expr) }
+ \| [sequence_expr](#sequence_expr) [cycle_delay_range](#cycle_delay_range) [sequence_expr](#sequence_expr) \{ [cycle_delay_range](#cycle_delay_range) [sequence_expr](#sequence_expr) }
+ \| [expression_or_dist](#expression_or_dist) \[ [boolean_abbrev](#boolean_abbrev) ]
+ \| [sequence_instance](#sequence_instance) \[ [sequence_abbrev](#sequence_abbrev) ]
+ \| `(` [sequence_expr](#sequence_expr) \{ `,` [sequence_match_item](#sequence_match_item) } `)` \[ [sequence_abbrev](#sequence_abbrev) ]
+ \| [sequence_expr](#sequence_expr) [and](#and) [sequence_expr](#sequence_expr)
+ \| [sequence_expr](#sequence_expr) [intersect](#intersect) [sequence_expr](#sequence_expr)
+ \| [sequence_expr](#sequence_expr) [or](#or) [sequence_expr](#sequence_expr)
+ \| [first_match](#first_match) `(` [sequence_expr](#sequence_expr) \{ `,` [sequence_match_item](#sequence_match_item) } `)`
+ \| [expression_or_dist](#expression_or_dist) [throughout](#throughout) [sequence_expr](#sequence_expr)
+ \| [sequence_expr](#sequence_expr) [within](#within) [sequence_expr](#sequence_expr)
+ \| [clocking_event](#clocking_event) [sequence_expr](#sequence_expr)
+cycle\_delay\_range ::=
+ `##` [constant_primary](#constant_primary)
+ \| `##` \[ [cycle_delay_const_range_expression](#cycle_delay_const_range_expression) ]
+ \| `##[*]`
+ \| `##[+]`
+sequence\_method\_call ::= [sequence_instance](#sequence_instance) `.` [method_identifier](#method_identifier)
+sequence\_match\_item ::=
+ [operator_assignment](#operator_assignment)
+ \| [inc_or_dec_expression](#inc_or_dec_expression)
+ \| [subroutine_call](#subroutine_call)
+sequence\_instance ::= [ps_or_hierarchical_sequence_identifier](#ps_or_hierarchical_sequence_identifier) \[ `(` \[ [sequence_list_of_arguments](#sequence_list_of_arguments) ] `)` ]
+sequence\_list\_of\_arguments ::=
+ \[ [sequence_actual_arg](#sequence_actual_arg) ] \{ `,` \[ [sequence_actual_arg](#sequence_actual_arg) ] } \{ `,` `.` [identifier](#identifier) `(` \[ [sequence_actual_arg](#sequence_actual_arg) ] `)` }
+ \| `.` [identifier](#identifier) `(` \[ [sequence_actual_arg](#sequence_actual_arg) ] `)` \{ `,` `.` [identifier](#identifier) `(` \[ [sequence_actual_arg](#sequence_actual_arg) ] `)` }
+sequence\_actual\_arg ::=
+ [event_expression](#event_expression)
+ \| [sequence_expr](#sequence_expr)
+ \| `$`
+boolean\_abbrev ::=
+ [consecutive_repetition](#consecutive_repetition)
+ \| [nonconsecutive_repetition](#nonconsecutive_repetition)
+ \| [goto_repetition](#goto_repetition)
+sequence\_abbrev ::= [consecutive_repetition](#consecutive_repetition)
+consecutive\_repetition ::=
+ `[*` [const_or_range_expression](#const_or_range_expression) ]
+ \| `[*]`
+ \| `[+]`
+nonconsecutive\_repetition ::= `[=` [const_or_range_expression](#const_or_range_expression) ]
+goto\_repetition ::= `[->` [const_or_range_expression](#const_or_range_expression) ]
+const\_or\_range\_expression ::=
+ [constant_expression](#constant_expression)
+ \| [cycle_delay_const_range_expression](#cycle_delay_const_range_expression)
+cycle\_delay\_const\_range\_expression ::=
+ [constant_expression](#constant_expression) `:` [constant_expression](#constant_expression)
+ \| [constant_expression](#constant_expression) `:` `$`
+assertion\_variable\_declaration ::= [var_data_type](#var_data_type) [list_of_variable_decl_assignments](#list_of_variable_decl_assignments) `;`
### A.2.11 Covergroup declarations
-covergroup\_declaration ::=
- [covergroup](#covergroup) [covergroup_identifier](#covergroup_identifier) \[ `(` \[ [tf_port_list](#tf_port_list) ] `)` ] \[ [coverage_event](#coverage_event) ] `;`
- \{ [coverage_spec_or_option](#coverage_spec_or_option) }
- [endgroup](#endgroup) \[ `:` [covergroup_identifier](#covergroup_identifier) ]
- \| [covergroup](#covergroup) [extends](#extends) [covergroup_identifier](#covergroup_identifier) `;`[29](#29)
- \{ [coverage_spec_or_option](#coverage_spec_or_option) }
- [endgroup](#endgroup) \[ `:` [covergroup_identifier](#covergroup_identifier) ]
-coverage\_spec\_or\_option ::=
- \{ [attribute_instance](#attribute_instance) } [coverage_spec](#coverage_spec)
- \| \{ [attribute_instance](#attribute_instance) } [coverage_option](#coverage_option) `;`
-coverage\_option ::=
- [option](#option) `.` [member_identifier](#member_identifier) `=` [expression](#expression)
- \| [type_option](#type_option) `.` [member_identifier](#member_identifier) `=` [constant_expression](#constant_expression)
-coverage\_spec ::=
- [cover_point](#cover_point)
- \| [cover_cross](#cover_cross)
-coverage\_event ::=
- [clocking_event](#clocking_event)
- \| [with](#with) [function](#function) [sample](#sample) `(` \[ [tf_port_list](#tf_port_list) ] `)`
- \| `@@` `(` [block_event_expression](#block_event_expression) `)`
-block\_event\_expression ::=
- [block_event_expression](#block_event_expression) [or](#or) [block_event_expression](#block_event_expression)
- \| [begin](#begin) [hierarchical_btf_identifier](#hierarchical_btf_identifier)
- \| [end](#end) [hierarchical_btf_identifier](#hierarchical_btf_identifier)
-hierarchical\_btf\_identifier ::=
- [hierarchical_tf_identifier](#hierarchical_tf_identifier)
- \| [hierarchical_block_identifier](#hierarchical_block_identifier)
- \| \[ [hierarchical_identifier](#hierarchical_identifier) `.` \| [class_scope](#class_scope) ] [method_identifier](#method_identifier)
-cover\_point ::=
- \[ \[ [data_type_or_implicit](#data_type_or_implicit) ] [cover_point_identifier](#cover_point_identifier) `:` ] [coverpoint](#coverpoint) [expression](#expression) \[ [iff](#iff) `(` [expression](#expression) `)` ]
- [bins_or_empty](#bins_or_empty)
-bins\_or\_empty ::=
- \{ \{ [attribute_instance](#attribute_instance) } \{ [bins_or_options](#bins_or_options) `;` } }
- \| `;`
-bins\_or\_options ::=
- [coverage_option](#coverage_option)
- \| \[ [wildcard](#wildcard) ] [bins_keyword](#bins_keyword) [bin_identifier](#bin_identifier) \[ \[ \[ [covergroup_expression](#covergroup_expression) ] ] ] `=`
- \{ [covergroup_range_list](#covergroup_range_list) } \[ [with](#with) `(` [with_covergroup_expression](#with_covergroup_expression) `)` ] \[ [iff](#iff) `(` [expression](#expression) `)` ]
- \| \[ [wildcard](#wildcard) ] [bins_keyword](#bins_keyword) [bin_identifier](#bin_identifier) \[ \[ \[ [covergroup_expression](#covergroup_expression) ] ] ] `=`
- [cover_point_identifier](#cover_point_identifier) [with](#with) `(` [with_covergroup_expression](#with_covergroup_expression) `)` \[ [iff](#iff) `(` [expression](#expression) `)` ]
- \| \[ [wildcard](#wildcard) ] [bins_keyword](#bins_keyword) [bin_identifier](#bin_identifier) \[ \[ \[ [covergroup_expression](#covergroup_expression) ] ] ] `=`
- [set_covergroup_expression](#set_covergroup_expression) \[ [iff](#iff) `(` [expression](#expression) `)` ]
- \| \[ [wildcard](#wildcard)] [bins_keyword](#bins_keyword) [bin_identifier](#bin_identifier) \[ \[ ] ] `=` [trans_list](#trans_list) \[ [iff](#iff) `(` [expression](#expression) `)` ]
- \| [bins_keyword](#bins_keyword) [bin_identifier](#bin_identifier) \[ \[ \[ [covergroup_expression](#covergroup_expression) ] ] ] `=` [default](#default) \[ [iff](#iff) `(` [expression](#expression) `)` ]
- \| [bins_keyword](#bins_keyword) [bin_identifier](#bin_identifier) `=` [default](#default) [sequence](#sequence) \[ [iff](#iff) `(` [expression](#expression) `)` ]
- [bins_keyword](#bins_keyword)`::=` [bins](#bins) \| [illegal_bins](#illegal_bins) \| [ignore_bins](#ignore_bins)
-trans\_list ::= `(` [trans_set](#trans_set) `)` \{ `,` `(` [trans_set](#trans_set) `)` }
-trans\_set ::= [trans_range_list](#trans_range_list) \{ `=>` [trans_range_list](#trans_range_list) }
-trans\_range\_list ::=
- [trans_item](#trans_item)
- \| [trans_item](#trans_item) `[*` [repeat_range](#repeat_range) ]
- \| [trans_item](#trans_item) \[[â](#â)`€“>` [repeat_range](#repeat_range) ]
- \| [trans_item](#trans_item) `[=` [repeat_range](#repeat_range) ]
-trans\_item ::= [covergroup_range_list](#covergroup_range_list)
-repeat\_range ::=
- [covergroup_expression](#covergroup_expression)
- \| [covergroup_expression](#covergroup_expression) `:` [covergroup_expression](#covergroup_expression)
-cover\_cross ::= \[ [cross_identifier](#cross_identifier) `:` ] [cross](#cross) [list_of_cross_items](#list_of_cross_items) \[ [iff](#iff) `(` [expression](#expression) `)` ] [cross_body](#cross_body)
-list\_of\_cross\_items ::= [cross_item](#cross_item) `,` [cross_item](#cross_item) \{ `,` [cross_item](#cross_item) }
-cross\_item ::=
- [cover_point_identifier](#cover_point_identifier)
- \| [variable_identifier](#variable_identifier)
-cross\_body ::=
- \{ \{ [cross_body_item](#cross_body_item) } }
- \| `;`
-cross\_body\_item ::=
- [function_declaration](#function_declaration)
- \| [bins_selection_or_option](#bins_selection_or_option) `;`
-bins\_selection\_or\_option ::=
- \{ [attribute_instance](#attribute_instance) } [coverage_option](#coverage_option)
- \| \{ [attribute_instance](#attribute_instance) } [bins_selection](#bins_selection)
-bins\_selection ::= [bins_keyword](#bins_keyword) [bin_identifier](#bin_identifier) `=` [select_expression](#select_expression) \[ [iff](#iff) `(` [expression](#expression) `)` ]
-select\_expression30 ::=
- [select_condition](#select_condition)
- \| `!` [select_condition](#select_condition)
- \| [select_expression](#select_expression) `&&` [select_expression](#select_expression)
- \| [select_expression](#select_expression) `||` [select_expression](#select_expression)
- \| `(` [select_expression](#select_expression) `)`
- \| [select_expression](#select_expression) [with](#with) `(` [with_covergroup_expression](#with_covergroup_expression) `)` \[ [matches](#matches) [integer_covergroup_expression](#integer_covergroup_expression) ]
- \| [cross_identifier](#cross_identifier)
- \| [cross_set_expression](#cross_set_expression) \[ [matches](#matches) [integer_covergroup_expression](#integer_covergroup_expression) ]
-select\_condition ::= [binsof](#binsof) `(` [bins_expression](#bins_expression) `)` \[ [intersect](#intersect) \{ [covergroup_range_list](#covergroup_range_list) } ]
-bins\_expression ::=
- [variable_identifier](#variable_identifier)
- \| [cover_point_identifier](#cover_point_identifier) \[ `.` [bin_identifier](#bin_identifier) ]
-covergroup\_range\_list ::= [covergroup_value_range](#covergroup_value_range) \{ `,` [covergroup_value_range](#covergroup_value_range) }
-covergroup\_value\_range ::=
- [covergroup_expression](#covergroup_expression)
- \| \[ [covergroup_expression](#covergroup_expression) `:` [covergroup_expression](#covergroup_expression) ]
- \| \[ `$` `:` [covergroup_expression](#covergroup_expression) ]
- \| \[ [covergroup_expression](#covergroup_expression) `:` `$` ]
- \| \[ [covergroup_expression](#covergroup_expression) `+/-` [covergroup_expression](#covergroup_expression) ]
- \| \[ [covergroup_expression](#covergroup_expression) `+%-` [covergroup_expression](#covergroup_expression) ]
-with\_covergroup\_expression ::= [covergroup_expression31](#covergroup_expression31)
-set\_covergroup\_expression ::= [covergroup_expression32](#covergroup_expression32)
-integer\_covergroup\_expression ::= [covergroup_expression](#covergroup_expression) \| `$`
-cross\_set\_expression ::= [covergroup_expression](#covergroup_expression)
-covergroup\_expression ::= [expression33](#expression33)
+covergroup\_declaration ::=
+ [covergroup](#covergroup) [covergroup_identifier](#covergroup_identifier) \[ `(` \[ [tf_port_list](#tf_port_list) ] `)` ] \[ [coverage_event](#coverage_event) ] `;`
+ \{ [coverage_spec_or_option](#coverage_spec_or_option) }
+ [endgroup](#endgroup) \[ `:` [covergroup_identifier](#covergroup_identifier) ]
+ \| [covergroup](#covergroup) [extends](#extends) [covergroup_identifier](#covergroup_identifier) `;`[29](#29)
+ \{ [coverage_spec_or_option](#coverage_spec_or_option) }
+ [endgroup](#endgroup) \[ `:` [covergroup_identifier](#covergroup_identifier) ]
+coverage\_spec\_or\_option ::=
+ \{ [attribute_instance](#attribute_instance) } [coverage_spec](#coverage_spec)
+ \| \{ [attribute_instance](#attribute_instance) } [coverage_option](#coverage_option) `;`
+coverage\_option ::=
+ [option](#option) `.` [member_identifier](#member_identifier) `=` [expression](#expression)
+ \| [type_option](#type_option) `.` [member_identifier](#member_identifier) `=` [constant_expression](#constant_expression)
+coverage\_spec ::=
+ [cover_point](#cover_point)
+ \| [cover_cross](#cover_cross)
+coverage\_event ::=
+ [clocking_event](#clocking_event)
+ \| [with](#with) [function](#function) [sample](#sample) `(` \[ [tf_port_list](#tf_port_list) ] `)`
+ \| `@@` `(` [block_event_expression](#block_event_expression) `)`
+block\_event\_expression ::=
+ [block_event_expression](#block_event_expression) [or](#or) [block_event_expression](#block_event_expression)
+ \| [begin](#begin) [hierarchical_btf_identifier](#hierarchical_btf_identifier)
+ \| [end](#end) [hierarchical_btf_identifier](#hierarchical_btf_identifier)
+hierarchical\_btf\_identifier ::=
+ [hierarchical_tf_identifier](#hierarchical_tf_identifier)
+ \| [hierarchical_block_identifier](#hierarchical_block_identifier)
+ \| \[ [hierarchical_identifier](#hierarchical_identifier) `.` \| [class_scope](#class_scope) ] [method_identifier](#method_identifier)
+cover\_point ::=
+ \[ \[ [data_type_or_implicit](#data_type_or_implicit) ] [cover_point_identifier](#cover_point_identifier) `:` ] [coverpoint](#coverpoint) [expression](#expression) \[ [iff](#iff) `(` [expression](#expression) `)` ]
+ [bins_or_empty](#bins_or_empty)
+bins\_or\_empty ::=
+ \{ \{ [attribute_instance](#attribute_instance) } \{ [bins_or_options](#bins_or_options) `;` } }
+ \| `;`
+bins\_or\_options ::=
+ [coverage_option](#coverage_option)
+ \| \[ [wildcard](#wildcard) ] [bins_keyword](#bins_keyword) [bin_identifier](#bin_identifier) \[ \[ \[ [covergroup_expression](#covergroup_expression) ] ] ] `=`
+ \{ [covergroup_range_list](#covergroup_range_list) } \[ [with](#with) `(` [with_covergroup_expression](#with_covergroup_expression) `)` ] \[ [iff](#iff) `(` [expression](#expression) `)` ]
+ \| \[ [wildcard](#wildcard) ] [bins_keyword](#bins_keyword) [bin_identifier](#bin_identifier) \[ \[ \[ [covergroup_expression](#covergroup_expression) ] ] ] `=`
+ [cover_point_identifier](#cover_point_identifier) [with](#with) `(` [with_covergroup_expression](#with_covergroup_expression) `)` \[ [iff](#iff) `(` [expression](#expression) `)` ]
+ \| \[ [wildcard](#wildcard) ] [bins_keyword](#bins_keyword) [bin_identifier](#bin_identifier) \[ \[ \[ [covergroup_expression](#covergroup_expression) ] ] ] `=`
+ [set_covergroup_expression](#set_covergroup_expression) \[ [iff](#iff) `(` [expression](#expression) `)` ]
+ \| \[ [wildcard](#wildcard)] [bins_keyword](#bins_keyword) [bin_identifier](#bin_identifier) \[ \[ ] ] `=` [trans_list](#trans_list) \[ [iff](#iff) `(` [expression](#expression) `)` ]
+ \| [bins_keyword](#bins_keyword) [bin_identifier](#bin_identifier) \[ \[ \[ [covergroup_expression](#covergroup_expression) ] ] ] `=` [default](#default) \[ [iff](#iff) `(` [expression](#expression) `)` ]
+ \| [bins_keyword](#bins_keyword) [bin_identifier](#bin_identifier) `=` [default](#default) [sequence](#sequence) \[ [iff](#iff) `(` [expression](#expression) `)` ]
+ [bins_keyword](#bins_keyword)`::=` [bins](#bins) \| [illegal_bins](#illegal_bins) \| [ignore_bins](#ignore_bins)
+trans\_list ::= `(` [trans_set](#trans_set) `)` \{ `,` `(` [trans_set](#trans_set) `)` }
+trans\_set ::= [trans_range_list](#trans_range_list) \{ `=>` [trans_range_list](#trans_range_list) }
+trans\_range\_list ::=
+ [trans_item](#trans_item)
+ \| [trans_item](#trans_item) `[*` [repeat_range](#repeat_range) ]
+ \| [trans_item](#trans_item) \[[â](#â)`€“>` [repeat_range](#repeat_range) ]
+ \| [trans_item](#trans_item) `[=` [repeat_range](#repeat_range) ]
+trans\_item ::= [covergroup_range_list](#covergroup_range_list)
+repeat\_range ::=
+ [covergroup_expression](#covergroup_expression)
+ \| [covergroup_expression](#covergroup_expression) `:` [covergroup_expression](#covergroup_expression)
+cover\_cross ::= \[ [cross_identifier](#cross_identifier) `:` ] [cross](#cross) [list_of_cross_items](#list_of_cross_items) \[ [iff](#iff) `(` [expression](#expression) `)` ] [cross_body](#cross_body)
+list\_of\_cross\_items ::= [cross_item](#cross_item) `,` [cross_item](#cross_item) \{ `,` [cross_item](#cross_item) }
+cross\_item ::=
+ [cover_point_identifier](#cover_point_identifier)
+ \| [variable_identifier](#variable_identifier)
+cross\_body ::=
+ \{ \{ [cross_body_item](#cross_body_item) } }
+ \| `;`
+cross\_body\_item ::=
+ [function_declaration](#function_declaration)
+ \| [bins_selection_or_option](#bins_selection_or_option) `;`
+bins\_selection\_or\_option ::=
+ \{ [attribute_instance](#attribute_instance) } [coverage_option](#coverage_option)
+ \| \{ [attribute_instance](#attribute_instance) } [bins_selection](#bins_selection)
+bins\_selection ::= [bins_keyword](#bins_keyword) [bin_identifier](#bin_identifier) `=` [select_expression](#select_expression) \[ [iff](#iff) `(` [expression](#expression) `)` ]
+select\_expression30 ::=
+ [select_condition](#select_condition)
+ \| `!` [select_condition](#select_condition)
+ \| [select_expression](#select_expression) `&&` [select_expression](#select_expression)
+ \| [select_expression](#select_expression) `||` [select_expression](#select_expression)
+ \| `(` [select_expression](#select_expression) `)`
+ \| [select_expression](#select_expression) [with](#with) `(` [with_covergroup_expression](#with_covergroup_expression) `)` \[ [matches](#matches) [integer_covergroup_expression](#integer_covergroup_expression) ]
+ \| [cross_identifier](#cross_identifier)
+ \| [cross_set_expression](#cross_set_expression) \[ [matches](#matches) [integer_covergroup_expression](#integer_covergroup_expression) ]
+select\_condition ::= [binsof](#binsof) `(` [bins_expression](#bins_expression) `)` \[ [intersect](#intersect) \{ [covergroup_range_list](#covergroup_range_list) } ]
+bins\_expression ::=
+ [variable_identifier](#variable_identifier)
+ \| [cover_point_identifier](#cover_point_identifier) \[ `.` [bin_identifier](#bin_identifier) ]
+covergroup\_range\_list ::= [covergroup_value_range](#covergroup_value_range) \{ `,` [covergroup_value_range](#covergroup_value_range) }
+covergroup\_value\_range ::=
+ [covergroup_expression](#covergroup_expression)
+ \| \[ [covergroup_expression](#covergroup_expression) `:` [covergroup_expression](#covergroup_expression) ]
+ \| \[ `$` `:` [covergroup_expression](#covergroup_expression) ]
+ \| \[ [covergroup_expression](#covergroup_expression) `:` `$` ]
+ \| \[ [covergroup_expression](#covergroup_expression) `+/-` [covergroup_expression](#covergroup_expression) ]
+ \| \[ [covergroup_expression](#covergroup_expression) `+%-` [covergroup_expression](#covergroup_expression) ]
+with\_covergroup\_expression ::= [covergroup_expression31](#covergroup_expression31)
+set\_covergroup\_expression ::= [covergroup_expression32](#covergroup_expression32)
+integer\_covergroup\_expression ::= [covergroup_expression](#covergroup_expression) \| `$`
+cross\_set\_expression ::= [covergroup_expression](#covergroup_expression)
+covergroup\_expression ::= [expression33](#expression33)
### A.2.12 Let declarations
-let\_declaration ::= [let](#let) [let_identifier](#let_identifier) \[ `(` \[ [let_port_list](#let_port_list) ] `)` ] `=` [expression](#expression) `;`
-let\_identifier ::= [identifier](#identifier)
-let\_port\_list ::= [let_port_item](#let_port_item) \{ `,` [let_port_item](#let_port_item) }
-let\_port\_item ::=
- \{ [attribute_instance](#attribute_instance) } [let_formal_type](#let_formal_type) [formal_port_identifier](#formal_port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [expression](#expression) ]
-let\_formal\_type ::=
- [data_type_or_implicit](#data_type_or_implicit)
- \| [untyped](#untyped)
-let\_expression ::= \[ [package_scope](#package_scope) ] [let_identifier](#let_identifier) \[ `(` \[ [let_list_of_arguments](#let_list_of_arguments) ] `)` ]
-let\_list\_of\_arguments ::=
- \[ [let_actual_arg](#let_actual_arg) ] \{ `,` \[ [let_actual_arg](#let_actual_arg) ] } \{ `,` `.` [identifier](#identifier) `(` \[ [let_actual_arg](#let_actual_arg) ] `)` }
- \| `.` [identifier](#identifier) `(` \[ [let_actual_arg](#let_actual_arg) ] `)` \{ `,` `.` [identifier](#identifier) `(` \[ [let_actual_arg](#let_actual_arg) ] `)` }
-let\_actual\_arg ::= [expression](#expression)
+let\_declaration ::= [let](#let) [let_identifier](#let_identifier) \[ `(` \[ [let_port_list](#let_port_list) ] `)` ] `=` [expression](#expression) `;`
+let\_identifier ::= [identifier](#identifier)
+let\_port\_list ::= [let_port_item](#let_port_item) \{ `,` [let_port_item](#let_port_item) }
+let\_port\_item ::=
+ \{ [attribute_instance](#attribute_instance) } [let_formal_type](#let_formal_type) [formal_port_identifier](#formal_port_identifier) \{ [variable_dimension](#variable_dimension) } \[ `=` [expression](#expression) ]
+let\_formal\_type ::=
+ [data_type_or_implicit](#data_type_or_implicit)
+ \| [untyped](#untyped)
+let\_expression ::= \[ [package_scope](#package_scope) ] [let_identifier](#let_identifier) \[ `(` \[ [let_list_of_arguments](#let_list_of_arguments) ] `)` ]
+let\_list\_of\_arguments ::=
+ \[ [let_actual_arg](#let_actual_arg) ] \{ `,` \[ [let_actual_arg](#let_actual_arg) ] } \{ `,` `.` [identifier](#identifier) `(` \[ [let_actual_arg](#let_actual_arg) ] `)` }
+ \| `.` [identifier](#identifier) `(` \[ [let_actual_arg](#let_actual_arg) ] `)` \{ `,` `.` [identifier](#identifier) `(` \[ [let_actual_arg](#let_actual_arg) ] `)` }
+let\_actual\_arg ::= [expression](#expression)
## A.3 Primitive instances
### A.3.1 Primitive instantiation and instances
-gate\_instantiation ::=
- [cmos_switchtype](#cmos_switchtype) \[ [delay3](#delay3) ] [cmos_switch_instance](#cmos_switch_instance) \{ `,` [cmos_switch_instance](#cmos_switch_instance) } `;`
- \| [mos_switchtype](#mos_switchtype) \[ [delay3](#delay3) ] [mos_switch_instance](#mos_switch_instance) \{ `,` [mos_switch_instance](#mos_switch_instance) } `;`
- \| [enable_gatetype](#enable_gatetype) \[ [drive_strength](#drive_strength) ] \[ [delay3](#delay3) ] [enable_gate_instance](#enable_gate_instance) \{ `,` [enable_gate_instance](#enable_gate_instance) } `;`
- \| [n_input_gatetype](#n_input_gatetype) \[ [drive_strength](#drive_strength) ] \[ [delay2](#delay2) ] [n_input_gate_instance](#n_input_gate_instance) \{ `,` [n_input_gate_instance](#n_input_gate_instance) } `;`
- \| [n_output_gatetype](#n_output_gatetype) \[ [drive_strength](#drive_strength) ] \[ [delay2](#delay2) ] [n_output_gate_instance](#n_output_gate_instance) \{ `,` [n_output_gate_instance](#n_output_gate_instance) } `;`
- \| [pass_en_switchtype](#pass_en_switchtype) \[ [delay2](#delay2) ] [pass_enable_switch_instance](#pass_enable_switch_instance) \{ `,` [pass_enable_switch_instance](#pass_enable_switch_instance) } `;`
- \| [pass_switchtype](#pass_switchtype) [pass_switch_instance](#pass_switch_instance) \{ `,` [pass_switch_instance](#pass_switch_instance) } `;`
- \| [pulldown](#pulldown) \[ [pulldown_strength](#pulldown_strength) ] [pull_gate_instance](#pull_gate_instance) \{ `,` [pull_gate_instance](#pull_gate_instance) } `;`
- \| [pullup](#pullup) \[ [pullup_strength](#pullup_strength) ] [pull_gate_instance](#pull_gate_instance) \{ `,` [pull_gate_instance](#pull_gate_instance) } `;`
-cmos\_switch\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [output_terminal](#output_terminal) `,` [input_terminal](#input_terminal) `,`
- [ncontrol_terminal](#ncontrol_terminal) `,` [pcontrol_terminal](#pcontrol_terminal) `)`
-enable\_gate\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [output_terminal](#output_terminal) `,` [input_terminal](#input_terminal) `,` [enable_terminal](#enable_terminal) `)`
-mos\_switch\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [output_terminal](#output_terminal) `,` [input_terminal](#input_terminal) `,` [enable_terminal](#enable_terminal) `)`
-n\_input\_gate\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [output_terminal](#output_terminal) `,` [input_terminal](#input_terminal) \{ `,` [input_terminal](#input_terminal) } `)`
-n\_output\_gate\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [output_terminal](#output_terminal) \{ `,` [output_terminal](#output_terminal) } `,`
- [input_terminal](#input_terminal) `)`
-pass\_switch\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [inout_terminal](#inout_terminal) `,` [inout_terminal](#inout_terminal) `)`
-pass\_enable\_switch\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [inout_terminal](#inout_terminal) `,` [inout_terminal](#inout_terminal) `,`
- [enable_terminal](#enable_terminal) `)`
-pull\_gate\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [output_terminal](#output_terminal) `)`
+gate\_instantiation ::=
+ [cmos_switchtype](#cmos_switchtype) \[ [delay3](#delay3) ] [cmos_switch_instance](#cmos_switch_instance) \{ `,` [cmos_switch_instance](#cmos_switch_instance) } `;`
+ \| [mos_switchtype](#mos_switchtype) \[ [delay3](#delay3) ] [mos_switch_instance](#mos_switch_instance) \{ `,` [mos_switch_instance](#mos_switch_instance) } `;`
+ \| [enable_gatetype](#enable_gatetype) \[ [drive_strength](#drive_strength) ] \[ [delay3](#delay3) ] [enable_gate_instance](#enable_gate_instance) \{ `,` [enable_gate_instance](#enable_gate_instance) } `;`
+ \| [n_input_gatetype](#n_input_gatetype) \[ [drive_strength](#drive_strength) ] \[ [delay2](#delay2) ] [n_input_gate_instance](#n_input_gate_instance) \{ `,` [n_input_gate_instance](#n_input_gate_instance) } `;`
+ \| [n_output_gatetype](#n_output_gatetype) \[ [drive_strength](#drive_strength) ] \[ [delay2](#delay2) ] [n_output_gate_instance](#n_output_gate_instance) \{ `,` [n_output_gate_instance](#n_output_gate_instance) } `;`
+ \| [pass_en_switchtype](#pass_en_switchtype) \[ [delay2](#delay2) ] [pass_enable_switch_instance](#pass_enable_switch_instance) \{ `,` [pass_enable_switch_instance](#pass_enable_switch_instance) } `;`
+ \| [pass_switchtype](#pass_switchtype) [pass_switch_instance](#pass_switch_instance) \{ `,` [pass_switch_instance](#pass_switch_instance) } `;`
+ \| [pulldown](#pulldown) \[ [pulldown_strength](#pulldown_strength) ] [pull_gate_instance](#pull_gate_instance) \{ `,` [pull_gate_instance](#pull_gate_instance) } `;`
+ \| [pullup](#pullup) \[ [pullup_strength](#pullup_strength) ] [pull_gate_instance](#pull_gate_instance) \{ `,` [pull_gate_instance](#pull_gate_instance) } `;`
+cmos\_switch\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [output_terminal](#output_terminal) `,` [input_terminal](#input_terminal) `,`
+ [ncontrol_terminal](#ncontrol_terminal) `,` [pcontrol_terminal](#pcontrol_terminal) `)`
+enable\_gate\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [output_terminal](#output_terminal) `,` [input_terminal](#input_terminal) `,` [enable_terminal](#enable_terminal) `)`
+mos\_switch\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [output_terminal](#output_terminal) `,` [input_terminal](#input_terminal) `,` [enable_terminal](#enable_terminal) `)`
+n\_input\_gate\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [output_terminal](#output_terminal) `,` [input_terminal](#input_terminal) \{ `,` [input_terminal](#input_terminal) } `)`
+n\_output\_gate\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [output_terminal](#output_terminal) \{ `,` [output_terminal](#output_terminal) } `,`
+ [input_terminal](#input_terminal) `)`
+pass\_switch\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [inout_terminal](#inout_terminal) `,` [inout_terminal](#inout_terminal) `)`
+pass\_enable\_switch\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [inout_terminal](#inout_terminal) `,` [inout_terminal](#inout_terminal) `,`
+ [enable_terminal](#enable_terminal) `)`
+pull\_gate\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [output_terminal](#output_terminal) `)`
### A.3.2 Primitive strengths
-pulldown\_strength ::=
- `(` [strength0](#strength0) `,` [strength1](#strength1) `)`
- \| `(` [strength1](#strength1) `,` [strength0](#strength0) `)`
- \| `(` [strength0](#strength0) `)`
-pullup\_strength ::=
- `(` [strength0](#strength0) `,` [strength1](#strength1) `)`
- \| `(` [strength1](#strength1) `,` [strength0](#strength0) `)`
- \| `(` [strength1](#strength1) `)`
+pulldown\_strength ::=
+ `(` [strength0](#strength0) `,` [strength1](#strength1) `)`
+ \| `(` [strength1](#strength1) `,` [strength0](#strength0) `)`
+ \| `(` [strength0](#strength0) `)`
+pullup\_strength ::=
+ `(` [strength0](#strength0) `,` [strength1](#strength1) `)`
+ \| `(` [strength1](#strength1) `,` [strength0](#strength0) `)`
+ \| `(` [strength1](#strength1) `)`
### A.3.3 Primitive terminals
-enable\_terminal ::= [expression](#expression)
-inout\_terminal ::= [net_lvalue](#net_lvalue)
-input\_terminal ::= [expression](#expression)
-ncontrol\_terminal ::= [expression](#expression)
-output\_terminal ::= [net_lvalue](#net_lvalue)
-pcontrol\_terminal ::= [expression](#expression)
+enable\_terminal ::= [expression](#expression)
+inout\_terminal ::= [net_lvalue](#net_lvalue)
+input\_terminal ::= [expression](#expression)
+ncontrol\_terminal ::= [expression](#expression)
+output\_terminal ::= [net_lvalue](#net_lvalue)
+pcontrol\_terminal ::= [expression](#expression)
### A.3.4 Primitive gate and switch types
-cmos\_switchtype ::= [cmos](#cmos) \| [rcmos](#rcmos)
-enable\_gatetype ::= [bufif0](#bufif0) \| [bufif1](#bufif1) \| [notif0](#notif0) \| [notif1](#notif1)
-mos\_switchtype ::= [nmos](#nmos) \| [pmos](#pmos) \| [rnmos](#rnmos) \| [rpmos](#rpmos)
-n\_input\_gatetype ::= [and](#and) \| [nand](#nand) \| [or](#or) \| [nor](#nor) \| [xor](#xor) \| [xnor](#xnor)
-n\_output\_gatetype ::= [buf](#buf) \| [not](#not)
-pass\_en\_switchtype ::= [tranif0](#tranif0) \| [tranif1](#tranif1) \| [rtranif1](#rtranif1) \| [rtranif0](#rtranif0)
-pass\_switchtype ::= [tran](#tran) \| [rtran](#rtran)
+cmos\_switchtype ::= [cmos](#cmos) \| [rcmos](#rcmos)
+enable\_gatetype ::= [bufif0](#bufif0) \| [bufif1](#bufif1) \| [notif0](#notif0) \| [notif1](#notif1)
+mos\_switchtype ::= [nmos](#nmos) \| [pmos](#pmos) \| [rnmos](#rnmos) \| [rpmos](#rpmos)
+n\_input\_gatetype ::= [and](#and) \| [nand](#nand) \| [or](#or) \| [nor](#nor) \| [xor](#xor) \| [xnor](#xnor)
+n\_output\_gatetype ::= [buf](#buf) \| [not](#not)
+pass\_en\_switchtype ::= [tranif0](#tranif0) \| [tranif1](#tranif1) \| [rtranif1](#rtranif1) \| [rtranif0](#rtranif0)
+pass\_switchtype ::= [tran](#tran) \| [rtran](#rtran)
## A.4 Instantiations
### A.4.1 Instantiation
#### A.4.1.1 Module instantiation
-module\_instantiation ::=
- [module_identifier](#module_identifier) \[ [parameter_value_assignment](#parameter_value_assignment) ] [hierarchical_instance](#hierarchical_instance) \{ `,` [hierarchical_instance](#hierarchical_instance) } `;`
-parameter\_value\_assignment ::= `#` `(` \[ [list_of_parameter_value_assignments](#list_of_parameter_value_assignments) ] `)`
-list\_of\_parameter\_value\_assignments ::=
- [ordered_parameter_assignment](#ordered_parameter_assignment) \{ `,` [ordered_parameter_assignment](#ordered_parameter_assignment) }
- \| [named_parameter_assignment](#named_parameter_assignment) \{ `,` [named_parameter_assignment](#named_parameter_assignment) }
-ordered\_parameter\_assignment ::= [param_expression](#param_expression)
-named\_parameter\_assignment ::= `.` [parameter_identifier](#parameter_identifier) `(` \[ [param_expression](#param_expression) ] `)`
-hierarchical\_instance ::= [name_of_instance](#name_of_instance) `(` \[ [list_of_port_connections](#list_of_port_connections) ] `)`
-name\_of\_instance ::= [instance_identifier](#instance_identifier) \{ [unpacked_dimension](#unpacked_dimension) }
-list\_of\_port\_connections34 ::=
- [ordered_port_connection](#ordered_port_connection) \{ `,` [ordered_port_connection](#ordered_port_connection) }
- \| [named_port_connection](#named_port_connection) \{ `,` [named_port_connection](#named_port_connection) }
-ordered\_port\_connection ::= \{ [attribute_instance](#attribute_instance) } \[ [expression](#expression) ]
-named\_port\_connection ::=
- \{ [attribute_instance](#attribute_instance) } `.` [port_identifier](#port_identifier) \[ `(` \[ [expression](#expression) ] `)` ]
- \| \{ [attribute_instance](#attribute_instance) } `.` `*`
+module\_instantiation ::=
+ [module_identifier](#module_identifier) \[ [parameter_value_assignment](#parameter_value_assignment) ] [hierarchical_instance](#hierarchical_instance) \{ `,` [hierarchical_instance](#hierarchical_instance) } `;`
+parameter\_value\_assignment ::= `#` `(` \[ [list_of_parameter_value_assignments](#list_of_parameter_value_assignments) ] `)`
+list\_of\_parameter\_value\_assignments ::=
+ [ordered_parameter_assignment](#ordered_parameter_assignment) \{ `,` [ordered_parameter_assignment](#ordered_parameter_assignment) }
+ \| [named_parameter_assignment](#named_parameter_assignment) \{ `,` [named_parameter_assignment](#named_parameter_assignment) }
+ordered\_parameter\_assignment ::= [param_expression](#param_expression)
+named\_parameter\_assignment ::= `.` [parameter_identifier](#parameter_identifier) `(` \[ [param_expression](#param_expression) ] `)`
+hierarchical\_instance ::= [name_of_instance](#name_of_instance) `(` \[ [list_of_port_connections](#list_of_port_connections) ] `)`
+name\_of\_instance ::= [instance_identifier](#instance_identifier) \{ [unpacked_dimension](#unpacked_dimension) }
+list\_of\_port\_connections34 ::=
+ [ordered_port_connection](#ordered_port_connection) \{ `,` [ordered_port_connection](#ordered_port_connection) }
+ \| [named_port_connection](#named_port_connection) \{ `,` [named_port_connection](#named_port_connection) }
+ordered\_port\_connection ::= \{ [attribute_instance](#attribute_instance) } \[ [expression](#expression) ]
+named\_port\_connection ::=
+ \{ [attribute_instance](#attribute_instance) } `.` [port_identifier](#port_identifier) \[ `(` \[ [expression](#expression) ] `)` ]
+ \| \{ [attribute_instance](#attribute_instance) } `.` `*`
#### A.4.1.2 Interface instantiation
-interface\_instantiation ::=
- [interface_identifier](#interface_identifier) \[ [parameter_value_assignment](#parameter_value_assignment) ] [hierarchical_instance](#hierarchical_instance) \{ `,` [hierarchical_instance](#hierarchical_instance) } `;`
+interface\_instantiation ::=
+ [interface_identifier](#interface_identifier) \[ [parameter_value_assignment](#parameter_value_assignment) ] [hierarchical_instance](#hierarchical_instance) \{ `,` [hierarchical_instance](#hierarchical_instance) } `;`
#### A.4.1.3 Program instantiation
-program\_instantiation ::=
- [program_identifier](#program_identifier) \[ [parameter_value_assignment](#parameter_value_assignment) ] [hierarchical_instance](#hierarchical_instance) \{ `,` [hierarchical_instance](#hierarchical_instance) } `;`
+program\_instantiation ::=
+ [program_identifier](#program_identifier) \[ [parameter_value_assignment](#parameter_value_assignment) ] [hierarchical_instance](#hierarchical_instance) \{ `,` [hierarchical_instance](#hierarchical_instance) } `;`
#### A.4.1.4 Checker instantiation
-checker\_instantiation ::=
- [ps_checker_identifier](#ps_checker_identifier) [name_of_instance](#name_of_instance) `(` \[ [list_of_checker_port_connections](#list_of_checker_port_connections) ] `)` `;`
-list\_of\_checker\_port\_connections34 ::=
- [ordered_checker_port_connection](#ordered_checker_port_connection) \{ `,` [ordered_checker_port_connection](#ordered_checker_port_connection) }
- \| [named_checker_port_connection](#named_checker_port_connection) \{ `,` [named_checker_port_connection](#named_checker_port_connection) }
-ordered\_checker\_port\_connection ::= \{ [attribute_instance](#attribute_instance) } \[ [property_actual_arg](#property_actual_arg) ]
-named\_checker\_port\_connection ::=
- \{ [attribute_instance](#attribute_instance) } `.` [formal_port_identifier](#formal_port_identifier) \[ `(` \[ [property_actual_arg](#property_actual_arg) ] `)` ]
- \| \{ [attribute_instance](#attribute_instance) } `.` `*`
+checker\_instantiation ::=
+ [ps_checker_identifier](#ps_checker_identifier) [name_of_instance](#name_of_instance) `(` \[ [list_of_checker_port_connections](#list_of_checker_port_connections) ] `)` `;`
+list\_of\_checker\_port\_connections34 ::=
+ [ordered_checker_port_connection](#ordered_checker_port_connection) \{ `,` [ordered_checker_port_connection](#ordered_checker_port_connection) }
+ \| [named_checker_port_connection](#named_checker_port_connection) \{ `,` [named_checker_port_connection](#named_checker_port_connection) }
+ordered\_checker\_port\_connection ::= \{ [attribute_instance](#attribute_instance) } \[ [property_actual_arg](#property_actual_arg) ]
+named\_checker\_port\_connection ::=
+ \{ [attribute_instance](#attribute_instance) } `.` [formal_port_identifier](#formal_port_identifier) \[ `(` \[ [property_actual_arg](#property_actual_arg) ] `)` ]
+ \| \{ [attribute_instance](#attribute_instance) } `.` `*`
### A.4.2 Generated instantiation
-generate\_region ::= [generate](#generate) \{ [generate_item](#generate_item) } [endgenerate](#endgenerate)
-loop\_generate\_construct ::=
- [for](#for) `(` [genvar_initialization](#genvar_initialization) `;` [genvar_expression](#genvar_expression) `;` [genvar_iteration](#genvar_iteration) `)` [generate_block](#generate_block)
-genvar\_initialization ::= \[ [genvar](#genvar) ] [genvar_identifier](#genvar_identifier) `=` [constant_expression](#constant_expression)
-genvar\_iteration ::=
- [genvar_identifier](#genvar_identifier) [assignment_operator](#assignment_operator) [genvar_expression](#genvar_expression)
- \| [inc_or_dec_operator](#inc_or_dec_operator) [genvar_identifier](#genvar_identifier)
- \| [genvar_identifier](#genvar_identifier) [inc_or_dec_operator](#inc_or_dec_operator)
-conditional\_generate\_construct ::=
- [if_generate_construct](#if_generate_construct)
- \| [case_generate_construct](#case_generate_construct)
-if\_generate\_construct ::= [if](#if) `(` [constant_expression](#constant_expression) `)` [generate_block](#generate_block) \[ [else](#else) [generate_block](#generate_block) ]
-case\_generate\_construct ::=
- [case](#case) `(` [constant_expression](#constant_expression) `)` [case_generate_item](#case_generate_item) \{ [case_generate_item](#case_generate_item) } [endcase](#endcase)
-case\_generate\_item ::=
- [constant_expression](#constant_expression) \{ `,` [constant_expression](#constant_expression) } `:` [generate_block](#generate_block)
- \| [default](#default) \[ `:` ] [generate_block](#generate_block)
-generate\_block ::=
- [generate_item](#generate_item)
- \| \[ [generate_block_identifier](#generate_block_identifier) `:` ] [begin](#begin) \[ `:` [generate_block_identifier](#generate_block_identifier) ]
- \{ [generate_item](#generate_item) }
- [end](#end) \[ `:` [generate_block_identifier](#generate_block_identifier) ]
-generate\_item35 ::=
- [module_or_generate_item](#module_or_generate_item)
- \| [interface_or_generate_item](#interface_or_generate_item)
- \| [checker_or_generate_item](#checker_or_generate_item)
+generate\_region ::= [generate](#generate) \{ [generate_item](#generate_item) } [endgenerate](#endgenerate)
+loop\_generate\_construct ::=
+ [for](#for) `(` [genvar_initialization](#genvar_initialization) `;` [genvar_expression](#genvar_expression) `;` [genvar_iteration](#genvar_iteration) `)` [generate_block](#generate_block)
+genvar\_initialization ::= \[ [genvar](#genvar) ] [genvar_identifier](#genvar_identifier) `=` [constant_expression](#constant_expression)
+genvar\_iteration ::=
+ [genvar_identifier](#genvar_identifier) [assignment_operator](#assignment_operator) [genvar_expression](#genvar_expression)
+ \| [inc_or_dec_operator](#inc_or_dec_operator) [genvar_identifier](#genvar_identifier)
+ \| [genvar_identifier](#genvar_identifier) [inc_or_dec_operator](#inc_or_dec_operator)
+conditional\_generate\_construct ::=
+ [if_generate_construct](#if_generate_construct)
+ \| [case_generate_construct](#case_generate_construct)
+if\_generate\_construct ::= [if](#if) `(` [constant_expression](#constant_expression) `)` [generate_block](#generate_block) \[ [else](#else) [generate_block](#generate_block) ]
+case\_generate\_construct ::=
+ [case](#case) `(` [constant_expression](#constant_expression) `)` [case_generate_item](#case_generate_item) \{ [case_generate_item](#case_generate_item) } [endcase](#endcase)
+case\_generate\_item ::=
+ [constant_expression](#constant_expression) \{ `,` [constant_expression](#constant_expression) } `:` [generate_block](#generate_block)
+ \| [default](#default) \[ `:` ] [generate_block](#generate_block)
+generate\_block ::=
+ [generate_item](#generate_item)
+ \| \[ [generate_block_identifier](#generate_block_identifier) `:` ] [begin](#begin) \[ `:` [generate_block_identifier](#generate_block_identifier) ]
+ \{ [generate_item](#generate_item) }
+ [end](#end) \[ `:` [generate_block_identifier](#generate_block_identifier) ]
+generate\_item35 ::=
+ [module_or_generate_item](#module_or_generate_item)
+ \| [interface_or_generate_item](#interface_or_generate_item)
+ \| [checker_or_generate_item](#checker_or_generate_item)
## A.5 UDP declaration and instantiation
### A.5.1 UDP declaration
-udp\_nonansi\_declaration ::= \{ [attribute_instance](#attribute_instance) } [primitive](#primitive) [udp_identifier](#udp_identifier) `(` [udp_port_list](#udp_port_list) `)` `;`
-udp\_ansi\_declaration ::= \{ [attribute_instance](#attribute_instance) } [primitive](#primitive) [udp_identifier](#udp_identifier) `(` [udp_declaration_port_list](#udp_declaration_port_list) `)` `;`
-udp\_declaration ::=
- [udp_nonansi_declaration](#udp_nonansi_declaration) [udp_port_declaration](#udp_port_declaration) \{ [udp_port_declaration](#udp_port_declaration) }
- [udp_body](#udp_body)
- [endprimitive](#endprimitive) \[ `:` [udp_identifier](#udp_identifier) ]
- \| [udp_ansi_declaration](#udp_ansi_declaration)
- [udp_body](#udp_body)
- [endprimitive](#endprimitive) \[ `:` [udp_identifier](#udp_identifier) ]
- \| [extern](#extern) [udp_nonansi_declaration](#udp_nonansi_declaration)
- \| [extern](#extern) [udp_ansi_declaration](#udp_ansi_declaration)
- \| \{ [attribute_instance](#attribute_instance) } [primitive](#primitive) [udp_identifier](#udp_identifier) `(` `.` `*` `)` `;`
- \{ [udp_port_declaration](#udp_port_declaration) }
- [udp_body](#udp_body)
- [endprimitive](#endprimitive) \[ `:` [udp_identifier](#udp_identifier) ]
+udp\_nonansi\_declaration ::= \{ [attribute_instance](#attribute_instance) } [primitive](#primitive) [udp_identifier](#udp_identifier) `(` [udp_port_list](#udp_port_list) `)` `;`
+udp\_ansi\_declaration ::= \{ [attribute_instance](#attribute_instance) } [primitive](#primitive) [udp_identifier](#udp_identifier) `(` [udp_declaration_port_list](#udp_declaration_port_list) `)` `;`
+udp\_declaration ::=
+ [udp_nonansi_declaration](#udp_nonansi_declaration) [udp_port_declaration](#udp_port_declaration) \{ [udp_port_declaration](#udp_port_declaration) }
+ [udp_body](#udp_body)
+ [endprimitive](#endprimitive) \[ `:` [udp_identifier](#udp_identifier) ]
+ \| [udp_ansi_declaration](#udp_ansi_declaration)
+ [udp_body](#udp_body)
+ [endprimitive](#endprimitive) \[ `:` [udp_identifier](#udp_identifier) ]
+ \| [extern](#extern) [udp_nonansi_declaration](#udp_nonansi_declaration)
+ \| [extern](#extern) [udp_ansi_declaration](#udp_ansi_declaration)
+ \| \{ [attribute_instance](#attribute_instance) } [primitive](#primitive) [udp_identifier](#udp_identifier) `(` `.` `*` `)` `;`
+ \{ [udp_port_declaration](#udp_port_declaration) }
+ [udp_body](#udp_body)
+ [endprimitive](#endprimitive) \[ `:` [udp_identifier](#udp_identifier) ]
### A.5.2 UDP ports
-udp\_port\_list ::= [output_port_identifier](#output_port_identifier) `,` [input_port_identifier](#input_port_identifier) \{ `,` [input_port_identifier](#input_port_identifier) }
-udp\_declaration\_port\_list ::= [udp_output_declaration](#udp_output_declaration) `,` [udp_input_declaration](#udp_input_declaration) \{ `,` [udp_input_declaration](#udp_input_declaration) }
-udp\_port\_declaration ::=
- [udp_output_declaration](#udp_output_declaration) `;`
- \| [udp_input_declaration](#udp_input_declaration) `;`
- \| [udp_reg_declaration](#udp_reg_declaration) `;`
-udp\_output\_declaration ::=
- \{ [attribute_instance](#attribute_instance) } [output](#output) [port_identifier](#port_identifier)
- \| \{ [attribute_instance](#attribute_instance) } [output](#output) [reg](#reg) [port_identifier](#port_identifier) \[ `=` [constant_expression](#constant_expression) ]
-udp\_input\_declaration ::= \{ [attribute_instance](#attribute_instance) } [input](#input) [list_of_udp_port_identifiers](#list_of_udp_port_identifiers)
-udp\_reg\_declaration ::= \{ [attribute_instance](#attribute_instance) } [reg](#reg) [variable_identifier](#variable_identifier)
+udp\_port\_list ::= [output_port_identifier](#output_port_identifier) `,` [input_port_identifier](#input_port_identifier) \{ `,` [input_port_identifier](#input_port_identifier) }
+udp\_declaration\_port\_list ::= [udp_output_declaration](#udp_output_declaration) `,` [udp_input_declaration](#udp_input_declaration) \{ `,` [udp_input_declaration](#udp_input_declaration) }
+udp\_port\_declaration ::=
+ [udp_output_declaration](#udp_output_declaration) `;`
+ \| [udp_input_declaration](#udp_input_declaration) `;`
+ \| [udp_reg_declaration](#udp_reg_declaration) `;`
+udp\_output\_declaration ::=
+ \{ [attribute_instance](#attribute_instance) } [output](#output) [port_identifier](#port_identifier)
+ \| \{ [attribute_instance](#attribute_instance) } [output](#output) [reg](#reg) [port_identifier](#port_identifier) \[ `=` [constant_expression](#constant_expression) ]
+udp\_input\_declaration ::= \{ [attribute_instance](#attribute_instance) } [input](#input) [list_of_udp_port_identifiers](#list_of_udp_port_identifiers)
+udp\_reg\_declaration ::= \{ [attribute_instance](#attribute_instance) } [reg](#reg) [variable_identifier](#variable_identifier)
### A.5.3 UDP body
-udp\_body ::=
- [combinational_body](#combinational_body)
- \| [sequential_body](#sequential_body)
-combinational\_body ::= [table](#table) [combinational_entry](#combinational_entry) \{ [combinational_entry](#combinational_entry) } [endtable](#endtable)
-combinational\_entry ::= [level_input_list](#level_input_list) `:` [output_symbol](#output_symbol) `;`
-sequential\_body ::= \[ [udp_initial_statement](#udp_initial_statement) ] [table](#table) [sequential_entry](#sequential_entry) \{ [sequential_entry](#sequential_entry) } [endtable](#endtable)
-udp\_initial\_statement ::= [initial](#initial) [output_port_identifier](#output_port_identifier) `=` [init_val](#init_val) `;`
-init\_val ::= [1](#1)`'`[b0](#b0) \| [1](#1)`'`[b1](#b1) \| [1](#1)`'`[bx](#bx) \| [1](#1)`'`[bX](#bX) \| [1](#1)`'`[B0](#B0) \| [1](#1)`'`[B1](#B1) \| [1](#1)`'`[Bx](#Bx) \| [1](#1)`'`[BX](#BX) \| [1](#1) \| [0](#0)
-sequential\_entry ::= [seq_input_list](#seq_input_list) `:` [current_state](#current_state) `:` [next_state](#next_state) `;`
-seq\_input\_list ::=
- [level_input_list](#level_input_list)
- \| [edge_input_list](#edge_input_list)
-level\_input\_list ::= [level_symbol](#level_symbol) \{ [level_symbol](#level_symbol) }
-edge\_input\_list ::= \{ [level_symbol](#level_symbol) } [edge_indicator](#edge_indicator) \{ [level_symbol](#level_symbol) }
-edge\_indicator ::= `(` [level_symbol](#level_symbol) [level_symbol](#level_symbol) `)` \| [edge_symbol](#edge_symbol)
-current\_state ::= [level_symbol](#level_symbol)
-next\_state ::=
- [output_symbol](#output_symbol)
- \| `-`
-output\_symbol ::= [0](#0) \| [1](#1) \| [x](#x) \| [X](#X)
-level\_symbol ::= [0](#0) \| [1](#1) \| [x](#x) \| [X](#X) \| `?` \| [b](#b) \| [B](#B)
-edge\_symbol ::= [r](#r) \| [R](#R) \| [f](#f) \| [F](#F) \| [p](#p) \| [P](#P) \| [n](#n) \| [N](#N) \| `*`
+udp\_body ::=
+ [combinational_body](#combinational_body)
+ \| [sequential_body](#sequential_body)
+combinational\_body ::= [table](#table) [combinational_entry](#combinational_entry) \{ [combinational_entry](#combinational_entry) } [endtable](#endtable)
+combinational\_entry ::= [level_input_list](#level_input_list) `:` [output_symbol](#output_symbol) `;`
+sequential\_body ::= \[ [udp_initial_statement](#udp_initial_statement) ] [table](#table) [sequential_entry](#sequential_entry) \{ [sequential_entry](#sequential_entry) } [endtable](#endtable)
+udp\_initial\_statement ::= [initial](#initial) [output_port_identifier](#output_port_identifier) `=` [init_val](#init_val) `;`
+init\_val ::= [1](#1)`'`[b0](#b0) \| [1](#1)`'`[b1](#b1) \| [1](#1)`'`[bx](#bx) \| [1](#1)`'`[bX](#bX) \| [1](#1)`'`[B0](#B0) \| [1](#1)`'`[B1](#B1) \| [1](#1)`'`[Bx](#Bx) \| [1](#1)`'`[BX](#BX) \| [1](#1) \| [0](#0)
+sequential\_entry ::= [seq_input_list](#seq_input_list) `:` [current_state](#current_state) `:` [next_state](#next_state) `;`
+seq\_input\_list ::=
+ [level_input_list](#level_input_list)
+ \| [edge_input_list](#edge_input_list)
+level\_input\_list ::= [level_symbol](#level_symbol) \{ [level_symbol](#level_symbol) }
+edge\_input\_list ::= \{ [level_symbol](#level_symbol) } [edge_indicator](#edge_indicator) \{ [level_symbol](#level_symbol) }
+edge\_indicator ::= `(` [level_symbol](#level_symbol) [level_symbol](#level_symbol) `)` \| [edge_symbol](#edge_symbol)
+current\_state ::= [level_symbol](#level_symbol)
+next\_state ::=
+ [output_symbol](#output_symbol)
+ \| `-`
+output\_symbol ::= [0](#0) \| [1](#1) \| [x](#x) \| [X](#X)
+level\_symbol ::= [0](#0) \| [1](#1) \| [x](#x) \| [X](#X) \| `?` \| [b](#b) \| [B](#B)
+edge\_symbol ::= [r](#r) \| [R](#R) \| [f](#f) \| [F](#F) \| [p](#p) \| [P](#P) \| [n](#n) \| [N](#N) \| `*`
### A.5.4 UDP instantiation
-udp\_instantiation ::= [udp_identifier](#udp_identifier) \[ [drive_strength](#drive_strength) ] \[ [delay2](#delay2) ] [udp_instance](#udp_instance) \{ `,` [udp_instance](#udp_instance) } `;`
-udp\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [output_terminal](#output_terminal) `,` [input_terminal](#input_terminal) \{ `,` [input_terminal](#input_terminal) } `)`
+udp\_instantiation ::= [udp_identifier](#udp_identifier) \[ [drive_strength](#drive_strength) ] \[ [delay2](#delay2) ] [udp_instance](#udp_instance) \{ `,` [udp_instance](#udp_instance) } `;`
+udp\_instance ::= \[ [name_of_instance](#name_of_instance) ] `(` [output_terminal](#output_terminal) `,` [input_terminal](#input_terminal) \{ `,` [input_terminal](#input_terminal) } `)`
## A.6 Behavioral statements
### A.6.1 Continuous assignment and net alias statements
-continuous\_assign ::=
- [assign](#assign) \[ [drive_strength](#drive_strength) ] \[ [delay3](#delay3) ] [list_of_net_assignments](#list_of_net_assignments) `;`
- \| [assign](#assign) \[ [delay_control](#delay_control) ] [list_of_variable_assignments](#list_of_variable_assignments) `;`
-list\_of\_net\_assignments ::= [net_assignment](#net_assignment) \{ `,` [net_assignment](#net_assignment) }
-list\_of\_variable\_assignments ::= [variable_assignment](#variable_assignment) \{ `,` [variable_assignment](#variable_assignment) }
-net\_alias ::= [alias](#alias) [net_lvalue](#net_lvalue) `=` [net_lvalue](#net_lvalue) \{ `=` [net_lvalue](#net_lvalue) } `;`
-net\_assignment ::= [net_lvalue](#net_lvalue) `=` [expression](#expression)
+continuous\_assign ::=
+ [assign](#assign) \[ [drive_strength](#drive_strength) ] \[ [delay3](#delay3) ] [list_of_net_assignments](#list_of_net_assignments) `;`
+ \| [assign](#assign) \[ [delay_control](#delay_control) ] [list_of_variable_assignments](#list_of_variable_assignments) `;`
+list\_of\_net\_assignments ::= [net_assignment](#net_assignment) \{ `,` [net_assignment](#net_assignment) }
+list\_of\_variable\_assignments ::= [variable_assignment](#variable_assignment) \{ `,` [variable_assignment](#variable_assignment) }
+net\_alias ::= [alias](#alias) [net_lvalue](#net_lvalue) `=` [net_lvalue](#net_lvalue) \{ `=` [net_lvalue](#net_lvalue) } `;`
+net\_assignment ::= [net_lvalue](#net_lvalue) `=` [expression](#expression)
### A.6.2 Procedural blocks and assignments
-initial\_construct ::= [initial](#initial) [statement_or_null](#statement_or_null)
-always\_construct ::= [always_keyword](#always_keyword) [statement](#statement)
-always\_keyword ::= [always](#always) \| [always_comb](#always_comb) \| [always_latch](#always_latch) \| [always_ff](#always_ff)
-final\_construct ::= [final](#final) [function_statement](#function_statement)
-blocking\_assignment ::=
- [variable_lvalue](#variable_lvalue) `=` [delay_or_event_control](#delay_or_event_control) [expression](#expression)
- \| [nonrange_variable_lvalue](#nonrange_variable_lvalue) `=` [dynamic_array_new](#dynamic_array_new)
- \| \[ [implicit_class_handle](#implicit_class_handle) `.` \| [class_scope](#class_scope) \| [package_scope](#package_scope) ] [hierarchical_variable_identifier](#hierarchical_variable_identifier)
- [select](#select) `=` [class_new](#class_new)
- \| [operator_assignment](#operator_assignment)
- \| [inc_or_dec_expression](#inc_or_dec_expression)
-operator\_assignment ::= [variable_lvalue](#variable_lvalue) [assignment_operator](#assignment_operator) [expression](#expression)
-assignment\_operator ::= `=` \| `+=` \| `-=` \| `*=` \| `/=` \| `%=` \| `&=` \| `|=` \| `^=` \| `<<=` \| `>>=` \| `<<<=` \| `>>>=`
-nonblocking\_assignment ::= [variable_lvalue](#variable_lvalue) `<=` \[ [delay_or_event_control](#delay_or_event_control) ] [expression](#expression)
-procedural\_continuous\_assignment ::=
- [assign](#assign) [variable_assignment](#variable_assignment)
- \| [deassign](#deassign) [variable_lvalue](#variable_lvalue)
- \| [force](#force) [variable_assignment](#variable_assignment)
- \| [force](#force) [net_assignment](#net_assignment)
- \| [release](#release) [variable_lvalue](#variable_lvalue)
- \| [release](#release) [net_lvalue](#net_lvalue)
-variable\_assignment ::= [variable_lvalue](#variable_lvalue) `=` [expression](#expression)
+initial\_construct ::= [initial](#initial) [statement_or_null](#statement_or_null)
+always\_construct ::= [always_keyword](#always_keyword) [statement](#statement)
+always\_keyword ::= [always](#always) \| [always_comb](#always_comb) \| [always_latch](#always_latch) \| [always_ff](#always_ff)
+final\_construct ::= [final](#final) [function_statement](#function_statement)
+blocking\_assignment ::=
+ [variable_lvalue](#variable_lvalue) `=` [delay_or_event_control](#delay_or_event_control) [expression](#expression)
+ \| [nonrange_variable_lvalue](#nonrange_variable_lvalue) `=` [dynamic_array_new](#dynamic_array_new)
+ \| \[ [implicit_class_handle](#implicit_class_handle) `.` \| [class_scope](#class_scope) \| [package_scope](#package_scope) ] [hierarchical_variable_identifier](#hierarchical_variable_identifier)
+ [select](#select) `=` [class_new](#class_new)
+ \| [operator_assignment](#operator_assignment)
+ \| [inc_or_dec_expression](#inc_or_dec_expression)
+operator\_assignment ::= [variable_lvalue](#variable_lvalue) [assignment_operator](#assignment_operator) [expression](#expression)
+assignment\_operator ::= `=` \| `+=` \| `-=` \| `*=` \| `/=` \| `%=` \| `&=` \| `|=` \| `^=` \| `<<=` \| `>>=` \| `<<<=` \| `>>>=`
+nonblocking\_assignment ::= [variable_lvalue](#variable_lvalue) `<=` \[ [delay_or_event_control](#delay_or_event_control) ] [expression](#expression)
+procedural\_continuous\_assignment ::=
+ [assign](#assign) [variable_assignment](#variable_assignment)
+ \| [deassign](#deassign) [variable_lvalue](#variable_lvalue)
+ \| [force](#force) [variable_assignment](#variable_assignment)
+ \| [force](#force) [net_assignment](#net_assignment)
+ \| [release](#release) [variable_lvalue](#variable_lvalue)
+ \| [release](#release) [net_lvalue](#net_lvalue)
+variable\_assignment ::= [variable_lvalue](#variable_lvalue) `=` [expression](#expression)
### A.6.3 Parallel and sequential blocks
-action\_block ::=
- [statement_or_null](#statement_or_null)
- \| \[ [statement](#statement) ] [else](#else) [statement_or_null](#statement_or_null)
-seq\_block ::=
- [begin](#begin) \[ `:` [block_identifier](#block_identifier) ] \{ [block_item_declaration](#block_item_declaration) } \{ [statement_or_null](#statement_or_null) }
- [end](#end) \[ `:` [block_identifier](#block_identifier) ]
-par\_block ::=
- [fork](#fork) \[ `:` [block_identifier](#block_identifier) ] \{ [block_item_declaration](#block_item_declaration) } \{ [statement_or_null](#statement_or_null) }
- [join_keyword](#join_keyword) \[ `:` [block_identifier](#block_identifier) ]
-join\_keyword ::= [join](#join) \| [join_any](#join_any) \| [join_none](#join_none)
+action\_block ::=
+ [statement_or_null](#statement_or_null)
+ \| \[ [statement](#statement) ] [else](#else) [statement_or_null](#statement_or_null)
+seq\_block ::=
+ [begin](#begin) \[ `:` [block_identifier](#block_identifier) ] \{ [block_item_declaration](#block_item_declaration) } \{ [statement_or_null](#statement_or_null) }
+ [end](#end) \[ `:` [block_identifier](#block_identifier) ]
+par\_block ::=
+ [fork](#fork) \[ `:` [block_identifier](#block_identifier) ] \{ [block_item_declaration](#block_item_declaration) } \{ [statement_or_null](#statement_or_null) }
+ [join_keyword](#join_keyword) \[ `:` [block_identifier](#block_identifier) ]
+join\_keyword ::= [join](#join) \| [join_any](#join_any) \| [join_none](#join_none)
### A.6.4 Statements
-statement\_or\_null ::=
- [statement](#statement)
- \| \{ [attribute_instance](#attribute_instance) } `;`
-statement ::= \[ [block_identifier](#block_identifier) `:` ] \{ [attribute_instance](#attribute_instance) } [statement_item](#statement_item)
-statement\_item ::=
- [blocking_assignment](#blocking_assignment) `;`
- \| [nonblocking_assignment](#nonblocking_assignment) `;`
- \| [procedural_continuous_assignment](#procedural_continuous_assignment) `;`
- \| [case_statement](#case_statement)
- \| [conditional_statement](#conditional_statement)
- \| [subroutine_call_statement](#subroutine_call_statement)
- \| [disable_statement](#disable_statement)
- \| [event_trigger](#event_trigger)
- \| [loop_statement](#loop_statement)
- \| [jump_statement](#jump_statement)
- \| [par_block](#par_block)
- \| [procedural_timing_control_statement](#procedural_timing_control_statement)
- \| [seq_block](#seq_block)
- \| [wait_statement](#wait_statement)
- \| [procedural_assertion_statement](#procedural_assertion_statement)
- \| [clocking_drive](#clocking_drive) `;`
- \| [randsequence_statement](#randsequence_statement)
- \| [randcase_statement](#randcase_statement)
- \| [expect_property_statement](#expect_property_statement)
-function\_statement ::= [statement](#statement)
-function\_statement\_or\_null ::=
- [function_statement](#function_statement)
- \| \{ [attribute_instance](#attribute_instance) } `;`
+statement\_or\_null ::=
+ [statement](#statement)
+ \| \{ [attribute_instance](#attribute_instance) } `;`
+statement ::= \[ [block_identifier](#block_identifier) `:` ] \{ [attribute_instance](#attribute_instance) } [statement_item](#statement_item)
+statement\_item ::=
+ [blocking_assignment](#blocking_assignment) `;`
+ \| [nonblocking_assignment](#nonblocking_assignment) `;`
+ \| [procedural_continuous_assignment](#procedural_continuous_assignment) `;`
+ \| [case_statement](#case_statement)
+ \| [conditional_statement](#conditional_statement)
+ \| [subroutine_call_statement](#subroutine_call_statement)
+ \| [disable_statement](#disable_statement)
+ \| [event_trigger](#event_trigger)
+ \| [loop_statement](#loop_statement)
+ \| [jump_statement](#jump_statement)
+ \| [par_block](#par_block)
+ \| [procedural_timing_control_statement](#procedural_timing_control_statement)
+ \| [seq_block](#seq_block)
+ \| [wait_statement](#wait_statement)
+ \| [procedural_assertion_statement](#procedural_assertion_statement)
+ \| [clocking_drive](#clocking_drive) `;`
+ \| [randsequence_statement](#randsequence_statement)
+ \| [randcase_statement](#randcase_statement)
+ \| [expect_property_statement](#expect_property_statement)
+function\_statement ::= [statement](#statement)
+function\_statement\_or\_null ::=
+ [function_statement](#function_statement)
+ \| \{ [attribute_instance](#attribute_instance) } `;`
### A.6.5 Timing control statements
-procedural\_timing\_control\_statement ::= [procedural_timing_control](#procedural_timing_control) [statement_or_null](#statement_or_null)
-delay\_or\_event\_control ::=
- [delay_control](#delay_control)
- \| [event_control](#event_control)
- \| [repeat](#repeat) `(` [expression](#expression) `)` [event_control](#event_control)
-delay\_control ::=
- `#` [delay_value](#delay_value)
- \| `#` `(` [mintypmax_expression](#mintypmax_expression) `)`
-event\_control ::=
- [clocking_event](#clocking_event)
- \| `@` `*`
- \| `@` `(` `*` `)`
-clocking\_event ::=
- `@` [ps_identifier](#ps_identifier)
- \| `@` [hierarchical_identifier](#hierarchical_identifier)
- \| `@` `(` [event_expression](#event_expression) `)`
-event\_expression36 ::=
- \[ [edge_identifier](#edge_identifier) ] [expression](#expression) \[ [iff](#iff) [expression](#expression) ]
- \| [sequence_instance](#sequence_instance) \[ [iff](#iff) [expression](#expression) ]
- \| [event_expression](#event_expression) [or](#or) [event_expression](#event_expression)
- \| [event_expression](#event_expression) `,` [event_expression](#event_expression)
- \| `(` [event_expression](#event_expression) `)`
-procedural\_timing\_control ::=
- [delay_control](#delay_control)
- \| [event_control](#event_control)
- \| [cycle_delay](#cycle_delay)
-jump\_statement ::=
- [return](#return) \[ [expression](#expression) ] `;`
- \| [break](#break) `;`
- \| [continue](#continue) `;`
-wait\_statement ::=
- [wait](#wait) `(` [expression](#expression) `)` [statement_or_null](#statement_or_null)
- \| [wait](#wait) [fork](#fork) `;`
- \| [wait_order](#wait_order) `(` [hierarchical_identifier](#hierarchical_identifier) \{ `,` [hierarchical_identifier](#hierarchical_identifier) } `)` [action_block](#action_block)
-event\_trigger ::=
- `->` [hierarchical_event_identifier](#hierarchical_event_identifier) [nonrange_select](#nonrange_select) `;`
- \| `->>` \[ [delay_or_event_control](#delay_or_event_control) ] [hierarchical_event_identifier](#hierarchical_event_identifier) [nonrange_select](#nonrange_select) `;`
-disable\_statement ::=
- [disable](#disable) [hierarchical_task_identifier](#hierarchical_task_identifier) `;`
- \| [disable](#disable) [hierarchical_block_identifier](#hierarchical_block_identifier) `;`
- \| [disable](#disable) [fork](#fork) `;`
+procedural\_timing\_control\_statement ::= [procedural_timing_control](#procedural_timing_control) [statement_or_null](#statement_or_null)
+delay\_or\_event\_control ::=
+ [delay_control](#delay_control)
+ \| [event_control](#event_control)
+ \| [repeat](#repeat) `(` [expression](#expression) `)` [event_control](#event_control)
+delay\_control ::=
+ `#` [delay_value](#delay_value)
+ \| `#` `(` [mintypmax_expression](#mintypmax_expression) `)`
+event\_control ::=
+ [clocking_event](#clocking_event)
+ \| `@` `*`
+ \| `@` `(` `*` `)`
+clocking\_event ::=
+ `@` [ps_identifier](#ps_identifier)
+ \| `@` [hierarchical_identifier](#hierarchical_identifier)
+ \| `@` `(` [event_expression](#event_expression) `)`
+event\_expression36 ::=
+ \[ [edge_identifier](#edge_identifier) ] [expression](#expression) \[ [iff](#iff) [expression](#expression) ]
+ \| [sequence_instance](#sequence_instance) \[ [iff](#iff) [expression](#expression) ]
+ \| [event_expression](#event_expression) [or](#or) [event_expression](#event_expression)
+ \| [event_expression](#event_expression) `,` [event_expression](#event_expression)
+ \| `(` [event_expression](#event_expression) `)`
+procedural\_timing\_control ::=
+ [delay_control](#delay_control)
+ \| [event_control](#event_control)
+ \| [cycle_delay](#cycle_delay)
+jump\_statement ::=
+ [return](#return) \[ [expression](#expression) ] `;`
+ \| [break](#break) `;`
+ \| [continue](#continue) `;`
+wait\_statement ::=
+ [wait](#wait) `(` [expression](#expression) `)` [statement_or_null](#statement_or_null)
+ \| [wait](#wait) [fork](#fork) `;`
+ \| [wait_order](#wait_order) `(` [hierarchical_identifier](#hierarchical_identifier) \{ `,` [hierarchical_identifier](#hierarchical_identifier) } `)` [action_block](#action_block)
+event\_trigger ::=
+ `->` [hierarchical_event_identifier](#hierarchical_event_identifier) [nonrange_select](#nonrange_select) `;`
+ \| `->>` \[ [delay_or_event_control](#delay_or_event_control) ] [hierarchical_event_identifier](#hierarchical_event_identifier) [nonrange_select](#nonrange_select) `;`
+disable\_statement ::=
+ [disable](#disable) [hierarchical_task_identifier](#hierarchical_task_identifier) `;`
+ \| [disable](#disable) [hierarchical_block_identifier](#hierarchical_block_identifier) `;`
+ \| [disable](#disable) [fork](#fork) `;`
### A.6.6 Conditional statements
-conditional\_statement ::=
- \[ [unique_priority](#unique_priority) ] [if](#if) `(` [cond_predicate](#cond_predicate) `)` [statement_or_null](#statement_or_null)
- \{ [else](#else) [if](#if) `(` [cond_predicate](#cond_predicate) `)` [statement_or_null](#statement_or_null) }
- \[ [else](#else) [statement_or_null](#statement_or_null) ]
-unique\_priority ::= [unique](#unique) \| [unique0](#unique0) \| [priority](#priority)
-cond\_predicate ::= [expression_or_cond_pattern](#expression_or_cond_pattern) \{ `&&&` [expression_or_cond_pattern](#expression_or_cond_pattern) }
-expression\_or\_cond\_pattern ::=
- [expression](#expression)
- \| [cond_pattern](#cond_pattern)
-cond\_pattern ::= [expression](#expression) [matches](#matches) [pattern](#pattern)
+conditional\_statement ::=
+ \[ [unique_priority](#unique_priority) ] [if](#if) `(` [cond_predicate](#cond_predicate) `)` [statement_or_null](#statement_or_null)
+ \{ [else](#else) [if](#if) `(` [cond_predicate](#cond_predicate) `)` [statement_or_null](#statement_or_null) }
+ \[ [else](#else) [statement_or_null](#statement_or_null) ]
+unique\_priority ::= [unique](#unique) \| [unique0](#unique0) \| [priority](#priority)
+cond\_predicate ::= [expression_or_cond_pattern](#expression_or_cond_pattern) \{ `&&&` [expression_or_cond_pattern](#expression_or_cond_pattern) }
+expression\_or\_cond\_pattern ::=
+ [expression](#expression)
+ \| [cond_pattern](#cond_pattern)
+cond\_pattern ::= [expression](#expression) [matches](#matches) [pattern](#pattern)
### A.6.7 Case statements
-case\_statement ::=
- \[ [unique_priority](#unique_priority) ] [case_keyword](#case_keyword) `(` [case_expression](#case_expression) `)`
- [case_item](#case_item) \{ [case_item](#case_item) } [endcase](#endcase)
- \| \[ [unique_priority](#unique_priority) ] [case_keyword](#case_keyword) `(` [case_expression](#case_expression) `)` [matches](#matches)
- [case_pattern_item](#case_pattern_item) \{ [case_pattern_item](#case_pattern_item) } [endcase](#endcase)
- \| \[ [unique_priority](#unique_priority) ] [case](#case) `(` [case_expression](#case_expression) `)` [inside](#inside)
- [case_inside_item](#case_inside_item) \{ [case_inside_item](#case_inside_item) } [endcase](#endcase)
-case\_keyword ::= [case](#case) \| [casez](#casez) \| [casex](#casex)
-case\_expression ::= [expression](#expression)
-case\_item ::=
- [case_item_expression](#case_item_expression) \{ `,` [case_item_expression](#case_item_expression) } `:` [statement_or_null](#statement_or_null)
- \| [default](#default) \[ `:` ] [statement_or_null](#statement_or_null)
-case\_pattern\_item ::=
- [pattern](#pattern) \[ `&&&` [expression](#expression) ] `:` [statement_or_null](#statement_or_null)
- \| [default](#default) \[ `:` ] [statement_or_null](#statement_or_null)
-case\_inside\_item ::=
- [range_list](#range_list) `:` [statement_or_null](#statement_or_null)
- \| [default](#default) \[ `:` ] [statement_or_null](#statement_or_null)
-case\_item\_expression ::= [expression](#expression)
-randcase\_statement ::= [randcase](#randcase) [randcase_item](#randcase_item) \{ [randcase_item](#randcase_item) } [endcase](#endcase)
-randcase\_item ::= [expression](#expression) `:` [statement_or_null](#statement_or_null)
-range\_list ::= [value_range](#value_range) \{ `,` [value_range](#value_range) }
-value\_range ::=
- [expression](#expression)
- \| \[ [expression](#expression) `:` [expression](#expression) ]
- \| \[ `$` `:` [expression](#expression) ]
- \| \[ [expression](#expression) `:` `$` ]
- \| \[ [expression](#expression) `+/-` [expression](#expression) ]
- \| \[ [expression](#expression) `+%-` [expression](#expression) ]
+case\_statement ::=
+ \[ [unique_priority](#unique_priority) ] [case_keyword](#case_keyword) `(` [case_expression](#case_expression) `)`
+ [case_item](#case_item) \{ [case_item](#case_item) } [endcase](#endcase)
+ \| \[ [unique_priority](#unique_priority) ] [case_keyword](#case_keyword) `(` [case_expression](#case_expression) `)` [matches](#matches)
+ [case_pattern_item](#case_pattern_item) \{ [case_pattern_item](#case_pattern_item) } [endcase](#endcase)
+ \| \[ [unique_priority](#unique_priority) ] [case](#case) `(` [case_expression](#case_expression) `)` [inside](#inside)
+ [case_inside_item](#case_inside_item) \{ [case_inside_item](#case_inside_item) } [endcase](#endcase)
+case\_keyword ::= [case](#case) \| [casez](#casez) \| [casex](#casex)
+case\_expression ::= [expression](#expression)
+case\_item ::=
+ [case_item_expression](#case_item_expression) \{ `,` [case_item_expression](#case_item_expression) } `:` [statement_or_null](#statement_or_null)
+ \| [default](#default) \[ `:` ] [statement_or_null](#statement_or_null)
+case\_pattern\_item ::=
+ [pattern](#pattern) \[ `&&&` [expression](#expression) ] `:` [statement_or_null](#statement_or_null)
+ \| [default](#default) \[ `:` ] [statement_or_null](#statement_or_null)
+case\_inside\_item ::=
+ [range_list](#range_list) `:` [statement_or_null](#statement_or_null)
+ \| [default](#default) \[ `:` ] [statement_or_null](#statement_or_null)
+case\_item\_expression ::= [expression](#expression)
+randcase\_statement ::= [randcase](#randcase) [randcase_item](#randcase_item) \{ [randcase_item](#randcase_item) } [endcase](#endcase)
+randcase\_item ::= [expression](#expression) `:` [statement_or_null](#statement_or_null)
+range\_list ::= [value_range](#value_range) \{ `,` [value_range](#value_range) }
+value\_range ::=
+ [expression](#expression)
+ \| \[ [expression](#expression) `:` [expression](#expression) ]
+ \| \[ `$` `:` [expression](#expression) ]
+ \| \[ [expression](#expression) `:` `$` ]
+ \| \[ [expression](#expression) `+/-` [expression](#expression) ]
+ \| \[ [expression](#expression) `+%-` [expression](#expression) ]
#### A.6.7.1 Patterns
-pattern ::=
- `(` [pattern](#pattern) `)`
- \| `.` [variable_identifier](#variable_identifier)
- \| `.` `*`
- \| [constant_expression](#constant_expression)
- \| [tagged](#tagged) [member_identifier](#member_identifier) \[ [pattern](#pattern) ]
- \| `'` \{ [pattern](#pattern) \{ `,` [pattern](#pattern) } }
- \| `'` \{ [member_identifier](#member_identifier) `:` [pattern](#pattern) \{ `,` [member_identifier](#member_identifier) `:` [pattern](#pattern) } }
-assignment\_pattern ::=
- `'` \{ [expression](#expression) \{ `,` [expression](#expression) } }
- \| `'` \{ [structure_pattern_key](#structure_pattern_key) `:` [expression](#expression) \{ `,` [structure_pattern_key](#structure_pattern_key) `:` [expression](#expression) } }
- \| `'` \{ [array_pattern_key](#array_pattern_key) `:` [expression](#expression) \{ `,` [array_pattern_key](#array_pattern_key) `:` [expression](#expression) } }
- \| `'` \{ [constant_expression](#constant_expression) \{ [expression](#expression) \{ `,` [expression](#expression) } } }
-structure\_pattern\_key ::= [member_identifier](#member_identifier) \| [assignment_pattern_key](#assignment_pattern_key)
-array\_pattern\_key ::= [constant_expression](#constant_expression) \| [assignment_pattern_key](#assignment_pattern_key)
-assignment\_pattern\_key ::= [simple_type](#simple_type) \| [default](#default)
-assignment\_pattern\_expression ::= \[ [assignment_pattern_expression_type](#assignment_pattern_expression_type) ] [assignment_pattern](#assignment_pattern)
-assignment\_pattern\_expression\_type ::=
- [ps_type_identifier](#ps_type_identifier)
- \| [ps_parameter_identifier](#ps_parameter_identifier)
- \| [integer_atom_type](#integer_atom_type)
- \| [type_reference](#type_reference)
-constant\_assignment\_pattern\_expression ::= [assignment_pattern_expression37](#assignment_pattern_expression37)
-assignment\_pattern\_net\_lvalue ::= `'` \{ [net_lvalue](#net_lvalue) \{ `,` [net_lvalue](#net_lvalue) } }
-assignment\_pattern\_variable\_lvalue ::= `'` \{ [variable_lvalue](#variable_lvalue) \{ `,` [variable_lvalue](#variable_lvalue) } }
+pattern ::=
+ `(` [pattern](#pattern) `)`
+ \| `.` [variable_identifier](#variable_identifier)
+ \| `.` `*`
+ \| [constant_expression](#constant_expression)
+ \| [tagged](#tagged) [member_identifier](#member_identifier) \[ [pattern](#pattern) ]
+ \| `'` \{ [pattern](#pattern) \{ `,` [pattern](#pattern) } }
+ \| `'` \{ [member_identifier](#member_identifier) `:` [pattern](#pattern) \{ `,` [member_identifier](#member_identifier) `:` [pattern](#pattern) } }
+assignment\_pattern ::=
+ `'` \{ [expression](#expression) \{ `,` [expression](#expression) } }
+ \| `'` \{ [structure_pattern_key](#structure_pattern_key) `:` [expression](#expression) \{ `,` [structure_pattern_key](#structure_pattern_key) `:` [expression](#expression) } }
+ \| `'` \{ [array_pattern_key](#array_pattern_key) `:` [expression](#expression) \{ `,` [array_pattern_key](#array_pattern_key) `:` [expression](#expression) } }
+ \| `'` \{ [constant_expression](#constant_expression) \{ [expression](#expression) \{ `,` [expression](#expression) } } }
+structure\_pattern\_key ::= [member_identifier](#member_identifier) \| [assignment_pattern_key](#assignment_pattern_key)
+array\_pattern\_key ::= [constant_expression](#constant_expression) \| [assignment_pattern_key](#assignment_pattern_key)
+assignment\_pattern\_key ::= [simple_type](#simple_type) \| [default](#default)
+assignment\_pattern\_expression ::= \[ [assignment_pattern_expression_type](#assignment_pattern_expression_type) ] [assignment_pattern](#assignment_pattern)
+assignment\_pattern\_expression\_type ::=
+ [ps_type_identifier](#ps_type_identifier)
+ \| [ps_parameter_identifier](#ps_parameter_identifier)
+ \| [integer_atom_type](#integer_atom_type)
+ \| [type_reference](#type_reference)
+constant\_assignment\_pattern\_expression ::= [assignment_pattern_expression37](#assignment_pattern_expression37)
+assignment\_pattern\_net\_lvalue ::= `'` \{ [net_lvalue](#net_lvalue) \{ `,` [net_lvalue](#net_lvalue) } }
+assignment\_pattern\_variable\_lvalue ::= `'` \{ [variable_lvalue](#variable_lvalue) \{ `,` [variable_lvalue](#variable_lvalue) } }
### A.6.8 Looping statements
-loop\_statement ::=
- [forever](#forever) [statement_or_null](#statement_or_null)
- \| [repeat](#repeat) `(` [expression](#expression) `)` [statement_or_null](#statement_or_null)
- \| [while](#while) `(` [expression](#expression) `)` [statement_or_null](#statement_or_null)
- \| [for](#for) `(` \[ [for_initialization](#for_initialization) ] `;` \[ [expression](#expression) ] `;` \[ [for_step](#for_step) ] `)` [statement_or_null](#statement_or_null)
- \| [do](#do) [statement_or_null](#statement_or_null) [while](#while) `(` [expression](#expression) `)` `;`
- \| [foreach](#foreach) `(` [ps_or_hierarchical_array_identifier](#ps_or_hierarchical_array_identifier) \[ [loop_variables](#loop_variables) ] `)` [statement](#statement)
-for\_initialization ::=
- [list_of_variable_assignments](#list_of_variable_assignments)
- \| [for_variable_declaration](#for_variable_declaration) \{ `,` [for_variable_declaration](#for_variable_declaration) }
-for\_variable\_declaration ::=
- \[ [var](#var) ] [data_type](#data_type) [variable_identifier](#variable_identifier) `=` [expression](#expression) \{ `,` [variable_identifier](#variable_identifier) `=` [expression](#expression) }[18](#18)
-for\_step ::= [for_step_assignment](#for_step_assignment) \{ `,` [for_step_assignment](#for_step_assignment) }
-for\_step\_assignment ::=
- [operator_assignment](#operator_assignment)
- \| [inc_or_dec_expression](#inc_or_dec_expression)
- \| [function_subroutine_call](#function_subroutine_call)
-loop\_variables ::= \[ [index_variable_identifier](#index_variable_identifier) ] \{ `,` \[ [index_variable_identifier](#index_variable_identifier) ] }
+loop\_statement ::=
+ [forever](#forever) [statement_or_null](#statement_or_null)
+ \| [repeat](#repeat) `(` [expression](#expression) `)` [statement_or_null](#statement_or_null)
+ \| [while](#while) `(` [expression](#expression) `)` [statement_or_null](#statement_or_null)
+ \| [for](#for) `(` \[ [for_initialization](#for_initialization) ] `;` \[ [expression](#expression) ] `;` \[ [for_step](#for_step) ] `)` [statement_or_null](#statement_or_null)
+ \| [do](#do) [statement_or_null](#statement_or_null) [while](#while) `(` [expression](#expression) `)` `;`
+ \| [foreach](#foreach) `(` [ps_or_hierarchical_array_identifier](#ps_or_hierarchical_array_identifier) \[ [loop_variables](#loop_variables) ] `)` [statement](#statement)
+for\_initialization ::=
+ [list_of_variable_assignments](#list_of_variable_assignments)
+ \| [for_variable_declaration](#for_variable_declaration) \{ `,` [for_variable_declaration](#for_variable_declaration) }
+for\_variable\_declaration ::=
+ \[ [var](#var) ] [data_type](#data_type) [variable_identifier](#variable_identifier) `=` [expression](#expression) \{ `,` [variable_identifier](#variable_identifier) `=` [expression](#expression) }[18](#18)
+for\_step ::= [for_step_assignment](#for_step_assignment) \{ `,` [for_step_assignment](#for_step_assignment) }
+for\_step\_assignment ::=
+ [operator_assignment](#operator_assignment)
+ \| [inc_or_dec_expression](#inc_or_dec_expression)
+ \| [function_subroutine_call](#function_subroutine_call)
+loop\_variables ::= \[ [index_variable_identifier](#index_variable_identifier) ] \{ `,` \[ [index_variable_identifier](#index_variable_identifier) ] }
### A.6.9 Subroutine call statements
-subroutine\_call\_statement ::=
- [subroutine_call](#subroutine_call) `;`
- \| [void](#void) `'` `(` [function_subroutine_call](#function_subroutine_call) `)` `;`
+subroutine\_call\_statement ::=
+ [subroutine_call](#subroutine_call) `;`
+ \| [void](#void) `'` `(` [function_subroutine_call](#function_subroutine_call) `)` `;`
### A.6.10 Assertion statements
-assertion\_item ::=
- [concurrent_assertion_item](#concurrent_assertion_item)
- \| [deferred_immediate_assertion_item](#deferred_immediate_assertion_item)
-deferred\_immediate\_assertion\_item ::= \[ [block_identifier](#block_identifier) `:` ] [deferred_immediate_assertion_statement](#deferred_immediate_assertion_statement)
-procedural\_assertion\_statement ::=
- [concurrent_assertion_statement](#concurrent_assertion_statement)
- \| [immediate_assertion_statement](#immediate_assertion_statement)
- \| [checker_instantiation](#checker_instantiation)
-immediate\_assertion\_statement ::=
- [simple_immediate_assertion_statement](#simple_immediate_assertion_statement)
- \| [deferred_immediate_assertion_statement](#deferred_immediate_assertion_statement)
-simple\_immediate\_assertion\_statement ::=
- [simple_immediate_assert_statement](#simple_immediate_assert_statement)
- \| [simple_immediate_assume_statement](#simple_immediate_assume_statement)
- \| [simple_immediate_cover_statement](#simple_immediate_cover_statement)
-deferred\_immediate\_assertion\_statement ::=
- [deferred_immediate_assert_statement](#deferred_immediate_assert_statement)
- \| [deferred_immediate_assume_statement](#deferred_immediate_assume_statement)
- \| [deferred_immediate_cover_statement](#deferred_immediate_cover_statement)
-simple\_immediate\_assert\_statement ::=
- [assert](#assert) `(` [expression](#expression) `)` [action_block](#action_block)
-simple\_immediate\_assume\_statement ::=
- [assume](#assume) `(` [expression](#expression) `)` [action_block](#action_block)
-simple\_immediate\_cover\_statement ::=
- [cover](#cover) `(` [expression](#expression) `)` [statement_or_null](#statement_or_null)
-deferred\_immediate\_assert\_statement ::=
- [assert](#assert) `#`[0](#0) `(` [expression](#expression) `)` [action_block](#action_block)
- \| [assert](#assert) [final](#final) `(` [expression](#expression) `)` [action_block](#action_block)
-deferred\_immediate\_assume\_statement ::=
- [assume](#assume) `#`[0](#0) `(` [expression](#expression) `)` [action_block](#action_block)
- \| [assume](#assume) [final](#final) `(` [expression](#expression) `)` [action_block](#action_block)
-deferred\_immediate\_cover\_statement ::=
- [cover](#cover) `#`[0](#0) `(` [expression](#expression) `)` [statement_or_null](#statement_or_null)
- \| [cover](#cover) [final](#final) `(` [expression](#expression) `)` [statement_or_null](#statement_or_null)
+assertion\_item ::=
+ [concurrent_assertion_item](#concurrent_assertion_item)
+ \| [deferred_immediate_assertion_item](#deferred_immediate_assertion_item)
+deferred\_immediate\_assertion\_item ::= \[ [block_identifier](#block_identifier) `:` ] [deferred_immediate_assertion_statement](#deferred_immediate_assertion_statement)
+procedural\_assertion\_statement ::=
+ [concurrent_assertion_statement](#concurrent_assertion_statement)
+ \| [immediate_assertion_statement](#immediate_assertion_statement)
+ \| [checker_instantiation](#checker_instantiation)
+immediate\_assertion\_statement ::=
+ [simple_immediate_assertion_statement](#simple_immediate_assertion_statement)
+ \| [deferred_immediate_assertion_statement](#deferred_immediate_assertion_statement)
+simple\_immediate\_assertion\_statement ::=
+ [simple_immediate_assert_statement](#simple_immediate_assert_statement)
+ \| [simple_immediate_assume_statement](#simple_immediate_assume_statement)
+ \| [simple_immediate_cover_statement](#simple_immediate_cover_statement)
+deferred\_immediate\_assertion\_statement ::=
+ [deferred_immediate_assert_statement](#deferred_immediate_assert_statement)
+ \| [deferred_immediate_assume_statement](#deferred_immediate_assume_statement)
+ \| [deferred_immediate_cover_statement](#deferred_immediate_cover_statement)
+simple\_immediate\_assert\_statement ::=
+ [assert](#assert) `(` [expression](#expression) `)` [action_block](#action_block)
+simple\_immediate\_assume\_statement ::=
+ [assume](#assume) `(` [expression](#expression) `)` [action_block](#action_block)
+simple\_immediate\_cover\_statement ::=
+ [cover](#cover) `(` [expression](#expression) `)` [statement_or_null](#statement_or_null)
+deferred\_immediate\_assert\_statement ::=
+ [assert](#assert) `#`[0](#0) `(` [expression](#expression) `)` [action_block](#action_block)
+ \| [assert](#assert) [final](#final) `(` [expression](#expression) `)` [action_block](#action_block)
+deferred\_immediate\_assume\_statement ::=
+ [assume](#assume) `#`[0](#0) `(` [expression](#expression) `)` [action_block](#action_block)
+ \| [assume](#assume) [final](#final) `(` [expression](#expression) `)` [action_block](#action_block)
+deferred\_immediate\_cover\_statement ::=
+ [cover](#cover) `#`[0](#0) `(` [expression](#expression) `)` [statement_or_null](#statement_or_null)
+ \| [cover](#cover) [final](#final) `(` [expression](#expression) `)` [statement_or_null](#statement_or_null)
### A.6.11 Clocking block
-clocking\_declaration ::=
- \[ [default](#default) ] [clocking](#clocking) \[ [clocking_identifier](#clocking_identifier) ] [clocking_event](#clocking_event) `;`
- \{ [clocking_item](#clocking_item) }
- [endclocking](#endclocking) \[ `:` [clocking_identifier](#clocking_identifier) ]
- \| [global](#global) [clocking](#clocking) \[ [clocking_identifier](#clocking_identifier) ] [clocking_event](#clocking_event) `;`
- [endclocking](#endclocking) \[ `:` [clocking_identifier](#clocking_identifier) ]
-clocking\_item ::=
- [default](#default) [default_skew](#default_skew) `;`
- \| [clocking_direction](#clocking_direction) [list_of_clocking_decl_assign](#list_of_clocking_decl_assign) `;`
- \| \{ [attribute_instance](#attribute_instance) } [assertion_item_declaration](#assertion_item_declaration)
-default\_skew ::=
- [input](#input) [clocking_skew](#clocking_skew)
- \| [output](#output) [clocking_skew](#clocking_skew)
- \| [input](#input) [clocking_skew](#clocking_skew) [output](#output) [clocking_skew](#clocking_skew)
-clocking\_direction ::=
- [input](#input) \[ [clocking_skew](#clocking_skew) ]
- \| [output](#output) \[ [clocking_skew](#clocking_skew) ]
- \| [input](#input) \[ [clocking_skew](#clocking_skew) ] [output](#output) \[ [clocking_skew](#clocking_skew) ]
- \| [inout](#inout)
-list\_of\_clocking\_decl\_assign ::= [clocking_decl_assign](#clocking_decl_assign) \{ `,` [clocking_decl_assign](#clocking_decl_assign) }
-clocking\_decl\_assign ::= [signal_identifier](#signal_identifier) \[ `=` [expression](#expression) ]
-clocking\_skew ::=
- [edge_identifier](#edge_identifier) \[ [delay_control](#delay_control) ]
- \| [delay_control](#delay_control)
-clocking\_drive ::= [clockvar_expression](#clockvar_expression) `<=` \[ [cycle_delay](#cycle_delay) ] [expression](#expression)
-cycle\_delay ::=
- `##` [integral_number](#integral_number)
- \| `##` [identifier](#identifier)
- \| `##` `(` [expression](#expression) `)`
-clockvar ::= [hierarchical_identifier](#hierarchical_identifier)
-clockvar\_expression ::= [clockvar](#clockvar) [select](#select)
+clocking\_declaration ::=
+ \[ [default](#default) ] [clocking](#clocking) \[ [clocking_identifier](#clocking_identifier) ] [clocking_event](#clocking_event) `;`
+ \{ [clocking_item](#clocking_item) }
+ [endclocking](#endclocking) \[ `:` [clocking_identifier](#clocking_identifier) ]
+ \| [global](#global) [clocking](#clocking) \[ [clocking_identifier](#clocking_identifier) ] [clocking_event](#clocking_event) `;`
+ [endclocking](#endclocking) \[ `:` [clocking_identifier](#clocking_identifier) ]
+clocking\_item ::=
+ [default](#default) [default_skew](#default_skew) `;`
+ \| [clocking_direction](#clocking_direction) [list_of_clocking_decl_assign](#list_of_clocking_decl_assign) `;`
+ \| \{ [attribute_instance](#attribute_instance) } [assertion_item_declaration](#assertion_item_declaration)
+default\_skew ::=
+ [input](#input) [clocking_skew](#clocking_skew)
+ \| [output](#output) [clocking_skew](#clocking_skew)
+ \| [input](#input) [clocking_skew](#clocking_skew) [output](#output) [clocking_skew](#clocking_skew)
+clocking\_direction ::=
+ [input](#input) \[ [clocking_skew](#clocking_skew) ]
+ \| [output](#output) \[ [clocking_skew](#clocking_skew) ]
+ \| [input](#input) \[ [clocking_skew](#clocking_skew) ] [output](#output) \[ [clocking_skew](#clocking_skew) ]
+ \| [inout](#inout)
+list\_of\_clocking\_decl\_assign ::= [clocking_decl_assign](#clocking_decl_assign) \{ `,` [clocking_decl_assign](#clocking_decl_assign) }
+clocking\_decl\_assign ::= [signal_identifier](#signal_identifier) \[ `=` [expression](#expression) ]
+clocking\_skew ::=
+ [edge_identifier](#edge_identifier) \[ [delay_control](#delay_control) ]
+ \| [delay_control](#delay_control)
+clocking\_drive ::= [clockvar_expression](#clockvar_expression) `<=` \[ [cycle_delay](#cycle_delay) ] [expression](#expression)
+cycle\_delay ::=
+ `##` [integral_number](#integral_number)
+ \| `##` [identifier](#identifier)
+ \| `##` `(` [expression](#expression) `)`
+clockvar ::= [hierarchical_identifier](#hierarchical_identifier)
+clockvar\_expression ::= [clockvar](#clockvar) [select](#select)
### A.6.12 Randsequence
-randsequence\_statement ::=
- [randsequence](#randsequence) `(` \[ [rs_production_identifier](#rs_production_identifier) ] `)`
- [rs_production](#rs_production) \{ [rs_production](#rs_production) }
- [endsequence](#endsequence)
-rs\_production ::= \[ [data_type_or_void](#data_type_or_void) ] [rs_production_identifier](#rs_production_identifier) \[ `(` [tf_port_list](#tf_port_list) `)` ] `:` [rs_rule](#rs_rule) \{ \| [rs_rule](#rs_rule) } `;`
-rs\_rule ::= [rs_production_list](#rs_production_list) \[ `:=` [rs_weight_specification](#rs_weight_specification) \[ [rs_code_block](#rs_code_block) ] ]
-rs\_production\_list ::=
- [rs_prod](#rs_prod) \{ [rs_prod](#rs_prod) }
- \| [rand](#rand) [join](#join) \[ `(` [expression](#expression) `)` ] [rs_production_item](#rs_production_item) [rs_production_item](#rs_production_item) \{ [rs_production_item](#rs_production_item) }
-rs\_weight\_specification ::=
- [integral_number](#integral_number)
- \| [ps_identifier](#ps_identifier)
- \| `(` [expression](#expression) `)`
-rs\_code\_block ::= \{ \{ [data_declaration](#data_declaration) } \{ [statement_or_null](#statement_or_null) } }
-rs\_prod ::=
- [rs_production_item](#rs_production_item)
- \| [rs_code_block](#rs_code_block)
- \| [rs_if_else](#rs_if_else)
- \| [rs_repeat](#rs_repeat)
- \| [rs_case](#rs_case)
-rs\_production\_item ::= [rs_production_identifier](#rs_production_identifier) \[ `(` [list_of_arguments](#list_of_arguments) `)` ]
-rs\_if\_else ::= [if](#if) `(` [expression](#expression) `)` [rs_production_item](#rs_production_item) \[ [else](#else) [rs_production_item](#rs_production_item) ]
-rs\_repeat ::= [repeat](#repeat) `(` [expression](#expression) `)` [rs_production_item](#rs_production_item)
-rs\_case ::= [case](#case) `(` [case_expression](#case_expression) `)` [rs_case_item](#rs_case_item) \{ [rs_case_item](#rs_case_item) } [endcase](#endcase)
-rs\_case\_item ::=
- [case_item_expression](#case_item_expression) \{ `,` [case_item_expression](#case_item_expression) } `:` [rs_production_item](#rs_production_item) `;`
- \| [default](#default) \[ `:` ] [rs_production_item](#rs_production_item) `;`
+randsequence\_statement ::=
+ [randsequence](#randsequence) `(` \[ [rs_production_identifier](#rs_production_identifier) ] `)`
+ [rs_production](#rs_production) \{ [rs_production](#rs_production) }
+ [endsequence](#endsequence)
+rs\_production ::= \[ [data_type_or_void](#data_type_or_void) ] [rs_production_identifier](#rs_production_identifier) \[ `(` [tf_port_list](#tf_port_list) `)` ] `:` [rs_rule](#rs_rule) \{ \| [rs_rule](#rs_rule) } `;`
+rs\_rule ::= [rs_production_list](#rs_production_list) \[ `:=` [rs_weight_specification](#rs_weight_specification) \[ [rs_code_block](#rs_code_block) ] ]
+rs\_production\_list ::=
+ [rs_prod](#rs_prod) \{ [rs_prod](#rs_prod) }
+ \| [rand](#rand) [join](#join) \[ `(` [expression](#expression) `)` ] [rs_production_item](#rs_production_item) [rs_production_item](#rs_production_item) \{ [rs_production_item](#rs_production_item) }
+rs\_weight\_specification ::=
+ [integral_number](#integral_number)
+ \| [ps_identifier](#ps_identifier)
+ \| `(` [expression](#expression) `)`
+rs\_code\_block ::= \{ \{ [data_declaration](#data_declaration) } \{ [statement_or_null](#statement_or_null) } }
+rs\_prod ::=
+ [rs_production_item](#rs_production_item)
+ \| [rs_code_block](#rs_code_block)
+ \| [rs_if_else](#rs_if_else)
+ \| [rs_repeat](#rs_repeat)
+ \| [rs_case](#rs_case)
+rs\_production\_item ::= [rs_production_identifier](#rs_production_identifier) \[ `(` [list_of_arguments](#list_of_arguments) `)` ]
+rs\_if\_else ::= [if](#if) `(` [expression](#expression) `)` [rs_production_item](#rs_production_item) \[ [else](#else) [rs_production_item](#rs_production_item) ]
+rs\_repeat ::= [repeat](#repeat) `(` [expression](#expression) `)` [rs_production_item](#rs_production_item)
+rs\_case ::= [case](#case) `(` [case_expression](#case_expression) `)` [rs_case_item](#rs_case_item) \{ [rs_case_item](#rs_case_item) } [endcase](#endcase)
+rs\_case\_item ::=
+ [case_item_expression](#case_item_expression) \{ `,` [case_item_expression](#case_item_expression) } `:` [rs_production_item](#rs_production_item) `;`
+ \| [default](#default) \[ `:` ] [rs_production_item](#rs_production_item) `;`
## A.7 Specify section
### A.7.1 Specify block declaration
-specify\_block ::= [specify](#specify) \{ [specify_item](#specify_item) } [endspecify](#endspecify)
-specify\_item ::=
- [specparam_declaration](#specparam_declaration)
- \| [pulsestyle_declaration](#pulsestyle_declaration)
- \| [showcancelled_declaration](#showcancelled_declaration)
- \| [path_declaration](#path_declaration)
- \| [system_timing_check](#system_timing_check)
-pulsestyle\_declaration ::=
- [pulsestyle_onevent](#pulsestyle_onevent) [list_of_path_outputs](#list_of_path_outputs) `;`
- \| [pulsestyle_ondetect](#pulsestyle_ondetect) [list_of_path_outputs](#list_of_path_outputs) `;`
-showcancelled\_declaration ::=
- [showcancelled](#showcancelled) [list_of_path_outputs](#list_of_path_outputs) `;`
- \| [noshowcancelled](#noshowcancelled) [list_of_path_outputs](#list_of_path_outputs) `;`
+specify\_block ::= [specify](#specify) \{ [specify_item](#specify_item) } [endspecify](#endspecify)
+specify\_item ::=
+ [specparam_declaration](#specparam_declaration)
+ \| [pulsestyle_declaration](#pulsestyle_declaration)
+ \| [showcancelled_declaration](#showcancelled_declaration)
+ \| [path_declaration](#path_declaration)
+ \| [system_timing_check](#system_timing_check)
+pulsestyle\_declaration ::=
+ [pulsestyle_onevent](#pulsestyle_onevent) [list_of_path_outputs](#list_of_path_outputs) `;`
+ \| [pulsestyle_ondetect](#pulsestyle_ondetect) [list_of_path_outputs](#list_of_path_outputs) `;`
+showcancelled\_declaration ::=
+ [showcancelled](#showcancelled) [list_of_path_outputs](#list_of_path_outputs) `;`
+ \| [noshowcancelled](#noshowcancelled) [list_of_path_outputs](#list_of_path_outputs) `;`
### A.7.2 Specify path declarations
-path\_declaration ::=
- [simple_path_declaration](#simple_path_declaration) `;`
- \| [edge_sensitive_path_declaration](#edge_sensitive_path_declaration) `;`
- \| [state_dependent_path_declaration](#state_dependent_path_declaration) `;`
-simple\_path\_declaration ::=
- [parallel_path_description](#parallel_path_description) `=` [path_delay_value](#path_delay_value)
- \| [full_path_description](#full_path_description) `=` [path_delay_value](#path_delay_value)
-parallel\_path\_description ::=
- `(` [specify_input_terminal_descriptor](#specify_input_terminal_descriptor) \[ [polarity_operator](#polarity_operator) ] `=>` [specify_output_terminal_descriptor](#specify_output_terminal_descriptor) `)`
-full\_path\_description ::= `(` [list_of_path_inputs](#list_of_path_inputs) \[ [polarity_operator](#polarity_operator) ] `*>` [list_of_path_outputs](#list_of_path_outputs) `)`
-edge\_sensitive\_path\_declaration ::=
- [parallel_edge_sensitive_path_description](#parallel_edge_sensitive_path_description) `=` [path_delay_value](#path_delay_value)
- \| [full_edge_sensitive_path_description](#full_edge_sensitive_path_description) `=` [path_delay_value](#path_delay_value)
-parallel\_edge\_sensitive\_path\_description ::=
- `(` \[ [edge_identifier](#edge_identifier) ] [specify_input_terminal_descriptor](#specify_input_terminal_descriptor) \[ [polarity_operator](#polarity_operator) ] `=>`
- `(` [specify_output_terminal_descriptor](#specify_output_terminal_descriptor) \[ [polarity_operator](#polarity_operator) ] `:` [data_source_expression](#data_source_expression) `)` `)`
- \| `(` \[ [edge_identifier](#edge_identifier) ] [specify_input_terminal_descriptor](#specify_input_terminal_descriptor) \[ [polarity_operator](#polarity_operator) ] `=>`
- [specify_output_terminal_descriptor](#specify_output_terminal_descriptor) `)`
-full\_edge\_sensitive\_path\_description ::=
- `(` \[ [edge_identifier](#edge_identifier) ] [list_of_path_inputs](#list_of_path_inputs) \[ [polarity_operator](#polarity_operator) ] `*>`
- `(` [list_of_path_outputs](#list_of_path_outputs) \[ [polarity_operator](#polarity_operator) ] `:` [data_source_expression](#data_source_expression) `)` `)`
- \| `(` \[ [edge_identifier](#edge_identifier) ] [list_of_path_inputs](#list_of_path_inputs) \[ [polarity_operator](#polarity_operator) ] `*>`
- [list_of_path_outputs](#list_of_path_outputs) `)`
-state\_dependent\_path\_declaration ::=
- [if](#if) `(` [module_path_expression](#module_path_expression) `)` [simple_path_declaration](#simple_path_declaration)
- \| [if](#if) `(` [module_path_expression](#module_path_expression) `)` [edge_sensitive_path_declaration](#edge_sensitive_path_declaration)
- \| [ifnone](#ifnone) [simple_path_declaration](#simple_path_declaration)
-data\_source\_expression ::= [expression](#expression)
-edge\_identifier ::= [posedge](#posedge) \| [negedge](#negedge) \| [edge](#edge)
-polarity\_operator ::= `+` \| `-`
+path\_declaration ::=
+ [simple_path_declaration](#simple_path_declaration) `;`
+ \| [edge_sensitive_path_declaration](#edge_sensitive_path_declaration) `;`
+ \| [state_dependent_path_declaration](#state_dependent_path_declaration) `;`
+simple\_path\_declaration ::=
+ [parallel_path_description](#parallel_path_description) `=` [path_delay_value](#path_delay_value)
+ \| [full_path_description](#full_path_description) `=` [path_delay_value](#path_delay_value)
+parallel\_path\_description ::=
+ `(` [specify_input_terminal_descriptor](#specify_input_terminal_descriptor) \[ [polarity_operator](#polarity_operator) ] `=>` [specify_output_terminal_descriptor](#specify_output_terminal_descriptor) `)`
+full\_path\_description ::= `(` [list_of_path_inputs](#list_of_path_inputs) \[ [polarity_operator](#polarity_operator) ] `*>` [list_of_path_outputs](#list_of_path_outputs) `)`
+edge\_sensitive\_path\_declaration ::=
+ [parallel_edge_sensitive_path_description](#parallel_edge_sensitive_path_description) `=` [path_delay_value](#path_delay_value)
+ \| [full_edge_sensitive_path_description](#full_edge_sensitive_path_description) `=` [path_delay_value](#path_delay_value)
+parallel\_edge\_sensitive\_path\_description ::=
+ `(` \[ [edge_identifier](#edge_identifier) ] [specify_input_terminal_descriptor](#specify_input_terminal_descriptor) \[ [polarity_operator](#polarity_operator) ] `=>`
+ `(` [specify_output_terminal_descriptor](#specify_output_terminal_descriptor) \[ [polarity_operator](#polarity_operator) ] `:` [data_source_expression](#data_source_expression) `)` `)`
+ \| `(` \[ [edge_identifier](#edge_identifier) ] [specify_input_terminal_descriptor](#specify_input_terminal_descriptor) \[ [polarity_operator](#polarity_operator) ] `=>`
+ [specify_output_terminal_descriptor](#specify_output_terminal_descriptor) `)`
+full\_edge\_sensitive\_path\_description ::=
+ `(` \[ [edge_identifier](#edge_identifier) ] [list_of_path_inputs](#list_of_path_inputs) \[ [polarity_operator](#polarity_operator) ] `*>`
+ `(` [list_of_path_outputs](#list_of_path_outputs) \[ [polarity_operator](#polarity_operator) ] `:` [data_source_expression](#data_source_expression) `)` `)`
+ \| `(` \[ [edge_identifier](#edge_identifier) ] [list_of_path_inputs](#list_of_path_inputs) \[ [polarity_operator](#polarity_operator) ] `*>`
+ [list_of_path_outputs](#list_of_path_outputs) `)`
+state\_dependent\_path\_declaration ::=
+ [if](#if) `(` [module_path_expression](#module_path_expression) `)` [simple_path_declaration](#simple_path_declaration)
+ \| [if](#if) `(` [module_path_expression](#module_path_expression) `)` [edge_sensitive_path_declaration](#edge_sensitive_path_declaration)
+ \| [ifnone](#ifnone) [simple_path_declaration](#simple_path_declaration)
+data\_source\_expression ::= [expression](#expression)
+edge\_identifier ::= [posedge](#posedge) \| [negedge](#negedge) \| [edge](#edge)
+polarity\_operator ::= `+` \| `-`
### A.7.3 Specify block terminals
-list\_of\_path\_inputs ::= [specify_input_terminal_descriptor](#specify_input_terminal_descriptor) \{ `,` [specify_input_terminal_descriptor](#specify_input_terminal_descriptor) }
-list\_of\_path\_outputs ::= [specify_output_terminal_descriptor](#specify_output_terminal_descriptor) \{ `,` [specify_output_terminal_descriptor](#specify_output_terminal_descriptor) }
-specify\_input\_terminal\_descriptor ::= [input_identifier](#input_identifier) \[ \[ [constant_range_expression](#constant_range_expression) ] ]
-specify\_output\_terminal\_descriptor ::= [output_identifier](#output_identifier) \[ \[ [constant_range_expression](#constant_range_expression) ] ]
-input\_identifier ::=
- [input_port_identifier](#input_port_identifier)
- \| [inout_port_identifier](#inout_port_identifier)
- \| [interface_identifier](#interface_identifier) `.` [port_identifier](#port_identifier)
-output\_identifier ::=
- [output_port_identifier](#output_port_identifier)
- \| [inout_port_identifier](#inout_port_identifier)
- \| [interface_identifier](#interface_identifier) `.` [port_identifier](#port_identifier)
+list\_of\_path\_inputs ::= [specify_input_terminal_descriptor](#specify_input_terminal_descriptor) \{ `,` [specify_input_terminal_descriptor](#specify_input_terminal_descriptor) }
+list\_of\_path\_outputs ::= [specify_output_terminal_descriptor](#specify_output_terminal_descriptor) \{ `,` [specify_output_terminal_descriptor](#specify_output_terminal_descriptor) }
+specify\_input\_terminal\_descriptor ::= [input_identifier](#input_identifier) \[ \[ [constant_range_expression](#constant_range_expression) ] ]
+specify\_output\_terminal\_descriptor ::= [output_identifier](#output_identifier) \[ \[ [constant_range_expression](#constant_range_expression) ] ]
+input\_identifier ::=
+ [input_port_identifier](#input_port_identifier)
+ \| [inout_port_identifier](#inout_port_identifier)
+ \| [interface_identifier](#interface_identifier) `.` [port_identifier](#port_identifier)
+output\_identifier ::=
+ [output_port_identifier](#output_port_identifier)
+ \| [inout_port_identifier](#inout_port_identifier)
+ \| [interface_identifier](#interface_identifier) `.` [port_identifier](#port_identifier)
### A.7.4 Specify path delays
-path\_delay\_value ::=
- [list_of_path_delay_expressions](#list_of_path_delay_expressions)
- \| `(` [list_of_path_delay_expressions](#list_of_path_delay_expressions) `)`
-list\_of\_path\_delay\_expressions ::=
- [t_path_delay_expression](#t_path_delay_expression)
- \| [trise_path_delay_expression](#trise_path_delay_expression) `,` [tfall_path_delay_expression](#tfall_path_delay_expression)
- \| [trise_path_delay_expression](#trise_path_delay_expression) `,` [tfall_path_delay_expression](#tfall_path_delay_expression) `,` [tz_path_delay_expression](#tz_path_delay_expression)
- \| [t01_path_delay_expression](#t01_path_delay_expression) `,` [t10_path_delay_expression](#t10_path_delay_expression) `,` [t0z_path_delay_expression](#t0z_path_delay_expression) `,`
- [tz1_path_delay_expression](#tz1_path_delay_expression) `,` [t1z_path_delay_expression](#t1z_path_delay_expression) `,` [tz0_path_delay_expression](#tz0_path_delay_expression)
- \| [t01_path_delay_expression](#t01_path_delay_expression) `,` [t10_path_delay_expression](#t10_path_delay_expression) `,` [t0z_path_delay_expression](#t0z_path_delay_expression) `,`
- [tz1_path_delay_expression](#tz1_path_delay_expression) `,` [t1z_path_delay_expression](#t1z_path_delay_expression) `,` [tz0_path_delay_expression](#tz0_path_delay_expression) `,`
- [t0x_path_delay_expression](#t0x_path_delay_expression) `,` [tx1_path_delay_expression](#tx1_path_delay_expression) `,` [t1x_path_delay_expression](#t1x_path_delay_expression) `,`
- [tx0_path_delay_expression](#tx0_path_delay_expression) `,` [txz_path_delay_expression](#txz_path_delay_expression) `,` [tzx_path_delay_expression](#tzx_path_delay_expression)
-t\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-trise\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-tfall\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-tz\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-t01\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-t10\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-t0z\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-tz1\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-t1z\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-tz0\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-t0x\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-tx1\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-t1x\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-tx0\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-txz\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-tzx\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
-path\_delay\_expression ::= [constant_mintypmax_expression](#constant_mintypmax_expression)
+path\_delay\_value ::=
+ [list_of_path_delay_expressions](#list_of_path_delay_expressions)
+ \| `(` [list_of_path_delay_expressions](#list_of_path_delay_expressions) `)`
+list\_of\_path\_delay\_expressions ::=
+ [t_path_delay_expression](#t_path_delay_expression)
+ \| [trise_path_delay_expression](#trise_path_delay_expression) `,` [tfall_path_delay_expression](#tfall_path_delay_expression)
+ \| [trise_path_delay_expression](#trise_path_delay_expression) `,` [tfall_path_delay_expression](#tfall_path_delay_expression) `,` [tz_path_delay_expression](#tz_path_delay_expression)
+ \| [t01_path_delay_expression](#t01_path_delay_expression) `,` [t10_path_delay_expression](#t10_path_delay_expression) `,` [t0z_path_delay_expression](#t0z_path_delay_expression) `,`
+ [tz1_path_delay_expression](#tz1_path_delay_expression) `,` [t1z_path_delay_expression](#t1z_path_delay_expression) `,` [tz0_path_delay_expression](#tz0_path_delay_expression)
+ \| [t01_path_delay_expression](#t01_path_delay_expression) `,` [t10_path_delay_expression](#t10_path_delay_expression) `,` [t0z_path_delay_expression](#t0z_path_delay_expression) `,`
+ [tz1_path_delay_expression](#tz1_path_delay_expression) `,` [t1z_path_delay_expression](#t1z_path_delay_expression) `,` [tz0_path_delay_expression](#tz0_path_delay_expression) `,`
+ [t0x_path_delay_expression](#t0x_path_delay_expression) `,` [tx1_path_delay_expression](#tx1_path_delay_expression) `,` [t1x_path_delay_expression](#t1x_path_delay_expression) `,`
+ [tx0_path_delay_expression](#tx0_path_delay_expression) `,` [txz_path_delay_expression](#txz_path_delay_expression) `,` [tzx_path_delay_expression](#tzx_path_delay_expression)
+t\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+trise\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+tfall\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+tz\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+t01\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+t10\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+t0z\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+tz1\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+t1z\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+tz0\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+t0x\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+tx1\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+t1x\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+tx0\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+txz\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+tzx\_path\_delay\_expression ::= [path_delay_expression](#path_delay_expression)
+path\_delay\_expression ::= [constant_mintypmax_expression](#constant_mintypmax_expression)
### A.7.5 System timing checks
#### A.7.5.1 System timing check commands
-system\_timing\_check ::=
- `$`[setup_timing_check](#setup_timing_check)
- \| `$`[hold_timing_check](#hold_timing_check)
- \| `$`[setuphold_timing_check](#setuphold_timing_check)
- \| `$`[recovery_timing_check](#recovery_timing_check)
- \| `$`[removal_timing_check](#removal_timing_check)
- \| `$`[recrem_timing_check](#recrem_timing_check)
- \| `$`[skew_timing_check](#skew_timing_check)
- \| `$`[timeskew_timing_check](#timeskew_timing_check)
- \| `$`[fullskew_timing_check](#fullskew_timing_check)
- \| `$`[period_timing_check](#period_timing_check)
- \| `$`[width_timing_check](#width_timing_check)
- \| `$`[nochange_timing_check](#nochange_timing_check)
- `$`
-setup\_timing\_check ::=
- `$`[setup](#setup) `(` [data_event](#data_event) `,` [reference_event](#reference_event) `,` [timing_check_limit](#timing_check_limit) \[ `,` \[ [notifier](#notifier) ] ] `)` `;`
- `$`
-hold\_timing\_check ::=
- `$`[hold](#hold) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit) \[ `,` \[ [notifier](#notifier) ] ] `)` `;`
- `$`
-setuphold\_timing\_check ::=
- `$`[setuphold](#setuphold) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit) `,` [timing_check_limit](#timing_check_limit)
- \[ `,` \[ [notifier](#notifier) ] \[ `,` \[ [timestamp_condition](#timestamp_condition) ] \[ `,` \[ [timecheck_condition](#timecheck_condition) ]
- \[ `,` \[ [delayed_reference](#delayed_reference) ] \[ `,` \[ [delayed_data](#delayed_data) ] ] ] ] ] ] `)` `;`
- `$`
-recovery\_timing\_check ::=
- `$`[recovery](#recovery) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit) \[ `,` \[ [notifier](#notifier) ] ] `)` `;`
- `$`
-removal\_timing\_check ::=
- `$`[removal](#removal) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit) \[ `,` \[ [notifier](#notifier) ] ] `)` `;`
- `$`
-recrem\_timing\_check ::=
- `$`[recrem](#recrem) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit) `,` [timing_check_limit](#timing_check_limit)
- \[ `,` \[ [notifier](#notifier) ] \[ `,` \[ [timestamp_condition](#timestamp_condition) ] \[ `,` \[ [timecheck_condition](#timecheck_condition) ]
- \[ `,` \[ [delayed_reference](#delayed_reference) ] \[ `,` \[ [delayed_data](#delayed_data) ] ] ] ] ] ] `)` `;`
- `$`
-skew\_timing\_check ::=
- `$`[skew](#skew) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit) \[ `,` \[ [notifier](#notifier) ] ] `)` `;`
- `$`
-timeskew\_timing\_check ::=
- `$`[timeskew](#timeskew) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit)
- \[ `,` \[ [notifier](#notifier) ] \[ `,` \[ [event_based_flag](#event_based_flag) ] \[ `,` \[ [remain_active_flag](#remain_active_flag) ] ] ] ] `)` `;`
- `$`
-fullskew\_timing\_check ::=
- `$`[fullskew](#fullskew) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit) `,` [timing_check_limit](#timing_check_limit)
- \[ `,` \[ [notifier](#notifier) ] \[ `,` \[ [event_based_flag](#event_based_flag) ] \[ `,` \[ [remain_active_flag](#remain_active_flag) ] ] ] ] `)` `;`
- `$`
-period\_timing\_check ::=
- `$`[period](#period) `(` [controlled_reference_event](#controlled_reference_event) `,` [timing_check_limit](#timing_check_limit) \[ `,` \[ [notifier](#notifier) ] ] `)` `;`
- `$`
-width\_timing\_check ::=
- `$`[width](#width) `(` [controlled_reference_event](#controlled_reference_event) `,` [timing_check_limit](#timing_check_limit) `,` [threshold](#threshold) \[ `,` \[ [notifier](#notifier) ] ] `)` `;`
- `$`
-nochange\_timing\_check ::=
- `$`[nochange](#nochange) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [start_edge_offset](#start_edge_offset) `,` [end_edge_offset](#end_edge_offset) \[ `,` \[ [notifier](#notifier) ] ] `);`
+system\_timing\_check ::=
+ `$`[setup_timing_check](#setup_timing_check)
+ \| `$`[hold_timing_check](#hold_timing_check)
+ \| `$`[setuphold_timing_check](#setuphold_timing_check)
+ \| `$`[recovery_timing_check](#recovery_timing_check)
+ \| `$`[removal_timing_check](#removal_timing_check)
+ \| `$`[recrem_timing_check](#recrem_timing_check)
+ \| `$`[skew_timing_check](#skew_timing_check)
+ \| `$`[timeskew_timing_check](#timeskew_timing_check)
+ \| `$`[fullskew_timing_check](#fullskew_timing_check)
+ \| `$`[period_timing_check](#period_timing_check)
+ \| `$`[width_timing_check](#width_timing_check)
+ \| `$`[nochange_timing_check](#nochange_timing_check)
+ `$`
+setup\_timing\_check ::=
+ `$`[setup](#setup) `(` [data_event](#data_event) `,` [reference_event](#reference_event) `,` [timing_check_limit](#timing_check_limit) \[ `,` \[ [notifier](#notifier) ] ] `)` `;`
+ `$`
+hold\_timing\_check ::=
+ `$`[hold](#hold) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit) \[ `,` \[ [notifier](#notifier) ] ] `)` `;`
+ `$`
+setuphold\_timing\_check ::=
+ `$`[setuphold](#setuphold) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit) `,` [timing_check_limit](#timing_check_limit)
+ \[ `,` \[ [notifier](#notifier) ] \[ `,` \[ [timestamp_condition](#timestamp_condition) ] \[ `,` \[ [timecheck_condition](#timecheck_condition) ]
+ \[ `,` \[ [delayed_reference](#delayed_reference) ] \[ `,` \[ [delayed_data](#delayed_data) ] ] ] ] ] ] `)` `;`
+ `$`
+recovery\_timing\_check ::=
+ `$`[recovery](#recovery) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit) \[ `,` \[ [notifier](#notifier) ] ] `)` `;`
+ `$`
+removal\_timing\_check ::=
+ `$`[removal](#removal) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit) \[ `,` \[ [notifier](#notifier) ] ] `)` `;`
+ `$`
+recrem\_timing\_check ::=
+ `$`[recrem](#recrem) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit) `,` [timing_check_limit](#timing_check_limit)
+ \[ `,` \[ [notifier](#notifier) ] \[ `,` \[ [timestamp_condition](#timestamp_condition) ] \[ `,` \[ [timecheck_condition](#timecheck_condition) ]
+ \[ `,` \[ [delayed_reference](#delayed_reference) ] \[ `,` \[ [delayed_data](#delayed_data) ] ] ] ] ] ] `)` `;`
+ `$`
+skew\_timing\_check ::=
+ `$`[skew](#skew) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit) \[ `,` \[ [notifier](#notifier) ] ] `)` `;`
+ `$`
+timeskew\_timing\_check ::=
+ `$`[timeskew](#timeskew) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit)
+ \[ `,` \[ [notifier](#notifier) ] \[ `,` \[ [event_based_flag](#event_based_flag) ] \[ `,` \[ [remain_active_flag](#remain_active_flag) ] ] ] ] `)` `;`
+ `$`
+fullskew\_timing\_check ::=
+ `$`[fullskew](#fullskew) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [timing_check_limit](#timing_check_limit) `,` [timing_check_limit](#timing_check_limit)
+ \[ `,` \[ [notifier](#notifier) ] \[ `,` \[ [event_based_flag](#event_based_flag) ] \[ `,` \[ [remain_active_flag](#remain_active_flag) ] ] ] ] `)` `;`
+ `$`
+period\_timing\_check ::=
+ `$`[period](#period) `(` [controlled_reference_event](#controlled_reference_event) `,` [timing_check_limit](#timing_check_limit) \[ `,` \[ [notifier](#notifier) ] ] `)` `;`
+ `$`
+width\_timing\_check ::=
+ `$`[width](#width) `(` [controlled_reference_event](#controlled_reference_event) `,` [timing_check_limit](#timing_check_limit) `,` [threshold](#threshold) \[ `,` \[ [notifier](#notifier) ] ] `)` `;`
+ `$`
+nochange\_timing\_check ::=
+ `$`[nochange](#nochange) `(` [reference_event](#reference_event) `,` [data_event](#data_event) `,` [start_edge_offset](#start_edge_offset) `,` [end_edge_offset](#end_edge_offset) \[ `,` \[ [notifier](#notifier) ] ] `);`
#### A.7.5.2 System timing check command arguments
-controlled\_reference\_event ::= [controlled_timing_check_event](#controlled_timing_check_event)
-data\_event ::= [timing_check_event](#timing_check_event)
-delayed\_data ::=
- [terminal_identifier](#terminal_identifier)
- \| [terminal_identifier](#terminal_identifier) \[ [constant_mintypmax_expression](#constant_mintypmax_expression) ]
-delayed\_reference ::=
- [terminal_identifier](#terminal_identifier)
- \| [terminal_identifier](#terminal_identifier) \[ [constant_mintypmax_expression](#constant_mintypmax_expression) ]
-end\_edge\_offset ::= [mintypmax_expression](#mintypmax_expression)
-event\_based\_flag ::= [constant_expression](#constant_expression)
-notifier ::= [variable_identifier](#variable_identifier)
-reference\_event ::= [timing_check_event](#timing_check_event)
-remain\_active\_flag ::= [constant_mintypmax_expression](#constant_mintypmax_expression)
-timecheck\_condition ::= [mintypmax_expression](#mintypmax_expression)
-timestamp\_condition ::= [mintypmax_expression](#mintypmax_expression)
-start\_edge\_offset ::= [mintypmax_expression](#mintypmax_expression)
-threshold ::= [constant_expression](#constant_expression)
-timing\_check\_limit ::= [expression](#expression)
+controlled\_reference\_event ::= [controlled_timing_check_event](#controlled_timing_check_event)
+data\_event ::= [timing_check_event](#timing_check_event)
+delayed\_data ::=
+ [terminal_identifier](#terminal_identifier)
+ \| [terminal_identifier](#terminal_identifier) \[ [constant_mintypmax_expression](#constant_mintypmax_expression) ]
+delayed\_reference ::=
+ [terminal_identifier](#terminal_identifier)
+ \| [terminal_identifier](#terminal_identifier) \[ [constant_mintypmax_expression](#constant_mintypmax_expression) ]
+end\_edge\_offset ::= [mintypmax_expression](#mintypmax_expression)
+event\_based\_flag ::= [constant_expression](#constant_expression)
+notifier ::= [variable_identifier](#variable_identifier)
+reference\_event ::= [timing_check_event](#timing_check_event)
+remain\_active\_flag ::= [constant_mintypmax_expression](#constant_mintypmax_expression)
+timecheck\_condition ::= [mintypmax_expression](#mintypmax_expression)
+timestamp\_condition ::= [mintypmax_expression](#mintypmax_expression)
+start\_edge\_offset ::= [mintypmax_expression](#mintypmax_expression)
+threshold ::= [constant_expression](#constant_expression)
+timing\_check\_limit ::= [expression](#expression)
#### A.7.5.3 System timing check event definitions
-timing\_check\_event ::=
- \[ [timing_check_event_control](#timing_check_event_control) ] [specify_terminal_descriptor](#specify_terminal_descriptor) \[ `&&&` [timing_check_condition](#timing_check_condition) ]
-controlled\_timing\_check\_event ::=
- [timing_check_event_control](#timing_check_event_control) [specify_terminal_descriptor](#specify_terminal_descriptor) \[ `&&&` [timing_check_condition](#timing_check_condition) ]
-timing\_check\_event\_control ::=
- [posedge](#posedge)
- \| [negedge](#negedge)
- \| [edge](#edge)
- \| [edge_control_specifier](#edge_control_specifier)
-specify\_terminal\_descriptor ::=
- [specify_input_terminal_descriptor](#specify_input_terminal_descriptor)
- \| [specify_output_terminal_descriptor](#specify_output_terminal_descriptor)
-edge\_control\_specifier ::= [edge](#edge) \[ [edge_descriptor](#edge_descriptor) \{ `,` [edge_descriptor](#edge_descriptor) } ]
-edge\_descriptor38 ::= [01](#01) \| [10](#10) \| [z_or_x](#z_or_x) [zero_or_one](#zero_or_one) \| [zero_or_one](#zero_or_one) [z_or_x](#z_or_x)
-zero\_or\_one ::= [0](#0) \| [1](#1)
-z\_or\_x ::= [x](#x) \| [X](#X) \| [z](#z) \| [Z](#Z)
-timing\_check\_condition ::=
- [scalar_timing_check_condition](#scalar_timing_check_condition)
- \| `(` [scalar_timing_check_condition](#scalar_timing_check_condition) `)`
-scalar\_timing\_check\_condition ::=
- [expression](#expression)
- \| `~` [expression](#expression)
- \| [expression](#expression) `==` [scalar_constant](#scalar_constant)
- \| [expression](#expression) `===` [scalar_constant](#scalar_constant)
- \| [expression](#expression) `!=` [scalar_constant](#scalar_constant)
- \| [expression](#expression) `!==` [scalar_constant](#scalar_constant)
-scalar\_constant ::= [1](#1)`'`[b0](#b0) \| [1](#1)`'`[b1](#b1) \| [1](#1)`'`[B0](#B0) \| [1](#1)`'`[B1](#B1) \| `'`[b0](#b0) \| `'`[b1](#b1) \| `'`[B0](#B0) \| `'`[B1](#B1) \| [1](#1) \| [0](#0)
+timing\_check\_event ::=
+ \[ [timing_check_event_control](#timing_check_event_control) ] [specify_terminal_descriptor](#specify_terminal_descriptor) \[ `&&&` [timing_check_condition](#timing_check_condition) ]
+controlled\_timing\_check\_event ::=
+ [timing_check_event_control](#timing_check_event_control) [specify_terminal_descriptor](#specify_terminal_descriptor) \[ `&&&` [timing_check_condition](#timing_check_condition) ]
+timing\_check\_event\_control ::=
+ [posedge](#posedge)
+ \| [negedge](#negedge)
+ \| [edge](#edge)
+ \| [edge_control_specifier](#edge_control_specifier)
+specify\_terminal\_descriptor ::=
+ [specify_input_terminal_descriptor](#specify_input_terminal_descriptor)
+ \| [specify_output_terminal_descriptor](#specify_output_terminal_descriptor)
+edge\_control\_specifier ::= [edge](#edge) \[ [edge_descriptor](#edge_descriptor) \{ `,` [edge_descriptor](#edge_descriptor) } ]
+edge\_descriptor38 ::= [01](#01) \| [10](#10) \| [z_or_x](#z_or_x) [zero_or_one](#zero_or_one) \| [zero_or_one](#zero_or_one) [z_or_x](#z_or_x)
+zero\_or\_one ::= [0](#0) \| [1](#1)
+z\_or\_x ::= [x](#x) \| [X](#X) \| [z](#z) \| [Z](#Z)
+timing\_check\_condition ::=
+ [scalar_timing_check_condition](#scalar_timing_check_condition)
+ \| `(` [scalar_timing_check_condition](#scalar_timing_check_condition) `)`
+scalar\_timing\_check\_condition ::=
+ [expression](#expression)
+ \| `~` [expression](#expression)
+ \| [expression](#expression) `==` [scalar_constant](#scalar_constant)
+ \| [expression](#expression) `===` [scalar_constant](#scalar_constant)
+ \| [expression](#expression) `!=` [scalar_constant](#scalar_constant)
+ \| [expression](#expression) `!==` [scalar_constant](#scalar_constant)
+scalar\_constant ::= [1](#1)`'`[b0](#b0) \| [1](#1)`'`[b1](#b1) \| [1](#1)`'`[B0](#B0) \| [1](#1)`'`[B1](#B1) \| `'`[b0](#b0) \| `'`[b1](#b1) \| `'`[B0](#B0) \| `'`[B1](#B1) \| [1](#1) \| [0](#0)
## A.8 Expressions
### A.8.1 Concatenations
-concatenation ::=
- \{ [expression](#expression) \{ `,` [expression](#expression) } }
-constant\_concatenation ::=
- \{ [constant_expression](#constant_expression) \{ `,` [constant_expression](#constant_expression) } }
-constant\_multiple\_concatenation ::= \{ [constant_expression](#constant_expression) [constant_concatenation](#constant_concatenation) }
-module\_path\_concatenation ::= \{ [module_path_expression](#module_path_expression) \{ `,` [module_path_expression](#module_path_expression) } }
-module\_path\_multiple\_concatenation ::= \{ [constant_expression](#constant_expression) [module_path_concatenation](#module_path_concatenation) }
-multiple\_concatenation ::= \{ [expression](#expression) [concatenation](#concatenation) }[39](#39)
-streaming\_concatenation ::= \{ [stream_operator](#stream_operator) \[ [slice_size](#slice_size) ] [stream_concatenation](#stream_concatenation) }
-stream\_operator ::= `>>` \| `<<`
-slice\_size ::= [simple_type](#simple_type) \| [constant_expression](#constant_expression)
-stream\_concatenation ::= \{ [stream_expression](#stream_expression) \{ `,` [stream_expression](#stream_expression) } }
-stream\_expression ::= [expression](#expression) \[ [with](#with) \[ [array_range_expression](#array_range_expression) ] ]
-array\_range\_expression ::=
- [expression](#expression)
- \| [expression](#expression) `:` [expression](#expression)
- \| [expression](#expression) `+:` [expression](#expression)
- \| [expression](#expression) `-:` [expression](#expression)
-empty\_unpacked\_array\_concatenation40 ::= \{ }
+concatenation ::=
+ \{ [expression](#expression) \{ `,` [expression](#expression) } }
+constant\_concatenation ::=
+ \{ [constant_expression](#constant_expression) \{ `,` [constant_expression](#constant_expression) } }
+constant\_multiple\_concatenation ::= \{ [constant_expression](#constant_expression) [constant_concatenation](#constant_concatenation) }
+module\_path\_concatenation ::= \{ [module_path_expression](#module_path_expression) \{ `,` [module_path_expression](#module_path_expression) } }
+module\_path\_multiple\_concatenation ::= \{ [constant_expression](#constant_expression) [module_path_concatenation](#module_path_concatenation) }
+multiple\_concatenation ::= \{ [expression](#expression) [concatenation](#concatenation) }[39](#39)
+streaming\_concatenation ::= \{ [stream_operator](#stream_operator) \[ [slice_size](#slice_size) ] [stream_concatenation](#stream_concatenation) }
+stream\_operator ::= `>>` \| `<<`
+slice\_size ::= [simple_type](#simple_type) \| [constant_expression](#constant_expression)
+stream\_concatenation ::= \{ [stream_expression](#stream_expression) \{ `,` [stream_expression](#stream_expression) } }
+stream\_expression ::= [expression](#expression) \[ [with](#with) \[ [array_range_expression](#array_range_expression) ] ]
+array\_range\_expression ::=
+ [expression](#expression)
+ \| [expression](#expression) `:` [expression](#expression)
+ \| [expression](#expression) `+:` [expression](#expression)
+ \| [expression](#expression) `-:` [expression](#expression)
+empty\_unpacked\_array\_concatenation40 ::= \{ }
### A.8.2 Subroutine calls
-constant\_function\_call ::= [function_subroutine_call41](#function_subroutine_call41)
-tf\_call42 ::= [ps_or_hierarchical_tf_identifier](#ps_or_hierarchical_tf_identifier) \{ [attribute_instance](#attribute_instance) } \[ `(` [list_of_arguments](#list_of_arguments) `)` ]
-system\_tf\_call ::=
- [system_tf_identifier](#system_tf_identifier) \[ `(` [list_of_arguments](#list_of_arguments) `)` ]
- \| [system_tf_identifier](#system_tf_identifier) `(` [data_type](#data_type) \[ `,` [expression](#expression) ] `)`
- \| [system_tf_identifier](#system_tf_identifier) `(` [expression](#expression) \{ `,` \[ [expression](#expression) ] } \[ `,` \[ [clocking_event](#clocking_event) ] ] `)`
-subroutine\_call ::=
- [tf_call](#tf_call)
- \| [system_tf_call](#system_tf_call)
- \| [method_call](#method_call)
- \| \[ [std](#std) `::` ] [randomize_call](#randomize_call)
-function\_subroutine\_call ::= [subroutine_call](#subroutine_call)
-list\_of\_arguments ::=
- \[ [expression](#expression) ] \{ `,` \[ [expression](#expression) ] } \{ `,` `.` [identifier](#identifier) `(` \[ [expression](#expression) ] `)` }
- \| `.` [identifier](#identifier) `(` \[ [expression](#expression) ] `)` \{ `,` `.` [identifier](#identifier) `(` \[ [expression](#expression) ] `)` }
-method\_call ::= [method_call_root](#method_call_root) `.` [method_call_body](#method_call_body)
-method\_call\_body ::=
- [method_identifier](#method_identifier) \{ [attribute_instance](#attribute_instance) } \[ `(` [list_of_arguments](#list_of_arguments) `)` ]
- \| [built_in_method_call](#built_in_method_call)
-built\_in\_method\_call ::= [array_manipulation_call](#array_manipulation_call) \| [randomize_call](#randomize_call)
-array\_manipulation\_call ::=
- [array_method_name](#array_method_name) \{ [attribute_instance](#attribute_instance) }
- \[ `(` [list_of_arguments](#list_of_arguments) `)` ]
- \[ [with](#with) `(` [expression](#expression) `)` ]
-randomize\_call ::=
- [randomize](#randomize) \{ [attribute_instance](#attribute_instance) }
- \[ `(` \[ [variable_identifier_list](#variable_identifier_list) \| [null](#null) ] `)` ]
- \[ [with](#with) \[ `(` \[ [identifier_list](#identifier_list) ] `)` ] [constraint_block](#constraint_block) ][43](#43)
-variable\_identifier\_list ::= [variable_identifier](#variable_identifier) \{ `,` [variable_identifier](#variable_identifier) }
-identifier\_list ::= [identifier](#identifier) \{ `,` [identifier](#identifier) }
-method\_call\_root ::= [primary](#primary) \| [implicit_class_handle](#implicit_class_handle)
-array\_method\_name ::= [method_identifier](#method_identifier) \| [unique](#unique) \| [and](#and) \| [or](#or) \| [xor](#xor)
+constant\_function\_call ::= [function_subroutine_call41](#function_subroutine_call41)
+tf\_call42 ::= [ps_or_hierarchical_tf_identifier](#ps_or_hierarchical_tf_identifier) \{ [attribute_instance](#attribute_instance) } \[ `(` [list_of_arguments](#list_of_arguments) `)` ]
+system\_tf\_call ::=
+ [system_tf_identifier](#system_tf_identifier) \[ `(` [list_of_arguments](#list_of_arguments) `)` ]
+ \| [system_tf_identifier](#system_tf_identifier) `(` [data_type](#data_type) \[ `,` [expression](#expression) ] `)`
+ \| [system_tf_identifier](#system_tf_identifier) `(` [expression](#expression) \{ `,` \[ [expression](#expression) ] } \[ `,` \[ [clocking_event](#clocking_event) ] ] `)`
+subroutine\_call ::=
+ [tf_call](#tf_call)
+ \| [system_tf_call](#system_tf_call)
+ \| [method_call](#method_call)
+ \| \[ [std](#std) `::` ] [randomize_call](#randomize_call)
+function\_subroutine\_call ::= [subroutine_call](#subroutine_call)
+list\_of\_arguments ::=
+ \[ [expression](#expression) ] \{ `,` \[ [expression](#expression) ] } \{ `,` `.` [identifier](#identifier) `(` \[ [expression](#expression) ] `)` }
+ \| `.` [identifier](#identifier) `(` \[ [expression](#expression) ] `)` \{ `,` `.` [identifier](#identifier) `(` \[ [expression](#expression) ] `)` }
+method\_call ::= [method_call_root](#method_call_root) `.` [method_call_body](#method_call_body)
+method\_call\_body ::=
+ [method_identifier](#method_identifier) \{ [attribute_instance](#attribute_instance) } \[ `(` [list_of_arguments](#list_of_arguments) `)` ]
+ \| [built_in_method_call](#built_in_method_call)
+built\_in\_method\_call ::= [array_manipulation_call](#array_manipulation_call) \| [randomize_call](#randomize_call)
+array\_manipulation\_call ::=
+ [array_method_name](#array_method_name) \{ [attribute_instance](#attribute_instance) }
+ \[ `(` [list_of_arguments](#list_of_arguments) `)` ]
+ \[ [with](#with) `(` [expression](#expression) `)` ]
+randomize\_call ::=
+ [randomize](#randomize) \{ [attribute_instance](#attribute_instance) }
+ \[ `(` \[ [variable_identifier_list](#variable_identifier_list) \| [null](#null) ] `)` ]
+ \[ [with](#with) \[ `(` \[ [identifier_list](#identifier_list) ] `)` ] [constraint_block](#constraint_block) ][43](#43)
+variable\_identifier\_list ::= [variable_identifier](#variable_identifier) \{ `,` [variable_identifier](#variable_identifier) }
+identifier\_list ::= [identifier](#identifier) \{ `,` [identifier](#identifier) }
+method\_call\_root ::= [primary](#primary) \| [implicit_class_handle](#implicit_class_handle)
+array\_method\_name ::= [method_identifier](#method_identifier) \| [unique](#unique) \| [and](#and) \| [or](#or) \| [xor](#xor)
### A.8.3 Expressions
-inc\_or\_dec\_expression ::=
- [inc_or_dec_operator](#inc_or_dec_operator) \{ [attribute_instance](#attribute_instance) } [variable_lvalue](#variable_lvalue)
- \| [variable_lvalue](#variable_lvalue) \{ [attribute_instance](#attribute_instance) } [inc_or_dec_operator](#inc_or_dec_operator)
-conditional\_expression ::= [cond_predicate](#cond_predicate) `?` \{ [attribute_instance](#attribute_instance) } [expression](#expression) `:` [expression](#expression)
-constant\_expression ::=
- [constant_primary](#constant_primary)
- \| [unary_operator](#unary_operator) \{ [attribute_instance](#attribute_instance) } [constant_primary](#constant_primary)
- \| [constant_expression](#constant_expression) [binary_operator](#binary_operator) \{ [attribute_instance](#attribute_instance) } [constant_expression](#constant_expression)
- \| [constant_expression](#constant_expression) `?` \{ [attribute_instance](#attribute_instance) } [constant_expression](#constant_expression) `:` [constant_expression](#constant_expression)
-constant\_mintypmax\_expression ::=
- [constant_expression](#constant_expression)
- \| [constant_expression](#constant_expression) `:` [constant_expression](#constant_expression) `:` [constant_expression](#constant_expression)
-constant\_param\_expression ::= [constant_mintypmax_expression](#constant_mintypmax_expression) \| [data_type](#data_type) \| `$`
-param\_expression ::= [mintypmax_expression](#mintypmax_expression) \| [data_type](#data_type) \| `$`
-constant\_range\_expression ::= [constant_expression](#constant_expression) \| [constant_part_select_range](#constant_part_select_range)
-constant\_part\_select\_range ::= [constant_range](#constant_range) \| [constant_indexed_range](#constant_indexed_range)
-constant\_range ::= [constant_expression](#constant_expression) `:` [constant_expression](#constant_expression)
-constant\_indexed\_range ::=
- [constant_expression](#constant_expression) `+:` [constant_expression](#constant_expression)
- \| [constant_expression](#constant_expression) `-:` [constant_expression](#constant_expression)
-expression ::=
- [primary](#primary)
- \| [unary_operator](#unary_operator) \{ [attribute_instance](#attribute_instance) } [primary](#primary)
- \| [inc_or_dec_expression](#inc_or_dec_expression)
- \| `(` [operator_assignment](#operator_assignment) `)`
- \| [expression](#expression) [binary_operator](#binary_operator) \{ [attribute_instance](#attribute_instance) } [expression](#expression)
- \| [conditional_expression](#conditional_expression)
- \| [inside_expression](#inside_expression)
- \| [tagged_union_expression](#tagged_union_expression)
-tagged\_union\_expression ::=
- [tagged](#tagged) [member_identifier](#member_identifier) \[ [primary](#primary) ]
-inside\_expression ::= [expression](#expression) [inside](#inside) \{ [range_list](#range_list) }
-mintypmax\_expression ::=
- [expression](#expression)
- \| [expression](#expression) `:` [expression](#expression) `:` [expression](#expression)
-module\_path\_conditional\_expression ::= [module_path_expression](#module_path_expression) `?` \{ [attribute_instance](#attribute_instance) }
- [module_path_expression](#module_path_expression) `:` [module_path_expression](#module_path_expression)
-module\_path\_expression ::=
- [module_path_primary](#module_path_primary)
- \| [unary_module_path_operator](#unary_module_path_operator) \{ [attribute_instance](#attribute_instance) } [module_path_primary](#module_path_primary)
- \| [module_path_expression](#module_path_expression) [binary_module_path_operator](#binary_module_path_operator) \{ [attribute_instance](#attribute_instance) }
- [module_path_expression](#module_path_expression)
- \| [module_path_conditional_expression](#module_path_conditional_expression)
-module\_path\_mintypmax\_expression ::=
- [module_path_expression](#module_path_expression)
- \| [module_path_expression](#module_path_expression) `:` [module_path_expression](#module_path_expression) `:` [module_path_expression](#module_path_expression)
-part\_select\_range ::= [constant_range](#constant_range) \| [indexed_range](#indexed_range)
-indexed\_range ::=
- [expression](#expression) `+:` [constant_expression](#constant_expression)
- \| [expression](#expression) `-:` [constant_expression](#constant_expression)
-genvar\_expression ::= [constant_expression](#constant_expression)
+inc\_or\_dec\_expression ::=
+ [inc_or_dec_operator](#inc_or_dec_operator) \{ [attribute_instance](#attribute_instance) } [variable_lvalue](#variable_lvalue)
+ \| [variable_lvalue](#variable_lvalue) \{ [attribute_instance](#attribute_instance) } [inc_or_dec_operator](#inc_or_dec_operator)
+conditional\_expression ::= [cond_predicate](#cond_predicate) `?` \{ [attribute_instance](#attribute_instance) } [expression](#expression) `:` [expression](#expression)
+constant\_expression ::=
+ [constant_primary](#constant_primary)
+ \| [unary_operator](#unary_operator) \{ [attribute_instance](#attribute_instance) } [constant_primary](#constant_primary)
+ \| [constant_expression](#constant_expression) [binary_operator](#binary_operator) \{ [attribute_instance](#attribute_instance) } [constant_expression](#constant_expression)
+ \| [constant_expression](#constant_expression) `?` \{ [attribute_instance](#attribute_instance) } [constant_expression](#constant_expression) `:` [constant_expression](#constant_expression)
+constant\_mintypmax\_expression ::=
+ [constant_expression](#constant_expression)
+ \| [constant_expression](#constant_expression) `:` [constant_expression](#constant_expression) `:` [constant_expression](#constant_expression)
+constant\_param\_expression ::= [constant_mintypmax_expression](#constant_mintypmax_expression) \| [data_type](#data_type) \| `$`
+param\_expression ::= [mintypmax_expression](#mintypmax_expression) \| [data_type](#data_type) \| `$`
+constant\_range\_expression ::= [constant_expression](#constant_expression) \| [constant_part_select_range](#constant_part_select_range)
+constant\_part\_select\_range ::= [constant_range](#constant_range) \| [constant_indexed_range](#constant_indexed_range)
+constant\_range ::= [constant_expression](#constant_expression) `:` [constant_expression](#constant_expression)
+constant\_indexed\_range ::=
+ [constant_expression](#constant_expression) `+:` [constant_expression](#constant_expression)
+ \| [constant_expression](#constant_expression) `-:` [constant_expression](#constant_expression)
+expression ::=
+ [primary](#primary)
+ \| [unary_operator](#unary_operator) \{ [attribute_instance](#attribute_instance) } [primary](#primary)
+ \| [inc_or_dec_expression](#inc_or_dec_expression)
+ \| `(` [operator_assignment](#operator_assignment) `)`
+ \| [expression](#expression) [binary_operator](#binary_operator) \{ [attribute_instance](#attribute_instance) } [expression](#expression)
+ \| [conditional_expression](#conditional_expression)
+ \| [inside_expression](#inside_expression)
+ \| [tagged_union_expression](#tagged_union_expression)
+tagged\_union\_expression ::=
+ [tagged](#tagged) [member_identifier](#member_identifier) \[ [primary](#primary) ]
+inside\_expression ::= [expression](#expression) [inside](#inside) \{ [range_list](#range_list) }
+mintypmax\_expression ::=
+ [expression](#expression)
+ \| [expression](#expression) `:` [expression](#expression) `:` [expression](#expression)
+module\_path\_conditional\_expression ::= [module_path_expression](#module_path_expression) `?` \{ [attribute_instance](#attribute_instance) }
+ [module_path_expression](#module_path_expression) `:` [module_path_expression](#module_path_expression)
+module\_path\_expression ::=
+ [module_path_primary](#module_path_primary)
+ \| [unary_module_path_operator](#unary_module_path_operator) \{ [attribute_instance](#attribute_instance) } [module_path_primary](#module_path_primary)
+ \| [module_path_expression](#module_path_expression) [binary_module_path_operator](#binary_module_path_operator) \{ [attribute_instance](#attribute_instance) }
+ [module_path_expression](#module_path_expression)
+ \| [module_path_conditional_expression](#module_path_conditional_expression)
+module\_path\_mintypmax\_expression ::=
+ [module_path_expression](#module_path_expression)
+ \| [module_path_expression](#module_path_expression) `:` [module_path_expression](#module_path_expression) `:` [module_path_expression](#module_path_expression)
+part\_select\_range ::= [constant_range](#constant_range) \| [indexed_range](#indexed_range)
+indexed\_range ::=
+ [expression](#expression) `+:` [constant_expression](#constant_expression)
+ \| [expression](#expression) `-:` [constant_expression](#constant_expression)
+genvar\_expression ::= [constant_expression](#constant_expression)
### A.8.4 Primaries
-constant\_primary ::=
- [primary_literal](#primary_literal)
- \| [ps_parameter_identifier](#ps_parameter_identifier) [constant_select](#constant_select)
- \| [specparam_identifier](#specparam_identifier) \[ \[ [constant_range_expression](#constant_range_expression) ] ]
- \| [genvar_identifier44](#genvar_identifier44)
- \| [formal_port_identifier](#formal_port_identifier) [constant_select](#constant_select)
- \| \[ [package_scope](#package_scope) \| [class_scope](#class_scope) ] [enum_identifier](#enum_identifier)
- \| [empty_unpacked_array_concatenation](#empty_unpacked_array_concatenation)
- \| [constant_concatenation](#constant_concatenation) \[ \[ [constant_range_expression](#constant_range_expression) ] ]
- \| [constant_multiple_concatenation](#constant_multiple_concatenation) \[ \[ [constant_range_expression](#constant_range_expression) ] ]
- \| [constant_function_call](#constant_function_call) \[ \[ [constant_range_expression](#constant_range_expression) ] ]
- \| [constant_let_expression](#constant_let_expression)
- \| `(` [constant_mintypmax_expression](#constant_mintypmax_expression) `)`
- \| [constant_cast](#constant_cast)
- \| [constant_assignment_pattern_expression](#constant_assignment_pattern_expression)
- \| [type_reference45](#type_reference45)
- \| [null](#null)
-module\_path\_primary ::=
- [number](#number)
- \| [identifier](#identifier)
- \| [module_path_concatenation](#module_path_concatenation)
- \| [module_path_multiple_concatenation](#module_path_multiple_concatenation)
- \| [function_subroutine_call](#function_subroutine_call)
- \| `(` [module_path_mintypmax_expression](#module_path_mintypmax_expression) `)`
-primary ::=
- [primary_literal](#primary_literal)
- \| \[ [class_qualifier](#class_qualifier) \| [package_scope](#package_scope) ] [hierarchical_identifier](#hierarchical_identifier) [select](#select)
- \| [empty_unpacked_array_concatenation](#empty_unpacked_array_concatenation)
- \| [concatenation](#concatenation) \[ \[ [range_expression](#range_expression) ] ]
- \| [multiple_concatenation](#multiple_concatenation) \[ \[ [range_expression](#range_expression) ] ]
- \| [function_subroutine_call](#function_subroutine_call) \[ \[ [range_expression](#range_expression) ] ]
- \| [let_expression](#let_expression)
- \| `(` [mintypmax_expression](#mintypmax_expression) `)`
- \| [cast](#cast)
- \| [assignment_pattern_expression](#assignment_pattern_expression)
- \| [streaming_concatenation](#streaming_concatenation)
- \| [sequence_method_call](#sequence_method_call)
- \| [this46](#this46)
- \| `$`[47](#47)
- \| [null](#null)
- [class_qualifier](#class_qualifier) `:=` \[ [local](#local) `::`[48](#48) ] \[ [implicit_class_handle](#implicit_class_handle) `.` \| [class_scope](#class_scope) ]
-range\_expression ::= [expression](#expression) \| [part_select_range](#part_select_range)
-primary\_literal ::= [number](#number) \| [time_literal](#time_literal) \| [unbased_unsized_literal](#unbased_unsized_literal) \| [string_literal](#string_literal)
-time\_literal49 ::=
- [unsigned_number](#unsigned_number) [time_unit](#time_unit)
- \| [fixed_point_number](#fixed_point_number) [time_unit](#time_unit)
-time\_unit ::= [s](#s) \| [ms](#ms) \| [us](#us) \| [ns](#ns) \| [ps](#ps) \| [fs](#fs)
-implicit\_class\_handle46 ::= [this](#this) \| [super](#super) \| [this](#this) `.` [super](#super)
-bit\_select ::= \{ \[ [expression](#expression) ] }
-select ::=
- \[ \{ `.` [member_identifier](#member_identifier) [bit_select](#bit_select) } `.` [member_identifier](#member_identifier) ] [bit_select](#bit_select) \[ \[ [part_select_range](#part_select_range) ] ]
-nonrange\_select ::=
- \[ \{ `.` [member_identifier](#member_identifier) [bit_select](#bit_select) } `.` [member_identifier](#member_identifier) ] [bit_select](#bit_select)
-constant\_bit\_select ::= \{ \[ [constant_expression](#constant_expression) ] }
-constant\_select ::=
- \[ \{ `.` [member_identifier](#member_identifier) [constant_bit_select](#constant_bit_select) } `.` [member_identifier](#member_identifier) ] [constant_bit_select](#constant_bit_select)
- \[ \[ [constant_part_select_range](#constant_part_select_range) ] ]
-cast ::= [casting_type](#casting_type) `'` `(` [expression](#expression) `)`
-constant\_cast ::= [casting_type](#casting_type) `'` `(` [constant_expression](#constant_expression) `)`
-constant\_let\_expression ::= [let_expression50](#let_expression50)
+constant\_primary ::=
+ [primary_literal](#primary_literal)
+ \| [ps_parameter_identifier](#ps_parameter_identifier) [constant_select](#constant_select)
+ \| [specparam_identifier](#specparam_identifier) \[ \[ [constant_range_expression](#constant_range_expression) ] ]
+ \| [genvar_identifier44](#genvar_identifier44)
+ \| [formal_port_identifier](#formal_port_identifier) [constant_select](#constant_select)
+ \| \[ [package_scope](#package_scope) \| [class_scope](#class_scope) ] [enum_identifier](#enum_identifier)
+ \| [empty_unpacked_array_concatenation](#empty_unpacked_array_concatenation)
+ \| [constant_concatenation](#constant_concatenation) \[ \[ [constant_range_expression](#constant_range_expression) ] ]
+ \| [constant_multiple_concatenation](#constant_multiple_concatenation) \[ \[ [constant_range_expression](#constant_range_expression) ] ]
+ \| [constant_function_call](#constant_function_call) \[ \[ [constant_range_expression](#constant_range_expression) ] ]
+ \| [constant_let_expression](#constant_let_expression)
+ \| `(` [constant_mintypmax_expression](#constant_mintypmax_expression) `)`
+ \| [constant_cast](#constant_cast)
+ \| [constant_assignment_pattern_expression](#constant_assignment_pattern_expression)
+ \| [type_reference45](#type_reference45)
+ \| [null](#null)
+module\_path\_primary ::=
+ [number](#number)
+ \| [identifier](#identifier)
+ \| [module_path_concatenation](#module_path_concatenation)
+ \| [module_path_multiple_concatenation](#module_path_multiple_concatenation)
+ \| [function_subroutine_call](#function_subroutine_call)
+ \| `(` [module_path_mintypmax_expression](#module_path_mintypmax_expression) `)`
+primary ::=
+ [primary_literal](#primary_literal)
+ \| \[ [class_qualifier](#class_qualifier) \| [package_scope](#package_scope) ] [hierarchical_identifier](#hierarchical_identifier) [select](#select)
+ \| [empty_unpacked_array_concatenation](#empty_unpacked_array_concatenation)
+ \| [concatenation](#concatenation) \[ \[ [range_expression](#range_expression) ] ]
+ \| [multiple_concatenation](#multiple_concatenation) \[ \[ [range_expression](#range_expression) ] ]
+ \| [function_subroutine_call](#function_subroutine_call) \[ \[ [range_expression](#range_expression) ] ]
+ \| [let_expression](#let_expression)
+ \| `(` [mintypmax_expression](#mintypmax_expression) `)`
+ \| [cast](#cast)
+ \| [assignment_pattern_expression](#assignment_pattern_expression)
+ \| [streaming_concatenation](#streaming_concatenation)
+ \| [sequence_method_call](#sequence_method_call)
+ \| [this46](#this46)
+ \| `$`[47](#47)
+ \| [null](#null)
+ [class_qualifier](#class_qualifier) `:=` \[ [local](#local) `::`[48](#48) ] \[ [implicit_class_handle](#implicit_class_handle) `.` \| [class_scope](#class_scope) ]
+range\_expression ::= [expression](#expression) \| [part_select_range](#part_select_range)
+primary\_literal ::= [number](#number) \| [time_literal](#time_literal) \| [unbased_unsized_literal](#unbased_unsized_literal) \| [string_literal](#string_literal)
+time\_literal49 ::=
+ [unsigned_number](#unsigned_number) [time_unit](#time_unit)
+ \| [fixed_point_number](#fixed_point_number) [time_unit](#time_unit)
+time\_unit ::= [s](#s) \| [ms](#ms) \| [us](#us) \| [ns](#ns) \| [ps](#ps) \| [fs](#fs)
+implicit\_class\_handle46 ::= [this](#this) \| [super](#super) \| [this](#this) `.` [super](#super)
+bit\_select ::= \{ \[ [expression](#expression) ] }
+select ::=
+ \[ \{ `.` [member_identifier](#member_identifier) [bit_select](#bit_select) } `.` [member_identifier](#member_identifier) ] [bit_select](#bit_select) \[ \[ [part_select_range](#part_select_range) ] ]
+nonrange\_select ::=
+ \[ \{ `.` [member_identifier](#member_identifier) [bit_select](#bit_select) } `.` [member_identifier](#member_identifier) ] [bit_select](#bit_select)
+constant\_bit\_select ::= \{ \[ [constant_expression](#constant_expression) ] }
+constant\_select ::=
+ \[ \{ `.` [member_identifier](#member_identifier) [constant_bit_select](#constant_bit_select) } `.` [member_identifier](#member_identifier) ] [constant_bit_select](#constant_bit_select)
+ \[ \[ [constant_part_select_range](#constant_part_select_range) ] ]
+cast ::= [casting_type](#casting_type) `'` `(` [expression](#expression) `)`
+constant\_cast ::= [casting_type](#casting_type) `'` `(` [constant_expression](#constant_expression) `)`
+constant\_let\_expression ::= [let_expression50](#let_expression50)
### A.8.5 Expression left-side values
-net\_lvalue ::=
- [ps_or_hierarchical_net_identifier](#ps_or_hierarchical_net_identifier) [constant_select](#constant_select)
- \| \{ [net_lvalue](#net_lvalue) \{ `,` [net_lvalue](#net_lvalue) } }
- \| \[ [assignment_pattern_expression_type](#assignment_pattern_expression_type) ] [assignment_pattern_net_lvalue](#assignment_pattern_net_lvalue)
-variable\_lvalue ::=
- \[ [implicit_class_handle](#implicit_class_handle) `.` \| [package_scope](#package_scope) ] [hierarchical_variable_identifier](#hierarchical_variable_identifier) [select51](#select51)
- \| \{ [variable_lvalue](#variable_lvalue) \{ `,` [variable_lvalue](#variable_lvalue) } }
- \| \[ [assignment_pattern_expression_type](#assignment_pattern_expression_type) ] [assignment_pattern_variable_lvalue](#assignment_pattern_variable_lvalue)
- \| [streaming_concatenation52](#streaming_concatenation52)
-nonrange\_variable\_lvalue ::=
- \[ [implicit_class_handle](#implicit_class_handle) `.` \| [package_scope](#package_scope) ] [hierarchical_variable_identifier](#hierarchical_variable_identifier) [nonrange_select](#nonrange_select)
+net\_lvalue ::=
+ [ps_or_hierarchical_net_identifier](#ps_or_hierarchical_net_identifier) [constant_select](#constant_select)
+ \| \{ [net_lvalue](#net_lvalue) \{ `,` [net_lvalue](#net_lvalue) } }
+ \| \[ [assignment_pattern_expression_type](#assignment_pattern_expression_type) ] [assignment_pattern_net_lvalue](#assignment_pattern_net_lvalue)
+variable\_lvalue ::=
+ \[ [implicit_class_handle](#implicit_class_handle) `.` \| [package_scope](#package_scope) ] [hierarchical_variable_identifier](#hierarchical_variable_identifier) [select51](#select51)
+ \| \{ [variable_lvalue](#variable_lvalue) \{ `,` [variable_lvalue](#variable_lvalue) } }
+ \| \[ [assignment_pattern_expression_type](#assignment_pattern_expression_type) ] [assignment_pattern_variable_lvalue](#assignment_pattern_variable_lvalue)
+ \| [streaming_concatenation52](#streaming_concatenation52)
+nonrange\_variable\_lvalue ::=
+ \[ [implicit_class_handle](#implicit_class_handle) `.` \| [package_scope](#package_scope) ] [hierarchical_variable_identifier](#hierarchical_variable_identifier) [nonrange_select](#nonrange_select)
### A.8.6 Operators
-unary\_operator ::= `+` \| `-` \| `!` \| `~` \| `&` \| `~&` \| \| \| `~|` \| `^` \| `~^` \| `^~`
-binary\_operator ::=
- `+` \| `-` \| `*` \| `/` \| `%` \| `==` \| `!=` \| `===` \| `!==` \| `==?` \| `!=?` \| `&&` \| `||` \| `**`
- \| `<` \| `<=` \| `>` \| `>=` \| `&` \| \| \| `^` \| `^~` \| `~^` \| `>>` \| `<<` \| `>>>` \| `<<<` `|->` \| `<->`
-inc\_or\_dec\_operator ::= `++` \| `--`
-unary\_module\_path\_operator ::= `!` \| `~` \| `&` \| `~&` \| \| \| `~|` \| `^` \| `~^` \| `^~`
-binary\_module\_path\_operator ::= `==` \| `!=` \| `&&` \| `||` \| `&` \| \| \| `^` \| `^~` \| `~^`
+unary\_operator ::= `+` \| `-` \| `!` \| `~` \| `&` \| `~&` \| \| \| `~|` \| `^` \| `~^` \| `^~`
+binary\_operator ::=
+ `+` \| `-` \| `*` \| `/` \| `%` \| `==` \| `!=` \| `===` \| `!==` \| `==?` \| `!=?` \| `&&` \| `||` \| `**`
+ \| `<` \| `<=` \| `>` \| `>=` \| `&` \| \| \| `^` \| `^~` \| `~^` \| `>>` \| `<<` \| `>>>` \| `<<<` `|->` \| `<->`
+inc\_or\_dec\_operator ::= `++` \| `--`
+unary\_module\_path\_operator ::= `!` \| `~` \| `&` \| `~&` \| \| \| `~|` \| `^` \| `~^` \| `^~`
+binary\_module\_path\_operator ::= `==` \| `!=` \| `&&` \| `||` \| `&` \| \| \| `^` \| `^~` \| `~^`
### A.8.7 Numbers
-number ::=
- [integral_number](#integral_number)
- \| [real_number](#real_number)
-integral\_number ::=
- [decimal_number](#decimal_number)
- \| [octal_number](#octal_number)
- \| [binary_number](#binary_number)
- \| [hex_number](#hex_number)
-decimal\_number ::=
- [unsigned_number](#unsigned_number)
- \| \[ [size](#size) ] [decimal_base](#decimal_base) [unsigned_number](#unsigned_number)
- \| \[ [size](#size) ] [decimal_base](#decimal_base) [x_digit](#x_digit) \{ [_](#_) }
- \| \[ [size](#size) ] [decimal_base](#decimal_base) [z_digit](#z_digit) \{ [_](#_) }
-binary\_number ::= \[ [size](#size) ] [binary_base](#binary_base) [binary_value](#binary_value)
-octal\_number ::= \[ [size](#size) ] [octal_base](#octal_base) [octal_value](#octal_value)
-hex\_number ::= \[ [size](#size) ] [hex_base](#hex_base) [hex_value](#hex_value)
-sign ::= `+` \| `-`
-size ::= [unsigned_number](#unsigned_number)
-real\_number38 ::=
- [fixed_point_number](#fixed_point_number)
- \| [unsigned_number](#unsigned_number) \[ `.` [unsigned_number](#unsigned_number) ] [exp](#exp) \[ [sign](#sign) ] [unsigned_number](#unsigned_number)
-fixed\_point\_number38 ::= [unsigned_number](#unsigned_number) `.` [unsigned_number](#unsigned_number)
-exp ::= [e](#e) \| [E](#E)
-unsigned\_number38 ::= [decimal_digit](#decimal_digit) \{ [_](#_) \| [decimal_digit](#decimal_digit) }
-binary\_value38 ::= [binary_digit](#binary_digit) \{ [_](#_) \| [binary_digit](#binary_digit) }
-octal\_value38 ::= [octal_digit](#octal_digit) \{ [_](#_) \| [octal_digit](#octal_digit) }
-hex\_value38 ::= [hex_digit](#hex_digit) \{ [_](#_) \| [hex_digit](#hex_digit) }
-decimal\_base38 ::= `'[`[s](#s)\|[S](#S)][d](#d) \| `'[`[s](#s)\|[S](#S)][D](#D)
-binary\_base38 ::= `'[`[s](#s)\|[S](#S)][b](#b) \| `'[`[s](#s)\|[S](#S)][B](#B)
-octal\_base38 ::= `'[`[s](#s)\|[S](#S)][o](#o) \| `'[`[s](#s)\|[S](#S)][O](#O)
-hex\_base38 ::= `'[`[s](#s)\|[S](#S)][h](#h) \| `'[`[s](#s)\|[S](#S)][H](#H)
-decimal\_digit ::= [0](#0) \| [1](#1) \| [2](#2) \| [3](#3) \| [4](#4) \| [5](#5) \| [6](#6) \| [7](#7) \| [8](#8) \| [9](#9)
-binary\_digit ::= [x_digit](#x_digit) \| [z_digit](#z_digit) \| [0](#0) \| [1](#1)
-octal\_digit ::= [x_digit](#x_digit) \| [z_digit](#z_digit) \| [0](#0) \| [1](#1) \| [2](#2) \| [3](#3) \| [4](#4) \| [5](#5) \| [6](#6) \| [7](#7)
-hex\_digit ::= [x_digit](#x_digit) \| [z_digit](#z_digit) \| [0](#0) \| [1](#1) \| [2](#2) \| [3](#3) \| [4](#4) \| [5](#5) \| [6](#6) \| [7](#7) \| [8](#8) \| [9](#9) \| [a](#a) \| [b](#b) \| [c](#c) \| [d](#d) \| [e](#e) \| [f](#f) \| [A](#A) \| [B](#B) \| [C](#C) \| [D](#D) \| [E](#E) \| [F](#F)
-x\_digit ::= [x](#x) \| [X](#X)
-z\_digit ::= [z](#z) \| [Z](#Z) \| `?`
-unbased\_unsized\_literal ::= `'`[0](#0) \| `'`[1](#1) \| `'`[z_or_x](#z_or_x) [53](#53)
+number ::=
+ [integral_number](#integral_number)
+ \| [real_number](#real_number)
+integral\_number ::=
+ [decimal_number](#decimal_number)
+ \| [octal_number](#octal_number)
+ \| [binary_number](#binary_number)
+ \| [hex_number](#hex_number)
+decimal\_number ::=
+ [unsigned_number](#unsigned_number)
+ \| \[ [size](#size) ] [decimal_base](#decimal_base) [unsigned_number](#unsigned_number)
+ \| \[ [size](#size) ] [decimal_base](#decimal_base) [x_digit](#x_digit) \{ [_](#_) }
+ \| \[ [size](#size) ] [decimal_base](#decimal_base) [z_digit](#z_digit) \{ [_](#_) }
+binary\_number ::= \[ [size](#size) ] [binary_base](#binary_base) [binary_value](#binary_value)
+octal\_number ::= \[ [size](#size) ] [octal_base](#octal_base) [octal_value](#octal_value)
+hex\_number ::= \[ [size](#size) ] [hex_base](#hex_base) [hex_value](#hex_value)
+sign ::= `+` \| `-`
+size ::= [unsigned_number](#unsigned_number)
+real\_number38 ::=
+ [fixed_point_number](#fixed_point_number)
+ \| [unsigned_number](#unsigned_number) \[ `.` [unsigned_number](#unsigned_number) ] [exp](#exp) \[ [sign](#sign) ] [unsigned_number](#unsigned_number)
+fixed\_point\_number38 ::= [unsigned_number](#unsigned_number) `.` [unsigned_number](#unsigned_number)
+exp ::= [e](#e) \| [E](#E)
+unsigned\_number38 ::= [decimal_digit](#decimal_digit) \{ [_](#_) \| [decimal_digit](#decimal_digit) }
+binary\_value38 ::= [binary_digit](#binary_digit) \{ [_](#_) \| [binary_digit](#binary_digit) }
+octal\_value38 ::= [octal_digit](#octal_digit) \{ [_](#_) \| [octal_digit](#octal_digit) }
+hex\_value38 ::= [hex_digit](#hex_digit) \{ [_](#_) \| [hex_digit](#hex_digit) }
+decimal\_base38 ::= `'[`[s](#s)\|[S](#S)][d](#d) \| `'[`[s](#s)\|[S](#S)][D](#D)
+binary\_base38 ::= `'[`[s](#s)\|[S](#S)][b](#b) \| `'[`[s](#s)\|[S](#S)][B](#B)
+octal\_base38 ::= `'[`[s](#s)\|[S](#S)][o](#o) \| `'[`[s](#s)\|[S](#S)][O](#O)
+hex\_base38 ::= `'[`[s](#s)\|[S](#S)][h](#h) \| `'[`[s](#s)\|[S](#S)][H](#H)
+decimal\_digit ::= [0](#0) \| [1](#1) \| [2](#2) \| [3](#3) \| [4](#4) \| [5](#5) \| [6](#6) \| [7](#7) \| [8](#8) \| [9](#9)
+binary\_digit ::= [x_digit](#x_digit) \| [z_digit](#z_digit) \| [0](#0) \| [1](#1)
+octal\_digit ::= [x_digit](#x_digit) \| [z_digit](#z_digit) \| [0](#0) \| [1](#1) \| [2](#2) \| [3](#3) \| [4](#4) \| [5](#5) \| [6](#6) \| [7](#7)
+hex\_digit ::= [x_digit](#x_digit) \| [z_digit](#z_digit) \| [0](#0) \| [1](#1) \| [2](#2) \| [3](#3) \| [4](#4) \| [5](#5) \| [6](#6) \| [7](#7) \| [8](#8) \| [9](#9) \| [a](#a) \| [b](#b) \| [c](#c) \| [d](#d) \| [e](#e) \| [f](#f) \| [A](#A) \| [B](#B) \| [C](#C) \| [D](#D) \| [E](#E) \| [F](#F)
+x\_digit ::= [x](#x) \| [X](#X)
+z\_digit ::= [z](#z) \| [Z](#Z) \| `?`
+unbased\_unsized\_literal ::= `'`[0](#0) \| `'`[1](#1) \| `'`[z_or_x](#z_or_x) [53](#53)
### A.8.8 Strings
-string\_literal ::=
- [quoted_string](#quoted_string)
- \| [triple_quoted_string](#triple_quoted_string)
-quoted\_string ::= `"` \{ [quoted_string_item](#quoted_string_item) \| [string_escape_seq](#string_escape_seq) } `"`
-triple\_quoted\_string ::= `"""` \{ [triple_quoted_string_item](#triple_quoted_string_item) \| [string_escape_seq](#string_escape_seq) } `"""`
-quoted\_string\_item ::= [any_ASCII_character](#any_ASCII_character) [except](#except) `\` [or](#or) [newline](#newline) [or](#or) `"`
-triple\_quoted\_string\_item ::= [any_ASCII_character](#any_ASCII_character) [except](#except) `\`
-string\_escape\_seq ::=
- `\`[any_ASCII_character](#any_ASCII_character)
- \| `\`[one_to_three_digit_octal_number](#one_to_three_digit_octal_number)
- \| `\`[x](#x) [one_to_two_digit_hex_number](#one_to_two_digit_hex_number)
+string\_literal ::=
+ [quoted_string](#quoted_string)
+ \| [triple_quoted_string](#triple_quoted_string)
+quoted\_string ::= `"` \{ [quoted_string_item](#quoted_string_item) \| [string_escape_seq](#string_escape_seq) } `"`
+triple\_quoted\_string ::= `"""` \{ [triple_quoted_string_item](#triple_quoted_string_item) \| [string_escape_seq](#string_escape_seq) } `"""`
+quoted\_string\_item ::= [any_ASCII_character](#any_ASCII_character) [except](#except) `\` [or](#or) [newline](#newline) [or](#or) `"`
+triple\_quoted\_string\_item ::= [any_ASCII_character](#any_ASCII_character) [except](#except) `\`
+string\_escape\_seq ::=
+ `\`[any_ASCII_character](#any_ASCII_character)
+ \| `\`[one_to_three_digit_octal_number](#one_to_three_digit_octal_number)
+ \| `\`[x](#x) [one_to_two_digit_hex_number](#one_to_two_digit_hex_number)
## A.9 General
### A.9.1 Attributes
-attribute\_instance ::= `(*` [attr_spec](#attr_spec) \{ `,` [attr_spec](#attr_spec) } `*)`
-attr\_spec ::= [attr_name](#attr_name) \[ `=` [constant_expression](#constant_expression) ]
-attr\_name ::= [identifier](#identifier)
+attribute\_instance ::= `(*` [attr_spec](#attr_spec) \{ `,` [attr_spec](#attr_spec) } `*)`
+attr\_spec ::= [attr_name](#attr_name) \[ `=` [constant_expression](#constant_expression) ]
+attr\_name ::= [identifier](#identifier)
### A.9.2 Comments
-comment ::=
- [one_line_comment](#one_line_comment)
- \| [block_comment](#block_comment)
-one\_line\_comment ::= `//` [comment_text](#comment_text) `\`[n](#n)
-block\_comment ::= `/*` [comment_text](#comment_text) `*/`
-comment\_text ::= \{ [Any_ASCII_character](#Any_ASCII_character) }
+comment ::=
+ [one_line_comment](#one_line_comment)
+ \| [block_comment](#block_comment)
+one\_line\_comment ::= `//` [comment_text](#comment_text) `\`[n](#n)
+block\_comment ::= `/*` [comment_text](#comment_text) `*/`
+comment\_text ::= \{ [Any_ASCII_character](#Any_ASCII_character) }
### A.9.3 Identifiers
-array\_identifier ::= [identifier](#identifier)
-block\_identifier ::= [identifier](#identifier)
-bin\_identifier ::= [identifier](#identifier)
-c\_identifier54 ::= \[ [a](#a)`-`[zA](#zA)`-`[Z_](#Z_) ] \{ \[ [a](#a)`-`[zA](#zA)`-`[Z0](#Z0)`-`[9_](#9_) ] }
-cell\_identifier ::= [identifier](#identifier)
-checker\_identifier ::= [identifier](#identifier)
-class\_identifier ::= [identifier](#identifier)
-class\_variable\_identifier ::= [variable_identifier](#variable_identifier)
-clocking\_identifier ::= [identifier](#identifier)
-config\_identifier ::= [identifier](#identifier)
-const\_identifier ::= [identifier](#identifier)
-constraint\_identifier ::= [identifier](#identifier)
-covergroup\_identifier ::= [identifier](#identifier)
-covergroup\_variable\_identifier ::= [variable_identifier](#variable_identifier)
-cover\_point\_identifier ::= [identifier](#identifier)
-cross\_identifier ::= [identifier](#identifier)
-dynamic\_array\_variable\_identifier ::= [variable_identifier](#variable_identifier)
-enum\_identifier ::= [identifier](#identifier)
-escaped\_identifier ::= `\` \{ [any_printable_ASCII_character_except_white_space](#any_printable_ASCII_character_except_white_space) } [white_space](#white_space)
-formal\_identifier ::= [identifier](#identifier)
-formal\_port\_identifier ::= [identifier](#identifier)
-function\_identifier ::= [identifier](#identifier)
-generate\_block\_identifier ::= [identifier](#identifier)
-genvar\_identifier ::= [identifier](#identifier)
-hierarchical\_array\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
-hierarchical\_block\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
-hierarchical\_event\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
-hierarchical\_identifier ::= \[ `$`[root](#root) `.` ] \{ [identifier](#identifier) [constant_bit_select](#constant_bit_select) `.` } [identifier](#identifier)
-hierarchical\_net\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
-hierarchical\_parameter\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
-hierarchical\_property\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
-hierarchical\_sequence\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
-hierarchical\_task\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
-hierarchical\_tf\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
-hierarchical\_variable\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
-identifier ::= [simple_identifier](#simple_identifier) \| [escaped_identifier](#escaped_identifier)
-index\_variable\_identifier ::= [identifier](#identifier)
-interface\_identifier ::= [identifier](#identifier)
-interface\_port\_identifier ::= [identifier](#identifier)
-inout\_port\_identifier ::= [identifier](#identifier)
-input\_port\_identifier ::= [identifier](#identifier)
-instance\_identifier ::= [identifier](#identifier)
-library\_identifier ::= [identifier](#identifier)
-member\_identifier ::= [identifier](#identifier)
-method\_identifier ::= [identifier](#identifier)
-modport\_identifier ::= [identifier](#identifier)
-module\_identifier ::= [identifier](#identifier)
-net\_identifier ::= [identifier](#identifier)
-nettype\_identifier ::= [identifier](#identifier)
-output\_port\_identifier ::= [identifier](#identifier)
-package\_identifier ::= [identifier](#identifier)
-package\_scope ::=
- [package_identifier](#package_identifier) `::`
- \| `$`[unit](#unit) `::`
-parameter\_identifier ::= [identifier](#identifier)
-port\_identifier ::= [identifier](#identifier)
-program\_identifier ::= [identifier](#identifier)
-property\_identifier ::= [identifier](#identifier)
-ps\_class\_identifier ::= \[ [package_scope](#package_scope) ] [class_identifier](#class_identifier)
-ps\_covergroup\_identifier ::= \[ [package_scope](#package_scope) ] [covergroup_identifier](#covergroup_identifier)
-ps\_checker\_identifier ::= \[ [package_scope](#package_scope) ] [checker_identifier](#checker_identifier)
-ps\_identifier ::= \[ [package_scope](#package_scope) ] [identifier](#identifier)
-ps\_or\_hierarchical\_array\_identifier ::=
- \[ [implicit_class_handle](#implicit_class_handle) `.` \| [class_scope](#class_scope) \| [package_scope](#package_scope) ] [hierarchical_array_identifier](#hierarchical_array_identifier)
-ps\_or\_hierarchical\_net\_identifier ::=
- \[ [package_scope](#package_scope) ] [net_identifier](#net_identifier)
- \| [hierarchical_net_identifier](#hierarchical_net_identifier)
-ps\_or\_hierarchical\_property\_identifier ::=
- \[ [package_scope](#package_scope) ] [property_identifier](#property_identifier)
- \| [hierarchical_property_identifier](#hierarchical_property_identifier)
-ps\_or\_hierarchical\_sequence\_identifier ::=
- \[ [package_scope](#package_scope) ] [sequence_identifier](#sequence_identifier)
- \| [hierarchical_sequence_identifier](#hierarchical_sequence_identifier)
-ps\_or\_hierarchical\_tf\_identifier ::=
- \[ [package_scope](#package_scope) ] [tf_identifier](#tf_identifier)
- \| [hierarchical_tf_identifier](#hierarchical_tf_identifier)
-ps\_parameter\_identifier ::=
- \[ [package_scope](#package_scope) \| [class_scope](#class_scope) ] [parameter_identifier](#parameter_identifier)
- \| \{ [generate_block_identifier](#generate_block_identifier) \[ \[ [constant_expression](#constant_expression) ] ] `.` } [parameter_identifier](#parameter_identifier)
-ps\_type\_identifier ::= \[ [local](#local) `::`[48](#48) \| [package_scope](#package_scope) \| [class_scope](#class_scope) ] [type_identifier](#type_identifier)
-rs\_production\_identifier ::= [identifier](#identifier)
-sequence\_identifier ::= [identifier](#identifier)
-signal\_identifier ::= [identifier](#identifier)
-simple\_identifier54 ::= \[ [a](#a)`-`[zA](#zA)`-`[Z_](#Z_) ] \{ \[ [a](#a)`-`[zA](#zA)`-`[Z0](#Z0)`-`[9_](#9_)`$` ] }
-specparam\_identifier ::= [identifier](#identifier)
-system\_tf\_identifier55 ::= `$[` [a](#a)`-`[zA](#zA)`-`[Z0](#Z0)`-`[9_](#9_)`$` `]{` \[ [a](#a)`-`[zA](#zA)`-`[Z0](#Z0)`-`[9_](#9_)`$` ] }
-task\_identifier ::= [identifier](#identifier)
-tf\_identifier ::= [identifier](#identifier)
-terminal\_identifier ::= [identifier](#identifier)
-topmodule\_identifier ::= [identifier](#identifier)
-type\_identifier ::= [identifier](#identifier)
-udp\_identifier ::= [identifier](#identifier)
-variable\_identifier ::= [identifier](#identifier)
+array\_identifier ::= [identifier](#identifier)
+block\_identifier ::= [identifier](#identifier)
+bin\_identifier ::= [identifier](#identifier)
+c\_identifier54 ::= \[ [a](#a)`-`[zA](#zA)`-`[Z_](#Z_) ] \{ \[ [a](#a)`-`[zA](#zA)`-`[Z0](#Z0)`-`[9_](#9_) ] }
+cell\_identifier ::= [identifier](#identifier)
+checker\_identifier ::= [identifier](#identifier)
+class\_identifier ::= [identifier](#identifier)
+class\_variable\_identifier ::= [variable_identifier](#variable_identifier)
+clocking\_identifier ::= [identifier](#identifier)
+config\_identifier ::= [identifier](#identifier)
+const\_identifier ::= [identifier](#identifier)
+constraint\_identifier ::= [identifier](#identifier)
+covergroup\_identifier ::= [identifier](#identifier)
+covergroup\_variable\_identifier ::= [variable_identifier](#variable_identifier)
+cover\_point\_identifier ::= [identifier](#identifier)
+cross\_identifier ::= [identifier](#identifier)
+dynamic\_array\_variable\_identifier ::= [variable_identifier](#variable_identifier)
+enum\_identifier ::= [identifier](#identifier)
+escaped\_identifier ::= `\` \{ [any_printable_ASCII_character_except_white_space](#any_printable_ASCII_character_except_white_space) } [white_space](#white_space)
+formal\_identifier ::= [identifier](#identifier)
+formal\_port\_identifier ::= [identifier](#identifier)
+function\_identifier ::= [identifier](#identifier)
+generate\_block\_identifier ::= [identifier](#identifier)
+genvar\_identifier ::= [identifier](#identifier)
+hierarchical\_array\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
+hierarchical\_block\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
+hierarchical\_event\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
+hierarchical\_identifier ::= \[ `$`[root](#root) `.` ] \{ [identifier](#identifier) [constant_bit_select](#constant_bit_select) `.` } [identifier](#identifier)
+hierarchical\_net\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
+hierarchical\_parameter\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
+hierarchical\_property\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
+hierarchical\_sequence\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
+hierarchical\_task\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
+hierarchical\_tf\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
+hierarchical\_variable\_identifier ::= [hierarchical_identifier](#hierarchical_identifier)
+identifier ::= [simple_identifier](#simple_identifier) \| [escaped_identifier](#escaped_identifier)
+index\_variable\_identifier ::= [identifier](#identifier)
+interface\_identifier ::= [identifier](#identifier)
+interface\_port\_identifier ::= [identifier](#identifier)
+inout\_port\_identifier ::= [identifier](#identifier)
+input\_port\_identifier ::= [identifier](#identifier)
+instance\_identifier ::= [identifier](#identifier)
+library\_identifier ::= [identifier](#identifier)
+member\_identifier ::= [identifier](#identifier)
+method\_identifier ::= [identifier](#identifier)
+modport\_identifier ::= [identifier](#identifier)
+module\_identifier ::= [identifier](#identifier)
+net\_identifier ::= [identifier](#identifier)
+nettype\_identifier ::= [identifier](#identifier)
+output\_port\_identifier ::= [identifier](#identifier)
+package\_identifier ::= [identifier](#identifier)
+package\_scope ::=
+ [package_identifier](#package_identifier) `::`
+ \| `$`[unit](#unit) `::`
+parameter\_identifier ::= [identifier](#identifier)
+port\_identifier ::= [identifier](#identifier)
+program\_identifier ::= [identifier](#identifier)
+property\_identifier ::= [identifier](#identifier)
+ps\_class\_identifier ::= \[ [package_scope](#package_scope) ] [class_identifier](#class_identifier)
+ps\_covergroup\_identifier ::= \[ [package_scope](#package_scope) ] [covergroup_identifier](#covergroup_identifier)
+ps\_checker\_identifier ::= \[ [package_scope](#package_scope) ] [checker_identifier](#checker_identifier)
+ps\_identifier ::= \[ [package_scope](#package_scope) ] [identifier](#identifier)
+ps\_or\_hierarchical\_array\_identifier ::=
+ \[ [implicit_class_handle](#implicit_class_handle) `.` \| [class_scope](#class_scope) \| [package_scope](#package_scope) ] [hierarchical_array_identifier](#hierarchical_array_identifier)
+ps\_or\_hierarchical\_net\_identifier ::=
+ \[ [package_scope](#package_scope) ] [net_identifier](#net_identifier)
+ \| [hierarchical_net_identifier](#hierarchical_net_identifier)
+ps\_or\_hierarchical\_property\_identifier ::=
+ \[ [package_scope](#package_scope) ] [property_identifier](#property_identifier)
+ \| [hierarchical_property_identifier](#hierarchical_property_identifier)
+ps\_or\_hierarchical\_sequence\_identifier ::=
+ \[ [package_scope](#package_scope) ] [sequence_identifier](#sequence_identifier)
+ \| [hierarchical_sequence_identifier](#hierarchical_sequence_identifier)
+ps\_or\_hierarchical\_tf\_identifier ::=
+ \[ [package_scope](#package_scope) ] [tf_identifier](#tf_identifier)
+ \| [hierarchical_tf_identifier](#hierarchical_tf_identifier)
+ps\_parameter\_identifier ::=
+ \[ [package_scope](#package_scope) \| [class_scope](#class_scope) ] [parameter_identifier](#parameter_identifier)
+ \| \{ [generate_block_identifier](#generate_block_identifier) \[ \[ [constant_expression](#constant_expression) ] ] `.` } [parameter_identifier](#parameter_identifier)
+ps\_type\_identifier ::= \[ [local](#local) `::`[48](#48) \| [package_scope](#package_scope) \| [class_scope](#class_scope) ] [type_identifier](#type_identifier)
+rs\_production\_identifier ::= [identifier](#identifier)
+sequence\_identifier ::= [identifier](#identifier)
+signal\_identifier ::= [identifier](#identifier)
+simple\_identifier54 ::= \[ [a](#a)`-`[zA](#zA)`-`[Z_](#Z_) ] \{ \[ [a](#a)`-`[zA](#zA)`-`[Z0](#Z0)`-`[9_](#9_)`$` ] }
+specparam\_identifier ::= [identifier](#identifier)
+system\_tf\_identifier55 ::= `$[` [a](#a)`-`[zA](#zA)`-`[Z0](#Z0)`-`[9_](#9_)`$` `]{` \[ [a](#a)`-`[zA](#zA)`-`[Z0](#Z0)`-`[9_](#9_)`$` ] }
+task\_identifier ::= [identifier](#identifier)
+tf\_identifier ::= [identifier](#identifier)
+terminal\_identifier ::= [identifier](#identifier)
+topmodule\_identifier ::= [identifier](#identifier)
+type\_identifier ::= [identifier](#identifier)
+udp\_identifier ::= [identifier](#identifier)
+variable\_identifier ::= [identifier](#identifier)
### A.9.4 White space
-white\_space ::= [space](#space) \| [tab](#tab) \| [newline](#newline) \| [formfeed](#formfeed) \| [eof56](#eof56)
+white\_space ::= [space](#space) \| [tab](#tab) \| [newline](#newline) \| [formfeed](#formfeed) \| [eof56](#eof56)
diff --git a/docs/grammar_sdf.md b/docs/grammar_sdf.md
new file mode 100644
index 000000000..b6fa82b0e
--- /dev/null
+++ b/docs/grammar_sdf.md
@@ -0,0 +1,144 @@
+# Standard Delay Format (SDF)
+## A.1 Formal syntax definition
+ [The](#The) [formal](#formal) [syntax](#syntax) [of](#of) [SDF](#SDF) [is](#is) [described](#described) [using](#using) [Backus](#Backus)`-`[Naur](#Naur) `(`[BNF](#BNF)`).`
+ [Lexical](#Lexical) [elements](#elements) [are](#are) [shown](#shown) [italicized](#italicized)`.` [All](#All) [leaf](#leaf) [characters](#characters) [are](#are) [shown](#shown) [in](#in) [bold](#bold)`.` [Keywords](#Keywords) [are](#are) [shown](#shown) [in](#in) [uppercase](#uppercase) [bold](#bold) `(`[for](#for) [example](#example)`,` [IOPATH](#IOPATH)`)` [for](#for) [easy](#easy) [identification](#identification)`,` [but](#but) [are](#are) [case](#case) [insensitive](#insensitive)`.`
+### A.1.1 SDF delay file and header
+delay\_file ::= `(` [DELAYFILE](#DELAYFILE) [sdf_header](#sdf_header) [cell](#cell) \{ [cell](#cell) } `)`
+sdf\_header ::=
+ [sdf_version](#sdf_version) \[ [design_name](#design_name) ] \[ [date](#date) ] \[ [vendor](#vendor) ] \[ [program_name](#program_name) ] \[ [program_version](#program_version) ] \[[hierarchy_divider](#hierarchy_divider) ] \[ [voltage](#voltage) ] \[ [process](#process) ] \[[temperature](#temperature) ] \[ [time_scale](#time_scale) ]
+sdf\_version ::= `(` [SDFVERSION](#SDFVERSION) [qstring](#qstring) `)`
+design\_name ::= `(` [DESIGN](#DESIGN) [qstring](#qstring) `)`
+date ::= `(` [DATE](#DATE) [qstring](#qstring) `)`
+vendor ::= `(` [VENDOR](#VENDOR) [qstring](#qstring) `)`
+program\_name ::= `(` [PROGRAM](#PROGRAM) [qstring](#qstring) `)`
+program\_version ::= `(` [VERSION](#VERSION) [qstring](#qstring) `)`
+hierarchy\_divider ::= `(` [DIVIDER](#DIVIDER) [hchar](#hchar) `)`
+voltage ::= `(` [VOLTAGE](#VOLTAGE) [rtriple](#rtriple) `)` \| `(` [VOLTAGE](#VOLTAGE) [signed_real_number](#signed_real_number) `)`
+process ::= `(` [PROCESS](#PROCESS) [qstring](#qstring) `)`
+temperature ::= `(` [TEMPERATURE](#TEMPERATURE) [rtriple](#rtriple) `)` \| `(` [TEMPERATURE](#TEMPERATURE) [signed_real_number](#signed_real_number) `)`
+time\_scale ::= `(` [TIMESCALE](#TIMESCALE) [timescale_number](#timescale_number) [timescale_unit](#timescale_unit) `)`
+timescale\_number ::= [1](#1) \| [10](#10) \| [100](#100) \| [1](#1)`.`[0](#0) \| [10](#10)`.`[0](#0) \| [100](#100)`.`[0](#0)
+timescale\_unit ::= [s](#s) \| [ms](#ms) \| [us](#us) \| [ns](#ns) \| [ps](#ps) \| [fs](#fs)
+### A.1.2 Cells
+cell ::= `(` [CELL](#CELL) [celltype](#celltype) [cell_instance](#cell_instance) \{ [timing_spec](#timing_spec) } `)`
+celltype ::= `(` [CELLTYPE](#CELLTYPE) [qstring](#qstring) `)`
+cell\_instance ::= `(` [INSTANCE](#INSTANCE) \[ [hierarchical_identifier](#hierarchical_identifier) ] `)` \| `(` [INSTANCE](#INSTANCE) `*` `)`
+### A.1.3 Timing specifications
+timing\_spec ::= [del_spec](#del_spec) \| [tc_spec](#tc_spec) \| [lbl_spec](#lbl_spec) \| [te_spec](#te_spec)
+del\_spec ::= `(` [DELAY](#DELAY) [deltype](#deltype) \{ [deltype](#deltype) } `)`
+tc\_spec ::= `(` [TIMINGCHECK](#TIMINGCHECK) [tchk_def](#tchk_def) \{ [tchk_def](#tchk_def) } `)`
+te\_spec ::= `(` [TIMINGENV](#TIMINGENV) [te_def](#te_def) \{ [te_def](#te_def) } `)`
+lbl\_spec ::= `(` [LABEL](#LABEL) [lbl_type](#lbl_type) \{ [lbl_type](#lbl_type) } `)`
+deltype ::= \| [absolute_deltype](#absolute_deltype) \| [increment_deltype](#increment_deltype) \| [pathpulse_deltype](#pathpulse_deltype) \| [pathpulsepercent_deltype](#pathpulsepercent_deltype)
+pathpulse\_deltype ::= `(` [PATHPULSE](#PATHPULSE) \[ [input_output_path](#input_output_path) ] [value](#value) \[ [value](#value) ] `)`
+pathpulsepercent\_deltype ::= `(` [PATHPULSEPERCENT](#PATHPULSEPERCENT) \[ [input_output_path](#input_output_path) ] [value](#value) \[ [value](#value) ] `)`
+absolute\_deltype ::= `(` [ABSOLUTE](#ABSOLUTE) [del_def](#del_def) \{ [del_def](#del_def) } `)`
+increment\_deltype ::= `(` [INCREMENT](#INCREMENT) [del_def](#del_def) \{ [del_def](#del_def) } `)`
+input\_output\_path ::= [port_instance](#port_instance) [port_instance](#port_instance)
+del\_def ::= [iopath_def](#iopath_def) \| [cond_def](#cond_def) \| [condelse_def](#condelse_def) \| [port_del](#port_del) \| [interconnect_def](#interconnect_def) \| [netdelay_def](#netdelay_def) \| [device_def](#device_def)
+iopath\_def ::= `(` [IOPATH](#IOPATH) [port_spec](#port_spec) [port_instance](#port_instance) \{ [retain_def](#retain_def) } [delval_list](#delval_list) `)`
+retain\_def ::= `(` [RETAIN](#RETAIN) [retval_list](#retval_list) `)`
+cond\_def ::= `(` [COND](#COND) \[ [qstring](#qstring) ] [conditional_port_expr](#conditional_port_expr) [iopath_def](#iopath_def) `)`
+condelse\_def ::= `(` [CONDELSE](#CONDELSE) [iopath_def](#iopath_def) `)`
+port\_def ::= `(` [PORT](#PORT) [port_instance](#port_instance) [delval_list](#delval_list) `)`
+interconnect\_def ::= `(` [INTERCONNECT](#INTERCONNECT) [port_instance](#port_instance) [port_instance](#port_instance) [delval_list](#delval_list) `)`
+netdelay\_def ::= `(` [NETDELAY](#NETDELAY) [net_spec](#net_spec) [delval_list](#delval_list) `)`
+device\_def ::= `(` [DEVICE](#DEVICE) \[ [port_instance](#port_instance) ] [delval_list](#delval_list) `)`
+tchk\_def ::= [setup_timing_check](#setup_timing_check) \| [hold_timing_check](#hold_timing_check) \| [setuphold_timing_check](#setuphold_timing_check) \| [recovery_timing_check](#recovery_timing_check) \| [removal_timing_check](#removal_timing_check) \| [recrem_timing_check](#recrem_timing_check) \| [skew_timing_check](#skew_timing_check) \| [bidirectskew_timing_check](#bidirectskew_timing_check) \| [width_timing_check](#width_timing_check) \| [period_timing_check](#period_timing_check) \| [nochange_timing_check](#nochange_timing_check)
+setup\_timing\_check ::= `(` [SETUP](#SETUP) [port_tchk](#port_tchk) [port_tchk](#port_tchk) [value](#value) `)`
+hold\_timing\_check ::= `(` [HOLD](#HOLD) [port_tchk](#port_tchk) [port_tchk](#port_tchk) [value](#value) `)`
+setuphold\_timing\_check ::= `(` [SETUPHOLD](#SETUPHOLD) [port_tchk](#port_tchk) [port_tchk](#port_tchk) [rvalue](#rvalue) [rvalue](#rvalue) `)` \| `(` [SETUPHOLD](#SETUPHOLD) [port_spec](#port_spec) [port_spec](#port_spec) [rvalue](#rvalue) [rvalue](#rvalue) \[ [scond](#scond) ] \[ [ccond](#ccond) ] `)`
+recovery\_timing\_check ::= `(` [RECOVERY](#RECOVERY) [port_tchk](#port_tchk) [port_tchk](#port_tchk) [value](#value) `)`
+removal\_timing\_check ::= `(` [REMOVAL](#REMOVAL) [port_tchk](#port_tchk) [port_tchk](#port_tchk) [value](#value) `)`
+recrem\_timing\_check ::= `(` [RECREM](#RECREM) [port_tchk](#port_tchk) [port_tchk](#port_tchk) [rvalue](#rvalue) [rvalue](#rvalue) `)` \| `(` [RECREM](#RECREM) [port_spec](#port_spec) [port_spec](#port_spec) [rvalue](#rvalue) [rvalue](#rvalue) \[ [scond](#scond) ] \[ [ccond](#ccond) ] `)`
+skew\_timing\_check ::= `(` [SKEW](#SKEW) [port_tchk](#port_tchk) [port_tchk](#port_tchk) [rvalue](#rvalue) `)`
+bidirectskew\_timing\_check ::= `(` [BIDIRECTSKEW](#BIDIRECTSKEW) [port_tchk](#port_tchk) [port_tchk](#port_tchk) [value](#value) [value](#value) `)`
+width\_timing\_check ::= `(` [WIDTH](#WIDTH) [port_tchk](#port_tchk) [value](#value) `)`
+period\_timing\_check ::= `(` [PERIOD](#PERIOD) [port_tchk](#port_tchk) [value](#value) `)`
+nochange\_timing\_check ::= `(` [NOCHANGE](#NOCHANGE) [port_tchk](#port_tchk) [port_tchk](#port_tchk) [rvalue](#rvalue) [rvalue](#rvalue) `)`
+port\_tchk ::= [port_spec](#port_spec) \| `(` [COND](#COND) \[ [qstring](#qstring) ] [timing_check_condition](#timing_check_condition) [port_spec](#port_spec) `)`
+scond ::= `(` [SCOND](#SCOND) \[ [qstring](#qstring) ] [timing_check_condition](#timing_check_condition) `)`
+ccond ::= `(` [CCOND](#CCOND) \[ [qstring](#qstring) ] [timing_check_condition](#timing_check_condition) `)`
+te\_def ::= [cns_def](#cns_def) \| [tenv_def](#tenv_def)
+cns\_def ::= [path_constraint](#path_constraint) \| [period_constraint](#period_constraint) \| [sum_constraint](#sum_constraint) \| [diff_constraint](#diff_constraint) \| [skew_constraint](#skew_constraint)
+path\_constraint ::= `(` [PATHCONSTRAINT](#PATHCONSTRAINT) \[ [name](#name) ] [port_instance](#port_instance) [port_instance](#port_instance) \{ [port_instance](#port_instance) } [rvalue](#rvalue) [rvalue](#rvalue) `)`
+period\_constraint ::=`(` [PERIODCONSTRAINT](#PERIODCONSTRAINT) [port_instance](#port_instance) [value](#value) \[ [exception](#exception) ] `)`
+sum\_constraint ::= `(` [SUM](#SUM) [constraint_path](#constraint_path) [constraint_path](#constraint_path) \{ [constraint_path](#constraint_path) } [rvalue](#rvalue) \[ [rvalue](#rvalue) ] `)`
+diff\_constraint ::= `(` [DIFF](#DIFF) [constraint_path](#constraint_path) [constraint_path](#constraint_path) [value](#value) \[ [value](#value) ] `)`
+skew\_constraint ::= `(` [SKEWCONSTRAINT](#SKEWCONSTRAINT) [port_spec](#port_spec) [value](#value) `)`
+exception ::= `(` [EXCEPTION](#EXCEPTION) [cell_instance](#cell_instance) \{ [cell_instance](#cell_instance) } `)`
+name ::= `(` [NAME](#NAME) \[ [qstring](#qstring) ] `)`
+constraint\_path ::= `(` [port_instance](#port_instance) [port_instance](#port_instance) `)`
+tenv\_def ::= [arrival_env](#arrival_env) \| [departure_env](#departure_env) \| [slack_env](#slack_env) \| [waveform_env](#waveform_env)
+arrival\_env ::= `(` [ARRIVAL](#ARRIVAL) \[ [port_edge](#port_edge) ] [port_instance](#port_instance) [rvalue](#rvalue) [rvalue](#rvalue) [rvalue](#rvalue) [rvalue](#rvalue) `)`
+departure\_env ::= `(` [DEPARTURE](#DEPARTURE) \[ [port_edge](#port_edge) ] [port_instance](#port_instance) [rvalue](#rvalue) [rvalue](#rvalue) [rvalue](#rvalue) [rvalue](#rvalue) `)`
+slack\_env ::= `(` [SLACK](#SLACK) [port_instance](#port_instance) [rvalue](#rvalue) [rvalue](#rvalue) [rvalue](#rvalue) [rvalue](#rvalue) \[ [real_number](#real_number) ] `)`
+waveform\_env ::= `(` [WAVEFORM](#WAVEFORM) [port_instance](#port_instance) [real_number](#real_number) [edge_list](#edge_list) `)`
+edge\_list ::= [pos_pair](#pos_pair) \{ [pos_pair](#pos_pair) } \| [neg_pair](#neg_pair) \{ [neg_pair](#neg_pair) }
+pos\_pair ::= `(` [posedge](#posedge) [signed_real_number](#signed_real_number) \[ [signed_real_number](#signed_real_number) ] `)` `(` [negedge](#negedge) [signed_real_number](#signed_real_number) \[ [signed_real_number](#signed_real_number) ] `)`
+neg\_pair ::= `(` [negedge](#negedge) [signed_real_number](#signed_real_number) \[ [signed_real_number](#signed_real_number) ] `)` `(` [posedge](#posedge) [signed_real_number](#signed_real_number) \[ [signed_real_number](#signed_real_number) ] `)`
+lbl\_type ::= `(` [INCREMENT](#INCREMENT) [lbl_def](#lbl_def) \{ [lbl_def](#lbl_def) } `)` \| `(` [ABSOLUTE](#ABSOLUTE) [lbl_def](#lbl_def) \{ [lbl_def](#lbl_def) } `)`
+lbl\_def ::= `(` [identifier](#identifier) [delval_list](#delval_list) `)`
+port\_spec ::= [port_instance](#port_instance) \| [port_edge](#port_edge)
+port\_edge ::= `(` [edge_identifier](#edge_identifier) [port_instance](#port_instance) `)`
+edge\_identifier ::= [posedge](#posedge) \| [negedge](#negedge) \| [01](#01) \| [10](#10) \| [0z](#0z) \| [z1](#z1) \| [1z](#1z) \| [z0](#z0)
+port\_instance ::= [port](#port) \| [hierarchical_identifier](#hierarchical_identifier) [hchar](#hchar) [port](#port)
+port ::= [scalar_port](#scalar_port) \| [bus_port](#bus_port)
+scalar\_port ::= [hierarchical_identifier](#hierarchical_identifier) \| [hierarchical_identifier](#hierarchical_identifier) \[ [integer](#integer) ]
+bus\_port ::= [hierarchical_identifier](#hierarchical_identifier) \[ [integer](#integer) `:` [integer](#integer) ]
+net\_spec ::= [port_instance](#port_instance) \| [net_instance](#net_instance)
+net\_instance ::= [net](#net) \| [hierarchical_identifier](#hierarchical_identifier) [hier_divider_char](#hier_divider_char) [net](#net)
+net ::= [scalar_net](#scalar_net) \| [bus_net](#bus_net)
+scalar\_net ::= [hierarchical_identifier](#hierarchical_identifier) \| [hierarchical_identifier](#hierarchical_identifier) \[ [integer](#integer) ]
+bus\_net ::= [hierarchical_identifier](#hierarchical_identifier) \[ [integer](#integer) `:` [integer](#integer) ]
+### A.1.4 Data values
+value ::= `(` \[ [real_number](#real_number) ] `)` \| `(` \[[triple](#triple)] `)`
+triple ::= [real_number](#real_number) `:` \[ [real_number](#real_number) ] `:` \[ [real_number](#real_number) ] \| \[ [real_number](#real_number) ] `:` [real_number](#real_number) `:` \[ [real_number](#real_number) ] \| \[ [real_number](#real_number) ] `:` \[ [real_number](#real_number) ] `:` [real_number](#real_number)
+rvalue ::= `(` \[ [signed_real_number](#signed_real_number) ] `)` \| `(` \[ [rtriple](#rtriple) ] `)`
+rtriple ::= [signed_real_number](#signed_real_number) `:` \[ [signed_real_number](#signed_real_number) ] `:` \[ [signed_real_number](#signed_real_number) ] \| \[ [signed_real_number](#signed_real_number) ] `:` [signed_real_number](#signed_real_number) `:` \[ [signed_real_number](#signed_real_number) ] \| \[ [signed_real_number](#signed_real_number) ] `:` \[ [signed_real_number](#signed_real_number) ] `:` [signed_real_number](#signed_real_number)
+delval ::= [rvalue](#rvalue) \| `(` [rvalue](#rvalue) [rvalue](#rvalue) `)` \| `(` [rvalue](#rvalue) [rvalue](#rvalue) [rvalue](#rvalue) `)`
+delval\_list ::= [delval](#delval) \| [delval](#delval) [delval](#delval) \| [delval](#delval) [delval](#delval) [delval](#delval) \| [delval](#delval) [delval](#delval) [delval](#delval) [delval](#delval) \[ [delval](#delval) ] \[ [delval](#delval) ] \| [delval](#delval) [delval](#delval) [delval](#delval) [delval](#delval) [delval](#delval) [delval](#delval) [delval](#delval) \[ [delval](#delval) ] \[ [delval](#delval) ] \[ [delval](#delval) ] \[ [delval](#delval) ] \[ [delval](#delval) ]
+retval\_list ::= [delval](#delval) \| [delval](#delval) [delval](#delval) \| [delval](#delval) [delval](#delval) [delval](#delval)
+### A.1.5 Conditions for path delays
+conditional\_port\_expr ::= [simple_expression](#simple_expression) \| `(` [conditional_port_expr](#conditional_port_expr) `)` \| [unary_operator](#unary_operator) `(` [conditional_port_expr](#conditional_port_expr) `)` \| [conditional_port_expr](#conditional_port_expr) [binary_operator](#binary_operator) [conditional_port_expr](#conditional_port_expr)
+simple\_expression ::= `(` [simple_expression](#simple_expression) `)` \| [unary_operator](#unary_operator) `(` [simple_expression](#simple_expression) `)` \| [port](#port) \| [unary_operator](#unary_operator) [port](#port) \| [scalar_constant](#scalar_constant) \| [unary_operator](#unary_operator) [scalar_constant](#scalar_constant) \| [simple_expression](#simple_expression) `?` [simple_expression](#simple_expression) `:` [simple_expression](#simple_expression) \| \{ [simple_expression](#simple_expression) \[ [concat_expression](#concat_expression) ] } \| \{ [simple_expression](#simple_expression) \{ [simple_expression](#simple_expression) \[ [concat_expression](#concat_expression) ] } }
+concat\_expression ::= `,` [simple_expression](#simple_expression)
+### A.1.6 Conditions for timing checks
+timing\_check\_condition ::= [scalar_node](#scalar_node) \| [inversion_operator](#inversion_operator) [scalar_node](#scalar_node) \| [scalar_node](#scalar_node) [equality_operator](#equality_operator) [scalar_constant](#scalar_constant)
+scalar\_node ::= [scalar_port](#scalar_port) \| [scalar_net](#scalar_net)
+scalar\_net ::= [hierarchical_identifier](#hierarchical_identifier)
+### A.1.7 Fundamental lexical elements
+ [White](#White) [space](#space) [is](#is) [normally](#normally) [permitted](#permitted) [between](#between) [lexical](#lexical) [tokens](#tokens)`,` [but](#but) [not](#not) [within](#within) [the](#the) [definitions](#definitions) [in](#in) [A](#A)`.`[1](#1)`.`[7](#7)`.`
+identifier ::= [character](#character) \{ [character](#character) }
+hierarchical\_identifier ::=[identifier](#identifier) \{ [hchar](#hchar) [identifier](#identifier) }
+qstring ::= `"` \{ [any_character](#any_character) } `"`
+integer ::= [decimal_digit](#decimal_digit) \{ [decimal_digit](#decimal_digit) }
+real\_number ::= [integer](#integer) \| [integer](#integer) \[ `.` [integer](#integer) ] \| [integer](#integer) \[ `.` [integer](#integer) ] [e](#e) \[ [sign](#sign) ] [integer](#integer)
+signed\_real\_number ::= \[ [sign](#sign) ] [real_number](#real_number)
+sign ::= `+` \| `-`
+hchar ::= `.` \| `/`
+character ::= [alphanumeric](#alphanumeric) \| [escaped_character](#escaped_character)
+escaped\_character ::= `\` [character](#character) \| `\` [special_character](#special_character) \| `\"`
+any\_character ::= [character](#character) \| [special_character](#special_character) \| `\"`
+decimal\_digit ::= [0](#0) \| [1](#1) \| [2](#2) \| [3](#3) \| [4](#4) \| [5](#5) \| [6](#6) \| [7](#7) \| [8](#8) \| [9](#9)
+alphanumeric ::= [a](#a) \| [b](#b) \| [c](#c) \| [d](#d) \| [e](#e) \| [f](#f) \| [g](#g) \| [h](#h) \| [i](#i) \| [j](#j) \| [k](#k) \| [l](#l) \| [m](#m) \| [n](#n) \| [o](#o) \| [p](#p) \| [q](#q) \| [r](#r) \| [s](#s) \| [t](#t) \| [u](#u) \| [v](#v) \| [w](#w) \| [x](#x) \| [y](#y) \| [z](#z) \| [A](#A) \| [B](#B) \| [C](#C) \| [D](#D) \| [E](#E) \| [F](#F) \| [G](#G) \| [H](#H) \| [I](#I) \| [J](#J) \| [K](#K) \| [L](#L) \| [M](#M) \| [N](#N) \| [O](#O) \| [P](#P) \| [Q](#Q) \| [R](#R) \| [S](#S) \| [T](#T) \| [U](#U) \| [V](#V) \| [W](#W) \| [X](#X) \| [Y](#Y) \| [Z](#Z) \| [_](#_) \| `$` \| [decimal_digit](#decimal_digit)
+special\_character ::= `!` \| `#` \| `%` \| `&` \| `«` \| `(` \| `)` \| `*` \| `+` \| `,` \| `-` \| `.` \| `/` \| `:` \| `;` \| `<` \| `=` \| `>` \| `?` \| `@` \| \[ \| `\` \| ] \| `^` \| `‘` \| \{ \| \| \| } \| `~`
+### A.1.8 Constants for expressions
+scalar\_constant ::= [0](#0) \| [b0](#b0) \| [B0](#B0) \| [1](#1) [b0](#b0) \| [1](#1) [B0](#B0) \| [1](#1) \| [b1](#b1) \| [B1](#B1) \| [1](#1) [b1](#b1) \| [1](#1) [B1](#B1)
+### A.1.9 Operators for expressions
+unary\_operator ::= `+` \| `-` \| `!` \| `~` \| `&` \| `~&` \| \| \| `~|` \| `^` \| `^~` \| `~^`
+inversion\_operator ::= `!` \| `~`
+binary\_operator ::= `+` \| `-` \| `*` \| `/` \| `%` \| `==` \| `!=` \| `===` \| `!==` \| `&&` \| `||` \| `<` \| `<=` \| `>` \| `>=` \| `&` \| \| \| `^` \| `^~` \| `~^` \| `>>` \| `<<`
+equality\_operator ::= `==` \| `!=` \| `===` \| `!==`
+### A.1.10 Precedence rules of SDF operators
+ `!` `~` [highest](#highest) [precedence](#precedence)
+ `*` `/` `%`
+ `+` `-`
+ `<<` `>>`
+ `<` `<=` `>` `>=`
+ `==` `!=` `===` `!==`
+ `&`
+ `^` `^~`
+ \|
+ `&&`
+ `||` [lowest](#lowest) [precedence](#precedence)
diff --git a/include/slang/driver/SourceLoader.h b/include/slang/driver/SourceLoader.h
index f84868bb3..99b4601fc 100644
--- a/include/slang/driver/SourceLoader.h
+++ b/include/slang/driver/SourceLoader.h
@@ -111,6 +111,13 @@ class SLANG_EXPORT SourceLoader {
void addLibraryMaps(std::string_view pattern, const std::filesystem::path& basePath,
const Bag& optionBag);
+ /// @brief Adds SDF files to the loader.
+ ///
+ /// All files that match the given pattern will be loaded and parsed as if
+ /// they were SDF files.
+ void addSDFFiles(std::string_view pattern, const std::filesystem::path& basePath,
+ const Bag& optionBag);
+
/// @brief Adds a group of files as a separately compiled compilation unit.
///
/// Unlike files added via the @a addFiles method, files added here are
@@ -124,6 +131,9 @@ class SLANG_EXPORT SourceLoader {
const std::vector& includePaths,
std::vector defines, const std::string& libraryName);
+ /// Returns a list of all library map syntax trees that have been loaded and parsed.
+ const SyntaxTreeList& getSDFUnits() const { return sdfUnitTrees; }
+
/// Returns a list of all library map syntax trees that have been loaded and parsed.
const SyntaxTreeList& getLibraryMaps() const { return libraryMapTrees; }
@@ -206,6 +216,8 @@ class SLANG_EXPORT SourceLoader {
void addLibraryMapsInternal(std::string_view pattern, const std::filesystem::path& basePath,
const Bag& optionBag, bool expandEnvVars,
flat_hash_set& seenMaps);
+ void addSDFFilesInternal(std::string_view pattern, const std::filesystem::path& basePath,
+ const Bag& optionBag);
void createLibrary(const syntax::LibraryDeclarationSyntax& syntax,
const std::filesystem::path& basePath);
LoadResult loadAndParse(const FileEntry& fileEntry, const Bag& optionBag,
@@ -223,6 +235,7 @@ class SLANG_EXPORT SourceLoader {
flat_hash_set uniqueExtensions;
std::vector errors;
SyntaxTreeList libraryMapTrees;
+ SyntaxTreeList sdfUnitTrees;
static constexpr int MinFilesForThreading = 4;
};
diff --git a/include/slang/parsing/Lexer.h b/include/slang/parsing/Lexer.h
index 439946057..a92a03fe8 100644
--- a/include/slang/parsing/Lexer.h
+++ b/include/slang/parsing/Lexer.h
@@ -30,6 +30,8 @@ struct SLANG_EXPORT LexerOptions {
uint32_t maxErrors = 16;
/// The version of the SystemVerilog language to use.
+ /// If set to LanguageVersion::v1497_2001 preprocessor will support
+ /// SDF keywords and special tokens.
LanguageVersion languageVersion = LanguageVersion::Default;
/// If true, the preprocessor will support legacy protected envelope directives,
@@ -88,6 +90,8 @@ class SLANG_EXPORT Lexer {
const SourceManager& sourceManager, Token sourceToken, size_t offset,
KeywordVersion keywordVersion, SmallVectorBase& results);
+ bool isSDFFile() { return options.languageVersion == LanguageVersion::v1497_2001; }
+
private:
Lexer(BufferID bufferId, std::string_view source, const char* startPtr, BumpAllocator& alloc,
Diagnostics& diagnostics, LexerOptions options);
diff --git a/include/slang/parsing/LexerFacts.h b/include/slang/parsing/LexerFacts.h
index ad1c0d126..6bf96079b 100644
--- a/include/slang/parsing/LexerFacts.h
+++ b/include/slang/parsing/LexerFacts.h
@@ -33,7 +33,9 @@ enum class SLANG_EXPORT KeywordVersion : uint8_t {
v1800_2009 = 5,
v1800_2012 = 6,
v1800_2017 = 7,
- v1800_2023 = 8
+ v1800_2023 = 8,
+ // IEEE Standard for Standard Delay Format (SDF)
+ v1497_2001 = 9
};
class SLANG_EXPORT LexerFacts {
diff --git a/include/slang/parsing/Parser.h b/include/slang/parsing/Parser.h
index 4c0bc6c10..e312b892b 100644
--- a/include/slang/parsing/Parser.h
+++ b/include/slang/parsing/Parser.h
@@ -7,6 +7,8 @@
//------------------------------------------------------------------------------
#pragma once
+#include
+
#include "slang/parsing/NumberParser.h"
#include "slang/parsing/ParserBase.h"
#include "slang/parsing/ParserMetadata.h"
@@ -54,9 +56,15 @@ enum class ExpressionOptions {
BinsSelectContext = 1 << 6,
/// "dist" expressions are allowed in this context.
- AllowDist = 1 << 7
+ AllowDist = 1 << 7,
+
+ /// Allows to parse SDF conditional port expressions
+ SDFCondExpr = 1 << 8,
+
+ // Allows to parse SDF timing check conditional expressions
+ SDFTimingCheckCondExpr = 1 << 9,
};
-SLANG_BITMASK(ExpressionOptions, AllowDist)
+SLANG_BITMASK(ExpressionOptions, SDFTimingCheckCondExpr)
/// Various options for parsing names.
enum class NameOptions {
@@ -137,6 +145,10 @@ struct SLANG_EXPORT ParserOptions {
/// Implements a full syntax parser for SystemVerilog.
class SLANG_EXPORT Parser : ParserBase, syntax::SyntaxFacts {
public:
+ Parser(const Parser&) = delete;
+ Parser(Parser&&) = delete;
+ Parser& operator=(const Parser&) = delete;
+ Parser& operator=(Parser&&) = delete;
explicit Parser(Preprocessor& preprocessor, const Bag& options = {});
/// Parse a whole compilation unit.
@@ -145,6 +157,9 @@ class SLANG_EXPORT Parser : ParserBase, syntax::SyntaxFacts {
/// Parse a library map file.
syntax::LibraryMapSyntax& parseLibraryMap();
+ /// Parse a standard delay format (SDF) file.
+ syntax::SDFUnitSyntax& parseSDFUnit();
+
/// Parse an expression / statement / module / class / name.
/// These are mostly for testing; only use if you know that the
/// source stream is currently looking at one of these.
@@ -179,17 +194,21 @@ class SLANG_EXPORT Parser : ParserBase, syntax::SyntaxFacts {
// clang-format off
syntax::ExpressionSyntax& parseMinTypMaxExpression(bitmask options = {});
syntax::ExpressionSyntax& parsePrimaryExpression(bitmask options);
+ syntax::ExpressionSyntax& parseSDFPrimaryExpression(bitmask options);
+ syntax::ExpressionSyntax& parseSDFScalarConstant();
syntax::ExpressionSyntax& parseIntegerExpression(bool disallowVector);
syntax::ExpressionSyntax& parseInsideExpression(syntax::ExpressionSyntax& expr);
syntax::ExpressionSyntax& parsePostfixExpression(syntax::ExpressionSyntax& expr, bitmask options);
+ syntax::ExpressionSyntax& parseSDFPostfixExpression(syntax::ExpressionSyntax& expr);
syntax::ExpressionSyntax& parseNewExpression(syntax::NameSyntax& expr, bitmask options);
- syntax::ConcatenationExpressionSyntax& parseConcatenation(Token openBrace, syntax::ExpressionSyntax* first);
+ syntax::ConcatenationExpressionSyntax& parseConcatenation(Token openBrace, syntax::ExpressionSyntax* first, bool isSDFCondExpr = false);
syntax::StreamingConcatenationExpressionSyntax& parseStreamConcatenation(Token openBrace);
syntax::StreamExpressionSyntax& parseStreamExpression();
syntax::RangeListSyntax& parseRangeList();
syntax::ExpressionSyntax& parseValueRangeElement(bitmask options = {});
syntax::ElementSelectSyntax& parseElementSelect();
syntax::SelectorSyntax* parseElementSelector();
+ syntax::NameSyntax& parseSDFHierIdentifier();
syntax::NameSyntax& parseName(bitmask options);
syntax::NameSyntax& parseNamePart(bitmask options);
syntax::ParameterValueAssignmentSyntax* parseParameterValueAssignment();
@@ -204,7 +223,7 @@ class SLANG_EXPORT Parser : ParserBase, syntax::SyntaxFacts {
syntax::EventExpressionSyntax& parseEventExpression();
syntax::NamedBlockClauseSyntax* parseNamedBlockClause();
syntax::TimingControlSyntax* parseTimingControl();
- syntax::ConditionalPredicateSyntax& parseConditionalPredicate(syntax::ExpressionSyntax& first, TokenKind endKind, Token& end);
+ syntax::ConditionalPredicateSyntax& parseConditionalPredicate(syntax::ExpressionSyntax& first, TokenKind endKind, Token& end, bool isSDFCondPred = false);
syntax::ConditionalPatternSyntax& parseConditionalPattern();
syntax::ConditionalStatementSyntax& parseConditionalStatement(syntax::NamedLabelSyntax* label, AttrList attributes, Token uniqueOrPriority);
syntax::ElseClauseSyntax* parseElseClause();
@@ -378,6 +397,54 @@ class SLANG_EXPORT Parser : ParserBase, syntax::SyntaxFacts {
syntax::MemberSyntax* parseLibraryMember();
syntax::FilePathSpecSyntax& parseFilePathSpec();
syntax::LibraryDeclarationSyntax& parseLibraryDecl();
+ syntax::SDFTimescaleSyntax *parseSDFTimescale();
+ syntax::SDFCharMemberSyntax *parseSDFCharMember(TokenKind keywordKind, bool weak = true);
+ syntax::SDFValueSyntax *parseSDFValue(const std::set& endKinds, bool withParens = false, bool isSign = true);
+ syntax::SDFDelayValueSyntax* parseSDFDelayValue();
+ std::span parseSDFDelayValueList(bool isRetain = false);
+ syntax::SDFValueMemberSyntax *parseSDFValueMember(TokenKind keywordKind);
+ syntax::SDFHeaderSyntax& parseSDFHeader();
+ syntax::SDFNameSyntax* parseSDFName();
+ syntax::SDFPortSpecSyntax* parseSDFPortSpec();
+ syntax::SDFPortSyntax* parseSDFPort();
+ syntax::SDFPortEdgeSyntax* parseSDFPortEdge();
+ syntax::SDFCellInstanceSyntax* parseSDFCellInstance();
+ syntax::SDFExceptionSyntax* parseSDFException();
+ syntax::SDFPathPulseSyntax *parseSDFPathPulse();
+ syntax::SDFRetainSyntax* parseSDFRetain();
+ syntax::SDFIOPathSyntax *parseSDFIOPath();
+ syntax::SDFCondSyntax *parseSDFCond();
+ syntax::SDFCondElseSyntax *parseSDFCondElse();
+ syntax::SDFPortDelayDefSyntax *parseSDFPortDelayDef();
+ syntax::SDFInterconnectSyntax *parseSDFInterconnect();
+ syntax::SDFNetDelaySyntax *parseSDFNetDelay();
+ syntax::SDFDeviceSyntax *parseSDFDevice();
+ syntax::SDFAbsIncDelayTypeSyntax *parseSDFAbsIncDelayType();
+ std::span parseSDFDelayTypes();
+ syntax::SDFDelaySpecSyntax *parseSDFDelaySpec();
+ syntax::SDFPathConstraintSyntax *parseSDFPathConstraint();
+ syntax::SDFPeriodConstraintSyntax *parseSDFPeriodConstraint();
+ syntax::SDFConstraintPathSyntax* parseSDFConstraintPath();
+ syntax::SDFSumDiffConstraintSyntax* parseSDFSumDiffConstraint(bool isDiff = false);
+ syntax::SDFSkewConstraintSyntax* parseSDFSkewConstraint();
+ syntax::SDFTimingEnvConstructSyntax* parseSDFTimingEnvConstruct(bool isSlack = false);
+ syntax::SDFEdgeSyntax* parseSDFEdge();
+ syntax::SDFEdgePairSyntax* parseSDFEdgePair();
+ syntax::SDFWaveformSyntax* parseSDFWaveform();
+ std::span parseSDFTimingEnvDefs();
+ syntax::SDFTimingEnvSyntax *parseSDFTimingEnv();
+ syntax::SDFPortTimingCheckSyntax* parseSDFPortTimingCheck();
+ syntax::SDFTimingCheckConditionSyntax* parseSDFTimingCheckCondition(TokenKind keywordKind);
+ syntax::SDFTimingCheckDefSyntax* parseSDFTimingCheckDef(bool hasTwoPorts, bool hasTwoValues, bool isSign, bool hasConds = false);
+ std::span parseSDFTimingCheckDefs();
+ syntax::SDFTimingCheckSyntax* parseSDFTimingCheck();
+ syntax::SDFLabelDefSyntax* parseSDFLabelDef();
+ syntax::SDFLabelTypeSyntax* parseSDFLabelType();
+ std::span parseSDFLabelTypes();
+ syntax::SDFLabelSyntax *parseSDFLabel();
+ std::span parseSDFTimingSpecs();
+ std::span parseSDFCells();
+ syntax::SDFDelayFileSyntax *parseSDFDelayFile();
// clang-format on
template
@@ -389,7 +456,8 @@ class SLANG_EXPORT Parser : ParserBase, syntax::SyntaxFacts {
template
std::span parseMemberList(TokenKind endKind, Token& endToken,
- syntax::SyntaxKind parentKind, TParseFunc&& parseFunc);
+ syntax::SyntaxKind parentKind, TParseFunc&& parseFunc,
+ uint32_t memberLimit = 0);
template
bool parseCaseItems(TokenKind caseKind, SmallVectorBase& itemBuffer,
diff --git a/include/slang/syntax/SyntaxFacts.h b/include/slang/syntax/SyntaxFacts.h
index fe92d5da7..574b25247 100644
--- a/include/slang/syntax/SyntaxFacts.h
+++ b/include/slang/syntax/SyntaxFacts.h
@@ -31,6 +31,10 @@ class SLANG_EXPORT SyntaxFacts {
/// unary prefix operator token.
static SyntaxKind getUnaryPrefixExpression(TokenKind kind);
+ /// @return the kind of syntax that should be created for the given
+ /// unary prefix operator token of SDF expressions.
+ static SyntaxKind getSDFUnaryPrefixExpression(TokenKind kind);
+
/// @return the kind of syntax that should be created for the given
/// unary postfix operator token.
static SyntaxKind getUnaryPostfixExpression(TokenKind kind);
@@ -39,6 +43,10 @@ class SLANG_EXPORT SyntaxFacts {
/// literal token.
static SyntaxKind getLiteralExpression(TokenKind kind);
+ /// @return the kind of syntax that should be created for the given
+ /// binary operator token of SDF expressions.
+ static SyntaxKind getSDFBinaryExpression(TokenKind kind);
+
/// @return the kind of syntax that should be created for the given
/// binary operator token.
static SyntaxKind getBinaryExpression(TokenKind kind);
diff --git a/include/slang/syntax/SyntaxTree.h b/include/slang/syntax/SyntaxTree.h
index 04ae3e0da..6e483c184 100644
--- a/include/slang/syntax/SyntaxTree.h
+++ b/include/slang/syntax/SyntaxTree.h
@@ -180,6 +180,38 @@ class SLANG_EXPORT SyntaxTree {
SourceManager& sourceManager,
const Bag& options = {});
+ /// Creates a syntax tree from a standard delay format (SDF) file.
+ /// @a path is the path to the source file on disk.
+ /// @a sourceManager is the manager that owns all of the loaded source code.
+ /// @a options is an optional bag of lexer, preprocessor, and parser options.
+ /// @return the created and parsed syntax tree.
+ static std::shared_ptr fromSDFFile(std::string_view path,
+ SourceManager& sourceManager,
+ const Bag& options = {});
+
+ /// Creates a syntax tree from a standard delay format (SDF) located in memory.
+ /// @a text is the actual source code text.
+ /// @a sourceManager is the manager that owns all of the loaded source code.
+ /// @a name is an optional name to give to the loaded source buffer.
+ /// @a path is an optional path to give to the loaded source buffer.
+ /// @a options is an optional bag of lexer, preprocessor, and parser options.
+ /// @return the created and parsed syntax tree.
+ static std::shared_ptr fromSDFText(std::string_view text,
+ SourceManager& sourceManager,
+ std::string_view name = "source"sv,
+ std::string_view path = "",
+ const Bag& options = {});
+
+ /// Creates a syntax tree from a standard delay format (SDF) already loaded into a source
+ /// buffer.
+ /// @a buffer is the loaded source buffer.
+ /// @a sourceManager is the manager that owns the buffer.
+ /// @a options is an optional bag of lexer, preprocessor, and parser options.
+ /// @return the created and parsed syntax tree.
+ static std::shared_ptr fromSDFBuffer(const SourceBuffer& buffer,
+ SourceManager& sourceManager,
+ const Bag& options = {});
+
/// Gets any diagnostics generated while parsing.
Diagnostics& diagnostics() { return diagnosticsBuffer; }
diff --git a/include/slang/util/LanguageVersion.h b/include/slang/util/LanguageVersion.h
index 923a24f24..01b5c9d3f 100644
--- a/include/slang/util/LanguageVersion.h
+++ b/include/slang/util/LanguageVersion.h
@@ -11,8 +11,8 @@
namespace slang {
-/// Specifies SystemVerilog language versions.
-enum class LanguageVersion { v1800_2017, v1800_2023, Default = v1800_2017 };
+/// Specifies SystemVerilog language versions and Standard Delay Format (SDF) standard.
+enum class LanguageVersion { v1800_2017, v1800_2023, v1497_2001, Default = v1800_2017 };
inline std::string_view toString(LanguageVersion lv) {
switch (lv) {
@@ -20,6 +20,8 @@ inline std::string_view toString(LanguageVersion lv) {
return "1800-2017";
case LanguageVersion::v1800_2023:
return "1800-2023";
+ case LanguageVersion::v1497_2001:
+ return "1497-2001";
default:
return "";
}
diff --git a/scripts/diagnostics.txt b/scripts/diagnostics.txt
index 96ad900e3..ed839f194 100644
--- a/scripts/diagnostics.txt
+++ b/scripts/diagnostics.txt
@@ -117,6 +117,7 @@ error MisplacedTrailingSeparator "misplaced trailing '{}'"
error ImplicitNotAllowed "expected data type (implicit type name not allowed)"
error InvalidAccessDotColon "invalid access token; '{}' should be '{}'"
error ExpectedMember "expected member"
+error MemberLimitViolation "expected only {} member(s)"
error ExpectedStatement "expected statement"
error ExpectedParameterPort "expected parameter declaration"
error ExpectedNonAnsiPort "expected non-ansi port declaration"
@@ -153,6 +154,23 @@ error ExpectedPortList "expected parameter list or port list"
error ExpectedRsRule "expected randsequence production rule"
error ExpectedPattern "expected pattern"
error ExpectedFunctionPortList "expected function port list"
+error ExpectedSDFDivider "expected '/' or '.' divider"
+error ExpectedSDFMember "expected at least one {} member specified"
+error InvalidSDFTimescaleUnit "invalid SDF timescale unit; expected a combination of (1 | 10 | 100 | 1.0 | 10.0 | 100.0) and (s | ms | us | ns | ps | fs)"
+error InvalidSDFValueSep "invalid SDF value separator; expected ':'"
+error InvalidSDFValueExpr "invalid SDF value expression"
+error InvalidSDFCellInstanceIdentifier "invalid SDF cell intstance identifer expected empty identifier or '*' or hierarchical identifier"
+error ExpectedSDFIdentifier "expected SDF identifier name"
+error InvalidSDFPortEdgeIdentifier "invalid SDF port edge identifier; expected one of (posedge | negedge | 01 | 10 | 0z | z1 | 1z | z0)"
+error InvalidSDFDelayValuesList "expected no more than {} delay values"
+error InvalidSDFPathCnsPortNum "expected at least 2 port instance specified at path constraint"
+error InvalidSDFSumDiffCnsPathesNum "expected at least 2 path constraint specifier at SUM/DIFF constraint"
+error InvalidSDFEdgeSpec "expected posedge or negedge edge specifier"
+error InvalidSDFEdgePair "expected {}"
+error InvalidSDFExprScalar "invalid SDF constant scalar expression; expected one of: (0 | b0 | B0 | 1 b0 | 1 B0 | 1 | b1 | B1 | 1 b1 | 1 B1)"
+error InvalidSDFInvOp "invalid inversion operator; expected '~' or '!'"
+error ExpectedRealLiteralExpression "expected usigned integer or real literal"
+error DifferentSDFNameSeperator "only one type ('{}') of separator should be used"
error NoLabelOnSemicolon "labels are not allowed on empty semicolon"
error DeferredDelayMustBeZero "deferred assertion delay must be zero"
error InvalidGenvarIterExpression "invalid genvar iteration expression"
diff --git a/scripts/grammar_gen.py b/scripts/grammar_gen.py
index 7361e0271..f2c15b72f 100644
--- a/scripts/grammar_gen.py
+++ b/scripts/grammar_gen.py
@@ -10,10 +10,17 @@
ourdir = os.path.dirname(os.path.realpath(__file__))
-inf = open(os.path.join(ourdir, "grammar.txt"))
-outf = open(os.path.join(ourdir, "../docs/grammar.md"), "w")
+infs = [
+ open(os.path.join(ourdir, "grammar.txt")),
+ open(os.path.join(ourdir, "grammar_sdf.txt")),
+]
+outfs = [
+ open(os.path.join(ourdir, "../docs/grammar.md"), "w"),
+ open(os.path.join(ourdir, "../docs/grammar_sdf.md"), "w"),
+]
-outf.write("# SystemVerilog\n")
+outfs[0].write("# SystemVerilog\n")
+outfs[1].write("# Standard Delay Format (SDF)\n")
def entry(line):
@@ -49,21 +56,23 @@ def replacer(m):
entry(saved_match)
-for line in inf:
- line = line.strip()
- if not line:
- continue
+for i, inf in enumerate(infs):
+ outf = outfs[i]
+ for line in inf:
+ line = line.strip()
+ if not line:
+ continue
- if line.startswith("A."):
- count = line.split(" ")[0].count(".")
- if count == 1:
- outf.write("## ")
- elif count == 2:
- outf.write("### ")
- elif count == 3:
- outf.write("#### ")
+ if line.startswith("A."):
+ count = line.split(" ")[0].count(".")
+ if count == 1:
+ outf.write("## ")
+ elif count == 2:
+ outf.write("### ")
+ elif count == 3:
+ outf.write("#### ")
+ else:
+ raise Exception("wut")
+ outf.write(line + "\n")
else:
- raise Exception("wut")
- outf.write(line + "\n")
- else:
- entry(line)
+ entry(line)
diff --git a/scripts/grammar_sdf.txt b/scripts/grammar_sdf.txt
new file mode 100644
index 000000000..e5d303acb
--- /dev/null
+++ b/scripts/grammar_sdf.txt
@@ -0,0 +1,268 @@
+A.1 Formal syntax definition
+
+A.1.1 SDF delay file and header
+
+delay_file ::= ( DELAYFILE sdf_header cell { cell } )
+
+sdf_header ::=
+sdf_version [ design_name ] [ date ] [ vendor ] [ program_name ] [ program_version ] [hierarchy_divider ] [ voltage ] [ process ] [temperature ] [ time_scale ]
+
+sdf_version ::= ( SDFVERSION qstring )
+
+design_name ::= ( DESIGN qstring )
+
+date ::= ( DATE qstring )
+
+vendor ::= ( VENDOR qstring )
+
+program_name ::= ( PROGRAM qstring )
+
+program_version ::= ( VERSION qstring )
+
+hierarchy_divider ::= ( DIVIDER hchar )
+
+voltage ::= ( VOLTAGE rtriple ) | ( VOLTAGE signed_real_number )
+
+process ::= ( PROCESS qstring )
+
+temperature ::= ( TEMPERATURE rtriple ) | ( TEMPERATURE signed_real_number )
+
+time_scale ::= ( TIMESCALE timescale_number timescale_unit )
+
+timescale_number ::= 1 | 10 | 100 | 1.0 | 10.0 | 100.0
+
+timescale_unit ::= s | ms | us | ns | ps | fs
+
+A.1.2 Cells
+
+cell ::= ( CELL celltype cell_instance { timing_spec } )
+
+celltype ::= ( CELLTYPE qstring )
+
+cell_instance ::= ( INSTANCE [ hierarchical_identifier ] ) | ( INSTANCE * )
+
+A.1.3 Timing specifications
+
+timing_spec ::= del_spec | tc_spec | lbl_spec | te_spec
+
+del_spec ::= ( DELAY deltype { deltype } )
+
+tc_spec ::= ( TIMINGCHECK tchk_def { tchk_def } )
+
+te_spec ::= ( TIMINGENV te_def { te_def } )
+
+lbl_spec ::= ( LABEL lbl_type { lbl_type } )
+
+deltype ::= | absolute_deltype | increment_deltype | pathpulse_deltype | pathpulsepercent_deltype
+
+pathpulse_deltype ::= ( PATHPULSE [ input_output_path ] value [ value ] )
+
+pathpulsepercent_deltype ::= ( PATHPULSEPERCENT [ input_output_path ] value [ value ] )
+
+absolute_deltype ::= ( ABSOLUTE del_def { del_def } )
+
+increment_deltype ::= ( INCREMENT del_def { del_def } )
+
+input_output_path ::= port_instance port_instance
+
+del_def ::= iopath_def | cond_def | condelse_def | port_del | interconnect_def | netdelay_def | device_def
+
+iopath_def ::= ( IOPATH port_spec port_instance { retain_def } delval_list )
+
+retain_def ::= ( RETAIN retval_list )
+
+cond_def ::= ( COND [ qstring ] conditional_port_expr iopath_def )
+
+condelse_def ::= ( CONDELSE iopath_def )
+
+port_def ::= ( PORT port_instance delval_list )
+
+interconnect_def ::= ( INTERCONNECT port_instance port_instance delval_list )
+
+netdelay_def ::= ( NETDELAY net_spec delval_list )
+
+device_def ::= ( DEVICE [ port_instance ] delval_list )
+
+tchk_def ::= setup_timing_check | hold_timing_check | setuphold_timing_check | recovery_timing_check | removal_timing_check | recrem_timing_check | skew_timing_check | bidirectskew_timing_check | width_timing_check | period_timing_check | nochange_timing_check
+
+setup_timing_check ::= ( SETUP port_tchk port_tchk value )
+
+hold_timing_check ::= ( HOLD port_tchk port_tchk value )
+
+setuphold_timing_check ::= ( SETUPHOLD port_tchk port_tchk rvalue rvalue ) | ( SETUPHOLD port_spec port_spec rvalue rvalue [ scond ] [ ccond ] )
+
+recovery_timing_check ::= ( RECOVERY port_tchk port_tchk value )
+
+removal_timing_check ::= ( REMOVAL port_tchk port_tchk value )
+
+recrem_timing_check ::= ( RECREM port_tchk port_tchk rvalue rvalue ) | ( RECREM port_spec port_spec rvalue rvalue [ scond ] [ ccond ] )
+
+skew_timing_check ::= ( SKEW port_tchk port_tchk rvalue )
+
+bidirectskew_timing_check ::= ( BIDIRECTSKEW port_tchk port_tchk value value )
+
+width_timing_check ::= ( WIDTH port_tchk value )
+
+period_timing_check ::= ( PERIOD port_tchk value )
+
+nochange_timing_check ::= ( NOCHANGE port_tchk port_tchk rvalue rvalue )
+
+port_tchk ::= port_spec | ( COND [ qstring ] timing_check_condition port_spec )
+
+scond ::= ( SCOND [ qstring ] timing_check_condition )
+
+ccond ::= ( CCOND [ qstring ] timing_check_condition )
+
+te_def ::= cns_def | tenv_def
+
+cns_def ::= path_constraint | period_constraint | sum_constraint | diff_constraint | skew_constraint
+
+path_constraint ::= ( PATHCONSTRAINT [ name ] port_instance port_instance { port_instance } rvalue rvalue )
+
+period_constraint ::=( PERIODCONSTRAINT port_instance value [ exception ] )
+
+sum_constraint ::= ( SUM constraint_path constraint_path { constraint_path } rvalue [ rvalue ] )
+
+diff_constraint ::= ( DIFF constraint_path constraint_path value [ value ] )
+
+skew_constraint ::= ( SKEWCONSTRAINT port_spec value )
+
+exception ::= ( EXCEPTION cell_instance { cell_instance } )
+
+name ::= ( NAME [ qstring ] )
+
+constraint_path ::= ( port_instance port_instance )
+
+tenv_def ::= arrival_env | departure_env | slack_env | waveform_env
+
+arrival_env ::= ( ARRIVAL [ port_edge ] port_instance rvalue rvalue rvalue rvalue )
+
+departure_env ::= ( DEPARTURE [ port_edge ] port_instance rvalue rvalue rvalue rvalue )
+
+slack_env ::= ( SLACK port_instance rvalue rvalue rvalue rvalue [ real_number ] )
+
+waveform_env ::= ( WAVEFORM port_instance real_number edge_list )
+
+edge_list ::= pos_pair { pos_pair } | neg_pair { neg_pair }
+
+pos_pair ::= ( posedge signed_real_number [ signed_real_number ] ) ( negedge signed_real_number [ signed_real_number ] )
+
+neg_pair ::= ( negedge signed_real_number [ signed_real_number ] ) ( posedge signed_real_number [ signed_real_number ] )
+
+lbl_type ::= ( INCREMENT lbl_def { lbl_def } ) | ( ABSOLUTE lbl_def { lbl_def } )
+
+lbl_def ::= ( identifier delval_list )
+
+port_spec ::= port_instance | port_edge
+
+port_edge ::= ( edge_identifier port_instance )
+
+edge_identifier ::= posedge | negedge | 01 | 10 | 0z | z1 | 1z | z0
+
+port_instance ::= port | hierarchical_identifier hchar port
+
+port ::= scalar_port | bus_port
+
+scalar_port ::= hierarchical_identifier | hierarchical_identifier [ integer ]
+
+bus_port ::= hierarchical_identifier [ integer : integer ]
+
+net_spec ::= port_instance | net_instance
+
+net_instance ::= net | hierarchical_identifier hier_divider_char net
+
+net ::= scalar_net | bus_net
+
+scalar_net ::= hierarchical_identifier | hierarchical_identifier [ integer ]
+
+bus_net ::= hierarchical_identifier [ integer : integer ]
+
+A.1.4 Data values
+
+value ::= ( [ real_number ] ) | ( [triple] )
+
+triple ::= real_number : [ real_number ] : [ real_number ] | [ real_number ] : real_number : [ real_number ] | [ real_number ] : [ real_number ] : real_number
+
+rvalue ::= ( [ signed_real_number ] ) | ( [ rtriple ] )
+
+rtriple ::= signed_real_number : [ signed_real_number ] : [ signed_real_number ] | [ signed_real_number ] : signed_real_number : [ signed_real_number ] | [ signed_real_number ] : [ signed_real_number ] : signed_real_number
+
+delval ::= rvalue | ( rvalue rvalue ) | ( rvalue rvalue rvalue )
+
+delval_list ::= delval | delval delval | delval delval delval | delval delval delval delval [ delval ] [ delval ] | delval delval delval delval delval delval delval [ delval ] [ delval ] [ delval ] [ delval ] [ delval ]
+
+retval_list ::= delval | delval delval | delval delval delval
+
+A.1.5 Conditions for path delays
+
+conditional_port_expr ::= simple_expression | ( conditional_port_expr ) | unary_operator ( conditional_port_expr ) | conditional_port_expr binary_operator conditional_port_expr
+
+simple_expression ::= ( simple_expression ) | unary_operator ( simple_expression ) | port | unary_operator port | scalar_constant | unary_operator scalar_constant | simple_expression ? simple_expression : simple_expression | { simple_expression [ concat_expression ] } | { simple_expression { simple_expression [ concat_expression ] } }
+
+concat_expression ::= , simple_expression
+
+A.1.6 Conditions for timing checks
+
+timing_check_condition ::= scalar_node | inversion_operator scalar_node | scalar_node equality_operator scalar_constant
+
+scalar_node ::= scalar_port | scalar_net
+
+scalar_net ::= hierarchical_identifier
+
+A.1.7 Fundamental lexical elements
+
+identifier ::= character { character }
+
+hierarchical_identifier ::=identifier { hchar identifier }
+
+qstring ::= " { any_character } "
+
+integer ::= decimal_digit { decimal_digit }
+
+real_number ::= integer | integer [ . integer ] | integer [ . integer ] e [ sign ] integer
+
+signed_real_number ::= [ sign ] real_number
+
+sign ::= + | -
+
+hchar ::= . | /
+
+character ::= alphanumeric | escaped_character
+
+escaped_character ::= \ character | \ special_character | \"
+
+any_character ::= character | special_character | \"
+
+decimal_digit ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
+
+alphanumeric ::= a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | _ | $ | decimal_digit
+
+special_character ::= ! | # | % | & | « | ( | ) | * | + | , | - | . | / | : | ; | < | = | > | ? | @ | [ | \ | ] | ^ | ‘ | { | | | } | ~
+
+A.1.8 Constants for expressions
+
+scalar_constant ::= 0 | b0 | B0 | 1 b0 | 1 B0 | 1 | b1 | B1 | 1 b1 | 1 B1
+
+A.1.9 Operators for expressions
+
+unary_operator ::= + | - | ! | ~ | & | ~& | | | ~| | ^ | ^~ | ~^
+
+inversion_operator ::= ! | ~
+
+binary_operator ::= + | - | * | / | % | == | != | === | !== | && | || | < | <= | > | >= | & | | | ^ | ^~ | ~^ | >> | <<
+
+equality_operator ::= == | != | === | !==
+
+A.1.10 Precedence rules of SDF operators
+
+! ~
+* / %
++ -
+<< >>
+< <= > >=
+== != === !==
+&
+^ ^~
+|
+&&
+||
diff --git a/scripts/syntax.txt b/scripts/syntax.txt
index 62f4e06df..59e0387fe 100644
--- a/scripts/syntax.txt
+++ b/scripts/syntax.txt
@@ -2176,6 +2176,10 @@ LibraryMap
list members
token endOfFile
+SDFUnit
+list members
+token endOfFile
+
// ----- DIRECTIVES -----
Directive final=false
@@ -2384,3 +2388,299 @@ LibraryIncludeStatement base=Member
token include
FilePathSpec filePath
token semi
+
+// ----- SDF types common -----
+
+SDFValue
+Expression? min
+Expression? typ
+Expression? max
+
+SDFDelayValue
+list values
+
+SDFPortTimingCheck final=false
+empty
+
+SDFPortSpec base=SDFPortTimingCheck final=false
+empty
+
+SDFPort base=SDFPortSpec
+Expression portExpr
+
+SDFPortEdge base=SDFPortSpec
+token openParen
+token identifier
+SDFPort port
+token closeParen
+
+SDFValueMember
+token openParen
+token keyword
+SDFValue value
+token closeParen
+
+SDFCharMember
+token openParen
+token keyword
+token value
+token closeParen
+
+SDFName
+token openParen
+token keyword
+LiteralExpression? name
+token closeParen
+
+// ----- SDF expressions -----
+
+// ----- SDF timing specifications -----
+
+SDFRetain
+token openParen
+token keyword
+list values
+token closeParen
+
+SDFDelayDef final=false
+empty
+
+SDFIOPath base=SDFDelayDef
+token openParen
+token keyword
+list ports
+SDFRetain? retain
+list values
+token closeParen
+
+SDFCond base=SDFDelayDef
+token openParen
+token keyword
+LiteralExpression? name
+Expression condition
+SDFIOPath iopath
+token closeParen
+
+SDFCondElse base=SDFDelayDef
+token openParen
+token keyword
+SDFIOPath iopath
+token closeParen
+
+SDFPortDelayDef base=SDFDelayDef
+token openParen
+token keyword
+SDFPort port
+list values
+token closeParen
+
+SDFInterconnect base=SDFDelayDef
+token openParen
+token keyword
+list ports
+list values
+token closeParen
+
+SDFNetDelay base=SDFDelayDef
+token openParen
+token keyword
+SDFPort net
+list values
+token closeParen
+
+SDFDevice base=SDFDelayDef
+token openParen
+token keyword
+SDFPort? port
+list values
+token closeParen
+
+SDFDelayType final=false
+empty
+
+SDFPathPulse base=SDFDelayType
+token openParen
+token keyword
+SDFPort? in
+SDFPort? out
+list values
+token closeParen
+
+SDFAbsIncDelayType base=SDFDelayType
+token openParen
+token keyword
+list defs
+token closeParen
+
+SDFTimingCheckCondition base=SDFPortTimingCheck
+token openParen
+token keyword
+LiteralExpression? name
+Expression condition
+SDFPortSpec? portSpec
+token closeParen
+
+SDFTimingCheckDef final=false
+empty
+
+SDFTimingCheckDef
+token openParen
+token keyword
+list ports
+list values
+list conditions
+token closeParen
+
+SDFTimingEnvDef final=false
+empty
+
+SDFPathConstraint base=SDFTimingEnvDef
+token openParen
+token keyword
+SDFName? name
+list ports
+list values
+token closeParen
+
+SDFConstraintPath
+token openParen
+list ports
+token closeParen
+
+SDFSumDiffConstraint base=SDFTimingEnvDef
+token openParen
+token keyword
+list pathes
+list values
+token closeParen
+
+SDFSkewConstraint base=SDFTimingEnvDef
+token openParen
+token keyword
+SDFPortSpec portSpec
+SDFValue value
+token closeParen
+
+SDFTimingEnvConstruct base=SDFTimingEnvDef
+token openParen
+token keyword
+SDFPortEdge? edge
+SDFPort port
+list values
+Expression? period
+token closeParen
+
+SDFEdge
+token openParen
+token edge
+list offsets
+token closeParen
+
+SDFEdgePair
+list edges
+
+SDFWaveform base=SDFTimingEnvDef
+token openParen
+token keyword
+SDFPort port
+Expression period
+list pairs
+token closeParen
+
+SDFLabelDef
+token openParen
+Name identifier
+list values
+token closeParen
+
+SDFLabelType
+token openParen
+token keyword
+list defs
+token closeParen
+
+SDFTimingSpec final=false
+empty
+
+SDFDelaySpec base=SDFTimingSpec
+token openParen
+token keyword
+list types
+token closeParen
+
+SDFTimingCheck base=SDFTimingSpec
+token opneParne
+token keyword
+list defs
+token closeParen
+
+SDFTimingEnv base=SDFTimingSpec
+token openParen
+token keyword
+list defs
+token closeParen
+
+SDFLabel base=SDFTimingSpec
+token openParen
+token keyword
+list type
+token closeParen
+
+// ----- SDF cells -----
+
+SDFCellInstance
+token openParen
+token keyword
+Name name
+token closeParen
+
+SDFException
+token openParen
+token keyword
+list instances
+token closeParen
+
+SDFPeriodConstraint base=SDFTimingEnvDef
+token openParen
+token keyword
+SDFPort port
+SDFValue value
+SDFException? exception
+token closeParen
+
+SDFCell
+token openParen
+token keyword
+SDFCharMember type
+SDFCellInstance instance
+list specs
+token closeParen
+
+// ----- SDF delay file and header -----
+
+SDFTimescale
+token openParen
+token keyword
+LiteralExpression number
+token unit
+token closeParen
+
+SDFHeader
+SDFCharMember? version
+SDFCharMember? design
+SDFCharMember? date
+SDFCharMember? vendor
+SDFCharMember? programName
+SDFCharMember? programVersion
+SDFCharMember? divider
+SDFValueMember? voltage
+SDFCharMember? process
+SDFValueMember? temperature
+SDFTimescale? timescale
+
+SDFDelayFile base=Member
+token openParen
+token keyword
+SDFHeader header
+list cells
+token closeParen
diff --git a/scripts/tokenkinds.txt b/scripts/tokenkinds.txt
index 0d20e924c..5bd301ccc 100644
--- a/scripts/tokenkinds.txt
+++ b/scripts/tokenkinds.txt
@@ -350,3 +350,60 @@ MacroEscapedQuote
MacroPaste
EmptyMacroArgument
LineContinuation
+SDFDelayFileKeyword
+SDFVersionKeyword
+SDFDesignKeyword
+SDFDateKeyword
+SDFVendorKeyword
+SDFProgramKeyword
+SDFProgramVersionKeyword
+SDFDividerKeyword
+SDFVoltageKeyword
+SDFProcessKeyword
+SDFTemperatureKeyword
+SDFTimescaleKeyword
+SDFCellKeyword
+SDFCellTypeKeyword
+SDFInstanceKeyword
+SDFDelayKeyword
+SDFTimingCheckKeyword
+SDFTimingEnvKeyword
+SDFLabelKeyword
+SDFPathPulseKeyword
+SDFPathPulsePercentKeyword
+SDFAbsoluteKeyword
+SDFIncrementKeyword
+SDFIOPathKeyword
+SDFRetainKeyword
+SDFCondKeyword
+SDFCondElseKeyword
+SDFPortKeyword
+SDFInterconnectKeyword
+SDFNetDelayKeyword
+SDFDeviceKeyword
+SDFSetupKeyword
+SDFHoldKeyword
+SDFSetupHoldKeyword
+SDFRecoveryKeyword
+SDFRemovalKeyword
+SDFRecremKeyword
+SDFSkewKeyword
+SDFBidirectSkewKeyword
+SDFWidthKeyword
+SDFPeriodKeyword
+SDFNochangeKeyword
+SDFSCondKeyword
+SDFCCondKeyword
+SDFPathConstraintKeyword
+SDFPeriodConstraintKeyword
+SDFSumKeyword
+SDFDiffKeyword
+SDFSkewConstraintKeyword
+SDFExceptionKeyword
+SDFNameKeyword
+SDFArrivalKeyword
+SDFDepartureKeyword
+SDFSlackKeyword
+SDFWaveformKeyword
+SDFEdgeIdent0Z
+SDFEdgeIdent1Z
diff --git a/source/ast/Scope.cpp b/source/ast/Scope.cpp
index 782a942b6..73607a795 100644
--- a/source/ast/Scope.cpp
+++ b/source/ast/Scope.cpp
@@ -544,8 +544,9 @@ void Scope::addMembers(const SyntaxNode& syntax) {
break;
case SyntaxKind::LibraryDeclaration:
case SyntaxKind::LibraryIncludeStatement:
+ case SyntaxKind::SDFUnit:
// These are ignored here, they're only processed during
- // library map construction.
+ // library map or SDF unit construction.
break;
default:
SLANG_UNREACHABLE;
diff --git a/source/driver/Driver.cpp b/source/driver/Driver.cpp
index 70e191991..2ef5bd14c 100644
--- a/source/driver/Driver.cpp
+++ b/source/driver/Driver.cpp
@@ -277,6 +277,20 @@ void Driver::addStandardArgs() {
"for library name mappings and file lists",
"[,...]", CommandLineFlags::CommaList);
+ cmdLine.add(
+ "--sdf",
+ [this](std::string_view value) {
+ Bag optionBag;
+ addParseOptions(optionBag);
+ auto lo = optionBag.insertOrGet();
+ lo.languageVersion = LanguageVersion::v1497_2001;
+ optionBag.set(lo);
+ sourceLoader.addSDFFiles(value, {}, optionBag);
+ return "";
+ },
+ "One or more standard delay format files to parse", "[,...]",
+ CommandLineFlags::CommaList);
+
cmdLine.add(
"-y,--libdir",
[this](std::string_view value) {
@@ -782,6 +796,8 @@ std::unique_ptr Driver::createCompilation() {
defaultLib->isDefault = true;
auto compilation = std::make_unique(createOptionBag(), defaultLib);
+ for (auto& tree : sourceLoader.getSDFUnits())
+ compilation->addSyntaxTree(tree);
for (auto& tree : sourceLoader.getLibraryMaps())
compilation->addSyntaxTree(tree);
for (auto& tree : syntaxTrees)
diff --git a/source/driver/SourceLoader.cpp b/source/driver/SourceLoader.cpp
index a2fd7506b..7d9d4f515 100644
--- a/source/driver/SourceLoader.cpp
+++ b/source/driver/SourceLoader.cpp
@@ -74,6 +74,11 @@ void SourceLoader::addLibraryMaps(std::string_view pattern, const fs::path& base
addLibraryMapsInternal(pattern, basePath, optionBag, /* expandEnvVars */ false, seenMaps);
}
+void SourceLoader::addSDFFiles(std::string_view pattern, const fs::path& basePath,
+ const Bag& optionBag) {
+ addSDFFilesInternal(pattern, basePath, optionBag);
+}
+
void SourceLoader::addSeparateUnit(std::span filePatterns,
const std::vector& includePaths,
std::vector defines,
@@ -152,6 +157,29 @@ void SourceLoader::addLibraryMapsInternal(std::string_view pattern, const fs::pa
}
}
+void SourceLoader::addSDFFilesInternal(std::string_view pattern, const fs::path& basePath,
+ const Bag& optionBag) {
+ SmallVector files;
+ std::error_code ec;
+ svGlob(basePath, pattern, GlobMode::Files, files, /* expandEnvVars=*/false, ec);
+
+ if (ec) {
+ addError(pattern, ec);
+ return;
+ }
+
+ for (auto& path : files) {
+ auto buffer = sourceManager.readSource(path, /* library */ nullptr);
+ if (!buffer) {
+ addError(path, buffer.error());
+ continue;
+ }
+
+ auto tree = SyntaxTree::fromSDFBuffer(*buffer, sourceManager, optionBag);
+ sdfUnitTrees.push_back(tree);
+ }
+}
+
std::vector SourceLoader::loadSources() {
std::vector results;
results.reserve(fileEntries.size());
diff --git a/source/parsing/Lexer.cpp b/source/parsing/Lexer.cpp
index 6d76df7c9..424aa4dfe 100644
--- a/source/parsing/Lexer.cpp
+++ b/source/parsing/Lexer.cpp
@@ -448,6 +448,13 @@ Token Lexer::lexToken(KeywordVersion keywordVersion) {
case '7':
case '8':
case '9':
+ // Parse SDF '0z'/'1z' lexemes
+ if (isSDFFile() and peek() == 'z' and (c == '0' or c == '1')) {
+ advance();
+ return (c == '0') ? create(TokenKind::SDFEdgeIdent0Z)
+ : create(TokenKind::SDFEdgeIdent1Z);
+ }
+
// back up so that lexNumericLiteral can look at this digit again
sourceBuffer--;
return lexNumericLiteral();
@@ -570,10 +577,24 @@ Token Lexer::lexToken(KeywordVersion keywordVersion) {
case 'y': case 'z':
case '_': {
// clang-format on
+ // Parse SDF scalar constant base which not consist an apostrophe
+ // (due to grammar)
+ if (isSDFFile() && (c == 'b' || c == 'B')) {
+ if (peek() == '0' || peek() == '1') {
+ advance();
+ if (!isAlphaNumeric(peek())) {
+ --sourceBuffer;
+ LiteralBase base = LiteralBase::Binary;
+ return create(TokenKind::IntegerBase, base, true);
+ }
+ }
+ }
scanIdentifier();
// might be a keyword
- auto table = LF::getKeywordTable(keywordVersion);
+ auto table = (!isSDFFile()) ? LF::getKeywordTable(keywordVersion)
+ : LF::getKeywordTable(KeywordVersion::v1497_2001);
+
SLANG_ASSERT(table);
if (auto it = table->find(lexeme()); it != table->end())
return create(it->second);
diff --git a/source/parsing/LexerFacts.cpp b/source/parsing/LexerFacts.cpp
index ed0f1b08b..522af2086 100644
--- a/source/parsing/LexerFacts.cpp
+++ b/source/parsing/LexerFacts.cpp
@@ -69,7 +69,9 @@ const static flat_hash_map keywordVersionTable
{ "1800-2009", KeywordVersion::v1800_2009 },
{ "1800-2012", KeywordVersion::v1800_2012 },
{ "1800-2017", KeywordVersion::v1800_2017 },
- { "1800-2023", KeywordVersion::v1800_2023 }
+ { "1800-2023", KeywordVersion::v1800_2023 },
+ // SDF standard
+ { "1497-2001", KeywordVersion::v1497_2001 }
};
// Lists of keywords, separated by the specification in which they were first introduced
@@ -336,9 +338,66 @@ const static flat_hash_map keywordVersionTable
{ "nettype", TokenKind::NetTypeKeyword },\
{ "soft", TokenKind::SoftKeyword }
+#define SDFKEYWORDS_1497_2001 \
+ { "DELAYFILE", TokenKind::SDFDelayFileKeyword },\
+ { "SDFVERSION", TokenKind::SDFVersionKeyword },\
+ { "DESIGN", TokenKind::SDFDesignKeyword },\
+ { "DATE", TokenKind::SDFDateKeyword },\
+ { "VENDOR", TokenKind::SDFVendorKeyword },\
+ { "PROGRAM", TokenKind::SDFProgramKeyword },\
+ { "VERSION", TokenKind::SDFProgramVersionKeyword },\
+ { "DIVIDER", TokenKind::SDFDividerKeyword },\
+ { "VOLTAGE", TokenKind::SDFVoltageKeyword },\
+ { "PROCESS", TokenKind::SDFProcessKeyword },\
+ { "TEMPERATURE", TokenKind::SDFTemperatureKeyword },\
+ { "TIMESCALE", TokenKind::SDFTimescaleKeyword },\
+ { "CELL", TokenKind::SDFCellKeyword },\
+ { "CELLTYPE", TokenKind::SDFCellTypeKeyword },\
+ { "INSTANCE", TokenKind::SDFInstanceKeyword },\
+ { "DELAY", TokenKind::SDFDelayKeyword },\
+ { "TIMINGCHECK", TokenKind::SDFTimingCheckKeyword },\
+ { "TIMINGENV", TokenKind::SDFTimingEnvKeyword },\
+ { "LABEL", TokenKind::SDFLabelKeyword },\
+ { "PATHPULSE", TokenKind::SDFPathPulseKeyword },\
+ { "PATHPULSEPERCENT", TokenKind::SDFPathPulsePercentKeyword },\
+ { "ABSOLUTE", TokenKind::SDFAbsoluteKeyword },\
+ { "INCREMENT", TokenKind::SDFIncrementKeyword },\
+ { "IOPATH", TokenKind::SDFIOPathKeyword },\
+ { "RETAIN", TokenKind::SDFRetainKeyword },\
+ { "COND", TokenKind::SDFCondKeyword },\
+ { "CONDELSE", TokenKind::SDFCondElseKeyword },\
+ { "PORT", TokenKind::SDFPortKeyword },\
+ { "INTERCONNECT", TokenKind::SDFInterconnectKeyword },\
+ { "NETDELAY", TokenKind::SDFNetDelayKeyword },\
+ { "DEVICE", TokenKind::SDFDeviceKeyword },\
+ { "SETUP", TokenKind::SDFSetupKeyword },\
+ { "HOLD", TokenKind::SDFHoldKeyword },\
+ { "SETUPHOLD", TokenKind::SDFSetupHoldKeyword },\
+ { "RECOVERY", TokenKind::SDFRecoveryKeyword },\
+ { "REMOVAL", TokenKind::SDFRemovalKeyword },\
+ { "RECREM", TokenKind::SDFRecremKeyword },\
+ { "SKEW", TokenKind::SDFSkewKeyword },\
+ { "BIDIRECTSKEW", TokenKind::SDFBidirectSkewKeyword },\
+ { "WIDTH", TokenKind::SDFWidthKeyword },\
+ { "PERIOD", TokenKind::SDFPeriodKeyword },\
+ { "NOCHANGE", TokenKind::SDFNochangeKeyword },\
+ { "SCOND", TokenKind::SDFSCondKeyword },\
+ { "CCOND", TokenKind::SDFCCondKeyword },\
+ { "PATHCONSTRAINT", TokenKind::SDFPathConstraintKeyword },\
+ { "PERIODCONSTRAINT", TokenKind::SDFPeriodConstraintKeyword },\
+ { "SUM", TokenKind::SDFSumKeyword },\
+ { "DIFF", TokenKind::SDFDiffKeyword },\
+ { "SKEWCONSTRAINT", TokenKind::SDFSkewConstraintKeyword },\
+ { "EXCEPTION", TokenKind::SDFExceptionKeyword },\
+ { "NAME", TokenKind::SDFNameKeyword },\
+ { "ARRIVAL", TokenKind::SDFArrivalKeyword },\
+ { "DEPARTURE", TokenKind::SDFDepartureKeyword },\
+ { "SLACK", TokenKind::SDFSlackKeyword },\
+ { "WAVEFORM", TokenKind::SDFWaveformKeyword }
+
// We maintain a separate table of keywords for all the various specifications,
// to allow for easy switching between them when requested
-const static flat_hash_map allKeywords[9] =
+const static flat_hash_map allKeywords[10] =
{ { // IEEE 1364-1995
KEYWORDS_1364_1995
}, { // IEEE 1364-2001-noconfig
@@ -390,7 +449,9 @@ const static flat_hash_map allKeywords[9] =
NEWKEYWORDS_1800_2005,
NEWKEYWORDS_1800_2009,
NEWKEYWORDS_1800_2012
-} };
+}, { // IEEE 1497-2001 (SDF)
+ SDFKEYWORDS_1497_2001
+}};
// clang-format on
bool LexerFacts::isKeyword(TokenKind kind) {
@@ -669,6 +730,8 @@ KeywordVersion LexerFacts::getDefaultKeywordVersion(LanguageVersion languageVers
return KeywordVersion::v1800_2017;
case LanguageVersion::v1800_2023:
return KeywordVersion::v1800_2023;
+ case LanguageVersion::v1497_2001:
+ return KeywordVersion::v1497_2001;
default:
SLANG_UNREACHABLE;
}
@@ -1058,6 +1121,66 @@ std::string_view LexerFacts::getTokenKindText(TokenKind kind) {
case TokenKind::MacroEscapedQuote: return "`\\`\"";
case TokenKind::MacroPaste: return "``";
+ // SDF keywords
+ case TokenKind::SDFAbsoluteKeyword: return "ABSOLUTE";
+ case TokenKind::SDFArrivalKeyword: return "ARRIVAL";
+ case TokenKind::SDFBidirectSkewKeyword: return "BIDIRECTSKEW";
+ case TokenKind::SDFCCondKeyword: return "CCOND";
+ case TokenKind::SDFCellKeyword: return "CELL";
+ case TokenKind::SDFCellTypeKeyword: return "CELLTYPE";
+ case TokenKind::SDFCondKeyword: return "COND";
+ case TokenKind::SDFCondElseKeyword: return "CONDELSE";
+ case TokenKind::SDFDateKeyword: return "DATE";
+ case TokenKind::SDFDelayKeyword: return "DELAY";
+ case TokenKind::SDFDelayFileKeyword: return "DELAYFILE";
+ case TokenKind::SDFDepartureKeyword: return "DEPARTURE";
+ case TokenKind::SDFDesignKeyword: return "DESIGN";
+ case TokenKind::SDFDeviceKeyword: return "DEVICE";
+ case TokenKind::SDFDiffKeyword: return "DIFF";
+ case TokenKind::SDFDividerKeyword: return "DIVIDER";
+ case TokenKind::SDFExceptionKeyword: return "EXCEPTION";
+ case TokenKind::SDFHoldKeyword: return "HOLD";
+ case TokenKind::SDFIOPathKeyword: return "IOPATH";
+ case TokenKind::SDFIncrementKeyword: return "INCREMENT";
+ case TokenKind::SDFInstanceKeyword: return "INSTANCE";
+ case TokenKind::SDFInterconnectKeyword: return "INTERCONNECT";
+ case TokenKind::SDFLabelKeyword: return "LABEL";
+ case TokenKind::SDFNameKeyword: return "NAME";
+ case TokenKind::SDFNetDelayKeyword: return "NETDELAY";
+ case TokenKind::SDFNochangeKeyword: return "NOCHANGE";
+ case TokenKind::SDFPathConstraintKeyword: return "PATHCONSTRAINT";
+ case TokenKind::SDFPathPulseKeyword: return "PATHPULSE";
+ case TokenKind::SDFPathPulsePercentKeyword: return "PATHPULSEPERCENT";
+ case TokenKind::SDFPeriodKeyword: return "PERIOD";
+ case TokenKind::SDFPeriodConstraintKeyword: return "PERIODCONSTRAINT";
+ case TokenKind::SDFPortKeyword: return "PORT";
+ case TokenKind::SDFProcessKeyword: return "PROCESS";
+ case TokenKind::SDFProgramKeyword: return "PROGRAM";
+ case TokenKind::SDFProgramVersionKeyword: return "VERSION";
+ case TokenKind::SDFRecoveryKeyword: return "RECOVERY";
+ case TokenKind::SDFRecremKeyword: return "RECREM";
+ case TokenKind::SDFRemovalKeyword: return "REMOVAL";
+ case TokenKind::SDFRetainKeyword: return "RETAIN";
+ case TokenKind::SDFSCondKeyword: return "SCOND";
+ case TokenKind::SDFSetupKeyword: return "SETUP";
+ case TokenKind::SDFSetupHoldKeyword: return "SETUPHOLD";
+ case TokenKind::SDFSkewKeyword: return "SKEW";
+ case TokenKind::SDFSkewConstraintKeyword: return "SKEWCONSTRAINT";
+ case TokenKind::SDFSlackKeyword: return "SLACK";
+ case TokenKind::SDFSumKeyword: return "SUM";
+ case TokenKind::SDFTemperatureKeyword: return "TEMPERATURE";
+ case TokenKind::SDFTimescaleKeyword: return "TIMESCALE";
+ case TokenKind::SDFTimingCheckKeyword: return "TIMINGCHECK";
+ case TokenKind::SDFTimingEnvKeyword: return "TIMINGENV";
+ case TokenKind::SDFVendorKeyword: return "VENDOR";
+ case TokenKind::SDFVersionKeyword: return "SDFVERSION";
+ case TokenKind::SDFVoltageKeyword: return "VOLTAGE";
+ case TokenKind::SDFWaveformKeyword: return "WAVEFORM";
+ case TokenKind::SDFWidthKeyword: return "WIDTH";
+
+ // SDF special tokens
+ case TokenKind::SDFEdgeIdent0Z: return "0Z";
+ case TokenKind::SDFEdgeIdent1Z: return "1Z";
default: return "";
}
}
diff --git a/source/parsing/Parser_expressions.cpp b/source/parsing/Parser_expressions.cpp
index 6a7759cb0..916a5ab0c 100644
--- a/source/parsing/Parser_expressions.cpp
+++ b/source/parsing/Parser_expressions.cpp
@@ -48,17 +48,20 @@ static bool isNewExpr(const ExpressionSyntax* expr) {
}
ExpressionSyntax& Parser::parseSubExpression(bitmask options, int precedence) {
+ bool isSDFCondExpr = options.has(ExpressionOptions::SDFCondExpr);
+ bool isSDFTimingCheckExpr = options.has(ExpressionOptions::SDFTimingCheckCondExpr);
+ bool isSDFExpr = isSDFCondExpr || isSDFTimingCheckExpr;
auto dg = setDepthGuard();
auto current = peek();
- if (isPossibleDelayOrEventControl(current.kind)) {
+ if (isPossibleDelayOrEventControl(current.kind) && !isSDFExpr) {
auto timingControl = parseTimingControl();
SLANG_ASSERT(timingControl);
auto& expr = factory.timingControlExpression(*timingControl, parseExpression());
return parsePostfixExpression(expr, options);
}
- else if (current.kind == TokenKind::TaggedKeyword) {
+ else if (current.kind == TokenKind::TaggedKeyword && !isSDFExpr) {
auto tagged = consume();
auto member = expect(TokenKind::Identifier);
@@ -74,14 +77,34 @@ ExpressionSyntax& Parser::parseSubExpression(bitmask options,
}
ExpressionSyntax* leftOperand;
- SyntaxKind opKind = getUnaryPrefixExpression(current.kind);
+ SyntaxKind opKind = (!isSDFExpr) ? getUnaryPrefixExpression(current.kind)
+ : getSDFUnaryPrefixExpression(current.kind);
+
if (opKind != SyntaxKind::Unknown) {
- auto opToken = consume();
- auto attributes = parseAttributes();
+ if (isSDFTimingCheckExpr && opKind != SyntaxKind::UnaryBitwiseNotExpression &&
+ opKind != SyntaxKind::UnaryLogicalNotExpression)
+ addDiag(diag::InvalidSDFInvOp, current.range());
- auto& operand = parsePrimaryExpression(options);
- auto& postfix = parsePostfixExpression(operand, options);
- leftOperand = &factory.prefixUnaryExpression(opKind, opToken, attributes, postfix);
+ auto opToken = consume();
+ AttrList attributes;
+ if (!isSDFExpr)
+ attributes = parseAttributes();
+
+ ExpressionSyntax* postfix = nullptr;
+ if (isSDFCondExpr)
+ postfix = &parseSDFPrimaryExpression(options);
+ else if (isSDFTimingCheckExpr)
+ return factory.prefixUnaryExpression(
+ opKind, opToken, attributes, parseSDFPostfixExpression(parseSDFHierIdentifier()));
+ else
+ postfix = &parsePostfixExpression(parsePrimaryExpression(options), options);
+ leftOperand = &factory.prefixUnaryExpression(opKind, opToken, attributes, *postfix);
+ }
+ else if (isSDFExpr) {
+ if (isSDFCondExpr)
+ leftOperand = &parseSDFPrimaryExpression(options);
+ else
+ leftOperand = &parseSDFPostfixExpression(parseSDFHierIdentifier());
}
else {
leftOperand = &parsePrimaryExpression(options);
@@ -101,10 +124,33 @@ ExpressionSyntax& Parser::parseSubExpression(bitmask options,
ExpressionSyntax& Parser::parseBinaryExpression(ExpressionSyntax* left,
bitmask options,
int precedence) {
+ bool isSDFCondExpr = options.has(ExpressionOptions::SDFCondExpr);
+ bool isSDFTimingCheckExpr = options.has(ExpressionOptions::SDFTimingCheckCondExpr);
+
Token current;
while (true) {
// either a binary operator, or we're done
current = peek();
+
+ if (isSDFCondExpr) {
+ if (current.kind != TokenKind::Question)
+ return *left;
+ // Trying to parse only ternary operator
+ // according to SDF port conditional expression syntax
+ break;
+ }
+
+ if (isSDFTimingCheckExpr) {
+ auto opKind = getSDFBinaryExpression(current.kind);
+ if (opKind == SyntaxKind::Unknown)
+ return *left;
+
+ auto opToken = consume();
+ AttrList attributes;
+ return factory.binaryExpression(opKind, *left, opToken, attributes,
+ parseSDFPostfixExpression(parseSDFHierIdentifier()));
+ }
+
auto opKind = getBinaryExpression(current.kind);
if (opKind == SyntaxKind::Unknown) {
break;
@@ -182,8 +228,11 @@ ExpressionSyntax& Parser::parseBinaryExpression(ExpressionSyntax* left,
if (takeConditional) {
Token question;
- auto& predicate = parseConditionalPredicate(*left, TokenKind::Question, question);
- auto attributes = parseAttributes();
+ auto& predicate = parseConditionalPredicate(*left, TokenKind::Question, question,
+ /*isSDFCondPred =*/isSDFCondExpr);
+ AttrList attributes;
+ if (!isSDFCondExpr)
+ attributes = parseAttributes();
auto& lhs = parseSubExpression(options, logicalOrPrecedence - 1);
auto colon = expect(TokenKind::Colon);
auto& rhs = parseSubExpression(options, logicalOrPrecedence - 1);
@@ -301,6 +350,70 @@ ExpressionSyntax& Parser::parsePrimaryExpression(bitmask opti
}
}
+ExpressionSyntax& Parser::parseSDFScalarConstant() {
+ // Valid SDF scalar syntax can be present in such forms:
+ // 0, b0, B0, 1 b0, 1 B0, 1, b1, B1, 1 b1, 1 B1
+
+ // Parse value
+ Token tok = peek();
+ Token size;
+ if (tok.kind == TokenKind::IntegerLiteral) {
+ if (tok.valueText() != "0" && tok.valueText() != "1")
+ addDiag(diag::InvalidSDFExprScalar, tok.range());
+ size = consume();
+ }
+
+ static const std::set validBases = {"b", "B"};
+
+ // Parse base
+ tok = peek();
+ Token base;
+ Token val;
+ // Assume that we lex an SDF syntax scalar constant base form which don't have an apostrophe.
+ if (tok.kind == TokenKind::IntegerBase && validBases.contains(tok.valueText())) {
+ base = consume();
+ val = consume();
+ }
+
+ if (size.kind == TokenKind::Unknown && base.kind == TokenKind::Unknown)
+ addDiag(diag::InvalidSDFExprScalar, tok.range());
+
+ return factory.integerVectorExpression(size, base, val);
+}
+
+ExpressionSyntax& Parser::parseSDFPrimaryExpression(bitmask options) {
+ TokenKind kind = peek().kind;
+ switch (kind) {
+ case TokenKind::IntegerLiteral:
+ case TokenKind::IntegerBase:
+ return parseSDFScalarConstant();
+ case TokenKind::OpenParenthesis: {
+ auto openParen = consume();
+ auto* expr = &parseSubExpression(options, 0);
+ auto closeParen = expect(TokenKind::CloseParenthesis);
+ return factory.parenthesizedExpression(openParen, *expr, closeParen);
+ }
+ case TokenKind::OpenBrace: {
+ // Parse 2 types of concatentation expressions:
+ // 1. multiple concatenation {expr {concat}}
+ // 2. concatenation {expr, expr}
+ auto openBrace = consume();
+ auto& first = parseSubExpression(options, 0);
+ if (!peek(TokenKind::OpenBrace))
+ return parseConcatenation(openBrace, &first, /*isSDFCondExpr = */ true);
+
+ auto openBraceInner = consume();
+ auto& concat = parseConcatenation(openBraceInner, nullptr,
+ /*isSDFCondExpr = */ true);
+ auto closeBrace = expect(TokenKind::CloseBrace);
+ return factory.multipleConcatenationExpression(openBrace, first, concat, closeBrace);
+ }
+ default:
+ // Parse SDF qualified name
+ return parseSDFHierIdentifier();
+ }
+}
+
ExpressionSyntax& Parser::parseIntegerExpression(bool disallowVector) {
auto result = disallowVector ? numberParser.parseSimpleInt(*this)
: numberParser.parseInteger(*this);
@@ -362,8 +475,8 @@ ExpressionSyntax& Parser::parseValueRangeElement(bitmask opti
return factory.valueRangeExpression(openBracket, left, op, right, closeBracket);
}
-ConcatenationExpressionSyntax& Parser::parseConcatenation(Token openBrace,
- ExpressionSyntax* first) {
+ConcatenationExpressionSyntax& Parser::parseConcatenation(Token openBrace, ExpressionSyntax* first,
+ bool isSDFCondExpr) {
SmallVector buffer;
if (first) {
// it's possible to have just one element in the concatenation list, so check for a close
@@ -378,7 +491,11 @@ ConcatenationExpressionSyntax& Parser::parseConcatenation(Token openBrace,
Token closeBrace;
parseList(
buffer, TokenKind::CloseBrace, TokenKind::Comma, closeBrace, RequireItems::False,
- diag::ExpectedExpression, [this] { return &parseExpression(); });
+ diag::ExpectedExpression, [this, isSDFCondExpr] {
+ if (!isSDFCondExpr)
+ return &parseExpression();
+ return &parseSubExpression(ExpressionOptions::SDFCondExpr, 0);
+ });
return factory.concatenationExpression(openBrace, buffer.copy(alloc), closeBrace);
}
@@ -668,10 +785,52 @@ ExpressionSyntax& Parser::parsePostfixExpression(ExpressionSyntax& lhs,
}
}
+ExpressionSyntax& Parser::parseSDFPostfixExpression(ExpressionSyntax& expr) {
+ if (peek().kind == TokenKind::OpenBracket) {
+ auto openBracket = expect(TokenKind::OpenBracket);
+ auto* selector = &factory.bitSelect(factory.literalExpression(
+ SyntaxKind::IntegerLiteralExpression, expect(TokenKind::IntegerLiteral)));
+ auto closeBracket = expect(TokenKind::CloseBracket);
+ auto& elemSelect = factory.elementSelect(openBracket, selector, closeBracket);
+ return factory.elementSelectExpression(expr, elemSelect);
+ }
+ return expr;
+}
+
NameSyntax& Parser::parseName() {
return parseName(NameOptions::None);
}
+NameSyntax& Parser::parseSDFHierIdentifier() {
+ NameSyntax* name = &factory.identifierName(expect(TokenKind::Identifier));
+ Token sep;
+
+ while (true) {
+ auto curr = peek();
+ if (curr.kind != TokenKind::Dot && curr.kind != TokenKind::Slash)
+ break;
+
+ // Parse separator
+ curr = consume();
+ if (sep.kind == TokenKind::Unknown)
+ sep = curr;
+ else if (curr.kind != sep.kind)
+ addDiag(diag::DifferentSDFNameSeperator, curr.range()) << sep.valueText();
+
+ // Parse name
+ curr = peek();
+ if (curr.kind != TokenKind::Identifier) {
+ addDiag(diag::ExpectedSDFIdentifier, curr.range());
+ break;
+ }
+
+ NameSyntax& rhs = factory.identifierName(consume());
+ name = &factory.scopedName(*name, sep, rhs);
+ }
+
+ return *name;
+}
+
NameSyntax& Parser::parseName(bitmask options) {
NameSyntax* name = &parseNamePart(options | NameOptions::IsFirst);
options &= ~NameOptions::ExpectingExpression;
@@ -980,18 +1139,19 @@ StructurePatternMemberSyntax& Parser::parseMemberPattern() {
}
ConditionalPredicateSyntax& Parser::parseConditionalPredicate(ExpressionSyntax& first,
- TokenKind endKind, Token& end) {
+ TokenKind endKind, Token& end,
+ bool isSDFCondPred) {
SmallVector buffer;
MatchesClauseSyntax* matchesClause = nullptr;
- if (peek(TokenKind::MatchesKeyword)) {
+ if (!isSDFCondPred && peek(TokenKind::MatchesKeyword)) {
auto matches = consume();
matchesClause = &factory.matchesClause(matches, parsePattern());
}
buffer.push_back(&factory.conditionalPattern(first, matchesClause));
- if (peek(TokenKind::TripleAnd)) {
+ if (!isSDFCondPred && peek(TokenKind::TripleAnd)) {
buffer.push_back(consume());
parseList(
buffer, endKind, TokenKind::TripleAnd, end, RequireItems::True,
diff --git a/source/parsing/Parser_members.cpp b/source/parsing/Parser_members.cpp
index 0bf3257d7..9311260fd 100644
--- a/source/parsing/Parser_members.cpp
+++ b/source/parsing/Parser_members.cpp
@@ -41,6 +41,19 @@ LibraryMapSyntax& Parser::parseLibraryMap() {
}
}
+SDFUnitSyntax& Parser::parseSDFUnit() {
+ SLANG_TRY {
+ auto members = parseMemberList(
+ TokenKind::EndOfFile, meta.eofToken, SyntaxKind::SDFUnit,
+ [this](SyntaxKind, bool&) { return parseSDFDelayFile(); }, /*memberLimit =*/1);
+
+ return factory.sDFUnit(members, meta.eofToken);
+ }
+ SLANG_CATCH(const RecursionException&) {
+ return factory.sDFUnit(nullptr, meta.eofToken);
+ }
+}
+
MemberSyntax& Parser::parseModule() {
bool anyLocalModules = false;
return parseModule(parseAttributes(), SyntaxKind::CompilationUnit, anyLocalModules);
@@ -423,7 +436,8 @@ MemberSyntax* Parser::parseSingleMember(SyntaxKind parentKind) {
template
std::span Parser::parseMemberList(TokenKind endKind, Token& endToken,
- SyntaxKind parentKind, TParseFunc&& parseFunc) {
+ SyntaxKind parentKind, TParseFunc&& parseFunc,
+ uint32_t memberLimit) {
SmallVector members;
bool errored = false;
bool anyLocalModules = false;
@@ -435,6 +449,13 @@ std::span Parser::parseMemberList(TokenKind endKind, Token& endToken,
auto member = parseFunc(parentKind, anyLocalModules);
if (member) {
+ // If memberLimit is set to 0 (which is default value)
+ // the number of members will not be checked.
+ if (memberLimit && memberLimit == members.size()) {
+ addDiag(diag::MemberLimitViolation, member->sourceRange().start()) << memberLimit;
+ continue;
+ }
+
checkMemberAllowed(*member, parentKind);
members.push_back(member);
errored = false;
@@ -3894,6 +3915,934 @@ FilePathSpecSyntax& Parser::parseFilePathSpec() {
return factory.filePathSpec(path);
}
+SDFTimescaleSyntax* Parser::parseSDFTimescale() {
+ if (peek().kind != TokenKind::OpenParenthesis || peek(1).kind != TokenKind::SDFTimescaleKeyword)
+ return nullptr;
+
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = expect(TokenKind::SDFTimescaleKeyword);
+
+ // Timescale number and unit can be parsed as two tokens (RealLiteral and Identifier) for
+ // example: "1 ns" and also as one (TimeLiteral) - 1ns.
+ static std::set validTimescaleNumbers{"1", "10", "100", "1.0", "10", "100.0"};
+ auto number = peek();
+ std::string_view realLitStr = number.valueText();
+ if (number.kind == TokenKind::TimeLiteral) {
+ auto numberText = number.valueText();
+ // Remove 's' suffix
+ realLitStr = numberText.substr(0, numberText.length() - 1);
+ // Remove remaining alpha suffix if it present
+ if (isalpha(realLitStr.back()) != 0)
+ realLitStr = numberText.substr(0, numberText.length() - 2);
+ }
+
+ if (!validTimescaleNumbers.contains(realLitStr)) {
+ addDiag(diag::InvalidSDFTimescaleUnit, number.range());
+ return nullptr;
+ }
+ number = consume();
+
+ if (number.kind != TokenKind::TimeLiteral) {
+ static std::set validTimescaleUnits{"s", "ms", "us", "ns", "ps", "fs"};
+ auto unit = peek();
+ if (!validTimescaleUnits.contains(unit.valueText())) {
+ addDiag(diag::InvalidSDFTimescaleUnit, number.range());
+ return nullptr;
+ }
+ unit = consume();
+ return &factory.sDFTimescale(openParen, keyword,
+ factory.literalExpression(SyntaxKind::RealLiteralExpression,
+ number),
+ unit, expect(TokenKind::CloseParenthesis));
+ }
+
+ return &factory.sDFTimescale(
+ openParen, keyword, factory.literalExpression(SyntaxKind::TimeLiteralExpression, number),
+ Token(), expect(TokenKind::CloseParenthesis));
+}
+
+SDFCharMemberSyntax* Parser::parseSDFCharMember(TokenKind keywordKind, bool weak) {
+ if (peek().kind != TokenKind::OpenParenthesis || (weak && peek(1).kind != keywordKind))
+ return nullptr;
+
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = expect(keywordKind);
+
+ auto value = peek();
+ if (keywordKind == TokenKind::SDFDividerKeyword) {
+ if (value.kind != TokenKind::Slash && value.kind != TokenKind::Dot) {
+ addDiag(diag::ExpectedSDFDivider, value.range());
+ return nullptr;
+ }
+ }
+ else if (value.kind != TokenKind::StringLiteral) {
+ addDiag(diag::ExpectedStringLiteral, value.range());
+ return nullptr;
+ }
+ value = consume();
+
+ return &factory.sDFCharMember(openParen, keyword, value, expect(TokenKind::CloseParenthesis));
+}
+
+SDFValueSyntax* Parser::parseSDFValue(const std::set& endKinds, bool withParens,
+ bool isSign) {
+ // Try to parse such value cases (where braces wrap optional tokens and min, typ, max may be
+ // signed or unsigned integers or real literals):
+ // - triple [`(`] [min] `:` [typ] `:` [max] [`)`]
+ // - single [`(`] [value] [`)`]
+ // Why the `parseMinTypMaxExpression` method is not used is that parsing this type of SDF
+ // expression is more difficult due to the fact that all values can be optional.
+ std::set expectedExprKinds{SyntaxKind::IntegerLiteralExpression,
+ SyntaxKind::RealLiteralExpression};
+ if (isSign)
+ expectedExprKinds.insert(SyntaxKind::UnaryMinusExpression);
+
+ ExpressionSyntax* min = nullptr;
+ ExpressionSyntax* typ = nullptr;
+ ExpressionSyntax* max = nullptr;
+ Token curr;
+ if (withParens)
+ curr = expect(TokenKind::OpenParenthesis);
+
+ uint32_t colonCount = 0;
+ while (true) {
+ curr = peek();
+ if (endKinds.contains(curr.kind) || colonCount >= 2)
+ break;
+
+ if (curr.kind != TokenKind::Colon && curr.kind != TokenKind::DoubleColon) {
+ if (min != nullptr) {
+ addDiag(diag::InvalidSDFValueSep, curr.range());
+ return &factory.sDFValue(min, typ, max);
+ }
+ }
+ else {
+ curr = consume();
+ colonCount = (curr.kind == TokenKind::Colon) ? colonCount + 1 : colonCount + 2;
+ }
+
+ if (endKinds.contains(peek().kind))
+ break;
+
+ auto* expr = &parseExpression();
+ if (!expectedExprKinds.contains(expr->kind)) {
+ addDiag(diag::InvalidSDFValueExpr, expr->sourceRange());
+ return &factory.sDFValue(min, typ, max);
+ }
+
+ switch (colonCount) {
+ case 0:
+ min = expr;
+ break;
+ case 1:
+ typ = expr;
+ break;
+ case 2:
+ max = expr;
+ break;
+ default:
+ break;
+ }
+ }
+
+ // When colonCount is 0 then single scalar or no scalar is emitted instead of triple
+ if (colonCount != 0 && colonCount != 2)
+ addDiag(diag::InvalidSDFValueExpr, curr.range());
+
+ // Value propagation in case of single value
+ if (colonCount == 0 && min)
+ max = typ = min;
+
+ if (withParens)
+ curr = expect(TokenKind::CloseParenthesis);
+ return &factory.sDFValue(min, typ, max);
+}
+
+SDFDelayValueSyntax* Parser::parseSDFDelayValue() {
+ SmallVector values;
+ if (peek().kind != TokenKind::OpenParenthesis)
+ return &factory.sDFDelayValue(values.copy(alloc));
+
+ auto lookahead = peek(1);
+ if (lookahead.kind == TokenKind::OpenParenthesis) {
+ lookahead = expect(TokenKind::OpenParenthesis);
+ values.push_back(
+ parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true, /*isSign =*/true));
+ values.push_back(
+ parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true, /*isSign =*/true));
+ lookahead = peek();
+ if (lookahead.kind != TokenKind::CloseParenthesis)
+ values.push_back(parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true,
+ /*isSign =*/true));
+ lookahead = expect(TokenKind::CloseParenthesis);
+ }
+ else {
+ values.push_back(
+ parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true, /*isSign =*/true));
+ }
+
+ return &factory.sDFDelayValue(values.copy(alloc));
+}
+
+std::span Parser::parseSDFDelayValueList(bool isRetain) {
+ SmallVector delayValues;
+ delayValues.push_back(parseSDFDelayValue());
+
+ while (peek().kind == TokenKind::OpenParenthesis)
+ delayValues.push_back(parseSDFDelayValue());
+
+ if (isRetain && delayValues.size() > 3)
+ addDiag(diag::InvalidSDFDelayValuesList, peek().range()) << 3;
+ else if (delayValues.size() > 12)
+ addDiag(diag::InvalidSDFDelayValuesList, peek().range()) << 12;
+ return delayValues.copy(alloc);
+}
+
+SDFValueMemberSyntax* Parser::parseSDFValueMember(TokenKind keywordKind) {
+ if (peek().kind != TokenKind::OpenParenthesis || (peek(1).kind != keywordKind))
+ return nullptr;
+
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+
+ auto* value = parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/false,
+ /*isSign =*/true);
+ return &factory.sDFValueMember(openParen, keyword, *value, expect(TokenKind::CloseParenthesis));
+}
+
+SDFHeaderSyntax& Parser::parseSDFHeader() {
+ auto* version = parseSDFCharMember(TokenKind::SDFVersionKeyword, /*weak =*/false);
+ auto* design = parseSDFCharMember(TokenKind::SDFDesignKeyword);
+ auto* date = parseSDFCharMember(TokenKind::SDFDateKeyword);
+ auto* vendor = parseSDFCharMember(TokenKind::SDFVendorKeyword);
+ auto* programName = parseSDFCharMember(TokenKind::SDFProgramKeyword);
+ auto* programVersion = parseSDFCharMember(TokenKind::SDFProgramVersionKeyword);
+ auto* divider = parseSDFCharMember(TokenKind::SDFDividerKeyword);
+ SDFValueMemberSyntax* voltage = parseSDFValueMember(TokenKind::SDFVoltageKeyword);
+ auto* process = parseSDFCharMember(TokenKind::SDFProcessKeyword);
+ SDFValueMemberSyntax* temperature = parseSDFValueMember(TokenKind::SDFTemperatureKeyword);
+ SDFTimescaleSyntax* timescale = parseSDFTimescale();
+ return factory.sDFHeader(version, design, date, vendor, programName, programVersion, divider,
+ voltage, process, temperature, timescale);
+}
+
+SDFNameSyntax* Parser::parseSDFName() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = expect(TokenKind::SDFNameKeyword);
+ LiteralExpressionSyntax* name = nullptr;
+ if (peek().kind == TokenKind::StringLiteral)
+ name = &factory.literalExpression(SyntaxKind::StringLiteralExpression, consume());
+ return &factory.sDFName(openParen, keyword, name, expect(TokenKind::CloseParenthesis));
+}
+
+SDFPortSpecSyntax* Parser::parseSDFPortSpec() {
+ if (peek().kind == TokenKind::OpenParenthesis)
+ return parseSDFPortEdge();
+ return parseSDFPort();
+}
+
+SDFPortSyntax* Parser::parseSDFPort() {
+ NameSyntax& name = parseSDFHierIdentifier();
+ auto lookahead = peek();
+ if (lookahead.kind == TokenKind::OpenBracket) {
+ SelectorSyntax* selector = nullptr;
+ auto openBracket = consume();
+ auto& lhs = factory.literalExpression(SyntaxKind::IntegerLiteralExpression,
+ expect(TokenKind::IntegerLiteral));
+ auto colon = peek();
+ if (colon.kind == TokenKind::Colon) {
+ colon = consume();
+ auto& rhs = factory.literalExpression(SyntaxKind::IntegerLiteralExpression,
+ expect(TokenKind::IntegerLiteral));
+ selector = &factory.rangeSelect(SyntaxKind::SimpleRangeSelect, lhs, colon, rhs);
+ }
+ else {
+ selector = &factory.bitSelect(lhs);
+ }
+
+ auto closeBracket = expect(TokenKind::CloseBracket);
+ auto& elemSelect = factory.elementSelect(openBracket, selector, closeBracket);
+ return &factory.sDFPort(factory.elementSelectExpression(name, elemSelect));
+ }
+
+ return &factory.sDFPort(name);
+}
+
+SDFPortEdgeSyntax* Parser::parseSDFPortEdge() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ // posedge and negedge are not specified as keywords in IEEE 1497-2001 SDF standard
+ static const std::set validTokenText{"posedge", "negedge", "01",
+ "10", "0z", "1z"};
+ bool isError = false;
+ auto edge = consume();
+ switch (edge.kind) {
+ case TokenKind::SDFEdgeIdent0Z:
+ case TokenKind::SDFEdgeIdent1Z:
+ break;
+ case TokenKind::IntegerLiteral:
+ case TokenKind::Identifier: {
+ if (!validTokenText.contains(edge.valueText()))
+ isError = true;
+ break;
+ }
+ default:
+ isError = true;
+ break;
+ }
+
+ if (isError)
+ addDiag(diag::InvalidSDFPortEdgeIdentifier, edge.range());
+
+ auto* port = parseSDFPort();
+ return &factory.sDFPortEdge(openParen, edge, *port, expect(TokenKind::CloseParenthesis));
+}
+
+SDFCellInstanceSyntax* Parser::parseSDFCellInstance() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = expect(TokenKind::SDFInstanceKeyword);
+ NameSyntax* name = nullptr;
+ auto lookahead = peek();
+ switch (lookahead.kind) {
+ case TokenKind::Star:
+ name = &factory.identifierName(consume());
+ break;
+ case TokenKind::Identifier:
+ name = &parseSDFHierIdentifier();
+ break;
+ default: {
+ if (lookahead.kind != TokenKind::CloseParenthesis)
+ addDiag(diag::InvalidSDFCellInstanceIdentifier, lookahead.range());
+
+ name = &factory.identifierName(Token());
+ break;
+ }
+ }
+
+ auto closeParen = expect(TokenKind::CloseParenthesis);
+ return &factory.sDFCellInstance(openParen, keyword, *name, closeParen);
+}
+
+SDFExceptionSyntax* Parser::parseSDFException() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = expect(TokenKind::SDFExceptionKeyword);
+ SmallVector instances;
+ while (peek().kind == TokenKind::OpenParenthesis)
+ instances.push_back(parseSDFCellInstance());
+
+ if (instances.empty())
+ addDiag(diag::ExpectedSDFMember, peek().range()) << "cell instance"sv;
+ return &factory.sDFException(openParen, keyword, instances.copy(alloc),
+ expect(TokenKind::CloseParenthesis));
+}
+
+SDFPathPulseSyntax* Parser::parseSDFPathPulse() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ SDFPortSyntax* in = nullptr;
+ SDFPortSyntax* out = nullptr;
+ // Parse input and output port identifiers
+ if (peek().kind == TokenKind::Identifier) {
+ in = parseSDFPort();
+ out = parseSDFPort();
+ }
+
+ SmallVector values;
+ values.push_back(parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true,
+ /*isSign =*/false));
+
+ if (peek().kind != TokenKind::CloseParenthesis)
+ values.push_back(parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true,
+ /*isSign =*/false));
+
+ auto closeParen = expect(TokenKind::CloseParenthesis);
+ return &factory.sDFPathPulse(openParen, keyword, in, out, values.copy(alloc), closeParen);
+}
+
+SDFRetainSyntax* Parser::parseSDFRetain() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ auto values = parseSDFDelayValueList(/*isRetain =*/true);
+ auto closeParen = expect(TokenKind::CloseParenthesis);
+ return &factory.sDFRetain(openParen, keyword, values, closeParen);
+}
+
+SDFIOPathSyntax* Parser::parseSDFIOPath() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ SmallVector ports;
+ ports.push_back(parseSDFPortSpec());
+ ports.push_back(parseSDFPort());
+ SDFRetainSyntax* retain = nullptr;
+ if (peek().kind == TokenKind::OpenParenthesis && peek(1).kind == TokenKind::SDFRetainKeyword)
+ retain = parseSDFRetain();
+ auto values = parseSDFDelayValueList();
+ auto closeParen = expect(TokenKind::CloseParenthesis);
+ return &factory.sDFIOPath(openParen, keyword, ports.copy(alloc), retain, values, closeParen);
+}
+
+SDFCondSyntax* Parser::parseSDFCond() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ LiteralExpressionSyntax* name = nullptr;
+ if (peek().kind == TokenKind::StringLiteral)
+ name = &factory.literalExpression(SyntaxKind::StringLiteralExpression, consume());
+ auto* condition = &parseSubExpression(ExpressionOptions::SDFCondExpr, 0);
+ auto* iOPath = parseSDFIOPath();
+ return &factory.sDFCond(openParen, keyword, name, *condition, *iOPath,
+ expect(TokenKind::CloseParenthesis));
+}
+
+SDFCondElseSyntax* Parser::parseSDFCondElse() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ auto* iOPath = parseSDFIOPath();
+ return &factory.sDFCondElse(openParen, keyword, *iOPath, expect(TokenKind::CloseParenthesis));
+}
+
+SDFPortDelayDefSyntax* Parser::parseSDFPortDelayDef() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ auto* port = parseSDFPort();
+ auto values = parseSDFDelayValueList();
+ return &factory.sDFPortDelayDef(openParen, keyword, *port, values,
+ expect(TokenKind::CloseParenthesis));
+}
+
+SDFInterconnectSyntax* Parser::parseSDFInterconnect() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ SmallVector ports;
+ ports.push_back(parseSDFPort());
+ ports.push_back(parseSDFPort());
+ auto values = parseSDFDelayValueList();
+ return &factory.sDFInterconnect(openParen, keyword, ports.copy(alloc), values,
+ expect(TokenKind::CloseParenthesis));
+}
+
+SDFNetDelaySyntax* Parser::parseSDFNetDelay() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ auto* net = parseSDFPort();
+ auto values = parseSDFDelayValueList();
+ return &factory.sDFNetDelay(openParen, keyword, *net, values,
+ expect(TokenKind::CloseParenthesis));
+}
+
+SDFDeviceSyntax* Parser::parseSDFDevice() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ SDFPortSyntax* port = nullptr;
+ if (peek().kind != TokenKind::OpenParenthesis)
+ port = parseSDFPort();
+ auto values = parseSDFDelayValueList();
+ return &factory.sDFDevice(openParen, keyword, port, values,
+ expect(TokenKind::CloseParenthesis));
+}
+
+SDFAbsIncDelayTypeSyntax* Parser::parseSDFAbsIncDelayType() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ SmallVector defs;
+ bool next = true;
+ while (next && peek().kind == TokenKind::OpenParenthesis) {
+ switch (peek(1).kind) {
+ case TokenKind::SDFIOPathKeyword:
+ defs.push_back(parseSDFIOPath());
+ break;
+ case TokenKind::SDFCondKeyword:
+ defs.push_back(parseSDFCond());
+ break;
+ case TokenKind::SDFCondElseKeyword:
+ defs.push_back(parseSDFCondElse());
+ break;
+ case TokenKind::SDFPortKeyword:
+ defs.push_back(parseSDFPortDelayDef());
+ break;
+ case TokenKind::SDFInterconnectKeyword:
+ defs.push_back(parseSDFInterconnect());
+ break;
+ case TokenKind::SDFNetDelayKeyword:
+ defs.push_back(parseSDFNetDelay());
+ break;
+ case TokenKind::SDFDeviceKeyword:
+ defs.push_back(parseSDFDevice());
+ break;
+ default:
+ next = false;
+ break;
+ }
+ }
+
+ if (defs.empty())
+ addDiag(diag::ExpectedSDFMember, peek().range()) << "delay definition"sv;
+ return &factory.sDFAbsIncDelayType(openParen, keyword, defs.copy(alloc),
+ expect(TokenKind::CloseParenthesis));
+}
+
+std::span Parser::parseSDFDelayTypes() {
+ SmallVector types;
+ bool next = true;
+ while (next && peek().kind == TokenKind::OpenParenthesis) {
+ auto lookahead = peek(1);
+ switch (lookahead.kind) {
+ case TokenKind::SDFPathPulseKeyword:
+ case TokenKind::SDFPathPulsePercentKeyword:
+ types.push_back(parseSDFPathPulse());
+ break;
+ case TokenKind::SDFAbsoluteKeyword:
+ case TokenKind::SDFIncrementKeyword:
+ types.push_back(parseSDFAbsIncDelayType());
+ break;
+ default:
+ next = false;
+ break;
+ }
+ }
+ return types.copy(alloc);
+}
+
+SDFDelaySpecSyntax* Parser::parseSDFDelaySpec() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ auto types = parseSDFDelayTypes();
+ if (types.empty())
+ addDiag(diag::ExpectedSDFMember, peek().range()) << "delay type"sv;
+ return &factory.sDFDelaySpec(openParen, keyword, types, expect(TokenKind::CloseParenthesis));
+}
+
+SDFPathConstraintSyntax* Parser::parseSDFPathConstraint() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ SDFNameSyntax* name = nullptr;
+ if (peek().kind == TokenKind::OpenParenthesis)
+ name = parseSDFName();
+
+ SmallVector ports;
+ while (peek().kind == TokenKind::Identifier)
+ ports.push_back(parseSDFPort());
+
+ if (ports.size() < 2)
+ addDiag(diag::InvalidSDFPathCnsPortNum, peek().range());
+
+ SmallVector values;
+ values.push_back(
+ parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true, /*isSign =*/true));
+ values.push_back(
+ parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true, /*isSign =*/true));
+ return &factory.sDFPathConstraint(openParen, keyword, name, ports.copy(alloc),
+ values.copy(alloc), expect(TokenKind::CloseParenthesis));
+}
+
+SDFPeriodConstraintSyntax* Parser::parseSDFPeriodConstraint() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ auto* port = parseSDFPort();
+ auto* value = parseSDFValue({TokenKind::OpenParenthesis, TokenKind::CloseParenthesis},
+ /*withParens =*/true,
+ /*isSign =*/false);
+ auto* exception = parseSDFException();
+ return &factory.sDFPeriodConstraint(openParen, keyword, *port, *value, exception,
+ expect(TokenKind::CloseParenthesis));
+}
+
+SDFConstraintPathSyntax* Parser::parseSDFConstraintPath() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ SmallVector ports;
+ ports.push_back(parseSDFPort());
+ ports.push_back(parseSDFPort());
+ return &factory.sDFConstraintPath(openParen, ports.copy(alloc),
+ expect(TokenKind::CloseParenthesis));
+}
+
+SDFSumDiffConstraintSyntax* Parser::parseSDFSumDiffConstraint(bool isDiff) {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ SmallVector pathes;
+ while (peek().kind == TokenKind::OpenParenthesis && peek(1).kind == TokenKind::Identifier &&
+ !(isDiff && pathes.size() == 2))
+ pathes.push_back(parseSDFConstraintPath());
+
+ if (pathes.size() < 2)
+ addDiag(diag::InvalidSDFSumDiffCnsPathesNum, peek().range());
+
+ SmallVector values;
+ bool isSign = !isDiff;
+ values.push_back(
+ parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true, /*isSign =*/isSign));
+ if (peek().kind != TokenKind::CloseParenthesis)
+ values.push_back(
+ parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true, /*isSign =*/isSign));
+ return &factory.sDFSumDiffConstraint(openParen, keyword, pathes.copy(alloc), values.copy(alloc),
+ expect(TokenKind::CloseParenthesis));
+}
+
+SDFSkewConstraintSyntax* Parser::parseSDFSkewConstraint() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ auto* portSpec = parseSDFPortSpec();
+ auto* value = parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true,
+ /*isSign =*/false);
+ return &factory.sDFSkewConstraint(openParen, keyword, *portSpec, *value,
+ expect(TokenKind::CloseParenthesis));
+}
+
+SDFTimingEnvConstructSyntax* Parser::parseSDFTimingEnvConstruct(bool isSlack) {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ SDFPortEdgeSyntax* edge = nullptr;
+ if (!isSlack && peek().kind == TokenKind::OpenParenthesis)
+ edge = parseSDFPortEdge();
+ auto* port = parseSDFPort();
+ SmallVector values;
+ values.push_back(
+ parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true, /*isSign =*/true));
+ values.push_back(
+ parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true, /*isSign =*/true));
+ values.push_back(
+ parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true, /*isSign =*/true));
+ values.push_back(
+ parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true, /*isSign =*/true));
+ ExpressionSyntax* period = nullptr;
+ if (isSlack && peek().kind != TokenKind::CloseParenthesis) {
+ period = &parseExpression();
+ if (period->kind != SyntaxKind::RealLiteralExpression &&
+ period->kind != SyntaxKind::IntegerLiteralExpression)
+ addDiag(diag::ExpectedRealLiteralExpression, period->sourceRange());
+ }
+ return &factory.sDFTimingEnvConstruct(openParen, keyword, edge, *port, values.copy(alloc),
+ period, expect(TokenKind::CloseParenthesis));
+}
+
+SDFEdgeSyntax* Parser::parseSDFEdge() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto edge = peek();
+ auto edgeText = edge.valueText();
+ if (edgeText != "posedge" && edgeText != "negedge")
+ addDiag(diag::InvalidSDFEdgeSpec, edge.range());
+ else
+ edge = consume();
+
+ static const std::set expectedExprKinds{SyntaxKind::IntegerLiteralExpression,
+ SyntaxKind::RealLiteralExpression,
+ SyntaxKind::UnaryMinusExpression};
+ SmallVector values;
+ auto* expr = &parseExpression();
+ if (!expectedExprKinds.contains(expr->kind))
+ addDiag(diag::InvalidSDFValueExpr, expr->sourceRange());
+ values.push_back(expr);
+
+ if (peek().kind != TokenKind::CloseParenthesis) {
+ expr = &parseExpression();
+ if (!expectedExprKinds.contains(expr->kind))
+ addDiag(diag::InvalidSDFValueExpr, expr->sourceRange());
+ values.push_back(expr);
+ }
+ return &factory.sDFEdge(openParen, edge, values.copy(alloc),
+ expect(TokenKind::CloseParenthesis));
+}
+
+SDFEdgePairSyntax* Parser::parseSDFEdgePair() {
+ SmallVector pair;
+ pair.push_back(parseSDFEdge());
+ pair.push_back(parseSDFEdge());
+ if (pair[0]->edge.valueText() == pair[1]->edge.valueText())
+ addDiag(diag::InvalidSDFEdgePair, pair[1]->edge.range())
+ << ((pair[1]->edge.valueText() == "posedge") ? "negedge"sv : "posedge"sv);
+ return &factory.sDFEdgePair(pair.copy(alloc));
+}
+
+SDFWaveformSyntax* Parser::parseSDFWaveform() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ auto* port = parseSDFPort();
+ auto* period = &parseExpression();
+ if (period->kind != SyntaxKind::RealLiteralExpression &&
+ period->kind != SyntaxKind::IntegerLiteralExpression)
+ addDiag(diag::ExpectedRealLiteralExpression, period->sourceRange());
+
+ SmallVector edgeList;
+ while (peek().kind == TokenKind::OpenParenthesis)
+ edgeList.push_back(parseSDFEdgePair());
+
+ if (edgeList.empty())
+ addDiag(diag::ExpectedSDFMember, peek().range()) << "edge pair"sv;
+
+ const auto* first = *edgeList.begin();
+ for (const auto* pair : edgeList) {
+ if (pair == first)
+ continue;
+
+ const auto edge = pair->edges[0]->edge;
+ if (edge.valueText() != first->edges[0]->edge.valueText())
+ addDiag(diag::InvalidSDFEdgePair, edge.range())
+ << ((edge.valueText() == "posedge") ? "negedge"sv : "posedge"sv);
+ }
+
+ return &factory.sDFWaveform(openParen, keyword, *port, *period, edgeList.copy(alloc),
+ expect(TokenKind::CloseParenthesis));
+}
+
+std::span Parser::parseSDFTimingEnvDefs() {
+ SmallVector defs;
+ bool next = true;
+ while (next && peek().kind == TokenKind::OpenParenthesis) {
+ auto lookahead = peek(1);
+ switch (lookahead.kind) {
+ case TokenKind::SDFPathConstraintKeyword:
+ defs.push_back(parseSDFPathConstraint());
+ break;
+ case TokenKind::SDFPeriodConstraintKeyword:
+ defs.push_back(parseSDFPeriodConstraint());
+ break;
+ case TokenKind::SDFSumKeyword:
+ defs.push_back(parseSDFSumDiffConstraint());
+ break;
+ case TokenKind::SDFDiffKeyword:
+ defs.push_back(parseSDFSumDiffConstraint(/*isDiff =*/true));
+ break;
+ case TokenKind::SDFSkewConstraintKeyword:
+ defs.push_back(parseSDFSkewConstraint());
+ break;
+ case TokenKind::SDFArrivalKeyword:
+ case TokenKind::SDFDepartureKeyword:
+ defs.push_back(parseSDFTimingEnvConstruct());
+ break;
+ case TokenKind::SDFSlackKeyword:
+ defs.push_back(parseSDFTimingEnvConstruct(/*isSlack =*/true));
+ break;
+ case TokenKind::SDFWaveformKeyword:
+ defs.push_back(parseSDFWaveform());
+ break;
+ default:
+ next = false;
+ break;
+ }
+ }
+ return defs.copy(alloc);
+}
+
+SDFPortTimingCheckSyntax* Parser::parseSDFPortTimingCheck() {
+ if (peek().kind == TokenKind::OpenParenthesis && peek(1).kind == TokenKind::SDFCondKeyword)
+ return parseSDFTimingCheckCondition(TokenKind::SDFCondKeyword);
+ return parseSDFPortSpec();
+}
+
+SDFTimingCheckConditionSyntax* Parser::parseSDFTimingCheckCondition(TokenKind keywordKind) {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = expect(keywordKind);
+ LiteralExpressionSyntax* name = nullptr;
+ if (peek().kind == TokenKind::StringLiteral)
+ name = &factory.literalExpression(SyntaxKind::StringLiteralExpression, consume());
+ auto* condition = &parseSubExpression(ExpressionOptions::SDFTimingCheckCondExpr, 0);
+ SDFPortSpecSyntax* portSpec = nullptr;
+ if (peek().kind != TokenKind::CloseParenthesis)
+ portSpec = parseSDFPortSpec();
+ return &factory.sDFTimingCheckCondition(openParen, keyword, name, *condition, portSpec,
+ expect(TokenKind::CloseParenthesis));
+}
+
+SDFTimingCheckDefSyntax* Parser::parseSDFTimingCheckDef(bool hasTwoPorts, bool hasTwoValues,
+ bool isSign, bool hasConds) {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ SmallVector ports;
+ bool hasPortConds = false;
+ if (hasConds) {
+ if (peek().kind == TokenKind::OpenParenthesis && peek(1).kind == TokenKind::SDFCondKeyword)
+ hasPortConds = true;
+ ports.push_back(parseSDFPortTimingCheck());
+ if (peek().kind == TokenKind::OpenParenthesis && peek(1).kind == TokenKind::SDFCondKeyword)
+ hasPortConds = true;
+ ports.push_back(parseSDFPortTimingCheck());
+ }
+ else {
+ ports.push_back(parseSDFPortSpec());
+ if (hasTwoPorts)
+ ports.push_back(parseSDFPortSpec());
+ }
+
+ SmallVector values;
+ values.push_back(
+ parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true, /*isSign =*/isSign));
+ if (hasTwoValues)
+ values.push_back(parseSDFValue({TokenKind::CloseParenthesis}, /*withParens =*/true,
+ /*isSign =*/isSign));
+ SmallVector conditions;
+ if (hasConds && !hasPortConds) {
+ if (peek().kind == TokenKind::OpenParenthesis && peek(1).kind == TokenKind::SDFSCondKeyword)
+ conditions.push_back(parseSDFTimingCheckCondition(TokenKind::SDFSCondKeyword));
+ if (peek().kind == TokenKind::OpenParenthesis && peek(1).kind == TokenKind::SDFCCondKeyword)
+ conditions.push_back(parseSDFTimingCheckCondition(TokenKind::SDFCCondKeyword));
+ }
+ return &factory.sDFTimingCheckDef(openParen, keyword, ports.copy(alloc), values.copy(alloc),
+ conditions.copy(alloc), expect(TokenKind::CloseParenthesis));
+}
+
+std::span Parser::parseSDFTimingCheckDefs() {
+ SmallVector defs;
+ bool next = true;
+ while (next && peek().kind == TokenKind::OpenParenthesis) {
+ auto lookahead = peek(1);
+ switch (lookahead.kind) {
+ case TokenKind::SDFSetupKeyword:
+ case TokenKind::SDFHoldKeyword:
+ case TokenKind::SDFRecoveryKeyword:
+ case TokenKind::SDFRemovalKeyword:
+ defs.push_back(parseSDFTimingCheckDef(/*hasTwoPorts =*/true,
+ /*hasTwoValues =*/false, /*isSign =*/false));
+ break;
+ case TokenKind::SDFSetupHoldKeyword:
+ case TokenKind::SDFRecremKeyword:
+ defs.push_back(parseSDFTimingCheckDef(/*hasTwoPorts =*/true, /*hasTwoValues =*/true,
+ /*isSign =*/true, /*hasConds =*/true));
+ break;
+ case TokenKind::SDFSkewKeyword:
+ defs.push_back(parseSDFTimingCheckDef(/*hasTwoPorts =*/true,
+ /*hasTwoValues =*/false, /*isSign =*/true));
+ break;
+ case TokenKind::SDFBidirectSkewKeyword:
+ defs.push_back(parseSDFTimingCheckDef(/*hasTwoPorts =*/true, /*hasTwoValues =*/true,
+ /*isSign =*/false));
+ break;
+ case TokenKind::SDFWidthKeyword:
+ case TokenKind::SDFPeriodKeyword:
+ defs.push_back(parseSDFTimingCheckDef(/*hasTwoPorts =*/false,
+ /*hasTwoValues =*/false, /*isSign =*/false));
+ break;
+ case TokenKind::SDFNochangeKeyword:
+ defs.push_back(parseSDFTimingCheckDef(/*hasTwoPorts =*/true, /*hasTwoValues =*/true,
+ /*isSign =*/true));
+ break;
+ default:
+ next = false;
+ break;
+ }
+ }
+ return defs.copy(alloc);
+}
+
+SDFTimingCheckSyntax* Parser::parseSDFTimingCheck() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ auto defs = parseSDFTimingCheckDefs();
+ if (defs.empty())
+ addDiag(diag::ExpectedSDFMember, peek().range()) << "timing check definition"sv;
+ return &factory.sDFTimingCheck(openParen, keyword, defs, expect(TokenKind::CloseParenthesis));
+}
+
+SDFTimingEnvSyntax* Parser::parseSDFTimingEnv() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ auto defs = parseSDFTimingEnvDefs();
+ if (defs.empty())
+ addDiag(diag::ExpectedSDFMember, peek().range()) << "timing environment definition"sv;
+ return &factory.sDFTimingEnv(openParen, keyword, defs, expect(TokenKind::CloseParenthesis));
+}
+
+SDFLabelDefSyntax* Parser::parseSDFLabelDef() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto* identifier = &factory.identifierName(expect(TokenKind::Identifier));
+ auto values = parseSDFDelayValueList();
+ return &factory.sDFLabelDef(openParen, *identifier, values,
+ expect(TokenKind::CloseParenthesis));
+}
+
+SDFLabelTypeSyntax* Parser::parseSDFLabelType() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ SmallVector defs;
+ while (peek().kind == TokenKind::OpenParenthesis) {
+ defs.push_back(parseSDFLabelDef());
+ }
+
+ if (defs.empty())
+ addDiag(diag::ExpectedSDFMember, peek().range()) << "label definition"sv;
+ return &factory.sDFLabelType(openParen, keyword, defs.copy(alloc),
+ expect(TokenKind::CloseParenthesis));
+}
+
+std::span Parser::parseSDFLabelTypes() {
+ SmallVector types;
+ bool next = true;
+ while (next && peek().kind == TokenKind::OpenParenthesis) {
+ auto lookahead = peek(1);
+ switch (lookahead.kind) {
+ case TokenKind::SDFAbsoluteKeyword:
+ case TokenKind::SDFIncrementKeyword:
+ types.push_back(parseSDFLabelType());
+ break;
+ default:
+ next = false;
+ break;
+ }
+ }
+ return types.copy(alloc);
+}
+
+SDFLabelSyntax* Parser::parseSDFLabel() {
+ auto openParen = expect(TokenKind::OpenParenthesis);
+ auto keyword = consume();
+ auto types = parseSDFLabelTypes();
+ if (types.empty())
+ addDiag(diag::ExpectedSDFMember, peek().range()) << "label type"sv;
+ return &factory.sDFLabel(openParen, keyword, types, expect(TokenKind::CloseParenthesis));
+}
+
+std::span Parser::parseSDFTimingSpecs() {
+ SmallVector timingSpecs;
+ bool next = true;
+ while (next && peek().kind == TokenKind::OpenParenthesis) {
+ auto lookahead = peek(1);
+ switch (lookahead.kind) {
+ case TokenKind::SDFDelayKeyword:
+ timingSpecs.push_back(parseSDFDelaySpec());
+ break;
+ case TokenKind::SDFTimingCheckKeyword:
+ timingSpecs.push_back(parseSDFTimingCheck());
+ break;
+ case TokenKind::SDFTimingEnvKeyword:
+ timingSpecs.push_back(parseSDFTimingEnv());
+ break;
+ case TokenKind::SDFLabelKeyword:
+ timingSpecs.push_back(parseSDFLabel());
+ break;
+ default:
+ next = false;
+ break;
+ }
+ }
+ return timingSpecs.copy(alloc);
+}
+
+std::span Parser::parseSDFCells() {
+ SmallVector cells;
+ while (peek().kind == TokenKind::OpenParenthesis && peek(1).kind == TokenKind::SDFCellKeyword) {
+ auto openParen = consume();
+ auto keyword = consume();
+ auto* type = parseSDFCharMember(TokenKind::SDFCellTypeKeyword, /*weak =*/false);
+ auto* instance = parseSDFCellInstance();
+ auto timingSpecs = parseSDFTimingSpecs();
+ cells.push_back(&factory.sDFCell(openParen, keyword, *type, *instance, timingSpecs,
+ expect(TokenKind::CloseParenthesis)));
+ }
+ return cells.copy(alloc);
+}
+
+SDFDelayFileSyntax* Parser::parseSDFDelayFile() {
+ if (peek().kind == TokenKind::OpenParenthesis &&
+ peek(1).kind == TokenKind::SDFDelayFileKeyword) {
+ auto openParen = consume();
+ auto keyword = consume();
+ SDFHeaderSyntax& header = parseSDFHeader();
+ auto cells = parseSDFCells();
+ if (cells.empty())
+ addDiag(diag::ExpectedSDFMember, peek().range()) << "cell"sv;
+ return &factory.sDFDelayFile(nullptr, openParen, keyword, header, cells,
+ expect(TokenKind::CloseParenthesis));
+ }
+ return nullptr;
+}
+
void Parser::checkMemberAllowed(const SyntaxNode& member, SyntaxKind parentKind) {
// If this is an empty member with a missing semicolon, it was some kind
// of error that has already been reported so don't pile on here.
@@ -3968,6 +4917,7 @@ void Parser::checkMemberAllowed(const SyntaxNode& member, SyntaxKind parentKind)
case SyntaxKind::ClockingDeclaration:
case SyntaxKind::SpecifyBlock:
case SyntaxKind::LibraryMap:
+ case SyntaxKind::SDFUnit:
return;
default:
SLANG_UNREACHABLE;
diff --git a/source/syntax/SyntaxFacts.cpp b/source/syntax/SyntaxFacts.cpp
index 1c36e637d..99deb1fe0 100644
--- a/source/syntax/SyntaxFacts.cpp
+++ b/source/syntax/SyntaxFacts.cpp
@@ -42,6 +42,26 @@ SyntaxKind SyntaxFacts::getUnaryPrefixExpression(TokenKind kind) {
}
}
+// clang-format off
+SyntaxKind SyntaxFacts::getSDFUnaryPrefixExpression(TokenKind kind) {
+ switch (kind) {
+ case TokenKind::Plus: return SyntaxKind::UnaryPlusExpression;
+ case TokenKind::Minus: return SyntaxKind::UnaryMinusExpression;
+ case TokenKind::And: return SyntaxKind::UnaryBitwiseAndExpression;
+ case TokenKind::TildeAnd: return SyntaxKind::UnaryBitwiseNandExpression;
+ case TokenKind::Or: return SyntaxKind::UnaryBitwiseOrExpression;
+ case TokenKind::TildeOr: return SyntaxKind::UnaryBitwiseNorExpression;
+ case TokenKind::Xor: return SyntaxKind::UnaryBitwiseXorExpression;
+ case TokenKind::XorTilde:
+ case TokenKind::TildeXor:
+ return SyntaxKind::UnaryBitwiseXnorExpression;
+ case TokenKind::Tilde: return SyntaxKind::UnaryBitwiseNotExpression;
+ case TokenKind::Exclamation: return SyntaxKind::UnaryLogicalNotExpression;
+ default:
+ return SyntaxKind::Unknown;
+ }
+}
+
SyntaxKind SyntaxFacts::getUnaryPostfixExpression(TokenKind kind) {
switch (kind) {
case TokenKind::DoublePlus: return SyntaxKind::PostincrementExpression;
@@ -63,6 +83,34 @@ SyntaxKind SyntaxFacts::getLiteralExpression(TokenKind kind) {
}
}
+SyntaxKind SyntaxFacts::getSDFBinaryExpression(TokenKind kind) {
+ switch (kind) {
+ case TokenKind::Plus: return SyntaxKind::AddExpression;
+ case TokenKind::Minus: return SyntaxKind::SubtractExpression;
+ case TokenKind::Star: return SyntaxKind::MultiplyExpression;
+ case TokenKind::Slash: return SyntaxKind::DivideExpression;
+ case TokenKind::Percent: return SyntaxKind::ModExpression;
+ case TokenKind::DoubleEquals: return SyntaxKind::EqualityExpression;
+ case TokenKind::ExclamationEquals: return SyntaxKind::InequalityExpression;
+ case TokenKind::TripleEquals: return SyntaxKind::CaseEqualityExpression;
+ case TokenKind::ExclamationDoubleEquals: return SyntaxKind::CaseInequalityExpression;
+ case TokenKind::DoubleAnd: return SyntaxKind::LogicalAndExpression;
+ case TokenKind::DoubleOr: return SyntaxKind::LogicalOrExpression;
+ case TokenKind::LessThan: return SyntaxKind::LessThanExpression;
+ case TokenKind::LessThanEquals: return SyntaxKind::LessThanEqualExpression;
+ case TokenKind::GreaterThan: return SyntaxKind::GreaterThanExpression;
+ case TokenKind::GreaterThanEquals: return SyntaxKind::GreaterThanEqualExpression;
+ case TokenKind::And: return SyntaxKind::BinaryAndExpression;
+ case TokenKind::Or: return SyntaxKind::BinaryOrExpression;
+ case TokenKind::Xor: return SyntaxKind::BinaryXorExpression;
+ case TokenKind::XorTilde: return SyntaxKind::BinaryXnorExpression;
+ case TokenKind::TildeXor: return SyntaxKind::BinaryXnorExpression;
+ case TokenKind::RightShift: return SyntaxKind::LogicalShiftRightExpression;
+ case TokenKind::LeftShift: return SyntaxKind::LogicalShiftLeftExpression;
+ default: return SyntaxKind::Unknown;
+ }
+}
+
SyntaxKind SyntaxFacts::getBinaryExpression(TokenKind kind) {
switch (kind) {
case TokenKind::Plus: return SyntaxKind::AddExpression;
diff --git a/source/syntax/SyntaxTree.cpp b/source/syntax/SyntaxTree.cpp
index 06707b911..a64a97b46 100644
--- a/source/syntax/SyntaxTree.cpp
+++ b/source/syntax/SyntaxTree.cpp
@@ -216,4 +216,44 @@ std::shared_ptr SyntaxTree::fromLibraryMapBuffer(const SourceBuffer&
parser.getMetadata(), preprocessor.getDefinedMacros(), options));
}
+std::shared_ptr SyntaxTree::fromSDFFile(std::string_view path,
+ SourceManager& sourceManager,
+ const Bag& options) {
+ auto buffer = sourceManager.readSource(path, /* library */ nullptr);
+ if (!buffer)
+ return nullptr;
+
+ return fromSDFBuffer(*buffer, sourceManager, options);
+}
+
+std::shared_ptr SyntaxTree::fromSDFText(std::string_view text,
+ SourceManager& sourceManager,
+ std::string_view name, std::string_view path,
+ const Bag& options) {
+ SourceBuffer buffer = sourceManager.assignText(path, text);
+ if (!buffer)
+ return nullptr;
+
+ if (!name.empty())
+ sourceManager.addLineDirective(SourceLocation(buffer.id, 0), 2, name, 0);
+
+ return fromSDFBuffer(buffer, sourceManager, options);
+}
+
+std::shared_ptr SyntaxTree::fromSDFBuffer(const SourceBuffer& buffer,
+ SourceManager& sourceManager,
+ const Bag& options) {
+ BumpAllocator alloc;
+ Diagnostics diagnostics;
+ Preprocessor preprocessor(sourceManager, alloc, diagnostics, options);
+ preprocessor.pushSource(buffer);
+
+ Parser parser(preprocessor, options);
+ auto& root = parser.parseSDFUnit();
+
+ return std::shared_ptr(
+ new SyntaxTree(&root, nullptr, sourceManager, std::move(alloc), std::move(diagnostics),
+ parser.getMetadata(), preprocessor.getDefinedMacros(), options));
+}
+
} // namespace slang::syntax
diff --git a/tests/unittests/CMakeLists.txt b/tests/unittests/CMakeLists.txt
index 2f3b8d1f2..838c6ab1f 100644
--- a/tests/unittests/CMakeLists.txt
+++ b/tests/unittests/CMakeLists.txt
@@ -30,6 +30,7 @@ add_executable(
parsing/PreprocessorTests.cpp
parsing/VisitorTests.cpp
parsing/StatementParsingTests.cpp
+ parsing/SDFParsingTests.cpp
util/CommandLineTests.cpp
util/IntervalMapTests.cpp
util/NumericTests.cpp
diff --git a/tests/unittests/Test.cpp b/tests/unittests/Test.cpp
index 7f2a86fd0..234dbaf57 100644
--- a/tests/unittests/Test.cpp
+++ b/tests/unittests/Test.cpp
@@ -176,6 +176,17 @@ const CompilationUnitSyntax& parseCompilationUnit(const std::string& text,
return parser.parseCompilationUnit();
}
+const SDFUnitSyntax& parseSDFUnit(const std::string& text) {
+ diagnostics.clear();
+
+ auto options = optionsFor(LanguageVersion::v1497_2001);
+ Preprocessor preprocessor(getSourceManager(), alloc, diagnostics, options);
+ preprocessor.pushSource(text);
+
+ Parser parser(preprocessor, options);
+ return parser.parseSDFUnit();
+}
+
const InstanceSymbol& evalModule(std::shared_ptr syntax, Compilation& compilation) {
compilation.addSyntaxTree(syntax);
const RootSymbol& root = compilation.getRoot();
diff --git a/tests/unittests/Test.h b/tests/unittests/Test.h
index 549d4f962..9d0ef2349 100644
--- a/tests/unittests/Test.h
+++ b/tests/unittests/Test.h
@@ -94,6 +94,7 @@ const StatementSyntax& parseStatement(const std::string& text);
const ExpressionSyntax& parseExpression(const std::string& text);
const CompilationUnitSyntax& parseCompilationUnit(
const std::string& text, LanguageVersion languageVersion = LanguageVersion::v1800_2017);
+const SDFUnitSyntax& parseSDFUnit(const std::string& text);
const InstanceSymbol& evalModule(std::shared_ptr syntax, Compilation& compilation);
class LogicExactlyEqualMatcher : public Catch::Matchers::MatcherGenericBase {
diff --git a/tests/unittests/parsing/SDFParsingTests.cpp b/tests/unittests/parsing/SDFParsingTests.cpp
new file mode 100644
index 000000000..007898c1c
--- /dev/null
+++ b/tests/unittests/parsing/SDFParsingTests.cpp
@@ -0,0 +1,549 @@
+// SPDX-FileCopyrightText: Michael Popoloski
+// SPDX-License-Identifier: MIT
+
+#include "Test.h"
+
+#include "slang/diagnostics/ParserDiags.h"
+#include "slang/parsing/Parser.h"
+#include "slang/parsing/Preprocessor.h"
+
+TEST_CASE("SDF file correct (unformatted and with comments") {
+ auto& text = R"(
+(DELAYFILE
+ (SDFVERSION "3.0")
+ (DESIGN "mux")
+ (DATE "Fri Apr 19 09:40:01 2019")
+ (VENDOR "Xilinx")
+ (PROGRAM "Xilinx SDF Writer")
+ (VERSION "P.20131013")
+ (DIVIDER /)
+ //(VOLTAGE 1.800::1.800)
+ (VOLTAGE 1:-1.0e-10:-1.2)
+ (PROCESS "1.000::1.000")
+ (TEMPERATURE 25.000::25.000)
+ (TIMESCALE 100.0 ps)
+ (CELL (CELLTYPE "X_BUF")
+ //(INSTANCE aa/aa.das/a)
+ (INSTANCE aa/aa/das/a)
+ (DELAY (PATHPULSE a y (13) (24))
+ (PATHPULSE b y (15) (21))
+ (PATHPULSEPERCENT a y (13) (24))
+ (PATHPULSEPERCENT b y (15) (21))
+ )
+ )
+ (CELL (CELLTYPE "X_BUF")
+ (INSTANCE a27_IBUF)
+ // (DELAY)
+ )
+ (CELL (CELLTYPE "X_BUF")
+ (INSTANCE a27_IBUF)
+ (DELAY
+ (ABSOLUTE
+ (IOPATH (posedge I) O/sadas/df (RETAIN (4:5:7) (5:6:9) (3)) ( 1500 )( 1500 ))
+ (COND ~a (IOPATH b y (0.37) (0.45) ) )
+ (COND aa/b/b/n /*? {fsafas} : {fdsafas}*/ (IOPATH b y (0.37) (0.45) ) )
+ (COND 0 (IOPATH b y (0.37) (0.45) ) )
+ (COND B2 (IOPATH b y (0.37) (0.45) ) )
+ (COND B0 (IOPATH b y (0.37) (0.45) ) )
+ (COND 1 B0 (IOPATH b y (0.37) (0.45) ) )
+ (COND aa/b/b/n ? {(sdsadsasdas) ? {fsafas, fasfas, 1 B0} : fdsafas} : {asds, asdsa} (IOPATH b y (0.37) (0.45) ) )
+ //(COND aa/b/b/n ? {sdsadsasdas ? {fsafas[2], fasfas, 1 B0} : fdsafas} : {asds, asdsa} (IOPATH b y (0.37) (0.45) ) )
+ //(COND aa/b/b/n ? {sdsadsa + sdas ? {fsafas, fasfas, 2b1} : fdsafas} : {asds, asdsa} (IOPATH b y (0.37) (0.45) ) )
+ //(COND "asadas" ~a/a/a/a/a[2:3] (IOPATH b y (0.37) (0.45) ) )
+ )
+ )
+ (TIMINGCHECK(
+ SETUP din (posedge clk) (3:4:5.5))
+ (HOLD din (posedge clk) (4:5.5:7))
+ (SETUPHOLD (COND reset din) (posedge clk) (12) (9.5))
+ (SETUPHOLD (COND ~reset din) (posedge clk) (12) (9.5))
+ //(SETUPHOLD (COND +reset din) (posedge clk) (12) (9.5))
+ //(SETUPHOLD (COND (reset) din) (posedge clk) (12) (9.5))
+ //(SETUPHOLD (COND reset[2] din) (posedge clk) (12) (9.5))
+ //(SETUPHOLD (posedge clk) (12) (9.5) (SCOND reset))
+ //(SETUPHOLD (posedge clk) (negedge clk1) (12) (9.5) (SCOND reset -> reset))
+ (SETUPHOLD (posedge clk) (negedge clk1) (12) (9.5) (SCOND reset == reset))
+ //(SETUPHOLD (posedge clk) (negedge clk1) (12) (9.5) (COND reset == reset))
+ (SETUPHOLD (posedge clk) (negedge clk1) (12) (9.5) (CCOND reset == reset))
+ (SETUPHOLD (posedge clk) (negedge clk1) (12) (9.5) (SCOND reset[4] == reset))
+ (SETUPHOLD (posedge clk) (negedge clk1) (12) (9.5) (SCOND reset == reset[4]))
+ (SETUPHOLD (posedge clk) (negedge clk1) (12) (9.5) (SCOND reset[3] == reset[4]))
+ (SETUPHOLD (posedge clk) (negedge clk1) (12) (9.5) (SCOND reset[4] == reset[4]))
+ //(SETUPHOLD (posedge clk) (negedge clk1) (12) (9.5) (SCOND reset[4] == reset[4:3]))
+ //(SETUPHOLD (posedge clk) (negedge clk1) (12) (9.5) (SCOND reset == reset[+4]))
+ //(SETUPHOLD (posedge clk) (negedge clk1) (12) (9.5) (SCOND reset == reset[-4]))
+ //(SETUPHOLD (posedge clk) (negedge clk1) (12) (9.5) (SCOND reset == reset[+4]))
+ //(SETUPHOLD (posedge clk) (negedge clk1) (12) (9.5) (SCOND reset == !reset))
+ //(SETUPHOLD (posedge clk) (negedge clk1) (12) (9.5) (SCOND !reset == reset))
+(SETUPHOLD din (posedge clk) (12) (9.5) (CCOND ~reset))
+(RECOVERY (posedge clearbar) (posedge clk) (11.5))
+(REMOVAL (posedge clearbar) (posedge clk) (6.3))
+(REMOVAL (posedge clearbar) (posedge clk) (6.3))
+(SKEW (posedge clk1) (posedge clk2) (6))
+(BIDIRECTSKEW (posedge clk1) (posedge clk2) (6) (7))
+(WIDTH (posedge clk) (30))
+(WIDTH (negedge clk) (16.5))
+(PERIOD (posedge clk) (46.5))
+(NOCHANGE (negedge write) addr (4.5) (3.5))
+ )
+ (LABEL
+ (ABSOLUTE
+ (TCLK_Q (7.54:12.14:19.78) (6.97:13.66:18.47))
+ (TCLK_QB (8.16:13.74:20.25) (7.63:14.83:21.42))
+ (TSETUP_D_CLK (3:4:5.6))
+ (THOLD_D_CLK (4:5.6:7))
+ ))
+ (TIMINGENV
+ (PATHCONSTRAINT I2/H01 I1/N01 (989:1269:1269) (989:1269:1269) )
+ //(PATHCONSTRAINT I2/H01 /*I3.N01*/ (904:1087:1087) (904:1087:1087) )
+ )
+ (TIMINGENV
+ (PATHCONSTRAINT y/z/i3 y/z/o2 a/b/o1 (25.1) (15.6))
+ (PERIODCONSTRAINT bufa/y (10)
+ (EXCEPTION (INSTANCE dff3) (INSTANCE ddasdas32) )
+ )
+ (SUM (m/n/o1 y/z/i1) (y/z/o2 a/b/i2) (67.3))
+ (DIFF (m/n/o1 y/z/i1) (y/z/o2 a/b/i2) (67.3))
+ (SKEWCONSTRAINT (posedge y) (7.5))
+ (ARRIVAL (posedge MCLK) D[15:0] (10) (40) (12) (45) )
+ (ARRIVAL (posedge MCLK) D[0] (10) (40) (12) (45) )
+ (DEPARTURE (posedge SCLK) A[15:0] (8) (20) (12) (34) )
+ (SLACK B (3) (3) (7) (7))
+ (WAVEFORM clka 15 (posedge 0 2) (negedge 5 7))
+ (WAVEFORM clkb 25
+ (negedge 0) (posedge 5)
+ (negedge 10) (posedge 15)
+ )
+ (WAVEFORM clkb 50
+ (negedge -10) (posedge 20)
+ )
+ //(WAVEFORM clka -15 (posedge 0 2) (negedge 5 7))
+ )
+ )
+
+ )
+ /*(DELAYFILE
+ (SDFVERSION "3.0")
+ (DESIGN "mux")
+ (DATE "Fri Apr 19 09:40:01 2019")
+ (VENDOR "Xilinx")
+ (PROGRAM "Xilinx SDF Writer")
+ (VERSION "P.20131013")
+ (DIVIDER /)
+ //(VOLTAGE 1.800::1.800)
+ (VOLTAGE 1:-1.0e-10:-1.2)
+ (PROCESS "1.000::1.000")
+ (TEMPERATURE 25.000::25.000)
+ (TIMESCALE 100.0 ps)
+ )*/
+)";
+
+ auto& unit = parseSDFUnit(text);
+ CHECK_DIAGNOSTICS_EMPTY;
+ REQUIRE(unit.kind == SyntaxKind::SDFUnit);
+ REQUIRE(unit.members.size() == 1);
+ REQUIRE(unit.members[0]->kind == SyntaxKind::SDFDelayFile);
+}
+
+TEST_CASE("correct SDF simple file") {
+ auto& text = R"(
+(DELAYFILE
+ (SDFVERSION "3.0")
+ (DESIGN "mux")
+ (DATE "Fri Apr 19 09:40:01 2019")
+ (VENDOR "Xilinx")
+ (PROGRAM "Xilinx SDF Writer")
+ (VERSION "P.20131013")
+ (DIVIDER /)
+ (VOLTAGE 1.800::1.800)
+ (PROCESS "1.000::1.000")
+ (TEMPERATURE 25.000::25.000)
+ (TIMESCALE 1ns)
+ (CELL (CELLTYPE "X_BUF")
+ (INSTANCE a27_IBUF)
+ (DELAY
+ (ABSOLUTE
+ (IOPATH I O ( 1500 )( 1500 ))
+ )
+ )
+ (DELAY
+ (ABSOLUTE
+ (INTERCONNECT wb_clk_i clkbuf_0_wb_clk_i.A (0.036:0.036:0.036) (0.035:0.035:0.035))
+ (INTERCONNECT wb_clk_i ANTENNA_1.DIODE (0.036:0.036:0.036) (0.035:0.035:0.035))
+ (INTERCONNECT wb_rst_i input10.A (0.000:0.000:0.000) (0.000:0.000:0.000))
+ (INTERCONNECT io_in[8] input9.A (0.000:0.000:0.000) (0.000:0.000:0.000))
+ (INTERCONNECT io_in[7] input8.A (0.000:0.000:0.000) (0.000:0.000:0.000))
+ (INTERCONNECT io_in[6] input7.A (0.000:0.000:0.000) (0.000:0.000:0.000))
+ (INTERCONNECT io_in[5] input6.A (0.000:0.000:0.000) (0.000:0.000:0.000))
+ (INTERCONNECT io_in[4] input5.A (0.000:0.000:0.000) (0.000:0.000:0.000))
+ (INTERCONNECT io_in[3] input4.A (0.000:0.000:0.000) (0.000:0.000:0.000))
+ (INTERCONNECT io_in[2] input3.A (0.000:0.000:0.000) (0.000:0.000:0.000))
+ (INTERCONNECT io_in[1] input2.A (0.000:0.000:0.000) (0.000:0.000:0.000))
+ (INTERCONNECT io_in[0] input1.A (0.000:0.000:0.000) (0.000:0.000:0.000))
+ (INTERCONNECT _135_O/Y _248_/A1 (0.000:0.000:0.000) (0.000:0.000:0.000))
+ (INTERCONNECT _135_O/Y _249_/A1 (0.000:0.000:0.000) (0.000:0.000:0.000))
+ (INTERCONNECT _136_O/Y _248_/B2 (0.000:0.000:0.000) (0.000:0.000:0.000))
+ (INTERCONNECT _136_O/Y _249_/B2 (0.000:0.000:0.000) (0.000:0.000:0.000))
+ (INTERCONNECT _298_.Q ANTENNA_hold54_A.DIODE (0.031:0.031:0.031) (0.030:0.030:0.030))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_XOR2")
+ (INSTANCE DSACK0_OBUF_D)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 0 )( 0 ))
+ (PORT I1 ( 0 )( 0 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_AND3")
+ (INSTANCE DSACK0_OBUF_D2_PT_0)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 2900 )( 2900 ))
+ (PORT I1 ( 2900 )( 2900 ))
+ (PORT I2 ( 2900 )( 2900 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ (IOPATH I2 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_BUF")
+ (INSTANCE cntr_0_Q)
+ (DELAY
+ (ABSOLUTE
+ (IOPATH I O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_OR2")
+ (INSTANCE cntr_0_tsimcreated_prld_Q)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 0 )( 0 ))
+ (PORT I1 ( 0 )( 0 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_FF")
+ (INSTANCE cntr_0_REG)
+ (DELAY
+ (ABSOLUTE
+ (IOPATH CLK O ( 400 )( 400 ))
+ (IOPATH SET O ( 6000 )( 6000 ))
+ (IOPATH RST O ( 6000 )( 6000 ))
+ )
+ )
+ (TIMINGCHECK
+ (SETUPHOLD (posedge I) (posedge CLK) (2300)(1400))
+ (SETUPHOLD (negedge I) (posedge CLK) (2300)(1400))
+ (SETUPHOLD (posedge CE) (posedge CLK) (0)(0))
+ (PERIOD (posedge CLK) (5600))
+ (WIDTH (posedge SET) (5000))
+ (WIDTH (posedge RST) (5000))
+ )
+ )
+ (CELL (CELLTYPE "X_XOR2")
+ (INSTANCE cntr_0_D)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 0 )( 0 ))
+ (PORT I1 ( 0 )( 0 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_AND2")
+ (INSTANCE cntr_0_RSTF)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 2900 )( 2900 ))
+ (PORT I1 ( 2900 )( 2900 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_BUF")
+ (INSTANCE cntr_1_Q)
+ (DELAY
+ (ABSOLUTE
+ (IOPATH I O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_XOR2")
+ (INSTANCE cntr_1_tsimcreated_xor_Q)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 0 )( 0 ))
+ (PORT I1 ( 1400 )( 1400 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_FF")
+ (INSTANCE cntr_1_REG)
+ (DELAY
+ (ABSOLUTE
+ (IOPATH CLK O ( 400 )( 400 ))
+ (IOPATH SET O ( 6000 )( 6000 ))
+ (IOPATH RST O ( 6000 )( 6000 ))
+ )
+ )
+ (TIMINGCHECK
+ (SETUPHOLD (posedge I) (posedge CLK) (2300)(1400))
+ (SETUPHOLD (negedge I) (posedge CLK) (2300)(1400))
+ (SETUPHOLD (posedge CE) (posedge CLK) (0)(0))
+ (PERIOD (posedge CLK) (5600))
+ (WIDTH (posedge SET) (5000))
+ (WIDTH (posedge RST) (5000))
+ )
+ )
+ (CELL (CELLTYPE "X_AND2")
+ (INSTANCE cntr_1_RSTF)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 2900 )( 2900 ))
+ (PORT I1 ( 2900 )( 2900 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_OR3")
+ (INSTANCE ETHRNT_OBUF_D2)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 0 )( 0 ))
+ (PORT I1 ( 0 )( 0 ))
+ (PORT I2 ( 0 )( 0 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ (IOPATH I2 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_XOR2")
+ (INSTANCE FLOPPY_OBUF_D)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 0 )( 0 ))
+ (PORT I1 ( 0 )( 0 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_AND7")
+ (INSTANCE FLOPPY_OBUF_D2_PT_0)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 1000 )( 1000 ))
+ (PORT I1 ( 1000 )( 1000 ))
+ (PORT I2 ( 1000 )( 1000 ))
+ (PORT I3 ( 1000 )( 1000 ))
+ (PORT I4 ( 1000 )( 1000 ))
+ (PORT I5 ( 1000 )( 1000 ))
+ (PORT I6 ( 1000 )( 1000 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ (IOPATH I2 O ( 0 )( 0 ))
+ (IOPATH I3 O ( 0 )( 0 ))
+ (IOPATH I4 O ( 0 )( 0 ))
+ (IOPATH I5 O ( 0 )( 0 ))
+ (IOPATH I6 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_OR3")
+ (INSTANCE FLOPPY_OBUF_D2)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 0 )( 0 ))
+ (PORT I1 ( 0 )( 0 ))
+ (PORT I2 ( 0 )( 0 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ (IOPATH I2 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_BUF")
+ (INSTANCE IDE_OBUF_Q)
+ (DELAY
+ (ABSOLUTE
+ (IOPATH I O ( 500 )( 500 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_XOR2")
+ (INSTANCE IDE_OBUF_D)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 0 )( 0 ))
+ (PORT I1 ( 0 )( 0 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_AND7")
+ (INSTANCE IDE_OBUF_D2_PT_0)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 1000 )( 1000 ))
+ (PORT I1 ( 1000 )( 1000 ))
+ (PORT I2 ( 1000 )( 1000 ))
+ (PORT I3 ( 1000 )( 1000 ))
+ (PORT I4 ( 1000 )( 1000 ))
+ (PORT I5 ( 1000 )( 1000 ))
+ (PORT I6 ( 1000 )( 1000 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ (IOPATH I2 O ( 0 )( 0 ))
+ (IOPATH I3 O ( 0 )( 0 ))
+ (IOPATH I4 O ( 0 )( 0 ))
+ (IOPATH I5 O ( 0 )( 0 ))
+ (IOPATH I6 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_OR3")
+ (INSTANCE IDE_OBUF_D2)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 0 )( 0 ))
+ (PORT I1 ( 0 )( 0 ))
+ (PORT I2 ( 0 )( 0 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ (IOPATH I2 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_AND2")
+ (INSTANCE READ_n_OBUF_D2)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 1000 )( 1000 ))
+ (PORT I1 ( 1000 )( 1000 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_XOR2")
+ (INSTANCE I_MEMW_OBUF_D)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 0 )( 0 ))
+ (PORT I1 ( 0 )( 0 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ )
+ )
+ )
+ (CELL (CELLTYPE "X_XOR2")
+ (INSTANCE cntr_2_cntr_2_RSTF_INT_D)
+ (DELAY
+ (ABSOLUTE
+ (PORT I0 ( 0 )( 0 ))
+ (PORT I1 ( 0 )( 0 ))
+ (IOPATH I0 O ( 0 )( 0 ))
+ (IOPATH I1 O ( 0 )( 0 ))
+ )
+ )
+ )
+)
+)";
+
+ auto& unit = parseSDFUnit(text);
+ CHECK_DIAGNOSTICS_EMPTY;
+ REQUIRE(unit.kind == SyntaxKind::SDFUnit);
+ REQUIRE(unit.members.size() == 1);
+ REQUIRE(unit.members[0]->kind == SyntaxKind::SDFDelayFile);
+}
+
+TEST_CASE("SDF file incorrect (invalid order of SDF file attributes/invalid number of SDFDelayFile "
+ "members/no specified cells)") {
+ auto& text = R"(
+(DELAYFILE
+ (SDFVERSION "3.0")
+ (DESIGN "mux")
+ (DATE "Fri Apr 19 09:40:01 2019")
+ (VENDOR "Xilinx")
+ (PROGRAM "Xilinx SDF Writer")
+ (VERSION "P.20131013")
+ (DIVIDER +)
+ (PROCESS "1.000::1.000")
+ (TEMPERATURE 25.000::25.000)
+ (VOLTAGE 1.800::1.800)
+ (TIMESCALE 1ns)
+)
+
+(DELAYFILE)
+)";
+ auto& unit = parseSDFUnit(text);
+
+ REQUIRE(diagnostics.size() == 6);
+ CHECK(diagnostics[0].code == diag::ExpectedSDFDivider);
+ CHECK(diagnostics[1].code == diag::ExpectedSDFMember);
+ CHECK(diagnostics[2].code == diag::UnexpectedEndDelim);
+ CHECK(diagnostics[3].code == diag::UnexpectedEndDelim);
+ CHECK(diagnostics[4].code == diag::ExpectedSDFMember);
+ CHECK(diagnostics[5].code == diag::MemberLimitViolation);
+}
+
+TEST_CASE("SDF file incorrect (invalid timing check values)") {
+ auto& text = R"(
+(DELAYFILE
+ (SDFVERSION "3.0")
+ (DESIGN "mux")
+ (DATE "Fri Apr 19 09:40:01 2019")
+ (VENDOR "Xilinx")
+ (PROGRAM "Xilinx SDF Writer")
+ (VERSION "P.20131013")
+ (VOLTAGE 1.800::1.800)
+ (PROCESS "1.000::1.000")
+ (TEMPERATURE 25.000::25.000)
+ (TIMESCALE 1ns)
+ (CELL
+ (CELLTYPE "sky130_fd_sc_hd__dfrtp_1")
+ (INSTANCE _279_)
+ (DELAY
+ (ABSOLUTE
+ (IOPATH CLK Q (0.341:0.341:0.341) (0.379:0.379:0.379))
+ (IOPATH RESET_B.d Q () (0.000:0.000:0.000))
+ )
+ )
+ (TIMINGCHECK
+ (REMOVAL (posedge RESET_B) (posedge CLK) (0.348:0.348:0.348))
+ (RECOVERY (posedge RESET_B) (posedge CLK) (-0.255:-0.255:-0.255))
+ (HOLD (posedge D) (posedge CLK) (-0.029:-0.030:-0.030))
+ (HOLD (negedge D) (posedge CLK) (-0.020:-0.020:-0.021))
+ (SETUP (posedge D) (posedge CLK) (0.054:0.054:0.055))
+ (SETUP (negedge D) (posedge CLK) (0.088:0.088:0.089))
+ )
+ )
+)
+)";
+ auto& unit = parseSDFUnit(text);
+
+ REQUIRE(diagnostics.size() == 7);
+ CHECK(diagnostics[0].code == diag::InvalidSDFValueExpr);
+ CHECK(diagnostics[1].code == diag::ExpectedToken);
+ CHECK(diagnostics[2].code == diag::UnexpectedEndDelim);
+ CHECK(diagnostics[3].code == diag::UnexpectedEndDelim);
+ CHECK(diagnostics[4].code == diag::UnexpectedEndDelim);
+ CHECK(diagnostics[5].code == diag::UnexpectedEndDelim);
+ CHECK(diagnostics[6].code == diag::UnexpectedEndDelim);
+}