DPI: Constify new $sformatf

This commit is contained in:
Wilson Snyder 2010-01-17 20:06:08 -05:00
parent 72b596efb3
commit 27e4503dc6
7 changed files with 72 additions and 6 deletions

View File

@ -83,6 +83,34 @@ public:
virtual int instrCount() const { return widthInstrs(); }
};
struct AstConstString : public AstNodeMath {
// A constant string
private:
string m_name;
public:
AstConstString(FileLine* fl, const string& name)
: AstNodeMath(fl), m_name(name) {
rewidth();
}
void rewidth() {
if (m_name.length()==0) {
width(1,1); // 0 width isn't allowed due to historic special cases
} else {
width(m_name.length()*8, m_name.length()*8);
}
}
ASTNODE_NODE_FUNCS(ConstString, CONSTSTRING)
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() { return true; }
virtual V3Hash sameHash() const { return V3Hash(name()); }
virtual bool same(AstNode* samep) const {
return name()==samep->castConstString()->name(); }
virtual int instrCount() const { return 2; } // C just loads a pointer
virtual string name() const { return m_name; }
void name(const string& flag) { m_name = flag; rewidth(); }
};
struct AstRange : public AstNode {
// Range specification, for use under variables and cells
private:
@ -1511,10 +1539,12 @@ public:
class AstSFormatF : public AstNode {
// Convert format to string, generally under a AstDisplay or AstSFormat
// Also used as "real" function for /*verilator sformat*/ functions
string m_text;
bool m_hidden; // Under display, etc
public:
AstSFormatF(FileLine* fl, const string& text, AstNode* exprsp)
: AstNode(fl), m_text(text) {
AstSFormatF(FileLine* fl, const string& text, bool hidden, AstNode* exprsp)
: AstNode(fl), m_text(text), m_hidden(hidden) {
addNOp1p(exprsp); addNOp2p(NULL); }
ASTNODE_NODE_FUNCS(SFormatF, SFORMATF)
virtual string name() const { return m_text; }
@ -1530,6 +1560,7 @@ public:
void scopeNamep(AstNode* nodep) { setNOp2p(nodep); }
bool formatScopeTracking() const { // Track scopeNamep(); Ok if false positive
return (name().find("%m") != string::npos || name().find("%M") != string::npos); }
bool hidden() const { return m_hidden; }
};
struct AstDisplay : public AstNode {
@ -1541,7 +1572,7 @@ private:
public:
AstDisplay(FileLine* fileline, AstDisplayType dispType, const string& text, AstNode* filep, AstNode* exprsp)
: AstNode (fileline) {
setNOp1p(new AstSFormatF(fileline,text,exprsp));
setOp1p(new AstSFormatF(fileline,text,true,exprsp));
setNOp3p(filep);
m_displayType = dispType;
}
@ -1573,7 +1604,7 @@ struct AstSFormat : public AstNode {
// Children: SFORMATF to generate print string
AstSFormat(FileLine* fileline, AstNode* lhsp, const string& text, AstNode* exprsp)
: AstNode (fileline) {
setOp1p(new AstSFormatF(fileline,text,exprsp));
setOp1p(new AstSFormatF(fileline,text,true,exprsp));
setOp3p(lhsp);
}
ASTNODE_NODE_FUNCS(SFormat, SFORMAT)

View File

@ -432,6 +432,15 @@ private:
replaceNum(nodep, num); nodep=NULL;
}
void replaceConstString (AstNode* oldp, const string& num) {
// Replace oldp node with a constant set to specified value
UASSERT (oldp, "Null old\n");
AstNode* newp = new AstConstString(oldp->fileline(), num);
if (debug()>5) oldp->dumpTree(cout," const_old: ");
if (debug()>5) newp->dumpTree(cout," _new: ");
oldp->replaceWith(newp);
oldp->deleteTree(); oldp=NULL;
}
//----------------------------------------
// Replacement functions.
// These all take a node and replace it with something else
@ -1459,6 +1468,12 @@ private:
nodep->text(dispout);
//UINFO(9," Display out "<<nodep->text()<<endl);
}
if (!nodep->exprsp()
&& nodep->name().find("%") == string::npos
&& !nodep->hidden()) {
// Just a simple constant string - the formatting is pointless
replaceConstString(nodep, nodep->name()); nodep=NULL;
}
}
virtual void visit(AstFuncRef* nodep, AstNUser*) {
@ -1712,6 +1727,9 @@ private:
TREEOPV("AstRedXnor{$lhsp}", "AstNot{AstRedXor{$lhsp}}"); // Just eliminate XNOR's
TREEOPV("AstLogIf {$lhsp, $rhsp}", "AstLogOr{AstLogNot{$lhsp},$rhsp}");
TREEOPV("AstLogIff{$lhsp, $rhsp}", "AstLogNot{AstXor{$lhsp,$rhsp}}");
// Strings
TREEOP ("AstCvtPackString{$lhsp.castConst}", "replaceConstString(nodep, nodep->lhsp()->castConst()->num().toString())");
// Possible futures:
// (a?(b?y:x):y) -> (a&&!b)?x:y

View File

@ -563,6 +563,9 @@ public:
emitConstant(nodep, NULL, "");
}
}
virtual void visit(AstConstString* nodep, AstNUser*) {
putsQuoted(nodep->name());
}
// Just iterate
virtual void visit(AstNetlist* nodep, AstNUser*) {

View File

@ -456,6 +456,10 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
virtual void visit(AstConst* nodep, AstNUser*) {
putfs(nodep,nodep->num().ascii(true,true));
}
virtual void visit(AstConstString* nodep, AstNUser*) {
putfs(nodep,"");
putsQuoted(nodep->name());
}
// Just iterate
virtual void visit(AstTopScope* nodep, AstNUser*) {

View File

@ -448,6 +448,9 @@ private:
// We don't size the constant until we commit the widths, as need parameters
// to remain unsized, and numbers to remain unsized to avoid backp() warnings
}
virtual void visit(AstConstString* nodep, AstNUser* vup) {
nodep->rewidth();
}
virtual void visit(AstRand* nodep, AstNUser* vup) {
if (vup->c()->prelim()) {
nodep->width(32,32); // Says the spec
@ -962,7 +965,7 @@ private:
string format;
if (pinp->castConst()) format = pinp->castConst()->num().toString();
else pinp->v3error("Format to $display-like function must have constant format string");
AstSFormatF* newp = new AstSFormatF(nodep->fileline(), format, argsp);
AstSFormatF* newp = new AstSFormatF(nodep->fileline(), format, false, argsp);
if (!newp->scopeNamep() && newp->formatScopeTracking()) {
newp->scopeNamep(new AstScopeName(newp->fileline()));
}

View File

@ -2066,7 +2066,7 @@ system_f_call<nodep>: // IEEE: system_tf_call (as func)
| yD_ONEHOT0 '(' expr ')' { $$ = new AstOneHot0($1,$3); }
| yD_RANDOM '(' expr ')' { $1->v3error("Unsupported: Seeding $random doesn't map to C++, use $c(\"srand\")"); }
| yD_RANDOM parenE { $$ = new AstRand($1); }
//| yD_SFORMATF '(' str commaEListE ')' { $$ = new AstSFormatF($1,*$3,$4); } // Have AST, just need testing and debug
//| yD_SFORMATF '(' str commaEListE ')' { $$ = new AstSFormatF($1,*$3,false,$4); } // Have AST, just need testing and debug
| yD_SIGNED '(' expr ')' { $$ = new AstSigned($1,$3); }
| yD_STIME parenE { $$ = new AstSel($1,new AstTime($1),0,32); }
| yD_TIME parenE { $$ = new AstTime($1); }

View File

@ -98,6 +98,8 @@ module t ();
bit [127:0] wide;
bit [6*8:1] string6;
initial begin
wide = 128'h36f3e51d15caff7a73c48afee4ffcb57;
@ -165,6 +167,11 @@ module t ();
if (dpii_f_strlen ("stri")!=4) $stop;
if (dpii_f_strlen ("string_l")!=8) $stop;
if (dpii_f_strlen ("string_len")!=10) $stop;
string6 = "hello6";
`ifdef VERILATOR
string6 = $c48(string6); // Don't optimize away - want to see the constant conversion function
`endif
if (dpii_f_strlen (string6) != 6) $stop;
dpii_f_void();
dpii_t_void();