/* SB - General comments: 
        1) I tried to add attribute_instances where appropriate, to 
           match the usage in the 1364-2001 bnf 
        2) There were many productions where a recursive production 
           in the SV d3 bnf didn't make sense as recursive (for 
           example, statement has a production 'identifier : statement
           which would suggest that 'abc: def: foo = 3;' is 
           valid. 
        3) When in doubt about ambiguous bnf, I ran tests through 
           systemsim to check. This was to ensure that I didn't 
           introduce "enhancements" that were not intended in the 
           bnf. 
        4) The structure of the SV d3 bnf and 1364-2001 bnf are 
           radically different, so the mapping of the SV d3 bnf 
           may not be obvious 
*/ 

Annex A 
Formal syntax definition 
(normative) 
The formal syntax of Verilog HDL is described using Backus-Naur Form (BNF). 

A.1 Source text 


A.1.1 Library source text 


library_text ::= { library_descriptions } 
/* SB do we need '[unit] [precision]' here? I would think that 
   it's only important for source_textnot library_text */ 

library_descriptions ::= 
          library_declaration 
        | include_statement 
        | config_declaration 
library_declaration ::= 
          library library_identifier file_path_spec [ { , file_path_spec } ] 
          [ -incdir file_path_spec [ { , file_path_spec } ] ] ; 
file_path_spec ::= file_path 
include_statement ::= include <file_path_spec; 

A.1.2 Configuration source text 


