%require "3.0" %defines %define parse.trace %verbose %define parse.error verbose %{ /* ** HDL4SE: 软件Verilog综合仿真平台 ** Copyright (C) 2021-2021, raoxianhong ** LCOM: 轻量级组件对象模型 ** Copyright (C) 2021-2021, raoxianhong ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** ** * Redistributions of source code must retain the above copyright notice, ** this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright notice, ** this list of conditions and the following disclaimer in the documentation ** and/or other materials provided with the distribution. ** * The name of the author may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF ** THE POSSIBILITY OF SUCH DAMAGE. */ /* * verilog_parser.y 修改记录: 202105280612: rxh, initial version 202106291739: rxh, 表达式运算符优先级的语法实现,规范中没有给出运算符优先级的语法表达 */ #include #include #include #include "object.h" #include "dlist.h" #include "conststring.h" #include "verilog_keyword.h" #include "bignumber.h" #include "mapstr2ptr.h" #include "verilog_parsetree.h" extern int yylex(); extern int yylineno; extern char * yytext; HOBJECT lastport = NULL; HOBJECT lastparameter = NULL; HOBJECT currentmodule = NULL; static char logbuf[2048]; void yyerror(const char *msg){ IConstStringVar *pfilename; int lineno; int linepos; int filepos; pfilename = NULL; if (0 == hdl4se_parser_GetCurrentFile(&pfilename, &lineno, &linepos, &filepos)) { if (pfilename != NULL) { sprintf(logbuf, "file %s line %d - ERROR: %s\n - '%s'", pfilename->string, lineno, msg, yytext); hdl4se_parser_AddLog(logbuf); } } } %} %code requires{ #include "stdio.h" #include "object.h" #include "dlist.h" #include "bignumber.h" #include "conststring.h" #include "mapstr2ptr.h" #include "verilog_parsetree.h" #include "verilog_root.h" #include "verilog_module.h" #include "verilog_keyword.h" #include "verilog_attrspec.h" #include "verilog_parameter.h" #include "verilog_expr.h" #include "verilog_port.h" #include "verilog_vardecl.h" #include "verilog_varsel.h" #include "verilog_paraminst.h" #include "verilog_moduleinst.h" #include "verilog_assignment.h" #include "verilog_statement.h" } /* token types */ %union { HOBJECT treenode; HOBJECT obj; struct _mul_obj { int type; int objcount; HOBJECT obj[16]; }mul_obj; struct _str_bind_obj { IConstStringVar * key; HOBJECT obj; }str_bind_obj; IConstStringVar * string; int token; int operator; int ival; IDListVar* list; } %token END ANY NEWLINE SPACE TAB %token BIN_VALUE OCT_VALUE HEX_VALUE DEC_VALUE DEC_BASE BIN_BASE OCT_BASE HEX_BASE NUM_REAL NUM_SIZE UNSIGNED_NUMBER SYSTEM_ID SIMPLE_ID ESCAPED_ID DEFINE_ID STRING /* Operators Precedence */ %token '@' ',' '#' '.' '=' ':' ';' '(' ')' '[' ']' '{' '}' '+' '-' '*' '/' '%' '>' '<' '!' '&' '|' '^' '~' '?' %token ATTRIBUTE_START ATTRIBUTE_END ASL ASR LSL LSR GTE LTE L_AND L_OR L_EQ C_EQ L_NEQ C_NEQ B_EQU B_NAND B_NOR IDX_PRT_SEL POW T_AND STARTPLUSWIDTH STARTMINUSWIDTH MINUSGT EQGT STARGT %token KW_ALWAYS KW_AND KW_ASSIGN KW_AUTOMATIC KW_BEGIN KW_BUF KW_BUFIF0 KW_BUFIF1 KW_CASE KW_CASEX KW_CASEZ KW_CELL KW_CMOS KW_CONFIG KW_DEASSIGN KW_DEFAULT KW_DEFPARAM KW_DESIGN KW_DISABLE KW_EDGE KW_ELSE KW_END KW_ENDCASE KW_ENDCONFIG KW_ENDFUNCTION KW_ENDGENERATE KW_ENDMODULE KW_ENDPRIMITIVE KW_ENDSPECIFY KW_ENDTABLE KW_ENDTASK KW_EVENT KW_FOR KW_FORCE KW_FOREVER KW_FORK KW_FUNCTION KW_GENERATE KW_GENVAR KW_HIGHZ0 KW_HIGHZ1 KW_IF KW_IFNONE KW_INCDIR KW_INCLUDE KW_INITIAL KW_INOUT KW_INPUT KW_INSTANCE KW_INTEGER KW_JOIN KW_LARGE KW_LIBLIST KW_LIBRARY KW_LOCALPARAM KW_MACROMODULE KW_MEDIUM KW_MODULE KW_NAN KW_NEGEDGE KW_NMOS KW_NOR KW_NOSHOWCANCELLED KW_NOT KW_NOTIF0 KW_NOTIF1 KW_OR KW_OUTPUT KW_PARAMETER KW_PATHPULSE KW_PMOS KW_POSEDGE KW_PRIMITIVE KW_PULL0 KW_PULL1 KW_PULLDOWN KW_PULLUP KW_PULSESTYLE_ONEVENT KW_PULSESTYLE_ONDETECT KW_RCMOS KW_REAL KW_REALTIME KW_REG KW_RELEASE KW_REPEAT KW_RNMOS KW_RPMOS KW_RTRAN KW_RTRANIF0 KW_RTRANIF1 KW_SCALARED KW_SHOWCANCELLED KW_SIGNED KW_SMALL KW_SPECIFY KW_SPECPARAM KW_STRONG0 KW_STRONG1 KW_SUPPLY0 KW_SUPPLY1 KW_TABLE KW_TASK KW_TIME KW_TRAN KW_TRANIF0 KW_TRANIF1 KW_TRI KW_TRI0 KW_TRI1 KW_TRIAND KW_TRIOR KW_TRIREG KW_UNSIGNED KW_USE KW_VECTORED KW_WAIT KW_WAND KW_WEAK0 KW_WEAK1 KW_WHILE KW_WIRE KW_WOR KW_XNOR KW_XOR KW_NAND KW_UWIRE KW_SYS_SETUP KW_SYS_HOLD KW_SYS_SETUPHOLD KW_SYS_RECOVERY KW_SYS_REMOVAL KW_SYS_RECREM KW_SYS_SKEW KW_SYS_TIMESKEW KW_SYS_FULLSKEW KW_SYS_PERIOD KW_SYS_WIDTH KW_SYS_NOCHANGE /* Operator Precedence */ %right '?' /* Lowest Precedence */ %left L_OR %left L_AND %left '|' B_NOR %left B_EQU '^' %left B_NAND '&' %left L_EQ C_EQ L_NEQ C_NEQ %left '>' '<' GTE LTE %left LSL LSR ASR ASL %left '+' '-' %left '*' '/' '%' %left POW %right '!' '~' /* Highest Precedence. */ %start grammar_begin %type attr_name identifier module_identifier topmodule_identifier parameter_identifier port_identifier net_identifier module_instance_identifier number string unsigned_number %type parameter_type unary_operator binary_operator signed_option unary_module_path_operator binary_module_path_operator net_type net_type_option output_variable_type vectored_or_scalared_option vectored_option scalared_option %type range range_option constant_range_expression dimension mintypmax_expression mintypmax_expression_option var %type port_ident param_assignment net_decl_assignment %type attr_spec %type constant_mintypmax_expression constant_primary port parameter_declaration port_declaration inout_declaration input_declaration output_declaration port_reference constant_base_expression width_constant_expression msb_constant_expression lsb_constant_expression dimension_constant_expression primary unary_expression pow_expression multiplicative_expression additive_expression shift_expression relational_expression equality_expression and_expression exclusive_or_expression inclusive_or_expression logical_and_expression logical_or_expression conditional_expression expression expression_option unary_constant_expression pow_constant_expression multiplicative_constant_expression additive_constant_expression shift_constant_expression relational_constant_expression equality_constant_expression and_constant_expression exclusive_or_constant_expression inclusive_or_constant_expression logical_and_constant_expression logical_or_constant_expression conditional_constant_expression constant_expression base_expression module_instance ordered_parameter_assignment named_parameter_assignment named_port_connection ordered_port_connection net_assignment hierarchical_identifier_part statement statement_or_null blocking_assignment nonblocking_assignment %type attribute_instance_list attribute_instance attribute_instance_spec_list hierarchical_identifier %type list_of_net list_of_net_identifiers list_of_net_decl_assignments %type dimension_list %type module_parameter_port_list module_param_list list_of_param_assignments port_declaration_list list_of_port_connections_option %type module_instance_list parameter_value_assignment_option parameter_value_assignment list_of_parameter_assignments ordered_parameter_assignment_list named_parameter_assignment_list list_of_port_connections ordered_port_connection_list named_port_connection_list %type list_of_port_declarations list_of_ports module_item_list non_port_module_item_list ports port_declarations port_expression %type list_of_net_assignments %% /* Start variables */ grammar_begin : library_text {} | source_text {} | %empty { } ; /* A.1.1 Library Source Text */ library_text : library_descriptions {} | library_text library_descriptions{} ; library_descriptions : library_declaration{} | include_statement{} | config_declaration{} ; library_declaration : KW_LIBRARY library_identifier file_path_specs ';'{} | KW_LIBRARY library_identifier file_path_specs KW_INCDIR file_path_specs ';'{} ; file_path_specs : file_path_spec{} | file_path_specs ',' file_path_spec{} ; file_path_spec : file_path{} ; file_path : string {} ; include_statement : KW_INCLUDE file_path_spec ';'{} ; /* A.1.2 Verilog source text. */ source_text : description { } | source_text description{ } ; description : module_declaration { } | udp_declaration { } | config_declaration { } ; module_item_list : %empty { } | module_item { } | module_item_list module_item { } ; non_port_module_item_list : %empty { } | non_port_module_item { } | non_port_module_item_list non_port_module_item { } ; module_declaration : attribute_instance_list module_keyword module_identifier module_parameter_port_list list_of_ports ';' { IVerilogRoot ** ppRoot = getVerilogRoot(); (*ppRoot)->add_module(ppRoot, $3, currentmodule = verilogparseCreateModuleDeclaration($1,$3,$4,$5)); objectRelease($3); lastport = NULL; lastparameter = NULL; } module_item_list KW_ENDMODULE { /* IVerilogRoot ** ppRoot = getVerilogRoot(); (*ppRoot)->add_module(ppRoot, $3, verilogparseCreateModuleDeclaration($1,$3,$4,$5)); objectRelease($3); lastport = NULL; lastparameter = NULL; */ currentmodule = NULL; } | attribute_instance_list module_keyword module_identifier module_parameter_port_list list_of_port_declarations ';' { IVerilogRoot ** ppRoot = getVerilogRoot(); (*ppRoot)->add_module(ppRoot, $3, currentmodule = verilogparseCreateModuleDeclaration($1,$3,$4,$5)); objectRelease($3); lastport = NULL; lastparameter = NULL; } non_port_module_item_list KW_ENDMODULE { /* IVerilogRoot ** ppRoot = getVerilogRoot(); (*ppRoot)->add_module(ppRoot, $3, verilogparseCreateModuleDeclaration($1,$3,$4,$5)); objectRelease($3); lastport = NULL; lastparameter = NULL; */ currentmodule = NULL; } ; module_keyword : KW_MODULE { } | KW_MACROMODULE { } ; /* A.1.3 Module parameters and ports */ module_parameter_port_list : %empty { $$ = dlistCreate(); lastparameter = NULL; } | '#' '(' module_param_list ')'{ $$ = $3; lastparameter = NULL; } ; module_param_list : parameter_declaration { $$ = dlistCreate(); dlistAppendItem($$, $1); } | module_param_list ',' parameter_declaration{ $$ = $1; dlistAppendItem($$, $3); } ; list_of_ports : %empty { $$ = dlistCreate(); } | '(' ports ')' { $$ = $2; } ; /* 我们不支持复杂端口定义 */ ports : %empty { $$ = dlistCreate(); } | ports ',' port_identifier{ $$ = $1; dlistAppendItem($$, verilogparseCreatePort( NULL, /* IDListVarPtr attributes, */ PORT_DIRECT_UNKNOW, /* int port_direct, */ 0, /* int port_type, */ 0, /* int port_issigned, */ RANGE_TYPE_NONE, /*int range_type*/ NULL, /* HOBJECT param_range_msb, expression */ NULL, /* HOBJECT param_range_lsb, expression */ $3, /* const char * name, */ NULL /* HOBJECT expr */ ) ); } | port_identifier { $$ = dlistCreate(); dlistAppendItem($$, verilogparseCreatePort( NULL, /* IDListVarPtr attributes, */ PORT_DIRECT_UNKNOW, /* int port_direct, */ VAR_TYPE_NONE, /* int port_type, */ 0, /* int port_issigned, */ RANGE_TYPE_NONE, /*int range_type*/ NULL, /* HOBJECT param_range_msb, expression */ NULL, /* HOBJECT param_range_lsb, expression */ $1, /* const char * name, */ NULL /* HOBJECT expr */ ) ); } ; /* ports : %empty { $$ = dlistCreate(); } | ports ',' port{ $$ = $1; dlistAppendItem($$,$3); } | port { $$ = dlistCreate(); dlistAppendItem($$,$1); } ; */ list_of_port_declarations : '(' port_declarations ')'{ $$ = $2; } ; port_declarations : %empty { $$ = dlistCreate(); } | port_declarations ',' port_declaration { $$ = $1; dlistAppendItem($$,$3); } | port_declaration { $$ = dlistCreate(); dlistAppendItem($$,$1); } ; port : port_expression{ $$ = $1; } | '.' port_identifier '(' port_expression ')'{ // $$ = verilogparserCreatePort($2, $4); } ; port_expression : %empty { $$ = dlistCreate(); } | port_reference { $$ = dlistCreate(); dlistAppendItem($$, $1); } | port_expression ',' port_reference{ $$ = $1; dlistAppendItem($$,$3); } ; port_reference : port_identifier{ $$ = NULL; } | port_identifier '[' ']' { $$ = NULL; } | port_identifier '[' constant_range_expression ']' { $$ = NULL; } ; /* port_declaration : attribute_instance_list inout_declaration { } | attribute_instance_list input_declaration { } | attribute_instance_list output_declaration { } ; */ /* IEEE. 1364-2005的这种格式端口定义不满足LALR(1), module test ( input [7:0] a, input signed [7:0] b, c, d, output [7:0] e, output reg signed [7:0] f, g, output signed [7:0] h) ; endmodule 原来的语法是分组描述的,然而注意每一组定义后面用逗号, 与组内的标识符后的逗号冲突了,这样不满足LALR(1)的要求, 现在改为为每个端口都是单独声明的,声明可以带属性也可以 不带属性,不带属性的声明使用前面最近一个带属性的声明的 属性。导致的问题有二:1.第一个端口必须是带属性的,这个 应该由动作函数来做检查,2.output端口类型可以设置REG等属 性并设置初始值,这是其他端口不能有的,这个也由动作函数 来做检查吧。 注意后面的input_declaration,input_declaration和 output_declaration也做了相应的调整,每个后面不是跟一系列 标识符,而是只跟一个port_ident了,这样就消除了冲突,满足 LALR(1)的要求。 */ port_declaration : inout_declaration { $$ = $1; lastport = $1; } | input_declaration { $$ = $1; lastport = $1; } | output_declaration { $$ = $1; lastport = $1; } | port_ident { $$ = verilogparseCreatePort( NULL, /* IDListVarPtr attributes, */ PORT_DIRECT_ASPRE, /* int port_direct, */ VAR_TYPE_NONE, /* int port_type, */ 0, /* int port_issigned, */ RANGE_TYPE_NONE, /*int range_type*/ lastport, /* HOBJECT param_range_msb, expression */ NULL, /* HOBJECT param_range_lsb, expression */ $1.key, /* const char * name, */ $1.obj /* HOBJECT expr */ ); } ; /* 下面修改过的语法从A.2.1.2过来的 */ inout_declaration : attribute_instance_list KW_INOUT net_type_option signed_option range_option port_ident { $$ = verilogparseCreatePort( $1, /* IDListVarPtr attributes, */ PORT_DIRECT_INOUT, /* int port_direct, */ $3, /* int port_type, */ $4, /* int port_issigned, */ $5.type, /*int range_type*/ $5.obj[0], /* HOBJECT param_range_msb, expression */ $5.obj[1], /* HOBJECT param_range_lsb, expression */ $6.key, /* const char * name, */ $6.obj /* HOBJECT expr */ ); } ; input_declaration : attribute_instance_list KW_INPUT net_type_option signed_option range_option port_ident { $$ = verilogparseCreatePort( $1, /* IDListVarPtr attributes, */ PORT_DIRECT_INPUT, /* int port_direct, */ $3, /* int port_type, */ $4, /* int port_issigned, */ $5.type, /*int range_type*/ $5.obj[0], /* HOBJECT param_range_msb, expression */ $5.obj[1], /* HOBJECT param_range_lsb, expression */ $6.key, /* const char * name, */ $6.obj /* HOBJECT expr */ ); } ; output_declaration : attribute_instance_list KW_OUTPUT net_type_option signed_option range_option port_ident { $$ = verilogparseCreatePort( $1, /* IDListVarPtr attributes, */ PORT_DIRECT_OUTPUT, /* int port_direct, */ $3, /* int port_type, */ $4, /* int port_issigned, */ $5.type, /*int range_type*/ $5.obj[0], /* HOBJECT param_range_msb, expression */ $5.obj[1], /* HOBJECT param_range_lsb, expression */ $6.key, /* const char * name, */ $6.obj /* HOBJECT expr */ ); } | attribute_instance_list KW_OUTPUT KW_REG signed_option range_option port_ident { $$ = verilogparseCreatePort( $1, /* IDListVarPtr attributes, */ PORT_DIRECT_OUTPUT, /* int port_direct, */ VAR_TYPE_REG, /* int port_type, */ $4, /* int port_issigned, */ $5.type, /*int range_type*/ $5.obj[0], /* HOBJECT param_range_msb, expression */ $5.obj[1], /* HOBJECT param_range_lsb, expression */ $6.key, /* const char * name, */ $6.obj /* HOBJECT expr */ ); } | attribute_instance_list KW_OUTPUT output_variable_type port_ident { $$ = verilogparseCreatePort( $1, /* IDListVarPtr attributes, */ PORT_DIRECT_OUTPUT, /* int port_direct, */ $3, /* int port_type, */ 0, /* int port_issigned, */ RANGE_TYPE_NONE, /*int range_type*/ NULL, /* HOBJECT param_range_msb, expression */ NULL, /* HOBJECT param_range_lsb, expression */ $4.key, /* const char * name, */ $4.obj /* HOBJECT expr */ ); } ; /* A.1.4 Module Items */ port_declaration_list : inout_declaration { $$ = dlistCreate(); dlistAppendItem($$, $1); lastport = $1; } | input_declaration { $$ = dlistCreate(); dlistAppendItem($$, $1); lastport = $1; } | output_declaration { $$ = dlistCreate(); dlistAppendItem($$, $1); lastport = $1; } | port_declaration_list ',' port_ident { $$ = $1; dlistAppendItem($$, verilogparseCreatePort( NULL, /* IDListVarPtr attributes, */ PORT_DIRECT_ASPRE, /* int port_direct, */ VAR_TYPE_NONE, /* int port_type, */ 0, /* int port_issigned, */ RANGE_TYPE_NONE, /*int range_type*/ lastport, /* HOBJECT param_range_msb, expression */ NULL, /* HOBJECT param_range_lsb, expression */ $3.key, /* const char * name, */ $3.obj /* HOBJECT expr */ )); } module_item : port_declaration_list { } | non_port_module_item { } ; module_or_generate_item : module_or_generate_item_declaration { } | attribute_instance_list local_parameter_declaration ';' { } | attribute_instance_list parameter_override { } | continuous_assign { } | attribute_instance_list gate_instantiation { } | attribute_instance_list udp_instantiation { } | module_instantiation { } | attribute_instance_list initial_construct { } | always_construct { } | attribute_instance_list loop_generate_construct { } | attribute_instance_list conditional_generate_construct { } ; module_or_generate_item_declaration : net_declaration { } | attribute_instance_list reg_declaration { } | attribute_instance_list integer_declaration { } | attribute_instance_list real_declaration { } | attribute_instance_list time_declaration { } | attribute_instance_list realtime_declaration { } | attribute_instance_list event_declaration { } | attribute_instance_list genvar_declaration { } | attribute_instance_list task_declaration { } | attribute_instance_list function_declaration { } ; non_port_module_item : module_or_generate_item { } | generate_region { } | specify_block { } | attribute_instance_list parameter_declaration ';' { } | attribute_instance_list specparam_declaration { } ; parameter_override : KW_DEFPARAM list_of_defparam_assignments ';' { } ; /* A.1.5 Configuration source text */ config_declaration : KW_CONFIG config_identifier ';' design_statement KW_ENDCONFIG { } | KW_CONFIG config_identifier ';' design_statement config_rule_statement KW_ENDCONFIG { } ; design_statement : KW_DESIGN design_cell_list ';' { } ; design_cell_list : %empty { } | design_cell_list design_cell { } | design_cell { } ; design_cell : cell_identifier { } | 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 : KW_DEFAULT { } ; inst_clause : KW_INSTANCE inst_name { } ; inst_name : topmodule_identifier { } | inst_name '.' instance_identifier { } ; cell_clause : KW_CELL cell_identifier { } | KW_CELL library_identifier '.' cell_identifier { } ; liblist_clause : KW_LIBLIST { } | KW_LIBLIST library_identifier { } ; use_clause : KW_USE cell_identifier { } | KW_USE cell_identifier ':' KW_CONFIG { } | KW_USE library_identifier '.' cell_identifier { } | KW_USE library_identifier '.' cell_identifier ':' KW_CONFIG { } ; /* A.2 Declarations A.2.1 Declaration types A.2.1.1 Module parameter declarations */ signed_option: %empty { $$ = 0; } | KW_SIGNED { $$ = 1; } ; range_option: %empty { $$.type = RANGE_TYPE_NONE; $$.obj[0] = NULL; $$.obj[1] = NULL; } | range { $$ = $1; } ; local_parameter_declaration : KW_LOCALPARAM signed_option range_option list_of_param_assignments { } | KW_LOCALPARAM parameter_type list_of_param_assignments{ } ; /* 因不满足LALR(1)而修改。 parameter_declaration : KW_PARAMETER signed_option range_option list_of_param_assignments { } | KW_PARAMETER parameter_type list_of_param_assignments { } ; */ parameter_declaration : KW_PARAMETER signed_option range_option param_assignment { $$ = verilogparseCreateParameter(PARAM_TYPE_PARAM, PARAM_DATA_TYPE_INTEGER, $2, $3.type, $3.obj[0], $3.obj[1], $4.key, $4.obj); lastparameter = $$; } | KW_PARAMETER parameter_type param_assignment { $$ = verilogparseCreateParameter(PARAM_TYPE_PARAM, $2, 0, RANGE_TYPE_NONE, NULL, NULL, $3.key, $3.obj); lastparameter = $$; } | param_assignment { $$ = verilogparseCreateParameter(PARAM_TYPE_ASPRE, 0, 0, RANGE_TYPE_NONE, lastparameter, NULL, $1.key, $1.obj); } ; specparam_declaration : KW_SPECPARAM range_option list_of_specparam_assignments ';' { } ; parameter_type : KW_INTEGER { $$ = PARAM_DATA_TYPE_INTEGER; } | KW_REAL { $$ = PARAM_DATA_TYPE_REAL; } | KW_REALTIME { $$ = PARAM_DATA_TYPE_REALTIME; } | KW_TIME { $$ = PARAM_DATA_TYPE_TIME; } ; /* A.2.1.2 Port declarations */ net_type_option : %empty { $$ = VAR_TYPE_NONE; } | net_type { $$ = $1; } ; /* inout_declaration : KW_INOUT net_type_option signed_option range_option list_of_port_identifiers { } ; input_declaration : KW_INPUT net_type_option signed_option range_option list_of_port_identifiers { } ; output_declaration : KW_OUTPUT net_type_option signed_option range_option list_of_port_identifiers { } | KW_OUTPUT KW_REG signed_option range_option list_of_variable_port_identifiers { } | KW_OUTPUT output_variable_type list_of_variable_port_identifiers { } ; */ /* A.2.1.3 Type declarations */ event_declaration : KW_EVENT list_of_event_identifiers ';' { } ; integer_declaration : KW_INTEGER list_of_variable_identifiers ';' { } ; delay3_option: %empty { } | delay3 { } ; drive_strength_option : %empty { } | drive_strength { } ; vectored_option : %empty { $$ = VS_NONE; } | KW_VECTORED { $$ = VS_VECTORED; } ; scalared_option : %empty { $$ = VS_NONE; } | KW_SCALARED { $$ = VS_SCALARED; } ; charge_strength_option : %empty { } | charge_strength { } ; vectored_or_scalared_option : %empty { $$ = VS_NONE; } | KW_VECTORED { $$ = VS_VECTORED; } | KW_SCALARED { $$ = VS_SCALARED; } ; list_of_net : list_of_net_identifiers { $$ = $1; } | list_of_net_decl_assignments { $$ = $1; } ; net_declaration : /* attribute_instance_list net_type signed_option delay3_option list_of_net_identifiers ';' { } | attribute_instance_list net_type drive_strength_option signed_option delay3_option list_of_net_decl_assignments ';' { } |*/ attribute_instance_list net_type drive_strength_option vectored_or_scalared_option signed_option range_option delay3_option list_of_net ';' { if (currentmodule == NULL) { yyerror("no current module"); } else { IDListVar* list; IDListVarPtr pitem, pitemtemp; list = dlistCreate(); pitem = $8->__dlist_pNext; while (!IsDListHeader(pitem)) { pitemtemp = pitem->__dlist_pNext; dlistDetach(pitem); verilogparseVarDeclSetOptions(pitem, $2, //int type, $1, //IDListVar* attributes, $4, //int vectored_or_scalared, $5, //int issigned, $6.type, //int range_type, $6.obj[0], //HOBJECT range_msb, $6.obj[1] //HOBJECT range_lsb ); dlistAppendItem(list, pitem); pitem = pitemtemp; } objectRelease($8); verilogparseAddModuleItems(currentmodule, list, MODULE_ITEM_TYPE_NET_DECLARATION); } } /* | attribute_instance_list net_type scalared_option signed_option range delay3_option list_of_net_identifiers ';' { } | attribute_instance_list net_type drive_strength_option vectored_option scalared_option signed_option range delay3_option list_of_net_decl_assignments ';' { } */ | attribute_instance_list KW_TRIREG charge_strength_option signed_option delay3_option list_of_net_identifiers ';' | attribute_instance_list KW_TRIREG drive_strength_option signed_option delay3_option list_of_net_decl_assignments ';' { } | attribute_instance_list KW_TRIREG charge_strength_option vectored_or_scalared_option signed_option range delay3_option list_of_net_identifiers ';' { } | attribute_instance_list KW_TRIREG drive_strength_option vectored_or_scalared_option signed_option range delay3_option list_of_net_decl_assignments ';' { } ; real_declaration : KW_REAL list_of_real_identifiers ';' { } ; realtime_declaration : KW_REALTIME list_of_real_identifiers ';' { } ; reg_declaration : KW_REG signed_option range_option list_of_variable_identifiers ';' { } ; time_declaration : KW_TIME list_of_variable_identifiers ';' { } ; /* A.2.2 Declaration data types A.2.2.1 Net and variable types */ net_type : KW_SUPPLY0 { $$ = VAR_TYPE_SUPPLY0; } | KW_SUPPLY1 { $$ = VAR_TYPE_SUPPLY1; } | KW_TRI { $$ = VAR_TYPE_TRI; } | KW_TRIAND { $$ = VAR_TYPE_TRIAND; } | KW_TRIOR { $$ = VAR_TYPE_TRIOR; } | KW_TRI0 { $$ = VAR_TYPE_TRI0; } | KW_TRI1 { $$ = VAR_TYPE_TRI1; } | KW_UWIRE { $$ = VAR_TYPE_UWIRE; } | KW_WIRE { $$ = VAR_TYPE_WIRE; } | KW_WAND { $$ = VAR_TYPE_WAND; } | KW_WOR { $$ = VAR_TYPE_WOR; } ; output_variable_type : KW_INTEGER { $$ = VAR_TYPE_INTEGER; } | KW_TIME { $$ = VAR_TYPE_TIME; } ; dimension_list : %empty { $$ = dlistCreate(); } | dimension_list dimension { $$ = $1; dlistAppendItem($$, $2.obj[0]); dlistAppendItem($$, $2.obj[1]); } | dimension { $$ = dlistCreate(); dlistAppendItem($$, $1.obj[0]); dlistAppendItem($$, $1.obj[1]); } ; real_type : real_identifier dimension_list { } | real_identifier '=' constant_expression { } ; variable_type : variable_identifier dimension_list { } | variable_identifier '=' constant_expression { } ; /* A.2.2.2 Strengths */ drive_strength : '(' strength0 ',' strength1 ')' { } | '(' strength1 ',' strength0 ')' { } | '(' strength0 ',' KW_HIGHZ1 ')' { } | '(' strength1 ',' KW_HIGHZ0 ')' { } | '(' KW_HIGHZ0 ',' strength1 ')' { } | '(' KW_HIGHZ1 ',' strength0 ')' { } ; strength0 : KW_SUPPLY0 { } | KW_STRONG0 { } | KW_PULL0 { } | KW_WEAK0 { } ; strength1 : KW_SUPPLY1 { } | KW_STRONG1 { } | KW_PULL1 { } | KW_WEAK1 { } ; charge_strength : '(' KW_SMALL ')' { } | '(' KW_MEDIUM ')' { } | '(' KW_LARGE ')' { } ; /* A.2.2.3 Delays */ delay3 : '#' delay_value { } | '#' '(' mintypmax_expression ')' { } | '#' '(' mintypmax_expression ',' mintypmax_expression ')' { } | '#' '(' mintypmax_expression ',' mintypmax_expression ',' mintypmax_expression ')' { } ; delay2 : '#' delay_value { } | '#' '(' mintypmax_expression ')' { } | '#' '(' mintypmax_expression ',' mintypmax_expression ')' { } ; delay_value : unsigned_number { } | NUM_REAL { } | identifier { } ; /* A.2.3 Declaration lists */ list_of_defparam_assignments : defparam_assignment { } | list_of_defparam_assignments ',' defparam_assignment { } ; list_of_dimensions: dimension { } | list_of_dimensions ',' dimension { } ; list_of_event_identifiers : event_identifier list_of_dimensions { } | list_of_event_identifiers ',' event_identifier list_of_dimensions { } ; list_of_net_decl_assignments : net_decl_assignment { HOBJECT vardecl; vardecl = verilogparseCreateVarDecl($1.key); objectRelease($1.key); verilogparseVarDeclSetAssignExpr(vardecl, $1.obj); objectRelease($1.obj); $$ = dlistCreate(); dlistAppendItem($$, vardecl); } | list_of_net_decl_assignments ',' net_decl_assignment { HOBJECT vardecl; vardecl = verilogparseCreateVarDecl($3.key); objectRelease($3.key); verilogparseVarDeclSetAssignExpr(vardecl, $3.obj); objectRelease($3.obj); $$ = $1; dlistAppendItem($$, vardecl); } ; list_of_net_identifiers : net_identifier dimension_list { HOBJECT vardecl; $$ = dlistCreate(); dlistAppendItem($$, vardecl = verilogparseCreateVarDecl($1)); verilogparseVarDeclSetDimensions(vardecl, $2); objectRelease($1); } | list_of_net_identifiers ',' net_identifier dimension_list { HOBJECT vardecl; $$ = $1; dlistAppendItem($$, vardecl = verilogparseCreateVarDecl($3)); verilogparseVarDeclSetDimensions(vardecl, $4); objectRelease($4); objectRelease($3); } ; list_of_event_identifiers : net_identifier list_of_dimensions { } | list_of_event_identifiers ',' net_identifier list_of_dimensions { } ; list_of_param_assignments : param_assignment { $$ = NULL; } | list_of_param_assignments ',' param_assignment { $$ = NULL; } ; list_of_port_identifiers : port_identifier { } | list_of_port_identifiers ',' port_identifier { } ; list_of_real_identifiers : real_type { } | list_of_real_identifiers ',' real_type { } ; list_of_specparam_assignments : specparam_assignment { } | list_of_specparam_assignments ',' specparam_assignment { } ; list_of_variable_identifiers : variable_type { } | list_of_variable_identifiers ',' variable_type { } ; port_ident : port_identifier { $$.key = $1; $$.obj = NULL; } | port_identifier '=' constant_expression { $$.key = $1; $$.obj = $3; } ; list_of_variable_port_identifiers : port_ident { } | list_of_variable_port_identifiers ',' port_ident { } ; /* A.2.4 Declaration assignments */ defparam_assignment : hierarchical_parameter_identifier '=' constant_mintypmax_expression { } ; net_decl_assignment : net_identifier '=' expression { $$.key = $1; $$.obj = $3; } | net_identifier { $$.key = $1; $$.obj = NULL; } ; param_assignment : parameter_identifier '=' constant_mintypmax_expression { $$.key = $1; $$.obj = $3; } ; specparam_assignment : specparam_identifier '=' constant_mintypmax_expression { } | pulse_control_specparam { } ; /* PATHPULSE$specify_input_terminal_descriptor$specify_output_terminal_descriptor must be: 1.PATHPULSE$identinput$identoutput 1.PATHPULSE$identinput$identoutput '[' constant_range_expression ']' 1.PATHPULSE$identinput '[' constant_range_expression ']' $identoutput 1.PATHPULSE$identinput '[' constant_range_expression ']' $identoutput '[' constant_range_expression ']' */ pulse_control_specparam_lvalue : SIMPLE_ID /* PATHPULSE$identinput$identoutput */ { } | SIMPLE_ID /* PATHPULSE$identinput$identoutput '[' constant_range_expression ']' */ '[' constant_range_expression ']' { } | SIMPLE_ID /* PATHPULSE$identinput '[' constant_range_expression ']' $identoutput*/ '[' constant_range_expression ']' SYSTEM_ID { } | SIMPLE_ID /* PATHPULSE$identinput '[' constant_range_expression ']' $identoutput '[' constant_range_expression ']'*/ '[' constant_range_expression ']' SYSTEM_ID '[' constant_range_expression ']' { } ; pulse_control_specparam : KW_PATHPULSE '=' '(' reject_limit_value ')' { } | KW_PATHPULSE '=' '(' reject_limit_value ',' error_limit_value ')' { } | pulse_control_specparam_lvalue '=' '(' reject_limit_value ')' { } | pulse_control_specparam_lvalue '=' '(' 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 */ dimension : '[' dimension_constant_expression ':' dimension_constant_expression ']' { $$.obj[0] = $2; $$.obj[1] = $4; } ; range : '[' msb_constant_expression ':' lsb_constant_expression ']' { $$.type = RANGE_TYPE_PARTSELECT; $$.obj[0] = $2; $$.obj[1] = $4; } ; /* A.2.6 Function declarations */ automatic_option : %empty { } | KW_AUTOMATIC { } ; function_range_or_type_option: %empty { } | function_range_or_type { } ; function_item_declaration_list: function_item_declaration { } | function_item_declaration_list function_item_declaration { } ; block_item_declaration_list: %empty { } | block_item_declaration { } | block_item_declaration_list block_item_declaration { } ; function_range_or_type_option : %empty { } | function_range_or_type { } ; function_declaration : KW_FUNCTION automatic_option function_range_or_type_option function_identifier ';' function_item_declaration_list function_statement KW_ENDFUNCTION { } | KW_FUNCTION automatic_option function_range_or_type_option function_identifier '(' function_port_list ')' ';' block_item_declaration_list function_statement KW_ENDFUNCTION { } ; function_item_declaration : block_item_declaration | attribute_instance_list tf_input_declaration ';' { } ; function_port_list : attribute_instance_list tf_input_declaration { } | function_port_list attribute_instance_list tf_input_declaration { } ; function_range_or_type : signed_option range_option { } | KW_INTEGER { } | KW_REAL { } | KW_REALTIME { } | KW_TIME { } ; /* A.2.7 Task declarations */ task_item_declaration_list : %empty { } | task_item_declaration_list task_item_declaration { } | task_item_declaration { } ; task_port_list_option: %empty { } | task_port_list { } ; task_declaration : KW_TASK automatic_option task_identifier ';' task_item_declaration_list statement_or_null KW_ENDTASK { } | KW_TASK automatic_option task_identifier '(' task_port_list_option ')' ';' block_item_declaration_list statement_or_null KW_ENDTASK { } ; task_item_declaration : block_item_declaration { } | attribute_instance_list tf_input_declaration ';' { } | attribute_instance_list tf_output_declaration ';' { } | attribute_instance_list tf_inout_declaration ';' { } ; task_port_list : task_port_item { } | task_port_list ',' task_port_item { } ; task_port_item : attribute_instance_list tf_input_declaration { } | attribute_instance_list tf_output_declaration { } | attribute_instance_list tf_inout_declaration { } ; reg_option : %empty { } | KW_REG { } ; tf_input_declaration : KW_INPUT reg_option signed_option range_option list_of_port_identifiers { } | KW_INPUT task_port_type list_of_port_identifiers { } ; tf_output_declaration : KW_OUTPUT reg_option signed_option range_option list_of_port_identifiers { } | KW_OUTPUT task_port_type list_of_port_identifiers { } ; tf_inout_declaration : KW_INOUT reg_option signed_option range_option list_of_port_identifiers { } | KW_INOUT task_port_type list_of_port_identifiers { } ; task_port_type : KW_INTEGER { } | KW_REAL { } | KW_REALTIME { } | KW_TIME{ } ; /* A.2.8 Block item declarations */ block_item_declaration : attribute_instance_list KW_REG signed_option range_option list_of_block_variable_identifiers ';' { } | attribute_instance_list KW_INTEGER list_of_block_variable_identifiers ';' { } | attribute_instance_list KW_TIME list_of_block_variable_identifiers ';' { } | attribute_instance_list KW_REAL list_of_block_real_identifiers ';' { } | attribute_instance_list KW_REALTIME list_of_block_real_identifiers ';' { } | attribute_instance_list event_declaration { } | attribute_instance_list local_parameter_declaration ';' { } | attribute_instance_list parameter_declaration ';' { } ; list_of_block_variable_identifiers : block_variable_type { } | list_of_block_variable_identifiers ',' block_variable_type { } ; list_of_block_real_identifiers : block_real_type { } | list_of_block_real_identifiers ',' block_real_type { } ; block_variable_type : variable_identifier dimension_list { } ; block_real_type : real_identifier dimension_list { } ; /* A.3 Primitive instances A.3.1 Primitive instantiation and instances */ cmos_switch_instance_list: cmos_switch_instance { } | cmos_switch_instance_list ',' cmos_switch_instance { } ; enable_gate_instance_list: enable_gate_instance { } | enable_gate_instance_list ',' enable_gate_instance { } ; mos_switch_instance_list: mos_switch_instance { } | mos_switch_instance_list ',' mos_switch_instance { } ; n_input_gate_instance_list: n_input_gate_instance { } | n_input_gate_instance_list ',' n_input_gate_instance { } ; n_output_gate_instance_list: n_output_gate_instance { } | n_output_gate_instance_list ',' n_output_gate_instance { } ; pass_enable_switch_instance_list: pass_enable_switch_instance { } | pass_enable_switch_instance_list ',' pass_enable_switch_instance { } ; pass_switch_instance_list: pass_switch_instance { } | pass_switch_instance_list ',' pass_switch_instance { } ; pulldown_strength_option : %empty { } | pulldown_strength { } ; pullup_strength_option : %empty { } | pullup_strength { } ; pull_gate_instance_list: pull_gate_instance { } | pull_gate_instance_list ',' pull_gate_instance { } ; delay2_option : %empty { } | delay2 { } ; gate_instantiation : cmos_switchtype delay3_option cmos_switch_instance_list ';' { } | enable_gatetype drive_strength_option delay3_option enable_gate_instance_list ';' { } | mos_switchtype delay3_option mos_switch_instance_list ';' { } | n_input_gatetype drive_strength_option delay2_option n_input_gate_instance_list ';' { } | n_output_gatetype drive_strength_option delay2_option n_output_gate_instance_list ';' { } | pass_en_switchtype delay2_option pass_enable_switch_instance_list ';' { } | pass_switchtype pass_switch_instance_list ';' { } | KW_PULLDOWN pulldown_strength_option pull_gate_instance_list ';' { } | KW_PULLUP pullup_strength_option pull_gate_instance_list ';' { } ; name_of_gate_instance_option : %empty { } | name_of_gate_instance { } ; input_terminal_list: input_terminal { } | input_terminal_list ',' input_terminal { } ; output_terminal_list: output_terminal { } | output_terminal_list ',' output_terminal { } ; cmos_switch_instance : name_of_gate_instance_option '(' output_terminal ',' input_terminal ',' ncontrol_terminal ',' pcontrol_terminal ')' { } ; enable_gate_instance : name_of_gate_instance_option '(' output_terminal ',' input_terminal ',' enable_terminal ')' { } ; mos_switch_instance : name_of_gate_instance_option '(' output_terminal ',' input_terminal ',' enable_terminal ')' { } ; n_input_gate_instance : name_of_gate_instance_option '(' output_terminal ',' input_terminal_list ')' { } ; n_output_gate_instance : name_of_gate_instance_option '(' output_terminal_list ',' input_terminal ')' { } ; pass_switch_instance : name_of_gate_instance_option '(' inout_terminal ',' inout_terminal ')' { } ; pass_enable_switch_instance : name_of_gate_instance_option '(' inout_terminal ',' inout_terminal ',' enable_terminal ')' { } ; pull_gate_instance : name_of_gate_instance_option '(' output_terminal ')' { } ; name_of_gate_instance : gate_instance_identifier range_option { } ; /* 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 : KW_CMOS { } | KW_RCMOS { } ; enable_gatetype : KW_BUFIF0 { } | KW_BUFIF1 { } | KW_NOTIF0 { } | KW_NOTIF1 { } ; mos_switchtype : KW_NMOS { } | KW_PMOS { } | KW_RNMOS { } | KW_RPMOS { } ; n_input_gatetype : KW_AND { } | KW_NAND { } | KW_OR { } | KW_NOR { } | KW_XOR { } | KW_XNOR { } ; n_output_gatetype : KW_BUF { } | KW_NOT { } ; pass_en_switchtype : KW_TRANIF0 { } | KW_TRANIF1 { } | KW_RTRANIF1 { } | KW_RTRANIF0 { } ; pass_switchtype : KW_TRAN { } | KW_RTRAN { } ; /* A.4 Module instantiation and generate construct A.4.1 Module instantiation */ parameter_value_assignment_option : %empty { $$ = dlistCreate(); } | parameter_value_assignment { $$ = $1; } ; module_instance_list: module_instance { $$ = dlistCreate(); dlistAppendItem($$, $1); } | module_instance_list ',' module_instance { $$ = $1; dlistAppendItem($$, $3); } ; module_instantiation : attribute_instance_list module_identifier parameter_value_assignment_option module_instance_list ';' { IDListVarPtr pitem, pitemtemp; if (dlistItemCount($4) > 0) { pitem = $4->__dlist_pNext; while (pitem != $4) { pitemtemp = pitem->__dlist_pNext; verilogparseSetModuleInstanceOption( pitem, //HOBJECT inst, $1, //IDListVarPtr attributes, $2, //const char * modulename, $3 //IDListVarPtr parameter_value_assignment ); pitem = pitemtemp; } verilogparseAddModuleItems(currentmodule, $4, MODULE_ITEM_TYPE_MODULE_INSTANCE); } } ; parameter_value_assignment : '#' '(' list_of_parameter_assignments ')' { $$ = $3; } ; ordered_parameter_assignment_list: ordered_parameter_assignment { $$ = dlistCreate(); dlistAppendItem($$, $1); } | ordered_parameter_assignment_list ',' ordered_parameter_assignment { $$ = $1; dlistAppendItem($$, $3); } ; named_parameter_assignment_list: named_parameter_assignment { $$ = dlistCreate(); dlistAppendItem($$, $1); } | named_parameter_assignment_list ',' named_parameter_assignment { $$ = $1; dlistAppendItem($$, $3); } ; list_of_parameter_assignments : ordered_parameter_assignment_list { int index; IDListVarPtr pitem, pitemtemp; $$ = $1; index = 0; if ($$ != NULL) { pitem = $$->__dlist_pNext; while (pitem != $$) { pitemtemp = pitem->__dlist_pNext; verilogparseSetParamInstanceIndex(pitem, index); index++; pitem = pitemtemp; } } } | named_parameter_assignment_list { $$ = $1; } ; ordered_parameter_assignment : expression { $$ = verilogparseCreateParamInstance( NULL, //const char* name, 1, //int exprcount, $1, //HOBJECT expr0, NULL, //HOBJECT expr1, NULL, //HOBJECT expr2, NULL //IDListVarPtr attributes ); } ; mintypmax_expression_option: %empty { $$.objcount = 0; } | mintypmax_expression { $$ = $1; } ; named_parameter_assignment : '.' parameter_identifier '(' mintypmax_expression_option ')' { $$ = verilogparseCreateParamInstance( $2, //const char* name, $4.objcount, //int exprcount, $4.obj[0], //HOBJECT expr0, /*用mintymax方式传参数,估计只有用在delay中才用得上了*/ $4.obj[1], //HOBJECT expr1, $4.obj[2], //HOBJECT expr2, NULL //IDListVarPtr attributes ); } ; list_of_port_connections_option: %empty { $$ = dlistCreate(); } | list_of_port_connections { $$ = $1; } ; /* module_instance : name_of_module_instance '(' list_of_port_connections_option ')' { } ; */ module_instance : module_instance_identifier range_option '(' list_of_port_connections_option ')' { $$ = verilogparseCreateModuleInstance( $1, //const char * instname, $2.type, // int range_type, $2.obj[0], //HOBJECT range_msb,这个range很奇怪,不知道如何使用 $2.obj[1], //HOBJECT range_lsb, $4 //IDListVarPtr port_connections ); } ; /* name_of_module_instance : module_instance_identifier range_option { } ; */ ordered_port_connection_list: ordered_port_connection { $$ = dlistCreate(); dlistAppendItem($$, $1); } | ordered_port_connection_list ',' ordered_port_connection { $$ = $1; dlistAppendItem($$, $3); } ; named_port_connection_list: named_port_connection { $$ = dlistCreate(); dlistAppendItem($$, $1); } | named_port_connection_list ',' named_port_connection { $$ = $1; dlistAppendItem($$, $3); } ; list_of_port_connections : ordered_port_connection_list { int index; IDListVarPtr pitem, pitemtemp; $$ = $1; index = 0; if ($$ != NULL) { pitem = $$->__dlist_pNext; while (pitem != $$) { pitemtemp = pitem->__dlist_pNext; verilogparseSetParamInstanceIndex(pitem, index); index++; pitem = pitemtemp; } } } | named_port_connection_list { $$ = $1; } ; expression_option: %empty { $$ = NULL; } | expression { $$ = $1; } ; ordered_port_connection : attribute_instance_list expression_option { $$ = verilogparseCreateParamInstance( NULL, //const char* name, 1, //int exprcount, $2, //HOBJECT expr0, NULL, //HOBJECT expr1, NULL, //HOBJECT expr2, $1 //IDListVarPtr attributes ); } ; named_port_connection : attribute_instance_list '.' port_identifier '(' expression_option ')' { $$ = verilogparseCreateParamInstance( $3, //const char* name, 1, //int exprcount, $5, //HOBJECT expr0, NULL, //HOBJECT expr1, NULL, //HOBJECT expr2, $1 //IDListVarPtr attributes ); } ; /* A.4.2 Generate construct */ module_or_generate_item_list: %empty { } | module_or_generate_item { } | module_or_generate_item_list module_or_generate_item { } ; generate_region : KW_GENERATE module_or_generate_item_list KW_ENDGENERATE { } ; genvar_declaration : KW_GENVAR list_of_genvar_identifiers ';' { } ; list_of_genvar_identifiers : genvar_identifier { } | list_of_genvar_identifiers ',' genvar_identifier { } ; loop_generate_construct : KW_FOR '(' genvar_initialization ';' genvar_expression ';' genvar_iteration ')' generate_block { } ; genvar_initialization : genvar_identifier '=' constant_expression { } ; genvar_expression : genvar_primary { } | unary_operator attribute_instance_list genvar_primary { } | genvar_expression binary_operator attribute_instance_list genvar_expression { } | genvar_expression '?' attribute_instance_list genvar_expression ':' genvar_expression { } ; genvar_iteration : genvar_identifier '=' genvar_expression { } ; genvar_primary : constant_primary { } | genvar_identifier { } ; conditional_generate_construct : if_generate_construct { } | case_generate_construct { } ; if_generate_construct : KW_IF '(' constant_expression ')' generate_block_or_null { } | KW_IF '(' constant_expression ')' generate_block_or_null KW_ELSE generate_block_or_null { } ; case_generate_item_list: case_generate_item { } | case_generate_item_list case_generate_item { } ; case_generate_construct : KW_CASE '(' constant_expression ')' case_generate_item_list KW_ENDCASE { } ; constant_expression_list: constant_expression { } | constant_expression_list constant_expression { } ; case_generate_item : constant_expression_list ':' generate_block_or_null { } | KW_DEFAULT generate_block_or_null { } | KW_DEFAULT ':' generate_block_or_null { } ; module_or_generate_item_list : %empty { } | module_or_generate_item_list module_or_generate_item { } | module_or_generate_item { } ; generate_block : module_or_generate_item { } | KW_BEGIN ':' generate_block_identifier module_or_generate_item_list KW_END { } | KW_BEGIN module_or_generate_item_list KW_END { } ; generate_block_or_null : generate_block { } | ';' { } ; /* A.5 UDP declaration and instantiation A.5.1 UDP declaration */ udp_port_declaration_list : udp_port_declaration_list udp_port_declaration { } | udp_port_declaration { } ; udp_declaration : attribute_instance_list KW_PRIMITIVE udp_identifier '(' udp_port_list ')' ';' udp_port_declaration_list udp_body KW_ENDPRIMITIVE { } | attribute_instance_list KW_PRIMITIVE udp_identifier '(' udp_declaration_port_list ')' ';' udp_body KW_ENDPRIMITIVE { } ; /* A.5.2 UDP ports */ udp_port_list : output_port_identifier ',' input_port_identifier { } | udp_port_list ',' input_port_identifier { } ; udp_declaration_port_list : udp_output_declaration ',' udp_input_declaration{ } | udp_declaration_port_list ',' udp_input_declaration { } ; udp_port_declaration : udp_output_declaration ';' { } | udp_input_declaration ';' { } | udp_reg_declaration ';' { } ; udp_output_declaration : attribute_instance_list KW_OUTPUT port_identifier { } | attribute_instance_list KW_OUTPUT KW_REG port_identifier { } | attribute_instance_list KW_OUTPUT KW_REG port_identifier '=' constant_expression { } ; udp_input_declaration : attribute_instance_list KW_INPUT list_of_port_identifiers { } ; udp_reg_declaration : attribute_instance_list KW_REG variable_identifier { } ; /* A.5.3 UDP body */ udp_body : combinational_body { } | sequential_body { } ; combinational_entry_list : combinational_entry { } | combinational_entry_list combinational_entry { } ; combinational_body : KW_TABLE combinational_entry_list KW_ENDTABLE { } ; combinational_entry : level_input_list ':' output_symbol ';' { } ; sequential_entry_list : sequential_entry { } | sequential_entry_list sequential_entry { } ; sequential_body : KW_TABLE sequential_entry_list KW_ENDTABLE { } | udp_initial_statement KW_TABLE sequential_entry_list KW_ENDTABLE { } ; udp_initial_statement : KW_INITIAL output_port_identifier '=' init_val ';' { } ; init_val : number { } ; /* 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_input_list level_symbol { } ; level_symbol_list : %empty { } | level_symbol { } | level_symbol_list level_symbol { } ; edge_input_list : level_symbol_list edge_indicator level_symbol_list { } ; edge_indicator : '(' level_symbol level_symbol ')' { } | edge_symbol { } ; current_state : level_symbol { } ; next_state : output_symbol { } | '-' { } ; output_symbol : unsigned_number { } | '?' { } | SIMPLE_ID { } ; level_symbol : unsigned_number { } | '?' { } | SIMPLE_ID { } ; edge_symbol : /* can be r,f,p,n or star in any case. */ SIMPLE_ID { } | '*' { } ; /* fixed me! 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_instance_list : udp_instance { } | udp_instance_list ',' udp_instance { } ; udp_instantiation : udp_identifier drive_strength_option delay2_option udp_instance_list ';' { } ; input_terminal_list : input_terminal { } | input_terminal_list ',' input_terminal { } ; udp_instance : name_of_udp_instance '(' output_terminal ',' input_terminal_list ')' { } | '(' output_terminal ',' input_terminal_list ')' { } ; name_of_udp_instance : udp_instance_identifier range_option { } ; /* A.6 Behavioral statements A.6.1 Continuous assignment statements */ continuous_assign : attribute_instance_list KW_ASSIGN drive_strength_option delay3_option list_of_net_assignments ';' { if (currentmodule == NULL) { yyerror("no current module"); } else { IDListVarPtr pitem, pitemtemp; pitem = $5->__dlist_pNext; while (!IsDListHeader(pitem)) { pitemtemp = pitem->__dlist_pNext; verilog_Assignment* assignment = verilogAssignmentGetData(pitem); assignment->attributes = $1; pitem = pitemtemp; } verilogparseAddModuleItems(currentmodule, $5, MODULE_ITEM_TYPE_CONTINUOUS_ASSIGNMENT); } } ; list_of_net_assignments : net_assignment { $$ = dlistCreate(); dlistAppendItem($$, $1); } | list_of_net_assignments ',' net_assignment { $$ = $1; dlistAppendItem($$, $3); } ; /* net_assignment : net_lvalue '=' expression { } ; */ net_assignment : var '=' expression { $$ = verilogparseCreateAssignment( 0, $1.obj[0], /* IDListVarPtr hierarchical_identifier */ $1.obj[1], /* IDListVarPtr element_select */ $1.type, //int range_type, 1, /* int constelementsel */ $3, /* HOBJECT expr */ NULL /* IDListVarPtr attributes */ ); } ; /* A.6.2 Procedural blocks and assignments */ initial_construct : KW_INITIAL statement { } ; always_construct : attribute_instance_list KW_ALWAYS statement { verilogparseAddModuleItems(currentmodule, $3, MODULE_ITEM_TYPE_ALWAYS_CONSTRUCT); } ; delay_or_event_control_option : %empty { } | delay_or_event_control { } ; blocking_assignment : attribute_instance_list var '=' delay_or_event_control_option expression { $$ = verilogparseCreateAssignmentStatement( TIMECONTROL_NONE, STATEMENT_BLOCKING_ASSIGNMENT, verilogparseCreateAssignment( 0, $2.obj[0], /* IDListVarPtr hierarchical_identifier */ $2.obj[1], /* IDListVarPtr element_select */ $2.type, //int range_type, 1, /* int constelementsel */ $5, /* HOBJECT expr */ $1 /* IDListVarPtr attributes */ ) ); } /* variable_lvalue '=' expression | variable_lvalue '=' delay_or_event_control_option expression { } */ ; nonblocking_assignment : attribute_instance_list var LTE delay_or_event_control_option expression { $$ = verilogparseCreateAssignmentStatement( TIMECONTROL_NONE, STATEMENT_NONBLOCKING_ASSIGNMENT, verilogparseCreateAssignment ( 1, $2.obj[0], /* IDListVarPtr hierarchical_identifier */ $2.obj[1], /* IDListVarPtr element_select */ $2.type, //int range_type, 1, /* int constelementsel */ $5, /* HOBJECT expr */ $1 /* IDListVarPtr attributes */ ) ); } /* variable_lvalue LTE delay_or_event_control_option expression { } */ ; procedural_continuous_assignments : KW_ASSIGN variable_assignment { } | KW_DEASSIGN variable_lvalue { } | KW_FORCE variable_assignment { } | KW_FORCE net_assignment { } | KW_RELEASE variable_lvalue { } | KW_RELEASE net_lvalue { } ; variable_assignment : variable_lvalue '=' expression { } ; /* A.6.3 Parallel and sequential blocks */ block_item_declaration_list: %empty { } | block_item_declaration { } | block_item_declaration_list block_item_declaration { } ; statement_list: %empty { } | statement { } | statement_list statement { } ; par_block : KW_FORK statement_list KW_JOIN { } | KW_FORK ':' block_identifier block_item_declaration_list statement_list KW_JOIN { } ; seq_block : KW_BEGIN statement_list KW_END { } | KW_BEGIN ':' block_identifier block_item_declaration_list statement_list KW_END { } ; /* A.6.4 Statements */ statement : blocking_assignment ';' { $$ = 1; } | attribute_instance_list case_statement { } | conditional_statement { } | attribute_instance_list disable_statement { } | attribute_instance_list event_trigger { } | attribute_instance_list loop_statement { } | nonblocking_assignment ';' { $$ = 1; } | attribute_instance_list par_block { } | attribute_instance_list procedural_continuous_assignments ';' { } | attribute_instance_list procedural_timing_control_statement { } | attribute_instance_list seq_block { } | attribute_instance_list system_task_enable { } | attribute_instance_list task_enable { } | attribute_instance_list wait_statement { } ; statement_or_null : statement { $$ = $1; } | attribute_instance_list ';' { /*$$ = NULL*/ } ; function_statement : statement { } ; /* A.6.5 Timing control statements */ delay_control : '#' delay_value { } | '#' '(' mintypmax_expression ')' { } ; delay_or_event_control : delay_control { } | event_control { } | KW_REPEAT '(' expression ')' event_control { } ; disable_statement : KW_DISABLE hierarchical_task_identifier ';' { } | KW_DISABLE hierarchical_block_identifier ';' { } ; event_control : '@' hierarchical_event_identifier { } | '@' '(' event_expression ')' { } | '@' '*' { } | '@' '(' '*' ')' { } ; script_list : %empty { } | '['expression ']' { } |script_list '['expression ']' { } ; event_trigger : MINUSGT hierarchical_event_identifier script_list ';' { } ; event_expression : expression { } | KW_POSEDGE expression { } | KW_NEGEDGE expression { } | event_expression KW_OR event_expression { } | event_expression ',' event_expression { } ; procedural_timing_control : delay_control { } | event_control { } ; procedural_timing_control_statement : procedural_timing_control statement_or_null { } ; wait_statement : KW_WAIT '(' expression ')' statement_or_null { } ; /* A.6.6 Conditional statements */ conditional_statement : KW_IF '(' expression ')' statement_or_null KW_ELSE statement_or_null { } | KW_IF '(' expression ')' statement_or_null { } | if_else_if_statement { } ; else_if_list: %empty { } | KW_ELSE KW_IF '(' expression ')' statement_or_null { } | else_if_list KW_ELSE KW_IF '(' expression ')' statement_or_null { } ; if_else_if_statement : KW_IF '(' expression ')' statement_or_null else_if_list KW_ELSE statement_or_null { } | KW_IF '(' expression ')' statement_or_null else_if_list { } ; /* A.6.7 Case statements */ case_item_list : case_item { } | case_item_list case_item { } ; case_type: KW_CASE { } | KW_CASEZ { } | KW_CASEX { } ; case_statement : case_type '(' expression ')' case_item_list KW_ENDCASE { } ; expression_list : expression { } | expression_list ',' expression { } ; case_item : expression_list ':' statement_or_null { } | KW_DEFAULT ':' statement_or_null { } | KW_DEFAULT statement_or_null { } ; /* A.6.8 Looping statements */ loop_statement : KW_FOREVER statement { } | KW_REPEAT '(' expression ')' statement { } | KW_WHILE '(' expression ')' statement { } | KW_FOR '(' variable_assignment ';' expression ';' variable_assignment ')' statement { } ; /* A.6.9 Task enable statements */ expression_or_null_list : %empty { } | expression { } | expression_or_null_list ',' { } | expression_or_null_list ',' expression { } ; system_task_enable : SYSTEM_ID ';' { } | SYSTEM_ID '(' expression_or_null_list ')' ';' { } ; task_enable : hierarchical_task_identifier ';' { } | hierarchical_task_identifier '(' expression_list ')' ';' { } ; /* A.7 Specify section A.7.1 Specify block declaration */ specify_item_list : %empty { } | specify_item { } | specify_item_list specify_item { } ; specify_block : KW_SPECIFY specify_item_list KW_ENDSPECIFY { } ; specify_item : specparam_declaration { } | pulsestyle_declaration { } | showcancelled_declaration { } | path_declaration { } | system_timing_check { } ; pulsestyle_declaration : KW_PULSESTYLE_ONEVENT list_of_path_outputs ';' { } | KW_PULSESTYLE_ONDETECT list_of_path_outputs ';' { } ; showcancelled_declaration : KW_SHOWCANCELLED list_of_path_outputs ';' { } | KW_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 { } ; polarity_operator_option: %empty { } | polarity_operator { } ; parallel_path_description : '(' specify_input_terminal_descriptor polarity_operator_option EQGT specify_output_terminal_descriptor ')' { } ; full_path_description : '(' list_of_path_inputs polarity_operator_option STARGT list_of_path_outputs ')' { } ; list_of_path_inputs : specify_input_terminal_descriptor { } | list_of_path_inputs ',' specify_input_terminal_descriptor { } ; list_of_path_outputs : specify_output_terminal_descriptor { } | list_of_path_outputs ',' specify_output_terminal_descriptor { } ; /* A.7.3 Specify block terminals */ specify_input_terminal_descriptor : input_identifier { } | input_identifier '[' constant_range_expression ']' { } ; specify_output_terminal_descriptor : output_identifier { } | output_identifier '[' constant_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 { } ; edge_identifier_option : %empty { } | edge_identifier { } ; polarity_operator_option : %empty { } | polarity_operator { } ; parallel_edge_sensitive_path_description : '(' edge_identifier_option specify_input_terminal_descriptor EQGT '(' specify_output_terminal_descriptor polarity_operator_option ':' data_source_expression ')' ')' { } ; full_edge_sensitive_path_description : '(' edge_identifier_option list_of_path_inputs STARGT '(' list_of_path_outputs polarity_operator_option ':' data_source_expression ')' ')' { } ; data_source_expression : expression { } ; edge_identifier : KW_POSEDGE { } | KW_NEGEDGE { } ; state_dependent_path_declaration : KW_IF '(' module_path_expression ')' simple_path_declaration { } | KW_IF '(' module_path_expression ')' edge_sensitive_path_declaration { } | KW_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 { } ; notifier_or_null : %empty { } | ',' { } | ',' notifier { } ; setup_timing_check : KW_SYS_SETUP '(' data_event ',' reference_event ',' timing_check_limit notifier_or_null ')' ';' { } ; hold_timing_check : KW_SYS_HOLD '(' reference_event ',' data_event ',' timing_check_limit notifier_or_null ')' ';' { } ; notifier_option : %empty { } | notifier { } ; stamptime_condition_option : %empty { } | stamptime_condition { } ; checktime_condition_option : %empty { } | checktime_condition { } ; delayed_reference_option : %empty { } | delayed_reference { } ; delayed_data_option : %empty { } | delayed_data { } ; setuphold_timing_check : KW_SYS_SETUPHOLD '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ')' ';' { } | KW_SYS_SETUPHOLD '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ',' notifier_option ')' ';' { } | KW_SYS_SETUPHOLD '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ',' notifier_option ',' stamptime_condition_option ')' ';' { } | KW_SYS_SETUPHOLD '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ',' notifier_option ',' stamptime_condition_option ',' checktime_condition_option ')' ';' { } | KW_SYS_SETUPHOLD '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ',' notifier_option ',' stamptime_condition_option ',' checktime_condition_option ',' delayed_reference_option ')' ';' { } | KW_SYS_SETUPHOLD '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ',' notifier_option ',' stamptime_condition_option ',' checktime_condition_option ',' delayed_reference_option ',' delayed_data_option ')' ';' { } ; recovery_timing_check : KW_SYS_RECOVERY '(' reference_event ',' data_event ',' timing_check_limit notifier_or_null ')' ';' { } ; removal_timing_check : KW_SYS_REMOVAL '(' reference_event ',' data_event ',' timing_check_limit notifier_or_null ')' ';' { } ; recrem_timing_check : KW_SYS_RECREM '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ')' ';' { } | KW_SYS_RECREM '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ',' notifier_option ')' ';' { } | KW_SYS_RECREM '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ',' notifier_option ',' stamptime_condition_option ')' ';' { } | KW_SYS_RECREM '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ',' notifier_option ',' stamptime_condition_option ',' checktime_condition_option ')' ';' { } | KW_SYS_RECREM '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ',' notifier_option ',' stamptime_condition_option ',' checktime_condition_option ',' delayed_reference_option ')' ';' { } | KW_SYS_RECREM '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ',' notifier_option ',' stamptime_condition_option ',' checktime_condition_option ',' delayed_reference_option ',' delayed_data_option ')' ';' { } ; skew_timing_check : KW_SYS_SKEW '(' reference_event ',' data_event ',' timing_check_limit notifier_or_null ')' ';' { } ; timeskew_timing_check : KW_SYS_TIMESKEW '(' reference_event ',' data_event ',' timing_check_limit ')' ';' { } | KW_SYS_TIMESKEW '(' reference_event ',' data_event ',' timing_check_limit ',' notifier_option ')' ';' { } | KW_SYS_TIMESKEW '(' reference_event ',' data_event ',' timing_check_limit ',' notifier_option ',' event_based_flag_option ')' ';' { } | KW_SYS_TIMESKEW '(' reference_event ',' data_event ',' timing_check_limit ',' notifier_option ',' event_based_flag_option ',' remain_active_flag_option ')' ';' { } ; event_based_flag_option : %empty { } | event_based_flag { } ; remain_active_flag_option : %empty { } | remain_active_flag { } ; threshold_option : %empty { } | threshold { } ; fullskew_timing_check : KW_SYS_FULLSKEW '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ')' ';' { } | KW_SYS_FULLSKEW '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ',' notifier_option ')' ';' { } | KW_SYS_FULLSKEW '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ',' notifier_option ',' event_based_flag_option ')' ';' { } | KW_SYS_FULLSKEW '(' reference_event ',' data_event ',' timing_check_limit ',' timing_check_limit ',' notifier_option ',' event_based_flag_option ',' remain_active_flag_option ')' ';' { } ; period_timing_check : KW_SYS_PERIOD '(' controlled_reference_event ',' timing_check_limit notifier_or_null ')' ';' { } ; width_timing_check : KW_SYS_WIDTH '(' controlled_reference_event ',' timing_check_limit ')' ';' { } | KW_SYS_WIDTH '(' controlled_reference_event ',' timing_check_limit ',' threshold_option ')' ';' { } | KW_SYS_WIDTH '(' controlled_reference_event ',' timing_check_limit ',' threshold_option ',' notifier_option ')' ';' { } ; nochange_timing_check : KW_SYS_NOCHANGE '(' reference_event ',' data_event ',' start_edge_offset ',' end_edge_offset notifier_or_null ')' ';' { } ; /* 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 { } ; notifier : variable_identifier { } ; reference_event : timing_check_event { } ; remain_active_flag : constant_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_control_option : %empty { } | timing_check_event_control { } ; timing_check_event : timing_check_event_control_option specify_terminal_descriptor { } | timing_check_event_control_option specify_terminal_descriptor T_AND timing_check_condition { } ; controlled_timing_check_event : timing_check_event_control specify_terminal_descriptor { } | timing_check_event_control specify_terminal_descriptor T_AND timing_check_condition { } ; timing_check_event_control : KW_POSEDGE { } | KW_NEGEDGE { } | edge_control_specifier { } ; specify_terminal_descriptor : specify_input_terminal_descriptor { } | specify_output_terminal_descriptor { } ; edge_descriptor_list: %empty { } | edge_descriptor { } | edge_descriptor_list ',' edge_descriptor { } ; edge_control_specifier : KW_EDGE edge_descriptor_list { } ; edge_descriptor : number { } ; /* fixed me edge_descriptor : 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 L_EQ scalar_constant { } | expression C_EQ scalar_constant { } | expression L_NEQ scalar_constant { } | expression C_NEQ scalar_constant { } ; scalar_constant : number { } ; /* fixedme 1'b0 | 1'b1 | 1'B0 | 1'B1 | 'b0 | 'b1 | 'B0 | 'B1 | 1 | 0 */ /* A.8 Expressions A.8.1 Concatenations */ concatenation : '{' expression_list '}' { } ; constant_expression_list : constant_expression { } | constant_expression_list ',' constant_expression { } ; constant_concatenation : '{' constant_expression_list '}' { } ; constant_multiple_concatenation : '{' constant_expression constant_concatenation '}' { } ; module_path_expression_list : module_path_expression { } | module_path_expression_list ',' module_path_expression { } ; module_path_concatenation : '{' module_path_expression_list '}' { } ; module_path_multiple_concatenation : '{' constant_expression module_path_concatenation '}' { } ; multiple_concatenation : '{' constant_expression concatenation '}' { } ; /* A.8.2 Function calls */ constant_function_call : function_identifier attribute_instance_list '(' constant_expression_list ')' { } ; system_function_identifier : SYSTEM_ID { } ; constant_system_function_call : system_function_identifier '(' constant_expression_list ')' { } ; /* function_call : hierarchical_function_identifier attribute_instance_list '(' expression_list ')' { } ; */ function_call : hierarchical_identifier attribute_instance_list '(' expression_list ')' { } ; system_function_call : system_function_identifier { } | system_function_identifier '(' expression_list ')' { } ; /* A.8.3 Expressions */ base_expression : expression { $$ = $1; } ; conditional_expression : expression '?' attribute_instance_list expression ':' expression { $$ = verilogparseCreateIfopExpr( $1, //HOBJECT expr0, $4, //HOBJECT expr1, $6, //HOBJECT expr2, $3 //IDListVarPtr attributes ); } ; constant_base_expression : constant_expression { $$ = $1; } ; unary_constant_expression : constant_primary { $$ = $1; } | unary_operator attribute_instance_list unary_constant_expression { /*规范中是unary_operator attribute_instance_list primary, 似乎有点不大对啊 */ $$ = verilogparseCreateUnopConstantExpr( $1,//int op, $3,//HOBJECT expr, $2 //IDListVarPtr attributes ); } ; pow_constant_expression : unary_constant_expression { $$ = $1; } | pow_constant_expression POW attribute_instance_list unary_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_POW, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; multiplicative_constant_expression : pow_constant_expression { $$ = $1; } | multiplicative_constant_expression '*' attribute_instance_list pow_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_MUL, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | multiplicative_constant_expression '/' attribute_instance_list pow_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_DIV, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | multiplicative_constant_expression '%' attribute_instance_list pow_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_MOD, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; additive_constant_expression : multiplicative_constant_expression { $$ = $1; } | additive_constant_expression '+' attribute_instance_list multiplicative_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_PLUS, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | additive_constant_expression '-' attribute_instance_list multiplicative_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_MINUS, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; shift_constant_expression : additive_constant_expression { $$ = $1; } | shift_constant_expression LSL attribute_instance_list additive_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_LSL, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | shift_constant_expression LSR attribute_instance_list additive_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_LSR, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | shift_constant_expression ASL attribute_instance_list additive_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_ASL, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | shift_constant_expression ASR attribute_instance_list additive_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_ASR, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; relational_constant_expression : shift_constant_expression { $$ = $1; } | relational_constant_expression '>' attribute_instance_list shift_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_GT, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | relational_constant_expression '<' attribute_instance_list shift_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_LT, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | relational_constant_expression GTE attribute_instance_list shift_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_GTE, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | relational_constant_expression LTE attribute_instance_list shift_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_LTE, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; equality_constant_expression : relational_constant_expression { $$ = $1; } | equality_constant_expression L_EQ attribute_instance_list relational_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_L_EQ, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | equality_constant_expression C_EQ attribute_instance_list relational_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_C_EQ, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | equality_constant_expression L_NEQ attribute_instance_list relational_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_L_NEQ, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | equality_constant_expression C_NEQ attribute_instance_list relational_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_C_NEQ, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; and_constant_expression : equality_constant_expression { $$ = $1; } | and_constant_expression '&' attribute_instance_list equality_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_B_AND, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | and_constant_expression B_NAND attribute_instance_list equality_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_B_NAND, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; exclusive_or_constant_expression : and_constant_expression { $$ = $1; } | exclusive_or_constant_expression '^' attribute_instance_list and_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_B_XOR, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | exclusive_or_constant_expression B_EQU attribute_instance_list and_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_B_EQU, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; inclusive_or_constant_expression : exclusive_or_constant_expression { $$ = $1; } | inclusive_or_constant_expression '|' attribute_instance_list exclusive_or_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_B_OR, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | inclusive_or_constant_expression B_NOR attribute_instance_list exclusive_or_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_B_NOR, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; logical_and_constant_expression : inclusive_or_constant_expression { $$ = $1; } | logical_and_constant_expression L_AND attribute_instance_list inclusive_or_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_L_AND, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; logical_or_constant_expression : logical_and_constant_expression { $$ = $1; } | logical_or_constant_expression L_OR attribute_instance_list logical_and_constant_expression { $$ = verilogparseCreateBinopConstantExpr( OP_L_OR, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; constant_expression : logical_or_constant_expression { $$ = $1; } | constant_expression '?' attribute_instance_list constant_expression ':' constant_expression { $$ = verilogparseCreateIfopConstantExpr( $1, //HOBJECT expr0, $4, //HOBJECT expr1, $6, //HOBJECT expr2, $3 //IDListVarPtr attributes ); } ; /* constant_expression : constant_primary { $$ = $1; } | unary_operator attribute_instance_list constant_primary { $$ = verilogparseCreateUnopExpr( $1,//int op, $3,//HOBJECT expr, $2 //IDListVarPtr attributes ); } | constant_expression binary_operator attribute_instance_list constant_expression { $$ = verilogparseCreateBinopExpr( $2, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | constant_expression '?' attribute_instance_list constant_expression ':' constant_expression { $$ = verilogparseCreateIfopExpr( $1, //HOBJECT expr0, $4, //HOBJECT expr1, $6, //HOBJECT expr2, $3 //IDListVarPtr attributes ); } ; */ constant_mintypmax_expression : constant_expression { $$ = $1; } | constant_expression ':' constant_expression ':' constant_expression { $$ = $1; } ; constant_range_expression : constant_expression { $$.type = RANGE_TYPE_BITSELECT; $$.obj[0] = $1; $$.obj[1] = NULL; } | msb_constant_expression ':' lsb_constant_expression { $$.type = RANGE_TYPE_PARTSELECT; $$.obj[0] = $1; $$.obj[1] = $3; } | constant_base_expression STARTPLUSWIDTH width_constant_expression { $$.type = RANGE_TYPE_STARTPLUSWIDTH; $$.obj[0] = $1; $$.obj[1] = $3; } | constant_base_expression STARTMINUSWIDTH width_constant_expression { $$.type = RANGE_TYPE_STARTMINUSWIDTH; $$.obj[0] = $1; $$.obj[1] = $3; } ; dimension_constant_expression : constant_expression { $$ = $1; } ; unary_expression : primary { $$ = $1; } | unary_operator attribute_instance_list unary_expression { /*规范中是unary_operator attribute_instance_list primary, 似乎有点不大对啊 */ $$ = verilogparseCreateUnopExpr( $1,//int op, $3,//HOBJECT expr, $2 //IDListVarPtr attributes ); } ; pow_expression : unary_expression { $$ = $1; } | pow_expression POW attribute_instance_list unary_expression { $$ = verilogparseCreateBinopExpr( OP_POW, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; multiplicative_expression : pow_expression { $$ = $1; } | multiplicative_expression '*' attribute_instance_list pow_expression { $$ = verilogparseCreateBinopExpr( OP_MUL, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | multiplicative_expression '/' attribute_instance_list pow_expression { $$ = verilogparseCreateBinopExpr( OP_DIV, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | multiplicative_expression '%' attribute_instance_list pow_expression { $$ = verilogparseCreateBinopExpr( OP_MOD, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; additive_expression : multiplicative_expression { $$ = $1; } | additive_expression '+' attribute_instance_list multiplicative_expression { $$ = verilogparseCreateBinopExpr( OP_PLUS, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | additive_expression '-' attribute_instance_list multiplicative_expression { $$ = verilogparseCreateBinopExpr( OP_MINUS, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; shift_expression : additive_expression { $$ = $1; } | shift_expression LSL attribute_instance_list additive_expression { $$ = verilogparseCreateBinopExpr( OP_LSL, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | shift_expression LSR attribute_instance_list additive_expression { $$ = verilogparseCreateBinopExpr( OP_LSR, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | shift_expression ASL attribute_instance_list additive_expression { $$ = verilogparseCreateBinopExpr( OP_ASL, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | shift_expression ASR attribute_instance_list additive_expression { $$ = verilogparseCreateBinopExpr( OP_ASR, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; relational_expression : shift_expression { $$ = $1; } | relational_expression '>' attribute_instance_list shift_expression { $$ = verilogparseCreateBinopExpr( OP_GT, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | relational_expression '<' attribute_instance_list shift_expression { $$ = verilogparseCreateBinopExpr( OP_LT, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | relational_expression GTE attribute_instance_list shift_expression { $$ = verilogparseCreateBinopExpr( OP_GTE, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | relational_expression LTE attribute_instance_list shift_expression { $$ = verilogparseCreateBinopExpr( OP_LTE, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; equality_expression : relational_expression { $$ = $1; } | equality_expression L_EQ attribute_instance_list relational_expression { $$ = verilogparseCreateBinopExpr( OP_L_EQ, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | equality_expression C_EQ attribute_instance_list relational_expression { $$ = verilogparseCreateBinopExpr( OP_C_EQ, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | equality_expression L_NEQ attribute_instance_list relational_expression { $$ = verilogparseCreateBinopExpr( OP_L_NEQ, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | equality_expression C_NEQ attribute_instance_list relational_expression { $$ = verilogparseCreateBinopExpr( OP_C_NEQ, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; and_expression : equality_expression { $$ = $1; } | and_expression '&' attribute_instance_list equality_expression { $$ = verilogparseCreateBinopExpr( OP_B_AND, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | and_expression B_NAND attribute_instance_list equality_expression { $$ = verilogparseCreateBinopExpr( OP_B_NAND, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; exclusive_or_expression : and_expression { $$ = $1; } | exclusive_or_expression '^' attribute_instance_list and_expression { $$ = verilogparseCreateBinopExpr( OP_B_XOR, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | exclusive_or_expression B_EQU attribute_instance_list and_expression { $$ = verilogparseCreateBinopExpr( OP_B_EQU, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; inclusive_or_expression : exclusive_or_expression { $$ = $1; } | inclusive_or_expression '|' attribute_instance_list exclusive_or_expression { $$ = verilogparseCreateBinopExpr( OP_B_OR, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | inclusive_or_expression B_NOR attribute_instance_list exclusive_or_expression { $$ = verilogparseCreateBinopExpr( OP_B_NOR, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; logical_and_expression : inclusive_or_expression { $$ = $1; } | logical_and_expression L_AND attribute_instance_list inclusive_or_expression { $$ = verilogparseCreateBinopExpr( OP_L_AND, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; logical_or_expression : logical_and_expression { $$ = $1; } | logical_or_expression L_OR attribute_instance_list logical_and_expression { $$ = verilogparseCreateBinopExpr( OP_L_OR, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } ; expression : logical_or_expression { $$ = $1; } | conditional_expression { $$ = $1; } ; /* expression : primary { $$ = $1; } | unary_operator attribute_instance_list primary { $$ = verilogparseCreateUnopExpr( $1,//int op, $3,//HOBJECT expr, $2 //IDListVarPtr attributes ); } | expression binary_operator attribute_instance_list expression { $$ = verilogparseCreateBinopExpr( $2, //int op, $1, //HOBJECT expr0, $4, //HOBJECT expr1, $3 //IDListVarPtr attributes ); } | conditional_expression { $$ = $1; } ; */ /* expression1 ::= expression expression2 ::= expression expression3 ::= expression */ lsb_constant_expression : constant_expression { $$ = $1; } ; mintypmax_expression : expression { $$.objcount = 1; $$.obj[0] = $1; } | expression ':' expression ':' expression { $$.objcount = 3; $$.obj[0] = $1; $$.obj[1] = $3; $$.obj[2] = $5; } ; module_path_conditional_expression : module_path_expression '?' attribute_instance_list module_path_expression ':' module_path_expression { } ; module_path_expression : module_path_primary { } | unary_module_path_operator attribute_instance_list module_path_primary { } | module_path_expression binary_module_path_operator attribute_instance_list 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 { $$ = $1; } ; range_expression : expression { } | constant_expression ':' lsb_constant_expression { } | expression STARTPLUSWIDTH width_constant_expression { } | expression STARTMINUSWIDTH width_constant_expression { } ; width_constant_expression : constant_expression { $$ = $1; } ; /* A.8.4 Primaries */ constant_primary : number { $$ = verilogparseCreateValueExpr( EXPRTYPE_NUMBER, //int exprtype, $1, //IConstStringVar* value, NULL //IDListVarPtr attributes ); } | parameter_identifier { $$ = verilogparseCreateParamExpr( EXPRTYPE_PARAM, //int exprtype, $1, //IConstStringVar* name, RANGE_TYPE_NONE, //int range_type, NULL, //HOBJECT range_msb, NULL, //HOBJECT range_lsb, NULL //IDListVarPtr attributes ); } | parameter_identifier '[' constant_range_expression ']' { $$ = verilogparseCreateParamExpr( EXPRTYPE_PARAM, //int exprtype, $1, //IConstStringVar* name, $3.type, //int range_type, $3.obj[0], //HOBJECT range_msb, $3.obj[1], //HOBJECT range_lsb, NULL //IDListVarPtr attributes ); } | specparam_identifier { $$ = NULL; } | specparam_identifier '[' constant_range_expression ']' { $$ = NULL; } | constant_concatenation { $$ = NULL; } | constant_multiple_concatenation { $$ = NULL; } | constant_function_call { $$ = NULL; } | constant_system_function_call { $$ = NULL; } | '(' constant_mintypmax_expression ')' { $$ = $2; } | string { $$ = verilogparseCreateValueExpr( EXPRTYPE_STRING, //int exprtype, $1, //IConstStringVar* value, NULL //IDListVarPtr attributes ); } ; module_path_primary : number { } | identifier { } | module_path_concatenation { } | module_path_multiple_concatenation { } | function_call { } | system_function_call { } | '(' module_path_mintypmax_expression ')' { } ; array_element_select : %empty { } | '[' expression ']' { } | array_element_select '[' expression ']' { } ; range_expression_option : %empty { } | '[' range_expression ']' { } ; range_expression_list : %empty { } | '[' range_expression ']' { } | range_expression_list '[' range_expression ']' { /* 此时要判断前面的作为array_element_select只能由一个表达式组成, 不能是两个表达式表示的段选择 */ } ; /* 不满足LALR(1)的文法,只能够由后期判断了 | hierarchical_identifier array_element_select range_expression_option { } hierachical_header: identifier '.' { } | identifier '[' constant_expression ']' '.' { } | hierachical_header identifier '.' { } | hierachical_header identifier '[' constant_expression ']' '.' { } ; hierarchical_identifier : hierachical_header identifier { } | identifier { } ; */ hierarchical_identifier_part : identifier { $$ = verilogparseCreateVarSel( $1, //const char * name, RANGE_TYPE_NONE, //int range_type, NULL, //HOBJECT range_msb, NULL //HOBJECT range_lsb ); } | identifier '[' expression ']' { $$ = verilogparseCreateVarSel( $1, //const char * name, RANGE_TYPE_BITSELECT, //int range_type, $3, // HOBJECT range_msb, NULL //HOBJECT range_lsb ); } | identifier '[' expression ':' expression ']' { $$ = verilogparseCreateVarSel( $1, //const char * name, RANGE_TYPE_PARTSELECT, //int range_type, $3, // HOBJECT range_msb, $5 //HOBJECT range_lsb ); } | identifier '[' expression STARTPLUSWIDTH expression ']' { $$ = verilogparseCreateVarSel( $1, //const char * name, RANGE_TYPE_STARTPLUSWIDTH, //int range_type, $3, // HOBJECT range_msb, $5 //HOBJECT range_lsb ); } | identifier '[' expression STARTMINUSWIDTH expression ']' { $$ = verilogparseCreateVarSel( $1, //const char * name, RANGE_TYPE_STARTMINUSWIDTH, //int range_type, $3, // HOBJECT range_msb, $5 //HOBJECT range_lsb ); } ; var : hierarchical_identifier { $$.type = RANGE_TYPE_NONE; $$.obj[0] = $1; $$.obj[1] = dlistCreate(); } | var '[' expression ']' { $$ = $1; $$.type = RANGE_TYPE_BITSELECT; dlistAppendItem($$.obj[1], $3); dlistAppendItem($$.obj[1], $3); } | var '[' expression ':' expression ']' { $$ = $1; $$.type = RANGE_TYPE_PARTSELECT; /*只记录最后一次的类型,反正这种情况只有最后一次才会出现*/ dlistAppendItem($$.obj[1], $3); dlistAppendItem($$.obj[1], $5); } | var '[' expression STARTPLUSWIDTH expression ']' { $$ = $1; $$.type = RANGE_TYPE_STARTPLUSWIDTH; dlistAppendItem($$.obj[1], $3); dlistAppendItem($$.obj[1], $5); } | var '[' expression STARTMINUSWIDTH expression ']' { $$ = $1; $$.type = RANGE_TYPE_STARTMINUSWIDTH; dlistAppendItem($$.obj[1], $3); dlistAppendItem($$.obj[1], $5); } ; hierarchical_identifier : hierarchical_identifier_part { $$ = dlistCreate(); dlistAppendItem($$, $1); } | hierarchical_identifier '.' hierarchical_identifier_part { $$ = $1; dlistAppendItem($$, $3); } ; /* hierarchical_identifier array_element_select range_expression_option */ primary : number { $$ = verilogparseCreateValueExpr( EXPRTYPE_NUMBER, //int exprtype, $1, //IConstStringVar* value, NULL //IDListVarPtr attributes ); } | var { $$ = verilogparseCreateVariableExpr( EXPRTYPE_HIERARCHICAL_IDENT, $1.obj[0], //IDListVarPtr hierarchical_identifier, $1.obj[1], //IDListVarPtr elementselect, $1.type, //int range_type, NULL, //HOBJECT range_msb, NULL, //HOBJECT range_lsb, NULL //IDListVarPtr attributes ); } | concatenation { $$ = NULL; yyerror("no support for concatenation"); } | multiple_concatenation { $$ = NULL; yyerror("no support for multiple_concatenation"); } | function_call{ $$ = NULL; yyerror("no support for function_call"); } | system_function_call { $$ = NULL; yyerror("no support for system_function_call"); } | '(' mintypmax_expression ')' { $$ = $2.obj[0]; if ($2.objcount > 1) { yyerror("no supprot for mintypmax_expression when objcount > 1"); } } | string { $$ = verilogparseCreateValueExpr( EXPRTYPE_STRING, //int exprtype, $1, //IConstStringVar* value, NULL //IDListVarPtr attributes ); } ; /* A.8.5 Expression left-side values */ const_array_element_select : %empty { } | '[' constant_expression ']' { } | const_array_element_select '[' constant_expression ']' { } ; constant_range_expression_option : %empty { } | range_expression { } ; net_lvalue_list : net_lvalue { } | net_lvalue_list ',' net_lvalue { } ; net_lvalue : hierarchical_net_identifier const_array_element_select constant_range_expression_option { } | '{' net_lvalue_list '}' { } ; variable_lvalue_list : variable_lvalue { } | variable_lvalue_list ',' variable_lvalue { } ; variable_lvalue : hierarchical_variable_identifier array_element_select range_expression_option { } | '{' variable_lvalue_list '}' { } ; /* A.8.6 Operators */ unary_operator : '+' { $$ = OP_PLUS; } | '-' { $$ = OP_MINUS; } | '!' { $$ = OP_L_NOT; } | '~' { $$ = OP_B_NOT; } | '&' { $$ = OP_B_AND; } | B_NAND { $$ = OP_B_NAND; } | '|' { $$ = OP_B_OR; } | B_NOR { $$ = OP_B_NOR; } | '^' { $$ = OP_B_XOR; } | B_EQU { $$ = OP_B_EQU; } ; binary_operator : '+' { $$ = OP_PLUS; } | '-' { $$ = OP_MINUS; } | '*' { $$ = OP_MUL; } | '/' { $$ = OP_DIV; } | '%' { $$ = OP_MOD; } | L_EQ { $$ = OP_L_EQ; } | L_NEQ { $$ = OP_L_NEQ; } | C_EQ { $$ = OP_C_EQ; } | C_NEQ { $$ = OP_C_NEQ; } | L_AND { $$ = OP_L_AND; } | L_OR { $$ = OP_L_OR; } | POW { $$ = OP_POW; } | '<' { $$ = OP_LT; } | LTE { $$ = OP_LTE; } | '>' { $$ = OP_GT; } | GTE { $$ = OP_GTE; } | '&' { $$ = OP_B_AND; } | '|' { $$ = OP_B_OR; } | '^' { $$ = OP_B_XOR; } | B_EQU { $$ = OP_B_EQU; } | LSR { $$ = OP_LSR; } | LSL { $$ = OP_LSL; } | ASR { $$ = OP_ASR; } | ASL { $$ = OP_ASL; } ; unary_module_path_operator : '!' { $$ = OP_L_NOT; } | '~' { $$ = OP_B_NOT; } | '&' { $$ = OP_B_AND; } | B_NAND { $$ = OP_B_NAND; } | '|' { $$ = OP_B_OR; } | B_NOR { $$ = OP_B_NOR; } | '^' { $$ = OP_B_XOR; } | B_EQU { $$ = OP_B_EQU; } ; binary_module_path_operator : L_EQ { $$ = OP_L_EQ; } | L_NEQ { $$ = OP_L_NEQ; } | L_AND { $$ = OP_L_AND; } | L_OR { $$ = OP_L_OR; } | '&' { $$ = OP_B_AND; } | '|' { $$ = OP_B_OR; } | '^' { $$ = OP_B_XOR; } | B_EQU { $$ = OP_B_EQU; } ; /* A.8.7 Numbers */ /* number ::= decimal_number | octal_number | binary_number | hex_number | real_number real_number ::= 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_number2 ::= non_zero_decimal_digit { _ | decimal_digit} unsigned_number2 ::= decimal_digit { _ | decimal_digit } binary_value2 ::= binary_digit { _ | binary_digit } octal_value2 ::= octal_digit { _ | octal_digit } hex_value2 ::= hex_digit { _ | hex_digit } decimal_base2 ::= '[s|S]d | '[s|S]D binary_base2 ::= '[s|S]b | '[s|S]B octal_base2 ::= '[s|S]o | '[s|S]O hex_base2 ::= '[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 | ? */ unsigned_number : UNSIGNED_NUMBER { $$ = $1; } ; number : NUM_REAL{ $$ = $1; } | unsigned_number { $$ = $1; } | BIN_BASE BIN_VALUE { $$ = $1; hdl4seConstStringAppend($$, conststringFromVar($2)); objectRelease($2); } | HEX_BASE HEX_VALUE { $$ = $1; hdl4seConstStringAppend($$, conststringFromVar($2)); objectRelease($2); } | OCT_BASE OCT_VALUE { $$ = $1; hdl4seConstStringAppend($$, conststringFromVar($2)); objectRelease($2); } | DEC_BASE DEC_VALUE { $$ = $1; hdl4seConstStringAppend($$, conststringFromVar($2)); objectRelease($2); } | UNSIGNED_NUMBER BIN_BASE BIN_VALUE { $$ = $1; hdl4seConstStringAppend($$, conststringFromVar($2)); hdl4seConstStringAppend($$, conststringFromVar($3)); objectRelease($2); objectRelease($3); } | UNSIGNED_NUMBER HEX_BASE HEX_VALUE { $$ = $1; hdl4seConstStringAppend($$, conststringFromVar($2)); hdl4seConstStringAppend($$, conststringFromVar($3)); objectRelease($2); objectRelease($3); } | UNSIGNED_NUMBER OCT_BASE OCT_VALUE { $$ = $1; hdl4seConstStringAppend($$, conststringFromVar($2)); hdl4seConstStringAppend($$, conststringFromVar($3)); objectRelease($2); objectRelease($3); } | UNSIGNED_NUMBER DEC_BASE DEC_VALUE{ $$ = $1; hdl4seConstStringAppend($$, conststringFromVar($2)); hdl4seConstStringAppend($$, conststringFromVar($3)); objectRelease($2); objectRelease($3); } ; /* A.8.8 Strings */ string : STRING { $$ = $1; } ; /* string ::= " { Any_ASCII_Characters_except_new_line } " */ /* A.9 General A.9.1 Attributes */ attribute_instance_list : %empty { $$ = dlistCreate(); } | attribute_instance_list attribute_instance { $$ = $1; dlistConcat($$, $2); } | attribute_instance { $$ = $1; } ; attribute_instance : ATTRIBUTE_START attribute_instance_spec_list ATTRIBUTE_END { $$ = $2; } ; attribute_instance_spec_list : attribute_instance_spec_list ',' attr_spec { $$ = $1; dlistAppendItem($$, $3); } | attr_spec { $$ = dlistCreate(); dlistAppendItem($$, $1); } ; attr_spec : attr_name { $$ = verilogparseCreateAttrSpec($1, NULL); objectRelease($1); } | attr_name '=' constant_expression { $$ = verilogparseCreateAttrSpec($1, $3); objectRelease($1); objectRelease($3); } ; attr_name : identifier { $$ = $1; } ; /* 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 */ block_identifier : identifier { } ; cell_identifier : identifier { } ; config_identifier : identifier { } ; event_identifier : identifier { } ; function_identifier : identifier { } ; gate_instance_identifier : identifier { } ; generate_block_identifier : identifier { } ; genvar_identifier : identifier { } ; hierarchical_block_identifier : hierarchical_identifier { } ; hierarchical_event_identifier : hierarchical_identifier { } ; hierarchical_function_identifier : hierarchical_identifier { } ; /* hierachical_header: identifier '.' { } | identifier '[' constant_expression ']' '.' { } | hierachical_header identifier '.' { } | hierachical_header identifier '[' constant_expression ']' '.' { } ; hierarchical_identifier : hierachical_header identifier { } | identifier { } ; */ hierarchical_net_identifier : hierarchical_identifier { } ; hierarchical_parameter_identifier : hierarchical_identifier { } ; hierarchical_variable_identifier : hierarchical_identifier { } ; hierarchical_task_identifier : hierarchical_identifier { } ; identifier : SIMPLE_ID { $$ = $1; } | ESCAPED_ID { $$ = $1; } ; inout_port_identifier : identifier { } ; input_port_identifier : identifier { } ; instance_identifier : identifier { } ; library_identifier : identifier { } ; module_identifier : identifier { $$ = $1; } ; module_instance_identifier : identifier { $$ = $1; } ; net_identifier : identifier { $$ = $1; } ; output_port_identifier : identifier { } ; parameter_identifier : identifier { $$ = $1; } ; port_identifier : identifier { $$ = $1; } ; real_identifier : identifier { } ; specparam_identifier : identifier { } ; task_identifier : identifier { } ; terminal_identifier : identifier { } ; /* handle by preprocess text_macro_identifier : identifier { } ; */ topmodule_identifier : identifier { $$ = $1; } ; udp_identifier : identifier { } ; udp_instance_identifier : identifier { } ; variable_identifier : identifier { } ; /* A.9.4 White space */ /* white_space : space { } | tab { } | newline { } | eof { } ; */ %%