diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index 8770cddd3..fca88f8fc 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -179,13 +179,11 @@ void V3ParseImp::lexErrorPreprocDirective(FileLine* fl, const char* textp) { << (suggest.empty() ? "" : fl->warnMore() + suggest)); } -void V3ParseImp::tag(const char* text) { - if (m_tagNodep) { - string tmp = text + strlen("/*verilator tag "); - string::size_type pos; - if ((pos = tmp.rfind("*/")) != string::npos) { tmp.erase(pos); } - m_tagNodep->tag(tmp); - } +string V3ParseImp::lexParseTag(const char* textp) { + string tmp = textp + strlen("/*verilator tag "); + string::size_type pos; + if ((pos = tmp.rfind("*/")) != string::npos) { tmp.erase(pos); } + return tmp; } double V3ParseImp::lexParseTimenum(const char* textp) { diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index 750d9930f..c2017dcba 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -123,7 +123,6 @@ class V3ParseImp { std::deque m_lexLintState; // Current lint state for save/restore std::deque m_ppBuffers; // Preprocessor->lex buffer of characters to process - string m_tag; // Contents (if any) of current verilator tag AstNode* m_tagNodep; // Points to the node to set to m_tag or NULL to not set. VTimescale m_timeLastUnit; // Last `timescale's unit @@ -146,7 +145,6 @@ public: static bool optFuture(const string& flag) { return v3Global.opt.isFuture(flag); } void linenoInc() { fileline()->linenoInc(); } - void tag(const char* text); void tagNodep(AstNode* nodep) { m_tagNodep = nodep; } AstNode* tagNodep() const { return m_tagNodep; } void lexTimescaleParse(FileLine* fl, const char* textp); @@ -155,6 +153,7 @@ public: VTimescale timeLastUnit() const { return m_timeLastUnit; } static void lexErrorPreprocDirective(FileLine* fl, const char* textp); + static string lexParseTag(const char* textp); static double lexParseTimenum(const char* text); void lexPpline(const char* textp); void lexVerilatorCmtLint(FileLine* fl, const char* textp, bool warnOff); diff --git a/src/verilog.l b/src/verilog.l index d1c813ed3..533ee67ba 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -709,7 +709,8 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "/*verilator sformat*/" { FL; return yVL_SFORMAT; } "/*verilator split_var*/" { FL; return yVL_SPLIT_VAR; } "/*verilator systemc_clock*/" { FL; return yVL_CLOCK; } - "/*verilator tag"[^*]*"*/" { FL_FWD; PARSEP->tag(yytext); FL_BRK; } + "/*verilator tag"[^*]*"*/" { FL; yylval.strp = PARSEP->newString(V3ParseImp::lexParseTag(yytext)); + return yVL_TAG; } "/*verilator tracing_off*/" { FL_FWD; PARSEP->fileline()->tracingOn(false); FL_BRK; } "/*verilator tracing_on*/" { FL_FWD; PARSEP->fileline()->tracingOn(true); FL_BRK; } diff --git a/src/verilog.y b/src/verilog.y index 363300c51..80faa1b9c 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -808,23 +808,24 @@ class AstSenTree; %token yVL_CLOCK "/*verilator sc_clock*/" %token yVL_CLOCKER "/*verilator clocker*/" -%token yVL_NO_CLOCKER "/*verilator no_clocker*/" %token yVL_CLOCK_ENABLE "/*verilator clock_enable*/" %token yVL_COVERAGE_BLOCK_OFF "/*verilator coverage_block_off*/" %token yVL_FULL_CASE "/*verilator full_case*/" %token yVL_INLINE_MODULE "/*verilator inline_module*/" %token yVL_ISOLATE_ASSIGNMENTS "/*verilator isolate_assignments*/" +%token yVL_NO_CLOCKER "/*verilator no_clocker*/" %token yVL_NO_INLINE_MODULE "/*verilator no_inline_module*/" %token yVL_NO_INLINE_TASK "/*verilator no_inline_task*/" -%token yVL_SC_BV "/*verilator sc_bv*/" -%token yVL_SFORMAT "/*verilator sformat*/" %token yVL_PARALLEL_CASE "/*verilator parallel_case*/" %token yVL_PUBLIC "/*verilator public*/" %token yVL_PUBLIC_FLAT "/*verilator public_flat*/" %token yVL_PUBLIC_FLAT_RD "/*verilator public_flat_rd*/" %token yVL_PUBLIC_FLAT_RW "/*verilator public_flat_rw*/" %token yVL_PUBLIC_MODULE "/*verilator public_module*/" +%token yVL_SC_BV "/*verilator sc_bv*/" +%token yVL_SFORMAT "/*verilator sformat*/" %token yVL_SPLIT_VAR "/*verilator split_var*/" +%token yVL_TAG "/*verilator tag*/" %token yP_TICK "'" %token yP_TICKBRA "'{" @@ -1246,19 +1247,25 @@ paramPortDeclOrArg: // IEEE: param_assignment + parameter_port_declaratio // // We combine the two as we can't tell which follows a comma parameter_port_declarationFrontE param_assignment { $$ = $2; } | parameter_port_declarationTypeFrontE type_assignment { $$ = $2; } + | vlTag { $$ = NULL; } ; portsStarE: // IEEE: .* + list_of_ports + list_of_port_declarations + empty - /* empty */ { $$ = NULL; } - | '(' ')' { $$ = NULL; } + /* empty */ { $$ = NULL; } + | '(' ')' { $$ = NULL; } // // .* expanded from module_declaration //UNSUP '(' yP_DOTSTAR ')' { UNSUP } | '(' {VARRESET_LIST(PORT);} list_of_ports ')' { $$ = $3; VARRESET_NONLIST(UNKNOWN); } ; list_of_ports: // IEEE: list_of_ports + list_of_port_declarations + portAndTag { $$ = $1; } + | list_of_ports ',' portAndTag { $$ = $1->addNextNull($3); } + ; + +portAndTag: port { $$ = $1; } - | list_of_ports ',' port { $$ = $1->addNextNull($3); } + | vlTag port { $$ = $2; } // Tag will associate with previous port ; port: // ==IEEE: port @@ -1866,6 +1873,7 @@ struct_union_member: // ==IEEE: struct_union_member random_qualifierE data_type_or_void /*mid*/ { GRAMMARP->m_memDTypep = $2; } // As a list follows, need to attach this dtype to each member. /*cont*/ list_of_member_decl_assignments ';' { $$ = $4; GRAMMARP->m_memDTypep = NULL; } + | vlTag { $$ = NULL; } ; list_of_member_decl_assignments: // Derived from IEEE: list_of_variable_decl_assignments @@ -2053,6 +2061,7 @@ data_declaration: // ==IEEE: data_declaration // // Therefore the virtual_interface_declaration term isn't used // // 1800-2009: //UNSUP net_type_declaration { $$ = $1; } + | vlTag { $$ = NULL; } ; class_property: // ==IEEE: class_property, which is {property_qualifier} data_declaration @@ -2178,6 +2187,10 @@ dtypeAttr: yVL_PUBLIC { $$ = new AstAttrOf($1,AstAttrType::DT_PUBLIC); } ; +vlTag: // verilator tag handling + yVL_TAG { if (PARSEP->tagNodep()) PARSEP->tagNodep()->tag(*$1); } + ; + //************************************************ // Module Items