Compare commits

...
30 Commits
Author SHA1 Message Date
Wilson Snyder c8e437c45c Version bump 2018-08-22 18:09:06 -04:00
Wilson Snyder 4627716aa4 Remove extra space in generated func call. 2018-08-21 18:14:32 -04:00
Wilson Snyder 847dbbbaf0 Fix function inlining inside certain while loops, bug1330. 2018-08-21 18:09:40 -04:00
Wilson Snyder d90064eaee Change MODDUP errors to warnings, msg2588. 2018-07-23 18:57:34 -04:00
Wilson Snyder 8e646bc55f configure: Add URL 2018-07-22 19:44:03 -04:00
Wilson Snyder 3a777c2a37 Verilated: Always define VL_RDTSC, though unused; useful for benchmarking. 2018-07-22 11:53:35 -04:00
Wilson Snyder 237f4806bf Fix doxygen old dir refs. 2018-07-20 19:45:58 -04:00
Wilson Snyder dfe66a2b77 Fix whitespace after functions in generated files. 2018-07-18 22:42:05 -04:00
Wilson Snyder a0b09b6450 Remove tabs inside generated files/quotes. 2018-07-18 21:25:21 -04:00
Wilson Snyder 9e3a88c41d Inability to write a file is typically user, not internal error. 2018-07-14 19:22:50 -04:00
John Coiner 736bf75a50 tests: Allow cmdline args to override test args. 2018-07-05 18:52:25 -04:00
Wilson Snyder 129610821f Ignore automake flags passed by Ubuntu builds 2018-07-03 21:34:50 -04:00
Wilson Snyder 4cd0310516 Update error, bug1322. 2018-07-02 09:11:20 -04:00
Wilson Snyder 4f962bddd8 Fix std:: build error, bug1322. 2018-06-28 18:55:36 -04:00
Wilson Snyder 45eddfb335 Warn if using pre-C++11 so find out who needs it. 2018-06-26 07:33:55 -04:00
Wilson Snyder d4b9b5aba6 Fix to ignore Unicode UTF-8 BOM sequences, msg2576. 2018-06-26 07:11:56 -04:00
Wilson Snyder b1bf742544 Internals: rank() public for future optimizers. 2018-06-24 18:47:08 -04:00
Wilson Snyder cdd70ff8fc Commentary 2018-06-24 08:08:34 -04:00
Wilson Snyder 2b56acb39a Add git_untabify utility 2018-06-22 07:09:21 -04:00
Wilson Snyder 35a40b4930 Commentary 2018-06-22 06:35:27 -04:00
Wilson Snyder ae33a1ceb1 Tests: Add t_gate_tree test 2018-06-21 20:27:33 -04:00
Wilson Snyder d225e46e4a Fix define argument stringification, broke since 3.914. 2018-06-21 08:19:59 -04:00
John Coiner 43d07235c9 Tests: Fix sc_main compilation errors.
Signed-off-by: Wilson Snyder <[email protected]>
2018-06-20 19:01:19 -04:00
Wilson Snyder 047a08c999 Internals: Clean some UASSERTs. No functional change. 2018-06-16 18:00:21 -04:00
Wilson Snyder 1d74657bbb Internals: Remove dead code 2018-06-16 17:59:57 -04:00
Wilson Snyder 65bb93a6c5 Add OBJCACHE envvar support to examples and generated Makefiles. 2018-06-15 07:13:18 -04:00
Wilson Snyder 6e7f28785e Internals: Cleanup graph includes. No functional change. 2018-06-15 06:54:03 -04:00
Wilson Snyder 0eb1d0a84e Fix cppcheck warnings. No functional change intended. 2018-06-14 18:59:24 -04:00
Wilson Snyder 5d26bca55c Internals: Remove unneeded returns on asserts. 2018-06-13 18:05:00 -04:00
Wilson Snyder a15e6f68dd devel release 2018-06-12 21:22:01 -04:00
67 changed files with 820 additions and 247 deletions
+15
View File
@@ -2,6 +2,21 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 3.926 2018-08-22
**** Add OBJCACHE envvar support to examples and generated Makefiles.
**** Change MODDUP errors to warnings, msg2588. [Marshal Qiao]
**** Fix define argument stringification (`"), broke since 3.914. [Joe DErrico]
**** Fix to ignore Unicode UTF-8 BOM sequences, msg2576. [HyungKi Jeong]
**** Fix std:: build error, bug1322.
**** Fix function inlining inside certain while loops, bug1330. [Julien Margetts]
* Verilator 3.924 2018-06-12
*** Renamed --profile-cfuncs to --prof-cfuncs.
+50 -44
View File
@@ -1707,8 +1707,8 @@ needed at runtime.
Optionally specifies a caching or distribution program to place in front of
all runs of the C++ Compiler. For example, "objcache --read --write", or
"ccache". If using distcc, it would generally be run under either objcache
or ccache; see the documentation for those programs.
"ccache". If using distcc or icecc/icecream, they would generally be run
under either objcache or ccache; see the documentation for those programs.
=item SYSTEMC
@@ -3361,10 +3361,14 @@ correctly.
=item MODDUP
Error that a module has multiple definitions. Generally this indicates a
Warns that a module has multiple definitions. Generally this indicates a
coding error, or a mistake in a library file and it's good practice to have
one module per file to avoid these issues. For some gate level netlists
duplicates are unavoidable, and this error may be disabled.
one module per file (and only put each file once on the command line) to
avoid these issues. For some gate level netlists duplicates are sometimes
unavoidable, and MODDUP should be disabled.
Ignoring this warning will cause the more recent module definition to be
discarded.
=item MULTIDRIVEN
@@ -4147,7 +4151,7 @@ When possible, please instead report bugs to L<http://www.veripool.org/>.
Wilson Snyder <[email protected]>
Major concepts by Paul Wasson, Duane Galbi and Jie Xu.
Major concepts by Paul Wasson, Duane Galbi, John Coiner and Jie Xu.
=head1 CONTRIBUTORS
@@ -4171,50 +4175,52 @@ Some of the people who have provided ideas and feedback for Verilator
include: Ahmed El-Mahmoudy, David Addison, Tariq B. Ahmad, Nikana
Anastasiadis, Hans Van Antwerpen, Vasu Arasanipalai, Jens Arm, Sharad
Bagri, Andrew Bardsley, Matthew Barr, Geoff Barrett, Julius Baxter, Jeremy
Bennett, Michael Berman, David Binderman, Johan Bjork, David Black, Daniel
Bone, Gregg Bouchard, Christopher Boumenot, Nick Bowler, Byron Bradley,
Bryan Brady, Charlie Brej, J Briquet, Lane Brooks, John Brownlee, Jeff
Bush, Lawrence Butcher, Ted Campbell, Chris Candler, Lauren Carlson, Donal
Casey, Terry Chen, Enzo Chi, Robert A. Clark, Allan Cochrane, John Coiner,
Gunter Dannoritzer, Ashutosh Das, Bernard Deadman, John Demme, Mike Denio,
John Deroo, Philip Derrick, John Dickol, Ruben Diez, Danny Ding, Ivan
Djordjevic, Jonathon Donaldson, Sebastian Dressler, Alex Duller, Jeff
Dutton, Usuario Eda, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Robert
Bennett, Michael Berman, Victor Besyakov, David Binderman, Johan Bjork,
David Black, Tymoteusz Blazejczyk, Daniel Bone, Gregg Bouchard, Christopher
Boumenot, Nick Bowler, Byron Bradley, Bryan Brady, Charlie Brej, J Briquet,
Lane Brooks, John Brownlee, Jeff Bush, Lawrence Butcher, Ted Campbell,
Chris Candler, Lauren Carlson, Donal Casey, Terry Chen, Enzo Chi, Robert
A. Clark, Allan Cochrane, John Coiner, Laurens van Dam, Gunter Dannoritzer,
Ashutosh Das, Bernard Deadman, John Demme, Mike Denio, John Deroo, Philip
Derrick, Joe DErrico, John Dickol, Ruben Diez, Danny Ding, Ivan Djordjevic,
Jonathon Donaldson, Sebastian Dressler, Alex Duller, Jeff Dutton, Usuario
Eda, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Trevor Elbourne, Robert
Farrell, Eugen Fekete, Fabrizio Ferrandi, Brian Flachs, Andrea Foletto, Bob
Fredieu, Christian Gelinek, Glen Gibb, Shankar Giri, Dan Gisselquist, Sam
Gladstone, Amir Gonnen, Chitlesh Goorah, Xuan Guo, Neil Hamilton, Jannis
Harder, Junji Hashimoto, Thomas Hawkins, Robert Henry, David Hewson, Jamey
Hicks, Hiroki Honda, Alex Hornung, David Horton, Jae Hossell, Alan Hunter,
Jamie Iles, Ben Jackson, Shareef Jalloq, Krzysztof Jankowski, HyungKi
Jeong, Iztok Jeras, James Johnson, Christophe Joly, Franck Jullien, Mike
Kagen, Arthur Kahlich, Kaalia Kahn, Guy-Armand Kamendje, Vasu Kandadi,
Patricio Kaplan, Ralf Karge, Dan Katz, Sol Katzman, Jonathan Kimmitt, Olof
Kindgren, Sobhan Klnv, Gernot Koch, Soon Koh, Steve Kolecki, Brett Koonce,
Wojciech Koszek, Varun Koyyalagunta, David Kravitz, Roland Kruse, Sergey
Kvachonok, Ed Lander, Steve Lang, Stephane Laurent, Walter Lavino,
Christian Leber, Igor Lesik, John Li, Eivind Liland, Charlie Lind, Andrew
Ling, Paul Liu, Derek Lockhart, Arthur Low, Stefan Ludwig, Dan Lussier,
Fred Ma, Duraid Madina, Mark Marshall, Alfonso Martinez, Yves Mathieu,
Patrick Maupin, Jason McMullan, Elliot Mednick, Wim Michiels, Miodrag
Milanovic, Wai Sum Mong, Sean Moore, Dennis Muhlestein, John Murphy,
Richard Myers, Dimitris Nalbantis, Bob Newgard, Cong Van Nguyen, Paul
Nitza, Pete Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, James
Pallister, Brad Parker, Maciej Piechotka, David Pierce, Dominic Plunkett,
David Poole, Mike Popoloski, Rich Porter, Niranjan Prabhu, Usha
Priyadharshini, Mark Jackson Pulver, Prateek Puri, Chris Randall, Anton
Rapp, Odd Magne Reitan, Frederic Requin, Alberto Del Rio, Oleg Rodionov,
Paul Rolfe, Jan Egil Ruud, John Sanguinetti, Galen Seitz, Salman Sheikh,
Hicks, Joel Holdsworth, Hiroki Honda, Alex Hornung, David Horton, Jae
Hossell, Alan Hunter, James Hutchinson, Jamie Iles, Ben Jackson, Shareef
Jalloq, Krzysztof Jankowski, HyungKi Jeong, Iztok Jeras, James Johnson,
Christophe Joly, Franck Jullien, James Jung, Mike Kagen, Arthur Kahlich,
Kaalia Kahn, Guy-Armand Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf
Karge, Dan Katz, Sol Katzman, Jonathan Kimmitt, Olof Kindgren, Dan Kirkham,
Sobhan Klnv, Gernot Koch, Soon Koh, Steve Kolecki, Brett Koonce, Wojciech
Koszek, Varun Koyyalagunta, David Kravitz, Roland Kruse, Sergey Kvachonok,
Ed Lander, Steve Lang, Stephane Laurent, Walter Lavino, Christian Leber,
Igor Lesik, John Li, Eivind Liland, Charlie Lind, Andrew Ling, Paul Liu,
Derek Lockhart, Arthur Low, Stefan Ludwig, Dan Lussier, Fred Ma, Duraid
Madina, Mark Marshall, Alfonso Martinez, Yves Mathieu, Patrick Maupin,
Jason McMullan, Elliot Mednick, Wim Michiels, Miodrag Milanovic, Wai Sum
Mong, Sean Moore, Dennis Muhlestein, John Murphy, Richard Myers, Dimitris
Nalbantis, Bob Newgard, Cong Van Nguyen, Paul Nitza, Pete Nixon, Lisa
Noack, Mark Nodine, Andreas Olofsson, James Pallister, Brad Parker, Maciej
Piechotka, David Pierce, Dominic Plunkett, David Poole, Mike Popoloski,
Rich Porter, Niranjan Prabhu, Usha Priyadharshini, Mark Jackson Pulver,
Prateek Puri, Chris Randall, Anton Rapp, Josh Redford, Odd Magne Reitan,
Frederic Requin, Alberto Del Rio, Oleg Rodionov, Paul Rolfe, Arjen
Roodselaar, Jan Egil Ruud, John Sanguinetti, Galen Seitz, Salman Sheikh,
Mike Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Rodney Sinclair, Steven
Slatter, Brian Small, Alex Solomatnikov, Wei Song, Art Stamness, John
Stevenson, Rob Stoddard, Todd Strader, John Stroebel, Sven Stucki, Emerson
Suguimoto, Gene Sullivan, Renga Sundararajan, Yutetsu Takatsukasa, Peter
Tengstrand, Wesley Terpstra, Stefan Thiede, Gary Thomas, Kevin Thompson,
Ian Thompson, Mike Thyer, Hans Tichelaar, Steve Tong, Michael Tresidder,
Holger Waechtler, Stefan Wallentowitz, Shawn Wang, Greg Waters, Thomas
Watts, Eugene Weber, David Welch, Thomas J Whatson, Leon Wildman, Gerald
Williams, Trevor Williams, Jeff Winston, Joshua Wise, Clifford Wolf, Johan
Wouters, Ding Xiaoliang, Jie Xu, Mandy Xu, Luke Yang, and Amir
Yazdanbakhsh.
Stevenson, Patrick Stewart, Rob Stoddard, Todd Strader, John Stroebel, Sven
Stucki, Emerson Suguimoto, Gene Sullivan, Renga Sundararajan, Yutetsu
Takatsukasa, Peter Tengstrand, Wesley Terpstra, Rui Terra, Stefan Thiede,
Gary Thomas, Kevin Thompson, Ian Thompson, Mike Thyer, Hans Tichelaar,
Steve Tong, Michael Tresidder, Holger Waechtler, Stefan Wallentowitz, Shawn
Wang, Greg Waters, Thomas Watts, Eugene Weber, David Welch, Thomas J
Whatson, Leon Wildman, Gerald Williams, Trevor Williams, Jeff Winston,
Joshua Wise, Clifford Wolf, Johan Wouters, Junyi Xi, Ding Xiaoliang, Jie
Xu, Mandy Xu, Luke Yang, and Amir Yazdanbakhsh.
Thanks to them, and all those we've missed including above.
+41 -1
View File
@@ -6,7 +6,8 @@
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[3.924 2018-06-12])
AC_INIT([Verilator],[3.926 2018-08-22],[https://www.veripool.org/verilator],
[verilator],[https://www.veripool.org/verilator])
# When releasing, also update header of Changes file
# and commit using "devel release" or "Version bump" message
@@ -15,6 +16,14 @@ AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk incl
AC_MSG_RESULT([configuring for $PACKAGE_STRING])
# Ignore automake flags passed by Ubuntu builds
AC_ARG_ENABLE([dependency-tracking],
[AS_HELP_STRING([--disable-dependency-tracking], [ignored])])
AC_ARG_ENABLE([maintainer-mode],
[AS_HELP_STRING([--enable-maintainer-mode], [ignored])])
AC_ARG_ENABLE([silent-rules],
[AS_HELP_STRING([--disable-silent-rules], [ignored])])
# Special Substitutions - CFG_WITH_DEFENV
AC_MSG_CHECKING(whether to use hardcoded paths)
AC_ARG_ENABLE([defenv],
@@ -65,6 +74,21 @@ AC_ARG_ENABLE([longtests],
AC_SUBST(CFG_WITH_LONGTESTS)
AC_MSG_RESULT($CFG_WITH_LONGTESTS)
# CFG_WITH_PREC11
AC_MSG_CHECKING(whether allow pre-C++11)
AC_ARG_ENABLE([prec11],
[AS_HELP_STRING([--enable-prec11],
[enable pre-C++11 compilers])],
[case "${enableval}" in
yes) CFG_WITH_PREC11=yes ;;
no) CFG_WITH_PREC11=no ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-prec11]) ;;
esac],
[CFG_WITH_PREC11=no;]
)
AC_SUBST(CFG_WITH_PREC11)
AC_MSG_RESULT($CFG_WITH_PREC11)
# Compiler flags
CFLAGS=-I${includedir}
CPPFLAGS=-I${includedir}
@@ -250,6 +274,22 @@ CFG_WITH_THREADED=$_my_result
AC_SUBST(CFG_WITH_THREADED)
AC_MSG_RESULT($CFG_WITH_THREADED)
# Check compiler flag
if test "$CFG_WITH_THREADED" = "no" ; then
if test "$CFG_WITH_PREC11" = "no" ; then
AC_MSG_NOTICE([[]])
AC_MSG_ERROR([[the $CXX compiler appears to not support C++11.
Verilator plans to require a C++11 or newer compiler in a future release,
unless sufficient people report problems. Therefore, if you do not have a
C++11 compiler, please post a message to
https://www.veripool.org/boards/3/topics/2580-Verilator-Requiring-C-11-compiler
indicating your OS and when you think C++11 might be ok, and then rerun
configure with the --enable-prec11 argument. Thanks.]])
fi
fi
# Checks for library functions.
AC_CHECK_MEMBER([struct stat.st_mtim.tv_nsec],
[AC_DEFINE([HAVE_STAT_NSEC],[1],[Defined if struct stat has st_mtim.tv_nsec])],
+1 -5
View File
@@ -630,12 +630,8 @@ WARN_LOGFILE =
# with spaces.
INPUT = doxygen-mainpage \
include \
include \
src \
test_c \
test_regress \
test_sc \
test_v
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+3
View File
@@ -17,6 +17,9 @@ default: Vtop
# Include the rules made by Verilator
include Vtop.mk
# Use OBJCACHE (ccache) if using gmake and its installed
COMPILE.cc = $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
#######################################################################
# Compile flags
+3
View File
@@ -17,6 +17,9 @@ default: Vtop
# Include the rules made by Verilator
include Vtop.mk
# Use OBJCACHE (ccache) if using gmake and its installed
COMPILE.cc = $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
#######################################################################
# Compile flags
+1 -1
View File
@@ -327,7 +327,7 @@ public: // But internals only - called from VerilatedModule's
class Verilated {
// MEMBERS
// Slow path variables
static VerilatedMutex m_mutex; ///< Mutex for all static members, when VL_THREADED
static VerilatedMutex m_mutex; ///< Mutex for s_s/s_ns members, when VL_THREADED
static VerilatedVoidCb s_flushCb; ///< Flush callback function
+33 -33
View File
@@ -104,39 +104,39 @@ VLCOVGEN_ITEM("name=>'weight', short=>'w', group=>0, default=>undef, descr
class VerilatedCovKey {
public:
static std::string shortKey(const std::string& key) VL_PURE {
// VLCOVGEN_SHORT_AUTO_EDIT_BEGIN
if (key == "col0") return VL_CIK_COL0;
if (key == "col0_name") return VL_CIK_COL0_NAME;
if (key == "col1") return VL_CIK_COL1;
if (key == "col1_name") return VL_CIK_COL1_NAME;
if (key == "col2") return VL_CIK_COL2;
if (key == "col2_name") return VL_CIK_COL2_NAME;
if (key == "col3") return VL_CIK_COL3;
if (key == "col3_name") return VL_CIK_COL3_NAME;
if (key == "column") return VL_CIK_COLUMN;
if (key == "comment") return VL_CIK_COMMENT;
if (key == "filename") return VL_CIK_FILENAME;
if (key == "groupcmt") return VL_CIK_GROUPCMT;
if (key == "groupdesc") return VL_CIK_GROUPDESC;
if (key == "groupname") return VL_CIK_GROUPNAME;
if (key == "hier") return VL_CIK_HIER;
if (key == "limit") return VL_CIK_LIMIT;
if (key == "lineno") return VL_CIK_LINENO;
if (key == "per_instance") return VL_CIK_PER_INSTANCE;
if (key == "row0") return VL_CIK_ROW0;
if (key == "row0_name") return VL_CIK_ROW0_NAME;
if (key == "row1") return VL_CIK_ROW1;
if (key == "row1_name") return VL_CIK_ROW1_NAME;
if (key == "row2") return VL_CIK_ROW2;
if (key == "row2_name") return VL_CIK_ROW2_NAME;
if (key == "row3") return VL_CIK_ROW3;
if (key == "row3_name") return VL_CIK_ROW3_NAME;
if (key == "table") return VL_CIK_TABLE;
if (key == "thresh") return VL_CIK_THRESH;
if (key == "type") return VL_CIK_TYPE;
if (key == "weight") return VL_CIK_WEIGHT;
// VLCOVGEN_SHORT_AUTO_EDIT_END
return key;
// VLCOVGEN_SHORT_AUTO_EDIT_BEGIN
if (key == "col0") return VL_CIK_COL0;
if (key == "col0_name") return VL_CIK_COL0_NAME;
if (key == "col1") return VL_CIK_COL1;
if (key == "col1_name") return VL_CIK_COL1_NAME;
if (key == "col2") return VL_CIK_COL2;
if (key == "col2_name") return VL_CIK_COL2_NAME;
if (key == "col3") return VL_CIK_COL3;
if (key == "col3_name") return VL_CIK_COL3_NAME;
if (key == "column") return VL_CIK_COLUMN;
if (key == "comment") return VL_CIK_COMMENT;
if (key == "filename") return VL_CIK_FILENAME;
if (key == "groupcmt") return VL_CIK_GROUPCMT;
if (key == "groupdesc") return VL_CIK_GROUPDESC;
if (key == "groupname") return VL_CIK_GROUPNAME;
if (key == "hier") return VL_CIK_HIER;
if (key == "limit") return VL_CIK_LIMIT;
if (key == "lineno") return VL_CIK_LINENO;
if (key == "per_instance") return VL_CIK_PER_INSTANCE;
if (key == "row0") return VL_CIK_ROW0;
if (key == "row0_name") return VL_CIK_ROW0_NAME;
if (key == "row1") return VL_CIK_ROW1;
if (key == "row1_name") return VL_CIK_ROW1_NAME;
if (key == "row2") return VL_CIK_ROW2;
if (key == "row2_name") return VL_CIK_ROW2_NAME;
if (key == "row3") return VL_CIK_ROW3;
if (key == "row3_name") return VL_CIK_ROW3_NAME;
if (key == "table") return VL_CIK_TABLE;
if (key == "thresh") return VL_CIK_THRESH;
if (key == "type") return VL_CIK_TYPE;
if (key == "weight") return VL_CIK_WEIGHT;
// VLCOVGEN_SHORT_AUTO_EDIT_END
return key;
}
};
+1 -1
View File
@@ -569,7 +569,7 @@ void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep
sprintf(buf, " %2d ", bits);
decl += buf;
if (m_evcd) {
sprintf(buf, "<%d", code);
sprintf(buf, "<%u", code);
decl += buf;
} else {
decl += stringCode(code);
+6 -8
View File
@@ -356,21 +356,19 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
//=========================================================================
// Performance counters
#if VL_THREADED
/// The vluint64_t argument is loaded with a high-performance counter for profiling
/// or 0x0 if not implemeted on this platform
# if defined(__i386__) || defined(__x86_64__)
# define VL_RDTSC(val) { \
#if defined(__i386__) || defined(__x86_64__)
# define VL_RDTSC(val) { \
vluint32_t hi, lo; \
asm volatile("rdtsc" : "=a" (lo), "=d" (hi)); \
(val) = ((vluint64_t)lo) | (((vluint64_t)hi)<<32); \
}
# elif defined(__aarch64__)
# define VL_RDTSC(val) asm volatile("mrs %[rt],PMCCNTR_EL0" : [rt] "=r" (val));
# else
#elif defined(__aarch64__)
# define VL_RDTSC(val) asm volatile("mrs %[rt],PMCCNTR_EL0" : [rt] "=r" (val));
#else
// We just silently ignore unknown OSes, as only leads to missing statistics
# define VL_RDTSC(val) (val) = 0;
# endif
# define VL_RDTSC(val) (val) = 0;
#endif
//=========================================================================
+177
View File
@@ -0,0 +1,177 @@
#!/usr/bin/perl -w
# See copyright, etc in below POD section.
######################################################################
use Getopt::Long;
#use Data::Dumper; $Data::Dumper::Indent=1; $Data::Dumper::Sortkeys=1; #Debug
use IO::File;
use IO::Dir;
use Pod::Usage;
use strict;
use vars qw ($Debug);
our $VERSION = '0.001';
#======================================================================
# main
autoflush STDOUT 1;
autoflush STDERR 1;
Getopt::Long::config ("no_auto_abbrev");
if (! GetOptions (
"debug" => sub { $Debug = 1; },
"help" => sub { print "Version $VERSION\n";
pod2usage(-verbose=>2, -exitval => 2, output=>\*STDOUT, -noperldoc=>1); },
"version" => sub { print "Version $VERSION\n"; exit(0); },
"<>" => sub { die "%Error: Unknown parameter: $_[0]\n"; },
)) {
die "%Error: Bad usage, try 'git_untabify --help'\n";
}
read_patch();
#######################################################################
sub read_patch {
my $filename = undef;
my $lineno = 0;
my $editlines = {};
while (defined(my $line = <STDIN>)) {
if ($line =~ m!^\+\+\+ b/(.*)!) {
edit_file($filename, $editlines);
$filename = $1;
$lineno = 0;
$editlines = {};
print "FILE $filename\n" if $Debug;
}
elsif ($line =~ m!^@@ -?[0-9]+,?[0-9]* \+?([0-9]+)!) {
$lineno = $1 - 1;
print " LINE $1 $line" if $Debug;
}
elsif ($line =~ m!^ !) {
++$lineno;
}
elsif ($line =~ m!^\+!) {
++$lineno;
if ($line =~ m!\t!) {
print " $lineno: $line" if $Debug;
$editlines->{$lineno} = 1;
}
}
}
edit_file($filename, $editlines);
}
sub edit_file {
my $filename = shift;
my $editlines = shift;
return if (scalar keys(%$editlines) < 1);
if (ignore($filename)) {
print "%Warning: Ignoring $filename\n";
return;
}
print "Edit $filename ",join(",",sort(keys %$editlines)),"\n";
my $lineno = 0;
my @out;
{
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n";
while (defined(my $line = $fh->getline)) {
++$lineno;
if ($editlines->{$lineno}) {
print $line;
push @out, untabify($line);
} else {
push @out, $line;
}
}
$fh->close;
}
{
my $fh = IO::File->new(">${filename}.untab") or die "%Error: $! ${filename}.untab,";
$fh->print(join('',@out));
$fh->close;
my ($dev,$ino,$mode) = stat($filename);
chmod $mode, "${filename}.untab";
}
rename("${filename}.untab", $filename) or die "%Error: $! ${filename}.untab,";
}
sub ignore {
my $filename = shift;
return 1 if ($filename =~ /(Makefile|\.mk)/);
return 1 if ($filename =~ /\.(y|l|out|vcd)$/);
#
return 0 if ($filename =~ /\.(sv|v|vh|svh|h|vc|cpp|pl)$/);
return 0;
}
sub untabify {
my $line = shift;
my $out = "";
my $col = 0;
foreach my $c (split //, $line) {
if ($c eq "\t") {
my $destcol = int(($col+8)/8)*8;
while ($col < $destcol) { ++$col; $out .= " "; }
} else {
$out .= $c;
$col++;
}
}
return $out;
}
#######################################################################
__END__
=pod
=head1 NAME
git_untabify - Pipe a git diff report and untabify differences
=head1 SYNOPSIS
git diff a..b | git_untabify
=head1 DESCRIPTION
Take a patch file, and edit the files in the destination patch list to
untabify the related patch lines.
=head1 ARGUMENTS
=over 4
=item --help
Displays this message and program version and exits.
=item --version
Displays program version and exits.
=back
=head1 DISTRIBUTION
Copyright 2005-2018 by Wilson Snyder. Verilator 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.
=head1 AUTHORS
Wilson Snyder <[email protected]>
=head1 SEE ALSO
=cut
######################################################################
### Local Variables:
### compile-command: "./git_untabify "
### End:
+3 -3
View File
@@ -100,14 +100,14 @@ sub write_verilog {
my $fh = IO::File->new(">$dir/foo.cpp");
$fh->print('#include "Vfoo.h"' ,"\n");
$fh->print('unsigned int main_time = 0;' ,"\n");
$fh->print('double sc_time_stamp () {' ,"\n");
$fh->print('double sc_time_stamp() {' ,"\n");
$fh->print(' return main_time;' ,"\n");
$fh->print('}' ,"\n");
$fh->print('int main() {' ,"\n");
$fh->print(' Vfoo *top = new Vfoo;' ,"\n");
$fh->print(' while (!Verilated::gotFinish()) {',"\n");
$fh->print(' top->eval();' ,"\n");
$fh->print(' main_time++;' ,"\n");
$fh->print(' top->eval();' ,"\n");
$fh->print(' main_time++;' ,"\n");
$fh->print(' }' ,"\n");
$fh->print(' top->final();' ,"\n");
$fh->print('}' ,"\n");
+18 -18
View File
@@ -291,8 +291,8 @@ void AstNode::addNextHere(AstNode* newp) {
// This could be at head, tail, or both (single)
// New could be head of single node, or list
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
UASSERT(newp,"Null item passed to addNext");
UASSERT(newp->backp()==NULL,"New node (back) already assigned?");
UASSERT(newp, "Null item passed to addNext");
UASSERT(!newp->backp(), "New node (back) already assigned?");
this->debugTreeChange("-addHereThs: ", __LINE__, false);
newp->debugTreeChange("-addHereNew: ", __LINE__, true);
newp->editCountInc();
@@ -335,7 +335,7 @@ void AstNode::addNextHere(AstNode* newp) {
}
void AstNode::setOp1p(AstNode* newp) {
UASSERT(newp,"Null item passed to setOp1p\n");
UASSERT(newp, "Null item passed to setOp1p");
UDEBUGONLY(if (m_op1p) this->v3fatalSrc("Adding to non-empty, non-list op1"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op1"););
@@ -348,7 +348,7 @@ void AstNode::setOp1p(AstNode* newp) {
}
void AstNode::setOp2p(AstNode* newp) {
UASSERT(newp,"Null item passed to setOp2p\n");
UASSERT(newp, "Null item passed to setOp2p");
UDEBUGONLY(if (m_op2p) this->v3fatalSrc("Adding to non-empty, non-list op2"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op2"););
@@ -361,7 +361,7 @@ void AstNode::setOp2p(AstNode* newp) {
}
void AstNode::setOp3p(AstNode* newp) {
UASSERT(newp,"Null item passed to setOp3p\n");
UASSERT(newp, "Null item passed to setOp3p");
UDEBUGONLY(if (m_op3p) this->v3fatalSrc("Adding to non-empty, non-list op3"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op3"););
@@ -374,7 +374,7 @@ void AstNode::setOp3p(AstNode* newp) {
}
void AstNode::setOp4p(AstNode* newp) {
UASSERT(newp,"Null item passed to setOp4p\n");
UASSERT(newp, "Null item passed to setOp4p");
UDEBUGONLY(if (m_op4p) this->v3fatalSrc("Adding to non-empty, non-list op4"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op4"););
@@ -387,25 +387,25 @@ void AstNode::setOp4p(AstNode* newp) {
}
void AstNode::addOp1p(AstNode* newp) {
UASSERT(newp,"Null item passed to addOp1p\n");
UASSERT(newp, "Null item passed to addOp1p");
if (!m_op1p) { op1p(newp); }
else { m_op1p->addNext(newp); }
}
void AstNode::addOp2p(AstNode* newp) {
UASSERT(newp,"Null item passed to addOp2p\n");
UASSERT(newp, "Null item passed to addOp2p");
if (!m_op2p) { op2p(newp); }
else { m_op2p->addNext(newp); }
}
void AstNode::addOp3p(AstNode* newp) {
UASSERT(newp,"Null item passed to addOp3p\n");
UASSERT(newp, "Null item passed to addOp3p");
if (!m_op3p) { op3p(newp); }
else { m_op3p->addNext(newp); }
}
void AstNode::addOp4p(AstNode* newp) {
UASSERT(newp,"Null item passed to addOp4p\n");
UASSERT(newp, "Null item passed to addOp4p");
if (!m_op4p) { op4p(newp); }
else { m_op4p->addNext(newp); }
}
@@ -431,7 +431,7 @@ void AstNRelinker::dump(ostream& str) const {
AstNode* AstNode::unlinkFrBackWithNext(AstNRelinker* linkerp) {
this->debugTreeChange("-unlinkWNextThs: ", __LINE__, true);
AstNode* oldp = this;
UASSERT(oldp->m_backp,"Node has no back, already unlinked?\n");
UASSERT(oldp->m_backp, "Node has no back, already unlinked?");
oldp->editCountInc();
AstNode* backp = oldp->m_backp;
if (linkerp) {
@@ -479,7 +479,7 @@ AstNode* AstNode::unlinkFrBackWithNext(AstNRelinker* linkerp) {
AstNode* AstNode::unlinkFrBack(AstNRelinker* linkerp) {
this->debugTreeChange("-unlinkFrBkThs: ", __LINE__, true);
AstNode* oldp = this;
UASSERT(oldp->m_backp,"Node has no back, already unlinked?\n");
UASSERT(oldp->m_backp, "Node has no back, already unlinked?");
oldp->editCountInc();
AstNode* backp = oldp->m_backp;
if (linkerp) {
@@ -531,8 +531,8 @@ AstNode* AstNode::unlinkFrBack(AstNRelinker* linkerp) {
void AstNode::relink(AstNRelinker* linkerp) {
if (debug()>8) { UINFO(0," EDIT: relink: "); dumpPtrs(); }
AstNode* newp = this;
UASSERT(linkerp && linkerp->m_backp, "Need non-empty linker\n");
UASSERT(newp->backp()==NULL, "New node already linked?\n");
UASSERT(linkerp && linkerp->m_backp, "Need non-empty linker");
UASSERT(!newp->backp(), "New node already linked?");
newp->editCountInc();
if (debug()>8) { linkerp->dump(cout); cout<<endl; }
@@ -668,7 +668,7 @@ AstNode* AstNode::cloneTree(bool cloneNextLink) {
void AstNode::deleteNode() {
// private: Delete single node. Publicly call deleteTree() instead.
UASSERT(m_backp==NULL,"Delete called on node with backlink still set\n");
UASSERT(!m_backp, "Delete called on node with backlink still set");
editCountInc();
// Change links of old node so we coredump if used
this->m_nextp = (AstNode*)1;
@@ -713,7 +713,7 @@ void AstNode::deleteTreeIter() {
void AstNode::deleteTree() {
// deleteTree always deletes the next link, because you must have called
// unlinkFromBack or unlinkFromBackWithNext as appropriate before calling this.
UASSERT(m_backp==NULL,"Delete called on node with backlink still set\n");
UASSERT(!m_backp, "Delete called on node with backlink still set");
this->debugTreeChange("-delTree: ", __LINE__, true);
this->editCountInc();
// MUST be depth first!
@@ -1048,8 +1048,8 @@ void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) {
if (doDump) {
{ // Write log & close
UINFO(2,"Dumping "<<filename<<endl);
const vl_unique_ptr<ofstream> logsp (V3File::new_ofstream(filename, append));
if (logsp->fail()) v3fatalSrc("Can't write "<<filename);
const vl_unique_ptr<std::ofstream> logsp (V3File::new_ofstream(filename, append));
if (logsp->fail()) v3fatal("Can't write "<<filename);
*logsp<<"Verilator Tree Dump (format 0x3900) from <e"<<dec<<editCountLast()<<">";
*logsp<<" to <e"<<dec<<editCountGbl()<<">"<<endl;
if (editCountGbl()==editCountLast()
+3 -3
View File
@@ -167,7 +167,7 @@ class AstEdgeType {
public:
// REMEMBER to edit the strings below too
enum en {
// These must be in general -> most specific order, as we sort by it in V3Const::visit AstSenTre
// These must be in general -> most specific order, as we sort by it in V3Const::visit AstSenTree
ET_ILLEGAL,
// Involving a variable
ET_ANYEDGE, // Default for sensitivities; rip them out
@@ -364,8 +364,8 @@ public:
return names[m_e];
};
static void selfTest() {
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).ascii()," MAX"),"Enum array mismatch");
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).dpiType()," MAX"),"Enum array mismatch");
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).ascii()," MAX"), "SelfTest: Enum mismatch");
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).dpiType()," MAX"),"SelfTest: Enum mismatch");
}
inline AstBasicDTypeKwd () : m_e(UNKNOWN) {}
// cppcheck-suppress noExplicitConstructor
+3 -3
View File
@@ -399,7 +399,7 @@ private:
return rhs.m_keyword == m_keyword
&& rhs.m_nrange == m_nrange; }
} m;
// See also in AstNodeDtype: m_width, m_widthMin, m_numeric(issigned)
// See also in AstNodeDType: m_width, m_widthMin, m_numeric(issigned)
public:
AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, VSignedState signst=signedst_NOSIGN)
: AstNodeDType(fl) {
@@ -670,7 +670,7 @@ public:
class AstMemberDType : public AstNodeDType {
// A member of a struct/union
// PARENT: AstClassDType
// PARENT: AstNodeClassDType
private:
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
string m_name; // Name of variable
@@ -1949,7 +1949,7 @@ public:
};
class AstDot : public AstNode {
// A dot separating paths in an AstXRef, AstFuncRef or AstTaskRef
// A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef
// These are eliminated in the link stage
public:
AstDot(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
+1 -1
View File
@@ -160,7 +160,7 @@ void V3CCtors::cctorsAll() {
if (v3Global.opt.coverage()) {
V3CCtorsVisitor configure_coverage
(modp, "_configure_coverage", EmitCBaseVisitor::symClassVar()+ ", bool first", "vlSymsp, first",
"if (0 && vlSymsp && first) {} // Prevent unused\n");
"if (0 && vlSymsp && first) {} // Prevent unused\n");
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
if (AstCoverDecl* coverp = np->castCoverDecl()) {
AstNode* backp = coverp->backp();
+5 -5
View File
@@ -166,7 +166,7 @@ private:
}
UINFO(8,"Simple case statement: "<<nodep<<endl);
// Zero list of items for each value
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) m_valueItem[i] = NULL;
for (uint32_t i=0; i<(1UL<<m_caseWidth); ++i) m_valueItem[i] = NULL;
// Now pick up the values for each assignment
// We can cheat and use uint32_t's because we only support narrow case's
bool bitched = false;
@@ -184,7 +184,7 @@ private:
V3Number numval (itemp->fileline(), iconstp->width());
numval.opBitsOne(iconstp->num());
uint32_t val = numval.toUInt();
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
for (uint32_t i=0; i<(1UL<<m_caseWidth); ++i) {
if ((i & mask) == val) {
if (!m_valueItem[i]) {
m_valueItem[i] = itemp;
@@ -199,12 +199,12 @@ private:
}
// Defaults were moved to last in the caseitem list by V3LinkDot
if (itemp->isDefault()) { // Case statement's default... Fill the table
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
for (uint32_t i=0; i<(1UL<<m_caseWidth); ++i) {
if (!m_valueItem[i]) m_valueItem[i] = itemp;
}
}
}
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
for (uint32_t i=0; i<(1UL<<m_caseWidth); ++i) {
if (!m_valueItem[i]) {
nodep->v3warn(CASEINCOMPLETE,"Case values incompletely covered (example pattern 0x"<<hex<<i<<")");
m_caseNoOverlapsAllCovered = false;
@@ -278,7 +278,7 @@ private:
AstNode* cexprp = nodep->exprp()->unlinkFrBack();
if (debug()>=9) {
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
for (uint32_t i=0; i<(1UL<<m_caseWidth); ++i) {
if (AstNode* itemp = m_valueItem[i]) {
UINFO(9,"Value "<<hex<<i<<" "<<itemp<<endl);
}
+3 -3
View File
@@ -496,8 +496,8 @@ private:
}
string filename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__cdc_edges.txt";
const vl_unique_ptr<ofstream> ofp (V3File::new_ofstream(filename));
if (ofp->fail()) v3fatalSrc("Can't write "<<filename);
const vl_unique_ptr<std::ofstream> ofp (V3File::new_ofstream(filename));
if (ofp->fail()) v3fatal("Can't write "<<filename);
*ofp<<"Edge Report for "<<v3Global.opt.prefix()<<endl;
deque<string> report; // Sort output by name
@@ -739,7 +739,7 @@ public:
// Make report of all signal names and what clock edges they have
string filename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__cdc.txt";
m_ofp = V3File::new_ofstream(filename);
if (m_ofp->fail()) v3fatalSrc("Can't write "<<filename);
if (m_ofp->fail()) v3fatal("Can't write "<<filename);
m_ofFilename = filename;
*m_ofp<<"CDC Report for "<<v3Global.opt.prefix()<<endl;
*m_ofp<<"Each dump below traces logic from inputs/source flops to destination flop(s).\n";
+6 -3
View File
@@ -386,10 +386,13 @@ private:
public:
// CONSTUCTORS
explicit ClockVisitor(AstNetlist* nodep) {
m_modp=NULL;
m_modp = NULL;
m_evalFuncp = NULL;
m_topScopep=NULL;
m_lastSenp=NULL;
m_initFuncp = NULL;
m_finalFuncp = NULL;
m_settleFuncp = NULL;
m_topScopep = NULL;
m_lastSenp = NULL;
m_lastIfp = NULL;
m_scopep = NULL;
//
+1
View File
@@ -402,6 +402,7 @@ private:
UINFO(4," MOD "<<nodep<<endl);
m_modp = nodep;
m_modNFuncs = 0;
m_walkLast2p = NULL;
m_hashed.clear();
// Compute hash of all statement trees in the function
m_state = STATE_HASH;
+3 -3
View File
@@ -589,7 +589,7 @@ private:
void replaceNum (AstNode* oldp, const V3Number& num) {
// Replace oldp node with a constant set to specified value
UASSERT (oldp, "Null old\n");
UASSERT(oldp, "Null old");
if (oldp->castConst() && !oldp->castConst()->num().isFourState()) {
oldp->v3fatalSrc("Already constant??");
}
@@ -662,7 +662,7 @@ private:
void replaceConstString (AstNode* oldp, const string& num) {
// Replace oldp node with a constant set to specified value
UASSERT (oldp, "Null old\n");
UASSERT(oldp, "Null old");
AstNode* newp = new AstConst(oldp->fileline(), AstConst::String(), num);
if (debug()>5) oldp->dumpTree(cout," const_old: ");
if (debug()>5) newp->dumpTree(cout," _new: ");
@@ -1607,7 +1607,7 @@ private:
}
// virtual void visit(AstCvtPackString* nodep) {
// Not constant propagated (for today) because AstMath::isOpaque is set
// Not constant propagated (for today) because AstNodeMath::isOpaque is set
// Someday if lower is constant, convert to quoted "string".
bool onlySenItemInSenTree(AstNodeSenItem* nodep) {
+1
View File
@@ -382,6 +382,7 @@ public:
explicit CoverageVisitor(AstNetlist* rootp) {
// Operate on all modules
m_checkBlock = true;
m_modp = NULL;
m_beginHier = "";
m_inToggleOff = false;
m_inModOff = true;
+3 -3
View File
@@ -312,7 +312,7 @@ private:
if (!scp)
continue;
if (scp->user1() == 0) {
UINFO(4, " Dead AstScope " << scp << endl);
UINFO(4, " Dead AstScope " << scp << endl);
scp->aboveScopep()->user1Inc(-1);
if (scp->dtypep()) {
scp->dtypep()->user1Inc(-1);
@@ -344,7 +344,7 @@ private:
pair <AssignMap::iterator,AssignMap::iterator> eqrange = m_assignMap.equal_range(vscp);
for (AssignMap::iterator itr = eqrange.first; itr != eqrange.second; ++itr) {
AstNodeAssign* assp = itr->second;
UINFO(4," Dead assign "<<assp<<endl);
UINFO(4," Dead assign "<<assp<<endl);
assp->dtypep()->user1Inc(-1);
assp->unlinkFrBack()->deleteTree(); VL_DANGLING(assp);
}
@@ -360,7 +360,7 @@ private:
if (!varp)
continue;
if (varp->user1() == 0) {
UINFO(4, " Dead " << varp << endl);
UINFO(4, " Dead " << varp << endl);
if (varp->dtypep()) {
varp->dtypep()->user1Inc(-1);
}
+2 -1
View File
@@ -119,7 +119,8 @@ private:
<<nodep->varp()->prettyName());
}
}
AstVarScope* createVarSc(AstVarScope* oldvarscp, string name, int width/*0==fromoldvar*/, AstNodeDType* newdtypep) {
AstVarScope* createVarSc(AstVarScope* oldvarscp, const string& name,
int width/*0==fromoldvar*/, AstNodeDType* newdtypep) {
// Because we've already scoped it, we may need to add both the AstVar and the AstVarScope
if (!oldvarscp->scopep()) oldvarscp->v3fatalSrc("Var unscoped");
AstVar* varp;
+4 -2
View File
@@ -126,8 +126,10 @@ private:
public:
// CONSTUCTORS
explicit DepthBlockVisitor(AstNetlist* nodep) {
m_modp=NULL;
m_depth=0;
m_modp = NULL;
m_funcp = NULL;
m_depth = 0;
m_deepNum = 0;
//
nodep->accept(*this);
}
+1 -1
View File
@@ -87,7 +87,7 @@ private:
// false if the object is in another scope.
string descopedName(const AstScope* scopep, bool& hierThisr,
const AstVar* varp=NULL) {
UASSERT(scopep, "Var/Func not scoped\n");
UASSERT(scopep, "Var/Func not scoped");
hierThisr = (scopep == m_scopep);
// It's possible to disable relative references. This is a concession
+6 -6
View File
@@ -326,7 +326,7 @@ public:
virtual void visit(AstNodeReadWriteMem* nodep) {
puts(nodep->cFuncPrefixp());
emitIQW(nodep->filenamep());
puts(" ("); // We take a void* rather than emitIQW(nodep->memp());
puts("("); // We take a void* rather than emitIQW(nodep->memp());
puts(nodep->isHex()?"true":"false");
putbs(",");
puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width
@@ -371,11 +371,11 @@ public:
}
virtual void visit(AstFFlush* nodep) {
if (!nodep->filep()) {
puts("fflush (stdout);\n");
puts("fflush(stdout);\n");
} else {
puts("if (");
nodep->filep()->iterateAndNext(*this);
puts(") { fflush (VL_CVT_I_FP(");
puts(") { fflush(VL_CVT_I_FP(");
nodep->filep()->iterateAndNext(*this);
puts(")); }\n");
}
@@ -993,7 +993,7 @@ class EmitCImp : EmitCStmts {
// High level
void emitImp(AstNodeModule* modp);
void emitStaticDecl(AstNodeModule* modp);
void emitSettleLoop(std::string eval_call, bool initial);
void emitSettleLoop(const std::string& eval_call, bool initial);
void emitWrapEval(AstNodeModule* modp);
void emitInt(AstNodeModule* modp);
void maybeSplit(AstNodeModule* modp);
@@ -1715,7 +1715,7 @@ void EmitCImp::emitCellCtors(AstNodeModule* modp) {
}
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstCell* cellp=nodep->castCell()) {
puts("VL_CELL ("+cellp->name()+", "+modClassName(cellp->modp())+");\n");
puts("VL_CELL("+cellp->name()+", "+modClassName(cellp->modp())+");\n");
}
}
}
@@ -1752,7 +1752,7 @@ void EmitCImp::emitSensitives() {
}
}
void EmitCImp::emitSettleLoop(std::string eval_call, bool initial) {
void EmitCImp::emitSettleLoop(const std::string& eval_call, bool initial) {
putsDecoration("// Evaluate till stable\n");
puts("int __VclockLoop = 0;\n");
puts("QData __Vchange = 1;\n");
+1 -1
View File
@@ -206,7 +206,7 @@ public:
string cppfile = *it;
string basename = V3Os::filenameNonExt(cppfile);
of.puts(basename+".o: "+cppfile+"\n");
of.puts("\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<\n");
of.puts("\t$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<\n");
}
of.puts("\n### Link rules... (from --exe)\n");
+1 -1
View File
@@ -154,7 +154,7 @@ public:
// Later -Werror- options may make more of these.
bool pretendError() const { return ( m_e==ASSIGNIN || m_e==BLKANDNBLK
|| m_e==BLKLOOPINIT
|| m_e==IMPURE || m_e==MODDUP); }
|| m_e==IMPURE); }
// Warnings to mention manual
bool mentionManual() const { return ( m_e==EC_FATALSRC || m_e==SYMRSVDWORD
|| pretendError() ); }
+2
View File
@@ -829,6 +829,8 @@ private:
// Rather than doing a (slowish) ==##, we OR in the bits that aren't part of the mask
eqp = new AstOr (nodep->fileline(),
new AstConst (nodep->fileline(), notWideMask(nodep->lhsp())),
// Bug in cppcheck
// cppcheck-suppress memleak
eqp);
}
newp = (newp==NULL) ? eqp : (new AstAnd (nodep->fileline(), newp, eqp));
+4 -4
View File
@@ -134,8 +134,8 @@ V3FileDependImp dependImp; // Depend implementation class
// V3FileDependImp
inline void V3FileDependImp::writeDepend(const string& filename) {
const vl_unique_ptr<ofstream> ofp (V3File::new_ofstream(filename));
if (ofp->fail()) v3fatalSrc("Can't write "<<filename);
const vl_unique_ptr<std::ofstream> ofp (V3File::new_ofstream(filename));
if (ofp->fail()) v3fatal("Can't write "<<filename);
for (set<DependFile>::iterator iter=m_filenameList.begin();
iter!=m_filenameList.end(); ++iter) {
@@ -170,8 +170,8 @@ inline void V3FileDependImp::writeDepend(const string& filename) {
}
inline void V3FileDependImp::writeTimes(const string& filename, const string& cmdlineIn) {
const vl_unique_ptr<ofstream> ofp (V3File::new_ofstream(filename));
if (ofp->fail()) v3fatalSrc("Can't write "<<filename);
const vl_unique_ptr<std::ofstream> ofp (V3File::new_ofstream(filename));
if (ofp->fail()) v3fatal("Can't write "<<filename);
string cmdline = stripQuotes(cmdlineIn);
*ofp<<"# DESCR"<<"IPTION: Verilator output: Timestamp data for --skip-identical. Delete at will."<<endl;
+1 -1
View File
@@ -152,7 +152,7 @@ public:
void indentInc() { m_indentLevel += m_blockIndent; }
void indentDec() {
m_indentLevel -= m_blockIndent;
UASSERT(m_indentLevel>=0, ": "<<m_filename<<": Underflow of indentation\n");
UASSERT(m_indentLevel>=0, ": "<<m_filename<<": Underflow of indentation");
}
void blockInc() { m_parenVec.push(m_indentLevel + m_blockIndent); }
void blockDec() { if (!m_parenVec.empty()) m_parenVec.pop(); }
+1 -1
View File
@@ -312,7 +312,7 @@ private:
// {statement}Node::user1p -> GateLogicVertex* for this statement
// AstVarScope::user2 -> bool: Signal used in SenItem in *this* always statement
// AstVar::user2 -> bool: Warned about SYNCASYNCNET
// AstVarNodeRef::user2 -> bool: ConcatOffset visited
// AstNodeVarRef::user2 -> bool: ConcatOffset visited
AstUser1InUse m_inuser1;
AstUser2InUse m_inuser2;
+4
View File
@@ -22,6 +22,10 @@
#define _V3GLOBAL_H_ 1
#include "config_build.h"
#ifndef HAVE_CONFIG_BUILD
# error "Something failed during ./configure as config_build.h is incomplete. Perhaps you used autoreconf, don't."
#endif
#include "verilatedos.h"
#include <string>
+4 -4
View File
@@ -133,8 +133,8 @@ ostream& operator<<(ostream& os, V3GraphVertex* vertexp) {
void V3GraphEdge::init(V3Graph* graphp,
V3GraphVertex* fromp, V3GraphVertex* top, int weight,
bool cutable) {
UASSERT(fromp, "Null from pointer\n");
UASSERT(top, "Null to pointer\n");
UASSERT(fromp, "Null from pointer");
UASSERT(top, "Null to pointer");
m_fromp = fromp;
m_top = top;
m_weight = weight;
@@ -288,8 +288,8 @@ void V3Graph::dumpDotFilePrefixedAlways(const string& nameComment, bool colorAsS
void V3Graph::dumpDotFile(const string& filename, bool colorAsSubgraph) const {
// This generates a file used by graphviz, http://www.graphviz.org
// "hardcoded" parameters:
const vl_unique_ptr<ofstream> logp (V3File::new_ofstream(filename));
if (logp->fail()) v3fatalSrc("Can't write "<<filename);
const vl_unique_ptr<std::ofstream> logp (V3File::new_ofstream(filename));
if (logp->fail()) v3fatal("Can't write "<<filename);
// Header
*logp<<"digraph v3graph {\n";
+1 -2
View File
@@ -24,7 +24,6 @@
#include "verilatedos.h"
#include "V3Error.h"
#include "V3List.h"
#include "V3Ast.h"
#include <vector>
#include <algorithm>
@@ -160,7 +159,6 @@ protected:
void verticesPushBack(V3Graph* graphp);
// ACCESSORS
void fanout(double fanout) { m_fanout = fanout; }
void rank(uint32_t rank) { m_rank = rank; }
void inUnlink() { m_ins.reset(); } // Low level; normally unlinkDelete is what you want
void outUnlink() { m_outs.reset(); } // Low level; normally unlinkDelete is what you want
protected:
@@ -193,6 +191,7 @@ public:
uint32_t color() const { return m_color; }
void color(uint32_t color) { m_color = color; }
uint32_t rank() const { return m_rank; }
void rank(uint32_t rank) { m_rank = rank; }
double fanout() const { return m_fanout; }
void user(uint32_t user) { m_user = user; }
uint32_t user() const { return m_user; }
+1
View File
@@ -24,6 +24,7 @@
#include "verilatedos.h"
#include <vector>
#include "V3Ast.h" // for VNUser
#include "V3Global.h"
#include "V3Graph.h"
+6 -3
View File
@@ -119,9 +119,12 @@ public:
gp->stronglyConnected(&V3GraphEdge::followAlwaysTrue);
dump();
UASSERT(i->color()!=a->color() && a->color() != g2->color() && g2->color() != q->color(), "Separate colors not assigned");
UASSERT(a->color()==b->color() && a->color()==g1->color(), "Strongly connected nodes not colored together");
UASSERT(g2->color()==g3->color(), "Strongly connected nodes not colored together");
UASSERT(i->color()!=a->color() && a->color() != g2->color() && g2->color() != q->color(),
"SelfTest: Separate colors not assigned");
UASSERT(a->color()==b->color() && a->color()==g1->color(),
"SelfTest: Strongly connected nodes not colored together");
UASSERT(g2->color()==g3->color(),
"SelfTest: Strongly connected nodes not colored together");
}
};
+2 -2
View File
@@ -141,8 +141,8 @@ void V3Hashed::dumpFilePrefixed(const string& nameComment, bool tree) {
}
void V3Hashed::dumpFile(const string& filename, bool tree) {
const vl_unique_ptr<ofstream> logp (V3File::new_ofstream(filename));
if (logp->fail()) v3fatalSrc("Can't write "<<filename);
const vl_unique_ptr<std::ofstream> logp (V3File::new_ofstream(filename));
if (logp->fail()) v3fatal("Can't write "<<filename);
map<int,int> dist;
+2 -2
View File
@@ -136,8 +136,8 @@ public:
void dump(const string& nameComment="linkdot", bool force=false) {
if (debug()>=6 || force) {
string filename = v3Global.debugFilename(nameComment)+".txt";
const vl_unique_ptr<ofstream> logp (V3File::new_ofstream(filename));
if (logp->fail()) v3fatalSrc("Can't write "<<filename);
const vl_unique_ptr<std::ofstream> logp (V3File::new_ofstream(filename));
if (logp->fail()) v3fatal("Can't write "<<filename);
ostream& os = *logp;
m_syms.dump(os);
bool first = true;
+7 -7
View File
@@ -1162,7 +1162,7 @@ void OrderVisitor::processSensitive() {
void OrderVisitor::processDomains() {
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) {
OrderEitherVertex* vertexp = dynamic_cast<OrderEitherVertex*>(itp);
UASSERT(vertexp, "Null or vertex not derived from EitherVertex\n");
UASSERT(vertexp, "Null or vertex not derived from EitherVertex");
processDomainsIterate(vertexp);
}
}
@@ -1262,8 +1262,8 @@ void OrderVisitor::processDomainsIterate(OrderEitherVertex* vertexp) {
void OrderVisitor::processEdgeReport() {
// Make report of all signal names and what clock edges they have
string filename = v3Global.debugFilename("order_edges.txt");
const vl_unique_ptr<ofstream> logp (V3File::new_ofstream(filename));
if (logp->fail()) v3fatalSrc("Can't write "<<filename);
const vl_unique_ptr<std::ofstream> logp (V3File::new_ofstream(filename));
if (logp->fail()) v3fatal("Can't write "<<filename);
//Testing emitter: V3EmitV::verilogForTree(v3Global.rootp(), *logp);
deque<string> report;
@@ -1509,7 +1509,7 @@ void OrderVisitor::processMoveDoneOne(OrderMoveVertex* vertexp) {
}
void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* domScopep, int level) {
UASSERT(vertexp->domScopep() == domScopep, "Domain mismatch; list misbuilt?\n");
UASSERT(vertexp->domScopep() == domScopep, "Domain mismatch; list misbuilt?");
OrderLogicVertex* lvertexp = vertexp->logicp();
AstScope* scopep = lvertexp->scopep();
UINFO(5," POSmove l"<<setw(3)<<level<<" d="<<(void*)(lvertexp->domainp())
@@ -1612,7 +1612,7 @@ void OrderVisitor::process() {
UINFO(2," Process Circulars...\n");
processCircular(); // must be before processDomains
// Assign logic verticesto new domains
// Assign logic vertices to new domains
UINFO(2," Domains...\n");
processDomains();
m_graph.dumpDotFilePrefixed("orderg_domain");
@@ -1636,8 +1636,8 @@ void OrderVisitor::process() {
m_graph.dumpDotFilePrefixed("orderg_done");
if (0 && debug()) {
string dfilename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_INT_order";
const vl_unique_ptr<ofstream> logp (V3File::new_ofstream(dfilename));
if (logp->fail()) v3fatalSrc("Can't write "<<dfilename);
const vl_unique_ptr<std::ofstream> logp (V3File::new_ofstream(dfilename));
if (logp->fail()) v3fatal("Can't write "<<dfilename);
m_graph.dump(*logp);
}
}
+5 -8
View File
@@ -210,18 +210,17 @@ public:
class OrderVarVertex : public OrderEitherVertex {
AstVarScope* m_varScp;
OrderVarVertex* m_pilNewVertexp; // for processInsLoopNewVar
bool m_isClock; // Used as clock
bool m_isDelayed; // Set in a delayed assignment
protected:
OrderVarVertex(V3Graph* graphp, const OrderVarVertex& old)
: OrderEitherVertex(graphp, old)
, m_varScp(old.m_varScp), m_pilNewVertexp(old.m_pilNewVertexp), m_isClock(old.m_isClock)
, m_varScp(old.m_varScp), m_isClock(old.m_isClock)
, m_isDelayed(old.m_isDelayed) {}
public:
OrderVarVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
: OrderEitherVertex(graphp, scopep, NULL), m_varScp(varScp)
, m_pilNewVertexp(NULL), m_isClock(false), m_isDelayed(false) {}
, m_isClock(false), m_isDelayed(false) {}
virtual ~OrderVarVertex() {}
virtual OrderVarVertex* clone (V3Graph* graphp) const = 0;
virtual OrderVEdgeType type() const = 0;
@@ -231,8 +230,6 @@ public:
bool isClock() const { return m_isClock; }
void isDelayed(bool flag) { m_isDelayed=flag; }
bool isDelayed() const { return m_isDelayed; }
OrderVarVertex* pilNewVertexp() const { return m_pilNewVertexp; }
void pilNewVertexp (OrderVarVertex* vertexp) { m_pilNewVertexp = vertexp; }
};
class OrderVarStdVertex : public OrderVarVertex {
@@ -327,7 +324,7 @@ protected:
: V3GraphVertex(graphp, old), m_logicp(old.m_logicp), m_state(old.m_state)
, m_domScopep(old.m_domScopep) {}
public:
OrderMoveVertex(V3Graph* graphp, OrderLogicVertex* logicp)
OrderMoveVertex(V3Graph* graphp, OrderLogicVertex* logicp)
: V3GraphVertex(graphp), m_logicp(logicp), m_state(POM_WAIT), m_domScopep(NULL) {}
virtual ~OrderMoveVertex() {}
virtual OrderMoveVertex* clone(V3Graph* graphp) const {
@@ -357,11 +354,11 @@ public:
OrderLogicVertex* logicp() const { return m_logicp; }
bool isWait() const { return m_state==POM_WAIT; }
void setReady() {
UASSERT(m_state==POM_WAIT, "Wait->Ready on node not in proper state\n");
UASSERT(m_state==POM_WAIT, "Wait->Ready on node not in proper state");
m_state = POM_READY;
}
void setMoved() {
UASSERT(m_state==POM_READY, "Ready->Moved on node not in proper state\n");
UASSERT(m_state==POM_READY, "Ready->Moved on node not in proper state");
m_state = POM_MOVED;
}
OrderMoveDomScope* domScopep() const { return m_domScopep; }
+3 -3
View File
@@ -211,9 +211,9 @@ uint64_t V3Os::memUsageBytes() {
if (!fp) {
return 0;
}
uint64_t size, resident, share, text, lib, data, dt; // All in pages
if (7 != fscanf(fp, "%" VL_PRI64 "d %" VL_PRI64 "d %" VL_PRI64 "d %"
VL_PRI64 "d %" VL_PRI64 "d %" VL_PRI64 "d %" VL_PRI64 "d",
vluint64_t size, resident, share, text, lib, data, dt; // All in pages
if (7 != fscanf(fp, "%" VL_PRI64 "u %" VL_PRI64 "u %" VL_PRI64 "u %"
VL_PRI64 "u %" VL_PRI64 "u %" VL_PRI64 "u %" VL_PRI64 "u",
&size, &resident, &share, &text, &lib, &data, &dt)) {
fclose(fp);
return 0;
+7 -3
View File
@@ -32,7 +32,7 @@
// For interface Parent's we have the AstIfaceRefDType::cellp()
// pointing to this module. If that parent cell's interface
// module gets parameterized, AstIfaceRefDType::cloneRelink
// will update AstIfaceRefDType::cellp(), and AstLinkDot will
// will update AstIfaceRefDType::cellp(), and V3LinkDot will
// see the new interface.
//
// However if a submodule's AstIfaceRefDType::ifacep() points
@@ -197,12 +197,16 @@ private:
// Find it in the clone structure
//UINFO(8,"Clone find 0x"<<hex<<(uint32_t)pinp->modVarp()<<endl);
CloneMap::iterator cloneiter = clonemapp->find(pinp->modVarp());
UASSERT(cloneiter != clonemapp->end(), "Couldn't find pin in clone list");
if (cloneiter == clonemapp->end()) {
pinp->v3fatalSrc("Couldn't find pin in clone list");
}
pinp->modVarp(cloneiter->second->castVar());
}
else if (pinp->modPTypep()) {
CloneMap::iterator cloneiter = clonemapp->find(pinp->modPTypep());
UASSERT(cloneiter != clonemapp->end(), "Couldn't find pin in clone list");
if (cloneiter == clonemapp->end()) {
pinp->v3fatalSrc("Couldn't find pin in clone list");
}
pinp->modPTypep(cloneiter->second->castParamTypeDType());
}
else {
+4 -1
View File
@@ -76,10 +76,13 @@ symb ([a-zA-Z_][a-zA-Z0-9_$]*|\\[^ \t\f\r\n]+)
symbdef ([a-zA-Z_][a-zA-Z0-9_$]*|\\[^ \t\f\r\n`]+)
word [a-zA-Z0-9_]+
drop [\032]
bom [\357\273\277]
/**************************************************************/
%%
<INITIAL>{bom} { }
<INITIAL,STRIFY>^{ws}*"`line"{ws}+.*{crnl} { LEXP->lineDirective(yytext);
return(VP_LINE); }
@@ -208,7 +211,7 @@ drop [\032]
<ARGMODE>{crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); }
<ARGMODE>{quote} { yy_push_state(STRMODE); yymore(); }
<ARGMODE>"`\\`\"" { appendDefValue(yytext,yyleng); } /* Literal text */
<ARGMODE>{tickquote} { return(VP_STRIFY); }
<ARGMODE>{tickquote} { yy_push_state(STRIFY); return(VP_STRIFY); }
<ARGMODE>[{\[] { LEXP->m_parenLevel++; appendDefValue(yytext,yyleng); }
<ARGMODE>[}\]] { LEXP->m_parenLevel--; appendDefValue(yytext,yyleng); }
<ARGMODE>[(] { LEXP->m_parenLevel++;
+4
View File
@@ -1127,6 +1127,10 @@ int V3PreProcImp::getStateToken() {
string rtn; rtn.assign(yyourtext(),yyourleng());
refp->nextarg(refp->nextarg()+rtn);
goto next_tok;
} else if (tok==VP_STRIFY) {
// We must expand stringinfication, when done will return to this state
statePush(ps_STRIFY);
goto next_tok;
} else {
error((string)"Expecting ) or , to end argument list for define reference. Found: "+tokenName(tok));
statePop();
+1 -1
View File
@@ -55,7 +55,7 @@ class SliceVisitor : public AstNVisitor {
// NODE STATE
// Cleared on netlist
// AstNodeAssign::user1() -> bool. True if find is complete
// AstUniop::user1() -> bool. True if find is complete
// AstNodeUniop::user1() -> bool. True if find is complete
// AstArraySel::user1p() -> AstVarRef. The VarRef that the final ArraySel points to
AstUser1InUse m_inuser1;
+2 -2
View File
@@ -243,8 +243,8 @@ void V3Stats::statsReport() {
// Open stats file
string filename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__stats.txt";
ofstream* ofp (V3File::new_ofstream(filename));
if (ofp->fail()) v3fatalSrc("Can't write "<<filename);
std::ofstream* ofp (V3File::new_ofstream(filename));
if (ofp->fail()) v3fatal("Can't write "<<filename);
StatsReport reporter (ofp);
+2 -2
View File
@@ -283,8 +283,8 @@ public:
if (v3Global.opt.dumpTree()) {
string filename = v3Global.debugFilename(nameComment)+".txt";
UINFO(2,"Dumping "<<filename<<endl);
const vl_unique_ptr<ofstream> logp (V3File::new_ofstream(filename));
if (logp->fail()) v3fatalSrc("Can't write "<<filename);
const vl_unique_ptr<std::ofstream> logp (V3File::new_ofstream(filename));
if (logp->fail()) v3fatal("Can't write "<<filename);
dump(*logp, "");
}
}
+13 -4
View File
@@ -1081,10 +1081,12 @@ private:
m_insMode = prevInsMode;
m_insStmtp = prevInsStmtp;
}
void insertBeforeStmt(AstNode* nodep, AstNode* newp) {
AstNode* insertBeforeStmt(AstNode* nodep, AstNode* newp) {
// Return node that must be visited, if any
// See also AstNode::addBeforeStmt; this predates that function
if (debug()>=9) { nodep->dumpTree(cout,"-newstmt:"); }
if (!m_insStmtp) nodep->v3fatalSrc("Function not underneath a statement");
AstNode* visitp = NULL;
if (m_insMode == IM_BEFORE) {
// Add the whole thing before insertAt
UINFO(5," IM_Before "<<m_insStmtp<<endl);
@@ -1092,20 +1094,22 @@ private:
m_insStmtp->addHereThisAsNext(newp);
}
else if (m_insMode == IM_AFTER) {
UINFO(5," IM_After "<<m_insStmtp);
UINFO(5," IM_After "<<m_insStmtp<<endl);
m_insStmtp->addNextHere(newp);
}
else if (m_insMode == IM_WHILE_PRECOND) {
UINFO(5," IM_While_Precond "<<m_insStmtp);
UINFO(5," IM_While_Precond "<<m_insStmtp<<endl);
AstWhile* whilep = m_insStmtp->castWhile();
if (!whilep) nodep->v3fatalSrc("Insert should be under WHILE");
whilep->addPrecondsp(newp);
visitp = newp;
}
else {
nodep->v3fatalSrc("Unknown InsertMode");
}
m_insMode = IM_AFTER;
m_insStmtp = newp;
return visitp;
}
// VISITORS
@@ -1150,12 +1154,13 @@ private:
beginp = createInlinedFTask(nodep, namePrefix, outvscp);
}
// Replace the ref
AstNode* visitp = NULL;
if (nodep->castFuncRef()) {
if (!nodep->taskp()->isFunction()) nodep->v3fatalSrc("func reference to non-function");
AstVarRef* outrefp = new AstVarRef (nodep->fileline(), outvscp, false);
nodep->replaceWith(outrefp);
// Insert new statements
insertBeforeStmt(nodep, beginp);
visitp = insertBeforeStmt(nodep, beginp);
} else {
// outvscp maybe non-NULL if calling a function in a taskref,
// but if so we want to simply ignore the function result
@@ -1164,6 +1169,8 @@ private:
// Cleanup
nodep->deleteTree(); VL_DANGLING(nodep);
UINFO(4," FTask REF Done.\n");
// Visit nodes that normal iteration won't find
if (visitp) visitp->iterateAndNext(*this);
}
virtual void visit(AstNodeFTask* nodep) {
UINFO(4," Inline "<<nodep<<endl);
@@ -1258,7 +1265,9 @@ public:
m_modp = NULL;
m_topScopep = NULL;
m_scopep = NULL;
m_insMode = IM_BEFORE;
m_insStmtp = NULL;
m_modNCalls = 0;
AstNode::user1ClearTree();
nodep->accept(*this);
}
+2
View File
@@ -700,6 +700,8 @@ public:
m_chgSubFuncp = NULL;
m_chgSubParentp = NULL;
m_chgSubStmts = 0;
m_code = 0;
m_finding = false;
m_funcNum = 0;
nodep->accept(*this);
}
+2
View File
@@ -461,9 +461,11 @@ public:
UnrollVisitor(AstNode* nodep, bool generate, const string& beginName) {
m_forVarp = NULL;
m_forVscp = NULL;
m_varValuep = NULL;
m_ignoreIncp = NULL;
m_varModeCheck = false;
m_varModeReplace = false;
m_varAssignHit = false;
m_generate = generate;
m_beginName = beginName;
//
+7
View File
@@ -19,6 +19,13 @@
//*************************************************************************
// Cheat for speed and compile .cpp files into one object
#include "config_build.h"
#ifndef HAVE_CONFIG_BUILD
# error "Something failed during ./configure as config_build.h is incomplete. Perhaps you used autoreconf, don't."
#endif
#include "verilatedos.h"
#define _V3ERROR_NO_GLOBAL_ 1
#include "V3Error.cpp"
#include "V3String.cpp"
+16 -16
View File
@@ -19,11 +19,11 @@ my @Opt_Cpt;
my @Opt_I;
Getopt::Long::config ("pass_through", "no_auto_abbrev");
if (! GetOptions (
"help" => \&usage,
"debug" => sub { $Debug = 1; },
"classes!" => \$opt_classes,
"report!" => \$opt_report,
"<>" => \&parameter,
"help" => \&usage,
"debug" => sub { $Debug = 1; },
"classes!" => \$opt_classes,
"report!" => \$opt_report,
"<>" => \&parameter,
)) {
usage();
}
@@ -238,7 +238,7 @@ sub write_visitor {
sub write_intf {
my $fh = open_file(@_);
foreach my $type (sort (keys %Classes)) {
next if $type eq "Node"; # Special, just a return (this);
next if $type eq "Node"; # Special, just a return (this);
printf $fh " Ast%-16s cast${type}();\n"
,$type."*";
}
@@ -248,7 +248,7 @@ sub write_intf {
sub write_impl {
my $fh = open_file(@_);
foreach my $type (sort (keys %Classes)) {
next if $type eq "Node"; # Special, just a return (this);
next if $type eq "Node"; # Special, just a return (this);
# For performance, prefer static_cast where we can
if (children_of($type)) {
printf $fh "inline Ast%-16s AstNode::cast${type}() { return (dynamic_cast<Ast${type}*>(this)); }\n"
@@ -273,14 +273,14 @@ sub write_types {
printf $fh "\t_ENUM_END\n";
printf $fh " };\n";
printf $fh " const char* ascii() const {\n";
printf $fh " const char* const names[] = {\n";
printf $fh " const char* const names[] = {\n";
foreach my $type (sort (keys %Classes)) {
next if $type =~ /^Node/;
print $fh "\t\"", uc $type, "\",\n";
}
printf $fh "\t\"_ENUM_END\"\n";
printf $fh " };\n";
printf $fh " return names[m_e];\n";
printf $fh " };\n";
printf $fh " return names[m_e];\n";
printf $fh " };\n";
$fh->close();
}
@@ -575,7 +575,7 @@ sub tree_base {
my @out_for_type;
foreach my $base (::subclasses_of($type), $type) {
foreach my $typefunc (@{$self->{treeop}{$base}}) {
my @lines = (" if ($typefunc->{match_func}(nodep)) return;\n",);
my @lines = (" if ($typefunc->{match_func}(nodep)) return;\n",);
if ($typefunc->{short_circuit}) { # short-circuit match fn
push @out_for_type_sc, @lines;
} else { # Standard match fn
@@ -598,11 +598,11 @@ sub tree_base {
if ($out_for_type_sc[0]) { # Short-circuited types
$self->print(" // Generated by astgen with short-circuiting\n",
" virtual void visit(Ast${type}* nodep) {\n",
" nodep->lhsp()->iterateAndNext(*this);\n",
" nodep->lhsp()->iterateAndNext(*this);\n",
@out_for_type_sc);
$self->print(" nodep->rhsp()->iterateAndNext(*this);\n",
" AstNodeTriop *tnp = nodep->castNodeTriop();\n",
" if (tnp && tnp->thsp()) tnp->thsp()->iterateAndNext(*this);\n",
$self->print(" nodep->rhsp()->iterateAndNext(*this);\n",
" AstNodeTriop *tnp = nodep->castNodeTriop();\n",
" if (tnp && tnp->thsp()) tnp->thsp()->iterateAndNext(*this);\n",
@out_for_type,
" }\n") if ($out_for_type[0]);
} elsif ($out_for_type[0]) { # Other types with something to print
@@ -611,7 +611,7 @@ sub tree_base {
$self->print(" // Generated by astgen\n",
" virtual void visit$gen(Ast${type}* nodep) {\n",
($skip?"":
" nodep->iterateChildren(*this);\n"),
" nodep->iterateChildren(*this);\n"),
@out_for_type,
" }\n");
}
+4
View File
@@ -78,3 +78,7 @@ using namespace std;
//**** OS and compiler specifics
#include "verilatedos.h"
//**********************************************************************
//**** This file sometimes gets truncated, so check in consumers
#define HAVE_CONFIG_BUILD
+1 -1
View File
@@ -1893,7 +1893,7 @@ genvar_iteration<nodep>: // ==IEEE: genvar_iteration
| varRefBase yP_SRIGHTEQ expr { $$ = new AstAssign($2,$1,new AstShiftR ($2,$1->cloneTree(true),$3)); }
| varRefBase yP_SSRIGHTEQ expr { $$ = new AstAssign($2,$1,new AstShiftRS($2,$1->cloneTree(true),$3)); }
// // inc_or_dec_operator
// When support ++ as a real AST type, maybe AstWhile::precondsp() becomes generic AstMathStmt?
// When support ++ as a real AST type, maybe AstWhile::precondsp() becomes generic AstNodeMathStmt?
| yP_PLUSPLUS varRefBase { $$ = new AstAssign($1,$2,new AstAdd ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); }
| yP_MINUSMINUS varRefBase { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); }
| varRefBase yP_PLUSPLUS { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); }
+1 -1
View File
@@ -95,7 +95,7 @@ sub write_keys {
$deleting = 1;
push @out, $line;
foreach my $keyref (sort {$a->{name} cmp $b->{name}} @Items) {
push @out, sprintf("\tif (key == \"%s\") return VL_CIK_%s;\n",
push @out, sprintf(" if (key == \"%s\") return VL_CIK_%s;\n",
$keyref->{name}, uc $keyref->{name});
}
}
+26 -24
View File
@@ -591,7 +591,6 @@ sub compile_vlt_flags {
my @verilator_flags = @{$param{verilator_flags}};
unshift @verilator_flags, "--gdb" if $opt_gdb;
unshift @verilator_flags, "--gdbbt" if $opt_gdbbt;
unshift @verilator_flags, @Opt_Driver_Verilator_Flags;
unshift @verilator_flags, "--x-assign unique"; # More likely to be buggy
unshift @verilator_flags, "--trace" if $opt_trace;
if (defined $opt_optimize) {
@@ -615,6 +614,9 @@ sub compile_vlt_flags {
@{$param{verilator_flags3}},
@{$param{v_flags}},
@{$param{v_flags2}},
# Flags from driver cmdline override default flags and
# flags from the test itself
@Opt_Driver_Verilator_Flags,
$param{top_filename},
@{$param{v_other_filenames}},
($param{stdout_filename}?"> ".$param{stdout_filename}:""),
@@ -1171,7 +1173,7 @@ sub _make_main {
print $fh "$VM_PREFIX * topp;\n";
if (!$self->sc) {
print $fh "vluint64_t main_time = false;\n";
print $fh "double sc_time_stamp () {\n";
print $fh "double sc_time_stamp() {\n";
print $fh " return main_time;\n";
print $fh "}\n";
}
@@ -1203,7 +1205,7 @@ sub _make_main {
print $fh "int sc_main(int argc, char **argv) {\n";
print $fh " sc_signal<bool> fastclk;\n" if $self->{inputs}{fastclk};
print $fh " sc_signal<bool> clk;\n" if $self->{inputs}{clk};
print $fh " sc_time sim_time ($self->{sim_time}, SC_NS);\n";
print $fh " sc_time sim_time($self->{sim_time}, SC_NS);\n";
} else {
print $fh "int main(int argc, char **argv, char **env) {\n";
print $fh " double sim_time = $self->{sim_time};\n";
@@ -1212,7 +1214,7 @@ sub _make_main {
print $fh " Verilated::debug(".($self->{verilated_debug}?1:0).");\n";
print $fh " srand48(5);\n"; # Ensure determinism
print $fh " Verilated::randReset(".$self->{verilated_randReset}.");\n" if defined $self->{verilated_randReset};
print $fh " topp = new $VM_PREFIX (\"top\");\n";
print $fh " topp = new $VM_PREFIX(\"top\");\n";
my $set;
if ($self->sc) {
print $fh " topp->fastclk(fastclk);\n" if $self->{inputs}{fastclk};
@@ -1229,10 +1231,10 @@ sub _make_main {
$fh->print(" Verilated::traceEverOn(true);\n");
$fh->print(" VerilatedVcdC* tfp = new VerilatedVcdC;\n") if !$self->sc;
$fh->print(" VerilatedVcdSc* tfp = new VerilatedVcdSc;\n") if $self->sc;
$fh->print(" topp->trace (tfp, 99);\n");
$fh->print(" tfp->open (\"$self->{obj_dir}/simx.vcd\");\n");
$fh->print(" topp->trace(tfp, 99);\n");
$fh->print(" tfp->open(\"$self->{obj_dir}/simx.vcd\");\n");
if ($self->{trace} && !$self->sc) {
$fh->print(" if (tfp) tfp->dump (main_time);\n");
$fh->print(" if (tfp) tfp->dump (main_time);\n");
}
$fh->print("#endif\n");
}
@@ -1260,19 +1262,19 @@ sub _make_main {
for (my $i=0; $i<5; $i++) {
my $action = 0;
if ($self->{inputs}{fastclk}) {
print $fh " ${set}fastclk=!${set}fastclk;\n";
print $fh " ${set}fastclk=!${set}fastclk;\n";
$action = 1;
}
if ($i==0 && $self->{inputs}{clk}) {
print $fh " ${set}clk=!${set}clk;\n";
print $fh " ${set}clk=!${set}clk;\n";
$action = 1;
}
if ($self->{savable}) {
$fh->print(" if (sc_time_stamp() == save_time && save_time) {\n");
$fh->print(" save_model(\"$self->{obj_dir}/saved.vltsv\");\n");
$fh->print(" printf(\"Exiting after save_model\\n\");\n");
$fh->print(" exit(0);\n");
$fh->print(" }\n");
$fh->print(" if (sc_time_stamp() == save_time && save_time) {\n");
$fh->print(" save_model(\"$self->{obj_dir}/saved.vltsv\");\n");
$fh->print(" printf(\"Exiting after save_model\\n\");\n");
$fh->print(" exit(0);\n");
$fh->print(" }\n");
}
_print_advance_time($self, $fh, 1, $action);
}
@@ -1289,7 +1291,7 @@ sub _make_main {
}
if ($self->{trace}) {
$fh->print("#if VM_TRACE\n");
$fh->print(" if (tfp) tfp->close();\n");
$fh->print(" if (tfp) tfp->close();\n");
$fh->print("#endif //VM_TRACE\n");
}
$fh->print("\n");
@@ -1312,20 +1314,20 @@ sub _print_advance_time {
if ($self->sc) {
print $fh "#if (SYSTEMC_VERSION>=20070314)\n";
print $fh " sc_start(${time},SC_NS);\n";
print $fh " sc_start(${time},SC_NS);\n";
print $fh "#else\n";
print $fh " sc_start(${time});\n";
print $fh " sc_start(${time});\n";
print $fh "#endif\n";
} else {
if ($action) {
print $fh " ${set}eval();\n";
print $fh " ${set}eval();\n";
if ($self->{trace} && !$self->sc) {
$fh->print("#if VM_TRACE\n");
$fh->print(" if (tfp) tfp->dump (main_time);\n");
$fh->print(" if (tfp) tfp->dump (main_time);\n");
$fh->print("#endif //VM_TRACE\n");
}
}
print $fh " main_time += ${time};\n";
print $fh " main_time += ${time};\n";
}
}
@@ -1514,8 +1516,8 @@ sub verilator_version {
sub files_identical {
my $fn1 = shift;
my $fn2 = shift;
my $f1 = IO::File->new ("<$fn1"); if (!$f1) { warn "%Error: $! $fn1\n"; return 0; }
my $f2 = IO::File->new ("<$fn2"); if (!$f2) { warn "%Error: $! $fn2\n"; return 0; }
my $f1 = IO::File->new("<$fn1"); if (!$f1) { warn "%Error: $! $fn1\n"; return 0; }
my $f2 = IO::File->new("<$fn2"); if (!$f2) { warn "%Error: $! $fn2\n"; return 0; }
my @l1 = $f1->getlines();
my @l2 = $f2->getlines();
my $nl = $#l1; $nl = $#l2 if ($#l2 > $nl);
@@ -1734,8 +1736,8 @@ resource required by the test is not available, such as SystemC), or are
unsupported (buggy or require a feature change before will pass.)
There are hundreds of tests, and for faster completion you may want to run
the regression tests with CCACHE enabled and in parallel on a machine with
many cores. See the -j option.
the regression tests with OBJCACHE enabled and in parallel on a machine
with many cores. See the -j option and OBJCACHE environment variable.
=head1 TEST CONFIGURATION
+17
View File
@@ -0,0 +1,17 @@
#!/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.
scenarios(simulator => 1);
compile(
verilator_flags2 => ["--trace"],
);
ok(1);
1;
+32
View File
@@ -0,0 +1,32 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2018 by Julien Margetts.
module t #(parameter sz = 4096)
(
input wire clk,
output reg [tdw(sz)-1:0] data
);
// bug1330
function integer clog2(input integer value);
integer tmp;
tmp = value-1;
clog2 = 0;
for (clog2=0; (tmp>0) && (clog2<32); clog2=clog2+1)
tmp = tmp>>1;
endfunction
function integer tdw(input integer sz);
tdw = clog2(sz);
endfunction
integer b;
always @(posedge clk)
for (b=0; b<tdw(sz); b=b+1)
if ((data[b] === 1'bx))
$display("WARNING: %1t Writing X's to tag RAM [%m]", $time);
endmodule
+123
View File
@@ -0,0 +1,123 @@
#!/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.
use IO::File;
#use Data::Dumper;
use strict;
use vars qw($Self);
scenarios(simulator => 1);
my $width = 64*($ENV{VERILATOR_TEST_WIDTH}||4);
my $vars = 64;
$Self->{cycles} = ($Self->{benchmark} ? 1_000_000 : 100);
$Self->{sim_time} = $Self->{cycles} * 10 + 1000;
sub gen {
my $filename = shift;
my $fh = IO::File->new(">$filename");
$fh->print("// Generated by t_gate_tree.pl\n");
$fh->print("module t (clk);\n");
$fh->print(" input clk;\n");
$fh->print("\n");
$fh->print(" integer cyc=0;\n");
$fh->print(" reg reset;\n");
$fh->print("\n");
my %tree;
my $fanin = 8;
my $stages = int(log($vars)/log($fanin)+0.99999)+1;
my $result = 0;
for (my $n=0; $n<$vars; $n++) {
$result += ($n||1);
$tree{0}{$n}{$n} = 1;
my $nl = $n;
for (my $stage=1; $stage<$stages; $stage++) {
my $lastn = $nl;
$nl = int($nl/$fanin);
$tree{$stage}{$nl}{$lastn} = 1;
}
}
#print Dumper(\%tree);
$fh->print("\n");
my $workingset = 0;
foreach my $stage (sort {$a<=>$b} keys %tree) {
foreach my $n (sort {$a<=>$b} keys %{$tree{$stage}}) {
$fh->print( " reg [".($width-1).":0] v${stage}_${n};\n");
$workingset += int($width/8 + 7);
}
}
$fh->print("\n");
$fh->print(" always @ (posedge clk) begin\n");
$fh->print(" cyc <= cyc + 1;\n");
$fh->print("`ifdef TEST_VERBOSE\n");
$fh->print(" \$write(\"[%0t] rst=%0x v0_0=%0x v1_0=%0x result=%0x\\n\""
.", \$time, reset, v0_0, v1_0, v".($stages-1)."_0);\n");
$fh->print("`endif\n");
$fh->print(" if (cyc==0) begin\n");
$fh->print(" reset <= 1;\n");
$fh->print(" end\n");
$fh->print(" else if (cyc==10) begin\n");
$fh->print(" reset <= 0;\n");
$fh->print(" end\n");
$fh->print("`ifndef SIM_CYCLES\n");
$fh->print(" `define SIM_CYCLES 99\n");
$fh->print("`endif\n");
$fh->print(" else if (cyc==`SIM_CYCLES) begin\n");
$fh->print(" if (v".($stages-1)."_0 != ${width}'d${result}) \$stop;\n");
$fh->print(" \$write(\"VARS=${vars} WIDTH=${width}"
." WORKINGSET=".(int($workingset/1024))."KB\\n\");\n");
$fh->print(' $write("*-* All Finished *-*\n");',"\n");
$fh->print(' $finish;',"\n");
$fh->print(" end\n");
$fh->print(" end\n");
$fh->print("\n");
for (my $n=0; $n<$vars; $n++) {
$fh->print(" always @ (posedge clk)"
." v0_${n} <= reset ? ${width}'d".(${n}||1)." : v0_"
.((int($n/$fanin)*$fanin) + (($n+1) % $fanin)).";\n");
}
foreach my $stage (sort {$a<=>$b} keys %tree) {
next if $stage == 0;
$fh->print("\n");
foreach my $n (sort {$a<=>$b} keys %{$tree{$stage}}) {
$fh->print(" always @ (posedge clk)"
." v${stage}_${n} <=");
my $op = "";
foreach my $ni (sort {$a<=>$b} keys %{$tree{$stage}{$n}}) {
$fh->print($op." v".(${stage}-1)."_${ni}");
$op = " +";
}
$fh->print(";\n");
}
}
$fh->print("endmodule\n");
}
top_filename("$Self->{obj_dir}/t_gate_tree.v");
gen($Self->{top_filename});
compile(
v_flags2 => ["+define+SIM_CYCLES=$Self->{cycles}",],
verilator_flags2=>["--stats --x-assign fast --x-initial fast"],
);
execute(
check_finished => 1,
);
ok(1);
1;
+6 -1
View File
@@ -19,7 +19,12 @@ void check(const char* bus, int got, int exp) {
}
}
int main() {
#ifdef SYSTEMC_VERSION
int sc_main(int, char**)
#else
int main()
#endif
{
Verilated::debug(0);
tb = new VM_PREFIX ("tb");
+6 -1
View File
@@ -12,7 +12,12 @@ double sc_time_stamp() {
return 0;
}
int main() {
#ifdef SYSTEMC_VERSION
int sc_main(int, char**)
#else
int main()
#endif
{
Verilated::debug(0);
tb = new VM_PREFIX ("tb");
+2 -2
View File
@@ -12,8 +12,8 @@ scenarios(vlt_all => 1);
compile(
fails => 1,
expect =>
'%Error-MODDUP: t/t_mod_dup_bad.v:\d+: Duplicate declaration of module: a
%Error-MODDUP: t/t_mod_dup_bad.v:\d+: ... Location of original declaration
'%Warning-MODDUP: t/t_mod_dup_bad.v:\d+: Duplicate declaration of module: a
%Warning-MODDUP: t/t_mod_dup_bad.v:\d+: ... Location of original declaration
.*
%Error: Exiting due to.*',
);
+33 -1
View File
@@ -899,6 +899,38 @@ XYS_FAMILY = XYS_foo
`line 614 "t/t_preproc.v" 0
`line 617 "t/t_preproc.v" 0
`dbg_hdl(UVM_LOW, ("Functional coverage enabled: paramgrp"));
`line 620 "t/t_preproc.v" 0
`line 628 "t/t_preproc.v" 0
module pcc2_cfg;
generate
`line 630 "t/t_preproc.v" 0
covergroup a @(posedge b);
`line 630 "t/t_preproc.v" 0
c: coverpoint d iff ((c) === 1'b1); endgroup
`line 630 "t/t_preproc.v" 0
a u_a;
`line 630 "t/t_preproc.v" 0
initial do begin $display ("DEBUG : %s [%m]", $sformatf ("Functional coverage enabled: u_a")); end while(0);
endgenerate
endmodule
`line 634 "t/t_preproc.v" 0
predef 0 0
predef 1 1
@@ -917,4 +949,4 @@ predef 1 1
predef 2 2
`line 634 "t/t_preproc.v" 2
`line 654 "t/t_preproc.v" 2
+20
View File
@@ -611,6 +611,26 @@ NYS_FAMILY = `NYS_FAMILY
`define INSTANCE(NAME) (.mySig (myInterface.``NAME),
`INSTANCE(pa5)
//======================================================================
// Stringify bug
`define hack(GRP) `dbg_hdl(UVM_LOW, (`"Functional coverage enabled: GRP`"));
`hack(paramgrp)
`define dbg_hdl(LVL, MSG) $display ("DEBUG : %s [%m]", $sformatf MSG)
`define svfcov_new(GRP) \
initial do begin `dbg_hdl(UVM_LOW, (`"Functional coverage enabled: GRP`")); end while(0)
`define simple_svfcov_clk(LBL, CLK, RST, ARG) \
covergroup LBL @(posedge CLK); \
c: coverpoint ARG iff ((RST) === 1'b1); endgroup \
LBL u_``LBL; `svfcov_new(u_``LBL)
module pcc2_cfg;
generate
`simple_svfcov_clk(a, b, c, d);
endgenerate
endmodule
//======================================================================
// IEEE mandated predefines
`undefineall // undefineall should have no effect on these
+50
View File
@@ -0,0 +1,50 @@
#!/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.
use IO::File;
#use Data::Dumper;
use strict;
use vars qw($Self);
scenarios(simulator => 1);
sub gen {
my $filename = shift;
my $fh = IO::File->new(">$filename");
$fh->print(chr(0xEF).chr(0xBB).chr(0xBF)); # BOM
$fh->print("// Bom\n");
$fh->print("// Generated by t_unicode.pl\n");
$fh->print("module t;\n");
$fh->print(" // Chinese "
.chr(0xe8).chr(0xaf).chr(0x84).chr(0xe8).chr(0xae).chr(0xba) # Comment
."\n");
$fh->print(" initial begin\n");
$fh->print(" \$write(\"Hello "
.chr(0xe4).chr(0xb8).chr(0x96).chr(0xe7).chr(0x95).chr(0x8c) # World
."\\n\");\n");
$fh->print(" \$write(\"*-* All Finished *-*\\n\");\n");
$fh->print(" \$finish;\n");
$fh->print(" end\n");
$fh->print("endmodule\n");
}
top_filename("$Self->{obj_dir}/t_unicode.v");
gen($Self->{top_filename});
compile(
);
execute(
check_finished => 1,
expect => q{Hello \344\270\226\347\225\214.*},
);
ok(1);
1;