Merge from master

This commit is contained in:
Wilson Snyder 2018-03-10 16:51:34 -05:00
commit 2c30aecc5b
87 changed files with 927 additions and 378 deletions

10
Changes
View File

@ -17,10 +17,20 @@ The contributors that suggested a given feature are shown in []. Thanks!
*** Support trig functions ($sin() etc), bug1281. [Patrick Stewart]
*** Support calling system functions as tasks, bug1285. [Joel Holdsworth]
*** Add --no-debug-leak to reduce memory use under debug. [John Coiner]
**** On convergence errors, show activity. [John Coiner]
**** Fix GCC 8.0 issues, bug1273.
**** Fix pullup/pulldowns on bit selects, bug1274. [Rob Stoddard]
**** Fix verilator_coverage --annotate-min, bug1284. [Tymoteusz Blazejczyk]
**** Fix quoting of quoted arguments. [John Coiner]
* Verilator 3.920 2018-02-01

View File

@ -54,18 +54,6 @@ push @ARGV, (split ' ',$ENV{VERILATOR_TEST_FLAGS}||"");
# We sneak a look at the flags so we can do some pre-environment checks
# All flags will hit verilator...
foreach my $sw (@ARGV) {
# Some special treatment for parameters to allow verilog literals for numbers
if ((substr($sw, 0, 2) eq "-G") || (substr($sw, 0, 8) eq "-pvalue+")) {
# If there is a single quote in the parameter put it double quotes ,
# else just put it in double quotes
if ($sw =~ m![\']!) {
$sw = "\"$sw\"";
} else {
$sw = "'$sw'";
}
} else {
$sw = "'$sw'" if $sw =~ m![^---a-zA-Z0-9_/\\:.+]!;
}
push @Opt_Verilator_Sw, $sw;
}
@ -84,16 +72,27 @@ if (! GetOptions (
pod2usage(-exitstatus=>2, -verbose=>0);
}
# Determine runtime flags and run
if ($opt_gdbbt && !gdb_works()) {
warn "-Info: --gdbbt ignored: gdb doesn't seem to be working\n" if $Debug;
$opt_gdbbt = 0;
}
# Determine runtime flags and run
# Opt_Verilator_Sw is what we want verilator to see on its argc/argv.
# Starting with that, escape all special chars for the shell;
# The shell will undo the escapes and the verilator binary should
# then see exactly the contents of @Opt_Verilator_Sw.
my @quoted_sw = map {sh_escape($_)} @Opt_Verilator_Sw;
if ($opt_gdb) {
# Generic GDB interactive
run (("gdb"||$ENV{VERILATOR_GDB})
." ".verilator_bin()
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
# Note, we must use double-quotes ("run <switches>")
# and not single ('run <switches>') below. Bash swallows
# escapes as you would expect in a double-quoted string.
# That's not true for a single-quoted string, where \'
# actually terminates the string -- not what we want!
." -ex \"run ".join(' ', @quoted_sw)."\""
." -ex 'set width 0'"
." -ex 'bt'");
} elsif ($opt_gdbbt && $Debug) {
@ -101,13 +100,12 @@ if ($opt_gdb) {
run ("gdb"
." ".verilator_bin()
." --batch --quiet --return-child-result"
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
." -ex \"run ".join(' ', @quoted_sw)."\""
." -ex 'set width 0'"
." -ex 'bt'");
} else {
# Normal, non gdb
run (verilator_bin()
." ".join(' ',@Opt_Verilator_Sw));
run (verilator_bin()." ".join(' ',@quoted_sw));
}
#----------------------------------------------------------------------
@ -196,6 +194,16 @@ sub run {
}
}
sub sh_escape {
my ($arg) = @_;
# This is similar to quotemeta() but less aggressive.
# There's no need to escape hyphens, periods, or forward slashes
# for the shell as these have no special meaning to the shell.
$arg =~ s/([^0-9a-zA-Z_\-\.\/])/\\$1/g;
return $arg;
}
#######################################################################
#######################################################################
package main;
@ -270,6 +278,7 @@ descriptions in the next sections for more information.
-D<var>[=<value>] Set preprocessor define
--debug Enable debugging
--debug-check Enable debugging assertions
--no-debug-leak Disable leaking memory in --debug mode
--debugi <level> Enable debugging at a specified level
--debugi-<srcfile> <level> Enable debugging a source file at a level
--default-language <lang> Default language to parse
@ -627,6 +636,18 @@ to C<--dump-treei 3>).
Rarely needed. Enable internal debugging assertion checks, without
changing debug verbosity. Enabled automatically when --debug specified.
=item --no-debug-leak
In --debug mode, by default Verilator intentionally leaks AstNode's
instead of freeing them, so that each node pointer is unique in the
resulting tree files and dot files.
This option disables the leak. This may avoid out-of-memory errors
when Verilating large models in --debug mode.
Outside of --debug mode, AstNode's should never be leaked and this option
has no effect.
=item --debugi <level>
=item --debugi-<srcfile> <level>
@ -1251,8 +1272,9 @@ supports which the older version does not support.
=item -Wno-I<message>
Disable the specified warning message. This will override any lint_on
directives in the source, i.e. the warning will still not be printed.
Disable the specified warning message, or in some cases where noted here
disable an error. This will override any lint_on directives in the source,
i.e. the warning will still not be printed.
=item -Wno-lint
@ -3047,13 +3069,15 @@ Simply use a different register for the flop:
always @* foo[0] = foo_flopped[0];
always @* foo[1] = ...
It is also possible to disable this error when one of the assignments is
inside a public task.
This is not illegal in SystemVerilog, but a violation of good coding
practice. Verilator reports this as an error, because ignoring this warning
may make Verilator simulations differ from other simulators.
It is generally safe to disable this error (with a "// verilator lint_off
BLKANDNBLK" metacomment or the -Wno-BLKANDNBLK option) when one of the
assignments is inside a public task, or when the blocked and non-blocking
assignments have non-overlapping bits and structure members.
=item BLKSEQ
This indicates that a blocking assignment (=) is used in a sequential

View File

@ -430,7 +430,8 @@ QData VL_POW_QQW(int, int, int rbits, QData lhs, WDataInP rwp) VL_MT_SAFE {
return out;
}
WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool lsign, bool rsign) VL_MT_SAFE {
WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp,
bool lsign, bool rsign) VL_MT_SAFE {
// obits==lbits, rbits can be different
if (rsign && VL_SIGN_W(rbits, rwp)) {
int words = VL_WORDS_I(obits);
@ -450,7 +451,9 @@ WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, W
}
return VL_POW_WWW(obits, rbits, rbits, owp, lwp, rwp);
}
WDataOutP VL_POWSS_WWQ(int obits, int lbits, int rbits, WDataOutP owp, WDataInP lwp, QData rhs, bool lsign, bool rsign) VL_MT_SAFE {
WDataOutP VL_POWSS_WWQ(int obits, int lbits, int rbits,
WDataOutP owp, WDataInP lwp, QData rhs,
bool lsign, bool rsign) VL_MT_SAFE {
WData rhsw[2]; VL_SET_WQ(rhsw, rhs);
return VL_POWSS_WWW(obits,lbits,rbits,owp,lwp,rhsw,lsign,rsign);
}
@ -982,7 +985,8 @@ void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) VL_MT_SAFE
}
}
*destp = '\0'; // Terminate
if (!start) while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0'; // Drop trailing spaces
// Drop trailing spaces
if (!start) while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0';
}
void _VL_STRING_TO_VINT(int obits, void* destp, size_t srclen, const char* srcp) VL_MT_SAFE {
@ -1239,7 +1243,8 @@ void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
while (1) {
int c = fgetc(fp);
if (VL_UNLIKELY(c==EOF)) break;
//printf("%d: Got '%c' Addr%x IN%d IgE%d IgC%d ninc%d\n", linenum, c, addr, innum, ignore_to_eol, ignore_to_cmt, needinc);
//printf("%d: Got '%c' Addr%x IN%d IgE%d IgC%d ninc%d\n",
// linenum, c, addr, innum, ignore_to_eol, ignore_to_cmt, needinc);
if (c=='\n') { linenum++; ignore_to_eol=false; if (innum) reading_addr=false; innum=false; }
else if (c=='\t' || c==' ' || c=='\r' || c=='\f') { if (innum) reading_addr=false; innum=false; }
// Skip // comments and detect /* comments
@ -1267,7 +1272,8 @@ void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
//printf(" Value width=%d @%x = %c\n", width, addr, c);
if (VL_UNLIKELY(addr >= static_cast<IData>(depth+array_lsb)
|| addr < static_cast<IData>(array_lsb))) {
VL_FATAL_MT (ofilenamep.c_str(), linenum, "", "$readmem file address beyond bounds of array");
VL_FATAL_MT (ofilenamep.c_str(), linenum, "",
"$readmem file address beyond bounds of array");
} else {
int entry = addr - array_lsb;
QData shift = hex ? VL_ULL(4) : VL_ULL(1);
@ -1296,7 +1302,8 @@ void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
datap[0] |= value;
}
if (VL_UNLIKELY(value>=(1<<shift))) {
VL_FATAL_MT (ofilenamep.c_str(), linenum, "", "$readmemb (binary) file contains hex characters");
VL_FATAL_MT (ofilenamep.c_str(), linenum, "",
"$readmemb (binary) file contains hex characters");
}
}
}
@ -1745,7 +1752,9 @@ void VerilatedScope::varInsert(int finalize, const char* namep, void* datap,
} else {
// We could have a linked list of ranges, but really this whole thing needs
// to be generalized to support structs and unions, etc.
VL_FATAL_MT(__FILE__,__LINE__,"",(std::string("Unsupported multi-dimensional public varInsert: ")+namep).c_str());
VL_FATAL_MT(__FILE__,__LINE__,"",
(std::string("Unsupported multi-dimensional public varInsert: ")
+ namep).c_str());
}
}
va_end(ap);

View File

