diff --git a/Changes b/Changes index bc1d5c5df..b4f984768 100644 --- a/Changes +++ b/Changes @@ -4,6 +4,8 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 4.201 devel +**** Verilated signals now use VlWide and VlPacked in place of C arrays. + * Verilator 4.200 2021-03-12 diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 0575b1826..53341c960 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -635,6 +635,7 @@ string AstNodeDType::cType(const string& name, bool forFunc, bool isRef) const { } AstNodeDType::CTypeRecursed AstNodeDType::cTypeRecurse(bool compound) const { + // Legacy compound argument currently just passed through and unused CTypeRecursed info; const AstNodeDType* dtypep = this->skipRefp(); @@ -656,14 +657,9 @@ AstNodeDType::CTypeRecursed AstNodeDType::cTypeRecurse(bool compound) const { } else if (const auto* adtypep = VN_CAST_CONST(dtypep, UnpackArrayDType)) { if (adtypep->isCompound()) compound = true; const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(compound); - if (compound) { - info.m_type = "VlUnpacked<" + sub.m_type; - info.m_type += ", " + cvtToStr(adtypep->declRange().elements()); - info.m_type += ">"; - } else { - info.m_type = sub.m_type; - info.m_dims = "[" + cvtToStr(adtypep->declRange().elements()) + "]" + sub.m_dims; - } + info.m_type = "VlUnpacked<" + sub.m_type; + info.m_type += ", " + cvtToStr(adtypep->declRange().elements()); + info.m_type += ">"; } else if (const AstBasicDType* bdtypep = dtypep->basicp()) { // We don't print msb()/lsb() as multidim packed would require recursion, // and may confuse users as C++ data is stored always with bit 0 used @@ -687,12 +683,7 @@ AstNodeDType::CTypeRecursed AstNodeDType::cTypeRecurse(bool compound) const { } else if (dtypep->isQuad()) { info.m_type = "QData" + bitvec; } else if (dtypep->isWide()) { - if (compound) { - info.m_type = "VlWide<" + cvtToStr(dtypep->widthWords()) + ">"; - } else { - info.m_type += "WData" + bitvec; // []'s added later - info.m_dims = "[" + cvtToStr(dtypep->widthWords()) + "]"; - } + info.m_type = "VlWide<" + cvtToStr(dtypep->widthWords()) + ">" + bitvec; } } else { v3fatalSrc("Unknown data type in var type emitter: " << dtypep->prettyName()); diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 0a1416f1d..d231f37d5 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -104,6 +104,12 @@ public: : (nodep->isScQuad() ? "SQ" : "SI")); // clang-format on } + void emitDatap(AstNode* nodep) { + // When passing to a function with va_args the compiler doesn't + // know need a pointer so when wide, need to look inside VlWide + if (nodep->isWide()) puts(".data()"); + } + void emitOpName(AstNode* nodep, const string& format, AstNode* lhsp, AstNode* rhsp, AstNode* thsp); void emitDeclArrayBrackets(const AstVar* nodep) { @@ -376,9 +382,6 @@ public: iterateAndNextNull(nodep->bitp()); } puts(")"); - if (nodep->dtypep()->isWide()) { - puts(".data()"); // Access returned std::array as C array - } } virtual void visit(AstNodeCCall* nodep) override { if (AstCMethodCall* ccallp = VN_CAST(nodep, CMethodCall)) { @@ -415,12 +418,6 @@ public: comma = true; } puts(")"); - // if there is a return value that is wide convert to array - if (nodep->dtypep()->isWide() - && (VN_IS(nodep->fromp()->dtypep(), QueueDType) - || VN_IS(nodep->fromp()->dtypep(), DynArrayDType))) { - puts(".data()"); // Access returned std::array as C array - } // Some are statements some are math. if (nodep->isStatement()) puts(";\n"); UASSERT_OBJ(!nodep->isStatement() || VN_IS(nodep->dtypep(), VoidDType), nodep, @@ -653,7 +650,12 @@ public: putbs(", "); emitCvtPackStr(nodep->filenamep()); putbs(", "); - iterateAndNextNull(nodep->memp()); + { + const bool need_ptr = !VN_IS(nodep->memp()->dtypep(), AssocArrayDType); + if (need_ptr) puts(" &("); + iterateAndNextNull(nodep->memp()); + if (need_ptr) puts(")"); + } putbs(", "); if (nodep->lsbp()) { iterateAndNextNull(nodep->lsbp()); @@ -709,7 +711,6 @@ public: puts("VL_FREAD_I("); puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width putbs(","); - bool memory = false; uint32_t array_lo = 0; uint32_t array_size = 0; { @@ -719,7 +720,6 @@ public: } else if (VN_CAST(varrefp->varp()->dtypeSkipRefp(), BasicDType)) { } else if (const AstUnpackArrayDType* adtypep = VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) { - memory = true; array_lo = adtypep->lo(); array_size = adtypep->elementsConst(); } else { @@ -731,9 +731,9 @@ public: putbs(","); puts(cvtToStr(array_size)); putbs(", "); - if (!memory) puts("&("); + puts("&("); iterateAndNextNull(nodep->memp()); - if (!memory) puts(")"); + puts(")"); putbs(", "); iterateAndNextNull(nodep->filep()); putbs(", "); @@ -2193,17 +2193,11 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) { if (func != "") { puts(func); } else if (argp) { - if (isScan) { - puts("&("); - } else if (fmt == '@') { - puts("&("); - } + bool addrof = isScan || (fmt == '@'); + if (addrof) puts("&("); iterate(argp); - if (isScan) { - puts(")"); - } else if (fmt == '@') { - puts(")"); - } + if (!addrof) emitDatap(argp); + if (addrof) puts(")"); } ofp()->indentDec(); }