config_declaration ::= 
          config config_identifier ; 
          design_statement 
          {config_rule_statement
          endconfig 
design_statement ::= design { [library_identifier.]cell_identifier } ; 
config_rule_statement ::= 
          default_clause liblist_clause 
        | inst_clause liblist_clause 
        | inst_clause use_clause 
        | cell_clause liblist_clause 
        | cell_clause use_clause 
default_clause ::= default 
inst_clause ::= instance inst_name 
inst_name ::= topmodule_identifier{.instance_identifier
cell_clause ::= cell [ library_identifier.]cell_identifier 
liblist_clause ::= liblist [{library_identifier}] 
use_clause ::= use [library_identifier.]cell_identifier[:config] 

A.1.3 Module and primitive source text 


source_text ::=  [unit] [precision { description } 
description ::= 
          module_declaration 
        | udp_declaration 
        | module_root_item 
        | statement 
/* SB - restricting $root involves description
         module_root_item allows declaration of everything (except parameter, 
                          localparam, specparam) 
         statement allows you to do anything... 
*/ 

module_declaration ::= 
          { attribute_instance } module_keyword module_identifier [ parameter_port_list ] 
                  [ list_of_ports ] ;  [unit] [precision { module_item } 
                  endmodule 
        | { attribute_instance } module_keyword module_identifier [ parameter_port_list ] 
                  [ list_of_port_declarations ] ;  [unit] [precision 
                  { non_port_module_item } 
                  endmodule 
module_keyword ::= module | macromodule 
interface_declaration ::= 
          { attribute_instance } interface interface_identifier [ parameter_port_list ] 
                  [ list_of_ports ] ; [unit] [precision] { interface_item } 
                  endinterface [: interface_identifier
        | { attribute_instance } interface interface_identifier [ parameter_port_list ] 
                [ list_of_port_declarations ] ; [unit] [precision
                { non_port_interface_item } 
                endinterface [: interface_identifier
unit ::= [ timeunit [ time_literal ] ; ] 
precision ::= [ timeprecision [ time_literal ] ; ] 

A.1.4 Module parameters and ports 


parameter_port_list ::= # ( parameter_declaration { , parameter_declaration } ) 
list_of_ports ::= ( port { , port } ) 
list_of_port_declarations ::= 
          ( port_declaration { , port_declaration } ) 
        | ( ) 
port ::= 
          [ port_expression ] 
        | . port_identifier ( [ port_expression ] ) 
port_expression ::= 
          port_reference 
        | { port_reference { , port_reference } } 
port_reference ::= 
          port_identifier 
        | port_identifier [ constant_expression ] 
        | port_identifier [ range_expression ] 
port_declaration ::= 
          { attribute_instance } inout_declaration 
        | { attribute_instance } input_declaration 
        | { attribute_instance } output_declaration 
        | { attribute_instance } interface_port_declaration 

A.1.5 Module items 


module_common_item ::= 
          { attribute_instance } module_or_generate_item_declaration 
        | { attribute_instance } interface_instantiation 

module_item ::= 
        port_declaration ; 
        | non_port_module_item 

module_or_generate_item ::= 
          { attribute_instance } module_or_generate_item_declaration 
        |
 { attribute_instance } parameter_override 
        | { attribute_instance } continuous_assign 
        | { attribute_instance } gate_instantiation 
        | { attribute_instance } udp_instantiation 
        | { attribute_instance } module_instantiation 
        | { attribute_instance } initial_construct 
        | { attribute_instance } always_construct 
/* SB - the three following statment types were not referenced by 
        other productions in the SV d3, so I put them here since 
        this seemed to be the most logical place */ 
        | { attribute_instance } combinational_statement 
        | { attribute_instance } latch_statement 
        | { attribute_instance } ff_statement 
        | module_common_item 
module_root_item ::= 
          { attribute_instance } module_instantiation 
        | interface_declaration 
        | module_common_item 

module_or_generate_item_declaration ::= 
          net_declaration 
        | reg_declaration 
        | integer_declaration 
        | real_declaration 
        | time_declaration 
        | realtime_declaration 

        | data_declaration 

        | event_declaration 
        | genvar_declaration 
        | task_declaration 
        | function_declaration 
 
non_port_module_item ::= 
          { attribute_instance } generated_module_instantiation 
        | { attribute_instance } local_parameter_declaration 
        | { attribute_instance } module_or_generate_item 
        | { attribute_instance } parameter_declaration 
        | { attribute_instance } specify_block 
        | { attribute_instance } specparam_declaration 
        | module_declaration 

parameter_override ::= defparam list_of_param_assignments ; 

A.1.6 Interface items 


interface_or_generate_item ::= 
          { attribute_instance } continuous_assign 
        | { attribute_instance } initial_construct 
        | { attribute_instance } always_construct 
/* SB - the three following statment types were not referenced by 
        other productions in the SV d3, so I put them here since 
        this seemed to be the most logical place */ 
        | { attribute_instance } combinational_statement 
        | { attribute_instance } latch_statement 
        | { attribute_instance } ff_statement 
        | { attribute_instance } local_parameter_declaration 
        | { attribute_instance } parameter_declaration 
        | module_common_item 
        | { attribute_instance } modport_declaration 
interface_item ::= 
          port_declaration 
        | non_port_interface_item 
non_port_interface_item ::= 
          { attribute_instance } generated_interface_instantiation 
        | { attribute_instance } local_parameter_declaration 
        | { attribute_instance } parameter_declaration 
        | { attribute_instance } specparam_declaration 
        | interface_or_generate_item 
        | interface_declaration 

A.2 Declarations 


A.2.1 Declaration types 


A.2.1.1 Module parameter declarations 


local_parameter_declaration ::= 
          localparam [ signing ] packed_dimension } [ range ] list_of_param_assignments ; 
        | localparam integer list_of_param_assignments ; 
        | localparam real list_of_param_assignments ; 
        | localparam realtime list_of_param_assignments ; 
        | localparam time list_of_param_assignments ; 

        | localparam data_type list_of_param_assignments ; 

parameter_declaration ::= 
          parameter [ signing ] packed_dimension } [ range ] list_of_param_assignments ; 
        | parameter integer list_of_param_assignments ; 
        | parameter real list_of_param_assignments ; 
        | parameter realtime list_of_param_assignments ; 
        | parameter time list_of_param_assignments ; 

        | parameter data_type list_of_param_assignments ; 
        | parameter type list_of_type_assignments ; 

specparam_declaration ::= 
specparam [ range ] list_of_specparam_assignments ; 
/* SB - The SV draft3 bnf would enhance the specparam to be identical 
        to the localparam. If that is what we want to do, then we should 
        remove all the special stuff for specparam_assignments and 
        make specparam the same as localparam */ 

A.2.1.2 Port declarations 


inout_declaration ::= inout [ net_type ] [ signed ] [ range ] list_of_port_identifiers 

inout_declaration ::= inout [ port_type ] list_of_port_identifiers 
        | inout . port_identifier ( [ port_expression ] ) 
 
/* SB - I don't particularly care for this... I remember deliberately 
        disallowing this style in V2K1. It allows jumpered ports (i.e. 
        "inout .m1(x), inout .m2(x)") that would normally not be 
        allowed with the ansi style because port identifiers would otherwise 
        have to be unique... if that's desirable, then this is a 
        also a desireable enhancement. 
 
        NOTE: Limitations (same as Draft3 BNF) are that: 
          1) Can't specify a list of ports this way 
             Example of unsupported:    module foo(inout .m1(x), .m2(y)); 
          2) Can't specify type, signedness or size 
             Example of unsupported:    module foo(inout signed [31:0] .m1(x)); 
*/ 

input_declaration ::= input [ net_type ] [ signed ] [ range ] 
                  list_of_port_identifiers 

input_declaration ::= input [ port_type ] list_of_port_identifiers 
        | input . port_identifier ( [ port_expression ] ) 

output_declaration ::= 
          output [ net_type ] [ signed ] [ range ] 
                  list_of_port_identifiers 
        | output [ reg ] [ signed ] [ range ] 
                  list_of_port_identifiers 
        | output reg [ signed ] [ range ] 
                  list_of_variable_port_identifiers 
        | output [ output_variable_type ] 
                  list_of_port_identifiers 
        | output output_variable_type 
                  list_of_variable_port_identifiers 

          output [ port_type ] list_of_port_identifiers 
        | output . port_identifier ( [ port_expression ] ) 
        | output data_type list_of_variable_port_identifiers 
interface_port_declaration ::= 
          interface list_of_interface_identifiers 
        | interface . modport_identifier list_of_interface_identifiers 
        | identifier list_of_interface_identifiers 
        | identifier . modport_identifier list_of_interface_identifiers 

A.2.1.3 Type declarations 


block_data_declaration ::= 
          block_variable_declaration 
        | constant_declaration 
        | type_declaration 
        | state_declaration 
constant_declaration ::= const data_type const_assignment ; 
/* SB - I changed constant_declaration to use const_assignment 
        with only allows a constant expression on the rhs. It 
        seemed like a typo to allow any expressionand systemsim 
        agreed. 
*/ 
data_declaration ::= 
          variable_declaration 
        | constant_declaration 
        | type_declaration 
        | state_declaration 

event_declaration ::= event list_of_event_identifiers ; 
genvar_declaration ::= genvar list_of_genvar_identifiers ; 
integer_declaration ::= integer list_of_variable_identifiers ; 

net_declaration ::= 
          net_type [ signing ] 
                  [ delay3 ] list_of_net_identifiers ; 
        | net_type [ drive_strength ] [ signing ] 
                  [ delay3 ] list_of_net_decl_assignments ; 
        | net_type [ vectored | scalared ] [ signing ] 
                  packed_dimension } range [ delay3 ] list_of_net_identifiers ; 
        | net_type [ drive_strength ] [ vectored | scalared ] [ signing ] 
                  packed_dimension } range [ delay3 ] list_of_net_decl_assignments ; 
        | trireg [ charge_strength ] [ signing ] 
                  [ delay3 ] list_of_net_identifiers ; 
        | trireg [ drive_strength ] [ signing ] 
                  [ delay3 ] list_of_net_decl_assignments ; 
        | trireg [ charge_strength ] [ vectored | scalared ] [ signing ] 
                  packed_dimension } range [ delay3 ] list_of_net_identifiers ; 
        | trireg [ drive_strength ] [ vectored | scalared ] [ signing ] 
                  packed_dimension } range [ delay3 ] list_of_net_decl_assignments ; 
real_declaration ::= real list_of_real_identifiers ; 
realtime_declaration ::= realtime list_of_real_identifiers ; 
reg_declaration ::= reg [ signing
 ] [ range ] 
                  list_of_variable_identifiers ; 
state_declaration ::= state { state_list } state_identifier [ delay_or_event_control ] ; 
state_list ::= and_states | or_states 
and_states ::= state and state { and state } 
or_states ::= state , state { , state } 
state ::= [ { state_list } ] state_identifier 

time_declaration ::= time list_of_variable_identifiers ; 

type_declaration ::= 
          typedef data_type type_declaration_identifier ; 
        | typedef interface_identifier { [ constant_expression ] } . type_identifier 
                type_declaration_identifier ; 
block_variable_declaration ::= 
          [ lifetime ] data_type list_of_variable_identifiers ; 
        | lifetime data_type list_of_variable_decl_assignments ; 
/* SB - The SV d3 bnf didn't appear to allow variable declarations 
        in seq or par blocks, but it did specify 
        variable_declaration as part of a data_declaration, that 
        allows the user to optionally specify the lifetime and 
        make initial assignments
        Since the declarations used in functions and tasks are 
        identical to those in blocks, it suggested that these 
        enhancements were intended for the seq/par blocks as 
        well. Since decl assignments were deliberately disallowed in 
        1364-2001, I checked the systemsim implementation and 
        found that decl assignments are only allowed when the 
        lifetime is explicitly specified. Thus I added that 
        restriction into the production above. 
*/ 
variable_declaration ::= 
          [ lifetime ] data_type list_of_variable_identifiers_or_assignments ; 
lifetime ::= static | automatic 

A.2.2 Declaration data types 


A.2.2.1 Net and variable types 


output_variable_type ::= integer | time 
real_type ::= 
          real_identifier [ = constant_expression ] 
        | real_identifier dimension { dimension } 
variable_type ::= 
          variable_identifier [ = constant_expression ] 
        | variable_identifier dimension { dimension } 

/* SB - moved variable_type to variable_declaration_identifier 
data_type ::= 
          integer_vector_type [ signing ] { packed_dimension } [ range ] 
        | integer_atom_type [ signing ] { packed_dimension } 
        | type_declaration_identifier 
        | non_integer_type 
        | struct { { struct_union_member } } 
        | union { { struct_union_member } } 
        | enum { enum_identifier [ = constant_expression ] 
                { , enum_identifier [ = constant_expression ] } } 
/* SB - I made the enum require at least one identifier because 
        it seemed to be a accidental to allow 'enum {} myenum;' 
        and systemsim agreed with me. 
*/ 
        | void 
integer_atom_type ::= byte | char | shortint | int | longint | integer 
integer_type ::= integer_vector_type | integer_atom_type 
integer_vector_type ::= bit | logic | reg 

net_type ::= 
          supply0 | supply1 
        | tri           | triand  | trior | tri0 | tri1 
        | wire          | wand   | wor 
non_integer_type ::= time | shortreal | real | realtime | $built-in 
/* SB  - realtime was missing from SV d3 bnf.  I've added 
         it for completenes */ 
port_type ::= 
          data_type { packed_dimension } 
        | net_type [ signing ] { packed_dimension } 
        | trireg [ signing ] { packed_dimension } 
        | event 
/* SB - IMPLICIT PORT TYPE 
        following was not in SV d3, but is part of 1364-2001 as 
        explicit parts of input, output and inout. I've extended 
        the single dimension of 1364-2001 to support SV array passing */ 
        | [ signing ] { packed_dimension } range 
signing ::= [ signed ] | [ unsigned ] 
simple_type ::= integer_type | non_integer_type | type_identifier 
struct_union_member ::= data_type list_of_variable_identifiers_or_assignments ; 

A.2.2.2 Strengths 


drive_strength ::= 
          ( strength0 , strength1 ) 
        | ( strength1 , strength0 ) 
        | ( strength0 , highz1 ) 
        | ( strength1 , highz0 ) 
        | ( highz0 , strength1 ) 
        | ( highz1 , strength0 ) 
strength0 ::= supply0 | strong0 | pull0 | weak0 
strength1 ::= supply1 | strong1 | pull1 | weak1 
charge_strength ::= ( small ) | ( medium ) | ( large ) 

A.2.2.3 Delays 


delay3 ::= # delay_value | # ( delay_value [ , delay_value [ , delay_value ] ] ) 
delay2 ::= # delay_value | # ( delay_value [ , delay_value ] ) 
delay_value ::= 
          unsigned_number 
        | parameter_identifier 
        | specparam_identifier 
        | mintypmax_expression 

A.2.3 Declaration lists 


list_of_event_identifiers ::= event_identifier [ unpacked_dimension { unpacked_dimension }] 
                { , event_identifier [ unpacked_dimension { unpacked_dimension }] } 
list_of_genvar_identifiers ::= genvar_identifier { , genvar_identifier } 
list_of_interface_identifiers ::= interface_identifier { unpacked_dimension } 
                { , interface_identifier  { unpacked_dimension } } 

list_of_net_decl_assignments ::= net_decl_assignment { , net_decl_assignment } 
list_of_net_identifiers ::= net_identifier [ unpacked_dimension { unpacked_dimension }] 
                { , net_identifier [ unpacked_dimension { unpacked_dimension }] } 
list_of_param_assignments ::= param_assignment { , param_assignment } 
list_of_port_identifiers ::= port_identifier unpacked_dimension } 
                { , port_identifier unpacked_dimension } } 
list_of_udp_port_identifiers ::= port_identifier { , port_identifier } 
list_of_real_identifiers ::= real_type { , real_type } 

list_of_specparam_assignments ::= specparam_assignment { , specparam_assignment } 
list_of_type_assignments ::= type_assignment { , type_assignment } 

list_of_variable_decl_assignments ::= variable_decl_assign_identifier { , variable_decl_assign_identifier } 
list_of_variable_identifiers ::= variable_declaration_identifier { , variable_declaration_identifier } 
list_of_variable_identifiers_or_assignments ::= 
          list_of_variable_decl_assignments 
        | list_of_variable_identifiers 
list_of_variable_port_identifiers ::= port_identifier unpacked_dimension } [ = constant_expression ] 
                             { , port_identifier unpacked_dimension } [ = constant_expression ] } 

A.2.4 Declaration assignments 


const_assignment ::= const_identifier = constant_expression 

net_decl_assignment ::= net_identifier = expression 
param_assignment ::= parameter_identifier = constant_expression 
specparam_assignment ::= 
          specparam_identifier = constant_mintypmax_expression 
        | pulse_control_specparam 
type_assignment ::= type_identifier = data_type 

pulse_control_specparam ::= 
          PATHPULSE$ = ( reject_limit_value [ , error_limit_value ] ) ; 
        | PATHPULSE$specify_input_terminal_descriptor$specify_output_terminal_descriptor 
                                = ( reject_limit_value [ , error_limit_value ] ) ; 
error_limit_value ::= limit_value 
reject_limit_value ::= limit_value 
limit_value ::= constant_mintypmax_expression 

A.2.5 Declaration ranges 


unpacked_dimension ::= [ dimension_constant_expression : dimension_constant_expression ] 
packed_dimension ::= [ dimension_constant_expression : dimension_constant_expression ] 

range ::= [ msb_constant_expression : lsb_constant_expression ] 

A.2.6 Function declarations 


function_declaration ::= 
            function [ automatic ] [ signing ] [ range_or_type ] 
                  [ interface_identifier . ] function_identifier ; 
            function_item_declaration { function_item_declaration } 
            function_statement } 
            endfunction : function_identifier ] 
           | function [ automatic ] [ signing ] [ range_or_type ] 
                  [ interface_identifier . ] function_identifier ( function_port_list ) ; 
            block_item_declaration { block_item_declaration } 
            function_statement } 
            endfunction : function_identifier ] 
/* SB - The SV d3 bnf had 'endfunction [: identifier : ]' which 
        didn't make sense, looked like a typo, and gave a syntax 
        error in systemsim. I removed the extra ':' 
*/ 

function_item_declaration ::= 
          block_item_declaration 
        | { attribute_instance } input_declaration ; 
        | { attribute_instance } output_declaration ; 
        | { attribute_instance } inout_declaration ; 
function_port_item ::= 
          { attribute_instance } input_declaration 
        | { attribute_instance } output_declaration 
        | { attribute_instance } inout_declaration 
function_port_list ::= function_port_item { , function_port_item } 

function_port_list ::= { attribute_instance } input_declaration { , { attribute_instance } input_declaration } 
range_or_type ::= range | integer | real | realtime | time 

function_prototype ::= function data_type ( list_of_function_proto_formals ) 
named_function_proto ::= function data_type function_identifier ( list_of_function_proto_formals ) 
list_of_function_proto_formals ::= 
          [ { attribute_instance } function_proto_formal { , 
                { attribute_instance } function_proto_formal } ] 
function_proto_formal ::= 
          input data_type [ variable_declaration_identifier ] 
        | inout data_type [ variable_declaration_identifier ] 
        | output data_type [ variable_declaration_identifier ] 
        | variable_declaration_identifier 
/* SB - Protype functions are also in the SV d3 bnf, but aren't referred to 
        by any of the other productions. They appear to be part of modports 
        but are not adequately described in the text or tied to the modport 
        production. */ 
range_or_type ::= 
          { packed_dimension } range 
        | data_type 

A.2.7 Task declarations 


task_declaration ::= 
            task [ automatic ] [ interface_identifier . ] task_identifier ; 
            { task_item_declaration } 
            statement } 
            endtask : task_identifier ] 
          | task [ automatic ] [ interface_identifier . ] task_identifier ( task_port_list ) ; 
            { block_item_declaration } 
            statement } 
            endtask : task_identifier ] 
task_item_declaration ::= 
          block_item_declaration 
        | { attribute_instance } input_declaration ; 
        | { attribute_instance } output_declaration ; 
        | { attribute_instance } inout_declaration ; 
task_port_list ::= task_port_item { , task_port_item } 
task_port_item ::= 
          { attribute_instance } port ] input_declaration 
        | { attribute_instance } port ] output_declaration 
        | { attribute_instance } port ] inout_declaration 
        | { attribute_instance } port event list_of_port_identifiers 
/* SB - What's with the 'port'? It's not described in the text. 
        We should either remove it from the bnf or add it to the 
        text. 
/* SB - Protype tasks are also in the SV d3 bnf, but aren't referred to 
        by any of the other productions. They appear to be part of modports 
        but are not adequately described in the text or tied to the modport 
        production. */ 
task_prototype ::= 
          task ( { attribute_instance } task_proto_formal 
                { , { attribute_instance } task_proto_formal } ) 
named_task_proto ::= task task_identifier ( task_proto_formal { , task_proto_formal } ) 
task_proto_formal ::= 
          [ port ] input data_type [ variable_declaration_identifier ] 
        | [ port ] inout data_type [ variable_declaration_identifier ] 
        | [ port ] output data_type [ variable_declaration_identifier ] 
        | port event variable 

A.2.8 Block item declarations 


block_item_declaration ::= 
          { attribute_instance } block_reg_declaration 

          { attribute_instance } block_data_declaration 

        | { attribute_instance } event_declaration 
        | { attribute_instance } integer_declaration 

        | { attribute_instance } local_parameter_declaration 
        | { attribute_instance } parameter_declaration 
        | { attribute_instance } real_declaration 
        | { attribute_instance } realtime_declaration 
        | { attribute_instance } time_declaration 
block_reg_declaration ::= reg [ signing
 ] [ range ] 
                  list_of_block_variable_identifiers ; 
list_of_block_variable_identifiers ::= 
                  block_variable_type { , block_variable_type } 
block_variable_type ::= 
          variable_identifier 
        | variable_identifier dimension { dimension } 

A.2.9 Interface declarations 


