Compare commits

...
16 Commits
35 changed files with 425 additions and 78 deletions
+20
View File
@@ -3,6 +3,26 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. [by ...]
indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.805 2010/11/02
**** Add warning when directory contains spaces, msg378. [Salman Sheikh]
**** Fix wrong filename on include file errors, bug289. [Brad Parker]
**** Fix segfault on SystemVerilog "output wire foo=0", bug291. [Joshua Wise]
**** Fix DPI export name not found, msg369. [Terry Chen]
* Verilator 3.804 2010/09/20
*** Support tracing/coverage of underscore signals, bug280. [by Jason McMullan]
**** Fix preprocessor `` of existing base define, bug283. [Usha Priyadharshini]
**** Increase define recursions before error. [Paul Liu]
**** On core dump, print debug suggestions.
* Verilator 3.803 2010/07/10
*** Fix preprocessor preservation of newlines across macro substitutions.
+1 -1
View File
@@ -118,7 +118,7 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
src/.*ignore src/*.in src/*.cpp src/*.[chly] src/astgen src/bisonpre src/*fix \
src/*.pl src/*.pod \
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh test_*/vlint \
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \
test_verilated/vgen*.pl \
test_regress/t/*.cpp \
test_regress/t/*.h \
+21
View File
@@ -137,6 +137,15 @@ sub run {
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
warn "%Error: $command\n";
}
if ($status & 255) {
if (($status & 255) == 8 || ($status & 255) == 11) { # SIGFPA or SIGSEGV
warn "%Error: Verilator internal fault, sorry. Consider trying --debug --gdbbt\n" if !$Debug;
} elsif (($status & 255) == 6) { # SIGABRT
warn "%Error: Verilator aborted. Consider trying --debug --gdbbt\n" if !$Debug;
} else {
warn "%Error: Verilator threw signal $status. Consider trying --debug --gdbbt\n" if !$Debug;
}
}
die "%Error: Command Failed $command\n";
}
}
@@ -207,6 +216,7 @@ descriptions in the next sections for more information.
--coverage-line Enable line coverage
--coverage-toggle Enable toggle coverage
--coverage-user Enable PSL/SVL user coverage
--coverage-underscore Enable covarge of _signals
-D<var>[=<value>] Set preprocessor define
--debug Enable debugging
--debug-check Enable debugging assertions
@@ -256,6 +266,7 @@ descriptions in the next sections for more information.
--top-module <topname> Name of top level input module
--trace Enable waveform creation
--trace-depth <levels> Depth of tracing
--trace-underscore Enable tracing of _signals
-U<var> Undefine preprocessor define
--unroll-count <loops> Tune maximum loop iterations
--unroll-stmts <stmts> Tune maximum loop body size
@@ -426,6 +437,11 @@ counting such behavior.
A /*verilator coverage_off/on */ comment pair can be used around signals
that do not need toggle analysis, such as RAMs and register files.
=item --coverage-underscore
Enable coverage of signals that start with an underscore. Normally, these
signals are not covered. See also --trace-underscore.
=item --coverage-user
Enables user inserted functional coverage. Currently, all functional
@@ -750,6 +766,11 @@ Specify the number of levels deep to enable tracing, for example
entire model. Using a small number will decrease visibility, but greatly
improve runtime and trace file size.
=item --trace-underscore
Enable tracing of signals that start with an underscore. Normally, these
signals are not output during tracing. See also --coverage-underscore.
=item -UI<var>
Undefines the given preprocessor symbol.
+7
View File
@@ -19,6 +19,13 @@ RANLIB = ranlib
SP_PREPROC = sp_preproc
SP_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer
######################################################################
# Make checks
ifneq ($(words $(CURDIR)),1)
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
endif
######################################################################
# C Preprocessor flags
+1 -1
View File
@@ -49,7 +49,7 @@ class VerilatedImp {
typedef vector<string> ArgVec;
typedef map<pair<const void*,void*>,void*> UserMap;
typedef map<const char*, const VerilatedScope*, VerilatedCStrCmp> ScopeNameMap;
typedef map<const char*, int> ExportNameMap;
typedef map<const char*, int, VerilatedCStrCmp> ExportNameMap;
// MEMBERS
static VerilatedImp s_s; ///< Static Singleton; One and only static this
+16 -20
View File
@@ -72,15 +72,14 @@ Download the latest package from that site, and decompress.
If you will be using SystemC (vs straight C++ output), download SystemC
2.0.1 from L<http://www.systemc.org>. Follow their installation
instructions. As described in the System-Perl README, you will need to set
SYSTEMC and/or SYSTEMC_KIT to point to this download. Also, set
SYSTEMC_ARCH to the architecture name you used with SystemC, generally
'linux' or 'cygwin'.
instructions. You will need to set the SYSTEMC environment variable to
point to this download. Also, setenv SYSTEMC_ARCH to the architecture name
you used with SystemC, generally 'linux' or 'cygwin'.
=item
If you will be using SystemPerl or coverage, download and install
Verilog-Perl, L<http://www.veripool.org/verilog-perl>.
Verilator assumes you did a make in the SystemC kit directory and SYSTEMC
points to that directory. There must be appropriate files in
C<$SYSTEMC/include> and C<$SYSTEMC/lib-linux> for SystemC compilation to
work.
=item
@@ -100,7 +99,7 @@ You now have to decide how you're going to eventually install the kit.
Our personal favorite is to always run Verilator from the kit directory.
This allows the easiest experimentation and upgrading. It's also how most
EDA tools operate; you just point to the tarball.
EDA tools operate; to run any of them you point to the tarball.
export VERILATOR_ROOT=`pwd` # if your shell is bash
setenv VERILATOR_ROOT `pwd` # if your shell is csh
@@ -119,11 +118,9 @@ most GNU tools support:
unsetenv VERILATOR_ROOT # if your shell is csh
./configure --prefix /opt/verilator-VERSION
Finally, if you are configuring Verilator to be part of a RPM or other
distribution package system, you may want to tune the various install
directories and use the --enable-defenv configure flag. This will take the
current value of VERILATOR_ROOT, SYSTEMC, SYSTEMC_ARCH, SYSTEMPERL, and
SYSTEMPERL_INCLUDE and build them as defaults into the executable.
Note Verilator builds the current value of VERILATOR_ROOT, SYSTEMC,
SYSTEMC_ARCH, SYSTEMPERL, and SYSTEMPERL_INCLUDE as defaults into the
executable, so try to have them correct before configuring.
=item
@@ -141,16 +138,15 @@ unsigned long uint32_t;}.
=item
If you used the VERILATOR_ROOT sheme you're done. Programs should set the
If you used the VERILATOR_ROOT scheme you're done. Programs should set the
environment variable VERILATOR_ROOT to point to this distribution, then
execute $VERILATOR_ROOT/bin/verilator, which will find the path to all
needed files.
If you used the prefix scheme, now do a C<make install>.
Verilator assumes you did a make in the SystemC kit directory. If not, you
will need to populate C<$SYSTEMC/include> and C<$SYSTEMC/lib-linux>
appropriately.
If you used the prefix scheme, now do a C<make install>. To run verilator,
have the verilator binary directory in your PATH (this should already be
true if using the default configure), and make sure VERILATOR_ROOT is not
set.
=back
+4
View File
@@ -46,6 +46,10 @@ export OBJCACHE_JOBS := -j $(shell objcache --jobs "$(OBJCACHE_HOSTS)")
endif
endif
ifneq ($(words $(CURDIR)),1)
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
endif
UNDER_GIT = $(wildcard ../.git/logs/HEAD)
#*********************************************************************
+1 -1
View File
@@ -813,7 +813,7 @@ void AstNode::iterateAndNextIgnoreEdit(AstNVisitor& v, AstNUser* vup) {
AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
// Some visitors perform tree edits (such as V3Const), and may even
// replace/delete the exact nodep that the visitor is called with. If
// this happens, the parent will loose the handle to the node that was
// this happens, the parent will lose the handle to the node that was
// processed.
// To solve this, this function returns the pointer to the replacement node,
// which in many cases is just the same node that was passed in.
+1 -1
View File
@@ -1106,7 +1106,7 @@ private:
// Someday if lower is constant, convert to quoted "string".
virtual void visit(AstAttrOf* nodep, AstNUser*) {
// Don't iterate children, don't want to loose VarRef.
// Don't iterate children, don't want to lose VarRef.
if (nodep->attrType()==AstAttrType::EXPR_BITS) {
if (!nodep->fromp() || !nodep->fromp()->widthMin()) nodep->v3fatalSrc("Unsized expression");
V3Number num (nodep->fileline(), 32, nodep->fromp()->widthMin());
+6 -4
View File
@@ -81,10 +81,12 @@ private:
string prettyName = nodep->prettyName();
if (!nodep->isToggleCoverable())
return "Not relevant signal type";
if (prettyName.c_str()[0] == '_')
return "Leading underscore";
if (prettyName.find("._") != string::npos)
return "Inlined leading underscore";
if (!v3Global.opt.coverageUnderscore()) {
if (prettyName.c_str()[0] == '_')
return "Leading underscore";
if (prettyName.find("._") != string::npos)
return "Inlined leading underscore";
}
if ((nodep->width()*nodep->arrayElements()) > 256) return "Wide bus/array > 256 bits";
// We allow this, though tracing doesn't
// if (nodep->arrayp(1)) return "Unsupported: Multi-dimensional array";
+4 -4
View File
@@ -196,13 +196,13 @@ inline void v3errorEnd(ostringstream& sstr) { V3Error::v3errorEnd(sstr); }
// Use this instead of fatal() to mention the source code line.
#define v3fatalSrc(msg) v3warn(EC_FATALSRC,__FILE__<<":"<<dec<<__LINE__<<": "<<msg)
#define UINFO(level,stmsg) {if(debug()>=(level)) { cout<<"- "<<V3Error::lineStr(__FILE__,__LINE__)<<stmsg; }}
#define UINFONL(level,stmsg) {if(debug()>=(level)) { cout<<stmsg; } }
#define UINFO(level,stmsg) {if(VL_UNLIKELY(debug()>=(level))) { cout<<"- "<<V3Error::lineStr(__FILE__,__LINE__)<<stmsg; }}
#define UINFONL(level,stmsg) {if(VL_UNLIKELY(debug()>=(level))) { cout<<stmsg; } }
#define UDEBUGONLY(stmts) {stmts}
#define UASSERT(condition,stmsg) { if (!(condition)) { v3fatalSrc(stmsg); }}
#define UASSERT(condition,stmsg) { if (VL_UNLIKELY(!(condition))) { v3fatalSrc(stmsg); }}
// For use in V3Ast static functions only
#define UASSERT_STATIC(condition,stmsg) { if (!(condition)) { cerr<<"Internal Error: "<<__FILE__<<":"<<dec<<__LINE__<<":"<<(stmsg)<<endl; abort(); } }
#define UASSERT_STATIC(condition,stmsg) { if (VL_UNLIKELY(!(condition))) { cerr<<"Internal Error: "<<__FILE__<<":"<<dec<<__LINE__<<":"<<(stmsg)<<endl; abort(); } }
#define V3ERROR_NA { v3error("Internal: Unexpected Call"); v3fatalSrc("Unexpected Call"); }
+1 -1
View File
@@ -196,7 +196,7 @@ private:
virtual void visit(AstNodePreSel* nodep, AstNUser*) {
if (!nodep->attrp()) {
nodep->iterateChildren(*this);
// Constification may change the fromp() to a constant, which will loose the
// Constification may change the fromp() to a constant, which will lose the
// variable we're extracting from (to determine MSB/LSB/endianness/etc.)
// So we replicate it in another node
// Note that V3Param knows not to replace AstVarRef's under AstAttrOf's
+6
View File
@@ -611,9 +611,12 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
else if ( onoff (sw, "-coverage", flag/*ref*/) ) { coverage(flag); }
else if ( onoff (sw, "-coverage-line", flag/*ref*/) ){ m_coverageLine = flag; }
else if ( onoff (sw, "-coverage-toggle", flag/*ref*/) ){ m_coverageToggle = flag; }
else if ( onoff (sw, "-coverage-underscore", flag/*ref*/) ){ m_coverageUnderscore = flag; }
else if ( onoff (sw, "-coverage-user", flag/*ref*/) ){ m_coverageUser = flag; }
else if ( onoff (sw, "-covsp", flag/*ref*/) ) { } // TBD
else if ( !strcmp (sw, "-debug-abort") ) { abort(); } // Undocumented, see also --debug-core-dump
else if ( onoff (sw, "-debug-check", flag/*ref*/) ){ m_debugCheck = flag; }
else if ( !strcmp (sw, "-debug-core-dump") ) { char* zp=NULL; *zp=0; } // Undocumented, see also --debug-abort
else if ( onoff (sw, "-dump-tree", flag/*ref*/) ) { m_dumpTree = flag; }
else if ( onoff (sw, "-exe", flag/*ref*/) ) { m_exe = flag; }
else if ( onoff (sw, "-ignc", flag/*ref*/) ) { m_ignc = flag; }
@@ -634,6 +637,7 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
else if ( !strcmp (sw, "-sv") ) { m_language = V3LangCode::L1800_2005; }
else if ( onoff (sw, "-trace", flag/*ref*/) ) { m_trace = flag; }
else if ( onoff (sw, "-trace-dups", flag/*ref*/) ) { m_traceDups = flag; }
else if ( onoff (sw, "-trace-underscore", flag/*ref*/) ) { m_traceUnderscore = flag; }
else if ( onoff (sw, "-underline-zero", flag/*ref*/) ) { m_underlineZero = flag; } // Undocumented, old Verilator-2
// Optimization
else if ( !strncmp (sw, "-O", 2) ) {
@@ -993,6 +997,7 @@ V3Options::V3Options() {
m_autoflush = false;
m_coverageLine = false;
m_coverageToggle = false;
m_coverageUnderscore = false;
m_coverageUser = false;
m_debugCheck = false;
m_dumpTree = false;
@@ -1014,6 +1019,7 @@ V3Options::V3Options() {
m_systemPerl = false;
m_trace = false;
m_traceDups = false;
m_traceUnderscore = false;
m_underlineZero = false;
m_errorLimit = 50;
+4
View File
@@ -103,6 +103,7 @@ class V3Options {
bool m_cdc; // main switch: --cdc
bool m_coverageLine; // main switch: --coverage-block
bool m_coverageToggle;// main switch: --coverage-toggle
bool m_coverageUnderscore;// main switch: --coverage-underscore
bool m_coverageUser; // main switch: --coverage-func
bool m_debugCheck; // main switch: --debug-check
bool m_dumpTree; // main switch: --dump-tree
@@ -122,6 +123,7 @@ class V3Options {
bool m_stats; // main switch: --stats
bool m_trace; // main switch: --trace
bool m_traceDups; // main switch: --trace-dups
bool m_traceUnderscore;// main switch: --trace-underscore
bool m_underlineZero;// main switch: --underline-zero; undocumented old Verilator 2
int m_errorLimit; // main switch: --error-limit
@@ -222,12 +224,14 @@ class V3Options {
bool coverage() const { return m_coverageLine || m_coverageToggle || m_coverageUser; }
bool coverageLine() const { return m_coverageLine; }
bool coverageToggle() const { return m_coverageToggle; }
bool coverageUnderscore() const { return m_coverageUnderscore; }
bool coverageUser() const { return m_coverageUser; }
bool debugCheck() const { return m_debugCheck; }
bool dumpTree() const { return m_dumpTree; }
bool exe() const { return m_exe; }
bool trace() const { return m_trace; }
bool traceDups() const { return m_traceDups; }
bool traceUnderscore() const { return m_traceUnderscore; }
bool outFormatOk() const { return m_outFormatOk; }
bool keepTempFiles() const { return (V3Error::debugDefault()!=0); }
bool pinsUint8() const { return m_pinsUint8; }
+1 -1
View File
@@ -862,7 +862,7 @@ void OrderVisitor::processInsLoopEdge(V3GraphEdge* oldEdgep) {
OrderLoopEndVertex* endp = m_pmlLoopEndps[fromId];
newFromp = endp;
// If it goes from(to) a cutable VarVertex inside the Begin/End block,
// we can't loose the variable, as we might need to cut that variable out
// we can't lose the variable, as we might need to cut that variable out
// in the next pass of processLoops, and processBrokeLoops needs the var pointer.
// We'll make another VarVertex (dup of the one "inside" the loop)
// and point to it.
+2
View File
@@ -63,6 +63,8 @@ class V3PreProcImp;
#define VP_DEFFORM 309
#define VP_STRIFY 310
#define VP_BACKQUOTE 311
#define VP_SYMBOL_JOIN 312
#define VP_DEFREF_JOIN 313
#define VP_PSL 350
+7 -3
View File
@@ -80,6 +80,7 @@ crnl [\r]*[\n]
quote [\"]
tickquote [`][\"]
backslash [\\]
/* Where we use symb/symbdef, we must also look for a `` join */
symb ([a-zA-Z_][a-zA-Z0-9_$]*|\\[^ \t\f\r\n]+)
symbdef ([a-zA-Z_][a-zA-Z0-9_$]*|\\[^ \t\f\r\n`]+)
word [a-zA-Z0-9_]+
@@ -225,6 +226,7 @@ psl [p]sl
yy_pop_state(); return (VP_DEFARG);
}}
<ARGMODE>"`"{symbdef} { appendDefValue(yytext,yyleng); } /* defref in defref - outer macro expands first */
<ARGMODE>"`"{symbdef}`` { appendDefValue(yytext,yyleng); } /* defref in defref - outer macro expands first */
<ARGMODE>[^\/\*\n\r\\(,){}\[\]\"`]+ |
<ARGMODE>. { appendDefValue(yytext,yyleng); }
@@ -267,13 +269,15 @@ psl [p]sl
<PSLMULM>"//"[^\n\r]* { return (VP_COMMENT); } /* Comments inside block comments get literal inclusion (later removal) */
/* Define calls */
/* symbdef prevents normal lex rules from makeing `\`"foo a symbol {`"foo} instead of a BACKQUOTE */
/* symbdef prevents normal lex rules from making `\`"foo a symbol {`"foo} instead of a BACKQUOTE */
<INITIAL,PSLMULM,PSLONEM>"`"{symbdef} { return (VP_DEFREF); }
<INITIAL,PSLMULM,PSLONEM>"`"{symbdef}`` { yyleng-=2; return (VP_DEFREF_JOIN); }
/* Generics */
<INITIAL,PSLMULM>{crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); }
<INITIAL,PSLMULM,PSLONEM><<EOF>> { yyterminate(); } /* A "normal" EOF */
<INITIAL,PSLMULM,PSLONEM>{symb} { return (VP_SYMBOL); }
<INITIAL,PSLMULM,PSLONEM><<EOF>> { yyterminate(); } /* A "normal" EOF */
<INITIAL,PSLMULM,PSLONEM>{symb} { return (VP_SYMBOL); }
<INITIAL,PSLMULM,PSLONEM>{symb}`` { yyleng-=2; return (VP_SYMBOL_JOIN); }
<INITIAL,PSLMULM,PSLONEM>{wsn}+ { return (VP_WHITE); }
<INITIAL,PSLMULM,PSLONEM>{drop} { }
<INITIAL,PSLMULM,PSLONEM>[\r] { }
+76 -17
View File
@@ -126,14 +126,14 @@ struct V3PreProcImp : public V3PreProc {
ps_DEFNAME_UNDEF, ps_DEFNAME_DEFINE,
ps_DEFNAME_IFDEF, ps_DEFNAME_IFNDEF, ps_DEFNAME_ELSIF,
ps_DEFFORM, ps_DEFVALUE, ps_DEFPAREN, ps_DEFARG,
ps_INCNAME, ps_ERRORNAME, ps_STRIFY };
ps_INCNAME, ps_ERRORNAME, ps_JOIN, ps_STRIFY };
const char* procStateName(ProcState s) {
static const char* states[]
= {"ps_TOP",
"ps_DEFNAME_UNDEF", "ps_DEFNAME_DEFINE",
"ps_DEFNAME_IFDEF", "ps_DEFNAME_IFNDEF", "ps_DEFNAME_ELSIF",
"ps_DEFFORM", "ps_DEFVALUE", "ps_DEFPAREN", "ps_DEFARG",
"ps_INCNAME", "ps_ERRORNAME", "ps_STRIFY"};
"ps_INCNAME", "ps_ERRORNAME", "ps_JOIN", "ps_STRIFY"};
return states[s];
};
@@ -162,6 +162,10 @@ struct V3PreProcImp : public V3PreProc {
stack<V3DefineRef> m_defRefs; // Pending definine substitution
stack<VPreIfEntry> m_ifdefStack; ///< Stack of true/false emitting evaluations
unsigned m_defDepth; ///< How many `defines deep
bool m_defPutJoin; ///< Insert `` after substitution
// For `` join
stack<string> m_joinStack; ///< Text on lhs of join
// For getline()
string m_lineChars; ///< Characters left for next line
@@ -246,6 +250,7 @@ public:
m_finAhead = false;
m_finAtBol = true;
m_defDepth = 0;
m_defPutJoin = false;
}
void configure(FileLine* filelinep) {
// configure() separate from constructor to avoid calling abstract functions
@@ -459,6 +464,7 @@ const char* V3PreProcImp::tokenName(int tok) {
case VP_DEFFORM : return("DEFFORM");
case VP_DEFINE : return("DEFINE");
case VP_DEFREF : return("DEFREF");
case VP_DEFREF_JOIN : return("DEFREF_JOIN");
case VP_DEFVALUE : return("DEFVALUE");
case VP_ELSE : return("ELSE");
case VP_ELSIF : return("ELSIF");
@@ -473,6 +479,7 @@ const char* V3PreProcImp::tokenName(int tok) {
case VP_STRIFY : return("STRIFY");
case VP_STRING : return("STRING");
case VP_SYMBOL : return("SYMBOL");
case VP_SYMBOL_JOIN : return("SYMBOL_JOIN");
case VP_TEXT : return("TEXT");
case VP_UNDEF : return("UNDEF");
case VP_UNDEFINEALL : return("UNDEFINEALL");
@@ -640,7 +647,7 @@ string V3PreProcImp::defineSubst(V3DefineRef* refp) {
if (!quote) {
// Check for `` only after we've detected end-of-argname
if (cp[0]=='`' && cp[1]=='`') {
//out += ""; // `` means to suppress the ``
out += "``"; // `` must get removed later, as `FOO```BAR must pre-expand FOO and BAR
cp++;
continue;
}
@@ -770,7 +777,7 @@ int V3PreProcImp::getRawToken() {
m_lineAdd--;
m_rawAtBol = true;
yyourtext("\n",1);
if (debug()) debugToken(VP_WHITE, "LNA");
if (debug()>=5) debugToken(VP_WHITE, "LNA");
return (VP_WHITE);
}
if (m_lineCmt!="") {
@@ -788,7 +795,7 @@ int V3PreProcImp::getRawToken() {
V3PreLex::s_currentLexp->appendDefValue(yyourtext(),yyourleng());
goto next_tok;
} else {
if (debug()) debugToken(VP_TEXT, "LCM");
if (debug()>=5) debugToken(VP_TEXT, "LCM");
return (VP_TEXT);
}
}
@@ -797,7 +804,7 @@ int V3PreProcImp::getRawToken() {
// Snarf next token from the file
int tok = m_lexp->lex();
if (debug()) debugToken(tok, "RAW");
if (debug()>=5) debugToken(tok, "RAW");
// A EOF on an include, so we can print `line and detect mis-matched "s
if (tok==VP_EOF) {
@@ -810,7 +817,7 @@ int V3PreProcImp::getRawToken() {
}
void V3PreProcImp::debugToken(int tok, const char* cmtp) {
if (debug()>4) {
if (debug()>=5) {
string buf = string (yyourtext(), yyourleng());
string::size_type pos;
while ((pos=buf.find("\n")) != string::npos) { buf.replace(pos, 1, "\\n"); }
@@ -856,6 +863,40 @@ int V3PreProcImp::getStateToken() {
goto next_tok;
}
if (tok==VP_DEFREF_JOIN) {
// Here's something fun and unspecified as yet:
// The existance of non-existance of a base define changes `` expansion
// `define QA_b zzz
// `define Q1 `QA``_b
// 1Q1 -> zzz
// `define QA a
// `Q1 -> a_b
// Note parenthesis make this unambiguous
// `define Q1 `QA()``_b // -> a_b
// This may be a side effect of how `UNDEFINED remains as `UNDEFINED,
// but it screws up our method here. So hardcode it.
string name (yyourtext()+1,yyourleng()-1);
if (defExists(name)) { // JOIN(DEFREF)
// Put back the `` and process the defref
UINFO(5,"```: define "<<name<<" exists, expand first\n");
m_defPutJoin = true; // After define, unputString("``"). Not now as would lose yyourtext()
UINFO(5,"TOKEN now DEFREF\n");
tok = VP_DEFREF;
} else { // DEFREF(JOIN)
UINFO(5,"```: define "<<name<<" doesn't exist, join first\n");
// FALLTHRU, handle as with VP_SYMBOL_JOIN
}
}
if (tok==VP_SYMBOL_JOIN || tok==VP_DEFREF_JOIN) { // not else if, can fallthru from above if()
// a`` -> string doesn't include the ``, so can just grab next and continue
string out (yyourtext(),yyourleng());
UINFO(5,"`` LHS:"<<out<<endl);
// a``b``c can have multiple joins, so we need a stack
m_joinStack.push(out);
statePush(ps_JOIN);
goto next_tok;
}
// Deal with some special parser states
switch (state) {
case ps_TOP: {
@@ -928,7 +969,7 @@ int V3PreProcImp::getStateToken() {
case ps_DEFFORM: {
if (tok==VP_DEFFORM) {
m_formals = m_lexp->m_defValue;
if (debug()) cout<<"DefFormals='"<<V3PreLex::cleanDbgStrg(m_formals)<<"'\n";
if (debug()>=5) cout<<"DefFormals='"<<V3PreLex::cleanDbgStrg(m_formals)<<"'\n";
stateChange(ps_DEFVALUE);
m_lexp->pushStateDefValue();
goto next_tok;
@@ -945,8 +986,8 @@ int V3PreProcImp::getStateToken() {
static string newlines;
newlines = "\n"; // Always start with trailing return
if (tok == VP_DEFVALUE) {
if (debug()) cout<<"DefValue='"<<V3PreLex::cleanDbgStrg(m_lexp->m_defValue)
<<"' formals='"<<V3PreLex::cleanDbgStrg(m_formals)<<"'\n";
if (debug()>=5) cout<<"DefValue='"<<V3PreLex::cleanDbgStrg(m_lexp->m_defValue)
<<"' formals='"<<V3PreLex::cleanDbgStrg(m_formals)<<"'\n";
// Add any formals
string formals = m_formals;
string value = m_lexp->m_defValue;
@@ -1089,6 +1130,27 @@ int V3PreProcImp::getStateToken() {
goto next_tok;
}
}
case ps_JOIN: {
if (tok==VP_SYMBOL || tok==VP_TEXT) {
if (m_joinStack.empty()) fatalSrc("`` join stack empty, but in a ``");
string lhs = m_joinStack.top(); m_joinStack.pop();
UINFO(5,"`` LHS:"<<lhs<<endl);
string rhs (yyourtext(),yyourleng());
UINFO(5,"`` RHS:"<<rhs<<endl);
string out = lhs+rhs;
UINFO(5,"`` Out:"<<out<<endl);
unputString(out);
statePop();
goto next_tok;
} else if (tok==VP_EOF || tok==VP_WHITE || tok == VP_COMMENT || tok==VP_STRING) {
error((string)"Expecting symbol to terminate ``; whitespace etc cannot follow ``. Found: "+tokenName(tok)+"\n");
statePop();
goto next_tok;
} else {
// `define, etc, fall through and expand. Pop back here.
break;
}
}
case ps_STRIFY: {
if (tok==VP_STRIFY) {
// Quote what's in the middle of the stringification
@@ -1175,8 +1237,9 @@ int V3PreProcImp::getStateToken() {
case VP_DEFREF: {
// m_off not right here, but inside substitution, to make this work: `ifdef NEVER `DEFUN(`endif)
string name; name.append(yyourtext()+1,yyourleng()-1);
string name (yyourtext()+1,yyourleng()-1);
UINFO(4,"DefRef "<<name<<endl);
if (m_defPutJoin) { m_defPutJoin = false; unputString("``"); }
if (m_defDepth++ > V3PreProc::DEFINE_RECURSION_LEVEL_MAX) {
error("Recursive `define substitution: `"+name);
goto next_tok;
@@ -1296,7 +1359,7 @@ int V3PreProcImp::getFinalToken(string& buf) {
if (debug()>=5) fprintf(stderr,"%d: FIN: readjust, fin at %d request at %d\n",
m_lexp->m_tokFilelinep->lineno(),
m_finFilelinep->lineno(), m_lexp->m_tokFilelinep->lineno());
m_finFilelinep = m_finFilelinep->create(m_lexp->m_tokFilelinep->lineno());
m_finFilelinep = m_finFilelinep->create(m_lexp->m_tokFilelinep->filename(),m_lexp->m_tokFilelinep->lineno());
if (outBehind > 0 && outBehind <= (int)V3PreProc::NEWLINES_VS_TICKLINE) {
// Output stream is behind, send newlines to get back in sync
// (Most likely because we're completing a disabled `endif)
@@ -1333,7 +1396,7 @@ string V3PreProcImp::getline() {
while (NULL==(rtnp=strchr(m_lineChars.c_str(),'\n')) && !gotEof) {
string buf;
int tok = getFinalToken(buf/*ref*/);
if (debug()>4) {
if (debug()>=5) {
fprintf (stderr,"%d: GETFETC: %-10s: %s\n",
m_lexp->m_tokFilelinep->lineno(), tokenName(tok), V3PreLex::cleanDbgStrg(buf).c_str());
}
@@ -1359,9 +1422,5 @@ string V3PreProcImp::getline() {
if (debug()>=4) fprintf (stderr,"%d: GETLINE: %s\n",
m_lexp->m_tokFilelinep->lineno(),
V3PreLex::cleanDbgStrg(theLine).c_str());
if (debug()>=4) fprintf (stderr,"%d: GETLINE len %d FC %d\n",
m_lexp->m_tokFilelinep->lineno(),
(int)(theLine.length()),
(int)(theLine.length()>0?theLine[0]:-1));
return theLine;
}
+1 -1
View File
@@ -48,7 +48,7 @@ protected:
public:
// CONSTANTS
enum MiscConsts {
DEFINE_RECURSION_LEVEL_MAX = 50, // How many `def substitutions before an error
DEFINE_RECURSION_LEVEL_MAX = 1000, // How many `def substitutions before an error
INCLUDE_DEPTH_MAX = 500, // How many `includes deep before an error
NEWLINES_VS_TICKLINE = 20 // Use `line in place of this many newlines
};
+6 -4
View File
@@ -69,10 +69,12 @@ private:
string prettyName = nodep->prettyName();
if (!nodep->isTrace())
return "Verilator trace_off";
if (prettyName.c_str()[0] == '_')
return "Leading underscore";
if (prettyName.find("._") != string::npos)
return "Inlined leading underscore";
if (!v3Global.opt.traceUnderscore()) {
if (prettyName.c_str()[0] == '_')
return "Leading underscore";
if (prettyName.find("._") != string::npos)
return "Inlined leading underscore";
}
if (nodep->width() > 256) return "Wide bus > 256 bits";
if (nodep->arrayElements() > 32) return "Wide memory > 32 ents";
if (!(nodep->dtypeSkipRefp()->castBasicDType()
+1 -1
View File
@@ -130,7 +130,7 @@ private:
AstLogicPacked(), prep->width());
m_modp->addStmtp(varp);
AstNode* abovep = prep->backp(); // Grab above point before loose it w/ next replace
AstNode* abovep = prep->backp(); // Grab above point before lose it w/ next replace
prep->replaceWith(new AstVarRef(fl, varp, true));
AstNode* newp = new AstIf(fl, condp,
(needDly
+1 -1
View File
@@ -327,7 +327,7 @@ private:
if (nodep->lsbp()->castConst() && nodep->msbConst() > frommsb) {
// See also warning in V3Const
// We need to check here, because the widthCheck may silently
// add another SEL which will loose the out-of-range check
// add another SEL which will lose the out-of-range check
nodep->v3error("Selection index out of range: "
<<nodep->msbConst()<<":"<<nodep->lsbConst()
<<" outside "<<frommsb<<":"<<fromlsb);
+1 -1
View File
@@ -178,7 +178,7 @@ void process () {
//v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("widthcommit.tree"));
// Coverage insertion
// Before we do dead code elimination and inlining, or we'll loose it.
// Before we do dead code elimination and inlining, or we'll lose it.
if (v3Global.opt.coverage()) {
V3Coverage::coverage(v3Global.rootp());
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("coverage.tree"));
+1 -1
View File
@@ -25,7 +25,7 @@
//**********************************************************************
//**** Version and host name
#define DTVERSION "Verilator 3.803 2010/07/10"
#define DTVERSION "Verilator 3.805 2010/07/10"
//**********************************************************************
//**** Functions
+3 -3
View File
@@ -826,11 +826,11 @@ port<nodep>: // ==IEEE: port
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
{ $$=$3; VARDTYPE($2); AstVar* vp=VARDONEP($$,$4,$5); $$->addNextNull(vp); vp->valuep($7); }
| portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
{ $$=$3; VARDTYPE($3); AstVar* vp=VARDONEP($$,$5,$6); $$->addNextNull(vp); vp->valuep($8); }
{ $$=$4; VARDTYPE($3); AstVar* vp=VARDONEP($$,$5,$6); $$->addNextNull(vp); vp->valuep($8); }
| portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE '=' constExpr
{ $$=$3; VARDTYPE($3); AstVar* vp=VARDONEP($$,$5,$6); $$->addNextNull(vp); vp->valuep($8); }
{ $$=$4; VARDTYPE($3); AstVar* vp=VARDONEP($$,$5,$6); $$->addNextNull(vp); vp->valuep($8); }
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr
{ $$=$3; /*VARDTYPE-same*/ AstVar* vp=VARDONEP($$,$3,$4); $$->addNextNull(vp); vp->valuep($6); }
{ $$=$2; /*VARDTYPE-same*/ AstVar* vp=VARDONEP($$,$3,$4); $$->addNextNull(vp); vp->valuep($6); }
;
portDirNetE: // IEEE: part of port, optional net type and/or direction
+6 -1
View File
@@ -66,6 +66,7 @@ if (! GetOptions (
"gdb!" => \$opt_gdb,
"gdbbt!" => \$opt_gdbbt,
"gdbsim!" => \$opt_gdbsim,
"golden!" => sub { $ENV{HARNESS_UPDATE_GOLDEN} = 1; },
"help" => \&usage,
"iverilog!" => \$opt_iv,
"j=i" => \$opt_jobs,
@@ -1020,7 +1021,7 @@ sub files_identical {
eval "use File::Copy;";
File::Copy::copy($fn1,$fn2);
} else {
warn "To update reference: HARNESS_UPDATE_GOLDEN=1 {command}\n";
warn "To update reference: HARNESS_UPDATE_GOLDEN=1 {command} or --golden\n";
}
return 0;
}
@@ -1220,6 +1221,10 @@ Requires --debug.
Run Verilator generated executable under the debugger.
=item --golden
Update golden files, equivalent to setting HARNESS_UPDATE_GOLDEN=1.
=item --help
Displays this message and program version and exits.
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
compile (
v_flags2 => ["--debug-core-dump"],
fails=>$Self->{v3},
expect=>
'%Error: Verilator internal fault, sorry. Consider trying --debug --gdbbt
%Error: Command Failed.*',
);
ok(1);
1;
+4 -4
View File
@@ -17,14 +17,14 @@ example line 11;
`line 13 "t/t_pipe_filter.v" 0
`line 1 "t/t_pipe_filter_inc.vh" 1
int lint_off_line_7 = 1;
`line 2 "t/t_pipe_filter.v" 0
`line 2 "t/t_pipe_filter_inc.vh" 0
int lint_off_line_8 = 1;
`line 8 "t/t_pipe_filter.v" 0
`line 8 "t/t_pipe_filter_inc.vh" 0
inc line 6;
inc line 7;
inc line 8;
@@ -39,14 +39,14 @@ inc line 9;
`line 15 "t/t_pipe_filter.v" 0
`line 1 "t/t_pipe_filter_inc.vh" 1
int lint_off_line_7 = 1;
`line 2 "t/t_pipe_filter.v" 0
`line 2 "t/t_pipe_filter_inc.vh" 0
int lint_off_line_8 = 1;
`line 8 "t/t_pipe_filter.v" 0
`line 8 "t/t_pipe_filter_inc.vh" 0
inc line 6;
inc line 7;
inc line 8;
+55 -7
View File
@@ -10,10 +10,10 @@
`line 7 "t/t_preproc.v" 0
`line 1 "t/t_preproc_inc2.vh" 1
`line 3 "t/t_preproc.v" 0
`line 3 "t/t_preproc_inc2.vh" 0
`line 4 "t/t_preproc.v" 0
`line 4 "t/t_preproc_inc2.vh" 0
At file "t/t_preproc_inc2.vh" line 4
@@ -288,11 +288,11 @@ begin addr <= ({regs[6], regs[7]}); wdata <= (rdata); wr <= 1; end more
`line 180 "t/t_preproc.v" 0
`line 1 "t/t_preproc_inc4.vh" 1
`line 3 "t/t_preproc.v" 0
`line 3 "t/t_preproc_inc4.vh" 0
`line 5 "t/t_preproc.v" 0
`line 5 "t/t_preproc_inc4.vh" 0
`line 7 "t/t_preproc_inc4.vh" 2
@@ -612,11 +612,11 @@ hello4hello4hello4hello4
`line 388 "t/t_preproc.v" 0
`line 1 "t/t_preproc_inc4.vh" 1
`line 3 "t/t_preproc.v" 0
`line 3 "t/t_preproc_inc4.vh" 0
`line 5 "t/t_preproc.v" 0
`line 5 "t/t_preproc_inc4.vh" 0
`line 7 "t/t_preproc_inc4.vh" 2
@@ -654,4 +654,52 @@ Line_Preproc_Check 407
Line_Preproc_Check 410
`line 413 "t/t_preproc.v" 2
`line 414 "t/t_preproc.v" 0
`line 418 "t/t_preproc.v" 0
abc
`line 424 "t/t_preproc.v" 0
EXP: sonet_frame
sonet_frame
`line 430 "t/t_preproc.v" 0
EXP: sonet_frame
sonet_frame
`line 435 "t/t_preproc.v" 0
EXP: sonet_frame
sonet_frame
`line 441 "t/t_preproc.v" 0
EXP: module zzz ; endmodule
module zzz ; endmodule
module zzz ; endmodule
`line 447 "t/t_preproc.v" 0
EXP: module a_b ; endmodule
module a_b ; endmodule
module a_b ; endmodule
`line 454 "t/t_preproc.v" 2
+41
View File
@@ -409,3 +409,44 @@ Line_Preproc_Check `__LINE__
arg_line2")
Line_Preproc_Check `__LINE__
//======================================================================
// bug283
`define A a
`define B b
`define C c
// EXP: abc
`define C5 `A``b```C
`C5
`undef A
`undef B
`undef C
`define XTYPE sonet
`define XJOIN(__arg1, __arg2) __arg1``__arg2
`define XACTION `XJOIN(`XTYPE, _frame)
EXP: sonet_frame
`XACTION
//
`define XFRAME frame
`define XACTION2 `XJOIN(sonet_, `XFRAME)
EXP: sonet_frame
`XACTION2
// This result varies between simulators
`define sonet_frame other_frame
`define XACTION3 `XTYPE``_frame
EXP: sonet_frame
`XACTION3
// The existance of non-existance of a base define can make a difference
`define QA_b zzz
`define Q1 `QA``_b
EXP: module zzz ; endmodule
module `Q1 ; endmodule
module `Q1 ; endmodule
`define QA a
EXP: module a_b ; endmodule
module `Q1 ; endmodule
module `Q1 ; endmodule
//======================================================================
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
compile (
verilator_flags2 => ["--lint-only"],
fails=>1,
# The .vh file has the error, not the .v file
expect=>
'%Error: t/t_preproc_inc_inc_bad.vh:10: syntax error, unexpected endmodule, expecting IDENTIFIER'
);
ok(1);
1;
+11
View File
@@ -0,0 +1,11 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2010 by Wilson Snyder.
//See bug289
`include "t_preproc_inc_inc_bad.vh"
module t;
endmodule
+10
View File
@@ -0,0 +1,10 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2010 by Wilson Snyder.
module xx;
xx // intentional error
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+45
View File
@@ -0,0 +1,45 @@
// DESCRIPTION: Verilator: Verilog Test module
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2010 by Wilson Snyder.
// bug291
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer out18;
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire out1; // From test of Test.v
wire out19; // From test of Test.v
wire out1b; // From test of Test.v
// End of automatics
Test test (/*AUTOINST*/
// Outputs
.out1 (out1),
.out18 (out18),
.out1b (out1b),
.out19 (out19));
// Test loop
always @ (posedge clk) begin
if (out1 !== 1'b1) $stop;
if (out18 !== 32'h18) $stop;
if (out1b !== 1'b1) $stop;
if (out19 !== 1'b1) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
module Test (
output wire out1 = 1'b1,
output integer out18 = 32'h18,
output var out1b = 1'b1,
output var logic out19 = 1'b1
);
endmodule