From 6ac672b4a38b388acd55bdc23ead4d45a9e37bf8 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 25 Feb 2015 21:09:55 -0500 Subject: [PATCH] Fix SystemC arrayed bit vectors, bug886. --- Changes | 2 ++ src/V3AstNodes.cpp | 21 +++++++++++++++++++++ src/V3AstNodes.h | 1 + src/V3Cast.cpp | 1 + src/V3EmitC.cpp | 11 +++++------ src/V3Expand.cpp | 11 ++++------- src/V3Premit.cpp | 2 +- test_regress/t/t_var_pinsizes.v | 11 +++++++++-- 8 files changed, 44 insertions(+), 16 deletions(-) diff --git a/Changes b/Changes index 280c1bd40..0554b1360 100644 --- a/Changes +++ b/Changes @@ -7,6 +7,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix comma-instantiations with parameters, bug884. [Franck Jullien] +**** Fix SystemC arrayed bit vectors, bug886. [David Poole] + * Verilator 3.870 2015-02-12 diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 751540893..ed0907d27 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -350,6 +350,27 @@ string AstVar::scType() const { } } +AstVar* AstVar::scVarRecurse(AstNode* nodep) { + // See if this is a SC assignment; if so return that type + // Historically sc variables are identified by a variable + // attribute. TODO it would better be a data type attribute. + if (AstVar* anodep = nodep->castVar()) { + if (anodep->isSc()) return anodep; + else return NULL; + } + else if (nodep->castVarRef()) { + if (nodep->castVarRef()->varp()->isSc()) return nodep->castVarRef()->varp(); + else return NULL; + } + else if (nodep->castArraySel()) { + if (nodep->op1p()) if (AstVar* p = scVarRecurse(nodep->op1p())) return p; + if (nodep->op2p()) if (AstVar* p = scVarRecurse(nodep->op2p())) return p; + if (nodep->op3p()) if (AstVar* p = scVarRecurse(nodep->op3p())) return p; + if (nodep->op4p()) if (AstVar* p = scVarRecurse(nodep->op4p())) return p; + } + return NULL; +} + AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) { // dimension passed from AstArraySel::dimension // Dimension 0 means the VAR itself, 1 is the closest SEL to the AstVar, diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index d88790c65..999c90abb 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -1132,6 +1132,7 @@ public: if (varType()==AstVarType::INOUT) m_varType = AstVarType::TRIWIRE; if (varType()==AstVarType::INPUT || varType()==AstVarType::OUTPUT) m_varType = AstVarType::WIRE; } + static AstVar* scVarRecurse(AstNode* nodep); }; class AstDefParam : public AstNode { diff --git a/src/V3Cast.cpp b/src/V3Cast.cpp index 75a4b2a94..fbf7ead5d 100644 --- a/src/V3Cast.cpp +++ b/src/V3Cast.cpp @@ -149,6 +149,7 @@ private: if (!nodep->lvalue() && !nodep->backp()->castCCast() && nodep->backp()->castNodeMath() + && !nodep->backp()->castArraySel() && nodep->backp()->width() && castSize(nodep) != castSize(nodep->varp())) { // Cast vars to IData first, else below has upper bits wrongly set diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index b307a4792..4f9bd928b 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -83,6 +83,7 @@ public: : nodep->isQuad() ? "Q" : "I"); } void emitScIQW(AstVar* nodep) { + if (!nodep->isSc()) nodep->v3fatalSrc("emitting SystemC operator on non-SC variable"); puts (nodep->isScBigUint() ? "SB" : nodep->isScUint() ? "SU" : nodep->isScBv() ? "SW" @@ -155,19 +156,17 @@ public: selp->lsbp()->iterateAndNext(*this); puts(", "); selp->fromp()->iterateAndNext(*this); puts(", "); } - } else if (nodep->lhsp()->castVarRef() - && nodep->lhsp()->castVarRef()->varp()->isSc()) { + } else if (AstVar* varp = AstVar::scVarRecurse(nodep->lhsp())) { putbs("VL_ASSIGN_"); // Set a systemC variable - emitScIQW(nodep->lhsp()->castVarRef()->varp()); + emitScIQW(varp); emitIQW(nodep); puts("("); puts(cvtToStr(nodep->widthMin())+","); nodep->lhsp()->iterateAndNext(*this); puts(", "); - } else if (nodep->rhsp()->castVarRef() - && nodep->rhsp()->castVarRef()->varp()->isSc()) { + } else if (AstVar* varp = AstVar::scVarRecurse(nodep->rhsp())) { putbs("VL_ASSIGN_"); // Get a systemC variable emitIQW(nodep); - emitScIQW(nodep->rhsp()->castVarRef()->varp()); + emitScIQW(varp); puts("("); puts(cvtToStr(nodep->widthMin())+","); nodep->lhsp()->iterateAndNext(*this); puts(", "); diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp index 12932ee52..5863d8409 100644 --- a/src/V3Expand.cpp +++ b/src/V3Expand.cpp @@ -874,16 +874,13 @@ private: nodep->iterateChildren(*this); bool did = false; if (nodep->isWide() && ((nodep->lhsp()->castVarRef() - && !nodep->lhsp()->castVarRef()->varp()->isSc()) - || nodep->lhsp()->castArraySel())) { + || nodep->lhsp()->castArraySel())) + && !AstVar::scVarRecurse(nodep->lhsp()) // Need special function for SC + && !AstVar::scVarRecurse(nodep->rhsp())) { if (AstConst* rhsp = nodep->rhsp()->castConst()) { did = expandWide(nodep,rhsp); } else if (AstVarRef* rhsp = nodep->rhsp()->castVarRef()) { - if (rhsp->varp()->isSc()) { - // Still need special access function - } else { - did = expandWide(nodep,rhsp); - } + did = expandWide(nodep,rhsp); } else if (AstSel* rhsp = nodep->rhsp()->castSel()) { did = expandWide(nodep,rhsp); } else if (AstArraySel* rhsp = nodep->rhsp()->castArraySel()) { diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index 3a92aafaa..88e2dbee9 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -124,7 +124,7 @@ private: bool assignNoTemp(AstNodeAssign* nodep) { return (nodep->lhsp()->castVarRef() - && !nodep->lhsp()->castVarRef()->varp()->isSc() + && !AstVar::scVarRecurse(nodep->lhsp()) && nodep->rhsp()->castConst()); } void checkNode(AstNode* nodep) { diff --git a/test_regress/t/t_var_pinsizes.v b/test_regress/t/t_var_pinsizes.v index 8db1d550e..f6ad839f5 100644 --- a/test_regress/t/t_var_pinsizes.v +++ b/test_regress/t/t_var_pinsizes.v @@ -8,9 +8,9 @@ module t (/*AUTOARG*/ // Outputs - o1, o8, o16, o32, o64, o65, o128, o513, obv1, obv16, + o1, o8, o16, o32, o64, o65, o128, o513, o1a2, o94a3, obv1, obv16, // Inputs - clk, i1, i8, i16, i32, i64, i65, i128, i513, ibv1, ibv16 + clk, i1, i8, i16, i32, i64, i65, i128, i513, i1a2, i94a3, ibv1, ibv16 ); input clk; @@ -23,6 +23,9 @@ module t (/*AUTOARG*/ input [64:0] i65; input [127:0] i128; input [512:0] i513; + input i1a2 [1:0]; + input [93:0] i94a3 [2:0]; + output o1; output [7:0] o8; @@ -32,6 +35,8 @@ module t (/*AUTOARG*/ output [64:0] o65; output [127:0] o128; output [512:0] o513; + output o1a2 [1:0]; + output [93:0] o94a3 [2:0]; input [0:0] ibv1 /*verilator sc_bv*/; input [15:0] ibv16 /*verilator sc_bv*/; @@ -50,6 +55,8 @@ module t (/*AUTOARG*/ o513 <= i513; obv1 <= ibv1; obv16 <= ibv16; + o1a2 <= i1a2; + o94a3 <= i94a3; end endmodule