diff --git a/include/verilated.h b/include/verilated.h index e5035a35f..2fd7b333f 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -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 }; //========================================================================= diff --git a/include/verilated_fst_c.cpp b/include/verilated_fst_c.cpp index 630c859d9..99123bcc8 100644 --- a/include/verilated_fst_c.cpp +++ b/include/verilated_fst_c.cpp @@ -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 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); } } diff --git a/include/verilated_fst_c.h b/include/verilated_fst_c.h index 85ffc9ddb..fcf1a0812 100644 --- a/include/verilated_fst_c.h +++ b/include/verilated_fst_c.h @@ -55,7 +55,8 @@ private: std::list 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 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 diff --git a/include/verilated_lxt2_c.h b/include/verilated_lxt2_c.h index 59498bcc6..bd665e465 100644 --- a/include/verilated_lxt2_c.h +++ b/include/verilated_lxt2_c.h @@ -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 diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 7e0a178b8..5450399a6 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -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; diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 2fbc7671c..e0150e174 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -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 { diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 282ec8437..1616e3416 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -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 { diff --git a/src/V3TraceDecl.cpp b/src/V3TraceDecl.cpp index d75428222..d8be40079 100644 --- a/src/V3TraceDecl.cpp +++ b/src/V3TraceDecl.cpp @@ -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 "<