modport_declaration ::= modport list_of_modport_identifiers ; 
list_of_modport_identifiers ::= modport_item { , modport_item } 
modport_item ::= modport_identifier ( modport_port { , modport_port } ) 
modport_port ::= 
          input  [port_typeport_identifier 
        | output [port_typeport_identifier 
        | inout  [port_typeport_identifier 
        | interface_identifier . port_identifier 

A.3 Primitive instances 


A.3.1 Primitive instantiation and instances 


gate_instantiation ::= 
          cmos_switchtype [delay3
                  cmos_switch_instance { , cmos_switch_instance } ; 
        | enable_gatetype [drive_strength] [delay3
                  enable_gate_instance { , enable_gate_instance } ; 
        | mos_switchtype [delay3
                  mos_switch_instance { , mos_switch_instance } ; 
        | n_input_gatetype [drive_strength] [delay2
                  n_input_gate_instance { , n_input_gate_instance } ; 
        | n_output_gatetype [drive_strength] [delay2
                  n_output_gate_instance { , n_output_gate_instance } ; 
        | pass_en_switchtype [delay2
                  pass_enable_switch_instance { , pass_enable_switch_instance } ; 
        | pass_switchtype 
                  pass_switch_instance { , pass_switch_instance } ; 
        | pulldown [pulldown_strength
                  pull_gate_instance { , pull_gate_instance } ; 
        | pullup [pullup_strength
                  pull_gate_instance { , pull_gate_instance } ; 
cmos_switch_instance ::= [ name_of_gate_instance ] ( output_terminal , input_terminal , 
                ncontrol_terminal , pcontrol_terminal ) 
enable_gate_instance ::= [ name_of_gate_instance ] ( output_terminal , input_terminal , enable_terminal ) 
mos_switch_instance ::= [ name_of_gate_instance ] ( output_terminal , input_terminal , enable_terminal ) 
n_input_gate_instance ::= [ name_of_gate_instance ] ( output_terminal , input_terminal { , input_terminal } ) 
n_output_gate_instance ::= [ name_of_gate_instance ] ( output_terminal { , output_terminal } , input_terminal ) 
pass_switch_instance ::= [ name_of_gate_instance ] ( inout_terminal , inout_terminal ) 
pass_enable_switch_instance ::= [ name_of_gate_instance ] ( inout_terminal , inout_terminal , enable_terminal ) 
pull_gate_instance ::= [ name_of_gate_instance ] ( output_terminal ) 
/* SB - This makes arrays of instances multi-dimentional, which 
        is not mentioned in the text of the standard. 
        I added the multi-dimension requirement here even though 
        the SV d3 bnf did not require the identifier before 
        specification of the ranges because it seemed to be an 
        unintended ambiguity in the bnf and gave a syntax error 
        in systemsim. */ 

name_of_gate_instance ::= gate_instance_identifier [ range ] range } 

A.3.2 Primitive strengths 


pulldown_strength ::= 
          ( strength0 , strength1 ) 
        | ( strength1 , strength0 ) 
        | ( strength0 ) 
pullup_strength ::= 
          ( strength0 , strength1 ) 
        | ( strength1 , strength0 ) 
        | ( strength1 ) 

A.3.3 Primitive terminals 


enable_terminal ::= expression 
inout_terminal ::= net_lvalue 
input_terminal ::= expression 
ncontrol_terminal ::= expression 
output_terminal ::= net_lvalue 
pcontrol_terminal ::= expression 

A.3.4 Primitive gate and switch types 


cmos_switchtype ::= cmos | rcmos 
enable_gatetype ::= bufif0 | bufif1 | notif0 | notif1 
mos_switchtype ::= nmos | pmos | rnmos | rpmos 
n_input_gatetype ::= and | nand | or | nor | xor | xnor 
n_output_gatetype ::= buf | not 
pass_en_switchtype ::= tranif0 | tranif1 | rtranif1 | rtranif0 
pass_switchtype ::= tran | rtran 

A.4 Module, interface and generated instantiation 


A.4.1 Instantiation 


A.4.1.1 Module instantiation 


module_instantiation ::= 
          module_identifier [ parameter_value_assignment ] 
              module_instance { , module_instance } ; 
parameter_value_assignment ::= # ( list_of_parameter_assignments ) 
list_of_parameter_assignments ::= 
        ordered_parameter_assignment { , ordered_parameter_assignment } | 
        named_parameter_assignment   { , named_parameter_assignment } 
ordered_parameter_assignment ::= expression 
named_parameter_assignment ::= . parameter_identifier ( [ expression ] ) 
module_instance ::= name_of_instance ( [ list_of_port_connections ] ) 
/* SB - This makes arrays of instances multi-dimentional, which 
        is not mentioned in the text of the standard. 
        I added the multi-dimension requirement here even though 
        the SV d3 bnf did not require the identifier before 
        specification of the ranges because it seemed to be an 
        unintended ambiguity in the bnf and gave a syntax error 
        in systemsim.  */ 

name_of_instance ::= module_instance_identifier range } [ range ] 
list_of_port_connections ::= 
          ordered_port_connection { , ordered_port_connection } 
        | named_port_connection { , named_port_connection } 
ordered_port_connection ::= { attribute_instance } [ expression ] 
named_port_connection ::= { attribute_instance } .port_identifier ( [ expression ] ) 

A.4.1.2 Interface instantiation 


interface_instantiation ::= 
          interface_identifier [ parameter_value_assignment ] 
              module_instance { , module_instance } ; 

A.4.2 Generated instantiation 


A.4.2.1 Generated module instantiation 


generated_module_instantiation ::= generate { generate_module_item } endgenerate 
generate_module_item_or_null ::= generate_module_item | ; 
generate_module_item ::= 
          generate_module_conditional_statement 
        | generate_module_case_statement 
        | generate_module_loop_statement 
        | generate_module_block 
        | module_or_generate_item 
generate_module_conditional_statement ::= 
          if ( constant_expression ) generate_module_item_or_null 
          [ else generate_module_item_or_null ] 
generate_module_case_statement ::= 
          case ( constant_expression ) 
          genvar_module_case_item { genvar_module_case_item } 
          endcase 
genvar_module_case_item ::= 
          constant_expression  { , constant_expression } : generate_module_item_or_null 
          | default [ : ] generate_module_item_or_null 
generate_module_loop_statement ::= 
          for ( genvar_decl_assignment ; constant_expression ; genvar_assignment ) 
          begin : generate_block_identifier { generate_module_item
 } end 
          generate_module_named_block 

genvar_assignment ::= 
          genvar_identifier = constant_expression 
        | genvar_identifier assignment_operator constant_expression 
        | bump_operator genvar_identifier 
        | genvar_identifier bump_operator 
/* SB - I only added the bump_operator to the 
        genvar_assignment. The SV d3 bnf added all unary 
        operators, but as the bump_operator is the only unary 
        operator that modifies the value of the genvar variable, 
        it is the only one that makes sense here. */ 
genvar_decl_assignment ::= 
          [ genvar ] genvar_identifier = constant_expression 
generate_module_named_block ::= 
          begin : generate_block_identifier { generate_module_item } end 
        | generate_block_identifier : generate_module_block 

generate_module_block ::= 
          begin [ : generate_block_identifier ]  { generate_module_item } end 
/* SB - Shouldn't generate_block have an optional identifier 
        after the end, just like other begin/end pairs??? */ 

A.4.2.2 Generated interface instantiation 


generated_interface_instantiation ::= generate { generate_interface_item } endgenerate 
generate_interface_item_or_null ::= generate_interface_item | ; 
generate_interface_item ::= 
          generate_interface_conditional_statement 
        | generate_interface_case_statement 
        | generate_interface_loop_statement 
        | generate_interface_block 
        | interface_or_generate_item 
generate_interface_conditional_statement ::= 
          if ( constant_expression ) generate_interface_item_or_null  [ else generate_interface_item_or_null ] 
generate_interface_case_statement ::=  case ( constant_expression ) 
                        genvar_interface_case_item { genvar_interface_case_item } endcase 
genvar_interface_case_item ::=  constant_expression  { , constant_expression } : 
                        generate_interface_item_or_null  | default [ : ] generate_interface_item_or_null 
generate_interface_loop_statement ::= 
          for ( genvar_decl_assignment ; constant_expression ; genvar_assignment ) 
          generate_interface_named_block 
begin : generate_block_identifier { generate_interface_item } end 
generate_interface_named_block ::= 
          begin : generate_block_identifier { generate_module_item } end 
        | generate_block_identifier : generate_module_block 
generate_interface_block ::= begin [ : generate_block_identifier ]  { generate_interface_item } end 

A.5 UDP declaration and instantiation 


A.5.1 UDP declaration 


udp_declaration ::= 
           { attribute_instance }  primitive udp_identifier ( udp_port_list ) ; 
            udp_port_declaration { udp_port_declaration } 
            udp_body 
            endprimitive 
          | { attribute_instance } primitive udp_identifier ( udp_declaration_port_list ) ; 
            udp_body 
            endprimitive 

A.5.2 UDP ports 


udp_port_list ::= output_port_identifier , input_port_identifier { , input_port_identifier } 
udp_declaration_port_list ::= 
        udp_output_declaration , udp_input_declaration { , udp_input_declaration } 
udp_port_declaration ::= 
          udp_output_declaration ; 
        | udp_input_declaration ; 
        | udp_reg_declaration ; 
udp_output_declaration ::= 
          { attribute_instance } output port_identifier 
        | { attribute_instance } output reg port_identifier [ = constant_expression ] 
udp_input_declaration ::= { attribute_instance } input list_of_udp_port_identifiers 
udp_reg_declaration ::= { attribute_instance } reg variable_identifier 

A.5.3 UDP body 


udp_body ::= combinational_body | sequential_body 
combinational_body ::= table combinational_entry { combinational_entry } endtable 
combinational_entry ::= level_input_list : output_symbol ; 
sequential_body ::= [ udp_initial_statement ] table sequential_entry { sequential_entry } endtable 
udp_initial_statement ::= initial output_port_identifier = init_val ; 
init_val ::= 1'b0 | 1'b1 | 1'bx | 1'bX | 1'B0 | 1'B1 | 1'Bx | 1'BX | 1 | 0 
sequential_entry ::= seq_input_list : current_state : next_state ; 
seq_input_list ::= level_input_list | edge_input_list 
level_input_list ::= level_symbol { level_symbol } 
edge_input_list ::= { level_symbol } edge_indicator { level_symbol } 
edge_indicator ::= ( level_symbol level_symbol ) | edge_symbol 
current_state ::= level_symbol 
next_state ::= output_symbol | - 
output_symbol ::= 0 | 1 | x | X 
level_symbol ::= 0 | 1 | x | X | ? | b | B 
edge_symbol ::= r | R | f | F | p | P | n | N | * 
 

A.5.4 UDP instantiation 


udp_instantiation ::= udp_identifier [ drive_strength ] [ delay2 ] 
                                                 udp_instance { , udp_instance } ; 
/* SB - This makes arrays of instances multi-dimentional, which 
        is not mentioned in the text of the standard. 
        I added the multi-dimension requirement here even though 
        the SV d3 bnf did not require the identifier before 
        specification of the ranges because it seemed to be an 
        unintended ambiguity in the bnf and gave a syntax error 
        in systemsim.  */ 

udp_instance ::= [ name_of_udp_instance ] range } output_terminal , input_terminal 
                                                { , input_terminal } ) 
name_of_udp_instance ::= udp_instance_identifier [ range ] 

A.6 Behavioral statements 


A.6.1 Continuous assignment statements 


continuous_assign ::= assign [ drive_strength ] [ delay3 ] list_of_net_assignments ; 
list_of_net_assignments ::= net_assignment { , net_assignment } 
net_assignment ::= net_lvalue = expression 

A.6.2 Procedural blocks and assignments 


initial_construct ::= initial statement 
always_construct ::= always statement 
combinational_statement ::= always_comb statement 
latch_statement ::= always_latch statement 
ff_statement ::= always_ff statement 

blocking_assignment ::= 
          variable_lvalue = delay_or_event_control expression 
        | operator_assignment 
operator_assignment ::= variable_lvalue assignment_operator expression 
assignment_operator ::= = | *= | /= | %= | += | - = | <<= | >>= | &= | ^= | |= 

nonblocking_assignment ::= variable_lvalue <= [ delay_or_event_control ] expression 
/* SB - SV d3 bnf allowed 'force a, b = 1;' but that looked 
        incorrect and since systemsim agreed with me, I didn't 
        add it to procedural_continuous_assignments. */ 

procedural_continuous_assignments ::= 
          assign variable_assignment 
        | deassign variable_lvalue 
        | force variable_assignment 
        | force net_assignment 
        | release variable_lvalue 
        | release net_lvalue 
function_blocking_assignment ::= variable_lvalue = expression 
function_statement_or_null ::= 
          function_statement 
        | { attribute_instance } ; 

A.6.3 Parallel and sequential blocks 


function_seq_block ::= begin [ : block_identifier 
                { block_item_declaration } ] { function_statement } end 
variable_assignment ::= variable_lvalue = expression 
par_block ::= fork [ : block_identifier ] 
                { block_item_declaration }  
                { statement } join : block_identifier ] 
seq_block ::= begin [ : block_identifier ] 
                { block_item_declaration }  
                { statement } end : block_identifier ] 

A.6.4 Statements 


statement ::= 
          [ block_identifier : ] statement_item 

statement_item ::= 
          { attribute_instance } blocking_assignment ; 
        | { attribute_instance } case_statement 
        | { attribute_instance } conditional_statement 
        | { attribute_instance } transition_statement 
        | { attribute_instance } transition_to_state statement_or_null 
        | { attribute_instance } bump_expression 
/* SB - SV d3 bnf allowed expression as a statement, but the only 
        expression that makes sense as a statement is the bump 
        operator. Since systemsim agrees with me, I have only 
        allowed the pre and post bump operators here */ 

        | { attribute_instance } disable_statement 
        | { attribute_instance } event_trigger 
        | { attribute_instance } loop_statement 
        | { attribute_instance } jump_statement 

        | { attribute_instance } nonblocking_assignment ; 
        | { attribute_instance } par_block 
        | { attribute_instance } procedural_continuous_assignments ; 
        | { attribute_instance } procedural_timing_control_statement 
        | { attribute_instance } seq_block 
        | { attribute_instance } system_task_enable 
        | { attribute_instance } task_enable 
        | { attribute_instance } wait_statement 
        | { attribute_instance } process statement 

statement_or_null ::= 
          statement 
        | { attribute_instance } ; 
function_statement ::= 
          [ block_identifier : ] function_statement_item 

function_statement_item ::= 
          { attribute_instance } function_blocking_assignment ; 
        | { attribute_instance } function_case_statement 
        | { attribute_instance } function_conditional_statement 
        | { attribute_instance } function_transition_statement 
        | { attribute_instance } transition_to_state function_statement_or_null 
        | { attribute_instance } bump_expression 
/* SB - SV d3 bnf allowed expression as a statement, but the only 
        expression that makes sense as a statement is the bump 
        operator. Since systemsim agrees with me, I have only 
        allowed the pre and post bump operators here */ 

        | { attribute_instance } function_loop_statement 
        | { attribute_instance } jump_statement 

        | { attribute_instance } function_seq_block 
        | { attribute_instance } disable_statement 
        | { attribute_instance } system_task_enable 

A.6.5 Timing control statements 


delay_control ::= 
          # delay_value 
        | # ( mintypmax_expression ) 
delay_or_event_control ::= 
          delay_control 
        | event_control 
        | repeat ( expression ) event_control 
disable_statement ::= 
          disable hierarchical_task_identifier ; 
        | disable hierarchical_block_identifier ; 
event_control ::= 
          @ event_identifier 
        | @ ( event_expression ) 
        | @* 
        | @ (*) 
event_trigger ::= 
          -> hierarchical_event_identifier ; 
event_expression ::= 
          expression [ iff expression ] 
        | hierarchical_identifier [ iff expression ] 
        | edge ] expression [ iff expression ] 
        | negedge expression 

        | event_expression or event_expression 
        | event_expression , event_expression 
edge ::= posedge | negedge | changed 
/* SB - The SV d3 bnf adds all of these to the jump statement, but 
        since there are limitations on where these are allowed as 
        a statement, we should consider specifying every place 
        they are allowed (much like the way the 1364-2001 bnf 
        separates the statements allowed in functions from the 
        rest of the functions. */ 
jump_statement ::= 
          return [ expression ] ; 
        | break ; 
        | continue ; 

procedural_timing_control_statement ::= 
          delay_or_event_control statement_or_null 
wait_statement ::= 
          wait ( expression ) statement_or_null 

A.6.6 Conditional statements 


conditional_statement ::= 
          unique_priority ] if ( expression ) 
                  statement_or_null [ else statement_or_null ] 
        | if_else_if_statement 
if_else_if_statement ::= 
          unique_priority ] if ( expression ) statement_or_null 
         { else unique_priority ] if ( expression ) statement_or_null } 
         [ else statement_or_null ] 
function_conditional_statement ::= 
          unique_priority ] if ( expression ) function_statement_or_null 
                  [ else function_statement_or_null ] 
        | function_if_else_if_statement 
function_if_else_if_statement ::= 
          unique_priority ] if ( expression ) function_statement_or_null 
         { else unique_priority ] if ( expression ) function_statement_or_null } 
          [ else function_statement_or_null ] 
unique_priority ::= unique | priority 

A.6.7 Case statements 


case_statement ::= 
          unique_priority ] case ( expression ) 
                  case_item { case_item } endcase 
        | unique_priority ] casez ( expression ) 
                  case_item { case_item } endcase 
        | unique_priority ] casex ( expression ) 
                  case_item { case_item } endcase 
case_item ::= 
          expression { , expression } : statement_or_null 
        | default [ : ] statement_or_null 
function_case_statement ::= 
          unique_priority ] case ( expression ) 
                  function_case_item { function_case_item } endcase 
        | unique_priority ] casez ( expression ) 
                  function_case_item { function_case_item } endcase 
        | unique_priority ] casex ( expression ) 
                  function_case_item { function_case_item } endcase 
function_case_item ::= 
          expression { , expression } : function_statement_or_null 
        | default [ : ] function_statement_or_null 

A.6.8 Transition statements 


transition_statement ::= 
          transition ( hierarchical_identifier ) 
          transition_item { transition_item } endtransition 
function_transition_statement ::= 
          transition ( hierarchical_identifier ) 
          function_transition_item { function_transition_item } endtransition 
transition_item ::= 
          list_of_state_conditions : statement_or_null 
        | default [ : ] statement_or_null 
