diff --git a/Changes b/Changes index 488a8be50..0d1802b68 100644 --- a/Changes +++ b/Changes @@ -34,6 +34,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix not reporting some duplicate signals, bug1462. [Peter Gerst] +**** Fix --savable invalid C++ on packed arrays, bug1465. [Alex Chadwick] + * Verilator 4.014 2019-05-08 diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index baf9f5909..3cd7de0aa 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -5,6 +5,7 @@ under the Developer Certificate of Origin Please see the Verilator manual for additional contributors. Jeremy Bennett +Alex Chadwick John Coiner Kanad Kanhere Richard Myers diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 456600f94..f5462978b 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -1955,11 +1955,10 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) { else if (varp->isStatic() && varp->isConst()) {} else { int vects = 0; - // This isn't very robust and may need cleanup for other data types - for (AstUnpackArrayDType* arrayp - = VN_CAST(varp->dtypeSkipRefp(), UnpackArrayDType); + AstNodeDType* elementp = varp->dtypeSkipRefp(); + for (AstUnpackArrayDType* arrayp = VN_CAST(elementp, UnpackArrayDType); arrayp; - arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) { + arrayp = VN_CAST(elementp, UnpackArrayDType)) { int vecnum = vects++; if (arrayp->msb() < arrayp->lsb()) { varp->v3fatalSrc("Should have swapped msb & lsb earlier."); @@ -1970,19 +1969,22 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) { puts("{ int __Vi"+cvtToStr(vecnum)+"="+cvtToStr(0)+";"); puts(" for (; "+ivar+"<"+cvtToStr(arrayp->elementsConst())); puts("; ++"+ivar+") {\n"); + elementp = arrayp->subDTypep()->skipRefp(); } - if (varp->basicp() && (varp->basicp()->keyword() == AstBasicDTypeKwd::STRING - || !varp->basicp()->isWide())) { - puts("os"+op+varp->name()); - for (int v=0; vname()); - for (int v=0; vname()); - for (int v=0; vbasicp(); + if (elementp->isWide() + && !(basicp && basicp->keyword() == AstBasicDTypeKwd::STRING)) { + int vecnum = vects++; + string ivar = string("__Vi")+cvtToStr(vecnum); + puts("{ int __Vi"+cvtToStr(vecnum)+"="+cvtToStr(0)+";"); + puts(" for (; "+ivar+"<"+cvtToStr(elementp->widthWords())); + puts("; ++"+ivar+") {\n"); } + puts("os"+op+varp->name()); + for (int v=0; v