virtual void visit(AstNodeClassDType* nodep, AstNUser*) { if (m_traVscp) { if (nodep->packed() && !v3Global.opt.traceStructs()) { // Everything downstream is packed, so deal with as one trace unit // This may not be the nicest for user presentation, but is a much faster way to trace addTraceDecl(VNumRange()); } else { if (!nodep->packed()) { addIgnore("Unsupported: Unpacked struct/union"); } else { for (AstMemberDType* itemp = nodep->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) { AstNodeDType* subtypep = itemp->subDTypep()->skipRefp(); string oldShowname = m_traShowname; AstNode* oldValuep = m_traValuep; { m_traShowname += string(" ")+itemp->prettyName(); if (nodep->castStructDType()) { m_traValuep = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true), itemp->lsb(), subtypep->width()); subtypep->accept(*this); m_traValuep->deleteTree(); m_traValuep = NULL; } else { // Else union, replicate fields subtypep->accept(*this); } } m_traShowname = oldShowname; m_traValuep = oldValuep; } } } } }
virtual void visit(AstPackArrayDType* nodep, AstNUser*) { if (m_traVscp) { if (!v3Global.opt.traceStructs()) { // Everything downstream is packed, so deal with as one trace unit // This may not be the nicest for user presentation, but is a much faster way to trace addTraceDecl(VNumRange()); } else { AstNodeDType* subtypep = nodep->subDTypep()->skipRefp(); for (int i=nodep->lsb(); i<=nodep->msb(); ++i) { string oldShowname = m_traShowname; AstNode* oldValuep = m_traValuep; { m_traShowname += string("(")+cvtToStr(i)+string(")"); m_traValuep = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true), (i - nodep->lsb())*subtypep->width(), subtypep->width()); subtypep->accept(*this); m_traValuep->deleteTree(); m_traValuep = NULL; } m_traShowname = oldShowname; m_traValuep = oldValuep; } } } }
virtual void visit(AstUnpackArrayDType* nodep, AstNUser*) { // Note more specific dtypes above if (m_traVscp) { if ((int)nodep->arrayUnpackedElements() > v3Global.opt.traceMaxArray()) { addIgnore("Wide memory > --trace-max-array ents"); } else if (nodep->subDTypep()->skipRefp()->castBasicDType() // Nothing lower than this array && m_traVscp->dtypep()->skipRefp() == nodep) { // Nothing above this array // Simple 1-D array, use exising V3EmitC runtime loop rather than unrolling // This will put "(index)" at end of signal name for us addTraceDecl(nodep->declRange()); } else { // Unroll now, as have no other method to get right signal names AstNodeDType* subtypep = nodep->subDTypep()->skipRefp(); for (int i=nodep->lsb(); i<=nodep->msb(); ++i) { string oldShowname = m_traShowname; AstNode* oldValuep = m_traValuep; { m_traShowname += string("(")+cvtToStr(i)+string(")"); m_traValuep = new AstArraySel(nodep->fileline(), m_traValuep->cloneTree(true), i - nodep->lsb()); subtypep->accept(*this); m_traValuep->deleteTree(); m_traValuep = NULL; } m_traShowname = oldShowname; m_traValuep = oldValuep; } } } }