From a1e4d676c3020b032c3b1f5fcffcca39e6a939d1 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 21 Dec 2016 18:23:14 -0500 Subject: [PATCH] Fix parsing sensitivity with &&, bug934. --- Changes | 2 ++ src/V3AstNodes.h | 6 ++++++ src/V3Clock.cpp | 6 ++++++ src/V3Const.cpp | 1 + src/V3LinkResolve.cpp | 3 ++- src/verilog.y | 5 ++--- test_regress/t/t_lint_unsup_mixed.v | 13 ++++++++++++- 7 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Changes b/Changes index 0a624315c..bf21d1ed3 100644 --- a/Changes +++ b/Changes @@ -7,6 +7,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** With --bbox-unsup, suppress desassign and mixed edges, bug1120. [Galen Seitz] +**** Fix parsing sensitivity with &&, bug934. [Luke Yang] + **** Fix internal error on double-for loop unrolling, bug1044. [Jan Egil Ruud] **** Fix internal error on unique casez with --assert, bug1117. [Enzo Chi] diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 811f453ab..0f891edf4 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -1870,6 +1870,7 @@ private: AstEdgeType m_edgeType; // Edge type public: class Combo {}; // for creator type-overload selection + class Illegal {}; // for creator type-overload selection class Initial {}; // for creator type-overload selection class Settle {}; // for creator type-overload selection class Never {}; // for creator type-overload selection @@ -1881,6 +1882,10 @@ public: : AstNodeSenItem(fl) { m_edgeType = AstEdgeType::ET_COMBO; } + AstSenItem(FileLine* fl, Illegal) + : AstNodeSenItem(fl) { + m_edgeType = AstEdgeType::ET_ILLEGAL; + } AstSenItem(FileLine* fl, Initial) : AstNodeSenItem(fl) { m_edgeType = AstEdgeType::ET_INITIAL; @@ -1906,6 +1911,7 @@ public: virtual bool isClocked() const { return edgeType().clockedStmt(); } virtual bool isCombo() const { return edgeType()==AstEdgeType::ET_COMBO; } virtual bool isInitial() const { return edgeType()==AstEdgeType::ET_INITIAL; } + virtual bool isIllegal() const { return edgeType()==AstEdgeType::ET_ILLEGAL; } virtual bool isSettle() const { return edgeType()==AstEdgeType::ET_SETTLE; } virtual bool isNever() const { return edgeType()==AstEdgeType::ET_NEVER; } bool hasVar() const { return !(isCombo()||isInitial()||isSettle()||isNever()); } diff --git a/src/V3Clock.cpp b/src/V3Clock.cpp index ce22030da..409c9364a 100644 --- a/src/V3Clock.cpp +++ b/src/V3Clock.cpp @@ -108,6 +108,12 @@ private: // HIGHEDGE: var // LOWEDGE: ~var AstNode* newp = NULL; + if (nodep->edgeType()==AstEdgeType::ET_ILLEGAL) { + if (!v3Global.opt.bboxUnsup()) { + nodep->v3error("Unsupported: Complicated event expression in sensitive activity list"); + } + return NULL; + } AstVarScope* clkvscp = nodep->varrefp()->varScopep(); if (nodep->edgeType()==AstEdgeType::ET_POSEDGE) { AstVarScope* lastVscp = getCreateLastClk(clkvscp); diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 6ac4bd823..e5ee24985 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -1554,6 +1554,7 @@ private: } else if (!m_doNConst // Deal with later when doNConst missing && (nodep->sensp()->castEnumItemRef() || nodep->sensp()->castConst())) { + } else if (nodep->isIllegal()) { // Deal with later } else { if (nodep->hasVar() && !nodep->varrefp()) nodep->v3fatalSrc("Null sensitivity variable"); } diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 72874e269..17ed29abe 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -185,7 +185,8 @@ private: } } if (!nodep->sensp()->castNodeVarRef() - && !nodep->sensp()->castEnumItemRef()) { // V3Const will cleanup + && !nodep->sensp()->castEnumItemRef() // V3Const will cleanup + && !nodep->isIllegal()) { if (debug()) nodep->dumpTree(cout,"-tree: "); nodep->v3error("Unsupported: Complex statement in sensitivity list"); } diff --git a/src/verilog.y b/src/verilog.y index f17aa8afe..4fa112a98 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -2169,15 +2169,14 @@ event_expression: // IEEE: event_expression - split over several senitem: // IEEE: part of event_expression, non-'OR' ',' terms senitemEdge { $$ = $1; } | senitemVar { $$ = $1; } - | '(' senitemVar ')' { $$ = $2; } + | '(' senitem ')' { $$ = $2; } //UNSUP expr { UNSUP } | '{' event_expression '}' { $$ = $2; } + | senitem yP_ANDAND senitem { $$ = new AstSenItem($2, AstSenItem::Illegal()); } //UNSUP expr yIFF expr { UNSUP } // Since expr is unsupported we allow and ignore constants (removed in V3Const) | yaINTNUM { $$ = NULL; } | yaFLOATNUM { $$ = NULL; } - | '(' yaINTNUM ')' { $$ = NULL; } - | '(' yaFLOATNUM ')' { $$ = NULL; } ; senitemVar: diff --git a/test_regress/t/t_lint_unsup_mixed.v b/test_regress/t/t_lint_unsup_mixed.v index c57068b59..58c66c8e7 100644 --- a/test_regress/t/t_lint_unsup_mixed.v +++ b/test_regress/t/t_lint_unsup_mixed.v @@ -6,11 +6,13 @@ module t ( input wire clk, - input wire a + input wire a, + input wire b ); integer q; + // bug1120 always @ (a or posedge clk) begin if (a) @@ -19,4 +21,13 @@ module t q = q + 1; end + // bug934 + integer qb; + always @((a && b) or posedge clk) begin + if (a) + qb = 0; + else + qb = qb + 1; + end + endmodule