@ -373,7 +373,8 @@ public:
#endif
/// Enable calculation of unused signals
static void calcUnusedSigs(bool flag) VL_MT_SAFE;
static bool calcUnusedSigs() VL_MT_SAFE { return s_s.s_calcUnusedSigs; } ///< Return calcUnusedSigs value
static bool calcUnusedSigs() VL_MT_SAFE { ///< Return calcUnusedSigs value
return s_s.s_calcUnusedSigs; }
/// Did the simulation $finish?
static void gotFinish(bool flag) VL_MT_SAFE;
static bool gotFinish() VL_MT_SAFE { return s_s.s_gotFinish; } ///< Return if got a $finish
@ -535,8 +536,8 @@ extern IData VL_FGETS_IXI(int obits, void* destp, IData fpi);
extern IData VL_FOPEN_S(const char* filenamep, const char* mode);
extern IData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
extern IData VL_FOPEN_QI(QData ofilename, IData mode);
inline IData VL_FOPEN_II(IData ofilename, IData mode) VL_MT_SAFE { return VL_FOPEN_QI(ofilename,mode); }
inline IData VL_FOPEN_II(IData ofilename, IData mode) VL_MT_SAFE {
return VL_FOPEN_QI(ofilename,mode); }
extern void VL_FCLOSE_I(IData fdi);
@ -576,16 +577,20 @@ extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish
#define VL_BITISSET_I(data,bit) (data & (VL_UL(1)<<VL_BITBIT_I(bit)))
#define VL_BITISSET_Q(data,bit) (data & (VL_ULL(1)<<VL_BITBIT_Q(bit)))
#define VL_BITISSET_W(data,bit) (data[VL_BITWORD_I(bit)] & (VL_UL(1)<<VL_BITBIT_I(bit)))
#define VL_BITISSETLIMIT_W(data,width,bit) (((bit)<(width)) && data[VL_BITWORD_I(bit)] & (VL_UL(1)<<VL_BITBIT_I(bit)))
#define VL_BITISSETLIMIT_W(data,width,bit) \
(((bit)<(width)) && data[VL_BITWORD_I(bit)] & (VL_UL(1)<<VL_BITBIT_I(bit)))
/// Shift appropriate word by bit. Does not account for wrapping between two words
#define VL_BITRSHIFT_W(data,bit) (data[VL_BITWORD_I(bit)] >> VL_BITBIT_I(bit))
/// Create two 32-bit words from quadword
/// WData is always at least 2 words; does not clean upper bits
#define VL_SET_WQ(owp,data) { owp[0]=static_cast<IData>(data); owp[1]=static_cast<IData>((data)>>VL_WORDSIZE); }
#define VL_SET_WQ(owp,data) { owp[0]=static_cast<IData>(data); \
owp[1]=static_cast<IData>((data)>>VL_WORDSIZE); }
#define VL_SET_WI(owp,data) { owp[0]=static_cast<IData>(data); owp[1]=0; }
#define VL_SET_QW(lwp) ( (static_cast<QData>(lwp[0])) | (static_cast<QData>(lwp[1])<<(static_cast<QData>(VL_WORDSIZE)) ))
#define VL_SET_QW(lwp) \
( (static_cast<QData>(lwp[0])) \
| (static_cast<QData>(lwp[1])<<(static_cast<QData>(VL_WORDSIZE)) ))
#define _VL_SET_QII(ld,rd) ( (static_cast<QData>(ld)<<VL_ULL(32)) | static_cast<QData>(rd) )
/// Return FILE* from IData
@ -593,19 +598,26 @@ extern FILE* VL_CVT_I_FP(IData lhs);
// Use a union to avoid cast-to-different-size warnings
/// Return void* from QData
static inline void* VL_CVT_Q_VP(QData lhs) VL_PURE { union { void* fp; QData q; } u; u.q=lhs; return u.fp; }
static inline void* VL_CVT_Q_VP(QData lhs) VL_PURE {
union { void* fp; QData q; } u; u.q=lhs; return u.fp; }
/// Return QData from void*
static inline QData VL_CVT_VP_Q(void* fp) VL_PURE { union { void* fp; QData q; } u; u.q=0; u.fp=fp; return u.q; }
static inline QData VL_CVT_VP_Q(void* fp) VL_PURE {
union { void* fp; QData q; } u; u.q=0; u.fp=fp; return u.q; }
/// Return double from QData (bits, not numerically)
static inline double VL_CVT_D_Q(QData lhs) VL_PURE { union { double d; QData q; } u; u.q=lhs; return u.d; }
static inline double VL_CVT_D_Q(QData lhs) VL_PURE {
union { double d; QData q; } u; u.q=lhs; return u.d; }
/// Return QData from double (bits, not numerically)
static inline QData VL_CVT_Q_D(double lhs) VL_PURE { union { double d; QData q; } u; u.d=lhs; return u.q; }
static inline QData VL_CVT_Q_D(double lhs) VL_PURE {
union { double d; QData q; } u; u.d=lhs; return u.q; }
/// Return double from QData (numeric)
static inline double VL_ITOR_D_I(IData lhs) VL_PURE { return static_cast<double>(static_cast<vlsint32_t>(lhs)); }
static inline double VL_ITOR_D_I(IData lhs) VL_PURE {
return static_cast<double>(static_cast<vlsint32_t>(lhs)); }
/// Return QData from double (numeric)
static inline IData VL_RTOI_I_D(double lhs) VL_PURE { return static_cast<vlsint32_t>(VL_TRUNC(lhs)); }
static inline IData VL_RTOI_I_D(double lhs) VL_PURE {
return static_cast<vlsint32_t>(VL_TRUNC(lhs)); }
/// Return QData from double (numeric)
static inline IData VL_RTOIROUND_I_D(double lhs) VL_PURE { return static_cast<vlsint32_t>(VL_ROUND(lhs)); }
static inline IData VL_RTOIROUND_I_D(double lhs) VL_PURE {
return static_cast<vlsint32_t>(VL_ROUND(lhs)); }
// Sign extend such that if MSB set, we get ffff_ffff, else 0s
// (Requires clean input)
@ -616,8 +628,10 @@ static inline IData VL_RTOIROUND_I_D(double lhs) VL_PURE { return static_cast<v
// Sign bit extended up to MSB, doesn't include unsigned portion
// Optimization bug in GCC 3.3 returns different bitmasks to later states for
static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) VL_PURE { return (-((lhs)&(VL_UL(1)<<(lbits-1)))); }
static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) VL_PURE { return (-((lhs)&(VL_ULL(1)<<(lbits-1)))); }
static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) VL_PURE {
return (-((lhs)&(VL_UL(1)<<(lbits-1)))); }
static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) VL_PURE {
return (-((lhs)&(VL_ULL(1)<<(lbits-1)))); }
// Debugging prints
extern void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp);
@ -1400,13 +1414,19 @@ WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDa
WDataOutP VL_POW_WWQ(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, QData rhs);
QData VL_POW_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp);
#define VL_POWSS_IIQ(obits,lbits,rbits,lhs,rhs,lsign,rsign) VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
#define VL_POWSS_IIQ(obits,lbits,rbits,lhs,rhs,lsign,rsign) VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
#define VL_POWSS_IIW(obits,lbits,rbits,lhs,rwp,lsign,rsign) VL_POWSS_QQW(obits,lbits,rbits,lhs,rwp,lsign,rsign)
#define VL_POWSS_QQI(obits,lbits,rbits,lhs,rhs,lsign,rsign) VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
#define VL_POWSS_WWI(obits,lbits,rbits,owp,lwp,rhs,lsign,rsign) VL_POWSS_WWQ(obits,lbits,rbits,owp,lwp,rhs,lsign,rsign)
#define VL_POWSS_IIQ(obits,lbits,rbits,lhs,rhs,lsign,rsign) \
VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
#define VL_POWSS_IIQ(obits,lbits,rbits,lhs,rhs,lsign,rsign) \
VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
#define VL_POWSS_IIW(obits,lbits,rbits,lhs,rwp,lsign,rsign) \
VL_POWSS_QQW(obits,lbits,rbits,lhs,rwp,lsign,rsign)
#define VL_POWSS_QQI(obits,lbits,rbits,lhs,rhs,lsign,rsign) \
VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
#define VL_POWSS_WWI(obits,lbits,rbits,owp,lwp,rhs,lsign,rsign) \
VL_POWSS_WWQ(obits,lbits,rbits,owp,lwp,rhs,lsign,rsign)
static inline IData VL_POWSS_III(int obits, int, int rbits, IData lhs, IData rhs, bool lsign, bool rsign) VL_MT_SAFE {
static inline IData VL_POWSS_III(int obits, int, int rbits,
IData lhs, IData rhs, bool lsign, bool rsign) VL_MT_SAFE {
if (VL_UNLIKELY(rhs==0)) return 1;
if (rsign && VL_SIGN_I(rbits, rhs)) {
if (lhs==0) return 0; // "X"
@ -1419,7 +1439,8 @@ static inline IData VL_POWSS_III(int obits, int, int rbits, IData lhs, IData rhs
}
return VL_POW_III(obits, rbits, rbits, lhs, rhs);
}
static inline QData VL_POWSS_QQQ(int obits, int, int rbits, QData lhs, QData rhs, bool lsign, bool rsign) VL_MT_SAFE {
static inline QData VL_POWSS_QQQ(int obits, int, int rbits,
QData lhs, QData rhs, bool lsign, bool rsign) VL_MT_SAFE {
if (VL_UNLIKELY(rhs==0)) return 1;
if (rsign && VL_SIGN_I(rbits, rhs)) {
if (lhs==0) return 0; // "X"
@ -1432,9 +1453,12 @@ static inline QData VL_POWSS_QQQ(int obits, int, int rbits, QData lhs, QData rhs
}
return VL_POW_QQQ(obits, rbits, rbits, lhs, rhs);
}
WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool lsign, bool rsign);
WDataOutP VL_POWSS_WWQ(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, QData rhs, bool lsign, bool rsign);
QData VL_POWSS_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp, bool lsign, bool rsign);
WDataOutP VL_POWSS_WWW(int obits, int, int rbits,
WDataOutP owp, WDataInP lwp, WDataInP rwp, bool lsign, bool rsign);
WDataOutP VL_POWSS_WWQ(int obits, int, int rbits,
WDataOutP owp, WDataInP lwp, QData rhs, bool lsign, bool rsign);
QData VL_POWSS_QQW(int obits, int, int rbits,
QData lhs, WDataInP rwp, bool lsign, bool rsign);
//===================================================================
// Concat/replication
@ -1554,21 +1578,24 @@ static inline QData VL_REPLICATE_QII(int, int lbits, int, IData ld, IData rep) V
}
return (returndata);
}
static inline WDataOutP VL_REPLICATE_WII(int obits, int lbits, int, WDataOutP owp, IData ld, IData rep) VL_MT_SAFE {
static inline WDataOutP VL_REPLICATE_WII(int obits, int lbits, int,
WDataOutP owp, IData ld, IData rep) VL_MT_SAFE {
owp[0] = ld;
for (unsigned i=1; i < rep; ++i){
_VL_INSERT_WI(obits,owp,ld,i*lbits+lbits-1,i*lbits);
}
return(owp);
}
static inline WDataOutP VL_REPLICATE_WQI(int obits, int lbits, int, WDataOutP owp, QData ld, IData rep) VL_MT_SAFE {
static inline WDataOutP VL_REPLICATE_WQI(int obits, int lbits, int,
WDataOutP owp, QData ld, IData rep) VL_MT_SAFE {
VL_SET_WQ(owp,ld);
for (unsigned i=1; i < rep; ++i){
_VL_INSERT_WQ(obits,owp,ld,i*lbits+lbits-1,i*lbits);
}
return(owp);
}
static inline WDataOutP VL_REPLICATE_WWI(int obits, int lbits, int, WDataOutP owp, WDataInP lwp, IData rep) VL_MT_SAFE {
static inline WDataOutP VL_REPLICATE_WWI(int obits, int lbits, int,
WDataOutP owp, WDataInP lwp, IData rep) VL_MT_SAFE {
for (int i=0; i < VL_WORDS_I(lbits); ++i) owp[i] = lwp[i];
for (unsigned i=1; i < rep; ++i){
_VL_INSERT_WW(obits,owp,lwp,i*lbits+lbits-1,i*lbits);
@ -1633,15 +1660,20 @@ static inline QData VL_STREAML_FAST_QQI(int, int lbits, int, QData ld, IData rd_
}
switch (rd_log2) {
case 0:
ret = ((ret >> 1) & VL_ULL(0x5555555555555555)) | ((ret & VL_ULL(0x5555555555555555)) << 1); // FALLTHRU
ret = (((ret >> 1) & VL_ULL(0x5555555555555555))
| ((ret & VL_ULL(0x5555555555555555)) << 1)); // FALLTHRU
case 1:
ret = ((ret >> 2) & VL_ULL(0x3333333333333333)) | ((ret & VL_ULL(0x3333333333333333)) << 2); // FALLTHRU
ret = (((ret >> 2) & VL_ULL(0x3333333333333333))
| ((ret & VL_ULL(0x3333333333333333)) << 2)); // FALLTHRU
case 2:
ret = ((ret >> 4) & VL_ULL(0x0f0f0f0f0f0f0f0f)) | ((ret & VL_ULL(0x0f0f0f0f0f0f0f0f)) << 4); // FALLTHRU
ret = (((ret >> 4) & VL_ULL(0x0f0f0f0f0f0f0f0f))
| ((ret & VL_ULL(0x0f0f0f0f0f0f0f0f)) << 4)); // FALLTHRU
case 3:
ret = ((ret >> 8) & VL_ULL(0x00ff00ff00ff00ff)) | ((ret & VL_ULL(0x00ff00ff00ff00ff)) << 8); // FALLTHRU
ret = (((ret >> 8) & VL_ULL(0x00ff00ff00ff00ff))
| ((ret & VL_ULL(0x00ff00ff00ff00ff)) << 8)); // FALLTHRU
case 4:
ret = ((ret >> 16) & VL_ULL(0x0000ffff0000ffff)) | ((ret & VL_ULL(0x0000ffff0000ffff)) << 16); // FALLTHRU
ret = (((ret >> 16) & VL_ULL(0x0000ffff0000ffff))
| ((ret & VL_ULL(0x0000ffff0000ffff)) << 16)); // FALLTHRU
case 5:
ret = ((ret >> 32) | (ret << 32));
}
@ -1694,61 +1726,75 @@ static inline WDataOutP VL_STREAML_WWI(int, int lbits, int, WDataOutP owp, WData
// Thus we specify inputs must be clean, so we don't need to clean the output.
// Note the bit shifts are always constants, so the adds in these constify out.
// Casts required, as args may be 8 bit entities, and need to shift to appropriate output size
#define VL_CONCAT_III(obits,lbits,rbits,ld,rd) (static_cast<IData>(ld)<<(rbits) | static_cast<IData>(rd))
#define VL_CONCAT_QII(obits,lbits,rbits,ld,rd) (static_cast<QData>(ld)<<(rbits) | static_cast<QData>(rd))
#define VL_CONCAT_QIQ(obits,lbits,rbits,ld,rd) (static_cast<QData>(ld)<<(rbits) | static_cast<QData>(rd))
#define VL_CONCAT_QQI(obits,lbits,rbits,ld,rd) (static_cast<QData>(ld)<<(rbits) | static_cast<QData>(rd))
#define VL_CONCAT_QQQ(obits,lbits,rbits,ld,rd) (static_cast<QData>(ld)<<(rbits) | static_cast<QData>(rd))
#define VL_CONCAT_III(obits,lbits,rbits,ld,rd) \
(static_cast<IData>(ld)<<(rbits) | static_cast<IData>(rd))
#define VL_CONCAT_QII(obits,lbits,rbits,ld,rd) \
(static_cast<QData>(ld)<<(rbits) | static_cast<QData>(rd))
#define VL_CONCAT_QIQ(obits,lbits,rbits,ld,rd) \
(static_cast<QData>(ld)<<(rbits) | static_cast<QData>(rd))
#define VL_CONCAT_QQI(obits,lbits,rbits,ld,rd) \
(static_cast<QData>(ld)<<(rbits) | static_cast<QData>(rd))
#define VL_CONCAT_QQQ(obits,lbits,rbits,ld,rd) \
(static_cast<QData>(ld)<<(rbits) | static_cast<QData>(rd))
static inline WDataOutP VL_CONCAT_WII(int obits,int lbits,int rbits,WDataOutP owp,IData ld,IData rd) VL_MT_SAFE {
static inline WDataOutP VL_CONCAT_WII(int obits, int lbits, int rbits,
WDataOutP owp, IData ld,IData rd) VL_MT_SAFE {
owp[0] = rd;
for (int i=1; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
_VL_INSERT_WI(obits,owp,ld,rbits+lbits-1,rbits);
return(owp);
}
static inline WDataOutP VL_CONCAT_WWI(int obits,int lbits,int rbits,WDataOutP owp,WDataInP lwp, IData rd) VL_MT_SAFE {
static inline WDataOutP VL_CONCAT_WWI(int obits, int lbits, int rbits,
WDataOutP owp, WDataInP lwp, IData rd) VL_MT_SAFE {
owp[0] = rd;
for (int i=1; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
_VL_INSERT_WW(obits,owp,lwp,rbits+lbits-1,rbits);
return(owp);
}
static inline WDataOutP VL_CONCAT_WIW(int obits,int lbits,int rbits,WDataOutP owp,IData ld, WDataInP rwp) VL_MT_SAFE {
static inline WDataOutP VL_CONCAT_WIW(int obits, int lbits, int rbits,
WDataOutP owp, IData ld, WDataInP rwp) VL_MT_SAFE {
for (int i=0; i < VL_WORDS_I(rbits); ++i) owp[i] = rwp[i];
for (int i=VL_WORDS_I(rbits); i < VL_WORDS_I(obits); ++i) owp[i] = 0;
_VL_INSERT_WI(obits,owp,ld,rbits+lbits-1,rbits);
return(owp);
}
static inline WDataOutP VL_CONCAT_WIQ(int obits,int lbits,int rbits,WDataOutP owp,IData ld,QData rd) VL_MT_SAFE {
static inline WDataOutP VL_CONCAT_WIQ(int obits, int lbits, int rbits,
WDataOutP owp, IData ld, QData rd) VL_MT_SAFE {
VL_SET_WQ(owp,rd);
for (int i=2; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
_VL_INSERT_WI(obits,owp,ld,rbits+lbits-1,rbits);
return(owp);
}
static inline WDataOutP VL_CONCAT_WQI(int obits,int lbits,int rbits,WDataOutP owp,QData ld,IData rd) VL_MT_SAFE {
static inline WDataOutP VL_CONCAT_WQI(int obits, int lbits, int rbits,
WDataOutP owp, QData ld, IData rd) VL_MT_SAFE {
owp[0] = rd;
for (int i=1; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
_VL_INSERT_WQ(obits,owp,ld,rbits+lbits-1,rbits);
return(owp);
}
static inline WDataOutP VL_CONCAT_WQQ(int obits,int lbits,int rbits,WDataOutP owp,QData ld,QData rd) VL_MT_SAFE {
static inline WDataOutP VL_CONCAT_WQQ(int obits, int lbits, int rbits,
WDataOutP owp, QData ld, QData rd) VL_MT_SAFE {
VL_SET_WQ(owp,rd);
for (int i=2; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
_VL_INSERT_WQ(obits,owp,ld,rbits+lbits-1,rbits);
return(owp);
}
static inline WDataOutP VL_CONCAT_WWQ(int obits,int lbits,int rbits,WDataOutP owp,WDataInP lwp, QData rd) VL_MT_SAFE {
static inline WDataOutP VL_CONCAT_WWQ(int obits, int lbits, int rbits,
WDataOutP owp, WDataInP lwp, QData rd) VL_MT_SAFE {
VL_SET_WQ(owp,rd);
for (int i=2; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
_VL_INSERT_WW(obits,owp,lwp,rbits+lbits-1,rbits);
return(owp);
}
static inline WDataOutP VL_CONCAT_WQW(int obits,int lbits,int rbits,WDataOutP owp,QData ld, WDataInP rwp) VL_MT_SAFE {
static inline WDataOutP VL_CONCAT_WQW(int obits, int lbits, int rbits,
WDataOutP owp, QData ld, WDataInP rwp) VL_MT_SAFE {
for (int i=0; i < VL_WORDS_I(rbits); ++i) owp[i] = rwp[i];
for (int i=VL_WORDS_I(rbits); i < VL_WORDS_I(obits); ++i) owp[i] = 0;
_VL_INSERT_WQ(obits,owp,ld,rbits+lbits-1,rbits);
return(owp);
}
static inline WDataOutP VL_CONCAT_WWW(int obits,int lbits,int rbits,WDataOutP owp,WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
static inline WDataOutP VL_CONCAT_WWW(int obits, int lbits, int rbits,
WDataOutP owp, WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
for (int i=0; i < VL_WORDS_I(rbits); ++i) owp[i] = rwp[i];
for (int i=VL_WORDS_I(rbits); i < VL_WORDS_I(obits); ++i) owp[i] = 0;
_VL_INSERT_WW(obits,owp,lwp,rbits+lbits-1,rbits);
@ -1787,7 +1833,8 @@ static inline WDataOutP VL_SHIFTL_WWI(int obits,int,int,WDataOutP owp,WDataInP l
}
return(owp);
}
static inline WDataOutP VL_SHIFTL_WWW(int obits,int lbits,int rbits,WDataOutP owp,WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
static inline WDataOutP VL_SHIFTL_WWW(int obits, int lbits, int rbits,
WDataOutP owp, WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
for (int i=1; i < VL_WORDS_I(rbits); ++i) {
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
return VL_ZERO_W(obits, owp);
@ -1807,7 +1854,8 @@ static inline IData VL_SHIFTL_IIW(int obits,int,int rbits,IData lhs, WDataInP rw
// EMIT_RULE: VL_SHIFTR: oclean=lclean; rclean==clean;
// Important: Unlike most other funcs, the shift might well be a computed
// expression. Thus consider this when optimizing. (And perhaps have 2 funcs?)
static inline WDataOutP VL_SHIFTR_WWI(int obits,int,int,WDataOutP owp,WDataInP lwp, IData rd) VL_MT_SAFE {
static inline WDataOutP VL_SHIFTR_WWI(int obits, int, int,
WDataOutP owp,WDataInP lwp, IData rd) VL_MT_SAFE {
int word_shift = VL_BITWORD_I(rd); // Maybe 0
int bit_shift = VL_BITBIT_I(rd);
if (rd >= static_cast<IData>(obits)) { // rd may be huge with MSB set
@ -1832,7 +1880,8 @@ static inline WDataOutP VL_SHIFTR_WWI(int obits,int,int,WDataOutP owp,WDataInP l
}
return(owp);
}
static inline WDataOutP VL_SHIFTR_WWW(int obits,int lbits,int rbits,WDataOutP owp,WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
static inline WDataOutP VL_SHIFTR_WWW(int obits, int lbits, int rbits,
WDataOutP owp, WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
for (int i=1; i < VL_WORDS_I(rbits); ++i) {
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
return VL_ZERO_W(obits, owp);
@ -1864,10 +1913,12 @@ static inline QData VL_SHIFTRS_QQI(int obits, int lbits, int, QData lhs, IData r
QData signext = ~(VL_MASK_Q(lbits) >> rhs);
return (lhs >> rhs) | (sign & VL_CLEAN_QQ(obits,obits,signext));
}
static inline IData VL_SHIFTRS_IQI(int obits, int lbits, int rbits, QData lhs, IData rhs) VL_PURE {
static inline IData VL_SHIFTRS_IQI(int obits, int lbits, int rbits,
QData lhs, IData rhs) VL_PURE {
return static_cast<IData>(VL_SHIFTRS_QQI(obits, lbits, rbits, lhs, rhs));
}
static inline WDataOutP VL_SHIFTRS_WWI(int obits,int lbits,int,WDataOutP owp,WDataInP lwp, IData rd) VL_MT_SAFE {
static inline WDataOutP VL_SHIFTRS_WWI(int obits, int lbits, int,
WDataOutP owp, WDataInP lwp, IData rd) VL_MT_SAFE {
int word_shift = VL_BITWORD_I(rd);
int bit_shift = VL_BITBIT_I(rd);
int lmsw = VL_WORDS_I(obits)-1;
@ -1899,7 +1950,8 @@ static inline WDataOutP VL_SHIFTRS_WWI(int obits,int lbits,int,WDataOutP owp,WDa
}
return(owp);
}
static inline WDataOutP VL_SHIFTRS_WWW(int obits,int lbits,int rbits,WDataOutP owp,WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
static inline WDataOutP VL_SHIFTRS_WWW(int obits, int lbits, int rbits,
WDataOutP owp, WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
for (int i=1; i < VL_WORDS_I(rbits); ++i) {
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
int lmsw = VL_WORDS_I(obits)-1;
@ -1911,7 +1963,8 @@ static inline WDataOutP VL_SHIFTRS_WWW(int obits,int lbits,int rbits,WDataOutP o
}
return VL_SHIFTRS_WWI(obits,lbits,32,owp,lwp,rwp[0]);
}
static inline IData VL_SHIFTRS_IIW(int obits,int lbits,int rbits,IData lhs, WDataInP rwp) VL_MT_SAFE {
static inline IData VL_SHIFTRS_IIW(int obits, int lbits, int rbits,
IData lhs, WDataInP rwp) VL_MT_SAFE {
for (int i=1; i < VL_WORDS_I(rbits); ++i) {
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
IData sign = -(lhs >> (lbits-1)); // ffff_ffff if negative
@ -1920,7 +1973,8 @@ static inline IData VL_SHIFTRS_IIW(int obits,int lbits,int rbits,IData lhs, WDat
}
return VL_SHIFTRS_III(obits,lbits,32,lhs,rwp[0]);
}
static inline QData VL_SHIFTRS_QQW(int obits,int lbits,int rbits,QData lhs, WDataInP rwp) VL_MT_SAFE {
static inline QData VL_SHIFTRS_QQW(int obits, int lbits, int rbits,
QData lhs, WDataInP rwp) VL_MT_SAFE {
for (int i=1; i < VL_WORDS_I(rbits); ++i) {
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
QData sign = -(lhs >> (lbits-1)); // ffff_ffff if negative
@ -1963,7 +2017,8 @@ static inline IData VL_BITSEL_IWII(int, int lbits, int, int, WDataInP lwp, IData
#define VL_SEL_QQII(obits,lbits,rbits,tbits,lhs,lsb,width) ((lhs)>>(lsb))
#define VL_SEL_IQII(obits,lbits,rbits,tbits,lhs,lsb,width) (static_cast<IData>((lhs)>>(lsb)))
static inline IData VL_SEL_IWII(int, int lbits, int, int, WDataInP lwp, IData lsb, IData width) VL_MT_SAFE {
static inline IData VL_SEL_IWII(int, int lbits, int, int,
WDataInP lwp, IData lsb, IData width) VL_MT_SAFE {
int msb = lsb+width-1;
if (VL_UNLIKELY(msb>lbits)) {
return ~0; // Spec says you can go outside the range of a array. Don't coredump if so.
@ -1977,7 +2032,8 @@ static inline IData VL_SEL_IWII(int, int lbits, int, int, WDataInP lwp, IData ls
}
}
static inline QData VL_SEL_QWII(int, int lbits, int, int, WDataInP lwp, IData lsb, IData width) VL_MT_SAFE {
static inline QData VL_SEL_QWII(int, int lbits, int, int,
WDataInP lwp, IData lsb, IData width) VL_MT_SAFE {
int msb = lsb+width-1;
if (VL_UNLIKELY(msb>lbits)) {
return ~0; // Spec says you can go outside the range of a array. Don't coredump if so.
@ -1998,7 +2054,8 @@ static inline QData VL_SEL_QWII(int, int lbits, int, int, WDataInP lwp, IData ls
}
}
static inline WDataOutP VL_SEL_WWII(int obits,int lbits,int,int,WDataOutP owp,WDataInP lwp, IData lsb, IData width) VL_MT_SAFE {
static inline WDataOutP VL_SEL_WWII(int obits, int lbits, int, int,
WDataOutP owp, WDataInP lwp, IData lsb, IData width) VL_MT_SAFE {
int msb = lsb+width-1;
int word_shift = VL_BITWORD_I(lsb);
if (VL_UNLIKELY(msb>lbits)) { // Outside bounds,
@ -2121,37 +2178,41 @@ static inline WDataOutP VL_CONSTHI_W_1X(int obits, int lsb, WDataOutP obase,
o[0]=d0;
_END(obits,1); }
static inline WDataOutP VL_CONSTHI_W_2X(int obits, int lsb, WDataOutP obase,
IData d1,IData d0) VL_MT_SAFE {
IData d1, IData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1;
_END(obits,2); }
static inline WDataOutP VL_CONSTHI_W_3X(int obits, int lsb, WDataOutP obase,
IData d2,IData d1,IData d0) VL_MT_SAFE {
IData d2, IData d1, IData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2;
_END(obits,3); }
static inline WDataOutP VL_CONSTHI_W_4X(int obits, int lsb, WDataOutP obase,
IData d3,IData d2,IData d1,IData d0) VL_MT_SAFE {
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3;
_END(obits,4); }
static inline WDataOutP VL_CONSTHI_W_5X(int obits, int lsb, WDataOutP obase,
IData d4,IData d3,IData d2,IData d1,IData d0) VL_MT_SAFE {
IData d4,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4;
_END(obits,5); }
static inline WDataOutP VL_CONSTHI_W_6X(int obits, int lsb, WDataOutP obase,
IData d5,IData d4,IData d3,IData d2,IData d1,IData d0) VL_MT_SAFE {
IData d5, IData d4,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5;
_END(obits,6); }
static inline WDataOutP VL_CONSTHI_W_7X(int obits, int lsb, WDataOutP obase,
IData d6,IData d5,IData d4,IData d3,IData d2,IData d1,IData d0) VL_MT_SAFE {
IData d6, IData d5, IData d4,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6;
_END(obits,7); }
static inline WDataOutP VL_CONSTHI_W_8X(int obits, int lsb, WDataOutP obase,
IData d7,IData d6,IData d5,IData d4,IData d3,IData d2,IData d1,IData d0) VL_MT_SAFE {
IData d7, IData d6, IData d5, IData d4,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
_END(obits,8); }
@ -2160,7 +2221,8 @@ static inline WDataOutP VL_CONSTHI_W_8X(int obits, int lsb, WDataOutP obase,
// Partial constant, lower words of vector wider than 8*32, starting at bit number lsb
static inline void VL_CONSTLO_W_8X(int lsb, WDataOutP obase,
IData d7, IData d6, IData d5, IData d4, IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
IData d7, IData d6, IData d5, IData d4,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7; }

View File

@ -192,11 +192,13 @@ void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal s, int lbit, int w
static inline const VerilatedDpiOpenVar* _vl_openhandle_varp(const svOpenArrayHandle h) {
if (VL_UNLIKELY(!h)) {
VL_FATAL_MT(__FILE__,__LINE__,"","%%Error: DPI svOpenArrayHandle function called with NULL handle");
VL_FATAL_MT(__FILE__, __LINE__, "",
"%%Error: DPI svOpenArrayHandle function called with NULL handle");
}
const VerilatedDpiOpenVar* varp = reinterpret_cast<const VerilatedDpiOpenVar*>(h);
if (VL_UNLIKELY(!varp->magicOk())) {
VL_FATAL_MT(__FILE__,__LINE__,"","%%Error: DPI svOpenArrayHandle function called with non-Verilator handle");
VL_FATAL_MT(__FILE__, __LINE__, "",
"%%Error: DPI svOpenArrayHandle function called with non-Verilator handle");
}
return varp;
}
@ -246,7 +248,8 @@ static void* _vl_sv_adjusted_datap(const VerilatedDpiOpenVar* varp,
int nargs, int indx1, int indx2, int indx3) {
void* datap = varp->datap();
if (VL_UNLIKELY(nargs != varp->udims())) {
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function called on %d dimensional array using %d dimensional function.\n",
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function called on"
" %d dimensional array using %d dimensional function.\n",
varp->udims(), nargs);
return NULL;
}

View File

@ -56,7 +56,8 @@ inline std::string VL_REPLICATEN_NNQ(int,int,int, const std::string& lhs, IData
for (unsigned times=0; times<rep; ++times) out += lhs;
return out;
}
inline std::string VL_REPLICATEN_NNI(int obits,int lbits,int rbits, const std::string& lhs, IData rep) VL_PURE {
inline std::string VL_REPLICATEN_NNI(int obits,int lbits,int rbits,
const std::string& lhs, IData rep) VL_PURE {
return VL_REPLICATEN_NNQ(obits,lbits,rbits,lhs,rep);
}

View File

@ -138,7 +138,8 @@ public:
}
// Read a datum and compare with expected value
VerilatedDeserialize& readAssert(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE;
VerilatedDeserialize& readAssert(vluint64_t data) VL_MT_UNSAFE_ONE { return readAssert(&data, sizeof(data)); }
VerilatedDeserialize& readAssert(vluint64_t data) VL_MT_UNSAFE_ONE {
return readAssert(&data, sizeof(data)); }
private:
bool readDiffers(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE;
VerilatedDeserialize& bufferCheck() VL_MT_UNSAFE_ONE {

View File

@ -52,7 +52,8 @@ public:
int right() const { return m_right; }
int low() const { return (m_left < m_right) ? m_left : m_right; }
int high() const { return (m_left > m_right) ? m_left : m_right; }
int elements() const { return (VL_LIKELY(m_left>=m_right) ? (m_left-m_right+1) : (m_right-m_left+1)); }
int elements() const {
return (VL_LIKELY(m_left>=m_right) ? (m_left-m_right+1) : (m_right-m_left+1)); }
int increment() const { return (m_left >= m_right) ? 1 : -1; }
};
@ -81,45 +82,54 @@ public:
class Unpacked {};
// Without packed
VerilatedVarProps(VerilatedVarType vltype, int vlflags)
: m_magic(MAGIC), m_vltype(vltype), m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(0) { }
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(0) { }
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Unpacked, int u0l, int u0r)
: m_magic(MAGIC), m_vltype(vltype), m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(1) {
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(1) {
m_unpacked[0].init(u0l, u0r); }
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Unpacked, int u0l, int u0r, int u1l, int u1r)
: m_magic(MAGIC), m_vltype(vltype), m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(2) {
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(2) {
m_unpacked[0].init(u0l, u0r); m_unpacked[1].init(u1l, u1r); }
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Unpacked, int u0l, int u0r, int u1l, int u1r, int u2l, int u2r)
: m_magic(MAGIC), m_vltype(vltype), m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(3) {
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(3) {
m_unpacked[0].init(u0l, u0r); m_unpacked[1].init(u1l, u1r); m_unpacked[2].init(u2l, u2r); }
// With packed
class Packed {};
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Packed, int pl, int pr)
: m_magic(MAGIC), m_vltype(vltype), m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(0), m_packed(pl,pr) { }
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(0), m_packed(pl,pr) { }
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Packed, int pl, int pr,
Unpacked, int u0l, int u0r)
: m_magic(MAGIC), m_vltype(vltype), m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(1), m_packed(pl,pr) {
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(1), m_packed(pl,pr) {
m_unpacked[0].init(u0l, u0r); }
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Packed, int pl, int pr,
Unpacked, int u0l, int u0r, int u1l, int u1r)
: m_magic(MAGIC), m_vltype(vltype), m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(2), m_packed(pl,pr) {
: m_magic(MAGIC), m_vltype(vltype), m_vlflags(VerilatedVarFlags(vlflags)),
m_pdims(1), m_udims(2), m_packed(pl,pr) {
m_unpacked[0].init(u0l, u0r); m_unpacked[1].init(u1l, u1r); }
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Packed, int pl, int pr,
Unpacked, int u0l, int u0r, int u1l, int u1r, int u2l, int u2r)
: m_magic(MAGIC), m_vltype(vltype), m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(3), m_packed(pl,pr) {
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(3), m_packed(pl,pr) {
m_unpacked[0].init(u0l, u0r); m_unpacked[1].init(u1l, u1r); m_unpacked[2].init(u2l, u2r); }
public:
~VerilatedVarProps() {}
// METHODS
bool magicOk() const { return m_magic==MAGIC; }
VerilatedVarType vltype() const { return m_vltype; }
VerilatedVarFlags vldir() const { return static_cast<VerilatedVarFlags>(static_cast<int>(m_vlflags) & VLVF_MASK_DIR); }
VerilatedVarFlags vldir() const {
return static_cast<VerilatedVarFlags>(static_cast<int>(m_vlflags) & VLVF_MASK_DIR); }
vluint32_t entSize() const;
bool isPublicRW() const { return ((m_vlflags & VLVF_PUB_RW) != 0); }
/// DPI compatible C standard layout

View File

@ -382,12 +382,14 @@ void VerilatedVcd::bufferFlush () VL_MT_UNSAFE_ONE {
// Simple methods
void VerilatedVcd::set_time_unit (const char* unitp) {
//cout<<" set_time_unit ("<<unitp<<") == "<<timescaleToDouble(unitp)<<" == "<<doubleToTimescale(timescaleToDouble(unitp))<<endl;
//cout<<" set_time_unit ("<<unitp<<") == "<<timescaleToDouble(unitp)
// <<" == "<<doubleToTimescale(timescaleToDouble(unitp))<<endl;
m_timeUnit = timescaleToDouble(unitp);
}
void VerilatedVcd::set_time_resolution (const char* unitp) {
//cout<<"set_time_resolution ("<<unitp<<") == "<<timescaleToDouble(unitp)<<" == "<<doubleToTimescale(timescaleToDouble(unitp))<<endl;
//cout<<"set_time_resolution ("<<unitp<<") == "<<timescaleToDouble(unitp)
// <<" == "<<doubleToTimescale(timescaleToDouble(unitp))<<endl;
m_timeRes = timescaleToDouble(unitp);
}

View File

@ -91,7 +91,8 @@ public:
t_freeHead = oldp;
}
// MEMBERS
static inline VerilatedVpio* castp(vpiHandle h) { return dynamic_cast<VerilatedVpio*>((VerilatedVpio*)h); }
static inline VerilatedVpio* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpio*>((VerilatedVpio*)h); }
inline vpiHandle castVpiHandle() { return reinterpret_cast<vpiHandle>(this); }
// ACCESSORS
virtual const char* name() const { return "<null>"; }
@ -117,7 +118,8 @@ public:
m_cbData.value = &m_value;
}
virtual ~VerilatedVpioCb() {}
static inline VerilatedVpioCb* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioCb*>((VerilatedVpio*)h); }
static inline VerilatedVpioCb* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioCb*>((VerilatedVpio*)h); }
virtual vluint32_t type() const { return vpiCallback; }
vluint32_t reason() const { return m_cbData.reason; }
VerilatedPliCb cb_rtnp() const { return m_cbData.cb_rtn; }
@ -130,7 +132,8 @@ class VerilatedVpioConst : public VerilatedVpio {
public:
explicit VerilatedVpioConst(vlsint32_t num) : m_num(num) {}
virtual ~VerilatedVpioConst() {}
static inline VerilatedVpioConst* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioConst*>((VerilatedVpio*)h); }
static inline VerilatedVpioConst* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioConst*>((VerilatedVpio*)h); }
virtual vluint32_t type() const { return vpiUndefined; }
vlsint32_t num() const { return m_num; }
};
@ -141,7 +144,8 @@ class VerilatedVpioRange : public VerilatedVpio {
public:
explicit VerilatedVpioRange(const VerilatedRange* range) : m_range(range), m_iteration(0) {}
virtual ~VerilatedVpioRange() {}
static inline VerilatedVpioRange* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioRange*>((VerilatedVpio*)h); }
static inline VerilatedVpioRange* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioRange*>((VerilatedVpio*)h); }
virtual vluint32_t type() const { return vpiRange; }
virtual vluint32_t size() const { return m_range->elements(); }
virtual const VerilatedRange* rangep() const { return m_range; }
@ -164,7 +168,8 @@ public:
explicit VerilatedVpioScope(const VerilatedScope* scopep)
: m_scopep(scopep) {}
virtual ~VerilatedVpioScope() {}
static inline VerilatedVpioScope* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioScope*>((VerilatedVpio*)h); }
static inline VerilatedVpioScope* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioScope*>((VerilatedVpio*)h); }
virtual vluint32_t type() const { return vpiScope; }
const VerilatedScope* scopep() const { return m_scopep; }
virtual const char* name() const { return m_scopep->name(); }
@ -198,7 +203,8 @@ public:
virtual ~VerilatedVpioVar() {
if (m_prevDatap) { delete [] m_prevDatap; m_prevDatap = NULL; }
}
static inline VerilatedVpioVar* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioVar*>((VerilatedVpio*)h); }
static inline VerilatedVpioVar* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioVar*>((VerilatedVpio*)h); }
const VerilatedVar* varp() const { return m_varp; }
const VerilatedScope* scopep() const { return m_scopep; }
vluint32_t mask() const { return m_mask.u32; }
@ -236,7 +242,8 @@ public:
m_varDatap = ((vluint8_t*)varp->datap()) + entSize()*offset;
}
virtual ~VerilatedVpioMemoryWord() {}
static inline VerilatedVpioMemoryWord* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioMemoryWord*>((VerilatedVpio*)h); }
static inline VerilatedVpioMemoryWord* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioMemoryWord*>((VerilatedVpio*)h); }
virtual vluint32_t type() const { return vpiMemoryWord; }
virtual vluint32_t size() const { return varp()->packed().elements(); }
virtual const VerilatedRange* rangep() const { return &(varp()->packed()); }
@ -256,7 +263,8 @@ public:
explicit VerilatedVpioVarIter(const VerilatedScope* scopep)
: m_scopep(scopep), m_started(false) { }
virtual ~VerilatedVpioVarIter() {}
static inline VerilatedVpioVarIter* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioVarIter*>((VerilatedVpio*)h); }
static inline VerilatedVpioVarIter* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioVarIter*>((VerilatedVpio*)h); }
virtual vluint32_t type() const { return vpiIterator; }
virtual vpiHandle dovpi_scan() {
if (VL_LIKELY(m_scopep->varsp())) {
@ -281,9 +289,13 @@ class VerilatedVpioMemoryWordIter : public VerilatedVpio {
bool m_done;
public:
VerilatedVpioMemoryWordIter(const vpiHandle handle, const VerilatedVar* varp)
: m_handle(handle), m_varp(varp), m_iteration(varp->unpacked().right()), m_direction(VL_LIKELY(varp->unpacked().left()>varp->unpacked().right())?1:-1), m_done(false) { }
: m_handle(handle), m_varp(varp), m_iteration(varp->unpacked().right()),
m_direction(VL_LIKELY(varp->unpacked().left() > varp->unpacked().right())
? 1 : -1),
m_done(false) { }
virtual ~VerilatedVpioMemoryWordIter() {}
static inline VerilatedVpioMemoryWordIter* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioMemoryWordIter*>((VerilatedVpio*)h); }
static inline VerilatedVpioMemoryWordIter* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioMemoryWordIter*>((VerilatedVpio*)h); }
virtual vluint32_t type() const { return vpiIterator; }
void iterationInc() {
if (!(m_done = (m_iteration == m_varp->unpacked().left()))) m_iteration+=m_direction;
@ -337,7 +349,9 @@ public:
varop->createPrevDatap();
}
}
if (VL_UNLIKELY(vop->reason() >= CB_ENUM_MAX_VALUE)) VL_FATAL_MT(__FILE__,__LINE__,"", "vpi bb reason too large");
if (VL_UNLIKELY(vop->reason() >= CB_ENUM_MAX_VALUE)) {
VL_FATAL_MT(__FILE__,__LINE__,"", "vpi bb reason too large");
}
s_s.m_cbObjLists[vop->reason()].push_back(vop);
}
static void cbTimedAdd(VerilatedVpioCb* vop) {
@ -921,7 +935,8 @@ vpiHandle vpi_register_cb(p_cb_data cb_data_p) {
QData time = 0;
if (cb_data_p->time) time = _VL_SET_QII(cb_data_p->time->high, cb_data_p->time->low);
VerilatedVpioCb* vop = new VerilatedVpioCb(cb_data_p, VL_TIME_Q()+time);
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_register_cb %d %p delay=%" VL_PRI64 "u\n",cb_data_p->reason,vop,time););
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_register_cb %d %p delay=%" VL_PRI64 "u\n",
cb_data_p->reason, vop, time););
VerilatedVpiImp::cbTimedAdd(vop);
return vop->castVpiHandle();
}
@ -1016,12 +1031,14 @@ vpiHandle vpi_handle_by_index(vpiHandle object, PLI_INT32 indx) {
if (VL_LIKELY(varop)) {
if (varop->varp()->dims()<2) return 0;
if (VL_LIKELY(varop->varp()->unpacked().left() >= varop->varp()->unpacked().right())) {
if (VL_UNLIKELY(indx > varop->varp()->unpacked().left() || indx < varop->varp()->unpacked().right())) return 0;
if (VL_UNLIKELY(indx > varop->varp()->unpacked().left()
|| indx < varop->varp()->unpacked().right())) return 0;
return (new VerilatedVpioMemoryWord(varop->varp(), varop->scopep(), indx,
indx - varop->varp()->unpacked().right()))
->castVpiHandle();
} else {
if (VL_UNLIKELY(indx < varop->varp()->unpacked().left() || indx > varop->varp()->unpacked().right())) return 0;
if (VL_UNLIKELY(indx < varop->varp()->unpacked().left()
|| indx > varop->varp()->unpacked().right())) return 0;
return (new VerilatedVpioMemoryWord(varop->varp(), varop->scopep(), indx,
indx - varop->varp()->unpacked().left()))
->castVpiHandle();
@ -1206,7 +1223,8 @@ void vpi_put_delays(vpiHandle object, p_vpi_delay delay_p) {
// value processing
void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
static VL_THREAD_LOCAL char outStr[1+VL_MULS_MAX_WORDS*32]; // Maximum required size is for binary string, one byte per bit plus null termination
// Maximum required size is for binary string, one byte per bit plus null termination
static VL_THREAD_LOCAL char outStr[1+VL_MULS_MAX_WORDS*32];
// cppcheck-suppress variableScope
static VL_THREAD_LOCAL int outStrSz = sizeof(outStr)-1;
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_get_value %p\n",object););
@ -1274,8 +1292,10 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
if (bits > outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
bits = outStrSz;
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, bits);
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s"
" as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, bits);
}
for (i=0; i<bits; ++i) {
char val = (datap[i>>3]>>(i&7))&1;
@ -1286,7 +1306,8 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
}
default:
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
return;
}
} else if (value_p->format == vpiOctStrVal) {
@ -1303,8 +1324,10 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
int i;
if (chars > outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, chars);
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s"
" as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, chars);
chars = outStrSz;
}
for (i=0; i<chars; ++i) {
@ -1368,8 +1391,10 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
int i;
if (chars > outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, chars);
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s"
" as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, chars);
chars = outStrSz;
}
for (i=0; i<chars; ++i) {
@ -1406,7 +1431,8 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
int i;
if (bytes > outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)",
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s"
" as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, bytes);
bytes = outStrSz;
@ -1478,7 +1504,9 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
VL_DBG_MSGF("- vpi: varp=%p putatp=%p\n",
vop->varp()->datap(), vop->varDatap()););
if (VL_UNLIKELY(!vop->varp()->isPublicRW())) {
_VL_VPI_WARNING(__FILE__, __LINE__, "Ignoring vpi_put_value to signal marked read-only, use public_flat_rw instead: ", vop->fullname());
_VL_VPI_WARNING(__FILE__, __LINE__, "Ignoring vpi_put_value to signal marked read-only,"
" use public_flat_rw instead: ",
vop->fullname());
return 0;
}
if (value_p->format == vpiVectorVal) {
@ -1615,7 +1643,9 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
}
if (success > 1) {
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Trailing garbage '%s' in '%s' as value %s for %s",
VL_FUNC, remainder, value_p->value.str, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
VL_FUNC, remainder, value_p->value.str,
VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
}
switch (vop->varp()->vltype()) {
case VLVT_UINT8 : *(reinterpret_cast<CData*>(vop->varDatap())) = val & vop->mask(); break;
@ -1655,7 +1685,9 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
else if (digit >= 'A' && digit <= 'F') hex = digit - 'A' + 10;
else {
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Non hex character '%c' in '%s' as value %s for %s",
VL_FUNC, digit, value_p->value.str, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
VL_FUNC, digit, value_p->value.str,
VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
hex = 0;
}
} else {
@ -1688,7 +1720,8 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
int len = strlen(value_p->value.str);
CData* datap = (reinterpret_cast<CData*>(vop->varDatap()));
for (int i=0; i<bytes; ++i) {
datap[i] = (i < len)?value_p->value.str[len-i-1]:0; // prepend with 0 values before placing string the least signifcant bytes
// prepend with 0 values before placing string the least signifcant bytes
datap[i] = (i < len)?value_p->value.str[len-i-1]:0;
}
return object;
}

View File

@ -174,11 +174,13 @@ private:
// Convert to a non-delayed assignment
UINFO(5," ASSIGNDLY "<<nodep<<endl);
if (m_check == CT_INITIAL) {
nodep->v3warn(INITIALDLY,"Delayed assignments (<=) in initial or final block; suggest blocking assignments (=).");
nodep->v3warn(INITIALDLY, "Delayed assignments (<=) in initial"
" or final block; suggest blocking assignments (=).");
} else if (m_check == CT_LATCH) {
// Suppress. Shouldn't matter that the interior of the latch races
} else {
nodep->v3warn(COMBDLY,"Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=).");
nodep->v3warn(COMBDLY, "Delayed assignments (<=) in non-clocked"
" (non flop or latch) block; suggest blocking assignments (=).");
}
AstNode* newp = new AstAssign (nodep->fileline(),
nodep->lhsp()->unlinkFrBack(),
@ -437,6 +439,8 @@ public:
void V3Active::activeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ActiveVisitor visitor (nodep);
{
ActiveVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("active", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -159,6 +159,8 @@ public:
void V3ActiveTop::activeTopAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ActiveTopVisitor visitor (nodep);
{
ActiveTopVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("activetop", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -349,6 +349,8 @@ public:
void V3Assert::assertAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
AssertVisitor visitor (nodep);
{
AssertVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("assert", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -136,6 +136,8 @@ public:
void V3AssertPre::assertPreAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
AssertPreVisitor visitor (nodep);
{
AssertPreVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("assertpre", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -229,7 +229,8 @@ inline void AstNode::debugTreeChange(const char* prefix, int lineno, bool next)
// Called on all major tree changers.
// Only for use for those really nasty bugs relating to internals
// Note this may be null.
//if (debug()) cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<": "<<(void*)this<<" <e"<<AstNode::s_editCntGbl<<">"<<endl;
//if (debug()) cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "
// <<prefix<<": "<<(void*)this<<" <e"<<AstNode::s_editCntGbl<<">"<<endl;
//if (debug()) {
// cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<endl;
// // Commenting out the section below may crash, as the tree state
@ -677,9 +678,17 @@ void AstNode::deleteNode() {
this->m_op2p = (AstNode*)1;
this->m_op3p = (AstNode*)1;
this->m_op4p = (AstNode*)1;
if (
#if !defined(VL_DEBUG) || defined(VL_LEAK_CHECKS)
delete this; // Leak massively, so each pointer is unique and we can debug easier
1
#else
!v3Global.opt.debugLeak()
#endif
) {
delete this;
}
// Else leak massively, so each pointer is unique
// and we can debug easier.
}
AstNode::~AstNode() {
@ -779,7 +788,9 @@ void AstNode::iterateAndNext(AstNVisitor& v) {
niterp->m_iterpp = &niterp;
niterp->accept(v);
// accept may do a replaceNode and change niterp on us...
//if (niterp != nodep) UINFO(1,"iterateAndNext edited "<<(void*)nodep<<" now into "<<(void*)niterp<<endl); // niterp maybe NULL, so need cast
// niterp maybe NULL, so need cast if printing
//if (niterp != nodep) UINFO(1,"iterateAndNext edited "<<(void*)nodep
// <<" now into "<<(void*)niterp<<endl);
if (!niterp) return; // Perhaps node deleted inside accept
niterp->m_iterpp = NULL;
if (VL_UNLIKELY(niterp!=nodep)) { // Edited node inside accept

View File

@ -1110,7 +1110,8 @@ public:
AstNode* op4p() const { return m_op4p; }
AstNodeDType* dtypep() const { return m_dtypep; }
AstNode* clonep() const { return ((m_cloneCnt==s_cloneCntGbl)?m_clonep:NULL); }
AstNode* firstAbovep() const { return ((backp() && backp()->nextp()!=this) ? backp() : NULL); } // Returns NULL when second or later in list
AstNode* firstAbovep() const { // Returns NULL when second or later in list
return ((backp() && backp()->nextp()!=this) ? backp() : NULL); }
bool brokeExists() const;
bool brokeExistsAbove() const;
@ -1301,7 +1302,8 @@ public:
void addHereThisAsNext(AstNode* newp); // Adds at old place of this, this becomes next
void replaceWith(AstNode* newp); // Replace current node in tree with new node
AstNode* unlinkFrBack(AstNRelinker* linkerp=NULL); // Unlink this from whoever points to it.
AstNode* unlinkFrBackWithNext(AstNRelinker* linkerp=NULL); // Unlink this from whoever points to it, keep entire next list with unlinked node
// Unlink this from whoever points to it, keep entire next list with unlinked node
AstNode* unlinkFrBackWithNext(AstNRelinker* linkerp=NULL);
void swapWith(AstNode* bp);
void relink(AstNRelinker* linkerp); // Generally use linker->relink() instead
void cloneRelinkNode() { cloneRelink(); }
@ -1330,17 +1332,20 @@ public:
virtual bool isPure() const { return true; } // Else a $display, etc, that must be ordered with other displays
virtual bool isBrancher() const { return false; } // Changes control flow, disable some optimizations
virtual bool isGateOptimizable() const { return true; } // Else a AstTime etc that can't be pushed out
virtual bool isGateDedupable() const { return isGateOptimizable(); } // GateDedupable is a slightly larger superset of GateOptimzable (eg, AstNodeIf)
// GateDedupable is a slightly larger superset of GateOptimzable (eg, AstNodeIf)
virtual bool isGateDedupable() const { return isGateOptimizable(); }
virtual bool isSubstOptimizable() const { return true; } // Else a AstTime etc that can't be substituted out
virtual bool isPredictOptimizable() const { return true; } // Else a AstTime etc which output can't be predicted from input
virtual bool isOutputter() const { return false; } // Else creates output or exits, etc, not unconsumed
virtual bool isUnlikely() const { return false; } // Else $stop or similar statement which means an above IF statement is unlikely to be taken
// isUnlikely handles $stop or similar statement which means an above IF statement is unlikely to be taken
virtual bool isUnlikely() const { return false; }
virtual int instrCount() const { return 0; }
virtual V3Hash sameHash() const { return V3Hash(V3Hash::Illegal()); } // Not a node that supports it
virtual bool same(const AstNode*) const { return true; }
virtual bool hasDType() const { return false; } // Iff has a data type; dtype() must be non null
virtual AstNodeDType* getChildDTypep() const { return NULL; } // Iff has a non-null childDTypep(), as generic node function
virtual bool maybePointedTo() const { return false; } // Another AstNode* may have a pointer into this node, other then normal front/back/etc.
// Another AstNode* may have a pointer into this node, other then normal front/back/etc.
virtual bool maybePointedTo() const { return false; }
virtual const char* broken() const { return NULL; }
// INVOKERS
@ -1463,7 +1468,9 @@ public:
void rhsp(AstNode* nodep) { return setOp2p(nodep); }
void thsp(AstNode* nodep) { return setOp3p(nodep); }
// METHODS
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, const V3Number& ths) = 0; // Set out to evaluation of a AstConst'ed
// Set out to evaluation of a AstConst'ed
virtual void numberOperate(V3Number& out, const V3Number& lhs,
const V3Number& rhs, const V3Number& ths) = 0;
virtual bool cleanLhs() = 0; // True if LHS must have extra upper bits zero
virtual bool cleanRhs() = 0; // True if RHS must have extra upper bits zero
virtual bool cleanThs() = 0; // True if THS must have extra upper bits zero
@ -1749,7 +1756,8 @@ public:
bool isNosign() const { return m_numeric.isNosign(); }
AstNumeric numeric() const { return m_numeric; }
int widthWords() const { return VL_WORDS_I(width()); }
int widthMin() const { return m_widthMin?m_widthMin:m_width; } // If sized, the size, if unsized the min digits to represent it
int widthMin() const { // If sized, the size, if unsized the min digits to represent it
return m_widthMin?m_widthMin:m_width; }
int widthPow2() const;
void widthMinFromWidth() { m_widthMin = m_width; }
bool widthSized() const { return !m_widthMin || m_widthMin==m_width; }
@ -2089,11 +2097,16 @@ public:
inline int AstNode::width() const { return dtypep() ? dtypep()->width() : 0; }
inline int AstNode::widthMin() const { return dtypep() ? dtypep()->widthMin() : 0; }
inline bool AstNode::width1() const { return dtypep() && dtypep()->width()==1; } // V3Const uses to know it can optimize
inline int AstNode::widthInstrs() const { return (!dtypep() ? 1 : (dtypep()->isWide() ? dtypep()->widthWords() : 1)); }
inline bool AstNode::isDouble() const { return dtypep() && VN_IS(dtypep(), BasicDType) && VN_CAST(dtypep(), BasicDType)->isDouble(); }
inline bool AstNode::isString() const { return dtypep() && dtypep()->basicp() && dtypep()->basicp()->isString(); }
inline bool AstNode::isSigned() const { return dtypep() && dtypep()->isSigned(); }
inline bool AstNode::width1() const { // V3Const uses to know it can optimize
return dtypep() && dtypep()->width()==1; }
inline int AstNode::widthInstrs() const {
return (!dtypep() ? 1 : (dtypep()->isWide() ? dtypep()->widthWords() : 1)); }
inline bool AstNode::isDouble() const {
return dtypep() && VN_IS(dtypep(), BasicDType) && VN_CAST(dtypep(), BasicDType)->isDouble(); }
inline bool AstNode::isString() const {
return dtypep() && dtypep()->basicp() && dtypep()->basicp()->isString(); }
inline bool AstNode::isSigned() const {
return dtypep() && dtypep()->isSigned(); }
inline bool AstNode::isZero() const { return (VN_IS(this, Const) && VN_CAST_CONST(this, Const)->num().isEqZero()); }
inline bool AstNode::isNeqZero() const { return (VN_IS(this, Const) && VN_CAST_CONST(this, Const)->num().isNeqZero()); }

View File

@ -65,7 +65,8 @@ int AstNodeSel::bitConst() const {
void AstNodeClassDType::repairMemberCache() {
clearCache();
for (AstMemberDType* itemp = membersp(); itemp; itemp=VN_CAST(itemp->nextp(), MemberDType)) {
if (m_members.find(itemp->name())!=m_members.end()) { itemp->v3error("Duplicate declaration of member name: "<<itemp->prettyName()); }
if (m_members.find(itemp->name())!=m_members.end()) {
itemp->v3error("Duplicate declaration of member name: "<<itemp->prettyName()); }
else m_members.insert(make_pair(itemp->name(), itemp));
}
}

View File

@ -47,26 +47,26 @@ private:
public:
AstConst(FileLine* fl, const V3Number& num)
:AstNodeMath(fl)
,m_num(num) {
,m_num(num) {
if (m_num.isDouble()) {
dtypeSetDouble();
} else if (m_num.isString()) {
} else if (m_num.isString()) {
dtypeSetString();
} else {
dtypeSetLogicSized(m_num.width(), m_num.sized()?0:m_num.widthMin(),
m_num.isSigned() ? AstNumeric::SIGNED
dtypeSetLogicSized(m_num.width(), m_num.sized()?0:m_num.widthMin(),
m_num.isSigned() ? AstNumeric::SIGNED
: AstNumeric::UNSIGNED);
}
}
}
AstConst(FileLine* fl, uint32_t num)
:AstNodeMath(fl)
,m_num(V3Number(fl,32,num)) { dtypeSetLogicSized(m_num.width(),
,m_num(V3Number(fl,32,num)) { dtypeSetLogicSized(m_num.width(),
m_num.sized()?0:m_num.widthMin(),
AstNumeric::UNSIGNED); }
class Unsized32 {}; // for creator type-overload selection
class Unsized32 {}; // for creator type-overload selection
AstConst(FileLine* fl, Unsized32, uint32_t num) // Unsized 32-bit integer of specified value
:AstNodeMath(fl)
,m_num(V3Number(fl,32,num)) { m_num.width(32,false); dtypeSetLogicSized(32,m_num.widthMin(),
:AstNodeMath(fl)
,m_num(V3Number(fl,32,num)) { m_num.width(32,false); dtypeSetLogicSized(32,m_num.widthMin(),
AstNumeric::UNSIGNED); }
class Signed32 {}; // for creator type-overload selection
AstConst(FileLine* fl, Signed32, int32_t num) // Signed 32-bit integer of specified value
@ -79,7 +79,7 @@ public:
,m_num(V3Number(fl,64)) { m_num.setDouble(num); dtypeSetDouble(); }
class String {}; // for creator type-overload selection
AstConst(FileLine* fl, String, const string& num)
:AstNodeMath(fl)
:AstNodeMath(fl)
,m_num(V3Number(V3Number::String(), fl, num)) { dtypeSetString(); }
class LogicFalse {};
AstConst(FileLine* fl, LogicFalse) // Shorthand const 0, know the dtype should be a logic of size 1
@ -706,13 +706,17 @@ public:
virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); }
virtual bool similarDType(AstNodeDType* samep) const { return this==samep; }
//
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType)
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } // op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType)
// (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType)
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); }
// op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType)
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); }
virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); }
virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); }
virtual AstNodeDType* skipRefToEnump() const { return subDTypep()->skipRefToEnump(); }
virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
// (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); }
// (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); }
// METHODS
virtual void name(const string& name) { m_name = name; }
virtual void tag(const string& text) { m_tag = text;}
@ -1183,7 +1187,8 @@ public:
string scType() const; // Return SysC type: bool, uint32_t, uint64_t, sc_bv
string cPubArgType(bool named, bool forReturn) const; // Return C /*public*/ type for argument: bool, uint32_t, uint64_t, etc.
string dpiArgType(bool named, bool forReturn) const; // Return DPI-C type for argument
string vlArgType(bool named, bool forReturn, bool forFunc) const; // Return Verilator internal type for argument: CData, SData, IData, WData
// Return Verilator internal type for argument: CData, SData, IData, WData
string vlArgType(bool named, bool forReturn, bool forFunc) const;
string vlEnumType() const; // Return VerilatorVarType: VLVT_UINT32, etc
string vlEnumDir() const; // Return VerilatorVarDir: VLVD_INOUT, etc
string vlPropInit() const; // Return VerilatorVarProps initializer
@ -1191,7 +1196,8 @@ public:
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Range of variable
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); }
AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType)
// (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType)
AstBasicDType* basicp() const { return subDTypep()->basicp(); }
AstNode* valuep() const { return op3p(); } // op3 = Initial value that never changes (static const)
void valuep(AstNode* nodep) { setOp3p(nodep); } // It's valuep, not constp, as may be more complicated than an AstConst
void addAttrsp(AstNode* nodep) { addNOp4p(nodep); }
@ -1443,11 +1449,14 @@ class AstVarRef : public AstNodeVarRef {
// A reference to a variable (lvalue or rvalue)
public:
AstVarRef(FileLine* fl, const string& name, bool lvalue)
:AstNodeVarRef(fl, name, NULL, lvalue) {}
AstVarRef(FileLine* fl, AstVar* varp, bool lvalue) // This form only allowed post-link
:AstNodeVarRef(fl, varp->name(), varp, lvalue) {} // because output/wire compression may lead to deletion of AstVar's
AstVarRef(FileLine* fl, AstVarScope* varscp, bool lvalue) // This form only allowed post-link
:AstNodeVarRef(fl, varscp->varp()->name(), varscp->varp(), lvalue) { // because output/wire compression may lead to deletion of AstVar's
: AstNodeVarRef(fl, name, NULL, lvalue) {}
// This form only allowed post-link because output/wire compression may
// lead to deletion of AstVar's
AstVarRef(FileLine* fl, AstVar* varp, bool lvalue)
: AstNodeVarRef(fl, varp->name(), varp, lvalue) {}
// This form only allowed post-link (see above)
AstVarRef(FileLine* fl, AstVarScope* varscp, bool lvalue)
: AstNodeVarRef(fl, varscp->varp()->name(), varscp->varp(), lvalue) {
varScopep(varscp);
}
ASTNODE_NODE_FUNCS(VarRef)
@ -2331,7 +2340,9 @@ public:
ASTNODE_NODE_FUNCS(CoverDecl)
virtual const char* broken() const {
BROKEN_RTN(m_dataDeclp && !m_dataDeclp->brokeExists());
if (m_dataDeclp && m_dataDeclp->m_dataDeclp) v3fatalSrc("dataDeclp should point to real data, not be a list"); // Avoid O(n^2) accessing
if (m_dataDeclp && m_dataDeclp->m_dataDeclp) { // Avoid O(n^2) accessing
v3fatalSrc("dataDeclp should point to real data, not be a list");
}
return NULL; }
virtual void cloneRelink() { if (m_dataDeclp && m_dataDeclp->clonep()) m_dataDeclp = m_dataDeclp->clonep(); }
virtual void dump(std::ostream& str);
@ -2594,6 +2605,26 @@ public:
void lhsp(AstNode* nodep) { setOp3p(nodep); }
};
class AstSysFuncAsTask : public AstNodeStmt {
// Call what is normally a system function (with a return) in a non-return context
// Parents: stmtlist
// Children: a system function
public:
AstSysFuncAsTask(FileLine* fileline, AstNode* exprsp)
: AstNodeStmt (fileline) { addNOp1p(exprsp); }
ASTNODE_NODE_FUNCS(SysFuncAsTask)
virtual string verilogKwd() const { return ""; }
virtual bool isGateOptimizable() const { return true; }
virtual bool isPredictOptimizable() const { return true; }
virtual bool isPure() const { return true; }
virtual bool isOutputter() const { return false; }
virtual int instrCount() const { return 0; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(const AstNode* samep) const { return true; }
AstNode* lhsp() const { return op1p(); } // op1 = Expressions to eval
void lhsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to eval
};
class AstSysIgnore : public AstNodeStmt {
// Parents: stmtlist
// Children: varrefs or exprs
@ -3420,10 +3451,14 @@ public:
void scopeAttrp(AstNode* nodep) { addOp1p(nodep); }
AstText* scopeEntrp() const { return VN_CAST(op2p(), Text); }
void scopeEntrp(AstNode* nodep) { addOp2p(nodep); }
string scopeSymName() const { return scopeNameFormatter(scopeAttrp()); } // Name for __Vscope variable including children
string scopeDpiName() const { return scopeNameFormatter(scopeEntrp()); } // Name for DPI import scope
string scopePrettySymName() const { return scopePrettyNameFormatter(scopeAttrp()); } // Name for __Vscope variable including children
string scopePrettyDpiName() const { return scopePrettyNameFormatter(scopeEntrp()); } // Name for __Vscope variable including children
string scopeSymName() const { // Name for __Vscope variable including children
return scopeNameFormatter(scopeAttrp()); }
string scopeDpiName() const { // Name for DPI import scope
return scopeNameFormatter(scopeEntrp()); }
string scopePrettySymName() const { // Name for __Vscope variable including children
return scopePrettyNameFormatter(scopeAttrp()); }
string scopePrettyDpiName() const { // Name for __Vscope variable including children
return scopePrettyNameFormatter(scopeEntrp()); }
bool dpiExport() const { return m_dpiExport; }
void dpiExport(bool flag) { m_dpiExport=flag; }
};
@ -4606,7 +4641,9 @@ public:
virtual string emitSimpleOperator() { return ">>"; }
virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} // LHS size might be > output size, so don't want to force size
// LHS size might be > output size, so don't want to force size
virtual bool sizeMattersLhs() {return false;}
virtual bool sizeMattersRhs() {return false;}
};
class AstShiftRS : public AstNodeBiop {
// Shift right with sign extension, >>> operator
@ -5677,8 +5714,10 @@ public:
BROKEN_RTN(m_evalp && !m_evalp->brokeExists());
return NULL;
}
AstNodeModule* modulesp() const { return VN_CAST(op1p(), NodeModule); } // op1 = List of modules
AstNodeModule* topModulep() const { return VN_CAST(op1p(), NodeModule); } // * = Top module in hierarchy (first one added, for now)
AstNodeModule* modulesp() const { // op1 = List of modules
return VN_CAST(op1p(), NodeModule); }
AstNodeModule* topModulep() const { // * = Top module in hierarchy (first one added, for now)
return VN_CAST(op1p(), NodeModule); }
void addModulep(AstNodeModule* modulep) { addOp1p(modulep); }
AstCFile* filesp() const { return VN_CAST(op2p(), CFile);} // op2 = List of files
void addFilesp(AstCFile* filep) { addOp2p(filep); }

View File

@ -291,10 +291,12 @@ public:
void V3Begin::debeginAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
BeginState state;
{ BeginVisitor bvisitor (nodep,&state); }
if (state.anyFuncInBegin()) {
BeginRelinkVisitor brvisitor (nodep,&state);
}
{
BeginState state;
{ BeginVisitor bvisitor (nodep,&state); }
if (state.anyFuncInBegin()) {
BeginRelinkVisitor brvisitor (nodep,&state);
}
} // Destruct before checking
V3Global::dumpCheckGlobalTree("begin", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -224,8 +224,10 @@ private:
nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo): "<<whyp);
}
if (nodep->dtypep()) {
if (!nodep->dtypep()->brokeExists()) { nodep->v3fatalSrc("Broken link in node->dtypep() to "<<(void*)nodep->dtypep()); }
else if (!VN_IS(nodep->dtypep(), NodeDType)) { nodep->v3fatalSrc("Non-dtype link in node->dtypep() to "<<(void*)nodep->dtypep()); }
if (!nodep->dtypep()->brokeExists()) {
nodep->v3fatalSrc("Broken link in node->dtypep() to "<<(void*)nodep->dtypep()); }
else if (!VN_IS(nodep->dtypep(), NodeDType)) {
nodep->v3fatalSrc("Non-dtype link in node->dtypep() to "<<(void*)nodep->dtypep()); }
}
if (v3Global.assertDTypesResolved()) {
if (nodep->hasDType()) {

View File

@ -130,7 +130,8 @@ void V3CCtors::evalAsserts() {
newp = new AstAnd(varp->fileline(), newp,
new AstConst(varp->fileline(), num));
AstNodeIf* ifp = new AstIf(varp->fileline(), newp,
new AstCStmt(varp->fileline(), "Verilated::overWidthError(\""+varp->prettyName()+"\");"));
new AstCStmt(varp->fileline(),
"Verilated::overWidthError(\""+varp->prettyName()+"\");"));
ifp->branchPred(AstBranchPred::BP_UNLIKELY);
newp = ifp;
funcp->addStmtsp(newp);

View File

@ -488,7 +488,9 @@ public:
void V3Case::caseAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CaseVisitor visitor (nodep);
{
CaseVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("case", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Case::caseLint(AstNodeCase* nodep) {

View File

@ -187,6 +187,8 @@ public:
void V3Cast::castAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CastVisitor visitor (nodep);
{
CastVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("cast", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -175,13 +175,17 @@ private:
newChangeDet();
} else {
if (debug()) nodep->dumpTree(cout,"-DETECTARRAY-class-");
m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<<m_vscp->varp()->prettyName());
m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable"
" (probably with UNOPTFLAT warning suppressed): "
<<m_vscp->varp()->prettyName());
}
}
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
if (debug()) nodep->dumpTree(cout,"-DETECTARRAY-general-");
m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<<m_vscp->varp()->prettyName());
m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable"
" (probably with UNOPTFLAT warning suppressed): "
<<m_vscp->varp()->prettyName());
}
public:
// CONSTUCTORS
@ -300,7 +304,9 @@ public:
void V3Changed::changedAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ChangedState state;
ChangedVisitor visitor (nodep, &state);
{
ChangedState state;
ChangedVisitor visitor (nodep, &state);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("changed", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -297,6 +297,8 @@ public:
void V3Clean::cleanAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CleanVisitor visitor (nodep);
{
CleanVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("clean", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -912,8 +912,10 @@ public:
void V3ClkGater::clkGaterAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
// While the gater does well at some modules, it seems to slow down many others
UINFO(5,"ClkGater is disabled due to performance issues\n");
{
// While the gater does well at some modules, it seems to slow down many others
UINFO(5,"ClkGater is disabled due to performance issues\n");
} // Destruct before checking
//GaterVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("clkgater", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -406,6 +406,8 @@ public:
void V3Clock::clockAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ClockVisitor visitor (nodep);
{
ClockVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("clock", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -473,6 +473,8 @@ public:
void V3Combine::combineAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CombineVisitor visitor (nodep);
{
CombineVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("combine", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -1202,7 +1202,8 @@ private:
AstAnd* newp = new AstAnd(nodep->fileline(),
new AstConst(nodep->fileline(), val),
fromp);
newp->dtypeSetLogicSized(nodep->width(), nodep->width(), AstNumeric::UNSIGNED); // widthMin no longer applicable if different C-expanded width
// widthMin no longer applicable if different C-expanded width
newp->dtypeSetLogicSized(nodep->width(), nodep->width(), AstNumeric::UNSIGNED);
nodep->replaceWith(newp);
nodep->deleteTree(); VL_DANGLING(nodep);
if (debug()>=9) newp->dumpTree(cout," _new: ");
@ -1759,7 +1760,8 @@ private:
// Something's out of order, sort it
senp = NULL;
std::vector<AstNodeSenItem*> vec;
for (AstNodeSenItem* senp = VN_CAST(nodep->sensesp(), NodeSenItem); senp; senp=VN_CAST(senp->nextp(), NodeSenItem)) {
for (AstNodeSenItem* senp = VN_CAST(nodep->sensesp(), NodeSenItem);
senp; senp=VN_CAST(senp->nextp(), NodeSenItem)) {
vec.push_back(senp);
}
stable_sort(vec.begin(), vec.end(), SenItemCmp());
@ -2561,15 +2563,19 @@ AstNode* V3Const::constifyGenerateParamsEdit(AstNode* nodep) {
void V3Const::constifyAllLint(AstNetlist* nodep) {
// Only call from Verilator.cpp, as it uses user#'s
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (ConstVisitor::PROC_V_WARN);
(void)visitor.mainAcceptEdit(nodep);
{
ConstVisitor visitor (ConstVisitor::PROC_V_WARN);
(void)visitor.mainAcceptEdit(nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("const", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Const::constifyCpp(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (ConstVisitor::PROC_CPP);
(void)visitor.mainAcceptEdit(nodep);
{
ConstVisitor visitor (ConstVisitor::PROC_CPP);
(void)visitor.mainAcceptEdit(nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("const_cpp", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
@ -2584,16 +2590,20 @@ void V3Const::constifyAllLive(AstNetlist* nodep) {
// This only pushes constants up, doesn't make any other edits
// IE doesn't prune dead statements, as we need to do some usability checks after this
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (ConstVisitor::PROC_LIVE);
(void)visitor.mainAcceptEdit(nodep);
{
ConstVisitor visitor (ConstVisitor::PROC_LIVE);
(void)visitor.mainAcceptEdit(nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("const", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Const::constifyAll(AstNetlist* nodep) {
// Only call from Verilator.cpp, as it uses user#'s
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (ConstVisitor::PROC_V_EXPENSIVE);
(void)visitor.mainAcceptEdit(nodep);
{
ConstVisitor visitor (ConstVisitor::PROC_V_EXPENSIVE);
(void)visitor.mainAcceptEdit(nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("const", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -395,6 +395,8 @@ public:
void V3Coverage::coverage(AstNetlist* rootp) {
UINFO(2,__FUNCTION__<<": "<<endl);
CoverageVisitor visitor (rootp);
{
CoverageVisitor visitor (rootp);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("coverage", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -134,6 +134,8 @@ public:
void V3CoverageJoin::coverageJoin(AstNetlist* rootp) {
UINFO(2,__FUNCTION__<<": "<<endl);
CoverageJoinVisitor visitor (rootp);
{
CoverageJoinVisitor visitor (rootp);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("coveragejoin", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -378,7 +378,8 @@ private:
// members are still alive.
if ((classp = VN_CAST((*it), NodeClassDType))) {
bool cont = true;
for (AstMemberDType *memberp = classp->membersp(); memberp; memberp = VN_CAST(memberp->nextp(), MemberDType)) {
for (AstMemberDType *memberp = classp->membersp();
memberp; memberp = VN_CAST(memberp->nextp(), MemberDType)) {
if (memberp->user1() != 0) {
cont = false;
break;
@ -425,30 +426,40 @@ public:
void V3Dead::deadifyModules(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, false, false, false, false);
{
DeadVisitor visitor (nodep, false, false, false, false);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("deadModules", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
void V3Dead::deadifyDTypes(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, false, true, false, false);
{
DeadVisitor visitor (nodep, false, true, false, false);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("deadDtypes", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Dead::deadifyDTypesScoped(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, false, true, true, false);
{
DeadVisitor visitor (nodep, false, true, true, false);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("deadDtypesScoped", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Dead::deadifyAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, true, true, false, true);
{
DeadVisitor visitor (nodep, true, true, false, true);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("deadAll", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Dead::deadifyAllScoped(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, true, true, true, true);
{
DeadVisitor visitor (nodep, true, true, true, true);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("deadAllScoped", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -115,7 +115,8 @@ private:
//UINFO(4," MVU "<<flags<<" "<<nodep<<endl);
nodep->user5( nodep->user5() | flags );
if ((nodep->user5() & VU_DLY) && (nodep->user5() & VU_NONDLY)) {
nodep->v3warn(BLKANDNBLK,"Unsupported: Blocked and non-blocking assignments to same variable: "<<nodep->varp()->prettyName());
nodep->v3warn(BLKANDNBLK,"Unsupported: Blocked and non-blocking assignments to same variable: "
<<nodep->varp()->prettyName());
}
}
AstVarScope* createVarSc(AstVarScope* oldvarscp, string name, int width/*0==fromoldvar*/, AstNodeDType* newdtypep) {
@ -158,7 +159,8 @@ private:
if (oldactivep->sensesp() != m_activep->sensesp()) {
if (!varrefp->varp()->fileline()->warnIsOff(V3ErrorCode::MULTIDRIVEN)
&& !varrefp->varp()->user2()) {
varrefp->varp()->v3warn(MULTIDRIVEN,"Signal has multiple driving blocks with different clocking: "<<varrefp->varp()->prettyName()<<endl
varrefp->varp()->v3warn(MULTIDRIVEN,"Signal has multiple driving blocks with different clocking: "
<<varrefp->varp()->prettyName()<<endl
<<varrefp->warnMore()<<"... Location of first driving block"<<endl
<<oldactivep->warnMore()<<"... Location of other driving block");
varrefp->varp()->user2(true);
@ -195,8 +197,9 @@ private:
arrayselp = VN_CAST(lhsp, ArraySel);
}
if (!arrayselp) nodep->v3fatalSrc("No arraysel under bitsel?");
if (VN_IS(arrayselp->dtypep()->skipRefp(), UnpackArrayDType)) nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
if (VN_IS(arrayselp->dtypep()->skipRefp(), UnpackArrayDType)) {
nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
}
UINFO(4,"AssignDlyArray: "<<nodep<<endl);
//
//=== Dimensions: __Vdlyvdim__
@ -391,7 +394,9 @@ private:
UINFO(4,"AssignDlyVar: "<<nodep<<endl);
markVarUsage(nodep->varScopep(), VU_DLY);
if (!m_activep) nodep->v3fatalSrc("<= not under sensitivity block");
if (!m_activep->hasClocked()) nodep->v3error("Internal: Blocking <= assignment in non-clocked block, should have converted in V3Active");
if (!m_activep->hasClocked()) {
nodep->v3error("Internal: Blocking <= assignment in non-clocked block, should have converted in V3Active");
}
AstVarScope* oldvscp = nodep->varScopep();
if (!oldvscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp");
AstVarScope* dlyvscp = VN_CAST(oldvscp->user1p(), VarScope);
@ -470,6 +475,8 @@ public:
void V3Delayed::delayedAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DelayedVisitor visitor (nodep);
{
DelayedVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("delayed", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -174,6 +174,8 @@ public:
void V3Depth::depthAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DepthVisitor visitor (nodep);
{
DepthVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("depth", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}

View File

@ -139,6 +139,8 @@ public:
void V3DepthBlock::depthBlockAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DepthBlockVisitor visitor (nodep);
{
DepthBlockVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("deepblock", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -311,6 +311,8 @@ public:
void V3Descope::descopeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DescopeVisitor visitor (nodep);
{
DescopeVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("descope", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -376,6 +376,11 @@ public:
puts(")); }\n");
}
}
virtual void visit(AstSysFuncAsTask* nodep) {
if (!nodep->lhsp()->isWide()) puts("(void)");
nodep->lhsp()->iterateAndNext(*this);
if (!nodep->lhsp()->isWide()) puts(";");
}
virtual void visit(AstSystemT* nodep) {
puts("(void)VL_SYSTEM_I");
emitIQW(nodep->lhsp());
@ -509,31 +514,36 @@ public:
}
virtual void visit(AstMulS* nodep) {
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
nodep->v3error("Unsupported: Signed multiply of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
nodep->v3error("Unsupported: Signed multiply of "<<nodep->width()
<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
}
visit(VN_CAST(nodep, NodeBiop));
}
virtual void visit(AstPow* nodep) {
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
nodep->v3error("Unsupported: Power of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
nodep->v3error("Unsupported: Power of "<<nodep->width()
<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
}
visit(VN_CAST(nodep, NodeBiop));
}
virtual void visit(AstPowSS* nodep) {
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
nodep->v3error("Unsupported: Power of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
nodep->v3error("Unsupported: Power of "<<nodep->width()
<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
}
visit(VN_CAST(nodep, NodeBiop));
}
virtual void visit(AstPowSU* nodep) {
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
nodep->v3error("Unsupported: Power of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
nodep->v3error("Unsupported: Power of "<<nodep->width()
<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
}
visit(VN_CAST(nodep, NodeBiop));
}
virtual void visit(AstPowUS* nodep) {
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
nodep->v3error("Unsupported: Power of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
nodep->v3error("Unsupported: Power of "<<nodep->width()
<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
}
visit(VN_CAST(nodep, NodeBiop));
}
@ -978,6 +988,7 @@ class EmitCImp : EmitCStmts {
// High level
void emitImp(AstNodeModule* modp);
void emitStaticDecl(AstNodeModule* modp);
void emitSettleLoop(std::string eval_call, bool initial);
void emitWrapEval(AstNodeModule* modp);
void emitInt(AstNodeModule* modp);
@ -1550,7 +1561,8 @@ void EmitCImp::emitCoverageImp(AstNodeModule* modp) {
puts("\n// Coverage\n");
// Rather than putting out VL_COVER_INSERT calls directly, we do it via this function
// This gets around gcc slowness constructing all of the template arguments.
puts("void "+modClassName(m_modp)+"::__vlCoverInsert(uint32_t* countp, bool enable, const char* filenamep, int lineno, int column,\n");
puts("void "+modClassName(m_modp)+"::__vlCoverInsert(uint32_t* countp, bool enable,"
" const char* filenamep, int lineno, int column,\n");
puts( "const char* hierp, const char* pagep, const char* commentp) {\n");
puts( "static uint32_t fake_zero_count = 0;\n"); // static doesn't need save-restore as constant
puts( "if (!enable) countp = &fake_zero_count;\n"); // Used for second++ instantiation of identical bin
@ -1729,6 +1741,29 @@ void EmitCImp::emitSensitives() {
}
}
void EmitCImp::emitSettleLoop(std::string eval_call, bool initial) {
putsDecoration("// Evaluate till stable\n");
puts("int __VclockLoop = 0;\n");
puts("QData __Vchange = 1;\n");
puts("do {\n");
puts( eval_call + "\n");
puts( "if (VL_UNLIKELY(++__VclockLoop > "+cvtToStr(v3Global.opt.convergeLimit())
+")) {\n");
puts( "// About to fail, so enable debug to see what's not settling.\n");
puts( "// Note you must run make with OPT=-DVL_DEBUG for debug prints.\n");
puts( "int __Vsaved_debug = Verilated::debug();\n");
puts( "Verilated::debug(1);\n");
puts( "__Vchange = _change_request(vlSymsp);\n");
puts( "Verilated::debug(__Vsaved_debug);\n");
puts( "VL_FATAL_MT(__FILE__,__LINE__,__FILE__,\"Verilated model didn't ");
if (initial) puts ("DC ");
puts( "converge\");\n");
puts( "} else {\n");
puts( "__Vchange = _change_request(vlSymsp);\n");
puts( "}\n");
puts("} while (VL_UNLIKELY(__Vchange));\n");
}
void EmitCImp::emitWrapEval(AstNodeModule* modp) {
puts("\nvoid "+modClassName(modp)+"::eval() {\n");
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+++++TOP Evaluate "+modClassName(modp)+"::eval\\n\"); );\n");
@ -1750,20 +1785,10 @@ void EmitCImp::emitWrapEval(AstNodeModule* modp) {
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"Train starting, trainId="+cvtToStr(trainId)+"\\n\"););\n");
puts("Verilated::trainId("+cvtToStr(trainId)+");\n");
}
putsDecoration("// Evaluate till stable\n");
puts("int __VclockLoop = 0;\n");
puts("QData __Vchange = 1;\n");
puts("while (VL_LIKELY(__Vchange)) {\n");
puts( "VL_DEBUG_IF(VL_DBG_MSGF(\"+ Clock loop\\n\"););\n");
if (v3Global.opt.trace()) {
puts("vlSymsp->__Vm_activity = true;\n");
}
puts( "_eval(vlSymsp);\n");
puts( "__Vchange = _change_request(vlSymsp);\n");
puts( "if (VL_UNLIKELY(++__VclockLoop > "+cvtToStr(v3Global.opt.convergeLimit())
+")) VL_FATAL_MT(__FILE__,__LINE__,__FILE__,\"Verilated model didn't converge\");\n");
puts("}\n");
emitSettleLoop(
(string("VL_DEBUG_IF(VL_DBG_MSGF(\"+ Clock loop\\n\"););\n")
+ (v3Global.opt.trace() ? "vlSymsp->__Vm_activity = true;\n" : "")
+ "_eval(vlSymsp);"), false);
if (v3Global.opt.threads()) { // THREADED-TODO move to end of all trains on thread
puts("Verilated::endOfThreadTrain(vlSymsp->__Vm_evalMsgQp);\n");
}
@ -1780,15 +1805,8 @@ void EmitCImp::emitWrapEval(AstNodeModule* modp) {
if (v3Global.opt.trace()) {
puts("vlSymsp->__Vm_activity = true;\n");
}
puts( "int __VclockLoop = 0;\n");
puts( "QData __Vchange = 1;\n");
puts( "while (VL_LIKELY(__Vchange)) {\n");
puts( "_eval_settle(vlSymsp);\n");
puts( "_eval(vlSymsp);\n");
puts( "__Vchange = _change_request(vlSymsp);\n");
puts( "if (VL_UNLIKELY(++__VclockLoop > "+cvtToStr(v3Global.opt.convergeLimit())
+")) VL_FATAL_MT(__FILE__,__LINE__,__FILE__,\"Verilated model didn't DC converge\");\n");
puts( "}\n");
emitSettleLoop((string("_eval_settle(vlSymsp);\n")
+"_eval(vlSymsp);"), true);
puts("}\n");
splitSizeInc(10);
}
@ -2296,8 +2314,9 @@ class EmitCTrace : EmitCStmts {
putsDecoration("// Callback from vcd->open()\n");
puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n");
puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n");
puts("if (!Verilated::calcUnusedSigs()) VL_FATAL_MT(__FILE__,__LINE__,__FILE__,\"Turning on wave traces requires Verilated::traceEverOn(true) call before time 0.\");\n");
puts("if (!Verilated::calcUnusedSigs()) {\n");
puts( "VL_FATAL_MT(__FILE__,__LINE__,__FILE__,\"Turning on wave traces requires Verilated::traceEverOn(true) call before time 0.\");\n");
puts("}\n");
puts("vcdp->scopeEscape(' ');\n");
puts("t->traceInitThis(vlSymsp, vcdp, code);\n");
puts("vcdp->scopeEscape('.');\n"); // Restore so later traced files won't break

View File

@ -103,7 +103,8 @@ 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->prettyName()<<"'");
nodep->v3error("Symbol matching "+rsvd+" reserved word reached emitter,"
" should have hit SYMRSVDWORD: '"<<nodep->prettyName()<<"'");
}
}
}

View File

@ -278,6 +278,10 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
if (nodep->msbp()) { putbs(","); nodep->msbp()->iterateAndNext(*this); }
puts(");\n");
}
virtual void visit(AstSysFuncAsTask* nodep) {
nodep->lhsp()->iterateAndNext(*this);
puts(";\n");
}
virtual void visit(AstSysIgnore* nodep) {
putfs(nodep,nodep->verilogKwd());
putbs(" (");

View File

@ -266,8 +266,11 @@ inline void v3errorEndFatal(std::ostringstream& sstr) { V3Error::v3errorEnd(sstr
// Careful, you can't put () around msg, as you would in most macro definitions
// Note the commas are the comma operator, not separating arguments. These are needed to insure
// evaluation order as otherwise we couldn't insure v3errorPrep is called first.
#define v3warnCode(code,msg) v3errorEnd((V3Error::v3errorPrep(code), (V3Error::v3errorStr()<<msg), V3Error::v3errorStr()));
#define v3warnCodeFatal(code,msg) v3errorEndFatal((V3Error::v3errorPrep(code), (V3Error::v3errorStr()<<msg), V3Error::v3errorStr()));
#define v3warnCode(code,msg) \
v3errorEnd((V3Error::v3errorPrep(code), (V3Error::v3errorStr()<<msg), V3Error::v3errorStr()));
#define v3warnCodeFatal(code,msg) \
v3errorEndFatal((V3Error::v3errorPrep(code), (V3Error::v3errorStr()<<msg), \
V3Error::v3errorStr()));
#define v3warn(code,msg) v3warnCode(V3ErrorCode::code, msg)
#define v3info(msg) v3warnCode(V3ErrorCode::EC_INFO, msg)
#define v3error(msg) v3warnCode(V3ErrorCode::EC_ERROR, msg)
@ -286,7 +289,9 @@ inline void v3errorEndFatal(std::ostringstream& sstr) { V3Error::v3errorEnd(sstr
#define UASSERT(condition,stmsg) { if (VL_UNLIKELY(!(condition))) { v3fatalSrc(stmsg); }}
// For use in V3Ast static functions only
#define UASSERT_STATIC(condition,stmsg) { if (VL_UNLIKELY(!(condition))) { std::cerr<<"Internal Error: "<<__FILE__<<":"<<std::dec<<__LINE__<<":"<<(stmsg)<<std::endl; abort(); } }
#define UASSERT_STATIC(condition,stmsg) \
{ if (VL_UNLIKELY(!(condition))) { \
std::cerr<<"Internal Error: "<<__FILE__<<":"<<std::dec<<__LINE__<<":"<<(stmsg)<<std::endl; abort(); } }
#define V3ERROR_NA { v3error("Internal: Unexpected Call"); v3fatalSrc("Unexpected Call"); }

View File

@ -243,7 +243,9 @@ private:
}
bool expandWide (AstNodeAssign* nodep, AstArraySel* rhsp) {
UINFO(8," Wordize ASSIGN(ARRAYSEL) "<<nodep<<endl);
if (VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)) nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
if (VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)) {
nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
}
for (int w=0; w<nodep->widthWords(); w++) {
addWordAssign(nodep, w, newAstWordSelClone (rhsp, w));
}
@ -936,6 +938,8 @@ public:
void V3Expand::expandAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ExpandVisitor visitor (nodep);
{
ExpandVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("expand", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -238,7 +238,8 @@ inline bool V3FileDependImp::checkTimes(const string& filename, const string& cm
UINFO(2," --check-times failed: missing "<<chkFilename<<endl);
return false;
}
//UINFO(9," got d="<<chkDir<<" s="<<chkSize<<" ct="<<chkCstime<<"."<<chkCnstime<<" mt="<<chkMstime<<"."<<chkMnstime<<" fn = "<<chkFilename<<endl);
//UINFO(9," got d="<<chkDir<<" s="<<chkSize<<" ct="<<chkCstime<<"."
// <<chkCnstime<<" mt="<<chkMstime<<"."<<chkMnstime<<" fn = "<<chkFilename<<endl);
//UINFO(9," nowSt s="<<chkStat.st_size<<" mt="<<chkStat.st_mtime<<" ct="<<chkStat.st_ctime<<" fn = "<<chkFilename<<endl);
if (filename != chkFilename) { // Other then the .dat file itself, as we were writing it at the time...
// We'd like this rule:

View File

@ -1496,7 +1496,9 @@ public:
void V3Gate::gateAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
GateVisitor visitor (nodep);
GateDeassignVisitor deassign (nodep);
{
GateVisitor visitor (nodep);
GateDeassignVisitor deassign (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("gate", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -242,6 +242,8 @@ public:
void V3GenClk::genClkAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
GenClkReadVisitor visitor (nodep);
{
GenClkReadVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("genclk", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -545,7 +545,8 @@ public:
// Important to add statement next to cell, in case there is a generate with same named cell
cellp->addNextHere(newvarp);
if (pinVarp->isInout()) {
pinVarp->v3fatalSrc("Unsupported: Inout connections to pins must be direct one-to-one connection (without any expression)");
pinVarp->v3fatalSrc("Unsupported: Inout connections to pins must be"
" direct one-to-one connection (without any expression)");
} else if (pinVarp->isOutput()) {
// See also V3Inst
AstNode* rhsp = new AstVarRef(pinp->fileline(), newvarp, false);
@ -582,12 +583,16 @@ AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModu
void V3Inst::instAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
InstVisitor visitor (nodep);
{
InstVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("inst", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Inst::dearrayAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
InstDeVisitor visitor (nodep);
{
InstDeVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("dearray", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}

View File

@ -518,7 +518,9 @@ public:
void V3Life::lifeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
LifeState state;
LifeTopVisitor visitor (nodep, &state);
{
LifeState state;
LifeTopVisitor visitor (nodep, &state);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("life", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -228,6 +228,8 @@ public:
void V3LifePost::lifepostAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
// Mark redundant AssignPost
LifePostDlyVisitor visitor (nodep);
{
LifePostDlyVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("life_post", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -413,7 +413,9 @@ private:
idtypep->cellp(nodep); // Only set when real parent cell known.
AstVar* varp;
if (nodep->rangep()) {
AstNodeArrayDType* arrp = new AstUnpackArrayDType(nodep->fileline(),VFlagChildDType(), idtypep, nodep->rangep()->cloneTree(true));
AstNodeArrayDType* arrp
= new AstUnpackArrayDType(nodep->fileline(), VFlagChildDType(),
idtypep, nodep->rangep()->cloneTree(true));
varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName,
VFlagChildDType(), arrp);
} else {

View File

@ -262,7 +262,8 @@ public:
AstCell* nodep, const string& scopename) {
if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node");
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
UINFO(9," INSERTcel se"<<(void*)symp<<" "<<scopename<<" above=se"<<(void*)abovep<<" mods=se"<<(void*)modSymp<<" node="<<nodep<<endl);
UINFO(9," INSERTcel se"<<(void*)symp<<" "<<scopename<<" above=se"<<(void*)abovep
<<" mods=se"<<(void*)modSymp<<" node="<<nodep<<endl);
symp->parentp(abovep);
symp->fallbackp(dunitEntp()); // Needed so can find $unit stuff
nodep->user1p(symp);
@ -283,7 +284,8 @@ public:
// This refrences to another Sym, and eventually resolves to a module with a prefix
if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node");
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
UINFO(9," INSERTinl se"<<(void*)symp<<" "<<basename<<" above=se"<<(void*)abovep<<" mods=se"<<(void*)modSymp<<" node="<<nodep<<endl);
UINFO(9," INSERTinl se"<<(void*)symp<<" "<<basename<<" above=se"<<(void*)abovep
<<" mods=se"<<(void*)modSymp<<" node="<<nodep<<endl);
symp->parentp(abovep);
symp->fallbackp(modSymp);
symp->symPrefix(nodep->name()+"__DOT__");
@ -1551,7 +1553,8 @@ private:
inline void checkNoDot(AstNode* nodep) {
if (VL_UNLIKELY(m_ds.m_dotPos != DP_NONE)) {
//UINFO(9,"ds="<<m_ds.ascii()<<endl);
nodep->v3error("Syntax Error: Not expecting "<<nodep->type()<<" under a "<<nodep->backp()->type()<<" in dotted expression");
nodep->v3error("Syntax Error: Not expecting "<<nodep->type()<<" under a "
<<nodep->backp()->type()<<" in dotted expression");
m_ds.m_dotErr = true;
}
}
@ -1815,7 +1818,8 @@ private:
AstCell* cellp = VN_CAST(foundp->nodep(), Cell);
if (VN_IS(cellp->modp(), Iface)) {
// Interfaces can be referenced like a variable for interconnect
VSymEnt* cellEntp = m_statep->getNodeSym(cellp); if (!cellEntp) nodep->v3fatalSrc("No interface sym entry");
VSymEnt* cellEntp = m_statep->getNodeSym(cellp);
if (!cellEntp) nodep->v3fatalSrc("No interface sym entry");
VSymEnt* parentEntp = cellEntp->parentp(); // Container of the var; probably a module or generate begin
string findName = nodep->name()+"__Viftop";
VSymEnt* ifaceSymp = parentEntp->findIdFallback(findName);
@ -2011,7 +2015,8 @@ private:
VSymEnt* foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot);
AstVarScope* vscp = foundp ? VN_CAST(foundp->nodep(), VarScope) : NULL;
if (!vscp) {
nodep->v3error("Can't find varpin scope of '"<<baddot<<"' in dotted signal: "<<nodep->dotted()+"."+nodep->prettyName());
nodep->v3error("Can't find varpin scope of '"<<baddot
<<"' in dotted signal: "<<nodep->dotted()+"."+nodep->prettyName());
okSymp->cellErrorScopes(nodep);
} else {
while (vscp->user2p()) { // If V3Inline aliased it, pick up the new signal
@ -2126,7 +2131,8 @@ private:
} else if (nodep->dotted() == "") {
nodep->v3error("Can't find definition of task/function: "<<nodep->prettyName());
} else {
nodep->v3error("Can't find definition of '"<<baddot<<"' in dotted task/function: "<<nodep->dotted()+"."+nodep->prettyName());
nodep->v3error("Can't find definition of '"<<baddot
<<"' in dotted task/function: "<<nodep->dotted()+"."+nodep->prettyName());
okSymp->cellErrorScopes(nodep);
}
}
@ -2314,21 +2320,29 @@ public:
int V3LinkDot::debug() { return LinkDotState::debug(); }
void V3LinkDot::linkDotGuts(AstNetlist* rootp, VLinkDotStep step) {
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot.tree"));
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) {
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot.tree"));
}
LinkDotState state (rootp, step);
LinkDotFindVisitor visitor(rootp,&state);
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-find.tree"));
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) {
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-find.tree"));
}
if (step == LDS_PRIMARY || step == LDS_PARAMED) {
// Initial link stage, resolve parameters
LinkDotParamVisitor visitors(rootp,&state);
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-param.tree"));
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) {
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-param.tree"));
}
}
else if (step == LDS_ARRAYED) {}
else if (step == LDS_SCOPED) {
// Well after the initial link when we're ready to operate on the flat design,
// process AstScope's. This needs to be separate pass after whole hierarchy graph created.
LinkDotScopeVisitor visitors(rootp,&state);
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-scoped.tree"));
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) {
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-scoped.tree"));
}
}
else v3fatalSrc("Bad case");
state.dump();

View File

@ -35,19 +35,23 @@ private:
static void linkDotGuts(AstNetlist* nodep, VLinkDotStep step);
public:
static void linkDotPrimary(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_PRIMARY);
UINFO(2,__FUNCTION__<<": "<<endl);
linkDotGuts(nodep,LDS_PRIMARY);
V3Global::dumpCheckGlobalTree("linkdot", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
static void linkDotParamed(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_PARAMED);
UINFO(2,__FUNCTION__<<": "<<endl);
linkDotGuts(nodep,LDS_PARAMED);
V3Global::dumpCheckGlobalTree("paramlink", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
static void linkDotArrayed(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_ARRAYED);
UINFO(2,__FUNCTION__<<": "<<endl);
linkDotGuts(nodep,LDS_ARRAYED);
V3Global::dumpCheckGlobalTree("linkdot", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
static void linkDotScope(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_SCOPED);
UINFO(2,__FUNCTION__<<": "<<endl);
linkDotGuts(nodep,LDS_SCOPED);
V3Global::dumpCheckGlobalTree("linkdot", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
};

View File

@ -262,6 +262,8 @@ public:
void V3LinkJump::linkJump(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
LinkJumpVisitor bvisitor (nodep);
{
LinkJumpVisitor bvisitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("link", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -278,7 +278,9 @@ public:
void V3LinkLValue::linkLValue(AstNetlist* rootp) {
UINFO(4,__FUNCTION__<<": "<<endl);
LinkLValueVisitor visitor(rootp, false);
{
LinkLValueVisitor visitor(rootp, false);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("linklvalue", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
void V3LinkLValue::linkLValueSet(AstNode* nodep) {

View File

@ -430,6 +430,8 @@ public:
void V3LinkParse::linkParse(AstNetlist* rootp) {
UINFO(4,__FUNCTION__<<": "<<endl);
LinkParseVisitor visitor(rootp);
{
LinkParseVisitor visitor(rootp);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("linkparse", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}

View File

@ -515,7 +515,9 @@ public:
void V3LinkResolve::linkResolve(AstNetlist* rootp) {
UINFO(4,__FUNCTION__<<": "<<endl);
LinkResolveVisitor visitor(rootp);
LinkBotupVisitor visitorb(rootp);
{
LinkResolveVisitor visitor(rootp);
LinkBotupVisitor visitorb(rootp);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("linkresolve", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}

View File

@ -248,8 +248,10 @@ public:
void V3Localize::localizeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
LocalizeVisitor visitor (nodep);
// Fix up hiernames
LocalizeDehierVisitor dvisitor (nodep);
{
LocalizeVisitor visitor (nodep);
// Fix up hiernames
LocalizeDehierVisitor dvisitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("localize", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}

View File

@ -148,6 +148,8 @@ public:
void V3Name::nameAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
NameVisitor visitor (nodep);
{
NameVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("name", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}

View File

@ -659,6 +659,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if ( onoff (sw, "-covsp", flag/*ref*/) ) { } // TBD
else if ( !strcmp (sw, "-debug-abort") ) { abort(); } // Undocumented, see also --debug-sigsegv
else if ( onoff (sw, "-debug-check", flag/*ref*/) ){ m_debugCheck = flag; }
else if ( onoff (sw, "-debug-leak", flag/*ref*/) ){ m_debugLeak = flag; }
else if ( !strcmp (sw, "-debug-sigsegv") ) { throwSigsegv(); } // Undocumented, see also --debug-abort
else if ( !strcmp (sw, "-debug-fatalsrc") ) { v3fatalSrc("--debug-fatal-src"); } // Undocumented, see also --debug-abort
else if ( onoff (sw, "-decoration", flag/*ref*/) ) { m_decoration = flag; }
@ -1218,6 +1219,7 @@ V3Options::V3Options() {
m_coverageUnderscore = false;
m_coverageUser = false;
m_debugCheck = false;
m_debugLeak = true;
m_decoration = true;
m_exe = false;
m_ignc = false;

View File

@ -75,6 +75,7 @@ class V3Options {
bool m_coverageUnderscore;// main switch: --coverage-underscore
bool m_coverageUser; // main switch: --coverage-func
bool m_debugCheck; // main switch: --debug-check
bool m_debugLeak; // main switch: --debug-leak
bool m_decoration; // main switch: --decoration
bool m_exe; // main switch: --exe
bool m_ignc; // main switch: --ignc
@ -229,6 +230,7 @@ class V3Options {
bool coverageUnderscore() const { return m_coverageUnderscore; }
bool coverageUser() const { return m_coverageUser; }
bool debugCheck() const { return m_debugCheck; }
bool debugLeak() const { return m_debugLeak; }
bool decoration() const { return m_decoration; }
bool exe() const { return m_exe; }
bool trace() const { return m_trace; }

View File

@ -1566,14 +1566,16 @@ void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* d
processMoveDoneOne (vertexp);
}
inline void OrderMoveDomScope::ready(OrderVisitor* ovp) { // Check the domScope is on ready list, add if not
// Check the domScope is on ready list, add if not
inline void OrderMoveDomScope::ready(OrderVisitor* ovp) {
if (!m_onReadyList) {
m_onReadyList = true;
m_readyDomScopeE.pushBack(ovp->m_pomReadyDomScope, this);
}
}
inline void OrderMoveDomScope::movedVertex(OrderVisitor* ovp, OrderMoveVertex* vertexp) { // Mark one vertex as finished, remove from ready list if done
// Mark one vertex as finished, remove from ready list if done
inline void OrderMoveDomScope::movedVertex(OrderVisitor* ovp, OrderMoveVertex* vertexp) {
UASSERT(m_onReadyList, "Moving vertex from ready when nothing was on que as ready.");
if (m_readyVertices.empty()) { // Else more work to get to later
m_onReadyList = false;
@ -1645,8 +1647,10 @@ void OrderVisitor::process() {
void V3Order::orderAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
OrderClkMarkVisitor markVisitor(nodep);
OrderVisitor visitor;
visitor.main(nodep);
{
OrderClkMarkVisitor markVisitor(nodep);
OrderVisitor visitor;
visitor.main(nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("order", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -38,7 +38,8 @@ public:
static string filenameFromDirBase (const string& dir, const string& basename);
static string filenameNonDir (const string& filename); ///< Return non-directory part of filename
static string filenameNonExt (const string& filename); ///< Return non-extensioned (no .) part of filename
static string filenameNonDirExt (const string& filename) { return filenameNonExt(filenameNonDir(filename)); } ///< Return basename of filename
static string filenameNonDirExt (const string& filename) { ///< Return basename of filename
return filenameNonExt(filenameNonDir(filename)); }
static string filenameDir (const string& filename); ///< Return directory part of filename
static string filenameSubstitute (const string& filename); ///< Return filename with env vars removed
static string filenameRealPath(const string& fn); ///< Return realpath of filename

View File

@ -782,6 +782,8 @@ void ParamVisitor::visitCell(AstCell* nodep) {
void V3Param::param(AstNetlist* rootp) {
UINFO(2,__FUNCTION__<<": "<<endl);
ParamVisitor visitor (rootp);
{
ParamVisitor visitor (rootp);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("param", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}

View File

@ -427,6 +427,8 @@ public:
void V3Premit::premitAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
PremitVisitor visitor (nodep);
{
PremitVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("premit", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -416,7 +416,9 @@ public:
void V3Scope::scopeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ScopeVisitor visitor (nodep);
ScopeCleanupVisitor cleanVisitor (nodep);
{
ScopeVisitor visitor (nodep);
ScopeCleanupVisitor cleanVisitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("scope", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -718,7 +718,9 @@ private:
nodep->bodysp()->iterateAndNext(*this);
nodep->incsp()->iterateAndNext(*this);
if (loops++ > unrollCount()*16) {
clearOptimizable(nodep, "Loop unrolling took too long; probably this is an infinite loop, or set --unroll-count above "+cvtToStr(unrollCount()));
clearOptimizable(nodep, "Loop unrolling took too long; probably this is an"
"infinite loop, or set --unroll-count above "
+ cvtToStr(unrollCount()));
break;
}
}
@ -752,7 +754,8 @@ private:
// Prep for next loop
if (loops++ > unrollCount()*16) {
clearOptimizable(nodep, "Loop unrolling took too long; probably this is an infinite loop, or set --unroll-count above "+cvtToStr(unrollCount()));
clearOptimizable(nodep, "Loop unrolling took too long; probably this is an infinite"
" loop, or set --unroll-count above "+cvtToStr(unrollCount()));
break;
}
}

View File

@ -74,7 +74,10 @@ class SliceVisitor : public AstNVisitor {
// Insert an ArraySel, except for a few special cases
AstUnpackArrayDType* arrayp = VN_CAST(nodep->dtypep()->skipRefp(), UnpackArrayDType);
if (!arrayp) { // V3Width should have complained, but...
if (!m_assignError) nodep->v3error(nodep->prettyTypeName()<<" is not an unpacked array, but is in an unpacked array context");
if (!m_assignError) {
nodep->v3error(nodep->prettyTypeName()
<<" is not an unpacked array, but is in an unpacked array context");
}
m_assignError = true;
return nodep->cloneTree(false); // Likely will cause downstream errors
}
@ -241,6 +244,8 @@ public:
void V3Slice::sliceAll(AstNetlist* rootp) {
UINFO(2,__FUNCTION__<<": "<<endl);
SliceVisitor visitor(rootp);
{
SliceVisitor visitor(rootp);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("slice", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -1024,11 +1024,15 @@ private:
void V3Split::splitReorderAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ReorderVisitor visitor (nodep);
{
ReorderVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("reorder", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Split::splitAlwaysAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
SplitVisitor visitor (nodep);
{
SplitVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("split", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -215,6 +215,8 @@ public:
void V3SplitAs::splitAsAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
SplitAsVisitor visitor (nodep);
{
SplitAsVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("splitas", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -400,6 +400,8 @@ public:
void V3Subst::substituteAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
SubstVisitor visitor (nodep);
{
SubstVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("subst", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -66,7 +66,8 @@ private:
static inline int debug() { return 0; } // NOT runtime, too hot of a function
#endif
public:
void dumpIterate(std::ostream& os, VSymConstMap& doneSymsr, const string& indent, int numLevels, const string& searchName) const {
void dumpIterate(std::ostream& os, VSymConstMap& doneSymsr, const string& indent,
int numLevels, const string& searchName) const {
os<<indent<<"+ "<<std::left<<std::setw(30)<<(searchName==""?"\"\"":searchName)<<std::setw(0)<<std::right;
os<<" se"<<(void*)(this)<<std::setw(0);
os<<" fallb=se"<<(void*)(m_fallbackp);

View File

@ -305,7 +305,10 @@ private:
// Simulate
simvis.mainTableEmulate(nodep);
if (!simvis.optimizable()) simvis.whyNotNodep()->v3fatalSrc("Optimizable cleared, even though earlier test run said not: "<<simvis.whyNotMessage());
if (!simvis.optimizable()) {
simvis.whyNotNodep()->v3fatalSrc("Optimizable cleared, even though earlier test run said not: "
<<simvis.whyNotMessage());
}
// If a output changed, add it to table
int outnum = 0;
@ -465,6 +468,8 @@ void TableSimulateVisitor::varRefCb(AstVarRef* nodep) {
void V3Table::tableAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
TableVisitor visitor (nodep);
{
TableVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("table", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -600,7 +600,8 @@ private:
bool bitvec = (portp->basicp()->keyword().isDpiBitVal() && portp->width() > 32);
bool logicvec = (portp->basicp()->keyword().isDpiLogicVal() && portp->width() > 1);
if (isRtn && (bitvec || logicvec)) {
portp->v3error("DPI functions cannot return > 32 bits or four-state; use a two-state type or task instead: "<<portp->prettyName());
portp->v3error("DPI functions cannot return > 32 bits or four-state;"
" use a two-state type or task instead: "<<portp->prettyName());
// Code below works, but won't compile right, and IEEE illegal
}
string stmt;
@ -1395,7 +1396,9 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
void V3Task::taskAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
TaskStateVisitor visitors (nodep);
TaskVisitor visitor (nodep, &visitors);
{
TaskStateVisitor visitors (nodep);
TaskVisitor visitor (nodep, &visitors);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("task", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -36,7 +36,8 @@ typedef std::vector<V3TaskConnect> V3TaskConnects; // [ [port, pin-connects-to]
class V3Task {
public:
static void taskAll(AstNetlist* nodep);
static V3TaskConnects taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp); // Return vector of [port, pin-connects-to] (SLOW)
/// Return vector of [port, pin-connects-to] (SLOW)
static V3TaskConnects taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp);
};
#endif // Guard

View File

@ -205,7 +205,10 @@ private:
if (TraceTraceVertex* vvertexp = dynamic_cast<TraceTraceVertex*>(itp)) {
AstTraceInc* nodep = vvertexp->nodep();
if (nodep->valuep()) {
if (nodep->valuep()->backp() != nodep) nodep->v3fatalSrc("Trace duplicate back needs consistency, so we can map duplicates back to TRACEINCs");
if (nodep->valuep()->backp() != nodep) {
nodep->v3fatalSrc("Trace duplicate back needs consistency,"
" so we can map duplicates back to TRACEINCs");
}
hashed.hash(nodep->valuep());
UINFO(8, " Hashed "<<std::hex<<hashed.nodeHash(nodep->valuep())<<" "<<nodep<<endl);
@ -712,6 +715,8 @@ public:
void V3Trace::traceAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
TraceVisitor visitor (nodep);
{
TraceVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("trace", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -325,6 +325,8 @@ public:
void V3TraceDecl::traceDeclAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
TraceDeclVisitor visitor (nodep);
{
TraceDeclVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("tracedecl", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -221,7 +221,8 @@ public:
TristateVertex* vvertexp = static_cast<TristateVertex*>(itp);
if (vvertexp->isTristate() && !vvertexp->processed()) {
// Not v3errorSrc as no reason to stop the world
vvertexp->nodep()->v3error("Unsupported tristate construct (in graph; not converted): "<<vvertexp->nodep()->prettyTypeName());
vvertexp->nodep()->v3error("Unsupported tristate construct"
" (in graph; not converted): "<<vvertexp->nodep()->prettyTypeName());
}
}
m_graph.clear();
@ -1341,6 +1342,8 @@ public:
void V3Tristate::tristateAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
TristateVisitor visitor (nodep);
{
TristateVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("tristate", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -479,6 +479,8 @@ public:
void V3Unknown::unknownAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
UnknownVisitor visitor (nodep);
{
UnknownVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("unknown", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -185,10 +185,11 @@ private:
}
bool canSimulate(AstNode *nodep) {
SimulateVisitor simvis;
AstNode* clone = nodep->cloneTree(true);
simvis.mainCheckTree(clone);
return simvis.optimizable();
SimulateVisitor simvis;
AstNode* clonep = nodep->cloneTree(true);
simvis.mainCheckTree(clonep);
pushDeletep(clonep); clonep = NULL;
return simvis.optimizable();
}
bool simulateTree(AstNode *nodep, const V3Number *loopValue, AstNode *dtypep, V3Number &outNum) {
@ -333,7 +334,9 @@ private:
++m_statIters;
if (++times > unrollCount()*3) {
nodep->v3error("Loop unrolling took too long; probably this is an infinite loop, or set --unroll-count above "<<unrollCount());
nodep->v3error("Loop unrolling took too long;"
" probably this is an infinite loop, or set --unroll-count above "
<<unrollCount());
break;
}
@ -477,7 +480,9 @@ public:
void V3Unroll::unrollAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
UnrollVisitor visitor (nodep, false, "");
{
UnrollVisitor visitor (nodep, false, "");
} // Destruct before checking
V3Global::dumpCheckGlobalTree("unroll", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -31,11 +31,11 @@
// widthSized() = true if all constants sized, else false
// Compute size of this expression
// Lint warn about mismatches
// If expr size != subop fixed, bad
// If expr size < subop unsized minimum, bad
// If expr size != subop, edit netlist
// For == and similar ops, if multibit underneath, add a REDOR
// If subop larger, add a EXTRACT
// If expr size != subop fixed, bad
// If expr size < subop unsized minimum, bad
// If expr size != subop, edit netlist
// For == and similar ops, if multibit underneath, add a REDOR
// If subop larger, add a EXTRACT
// If subop smaller, add a EXTEND
// Pass size to sub-expressions if required (+/-* etc)
// FINAL = true.
@ -48,16 +48,16 @@
// Comparison results are unsigned
// Bit&Part selects are unsigned, even if whole
// Concatenates are unsigned
// Ignore signedness of self-determined:
// shift rhs, ** rhs, x?: lhs, concat and replicate members
// Ignore signedness of self-determined:
// shift rhs, ** rhs, x?: lhs, concat and replicate members
// Else, if any operand unsigned, output unsigned
//
// Real number rules:
// Real numbers are real (duh)
// Reals convert to integers by rounding
// Reals init to 0.0
// Logicals convert compared to zero
// If any operand is real, result is real
// Logicals convert compared to zero
// If any operand is real, result is real
//*************************************************************************
// V3Width is the only visitor that uses vup. We could switch to using userp,
// though note some iterators operate on next() and so would need to pass the
@ -1199,7 +1199,9 @@ private:
if (nodep->valuep()->dtypep()->widthSized()) {
width = nodep->valuep()->width();
} else {
if (nodep->valuep()->width()>32) nodep->valuep()->v3warn(WIDTH,"Assigning >32 bit to unranged parameter (defaults to 32 bits)");
if (nodep->valuep()->width()>32) {
nodep->valuep()->v3warn(WIDTH,"Assigning >32 bit to unranged parameter (defaults to 32 bits)");
}
width = 32;
}
// Can't just inherit valuep()->dtypep() as mwidth might not equal width
@ -1244,7 +1246,8 @@ private:
if (nodep->didWidth()) return;
if (!nodep->varp()) {
if (m_paramsOnly && VN_IS(nodep, VarXRef)) {
checkConstantOrReplace(nodep, "Parameter-resolved constants must not use dotted references: "+nodep->prettyName()); VL_DANGLING(nodep);
checkConstantOrReplace(nodep, "Parameter-resolved constants must not use dotted references: "
+nodep->prettyName()); VL_DANGLING(nodep);
return;
} else {
nodep->v3fatalSrc("Unlinked varref");
@ -1493,13 +1496,15 @@ private:
} else {
AstSel* newp = new AstSel(nodep->fileline(), nodep->fromp()->unlinkFrBack(),
memberp->lsb(), memberp->width());
newp->dtypep(memberp->subDTypep()->skipRefToEnump()); // Must skip over the member to find the union; as the member may disappear later
// Must skip over the member to find the union; as the member may disappear later
newp->dtypep(memberp->subDTypep()->skipRefToEnump());
newp->didWidth(true); // Don't replace dtype with basic type
UINFO(9," MEMBERSEL -> "<<newp<<endl);
UINFO(9," dt-> "<<newp->dtypep()<<endl);
nodep->replaceWith(newp);
pushDeletep(nodep); VL_DANGLING(nodep);
// Should be able to treat it as a normal-ish nodesel - maybe. The lhsp() will be strange until this stage; create the number here?
// Should be able to treat it as a normal-ish nodesel - maybe.
// The lhsp() will be strange until this stage; create the number here?
}
}
if (!memberp) { // Very bogus, but avoids core dump
@ -1661,7 +1666,9 @@ private:
nodep->dtypep(m_vup->dtypep());
}
AstNodeDType* vdtypep = nodep->dtypep();
if (!vdtypep) nodep->v3error("Unsupported/Illegal: Assignment pattern member not underneath a supported construct: "<<nodep->backp()->prettyTypeName());
if (!vdtypep) nodep->v3error("Unsupported/Illegal: Assignment pattern"
" member not underneath a supported construct: "
<<nodep->backp()->prettyTypeName());
{
vdtypep = vdtypep->skipRefp();
nodep->dtypep(vdtypep);
@ -1721,7 +1728,8 @@ private:
continue;
}
} else {
patp->keyp()->v3error("Assignment pattern key not supported/understood: "<<patp->keyp()->prettyTypeName());
patp->keyp()->v3error("Assignment pattern key not"
" supported/understood: "<<patp->keyp()->prettyTypeName());
}
}
}
@ -1733,7 +1741,8 @@ private:
} else {
std::pair<PatMap::iterator, bool> ret = patmap.insert(make_pair(memp, patp));
if (!ret.second) {
patp->v3error("Assignment pattern contains duplicate entry: " << VN_CAST(patp->keyp(), Text)->text());
patp->v3error("Assignment pattern contains duplicate entry: "
<< VN_CAST(patp->keyp(), Text)->text());
}
}
// Next
@ -2189,6 +2198,10 @@ private:
nodep->dtypeSetSigned32(); // Spec says integer return
}
}
virtual void visit(AstSysFuncAsTask* nodep) {
assertAtStatement(nodep);
userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p());
}
virtual void visit(AstSystemT* nodep) {
assertAtStatement(nodep);
userIterateAndNext(nodep->lhsp(), WidthVP(SELF,BOTH).p());
@ -2286,8 +2299,12 @@ private:
if ((VN_IS(modDTypep, IfaceRefDType) && !VN_IS(exprDTypep, IfaceRefDType)) ||
(VN_IS(exprDTypep, IfaceRefDType) && !VN_IS(modDTypep, IfaceRefDType))) {
nodep->v3error("Illegal "<<nodep->prettyOperatorName()<<","
<<" mismatch between port which is"<<(VN_CAST(modDTypep, IfaceRefDType)?"":" not")<<" an interface,"
<<" and expression which is"<<(VN_CAST(exprDTypep, IfaceRefDType)?"":" not")<<" an interface.");
<<" mismatch between port which is"
<<(VN_CAST(modDTypep, IfaceRefDType)?"":" not")
<<" an interface,"
<<" and expression which is"
<<(VN_CAST(exprDTypep, IfaceRefDType)?"":" not")
<<" an interface.");
}
// TODO Simple dtype checking, should be a more general check
@ -2952,9 +2969,12 @@ private:
bool widthBad (AstNode* nodep, AstNodeDType* expDTypep) {
int expWidth = expDTypep->width();
int expWidthMin = expDTypep->widthMin();
if (!nodep->dtypep()) nodep->v3fatalSrc("Under node "<<nodep->prettyTypeName()<<" has no dtype?? Missing Visitor func?");
if (nodep->width()==0) nodep->v3fatalSrc("Under node "<<nodep->prettyTypeName()<<" has no expected width?? Missing Visitor func?");
if (expWidth==0) nodep->v3fatalSrc("Node "<<nodep->prettyTypeName()<<" has no expected width?? Missing Visitor func?");
if (!nodep->dtypep()) nodep->v3fatalSrc("Under node "<<nodep->prettyTypeName()
<<" has no dtype?? Missing Visitor func?");
if (nodep->width()==0) nodep->v3fatalSrc("Under node "<<nodep->prettyTypeName()
<<" has no expected width?? Missing Visitor func?");
if (expWidth==0) nodep->v3fatalSrc("Node "<<nodep->prettyTypeName()
<<" has no expected width?? Missing Visitor func?");
if (expWidthMin==0) expWidthMin = expWidth;
if (nodep->dtypep()->width() == expWidth) return false;
if (nodep->dtypep()->widthSized() && nodep->width() != expWidthMin) return true;
@ -3860,12 +3880,14 @@ int V3Width::debug() {
void V3Width::width(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
// We should do it in bottom-up module order, but it works in any order.
WidthClearVisitor cvisitor (nodep);
WidthVisitor visitor (false, false);
(void)visitor.mainAcceptEdit(nodep);
WidthRemoveVisitor rvisitor;
(void)rvisitor.mainAcceptEdit(nodep);
{
// We should do it in bottom-up module order, but it works in any order.
WidthClearVisitor cvisitor (nodep);
WidthVisitor visitor (false, false);
(void)visitor.mainAcceptEdit(nodep);
WidthRemoveVisitor rvisitor;
(void)rvisitor.mainAcceptEdit(nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("width", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
@ -3901,6 +3923,8 @@ AstNode* V3Width::widthGenerateParamsEdit(
void V3Width::widthCommit(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
WidthCommitVisitor visitor (nodep);
{
WidthCommitVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("widthcommit", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}

View File

@ -77,6 +77,10 @@ void VlcOptions::parseOptsList(int argc, char** argv) {
else if ( onoff (sw, "-rank", flag/*ref*/) ) { m_rank = flag; }
else if ( onoff (sw, "-unlink", flag/*ref*/) ) { m_unlink = flag; }
// Parameterized switches
else if ( !strcmp (sw, "-annotate-min") && (i+1)<argc ) {
shift;
m_annotateMin = atoi(argv[i]);
}
else if ( !strcmp (sw, "-annotate") && (i+1)<argc ) {
shift;
m_annotateOut = argv[i];

View File

@ -19,7 +19,7 @@ my $Opt_Prefix = $ARGV[0] or die "%Error: No prefix specified,";
foreach my $line (<STDIN>) {
# Fix flex 2.6.1 warning
$line =~ s/for \( i = 0; i < _yybytes_len; \+\+i \)/for ( i = 0; i < (yy_size_t)(_yybytes_len); ++i )/g;
$line =~ s/for \( i = 0; i < _yybytes_len; \+\+i \)/for ( i = 0; (yy_size_t)(i) < (yy_size_t)(_yybytes_len); ++i )/g;
# Fix flex 2.6.0 warning
$line =~ s/\(\(int\) \(\(yy_n_chars\) \+ number_to_move\) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size\)/((int) ((yy_n_chars) + number_to_move) > (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size)/g;
$line =~ s/ number_to_move == YY_MORE_ADJ / (int)number_to_move == (int)YY_MORE_ADJ /;

View File

@ -1065,7 +1065,8 @@ void V3ParseImp::lexToken() {
}
else if (token == yGLOBAL__LEX) {
if (nexttok == yCLOCKING) token = yGLOBAL__CLOCKING;
else { token = yaID__LEX; yylval.strp = PARSEP->newString("global"); } // Avoid 2009 "global" conflicting with old code when we can
// Avoid 2009 "global" conflicting with old code when we can
else { token = yaID__LEX; yylval.strp = PARSEP->newString("global"); }
}
// If add to above "else if", also add to "if (token" further above
}

View File

@ -2663,6 +2663,8 @@ system_t_call<nodep>: // IEEE: system_tf_call (as task)
| yaD_DPI '(' exprList ')' { $$ = new AstTaskRef($2,*$1,$3); GRAMMARP->argWrapList(VN_CAST($$, TaskRef)); }
//
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); }
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemT($1,$3); }
//
| yD_FCLOSE '(' idClassSel ')' { $$ = new AstFClose($1, $3); }
| yD_FFLUSH parenE { $1->v3error("Unsupported: $fflush of all handles does not map to C++."); }
| yD_FFLUSH '(' expr ')' { $$ = new AstFFlush($1, $3); }
@ -2673,7 +2675,6 @@ system_t_call<nodep>: // IEEE: system_tf_call (as task)
//
| yD_SFORMAT '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); }
| yD_SWRITE '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); }
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemT($1,$3); }
//
| yD_DISPLAY parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,NULL,NULL); }
| yD_DISPLAY '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,NULL,$3); }
@ -2698,6 +2699,9 @@ system_t_call<nodep>: // IEEE: system_tf_call (as task)
| yD_READMEMH '(' expr ',' idClassSel ')' { $$ = new AstReadMem($1,true, $3,$5,NULL,NULL); }
| yD_READMEMH '(' expr ',' idClassSel ',' expr ')' { $$ = new AstReadMem($1,true, $3,$5,$7,NULL); }
| yD_READMEMH '(' expr ',' idClassSel ',' expr ',' expr ')' { $$ = new AstReadMem($1,true, $3,$5,$7,$9); }
//
// Any system function as a task
| system_f_call_or_t { $$ = new AstSysFuncAsTask($<fl>1, $1); }
;
system_f_call<nodep>: // IEEE: system_tf_call (as func)
@ -2707,7 +2711,14 @@ system_f_call<nodep>: // IEEE: system_tf_call (as func)
| yaD_DPI parenE { $$ = new AstFuncRef($<fl>1,*$1,NULL); }
| yaD_DPI '(' exprList ')' { $$ = new AstFuncRef($2,*$1,$3); GRAMMARP->argWrapList(VN_CAST($$, FuncRef)); }
//
| yD_ACOS '(' expr ')' { $$ = new AstAcosD($1,$3); }
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCFunc($1,$3)); }
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemF($1,$3); }
//
| system_f_call_or_t { $$ = $1; }
;
system_f_call_or_t<nodep>: // IEEE: part of system_tf_call (can be task or func)
yD_ACOS '(' expr ')' { $$ = new AstAcosD($1,$3); }
| yD_ACOSH '(' expr ')' { $$ = new AstAcoshD($1,$3); }
| yD_ASIN '(' expr ')' { $$ = new AstAsinD($1,$3); }
| yD_ASINH '(' expr ')' { $$ = new AstAsinhD($1,$3); }
@ -2717,7 +2728,6 @@ system_f_call<nodep>: // IEEE: system_tf_call (as func)
| yD_BITS '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3); }
| yD_BITS '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3,$5); }
| yD_BITSTOREAL '(' expr ')' { $$ = new AstBitsToRealD($1,$3); }
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCFunc($1,$3)); }
| yD_CEIL '(' expr ')' { $$ = new AstCeilD($1,$3); }
| yD_CLOG2 '(' expr ')' { $$ = new AstCLog2($1,$3); }
| yD_COS '(' expr ')' { $$ = new AstCosD($1,$3); }
@ -2762,7 +2772,6 @@ system_f_call<nodep>: // IEEE: system_tf_call (as func)
| yD_SQRT '(' expr ')' { $$ = new AstSqrtD($1,$3); }
| yD_SSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstSScanF($1,*$5,$3,$6); }
| yD_STIME parenE { $$ = new AstSel($1,new AstTime($1),0,32); }
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemF($1,$3); }
| yD_TAN '(' expr ')' { $$ = new AstTanD($1,$3); }
| yD_TANH '(' expr ')' { $$ = new AstTanhD($1,$3); }
| yD_TESTPLUSARGS '(' str ')' { $$ = new AstTestPlusArgs($1,*$3); }

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 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.
$Self->{vlt} or $Self->skip("Verilator only test");
compile (
v_flags2 => ["--debug --no-debug-leak"],
verilator_make_gcc => 0,
make_top_shell => 0,
make_main => 0,
);
ok(1);
1;

View File

@ -0,0 +1,12 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2008 by Wilson Snyder.
module t;
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -45,6 +45,11 @@ module t;
$display("str='%s'",sv_str);
if (sv_str != "T=1234") $stop;
sv_str = "none";
$value$plusargs("IN%s", sv_str);
$display("str='%s'",sv_str);
if (sv_str != "T=1234") $stop;
p_in = "IN%s";
`ifdef VERILATOR
p_in = $c(p_in); // Prevent constant propagation

View File

@ -0,0 +1,25 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2007 by Wilson Snyder.
module t (/*AUTOARG*/
// Outputs
x,
// Inputs
clk
);
`ifdef ALLOW_UNOPT
/*verilator lint_off UNOPTFLAT*/
`endif
input clk;
output [31:0] x; // Avoid eliminating x
reg [31:0] x;
always @* begin
x = x ^ $random;
end
endmodule

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 2007 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.
top_filename("t/t_unopt_converge_initial.v");
compile (
v_flags2 => ['+define+ALLOW_UNOPT'],
);
execute (
fails=>1,
expect=> '%Error: \S+:\d+: Verilated model didn\'t DC converge',
) if $Self->{vlt};
ok(1);
1;