diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 64c3a40ab..511bd5eed 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -521,6 +521,9 @@ private: nodep->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference } else { + UINFO(1," Related var dtypep: "<varp()->dtypep()<v3fatalSrc("Array reference exceeds dimension of array"); frommsb = fromlsb = 0; } @@ -545,22 +548,34 @@ private: virtual void visit(AstSelBit* nodep, AstNUser* vup) { // Just a quick check as after V3Param these nodes instead are AstSel's + nodep->fromp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel + nodep->rhsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel + nodep->thsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel nodep->attrp()->iterateAndNext(*this,WidthVP(0,0,FINAL).p()); AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; } nodep->v3fatalSrc("AstSelBit should disappear after widthSel"); } virtual void visit(AstSelExtract* nodep, AstNUser* vup) { // Just a quick check as after V3Param these nodes instead are AstSel's + nodep->fromp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel + nodep->rhsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel + nodep->thsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel nodep->attrp()->iterateAndNext(*this,WidthVP(0,0,FINAL).p()); AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; } nodep->v3fatalSrc("AstSelExtract should disappear after widthSel"); } virtual void visit(AstSelPlus* nodep, AstNUser* vup) { + nodep->fromp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel + nodep->rhsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel + nodep->thsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel nodep->attrp()->iterateAndNext(*this,WidthVP(0,0,FINAL).p()); AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; } nodep->v3fatalSrc("AstSelPlus should disappear after widthSel"); } virtual void visit(AstSelMinus* nodep, AstNUser* vup) { + nodep->fromp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel + nodep->rhsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel + nodep->thsp()->iterateAndNext(*this,WidthVP(0,0,PRELIM).p()); //FINAL in AstSel nodep->attrp()->iterateAndNext(*this,WidthVP(0,0,FINAL).p()); AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; } nodep->v3fatalSrc("AstSelMinus should disappear after widthSel"); diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index a257e7607..e6bc6dfe3 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -69,32 +69,59 @@ private: } } - AstNodeDType* dtypeForExtractp(AstNode* nodep, AstNode* basefromp, int dimension, bool rangedSelect) { - // Perform error checks on the node - AstNode* errp; - AstNodeDType* bfdtypep = baseDTypeFrom(basefromp, errp/*ref*/); - //UINFO(9,"SCD\n"); if (debug()>=9) bfdtypep->dumpTree(cout,"-dtfexvar: "); - // This may be called on dotted variables before we've completed widthing of the dotted var. - AstNodeDType* ddtypep = bfdtypep; - ddtypep = ddtypep->dtypeDimensionp(dimension); - if (debug()>=9 &&ddtypep) ddtypep->dumpTree(cout,"-ddtypep: "); + // RETURN TYPE + struct FromData { + AstNode* m_errp; // Node that was found, for error reporting if not known type + AstNodeDType* m_dtypep; // Data type for the 'from' slice + VNumRange m_fromRange; // Numeric range bounds for the 'from' slice + FromData(AstNode* errp, AstNodeDType* dtypep, VNumRange fromRange) + { m_errp=errp; m_dtypep=dtypep; m_fromRange=fromRange; } + ~FromData() {} + }; + FromData fromDataForArray(AstNode* nodep, AstNode* basefromp, bool rangedSelect) { + // What is the data type and information for this SEL-ish's from()? + UINFO(9," fromData start ddtypep = "<castAttrOf()) { + basefromp = basefromp->castAttrOf()->fromp(); + continue; + } + break; + } + if (!basefromp || !basefromp->dtypep()) nodep->v3fatalSrc("Select with no from dtype"); + AstNodeDType* ddtypep = basefromp->dtypep()->skipRefp(); + AstNode* errp = ddtypep; + UINFO(9," fromData.ddtypep = "<castNodeArrayDType()) { - return adtypep; + fromRange.init(adtypep->msb(), + adtypep->lsb(), + adtypep->rangep()->littleEndian()); } else if (AstNodeClassDType* adtypep = ddtypep->castNodeClassDType()) { - return adtypep; + fromRange.init(adtypep->msb(), + adtypep->lsb(), + false); // big endian } else if (AstBasicDType* adtypep = ddtypep->castBasicDType()) { if (!adtypep->isRanged()) { - nodep->v3error("Illegal bit select; variable does not have a bit range, or bad dimension: "<prettyName()); - return NULL; + nodep->v3error("Illegal bit or array select; type does not have a bit range, or bad dimension: type is " + <prettyName()); + } else { + if (adtypep->rangep() + && (!adtypep->rangep()->msbp()->castConst() + || !adtypep->rangep()->lsbp()->castConst())) + nodep->v3fatalSrc("Non-constant variable range; errored earlier"); // in constifyParam(bfdtypep) + fromRange.init(adtypep->msb(), + adtypep->lsb(), + adtypep->littleEndian()); } - return adtypep; } else { - nodep->v3error("Illegal bit or array select; variable already selected, or bad dimension: "<prettyName()); + nodep->v3error("Illegal bit or array select; type already selected, or bad dimension: type is " + <prettyName()); } - return NULL; + return FromData(errp,ddtypep,fromRange); } AstNode* newSubNeg(AstNode* lhsp, vlsint32_t rhs) { @@ -133,47 +160,22 @@ private: return newp; } - AstNodeDType* baseDTypeFrom(AstNode* basefromp, AstNode*& errpr) { - errpr = basefromp; - if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { - AstVar* varp = varrefp->varp(); if (!varp) { varrefp->v3fatalSrc("Signal not linked"); return NULL; } - errpr = varp; - AstNodeDType* bfdtypep = varp->subDTypep(); - if (!bfdtypep) basefromp->v3fatalSrc("No datatype found for variable in select"); - return bfdtypep; - } else if (AstMemberSel* selp = basefromp->castMemberSel()) { - errpr = selp; - AstNodeDType* bfdtypep = selp->dtypep(); - if (!bfdtypep) basefromp->v3fatalSrc("No datatype found for variable in select"); - return bfdtypep; - } else { - basefromp->v3fatalSrc("Bit/array selection of non-variable"); - } - return NULL; - } - - AstNode* newSubLsbOf(AstNode* underp, AstNode* basefromp) { + AstNode* newSubLsbOf(AstNode* underp, VNumRange fromRange) { // Account for a variable's LSB in bit selections // Will likely become SUB(underp, lsb_of_signal) // Don't report WIDTH warnings etc here, as may be inside a generate branch that will be deleted - AstNode* errp; - AstNodeDType* bfdtypep = baseDTypeFrom(basefromp, errp/*ref*/); // SUB #'s Not needed when LSB==0 and MSB>=0 (ie [0:-13] must still get added!) - if (!bfdtypep->basicp()->isRanged()) { + if (!fromRange.ranged()) { // vector without range, or 0 lsb is ok, for example a INTEGER x; y = x[21:0]; return underp; } else { - if (bfdtypep->basicp()->rangep() - && (!bfdtypep->basicp()->rangep()->msbp()->castConst() - || !bfdtypep->basicp()->rangep()->lsbp()->castConst())) - bfdtypep->v3fatalSrc("Non-constant variable range; errored earlier"); // in constifyParam(bfdtypep) - if (bfdtypep->basicp()->littleEndian()) { + if (fromRange.littleEndian()) { // reg [1:3] was swapped to [3:1] (lsbEndianedp==3) and needs a SUB(3,under) - AstNode* newp = newSubNeg(bfdtypep->basicp()->msb(), underp); + AstNode* newp = newSubNeg(fromRange.msb(), underp); return newp; } else { // reg [3:1] needs a SUB(under,1) - AstNode* newp = newSubNeg(underp, bfdtypep->basicp()->lsb()); + AstNode* newp = newSubNeg(underp, fromRange.lsb()); return newp; } } @@ -186,88 +188,83 @@ private: // Select of a non-width specified part of an array, i.e. "array[2]" // This select style has a lsb and msb (no user specified width) UINFO(6,"SELBIT "<=9) nodep->backp()->dumpTree(cout,"-vsbin(-1): "); + if (debug()>=9) nodep->backp()->dumpTree(cout,"--SELBT0: "); // lhsp/rhsp do not need to be constant - AstNode* basefromp = AstArraySel::baseFromp(nodep->attrp()); - int dimension = AstArraySel::dimension(nodep->fromp()); // Not attrp as need hierarchy - AstNodeDType* ddtypep = dtypeForExtractp(nodep, basefromp, dimension, false); AstNode* fromp = nodep->lhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); // bit we're extracting - if (debug()>=9) ddtypep->dumpTree(cout,"-ddtypep: "); - if (debug()>=9) nodep->dumpTree(cout,"-vsbmd: "); - if (AstNodeArrayDType* adtypep = ddtypep->castNodeArrayDType()) { + if (debug()>=9) nodep->dumpTree(cout,"--SELBT2: "); + FromData fromdata = fromDataForArray(nodep, fromp, false); + AstNodeDType* ddtypep = fromdata.m_dtypep; + VNumRange fromRange = fromdata.m_fromRange; + if (ddtypep->castNodeArrayDType()) { // SELBIT(array, index) -> ARRAYSEL(array, index) AstNode* subp = rhsp; - if (adtypep->lsb()!=0 || adtypep->msb()<0) { - subp = newSubNeg (subp, adtypep->lsb()); + if (fromRange.lsb()!=0 || fromRange.msb()<0) { + subp = newSubNeg (subp, fromRange.lsb()); } AstArraySel* newp = new AstArraySel (nodep->fileline(), fromp, subp); - UINFO(6," newd"<=9) newp->dumpTree(cout,"--SELBTn: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } - else if (AstBasicDType* adtypep = ddtypep->castBasicDType()) { - if (adtypep) {} // unused + else if (ddtypep->castBasicDType()) { // SELBIT(range, index) -> SEL(array, index, 1) AstSel* newp = new AstSel (nodep->fileline(), fromp, - newSubLsbOf(rhsp, basefromp), + newSubLsbOf(rhsp, fromRange), // Unsized so width from user new AstConst (nodep->fileline(),AstConst::Unsized32(),1)); - UINFO(6," new "<=9) newp->dumpTree(cout,"-vsbnw: "); + UINFO(6," new "<=9) newp->dumpTree(cout,"--SELBTn: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } - else if (AstNodeClassDType* adtypep = ddtypep->castNodeClassDType()) { - if (adtypep) {} // unused + else if (ddtypep->castNodeClassDType()) { // SELBIT(range, index) -> SEL(array, index, 1) AstSel* newp = new AstSel (nodep->fileline(), fromp, - newSubLsbOf(rhsp, basefromp), + newSubLsbOf(rhsp, fromRange), // Unsized so width from user new AstConst (nodep->fileline(),AstConst::Unsized32(),1)); - UINFO(6," new "<=9) newp->dumpTree(cout,"-vsbnw: "); + UINFO(6," new "<=9) newp->dumpTree(cout,"--SELBTn: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } else { // NULL=bad extract, or unknown node type - nodep->v3error("Illegal bit or array select; variable already selected, or bad dimension"); + nodep->v3error("Illegal bit or array select; type already selected, or bad dimension: type is" + <prettyName()); // How to recover? We'll strip a dimension. nodep->replaceWith(fromp); pushDeletep(nodep); nodep=NULL; } if (!rhsp->backp()) pushDeletep(rhsp); rhsp=NULL; } - virtual void visit(AstSelExtract* nodep, AstNUser*) { // Select of a range specified part of an array, i.e. "array[2:3]" // SELEXTRACT(from,msb,lsb) -> SEL(from, lsb, 1+msb-lsb) // This select style has a (msb or lsb) and width UINFO(6,"SELEXTRACT "<=9) nodep->dumpTree(cout,"--SLEX0: "); + //if (debug()>=9) nodep->dumpTree(cout,"--SELEX0: "); // Below 2 lines may change nodep->widthp() V3Const::constifyParamsEdit(nodep->lsbp()); // May relink pointed to node V3Const::constifyParamsEdit(nodep->msbp()); // May relink pointed to node - //if (debug()>=9) nodep->dumpTree(cout,"--SLEX3: "); + //if (debug()>=9) nodep->dumpTree(cout,"--SELEX3: "); checkConstantOrReplace(nodep->lsbp(), "First value of [a:b] isn't a constant, maybe you want +: or -:"); checkConstantOrReplace(nodep->msbp(), "Second value of [a:b] isn't a constant, maybe you want +: or -:"); - AstNode* basefromp = AstArraySel::baseFromp(nodep->attrp()); - int dimension = AstArraySel::dimension(nodep->fromp()); // Not attrp as need hierarchy AstNode* fromp = nodep->lhsp()->unlinkFrBack(); AstNode* msbp = nodep->rhsp()->unlinkFrBack(); AstNode* lsbp = nodep->thsp()->unlinkFrBack(); - AstNode* errp; - AstNodeDType* bfdtypep = baseDTypeFrom(basefromp, errp/*ref*/); vlsint32_t msb = msbp->castConst()->toSInt(); vlsint32_t lsb = lsbp->castConst()->toSInt(); - AstNodeDType* ddtypep = dtypeForExtractp(nodep, basefromp, dimension, msb!=lsb); - if (AstNodeArrayDType* adtypep = ddtypep->castNodeArrayDType()) { - if (adtypep) {} + FromData fromdata = fromDataForArray(nodep, fromp, false); + AstNodeDType* ddtypep = fromdata.m_dtypep; + VNumRange fromRange = fromdata.m_fromRange; + if (ddtypep->castNodeArrayDType()) { // Slice extraction AstArraySel* newp = new AstArraySel (nodep->fileline(), fromp, lsbp); newp->start(lsb); newp->length((msb - lsb) + 1); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; - } else if (AstBasicDType* adtypep = ddtypep->castBasicDType()) { - if (adtypep) {} // Unused - if (bfdtypep->basicp()->littleEndian()) { + } else if (ddtypep->castBasicDType()) { + if (fromRange.littleEndian()) { // Below code assumes big bit endian; just works out if we swap int x = msb; msb = lsb; lsb = x; } @@ -279,13 +276,12 @@ private: msb +1-lsb); AstSel* newp = new AstSel (nodep->fileline(), fromp, - newSubLsbOf(lsbp, basefromp), + newSubLsbOf(lsbp, fromRange), widthp); UINFO(6," new "<=9) newp->dumpTree(cout,"--SLEXnew: "); + //if (debug()>=9) newp->dumpTree(cout,"--SELEXnew: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; - } else if (AstNodeClassDType* adtypep = ddtypep->castNodeClassDType()) { - if (adtypep) {} // Unused + } else if (ddtypep->castNodeClassDType()) { // Classes aren't little endian if (lsb > msb) { nodep->v3error("["<fileline(), fromp, - newSubLsbOf(lsbp, basefromp), + newSubLsbOf(lsbp, fromRange), widthp); UINFO(6," new "<=9) newp->dumpTree(cout,"--SLEXnew: "); + //if (debug()>=9) newp->dumpTree(cout,"--SELEXnew: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } else { // NULL=bad extract, or unknown node type - nodep->v3error("Illegal range select; variable already selected, or bad dimension"); + nodep->v3error("Illegal range select; type already selected, or bad dimension: type is " + <prettyName()); // How to recover? We'll strip a dimension. nodep->replaceWith(fromp); pushDeletep(nodep); nodep=NULL; } @@ -317,46 +314,48 @@ private: // This select style has a lsb and width UINFO(6,"SELPLUS/MINUS "<widthp() + if (debug()>=9) nodep->dumpTree(cout,"--SELPM0: "); V3Const::constifyParamsEdit(nodep->thsp()); // May relink pointed to node checkConstantOrReplace(nodep->thsp(), "Width of :+ or :- bit extract isn't a constant"); + if (debug()>=9) nodep->dumpTree(cout,"--SELPM3: "); // Now replace it with an AstSel - AstNode* basefromp = AstArraySel::baseFromp(nodep->attrp()); - int dimension = AstArraySel::dimension(nodep->fromp()); // Not attrp as need hierarchy AstNode* fromp = nodep->lhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNode* widthp = nodep->thsp()->unlinkFrBack(); int width = widthp->castConst()->toSInt(); if (width > (1<<28)) nodep->v3error("Width of :+ or :- is huge; vector of over 1billion bits: "<prettyName()); if (width<0) nodep->v3error("Width of :+ or :- is < 0: "<prettyName()); - AstNodeDType* ddtypep = dtypeForExtractp(nodep, basefromp, dimension, width!=1); - if (AstBasicDType* adtypep = ddtypep->castBasicDType()) { + FromData fromdata = fromDataForArray(nodep, fromp, width!=1); + AstNodeDType* ddtypep = fromdata.m_dtypep; + VNumRange fromRange = fromdata.m_fromRange; + if (ddtypep->castBasicDType()) { AstSel* newp = NULL; if (nodep->castSelPlus()) { - if (adtypep->littleEndian()) { + if (fromRange.littleEndian()) { // SELPLUS(from,lsb,width) -> SEL(from, (vector_msb-width+1)-sel, width) newp = new AstSel (nodep->fileline(), fromp, - newSubNeg((adtypep->msb()-width+1), rhsp), + newSubNeg((fromRange.msb()-width+1), rhsp), widthp); } else { // SELPLUS(from,lsb,width) -> SEL(from, lsb-vector_lsb, width) newp = new AstSel (nodep->fileline(), fromp, - newSubNeg(rhsp, adtypep->lsb()), + newSubNeg(rhsp, fromRange.lsb()), widthp); } } else if (nodep->castSelMinus()) { - if (adtypep->littleEndian()) { + if (fromRange.littleEndian()) { // SELMINUS(from,msb,width) -> SEL(from, msb-[bit]) newp = new AstSel (nodep->fileline(), fromp, - newSubNeg(adtypep->msb(), rhsp), + newSubNeg(fromRange.msb(), rhsp), widthp); } else { // SELMINUS(from,msb,width) -> SEL(from, msb-(width-1)-lsb#) newp = new AstSel (nodep->fileline(), fromp, - newSubNeg(rhsp, adtypep->lsb()+(width-1)), + newSubNeg(rhsp, fromRange.lsb()+(width-1)), widthp); } } else { @@ -366,7 +365,8 @@ private: nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } else { // NULL=bad extract, or unknown node type - nodep->v3error("Illegal +: or -: select; variable already selected, or bad dimension"); + nodep->v3error("Illegal +: or -: select; type already selected, or bad dimension: type is " + <prettyTypeName()); // How to recover? We'll strip a dimension. nodep->replaceWith(fromp); pushDeletep(nodep); nodep=NULL; } diff --git a/test_regress/t/t_bitsel_const_bad.pl b/test_regress/t/t_bitsel_const_bad.pl index 992015386..5e7afe281 100755 --- a/test_regress/t/t_bitsel_const_bad.pl +++ b/test_regress/t/t_bitsel_const_bad.pl @@ -11,9 +11,8 @@ compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> -'%Error: t/t_bitsel_const_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension: b -.* -%Error: Exiting due to.*', +'%Error: t/t_bitsel_const_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is logic +.*%Error: Exiting due to.*', ); ok(1); diff --git a/test_regress/t/t_mem_multi_ref_bad.pl b/test_regress/t/t_mem_multi_ref_bad.pl index d3bf5be21..d066d0c7f 100755 --- a/test_regress/t/t_mem_multi_ref_bad.pl +++ b/test_regress/t/t_mem_multi_ref_bad.pl @@ -11,15 +11,11 @@ compile ( fails=>$Self->{v3}, nc=>0, # Need to get it not to give the prompt expect=> -q{%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension: dimn -.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal range select; variable already selected, or bad dimension -.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension: dim0 -.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension -.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension: dim1 -.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension -.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal \+: or -: select; variable already selected, or bad dimension -.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension: dim0nv -.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension +q{%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is logic +.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is bit +.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is bit +.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal \+: or -: select; type already selected, or bad dimension: type is UNPACKARRAYDTYPE +.*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is logic .*%Error: Exiting due to.*}, ); diff --git a/test_regress/t/t_var_types_bad.pl b/test_regress/t/t_var_types_bad.pl index 69c787da0..795407c97 100755 --- a/test_regress/t/t_var_types_bad.pl +++ b/test_regress/t/t_var_types_bad.pl @@ -12,17 +12,12 @@ $Self->{verilated_randReset} = 1; # allow checking if we initialize vars to zer compile ( fails=>1, expect=> -'%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension: d_bitz -%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension -%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension: d_logicz -%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension -%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension: d_regz -%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension -%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension: d_real -%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension -%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension: d_realtime -%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; variable already selected, or bad dimension -%Error: Exiting due to.*', +'%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is bit +.*%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is logic +.*%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is logic +.*%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is real +.*%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is real +.*%Error: Exiting due to.*', ); ok(1);