Compare commits

...
33 Commits
Author SHA1 Message Date
Wilson Snyder 813d62005d Version bump 2016-10-14 19:42:18 -04:00
Wilson Snyder 411de9bddf Commentary. 2016-09-30 18:16:56 -04:00
Wilson Snyder bd28945374 Untabify 2016-09-30 18:14:42 -04:00
Wilson Snyder 1e4c3751e1 Support foreach, bug1078. 2016-09-19 22:00:13 -04:00
Wilson Snyder 5b6f47cd0f If VM_PARALLEL_BUILDS=1, use OPT_FAST and OPT_SLOW. 2016-09-19 19:31:09 -04:00
Wilson Snyder bec8c5bf4c Commentary 2016-09-19 17:55:43 -04:00
Johan Bjork 15495bb200 Improve Verilation performance on trace duplicates, msg2017.
Signed-off-by: Wilson Snyder <[email protected]>
2016-09-19 17:54:42 -04:00
Wilson Snyder 999f278971 Fix concats with wide width, bug1088 continued. 2016-09-16 18:54:28 -04:00
Wilson Snyder 7ca1d35a4e New test. 2016-09-16 18:15:32 -04:00
Wilson Snyder 2117fe414e Fix error on wide numbers that represent shifts, bug1088. 2016-09-14 20:27:20 -04:00
Wilson Snyder 7d8c51181d With --no-decoration also shrink output code indents. 2016-09-13 22:53:09 -04:00
Wilson Snyder c30211cb27 Add --no-decoration to remove output comments, msg2015. 2016-09-13 22:28:07 -04:00
Johan Bjork 901da118e5 Internals: Move prettyName invocation to after option checks in trace and coverage
Signed-off-by: Wilson Snyder <[email protected]>
2016-09-12 21:52:40 -04:00
Wilson Snyder f11757e43a Fix error on wide shift, msg2005. 2016-09-12 18:31:45 -04:00
Wilson Snyder 3f143317a6 Add error on DPI functions > 32 bits, msg1995. 2016-09-10 08:14:17 -04:00
Wilson Snyder 45d7312dfc Improve Verilation performance on internal strings, msg1975. 2016-09-08 22:04:14 -04:00
Wilson Snyder 26774eb045 Fix error on wide numbers that represent small msb/lsb, msg1991. 2016-09-08 21:30:35 -04:00
Wilson Snyder 6789d247e2 Fix SystemC compiles with VPI, bug1081. 2016-08-23 18:05:29 -04:00
Johan Bjork 462bc3d707 Clean up disabled tests for bugs already fixed.
Signed-off-by: Wilson Snyder <[email protected]>
2016-08-23 06:45:25 -04:00
Wilson Snyder e1755ea6a8 devel release 2016-07-30 10:18:52 -04:00
Wilson Snyder b4a7e4697e Version bump 2016-07-30 10:10:35 -04:00
Wilson Snyder cd61b1d045 Usage check. 2016-07-30 10:05:55 -04:00
Wilson Snyder 24dc36ba4c Fix comparison of unpacked arrays, bug1071. 2016-07-23 16:58:30 -04:00
Wilson Snyder e8e4f1777d Internals: Add cloneType method. Unused - for next checkin. 2016-07-23 16:54:36 -04:00
Wilson Snyder ae38a26af3 Internals: Cleanup some slice code. No functional change. 2016-07-21 23:07:22 -04:00
Wilson Snyder 8ee94dd7aa Tests: Smaller verilated test. 2016-07-21 23:03:54 -04:00
Wilson Snyder e741a29d36 Commentary 2016-07-13 22:51:40 -04:00
Wilson Snyder be1d275151 Fix Ubuntu 16.04 test failures. 2016-07-12 21:43:16 -04:00
David Horton 31c9e26e2e Fix compiler warning in GCC 6.
Signed-off-by: Wilson Snyder <[email protected]>
2016-07-09 04:09:34 -04:00
Wilson Snyder 20ed1ada03 Spelling fixes. 2016-07-09 03:31:22 -04:00
Wilson Snyder 891214fa72 Fix enum values of 11-16 bits wide using .next/.prev, bug1062. 2016-06-15 22:46:34 -04:00
Wilson Snyder e819e285e2 Fix false warnings on non-power-2 enums using .next/.prev. 2016-06-15 20:13:52 -04:00
Wilson Snyder 171c175e54 devel release 2016-05-18 21:15:33 -04:00
61 changed files with 1240 additions and 359 deletions
+32 -2
View File
@@ -1,7 +1,37 @@
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!
The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 3.888 2016-10-14
** Support foreach, bug1078. [Xuan Guo]
*** Add --no-decoration to remove output comments, msg2015. [Frederic Requin]
*** If VM_PARALLEL_BUILDS=1, use OPT_FAST and OPT_SLOW. [Frederic Requin]
Set VM_DEFAULT_RULES=0 for old behavior.
**** Add error on DPI functions > 32 bits, msg1995. [Elliot Mednick]
**** Fix SystemC compiles with VPI, bug1081. [Arthur Kahlich]
**** Fix error on wide numbers that represent shifts, msg1991, bug1088. [Mandy Xu]
**** Improve Verilation performance on internal strings, msg1975. [Johan Bjork]
**** Improve Verilation performance on trace duplicates, bug1090. [Johan Bjork]
* Verilator 3.886 2016-07-30
**** Fix enum values of 11-16 bits wide using .next/.prev, bug1062. [Brian Flachs]
**** Fix false warnings on non-power-2 enums using .next/.prev.
**** Fix comparison of unpacked arrays, bug1071. [Andrew Bardsley]
**** Fix compiler warning in GCC 6. [David Horton]
* Verilator 3.884 2016-05-18
+165 -151
View File
@@ -19,8 +19,8 @@ require 5.006_001;
use warnings;
BEGIN {
if ($ENV{DIRPROJECT} && $ENV{DIRPROJECT_PERL_BOOT}) {
# Magic to allow author testing of perl packages in local directory
require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT};
# Magic to allow author testing of perl packages in local directory
require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT};
}
}
@@ -71,16 +71,16 @@ foreach my $sw (@ARGV) {
Getopt::Long::config ("no_auto_abbrev","pass_through");
if (! GetOptions (
# Major operating modes
"help" => \&usage,
"debug:s" => \&debug,
# "version!" => \&version, # Also passthru'ed
# Switches
"gdb!" => \$opt_gdb,
"gdbbt!" => \$opt_gdbbt,
# Additional parameters
"<>" => sub {}, # Ignored
)) {
# Major operating modes
"help" => \&usage,
"debug:s" => \&debug,
# "version!" => \&version, # Also passthru'ed
# Switches
"gdb!" => \$opt_gdb,
"gdbbt!" => \$opt_gdbbt,
# Additional parameters
"<>" => sub {}, # Ignored
)) {
pod2usage(-exitstatus=>2, -verbose=>0);
}
@@ -92,22 +92,22 @@ if ($opt_gdbbt && !gdb_works()) {
if ($opt_gdb) {
# Generic GDB interactive
run (("gdb"||$ENV{VERILATOR_GDB})
." ".verilator_bin()
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
." -ex 'set width 0'"
." -ex 'bt'");
." ".verilator_bin()
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
." -ex 'set width 0'"
." -ex 'bt'");
} elsif ($opt_gdbbt && $Debug) {
# Run under GDB to get gdbbt
run ("gdb"
." ".verilator_bin()
." --batch --quiet --return-child-result"
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
." -ex 'set width 0'"
." -ex 'bt'");
." ".verilator_bin()
." --batch --quiet --return-child-result"
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
." -ex 'set width 0'"
." -ex 'bt'");
} else {
# Normal, non gdb
run (verilator_bin()
." ".join(' ',@Opt_Verilator_Sw));
." ".join(' ',@Opt_Verilator_Sw));
}
#----------------------------------------------------------------------
@@ -130,23 +130,23 @@ sub verilator_bin {
my $bin = "";
# Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
my $basename = ($ENV{VERILATOR_BIN}
|| ($Debug ? "verilator_bin_dbg" : "verilator_bin"));
|| ($Debug ? "verilator_bin_dbg" : "verilator_bin"));
if (defined($ENV{VERILATOR_ROOT})) {
my $dir = $ENV{VERILATOR_ROOT};
if (-x "$dir/bin/$basename") { # From a "make install" into VERILATOR_ROOT
$bin = "$dir/bin/$basename";
} else {
$bin = "$dir/$basename"; # From pointing to kit directory
}
my $dir = $ENV{VERILATOR_ROOT};
if (-x "$dir/bin/$basename") { # From a "make install" into VERILATOR_ROOT
$bin = "$dir/bin/$basename";
} else {
$bin = "$dir/$basename"; # From pointing to kit directory
}
} else {
if (-x "$RealBin/$basename") {
$bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
} else {
$bin = $basename; # Find in PATH
}
# Note we don't look under bin/$basename which would be right if running
# in the kit dir. Running that would likely break, since
# VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
if (-x "$RealBin/$basename") {
$bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
} else {
$bin = $basename; # Find in PATH
}
# Note we don't look under bin/$basename which would be right if running
# in the kit dir. Running that would likely break, since
# VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
}
return $bin;
}
@@ -158,10 +158,10 @@ sub verilator_bin {
sub gdb_works {
$! = undef; # Cleanup -x
system("gdb /bin/echo"
." --batch-silent --quiet --return-child-result"
." -ex 'run -n'" # `echo -n`
." -ex 'set width 0'"
." -ex 'bt'");
." --batch-silent --quiet --return-child-result"
." -ex 'run -n'" # `echo -n`
." -ex 'set width 0'"
." -ex 'bt'");
my $status = $?;
return $status==0;
}
@@ -174,23 +174,23 @@ sub run {
system($command);
my $status = $?;
if ($status) {
if ($! =~ /no such file or directory/i) {
warn "%Error: verilator: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
}
if ($Debug) { # For easy rerunning
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
warn "%Error: $command\n";
}
if ($status & 127) {
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
warn "%Error: Verilator internal fault, sorry. Consider trying --debug --gdbbt\n" if !$Debug;
} elsif (($status & 127) == 6) { # SIGABRT
warn "%Error: Verilator aborted. Consider trying --debug --gdbbt\n" if !$Debug;
} else {
warn "%Error: Verilator threw signal $status. Consider trying --debug --gdbbt\n" if !$Debug;
}
}
die "%Error: Command Failed $command\n";
if ($! =~ /no such file or directory/i) {
warn "%Error: verilator: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
}
if ($Debug) { # For easy rerunning
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
warn "%Error: $command\n";
}
if ($status & 127) {
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
warn "%Error: Verilator internal fault, sorry. Consider trying --debug --gdbbt\n" if !$Debug;
} elsif (($status & 127) == 6) { # SIGABRT
warn "%Error: Verilator aborted. Consider trying --debug --gdbbt\n" if !$Debug;
} else {
warn "%Error: Verilator threw signal $status. Consider trying --debug --gdbbt\n" if !$Debug;
}
}
die "%Error: Command Failed $command\n";
}
}
@@ -300,6 +300,7 @@ descriptions in the next sections for more information.
--Mdir <directory> Name of output object directory
--mod-prefix <topname> Name to prepend to lower classes
--no-clk <signal-name> Prevent marking specified signal as clock
--no-decoration Disable comments and symbol decorations
--no-pins64 Don't use vluint64_t's for 33-64 bit sigs
--no-skip-identical Disable skipping identical output
+notimingchecks Ignored
@@ -323,7 +324,7 @@ descriptions in the next sections for more information.
--public Debugging; see docs
-pvalue+<name>=<value> Overwrite toplevel parameter
--report-unoptflat Extra diagnostics for UNOPTFLAT
--savable Enable model save-restore
--savable Enable model save-restore
--sc Create SystemC output
--stats Create statistics file
--stats-vars Provide statistics on variables
@@ -493,7 +494,7 @@ RTL file to mark the signal directly.
=item --compiler I<compiler-name>
Enables tunings and work-arounds for the specified C++ compiler.
Enables tunings and workarounds for the specified C++ compiler.
=over 4
@@ -606,8 +607,8 @@ alias for GCC compatibility.
=item --debug
Select the debug built image of Verilator (if available), and enable more
internal assertions (equivelent to C<--debug-check>), debugging messages
(equivelent to C<--debugi 4>), and intermediate form dump files (equivilent
internal assertions (equivalent to C<--debug-check>), debugging messages
(equivalent to C<--debugi 4>), and intermediate form dump files (equivalent
to C<--dump-treei 3>).
=item --debug-check
@@ -798,7 +799,7 @@ show by default "t". With "--l2-name v" it will print "v".
=item --language I<value>
A synonym for C<--default-langauge>, for compatibility with other tools and
A synonym for C<--default-language>, for compatibility with other tools and
earlier versions of Verilator.
=item +libext+I<ext>+I<ext>...
@@ -843,6 +844,13 @@ the same as --prefix.
Prevent the specified signal from being marked as clock. See C<--clk>.
=item --no-decoration
When creating output Verilated code, minimize comments, whitespace, symbol
names and other decorative items, at the cost of greatly reduced
readability. This may assist C++ compile times. This will not typically
change the ultimate model's performance, but may in some cases.
=item --no-pins64
Backward compatible alias for "--pins-bv 33".
@@ -926,9 +934,10 @@ Backward compatible alias for "--pins-bv 65". Note that's a 65, not a 64.
Specifies SystemC inputs/outputs of greater than or equal to I<width> bits
wide should use sc_bv's instead of uint32/vluint64_t's. The default is
"--pins-bv 65". Versions before Verilator 3.671 defaulted to "--pins-bv
33". The more sc_bv is used, the worse for performance. Use the
"/*verilator sc_bv*/" attribute to select specific ports to be sc_bv.
"--pins-bv 65", and the value must be less than or equal to 65. Versions
before Verilator 3.671 defaulted to "--pins-bv 33". The more sc_bv is
used, the worse for performance. Use the "/*verilator sc_bv*/" attribute
to select specific ports to be sc_bv.
=item --pins-sc-uint
@@ -1327,7 +1336,7 @@ We'll compile this example into C++.
#include "Vour.h"
#include "verilated.h"
int main(int argc, char **argv, char **env) {
Verilated::commandArgs(argc, argv);
Verilated::commandArgs(argc, argv);
Vour* top = new Vour;
while (!Verilated::gotFinish()) { top->eval(); }
delete top;
@@ -1352,8 +1361,7 @@ section below for descriptions of some of the files that were created.
We then can compile it
cd obj_dir
make -j -f Vour.mk Vour
make -j -C obj_dir -f Vour.mk Vour
(Verilator included a default compile rule and link rule, since we used
--exe and passed a .cpp file on the Verilator command line. You can also
@@ -1361,7 +1369,6 @@ write your own compile rules, as we'll show in the SYSTEMC section.)
And now we run it
cd ..
obj_dir/Vour
And we get as output
@@ -1370,8 +1377,9 @@ And we get as output
- our.v:2: Verilog $finish
Really, you're better off writing a Makefile to do all this for you. Then,
when your source changes it will automatically run all of these steps. See
the test_c directory in the distribution for an example.
when your source changes it will automatically run all of these steps; to
aid this Verilator can create a makefile dependency file. See the test_c
directory in the distribution for an example.
=head1 EXAMPLE SYSTEMC EXECUTION
@@ -1392,7 +1400,7 @@ This is an example similar to the above, but using SystemC.
cat <<EOF >sc_main.cpp
#include "Vour.h"
int sc_main(int argc, char **argv) {
Verilated::commandArgs(argc, argv);
Verilated::commandArgs(argc, argv);
sc_clock clk ("clk",10, 0.5, 3, true);
Vour* top;
top = new Vour("top"); // SP_CELL (top, Vour);
@@ -1415,6 +1423,7 @@ Now we run Verilator on our little example.
We then can compile it
cd obj_dir
make -j -f Vour.mk Vour__ALL.a
make -j -f Vour.mk ../sc_main.o verilated.o
@@ -1520,42 +1529,42 @@ All output files are placed in the output directory name specified with the
Verilator creates the following files in the output directory:
{prefix}.mk // Make include file for compiling
{prefix}_classes.mk // Make include file with class names
{prefix}.mk // Make include file for compiling
{prefix}_classes.mk // Make include file with class names
For -cc and -sc mode, it also creates:
{prefix}.cpp // Top level C++ file
{prefix}.h // Top level header
{prefix}{each_verilog_module}.cpp // Lower level internal C++ files
{prefix}{each_verilog_module}.h // Lower level internal header files
{prefix}.cpp // Top level C++ file
{prefix}.h // Top level header
{prefix}{each_verilog_module}.cpp // Lower level internal C++ files
{prefix}{each_verilog_module}.h // Lower level internal header files
In certain optimization modes, it also creates:
{prefix}__Dpi.h // DPI import and export declarations
{prefix}__Inlines.h // Inline support functions
{prefix}__Slow.cpp // Constructors and infrequent routines
{prefix}__Syms.cpp // Global symbol table C++
{prefix}__Syms.h // Global symbol table header
{prefix}__Trace.cpp // Wave file generation code (--trace)
{prefix}__cdc.txt // Clock Domain Crossing checks (--cdc)
{prefix}__stats.txt // Statistics (--stats)
{prefix}__Dpi.h // DPI import and export declarations
{prefix}__Inlines.h // Inline support functions
{prefix}__Slow.cpp // Constructors and infrequent routines
{prefix}__Syms.cpp // Global symbol table C++
{prefix}__Syms.h // Global symbol table header
{prefix}__Trace.cpp // Wave file generation code (--trace)
{prefix}__cdc.txt // Clock Domain Crossing checks (--cdc)
{prefix}__stats.txt // Statistics (--stats)
It also creates internal files that can be mostly ignored:
{each_verilog_module}.vpp // Post-processed verilog (--debug)
{prefix}.flags_vbin // Verilator dependencies
{prefix}.flags_vpp // Pre-processor dependencies
{prefix}__verFiles.dat // Timestamps for skip-identical
{prefix}{misc}.d // Make dependencies (-MMD)
{prefix}{misc}.dot // Debugging graph files (--debug)
{prefix}{misc}.tree // Debugging files (--debug)
{each_verilog_module}.vpp // Post-processed verilog (--debug)
{prefix}.flags_vbin // Verilator dependencies
{prefix}.flags_vpp // Pre-processor dependencies
{prefix}__verFiles.dat // Timestamps for skip-identical
{prefix}{misc}.d // Make dependencies (-MMD)
{prefix}{misc}.dot // Debugging graph files (--debug)
{prefix}{misc}.tree // Debugging files (--debug)
After running Make, the C++ compiler should produce the following:
{prefix} // Final executable (w/--exe argument)
{prefix}__ALL.a // Library of all Verilated objects
{prefix}{misc}.o // Intermediate objects
{prefix} // Final executable (w/--exe argument)
{prefix}__ALL.a // Library of all Verilated objects
{prefix}{misc}.o // Intermediate objects
=head1 ENVIRONMENT
@@ -1650,46 +1659,47 @@ simulation executable.
The user must write the top level of the simulation. Here's a simple
example:
#include <verilated.h> // Defines common routines
#include "Vtop.h" // From Verilating "top.v"
#include <verilated.h> // Defines common routines
#include <iostream> // Need std::cout
#include "Vtop.h" // From Verilating "top.v"
Vtop *top; // Instantiation of module
Vtop *top; // Instantiation of module
vluint64_t main_time = 0; // Current simulation time
// This is a 64-bit integer to reduce wrap over issues and
// allow modulus. You can also use a double, if you wish.
vluint64_t main_time = 0; // Current simulation time
// This is a 64-bit integer to reduce wrap over issues and
// allow modulus. You can also use a double, if you wish.
double sc_time_stamp () { // Called by $time in Verilog
return main_time; // converts to double, to match
// what SystemC does
}
double sc_time_stamp () { // Called by $time in Verilog
return main_time; // converts to double, to match
// what SystemC does
}
int main(int argc, char** argv) {
Verilated::commandArgs(argc, argv); // Remember args
int main(int argc, char** argv) {
Verilated::commandArgs(argc, argv); // Remember args
top = new Vtop; // Create instance
top = new Vtop; // Create instance
top->reset_l = 0; // Set some inputs
top->reset_l = 0; // Set some inputs
while (!Verilated::gotFinish()) {
if (main_time > 10) {
top->reset_l = 1; // Deassert reset
}
if ((main_time % 10) == 1) {
top->clk = 1; // Toggle clock
}
if ((main_time % 10) == 6) {
top->clk = 0;
}
top->eval(); // Evaluate model
cout << top->out << endl; // Read a output
main_time++; // Time passes...
}
while (!Verilated::gotFinish()) {
if (main_time > 10) {
top->reset_l = 1; // Deassert reset
}
if ((main_time % 10) == 1) {
top->clk = 1; // Toggle clock
}
if ((main_time % 10) == 6) {
top->clk = 0;
}
top->eval(); // Evaluate model
cout << top->out << endl; // Read a output
main_time++; // Time passes...
}
top->final(); // Done simulating
// // (Though this example doesn't get here)
delete top;
}
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.
You call the eval() method to evaluate the model. When the simulation is
@@ -1919,8 +1929,8 @@ VerilatedVpi::callValueCbs().
...
while (time passes) {
...
topp->eval();
VerilatedVpi::callValueCbs();
topp->eval();
VerilatedVpi::callValueCbs();
}
@@ -1964,10 +1974,10 @@ underneath NC:
cd obj_dir
ncsc_run \
sc_main.cpp \
Vour__ALLcls.cpp \
Vour__ALLsup.cpp \
verilated.cpp
sc_main.cpp \
Vour__ALLcls.cpp \
Vour__ALLsup.cpp \
verilated.cpp
For larger designs you'll want to automate this using makefiles, which pull
the names of the .cpp files to compile in from the make variables generated
@@ -2484,12 +2494,12 @@ such as $stop, $finish and $display. That is, you cannot use hierarchical
references, events or similar features of the Verilog language. It also
simulates as Synopsys's Design Compiler would; namely a block of the form:
always @ (x) y = x & z;
always @ (x) y = x & z;
This will recompute y when there is even a potential for change in x or a
change in z, that is when the flops computing x or z evaluate (which is
what Design Compiler will synthesize.) A compliant simulator would only
calculate y if x changes. Use verilog-mode's /*AS*/ or Verilog 2001's
calculate y if x changes. Use Verilog-Mode's /*AS*/ or Verilog 2001's
always @* to reduce missing activity items. Avoid putting $displays in
combo blocks, as they may print multiple times when not desired, even on
compliant simulators as event ordering is not specified.
@@ -2572,7 +2582,7 @@ 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
code (particularly 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.
@@ -2625,7 +2635,7 @@ clock_enable*/ attribute.
=head2 Ranges must be big-bit-endian
Bit ranges must be numbered with the MSB being numbered greater or the same
as the LSB. Little-bit-endian busses [0:15] are not supported as they
as the LSB. Little-bit-endian buses [0:15] are not supported as they
aren't easily made compatible with C++.
=head2 Gate Primitives
@@ -2824,13 +2834,17 @@ when displaying all times, model wide.
=head1 ERRORS AND WARNINGS
Warnings may be disabled in two ways. First, when the warning is
Warnings may be disabled in three ways. First, when the warning is
printed it will include a warning code. Simply surround the offending
line with a warn_off/warn_on pair:
// verilator lint_off UNSIGNED
if (`DEF_THAT_IS_EQ_ZERO <= 3) $stop;
// verilator lint_on UNSIGNED
// verilator lint_off UNSIGNED
if (`DEF_THAT_IS_EQ_ZERO <= 3) $stop;
// verilator lint_on UNSIGNED
Second, warnings may be disabled using a configuration file with a lint_off
command. This is useful when a script is suppressing warnings and the
Verilog source should not be changed.
Warnings may also be globally disabled by invoking Verilator with the
C<-Wno-I<warning>> switch. This should be avoided, as it removes all
@@ -2924,10 +2938,10 @@ were used, the simulator would have to copy large arrays every cycle. (In
smaller loops, loop unrolling allows the delayed assignment to work, though
it's a bit slower than a non-delayed assignment.) Here's an example
always @ (posedge clk)
always @ (posedge clk)
if (~reset_l) begin
for (i=0; i<`ARRAY_SIZE; i++) begin
array[i] = 0; // Non-delayed for verilator
array[i] = 0; // Non-delayed for verilator
end
This message is only seen on large or complicated loops because Verilator
@@ -3385,9 +3399,9 @@ A recommended style for unused nets is to put at the bottom of a file code
similar to the following:
wire _unused_ok = &{1'b0,
sig_not_used_a,
sig_not_used_yet_b, // To be fixed
1'b0};
sig_not_used_a,
sig_not_used_yet_b, // To be fixed
1'b0};
The reduction AND and constant zeros mean the net will always be zero, so
won't use simulation time. The redundant leading and trailing zeros avoid
@@ -3424,11 +3438,11 @@ unwidthed. Verilator considers zero to be any width needed.
Concatenate leading zeros when doing arithmetic. In the statement
wire [5:0] plus_one = from[5:0] + 6'd1 + carry[0];
wire [5:0] plus_one = from[5:0] + 6'd1 + carry[0];
The best fix, which clarifies intent and will also make all tools happy is:
wire [5:0] plus_one = from[5:0] + 6'd1 + {5'd0,carry[0]};
wire [5:0] plus_one = from[5:0] + 6'd1 + {5'd0,carry[0]};
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
@@ -3626,7 +3640,7 @@ trace file if you want all data to land in the same output file.
tfp->open ("obj_dir/t_trace_ena_cc/simx.vcd");
...
sc_start(1);
...
...
tfp->close();
}
+1 -1
View File
@@ -6,7 +6,7 @@
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[3.884 2016-05-18])
AC_INIT([Verilator],[3.888 2016-10-14])
# When releasing, also update header of Changes file
AC_CONFIG_HEADER(src/config_build.h)
+1 -1
View File
@@ -1226,7 +1226,7 @@ VerilatedModule::VerilatedModule(const char* namep)
}
VerilatedModule::~VerilatedModule() {
if (m_namep) free((void*)m_namep); m_namep=NULL;
if (m_namep) { free((void*)m_namep); m_namep=NULL; }
}
//======================================================================
+15 -15
View File
@@ -43,8 +43,9 @@ VK_CPPFLAGS_ALWAYS += \
-I$(VERILATOR_ROOT)/include \
-I$(VERILATOR_ROOT)/include/vltstd \
-DVL_PRINTF=printf \
-DVM_TRACE=$(VM_TRACE) \
-DVM_COVERAGE=$(VM_COVERAGE) \
-DVM_SC=$(VM_SC) \
-DVM_TRACE=$(VM_TRACE) \
$(CFG_CXXFLAGS_NO_UNUSED) \
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
@@ -123,19 +124,10 @@ else
preproc:
endif
#######################################################################
##### SystemC w/o SystemPerl builds
ifeq ($(VM_SC),1)
LIBS += -lm -lstdc++
endif
#######################################################################
##### C/H builds
ifeq ($(VM_PCLI),1)
LIBS += -lm -lstdc++
endif
LIBS += -lm -lstdc++
#######################################################################
# Overall Objects Linking
@@ -171,16 +163,24 @@ $(VM_PREFIX)__ALL.a: $(VK_OBJS)
######################################################################
### Compile rules
#Default rule embedded in make: (Not defined so user makefiles can override it)
#.cpp.o:
# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
ifneq ($(VM_DEFAULT_RULES),0)
$(VM_PREFIX)__ALLsup.o: $(VM_PREFIX)__ALLsup.cpp
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $<
$(VM_PREFIX)__ALLcls.o: $(VM_PREFIX)__ALLcls.cpp
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
$(VM_PREFIX)%__Slow.o: $(VM_PREFIX)%__Slow.cpp
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $<
$(VM_PREFIX)%.o: $(VM_PREFIX)%.cpp
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
endif
#Default rule embedded in make:
#.cpp.o:
# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
######################################################################
### Debugging
+3
View File
@@ -26,6 +26,9 @@
//=========================================================================
#if VM_SC
# include "verilated_sc.h"
#endif
#include "verilated.h"
#include "verilated_vpi.h"
+39 -30
View File
@@ -166,44 +166,53 @@ string AstNode::vcdName(const string& namein) {
}
string AstNode::prettyName(const string& namein) {
// This function is somewhat hot, so we short-circuit some compares
string pretty;
pretty = "";
pretty.reserve(namein.length());
for (const char* pos = namein.c_str(); *pos; ) {
if (0==strncmp(pos,"__BRA__",7)) {
pretty += "[";
pos += 7;
}
else if (0==strncmp(pos,"__KET__",7)) {
pretty += "]";
pos += 7;
}
else if (0==strncmp(pos,"__DOT__",7)) {
pretty += ".";
pos += 7;
}
else if (0==strncmp(pos,"->",2)) {
if (pos[0]=='-' && pos[1]=='>') { // ->
pretty += ".";
pos += 2;
continue;
}
else if (0==strncmp(pos,"__PVT__",7)) {
pretty += "";
pos += 7;
}
else if (pos[0]=='_' && pos[1]=='_' && pos[2]=='0'
&& isxdigit(pos[3]) && isxdigit(pos[4])) {
char value = 0;
value += 16*(isdigit(pos[3]) ? (pos[3]-'0') : (tolower(pos[3])-'a'+10));
value += (isdigit(pos[4]) ? (pos[4]-'0') : (tolower(pos[4])-'a'+10));
pretty += value;
pos += 5;
}
else {
pretty += pos[0];
++pos;
if (pos[0]=='_' && pos[1]=='_') { // Short-circuit
if (0==strncmp(pos,"__BRA__",7)) {
pretty += "[";
pos += 7;
continue;
}
if (0==strncmp(pos,"__KET__",7)) {
pretty += "]";
pos += 7;
continue;
}
if (0==strncmp(pos,"__DOT__",7)) {
pretty += ".";
pos += 7;
continue;
}
if (0==strncmp(pos,"__PVT__",7)) {
pretty += "";
pos += 7;
continue;
}
if (pos[0]=='_' && pos[1]=='_' && pos[2]=='0'
&& isxdigit(pos[3]) && isxdigit(pos[4])) {
char value = 0;
value += 16*(isdigit(pos[3]) ? (pos[3]-'0') : (tolower(pos[3])-'a'+10));
value += (isdigit(pos[4]) ? (pos[4]-'0') : (tolower(pos[4])-'a'+10));
pretty += value;
pos += 5;
continue;
}
}
// Default
pretty += pos[0];
++pos;
}
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
if (pretty.substr(0,5) == "TOP->") pretty.replace(0,5,"");
if (pretty[0]=='T' && pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
if (pretty[0]=='T' && pretty.substr(0,5) == "TOP->") pretty.replace(0,5,"");
return pretty;
}
+2
View File
@@ -1350,6 +1350,8 @@ public:
: AstNodeMath(fl) {
setOp1p(lhs); setOp2p(rhs); }
ASTNODE_BASE_FUNCS(NodeBiop)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp)=0; // Clone single node, just get same type back.
// ACCESSORS
AstNode* lhsp() const { return op1p()->castNode(); }
AstNode* rhsp() const { return op2p()->castNode(); }
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
+104 -5
View File
@@ -764,6 +764,7 @@ public:
init(fromp);
}
ASTNODE_NODE_FUNCS(ArraySel, ARRAYSEL)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstArraySel(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) {
V3ERROR_NA; /* How can from be a const? */ }
virtual string emitVerilog() { return "%k(%l%f[%r])"; }
@@ -793,6 +794,7 @@ public:
dtypeSetUInt32(); // Always used on IData arrays so returns word entities
}
ASTNODE_NODE_FUNCS(WordSel, WORDSEL)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstWordSel(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit) { V3ERROR_NA; }
virtual string emitVerilog() { return "%k(%l%f[%r])"; }
virtual string emitC() { return "%li[%ri]"; } // Not %k, as usually it's a small constant rhsp
@@ -2675,6 +2677,23 @@ public:
ASTNODE_NODE_FUNCS(GenFor, GENFOR)
};
class AstForeach : public AstNodeStmt {
public:
AstForeach(FileLine* fileline, AstNode* arrayp, AstNode* varsp,
AstNode* bodysp)
: AstNodeStmt(fileline) {
setOp1p(arrayp); addNOp2p(varsp); addNOp4p(bodysp);
}
ASTNODE_NODE_FUNCS(Foreach, FOREACH)
AstNode* arrayp() const { return op1p()->castNode(); } // op1= array
AstNode* varsp() const { return op2p()->castNode(); } // op2= variable index list
AstNode* bodysp() const { return op4p()->castNode(); } // op4= body of loop
virtual bool isGateOptimizable() const { return false; }
virtual int instrCount() const { return instrCountBranch(); }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
};
class AstRepeat : public AstNodeStmt {
public:
AstRepeat(FileLine* fileline, AstNode* countp, AstNode* bodysp)
@@ -2863,6 +2882,7 @@ public:
dtypeSetUInt32(); // Always used on, and returns word entities
}
ASTNODE_NODE_FUNCS(ChangeXor, CHANGEXOR)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstChangeXor(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opChangeXor(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f^ %r)"; }
virtual string emitC() { return "VL_CHANGEXOR_%li(%lw, %P, %li, %ri)"; }
@@ -2981,20 +3001,37 @@ class AstInitArray : public AstNode {
// Set a var to a large list of values
// The values must be in sorted order, and not exceed the size of the var's array.
// The first value on the initsp() list is for the lo() index of the array.
// If default is specified, the vector may be sparse, and not provide each value.
// Parents: ASTVAR::init()
// Children: CONSTs...
deque<uint32_t> m_indices; // Which array index each entry in the list is for (if defaultp)
public:
AstInitArray(FileLine* fl, AstNodeArrayDType* newDTypep, AstNode* initsp)
AstInitArray(FileLine* fl, AstNodeArrayDType* newDTypep, AstNode* defaultp)
: AstNode(fl) {
dtypep(newDTypep);
addNOp1p(initsp);
addNOp1p(defaultp);
}
ASTNODE_NODE_FUNCS(InitArray, INITARRAY)
AstNode* initsp() const { return op1p()->castNode(); } // op1 = Initial value expressions
void addInitsp(AstNode* newp) { addOp1p(newp); }
AstNode* defaultp() const { return op1p()->castNode(); } // op1 = Default if sparse
void defaultp(AstNode* newp) { setOp1p(newp); }
AstNode* initsp() const { return op2p()->castNode(); } // op2 = Initial value expressions
void addValuep(AstNode* newp) { addIndexValuep(m_indices.size(), newp); }
void addIndexValuep(uint32_t index, AstNode* newp) {
// Must insert in sorted order
if (!m_indices.empty()) UASSERT(index > m_indices.back(), "InitArray adding index <= previous index");
m_indices.push_back(index);
addOp2p(newp); }
void addFrontValuep(AstNode* newp) { // Add to front of list, e.g. index 0.
// e.g. 0:100, 1:101 when addFront(200), get 0:200, 1:100, 2:101
initsp()->addHereThisAsNext(newp);
m_indices.push_back(m_indices.size());
}
int posIndex(int listPos) {
UASSERT (listPos < (int)m_indices.size(), "InitArray past end of indices list");
return m_indices[listPos]; }
virtual bool hasDType() const { return true; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
virtual bool same(AstNode* samep) const { return m_indices==samep->castInitArray()->m_indices; }
};
class AstPragma : public AstNode {
@@ -3806,6 +3843,7 @@ public:
AstLogOr(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(LogOr, LOGOR)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLogOr(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogOr(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f|| %r)"; }
virtual string emitC() { return "VL_LOGOR_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
@@ -3820,6 +3858,7 @@ public:
AstLogAnd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(LogAnd, LOGAND)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLogAnd(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogAnd(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f&& %r)"; }
virtual string emitC() { return "VL_LOGAND_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
@@ -3834,6 +3873,7 @@ public:
AstLogIf(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(LogIf, LOGIF)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLogIf(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogIf(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f-> %r)"; }
virtual string emitC() { return "VL_LOGIF_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
@@ -3848,6 +3888,7 @@ public:
AstLogIff(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(LogIff, LOGIFF)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLogIff(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogIff(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f<-> %r)"; }
virtual string emitC() { return "VL_LOGIFF_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
@@ -3862,6 +3903,7 @@ public:
AstOr(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(Or, OR)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstOr(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opOr(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f| %r)"; }
virtual string emitC() { return "VL_OR_%lq(%lW, %P, %li, %ri)"; }
@@ -3875,6 +3917,7 @@ public:
AstAnd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(And, AND)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAnd(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAnd(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f& %r)"; }
virtual string emitC() { return "VL_AND_%lq(%lW, %P, %li, %ri)"; }
@@ -3888,6 +3931,7 @@ public:
AstXor(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(Xor, XOR)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstXor(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opXor(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f^ %r)"; }
virtual string emitC() { return "VL_XOR_%lq(%lW, %P, %li, %ri)"; }
@@ -3901,6 +3945,7 @@ public:
AstXnor(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(Xnor, XNOR)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstXnor(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opXnor(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f^ ~ %r)"; }
virtual string emitC() { return "VL_XNOR_%lq(%lW, %P, %li, %ri)"; }
@@ -3914,6 +3959,7 @@ public:
AstEq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(Eq, EQ)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstEq(this->fileline(), lhsp, rhsp); }
static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp); // Return AstEq/AstEqD
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f== %r)"; }
@@ -3928,6 +3974,7 @@ public:
AstEqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(EqD, EQD)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstEqD(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEqD(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f== %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -3943,6 +3990,7 @@ public:
AstEqN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(EqN, EQN)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstEqN(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEqN(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f== %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -3958,6 +4006,7 @@ public:
AstNeq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(Neq, NEQ)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstNeq(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f!= %r)"; }
virtual string emitC() { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; }
@@ -3971,6 +4020,7 @@ public:
AstNeqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(NeqD, NEQD)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstNeqD(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeqD(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f!= %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -3986,6 +4036,7 @@ public:
AstNeqN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(NeqN, NEQN)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstNeqN(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeqN(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f!= %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -4001,6 +4052,7 @@ public:
AstLt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(Lt, LT)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLt(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLt(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f< %r)"; }
virtual string emitC() { return "VL_LT_%lq(%lW, %P, %li, %ri)"; }
@@ -4014,6 +4066,7 @@ public:
AstLtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(LtD, LTD)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLtD(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtD(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f< %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -4029,6 +4082,7 @@ public:
AstLtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(LtS, LTS)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLtS(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f< %r)"; }
virtual string emitC() { return "VL_LTS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
@@ -4043,6 +4097,7 @@ public:
AstLtN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(LtN, LTN)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLtN(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtN(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f< %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -4058,6 +4113,7 @@ public:
AstGt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(Gt, GT)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGt(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGt(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f> %r)"; }
virtual string emitC() { return "VL_GT_%lq(%lW, %P, %li, %ri)"; }
@@ -4071,6 +4127,7 @@ public:
AstGtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(GtD, GTD)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGtD(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtD(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f> %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -4086,6 +4143,7 @@ public:
AstGtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(GtS, GTS)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGtS(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f> %r)"; }
virtual string emitC() { return "VL_GTS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
@@ -4100,6 +4158,7 @@ public:
AstGtN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(GtN, GTN)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGtN(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtN(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f> %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -4115,6 +4174,7 @@ public:
AstGte(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(Gte, GTE)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGte(this->fileline(), lhsp, rhsp); }
static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp); // Return AstGte/AstGteS/AstGteD
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGte(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f>= %r)"; }
@@ -4129,6 +4189,7 @@ public:
AstGteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(GteD, GTED)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGteD(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteD(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f>= %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -4144,6 +4205,7 @@ public:
AstGteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(GteS, GTES)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGteS(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f>= %r)"; }
virtual string emitC() { return "VL_GTES_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
@@ -4158,6 +4220,7 @@ public:
AstGteN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(GteN, GTEN)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstGteN(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteN(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f>= %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -4173,6 +4236,7 @@ public:
AstLte(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(Lte, LTE)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLte(this->fileline(), lhsp, rhsp); }
static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp); // Return AstLte/AstLteS/AstLteD
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLte(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f<= %r)"; }
@@ -4187,6 +4251,7 @@ public:
AstLteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(LteD, LTED)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLteD(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteD(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f<= %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -4202,6 +4267,7 @@ public:
AstLteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(LteS, LTES)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLteS(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f<= %r)"; }
virtual string emitC() { return "VL_LTES_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
@@ -4216,6 +4282,7 @@ public:
AstLteN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(LteN, LTEN)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstLteN(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteN(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f<= %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -4233,6 +4300,7 @@ public:
if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::UNSIGNED); }
}
ASTNODE_NODE_FUNCS(ShiftL, SHIFTL)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstShiftL(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftL(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f<< %r)"; }
virtual string emitC() { return "VL_SHIFTL_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
@@ -4248,6 +4316,7 @@ public:
if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::UNSIGNED); }
}
ASTNODE_NODE_FUNCS(ShiftR, SHIFTR)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstShiftR(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftR(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f>> %r)"; }
virtual string emitC() { return "VL_SHIFTR_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
@@ -4266,6 +4335,7 @@ public:
if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::SIGNED); }
}
ASTNODE_NODE_FUNCS(ShiftRS, SHIFTRS)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstShiftRS(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) {
out.opShiftRS(lhs,rhs,lhsp()->widthMinV()); }
virtual string emitVerilog() { return "%k(%l %f>>> %r)"; }
@@ -4281,6 +4351,7 @@ public:
AstAdd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(Add, ADD)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAdd(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAdd(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f+ %r)"; }
virtual string emitC() { return "VL_ADD_%lq(%lW, %P, %li, %ri)"; }
@@ -4294,6 +4365,7 @@ public:
AstAddD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
dtypeSetDouble(); }
ASTNODE_NODE_FUNCS(AddD, ADDD)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAddD(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAddD(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f+ %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -4309,6 +4381,7 @@ public:
AstSub(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(Sub, SUB)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstSub(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opSub(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f- %r)"; }
virtual string emitC() { return "VL_SUB_%lq(%lW, %P, %li, %ri)"; }
@@ -4322,6 +4395,7 @@ public:
AstSubD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetDouble(); }
ASTNODE_NODE_FUNCS(SubD, SUBD)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstSubD(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opSubD(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f- %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -4337,6 +4411,7 @@ public:
AstMul(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(Mul, MUL)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstMul(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMul(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f* %r)"; }
virtual string emitC() { return "VL_MUL_%lq(%lW, %P, %li, %ri)"; }
@@ -4351,6 +4426,7 @@ public:
AstMulD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
dtypeSetDouble(); }
ASTNODE_NODE_FUNCS(MulD, MULD)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstMulD(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMulD(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f* %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -4366,6 +4442,7 @@ public:
AstMulS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(MulS, MULS)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstMulS(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMulS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f* %r)"; }
virtual string emitC() { return "VL_MULS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
@@ -4381,6 +4458,7 @@ public:
AstDiv(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(Div, DIV)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstDiv(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDiv(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f/ %r)"; }
virtual string emitC() { return "VL_DIV_%nq%lq%rq(%lw, %P, %li, %ri)"; }
@@ -4394,6 +4472,7 @@ public:
AstDivD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetDouble(); }
ASTNODE_NODE_FUNCS(DivD, DIVD)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstDivD(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDivD(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f/ %r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
@@ -4409,6 +4488,7 @@ public:
AstDivS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(DivS, DIVS)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstDivS(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDivS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f/ %r)"; }
virtual string emitC() { return "VL_DIVS_%nq%lq%rq(%lw, %P, %li, %ri)"; }
@@ -4423,6 +4503,7 @@ public:
AstModDiv(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(ModDiv, MODDIV)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstModDiv(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opModDiv(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f%% %r)"; }
virtual string emitC() { return "VL_MODDIV_%nq%lq%rq(%lw, %P, %li, %ri)"; }
@@ -4436,6 +4517,7 @@ public:
AstModDivS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(ModDivS, MODDIVS)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstModDivS(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opModDivS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f%% %r)"; }
virtual string emitC() { return "VL_MODDIVS_%nq%lq%rq(%lw, %P, %li, %ri)"; }
@@ -4450,6 +4532,7 @@ public:
AstPow(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(Pow, POW)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstPow(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPow(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f** %r)"; }
virtual string emitC() { return "VL_POW_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
@@ -4463,6 +4546,7 @@ public:
AstPowD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetDouble(); }
ASTNODE_NODE_FUNCS(PowD, POWD)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstPowD(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowD(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f** %r)"; }
virtual string emitC() { return "pow(%li,%ri)"; }
@@ -4477,6 +4561,7 @@ public:
AstPowSU(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(PowSU, POWSU)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstPowSU(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowSU(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f** %r)"; }
virtual string emitC() { return "VL_POWSS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri, 1,0)"; }
@@ -4491,6 +4576,7 @@ public:
AstPowSS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(PowSS, POWSS)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstPowSS(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowSS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f** %r)"; }
virtual string emitC() { return "VL_POWSS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri, 1,1)"; }
@@ -4505,6 +4591,7 @@ public:
AstPowUS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(PowUS, POWUS)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstPowUS(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowUS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f** %r)"; }
virtual string emitC() { return "VL_POWSS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri, 0,1)"; }
@@ -4519,6 +4606,7 @@ public:
AstEqCase(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(EqCase, EQCASE)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstEqCase(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opCaseEq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f=== %r)"; }
virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; }
@@ -4532,6 +4620,7 @@ public:
AstNeqCase(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(NeqCase, NEQCASE)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstNeqCase(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opCaseNeq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f!== %r)"; }
virtual string emitC() { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; }
@@ -4546,6 +4635,7 @@ public:
AstEqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(EqWild, EQWILD)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstEqWild(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildEq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f==? %r)"; }
virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; }
@@ -4559,6 +4649,7 @@ public:
AstNeqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(NeqWild, NEQWILD)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstNeqWild(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildNeq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f!=? %r)"; }
virtual string emitC() { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; }
@@ -4578,6 +4669,7 @@ public:
}
}
ASTNODE_NODE_FUNCS(Concat, CONCAT)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstConcat(this->fileline(), lhsp, rhsp); }
virtual string emitVerilog() { return "%f{%l, %k%r}"; }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opConcat(lhs,rhs); }
virtual string emitC() { return "VL_CONCAT_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
@@ -4593,6 +4685,7 @@ public:
dtypeSetString();
}
ASTNODE_NODE_FUNCS(ConcatN, CONCATN)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstConcatN(this->fileline(), lhsp, rhsp); }
virtual string emitVerilog() { return "%f{%l, %k%r}"; }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opConcatN(lhs,rhs); }
virtual string emitC() { return "VL_CONCATN_NNN(%li, %ri)"; }
@@ -4619,6 +4712,7 @@ public:
AstReplicate(FileLine* fl, AstNode* lhsp, uint32_t repCount)
: AstNodeBiop(fl, lhsp, new AstConst(fl, repCount)) { init(); }
ASTNODE_NODE_FUNCS(Replicate, REPLICATE)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstReplicate(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opRepl(lhs,rhs); }
virtual string emitVerilog() { return "%f{%r{%k%l}}"; }
virtual string emitC() { return "VL_REPLICATE_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
@@ -4637,6 +4731,7 @@ public:
AstReplicateN(FileLine* fl, AstNode* lhsp, uint32_t repCount)
: AstNodeBiop(fl, lhsp, new AstConst(fl, repCount)) { init(); }
ASTNODE_NODE_FUNCS(ReplicateN, REPLICATEN)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstReplicateN(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opReplN(lhs,rhs); }
virtual string emitVerilog() { return "%f{%r{%k%l}}"; }
virtual string emitC() { return "VL_REPLICATEN_NN%rq(0,0,%rw, %li, %ri)"; }
@@ -4651,6 +4746,7 @@ class AstStreamL : public AstNodeStream {
public:
AstStreamL(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeStream(fl, lhsp, rhsp) {}
ASTNODE_NODE_FUNCS(StreamL, STREAML)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstStreamL(this->fileline(), lhsp, rhsp); }
virtual string emitVerilog() { return "%f{ << %r %k{%l} }"; }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opStreamL(lhs,rhs); }
virtual string emitC() { return "VL_STREAML_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
@@ -4664,6 +4760,7 @@ class AstStreamR : public AstNodeStream {
public:
AstStreamR(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeStream(fl, lhsp, rhsp) {}
ASTNODE_NODE_FUNCS(StreamR, STREAMR)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstStreamR(this->fileline(), lhsp, rhsp); }
virtual string emitVerilog() { return "%f{ >> %r %k{%l} }"; }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAssign(lhs); }
virtual string emitC() { return isWide() ? "VL_ASSIGN_W(%nw, %P, %li)" : "%li"; }
@@ -4679,6 +4776,7 @@ public:
AstBufIf1(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
dtypeFrom(lhsp); }
ASTNODE_NODE_FUNCS(BufIf1, BUFIF1)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstBufIf1(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opBufIf1(lhs,rhs); }
virtual string emitVerilog() { return "bufif(%r,%l)"; }
virtual string emitC() { V3ERROR_NA; return "";} // Lclean || Rclean
@@ -4691,6 +4789,7 @@ class AstFGetS : public AstNodeBiop {
public:
AstFGetS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {}
ASTNODE_NODE_FUNCS(FGetS, FGETS)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstFGetS(this->fileline(), lhsp, rhsp); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; }
virtual string emitVerilog() { return "%f$fgets(%l,%r)"; }
virtual string emitC() { return "VL_FGETS_%nqX%rq(%lw, %P, &(%li), %ri)"; }
+15 -3
View File
@@ -1464,9 +1464,21 @@ private:
did=true;
}
else if (m_selp && valuep->castInitArray()) {
int bit = m_selp->bitConst();
AstNode* itemp = valuep->castInitArray()->initsp();
for (int n=0; n<bit && itemp; ++n, itemp=itemp->nextp()) {}
AstInitArray* initarp = valuep->castInitArray();
uint32_t bit = m_selp->bitConst();
int pos = 0;
AstNode* itemp = initarp->initsp();
for (; itemp; ++pos, itemp=itemp->nextp()) {
uint32_t index = initarp->posIndex(pos);
if (index == bit) break;
if (index > bit) {
if (initarp->defaultp()) {
itemp = initarp->defaultp();
} else {
initarp->v3fatalSrc("Not enough values in array initalizement");
}
}
}
if (itemp->castConst()) {
const V3Number& num = itemp->castConst()->num();
//UINFO(2,"constVisit "<<(void*)valuep<<" "<<num<<endl);
+1 -1
View File
@@ -83,10 +83,10 @@ private:
const char* varIgnoreToggle(AstVar* nodep) {
// Return true if this shouldn't be traced
// See also similar rule in V3TraceDecl::varIgnoreTrace
string prettyName = nodep->prettyName();
if (!nodep->isToggleCoverable())
return "Not relevant signal type";
if (!v3Global.opt.coverageUnderscore()) {
string prettyName = nodep->prettyName();
if (prettyName[0] == '_')
return "Leading underscore";
if (prettyName.find("._") != string::npos)
+37 -29
View File
@@ -113,7 +113,7 @@ public:
}
if (AstEnumDType* adtypep = nodep->dtypep()->skipRefToEnump()->castEnumDType()) {
if (adtypep->width()>64) {
puts("// enum "+nodep->name()+" // Ignored: Too wide for C++\n");
putsDecoration("// enum "+nodep->name()+" // Ignored: Too wide for C++\n");
} else {
puts("enum "+nodep->name()+" {\n");
for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp=itemp->nextp()->castEnumItem()) {
@@ -220,7 +220,7 @@ public:
nodep->v3fatalSrc("Case statements should have been reduced out\n");
}
virtual void visit(AstComment* nodep, AstNUser*) {
puts((string)"// "+nodep->name()+" at "+nodep->fileline()->ascii()+"\n");
putsDecoration((string)"// "+nodep->name()+" at "+nodep->fileline()->ascii()+"\n");
nodep->iterateChildren(*this);
}
virtual void visit(AstCoverDecl* nodep, AstNUser*) {
@@ -499,13 +499,13 @@ public:
nodep->bodysp()->iterateAndNext(*this);
}
virtual void visit(AstUCStmt* nodep, AstNUser*) {
puts("// $c statement at "+nodep->fileline()->ascii()+"\n");
putsDecoration("// $c statement at "+nodep->fileline()->ascii()+"\n");
nodep->bodysp()->iterateAndNext(*this);
puts("\n");
}
virtual void visit(AstUCFunc* nodep, AstNUser*) {
puts("\n");
puts("// $c function at "+nodep->fileline()->ascii()+"\n");
putsDecoration("// $c function at "+nodep->fileline()->ascii()+"\n");
nodep->bodysp()->iterateAndNext(*this);
puts("\n");
}
@@ -844,7 +844,7 @@ class EmitCImp : EmitCStmts {
if (nodep->symProlog()) puts(EmitCBaseVisitor::symTopAssign()+"\n");
if (nodep->initsp()) puts("// Variables\n");
if (nodep->initsp()) putsDecoration("// Variables\n");
ofp()->putAlign(V3OutFile::AL_AUTO, 4);
for (AstNode* subnodep=nodep->argsp(); subnodep; subnodep = subnodep->nextp()) {
if (AstVar* varp=subnodep->castVar()) {
@@ -858,11 +858,11 @@ class EmitCImp : EmitCStmts {
nodep->initsp()->iterateAndNext(*this);
if (nodep->stmtsp()) puts("// Body\n");
if (nodep->stmtsp()) putsDecoration("// Body\n");
nodep->stmtsp()->iterateAndNext(*this);
if (!m_blkChangeDetVec.empty()) emitChangeDet();
if (nodep->finalsp()) puts("// Final\n");
if (nodep->finalsp()) putsDecoration("// Final\n");
nodep->finalsp()->iterateAndNext(*this);
//
@@ -873,7 +873,7 @@ class EmitCImp : EmitCStmts {
}
void emitChangeDet() {
puts("// Change detection\n");
putsDecoration("// Change detection\n");
puts("QData __req = false; // Logically a bool\n"); // But not because it results in faster code
bool gotOne = false;
for (vector<AstChangeDet*>::iterator it = m_blkChangeDetVec.begin();
@@ -1397,12 +1397,20 @@ void EmitCImp::emitVarReset(AstVar* varp) {
//puts("// parameter "+varp->name()+" = "+varp->valuep()->name()+"\n");
}
else if (AstInitArray* initarp = varp->valuep()->castInitArray()) {
AstConst* constsp = initarp->initsp()->castConst();
if (AstUnpackArrayDType* arrayp = varp->dtypeSkipRefp()->castUnpackArrayDType()) {
for (int i=0; i<arrayp->elementsConst(); i++) {
if (!constsp) initarp->v3fatalSrc("Not enough values in array initalizement");
emitSetVarConstant(varp->name()+"["+cvtToStr(i)+"]", constsp);
constsp = constsp->nextp()->castConst();
if (initarp->defaultp()) {
// MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block
puts("{ int __Vi=0;");
puts(" for (; __Vi<"+cvtToStr(arrayp->elementsConst()));
puts("; ++__Vi) {\n");
emitSetVarConstant(varp->name()+"[__Vi]", initarp->defaultp()->castConst());
puts("}}\n");
}
int pos = 0;
for (AstNode* itemp = initarp->initsp(); itemp; ++pos, itemp=itemp->nextp()) {
int index = initarp->posIndex(pos);
if (!initarp->defaultp() && index!=pos) initarp->v3fatalSrc("Not enough values in array initalizement");
emitSetVarConstant(varp->name()+"["+cvtToStr(index)+"]", itemp->castConst());
}
} else {
varp->v3fatalSrc("InitArray under non-arrayed var");
@@ -1466,7 +1474,7 @@ void EmitCImp::emitVarReset(AstVar* varp) {
void EmitCImp::emitCoverageDecl(AstNodeModule* modp) {
if (v3Global.opt.coverage()) {
ofp()->putsPrivate(true);
puts("// Coverage\n");
putsDecoration("// Coverage\n");
puts("void __vlCoverInsert(uint32_t* countp, bool enable, const char* filenamep, int lineno, int column,\n");
puts( "const char* hierp, const char* pagep, const char* commentp);\n");
}
@@ -1486,12 +1494,12 @@ void EmitCImp::emitCtorImp(AstNodeModule* modp) {
emitCellCtors(modp);
emitSensitives();
puts("// Reset internal values\n");
putsDecoration("// Reset internal values\n");
if (modp->isTop()) {
if (v3Global.opt.inhibitSim()) puts("__Vm_inhibitSim = false;\n");
puts("\n");
}
puts("// Reset structure values\n");
putsDecoration("// Reset structure values\n");
puts("_ctor_var_reset();\n");
emitTextSection(AstType::atSCCTOR);
if (optSystemPerl()) puts("SP_AUTO_CTOR;\n");
@@ -1507,7 +1515,7 @@ void EmitCImp::emitConfigureImp(AstNodeModule* modp) {
if (nodep->castCoverDecl()) {
if (first) {
first = false;
puts("// Coverage Declarations\n");
putsDecoration("// Coverage Declarations\n");
}
nodep->accept(*this);
splitSizeInc(nodep);
@@ -1673,7 +1681,7 @@ void EmitCImp::emitSensitives() {
// Create sensitivity list for when to evaluate the model.
// If C++ code, the user must call this routine themself.
if (m_modp->isTop() && optSystemC()) {
puts("// Sensitivities on all clocks and combo inputs\n");
putsDecoration("// Sensitivities on all clocks and combo inputs\n");
puts("SC_METHOD(eval);\n");
for (AstNode* nodep=m_modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstVar* varp = nodep->castVar()) {
@@ -1705,12 +1713,12 @@ void EmitCImp::emitWrapEval(AstNodeModule* modp) {
puts("\nvoid "+modClassName(modp)+"::eval() {\n");
puts(EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp; // Setup global symbol table\n");
puts(EmitCBaseVisitor::symTopAssign()+"\n");
puts("// Initialize\n");
putsDecoration("// Initialize\n");
puts("if (VL_UNLIKELY(!vlSymsp->__Vm_didInit)) _eval_initial_loop(vlSymsp);\n");
if (v3Global.opt.inhibitSim()) {
puts("if (VL_UNLIKELY(__Vm_inhibitSim)) return;\n");
}
puts("// Evaluate till stable\n");
putsDecoration("// Evaluate till stable\n");
puts("VL_DEBUG_IF(VL_PRINTF(\"\\n----TOP Evaluate "+modClassName(modp)+"::eval\\n\"); );\n");
puts("int __VclockLoop = 0;\n");
puts("QData __Vchange=1;\n");
@@ -1879,7 +1887,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
if (optSystemPerl()) {
puts("/*AUTOSUBCELLS*/\n\n");
} else {
puts("// CELLS\n");
putsDecoration("// CELLS\n");
if (modp->isTop()) puts("// Public to allow access to /*verilator_public*/ items;\n");
if (modp->isTop()) puts("// otherwise the application code can consider these internals.\n");
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
@@ -1931,9 +1939,9 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
// These should be static const values, however microsloth VC++ doesn't
// support them. They also cause problems with GDB under GCC2.95.
if (varp->isWide()) { // Unsupported for output
puts("// enum WData "+varp->name()+" //wide");
putsDecoration("// enum WData "+varp->name()+" //wide");
} else if (!varp->valuep()->castConst()) { // Unsupported for output
//puts("// enum ..... "+varp->name()+" //not simple value, see variable above instead");
//putsDecoration("// enum ..... "+varp->name()+" //not simple value, see variable above instead");
} else {
puts("enum ");
puts(varp->isQuad()?"_QData":"_IData");
@@ -2214,7 +2222,7 @@ class EmitCTrace : EmitCStmts {
puts("void "+topClassName()+"::traceInit("
+v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code) {\n");
puts("// Callback from vcd->open()\n");
putsDecoration("// Callback from vcd->open()\n");
puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n");
puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n");
puts("if (!Verilated::calcUnusedSigs()) vl_fatal(__FILE__,__LINE__,__FILE__,\"Turning on wave traces requires Verilated::traceEverOn(true) call before time 0.\");\n");
@@ -2227,7 +2235,7 @@ class EmitCTrace : EmitCStmts {
puts("void "+topClassName()+"::traceFull("
+v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code) {\n");
puts("// Callback from vcd->dump()\n");
putsDecoration("// Callback from vcd->dump()\n");
puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n");
puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n");
puts("t->traceFullThis (vlSymsp, vcdp, code);\n");
@@ -2242,7 +2250,7 @@ class EmitCTrace : EmitCStmts {
puts("void "+topClassName()+"::traceChg("
+v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code) {\n");
puts("// Callback from vcd->dump()\n");
putsDecoration("// Callback from vcd->dump()\n");
puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n");
puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n");
puts("if (vlSymsp->getClearActivity()) {\n");
@@ -2396,16 +2404,16 @@ class EmitCTrace : EmitCStmts {
} else if (nodep->funcType() == AstCFuncType::TRACE_CHANGE_SUB) {
} else nodep->v3fatalSrc("Bad Case");
if (nodep->initsp()) puts("// Variables\n");
if (nodep->initsp()) putsDecoration("// Variables\n");
emitVarList(nodep->initsp(), EVL_ALL, "");
nodep->initsp()->iterateAndNext(*this);
ofp()->putAlign(V3OutFile::AL_AUTO, 4);
puts("// Body\n");
putsDecoration("// Body\n");
puts("{\n");
nodep->stmtsp()->iterateAndNext(*this);
puts("}\n");
if (nodep->finalsp()) puts("// Final\n");
if (nodep->finalsp()) putsDecoration("// Final\n");
nodep->finalsp()->iterateAndNext(*this);
puts("}\n");
}
+1
View File
@@ -43,6 +43,7 @@ public:
V3OutCFile* ofp() const { return m_ofp; }
void puts(const string& str) { ofp()->puts(str); }
void putbs(const string& str) { ofp()->putbs(str); }
void putsDecoration(const string& str) { if (v3Global.opt.decoration()) puts(str); }
void putsQuoted(const string& str) { ofp()->putsQuoted(str); }
bool optSystemC() { return v3Global.opt.systemC(); }
bool optSystemPerl() { return v3Global.opt.systemPerl(); }
+7 -3
View File
@@ -448,9 +448,13 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
}
virtual void visit(AstInitArray* nodep, AstNUser*) {
putfs(nodep,"`{");
for (AstNode* subp = nodep->initsp(); subp; subp=subp->nextp()) {
subp->accept(*this);
if (subp->nextp()) putbs(",");
int pos = 0;
for (AstNode* itemp = nodep->initsp(); itemp; ++pos, itemp=itemp->nextp()) {
int index = nodep->posIndex(pos);
puts(cvtToStr(index));
puts(":");
itemp->accept(*this);
if (itemp->nextp()) putbs(",");
}
puts("}");
}
+8 -2
View File
@@ -551,10 +551,12 @@ bool V3InFilter::readWholefile(const string& filename, V3InFilter::StrList& outl
// V3OutFormatter: A class for printing to a file, with automatic indentation of C++ code.
V3OutFormatter::V3OutFormatter(const string& filename, V3OutFormatter::Language lang)
: m_filename(filename), m_lang(lang), m_blockIndent(4)
: m_filename(filename), m_lang(lang)
, m_lineno(1), m_column(0)
, m_nobreak(false), m_prependIndent(true), m_indentLevel(0)
, m_declSAlign(0), m_declNSAlign(0), m_declPadNum(0) {
m_blockIndent = v3Global.opt.decoration() ? 4 : 1;
m_commaWidth = v3Global.opt.decoration() ? 50 : 150;
}
//----------------------------------------------------------------------
@@ -682,7 +684,11 @@ void V3OutFormatter::puts (const char *strg) {
break;
case '(':
indentInc();
m_parenVec.push(m_column);
if (v3Global.opt.decoration()) {
m_parenVec.push(m_column); // Line up continuation with open paren, plus one indent
} else {
m_parenVec.push(m_indentLevel*m_blockIndent); // Line up continuation with block+1
}
break;
case ')':
if (!m_parenVec.empty()) m_parenVec.pop();
+2 -2
View File
@@ -97,7 +97,6 @@ public:
class V3OutFormatter {
// TYPES
enum MiscConsts {
WIDTH = 50, // Width after which to break at ,'s
MAXSPACE = 80}; // After this indent, stop indenting more
public:
enum AlignClass {
@@ -115,6 +114,7 @@ private:
string m_filename;
Language m_lang; // Indenting Verilog code
int m_blockIndent; // Characters per block indent
int m_commaWidth; // Width after which to break at ,'s
int m_lineno;
int m_column;
int m_nobreak; // Basic operator or begin paren, don't break next
@@ -147,7 +147,7 @@ public:
void putAlign(bool isstatic/*AlignClass*/, int align, int size=0/*=align*/, const string& prefix=""); // Declare a variable, with natural alignment
void putbs(const char* strg) { putBreakExpr(); puts(strg); }
void putbs(const string& strg) { putBreakExpr(); puts(strg); }
bool exceededWidth() const { return m_column > WIDTH; }
bool exceededWidth() const { return m_column > m_commaWidth; }
bool tokenStart(const char* cp, const char* cmp);
bool tokenEnd(const char* cp);
void indentInc() { m_indentLevel += m_blockIndent; }
+45
View File
@@ -322,6 +322,51 @@ private:
nodep->unlinkFrBack()->deleteTree();
}
virtual void visit(AstForeach* nodep, AstNUser*) {
// FOREACH(array,loopvars,body)
// -> BEGIN(declare vars, loopa=lowest; WHILE(loopa<=highest, ... body))
//nodep->dumpTree(cout, "-foreach-old:");
AstNode* newp = nodep->bodysp()->unlinkFrBackWithNext();
AstNode* arrayp = nodep->arrayp();
int dimension = 1;
// Must do innermost (last) variable first
AstNode* firstVarsp = nodep->varsp()->unlinkFrBackWithNext();
AstNode* lastVarsp = firstVarsp;
while (lastVarsp->nextp()) { lastVarsp = lastVarsp->nextp(); dimension++; }
for (AstNode* varsp = lastVarsp; varsp; varsp=varsp->backp()) {
UINFO(0,"foreachVar "<<varsp<<endl);
FileLine* fl = varsp->fileline();
AstNode* varp = new AstVar(fl, AstVarType::BLOCKTEMP,
varsp->name(), nodep->findSigned32DType());
AstNode* leftp = new AstAttrOf(fl, AstAttrType::DIM_LEFT,
new AstVarRef(fl, arrayp->name(), false),
new AstConst(fl, dimension));
AstNode* rightp = new AstAttrOf(fl, AstAttrType::DIM_RIGHT,
new AstVarRef(fl, arrayp->name(), false),
new AstConst(fl, dimension));
AstNode* stmtsp = varp;
stmtsp->addNext(new AstAssign(fl, new AstVarRef(fl, varp->name(), true), leftp));
AstNode* comparep =
new AstCond(fl, new AstLte(fl, leftp->cloneTree(true), rightp->cloneTree(true)),
// left increments up to right
new AstLte(fl, new AstVarRef(fl, varp->name(), false), rightp->cloneTree(true)),
// left decrements down to right
new AstGte(fl, new AstVarRef(fl, varp->name(), false), rightp));
AstNode* incp =
new AstAssign(fl, new AstVarRef(fl, varp->name(), true),
new AstAdd(fl, new AstVarRef(fl, varp->name(), false),
new AstNegate(fl, new AstAttrOf(fl, AstAttrType::DIM_INCREMENT,
new AstVarRef(fl, arrayp->name(), false),
new AstConst(fl, dimension)))));
stmtsp->addNext(new AstWhile(fl, comparep, newp, incp));
newp = new AstBegin(nodep->fileline(),"",stmtsp);
dimension--;
}
//newp->dumpTree(cout, "-foreach-new:");
firstVarsp->deleteTree(); VL_DANGLING(firstVarsp);
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstNodeModule* nodep, AstNUser*) {
// Module: Create sim table for entire module and iterate
cleanFileline(nodep);
+8 -2
View File
@@ -605,7 +605,10 @@ string V3Number::displayed(FileLine*fl, const string& vformat) const {
uint32_t V3Number::toUInt() const {
UASSERT(!isFourState(),"toUInt with 4-state "<<*this);
UASSERT((width()<33 || (width()<65 && m_value[1]==0)), "Value too wide "<<*this);
// We allow wide numbers that represent values <= 32 bits
for (int i=1; i<words(); ++i) {
UASSERT(!m_value[i], "Value too wide for 32-bits expected in this context "<<*this);
}
return m_value[0];
}
@@ -636,7 +639,10 @@ vlsint32_t V3Number::toSInt() const {
vluint64_t V3Number::toUQuad() const {
UASSERT(!isFourState(),"toUQuad with 4-state "<<*this);
UASSERT(width()<65, "Value too wide "<<*this);
// We allow wide numbers that represent values <= 64 bits
for (int i=2; i<words(); ++i) {
UASSERT(!m_value[i], "Value too wide for 64-bits expected in this context "<<*this);
}
if (width()<=32) return ((vluint64_t)(toUInt()));
return ((vluint64_t)m_value[1]<<VL_ULL(32)) | ((vluint64_t)m_value[0]);
}
+3
View File
@@ -689,6 +689,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if ( onoff (sw, "-debug-check", flag/*ref*/) ){ m_debugCheck = flag; }
else if ( !strcmp (sw, "-debug-sigsegv") ) { throwSigsegv(); } // Undocumented, see also --debug-abort
else if ( !strcmp (sw, "-debug-fatalsrc") ) { v3fatalSrc("--debug-fatal-src"); } // Undocumented, see also --debug-abort
else if ( onoff (sw, "-decoration", flag/*ref*/) ) { m_decoration = flag; }
else if ( onoff (sw, "-dump-tree", flag/*ref*/) ) { m_dumpTree = flag ? 3 : 0; } // Also see --dump-treei
else if ( onoff (sw, "-exe", flag/*ref*/) ) { m_exe = flag; }
else if ( onoff (sw, "-ignc", flag/*ref*/) ) { m_ignc = flag; }
@@ -986,6 +987,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
}
else if ( !strcmp (sw, "-pins-bv") && (i+1)<argc ) {
shift; m_pinsBv = atoi(argv[i]);
if (m_pinsBv > 65) fl->v3fatal("--pins-bv maximum is 65: "<<argv[i]);
}
else if ( !strcmp (sw, "-pipe-filter") && (i+1)<argc ) {
shift; m_pipeFilter = argv[i];
@@ -1198,6 +1200,7 @@ V3Options::V3Options() {
m_coverageUnderscore = false;
m_coverageUser = false;
m_debugCheck = false;
m_decoration = true;
m_exe = false;
m_ignc = false;
m_inhibitSim = false;
+2
View File
@@ -75,6 +75,7 @@ class V3Options {
bool m_coverageUnderscore;// main switch: --coverage-underscore
bool m_coverageUser; // main switch: --coverage-func
bool m_debugCheck; // main switch: --debug-check
bool m_decoration; // main switch: --decoration
bool m_exe; // main switch: --exe
bool m_ignc; // main switch: --ignc
bool m_inhibitSim; // main switch: --inhibit-sim
@@ -226,6 +227,7 @@ class V3Options {
bool coverageUnderscore() const { return m_coverageUnderscore; }
bool coverageUser() const { return m_coverageUser; }
bool debugCheck() const { return m_debugCheck; }
bool decoration() const { return m_decoration; }
bool exe() const { return m_exe; }
bool trace() const { return m_trace; }
bool traceDups() const { return m_traceDups; }
+10 -1
View File
@@ -144,8 +144,12 @@ private:
&& nodep->firstAbovep()->castNodeAssign()
&& assignNoTemp(nodep->firstAbovep()->castNodeAssign())) {
// Not much point if it's just a direct assignment to a constant
} else if (nodep->backp()->castSel()
&& nodep->backp()->castSel()->widthp() == nodep) {
// AstSel::width must remain a constant
} else if (nodep->firstAbovep()
&& nodep->firstAbovep()->castArraySel()) { // ArraySel's are pointer refs, ignore
&& nodep->firstAbovep()->castArraySel()) {
// ArraySel's are pointer refs, ignore
} else {
UINFO(4,"Cre Temp: "<<nodep<<endl);
createDeepTemp(nodep, false);
@@ -263,6 +267,11 @@ private:
// Shifts of > 32/64 bits in C++ will wrap-around and generate non-0s
if (!nodep->user2SetOnce()) {
UINFO(4," ShiftFix "<<nodep<<endl);
AstConst* shiftp = nodep->rhsp()->castConst();
if (shiftp && shiftp->num().mostSetBitP1() > 32) {
shiftp->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->widthMin()<=64 // Else we'll use large operators which work right
// C operator's width must be < maximum shift which is based on Verilog width
&& nodep->width() < (1LL<<nodep->rhsp()->widthMin())) {
+89 -40
View File
@@ -139,37 +139,34 @@ class SliceCloneVisitor : public AstNVisitor {
UINFO(4, "Cloning "<<nodep->user2()<<" times: "<<nodep<<endl);
AstNode* lhsp = NULL;
AstNode* rhsp = NULL;
for (int i = 0; i < nodep->user2(); ++i) {
// Clone the node and iterate over the clone
m_vecIdx = -1;
AstNodeUniop* clonep = nodep->cloneTree(false)->castNodeUniop();
clonep->iterateChildren(*this);
if (!lhsp) lhsp = clonep;
else rhsp = clonep;
if (lhsp && rhsp) {
else {
switch (nodep->type()) {
case AstType::atREDOR:
lhsp = new AstOr(nodep->fileline(), lhsp, rhsp);
lhsp = new AstOr(nodep->fileline(), lhsp, clonep);
break;
case AstType::atREDAND:
lhsp = new AstAnd(nodep->fileline(), lhsp, rhsp);
lhsp = new AstAnd(nodep->fileline(), lhsp, clonep);
break;
case AstType::atREDXOR:
lhsp = new AstXor(nodep->fileline(), lhsp, rhsp);
lhsp = new AstXor(nodep->fileline(), lhsp, clonep);
break;
case AstType::atREDXNOR:
lhsp = new AstXnor(nodep->fileline(), lhsp, rhsp);
lhsp = new AstXnor(nodep->fileline(), lhsp, clonep);
break;
default:
nodep->v3fatalSrc("Unsupported: Unary operation on multiple packed dimensions");
break;
}
rhsp = NULL;
}
}
nodep->addNextHere(lhsp);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
nodep->replaceWith(lhsp);
nodep->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstRedOr* nodep, AstNUser*) {
cloneUniop(nodep);
@@ -421,17 +418,19 @@ class SliceVisitor : public AstNVisitor {
if (AstInitArray* initp = nodep->rhsp()->castInitArray()) {
//if (debug()>=9) nodep->dumpTree(cout, "-InitArrayIn: ");
AstNode* newp = NULL;
int index = 0;
while (AstNode* subp=initp->initsp()) {
for (int pos = 0; AstNode* itemp=initp->initsp(); ++pos) {
int index = initp->posIndex(pos);
AstNode* lhsp = new AstArraySel(nodep->fileline(),
nodep->lhsp()->cloneTree(false),
index++);
newp = AstNode::addNext(newp, nodep->cloneType(lhsp, subp->unlinkFrBack()));
index);
newp = AstNode::addNext(newp, nodep->cloneType(lhsp, itemp->unlinkFrBack()));
// Deleted from list of items without correcting posIndex, but that's ok as about
// to delete the entire InitArray
}
//if (debug()>=9) newp->dumpTreeAndNext(cout, "-InitArrayOut: ");
nodep->replaceWith(newp);
pushDeletep(nodep); VL_DANGLING(nodep);
return; // WIll iterate in a moment
return; // Will iterate in a moment
}
// Hasn't been searched for implicit slices yet
findImplicit(nodep);
@@ -439,44 +438,94 @@ class SliceVisitor : public AstNVisitor {
}
void expandUniOp(AstNodeUniop* nodep) {
nodep->user1(true);
unsigned dim = 0;
if (AstArraySel* selp = nodep->lhsp()->castArraySel()) {
// We have explicit dimensions, either packed or unpacked
dim = explicitDimensions(selp);
}
if (dim == 0 && !nodep->lhsp()->castVarRef()) {
// No ArraySel nor VarRef, not something we can expand
nodep->iterateChildren(*this);
} else {
AstVarRef* refp = findVarRefRecurse(nodep->lhsp());
ArrayDimensions varDim = refp->varp()->dtypep()->dimensions(false);
if ((int)(dim - varDim.second) < 0) {
// Unpacked dimensions are referenced first, make sure we have them all
nodep->v3error("Unary operator used across unpacked dimensions");
if (!nodep->user1()) {
nodep->user1(true);
unsigned dim = 0;
if (AstArraySel* selp = nodep->lhsp()->castArraySel()) {
// We have explicit dimensions, either packed or unpacked
dim = explicitDimensions(selp);
}
if (dim == 0 && !nodep->lhsp()->castVarRef()) {
// No ArraySel nor VarRef, not something we can expand
nodep->iterateChildren(*this);
} else {
AstVarRef* refp = findVarRefRecurse(nodep->lhsp());
ArrayDimensions varDim = refp->varp()->dtypep()->dimensions(false);
if ((int)(dim - varDim.second) < 0) {
// Unpacked dimensions are referenced first, make sure we have them all
nodep->v3error("Unary operator used across unpacked dimensions");
}
}
}
}
virtual void visit(AstRedOr* nodep, AstNUser*) {
if (!nodep->user1()) {
expandUniOp(nodep);
}
expandUniOp(nodep);
}
virtual void visit(AstRedAnd* nodep, AstNUser*) {
if (!nodep->user1()) {
expandUniOp(nodep);
}
expandUniOp(nodep);
}
virtual void visit(AstRedXor* nodep, AstNUser*) {
if (!nodep->user1()) {
expandUniOp(nodep);
}
expandUniOp(nodep);
}
virtual void visit(AstRedXnor* nodep, AstNUser*) {
expandUniOp(nodep);
}
void expandBiOp(AstNodeBiop* nodep) {
if (!nodep->user1()) {
expandUniOp(nodep);
nodep->user1(true);
// If it's a unpacked array, blow it up into comparing each element
AstNodeDType* fromDtp = nodep->lhsp()->dtypep()->skipRefp();
UINFO(9, " Bi-Eq/Neq expansion "<<nodep<<endl);
if (AstUnpackArrayDType* adtypep = fromDtp->castUnpackArrayDType()) {
AstNodeBiop* logp = NULL;
for (int index = adtypep->rangep()->lsbConst();
index <= adtypep->rangep()->msbConst(); ++index) {
// EQ(a,b) -> LOGAND(EQ(ARRAYSEL(a,0), ARRAYSEL(b,0)), ...[1])
AstNodeBiop* clonep = nodep->cloneType
(new AstArraySel(nodep->fileline(),
nodep->lhsp()->cloneTree(false),
index),
new AstArraySel(nodep->fileline(),
nodep->rhsp()->cloneTree(false),
index))->castNodeBiop();
if (!logp) logp = clonep;
else {
switch (nodep->type()) {
case AstType::atEQ: // FALLTHRU
case AstType::atEQCASE:
logp = new AstLogAnd(nodep->fileline(), logp, clonep);
break;
case AstType::atNEQ: // FALLTHRU
case AstType::atNEQCASE:
logp = new AstLogOr(nodep->fileline(), logp, clonep);
break;
default:
nodep->v3fatalSrc("Unknown node type processing array slice");
break;
}
}
}
if (!logp) nodep->v3fatalSrc("Unpacked array with empty indices range");
nodep->replaceWith(logp);
pushDeletep(nodep); VL_DANGLING(nodep);
nodep = logp;
}
nodep->iterateChildren(*this);
}
}
virtual void visit(AstEq* nodep, AstNUser*) {
expandBiOp(nodep);
}
virtual void visit(AstNeq* nodep, AstNUser*) {
expandBiOp(nodep);
}
virtual void visit(AstEqCase* nodep, AstNUser*) {
expandBiOp(nodep);
}
virtual void visit(AstNeqCase* nodep, AstNUser*) {
expandBiOp(nodep);
}
virtual void visit(AstNode* nodep, AstNUser*) {
// Default: Just iterate
+2 -2
View File
@@ -328,7 +328,7 @@ private:
setp = new AstConst (outnump->fileline(), *outnump);
}
// Note InitArray requires us to have the values in inValue order
m_tableVarps[outnum]->varp()->valuep()->castInitArray()->addInitsp(setp);
m_tableVarps[outnum]->varp()->valuep()->castInitArray()->addValuep(setp);
outnum++;
}
@@ -336,7 +336,7 @@ private:
if (inValue != inValueNextInitArray++)
nodep->v3fatalSrc("InitArray requires us to have the values in inValue order");
AstNode* setp = new AstConst (nodep->fileline(), outputChgMask);
chgVscp->varp()->valuep()->castInitArray()->addInitsp(setp);
chgVscp->varp()->valuep()->castInitArray()->addValuep(setp);
}
} // each value
}
+9 -4
View File
@@ -584,9 +584,14 @@ private:
return new AstCStmt(portp->fileline(), stmt);
}
AstNode* createAssignInternalToDpi(AstVar* portp, bool isPtr, const string& frSuffix, const string& toSuffix) {
AstNode* createAssignInternalToDpi(AstVar* portp, bool isRtn, bool isPtr,
const string& frSuffix, const string& toSuffix) {
// Create assignment from internal format into DPI temporary
bool bitvec = (portp->basicp()->isBitLogic() && portp->width() > 32);
if (isRtn && bitvec) {
portp->v3error("DPI functions cannot return > 32 bits; use a two-state type or task instead: "<<portp->prettyName());
// Code below works, but won't compile right, and IEEE illegal
}
string stmt;
string ket;
// Someday we'll have better type support, and this can make variables and casts.
@@ -727,14 +732,14 @@ private:
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (portp->isIO() && portp->isOutput() && !portp->isFuncReturn()) {
dpip->addStmtsp(createAssignInternalToDpi(portp,true,"__Vcvt",""));
dpip->addStmtsp(createAssignInternalToDpi(portp,false,true,"__Vcvt",""));
}
}
}
if (rtnvarp) {
dpip->addStmtsp(createDpiTemp(rtnvarp,""));
dpip->addStmtsp(createAssignInternalToDpi(rtnvarp,false,"__Vcvt",""));
dpip->addStmtsp(createAssignInternalToDpi(rtnvarp,true,false,"__Vcvt",""));
string stmt = "return "+rtnvarp->name()+";\n";
dpip->addStmtsp(new AstCStmt(nodep->fileline(), stmt));
}
@@ -784,7 +789,7 @@ private:
cfuncp->addStmtsp(createDpiTemp(portp,"__Vcvt"));
if (portp->isInput()) {
cfuncp->addStmtsp(createAssignInternalToDpi(portp,false,"","__Vcvt"));
cfuncp->addStmtsp(createAssignInternalToDpi(portp,false,false,"","__Vcvt"));
}
}
}
+11 -7
View File
@@ -206,8 +206,13 @@ private:
AstTraceInc* nodep = vvertexp->nodep();
if (nodep->valuep()) {
if (nodep->valuep()->backp() != nodep) nodep->v3fatalSrc("Trace duplicate back needs consistency, so we can map duplicates back to TRACEINCs");
hashed.hashAndInsert(nodep->valuep());
hashed.hash(nodep->valuep());
UINFO(8, " Hashed "<<hex<<hashed.nodeHash(nodep->valuep())<<" "<<nodep<<endl);
// Just keep one node in the map and point all duplicates to this node
if (hashed.findDuplicate(nodep->valuep()) == hashed.end()) {
hashed.hashAndInsert(nodep->valuep());
}
}
}
}
@@ -223,11 +228,8 @@ private:
TraceTraceVertex* dupvertexp = dynamic_cast<TraceTraceVertex*>(dupincp->user1p()->castGraphVertex());
UINFO(8," Orig "<<nodep<<endl);
UINFO(8," dup "<<dupincp<<endl);
// Mark the found node as a duplicate of the first node
// (Not vice-versa as we get the iterator for the found node)
dupvertexp->duplicatep(vvertexp);
// Remove node from comparison so don't hit it again
hashed.erase(dupit);
// Mark the hashed node as the original and our iterating node as duplicated
vvertexp->duplicatep(dupvertexp);
}
}
}
@@ -493,11 +495,13 @@ private:
//if (debug()>=9) nodep->dumpTree(cout,"- assnnode: ");
// Find non-duplicated node; note some nodep's maybe null, as they were deleted below
TraceTraceVertex* dupvertexp = vvertexp;
while (dupvertexp->duplicatep()) {
if (dupvertexp->duplicatep()) {
dupvertexp = dupvertexp->duplicatep();
UINFO(9," dupOf "<<((void*)dupvertexp)<<" "<<((void*)dupvertexp->nodep())
<<" "<<dupvertexp<<endl);
if (dupvertexp->duplicatep()) dupvertexp->nodep()->v3fatalSrc("Original node was marked as a duplicate");
}
if (dupvertexp != vvertexp) {
// It's an exact copy. We'll assign the code to the master on
// the first one we hit; the later ones will share the code.
+1 -1
View File
@@ -68,7 +68,6 @@ private:
// Return true if this shouldn't be traced
// See also similar rule in V3Coverage::varIgnoreToggle
AstVar* varp = nodep->varp();
string prettyName = varp->prettyName();
if (!varp->isTrace()) {
return "Verilator trace_off";
}
@@ -76,6 +75,7 @@ private:
return "Verilator cell trace_off";
}
else if (!v3Global.opt.traceUnderscore()) {
string prettyName = varp->prettyName();
if (prettyName.size()>=1 && prettyName[0] == '_')
return "Leading underscore";
if (prettyName.find("._") != string::npos)
+29 -24
View File
@@ -1493,6 +1493,7 @@ private:
nodep->v3error("Unsupported: Arguments passed to enum.next method");
}
// Need a runtime lookup table. Yuk.
// Most enums unless overridden are 32 bits, so we size array based on max enum value used.
// Ideally we would have a fast algorithm when a number is
// of small width and complete and so can use an array, and
// a map for when the value is many bits and sparse.
@@ -1503,15 +1504,20 @@ private:
if (!vconstp) nodep->v3fatalSrc("Enum item without constified value");
if (vconstp->toUQuad() >= msbdim) msbdim = vconstp->toUQuad();
}
if (adtypep->itemsp()->width() > 64 || msbdim >= 1024) {
if (adtypep->itemsp()->width() > 64 || msbdim >= (1<<16)) {
nodep->v3error("Unsupported; enum next/prev method on enum with > 10 bits");
return;
}
}
AstVar* varp = enumVarp(adtypep, attrType, msbdim);
int selwidth = V3Number::log2b(msbdim)+1; // Width to address a bit
AstVar* varp = enumVarp(adtypep, attrType, (VL_ULL(1)<<selwidth)-1);
AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, false);
varrefp->packagep(v3Global.rootp()->dollarUnitPkgAddp());
AstNode* newp = new AstArraySel(nodep->fileline(), varrefp, nodep->fromp()->unlinkFrBack());
AstNode* newp = new AstArraySel(nodep->fileline(), varrefp,
// Select in case widths are off due to msblen!=width
new AstSel(nodep->fileline(),
nodep->fromp()->unlinkFrBack(),
0, selwidth));
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
} else {
nodep->v3error("Unknown built-in enum method '"<<nodep->fromp()->prettyTypeName()<<"'");
@@ -1697,11 +1703,13 @@ private:
}
if (arrayp->castUnpackArrayDType()) {
if (!newp) {
newp = new AstInitArray(nodep->fileline(), arrayp, valuep);
AstInitArray* newap = new AstInitArray(nodep->fileline(), arrayp, NULL);
newap->addValuep(valuep);
newp = newap;
} else {
// We iterate hi()..lo() as that is what packed needs,
// but INITARRAY needs lo() first
newp->castInitArray()->initsp()->addHereThisAsNext(valuep);
newp->castInitArray()->addFrontValuep(valuep);
}
} else { // Packed. Convert to concat for now.
if (!newp) newp = valuep;
@@ -2624,9 +2632,6 @@ private:
AstNode* shiftp = nodep->rhsp();
nodep->rhsp()->replaceWith(new AstConst(shiftp->fileline(), num));
shiftp->deleteTree(); VL_DANGLING(shiftp);
} 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");
}
}
}
@@ -3403,9 +3408,9 @@ private:
// Add to root, as don't know module we are in, and aids later structure sharing
v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp);
// Element 0 is a non-index and has speced values
initp->addInitsp(dimensionValue(nodep, attrType, 0));
initp->addValuep(dimensionValue(nodep, attrType, 0));
for (unsigned i=1; i<msbdim+1; ++i) {
initp->addInitsp(dimensionValue(nodep, attrType, i));
initp->addValuep(dimensionValue(nodep, attrType, i));
}
varp->iterate(*this); // May have already done $unit so must do this var
m_tableMap.insert(make_pair(make_pair(nodep,attrType), varp));
@@ -3413,7 +3418,7 @@ private:
}
AstVar* enumVarp(AstEnumDType* nodep, AstAttrType attrType, uint32_t msbdim) {
// Return a variable table which has specified dimension properties for this variable
TableMap::iterator pos = m_tableMap.find(make_pair(nodep,attrType));
TableMap::iterator pos = m_tableMap.find(make_pair(nodep, attrType));
if (pos != m_tableMap.end()) {
return pos->second;
}
@@ -3422,7 +3427,7 @@ private:
if (attrType == AstAttrType::ENUM_NAME) {
basep = nodep->findStringDType();
} else {
basep = nodep->findSigned32DType();
basep = nodep->dtypep();
}
AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(),
basep,
@@ -3438,6 +3443,16 @@ private:
// Add to root, as don't know module we are in, and aids later structure sharing
v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp);
// Default for all unspecified values
if (attrType == AstAttrType::ENUM_NAME) {
initp->defaultp(new AstConst(nodep->fileline(), AstConst::String(), ""));
} else if (attrType == AstAttrType::ENUM_NEXT
|| attrType == AstAttrType::ENUM_PREV) {
initp->defaultp(new AstConst(nodep->fileline(), V3Number(nodep->fileline(), nodep->width(), 0)));
} else {
nodep->v3fatalSrc("Bad case");
}
// Find valid values and populate
if (!nodep->itemsp()) nodep->v3fatalSrc("enum without items");
vector<AstNode*> values;
@@ -3467,20 +3482,10 @@ private:
itemp = nextp;
}
}
// Fill in all unspecified values and add to table
// Add all specified values to table
for (unsigned i=0; i<(msbdim+1); ++i) {
AstNode* valp = values[i];
if (!valp) {
if (attrType == AstAttrType::ENUM_NAME) {
valp = new AstConst(nodep->fileline(), AstConst::String(), "");
} else if (attrType == AstAttrType::ENUM_NEXT
|| attrType == AstAttrType::ENUM_PREV) {
valp = new AstConst(nodep->fileline(), V3Number(nodep->fileline(), nodep->width(), 0));
} else {
nodep->v3fatalSrc("Bad case");
}
}
initp->addInitsp(valp);
if (valp) initp->addIndexValuep(i, valp);
}
varp->iterate(*this); // May have already done $unit so must do this var
m_tableMap.insert(make_pair(make_pair(nodep,attrType), varp));
+1 -1
View File
@@ -261,6 +261,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"endtable" { yyerrorf("Syntax error: ENDTABLE outside of TABLE"); }
"endtask" { FL; return yENDTASK; }
"for" { FL; return yFOR; }
"foreach" { FL; return yFOREACH; }
"forever" { FL; return yFOREVER; }
"function" { FL; return yFUNCTION; }
"if" { FL; return yIF; }
@@ -486,7 +487,6 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"extends" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"extern" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"first_match" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"foreach" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"forkjoin" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"ignore_bins" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"illegal_bins" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
+18 -1
View File
@@ -344,6 +344,7 @@ class AstSenTree;
%token<fl> yEXPORT "export"
%token<fl> yFINAL "final"
%token<fl> yFOR "for"
%token<fl> yFOREACH "foreach"
%token<fl> yFOREVER "forever"
%token<fl> yFUNCTION "function"
%token<fl> yGENERATE "generate"
@@ -2327,7 +2328,7 @@ statement_item<nodep>: // IEEE: statement_item
{ $$ = 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 }
| yFOREACH '(' idClassForeach '[' loop_variables ']' ')' stmtBlock { $$ = new AstForeach($1,$3,$5,$8); }
//
// // IEEE: jump_statement
| yRETURN ';' { $$ = new AstReturn($1); }
@@ -2559,6 +2560,11 @@ for_step<nodep>: // IEEE: for_step
genvar_iteration { $$ = $1; }
;
loop_variables<nodep>: // IEEE: loop_variables
varRefBase { $$ = $1; }
| loop_variables ',' varRefBase { $$ = $1;$1->addNext($3); }
;
//************************************************
// Functions/tasks
@@ -3546,6 +3552,17 @@ idArrayed<nodep>: // IEEE: id + select
| idArrayed '[' expr yP_MINUSCOLON constExpr ']' { $$ = new AstSelMinus($2,$1,$3,$5); }
;
idClassForeach<nodep>:
idForeach { $$ = $1; }
| package_scopeIdFollows idForeach { $$ = AstDot::newIfPkg($2->fileline(), $1, $2); }
;
idForeach<nodep>:
varRefBase { $$ = $1; }
| idForeach '.' varRefBase { $$ = new AstDot($2,$1,$3); }
;
// VarRef without any dots or vectorizaion
varRefBase<varrefp>:
id { $$ = new AstVarRef($<fl>1,*$1,false);}
+1 -1
View File
@@ -13,7 +13,7 @@
// please note it here, otherwise:**
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2015 by ____YOUR_NAME_HERE____.
// without warranty, 2016 by ____YOUR_NAME_HERE____.
module t (/*AUTOARG*/
// Inputs
+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;
+58
View File
@@ -0,0 +1,58 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2016 by Andrew Bardsley.
// bug1071
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
reg [3:0] array_1 [2:0];
reg [3:0] array_2 [2:0];
reg [3:0] array_3 [3:1];
reg [3:0] elem;
reg array_1_ne_array_2;
reg array_1_eq_array_2;
reg array_1_ne_array_3;
reg array_1_eq_array_3;
initial begin
array_1[0] = 4'b1000;
array_1[1] = 4'b1000;
array_1[2] = 4'b1000;
array_2[0] = 4'b1000;
array_2[1] = 4'b1000;
array_2[2] = 4'b1000;
array_3[1] = 4'b1000;
array_3[2] = 4'b0100;
array_3[3] = 4'b0100;
// Comparisons only compare elements 0
array_1_ne_array_2 = array_1 != array_2; // 0
array_1_eq_array_2 = array_1 == array_2; // 0
array_1_ne_array_3 = array_1 != array_3; // 1
array_1_eq_array_3 = array_1 == array_3; // 1
`ifdef TEST_VERBOSE
$write("array_1_ne_array2==%0d\n", array_1_ne_array_2);
$write("array_1_ne_array3==%0d\n", array_1_ne_array_3);
`endif
if (array_1_ne_array_2 !== 0) $stop;
if (array_1_eq_array_2 !== 1) $stop;
if (array_1_ne_array_3 !== 1) $stop;
if (array_1_eq_array_3 !== 0) $stop;
$write("*-* All Finished *-*\n");
$finish;
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 (
v_flags2 => ["--lint-only"],
fails=>$Self->{v3},
expect=>
'%Error: t/t_dpi_exp_bad.v:\d+: DPI functions cannot return > 32 bits; use a two-state type or task instead: dpix_f_bit48__Vfuncrtn
%Error: Exiting due to .*'
);
ok(1);
1;
+13
View File
@@ -0,0 +1,13 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// Copyright 2009 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.
module t;
export "DPI-C" function dpix_f_bit48;
function bit [47:0] dpix_f_bit48 (bit [47:0] i); dpix_f_bit48 = ~i; endfunction
endmodule
+2
View File
@@ -38,6 +38,8 @@ module t;
function longint dpix_f_longint (longint i); dpix_f_longint = ~i; endfunction
function chandle dpix_f_chandle (chandle i); dpix_f_chandle = i; endfunction
export "DPI-C" task dpix_t_bit48;
task dpix_t_bit48(input bit [47:0] i, output bit [47:0] o); o = ~i; endtask
export "DPI-C" task dpix_t_bit95;
task dpix_t_bit95(input bit [94:0] i, output bit [94:0] o); o = ~i; endtask
export "DPI-C" task dpix_t_bit96;
+13
View File
@@ -46,6 +46,8 @@ extern "C" {
extern int dpix_int123();
extern unsigned char dpix_f_bit(unsigned char i);
extern svBitVecVal dpix_f_bit15(const svBitVecVal* i);
extern svBitVecVal dpix_f_bit48(const svBitVecVal* i);
extern int dpix_f_int(int i);
extern char dpix_f_byte(char i);
extern short int dpix_f_shortint(short int i);
@@ -136,6 +138,17 @@ int dpix_run_tests() {
CHECK_RESULT (unsigned long long, dpix_f_longint(1), 0xfffffffffffffffeULL);
CHECK_RESULT (void*, dpix_f_chandle((void*)(12345)), (void*)(12345));
{
svBitVecVal i_vec48[2] = {0xab782a12,0x8a413bd9};
svBitVecVal o_vec48[2] = {0,0};
dpix_t_bit48(i_vec48, o_vec48);
CHECK_RESULT(int, o_vec48[0], ~i_vec48[0]);
#ifdef VCS // VCS has bug where doesn't clean input
CHECK_RESULT(int, o_vec48[1], (~i_vec48[1]));
#else
CHECK_RESULT(int, o_vec48[1], (~i_vec48[1])&0x0000ffffUL);
#endif
}
{
svBitVecVal i_vec95[3] = {0x72912312,0xab782a12,0x8a413bd9};
svBitVecVal o_vec95[3] = {0,0,0};
+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;
+55
View File
@@ -0,0 +1,55 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2014 by Wilson Snyder.
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
`define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
typedef enum {
E01 = 'h1,
ELARGE = 'hf00d
} my_t;
integer cyc=0;
my_t e;
string all;
// Check runtime
always @ (posedge clk) begin
cyc <= cyc + 1;
if (cyc==0) begin
// Setup
e <= E01;
end
else if (cyc==1) begin
`checks(e.name, "E01");
`checkh(e.next, ELARGE);
e <= ELARGE;
end
else if (cyc==3) begin
`checks(e.name, "ELARGE");
`checkh(e.next, E01);
`checkh(e.prev, E01);
e <= E01;
end
else if (cyc==20) begin
e <= 'h11; // Unknown
end
else if (cyc==20) begin
`checks(e.name, ""); // Unknown
end
else if (cyc==99) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
+5 -5
View File
@@ -12,11 +12,11 @@ module t (/*AUTOARG*/
);
input clk;
typedef enum {
E01 = 1,
E03 = 3,
E04 = 4
} my_t;
typedef enum [3:0] {
E01 = 1,
E03 = 3,
E04 = 4
} my_t;
integer cyc=0;
my_t e;
+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;
+76
View File
@@ -0,0 +1,76 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2016 by Wilson Snyder.
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
module t (/*AUTOARG*/);
// verilator lint_off LITENDIAN
// verilator lint_off WIDTH
reg [63:0] sum;
reg [2:1] [4:3] array [5:6] [7:8];
reg [1:2] [3:4] larray [6:5] [8:7];
function [63:0] crc (input [63:0] sum, input [31:0] a, input [31:0] b, input [31:0] c, input [31:0] d);
crc = {sum[62:0],sum[63]} ^ {4'b0,a[7:0], 4'h0,b[7:0], 4'h0,c[7:0], 4'h0,d[7:0]};
endfunction
initial begin
sum = 0;
foreach (array[a]) begin
sum = crc(sum, a, 0, 0, 0);
end
`checkh(sum, 64'h000000c000000000);
sum = 0;
foreach (array[a,b]) begin
sum = crc(sum, a, b, 0, 0);
end
`checkh(sum, 64'h000003601e000000);
sum = 0;
foreach (array[a,b,c]) begin
sum = crc(sum, a, b, c, 0);
end
`checkh(sum, 64'h00003123fc101000);
sum = 0;
foreach (array[a,b,c,d]) begin
sum = crc(sum, a, b, c, d);
end
`checkh(sum, 64'h0030128ab2a8e557);
//
sum = 0;
foreach (larray[a]) begin
sum = crc(sum, a, 0, 0, 0);
end
`checkh(sum, 64'h0000009000000000);
sum = 0;
foreach (larray[a,b]) begin
sum = crc(sum, a, b, 0, 0);
sum = sum + {4'b0,a[7:0], 4'h0,b[7:0]};
end
`checkh(sum, 64'h000002704b057073);
sum = 0;
foreach (larray[a,b,c]) begin
sum = crc(sum, a, b, c, 0);
end
`checkh(sum, 64'h00002136f9000000);
sum = 0;
foreach (larray[a,b,c,d]) begin
sum = crc(sum, a, b, c, d);
end
`checkh(sum, 64'h0020179aa7aa0aaa);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
@@ -7,8 +7,6 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} and $Self->unsupported("Verilator unsupported, bug978");
compile (
);
+6 -2
View File
@@ -13,10 +13,13 @@ module t (/*AUTOARG*/
input clk;
output [31:0] ign;
parameter [95:0] P6 = 6;
localparam P64 = (1 << P6);
reg [31:0] right;
reg [31:0] left;
reg [63:0] qright;
reg [63:0] qleft;
reg [P64-1:0] qright;
reg [P64-1:0] qleft;
reg [31:0] amt;
assign ign = {31'h0, clk} >>> 4'bx; // bug760
@@ -37,6 +40,7 @@ module t (/*AUTOARG*/
`endif
if (cyc==1) begin
amt <= 32'd0;
if (P64 != 64) $stop;
if (5'b10110>>2 != 5'b00101) $stop;
if (5'b10110>>>2 != 5'b00101) $stop; // Note it cares about sign-ness
if (5'b10110<<2 != 5'b11000) $stop;
+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 2010 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
compile (
verilator_flags2 => ["--lint-only"],
fails=>1,
expect=>
'%Error: Internal Error: .*: Value too wide for 32-bits expected in this context 64\'h123456789abcdef
.',
);
ok(1);
1;
+20
View File
@@ -0,0 +1,20 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2016 by Wilson Snyder.
module t (/*AUTOARG*/
// Outputs
o,
// Inputs
clk, i
);
input clk;
input [31:0] i;
output [31:0] o;
assign o = i << 64'h01234567_89abcdef;
endmodule
-2
View File
@@ -7,8 +7,6 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} and $Self->unsupported("Verilator unsupported, bug474");
compile (
);
+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;
+28
View File
@@ -0,0 +1,28 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2016 by Mandy Xu.
// verilator lint_off WIDTH
//bug1088
module t (/*AUTOARG*/
// Outputs
err_count,
// Inputs
clk, syndromes
);
input clk;
input [7:0] syndromes;
output reg [1:0] err_count = 0;
localparam [95:0] M = 96'h4;
wire [3:0] syn1 = syndromes[0+:M];
always @(posedge clk) begin
err_count <= {1'b0, |syn1};
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
-4
View File
@@ -7,10 +7,6 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# Really we shouldn't need to warn in this case.
# When supported, make a new test case that checks the warning
#$Self->{vlt} and $Self->unsupported("Verilator unsupported, bug477");
top_filename("t/t_param_sel_range.v");
compile (
+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;
+30
View File
@@ -0,0 +1,30 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2016 by Mandy Xu.
module t
#(parameter[95:0] P = 1)
(input clk);
localparam [32:0] M = 4;
function [M:0] gen_matrix;
gen_matrix[0] = 1>> M;
endfunction
reg [95: 0] lfsr = 0;
always @(posedge clk) begin
lfsr <= (1 >> P);
end
wire [95: 0] lfsr_w = 1 >> P;
localparam [95: 0] lfsr_p = 1 >> P;
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+16
View File
@@ -0,0 +1,16 @@
#!/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 ();
ok(1);
1;
+19
View File
@@ -0,0 +1,19 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2016 by Wilson Snyder.
// issue 1991
module t
#(
parameter[96:0] P = 97'h12344321_12344321_12344327
)
(
input [P&7 - 1:0] in,
output [P&7 - 1:0] out
);
wire out = in;
endmodule
+1 -3
View File
@@ -17,9 +17,7 @@ compile (
stdout_filename => $stdout_filename,
fails=>1,
expect=>
'%Error: t_pipe_exit_bad.pf: Intentional bad exit status...
%Error: File not found: t/t_pipe_filter.v
%Error: Exiting due to.*',
'%Error: t_pipe_exit_bad.pf: Intentional bad exit status....*',
);
ok(1);
+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-2009 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 => ['--cc --trace --no-decoration'],
);
execute (
check_finished=>1,
);
file_grep_not ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr!// Body!x);
ok(1);
1;
+22
View File
@@ -0,0 +1,22 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2014 by Wilson Snyder.
module t (clk);
input clk;
integer a_very_long_name_which_we_will_hash_eventually=0;
always @ (posedge clk) begin
a_very_long_name_which_we_will_hash_eventually <= a_very_long_name_which_we_will_hash_eventually + 1;
if (a_very_long_name_which_we_will_hash_eventually == 5) begin
fin();
end
end
task fin;
$write("*-* All Finished *-*\n");
$finish;
endtask
endmodule
+3 -3
View File
@@ -16,9 +16,9 @@ bool check() {
bool verbose = false;
#endif
int Y = (tb->OE1 & !tb->OE2) ? tb->A1
: (!tb->OE1 & tb->OE2) ? tb->A2
: (tb->OE1 & tb->OE2) ? (tb->A1 | tb->A2)
int Y = ((tb->OE1) & (!tb->OE2)) ? tb->A1
: ((!tb->OE1) & (tb->OE2)) ? tb->A2
: ((tb->OE1) & (tb->OE2)) ? (tb->A1 | tb->A2)
: 3; // pullup
int W = (((tb->OE2) ? (tb->A2 & 0x1) : 0) << tb->A1)
+13
View File
@@ -0,0 +1,13 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
#include "Vt_vpi_sc.h"
VM_PREFIX* tb = NULL;
int sc_main(int argc, char *argv[]) {
tb = new VM_PREFIX("tb");
VL_PRINTF("*-* All Finished *-*\n");
tb->final();
return 0;
}
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2010 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 (
# Must not make shell/main or hides bug
make_top_shell => 0,
make_main => 0,
verilator_flags2 => ["--exe --vpi --sc $Self->{t_dir}/t_vpi_sc.cpp"],
);
execute (
check_finished=>1
);
ok(1);
1;
+18
View File
@@ -0,0 +1,18 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// Copyright 2010 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.
module t;
// bug1081 - We don't use VPI, just need SC with VPI
initial begin
$write("%0t: Hello\n", $time);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule : t
+7 -9
View File
@@ -196,7 +196,7 @@ foreach my $op (keys %ops2) {
my $opt_seed=5;
our $Opt_NumOps = 300;
our $Opt_NumOps = 30;
our $Opt_Depth = 4;
our $Opt_Signed = 1;
our $Opt_Raise;
@@ -377,17 +377,15 @@ sub rnd_const {
my $val = Bit::Vector->new($width);
if ($v<25) { # zero
} elsif ($v<50) { # ones
$val->Word_Store(0,~0);
$val->Word_Store(1,~0) if $width>32;
$val->Word_Store(2,~0) if $width>64;
$val->Word_Store(3,~0) if $width>96;
for (my $w=0; $w<$val->Word_Size; ++$w) {
$val->Word_Store(0,~0);
}
} elsif ($v<60) { # one
$val->Word_Store(0,1);
} else { #random
$val->Word_Store(0,rnd_int());
$val->Word_Store(1,rnd_int()) if $width>32;
$val->Word_Store(2,rnd_int()) if $width>64;
$val->Word_Store(3,rnd_int()) if $width>96;
for (my $w=0; $w<$val->Word_Size; ++$w) {
$val->Word_Store($w,rnd_int());
}
}
$treeref->{val} = $val;
}