Rework variable emit to prep for other data types.

This commit is contained in:
Wilson Snyder 2019-11-12 21:52:25 -05:00
parent 77e30d4920
commit 21a380def0
4 changed files with 112 additions and 128 deletions

View File

@ -221,13 +221,6 @@ public:
//========================================================================= //=========================================================================
// Declare nets // 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 #ifndef VL_SIG
# define VL_SIG8(name, msb,lsb) CData name ///< Declare signal, 1-8 bits # 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 # define VL_SIG16(name, msb,lsb) SData name ///< Declare signal, 9-16 bits

View File

@ -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, 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");
string otype; VlArgTypeRecurseInfo info;
AstBasicDType* bdtypep = basicp(); info.m_named = named;
bool strtype = bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::STRING; info.m_forFunc = forFunc;
if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::CHARPTR) { info.m_mayParen = false;
otype += "const char*"; info.m_namespc = namespc;
} 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
}
bool mayparen = false; // Need paren, to handle building "(& name)[2]" string ostatic;
string oname; if (isStatic() && info.m_namespc.empty()) ostatic = "static ";
if (isDpiOpenArray() return ostatic + vlArgTypeRecurse(dtypep(), &info, "");
|| (isWide() && !strtype) }
|| (forFunc && (isWritable()
|| direction()==VDirection::REF
|| direction()==VDirection::CONSTREF
|| (strtype && isNonOutput())))) {
oname += "&";
mayparen = true;
}
if (named) oname += " "+VIdProtect::protectIf(name(), protect());
string oarray; string AstVar::vlArgTypeRecurse(AstNodeDType* dtypep, VlArgTypeRecurseInfo* infop,
if (isDpiOpenArray() || direction().isRefOrConstRef()) { const string& inarray) const {
for (AstNodeDType* dtp=dtypep(); dtp; ) { dtypep = dtypep->skipRefp();
dtp = dtp->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
if (AstUnpackArrayDType* adtypep = VN_CAST(dtp, UnpackArrayDType)) { string oarray = "["+cvtToStr(adtypep->declRange().elements())+"]";
if (mayparen) { oname = " ("+oname+")"; mayparen = false; } return vlArgTypeRecurse(adtypep->subDTypep(), infop, inarray+oarray);
oarray += "["+cvtToStr(adtypep->declRange().elements())+"]"; } else if (AstBasicDType* bdtypep = basicp()) {
dtp = adtypep->subDTypep(); string otype;
} else break; 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 { string AstVar::vlEnumType() const {

View File

@ -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 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 string dpiArgType(bool named, bool forReturn) const; // Return DPI-C type for argument
// Return Verilator internal type for argument: CData, SData, IData, WData // 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 vlEnumType() const; // Return VerilatorVarType: VLVT_UINT32, etc
string vlEnumDir() const; // Return VerilatorVarDir: VLVD_INOUT, etc string vlEnumDir() const; // Return VerilatorVarDir: VLVD_INOUT, etc
string vlPropInit() const; // Return VerilatorVarProps initializer string vlPropInit() const; // Return VerilatorVarProps initializer
@ -1410,6 +1410,10 @@ public:
void addConsumingMTaskId(int id) { m_mtaskIds.insert(id); } void addConsumingMTaskId(int id) { m_mtaskIds.insert(id); }
const MTaskIdSet& mtaskIds() const { return m_mtaskIds; } const MTaskIdSet& mtaskIds() const { return m_mtaskIds; }
string mtasksString() const; string mtasksString() const;
private:
class VlArgTypeRecurseInfo;
string vlArgTypeRecurse(AstNodeDType* dtypep, VlArgTypeRecurseInfo* infop,
const string& oarray) const;
}; };
class AstDefParam : public AstNode { class AstDefParam : public AstNode {

View File

@ -1303,71 +1303,34 @@ 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"); UASSERT_OBJ(basicp, nodep, "Unimplemented: Outputting this data type");
if (nodep->isIO()) { if (nodep->isIO() && nodep->isSc()) {
if (nodep->isSc()) { 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 "); } else {
} else { if (nodep->isInoutish()) puts("sc_inout<");
if (nodep->isInoutish()) puts("sc_inout<"); else if (nodep->isWritable()) puts("sc_out<");
else if (nodep->isWritable()) puts("sc_out<"); else if (nodep->isNonOutput()) puts("sc_in<");
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");
else nodep->v3fatalSrc("Unknown type"); else nodep->v3fatalSrc("Unknown type");
if (nodep->isQuad()) puts("64"); puts(nodep->scType());
else if (nodep->widthMin() <= 8) puts("8"); puts("> ");
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");
} }
} else if (basicp && basicp->isOpaque()) { puts(nodep->nameProtect());
// strings and other fundamental c types
puts(nodep->vlArgType(true, false, false));
emitDeclArrayBrackets(nodep); emitDeclArrayBrackets(nodep);
puts(";\n"); puts(";\n");
} else { } else if (nodep->isIO() && basicp && !basicp->isOpaque()) {
// Arrays need a small alignment, but may need different padding after. if (nodep->isInoutish()) puts("VL_INOUT");
// For example three VL_SIG8's needs alignment 1 but size 3. else if (nodep->isWritable()) puts("VL_OUT");
if (nodep->isStatic() && prefixIfImp=="") puts("static "); else if (nodep->isNonOutput()) puts("VL_IN");
if (nodep->isStatic()) puts("VL_ST_"); else puts("VL_"); else nodep->v3fatalSrc("Unknown type");
if (nodep->widthMin() <= 8) {
puts("SIG8("); if (nodep->isQuad()) puts("64");
} else if (nodep->widthMin() <= 16) { else if (nodep->widthMin() <= 8) puts("8");
puts("SIG16("); else if (nodep->widthMin() <= 16) puts("16");
} else if (nodep->isQuad()) { else if (nodep->isWide()) puts("W");
puts("SIG64(");
} else if (!nodep->isWide()) { puts("("+nodep->nameProtect());
puts("SIG(");
} else {
puts("SIGW(");
}
if (prefixIfImp!="") { puts(prefixIfImp); puts("::"); }
puts(nodep->nameProtect());
emitDeclArrayBrackets(nodep); emitDeclArrayBrackets(nodep);
// If it's a packed struct/array then nodep->width is the whole // If it's a packed struct/array then nodep->width is the whole
// thing, msb/lsb is just lowest dimension // thing, msb/lsb is just lowest dimension
@ -1375,6 +1338,10 @@ void EmitCStmts::emitVarDecl(const AstVar* nodep, const string& prefixIfImp) {
+","+cvtToStr(basicp->lsb())); +","+cvtToStr(basicp->lsb()));
if (nodep->isWide()) puts(","+cvtToStr(nodep->widthWords())); if (nodep->isWide()) puts(","+cvtToStr(nodep->widthWords()));
puts(");\n"); puts(");\n");
} else {
// strings and other fundamental c types
puts(nodep->vlArgType(true, false, false, prefixIfImp));
puts(";\n");
} }
} }