mirror of
https://github.com/verilator/verilator.git
synced 2026-10-03 16:44:11 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
813d62005d | ||
|
|
411de9bddf | ||
|
|
bd28945374 | ||
|
|
1e4c3751e1 | ||
|
|
5b6f47cd0f | ||
|
|
bec8c5bf4c | ||
|
|
15495bb200 | ||
|
|
999f278971 | ||
|
|
7ca1d35a4e | ||
|
|
2117fe414e | ||
|
|
7d8c51181d | ||
|
|
c30211cb27 | ||
|
|
901da118e5 | ||
|
|
f11757e43a | ||
|
|
3f143317a6 | ||
|
|
45d7312dfc | ||
|
|
26774eb045 | ||
|
|
6789d247e2 | ||
|
|
462bc3d707 | ||
|
|
e1755ea6a8 | ||
|
|
b4a7e4697e | ||
|
|
cd61b1d045 | ||
|
|
24dc36ba4c | ||
|
|
e8e4f1777d | ||
|
|
ae38a26af3 | ||
|
|
8ee94dd7aa | ||
|
|
e741a29d36 | ||
|
|
be1d275151 | ||
|
|
31c9e26e2e | ||
|
|
20ed1ada03 | ||
|
|
891214fa72 | ||
|
|
e819e285e2 | ||
|
|
171c175e54 |
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
//=========================================================================
|
||||
|
||||
|
||||
#if VM_SC
|
||||
# include "verilated_sc.h"
|
||||
#endif
|
||||
#include "verilated.h"
|
||||
#include "verilated_vpi.h"
|
||||
|
||||
|
||||
+39
-30
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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; }
|
||||
|
||||
@@ -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
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);}
|
||||
|
||||
@@ -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
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,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
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
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;
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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};
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,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
|
||||
@@ -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;
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,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 (
|
||||
);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 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;
|
||||
@@ -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
|
||||
@@ -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 (
|
||||
);
|
||||
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,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
|
||||
@@ -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 (
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,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
|
||||
Executable
+16
@@ -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;
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-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;
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Executable
+22
@@ -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;
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user