Merge branch 'master' into split_var0
This commit is contained in:
commit
34a6499218
10
Changes
10
Changes
|
|
@ -5,11 +5,15 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
|||
|
||||
* Verilator 4.027 devel
|
||||
|
||||
** Support attributes (public, isolate_assignments, etc.) in configuration files.
|
||||
** Support attributes (public, isolate_assignments, etc.) in configuration files.
|
||||
|
||||
** Add -match to lint_off to waive warnings. [Philipp Wagner]
|
||||
** Add -match to lint_off to waive warnings. [Philipp Wagner]
|
||||
|
||||
*** Support $readmem/$writemem with assoc arrarys. Closes #2100. [agrobman]
|
||||
*** Support $readmem/$writemem with assoc arrarys. Closes #2100. [agrobman]
|
||||
|
||||
**** Support left justified $display. Closes #2101. [Pieter Kapsenberg]
|
||||
|
||||
**** Add parameter values in XML. #2110. [Pieter Kapsenberg]
|
||||
|
||||
**** Add error on misused define. [Topa Tota]
|
||||
|
||||
|
|
|
|||
17
README.adoc
17
README.adoc
|
|
@ -16,6 +16,7 @@ ifndef::env-github[]
|
|||
:link_verilator_contributing: https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.adoc
|
||||
:link_verilator_install: https://verilator.org/install
|
||||
endif::[]
|
||||
:link_verilator_commercial_support: https://verilator.org/verilator_commercial_support
|
||||
|
||||
== Welcome to Verilator
|
||||
|
||||
|
|
@ -38,12 +39,18 @@ endif::[]
|
|||
+++ <br/> +++ • Out-of-the-box support from Arm, and RISC-V vendor IP
|
||||
<.^|image:https://www.veripool.org/img/verilator_usage_400x200-min.png[,400,200]
|
||||
|
||||
>.^|image:https://www.veripool.org/img/chips_alliance_logo_225x75-min.png[CHIPS Alliance,link=https://chipsalliance.org]
|
||||
image:https://www.veripool.org/img/osi_logo_125x125-min.png[,125,125]
|
||||
>.^|image:https://www.veripool.org/img/verilator_community_400x125-min.png[,400,125]
|
||||
^.^| *Community Driven & Openly Licensed*
|
||||
+++ <br/> +++ • Guided by the https://chipsalliance.org/[CHIPS Alliance] and https://www.linuxfoundation.org/[Linux Foundation]
|
||||
+++ <br/> +++ • Open, and free as in both speech and beer
|
||||
+++ <br/> +++ • More simulation for your verification budget
|
||||
|
||||
^.^| *Commercial Support Available*
|
||||
+++ <br/> +++ • Commercial support contracts
|
||||
+++ <br/> +++ • Design support contracts
|
||||
+++ <br/> +++ • Enhancement contracts
|
||||
<.^|image:https://www.veripool.org/img/verilator_support_400x125-min.png[,400,125]
|
||||
|
||||
|===
|
||||
|
||||
== What Verilator Does
|
||||
|
|
@ -109,7 +116,7 @@ or https://verilator.org/verilator_doc.pdf[Verilator manual (PDF)]
|
|||
|
||||
* https://verilator.org/issues[Verilator Issues]
|
||||
|
||||
== Community Supported
|
||||
== Support
|
||||
|
||||
Verilator is a community project, guided by the
|
||||
https://chipsalliance.org/[CHIPS Alliance] under the
|
||||
|
|
@ -120,6 +127,10 @@ We appreciate and welcome your contributions in whatever form; please see
|
|||
https://verilator.org/verilator_doc.html#CONTRIBUTORS[Contributors and
|
||||
Sponsors].
|
||||
|
||||
Verilator also supports and encourages commercial support models and
|
||||
organizations; please see {link_verilator_commercial_support}[Verilator
|
||||
Commercial Support].
|
||||
|
||||
== Related Projects
|
||||
|
||||
* http://gtkwave.sourceforge.net/[GTKwave] - Waveform viewer for Verilator
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ contributions flow more efficiently.
|
|||
https://verilator.org/issues[Verilator Issues].
|
||||
|
||||
* If you're unable to find an open issue addressing the problem,
|
||||
https://verilator.org/issues/new[open a new issue].
|
||||
https://verilator.org/issues/new[open a new Verilator issue].
|
||||
|
||||
** Be sure to include a **code sample** or an **executable test case**
|
||||
demonstrating the bug and expected behavior that is not occurring.
|
||||
|
|
|
|||
|
|
@ -24,12 +24,14 @@ Lukasz Dalek
|
|||
Maarten De Braekeleer
|
||||
Matthew Ballance
|
||||
Mike Popoloski
|
||||
Peter Monsson
|
||||
Patrick Stewart
|
||||
Peter Monsson
|
||||
Philipp Wagner
|
||||
Pieter Kapsenberg
|
||||
Richard Myers
|
||||
Sebastien Van Cauwenberghe
|
||||
Stefan Wallentowitz
|
||||
Tobias Rosenkranz
|
||||
Todd Strader
|
||||
Wilson Snyder
|
||||
Yutetsu TAKATSUKASA
|
||||
|
|
|
|||
|
|
@ -618,7 +618,8 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
|||
const char* pctp = NULL; // Most recent %##.##g format
|
||||
bool inPct = false;
|
||||
bool widthSet = false;
|
||||
int width = 0;
|
||||
bool left = false;
|
||||
size_t width = 0;
|
||||
for (const char* pos = formatp; *pos; ++pos) {
|
||||
if (!inPct && pos[0]=='%') {
|
||||
pctp = pos;
|
||||
|
|
@ -643,6 +644,10 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
|||
widthSet = true;
|
||||
width = width*10 + (fmt - '0');
|
||||
break;
|
||||
case '-':
|
||||
left = true;
|
||||
inPct = true; // Get more digits
|
||||
break;
|
||||
case '.':
|
||||
inPct = true; // Get more digits
|
||||
break;
|
||||
|
|
@ -662,8 +667,9 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
|||
case '@': { // Verilog/C++ string
|
||||
va_arg(ap, int); // # bits is ignored
|
||||
const std::string* cstrp = va_arg(ap, const std::string*);
|
||||
if (width > cstrp->size()) output += std::string(width - cstrp->size(), ' ');
|
||||
output += *cstrp;
|
||||
std::string padding;
|
||||
if (width > cstrp->size()) padding.append(width - cstrp->size(), ' ');
|
||||
output += left ? (*cstrp + padding) : (padding + *cstrp);
|
||||
break;
|
||||
}
|
||||
case 'e':
|
||||
|
|
@ -721,8 +727,9 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
|||
IData charval = VL_BITRSHIFT_W(lwp, lsb) & 0xff;
|
||||
field += (charval==0)?' ':charval;
|
||||
}
|
||||
if (width > field.size()) output += std::string(width - field.size(), ' ');
|
||||
output += field;
|
||||
std::string padding;
|
||||
if (width > field.size()) padding.append(width - field.size(), ' ');
|
||||
output += left ? (field + padding) : (padding + field);
|
||||
break;
|
||||
}
|
||||
case 'd': { // Signed decimal
|
||||
|
|
@ -743,14 +750,15 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
|||
digits = append.length();
|
||||
}
|
||||
int needmore = width-digits;
|
||||
std::string padding;
|
||||
if (needmore>0) {
|
||||
if (pctp && pctp[0] && pctp[1]=='0') { // %0
|
||||
output.append(needmore, '0'); // Pre-pad zero
|
||||
padding.append(needmore, '0'); // Pre-pad zero
|
||||
} else {
|
||||
output.append(needmore, ' '); // Pre-pad spaces
|
||||
padding.append(needmore, ' '); // Pre-pad spaces
|
||||
}
|
||||
}
|
||||
output += append;
|
||||
output += left ? (append + padding) : (padding + append);
|
||||
break;
|
||||
}
|
||||
case '#': { // Unsigned decimal
|
||||
|
|
@ -764,14 +772,15 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
|||
digits = append.length();
|
||||
}
|
||||
int needmore = width-digits;
|
||||
std::string padding;
|
||||
if (needmore>0) {
|
||||
if (pctp && pctp[0] && pctp[1]=='0') { // %0
|
||||
output.append(needmore, '0'); // Pre-pad zero
|
||||
padding.append(needmore, '0'); // Pre-pad zero
|
||||
} else {
|
||||
output.append(needmore, ' '); // Pre-pad spaces
|
||||
padding.append(needmore, ' '); // Pre-pad spaces
|
||||
}
|
||||
}
|
||||
output += append;
|
||||
output += left ? (append + padding) : (padding + append);
|
||||
break;
|
||||
}
|
||||
case 't': { // Time
|
||||
|
|
@ -786,8 +795,9 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
|||
VL_FATAL_MT(__FILE__, __LINE__, "", "Unsupported VL_TIME_MULTIPLIER");
|
||||
}
|
||||
int needmore = width-digits;
|
||||
if (needmore>0) output.append(needmore, ' '); // Pre-pad spaces
|
||||
output += tmp;
|
||||
std::string padding;
|
||||
if (needmore>0) padding.append(needmore, ' '); // Pad with spaces
|
||||
output += left ? (tmp + padding) : (padding + tmp);
|
||||
break;
|
||||
}
|
||||
case 'b':
|
||||
|
|
@ -1740,9 +1750,7 @@ void VlReadMem::setData(void* valuep, const std::string& rhs) {
|
|||
}
|
||||
|
||||
VlWriteMem::VlWriteMem(bool hex, int bits, const std::string& filename, QData start, QData end)
|
||||
: m_hex(hex)
|
||||
, m_bits(bits)
|
||||
, m_filename(filename)
|
||||
: m_bits(bits)
|
||||
, m_addr(0) {
|
||||
if (VL_UNLIKELY(!hex)) {
|
||||
VL_FATAL_MT(filename.c_str(), 0, "",
|
||||
|
|
|
|||
|
|
@ -65,9 +65,7 @@ public:
|
|||
};
|
||||
|
||||
class VlWriteMem {
|
||||
bool m_hex; // Hex format
|
||||
int m_bits; // Bit width of values
|
||||
const std::string& m_filename; // Filename
|
||||
FILE* m_fp; // File handle for filename
|
||||
QData m_addr; // Next address to write
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -160,9 +160,13 @@
|
|||
# define VL_DANGLING(var) do { (var) = NULL; } while(0)
|
||||
#endif
|
||||
|
||||
///< Perform an e.g. delete, then set variable to NULL to indicate must not use later
|
||||
///< Perform an e.g. delete, then set variable to NULL to indicate must not use later.
|
||||
///< Unlike VL_DO_CLEAR the setting of the variable is only for debug reasons.
|
||||
#define VL_DO_DANGLING(stmt, var) do { do { stmt; } while(0); VL_DANGLING(var); } while(0)
|
||||
|
||||
///< Perform an e.g. delete, then set variable to NULL as a requirement
|
||||
#define VL_DO_CLEAR(stmt, stmt2) do { do { stmt; } while(0); do { stmt2; } while(0); } while(0)
|
||||
|
||||
//=========================================================================
|
||||
// C++-2011
|
||||
|
||||
|
|
|
|||
17
src/V3Ast.h
17
src/V3Ast.h
|
|
@ -1724,12 +1724,15 @@ public:
|
|||
|
||||
class AstNodeStmt : public AstNode {
|
||||
// Statement -- anything that's directly under a function
|
||||
bool m_statement; // Really a statement (e.g. not a function with return)
|
||||
public:
|
||||
explicit AstNodeStmt(FileLine* fl)
|
||||
: AstNode(fl) {}
|
||||
explicit AstNodeStmt(FileLine* fl, bool statement = true)
|
||||
: AstNode(fl)
|
||||
, m_statement(statement) {}
|
||||
ASTNODE_BASE_FUNCS(NodeStmt)
|
||||
// METHODS
|
||||
virtual bool isStatement() const { return true; } // Really a statement
|
||||
bool isStatement() const { return m_statement; } // Really a statement
|
||||
void statement(bool flag) { m_statement = flag; }
|
||||
virtual void addNextStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here
|
||||
virtual void addBeforeStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here
|
||||
};
|
||||
|
|
@ -2171,13 +2174,13 @@ private:
|
|||
string m_inlinedDots; // Dotted hierarchy flattened out
|
||||
AstPackage* m_packagep; // Package hierarchy
|
||||
public:
|
||||
AstNodeFTaskRef(FileLine* fl, AstNode* namep, AstNode* pinsp)
|
||||
: AstNodeStmt(fl)
|
||||
AstNodeFTaskRef(FileLine* fl, bool statement, AstNode* namep, AstNode* pinsp)
|
||||
: AstNodeStmt(fl, statement)
|
||||
, m_taskp(NULL), m_packagep(NULL) {
|
||||
setOp1p(namep); addNOp2p(pinsp);
|
||||
}
|
||||
AstNodeFTaskRef(FileLine* fl, const string& name, AstNode* pinsp)
|
||||
: AstNodeStmt(fl)
|
||||
AstNodeFTaskRef(FileLine* fl, bool statement, const string& name, AstNode* pinsp)
|
||||
: AstNodeStmt(fl, statement)
|
||||
, m_taskp(NULL), m_name(name), m_packagep(NULL) {
|
||||
addNOp2p(pinsp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -999,6 +999,12 @@ void AstJumpGo::dump(std::ostream& str) const {
|
|||
if (labelp()) { labelp()->dump(str); }
|
||||
else { str<<"%Error:UNLINKED"; }
|
||||
}
|
||||
void AstMemberSel::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
str << " -> ";
|
||||
if (varp()) { varp()->dump(str); }
|
||||
else { str << "%Error:UNLINKED"; }
|
||||
}
|
||||
void AstModportFTaskRef::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
if (isExport()) str<<" EXPORT";
|
||||
|
|
|
|||
|
|
@ -1366,39 +1366,40 @@ public:
|
|||
void addPinsp(AstNode* nodep) { addOp2p(nodep); }
|
||||
};
|
||||
|
||||
class AstCMethodCall : public AstNodeStmt {
|
||||
class AstCMethodHard : public AstNodeStmt {
|
||||
// A reference to a "C" hardocded member task (or function)
|
||||
// PARENTS: stmt/math
|
||||
// Not all calls are statments vs math. AstNodeStmt needs isStatement() to deal.
|
||||
private:
|
||||
string m_name; // Name of method
|
||||
bool m_pure; // Pure optimizable
|
||||
bool m_statement; // Is a statement (AstNodeMath-like) versus AstNodeStmt-like
|
||||
public:
|
||||
AstCMethodCall(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name,
|
||||
AstCMethodHard(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name,
|
||||
AstNode* pinsp)
|
||||
: AstNodeStmt(fl), m_name(name), m_pure(false), m_statement(false) {
|
||||
: AstNodeStmt(fl, false)
|
||||
, m_name(name)
|
||||
, m_pure(false) {
|
||||
setOp1p(fromp);
|
||||
dtypep(NULL); // V3Width will resolve
|
||||
addNOp2p(pinsp);
|
||||
}
|
||||
AstCMethodCall(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp)
|
||||
: AstNodeStmt(fl), m_name(name), m_statement(false) {
|
||||
AstCMethodHard(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp)
|
||||
: AstNodeStmt(fl, false)
|
||||
, m_name(name) {
|
||||
setOp1p(fromp);
|
||||
addNOp2p(pinsp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(CMethodCall)
|
||||
ASTNODE_NODE_FUNCS(CMethodHard)
|
||||
virtual string name() const { return m_name; } // * = Var name
|
||||
virtual bool hasDType() const { return true; }
|
||||
virtual void name(const string& name) { m_name = name; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(m_name); }
|
||||
virtual bool same(const AstNode* samep) const {
|
||||
const AstCMethodCall* asamep = static_cast<const AstCMethodCall*>(samep);
|
||||
const AstCMethodHard* asamep = static_cast<const AstCMethodHard*>(samep);
|
||||
return (m_name == asamep->m_name); }
|
||||
virtual bool isStatement() const { return m_statement; }
|
||||
virtual bool isPure() const { return m_pure; }
|
||||
void pure(bool flag) { m_pure = flag; }
|
||||
void makeStatement() { m_statement = true; dtypeSetVoid(); }
|
||||
void makeStatement() { statement(true); dtypeSetVoid(); }
|
||||
AstNode* fromp() const { return op1p(); } // op1 = Extracting what (NULL=TBD during parsing)
|
||||
void fromp(AstNode* nodep) { setOp1p(nodep); }
|
||||
AstNode* pinsp() const { return op2p(); } // op2 = Pin interconnection list
|
||||
|
|
@ -2064,6 +2065,7 @@ public:
|
|||
virtual void cloneRelink() { if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep(); } }
|
||||
virtual const char* broken() const {
|
||||
BROKEN_RTN(m_varp && !m_varp->brokeExists()); return NULL; }
|
||||
virtual void dump(std::ostream& str) const;
|
||||
virtual string name() const { return m_name; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(m_name); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) {
|
||||
|
|
@ -2430,22 +2432,22 @@ class AstTaskRef : public AstNodeFTaskRef {
|
|||
// A reference to a task
|
||||
public:
|
||||
AstTaskRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp)
|
||||
: AstNodeFTaskRef(fl, namep, pinsp) {}
|
||||
: AstNodeFTaskRef(fl, true, namep, pinsp) {
|
||||
statement(true);
|
||||
}
|
||||
AstTaskRef(FileLine* fl, const string& name, AstNode* pinsp)
|
||||
: AstNodeFTaskRef(fl, name, pinsp) {}
|
||||
: AstNodeFTaskRef(fl, true, name, pinsp) {}
|
||||
ASTNODE_NODE_FUNCS(TaskRef)
|
||||
virtual bool isStatement() const { return true; } // A statement, unlike FuncRef
|
||||
};
|
||||
|
||||
class AstFuncRef : public AstNodeFTaskRef {
|
||||
// A reference to a function
|
||||
public:
|
||||
AstFuncRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp)
|
||||
: AstNodeFTaskRef(fl, namep, pinsp) {}
|
||||
: AstNodeFTaskRef(fl, false, namep, pinsp) {}
|
||||
AstFuncRef(FileLine* fl, const string& name, AstNode* pinsp)
|
||||
: AstNodeFTaskRef(fl, name, pinsp) {}
|
||||
: AstNodeFTaskRef(fl, false, name, pinsp) {}
|
||||
ASTNODE_NODE_FUNCS(FuncRef)
|
||||
virtual bool isStatement() const { return false; } // Not a statement, unlike TaskRef
|
||||
virtual bool hasDType() const { return true; }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -761,7 +761,7 @@ public:
|
|||
}
|
||||
}
|
||||
virtual ~CdcVisitor() {
|
||||
if (m_ofp) { delete m_ofp; m_ofp = NULL; }
|
||||
if (m_ofp) VL_DO_CLEAR(delete m_ofp, m_ofp = NULL);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ private:
|
|||
insureCleanAndNext(nodep->argsp());
|
||||
setClean(nodep, true);
|
||||
}
|
||||
virtual void visit(AstCMethodCall* nodep) {
|
||||
virtual void visit(AstCMethodHard* nodep) {
|
||||
iterateChildren(nodep);
|
||||
insureCleanAndNext(nodep->pinsp());
|
||||
setClean(nodep, true);
|
||||
|
|
|
|||
|
|
@ -2072,7 +2072,7 @@ private:
|
|||
if (!inPct && ch=='%') {
|
||||
inPct = true;
|
||||
fmt = ch;
|
||||
} else if (inPct && (isdigit(ch) || ch=='.')) {
|
||||
} else if (inPct && (isdigit(ch) || ch=='.' || ch=='-')) {
|
||||
fmt += ch;
|
||||
} else if (inPct) {
|
||||
inPct = false;
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ private:
|
|||
: m_comment(comment), m_varRefp(vp), m_chgRefp(cp) {}
|
||||
~ToggleEnt() {}
|
||||
void cleanup() {
|
||||
m_varRefp->deleteTree(); m_varRefp = NULL;
|
||||
m_chgRefp->deleteTree(); m_chgRefp = NULL;
|
||||
VL_DO_CLEAR(m_varRefp->deleteTree(), m_varRefp = NULL);
|
||||
VL_DO_CLEAR(m_chgRefp->deleteTree(), m_chgRefp = NULL);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ private:
|
|||
return (!nodep->isSigPublic() // Can't elim publics!
|
||||
&& !nodep->isIO()
|
||||
&& ((nodep->isTemp() && !nodep->isTrace())
|
||||
|| (nodep->isParam() && !nodep->isTrace())
|
||||
|| (nodep->isParam() && !nodep->isTrace() && !v3Global.opt.xmlOnly())
|
||||
|| m_elimUserVars)); // Post-Trace can kill most anything
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ public:
|
|||
} else if (nodep->isWide()
|
||||
&& VN_IS(nodep->lhsp(), VarRef)
|
||||
&& !VN_IS(nodep->rhsp(), CMath)
|
||||
&& !VN_IS(nodep->rhsp(), CMethodCall)
|
||||
&& !VN_IS(nodep->rhsp(), CMethodHard)
|
||||
&& !VN_IS(nodep->rhsp(), VarRef)
|
||||
&& !VN_IS(nodep->rhsp(), AssocSel)
|
||||
&& !VN_IS(nodep->rhsp(), ArraySel)) {
|
||||
|
|
@ -257,7 +257,7 @@ public:
|
|||
puts(");\n");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCMethodCall* nodep) {
|
||||
virtual void visit(AstCMethodHard* nodep) {
|
||||
iterate(nodep->fromp());
|
||||
puts(".");
|
||||
puts(nodep->nameProtect());
|
||||
|
|
@ -1797,7 +1797,8 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep,
|
|||
switch (tolower(pos[0])) {
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
case '.':
|
||||
case '.': // FALLTHRU
|
||||
case '-':
|
||||
// Digits, like %5d, etc.
|
||||
vfmt += pos[0];
|
||||
inPct = true; // Get more digits
|
||||
|
|
@ -2812,7 +2813,7 @@ void EmitCImp::emitImp(AstNodeModule* modp) {
|
|||
void EmitCImp::maybeSplit(AstNodeModule* modp) {
|
||||
if (splitNeeded()) {
|
||||
// Close old file
|
||||
delete m_ofp; m_ofp = NULL;
|
||||
VL_DO_CLEAR(delete m_ofp, m_ofp = NULL);
|
||||
// Open a new file
|
||||
m_ofp = newOutCFile(modp, !m_fast, true/*source*/, splitFilenumInc());
|
||||
emitImp(modp);
|
||||
|
|
@ -2833,7 +2834,7 @@ void EmitCImp::main(AstNodeModule* modp, bool slow, bool fast) {
|
|||
if (m_fast) {
|
||||
m_ofp = newOutCFile(modp, !m_fast, false/*source*/);
|
||||
emitInt(modp);
|
||||
delete m_ofp; m_ofp = NULL;
|
||||
VL_DO_CLEAR(delete m_ofp, m_ofp = NULL);
|
||||
}
|
||||
|
||||
m_ofp = newOutCFile(modp, !m_fast, true/*source*/);
|
||||
|
|
@ -2864,7 +2865,7 @@ void EmitCImp::main(AstNodeModule* modp, bool slow, bool fast) {
|
|||
}
|
||||
}
|
||||
}
|
||||
delete m_ofp; m_ofp = NULL;
|
||||
VL_DO_CLEAR(delete m_ofp, m_ofp = NULL);
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -3191,7 +3192,7 @@ class EmitCTrace : EmitCStmts {
|
|||
|
||||
if (splitNeeded()) {
|
||||
// Close old file
|
||||
delete m_ofp; m_ofp = NULL;
|
||||
VL_DO_CLEAR(delete m_ofp, m_ofp = NULL);
|
||||
// Open a new file
|
||||
newOutCFile(splitFilenumInc());
|
||||
}
|
||||
|
|
@ -3272,7 +3273,7 @@ public:
|
|||
|
||||
iterate(v3Global.rootp());
|
||||
|
||||
delete m_ofp; m_ofp = NULL;
|
||||
VL_DO_CLEAR(delete m_ofp, m_ofp = NULL);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -480,8 +480,7 @@ void EmitCSyms::closeSplit() {
|
|||
if (!m_ofp || m_ofp == m_ofpBase) return;
|
||||
|
||||
puts("}\n");
|
||||
delete m_ofp;
|
||||
m_ofp = NULL;
|
||||
VL_DO_CLEAR(delete m_ofp, m_ofp = NULL);
|
||||
}
|
||||
|
||||
void EmitCSyms::checkSplit(bool usesVfinal) {
|
||||
|
|
|
|||
|
|
@ -140,6 +140,8 @@ class EmitXmlFileVisitor : public AstNVisitor {
|
|||
if (nodep->isSigPublic()) puts(" public=\"true\"");
|
||||
if (nodep->isSigUserRdPublic()) puts(" public_flat_rd=\"true\"");
|
||||
if (nodep->isSigUserRWPublic()) puts(" public_flat_rw=\"true\"");
|
||||
if (nodep->isGParam()) puts(" param=\"true\"");
|
||||
else if (nodep->isParam()) puts(" localparam=\"true\"");
|
||||
if (nodep->attrScBv()) puts(" sc_bv=\"true\"");
|
||||
if (nodep->attrScClocked()) puts(" sc_clock=\"true\"");
|
||||
if (nodep->attrSFormat()) puts(" sformat=\"true\"");
|
||||
|
|
|
|||
|
|
@ -594,7 +594,7 @@ protected:
|
|||
// Just dispatch to the implementation
|
||||
|
||||
VInFilter::VInFilter(const string& command) { m_impp = new VInFilterImp(command); }
|
||||
VInFilter::~VInFilter() { if (m_impp) delete m_impp; m_impp = NULL; }
|
||||
VInFilter::~VInFilter() { if (m_impp) VL_DO_CLEAR(delete m_impp, m_impp = NULL); }
|
||||
|
||||
bool VInFilter::readWholefile(const string& filename, VInFilter::StrList& outl) {
|
||||
if (!m_impp) v3fatalSrc("readWholefile on invalid filter");
|
||||
|
|
|
|||
|
|
@ -150,9 +150,7 @@ public:
|
|||
V3GraphEdge* deletep = NULL;
|
||||
for (V3GraphEdge* edgep = vxp->outBeginp();
|
||||
edgep; edgep = edgep->outNextp()) {
|
||||
if (deletep) {
|
||||
deletep->unlinkDelete(); deletep = NULL;
|
||||
}
|
||||
if (deletep) VL_DO_CLEAR(deletep->unlinkDelete(), deletep = NULL);
|
||||
// It should be safe to modify the graph, despite using
|
||||
// the GraphPathChecker, as none of the modifications will
|
||||
// change what can be reached from what, nor should they
|
||||
|
|
|
|||
|
|
@ -595,7 +595,7 @@ public:
|
|||
add_complement_edges();
|
||||
if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_preswap");
|
||||
|
||||
m_tempNewerReject->unlinkDelete(graphp()); m_tempNewerReject = NULL;
|
||||
VL_DO_CLEAR(m_tempNewerReject->unlinkDelete(graphp()), m_tempNewerReject = NULL);
|
||||
if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_out");
|
||||
}
|
||||
~DfaGraphComplement() {}
|
||||
|
|
|
|||
|
|
@ -453,11 +453,11 @@ public:
|
|||
{
|
||||
m_lifep = new LifeBlock(NULL, m_statep);
|
||||
iterate(nodep);
|
||||
if (m_lifep) { delete m_lifep; m_lifep = NULL; }
|
||||
if (m_lifep) VL_DO_CLEAR(delete m_lifep, m_lifep = NULL);
|
||||
}
|
||||
}
|
||||
virtual ~LifeVisitor() {
|
||||
if (m_lifep) { delete m_lifep; m_lifep = NULL; }
|
||||
if (m_lifep) VL_DO_CLEAR(delete m_lifep, m_lifep = NULL);
|
||||
}
|
||||
VL_UNCOPYABLE(LifeVisitor);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -49,12 +49,12 @@ private:
|
|||
// NODE STATE
|
||||
// Entire netlist:
|
||||
// AstCaseItem::user2() // bool Moved default caseitems
|
||||
AstUser2InUse m_inuser2;
|
||||
AstUser2InUse m_inuser2;
|
||||
|
||||
// STATE
|
||||
// Below state needs to be preserved between each module call.
|
||||
AstNodeModule* m_modp; // Current module
|
||||
AstNodeFTask* m_ftaskp; // Function or task we're inside
|
||||
AstNodeModule* m_modp; // Current module
|
||||
AstNodeFTask* m_ftaskp; // Function or task we're inside
|
||||
AstNodeCoverOrAssert* m_assertp; // Current assertion
|
||||
int m_senitemCvtNum; // Temporary signal counter
|
||||
|
||||
|
|
@ -270,7 +270,7 @@ private:
|
|||
if (!inPct && ch=='%') {
|
||||
inPct = true;
|
||||
fmt = ch;
|
||||
} else if (inPct && (isdigit(ch) || ch=='.')) {
|
||||
} else if (inPct && (isdigit(ch) || ch=='.' || ch=='-')) {
|
||||
fmt += ch;
|
||||
} else if (inPct) {
|
||||
inPct = false;
|
||||
|
|
|
|||
|
|
@ -497,10 +497,10 @@ bool V3Number::displayedFmtLegal(char format) {
|
|||
}
|
||||
}
|
||||
|
||||
string V3Number::displayPad(size_t fmtsize, char pad, const string& in) {
|
||||
string prefix;
|
||||
if (in.length() < fmtsize) prefix = string(fmtsize - in.length(), pad);
|
||||
return prefix + in;
|
||||
string V3Number::displayPad(size_t fmtsize, char pad, bool left, const string& in) {
|
||||
string padding;
|
||||
if (in.length() < fmtsize) padding = string(fmtsize - in.length(), pad);
|
||||
return left ? (in + padding) : (padding + in);
|
||||
}
|
||||
|
||||
string V3Number::displayed(AstNode* nodep, const string& vformat) const {
|
||||
|
|
@ -512,6 +512,11 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
|
|||
UASSERT(pos != vformat.end() && pos[0]=='%',
|
||||
"$display-like function with non format argument "<<*this);
|
||||
++pos;
|
||||
bool left = false;
|
||||
if (pos[0] == '-') {
|
||||
left = true;
|
||||
++pos;
|
||||
}
|
||||
string fmtsize;
|
||||
for (; pos != vformat.end() && (isdigit(pos[0]) || pos[0]=='.'); ++pos) {
|
||||
fmtsize += pos[0];
|
||||
|
|
@ -574,7 +579,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
|
|||
}
|
||||
}
|
||||
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
|
||||
str = displayPad(fmtsizen, ' ', str);
|
||||
str = displayPad(fmtsizen, ' ', left, str);
|
||||
return str;
|
||||
}
|
||||
case '~': // Signed decimal
|
||||
|
|
@ -604,7 +609,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
|
|||
bool zeropad = fmtsize.length()>0 && fmtsize[0]=='0';
|
||||
// fmtsize might have changed since we parsed the %fmtsize
|
||||
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
|
||||
str = displayPad(fmtsizen, (zeropad ? '0' : ' '), str);
|
||||
str = displayPad(fmtsizen, (zeropad ? '0' : ' '), left, str);
|
||||
return str;
|
||||
}
|
||||
case 'e':
|
||||
|
|
@ -651,7 +656,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
|
|||
}
|
||||
case '@': { // Packed string
|
||||
size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
|
||||
str = displayPad(fmtsizen, ' ', toString());
|
||||
str = displayPad(fmtsizen, ' ', left, toString());
|
||||
return str;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ private:
|
|||
for (int i=0; i<words(); i++) m_value[i] = m_valueX[i] = 0;
|
||||
}
|
||||
void setNames(AstNode* nodep);
|
||||
static string displayPad(size_t fmtsize, char pad, const string& in);
|
||||
static string displayPad(size_t fmtsize, char pad, bool left, const string& in);
|
||||
string displayed(FileLine* fl, const string& vformat) const;
|
||||
string displayed(const string& vformat) const {
|
||||
return displayed(m_fileline, vformat);
|
||||
|
|
|
|||
|
|
@ -1553,7 +1553,7 @@ V3Options::V3Options() {
|
|||
}
|
||||
|
||||
V3Options::~V3Options() {
|
||||
delete m_impp; m_impp = NULL;
|
||||
VL_DO_CLEAR(delete m_impp, m_impp = NULL);
|
||||
}
|
||||
|
||||
void V3Options::setDebugMode(int level) {
|
||||
|
|
|
|||
|
|
@ -57,11 +57,11 @@ extern void yyerrorf(const char* format, ...);
|
|||
|
||||
V3ParseImp::~V3ParseImp() {
|
||||
for (std::deque<string*>::iterator it = m_stringps.begin(); it != m_stringps.end(); ++it) {
|
||||
delete (*it);
|
||||
VL_DO_DANGLING(delete *it, *it);
|
||||
}
|
||||
m_stringps.clear();
|
||||
for (std::deque<V3Number*>::iterator it = m_numberps.begin(); it != m_numberps.end(); ++it) {
|
||||
delete (*it);
|
||||
VL_DO_DANGLING(delete *it, *it);
|
||||
}
|
||||
m_numberps.clear();
|
||||
lexDestroy();
|
||||
|
|
@ -297,7 +297,7 @@ V3Parse::V3Parse(AstNetlist* rootp, VInFilter* filterp, V3ParseSym* symp) {
|
|||
m_impp = new V3ParseImp(rootp, filterp, symp);
|
||||
}
|
||||
V3Parse::~V3Parse() {
|
||||
delete m_impp; m_impp = NULL;
|
||||
VL_DO_CLEAR(delete m_impp, m_impp = NULL);
|
||||
}
|
||||
void V3Parse::parseFile(FileLine* fileline, const string& modname, bool inLibrary,
|
||||
const string& errmsg) {
|
||||
|
|
|
|||
|
|
@ -82,5 +82,5 @@ void V3ParseImp::lexNew() {
|
|||
}
|
||||
|
||||
void V3ParseImp::lexDestroy() {
|
||||
if (m_lexerp) { delete m_lexerp; m_lexerp = NULL; }
|
||||
if (m_lexerp) VL_DO_CLEAR(delete m_lexerp, m_lexerp = NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1411,7 +1411,7 @@ private:
|
|||
// Remove and free the connecting edge. Must do this before
|
||||
// propagating CP's below.
|
||||
m_sb.removeElem(mergeCanp);
|
||||
mergeEdgep->unlinkDelete(); mergeEdgep=NULL;
|
||||
VL_DO_CLEAR(mergeEdgep->unlinkDelete(), mergeEdgep=NULL);
|
||||
}
|
||||
|
||||
// This also updates cost and stepCost on recipientp
|
||||
|
|
@ -1467,7 +1467,7 @@ private:
|
|||
partMergeEdgesFrom(m_mtasksp, recipientp, donorp, &m_sb);
|
||||
|
||||
// Delete the donorp mtask from the graph
|
||||
donorp->unlinkDelete(m_mtasksp); donorp = NULL;
|
||||
VL_DO_CLEAR(donorp->unlinkDelete(m_mtasksp), donorp = NULL);
|
||||
|
||||
m_mergesSinceRescore++;
|
||||
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ class V3PreLex {
|
|||
}
|
||||
~V3PreLex() {
|
||||
while (!m_streampStack.empty()) { delete m_streampStack.top(); m_streampStack.pop(); }
|
||||
yy_delete_buffer(m_bufferState); m_bufferState = NULL;
|
||||
VL_DO_CLEAR(yy_delete_buffer(m_bufferState), m_bufferState = NULL);
|
||||
}
|
||||
|
||||
// Called by V3PreLex.l from lexer
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ public:
|
|||
m_lexp->debug(debug()>=5 ? debug() : 0); // See also V3PreProc::debug() method
|
||||
}
|
||||
~V3PreProcImp() {
|
||||
if (m_lexp) { delete m_lexp; m_lexp = NULL; }
|
||||
if (m_lexp) VL_DO_CLEAR(delete m_lexp, m_lexp = NULL);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -164,12 +164,12 @@ public:
|
|||
void deleteUnusedAssign() {
|
||||
// If there are unused assignments in this var, kill them
|
||||
if (!m_whole.m_use && !m_wordUse && m_whole.m_assignp) {
|
||||
deleteAssign(m_whole.m_assignp); m_whole.m_assignp = NULL;
|
||||
VL_DO_CLEAR(deleteAssign(m_whole.m_assignp), m_whole.m_assignp = NULL);
|
||||
}
|
||||
for (unsigned i=0; i<m_words.size(); i++) {
|
||||
if (!m_whole.m_use && !m_words[i].m_use
|
||||
&& m_words[i].m_assignp && !m_words[i].m_complex) {
|
||||
deleteAssign(m_words[i].m_assignp); m_words[i].m_assignp = NULL;
|
||||
VL_DO_CLEAR(deleteAssign(m_words[i].m_assignp), m_words[i].m_assignp = NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,15 +129,14 @@ public:
|
|||
return iter->second;
|
||||
}
|
||||
bool ftaskNoInline(AstNodeFTask* nodep) {
|
||||
return (getFTaskVertex(nodep)->noInline());
|
||||
return getFTaskVertex(nodep)->noInline();
|
||||
}
|
||||
AstCFunc* ftaskCFuncp(AstNodeFTask* nodep) {
|
||||
return (getFTaskVertex(nodep)->cFuncp());
|
||||
return getFTaskVertex(nodep)->cFuncp();
|
||||
}
|
||||
void ftaskCFuncp(AstNodeFTask* nodep, AstCFunc* cfuncp) {
|
||||
getFTaskVertex(nodep)->cFuncp(cfuncp);
|
||||
}
|
||||
|
||||
void checkPurity(AstNodeFTask* nodep) {
|
||||
checkPurity(nodep, getFTaskVertex(nodep));
|
||||
}
|
||||
|
|
@ -196,7 +195,7 @@ private:
|
|||
// of multiple statements. Perhaps someday make all wassigns into always's?
|
||||
UINFO(5," IM_WireRep "<<m_assignwp<<endl);
|
||||
m_assignwp->convertToAlways();
|
||||
pushDeletep(m_assignwp); m_assignwp = NULL;
|
||||
VL_DO_CLEAR(pushDeletep(m_assignwp), m_assignwp = NULL);
|
||||
}
|
||||
// We make multiple edges if a task is called multiple times from another task.
|
||||
UASSERT_OBJ(nodep->taskp(), nodep, "Unlinked task");
|
||||
|
|
@ -471,7 +470,8 @@ private:
|
|||
{
|
||||
AstBegin* tempp = new AstBegin(beginp->fileline(), "[EditWrapper]", beginp);
|
||||
TaskRelinkVisitor visit (tempp);
|
||||
tempp->stmtsp()->unlinkFrBackWithNext(); VL_DO_DANGLING(tempp->deleteTree(), tempp);
|
||||
tempp->stmtsp()->unlinkFrBackWithNext();
|
||||
VL_DO_DANGLING(tempp->deleteTree(), tempp);
|
||||
}
|
||||
//
|
||||
if (debug()>=9) { beginp->dumpTreeAndNext(cout, "-iotask: "); }
|
||||
|
|
@ -489,8 +489,8 @@ private:
|
|||
string("Function: ")+refp->name(), true);
|
||||
AstCCall* ccallp = new AstCCall(refp->fileline(), cfuncp, NULL);
|
||||
beginp->addNext(ccallp);
|
||||
// Convert complicated outputs to temp signals
|
||||
|
||||
// Convert complicated outputs to temp signals
|
||||
V3TaskConnects tconnects = V3Task::taskConnects(refp, refp->taskp()->stmtsp());
|
||||
for (V3TaskConnects::iterator it=tconnects.begin(); it!=tconnects.end(); ++it) {
|
||||
AstVar* portp = it->first;
|
||||
|
|
@ -521,7 +521,7 @@ private:
|
|||
// Correct lvalue; we didn't know when we linked
|
||||
// This is slightly scary; are we sure no decisions were made
|
||||
// before here based on this not being a lvalue?
|
||||
// Doesn't seem so; V3Unknown uses it earlier, but works ok.
|
||||
// Seems correct assumption; V3Unknown uses it earlier, but works ok.
|
||||
V3LinkLValue::linkLValueSet(pinp);
|
||||
|
||||
// Even if it's referencing a varref, we still make a temporary
|
||||
|
|
@ -1074,7 +1074,8 @@ private:
|
|||
{
|
||||
AstBegin* tempp = new AstBegin(cfuncp->fileline(), "[EditWrapper]", cfuncp);
|
||||
TaskRelinkVisitor visit (tempp);
|
||||
tempp->stmtsp()->unlinkFrBackWithNext(); VL_DO_DANGLING(tempp->deleteTree(), tempp);
|
||||
tempp->stmtsp()->unlinkFrBackWithNext();
|
||||
VL_DO_DANGLING(tempp->deleteTree(), tempp);
|
||||
}
|
||||
// Delete rest of cloned task and return new func
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
|
|
@ -1411,7 +1412,8 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
|
|||
UINFO(9,"Default pin for "<<portp<<endl);
|
||||
AstArg* newp = new AstArg(nodep->fileline(), portp->name(), newvaluep);
|
||||
if (tconnects[i].second) { // Have a "NULL" pin already defined for it
|
||||
tconnects[i].second->unlinkFrBack()->deleteTree(); tconnects[i].second = NULL;
|
||||
VL_DO_CLEAR(tconnects[i].second->unlinkFrBack()->deleteTree(),
|
||||
tconnects[i].second = NULL);
|
||||
}
|
||||
tconnects[i].second = newp;
|
||||
reorganize = true;
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ private:
|
|||
iterate(varp->dtypeSkipRefp());
|
||||
}
|
||||
// Cleanup
|
||||
if (m_traValuep) { m_traValuep->deleteTree(); m_traValuep = NULL; }
|
||||
if (m_traValuep) VL_DO_CLEAR(m_traValuep->deleteTree(), m_traValuep = NULL);
|
||||
}
|
||||
m_traVscp = NULL;
|
||||
m_traValuep = NULL;
|
||||
|
|
@ -272,7 +272,7 @@ private:
|
|||
i - nodep->lsb());
|
||||
|
||||
iterate(subtypep);
|
||||
m_traValuep->deleteTree(); m_traValuep = NULL;
|
||||
VL_DO_CLEAR(m_traValuep->deleteTree(), m_traValuep = NULL);
|
||||
}
|
||||
m_traShowname = oldShowname;
|
||||
m_traValuep = oldValuep;
|
||||
|
|
@ -298,7 +298,7 @@ private:
|
|||
(i - nodep->lsb())*subtypep->width(),
|
||||
subtypep->width());
|
||||
iterate(subtypep);
|
||||
m_traValuep->deleteTree(); m_traValuep = NULL;
|
||||
VL_DO_CLEAR(m_traValuep->deleteTree(), m_traValuep = NULL);
|
||||
}
|
||||
m_traShowname = oldShowname;
|
||||
m_traValuep = oldValuep;
|
||||
|
|
@ -329,7 +329,7 @@ private:
|
|||
m_traValuep->cloneTree(true),
|
||||
itemp->lsb(), subtypep->width());
|
||||
iterate(subtypep);
|
||||
m_traValuep->deleteTree(); m_traValuep = NULL;
|
||||
VL_DO_CLEAR(m_traValuep->deleteTree(), m_traValuep = NULL);
|
||||
} else { // Else union, replicate fields
|
||||
iterate(subtypep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1155,7 +1155,9 @@ class TristateVisitor : public TristateBaseVisitor {
|
|||
AstVar* outModVarp = static_cast<AstVar*>(nodep->modVarp()->user4p());
|
||||
if (!outModVarp) {
|
||||
// At top, no need for __out as might be input only. Otherwise resolvable.
|
||||
UASSERT_OBJ(m_modp->isTop(), nodep, "Unlinked");
|
||||
if (!m_modp->isTop()) {
|
||||
nodep->v3error("Unsupported: tristate in top-level IO: " << nodep->prettyNameQ());
|
||||
}
|
||||
} else {
|
||||
AstNode* outexprp = nodep->exprp()->cloneTree(false); // Note has lvalue() set
|
||||
outpinp = new AstPin(nodep->fileline(),
|
||||
|
|
|
|||
|
|
@ -86,7 +86,8 @@ private:
|
|||
// Wire assigns must become always statements to deal with insertion
|
||||
// of multiple statements. Perhaps someday make all wassigns into always's?
|
||||
UINFO(5," IM_WireRep "<<m_assignwp<<endl);
|
||||
m_assignwp->convertToAlways(); pushDeletep(m_assignwp); m_assignwp = NULL;
|
||||
m_assignwp->convertToAlways();
|
||||
VL_DO_CLEAR(pushDeletep(m_assignwp), m_assignwp = NULL);
|
||||
}
|
||||
bool needDly = (m_assigndlyp != NULL);
|
||||
if (m_assigndlyp) {
|
||||
|
|
@ -95,7 +96,8 @@ private:
|
|||
AstNode* newp = new AstAssign(m_assigndlyp->fileline(),
|
||||
m_assigndlyp->lhsp()->unlinkFrBackWithNext(),
|
||||
m_assigndlyp->rhsp()->unlinkFrBackWithNext());
|
||||
m_assigndlyp->replaceWith(newp); pushDeletep(m_assigndlyp); m_assigndlyp = NULL;
|
||||
m_assigndlyp->replaceWith(newp);
|
||||
VL_DO_CLEAR(pushDeletep(m_assigndlyp), m_assigndlyp = NULL);
|
||||
}
|
||||
AstNode* prep = nodep;
|
||||
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ private:
|
|||
SimulateVisitor simvis;
|
||||
AstNode* clonep = nodep->cloneTree(true);
|
||||
simvis.mainCheckTree(clonep);
|
||||
pushDeletep(clonep); clonep = NULL;
|
||||
VL_DO_CLEAR(pushDeletep(clonep), clonep = NULL);
|
||||
return simvis.optimizable();
|
||||
}
|
||||
|
||||
|
|
@ -202,7 +202,7 @@ private:
|
|||
clonep = tempp->stmtsp()->unlinkFrBackWithNext();
|
||||
tempp->deleteTree();
|
||||
tempp = NULL;
|
||||
pushDeletep(m_varValuep); m_varValuep = NULL;
|
||||
VL_DO_CLEAR(pushDeletep(m_varValuep), m_varValuep = NULL);
|
||||
}
|
||||
SimulateVisitor simvis;
|
||||
simvis.mainParamEmulate(clonep);
|
||||
|
|
@ -329,7 +329,7 @@ private:
|
|||
string nname = m_beginName + "__BRA__" + index + "__KET__";
|
||||
oneloopp = new AstBegin(oneloopp->fileline(), nname, oneloopp, true);
|
||||
}
|
||||
pushDeletep(m_varValuep); m_varValuep = NULL;
|
||||
VL_DO_CLEAR(pushDeletep(m_varValuep), m_varValuep = NULL);
|
||||
if (newbodysp) newbodysp->addNext(oneloopp);
|
||||
else newbodysp = oneloopp;
|
||||
|
||||
|
|
|
|||
|
|
@ -1081,7 +1081,7 @@ private:
|
|||
if (VN_IS(nodep->fromp()->dtypep(), QueueDType)) {
|
||||
switch (nodep->attrType()) {
|
||||
case AstAttrType::DIM_SIZE: {
|
||||
AstNode* newp = new AstCMethodCall(
|
||||
AstNode* newp = new AstCMethodHard(
|
||||
nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size", NULL);
|
||||
newp->dtypeSetSigned32();
|
||||
newp->didWidth(true);
|
||||
|
|
@ -1097,7 +1097,7 @@ private:
|
|||
}
|
||||
case AstAttrType::DIM_RIGHT:
|
||||
case AstAttrType::DIM_HIGH: {
|
||||
AstNode* sizep = new AstCMethodCall(
|
||||
AstNode* sizep = new AstCMethodHard(
|
||||
nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size", NULL);
|
||||
sizep->dtypeSetSigned32();
|
||||
sizep->didWidth(true);
|
||||
|
|
@ -1788,7 +1788,7 @@ private:
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual void visit(AstCMethodCall* nodep) {
|
||||
virtual void visit(AstCMethodHard* nodep) {
|
||||
// Never created before V3Width, so no need to redo it
|
||||
UASSERT_OBJ(nodep->dtypep(), nodep, "CMETHODCALLs should have already been sized");
|
||||
}
|
||||
|
|
@ -1936,11 +1936,11 @@ private:
|
|||
}
|
||||
}
|
||||
void methodCallAssoc(AstMethodCall* nodep, AstAssocArrayDType* adtypep) {
|
||||
AstCMethodCall* newp = NULL;
|
||||
AstCMethodHard* newp = NULL;
|
||||
if (nodep->name() == "num" // function int num()
|
||||
|| nodep->name() == "size") {
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
newp = new AstCMethodHard(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
"size", NULL); // So don't need num()
|
||||
newp->dtypeSetSigned32();
|
||||
|
|
@ -1952,7 +1952,7 @@ private:
|
|||
|| nodep->name() == "prev") {
|
||||
methodOkArguments(nodep, 1, 1);
|
||||
AstNode* index_exprp = methodCallAssocIndexExpr(nodep, adtypep);
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
newp = new AstCMethodHard(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), // first/last/next/prev
|
||||
index_exprp->unlinkFrBack());
|
||||
|
|
@ -1963,7 +1963,7 @@ private:
|
|||
// IEEE really should have made this a "bit" return
|
||||
methodOkArguments(nodep, 1, 1);
|
||||
AstNode* index_exprp = methodCallAssocIndexExpr(nodep, adtypep);
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
newp = new AstCMethodHard(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
"exists", index_exprp->unlinkFrBack());
|
||||
newp->dtypeSetSigned32();
|
||||
|
|
@ -1974,14 +1974,14 @@ private:
|
|||
methodOkArguments(nodep, 0, 1);
|
||||
methodCallLValue(nodep, nodep->fromp(), true);
|
||||
if (!nodep->pinsp()) {
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
newp = new AstCMethodHard(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
"clear", NULL);
|
||||
newp->protect(false);
|
||||
newp->makeStatement();
|
||||
} else {
|
||||
AstNode* index_exprp = methodCallAssocIndexExpr(nodep, adtypep);
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
newp = new AstCMethodHard(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
"erase",
|
||||
index_exprp->unlinkFrBack());
|
||||
|
|
@ -2013,11 +2013,11 @@ private:
|
|||
}
|
||||
}
|
||||
void methodCallQueue(AstMethodCall* nodep, AstQueueDType* adtypep) {
|
||||
AstCMethodCall* newp = NULL;
|
||||
AstCMethodHard* newp = NULL;
|
||||
if (nodep->name() == "at") { // Created internally for []
|
||||
methodOkArguments(nodep, 1, 1);
|
||||
methodCallLValue(nodep, nodep->fromp(), true);
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
newp = new AstCMethodHard(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
"at", NULL);
|
||||
newp->dtypeFrom(adtypep->subDTypep());
|
||||
|
|
@ -2026,7 +2026,7 @@ private:
|
|||
} else if (nodep->name() == "num" // function int num()
|
||||
|| nodep->name() == "size") {
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
newp = new AstCMethodHard(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
"size", NULL);
|
||||
newp->dtypeSetSigned32();
|
||||
|
|
@ -2036,7 +2036,7 @@ private:
|
|||
methodOkArguments(nodep, 0, 1);
|
||||
methodCallLValue(nodep, nodep->fromp(), true);
|
||||
if (!nodep->pinsp()) {
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
newp = new AstCMethodHard(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
"clear", NULL);
|
||||
newp->protect(false);
|
||||
|
|
@ -2044,7 +2044,7 @@ private:
|
|||
} else {
|
||||
AstNode* index_exprp = methodCallQueueIndexExpr(nodep);
|
||||
if (index_exprp->isZero()) { // delete(0) is a pop_front
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
newp = new AstCMethodHard(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
"pop_front", NULL);
|
||||
newp->dtypeFrom(adtypep->subDTypep());
|
||||
|
|
@ -2053,7 +2053,7 @@ private:
|
|||
newp->makeStatement();
|
||||
} else {
|
||||
nodep->v3error("Unsupported: Queue .delete(index) method, as is O(n) complexity and slow.");
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
newp = new AstCMethodHard(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
"erase", index_exprp->unlinkFrBack());
|
||||
newp->protect(false);
|
||||
|
|
@ -2067,14 +2067,14 @@ private:
|
|||
AstArg* argp = VN_CAST(nodep->pinsp()->nextp(), Arg);
|
||||
iterateCheckTyped(nodep, "insert value", argp->exprp(), adtypep->subDTypep(), BOTH);
|
||||
if (index_exprp->isZero()) { // insert(0, ...) is a push_front
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
newp = new AstCMethodHard(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
"push_front", argp->exprp()->unlinkFrBack());
|
||||
newp->protect(false);
|
||||
newp->makeStatement();
|
||||
} else {
|
||||
nodep->v3error("Unsupported: Queue .insert method, as is O(n) complexity and slow.");
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
newp = new AstCMethodHard(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(),
|
||||
index_exprp->unlinkFrBack());
|
||||
|
|
@ -2086,7 +2086,7 @@ private:
|
|||
|| nodep->name() == "pop_back") {
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValue(nodep, nodep->fromp(), true);
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
newp = new AstCMethodHard(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), NULL);
|
||||
newp->dtypeFrom(adtypep->subDTypep());
|
||||
|
|
@ -2101,7 +2101,7 @@ private:
|
|||
methodCallLValue(nodep, nodep->fromp(), true);
|
||||
AstArg* argp = VN_CAST(nodep->pinsp(), Arg);
|
||||
iterateCheckTyped(nodep, "push value", argp->exprp(), adtypep->subDTypep(), BOTH);
|
||||
newp = new AstCMethodCall(nodep->fileline(),
|
||||
newp = new AstCMethodHard(nodep->fileline(),
|
||||
nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), argp->exprp()->unlinkFrBack());
|
||||
newp->protect(false);
|
||||
|
|
@ -2706,7 +2706,7 @@ private:
|
|||
if (!inPct && ch=='%') {
|
||||
inPct = true;
|
||||
fmt = ch;
|
||||
} else if (inPct && (isdigit(ch) || ch=='.')) {
|
||||
} else if (inPct && (isdigit(ch) || ch=='.' || ch=='-')) {
|
||||
fmt += ch;
|
||||
} else if (tolower(inPct)) {
|
||||
inPct = false;
|
||||
|
|
@ -2737,7 +2737,7 @@ private:
|
|||
newFormat += "%@";
|
||||
AstNRelinker handle;
|
||||
argp->unlinkFrBack(&handle);
|
||||
AstCMethodCall* newp = new AstCMethodCall(
|
||||
AstCMethodHard* newp = new AstCMethodHard(
|
||||
nodep->fileline(), argp, "to_string", NULL);
|
||||
newp->dtypeSetString();
|
||||
newp->pure(true);
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ private:
|
|||
else if (AstQueueDType* adtypep = VN_CAST(ddtypep, QueueDType)) {
|
||||
// SELBIT(array, index) -> CMETHODCALL(queue, "at", index)
|
||||
AstNode* subp = rhsp;
|
||||
AstCMethodCall* newp = new AstCMethodCall(nodep->fileline(),
|
||||
AstCMethodHard* newp = new AstCMethodHard(nodep->fileline(),
|
||||
fromp, "at", subp);
|
||||
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off queue reference
|
||||
if (debug()>=9) newp->dumpTree(cout, "--SELBTq: ");
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ AstNetlist* V3Global::makeNetlist() {
|
|||
void V3Global::checkTree() { rootp()->checkTree(); }
|
||||
|
||||
void V3Global::clear() {
|
||||
if (m_rootp) { m_rootp->deleteTree(); m_rootp = NULL; }
|
||||
if (m_rootp) VL_DO_CLEAR(m_rootp->deleteTree(), m_rootp = NULL);
|
||||
}
|
||||
|
||||
void V3Global::readFiles() {
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ public:
|
|||
VlcTests() {}
|
||||
~VlcTests() {
|
||||
for (VlcTests::ByName::iterator it=begin(); it!=end(); ++it) {
|
||||
delete *it; *it=NULL;
|
||||
VL_DO_CLEAR(delete *it, *it=NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ public:
|
|||
}
|
||||
void setVarDecl(AstVarType type) { m_varDecl = type; }
|
||||
void setDType(AstNodeDType* dtypep) {
|
||||
if (m_varDTypep) { m_varDTypep->deleteTree(); m_varDTypep=NULL; } // It was cloned, so this is safe.
|
||||
if (m_varDTypep) VL_DO_CLEAR(m_varDTypep->deleteTree(), m_varDTypep=NULL); // It was cloned, so this is safe.
|
||||
m_varDTypep = dtypep;
|
||||
}
|
||||
AstPackage* unitPackage(FileLine* fl) {
|
||||
|
|
@ -2364,7 +2364,10 @@ etcInst<nodep>: // IEEE: module_instantiation + gate_instantiation + udp_insta
|
|||
instDecl<nodep>:
|
||||
id parameter_value_assignmentE {INSTPREP($<fl>1,*$1,$2);} instnameList ';'
|
||||
{ $$ = $4; GRAMMARP->m_impliedDecl=false;
|
||||
if (GRAMMARP->m_instParamp) { GRAMMARP->m_instParamp->deleteTree(); GRAMMARP->m_instParamp = NULL; } }
|
||||
if (GRAMMARP->m_instParamp) {
|
||||
VL_DO_CLEAR(GRAMMARP->m_instParamp->deleteTree(),
|
||||
GRAMMARP->m_instParamp = NULL);
|
||||
} }
|
||||
// // IEEE: interface_identifier' .' modport_identifier list_of_interface_identifiers
|
||||
| id/*interface*/ '.' id/*modport*/
|
||||
{ VARRESET_NONLIST(AstVarType::IFACEREF);
|
||||
|
|
@ -5356,13 +5359,17 @@ classExtendsE<nodep>: // IEEE: part of class_declaration
|
|||
|
||||
classExtendsList<nodep>: // IEEE: part of class_declaration
|
||||
classExtendsOne { $$ = $1; }
|
||||
| classExtendsList ',' classExtendsOne { $$ = AstNode::addNextNull($1, $3); }
|
||||
| classExtendsList ',' classExtendsOne
|
||||
{ $$ = $3; BBUNSUP($3, "Multiple inheritance illegal on non-interface classes (IEEE 8.13)"
|
||||
", and unsupported for interface classes."); }
|
||||
;
|
||||
|
||||
classExtendsOne<nodep>: // IEEE: part of class_declaration
|
||||
class_typeWithoutId { $$ = NULL; BBUNSUP($1, "Unsupported: extends"); }
|
||||
class_typeWithoutId
|
||||
{ $$ = NULL; BBUNSUP($1, "Unsupported: extends"); }
|
||||
// // IEEE: Might not be legal to have more than one set of parameters in an extends
|
||||
| class_typeWithoutId '(' list_of_argumentsE ')' { $$ = NULL; BBUNSUP($1, "Unsupported: extends"); }
|
||||
| class_typeWithoutId '(' list_of_argumentsE ')'
|
||||
{ $$ = NULL; BBUNSUP($1, "Unsupported: extends"); }
|
||||
;
|
||||
|
||||
classImplementsE<nodep>: // IEEE: part of class_declaration
|
||||
|
|
|
|||
|
|
@ -51,5 +51,19 @@ extra argument: 0000000000000000
|
|||
[0] Embedded <#013> return
|
||||
[0] Embedded
|
||||
multiline
|
||||
'23 23 23'
|
||||
'23 23 23 '
|
||||
'23 23 23'
|
||||
'23 23 23 '
|
||||
' 24'
|
||||
'24 '
|
||||
' 0'
|
||||
'0 '
|
||||
' sv-str'
|
||||
'sv-str '
|
||||
' meep'
|
||||
'meep '
|
||||
' beep'
|
||||
'beep '
|
||||
log10(2) = 2
|
||||
*-* All Finished *-*
|
||||
|
|
|
|||
|
|
@ -13,7 +13,10 @@ module t;
|
|||
reg [31:0] str; initial str = "\000\277\021\n";
|
||||
reg [47:0] str2; initial str2 = "\000what!";
|
||||
reg [79:0] str3; initial str3 = "\000hmmm!1234";
|
||||
int n; initial n = 23;
|
||||
reg [7:0] m; initial m = 24;
|
||||
string svs = "sv-str";
|
||||
reg [31:0] regstr = "meep";
|
||||
|
||||
sub sub ();
|
||||
sub2 sub2 ();
|
||||
|
|
@ -144,6 +147,22 @@ multiline", $time);
|
|||
if (str !== 32'h00_bf_11_0a) $stop;
|
||||
`endif
|
||||
|
||||
// Padding
|
||||
$write("'%0d %2d %8d'\n", 23, 23, 23);
|
||||
$write("'%-0d %-2d %-8d'\n", 23, 23, 23);
|
||||
$write("'%0d %2d %8d'\n", n, n, n);
|
||||
$write("'%-0d %-2d %-8d'\n", n, n, n);
|
||||
$write("'%8d'\n", m);
|
||||
$write("'%-8d'\n", m);
|
||||
$write("'%8t'\n", $time);
|
||||
$write("'%-8t'\n", $time);
|
||||
$write("'%8s'\n", svs);
|
||||
$write("'%-8s'\n", svs);
|
||||
$write("'%8s'\n", regstr);
|
||||
$write("'%-8s'\n", regstr);
|
||||
$write("'%8s'\n", "beep");
|
||||
$write("'%-8s'\n", "beep");
|
||||
|
||||
// $itord conversion bug, note a %d instead of proper float
|
||||
$display("log10(2) = %d", $log10(100));
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,10 @@ sub check {
|
|||
for my $author (sort keys %Authors) {
|
||||
print "Check: $author\n" if $Self->{verbose};
|
||||
if (!$Contributors{$author}) {
|
||||
error("Certify your contribution by appending '$author' to CONTRIBUTORS");
|
||||
error("Certify your contribution by appending '$author' to docs/CONTRIBUTORS.\n"
|
||||
." If '$author' is not your real name, please fix 'name=' in ~/.gitconfig\n"
|
||||
." Also check your https://github.com account's Settings->Profile->Name\n"
|
||||
." matches your ~/.gitconfig 'name='.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
%Error: t/t_tri_compass_bad.v:15: Unsupported: tristate in top-level IO: '__pinNumber1'
|
||||
: ... In instance t
|
||||
sub sub(i, o);
|
||||
^
|
||||
%Error: Exiting due to
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
scenarios(vlt => 1);
|
||||
|
||||
compile(
|
||||
expect_filename => $Self->{golden_filename},
|
||||
fails => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2020 by Wilson Snyder.
|
||||
|
||||
module t(/*AUTOARG*/
|
||||
// Outputs
|
||||
o,
|
||||
// Inputs
|
||||
i
|
||||
);
|
||||
|
||||
input i;
|
||||
output o;
|
||||
sub sub(i, o);
|
||||
endmodule
|
||||
|
||||
module sub(input i, output o);
|
||||
assign o = (i===1'bz) ? 1'b0 : i;
|
||||
endmodule
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
</module_files>
|
||||
<cells>
|
||||
<cell fl="d6" name="t" submodname="t" hier="t">
|
||||
<cell fl="d18" name="cell1" submodname="mod1" hier="t.cell1"/>
|
||||
<cell fl="d19" name="cell1" submodname="mod1__W4" hier="t.cell1"/>
|
||||
<cell fl="d24" name="cell2" submodname="mod2" hier="t.cell2"/>
|
||||
</cell>
|
||||
</cells>
|
||||
|
|
@ -22,57 +22,64 @@
|
|||
<var fl="d13" name="d" dtype_id="2" dir="input" vartype="logic" origName="d"/>
|
||||
<var fl="d14" name="q" dtype_id="2" dir="output" vartype="logic" origName="q"/>
|
||||
<var fl="d16" name="between" dtype_id="2" vartype="logic" origName="between"/>
|
||||
<instance fl="d18" name="cell1" defName="mod1" origName="cell1">
|
||||
<port fl="d18" name="q" direction="out" portIndex="1">
|
||||
<varref fl="d18" name="between" dtype_id="2"/>
|
||||
<instance fl="d19" name="cell1" defName="mod1__W4" origName="cell1">
|
||||
<port fl="d19" name="q" direction="out" portIndex="1">
|
||||
<varref fl="d19" name="between" dtype_id="2"/>
|
||||
</port>
|
||||
<port fl="d21" name="clk" direction="in" portIndex="2">
|
||||
<varref fl="d21" name="clk" dtype_id="1"/>
|
||||
<port fl="d20" name="clk" direction="in" portIndex="2">
|
||||
<varref fl="d20" name="clk" dtype_id="1"/>
|
||||
</port>
|
||||
<port fl="d22" name="d" direction="in" portIndex="3">
|
||||
<varref fl="d22" name="d" dtype_id="2"/>
|
||||
<port fl="d21" name="d" direction="in" portIndex="3">
|
||||
<varref fl="d21" name="d" dtype_id="2"/>
|
||||
</port>
|
||||
</instance>
|
||||
<instance fl="d24" name="cell2" defName="mod2" origName="cell2">
|
||||
<port fl="d24" name="d" direction="in" portIndex="1">
|
||||
<varref fl="d24" name="between" dtype_id="2"/>
|
||||
</port>
|
||||
<port fl="d27" name="q" direction="out" portIndex="2">
|
||||
<varref fl="d27" name="q" dtype_id="2"/>
|
||||
<port fl="d25" name="q" direction="out" portIndex="2">
|
||||
<varref fl="d25" name="q" dtype_id="2"/>
|
||||
</port>
|
||||
<port fl="d29" name="clk" direction="in" portIndex="3">
|
||||
<varref fl="d29" name="clk" dtype_id="1"/>
|
||||
<port fl="d26" name="clk" direction="in" portIndex="3">
|
||||
<varref fl="d26" name="clk" dtype_id="1"/>
|
||||
</port>
|
||||
</instance>
|
||||
</module>
|
||||
<module fl="d33" name="mod1" origName="mod1">
|
||||
<var fl="d35" name="clk" dtype_id="1" dir="input" vartype="logic" origName="clk"/>
|
||||
<var fl="d36" name="d" dtype_id="2" dir="input" vartype="logic" origName="d"/>
|
||||
<var fl="d37" name="q" dtype_id="2" dir="output" vartype="logic" origName="q"/>
|
||||
<always fl="d39">
|
||||
<sentree fl="d39">
|
||||
<senitem fl="d39" edgeType="POS">
|
||||
<varref fl="d39" name="clk" dtype_id="1"/>
|
||||
<module fl="d30" name="mod1__W4" origName="mod1">
|
||||
<var fl="d31" name="WIDTH" dtype_id="3" vartype="logic" origName="WIDTH" param="true">
|
||||
<const fl="d18" name="32'sh4" dtype_id="3"/>
|
||||
</var>
|
||||
<var fl="d33" name="clk" dtype_id="1" dir="input" vartype="logic" origName="clk"/>
|
||||
<var fl="d34" name="d" dtype_id="2" dir="input" vartype="logic" origName="d"/>
|
||||
<var fl="d35" name="q" dtype_id="2" dir="output" vartype="logic" origName="q"/>
|
||||
<var fl="d38" name="IGNORED" dtype_id="3" vartype="logic" origName="IGNORED" localparam="true">
|
||||
<const fl="d38" name="32'sh1" dtype_id="3"/>
|
||||
</var>
|
||||
<always fl="d40">
|
||||
<sentree fl="d40">
|
||||
<senitem fl="d40" edgeType="POS">
|
||||
<varref fl="d40" name="clk" dtype_id="1"/>
|
||||
</senitem>
|
||||
</sentree>
|
||||
<assigndly fl="d40" dtype_id="2">
|
||||
<varref fl="d40" name="d" dtype_id="2"/>
|
||||
<varref fl="d40" name="q" dtype_id="2"/>
|
||||
<assigndly fl="d41" dtype_id="2">
|
||||
<varref fl="d41" name="d" dtype_id="2"/>
|
||||
<varref fl="d41" name="q" dtype_id="2"/>
|
||||
</assigndly>
|
||||
</always>
|
||||
</module>
|
||||
<module fl="d44" name="mod2" origName="mod2">
|
||||
<var fl="d46" name="clk" dtype_id="1" dir="input" vartype="logic" origName="clk"/>
|
||||
<var fl="d47" name="d" dtype_id="2" dir="input" vartype="logic" origName="d"/>
|
||||
<var fl="d48" name="q" dtype_id="2" dir="output" vartype="logic" origName="q"/>
|
||||
<contassign fl="d51" dtype_id="2">
|
||||
<varref fl="d51" name="d" dtype_id="2"/>
|
||||
<varref fl="d51" name="q" dtype_id="2"/>
|
||||
<module fl="d45" name="mod2" origName="mod2">
|
||||
<var fl="d47" name="clk" dtype_id="1" dir="input" vartype="logic" origName="clk"/>
|
||||
<var fl="d48" name="d" dtype_id="2" dir="input" vartype="logic" origName="d"/>
|
||||
<var fl="d49" name="q" dtype_id="2" dir="output" vartype="logic" origName="q"/>
|
||||
<contassign fl="d52" dtype_id="2">
|
||||
<varref fl="d52" name="d" dtype_id="2"/>
|
||||
<varref fl="d52" name="q" dtype_id="2"/>
|
||||
</contassign>
|
||||
</module>
|
||||
<typetable fl="a0">
|
||||
<basicdtype fl="d46" id="1" name="logic"/>
|
||||
<basicdtype fl="d47" id="1" name="logic"/>
|
||||
<basicdtype fl="d13" id="2" name="logic" left="3" right="0"/>
|
||||
<basicdtype fl="d18" id="3" name="logic" left="31" right="0"/>
|
||||
</typetable>
|
||||
</netlist>
|
||||
</verilator_xml>
|
||||
|
|
|
|||
|
|
@ -13,29 +13,30 @@ module t (/*AUTOARG*/
|
|||
input [3:0] d;
|
||||
output wire [3:0] q;
|
||||
|
||||
logic [3:0] between;
|
||||
logic [3:0] between;
|
||||
|
||||
mod1 cell1 (.q(between),
|
||||
/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.d (d[3:0]));
|
||||
mod1 #(.WIDTH(4))
|
||||
cell1 (.q(between),
|
||||
.clk (clk),
|
||||
.d (d[3:0]));
|
||||
|
||||
mod2 cell2 (.d(between),
|
||||
/*AUTOINST*/
|
||||
// Outputs
|
||||
.q (q[3:0]),
|
||||
// Inputs
|
||||
.clk (clk));
|
||||
mod2
|
||||
cell2 (.d(between),
|
||||
.q (q[3:0]),
|
||||
.clk (clk));
|
||||
|
||||
endmodule
|
||||
|
||||
module mod1
|
||||
(
|
||||
input clk,
|
||||
input [3:0] d,
|
||||
output logic [3:0] q
|
||||
#(parameter WIDTH = 32)
|
||||
(
|
||||
input clk,
|
||||
input [WIDTH-1:0] d,
|
||||
output logic [WIDTH-1:0] q
|
||||
);
|
||||
|
||||
localparam IGNORED = 1;
|
||||
|
||||
always @(posedge clk)
|
||||
q <= d;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue