Compare commits

...
18 Commits
Author SHA1 Message Date
Wilson Snyder 8108b97050 Version bump 2012-11-03 20:16:01 -04:00
Wilson Snyder a1c3491dea Display speed ups, bug574. 2012-11-03 20:11:53 -04:00
Wilson Snyder 8bba96a84e Tests 2012-11-03 09:23:34 -04:00
Wilson Snyder 6cd9b25a53 Fix array of struct references giving false error, bug566. 2012-11-03 09:17:42 -04:00
Wilson Snyder 0431b1909c Fix name collision on task inputs, bug569. 2012-11-03 08:01:19 -04:00
Wilson Snyder 907665e2e8 Fix name collision on unnamed blocks, bug567. 2012-11-02 20:30:47 -04:00
Wilson Snyder 61e8836fbd Add -x-initial-edge, bug570. by Jeremy Bennett; from BENNETT/initial-edge branch. 2012-11-02 19:55:34 -04:00
Wilson Snyder 0e921b5dff Speed display, bug373. 2012-11-02 17:54:14 -04:00
Wilson Snyder 7ef37d6e17 Fix missing var access functions when no DPI, bug572. 2012-10-30 03:02:35 -04:00
Wilson Snyder dce227684a Fix mangling on GCC 4.7, msg927. 2012-10-28 17:35:48 -04:00
Wilson Snyder 158e112752 Internals: Resolve misc bison comments with Verilog-Perl. No functional change. 2012-10-08 21:20:13 -04:00
Wilson Snyder ec992c7f5e Internals: Resolve misc bison comments with Verilog-Perl 2012-10-08 20:45:39 -04:00
Wilson Snyder e7d63c7644 Fix large shift error on large shift constants. 2012-10-08 07:05:54 -04:00
Wilson Snyder 6464e8fee6 Misc code cleanups. Merge from assignment pattern branch. No functional change. 2012-09-25 19:27:00 -04:00
Wilson Snyder 047d66a657 Slice code cleanup. No functional change. 2012-09-25 19:17:57 -04:00
Wilson Snyder 55c23360d9 Commentary 2012-09-24 18:28:19 -04:00
Wilson Snyder c378d32c85 Fix parameter pins interspersed with cells broke in 3.840. 2012-09-07 19:51:41 -04:00
Wilson Snyder 3d9540c58c devel release 2012-09-03 20:32:32 -04:00
33 changed files with 673 additions and 132 deletions
+19
View File
@@ -3,6 +3,25 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. [by ...]
indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.842 2012/11/03
**** Add -x-initial-edge, bug570. [Jeremy Bennett]
**** Fix parameter pins interspersed with cells broke in 3.840. [Bernard Deadman]
**** Fix large shift error on large shift constants. [David Welch]
**** Fix $display mangling on GCC 4.7 and speed up, msg927, bug373, bug574. [R Diez]
**** Fix array of struct references giving false error, bug566. [Julius Baxter]
**** Fix missing var access functions when no DPI, bug572. [Amir Gonnen]
**** Fix name collision on unnamed blocks, bug567. [Chandan Egbert]
**** Fix name collision on task inputs, bug569. [Chandan Egbert]
* Verilator 3.841 2012/09/03
*** Add --savable to support model save/restore. [Jeremy Bennett]
+85 -21
View File
@@ -326,7 +326,8 @@ descriptions in the next sections for more information.
-Wno-lint Disable all lint warnings
-Wno-style Disable all style warnings
-Wno-fatal Disable fatal exit on warnings
-x-assign <mode> Initially assign Xs to this value
--x-assign <mode> Initially assign Xs to this value
--x-initial-edge Enable initial X->0 and X->1 edge triggers
-y <dir> Directory to search for modules
@@ -359,13 +360,16 @@ with the --exe option.
Enable all assertions, includes enabling the --psl flag. (If psl is not
desired, but other assertions are, use --assert --nopsl.)
See also --x-assign; setting "--x-assign unique" may be desirable.
See also --x-assign and --x-initial-edge; setting "--x-assign unique"
and/or "--x-initial-edge" may be desirable.
=item --autoflush
After every $display or $fdisplay, flush the output stream. This insures
that messages will appear immediately but may reduce performance. Defaults
off, which will buffer output as provided by the normal C stdio calls.
that messages will appear immediately but may reduce performance; for best
performance call "fflush(stdout)" occasionally in the main C loop.
Defaults off, which will buffer output as provided by the normal C stdio
calls.
=item --bbox-sys
@@ -1000,29 +1004,63 @@ Enable all code style related warning messages. This is equivalent to
-Wwarn-PINNOCONNECT -Wwarn-SYNCASYNCNET -Wwarn-UNDRIVEN -Wwarn-UNUSED
-Wwarn-VARHIDDEN".
=item -x-assign 0
=item --x-assign 0
=item -x-assign 1
=item --x-assign 1
=item -x-assign fast (default)
=item --x-assign fast (default)
=item -x-assign unique
=item --x-assign unique
Controls the two-state value that is replaced when an assignment to X is
encountered. -x-assign=fast, the default, converts all Xs to whatever is
best for performance. -x-assign=0 converts all Xs to 0s, and is also fast.
-x-assign=1 converts all Xs to 1s, this is nearly as fast as 0, but more
likely to find reset bugs as active high logic will fire. -x-assign=unique
encountered. --x-assign=fast, the default, converts all Xs to whatever is
best for performance. --x-assign=0 converts all Xs to 0s, and is also fast.
--x-assign=1 converts all Xs to 1s, this is nearly as fast as 0, but more
likely to find reset bugs as active high logic will fire. --x-assign=unique
will call a function to determine the value, this allows randomization of
all Xs to find reset bugs and is the slowest, but safest for finding reset
bugs in code.
If using -x-assign unique, you may want to seed your random number
If using --x-assign unique, you may want to seed your random number
generator such that each regression run gets a different randomization
sequence. Use the system's srand48() or for Windows srand() function to do
this. You'll probably also want to print any seeds selected, and code to
enable rerunning with that same seed so you can reproduce bugs.
B<Note.> This option applies only to variables which are explicitly assigned
to X in the Verilog source code. Initial values of clocks are set to 0 unless
--x-initial-edge is specified. Initial values of all other state holding
variables are set as though --x-assign unique had been specified.
=item --x-initial-edge
Enables emulation of event driven simulators which generally trigger an
edge on a transition from X to 1 (C<posedge>) or X to 0 (C<negedge>). Thus
the following code, where C<rst_n> is uninitialized would set C<res_n> to
C<1'b1> when C<rst_n> is first set to zero:
reg res_n = 1'b0;
always @(negedge rst_n) begin
if (rst_n == 1'b0) begin
res_n <= 1'b1;
end
end
In Verilator, by default, uninitialized clocks are given a value of zero,
so the above C<always> block would not trigger.
While it is not good practice, there are some designs that rely on X
E<rarr> 0 triggering a C<negedge>, particularly in reset sequences. Using
--x-initial-edge with Verilator will replicate this behaviour. It will also
ensure that X E<rarr> 1 triggers a C<posedge>.
B<Note.> Some users have reported that using this option can affect
convergence, and that it may be necessary to use --converge-limit to
increase the number of convergence iterations. This may be another
indication of problems with the modelled design that should be addressed.
=item -y I<dir>
Add the directory to the list of directories that should be searched for
@@ -1058,6 +1096,7 @@ We'll compile this example into C++.
Verilated::commandArgs(argc, argv);
Vour* top = new Vour;
while (!Verilated::gotFinish()) { top->eval(); }
delete top;
exit(0);
}
EOF
@@ -1125,6 +1164,7 @@ This is an example similar to the above, but using SystemPerl.
top = new Vour("top"); // SP_CELL (top, Vour);
top->clk(clk); // SP_PIN (top, clk, clk);
while (!Verilated::gotFinish()) { sc_start(1, SC_NS); }
delete top;
exit(0);
}
EOF
@@ -1181,9 +1221,9 @@ the test_sp directory in the distribution for an example.
=head1 BENCHMARKING & OPTIMIZATION
For best performance, run Verilator with the "-O3 -x-assign=fast
For best performance, run Verilator with the "-O3 --x-assign=fast
--noassert" flags. The -O3 flag will require longer compile times, and
-x-assign=fast may increase the risk of reset bugs in trade for
--x-assign=fast may increase the risk of reset bugs in trade for
performance; see the above documentation for these flags.
Minor Verilog code changes can also give big wins. You should not have any
@@ -1198,8 +1238,10 @@ C++ compiler and size of your CPU's caches.
By default, the lib/verilated.mk file has optimization turned off. This is
for the benefit of new users, as it improves compile times at the cost of
runtimes. To add optimization as the default, set one of three variables,
OPT, OPT_FAST, or OPT_SLOW in lib/verilated.mk. Or, just for one run, pass
them on the command line to make:
OPT, OPT_FAST, or OPT_SLOW lib/verilated.mk. Or, use the -CFLAGS and/or
-LDFLAGS option on the verilator command line to pass the flags directly to
the compiler or linker. Or, just for one run, pass them on the command
line to make:
make OPT_FAST="-O2" -f Vour.mk Vour__ALL.a
@@ -1210,7 +1252,9 @@ rarely, yet take a long time to compile with optimization on. OPT
specifies overall optimization and affects all compiles, including those
OPT_FAST and OPT_SLOW affect. For best results, use OPT="-O2", and link
with "-static". Nearly the same results can be had with much better
compile times with OPT_FAST="-O1 -fstrict-aliasing".
compile times with OPT_FAST="-O1 -fstrict-aliasing". Higher optimization
such as "-O3" may help, but gcc compile times may be excessive under O3 on
even medium sized designs.
Unfortunately, using the optimizer with SystemC files can result in
compiles taking several minutes. (The SystemC libraries have many little
@@ -1224,6 +1268,11 @@ If you will be running many simulations on a single compile, investigate
feedback driven compilation. With GCC, using -fprofile-arcs, then
-fbranch-probabilities will yield another 15% or so.
Modern compilers also support link-time optimization (LTO), which can help
especially if you link in DPI code. To enable LTO on GCC, pass "-flto" in
both compilation and link. Note LTO may cause excessive compile times on
large designs.
You may uncover further tuning possibilities by profiling the Verilog code.
Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run
either oprofile or gprof to see where in the C++ code the time is spent.
@@ -1423,6 +1472,7 @@ example:
top->final(); // Done simulating
// // (Though this example doesn't get here)
delete top;
}
Note signals are read and written as member variables of the lower module.
@@ -2264,7 +2314,7 @@ from a four state simulator. An === comparison to X will always be false,
so that Verilog code which checks for uninitialized logic will not fire.
Assigning a variable to a X will actually assign the variable to a random
value (see the -x-assign switch.) Thus if the value is actually used, the
value (see the --x-assign switch.) Thus if the value is actually used, the
random value should cause downstream errors. Integers also randomize, even
though the Verilog 2001 specification says they initialize to zero.
@@ -2276,6 +2326,18 @@ following runs have it initialize them randomly. If the results match,
reset works. (Note this is what the hardware will really do.) In
practice, just setting all variables to one at startup finds most problems.
B<Note.> --x-assign applies to variables explicitly initialized or assigned to
X. Unititialized clocks are initialized to zero, while all other state holding
variables are initialized to a random value.
Event driven simulators will generally trigger an edge on a transition from X
to 1 (C<posedge>) or X to 0 (C<negedge>). However, by default, since clocks
are initialized to zero, Verilator will not trigger an initial negedge. Some
code (particulary for reset) may rely on X->0 triggering an edge. Verilator
provides a switch (see --x-initial-edge) to enable this behavior. Comparing
runs with and without this switch will find such problems.
=head2 Tri/Inout
Verilator converts some simple tristate structures into two state. Pullup,
@@ -3594,9 +3656,11 @@ Major concepts by Paul Wasson and Duane Galbi.
=head1 SEE ALSO
L<verilator_profcfunc>, L<systemperl>, L<vcoverage>, L<make>
L<verilator_profcfunc>, L<systemperl>, L<vcoverage>, L<make>,
And internals.txt in the distribution.
L<verilator --help> which is the source for this document,
and internals.txt in the distribution.
=cut
+3 -1
View File
@@ -4,7 +4,9 @@
# 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.
AC_INIT([Verilator],[3.841 2012-09-03])
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[3.842 2012-11-03])
AC_CONFIG_HEADER(src/config_build.h)
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk)
+13 -9
View File
@@ -308,7 +308,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
const char *ep = pos;
while (ep[0] && ep[0]!='%') ep++;
if (ep != pos) {
output += string(pos, ep-pos);
output.append(pos, ep-pos);
pos += ep-pos-1;
}
} else { // Format character
@@ -353,9 +353,9 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
// Deal with all read-and-print somethings
const int lbits = va_arg(ap, int);
QData ld = 0;
WData qlwp[2];
WDataInP lwp;
if (lbits <= VL_QUADSIZE) {
WData qlwp[2];
ld = _VL_VA_ARG_Q(ap, lbits);
VL_SET_WQ(qlwp,ld);
lwp = qlwp;
@@ -757,9 +757,10 @@ void VL_FCLOSE_I(IData fdi) {
}
void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
string output;
_vl_vsformat(output, formatp, ap);
va_end(ap);
@@ -767,9 +768,10 @@ void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) {
}
string VL_SFORMATF_NX(const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
string output;
_vl_vsformat(output, formatp, ap);
va_end(ap);
@@ -777,9 +779,10 @@ string VL_SFORMATF_NX(const char* formatp, ...) {
}
void VL_WRITEF(const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
string output;
_vl_vsformat(output, formatp, ap);
va_end(ap);
@@ -788,12 +791,13 @@ void VL_WRITEF(const char* formatp, ...) {
}
void VL_FWRITEF(IData fpi, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
output = "";
FILE* fp = VL_CVT_I_FP(fpi);
if (VL_UNLIKELY(!fp)) return;
va_list ap;
va_start(ap,formatp);
string output;
_vl_vsformat(output, formatp, ap);
va_end(ap);
@@ -956,13 +960,13 @@ IData VL_SYSTEM_IW(int lhswords, WDataInP filenamep) {
}
IData VL_TESTPLUSARGS_I(const char* formatp) {
string match = VerilatedImp::argPlusMatch(formatp);
const string& match = VerilatedImp::argPlusMatch(formatp);
if (match == "") return 0;
else return 1;
}
IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rwp) {
string match = VerilatedImp::argPlusMatch(prefixp);
const string& match = VerilatedImp::argPlusMatch(prefixp);
const char* dp = match.c_str() + 1 /*leading + */ + strlen(prefixp);
if (match == "") return 0;
VL_ZERO_RESET_W(rbits, rwp);
@@ -998,7 +1002,7 @@ IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rw
}
const char* vl_mc_scan_plusargs(const char* prefixp) {
string match = VerilatedImp::argPlusMatch(prefixp);
const string& match = VerilatedImp::argPlusMatch(prefixp);
static VL_THREAD char outstr[VL_VALUE_STRING_MAX_WIDTH];
if (match == "") return NULL;
strncpy(outstr, match.c_str()+strlen(prefixp)+1, // +1 to skip the "+"
+2 -2
View File
@@ -182,7 +182,7 @@ public:
vluint32_t entSize() const { return m_entSize; }
virtual const char* name() { return m_varp->name(); }
virtual const char* fullname() {
static VL_THREAD string out;
VL_STATIC_OR_THREAD string out;
out = string(m_scopep->name())+"."+name();
return out.c_str();
}
@@ -207,7 +207,7 @@ public:
virtual ~VerilatedVpioVarIndex() {}
static inline VerilatedVpioVarIndex* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioVarIndex*>((VerilatedVpio*)h); }
virtual const char* fullname() {
static VL_THREAD string out;
VL_STATIC_OR_THREAD string out;
char num[20]; sprintf(num,"%d",m_index);
out = string(scopep()->name())+"."+name()+"["+num+"]";
return out.c_str();
+4
View File
@@ -78,8 +78,12 @@
# else
# error "Unsupported compiler for VL_THREADED: No thread-local declarator"
# endif
# define VL_STATIC_OR_THREAD ///< Static if unthreaded, as some strings can be faster
// ///< if non-dynamic and can't do "static VL_THREAD string"
#else
# define VL_THREAD ///< Storage class for thread-local storage
# define VL_STATIC_OR_THREAD static ///< Static if unthreaded, as some strings can be faster
// ///< if non-dynamic and can't do "static VL_THREAD string"
#endif
#ifdef _MSC_VER
+8 -1
View File
@@ -371,6 +371,13 @@ the documentation in:
test_regress/t/driver.pl --help
It is important to add tests for failures as well as success (for example to
check that an error message is correctly triggered).
Tests that fail should by convenition have the suffix C<_bad> in their name,
and include C<fails =E<gt> 1> in either their C<compile> or C<execute> step as
appropriate.
Developers will also want to configure with two extra flags:
=over 4
@@ -382,7 +389,7 @@ ensure no sloppy code gets added, however it can be painful when it comes
to testing, since third party code used in the tests (e.g. SystemC) may not
be warning free.
=item --enable-long-tests
=item --enable-longtests
In addition to the standard C, SystemC and SystemPerl tests also run the
tests in the C<test_vcs>, C<test_verilated> and C<test_regress> directories
+1 -1
View File
@@ -83,7 +83,7 @@ private:
if (vscp->user1p()) return ((AstVarScope*)vscp->user1p());
AstVar* varp = vscp->varp();
if (!varp->width1()) varp->v3error("Unsupported: Clock edge on non-single bit signal: "<<varp->prettyName());
string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->shortName());
string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->name());
AstVar* newvarp = new AstVar (vscp->fileline(), AstVarType::MODULETEMP, newvarname, VFlagLogicPacked(), 1);
m_modp->addStmtp(newvarp);
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp);
+10 -1
View File
@@ -1368,7 +1368,16 @@ void EmitCImp::emitVarResets(AstNodeModule* modp) {
puts(varp->name());
for (int v=0; v<vects; ++v) puts( "[__Vi"+cvtToStr(v)+"]");
if (zeroit) {
puts(" = 0;\n");
// We want to force an initial edge on uninitialized clocks (from 'X' to
// whatever the first value is). Since the class is instantiated before
// initial blocks are evaluated, this should not clash with any initial
// block settings. Clocks are always BIT datatypes, so zeroit is true.
if (v3Global.opt.xInitialEdge()
&& (0 == varp->name().find("__Vclklast__"))) {
puts(" = 1;\n");
} else {
puts(" = 0;\n");
}
} else {
puts(" = VL_RAND_RESET_");
emitIQW(varp);
+3 -2
View File
@@ -115,8 +115,8 @@ class EmitCSyms : EmitCBaseVisitor {
AstScope* scopep = it->first; AstNodeModule* smodp = it->second;
for (vector<ModVarPair>::iterator it = m_modVars.begin(); it != m_modVars.end(); ++it) {
AstNodeModule* modp = it->first;
AstVar* varp = it->second;
if (modp == smodp) {
AstVar* varp = it->second;
// Need to split the module + var name into the original-ish full scope and variable name under that scope.
// The module instance name is included later, when we know the scopes this module is under
string whole = scopep->name()+"__DOT__"+varp->name();
@@ -204,7 +204,8 @@ class EmitCSyms : EmitCBaseVisitor {
}
virtual void visit(AstVar* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (nodep->isSigUserRdPublic()) {
if (nodep->isSigUserRdPublic()
&& !nodep->isParam()) { // The VPI functions require a pointer to allow modification, but parameters are constants
m_modVars.push_back(make_pair(m_modp, nodep));
}
}
+15 -4
View File
@@ -154,6 +154,7 @@ public:
// See t_gen_forif.v for an example.
} else {
preErrorDump();
UINFO(4,"name "<<name<<endl); // Not always same as nodep->name
UINFO(4,"Var1 "<<nodep<<endl);
UINFO(4,"Var2 "<<fnodep<<endl);
if (nodep->type() == fnodep->type()) {
@@ -450,6 +451,9 @@ private:
string oldscope = m_scope;
VSymEnt* oldModSymp = m_modSymp;
VSymEnt* oldCurSymp = m_curSymp;
int oldParamNum = m_paramNum;
int oldBeginNum = m_beginNum;
int oldModBeginNum = m_modBeginNum;
if (doit) {
UINFO(2," Link Module: "<<nodep<<endl);
if (nodep->dead()) nodep->v3fatalSrc("Module in cell tree mislabeled as dead?");
@@ -481,6 +485,9 @@ private:
m_scope = oldscope;
m_modSymp = oldModSymp;
m_curSymp = oldCurSymp;
m_paramNum = oldParamNum;
m_beginNum = oldBeginNum;
m_modBeginNum = oldModBeginNum;
// Prep for next
m_packagep = NULL;
}
@@ -497,6 +504,7 @@ private:
AstBegin* oldbeginp = m_beginp;
VSymEnt* oldModSymp = m_modSymp;
VSymEnt* oldCurSymp = m_curSymp;
int oldParamNum = m_paramNum;
// Where do we add it?
VSymEnt* aboveSymp = m_curSymp;
string origname = AstNode::dedotName(nodep->name());
@@ -522,6 +530,7 @@ private:
m_beginp = oldbeginp;
m_modSymp = oldModSymp;
m_curSymp = oldCurSymp;
m_paramNum = oldParamNum;
}
virtual void visit(AstCellInline* nodep, AstNUser*) {
UINFO(5," CELLINLINE under "<<m_scope<<" is "<<nodep<<endl);
@@ -1010,7 +1019,7 @@ private:
AstCell* m_cellp; // Current cell
AstNodeModule* m_modp; // Current module
AstNodeFTask* m_ftaskp; // Current function/task
AstDot* m_dotp; // Current dot
AstDot* m_dotp; // Current dot
DotPosition m_dotPos; // Scope part of dotted resolution
bool m_dotErr; // Error found in dotted resolution, ignore upwards
string m_dotText; // String of dotted names found in below parseref
@@ -1243,6 +1252,7 @@ private:
if (m_dotText!="") m_dotText += ".";
m_dotText += nodep->name();
m_dotSymp = foundp;
m_dotPos = DP_SCOPE;
// Upper AstDot visitor will handle it from here
}
}
@@ -1356,6 +1366,7 @@ private:
VSymEnt* okSymp;
VSymEnt* dotSymp = m_curSymp; // Start search at current scope
if (nodep->inlinedDots()!="") { // Correct for current scope
dotSymp = m_modSymp; // Dotted lookup is always relative to module, as maybe variable name lower down with same scope name we want to ignore (t_math_divw)
string inl = AstNode::dedotName(nodep->inlinedDots());
dotSymp = m_statep->findDotted(dotSymp, inl, baddot, okSymp);
if (!dotSymp) {
@@ -1461,8 +1472,8 @@ private:
}
virtual void visit(AstSelBit* nodep, AstNUser*) {
if (nodep->user3SetOnce()) return;
nodep->lhsp()->iterateAndNext(*this);
if (m_dotPos == DP_SCOPE) { // Already under dot, so this is {modulepart} DOT {modulepart}
nodep->lhsp()->iterateAndNext(*this);
if (AstConst* constp = nodep->rhsp()->castConst()) {
string index = AstNode::encodeNumber(constp->toSInt());
m_dotText += "__BRA__"+index+"__KET__";
@@ -1470,9 +1481,9 @@ private:
nodep->v3error("Unsupported: Non-constant inside []'s in the cell part of a dotted reference");
}
// And pass up m_dotText
} else {
nodep->iterateChildren(*this);
}
nodep->fromp()->iterateAndNext(*this);
nodep->bitp()->iterateAndNext(*this);
}
virtual void visit(AstBegin* nodep, AstNUser*) {
UINFO(5," "<<nodep<<endl);
+2
View File
@@ -700,6 +700,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if ( onoff (sw, "-trace-dups", flag/*ref*/) ) { m_traceDups = flag; }
else if ( onoff (sw, "-trace-underscore", flag/*ref*/) ) { m_traceUnderscore = flag; }
else if ( onoff (sw, "-underline-zero", flag/*ref*/) ) { m_underlineZero = flag; } // Undocumented, old Verilator-2
else if ( onoff (sw, "-x-initial-edge", flag/*ref*/) ) { m_xInitialEdge = flag; }
else if ( onoff (sw, "-xml-only", flag/*ref*/) ) { m_xmlOnly = flag; } // Undocumented, still experimental
// Optimization
else if ( !strncmp (sw, "-O", 2) ) {
@@ -1144,6 +1145,7 @@ V3Options::V3Options() {
m_traceDups = false;
m_traceUnderscore = false;
m_underlineZero = false;
m_xInitialEdge = false;
m_xmlOnly = false;
m_convergeLimit = 100;
+2
View File
@@ -124,6 +124,7 @@ class V3Options {
bool m_traceDups; // main switch: --trace-dups
bool m_traceUnderscore;// main switch: --trace-underscore
bool m_underlineZero;// main switch: --underline-zero; undocumented old Verilator 2
bool m_xInitialEdge; // main switch: --x-initial-edge
bool m_xmlOnly; // main switch: --xml-netlist
int m_convergeLimit;// main switch: --converge-limit
@@ -252,6 +253,7 @@ class V3Options {
bool lintOnly() const { return m_lintOnly; }
bool ignc() const { return m_ignc; }
bool inhibitSim() const { return m_inhibitSim; }
bool xInitialEdge() const { return m_xInitialEdge; }
bool xmlOnly() const { return m_xmlOnly; }
int convergeLimit() const { return m_convergeLimit; }
+6 -22
View File
@@ -54,14 +54,6 @@ class SliceCloneVisitor : public AstNVisitor {
// AstNodeAssign::user2() -> int. The number of clones needed for this assign
// AstArraySel::user3() -> bool. Error detected
// ENUMS
enum RedOp { // The type of unary operation to be expanded
REDOP_UNKNOWN, // Unknown/Unsupported
REDOP_OR, // Or Reduction
REDOP_AND, // And Reduction
REDOP_XOR, // Xor Reduction
REDOP_XNOR}; // Xnor Reduction
// STATE
vector<vector<unsigned> > m_selBits; // Indexes of the ArraySel we are expanding
int m_vecIdx; // Current vector index
@@ -140,14 +132,6 @@ class SliceCloneVisitor : public AstNVisitor {
m_selBits.clear();
UINFO(4, "Cloning "<<nodep->user2()<<" times: "<<nodep<<endl);
// Figure out what type of operation this is so we don't have to cast on
// every clone.
RedOp redOpType = REDOP_UNKNOWN;
if (nodep->castRedOr()) redOpType = REDOP_OR;
else if (nodep->castRedAnd()) redOpType = REDOP_AND;
else if (nodep->castRedXor()) redOpType = REDOP_XOR;
else if (nodep->castRedXnor()) redOpType = REDOP_XNOR;
AstNode* lhsp = NULL;
AstNode* rhsp = NULL;
for (int i = 0; i < nodep->user2(); ++i) {
@@ -158,20 +142,20 @@ class SliceCloneVisitor : public AstNVisitor {
if (!lhsp) lhsp = clonep;
else rhsp = clonep;
if (lhsp && rhsp) {
switch (redOpType) {
case REDOP_OR:
switch (nodep->type()) {
case AstType::atREDOR:
lhsp = new AstOr(nodep->fileline(), lhsp, rhsp);
break;
case REDOP_AND:
case AstType::atREDAND:
lhsp = new AstAnd(nodep->fileline(), lhsp, rhsp);
break;
case REDOP_XOR:
case AstType::atREDXOR:
lhsp = new AstXor(nodep->fileline(), lhsp, rhsp);
break;
case REDOP_XNOR:
case AstType::atREDXNOR:
lhsp = new AstXnor(nodep->fileline(), lhsp, rhsp);
break;
default: // REDOP_UNKNOWN
default:
nodep->v3fatalSrc("Unsupported: Unary operation on multiple packed dimensions");
break;
}
+1 -1
View File
@@ -60,7 +60,7 @@ private:
return level;
}
#else
static int debug() { return 0; } // NOT runtime, too hot of a function
static inline int debug() { return 0; } // NOT runtime, too hot of a function
#endif
public:
void dumpIterate(ostream& os, VSymMap& doneSymsr, const string& indent, int numLevels, const string& searchName) {
+31 -15
View File
@@ -1006,6 +1006,23 @@ private:
m_assDTypep = m_assDTypep->skipRefp();
UINFO(9," adtypep "<<m_assDTypep<<endl);
nodep->dtypep(m_assDTypep);
for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) {
// Determine replication count, and replicate initial value as widths need to be individually determined
int times = visitPatMemberRep(patp);
for (int i=1; i<times; i++) {
AstNode* newp = patp->cloneTree(false);
patp->addNextHere(newp);
// This loop will see the new elements as part of nextp()
}
}
AstPatMember* defaultp = NULL;
for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) {
if (patp->isDefault()) {
if (defaultp) nodep->v3error("Multiple '{ default: } clauses");
defaultp = patp;
patp->unlinkFrBack();
}
}
if (AstNodeClassDType* classp = m_assDTypep->castNodeClassDType()) {
// Due to "default" and tagged patterns, we need to determine
// which member each AstPatMember corresponds to before we can
@@ -1013,19 +1030,11 @@ private:
// width the initial value appropriately.
typedef map<AstMemberDType*,AstPatMember*> PatMap;
PatMap patmap;
AstPatMember* defaultp = NULL;
{
AstMemberDType* memp = classp->membersp();
AstPatMember* patp = nodep->itemsp()->castPatMember();
for (; memp || patp; ) {
// Determine replication count, and replicate initial value as widths need to be individually determined
if (patp) {
int times = visitPatMemberRep(patp);
for (int i=1; i<times; i++) {
AstNode* newp = patp->cloneTree(false);
patp->addNextHere(newp);
// This loop will see the new elements as part of nextp()
}
if (patp->keyp()) {
if (AstText* textp = patp->keyp()->castText()) {
memp = classp->findMember(textp->text());
@@ -1038,10 +1047,7 @@ private:
}
}
}
if (patp && patp->isDefault()) {
if (defaultp) nodep->v3error("Multiple '{ default: } clauses");
defaultp = patp;
} else if (memp && !patp) {
if (memp && !patp) {
// Missing init elements, warn below
memp=NULL; patp=NULL; break;
} else if (!memp && patp) { patp->v3error("Assignment pattern contains too many elements");
@@ -1815,9 +1821,19 @@ private:
int width=nodep->width(); int ewidth=nodep->widthMin();
nodep->lhsp()->iterateAndNext(*this,WidthVP(width,ewidth,FINAL).p());
widthCheck(nodep,"LHS",nodep->lhsp(),width,ewidth);
if (nodep->rhsp()->width()>32)
nodep->rhsp()->v3error("Unsupported: Shifting of by over 32-bit number isn't supported."
<<" (This isn't a shift of 32 bits, but a shift of 2^32, or 4 billion!)\n");
if (nodep->rhsp()->width()>32) {
AstConst* shiftp = nodep->rhsp()->castConst();
if (shiftp && shiftp->num().mostSetBitP1() <= 32) {
// If (number)<<96'h1, then make it into (number)<<32'h1
V3Number num (shiftp->fileline(), 32, 0); num.opAssign(shiftp->num());
AstNode* shiftp = nodep->rhsp();
nodep->rhsp()->replaceWith(new AstConst(shiftp->fileline(), num));
shiftp->deleteTree(); shiftp=NULL;
} else {
nodep->rhsp()->v3error("Unsupported: Shifting of by over 32-bit number isn't supported."
<<" (This isn't a shift of 32 bits, but a shift of 2^32, or 4 billion!)\n");
}
}
}
return nodep; // May edit
}
+84 -33
View File
@@ -208,6 +208,9 @@ class AstSenTree;
%token<strp> yaID__LEX "IDENTIFIER-in-lex"
%token<strp> yaID__aPACKAGE "PACKAGE-IDENTIFIER"
%token<strp> yaID__aTYPE "TYPE-IDENTIFIER"
// Can't predecode aFUNCTION, can declare after use
// Can't predecode aINTERFACE, can declare after use
// Can't predecode aTASK, can declare after use
// IEEE: integral_number
%token<nump> yaINTNUM "INTEGER NUMBER"
@@ -631,6 +634,7 @@ descriptionList: // IEEE: part of source_text
description: // ==IEEE: description
module_declaration { }
// // udp_declaration moved into module_declaration
//UNSUP interface_declaration { }
| program_declaration { }
| package_declaration { }
@@ -644,6 +648,7 @@ description: // ==IEEE: description
timeunits_declaration<nodep>: // ==IEEE: timeunits_declaration
yTIMEUNIT yaTIMENUM ';' { $$ = NULL; }
| yTIMEUNIT yaTIMENUM '/' yaTIMENUM ';' { $$ = NULL; }
| yTIMEPRECISION yaTIMENUM ';' { $$ = NULL; }
;
@@ -681,6 +686,7 @@ package_itemList<nodep>: // IEEE: { package_item }
package_item<nodep>: // ==IEEE: package_item
package_or_generate_item_declaration { $$ = $1; }
//UNSUP anonymous_program { $$ = $1; }
//UNSUP package_export_declaration { $$ = $1; }
| timeunits_declaration { $$ = $1; }
;
@@ -689,15 +695,16 @@ package_or_generate_item_declaration<nodep>: // ==IEEE: package_or_generate_item
| data_declaration { $$ = $1; }
| task_declaration { $$ = $1; }
| function_declaration { $$ = $1; }
//UNSUP checker_declaration { $$ = $1; }
| dpi_import_export { $$ = $1; }
//UNSUP extern_constraint_declaration { $$ = $1; }
//UNSUP class_declaration { $$ = $1; }
// // class_constructor_declaration is part of function_declaration
| local_parameter_declaration ';' { $$ = $1; }
| parameter_declaration ';' { $$ = $1; }
| local_parameter_declaration { $$ = $1; }
//UNSUP covergroup_declaration { $$ = $1; }
//UNSUP overload_declaration { $$ = $1; }
//UNSUP concurrent_assertion_item_declaration { $$ = $1; }
//UNSUP assertion_item_declaration { $$ = $1; }
| ';' { $$ = NULL; }
;
@@ -822,13 +829,17 @@ port<nodep>: // ==IEEE: port
// // IEEE: interface_port_header port_identifier { unpacked_dimension }
// // Expanded interface_port_header
// // We use instantCb here because the non-port form looks just like a module instantiation
//UNSUP portDirNetE id/*interface*/ idAny/*port*/ rangeListE sigAttrListE { VARDTYPE($2); VARDONEA($<fl>3, $3, $4); PARSEP->instantCb($<fl>2, $2, $3, $4); PINNUMINC(); }
//UNSUP portDirNetE yINTERFACE idAny/*port*/ rangeListE sigAttrListE { VARDTYPE($2); VARDONEA($<fl>3, $3, $4); PINNUMINC(); }
//UNSUP portDirNetE id/*interface*/ '.' idAny/*modport*/ idAny/*port*/ rangeListE sigAttrListE { VARDTYPE($2); VARDONEA($<fl>5, $5, $6); PARSEP->instantCb($<fl>2, $2, $5, $6); PINNUMINC(); }
//UNSUP portDirNetE yINTERFACE '.' idAny/*modport*/ idAny/*port*/ rangeListE sigAttrListE { VARDTYPE($2); VARDONEA($<fl>5, $5, $6); PINNUMINC(); }
//UNSUP portDirNetE id/*interface*/ idAny/*port*/ rangeListE sigAttrListE
//UNSUP { VARDTYPE($2); VARDONEA($<fl>3, $3, $4); PARSEP->instantCb($<fl>2, $2, $3, $4); PINNUMINC(); }
//UNSUP portDirNetE yINTERFACE idAny/*port*/ rangeListE sigAttrListE
//UNSUP { VARDTYPE($2); VARDONEA($<fl>3, $3, $4); PINNUMINC(); }
//UNSUP portDirNetE id/*interface*/ '.' idAny/*modport*/ idAny/*port*/ rangeListE sigAttrListE
//UNSUP { VARDTYPE($2); VARDONEA($<fl>5, $5, $6); PARSEP->instantCb($<fl>2, $2, $5, $6); PINNUMINC(); }
//UNSUP portDirNetE yINTERFACE '.' idAny/*modport*/ idAny/*port*/ rangeListE sigAttrListE
//UNSUP { VARDTYPE($2); VARDONEA($<fl>5, $5, $6); PINNUMINC(); }
//
// // IEEE: ansi_port_declaration, with [port_direction] removed
// // IEEE: [ net_port_header | interface_port_header ] port_identifier { unpacked_dimension }
// // IEEE: [ net_port_header | interface_port_header ] port_identifier { unpacked_dimension } [ '=' constant_expression ]
// // IEEE: [ net_port_header | variable_port_header ] '.' port_identifier '(' [ expression ] ')'
// // IEEE: [ variable_port_header ] port_identifier { variable_dimension } [ '=' constant_expression ]
// // Substitute net_port_header = [ port_direction ] net_port_type
@@ -852,11 +863,16 @@ port<nodep>: // ==IEEE: port
//
// // Note implicit rules looks just line declaring additional followon port
// // No VARDECL("port") for implicit, as we don't want to declare variables for them
//UNSUP portDirNetE data_type '.' portSig '(' portAssignExprE ')' sigAttrListE { UNSUP }
//UNSUP portDirNetE yVAR data_type '.' portSig '(' portAssignExprE ')' sigAttrListE { UNSUP }
//UNSUP portDirNetE yVAR implicit_type '.' portSig '(' portAssignExprE ')' sigAttrListE { UNSUP }
//UNSUP portDirNetE signingE rangeList '.' portSig '(' portAssignExprE ')' sigAttrListE { UNSUP }
//UNSUP portDirNetE /*implicit*/ '.' portSig '(' portAssignExprE ')' sigAttrListE { UNSUP }
//UNSUP portDirNetE data_type '.' portSig '(' portAssignExprE ')' sigAttrListE
//UNSUP { UNSUP }
//UNSUP portDirNetE yVAR data_type '.' portSig '(' portAssignExprE ')' sigAttrListE
//UNSUP { UNSUP }
//UNSUP portDirNetE yVAR implicit_type '.' portSig '(' portAssignExprE ')' sigAttrListE
//UNSUP { UNSUP }
//UNSUP portDirNetE signingE rangeList '.' portSig '(' portAssignExprE ')' sigAttrListE
//UNSUP { UNSUP }
//UNSUP portDirNetE /*implicit*/ '.' portSig '(' portAssignExprE ')' sigAttrListE
//UNSUP { UNSUP }
//
portDirNetE data_type portSig variable_dimensionListE sigAttrListE
{ $$=$3; VARDTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); }
@@ -955,6 +971,7 @@ program_generate_item<nodep>: // ==IEEE: program_generate_item
loop_generate_construct { $$ = $1; }
| conditional_generate_construct { $$ = $1; }
| generate_region { $$ = $1; }
//UNSUP elaboration_system_task { $$ = $1; }
;
//************************************************
@@ -977,7 +994,7 @@ genvar_identifierDecl<varp>: // IEEE: genvar_identifier (for declaration)
local_parameter_declaration<nodep>: // IEEE: local_parameter_declaration
// // See notes in parameter_declaration
local_parameter_declarationFront list_of_param_assignments ';' { $$ = $2; }
local_parameter_declarationFront list_of_param_assignments { $$ = $2; }
;
parameter_declaration<nodep>: // IEEE: parameter_declaration
@@ -1471,7 +1488,7 @@ non_port_module_item<nodep>: // ==IEEE: non_port_module_item
| yaSCDTOR { $$ = new AstScDtor($<fl>1,*$1); }
| yVL_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::INLINE_MODULE); }
| yVL_NO_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_MODULE); }
| yVL_PUBLIC_MODULE { $$ = new AstPragma($1,AstPragmaType::PUBLIC_MODULE); }
| yVL_PUBLIC_MODULE { $$ = new AstPragma($1,AstPragmaType::PUBLIC_MODULE); v3Global.dpi(true); }
;
module_or_generate_item<nodep>: // ==IEEE: module_or_generate_item
@@ -1480,7 +1497,8 @@ module_or_generate_item<nodep>: // ==IEEE: module_or_generate_item
// // IEEE: gate_instantiation + udp_instantiation + module_instantiation
// // not here, see etcInst in module_common_item
// // We joined udp & module definitions, so this goes here
| table { $$ = $1; }
| combinational_body { $$ = $1; }
// // This module_common_item shared with interface_or_generate_item:module_common_item
| module_common_item { $$ = $1; }
;
@@ -1530,6 +1548,11 @@ module_or_generate_item_declaration<nodep>: // ==IEEE: module_or_generate_item_d
//************************************************
// Generates
//
// Way down in generate_item is speced a difference between module,
// interface and checker generates. modules and interfaces are almost
// identical (minus DEFPARAMs) so we overlap them. Checkers are too
// different, so we copy all rules for checkers.
generate_region<nodep>: // ==IEEE: generate_region
yGENERATE genItemList yENDGENERATE { $$ = new AstGenerate($1, $2); }
@@ -1554,13 +1577,13 @@ genItemBegin<nodep>: // IEEE: part of generate_block
;
genItemOrBegin<nodep>: // Not in IEEE, but our begin isn't under generate_item
generate_item { $$ = $1; }
| genItemBegin { $$ = $1; }
~c~generate_item { $$ = $1; }
| ~c~genItemBegin { $$ = $1; }
;
genItemList<nodep>:
genItemOrBegin { $$ = $1; }
| genItemList genItemOrBegin { $$ = $1->addNextNull($2); }
~c~genItemOrBegin { $$ = $1; }
| ~c~genItemList ~c~genItemOrBegin { $$ = $1->addNextNull($2); }
;
generate_item<nodep>: // IEEE: module_or_interface_or_generate_item
@@ -1568,16 +1591,19 @@ generate_item<nodep>: // IEEE: module_or_interface_or_generate_item
module_or_generate_item { $$ = $1; }
// // Only legal when in a generate under an interface
//UNSUP interface_or_generate_item { $$ = $1; }
// // IEEE: checker_or_generate_item
// // Only legal when in a generate under a checker
// // so below in c_generate_item
;
conditional_generate_construct<nodep>: // ==IEEE: conditional_generate_construct
yCASE '(' expr ')' case_generate_itemListE yENDCASE { $$ = new AstGenCase($1,$3,$5); }
yCASE '(' expr ')' ~c~case_generate_itemListE yENDCASE { $$ = new AstGenCase($1,$3,$5); }
| yIF '(' expr ')' generate_block_or_null %prec prLOWER_THAN_ELSE { $$ = new AstGenIf($1,$3,$5,NULL); }
| yIF '(' expr ')' generate_block_or_null yELSE generate_block_or_null { $$ = new AstGenIf($1,$3,$5,$7); }
;
loop_generate_construct<nodep>: // ==IEEE: loop_generate_construct
yFOR '(' genvar_initialization ';' expr ';' genvar_iteration ')' generate_block_or_null
yFOR '(' genvar_initialization ';' expr ';' genvar_iteration ')' ~c~generate_block_or_null
{ // Convert BEGIN(...) to BEGIN(GENFOR(...)), as we need the BEGIN to hide the local genvar
AstBegin* lowerBegp = $9->castBegin();
if ($9 && !lowerBegp) $9->v3fatalSrc("Child of GENFOR should have been begin");
@@ -1633,8 +1659,8 @@ case_generate_itemListE<nodep>: // IEEE: [{ case_generate_itemList }]
;
case_generate_itemList<nodep>: // IEEE: { case_generate_itemList }
case_generate_item { $$=$1; }
| case_generate_itemList case_generate_item { $$=$1; $1->addNext($2); }
~c~case_generate_item { $$=$1; }
| ~c~case_generate_itemList ~c~case_generate_item { $$=$1; $1->addNext($2); }
;
case_generate_item<nodep>: // ==IEEE: case_generate_item
@@ -1719,11 +1745,11 @@ sigAttrList<nodep>:
sigAttr<nodep>:
yVL_CLOCK { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCK); }
| yVL_CLOCK_ENABLE { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCK_ENABLE); }
| yVL_PUBLIC { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC); }
| yVL_PUBLIC_FLAT { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT); }
| yVL_PUBLIC_FLAT_RD { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RD); }
| yVL_PUBLIC_FLAT_RW { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RW); }
| yVL_PUBLIC_FLAT_RW attr_event_control { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RW);
| yVL_PUBLIC { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC); v3Global.dpi(true); }
| yVL_PUBLIC_FLAT { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT); v3Global.dpi(true); }
| yVL_PUBLIC_FLAT_RD { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RD); v3Global.dpi(true); }
| yVL_PUBLIC_FLAT_RW { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RW); v3Global.dpi(true); }
| yVL_PUBLIC_FLAT_RW attr_event_control { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RW); v3Global.dpi(true);
$$ = $$->addNext(new AstAlwaysPublic($1,$2,NULL)); }
| yVL_ISOLATE_ASSIGNMENTS { $$ = new AstAttrOf($1,AstAttrType::VAR_ISOLATE_ASSIGNMENTS); }
| yVL_SC_BV { $$ = new AstAttrOf($1,AstAttrType::VAR_SC_BV); }
@@ -1806,6 +1832,7 @@ defparam_assignment<nodep>: // ==IEEE: defparam_assignment
// gate (strong0) [#(delay)] [name] (pins) [, (pins)...] ; // gate_instantiation
// program_id [#(params}] name ; // program_instantiation
// interface_id [#(params}] name ; // interface_instantiation
// checker_id name (pins) ; // checker_instantiation
etcInst<nodep>: // IEEE: module_instantiation + gate_instantiation + udp_instantiation
instDecl { $$ = $1; }
@@ -1940,7 +1967,7 @@ stmtBlock<nodep>: // IEEE: statement + seq_block + par_block
seq_block<nodep>: // ==IEEE: seq_block
// // IEEE doesn't allow declarations in unnamed blocks, but several simulators do.
// // So need begin's even if unnamed to scope variables down
// // So need AstBegin's even if unnamed to scope variables down
seq_blockFront blockDeclStmtList yEND endLabelE { $$=$1; $1->addStmtsp($2); SYMP->popScope($1); GRAMMARP->endLabel($<fl>4,$1,$4); }
| seq_blockFront /**/ yEND endLabelE { $$=$1; SYMP->popScope($1); GRAMMARP->endLabel($<fl>3,$1,$3); }
;
@@ -1964,9 +1991,10 @@ block_item_declarationList<nodep>: // IEEE: [ block_item_declaration ]
block_item_declaration<nodep>: // ==IEEE: block_item_declaration
data_declaration { $$ = $1; }
| local_parameter_declaration { $$ = $1; }
| local_parameter_declaration ';' { $$ = $1; }
| parameter_declaration ';' { $$ = $1; }
//UNSUP overload_declaration { $$ = $1; }
//UNSUP let_declaration { $$ = $1; }
;
stmtList<nodep>:
@@ -1988,6 +2016,8 @@ statement_item<nodep>: // IEEE: statement_item
foperator_assignment ';' { $$ = $1; }
//
// // IEEE: blocking_assignment
// // 1800-2009 restricts LHS of assignment to new to not have a range
// // This is ignored to avoid conflicts
//UNSUP fexprLvalue '=' class_new ';' { UNSUP }
//UNSUP fexprLvalue '=' dynamic_array_new ';' { UNSUP }
//
@@ -2058,6 +2088,7 @@ statement_item<nodep>: // IEEE: statement_item
| yFOR '(' for_initialization expr ';' for_stepE ')' stmtBlock
{ $$ = new AstBegin($1,"",$3); $3->addNext(new AstWhile($1, $4,$8,$6)); }
| yDO stmtBlock yWHILE '(' expr ')' ';' { $$ = $2->cloneTree(true); $$->addNext(new AstWhile($1,$5,$2));}
// // IEEE says array_identifier here, but dotted accepted in VMM and 1800-2009
//UNSUP yFOREACH '(' idClassForeach/*array_id[loop_variables]*/ ')' stmt { UNSUP }
//
// // IEEE: jump_statement
@@ -2286,6 +2317,14 @@ taskRef<parserefp>: // IEEE: part of tf_call
;
funcRef<parserefp>: // IEEE: part of tf_call
// // package_scope/hierarchical_... is part of expr, so just need ID
// // making-a id-is-a
// // ----------------- ------------------
// // tf_call tf_identifier expr (list_of_arguments)
// // method_call(post .) function_identifier expr (list_of_arguments)
// // property_instance property_identifier property_actual_arg
// // sequence_instance sequence_identifier sequence_actual_arg
// // let_expression let_identifier let_actual_arg
idDotted '(' list_of_argumentsE ')' { $$ = new AstParseRef($1->fileline(), AstParseRefExp::PX_FTASK, "", $1, new AstFuncRef($2, "", $3)); $$->start(true); }
| package_scopeIdFollows idDotted '(' list_of_argumentsE ')' { AstFuncRef* f=new AstFuncRef($3,"",$4); f->packagep($1); $$ = new AstParseRef($2->fileline(), AstParseRefExp::PX_FTASK, "", $2, f); $$->start(true); }
//UNSUP: idDotted is really just id to allow dotted method calls
@@ -2501,7 +2540,7 @@ tf_item_declaration<nodep>: // ==IEEE: tf_item_declaration
;
tf_item_declarationVerilator<nodep>: // Verilator extensions
yVL_PUBLIC { $$ = new AstPragma($1,AstPragmaType::PUBLIC_TASK); }
yVL_PUBLIC { $$ = new AstPragma($1,AstPragmaType::PUBLIC_TASK); v3Global.dpi(true); }
| yVL_NO_INLINE_TASK { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_TASK); }
;
@@ -2709,6 +2748,9 @@ expr<nodep>: // IEEE: part of expression/constant_expression/primary
// // method_call:array_method requires a '.'
//UNSUP ~l~expr '.' array_methodNoRoot { UNSUP }
//
// // IEEE: let_expression
// // see funcRef
//
// // IEEE: '(' mintypmax_expression ')'
| ~noPar__IGNORE~'(' expr ')' { $$ = $2; }
//UNSUP ~noPar__IGNORE~'(' expr ':' expr ':' expr ')' { $$ = $4; }
@@ -2766,7 +2808,7 @@ exprOkLvalue<nodep>: // expression that's also OK to use as a variable_lvalue
// // IEEE: concatenation/constant_concatenation
| '{' cateList '}' { $$ = $2; }
// // IEEE: assignment_pattern_expression
// // IEEE: [ assignment_pattern_expression_type ] == [ ps_type_id /ps_paremeter_id]
// // IEEE: [ assignment_pattern_expression_type ] == [ ps_type_id /ps_paremeter_id/data_type]
// // We allow more here than the spec requires
//UNSUP ~l~exprScope assignment_pattern { UNSUP }
//UNSUP data_type assignment_pattern { UNSUP }
@@ -2778,6 +2820,7 @@ exprOkLvalue<nodep>: // expression that's also OK to use as a variable_lvalue
exprScope<nodep>: // scope and variable for use to inside an expression
// // Here we've split method_call_root | implicit_class_handle | class_scope | package_scope
// // from the object being called and let expr's "." deal with resolving it.
// // (note method_call_root was simplified to require a primary in 1800-2009)
//
// // IEEE: [ implicit_class_handle . | class_scope | package_scope ] hierarchical_identifier select
// // Or method_call_body without parenthesis
@@ -3033,7 +3076,7 @@ strengthSpecE: // IEEE: drive_strength + pullup_strength + pulldown_strength +
//************************************************
// Tables
table<nodep>: // IEEE: combinational_body + sequential_body
combinational_body<nodep>: // IEEE: combinational_body + sequential_body
yTABLE tableEntryList yENDTABLE { $$ = new AstUdpTable($1,$2); }
;
@@ -3131,6 +3174,7 @@ idClassSel<parserefp>: // Misc Ref to dotted, and/or arrayed, and/or bit-range
//UNSUP ySUPER '.' idDotted { UNSUP }
//UNSUP yTHIS '.' ySUPER '.' idDotted { UNSUP }
// // Expanded: package_scope idDotted
//UNSUP class_scopeIdFollows idDotted { UNSUP }
//UNSUP package_scopeIdFollows idDotted { UNSUP }
;
@@ -3206,6 +3250,8 @@ labeledStmt<nodep>:
concurrent_assertion_item<nodep>: // IEEE: concurrent_assertion_item
concurrent_assertion_statement { $$ = $1; }
| id/*block_identifier*/ ':' concurrent_assertion_statement { $$ = new AstBegin($2,*$1,$3); }
// // IEEE: checker_instantiation
// // identical to module_instantiation; see etcInst
;
concurrent_assertion_statement<nodep>: // ==IEEE: concurrent_assertion_statement
@@ -3252,12 +3298,15 @@ ps_type<dtypep>: // IEEE: ps_parameter_identifier | ps_type_identifier
// Even though we looked up the type and have a AstNode* to it,
// we can't fully resolve it because it may have been just a forward definition.
package_scopeIdFollowsE yaID__aTYPE { $$ = new AstRefDType($<fl>2, *$2); $$->castRefDType()->packagep($1); }
// // Simplify typing - from ps_covergroup_identifier
//UNSUP package_scopeIdFollowsE yaID__aCOVERGROUP { $<fl>$=$<fl>1; $$=$1+$2; }
;
//=== Below rules assume special scoping per above
package_scopeIdFollowsE<packagep>: // IEEE: [package_scope]
// // IMPORTANT: The lexer will parse the following ID to be in the found package
// // class_qualifier := [ yLOCAL '::' ] [ implicit_class_handle '.' class_scope ]
/* empty */ { $$ = NULL; }
| package_scopeIdFollows { $$ = $1; }
;
@@ -3269,6 +3318,8 @@ package_scopeIdFollows<packagep>: // IEEE: package_scope
/*cont*/ yP_COLONCOLON { $$ = GRAMMARP->unitPackage($<fl>1); }
| yaID__aPACKAGE { SYMP->nextId($<scp>1); }
/*cont*/ yP_COLONCOLON { $$ = $<scp>1->castPackage(); }
//UNSUP yLOCAL__COLONCOLON { PARSEP->symTableNextId($<scp>1); }
//UNSUP /*cont*/ yP_COLONCOLON { UNSUP }
;
//************************************************
+3 -19
View File
@@ -58,12 +58,8 @@ module t (/*AUTOARG*/
else if (cnt[30:2]== 2) array_bg <= '{default:13};
else if (cnt[30:2]== 3) array_bg <= '{0:4, 1:5, 2:6, 3:7};
else if (cnt[30:2]== 4) array_bg <= '{2:15, default:13};
else if (cnt[30:2]== 5) array_bg <= '{WA { {WB/2 {2'b10}} }};
else if (cnt[30:2]== 6) array_bg <= '{WA { {3'b101, {WB/2-1{2'b10}}} }};
else if (cnt[30:2]== 7) array_bg <= '{WA { {WB/2-1{2'b10}} }};
else if (cnt[30:2]== 8) array_bg [WA/2-1:0 ] <= '{WA/2{ {WB/2 {2'b10}} }};
else if (cnt[30:2]== 9) array_bg [WA -1:WA/2] <= '{WA/2{ {WB/2 {2'b01}} }};
else if (cnt[30:2]==10) array_bg <= '{cnt+0, cnt+1, cnt+2, cnt+3};
else if (cnt[30:2]== 5) array_bg <= '{WA { {WB {2'b10}} }};
else if (cnt[30:2]== 6) array_bg <= '{cnt+0, cnt+1, cnt+2, cnt+3};
end else if (cnt[1:0]==2'd2) begin
// chack array agains expected value
if (cnt[30:2]== 0) begin if (array_bg !== 16'b0000000000000000) begin $display("%b", array_bg); $stop(); end end
@@ -72,11 +68,7 @@ module t (/*AUTOARG*/
else if (cnt[30:2]== 3) begin if (array_bg !== 16'b0111011001010100) begin $display("%b", array_bg); $stop(); end end
else if (cnt[30:2]== 4) begin if (array_bg !== 16'b1101111111011101) begin $display("%b", array_bg); $stop(); end end
else if (cnt[30:2]== 5) begin if (array_bg !== 16'b1010101010101010) begin $display("%b", array_bg); $stop(); end end
else if (cnt[30:2]== 6) begin if (array_bg !== 16'b0110011001100110) begin $display("%b", array_bg); $stop(); end end
else if (cnt[30:2]== 7) begin if (array_bg !== 16'b0010001000100010) begin $display("%b", array_bg); $stop(); end end
else if (cnt[30:2]== 8) begin if (array_bg !== 16'b1010101000000000) begin $display("%b", array_bg); $stop(); end end
else if (cnt[30:2]== 9) begin if (array_bg !== 16'b0000000010101010) begin $display("%b", array_bg); $stop(); end end
else if (cnt[30:2]==10) begin if (array_bg !== 16'b1001101010111100) begin $display("%b", array_bg); $stop(); end end
else if (cnt[30:2]== 6) begin if (array_bg !== 16'b1001101010111100) begin $display("%b", array_bg); $stop(); end end
end
// little endian
@@ -102,10 +94,6 @@ module t (/*AUTOARG*/
else if (cnt[30:2]== 3) array_lt <= '{3:4, 2:5, 1:6, 0:7};
else if (cnt[30:2]== 4) array_lt <= '{1:15, default:13};
else if (cnt[30:2]== 5) array_lt <= '{WA { {WB/2 {2'b10}} }};
else if (cnt[30:2]== 6) array_lt <= '{WA { {3'b101, {WB/2-1{2'b10}}} }};
else if (cnt[30:2]== 7) array_lt <= '{WA { {WB/2-1{2'b10}} }};
else if (cnt[30:2]== 8) array_lt [0 :WA/2-1] <= '{WA/2{ {WB/2 {2'b10}} }};
else if (cnt[30:2]== 9) array_lt [WA/2:WA -1] <= '{WA/2{ {WB/2 {2'b01}} }};
else if (cnt[30:2]==10) array_lt <= '{cnt+0, cnt+1, cnt+2, cnt+3};
end else if (cnt[1:0]==2'd2) begin
// chack array agains expected value
@@ -115,10 +103,6 @@ module t (/*AUTOARG*/
else if (cnt[30:2]== 3) begin if (array_lt !== 16'b0111011001010100) begin $display("%b", array_lt); $stop(); end end
else if (cnt[30:2]== 4) begin if (array_lt !== 16'b1101111111011101) begin $display("%b", array_lt); $stop(); end end
else if (cnt[30:2]== 5) begin if (array_lt !== 16'b1010101010101010) begin $display("%b", array_lt); $stop(); end end
else if (cnt[30:2]== 6) begin if (array_lt !== 16'b0110011001100110) begin $display("%b", array_lt); $stop(); end end
else if (cnt[30:2]== 7) begin if (array_lt !== 16'b0010001000100010) begin $display("%b", array_lt); $stop(); end end
else if (cnt[30:2]== 8) begin if (array_lt !== 16'b1010101000000000) begin $display("%b", array_lt); $stop(); end end
else if (cnt[30:2]== 9) begin if (array_lt !== 16'b0000000010101010) begin $display("%b", array_lt); $stop(); end end
else if (cnt[30:2]==10) begin if (array_lt !== 16'b1001101010111100) begin $display("%b", array_lt); $stop(); end end
end
@@ -24,6 +24,10 @@ module t (/*AUTOARG*/
integer cnt = 0;
// msg926
logic [3:0][31:0] packedArray;
initial packedArray <= '0;
// event counter
always @ (posedge clk) begin
cnt <= cnt + 1;
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+34
View File
@@ -0,0 +1,34 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2012 by Chandan Egbert.
// See bug569
module t();
`ifdef T_FUNC_V_NOINL
// verilator no_inline_module
`endif
level1 ul1();
initial ul1.doit(4'b0);
endmodule
module level1();
`ifdef T_FUNC_V_NOINL
// verilator no_inline_module
`endif
level2 ul2();
task doit(input logic [3:0] v);
ul2.mem = v;
$write("*-* All Finished *-*\n");
$finish;
endtask
endmodule
module level2();
`ifdef T_FUNC_V_NOINL
// verilator no_inline_module
`endif
logic [3:0] mem;
endmodule
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
top_filename("t/t_func_v.v");
compile (
v_flags2 => ['+define+T_FUNC_V_NOINL',],
);
execute (
check_finished=>1,
);
ok(1);
1;
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
v_flags2 => ["--lint-only"],
make_top_shell => 0,
make_main => 0,
verilator_make_gcc => 0,
);
ok(1);
1;
+24
View File
@@ -0,0 +1,24 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2012 by Chandan Egbert.
module sub();
endmodule
module t(input logic a, input logic b,
output logic x, output logic y);
always_comb begin
integer i;
x = a;
end
sub u0();
always_comb begin
integer j;
y = b;
end
endmodule
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
verilator_flags2 => ["--x-initial-edge"]
);
execute (
check_finished=>1,
);
ok(1);
1;
+101
View File
@@ -0,0 +1,101 @@
// DESCRIPTION: Verilator: initial edge issue
//
// The module initial_edge drives the output "res" high when the reset signal,
// rst, goes high.
//
// The module initial_edge_n drives the output "res_n" high when the reset
// signal, rst_n, goes low.
//
// For 4-state simulators, that edge occurs when the initial value of rst_n,
// X, goes to zero. However, by default for Verilator, being 2-state, the
// initial value is zero, so no edge is seen.
//
// This is not a bug in verilator (it is bad design to rely on an edge
// transition from an unitialized signal), but the problem is that there are
// quite a few instances of code out there that seems to be dependent on this
// behaviour to get out of reset.
//
// The Verilator --x-initial-edge flag causes these initial edges to trigger,
// thus matching the behaviour of a 4-state simulator. This is reportedly also
// the behaviour of commercial cycle accurate modelling tools as well.
//
// This file ONLY is placed into the Public Domain, for any use, without
// warranty, 2012 by Wilson Snyder.
`timescale 1ns/1ns
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
wire res;
wire res_n;
reg rst;
reg rst_n;
integer count = 0;
initial_edge i_edge (.res (res),
.rst (rst));
initial_edge_n i_edge_n (.res_n (res_n),
.rst_n (rst_n));
// run for 3 cycles, with one cycle of reset.
always @(posedge clk) begin
rst <= (count == 0) ? 1 : 0;
rst_n <= (count == 0) ? 0 : 1;
if (count == 3) begin
if ((res == 1) && (res_n == 1)) begin
$write ("*-* All Finished *-*\n");
$finish;
end
else begin
`ifdef TEST_VERBOSE
$write ("FAILED: res = %b, res_n = %b\n", res, res_n);
`endif
$stop;
end
end
count = count + 1;
end
endmodule
module initial_edge_n (res_n,
rst_n);
output res_n;
input rst_n;
reg res_n = 1'b0;
always @(negedge rst_n) begin
if (rst_n == 1'b0) begin
res_n <= 1'b1;
end
end
endmodule // initial_edge_n
module initial_edge (res,
rst);
output res;
input rst;
reg res = 1'b0;
always @(posedge rst) begin
if (rst == 1'b1) begin
res <= 1'b1;
end
end
endmodule // initial_edge
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
top_filename("t/t_initial_edge.v");
# This works with other simulators, we we don't run it for them. It should
# fail with Verilator if --x-initial-edge is not specified.
$Self->{vlt} or $Self->skip("Verilator only test");
compile (
);
execute (
fails => 1,
);
ok(1);
1;
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
ok(1);
1;
+32
View File
@@ -0,0 +1,32 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2012 by Wilson Snyder.
module t;
sub #(10,11,12,13) sub ();
endmodule
module sub ();
parameter A = 0;
parameter B = 1;
ip ip();
parameter C = 2;
parameter D = 3;
initial begin
if (A!=10) $stop;
if (B!=11) $stop;
if (C!=12) $stop;
if (D!=13) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
module ip;
endmodule
+2
View File
@@ -40,6 +40,8 @@ module t (/*AUTOARG*/
if (5'sb10110>>>2 != 5'sb11101) $stop;
if (5'sb10110<<2 != 5'sb11000) $stop;
if (5'sb10110<<<2 != 5'sb11000) $stop;
// Allow >64 bit shifts if the shift amount is a constant
if ((64'sh458c2de282e30f8b >> 68'sh4) !== 64'sh0458c2de282e30f8) $stop;
end
if (cyc==2) begin
amt <= 32'd28;
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+37
View File
@@ -0,0 +1,37 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2012 by Wilson Snyder.
package TEST_TYPES;
typedef struct packed {
logic stuff;
} a_struct_t;
endpackage // TEST_TYPES
module t(clk);
input clk;
TEST_TYPES::a_struct_t [3:0] a_out;
sub sub (.a_out);
always @ (posedge clk) begin
if (a_out[0] != 1'b0) $stop;
if (a_out[1] != 1'b1) $stop;
if (a_out[2] != 1'b0) $stop;
if (a_out[3] != 1'b1) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
module sub(a_out);
parameter n = 4;
output TEST_TYPES::a_struct_t [n-1:0] a_out;
always_comb begin
for (int i=0;i<n;i++)
a_out[i].stuff = i[0];
end
endmodule
// Local Variables:
// verilog-typedef-regexp: "_t$"
// End:
+15
View File
@@ -5,12 +5,23 @@
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
`ifdef VERILATOR
//We call it via $c so we can verify DPI isn't required - see bug572
`else
import "DPI-C" context function integer mon_check();
`endif
module t (/*AUTOARG*/
// Inputs
clk
);
`ifdef VERILATOR
`systemc_header
extern "C" int mon_check();
`verilog
`endif
input clk;
reg onebit /*verilator public_flat_rw @(posedge clk) */;
@@ -29,7 +40,11 @@ module t (/*AUTOARG*/
// Test loop
initial begin
onebit = 1'b0;
`ifdef VERILATOR
status = $c32("mon_check()");
`else
status = mon_check();
`endif
if (status!=0) begin
$write("%%Error: t_vpi_var.cpp:%0d: C Test failed\n", status);
$stop;