本文整理汇总了C++中AstNode::castVarRef方法的典型用法代码示例。如果您正苦于以下问题:C++ AstNode::castVarRef方法的具体用法?C++ AstNode::castVarRef怎么用?C++ AstNode::castVarRef使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类AstNode
的用法示例。
在下文中一共展示了AstNode::castVarRef方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: visit
// VISITORS
virtual void visit(AstNodeVarRef* nodep, AstNUser*) {
if (nodep->varScopep() == m_elimVarScp) {
// Substitute in the new tree
// It's possible we substitute into something that will be reduced more later
// however, as we never delete the top Always/initial statement, all should be well.
m_didReplace = true;
if (nodep->lvalue()) nodep->v3fatalSrc("Can't replace lvalue assignments with const var");
AstNode* substp = m_replaceTreep->cloneTree(false);
if (nodep->castNodeVarRef()
&& substp->castNodeVarRef()
&& nodep->same(substp)) {
// Prevent a infinite loop...
substp->v3fatalSrc("Replacing node with itself; perhaps circular logic?");
}
// Which fileline() to use?
// If replacing with logic, an error/warning is likely to want to point to the logic
// IE what we're replacing with.
// However a VARREF should point to the original as it's otherwise confusing
// to throw warnings that point to a PIN rather than where the pin us used.
if (substp->castVarRef()) substp->fileline(nodep->fileline());
// Make the substp an rvalue like nodep. This facilitate the hashing in dedupe.
if (AstNodeVarRef* varrefp = substp->castNodeVarRef()) varrefp->lvalue(false);
nodep->replaceWith(substp);
nodep->deleteTree(); VL_DANGLING(nodep);
}
}
示例2: visit
virtual void visit(AstPin* nodep, AstNUser*) {
// Any non-direct pins need reconnection with a part-select
if (!nodep->exprp()) return; // No-connect
if (m_cellRangep) {
UINFO(4," PIN "<<nodep<<endl);
int pinwidth = nodep->modVarp()->width();
int expwidth = nodep->exprp()->width();
if (expwidth == pinwidth) {
// NOP: Arrayed instants: widths match so connect to each instance
} else if (expwidth == pinwidth*m_cellRangep->elementsConst()) {
// Arrayed instants: one bit for each of the instants (each assign is 1 pinwidth wide)
AstNode* exprp = nodep->exprp()->unlinkFrBack();
bool inputPin = nodep->modVarp()->isInput();
if (!inputPin && !exprp->castVarRef()
&& !exprp->castConcat() // V3Const will collapse the SEL with the one we're about to make
&& !exprp->castSel()) { // V3Const will collapse the SEL with the one we're about to make
nodep->v3error("Unsupported: Per-bit array instantiations with output connections to non-wires.");
// Note spec allows more complicated matches such as slices and such
}
exprp = new AstSel (exprp->fileline(), exprp,
pinwidth*(m_instNum-m_instLsb),
pinwidth);
nodep->exprp(exprp);
} else {
nodep->v3fatalSrc("Width mismatch; V3Width should have errored out.");
}
}
}
示例3: visit
//*******************************************************************
// The following visitor functions deal with detecting Z's in the
// logic, stripping the Z's out and creating an __en signal and its
// logic.
//*******************************************************************
virtual void visit(AstPull* nodep, AstNUser*) {
// replace any pullup/pulldowns with assignw logic and an __en
// signal just like it is any other tristate signal. The only
// difference is that the user2() variable on the __en signal
// will be given a pull direction--i.e. pulldown=1, pullup=2.
// This will signal the driver exansion logic to put a default
// pullup or pulldown state on the tristate bus under the high-Z
// condition when no one is driving the bus. Given the complexity
// of merging tristate drivers at any level, the current limitation
// of this implementation is that a pullup/down gets applied
// to all bits of a bus and a bus cannot have drivers in opposite
// directions on indvidual pins.
AstNode* outp = nodep->lhsp()->unlinkFrBack();;
AstVarRef* outrefp = NULL;
int width=-1;
if (outp->castVarRef()) {
outrefp = outp->castVarRef();
} else if (outp->castSel()) {
outrefp = outp->castSel()->fromp()->castVarRef();
width = outp->castSel()->widthConst();
} else {
nodep->v3error("Can't find LHS varref");
}
outrefp->lvalue(true);
AstVar* varp = outrefp->varp();
if (width==-1) width=varp->width();
V3Number num0 (nodep->fileline(), width);
num0.setAllBits0();
V3Number num1 (nodep->fileline(), width);
num1.setAllBits1();
AstConst* enrhsp = new AstConst(nodep->fileline(), num0);
AstVar* enp = createEnableVar(outp, outrefp, enrhsp, width, "pull");
enp->user2(nodep->direction()+1); // record the pull direction
AstAssignW* newassp = new AstAssignW(nodep->fileline(), outp,
new AstConst(nodep->fileline(), nodep->direction() ? num1 : num0));
nodep->replaceWith(newassp);
nodep->deleteTree(); nodep=NULL;
newassp->iterateChildren(*this);
}
示例4: explicitDimensions
unsigned explicitDimensions(AstArraySel* nodep) {
// Find out how many explicit dimensions are in a given ArraySel.
unsigned dim = 0;
AstNode* fromp = nodep;
AstArraySel* selp;
do {
selp = fromp->castArraySel();
if (!selp) {
nodep->user1p(fromp->castVarRef());
selp = NULL;
break;
} else {
fromp = selp->fromp();
if (fromp) ++dim;
}
} while (fromp && selp);
if (!nodep->user1p()) nodep->v3fatalSrc("Couldn't find VarRef under the ArraySel");
return dim;
}
示例5: visit
virtual void visit(AstCell* nodep, AstNUser*) {
if (nodep->modp()->user1()) { // Marked with inline request
UINFO(5," Inline CELL "<<nodep<<endl);
UINFO(5," To MOD "<<m_modp<<endl);
++m_statCells;
// Before cloning simplify pin assignments
// Better off before, as if module has multiple instantiations
// we'll save work, and we can't call pinReconnectSimple in
// this loop as it clone()s itself.
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
if (!pinp->exprp()) continue;
V3Inst::pinReconnectSimple(pinp, nodep, m_modp, false);
}
// Clone original module
if (debug()>=9) { nodep->dumpTree(cout,"inlcell:"); }
//if (debug()>=9) { nodep->modp()->dumpTree(cout,"oldmod:"); }
AstNodeModule* newmodp = nodep->modp()->cloneTree(false);
if (debug()>=9) { newmodp->dumpTree(cout,"newmod:"); }
// Clear var markings and find cell cross references
AstNode::user2ClearTree();
AstNode::user4ClearTree();
{ InlineCollectVisitor(nodep->modp()); } // {} to destroy visitor immediately
// Create data for dotted variable resolution
AstCellInline* inlinep = new AstCellInline(nodep->fileline(),
nodep->name(), nodep->modp()->origName());
m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells
// Create assignments to the pins
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
if (!pinp->exprp()) continue;
UINFO(6," Pin change from "<<pinp->modVarp()<<endl);
// Make new signal; even though we'll optimize the interconnect, we
// need an alias to trace correctly. If tracing is disabled, we'll
// delete it in later optimizations.
AstVar* pinOldVarp = pinp->modVarp();
AstVar* pinNewVarp = pinOldVarp->clonep()->castVar();
AstNode* connectRefp = pinp->exprp();
if (!connectRefp->castConst() && !connectRefp->castVarRef()) {
pinp->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up\n");
}
if (pinNewVarp->isOutOnly() && connectRefp->castConst()) {
pinp->v3error("Output port is connected to a constant pin, electrical short");
}
// Propagate any attributes across the interconnect
pinNewVarp->propagateAttrFrom(pinOldVarp);
if (connectRefp->castVarRef()) {
connectRefp->castVarRef()->varp()->propagateAttrFrom(pinOldVarp);
}
// One to one interconnect won't make a temporary variable.
// This prevents creating a lot of extra wires for clock signals.
// It will become a tracing alias.
UINFO(6,"One-to-one "<<connectRefp<<endl);
UINFO(6," -to "<<pinNewVarp<<endl);
pinNewVarp->user2p(connectRefp);
// Public output inside the cell must go via an assign rather than alias
// Else the public logic will set the alias, loosing the value to be propagated up
// (InOnly isn't a problem as the AssignAlias will create the assignment for us)
pinNewVarp->user3(pinNewVarp->isSigUserRWPublic() && pinNewVarp->isOutOnly());
}
// Cleanup var names, etc, to not conflict
{ InlineRelinkVisitor(newmodp, m_modp, nodep); }
// Move statements to top module
if (debug()>=9) { newmodp->dumpTree(cout,"fixmod:"); }
AstNode* stmtsp = newmodp->stmtsp();
if (stmtsp) stmtsp->unlinkFrBackWithNext();
if (stmtsp) m_modp->addStmtp(stmtsp);
// Remove the cell
newmodp->deleteTree(); newmodp=NULL; // Clear any leftover ports, etc
nodep->unlinkFrBack();
pushDeletep(nodep); nodep = NULL;
if (debug()>=9) { m_modp->dumpTree(cout,"donemod:"); }
}
}
示例6: visitCell
void ParamVisitor::visitCell(AstCell* nodep) {
// Cell: Check for parameters in the instantiation.
nodep->iterateChildren(*this);
if (!nodep->modp()) nodep->v3fatalSrc("Not linked?");
if (nodep->paramsp()
|| 1 // Need to look for interfaces; could track when one exists, but should be harmless to always do this
) {
UINFO(4,"De-parameterize: "<<nodep<<endl);
// Create new module name with _'s between the constants
if (debug()>=10) nodep->dumpTree(cout,"-cell:\t");
// Evaluate all module constants
V3Const::constifyParamsEdit(nodep);
// Make sure constification worked
// Must be a separate loop, as constant conversion may have changed some pointers.
//if (debug()) nodep->dumpTree(cout,"-cel2:\t");
string longname = nodep->modp()->name();
bool any_overrides = false;
longname += "_";
if (debug()>8) nodep->paramsp()->dumpTreeAndNext(cout,"-cellparams:\t");
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) {
if (!pinp->exprp()) continue; // No-connect
AstVar* modvarp = pinp->modVarp();
if (!modvarp) {
pinp->v3error("Parameter not found in sub-module: Param "<<pinp->name()<<" of "<<nodep->prettyName());
} else if (!modvarp->isGParam()) {
pinp->v3error("Attempted parameter setting of non-parameter: Param "<<pinp->name()<<" of "<<nodep->prettyName());
} else {
AstConst* constp = pinp->exprp()->castConst();
AstConst* origconstp = modvarp->valuep()->castConst();
if (!constp) {
//if (debug()) pinp->dumpTree(cout,"error:");
pinp->v3error("Can't convert defparam value to constant: Param "<<pinp->name()<<" of "<<nodep->prettyName());
pinp->exprp()->replaceWith(new AstConst(pinp->fileline(), V3Number(pinp->fileline(), modvarp->width(), 0)));
} else if (origconstp && constp->sameTree(origconstp)) {
// Setting parameter to its default value. Just ignore it.
// This prevents making additional modules, and makes coverage more
// obvious as it won't show up under a unique module page name.
} else {
longname += "_" + paramSmallName(nodep->modp(),pinp->modVarp())+constp->num().ascii(false);
any_overrides = true;
}
}
}
IfaceRefRefs ifaceRefRefs;
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
AstVar* modvarp = pinp->modVarp();
if (modvarp->isIfaceRef()) {
AstIfaceRefDType* portIrefp = modvarp->subDTypep()->castIfaceRefDType();
AstIfaceRefDType* pinIrefp = NULL;
AstNode *exprp = pinp->exprp();
if (exprp
&& exprp->castVarRef()
&& exprp->castVarRef()->varp()
&& exprp->castVarRef()->varp()->subDTypep()
&& exprp->castVarRef()->varp()->subDTypep()->castIfaceRefDType())
pinIrefp = exprp->castVarRef()->varp()->subDTypep()->castIfaceRefDType();
else if (exprp
&& exprp->op1p()
&& exprp->op1p()->castVarRef()
&& exprp->op1p()->castVarRef()->varp()
&& exprp->op1p()->castVarRef()->varp()->subDTypep()
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())
pinIrefp = exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
//UINFO(9," portIfaceRef "<<portIrefp<<endl);
if (!pinIrefp) {
pinp->v3error("Interface port '"<<modvarp->prettyName()<<"' is not connected to interface/modport pin expression");
} else {
//UINFO(9," pinIfaceRef "<<pinIrefp<<endl);
if (portIrefp->ifaceViaCellp() != pinIrefp->ifaceViaCellp()) {
UINFO(9," IfaceRefDType needs reconnect "<<pinIrefp<<endl);
longname += "_" + paramSmallName(nodep->modp(),pinp->modVarp())+paramValueNumber(pinIrefp);
any_overrides = true;
ifaceRefRefs.push_back(make_pair(portIrefp,pinIrefp));
}
}
}
}
if (!any_overrides) {
UINFO(8,"Cell parameters all match original values, skipping expansion.\n");
} else {
// If the name is very long, we don't want to overwhelm the filename limit
// We don't do this always, as it aids debugability to have intuitive naming.
// TODO can use new V3Name hash replacement instead of this
string newname = longname;
if (longname.length()>30) {
LongMap::iterator iter = m_longMap.find(longname);
if (iter != m_longMap.end()) {
newname = iter->second;
} else {
newname = nodep->modp()->name();
newname += "__pi"+cvtToStr(++m_longId); // We use all upper case above, so lower here can't conflict
m_longMap.insert(make_pair(longname, newname));
}
}
UINFO(4,"Name: "<<nodep->modp()->name()<<"->"<<longname<<"->"<<newname<<endl);
//.........这里部分代码省略.........