本文整理汇总了C++中AstVarRef::varp方法的典型用法代码示例。如果您正苦于以下问题:C++ AstVarRef::varp方法的具体用法?C++ AstVarRef::varp怎么用?C++ AstVarRef::varp使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类AstVarRef
的用法示例。
在下文中一共展示了AstVarRef::varp方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: visit
virtual void visit(AstArraySel* nodep, AstNUser*) {
if (!m_assignp) return;
if (nodep->user3()) return; // Prevent recursion on just created nodes
unsigned dim = explicitDimensions(nodep);
AstVarRef* refp = nodep->user1p()->castNode()->castVarRef();
pair<uint32_t,uint32_t> arrDim = refp->varp()->dtypep()->dimensions(false);
uint32_t implicit = (arrDim.second) - dim;
if (implicit > 0) {
AstArraySel* newp = insertImplicit(nodep->cloneTree(false), dim+1, implicit);
nodep->replaceWith(newp); nodep = newp;
nodep->user3(true);
}
int clones = countClones(nodep);
if (m_assignp->user2() > 0 && m_assignp->user2() != clones) {
m_assignp->v3error("Slices of arrays in assignments must have the same unpacked dimensions");
} else if (!m_assignp->user2()) {
if (m_extend && clones > 1 && !m_assignError) {
m_assignp->v3error("Unsupported: Assignment between unpacked arrays of different dimensions");
m_assignError = true;
}
if (clones > 1 && !refp->lvalue() && refp->varp() == m_lhsVarRefp->varp()
&& !m_assignp->castAssignDly() && !m_assignError) {
// LHS Var != RHS Var for a non-delayed assignment
m_assignp->v3error("Unsupported: Slices in a non-delayed assignment with the same Var on both sides");
m_assignError = true;
}
m_assignp->user2(clones);
}
}
示例2: visit
virtual void visit(AstVar* nodep, AstNUser*) {
if (nodep->user2p()) {
// Make an assignment, so we'll trace it properly
// user2p is either a const or a var.
AstConst* exprconstp = nodep->user2p()->castNode()->castConst();
AstVarRef* exprvarrefp = nodep->user2p()->castNode()->castVarRef();
UINFO(8,"connectto: "<<nodep->user2p()->castNode()<<endl);
if (!exprconstp && !exprvarrefp) {
nodep->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up\n");
}
if (exprconstp) {
m_modp->addStmtp(new AstAssignW(nodep->fileline(),
new AstVarRef(nodep->fileline(), nodep, true),
exprconstp->cloneTree(true)));
} else if (nodep->user3()) {
// Public variable at the lower module end - we need to make sure we propagate
// the logic changes up and down; if we aliased, we might remove the change detection
// on the output variable.
UINFO(9,"public pin assign: "<<exprvarrefp<<endl);
if (nodep->isInput()) nodep->v3fatalSrc("Outputs only - inputs use AssignAlias");
m_modp->addStmtp(new AstAssignW(nodep->fileline(),
new AstVarRef(nodep->fileline(), exprvarrefp->varp(), true),
new AstVarRef(nodep->fileline(), nodep, false)));
} else if (nodep->isIfaceRef()) {
m_modp->addStmtp(new AstAssignVarScope(nodep->fileline(),
new AstVarRef(nodep->fileline(), nodep, true),
new AstVarRef(nodep->fileline(), exprvarrefp->varp(), false)));
AstNode* nodebp=exprvarrefp->varp();
nodep ->fileline()->modifyStateInherit(nodebp->fileline());
nodebp->fileline()->modifyStateInherit(nodep ->fileline());
} else {
// Do to inlining child's variable now within the same module, so a AstVarRef not AstVarXRef below
m_modp->addStmtp(new AstAssignAlias(nodep->fileline(),
new AstVarRef(nodep->fileline(), nodep, true),
new AstVarRef(nodep->fileline(), exprvarrefp->varp(), false)));
AstNode* nodebp=exprvarrefp->varp();
nodep ->fileline()->modifyStateInherit(nodebp->fileline());
nodebp->fileline()->modifyStateInherit(nodep ->fileline());
}
}
// Variable under the inline cell, need to rename to avoid conflicts
// Also clear I/O bits, as it is now local.
string name = m_cellp->name() + "__DOT__" + nodep->name();
if (!nodep->isFuncLocal()) nodep->inlineAttrReset(name);
if (debug()>=9) { nodep->dumpTree(cout,"varchanged:"); }
if (debug()>=9) { nodep->valuep()->dumpTree(cout,"varchangei:"); }
// Iterate won't hit AstIfaceRefDType directly as it is no longer underneath the module
if (AstIfaceRefDType* ifacerefp = nodep->dtypep()->castIfaceRefDType()) {
// Relink to point to newly cloned cell
if (ifacerefp->cellp()) {
if (AstCell* newcellp = ifacerefp->cellp()->user4p()->castNode()->castCell()) {
ifacerefp->cellp(newcellp);
ifacerefp->cellName(newcellp->name());
}
}
}
nodep->iterateChildren(*this);
}
示例3: insertImplicit
AstArraySel* insertImplicit(AstNode* nodep, unsigned start, unsigned count) {
// Insert any implicit slices as explicit slices (ArraySel nodes).
// Return a new pointer to replace nodep() in the ArraySel.
UINFO(9," insertImplicit (start="<<start<<",c="<<count<<") "<<nodep<<endl);
AstVarRef* refp = nodep->user1p()->castNode()->castVarRef();
if (!refp) nodep->v3fatalSrc("No VarRef in user1 of node "<<nodep);
AstVar* varp = refp->varp();
AstNode* topp = nodep;
for (unsigned i = start; i < start + count; ++i) {
AstNodeDType* dtypep = varp->dtypep()->dtypeDimensionp(i-1);
AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType();
if (!adtypep) nodep->v3fatalSrc("insertImplicit tried to expand an array without an ArrayDType");
vlsint32_t msb = adtypep->msb();
vlsint32_t lsb = adtypep->lsb();
if (lsb > msb) {
// Below code assumes big bit endian; just works out if we swap
int x = msb; msb = lsb; lsb = x;
}
UINFO(9," ArraySel-child: "<<topp<<endl);
AstArraySel* newp = new AstArraySel(nodep->fileline(), topp,
// "lsb-lsb": Arrays are zero-based so index 0 is always lsb
new AstConst(nodep->fileline(), lsb-lsb));
if (!newp->dtypep()) {
newp->v3fatalSrc("ArraySel dtyping failed when resolving slice"); // see ArraySel constructor
}
newp->user1p(refp);
newp->start(lsb);
newp->length(msb - lsb + 1);
topp = newp;
}
return topp->castArraySel();
}
示例4: visit
virtual void visit(AstPin* nodep, AstNUser*) {
// Check to see if any output pins have __en pins and create the __en pins to match
AstVarRef* refp = findVarRef(nodep);
if (refp && refp->lvalue() && nodep->modVarp()->user1p()) {
AstVar* enchildp = (AstVar*)nodep->modVarp()->user1p();
UINFO(9, " Pulling __en var" << enchildp << endl);
AstVar* enp = new AstVar(enchildp->fileline(),
AstVarType::OUTPUT,
enchildp->name()+cvtToStr(m_unique++),
enchildp);
enp->user2(enchildp->user2());
m_modp->addStmtp(enp);
AstPin* pinp = new AstPin(nodep->fileline(),
nodep->pinNum(),
enp->name(),
new AstVarRef(nodep->fileline(), enp, true));
AstVarRef *rp = findVarRef(pinp);
rp->replaceWith(new AstVarRef(nodep->fileline(), enp, true));
rp->deleteTree(); rp=NULL;
pinp->width(enp->width(),enp->width()); // minwidth==width
pinp->modVarp(enchildp);
m_cellp->addPinsp(pinp);
refp->user1p(enp);
refp->varp()->user1p(enp);
}
// Simplify interconnect in preperation for V3Inst
// (This could be a separate visitor, but we're in the neighborhood)
V3Inst::pinReconnectSimple(nodep, m_cellp, m_modp);
}
示例5: visit
virtual void visit(AstSel* nodep, AstNUser*) {
AstVarRef* varrefp = nodep->fromp()->castVarRef();
AstConst* constp = nodep->lsbp()->castConst();
if (varrefp && constp && !constp->num().isFourState()) {
UndrivenVarEntry* entryp = getEntryp (varrefp->varp());
int lsb = constp->toUInt();
if (m_markBoth || varrefp->lvalue()) entryp->drivenBit(lsb, nodep->width());
if (m_markBoth || !varrefp->lvalue()) entryp->usedBit(lsb, nodep->width());
} else {
// else other varrefs handled as unknown mess in AstVarRef
nodep->iterateChildren(*this);
}
}
示例6: expandUniOp
void expandUniOp(AstNodeUniop* nodep) {
nodep->user1(true);
unsigned dim = 0;
if (AstArraySel* selp = nodep->lhsp()->castArraySel()) {
// We have explicit dimensions, either packed or unpacked
dim = explicitDimensions(selp);
}
if (dim == 0 && !nodep->lhsp()->castVarRef()) {
// No ArraySel nor VarRef, not something we can expand
nodep->iterateChildren(*this);
} else {
AstVarRef* refp = findVarRefRecurse(nodep->lhsp());
ArrayDimensions varDim = refp->varp()->dtypep()->dimensions(false);
if ((int)(dim - varDim.second) < 0) {
// Unpacked dimensions are referenced first, make sure we have them all
nodep->v3error("Unary operator used across unpacked dimensions");
}
}
}
示例7: visit
virtual void visit(AstSel* nodep, AstNUser*) {
AstVarRef* varrefp = nodep->fromp()->castVarRef();
AstConst* constp = nodep->lsbp()->castConst();
if (varrefp && constp && !constp->num().isFourState()) {
for (int usr=1; usr<(m_alwaysp?3:2); ++usr) {
UndrivenVarEntry* entryp = getEntryp (varrefp->varp(), usr);
int lsb = constp->toUInt();
if (m_markBoth || varrefp->lvalue()) {
// Don't warn if already driven earlier as "a=0; if(a) a=1;" is fine.
if (usr==2 && m_alwaysp && entryp->isUsedNotDrivenBit(lsb, nodep->width())) {
UINFO(9," Select. Entryp="<<(void*)entryp<<endl);
warnAlwCombOrder(varrefp);
}
entryp->drivenBit(lsb, nodep->width());
}
if (m_markBoth || !varrefp->lvalue()) entryp->usedBit(lsb, nodep->width());
}
} else {
// else other varrefs handled as unknown mess in AstVarRef
nodep->iterateChildren(*this);
}
}
示例8: pinReconnectSimple
static AstAssignW* pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule*,
bool forTristate, bool alwaysCvt) {
// If a pin connection is "simple" leave it as-is
// Else create a intermediate wire to perform the interconnect
// Return the new assignment, if one was made
// Note this module calles cloneTree() via new AstVar
AstVar* pinVarp = pinp->modVarp();
AstVarRef* connectRefp = pinp->exprp()->castVarRef();
AstBasicDType* pinBasicp = pinVarp->dtypep()->basicp(); // Maybe NULL
AstBasicDType* connBasicp = NULL;
AstAssignW* assignp = NULL;
if (connectRefp) connBasicp = connectRefp->varp()->dtypep()->basicp();
//
if (!alwaysCvt
&& connectRefp
&& connectRefp->varp()->dtypep()->sameTree(pinVarp->dtypep())
&& !connectRefp->varp()->isSc()) { // Need the signal as a 'shell' to convert types
// Done. Same data type
} else if (!alwaysCvt
&& connectRefp
&& connectRefp->varp()->isIfaceRef()) {
// Done. Interface
} else if (!alwaysCvt
&& connBasicp
&& pinBasicp
&& connBasicp->width() == pinBasicp->width()
&& connBasicp->lsb() == pinBasicp->lsb()
&& !connectRefp->varp()->isSc() // Need the signal as a 'shell' to convert types
&& connBasicp->width() == pinVarp->width()
&& 1) {
// Done. One to one interconnect won't need a temporary variable.
} else if (!alwaysCvt && !forTristate && pinp->exprp()->castConst()) {
// Done. Constant.
} else {
// Make a new temp wire
//if (1||debug()>=9) { pinp->dumpTree(cout,"-in_pin:"); }
AstNode* pinexprp = pinp->exprp()->unlinkFrBack();
string newvarname = ((string)(pinVarp->isOutput() ? "__Vcellout" : "__Vcellinp")
+(forTristate?"t":"") // Prevent name conflict if both tri & non-tri add signals
+"__"+cellp->name()+"__"+pinp->name());
AstVar* newvarp = new AstVar (pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp);
// Important to add statement next to cell, in case there is a generate with same named cell
cellp->addNextHere(newvarp);
if (pinVarp->isInout()) {
pinVarp->v3fatalSrc("Unsupported: Inout connections to pins must be direct one-to-one connection (without any expression)");
} else if (pinVarp->isOutput()) {
// See also V3Inst
AstNode* rhsp = new AstVarRef(pinp->fileline(), newvarp, false);
UINFO(5,"pinRecon width "<<pinVarp->width()<<" >? "<<rhsp->width()<<" >? "<<pinexprp->width()<<endl);
rhsp = extendOrSel (pinp->fileline(), rhsp, pinVarp);
pinp->exprp(new AstVarRef (newvarp->fileline(), newvarp, true));
AstNode* rhsSelp = extendOrSel (pinp->fileline(), rhsp, pinexprp);
assignp = new AstAssignW (pinp->fileline(), pinexprp, rhsSelp);
} else {
// V3 width should have range/extended to make the widths correct
assignp = new AstAssignW (pinp->fileline(),
new AstVarRef(pinp->fileline(), newvarp, true),
pinexprp);
pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, false));
}
if (assignp) cellp->addNextHere(assignp);
//if (debug()) { pinp->dumpTree(cout,"- out:"); }
//if (debug()) { assignp->dumpTree(cout,"- aout:"); }
}
return assignp;
}
示例9: forUnrollCheck
bool forUnrollCheck(AstNode* nodep,
AstNode* initp, // Maybe under nodep (no nextp), or standalone (ignore nextp)
AstNode* precondsp, AstNode* condp,
AstNode* incp, // Maybe under nodep or in bodysp
AstNode* bodysp) {
// To keep the IF levels low, we return as each test fails.
UINFO(4, " FOR Check "<<nodep<<endl);
if (initp) UINFO(6, " Init "<<initp<<endl);
if (precondsp) UINFO(6, " Pcon "<<precondsp<<endl);
if (condp) UINFO(6, " Cond "<<condp<<endl);
if (incp) UINFO(6, " Inc "<<incp<<endl);
// Initial value check
AstAssign* initAssp = initp->castAssign();
if (!initAssp) return cantUnroll(nodep, "no initial assignment");
if (initp->nextp() && initp->nextp()!=nodep) nodep->v3fatalSrc("initial assignment shouldn't be a list");
if (!initAssp->lhsp()->castVarRef()) return cantUnroll(nodep, "no initial assignment to simple variable");
m_forVarp = initAssp->lhsp()->castVarRef()->varp();
m_forVscp = initAssp->lhsp()->castVarRef()->varScopep();
if (nodep->castGenFor() && !m_forVarp->isGenVar()) {
nodep->v3error("Non-genvar used in generate for: "<<m_forVarp->name()<<endl);
}
if (m_generate) V3Const::constifyParamsEdit(initAssp->rhsp()); // rhsp may change
AstConst* constInitp = initAssp->rhsp()->castConst();
if (!constInitp) return cantUnroll(nodep, "non-constant initializer");
//
// Condition check
if (condp->nextp()) nodep->v3fatalSrc("conditional shouldn't be a list");
//
// Assignment of next value check
AstAssign* incAssp = incp->castAssign();
if (!incAssp) return cantUnroll(nodep, "no increment assignment");
if (incAssp->nextp()) nodep->v3fatalSrc("increment shouldn't be a list");
AstNodeBiop* incInstrp = incAssp->rhsp()->castNodeBiop();
//
if (m_forVscp) { UINFO(8, " Loop Variable: "<<m_forVscp<<endl); }
else { UINFO(8, " Loop Variable: "<<m_forVarp<<endl); }
if (debug()>=9) nodep->dumpTree(cout,"- for: ");
//
// Extract the constant loop bounds
bool subtract = incInstrp->castSub();
{
if (!subtract && !incInstrp->castAdd()) return cantUnroll(nodep, "missing add/sub for incrementer");
AstVarRef* incVarrp = (subtract ? incInstrp->lhsp()->castVarRef()
: incInstrp->rhsp()->castVarRef());
if (!incVarrp) return cantUnroll(nodep, "missing variable in incrementer");
if (incVarrp->varp() != m_forVarp
|| incVarrp->varScopep() != m_forVscp) {
return cantUnroll(nodep, "different variables in incrementer");
}
}
//
// Adds have the # on the lhsp because V3Const pushes rhs consts over to the lhs
// Subtracts have it on the rhs, because you write i=i-1; i=1-i is non-sensible.
AstConst* preconstIncp = (subtract ? incInstrp->rhsp()->castConst()
: incInstrp->lhsp()->castConst());
if (m_generate) preconstIncp = V3Const::constifyParamsEdit(preconstIncp)->castConst();
AstConst* constIncp = (subtract ? incInstrp->rhsp()->castConst()
: incInstrp->lhsp()->castConst());
UINFO(8, " Inc expr ok: "<<constIncp<<endl);
if (!constIncp) return cantUnroll(nodep, "non-constant increment");
if (constIncp->isZero()) return cantUnroll(nodep, "zero increment"); // Or we could loop forever below...
bool lt = condp->castLt() || condp->castLtS();
bool lte = condp->castLte() || condp->castLteS();
bool gt = condp->castGt() || condp->castGtS();
bool gte = condp->castGte() || condp->castGteS();
if (!lt && !lte && !gt && !gte)
return cantUnroll(nodep, "condition not <= or <");
AstNodeBiop* condBip = condp->castNodeBiop();
if (!condBip->lhsp()->castVarRef())
return cantUnroll(nodep, "no variable on lhs of condition");
if (condBip->lhsp()->castVarRef()->varp() != m_forVarp
|| condBip->lhsp()->castVarRef()->varScopep() != m_forVscp)
return cantUnroll(nodep, "different variable in condition");
if (m_generate) V3Const::constifyParamsEdit(condBip->rhsp()); // rhsp may change
AstConst* constStopp = condBip->rhsp()->castConst();
if (!constStopp) return cantUnroll(nodep, "non-constant final value");
UINFO(8, " Stop expr ok: "<<constStopp<<endl);
//
if (constInitp->width()>32 || constInitp->num().isFourState()
|| constStopp->width()>32 || constStopp->num().isFourState()
|| constIncp->width()>32 || constIncp->num().isFourState())
return cantUnroll(nodep, "init/final/increment too large or four state");
vlsint32_t valInit = constInitp->num().toSInt();
vlsint32_t valStop = constStopp->num().toSInt();
if (lte) valStop++; if (gte) valStop--;
vlsint32_t valInc = constIncp->num().toSInt();
if (subtract) valInc = -valInc;
UINFO(8," In Numbers: for (v="<<valInit<<"; v<"<<valStop<<"; v=v+"<<valInc<<")\n");
//
if (!m_generate) {
int loops = ((valStop - valInit)/valInc);
if (loops < 0) { loops += (1ULL<<constStopp->width()); } // Will roll around
UINFO(8, " ~Iters: "<<loops<<" c="<<unrollCount()<<endl);
if (loops > unrollCount())
return cantUnroll(nodep, "too many iterations");
// Less than 10 statements in the body?
int bodySize = 0;
int bodyLimit = v3Global.opt.unrollStmts();
//.........这里部分代码省略.........
示例10: AstVarRef
void V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule* modp) {
// If a pin connection is "simple" leave it as-is
// Else create a intermediate wire to perform the interconnect
// Note this module calles cloneTree() via new AstVar
AstVar* pinVarp = pinp->modVarp();
AstVarRef* connectRefp = pinp->exprp()->castVarRef();
AstBasicDType* pinBasicp = pinVarp->dtypep()->basicp(); // Maybe NULL
AstBasicDType* connBasicp = NULL;
if (connectRefp) connBasicp = connectRefp->varp()->dtypep()->basicp();
//
if (connectRefp
&& connectRefp->varp()->dtypep()->sameTree(pinVarp->dtypep())
&& !connectRefp->varp()->isSc()) { // Need the signal as a 'shell' to convert types
// Done. Same data type
} else if (connBasicp
&& pinBasicp
&& connBasicp->width() == pinBasicp->width()
&& connBasicp->lsb() == pinBasicp->lsb()
&& !connectRefp->varp()->isSc() // Need the signal as a 'shell' to convert types
&& pinp->width() == pinVarp->width()
&& 1) {
// Done. One to one interconnect won't need a temporary variable.
} else if (pinp->exprp()->castConst()) {
// Done. Constant.
} else {
// Make a new temp wire
//if (1||debug()>=9) { pinp->dumpTree(cout,"in_pin:"); }
AstAssignW* assignp = NULL;
AstNode* pinexprp = pinp->exprp()->unlinkFrBack();
string newvarname = "__Vcellinp__"+cellp->name()+"__"+pinp->name();
AstVar* newvarp = new AstVar (pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp);
modp->addStmtp(newvarp);
if (pinVarp->isInout()) {
pinVarp->v3fatalSrc("Unsupported: Inout connections to pins must be direct one-to-one connection (without any expression)");
} else if (pinVarp->isOutput()) {
// See also V3Inst
AstNode* rhsp = new AstVarRef(pinp->fileline(), newvarp, false);
if (pinp->width() > rhsp->width()) {
if (rhsp->isSigned()) {
rhsp = new AstExtendS(pinp->fileline(), rhsp);
} else {
rhsp = new AstExtend (pinp->fileline(), rhsp);
}
} else if (pinp->width() < rhsp->width()) {
rhsp = new AstSel (pinp->fileline(), rhsp, 0, pinp->width());
}
rhsp->widthSignedFrom(pinp);
assignp = new AstAssignW (pinp->fileline(), pinexprp, rhsp);
pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, true));
} else {
// V3 width should have range/extended to make the widths correct
if (pinexprp->width() != pinVarp->width()) pinp->v3fatalSrc("Input pin width mismatch");
assignp = new AstAssignW (pinp->fileline(),
new AstVarRef(pinp->fileline(), newvarp, true),
pinexprp);
pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, false));
}
pinp->widthSignedFrom(pinp->exprp());
if (assignp) modp->addStmtp(assignp);
//if (1||debug()) { pinp->dumpTree(cout," out:"); }
//if (1||debug()) { assignp->dumpTree(cout," aout:"); }
}
}
示例11: createDlyArray
AstNode* createDlyArray(AstAssignDly* nodep, AstNode* lhsp) {
// Create delayed assignment
// See top of this file for transformation
// Return the new LHS for the assignment, Null = unlink
// Find selects
AstNode* newlhsp = NULL; // NULL = unlink old assign
AstSel* bitselp = NULL;
AstArraySel* arrayselp = NULL;
if (lhsp->castSel()) {
bitselp = lhsp->castSel();
arrayselp = bitselp->fromp()->castArraySel();
} else {
arrayselp = lhsp->castArraySel();
}
if (!arrayselp) nodep->v3fatalSrc("No arraysel under bitsel?");
if (arrayselp->length()!=1) nodep->v3fatalSrc("ArraySel with length!=1 should have been removed in V3Slice");
UINFO(4,"AssignDlyArray: "<<nodep<<endl);
//
//=== Dimensions: __Vdlyvdim__
deque<AstNode*> dimvalp; // Assignment value for each dimension of assignment
AstNode* dimselp=arrayselp;
for (; dimselp->castArraySel(); dimselp=dimselp->castArraySel()->fromp()) {
AstNode* valp = dimselp->castArraySel()->bitp()->unlinkFrBack();
dimvalp.push_front(valp);
}
AstVarRef* varrefp = dimselp->castVarRef();
if (!varrefp) nodep->v3fatalSrc("No var underneath arraysels\n");
if (!varrefp->varScopep()) varrefp->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n");
varrefp->unlinkFrBack();
AstVar* oldvarp = varrefp->varp();
int modVecNum = oldvarp->user4(); oldvarp->user4(modVecNum+1);
//
deque<AstNode*> dimreadps; // Read value for each dimension of assignment
for (unsigned dimension=0; dimension<dimvalp.size(); dimension++) {
AstNode* dimp = dimvalp[dimension];
if (dimp->castConst()) { // bit = const, can just use it
dimreadps.push_front(dimp);
} else {
string bitvarname = (string("__Vdlyvdim")+cvtToStr(dimension)
+"__"+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
AstVarScope* bitvscp = createVarSc(varrefp->varScopep(), bitvarname, dimp->width());
AstAssign* bitassignp
= new AstAssign (nodep->fileline(),
new AstVarRef(nodep->fileline(), bitvscp, true),
dimp);
nodep->addNextHere(bitassignp);
dimreadps.push_front(new AstVarRef(nodep->fileline(), bitvscp, false));
}
}
//
//=== Bitselect: __Vdlyvlsb__
AstNode* bitreadp=NULL; // Code to read Vdlyvlsb
if (bitselp) {
AstNode* lsbvaluep = bitselp->lsbp()->unlinkFrBack();
if (bitselp->fromp()->castConst()) {// vlsb = constant, can just push constant into where we use it
bitreadp = lsbvaluep;
} else {
string bitvarname = (string("__Vdlyvlsb__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
AstVarScope* bitvscp = createVarSc(varrefp->varScopep(), bitvarname, lsbvaluep->width());
AstAssign* bitassignp = new AstAssign (nodep->fileline(),
new AstVarRef(nodep->fileline(), bitvscp, true),
lsbvaluep);
nodep->addNextHere(bitassignp);
bitreadp = new AstVarRef(nodep->fileline(), bitvscp, false);
}
}
//
//=== Value: __Vdlyvval__
AstNode* valreadp; // Code to read Vdlyvval
if (nodep->rhsp()->castConst()) { // vval = constant, can just push constant into where we use it
valreadp = nodep->rhsp()->unlinkFrBack();
} else {
string valvarname = (string("__Vdlyvval__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
AstVarScope* valvscp = createVarSc(varrefp->varScopep(), valvarname, nodep->rhsp()->width());
newlhsp = new AstVarRef(nodep->fileline(), valvscp, true);
valreadp = new AstVarRef(nodep->fileline(), valvscp, false);
}
//
//=== Setting/not setting boolean: __Vdlyvset__
AstVarScope* setvscp;
AstAssignPre* setinitp = NULL;
if (nodep->user3p()) {
// Simplistic optimization. If the previous statement in same scope was also a =>,
// then we told this nodep->user3 we can use its Vdlyvset rather than making a new one.
// This is good for code like:
// for (i=0; i<5; i++) vector[i] <= something;
setvscp = nodep->user3p()->castNode()->castVarScope();
++m_statSharedSet;
} else { // Create new one
string setvarname = (string("__Vdlyvset__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
setvscp = createVarSc(varrefp->varScopep(), setvarname, 1);
setinitp = new AstAssignPre (nodep->fileline(),
new AstVarRef(nodep->fileline(), setvscp, true),
new AstConst(nodep->fileline(), 0));
AstAssign* setassignp
= new AstAssign (nodep->fileline(),
new AstVarRef(nodep->fileline(), setvscp, true),
new AstConst(nodep->fileline(),
//.........这里部分代码省略.........