Rework variable emit to prep for other data types.
This commit is contained in:
parent
77e30d4920
commit
21a380def0
|
|
@ -221,13 +221,6 @@ public:
|
|||
//=========================================================================
|
||||
// Declare nets
|
||||
|
||||
#ifndef VL_ST_SIG
|
||||
# define VL_ST_SIG8(name, msb,lsb) CData name ///< Declare signal, 1-8 bits
|
||||
# define VL_ST_SIG16(name, msb,lsb) SData name ///< Declare signal, 9-16 bits
|
||||
# define VL_ST_SIG64(name, msb,lsb) QData name ///< Declare signal, 33-64 bits
|
||||
# define VL_ST_SIG(name, msb,lsb) IData name ///< Declare signal, 17-32 bits
|
||||
# define VL_ST_SIGW(name,msb,lsb,words) WData name[words] ///< Declare signal, 65+ bits
|
||||
#endif
|
||||
#ifndef VL_SIG
|
||||
# define VL_SIG8(name, msb,lsb) CData name ///< Declare signal, 1-8 bits
|
||||
# define VL_SIG16(name, msb,lsb) SData name ///< Declare signal, 9-16 bits
|
||||
|
|
|
|||
|
|
@ -226,72 +226,92 @@ string AstVar::verilogKwd() const {
|
|||
}
|
||||
}
|
||||
|
||||
string AstVar::vlArgType(bool named, bool forReturn, bool forFunc) const {
|
||||
class AstVar::VlArgTypeRecurseInfo {
|
||||
public:
|
||||
bool m_named;
|
||||
bool m_forFunc;
|
||||
bool m_mayParen;
|
||||
string m_namespc;
|
||||
string paren(const string& s) {
|
||||
if (m_mayParen) { m_mayParen = false; return " ("+s+")"; }
|
||||
else return s;
|
||||
}
|
||||
};
|
||||
|
||||
string AstVar::vlArgType(bool named, bool forReturn, bool forFunc, const string& namespc) const {
|
||||
UASSERT_OBJ(!forReturn, this,
|
||||
"Internal data is never passed as return, but as first argument");
|
||||
string otype;
|
||||
AstBasicDType* bdtypep = basicp();
|
||||
bool strtype = bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::STRING;
|
||||
if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::CHARPTR) {
|
||||
otype += "const char*";
|
||||
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::SCOPEPTR) {
|
||||
otype += "const VerilatedScope*";
|
||||
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::DOUBLE) {
|
||||
if (forFunc && isReadOnly()) otype += "const ";
|
||||
otype += "double";
|
||||
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::FLOAT) {
|
||||
if (forFunc && isReadOnly()) otype += "const ";
|
||||
otype += "float";
|
||||
} else if (strtype) {
|
||||
if (forFunc && isReadOnly()) otype += "const ";
|
||||
otype += "std::string";
|
||||
} else if (widthMin() <= 8) {
|
||||
if (forFunc && isReadOnly()) otype += "const ";
|
||||
otype += "CData";
|
||||
} else if (widthMin() <= 16) {
|
||||
if (forFunc && isReadOnly()) otype += "const ";
|
||||
otype += "SData";
|
||||
} else if (widthMin() <= VL_WORDSIZE) {
|
||||
if (forFunc && isReadOnly()) otype += "const ";
|
||||
otype += "IData";
|
||||
} else if (isQuad()) {
|
||||
if (forFunc && isReadOnly()) otype += "const ";
|
||||
otype += "QData";
|
||||
} else if (isWide()) {
|
||||
if (forFunc && isReadOnly()) otype += "const ";
|
||||
otype += "WData"; // []'s added later
|
||||
}
|
||||
VlArgTypeRecurseInfo info;
|
||||
info.m_named = named;
|
||||
info.m_forFunc = forFunc;
|
||||
info.m_mayParen = false;
|
||||
info.m_namespc = namespc;
|
||||
|
||||
bool mayparen = false; // Need paren, to handle building "(& name)[2]"
|
||||
string oname;
|
||||
if (isDpiOpenArray()
|
||||
|| (isWide() && !strtype)
|
||||
|| (forFunc && (isWritable()
|
||||
|| direction()==VDirection::REF
|
||||
|| direction()==VDirection::CONSTREF
|
||||
|| (strtype && isNonOutput())))) {
|
||||
oname += "&";
|
||||
mayparen = true;
|
||||
}
|
||||
if (named) oname += " "+VIdProtect::protectIf(name(), protect());
|
||||
string ostatic;
|
||||
if (isStatic() && info.m_namespc.empty()) ostatic = "static ";
|
||||
return ostatic + vlArgTypeRecurse(dtypep(), &info, "");
|
||||
}
|
||||
|
||||
string oarray;
|
||||
if (isDpiOpenArray() || direction().isRefOrConstRef()) {
|
||||
for (AstNodeDType* dtp=dtypep(); dtp; ) {
|
||||
dtp = dtp->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (AstUnpackArrayDType* adtypep = VN_CAST(dtp, UnpackArrayDType)) {
|
||||
if (mayparen) { oname = " ("+oname+")"; mayparen = false; }
|
||||
oarray += "["+cvtToStr(adtypep->declRange().elements())+"]";
|
||||
dtp = adtypep->subDTypep();
|
||||
} else break;
|
||||
string AstVar::vlArgTypeRecurse(AstNodeDType* dtypep, VlArgTypeRecurseInfo* infop,
|
||||
const string& inarray) const {
|
||||
dtypep = dtypep->skipRefp();
|
||||
if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
string oarray = "["+cvtToStr(adtypep->declRange().elements())+"]";
|
||||
return vlArgTypeRecurse(adtypep->subDTypep(), infop, inarray+oarray);
|
||||
} else if (AstBasicDType* bdtypep = basicp()) {
|
||||
string otype;
|
||||
string oarray = inarray;
|
||||
bool strtype = bdtypep && bdtypep->keyword() == AstBasicDTypeKwd::STRING;
|
||||
string bitvec;
|
||||
if (bdtypep && !bdtypep->isOpaque() && !v3Global.opt.protectIds()) {
|
||||
bitvec = ("/*"+cvtToStr(bdtypep->lsb()+bdtypep->width()-1)
|
||||
+":"+cvtToStr(bdtypep->lsb())+"*/");
|
||||
}
|
||||
if ((infop->m_forFunc && isReadOnly())
|
||||
|| bdtypep->keyword() == AstBasicDTypeKwd::CHARPTR
|
||||
|| bdtypep->keyword() == AstBasicDTypeKwd::SCOPEPTR) otype += "const ";
|
||||
if (bdtypep && bdtypep->keyword() == AstBasicDTypeKwd::CHARPTR) {
|
||||
otype += "char*";
|
||||
} else if (bdtypep && bdtypep->keyword() == AstBasicDTypeKwd::SCOPEPTR) {
|
||||
otype += "VerilatedScope*";
|
||||
} else if (bdtypep && bdtypep->keyword() == AstBasicDTypeKwd::DOUBLE) {
|
||||
otype += "double";
|
||||
} else if (bdtypep && bdtypep->keyword() == AstBasicDTypeKwd::FLOAT) {
|
||||
otype += "float";
|
||||
} else if (strtype) {
|
||||
otype += "std::string";
|
||||
} else if (widthMin() <= 8) {
|
||||
otype += "CData"+bitvec;
|
||||
} else if (widthMin() <= 16) {
|
||||
otype += "SData"+bitvec;
|
||||
} else if (widthMin() <= VL_WORDSIZE) {
|
||||
otype += "IData"+bitvec;
|
||||
} else if (isQuad()) {
|
||||
otype += "QData"+bitvec;
|
||||
} else if (isWide()) {
|
||||
otype += "WData"+bitvec; // []'s added later
|
||||
oarray += "["+cvtToStr(widthWords())+"]";
|
||||
}
|
||||
|
||||
string oname;
|
||||
if (isDpiOpenArray()
|
||||
|| (infop->m_forFunc && (isWritable()
|
||||
|| direction() == VDirection::REF
|
||||
|| direction() == VDirection::CONSTREF
|
||||
|| (strtype && isNonOutput())))) {
|
||||
oname += "&";
|
||||
infop->m_mayParen = true;
|
||||
}
|
||||
if (infop->m_named) {
|
||||
oname += " ";
|
||||
if (!infop->m_namespc.empty()) oname += infop->m_namespc+"::";
|
||||
oname += VIdProtect::protectIf(name(), protect());
|
||||
}
|
||||
if (!oarray.empty()) oname = infop->paren(oname);
|
||||
return otype+oname+oarray;
|
||||
} else {
|
||||
v3fatalSrc("Unknown data type in var type emitter: "<<dtypep->prettyName());
|
||||
}
|
||||
if (isWide() && !strtype) {
|
||||
if (mayparen) { oname = " ("+oname+")"; mayparen = false; }
|
||||
oarray += "["+cvtToStr(widthWords())+"]";
|
||||
}
|
||||
if (mayparen) { }
|
||||
return otype+oname+oarray;
|
||||
}
|
||||
|
||||
string AstVar::vlEnumType() const {
|
||||
|
|
|
|||
|
|
@ -1271,7 +1271,7 @@ public:
|
|||
string cPubArgType(bool named, bool forReturn) const; // Return C /*public*/ type for argument: bool, uint32_t, uint64_t, etc.
|
||||
string dpiArgType(bool named, bool forReturn) const; // Return DPI-C type for argument
|
||||
// Return Verilator internal type for argument: CData, SData, IData, WData
|
||||
string vlArgType(bool named, bool forReturn, bool forFunc) const;
|
||||
string vlArgType(bool named, bool forReturn, bool forFunc, const string& namespc="") const;
|
||||
string vlEnumType() const; // Return VerilatorVarType: VLVT_UINT32, etc
|
||||
string vlEnumDir() const; // Return VerilatorVarDir: VLVD_INOUT, etc
|
||||
string vlPropInit() const; // Return VerilatorVarProps initializer
|
||||
|
|
@ -1410,6 +1410,10 @@ public:
|
|||
void addConsumingMTaskId(int id) { m_mtaskIds.insert(id); }
|
||||
const MTaskIdSet& mtaskIds() const { return m_mtaskIds; }
|
||||
string mtasksString() const;
|
||||
private:
|
||||
class VlArgTypeRecurseInfo;
|
||||
string vlArgTypeRecurse(AstNodeDType* dtypep, VlArgTypeRecurseInfo* infop,
|
||||
const string& oarray) const;
|
||||
};
|
||||
|
||||
class AstDefParam : public AstNode {
|
||||
|
|
|
|||
|
|
@ -1303,71 +1303,34 @@ public:
|
|||
void EmitCStmts::emitVarDecl(const AstVar* nodep, const string& prefixIfImp) {
|
||||
AstBasicDType* basicp = nodep->basicp();
|
||||
UASSERT_OBJ(basicp, nodep, "Unimplemented: Outputting this data type");
|
||||
if (nodep->isIO()) {
|
||||
if (nodep->isSc()) {
|
||||
m_ctorVarsVec.push_back(nodep);
|
||||
if (nodep->attrScClocked() && nodep->isReadOnly()) {
|
||||
puts("sc_in_clk ");
|
||||
} else {
|
||||
if (nodep->isInoutish()) puts("sc_inout<");
|
||||
else if (nodep->isWritable()) puts("sc_out<");
|
||||
else if (nodep->isNonOutput()) puts("sc_in<");
|
||||
else nodep->v3fatalSrc("Unknown type");
|
||||
|
||||
puts(nodep->scType());
|
||||
puts("> ");
|
||||
}
|
||||
puts(nodep->nameProtect());
|
||||
emitDeclArrayBrackets(nodep);
|
||||
puts(";\n");
|
||||
} else if (basicp && basicp->isOpaque()) {
|
||||
// strings and other fundamental c types; no VL_ macro can be used
|
||||
puts(nodep->vlArgType(true, false, false));
|
||||
emitDeclArrayBrackets(nodep);
|
||||
puts(";\n");
|
||||
} else { // C++ signals
|
||||
if (nodep->isInoutish()) puts("VL_INOUT");
|
||||
else if (nodep->isWritable()) puts("VL_OUT");
|
||||
else if (nodep->isNonOutput()) puts("VL_IN");
|
||||
if (nodep->isIO() && nodep->isSc()) {
|
||||
m_ctorVarsVec.push_back(nodep);
|
||||
if (nodep->attrScClocked() && nodep->isReadOnly()) {
|
||||
puts("sc_in_clk ");
|
||||
} else {
|
||||
if (nodep->isInoutish()) puts("sc_inout<");
|
||||
else if (nodep->isWritable()) puts("sc_out<");
|
||||
else if (nodep->isNonOutput()) puts("sc_in<");
|
||||
else nodep->v3fatalSrc("Unknown type");
|
||||
|
||||
if (nodep->isQuad()) puts("64");
|
||||
else if (nodep->widthMin() <= 8) puts("8");
|
||||
else if (nodep->widthMin() <= 16) puts("16");
|
||||
else if (nodep->isWide()) puts("W");
|
||||
|
||||
puts("("+nodep->nameProtect());
|
||||
emitDeclArrayBrackets(nodep);
|
||||
// If it's a packed struct/array then nodep->width is the whole
|
||||
// thing, msb/lsb is just lowest dimension
|
||||
puts(","+cvtToStr(basicp->lsb()+nodep->width()-1)
|
||||
+","+cvtToStr(basicp->lsb()));
|
||||
if (nodep->isWide()) puts(","+cvtToStr(nodep->widthWords()));
|
||||
puts(");\n");
|
||||
puts(nodep->scType());
|
||||
puts("> ");
|
||||
}
|
||||
} else if (basicp && basicp->isOpaque()) {
|
||||
// strings and other fundamental c types
|
||||
puts(nodep->vlArgType(true, false, false));
|
||||
puts(nodep->nameProtect());
|
||||
emitDeclArrayBrackets(nodep);
|
||||
puts(";\n");
|
||||
} else {
|
||||
// Arrays need a small alignment, but may need different padding after.
|
||||
// For example three VL_SIG8's needs alignment 1 but size 3.
|
||||
if (nodep->isStatic() && prefixIfImp=="") puts("static ");
|
||||
if (nodep->isStatic()) puts("VL_ST_"); else puts("VL_");
|
||||
if (nodep->widthMin() <= 8) {
|
||||
puts("SIG8(");
|
||||
} else if (nodep->widthMin() <= 16) {
|
||||
puts("SIG16(");
|
||||
} else if (nodep->isQuad()) {
|
||||
puts("SIG64(");
|
||||
} else if (!nodep->isWide()) {
|
||||
puts("SIG(");
|
||||
} else {
|
||||
puts("SIGW(");
|
||||
}
|
||||
if (prefixIfImp!="") { puts(prefixIfImp); puts("::"); }
|
||||
puts(nodep->nameProtect());
|
||||
} else if (nodep->isIO() && basicp && !basicp->isOpaque()) {
|
||||
if (nodep->isInoutish()) puts("VL_INOUT");
|
||||
else if (nodep->isWritable()) puts("VL_OUT");
|
||||
else if (nodep->isNonOutput()) puts("VL_IN");
|
||||
else nodep->v3fatalSrc("Unknown type");
|
||||
|
||||
if (nodep->isQuad()) puts("64");
|
||||
else if (nodep->widthMin() <= 8) puts("8");
|
||||
else if (nodep->widthMin() <= 16) puts("16");
|
||||
else if (nodep->isWide()) puts("W");
|
||||
|
||||
puts("("+nodep->nameProtect());
|
||||
emitDeclArrayBrackets(nodep);
|
||||
// If it's a packed struct/array then nodep->width is the whole
|
||||
// thing, msb/lsb is just lowest dimension
|
||||
|
|
@ -1375,6 +1338,10 @@ void EmitCStmts::emitVarDecl(const AstVar* nodep, const string& prefixIfImp) {
|
|||
+","+cvtToStr(basicp->lsb()));
|
||||
if (nodep->isWide()) puts(","+cvtToStr(nodep->widthWords()));
|
||||
puts(");\n");
|
||||
} else {
|
||||
// strings and other fundamental c types
|
||||
puts(nodep->vlArgType(true, false, false, prefixIfImp));
|
||||
puts(";\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue