Compare commits

...
20 Commits
Author SHA1 Message Date
Wilson Snyder 813d62005d Version bump 2016-10-14 19:42:18 -04:00
Wilson Snyder 411de9bddf Commentary. 2016-09-30 18:16:56 -04:00
Wilson Snyder bd28945374 Untabify 2016-09-30 18:14:42 -04:00
Wilson Snyder 1e4c3751e1 Support foreach, bug1078. 2016-09-19 22:00:13 -04:00
Wilson Snyder 5b6f47cd0f If VM_PARALLEL_BUILDS=1, use OPT_FAST and OPT_SLOW. 2016-09-19 19:31:09 -04:00
Wilson Snyder bec8c5bf4c Commentary 2016-09-19 17:55:43 -04:00
Johan Bjork 15495bb200 Improve Verilation performance on trace duplicates, msg2017.
Signed-off-by: Wilson Snyder <[email protected]>
2016-09-19 17:54:42 -04:00
Wilson Snyder 999f278971 Fix concats with wide width, bug1088 continued. 2016-09-16 18:54:28 -04:00
Wilson Snyder 7ca1d35a4e New test. 2016-09-16 18:15:32 -04:00
Wilson Snyder 2117fe414e Fix error on wide numbers that represent shifts, bug1088. 2016-09-14 20:27:20 -04:00
Wilson Snyder 7d8c51181d With --no-decoration also shrink output code indents. 2016-09-13 22:53:09 -04:00
Wilson Snyder c30211cb27 Add --no-decoration to remove output comments, msg2015. 2016-09-13 22:28:07 -04:00
Johan Bjork 901da118e5 Internals: Move prettyName invocation to after option checks in trace and coverage
Signed-off-by: Wilson Snyder <[email protected]>
2016-09-12 21:52:40 -04:00
Wilson Snyder f11757e43a Fix error on wide shift, msg2005. 2016-09-12 18:31:45 -04:00
Wilson Snyder 3f143317a6 Add error on DPI functions > 32 bits, msg1995. 2016-09-10 08:14:17 -04:00
Wilson Snyder 45d7312dfc Improve Verilation performance on internal strings, msg1975. 2016-09-08 22:04:14 -04:00
Wilson Snyder 26774eb045 Fix error on wide numbers that represent small msb/lsb, msg1991. 2016-09-08 21:30:35 -04:00
Wilson Snyder 6789d247e2 Fix SystemC compiles with VPI, bug1081. 2016-08-23 18:05:29 -04:00
Johan Bjork 462bc3d707 Clean up disabled tests for bugs already fixed.
Signed-off-by: Wilson Snyder <[email protected]>
2016-08-23 06:45:25 -04:00
Wilson Snyder e1755ea6a8 devel release 2016-07-30 10:18:52 -04:00
46 changed files with 801 additions and 247 deletions
+21 -2
View File
@@ -1,7 +1,26 @@
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
+149 -140
View File
@@ -19,8 +19,8 @@ require 5.006_001;
use warnings;
BEGIN {
if ($ENV{DIRPROJECT} && $ENV{DIRPROJECT_PERL_BOOT}) {
# Magic to allow author testing of perl packages in local directory
require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT};
# Magic to allow author testing of perl packages in local directory
require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT};
}
}
@@ -71,16 +71,16 @@ foreach my $sw (@ARGV) {
Getopt::Long::config ("no_auto_abbrev","pass_through");
if (! GetOptions (
# Major operating modes
"help" => \&usage,
"debug:s" => \&debug,
# "version!" => \&version, # Also passthru'ed
# Switches
"gdb!" => \$opt_gdb,
"gdbbt!" => \$opt_gdbbt,
# Additional parameters
"<>" => sub {}, # Ignored
)) {
# Major operating modes
"help" => \&usage,
"debug:s" => \&debug,
# "version!" => \&version, # Also passthru'ed
# Switches
"gdb!" => \$opt_gdb,
"gdbbt!" => \$opt_gdbbt,
# Additional parameters
"<>" => sub {}, # Ignored
)) {
pod2usage(-exitstatus=>2, -verbose=>0);
}
@@ -92,22 +92,22 @@ if ($opt_gdbbt && !gdb_works()) {
if ($opt_gdb) {
# Generic GDB interactive
run (("gdb"||$ENV{VERILATOR_GDB})
." ".verilator_bin()
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
." -ex 'set width 0'"
." -ex 'bt'");
." ".verilator_bin()
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
." -ex 'set width 0'"
." -ex 'bt'");
} elsif ($opt_gdbbt && $Debug) {
# Run under GDB to get gdbbt
run ("gdb"
." ".verilator_bin()
." --batch --quiet --return-child-result"
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
." -ex 'set width 0'"
." -ex 'bt'");
." ".verilator_bin()
." --batch --quiet --return-child-result"
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
." -ex 'set width 0'"
." -ex 'bt'");
} else {
# Normal, non gdb
run (verilator_bin()
." ".join(' ',@Opt_Verilator_Sw));
." ".join(' ',@Opt_Verilator_Sw));
}
#----------------------------------------------------------------------
@@ -130,23 +130,23 @@ sub verilator_bin {
my $bin = "";
# Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
my $basename = ($ENV{VERILATOR_BIN}
|| ($Debug ? "verilator_bin_dbg" : "verilator_bin"));
|| ($Debug ? "verilator_bin_dbg" : "verilator_bin"));
if (defined($ENV{VERILATOR_ROOT})) {
my $dir = $ENV{VERILATOR_ROOT};
if (-x "$dir/bin/$basename") { # From a "make install" into VERILATOR_ROOT
$bin = "$dir/bin/$basename";
} else {
$bin = "$dir/$basename"; # From pointing to kit directory
}
my $dir = $ENV{VERILATOR_ROOT};
if (-x "$dir/bin/$basename") { # From a "make install" into VERILATOR_ROOT
$bin = "$dir/bin/$basename";
} else {
$bin = "$dir/$basename"; # From pointing to kit directory
}
} else {
if (-x "$RealBin/$basename") {
$bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
} else {
$bin = $basename; # Find in PATH
}
# Note we don't look under bin/$basename which would be right if running
# in the kit dir. Running that would likely break, since
# VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
if (-x "$RealBin/$basename") {
$bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
} else {
$bin = $basename; # Find in PATH
}
# Note we don't look under bin/$basename which would be right if running
# in the kit dir. Running that would likely break, since
# VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
}
return $bin;
}
@@ -158,10 +158,10 @@ sub verilator_bin {
sub gdb_works {
$! = undef; # Cleanup -x
system("gdb /bin/echo"
." --batch-silent --quiet --return-child-result"
." -ex 'run -n'" # `echo -n`
." -ex 'set width 0'"
." -ex 'bt'");
." --batch-silent --quiet --return-child-result"
." -ex 'run -n'" # `echo -n`
." -ex 'set width 0'"
." -ex 'bt'");
my $status = $?;
return $status==0;
}
@@ -174,23 +174,23 @@ sub run {
system($command);
my $status = $?;
if ($status) {
if ($! =~ /no such file or directory/i) {
warn "%Error: verilator: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
}
if ($Debug) { # For easy rerunning
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
warn "%Error: $command\n";
}
if ($status & 127) {
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
warn "%Error: Verilator internal fault, sorry. Consider trying --debug --gdbbt\n" if !$Debug;
} elsif (($status & 127) == 6) { # SIGABRT
warn "%Error: Verilator aborted. Consider trying --debug --gdbbt\n" if !$Debug;
} else {
warn "%Error: Verilator threw signal $status. Consider trying --debug --gdbbt\n" if !$Debug;
}
}
die "%Error: Command Failed $command\n";
if ($! =~ /no such file or directory/i) {
warn "%Error: verilator: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
}
if ($Debug) { # For easy rerunning
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
warn "%Error: $command\n";
}
if ($status & 127) {
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
warn "%Error: Verilator internal fault, sorry. Consider trying --debug --gdbbt\n" if !$Debug;
} elsif (($status & 127) == 6) { # SIGABRT
warn "%Error: Verilator aborted. Consider trying --debug --gdbbt\n" if !$Debug;
} else {
warn "%Error: Verilator threw signal $status. Consider trying --debug --gdbbt\n" if !$Debug;
}
}
die "%Error: Command Failed $command\n";
}
}
@@ -300,6 +300,7 @@ descriptions in the next sections for more information.
--Mdir <directory> Name of output object directory
--mod-prefix <topname> Name to prepend to lower classes
--no-clk <signal-name> Prevent marking specified signal as clock
--no-decoration Disable comments and symbol decorations
--no-pins64 Don't use vluint64_t's for 33-64 bit sigs
--no-skip-identical Disable skipping identical output
+notimingchecks Ignored
@@ -323,7 +324,7 @@ descriptions in the next sections for more information.
--public Debugging; see docs
-pvalue+<name>=<value> Overwrite toplevel parameter
--report-unoptflat Extra diagnostics for UNOPTFLAT
--savable Enable model save-restore
--savable Enable model save-restore
--sc Create SystemC output
--stats Create statistics file
--stats-vars Provide statistics on variables
@@ -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".
@@ -1328,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;
@@ -1353,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
@@ -1362,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
@@ -1371,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
@@ -1393,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);
@@ -1416,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
@@ -1521,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
@@ -1651,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
@@ -1920,8 +1929,8 @@ VerilatedVpi::callValueCbs().
...
while (time passes) {
...
topp->eval();
VerilatedVpi::callValueCbs();
topp->eval();
VerilatedVpi::callValueCbs();
}
@@ -1965,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
@@ -2485,7 +2494,7 @@ 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
@@ -2829,9 +2838,9 @@ 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
@@ -2929,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
@@ -3390,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
@@ -3429,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.
@@ -3631,7 +3640,7 @@ trace file if you want all data to land in the same output file.
tfp->open ("obj_dir/t_trace_ena_cc/simx.vcd");
...
sc_start(1);
...
...
tfp->close();
}
+1 -1
View File
@@ -6,7 +6,7 @@
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[3.886 2016-07-30])
AC_INIT([Verilator],[3.888 2016-10-14])
# When releasing, also update header of Changes file
AC_CONFIG_HEADER(src/config_build.h)
+15 -15
View File
@@ -43,8 +43,9 @@ VK_CPPFLAGS_ALWAYS += \
-I$(VERILATOR_ROOT)/include \
-I$(VERILATOR_ROOT)/include/vltstd \
-DVL_PRINTF=printf \
-DVM_TRACE=$(VM_TRACE) \
-DVM_COVERAGE=$(VM_COVERAGE) \
-DVM_SC=$(VM_SC) \
-DVM_TRACE=$(VM_TRACE) \
$(CFG_CXXFLAGS_NO_UNUSED) \
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
@@ -123,19 +124,10 @@ else
preproc:
endif
#######################################################################
##### SystemC w/o SystemPerl builds
ifeq ($(VM_SC),1)
LIBS += -lm -lstdc++
endif
#######################################################################
##### C/H builds
ifeq ($(VM_PCLI),1)
LIBS += -lm -lstdc++
endif
LIBS += -lm -lstdc++
#######################################################################
# Overall Objects Linking
@@ -171,16 +163,24 @@ $(VM_PREFIX)__ALL.a: $(VK_OBJS)
######################################################################
### Compile rules
#Default rule embedded in make: (Not defined so user makefiles can override it)
#.cpp.o:
# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
ifneq ($(VM_DEFAULT_RULES),0)
$(VM_PREFIX)__ALLsup.o: $(VM_PREFIX)__ALLsup.cpp
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $<
$(VM_PREFIX)__ALLcls.o: $(VM_PREFIX)__ALLcls.cpp
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
$(VM_PREFIX)%__Slow.o: $(VM_PREFIX)%__Slow.cpp
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $<
$(VM_PREFIX)%.o: $(VM_PREFIX)%.cpp
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
endif
#Default rule embedded in make:
#.cpp.o:
# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
######################################################################
### Debugging
+3
View File
@@ -26,6 +26,9 @@
//=========================================================================
#if VM_SC
# include "verilated_sc.h"
#endif
#include "verilated.h"
#include "verilated_vpi.h"
+39 -30
View File
@@ -166,44 +166,53 @@ string AstNode::vcdName(const string& namein) {
}
string AstNode::prettyName(const string& namein) {
// This function is somewhat hot, so we short-circuit some compares
string pretty;
pretty = "";
pretty.reserve(namein.length());
for (const char* pos = namein.c_str(); *pos; ) {
if (0==strncmp(pos,"__BRA__",7)) {
pretty += "[";
pos += 7;
}
else if (0==strncmp(pos,"__KET__",7)) {
pretty += "]";
pos += 7;
}
else if (0==strncmp(pos,"__DOT__",7)) {
pretty += ".";
pos += 7;
}
else if (0==strncmp(pos,"->",2)) {
if (pos[0]=='-' && pos[1]=='>') { // ->
pretty += ".";
pos += 2;
continue;
}
else if (0==strncmp(pos,"__PVT__",7)) {
pretty += "";
pos += 7;
}
else if (pos[0]=='_' && pos[1]=='_' && pos[2]=='0'
&& isxdigit(pos[3]) && isxdigit(pos[4])) {
char value = 0;
value += 16*(isdigit(pos[3]) ? (pos[3]-'0') : (tolower(pos[3])-'a'+10));
value += (isdigit(pos[4]) ? (pos[4]-'0') : (tolower(pos[4])-'a'+10));
pretty += value;
pos += 5;
}
else {
pretty += pos[0];
++pos;
if (pos[0]=='_' && pos[1]=='_') { // Short-circuit
if (0==strncmp(pos,"__BRA__",7)) {
pretty += "[";
pos += 7;
continue;
}
if (0==strncmp(pos,"__KET__",7)) {
pretty += "]";
pos += 7;
continue;
}
if (0==strncmp(pos,"__DOT__",7)) {
pretty += ".";
pos += 7;
continue;
}
if (0==strncmp(pos,"__PVT__",7)) {
pretty += "";
pos += 7;
continue;
}
if (pos[0]=='_' && pos[1]=='_' && pos[2]=='0'
&& isxdigit(pos[3]) && isxdigit(pos[4])) {
char value = 0;
value += 16*(isdigit(pos[3]) ? (pos[3]-'0') : (tolower(pos[3])-'a'+10));
value += (isdigit(pos[4]) ? (pos[4]-'0') : (tolower(pos[4])-'a'+10));
pretty += value;
pos += 5;
continue;
}
}
// Default
pretty += pos[0];
++pos;
}
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
if (pretty.substr(0,5) == "TOP->") pretty.replace(0,5,"");
if (pretty[0]=='T' && pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
if (pretty[0]=='T' && pretty.substr(0,5) == "TOP->") pretty.replace(0,5,"");
return pretty;
}
+17
View File
@@ -2677,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)
+1 -1
View File
@@ -83,10 +83,10 @@ private:
const char* varIgnoreToggle(AstVar* nodep) {
// Return true if this shouldn't be traced
// See also similar rule in V3TraceDecl::varIgnoreTrace
string prettyName = nodep->prettyName();
if (!nodep->isToggleCoverable())
return "Not relevant signal type";
if (!v3Global.opt.coverageUnderscore()) {
string prettyName = nodep->prettyName();
if (prettyName[0] == '_')
return "Leading underscore";
if (prettyName.find("._") != string::npos)
+24 -24
View File
@@ -113,7 +113,7 @@ public:
}
if (AstEnumDType* adtypep = nodep->dtypep()->skipRefToEnump()->castEnumDType()) {
if (adtypep->width()>64) {
puts("// enum "+nodep->name()+" // Ignored: Too wide for C++\n");
putsDecoration("// enum "+nodep->name()+" // Ignored: Too wide for C++\n");
} else {
puts("enum "+nodep->name()+" {\n");
for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp=itemp->nextp()->castEnumItem()) {
@@ -220,7 +220,7 @@ public:
nodep->v3fatalSrc("Case statements should have been reduced out\n");
}
virtual void visit(AstComment* nodep, AstNUser*) {
puts((string)"// "+nodep->name()+" at "+nodep->fileline()->ascii()+"\n");
putsDecoration((string)"// "+nodep->name()+" at "+nodep->fileline()->ascii()+"\n");
nodep->iterateChildren(*this);
}
virtual void visit(AstCoverDecl* nodep, AstNUser*) {
@@ -499,13 +499,13 @@ public:
nodep->bodysp()->iterateAndNext(*this);
}
virtual void visit(AstUCStmt* nodep, AstNUser*) {
puts("// $c statement at "+nodep->fileline()->ascii()+"\n");
putsDecoration("// $c statement at "+nodep->fileline()->ascii()+"\n");
nodep->bodysp()->iterateAndNext(*this);
puts("\n");
}
virtual void visit(AstUCFunc* nodep, AstNUser*) {
puts("\n");
puts("// $c function at "+nodep->fileline()->ascii()+"\n");
putsDecoration("// $c function at "+nodep->fileline()->ascii()+"\n");
nodep->bodysp()->iterateAndNext(*this);
puts("\n");
}
@@ -844,7 +844,7 @@ class EmitCImp : EmitCStmts {
if (nodep->symProlog()) puts(EmitCBaseVisitor::symTopAssign()+"\n");
if (nodep->initsp()) puts("// Variables\n");
if (nodep->initsp()) putsDecoration("// Variables\n");
ofp()->putAlign(V3OutFile::AL_AUTO, 4);
for (AstNode* subnodep=nodep->argsp(); subnodep; subnodep = subnodep->nextp()) {
if (AstVar* varp=subnodep->castVar()) {
@@ -858,11 +858,11 @@ class EmitCImp : EmitCStmts {
nodep->initsp()->iterateAndNext(*this);
if (nodep->stmtsp()) puts("// Body\n");
if (nodep->stmtsp()) putsDecoration("// Body\n");
nodep->stmtsp()->iterateAndNext(*this);
if (!m_blkChangeDetVec.empty()) emitChangeDet();
if (nodep->finalsp()) puts("// Final\n");
if (nodep->finalsp()) putsDecoration("// Final\n");
nodep->finalsp()->iterateAndNext(*this);
//
@@ -873,7 +873,7 @@ class EmitCImp : EmitCStmts {
}
void emitChangeDet() {
puts("// Change detection\n");
putsDecoration("// Change detection\n");
puts("QData __req = false; // Logically a bool\n"); // But not because it results in faster code
bool gotOne = false;
for (vector<AstChangeDet*>::iterator it = m_blkChangeDetVec.begin();
@@ -1474,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");
}
@@ -1494,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");
@@ -1515,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);
@@ -1681,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()) {
@@ -1713,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");
@@ -1887,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()) {
@@ -1939,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");
@@ -2222,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");
@@ -2235,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");
@@ -2250,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");
@@ -2404,16 +2404,16 @@ class EmitCTrace : EmitCStmts {
} else if (nodep->funcType() == AstCFuncType::TRACE_CHANGE_SUB) {
} else nodep->v3fatalSrc("Bad Case");
if (nodep->initsp()) puts("// Variables\n");
if (nodep->initsp()) putsDecoration("// Variables\n");
emitVarList(nodep->initsp(), EVL_ALL, "");
nodep->initsp()->iterateAndNext(*this);
ofp()->putAlign(V3OutFile::AL_AUTO, 4);
puts("// Body\n");
putsDecoration("// Body\n");
puts("{\n");
nodep->stmtsp()->iterateAndNext(*this);
puts("}\n");
if (nodep->finalsp()) puts("// Final\n");
if (nodep->finalsp()) putsDecoration("// Final\n");
nodep->finalsp()->iterateAndNext(*this);
puts("}\n");
}
+1
View File
@@ -43,6 +43,7 @@ public:
V3OutCFile* ofp() const { return m_ofp; }
void puts(const string& str) { ofp()->puts(str); }
void putbs(const string& str) { ofp()->putbs(str); }
void putsDecoration(const string& str) { if (v3Global.opt.decoration()) puts(str); }
void putsQuoted(const string& str) { ofp()->putsQuoted(str); }
bool optSystemC() { return v3Global.opt.systemC(); }
bool optSystemPerl() { return v3Global.opt.systemPerl(); }
+8 -2
View File
@@ -551,10 +551,12 @@ bool V3InFilter::readWholefile(const string& filename, V3InFilter::StrList& outl
// V3OutFormatter: A class for printing to a file, with automatic indentation of C++ code.
V3OutFormatter::V3OutFormatter(const string& filename, V3OutFormatter::Language lang)
: m_filename(filename), m_lang(lang), m_blockIndent(4)
: m_filename(filename), m_lang(lang)
, m_lineno(1), m_column(0)
, m_nobreak(false), m_prependIndent(true), m_indentLevel(0)
, m_declSAlign(0), m_declNSAlign(0), m_declPadNum(0) {
m_blockIndent = v3Global.opt.decoration() ? 4 : 1;
m_commaWidth = v3Global.opt.decoration() ? 50 : 150;
}
//----------------------------------------------------------------------
@@ -682,7 +684,11 @@ void V3OutFormatter::puts (const char *strg) {
break;
case '(':
indentInc();
m_parenVec.push(m_column);
if (v3Global.opt.decoration()) {
m_parenVec.push(m_column); // Line up continuation with open paren, plus one indent
} else {
m_parenVec.push(m_indentLevel*m_blockIndent); // Line up continuation with block+1
}
break;
case ')':
if (!m_parenVec.empty()) m_parenVec.pop();
+2 -2
View File
@@ -97,7 +97,6 @@ public:
class V3OutFormatter {
// TYPES
enum MiscConsts {
WIDTH = 50, // Width after which to break at ,'s
MAXSPACE = 80}; // After this indent, stop indenting more
public:
enum AlignClass {
@@ -115,6 +114,7 @@ private:
string m_filename;
Language m_lang; // Indenting Verilog code
int m_blockIndent; // Characters per block indent
int m_commaWidth; // Width after which to break at ,'s
int m_lineno;
int m_column;
int m_nobreak; // Basic operator or begin paren, don't break next
@@ -147,7 +147,7 @@ public:
void putAlign(bool isstatic/*AlignClass*/, int align, int size=0/*=align*/, const string& prefix=""); // Declare a variable, with natural alignment
void putbs(const char* strg) { putBreakExpr(); puts(strg); }
void putbs(const string& strg) { putBreakExpr(); puts(strg); }
bool exceededWidth() const { return m_column > WIDTH; }
bool exceededWidth() const { return m_column > m_commaWidth; }
bool tokenStart(const char* cp, const char* cmp);
bool tokenEnd(const char* cp);
void indentInc() { m_indentLevel += m_blockIndent; }
+45
View File
@@ -322,6 +322,51 @@ private:
nodep->unlinkFrBack()->deleteTree();
}
virtual void visit(AstForeach* nodep, AstNUser*) {
// FOREACH(array,loopvars,body)
// -> BEGIN(declare vars, loopa=lowest; WHILE(loopa<=highest, ... body))
//nodep->dumpTree(cout, "-foreach-old:");
AstNode* newp = nodep->bodysp()->unlinkFrBackWithNext();
AstNode* arrayp = nodep->arrayp();
int dimension = 1;
// Must do innermost (last) variable first
AstNode* firstVarsp = nodep->varsp()->unlinkFrBackWithNext();
AstNode* lastVarsp = firstVarsp;
while (lastVarsp->nextp()) { lastVarsp = lastVarsp->nextp(); dimension++; }
for (AstNode* varsp = lastVarsp; varsp; varsp=varsp->backp()) {
UINFO(0,"foreachVar "<<varsp<<endl);
FileLine* fl = varsp->fileline();
AstNode* varp = new AstVar(fl, AstVarType::BLOCKTEMP,
varsp->name(), nodep->findSigned32DType());
AstNode* leftp = new AstAttrOf(fl, AstAttrType::DIM_LEFT,
new AstVarRef(fl, arrayp->name(), false),
new AstConst(fl, dimension));
AstNode* rightp = new AstAttrOf(fl, AstAttrType::DIM_RIGHT,
new AstVarRef(fl, arrayp->name(), false),
new AstConst(fl, dimension));
AstNode* stmtsp = varp;
stmtsp->addNext(new AstAssign(fl, new AstVarRef(fl, varp->name(), true), leftp));
AstNode* comparep =
new AstCond(fl, new AstLte(fl, leftp->cloneTree(true), rightp->cloneTree(true)),
// left increments up to right
new AstLte(fl, new AstVarRef(fl, varp->name(), false), rightp->cloneTree(true)),
// left decrements down to right
new AstGte(fl, new AstVarRef(fl, varp->name(), false), rightp));
AstNode* incp =
new AstAssign(fl, new AstVarRef(fl, varp->name(), true),
new AstAdd(fl, new AstVarRef(fl, varp->name(), false),
new AstNegate(fl, new AstAttrOf(fl, AstAttrType::DIM_INCREMENT,
new AstVarRef(fl, arrayp->name(), false),
new AstConst(fl, dimension)))));
stmtsp->addNext(new AstWhile(fl, comparep, newp, incp));
newp = new AstBegin(nodep->fileline(),"",stmtsp);
dimension--;
}
//newp->dumpTree(cout, "-foreach-new:");
firstVarsp->deleteTree(); VL_DANGLING(firstVarsp);
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstNodeModule* nodep, AstNUser*) {
// Module: Create sim table for entire module and iterate
cleanFileline(nodep);
+8 -2
View File
@@ -605,7 +605,10 @@ string V3Number::displayed(FileLine*fl, const string& vformat) const {
uint32_t V3Number::toUInt() const {
UASSERT(!isFourState(),"toUInt with 4-state "<<*this);
UASSERT((width()<33 || (width()<65 && m_value[1]==0)), "Value too wide "<<*this);
// We allow wide numbers that represent values <= 32 bits
for (int i=1; i<words(); ++i) {
UASSERT(!m_value[i], "Value too wide for 32-bits expected in this context "<<*this);
}
return m_value[0];
}
@@ -636,7 +639,10 @@ vlsint32_t V3Number::toSInt() const {
vluint64_t V3Number::toUQuad() const {
UASSERT(!isFourState(),"toUQuad with 4-state "<<*this);
UASSERT(width()<65, "Value too wide "<<*this);
// We allow wide numbers that represent values <= 64 bits
for (int i=2; i<words(); ++i) {
UASSERT(!m_value[i], "Value too wide for 64-bits expected in this context "<<*this);
}
if (width()<=32) return ((vluint64_t)(toUInt()));
return ((vluint64_t)m_value[1]<<VL_ULL(32)) | ((vluint64_t)m_value[0]);
}
+2
View File
@@ -689,6 +689,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if ( onoff (sw, "-debug-check", flag/*ref*/) ){ m_debugCheck = flag; }
else if ( !strcmp (sw, "-debug-sigsegv") ) { throwSigsegv(); } // Undocumented, see also --debug-abort
else if ( !strcmp (sw, "-debug-fatalsrc") ) { v3fatalSrc("--debug-fatal-src"); } // Undocumented, see also --debug-abort
else if ( onoff (sw, "-decoration", flag/*ref*/) ) { m_decoration = flag; }
else if ( onoff (sw, "-dump-tree", flag/*ref*/) ) { m_dumpTree = flag ? 3 : 0; } // Also see --dump-treei
else if ( onoff (sw, "-exe", flag/*ref*/) ) { m_exe = flag; }
else if ( onoff (sw, "-ignc", flag/*ref*/) ) { m_ignc = flag; }
@@ -1199,6 +1200,7 @@ V3Options::V3Options() {
m_coverageUnderscore = false;
m_coverageUser = false;
m_debugCheck = false;
m_decoration = true;
m_exe = false;
m_ignc = false;
m_inhibitSim = false;
+2
View File
@@ -75,6 +75,7 @@ class V3Options {
bool m_coverageUnderscore;// main switch: --coverage-underscore
bool m_coverageUser; // main switch: --coverage-func
bool m_debugCheck; // main switch: --debug-check
bool m_decoration; // main switch: --decoration
bool m_exe; // main switch: --exe
bool m_ignc; // main switch: --ignc
bool m_inhibitSim; // main switch: --inhibit-sim
@@ -226,6 +227,7 @@ class V3Options {
bool coverageUnderscore() const { return m_coverageUnderscore; }
bool coverageUser() const { return m_coverageUser; }
bool debugCheck() const { return m_debugCheck; }
bool decoration() const { return m_decoration; }
bool exe() const { return m_exe; }
bool trace() const { return m_trace; }
bool traceDups() const { return m_traceDups; }
+10 -1
View File
@@ -144,8 +144,12 @@ private:
&& nodep->firstAbovep()->castNodeAssign()
&& assignNoTemp(nodep->firstAbovep()->castNodeAssign())) {
// Not much point if it's just a direct assignment to a constant
} else if (nodep->backp()->castSel()
&& nodep->backp()->castSel()->widthp() == nodep) {
// AstSel::width must remain a constant
} else if (nodep->firstAbovep()
&& nodep->firstAbovep()->castArraySel()) { // ArraySel's are pointer refs, ignore
&& nodep->firstAbovep()->castArraySel()) {
// ArraySel's are pointer refs, ignore
} else {
UINFO(4,"Cre Temp: "<<nodep<<endl);
createDeepTemp(nodep, false);
@@ -263,6 +267,11 @@ private:
// Shifts of > 32/64 bits in C++ will wrap-around and generate non-0s
if (!nodep->user2SetOnce()) {
UINFO(4," ShiftFix "<<nodep<<endl);
AstConst* shiftp = nodep->rhsp()->castConst();
if (shiftp && shiftp->num().mostSetBitP1() > 32) {
shiftp->v3error("Unsupported: Shifting of by over 32-bit number isn't supported."
<<" (This isn't a shift of 32 bits, but a shift of 2^32, or 4 billion!)\n");
}
if (nodep->widthMin()<=64 // Else we'll use large operators which work right
// C operator's width must be < maximum shift which is based on Verilog width
&& nodep->width() < (1LL<<nodep->rhsp()->widthMin())) {
+9 -4
View File
@@ -584,9 +584,14 @@ private:
return new AstCStmt(portp->fileline(), stmt);
}
AstNode* createAssignInternalToDpi(AstVar* portp, bool isPtr, const string& frSuffix, const string& toSuffix) {
AstNode* createAssignInternalToDpi(AstVar* portp, bool isRtn, bool isPtr,
const string& frSuffix, const string& toSuffix) {
// Create assignment from internal format into DPI temporary
bool bitvec = (portp->basicp()->isBitLogic() && portp->width() > 32);
if (isRtn && bitvec) {
portp->v3error("DPI functions cannot return > 32 bits; use a two-state type or task instead: "<<portp->prettyName());
// Code below works, but won't compile right, and IEEE illegal
}
string stmt;
string ket;
// Someday we'll have better type support, and this can make variables and casts.
@@ -727,14 +732,14 @@ private:
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (portp->isIO() && portp->isOutput() && !portp->isFuncReturn()) {
dpip->addStmtsp(createAssignInternalToDpi(portp,true,"__Vcvt",""));
dpip->addStmtsp(createAssignInternalToDpi(portp,false,true,"__Vcvt",""));
}
}
}
if (rtnvarp) {
dpip->addStmtsp(createDpiTemp(rtnvarp,""));
dpip->addStmtsp(createAssignInternalToDpi(rtnvarp,false,"__Vcvt",""));
dpip->addStmtsp(createAssignInternalToDpi(rtnvarp,true,false,"__Vcvt",""));
string stmt = "return "+rtnvarp->name()+";\n";
dpip->addStmtsp(new AstCStmt(nodep->fileline(), stmt));
}
@@ -784,7 +789,7 @@ private:
cfuncp->addStmtsp(createDpiTemp(portp,"__Vcvt"));
if (portp->isInput()) {
cfuncp->addStmtsp(createAssignInternalToDpi(portp,false,"","__Vcvt"));
cfuncp->addStmtsp(createAssignInternalToDpi(portp,false,false,"","__Vcvt"));
}
}
}
+11 -7
View File
@@ -206,8 +206,13 @@ private:
AstTraceInc* nodep = vvertexp->nodep();
if (nodep->valuep()) {
if (nodep->valuep()->backp() != nodep) nodep->v3fatalSrc("Trace duplicate back needs consistency, so we can map duplicates back to TRACEINCs");
hashed.hashAndInsert(nodep->valuep());
hashed.hash(nodep->valuep());
UINFO(8, " Hashed "<<hex<<hashed.nodeHash(nodep->valuep())<<" "<<nodep<<endl);
// Just keep one node in the map and point all duplicates to this node
if (hashed.findDuplicate(nodep->valuep()) == hashed.end()) {
hashed.hashAndInsert(nodep->valuep());
}
}
}
}
@@ -223,11 +228,8 @@ private:
TraceTraceVertex* dupvertexp = dynamic_cast<TraceTraceVertex*>(dupincp->user1p()->castGraphVertex());
UINFO(8," Orig "<<nodep<<endl);
UINFO(8," dup "<<dupincp<<endl);
// Mark the found node as a duplicate of the first node
// (Not vice-versa as we get the iterator for the found node)
dupvertexp->duplicatep(vvertexp);
// Remove node from comparison so don't hit it again
hashed.erase(dupit);
// Mark the hashed node as the original and our iterating node as duplicated
vvertexp->duplicatep(dupvertexp);
}
}
}
@@ -493,11 +495,13 @@ private:
//if (debug()>=9) nodep->dumpTree(cout,"- assnnode: ");
// Find non-duplicated node; note some nodep's maybe null, as they were deleted below
TraceTraceVertex* dupvertexp = vvertexp;
while (dupvertexp->duplicatep()) {
if (dupvertexp->duplicatep()) {
dupvertexp = dupvertexp->duplicatep();
UINFO(9," dupOf "<<((void*)dupvertexp)<<" "<<((void*)dupvertexp->nodep())
<<" "<<dupvertexp<<endl);
if (dupvertexp->duplicatep()) dupvertexp->nodep()->v3fatalSrc("Original node was marked as a duplicate");
}
if (dupvertexp != vvertexp) {
// It's an exact copy. We'll assign the code to the master on
// the first one we hit; the later ones will share the code.
+1 -1
View File
@@ -68,7 +68,6 @@ private:
// Return true if this shouldn't be traced
// See also similar rule in V3Coverage::varIgnoreToggle
AstVar* varp = nodep->varp();
string prettyName = varp->prettyName();
if (!varp->isTrace()) {
return "Verilator trace_off";
}
@@ -76,6 +75,7 @@ private:
return "Verilator cell trace_off";
}
else if (!v3Global.opt.traceUnderscore()) {
string prettyName = varp->prettyName();
if (prettyName.size()>=1 && prettyName[0] == '_')
return "Leading underscore";
if (prettyName.find("._") != string::npos)
-3
View File
@@ -2632,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");
}
}
}
+1 -1
View File
@@ -261,6 +261,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"endtable" { yyerrorf("Syntax error: ENDTABLE outside of TABLE"); }
"endtask" { FL; return yENDTASK; }
"for" { FL; return yFOR; }
"foreach" { FL; return yFOREACH; }
"forever" { FL; return yFOREVER; }
"function" { FL; return yFUNCTION; }
"if" { FL; return yIF; }
@@ -486,7 +487,6 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"extends" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"extern" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"first_match" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"foreach" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"forkjoin" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"ignore_bins" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"illegal_bins" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
+18 -1
View File
@@ -344,6 +344,7 @@ class AstSenTree;
%token<fl> yEXPORT "export"
%token<fl> yFINAL "final"
%token<fl> yFOR "for"
%token<fl> yFOREACH "foreach"
%token<fl> yFOREVER "forever"
%token<fl> yFUNCTION "function"
%token<fl> yGENERATE "generate"
@@ -2327,7 +2328,7 @@ statement_item<nodep>: // IEEE: statement_item
{ $$ = new AstBegin($1,"",$3); $3->addNext(new AstWhile($1, $4,$8,$6)); }
| yDO stmtBlock yWHILE '(' expr ')' ';' { $$ = $2->cloneTree(true); $$->addNext(new AstWhile($1,$5,$2));}
// // IEEE says array_identifier here, but dotted accepted in VMM and 1800-2009
//UNSUP yFOREACH '(' idClassForeach/*array_id[loop_variables]*/ ')' stmt { UNSUP }
| yFOREACH '(' idClassForeach '[' loop_variables ']' ')' stmtBlock { $$ = new AstForeach($1,$3,$5,$8); }
//
// // IEEE: jump_statement
| yRETURN ';' { $$ = new AstReturn($1); }
@@ -2559,6 +2560,11 @@ for_step<nodep>: // IEEE: for_step
genvar_iteration { $$ = $1; }
;
loop_variables<nodep>: // IEEE: loop_variables
varRefBase { $$ = $1; }
| loop_variables ',' varRefBase { $$ = $1;$1->addNext($3); }
;
//************************************************
// Functions/tasks
@@ -3546,6 +3552,17 @@ idArrayed<nodep>: // IEEE: id + select
| idArrayed '[' expr yP_MINUSCOLON constExpr ']' { $$ = new AstSelMinus($2,$1,$3,$5); }
;
idClassForeach<nodep>:
idForeach { $$ = $1; }
| package_scopeIdFollows idForeach { $$ = AstDot::newIfPkg($2->fileline(), $1, $2); }
;
idForeach<nodep>:
varRefBase { $$ = $1; }
| idForeach '.' varRefBase { $$ = new AstDot($2,$1,$3); }
;
// VarRef without any dots or vectorizaion
varRefBase<varrefp>:
id { $$ = new AstVarRef($<fl>1,*$1,false);}
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
v_flags2 => ["--lint-only"],
fails=>$Self->{v3},
expect=>
'%Error: t/t_dpi_exp_bad.v:\d+: DPI functions cannot return > 32 bits; use a two-state type or task instead: dpix_f_bit48__Vfuncrtn
%Error: Exiting due to .*'
);
ok(1);
1;
+13
View File
@@ -0,0 +1,13 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// Copyright 2009 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
module t;
export "DPI-C" function dpix_f_bit48;
function bit [47:0] dpix_f_bit48 (bit [47:0] i); dpix_f_bit48 = ~i; endfunction
endmodule
+2
View File
@@ -38,6 +38,8 @@ module t;
function longint dpix_f_longint (longint i); dpix_f_longint = ~i; endfunction
function chandle dpix_f_chandle (chandle i); dpix_f_chandle = i; endfunction
export "DPI-C" task dpix_t_bit48;
task dpix_t_bit48(input bit [47:0] i, output bit [47:0] o); o = ~i; endtask
export "DPI-C" task dpix_t_bit95;
task dpix_t_bit95(input bit [94:0] i, output bit [94:0] o); o = ~i; endtask
export "DPI-C" task dpix_t_bit96;
+13
View File
@@ -46,6 +46,8 @@ extern "C" {
extern int dpix_int123();
extern unsigned char dpix_f_bit(unsigned char i);
extern svBitVecVal dpix_f_bit15(const svBitVecVal* i);
extern svBitVecVal dpix_f_bit48(const svBitVecVal* i);
extern int dpix_f_int(int i);
extern char dpix_f_byte(char i);
extern short int dpix_f_shortint(short int i);
@@ -136,6 +138,17 @@ int dpix_run_tests() {
CHECK_RESULT (unsigned long long, dpix_f_longint(1), 0xfffffffffffffffeULL);
CHECK_RESULT (void*, dpix_f_chandle((void*)(12345)), (void*)(12345));
{
svBitVecVal i_vec48[2] = {0xab782a12,0x8a413bd9};
svBitVecVal o_vec48[2] = {0,0};
dpix_t_bit48(i_vec48, o_vec48);
CHECK_RESULT(int, o_vec48[0], ~i_vec48[0]);
#ifdef VCS // VCS has bug where doesn't clean input
CHECK_RESULT(int, o_vec48[1], (~i_vec48[1]));
#else
CHECK_RESULT(int, o_vec48[1], (~i_vec48[1])&0x0000ffffUL);
#endif
}
{
svBitVecVal i_vec95[3] = {0x72912312,0xab782a12,0x8a413bd9};
svBitVecVal o_vec95[3] = {0,0,0};
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+76
View File
@@ -0,0 +1,76 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2016 by Wilson Snyder.
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
module t (/*AUTOARG*/);
// verilator lint_off LITENDIAN
// verilator lint_off WIDTH
reg [63:0] sum;
reg [2:1] [4:3] array [5:6] [7:8];
reg [1:2] [3:4] larray [6:5] [8:7];
function [63:0] crc (input [63:0] sum, input [31:0] a, input [31:0] b, input [31:0] c, input [31:0] d);
crc = {sum[62:0],sum[63]} ^ {4'b0,a[7:0], 4'h0,b[7:0], 4'h0,c[7:0], 4'h0,d[7:0]};
endfunction
initial begin
sum = 0;
foreach (array[a]) begin
sum = crc(sum, a, 0, 0, 0);
end
`checkh(sum, 64'h000000c000000000);
sum = 0;
foreach (array[a,b]) begin
sum = crc(sum, a, b, 0, 0);
end
`checkh(sum, 64'h000003601e000000);
sum = 0;
foreach (array[a,b,c]) begin
sum = crc(sum, a, b, c, 0);
end
`checkh(sum, 64'h00003123fc101000);
sum = 0;
foreach (array[a,b,c,d]) begin
sum = crc(sum, a, b, c, d);
end
`checkh(sum, 64'h0030128ab2a8e557);
//
sum = 0;
foreach (larray[a]) begin
sum = crc(sum, a, 0, 0, 0);
end
`checkh(sum, 64'h0000009000000000);
sum = 0;
foreach (larray[a,b]) begin
sum = crc(sum, a, b, 0, 0);
sum = sum + {4'b0,a[7:0], 4'h0,b[7:0]};
end
`checkh(sum, 64'h000002704b057073);
sum = 0;
foreach (larray[a,b,c]) begin
sum = crc(sum, a, b, c, 0);
end
`checkh(sum, 64'h00002136f9000000);
sum = 0;
foreach (larray[a,b,c,d]) begin
sum = crc(sum, a, b, c, d);
end
`checkh(sum, 64'h0020179aa7aa0aaa);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
@@ -7,8 +7,6 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} and $Self->unsupported("Verilator unsupported, bug978");
compile (
);
+6 -2
View File
@@ -13,10 +13,13 @@ module t (/*AUTOARG*/
input clk;
output [31:0] ign;
parameter [95:0] P6 = 6;
localparam P64 = (1 << P6);
reg [31:0] right;
reg [31:0] left;
reg [63:0] qright;
reg [63:0] qleft;
reg [P64-1:0] qright;
reg [P64-1:0] qleft;
reg [31:0] amt;
assign ign = {31'h0, clk} >>> 4'bx; // bug760
@@ -37,6 +40,7 @@ module t (/*AUTOARG*/
`endif
if (cyc==1) begin
amt <= 32'd0;
if (P64 != 64) $stop;
if (5'b10110>>2 != 5'b00101) $stop;
if (5'b10110>>>2 != 5'b00101) $stop; // Note it cares about sign-ness
if (5'b10110<<2 != 5'b11000) $stop;
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2010 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
compile (
verilator_flags2 => ["--lint-only"],
fails=>1,
expect=>
'%Error: Internal Error: .*: Value too wide for 32-bits expected in this context 64\'h123456789abcdef
.',
);
ok(1);
1;
+20
View File
@@ -0,0 +1,20 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2016 by Wilson Snyder.
module t (/*AUTOARG*/
// Outputs
o,
// Inputs
clk, i
);
input clk;
input [31:0] i;
output [31:0] o;
assign o = i << 64'h01234567_89abcdef;
endmodule
-2
View File
@@ -7,8 +7,6 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} and $Self->unsupported("Verilator unsupported, bug474");
compile (
);
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+28
View File
@@ -0,0 +1,28 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2016 by Mandy Xu.
// verilator lint_off WIDTH
//bug1088
module t (/*AUTOARG*/
// Outputs
err_count,
// Inputs
clk, syndromes
);
input clk;
input [7:0] syndromes;
output reg [1:0] err_count = 0;
localparam [95:0] M = 96'h4;
wire [3:0] syn1 = syndromes[0+:M];
always @(posedge clk) begin
err_count <= {1'b0, |syn1};
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
-4
View File
@@ -7,10 +7,6 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# Really we shouldn't need to warn in this case.
# When supported, make a new test case that checks the warning
#$Self->{vlt} and $Self->unsupported("Verilator unsupported, bug477");
top_filename("t/t_param_sel_range.v");
compile (
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+30
View File
@@ -0,0 +1,30 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2016 by Mandy Xu.
module t
#(parameter[95:0] P = 1)
(input clk);
localparam [32:0] M = 4;
function [M:0] gen_matrix;
gen_matrix[0] = 1>> M;
endfunction
reg [95: 0] lfsr = 0;
always @(posedge clk) begin
lfsr <= (1 >> P);
end
wire [95: 0] lfsr_w = 1 >> P;
localparam [95: 0] lfsr_p = 1 >> P;
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
#execute ();
ok(1);
1;
+19
View File
@@ -0,0 +1,19 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2016 by Wilson Snyder.
// issue 1991
module t
#(
parameter[96:0] P = 97'h12344321_12344321_12344327
)
(
input [P&7 - 1:0] in,
output [P&7 - 1:0] out
);
wire out = in;
endmodule
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
verilator_flags2 => ['--cc --trace --no-decoration'],
);
execute (
check_finished=>1,
);
file_grep_not ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr!// Body!x);
ok(1);
1;
+22
View File
@@ -0,0 +1,22 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2014 by Wilson Snyder.
module t (clk);
input clk;
integer a_very_long_name_which_we_will_hash_eventually=0;
always @ (posedge clk) begin
a_very_long_name_which_we_will_hash_eventually <= a_very_long_name_which_we_will_hash_eventually + 1;
if (a_very_long_name_which_we_will_hash_eventually == 5) begin
fin();
end
end
task fin;
$write("*-* All Finished *-*\n");
$finish;
endtask
endmodule
+13
View File
@@ -0,0 +1,13 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
#include "Vt_vpi_sc.h"
VM_PREFIX* tb = NULL;
int sc_main(int argc, char *argv[]) {
tb = new VM_PREFIX("tb");
VL_PRINTF("*-* All Finished *-*\n");
tb->final();
return 0;
}
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2010 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
# Must not make shell/main or hides bug
make_top_shell => 0,
make_main => 0,
verilator_flags2 => ["--exe --vpi --sc $Self->{t_dir}/t_vpi_sc.cpp"],
);
execute (
check_finished=>1
);
ok(1);
1;
+18
View File
@@ -0,0 +1,18 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// Copyright 2010 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
module t;
// bug1081 - We don't use VPI, just need SC with VPI
initial begin
$write("%0t: Hello\n", $time);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule : t