Support in/out directions in FST dumps, bug1358.
This commit is contained in:
parent
a5aa0e2b0a
commit
8ef9ac7dba
|
|
@ -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
|
||||
};
|
||||
|
||||
//=========================================================================
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue