'Merge from master for release.'
This commit is contained in:
commit
c4f7bd6a04
|
|
@ -1,5 +1,6 @@
|
|||
\#*
|
||||
.#*
|
||||
.nfs*
|
||||
*~
|
||||
*.tidy
|
||||
*.old
|
||||
|
|
|
|||
29
Changes
29
Changes
|
|
@ -2,6 +2,35 @@ Revision history for Verilator
|
|||
|
||||
The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
* Verilator 4.040 2020-08-15
|
||||
|
||||
** Version 4.040 is planned to be the final version that will
|
||||
support pre-C++11 compilers. Please move to C++11 or newer compilers.
|
||||
|
||||
*** Fix arrayed interfaces, broke in 4.038 (#2468). [Josh Redford]
|
||||
|
||||
**** Support $stable, $rose and $fell. (#2148) (#2501) [Peter Monsson]
|
||||
|
||||
**** Support simple function localparams (#2461). [James Hanlon]
|
||||
|
||||
**** Miscellaneous parsing error changes towards UVM support.
|
||||
|
||||
**** Fix arrayed interfaces (#2469). [Josh Redford]
|
||||
|
||||
**** Fix protect lib VCS warning. (#2479) [Julien Margetts]
|
||||
|
||||
**** Fix combining different-width parameters (#2484). [abirkmanis]
|
||||
|
||||
**** Fix protect-lib without sequential logic (#2492). [Yutetsu TAKATSUKASA]
|
||||
|
||||
**** Fix V3Unknown from running with flat XML output (#2494). [James Hanlon]
|
||||
|
||||
**** Fix non-32 bit conversion to float (#2495). [dsvf]
|
||||
|
||||
**** Fix casting non-self-determined subexpressions (#2493). [phantom-killua]
|
||||
|
||||
**** Fix SystemC net names (#2500). [Edgar E. Iglesias]
|
||||
|
||||
|
||||
* Verilator 4.038 2020-07-11
|
||||
|
||||
|
|
|
|||
|
|
@ -80,23 +80,23 @@ elif [ "$TRAVIS_BUILD_STAGE_NAME" = "test" ]; then
|
|||
if [ "$M32" = 1 ]; then
|
||||
sudo apt-get install lib32z1-dev gcc-multilib g++-multilib
|
||||
fi
|
||||
yes yes | sudo cpan -fi Unix::Processors Parallel::Forker
|
||||
# Not listing Bit::Vector as slow to install, and only skips one test
|
||||
install-vcddiff
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
brew update
|
||||
# brew cask install gtkwave # fst2vcd hangs at launch, so don't bother
|
||||
brew install ccache perl
|
||||
yes yes | sudo cpan -fi Unix::Processors Parallel::Forker
|
||||
install-vcddiff
|
||||
elif [ "$TRAVIS_OS_NAME" = "freebsd" ]; then
|
||||
# fst2vcd fails with "Could not open '<input file>', exiting."
|
||||
sudo pkg install -y ccache gmake perl5 python3
|
||||
yes yes | sudo cpan -fi Unix::Processors Parallel::Forker
|
||||
install-vcddiff
|
||||
else
|
||||
fatal "Unknown os: '$TRAVIS_OS_NAME'"
|
||||
fi
|
||||
# Common installs
|
||||
if [ "$TRAVIS_DIST" != "trusty" ]; then
|
||||
TRAVIS_CPAN_REPO=https://cpan.org
|
||||
fi
|
||||
# Not listing Bit::Vector as slow to install, and only skips one test
|
||||
yes yes | sudo cpan -M $TRAVIS_CPAN_REPO -fi Unix::Processors Parallel::Forker
|
||||
install-vcddiff
|
||||
else
|
||||
##############################################################################
|
||||
# Unknown build stage
|
||||
|
|
|
|||
|
|
@ -7,11 +7,12 @@
|
|||
|
||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[4.038 2020-07-11],
|
||||
AC_INIT([Verilator],[4.040 2020-08-15],
|
||||
[https://verilator.org],
|
||||
[verilator],[https://verilator.org])
|
||||
# When releasing, also update header of Changes file
|
||||
# and commit using "devel release" or "Version bump" message
|
||||
# Then 'make maintainer-dist'
|
||||
|
||||
AC_CONFIG_HEADER(src/config_build.h)
|
||||
AC_CONFIG_FILES(Makefile docs/Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc verilator-config.cmake verilator-config-version.cmake)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ Dan Petrisko
|
|||
David Horton
|
||||
David Stanford
|
||||
Driss Hafdi
|
||||
Edgar E. Iglesias
|
||||
Eric Rippey
|
||||
Fan Shupei
|
||||
Garrett Smith
|
||||
|
|
@ -28,6 +29,7 @@ Jan Van Winkel
|
|||
Jeremy Bennett
|
||||
John Coiner
|
||||
John Demme
|
||||
Josh Redford
|
||||
Julien Margetts
|
||||
Kanad Kanhere
|
||||
Kevin Kiningham
|
||||
|
|
@ -37,6 +39,7 @@ Lukasz Dalek
|
|||
Maarten De Braekeleer
|
||||
Maciej Sobkowski
|
||||
Marco Widmer
|
||||
Marshal Qiao
|
||||
Matthew Ballance
|
||||
Michael Killough
|
||||
Mike Popoloski
|
||||
|
|
@ -47,6 +50,7 @@ Peter Horvath
|
|||
Peter Monsson
|
||||
Philipp Wagner
|
||||
Pieter Kapsenberg
|
||||
Piotr Binkowski
|
||||
Qingyao Sun
|
||||
Richard Myers
|
||||
Sean Cross
|
||||
|
|
|
|||
|
|
@ -584,6 +584,30 @@ QData VL_POWSS_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp, bool lsig
|
|||
return VL_POW_QQW(obits, rbits, rbits, lhs, rwp);
|
||||
}
|
||||
|
||||
double VL_ITOR_D_W(int lbits, WDataInP lwp) VL_PURE {
|
||||
int ms_word = VL_WORDS_I(lbits) - 1;
|
||||
for (; !lwp[ms_word] && ms_word > 0;) --ms_word;
|
||||
if (ms_word == 0) return static_cast<double>(lwp[0]);
|
||||
if (ms_word == 1) return static_cast<double>(VL_SET_QW(lwp));
|
||||
// We need 53 bits of mantissa, which might mean looking at 3 words
|
||||
// namely ms_word, ms_word-1 and ms_word-2
|
||||
EData ihi = lwp[ms_word];
|
||||
EData imid = lwp[ms_word - 1];
|
||||
EData ilo = lwp[ms_word - 2];
|
||||
double hi = static_cast<double>(ihi) * exp2(2 * VL_EDATASIZE);
|
||||
double mid = static_cast<double>(imid) * exp2(VL_EDATASIZE);
|
||||
double lo = static_cast<double>(ilo);
|
||||
double d = (hi + mid + lo) * exp2(VL_EDATASIZE * (ms_word - 2));
|
||||
return d;
|
||||
}
|
||||
double VL_ISTOR_D_W(int lbits, WDataInP lwp) VL_PURE {
|
||||
if (!VL_SIGN_W(lbits, lwp)) return VL_ITOR_D_W(lbits, lwp);
|
||||
vluint32_t pos[VL_MULS_MAX_WORDS + 1]; // Fixed size, as MSVC++ doesn't allow [words] here
|
||||
VL_NEGATE_W(VL_WORDS_I(lbits), pos, lwp);
|
||||
_VL_CLEAN_INPLACE_W(lbits, pos);
|
||||
return -VL_ITOR_D_W(lbits, pos);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Formatting
|
||||
|
||||
|
|
|
|||
|
|
@ -764,9 +764,27 @@ static inline QData VL_CVT_Q_D(double lhs) VL_PURE {
|
|||
}
|
||||
// clang-format on
|
||||
|
||||
/// Return double from QData (numeric)
|
||||
static inline double VL_ITOR_D_I(IData lhs) VL_PURE {
|
||||
return static_cast<double>(static_cast<vlsint32_t>(lhs));
|
||||
/// Return double from lhs (numeric) unsigned
|
||||
double VL_ITOR_D_W(int lbits, WDataInP lwp) VL_PURE;
|
||||
static inline double VL_ITOR_D_I(int, IData lhs) VL_PURE {
|
||||
return static_cast<double>(static_cast<vluint32_t>(lhs));
|
||||
}
|
||||
static inline double VL_ITOR_D_Q(int, QData lhs) VL_PURE {
|
||||
return static_cast<double>(static_cast<vluint64_t>(lhs));
|
||||
}
|
||||
/// Return double from lhs (numeric) signed
|
||||
double VL_ISTOR_D_W(int lbits, WDataInP lwp) VL_PURE;
|
||||
static inline double VL_ISTOR_D_I(int lbits, IData lhs) VL_PURE {
|
||||
if (lbits == 32) return static_cast<double>(static_cast<vlsint32_t>(lhs));
|
||||
WData lwp[VL_WQ_WORDS_E];
|
||||
VL_SET_WI(lwp, lhs);
|
||||
return VL_ISTOR_D_W(lbits, lwp);
|
||||
}
|
||||
static inline double VL_ISTOR_D_Q(int lbits, QData lhs) VL_PURE {
|
||||
if (lbits == 64) return static_cast<double>(static_cast<vlsint64_t>(lhs));
|
||||
WData lwp[VL_WQ_WORDS_E];
|
||||
VL_SET_WQ(lwp, lhs);
|
||||
return VL_ISTOR_D_W(lbits, lwp);
|
||||
}
|
||||
/// Return QData from double (numeric)
|
||||
static inline IData VL_RTOI_I_D(double lhs) VL_PURE {
|
||||
|
|
@ -1453,6 +1471,7 @@ static inline int _VL_CMPS_W(int lbits, WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
|
|||
//=========================================================================
|
||||
// Math
|
||||
|
||||
// Output NOT clean
|
||||
static inline WDataOutP VL_NEGATE_W(int words, WDataOutP owp, WDataInP lwp) VL_MT_SAFE {
|
||||
EData carry = 1;
|
||||
for (int i = 0; i < words; ++i) {
|
||||
|
|
@ -2538,25 +2557,25 @@ static inline WDataOutP VL_CONSTHI_W_1X(int obits, int lsb, WDataOutP obase,
|
|||
EData d0) VL_MT_SAFE {
|
||||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0;
|
||||
_END(obits,1);
|
||||
_END(obits, VL_WORDS_I(lsb) + 1);
|
||||
}
|
||||
static inline WDataOutP VL_CONSTHI_W_2X(int obits, int lsb, WDataOutP obase,
|
||||
EData d1, EData d0) VL_MT_SAFE {
|
||||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0; o[1] = d1;
|
||||
_END(obits,2);
|
||||
_END(obits, VL_WORDS_I(lsb) + 2);
|
||||
}
|
||||
static inline WDataOutP VL_CONSTHI_W_3X(int obits, int lsb, WDataOutP obase,
|
||||
EData d2, EData d1, EData d0) VL_MT_SAFE {
|
||||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0; o[1] = d1; o[2] = d2;
|
||||
_END(obits,3);
|
||||
_END(obits, VL_WORDS_I(lsb) + 3);
|
||||
}
|
||||
static inline WDataOutP VL_CONSTHI_W_4X(int obits, int lsb, WDataOutP obase,
|
||||
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
||||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
||||
_END(obits,4);
|
||||
_END(obits, VL_WORDS_I(lsb) + 4);
|
||||
}
|
||||
static inline WDataOutP VL_CONSTHI_W_5X(int obits, int lsb, WDataOutP obase,
|
||||
EData d4,
|
||||
|
|
@ -2564,7 +2583,7 @@ static inline WDataOutP VL_CONSTHI_W_5X(int obits, int lsb, WDataOutP obase,
|
|||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
||||
o[4] = d4;
|
||||
_END(obits,5);
|
||||
_END(obits, VL_WORDS_I(lsb) + 5);
|
||||
}
|
||||
static inline WDataOutP VL_CONSTHI_W_6X(int obits, int lsb, WDataOutP obase,
|
||||
EData d5, EData d4,
|
||||
|
|
@ -2572,7 +2591,7 @@ static inline WDataOutP VL_CONSTHI_W_6X(int obits, int lsb, WDataOutP obase,
|
|||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
||||
o[4] = d4; o[5] = d5;
|
||||
_END(obits,6);
|
||||
_END(obits, VL_WORDS_I(lsb) + 6);
|
||||
}
|
||||
static inline WDataOutP VL_CONSTHI_W_7X(int obits, int lsb, WDataOutP obase,
|
||||
EData d6, EData d5, EData d4,
|
||||
|
|
@ -2580,7 +2599,7 @@ static inline WDataOutP VL_CONSTHI_W_7X(int obits, int lsb, WDataOutP obase,
|
|||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
||||
o[4] = d4; o[5] = d5; o[6] = d6;
|
||||
_END(obits,7);
|
||||
_END(obits, VL_WORDS_I(lsb) + 7);
|
||||
}
|
||||
static inline WDataOutP VL_CONSTHI_W_8X(int obits, int lsb, WDataOutP obase,
|
||||
EData d7, EData d6, EData d5, EData d4,
|
||||
|
|
@ -2588,7 +2607,7 @@ static inline WDataOutP VL_CONSTHI_W_8X(int obits, int lsb, WDataOutP obase,
|
|||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
||||
o[4] = d4; o[5] = d5; o[6] = d6; o[7] = d7;
|
||||
_END(obits,8);
|
||||
_END(obits, VL_WORDS_I(lsb) + 8);
|
||||
}
|
||||
|
||||
#undef _END
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public:
|
|||
}
|
||||
virtual ~VerilatedSerialize() {
|
||||
close();
|
||||
if (m_bufp) VL_DO_CLEAR(delete m_bufp, m_bufp = NULL);
|
||||
if (m_bufp) VL_DO_CLEAR(delete[] m_bufp, m_bufp = NULL);
|
||||
}
|
||||
// METHODS
|
||||
bool isOpen() const { return m_isOpen; }
|
||||
|
|
@ -118,7 +118,7 @@ public:
|
|||
}
|
||||
virtual ~VerilatedDeserialize() {
|
||||
close();
|
||||
if (m_bufp) VL_DO_CLEAR(delete m_bufp, m_bufp = NULL);
|
||||
if (m_bufp) VL_DO_CLEAR(delete[] m_bufp, m_bufp = NULL);
|
||||
}
|
||||
// METHODS
|
||||
bool isOpen() const { return m_isOpen; }
|
||||
|
|
|
|||
|
|
@ -89,11 +89,54 @@ private:
|
|||
if (!nodep->immediate()) nodep->sentreep(newSenTree(nodep));
|
||||
clearAssertInfo();
|
||||
}
|
||||
virtual void visit(AstFell* nodep) VL_OVERRIDE {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
iterateChildren(nodep);
|
||||
FileLine* fl = nodep->fileline();
|
||||
AstNode* exprp = nodep->exprp()->unlinkFrBack();
|
||||
if (exprp->width() > 1) exprp = new AstSel(fl, exprp, 0, 1);
|
||||
AstNode* past = new AstPast(fl, exprp, NULL);
|
||||
past->dtypeFrom(exprp);
|
||||
exprp = new AstAnd(fl, past, new AstNot(fl, exprp->cloneTree(false)));
|
||||
exprp->dtypeSetLogicBool();
|
||||
nodep->replaceWith(exprp);
|
||||
nodep->sentreep(newSenTree(nodep));
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
virtual void visit(AstPast* nodep) VL_OVERRIDE {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
iterateChildren(nodep);
|
||||
nodep->sentreep(newSenTree(nodep));
|
||||
}
|
||||
virtual void visit(AstRose* nodep) VL_OVERRIDE {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
iterateChildren(nodep);
|
||||
FileLine* fl = nodep->fileline();
|
||||
AstNode* exprp = nodep->exprp()->unlinkFrBack();
|
||||
if (exprp->width() > 1) exprp = new AstSel(fl, exprp, 0, 1);
|
||||
AstNode* past = new AstPast(fl, exprp, NULL);
|
||||
past->dtypeFrom(exprp);
|
||||
exprp = new AstAnd(fl, new AstNot(fl, past), exprp->cloneTree(false));
|
||||
exprp->dtypeSetLogicBool();
|
||||
nodep->replaceWith(exprp);
|
||||
nodep->sentreep(newSenTree(nodep));
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
virtual void visit(AstStable* nodep) VL_OVERRIDE {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
iterateChildren(nodep);
|
||||
FileLine* fl = nodep->fileline();
|
||||
AstNode* exprp = nodep->exprp()->unlinkFrBack();
|
||||
AstNode* past = new AstPast(fl, exprp, NULL);
|
||||
past->dtypeFrom(exprp);
|
||||
exprp = new AstEq(fl, past,
|
||||
exprp->cloneTree(false)); // new AstVarRef(fl, exprp, true)
|
||||
exprp->dtypeSetLogicBool();
|
||||
nodep->replaceWith(exprp);
|
||||
nodep->sentreep(newSenTree(nodep));
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstPropClocked* nodep) VL_OVERRIDE {
|
||||
// No need to iterate the body, once replace will get iterated
|
||||
iterateAndNextNull(nodep->sensesp());
|
||||
|
|
|
|||
|
|
@ -1891,6 +1891,7 @@ public:
|
|||
// For documentation on emitC format see EmitCStmts::emitOpName
|
||||
virtual string emitC() = 0;
|
||||
virtual string emitSimpleOperator() { return ""; }
|
||||
virtual bool emitCheckMaxWords() { return false; } // Check VL_MULS_MAX_WORDS
|
||||
virtual bool cleanOut() const = 0; // True if output has extra upper bits zero
|
||||
// Someday we will generically support data types on every math node
|
||||
// Until then isOpaque indicates we shouldn't constant optimize this node type
|
||||
|
|
|
|||
|
|
@ -1493,19 +1493,19 @@ void AstParseRef::dump(std::ostream& str) const {
|
|||
this->AstNode::dump(str);
|
||||
str << " [" << expect().ascii() << "]";
|
||||
}
|
||||
void AstPackageRef::dump(std::ostream& str) const {
|
||||
void AstClassOrPackageRef::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
if (packagep()) { str << " pkg=" << nodeAddr(packagep()); }
|
||||
if (classOrPackagep()) { str << " cpkg=" << nodeAddr(classOrPackagep()); }
|
||||
str << " -> ";
|
||||
if (packagep()) {
|
||||
packagep()->dump(str);
|
||||
if (classOrPackagep()) {
|
||||
classOrPackagep()->dump(str);
|
||||
} else {
|
||||
str << "UNLINKED";
|
||||
}
|
||||
}
|
||||
void AstDot::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
if (colon()) str << "[::]";
|
||||
if (colon()) str << " [::]";
|
||||
}
|
||||
void AstActive::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
|
|
|
|||
164
src/V3AstNodes.h
164
src/V3AstNodes.h
|
|
@ -448,6 +448,7 @@ public:
|
|||
ASTNODE_NODE_FUNCS(TypedefFwd)
|
||||
// METHODS
|
||||
virtual string name() const { return m_name; }
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
};
|
||||
|
||||
class AstDefImplicitDType : public AstNodeDType {
|
||||
|
|
@ -1139,6 +1140,15 @@ public:
|
|||
, m_refDTypep(NULL)
|
||||
, m_name(name)
|
||||
, m_packagep(NULL) {}
|
||||
AstRefDType(FileLine* fl, const string& name, AstNode* classOrPackagep, AstNode* paramsp)
|
||||
: ASTGEN_SUPER(fl)
|
||||
, m_typedefp(NULL)
|
||||
, m_refDTypep(NULL)
|
||||
, m_name(name)
|
||||
, m_packagep(NULL) {
|
||||
setNOp3p(classOrPackagep);
|
||||
addNOp4p(paramsp);
|
||||
}
|
||||
class FlagTypeOfExpr {}; // type(expr) for parser only
|
||||
AstRefDType(FileLine* fl, FlagTypeOfExpr, AstNode* typeofp)
|
||||
: ASTGEN_SUPER(fl)
|
||||
|
|
@ -1216,6 +1226,8 @@ public:
|
|||
AstNodeModule* packagep() const { return m_packagep; }
|
||||
void packagep(AstNodeModule* nodep) { m_packagep = nodep; }
|
||||
AstNode* typeofp() const { return op2p(); }
|
||||
AstNode* classOrPackagep() const { return op3p(); }
|
||||
AstPin* paramsp() const { return VN_CAST(op4p(), Pin); }
|
||||
};
|
||||
|
||||
class AstStructDType : public AstNodeUOrStructDType {
|
||||
|
|
@ -2429,11 +2441,14 @@ public:
|
|||
|
||||
class AstModule : public AstNodeModule {
|
||||
// A module declaration
|
||||
private:
|
||||
bool m_isProgram; // Module represents a program
|
||||
public:
|
||||
AstModule(FileLine* fl, const string& name)
|
||||
: ASTGEN_SUPER(fl, name) {}
|
||||
AstModule(FileLine* fl, const string& name, bool program = false)
|
||||
: ASTGEN_SUPER(fl, name)
|
||||
, m_isProgram(program) {}
|
||||
ASTNODE_NODE_FUNCS(Module)
|
||||
virtual string verilogKwd() const { return "module"; }
|
||||
virtual string verilogKwd() const { return m_isProgram ? "program" : "module"; }
|
||||
};
|
||||
|
||||
class AstNotFoundModule : public AstNodeModule {
|
||||
|
|
@ -2891,29 +2906,40 @@ public:
|
|||
void ftaskrefp(AstNodeFTaskRef* nodep) { setNOp2p(nodep); } // op2 = Function/task reference
|
||||
};
|
||||
|
||||
class AstPackageRef : public AstNode {
|
||||
class AstClassOrPackageRef : public AstNode {
|
||||
private:
|
||||
AstPackage* m_packagep; // Package hierarchy
|
||||
string m_name;
|
||||
AstNode* m_classOrPackagep; // Package hierarchy
|
||||
public:
|
||||
AstPackageRef(FileLine* fl, AstPackage* packagep)
|
||||
AstClassOrPackageRef(FileLine* fl, const string& name, AstNode* classOrPackagep,
|
||||
AstNode* paramsp)
|
||||
: ASTGEN_SUPER(fl)
|
||||
, m_packagep(packagep) {}
|
||||
ASTNODE_NODE_FUNCS(PackageRef)
|
||||
, m_name(name)
|
||||
, m_classOrPackagep(classOrPackagep) {
|
||||
addNOp4p(paramsp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(ClassOrPackageRef)
|
||||
// METHODS
|
||||
virtual const char* broken() const {
|
||||
BROKEN_RTN(!m_packagep || !m_packagep->brokeExists());
|
||||
BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists());
|
||||
return NULL;
|
||||
}
|
||||
virtual void cloneRelink() {
|
||||
if (m_packagep && m_packagep->clonep()) { m_packagep = m_packagep->clonep(); }
|
||||
if (m_classOrPackagep && m_classOrPackagep->clonep()) {
|
||||
m_classOrPackagep = m_classOrPackagep->clonep();
|
||||
}
|
||||
}
|
||||
virtual bool same(const AstNode* samep) const {
|
||||
return (m_packagep == static_cast<const AstPackageRef*>(samep)->m_packagep);
|
||||
return (m_classOrPackagep
|
||||
== static_cast<const AstClassOrPackageRef*>(samep)->m_classOrPackagep);
|
||||
}
|
||||
virtual V3Hash sameHash() const { return V3Hash(m_packagep); }
|
||||
virtual V3Hash sameHash() const { return V3Hash(m_classOrPackagep); }
|
||||
virtual void dump(std::ostream& str = std::cout) const;
|
||||
AstPackage* packagep() const { return m_packagep; }
|
||||
void packagep(AstPackage* nodep) { m_packagep = nodep; }
|
||||
virtual string name() const { return m_name; } // * = Var name
|
||||
AstNode* classOrPackagep() const { return m_classOrPackagep; }
|
||||
AstPackage* packagep() const { return VN_CAST(classOrPackagep(), Package); }
|
||||
void classOrPackagep(AstNode* nodep) { m_classOrPackagep = nodep; }
|
||||
AstPin* paramsp() const { return VN_CAST(op4p(), Pin); }
|
||||
};
|
||||
|
||||
class AstDot : public AstNode {
|
||||
|
|
@ -2929,9 +2955,9 @@ public:
|
|||
}
|
||||
ASTNODE_NODE_FUNCS(Dot)
|
||||
// For parser, make only if non-null package
|
||||
static AstNode* newIfPkg(FileLine* fl, AstPackage* packagep, AstNode* rhsp) {
|
||||
if (!packagep) return rhsp;
|
||||
return new AstDot(fl, true, new AstPackageRef(fl, packagep), rhsp);
|
||||
static AstNode* newIfPkg(FileLine* fl, AstNode* packageOrClassp, AstNode* rhsp) {
|
||||
if (!packageOrClassp) return rhsp;
|
||||
return new AstDot(fl, true, packageOrClassp, rhsp);
|
||||
}
|
||||
virtual void dump(std::ostream& str) const;
|
||||
virtual string emitVerilog() { V3ERROR_NA_RETURN(""); }
|
||||
|
|
@ -5497,6 +5523,7 @@ public:
|
|||
virtual int instrCount() const { return instrCountDouble(); }
|
||||
};
|
||||
class AstIToRD : public AstNodeUniop {
|
||||
// $itor where lhs is unsigned
|
||||
public:
|
||||
AstIToRD(FileLine* fl, AstNode* lhsp)
|
||||
: ASTGEN_SUPER(fl, lhsp) {
|
||||
|
|
@ -5505,10 +5532,27 @@ public:
|
|||
ASTNODE_NODE_FUNCS(IToRD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opIToRD(lhs); }
|
||||
virtual string emitVerilog() { return "%f$itor(%l)"; }
|
||||
virtual string emitC() { return "VL_ITOR_D_I(%li)"; }
|
||||
virtual string emitC() { return "VL_ITOR_D_%lq(%lw, %li)"; }
|
||||
virtual bool cleanOut() const { return false; }
|
||||
virtual bool cleanLhs() const { return false; } // Eliminated before matters
|
||||
virtual bool sizeMattersLhs() const { return false; } // Eliminated before matters
|
||||
virtual bool cleanLhs() const { return true; }
|
||||
virtual bool sizeMattersLhs() const { return false; }
|
||||
virtual int instrCount() const { return instrCountDouble(); }
|
||||
};
|
||||
class AstISToRD : public AstNodeUniop {
|
||||
// $itor where lhs is signed
|
||||
public:
|
||||
AstISToRD(FileLine* fl, AstNode* lhsp)
|
||||
: ASTGEN_SUPER(fl, lhsp) {
|
||||
dtypeSetDouble();
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(ISToRD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opISToRD(lhs); }
|
||||
virtual string emitVerilog() { return "%f$itor($signed(%l))"; }
|
||||
virtual string emitC() { return "VL_ISTOR_D_%lq(%lw, %li)"; }
|
||||
virtual bool emitCheckMaxWords() { return true; }
|
||||
virtual bool cleanOut() const { return false; }
|
||||
virtual bool cleanLhs() const { return true; }
|
||||
virtual bool sizeMattersLhs() const { return false; }
|
||||
virtual int instrCount() const { return instrCountDouble(); }
|
||||
};
|
||||
class AstRealToBits : public AstNodeUniop {
|
||||
|
|
@ -7125,6 +7169,7 @@ public:
|
|||
virtual string emitVerilog() { return "%k(%l %f* %r)"; }
|
||||
virtual string emitC() { return "VL_MULS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return ""; }
|
||||
virtual bool emitCheckMaxWords() { return true; }
|
||||
virtual bool cleanOut() const { return false; }
|
||||
virtual bool cleanLhs() const { return true; }
|
||||
virtual bool cleanRhs() const { return true; }
|
||||
|
|
@ -7262,6 +7307,7 @@ public:
|
|||
}
|
||||
virtual string emitVerilog() { return "%k(%l %f** %r)"; }
|
||||
virtual string emitC() { return "VL_POW_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual bool emitCheckMaxWords() { return true; }
|
||||
virtual bool cleanOut() const { return false; }
|
||||
virtual bool cleanLhs() const { return true; }
|
||||
virtual bool cleanRhs() const { return true; }
|
||||
|
|
@ -7307,6 +7353,7 @@ public:
|
|||
}
|
||||
virtual string emitVerilog() { return "%k(%l %f** %r)"; }
|
||||
virtual string emitC() { return "VL_POWSS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri, 1,0)"; }
|
||||
virtual bool emitCheckMaxWords() { return true; }
|
||||
virtual bool cleanOut() const { return false; }
|
||||
virtual bool cleanLhs() const { return true; }
|
||||
virtual bool cleanRhs() const { return true; }
|
||||
|
|
@ -7330,6 +7377,7 @@ public:
|
|||
}
|
||||
virtual string emitVerilog() { return "%k(%l %f** %r)"; }
|
||||
virtual string emitC() { return "VL_POWSS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri, 1,1)"; }
|
||||
virtual bool emitCheckMaxWords() { return true; }
|
||||
virtual bool cleanOut() const { return false; }
|
||||
virtual bool cleanLhs() const { return true; }
|
||||
virtual bool cleanRhs() const { return true; }
|
||||
|
|
@ -7353,6 +7401,7 @@ public:
|
|||
}
|
||||
virtual string emitVerilog() { return "%k(%l %f** %r)"; }
|
||||
virtual string emitC() { return "VL_POWSS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri, 0,1)"; }
|
||||
virtual bool emitCheckMaxWords() { return true; }
|
||||
virtual bool cleanOut() const { return false; }
|
||||
virtual bool cleanLhs() const { return true; }
|
||||
virtual bool cleanRhs() const { return true; }
|
||||
|
|
@ -7942,6 +7991,31 @@ public:
|
|||
virtual bool isHeavy() const { return true; }
|
||||
};
|
||||
|
||||
class AstFell : public AstNodeMath {
|
||||
// Verilog $fell
|
||||
// Parents: math
|
||||
// Children: expression
|
||||
public:
|
||||
AstFell(FileLine* fl, AstNode* exprp)
|
||||
: ASTGEN_SUPER(fl) {
|
||||
addOp1p(exprp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(Fell)
|
||||
virtual string emitVerilog() { return "$fell(%l)"; }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) {
|
||||
V3ERROR_NA;
|
||||
}
|
||||
virtual string emitC() { V3ERROR_NA_RETURN(""); }
|
||||
virtual string emitSimpleOperator() { V3ERROR_NA_RETURN(""); }
|
||||
virtual bool cleanOut() const { V3ERROR_NA_RETURN(""); }
|
||||
virtual int instrCount() const { return widthInstrs(); }
|
||||
AstNode* exprp() const { return op1p(); } // op1 = expression
|
||||
AstSenTree* sentreep() const { return VN_CAST(op2p(), SenTree); } // op2 = clock domain
|
||||
void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(const AstNode* samep) const { return true; }
|
||||
};
|
||||
|
||||
class AstPast : public AstNodeMath {
|
||||
// Verilog $past
|
||||
// Parents: math
|
||||
|
|
@ -7969,6 +8043,31 @@ public:
|
|||
virtual bool same(const AstNode* samep) const { return true; }
|
||||
};
|
||||
|
||||
class AstRose : public AstNodeMath {
|
||||
// Verilog $rose
|
||||
// Parents: math
|
||||
// Children: expression
|
||||
public:
|
||||
AstRose(FileLine* fl, AstNode* exprp)
|
||||
: ASTGEN_SUPER(fl) {
|
||||
addOp1p(exprp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(Rose)
|
||||
virtual string emitVerilog() { return "$rose(%l)"; }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) {
|
||||
V3ERROR_NA;
|
||||
}
|
||||
virtual string emitC() { V3ERROR_NA_RETURN(""); }
|
||||
virtual string emitSimpleOperator() { V3ERROR_NA_RETURN(""); }
|
||||
virtual bool cleanOut() const { V3ERROR_NA_RETURN(""); }
|
||||
virtual int instrCount() const { return widthInstrs(); }
|
||||
AstNode* exprp() const { return op1p(); } // op1 = expression
|
||||
AstSenTree* sentreep() const { return VN_CAST(op2p(), SenTree); } // op2 = clock domain
|
||||
void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(const AstNode* samep) const { return true; }
|
||||
};
|
||||
|
||||
class AstSampled : public AstNodeMath {
|
||||
// Verilog $sampled
|
||||
// Parents: math
|
||||
|
|
@ -7989,6 +8088,31 @@ public:
|
|||
virtual bool same(const AstNode* samep) const { return true; }
|
||||
};
|
||||
|
||||
class AstStable : public AstNodeMath {
|
||||
// Verilog $stable
|
||||
// Parents: math
|
||||
// Children: expression
|
||||
public:
|
||||
AstStable(FileLine* fl, AstNode* exprp)
|
||||
: ASTGEN_SUPER(fl) {
|
||||
addOp1p(exprp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(Stable)
|
||||
virtual string emitVerilog() { return "$stable(%l)"; }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) {
|
||||
V3ERROR_NA;
|
||||
}
|
||||
virtual string emitC() { V3ERROR_NA_RETURN(""); }
|
||||
virtual string emitSimpleOperator() { V3ERROR_NA_RETURN(""); }
|
||||
virtual bool cleanOut() const { V3ERROR_NA_RETURN(""); }
|
||||
virtual int instrCount() const { return widthInstrs(); }
|
||||
AstNode* exprp() const { return op1p(); } // op1 = expression
|
||||
AstSenTree* sentreep() const { return VN_CAST(op2p(), SenTree); } // op2 = clock domain
|
||||
void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(const AstNode* samep) const { return true; }
|
||||
};
|
||||
|
||||
class AstPattern : public AstNodeMath {
|
||||
// Verilog '{a,b,c,d...}
|
||||
// Parents: AstNodeAssign, AstPattern, ...
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
// The following nodes have package pointers and are cleaned up here:
|
||||
// AstRefDType, AstEnumItemRef, AstNodeVarRef, AstNodeFTask
|
||||
// These have packagep but will not exist at this stage
|
||||
// AstPackageImport, AstDot, AstPackageRef
|
||||
// AstPackageImport, AstDot, AstClassOrPackageRef
|
||||
//
|
||||
// Note on packagep: After the V3Scope/V3LinkDotScoped stage, package links
|
||||
// are no longer used, but their presence prevents us from removing empty
|
||||
|
|
|
|||
|
|
@ -877,6 +877,15 @@ public:
|
|||
emitOpName(nodep, nodep->emitC(), NULL, NULL, NULL);
|
||||
}
|
||||
virtual void visit(AstNodeUniop* nodep) VL_OVERRIDE {
|
||||
if (nodep->emitCheckMaxWords()
|
||||
&& (nodep->widthWords() > VL_MULS_MAX_WORDS
|
||||
|| nodep->lhsp()->widthWords() > VL_MULS_MAX_WORDS)) {
|
||||
nodep->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
"Unsupported: "
|
||||
<< nodep->prettyOperatorName() << " operator of " << nodep->width()
|
||||
<< " bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
|
||||
}
|
||||
if (emitSimpleOk(nodep)) {
|
||||
putbs("(");
|
||||
puts(nodep->emitSimpleOperator());
|
||||
|
|
@ -888,6 +897,13 @@ public:
|
|||
}
|
||||
}
|
||||
virtual void visit(AstNodeBiop* nodep) VL_OVERRIDE {
|
||||
if (nodep->emitCheckMaxWords() && nodep->widthWords() > VL_MULS_MAX_WORDS) {
|
||||
nodep->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
"Unsupported: "
|
||||
<< nodep->prettyOperatorName() << " operator of " << nodep->width()
|
||||
<< " bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
|
||||
}
|
||||
if (emitSimpleOk(nodep)) {
|
||||
putbs("(");
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
|
|
@ -915,56 +931,6 @@ public:
|
|||
puts(")");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstMulS* nodep) VL_OVERRIDE {
|
||||
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
|
||||
nodep->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
"Unsupported: Signed multiply of "
|
||||
<< nodep->width()
|
||||
<< " bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
|
||||
}
|
||||
visit(VN_CAST(nodep, NodeBiop));
|
||||
}
|
||||
virtual void visit(AstPow* nodep) VL_OVERRIDE {
|
||||
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
|
||||
nodep->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
"Unsupported: Power of "
|
||||
<< nodep->width()
|
||||
<< " bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
|
||||
}
|
||||
visit(VN_CAST(nodep, NodeBiop));
|
||||
}
|
||||
virtual void visit(AstPowSS* nodep) VL_OVERRIDE {
|
||||
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
|
||||
nodep->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
"Unsupported: Power of "
|
||||
<< nodep->width()
|
||||
<< " bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
|
||||
}
|
||||
visit(VN_CAST(nodep, NodeBiop));
|
||||
}
|
||||
virtual void visit(AstPowSU* nodep) VL_OVERRIDE {
|
||||
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
|
||||
nodep->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
"Unsupported: Power of "
|
||||
<< nodep->width()
|
||||
<< " bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
|
||||
}
|
||||
visit(VN_CAST(nodep, NodeBiop));
|
||||
}
|
||||
virtual void visit(AstPowUS* nodep) VL_OVERRIDE {
|
||||
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
|
||||
nodep->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
"Unsupported: Power of "
|
||||
<< nodep->width()
|
||||
<< " bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
|
||||
}
|
||||
visit(VN_CAST(nodep, NodeBiop));
|
||||
}
|
||||
virtual void visit(AstCCast* nodep) VL_OVERRIDE {
|
||||
// Extending a value of the same word width is just a NOP.
|
||||
if (nodep->size() <= VL_IDATASIZE) {
|
||||
|
|
@ -3825,8 +3791,8 @@ void V3EmitC::emitc() {
|
|||
nodep = VN_CAST(nodep->nextp(), NodeModule)) {
|
||||
if (VN_IS(nodep, Class)) continue; // Imped with ClassPackage
|
||||
// clang-format off
|
||||
{ EmitCImp cint; cint.mainInt(nodep); }
|
||||
{ EmitCImp slow; slow.mainImp(nodep, true); }
|
||||
EmitCImp cint; cint.mainInt(nodep);
|
||||
cint.mainImp(nodep, true);
|
||||
{ EmitCImp fast; fast.mainImp(nodep, false); }
|
||||
// clang-format on
|
||||
}
|
||||
|
|
|
|||
|
|
@ -429,7 +429,9 @@ public:
|
|||
static AstIfaceRefDType* ifaceRefFromArray(AstNodeDType* nodep) {
|
||||
AstIfaceRefDType* ifacerefp = VN_CAST(nodep, IfaceRefDType);
|
||||
if (!ifacerefp) {
|
||||
if (AstUnpackArrayDType* arrp = VN_CAST(nodep, UnpackArrayDType)) {
|
||||
if (AstBracketArrayDType* arrp = VN_CAST(nodep, BracketArrayDType)) {
|
||||
ifacerefp = VN_CAST(arrp->subDTypep(), IfaceRefDType);
|
||||
} else if (AstUnpackArrayDType* arrp = VN_CAST(nodep, UnpackArrayDType)) {
|
||||
ifacerefp = VN_CAST(arrp->subDTypep(), IfaceRefDType);
|
||||
}
|
||||
}
|
||||
|
|
@ -1006,12 +1008,6 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
// Var: Remember its name for later resolution
|
||||
UASSERT_OBJ(m_curSymp && m_modSymp, nodep, "Var not under module?");
|
||||
iterateChildren(nodep);
|
||||
if (m_ftaskp && nodep->isParam()) {
|
||||
nodep->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported: Parameters in functions"); // Big3 unsupported too
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return;
|
||||
}
|
||||
if (nodep->isFuncLocal() && nodep->lifetime().isStatic()) {
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: 'static' function/task variables");
|
||||
} else if (nodep->isClassMember() && nodep->lifetime().isStatic()) {
|
||||
|
|
@ -1951,7 +1947,7 @@ private:
|
|||
m_ds.m_dotPos = DP_SCOPE;
|
||||
|
||||
// m_ds.m_dotText communicates the cell prefix between stages
|
||||
if (VN_IS(nodep->lhsp(), PackageRef)) {
|
||||
if (VN_IS(nodep->lhsp(), ClassOrPackageRef)) {
|
||||
// if (!start) { nodep->lhsp()->v3error("Package reference may not be embedded in
|
||||
// dotted reference"); m_ds.m_dotErr=true; }
|
||||
m_ds.m_dotPos = DP_PACKAGE;
|
||||
|
|
@ -2047,9 +2043,16 @@ private:
|
|||
expectWhat = "scope/variable";
|
||||
allowScope = true;
|
||||
allowVar = true;
|
||||
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), PackageRef), m_ds.m_dotp->lhsp(),
|
||||
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(),
|
||||
"Bad package link");
|
||||
packagep = VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep();
|
||||
AstClassOrPackageRef* cpackagerefp
|
||||
= VN_CAST(m_ds.m_dotp->lhsp(), ClassOrPackageRef);
|
||||
packagep = cpackagerefp->packagep();
|
||||
if (!packagep && cpackagerefp->classOrPackagep()) {
|
||||
nodep->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported: Class '::' references: "
|
||||
<< AstNode::prettyNameQ(cpackagerefp->name()));
|
||||
}
|
||||
UASSERT_OBJ(packagep, m_ds.m_dotp->lhsp(), "Bad package link");
|
||||
m_ds.m_dotSymp = m_statep->getNodeSym(packagep);
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
|
|
@ -2399,11 +2402,19 @@ private:
|
|||
if (nodep->user3SetOnce()) return;
|
||||
UINFO(8, " " << nodep << endl);
|
||||
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
|
||||
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), PackageRef), m_ds.m_dotp->lhsp(),
|
||||
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(),
|
||||
"Bad package link");
|
||||
UASSERT_OBJ(VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep(), m_ds.m_dotp->lhsp(),
|
||||
"Bad package link");
|
||||
nodep->packagep(VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep());
|
||||
AstClassOrPackageRef* cpackagerefp = VN_CAST(m_ds.m_dotp->lhsp(), ClassOrPackageRef);
|
||||
if (cpackagerefp->name() == "process" || cpackagerefp->name() == "local") {
|
||||
nodep->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported: " << AstNode::prettyNameQ(cpackagerefp->name()));
|
||||
}
|
||||
if (cpackagerefp->paramsp()) {
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: parameterized packages");
|
||||
}
|
||||
UASSERT_OBJ(VN_CAST(m_ds.m_dotp->lhsp(), ClassOrPackageRef)->packagep(),
|
||||
m_ds.m_dotp->lhsp(), "Bad package link");
|
||||
nodep->packagep(VN_CAST(m_ds.m_dotp->lhsp(), ClassOrPackageRef)->packagep());
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
m_ds.m_dotp = NULL;
|
||||
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_FINAL) {
|
||||
|
|
@ -2667,12 +2678,30 @@ private:
|
|||
virtual void visit(AstRefDType* nodep) VL_OVERRIDE {
|
||||
// Resolve its reference
|
||||
if (nodep->user3SetOnce()) return;
|
||||
if (AstNode* cpackagep = nodep->classOrPackagep()) {
|
||||
if (AstClassOrPackageRef* cpackagerefp = VN_CAST(cpackagep, ClassOrPackageRef)) {
|
||||
if (cpackagerefp->packagep()) {
|
||||
nodep->packagep(cpackagerefp->packagep());
|
||||
} else {
|
||||
cpackagep->v3warn(E_UNSUPPORTED, "Unsupported: Class '::' reference");
|
||||
// if (cpackagerefp->paramsp()) {
|
||||
// nodep->v3warn(E_UNSUPPORTED, "Unsupported: parameterized packages");
|
||||
// }
|
||||
}
|
||||
} else {
|
||||
cpackagep->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported: Multiple '::' package/class reference");
|
||||
}
|
||||
VL_DO_DANGLING(cpackagep->unlinkFrBack()->deleteTree(), cpackagep);
|
||||
} else if (nodep->paramsp()) {
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: parameterized packages");
|
||||
}
|
||||
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
|
||||
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), PackageRef), m_ds.m_dotp->lhsp(),
|
||||
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(),
|
||||
"Bad package link");
|
||||
UASSERT_OBJ(VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep(), m_ds.m_dotp->lhsp(),
|
||||
"Bad package link");
|
||||
nodep->packagep(VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep());
|
||||
UASSERT_OBJ(VN_CAST(m_ds.m_dotp->lhsp(), ClassOrPackageRef)->packagep(),
|
||||
m_ds.m_dotp->lhsp(), "Bad package link");
|
||||
nodep->packagep(VN_CAST(m_ds.m_dotp->lhsp(), ClassOrPackageRef)->packagep());
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
m_ds.m_dotp = NULL;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -2232,13 +2232,24 @@ V3Number& V3Number::opSelInto(const V3Number& lhs, int lsbval, int width) {
|
|||
//======================================================================
|
||||
// Ops - Floating point
|
||||
|
||||
V3Number& V3Number::opIToRD(const V3Number& lhs) {
|
||||
V3Number& V3Number::opIToRD(const V3Number& lhs, bool isSigned) {
|
||||
NUM_ASSERT_OP_ARGS1(lhs);
|
||||
NUM_ASSERT_LOGIC_ARGS1(lhs);
|
||||
// IEEE says we ignore x/z in real conversions
|
||||
V3Number noxz(lhs);
|
||||
noxz.opAssignNonXZ(lhs);
|
||||
return setDouble(noxz.toSInt());
|
||||
double d = 0;
|
||||
bool negate = isSigned && noxz.isNegative();
|
||||
if (negate) {
|
||||
V3Number noxz_signed = noxz;
|
||||
noxz.opNegate(noxz_signed);
|
||||
}
|
||||
for (int bit = noxz.width() - 1; bit >= 0; bit--) {
|
||||
// Some precision might be lost in this add, that's what we want
|
||||
if (noxz.bitIs1(bit)) d += exp2(bit);
|
||||
}
|
||||
if (negate) d = -d;
|
||||
return setDouble(d);
|
||||
}
|
||||
V3Number& V3Number::opRToIS(const V3Number& lhs) {
|
||||
NUM_ASSERT_OP_ARGS1(lhs);
|
||||
|
|
|
|||
|
|
@ -385,7 +385,8 @@ public:
|
|||
V3Number& opLteS(const V3Number& lhs, const V3Number& rhs); // Signed
|
||||
|
||||
// "D" - double (aka real) math
|
||||
V3Number& opIToRD(const V3Number& lhs);
|
||||
V3Number& opIToRD(const V3Number& lhs, bool isSigned = false);
|
||||
V3Number& opISToRD(const V3Number& lhs) { return opIToRD(lhs, true); }
|
||||
V3Number& opRToIS(const V3Number& lhs);
|
||||
V3Number& opRToIRoundS(const V3Number& lhs);
|
||||
V3Number& opRealToBits(const V3Number& lhs);
|
||||
|
|
|
|||
|
|
@ -106,6 +106,8 @@ private:
|
|||
typedef std::deque<AstCell*> CellList;
|
||||
CellList m_cellps; // Cells left to process (in this module)
|
||||
|
||||
AstNodeFTask* m_ftaskp; // Function/task reference
|
||||
|
||||
AstNodeModule* m_modp; // Current module being processed
|
||||
|
||||
string m_unlinkedTxt; // Text for AstUnlinkedRef
|
||||
|
|
@ -302,6 +304,11 @@ private:
|
|||
nodep->user5p(genHierNamep);
|
||||
m_cellps.push_back(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep) VL_OVERRIDE {
|
||||
m_ftaskp = nodep;
|
||||
iterateChildren(nodep);
|
||||
m_ftaskp = NULL;
|
||||
}
|
||||
|
||||
// Make sure all parameters are constantified
|
||||
virtual void visit(AstVar* nodep) VL_OVERRIDE {
|
||||
|
|
@ -323,6 +330,16 @@ private:
|
|||
new AstAssign(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), nodep, true),
|
||||
nodep->valuep()->cloneTree(true))));
|
||||
if (m_ftaskp) {
|
||||
// We put the initial in wrong place under a function. We
|
||||
// should move the parameter out of the function and to the
|
||||
// module, with appropriate dotting, but this confuses LinkDot
|
||||
// (as then name isn't found later), so punt - probably can
|
||||
// treat as static function variable when that is supported.
|
||||
nodep->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
"Unsupported: Parameters in functions with complex assign");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -556,6 +573,7 @@ public:
|
|||
// CONSTRUCTORS
|
||||
explicit ParamVisitor(AstNetlist* nodep) {
|
||||
m_longId = 0;
|
||||
m_ftaskp = NULL;
|
||||
m_modp = NULL;
|
||||
m_nextValue = 1;
|
||||
//
|
||||
|
|
@ -617,7 +635,7 @@ void ParamVisitor::visitCell(AstCell* nodep, const string& hierName) {
|
|||
// This prevents making additional modules, and makes coverage more
|
||||
// obvious as it won't show up under a unique module page name.
|
||||
} else if (exprp->num().isDouble() || exprp->num().isString()
|
||||
|| exprp->num().isFourState()) {
|
||||
|| exprp->num().isFourState() || exprp->num().width() != 32) {
|
||||
longname
|
||||
+= ("_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp));
|
||||
any_overrides = true;
|
||||
|
|
|
|||
|
|
@ -139,7 +139,6 @@ struct V3ParseBisonYYSType {
|
|||
AstSenItem* senitemp;
|
||||
AstNodeVarRef* varnodep;
|
||||
AstPackage* packagep;
|
||||
AstPackageRef* packagerefp;
|
||||
AstParseRef* parserefp;
|
||||
AstPatMember* patmemberp;
|
||||
AstPattern* patternp;
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ private:
|
|||
string m_libName;
|
||||
string m_topName;
|
||||
bool m_foundTop; // Have seen the top module
|
||||
bool m_hasClk; // True if the top module has sequential logic
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep) VL_OVERRIDE {
|
||||
|
|
@ -79,6 +80,8 @@ private:
|
|||
UASSERT_OBJ(!m_foundTop, nodep, "Multiple root modules");
|
||||
}
|
||||
FileLine* fl = nodep->fileline();
|
||||
// Need to know the existence of clk before createSvFile()
|
||||
m_hasClk = checkIfClockExists(nodep);
|
||||
createSvFile(fl);
|
||||
createCppFile(fl);
|
||||
|
||||
|
|
@ -162,14 +165,16 @@ private:
|
|||
txtp->addNodep(m_comboPortsp);
|
||||
txtp->addText(fl, ");\n\n");
|
||||
seqComment(txtp, fl);
|
||||
m_seqPortsp = new AstTextBlock(fl,
|
||||
"import \"DPI-C\" function longint " + m_libName
|
||||
+ "_protectlib_seq_update"
|
||||
"(\n",
|
||||
false, true);
|
||||
m_seqPortsp->addText(fl, "chandle handle__V\n");
|
||||
txtp->addNodep(m_seqPortsp);
|
||||
txtp->addText(fl, ");\n\n");
|
||||
if (m_hasClk) {
|
||||
m_seqPortsp = new AstTextBlock(fl,
|
||||
"import \"DPI-C\" function longint " + m_libName
|
||||
+ "_protectlib_seq_update"
|
||||
"(\n",
|
||||
false, true);
|
||||
m_seqPortsp->addText(fl, "chandle handle__V\n");
|
||||
txtp->addNodep(m_seqPortsp);
|
||||
txtp->addText(fl, ");\n\n");
|
||||
}
|
||||
comboIgnoreComment(txtp, fl);
|
||||
m_comboIgnorePortsp = new AstTextBlock(fl,
|
||||
"import \"DPI-C\" function void " + m_libName
|
||||
|
|
@ -192,12 +197,12 @@ private:
|
|||
m_tmpDeclsp = new AstTextBlock(fl);
|
||||
txtp->addNodep(m_tmpDeclsp);
|
||||
txtp->addText(fl, "\ntime last_combo_seqnum__V;\n");
|
||||
txtp->addText(fl, "time last_seq_seqnum__V;\n\n");
|
||||
if (m_hasClk) { txtp->addText(fl, "time last_seq_seqnum__V;\n\n"); }
|
||||
|
||||
// CPP hash value
|
||||
addComment(txtp, fl, "Hash value to make sure this file and the corresponding");
|
||||
addComment(txtp, fl, "library agree");
|
||||
m_hashValuep = new AstTextBlock(fl, "localparam int protectlib_hash__V = ");
|
||||
m_hashValuep = new AstTextBlock(fl, "localparam int protectlib_hash__V = 32'd");
|
||||
txtp->addNodep(m_hashValuep);
|
||||
txtp->addText(fl, "\n");
|
||||
|
||||
|
|
@ -222,33 +227,41 @@ private:
|
|||
txtp->addText(fl, "end\n\n");
|
||||
|
||||
// Sequential process
|
||||
addComment(txtp, fl, "Evaluate clock edges");
|
||||
m_clkSensp = new AstTextBlock(fl, "always @(", false, true);
|
||||
txtp->addNodep(m_clkSensp);
|
||||
txtp->addText(fl, ") begin\n");
|
||||
m_comboIgnoreParamsp
|
||||
= new AstTextBlock(fl, m_libName + "_protectlib_combo_ignore(\n", false, true);
|
||||
m_comboIgnoreParamsp->addText(fl, "handle__V\n");
|
||||
txtp->addNodep(m_comboIgnoreParamsp);
|
||||
txtp->addText(fl, ");\n");
|
||||
m_seqParamsp = new AstTextBlock(
|
||||
fl, "last_seq_seqnum__V <= " + m_libName + "_protectlib_seq_update(\n", false, true);
|
||||
m_seqParamsp->addText(fl, "handle__V\n");
|
||||
txtp->addNodep(m_seqParamsp);
|
||||
txtp->addText(fl, ");\n");
|
||||
m_nbAssignsp = new AstTextBlock(fl);
|
||||
txtp->addNodep(m_nbAssignsp);
|
||||
txtp->addText(fl, "end\n\n");
|
||||
if (m_hasClk) {
|
||||
addComment(txtp, fl, "Evaluate clock edges");
|
||||
m_clkSensp = new AstTextBlock(fl, "always @(", false, true);
|
||||
txtp->addNodep(m_clkSensp);
|
||||
txtp->addText(fl, ") begin\n");
|
||||
m_comboIgnoreParamsp
|
||||
= new AstTextBlock(fl, m_libName + "_protectlib_combo_ignore(\n", false, true);
|
||||
m_comboIgnoreParamsp->addText(fl, "handle__V\n");
|
||||
txtp->addNodep(m_comboIgnoreParamsp);
|
||||
txtp->addText(fl, ");\n");
|
||||
m_seqParamsp = new AstTextBlock(
|
||||
fl, "last_seq_seqnum__V <= " + m_libName + "_protectlib_seq_update(\n", false,
|
||||
true);
|
||||
m_seqParamsp->addText(fl, "handle__V\n");
|
||||
txtp->addNodep(m_seqParamsp);
|
||||
txtp->addText(fl, ");\n");
|
||||
m_nbAssignsp = new AstTextBlock(fl);
|
||||
txtp->addNodep(m_nbAssignsp);
|
||||
txtp->addText(fl, "end\n\n");
|
||||
}
|
||||
|
||||
// Select between combinatorial and sequential results
|
||||
addComment(txtp, fl, "Select between combinatorial and sequential results");
|
||||
txtp->addText(fl, "always @(*) begin\n");
|
||||
m_seqAssignsp = new AstTextBlock(fl, "if (last_seq_seqnum__V > "
|
||||
"last_combo_seqnum__V) begin\n");
|
||||
txtp->addNodep(m_seqAssignsp);
|
||||
m_comboAssignsp = new AstTextBlock(fl, "end else begin\n");
|
||||
txtp->addNodep(m_comboAssignsp);
|
||||
txtp->addText(fl, "end\n");
|
||||
if (m_hasClk) {
|
||||
m_seqAssignsp = new AstTextBlock(fl, "if (last_seq_seqnum__V > "
|
||||
"last_combo_seqnum__V) begin\n");
|
||||
txtp->addNodep(m_seqAssignsp);
|
||||
m_comboAssignsp = new AstTextBlock(fl, "end else begin\n");
|
||||
txtp->addNodep(m_comboAssignsp);
|
||||
txtp->addText(fl, "end\n");
|
||||
} else {
|
||||
m_comboAssignsp = new AstTextBlock(fl, "");
|
||||
txtp->addNodep(m_comboAssignsp);
|
||||
}
|
||||
txtp->addText(fl, "end\n\n");
|
||||
|
||||
// Final
|
||||
|
|
@ -327,19 +340,21 @@ private:
|
|||
txtp->addText(fl, "return handlep__V->m_seqnum++;\n");
|
||||
txtp->addText(fl, "}\n\n");
|
||||
|
||||
seqComment(txtp, fl);
|
||||
m_cSeqParamsp = new AstTextBlock(
|
||||
fl, "long long " + m_libName + "_protectlib_seq_update(\n", false, true);
|
||||
m_cSeqParamsp->addText(fl, "void* vhandlep__V\n");
|
||||
txtp->addNodep(m_cSeqParamsp);
|
||||
txtp->addText(fl, ")\n");
|
||||
m_cSeqClksp = new AstTextBlock(fl, "{\n");
|
||||
castPtr(fl, m_cSeqClksp);
|
||||
txtp->addNodep(m_cSeqClksp);
|
||||
m_cSeqOutsp = new AstTextBlock(fl, "handlep__V->eval();\n");
|
||||
txtp->addNodep(m_cSeqOutsp);
|
||||
txtp->addText(fl, "return handlep__V->m_seqnum++;\n");
|
||||
txtp->addText(fl, "}\n\n");
|
||||
if (m_hasClk) {
|
||||
seqComment(txtp, fl);
|
||||
m_cSeqParamsp = new AstTextBlock(
|
||||
fl, "long long " + m_libName + "_protectlib_seq_update(\n", false, true);
|
||||
m_cSeqParamsp->addText(fl, "void* vhandlep__V\n");
|
||||
txtp->addNodep(m_cSeqParamsp);
|
||||
txtp->addText(fl, ")\n");
|
||||
m_cSeqClksp = new AstTextBlock(fl, "{\n");
|
||||
castPtr(fl, m_cSeqClksp);
|
||||
txtp->addNodep(m_cSeqClksp);
|
||||
m_cSeqOutsp = new AstTextBlock(fl, "handlep__V->eval();\n");
|
||||
txtp->addNodep(m_cSeqOutsp);
|
||||
txtp->addText(fl, "return handlep__V->m_seqnum++;\n");
|
||||
txtp->addText(fl, "}\n\n");
|
||||
}
|
||||
|
||||
comboIgnoreComment(txtp, fl);
|
||||
m_cIgnoreParamsp = new AstTextBlock(
|
||||
|
|
@ -369,6 +384,7 @@ private:
|
|||
}
|
||||
if (nodep->direction() == VDirection::INPUT) {
|
||||
if (nodep->isUsedClock() || nodep->attrClocker() == VVarAttrClocker::CLOCKER_YES) {
|
||||
UASSERT_OBJ(m_hasClk, nodep, "checkIfClockExists() didn't find this clock");
|
||||
handleClock(nodep);
|
||||
} else {
|
||||
handleDataInput(nodep);
|
||||
|
|
@ -396,8 +412,10 @@ private:
|
|||
FileLine* fl = varp->fileline();
|
||||
handleInput(varp);
|
||||
m_seqPortsp->addNodep(varp->cloneTree(false));
|
||||
m_seqParamsp->addText(fl, varp->name() + "\n");
|
||||
m_clkSensp->addText(fl, "edge(" + varp->name() + ")");
|
||||
if (m_hasClk) {
|
||||
m_seqParamsp->addText(fl, varp->name() + "\n");
|
||||
m_clkSensp->addText(fl, "posedge " + varp->name() + " or negedge " + varp->name());
|
||||
}
|
||||
m_cSeqParamsp->addText(fl, varp->dpiArgType(true, false) + "\n");
|
||||
m_cSeqClksp->addText(fl, cInputConnection(varp));
|
||||
}
|
||||
|
|
@ -408,7 +426,7 @@ private:
|
|||
m_comboPortsp->addNodep(varp->cloneTree(false));
|
||||
m_comboParamsp->addText(fl, varp->name() + "\n");
|
||||
m_comboIgnorePortsp->addNodep(varp->cloneTree(false));
|
||||
m_comboIgnoreParamsp->addText(fl, varp->name() + "\n");
|
||||
if (m_hasClk) { m_comboIgnoreParamsp->addText(fl, varp->name() + "\n"); }
|
||||
m_cComboParamsp->addText(fl, varp->dpiArgType(true, false) + "\n");
|
||||
m_cComboInsp->addText(fl, cInputConnection(varp));
|
||||
m_cIgnoreParamsp->addText(fl, varp->dpiArgType(true, false) + "\n");
|
||||
|
|
@ -421,29 +439,49 @@ private:
|
|||
m_modPortsp->addNodep(varp->cloneTree(false));
|
||||
m_comboPortsp->addNodep(varp->cloneTree(false));
|
||||
m_comboParamsp->addText(fl, varp->name() + "_combo__V\n");
|
||||
m_seqPortsp->addNodep(varp->cloneTree(false));
|
||||
m_seqParamsp->addText(fl, varp->name() + "_tmp__V\n");
|
||||
if (m_hasClk) {
|
||||
m_seqPortsp->addNodep(varp->cloneTree(false));
|
||||
m_seqParamsp->addText(fl, varp->name() + "_tmp__V\n");
|
||||
}
|
||||
|
||||
AstNodeDType* comboDtypep = varp->dtypep()->cloneTree(false);
|
||||
m_comboDeclsp->addNodep(comboDtypep);
|
||||
m_comboDeclsp->addText(fl, " " + varp->name() + "_combo__V;\n");
|
||||
|
||||
AstNodeDType* seqDtypep = varp->dtypep()->cloneTree(false);
|
||||
m_seqDeclsp->addNodep(seqDtypep);
|
||||
m_seqDeclsp->addText(fl, " " + varp->name() + "_seq__V;\n");
|
||||
if (m_hasClk) {
|
||||
AstNodeDType* seqDtypep = varp->dtypep()->cloneTree(false);
|
||||
m_seqDeclsp->addNodep(seqDtypep);
|
||||
m_seqDeclsp->addText(fl, " " + varp->name() + "_seq__V;\n");
|
||||
|
||||
AstNodeDType* tmpDtypep = varp->dtypep()->cloneTree(false);
|
||||
m_tmpDeclsp->addNodep(tmpDtypep);
|
||||
m_tmpDeclsp->addText(fl, " " + varp->name() + "_tmp__V;\n");
|
||||
AstNodeDType* tmpDtypep = varp->dtypep()->cloneTree(false);
|
||||
m_tmpDeclsp->addNodep(tmpDtypep);
|
||||
m_tmpDeclsp->addText(fl, " " + varp->name() + "_tmp__V;\n");
|
||||
|
||||
m_nbAssignsp->addText(fl, varp->name() + "_seq__V <= " + varp->name() + "_tmp__V;\n");
|
||||
m_seqAssignsp->addText(fl, varp->name() + " = " + varp->name() + "_seq__V;\n");
|
||||
m_nbAssignsp->addText(fl, varp->name() + "_seq__V <= " + varp->name() + "_tmp__V;\n");
|
||||
m_seqAssignsp->addText(fl, varp->name() + " = " + varp->name() + "_seq__V;\n");
|
||||
}
|
||||
m_comboAssignsp->addText(fl, varp->name() + " = " + varp->name() + "_combo__V;\n");
|
||||
m_cComboParamsp->addText(fl, varp->dpiArgType(true, false) + "\n");
|
||||
m_cComboOutsp->addText(fl,
|
||||
V3Task::assignInternalToDpi(varp, true, "", "", "handlep__V->"));
|
||||
m_cSeqParamsp->addText(fl, varp->dpiArgType(true, false) + "\n");
|
||||
m_cSeqOutsp->addText(fl, V3Task::assignInternalToDpi(varp, true, "", "", "handlep__V->"));
|
||||
if (m_hasClk) {
|
||||
m_cSeqParamsp->addText(fl, varp->dpiArgType(true, false) + "\n");
|
||||
m_cSeqOutsp->addText(fl,
|
||||
V3Task::assignInternalToDpi(varp, true, "", "", "handlep__V->"));
|
||||
}
|
||||
}
|
||||
|
||||
static bool checkIfClockExists(AstNodeModule* modp) {
|
||||
for (AstNode* stmtp = modp->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstVar* varp = VN_CAST(stmtp, Var)) {
|
||||
if (varp->direction() == VDirection::INPUT
|
||||
&& (varp->isUsedClock()
|
||||
|| varp->attrClocker() == VVarAttrClocker::CLOCKER_YES)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -475,7 +513,8 @@ public:
|
|||
, m_cIgnoreParamsp(NULL)
|
||||
, m_libName(v3Global.opt.protectLib())
|
||||
, m_topName(v3Global.opt.prefix())
|
||||
, m_foundTop(false) {
|
||||
, m_foundTop(false)
|
||||
, m_hasClk(false) {
|
||||
iterate(nodep);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -332,7 +332,6 @@ private:
|
|||
//========
|
||||
// Widths: Output real, input integer signed
|
||||
virtual void visit(AstBitsToRealD* nodep) VL_OVERRIDE { visit_Or_Lu64(nodep); }
|
||||
virtual void visit(AstIToRD* nodep) VL_OVERRIDE { visit_Or_Ls32(nodep); }
|
||||
|
||||
// Widths: Output integer signed, input real
|
||||
virtual void visit(AstRToIS* nodep) VL_OVERRIDE { visit_Os32_Lr(nodep); }
|
||||
|
|
@ -1032,6 +1031,12 @@ private:
|
|||
// We don't size the constant until we commit the widths, as need parameters
|
||||
// to remain unsized, and numbers to remain unsized to avoid backp() warnings
|
||||
}
|
||||
virtual void visit(AstFell* nodep) VL_OVERRIDE {
|
||||
if (m_vup->prelim()) {
|
||||
iterateCheckSizedSelf(nodep, "LHS", nodep->exprp(), SELF, BOTH);
|
||||
nodep->dtypeSetLogicBool();
|
||||
}
|
||||
}
|
||||
virtual void visit(AstPast* nodep) VL_OVERRIDE {
|
||||
if (m_vup->prelim()) {
|
||||
iterateCheckSizedSelf(nodep, "LHS", nodep->exprp(), SELF, BOTH);
|
||||
|
|
@ -1056,12 +1061,27 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstRose* nodep) VL_OVERRIDE {
|
||||
if (m_vup->prelim()) {
|
||||
iterateCheckSizedSelf(nodep, "LHS", nodep->exprp(), SELF, BOTH);
|
||||
nodep->dtypeSetLogicBool();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstSampled* nodep) VL_OVERRIDE {
|
||||
if (m_vup->prelim()) {
|
||||
iterateCheckSizedSelf(nodep, "LHS", nodep->exprp(), SELF, BOTH);
|
||||
nodep->dtypeFrom(nodep->exprp());
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstStable* nodep) VL_OVERRIDE {
|
||||
if (m_vup->prelim()) {
|
||||
iterateCheckSizedSelf(nodep, "LHS", nodep->exprp(), SELF, BOTH);
|
||||
nodep->dtypeSetLogicBool();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstRand* nodep) VL_OVERRIDE {
|
||||
if (m_vup->prelim()) {
|
||||
nodep->dtypeSetSigned32(); // Says the spec
|
||||
|
|
@ -1524,7 +1544,8 @@ private:
|
|||
virtual void visit(AstCast* nodep) VL_OVERRIDE {
|
||||
nodep->dtypep(iterateEditMoveDTypep(nodep, nodep->subDTypep()));
|
||||
// if (debug()) nodep->dumpTree(cout, " CastPre: ");
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP(SELF, BOTH).p());
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP(SELF, PRELIM).p());
|
||||
|
||||
// When more general casts are supported, the cast elimination will be done later.
|
||||
// For now, replace it ASAP, so widthing can propagate easily
|
||||
// The cast may change signing, but we don't know the sign yet. Make it so.
|
||||
|
|
@ -1537,11 +1558,19 @@ private:
|
|||
// Note widthCheckSized might modify nodep->lhsp()
|
||||
AstNodeDType* subDTypep = nodep->findLogicDType(nodep->width(), nodep->width(),
|
||||
nodep->lhsp()->dtypep()->numeric());
|
||||
widthCheckSized(nodep, "Cast", nodep->lhsp(), subDTypep, EXTEND_EXP, false);
|
||||
iterateCheck(nodep, "value", nodep->lhsp(), CONTEXT, FINAL, subDTypep, EXTEND_EXP,
|
||||
false);
|
||||
} else {
|
||||
iterateCheck(nodep, "value", nodep->lhsp(), SELF, FINAL, nodep->lhsp()->dtypep(),
|
||||
EXTEND_EXP, false);
|
||||
}
|
||||
AstNode* newp = nodep->lhsp()->unlinkFrBack();
|
||||
if (basicp->isDouble() && !newp->isDouble()) {
|
||||
newp = new AstIToRD(nodep->fileline(), newp);
|
||||
if (newp->isSigned()) {
|
||||
newp = new AstISToRD(nodep->fileline(), newp);
|
||||
} else {
|
||||
newp = new AstIToRD(nodep->fileline(), newp);
|
||||
}
|
||||
} else if (!basicp->isDouble() && newp->isDouble()) {
|
||||
if (basicp->isSigned()) {
|
||||
newp = new AstRToIRoundS(nodep->fileline(), newp);
|
||||
|
|
@ -3923,16 +3952,27 @@ private:
|
|||
iterateCheck(nodep, "LHS", nodep->lhsp(), SELF, FINAL, subDTypep, EXTEND_EXP);
|
||||
}
|
||||
}
|
||||
void visit_Or_Ls32(AstNodeUniop* nodep) {
|
||||
// CALLER: AstIToRD
|
||||
virtual void visit(AstIToRD* nodep) VL_OVERRIDE {
|
||||
// Real: Output real
|
||||
// LHS presumed self-determined, then coerced to real
|
||||
if (m_vup->prelim()) { // First stage evaluation
|
||||
nodep->dtypeSetDouble();
|
||||
AstNodeDType* subDTypep = nodep->findLogicDType(32, 32, VSigning::SIGNED);
|
||||
// Self-determined operand
|
||||
// Self-determined operand (TODO check if numeric type)
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP(SELF, PRELIM).p());
|
||||
if (nodep->lhsp()->isSigned()) {
|
||||
nodep->replaceWith(
|
||||
new AstISToRD(nodep->fileline(), nodep->lhsp()->unlinkFrBack()));
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstISToRD* nodep) VL_OVERRIDE {
|
||||
// Real: Output real
|
||||
// LHS presumed self-determined, then coerced to real
|
||||
if (m_vup->prelim()) { // First stage evaluation
|
||||
nodep->dtypeSetDouble();
|
||||
// Self-determined operand (TODO check if numeric type)
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP(SELF, PRELIM).p());
|
||||
iterateCheck(nodep, "LHS", nodep->lhsp(), SELF, FINAL, subDTypep, EXTEND_EXP);
|
||||
}
|
||||
}
|
||||
void visit_Os32_Lr(AstNodeUniop* nodep) {
|
||||
|
|
@ -4792,7 +4832,12 @@ private:
|
|||
UINFO(6, " spliceCvtD: " << nodep << endl);
|
||||
AstNRelinker linker;
|
||||
nodep->unlinkFrBack(&linker);
|
||||
AstNode* newp = new AstIToRD(nodep->fileline(), nodep);
|
||||
AstNode* newp;
|
||||
if (nodep->dtypep()->skipRefp()->isSigned()) {
|
||||
newp = new AstISToRD(nodep->fileline(), nodep);
|
||||
} else {
|
||||
newp = new AstIToRD(nodep->fileline(), nodep);
|
||||
}
|
||||
linker.relink(newp);
|
||||
return newp;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -193,12 +193,16 @@ static void process() {
|
|||
// Expand inouts, stage 2
|
||||
// Also simplify pin connections to always be AssignWs in prep for V3Unknown
|
||||
V3Tristate::tristateAll(v3Global.rootp());
|
||||
}
|
||||
|
||||
if (!v3Global.opt.xmlOnly()) {
|
||||
// Move assignments from X into MODULE temps.
|
||||
// (Before flattening, so each new X variable is shared between all scopes of that module.)
|
||||
V3Unknown::unknownAll(v3Global.rootp());
|
||||
v3Global.constRemoveXs(true);
|
||||
}
|
||||
|
||||
if (!(v3Global.opt.xmlOnly() && !v3Global.opt.flatten())) {
|
||||
// Module inlining
|
||||
// Cannot remove dead variables after this, as alias information for final
|
||||
// V3Scope's V3LinkDot is in the AstVar.
|
||||
|
|
|
|||
|
|
@ -422,6 +422,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
|||
"$dimensions" { FL; return yD_DIMENSIONS; }
|
||||
"$error" { FL; return yD_ERROR; }
|
||||
"$fatal" { FL; return yD_FATAL; }
|
||||
"$fell" { FL; return yD_FELL; }
|
||||
"$high" { FL; return yD_HIGH; }
|
||||
"$increment" { FL; return yD_INCREMENT; }
|
||||
"$info" { FL; return yD_INFO; }
|
||||
|
|
@ -434,7 +435,9 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
|||
"$past" { FL; return yD_PAST; }
|
||||
"$right" { FL; return yD_RIGHT; }
|
||||
"$root" { FL; return yD_ROOT; }
|
||||
"$rose" { FL; return yD_ROSE; }
|
||||
"$size" { FL; return yD_SIZE; }
|
||||
"$stable" { FL; return yD_STABLE; }
|
||||
"$unpacked_dimensions" { FL; return yD_UNPACKED_DIMENSIONS; }
|
||||
"$warning" { FL; return yD_WARNING; }
|
||||
/* SV2005 Keywords */
|
||||
|
|
|
|||
|
|
@ -264,17 +264,6 @@ int V3ParseGrammar::s_modTypeImpNum = 0;
|
|||
GRAMMARP->m_instParamp = paramsp; \
|
||||
}
|
||||
|
||||
static AstPackage* CAST_PACKAGE_CLASS(AstNode* nodep) {
|
||||
if (!nodep) {
|
||||
return NULL;
|
||||
} else if (AstPackage* pkgp = VN_CAST(nodep, Package)) {
|
||||
return pkgp;
|
||||
} else {
|
||||
BBUNSUP(nodep->fileline(), "Unsupported class :: reference");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define DEL(nodep) \
|
||||
{ \
|
||||
if (nodep) nodep->deleteTree(); \
|
||||
|
|
@ -730,6 +719,7 @@ BISONPRE_VERSION(3.0,%define parse.error verbose)
|
|||
%token<fl> yD_FDISPLAYB "$fdisplayb"
|
||||
%token<fl> yD_FDISPLAYH "$fdisplayh"
|
||||
%token<fl> yD_FDISPLAYO "$fdisplayo"
|
||||
%token<fl> yD_FELL "$fell"
|
||||
%token<fl> yD_FEOF "$feof"
|
||||
%token<fl> yD_FERROR "$ferror"
|
||||
%token<fl> yD_FFLUSH "$fflush"
|
||||
|
|
@ -771,6 +761,7 @@ BISONPRE_VERSION(3.0,%define parse.error verbose)
|
|||
%token<fl> yD_REWIND "$rewind"
|
||||
%token<fl> yD_RIGHT "$right"
|
||||
%token<fl> yD_ROOT "$root"
|
||||
%token<fl> yD_ROSE "$rose"
|
||||
%token<fl> yD_RTOI "$rtoi"
|
||||
%token<fl> yD_SAMPLED "$sampled"
|
||||
%token<fl> yD_SFORMAT "$sformat"
|
||||
|
|
@ -782,6 +773,7 @@ BISONPRE_VERSION(3.0,%define parse.error verbose)
|
|||
%token<fl> yD_SIZE "$size"
|
||||
%token<fl> yD_SQRT "$sqrt"
|
||||
%token<fl> yD_SSCANF "$sscanf"
|
||||
%token<fl> yD_STABLE "$stable"
|
||||
%token<fl> yD_STIME "$stime"
|
||||
%token<fl> yD_STOP "$stop"
|
||||
%token<fl> yD_SWRITE "$swrite"
|
||||
|
|
@ -1476,7 +1468,7 @@ program_declaration: // IEEE: program_declaration + program_nonansi_header + pr
|
|||
|
||||
pgmFront<modulep>:
|
||||
yPROGRAM lifetimeE idAny/*new_program*/
|
||||
{ $$ = new AstModule($<fl>3,*$3);
|
||||
{ $$ = new AstModule($<fl>3, *$3, true);
|
||||
$$->lifetime($2);
|
||||
$$->inLibrary(PARSEP->inLibrary() || $$->fileline()->celldefineOn());
|
||||
$$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
|
||||
|
|
@ -1783,8 +1775,8 @@ simple_type<dtypep>: // ==IEEE: simple_type
|
|||
// // Even though we looked up the type and have a AstNode* to it,
|
||||
// // we can't fully resolve it because it may have been just a forward definition.
|
||||
| packageClassScopeE idType
|
||||
{ AstRefDType* refp = new AstRefDType($<fl>2, *$2);
|
||||
refp->packagep($1); $$ = refp; }
|
||||
{ AstRefDType* refp = new AstRefDType($<fl>2, *$2, $1, NULL);
|
||||
$$ = refp; }
|
||||
//
|
||||
// // { generate_block_identifer ... } '.'
|
||||
// // Need to determine if generate_block_identifier can be lex-detected
|
||||
|
|
@ -1801,13 +1793,10 @@ data_type<dtypep>: // ==IEEE: data_type
|
|||
// // IEEE: ps_covergroup_identifier
|
||||
// // Don't distinguish between types and classes so all these combined
|
||||
| packageClassScopeE idType packed_dimensionListE
|
||||
{ AstRefDType* refp = new AstRefDType($<fl>2, *$2);
|
||||
refp->packagep($1);
|
||||
{ AstRefDType* refp = new AstRefDType($<fl>2, *$2, $1, NULL);
|
||||
$$ = GRAMMARP->createArray(refp, $3, true); }
|
||||
| packageClassScopeE idType parameter_value_assignmentClass packed_dimensionListE
|
||||
{ AstRefDType* refp = new AstRefDType($<fl>2, *$2);
|
||||
refp->packagep($1);
|
||||
BBUNSUP($3->fileline(), "Unsupported: Parameter classes");
|
||||
{ AstRefDType* refp = new AstRefDType($<fl>2, *$2, $1, $3);
|
||||
$$ = GRAMMARP->createArray(refp, $4, true); }
|
||||
;
|
||||
|
||||
|
|
@ -1851,7 +1840,8 @@ var_data_type<dtypep>: // ==IEEE: var_data_type
|
|||
;
|
||||
|
||||
type_reference<dtypep>: // ==IEEE: type_reference
|
||||
yTYPE '(' exprOrDataType ')' { $$ = new AstRefDType($1, AstRefDType::FlagTypeOfExpr(), $3); }
|
||||
yTYPE '(' exprOrDataType ')'
|
||||
{ $$ = new AstRefDType($1, AstRefDType::FlagTypeOfExpr(), $3); }
|
||||
;
|
||||
|
||||
struct_unionDecl<uorstructp>: // IEEE: part of data_type
|
||||
|
|
@ -2021,8 +2011,7 @@ enum_base_typeE<dtypep>: // IEEE: enum_base_type
|
|||
| idAny rangeListE
|
||||
{ $$ = GRAMMARP->createArray(new AstRefDType($<fl>1, *$1), $2, true); }
|
||||
| packageClassScope idAny rangeListE
|
||||
{ AstRefDType* refp = new AstRefDType($<fl>2, *$2);
|
||||
refp->packagep($1);
|
||||
{ AstRefDType* refp = new AstRefDType($<fl>2, *$2, $1, NULL);
|
||||
$$ = GRAMMARP->createArray(refp, $3, true); }
|
||||
;
|
||||
|
||||
|
|
@ -2526,7 +2515,7 @@ delay_control<nodep>: //== IEEE: delay_control
|
|||
|
||||
delay_value<nodep>: // ==IEEE:delay_value
|
||||
// // IEEE: ps_identifier
|
||||
packageClassScopeE varRefBase { $$ = $2; $2->packagep($1); }
|
||||
packageClassScopeE varRefBase { $$ = AstDot::newIfPkg($<fl>2, $1, $2); }
|
||||
| yaINTNUM { $$ = new AstConst($<fl>1, *$1); }
|
||||
| yaFLOATNUM { $$ = new AstConst($<fl>1, AstConst::RealDouble(), $1); }
|
||||
| timeNumAdjusted { $$ = $1; }
|
||||
|
|
@ -3412,7 +3401,7 @@ taskRef<nodep>: // IEEE: part of tf_call
|
|||
id { $$ = new AstTaskRef($<fl>1,*$1,NULL); }
|
||||
| id '(' list_of_argumentsE ')' { $$ = new AstTaskRef($<fl>1,*$1,$3); }
|
||||
| packageClassScope id '(' list_of_argumentsE ')'
|
||||
{ $$ = AstDot::newIfPkg($<fl>2, CAST_PACKAGE_CLASS($1), new AstTaskRef($<fl>2, *$2, $4)); }
|
||||
{ $$ = AstDot::newIfPkg($<fl>2, $1, new AstTaskRef($<fl>2, *$2, $4)); }
|
||||
;
|
||||
|
||||
funcRef<nodep>: // IEEE: part of tf_call
|
||||
|
|
@ -3428,7 +3417,7 @@ funcRef<nodep>: // IEEE: part of tf_call
|
|||
id '(' list_of_argumentsE ')'
|
||||
{ $$ = new AstFuncRef($<fl>1, *$1, $3); }
|
||||
| packageClassScope id '(' list_of_argumentsE ')'
|
||||
{ $$ = AstDot::newIfPkg($<fl>2, CAST_PACKAGE_CLASS($1), new AstFuncRef($<fl>2, *$2, $4)); }
|
||||
{ $$ = AstDot::newIfPkg($<fl>2, $1, new AstFuncRef($<fl>2, *$2, $4)); }
|
||||
//UNSUP list_of_argumentE should be pev_list_of_argumentE
|
||||
//UNSUP: idDotted is really just id to allow dotted method calls
|
||||
;
|
||||
|
|
@ -3609,6 +3598,8 @@ system_f_call_or_t<nodep>: // IEEE: part of system_tf_call (can be task or func)
|
|||
| yD_COUNTONES '(' expr ')' { $$ = new AstCountOnes($1,$3); }
|
||||
| yD_DIMENSIONS '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_DIMENSIONS,$3); }
|
||||
| yD_EXP '(' expr ')' { $$ = new AstExpD($1,$3); }
|
||||
| yD_FELL '(' expr ')' { $$ = new AstFell($1,$3); }
|
||||
| yD_FELL '(' expr ',' expr ')' { $$ = $3; BBUNSUP($1, "Unsupported: $fell and clock arguments"); }
|
||||
| yD_FEOF '(' expr ')' { $$ = new AstFEof($1,$3); }
|
||||
| yD_FERROR '(' idClassSel ',' idClassSel ')' { $$ = new AstFError($1, $3, $5); }
|
||||
| yD_FGETC '(' expr ')' { $$ = new AstFGetC($1,$3); }
|
||||
|
|
@ -3650,6 +3641,8 @@ system_f_call_or_t<nodep>: // IEEE: part of system_tf_call (can be task or func)
|
|||
| yD_REWIND '(' idClassSel ')' { $$ = new AstFSeek($1, $3, new AstConst($1, 0), new AstConst($1, 0)); }
|
||||
| yD_RIGHT '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_RIGHT,$3,NULL); }
|
||||
| yD_RIGHT '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_RIGHT,$3,$5); }
|
||||
| yD_ROSE '(' expr ')' { $$ = new AstRose($1,$3); }
|
||||
| yD_ROSE '(' expr ',' expr ')' { $$ = $3; BBUNSUP($1, "Unsupported: $rose and clock arguments"); }
|
||||
| yD_RTOI '(' expr ')' { $$ = new AstRToIS($1,$3); }
|
||||
| yD_SAMPLED '(' expr ')' { $$ = new AstSampled($1, $3); }
|
||||
| yD_SFORMATF '(' exprDispList ')' { $$ = new AstSFormatF($1, AstSFormatF::NoFormat(), $3, 'd', false); }
|
||||
|
|
@ -3662,6 +3655,8 @@ system_f_call_or_t<nodep>: // IEEE: part of system_tf_call (can be task or func)
|
|||
| yD_SQRT '(' expr ')' { $$ = new AstSqrtD($1,$3); }
|
||||
| yD_SSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstSScanF($1,*$5,$3,$6); }
|
||||
| yD_STIME parenE { $$ = new AstSel($1, new AstTime($1, VTimescale(VTimescale::NONE)), 0, 32); }
|
||||
| yD_STABLE '(' expr ')' { $$ = new AstStable($1,$3); }
|
||||
| yD_STABLE '(' expr ',' expr ')' { $$ = $3; BBUNSUP($1, "Unsupported: $stable and clock arguments"); }
|
||||
| yD_TAN '(' expr ')' { $$ = new AstTanD($1,$3); }
|
||||
| yD_TANH '(' expr ')' { $$ = new AstTanhD($1,$3); }
|
||||
| yD_TESTPLUSARGS '(' str ')' { $$ = new AstTestPlusArgs($1,*$3); }
|
||||
|
|
@ -4263,7 +4258,7 @@ exprScope<nodep>: // scope and variable for use to inside an expression
|
|||
yTHIS { $$ = new AstParseRef($<fl>1, VParseRefExp::PX_ROOT, "this"); }
|
||||
| yD_ROOT { $$ = new AstParseRef($<fl>1, VParseRefExp::PX_ROOT, "$root"); }
|
||||
| idArrayed { $$ = $1; }
|
||||
| packageClassScope idArrayed { $$ = AstDot::newIfPkg($2->fileline(), CAST_PACKAGE_CLASS($1), $2); }
|
||||
| packageClassScope idArrayed { $$ = AstDot::newIfPkg($2->fileline(), $1, $2); }
|
||||
| ~l~expr '.' idArrayed { $$ = new AstDot($<fl>2, false, $1, $3); }
|
||||
// // expr below must be a "yTHIS"
|
||||
| ~l~expr '.' ySUPER { $$ = $1; BBUNSUP($3, "Unsupported: super"); }
|
||||
|
|
@ -4742,7 +4737,7 @@ idClassSel<nodep>: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged va
|
|||
{ $$ = new AstDot($2, false, new AstParseRef($<fl>1, VParseRefExp::PX_ROOT, "super"), $3); }
|
||||
| yTHIS '.' ySUPER '.' idDotted { $$ = $5; BBUNSUP($1, "Unsupported: this.super"); }
|
||||
// // Expanded: package_scope idDotted
|
||||
| packageClassScope idDotted { $$ = $2; BBUNSUP($2, "Unsupported: package scoped id"); }
|
||||
| packageClassScope idDotted { $$ = new AstDot($<fl>2, true, $1, $2); }
|
||||
;
|
||||
|
||||
idClassSelForeach<nodep>:
|
||||
|
|
@ -4754,7 +4749,7 @@ idClassSelForeach<nodep>:
|
|||
{ $$ = new AstDot($2, false, new AstParseRef($<fl>1, VParseRefExp::PX_ROOT, "super"), $3); }
|
||||
| yTHIS '.' ySUPER '.' idDottedForeach { $$ = $5; BBUNSUP($1, "Unsupported: this.super"); }
|
||||
// // Expanded: package_scope idForeach
|
||||
| packageClassScope idDottedForeach { $$ = $2; BBUNSUP($2, "Unsupported: package/class scoped id"); }
|
||||
| packageClassScope idDottedForeach { $$ = new AstDot($<fl>2, true, $1, $2); }
|
||||
;
|
||||
|
||||
idDotted<nodep>:
|
||||
|
|
@ -4785,7 +4780,8 @@ idDottedMoreForeach<nodep>:
|
|||
// id below includes:
|
||||
// enum_identifier
|
||||
idArrayed<nodep>: // IEEE: id + select
|
||||
id { $$ = new AstParseRef($<fl>1, VParseRefExp::PX_TEXT, *$1, NULL, NULL); }
|
||||
id
|
||||
{ $$ = new AstParseRef($<fl>1, VParseRefExp::PX_TEXT, *$1, NULL, NULL); }
|
||||
// // IEEE: id + part_select_range/constant_part_select_range
|
||||
| idArrayed '[' expr ']' { $$ = new AstSelBit($2, $1, $3); } // Or AstArraySel, don't know yet.
|
||||
| idArrayed '[' constExpr ':' constExpr ']' { $$ = new AstSelExtract($2, $1, $3, $5); }
|
||||
|
|
@ -4795,7 +4791,8 @@ idArrayed<nodep>: // IEEE: id + select
|
|||
;
|
||||
|
||||
idArrayedForeach<nodep>: // IEEE: id + select (under foreach expression)
|
||||
id { $$ = new AstParseRef($<fl>1, VParseRefExp::PX_TEXT, *$1, NULL, NULL); }
|
||||
id
|
||||
{ $$ = new AstParseRef($<fl>1, VParseRefExp::PX_TEXT, *$1, NULL, NULL); }
|
||||
// // IEEE: id + part_select_range/constant_part_select_range
|
||||
| idArrayed '[' expr ']' { $$ = new AstSelBit($2, $1, $3); } // Or AstArraySel, don't know yet.
|
||||
| idArrayed '[' constExpr ':' constExpr ']' { $$ = new AstSelExtract($2, $1, $3, $5); }
|
||||
|
|
@ -5888,18 +5885,17 @@ class_typeExtImpOne<nodep>: // part of IEEE: class_type, where we either get a p
|
|||
idAny
|
||||
/*mid*/ { /* no nextId as not refing it above this*/ }
|
||||
/*cont*/ parameter_value_assignmentE
|
||||
{ $$ = new AstParseRef($<fl>1, VParseRefExp::PX_TEXT, *$1, NULL, NULL);
|
||||
$<scp>$ = $<scp>1;
|
||||
if ($3) BBUNSUP($3->fileline(), "Unsupported: Parameterized classes"); }
|
||||
{ $$ = new AstClassOrPackageRef($<fl>1, *$1, $<scp>1, $3);
|
||||
$<scp>$ = $<scp>1; }
|
||||
//
|
||||
// // package_sopeIdFollows expanded
|
||||
| yD_UNIT yP_COLONCOLON
|
||||
{ $$ = new AstParseRef($<fl>1, VParseRefExp::PX_TEXT, "$unit", NULL, NULL);
|
||||
{ $$ = new AstClassOrPackageRef($<fl>1, "$unit", NULL, NULL);
|
||||
$<scp>$ = NULL; // No purpose otherwise, every symtab can see root
|
||||
SYMP->nextId(PARSEP->rootp()); }
|
||||
//
|
||||
| yLOCAL__COLONCOLON yP_COLONCOLON
|
||||
{ $$ = new AstParseRef($<fl>1, VParseRefExp::PX_TEXT, "local", NULL, NULL);
|
||||
{ $$ = new AstClassOrPackageRef($<fl>1, "local::", NULL, NULL);
|
||||
$<scp>$ = NULL; // UNSUP
|
||||
SYMP->nextId(PARSEP->rootp());
|
||||
BBUNSUP($1, "Unsupported: Randomize 'local::'"); }
|
||||
|
|
@ -5912,11 +5908,11 @@ class_typeExtImpOne<nodep>: // part of IEEE: class_type, where we either get a p
|
|||
|
||||
//=== Below rules assume special scoping per above
|
||||
|
||||
packageClassScopeNoId<packagep>: // IEEE: [package_scope] not followed by yaID
|
||||
packageClassScopeNoId<nodep>: // IEEE: [package_scope] not followed by yaID
|
||||
packageClassScope { $$ = $1; $<scp>$ = $<scp>1; SYMP->nextId(NULL); }
|
||||
;
|
||||
|
||||
packageClassScopeE<packagep>: // IEEE: [package_scope]
|
||||
packageClassScopeE<nodep>: // IEEE: [package_scope]
|
||||
// // IMPORTANT: The lexer will parse the following ID to be in the found package
|
||||
// // if not needed must use packageClassScopeNoId
|
||||
// // TODO: To support classes should return generic type, not packagep
|
||||
|
|
@ -5925,7 +5921,7 @@ packageClassScopeE<packagep>: // IEEE: [package_scope]
|
|||
| packageClassScope { $$ = $1; $<scp>$ = $<scp>1; }
|
||||
;
|
||||
|
||||
packageClassScope<packagep>: // IEEE: class_scope + type
|
||||
packageClassScope<nodep>: // IEEE: class_scope
|
||||
// // IEEE: "class_type yP_COLONCOLON"
|
||||
// // IMPORTANT: The lexer will parse the following ID to be in the found package
|
||||
// // if not needed must use packageClassScopeNoId
|
||||
|
|
@ -5934,10 +5930,11 @@ packageClassScope<packagep>: // IEEE: class_scope + type
|
|||
packageClassScopeList { $$ = $1; $<scp>$ = $<scp>1; }
|
||||
| localNextId yP_COLONCOLON { $$ = $1; $<scp>$ = $<scp>1; }
|
||||
| dollarUnitNextId yP_COLONCOLON { $$ = $1; $<scp>$ = $<scp>1; }
|
||||
| dollarUnitNextId yP_COLONCOLON packageClassScopeList { $$ = $3; $<scp>$ = $<scp>3; }
|
||||
| dollarUnitNextId yP_COLONCOLON packageClassScopeList
|
||||
{ $$ = new AstDot($2, true, $1, $3); $<scp>$ = $<scp>3; }
|
||||
;
|
||||
|
||||
packageClassScopeList<packagep>: // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE
|
||||
packageClassScopeList<nodep>: // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE
|
||||
// // Or IEEE: [package_scope]
|
||||
// // IMPORTANT: The lexer will parse the following ID to be in the found package
|
||||
// // if not needed must use packageClassScopeNoId
|
||||
|
|
@ -5945,10 +5942,10 @@ packageClassScopeList<packagep>: // IEEE: class_type: "id [ parameter_value_assi
|
|||
// // If you follow the rules down, class_type is really a list via ps_class_identifier
|
||||
packageClassScopeItem { $$ = $1; $<scp>$ = $<scp>1; }
|
||||
| packageClassScopeList packageClassScopeItem
|
||||
{ $$ = $2; $<scp>$ = $<scp>2; BBUNSUP($<fl>2, "Unsupported: Nested :: references"); }
|
||||
{ $$ = new AstDot($<fl>2, true, $1, $2); $<scp>$ = $<scp>2; }
|
||||
;
|
||||
|
||||
packageClassScopeItem<packagep>: // IEEE: package_scope or [package_scope]::[class_scope]
|
||||
packageClassScopeItem<nodep>: // IEEE: package_scope or [package_scope]::[class_scope]
|
||||
// // IMPORTANT: The lexer will parse the following ID to be in the found package
|
||||
// // if not needed must use packageClassScopeNoId
|
||||
// // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE
|
||||
|
|
@ -5956,29 +5953,30 @@ packageClassScopeItem<packagep>: // IEEE: package_scope or [package_scope]::[cla
|
|||
idCC
|
||||
/*mid*/ { SYMP->nextId($<scp>1); }
|
||||
/*cont*/ yP_COLONCOLON
|
||||
{ $$ = VN_CAST($<scp>1, Package); $<scp>$ = $<scp>1; } // UNSUP classes
|
||||
{ $$ = new AstClassOrPackageRef($<fl>1, *$1, $<scp>1, NULL); $<scp>$ = $<scp>1; }
|
||||
//
|
||||
| idCC parameter_value_assignment
|
||||
/*mid*/ { SYMP->nextId($<scp>1); } // Change next *after* we handle parameters, not before
|
||||
/*cont*/ yP_COLONCOLON
|
||||
{ $$ = VN_CAST($<scp>1, Package); $<scp>$ = $<scp>1; // UNSUP classes
|
||||
if ($2) BBUNSUP($2->fileline(), "Unsupported: Parameterized classes"); }
|
||||
{ $$ = new AstClassOrPackageRef($<fl>1, *$1, $<scp>1, $2); $<scp>$ = $<scp>1; }
|
||||
;
|
||||
|
||||
dollarUnitNextId<packagep>: // $unit
|
||||
dollarUnitNextId<nodep>: // $unit
|
||||
// // IMPORTANT: The lexer will parse the following ID to be in the found package
|
||||
// // if not needed must use packageClassScopeNoId
|
||||
// // Must call nextId without any additional tokens following
|
||||
yD_UNIT
|
||||
{ $$ = GRAMMARP->unitPackage($<fl>1); SYMP->nextId(PARSEP->rootp()); }
|
||||
{ $$ = new AstClassOrPackageRef($1, "$unit", GRAMMARP->unitPackage($<fl>1), NULL);
|
||||
SYMP->nextId(PARSEP->rootp()); }
|
||||
;
|
||||
|
||||
localNextId<packagep>: // local
|
||||
localNextId<nodep>: // local
|
||||
// // IMPORTANT: The lexer will parse the following ID to be in the found package
|
||||
// // if not needed must use packageClassScopeNoId
|
||||
// // Must call nextId without any additional tokens following
|
||||
yLOCAL__COLONCOLON
|
||||
{ $$ = GRAMMARP->unitPackage($<fl>1); SYMP->nextId(PARSEP->rootp());
|
||||
{ $$ = new AstClassOrPackageRef($1, "local::", GRAMMARP->unitPackage($<fl>1), NULL);
|
||||
SYMP->nextId(PARSEP->rootp());
|
||||
BBUNSUP($<fl>1, "Unsupported: Randomize 'local::'"); }
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
%Error: t/t_class2.v:35:16: Can't find definition of variable: 'ENUM_VAL'
|
||||
%Error-UNSUPPORTED: t/t_class2.v:35:16: Unsupported: Class '::' references: 'Cls'
|
||||
35 | if (Cls::ENUM_VAL != 22) $stop;
|
||||
| ^~~~~~~~
|
||||
%Error: Exiting due to
|
||||
%Error: Internal Error: t/t_class2.v:35:11: ../V3LinkDot.cpp:#: Bad package link
|
||||
35 | if (Cls::ENUM_VAL != 22) $stop;
|
||||
| ^~~
|
||||
... See the manual and https://verilator.org for more assistance.
|
||||
|
|
|
|||
|
|
@ -1,28 +1,16 @@
|
|||
%Error-UNSUPPORTED: t/t_class_extends.v:13:21: Unsupported: class extends
|
||||
13 | class Base1 extends Base0;
|
||||
| ^~~~~
|
||||
%Error: t/t_class_extends.v:13:21: Found definition of 'Base0' as a CLASS but expected a variable
|
||||
13 | class Base1 extends Base0;
|
||||
| ^~~~~
|
||||
%Error-UNSUPPORTED: t/t_class_extends.v:18:21: Unsupported: class extends
|
||||
18 | class Base2 extends Base1;
|
||||
| ^~~~~
|
||||
%Error: t/t_class_extends.v:18:21: Found definition of 'Base1' as a CLASS but expected a variable
|
||||
18 | class Base2 extends Base1;
|
||||
| ^~~~~
|
||||
%Error-UNSUPPORTED: t/t_class_extends.v:22:19: Unsupported: class extends
|
||||
22 | class Cls extends Base2;
|
||||
| ^~~~~
|
||||
%Error: t/t_class_extends.v:22:19: Found definition of 'Base2' as a CLASS but expected a variable
|
||||
22 | class Cls extends Base2;
|
||||
| ^~~~~
|
||||
%Error: t/t_class_extends.v:25:4: Can't find typedef: 'T'
|
||||
25 | T imemberc;
|
||||
| ^
|
||||
%Error-UNSUPPORTED: t/t_class_extends.v:33:43: Unsupported: class extends
|
||||
33 | class uvm__registry #(type T=int) extends uvm_object_wrapper;
|
||||
| ^~~~~~~~~~~~~~~~~~
|
||||
%Error: t/t_class_extends.v:33:43: Found definition of 'uvm_object_wrapper' as a CLASS but expected a variable
|
||||
33 | class uvm__registry #(type T=int) extends uvm_object_wrapper;
|
||||
| ^~~~~~~~~~~~~~~~~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -7,9 +7,6 @@
|
|||
%Error-UNSUPPORTED: t/t_class_extends_this.v:17:19: Unsupported: class extends
|
||||
17 | class Cls extends Base;
|
||||
| ^~~~
|
||||
%Error: t/t_class_extends_this.v:17:19: Found definition of 'Base' as a CLASS but expected a variable
|
||||
17 | class Cls extends Base;
|
||||
| ^~~~
|
||||
%Error-UNSUPPORTED: t/t_class_extends_this.v:21:11: Unsupported: this
|
||||
21 | if (this.value != 2) $stop;
|
||||
| ^~~~
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
%Error-UNSUPPORTED: t/t_class_member_bad.v:11:20: Unsupported: class extends
|
||||
11 | class Cls2 extends Base1;
|
||||
| ^~~~~
|
||||
%Error: t/t_class_member_bad.v:11:20: Found definition of 'Base1' as a CLASS but expected a variable
|
||||
11 | class Cls2 extends Base1;
|
||||
| ^~~~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
%Error-UNSUPPORTED: t/t_class_method_bad.v:11:20: Unsupported: class extends
|
||||
11 | class Cls2 extends Base1;
|
||||
| ^~~~~
|
||||
%Error: t/t_class_method_bad.v:11:20: Found definition of 'Base1' as a CLASS but expected a variable
|
||||
11 | class Cls2 extends Base1;
|
||||
| ^~~~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
%Error-UNSUPPORTED: t/t_class_param.v:20:11: Unsupported: Parameter classes
|
||||
%Error-UNSUPPORTED: t/t_class_param.v:20:4: Unsupported: parameterized packages
|
||||
20 | Cls #(.P(4)) c4;
|
||||
| ^
|
||||
| ^~~
|
||||
%Error-UNSUPPORTED: t/t_class_param.v:9:23: Unsupported: class parameter
|
||||
9 | class Cls #(parameter P = 12);
|
||||
| ^
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -1,4 +1,13 @@
|
|||
%Error-UNSUPPORTED: t/t_class_typedef.v:14:24: Unsupported: Parameterized classes
|
||||
%Error-UNSUPPORTED: t/t_class_typedef.v:12:4: Unsupported: Class '::' reference
|
||||
12 | uvm_resource_types::rsrc_q_t rtab [string];
|
||||
| ^~~~~~~~~~~~~~~~~~
|
||||
%Error: t/t_class_typedef.v:12:24: Can't find typedef: 'rsrc_q_t'
|
||||
12 | uvm_resource_types::rsrc_q_t rtab [string];
|
||||
| ^~~~~~~~
|
||||
%Error-UNSUPPORTED: t/t_class_typedef.v:14:4: Unsupported: Class '::' reference
|
||||
14 | uvm_resource_types#(1,2,3)::rsrc_q_t rtab_paramed [string];
|
||||
| ^
|
||||
| ^~~~~~~~~~~~~~~~~~
|
||||
%Error: t/t_class_typedef.v:14:32: Can't find typedef: 'rsrc_q_t'
|
||||
14 | uvm_resource_types#(1,2,3)::rsrc_q_t rtab_paramed [string];
|
||||
| ^~~~~~~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%Error-UNSUPPORTED: t/t_class_vparam_unsup.v:13:58: Unsupported: Parameter classes
|
||||
%Error-UNSUPPORTED: t/t_class_vparam_unsup.v:13:40: Unsupported: parameterized packages
|
||||
13 | pure virtual function void funcname(paramed_class_t #(CTYPE_t) v);
|
||||
| ^~~~~~~
|
||||
| ^~~~~~~~~~~~~~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2004 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2020 Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t(/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
integer cyc = 0;
|
||||
reg [1:0] reg_i;
|
||||
reg [1049:0] pad0;
|
||||
reg [1049:0] reg_o;
|
||||
reg [1049:0] spad1;
|
||||
|
||||
/*AUTOWIRE*/
|
||||
|
||||
always_comb begin
|
||||
if (reg_i[1] == 1'b1)
|
||||
reg_o = {986'd0, 64'hffff0000ffff0000};
|
||||
else if (reg_i[0] == 1'b1)
|
||||
reg_o = {64'hffff0000ffff0000, 986'd0};
|
||||
else
|
||||
reg_o = 1050'd0;
|
||||
end
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
if (cyc == 0) begin
|
||||
reg_i <= 2'b00;
|
||||
pad0 <= '1;
|
||||
spad1 <= '1;
|
||||
end
|
||||
else if (cyc == 1) begin
|
||||
reg_i <= 2'b01;
|
||||
end
|
||||
else if (cyc == 2) begin
|
||||
if (reg_o != {64'hffff0000ffff0000, 986'd0}) $stop;
|
||||
reg_i <= 2'b10;
|
||||
end
|
||||
else if (cyc == 99) begin
|
||||
if (reg_o != {986'd0, 64'hffff0000ffff0000}) $stop;
|
||||
if (pad0 != '1) $stop;
|
||||
if (spad1 != '1) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#!/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(simulator => 1);
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ['--assert'],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2020 by Peter Monsson.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
|
||||
input clk;
|
||||
integer cyc; initial cyc=2;
|
||||
wire [31:0] in = cyc;
|
||||
|
||||
Test test (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.in (in[31:0]));
|
||||
|
||||
Test2 test2 (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.in (in[31:0]));
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (cyc!=0) begin
|
||||
cyc <= cyc + 1;
|
||||
if (cyc==10) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module Test (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk, in
|
||||
);
|
||||
|
||||
input clk;
|
||||
input [31:0] in;
|
||||
|
||||
reg [31:0] dly0 = 1;
|
||||
|
||||
// If called in an assertion, sequence, or property, the appropriate clocking event.
|
||||
// Otherwise, if called in a disable condition or a clock expression in an assertion, sequence, or prop, explicit.
|
||||
// Otherwise, if called in an action block of an assertion, the leading clock of the assertion is used.
|
||||
// Otherwise, if called in a procedure, the inferred clock
|
||||
// Otherwise, default clocking
|
||||
|
||||
always @(posedge clk) begin
|
||||
dly0 <= in;
|
||||
// In clock expression
|
||||
$write("in=%0d, dly0=%0d, fell=%0d, past=%0d\n", in, dly0, $fell(dly0), $past(dly0));
|
||||
if ($fell(dly0[4])) $stop;
|
||||
end
|
||||
|
||||
assert property (@(posedge clk) $fell(dly0) || dly0%2==1);
|
||||
endmodule
|
||||
|
||||
|
||||
module Test2 (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk, in
|
||||
);
|
||||
|
||||
input clk;
|
||||
input [31:0] in;
|
||||
|
||||
reg [31:0] dly0 = 1;
|
||||
|
||||
always @(posedge clk) begin
|
||||
dly0 <= in;
|
||||
if ($fell(dly0[31:4])) $stop;
|
||||
end
|
||||
|
||||
default clocking @(posedge clk); endclocking
|
||||
assert property ($fell(dly0[0]) || dly0%2==1);
|
||||
endmodule
|
||||
|
|
@ -39,6 +39,19 @@ module ThingMuxOH
|
|||
the_intf.t things_in [NTHINGS-1:0],
|
||||
the_intf.i thing_out
|
||||
);
|
||||
assign thing_out.valid = things_in[0].valid;
|
||||
endmodule
|
||||
|
||||
module ThingMuxShort
|
||||
#(
|
||||
parameter NTHINGS = 1,
|
||||
parameter M = 5 )
|
||||
(
|
||||
input logic [NTHINGS-1:0] select_oh,
|
||||
the_intf.t things_in [NTHINGS],
|
||||
the_intf.i thing_out
|
||||
);
|
||||
assign thing_out.valid = things_in[0].valid;
|
||||
endmodule
|
||||
|
||||
module Thinker
|
||||
|
|
@ -55,8 +68,10 @@ module Thinker
|
|||
|
||||
the_intf #(.M(M)) curr_things [N-1:0] ();
|
||||
the_intf #(.M(M)) prev_things [N-1:0] ();
|
||||
the_intf #(.M(M)) s_things [N] ();
|
||||
the_intf #(.M(M)) curr_thing ();
|
||||
the_intf #(.M(M)) prev_thing ();
|
||||
the_intf #(.M(M)) s_thing ();
|
||||
|
||||
logic [N-1:0] select_oh;
|
||||
|
||||
|
|
@ -78,6 +93,15 @@ module Thinker
|
|||
.things_in( prev_things ),
|
||||
.thing_out( prev_thing ));
|
||||
|
||||
// 3rd mux, using short array nomenclature:
|
||||
ThingMuxShort #(
|
||||
.NTHINGS ( N ),
|
||||
.M ( M ))
|
||||
s_thing_mux(
|
||||
.select_oh( select_oh ),
|
||||
.things_in( s_things ),
|
||||
.thing_out( s_thing ));
|
||||
|
||||
endmodule
|
||||
|
||||
module t
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
// Version 2.0.
|
||||
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
`define checkr(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got=%f exp=%f\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
|
||||
`define is_near_real(a,b) (( ((a)<(b)) ? (b)-(a) : (a)-(b)) < (((a)/(b))*0.0001))
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
|
|
@ -16,6 +17,16 @@ module t (/*AUTOARG*/
|
|||
|
||||
integer i;
|
||||
reg [63:0] b;
|
||||
reg [47:0] i48;
|
||||
reg signed [47:0] is48;
|
||||
reg [31:0] ci32;
|
||||
reg signed [31:0] cis32;
|
||||
reg [47:0] ci48;
|
||||
reg signed [47:0] cis48;
|
||||
reg [63:0] ci64;
|
||||
reg signed [63:0] cis64;
|
||||
reg [95:0] ci96;
|
||||
reg signed [95:0] cis96;
|
||||
real r, r2;
|
||||
integer cyc=0;
|
||||
|
||||
|
|
@ -88,6 +99,41 @@ module t (/*AUTOARG*/
|
|||
// bug
|
||||
b = 64'h7fe8000000000000;
|
||||
$display("%6.3f", $bitstoreal(b));
|
||||
// bug
|
||||
i48 = 48'hff00_00000000;
|
||||
r = real'(i48);
|
||||
if (r != 280375465082880.0) $stop;
|
||||
r = $itor(i48);
|
||||
if (r != 280375465082880.0) $stop;
|
||||
|
||||
is48 = 48'shff00_00000000;
|
||||
r = real'(is48);
|
||||
if (r != -1099511627776.0) $stop;
|
||||
r = $itor(is48);
|
||||
if (r != -1099511627776.0) $stop;
|
||||
|
||||
r = 0;
|
||||
r = i48;
|
||||
if (r != 280375465082880.0) $stop;
|
||||
r = 0;
|
||||
|
||||
r = $itor(-10);
|
||||
if (r != -10.0) $stop;
|
||||
|
||||
r = real'(4'sb1111);
|
||||
if (r != -1) $stop;
|
||||
r = $itor(4'sb1111);
|
||||
if (r != -1) $stop;
|
||||
|
||||
r = real'(4'b1111);
|
||||
if (r != 15) $stop;
|
||||
r = $itor(4'b1111);
|
||||
if (r != 15) $stop;
|
||||
|
||||
r = real'(96'hf0000000_00000000_00000000);
|
||||
if (r != 74276402357122816493947453440.0) $stop;
|
||||
r = real'(96'shf0000000_00000000_00000000);
|
||||
if (r != -4951760157141521099596496896.0) $stop;
|
||||
end
|
||||
|
||||
// Test loop
|
||||
|
|
@ -98,8 +144,18 @@ module t (/*AUTOARG*/
|
|||
cyc <= cyc + 1;
|
||||
if (cyc==0) begin
|
||||
// Setup
|
||||
ci48 <= '0;
|
||||
cis48 <= '0;
|
||||
ci96 <= '0;
|
||||
cis96 <= '0;
|
||||
end
|
||||
else if (cyc<90) begin
|
||||
else if (cyc == 1) begin
|
||||
ci48 <= 48'hff00_00000000;
|
||||
cis48 <= 48'shff00_00000000;
|
||||
ci96 <= 96'hf0000000_00000000_00000000;
|
||||
cis96 <= 96'shf0000000_00000000_00000000;
|
||||
end
|
||||
else if (cyc<80) begin
|
||||
if ($time != {32'h0, $rtoi($realtime)}) $stop;
|
||||
if ($itor(cyc) != cyc) $stop;
|
||||
//Unsup: if ((real `($time)) != $realtime) $stop;
|
||||
|
|
@ -141,6 +197,76 @@ module t (/*AUTOARG*/
|
|||
!= (((cyc-50)!=0) ? 10 : 20)) $stop;
|
||||
//
|
||||
if ((!(r-50.0)) != (!((cyc-50) != 0))) $stop;
|
||||
//
|
||||
r = real'(ci48);
|
||||
`checkr(r, 280375465082880.0);
|
||||
r = real'(cis48);
|
||||
`checkr(r, -1099511627776.0);
|
||||
//
|
||||
r = real'(ci96);
|
||||
`checkr(r, 74276402357122816493947453440.0);
|
||||
r = real'(cis96);
|
||||
`checkr(r, -4951760157141521099596496896.0);
|
||||
end
|
||||
else if (cyc==90) begin
|
||||
ci32 <= '0;
|
||||
cis32 <= '0;
|
||||
ci48 <= '0;
|
||||
cis48 <= '0;
|
||||
ci64 <= '0;
|
||||
cis64 <= '0;
|
||||
ci96 <= '0;
|
||||
cis96 <= '0;
|
||||
end
|
||||
else if (cyc==91) begin
|
||||
`checkr(real'(ci32), 0.0);
|
||||
`checkr(real'(cis32), 0.0);
|
||||
`checkr(real'(ci48), 0.0);
|
||||
`checkr(real'(cis48), 0.0);
|
||||
`checkr(real'(ci64), 0.0);
|
||||
`checkr(real'(cis64), 0.0);
|
||||
`checkr(real'(ci96), 0.0);
|
||||
`checkr(real'(cis96), 0.0);
|
||||
end
|
||||
else if (cyc==92) begin
|
||||
ci32 <= 32'b1;
|
||||
cis32 <= 32'b1;
|
||||
ci48 <= 48'b1;
|
||||
cis48 <= 48'b1;
|
||||
ci64 <= 64'b1;
|
||||
cis64 <= 64'b1;
|
||||
ci96 <= 96'b1;
|
||||
cis96 <= 96'b1;
|
||||
end
|
||||
else if (cyc==93) begin
|
||||
`checkr(real'(ci32), 1.0);
|
||||
`checkr(real'(cis32), 1.0);
|
||||
`checkr(real'(ci48), 1.0);
|
||||
`checkr(real'(cis48), 1.0);
|
||||
`checkr(real'(ci64), 1.0);
|
||||
`checkr(real'(cis64), 1.0);
|
||||
`checkr(real'(ci96), 1.0);
|
||||
`checkr(real'(cis96), 1.0);
|
||||
end
|
||||
else if (cyc==94) begin
|
||||
ci32 <= ~ '0;
|
||||
cis32 <= ~ '0;
|
||||
ci48 <= ~ '0;
|
||||
cis48 <= ~ '0;
|
||||
ci64 <= ~ '0;
|
||||
cis64 <= ~ '0;
|
||||
ci96 <= ~ '0;
|
||||
cis96 <= ~ '0;
|
||||
end
|
||||
else if (cyc==95) begin
|
||||
`checkr(real'(ci32), 4294967295.0);
|
||||
`checkr(real'(cis32), -1.0);
|
||||
`checkr(real'(ci48), 281474976710655.0);
|
||||
`checkr(real'(cis48), -1.0);
|
||||
`checkr(real'(ci64), 18446744073709551616.0);
|
||||
`checkr(real'(cis64), -1.0);
|
||||
`checkr(real'(ci96), 79228162514264337593543950336.0);
|
||||
`checkr(real'(cis96), -1.0);
|
||||
end
|
||||
else if (cyc==99) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2019 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2020 Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
`define checkr(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got=%f exp=%f\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
|
||||
|
||||
module t(/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
integer cyc=0;
|
||||
reg [63:0] crc;
|
||||
reg [63:0] sum;
|
||||
|
||||
reg [127:0] in;
|
||||
|
||||
check #(48) check48 (.*);
|
||||
check #(31) check31 (.*);
|
||||
check #(32) check32 (.*);
|
||||
check #(63) check63 (.*);
|
||||
check #(64) check64 (.*);
|
||||
check #(96) check96 (.*);
|
||||
check #(128) check128 (.*);
|
||||
|
||||
always_comb begin
|
||||
if (crc[2:0] == 0) in = '0;
|
||||
else if (crc[2:0] == 1) in = ~'0;
|
||||
else if (crc[2:0] == 2) in = 128'b1;
|
||||
else if (crc[2:0] == 3) in = ~ 128'b1;
|
||||
else begin
|
||||
in = {crc, crc};
|
||||
if (crc[3]) in[31:0] = '0;
|
||||
if (crc[4]) in[63:32] = '0;
|
||||
if (crc[5]) in[95:64] = '0;
|
||||
if (crc[6]) in[127:96] = '0;
|
||||
if (crc[7]) in[31:0] = ~'0;
|
||||
if (crc[8]) in[63:32] = ~'0;
|
||||
if (crc[9]) in[95:64] = ~'0;
|
||||
if (crc[10]) in[127:96] = ~'0;
|
||||
end
|
||||
end
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("[%0t] cyc==%0d in=%x\n",$time, cyc, in);
|
||||
`endif
|
||||
cyc <= cyc + 1;
|
||||
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
|
||||
if (cyc == 0) begin
|
||||
// Setup
|
||||
crc <= 64'h5aef0c8d_d70a4497;
|
||||
sum <= '0;
|
||||
end
|
||||
else if (cyc == 99) begin
|
||||
`checkr(check48.sum, 14574057015683440.000000);
|
||||
`checkr(check31.sum, 114141374814.000000);
|
||||
`checkr(check32.sum, 236547942750.000000);
|
||||
`checkr(check63.sum, 513694866079917670400.000000);
|
||||
`checkr(check64.sum, 1002533584033221181440.000000);
|
||||
`checkr(check96.sum, 4377373669974269260279175970816.000000);
|
||||
`checkr(check128.sum, 18358899571808044815012294240949812330496.000000);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module check(/*AUTOARG*/
|
||||
// Inputs
|
||||
in, clk, cyc
|
||||
);
|
||||
parameter WIDTH = 128;
|
||||
input [127:0] in;
|
||||
|
||||
wire [WIDTH-1:0] ci = in[WIDTH-1:0];
|
||||
wire signed [WIDTH-1:0] cis = in[WIDTH-1:0];
|
||||
|
||||
real r;
|
||||
real rs;
|
||||
always_comb r = ci;
|
||||
always_comb rs = cis;
|
||||
|
||||
input clk;
|
||||
input integer cyc;
|
||||
real sum;
|
||||
|
||||
always_ff @ (negedge clk) begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("[%0t] w%0d in=%h r=%f rs=%f sum=%f\n", $time, WIDTH, ci, r, rs, sum);
|
||||
`endif
|
||||
if (cyc < 10) sum <= 0;
|
||||
else sum <= sum + r + rs;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute();
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2020 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
|
||||
logic in1 = 1;
|
||||
logic [1:0] in2 = 2'b11;
|
||||
logic [31:0] out;
|
||||
|
||||
typedef logic [7:0] data_t;
|
||||
|
||||
// verilator lint_off WIDTH
|
||||
initial begin
|
||||
in1 = 1;
|
||||
in2 = 0;
|
||||
out = data_t'(in1 << in2);
|
||||
if (out != 8'b1) $stop;
|
||||
|
||||
in2 = 1;
|
||||
out = data_t'(in1 << in2);
|
||||
if (out != 8'b10) $stop;
|
||||
|
||||
in2 = 2;
|
||||
out = data_t'(in1 << in2);
|
||||
if (out != 8'b100) $stop;
|
||||
|
||||
in2 = 3;
|
||||
out = data_t'(in1 << in2);
|
||||
if (out != 8'b1000) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish();
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
%Error-UNSUPPORTED: t/t_math_wide_bad.v:22:18: Unsupported: operator POWSS operator of 576 bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h
|
||||
22 | assign z2 = a ** 3;
|
||||
| ^~
|
||||
%Error-UNSUPPORTED: t/t_math_wide_bad.v:23:15: Unsupported: operator ISTORD operator of 64 bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h
|
||||
23 | assign r = real'(a);
|
||||
| ^~~~
|
||||
%Error-UNSUPPORTED: t/t_math_wide_bad.v:21:17: Unsupported: operator MULS operator of 576 bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h
|
||||
21 | assign z = a * b;
|
||||
| ^
|
||||
%Error: Exiting due to
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2010 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(linter => 1);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2020 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Outputs
|
||||
z, z2, r,
|
||||
// Inputs
|
||||
a, b
|
||||
);
|
||||
|
||||
input signed [17*32 : 0] a;
|
||||
input signed [17*32 : 0] b;
|
||||
|
||||
output signed [17*32 : 0] z;
|
||||
output signed [17*32 : 0] z2;
|
||||
output real r;
|
||||
|
||||
assign z = a * b;
|
||||
assign z2 = a ** 3;
|
||||
assign r = real'(a);
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2020 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t;
|
||||
sub #(.WIDTH(4)) sub4();
|
||||
sub #(.WIDTH(8)) sub8();
|
||||
|
||||
logic [3:0] out4;
|
||||
logic [7:0] out8;
|
||||
|
||||
initial begin
|
||||
out4 = sub4.orer(4'b1000);
|
||||
out8 = sub8.orer(8'b10000000);
|
||||
if (out4 != 4'b1011) $stop;
|
||||
if (out8 != 8'b10111111) $stop;
|
||||
out4 = sub4.orer2(4'b1000);
|
||||
out8 = sub8.orer2(8'b10000000);
|
||||
if (out4 != 4'b1001) $stop;
|
||||
if (out8 != 8'b10011111) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
||||
module sub;
|
||||
parameter WIDTH = 1;
|
||||
|
||||
function [WIDTH-1:0] orer;
|
||||
input [WIDTH-1:0] in;
|
||||
// IEEE provices no way to override this parameter, basically it's a localparam
|
||||
parameter MASK_W = WIDTH - 2;
|
||||
localparam [MASK_W-1:0] MASK = '1;
|
||||
// verilator lint_off WIDTH
|
||||
return in | MASK;
|
||||
// verilator lint_on WIDTH
|
||||
endfunction
|
||||
|
||||
function [WIDTH-1:0] orer2;
|
||||
input [WIDTH-1:0] in;
|
||||
// Same param names as other function to check we disambiguate
|
||||
// IEEE provices no way to override this parameter, basically it's a localparam
|
||||
parameter MASK_W = WIDTH - 3;
|
||||
localparam [MASK_W-1:0] MASK = '1;
|
||||
// verilator lint_off WIDTH
|
||||
return in | MASK;
|
||||
// verilator lint_on WIDTH
|
||||
endfunction
|
||||
endmodule
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
%Error-UNSUPPORTED: t/t_param_in_func_bad.v:24:26: Unsupported: Parameters in functions
|
||||
%Error-UNSUPPORTED: t/t_param_in_func_bad.v:24:26: Unsupported: Parameters in functions with complex assign
|
||||
: ... In instance t
|
||||
24 | localparam logic[7:0] digits[10]
|
||||
| ^~~~~~
|
||||
%Error: t/t_param_in_func_bad.v:28:11: Can't find definition of variable: 'digits'
|
||||
28 | return digits[d];
|
||||
| ^~~~~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2016 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// issue 1991
|
||||
|
||||
module t
|
||||
(/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
socket #(3'b000) s0();
|
||||
socket #(3'b010) s1();
|
||||
socket #(2'b10) s2();
|
||||
socket #(2'b11) s3();
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (s0.ADDR != 0) $stop;
|
||||
if (s1.ADDR != 2) $stop;
|
||||
if (s2.ADDR != 2) $stop;
|
||||
if (s3.ADDR != 3) $stop;
|
||||
if ($bits(s0.ADDR) != 3) $stop;
|
||||
if ($bits(s1.ADDR) != 3) $stop;
|
||||
if ($bits(s2.ADDR) != 2) $stop;
|
||||
if ($bits(s3.ADDR) != 2) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module socket #(ADDR)();
|
||||
initial
|
||||
$display("bits %0d, addr %b", $bits(ADDR), ADDR);
|
||||
endmodule
|
||||
|
|
@ -1,22 +1,9 @@
|
|||
%Error: t/t_process.v:22:4: Can't find typedef: 'process'
|
||||
22 | process p;
|
||||
| ^~~~~~~
|
||||
%Error: t/t_process.v:26:20: Can't find definition of task/function: 'self'
|
||||
%Error-UNSUPPORTED: t/t_process.v:26:20: Unsupported: 'process'
|
||||
26 | p = process::self();
|
||||
| ^~~~
|
||||
%Error: t/t_process.v:27:34: Can't find definition of variable: 'RUNNING'
|
||||
27 | if (p.status() != process::RUNNING) $stop;
|
||||
| ^~~~~~~
|
||||
%Error: t/t_process.v:28:34: Can't find definition of variable: 'WAITING'
|
||||
28 | if (p.status() == process::WAITING) $stop;
|
||||
| ^~~~~~~
|
||||
%Error: t/t_process.v:29:34: Can't find definition of variable: 'SUSPENDED'
|
||||
29 | if (p.status() == process::SUSPENDED) $stop;
|
||||
| ^~~~~~~~~
|
||||
%Error: t/t_process.v:30:34: Can't find definition of variable: 'KILLED'
|
||||
30 | if (p.status() == process::KILLED) $stop;
|
||||
| ^~~~~~
|
||||
%Error: t/t_process.v:31:34: Can't find definition of variable: 'FINISHED'
|
||||
31 | if (p.status() == process::FINISHED) $stop;
|
||||
| ^~~~~~~~
|
||||
%Error: Exiting due to
|
||||
%Error: Internal Error: t/t_process.v:26:11: ../V3LinkDot.cpp:#: Bad package link
|
||||
26 | p = process::self();
|
||||
| ^~~~~~~
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
#!/usr/bin/env perl
|
||||
# Makes the test run with tracing enabled by default, can be overridden
|
||||
# with --notrace
|
||||
unshift(@ARGV, "--trace");
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2019 by Todd Strader. 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(
|
||||
vlt => 1,
|
||||
xsim => 1,
|
||||
);
|
||||
|
||||
$Self->{sim_time} = $Self->{benchmark} * 100 if $Self->{benchmark};
|
||||
|
||||
my $secret_prefix = "secret";
|
||||
my $secret_dir = "$Self->{obj_dir}/$secret_prefix";
|
||||
mkdir $secret_dir;
|
||||
|
||||
while (1) {
|
||||
# Always compile the secret file with Verilator no matter what simulator
|
||||
# we are testing with
|
||||
run(logfile => "$secret_dir/vlt_compile.log",
|
||||
cmd => ["perl",
|
||||
"$ENV{VERILATOR_ROOT}/bin/verilator",
|
||||
"--prefix",
|
||||
"Vt_prot_lib_secret",
|
||||
"-cc",
|
||||
"-Mdir",
|
||||
$secret_dir,
|
||||
"--protect-lib",
|
||||
$secret_prefix,
|
||||
"t/t_prot_lib_comb.v"],
|
||||
verilator_run => 1,
|
||||
);
|
||||
last if $Self->{errors};
|
||||
|
||||
run(logfile => "$secret_dir/secret_gcc.log",
|
||||
cmd=>[$ENV{MAKE},
|
||||
"-C",
|
||||
$secret_dir,
|
||||
"-f",
|
||||
"Vt_prot_lib_secret.mk"]);
|
||||
last if $Self->{errors};
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ["$secret_dir/secret.sv",
|
||||
"+define+PROCESS_TOP",
|
||||
"-LDFLAGS",
|
||||
"$secret_prefix/libsecret.a"],
|
||||
xsim_flags2 => ["$secret_dir/secret.sv"],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
xsim_run_flags2 => ["--sv_lib",
|
||||
"$secret_dir/libsecret",
|
||||
"--dpi_absolute"],
|
||||
);
|
||||
|
||||
ok(1);
|
||||
last;
|
||||
}
|
||||
1;
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2020 by Yutetsu TAKATSUKASA.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
`ifdef PROCESS_TOP
|
||||
`define CHECK if (out0 != (in0 ^ in1) || out1 != (in0 | in1) || out2 != (in0 & in1)) begin \
|
||||
$display("Mismatch in0:%b in1:%b out0:%b out1:%b out2:%b", in0, in1, out0, out1, out2); \
|
||||
$stop; \
|
||||
end
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
|
||||
logic in0, in1;
|
||||
logic out0, out1, out2;
|
||||
logic [31:0] count = 0;
|
||||
// actually XOR and OR and AND
|
||||
secret i_secret(.in0(in0), .in1(in1), .out0(out0), .out1(out1), .out2(out2));
|
||||
|
||||
always @(posedge clk) begin
|
||||
count <= count + 32'd1;
|
||||
if (count == 32'd1) begin
|
||||
in0 <= 1'b0;
|
||||
in1 <= 1'b0;
|
||||
end else if (count == 32'd2) begin
|
||||
`CHECK
|
||||
in0 <= 1'b1;
|
||||
in1 <= 1'b0;
|
||||
end else if (count == 32'd3) begin
|
||||
`CHECK
|
||||
in0 <= 1'b0;
|
||||
in1 <= 1'b1;
|
||||
end else if (count == 32'd4) begin
|
||||
`CHECK
|
||||
in0 <= 1'b1;
|
||||
in1 <= 1'b1;
|
||||
end else if (count == 32'd5) begin
|
||||
`CHECK
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
`else
|
||||
module secret(input in0, input in1, output out0, output out1, output out2);
|
||||
assign out0 = in0 ^ in1;
|
||||
assign out1 = in0 | in1;
|
||||
assign out2 = in0 & in1;
|
||||
endmodule
|
||||
`endif
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#!/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(simulator => 1);
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ['--assert'],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2020 by Peter Monsson.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
|
||||
input clk;
|
||||
integer cyc; initial cyc=1;
|
||||
wire [31:0] in = cyc;
|
||||
|
||||
Test test (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.in (in[31:0]));
|
||||
|
||||
Test2 test2 (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.in (in[31:0]));
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (cyc!=0) begin
|
||||
cyc <= cyc + 1;
|
||||
if (cyc==10) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module Test (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk, in
|
||||
);
|
||||
|
||||
input clk;
|
||||
input [31:0] in;
|
||||
|
||||
reg [31:0] dly0 = 0;
|
||||
|
||||
// If called in an assertion, sequence, or property, the appropriate clocking event.
|
||||
// Otherwise, if called in a disable condition or a clock expression in an assertion, sequence, or prop, explicit.
|
||||
// Otherwise, if called in an action block of an assertion, the leading clock of the assertion is used.
|
||||
// Otherwise, if called in a procedure, the inferred clock
|
||||
// Otherwise, default clocking
|
||||
|
||||
always @(posedge clk) begin
|
||||
dly0 <= in;
|
||||
// In clock expression
|
||||
$write("in=%0d, dly0=%0d, rose=%0d, past=%0d\n", in, dly0, $rose(dly0), $past(dly0));
|
||||
if ($rose(dly0[4])) $stop;
|
||||
end
|
||||
|
||||
assert property (@(posedge clk) $rose(dly0) || dly0%2==0);
|
||||
endmodule
|
||||
|
||||
|
||||
module Test2 (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk, in
|
||||
);
|
||||
|
||||
input clk;
|
||||
input [31:0] in;
|
||||
|
||||
reg [31:0] dly0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
dly0 <= in;
|
||||
if ($rose(dly0[31:4])) $stop;
|
||||
end
|
||||
|
||||
default clocking @(posedge clk); endclocking
|
||||
assert property ($rose(dly0[0]) || dly0%2==0);
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2020 by Edgar E. Iglesias.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
#include VM_PREFIX_INCLUDE
|
||||
#include "Vt_sc_names.h"
|
||||
|
||||
VM_PREFIX* tb = NULL;
|
||||
|
||||
int sc_main(int argc, char* argv[]) {
|
||||
tb = new VM_PREFIX("tb");
|
||||
std::vector < sc_object* > ch = tb->get_child_objects();
|
||||
bool found = false;
|
||||
|
||||
/* We expect to find clk in here. */
|
||||
for (int i = 0; i < ch.size(); ++i) {
|
||||
if (!strcmp(ch[i]->basename(), "clk")) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
VL_PRINTF("*-* All Finished *-*\n");
|
||||
tb->final();
|
||||
} else {
|
||||
vl_fatal(__FILE__, __LINE__, "tb", "Unexpected results\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2020 by Edgar E. Iglesias. 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
if (!$Self->have_sc) {
|
||||
skip("No SystemC installed");
|
||||
}
|
||||
else {
|
||||
top_filename("t/t_sc_names.v");
|
||||
|
||||
compile(
|
||||
make_main => 0,
|
||||
verilator_flags2 => ["-sc --exe $Self->{t_dir}/t_sc_names.cpp"],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
}
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2020 by Edgar E. Iglesias.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t (
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#!/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(simulator => 1);
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ['--assert'],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2020 by Peter Monsson.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
|
||||
input clk;
|
||||
integer cyc; initial cyc=1;
|
||||
wire [31:0] in = cyc;
|
||||
|
||||
Test test (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.in (in[31:0]));
|
||||
|
||||
Test2 test2 (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.in (in[31:0]));
|
||||
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (cyc!=0) begin
|
||||
cyc <= cyc + 1;
|
||||
if (cyc==10) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module Test (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk, in
|
||||
);
|
||||
|
||||
input clk;
|
||||
input [31:0] in;
|
||||
|
||||
reg [31:0] dly0 = -1;
|
||||
|
||||
// If called in an assertion, sequence, or property, the appropriate clocking event.
|
||||
// Otherwise, if called in a disable condition or a clock expression in an assertion, sequence, or prop, explicit.
|
||||
// Otherwise, if called in an action block of an assertion, the leading clock of the assertion is used.
|
||||
// Otherwise, if called in a procedure, the inferred clock
|
||||
// Otherwise, default clocking
|
||||
|
||||
always @(posedge clk) begin
|
||||
dly0 <= in;
|
||||
// In clock expression
|
||||
$write("dly0=%0d, in=%0d, stable=%0d, past=%0d\n", dly0, in, $stable(dly0), $past(dly0));
|
||||
if ($stable(dly0)) $stop;
|
||||
end
|
||||
|
||||
assert property (@(posedge clk) !$stable(dly0));
|
||||
endmodule
|
||||
|
||||
module Test2 (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk, in
|
||||
);
|
||||
|
||||
input clk;
|
||||
input [31:0] in;
|
||||
|
||||
reg [31:0] dly0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
dly0 <= in;
|
||||
if (!$stable(dly0[31:4])) $stop;
|
||||
end
|
||||
|
||||
default clocking @(posedge clk); endclocking
|
||||
assert property ($stable(dly0[31:4]));
|
||||
endmodule
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
`define STRINGIFY(x) `"x`"
|
||||
`define ratio_error(a,b) (((a)>(b) ? ((a)-(b)) : ((b)-(a))) /(a))
|
||||
`define checkr(gotv,expv) do if (`ratio_error((gotv),(expv))>0.0001) begin $write("%%Error: %s:%0d: got=%g exp=%g\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
|
||||
`define checkr(gotv,expv) do if (`ratio_error((gotv),(expv))>0.0001) begin $write("%%Error: %s:%0d: got=%f exp=%f\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
|
||||
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
|
||||
`define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ module t (/*AUTOARG*/
|
|||
input clk;
|
||||
|
||||
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
|
||||
`define checkr(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got=%g exp=%g\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
|
||||
`define checkr(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got=%f exp=%f\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
|
||||
|
||||
// IEEE: integer_atom_type
|
||||
wire byte w_byte;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,200 @@
|
|||
<?xml version="1.0" ?>
|
||||
<!-- DESCRIPTION: Verilator output: XML representation of netlist -->
|
||||
<verilator_xml>
|
||||
<files>
|
||||
<file id="a" filename="<built-in>" language="1800-2017"/>
|
||||
<file id="b" filename="<command-line>" language="1800-2017"/>
|
||||
<file id="c" filename="input.vc" language="1800-2017"/>
|
||||
<file id="d" filename="t/t_xml_flat_vlvbound.v" language="1800-2017"/>
|
||||
</files>
|
||||
<module_files>
|
||||
<file id="d" filename="t/t_xml_flat_vlvbound.v" language="1800-2017"/>
|
||||
</module_files>
|
||||
<cells>
|
||||
<cell fl="d7" loc="d,7,8,7,21" name="TOP" submodname="TOP" hier="TOP"/>
|
||||
</cells>
|
||||
<netlist>
|
||||
<module fl="d7" loc="d,7,8,7,21" name="TOP" origName="TOP" topModule="1" public="true">
|
||||
<var fl="d9" loc="d,9,25,9,28" name="i_a" dtype_id="1" dir="input" vartype="logic" origName="i_a" public="true"/>
|
||||
<var fl="d10" loc="d,10,25,10,28" name="i_b" dtype_id="1" dir="input" vartype="logic" origName="i_b" public="true"/>
|
||||
<var fl="d11" loc="d,11,25,11,28" name="o_a" dtype_id="2" dir="output" vartype="logic" origName="o_a" public="true"/>
|
||||
<var fl="d12" loc="d,12,25,12,28" name="o_b" dtype_id="2" dir="output" vartype="logic" origName="o_b" public="true"/>
|
||||
<var fl="d9" loc="d,9,25,9,28" name="vlvbound_test.i_a" dtype_id="1" vartype="logic" origName="i_a"/>
|
||||
<var fl="d10" loc="d,10,25,10,28" name="vlvbound_test.i_b" dtype_id="1" vartype="logic" origName="i_b"/>
|
||||
<var fl="d11" loc="d,11,25,11,28" name="vlvbound_test.o_a" dtype_id="2" vartype="logic" origName="o_a"/>
|
||||
<var fl="d12" loc="d,12,25,12,28" name="vlvbound_test.o_b" dtype_id="2" vartype="logic" origName="o_b"/>
|
||||
<topscope fl="d7" loc="d,7,8,7,21">
|
||||
<scope fl="d7" loc="d,7,8,7,21" name="TOP">
|
||||
<varscope fl="d9" loc="d,9,25,9,28" name="i_a" dtype_id="1"/>
|
||||
<varscope fl="d10" loc="d,10,25,10,28" name="i_b" dtype_id="1"/>
|
||||
<varscope fl="d11" loc="d,11,25,11,28" name="o_a" dtype_id="2"/>
|
||||
<varscope fl="d12" loc="d,12,25,12,28" name="o_b" dtype_id="2"/>
|
||||
<varscope fl="d9" loc="d,9,25,9,28" name="vlvbound_test.i_a" dtype_id="1"/>
|
||||
<varscope fl="d10" loc="d,10,25,10,28" name="vlvbound_test.i_b" dtype_id="1"/>
|
||||
<varscope fl="d11" loc="d,11,25,11,28" name="vlvbound_test.o_a" dtype_id="2"/>
|
||||
<varscope fl="d12" loc="d,12,25,12,28" name="vlvbound_test.o_b" dtype_id="2"/>
|
||||
<varscope fl="d15" loc="d,15,34,15,37" name="__Vfunc_vlvbound_test.foo__0__Vfuncout" dtype_id="2"/>
|
||||
<varscope fl="d15" loc="d,15,57,15,60" name="__Vfunc_vlvbound_test.foo__0__val" dtype_id="1"/>
|
||||
<varscope fl="d16" loc="d,16,17,16,20" name="__Vfunc_vlvbound_test.foo__0__ret" dtype_id="2"/>
|
||||
<varscope fl="d17" loc="d,17,13,17,14" name="__Vfunc_vlvbound_test.foo__0__i" dtype_id="3"/>
|
||||
<varscope fl="d15" loc="d,15,34,15,37" name="__Vfunc_vlvbound_test.foo__1__Vfuncout" dtype_id="2"/>
|
||||
<varscope fl="d15" loc="d,15,57,15,60" name="__Vfunc_vlvbound_test.foo__1__val" dtype_id="1"/>
|
||||
<varscope fl="d16" loc="d,16,17,16,20" name="__Vfunc_vlvbound_test.foo__1__ret" dtype_id="2"/>
|
||||
<varscope fl="d17" loc="d,17,13,17,14" name="__Vfunc_vlvbound_test.foo__1__i" dtype_id="3"/>
|
||||
<assignalias fl="d9" loc="d,9,25,9,28" dtype_id="1">
|
||||
<varref fl="d9" loc="d,9,25,9,28" name="i_a" dtype_id="1"/>
|
||||
<varref fl="d9" loc="d,9,25,9,28" name="i_a" dtype_id="1"/>
|
||||
</assignalias>
|
||||
<assignalias fl="d10" loc="d,10,25,10,28" dtype_id="1">
|
||||
<varref fl="d10" loc="d,10,25,10,28" name="i_b" dtype_id="1"/>
|
||||
<varref fl="d10" loc="d,10,25,10,28" name="i_b" dtype_id="1"/>
|
||||
</assignalias>
|
||||
<assignalias fl="d11" loc="d,11,25,11,28" dtype_id="2">
|
||||
<varref fl="d11" loc="d,11,25,11,28" name="o_a" dtype_id="2"/>
|
||||
<varref fl="d11" loc="d,11,25,11,28" name="o_a" dtype_id="2"/>
|
||||
</assignalias>
|
||||
<assignalias fl="d12" loc="d,12,25,12,28" dtype_id="2">
|
||||
<varref fl="d12" loc="d,12,25,12,28" name="o_b" dtype_id="2"/>
|
||||
<varref fl="d12" loc="d,12,25,12,28" name="o_b" dtype_id="2"/>
|
||||
</assignalias>
|
||||
<always fl="d24" loc="d,24,14,24,15">
|
||||
<comment fl="d24" loc="d,24,16,24,19" name="Function: foo"/>
|
||||
<assign fl="d24" loc="d,24,20,24,23" dtype_id="1">
|
||||
<varref fl="d24" loc="d,24,20,24,23" name="i_a" dtype_id="1"/>
|
||||
<varref fl="d15" loc="d,15,57,15,60" name="__Vfunc_vlvbound_test.foo__0__val" dtype_id="1"/>
|
||||
</assign>
|
||||
<assign fl="d18" loc="d,18,11,18,12" dtype_id="3">
|
||||
<const fl="d18" loc="d,18,12,18,13" name="32'sh0" dtype_id="4"/>
|
||||
<varref fl="d18" loc="d,18,10,18,11" name="__Vfunc_vlvbound_test.foo__0__i" dtype_id="3"/>
|
||||
</assign>
|
||||
<while fl="d18" loc="d,18,5,18,8">
|
||||
<gts fl="d18" loc="d,18,18,18,19" dtype_id="5">
|
||||
<const fl="d18" loc="d,18,20,18,21" name="32'sh7" dtype_id="4"/>
|
||||
<varref fl="d18" loc="d,18,16,18,17" name="__Vfunc_vlvbound_test.foo__0__i" dtype_id="3"/>
|
||||
</gts>
|
||||
<assign fl="d19" loc="d,19,14,19,15" dtype_id="6">
|
||||
<eq fl="d19" loc="d,19,31,19,33" dtype_id="6">
|
||||
<const fl="d19" loc="d,19,34,19,39" name="2'h0" dtype_id="7"/>
|
||||
<sel fl="d19" loc="d,19,20,19,21" dtype_id="7">
|
||||
<varref fl="d19" loc="d,19,17,19,20" name="__Vfunc_vlvbound_test.foo__0__val" dtype_id="1"/>
|
||||
<sel fl="d19" loc="d,19,22,19,23" dtype_id="8">
|
||||
<muls fl="d19" loc="d,19,22,19,23" dtype_id="4">
|
||||
<const fl="d19" loc="d,19,23,19,24" name="32'sh2" dtype_id="4"/>
|
||||
<varref fl="d19" loc="d,19,21,19,22" name="__Vfunc_vlvbound_test.foo__0__i" dtype_id="3"/>
|
||||
</muls>
|
||||
<const fl="d19" loc="d,19,22,19,23" name="32'h0" dtype_id="9"/>
|
||||
<const fl="d19" loc="d,19,22,19,23" name="32'h4" dtype_id="9"/>
|
||||
</sel>
|
||||
<const fl="d19" loc="d,19,28,19,29" name="32'sh2" dtype_id="4"/>
|
||||
</sel>
|
||||
</eq>
|
||||
<sel fl="d19" loc="d,19,10,19,11" dtype_id="6">
|
||||
<varref fl="d19" loc="d,19,7,19,10" name="__Vfunc_vlvbound_test.foo__0__ret" dtype_id="2"/>
|
||||
<sel fl="d19" loc="d,19,11,19,12" dtype_id="10">
|
||||
<varref fl="d19" loc="d,19,11,19,12" name="__Vfunc_vlvbound_test.foo__0__i" dtype_id="3"/>
|
||||
<const fl="d19" loc="d,19,11,19,12" name="32'h0" dtype_id="9"/>
|
||||
<const fl="d19" loc="d,19,11,19,12" name="32'h3" dtype_id="9"/>
|
||||
</sel>
|
||||
<const fl="d19" loc="d,19,10,19,11" name="32'h1" dtype_id="9"/>
|
||||
</sel>
|
||||
</assign>
|
||||
<assign fl="d18" loc="d,18,24,18,26" dtype_id="3">
|
||||
<add fl="d18" loc="d,18,24,18,26" dtype_id="9">
|
||||
<const fl="d18" loc="d,18,24,18,26" name="32'h1" dtype_id="9"/>
|
||||
<varref fl="d18" loc="d,18,23,18,24" name="__Vfunc_vlvbound_test.foo__0__i" dtype_id="3"/>
|
||||
</add>
|
||||
<varref fl="d18" loc="d,18,23,18,24" name="__Vfunc_vlvbound_test.foo__0__i" dtype_id="3"/>
|
||||
</assign>
|
||||
</while>
|
||||
<assign fl="d21" loc="d,21,5,21,11" dtype_id="2">
|
||||
<varref fl="d21" loc="d,21,12,21,15" name="__Vfunc_vlvbound_test.foo__0__ret" dtype_id="2"/>
|
||||
<varref fl="d21" loc="d,21,5,21,11" name="__Vfunc_vlvbound_test.foo__0__Vfuncout" dtype_id="2"/>
|
||||
</assign>
|
||||
<assign fl="d24" loc="d,24,14,24,15" dtype_id="2">
|
||||
<varref fl="d24" loc="d,24,16,24,19" name="__Vfunc_vlvbound_test.foo__0__Vfuncout" dtype_id="2"/>
|
||||
<varref fl="d24" loc="d,24,10,24,13" name="o_a" dtype_id="2"/>
|
||||
</assign>
|
||||
</always>
|
||||
<always fl="d25" loc="d,25,14,25,15">
|
||||
<comment fl="d25" loc="d,25,16,25,19" name="Function: foo"/>
|
||||
<assign fl="d25" loc="d,25,20,25,23" dtype_id="1">
|
||||
<varref fl="d25" loc="d,25,20,25,23" name="i_b" dtype_id="1"/>
|
||||
<varref fl="d15" loc="d,15,57,15,60" name="__Vfunc_vlvbound_test.foo__1__val" dtype_id="1"/>
|
||||
</assign>
|
||||
<assign fl="d18" loc="d,18,11,18,12" dtype_id="3">
|
||||
<const fl="d18" loc="d,18,12,18,13" name="32'sh0" dtype_id="4"/>
|
||||
<varref fl="d18" loc="d,18,10,18,11" name="__Vfunc_vlvbound_test.foo__1__i" dtype_id="3"/>
|
||||
</assign>
|
||||
<while fl="d18" loc="d,18,5,18,8">
|
||||
<gts fl="d18" loc="d,18,18,18,19" dtype_id="5">
|
||||
<const fl="d18" loc="d,18,20,18,21" name="32'sh7" dtype_id="4"/>
|
||||
<varref fl="d18" loc="d,18,16,18,17" name="__Vfunc_vlvbound_test.foo__1__i" dtype_id="3"/>
|
||||
</gts>
|
||||
<assign fl="d19" loc="d,19,14,19,15" dtype_id="6">
|
||||
<eq fl="d19" loc="d,19,31,19,33" dtype_id="6">
|
||||
<const fl="d19" loc="d,19,34,19,39" name="2'h0" dtype_id="7"/>
|
||||
<sel fl="d19" loc="d,19,20,19,21" dtype_id="7">
|
||||
<varref fl="d19" loc="d,19,17,19,20" name="__Vfunc_vlvbound_test.foo__1__val" dtype_id="1"/>
|
||||
<sel fl="d19" loc="d,19,22,19,23" dtype_id="8">
|
||||
<muls fl="d19" loc="d,19,22,19,23" dtype_id="4">
|
||||
<const fl="d19" loc="d,19,23,19,24" name="32'sh2" dtype_id="4"/>
|
||||
<varref fl="d19" loc="d,19,21,19,22" name="__Vfunc_vlvbound_test.foo__1__i" dtype_id="3"/>
|
||||
</muls>
|
||||
<const fl="d19" loc="d,19,22,19,23" name="32'h0" dtype_id="9"/>
|
||||
<const fl="d19" loc="d,19,22,19,23" name="32'h4" dtype_id="9"/>
|
||||
</sel>
|
||||
<const fl="d19" loc="d,19,28,19,29" name="32'sh2" dtype_id="4"/>
|
||||
</sel>
|
||||
</eq>
|
||||
<sel fl="d19" loc="d,19,10,19,11" dtype_id="6">
|
||||
<varref fl="d19" loc="d,19,7,19,10" name="__Vfunc_vlvbound_test.foo__1__ret" dtype_id="2"/>
|
||||
<sel fl="d19" loc="d,19,11,19,12" dtype_id="10">
|
||||
<varref fl="d19" loc="d,19,11,19,12" name="__Vfunc_vlvbound_test.foo__1__i" dtype_id="3"/>
|
||||
<const fl="d19" loc="d,19,11,19,12" name="32'h0" dtype_id="9"/>
|
||||
<const fl="d19" loc="d,19,11,19,12" name="32'h3" dtype_id="9"/>
|
||||
</sel>
|
||||
<const fl="d19" loc="d,19,10,19,11" name="32'h1" dtype_id="9"/>
|
||||
</sel>
|
||||
</assign>
|
||||
<assign fl="d18" loc="d,18,24,18,26" dtype_id="3">
|
||||
<add fl="d18" loc="d,18,24,18,26" dtype_id="9">
|
||||
<const fl="d18" loc="d,18,24,18,26" name="32'h1" dtype_id="9"/>
|
||||
<varref fl="d18" loc="d,18,23,18,24" name="__Vfunc_vlvbound_test.foo__1__i" dtype_id="3"/>
|
||||
</add>
|
||||
<varref fl="d18" loc="d,18,23,18,24" name="__Vfunc_vlvbound_test.foo__1__i" dtype_id="3"/>
|
||||
</assign>
|
||||
</while>
|
||||
<assign fl="d21" loc="d,21,5,21,11" dtype_id="2">
|
||||
<varref fl="d21" loc="d,21,12,21,15" name="__Vfunc_vlvbound_test.foo__1__ret" dtype_id="2"/>
|
||||
<varref fl="d21" loc="d,21,5,21,11" name="__Vfunc_vlvbound_test.foo__1__Vfuncout" dtype_id="2"/>
|
||||
</assign>
|
||||
<assign fl="d25" loc="d,25,14,25,15" dtype_id="2">
|
||||
<varref fl="d25" loc="d,25,16,25,19" name="__Vfunc_vlvbound_test.foo__1__Vfuncout" dtype_id="2"/>
|
||||
<varref fl="d25" loc="d,25,10,25,13" name="o_b" dtype_id="2"/>
|
||||
</assign>
|
||||
</always>
|
||||
</scope>
|
||||
</topscope>
|
||||
<var fl="d15" loc="d,15,34,15,37" name="__Vfunc_vlvbound_test.foo__0__Vfuncout" dtype_id="2" vartype="logic" origName="__Vfunc_vlvbound_test__DOT__foo__0__Vfuncout"/>
|
||||
<var fl="d15" loc="d,15,57,15,60" name="__Vfunc_vlvbound_test.foo__0__val" dtype_id="1" vartype="logic" origName="__Vfunc_vlvbound_test__DOT__foo__0__val"/>
|
||||
<var fl="d16" loc="d,16,17,16,20" name="__Vfunc_vlvbound_test.foo__0__ret" dtype_id="2" vartype="logic" origName="__Vfunc_vlvbound_test__DOT__foo__0__ret"/>
|
||||
<var fl="d17" loc="d,17,13,17,14" name="__Vfunc_vlvbound_test.foo__0__i" dtype_id="3" vartype="integer" origName="__Vfunc_vlvbound_test__DOT__foo__0__i"/>
|
||||
<var fl="d15" loc="d,15,34,15,37" name="__Vfunc_vlvbound_test.foo__1__Vfuncout" dtype_id="2" vartype="logic" origName="__Vfunc_vlvbound_test__DOT__foo__1__Vfuncout"/>
|
||||
<var fl="d15" loc="d,15,57,15,60" name="__Vfunc_vlvbound_test.foo__1__val" dtype_id="1" vartype="logic" origName="__Vfunc_vlvbound_test__DOT__foo__1__val"/>
|
||||
<var fl="d16" loc="d,16,17,16,20" name="__Vfunc_vlvbound_test.foo__1__ret" dtype_id="2" vartype="logic" origName="__Vfunc_vlvbound_test__DOT__foo__1__ret"/>
|
||||
<var fl="d17" loc="d,17,13,17,14" name="__Vfunc_vlvbound_test.foo__1__i" dtype_id="3" vartype="integer" origName="__Vfunc_vlvbound_test__DOT__foo__1__i"/>
|
||||
</module>
|
||||
<typetable fl="a0" loc="a,0,0,0,0">
|
||||
<basicdtype fl="d18" loc="d,18,18,18,19" id="6" name="logic"/>
|
||||
<basicdtype fl="d19" loc="d,19,34,19,39" id="7" name="logic" left="1" right="0"/>
|
||||
<basicdtype fl="d9" loc="d,9,11,9,16" id="1" name="logic" left="15" right="0"/>
|
||||
<basicdtype fl="d11" loc="d,11,12,11,17" id="2" name="logic" left="6" right="0"/>
|
||||
<basicdtype fl="d17" loc="d,17,5,17,12" id="3" name="integer" left="31" right="0"/>
|
||||
<basicdtype fl="d19" loc="d,19,10,19,11" id="10" name="logic" left="2" right="0"/>
|
||||
<basicdtype fl="d19" loc="d,19,11,19,12" id="9" name="logic" left="31" right="0"/>
|
||||
<basicdtype fl="d19" loc="d,19,20,19,21" id="8" name="logic" left="3" right="0"/>
|
||||
<basicdtype fl="d18" loc="d,18,12,18,13" id="4" name="logic" left="31" right="0"/>
|
||||
<basicdtype fl="d18" loc="d,18,18,18,19" id="5" name="logic"/>
|
||||
</typetable>
|
||||
</netlist>
|
||||
</verilator_xml>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2012 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(vlt => 1);
|
||||
|
||||
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ['--xml-only', '--flatten'],
|
||||
verilator_make_gmake => 0,
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
);
|
||||
|
||||
files_identical("$out_filename", $Self->{golden_filename});
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2012 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module vlvbound_test
|
||||
(
|
||||
input logic [15:0] i_a,
|
||||
input logic [15:0] i_b,
|
||||
output logic [6:0] o_a,
|
||||
output logic [6:0] o_b
|
||||
);
|
||||
|
||||
function automatic logic [6:0] foo(input logic [15:0] val);
|
||||
logic [6:0] ret;
|
||||
integer i;
|
||||
for (i=0 ; i < 7; i++) begin
|
||||
ret[i] = (val[i*2 +: 2] == 2'b00);
|
||||
end
|
||||
return ret;
|
||||
endfunction
|
||||
|
||||
assign o_a = foo(i_a);
|
||||
assign o_b = foo(i_b);
|
||||
|
||||
endmodule
|
||||
Loading…
Reference in New Issue