Support in/out directions in FST dumps, bug1358.

This commit is contained in:
Wilson Snyder 2018-10-03 19:51:05 -04:00
parent a5aa0e2b0a
commit 8ef9ac7dba
8 changed files with 88 additions and 47 deletions

View File

@ -96,15 +96,16 @@ enum VerilatedVarType {
};
enum VerilatedVarFlags {
VLVD_IN=1, // == vpiInput
VLVD_OUT=2, // == vpiOutput
VLVD_INOUT=3, // == vpiInOut
VLVD_NODIR=5, // == vpiNoDirection
VLVF_MASK_DIR=7, // Bit mask for above directions
VLVD_0 = 0, // None
VLVD_IN = 1, // == vpiInput
VLVD_OUT = 2, // == vpiOutput
VLVD_INOUT = 3, // == vpiInOut
VLVD_NODIR = 5, // == vpiNoDirection
VLVF_MASK_DIR = 7, // Bit mask for above directions
// Flags
VLVF_PUB_RD=(1<<8), // Public readable
VLVF_PUB_RW=(1<<9), // Public writable
VLVF_DPI_CLAY=(1<<10) // DPI compatible C standard layout
VLVF_PUB_RD = (1<<8), // Public readable
VLVF_PUB_RW = (1<<9), // Public writable
VLVF_DPI_CLAY = (1<<10) // DPI compatible C standard layout
};
//=========================================================================

View File

@ -94,7 +94,8 @@ void VerilatedFst::module(const std::string& name) {
//=============================================================================
// Decl
void VerilatedFst::declSymbol(vluint32_t code, const char* name, int arraynum, uint32_t len, enum fstVarType vartype) {
void VerilatedFst::declSymbol(vluint32_t code, const char* name, VerilatedVarFlags varflags,
int arraynum, vluint32_t len, fstVarType vartype) {
std::pair<Code2SymbolType::iterator, bool> p
= m_code2symbol.insert(std::make_pair(code, (fstHandle)(0)));
std::istringstream nameiss(name);
@ -133,11 +134,17 @@ void VerilatedFst::declSymbol(vluint32_t code, const char* name, int arraynum, u
name_ss << "(" << arraynum << ")";
std::string name_str = name_ss.str();
static fstVarDir vardir;
if ((varflags & VLVD_INOUT) == VLVD_INOUT) vardir = FST_VD_INOUT;
else if ((varflags & VLVD_IN) == VLVD_IN) vardir = FST_VD_INPUT;
else if ((varflags & VLVD_OUT) == VLVD_OUT) vardir = FST_VD_OUTPUT;
else vardir = FST_VD_IMPLICIT;
if (p.second) { // New
p.first->second = fstWriterCreateVar(m_fst, vartype, FST_VD_IMPLICIT, len, name_str.c_str(), 0);
p.first->second = fstWriterCreateVar(m_fst, vartype, vardir, len, name_str.c_str(), 0);
assert(p.first->second);
} else { // Alias
fstWriterCreateVar(m_fst, vartype, FST_VD_IMPLICIT, len, name_str.c_str(), p.first->second);
fstWriterCreateVar(m_fst, vartype, vardir, len, name_str.c_str(), p.first->second);
}
}

View File

@ -55,7 +55,8 @@ private:
std::list<std::string> m_curScope;
// CONSTRUCTORS
VL_UNCOPYABLE(VerilatedFst);
void declSymbol(vluint32_t code, const char* name, int arraynum, uint32_t len, fstVarType vartype);
void declSymbol(vluint32_t code, const char* name, VerilatedVarFlags varflags,
int arraynum, vluint32_t len, fstVarType vartype);
// helpers
std::vector<char> m_valueStrBuffer;
char* word2Str(vluint32_t newval, int bits);
@ -95,23 +96,29 @@ public:
/// Inside dumping routines, declare a module
void module(const std::string& name);
/// Inside dumping routines, declare a signal
void declBit(vluint32_t code, const char* name, int arraynum) {
this->declSymbol(code, name, arraynum, 1, FST_VT_VCD_WIRE);
void declBit(vluint32_t code, const char* name, VerilatedVarFlags varflags,
int arraynum) {
declSymbol(code, name, varflags, arraynum, 1, FST_VT_VCD_WIRE);
}
void declBus(vluint32_t code, const char* name, int arraynum, int msb, int lsb) {
this->declSymbol(code, name, arraynum, msb - lsb + 1, FST_VT_VCD_WIRE);
void declBus(vluint32_t code, const char* name, VerilatedVarFlags varflags,
int arraynum, int msb, int lsb) {
declSymbol(code, name, varflags, arraynum, msb - lsb + 1, FST_VT_VCD_WIRE);
}
void declDouble(vluint32_t code, const char* name, int arraynum) {
this->declSymbol(code, name, arraynum, 2, FST_VT_VCD_REAL);
void declDouble(vluint32_t code, const char* name, VerilatedVarFlags varflags,
int arraynum) {
declSymbol(code, name, varflags, arraynum, 2, FST_VT_VCD_REAL);
}
void declFloat(vluint32_t code, const char* name, int arraynum) {
this->declSymbol(code, name, arraynum, 1, FST_VT_SV_SHORTREAL);
void declFloat(vluint32_t code, const char* name, VerilatedVarFlags varflags,
int arraynum) {
declSymbol(code, name, varflags, arraynum, 1, FST_VT_SV_SHORTREAL);
}
void declQuad(vluint32_t code, const char* name, int arraynum, int msb, int lsb) {
this->declSymbol(code, name, arraynum, msb - lsb + 1, FST_VT_VCD_WIRE);
void declQuad(vluint32_t code, const char* name, VerilatedVarFlags varflags,
int arraynum, int msb, int lsb) {
declSymbol(code, name, varflags, arraynum, msb - lsb + 1, FST_VT_VCD_WIRE);
}
void declArray(vluint32_t code, const char* name, int arraynum, int msb, int lsb) {
this->declSymbol(code, name, arraynum, msb - lsb + 1, FST_VT_VCD_WIRE);
void declArray(vluint32_t code, const char* name, VerilatedVarFlags varflags,
int arraynum, int msb, int lsb) {
declSymbol(code, name, varflags, arraynum, msb - lsb + 1, FST_VT_VCD_WIRE);
}
/// Inside dumping routines, dump one signal if it has changed

View File

@ -93,22 +93,22 @@ public:
void module(const std::string& name);
/// Inside dumping routines, declare a signal
void declBit(vluint32_t code, const char* name, int arraynum) {
this->declSymbol(code, name, arraynum, 0, 0, LXT2_WR_SYM_F_BITS);
declSymbol(code, name, arraynum, 0, 0, LXT2_WR_SYM_F_BITS);
}
void declBus(vluint32_t code, const char* name, int arraynum, int msb, int lsb) {
this->declSymbol(code, name, arraynum, msb, lsb, LXT2_WR_SYM_F_BITS);
declSymbol(code, name, arraynum, msb, lsb, LXT2_WR_SYM_F_BITS);
}
void declDouble(vluint32_t code, const char* name, int arraynum) {
this->declSymbol(code, name, arraynum, 63, 0, LXT2_WR_SYM_F_DOUBLE);
declSymbol(code, name, arraynum, 63, 0, LXT2_WR_SYM_F_DOUBLE);
}
void declFloat(vluint32_t code, const char* name, int arraynum) {
this->declSymbol(code, name, arraynum, 63, 0, LXT2_WR_SYM_F_DOUBLE);
declSymbol(code, name, arraynum, 63, 0, LXT2_WR_SYM_F_DOUBLE);
}
void declQuad(vluint32_t code, const char* name, int arraynum, int msb, int lsb) {
this->declSymbol(code, name, arraynum, msb, lsb, LXT2_WR_SYM_F_BITS);
declSymbol(code, name, arraynum, msb, lsb, LXT2_WR_SYM_F_BITS);
}
void declArray(vluint32_t code, const char* name, int arraynum, int msb, int lsb) {
this->declSymbol(code, name, arraynum, msb, lsb, LXT2_WR_SYM_F_BITS);
declSymbol(code, name, arraynum, msb, lsb, LXT2_WR_SYM_F_BITS);
}
/// Inside dumping routines, dump one signal if it has changed

View File

@ -185,8 +185,10 @@ void AstVar::combineType(AstVarType type) {
if (type == AstVarType::SUPPLY1) type = AstVarType::WIRE;
m_varType=type; // For debugging prints only
// These flags get combined with the existing settings of the flags.
if (type==AstVarType::INPUT || type==AstVarType::INOUT)
if (type==AstVarType::INPUT || type==AstVarType::INOUT) {
m_input = true;
m_declInput = true;
}
if (type==AstVarType::OUTPUT || type==AstVarType::INOUT) {
m_output = true;
m_declOutput = true;

View File

@ -1096,7 +1096,8 @@ private:
bool m_input:1; // Input or inout
bool m_output:1; // Output or inout
bool m_tristate:1; // Inout or triwire or trireg
bool m_declOutput:1; // Inout or output before tristate resolution
bool m_declInput:1; // Inout or input before tristate and inline resolution
bool m_declOutput:1; // Inout or output before tristate and inline resolution
bool m_primaryIO:1; // In/out to top level (or directly assigned from same)
bool m_sc:1; // SystemC variable
bool m_scClocked:1; // SystemC sc_clk<> needed
@ -1128,7 +1129,7 @@ private:
MTaskIdSet m_mtaskIds; // MTaskID's that read or write this var
void init() {
m_input=false; m_output=false; m_tristate=false; m_declOutput=false;
m_input=false; m_output=false; m_tristate=false; m_declInput=false; m_declOutput=false;
m_primaryIO=false;
m_sc=false; m_scClocked=false; m_scSensitive=false;
m_usedClock=false; m_usedParam=false; m_usedLoopIdx=false;
@ -1247,13 +1248,14 @@ public:
virtual string tag() const { return m_tag; }
virtual string directionName() const { return (isInout() ? "inout" : isInput() ? "input"
: isOutput() ? "output" : varType().ascii()); }
bool isInput() const { return m_input; }
bool isOutput() const { return m_output; }
bool isInOnly() const { return m_input && !m_output; }
bool isOutOnly() const { return m_output && !m_input; }
bool isInout() const { return m_input && m_output; }
bool isTristate() const { return m_tristate; }
bool isDeclOutput() const { return m_declOutput; }
bool isInput() const { return m_input; }
bool isOutput() const { return m_output; }
bool isInOnly() const { return m_input && !m_output; }
bool isOutOnly() const { return m_output && !m_input; }
bool isInout() const { return m_input && m_output; }
bool isTristate() const { return m_tristate; }
bool isDeclInput() const { return m_declInput; }
bool isDeclOutput() const { return m_declOutput; }
bool isPrimaryIO() const { return m_primaryIO; }
bool isPrimaryIn() const { return isPrimaryIO() && isInput(); }
bool isIO() const { return (m_input||m_output); }
@ -3351,8 +3353,13 @@ private:
VNumRange m_bitRange; // Property of var the trace details
VNumRange m_arrayRange; // Property of var the trace details
uint32_t m_codeInc; // Code increment
AstVarType m_varType; // Type of variable (for localparam vs. param)
bool m_declInput:1; // Input or inout
bool m_declOutput:1; // Output or inout
public:
AstTraceDecl(FileLine* fl, const string& showname, AstNode* valuep,
AstTraceDecl(FileLine* fl, const string& showname,
AstVar* varp, // For input/output state etc
AstNode* valuep,
const VNumRange& bitRange, const VNumRange& arrayRange)
: AstNodeStmt(fl)
, m_showname(showname), m_bitRange(bitRange), m_arrayRange(arrayRange) {
@ -3360,20 +3367,27 @@ public:
m_code = 0;
m_codeInc = ((arrayRange.ranged() ? arrayRange.elements() : 1)
* valuep->dtypep()->widthWords());
m_varType = varp->varType();
m_declInput = varp->isDeclInput();
m_declOutput = varp->isDeclOutput();
}
virtual int instrCount() const { return 100; } // Large...
virtual int instrCount() const { return 100; } // Large...
ASTNODE_NODE_FUNCS(TraceDecl)
virtual string name() const { return m_showname; }
virtual string name() const { return m_showname; }
virtual bool maybePointedTo() const { return true; }
virtual bool hasDType() const { return true; }
virtual bool same(const AstNode* samep) const { return false; }
string showname() const { return m_showname; } // * = Var name
// Details on what we're tracing
uint32_t code() const { return m_code; }
void code(uint32_t code) { m_code=code; }
uint32_t codeInc() const { return m_codeInc; }
uint32_t code() const { return m_code; }
void code(uint32_t code) { m_code=code; }
uint32_t codeInc() const { return m_codeInc; }
const VNumRange& bitRange() const { return m_bitRange; }
const VNumRange& arrayRange() const { return m_arrayRange; }
AstVarType varType() const { return m_varType; }
bool declInput() const { return m_declInput; }
bool declOutput() const { return m_declOutput; }
bool declInout() const { return m_declInput && m_declOutput; }
};
class AstTraceInc : public AstNodeStmt {

View File

@ -2831,10 +2831,19 @@ class EmitCTrace : EmitCStmts {
} else {
puts("vcdp->declBit ");
}
puts("(c+"+cvtToStr(nodep->code()));
if (nodep->arrayRange().ranged()) puts("+i*"+cvtToStr(nodep->widthWords()));
puts(",");
putsQuoted(nodep->showname());
// Direction
if (v3Global.opt.traceFormat() == TraceFormat::FST) {
if (nodep->declInout()) puts(",VLVD_INOUT");
else if (nodep->declInput()) puts(",VLVD_IN");
else if (nodep->declOutput()) puts(",VLVD_OUT");
else puts(",VLVD_0");
}
// Range
if (nodep->arrayRange().ranged()) {
puts(",(i+"+cvtToStr(nodep->arrayRange().lo())+")");
} else {

View File

@ -110,7 +110,8 @@ private:
AstBasicDType* bdtypep = m_traValuep->dtypep()->basicp();
if (widthOverride) bitRange = VNumRange(widthOverride-1,0,false);
else if (bdtypep) bitRange = bdtypep->nrange();
AstTraceDecl* declp = new AstTraceDecl(m_traVscp->fileline(), m_traShowname, m_traValuep,
AstTraceDecl* declp = new AstTraceDecl(m_traVscp->fileline(), m_traShowname,
m_traVscp->varp(), m_traValuep,
bitRange, arrayRange);
UINFO(9,"Decl "<<declp<<endl);