Compare commits

...
14 Commits
120 changed files with 1218 additions and 442 deletions
+17
View File
@@ -3,6 +3,23 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. [by ...]
indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.872 2015-04-05
*** Add VerilatedVcdFile to allow real-time waveforms, bug890. [HyungKi Jeong]
*** Add --clk and related optimizations, msg1533. [Jie Xu]
*** Fix order of C style arrays. [Duraid Madina]
**** Add --dump-treei-<srcfile>, bug894. [Jie Xu]
**** Fix comma-instantiations with parameters, bug884. [Franck Jullien]
**** Fix SystemC arrayed bit vectors, bug886. [David Poole]
**** Fix compile error on MinGW, bug887. [HyungKi Jeong]
* Verilator 3.870 2015-02-12
**** Suppress COMBDLY when inside always_latch, bug864. [Iztok Jeras]
+4 -6
View File
@@ -3,8 +3,6 @@
#
# This file is part of Verilator.
#
# Author: Wilson Snyder <[email protected]>
#
# Code available from: http://www.veripool.org/verilator
#
#*****************************************************************************
@@ -230,16 +228,16 @@ verilator.pdf: ${srcdir}/bin/verilator Makefile
pdflatex verilator.tex
-rm -f verilator.toc verilator.aux verilator.idx verilator.out
README: readme.pod
README: README.pod
-rm -f $@
$(POD2TEXT) --loose $< > $@
README.html: readme.pod
README.html: README.pod
pod2html $< >$@
# PDF needs DIST variables; but having configure.ac as dependency isn't detected
README.pdf: readme.pod Makefile
pod2latex --full --out README.tex readme.pod
README.pdf: README.pod Makefile
pod2latex --full --out README.tex README.pod
$(PERL) $(POD2LATEXFIX) "$(DISTTITLE) README File" "${DISTDATE}" < README.tex > README2.tex
mv README2.tex README.tex
pdflatex README.tex
+3 -1
View File
@@ -5,10 +5,12 @@
=head1 NAME
This is the Verilator Package README file.
This is the Verilator package README file.
=head1 DISTRIBUTION
http://www.veripool.org/verilator
This package is Copyright 2003-2015 by Wilson Snyder. (Report bugs to
L<http://www.veripool.org/>.)
+108 -42
View File
@@ -246,6 +246,7 @@ descriptions in the next sections for more information.
-CFLAGS <flags> C++ Compiler flags for makefile
--cc Create C++ output
--cdc Clock domain crossing analysis
--clk <signal-name> Mark specified signal as clock
--compiler <compiler-name> Tune for specified C++ compiler
--converge-limit <loops> Tune convergence settle time
--coverage Enable all coverage
@@ -262,6 +263,7 @@ descriptions in the next sections for more information.
+define+<var>=<value> Set preprocessor define
--dump-tree Enable dumping .tree files
--dump-treei <level> Enable dumping .tree files at a level
--dump-treei-<srcfile> <level> Enable dumping .tree file at a source file at a level
-E Preprocess, but do not compile
--error-limit <value> Abort after this number of errors
--exe Link to create executable
@@ -284,6 +286,7 @@ descriptions in the next sections for more information.
--MP Create phony dependency targets
--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-pins64 Don't use vluint64_t's for 33-64 bit sigs
--no-skip-identical Disable skipping identical output
+notimingchecks Ignored
@@ -456,6 +459,23 @@ information is also written to the file {prefix}__cdc.txt.
Currently only checks some items that other CDC tools missed; if you have
interest in adding more traditional CDC checks, please contact the authors.
=item --clk I<signal-name>
Sometimes it is quite difficult for Verilator to distinguish clock signals from
other data signals. Occasionally the clock signals can end up in the checking
list of signals which determines if further evaluation is needed. This will
heavily degrade the performance of verilated model.
With --clk <signal-name>, user can specified root clock into the model, then
Verilator will mark the signal as clocker and propagate the clocker attribute
automatically to other signals derived from that. In this way, Verilator will
try to avoid taking the clocker signal into checking list.
Note signal-name is specified by the RTL hiearchy path. For example, v.foo.bar.
If the signal is the input to top-module, the directly the signal name. If you
find it difficult to find the exact name, try to use C</*verilator clocker*/> in
RTL file to mark the signal directly.
=item --compiler I<compiler-name>
Enables tunings and work-arounds for the specified C++ compiler.
@@ -573,7 +593,7 @@ alias for GCC compatibility.
Select the debug built image of Verilator (if available), and enable more
internal assertions (equivelent to C<--debug-check>), debugging messages
(equivelent to C<--debugi 4>), and intermediate form dump files (equivilent
to C<--dump-tree>).
to C<--dump-treei 3>).
=item --debug-check
@@ -626,8 +646,12 @@ large and not desired.
=item --dump-treei <level>
Rarely needed. Enable writing .tree debug files with a specific dumping
level, 0 disbles dumps and is equivalent to "--no-dump-tree". Level 9
=item --dump-treei-<srcfile> <level>
Rarely needed - for developer use. Set internal tree dumping level
globally to a specific dumping level or set the specified Verilator source
file to the specified tree dumping level (e.g. C<--dump-treei-V3Order 9>).
Level 0 disbles dumps and is equivalent to "--no-dump-tree". Level 9
enables dumping of every stage.
=item -E
@@ -761,6 +785,10 @@ otherwise manually create the Mdir before calling Verilator.
Specifies the name to prepend to all lower level classes. Defaults to
the same as --prefix.
=item --no-clk <signal-name>
Prevent the specified signal from being marked as clock. See C<--clk>.
=item --no-pins64
Backward compatible alias for "--pins-bv 33".
@@ -1981,6 +2009,7 @@ Verilator likewise also asserts any "unique" or "priority" SystemVerilog
keywords on case statement, as well as "unique" on if statements.
However, "priority if" is currently simply ignored.
=head1 LANGUAGE EXTENSIONS
The following additional constructs are the extensions Verilator supports
@@ -2126,6 +2155,15 @@ scheduling algorithm, sometimes required for correct clock behavior, and
always improving performance. It's also a good idea to enable the
IMPERFECTSCH warning, to insure all clock enables are properly recognized.
=item /*verilator clocker*/
=item /*verilator no_clocker*/
Used after a signal declaration to indicate the signal is used as clock or
not. This information is used by Verilator to mark the signal as clocker
and propagate the clocker attribute automatically to derived signals. See
C<--clk> for more information.
=item /*verilator coverage_block_off*/
Specifies the entire begin/end block should be ignored for coverage
@@ -2842,6 +2880,16 @@ With --cdc only, warns that asynchronous flop reset terms come from other
than primary inputs or flopped outputs, creating the potential for reset
glitches.
=item CLKDATA
Warns that clock signal is mixed used with/as data signal. The checking for
this warning is enabled only if user has explicitly marked some signal as
clocker using command line option or in-source meta comment (see C<--clk>).
The warning can be disabled without affecting the simulation result. But it
is recommanded to check the warning as this may degrade the performance of
the Verilated model.
=item CMPCONST
Warns that you are comparing a value in a way that will always be constant.
@@ -3745,50 +3793,75 @@ as the need arises. Verilator is now about 3x faster than in 2002, and is
faster than many popular commercial simulators.
=head1 AUTHORS
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.
=head1 CONTRIBUTORS
Many people have provided ideas and other assistance with Verilator.
The major corporate sponsors of Verilator, by providing significant
contributions of time or funds include include Cavium Networks, Compaq
Corporation, Digital Equipment Corporation, Embecosm Ltd., Hicamp Systems,
Intel Corporation, Mindspeed Technologies Inc., MicroTune Inc., picoChip
Designs Ltd., Sun Microsystems, Nauticus Networks, and SiCortex Inc.
contributions of time or funds include include Atmel Corporation, Cavium
Inc., Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd.,
Hicamp Systems, Intel Corporation, Mindspeed Technologies Inc., MicroTune
Inc., picoChip Designs Ltd., Sun Microsystems Inc., Nauticus Networks Inc.,
and SiCortex Inc.
The people who have contributed major functionality are Byron Bradley,
Jeremy Bennett, Lane Brooks, Duane Galbi, Paul Wasson, and Wilson Snyder.
Major testers include Jeff Dutton, Ralf Karge, David Hewson, Wim Michiels,
Alex Solomatnikov, Sebastien Van Cauwenberghe and Gene Weber.
Jeremy Bennett, Jie Xu, Lane Brooks, Duane Galbi, Paul Wasson, and Wilson
Snyder. Major testers include Jeff Dutton, Jonathon Donaldson, Ralf Karge,
David Hewson, Iztok Jeras, Wim Michiels, Alex Solomatnikov, Sebastien Van
Cauwenberghe, Gene Weber, and Clifford Wolf.
Some of the people who have provided ideas and feedback for Verilator
include: David Addison, Vasu Arasanipalai, Jens Arm, J Baxter, Jeremy
Bennett, David Black, Gregg Bouchard, Christopher Boumenot, Nick Bowler,
Byron Bradley, Bryan Brady, Lane Brooks, John Brownlee, Lawrence Butcher,
Chris Candler, Lauren Carlson, Donal Casey, Terry Chen, Robert A. Clark,
Allan Cochrane, Gunter Dannoritzer, Ashutosh Das, Bernard Deadman, Mike
Denio, John Deroo, John Dickol, Ruben Diez, Danny Ding, Ivan Djordjevic,
Alex Duller, Jeff Dutton, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy,
Robert Farrell, Eugen Fekete, Andrea Foletto, Bob Fredieu, Shankar Giri,
Sam Gladstone, Amir Gonnen, Chitlesh Goorah, Neil Hamilton, Thomas Hawkins,
David Hewson, Jae Hossell, Ben Jackson, Iztok Jeras, Christophe Joly, Mike
Kagen, Guy-Armand Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan
Katz, Sol Katzman, Jonathan Kimmitt, Gernot Koch, Soon Koh, Steve Kolecki,
David Kravitz, Steve Lang, Stephane Laurent, Walter Lavino, Christian
Leber, John Li, Charlie Lind, Andrew Ling, Paul Liu, Dan Lussier, Fred Ma,
Duraid Madina, Mark Marshall, Jason McMullan, Wim Michiels, Dennis
Muhlestein, John Murphy, Richard Myers, Dimitris Nalbantis, Paul Nitza,
Pete Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, Brad Parker, Dominic
Plunkett, Niranjan Prabhu, Usha Priyadharshini, Alberto Del Rio, Oleg
Rodionov, John Sanguinetti, Salman Sheikh, Mike Shinkarovsky, Rafael
Shirakawa, Jeffrey Short, Rodney Sinclair, Brian Small, Alex Solomatnikov,
Art Stamness, John Stroebel, Emerson Suguimoto, Gene Sullivan, Renga
Sundararajan, Stefan Thiede, Gary Thomas, Steve Tong, Hans Van Antwerpen,
Holger Waechtler, Stefan Wallentowitz, Shawn Wang, Greg Waters, Thomas
Watts, Eugene Weber, David Welch, Leon Wildman, Gerald Williams, Trevor
Williams, Jeff Winston, Joshua Wise, Johan Wouters, and Ding Xiaoliang.
include: Yves Mathieu, David Addison, Nikana Anastasiadis, Hans Van
Antwerpen, Vasu Arasanipalai, Jens Arm, Sharad Bagri, Andrew Bardsley,
Geoff Barrett, J Baxter, Julius Baxter, Jeremy Bennett, Michael Berman,
David Binderman, David Black, Daniel Bone, Gregg Bouchard, Christopher
Boumenot, Nick Bowler, Byron Bradley, Bryan Brady, Charlie Brej, Lane
Brooks, John Brownlee, Jeff Bush, Lawrence Butcher, Ted Campbell, Chris
Candler, Lauren Carlson, Donal Casey, Terry Chen, Robert A. Clark, Allan
Cochrane, Gunter Dannoritzer, Ashutosh Das, Bernard Deadman, Mike Denio,
John Deroo, Philip Derrick, John Dickol, R. Diez, Ruben Diez, Danny Ding,
Ivan Djordjevic, Jonathon Donaldson, Alex Duller, Jeff Dutton, Chandan
Egbert, Joe Eiler, Ahmed El-Mahmoudy, Robert Farrell, Eugen Fekete,
Fabrizio Ferrandi, Andrea Foletto, Bob Fredieu, Christian Gelinek, Glen
Gibb, Shankar Giri, Sam Gladstone, Amir Gonnen, Chitlesh Goorah, Neil
Hamilton, Junji Hashimoto, Thomas Hawkins, David Hewson, Hiroki Honda, Alex
Hornung, Jae Hossell, Ben Jackson, Krzysztof Jankowski, HyungKi Jeong,
Iztok Jeras, James Johnson, Christophe Joly, Franck Jullien, Mike Kagen,
Kaalia Kahn, Guy-Armand Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf
Karge, Dan Katz, Sol Katzman, Jonathan Kimmitt, Sobhan Klnv, Gernot Koch,
Soon Koh, Steve Kolecki, Brett Koonce, Wojciech Koszek, Varun Koyyalagunta,
David Kravitz, Roland Kruse, 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, Jason McMullan, Wim
Michiels, 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, Brad Parker, David
Pierce, Dominic Plunkett, David Poole, Rich Porter, Niranjan Prabhu, Usha
Priyadharshini, Mark Jackson Pulver, Prateek Puri, Chris Randall, Frederic
Requin, Alberto Del Rio, Oleg Rodionov, Jan Egil Ruud, John Sanguinetti,
Salman Sheikh, Mike Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Rodney
Sinclair, Steven Slatter, Brian Small, Wilson Snyder, Alex Solomatnikov,
Art Stamness, John Stevenson, Todd Strader, John Stroebel, Emerson
Suguimoto, Gene Sullivan, Renga Sundararajan, Yutetsu Takatsukasa, Peter
Tengstrand, Stefan Thiede, Gary Thomas, Kevin Thompson, Mike Thyer, Steve
Tong, Holger Waechtler, Stefan Wallentowitz, Shawn Wang, Greg Waters,
Thomas Watts, Eugene Weber, David Welch, Leon Wildman, Gerald Williams,
Trevor Williams, Jeff Winston, Joshua Wise, Clifford Wolf, Johan Wouters,
Ding Xiaoliang, Jie Xu, and Amir Yazdanbakhsh.
Thanks to them, and all those we've missed including above.
=head1 DISTRIBUTION
The latest version is available from L<http://www.veripool.org/>.
@@ -3798,13 +3871,6 @@ redistribute it and/or modify the Verilator internals under the terms of
either the GNU Lesser General Public License Version 3 or the Perl Artistic
License Version 2.0.
=head1 AUTHORS
When possible, please instead report bugs to L<http://www.veripool.org/>.
Wilson Snyder <[email protected]>
Major concepts by Paul Wasson and Duane Galbi.
=head1 SEE ALSO
+1 -1
View File
@@ -6,7 +6,7 @@
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[3.870 2015-02-12])
AC_INIT([Verilator],[3.872 2015-04-05])
AC_CONFIG_HEADER(src/config_build.h)
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h)
-2
View File
@@ -17,8 +17,6 @@
/// \file
/// \brief Verilator coverage analysis
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
#include "verilatedos.h"
-2
View File
@@ -17,8 +17,6 @@
/// \file
/// \brief Coverage analysis support
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
#ifndef _VERILATED_COV_H_
-2
View File
@@ -17,8 +17,6 @@
/// \file
/// \brief Coverage item keys
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
#ifndef _VERILATED_COV_KEY_H_
-2
View File
@@ -17,8 +17,6 @@
/// \file
/// \brief C++ Tracing in VCD Format
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
#include "verilatedos.h"
-2
View File
@@ -17,8 +17,6 @@
/// \file
/// \brief Save-restore serialization of verilated modules
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
#ifndef _VERILATED_SAVE_C_H_
+42 -8
View File
@@ -17,8 +17,6 @@
/// \file
/// \brief C++ Tracing in VCD Format
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
// SPDIFF_OFF
@@ -76,11 +74,48 @@ protected:
: m_initcb(icb), m_fullcb(fcb), m_changecb(changecb), m_userthis(ut), m_code(code) {};
};
//=============================================================================
//=============================================================================
//=============================================================================
// VerilatedVcdFile
bool VerilatedVcdFile::open(const string& name) {
m_fd = ::open(name.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK, 0666);
return (m_fd>=0);
}
void VerilatedVcdFile::close() {
::close(m_fd);
}
ssize_t VerilatedVcdFile::write(const char* bufp, ssize_t len) {
return ::write(m_fd, bufp, len);
}
//=============================================================================
//=============================================================================
//=============================================================================
// Opening/Closing
VerilatedVcd::VerilatedVcd(VerilatedVcdFile* filep)
: m_isOpen(false), m_rolloverMB(0), m_modDepth(0), m_nextCode(1) {
// Not in header to avoid link issue if header is included without this .cpp file
m_fileNewed = (filep == NULL);
m_filep = m_fileNewed ? new VerilatedVcdFile : filep;
m_namemapp = NULL;
m_timeRes = m_timeUnit = 1e-9;
m_timeLastDump = 0;
m_sigs_oldvalp = NULL;
m_evcd = false;
m_scopeEscape = '.'; // Backward compatibility
m_fullDump = true;
m_wrChunkSize = 8*1024;
m_wrBufp = new char [m_wrChunkSize*8];
m_wrFlushp = m_wrBufp + m_wrChunkSize * 6;
m_writep = m_wrBufp;
m_wroteBytes = 0;
}
void VerilatedVcd::open (const char* filename) {
if (isOpen()) return;
@@ -142,9 +177,7 @@ void VerilatedVcd::openNext (bool incFilename) {
assert(0); // Not supported yet.
} else {
// cppcheck-suppress duplicateExpression
m_fd = ::open (m_filename.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK
, 0666);
if (m_fd<0) {
if (!m_filep->open(m_filename)) {
// User code can check isOpen()
m_isOpen = false;
return;
@@ -199,6 +232,7 @@ VerilatedVcd::~VerilatedVcd() {
if (m_wrBufp) { delete[] m_wrBufp; m_wrBufp=NULL; }
if (m_sigs_oldvalp) { delete[] m_sigs_oldvalp; m_sigs_oldvalp=NULL; }
deleteNameMap();
if (m_filep && m_fileNewed) { delete m_filep; m_filep = NULL; }
// Remove from list of traces
vector<VerilatedVcd*>::iterator pos = find(s_vcdVecp.begin(), s_vcdVecp.end(), this);
if (pos != s_vcdVecp.end()) { s_vcdVecp.erase(pos); }
@@ -209,7 +243,7 @@ void VerilatedVcd::closePrev () {
bufferFlush();
m_isOpen = false;
::close(m_fd);
m_filep->close();
}
void VerilatedVcd::closeErr () {
@@ -219,7 +253,7 @@ void VerilatedVcd::closeErr () {
// No buffer flush, just fclose
m_isOpen = false;
::close(m_fd); // May get error, just ignore it
m_filep->close(); // May get error, just ignore it
}
void VerilatedVcd::close() {
@@ -285,7 +319,7 @@ void VerilatedVcd::bufferFlush () {
ssize_t remaining = (m_writep - wp);
if (remaining==0) break;
errno = 0;
ssize_t got = write (m_fd, wp, remaining);
ssize_t got = m_filep->write(wp, remaining);
if (got>0) {
wp += got;
m_wroteBytes += got;
+20 -19
View File
@@ -17,8 +17,6 @@
/// \file
/// \brief C++ Tracing in VCD Format
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
// SPDIFF_OFF
@@ -36,6 +34,22 @@ class VerilatedVcd;
class VerilatedVcdCallInfo;
// SPDIFF_ON
//=============================================================================
// VerilatedFile
/// File handling routines, which can be overrode for e.g. socket I/O
class VerilatedVcdFile {
private:
int m_fd; ///< File descriptor we're writing to
public:
// METHODS
VerilatedVcdFile() : m_fd(0) {}
virtual ~VerilatedVcdFile() {}
virtual bool open(const string& name);
virtual void close();
virtual ssize_t write(const char* bufp, ssize_t len);
};
//=============================================================================
// VerilatedVcdSig
/// Internal data on one signal being traced.
@@ -62,9 +76,10 @@ typedef void (*VerilatedVcdCallback_t)(VerilatedVcd* vcdp, void* userthis, vluin
class VerilatedVcd {
private:
VerilatedVcdFile* m_filep; ///< File we're writing to
bool m_fileNewed; ///< m_filep needs destruction
bool m_isOpen; ///< True indicates open file
bool m_evcd; ///< True for evcd format
int m_fd; ///< File descriptor we're writing to
string m_filename; ///< Filename we're writing to (if open)
vluint64_t m_rolloverMB; ///< MB of file size to rollover at
char m_scopeEscape; ///< Character to separate scope components
@@ -135,21 +150,7 @@ protected:
public:
// CREATORS
VerilatedVcd () : m_isOpen(false), m_rolloverMB(0), m_modDepth(0), m_nextCode(1) {
m_namemapp = NULL;
m_timeRes = m_timeUnit = 1e-9;
m_timeLastDump = 0;
m_sigs_oldvalp = NULL;
m_evcd = false;
m_scopeEscape = '.'; // Backward compatibility
m_fd = 0;
m_fullDump = true;
m_wrChunkSize = 8*1024;
m_wrBufp = new char [m_wrChunkSize*8];
m_wrFlushp = m_wrBufp + m_wrChunkSize * 6;
m_writep = m_wrBufp;
m_wroteBytes = 0;
}
VerilatedVcd(VerilatedVcdFile* filep=NULL);
~VerilatedVcd();
// ACCESSORS
@@ -398,7 +399,7 @@ class VerilatedVcdC {
VerilatedVcd m_sptrace; ///< Trace file being created
public:
// CONSTRUCTORS
VerilatedVcdC() {}
VerilatedVcdC(VerilatedVcdFile* filep=NULL) : m_sptrace(filep) {}
~VerilatedVcdC() {}
// ACCESSORS
/// Is file open?
-2
View File
@@ -17,8 +17,6 @@
/// \file
/// \brief Verilator tracing in VCD Format
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
// SPDIFF_OFF
-2
View File
@@ -17,8 +17,6 @@
/// \file
/// \brief Verilator tracing in VCD format
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
// SPDIFF_OFF
+1
View File
@@ -178,6 +178,7 @@ typedef signed __int32 ssize_t; ///< signed size_t; returned fro
#else // Linux or compliant Unix flavors, -m64
# include <stdint.h> // Linux and most flavors
# include <unistd.h> // Linux ssize_t
# include <inttypes.h> // Solaris
typedef uint8_t vluint8_t; ///< 32-bit unsigned type
typedef uint16_t vluint16_t; ///< 32-bit unsigned type
+12
View File
@@ -407,6 +407,18 @@ Tests that fail should by convention have the suffix C<_bad> in their name,
and include C<fails =E<gt> 1> in either their C<compile> or C<execute> step as
appropriate.
=head2 Preparing to Run Tests
For all tests to pass you must install the following packages:
* SystemC to compile the SystemC outputs, see http://systemc.org
* Parallel::Forker from CPAN to run tests in parallel, you can install this
with e.g. "sudo cpan install Parallel::Forker".
* vcddiff to find differences in VCD outputs. See the readme at
https://github.com/veripool/vcddiff
=head2 Controlling the Test Driver
Test drivers are written in PERL. All invoke the main test driver script,
+1
View File
@@ -215,6 +215,7 @@ RAW_OBJS = \
V3Number.o \
V3Options.o \
V3Order.o \
V3Os.o \
V3Param.o \
V3PreShell.o \
V3Premit.o \
+1
View File
@@ -436,4 +436,5 @@ public:
void V3Active::activeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ActiveVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("active.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -160,4 +160,5 @@ public:
void V3ActiveTop::activeTopAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ActiveTopVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("activetop.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -337,4 +337,5 @@ public:
void V3Assert::assertAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
AssertVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("assert.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -137,4 +137,5 @@ public:
void V3AssertPre::assertPreAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
AssertPreVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("assertpre.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+5 -1
View File
@@ -176,6 +176,10 @@ string AstNode::prettyName(const string& namein) {
pretty += ".";
pos += 7;
}
else if (0==strncmp(pos,"->",2)) {
pretty += ".";
pos += 2;
}
else if (0==strncmp(pos,"__PVT__",7)) {
pretty += "";
pos += 7;
@@ -1009,7 +1013,7 @@ void AstNode::dumpTreeAndNext(ostream& os, const string& indent, int maxDepth) {
}
void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) {
if (v3Global.opt.dumpTree() && doDump) {
if (doDump) {
{ // Write log & close
UINFO(2,"Dumping "<<filename<<endl);
const auto_ptr<ofstream> logsp (V3File::new_ofstream(filename, append));
+36 -2
View File
@@ -257,7 +257,9 @@ public:
VAR_PUBLIC_FLAT_RW, // V3LinkParse moves to AstVar::sigPublic
VAR_ISOLATE_ASSIGNMENTS, // V3LinkParse moves to AstVar::attrIsolateAssign
VAR_SC_BV, // V3LinkParse moves to AstVar::attrScBv
VAR_SFORMAT // V3LinkParse moves to AstVar::attrSFormat
VAR_SFORMAT, // V3LinkParse moves to AstVar::attrSFormat
VAR_CLOCKER, // V3LinkParse moves to AstVar::attrClocker
VAR_NO_CLOCKER // V3LinkParse moves to AstVar::attrClocker
};
enum en m_e;
const char* ascii() const {
@@ -270,7 +272,8 @@ public:
"MEMBER_BASE",
"VAR_BASE", "VAR_CLOCK", "VAR_CLOCK_ENABLE", "VAR_PUBLIC",
"VAR_PUBLIC_FLAT", "VAR_PUBLIC_FLAT_RD","VAR_PUBLIC_FLAT_RW",
"VAR_ISOLATE_ASSIGNMENTS", "VAR_SC_BV", "VAR_SFORMAT"
"VAR_ISOLATE_ASSIGNMENTS", "VAR_SC_BV", "VAR_SFORMAT", "VAR_CLOCKER",
"VAR_NO_CLOCKER"
};
return names[m_e];
};
@@ -485,6 +488,37 @@ public:
//######################################################################
class AstVarAttrClocker {
public:
enum en {
CLOCKER_UNKNOWN=0,
CLOCKER_YES,
CLOCKER_NO,
_ENUM_END
};
enum en m_e;
// CONSTRUCTOR - note defaults to *UNKNOWN*
inline AstVarAttrClocker () : m_e(CLOCKER_UNKNOWN) {}
inline AstVarAttrClocker (en _e) : m_e(_e) {}
explicit inline AstVarAttrClocker (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
AstVarAttrClocker invert() const {
if (m_e==CLOCKER_YES) return CLOCKER_NO;
else if (m_e==CLOCKER_NO) return CLOCKER_YES;
else return m_e;
}
const char* ascii() const {
static const char* names[] = {
"","clker","non_clker"};
return names[m_e]; }
};
inline bool operator== (AstVarAttrClocker lhs, AstVarAttrClocker rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstVarAttrClocker lhs, AstVarAttrClocker::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstVarAttrClocker::en lhs, AstVarAttrClocker rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstVarAttrClocker rhs) { return os<<rhs.ascii(); }
//######################################################################
class VAlwaysKwd {
public:
enum en {
+21
View File
@@ -350,6 +350,27 @@ string AstVar::scType() const {
}
}
AstVar* AstVar::scVarRecurse(AstNode* nodep) {
// See if this is a SC assignment; if so return that type
// Historically sc variables are identified by a variable
// attribute. TODO it would better be a data type attribute.
if (AstVar* anodep = nodep->castVar()) {
if (anodep->isSc()) return anodep;
else return NULL;
}
else if (nodep->castVarRef()) {
if (nodep->castVarRef()->varp()->isSc()) return nodep->castVarRef()->varp();
else return NULL;
}
else if (nodep->castArraySel()) {
if (nodep->op1p()) if (AstVar* p = scVarRecurse(nodep->op1p())) return p;
if (nodep->op2p()) if (AstVar* p = scVarRecurse(nodep->op2p())) return p;
if (nodep->op3p()) if (AstVar* p = scVarRecurse(nodep->op3p())) return p;
if (nodep->op4p()) if (AstVar* p = scVarRecurse(nodep->op4p())) return p;
}
return NULL;
}
AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
// dimension passed from AstArraySel::dimension
// Dimension 0 means the VAR itself, 1 is the closest SEL to the AstVar,
+5 -2
View File
@@ -942,6 +942,7 @@ private:
bool m_isIfaceParent:1; // dtype is reference to interface present in this module
bool m_noSubst:1; // Do not substitute out references
bool m_trace:1; // Trace this variable
AstVarAttrClocker m_attrClocker;
void init() {
m_input=false; m_output=false; m_tristate=false; m_declOutput=false;
@@ -952,8 +953,7 @@ private:
m_funcLocal=false; m_funcReturn=false;
m_attrClockEn=false; m_attrScBv=false; m_attrIsolateAssign=false; m_attrSFormat=false;
m_fileDescr=false; m_isConst=false; m_isStatic=false; m_isPulldown=false; m_isPullup=false;
m_isIfaceParent=false;
m_noSubst=false;
m_isIfaceParent=false; m_attrClocker=AstVarAttrClocker::CLOCKER_UNKNOWN; m_noSubst=false;
m_trace=false;
}
public:
@@ -1026,6 +1026,7 @@ public:
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
void attrClockEn(bool flag) { m_attrClockEn = flag; }
void attrClocker(AstVarAttrClocker flag) { m_attrClocker = flag; }
void attrFileDescr(bool flag) { m_fileDescr = flag; }
void attrScClocked(bool flag) { m_scClocked = flag; }
void attrScBv(bool flag) { m_attrScBv = flag; }
@@ -1105,6 +1106,7 @@ public:
bool attrScClocked() const { return m_scClocked; }
bool attrSFormat() const { return m_attrSFormat; }
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
AstVarAttrClocker attrClocker() const { return m_attrClocker; }
virtual string verilogKwd() const;
void propagateAttrFrom(AstVar* fromp) {
// This is getting connected to fromp; keep attributes
@@ -1132,6 +1134,7 @@ public:
if (varType()==AstVarType::INOUT) m_varType = AstVarType::TRIWIRE;
if (varType()==AstVarType::INPUT || varType()==AstVarType::OUTPUT) m_varType = AstVarType::WIRE;
}
static AstVar* scVarRecurse(AstNode* nodep);
};
class AstDefParam : public AstNode {
+1
View File
@@ -271,4 +271,5 @@ void V3Begin::debeginAll(AstNetlist* nodep) {
if (state.anyFuncInBegin()) {
BeginRelinkVisitor brvisitor (nodep,&state);
}
V3Global::dumpCheckGlobalTree("begin.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -491,6 +491,7 @@ public:
void V3Case::caseAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CaseVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("case.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Case::caseLint(AstNodeCase* nodep) {
UINFO(4,__FUNCTION__<<": "<<endl);
+2
View File
@@ -149,6 +149,7 @@ private:
if (!nodep->lvalue()
&& !nodep->backp()->castCCast()
&& nodep->backp()->castNodeMath()
&& !nodep->backp()->castArraySel()
&& nodep->backp()->width()
&& castSize(nodep) != castSize(nodep->varp())) {
// Cast vars to IData first, else below has upper bits wrongly set
@@ -187,4 +188,5 @@ public:
void V3Cast::castAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CastVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("cast.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -252,4 +252,5 @@ void V3Changed::changedAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ChangedState state;
ChangedVisitor visitor (nodep, &state);
V3Global::dumpCheckGlobalTree("changed.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -292,4 +292,5 @@ public:
void V3Clean::cleanAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CleanVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("clean.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -914,4 +914,5 @@ void V3ClkGater::clkGaterAll(AstNetlist* nodep) {
// While the gater does well at some modules, it seems to slow down many others
UINFO(5,"ClkGater is disabled due to performance issues\n");
//GaterVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("clkgater.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -407,4 +407,5 @@ public:
void V3Clock::clockAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ClockVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("clock.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -474,4 +474,5 @@ public:
void V3Combine::combineAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CombineVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("combine.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+4
View File
@@ -2383,12 +2383,14 @@ void V3Const::constifyAllLint(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (ConstVisitor::PROC_V_WARN);
(void)visitor.mainAcceptEdit(nodep);
V3Global::dumpCheckGlobalTree("const.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Const::constifyCpp(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (ConstVisitor::PROC_CPP);
(void)visitor.mainAcceptEdit(nodep);
V3Global::dumpCheckGlobalTree("const_cpp.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
AstNode* V3Const::constifyEdit(AstNode* nodep) {
@@ -2404,6 +2406,7 @@ void V3Const::constifyAllLive(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (ConstVisitor::PROC_LIVE);
(void)visitor.mainAcceptEdit(nodep);
V3Global::dumpCheckGlobalTree("const.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Const::constifyAll(AstNetlist* nodep) {
@@ -2411,6 +2414,7 @@ void V3Const::constifyAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (ConstVisitor::PROC_V_EXPENSIVE);
(void)visitor.mainAcceptEdit(nodep);
V3Global::dumpCheckGlobalTree("const.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
AstNode* V3Const::constifyExpensiveEdit(AstNode* nodep) {
+1
View File
@@ -395,4 +395,5 @@ public:
void V3Coverage::coverage(AstNetlist* rootp) {
UINFO(2,__FUNCTION__<<": "<<endl);
CoverageVisitor visitor (rootp);
V3Global::dumpCheckGlobalTree("coverage.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -135,4 +135,5 @@ public:
void V3CoverageJoin::coverageJoin(AstNetlist* rootp) {
UINFO(2,__FUNCTION__<<": "<<endl);
CoverageJoinVisitor visitor (rootp);
V3Global::dumpCheckGlobalTree("coveragejoin.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+3
View File
@@ -291,12 +291,15 @@ public:
void V3Dead::deadifyModules(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, false, false);
V3Global::dumpCheckGlobalTree("deadModules.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
void V3Dead::deadifyDTypes(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, false, true);
V3Global::dumpCheckGlobalTree("deadDType.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Dead::deadifyAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, true, true);
V3Global::dumpCheckGlobalTree("deadAll.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -471,4 +471,5 @@ public:
void V3Delayed::delayedAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DelayedVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("delayed.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -175,4 +175,5 @@ public:
void V3Depth::depthAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DepthVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("depth.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+1
View File
@@ -140,4 +140,5 @@ public:
void V3DepthBlock::depthBlockAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DepthBlockVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("deepblock.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -262,4 +262,5 @@ public:
void V3Descope::descopeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DescopeVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("descope.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+5 -6
View File
@@ -83,6 +83,7 @@ public:
: nodep->isQuad() ? "Q" : "I");
}
void emitScIQW(AstVar* nodep) {
if (!nodep->isSc()) nodep->v3fatalSrc("emitting SystemC operator on non-SC variable");
puts (nodep->isScBigUint() ? "SB"
: nodep->isScUint() ? "SU"
: nodep->isScBv() ? "SW"
@@ -155,19 +156,17 @@ public:
selp->lsbp()->iterateAndNext(*this); puts(", ");
selp->fromp()->iterateAndNext(*this); puts(", ");
}
} else if (nodep->lhsp()->castVarRef()
&& nodep->lhsp()->castVarRef()->varp()->isSc()) {
} else if (AstVar* varp = AstVar::scVarRecurse(nodep->lhsp())) {
putbs("VL_ASSIGN_"); // Set a systemC variable
emitScIQW(nodep->lhsp()->castVarRef()->varp());
emitScIQW(varp);
emitIQW(nodep);
puts("(");
puts(cvtToStr(nodep->widthMin())+",");
nodep->lhsp()->iterateAndNext(*this); puts(", ");
} else if (nodep->rhsp()->castVarRef()
&& nodep->rhsp()->castVarRef()->varp()->isSc()) {
} else if (AstVar* varp = AstVar::scVarRecurse(nodep->rhsp())) {
putbs("VL_ASSIGN_"); // Get a systemC variable
emitIQW(nodep);
emitScIQW(nodep->rhsp()->castVarRef()->varp());
emitScIQW(varp);
puts("(");
puts(cvtToStr(nodep->widthMin())+",");
nodep->lhsp()->iterateAndNext(*this); puts(", ");
+5 -4
View File
@@ -29,6 +29,7 @@
#include <algorithm>
#include "V3Global.h"
#include "V3Os.h"
#include "V3EmitMk.h"
#include "V3EmitCBase.h"
@@ -46,7 +47,7 @@ public:
}
void putMakeClassEntry(V3OutMkFile& of, const string& name) {
of.puts("\t"+V3Options::filenameNonDirExt(name)+" \\\n");
of.puts("\t"+V3Os::filenameNonDirExt(name)+" \\\n");
}
void emitClassMake() {
@@ -184,8 +185,8 @@ public:
const V3StringSet& cppFiles = v3Global.opt.cppFiles();
for (V3StringSet::const_iterator it = cppFiles.begin(); it != cppFiles.end(); ++it) {
string cppfile = *it;
of.puts("\t"+V3Options::filenameNonExt(cppfile)+" \\\n");
string dir = V3Options::filenameDir(cppfile);
of.puts("\t"+V3Os::filenameNonExt(cppfile)+" \\\n");
string dir = V3Os::filenameDir(cppfile);
if (dirs.find(dir) == dirs.end()) dirs.insert(dir);
}
of.puts("\n");
@@ -209,7 +210,7 @@ public:
of.puts("\n");
for (V3StringSet::const_iterator it = cppFiles.begin(); it != cppFiles.end(); ++it) {
string cppfile = *it;
string basename = V3Options::filenameNonExt(cppfile);
string basename = V3Os::filenameNonExt(cppfile);
of.puts(basename+".o: "+cppfile+"\n");
of.puts("\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<\n");
}
+3 -2
View File
@@ -65,6 +65,7 @@ public:
CASEWITHX, // Case with X values
CASEX, // Casex
CDCRSTLOGIC, // Logic in async reset path
CLKDATA, // Clock used as data
CMPCONST, // Comparison is constant due to limited range
COMBDLY, // Combinatorial delayed assignment
DEFPARAM, // Style: Defparam
@@ -119,8 +120,8 @@ public:
" EC_FIRST_WARN",
"ALWCOMBORDER", "ASSIGNDLY", "ASSIGNIN",
"BLKANDNBLK", "BLKSEQ",
"CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CDCRSTLOGIC", "CMPCONST",
"COMBDLY", "DEFPARAM", "DECLFILENAME",
"CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CDCRSTLOGIC", "CLKDATA",
"CMPCONST", "COMBDLY", "DEFPARAM", "DECLFILENAME",
"ENDLABEL", "GENCLK",
"IFDEPTH", "IMPERFECTSCH", "IMPLICIT", "IMPURE",
"INCABSPATH", "INITIALDLY",
+5 -7
View File
@@ -874,16 +874,13 @@ private:
nodep->iterateChildren(*this);
bool did = false;
if (nodep->isWide() && ((nodep->lhsp()->castVarRef()
&& !nodep->lhsp()->castVarRef()->varp()->isSc())
|| nodep->lhsp()->castArraySel())) {
|| nodep->lhsp()->castArraySel()))
&& !AstVar::scVarRecurse(nodep->lhsp()) // Need special function for SC
&& !AstVar::scVarRecurse(nodep->rhsp())) {
if (AstConst* rhsp = nodep->rhsp()->castConst()) {
did = expandWide(nodep,rhsp);
} else if (AstVarRef* rhsp = nodep->rhsp()->castVarRef()) {
if (rhsp->varp()->isSc()) {
// Still need special access function
} else {
did = expandWide(nodep,rhsp);
}
did = expandWide(nodep,rhsp);
} else if (AstSel* rhsp = nodep->rhsp()->castSel()) {
did = expandWide(nodep,rhsp);
} else if (AstArraySel* rhsp = nodep->rhsp()->castArraySel()) {
@@ -940,4 +937,5 @@ public:
void V3Expand::expandAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ExpandVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("expand.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+2 -9
View File
@@ -40,6 +40,7 @@
#include "V3Global.h"
#include "V3File.h"
#include "V3Os.h"
#include "V3PreShell.h"
#include "V3Ast.h"
@@ -259,19 +260,11 @@ bool V3File::checkTimes(const string& filename, const string& cmdline) {
return dependImp.checkTimes(filename, cmdline);
}
void V3File::createDir(const string& dirname) {
#ifndef _WIN32
mkdir(dirname.c_str(), 0777);
#else
mkdir(dirname.c_str());
#endif
}
void V3File::createMakeDir() {
static bool created = false;
if (!created) {
created = true;
createDir(v3Global.opt.makeDir());
V3Os::createDir(v3Global.opt.makeDir());
}
}
-1
View File
@@ -67,7 +67,6 @@ public:
static bool checkTimes(const string& filename, const string& cmdline);
// Directory utilities
static void createDir(const string& dirname);
static void createMakeDir();
};
+1
View File
@@ -1266,4 +1266,5 @@ void V3Gate::gateAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
GateVisitor visitor (nodep);
GateDeassignVisitor deassign (nodep);
V3Global::dumpCheckGlobalTree("gate.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -228,4 +228,5 @@ public:
void V3GenClk::genClkAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
GenClkReadVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("genclk.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -563,4 +563,5 @@ void V3Inline::inlineAll(AstNetlist* nodep) {
modp->unlinkFrBack()->deleteTree(); modp=NULL;
}
}
V3Global::dumpCheckGlobalTree("inline.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+2
View File
@@ -322,9 +322,11 @@ AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModu
void V3Inst::instAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
InstVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("inst.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Inst::dearrayAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
InstDeVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("dearray.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+1
View File
@@ -515,4 +515,5 @@ void V3Life::lifeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
LifeState state;
LifeTopVisitor visitor (nodep, &state);
V3Global::dumpCheckGlobalTree("life.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -193,4 +193,5 @@ void V3LifePost::lifepostAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
// Mark redundant AssignPost
LifePostDlyVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("life_post.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+12 -4
View File
@@ -35,13 +35,21 @@ private:
static void linkDotGuts(AstNetlist* nodep, VLinkDotStep step);
public:
static void linkDotPrimary(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_PRIMARY); }
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_PRIMARY);
V3Global::dumpCheckGlobalTree("linkdot.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
static void linkDotParamed(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_PARAMED); }
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_PARAMED);
V3Global::dumpCheckGlobalTree("paramlink.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
static void linkDotArrayed(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_ARRAYED); }
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_ARRAYED);
V3Global::dumpCheckGlobalTree("linkdot.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
static void linkDotScope(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_SCOPED); }
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_SCOPED);
V3Global::dumpCheckGlobalTree("linkdot.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
};
#endif // Guard
+1
View File
@@ -263,4 +263,5 @@ public:
void V3LinkJump::linkJump(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
LinkJumpVisitor bvisitor (nodep);
V3Global::dumpCheckGlobalTree("link.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -269,6 +269,7 @@ public:
void V3LinkLValue::linkLValue(AstNetlist* rootp) {
UINFO(4,__FUNCTION__<<": "<<endl);
LinkLValueVisitor visitor(rootp, false);
V3Global::dumpCheckGlobalTree("linklvalue.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
void V3LinkLValue::linkLValueSet(AstNode* nodep) {
// Called by later link functions when it is known a node needs
+1
View File
@@ -80,6 +80,7 @@ void V3LinkLevel::modSortByLevel() {
v3Global.rootp()->addModulep(nodep);
}
UINFO(9,"modSortByLevel() done\n"); // Comment required for gcc4.6.3 / bug666
V3Global::dumpCheckGlobalTree("cells.tree", false, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
//######################################################################
+11
View File
@@ -237,6 +237,16 @@ private:
m_varp->attrScBv(true);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
}
else if (nodep->attrType() == AstAttrType::VAR_CLOCKER) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
m_varp->attrClocker(AstVarAttrClocker::CLOCKER_YES);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
}
else if (nodep->attrType() == AstAttrType::VAR_NO_CLOCKER) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
m_varp->attrClocker(AstVarAttrClocker::CLOCKER_NO);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
}
}
virtual void visit(AstAlwaysPublic* nodep, AstNUser*) {
@@ -359,4 +369,5 @@ public:
void V3LinkParse::linkParse(AstNetlist* rootp) {
UINFO(4,__FUNCTION__<<": "<<endl);
LinkParseVisitor visitor(rootp);
V3Global::dumpCheckGlobalTree("linkparse.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+1
View File
@@ -462,4 +462,5 @@ void V3LinkResolve::linkResolve(AstNetlist* rootp) {
UINFO(4,__FUNCTION__<<": "<<endl);
LinkResolveVisitor visitor(rootp);
LinkBotupVisitor visitorb(rootp);
V3Global::dumpCheckGlobalTree("linkresolve.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+1
View File
@@ -250,4 +250,5 @@ void V3Localize::localizeAll(AstNetlist* nodep) {
LocalizeVisitor visitor (nodep);
// Fix up hiernames
LocalizeDehierVisitor dvisitor (nodep);
V3Global::dumpCheckGlobalTree("localize.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+1
View File
@@ -149,4 +149,5 @@ public:
void V3Name::nameAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
NameVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("name.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+90 -153
View File
@@ -36,6 +36,7 @@
#include "V3Global.h"
#include "V3String.h"
#include "V3Os.h"
#include "V3Options.h"
#include "V3Error.h"
#include "V3File.h"
@@ -156,12 +157,27 @@ bool V3Options::isFuture(const string& flag) const {
bool V3Options::isLibraryFile(const string& filename) const {
return m_libraryFiles.find(filename) != m_libraryFiles.end();
}
void V3Options::addLibraryFile(const string& filename) {
if (m_libraryFiles.find(filename) == m_libraryFiles.end()) {
m_libraryFiles.insert(filename);
}
}
bool V3Options::isClocker(const string& signame) const {
return m_clockers.find(signame) != m_clockers.end();
}
void V3Options::addClocker(const string& signame) {
if (m_clockers.find(signame) == m_clockers.end()) {
m_clockers.insert(signame);
}
}
bool V3Options::isNoClocker(const string& signame) const {
return m_noClockers.find(signame) != m_noClockers.end();
}
void V3Options::addNoClocker(const string& signame) {
if (m_noClockers.find(signame) == m_noClockers.end()) {
m_noClockers.insert(signame);
}
}
void V3Options::addVFile(const string& filename) {
// We use a list for v files, because it's legal to have includes
// in a specific order and multiple of them.
@@ -197,83 +213,6 @@ V3LangCode::V3LangCode (const char* textp) {
//######################################################################
// File searching
string V3Options::filenameFromDirBase (const string& dir, const string& basename) {
// Don't return ./{filename} because if filename was absolute, that makes it relative
if (dir == ".") return basename;
else return dir+"/"+basename;
}
string V3Options::filenameDir (const string& filename) {
string::size_type pos;
if ((pos = filename.rfind("/")) != string::npos) {
return filename.substr(0,pos);
} else {
return ".";
}
}
string V3Options::filenameNonDir (const string& filename) {
string::size_type pos;
if ((pos = filename.rfind("/")) != string::npos) {
return filename.substr(pos+1);
} else {
return filename;
}
}
string V3Options::filenameNonExt (const string& filename) {
string base = filenameNonDir(filename);
string::size_type pos;
if ((pos = base.find(".")) != string::npos) {
base.erase(pos);
}
return base;
}
string V3Options::filenameSubstitute (const string& filename) {
string out;
enum { NONE, PAREN, CURLY } brackets = NONE;
for (string::size_type pos = 0; pos < filename.length(); ++pos) {
if ((filename[pos] == '$') && (pos+1 < filename.length())) {
switch (filename[pos+1]) {
case '{': brackets = CURLY; break;
case '(': brackets = PAREN; break;
default: brackets = NONE; break;
}
if (brackets != NONE) pos = pos+1;
string::size_type endpos = pos+1;
while (((endpos+1) < filename.length()) &&
(((brackets==NONE) && (isalnum(filename[endpos+1]) || filename[endpos+1]=='_')) ||
((brackets==CURLY) && (filename[endpos+1]!='}')) ||
((brackets==PAREN) && (filename[endpos+1]!=')'))))
++endpos;
// Catch bracket errors
if (((brackets==CURLY) && (filename[endpos+1]!='}')) ||
((brackets==PAREN) && (filename[endpos+1]!=')'))) {
v3fatal("Unmatched brackets in variable substitution in file: "+filename);
}
string envvar = filename.substr(pos+1,endpos-pos);
const char* envvalue = NULL;
if (envvar != "") envvalue = getenv(envvar.c_str());
if (envvalue) {
out += envvalue;
if (brackets==NONE) pos = endpos;
else pos = endpos+1;
} else {
out += filename[pos]; // *pos == '$'
}
} else {
out += filename[pos];
}
}
return out;
}
bool V3Options::filenameIsRel(const string& filename) {
return (filename.length()>0 && filename[0] != '/');
}
bool V3Options::fileStatDir(const string& filename) {
struct stat sstat; // Stat information
int err = stat(filename.c_str(), &sstat);
@@ -306,8 +245,8 @@ string V3Options::fileExists (const string& filename) {
// is quite slow; presumably because of re-reading each directory
// many times. So we read a whole dir at once and cache it
string dir = filenameDir(filename);
string basename = filenameNonDir(filename);
string dir = V3Os::filenameDir(filename);
string basename = V3Os::filenameNonDir(filename);
V3OptionsImp::DirMap::iterator diriter = m_impp->m_dirMap.find(dir);
if (diriter == m_impp->m_dirMap.end()) {
@@ -332,14 +271,14 @@ string V3Options::fileExists (const string& filename) {
return ""; // Not found
}
// Check if it is a directory, ignore if so
string filenameOut = filenameFromDirBase (dir, basename);
string filenameOut = V3Os::filenameFromDirBase (dir, basename);
if (!fileStatNormal(filenameOut)) return ""; // Directory
return filenameOut;
}
string V3Options::filePathCheckOneDir(const string& modname, const string& dirname) {
for (list<string>::iterator extIter=m_impp->m_libExtVs.begin(); extIter!=m_impp->m_libExtVs.end(); ++extIter) {
string fn = filenameFromDirBase(dirname, modname+*extIter);
string fn = V3Os::filenameFromDirBase(dirname, modname+*extIter);
string exists = fileExists(fn);
if (exists!="") {
// Strip ./, it just looks ugly
@@ -385,14 +324,14 @@ void V3Options::filePathLookedMsg(FileLine* fl, const string& modname) {
for (list<string>::iterator dirIter=m_impp->m_incDirUsers.begin();
dirIter!=m_impp->m_incDirUsers.end(); ++dirIter) {
for (list<string>::iterator extIter=m_impp->m_libExtVs.begin(); extIter!=m_impp->m_libExtVs.end(); ++extIter) {
string fn = filenameFromDirBase(*dirIter,modname+*extIter);
string fn = V3Os::filenameFromDirBase(*dirIter,modname+*extIter);
fl->v3error(" "<<fn<<endl);
}
}
for (list<string>::iterator dirIter=m_impp->m_incDirFallbacks.begin();
dirIter!=m_impp->m_incDirFallbacks.end(); ++dirIter) {
for (list<string>::iterator extIter=m_impp->m_libExtVs.begin(); extIter!=m_impp->m_libExtVs.end(); ++extIter) {
string fn = filenameFromDirBase(*dirIter,modname+*extIter);
string fn = V3Os::filenameFromDirBase(*dirIter,modname+*extIter);
fl->v3error(" "<<fn<<endl);
}
}
@@ -404,7 +343,7 @@ void V3Options::filePathLookedMsg(FileLine* fl, const string& modname) {
//! If we recognize the extension, use its language, otherwise, use the
//! default language.
V3LangCode V3Options::fileLanguage(const string &filename) {
string ext = filenameNonDir(filename);
string ext = V3Os::filenameNonDir(filename);
string::size_type pos;
if ((pos = ext.rfind(".")) != string::npos) {
ext.erase(0, pos + 1);
@@ -417,63 +356,27 @@ V3LangCode V3Options::fileLanguage(const string &filename) {
}
void V3Options::unlinkRegexp(const string& dir, const string& regexp) {
if (DIR* dirp = opendir(dir.c_str())) {
while (struct dirent* direntp = readdir(dirp)) {
if (VString::wildmatch(direntp->d_name, regexp.c_str())) {
string fullname = dir + "/" + string(direntp->d_name);
unlink (fullname.c_str());
}
}
closedir(dirp);
}
}
//######################################################################
// Environment
string V3Options::getenvStr(const string& envvar, const string& defaultValue) {
if (const char* envvalue = getenv(envvar.c_str())) {
return envvalue;
} else {
return defaultValue;
}
}
void V3Options::setenvStr(const string& envvar, const string& value, const string& why) {
if (why != "") {
UINFO(1,"export "<<envvar<<"="<<value<<" # "<<why<<endl);
} else {
UINFO(1,"export "<<envvar<<"="<<value<<endl);
}
#if defined(_BSD_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)
setenv(envvar.c_str(),value.c_str(),true);
#else
//setenv() replaced by putenv() in MinGW/Solaris environment. Prototype is different
//putenv() requires NAME=VALUE format
string vareq = envvar + "=" + value;
putenv(const_cast<char*>(vareq.c_str()));
#endif
}
string V3Options::getenvPERL() {
return getenvStr("PERL","perl");
return V3Os::getenvStr("PERL","perl");
}
string V3Options::getenvSYSTEMC() {
string var = getenvStr("SYSTEMC","");
string var = V3Os::getenvStr("SYSTEMC","");
if (var == "" && string(DEFENV_SYSTEMC) != "") {
var = DEFENV_SYSTEMC;
setenvStr("SYSTEMC", var, "Hardcoded at build time");
V3Os::setenvStr("SYSTEMC", var, "Hardcoded at build time");
}
return var;
}
string V3Options::getenvSYSTEMC_ARCH() {
string var = getenvStr("SYSTEMC_ARCH","");
string var = V3Os::getenvStr("SYSTEMC_ARCH","");
if (var == "" && string(DEFENV_SYSTEMC_ARCH) != "") {
var = DEFENV_SYSTEMC_ARCH;
setenvStr("SYSTEMC_ARCH", var, "Hardcoded at build time");
V3Os::setenvStr("SYSTEMC_ARCH", var, "Hardcoded at build time");
}
if (var == "") {
#if defined (__MINGW32__)
@@ -491,16 +394,16 @@ string V3Options::getenvSYSTEMC_ARCH() {
else if (VString::wildmatch(sysname.c_str(), "*cygwin*")) { var ="cygwin"; }
else { var = "linux"; }
#endif
setenvStr("SYSTEMC_ARCH", var,"From sysname '"+sysname+"'");
V3Os::setenvStr("SYSTEMC_ARCH", var,"From sysname '"+sysname+"'");
}
return var;
}
string V3Options::getenvSYSTEMC_INCLUDE() {
string var = getenvStr("SYSTEMC_INCLUDE","");
string var = V3Os::getenvStr("SYSTEMC_INCLUDE","");
if (var == "" && string(DEFENV_SYSTEMC_INCLUDE) != "") {
var = DEFENV_SYSTEMC_INCLUDE;
setenvStr("SYSTEMC_INCLUDE", var, "Hardcoded at build time");
V3Os::setenvStr("SYSTEMC_INCLUDE", var, "Hardcoded at build time");
}
if (var == "") {
string sc = getenvSYSTEMC();
@@ -517,10 +420,10 @@ string V3Options::getenvSYSTEMC_INCLUDE() {
}
string V3Options::getenvSYSTEMC_LIBDIR() {
string var = getenvStr("SYSTEMC_LIBDIR","");
string var = V3Os::getenvStr("SYSTEMC_LIBDIR","");
if (var == "" && string(DEFENV_SYSTEMC_LIBDIR) != "") {
var = DEFENV_SYSTEMC_LIBDIR;
setenvStr("SYSTEMC_LIBDIR", var, "Hardcoded at build time");
V3Os::setenvStr("SYSTEMC_LIBDIR", var, "Hardcoded at build time");
}
if (var == "") {
string sc = getenvSYSTEMC();
@@ -546,26 +449,26 @@ string V3Options::getenvSYSTEMPERL() {
string V3Options::getenvSYSTEMPERLGuts() {
// Get SYSTEMPERL when SYSTEMPERL_INCLUDE has already been tested
string var = getenvStr("SYSTEMPERL","");
string var = V3Os::getenvStr("SYSTEMPERL","");
if (var == "" && string(DEFENV_SYSTEMPERL) != "") {
var = DEFENV_SYSTEMPERL;
setenvStr("SYSTEMPERL", var, "Hardcoded at build time");
V3Os::setenvStr("SYSTEMPERL", var, "Hardcoded at build time");
}
return var;
}
string V3Options::getenvSYSTEMPERL_INCLUDE() {
string var = getenvStr("SYSTEMPERL_INCLUDE","");
string var = V3Os::getenvStr("SYSTEMPERL_INCLUDE","");
if (var == "") {
string sp_src = V3Options::getenvSYSTEMPERLGuts()+"/src";
if (V3Options::fileStatNormal(sp_src+"/systemperl.h")) {
var = sp_src;
setenvStr ("SYSTEMPERL_INCLUDE", var, "From $SYSTEMPERL/src");
V3Os::setenvStr ("SYSTEMPERL_INCLUDE", var, "From $SYSTEMPERL/src");
} else if (string(DEFENV_SYSTEMPERL_INCLUDE) != "") {
// Note if SYSTEMPERL is DEFENVed, then SYSTEMPERL_INCLUDE is also DEFENVed
// So we don't need to sweat testing DEFENV_SYSTEMPERL also
var = DEFENV_SYSTEMPERL_INCLUDE;
setenvStr("SYSTEMPERL_INCLUDE", var, "Hardcoded at build time");
V3Os::setenvStr("SYSTEMPERL_INCLUDE", var, "Hardcoded at build time");
}
}
// Only correct or check it if we really need the value
@@ -584,10 +487,10 @@ string V3Options::getenvSYSTEMPERL_INCLUDE() {
}
string V3Options::getenvVERILATOR_ROOT() {
string var = getenvStr("VERILATOR_ROOT","");
string var = V3Os::getenvStr("VERILATOR_ROOT","");
if (var == "" && string(DEFENV_VERILATOR_ROOT) != "") {
var = DEFENV_VERILATOR_ROOT;
setenvStr("VERILATOR_ROOT", var, "Hardcoded at build time");
V3Os::setenvStr("VERILATOR_ROOT", var, "Hardcoded at build time");
}
if (var == "") {
v3fatal("$VERILATOR_ROOT needs to be in environment\n");
@@ -639,7 +542,7 @@ void V3Options::parseOpts (FileLine* fl, int argc, char** argv) {
// Default prefix to the filename
if (prefix()=="" && topModule()!="") m_prefix = string("V")+topModule();
if (prefix()=="" && vFilesList.size()>=1) m_prefix = string("V")+filenameNonExt(*(vFilesList.begin()));
if (prefix()=="" && vFilesList.size()>=1) m_prefix = string("V")+V3Os::filenameNonExt(*(vFilesList.begin()));
if (modPrefix()=="") m_modPrefix = prefix();
// Find files in makedir
@@ -831,6 +734,11 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
shift;
m_dumpTree = atoi(argv[i]);
}
else if ( !strncmp (sw, "-dump-treei-", strlen("-dump-treei-"))) {
const char* src = sw+strlen("-dump-treei-");
shift;
setDumpTreeLevel(src, atoi(argv[i]));
}
else if ( !strcmp (sw, "-error-limit") && (i+1)<argc ) {
shift;
V3Error::errorLimit(atoi(argv[i]));
@@ -910,6 +818,14 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
shift;
V3Options::addLibraryFile(parseFileArg(optdir,argv[i]));
}
else if ( !strcmp (sw, "-clk") && (i+1)<argc ) {
shift;
V3Options::addClocker(argv[i]);
}
else if ( !strcmp (sw, "-no-clk") && (i+1)<argc ) {
shift;
V3Options::addNoClocker(argv[i]);
}
else if ( !strcmp (sw, "-V") ) {
showVersion(true);
exit(0);
@@ -1126,7 +1042,7 @@ void V3Options::parseOptsFile(FileLine* fl, const string& filename, bool rel) {
}
// Path
string optdir = (rel ? V3Options::filenameDir(filename) : ".");
string optdir = (rel ? V3Os::filenameDir(filename) : ".");
// Convert to argv style arg list and parse them
char* argv [args.size()+1];
@@ -1139,8 +1055,8 @@ void V3Options::parseOptsFile(FileLine* fl, const string& filename, bool rel) {
//======================================================================
string V3Options::parseFileArg(const string& optdir, const string& relfilename) {
string filename = V3Options::filenameSubstitute(relfilename);
if (optdir != "." && filenameIsRel(filename)) {
string filename = V3Os::filenameSubstitute(relfilename);
if (optdir != "." && V3Os::filenameIsRel(filename)) {
filename = optdir + "/" + filename;
}
return filename;
@@ -1190,15 +1106,15 @@ void V3Options::showVersion(bool verbose) {
cout <<endl;
cout << "Environment:\n";
cout << " PERL = " << getenvStr("PERL","")<<endl;
cout << " SYSTEMC = " << getenvStr("SYSTEMC","")<<endl;
cout << " SYSTEMC_ARCH = " << getenvStr("SYSTEMC_ARCH","")<<endl;
cout << " SYSTEMC_INCLUDE = " << getenvStr("SYSTEMC_INCLUDE","")<<endl;
cout << " SYSTEMC_LIBDIR = " << getenvStr("SYSTEMC_LIBDIR","")<<endl;
cout << " SYSTEMPERL = " << getenvStr("SYSTEMPERL","")<<endl;
cout << " SYSTEMPERL_INCLUDE = " << getenvStr("SYSTEMPERL_INCLUDE","")<<endl;
cout << " VERILATOR_ROOT = " << getenvStr("VERILATOR_ROOT","")<<endl;
cout << " VERILATOR_BIN = " << getenvStr("VERILATOR_BIN","")<<endl; // wrapper uses this
cout << " PERL = " << V3Os::getenvStr("PERL","")<<endl;
cout << " SYSTEMC = " << V3Os::getenvStr("SYSTEMC","")<<endl;
cout << " SYSTEMC_ARCH = " << V3Os::getenvStr("SYSTEMC_ARCH","")<<endl;
cout << " SYSTEMC_INCLUDE = " << V3Os::getenvStr("SYSTEMC_INCLUDE","")<<endl;
cout << " SYSTEMC_LIBDIR = " << V3Os::getenvStr("SYSTEMC_LIBDIR","")<<endl;
cout << " SYSTEMPERL = " << V3Os::getenvStr("SYSTEMPERL","")<<endl;
cout << " SYSTEMPERL_INCLUDE = " << V3Os::getenvStr("SYSTEMPERL_INCLUDE","")<<endl;
cout << " VERILATOR_ROOT = " << V3Os::getenvStr("VERILATOR_ROOT","")<<endl;
cout << " VERILATOR_BIN = " << V3Os::getenvStr("VERILATOR_BIN","")<<endl; // wrapper uses this
}
//======================================================================
@@ -1288,7 +1204,7 @@ V3Options::~V3Options() {
void V3Options::setDebugMode(int level) {
V3Error::debugDefault(level);
if (!m_dumpTree) m_dumpTree = true; // Don't override if already set.
if (!m_dumpTree) m_dumpTree = 3; // Don't override if already set.
m_stats = true;
m_debugCheck = true;
cout << "Starting "<<version()<<endl;
@@ -1306,7 +1222,7 @@ void V3Options::setDebugSrcLevel(const string& srcfile, int level) {
int V3Options::debugSrcLevel(const string& srcfile_path, int default_level) {
// For simplicity, calling functions can just use __FILE__ for srcfile.
// That means though we need to cleanup the filename from ../Foo.cpp -> Foo
string srcfile = V3Options::filenameNonDirExt(srcfile_path);
string srcfile = V3Os::filenameNonDirExt(srcfile_path);
DebugSrcMap::iterator iter = m_debugSrcs.find(srcfile);
if (iter!=m_debugSrcs.end()) {
return iter->second;
@@ -1315,6 +1231,27 @@ int V3Options::debugSrcLevel(const string& srcfile_path, int default_level) {
}
}
void V3Options::setDumpTreeLevel(const string& srcfile, int level) {
DebugSrcMap::iterator iter = m_dumpTrees.find(srcfile);
if (iter!=m_dumpTrees.end()) {
iter->second = level;
} else {
m_dumpTrees.insert(make_pair(srcfile,level));
}
}
int V3Options::dumpTreeLevel(const string& srcfile_path) {
// For simplicity, calling functions can just use __FILE__ for srcfile.
// That means though we need to cleanup the filename from ../Foo.cpp -> Foo
string srcfile = V3Os::filenameNonDirExt(srcfile_path);
DebugSrcMap::iterator iter = m_dumpTrees.find(srcfile);
if (iter!=m_dumpTrees.end()) {
return iter->second;
} else {
return m_dumpTree;
}
}
void V3Options::optimize(int level) {
// Set all optimizations to on/off
bool flag = level > 0;
+9 -12
View File
@@ -53,8 +53,11 @@ class V3Options {
V3StringSet m_ldLibs; // argument: user LDFLAGS
V3StringSet m_futures; // argument: -Wfuture- list
V3StringSet m_libraryFiles; // argument: Verilog -v files
V3StringSet m_clockers; // argument: Verilog -clk signals
V3StringSet m_noClockers; // argument: Verilog -noclk signals
V3StringList m_vFiles; // argument: Verilog files to read
DebugSrcMap m_debugSrcs; // argument: --debugi-<srcfile>=<level>
DebugSrcMap m_dumpTrees; // argument: --dump-treei-<srcfile>=<level>
bool m_preprocOnly; // main switch: -E
bool m_makeDepend; // main switch: -MMD
@@ -169,8 +172,6 @@ class V3Options {
bool parseLangExt(const char* swp, const char* langswp, const V3LangCode& lc);
string filePathCheckOneDir(const string& modname, const string& dirname);
static string getenvStr(const string& envvar, const string& defaultValue);
static void setenvStr(const string& envvar, const string& value, const string& why);
static string getenvSYSTEMPERLGuts();
public:
@@ -180,12 +181,16 @@ class V3Options {
void setDebugMode(int level);
void setDebugSrcLevel(const string& srcfile, int level);
int debugSrcLevel(const string& srcfile, int default_level=V3Error::debugDefault());
void setDumpTreeLevel(const string& srcfile, int level);
int dumpTreeLevel(const string& srcfile);
// METHODS
void addCppFile(const string& filename);
void addCFlags(const string& filename);
void addLdLibs(const string& filename);
void addLibraryFile(const string& filename);
void addClocker(const string& signame);
void addNoClocker(const string& signame);
void addVFile(const string& filename);
// ACCESSORS (options)
@@ -272,6 +277,8 @@ class V3Options {
bool isFuture(const string& flag) const;
bool isLibraryFile(const string& filename) const;
bool isClocker(const string& signame) const;
bool isNoClocker(const string& signame) const;
// ACCESSORS (optimization options)
bool oAcycSimp() const { return m_oAcycSimp; }
@@ -306,16 +313,6 @@ class V3Options {
void parseOptsList (FileLine* fl, const string& optdir, int argc, char** argv);
void parseOptsFile (FileLine* fl, const string& filename, bool rel);
// METHODS (generic file utilities)
static string filenameFromDirBase (const string& dir, const string& basename);
static string filenameNonDir (const string& filename); ///< Return non-directory part of filename
static string filenameNonExt (const string& filename); ///< Return non-extensioned (no .) part of filename
static string filenameNonDirExt (const string& filename) { return filenameNonExt(filenameNonDir(filename)); } ///< Return basename of filename
static string filenameDir (const string& filename); ///< Return directory part of filename
static string filenameSubstitute (const string& filename); ///< Return filename with env vars removed
static bool filenameIsRel (const string& filename); ///< True if relative
static void unlinkRegexp(const string& dir, const string& regexp);
// METHODS (environment)
// Most of these may be built into the executable with --enable-defenv,
// see the README. If adding new variables, also see src/Makefile_obj.in
+211 -1
View File
@@ -241,6 +241,185 @@ struct OrderVarFanoutCmp {
}
};
//######################################################################
// The class is used for propagating the clocker attribute for further
// avoiding marking clock signals as circular.
// Transformation:
// while (newClockerMarked)
// check all assignments
// if RHS is marked as clocker:
// mark LHS as clocker as well.
// newClockerMarked = true;
//
// In addition it also check whether clock and data signals are mixed, and
// produce a CLKDATA warning if so.
//
class OrderClkMarkVisitor : public AstNVisitor {
private:
bool m_hasClk; // flag indicating whether there is clock signal on rhs
bool m_inClocked; // Currently inside a sequential block
bool m_newClkMarked; // Flag for deciding whether a new run is needed
bool m_inAss; // Currently inside of a assignment
int m_childClkWidth; // If in hasClk, width of clock signal in child
int m_rightClkWidth; // Clk width on the RHS
// METHODS
static int debug() {
static int level = -1;
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
return level;
}
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
m_hasClk = false;
if (AstVarRef* varrefp = nodep->rhsp()->castVarRef()) {
this->visit(varrefp, NULL);
m_rightClkWidth = varrefp->width();
if (varrefp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) {
if (m_inClocked) {
varrefp->v3warn(CLKDATA, "Clock used as data (on rhs of assignment) in sequential block "<<varrefp<<endl);
} else {
m_hasClk = true;
UINFO(5, "node is already marked as clocker "<<varrefp<<endl);
}
}
} else {
m_inAss = true;
m_childClkWidth = 0;
nodep->rhsp()->iterateAndNext(*this);
m_rightClkWidth = m_childClkWidth;
m_inAss = false;
}
// do the marking
if (m_hasClk) {
if (nodep->lhsp()->width() > m_rightClkWidth) {
nodep->v3warn(CLKDATA, "Clock is assigned to part of data signal "<< nodep->lhsp()<<endl);
UINFO(4, "CLKDATA: lhs with width " << nodep->lhsp()->width() <<endl);
UINFO(4, " but rhs clock with width " << m_rightClkWidth <<endl);
return; // skip the marking
}
AstVarRef* lhsp = nodep->lhsp()->castVarRef();
if (lhsp && (lhsp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_UNKNOWN)) {
lhsp->varp()->attrClocker(AstVarAttrClocker::CLOCKER_YES); // mark as clocker
m_newClkMarked = true; // enable a further run since new clocker is marked
UINFO(5, "node is newly marked as clocker by assignment "<<lhsp<<endl);
}
}
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (m_inAss && nodep->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) {
if (m_inClocked) {
nodep->v3warn(CLKDATA, "Clock used as data (on rhs of assignment) in sequential block "<<nodep->prettyName());
} else {
m_hasClk = true;
m_childClkWidth = nodep->width(); // Pass up
UINFO(5, "node is already marked as clocker "<<nodep<<endl);
}
}
}
virtual void visit(AstConcat* nodep, AstNUser* wp) {
if (m_inAss) {
nodep->lhsp()->iterateAndNext(*this);
int lw = m_childClkWidth;
nodep->rhsp()->iterateAndNext(*this);
int rw = m_childClkWidth;
m_childClkWidth = lw + rw; // Pass up
}
}
virtual void visit(AstNodeSel* nodep, AstNUser* wp) {
if (m_inAss) {
nodep->iterateChildren(*this);
// Pass up result width
if (m_childClkWidth > nodep->width()) m_childClkWidth = nodep->width();
}
}
virtual void visit(AstSel* nodep, AstNUser*) {
if (m_inAss) {
nodep->iterateChildren(*this);
if (m_childClkWidth > nodep->width()) m_childClkWidth = nodep->width();
}
}
virtual void visit(AstReplicate* nodep, AstNUser*) {
if (m_inAss) {
nodep->iterateChildren(*this);
if (nodep->rhsp()->castConst()) {
m_childClkWidth = m_childClkWidth * nodep->rhsp()->castConst()->toUInt();
} else {
m_childClkWidth = nodep->width(); // can not check in this case.
}
}
}
virtual void visit(AstActive* nodep, AstNUser*) {
m_inClocked = nodep->hasClocked();
nodep->iterateChildren(*this);
m_inClocked = false;
}
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
public:
// CONSTUCTORS
OrderClkMarkVisitor(AstNode* nodep) {
m_hasClk = false;
m_inClocked = false;
m_inAss = false;
m_childClkWidth = 0;
m_rightClkWidth = 0;
do {
m_newClkMarked = false;
nodep->accept(*this);
} while (m_newClkMarked);
}
virtual ~OrderClkMarkVisitor() {}
};
//######################################################################
// The class used to check if the assignment has clocker inside.
class OrderClkAssVisitor : public AstNVisitor {
private:
bool m_clkAss; // There is signals marked as clocker in the assignment
// METHODS
static int debug() {
static int level = -1;
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
return level;
}
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
if (AstVarRef* varrefp = nodep->lhsp()->castVarRef() )
if (varrefp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) {
m_clkAss = true;
UINFO(6, "node was marked as clocker "<<varrefp<<endl);
}
nodep->rhsp()->iterateChildren(*this);
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (nodep->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) {
m_clkAss = true;
UINFO(6, "node was marked as clocker "<<nodep<<endl);
}
}
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
public:
// CONSTUCTORS
OrderClkAssVisitor(AstNode* nodep) {
m_clkAss = false;
nodep->accept(*this);
}
virtual ~OrderClkAssVisitor() {}
// METHODS
bool isClkAss() {return m_clkAss;}
};
//######################################################################
// Order class functions
@@ -280,6 +459,7 @@ private:
AstActive* m_activep; // Current activation block
bool m_inSenTree; // Underneath AstSenItem; any varrefs are clocks
bool m_inClocked; // Underneath clocked block
bool m_inClkAss; // Underneath AstAssign
bool m_inPre; // Underneath AstAssignPre
bool m_inPost; // Underneath AstAssignPost
OrderLogicVertex* m_activeSenVxp; // Sensitivity vertex
@@ -356,6 +536,15 @@ private:
return NULL;
}
bool isClkAssign(AstNodeAssign* nodep) {
if (AstVarRef* varrefp = nodep->lhsp()->castVarRef()) {
if (varrefp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) {
return true;
}
}
return false;
}
void process();
void processCircular();
typedef deque<OrderEitherVertex*> VertexVec;
@@ -650,6 +839,10 @@ private:
// clock_enable attribute: user's worring about it for us
con = false;
}
if (m_inClkAss && (varscp->varp()->attrClocker()) != AstVarAttrClocker::CLOCKER_YES) {
con = false;
UINFO(4, "nodep used as clock_enable "<<varscp<<" in "<<m_logicVxp->nodep()<<endl);
}
}
if (gen) varscp->user4(varscp->user4() | VU_GEN);
if (con) varscp->user4(varscp->user4() | VU_CON);
@@ -672,7 +865,12 @@ private:
<< varVxp << endl);
varVxp->isDelayed(true);
} else {
new OrderComboCutEdge(&m_graph, m_logicVxp, varVxp);
// If the lhs is a clocker, avoid marking that as circular by
// putting a hard edge instead of normal cuttable
if (varscp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES)
new OrderEdge(&m_graph, m_logicVxp, varVxp, WEIGHT_NORMAL);
else
new OrderComboCutEdge(&m_graph, m_logicVxp, varVxp);
}
// For m_inPost:
// Add edge consumed_var_POST->logic_vertex
@@ -758,17 +956,26 @@ private:
iterateNewStmt(nodep);
}
virtual void visit(AstAssignW* nodep, AstNUser*) {
OrderClkAssVisitor visitor(nodep);
m_inClkAss = visitor.isClkAss();
iterateNewStmt(nodep);
m_inClkAss = false;
}
virtual void visit(AstAssignPre* nodep, AstNUser*) {
OrderClkAssVisitor visitor(nodep);
m_inClkAss = visitor.isClkAss();
m_inPre = true;
iterateNewStmt(nodep);
m_inPre = false;
m_inClkAss = false;
}
virtual void visit(AstAssignPost* nodep, AstNUser*) {
OrderClkAssVisitor visitor(nodep);
m_inClkAss = visitor.isClkAss();
m_inPost = true;
iterateNewStmt(nodep);
m_inPost = false;
m_inClkAss = false;
}
virtual void visit(AstCoverToggle* nodep, AstNUser*) {
iterateNewStmt(nodep);
@@ -799,6 +1006,7 @@ public:
m_activep = NULL;
m_inSenTree = false;
m_inClocked = false;
m_inClkAss = false;
m_inPre = m_inPost = false;
m_comboDomainp = NULL;
m_deleteDomainp = NULL;
@@ -1449,6 +1657,8 @@ void OrderVisitor::process() {
void V3Order::orderAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
OrderClkMarkVisitor markVisitor(nodep);
OrderVisitor visitor;
visitor.main(nodep);
V3Global::dumpCheckGlobalTree("order.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+169
View File
@@ -0,0 +1,169 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Os-specific function wrapper
//
// Code available from: http://www.veripool.org/verilator
//
//*************************************************************************
//
// Copyright 2003-2015 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.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
#include "config_build.h"
#include "verilatedos.h"
#include <cstdarg>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <cerrno>
#include <fcntl.h>
#include <iomanip>
#include <memory>
#if defined(WIN32) || defined(__MINGW32__)
# include <direct.h> // mkdir
#endif
#include "V3Global.h"
#include "V3String.h"
#include "V3Os.h"
//######################################################################
// Environment
string V3Os::getenvStr(const string& envvar, const string& defaultValue) {
if (const char* envvalue = getenv(envvar.c_str())) {
return envvalue;
} else {
return defaultValue;
}
}
void V3Os::setenvStr(const string& envvar, const string& value, const string& why) {
if (why != "") {
UINFO(1,"export "<<envvar<<"="<<value<<" # "<<why<<endl);
} else {
UINFO(1,"export "<<envvar<<"="<<value<<endl);
}
#if defined(_BSD_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)
setenv(envvar.c_str(),value.c_str(),true);
#else
//setenv() replaced by putenv() in MinGW/Solaris environment. Prototype is different
//putenv() requires NAME=VALUE format
string vareq = envvar + "=" + value;
putenv(const_cast<char*>(vareq.c_str()));
#endif
}
//######################################################################
// Generic filename utilities
string V3Os::filenameFromDirBase (const string& dir, const string& basename) {
// Don't return ./{filename} because if filename was absolute, that makes it relative
if (dir == ".") return basename;
else return dir+"/"+basename;
}
string V3Os::filenameDir (const string& filename) {
string::size_type pos;
if ((pos = filename.rfind("/")) != string::npos) {
return filename.substr(0,pos);
} else {
return ".";
}
}
string V3Os::filenameNonDir (const string& filename) {
string::size_type pos;
if ((pos = filename.rfind("/")) != string::npos) {
return filename.substr(pos+1);
} else {
return filename;
}
}
string V3Os::filenameNonExt (const string& filename) {
string base = filenameNonDir(filename);
string::size_type pos;
if ((pos = base.find(".")) != string::npos) {
base.erase(pos);
}
return base;
}
string V3Os::filenameSubstitute (const string& filename) {
string out;
enum { NONE, PAREN, CURLY } brackets = NONE;
for (string::size_type pos = 0; pos < filename.length(); ++pos) {
if ((filename[pos] == '$') && (pos+1 < filename.length())) {
switch (filename[pos+1]) {
case '{': brackets = CURLY; break;
case '(': brackets = PAREN; break;
default: brackets = NONE; break;
}
if (brackets != NONE) pos = pos+1;
string::size_type endpos = pos+1;
while (((endpos+1) < filename.length()) &&
(((brackets==NONE) && (isalnum(filename[endpos+1]) || filename[endpos+1]=='_')) ||
((brackets==CURLY) && (filename[endpos+1]!='}')) ||
((brackets==PAREN) && (filename[endpos+1]!=')'))))
++endpos;
// Catch bracket errors
if (((brackets==CURLY) && (filename[endpos+1]!='}')) ||
((brackets==PAREN) && (filename[endpos+1]!=')'))) {
v3fatal("Unmatched brackets in variable substitution in file: "+filename);
}
string envvar = filename.substr(pos+1,endpos-pos);
const char* envvalue = NULL;
if (envvar != "") envvalue = getenv(envvar.c_str());
if (envvalue) {
out += envvalue;
if (brackets==NONE) pos = endpos;
else pos = endpos+1;
} else {
out += filename[pos]; // *pos == '$'
}
} else {
out += filename[pos];
}
}
return out;
}
bool V3Os::filenameIsRel(const string& filename) {
return (filename.length()>0 && filename[0] != '/');
}
//######################################################################
// Directory utilities
void V3Os::createDir(const string& dirname) {
#if defined(_WIN32) || defined(__MINGW32__)
mkdir(dirname.c_str());
#else
mkdir(dirname.c_str(), 0777);
#endif
}
void V3Os::unlinkRegexp(const string& dir, const string& regexp) {
if (DIR* dirp = opendir(dir.c_str())) {
while (struct dirent* direntp = readdir(dirp)) {
if (VString::wildmatch(direntp->d_name, regexp.c_str())) {
string fullname = dir + "/" + string(direntp->d_name);
unlink (fullname.c_str());
}
}
closedir(dirp);
}
}
+51
View File
@@ -0,0 +1,51 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Os-specific function wrapper
//
// Code available from: http://www.veripool.org/verilator
//
//*************************************************************************
//
// Copyright 2003-2015 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.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
#ifndef _V3OS_H_
#define _V3OS_H_ 1
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include <cstdio>
//============================================================================
// V3Os: OS static class
class V3Os {
public:
// METHODS (environment)
static string getenvStr(const string& envvar, const string& defaultValue);
static void setenvStr(const string& envvar, const string& value, const string& why);
// METHODS (generic filename utilities)
static string filenameFromDirBase (const string& dir, const string& basename);
static string filenameNonDir (const string& filename); ///< Return non-directory part of filename
static string filenameNonExt (const string& filename); ///< Return non-extensioned (no .) part of filename
static string filenameNonDirExt (const string& filename) { return filenameNonExt(filenameNonDir(filename)); } ///< Return basename of filename
static string filenameDir (const string& filename); ///< Return directory part of filename
static string filenameSubstitute (const string& filename); ///< Return filename with env vars removed
static bool filenameIsRel (const string& filename); ///< True if relative
// METHODS (directory utilities)
static void createDir(const string& dirname);
static void unlinkRegexp(const string& dir, const string& regexp);
};
#endif // Guard
+1
View File
@@ -570,4 +570,5 @@ void ParamVisitor::visitCell(AstCell* nodep) {
void V3Param::param(AstNetlist* rootp) {
UINFO(2,__FUNCTION__<<": "<<endl);
ParamVisitor visitor (rootp);
V3Global::dumpCheckGlobalTree("param.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+2 -1
View File
@@ -36,6 +36,7 @@
#include "V3Error.h"
#include "V3Global.h"
#include "V3Os.h"
#include "V3Ast.h"
#include "V3File.h"
#include "V3ParseImp.h"
@@ -91,7 +92,7 @@ size_t V3ParseImp::ppInputToLex(char* buf, size_t max_size) {
void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool inLibrary,
const string& errmsg) { // "" for no error, make fake node
string modname = V3Options::filenameNonExt(modfilename);
string modname = V3Os::filenameNonExt(modfilename);
UINFO(2,__FUNCTION__<<": "<<modname<<(inLibrary?" [LIB]":"")<<endl);
m_fileline = new FileLine(fileline);
-2
View File
@@ -4,8 +4,6 @@
//
// Code available from: http://www.veripool.org/verilator
//
// Authors: Wilson Snyder
//
//*************************************************************************
//
// Copyright 2000-2015 by Wilson Snyder. This program is free software;
+3 -3
View File
@@ -124,16 +124,16 @@ drop [\032]
/* Protected blocks */
<INITIAL>"`protected" { yy_push_state(PRTMODE); yymore(); }
<PRTMODE><<EOF>> { linenoInc(); yyerrorf("EOF in `protected"); yyleng=0; yyterminate(); }
<PRTMODE>{crnl} { linenoInc(); yymore(); }
<PRTMODE>{crnl} { linenoInc(); return VP_TEXT; }
<PRTMODE>. { yymore(); }
<PRTMODE>"`endprotected" { yy_pop_state(); return (VP_TEXT); }
<PRTMODE>"`endprotected" { yy_pop_state(); return VP_TEXT; }
/* Pass-through include <> filenames */
<INCMODE><<EOF>> { linenoInc(); yyerrorf("EOF in unterminated include filename"); yyleng=0; yyterminate(); }
<INCMODE>{crnl} { linenoInc(); yyerrorf("Unterminated include filename"); BEGIN(INITIAL); }
<INCMODE>[^\>\\] { yymore(); }
<INCMODE>{backslash}. { yymore(); }
<INCMODE>[\>] { yy_pop_state(); return (VP_STRING); }
<INCMODE>[\>] { yy_pop_state(); return VP_STRING; }
/* Reading definition formal parenthesis (or not) to begin formal arguments */
/* Note '(' must IMMEDIATELY follow definition name */
-2
View File
@@ -4,8 +4,6 @@
//
// Code available from: http://www.veripool.org/verilator
//
// Authors: Wilson Snyder
//
//*************************************************************************
//
// Copyright 2000-2015 by Wilson Snyder. This program is free software;
-2
View File
@@ -4,8 +4,6 @@
//
// Code available from: http://www.veripool.org/verilator
//
// Authors: Wilson Snyder
//
//*************************************************************************
//
// Copyright 2000-2015 by Wilson Snyder. This program is free software;
+2 -1
View File
@@ -124,7 +124,7 @@ private:
bool assignNoTemp(AstNodeAssign* nodep) {
return (nodep->lhsp()->castVarRef()
&& !nodep->lhsp()->castVarRef()->varp()->isSc()
&& !AstVar::scVarRecurse(nodep->lhsp())
&& nodep->rhsp()->castConst());
}
void checkNode(AstNode* nodep) {
@@ -403,4 +403,5 @@ public:
void V3Premit::premitAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
PremitVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("premit.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+7
View File
@@ -243,6 +243,12 @@ private:
UINFO(6," New scope "<<varscp<<endl);
if (m_aboveCellp && !m_aboveCellp->isTrace()) varscp->trace(false);
nodep->user1p(varscp);
if (v3Global.opt.isClocker(varscp->prettyName())) {
nodep->attrClocker(AstVarAttrClocker::CLOCKER_YES);
}
if (v3Global.opt.isNoClocker(varscp->prettyName())) {
nodep->attrClocker(AstVarAttrClocker::CLOCKER_NO);
}
if (!m_scopep) nodep->v3fatalSrc("No scope for var");
m_varScopes.insert(make_pair(make_pair(nodep, m_scopep), varscp));
m_scopep->addVarp(varscp);
@@ -410,4 +416,5 @@ void V3Scope::scopeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ScopeVisitor visitor (nodep);
ScopeCleanupVisitor cleanVisitor (nodep);
V3Global::dumpCheckGlobalTree("scope.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -501,4 +501,5 @@ public:
void V3Slice::sliceAll(AstNetlist* rootp) {
UINFO(2,__FUNCTION__<<": "<<endl);
SliceVisitor visitor(rootp);
V3Global::dumpCheckGlobalTree("slices.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+2
View File
@@ -578,8 +578,10 @@ public:
void V3Split::splitReorderAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
SplitVisitor visitor (nodep, true);
V3Global::dumpCheckGlobalTree("reorder.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Split::splitAlwaysAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
SplitVisitor visitor (nodep, false);
V3Global::dumpCheckGlobalTree("split.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+1
View File
@@ -216,4 +216,5 @@ public:
void V3SplitAs::splitAsAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
SplitAsVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("splitas.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -401,4 +401,5 @@ public:
void V3Subst::substituteAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
SubstVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("subst.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -466,4 +466,5 @@ void TableSimulateVisitor::varRefCb(AstVarRef* nodep) {
void V3Table::tableAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
TableVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("table.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -1294,4 +1294,5 @@ void V3Task::taskAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
TaskStateVisitor visitors (nodep);
TaskVisitor visitor (nodep, &visitors);
V3Global::dumpCheckGlobalTree("task.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -709,4 +709,5 @@ public:
void V3Trace::traceAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
TraceVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("trace.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -329,4 +329,5 @@ public:
void V3TraceDecl::traceDeclAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
TraceDeclVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("tracedecl.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -1323,4 +1323,5 @@ public:
void V3Tristate::tristateAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
TristateVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("tristate.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -475,4 +475,5 @@ public:
void V3Unknown::unknownAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
UnknownVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("unknown.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1
View File
@@ -463,6 +463,7 @@ public:
void V3Unroll::unrollAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
UnrollVisitor visitor (nodep, false, "");
V3Global::dumpCheckGlobalTree("unroll.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Unroll::unrollGen(AstNodeFor* nodep, string beginName) {
+2
View File
@@ -3483,6 +3483,7 @@ void V3Width::width(AstNetlist* nodep) {
(void)visitor.mainAcceptEdit(nodep);
WidthRemoveVisitor rvisitor;
(void)rvisitor.mainAcceptEdit(nodep);
V3Global::dumpCheckGlobalTree("width.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
//! Single node parameter propagation
@@ -3520,4 +3521,5 @@ AstNode* V3Width::widthGenerateParamsEdit(
void V3Width::widthCommit(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
WidthCommitVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("widthcommit.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+5 -83
View File
@@ -68,6 +68,7 @@
#include "V3Localize.h"
#include "V3Name.h"
#include "V3Order.h"
#include "V3Os.h"
#include "V3Param.h"
#include "V3Parse.h"
#include "V3ParseSym.h"
@@ -148,30 +149,22 @@ void V3Global::dumpCheckGlobalTree(const string& filename, int newNumber, bool d
//######################################################################
void process () {
bool dumpMore = (v3Global.opt.dumpTree() >= 9);
// Sort modules by level so later algorithms don't need to care
V3LinkLevel::modSortByLevel();
V3Global::dumpCheckGlobalTree("cells.tree");
V3Error::abortIfErrors();
// Convert parseref's to varrefs, and other directly post parsing fixups
V3LinkParse::linkParse(v3Global.rootp());
V3Global::dumpCheckGlobalTree("linkparse.tree", 0, dumpMore);
// Cross-link signal names
// Cross-link dotted hierarchical references
V3LinkDot::linkDotPrimary(v3Global.rootp());
V3Global::dumpCheckGlobalTree("linkdot.tree", 0, dumpMore);
v3Global.checkTree(); // Force a check, as link is most likely place for problems
// Correct state we couldn't know at parse time, repair SEL's
V3LinkResolve::linkResolve(v3Global.rootp());
V3Global::dumpCheckGlobalTree("linkresolve.tree", 0, dumpMore);
// Set Lvalue's in variable refs
V3LinkLValue::linkLValue(v3Global.rootp());
V3Global::dumpCheckGlobalTree("linklvalue.tree", 0, dumpMore);
// Convert return/continue/disable to jumps
V3LinkJump::linkJump(v3Global.rootp());
V3Global::dumpCheckGlobalTree("link.tree");
V3Error::abortIfErrors();
if (v3Global.opt.stats()) V3Stats::statsStageAll(v3Global.rootp(), "Link");
@@ -179,19 +172,15 @@ void process () {
// Remove parameters by cloning modules to de-parameterized versions
// This requires some width calculations and constant propagation
V3Param::param(v3Global.rootp());
V3Global::dumpCheckGlobalTree("param.tree", 0, dumpMore);
V3LinkDot::linkDotParamed(v3Global.rootp()); // Cleanup as made new modules
V3Global::dumpCheckGlobalTree("paramlink.tree");
V3Error::abortIfErrors();
// Remove any modules that were parameterized and are no longer referenced.
V3Dead::deadifyModules(v3Global.rootp());
V3Global::dumpCheckGlobalTree("dead.tree", 0, dumpMore);
v3Global.checkTree();
// Calculate and check widths, edit tree to TRUNC/EXTRACT any width mismatches
V3Width::width(v3Global.rootp());
V3Global::dumpCheckGlobalTree("width.tree");
V3Error::abortIfErrors();
@@ -199,19 +188,16 @@ void process () {
V3Width::widthCommit(v3Global.rootp());
v3Global.assertDTypesResolved(true);
v3Global.assertWidthsMatch(true);
V3Global::dumpCheckGlobalTree("widthcommit.tree", 0, dumpMore);
// Coverage insertion
// Before we do dead code elimination and inlining, or we'll lose it.
if (v3Global.opt.coverage()) {
V3Coverage::coverage(v3Global.rootp());
V3Global::dumpCheckGlobalTree("coverage.tree");
}
// Push constants, but only true constants preserving liveness
// so V3Undriven sees variables to be eliminated, ie "if (0 && foo) ..."
V3Const::constifyAllLive(v3Global.rootp());
V3Global::dumpCheckGlobalTree("const.tree");
// Signal based lint checks, no change to structures
// Must be before first constification pass drops dead code
@@ -220,10 +206,8 @@ void process () {
// Assertion insertion
// After we've added block coverage, but before other nasty transforms
V3AssertPre::assertPreAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("assertpre.tree");
//
V3Assert::assertAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("assert.tree");
if (!v3Global.opt.xmlOnly()) {
// Add top level wrapper with instance pointing to old top
@@ -234,39 +218,32 @@ void process () {
// Propagate constants into expressions
V3Const::constifyAllLint(v3Global.rootp());
V3Global::dumpCheckGlobalTree("const.tree");
if (!v3Global.opt.xmlOnly()) {
// Remove cell arrays (must be between V3Width and scoping)
V3Inst::dearrayAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("dearray.tree", 0, dumpMore);
}
if (!v3Global.opt.xmlOnly()) {
// Expand inouts, stage 2
// Also simplify pin connections to always be AssignWs in prep for V3Unknown
V3Tristate::tristateAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("tristate.tree");
// Task inlining & pushing BEGINs names to variables/cells
// Begin processing must be after Param, before module inlining
V3Begin::debeginAll(v3Global.rootp()); // Flatten cell names, before inliner
V3Global::dumpCheckGlobalTree("begin.tree");
// Move assignments from X into MODULE temps.
// (Before flattening, so each new X variable is shared between all scopes of that module.)
V3Unknown::unknownAll(v3Global.rootp());
v3Global.constRemoveXs(true);
V3Global::dumpCheckGlobalTree("unknown.tree");
// Module inlining
// Cannot remove dead variables after this, as alias information for final
// V3Scope's V3LinkDot is in the AstVar.
if (v3Global.opt.oInline()) {
V3Inline::inlineAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("inline.tree");
V3LinkDot::linkDotArrayed(v3Global.rootp()); // Cleanup as made new modules
V3Global::dumpCheckGlobalTree("linkdot.tree", 0, dumpMore);
}
}
@@ -274,11 +251,9 @@ void process () {
// Initial const/dead to reduce work for ordering code
V3Const::constifyAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore);
v3Global.checkTree();
V3Dead::deadifyDTypes(v3Global.rootp());
V3Global::dumpCheckGlobalTree("const.tree");
v3Global.checkTree();
V3Error::abortIfErrors();
@@ -291,17 +266,13 @@ void process () {
// Convert instantiations to wassigns and always blocks
V3Inst::instAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("inst.tree");
// Inst may have made lots of concats; fix them
V3Const::constifyAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("const.tree");
// Flatten hierarchy, creating a SCOPE for each module's usage as a cell
V3Scope::scopeAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("scope.tree");
V3LinkDot::linkDotScope(v3Global.rootp());
V3Global::dumpCheckGlobalTree("linkdot.tree");
}
//--SCOPE BASED OPTIMIZATIONS--------------
@@ -309,87 +280,69 @@ void process () {
if (!v3Global.opt.xmlOnly()) {
// Cleanup
V3Const::constifyAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore);
V3Dead::deadifyDTypes(v3Global.rootp());
v3Global.checkTree();
V3Global::dumpCheckGlobalTree("const.tree");
// Convert case statements to if() blocks. Must be after V3Unknown
// Must be before V3Task so don't need to deal with task in case value compares
V3Case::caseAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("case.tree");
// Inline all tasks
V3Task::taskAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("task.tree");
// Add __PVT's
// After V3Task so task internal variables will get renamed
V3Name::nameAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("name.tree", 0, dumpMore);
// Loop unrolling & convert FORs to WHILEs
V3Unroll::unrollAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("unroll.tree");
// Expand slices of arrays
V3Slice::sliceAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("slices.tree");
// Push constants across variables and remove redundant assignments
V3Const::constifyAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("const.tree");
if (v3Global.opt.oLife()) {
V3Life::lifeAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("life.tree");
}
// Make large low-fanin logic blocks into lookup tables
// This should probably be done much later, once we have common logic elimination.
if (!v3Global.opt.lintOnly() && v3Global.opt.oTable()) {
V3Table::tableAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("table.tree");
}
// Cleanup
V3Const::constifyAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore);
V3Dead::deadifyDTypes(v3Global.rootp());
v3Global.checkTree();
V3Global::dumpCheckGlobalTree("const.tree");
// Detect clock enables and mode into sensitives, and split always based on clocks
// (so this is a good prelude to splitAlways.)
if (v3Global.opt.oFlopGater()) {
V3ClkGater::clkGaterAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("clkgater.tree");
}
// Move assignments/sensitives into a SBLOCK for each unique sensitivity list
// (May convert some ALWAYS to combo blocks, so should be before V3Gate step.)
V3Active::activeAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("active.tree");
// Split single ALWAYS blocks into multiple blocks for better ordering chances
if (v3Global.opt.oSplit()) {
V3Split::splitAlwaysAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("split.tree", 0, dumpMore);
}
V3SplitAs::splitAsAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("splitas.tree");
// Create tracing sample points, before we start eliminating signals
if (v3Global.opt.trace()) {
V3TraceDecl::traceDeclAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("tracedecl.tree");
}
// Gate-based logic elimination; eliminate signals and push constant across cell boundaries
// Instant propagation makes lots-o-constant reduction possibilities.
if (v3Global.opt.oGate()) {
V3Gate::gateAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("gate.tree");
// V3Gate calls constant propagation itself.
} else {
v3info("Command Line disabled gate optimization with -Og/-O0. This may cause ordering problems.");
@@ -398,14 +351,11 @@ void process () {
// Combine COVERINCs with duplicate terms
if (v3Global.opt.coverage()) {
V3CoverageJoin::coverageJoin(v3Global.rootp());
V3Global::dumpCheckGlobalTree("coveragejoin.tree");
}
// Remove unused vars
V3Const::constifyAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore);
V3Dead::deadifyAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("const.tree");
// Clock domain crossing analysis
if (v3Global.opt.cdc()) {
@@ -417,32 +367,26 @@ void process () {
// Reorder assignments in pipelined blocks
if (v3Global.opt.oReorder()) {
V3Split::splitReorderAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("reorder.tree");
}
// Create delayed assignments
// This creates lots of duplicate ACTIVES so ActiveTop needs to be after this step
V3Delayed::delayedAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("delayed.tree");
// Make Active's on the top level
// Differs from V3Active, because identical clocks may be pushed down to a module and now be identical
V3ActiveTop::activeTopAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("activetop.tree");
if (v3Global.opt.stats()) V3Stats::statsStageAll(v3Global.rootp(), "PreOrder");
// Order the code; form SBLOCKs and BLOCKCALLs
V3Order::orderAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("order.tree");
// Change generated clocks to look at delayed signals
V3GenClk::genClkAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("genclk.tree");
// Convert sense lists into IF statements.
V3Clock::clockAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("clock.tree");
// Cleanup any dly vars or other temps that are simple assignments
// Life must be done before Subst, as it assumes each CFunc under _eval is called only once.
@@ -453,33 +397,25 @@ void process () {
if (v3Global.opt.oLifePost()) {
V3LifePost::lifepostAll(v3Global.rootp());
}
if (v3Global.opt.oLife() || v3Global.opt.oLifePost()) {
V3Global::dumpCheckGlobalTree("life.tree");
}
// Remove unused vars
V3Const::constifyAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore);
V3Dead::deadifyAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("const.tree");
// Detect change loop
V3Changed::changedAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("changed.tree");
// Create tracing logic, since we ripped out some signals the user might want to trace
// Note past this point, we presume traced variables won't move between CFuncs
// (It's OK if untraced temporaries move around, or vars "effectively" activate the same way.)
if (v3Global.opt.trace()) {
V3Trace::traceAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("trace.tree");
}
if (v3Global.opt.stats()) V3Stats::statsStageAll(v3Global.rootp(), "Scoped");
// Remove scopes; make varrefs/funccalls relative to current module
V3Descope::descopeAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("descope.tree");
}
//--MODULE OPTIMIZATIONS--------------
@@ -488,19 +424,16 @@ void process () {
// Split deep blocks to appease MSVC++. Must be before Localize.
if (!v3Global.opt.lintOnly() && v3Global.opt.compLimitBlocks()) {
V3DepthBlock::depthBlockAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("deepblock.tree");
}
// Move BLOCKTEMPS from class to local variables
if (v3Global.opt.oLocalize()) {
V3Localize::localizeAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("localize.tree", 0, dumpMore);
}
// Icache packing; combine common code in each module's functions into subroutines
if (v3Global.opt.oCombine()) {
V3Combine::combineAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("combine.tree");
}
}
@@ -511,9 +444,7 @@ void process () {
if (!v3Global.opt.xmlOnly()) {
// Remove unused vars
V3Const::constifyAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("const_predead.tree", 0, dumpMore);
V3Dead::deadifyAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("const.tree");
// Here down, widthMin() is the Verilog width, and width() is the C++ width
// Bits between widthMin() and width() are irrelevant, but may be non zero.
@@ -521,18 +452,15 @@ void process () {
// Make all math operations either 8, 16, 32 or 64 bits
V3Clean::cleanAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("clean.tree");
// Move wide constants to BLOCK temps.
V3Premit::premitAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("premit.tree");
}
// Expand macros and wide operators into C++ primitives
if (!v3Global.opt.xmlOnly()
&& v3Global.opt.oExpand()) {
V3Expand::expandAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("expand.tree");
}
// Propagate constants across WORDSEL arrayed temporaries
@@ -540,18 +468,14 @@ void process () {
&& v3Global.opt.oSubst()) {
// Constant folding of expanded stuff
V3Const::constifyCpp(v3Global.rootp());
V3Global::dumpCheckGlobalTree("const.tree");
V3Subst::substituteAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("subst.tree");
}
if (!v3Global.opt.xmlOnly()
&& v3Global.opt.oSubstConst()) {
// Constant folding of substitutions
V3Const::constifyCpp(v3Global.rootp());
V3Global::dumpCheckGlobalTree("constc.tree", 0, dumpMore);
V3Dead::deadifyAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("dead.tree");
}
if (!v3Global.opt.lintOnly()
@@ -559,7 +483,6 @@ void process () {
// Fix very deep expressions
// Mark evaluation functions as member functions, if needed.
V3Depth::depthAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("depth.tree", 0, dumpMore);
// Branch prediction
V3Branch::branchAll(v3Global.rootp());
@@ -567,7 +490,6 @@ void process () {
// Add C casts when longs need to become long-long and vice-versa
// Note depth may insert something needing a cast, so this must be last.
V3Cast::castAll(v3Global.rootp());
V3Global::dumpCheckGlobalTree("cast.tree");
}
V3Error::abortIfErrors();
@@ -660,9 +582,9 @@ int main(int argc, char** argv, char** env) {
//--FRONTEND------------------
// Cleanup
V3Options::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.tree");
V3Options::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.dot");
V3Options::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.txt");
V3Os::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.tree");
V3Os::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.dot");
V3Os::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.txt");
// Read first filename
v3Global.readFiles();
@@ -673,7 +595,7 @@ int main(int argc, char** argv, char** env) {
}
// Final steps
V3Global::dumpCheckGlobalTree("final.tree",990);
V3Global::dumpCheckGlobalTree("final.tree", 990, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Error::abortIfWarnings();
if (!v3Global.opt.lintOnly() && !v3Global.opt.cdc()
+2 -13
View File
@@ -21,6 +21,8 @@
// Cheat for speed and compile .cpp files into one object
#define _V3ERROR_NO_GLOBAL_ 1
#include "V3Error.cpp"
#include "V3String.cpp"
#include "V3Os.cpp"
#include "VlcTop.cpp"
#include "VlcOptions.h"
@@ -130,19 +132,6 @@ void VlcOptions::showVersion(bool verbose) {
cout << "See http://www.veripool.org/verilator for documentation\n";
}
//######################################################################
// File searching
// (TODO: Make a V3Os with these functions and share with Verilator)
string VlcOptions::filenameNonDir (const string& filename) {
string::size_type pos;
if ((pos = filename.rfind("/")) != string::npos) {
return filename.substr(pos+1);
} else {
return filename;
}
}
//######################################################################
int main(int argc, char** argv, char** env) {
-3
View File
@@ -77,9 +77,6 @@ public:
// METHODS (from main)
static string version();
// METHODS (file searching)
static string filenameNonDir(const string& filename);
};
//######################################################################
+3 -3
View File
@@ -18,8 +18,8 @@
//
//*************************************************************************
// Cheat for speed and compile .cpp files into one object
#include "V3Error.h"
#include "V3Os.h"
#include "VlcOptions.h"
#include "VlcTop.h"
@@ -194,12 +194,12 @@ void VlcTop::annotateCalcNeeded() {
void VlcTop::annotateOutputFiles(const string& dirname) {
// Create if uncreated, ignore errors
mkdir(dirname.c_str(), 0777);
V3Os::createDir(dirname);
for (VlcSources::NameMap::iterator sit=m_sources.begin(); sit!=m_sources.end(); ++sit) {
VlcSource& source = sit->second;
if (!source.needed()) continue;
string filename = source.name();
string outfilename = dirname+"/"+VlcOptions::filenameNonDir(filename);
string outfilename = dirname+"/"+V3Os::filenameNonDir(filename);
UINFO(1,"annotateOutputFile "<<filename<<" -> "<<outfilename<<endl);
+1
View File
@@ -42,6 +42,7 @@ private:
VlcSources m_sources; //< List of all source files to annotate
// METHODS
void createDir(const string& dirname);
void annotateCalc();
void annotateCalcNeeded();
void annotateOutputFiles(const string& dirname);
-2
View File
@@ -4,8 +4,6 @@
//
// This file is part of Verilator.
//
// Author: Wilson Snyder <[email protected]>
//
// Code available from: http://www.veripool.org/verilator
//
//*************************************************************************
+1 -1
View File
@@ -22,7 +22,7 @@ my $header = ("\\usepackage[left=1.7in,right=1.7in,top=1.3in,bottom=1.3in]{geome
."\\usepackage[pdftex,bookmarks=true,bookmarksnumbered=true,hypertexnames=false,breaklinks=true,linkbordercolor={0 0 1}]{hyperref}\n"
."\\usepackage{fancyhdr} \\pagestyle{fancy}\n"
."\\setlength{\\parindent}{0pt} \\setlength{\\parskip}{\\baselineskip}\n"
."\\title{${Opt_DistTitle}} \\date{${Opt_DistDate}} \\author{Wilson Snyder\\\\ http:\/\/www.veripool.org}\n"
."\\title{${Opt_DistTitle}} \\date{${Opt_DistDate}} \\author{http:\/\/www.veripool.org}\n"
."\\lhead[${Opt_DistTitle}]{${Opt_DistTitle}}\n"
);
+2
View File
@@ -674,6 +674,8 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"/*verilator public_flat_rw*/" { FL; return yVL_PUBLIC_FLAT_RW; } // The @(edge) is converted by the preproc
"/*verilator public_module*/" { FL; return yVL_PUBLIC_MODULE; }
"/*verilator sc_clock*/" { FL; return yVL_CLOCK; }
"/*verilator clocker*/" { FL; return yVL_CLOCKER; }
"/*verilator no_clocker*/" { FL; return yVL_NO_CLOCKER; }
"/*verilator sc_bv*/" { FL; return yVL_SC_BV; }
"/*verilator sformat*/" { FL; return yVL_SFORMAT; }
"/*verilator systemc_clock*/" { FL; return yVL_CLOCK; }
+10 -4
View File
@@ -489,6 +489,8 @@ class AstSenTree;
%token<fl> yD_WRITE "$write"
%token<fl> yVL_CLOCK "/*verilator sc_clock*/"
%token<fl> yVL_CLOCKER "/*verilator clocker*/"
%token<fl> yVL_NO_CLOCKER "/*verilator no_clocker*/"
%token<fl> yVL_CLOCK_ENABLE "/*verilator clock_enable*/"
%token<fl> yVL_COVERAGE_BLOCK_OFF "/*verilator coverage_block_off*/"
%token<fl> yVL_FULL_CASE "/*verilator full_case*/"
@@ -1462,7 +1464,7 @@ variable_dimension<rangep>: // ==IEEE: variable_dimension
//UNSUP '[' ']' { UNSUP }
// // IEEE: unpacked_dimension
anyrange { $$ = $1; }
| '[' constExpr ']' { $$ = new AstRange($1,new AstSub($1,$2, new AstConst($1,1)), new AstConst($1,0)); }
| '[' constExpr ']' { $$ = new AstRange($1, new AstConst($1, 0), new AstSub($1, $2, new AstConst($1, 1))); }
// // IEEE: associative_dimension
//UNSUP '[' data_type ']' { UNSUP }
//UNSUP yP_BRASTAR ']' { UNSUP }
@@ -1927,6 +1929,8 @@ sigAttrList<nodep>:
sigAttr<nodep>:
yVL_CLOCK { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCK); }
| yVL_CLOCKER { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCKER); }
| yVL_NO_CLOCKER { $$ = new AstAttrOf($1,AstAttrType::VAR_NO_CLOCKER); }
| yVL_CLOCK_ENABLE { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCK_ENABLE); }
| yVL_PUBLIC { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC); v3Global.dpi(true); }
| yVL_PUBLIC_FLAT { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT); v3Global.dpi(true); }
@@ -2013,7 +2017,8 @@ etcInst<nodep>: // IEEE: module_instantiation + gate_instantiation + udp_insta
instDecl<nodep>:
id parameter_value_assignmentE {INSTPREP(*$1,$2);} instnameList ';'
{ $$ = $4; GRAMMARP->m_impliedDecl=false;}
{ $$ = $4; GRAMMARP->m_impliedDecl=false;
if (GRAMMARP->m_instParamp) { GRAMMARP->m_instParamp->deleteTree(); GRAMMARP->m_instParamp = NULL; } }
// // IEEE: interface_identifier' .' modport_identifier list_of_interface_identifiers
| id/*interface*/ '.' id/*modport*/
{ VARRESET_NONLIST(AstVarType::IFACEREF);
@@ -2038,9 +2043,10 @@ instnameList<nodep>:
;
instnameParen<cellp>:
id instRangeE '(' cellpinList ')' { $$ = new AstCell($<fl>1,*$1,GRAMMARP->m_instModule,$4, GRAMMARP->m_instParamp,$2);
// // Must clone m_instParamp as may be comma'ed list of instances
id instRangeE '(' cellpinList ')' { $$ = new AstCell($<fl>1,*$1,GRAMMARP->m_instModule,$4, GRAMMARP->m_instParamp->cloneTree(true),$2);
$$->trace(GRAMMARP->allTracingOn($<fl>1)); }
| id instRangeE { $$ = new AstCell($<fl>1,*$1,GRAMMARP->m_instModule,NULL,GRAMMARP->m_instParamp,$2);
| id instRangeE { $$ = new AstCell($<fl>1,*$1,GRAMMARP->m_instModule,NULL,GRAMMARP->m_instParamp->cloneTree(true),$2);
$$->trace(GRAMMARP->allTracingOn($<fl>1)); }
//UNSUP instRangeE '(' cellpinList ')' { UNSUP } // UDP
// // Adding above and switching to the Verilog-Perl syntax
+4 -1
View File
@@ -393,6 +393,7 @@ sub new {
"-OD", # As currently disabled unless -O3
"--debug-check"],
verilator_flags2 => [],
verilator_flags3 => ["--clk clk"],
verilator_make_gcc => 1,
verilated_debug => $Opt_Verilated_Debug,
stdout_filename => undef, # Redirect stdout
@@ -502,7 +503,8 @@ sub compile_vlt_flags {
my $checkflags = join(' ',@{$param{v_flags}},
@{$param{v_flags2}},
@{$param{verilator_flags}},
@{$param{verilator_flags2}});
@{$param{verilator_flags2}},
@{$param{verilator_flags3}});
$self->{sc} = 1 if ($checkflags =~ /-sc\b/);
$self->{sp} = 1 if ($checkflags =~ /-sp\b/);
$self->{trace} = 1 if ($opt_trace || $checkflags =~ /-trace\b/);
@@ -533,6 +535,7 @@ sub compile_vlt_flags {
"--prefix ".$param{VM_PREFIX},
@verilator_flags,
@{$param{verilator_flags2}},
@{$param{verilator_flags3}},
@{$param{v_flags}},
@{$param{v_flags2}},
$param{top_filename},
+1
View File
@@ -8,6 +8,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Version 2.0.
compile (
verilator_flags2 => ["-Wno-CLKDATA"],
);
execute (
+5 -12
View File
@@ -39,30 +39,23 @@ module t (clk);
if (cyc==3) begin
d1 <= 1'b1; d3<=3'h3; d8<=8'h44;
ena <= 1'b1;
// PROPER ANSWER is 8'h11, but we are negative-testing
//if (q8 != 8'h11) $stop;
if (q8 != 8'h33) $stop;
if (q8 != 8'h11) $stop;
end
if (cyc==4) begin
d1 <= 1'b1; d3<=3'h4; d8<=8'h77;
ena <= 1'b1;
// PROPER ANSWER is 8'h11, but we are negative-testing
//if (q8 != 8'h11) $stop;
if (q8 != 8'h33) $stop;
if (q8 != 8'h11) $stop;
end
if (cyc==5) begin
d1 <= 1'b1; d3<=3'h0; d8<=8'h88;
ena <= 1'b1;
// PROPER ANSWER is 8'h44, but we are negative-testing
//if (q8 != 8'h44) $stop;
if (q8 != 8'h44) $stop;
end
if (cyc==6) begin
// PROPER ANSWER is 8'h77, but we are negative-testing
//if (q8 != 8'h77) $stop;
if (q8 != 8'h77) $stop;
end
if (cyc==7) begin
// PROPER ANSWER is 8'h88, but we are negative-testing
//if (q8 != 8'h88) $stop;
if (q8 != 8'h88) $stop;
end
//
if (cyc==20) begin
+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 (
# verilator_flags2 => ["-Wno-UNOPTFLAT"]
);
execute (
check_finished=>1,
);
ok(1);
1;
+66
View File
@@ -0,0 +1,66 @@
// DESCRIPTION: Verilator: Simple test of CLkDATA
//
// Trigger the CLKDATA detection
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2015 by Jie Xu.
localparam ID_MSB = 1;
module t (/*AUTOARG*/
// Inputs
clk,
res,
res8,
res16
);
input clk;
output res;
output [7:0] res8;
output [15:0] res16;
wire [7:0] clkSet;
wire clk_1;
wire [2:0] clk_3;
wire [3:0] clk_4;
wire clk_final;
reg [7:0] count;
assign clkSet = {8{clk}};
assign clk_4 = clkSet[7:4];
assign clk_1 = clk_4[0];;
// arraysel
assign clk_3 = {3{clk_1}};
assign clk_final = clk_3[0];
// the following two assignment triggers the CLKDATA warning
// because on LHS there are a mix of signals both CLOCK and
// DATA
/* verilator lint_off CLKDATA */
assign res8 = {clk_3, 1'b0, clk_4};
assign res16 = {count, clk_3, clk_1, clk_4};
/* verilator lint_on CLKDATA */
initial
count = 0;
always @(posedge clk_final or negedge clk_final) begin
count = count + 1;
// the following assignment should trigger the CLKDATA warning
// because CLOCK signal is used as DATA in sequential block
/* verilator lint_off CLKDATA */
res <= clk_final;
/* verilator lint_on CLKDATA */
if ( count == 8'hf) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule

Some files were not shown because too many files have changed in this diff Show More