function_transition_item ::= 
          list_of_state_conditions : function_statement_or_null 
        | default [ : ] function_statement_or_null 
list_of_state_conditions ::= state_condition { , state_condition } 
state_condition ::= state_identifier { and state_identifier } 
transition_to_state ::= 
          ->> hierarchical_identifier . state_identifier 
        | ->> hierarchical_identifier . ( state_condition ) 
        | [ transition_identifier ] ->> state_condition 
/* SB - I mapped machine_name to hierarchical_identifier as that 
        seemed to be the intention. */ 

A.6.9 Looping statements 


function_loop_statement ::= 
          forever function_statement 
        | repeat ( expression ) function_statement_or_null 
        | while ( expression ) function_statement_or_null 
        | for ( variable_decl_or_assignment ;  expression ; variable_assignment ) 
                  function_statement_or_null 
        | do function_statement while ( expression ) 

loop_statement ::= 
          forever statement 
        | repeat ( expression ) statement_or_null 
        | while ( expression ) statement_or_null 
        | for ( variable_decl_or_assignment ;  expression ; variable_assignment ) 
                  statement_or_null 
        | do statement while ( expression ) 
variable_decl_or_assignment ::= 
          data_type list_of_variable_identifiers_or_assignments ; 
        | variable_assignment 

A.6.10 Task enable statements 


system_task_enable ::= system_task_identifier [ ( expression { , expression } ) ] ; 
task_enable ::= hierarchical_task_identifier [ ( expression { , expression } ) ] ; 

A.7 Specify section 


A.7.1 Specify block declaration 


specify_block ::= specify { specify_item } endspecify 
specify_item ::= 
          specparam_declaration 
        | pulsestyle_declaration 
        | showcancelled_declaration 
        | path_declaration 
        | system_timing_check 
pulsestyle_declaration ::= 
          pulsestyle_onevent list_of_path_outputs ; 
       |  pulsestyle_ondetect list_of_path_outputs ; 
showcancelled_declaration ::= 
          showcancelled list_of_path_outputs ; 
        | noshowcancelled list_of_path_outputs ; 

A.7.2 Specify path declarations 


path_declaration ::= 
          simple_path_declaration ; 
        | edge_sensitive_path_declaration ; 
        | state_dependent_path_declaration ; 
simple_path_declaration ::= 
          parallel_path_description = path_delay_value 
        | full_path_description = path_delay_value 
parallel_path_description ::= 
        ( specify_input_terminal_descriptor [ polarity_operator ] => specify_output_terminal_descriptor ) 
full_path_description ::= 
        ( list_of_path_inputs [ polarity_operator ] *> list_of_path_outputs ) 
list_of_path_inputs ::= 
          specify_input_terminal_descriptor { , specify_input_terminal_descriptor } 
list_of_path_outputs ::= 
          specify_output_terminal_descriptor { , specify_output_terminal_descriptor } 

A.7.3 Specify block terminals 


specify_input_terminal_descriptor ::= 
          input_identifier 
        | input_identifier [ constant_expression ] 
        | input_identifier [ range_expression ] 
specify_output_terminal_descriptor ::= 
          output_identifier 
        | output_identifier [ constant_expression ] 
        | output_identifier [ range_expression ] 
input_identifier ::= input_port_identifier | inout_port_identifier 
output_identifier ::= output_port_identifier | inout_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 ::= 
          t_path_delay_expression 
        | trise_path_delay_expression , tfall_path_delay_expression 
        | trise_path_delay_expression , tfall_path_delay_expression , tz_path_delay_expression 
        | t01_path_delay_expression , t10_path_delay_expression , t0z_path_delay_expression , 
          tz1_path_delay_expression , t1z_path_delay_expression , tz0_path_delay_expression 
        | t01_path_delay_expression , t10_path_delay_expression , t0z_path_delay_expression , 
          tz1_path_delay_expression , t1z_path_delay_expression , tz0_path_delay_expression 
          t0x_path_delay_expression , tx1_path_delay_expression , t1x_path_delay_expression , 
          tx0_path_delay_expression , txz_path_delay_expression , tzx_path_delay_expression 
t_path_delay_expression ::= path_delay_expression 
trise_path_delay_expression ::= path_delay_expression 
tfall_path_delay_expression ::= path_delay_expression 
tz_path_delay_expression ::= path_delay_expression 
t01_path_delay_expression ::= path_delay_expression 
t10_path_delay_expression ::= path_delay_expression 
t0z_path_delay_expression ::= path_delay_expression 
tz1_path_delay_expression ::= path_delay_expression 
t1z_path_delay_expression ::= path_delay_expression 
tz0_path_delay_expression ::= path_delay_expression 
t0x_path_delay_expression ::= path_delay_expression 
tx1_path_delay_expression ::= path_delay_expression 
t1x_path_delay_expression ::= path_delay_expression 
tx0_path_delay_expression ::= path_delay_expression 
txz_path_delay_expression ::= path_delay_expression 
tzx_path_delay_expression ::= path_delay_expression 
path_delay_expression ::= constant_mintypmax_expression 
edge_sensitive_path_declaration ::= 
          parallel_edge_sensitive_path_description = path_delay_value 
        | full_edge_sensitive_path_description = path_delay_value 
parallel_edge_sensitive_path_description ::= 
          ( [ edge_identifier ] specify_input_terminal_descriptor => 
                specify_output_terminal_descriptor [ polarity_operator ] : data_source_expression ) 
full_edge_sensitive_path_description ::= 
          ( [ edge_identifier ] list_of_path_inputs *> 
                list_of_path_outputs [ polarity_operator ] : data_source_expression ) 
data_source_expression ::= expression 
edge_identifier ::= posedge | negedge 
state_dependent_path_declaration ::= 
          if ( module_path_expression ) simple_path_declaration 
        | if ( module_path_expression ) edge_sensitive_path_declaration 
        | ifnone simple_path_declaration 
polarity_operator ::= + | - 

A.7.5 System timing checks 


A.7.5.1 System timing check commands 


system_timing_check ::= 
          $setup_timing_check 
        | $hold _timing_check 
        | $setuphold_timing_check 
        | $recovery_timing_check 
        | $removal_timing_check 
        | $recrem_timing_check 
        | $skew_timing_check 
        | $timeskew_timing_check 
        | $fullskew_timing_check 
        | $period_timing_check 
        | $width_timing_check 
        | $nochange_timing_check 
$setup_timing_check ::= 
          $setup ( data_event , reference_event , timing_check_limit [ , [ notify_reg ] ] ) ; 
$hold _timing_check ::= 
          $hold ( reference_event , data_event , timing_check_limit [ , [ notify_reg ] ] ) ; 
$setuphold_timing_check ::= 
          $setuphold ( reference_event , data_event , timing_check_limit ,  timing_check_limit 
                                        [ , [ notify_reg ] [ , [ stamptime_condition ] [ , [ checktime_condition ] 
                                        [ , [ delayed_reference ] [ , [ delayed_data ] ] ] ] ] ] ) ; 
$recovery_timing_check ::= 
          $recovery ( reference_event , data_event , timing_check_limit [ , [ notify_reg ] ] ) ; 
$removal_timing_check ::= 
          $removal ( reference_event , data_event , timing_check_limit [ , [ notify_reg ] ] ) ; 
$recrem_timing_check ::= 
          $recrem ( reference_event , data_event , timing_check_limit , timing_check_limit 
                                        [ , [ notify_reg ] [ , [ stamptime_condition ] [ , [ checktime_condition ] 
                                        [ , [ delayed_reference ] [ , [ delayed_data ] ] ] ] ] ] ) ; 
$skew_timing_check ::= 
          $skew ( reference_event , data_event , timing_check_limit [ , [ notify_reg ] ] ) ; 
$timeskew_timing_check ::= 
          $timeskew ( reference_event , data_event , timing_check_limit 
                                        [ , [ notify_reg ] [ , [ event_based_flag ] [ , [ remain_active_flag ] ] ] ] ) ; 
$fullskew_timing_check ::= 
          $fullskew ( reference_event , data_event , timing_check_limit , timing_check_limit 
                                        [ , [ notify_reg ] [ , [ event_based_flag ] [ , [ remain_active_flag ] ] ] ] ) ; 
$period_timing_check ::= 
          $period ( controlled_reference_event , timing_check_limit [ , [ notify_reg ] ] ) ; 
$width_timing_check ::= 
          $width ( controlled_reference_event , timing_check_limit , 
                                        threshold [ , [ notify_reg ] ] ) ; 
$nochange_timing_check ::= 
          $nochange ( reference_event , data_event , start_edge_offset , 
                                        end_edge_offset [ , [ notify_reg ] ] ) ; 

A.7.5.2 System timing check command arguments 


checktime_condition ::= mintypmax_expression 
controlled_reference_event ::= controlled_timing_check_event 
data_event ::= timing_check_event 
delayed_data ::= 
          terminal_identifier 
        | terminal_identifier [ constant_mintypmax_expression ] 
delayed_reference ::= 
          terminal_identifier 
        | terminal_identifier [ constant_mintypmax_expression ] 
end_edge_offset ::= mintypmax_expression 
event_based_flag ::= constant_expression 
notify_reg ::= variable_identifier 
reference_event ::= timing_check_event 
remain_active_flag ::= constant_mintypmax_expression 
stamptime_condition ::= mintypmax_expression 
start_edge_offset ::= mintypmax_expression 
threshold ::=constant_expression 
timing_check_limit ::= expression 

A.7.5.3 System timing check event definitions 


timing_check_event ::= 
          [timing_check_event_controlspecify_terminal_descriptor [ &&& timing_check_condition ] 
controlled_timing_check_event ::= 
          timing_check_event_control specify_terminal_descriptor [ &&& timing_check_condition ] 
timing_check_event_control ::= 
          posedge 
        | negedge 
        | edge_control_specifier 
specify_terminal_descriptor ::= 
          specify_input_terminal_descriptor 
        | specify_output_terminal_descriptor 
edge_control_specifier ::= edge [ edge_descriptor [ , edge_descriptor ] ] 
edge_descriptor1 ::= 
          01 
        | 10 
        | z_or_x zero_or_one 
        | zero_or_one z_or_x 
zero_or_one ::= 0 | 1 
z_or_x ::= x | X | z | Z 
timing_check_condition ::= 
          scalar_timing_check_condition 
        | ( scalar_timing_check_condition ) 
scalar_timing_check_condition ::= 
          expression 
        | ~ expression 
        | expression == scalar_constant 
        | expression === scalar_constant 
        | expression != scalar_constant 
        | expression !== scalar_constant 
scalar_constant ::= 
          1'b0 | 1'b1 | 1'B0 | 1'B1 | 'b0 | 'b1 | 'B0 | 'B1 | 1 | 0 

A.8 Expressions 


A.8.1 Concatenations 


concatenation ::= { expression { , expression } } 
constant_concatenation ::= { constant_expression { , constant_expression } } 
constant_multiple_concatenation ::= { constant_expression constant_concatenation } 
module_path_concatenation ::= { module_path_expression { , module_path_expression } } 
module_path_multiple_concatenation ::= { constant_expression module_path_concatenation } 
multiple_concatenation ::= { constant_expression concatenation } 
net_concatenation ::= { net_concatenation_value { , net_concatenation_value } } 
net_concatenation_value ::= 
          hierarchical_net_identifier 
        | hierarchical_net_identifier [ expression ] { [ expression ] } 
        | hierarchical_net_identifier [ expression ] { [ expression ] } [ range_expression ] 
        | hierarchical_net_identifier [ range_expression ] 
        | net_concatenation 
variable_concatenation ::= { variable_concatenation_value { , variable_concatenation_value } } 
variable_concatenation_value ::= 
          hierarchical_variable_identifier 
        | hierarchical_variable_identifier [ expression ] { [ expression ] } 
        | hierarchical_variable_identifier [ expression ] { [ expression ] } [ range_expression ] 
        | hierarchical_variable_identifier [ range_expression ] 
        | variable_concatenation 

A.8.2 Function calls 


constant_function_call ::= function_identifier { attribute_instance } 
                  ( constant_expression { , constant_expression } ) 
function_call ::= hierarchical_function_identifierattribute_instance } 
                  ( expression { , expression } ) 
genvar_function_call ::= genvar_function_identifier { attribute_instance } 
                  ( constant_expression { , constant_expression } ) 
system_function_call ::= system_function_identifier 
                  [ ( expression { , expression } ) ] 

A.8.3 Expressions 


base_expression ::= expression 
bump_expression ::= 
          bump_operator variable_lvalue 
        | variable_lvalue bump_operator 

conditional_expression ::= expression1 ? { attribute_instance } expression2 : expression3 
constant_base_expression ::= constant_expression 
constant_expression ::= 
          constant_primary 
        | unary_operator { attribute_instance } constant_primary 
        | constant_expression binary_operator { attribute_instance } constant_expression 
        | constant_expression ? { attribute_instance } constant_expression : constant_expression 
        | string 
constant_mintypmax_expression ::= 
          constant_expression 
        | constant_expression : constant_expression : constant_expression 
constant_range_expression ::= 
          constant_expression 
        | msb_constant_expression : lsb_constant_expression 
        | constant_base_expression +: width_constant_expression 
        | constant_base_expression -: width_constant_expression 
dimension_constant_expression ::= constant_expression 
expression1 ::= expression 
expression2 ::= expression 
expression3 ::= expression 
expression ::= 
          primary 
        | unary_operator { attribute_instance } primary 
        | { attribute_instance } bump_expression 
/* SB - I didn't add bump_operator to unary_operator because 
        it doesn't make sense unless the operand can be changed 
        and systemsim only seems to allow this syntax as well */ 
        | ( operator_assignment ) 

        | expression binary_operator { attribute_instance } expression 
        | conditional_expression 
        | string 
lsb_constant_expression ::= constant_expression 
mintypmax_expression ::= 
          expression 
        | expression : expression : expression 
module_path_conditional_expression ::= module_path_expression ? { attribute_instance } 
                  module_path_expression : module_path_expression 
module_path_expression ::= 
          module_path_primary 
        | unary_module_path_operator { attribute_instance } module_path_primary 
        | module_path_expression binary_module_path_operator { attribute_instance } 
                  module_path_expression 
        | module_path_conditional_expression 
module_path_mintypmax_expression ::= 
          module_path_expression 
        | module_path_expression : module_path_expression : module_path_expression 
msb_constant_expression ::= constant_expression 
range_expression ::= 
          expression 
        | msb_constant_expression : lsb_constant_expression 
        | base_expression +: width_constant_expression 
        | base_expression -: width_constant_expression 
width_constant_expression ::= constant_expression 
 

A.8.4 Primaries 


constant_primary ::= 
          constant_concatenation 
        | constant_function_call 
        | ( constant_mintypmax_expression ) 
        | constant_multiple_concatenation 
        | genvar_identifier 
        | number 
        | parameter_identifier 
        | specparam_identifier 
        | time_literal 
        | '0 | '1 | 'z | 'Z | 'x | 'X 

module_path_primary ::= 
          number 
        | identifier 
        | module_path_concatenation 
        | module_path_multiple_concatenation 
        | function_call 
        | system_function_call 
        | constant_function_call 
        | ( module_path_mintypmax_expression ) 
primary ::= 
          number 
        | hierarchical_identifier 
        | hierarchical_identifier [ expression ] { [ expression ] } 
        | hierarchical_identifier [ expression ] { [ expression ] }  [ range_expression ] 
        | hierarchical_identifier [ range_expression ] 
        | concatenation 
        | multiple_concatenation 
        | function_call 
        | system_function_call 
        | constant_function_call 
        | ( mintypmax_expression ) 
        | ( expression ) 
        | { expression { , expression } } 
        | { expression { expression } } 
        | simple_type ' ( expression ) 
        | simple_type ' { expression { , expression } } 
        | simple_type ' { expression { expression } } 
        | time_literal 
        | '0 | '1 | 'z | 'Z | 'x | 'X 
        | data_type 
/* SB - I doubt we want data_type here... it doesn't make 
        sense in many expressions. We need to know what places it 
        makes sense and add it only to those types of 
        expressions. 
*/ 
time_literal ::= integer [ . integer ] time_unit 
time_unit ::= s | ms | us | ns | ps | fs 

A.8.5  Expression left-side values 


net_lvalue ::= 
          hierarchical_net_identifier 
        | hierarchical_net_identifier [ constant_expression ] { [ constant_expression ] } 
        | hierarchical_net_identifier [ constant_expression ] { [ constant_expression ] } [ constant_range_expression ] 
        | hierarchical_net_identifier [ constant_range_expression ] 
        | hierarchical_net_identifier ( [ constant_expression { , constant_expression } ] ) 

        | net_concatenation 
variable_lvalue ::=  
          variable_lvalue_item [ bump_operator ] 
        | hierarchical_variable_identifier ( [ constant_expression { , constant_expression } ] ) 
/* SB - This handles some of the postfix_expression 
        production. The rest was added to 
        hierarchical_variable_identifier. Since this production 
        was recursive, it was hard to know which applied to only 
        the leaf of the recursion vs what applied to every 
        stage. For example, I guessed that 'a->b->c' was ok, so 
        it went into hierarchical_variable_identifier, but I 
        guessed that a[1, 3, 5, 2].b[2:4].c([21, 24]) was not, so 
        these production elements stayed here. */ 
variable_lvalue_item ::= 

          hierarchical_variable_identifier 
        | hierarchical_variable_identifier [ expression ] { [ expression ] } 
        | hierarchical_variable_identifier [ expression ] { [ expression ] } [ range_expression ] 
        | hierarchical_variable_identifier [ range_expression ] 
        | variable_concatenation 

A.8.6 Operators 


unary_operator ::= 
          + | - | ! | ~ | & | ~& | | | ~| | ^ | ~^ | ^~ 
binary_operator ::= 
          + | - | * | / | % | == | != | === | !== | && | || | ** 
        | < | <= | > | >= | & | | | ^ | ^~ | ~^ | >> | << | >>> | <<< 
bump_operator ::= + + | - - 

unary_module_path_operator ::= 
          ! | ~ | & | ~& | | | ~| | ^ | ~^ | ^~ 
binary_module_path_operator ::= 
          == | != | && | || | & | | | ^ | ^~ | ~^ 

A.8.7 Numbers 


number ::= 
          decimal_number 
        | octal_number 
        | binary_number 
        | hex_number 
        | real_number 
real_number1 ::= 
          unsigned_number . unsigned_number 
        | unsigned_number [ . unsigned_number ] exp [ sign ] unsigned_number 
exp ::= e | E 
decimal_number ::= 
          unsigned_number 
        | [ size ] decimal_base unsigned_number 
        | [ size ] decimal_base x_digit { _ } 
        | [ size ] decimal_base z_digit { _ } 
binary_number ::= [ size ] binary_base binary_value 
octal_number ::= [ size ] octal_base octal_value 
hex_number ::= [ size ] hex_base hex_value 
sign ::= + | - 
size ::= non_zero_unsigned_number 
non_zero_unsigned_number1 ::= non_zero_decimal_digit { _ | decimal_digit
unsigned_number1 ::= decimal_digit { _ | decimal_digit } 
binary_value1 ::= binary_digit { _ | binary_digit } 
octal_value1 ::= octal_digit { _ | octal_digit } 
hex_value1 ::= hex_digit { _ | hex_digit } 
decimal_base1 ::= '[s|S]d | '[s|S]D 
binary_base1 ::= '[s|S]b |  '[s|S]B 
octal_base1 ::= '[s|S]o | '[s|S]O 
hex_base1 ::= '[s|S]h | '[s|S]H 
non_zero_decimal_digit ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 
decimal_digit ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 
binary_digit ::= x_digit | z_digit | 0 | 1 
octal_digit ::= x_digit | z_digit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 
hex_digit ::= 
          x_digit | z_digit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 
        | a | b | c | d | e | f | A | B | C | D | E | F 
 
x_digit ::= x | X 
z_digit ::= z | Z | ? 

A.8.8 Strings 


string ::= " { Any_ASCII_Characters_except_new_line } " 

A.9 General 


A.9.1 Attributes 


attribute_instance ::= (* attr_spec { , attr_spec } *) 
attr_spec ::= 
          attr_name = constant_expression 
        | attr_name 
attr_name ::= identifier 

A.9.2 Comments 


comment ::= 
          one_line_comment 
        | block_comment 
one_line_comment ::= // comment_text \n 
block_comment ::= /* comment_text */ 
comment_text ::= { Any_ASCII_character } 

A.9.3 Identifiers 


arrayed_identifier ::= 
          simple_arrayed_identifier 
        | escaped_arrayed_identifier 
block_identifier ::= identifier 
cell_identifier ::= identifier 
config_identifier ::= identifier 
const_identifier ::= identifier 
enum_identifier ::= identifier 

escaped_arrayed_identifier ::= escaped_identifier [ range ] 
escaped_hierarchical_identifier4 ::= 
          escaped_hierarchical_branch 
                { .simple_hierarchical_branch | .escaped_hierarchical_branch } 
escaped_identifier ::= \ {Any_ASCII_character_except_white_space} white_space 
event_identifier ::= identifier 
function_identifier ::= identifier 
gate_instance_identifier ::= arrayed_identifier 
generate_block_identifier ::= identifier 
genvar_function_identifier ::= identifier  /* Hierarchy disallowed */ 
genvar_identifier ::= identifier 
hierarchical_block_identifier ::= hierarchical_identifier 
hierarchical_event_identifier ::= hierarchical_identifier 
hierarchical_function_identifier ::= hierarchical_identifier 
hierarchical_identifier ::= 
          simple_hierarchical_identifier 
        | escaped_hierarchical_identifier 
hierarchical_net_identifier ::= hierarchical_identifier 
hierarchical_variable_identifier ::= hierarchical_identifier 
hierarchical_task_identifier ::= hierarchical_identifier 
identifier ::= 
          simple_identifier 
        | escaped_identifier 
interface_identifier ::= identifier 

inout_port_identifier ::= identifier 
input_port_identifier ::= identifier 
instance_identifier ::= identifier 
library_identifier ::= identifier 
memory_identifier ::= identifier 
modport_identifier ::= identifier 

module_identifier ::= identifier 
module_instance_identifier ::= arrayed_identifier 
net_identifier ::= identifier 
output_port_identifier ::= identifier 
parameter_identifier ::= identifier 
port_identifier ::= identifier 
real_identifier ::= identifier 
simple_arrayed_identifier ::= simple_identifier [ range ] 
simple_hierarchical_identifier3 ::= 
          simple_hierarchical_branch [ .escaped_identifier ] 
simple_identifier2 ::= [ a-zA-Z_ ] { [ a-zA-Z0-9_$ ] } 
specparam_identifier ::= identifier 
state_identifier ::= identifier 
system_function_identifier5 ::= $[ a-zA-Z0-9_$ ]{ [ a-zA-Z0-9_$ ] } 
system_task_identifier5 ::= $[ a-zA-Z0-9_$ ]{ [ a-zA-Z0-9_$ ] } 
task_identifier ::= identifier 
terminal_identifier ::= identifier 
text_macro_identifier ::= simple_identifier 
topmodule_identifier ::= identifier 
type_declaration_identifier ::= type_identifier { packed_dimension } 
type_identifier ::= identifier 

udp_identifier ::= identifier 
udp_instance_identifier ::= arrayed_identifier 
variable_decl_assign_identifier ::= 
          variable_identifier { unpacked_dimension } [ = constant_expression ] 
variable_declaration_identifier ::= 
          variable_identifier { unpacked_dimension } 

variable_identifier ::= identifier 

A.9.4 Identifier branches 


/* SB - Some of the production elements of postfix_expression 
        (see comments with variable_lvalue definition) were 
        incorporated here. The ones that seemed to apply to every 
        stage of a path went here and the rest went into 
        variable_lvalue
        I also added support for the multiple dimensional arrays 
        of instances. */ 

simple_hierarchical_branch3 ::= 
          simple_identifier [{ [ unsigned_number ] ]} 
                [ { . simple_identifier [{ [ unsigned_number ] ]} } ] 
        | simple_identifier [{ [ unsigned_number ]} ] 
                [ { -> simple_identifier [{ [ unsigned_number ] ]} } ] 

escaped_hierarchical_branch4 ::= 
          escaped_identifier [{ [ unsigned_number ] ]} 
                [ { . escaped_identifier [{ [ unsigned_number ] ]} } ] 
        | escaped_identifier [{ [ unsigned_number ] ]} 
                [ { -> escaped_identifier [{ [ unsigned_number ] ]} } ] 

A.9.5 White space 


white_space ::= space | tab | newline | eof6 
NOTES 
1)      Embedded spaces are illegal. 
2)      A simple_identifier and arrayed_reference shall start with an alpha or underscore (_) character, shall have at least one character, and shall not have any spaces. 
3)      The period (.) in simple_hierarchical_identifier and simple_hierarchical_ 
branch shall not be preceded or followed by white_space
4)      The period in escaped_hierarchical_identifier and escaped_hierarchical_ 
branch shall be preceded by white_space, but shall not be followed by white_space
5)      The $ character in a system_function_identifier or system_task_identifier shall not be followed by white_spaceA system_function_identifier or system_task_identifier shall not be escaped. 
6)      End of file.