mirror of
https://github.com/verilator/verilator.git
synced 2026-10-05 17:43:31 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8108b97050 | ||
|
|
a1c3491dea | ||
|
|
8bba96a84e | ||
|
|
6cd9b25a53 | ||
|
|
0431b1909c | ||
|
|
907665e2e8 | ||
|
|
61e8836fbd | ||
|
|
0e921b5dff | ||
|
|
7ef37d6e17 | ||
|
|
dce227684a | ||
|
|
158e112752 | ||
|
|
ec992c7f5e | ||
|
|
e7d63c7644 | ||
|
|
6464e8fee6 | ||
|
|
047d66a657 | ||
|
|
55c23360d9 | ||
|
|
c378d32c85 | ||
|
|
3d9540c58c |
@@ -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
@@ -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
@@ -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
@@ -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 "+"
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 }
|
||||
;
|
||||
|
||||
//************************************************
|
||||
|
||||
@@ -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;
|
||||
|
||||
Executable
+18
@@ -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;
|
||||
@@ -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
|
||||
Executable
+21
@@ -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;
|
||||
Executable
+18
@@ -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;
|
||||
@@ -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
|
||||
Executable
+19
@@ -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;
|
||||
@@ -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
|
||||
Executable
+24
@@ -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;
|
||||
Executable
+14
@@ -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;
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
Executable
+18
@@ -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;
|
||||
@@ -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:
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user