mirror of
https://github.com/verilator/verilator.git
synced 2025-04-30 20:46:54 +00:00
Internals: Misc refectoring for assoc/queues.
This commit is contained in:
parent
3d6e8e9eb0
commit
38e586fabe
@ -226,48 +226,56 @@ string AstVar::verilogKwd() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AstVar::VlArgTypeRecurseInfo {
|
class AstVar::VlArgTypeRecursed {
|
||||||
public:
|
public:
|
||||||
bool m_named;
|
string m_oref; // To output, reference part before name, "&"
|
||||||
bool m_forFunc;
|
string m_osuffix; // To output, suffixed after name, "[3]"
|
||||||
bool m_mayParen;
|
string m_oprefix; // To output, prefixed before name, "Foo_t"
|
||||||
string m_namespc;
|
void clear() {
|
||||||
string paren(const string& s) {
|
m_oref.clear();
|
||||||
if (m_mayParen) { m_mayParen = false; return " ("+s+")"; }
|
m_osuffix.clear();
|
||||||
else return s;
|
m_oprefix.clear();
|
||||||
|
}
|
||||||
|
string refParen(const string& name) {
|
||||||
|
return m_oref.empty() ? name : "("+m_oref+" "+name+")";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
string AstVar::vlArgType(bool named, bool forReturn, bool forFunc, const string& namespc) const {
|
string AstVar::vlArgType(bool named, bool forReturn, bool forFunc, const string& namespc) const {
|
||||||
UASSERT_OBJ(!forReturn, this,
|
UASSERT_OBJ(!forReturn, this,
|
||||||
"Internal data is never passed as return, but as first argument");
|
"Internal data is never passed as return, but as first argument");
|
||||||
VlArgTypeRecurseInfo info;
|
|
||||||
info.m_named = named;
|
|
||||||
info.m_forFunc = forFunc;
|
|
||||||
info.m_mayParen = false;
|
|
||||||
info.m_namespc = namespc;
|
|
||||||
|
|
||||||
string ostatic;
|
string ostatic;
|
||||||
if (isStatic() && info.m_namespc.empty()) ostatic = "static ";
|
if (isStatic() && namespc.empty()) ostatic = "static ";
|
||||||
return ostatic + vlArgTypeRecurse(dtypep(), &info, "");
|
|
||||||
|
VlArgTypeRecursed info = vlArgTypeRecurse(forFunc, dtypep());
|
||||||
|
|
||||||
|
string oname;
|
||||||
|
if (named) {
|
||||||
|
oname += " ";
|
||||||
|
if (!namespc.empty()) oname += namespc+"::";
|
||||||
|
oname += VIdProtect::protectIf(name(), protect());
|
||||||
|
}
|
||||||
|
return ostatic + info.m_oprefix + info.refParen(oname) + info.m_osuffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
string AstVar::vlArgTypeRecurse(AstNodeDType* dtypep, VlArgTypeRecurseInfo* infop,
|
AstVar::VlArgTypeRecursed AstVar::vlArgTypeRecurse(bool forFunc,
|
||||||
const string& inarray) const {
|
const AstNodeDType* dtypep) const {
|
||||||
dtypep = dtypep->skipRefp();
|
dtypep = dtypep->skipRefp();
|
||||||
if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
if (const AstUnpackArrayDType* adtypep = VN_CAST_CONST(dtypep, UnpackArrayDType)) {
|
||||||
string oarray = "["+cvtToStr(adtypep->declRange().elements())+"]";
|
VlArgTypeRecursed info = vlArgTypeRecurse(forFunc, adtypep->subDTypep());
|
||||||
return vlArgTypeRecurse(adtypep->subDTypep(), infop, inarray+oarray);
|
info.m_osuffix = "[" + cvtToStr(adtypep->declRange().elements()) + "]" + info.m_osuffix;
|
||||||
} else if (AstBasicDType* bdtypep = basicp()) {
|
return info;
|
||||||
|
} else if (const AstBasicDType* bdtypep = dtypep->basicp()) {
|
||||||
string otype;
|
string otype;
|
||||||
string oarray = inarray;
|
string oarray;
|
||||||
bool strtype = bdtypep && bdtypep->keyword() == AstBasicDTypeKwd::STRING;
|
bool strtype = bdtypep && bdtypep->keyword() == AstBasicDTypeKwd::STRING;
|
||||||
string bitvec;
|
string bitvec;
|
||||||
if (bdtypep && !bdtypep->isOpaque() && !v3Global.opt.protectIds()) {
|
if (bdtypep && !bdtypep->isOpaque() && !v3Global.opt.protectIds()) {
|
||||||
bitvec = ("/*"+cvtToStr(bdtypep->lsb()+bdtypep->width()-1)
|
// We don't print msb()/lsb() as multidim packed would require recursion,
|
||||||
+":"+cvtToStr(bdtypep->lsb())+"*/");
|
// and may confuse users as C++ data is stored always with bit 0 used
|
||||||
|
bitvec += "/*"+cvtToStr(dtypep->width()-1)+":0*/";
|
||||||
}
|
}
|
||||||
if ((infop->m_forFunc && isReadOnly())
|
if ((forFunc && isReadOnly())
|
||||||
|| bdtypep->keyword() == AstBasicDTypeKwd::CHARPTR
|
|| bdtypep->keyword() == AstBasicDTypeKwd::CHARPTR
|
||||||
|| bdtypep->keyword() == AstBasicDTypeKwd::SCOPEPTR) otype += "const ";
|
|| bdtypep->keyword() == AstBasicDTypeKwd::SCOPEPTR) otype += "const ";
|
||||||
if (bdtypep && bdtypep->keyword() == AstBasicDTypeKwd::CHARPTR) {
|
if (bdtypep && bdtypep->keyword() == AstBasicDTypeKwd::CHARPTR) {
|
||||||
@ -280,35 +288,35 @@ string AstVar::vlArgTypeRecurse(AstNodeDType* dtypep, VlArgTypeRecurseInfo* info
|
|||||||
otype += "float";
|
otype += "float";
|
||||||
} else if (strtype) {
|
} else if (strtype) {
|
||||||
otype += "std::string";
|
otype += "std::string";
|
||||||
} else if (widthMin() <= 8) {
|
} else if (dtypep->widthMin() <= 8) { // Handle unpacked arrays; not bdtypep->width
|
||||||
otype += "CData"+bitvec;
|
otype += "CData"+bitvec;
|
||||||
} else if (widthMin() <= 16) {
|
} else if (dtypep->widthMin() <= 16) {
|
||||||
otype += "SData"+bitvec;
|
otype += "SData"+bitvec;
|
||||||
} else if (widthMin() <= VL_WORDSIZE) {
|
} else if (dtypep->widthMin() <= VL_WORDSIZE) {
|
||||||
otype += "IData"+bitvec;
|
otype += "IData"+bitvec;
|
||||||
} else if (isQuad()) {
|
} else if (dtypep->isQuad()) {
|
||||||
otype += "QData"+bitvec;
|
otype += "QData"+bitvec;
|
||||||
} else if (isWide()) {
|
} else if (dtypep->isWide()) {
|
||||||
otype += "WData"+bitvec; // []'s added later
|
otype += "WData"+bitvec; // []'s added later
|
||||||
oarray += "["+cvtToStr(widthWords())+"]";
|
oarray += "["+cvtToStr(dtypep->widthWords())+"]";
|
||||||
}
|
}
|
||||||
|
|
||||||
string oname;
|
string oref;
|
||||||
if (isDpiOpenArray()
|
if (isDpiOpenArray()
|
||||||
|| (infop->m_forFunc && (isWritable()
|
|| (forFunc && (isWritable()
|
||||||
|| direction() == VDirection::REF
|
|| direction() == VDirection::REF
|
||||||
|| direction() == VDirection::CONSTREF
|
|| direction() == VDirection::CONSTREF
|
||||||
|| (strtype && isNonOutput())))) {
|
|| (strtype && isNonOutput())))) {
|
||||||
oname += "&";
|
oref = "&";
|
||||||
infop->m_mayParen = true;
|
|
||||||
}
|
}
|
||||||
if (infop->m_named) {
|
|
||||||
oname += " ";
|
VlArgTypeRecursed info;
|
||||||
if (!infop->m_namespc.empty()) oname += infop->m_namespc+"::";
|
info.m_oprefix = otype;
|
||||||
oname += VIdProtect::protectIf(name(), protect());
|
info.m_osuffix = oarray;
|
||||||
}
|
info.m_oref = oref;
|
||||||
if (!oarray.empty()) oname = infop->paren(oname);
|
//UINFO(9, "vlArgRec "<<"oprefix="<<info.m_oprefix<<" osuffix="<<info.m_osuffix
|
||||||
return otype+oname+oarray;
|
// <<" oref="<<info.m_oref<<" "<<dtypep);
|
||||||
|
return info;
|
||||||
} else {
|
} else {
|
||||||
v3fatalSrc("Unknown data type in var type emitter: "<<dtypep->prettyName());
|
v3fatalSrc("Unknown data type in var type emitter: "<<dtypep->prettyName());
|
||||||
}
|
}
|
||||||
|
@ -1411,9 +1411,8 @@ public:
|
|||||||
const MTaskIdSet& mtaskIds() const { return m_mtaskIds; }
|
const MTaskIdSet& mtaskIds() const { return m_mtaskIds; }
|
||||||
string mtasksString() const;
|
string mtasksString() const;
|
||||||
private:
|
private:
|
||||||
class VlArgTypeRecurseInfo;
|
class VlArgTypeRecursed;
|
||||||
string vlArgTypeRecurse(AstNodeDType* dtypep, VlArgTypeRecurseInfo* infop,
|
VlArgTypeRecursed vlArgTypeRecurse(bool forFunc, const AstNodeDType* dtypep) const;
|
||||||
const string& oarray) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AstDefParam : public AstNode {
|
class AstDefParam : public AstNode {
|
||||||
|
184
src/V3EmitC.cpp
184
src/V3EmitC.cpp
@ -1264,7 +1264,99 @@ class EmitCImp : EmitCStmts {
|
|||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
// Low level
|
// Low level
|
||||||
void emitVarReset(AstVar* varp);
|
void emitVarReset(AstVar* varp) {
|
||||||
|
AstNodeDType* dtypep = varp->dtypep()->skipRefp();
|
||||||
|
if (varp->isIO() && m_modp->isTop() && optSystemC()) {
|
||||||
|
// System C top I/O doesn't need loading, as the lower level subinst code does it.}
|
||||||
|
} else if (varp->isParam()) {
|
||||||
|
UASSERT_OBJ(varp->valuep(), varp, "No init for a param?");
|
||||||
|
// If a simple CONST value we initialize it using an enum
|
||||||
|
// If an ARRAYINIT we initialize it using an initial block similar to a signal
|
||||||
|
//puts("// parameter "+varp->nameProtect()+" = "+varp->valuep()->name()+"\n");
|
||||||
|
} else if (AstInitArray* initarp = VN_CAST(varp->valuep(), InitArray)) {
|
||||||
|
if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||||
|
if (initarp->defaultp()) {
|
||||||
|
// MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block
|
||||||
|
puts("{ int __Vi=0;");
|
||||||
|
puts(" for (; __Vi<"+cvtToStr(adtypep->elementsConst()));
|
||||||
|
puts("; ++__Vi) {\n");
|
||||||
|
emitSetVarConstant(varp->nameProtect()+"[__Vi]",
|
||||||
|
VN_CAST(initarp->defaultp(), Const));
|
||||||
|
puts("}}\n");
|
||||||
|
}
|
||||||
|
const AstInitArray::KeyItemMap& mapr = initarp->map();
|
||||||
|
for (AstInitArray::KeyItemMap::const_iterator it = mapr.begin();
|
||||||
|
it != mapr.end(); ++it) {
|
||||||
|
AstNode* valuep = it->second->valuep();
|
||||||
|
emitSetVarConstant(varp->nameProtect()
|
||||||
|
+"["+cvtToStr(it->first)+"]",
|
||||||
|
VN_CAST(valuep, Const));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
varp->v3fatalSrc("InitArray under non-arrayed var");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
puts(emitVarResetRecurse(varp, dtypep, 0, ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
string emitVarResetRecurse(AstVar* varp, AstNodeDType* dtypep, int depth, string suffix) {
|
||||||
|
dtypep = dtypep->skipRefp();
|
||||||
|
AstBasicDType* basicp = dtypep->basicp();
|
||||||
|
// Returns string to do resetting, empty to do nothing (which caller should handle)
|
||||||
|
if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||||
|
UASSERT_OBJ(adtypep->msb() >= adtypep->lsb(), varp,
|
||||||
|
"Should have swapped msb & lsb earlier.");
|
||||||
|
string ivar = string("__Vi")+cvtToStr(depth);
|
||||||
|
// MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block
|
||||||
|
string pre = ("{ int "+ivar+"="+cvtToStr(0)+";"
|
||||||
|
+" for (; "+ivar+"<"+cvtToStr(adtypep->elementsConst())
|
||||||
|
+"; ++"+ivar+") {\n");
|
||||||
|
string below = emitVarResetRecurse(varp, adtypep->subDTypep(), depth+1, suffix+"["+ivar+"]");
|
||||||
|
string post = "}}\n";
|
||||||
|
return below.empty() ? "" : pre + below + post;
|
||||||
|
}
|
||||||
|
else if (basicp && basicp->keyword() == AstBasicDTypeKwd::STRING) {
|
||||||
|
// String's constructor deals with it
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else if (basicp) {
|
||||||
|
bool zeroit = (varp->attrFileDescr() // Zero so we don't core dump if never $fopen
|
||||||
|
|| (basicp && basicp->isZeroInit())
|
||||||
|
|| (v3Global.opt.underlineZero()
|
||||||
|
&& !varp->name().empty() && varp->name()[0] == '_')
|
||||||
|
|| (v3Global.opt.xInitial() == "fast"
|
||||||
|
|| v3Global.opt.xInitial() == "0"));
|
||||||
|
splitSizeInc(1);
|
||||||
|
if (dtypep->isWide()) { // Handle unpacked; not basicp->isWide
|
||||||
|
string out;
|
||||||
|
if (zeroit) out += "VL_ZERO_RESET_W(";
|
||||||
|
else out += "VL_RAND_RESET_W(";
|
||||||
|
out += cvtToStr(dtypep->widthMin());
|
||||||
|
out += ", "+varp->nameProtect()+suffix+");\n";
|
||||||
|
return out;
|
||||||
|
} else {
|
||||||
|
string out = varp->nameProtect() + suffix;
|
||||||
|
// If --x-initial-edge is set, we want to force an initial
|
||||||
|
// edge on uninitialized clocks (from 'X' to whatever the
|
||||||
|
// first value is). Since the class is instantiated before
|
||||||
|
// initial blocks are evaluated, this should not clash
|
||||||
|
// with any initial block settings.
|
||||||
|
if (zeroit || (v3Global.opt.xInitialEdge() && varp->isUsedClock())) {
|
||||||
|
out += " = 0;\n";
|
||||||
|
} else {
|
||||||
|
out += " = VL_RAND_RESET_";
|
||||||
|
out += dtypep->charIQWN();
|
||||||
|
out += "("+ cvtToStr(dtypep->widthMin())+");\n";
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
v3fatalSrc("Unknown node type in reset generator: "<<varp->prettyTypeName());
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
void emitCellCtors(AstNodeModule* modp);
|
void emitCellCtors(AstNodeModule* modp);
|
||||||
void emitSensitives();
|
void emitSensitives();
|
||||||
// Medium level
|
// Medium level
|
||||||
@ -1303,8 +1395,8 @@ public:
|
|||||||
|
|
||||||
void EmitCStmts::emitVarDecl(const AstVar* nodep, const string& prefixIfImp) {
|
void EmitCStmts::emitVarDecl(const AstVar* nodep, const string& prefixIfImp) {
|
||||||
AstBasicDType* basicp = nodep->basicp();
|
AstBasicDType* basicp = nodep->basicp();
|
||||||
UASSERT_OBJ(basicp, nodep, "Unimplemented: Outputting this data type");
|
|
||||||
if (nodep->isIO() && nodep->isSc()) {
|
if (nodep->isIO() && nodep->isSc()) {
|
||||||
|
UASSERT_OBJ(basicp, nodep, "Unimplemented: Outputting this data type");
|
||||||
m_ctorVarsVec.push_back(nodep);
|
m_ctorVarsVec.push_back(nodep);
|
||||||
if (nodep->attrScClocked() && nodep->isReadOnly()) {
|
if (nodep->attrScClocked() && nodep->isReadOnly()) {
|
||||||
puts("sc_in_clk ");
|
puts("sc_in_clk ");
|
||||||
@ -1698,94 +1790,6 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep,
|
|||||||
//######################################################################
|
//######################################################################
|
||||||
// Internal EmitC
|
// Internal EmitC
|
||||||
|
|
||||||
void EmitCImp::emitVarReset(AstVar* varp) {
|
|
||||||
if (varp->isIO() && m_modp->isTop() && optSystemC()) {
|
|
||||||
// System C top I/O doesn't need loading, as the lower level subinst code does it.}
|
|
||||||
} else if (varp->isParam()) {
|
|
||||||
UASSERT_OBJ(varp->valuep(), varp, "No init for a param?");
|
|
||||||
// If a simple CONST value we initialize it using an enum
|
|
||||||
// If an ARRAYINIT we initialize it using an initial block similar to a signal
|
|
||||||
//puts("// parameter "+varp->nameProtect()+" = "+varp->valuep()->name()+"\n");
|
|
||||||
}
|
|
||||||
else if (AstInitArray* initarp = VN_CAST(varp->valuep(), InitArray)) {
|
|
||||||
if (AstUnpackArrayDType* arrayp = VN_CAST(varp->dtypeSkipRefp(), UnpackArrayDType)) {
|
|
||||||
if (initarp->defaultp()) {
|
|
||||||
// MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block
|
|
||||||
puts("{ int __Vi=0;");
|
|
||||||
puts(" for (; __Vi<"+cvtToStr(arrayp->elementsConst()));
|
|
||||||
puts("; ++__Vi) {\n");
|
|
||||||
emitSetVarConstant(varp->nameProtect()+"[__Vi]",
|
|
||||||
VN_CAST(initarp->defaultp(), Const));
|
|
||||||
puts("}}\n");
|
|
||||||
}
|
|
||||||
const AstInitArray::KeyItemMap& mapr = initarp->map();
|
|
||||||
for (AstInitArray::KeyItemMap::const_iterator it = mapr.begin();
|
|
||||||
it != mapr.end(); ++it) {
|
|
||||||
AstNode* valuep = it->second->valuep();
|
|
||||||
emitSetVarConstant(varp->nameProtect()
|
|
||||||
+"["+cvtToStr(it->first)+"]",
|
|
||||||
VN_CAST(valuep, Const));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
varp->v3fatalSrc("InitArray under non-arrayed var");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (varp->basicp() && varp->basicp()->keyword() == AstBasicDTypeKwd::STRING) {
|
|
||||||
// Constructor deals with it
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
arrayp;
|
|
||||||
arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
|
|
||||||
int vecnum = vects++;
|
|
||||||
UASSERT_OBJ(arrayp->msb() >= arrayp->lsb(), varp,
|
|
||||||
"Should have swapped msb & lsb earlier.");
|
|
||||||
string ivar = string("__Vi")+cvtToStr(vecnum);
|
|
||||||
// MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block
|
|
||||||
puts("{ int __Vi"+cvtToStr(vecnum)+"="+cvtToStr(0)+";");
|
|
||||||
puts(" for (; "+ivar+"<"+cvtToStr(arrayp->elementsConst()));
|
|
||||||
puts("; ++"+ivar+") {\n");
|
|
||||||
}
|
|
||||||
bool zeroit = (varp->attrFileDescr() // Zero it out, so we don't core dump if never call $fopen
|
|
||||||
|| (varp->basicp() && varp->basicp()->isZeroInit())
|
|
||||||
|| (v3Global.opt.underlineZero()
|
|
||||||
&& !varp->name().empty() && varp->name()[0]=='_')
|
|
||||||
|| (v3Global.opt.xInitial() == "fast" || v3Global.opt.xInitial() == "0"));
|
|
||||||
if (varp->isWide()) {
|
|
||||||
// DOCUMENT: We randomize everything. If the user wants a _var to be zero,
|
|
||||||
// there should be a initial statement. (Different from verilator2.)
|
|
||||||
if (zeroit) puts("VL_ZERO_RESET_W(");
|
|
||||||
else puts("VL_RAND_RESET_W(");
|
|
||||||
puts(cvtToStr(varp->widthMin()));
|
|
||||||
puts(",");
|
|
||||||
puts(varp->nameProtect());
|
|
||||||
for (int v=0; v<vects; ++v) puts( "[__Vi"+cvtToStr(v)+"]");
|
|
||||||
puts(");\n");
|
|
||||||
} else {
|
|
||||||
puts(varp->nameProtect());
|
|
||||||
for (int v=0; v<vects; ++v) puts( "[__Vi"+cvtToStr(v)+"]");
|
|
||||||
// If --x-initial-edge is set, we want to force an initial
|
|
||||||
// edge on uninitialized clocks (from 'X' to whatever the
|
|
||||||
// first value is). Since the class is instantiated before
|
|
||||||
// initial blocks are evaluated, this should not clash
|
|
||||||
// with any initial block settings.
|
|
||||||
if (zeroit || (v3Global.opt.xInitialEdge() && varp->isUsedClock())) {
|
|
||||||
puts(" = 0;\n");
|
|
||||||
} else {
|
|
||||||
puts(" = VL_RAND_RESET_");
|
|
||||||
emitIQW(varp);
|
|
||||||
puts("(");
|
|
||||||
puts(cvtToStr(varp->widthMin()));
|
|
||||||
puts(");\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int v=0; v<vects; ++v) puts( "}}\n");
|
|
||||||
}
|
|
||||||
splitSizeInc(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmitCImp::emitCoverageDecl(AstNodeModule* modp) {
|
void EmitCImp::emitCoverageDecl(AstNodeModule* modp) {
|
||||||
if (v3Global.opt.coverage()) {
|
if (v3Global.opt.coverage()) {
|
||||||
ofp()->putsPrivate(true);
|
ofp()->putsPrivate(true);
|
||||||
|
@ -113,17 +113,17 @@ AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep,
|
|||||||
AstNodeRange* prevp = VN_CAST(nrangep->backp(), NodeRange);
|
AstNodeRange* prevp = VN_CAST(nrangep->backp(), NodeRange);
|
||||||
if (prevp) nrangep->unlinkFrBack();
|
if (prevp) nrangep->unlinkFrBack();
|
||||||
AstRange* rangep = VN_CAST(nrangep, Range);
|
AstRange* rangep = VN_CAST(nrangep, Range);
|
||||||
if (!rangep) {
|
if (rangep && isPacked) {
|
||||||
UASSERT_OBJ(VN_IS(nrangep, UnsizedRange), nrangep,
|
|
||||||
"Expected range or unsized range");
|
|
||||||
arrayp = new AstUnsizedArrayDType
|
|
||||||
(nrangep->fileline(), VFlagChildDType(), arrayp);
|
|
||||||
} else if (isPacked) {
|
|
||||||
arrayp = new AstPackArrayDType
|
arrayp = new AstPackArrayDType
|
||||||
(rangep->fileline(), VFlagChildDType(), arrayp, rangep);
|
(rangep->fileline(), VFlagChildDType(), arrayp, rangep);
|
||||||
} else {
|
} else if (rangep) {
|
||||||
arrayp = new AstUnpackArrayDType
|
arrayp = new AstUnpackArrayDType
|
||||||
(rangep->fileline(), VFlagChildDType(), arrayp, rangep);
|
(rangep->fileline(), VFlagChildDType(), arrayp, rangep);
|
||||||
|
} else if (VN_IS(nrangep, UnsizedRange)) {
|
||||||
|
arrayp = new AstUnsizedArrayDType
|
||||||
|
(nrangep->fileline(), VFlagChildDType(), arrayp);
|
||||||
|
} else {
|
||||||
|
UASSERT_OBJ(0, nrangep, "Expected range or unsized range");
|
||||||
}
|
}
|
||||||
nrangep = prevp;
|
nrangep = prevp;
|
||||||
}
|
}
|
||||||
|
@ -388,7 +388,8 @@ private:
|
|||||||
// Any strings sent to a display must be var of string data type,
|
// Any strings sent to a display must be var of string data type,
|
||||||
// to avoid passing a pointer to a temporary.
|
// to avoid passing a pointer to a temporary.
|
||||||
for (AstNode* expp=nodep->exprsp(); expp; expp = expp->nextp()) {
|
for (AstNode* expp=nodep->exprsp(); expp; expp = expp->nextp()) {
|
||||||
if (expp->dtypep()->basicp()->isString()
|
if (expp->dtypep()->basicp()
|
||||||
|
&& expp->dtypep()->basicp()->isString()
|
||||||
&& !VN_IS(expp, VarRef)) {
|
&& !VN_IS(expp, VarRef)) {
|
||||||
createDeepTemp(expp, true);
|
createDeepTemp(expp, true);
|
||||||
}
|
}
|
||||||
|
@ -1358,7 +1358,7 @@ private:
|
|||||||
// Note genvar's are also entered as integers
|
// Note genvar's are also entered as integers
|
||||||
nodep->dtypeFrom(nodep->varp());
|
nodep->dtypeFrom(nodep->varp());
|
||||||
if (VN_IS(nodep->backp(), NodeAssign) && nodep->lvalue()) { // On LHS
|
if (VN_IS(nodep->backp(), NodeAssign) && nodep->lvalue()) { // On LHS
|
||||||
UASSERT_OBJ(nodep->widthMin(), nodep, "LHS var should be size complete");
|
UASSERT_OBJ(nodep->dtypep(), nodep, "LHS var should be dtype completed");
|
||||||
}
|
}
|
||||||
//if (debug()>=9) nodep->dumpTree(cout, " VRout ");
|
//if (debug()>=9) nodep->dumpTree(cout, " VRout ");
|
||||||
if (nodep->lvalue() && nodep->varp()->direction() == VDirection::CONSTREF) {
|
if (nodep->lvalue() && nodep->varp()->direction() == VDirection::CONSTREF) {
|
||||||
@ -1631,6 +1631,7 @@ private:
|
|||||||
|
|
||||||
virtual void visit(AstMethodCall* nodep) {
|
virtual void visit(AstMethodCall* nodep) {
|
||||||
UINFO(5," METHODSEL "<<nodep<<endl);
|
UINFO(5," METHODSEL "<<nodep<<endl);
|
||||||
|
if (nodep->didWidth()) return;
|
||||||
if (debug()>=9) nodep->dumpTree("-mts-in: ");
|
if (debug()>=9) nodep->dumpTree("-mts-in: ");
|
||||||
// Should check types the method requires, but at present we don't do much
|
// Should check types the method requires, but at present we don't do much
|
||||||
userIterate(nodep->fromp(), WidthVP(SELF, BOTH).p());
|
userIterate(nodep->fromp(), WidthVP(SELF, BOTH).p());
|
||||||
@ -2308,10 +2309,10 @@ private:
|
|||||||
}
|
}
|
||||||
case 'p': { // Packed
|
case 'p': { // Packed
|
||||||
AstBasicDType* basicp = argp ? argp->dtypep()->basicp() : NULL;
|
AstBasicDType* basicp = argp ? argp->dtypep()->basicp() : NULL;
|
||||||
if (basicp->isString()) {
|
if (basicp && basicp->isString()) {
|
||||||
added = true;
|
added = true;
|
||||||
newFormat += "\"%@\"";
|
newFormat += "\"%@\"";
|
||||||
} else if (basicp->isDouble()) {
|
} else if (basicp && basicp->isDouble()) {
|
||||||
added = true;
|
added = true;
|
||||||
newFormat += "%g";
|
newFormat += "%g";
|
||||||
} else {
|
} else {
|
||||||
@ -3482,6 +3483,16 @@ private:
|
|||||||
}
|
}
|
||||||
if (underp) {} // cppcheck
|
if (underp) {} // cppcheck
|
||||||
}
|
}
|
||||||
|
void iterateCheckTyped(AstNode* nodep, const char* side, AstNode* underp,
|
||||||
|
AstNodeDType* expDTypep, Stage stage) {
|
||||||
|
if (stage & PRELIM) {
|
||||||
|
underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF, PRELIM).p());
|
||||||
|
}
|
||||||
|
if (stage & FINAL) {
|
||||||
|
underp = iterateCheck(nodep, side, underp, SELF, FINAL, expDTypep, EXTEND_EXP);
|
||||||
|
}
|
||||||
|
if (underp) {} // cppcheck
|
||||||
|
}
|
||||||
void iterateCheckSizedSelf(AstNode* nodep, const char* side, AstNode* underp,
|
void iterateCheckSizedSelf(AstNode* nodep, const char* side, AstNode* underp,
|
||||||
Determ determ, Stage stage) {
|
Determ determ, Stage stage) {
|
||||||
// Coerce child to any sized-number data type; child is self-determined
|
// Coerce child to any sized-number data type; child is self-determined
|
||||||
|
Loading…
Reference in New Issue
Block a user