mirror of
https://github.com/verilator/verilator.git
synced 2026-10-02 16:13:34 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed2fbd8f25 | ||
|
|
42199bc8e5 | ||
|
|
7c5318768c | ||
|
|
aba25aab19 | ||
|
|
f99bd33f91 | ||
|
|
a6a6ce83f0 | ||
|
|
f4908a9758 |
@@ -3,6 +3,16 @@ 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.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
@@ -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 \
|
||||
|
||||
@@ -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.
|
||||
|
||||
+6
-4
@@ -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
@@ -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"); }
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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
@@ -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] { }
|
||||
|
||||
+75
-16
@@ -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 loose 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;
|
||||
@@ -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
@@ -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
@@ -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()
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//**********************************************************************
|
||||
//**** Version and host name
|
||||
|
||||
#define DTVERSION "Verilator 3.803 2010/07/10"
|
||||
#define DTVERSION "Verilator 3.804 2010/07/10"
|
||||
|
||||
//**********************************************************************
|
||||
//**** Functions
|
||||
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 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;
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
//======================================================================
|
||||
|
||||
Reference in New Issue
Block a user