Compare commits

...
20 Commits
Author SHA1 Message Date
Wilson Snyder a7aa8820e1 Version bump 2019-03-23 21:00:07 -04:00
Wilson Snyder 2582a83376 Unsupported error on select of concatenation 2019-03-13 19:52:23 -04:00
Wilson Snyder 0094cd7a81 Internals: Spacing fixes. No functional change. 2019-03-13 19:47:47 -04:00
Wilson Snyder d9b33d74a4 Support void' cast on functions called as tasks, bug1383. 2019-03-10 15:12:20 -04:00
Wilson Snyder 539a773ea7 Add IGNOREDRETURN warning. 2019-03-10 14:57:01 -04:00
Wilson Snyder b1831d7e33 Fix +1364-1995ext flags applying too late, bug1384. 2019-03-10 14:09:22 -04:00
Wilson Snyder b8ccb7a4c1 Fix maintainer test when no Parallel::Forker, msg2630. 2019-03-10 12:14:58 -04:00
Wilson Snyder 0eb75a41bb Fix perl 5.38 warning. 2019-03-10 12:14:02 -04:00
Wilson Snyder 4cc47e3297 Tests: Cleanup spacing/style. No functional change. 2019-03-10 09:25:23 -04:00
Wilson Snyder 7bf3366041 Support . 2019-03-07 20:56:53 -05:00
Wilson Snyder c4b9f4bccf Tests: Remove old verilator_file_descriptor 2019-03-07 18:29:44 -05:00
Wilson Snyder 455c552132 Fix MSVC compile error, bug1406. 2019-03-04 20:29:01 -05:00
Wilson Snyder f26fb51509 Commentary, bug1339. 2019-03-01 20:14:48 -05:00
Wilson Snyder ab3c6576ed Report PORTSHORT errors on concat constants, bug 1400. 2019-02-27 21:06:07 -05:00
Wilson Snyder d1bd994113 Commentary, bug1399. 2019-02-26 18:56:13 -05:00
Wilson Snyder d1548b1161 Commentary 2019-02-26 18:24:46 -05:00
Wilson Snyder 8a43f41ed6 Fix $value$plus$args missing verilated_heavy.h. 2019-02-15 18:33:52 -05:00
Wilson Snyder 42759e4011 Fix VERILATOR_GDB being ignored, msg2860. 2019-02-12 18:20:40 -05:00
Wilson Snyder 27fa19eb94 Add +verilator+seed, bug1396. 2019-02-04 20:28:17 -05:00
Wilson Snyder 426ed8589b devel release 2019-01-28 07:30:42 -05:00
56 changed files with 1002 additions and 226 deletions
+22
View File
@@ -2,6 +2,28 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 4.012 2019-3-23
*** Add +verilator+seed, bug1396. [Stan Sokorac]
*** Support $fread. [Leendert van Doorn]
*** Support void' cast on functions called as tasks, bug1383. [Al Grant]
*** Add IGNOREDRETURN warning, bug1383.
**** Report PORTSHORT errors on concat constants, bug 1400. [Will Korteland]
**** Fix VERILATOR_GDB being ignored, msg2860. [Yu Sheng Lin]
**** Fix $value$plus$args missing verilated_heavy.h. [Yi-Chung Chen]
**** Fix MSVC compile error, bug1406. [Benjamin Gartner]
**** Fix maintainer test when no Parallel::Forker, msg2630. [Enzo Chi]
**** Fix +1364-1995ext flags applying too late, bug1384. [Al Grant]
* Verilator 4.010 2019-01-27
+34 -14
View File
@@ -85,7 +85,7 @@ if ($opt_gdbbt && !gdb_works()) {
my @quoted_sw = map {sh_escape($_)} @Opt_Verilator_Sw;
if ($opt_gdb) {
# Generic GDB interactive
run (("gdb"||$ENV{VERILATOR_GDB})
run (($ENV{VERILATOR_GDB}||"gdb")
." ".verilator_bin()
# Note, uncomment to set breakpoints before running:
# ." -ex 'break main'"
@@ -399,7 +399,8 @@ detailed descriptions in L</"RUNTIME ARGUMENTS"> for more information.
+verilator+prof+threads+file+I<filename> Set profile filename
+verilator+prof+threads+start+I<value> Set profile starting point
+verilator+prof+threads+window+I<value> Set profile duration
+verilator+rand+reset+<value> Set random reset technique
+verilator+rand+reset+I<value> Set random reset technique
+verilator+seed+I<value> Set random seed
+verilator+V Verbose version and config
+verilator+version Show version and exit
@@ -1455,10 +1456,10 @@ Enable all code style related warning messages. This is equivalent to
=item --x-assign unique
Controls the two-state value that is replaced when an assignment to X is
encountered. --x-assign=fast, the default, converts all Xs to whatever is
best for performance. --x-assign=0 converts all Xs to 0s, and is also fast.
--x-assign=1 converts all Xs to 1s, this is nearly as fast as 0, but more
likely to find reset bugs as active high logic will fire. --x-assign=unique
encountered. C<--x-assign fast>, the default, converts all Xs to whatever is
best for performance. C<--x-assign 0> converts all Xs to 0s, and is also fast.
C<--x-assign 1> converts all Xs to 1s, this is nearly as fast as 0, but more
likely to find reset bugs as active high logic will fire. C<--x-assign unique>
will call a function to determine the value, this allows randomization of
all Xs to find reset bugs and is the slowest, but safest for finding reset
bugs in code.
@@ -1483,13 +1484,13 @@ variables are controlled with --x-initial.
Controls the two-state value that is used to initialize variables that are
not otherwise initialized.
--x-initial=0, initializes all otherwise uninitialized variables to zero.
C<--x-initial 0>, initializes all otherwise uninitialized variables to zero.
--x-initial=unique, the default, initializes variables using a function,
C<--x-initial unique>, the default, initializes variables using a function,
which determines the value to use each initialization. This gives greatest
flexibility and allows finding reset bugs. See L</"Unknown states">.
--x-initial=fast, is best for performance, and initializes all variables to
C<--x-initial fast>, is best for performance, and initializes all variables to
a state Verilator determines is optimal. This may allow further code
optimizations, but will likely hide any code bugs relating to missing
resets.
@@ -1599,6 +1600,11 @@ When a model was Verilated using "-x-inital unique", sets the
initialization technique. 0 = Reset to zeros. 1 = Reset to all-ones. 2 =
Randomize. See L</"Unknown states">.
=item +verilator+seed+I<value>
For $random and "-x-initial unique", set the random seed value. If zero or
not specified picks a value from the system random number generator.
=item +verilator+V
Shows the verbose version, including configuration information.
@@ -1759,8 +1765,8 @@ the examples directory in the distribution.
=head1 BENCHMARKING & OPTIMIZATION
For best performance, run Verilator with the "-O3 --x-assign=fast
--x-initial=fast --noassert" flags. The -O3 flag will require longer
compile times, and --x-assign=fast --x-initial=fast may increase the risk
--x-initial fast --noassert" flags. The -O3 flag will require longer
compile times, and "--x-assign fast --x-initial fast" may increase the risk
of reset bugs in trade for performance; see the above documentation for
these flags.
@@ -3018,9 +3024,10 @@ from a four state simulator. An === comparison to X will always be false,
so that Verilog code which checks for uninitialized logic will not fire.
Assigning a variable to a X will actually assign the variable to a random
value (see the --x-assign switch.) Thus if the value is actually used, the
random value should cause downstream errors. Integers also randomize, even
though the Verilog 2001 specification says they initialize to zero.
value (see the --x-assign switch and +verilator+rand+reset runtime switch.)
Thus if the value is actually used, the random value should cause
downstream errors. Integers also randomize, even though the Verilog 2001
specification says they initialize to zero.
All variables, depending on --x-initial setting, are typically randomly
initialized using a function. By running several random simulation runs
@@ -3573,6 +3580,19 @@ code to a case statement, or a SystemVerilog 'unique if' or 'priority if'.
Disabled by default as this is a code style warning; it will simulate
correctly.
=item IGNOREDRETURN
Warns that a non-void function is being called as a task, and hence the
return value is being ignored.
This warning is required by IEEE. The portable way to suppress this warning
(in SystemVerilog) is to use a void cast, e.g.
void'(function_being_called_as_task());
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item IMPERFECTSCH
Warns that the scheduling of the model is not absolutely perfect, and some
+1 -1
View File
@@ -6,7 +6,7 @@
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[4.010 2019-01-27],
AC_INIT([Verilator],[4.012 2019-03-23],
[https://www.veripool.org/verilator],
[verilator],[https://www.veripool.org/verilator])
# When releasing, also update header of Changes file
+6 -2
View File
@@ -27,15 +27,19 @@ int main(int argc, char** argv, char** env) {
// Prevent unused variable warnings
if (0 && argc && argv && env) {}
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
Verilated::commandArgs(argc, argv);
// Set debug level, 0 is off, 9 is highest presently used
// May be overridden by commandArgs
Verilated::debug(0);
// Randomization reset policy
// May be overridden by commandArgs
Verilated::randReset(2);
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
// This needs to be called before you create any model
Verilated::commandArgs(argc, argv);
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
Vtop* top = new Vtop; // Or use a const unique_ptr, or the VL_UNIQUE_PTR wrapper
+6 -2
View File
@@ -24,15 +24,19 @@ int sc_main(int argc, char* argv[]) {
// Prevent unused variable warnings
if (0 && argc && argv) {}
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
Verilated::commandArgs(argc, argv);
// Set debug level, 0 is off, 9 is highest presently used
// May be overridden by commandArgs
Verilated::debug(0);
// Randomization reset policy
// May be overridden by commandArgs
Verilated::randReset(2);
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
// This needs to be called before you create any model
Verilated::commandArgs(argc, argv);
// General logfile
ios::sync_with_stdio();
+77 -9
View File
@@ -33,7 +33,7 @@
#include <cctype>
#include <sys/stat.h> // mkdir
#if defined(WIN32) || defined(__MINGW32__)
#if defined(_WIN32) || defined(__MINGW32__)
# include <direct.h> // mkdir
#endif
@@ -208,6 +208,7 @@ void VL_PRINTF_MT(const char* formatp, ...) VL_MT_SAFE {
Verilated::Serialized::Serialized() {
s_randReset = 0;
s_randSeed = 0;
s_debug = 0;
s_calcUnusedSigs = false;
s_gotFinish = false;
@@ -245,18 +246,25 @@ vluint64_t vl_rand64() VL_MT_SAFE {
static VL_THREAD_LOCAL bool t_seeded = false;
static VL_THREAD_LOCAL vluint64_t t_state[2];
if (VL_UNLIKELY(!t_seeded)) {
t_seeded = true;
{
VerilatedLockGuard lock(s_mutex);
t_state[0] = ((static_cast<vluint64_t>(vl_sys_rand32()) << 32)
^ (static_cast<vluint64_t>(vl_sys_rand32())));
t_state[1] = ((static_cast<vluint64_t>(vl_sys_rand32()) << 32)
^ (static_cast<vluint64_t>(vl_sys_rand32())));
t_seeded = true;
{
VerilatedLockGuard lock(s_mutex);
if (Verilated::randSeed() != 0) {
t_state[0] = ((static_cast<vluint64_t>(Verilated::randSeed()) << 32)
^ (static_cast<vluint64_t>(Verilated::randSeed())));
t_state[1] = ((static_cast<vluint64_t>(Verilated::randSeed()) << 32)
^ (static_cast<vluint64_t>(Verilated::randSeed())));
} else {
t_state[0] = ((static_cast<vluint64_t>(vl_sys_rand32()) << 32)
^ (static_cast<vluint64_t>(vl_sys_rand32())));
t_state[1] = ((static_cast<vluint64_t>(vl_sys_rand32()) << 32)
^ (static_cast<vluint64_t>(vl_sys_rand32())));
}
// Fix state as algorithm is slow to randomize if many zeros
// This causes a loss of ~ 1 bit of seed entropy, no big deal
if (VL_COUNTONES_I(t_state[0]) < 10) t_state[0] = ~t_state[0];
if (VL_COUNTONES_I(t_state[1]) < 10) t_state[1] = ~t_state[1];
}
}
}
// Xoroshiro128+ algorithm
vluint64_t result = t_state[0] + t_state[1];
@@ -1376,6 +1384,59 @@ void VL_WRITEMEM_N(
fclose(fp);
}
IData VL_FREAD_I(int width, int array_lsb, int array_size,
void* memp, IData fpi, IData start, IData count) VL_MT_SAFE {
// While threadsafe, each thread can only access different file handles
FILE* fp = VL_CVT_I_FP(fpi);
if (VL_UNLIKELY(!fp)) return 0;
if (count > (array_size - (start - array_lsb))) count = array_size - (start - array_lsb);
// Prep for reading
IData read_count = 0;
IData read_elements = 0;
int start_shift = (width-1) & ~7; // bit+7:bit gets first character
int shift = start_shift;
// Read the data
// We process a character at a time, as then we don't need to deal
// with changing buffer sizes dynamically, etc.
while (1) {
int c = fgetc(fp);
if (VL_UNLIKELY(c==EOF)) break;
// Shift value in
IData entry = read_elements + start - array_lsb;
if (width <= 8) {
CData* datap = &(reinterpret_cast<CData*>(memp))[entry];
if (shift == start_shift) { *datap = 0; }
*datap |= (c << shift) & VL_MASK_I(width);
} else if (width <= 16) {
SData* datap = &(reinterpret_cast<SData*>(memp))[entry];
if (shift == start_shift) { *datap = 0; }
*datap |= (c << shift) & VL_MASK_I(width);
} else if (width <= VL_WORDSIZE) {
IData* datap = &(reinterpret_cast<IData*>(memp))[entry];
if (shift == start_shift) { *datap = 0; }
*datap |= (c << shift) & VL_MASK_I(width);
} else if (width <= VL_QUADSIZE) {
QData* datap = &(reinterpret_cast<QData*>(memp))[entry];
if (shift == start_shift) { *datap = 0; }
*datap |= ((static_cast<QData>(c) << static_cast<QData>(shift))
& VL_MASK_Q(width));
} else {
WDataOutP datap = &(reinterpret_cast<WDataOutP>(memp))[ entry*VL_WORDS_I(width) ];
if (shift == start_shift) { VL_ZERO_RESET_W(width, datap); }
datap[VL_BITWORD_I(shift)] |= (c << VL_BITBIT_I(shift));
}
// Prep for next
++read_count;
shift -= 8;
if (shift < 0) {
shift = start_shift;
++read_elements;
if (VL_UNLIKELY(read_elements >= count)) break;
}
}
return read_count;
}
void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int,
QData filename, void* memp, IData start, IData end) VL_MT_SAFE {
WData fnw[2]; VL_SET_WQ(fnw, filename);
@@ -1670,6 +1731,10 @@ void Verilated::randReset(int val) VL_MT_SAFE {
VerilatedLockGuard lock(m_mutex);
s_s.s_randReset = val;
}
void Verilated::randSeed(int val) VL_MT_SAFE {
VerilatedLockGuard lock(m_mutex);
s_s.s_randSeed = val;
}
void Verilated::calcUnusedSigs(bool flag) VL_MT_SAFE {
VerilatedLockGuard lock(m_mutex);
s_s.s_calcUnusedSigs = flag;
@@ -1879,6 +1944,9 @@ void VerilatedImp::commandArgVl(const std::string& arg) {
else if (commandArgVlValue(arg, "+verilator+rand+reset+", value/*ref*/)) {
Verilated::randReset(atoi(value.c_str()));
}
else if (commandArgVlValue(arg, "+verilator+seed+", value/*ref*/)) {
Verilated::randSeed(atoi(value.c_str()));
}
else if (arg == "+verilator+V") {
versionDump(); // Someday more info too
VL_FATAL_MT("COMMAND_LINE", 0, "", "Exiting due to command line argument (not an error)");
+14 -6
View File
@@ -342,7 +342,8 @@ class Verilated {
bool s_assertOn; ///< Assertions are enabled
bool s_fatalOnVpiError; ///< Stop on vpi error/unsupported
// Slow path
int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random
int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random
int s_randSeed; ///< Random seed: 0=random
Serialized();
~Serialized() {}
} s_s;
@@ -396,6 +397,8 @@ public:
/// 2 = Randomize all bits
static void randReset(int val) VL_MT_SAFE;
static int randReset() VL_MT_SAFE { return s_s.s_randReset; } ///< Return randReset value
static void randSeed(int val) VL_MT_SAFE;
static int randSeed() VL_MT_SAFE { return s_s.s_randSeed; } ///< Return randSeed value
/// Enable debug of internal verilated code
static void debug(int level) VL_MT_SAFE;
@@ -435,7 +438,9 @@ public:
static void flushCb(VerilatedVoidCb cb) VL_MT_SAFE;
static void flushCall() VL_MT_SAFE;
/// Record command line arguments, for retrieval by $test$plusargs/$value$plusargs
/// Record command line arguments, for retrieval by $test$plusargs/$value$plusargs,
/// and for parsing +verilator+ run-time arguments.
/// This should be called before the first model is created.
static void commandArgs(int argc, const char** argv) VL_MT_SAFE;
static void commandArgs(int argc, char** argv) VL_MT_SAFE {
commandArgs(argc, const_cast<const char**>(argv)); }
@@ -560,13 +565,13 @@ extern void VL_PRINTF_MT(const char* formatp, ...) VL_ATTR_PRINTF(1) VL_MT_SAFE;
/// Print a debug message from internals with standard prefix, with printf style format
extern void VL_DBG_MSGF(const char* formatp, ...) VL_ATTR_PRINTF(1) VL_MT_SAFE;
extern IData VL_RANDOM_I(int obits); ///< Randomize a signal
extern QData VL_RANDOM_Q(int obits); ///< Randomize a signal
extern IData VL_RANDOM_I(int obits); ///< Randomize a signal
extern QData VL_RANDOM_Q(int obits); ///< Randomize a signal
extern WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp); ///< Randomize a signal
/// Init time only, so slow is fine
extern IData VL_RAND_RESET_I(int obits); ///< Random reset a signal
extern QData VL_RAND_RESET_Q(int obits); ///< Random reset a signal
extern IData VL_RAND_RESET_I(int obits); ///< Random reset a signal
extern QData VL_RAND_RESET_Q(int obits); ///< Random reset a signal
extern WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp); ///< Random reset a signal
extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp); ///< Zero reset a signal (slow - else use VL_ZERO_W)
@@ -589,6 +594,9 @@ inline IData VL_FOPEN_II(IData filename, IData mode) VL_MT_SAFE {
extern void VL_FCLOSE_I(IData fdi);
extern IData VL_FREAD_I(int width, int array_lsb, int array_size,
void* memp, IData fpi, IData start, IData count);
extern void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
WDataInP filenamep, void* memp, IData start, IData end);
extern void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int fnwords,
+10 -9
View File
@@ -558,19 +558,20 @@ int AstNodeDType::widthPow2() const {
return 1;
}
AstNode* AstArraySel::baseFromp(AstNode* nodep) { ///< What is the base variable (or const) this dereferences?
AstNode* AstArraySel::baseFromp(AstNode* nodep) { ///< What is the base variable (or const) this dereferences?
// Else AstArraySel etc; search for the base
while (nodep) {
if (VN_IS(nodep, ArraySel)) { nodep=VN_CAST(nodep, ArraySel)->fromp(); continue; }
else if (VN_IS(nodep, Sel)) { nodep=VN_CAST(nodep, Sel)->fromp(); continue; }
// AstNodeSelPre stashes the associated variable under an ATTROF of AstAttrType::VAR_BASE/MEMBER_BASE so it isn't constified
else if (VN_IS(nodep, AttrOf)) { nodep=VN_CAST(nodep, AttrOf)->fromp(); continue; }
if (VN_IS(nodep, ArraySel)) { nodep = VN_CAST(nodep, ArraySel)->fromp(); continue; }
else if (VN_IS(nodep, Sel)) { nodep = VN_CAST(nodep, Sel)->fromp(); continue; }
// AstNodeSelPre stashes the associated variable under an ATTROF
// of AstAttrType::VAR_BASE/MEMBER_BASE so it isn't constified
else if (VN_IS(nodep, AttrOf)) { nodep = VN_CAST(nodep, AttrOf)->fromp(); continue; }
else if (VN_IS(nodep, NodePreSel)) {
if (VN_CAST(nodep, NodePreSel)->attrp()) {
nodep=VN_CAST(nodep, NodePreSel)->attrp();
} else {
nodep=VN_CAST(nodep, NodePreSel)->lhsp();
}
nodep = VN_CAST(nodep, NodePreSel)->attrp();
} else {
nodep = VN_CAST(nodep, NodePreSel)->lhsp();
}
continue;
}
else break;
+95 -59
View File
@@ -927,7 +927,7 @@ class AstSelPlus : public AstNodePreSel {
// Gets replaced during link with AstSel
public:
AstSelPlus(FileLine* fl, AstNode* fromp, AstNode* bitp, AstNode* widthp)
:AstNodePreSel(fl, fromp, bitp, widthp) {}
: AstNodePreSel(fl, fromp, bitp, widthp) {}
ASTNODE_NODE_FUNCS(SelPlus)
AstNode* bitp() const { return rhsp(); }
AstNode* widthp() const { return thsp(); }
@@ -938,7 +938,7 @@ class AstSelMinus : public AstNodePreSel {
// Gets replaced during link with AstSel
public:
AstSelMinus(FileLine* fl, AstNode* fromp, AstNode* bitp, AstNode* widthp)
:AstNodePreSel(fl, fromp, bitp, widthp) {}
: AstNodePreSel(fl, fromp, bitp, widthp) {}
ASTNODE_NODE_FUNCS(SelMinus)
AstNode* bitp() const { return rhsp(); }
AstNode* widthp() const { return thsp(); }
@@ -955,8 +955,8 @@ private:
int m_declElWidth; // If a packed array, the number of bits per element
public:
AstSel(FileLine* fl, AstNode* fromp, AstNode* lsbp, AstNode* widthp)
:AstNodeTriop(fl, fromp, lsbp, widthp) {
m_declElWidth = 1;
: AstNodeTriop(fl, fromp, lsbp, widthp) {
m_declElWidth = 1;
if (VN_IS(widthp, Const)) {
dtypeSetLogicSized(VN_CAST(widthp, Const)->toUInt(),
VN_CAST(widthp, Const)->toUInt(),
@@ -964,9 +964,9 @@ public:
}
}
AstSel(FileLine* fl, AstNode* fromp, int lsb, int bitwidth)
:AstNodeTriop(fl, fromp,
new AstConst(fl,lsb), new AstConst(fl,bitwidth)) {
m_declElWidth = 1;
: AstNodeTriop(fl, fromp,
new AstConst(fl,lsb), new AstConst(fl,bitwidth)) {
m_declElWidth = 1;
dtypeSetLogicSized(bitwidth,bitwidth,AstNumeric::UNSIGNED);
}
ASTNODE_NODE_FUNCS(Sel)
@@ -1076,9 +1076,9 @@ public:
addNOp2p(pinsp);
}
AstMethodSel(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp)
:AstNode(fl), m_name(name) {
setOp1p(fromp);
addNOp2p(pinsp);
: AstNode(fl), m_name(name) {
setOp1p(fromp);
addNOp2p(pinsp);
}
ASTNODE_NODE_FUNCS(MethodSel)
virtual string name() const { return m_name; } // * = Var name
@@ -1144,9 +1144,9 @@ private:
}
public:
AstVar(FileLine* fl, AstVarType type, const string& name, VFlagChildDType, AstNodeDType* dtp)
:AstNode(fl)
, m_name(name), m_origName(name) {
init();
: AstNode(fl)
, m_name(name), m_origName(name) {
init();
combineType(type);
childDTypep(dtp); // Only for parser
dtypep(NULL); // V3Width will resolve
@@ -1154,9 +1154,9 @@ public:
else m_declKwd = AstBasicDTypeKwd::LOGIC;
}
AstVar(FileLine* fl, AstVarType type, const string& name, AstNodeDType* dtp)
:AstNode(fl)
, m_name(name), m_origName(name) {
init();
: AstNode(fl)
, m_name(name), m_origName(name) {
init();
combineType(type);
UASSERT(dtp,"AstVar created with no dtype");
dtypep(dtp);
@@ -1164,24 +1164,24 @@ public:
else m_declKwd = AstBasicDTypeKwd::LOGIC;
}
AstVar(FileLine* fl, AstVarType type, const string& name, VFlagLogicPacked, int wantwidth)
:AstNode(fl)
, m_name(name), m_origName(name) {
init();
combineType(type);
dtypeSetLogicSized(wantwidth,wantwidth,AstNumeric::UNSIGNED);
: AstNode(fl)
, m_name(name), m_origName(name) {
init();
combineType(type);
dtypeSetLogicSized(wantwidth,wantwidth,AstNumeric::UNSIGNED);
m_declKwd = AstBasicDTypeKwd::LOGIC;
}
AstVar(FileLine* fl, AstVarType type, const string& name, VFlagBitPacked, int wantwidth)
:AstNode(fl)
, m_name(name), m_origName(name) {
init();
combineType(type);
dtypeSetLogicSized(wantwidth,wantwidth,AstNumeric::UNSIGNED);
: AstNode(fl)
, m_name(name), m_origName(name) {
init();
combineType(type);
dtypeSetLogicSized(wantwidth,wantwidth,AstNumeric::UNSIGNED);
m_declKwd = AstBasicDTypeKwd::BIT;
}
AstVar(FileLine* fl, AstVarType type, const string& name, AstVar* examplep)
:AstNode(fl)
, m_name(name), m_origName(name) {
: AstNode(fl)
, m_name(name), m_origName(name) {
init();
combineType(type);
if (examplep->childDTypep()) {
@@ -1396,9 +1396,9 @@ private:
AstNodeModule* m_modp; // Module scope corresponds to
public:
AstScope(FileLine* fl, AstNodeModule* modp, const string& name,
AstScope* aboveScopep, AstCell* aboveCellp)
:AstNode(fl)
,m_name(name) ,m_aboveScopep(aboveScopep) ,m_aboveCellp(aboveCellp), m_modp(modp) {}
AstScope* aboveScopep, AstCell* aboveCellp)
: AstNode(fl)
,m_name(name) ,m_aboveScopep(aboveScopep) ,m_aboveCellp(aboveCellp), m_modp(modp) {}
ASTNODE_NODE_FUNCS(Scope)
virtual void cloneRelink();
virtual const char* broken() const;
@@ -1426,8 +1426,8 @@ class AstTopScope : public AstNode {
// Children: SCOPEs
public:
AstTopScope(FileLine* fl, AstScope* ascopep)
:AstNode(fl)
{addNOp2p(ascopep);}
: AstNode(fl)
{addNOp2p(ascopep);}
ASTNODE_NODE_FUNCS(TopScope)
AstNode* stmtsp() const { return op1p(); }
void addStmtsp(AstNode* nodep) { addOp1p(nodep); }
@@ -1446,9 +1446,9 @@ private:
bool m_trace:1; // Tracing is turned on for this scope
public:
AstVarScope(FileLine* fl, AstScope* scopep, AstVar* varp)
:AstNode(fl)
, m_scopep(scopep), m_varp(varp) {
m_circular = false;
: AstNode(fl)
, m_scopep(scopep), m_varp(varp) {
m_circular = false;
m_trace = true;
dtypeFrom(varp);
}
@@ -1517,10 +1517,10 @@ private:
string m_inlinedDots; // Dotted hierarchy flattened out
public:
AstVarXRef(FileLine* fl, const string& name, const string& dotted, bool lvalue)
:AstNodeVarRef(fl, name, NULL, lvalue)
, m_dotted(dotted) { }
: AstNodeVarRef(fl, name, NULL, lvalue)
, m_dotted(dotted) { }
AstVarXRef(FileLine* fl, AstVar* varp, const string& dotted, bool lvalue)
:AstNodeVarRef(fl, varp->name(), varp, lvalue)
: AstNodeVarRef(fl, varp->name(), varp, lvalue)
, m_dotted(dotted) {
dtypeFrom(varp);
}
@@ -1555,16 +1555,16 @@ private:
bool m_svImplicit; // Pin is SystemVerilog .name'ed
public:
AstPin(FileLine* fl, int pinNum, const string& name, AstNode* exprp)
:AstNode(fl)
,m_name(name), m_param(false), m_svImplicit(false) {
m_pinNum = pinNum;
m_modVarp = NULL;
m_modPTypep = NULL;
setNOp1p(exprp);
: AstNode(fl)
,m_name(name), m_param(false), m_svImplicit(false) {
m_pinNum = pinNum;
m_modVarp = NULL;
m_modPTypep = NULL;
setNOp1p(exprp);
}
AstPin(FileLine* fl, int pinNum, AstVarRef* varname, AstNode* exprp)
:AstNode(fl), m_param(false), m_svImplicit(false) {
m_name = varname->name();
: AstNode(fl), m_param(false), m_svImplicit(false) {
m_name = varname->name();
m_pinNum = pinNum;
m_modVarp = NULL;
m_modPTypep = NULL;
@@ -1903,8 +1903,8 @@ private:
string m_name; // Name of pin
public:
AstPort(FileLine* fl, int pinnum, const string& name)
:AstNode(fl)
,m_pinNum(pinnum) ,m_name(name) {}
: AstNode(fl)
,m_pinNum(pinnum) ,m_name(name) {}
ASTNODE_NODE_FUNCS(Port)
virtual string name() const { return m_name; } // * = Port name
int pinNum() const { return m_pinNum; } // * = Pin number, for order based instantiation
@@ -1939,7 +1939,7 @@ private:
string m_name;
public:
AstParseRef(FileLine* fl, AstParseRefExp expect, const string& name, AstNode* lhsp, AstNodeFTaskRef* ftaskrefp)
:AstNode(fl), m_expect(expect), m_name(name) { setNOp1p(lhsp); setNOp2p(ftaskrefp); }
: AstNode(fl), m_expect(expect), m_name(name) { setNOp1p(lhsp); setNOp2p(ftaskrefp); }
ASTNODE_NODE_FUNCS(ParseRef)
virtual void dump(std::ostream& str);
virtual string name() const { return m_name; } // * = Var name
@@ -1984,7 +1984,7 @@ class AstDot : public AstNode {
// These are eliminated in the link stage
public:
AstDot(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
:AstNode(fl) { setOp1p(lhsp); setOp2p(rhsp); }
: AstNode(fl) { setOp1p(lhsp); setOp2p(rhsp); }
ASTNODE_NODE_FUNCS(Dot)
static AstNode* newIfPkg(FileLine*fl, AstPackage* packagep, AstNode* rhsp) { // For parser, make only if non-null package
if (!packagep) return rhsp;
@@ -2003,7 +2003,7 @@ class AstTask : public AstNodeFTask {
// A task inside a module
public:
AstTask(FileLine* fl, const string& name, AstNode* stmtp)
:AstNodeFTask(fl, name, stmtp) {}
: AstNodeFTask(fl, name, stmtp) {}
ASTNODE_NODE_FUNCS(Task)
};
@@ -2011,8 +2011,8 @@ class AstFunc : public AstNodeFTask {
// A function inside a module
public:
AstFunc(FileLine* fl, const string& name, AstNode* stmtp, AstNode* fvarsp)
:AstNodeFTask(fl, name, stmtp) {
addNOp1p(fvarsp);
: AstNodeFTask(fl, name, stmtp) {
addNOp1p(fvarsp);
}
ASTNODE_NODE_FUNCS(Func)
virtual bool hasDType() const { return true; }
@@ -2022,9 +2022,9 @@ class AstTaskRef : public AstNodeFTaskRef {
// A reference to a task
public:
AstTaskRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp)
:AstNodeFTaskRef(fl, namep, pinsp) {}
: AstNodeFTaskRef(fl, namep, pinsp) {}
AstTaskRef(FileLine* fl, const string& name, AstNode* pinsp)
:AstNodeFTaskRef(fl, name, pinsp) {}
: AstNodeFTaskRef(fl, name, pinsp) {}
ASTNODE_NODE_FUNCS(TaskRef)
virtual bool isStatement() const { return true; } // A statement, unlike FuncRef
};
@@ -2033,9 +2033,9 @@ class AstFuncRef : public AstNodeFTaskRef {
// A reference to a function
public:
AstFuncRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp)
:AstNodeFTaskRef(fl, namep, pinsp) {}
: AstNodeFTaskRef(fl, namep, pinsp) {}
AstFuncRef(FileLine* fl, const string& name, AstNode* pinsp)
:AstNodeFTaskRef(fl, name, pinsp) {}
: AstNodeFTaskRef(fl, name, pinsp) {}
ASTNODE_NODE_FUNCS(FuncRef)
virtual bool isStatement() const { return false; } // Not a statement, unlike TaskRef
virtual bool hasDType() const { return true; }
@@ -2050,7 +2050,7 @@ private:
string m_cname; // Name of function on c side
public:
AstDpiExport(FileLine* fl, const string& vname, const string& cname)
:AstNode(fl), m_name(vname), m_cname(cname) { }
: AstNode(fl), m_name(vname), m_cname(cname) { }
ASTNODE_NODE_FUNCS(DpiExport)
virtual string name() const { return m_name; }
virtual void name(const string& name) { m_name = name; }
@@ -2741,6 +2741,42 @@ public:
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
};
class AstFRead : public AstNodeMath {
// Parents: expr
// Children: varrefs to load
// Children: file which must be a varref
// Children: low index
// Children: count
public:
AstFRead(FileLine* fileline, AstNode* memp, AstNode* filep,
AstNode* startp, AstNode* countp)
: AstNodeMath(fileline) {
setOp1p(memp);
setOp2p(filep);
setNOp3p(startp);
setNOp4p(countp);
}
ASTNODE_NODE_FUNCS(FRead)
virtual string verilogKwd() const { return "$fread"; }
virtual string emitVerilog() { V3ERROR_NA; return ""; }
virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool isGateOptimizable() const { return false; }
virtual bool isPredictOptimizable() const { return false; }
virtual bool isPure() const { return false; } // SPECIAL: has 'visual' ordering
virtual bool isOutputter() const { return true; } // SPECIAL: makes output
virtual bool cleanOut() { return false; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(const AstNode* samep) const { return true; }
AstNode* memp() const { return op1p(); }
void memp(AstNode* nodep) { setOp1p(nodep); }
AstNode* filep() const { return op2p(); }
void filep(AstNode* nodep) { setOp2p(nodep); }
AstNode* startp() const { return op3p(); }
void startp(AstNode* nodep) { setNOp3p(nodep); }
AstNode* countp() const { return op4p(); }
void countp(AstNode* nodep) { setNOp4p(nodep); }
};
class AstFScanF : public AstNodeMath {
// Parents: expr
// Children: file which must be a varref
+39
View File
@@ -387,6 +387,45 @@ public:
puts(")); }\n");
}
}
virtual void visit(AstFRead* nodep) {
puts("VL_FREAD_I(");
puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width
putbs(",");
bool memory = false;
uint32_t array_lsb = 0;
uint32_t array_size = 0;
{
const AstVarRef* varrefp = VN_CAST(nodep->memp(), VarRef);
if (!varrefp) { nodep->v3error(nodep->verilogKwd() << " loading non-variable"); }
else if (VN_CAST(varrefp->varp()->dtypeSkipRefp(), BasicDType)) { }
else if (const AstUnpackArrayDType* adtypep
= VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) {
memory = true;
array_lsb = adtypep->lsb();
array_size = adtypep->elementsConst();
}
else {
nodep->v3error(nodep->verilogKwd()
<< " loading other than unpacked-array variable");
}
}
puts(cvtToStr(array_lsb));
putbs(",");
puts(cvtToStr(array_size));
putbs(", ");
if (!memory) puts("&(");
iterateAndNextNull(nodep->memp());
if (!memory) puts(")");
putbs(", ");
iterateAndNextNull(nodep->filep());
putbs(", ");
if (nodep->startp()) iterateAndNextNull(nodep->startp());
else puts(cvtToStr(array_lsb));
putbs(", ");
if (nodep->countp()) iterateAndNextNull(nodep->countp());
else puts(cvtToStr(array_size));
puts(");\n");
}
virtual void visit(AstSysFuncAsTask* nodep) {
if (!nodep->lhsp()->isWide()) puts("(void)");
iterateAndNextNull(nodep->lhsp());
+4 -2
View File
@@ -46,9 +46,11 @@ class EmitCInlines : EmitCBaseVisitor {
v3Global.needHeavy(true);
}
}
virtual void visit(AstValuePlusArgs* nodep) {
v3Global.needHeavy(true);
iterateChildren(nodep);
}
// NOPs
virtual void visit(AstNodeStmt*) {}
// Default
virtual void visit(AstNode* nodep) {
iterateChildren(nodep);
+10 -7
View File
@@ -49,8 +49,9 @@ public:
I_DEF_NETTYPE_WIRE, // `default_nettype is WIRE (false=NONE)
// Error codes:
E_DETECTARRAY, // Error: Unsupported: Can't detect changes on arrayed variable
E_MULTITOP, // Error: Multiple top level modules
E_TASKNSVAR, // Error: Task I/O not simple
E_MULTITOP, // Error: Multiple top level modules
E_PORTSHORT, // Error: Output port is connected to a constant, electrical short
E_TASKNSVAR, // Error: Task I/O not simple
//
// Warning codes:
EC_FIRST_WARN, // Just a code so the program knows where to start warnings
@@ -77,7 +78,8 @@ public:
ENDLABEL, // End lable name mismatch
GENCLK, // Generated Clock
IFDEPTH, // If statements too deep
IMPERFECTSCH, // Imperfect schedule (disabled by default)
IGNOREDRETURN, // Ignoring return value (funcation as task)
IMPERFECTSCH, // Imperfect schedule (disabled by default)
IMPLICIT, // Implicit wire
IMPORTSTAR, // Import::* in $unit
IMPURE, // Impure function not being inlined
@@ -128,9 +130,9 @@ public:
" MIN", " INFO", " FATAL", " FATALSRC", " ERROR",
// Boolean
" I_COVERAGE", " I_TRACING", " I_LINT", " I_DEF_NETTYPE_WIRE",
// Errors
"DETECTARRAY", "MULTITOP", "TASKNSVAR",
// Warnings
// Errors
"DETECTARRAY", "MULTITOP", "PORTSHORT", "TASKNSVAR",
// Warnings
" EC_FIRST_WARN",
"ALWCOMBORDER", "ASSIGNDLY", "ASSIGNIN",
"BLKANDNBLK", "BLKLOOPINIT", "BLKSEQ", "BSSPACE",
@@ -138,7 +140,8 @@ public:
"CMPCONST", "COLONPLUS", "COMBDLY", "CONTASSREG",
"DEFPARAM", "DECLFILENAME",
"ENDLABEL", "GENCLK",
"IFDEPTH", "IMPERFECTSCH", "IMPLICIT", "IMPORTSTAR", "IMPURE",
"IFDEPTH", "IGNOREDRETURN",
"IMPERFECTSCH", "IMPLICIT", "IMPORTSTAR", "IMPURE",
"INCABSPATH", "INFINITELOOP", "INITIALDLY",
"LITENDIAN", "MODDUP",
"MULTIDRIVEN",
+1
View File
@@ -91,6 +91,7 @@ protected:
friend class V3ParseImp;
friend class V3PreLex;
friend class V3PreProcImp;
friend class V3PreShellImp;
void lineno(int num) { m_lineno = num; }
void language(V3LangCode lang) { singleton().numberToLang(m_filenameno, lang); }
void filename(const string& name) { m_filenameno = singleton().nameToNumber(name); }
+2 -5
View File
@@ -550,14 +550,11 @@ private:
AstVar* pinNewVarp = pinOldVarp->clonep();
if (!pinNewVarp) pinOldVarp->v3fatalSrc("Cloning failed");
AstNode* connectRefp = pinp->exprp();
AstNode* connectRefp = pinp->exprp();
if (!VN_IS(connectRefp, Const) && !VN_IS(connectRefp, VarRef)) {
pinp->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up");
}
if (pinNewVarp->direction() == VDirection::OUTPUT
&& VN_IS(connectRefp, Const)) {
pinp->v3error("Output port is connected to a constant pin, electrical short");
}
V3Inst::checkOutputShort(pinp);
// Propagate any attributes across the interconnect
pinNewVarp->propagateAttrFrom(pinOldVarp);
+18 -7
View File
@@ -68,10 +68,7 @@ private:
UINFO(4," PIN "<<nodep<<endl);
if (!nodep->exprp()) return; // No-connect
if (debug()>=9) nodep->dumpTree(cout," Pin_oldb: ");
if (nodep->modVarp()->direction() == VDirection::OUTPUT
&& VN_IS(nodep->exprp(), Const)) {
nodep->v3error("Output port is connected to a constant pin, electrical short");
}
V3Inst::checkOutputShort(nodep);
// Use user1p on the PIN to indicate we created an assign for this pin
if (!nodep->user1SetOnce()) {
// Simplify it
@@ -513,8 +510,9 @@ public:
// Done. Constant.
} else {
// Make a new temp wire
//if (1||debug()>=9) { pinp->dumpTree(cout,"-in_pin:"); }
AstNode* pinexprp = pinp->exprp()->unlinkFrBack();
//if (1||debug()>=9) { pinp->dumpTree(cout,"-in_pin:"); }
V3Inst::checkOutputShort(pinp);
AstNode* pinexprp = pinp->exprp()->unlinkFrBack();
string newvarname = (string(pinVarp->isWritable() ? "__Vcellout" : "__Vcellinp")
// Prevent name conflict if both tri & non-tri add signals
+(forTristate?"t":"")
@@ -555,10 +553,23 @@ public:
// Inst class functions
AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp,
bool forTristate, bool alwaysCvt) {
bool forTristate, bool alwaysCvt) {
return InstStatic::pinReconnectSimple(pinp, cellp, forTristate, alwaysCvt);
}
void V3Inst::checkOutputShort(AstPin* nodep) {
if (nodep->modVarp()->direction() == VDirection::OUTPUT) {
if (VN_IS(nodep->exprp(), Const)
|| VN_IS(nodep->exprp(), Extend)
|| (VN_IS(nodep->exprp(), Concat)
&& (VN_IS(VN_CAST(nodep->exprp(), Concat)->lhsp(), Const)))) {
// Uses v3warn for error, as might be found multiple times
nodep->v3warn(E_PORTSHORT, "Output port is connected to a constant pin,"
" electrical short");
}
}
}
//######################################################################
// Inst class visitor
+1
View File
@@ -35,6 +35,7 @@ public:
static void dearrayAll(AstNetlist* nodep);
static AstAssignW* pinReconnectSimple(AstPin* pinp, AstCell* cellp,
bool forTristate, bool alwaysCvt=false);
static void checkOutputShort(AstPin* nodep);
};
#endif // Guard
+9
View File
@@ -131,6 +131,15 @@ private:
}
m_setRefLvalue = last_setRefLvalue;
}
virtual void visit(AstFRead* nodep) {
bool last_setRefLvalue = m_setRefLvalue;
{
m_setRefLvalue = true;
iterateAndNextNull(nodep->memp());
iterateAndNextNull(nodep->filep());
}
m_setRefLvalue = last_setRefLvalue;
}
virtual void visit(AstFScanF* nodep) {
bool last_setRefLvalue = m_setRefLvalue;
{
+9
View File
@@ -210,6 +210,11 @@ private:
} else if (AstEnumItemRef* fromp = VN_CAST(basefromp, EnumItemRef)) {
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::ENUM_BASE,
fromp->cloneTree(false)));
} else if (VN_IS(basefromp, Replicate)) {
// From {...}[...] syntax in IEEE 2017
if (basefromp) { UINFO(1," Related node: "<<basefromp<<endl); }
nodep->v3error("Unsupported: Select of concatenation");
nodep = NULL;
} else {
if (basefromp) { UINFO(1," Related node: "<<basefromp<<endl); }
nodep->v3fatalSrc("Illegal bit select; no signal/member being extracted from");
@@ -362,6 +367,10 @@ private:
iterateChildren(nodep);
expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef));
}
virtual void visit(AstFRead* nodep) {
iterateChildren(nodep);
expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef));
}
virtual void visit(AstFScanF* nodep) {
iterateChildren(nodep);
expectFormat(nodep, nodep->text(), nodep->exprsp(), true);
+1 -1
View File
@@ -36,7 +36,7 @@
#include <sys/time.h>
#include <sys/types.h>
#if defined(WIN32) || defined(__MINGW32__)
#if defined(_WIN32) || defined(__MINGW32__)
# include <direct.h> // mkdir
#endif
-11
View File
@@ -115,17 +115,6 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
m_fileline = new FileLine(fileline);
m_inLibrary = inLibrary;
// Set language standard up front
if (!v3Global.opt.preprocOnly()) {
// Leting lex parse this saves us from having to specially en/decode
// from the V3LangCode to the various Lex BEGIN states. The language
// of this source file is updated here, in case there have been any
// intervening +<lang>ext+ options since it was first ecountered.
FileLine *modfileline = new FileLine(modfilename, 0);
modfileline->language(v3Global.opt.fileLanguage(modfilename));
ppPushText(string("`begin_keywords \"")+modfileline->language().ascii()+"\"\n");
}
// Preprocess into m_ppBuffer
bool ok = V3PreShell::preproc(fileline, modfilename, m_filterp, this, errmsg);
if (!ok) {
+24 -8
View File
@@ -102,8 +102,20 @@ protected:
// Preprocess
s_filterp = filterp;
bool ok = preprocOpen(fl, s_filterp, modname, "", errmsg);
if (!ok) return false;
string modfilename = preprocOpen(fl, s_filterp, modname, "", errmsg);
if (modfilename.empty()) return false;
// Set language standard up front
if (!v3Global.opt.preprocOnly()) {
// Leting lex parse this saves us from having to specially en/decode
// from the V3LangCode to the various Lex BEGIN states. The language
// of this source file is updated here, in case there have been any
// intervening +<lang>ext+ options since it was first ecountered.
FileLine* modfileline = new FileLine(modfilename, 0);
modfileline->language(v3Global.opt.fileLanguage(modfilename));
V3Parse::ppPushText(parsep, (string("`begin_keywords \"")
+modfileline->language().ascii()+"\"\n"));
}
while (!s_preprocp->isEof()) {
string line = s_preprocp->getline();
@@ -116,12 +128,15 @@ protected:
if (modname[0]=='/' || modname[0]=='\\') {
fl->v3warn(INCABSPATH,"Suggest `include with absolute path be made relative, and use +include: "<<modname);
}
preprocOpen(fl, s_filterp, modname, V3Os::filenameDir(fl->filename()), "Cannot find include file: ");
preprocOpen(fl, s_filterp, modname, V3Os::filenameDir(fl->filename()),
"Cannot find include file: ");
}
bool preprocOpen(FileLine* fl, V3InFilter* filterp, const string& modname, const string& lastpath,
const string& errmsg) { // Error message or "" to suppress
// Returns true if successful
private:
string preprocOpen(FileLine* fl, V3InFilter* filterp,
const string& modname, const string& lastpath,
const string& errmsg) { // Error message or "" to suppress
// Returns filename if successful
// Try a pure name in case user has a bogus `filename they don't expect
string filename = v3Global.opt.filePath(fl, modname, lastpath, errmsg);
if (filename=="") {
@@ -131,13 +146,14 @@ protected:
filename = v3Global.opt.filePath(fl, ppmodname, lastpath, errmsg);
}
if (filename=="") return false; // Not found
if (filename=="") return ""; // Not found
UINFO(2," Reading "<<filename<<endl);
s_preprocp->openFile(fl, filterp, filename);
return true;
return filename;
}
public:
// CONSTRUCTORS
V3PreShellImp() {}
~V3PreShellImp() {}
+9 -5
View File
@@ -1170,11 +1170,15 @@ private:
nodep->replaceWith(outrefp);
// Insert new statements
visitp = insertBeforeStmt(nodep, beginp);
} else {
// outvscp maybe non-NULL if calling a function in a taskref,
// but if so we want to simply ignore the function result
nodep->replaceWith(beginp);
}
} else {
if (nodep->taskp()->isFunction()) {
nodep->v3warn(IGNOREDRETURN,
"Ignoring return value of non-void function (IEEE 2017 13.4.1)");
}
// outvscp maybe non-NULL if calling a function in a taskref,
// but if so we want to simply ignore the function result
nodep->replaceWith(beginp);
}
// Cleanup
nodep->deleteTree(); VL_DANGLING(nodep);
UINFO(4," FTask REF Done.\n");
+25
View File
@@ -2232,6 +2232,19 @@ private:
userIterateAndNext(nodep->strgp(), WidthVP(SELF,BOTH).p());
}
}
virtual void visit(AstFRead* nodep) {
if (m_vup->prelim()) {
nodep->dtypeSetSigned32(); // Spec says integer return
userIterateAndNext(nodep->memp(), WidthVP(SELF,BOTH).p());
iterateCheckFileDesc(nodep, nodep->filep(), BOTH);
if (nodep->startp()) {
iterateCheckSigned32(nodep, "$fread start", nodep->startp(), BOTH);
}
if (nodep->countp()) {
iterateCheckSigned32(nodep, "$fread count", nodep->countp(), BOTH);
}
}
}
virtual void visit(AstFScanF* nodep) {
if (m_vup->prelim()) {
nodep->dtypeSetSigned32(); // Spec says integer return
@@ -3172,6 +3185,18 @@ private:
underp = iterateCheck(nodep,"file_descriptor",underp,SELF,FINAL,expDTypep,EXTEND_EXP);
if (underp) {} // cppcheck
}
void iterateCheckSigned32(AstNode* nodep, const char* side, AstNode* underp, Stage stage) {
// Coerce child to signed32 if not already. Child is self-determined
// underp may change as a result of replacement
if (stage & PRELIM) {
underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF, PRELIM).p());
}
if (stage & FINAL) {
AstNodeDType* expDTypep = nodep->findSigned32DType();
underp = iterateCheck(nodep, side, underp, SELF, FINAL, expDTypep, EXTEND_EXP);
}
if (underp) {} // cppcheck
}
void iterateCheckReal(AstNode* nodep, const char* side, AstNode* underp, Stage stage) {
// Coerce child to real if not already. Child is self-determined
// e.g. nodep=ADDD, underp=ADD in ADDD(ADD(a,b), real-CONST)
+2 -2
View File
@@ -325,7 +325,7 @@ sub clean_input {
foreach my $line (@linesin) {
$l++;
if ($line =~ /BISONPRE_NOT/) {
($line =~ s/BISONPRE_NOT\((\S+)\)\s*({[^}]+})\s*$//)
($line =~ s/BISONPRE_NOT\((\S+)\)\s*(\{[^}]+})\s*$//)
or die "%Error: $filename:$l: Bad form of BISONPRE_NOT: $line\n";
my $endtok = $1; my $action = $2;
my @endtoks = split (/,/, $endtok);
@@ -412,7 +412,7 @@ sub _bisonpre_copy {
my $l = shift;
my $depth = shift;
while ($text =~ /BISONPRE_COPY/) {
($text =~ s/BISONPRE_COPY(_ONCE)?\((\S+)\s*,\s*{([^}]*)}\s*\)/{HERE}/)
($text =~ s/BISONPRE_COPY(_ONCE)?\((\S+)\s*,\s*\{([^}]*)}\s*\)/{HERE}/)
or die "%Error: $Self->{filename}:$l: Bad form of BISONPRE_NOT: $text\n";
my $once = $1; my $rule = $2; my $code = $3;
$Self->{rules}{$rule} or die "%Error: $Self->{filename}:$l: Can't find definition for rule: $rule\n";
+1
View File
@@ -227,6 +227,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"$finish" { FL; return yD_FINISH; }
"$floor" { FL; return yD_FLOOR; }
"$fopen" { FL; return yD_FOPEN; }
"$fread" { FL; return yD_FREAD; }
"$fscanf" { FL; return yD_FSCANF; }
"$fullskew" { FL; return yaTIMINGSPEC; }
"$fwrite" { FL; return yD_FWRITE; }
+27 -3
View File
@@ -475,6 +475,7 @@ class AstSenTree;
%token<fl> yD_FINISH "$finish"
%token<fl> yD_FLOOR "$floor"
%token<fl> yD_FOPEN "$fopen"
%token<fl> yD_FREAD "$fread"
%token<fl> yD_FSCANF "$fscanf"
%token<fl> yD_FWRITE "$fwrite"
%token<fl> yD_HIGH "$high"
@@ -2390,8 +2391,21 @@ statement_item<nodep>: // IEEE: statement_item
// // Below under expr
//
// // IEEE: subroutine_call_statement
//UNSUP yVOID yP_TICK '(' function_subroutine_callNoMethod ')' ';' { }
//UNSUP yVOID yP_TICK '(' expr '.' function_subroutine_callNoMethod ')' ';' { }
// // IEEE says we then expect a function call
// // (function_subroutine_callNoMethod), but rest of
// // the code expects an AstTask when used as a statement,
// // so parse as if task
// // Alternative would be shim with new AstVoidStmt.
| yVOID yP_TICK '(' task_subroutine_callNoMethod ')' ';'
{ $$ = $4;
FileLine* newfl = new FileLine($$->fileline());
newfl->warnOff(V3ErrorCode::IGNOREDRETURN, true);
$$->fileline(newfl); }
| yVOID yP_TICK '(' expr '.' task_subroutine_callNoMethod ')' ';'
{ $$ = new AstDot($5, $4, $6);
FileLine* newfl = new FileLine($6->fileline());
newfl->warnOff(V3ErrorCode::IGNOREDRETURN, true);
$6->fileline(newfl); }
// // Expr included here to resolve our not knowing what is a method call
// // Expr here must result in a subroutine_call
| task_subroutine_callNoMethod ';' { $$ = $1; }
@@ -2815,6 +2829,9 @@ system_f_call_or_t<nodep>: // IEEE: part of system_tf_call (can be task or func)
| yD_FEOF '(' expr ')' { $$ = new AstFEof($1,$3); }
| yD_FGETC '(' expr ')' { $$ = new AstFGetC($1,$3); }
| yD_FGETS '(' idClassSel ',' expr ')' { $$ = new AstFGetS($1,$3,$5); }
| yD_FREAD '(' idClassSel ',' expr ')' { $$ = new AstFRead($1,$3,$5,NULL,NULL); }
| yD_FREAD '(' idClassSel ',' expr ',' expr ')' { $$ = new AstFRead($1,$3,$5,$7,NULL); }
| yD_FREAD '(' idClassSel ',' expr ',' expr ',' expr ')' { $$ = new AstFRead($1,$3,$5,$7,$9); }
| yD_FLOOR '(' expr ')' { $$ = new AstFloorD($1,$3); }
| yD_FSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstFScanF($1,*$5,$3,$6); }
| yD_HIGH '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_HIGH,$3,NULL); }
@@ -3278,6 +3295,13 @@ exprOkLvalue<nodep>: // expression that's also OK to use as a variable_lvalue
// // IEEE: concatenation/constant_concatenation
// // Replicate(1) required as otherwise "{a}" would not be self-determined
| '{' cateList '}' { $$ = new AstReplicate($1,$2,1); }
| '{' cateList '}' '[' expr ']' { $$ = new AstSelBit($4, new AstReplicate($1,$2,1), $5); }
| '{' cateList '}' '[' constExpr ':' constExpr ']'
{ $$ = new AstSelExtract($4, new AstReplicate($1,$2,1), $5, $7); }
| '{' cateList '}' '[' expr yP_PLUSCOLON constExpr ']'
{ $$ = new AstSelPlus($4, new AstReplicate($1,$2,1), $5, $7); }
| '{' cateList '}' '[' expr yP_MINUSCOLON constExpr ']'
{ $$ = new AstSelMinus($4, new AstReplicate($1,$2,1), $5, $7); }
// // IEEE: assignment_pattern_expression
// // IEEE: [ assignment_pattern_expression_type ] == [ ps_type_id /ps_paremeter_id/data_type]
// // We allow more here than the spec requires
@@ -3961,7 +3985,7 @@ void V3ParseGrammar::argWrapList(AstNodeFTaskRef* nodep) {
}
AstNode* V3ParseGrammar::createSupplyExpr(FileLine* fileline, string name, int value) {
FileLine* newfl = new FileLine (fileline);
FileLine* newfl = new FileLine(fileline);
newfl->warnOff(V3ErrorCode::WIDTH, true);
AstNode* nodep = new AstConst(newfl, V3Number(newfl));
// Adding a NOT is less work than figuring out how wide to make it
+66 -55
View File
@@ -77,8 +77,8 @@ our $Opt_Unsupported;
our $Opt_Verilation = 1;
our @Opt_Driver_Verilator_Flags;
Getopt::Long::config ("pass_through");
if (! GetOptions (
Getopt::Long::config("pass_through");
if (! GetOptions(
"benchmark:i" => sub { $opt_benchmark = $_[1] ? $_[1] : 1; },
"debug" => \&debug,
#debugi see parameter()
@@ -136,6 +136,9 @@ if ($#opt_tests<0) {
if ($#opt_tests>=2 && $opt_jobs>=2) {
# Without this tests such as t_debug_sigsegv_bt_bad.pl will occasionally
# block on input and cause a SIGSTOP, then a "fg" was needed to resume testing.
if (!$::Have_Forker) {
print STDERR "driver.pl: NO_FORKER: For faster testing 'sudo cpan install Parallel::Forker'\n";
}
print STDERR "== Many jobs; redirecting STDIN\n";
open(STDIN, "+>/dev/null");
}
@@ -153,7 +156,7 @@ foreach my $testpl (@opt_tests) {
}
}
$Fork->wait_all(); # Wait for all children to finish
$Fork->wait_all(); # Wait for all children to finish
sub one_test {
my @params = @_;
@@ -173,9 +176,10 @@ sub one_test {
# Don't put anything other than _exit after _read,
# as may call _exit via another path
$test->_exit;
},
run_on_finish => sub {
my $test = VTest->new(@params);
},
run_on_finish => sub {
# RUnning in context of parent
my $test = VTest->new(@params);
$test->_read_status;
if ($test->ok) {
$OkCnt++;
@@ -218,7 +222,7 @@ exit(10) if $FailCnt;
sub usage {
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
exit (1);
exit(1);
}
sub debug {
@@ -310,7 +314,7 @@ use Cwd;
use Data::Dumper;
use File::Spec;
use vars qw ($Self $Self);
use vars qw($Self $Self);
use strict;
sub new {
@@ -366,9 +370,9 @@ sub new {
.($opt_benchmark ? " +define+TEST_BENCHMARK=$opt_benchmark":"")
.($opt_trace ? " +define+WAVES=1":"")
))],
v_flags2 => [], # Overridden in some sim files
v_other_filenames => [], # After the filename so we can spec multiple files
all_run_flags => [],
v_flags2 => [], # Overridden in some sim files
v_other_filenames => [], # After the filename so we can spec multiple files
all_run_flags => [],
pli_flags => ["-I$ENV{VERILATOR_ROOT}/include/vltstd -fPIC -shared"
.(($^O eq "darwin" )
? " -Wl,-undefined,dynamic_lookup"
@@ -390,9 +394,9 @@ sub new {
# IV
iv => 0,
iv_flags => [split(/\s+/,"+define+iverilog -o $self->{obj_dir}/simiv")],
iv_flags2 => [], # Overridden in some sim files
iv_pli => 0, # need to use pli
iv_run_flags => [],
iv_flags2 => [], # Overridden in some sim files
iv_pli => 0, # need to use pli
iv_run_flags => [],
# VCS
vcs => 0,
vcs_flags => [split(/\s+/,"+vcs+lic+wait +cli -debug_access +define+VCS+1 -q -sverilog -CFLAGS '-DVCS' ")],
@@ -420,9 +424,9 @@ sub new {
verilator_flags2 => [],
verilator_flags3 => ["--clk clk"],
verilator_make_gcc => 1,
verilated_debug => $Opt_Verilated_Debug,
stdout_filename => undef, # Redirect stdout
%$self};
verilated_debug => $Opt_Verilated_Debug,
stdout_filename => undef, # Redirect stdout
%$self};
bless $self, $class;
$self->{vlt_all} = $self->{vlt} || $self->{vltmt}; # Any Verilator scenario
@@ -435,8 +439,8 @@ sub new {
$self->{main_filename} ||= "$self->{obj_dir}/$self->{VM_PREFIX}__main.cpp";
($self->{top_filename} ||= $self->{pl_filename}) =~ s/\.pl$//;
($self->{golden_filename} ||= $self->{pl_filename}) =~ s/\.pl$/.out/;
if (-e ($self->{top_filename}.".vhd")) { # If VHDL file exists
$self->{vhdl} = 1;
if (-e ($self->{top_filename}.".vhd")) { # If VHDL file exists
$self->{vhdl} = 1;
$self->{top_filename} .= ".vhd";
} else {
$self->{top_filename} .= ".v";
@@ -580,7 +584,7 @@ sub _read_status {
sub compile_vlt_flags {
my $self = (ref $_[0]? shift : $Self);
my %param = (%{$self}, @_); # Default arguments are from $self
my %param = (%{$self}, @_); # Default arguments are from $self
return 1 if $self->errors || $self->skips || $self->unsupporteds;
my $checkflags = join(' ',@{$param{v_flags}},
@@ -637,7 +641,7 @@ sub compile_vlt_flags {
sub compile {
my $self = (ref $_[0]? shift : $Self);
my %param = (%{$self}, @_); # Default arguments are from $self
my %param = (%{$self}, @_); # Default arguments are from $self
return 1 if $self->errors || $self->skips || $self->unsupporteds;
$self->oprint("Compile\n");
@@ -676,7 +680,7 @@ sub compile {
@{$param{ghdl_flags}},
@{$param{ghdl_flags2}},
#@{$param{v_flags}}, # Not supported
#@{$param{v_flags2}}, # Not supported
#@{$param{v_flags2}}, # Not supported
$param{top_filename},
$param{top_shell_filename},
@{$param{v_other_filenames}},
@@ -809,8 +813,8 @@ sub compile {
sub execute {
my $self = (ref $_[0]? shift : $Self);
return 1 if $self->errors || $self->skips || $self->unsupporteds;
my %param = (%{$self}, @_); # Default arguments are from $self
# params may be expect or {tool}_expect
my %param = (%{$self}, @_); # Default arguments are from $self
# params may be expect or {tool}_expect
$self->oprint("Run\n");
my $run_env = $param{run_env};
@@ -845,10 +849,11 @@ sub execute {
@{$param{iv_run_flags}},
@{$param{all_run_flags}},
);
if ($param{iv_pli}) {
unshift @cmd, "vvp -n -m $self->{obj_dir}/libvpi.so"; # don't enter command line on $stop, include vpi
}
$self->_run(logfile=>"$self->{obj_dir}/iv_sim.log",
if ($param{iv_pli}) {
# don't enter command line on $stop, include vpi
unshift @cmd, "vvp -n -m $self->{obj_dir}/libvpi.so";
}
$self->_run(logfile=>"$self->{obj_dir}/iv_sim.log",
fails=>$param{fails},
cmd=> \@cmd,
%param,
@@ -900,7 +905,7 @@ sub execute {
$param{executable} ||= "$self->{obj_dir}/$param{VM_PREFIX}";
$self->_run(logfile=>"$self->{obj_dir}/vlt_sim.log",
cmd=>[($run_env
.($opt_gdbsim ? ("gdb"||$ENV{VERILATOR_GDB})." " : "")
.($opt_gdbsim ? ($ENV{VERILATOR_GDB}||"gdb")." " : "")
.$param{executable}
.($opt_gdbsim ? " -ex 'run " : "")),
@{$param{all_run_flags}},
@@ -921,7 +926,7 @@ sub inline_checks {
return 1 if $self->errors || $self->skips || $self->unsupporteds;
return 1 if !$self->{vlt_all};
my %param = (%{$self}, @_); # Default arguments are from $self
my %param = (%{$self}, @_); # Default arguments are from $self
my $covfn = $Self->{coverage_filename};
my $contents = $self->file_contents($covfn);
@@ -1057,9 +1062,9 @@ sub _run {
if ($param{logfile}) {
$logfh = IO::File->new(">$param{logfile}") or die "%Error: Can't open $param{logfile}";
}
my $pid=fork();
if ($pid) { # Parent
close CHILDWR;
my $pid=fork();
if ($pid) { # Parent
close CHILDWR;
while (1) {
my $buf = '';
my $got = sysread PARENTRD,$buf,10000;
@@ -1069,9 +1074,9 @@ sub _run {
}
close PARENTRD;
close $logfh if $logfh;
}
else { # Child
close PARENTRD;
}
else { # Child
close PARENTRD;
close $logfh if $logfh;
# Reset signals
$SIG{ALRM} = 'DEFAULT';
@@ -1082,9 +1087,9 @@ sub _run {
autoflush STDOUT 1;
autoflush STDERR 1;
system "$command";
exit ($? ? 10 : 0); # $?<<8 misses coredumps
}
waitpid($pid,0);
exit($? ? 10 : 0); # $?<<8 misses coredumps
}
waitpid($pid,0);
$status = $? || 0;
}
flush STDOUT;
@@ -1131,8 +1136,8 @@ sub _run {
$wholefile =~ s/^- [a-z.0-9]+:\d+:[^\n]+\n//mig;
$wholefile =~ s/^dot [^\n]+\n//mig;
# Compare
my $quoted = quotemeta ($param{expect});
# Compare
my $quoted = quotemeta($param{expect});
my $ok = ($wholefile eq $param{expect}
|| _try_regex($wholefile, $param{expect}) == 1
|| $wholefile =~ /$quoted/ms);
@@ -1503,9 +1508,9 @@ sub _read_inputs_v {
if ($line =~ /^\s*(function|task|endmodule)/) {
$get_sigs = 0;
}
}
if ($line =~ /^\s*module\s+t\b/) { # Ignore any earlier inputs; Module 't' has precedence
%inputs = ();
}
if ($line =~ /^\s*module\s+t\b/) { # Ignore any earlier inputs; Module 't' has precedence
%inputs = ();
$get_sigs = 1;
}
}
@@ -1685,7 +1690,7 @@ sub _vcd_read {
my $self = (ref $_[0]? shift : $Self);
my $filename = shift;
my $data = {};
my $fh = IO::File->new ("<$filename");
my $fh = IO::File->new("<$filename");
if (!$fh) { warn "%Error: $! $filename\n"; return $data; }
my @hier = ($data);
my $lasthier;
@@ -1813,8 +1818,14 @@ sub new {
sub schedule {
my $self = shift;
my %params = (@_);
&{$params{run_on_start}}();
&{$params{run_on_finish}}();
if (my $pid = fork()) { # Parent
waitpid($pid, 0);
} else { # Child
$params{run_on_start}->($self);
exit(0); # Don't close anything
}
$params{run_on_finish}->($self);
return $self;
}
sub max_proc {}
@@ -1865,7 +1876,7 @@ successful tests and then returns 1 as its result.
Both C<compile> and C<execute> take an optional argument hash table to
control their behavior. For example:
compile (
compile(
verilator_flags2 => ["--lint-only"],
fails => 1,
);
@@ -1981,7 +1992,7 @@ require their own C++ or SystemC test harness. This is commonly given the
same name as the test, but with .cpp as suffix
(C<test_regress/t/t_EXAMPLE.cpp>). This can be specified as follows:
compile (
compile(
make_top_shell => 0,
make_main => 0,
verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], );
@@ -1994,22 +2005,22 @@ Verilog C<$stop>) as that signals an error.
If termination should be triggered from the C++ wrapper, the following code
can be used:
vl_fatal (__FILE__, __LINE__, "dut", "<error message goes here>");
exit (1);
vl_fatal(__FILE__, __LINE__, "dut", "<error message goes here>");
exit(1);
This can be particularly useful if checking that the Verilator model has
not unexpectedly terminated.
if (Verilated::gotFinish ()) {
vl_fatal (__FILE__, __LINE__, "dut", "<error message goes here>");
exit (1);
if (Verilated::gotFinish()) {
vl_fatal(__FILE__, __LINE__, "dut", "<error message goes here>");
exit(1);
}
Where it might be useful for a test to produce output, it should qualify
this with C<TEST_VERBOSE>. For example in Verilog:
`ifdef TEST_VERBOSE
$write ("Conditional generate if MASK [%1d] = %d\n", g, MASK[g]);
$write("Conditional generate if MASK [%1d] = %d\n", g, MASK[g]);
`endif
Or in a hand-written C++ wrapper:
+5 -5
View File
@@ -15,8 +15,8 @@ module t (/*AUTOARG*/
input clk;
reg [63:0] crc;
`verilator_file_descriptor fd;
`verilator_file_descriptor fdtmp;
integer fd;
integer fdtmp;
t_case_write1_tasks tasks ();
@@ -33,14 +33,14 @@ module t (/*AUTOARG*/
cyc <= cyc + 1;
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
if (cyc==1) begin
crc <= 64'h00000000_00000097;
crc <= 64'h00000000_00000097;
$write("%s", {"Open ", `STRINGIFY(`TEST_OBJ_DIR), "/t_case_write1_logger.log\n"});
fdtmp = $fopen({`STRINGIFY(`TEST_OBJ_DIR), "/t_case_write1_logger.log"}, "w");
fd <= fdtmp;
end
if (cyc==90) begin
$write("*-* All Finished *-*\n");
$finish;
$write("*-* All Finished *-*\n");
$finish;
end
end
+5 -5
View File
@@ -15,8 +15,8 @@ module t (/*AUTOARG*/
input clk;
reg [63:0] crc;
`verilator_file_descriptor fd;
`verilator_file_descriptor fdtmp;
integer fd;
integer fdtmp;
t_case_write2_tasks tasks ();
@@ -33,14 +33,14 @@ module t (/*AUTOARG*/
cyc <= cyc + 1;
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
if (cyc==1) begin
crc <= 64'h00000000_00000097;
crc <= 64'h00000000_00000097;
$write("%s", {"Open ", `STRINGIFY(`TEST_OBJ_DIR), "/t_case_write2_logger.log\n"});
fdtmp = $fopen({`STRINGIFY(`TEST_OBJ_DIR), "/t_case_write2_logger.log"}, "w");
fd <= fdtmp;
end
if (cyc==90) begin
$write("*-* All Finished *-*\n");
$finish;
$write("*-* All Finished *-*\n");
$finish;
end
end
+2
View File
@@ -46,7 +46,9 @@ module t (/*AUTOARG*/);
// Test loop
initial begin
// bug963
// verilator lint_off IGNOREDRETURN
dpii_clear();
// verilator lint_on IGNOREDRETURN
j = 0;
for (i=0; i<64; i++) begin
if (i[0])
+3
View File
@@ -50,12 +50,15 @@ module t;
if (n !== 10) $stop;
// Functions called as tasks
// verilator lint_off IGNOREDRETURN
rglobal = 32'h4;
if (inc_and_return(32'h2) != 32'h6) $stop;
if (rglobal !== 32'h6) $stop;
rglobal = 32'h6;
inc_and_return(32'h3);
if (rglobal !== 32'h9) $stop;
// verilator lint_on IGNOREDRETURN
$write("*-* All Finished *-*\n");
$finish;
+1
View File
@@ -6,6 +6,7 @@
module t (/*AUTOARG*/);
initial begin
// verilator lint_off IGNOREDRETURN
func(0, 1'b1);
end
+20
View File
@@ -0,0 +1,20 @@
#!/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(
);
execute(
check_finished => 1,
);
ok(1);
1;
+36
View File
@@ -0,0 +1,36 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2003 by Wilson Snyder.
module t (clk);
input clk;
int side_effect;
function int f1;
input int in;
f1 = in + 1;
side_effect += in + 1;
endfunction
initial begin
int got;
side_effect = 1;
//
got = f1(10);
if (got != 11) $stop;
if (side_effect != 12) $stop;
// verilator lint_off IGNOREDRETURN
f1(20);
// verilator lint_on IGNOREDRETURN
if (side_effect != 33) $stop;
//
void'(f1(30));
if (side_effect != 64) $stop;
//
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+3
View File
@@ -0,0 +1,3 @@
%Warning-IGNOREDRETURN: t/t_func_void_bad.v:25: Ignoring return value of non-void function (IEEE 2017 13.4.1)
%Warning-IGNOREDRETURN: Use "/* verilator lint_off IGNOREDRETURN */" and lint_on around source to disable this message.
%Error: Exiting due to
+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.
scenarios(simulator => 1);
compile(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;
+35
View File
@@ -0,0 +1,35 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2003 by Wilson Snyder.
module t (clk);
input clk;
int side_effect;
function int f1;
input int in;
f1 = in + 1;
side_effect += in + 1;
endfunction
initial begin
int got;
side_effect = 1;
//
got = f1(10);
if (got != 11) $stop;
if (side_effect != 12) $stop;
//
f1(20);
if (side_effect != 33) $stop;
//
// void'f1(30);
// if (side_effect != 64) $stop;
//
$write("*-* All Finished *-*\n");
$finish;
end
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.
scenarios(simulator => 1);
# This is a compile only test.
compile(
v_flags2 => ["+1364-2005ext+v"],
);
ok(1);
1;
+12
View File
@@ -0,0 +1,12 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// A test of the +verilog2001ext+ and +verilog2005ext+ flags.
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Wilson Snyder.
// verilator lint_off SYMRSVDWORD
module t(input do);
t_langext_order_sub sub (.do(do));
endmodule
+11
View File
@@ -0,0 +1,11 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// A test of the +verilog2001ext+ and +verilog2005ext+ flags.
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Wilson Snyder.
// verilator lint_off SYMRSVDWORD
module t_langext_order_sub(input do);
endmodule
+2
View File
@@ -0,0 +1,2 @@
%Error-PORTSHORT: t/t_lint_setout_bad.v:16: Output port is connected to a constant pin, electrical short
%Error: Exiting due to
+1 -3
View File
@@ -15,9 +15,7 @@ compile(
verilator_make_gcc => 0,
make_top_shell => 0,
make_main => 0,
expect =>
'%Error: t/t_lint_setout_bad.v:\d+: Output port is connected to a constant pin, electrical short
.*',
expect_filename => $Self->{golden_filename},
);
ok(1);
@@ -0,0 +1,2 @@
%Error-PORTSHORT: t/t_lint_setout_bad.v:16: Output port is connected to a constant pin, electrical short
%Error: Exiting due to
+1 -3
View File
@@ -17,9 +17,7 @@ compile(
verilator_make_gcc => 0,
make_top_shell => 0,
make_main => 0,
expect =>
'%Error: t/t_lint_setout_bad.v:\d+: Output port is connected to a constant pin, electrical short
.*',
expect_filename => $Self->{golden_filename},
);
ok(1);
+4
View File
@@ -0,0 +1,4 @@
%Error-PORTSHORT: t/t_lint_subout_bad.v:11: Output port is connected to a constant pin, electrical short
%Error-PORTSHORT: t/t_lint_subout_bad.v:12: Output port is connected to a constant pin, electrical short
%Error-PORTSHORT: t/t_lint_subout_bad.v:10: Output port is connected to a constant pin, electrical short
%Error: Exiting due to
+21
View File
@@ -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 2008 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
scenarios(vlt_all => 1);
compile(
# No --lint-only as got compile error
verilator_flags2 => ["--trace"],
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;
+16
View File
@@ -0,0 +1,16 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Wilson Snyder.
// verilator lint_off UNDRIVEN
module t();
wire sig;
sub sub0(.out(33'b0));
sub sub1(.out({32'b0, sig}));
sub sub2(.out({32'b1, sig}));
endmodule
module sub(output reg [32 : 0] out);
endmodule
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/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.
scenarios(simulator => 1);
compile(
fails => 1,
);
ok(1);
1;
+58
View File
@@ -0,0 +1,58 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 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] a = crc[3:0];
wire [3:0] b = crc[19:16];
// TEST
wire [3:0] out1 = {a,b}[2 +: 4];
wire [3:0] out2 = {a,b}[5 -: 4];
wire [3:0] out3 = {a,b}[5 : 2];
wire [0:0] out4 = {a,b}[2];
// Aggregate outputs into a single result vector
wire [63:0] result = {51'h0, out4, out3, out2, out1};
// 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 <= '0;
end
else if (cyc<10) begin
sum <= '0;
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'h4afe43fb79d7b71e
if (sum !== `EXPECTED_SUM) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
scenarios(vlt_all => 1);
compile(
);
execute(
all_run_flags => ["+verilator+seed+5 +SEED=fffffff4"],
fails => 0,
);
execute(
all_run_flags => ["+verilator+seed+6 +SEED=fffffff2"],
fails => 0,
);
ok(1);
1;
+17
View File
@@ -0,0 +1,17 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Wilson Snyder.
`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);
module t;
initial begin
integer r = $random;
integer ex;
if ($value$plusargs("SEED=%x", ex) !== 1) $stop;
`checkh(r, ex);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+1 -1
View File
@@ -8,7 +8,7 @@
`define STRINGIFY(x) `"x`"
module t;
`verilator_file_descriptor file;
integer file;
integer chars;
reg [1*8:1] letterl;
+1 -1
View File
@@ -8,7 +8,7 @@
`define STRINGIFY(x) `"x`"
module t;
`verilator_file_descriptor infile, outfile;
integer infile, outfile;
integer count, a;
initial begin
+27
View File
@@ -0,0 +1,27 @@
Dump:
r_i: 00010203
r_upb: 0e 0d 0c 0b 0a 09 08 07 06 05 04
r_dnb: 19 18 17 16 15 14 13 12 11 10 0f
r_ups: 2e2f 2c2d 2a2b 2829 2627 2425 2223 2021 1e1f 1c1d 1a1b
r_dns: 3031 3233 3435 3637 3839 3a3b 3c3d 3e3f 0041 0243 0445
r_upi: 6e6f7071 6a6b6c6d 66676869 62636465 5e5f6061 5a5b5c5d 56575859 52535455 4e4f5051 4a4b4c4d 46474849
r_dni: 72737475 76777879 7a7b7c7d 7e7f8081 02838485 06878889 0a8b8c8d 0e8f9091 12939495 16979899 1a9b9c9d
r_upq: 2eeff0f1f2f3f4f5 26e7e8e9eaebeced 1edfe0e1e2e3e4e5 16d7d8d9dadbdcdd 0ecfd0d1d2d3d4d5 06c7c8c9cacbcccd 3ebfc0c1c2c3c4c5 36b7b8b9babbbcbd 2eafb0b1b2b3b4b5 26a7a8a9aaabacad 1e9fa0a1a2a3a4a5
r_dnq: 36f7f8f9fafbfcfd 3eff000102030405 060708090a0b0c0d 0e0f101112131415 161718191a1b1c1d 1e1f202122232425 262728292a2b2c2d 2e2f303132333435 363738393a3b3c3d 3e3f404142434445 064748494a4b4c4d
r_upw: a8a9aaabacadaeafb0 9fa0a1a2a3a4a5a6a7 969798999a9b9c9d9e 8d8e8f909192939495 8485868788898a8b8c 7b7c7d7e7f80818283 72737475767778797a 696a6b6c6d6e6f7071 606162636465666768 5758595a5b5c5d5e5f 4e4f50515253545556
r_dnw: b1b2b3b4b5b6b7b8b9 babbbcbdbebfc0c1c2 c3c4c5c6c7c8c9cacb cccdcecfd0d1d2d3d4 d5d6d7d8d9dadbdcdd dedfe0e1e2e3e4e5e6 e7e8e9eaebecedeeef f0f1f2f3f4f5f6f7f8 f9fafbfcfdfeff0001 02030405060708090a 0b0c0d0e0f10111213
Dump:
r_i: ffffffff
r_upb: 05 04 03 02 01 00 ff ff ff ff ff
r_dnb: ff ff ff ff ff ff ff ff ff ff ff
r_ups: 3fff 3fff 3fff 3fff 0809 0607 3fff 3fff 3fff 3fff 3fff
r_dns: 3fff 3fff 3fff 3fff 3fff 3fff 3fff 3fff 3fff 3fff 3fff
r_upi: 7fffffff 7fffffff 7fffffff 7fffffff 7fffffff 7fffffff 7fffffff 7fffffff 7fffffff 7fffffff 7fffffff
r_dni: 7fffffff 7fffffff 7fffffff 7fffffff 7fffffff 7fffffff 7fffffff 7fffffff 7fffffff 7fffffff 7fffffff
r_upq: 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff
r_dnq: 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff 3fffffffffffffff
r_upw: ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff
r_dnw: ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff ffffffffffffffffff
*-* All Finished *-*
+38
View File
@@ -0,0 +1,38 @@
#!/usr/bin/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.
use IO::File;
#use Data::Dumper;
use strict;
use vars qw($Self);
scenarios(simulator => 1);
sub gen {
my $filename = shift;
my $fh = IO::File->new(">$filename");
for (my $copy=0; $copy<32; ++$copy) {
for (my $i=0; $i<=255; ++$i) {
$fh->print(chr($i));
}
}
}
gen("$Self->{obj_dir}/t_sys_fread.mem");
compile(
);
execute(
check_finished => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;
+87
View File
@@ -0,0 +1,87 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Wilson Snyder.
`define STRINGIFY(x) `"x`"
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
//======================================================================
module t;
integer file;
integer r_i;
byte r_upb[20:10];
byte r_dnb[20:10];
reg [13:0] r_ups[20:10];
reg [13:0] r_dns[10:20];
reg [30:0] r_upi[20:10];
reg [30:0] r_dni[10:20];
reg [61:0] r_upq[20:10];
reg [61:0] r_dnq[10:20];
reg [71:0] r_upw[20:10];
reg [71:0] r_dnw[10:20];
task clear;
// Initialize memories to zero,
// avoid differences between 2-state and 4-state.
r_i = ~0;
foreach (r_upb[i]) r_upb[i] = ~0;
foreach (r_dnb[i]) r_dnb[i] = ~0;
foreach (r_ups[i]) r_ups[i] = ~0;
foreach (r_dns[i]) r_dns[i] = ~0;
foreach (r_upi[i]) r_upi[i] = ~0;
foreach (r_dni[i]) r_dni[i] = ~0;
foreach (r_upq[i]) r_upq[i] = ~0;
foreach (r_dnq[i]) r_dnq[i] = ~0;
foreach (r_upw[i]) r_upw[i] = ~0;
foreach (r_dnw[i]) r_dnw[i] = ~0;
// Open file
$fclose(file);
file = $fopen({`STRINGIFY(`TEST_OBJ_DIR),"/t_sys_fread.mem"}, "r");
if ($feof(file)) $stop;
endtask
task dump;
$write("Dump:");
$write("\n r_i:"); $write(" %x",r_i);
$write("\n r_upb:"); foreach (r_upb[i]) $write(" %x", r_upb[i]);
$write("\n r_dnb:"); foreach (r_dnb[i]) $write(" %x", r_dnb[i]);
$write("\n r_ups:"); foreach (r_ups[i]) $write(" %x", r_ups[i]);
$write("\n r_dns:"); foreach (r_dns[i]) $write(" %x", r_dns[i]);
$write("\n r_upi:"); foreach (r_upi[i]) $write(" %x", r_upi[i]);
$write("\n r_dni:"); foreach (r_dni[i]) $write(" %x", r_dni[i]);
$write("\n r_upq:"); foreach (r_upq[i]) $write(" %x", r_upq[i]);
$write("\n r_dnq:"); foreach (r_dnq[i]) $write(" %x", r_dnq[i]);
$write("\n r_upw:"); foreach (r_upw[i]) $write(" %x", r_upw[i]);
$write("\n r_dnw:"); foreach (r_dnw[i]) $write(" %x", r_dnw[i]);
$write("\n\n");
endtask
integer code;
initial begin
clear;
code = $fread(r_i, file); `checkd(code, 4);
code = $fread(r_upb, file); `checkd(code, 11);
code = $fread(r_dnb, file); `checkd(code, 11);
code = $fread(r_ups, file); `checkd(code, 22);
code = $fread(r_dns, file); `checkd(code, 22);
code = $fread(r_upi, file); `checkd(code, 44);
code = $fread(r_dni, file); `checkd(code, 44);
code = $fread(r_upq, file); `checkd(code, 88);
code = $fread(r_dnq, file); `checkd(code, 88);
code = $fread(r_upw, file); `checkd(code, 99);
code = $fread(r_dnw, file); `checkd(code, 99);
dump;
clear;
code = $fread(r_upb, file, 15); `checkd(code, 6);
code = $fread(r_ups, file, 15, 2); `checkd(code, 4);
dump;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule