mirror of
https://github.com/verilator/verilator.git
synced 2026-10-03 08:33:21 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4100f20a69 | ||
|
|
bedf946fb2 | ||
|
|
b9e67157c6 | ||
|
|
b30b2a183b | ||
|
|
9ab3bcdde3 | ||
|
|
5df3bbe188 | ||
|
|
8cf12416c0 | ||
|
|
b7c2c83c88 | ||
|
|
3b6da93331 | ||
|
|
b4642d3fd4 | ||
|
|
88a2b0b911 | ||
|
|
954e127f1d | ||
|
|
7654add5e5 | ||
|
|
85a37ea53f | ||
|
|
b337acebcc | ||
|
|
fb9ca54c95 | ||
|
|
1a15d41523 | ||
|
|
e378cc5791 | ||
|
|
748c189c79 | ||
|
|
b89be6c4b9 | ||
|
|
df207807b6 | ||
|
|
1f2b40cff1 | ||
|
|
734400fd37 | ||
|
|
f19979d928 | ||
|
|
19be7a53da | ||
|
|
e56af34fb0 |
@@ -3,7 +3,40 @@ 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.822 2011/10/20
|
||||
|
||||
* Verilator 3.830 2011/11/27
|
||||
|
||||
** With "--language VAMS" support a touch of Verilog AMS. [Holger Waechtler]
|
||||
|
||||
*** Add sc_bv attribute to force bit vectors, bug402. [by Stefan Wallentowitz]
|
||||
|
||||
**** Search for user -y paths before default current directory. [Ruben Diez]
|
||||
|
||||
**** Support constants in sensitivity lists, bug412. [Jeremy Bennett]
|
||||
|
||||
**** Support $system. [Ruben Diez]
|
||||
|
||||
**** Support $sscanf with %g. [Holger Wächtler]
|
||||
|
||||
**** Indicate 'exiting due to errors' if errors, not warnings. [Ruben Diez]
|
||||
|
||||
**** Fix bad result with if-else-return optimization, bug420. [Alex Solomatnikov]
|
||||
|
||||
**** Fix reporting not found modules if generate-off, bug403. [Jeremy Bennett]
|
||||
|
||||
**** Fix $display with %d following %g. [Holger Wächtler]
|
||||
|
||||
|
||||
* Verilator 3.824 2011/10/25
|
||||
|
||||
*** Fix "always @ (* )", bug403, bug404. [Walter Lavino]
|
||||
|
||||
*** Add ASSIGNIN as suppressable error. [Jeremy Bennett]
|
||||
|
||||
**** Fix 3.823 constructor core dump on Debian, bug401. [Ahmed El-Mahmoudy]
|
||||
|
||||
|
||||
* Verilator 3.823 2011/10/20
|
||||
|
||||
*** Support $ceil, $floor, etc. [Alex Solomatnikov]
|
||||
|
||||
|
||||
+64
-19
@@ -203,8 +203,9 @@ Verilator - Convert Verilog code to C++/SystemC
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Verilator converts synthesizable (not behavioral) Verilog code, plus some
|
||||
Synthesis, SystemVerilog and Sugar/PSL assertions, into C++, SystemC or
|
||||
SystemPerl code. It is not a complete simulator, just a compiler.
|
||||
Synthesis, SystemVerilog and a small subset of Verilog AMS and Sugar/PSL
|
||||
assertions, into C++, SystemC or SystemPerl code. It is not a complete
|
||||
simulator, just a compiler.
|
||||
|
||||
Verilator is invoked with parameters similar to GCC, Cadence
|
||||
Verilog-XL/NC-Verilog, or Synopsys's VCS. It reads the specified Verilog
|
||||
@@ -569,10 +570,7 @@ Displays this message and program version and exits.
|
||||
|
||||
=item -II<dir>
|
||||
|
||||
Add the directory to the list of directories that should be searched for
|
||||
include directories or libraries. Same as +incdir and -y; +incdir and -y
|
||||
are fairly standard across Verilog tools while -I is an alias for GCC
|
||||
compatibility.
|
||||
See -y.
|
||||
|
||||
=item --if-depth I<value>
|
||||
|
||||
@@ -581,10 +579,7 @@ defaults to 0 which disables this warning.
|
||||
|
||||
=item +incdir+I<dir>
|
||||
|
||||
Add the directory to the list of directories that should be searched for
|
||||
include directories or libraries. Same as -I and -y; +incdir and -y
|
||||
are fairly standard across Verilog tools while -I is an alias for GCC
|
||||
compatibility.
|
||||
See -y.
|
||||
|
||||
=item --inhibit-sim
|
||||
|
||||
@@ -616,9 +611,13 @@ in the Make variable LDLIBS, not LDFLAGS.)
|
||||
|
||||
Select the language to be used when first processing each Verilog file.
|
||||
The language value must be "1364-1995", "1364-2001", "1364-2001",
|
||||
"1364-2005", or "1800-2005". This should only be used for legacy code, as
|
||||
the preferable option is to edit the code to repair new keywords, or add
|
||||
appropriate `begin_keywords.
|
||||
"1364-2005", "1800-2005", "VAMS-2.3". Verilator also allows the
|
||||
non-standard "1800+VAMS" to allow both the full SystemVerilog and
|
||||
Verilog-AMS keywords.
|
||||
|
||||
The --language flag is only recommended for legacy code, as the preferable
|
||||
option is to edit the code to repair new keywords, or add appropriate
|
||||
`begin_keywords.
|
||||
|
||||
=item +libext+I<ext>+I<ext>...
|
||||
|
||||
@@ -722,7 +721,8 @@ Backward compatible alias for "--pins-bv 65". Note that's a 65, not a 64.
|
||||
Specifies SystemC inputs/outputs of greater than or equal to I<width> bits
|
||||
wide should use sc_bv's instead of uint32/vluint64_t's. The default is
|
||||
"--pins-bv 65". Versions before Verilator 3.671 defaulted to "--pins-bv
|
||||
33". The more sc_bv is used, the worse for performance.
|
||||
33". The more sc_bv is used, the worse for performance. Use the
|
||||
"/*verilator sc_bv*/" attribute to select specific ports to be sc_bv.
|
||||
|
||||
=item --pins-uint8
|
||||
|
||||
@@ -972,9 +972,14 @@ enable rerunning with that same seed so you can reproduce bugs.
|
||||
=item -y I<dir>
|
||||
|
||||
Add the directory to the list of directories that should be searched for
|
||||
include directories or libraries. Same as +incdir and -I; +incdir and +y
|
||||
are fairly standard across Verilog tools while -I is an alias for GCC
|
||||
compatibility.
|
||||
include files or libraries. The three flags -y, +incdir and -I have
|
||||
similar effect; +incdir and +y are fairly standard across Verilog tools while -I
|
||||
is an alias for GCC compatibility.
|
||||
|
||||
Verilator defaults to the current directory ("-y .") and any specified
|
||||
--Mdir, though these default paths are used after any user specified
|
||||
directories. This allows '-y "$(pwd)"' to be used if absolute filenames
|
||||
are desired for error messages instead of relative filenames.
|
||||
|
||||
=back
|
||||
|
||||
@@ -1308,10 +1313,13 @@ example:
|
||||
|
||||
Vtop *top; // Instantiation of module
|
||||
|
||||
unsigned int main_time = 0; // Current simulation time
|
||||
vluint64_t main_time = 0; // Current simulation time
|
||||
// This is a 64-bit integer to reduce wrap over issues and
|
||||
// allow modulus. You can also use a double, if you wish.
|
||||
|
||||
double sc_time_stamp () { // Called by $time in Verilog
|
||||
return main_time;
|
||||
return main_time; // converts to double, to match
|
||||
// what SystemC does
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
@@ -1682,6 +1690,18 @@ Verilator currently has some support for SystemVerilog 2009 synthesis
|
||||
constructs. As SystemVerilog features enter common usage they are added;
|
||||
please file a bug if a feature you need is missing.
|
||||
|
||||
=head2 Verilog AMS Support
|
||||
|
||||
Verilator implements a very small subset of Verilog AMS (Verilog Analog and
|
||||
Mixed-Signal Extensions) with the subset corresponding to those VMS
|
||||
keywords with near equivelents in the Verilog 2005 or SystemVerilog 2009
|
||||
languages.
|
||||
|
||||
AMS parsing is enabled with "--language VAMS" or "--language 1800+VAMS".
|
||||
|
||||
At present Verilator implements ceil, exp, floor, ln, log, pow, sqrt,
|
||||
string, and wreal.
|
||||
|
||||
=head2 Sugar/PSL Support
|
||||
|
||||
Most future work is being directed towards improving SystemVerilog
|
||||
@@ -2030,6 +2050,15 @@ should be declared in SystemC as a sc_clock instead of a bool. This was
|
||||
needed in SystemC 1.1 and 1.2 only; versions 2.0 and later do not require
|
||||
clock pins to be sc_clocks and this is no longer needed.
|
||||
|
||||
=item /*verilator sc_bv*/
|
||||
|
||||
Used after a port declaration. It sets the port to be of sc_bv<I<width>>
|
||||
type, instead of bool, vluint32_t or vluint64_t. This may be useful if
|
||||
the port width is parametrized and different of such modules interface
|
||||
a templated module (such as a transactor) or for other reasons. In general
|
||||
you should avoid using this attribute when not necessary as with increasing
|
||||
usage of sc_bv the performance increases significantly.
|
||||
|
||||
=item /*verilator sformat*/
|
||||
|
||||
Attached to the final input of a function or task "input string" to
|
||||
@@ -2377,6 +2406,17 @@ List of all warnings:
|
||||
|
||||
=over 4
|
||||
|
||||
=item ASSIGNIN
|
||||
|
||||
Error that an assignment is being made to an input signal. This is almost
|
||||
certainly a mistake, though technically legal.
|
||||
|
||||
input a;
|
||||
assign a = 1'b1;
|
||||
|
||||
Ignoring this warning will only suppress the lint check, it will simulate
|
||||
correctly.
|
||||
|
||||
=item ASSIGNDLY
|
||||
|
||||
Warns that you have an assignment statement with a delayed time in front of
|
||||
@@ -2962,6 +3002,11 @@ One limit is that you cannot under either license release a commercial
|
||||
Verilog simulation product incorporating Verilator without making the
|
||||
source code available.
|
||||
|
||||
As is standard with Open Source, contributions back to Verilator will be
|
||||
placed under the Verilator copyright and LGPL/Artistic license. Small test
|
||||
cases will be released into the public domain so they can be used anywhere,
|
||||
large tests under the LGPL/Artistic, unless requested otherwise.
|
||||
|
||||
=item Why is Verilation so slow?
|
||||
|
||||
Verilator needs more memory than the resulting simulator will require, as
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
# 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.
|
||||
|
||||
AC_INIT([Verilator],[3.823 2011/10/20])
|
||||
AC_INIT([Verilator],[3.830])
|
||||
AC_CONFIG_HEADER(src/config_build.h)
|
||||
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk)
|
||||
|
||||
|
||||
@@ -333,7 +333,9 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'g': {
|
||||
const int lbits = va_arg(ap, int);
|
||||
double d = va_arg(ap, double);
|
||||
if (lbits) {} // UNUSED - always 64
|
||||
strncpy(tmpf, pctp, pos-pctp+1);
|
||||
tmpf[pos-pctp+1] = '\0';
|
||||
sprintf(tmp, tmpf, d);
|
||||
@@ -596,6 +598,17 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||
VL_SET_WQ(owp,ld);
|
||||
break;
|
||||
}
|
||||
case 'f':
|
||||
case 'e':
|
||||
case 'g': { // Real number
|
||||
_vl_vsss_skipspace(fp,floc,fromp);
|
||||
_vl_vsss_read(fp,floc,fromp, tmp, "+-.0123456789eE");
|
||||
if (!tmp[0]) goto done;
|
||||
union { double r; vlsint64_t ld; } u;
|
||||
u.r = strtod(tmp, NULL);
|
||||
VL_SET_WQ(owp,u.ld);
|
||||
break;
|
||||
}
|
||||
case 't': // FALLTHRU // Time
|
||||
case 'u': { // Unsigned decimal
|
||||
_vl_vsss_skipspace(fp,floc,fromp);
|
||||
@@ -924,6 +937,17 @@ void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
|
||||
}
|
||||
}
|
||||
|
||||
IData VL_SYSTEM_IQ(QData lhs) {
|
||||
IData lhsw[2]; VL_SET_WQ(lhsw, lhs);
|
||||
return VL_SYSTEM_IW(2, lhsw);
|
||||
}
|
||||
IData VL_SYSTEM_IW(int lhswords, WDataInP filenamep) {
|
||||
char filenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
|
||||
_VL_VINT_TO_STRING(lhswords*VL_WORDSIZE, filenamez, filenamep);
|
||||
int code = system(filenamez);
|
||||
return code >> 8; // Want exit status
|
||||
}
|
||||
|
||||
IData VL_TESTPLUSARGS_I(const char* formatp) {
|
||||
string match = VerilatedImp::argPlusMatch(formatp);
|
||||
if (match == "") return 0;
|
||||
|
||||
@@ -349,6 +349,10 @@ extern IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...);
|
||||
|
||||
extern void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...);
|
||||
|
||||
extern IData VL_SYSTEM_IW(int lhsnwords, WDataInP lhs);
|
||||
extern IData VL_SYSTEM_IQ(QData lhs);
|
||||
inline IData VL_SYSTEM_II(IData lhs) { return VL_SYSTEM_IQ(lhs); }
|
||||
|
||||
extern IData VL_TESTPLUSARGS_I(const char* formatp);
|
||||
extern IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rwp);
|
||||
extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish
|
||||
|
||||
+2
-1
@@ -215,6 +215,7 @@ public:
|
||||
VAR_PUBLIC_FLAT_RD, // V3LinkParse moves to AstVar::sigPublic
|
||||
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
|
||||
};
|
||||
enum en m_e;
|
||||
@@ -223,7 +224,7 @@ public:
|
||||
"%E-AT", "EXPR_BITS", "VAR_BASE",
|
||||
"VAR_CLOCK", "VAR_CLOCK_ENABLE", "VAR_PUBLIC",
|
||||
"VAR_PUBLIC_FLAT", "VAR_PUBLIC_FLAT_RD","VAR_PUBLIC_FLAT_RW",
|
||||
"VAR_ISOLATE_ASSIGNMENTS", "VAR_SFORMAT"
|
||||
"VAR_ISOLATE_ASSIGNMENTS", "VAR_SC_BV", "VAR_SFORMAT"
|
||||
};
|
||||
return names[m_e];
|
||||
};
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ bool AstVar::isScQuad() const {
|
||||
}
|
||||
|
||||
bool AstVar::isScBv() const {
|
||||
return (isSc() && width() >= v3Global.opt.pinsBv());
|
||||
return ((isSc() && width() >= v3Global.opt.pinsBv()) || m_attrScBv);
|
||||
}
|
||||
|
||||
void AstVar::combineType(AstVarType type) {
|
||||
|
||||
+51
-1
@@ -587,6 +587,7 @@ private:
|
||||
bool m_funcLocal:1; // Local variable for a function
|
||||
bool m_funcReturn:1; // Return variable for a function
|
||||
bool m_attrClockEn:1;// User clock enable attribute
|
||||
bool m_attrScBv:1; // User force bit vector attribute
|
||||
bool m_attrIsolateAssign:1;// User isolate_assignments attribute
|
||||
bool m_attrSFormat:1;// User sformat attribute
|
||||
bool m_fileDescr:1; // File descriptor
|
||||
@@ -601,7 +602,7 @@ private:
|
||||
m_usedClock=false; m_usedParam=false; m_usedLoopIdx=false;
|
||||
m_sigPublic=false; m_sigModPublic=false; m_sigUserRdPublic=false; m_sigUserRWPublic=false;
|
||||
m_funcLocal=false; m_funcReturn=false;
|
||||
m_attrClockEn=false; m_attrIsolateAssign=false; m_attrSFormat=false;
|
||||
m_attrClockEn=false; m_attrScBv=false; m_attrIsolateAssign=false; m_attrSFormat=false;
|
||||
m_fileDescr=false; m_isConst=false; m_isStatic=false;
|
||||
m_trace=false;
|
||||
}
|
||||
@@ -664,6 +665,7 @@ public:
|
||||
void attrClockEn(bool flag) { m_attrClockEn = flag; }
|
||||
void attrFileDescr(bool flag) { m_fileDescr = flag; }
|
||||
void attrScClocked(bool flag) { m_scClocked = flag; }
|
||||
void attrScBv(bool flag) { m_attrScBv = flag; }
|
||||
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
|
||||
void attrSFormat(bool flag) { m_attrSFormat = flag; }
|
||||
void usedClock(bool flag) { m_usedClock = flag; }
|
||||
@@ -724,6 +726,7 @@ public:
|
||||
bool isFuncLocal() const { return m_funcLocal; }
|
||||
bool isFuncReturn() const { return m_funcReturn; }
|
||||
bool attrClockEn() const { return m_attrClockEn; }
|
||||
bool attrScBv() const { return m_attrScBv; }
|
||||
bool attrFileDescr() const { return m_fileDescr; }
|
||||
bool attrScClocked() const { return m_scClocked; }
|
||||
bool attrSFormat() const { return m_attrSFormat; }
|
||||
@@ -970,6 +973,14 @@ struct AstModule : public AstNodeModule {
|
||||
virtual string verilogKwd() const { return "module"; }
|
||||
};
|
||||
|
||||
struct AstNotFoundModule : public AstNodeModule {
|
||||
// A missing module declaration
|
||||
AstNotFoundModule(FileLine* fl, const string& name)
|
||||
: AstNodeModule (fl,name) {}
|
||||
ASTNODE_NODE_FUNCS(NotFoundModule, NOTFOUNDMODULE)
|
||||
virtual string verilogKwd() const { return "/*not-found-*/ module"; }
|
||||
};
|
||||
|
||||
struct AstPackage : public AstNodeModule {
|
||||
// A package declaration
|
||||
AstPackage(FileLine* fl, const string& name)
|
||||
@@ -1884,6 +1895,45 @@ public:
|
||||
AstNode* msbp() const { return op4p()->castNode(); }
|
||||
};
|
||||
|
||||
struct AstSystemT : public AstNodeStmt {
|
||||
// $system used as task
|
||||
AstSystemT(FileLine* fileline, AstNode* lhsp)
|
||||
: AstNodeStmt (fileline) {
|
||||
setOp1p(lhsp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(SystemT, SYSTEMT)
|
||||
virtual string verilogKwd() const { return "$system"; }
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual bool isPredictOptimizable() const { return false; }
|
||||
virtual bool isSplittable() const { return false; }
|
||||
virtual bool isOutputter() const { return true; }
|
||||
virtual bool isUnlikely() const { return true; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode* samep) const { return true; }
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
};
|
||||
|
||||
struct AstSystemF : public AstNodeMath {
|
||||
// $system used as function
|
||||
AstSystemF(FileLine* fileline, AstNode* lhsp)
|
||||
: AstNodeMath (fileline) {
|
||||
setOp1p(lhsp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(SystemF, SYSTEMF)
|
||||
virtual string verilogKwd() const { return "$system"; }
|
||||
virtual string emitVerilog() { return verilogKwd(); }
|
||||
virtual string emitC() { return "VL_SYSTEM_%nq(%lw, %P)"; }
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual bool isPredictOptimizable() const { return false; }
|
||||
virtual bool isSplittable() const { return false; }
|
||||
virtual bool isOutputter() const { return true; }
|
||||
virtual bool isUnlikely() const { return true; }
|
||||
virtual bool cleanOut() { return true; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode* samep) const { return true; }
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
};
|
||||
|
||||
struct AstValuePlusArgs : public AstNodeMath {
|
||||
// Parents: expr
|
||||
// Child: variable to set. If NULL then this is a $test$plusargs instead of $value$plusargs
|
||||
|
||||
@@ -361,6 +361,30 @@ public:
|
||||
puts(")); }\n");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSystemT* nodep, AstNUser*) {
|
||||
puts("(void)VL_SYSTEM_I");
|
||||
emitIQW(nodep->lhsp());
|
||||
puts("(");
|
||||
if (nodep->lhsp()->isWide()) {
|
||||
puts(cvtToStr(nodep->lhsp()->widthWords()));
|
||||
putbs(", ");
|
||||
}
|
||||
checkMaxWords(nodep->lhsp());
|
||||
nodep->lhsp()->iterateAndNext(*this);
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstSystemF* nodep, AstNUser*) {
|
||||
puts("VL_SYSTEM_I");
|
||||
emitIQW(nodep->lhsp());
|
||||
puts("(");
|
||||
if (nodep->lhsp()->isWide()) {
|
||||
puts(cvtToStr(nodep->lhsp()->widthWords()));
|
||||
putbs(", ");
|
||||
}
|
||||
checkMaxWords(nodep->lhsp());
|
||||
nodep->lhsp()->iterateAndNext(*this);
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstJumpGo* nodep, AstNUser*) {
|
||||
puts("goto __Vlabel"+cvtToStr(nodep->labelp()->labelNum())+";\n");
|
||||
}
|
||||
|
||||
+25
-23
@@ -34,11 +34,6 @@
|
||||
//======================================================================
|
||||
// Statics
|
||||
|
||||
map<string,int> FileLine::s_namemap;
|
||||
deque<string> FileLine::s_names;
|
||||
// s_defaultFileLine must be after s_name* initializer and in same .cpp file
|
||||
FileLine FileLine::s_defaultFileLine = FileLine(EmptySecret());
|
||||
|
||||
int V3Error::s_errCount = 0;
|
||||
int V3Error::s_warnCount = 0;
|
||||
int V3Error::s_debugDefault = 0;
|
||||
@@ -69,13 +64,28 @@ V3ErrorCode::V3ErrorCode(const char* msgp) {
|
||||
m_e = V3ErrorCode::EC_ERROR;
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// FileLineSingleton class functions
|
||||
|
||||
int FileLineSingleton::nameToNumber(const string& filename) {
|
||||
// Convert filenames to a filenameno
|
||||
// This lets us assign a nice small identifier for debug messages, but more
|
||||
// importantly lets us use a 4 byte int instead of 8 byte pointer in every FileLine.
|
||||
map<string,int>::const_iterator iter = m_namemap.find(filename);
|
||||
if (VL_LIKELY(iter != m_namemap.end())) return iter->second;
|
||||
int num = m_names.size();
|
||||
m_names.push_back(filename);
|
||||
m_namemap.insert(make_pair(filename,num));
|
||||
return num;
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// FileLine class functions
|
||||
|
||||
FileLine::FileLine(FileLine::EmptySecret) {
|
||||
// Sort of a singleton
|
||||
m_lineno=0;
|
||||
m_filenameno=nameToNumber("AstRoot");
|
||||
m_filenameno=singleton().nameToNumber("AstRoot");
|
||||
|
||||
m_warnOn=0;
|
||||
for (int codei=V3ErrorCode::EC_MIN; codei<V3ErrorCode::_ENUM_MAX; codei++) {
|
||||
@@ -84,18 +94,6 @@ FileLine::FileLine(FileLine::EmptySecret) {
|
||||
}
|
||||
}
|
||||
|
||||
int FileLine::nameToNumber(const string& filename) {
|
||||
// Convert filenames to a filenameno
|
||||
// This lets us assign a nice small identifier for debug messages, but more
|
||||
// importantly lets us use a 4 byte int instead of 8 byte pointer in every FileLine.
|
||||
map<string,int>::const_iterator iter = s_namemap.find(filename);
|
||||
if (VL_LIKELY(iter != s_namemap.end())) return iter->second;
|
||||
int num = s_names.size();
|
||||
s_names.push_back(filename);
|
||||
s_namemap.insert(make_pair(filename,num));
|
||||
return num;
|
||||
}
|
||||
|
||||
const string FileLine::filenameLetters() const {
|
||||
const int size = 1 + (64 / 4); // Each letter retires more than 4 bits of a > 64 bit number
|
||||
char out[size];
|
||||
@@ -291,8 +289,7 @@ void FileLine::deleteAllRemaining() {
|
||||
// Eventually the list will be empty and terminate the loop.
|
||||
}
|
||||
fileLineLeakChecks.clear();
|
||||
s_names.clear();
|
||||
s_namemap.clear();
|
||||
FileLineSingleton::clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -335,13 +332,18 @@ void V3Error::incErrors() {
|
||||
|
||||
void V3Error::abortIfErrors() {
|
||||
if (errorCount()) {
|
||||
v3fatal ("Exiting due to "<<dec<<errorOrWarnCount()<<" warning(s)\n");
|
||||
abortIfWarnings();
|
||||
}
|
||||
}
|
||||
|
||||
void V3Error::abortIfWarnings() {
|
||||
if (v3Global.opt.warnFatal() ? errorOrWarnCount() : errorCount()) {
|
||||
v3fatal ("Exiting due to "<<dec<<errorOrWarnCount()<<" warning(s)\n");
|
||||
bool exwarn = v3Global.opt.warnFatal() && warnCount();
|
||||
if (errorCount() && exwarn) {
|
||||
v3fatal ("Exiting due to "<<dec<<errorCount()<<" error(s), "<<warnCount()<<" warning(s)\n");
|
||||
} else if (errorCount()) {
|
||||
v3fatal ("Exiting due to "<<dec<<errorCount()<<" error(s)\n");
|
||||
} else if (exwarn) {
|
||||
v3fatal ("Exiting due to "<<dec<<warnCount()<<" warning(s)\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+34
-21
@@ -48,14 +48,15 @@ public:
|
||||
I_LINT, // All lint messages
|
||||
I_DEF_NETTYPE_WIRE, // `default_nettype is WIRE (false=NONE)
|
||||
// Error codes:
|
||||
E_BLKLOOPINIT, // Error: Delayed assignment to array inside for loops
|
||||
E_MULTITOP, // Error: Multiple top level modules
|
||||
E_TASKNSVAR, // Error: Task I/O not simple
|
||||
E_BLKLOOPINIT, // Error: Delayed assignment to array inside for loops
|
||||
//
|
||||
// Warning codes:
|
||||
EC_FIRST_WARN, // Just a code so the program knows where to start warnings
|
||||
//
|
||||
ASSIGNDLY, // Assignment delays
|
||||
ASSIGNIN, // Assigning to input
|
||||
BLKANDNBLK, // Blocked and non-blocking assignments to same variable
|
||||
BLKSEQ, // Blocking assignments in sequential block
|
||||
CASEINCOMPLETE, // Case statement has missing values
|
||||
@@ -105,10 +106,10 @@ public:
|
||||
// Boolean
|
||||
" I_COVERAGE", " I_TRACING", " I_LINT", " I_DEF_NETTYPE_WIRE",
|
||||
// Errors
|
||||
"MULTITOP", "TASKNSVAR", "BLKLOOPINIT",
|
||||
"BLKLOOPINIT", "MULTITOP", "TASKNSVAR",
|
||||
// Warnings
|
||||
" EC_FIRST_WARN",
|
||||
"ASSIGNDLY",
|
||||
"ASSIGNDLY", "ASSIGNIN",
|
||||
"BLKANDNBLK", "BLKSEQ",
|
||||
"CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CDCRSTLOGIC", "CMPCONST",
|
||||
"COMBDLY", "DEFPARAM", "DECLFILENAME",
|
||||
@@ -130,7 +131,8 @@ public:
|
||||
bool dangerous() const { return ( m_e==COMBDLY ); }
|
||||
// Warnings we'll present to the user as errors
|
||||
// Later -Werror- options may make more of these.
|
||||
bool pretendError() const { return ( m_e==BLKANDNBLK || m_e==IMPURE || m_e==MODDUP || m_e==SYMRSVDWORD); }
|
||||
bool pretendError() const { return ( m_e==ASSIGNIN || m_e==BLKANDNBLK
|
||||
|| m_e==IMPURE || m_e==MODDUP || m_e==SYMRSVDWORD); }
|
||||
// Warnings to mention manual
|
||||
bool mentionManual() const { return ( m_e==EC_FATALSRC || pretendError() ); }
|
||||
|
||||
@@ -252,8 +254,17 @@ inline uint32_t cvtToHash(void* vp) {
|
||||
class FileLine;
|
||||
|
||||
class FileLineSingleton {
|
||||
map<string,int> m_namemap; // filenameno for each filename
|
||||
deque<string> m_names; // filename text for each filenameno
|
||||
// COSNTRUCTORS
|
||||
FileLineSingleton() { }
|
||||
~FileLineSingleton() { }
|
||||
protected:
|
||||
friend class FileLine;
|
||||
// METHODS
|
||||
int nameToNumber(const string& filename);
|
||||
string numberToName(int filenameno) { return m_names[filenameno]; }
|
||||
void clear() { m_namemap.clear(); m_names.clear(); }
|
||||
};
|
||||
|
||||
class FileLine {
|
||||
@@ -263,31 +274,33 @@ class FileLine {
|
||||
bitset<V3ErrorCode::_ENUM_MAX> m_warnOn;
|
||||
// Consider moving opt.language() into here, so can know language per-node
|
||||
|
||||
static map<string,int> s_namemap; // filenameno for each filename
|
||||
static deque<string> s_names; // filename text for each filenameno
|
||||
static FileLine s_defaultFileLine;
|
||||
|
||||
static int nameToNumber(const string& filename);
|
||||
static string numberToName(int filenameno) { return s_names[filenameno]; }
|
||||
|
||||
private:
|
||||
struct EmptySecret {};
|
||||
|
||||
inline static FileLineSingleton& singleton() {
|
||||
static FileLineSingleton s;
|
||||
return s;
|
||||
}
|
||||
inline static FileLine& defaultFileLine() {
|
||||
static FileLine* defFilelinep = new FileLine(FileLine::EmptySecret());
|
||||
return *defFilelinep;
|
||||
}
|
||||
protected:
|
||||
// User routines should never need to change line numbers
|
||||
// We are storing pointers, so we CAN'T change them after initial reading.
|
||||
friend class FileLineSingleton;
|
||||
friend class V3ParseImp;
|
||||
friend class V3PreLex;
|
||||
friend class V3PreProcImp;
|
||||
void lineno(int num) { m_lineno = num; }
|
||||
void filename(const string& name) { m_filenameno = nameToNumber(name); }
|
||||
void filename(const string& name) { m_filenameno = singleton().nameToNumber(name); }
|
||||
void lineDirective(const char* textp, int& enterExitRef);
|
||||
void linenoInc() { m_lineno++; }
|
||||
void linenoIncInPlace() { m_lineno++; }
|
||||
FileLine* copyOrSameFileLine();
|
||||
public:
|
||||
FileLine (const string& filename, int lineno) {
|
||||
m_lineno=lineno; m_filenameno = nameToNumber(filename);
|
||||
m_warnOn=s_defaultFileLine.m_warnOn; }
|
||||
m_lineno=lineno; m_filenameno = singleton().nameToNumber(filename);
|
||||
m_warnOn=defaultFileLine().m_warnOn; }
|
||||
FileLine (FileLine* fromp) {
|
||||
m_lineno=fromp->m_lineno; m_filenameno = fromp->m_filenameno; m_warnOn=fromp->m_warnOn; }
|
||||
FileLine (EmptySecret);
|
||||
@@ -302,7 +315,7 @@ public:
|
||||
|
||||
int lineno () const { return m_lineno; }
|
||||
string ascii() const;
|
||||
const string filename () const { return numberToName(m_filenameno); }
|
||||
const string filename () const { return singleton().numberToName(m_filenameno); }
|
||||
const string filenameLetters() const;
|
||||
const string filebasename () const;
|
||||
const string filebasenameNoExt () const;
|
||||
@@ -315,7 +328,7 @@ public:
|
||||
void warnLintOff(bool flag);
|
||||
void warnStyleOff(bool flag);
|
||||
void warnStateFrom(const FileLine& from) { m_warnOn=from.m_warnOn; }
|
||||
void warnResetDefault() { warnStateFrom(s_defaultFileLine); }
|
||||
void warnResetDefault() { warnStateFrom(defaultFileLine()); }
|
||||
|
||||
// Specific flag ACCESSORS/METHODS
|
||||
bool coverageOn() const { return m_warnOn.test(V3ErrorCode::I_COVERAGE); }
|
||||
@@ -325,13 +338,13 @@ public:
|
||||
|
||||
// METHODS - Global
|
||||
static void globalWarnLintOff(bool flag) {
|
||||
s_defaultFileLine.warnLintOff(flag); }
|
||||
defaultFileLine().warnLintOff(flag); }
|
||||
static void globalWarnStyleOff(bool flag) {
|
||||
s_defaultFileLine.warnStyleOff(flag); }
|
||||
defaultFileLine().warnStyleOff(flag); }
|
||||
static void globalWarnOff(V3ErrorCode code, bool flag) {
|
||||
s_defaultFileLine.warnOff(code, flag); }
|
||||
defaultFileLine().warnOff(code, flag); }
|
||||
static bool globalWarnOff(const string& code, bool flag) {
|
||||
return s_defaultFileLine.warnOff(code, flag); }
|
||||
return defaultFileLine().warnOff(code, flag); }
|
||||
|
||||
// METHODS - Called from netlist
|
||||
// Merge warning disables from another fileline
|
||||
|
||||
+6
-1
@@ -563,8 +563,13 @@ private:
|
||||
nodep->v3fatalSrc("Cell has unlinked module"); // V3LinkCell should have errored out
|
||||
}
|
||||
else {
|
||||
if (nodep->modp()->castNotFoundModule()) {
|
||||
// Prevent warnings about missing pin connects
|
||||
if (nodep->pinsp()) nodep->pinsp()->unlinkFrBackWithNext()->deleteTree();
|
||||
if (nodep->paramsp()) nodep->paramsp()->unlinkFrBackWithNext()->deleteTree();
|
||||
}
|
||||
// Need to pass the module info to this cell, so we can link up the pin names
|
||||
if (m_idState==ID_RESOLVE) {
|
||||
else if (m_idState==ID_RESOLVE) {
|
||||
m_cellVarsp = nodep->modp()->user4p()->castSymTable();
|
||||
UINFO(4,"(Backto) Link Cell: "<<nodep<<endl);
|
||||
//if (debug()) { nodep->dumpTree(cout,"linkcell:"); }
|
||||
|
||||
+12
-2
@@ -135,7 +135,15 @@ private:
|
||||
AstNodeModule* modp = vvertexp->modp();
|
||||
modp->level(vvertexp->rank()+1);
|
||||
if (vvertexp == m_topVertexp && modp->level() != 2) {
|
||||
v3error("Specified --top-module '"<<v3Global.opt.topModule()<<"' isn't at the top level, it's under another cell.");
|
||||
AstNodeModule* abovep = NULL;
|
||||
if (V3GraphEdge* edgep = vvertexp->inBeginp()) {
|
||||
if (LinkCellsVertex* eFromVertexp = dynamic_cast<LinkCellsVertex*>(edgep->fromp())) {
|
||||
abovep = eFromVertexp->modp();
|
||||
}
|
||||
}
|
||||
v3error("Specified --top-module '"<<v3Global.opt.topModule()
|
||||
<<"' isn't at the top level, it's under another cell '"
|
||||
<<(abovep ? abovep->prettyName() : "UNKNOWN")<<"'");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -176,8 +184,10 @@ private:
|
||||
AstNodeModule* modp = m_mods.findIdUpward(nodep->modName())->castNodeModule();
|
||||
if (!modp) {
|
||||
// Read-subfile
|
||||
// If file not found, make AstNotFoundModule, rather than error out.
|
||||
// We'll throw the error when we know the module will really be needed.
|
||||
V3Parse parser (v3Global.rootp(), m_filterp);
|
||||
parser.parseFile(nodep->fileline(), nodep->modName(), false);
|
||||
parser.parseFile(nodep->fileline(), nodep->modName(), false, "");
|
||||
V3Error::abortIfErrors();
|
||||
// We've read new modules, grab new pointers to their names
|
||||
readModNames();
|
||||
|
||||
+7
-2
@@ -47,7 +47,7 @@ private:
|
||||
typedef vector<AstBegin*> BeginStack;
|
||||
|
||||
// STATE
|
||||
AstModule* m_modp; // Current module
|
||||
AstNodeModule* m_modp; // Current module
|
||||
AstNodeFTask* m_ftaskp; // Current function/task
|
||||
AstWhile* m_loopp; // Current loop
|
||||
bool m_loopInc; // In loop increment
|
||||
@@ -82,6 +82,11 @@ private:
|
||||
nodep->v3fatalSrc("Unknown jump point for break/disable/continue");
|
||||
return NULL;
|
||||
}
|
||||
// Skip over variables as we'll just move them in a momement
|
||||
// Also this would otherwise prevent us from using a label twice
|
||||
// see t_func_return test.
|
||||
while (underp && underp->castVar()) underp = underp->nextp();
|
||||
if (underp) UINFO(5," Underpoint is "<<underp<<endl);
|
||||
|
||||
if (!underp) {
|
||||
nodep->v3fatalSrc("Break/disable/continue not under expected statement");
|
||||
@@ -109,7 +114,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
m_modp = nodep;
|
||||
m_repeatNum = 0;
|
||||
nodep->iterateChildren(*this);
|
||||
|
||||
@@ -65,7 +65,7 @@ private:
|
||||
if (nodep->varp()) {
|
||||
if (nodep->lvalue() && nodep->varp()->isInOnly()) {
|
||||
if (!m_ftaskp) {
|
||||
nodep->v3error("Assigning to input variable: "<<nodep->prettyName());
|
||||
nodep->v3warn(ASSIGNIN,"Assigning to input variable: "<<nodep->prettyName());
|
||||
}
|
||||
}
|
||||
if (nodep->lvalue() && nodep->varp()->isConst()
|
||||
|
||||
@@ -326,6 +326,11 @@ private:
|
||||
m_varp->attrSFormat(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_SC_BV) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
m_varp->attrScBv(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstAlwaysPublic* nodep, AstNUser*) {
|
||||
|
||||
+86
-45
@@ -51,17 +51,29 @@ struct V3OptionsImp {
|
||||
|
||||
// STATE
|
||||
list<string> m_allArgs; // List of every argument encountered
|
||||
list<string> m_incDirs; // Include directories (ordered)
|
||||
set<string> m_incDirSet; // Include directories (for removing duplicates)
|
||||
list<string> m_incDirUsers; // Include directories (ordered)
|
||||
set<string> m_incDirUserSet; // Include directories (for removing duplicates)
|
||||
list<string> m_incDirFallbacks; // Include directories (ordered)
|
||||
set<string> m_incDirFallbackSet; // Include directories (for removing duplicates)
|
||||
list<string> m_libExts; // Library extensions (ordered)
|
||||
set<string> m_libExtSet; // Library extensions (for removing duplicates)
|
||||
DirMap m_dirMap; // Directory listing
|
||||
|
||||
// ACCESSOR METHODS
|
||||
void addIncDir(const string& incdir) {
|
||||
if (m_incDirSet.find(incdir) == m_incDirSet.end()) {
|
||||
m_incDirSet.insert(incdir);
|
||||
m_incDirs.push_back(incdir);
|
||||
void addIncDirUser(const string& incdir) {
|
||||
if (m_incDirUserSet.find(incdir) == m_incDirUserSet.end()) {
|
||||
m_incDirUserSet.insert(incdir);
|
||||
m_incDirUsers.push_back(incdir);
|
||||
m_incDirFallbacks.remove(incdir); // User has priority over Fallback
|
||||
m_incDirFallbackSet.erase(incdir); // User has priority over Fallback
|
||||
}
|
||||
}
|
||||
void addIncDirFallback(const string& incdir) {
|
||||
if (m_incDirUserSet.find(incdir) == m_incDirUserSet.end()) { // User has priority over Fallback
|
||||
if (m_incDirFallbackSet.find(incdir) == m_incDirFallbackSet.end()) {
|
||||
m_incDirFallbackSet.insert(incdir);
|
||||
m_incDirFallbacks.push_back(incdir);
|
||||
}
|
||||
}
|
||||
}
|
||||
void addLibExt(const string& libext) {
|
||||
@@ -73,8 +85,11 @@ struct V3OptionsImp {
|
||||
V3OptionsImp() {}
|
||||
};
|
||||
|
||||
void V3Options::addIncDir(const string& incdir) {
|
||||
m_impp->addIncDir(incdir);
|
||||
void V3Options::addIncDirUser(const string& incdir) {
|
||||
m_impp->addIncDirUser(incdir);
|
||||
}
|
||||
void V3Options::addIncDirFallback(const string& incdir) {
|
||||
m_impp->addIncDirFallback(incdir);
|
||||
}
|
||||
void V3Options::addLibExt(const string& libext) {
|
||||
m_impp->addLibExt(libext);
|
||||
@@ -288,42 +303,68 @@ string V3Options::fileExists (const string& filename) {
|
||||
return filenameOut;
|
||||
}
|
||||
|
||||
string V3Options::filePath (FileLine* fl, const string& modname, const string& errmsg) {
|
||||
// Find a filename to read the specified module name,
|
||||
// using the incdir and libext's.
|
||||
// Return "" if not found.
|
||||
for (list<string>::iterator dirIter=m_impp->m_incDirs.begin(); dirIter!=m_impp->m_incDirs.end(); ++dirIter) {
|
||||
for (list<string>::iterator extIter=m_impp->m_libExts.begin(); extIter!=m_impp->m_libExts.end(); ++extIter) {
|
||||
string fn = filenameFromDirBase(*dirIter,modname+*extIter);
|
||||
string exists = fileExists(fn);
|
||||
if (exists!="") {
|
||||
// Strip ./, it just looks ugly
|
||||
if (exists.substr(0,2)=="./") exists.erase(0,2);
|
||||
return exists;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Warn and return not found
|
||||
fl->v3error(errmsg+modname);
|
||||
static bool shown_notfound_msg = false;
|
||||
if (!shown_notfound_msg) {
|
||||
shown_notfound_msg = true;
|
||||
if (m_impp->m_incDirs.empty()) {
|
||||
fl->v3error("This may be because there's no search path specified with -I<dir>."<<endl);
|
||||
} else {
|
||||
fl->v3error("Looked in:"<<endl);
|
||||
for (list<string>::iterator dirIter=m_impp->m_incDirs.begin(); dirIter!=m_impp->m_incDirs.end(); ++dirIter) {
|
||||
for (list<string>::iterator extIter=m_impp->m_libExts.begin(); extIter!=m_impp->m_libExts.end(); ++extIter) {
|
||||
string fn = filenameFromDirBase(*dirIter,modname+*extIter);
|
||||
fl->v3error(" "<<fn<<endl);
|
||||
}
|
||||
}
|
||||
string V3Options::filePathCheckOneDir(const string& modname, const string& dirname) {
|
||||
for (list<string>::iterator extIter=m_impp->m_libExts.begin(); extIter!=m_impp->m_libExts.end(); ++extIter) {
|
||||
string fn = filenameFromDirBase(dirname, modname+*extIter);
|
||||
string exists = fileExists(fn);
|
||||
if (exists!="") {
|
||||
// Strip ./, it just looks ugly
|
||||
if (exists.substr(0,2)=="./") exists.erase(0,2);
|
||||
return exists;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
string V3Options::filePath (FileLine* fl, const string& modname,
|
||||
const string& errmsg) { // Error prefix or "" to suppress error
|
||||
// Find a filename to read the specified module name,
|
||||
// using the incdir and libext's.
|
||||
// Return "" if not found.
|
||||
for (list<string>::iterator dirIter=m_impp->m_incDirUsers.begin();
|
||||
dirIter!=m_impp->m_incDirUsers.end(); ++dirIter) {
|
||||
string exists = filePathCheckOneDir(modname, *dirIter);
|
||||
if (exists!="") return exists;
|
||||
}
|
||||
for (list<string>::iterator dirIter=m_impp->m_incDirFallbacks.begin();
|
||||
dirIter!=m_impp->m_incDirFallbacks.end(); ++dirIter) {
|
||||
string exists = filePathCheckOneDir(modname, *dirIter);
|
||||
if (exists!="") return exists;
|
||||
}
|
||||
|
||||
// Warn and return not found
|
||||
if (errmsg != "") {
|
||||
fl->v3error(errmsg+modname);
|
||||
filePathLookedMsg(fl, modname);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void V3Options::filePathLookedMsg(FileLine* fl, const string& modname) {
|
||||
static bool shown_notfound_msg = false;
|
||||
if (!shown_notfound_msg) {
|
||||
shown_notfound_msg = true;
|
||||
if (m_impp->m_incDirUsers.empty()) {
|
||||
fl->v3error("This may be because there's no search path specified with -I<dir>."<<endl);
|
||||
}
|
||||
fl->v3error("Looked in:"<<endl);
|
||||
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_libExts.begin(); extIter!=m_impp->m_libExts.end(); ++extIter) {
|
||||
string fn = 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_libExts.begin(); extIter!=m_impp->m_libExts.end(); ++extIter) {
|
||||
string fn = filenameFromDirBase(*dirIter,modname+*extIter);
|
||||
fl->v3error(" "<<fn<<endl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void V3Options::unlinkRegexp(const string& dir, const string& regexp) {
|
||||
if (DIR* dirp = opendir(dir.c_str())) {
|
||||
while (struct dirent* direntp = readdir(dirp)) {
|
||||
@@ -566,7 +607,7 @@ void V3Options::parseOpts (FileLine* fl, int argc, char** argv) {
|
||||
if (modPrefix()=="") m_modPrefix = prefix();
|
||||
|
||||
// Find files in makedir
|
||||
addIncDir(makeDir());
|
||||
addIncDirFallback(makeDir());
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
@@ -604,7 +645,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||
addDefine (string (sw+strlen("+define+")));
|
||||
}
|
||||
else if ( !strncmp (sw, "+incdir+", 8)) {
|
||||
addIncDir (parseFileArg(optdir, string (sw+strlen("+incdir+"))));
|
||||
addIncDirUser (parseFileArg(optdir, string (sw+strlen("+incdir+"))));
|
||||
}
|
||||
else if ( !strncmp (sw, "+libext+", 8)) {
|
||||
string exts = string(sw+strlen("+libext+"));
|
||||
@@ -727,7 +768,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||
m_errorLimit = atoi(argv[i]);
|
||||
}
|
||||
else if ( !strncmp (sw, "-I", 2)) {
|
||||
addIncDir (parseFileArg(optdir, string (sw+strlen("-I"))));
|
||||
addIncDirUser (parseFileArg(optdir, string (sw+strlen("-I"))));
|
||||
}
|
||||
else if ( !strcmp (sw, "-if-depth") && (i+1)<argc ) {
|
||||
shift;
|
||||
@@ -752,7 +793,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||
}
|
||||
else if ( !strcmp (sw, "-Mdir") && (i+1)<argc ) {
|
||||
shift; m_makeDir = argv[i];
|
||||
addIncDir (string (m_makeDir)); // Need to find generated files there too
|
||||
addIncDirFallback (string (m_makeDir)); // Need to find generated files there too
|
||||
}
|
||||
else if ( !strcmp (sw, "-o") && (i+1)<argc ) {
|
||||
shift; m_exeName = argv[i];
|
||||
@@ -918,7 +959,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||
}
|
||||
}
|
||||
else if ( !strcmp (sw, "-y") && (i+1)<argc ) {
|
||||
shift; addIncDir (parseFileArg(optdir,string (argv[i])));
|
||||
shift; addIncDirUser (parseFileArg(optdir,string (argv[i])));
|
||||
}
|
||||
else {
|
||||
fl->v3fatal ("Invalid Option: "<<argv[i]);
|
||||
@@ -1133,7 +1174,7 @@ V3Options::V3Options() {
|
||||
addLibExt(".v");
|
||||
addLibExt(".sv");
|
||||
// Default -I
|
||||
addIncDir("."); // Looks better than {long_cwd_path}/...
|
||||
addIncDirFallback("."); // Looks better than {long_cwd_path}/...
|
||||
}
|
||||
|
||||
V3Options::~V3Options() {
|
||||
|
||||
+5
-2
@@ -178,10 +178,11 @@ class V3Options {
|
||||
|
||||
private:
|
||||
// METHODS
|
||||
void addArg(const string& incdir);
|
||||
void addArg(const string& flag);
|
||||
void addDefine(const string& defline);
|
||||
void addFuture(const string& flag);
|
||||
void addIncDir(const string& incdir);
|
||||
void addIncDirUser(const string& incdir); // User requested
|
||||
void addIncDirFallback(const string& incdir); // Low priority if not found otherwise
|
||||
void addLibExt(const string& libext);
|
||||
void optimize(int level);
|
||||
void showVersion(bool verbose);
|
||||
@@ -189,6 +190,7 @@ class V3Options {
|
||||
bool onoff(const char* sw, const char* arg, bool& flag);
|
||||
bool suffixed(const char* sw, const char* arg);
|
||||
string parseFileArg(const string& optdir, const string& relfilename);
|
||||
string filePathCheckOneDir(const string& modname, const string& dirname);
|
||||
|
||||
static bool wildmatchi(const char* s, const char* p);
|
||||
static string getenvStr(const string& envvar, const string& defaultValue);
|
||||
@@ -345,6 +347,7 @@ class V3Options {
|
||||
// METHODS (file utilities using these options)
|
||||
string fileExists (const string& filename);
|
||||
string filePath (FileLine* fl, const string& modname, const string& errmsg);
|
||||
void filePathLookedMsg(FileLine* fl, const string& modname);
|
||||
static bool fileStatDir (const string& filename);
|
||||
static bool fileStatNormal (const string& filename);
|
||||
|
||||
|
||||
+2
-1
@@ -45,7 +45,8 @@ public:
|
||||
|
||||
// METHODS
|
||||
// Preprocess and read the Verilog file specified into the netlist database
|
||||
void parseFile(FileLine* fileline, const string& modname, bool inLibrary);
|
||||
void parseFile(FileLine* fileline, const string& modname, bool inLibrary,
|
||||
const string& errmsg);
|
||||
|
||||
// Push preprocessed text to the lexer
|
||||
static void ppPushText(V3ParseImp* impp, const string& text);
|
||||
|
||||
+13
-4
@@ -89,7 +89,8 @@ size_t V3ParseImp::ppInputToLex(char* buf, size_t max_size) {
|
||||
return got;
|
||||
}
|
||||
|
||||
void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool inLibrary) {
|
||||
void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool inLibrary,
|
||||
const string& errmsg) { // "" for no error, make fake node
|
||||
string modname = V3Options::filenameNonExt(modfilename);
|
||||
|
||||
UINFO(2,__FUNCTION__<<": "<<modname<<(inLibrary?" [LIB]":"")<<endl);
|
||||
@@ -104,7 +105,14 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
|
||||
}
|
||||
|
||||
// Preprocess into m_ppBuffer
|
||||
V3PreShell::preproc(fileline, modfilename, m_filterp, this);
|
||||
bool ok = V3PreShell::preproc(fileline, modfilename, m_filterp, this, errmsg);
|
||||
if (!ok) {
|
||||
if (errmsg != "") return; // Threw error already
|
||||
// Create fake node for later error reporting
|
||||
AstNodeModule* nodep = new AstNotFoundModule(fileline, modname);
|
||||
v3Global.rootp()->addModulep(nodep);
|
||||
return;
|
||||
}
|
||||
|
||||
if (v3Global.opt.preprocOnly() || v3Global.opt.keepTempFiles()) {
|
||||
// Create output file with all the preprocessor output we buffered up
|
||||
@@ -157,8 +165,9 @@ V3Parse::V3Parse(AstNetlist* rootp, V3InFilter* filterp) {
|
||||
V3Parse::~V3Parse() {
|
||||
delete m_impp; m_impp = NULL;
|
||||
}
|
||||
void V3Parse::parseFile(FileLine* fileline, const string& modname, bool inLibrary) {
|
||||
m_impp->parseFile(fileline, modname, inLibrary);
|
||||
void V3Parse::parseFile(FileLine* fileline, const string& modname, bool inLibrary,
|
||||
const string& errmsg) {
|
||||
m_impp->parseFile(fileline, modname, inLibrary, errmsg);
|
||||
}
|
||||
void V3Parse::ppPushText(V3ParseImp* impp, const string& text) {
|
||||
impp->ppPushText(text);
|
||||
|
||||
+2
-1
@@ -333,7 +333,8 @@ public:
|
||||
// Preprocess and read the Verilog file specified into the netlist database
|
||||
int lexToBison(); // Pass token to bison
|
||||
|
||||
void parseFile(FileLine* fileline, const string& modfilename, bool inLibrary);
|
||||
void parseFile(FileLine* fileline, const string& modfilename, bool inLibrary,
|
||||
const string& errmsg);
|
||||
|
||||
private:
|
||||
void lexFile(const string& modname);
|
||||
|
||||
+14
-6
@@ -74,7 +74,8 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
void preproc (FileLine* fl, const string& modname, V3InFilter* filterp, V3ParseImp* parsep) {
|
||||
bool preproc (FileLine* fl, const string& modname, V3InFilter* filterp, V3ParseImp* parsep,
|
||||
const string& errmsg) { // "" for no error
|
||||
debug(true); // Recheck if debug on - first check was before command line passed
|
||||
|
||||
// Preprocess the given module, putting output in vppFilename
|
||||
@@ -82,11 +83,14 @@ protected:
|
||||
|
||||
// Preprocess
|
||||
s_filterp = filterp;
|
||||
preprocOpen(fl, s_filterp, modname, "Cannot find file containing module: ");
|
||||
bool ok = preprocOpen(fl, s_filterp, modname, errmsg);
|
||||
if (!ok) return false;
|
||||
|
||||
while (!s_preprocp->isEof()) {
|
||||
string line = s_preprocp->getline();
|
||||
V3Parse::ppPushText(parsep, line);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void preprocInclude (FileLine* fl, const string& modname) {
|
||||
@@ -96,17 +100,20 @@ protected:
|
||||
preprocOpen(fl, s_filterp, modname, "Cannot find include file: ");
|
||||
}
|
||||
|
||||
void preprocOpen (FileLine* fl, V3InFilter* filterp, const string& modname, const string& errmsg) {
|
||||
bool preprocOpen (FileLine* fl, V3InFilter* filterp, const string& modname,
|
||||
const string& errmsg) { // Error message or "" to suppress
|
||||
// Returns true if successful
|
||||
// Allow user to put `defined names on the command line instead of filenames,
|
||||
// then convert them properly.
|
||||
string ppmodname = s_preprocp->removeDefines (modname);
|
||||
|
||||
// Open include or master file
|
||||
string filename = v3Global.opt.filePath (fl, ppmodname, errmsg);
|
||||
if (filename=="") return; // Not found
|
||||
if (filename=="") return false; // Not found
|
||||
|
||||
UINFO(2," Reading "<<filename<<endl);
|
||||
s_preprocp->openFile(fl, filterp, filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
// CONSTRUCTORS
|
||||
@@ -124,8 +131,9 @@ V3InFilter* V3PreShellImp::s_filterp = NULL;
|
||||
void V3PreShell::boot(char** env) {
|
||||
V3PreShellImp::s_preImp.boot(env);
|
||||
}
|
||||
void V3PreShell::preproc(FileLine* fl, const string& modname, V3InFilter* filterp, V3ParseImp* parsep) {
|
||||
V3PreShellImp::s_preImp.preproc(fl, modname, filterp, parsep);
|
||||
bool V3PreShell::preproc(FileLine* fl, const string& modname, V3InFilter* filterp,
|
||||
V3ParseImp* parsep, const string& errmsg) {
|
||||
return V3PreShellImp::s_preImp.preproc(fl, modname, filterp, parsep, errmsg);
|
||||
}
|
||||
void V3PreShell::preprocInclude(FileLine* fl, const string& modname) {
|
||||
V3PreShellImp::s_preImp.preprocInclude(fl, modname);
|
||||
|
||||
+2
-1
@@ -36,7 +36,8 @@ class V3PreShell {
|
||||
// Static class for calling preprocessor
|
||||
public:
|
||||
static void boot(char** env);
|
||||
static void preproc(FileLine* fileline, const string& module, V3InFilter* filterp, V3ParseImp* parsep);
|
||||
static bool preproc(FileLine* fileline, const string& module, V3InFilter* filterp,
|
||||
V3ParseImp* parsep, const string& errmsg);
|
||||
static void preprocInclude(FileLine* fileline, const string& module);
|
||||
static string dependFiles() { return ""; } // Perl only
|
||||
static void defineCmdLine(const string& name, const string& value);
|
||||
|
||||
+24
-8
@@ -229,6 +229,7 @@ private:
|
||||
|
||||
// STATE
|
||||
bool m_reorder; // Reorder statements vs. just splitting
|
||||
string m_noReorderWhy; // Reason we can't reorder
|
||||
VStack m_stmtStackps; // Current statements being tracked
|
||||
SplitPliVertex* m_pliVertexp; // Element specifying PLI ordering
|
||||
V3Graph m_graph; // Scoreboard of var usages/dependencies
|
||||
@@ -249,6 +250,7 @@ private:
|
||||
m_graph.clear();
|
||||
m_stmtStackps.clear();
|
||||
m_pliVertexp = NULL;
|
||||
m_noReorderWhy = "";
|
||||
AstNode::user1ClearTree();
|
||||
AstNode::user2ClearTree();
|
||||
AstNode::user3ClearTree();
|
||||
@@ -336,6 +338,7 @@ private:
|
||||
}
|
||||
|
||||
// Weak coloring to determine what needs to remain in order
|
||||
// This follows all step-relevant edges excluding PostEdges, which are done later
|
||||
m_graph.weaklyConnected(&SplitEdge::followScoreboard);
|
||||
|
||||
// Add hard orderings between all nodes of same color, in the order they appeared
|
||||
@@ -445,14 +448,18 @@ private:
|
||||
UINFO(9," processBlock "<<nodep<<endl);
|
||||
// Process block and followers
|
||||
scanBlock(nodep);
|
||||
// Reorder statements in this block
|
||||
cleanupBlockGraph(nodep);
|
||||
reorderBlock(nodep);
|
||||
// Delete old vertexes and edges only applying to this block
|
||||
while (firstp->backp()->nextp()==firstp) firstp = firstp->backp(); // Walk back to first in list
|
||||
for (AstNode* nextp=firstp; nextp; nextp=nextp->nextp()) {
|
||||
SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p();
|
||||
vvertexp->unlinkDelete(&m_graph);
|
||||
if (m_noReorderWhy != "") { // Jump or something nasty
|
||||
UINFO(9," NoReorderBlock because "<<m_noReorderWhy<<endl);
|
||||
} else {
|
||||
// Reorder statements in this block
|
||||
cleanupBlockGraph(nodep);
|
||||
reorderBlock(nodep);
|
||||
// Delete old vertexes and edges only applying to this block
|
||||
while (firstp->backp()->nextp()==firstp) firstp = firstp->backp(); // Walk back to first in list
|
||||
for (AstNode* nextp=firstp; nextp; nextp=nextp->nextp()) {
|
||||
SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p();
|
||||
vvertexp->unlinkDelete(&m_graph);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Again, nodep may no longer be first.
|
||||
@@ -534,6 +541,15 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstJumpGo* nodep, AstNUser*) {
|
||||
// Jumps will disable reordering at all levels
|
||||
// This is overly pessimistic; we could treat jumps as barriers, and
|
||||
// reorder everything between jumps/labels, however jumps are rare
|
||||
// in always, so the performance gain probably isn't worth the work.
|
||||
UINFO(9," NoReordering "<<nodep<<endl);
|
||||
m_noReorderWhy = "JumpGo";
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
//--------------------
|
||||
// Default
|
||||
|
||||
@@ -1041,6 +1041,14 @@ private:
|
||||
virtual void visit(AstSysIgnore* nodep, AstNUser* vup) {
|
||||
nodep->exprsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
}
|
||||
virtual void visit(AstSystemF* nodep, AstNUser*) {
|
||||
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
nodep->numeric(AstNumeric::UNSIGNED);
|
||||
nodep->width(32,32);
|
||||
}
|
||||
virtual void visit(AstSystemT* nodep, AstNUser*) {
|
||||
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
}
|
||||
virtual void visit(AstReadMem* nodep, AstNUser*) {
|
||||
nodep->filenamep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
nodep->memp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
@@ -1137,6 +1145,13 @@ private:
|
||||
}
|
||||
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||
if (!m_paramsOnly) {
|
||||
if (nodep->modp()->castNotFoundModule()) {
|
||||
// We've resolved parameters and hit a module that we couldn't resolve. It's
|
||||
// finally time to report it.
|
||||
// Note only here in V3Width as this is first visitor after V3Dead.
|
||||
nodep->v3error("Cannot find file containing module: "<<nodep->modName());
|
||||
v3Global.opt.filePathLookedMsg(nodep->fileline(), nodep->modName());
|
||||
}
|
||||
if (nodep->rangep()) {
|
||||
m_cellRangep = nodep->rangep();
|
||||
nodep->rangep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
|
||||
+4
-2
@@ -106,7 +106,8 @@ void V3Global::readFiles() {
|
||||
for (V3StringList::const_iterator it = v3Global.opt.vFiles().begin();
|
||||
it != v3Global.opt.vFiles().end(); ++it) {
|
||||
string filename = *it;
|
||||
parser.parseFile(new FileLine("COMMAND_LINE",0), filename, false);
|
||||
parser.parseFile(new FileLine("COMMAND_LINE",0), filename, false,
|
||||
"Cannot find file containing module: ");
|
||||
}
|
||||
|
||||
// Read libraries
|
||||
@@ -115,7 +116,8 @@ void V3Global::readFiles() {
|
||||
for (V3StringSet::const_iterator it = v3Global.opt.libraryFiles().begin();
|
||||
it != v3Global.opt.libraryFiles().end(); ++it) {
|
||||
string filename = *it;
|
||||
parser.parseFile(new FileLine("COMMAND_LINE",0), filename, true);
|
||||
parser.parseFile(new FileLine("COMMAND_LINE",0), filename, true,
|
||||
"Cannot find file containing library module: ");
|
||||
}
|
||||
//v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("parse.tree"));
|
||||
V3Error::abortIfErrors();
|
||||
|
||||
+24
-1
@@ -7,7 +7,7 @@ use Getopt::Long;
|
||||
use IO::File;
|
||||
use Pod::Usage;
|
||||
use strict;
|
||||
use vars qw ($Debug @Types %Classes %ClassRefs %Stages);
|
||||
use vars qw ($Debug @Types %Classes %Children %ClassRefs %Stages);
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
@@ -88,6 +88,7 @@ sub read_types {
|
||||
$class =~ s/^Ast//;
|
||||
$inh =~ s/^Ast//;
|
||||
$Classes{$class} = $inh;
|
||||
$Children{$inh}{$class} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,6 +153,22 @@ sub subclasses_of {
|
||||
return (reverse @cllist);
|
||||
}
|
||||
|
||||
sub children_of {
|
||||
my $type = shift;
|
||||
|
||||
my @cllist;
|
||||
my @todo;
|
||||
push @todo, $type;
|
||||
while (my $subclass = shift @todo) {
|
||||
foreach my $child (sort keys %{$::Children{$subclass}}) {
|
||||
push @todo, $child;
|
||||
push @cllist, $child;
|
||||
}
|
||||
}
|
||||
|
||||
return (@cllist);
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub write_report {
|
||||
@@ -172,6 +189,12 @@ sub write_report {
|
||||
printf $fh "Ast%-12s ",$subclass;
|
||||
}
|
||||
printf $fh "\n";
|
||||
$fh->print("\tchilds:\t");
|
||||
foreach my $subclass (children_of($type)) {
|
||||
next if $subclass eq 'Node';
|
||||
printf $fh "Ast%-12s ",$subclass;
|
||||
}
|
||||
printf $fh "\n";
|
||||
if (my $refs = $ClassRefs{"Ast${type}"}) {
|
||||
$fh->print("\tnewed:\t");
|
||||
foreach my $stage (sort {($Stages{$a}||-1) <=> ($Stages{$b}||-1)}
|
||||
|
||||
+115
-17
@@ -134,7 +134,7 @@ void yyerrorf(const char* format, ...) {
|
||||
|
||||
%s V95 V01 V05 S05 S09
|
||||
%s STRING ATTRMODE TABLE
|
||||
%s PSL VLT
|
||||
%s VA5 SA9 PSL VLT
|
||||
%s SYSCHDR SYSCINT SYSCIMP SYSCIMPH SYSCCTOR SYSCDTOR
|
||||
%s IGNORE
|
||||
|
||||
@@ -168,7 +168,7 @@ word [a-zA-Z0-9_]+
|
||||
|
||||
/************************************************************************/
|
||||
/* Verilog 1995 */
|
||||
<V95,V01,V05,S05,S09,PSL>{
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL>{
|
||||
{ws} { } /* otherwise ignore white-space */
|
||||
{crnl} { NEXTLINE(); } /* Count line numbers */
|
||||
/* Extensions to Verilog set, some specified by PSL */
|
||||
@@ -215,6 +215,7 @@ word [a-zA-Z0-9_]+
|
||||
"$stime" { FL; return yD_STIME; }
|
||||
"$stop" { FL; return yD_STOP; }
|
||||
"$swrite" { FL; return yD_SWRITE; }
|
||||
"$system" { FL; return yD_SYSTEM; }
|
||||
"$test$plusargs" { FL; return yD_TESTPLUSARGS; }
|
||||
"$time" { FL; return yD_TIME; }
|
||||
"$timeskew" { FL; return yaTIMINGSPEC; }
|
||||
@@ -340,7 +341,7 @@ word [a-zA-Z0-9_]+
|
||||
}
|
||||
|
||||
/* Verilog 2001 */
|
||||
<V01,V05,S05,S09,PSL>{
|
||||
<V01,V05,VA5,S05,S09,SA9,PSL>{
|
||||
/* System Tasks */
|
||||
"$signed" { FL; return yD_SIGNED; }
|
||||
"$unsigned" { FL; return yD_UNSIGNED; }
|
||||
@@ -371,7 +372,7 @@ word [a-zA-Z0-9_]+
|
||||
}
|
||||
|
||||
/* Verilog 2005 */
|
||||
<V05,S05,S09,PSL>{
|
||||
<V05,S05,S09,SA9,PSL>{
|
||||
/* Keywords */
|
||||
"uwire" { FL; return yWIRE; }
|
||||
}
|
||||
@@ -530,7 +531,7 @@ word [a-zA-Z0-9_]+
|
||||
}
|
||||
|
||||
/* Default PLI rule */
|
||||
<V95,V01,V05,S05,S09,PSL>{
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL>{
|
||||
"$"[a-zA-Z_$][a-zA-Z0-9_$]* { string str (yytext,yyleng);
|
||||
yylval.strp = PARSEP->newString(AstNode::encodeName(str));
|
||||
// Lookup unencoded name including the $, to avoid hitting normal signals
|
||||
@@ -540,11 +541,104 @@ word [a-zA-Z0-9_]+
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* AMS */
|
||||
|
||||
<VA5,SA9>{
|
||||
/* Generic unsupported warnings */
|
||||
"above" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"abs" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"absdelay" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"abstol" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"ac_stim" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"access" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"acos" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"acosh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"aliasparam" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"analog" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"analysis" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"asin" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"asinh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"assert" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"atan" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"atan2" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"atanh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"branch" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"ceil" { FL; return yD_CEIL; }
|
||||
"connect" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"connectmodule" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"connectrules" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"continuous" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"cos" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"cosh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"cross" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"ddt" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"ddt_nature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"ddx" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"discipline" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"discrete" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"domain" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"driver_update" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"endconnectrules" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"enddiscipline" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"endnature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"endparamset" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"exclude" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"exp" { FL; return yD_EXP; }
|
||||
"final_step" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"flicker_noise" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"floor" { FL; return yD_FLOOR; }
|
||||
"flow" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"from" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"ground" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"hypot" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"idt" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"idt_nature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"idtmod" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"inf" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"initial_step" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"laplace_nd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"laplace_np" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"laplace_zd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"laplace_zp" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"last_crossing" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"limexp" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"ln" { FL; return yD_LN; }
|
||||
"log" { FL; return yD_LOG10; }
|
||||
"max" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"merged" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"min" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"nature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"net_resolution" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"noise_table" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"paramset" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"potential" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"pow" { FL; return yD_POW; }
|
||||
"resolveto" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"sin" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"sinh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"slew" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"split" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"sqrt" { FL; return yD_SQRT; }
|
||||
"string" { FL; return ySTRING; }
|
||||
"tan" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"tanh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"timer" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"transition" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"units" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"white_noise" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"wreal" { FL; return yWREAL; }
|
||||
"zi_nd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"zi_np" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"zi_zd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
"zi_zp" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* PSL */
|
||||
|
||||
/*Entry into PSL; mode change */
|
||||
<V95,V01,V05,S05,S09>{
|
||||
<V95,V01,V05,VA5,S05,S09,SA9>{
|
||||
"psl" { yy_push_state(PSL); FL; return yPSL; }
|
||||
}
|
||||
|
||||
@@ -633,7 +727,7 @@ word [a-zA-Z0-9_]+
|
||||
/* Meta comments */
|
||||
|
||||
/* Converted from //{cmt}verilator ...{cmt} by preprocessor */
|
||||
<V95,V01,V05,S05,S09,PSL>{
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL>{
|
||||
"/*verilator"{ws}*"*/" {} /* Ignore empty comments, may be `endif // verilator */
|
||||
"/*verilator clock_enable*/" { FL; return yVL_CLOCK_ENABLE; }
|
||||
"/*verilator coverage_block_off*/" { FL; return yVL_COVERAGE_BLOCK_OFF; }
|
||||
@@ -649,6 +743,7 @@ word [a-zA-Z0-9_]+
|
||||
"/*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 sc_bv*/" { FL; return yVL_SC_BV; }
|
||||
"/*verilator sformat*/" { FL; return yVL_SFORMAT; }
|
||||
"/*verilator systemc_clock*/" { FL; return yVL_CLOCK; }
|
||||
"/*verilator tracing_off*/" {PARSEP->fileline()->tracingOn(false); }
|
||||
@@ -667,11 +762,11 @@ word [a-zA-Z0-9_]+
|
||||
/************************************************************************/
|
||||
|
||||
/* Single character operator thingies */
|
||||
<V95,V01,V05,S05,S09>{
|
||||
<V95,V01,V05,VA5,S05,S09,SA9>{
|
||||
"{" { FL; return yytext[0]; }
|
||||
"}" { FL; return yytext[0]; }
|
||||
}
|
||||
<V95,V01,V05,S05,S09,PSL>{
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL>{
|
||||
"!" { FL; return yytext[0]; }
|
||||
"#" { FL; return yytext[0]; }
|
||||
"$" { FL; return yytext[0]; }
|
||||
@@ -703,7 +798,7 @@ word [a-zA-Z0-9_]+
|
||||
/* Operators and multi-character symbols */
|
||||
|
||||
/* Verilog 1995 Operators */
|
||||
<V95,V01,V05,S05,S09,PSL>{
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL>{
|
||||
"&&" { FL; return yP_ANDAND; }
|
||||
"||" { FL; return yP_OROR; }
|
||||
"<=" { FL; return yP_LTE; }
|
||||
@@ -725,7 +820,7 @@ word [a-zA-Z0-9_]+
|
||||
}
|
||||
|
||||
/* Verilog 2001 Operators */
|
||||
<V01,V05,S05,S09,PSL>{
|
||||
<V01,V05,VA5,S05,S09,SA9,PSL>{
|
||||
"<<<" { FL; return yP_SLEFT; }
|
||||
">>>" { FL; return yP_SSRIGHT; }
|
||||
"**" { FL; return yP_POW; }
|
||||
@@ -784,7 +879,7 @@ word [a-zA-Z0-9_]+
|
||||
}
|
||||
|
||||
/* Identifiers and numbers */
|
||||
<V95,V01,V05,S05,S09,PSL,VLT>{
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL,VLT>{
|
||||
{escid} { FL; yylval.strp = PARSEP->newString
|
||||
(AstNode::encodeName(string(yytext+1))); // +1 to skip the backslash
|
||||
return yaID__LEX;
|
||||
@@ -859,8 +954,9 @@ word [a-zA-Z0-9_]+
|
||||
|
||||
/************************************************************************/
|
||||
/* Attributes */
|
||||
<V95,V01,V05,S05,S09>{
|
||||
"(*"/{ws}*[^)] { yymore(); yy_push_state(ATTRMODE); } // Doesn't match (*)
|
||||
/* Note simulators vary in support for "(* /_*something*_/ foo*)" where _ doesn't exist */
|
||||
<V95,V01,V05,VA5,S05,S09,SA9>{
|
||||
"(*"({ws}|{crnl})*({id}|{escid}) { yymore(); yy_push_state(ATTRMODE); } // Doesn't match (*), but (* attr_spec
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
@@ -876,7 +972,7 @@ word [a-zA-Z0-9_]+
|
||||
/* Preprocessor */
|
||||
/* Common for all SYSC header states */
|
||||
/* OPTIMIZE: we return one per line, make it one for the entire block */
|
||||
<V95,V01,V05,S05,S09,PSL,VLT,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>{
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL,VLT,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>{
|
||||
"`accelerate" { } // Verilog-XL compatibility
|
||||
"`autoexpand_vectornets" { } // Verilog-XL compatibility
|
||||
"`celldefine" { PARSEP->inCellDefine(true); }
|
||||
@@ -917,9 +1013,11 @@ word [a-zA-Z0-9_]+
|
||||
"`begin_keywords"[ \t]*\"1364-2001\" { yy_push_state(V01); PARSEP->pushBeginKeywords(YY_START); }
|
||||
"`begin_keywords"[ \t]*\"1364-2001-noconfig\" { yy_push_state(V01); PARSEP->pushBeginKeywords(YY_START); }
|
||||
"`begin_keywords"[ \t]*\"1364-2005\" { yy_push_state(V05); PARSEP->pushBeginKeywords(YY_START); }
|
||||
"`begin_keywords"[ \t]*\"VAMS[-0-9.]*\" { yy_push_state(VA5); PARSEP->pushBeginKeywords(YY_START); }
|
||||
"`begin_keywords"[ \t]*\"1800-2005\" { yy_push_state(S05); PARSEP->pushBeginKeywords(YY_START); }
|
||||
"`begin_keywords"[ \t]*\"1800-2009\" { yy_push_state(S09); PARSEP->pushBeginKeywords(YY_START); }
|
||||
"`end_keywords" { yy_pop_state(); if (!PARSEP->popBeginKeywords()) yyerrorf("`end_keywords when not inside `begin_keywords block"); }
|
||||
"`begin_keywords"[ \t]*\"1800+VAMS\" { yy_push_state(SA9); PARSEP->pushBeginKeywords(YY_START); }
|
||||
"`end_keywords" { yy_pop_state(); if (!PARSEP->popBeginKeywords()) yyerrorf("`end_keywords when not inside `begin_keywords block"); }
|
||||
|
||||
/* Verilator */
|
||||
"`systemc_ctor" { BEGIN SYSCCTOR; }
|
||||
@@ -949,7 +1047,7 @@ word [a-zA-Z0-9_]+
|
||||
/************************************************************************/
|
||||
/* Default rules - leave last */
|
||||
|
||||
<V95,V01,V05,S05,S09,PSL,VLT>{
|
||||
<V95,V01,V05,VA5,S05,S09,SA9,PSL,VLT>{
|
||||
"`"[a-zA-Z_0-9]+ { FL; yyerrorf("Define or directive not defined: %s",yytext); }
|
||||
"//"[^\n]* { } /* throw away single line comments */
|
||||
. { FL; return yytext[0]; } /* return single char ops. */
|
||||
|
||||
+17
-4
@@ -380,6 +380,7 @@ class AstSenTree;
|
||||
%token<fl> yVOID "void"
|
||||
%token<fl> yWHILE "while"
|
||||
%token<fl> yWIRE "wire"
|
||||
%token<fl> yWREAL "wreal"
|
||||
%token<fl> yXNOR "xnor"
|
||||
%token<fl> yXOR "xor"
|
||||
|
||||
@@ -425,6 +426,7 @@ class AstSenTree;
|
||||
%token<fl> yD_STIME "$stime"
|
||||
%token<fl> yD_STOP "$stop"
|
||||
%token<fl> yD_SWRITE "$swrite"
|
||||
%token<fl> yD_SYSTEM "$system"
|
||||
%token<fl> yD_TESTPLUSARGS "$test$plusargs"
|
||||
%token<fl> yD_TIME "$time"
|
||||
%token<fl> yD_UNIT "$unit"
|
||||
@@ -447,6 +449,7 @@ class AstSenTree;
|
||||
%token<fl> yVL_ISOLATE_ASSIGNMENTS "/*verilator isolate_assignments*/"
|
||||
%token<fl> yVL_NO_INLINE_MODULE "/*verilator no_inline_module*/"
|
||||
%token<fl> yVL_NO_INLINE_TASK "/*verilator no_inline_task*/"
|
||||
%token<fl> yVL_SC_BV "/*verilator sc_bv*/"
|
||||
%token<fl> yVL_SFORMAT "/*verilator sformat*/"
|
||||
%token<fl> yVL_PARALLEL_CASE "/*verilator parallel_case*/"
|
||||
%token<fl> yVL_PUBLIC "/*verilator public*/"
|
||||
@@ -1085,6 +1088,8 @@ non_integer_type<bdtypep>: // ==IEEE: non_integer_type
|
||||
yREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); }
|
||||
| yREALTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); }
|
||||
//UNSUP ySHORTREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::FLOAT); }
|
||||
// // VAMS - somewhat hackish
|
||||
| yWREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); VARDECL(WIRE); }
|
||||
;
|
||||
|
||||
signingE<signstate>: // IEEE: signing - plus empty
|
||||
@@ -1527,7 +1532,7 @@ assignOne<nodep>:
|
||||
|
||||
delayE:
|
||||
/* empty */ { }
|
||||
| delay_control { $1->v3warn(ASSIGNDLY,"Ignoring delay on this assignment/primitive."); } /* ignored */
|
||||
| delay_control { $1->v3warn(ASSIGNDLY,"Unsupported: Ignoring delay on this assignment/primitive."); } /* ignored */
|
||||
;
|
||||
|
||||
delay_control<fl>: //== IEEE: delay_control
|
||||
@@ -1596,6 +1601,7 @@ sigAttr<nodep>:
|
||||
| yVL_PUBLIC_FLAT_RW attr_event_control { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RW);
|
||||
$$ = $$->addNext(new AstAlwaysPublic($1,$2,NULL)); }
|
||||
| yVL_ISOLATE_ASSIGNMENTS { $$ = new AstAttrOf($1,AstAttrType::VAR_ISOLATE_ASSIGNMENTS); }
|
||||
| yVL_SC_BV { $$ = new AstAttrOf($1,AstAttrType::VAR_SC_BV); }
|
||||
| yVL_SFORMAT { $$ = new AstAttrOf($1,AstAttrType::VAR_SFORMAT); }
|
||||
;
|
||||
|
||||
@@ -1766,8 +1772,8 @@ event_control<sentreep>: // ==IEEE: event_control
|
||||
|
||||
event_expression<senitemp>: // IEEE: event_expression - split over several
|
||||
senitem { $$ = $1; }
|
||||
| event_expression yOR senitem { $$ = $1;$1->addNext($3); }
|
||||
| event_expression ',' senitem { $$ = $1;$1->addNext($3); } /* Verilog 2001 */
|
||||
| event_expression yOR senitem { $$ = $1;$1->addNextNull($3); }
|
||||
| event_expression ',' senitem { $$ = $1;$1->addNextNull($3); } /* Verilog 2001 */
|
||||
;
|
||||
|
||||
senitem<senitemp>: // IEEE: part of event_expression, non-'OR' ',' terms
|
||||
@@ -1776,6 +1782,11 @@ senitem<senitemp>: // IEEE: part of event_expression, non-'OR' ',' terms
|
||||
| '(' senitemVar ')' { $$ = $2; }
|
||||
//UNSUP expr { UNSUP }
|
||||
//UNSUP expr yIFF expr { UNSUP }
|
||||
// Since expr is unsupported we allow and ignore constants (removed in V3Const)
|
||||
| yaINTNUM { $$ = NULL; }
|
||||
| yaFLOATNUM { $$ = NULL; }
|
||||
| '(' yaINTNUM ')' { $$ = NULL; }
|
||||
| '(' yaFLOATNUM ')' { $$ = NULL; }
|
||||
;
|
||||
|
||||
senitemVar<senitemp>:
|
||||
@@ -1929,7 +1940,7 @@ statement_item<nodep>: // IEEE: statement_item
|
||||
//
|
||||
//UNSUP par_block { $$ = $1; }
|
||||
// // IEEE: procedural_timing_control_statement + procedural_timing_control
|
||||
| delay_control stmtBlock { $$ = $2; $1->v3warn(STMTDLY,"Ignoring delay on this delayed statement."); }
|
||||
| delay_control stmtBlock { $$ = $2; $1->v3warn(STMTDLY,"Unsupported: Ignoring delay on this delayed statement."); }
|
||||
//UNSUP event_control stmtBlock { UNSUP }
|
||||
//UNSUP cycle_delay stmtBlock { UNSUP }
|
||||
//
|
||||
@@ -2126,6 +2137,7 @@ system_t_call<nodep>: // IEEE: system_tf_call (as task)
|
||||
//
|
||||
| yD_SFORMAT '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); }
|
||||
| yD_SWRITE '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); }
|
||||
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemT($1,$3); }
|
||||
//
|
||||
| yD_DISPLAY parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,"", NULL,NULL); }
|
||||
| yD_DISPLAY '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,*$3,NULL,$4); }
|
||||
@@ -2177,6 +2189,7 @@ system_f_call<nodep>: // IEEE: system_tf_call (as func)
|
||||
| yD_FGETS '(' idClassSel ',' expr ')' { $$ = new AstFGetS($1,$3,$5); }
|
||||
| yD_FSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstFScanF($1,*$5,$3,$6); }
|
||||
| yD_SSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstSScanF($1,*$5,$3,$6); }
|
||||
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemF($1,$3); }
|
||||
| yD_ISUNKNOWN '(' expr ')' { $$ = new AstIsUnknown($1,$3); }
|
||||
| yD_ITOR '(' expr ')' { $$ = new AstIToRD($1,$3); }
|
||||
| yD_ONEHOT '(' expr ')' { $$ = new AstOneHot($1,$3); }
|
||||
|
||||
+3
-3
@@ -13,10 +13,10 @@
|
||||
|
||||
Vtop *top; // Instantiation of module
|
||||
|
||||
unsigned int main_time = 0; // Current simulation time
|
||||
vluint64_t main_time = 0; // Current simulation time (64-bit unsigned)
|
||||
|
||||
double sc_time_stamp () { // Called by $time in Verilog
|
||||
return main_time;
|
||||
return main_time; // Note does conversion to real, to match SystemC
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **env) {
|
||||
@@ -59,7 +59,7 @@ int main(int argc, char **argv, char **env) {
|
||||
#endif
|
||||
|
||||
// Read outputs
|
||||
VL_PRINTF ("[%d] %x %x %x %x %x_%08x_%08x\n",
|
||||
VL_PRINTF ("[%" VL_PRI64 "d] %x %x %x %x %x_%08x_%08x\n",
|
||||
main_time, top->clk, top->reset_l, top->passed,
|
||||
top->out_small, top->out_wide[2], top->out_wide[1], top->out_wide[0]);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// Use this file as a template for submitting bugs, etc.
|
||||
// This module takes a single clock input, and should either
|
||||
// $write("*-* All Finished *-*\n");
|
||||
// $finish
|
||||
// $finish;
|
||||
// on success, or $stop.
|
||||
//
|
||||
// The code as shown applies a random vector to the Test
|
||||
|
||||
@@ -11,7 +11,7 @@ module t (/*AUTOARG*/
|
||||
input clk;
|
||||
integer cyc; initial cyc=1;
|
||||
|
||||
reg [31:0] a, b, c, d, e;
|
||||
reg [31:0] a, b, c, d, e, f, g;
|
||||
|
||||
always @ (*) begin // Test Verilog 2001 (*)
|
||||
// verilator lint_off COMBDLY
|
||||
@@ -25,6 +25,14 @@ module t (/*AUTOARG*/
|
||||
always @ ((d)) begin // always bug 2008/4/18
|
||||
e = d;
|
||||
end
|
||||
|
||||
parameter CONSTANT = 1;
|
||||
always @ (e, 1'b0, CONSTANT) begin // not technically legal, see bug412
|
||||
f = e;
|
||||
end
|
||||
always @ (1'b0, CONSTANT, f) begin // not technically legal, see bug412
|
||||
g = f;
|
||||
end
|
||||
//always @ ((posedge b) or (a or b)) begin // note both illegal
|
||||
|
||||
always @ (posedge clk) begin
|
||||
@@ -38,7 +46,7 @@ module t (/*AUTOARG*/
|
||||
if (c != 32'hfeedface) $stop;
|
||||
end
|
||||
if (cyc==3) begin
|
||||
if (e != 32'hfeedface) $stop;
|
||||
if (g != 32'hfeedface) $stop;
|
||||
end
|
||||
if (cyc==7) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
|
||||
Executable
+18
@@ -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;
|
||||
@@ -0,0 +1,41 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2011 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
|
||||
input clk;
|
||||
|
||||
always @(*) begin
|
||||
if (clk) begin end
|
||||
end
|
||||
|
||||
always @(* ) begin
|
||||
if (clk) begin end
|
||||
end
|
||||
|
||||
// Not legal in some simulators, legal in others
|
||||
// always @(* /*cmt*/ ) begin
|
||||
// if (clk) begin end
|
||||
// end
|
||||
|
||||
// Not legal in some simulators, legal in others
|
||||
// always @(* // cmt
|
||||
// ) begin
|
||||
// if (clk) begin end
|
||||
// end
|
||||
|
||||
always @ (*
|
||||
) begin
|
||||
if (clk) begin end
|
||||
end
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -15,11 +15,11 @@ compile (
|
||||
verilator_flags2 => ['-Wall -Wno-DECLFILENAME'],
|
||||
fails=>1,
|
||||
expect=>
|
||||
'%Warning-ASSIGNDLY: t/t_delay.v:\d+: Ignoring delay on this assignment/primitive.
|
||||
'%Warning-ASSIGNDLY: t/t_delay.v:\d+: Unsupported: Ignoring delay on this assignment/primitive.
|
||||
%Warning-ASSIGNDLY: Use .*
|
||||
%Warning-ASSIGNDLY: t/t_delay.v:\d+: Ignoring delay on this assignment/primitive.
|
||||
%Warning-ASSIGNDLY: t/t_delay.v:\d+: Ignoring delay on this assignment/primitive.
|
||||
%Warning-STMTDLY: t/t_delay.v:\d+: Ignoring delay on this delayed statement.
|
||||
%Warning-ASSIGNDLY: t/t_delay.v:\d+: Unsupported: Ignoring delay on this assignment/primitive.
|
||||
%Warning-ASSIGNDLY: t/t_delay.v:\d+: Unsupported: Ignoring delay on this assignment/primitive.
|
||||
%Warning-STMTDLY: t/t_delay.v:\d+: Unsupported: Ignoring delay on this delayed statement.
|
||||
.*%Error: Exiting due to.*',
|
||||
);
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ execute (
|
||||
[0] e=2.579000e+15 e1=2.579000e+15 e30=3e+15 e32=2.58e+15
|
||||
[0] f=2579000000000000.000000 f1=2.579000e+15 f30=3e+15 f32=2.58e+15
|
||||
[0] g=2.579e+15 g1=2.579000e+15 g30=3e+15 g32=2.58e+15
|
||||
|
||||
r8= 3 n1=1 n2=0.1
|
||||
n1=1 n2=0.1 r8= 3
|
||||
'),
|
||||
);
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ module t;
|
||||
real n2; initial n2 = 0.1;
|
||||
real n3; initial n3 = 1.2345e-15;
|
||||
real n4; initial n4 = 2.579e+15;
|
||||
reg [7:0] r8; initial r8 = 3;
|
||||
|
||||
initial begin
|
||||
// Display formatting
|
||||
@@ -31,6 +32,9 @@ module t;
|
||||
$display("[%0t] e=%e e1=%1e e30=%3.0e e32=%3.2e", $time, n4,n4,n4,n4);
|
||||
$display("[%0t] f=%f f1=%1e f30=%3.0e f32=%3.2e", $time, n4,n4,n4,n4);
|
||||
$display("[%0t] g=%g g1=%1e g30=%3.0e g32=%3.2e", $time, n4,n4,n4,n4);
|
||||
$display;
|
||||
$display("r8=%d n1=%g n2=%g", r8, n1, n2);
|
||||
$display("n1=%g n2=%g r8=%d", n1, n2, r8);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
@@ -35,6 +35,9 @@ execute (
|
||||
[0] e=2.579000e+15 e1=2.579000e+15 e30=3e+15 e32=2.58e+15
|
||||
[0] f=2579000000000000.000000 f1=2.579000e+15 f30=3e+15 f32=2.58e+15
|
||||
[0] g=2.579e+15 g1=2.579000e+15 g30=3e+15 g32=2.58e+15
|
||||
|
||||
r8= 3 n1=1 n2=0.1
|
||||
n1=1 n2=0.1 r8= 3
|
||||
'),
|
||||
);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ compile (
|
||||
fails=>$Self->{v3},
|
||||
nc=>0, # Need to get it not to give the prompt
|
||||
expect=>
|
||||
'%Error: Specified --top-module \'a\' isn.t at the top level, it.s under another cell.
|
||||
'%Error: Specified --top-module \'a\' isn.t at the top level, it.s under another cell \'a_top\'
|
||||
%Error: Exiting due to.*',
|
||||
);
|
||||
|
||||
|
||||
Executable
+18
@@ -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;
|
||||
@@ -0,0 +1,66 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2011 by Wilson Snyder.
|
||||
|
||||
// bug420
|
||||
typedef logic [7-1:0] wb_ind_t;
|
||||
typedef logic [7-1:0] id_t;
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
integer cyc=0;
|
||||
reg [63:0] crc;
|
||||
reg [63:0] sum;
|
||||
|
||||
// Take CRC data and apply to testblock inputs
|
||||
wire [31:0] in = crc[31:0];
|
||||
|
||||
/*AUTOWIRE*/
|
||||
|
||||
wire [6:0] out = line_wb_ind( in[6:0] );
|
||||
|
||||
// Aggregate outputs into a single result vector
|
||||
wire [63:0] result = {57'h0, out};
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
//`ifdef TEST_VERBOSE
|
||||
$write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result);
|
||||
//`endif
|
||||
cyc <= cyc + 1;
|
||||
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
|
||||
sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]};
|
||||
if (cyc==0) begin
|
||||
// Setup
|
||||
crc <= 64'h5aef0c8d_d70a4497;
|
||||
sum <= 64'h0;
|
||||
end
|
||||
else if (cyc<10) begin
|
||||
sum <= 64'h0;
|
||||
end
|
||||
else if (cyc<90) begin
|
||||
end
|
||||
else if (cyc==99) begin
|
||||
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
|
||||
if (crc !== 64'hc77bb9b3784ea091) $stop;
|
||||
// What checksum will we end up with (above print should match)
|
||||
`define EXPECTED_SUM 64'hc918fa0aa882a206
|
||||
if (sum !== `EXPECTED_SUM) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
function wb_ind_t line_wb_ind( id_t id );
|
||||
if( id[$bits(id_t)-1] == 0 )
|
||||
return {2'b00, id[$bits(wb_ind_t)-3:0]};
|
||||
else
|
||||
return {2'b01, id[$bits(wb_ind_t)-3:0]};
|
||||
endfunction // line_wb_ind
|
||||
|
||||
endmodule
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
v_flags2 => ['+define+T_GEN_MISSING'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,58 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2011 by Wilson Snyder.
|
||||
|
||||
module t;
|
||||
`ifdef T_GEN_MISSING_BAD
|
||||
foobar #(.FOO_TYPE(1)) foobar; // This means we should instatiate missing module
|
||||
`elsif T_GEN_MISSING
|
||||
foobar #(.FOO_TYPE(0)) foobar; // This means we should instatiate foo0
|
||||
`else
|
||||
`error "Bad Test"
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
|
||||
module foobar
|
||||
#( parameter
|
||||
FOO_START = 0,
|
||||
FOO_NUM = 2,
|
||||
FOO_TYPE = 1
|
||||
)
|
||||
(
|
||||
input wire[FOO_NUM-1:0] foo,
|
||||
output wire[FOO_NUM-1:0] bar);
|
||||
|
||||
|
||||
generate
|
||||
begin: g
|
||||
genvar j;
|
||||
for (j = FOO_START; j < FOO_NUM+FOO_START; j = j + 1)
|
||||
begin: foo_inst;
|
||||
if (FOO_TYPE == 0)
|
||||
begin: foo_0
|
||||
// instatiate foo0
|
||||
foo0 i_foo(.x(foo[j]), .y(bar[j]));
|
||||
end
|
||||
if (FOO_TYPE == 1)
|
||||
begin: foo_1
|
||||
// instatiate foo1
|
||||
foo_not_needed i_foo(.x(foo[j]), .y(bar[j]));
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
module foo0(input wire x, output wire y);
|
||||
|
||||
assign y = ~x;
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/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.
|
||||
|
||||
top_filename("t/t_gen_missing.v");
|
||||
|
||||
$Self->{vlt} or $Self->skip("Verilator only test");
|
||||
compile (
|
||||
v_flags2 => ['+define+T_GEN_MISSING_BAD'],
|
||||
fails => 1,
|
||||
expect=>
|
||||
'%Error: t/t_gen_missing.v:\d+: Cannot find file containing module: foo_not_needed
|
||||
%Error: t/t_gen_missing.v:\d+: Looked in:
|
||||
%Error: t/t_gen_missing.v:\d+: t/foo_not_needed
|
||||
%Error: t/t_gen_missing.v:\d+: t/foo_not_needed.v
|
||||
%Error: t/t_gen_missing.v:\d+: t/foo_not_needed.sv
|
||||
.*%Error: Exiting due to.*',
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -14,6 +14,7 @@ module t (/*AUTOARG*/
|
||||
s3 s3 ();
|
||||
s4 s4 ();
|
||||
s5 s5 ();
|
||||
s6 s6 ();
|
||||
|
||||
initial begin
|
||||
$finish;
|
||||
@@ -51,3 +52,9 @@ module s5;
|
||||
end
|
||||
endmodule
|
||||
`end_keywords
|
||||
|
||||
`begin_keywords "VAMS-2.3"
|
||||
module s6;
|
||||
real foo; initial foo = sqrt(2.0);
|
||||
endmodule
|
||||
`end_keywords
|
||||
|
||||
@@ -13,6 +13,7 @@ module t;
|
||||
reg [8*8:1] letterq;
|
||||
reg [16*8:1] letterw;
|
||||
reg [16*8:1] letterz;
|
||||
real r;
|
||||
|
||||
`ifdef TEST_VERBOSE
|
||||
`define verbose 1'b1
|
||||
@@ -119,10 +120,11 @@ module t;
|
||||
if (letterq != 64'h13) $stop;
|
||||
if (letterw != 128'h55ce14f1a9c29e) $stop;
|
||||
|
||||
chars = $sscanf("d=-236123",
|
||||
"d=%d", letterq);
|
||||
chars = $sscanf("r=0.1 d=-236123",
|
||||
"r=%g d=%d", r, letterq);
|
||||
if (`verbose) $write("c=%0d d=%d\n", chars, letterq);
|
||||
if (chars != 1) $stop;
|
||||
if (chars != 2) $stop;
|
||||
if (r != 0.1) $stop;
|
||||
if (letterq != 64'hfffffffffffc65a5) $stop;
|
||||
|
||||
// $fscanf
|
||||
|
||||
Executable
+18
@@ -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;
|
||||
@@ -0,0 +1,31 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2011 by Wilson Snyder.
|
||||
|
||||
module t;
|
||||
|
||||
integer i;
|
||||
|
||||
initial begin
|
||||
`ifndef VERILATOR
|
||||
`ifndef VCS
|
||||
`ifndef NC
|
||||
$system(); // Legal per spec, but not supported everywhere and nonsensical
|
||||
`endif
|
||||
`endif
|
||||
`endif
|
||||
$system("exit 0");
|
||||
$system("echo hello");
|
||||
`ifndef VCS
|
||||
i = $system("exit 0");
|
||||
if (i!==0) $stop;
|
||||
i = $system("exit 10");
|
||||
if (i!==10) $stop;
|
||||
`endif
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
Executable
+18
@@ -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;
|
||||
@@ -0,0 +1,47 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2011 by Wilson Snyder.
|
||||
|
||||
`begin_keywords "VAMS-2.3"
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
task check (integer line, real got, real expec);
|
||||
real delta;
|
||||
delta = got-expec;
|
||||
if (delta > 0.001) begin
|
||||
$display("Line%d: Got %g Exp %g\n", line, got, expec);
|
||||
$stop;
|
||||
end
|
||||
endtask
|
||||
|
||||
wreal wr;
|
||||
assign wr = 1.1;
|
||||
|
||||
sub sub (.*);
|
||||
|
||||
initial begin
|
||||
check(`__LINE__, sqrt(2.0) , 1.414);
|
||||
check(`__LINE__, pow(2.0,2.0) , 4.0);
|
||||
check(`__LINE__, ln(2.0) , 0.693147);
|
||||
check(`__LINE__, log(2.0) , 0.30103);
|
||||
check(`__LINE__, floor(2.5) , 2.0);
|
||||
check(`__LINE__, exp(2.0) , 7.38906);
|
||||
check(`__LINE__, ceil(2.5) , 3.0);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module sub (
|
||||
input wreal wr
|
||||
);
|
||||
initial begin
|
||||
if (wr != 1.1) $stop;
|
||||
end
|
||||
endmodule
|
||||
Executable
+18
@@ -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;
|
||||
@@ -0,0 +1,64 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2008 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
integer cyc=0;
|
||||
integer v;
|
||||
|
||||
reg i;
|
||||
/*AUTOWIRE*/
|
||||
// Beginning of automatic wires (for undeclared instantiated-module outputs)
|
||||
wire oa; // From a of a.v
|
||||
wire oz; // From z of z.v
|
||||
// End of automatics
|
||||
|
||||
a a (.*);
|
||||
z z (.*);
|
||||
|
||||
always @ (posedge clk) begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("[%0t] cyc==%0d i=%x oa=%x oz=%x\n",$time, cyc, i, oa, oz);
|
||||
`endif
|
||||
cyc <= cyc + 1;
|
||||
i <= cyc[0];
|
||||
if (cyc==0) begin
|
||||
v = 3;
|
||||
if (v !== 3) $stop;
|
||||
if (assignin(v) !== 2) $stop;
|
||||
if (v !== 3) $stop; // Make sure V didn't get changed
|
||||
end
|
||||
else if (cyc<10) begin
|
||||
if (cyc==11 && oz!==1'b0) $stop;
|
||||
if (cyc==12 && oz!==1'b1) $stop;
|
||||
if (cyc==12 && oa!==1'b1) $stop;
|
||||
end
|
||||
else if (cyc<90) begin
|
||||
end
|
||||
else if (cyc==99) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
function integer assignin(input integer i);
|
||||
i = 2;
|
||||
assignin = i;
|
||||
endfunction
|
||||
|
||||
endmodule
|
||||
|
||||
module a (input i, output oa);
|
||||
// verilator lint_off ASSIGNIN
|
||||
assign i = 1'b1;
|
||||
assign oa = i;
|
||||
endmodule
|
||||
|
||||
module z (input i, output oz);
|
||||
assign oz = i;
|
||||
endmodule
|
||||
@@ -13,8 +13,8 @@ compile (
|
||||
v_flags2 => ["--lint-only --Mdir obj_lint_only"],
|
||||
fails=>1,
|
||||
expect=>
|
||||
'%Error: t/t_var_in_assign_bad.v:\d+: Assigning to input variable: value
|
||||
%Error: t/t_var_in_assign_bad.v:\d+: Assigning to input variable: valueSub
|
||||
'%Error-ASSIGNIN: t/t_var_in_assign_bad.v:\d+: Assigning to input variable: value
|
||||
%Error-ASSIGNIN: t/t_var_in_assign_bad.v:\d+: Assigning to input variable: valueSub
|
||||
%Error: Exiting due to.*',
|
||||
);
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ if ($Self->{vlt}) {
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<32>\s> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
|
||||
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<8>\s> \s+ o8;/x);
|
||||
@@ -30,6 +32,8 @@ if ($Self->{vlt}) {
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<32>\s> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
|
||||
}
|
||||
|
||||
execute();
|
||||
|
||||
@@ -23,6 +23,8 @@ if ($Self->{vlt}) {
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<32>\s> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
|
||||
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<8>\s> \s+ o8;/x);
|
||||
@@ -30,6 +32,8 @@ if ($Self->{vlt}) {
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<32>\s> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
|
||||
}
|
||||
|
||||
execute();
|
||||
|
||||
@@ -23,6 +23,8 @@ if ($Self->{vlt}) {
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
|
||||
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o8;/x);
|
||||
@@ -30,6 +32,8 @@ if ($Self->{vlt}) {
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
|
||||
}
|
||||
|
||||
execute();
|
||||
|
||||
@@ -23,6 +23,8 @@ if ($Self->{vlt}) {
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<vluint64_t> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
|
||||
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o8;/x);
|
||||
@@ -30,6 +32,8 @@ if ($Self->{vlt}) {
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<vluint64_t> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
|
||||
}
|
||||
|
||||
execute();
|
||||
|
||||
@@ -23,6 +23,8 @@ if ($Self->{vlt}) {
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<vluint64_t> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
|
||||
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint8_t> \s+ o8;/x);
|
||||
@@ -30,6 +32,8 @@ if ($Self->{vlt}) {
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<vluint64_t> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
|
||||
}
|
||||
|
||||
execute();
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Outputs
|
||||
o1, o8, o16, o32, o64, o65,
|
||||
o1, o8, o16, o32, o64, o65, obv1, obv16,
|
||||
// Inputs
|
||||
clk, i1, i8, i16, i32, i64, i65
|
||||
clk, i1, i8, i16, i32, i64, i65, ibv1, ibv16
|
||||
);
|
||||
|
||||
input clk;
|
||||
@@ -29,6 +29,12 @@ module t (/*AUTOARG*/
|
||||
output [63:0] o64;
|
||||
output [64:0] o65;
|
||||
|
||||
input [0:0] ibv1 /*verilator sc_bv*/;
|
||||
input [15:0] ibv16 /*verilator sc_bv*/;
|
||||
|
||||
output [0:0] obv1 /*verilator sc_bv*/;
|
||||
output [15:0] obv16 /*verilator sc_bv*/;
|
||||
|
||||
always @ (posedge clk) begin
|
||||
o1 <= i1;
|
||||
o8 <= i8;
|
||||
@@ -36,6 +42,8 @@ module t (/*AUTOARG*/
|
||||
o32 <= i32;
|
||||
o64 <= i64;
|
||||
o65 <= i65;
|
||||
obv1 <= ibv1;
|
||||
obv16 <= ibv16;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
Vvgen *top;
|
||||
|
||||
unsigned int main_time = 0;
|
||||
vluint64_t main_time = 0;
|
||||
|
||||
double sc_time_stamp () {
|
||||
return main_time;
|
||||
|
||||
Reference in New Issue
Block a user