Compare commits

...
14 Commits
52 changed files with 1191 additions and 108 deletions
+17
View File
@@ -3,6 +3,23 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. [by ...]
indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.847 2013-05-11
*** Add ALWCOMBORDER warning. [KC Buckenmaier]
*** Add --pins-sc-uint and --pins-sc-biguint, bug638. [Alex Hornung]
**** Support "signal[vec]++".
**** Fix simulation error when inputs and MULTIDRIVEN, bug634. [Ted Campbell]
**** Fix module resolution with __, bug631. [Jason McMullan]
**** Fix packed array non-zero right index select crash, bug642. [Krzysztof Jankowski]
**** Fix nested union crash, bug643. [Krzysztof Jankowski]
* Verilator 3.846 2013-03-09
** IEEE 1800-2012 is now the default language. This adds 4 new keywords
+38 -7
View File
@@ -302,6 +302,8 @@ descriptions in the next sections for more information.
--output-split <bytes> Split .cpp files into pieces
--output-split-cfuncs <statements> Split .ccp functions
--pins-bv <bits> Specify types for top level ports
--pins-sc-uint Specify types for top level ports
--pins-sc-biguint Specify types for top level ports
--pins-uint8 Specify types for top level ports
--pipe-filter <command> Filter all input through a script
--prefix <topname> Name of top level class
@@ -820,6 +822,20 @@ wide should use sc_bv's instead of uint32/vluint64_t's. The default is
33". The more sc_bv is used, the worse for performance. Use the
"/*verilator sc_bv*/" attribute to select specific ports to be sc_bv.
=item --pins-sc-uint
Specifies SystemC inputs/outputs of greater than 2 bits wide should use
sc_uint between 2 and 64. When combined with the "--pins-sc-biguint"
combination, it results in sc_uint being used between 2 and 64 and
sc_biguint being used between 65 and 512.
=item --pins-sc-biguint
Specifies SystemC inputs/outputs of greater than 65 bits wide should use
sc_biguint between 65 and 512, and sc_bv from 513 upwards. When combined
with the "--pins-sc-uint" combination, it results in sc_uint being used
between 2 and 64 and sc_biguint being used between 65 and 512.
=item --pins-uint8
Specifies SystemC inputs/outputs that are smaller than the --pins-bv
@@ -1052,10 +1068,10 @@ Disable the specified warning message.
=item -Wno-lint
Disable all lint related warning messages, and all style warnings. This is
equivalent to "-Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX
-Wno-CASEWITHX -Wno-CMPCONST -Wno-ENDLABEL -Wno-IMPLICIT -Wno-LITENDIAN
-Wno-PINMISSING -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNSIGNED -Wno-UNUSED
-Wno-WIDTH" plus the list shown for Wno-style.
equivalent to "-Wno-ALWCOMBORDER -Wno-CASEINCOMPLETE -Wno-CASEOVERLAP
-Wno-CASEX -Wno-CASEWITHX -Wno-CMPCONST -Wno-ENDLABEL -Wno-IMPLICIT
-Wno-LITENDIAN -Wno-PINMISSING -Wno-SYNCASYNCNET -Wno-UNDRIVEN
-Wno-UNSIGNED -Wno-UNUSED -Wno-WIDTH" plus the list shown for Wno-style.
It is strongly recommended you cleanup your code rather than using this
option, it is only intended to be use when running test-cases of code
@@ -1084,9 +1100,10 @@ Enables the specified warning message.
Enable all lint related warning messages (note by default they are already
enabled), but do not affect style messages. This is equivalent to
"-Wwarn-CASEINCOMPLETE -Wwarn-CASEOVERLAP -Wwarn-CASEX -Wwarn-CASEWITHX
-Wwarn-CMPCONST -Wwarn-ENDLABEL -Wwarn-IMPLICIT -Wwarn-LITENDIAN
-Wwarn-PINMISSING -Wwarn-REALCVT -Wwarn-UNSIGNED -Wwarn-WIDTH".
"-Wwarn-ALWCOMBORDER -Wwarn-CASEINCOMPLETE -Wwarn-CASEOVERLAP -Wwarn-CASEX
-Wwarn-CASEWITHX -Wwarn-CMPCONST -Wwarn-ENDLABEL -Wwarn-IMPLICIT
-Wwarn-LITENDIAN -Wwarn-PINMISSING -Wwarn-REALCVT -Wwarn-UNSIGNED
-Wwarn-WIDTH".
=item -Wwarn-style
@@ -2698,6 +2715,20 @@ List of all warnings:
=over 4
=item ALWCOMBORDER
Warns that an always_comb block has a variable which is set after it is
used. This may cause simulation-synthesis mismatches, as not all
commercial simulators allow this ordering.
always_comb begin
a = b;
b = 1;
end
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item ASSIGNIN
Error that an assignment is being made to an input signal. This is almost
+1 -1
View File
@@ -6,7 +6,7 @@
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[3.846 2013-03-09])
AC_INIT([Verilator],[3.847 2013-05-11])
AC_CONFIG_HEADER(src/config_build.h)
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h)
+4
View File
@@ -1075,6 +1075,10 @@ const char* Verilated::commandArgsPlusMatch(const char* prefixp) {
return VerilatedImp::argPlusMatch(prefixp).c_str();
}
void Verilated::internalsDump() {
VerilatedImp::internalsDump();
}
void Verilated::scopesDump() {
VerilatedImp::scopesDump();
}
+34
View File
@@ -294,6 +294,11 @@ public:
static const char* productName() { return VERILATOR_PRODUCT; }
static const char* productVersion() { return VERILATOR_VERSION; }
/// For debugging, print much of the Verilator internal state.
/// The output of this function may change in future
/// releases - contact the authors before production use.
static void internalsDump();
/// For debugging, print text list of all scope names with
/// dpiImport/Export context. This function may change in future
/// releases - contact the authors before production use.
@@ -547,6 +552,7 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
//===================================================================
// SYSTEMC OPERATORS
// Copying verilog format to systemc integers and bit vectors.
// Get a SystemC variable
#define VL_ASSIGN_ISI(obits,vvar,svar) { (vvar) = VL_CLEAN_II((obits),(obits),(svar).read()); }
#define VL_ASSIGN_QSQ(obits,vvar,svar) { (vvar) = VL_CLEAN_QQ((obits),(obits),(svar).read()); }
@@ -564,7 +570,21 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
owp[words-1] &= VL_MASK_I(obits); \
}
#define VL_ASSIGN_ISU(obits,vvar,svar) { (vvar) = VL_CLEAN_II((obits),(obits),(svar).read().to_uint()); }
#define VL_ASSIGN_QSU(obits,vvar,svar) { (vvar) = VL_CLEAN_QQ((obits),(obits),(svar).read().to_uint64()); }
#define VL_ASSIGN_WSB(obits,owp,svar) { \
int words = VL_WORDS_I(obits); \
sc_biguint<obits> _butemp = (svar).read(); \
for (int i=0; i < words; i++) { \
int msb = ((i+1)*VL_WORDSIZE) - 1; \
msb = (msb >= obits) ? (obits-1) : msb; \
owp[i] = _butemp.range(msb,i*VL_WORDSIZE).to_uint(); \
} \
owp[words-1] &= VL_MASK_I(obits); \
}
// Copying verilog format from systemc integers and bit vectors.
// Set a SystemC variable
#define VL_ASSIGN_SII(obits,svar,vvar) { (svar).write(vvar); }
#define VL_ASSIGN_SQQ(obits,svar,vvar) { (svar).write(vvar); }
@@ -586,6 +606,20 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
svar.write(_bvtemp); \
}
#define VL_ASSIGN_SUI(obits,svar,rd) { (svar).write(rd); }
#define VL_ASSIGN_SUQ(obits,svar,rd) { (svar).write(rd); }
#define VL_ASSIGN_SBI(obits,svar,rd) { (svar).write(rd); }
#define VL_ASSIGN_SBQ(obits,svar,rd) { (svar).write(rd); }
#define VL_ASSIGN_SBW(obits,svar,rwp) { \
sc_biguint<obits> _butemp; \
for (int i=0; i < VL_WORDS_I(obits); i++) { \
int msb = ((i+1)*VL_WORDSIZE) - 1; \
msb = (msb >= obits) ? (obits-1) : msb; \
_butemp.range(msb,i*VL_WORDSIZE) = rwp[i]; \
} \
svar.write(_butemp); \
}
//===================================================================
// Extending sizes
+28 -2
View File
@@ -78,6 +78,18 @@ public: // But only for verilated*.cpp
m_fdps[2] = stderr;
}
~VerilatedImp() {}
static void internalsDump() {
VL_PRINTF("internalsDump:\n");
VL_PRINTF(" Argv:");
for (ArgVec::iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) {
VL_PRINTF(" %s",it->c_str());
}
VL_PRINTF("\n");
VL_PRINTF(" Version: %s %s\n", Verilated::productName(), Verilated::productVersion());
scopesDump();
exportsDump();
userDump();
}
// METHODS - arguments
static void commandArgs(int argc, const char** argv) {
@@ -129,6 +141,14 @@ private:
}
}
}
static void userDump() {
bool first = true;
for (UserMap::iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ++it) {
if (first) { VL_PRINTF(" userDump:\n"); first=false; }
VL_PRINTF(" DPI_USER_DATA scope %p key %p: %p\n",
it->first.first, it->first.second, it->second);
}
}
public: // But only for verilated*.cpp
// METHODS - scope name
@@ -150,9 +170,8 @@ public: // But only for verilated*.cpp
ScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
if (it != s_s.m_nameMap.end()) s_s.m_nameMap.erase(it);
}
static void scopesDump() {
VL_PRINTF("scopesDump:\n");
VL_PRINTF(" scopesDump:\n");
for (ScopeNameMap::iterator it=s_s.m_nameMap.begin(); it!=s_s.m_nameMap.end(); ++it) {
const VerilatedScope* scopep = it->second;
scopep->scopeDump();
@@ -194,6 +213,13 @@ public: // But only for verilated*.cpp
}
return "*UNKNOWN*";
}
static void exportsDump() {
bool first = true;
for (ExportNameMap::iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) {
if (first) { VL_PRINTF(" exportDump:\n"); first=false; }
VL_PRINTF(" DPI_EXPORT_NAME %05d: %s\n", it->second, it->first);
}
}
// We don't free up m_exportMap until the end, because we can't be sure
// what other models are using the assigned funcnum's.
+56 -5
View File
@@ -366,10 +366,8 @@ AST.
=head1 TESTING
To write a test see the BUGS section of the Verilator primary manual, and
the documentation in:
test_regress/t/driver.pl --help
For an overview of how to write a test see the BUGS section of the
Verilator primary manual.
It is important to add tests for failures as well as success (for example to
check that an error message is correctly triggered).
@@ -378,7 +376,60 @@ Tests that fail should by convenition have the suffix C<_bad> in their name,
and include C<fails =E<gt> 1> in either their C<compile> or C<execute> step as
appropriate.
Developers will also want to configure with two extra flags:
=head2 Controlling the Test Driver
Test drivers are written in PERL. All invoke the main test driver script,
which can provide detailed help on all the features available when writing
a test driver.
test_regress/t/driver.pl --help
For convenience, a summary of the most commonly used features is provided
here. All drivers require a call to C<compile> subroutine to compile the
test. For run-time tests, this is followed by a call to the C<execute>
subroutine. Both of these functions can optionally be provided with a hash
table as argument specifying additonal options.
The test driver assumes by default that the source Verilog file name
matches the PERL driver name. So a test whose driver is C<t/t_mytest.pl>
will expect a Verilog source file C<t/t_mytest.v>. This can be changed
using the C<top_filename> subroutine, for example
top_filename("t/t_myothertest.v");
By default all tests will run with major simulators (Icarus Verilog, NC,
VCS, ModelSim) as well as Verilator, to allow results to be
compared. However if you wish a test only to be used with Verilator, you
can use the following:
$Self->{vlt} or $Self->skip("Verilator only test");
Of the many options that can be set through arguments to C<compiler> and
C<execute>, the following are particularly useful:
=over 4
=item C<verilator_flags2>
A list of flags to be passed to verilator when compiling.
=item C<fails>
Set to 1 to indicate that the compilation or execution is intended to fail.
=back
For example the following would specify that compilation requires two
defines and is expected to fail.
compile (
verilator_flags2 => ["-DSMALL_CLOCK -DGATED_COMMENT"],
fails => 1,
);
=head2 Regression Testing for Developers
Developers will also want to call ./configure with two extra flags:
=over 4
+1
View File
@@ -137,6 +137,7 @@ private:
if (nodep->castPslAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
//
AstNode* newp = new AstAlways (nodep->fileline(),
VAlwaysKwd::ALWAYS,
sentreep,
bodysp);
// Install it
+24
View File
@@ -467,6 +467,30 @@ public:
//######################################################################
class VAlwaysKwd {
public:
enum en {
ALWAYS,
ALWAYS_FF,
ALWAYS_LATCH,
ALWAYS_COMB
};
enum en m_e;
inline VAlwaysKwd () : m_e(ALWAYS) {}
inline VAlwaysKwd (en _e) : m_e(_e) {}
explicit inline VAlwaysKwd (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
const char* ascii() const {
static const char* names[] = {
"always","always_ff","always_latch","always_comb"};
return names[m_e]; }
};
inline bool operator== (VAlwaysKwd lhs, VAlwaysKwd rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (VAlwaysKwd lhs, VAlwaysKwd::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (VAlwaysKwd::en lhs, VAlwaysKwd rhs) { return (lhs == rhs.m_e); }
//######################################################################
class AstCaseType {
public:
enum en {
+19 -2
View File
@@ -103,13 +103,21 @@ bool AstVar::isSigPublic() const {
}
bool AstVar::isScQuad() const {
return (isSc() && isQuad() && !isScBv());
return (isSc() && isQuad() && !isScBv() && !isScBigUint());
}
bool AstVar::isScBv() const {
return ((isSc() && width() >= v3Global.opt.pinsBv()) || m_attrScBv);
}
bool AstVar::isScUint() const {
return ((isSc() && v3Global.opt.pinsScUint() && width() >= 2 && width() <= 64) && !isScBv());
}
bool AstVar::isScBigUint() const {
return ((isSc() && v3Global.opt.pinsScBigUint() && width() >= 65 && width() <= 512) && !isScBv());
}
void AstVar::combineType(AstVarType type) {
// These flags get combined with the existing settings of the flags.
// We don't test varType for certain types, instead set flags since
@@ -278,7 +286,11 @@ string AstVar::dpiArgType(bool named, bool forReturn) const {
}
string AstVar::scType() const {
if (isScBv()) {
if (isScBigUint()) {
return (string("sc_biguint<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
} else if (isScUint()) {
return (string("sc_uint<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
} else if (isScBv()) {
return (string("sc_bv<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
} else if (widthMin() == 1) {
return "bool";
@@ -665,6 +677,11 @@ void AstNode::dump(ostream& str) {
if (name()!="") str<<" "<<AstNode::quoteName(name());
}
void AstAlways::dump(ostream& str) {
this->AstNode::dump(str);
if (keyword() != VAlwaysKwd::ALWAYS) str<<" ["<<keyword().ascii()<<"]";
}
void AstArraySel::dump(ostream& str) {
this->AstNode::dump(str);
str<<" [start:"<<start()<<"] [length:"<<length()<<"]";
+9 -3
View File
@@ -979,6 +979,8 @@ public:
bool isSc() const { return m_sc; }
bool isScQuad() const;
bool isScBv() const;
bool isScUint() const;
bool isScBigUint() const;
bool isScSensitive() const { return m_scSensitive; }
bool isSigPublic() const;
bool isSigModPublic() const { return m_sigModPublic; }
@@ -1621,15 +1623,19 @@ public:
};
struct AstAlways : public AstNode {
AstAlways(FileLine* fl, AstSenTree* sensesp, AstNode* bodysp)
: AstNode(fl) {
VAlwaysKwd m_keyword;
public:
AstAlways(FileLine* fl, VAlwaysKwd keyword, AstSenTree* sensesp, AstNode* bodysp)
: AstNode(fl), m_keyword(keyword) {
addNOp1p(sensesp); addNOp2p(bodysp);
}
ASTNODE_NODE_FUNCS(Always, ALWAYS)
//
virtual void dump(ostream& str);
AstSenTree* sensesp() const { return op1p()->castSenTree(); } // op1 = Sensitivity list
AstNode* bodysp() const { return op2p()->castNode(); } // op2 = Statements to evaluate
void addStmtp(AstNode* nodep) { addOp2p(nodep); }
VAlwaysKwd keyword() const { return m_keyword; }
// Special accessors
bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); }
};
@@ -1700,7 +1706,7 @@ struct AstAssignW : public AstNodeAssign {
AstAlways* convertToAlways() {
AstNode* lhs1p = lhsp()->unlinkFrBack();
AstNode* rhs1p = rhsp()->unlinkFrBack();
AstAlways* newp = new AstAlways (fileline(), NULL,
AstAlways* newp = new AstAlways (fileline(), VAlwaysKwd::ALWAYS, NULL,
new AstAssign (fileline(), lhs1p, rhs1p));
replaceWith(newp); // User expected to then deleteTree();
return newp;
+1
View File
@@ -684,6 +684,7 @@ class GaterVisitor : public GaterBaseVisitor {
AstNode* bodyp = nodep->bodysp()->cloneTree(true);
AstAlways* alwp = new AstAlways(nodep->fileline(),
nodep->keyword(),
sensesp,
bodyp);
+27 -6
View File
@@ -79,7 +79,10 @@ public:
puts (nodep->isWide()?"W":(nodep->isQuad()?"Q":"I"));
}
void emitScIQW(AstVar* nodep) {
puts (nodep->isScBv()?"SW":(nodep->isScQuad()?"SQ":"SI"));
puts (nodep->isScBigUint() ? "SB"
: nodep->isScUint() ? "SU"
: nodep->isScBv() ? "SW"
: (nodep->isScQuad() ? "SQ" : "SI"));
}
void emitOpName(AstNode* nodep, const string& format,
AstNode* lhsp, AstNode* rhsp, AstNode* thsp);
@@ -1699,7 +1702,7 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
if (varp->isUsedClock() && varp->widthMin()==1) sortbytes = 0;
else if (varp->dtypeSkipRefp()->castUnpackArrayDType()) sortbytes=8;
else if (varp->basicp() && varp->basicp()->isOpaque()) sortbytes=7;
else if (varp->isScBv()) sortbytes=6;
else if (varp->isScBv() || varp->isScBigUint()) sortbytes=6;
else if (sigbytes==8) sortbytes=5;
else if (sigbytes==4) sortbytes=4;
else if (sigbytes==2) sortbytes=2;
@@ -2172,6 +2175,21 @@ class EmitCTrace : EmitCStmts {
AstVar* varp = varrefp->varp();
return varp->isSc() && varp->isScBv();
}
bool emitTraceIsScBigUint(AstTraceInc* nodep) {
AstVarRef* varrefp = nodep->valuep()->castVarRef();
if (!varrefp) return false;
AstVar* varp = varrefp->varp();
return varp->isSc() && varp->isScBigUint();
}
bool emitTraceIsScUint(AstTraceInc* nodep) {
AstVarRef* varrefp = nodep->valuep()->castVarRef();
if (!varrefp) return false;
AstVar* varp = varrefp->varp();
return varp->isSc() && varp->isScUint();
}
void emitTraceInitOne(AstTraceDecl* nodep) {
if (nodep->isDouble()) {
puts("vcdp->declDouble");
@@ -2207,7 +2225,7 @@ class EmitCTrace : EmitCStmts {
? "full":"chg");
if (nodep->isDouble()) {
puts("vcdp->"+full+"Double");
} else if (nodep->isWide() || emitTraceIsScBv(nodep)) {
} else if (nodep->isWide() || emitTraceIsScBv(nodep) || emitTraceIsScBigUint(nodep)) {
puts("vcdp->"+full+"Array");
} else if (nodep->isQuad()) {
puts("vcdp->"+full+"Quad ");
@@ -2221,7 +2239,7 @@ class EmitCTrace : EmitCStmts {
puts(",");
emitTraceValue(nodep, arrayindex);
if (!nodep->isDouble() // When float/double no longer have widths this can go
&& (nodep->declp()->left() || nodep->declp()->right() || emitTraceIsScBv(nodep))) {
&& (nodep->declp()->left() || nodep->declp()->right() || emitTraceIsScBv(nodep) || emitTraceIsScBigUint(nodep))) {
puts(","+cvtToStr(nodep->declp()->widthMin()));
}
puts(");\n");
@@ -2231,7 +2249,8 @@ class EmitCTrace : EmitCStmts {
AstVarRef* varrefp = nodep->valuep()->castVarRef();
AstVar* varp = varrefp->varp();
puts("(");
if (emitTraceIsScBv(nodep)) puts("VL_SC_BV_DATAP(");
if (emitTraceIsScBigUint(nodep)) puts("(vluint32_t*)");
else if (emitTraceIsScBv(nodep)) puts("VL_SC_BV_DATAP(");
varrefp->iterate(*this); // Put var name out
// Tracing only supports 1D arrays
if (varp->dtypeSkipRefp()->castUnpackArrayDType()) {
@@ -2240,7 +2259,9 @@ class EmitCTrace : EmitCStmts {
else puts("["+cvtToStr(arrayindex)+"]");
}
if (varp->isSc()) puts(".read()");
if (emitTraceIsScBv(nodep)) puts(")");
if (emitTraceIsScUint(nodep)) puts(nodep->isQuad() ? ".to_uint64()" : ".to_uint()");
else if (emitTraceIsScBigUint(nodep)) puts(".get_raw()");
else if (emitTraceIsScBv(nodep)) puts(")");
puts(")");
} else {
puts("(");
+1 -1
View File
@@ -102,7 +102,7 @@ class EmitCSyms : EmitCBaseVisitor {
if (rsvd != "") {
// Generally V3Name should find all of these and throw SYMRSVDWORD.
// We'll still check here because the compiler errors resulting if we miss this warning are SO nasty
nodep->v3error("Symbol matching "+rsvd+" reserved word reached emitter, should have hit SYMRSVDWORD: '"<<nodep->name()<<"'");
nodep->v3error("Symbol matching "+rsvd+" reserved word reached emitter, should have hit SYMRSVDWORD: '"<<nodep->prettyName()<<"'");
}
}
}
+4 -2
View File
@@ -57,6 +57,7 @@ public:
// Warning codes:
EC_FIRST_WARN, // Just a code so the program knows where to start warnings
//
ALWCOMBORDER, // Always_comb with unordered statements
ASSIGNDLY, // Assignment delays
ASSIGNIN, // Assigning to input
BLKANDNBLK, // Blocked and non-blocking assignments to same variable
@@ -116,7 +117,7 @@ public:
"BLKLOOPINIT", "DETECTARRAY", "MULTITOP", "TASKNSVAR",
// Warnings
" EC_FIRST_WARN",
"ASSIGNDLY", "ASSIGNIN",
"ALWCOMBORDER", "ASSIGNDLY", "ASSIGNIN",
"BLKANDNBLK", "BLKSEQ",
"CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CDCRSTLOGIC", "CMPCONST",
"COMBDLY", "DEFPARAM", "DECLFILENAME",
@@ -146,7 +147,8 @@ public:
bool mentionManual() const { return ( m_e==EC_FATALSRC || pretendError() ); }
// Warnings that are lint only
bool lintError() const { return ( m_e==CASEINCOMPLETE || m_e==CASEOVERLAP
bool lintError() const { return ( m_e==ALWCOMBORDER
|| m_e==CASEINCOMPLETE || m_e==CASEOVERLAP
|| m_e==CASEWITHX || m_e==CASEX
|| m_e==CMPCONST
|| m_e==ENDLABEL
+1
View File
@@ -64,6 +64,7 @@ class GateGraphBaseVisitor {
public:
virtual AstNUser* visit(GateLogicVertex* vertexp, AstNUser* vup=NULL) =0;
virtual AstNUser* visit(GateVarVertex* vertexp, AstNUser* vup=NULL) =0;
virtual ~GateGraphBaseVisitor() {}
};
//######################################################################
+2
View File
@@ -48,6 +48,8 @@ public:
struct V3HashedUserCheck {
// Functor for V3Hashed::findDuplicate
virtual bool check(AstNode*,AstNode*) =0;
V3HashedUserCheck() {}
virtual ~V3HashedUserCheck() {}
};
class V3Hashed : public VHashedBase {
+5 -4
View File
@@ -75,7 +75,7 @@ public:
void LinkCellsGraph::loopsMessageCb(V3GraphVertex* vertexp) {
if (LinkCellsVertex* vvertexp = dynamic_cast<LinkCellsVertex*>(vertexp)) {
vvertexp->modp()->v3error("Recursive module (module instantiates itself): "
<<vvertexp->modp()->name());
<<vvertexp->modp()->prettyName());
V3Error::abortIfErrors();
} else { // Everything should match above, but...
v3fatalSrc("Recursive instantiations");
@@ -128,8 +128,9 @@ private:
// Read-subfile
// If file not found, make AstNotFoundModule, rather than error out.
// We'll throw the error when we know the module will really be needed.
string prettyName = AstNode::prettyName(modName);
V3Parse parser (v3Global.rootp(), m_filterp, m_parseSymp);
parser.parseFile(nodep->fileline(), modName, false, "");
parser.parseFile(nodep->fileline(), prettyName, false, "");
V3Error::abortIfErrors();
// We've read new modules, grab new pointers to their names
readModNames();
@@ -137,7 +138,7 @@ private:
modp = m_mods.rootp()->findIdFallback(modName)->nodep()->castNodeModule();
if (!modp) {
// This shouldn't throw a message as parseFile will create a AstNotFoundModule for us
nodep->v3error("Can't resolve module reference: "<<modName);
nodep->v3error("Can't resolve module reference: "<<prettyName);
}
}
return modp;
@@ -189,7 +190,7 @@ private:
<<"' does not match "<<nodep->typeName()<<" name: "<<nodep->prettyName());
}
}
bool topMatch = (v3Global.opt.topModule()==nodep->name());
bool topMatch = (v3Global.opt.topModule()==nodep->prettyName());
if (topMatch) {
m_topVertexp = vertex(nodep);
UINFO(2,"Link --top-module: "<<nodep<<endl);
+3 -3
View File
@@ -698,7 +698,7 @@ private:
&& (!m_ftaskp || m_ftaskp != foundp->nodep()) // Not the function's variable hiding function
&& !nodep->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN)
&& !foundp->nodep()->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN)) {
nodep->v3warn(VARHIDDEN,"Declaration of signal hides declaration in upper scope: "<<nodep->name()<<endl
nodep->v3warn(VARHIDDEN,"Declaration of signal hides declaration in upper scope: "<<nodep->prettyName()<<endl
<<foundp->nodep()->warnMore()<<"... Location of original declaration");
}
ins = true;
@@ -744,7 +744,7 @@ private:
// User can disable the message at either point
if (!nodep->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN)
&& !foundp->nodep()->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN)) {
nodep->v3warn(VARHIDDEN,"Declaration of enum value hides declaration in upper scope: "<<nodep->name()<<endl
nodep->v3warn(VARHIDDEN,"Declaration of enum value hides declaration in upper scope: "<<nodep->prettyName()<<endl
<<foundp->nodep()->warnMore()<<"... Location of original declaration");
}
ins = true;
@@ -858,7 +858,7 @@ private:
}
virtual void visit(AstDefParam* nodep, AstNUser*) {
nodep->iterateChildren(*this);
nodep->v3warn(DEFPARAM,"Suggest replace defparam with Verilog 2001 #(."<<nodep->name()<<"(...etc...))");
nodep->v3warn(DEFPARAM,"Suggest replace defparam with Verilog 2001 #(."<<nodep->prettyName()<<"(...etc...))");
VSymEnt* foundp = m_statep->getNodeSym(nodep)->findIdFallback(nodep->path());
AstCell* cellp = foundp->nodep()->castCell();
if (!cellp) {
+1 -1
View File
@@ -227,7 +227,7 @@ private:
}
}
//if (debug()>=9) { UINFO(0,"\n"); beginp->dumpTree(cout," labeli: "); }
if (!beginp) { nodep->v3error("disable isn't underneath a begin with name: "<<nodep->name()); }
if (!beginp) { nodep->v3error("disable isn't underneath a begin with name: "<<nodep->prettyName()); }
else {
// Jump to the end of the named begin
AstJumpLabel* labelp = findAddLabel(beginp, false);
+1 -1
View File
@@ -66,7 +66,7 @@ private:
} else {
string rsvd = m_words.isKeyword(nodep->name());
if (rsvd != "") {
nodep->v3warn(SYMRSVDWORD,"Symbol matches "+rsvd+": '"<<nodep->name()<<"'");
nodep->v3warn(SYMRSVDWORD,"Symbol matches "+rsvd+": '"<<nodep->prettyName()<<"'");
string newname = (string)"__SYM__"+nodep->name();
nodep->name(newname);
}
+2
View File
@@ -737,6 +737,8 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if ( onoff (sw, "-lint-only", flag/*ref*/) ) { m_lintOnly = flag; }
else if ( !strcmp (sw, "-no-pins64") ) { m_pinsBv = 33; }
else if ( !strcmp (sw, "-pins64") ) { m_pinsBv = 65; }
else if ( onoff (sw, "-pins-sc-uint", flag/*ref*/) ){ m_pinsScUint = flag; if (!m_pinsScBigUint) m_pinsBv = 65; }
else if ( onoff (sw, "-pins-sc-biguint", flag/*ref*/) ){ m_pinsScBigUint = flag; m_pinsBv = 513; }
else if ( onoff (sw, "-pins-uint8", flag/*ref*/) ){ m_pinsUint8 = flag; }
else if ( !strcmp (sw, "-private") ) { m_public = false; }
else if ( onoff (sw, "-profile-cfuncs", flag/*ref*/) ) { m_profileCFuncs = flag; }
+4
View File
@@ -76,6 +76,8 @@ class V3Options {
bool m_lintOnly; // main switch: --lint-only
bool m_outFormatOk; // main switch: --cc, --sc or --sp was specified
bool m_warnFatal; // main switch: --warnFatal
bool m_pinsScUint; // main switch: --pins-sc-uint
bool m_pinsScBigUint;// main switch: --pins-sc-biguint
bool m_pinsUint8; // main switch: --pins-uint8
bool m_profileCFuncs;// main switch: --profile-cfuncs
bool m_psl; // main switch: --psl
@@ -215,6 +217,8 @@ class V3Options {
bool outFormatOk() const { return m_outFormatOk; }
bool keepTempFiles() const { return (V3Error::debugDefault()!=0); }
bool warnFatal() const { return m_warnFatal; }
bool pinsScUint() const { return m_pinsScUint; }
bool pinsScBigUint() const { return m_pinsScBigUint; }
bool pinsUint8() const { return m_pinsUint8; }
bool profileCFuncs() const { return m_profileCFuncs; }
bool psl() const { return m_psl; }
+37 -12
View File
@@ -375,8 +375,10 @@ private:
void processBrokeLoop();
#endif
void processCircular();
typedef deque<OrderEitherVertex*> VertexVec;
void processInputs();
void processInputsIterate(OrderEitherVertex* vertexp);
void processInputsInIterate(OrderEitherVertex* vertexp, VertexVec& todoVec);
void processInputsOutIterate(OrderEitherVertex* vertexp, VertexVec& todoVec);
void processSensitive();
void processDomains();
void processDomainsIterate(OrderEitherVertex* vertexp);
@@ -1059,28 +1061,33 @@ void OrderVisitor::processBrokeLoop() {
// Clock propagation
void OrderVisitor::processInputs() {
m_graph.userClearVertices(); // Vertex::user() // true if processed
m_graph.userClearVertices(); // Vertex::user() // 1 if input recursed, 2 if marked as input, 3 if out-edges recursed
// Start at input vertex, process from input-to-output order
VertexVec todoVec; // List of newly-input marked vectors we need to process
todoVec.push_front(m_inputsVxp);
m_inputsVxp->isFromInput(true); // By definition
processInputsIterate(m_inputsVxp);
while (!todoVec.empty()) {
OrderEitherVertex* vertexp = todoVec.back(); todoVec.pop_back();
processInputsOutIterate(vertexp, todoVec);
}
}
void OrderVisitor::processInputsIterate(OrderEitherVertex* vertexp) {
void OrderVisitor::processInputsInIterate(OrderEitherVertex* vertexp, VertexVec& todoVec) {
// Propagate PrimaryIn through simple assignments
if (vertexp->user()) return; // Already processed
if (0 && debug()>=9) {
UINFO(9," InIt "<<vertexp<<endl);
UINFO(9," InIIter "<<vertexp<<endl);
if (OrderLogicVertex* vvertexp = dynamic_cast<OrderLogicVertex*>(vertexp)) {
vvertexp->nodep()->dumpTree(cout,"- TT: ");
}
}
vertexp->user(true); // Processing
vertexp->user(1); // Processing
// First handle all inputs to this vertex, in most cases they'll be already processed earlier
// Also, determine if this vertex is an input
int inonly = 1; // 0=no, 1=maybe, 2=yes until a no
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep=edgep->inNextp()) {
OrderEitherVertex* frVertexp = (OrderEitherVertex*)edgep->fromp();
processInputsIterate(frVertexp);
processInputsInIterate(frVertexp, todoVec);
if (frVertexp->isFromInput()) {
if (inonly==1) inonly = 2;
} else if (dynamic_cast<OrderVarPostVertex*>(frVertexp)) {
@@ -1091,20 +1098,38 @@ void OrderVisitor::processInputsIterate(OrderEitherVertex* vertexp) {
break;
}
}
if (inonly == 2) { // Set it. Note may have already been set earlier, too
if (inonly == 2 && vertexp->user()<2) { // Set it. Note may have already been set earlier, too
UINFO(9," Input reassignment: "<<vertexp<<endl);
vertexp->isFromInput(true);
vertexp->user(2); // 2 means on list
// Can't work on out-edges of a node we know is an input immediately,
// as it might visit other nodes before their input state is resolved.
// So push to list and work on it later when all in-edges known resolved
todoVec.push_back(vertexp);
}
// If we're still an input, process all targets of this vertex
if (vertexp->isFromInput()) {
//UINFO(9," InIdone "<<vertexp<<endl);
}
void OrderVisitor::processInputsOutIterate(OrderEitherVertex* vertexp, VertexVec& todoVec) {
if (vertexp->user()==3) return; // Already out processed
//UINFO(9," InOIter "<<vertexp<<endl);
// First make sure input path is fully recursed
processInputsInIterate(vertexp, todoVec);
// Propagate PrimaryIn through simple assignments
if (!vertexp->isFromInput()) v3fatalSrc("processInputsOutIterate only for input marked vertexes");
vertexp->user(3); // out-edges processed
{
// Propagate PrimaryIn through simple assignments, followint target of vertex
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
OrderEitherVertex* toVertexp = (OrderEitherVertex*)edgep->top();
if (OrderVarStdVertex* vvertexp = dynamic_cast<OrderVarStdVertex*>(toVertexp)) {
processInputsIterate(vvertexp);
processInputsInIterate(vvertexp, todoVec);
}
if (OrderLogicVertex* vvertexp = dynamic_cast<OrderLogicVertex*>(toVertexp)) {
if (vvertexp->nodep()->castNodeAssign()) {
processInputsIterate(vvertexp);
processInputsInIterate(vvertexp, todoVec);
}
}
}
+1 -1
View File
@@ -416,7 +416,7 @@ private:
}
if (splitAlwaysp) {
++m_statSplits;
AstAlways* alwaysp = new AstAlways(newListp->fileline(), NULL, NULL);
AstAlways* alwaysp = new AstAlways(newListp->fileline(), VAlwaysKwd::ALWAYS, NULL, NULL);
addAfterp->addNextHere(alwaysp); addAfterp=alwaysp;
alwaysp->addStmtp(newListp);
} else {
+89 -27
View File
@@ -133,6 +133,17 @@ public:
}
}
}
bool isUsedNotDrivenBit (int bit, int width) const {
for (int i=0; i<width; i++) {
if (bitNumOk(bit+i)
&& (m_usedWhole || m_flags[(bit+i)*FLAGS_PER_BIT + FLAG_USED])
&& !(m_drivenWhole || m_flags[(bit+i)*FLAGS_PER_BIT + FLAG_DRIVEN])) return true;
}
return false;
}
bool isUsedNotDrivenAny () const {
return isUsedNotDrivenBit(0, m_flags.size()/FLAGS_PER_BIT);
}
bool unusedMatch(AstVar* nodep) {
const char* regexpp = v3Global.opt.unusedRegexp().c_str();
if (!regexpp || !*regexpp) return false;
@@ -213,11 +224,13 @@ private:
// NODE STATE
// AstVar::user1p -> UndrivenVar* for usage var, 0=not set yet
AstUser1InUse m_inuser1;
AstUser2InUse m_inuser2;
// STATE
vector<UndrivenVarEntry*> m_entryps; // Nodes to delete when we are finished
vector<UndrivenVarEntry*> m_entryps[3]; // Nodes to delete when we are finished
bool m_markBoth; // Mark as driven+used
AstNodeFTask* m_taskp; // Current task
AstAlways* m_alwaysp; // Current always
// METHODS
static int debug() {
@@ -226,31 +239,45 @@ private:
return level;
}
UndrivenVarEntry* getEntryp(AstVar* nodep) {
if (!nodep->user1p()) {
UndrivenVarEntry* getEntryp(AstVar* nodep, int which_user) {
if (!(which_user==1 ? nodep->user1p() : nodep->user2p())) {
UndrivenVarEntry* entryp = new UndrivenVarEntry (nodep);
m_entryps.push_back(entryp);
nodep->user1p(entryp);
//UINFO(9," Associate u="<<which_user<<" "<<(void*)this<<" "<<nodep->name()<<endl);
m_entryps[which_user].push_back(entryp);
if (which_user==1) nodep->user1p(entryp);
else if (which_user==2) nodep->user2p(entryp);
else nodep->v3fatalSrc("Bad case");
return entryp;
} else {
UndrivenVarEntry* entryp = (UndrivenVarEntry*)(nodep->user1p());
UndrivenVarEntry* entryp = (UndrivenVarEntry*)(which_user==1 ? nodep->user1p() : nodep->user2p());
return entryp;
}
}
void warnAlwCombOrder(AstVarRef* nodep) {
AstVar* varp = nodep->varp();
if (!varp->isParam() && !varp->isGenVar() && !varp->isUsedLoopIdx()
&& !varp->fileline()->warnIsOff(V3ErrorCode::ALWCOMBORDER)) { // Warn only once per variable
nodep->v3warn(ALWCOMBORDER, "Always_comb variable driven after use: "<<nodep->prettyName());
varp->fileline()->modifyWarnOff(V3ErrorCode::ALWCOMBORDER, true); // Complain just once for any usage
}
}
// VISITORS
virtual void visit(AstVar* nodep, AstNUser*) {
UndrivenVarEntry* entryp = getEntryp (nodep);
if (nodep->isInput()
|| nodep->isSigPublic() || nodep->isSigUserRWPublic()
|| (m_taskp && (m_taskp->dpiImport() || m_taskp->dpiExport()))) {
entryp->drivenWhole();
}
if (nodep->isOutput()
|| nodep->isSigPublic() || nodep->isSigUserRWPublic()
|| nodep->isSigUserRdPublic()
|| (m_taskp && (m_taskp->dpiImport() || m_taskp->dpiExport()))) {
entryp->usedWhole();
for (int usr=1; usr<(m_alwaysp?3:2); ++usr) {
UndrivenVarEntry* entryp = getEntryp (nodep, usr);
if (nodep->isInput()
|| nodep->isSigPublic() || nodep->isSigUserRWPublic()
|| (m_taskp && (m_taskp->dpiImport() || m_taskp->dpiExport()))) {
entryp->drivenWhole();
}
if (nodep->isOutput()
|| nodep->isSigPublic() || nodep->isSigUserRWPublic()
|| nodep->isSigUserRdPublic()
|| (m_taskp && (m_taskp->dpiImport() || m_taskp->dpiExport()))) {
entryp->usedWhole();
}
}
// Discover variables used in bit definitions, etc
nodep->iterateChildren(*this);
@@ -263,10 +290,19 @@ private:
AstVarRef* varrefp = nodep->fromp()->castVarRef();
AstConst* constp = nodep->lsbp()->castConst();
if (varrefp && constp && !constp->num().isFourState()) {
UndrivenVarEntry* entryp = getEntryp (varrefp->varp());
int lsb = constp->toUInt();
if (m_markBoth || varrefp->lvalue()) entryp->drivenBit(lsb, nodep->width());
if (m_markBoth || !varrefp->lvalue()) entryp->usedBit(lsb, nodep->width());
for (int usr=1; usr<(m_alwaysp?3:2); ++usr) {
UndrivenVarEntry* entryp = getEntryp (varrefp->varp(), usr);
int lsb = constp->toUInt();
if (m_markBoth || varrefp->lvalue()) {
// Don't warn if already driven earlier as "a=0; if(a) a=1;" is fine.
if (usr==2 && m_alwaysp && entryp->isUsedNotDrivenBit(lsb, nodep->width())) {
UINFO(9," Select. Entryp="<<(void*)entryp<<endl);
warnAlwCombOrder(varrefp);
}
entryp->drivenBit(lsb, nodep->width());
}
if (m_markBoth || !varrefp->lvalue()) entryp->usedBit(lsb, nodep->width());
}
} else {
// else other varrefs handled as unknown mess in AstVarRef
nodep->iterateChildren(*this);
@@ -274,10 +310,18 @@ private:
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
// Any variable
UndrivenVarEntry* entryp = getEntryp (nodep->varp());
bool fdrv = nodep->lvalue() && nodep->varp()->attrFileDescr(); // FD's are also being read from
if (m_markBoth || nodep->lvalue()) entryp->drivenWhole();
if (m_markBoth || !nodep->lvalue() || fdrv) entryp->usedWhole();
for (int usr=1; usr<(m_alwaysp?3:2); ++usr) {
UndrivenVarEntry* entryp = getEntryp (nodep->varp(), usr);
bool fdrv = nodep->lvalue() && nodep->varp()->attrFileDescr(); // FD's are also being read from
if (m_markBoth || nodep->lvalue()) {
if (usr==2 && m_alwaysp && entryp->isUsedNotDrivenAny()) {
UINFO(9," Full bus. Entryp="<<(void*)entryp<<endl);
warnAlwCombOrder(nodep);
}
entryp->drivenWhole();
}
if (m_markBoth || !nodep->lvalue() || fdrv) entryp->usedWhole();
}
}
// Don't know what black boxed calls do, assume in+out
@@ -288,6 +332,19 @@ private:
m_markBoth = prevMark;
}
virtual void visit(AstAlways* nodep, AstNUser*) {
AstAlways* prevAlwp = m_alwaysp;
{
AstNode::user2ClearTree();
if (nodep->keyword() == VAlwaysKwd::ALWAYS_COMB) UINFO(9," "<<nodep<<endl);
if (nodep->keyword() == VAlwaysKwd::ALWAYS_COMB) m_alwaysp = nodep;
else m_alwaysp = NULL;
nodep->iterateChildren(*this);
if (nodep->keyword() == VAlwaysKwd::ALWAYS_COMB) UINFO(9," Done "<<nodep<<endl);
}
m_alwaysp = prevAlwp;
}
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
AstNodeFTask* prevTaskp = m_taskp;
m_taskp = nodep;
@@ -315,12 +372,17 @@ public:
UndrivenVisitor(AstNetlist* nodep) {
m_markBoth = false;
m_taskp = NULL;
m_alwaysp = NULL;
nodep->accept(*this);
}
virtual ~UndrivenVisitor() {
for (vector<UndrivenVarEntry*>::iterator it = m_entryps.begin(); it != m_entryps.end(); ++it) {
for (vector<UndrivenVarEntry*>::iterator it = m_entryps[1].begin(); it != m_entryps[1].end(); ++it) {
(*it)->reportViolations();
delete (*it);
}
for (int usr=1; usr<3; ++usr) {
for (vector<UndrivenVarEntry*>::iterator it = m_entryps[usr].begin(); it != m_entryps[usr].end(); ++it) {
delete (*it);
}
}
}
};
+1 -1
View File
@@ -115,7 +115,7 @@ private:
m_forVarp = initAssp->lhsp()->castVarRef()->varp();
m_forVscp = initAssp->lhsp()->castVarRef()->varScopep();
if (nodep->castGenFor() && !m_forVarp->isGenVar()) {
nodep->v3error("Non-genvar used in generate for: "<<m_forVarp->name()<<endl);
nodep->v3error("Non-genvar used in generate for: "<<m_forVarp->prettyName()<<endl);
}
if (m_generate) V3Const::constifyParamsEdit(initAssp->rhsp()); // rhsp may change
AstConst* constInitp = initAssp->rhsp()->castConst();
+1 -1
View File
@@ -1135,7 +1135,7 @@ private:
} else {
AstSel* newp = new AstSel(nodep->fileline(), nodep->fromp()->unlinkFrBack(),
memberp->lsb(), memberp->width());
newp->dtypep(memberp);
newp->dtypep(memberp->skipRefp()); // Must skip over the member to find the union; as the member may disappear later
newp->didWidth(true); // Don't replace dtype with basic type
UINFO(9," MEMBERSEL -> "<<newp<<endl);
nodep->replaceWith(newp);
+1 -1
View File
@@ -217,7 +217,7 @@ private:
fromp,
new AstMul(nodep->fileline(),
new AstConst(nodep->fileline(),AstConst::Unsized32(),elwidth),
newSubLsbOf(rhsp, fromRange)),
subp),
new AstConst (nodep->fileline(),AstConst::Unsized32(),elwidth));
newp->declRange(fromRange);
newp->declElWidth(elwidth);
+3 -3
View File
@@ -403,9 +403,9 @@ word [a-zA-Z0-9_]+
"$warning" { FL; return yD_WARNING; }
/* SV2005 Keywords */
"$unit" { FL; return yD_UNIT; } /* Yes, a keyword, not task */
"always_comb" { FL; return yALWAYS; }
"always_ff" { FL; return yALWAYS; }
"always_latch" { FL; return yALWAYS; }
"always_comb" { FL; return yALWAYS_COMB; }
"always_ff" { FL; return yALWAYS_FF; }
"always_latch" { FL; return yALWAYS_LATCH; }
"bind" { FL; return yBIND; }
"bit" { FL; return yBIT; }
"break" { FL; return yBREAK; }
+11 -5
View File
@@ -273,6 +273,9 @@ class AstSenTree;
// Double underscores "yX__Y" means token X followed by Y,
// and "yX__ETC" means X folled by everything but Y(s).
%token<fl> yALWAYS "always"
%token<fl> yALWAYS_FF "always_ff"
%token<fl> yALWAYS_COMB "always_comb"
%token<fl> yALWAYS_LATCH "always_latch"
%token<fl> yAND "and"
%token<fl> yASSERT "assert"
%token<fl> yASSIGN "assign"
@@ -1549,7 +1552,10 @@ module_common_item<nodep>: // ==IEEE: module_common_item
| final_construct { $$ = $1; }
// // IEEE: always_construct
// // Verilator only - event_control attached to always
| yALWAYS event_controlE stmtBlock { $$ = new AstAlways($1,$2,$3); }
| yALWAYS event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS, $2,$3); }
| yALWAYS_FF event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_FF, $2,$3); }
| yALWAYS_COMB event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_COMB, $2,$3); }
| yALWAYS_LATCH event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_LATCH, $2,$3); }
| loop_generate_construct { $$ = $1; }
| conditional_generate_construct { $$ = $1; }
// // Verilator only
@@ -2204,10 +2210,10 @@ foperator_assignment<nodep>: // IEEE: operator_assignment (for first part of exp
finc_or_dec_expression<nodep>: // ==IEEE: inc_or_dec_expression
//UNSUP: Generic scopes in incrementes
varRefBase yP_PLUSPLUS { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); }
| varRefBase yP_MINUSMINUS { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); }
| yP_PLUSPLUS varRefBase { $$ = new AstAssign($1,$2,new AstAdd ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); }
| yP_MINUSMINUS varRefBase { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); }
fexprLvalue yP_PLUSPLUS { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); }
| fexprLvalue yP_MINUSMINUS { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); }
| yP_PLUSPLUS fexprLvalue { $$ = new AstAssign($1,$2,new AstAdd ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); }
| yP_MINUSMINUS fexprLvalue { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); }
;
//************************************************
+1
View File
@@ -1504,6 +1504,7 @@ sub sig_child {}
sub kill_tree_all {}
sub wait_all {}
sub ready {}
sub running {}
#######################################################################
1;
+1 -1
View File
@@ -99,7 +99,7 @@ int dpix_run_tests() {
static int didDump = 0;
if (didDump++ == 0) {
# ifdef TEST_VERBOSE
Verilated::scopesDump();
Verilated::internalsDump();
# endif
}
#endif
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+91
View File
@@ -0,0 +1,91 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2013 by Wilson Snyder.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc=0;
reg [63:0] crc;
reg [63:0] sum;
// Take CRC data and apply to testblock inputs
wire [3:0] datai = crc[3:0];
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
logic [3:0] datao; // From test of Test.v
// End of automatics
Test test (/*AUTOINST*/
// Outputs
.datao (datao[3:0]),
// Inputs
.clk (clk),
.datai (datai[3:0]));
// Aggregate outputs into a single result vector
wire [63:0] result = {60'h0, datao};
// Test loop
always @ (posedge clk) begin
`ifdef TEST_VERBOSE
$write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result);
`endif
cyc <= cyc + 1;
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]};
if (cyc==0) begin
// Setup
crc <= 64'h5aef0c8d_d70a4497;
sum <= 64'h0;
end
else if (cyc<10) begin
sum <= 64'h0;
end
else if (cyc<90) begin
end
else if (cyc==99) begin
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
if (crc !== 64'hc77bb9b3784ea091) $stop;
// What checksum will we end up with (above print should match)
`define EXPECTED_SUM 64'h3db7bc8bfe61f983
if (sum !== `EXPECTED_SUM) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module Test
(
input logic clk,
input logic [3:0] datai,
output logic [3:0] datao
);
genvar i;
parameter SIZE = 4;
logic [SIZE:1][3:0] delay;
always_ff @(posedge clk) begin
delay[1][3:0] <= datai;
end
generate
for (i = 2; i < (SIZE+1); i++) begin
always_ff @(posedge clk) begin
delay[i][3:0] <= delay[i-1][3:0];
end
end
endgenerate
always_comb datao = delay[SIZE][3:0];
endmodule
+4 -3
View File
@@ -18,16 +18,17 @@ module t (/*AUTOARG*/
reg ionewire;
`ifdef never_just_for_verilog_mode
wire oonewire; // From sub of t_inst_v2k_sub.v
wire oonewire; // From sub of t_inst_v2k__sub.v
`endif
wire [7:0] osizedreg; // From sub of t_inst_v2k_sub.v
wire [7:0] osizedreg; // From sub of t_inst_v2k__sub.v
wire [1:0] tied;
wire [3:0] tied_also;
hello hsub (.tied_also);
t_inst_v2k_sub sub
// Double underscore tests bug631
t_inst_v2k__sub sub
(
// Outputs
.osizedreg (osizedreg[7:0]),
@@ -5,7 +5,7 @@
// without warranty, 2003 by Wilson Snyder.
// This file is named .vi to test +libext+ flags.
module t_inst_v2k_sub
module t_inst_v2k__sub
(
output reg [7:0] osizedreg,
output wire oonewire /*verilator public*/,
+22
View File
@@ -0,0 +1,22 @@
#!/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.
compile (
verilator_flags2 => ["--lint-only"],
verilator_make_gcc => 0,
make_top_shell => 0,
make_main => 0,
fails => 1,
expect=>
'%Warning-ALWCOMBORDER: t/t_lint_always_comb_bad.v:\d+: Always_comb variable driven after use: mid
.*%Error: Exiting due to.*',
);
ok(1);
1;
+48
View File
@@ -0,0 +1,48 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2013 by Wilson Snyder.
module t (/*AUTOARG*/
// Outputs
mid, o3,
// Inputs
clk, i3
);
input clk;
output logic mid;
input i3;
output logic o3;
wire [15:0] temp1;
wire [15:0] temp1_d1r;
logic setbefore;
always_comb begin
setbefore = 1'b1;
if (setbefore) setbefore = 1'b0; // fine
end
always_comb begin
if (mid)
temp1 = 'h0;
else
temp1 = (temp1_d1r - 'h1);
mid = (temp1_d1r == 'h0); // BAD
end
always_comb begin
o3 = 'h0;
case (i3)
1'b1: begin
o3 = i3;
end
default: ;
endcase
end
always_ff @ (posedge clk) begin
temp1_d1r <= temp1;
end
endmodule
+16
View File
@@ -12,6 +12,7 @@ module t (/*AUTOARG*/
reg [39:0] con1,con2, con3;
reg [31:0] w32;
reg [31:0] v32 [2];
// surefire lint_off UDDSCN
reg [200:0] conw3, conw4;
@@ -105,6 +106,21 @@ module t (/*AUTOARG*/
w32 = 12; w32 ^= 15; if (w32 != 3) $stop;
w32 = 12; w32 >>= 1; if (w32 != 6) $stop;
w32 = 12; w32 <<= 1; if (w32 != 24) $stop;
// Increments
v32[2] = 12; v32[2]++; if (v32[2] != 13) $stop;
v32[2] = 12; ++v32[2]; if (v32[2] != 13) $stop;
v32[2] = 12; v32[2]--; if (v32[2] != 11) $stop;
v32[2] = 12; --v32[2]; if (v32[2] != 11) $stop;
v32[2] = 12; v32[2] += 2; if (v32[2] != 14) $stop;
v32[2] = 12; v32[2] -= 2; if (v32[2] != 10) $stop;
v32[2] = 12; v32[2] *= 2; if (v32[2] != 24) $stop;
v32[2] = 12; v32[2] /= 2; if (v32[2] != 6) $stop;
v32[2] = 12; v32[2] &= 6; if (v32[2] != 4) $stop;
v32[2] = 12; v32[2] |= 15; if (v32[2] != 15) $stop;
v32[2] = 12; v32[2] ^= 15; if (v32[2] != 3) $stop;
v32[2] = 12; v32[2] >>= 1; if (v32[2] != 6) $stop;
v32[2] = 12; v32[2] <<= 1; if (v32[2] != 24) $stop;
end
if (cyc==2) begin
win <= 32'h123123;
+56
View File
@@ -0,0 +1,56 @@
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2013 by Ted Campbell.
#include "Vt_order_multidriven.h"
#include "verilated.h"
#include "verilated_vcd_c.h"
Vt_order_multidriven * vcore;
VerilatedVcdC * vcd;
vluint64_t vtime;
#define PHASE_90
static void half_cycle( int clk ) {
if ( clk & 1 ) vcore->i_clk_wr = !vcore->i_clk_wr;
if ( clk & 2 ) vcore->i_clk_rd = !vcore->i_clk_rd;
vtime += 10 / 2;
vcore->eval();
vcore->eval();
vcd->dump( vtime );
}
static void cycle() {
#ifdef PHASE_90
half_cycle( 1 );
half_cycle( 2 );
half_cycle( 1 );
half_cycle( 2 );
#else
half_cycle( 3 );
half_cycle( 3 );
#endif
}
int main() {
Verilated::traceEverOn( true );
vcore = new Vt_order_multidriven;
vcd = new VerilatedVcdC;
vcore->trace( vcd, 99 );
vcd->open( "obj_dir/t_order_multidriven/sim.vcd" );
vcore->i_clk_wr = 0;
vcore->i_clk_rd = 0;
for ( int i = 0; i < 256; ++i )
cycle( );
vcd->close( );
printf("*-* All Finished *-*\n");
}
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2013 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.
$Self->{vlt} or $Self->skip("Verilator only test");
compile (
make_top_shell => 0,
make_main => 0,
v_flags2 => ["--trace --exe $Self->{t_dir}/t_order_multidriven.cpp"],
);
execute (
check_finished=>1,
);
ok(1);
1;
+192
View File
@@ -0,0 +1,192 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2013 by Ted Campbell.
//With MULTI_CLK defined shows bug, without it is hidden
`define MULTI_CLK
//bug634
module t (
input i_clk_wr,
input i_clk_rd
);
wire wr$wen;
wire [7:0] wr$addr;
wire [7:0] wr$wdata;
wire [7:0] wr$rdata;
wire rd$wen;
wire [7:0] rd$addr;
wire [7:0] rd$wdata;
wire [7:0] rd$rdata;
wire clk_wr;
wire clk_rd;
`ifdef MULTI_CLK
assign clk_wr = i_clk_wr;
assign clk_rd = i_clk_rd;
`else
assign clk_wr = i_clk_wr;
assign clk_rd = i_clk_wr;
`endif
FooWr u_wr (
.i_clk ( clk_wr ),
.o_wen ( wr$wen ),
.o_addr ( wr$addr ),
.o_wdata ( wr$wdata ),
.i_rdata ( wr$rdata )
);
FooRd u_rd (
.i_clk ( clk_rd ),
.o_wen ( rd$wen ),
.o_addr ( rd$addr ),
.o_wdata ( rd$wdata ),
.i_rdata ( rd$rdata )
);
FooMem u_mem (
.iv_clk ( {clk_wr, clk_rd } ),
.iv_wen ( {wr$wen, rd$wen } ),
.iv_addr ( {wr$addr, rd$addr } ),
.iv_wdata ( {wr$wdata,rd$wdata} ),
.ov_rdata ( {wr$rdata,rd$rdata} )
);
endmodule
// Memory Writer
module FooWr(
input i_clk,
output o_wen,
output [7:0] o_addr,
output [7:0] o_wdata,
input [7:0] i_rdata
);
reg [7:0] cnt = 0;
// Count [0,200]
always @( posedge i_clk )
if ( cnt < 8'd50 )
cnt <= cnt + 8'd1;
// Write addr in (10,30) if even
assign o_wen = ( cnt > 8'd10 ) && ( cnt < 8'd30 ) && ( cnt[0] == 1'b0 );
assign o_addr = cnt;
assign o_wdata = cnt;
endmodule
// Memory Reader
module FooRd(
input i_clk,
output o_wen,
output [7:0] o_addr,
output [7:0] o_wdata,
input [7:0] i_rdata
);
reg [7:0] cnt = 0;
reg [7:0] addr_r;
reg en_r;
// Count [0,200]
always @( posedge i_clk )
if ( cnt < 8'd200 )
cnt <= cnt + 8'd1;
// Read data
assign o_wen = 0;
assign o_addr = cnt - 8'd100;
// Track issued read
always @( posedge i_clk )
begin
addr_r <= o_addr;
en_r <= ( cnt > 8'd110 ) && ( cnt < 8'd130 ) && ( cnt[0] == 1'b0 );
end
// Display to console 100 cycles after writer
always @( negedge i_clk )
if ( en_r ) begin
`ifdef TEST_VERBOSE
$display( "MEM[%x] == %x", addr_r, i_rdata );
`endif
if (addr_r != i_rdata) $stop;
end
endmodule
// Multi-port memory abstraction
module FooMem(
input [2 -1:0] iv_clk,
input [2 -1:0] iv_wen,
input [2*8-1:0] iv_addr,
input [2*8-1:0] iv_wdata,
output [2*8-1:0] ov_rdata
);
FooMemImpl u_impl (
.a_clk ( iv_clk [0*1+:1] ),
.a_wen ( iv_wen [0*1+:1] ),
.a_addr ( iv_addr [0*8+:8] ),
.a_wdata ( iv_wdata[0*8+:8] ),
.a_rdata ( ov_rdata[0*8+:8] ),
.b_clk ( iv_clk [1*1+:1] ),
.b_wen ( iv_wen [1*1+:1] ),
.b_addr ( iv_addr [1*8+:8] ),
.b_wdata ( iv_wdata[1*8+:8] ),
.b_rdata ( ov_rdata[1*8+:8] )
);
endmodule
// Dual-Port L1 Memory Implementation
module FooMemImpl(
input a_clk,
input a_wen,
input [7:0] a_addr,
input [7:0] a_wdata,
output [7:0] a_rdata,
input b_clk,
input b_wen,
input [7:0] b_addr,
input [7:0] b_wdata,
output [7:0] b_rdata
);
/* verilator lint_off MULTIDRIVEN */
reg [7:0] mem[0:255];
/* verilator lint_on MULTIDRIVEN */
always @( posedge a_clk )
if ( a_wen )
mem[a_addr] <= a_wdata;
always @( posedge b_clk )
if ( b_wen )
mem[b_addr] <= b_wdata;
always @( posedge a_clk )
a_rdata <= mem[a_addr];
always @( posedge b_clk )
b_rdata <= mem[b_addr];
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+38
View File
@@ -0,0 +1,38 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2012 by Wilson Snyder.
//bug505
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
a #(1) a1 ();
b #(2) b2 ();
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
module a;
parameter ONE /*verilator public*/ = 22;
initial if (ONE != 1) $stop;
`ifdef VERILATOR
initial if ($c32("ONE") != 1) $stop;
`endif
endmodule
module b #(
parameter TWO /*verilator public*/ = 22
);
initial if (TWO != 2) $stop;
`ifdef VERILATOR
initial if ($c32("TWO") != 2) $stop;
`endif
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
v_flags2 => ["--lint-only"],
verilator_make_gcc => 0,
make_top_shell => 0,
make_main => 0,
);
ok(1);
1;
+45
View File
@@ -0,0 +1,45 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2013 by Wilson Snyder.
typedef struct packed {
logic [1:0] b1;
logic [1:0] b2;
logic [1:0] b3;
logic [1:0] b4;
} t__aa_bbbbbbb_ccccc_dddddd_eee;
typedef struct packed {
logic [31:0] a;
union packed {
logic [7:0] fbyte;
t__aa_bbbbbbb_ccccc_dddddd_eee pairs;
} b1;
logic [23:0] b2;
logic [7:0] c1;
logic [23:0] c2;
logic [31:0] d;
} t__aa_bbbbbbb_ccccc_dddddd;
typedef struct packed {
logic [31:0] a;
logic [31:0] b;
logic [31:0] c;
logic [31:0] d;
} t__aa_bbbbbbb_ccccc_eee;
typedef union packed {
t__aa_bbbbbbb_ccccc_dddddd dddddd;
t__aa_bbbbbbb_ccccc_eee eee;
} t__aa_bbbbbbb_ccccc;
module t (
input t__aa_bbbbbbb_ccccc xxxxxxx_yyyyy_zzzz,
output logic [15:0] datao_pre
);
always_comb datao_pre = { xxxxxxx_yyyyy_zzzz.dddddd.b1.fbyte, xxxxxxx_yyyyy_zzzz.dddddd.c1 };
endmodule
+46
View File
@@ -0,0 +1,46 @@
#!/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.
$Self->{vlt} or $Self->skip("Verilator only test");
top_filename("t/t_var_pinsizes.v");
compile (
verilator_flags2 => ["-sp --pins-sc-biguint --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
make_main => 0,
);
if ($Self->{vlt}) {
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i8;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i16;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i32;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<vluint64_t> \s+ i64;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_biguint<65>\s> \s+ i65;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_biguint<128>\s> \s+ i128;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<513>\s> \s+ i513;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o8;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o16;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o32;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<vluint64_t> \s+ o64;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_biguint<65>\s> \s+ o65;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_biguint<128>\s> \s+ o128;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<513>\s> \s+ o513;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
}
execute();
ok(1);
1;
+46
View File
@@ -0,0 +1,46 @@
#!/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.
$Self->{vlt} or $Self->skip("Verilator only test");
top_filename("t/t_var_pinsizes.v");
compile (
verilator_flags2 => ["-sp --pins-sc-uint --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
make_main => 0,
);
if ($Self->{vlt}) {
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<8>\s> \s+ i8;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<16>\s> \s+ i16;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<32>\s> \s+ i32;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<64>\s> \s+ i64;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<128>\s> \s+ i128;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<513>\s> \s+ i513;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<8>\s> \s+ o8;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<16>\s> \s+ o16;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<32>\s> \s+ o32;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<64>\s> \s+ o64;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<128>\s> \s+ o128;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<513>\s> \s+ o513;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
}
execute();
ok(1);
1;
+46
View File
@@ -0,0 +1,46 @@
#!/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.
$Self->{vlt} or $Self->skip("Verilator only test");
top_filename("t/t_var_pinsizes.v");
compile (
verilator_flags2 => ["-sp --pins-sc-uint --pins-sc-biguint --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
make_main => 0,
);
if ($Self->{vlt}) {
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<8>\s> \s+ i8;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<16>\s> \s+ i16;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<32>\s> \s+ i32;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<64>\s> \s+ i64;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_biguint<65>\s> \s+ i65;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_biguint<128>\s> \s+ i128;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<513>\s> \s+ i513;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<8>\s> \s+ o8;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<16>\s> \s+ o16;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<32>\s> \s+ o32;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<64>\s> \s+ o64;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_biguint<65>\s> \s+ o65;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_biguint<128>\s> \s+ o128;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<513>\s> \s+ o513;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
}
execute();
ok(1);
1;
+14
View File
@@ -12,6 +12,12 @@
# include "Vt_var_pins_sc64.h"
#elif defined(T_VAR_PINS_SCUI)
# include "Vt_var_pins_scui.h"
#elif defined(T_VAR_PINS_SC_UINT)
# include "Vt_var_pins_sc_uint.h"
#elif defined(T_VAR_PINS_SC_BIGUINT)
# include "Vt_var_pins_sc_biguint.h"
#elif defined(T_VAR_PINS_SC_UINT_BIGUINT)
# include "Vt_var_pins_sc_uint_biguint.h"
#else
# error "Unknown test"
#endif
@@ -30,3 +36,11 @@ int main() {
tb->final();
return 0;
}
int sc_main(int argc, char *argv[]) {
tb = new VM_PREFIX("tb");
VL_PRINTF("*-* All Finished *-*\n");
tb->final();
return 0;
}
+20 -14
View File
@@ -8,26 +8,30 @@
module t (/*AUTOARG*/
// Outputs
o1, o8, o16, o32, o64, o65, obv1, obv16,
o1, o8, o16, o32, o64, o65, o128, o513, obv1, obv16,
// Inputs
clk, i1, i8, i16, i32, i64, i65, ibv1, ibv16
clk, i1, i8, i16, i32, i64, i65, i128, i513, ibv1, ibv16
);
input clk;
input i1;
input [7:0] i8;
input [15:0] i16;
input [31:0] i32;
input [63:0] i64;
input [64:0] i65;
input i1;
input [7:0] i8;
input [15:0] i16;
input [31:0] i32;
input [63:0] i64;
input [64:0] i65;
input [127:0] i128;
input [512:0] i513;
output o1;
output [7:0] o8;
output [15:0] o16;
output [31:0] o32;
output [63:0] o64;
output [64:0] o65;
output o1;
output [7:0] o8;
output [15:0] o16;
output [31:0] o32;
output [63:0] o64;
output [64:0] o65;
output [127:0] o128;
output [512:0] o513;
input [0:0] ibv1 /*verilator sc_bv*/;
input [15:0] ibv16 /*verilator sc_bv*/;
@@ -42,6 +46,8 @@ module t (/*AUTOARG*/
o32 <= i32;
o64 <= i64;
o65 <= i65;
o128 <= i128;
o513 <= i513;
obv1 <= ibv1;
obv16 <= ibv16;
end