From 81e806e895e132780eacab245b84a42338047ebf Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 4 Aug 2019 22:34:54 -0400 Subject: [PATCH] Fix elaboration time errors, bug1429. --- Changes | 2 ++ src/V3AstNodes.h | 29 ++++++++++++++++++++++++++++ src/V3EmitV.cpp | 3 +++ src/V3EmitXml.cpp | 5 +++++ src/V3LinkResolve.cpp | 3 --- src/V3Width.cpp | 24 +++++++++++++++++++++++ src/verilog.y | 18 ++++++++--------- test_regress/t/t_assert_comp_bad.out | 24 +++++++++++++++++------ test_regress/t/t_assert_comp_bad.pl | 4 ---- 9 files changed, 90 insertions(+), 22 deletions(-) diff --git a/Changes b/Changes index 5fc677131..4da553b37 100644 --- a/Changes +++ b/Changes @@ -14,6 +14,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Show included-from filenames in warnings, bug1439. [Todd Strader] +**** Fix elaboration time errors, bug1429. [Udi Finkelstein] + **** Fix not reporting some duplicate signals/ports, bug1462. [Peter Gerst] **** Fix not in array context on non-power-of-two slices, msg2946. [Yu Sheng Lin] diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 8ed952de9..ff398b2c1 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -2674,6 +2674,35 @@ public: void filep(AstNodeVarRef* nodep) { setNOp3p(nodep); } }; +class AstElabDisplay : public AstNode { + // Parents: stmtlist + // Children: SFORMATF to generate print string +private: + AstDisplayType m_displayType; +public: + AstElabDisplay(FileLine* fileline, AstDisplayType dispType, AstNode* exprsp) + : AstNode(fileline) { + setOp1p(new AstSFormatF(fileline, AstSFormatF::NoFormat(), exprsp)); + m_displayType = dispType; + } + ASTNODE_NODE_FUNCS(ElabDisplay) + virtual const char* broken() const { BROKEN_RTN(!fmtp()); return NULL; } + virtual string verilogKwd() const { return (string("$")+string(displayType().ascii())); } + virtual bool isGateOptimizable() const { return false; } + virtual bool isPredictOptimizable() const { return false; } + virtual bool isPure() const { return false; } // SPECIAL: $display has 'visual' ordering + virtual bool isOutputter() const { return true; } // SPECIAL: $display makes output + virtual bool isUnlikely() const { return true; } + virtual V3Hash sameHash() const { return V3Hash(displayType()); } + virtual bool same(const AstNode* samep) const { + return displayType()==static_cast(samep)->displayType(); } + virtual int instrCount() const { return instrCountPli(); } + AstDisplayType displayType() const { return m_displayType; } + void displayType(AstDisplayType type) { m_displayType = type; } + void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter + AstSFormatF* fmtp() const { return VN_CAST(op1p(), SFormatF); } +}; + class AstSFormat : public AstNodeStmt { // Parents: statement container // Children: string to load diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp index 2dd747cd4..9d248c7d1 100644 --- a/src/V3EmitV.cpp +++ b/src/V3EmitV.cpp @@ -222,6 +222,9 @@ class EmitVBaseVisitor : public EmitCBaseVisitor { virtual void visit(AstDisplay* nodep) { visitNodeDisplay(nodep, nodep->filep(), nodep->fmtp()->text(), nodep->fmtp()->exprsp()); } + virtual void visit(AstElabDisplay* nodep) { + visitNodeDisplay(nodep, NULL, nodep->fmtp()->text(), nodep->fmtp()->exprsp()); + } virtual void visit(AstFScanF* nodep) { visitNodeDisplay(nodep, nodep->filep(), nodep->text(), nodep->exprsp()); } diff --git a/src/V3EmitXml.cpp b/src/V3EmitXml.cpp index 0f1f7435e..9d202e4ed 100644 --- a/src/V3EmitXml.cpp +++ b/src/V3EmitXml.cpp @@ -180,6 +180,11 @@ class EmitXmlFileVisitor : public AstNVisitor { puts(" displaytype="); putsQuoted(nodep->verilogKwd()); outputChildrenEnd(nodep, ""); } + virtual void visit(AstElabDisplay* nodep) { + outputTag(nodep, ""); + puts(" displaytype="); putsQuoted(nodep->verilogKwd()); + outputChildrenEnd(nodep, ""); + } virtual void visit(AstExtend* nodep) { outputTag(nodep, ""); puts(" width="); putsQuoted(cvtToStr(nodep->width())); diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index f4dcc7425..61513dad4 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -404,9 +404,6 @@ private: nodep->scopeNamep(new AstScopeName(nodep->fileline())); } } - virtual void visit(AstDisplay* nodep) { - iterateChildren(nodep); - } virtual void visit(AstUdpTable* nodep) { UINFO(5,"UDPTABLE "<fmtp()); // fmtp may change + switch (nodep->displayType()) { + case AstDisplayType::DT_INFO: + nodep->v3warn(USERINFO, nodep->fmtp()->text()); + break; + case AstDisplayType::DT_ERROR: + nodep->v3warn(USERERROR, nodep->fmtp()->text()); + break; + case AstDisplayType::DT_WARNING: + nodep->v3warn(USERWARN, nodep->fmtp()->text()); + break; + case AstDisplayType::DT_FATAL: + nodep->v3warn(USERFATAL, nodep->fmtp()->text()); + break; + default: UASSERT_OBJ(false, nodep, "Unexpected elaboration display type"); + } + nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); + } + } virtual void visit(AstFOpen* nodep) { // Although a system function in IEEE, here a statement which sets the file pointer (MCD) assertAtStatement(nodep); diff --git a/src/verilog.y b/src/verilog.y index 77cf57e9c..77b490d09 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -2961,15 +2961,15 @@ elaboration_system_task: // IEEE: elaboration_system_task (1800-2009) elaboration_system_task_guts: // IEEE: part of elaboration_system_task (1800-2009) // // $fatal first argument is exit number, must be constant - yD_INFO parenE { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, NULL, NULL); } - | yD_INFO '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, NULL, $3); } - | yD_WARNING parenE { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING, NULL, NULL); } - | yD_WARNING '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING, NULL, $3); } - | yD_ERROR parenE { $$ = GRAMMARP->createDisplayError($1); } - | yD_ERROR '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_ERROR, NULL, $3); $$->addNext(new AstStop($1)); } - | yD_FATAL parenE { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, NULL, NULL); $$->addNext(new AstStop($1)); } - | yD_FATAL '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, NULL, NULL); $$->addNext(new AstStop($1)); DEL($3); } - | yD_FATAL '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, NULL, $5); $$->addNext(new AstStop($1)); DEL($3); } + yD_INFO parenE { $$ = new AstElabDisplay($1, AstDisplayType::DT_INFO, NULL); } + | yD_INFO '(' exprList ')' { $$ = new AstElabDisplay($1, AstDisplayType::DT_INFO, $3); } + | yD_WARNING parenE { $$ = new AstElabDisplay($1, AstDisplayType::DT_WARNING, NULL); } + | yD_WARNING '(' exprList ')' { $$ = new AstElabDisplay($1, AstDisplayType::DT_WARNING, $3); } + | yD_ERROR parenE { $$ = new AstElabDisplay($1, AstDisplayType::DT_ERROR, NULL); } + | yD_ERROR '(' exprList ')' { $$ = new AstElabDisplay($1, AstDisplayType::DT_ERROR, $3); } + | yD_FATAL parenE { $$ = new AstElabDisplay($1, AstDisplayType::DT_FATAL, NULL); } + | yD_FATAL '(' expr ')' { $$ = new AstElabDisplay($1, AstDisplayType::DT_FATAL, NULL); DEL($3); } + | yD_FATAL '(' expr ',' exprListE ')' { $$ = new AstElabDisplay($1, AstDisplayType::DT_FATAL, $5); DEL($3); } ; exprOrDataType: // expr | data_type: combined to prevent conflicts diff --git a/test_regress/t/t_assert_comp_bad.out b/test_regress/t/t_assert_comp_bad.out index f29e5eaf2..ec27ed155 100644 --- a/test_regress/t/t_assert_comp_bad.out +++ b/test_regress/t/t_assert_comp_bad.out @@ -1,6 +1,18 @@ -[0] -Info: t_assert_comp_bad.v:9: Assertion failed in top.t.genblk1: User compile-time info -[0] %Warning: t_assert_comp_bad.v:10: Assertion failed in top.t.genblk1: User compile-time warning -[0] %Warning: t_assert_comp_bad.v:11: Assertion failed in top.t.genblk1: 00000001 -[0] %Error: t_assert_comp_bad.v:12: Assertion failed in top.t.genblk1: User compile-time error -%Error: t/t_assert_comp_bad.v:12: Verilog $stop -Aborting... +-Info: t/t_assert_comp_bad.v:9: User compile-time info + : ... In instance t + $info("User compile-time info"); + ^~~~~ +%Warning-USERWARN: t/t_assert_comp_bad.v:10: User compile-time warning + : ... In instance t + $warning("User compile-time warning"); + ^~~~~~~~ + ... Use "/* verilator lint_off USERWARN */" and lint_on around source to disable this message. +%Warning-USERWARN: t/t_assert_comp_bad.v:11: 00000001 + : ... In instance t + $warning(1); + ^~~~~~~~ +%Warning-USERERROR: t/t_assert_comp_bad.v:12: User compile-time error + : ... In instance t + $error("User compile-time error"); + ^~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_assert_comp_bad.pl b/test_regress/t/t_assert_comp_bad.pl index 941fa8e60..27ed6fc92 100755 --- a/test_regress/t/t_assert_comp_bad.pl +++ b/test_regress/t/t_assert_comp_bad.pl @@ -13,10 +13,6 @@ compile( verilator_flags2 => ['--assert'], nc_flags2 => ['+assert'], vcs_flags2 => ['-assert svaext'], - ); - -execute( - check_finished => 0, fails => 1, expect_filename => $Self->{golden_filename}, );