svlog: distill module grammar
Attempt to boil down the glorious mix of syntax and semantics in the
official formal syntax to a more useful, semantics-free version that can
actually be parsed. Then enforce the semantics on top of the AST that
results.
+% SystemVerilog Grammar
+
This file contains a destilled version of the SystemVerilog grammar, which, as
it is layed out in the standard, is a mixture of both syntax and semantics.
@@ -45,3 +47,82 @@ assignment_pattern_expression_type assignment_pattern => assignment_pattern_ex
expression
expression ":" expression => range
expression ("+:"|"-:") expression => indexed_range
+
+
+# LIST OF PORTS
+According to the standard, the formal syntax for both ANSI and non-ANSI module
+ports is as follows:
+
+ // header
+ module_nonansi_header
+ := {attribute_instance} module_keyword [lifetime] module_identifier {package_import_declaration} [parameter_port_list] list_of_ports ";"
+ module_ansi_header
+ := {attribute_instance} module_keyword [lifetime] module_identifier {package_import_declaration} [parameter_port_list] [list_of_port_declarations] ";"
+
+ // non-ANSI style
+ list_of_ports
+ := "(" port {"," port} ")"
+ port
+ := [port_expression]
+ := "." port_identifier "(" [port_expression] ")"
+ port_expression
+ := port_reference
+ := "{" port_reference {"," port_reference} "}"
+ port_reference
+ := port_identifier constant_select
+
+ // ANSI style
+ list_of_port_declarations
+ := "(" [{attribute_instance} ansi_port_declaration {"," {attribute_instance} ansi_port_declaration}] ")"
+ ansi_port_declaration
+ := [net_port_header | interface_port_header] port_identifier {unpacked_dimension} ["=" constant_expression]
+ := [variable_port_header] port_identifier {variable_dimension} ["=" constant_expression]
+ := [port_direction] "." port_identifier "(" [expression] ")"
+ net_port_header
+ := [port_direction] net_port_type
+ variable_port_header
+ := [port_direction] variable_port_type
+ interface_port_header
+ := interface_identifier ["." modport_identifier]
+ := "interface" ["." modport_identifier]
+ port_direction
+ := "input" | "output" | "inout" | "ref"
+ net_port_type
+ := [net_type] data_type_or_implicit
+ variable_port_type
+ := data_type
+ := "var" data_type_or_implicit
+
+To maintain sanity, the ANSI and non-ANSI variants shall be collapsed into one,
+and the verification that a list of declarations is provided in the ANSI case
+shall be performed at a later stage, once the AST has been built.
+
+ // header
+ module_header
+ := {attribute_instance} module_keyword [lifetime] module_identifier {package_import_declaration} [parameter_port_list] [list_of_ports] ";"
+ list_of_ports
+ := "(" [{attribute_instance} port {"," {attribute_instance} port}] ")"
+ port
+ := [port_expression]
+ := [net_port_header | interface_port_header] port_identifier {unpacked_dimension} ["=" constant_expression]
+ := [variable_port_header] port_identifier {variable_dimension} ["=" constant_expression]
+ := [port_direction] "." port_identifier "(" [expression] ")"
+ port_expression
+ := port_reference
+ := "{" port_reference {"," port_reference} "}"
+ port_reference
+ := port_identifier constant_select
+ net_port_header
+ := [port_direction] net_port_type
+ variable_port_header
+ := [port_direction] variable_port_type
+ interface_port_header
+ := interface_identifier ["." modport_identifier]
+ := "interface" ["." modport_identifier]
+ port_direction
+ := "input" | "output" | "inout" | "ref"
+ net_port_type
+ := [net_type] data_type_or_implicit
+ variable_port_type
+ := data_type
+ := "var" data_type_or_implicit
