Compare commits

...
32 Commits
Author SHA1 Message Date
Wilson Snyder fa9dac29e8 Version bump 2015-12-19 10:26:14 -05:00
Wilson Snyder afc432042f Fix ternary operation with unpacked array, bug1017. 2015-12-18 18:02:25 -05:00
Wilson Snyder 21cb29baf0 Fix arrayed instances to unpacked of same size, bug1015. Fix slices of unpacked arrays with non-zero LSBs. 2015-12-15 22:37:49 -05:00
Wilson Snyder e8b5001cfe Fix model restore crash, bug1013. 2015-12-14 19:58:22 -05:00
Wilson Snyder 849c1e46a2 Fix constant propagation, bug1012. 2015-12-08 22:22:42 -05:00
Wilson Snyder ebad6cde36 Fix error instead of warning on large concat, msg1768. 2015-12-08 21:25:43 -05:00
Johan Bjork f920b3945e Fix dotted generated array error, bug1005.
Signed-off-by: Wilson Snyder <[email protected]>
2015-12-05 19:58:58 -05:00
Wilson Snyder 178028a70a Commentary; part of last commit 2015-12-05 19:45:45 -05:00
Todd Strader 5e54d3e41a Fix interface inside generate, bug1001, bug1003.
Signed-off-by: Wilson Snyder <[email protected]>
2015-12-05 19:39:40 -05:00
Wilson Snyder f0af8726e3 Internals: Fix some spacing. No functional change. 2015-12-05 17:12:03 -05:00
Todd Strader 57f2fe77ea Fix cell [#] to mean # cells.
Signed-off-by: Wilson Snyder <[email protected]>
2015-12-01 18:23:11 -05:00
Todd Strader d56ca25089 Tests: Fix false hidden module warning.
Signed-off-by: Wilson Snyder <[email protected]>
2015-12-01 18:17:26 -05:00
Wilson Snyder d39ce17dea Makefiles: Turn off make built-in suffixes. 2015-11-28 17:33:01 -05:00
Johan Bjork 373a68ec8b Fix dtype indexing into arrays, bug1007.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-24 21:34:07 -05:00
Johan Bjork 5613758ee3 Fix array slicing of non-const indexes, bug1006.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-24 21:28:04 -05:00
Johan Bjork 2102f86909 Fix genvar constant propagation, bug1003.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-22 21:16:13 -05:00
Wilson Snyder d5ea785de7 Commentary; last commit was bug1004 2015-11-22 21:13:16 -05:00
Johan Bjork 9edd28d2ed Fix genvar constant propagation from package, bug1003.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-22 20:46:26 -05:00
Wilson Snyder 7698af5178 Tests 2015-11-14 20:53:36 -05:00
Wilson Snyder 52ae451f5c Fix interface inside generate, bug998. 2015-11-14 09:06:09 -05:00
Wilson Snyder 9254443cd4 Fix casts under generates, bug999. 2015-11-12 22:29:42 -05:00
Johan Bjork 4e4bc7b90f Fix constant function assigned to packed structs, bug997.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-11 20:49:45 -05:00
Johan Bjork c7e0f2e196 Fix function calls on arrayed interface, bug994.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-11 20:40:24 -05:00
Wilson Snyder acabaab6ac Internals: Avoid tristate coredump. 2015-11-11 20:37:52 -05:00
Wilson Snyder b0a249f338 Fix display %u, %v, %p, %z, bug989. 2015-11-10 21:12:15 -05:00
Wilson Snyder 0cb5d5cc5a Internals: Upgrade some C strings to C++ 2015-11-10 18:59:48 -05:00
Wilson Snyder 9208c87f91 Tests: Better upper-case display formats. 2015-11-10 07:09:53 -05:00
Johan Bjork 0081ce4a75 Fix size-changing cast on packed struct, bug993.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-06 19:12:17 -05:00
Todd Strader 7850f49963 Fix t_scope_map --verbose test, bug955.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-06 18:58:48 -05:00
Wilson Snyder c72ee41142 Add z to param values to avoid conflicts. 2015-11-05 07:00:04 -05:00
Wilson Snyder bf5dee955d Fix real parameters causing bad module names, bug992. 2015-11-04 22:01:21 -05:00
Wilson Snyder 3df23a148a devel release 2015-11-01 08:20:17 -05:00
85 changed files with 1974 additions and 308 deletions
+39
View File
@@ -3,6 +3,45 @@ 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.880 2015-12-19
*** Support display %u, %v, %p, %z, bug989. [Johan Bjork]
**** Fix real parameters causing bad module names, bug992. [Johan Bjork]
**** Fix size-changing cast on packed struct, bug993. [Johan Bjork]
**** Fix function calls on arrayed interface, bug994. [Johan Bjork]
**** Fix arrayed interfaces, bug879, bug1001. [Todd Strader]
**** Fix constant function assigned to packed structs, bug997. [Johan Bjork]
**** Fix interface inside generate, bug998. [Johan Bjork]
**** Fix $signed casts under generates, bug999. [Clifford Wolf]
**** Fix genvar constant propagation, bug1003. [Johan Bjork]
**** Fix parameter constant propagation from package, bug1004. [Johan Bjork]
**** Fix array slicing of non-const indexes, bug1006. [Johan Bjork]
**** Fix dotted generated array error, bug1005. [Jeff Bush, Johan Bjork]
**** Fix error instead of warning on large concat, msg1768. [Paul Rolfe]
**** Fix $bitstoreal constant propagation, bug1012. [Jonathan Kimmitt]
**** Fix model restore crash, bug1013. [Jason McMullan]
**** Fix arrayed instances to unpacked of same size, bug1015. [Varun Koyyalagunta]
**** Fix slices of unpacked arrays with non-zero LSBs.
**** Fix ternary operation with unpacked array, bug1017. [Varun Koyyalagunta].
* Verilator 3.878 2015-11-01
** Add --vpi flag, and fix VPI linkage, bug969. [Arthur Kahlich]
+2
View File
@@ -100,6 +100,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
#### End of system configuration section. ####
######################################################################
.SUFFIXES:
SHELL = /bin/sh
SUBDIRS = src test_verilated test_c test_sc test_regress
+1 -1
View File
@@ -6,7 +6,7 @@
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[3.878 2015-11-01])
AC_INIT([Verilator],[3.880 2015-12-19])
# When releasing, also update header of Changes file
AC_CONFIG_HEADER(src/config_build.h)
+26 -3
View File
@@ -374,7 +374,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
} else {
lwp = va_arg(ap,WDataInP);
ld = lwp[0];
if (fmt == 'u' || fmt == 'd') fmt = 'x'; // Not supported, but show something
if (fmt == 'd' || fmt == '#') fmt = 'x'; // Not supported, but show something
}
int lsb=lbits-1;
if (widthSet && width==0) while (lsb && !VL_BITISSET_W(lwp,lsb)) lsb--;
@@ -404,7 +404,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
output += tmp;
break;
}
case 'u': { // Unsigned decimal
case '#': { // Unsigned decimal
int digits=sprintf(tmp,"%" VL_PRI64 "u",ld);
int needmore = width-digits;
if (needmore>0) {
@@ -438,6 +438,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
output += ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) + '0';
}
break;
break;
case 'o':
for (; lsb>=0; lsb--) {
lsb = (lsb / 3) * 3; // Next digit
@@ -450,6 +451,28 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
+ ((VL_BITISSETLIMIT_W(lwp, lbits, lsb+2)) ? 4 : 0));
}
break;
case 'u': // Packed 2-state
output.reserve(output.size() + 4*VL_WORDS_I(lbits));
for (int i=0; i<VL_WORDS_I(lbits); i++) {
output += (char)((lwp[i] >> 0) & 0xff);
output += (char)((lwp[i] >> 8) & 0xff);
output += (char)((lwp[i] >> 16) & 0xff);
output += (char)((lwp[i] >> 24) & 0xff);
}
case 'z': // Packed 4-state
output.reserve(output.size() + 8*VL_WORDS_I(lbits));
for (int i=0; i<VL_WORDS_I(lbits); i++) {
output += (char)((lwp[i] >> 0) & 0xff);
output += (char)((lwp[i] >> 8) & 0xff);
output += (char)((lwp[i] >> 16) & 0xff);
output += (char)((lwp[i] >> 24) & 0xff);
output += "\0\0\0\0"; // No tristate
}
case 'v': // Strength; assume always strong
for (lsb=lbits-1; lsb>=0; lsb--) {
if ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) output += "St1 ";
else output += "St0 ";
}
case 'x':
for (; lsb>=0; lsb--) {
lsb = (lsb / 4) * 4; // Next digit
@@ -633,7 +656,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
break;
}
case 't': // FALLTHRU // Time
case 'u': { // Unsigned decimal
case '#': { // Unsigned decimal
_vl_vsss_skipspace(fp,floc,fromp,fstr);
_vl_vsss_read(fp,floc,fromp,fstr, tmp, "0123456789+-xXzZ?_");
if (!tmp[0]) goto done;
+1 -1
View File
@@ -201,7 +201,7 @@ void VerilatedRestore::fill() {
if (VL_UNLIKELY(!isOpen())) return;
// Move remaining characters down to start of buffer. (No memcpy, overlaps allowed)
vluint8_t* rp = m_bufp;
for (vluint8_t* sp=m_cp; rp < m_endp;) *rp++ = *sp++; // Overlaps
for (vluint8_t* sp=m_cp; sp < m_endp;) *rp++ = *sp++; // Overlaps
m_endp = m_bufp + (m_endp - m_cp);
m_cp = m_bufp; // Reset buffer
// Read into buffer starting at m_endp
+2
View File
@@ -46,6 +46,8 @@ obj_opt:
obj_dbg:
mkdir $@
.SUFFIXES:
.PHONY: ../verilator_bin ../verilator_bin_dbg ../verilator_coverage_bin_dbg
opt: ../verilator_bin
+2
View File
@@ -327,6 +327,8 @@ V3PreLex_pregen.yy.cpp: V3PreLex.l $(HEADERS)
V3PreLex.yy.cpp: V3PreLex_pregen.yy.cpp $(FLEXFIX)
$(PERL) $(FLEXFIX) V3PreLex <$< >$@
.SUFFIXES:
######################################################################
######################################################################
+2 -3
View File
@@ -94,10 +94,9 @@ void AstNode::init() {
string AstNode::encodeName(const string& namein) {
// Encode signal name raw from parser, then not called again on same signal
const char* start = namein.c_str();
string out;
for (const char* pos = start; *pos; pos++) {
if ((pos==start) ? isalpha(pos[0]) // digits can't lead identifiers
for (string::const_iterator pos = namein.begin(); pos!=namein.end(); ++pos) {
if ((pos==namein.begin()) ? isalpha(pos[0]) // digits can't lead identifiers
: isalnum(pos[0])) {
out += pos[0];
} else if (pos[0]=='_') {
+9 -9
View File
@@ -1604,21 +1604,21 @@ public:
AstNode* selp() const { return op1p(); } // op1 = Select expression
};
class AstUnlinkedVarXRef : public AstNode {
// As-of-yet unlinkable VarXRef
class AstUnlinkedRef : public AstNode {
// As-of-yet unlinkable Ref
private:
string m_name; // Var name
public:
AstUnlinkedVarXRef(FileLine* fl,
AstVarXRef* vxrp, string name, AstNode* crp)
AstUnlinkedRef(FileLine* fl,
AstNode* refp, string name, AstNode* crp)
: AstNode(fl)
, m_name(name) {
addNOp1p(vxrp); addNOp2p(crp); }
ASTNODE_NODE_FUNCS(UnlinkedVarXRef, UNLINKEDVARXREF)
addNOp1p(refp); addNOp2p(crp); }
ASTNODE_NODE_FUNCS(UnlinkedRef, UNLINKEDREF)
// ACCESSORS
virtual string name() const { return m_name; } // * = Var name
AstVarXRef* varxrefp() const { return op1p()->castVarXRef(); } // op1 = VarXRef
AstNode* cellrefp() const { return op2p(); } // op1 = CellArrayRef or CellRef
virtual string name() const { return m_name; } // * = Var name
AstNode* refp() const { return op1p(); } // op1 = VarXRef or AstNodeFTaskRef
AstNode* cellrefp() const { return op2p(); } // op2 = CellArrayRef or CellRef
};
class AstBind : public AstNode {
+27 -2
View File
@@ -56,7 +56,7 @@ public:
m_anyFuncInBegin = false;
}
~BeginState() {}
void userMarkChanged(AstNodeFTask* nodep) {
void userMarkChanged(AstNode* nodep) {
nodep->user1(true);
m_anyFuncInBegin = true;
}
@@ -166,6 +166,7 @@ private:
if (m_unnamedScope != "") {
// Rename it
nodep->name(m_unnamedScope+"__DOT__"+nodep->name());
m_statep->userMarkChanged(nodep);
// Move to module
nodep->unlinkFrBack();
if (m_ftaskp) m_ftaskp->addStmtsp(nodep); // Begins under funcs just move into the func
@@ -175,6 +176,7 @@ private:
virtual void visit(AstCell* nodep, AstNUser*) {
UINFO(8," CELL "<<nodep<<endl);
if (m_namedScope != "") {
m_statep->userMarkChanged(nodep);
// Rename it
nodep->name(m_namedScope+"__DOT__"+nodep->name());
UINFO(8," rename to "<<nodep->name()<<endl);
@@ -182,6 +184,14 @@ private:
nodep->unlinkFrBack();
m_modp->addStmtp(nodep);
}
nodep->iterateChildren(*this);
}
virtual void visit(AstVarXRef* nodep, AstNUser*) {
UINFO(9, " VARXREF "<<nodep<<endl);
if (m_namedScope != "" && nodep->inlinedDots() == "") {
nodep->inlinedDots(m_namedScope);
UINFO(9, " rescope to "<<nodep<<endl);
}
}
virtual void visit(AstScopeName* nodep, AstNUser*) {
// If there's a %m in the display text, we add a special node that will contain the name()
@@ -215,7 +225,7 @@ private:
}
nodep->iterateChildren(*this);
m_ifDepth = prevIfDepth;
}
}
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
@@ -249,6 +259,21 @@ private:
}
nodep->iterateChildren(*this);
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (nodep->varp()->user1()) { // It was converted
UINFO(9, " relinVarRef "<<nodep<<endl);
nodep->name(nodep->varp()->name());
}
nodep->iterateChildren(*this);
}
virtual void visit(AstIfaceRefDType* nodep, AstNUser*) {
// May have changed cell names
// TypeTable is always after all modules, so names are stable
UINFO(8," IFACEREFDTYPE "<<nodep<<endl);
if (nodep->cellp()) nodep->cellName(nodep->cellp()->name());
UINFO(8," rename to "<<nodep<<endl);
nodep->iterateChildren(*this);
}
//--------------------
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
+12 -14
View File
@@ -33,6 +33,7 @@
#include <algorithm>
#include "V3Global.h"
#include "V3String.h"
#include "V3Const.h"
#include "V3Ast.h"
#include "V3Width.h"
@@ -1828,7 +1829,7 @@ private:
}
if (m_doNConst && anyconst) {
//UINFO(9," Display in "<<nodep->text()<<endl);
string dispout = "";
string newFormat = "";
string fmt = "";
bool inPct = false;
AstNode* argp = nodep->exprsp();
@@ -1846,33 +1847,30 @@ private:
switch (tolower(ch)) {
case '%': break; // %% - just output a %
case 'm': break; // %m - auto insert "name"
case 'l': break; // %m - auto insert "library"
case 'l': break; // %l - auto insert "library"
default: // Most operators, just move to next argument
if (argp) {
AstNode* nextp=argp->nextp();
if (argp && argp->castConst()) { // Convert it
string out = argp->castConst()->num().displayed(fmt);
string out = argp->castConst()->num().displayed(nodep->fileline(), fmt);
UINFO(9," DispConst: "<<fmt<<" -> "<<out<<" for "<<argp<<endl);
{ // fmt = out w/ replace % with %% as it must be literal.
fmt = "";
for (string::iterator pos = out.begin(); pos != out.end(); ++pos) {
if (*pos == '%') fmt += '%';
fmt += *pos;
}
}
// fmt = out w/ replace % with %% as it must be literal.
fmt = VString::quotePercent(out);
argp->unlinkFrBack()->deleteTree();
}
argp=nextp;
}
break;
} // switch
dispout += fmt;
newFormat += fmt;
} else {
dispout += ch;
newFormat += ch;
}
}
nodep->text(dispout);
//UINFO(9," Display out "<<nodep->text()<<endl);
if (newFormat != nodep->text()) {
nodep->text(newFormat);
UINFO(9," Display out "<<nodep<<endl);
}
}
if (!nodep->exprsp()
&& nodep->name().find("%") == string::npos
+9 -11
View File
@@ -295,6 +295,7 @@ public:
case 'h': // FALLTHRU
case 'x': // FALLTHRU
case 'b': // FALLTHRU
case 'v': // FALLTHRU
case 's':
got++; format = tolower(ch);
break;
@@ -1273,17 +1274,18 @@ void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
dispp->v3error("Exceeded limit of "+cvtToStr(VL_VALUE_STRING_MAX_WIDTH)+" bits for any $display-like arguments");
}
if (argp && argp->isWide()
&& (fmtLetter=='d'||fmtLetter=='u')) {
&& (fmtLetter=='d'||fmtLetter=='#')) {
argp->v3error("Unsupported: "<<dispp->verilogKwd()<<" of dec format of > 64 bit results (use hex format instead)");
}
if (argp && argp->widthMin()>8 && fmtLetter=='c') {
// Technically legal, but surely not what the user intended.
argp->v3error(dispp->verilogKwd()<<" of char format of > 8 bit result");
argp->v3warn(WIDTH,dispp->verilogKwd()<<"of %c format of > 8 bit value");
}
//string pfmt = "%"+displayFormat(argp, vfmt, fmtLetter)+fmtLetter;
string pfmt;
if ((fmtLetter=='u' || fmtLetter=='d' || fmtLetter=='t')
if ((fmtLetter=='#' || fmtLetter=='d' || fmtLetter=='t')
&& !isScan
&& vfmt == "") { // Size decimal output. Spec says leading spaces, not zeros
double mantissabits = argp->widthMin() - ((fmtLetter=='d')?1:0);
@@ -1341,14 +1343,15 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep,
case 'b': displayArg(nodep,&elistp,isScan, vfmt,'b'); break;
case 'c': displayArg(nodep,&elistp,isScan, vfmt,'c'); break;
case 't': displayArg(nodep,&elistp,isScan, vfmt,'t'); break;
case 'd': displayArg(nodep,&elistp,isScan, vfmt,'u'); break; // Unsigned decimal
case 'd': displayArg(nodep,&elistp,isScan, vfmt,'#'); break; // Unsigned decimal
case 'o': displayArg(nodep,&elistp,isScan, vfmt,'o'); break;
case 'h':
case 'h': //FALLTHRU
case 'x': displayArg(nodep,&elistp,isScan, vfmt,'x'); break;
case 's': displayArg(nodep,&elistp,isScan, vfmt,'s'); break;
case 'e': displayArg(nodep,&elistp,isScan, vfmt,'e'); break;
case 'f': displayArg(nodep,&elistp,isScan, vfmt,'f'); break;
case 'g': displayArg(nodep,&elistp,isScan, vfmt,'g'); break;
case 'v': displayArg(nodep,&elistp,isScan, vfmt,'v'); break;
case 'm': {
if (!scopenamep) nodep->v3fatalSrc("Display with %m but no AstScopeName");
string suffix = scopenamep->scopePrettySymName();
@@ -1363,11 +1366,6 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep,
emitDispState.pushFormat("----");
break;
}
case 'u':
case 'z':
case 'v':
nodep->v3error("Unsupported: $display-like format code: %"<<pos[0]);
break;
default:
nodep->v3error("Unknown $display-like format code: %"<<pos[0]);
break;
@@ -1789,7 +1787,7 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
}
}
}
ofp()->putAlign(isstatic, 4, 0, prefixIfImp.c_str());
ofp()->putAlign(isstatic, 4, 0, prefixIfImp);
}
}
+6 -6
View File
@@ -750,19 +750,19 @@ void V3OutFormatter::putBreak () {
}
}
void V3OutFormatter::putsQuoted(const char* strg) {
void V3OutFormatter::putsQuoted(const string& strg) {
// Quote \ and " for use inside C programs
// Don't use to quote a filename for #include - #include doesn't \ escape.
putcNoTracking('"');
string quoted = V3Number::quoteNameControls(strg);
for (const char* cp=quoted.c_str(); *cp; cp++) {
putcNoTracking (*cp);
for (string::const_iterator cp=quoted.begin(); cp!=quoted.end(); ++cp) {
putcNoTracking (*cp);
}
putcNoTracking('"');
}
void V3OutFormatter::putsNoTracking (const char *strg) {
void V3OutFormatter::putsNoTracking (const string& strg) {
// Don't track {}'s, probably because it's a $display format string
for (const char* cp=strg; *cp; cp++) {
for (string::const_iterator cp=strg.begin(); cp!=strg.end(); ++cp) {
putcNoTracking (*cp);
}
}
@@ -791,7 +791,7 @@ void V3OutFormatter::putcNoTracking (char chr) {
putcOutput (chr);
}
void V3OutFormatter::putAlign (bool/*AlignClass*/ isStatic, int align, int size, const char* prefix) {
void V3OutFormatter::putAlign (bool/*AlignClass*/ isStatic, int align, int size, const string& prefix) {
if (size==0) size=align;
int alignSize = size; if (alignSize>8) alignSize=8;
int& alignr = isStatic ? m_declSAlign : m_declNSAlign;
+3 -5
View File
@@ -140,13 +140,11 @@ public:
void printf(const char* fmt...) VL_ATTR_PRINTF(2);
void puts(const char* strg);
void puts(const string& strg) { puts(strg.c_str()); }
void putsNoTracking(const char* strg);
void putsNoTracking(const string& strg) { putsNoTracking(strg.c_str()); }
void putsQuoted(const char* strg);
void putsQuoted(const string& strg) { putsQuoted(strg.c_str()); }
void putsNoTracking(const string& strg);
void putsQuoted(const string& strg);
void putBreak(); // Print linebreak if line is too wide
void putBreakExpr(); // Print linebreak in expression if line is too wide
void putAlign(bool isstatic/*AlignClass*/, int align, int size=0/*=align*/, const char* prefix=""); // Declare a variable, with natural alignment
void putAlign(bool isstatic/*AlignClass*/, int align, int size=0/*=align*/, const string& prefix=""); // Declare a variable, with natural alignment
void putbs(const char* strg) { putBreakExpr(); puts(strg); }
void putbs(const string& strg) { putBreakExpr(); puts(strg); }
bool exceededWidth() const { return m_column > WIDTH; }
+101 -16
View File
@@ -36,6 +36,7 @@
#include "V3Inst.h"
#include "V3Ast.h"
#include "V3Changed.h"
#include "V3Const.h"
//######################################################################
// Inst state, as a visitor of each AstNode
@@ -105,7 +106,9 @@ private:
exprp);
m_modp->addStmtp(assp);
if (debug()>=9) assp->dumpTree(cout," _new: ");
} else if (nodep->modVarp()->isIfaceRef()) {
} else if (nodep->modVarp()->isIfaceRef()
|| (nodep->modVarp()->subDTypep()->castUnpackArrayDType()
&& nodep->modVarp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())) {
// Create an AstAssignVarScope for Vars to Cells so we can link with their scope later
AstNode* lhsp = new AstVarXRef (exprp->fileline(), nodep->modVarp(), m_cellp->name(), false);
AstVarRef* refp = exprp->castVarRef();
@@ -171,7 +174,7 @@ private:
m_cellRangep = nodep->rangep();
UINFO(4," CELL "<<nodep<<endl);
AstVar *ifaceVarp = nodep->nextp()->castVar();
AstVar* ifaceVarp = nodep->nextp()->castVar();
bool isIface = ifaceVarp
&& ifaceVarp->dtypep()->castUnpackArrayDType()
&& ifaceVarp->dtypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
@@ -192,9 +195,11 @@ private:
// If this AstCell is actually an interface instantiation, let's ensure we also clone
// the IfaceRef.
if (isIface) {
AstUnpackArrayDType *arrdtype = ifaceVarp->dtypep()->castUnpackArrayDType();
AstUnpackArrayDType* arrdtype = ifaceVarp->dtypep()->castUnpackArrayDType();
AstIfaceRefDType* origIfaceRefp = arrdtype->subDTypep()->castIfaceRefDType();
origIfaceRefp->cellp(NULL);
AstVar* varNewp = ifaceVarp->cloneTree(false);
AstIfaceRefDType *ifaceRefp = arrdtype->subDTypep()->castIfaceRefDType()->cloneTree(false);
AstIfaceRefDType* ifaceRefp = arrdtype->subDTypep()->castIfaceRefDType()->cloneTree(false);
arrdtype->addNextHere(ifaceRefp);
ifaceRefp->cellp(newp);
ifaceRefp->cellName(newp->name());
@@ -219,6 +224,32 @@ private:
nodep->iterateChildren(*this);
}
virtual void visit(AstVar* nodep, AstNUser*) {
bool isIface = nodep->dtypep()->castUnpackArrayDType()
&& nodep->dtypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
if (isIface) {
AstUnpackArrayDType* arrdtype = nodep->dtypep()->castUnpackArrayDType();
AstNode* prev = NULL;
for (int i = arrdtype->lsb(); i <= arrdtype->msb(); ++i) {
AstVar* varNewp = nodep->cloneTree(false);
AstIfaceRefDType* ifaceRefp = arrdtype->subDTypep()->castIfaceRefDType()->cloneTree(false);
arrdtype->addNextHere(ifaceRefp);
ifaceRefp->cellp(NULL);
varNewp->name(varNewp->name() + "__BRA__" + cvtToStr(i) + "__KET__");
varNewp->origName(varNewp->origName() + "__BRA__" + cvtToStr(i) + "__KET__");
varNewp->dtypep(ifaceRefp);
if (!prev) {
prev = varNewp;
} else {
prev->addNextHere(varNewp);
}
}
nodep->addNextHere(prev);
if (debug()==9) { prev->dumpTree(cout, "newintf: "); cout << endl; }
}
nodep->iterateChildren(*this);
}
virtual void visit(AstPin* nodep, AstNUser*) {
// Any non-direct pins need reconnection with a part-select
if (!nodep->exprp()) return; // No-connect
@@ -226,7 +257,20 @@ private:
UINFO(4," PIN "<<nodep<<endl);
int pinwidth = nodep->modVarp()->width();
int expwidth = nodep->exprp()->width();
if (expwidth == pinwidth) {
pair<uint32_t,uint32_t> pinDim = nodep->modVarp()->dtypep()->dimensions(false);
pair<uint32_t,uint32_t> expDim = nodep->exprp()->dtypep()->dimensions(false);
UINFO(4," PINVAR "<<nodep->modVarp()<<endl);
UINFO(4," EXP "<<nodep->exprp()<<endl);
UINFO(4," pinwidth ew="<<expwidth<<" pw="<<pinwidth
<<" ed="<<expDim.first<<","<<expDim.second
<<" pd="<<pinDim.first<<","<<pinDim.second<<endl);
if (expDim.first == pinDim.first && expDim.second == pinDim.second+1) {
// Connection to array, where array dimensions match the instant dimension
AstNode* exprp = nodep->exprp()->unlinkFrBack();
exprp = new AstArraySel (exprp->fileline(), exprp,
(m_instNum-m_instLsb));
nodep->exprp(exprp);
} else if (expwidth == pinwidth) {
// NOP: Arrayed instants: widths match so connect to each instance
} else if (expwidth == pinwidth*m_cellRangep->elementsConst()) {
// Arrayed instants: one bit for each of the instants (each assign is 1 pinwidth wide)
@@ -245,29 +289,69 @@ private:
} else {
nodep->v3fatalSrc("Width mismatch; V3Width should have errored out.");
}
} else if(AstArraySel *arrselp = nodep->exprp()->castArraySel()) {
if (AstUnpackArrayDType *arrp = arrselp->lhsp()->dtypep()->castUnpackArrayDType()) {
} else if (AstArraySel* arrselp = nodep->exprp()->castArraySel()) {
if (AstUnpackArrayDType* arrp = arrselp->lhsp()->dtypep()->castUnpackArrayDType()) {
if (!arrp->subDTypep()->castIfaceRefDType())
return;
AstConst *constp = arrselp->rhsp()->castConst();
V3Const::constifyParamsEdit(arrselp->rhsp());
AstConst* constp = arrselp->rhsp()->castConst();
if (!constp) {
nodep->v3error("Unsupported: Non-constant index when passing interface to module");
return;
}
string index = AstNode::encodeNumber(constp->toSInt());
AstVarRef *varrefp = arrselp->lhsp()->castVarRef();
AstVarXRef *newp = new AstVarXRef(nodep->fileline(),varrefp->name () + "__BRA__" + index + "__KET__", "", true);
AstVar *varp = varrefp->varp()->cloneTree(true);
varp->name(varp->name() + "__TMP__" + "__BRA__" + index + "__KET__");
varp->dtypep(arrp->subDTypep()->backp()->castIfaceRefDType());
newp->addNextHere(varp);
newp->varp(varp);
newp->dtypep(arrp->subDTypep()->castIfaceRefDType());
AstVarRef* varrefp = arrselp->lhsp()->castVarRef();
AstVarXRef* newp = new AstVarXRef(nodep->fileline(),varrefp->name () + "__BRA__" + index + "__KET__", "", true);
newp->dtypep(nodep->modVarp()->dtypep());
newp->packagep(varrefp->packagep());
arrselp->addNextHere(newp);
arrselp->unlinkFrBack()->deleteTree();
}
} else {
AstVar* pinVarp = nodep->modVarp();
AstUnpackArrayDType* pinArrp = pinVarp->dtypep()->castUnpackArrayDType();
if (!pinArrp || !pinArrp->subDTypep()->castIfaceRefDType())
return;
AstNode* prevp = NULL;
AstNode* prevPinp = NULL;
// Clone the var referenced by the pin, and clone each var referenced by the varref
// Clone pin varp:
for (int i = pinArrp->lsb(); i <= pinArrp->msb(); ++i) {
AstVar* varNewp = pinVarp->cloneTree(false);
AstIfaceRefDType* ifaceRefp = pinArrp->subDTypep()->castIfaceRefDType();
ifaceRefp->cellp(NULL);
varNewp->name(varNewp->name() + "__BRA__" + cvtToStr(i) + "__KET__");
varNewp->origName(varNewp->origName() + "__BRA__" + cvtToStr(i) + "__KET__");
varNewp->dtypep(ifaceRefp);
if (!prevp) {
prevp = varNewp;
} else {
prevp->addNextHere(varNewp);
}
// Now also clone the pin itself and update its varref
AstPin* newp = nodep->cloneTree(false);
newp->modVarp(varNewp);
newp->name(newp->name() + "__BRA__" + cvtToStr(i) + "__KET__");
// And replace exprp with a new varxref
AstVarRef* varrefp = newp->exprp()->castVarRef();
string newname = varrefp->name () + "__BRA__" + cvtToStr(i) + "__KET__";
AstVarXRef* newVarXRefp = new AstVarXRef (nodep->fileline(), newname, "", true);
newVarXRefp->varp(newp->modVarp());
newVarXRefp->dtypep(newp->modVarp()->dtypep());
newp->exprp()->unlinkFrBack()->deleteTree();
newp->exprp(newVarXRefp);
if (!prevPinp) {
prevPinp = newp;
} else {
prevPinp->addNextHere(newp);
}
}
pinVarp->replaceWith(prevp);
nodep->replaceWith(prevPinp);
pushDeletep(pinVarp);
pushDeletep(nodep);
}
}
@@ -343,6 +427,7 @@ public:
// Done. Interface
} else if (!alwaysCvt
&& connectXRefp
&& connectXRefp->varp()
&& connectXRefp->varp()->isIfaceRef()) {
} else if (!alwaysCvt
&& connBasicp
+5 -4
View File
@@ -349,16 +349,17 @@ private:
// may remap interfaces to be more like a class.
if (!nodep->hasIfaceVar()) {
string varName = nodep->name() + "__Viftop"; // V3LinkDot looks for this naming
AstIfaceRefDType *idtypep = new AstIfaceRefDType(nodep->fileline(), nodep->name(),
AstIfaceRefDType* idtypep = new AstIfaceRefDType(nodep->fileline(), nodep->name(),
nodep->modp()->name());
idtypep->ifacep(NULL); // cellp overrides
AstVar *varp;
// In the case of arrayed interfaces, we replace cellp when de-arraying in V3Inst
idtypep->cellp(nodep); // Only set when real parent cell known.
AstVar* varp;
if (nodep->rangep()) {
AstNodeArrayDType *arrp = new AstUnpackArrayDType(nodep->fileline(),VFlagChildDType(), idtypep, nodep->rangep()->cloneTree(true));
AstNodeArrayDType* arrp = new AstUnpackArrayDType(nodep->fileline(),VFlagChildDType(), idtypep, nodep->rangep()->cloneTree(true));
varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName,
VFlagChildDType(), arrp);
} else {
idtypep->cellp(nodep); // Only set when real parent cell known
varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName,
VFlagChildDType(), idtypep);
}
+71 -13
View File
@@ -365,12 +365,22 @@ public:
void insertIfaceVarSym(VSymEnt* symp) { // Where sym is for a VAR of dtype IFACEREFDTYPE
m_ifaceVarSyms.push_back(symp);
}
// Iface for a raw or arrayed iface
static AstIfaceRefDType* ifaceRefFromArray(AstNodeDType* nodep) {
AstIfaceRefDType* ifacerefp = nodep->castIfaceRefDType();
if (!ifacerefp) {
if (AstUnpackArrayDType* arrp = nodep->castUnpackArrayDType()) {
ifacerefp = arrp->subDTypep()->castIfaceRefDType();
}
}
return ifacerefp;
}
void computeIfaceVarSyms() {
for (IfaceVarSyms::iterator it = m_ifaceVarSyms.begin(); it != m_ifaceVarSyms.end(); ++it) {
VSymEnt* varSymp = *it;
AstVar* varp = varSymp->nodep()->castVar();
UINFO(9, " insAllIface se"<<(void*)varSymp<<" "<<varp<<endl);
AstIfaceRefDType* ifacerefp = varp->subDTypep()->castIfaceRefDType();
AstIfaceRefDType* ifacerefp = ifaceRefFromArray(varp->subDTypep());
if (!ifacerefp) varp->v3fatalSrc("Non-ifacerefs on list!");
if (!ifacerefp->ifaceViaCellp()) {
if (!ifacerefp->cellp()) { // Probably a NotFoundModule, or a normal module if made mistake
@@ -408,6 +418,10 @@ public:
// Track and later insert scope aliases; an interface referenced by a child cell connecting to that interface
// Typically lhsp=VAR w/dtype IFACEREF, rhsp=IFACE cell
UINFO(9," insertScopeAlias se"<<(void*)lhsp<<" se"<<(void*)rhsp<<endl);
if (rhsp->nodep()->castCell()
&& !rhsp->nodep()->castCell()->modp()->castIface()) {
rhsp->nodep()->v3fatalSrc("Got a non-IFACE alias RHS");
}
m_scopeAliasMap[samn].insert(make_pair(lhsp, rhsp));
}
void computeScopeAliases() {
@@ -515,6 +529,17 @@ public:
return lookupSymp;
}
static string removeLastInlineScope(const string& name) {
string out = name;
string dot = "__DOT__";
size_t dotPos = out.rfind(dot, out.size() - dot.length() - 2);
if (dotPos == string::npos) {
return "";
} else {
return out.erase(dotPos + dot.length(), string::npos);
}
}
VSymEnt* findSymPrefixed(VSymEnt* lookupSymp, const string& dotname, string& baddot) {
// Find symbol in given point in hierarchy, allowing prefix (post-Inline)
// For simplicity lookupSymp may be passed NULL result from findDotted
@@ -525,7 +550,15 @@ public:
<<((lookupSymp->symPrefix()=="") ? "" : lookupSymp->symPrefix()+dotname)
<<" at se"<<lookupSymp
<<endl);
VSymEnt* foundp = lookupSymp->findIdFallback(lookupSymp->symPrefix() + dotname); // Might be NULL
string prefix = lookupSymp->symPrefix();
VSymEnt* foundp = NULL;
while (!foundp) {
foundp = lookupSymp->findIdFallback(prefix + dotname); // Might be NULL
if (prefix == "") {
break;
}
prefix = removeLastInlineScope(prefix);
}
if (!foundp) baddot = dotname;
return foundp;
}
@@ -842,10 +875,12 @@ class LinkDotFindVisitor : public AstNVisitor {
VSymEnt* insp = m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_packagep);
if (m_statep->forPrimary() && nodep->isGParam()) {
m_paramNum++;
VSymEnt* symp = m_statep->insertSym(m_curSymp, "__paramNumber"+cvtToStr(m_paramNum), nodep, m_packagep);
VSymEnt* symp = m_statep->insertSym(m_curSymp, "__paramNumber" + cvtToStr(m_paramNum),
nodep, m_packagep);
symp->exported(false);
}
if (nodep->subDTypep()->castIfaceRefDType()) {
AstIfaceRefDType* ifacerefp = LinkDotState::ifaceRefFromArray(nodep->subDTypep());
if (ifacerefp) {
// Can't resolve until interfaces and modport names are known; see notes at top
m_statep->insertIfaceVarSym(insp);
}
@@ -1111,7 +1146,7 @@ class LinkDotScopeVisitor : public AstNVisitor {
&& nodep->varp()->isIfaceParent()) {
UINFO(9,"Iface parent ref var "<<nodep->varp()->name()<<" "<<nodep<<endl);
// Find the interface cell the var references
AstIfaceRefDType* dtypep = nodep->varp()->dtypep()->castIfaceRefDType();
AstIfaceRefDType* dtypep = LinkDotState::ifaceRefFromArray(nodep->varp()->dtypep());
if (!dtypep) nodep->v3fatalSrc("Non AstIfaceRefDType on isIfaceRef() var");
UINFO(9,"Iface parent dtype "<<dtypep<<endl);
string ifcellname = dtypep->cellName();
@@ -1154,9 +1189,18 @@ class LinkDotScopeVisitor : public AstNVisitor {
AstVarRef* refp = nodep->rhsp()->castVarRef();
AstVarXRef* xrefp = nodep->rhsp()->castVarXRef();
if (!refp && !xrefp) nodep->v3fatalSrc("Unsupported: Non Var(X)Ref attached to interface pin");
string scopename = refp ? refp->name() : xrefp->name();
string baddot; VSymEnt* okSymp;
VSymEnt* symp = m_statep->findDotted(m_modSymp, scopename, baddot, okSymp);
string inl = (xrefp && xrefp->inlinedDots().size()) ? (xrefp->inlinedDots() + "__DOT__") : "";
VSymEnt* symp = NULL;
string scopename;
while (!symp) {
scopename = refp ? refp->name() : (inl.size() ? (inl + xrefp->name()) : xrefp->name());
string baddot; VSymEnt* okSymp;
symp = m_statep->findDotted(m_modSymp, scopename, baddot, okSymp);
if (inl == "")
break;
inl = LinkDotState::removeLastInlineScope(inl);
}
if (!symp) UINFO(9,"No symbol for interface alias rhs ("<<string(refp?"VARREF ":"VARXREF ")<<scopename<<")"<<endl);
if (!symp) nodep->v3fatalSrc("No symbol for interface alias rhs");
UINFO(5, " Found a linked scope RHS: "<<scopename<<" se"<<(void*)symp<<" "<<symp->nodep()<<endl);
rhsSymp = symp;
@@ -1647,7 +1691,8 @@ private:
}
}
else if (AstVar* varp = foundp->nodep()->castVar()) {
if (AstIfaceRefDType* ifacerefp = varp->subDTypep()->castIfaceRefDType()) {
AstIfaceRefDType* ifacerefp = LinkDotState::ifaceRefFromArray(varp->subDTypep());
if (ifacerefp) {
if (!ifacerefp->ifaceViaCellp()) ifacerefp->v3fatalSrc("Unlinked interface");
// Really this is a scope reference into an interface
UINFO(9,"varref-ifaceref "<<m_ds.m_dotText<<" "<<nodep<<endl);
@@ -1662,11 +1707,13 @@ private:
else if (allowVar) {
AstNode* newp;
if (m_ds.m_dotText != "") {
AstVarXRef* refp = new AstVarXRef(nodep->fileline(), nodep->name(), m_ds.m_dotText, false); // lvalue'ness computed later
AstVarXRef* refp = new AstVarXRef(nodep->fileline(), nodep->name(),
m_ds.m_dotText, false); // lvalue'ness computed later
refp->varp(varp);
m_ds.m_dotText = "";
if (m_ds.m_unresolved && m_ds.m_unlinkedScope) {
newp = new AstUnlinkedVarXRef(nodep->fileline(), refp->castVarXRef(), refp->name(), m_ds.m_unlinkedScope->unlinkFrBack());
newp = new AstUnlinkedRef(nodep->fileline(), refp->castVarXRef(),
refp->name(), m_ds.m_unlinkedScope->unlinkFrBack());
m_ds.m_unlinkedScope = NULL;
m_ds.m_unresolved = false;
} else {
@@ -1857,7 +1904,17 @@ private:
m_ds.m_dotPos = DP_SCOPE;
m_ds.m_dotp = NULL;
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_FINAL) {
nodep->dotted(m_ds.m_dotText); // Maybe ""
if (m_ds.m_unresolved && m_ds.m_unlinkedScope) {
AstNodeFTaskRef *newftaskp = nodep->cloneTree(false);
newftaskp->dotted(m_ds.m_dotText);
AstNode* newp = new AstUnlinkedRef(nodep->fileline(), newftaskp, nodep->name(), m_ds.m_unlinkedScope->unlinkFrBack());
m_ds.m_unlinkedScope = NULL;
m_ds.m_unresolved = false;
nodep->replaceWith(newp);
return;
} else {
nodep->dotted(m_ds.m_dotText); // Maybe ""
}
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_MEMBER) {
// Found a Var, everything following is method call. {scope}.{var}.HERE {method} ( ARGS )
AstNode* varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack();
@@ -2054,10 +2111,11 @@ private:
UINFO(5," AstCellArrayRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
// Expression already iterated
}
virtual void visit(AstUnlinkedVarXRef* nodep, AstNUser*) {
virtual void visit(AstUnlinkedRef* nodep, AstNUser*) {
UINFO(5," AstCellArrayRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
// No need to iterate, if we have a UnlinkedVarXRef, we're already done
}
virtual void visit(AstNode* nodep, AstNUser*) {
// Default: Just iterate
checkNoDot(nodep);
+20 -16
View File
@@ -38,6 +38,7 @@
#include <vector>
#include "V3Global.h"
#include "V3String.h"
#include "V3LinkResolve.h"
#include "V3Ast.h"
@@ -204,7 +205,7 @@ private:
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { // Maybe varxref - so need to clone
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
varrefp->cloneTree(false)));
} else if (AstUnlinkedVarXRef* uvxrp = basefromp->castUnlinkedVarXRef()) { // Maybe varxref - so need to clone
} else if (AstUnlinkedRef* uvxrp = basefromp->castUnlinkedRef()) { // Maybe unlinked - so need to clone
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
uvxrp->cloneTree(false)));
} else if (AstMemberSel* fromp = basefromp->castMemberSel()) {
@@ -255,26 +256,29 @@ private:
}
string expectFormat(AstNode* nodep, const string& format, AstNode* argp, bool isScan) {
// Check display arguments
// Check display arguments, return new format string
string newFormat;
bool inPct = false;
string fmt = "";
for (string::const_iterator it = format.begin(); it != format.end(); ++it) {
char ch = tolower(*it);
char ch = *it;
if (!inPct && ch=='%') {
inPct = true;
fmt = ch;
} else if (inPct && (isdigit(ch) || ch=='.')) {
fmt += ch;
} else if (inPct) {
inPct = false;
fmt += ch;
switch (tolower(ch)) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '.':
inPct = true;
case '%': // %% - just output a %
break;
case '%': break; // %% - just output a %
case 'm': // %m - auto insert "name"
if (isScan) nodep->v3error("Unsupported: %m in $fscanf");
if (isScan) { nodep->v3error("Unsupported: %m in $fscanf"); fmt = ""; }
break;
case 'l': // %l - auto insert "library"
if (isScan) nodep->v3error("Unsupported: %l in $fscanf");
if (isScan) { nodep->v3error("Unsupported: %l in $fscanf"); fmt = ""; }
if (m_modp) fmt = VString::quotePercent(m_modp->prettyName());
break;
default: // Most operators, just move to next argument
if (!V3Number::displayedFmtLegal(ch)) {
@@ -288,11 +292,14 @@ private:
}
break;
} // switch
newFormat += fmt;
} else {
newFormat += ch;
}
}
if (argp && !isScan) {
int skipCount = 0; // number of args consume by any additional format strings
string newFormat(format);
while (argp) {
if (skipCount) {
argp = argp->nextp();
@@ -338,10 +345,8 @@ private:
argp = argp->nextp();
}
}
return newFormat;
} else {
return string();
}
return newFormat;
}
void expectDescriptor(AstNode* nodep, AstNodeVarRef* filep) {
@@ -372,8 +377,7 @@ private:
virtual void visit(AstSFormatF* nodep, AstNUser*) {
nodep->iterateChildren(*this);
string newFormat = expectFormat(nodep, nodep->text(), nodep->exprsp(), false);
if (newFormat.size())
nodep->text(newFormat);
nodep->text(newFormat);
if ((nodep->backp()->castDisplay() && nodep->backp()->castDisplay()->displayType().needScopeTracking())
|| nodep->formatScopeTracking()) {
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
+60 -17
View File
@@ -396,12 +396,12 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
if (binary) {
out<<"b";
out<<displayed("%0b");
out<<displayed(m_fileline, "%0b");
}
else {
if (prefixed) out<<"h";
// Always deal with 4 bits at once. Note no 4-state, it's above.
out<<displayed("%0h");
out<<displayed(m_fileline, "%0h");
}
return out.str();
}
@@ -409,9 +409,8 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
string V3Number::quoteNameControls(const string& namein) {
// Encode control chars into C style escapes
// Reverse is V3Parse::deQuote
const char* start = namein.c_str();
string out;
for (const char* pos = start; *pos; pos++) {
for (string::const_iterator pos=namein.begin(); pos!=namein.end(); ++pos) {
if (pos[0]=='\\' || pos[0]=='"') {
out += string("\\")+pos[0];
} else if (pos[0]=='\n') {
@@ -424,7 +423,8 @@ string V3Number::quoteNameControls(const string& namein) {
out += pos[0];
} else {
// This will also cover \a etc
char octal[10]; sprintf(octal,"\\%03o",pos[0]);
// Can't use %03o as messes up when signed
char octal[10]; sprintf(octal,"\\%o%o%o",(pos[0]>>6)&3, (pos[0]>>3)&7, pos[0]&7);
out += octal;
}
}
@@ -442,16 +442,20 @@ bool V3Number::displayedFmtLegal(char format) {
case 'g': return true;
case 'h': return true;
case 'o': return true;
case 'p': return true; // Pattern
case 's': return true;
case 't': return true;
case 'u': return true; // Packed 2-state
case 'v': return true; // Strength
case 'x': return true;
case 'z': return true; // Packed 4-state
case '@': return true; // Packed string
case '~': return true; // Signed decimal
default: return false;
}
}
string V3Number::displayed(const string& vformat) const {
string V3Number::displayed(FileLine*fl, const string& vformat) const {
string::const_iterator pos = vformat.begin();
UASSERT(pos != vformat.end() && pos[0]=='%', "$display-like function with non format argument "<<*this);
++pos;
@@ -496,14 +500,12 @@ string V3Number::displayed(const string& vformat) const {
return str;
}
case 'c': {
if (this->width()>8) m_fileline->v3error("$display-like format of char of > 8 bit value");
int v = bitsValue(0, 8);
str += (char)(v);
if (this->width()>8) fl->v3warn(WIDTH,"$display-like format of %c format of > 8 bit value");
unsigned int v = bitsValue(0, 8);
char strc[2]; strc[0] = v&0xff; strc[1] = '\0';
str = strc;
return str;
}
case '@': { // Packed string
return toString();
}
case 's': {
// Spec says always drop leading zeros, this isn't quite right, we space pad.
int bit=this->width()-1;
@@ -532,7 +534,7 @@ string V3Number::displayed(const string& vformat) const {
fmtsize = cvtToStr(int(dchars));
}
if (width() > 64) {
m_fileline->v3error("Unsupported: $display-like format of decimal of > 64 bit results (use hex format instead)");
fl->v3error("Unsupported: $display-like format of decimal of > 64 bit results (use hex format instead)");
return "ERR";
}
if (issigned) {
@@ -555,8 +557,45 @@ string V3Number::displayed(const string& vformat) const {
sprintf(tmp, vformat.c_str(), toDouble());
return tmp;
}
// 'l' // Library - converted to text by V3LinkResolve
// 'p' // Packed - converted to another code by V3Width
case 'u': { // Packed 2-state
for (int i=0; i<words(); i++) {
str += (char)((m_value[i] >> 0) & 0xff);
str += (char)((m_value[i] >> 8) & 0xff);
str += (char)((m_value[i] >> 16) & 0xff);
str += (char)((m_value[i] >> 24) & 0xff);
}
return str;
}
case 'z': { // Packed 4-state
for (int i=0; i<words(); i++) {
str += (char)((m_value[i] >> 0) & 0xff);
str += (char)((m_value[i] >> 8) & 0xff);
str += (char)((m_value[i] >> 16) & 0xff);
str += (char)((m_value[i] >> 24) & 0xff);
str += (char)((m_valueX[i] >> 0) & 0xff);
str += (char)((m_valueX[i] >> 8) & 0xff);
str += (char)((m_valueX[i] >> 16) & 0xff);
str += (char)((m_valueX[i] >> 24) & 0xff);
}
return str;
}
case 'v': { // Strength
int bit = width()-1;
for (; bit>=0; bit--) {
if (bitIs0(bit)) str+="St0 "; // Yes, always a space even for bit 0
else if (bitIs1(bit)) str+="St1 ";
else if (bitIsZ(bit)) str+="StZ ";
else str+="StX";
}
return str;
}
case '@': { // Packed string
return toString();
}
default:
m_fileline->v3fatalSrc("Unknown $display-like format code for number: %"<<pos[0]);
fl->v3fatalSrc("Unknown $display-like format code for number: %"<<pos[0]);
return "ERR";
}
}
@@ -939,7 +978,7 @@ V3Number& V3Number::opRepl (const V3Number& lhs, const V3Number& rhs) { // rhs i
V3Number& V3Number::opRepl (const V3Number& lhs, uint32_t rhsval) { // rhs is # of times to replicate
// i op repl, L(i)*value(rhs) bit return
setZero();
if (rhsval>8192) m_fileline->v3fatal("More than a 8k bit replication is probably wrong: "<<rhsval);
if (rhsval>8192) m_fileline->v3warn(WIDTHCONCAT,"More than a 8k bit replication is probably wrong: "<<rhsval);
int obit = 0;
for (unsigned times=0; times<rhsval; times++) {
for(int bit=0; bit<lhs.width(); bit++) {
@@ -1627,14 +1666,18 @@ V3Number& V3Number::opRealToBits (const V3Number& lhs) {
if (lhs.width()!=64 || this->width()!=64) {
m_fileline->v3fatalSrc("Real operation on wrong sized number");
}
return opAssign(lhs);
opAssign(lhs);
m_double = false;
return *this;
}
V3Number& V3Number::opBitsToRealD (const V3Number& lhs) {
// Conveniently our internal format is identical so we can copy bits...
if (lhs.width()!=64 || this->width()!=64) {
m_fileline->v3fatalSrc("Real operation on wrong sized number");
}
return opAssign(lhs);
opAssign(lhs);
m_double = true;
return *this;
}
V3Number& V3Number::opNegateD (const V3Number& lhs) {
return setDouble(- lhs.toDouble());
+1 -1
View File
@@ -171,7 +171,7 @@ public:
// ACCESSORS
string ascii(bool prefixed=true, bool cleanVerilog=false) const;
static string quoteNameControls(const string& namein); // Add backslash quotes to strings
string displayed(const string& format) const;
string displayed(FileLine* fl, const string& format) const;
static bool displayedFmtLegal(char format); // Is this a valid format letter?
int width() const { return m_width; }
int widthMin() const; // Minimum width that can represent this number (~== log2(num)+1)
+55 -32
View File
@@ -108,7 +108,7 @@ private:
typedef deque<AstCell*> CellList;
CellList m_cellps; // Cells left to process (in this module)
string m_unlinkedTxt; // Text for AstUnlinkedVarXRef
string m_unlinkedTxt; // Text for AstUnlinkedRef
// METHODS
static int debug() {
@@ -139,7 +139,7 @@ private:
char ch = varp->user4()&255;
string st = cvtToStr(ch);
while (index) {
st += cvtToStr(char((index%26)+'A'));
st += cvtToStr(char((index%25)+'A'));
index /= 26;
}
return st;
@@ -148,7 +148,7 @@ private:
// Given a compilcated object create a number to use for param module assignment
// Ideally would be relatively stable if design changes (not use pointer value),
// and must return same value given same input node
// Return must presently be numberic so doesn't collide with 'small' alphanumeric parameter names
// Return must presently be numeric so doesn't collide with 'small' alphanumeric parameter names
ValueMap::iterator it = m_valueMap.find(nodep);
if (it != m_valueMap.end()) {
return cvtToStr(it->second);
@@ -162,7 +162,8 @@ private:
else { m_nextValueMap.insert(make_pair(bucket, offset + 1)); }
int num = bucket + offset * BUCKETS;
m_valueMap.insert(make_pair(nodep, num));
return cvtToStr(num);
// 'z' just to make sure we don't collide with a normal non-hashed number
return (string)"z"+cvtToStr(num);
}
}
void relinkPins(VarCloneMap* clonemapp, AstPin* startpinp) {
@@ -253,41 +254,44 @@ private:
virtual void visit(AstVarXRef* nodep, AstNUser*) {
nodep->varp(NULL); // Needs relink, as may remove pointed-to var
}
virtual void visit(AstUnlinkedVarXRef* nodep, AstNUser*) {
m_unlinkedTxt.clear();
virtual void visit(AstUnlinkedRef* nodep, AstNUser*) {
AstVarXRef* varxrefp = nodep->op1p()->castVarXRef();
AstNodeFTaskRef* taskrefp = nodep->op1p()->castNodeFTaskRef();
if (varxrefp) {
m_unlinkedTxt = varxrefp->dotted();
} else if (taskrefp) {
m_unlinkedTxt = taskrefp->dotted();
} else {
nodep->v3fatalSrc("Unexpected AstUnlinkedRef node");
return;
}
nodep->cellrefp()->iterate(*this);
nodep->varxrefp()->dotted(m_unlinkedTxt);
nodep->replaceWith(nodep->varxrefp()->unlinkFrBack());
if (varxrefp) {
varxrefp->dotted(m_unlinkedTxt);
} else {
taskrefp->dotted(m_unlinkedTxt);
}
nodep->replaceWith(nodep->op1p()->unlinkFrBack());
pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstCellArrayRef* nodep, AstNUser*) {
V3Const::constifyParamsEdit(nodep->selp());
if (AstConst* constp = nodep->selp()->castConst()) {
string index = AstNode::encodeNumber(constp->toSInt());
m_unlinkedTxt += nodep->name() + "__BRA__"+index+"__KET__";
string replacestr = nodep->name() + "__BRA__??__KET__";
size_t pos = m_unlinkedTxt.find(replacestr);
if (pos == string::npos) {
nodep->v3error("Could not find array index in unlinked text: '" << m_unlinkedTxt << "' for node: " << nodep);
return;
}
m_unlinkedTxt.replace(pos, replacestr.length(), nodep->name() + "__BRA__"+index+"__KET__");
} else {
nodep->v3error("Could not expand constant selection inside dotted reference: "<<nodep->selp()->prettyName());
return;
}
}
virtual void visit(AstCellRef* nodep, AstNUser*) {
// Children must be CellArrayRef, CellRef or ParseRef
if (nodep->cellp()->castCellArrayRef() || nodep->cellp()->castCellRef()) {
nodep->cellp()->iterate(*this);
} else if (nodep->cellp()->castParseRef()) {
m_unlinkedTxt += nodep->cellp()->name();
} else {
nodep->v3error("Could not elaborate dotted reference (LHS): "<<nodep->cellp()->prettyName());
}
m_unlinkedTxt += ".";
if (nodep->exprp()->castCellArrayRef() || nodep->exprp()->castCellRef()) {
nodep->exprp()->iterate(*this);
} else if (nodep->exprp()->castParseRef()) {
m_unlinkedTxt += nodep->exprp()->name();
} else {
nodep->v3error("Could not elaborate dotted reference (RHS): "<<nodep->exprp()->prettyName());
}
}
// Generate Statements
virtual void visit(AstGenerate* nodep, AstNUser*) {
@@ -470,9 +474,13 @@ void ParamVisitor::visitCell(AstCell* nodep) {
// Setting parameter to its default value. Just ignore it.
// This prevents making additional modules, and makes coverage more
// obvious as it won't show up under a unique module page name.
} else {
} else if (!constp->num().isDouble() && !constp->num().isString()
&& !constp->num().isFourState() && !constp->num().isNegative()) {
longname += "_" + paramSmallName(nodep->modp(),pinp->modVarp())+constp->num().ascii(false);
any_overrides = true;
} else {
longname += "_" + paramSmallName(nodep->modp(),pinp->modVarp())+paramValueNumber(constp);
any_overrides = true;
}
}
}
@@ -481,8 +489,12 @@ void ParamVisitor::visitCell(AstCell* nodep) {
AstVar* modvarp = pinp->modVarp();
if (modvarp->isIfaceRef()) {
AstIfaceRefDType* portIrefp = modvarp->subDTypep()->castIfaceRefDType();
if (!portIrefp) {
portIrefp = modvarp->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
}
AstIfaceRefDType* pinIrefp = NULL;
AstNode *exprp = pinp->exprp();
AstNode* exprp = pinp->exprp();
if (exprp
&& exprp->castVarRef()
&& exprp->castVarRef()->varp()
@@ -498,12 +510,23 @@ void ParamVisitor::visitCell(AstCell* nodep) {
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())
pinIrefp = exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
//UINFO(9," portIfaceRef "<<portIrefp<<endl);
else if (exprp
&& exprp->castVarRef()
&& exprp->castVarRef()->varp()
&& exprp->castVarRef()->varp()->subDTypep()
&& exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()
&& exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()
&& exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())
pinIrefp = exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
if (!pinIrefp) {
UINFO(9," portIfaceRef "<<portIrefp<<endl);
if (!portIrefp) {
pinp->v3error("Interface port '"<<modvarp->prettyName()<<"' is not an interface" << modvarp);
} else if (!pinIrefp) {
pinp->v3error("Interface port '"<<modvarp->prettyName()<<"' is not connected to interface/modport pin expression");
} else {
//UINFO(9," pinIfaceRef "<<pinIrefp<<endl);
UINFO(9," pinIfaceRef "<<pinIrefp<<endl);
if (portIrefp->ifaceViaCellp() != pinIrefp->ifaceViaCellp()) {
UINFO(9," IfaceRefDType needs reconnect "<<pinIrefp<<endl);
longname += "_" + paramSmallName(nodep->modp(),pinp->modVarp())+paramValueNumber(pinIrefp);
+57 -37
View File
@@ -255,6 +255,7 @@ private:
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (jumpingOver(nodep)) return;
if (!optimizable()) return; // Accelerate
nodep->varp()->iterateChildren(*this);
AstNode* vscp = varOrScope(nodep);
// We can't have non-delayed assignments with same value on LHS and RHS
@@ -282,10 +283,10 @@ private:
if (!m_params && (vscp->user1() & VU_LV)) clearOptimizable(nodep,"Var write & read");
vscp->user1( vscp->user1() | VU_RV);
bool isConst = nodep->varp()->isParam();
AstConst* constp = (isConst ? nodep->varp()->valuep()->castConst() : NULL);
if (isConst && constp) { // Propagate PARAM constants for constant function analysis
V3Number* nump = isConst ? fetchNumberNull(nodep->varp()->valuep()) : NULL;
if (isConst && nump) { // Propagate PARAM constants for constant function analysis
if (!m_checkOnly && optimizable()) {
newNumber(vscp)->opAssign(constp->num());
newNumber(vscp)->opAssign(*nump);
}
} else {
if (m_checkOnly) varRefCb (nodep);
@@ -451,6 +452,56 @@ private:
}
}
}
bool handleAssignSel(AstNodeAssign* nodep, AstSel* selp, AstVarRef** outVarrefp, int depth) {
checkNodeInfo(selp);
AstVarRef* varrefp = selp->fromp()->castVarRef();
if (!varrefp) {
selp = selp->lhsp()->castSel();
if (selp) {
if (!handleAssignSel(nodep, selp, &varrefp, depth+1)) {
clearOptimizable(nodep, "Select LHS isn't simple variable");
return false;
}
}
}
if (m_checkOnly) {
nodep->iterateChildren(*this);
} else {
selp->lsbp()->iterateAndNext(*this);
nodep->rhsp()->iterateAndNext(*this);
if (optimizable()) {
AstNode* vscp;
if (varrefp) {
vscp = varOrScope(varrefp);
V3Number outnum = V3Number(nodep->fileline());
if (V3Number* vscpnump = fetchOutNumberNull(vscp)) {
outnum = *vscpnump;
} else if (V3Number* vscpnump = fetchNumberNull(vscp)) {
outnum = *vscpnump;
} else { // Assignment to unassigned variable, all bits are X or 0
outnum = V3Number(nodep->fileline(), varrefp->varp()->widthMin());
if (varrefp->varp()->basicp() && varrefp->varp()->basicp()->isZeroInit()) {
outnum.setAllBits0();
} else {
outnum.setAllBitsX();
}
}
if (depth == 0) {
outnum.opSelInto(*fetchNumber(nodep->rhsp()),
*fetchNumber(selp->lsbp()),
selp->widthConst());
assignOutNumber(nodep, vscp, &outnum);
}
}
}
}
if (outVarrefp) *outVarrefp = varrefp;
return true;
}
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
if (jumpingOver(nodep)) return;
if (!optimizable()) return; // Accelerate
@@ -462,41 +513,10 @@ private:
if (m_anyAssignDly) clearOptimizable(nodep, "Mix of dly/non-dly assigns");
m_anyAssignComb = true;
}
if (AstSel* selp = nodep->lhsp()->castSel()) {
if (!m_params) { clearOptimizable(nodep, "LHS has select"); return; }
checkNodeInfo(selp);
AstVarRef* varrefp = selp->fromp()->castVarRef();
if (!varrefp) {
clearOptimizable(nodep, "Select LHS isn't simple variable");
return;
}
if (m_checkOnly) {
nodep->iterateChildren(*this);
} else {
selp->lsbp()->iterateAndNext(*this);
nodep->rhsp()->iterateAndNext(*this);
if (optimizable()) {
AstNode* vscp = varOrScope(varrefp);
if (optimizable()) {
V3Number outnum (nodep->fileline(), varrefp->varp()->widthMin());
if (V3Number* outnump = fetchOutNumberNull(vscp)) {
outnum = *outnump;
} else if (V3Number* outnump = fetchNumberNull(vscp)) {
outnum = *outnump;
} else { // Assignment to unassigned variable, all bits are X or 0
if (varrefp->varp()->basicp() && varrefp->varp()->basicp()->isZeroInit()) {
outnum.setAllBits0();
} else {
outnum.setAllBitsX();
}
}
outnum.opSelInto(*fetchNumber(nodep->rhsp()),
*fetchNumber(selp->lsbp()),
selp->widthConst());
assignOutNumber(nodep, vscp, &outnum);
}
}
}
handleAssignSel(nodep, selp, NULL, 0);
}
else if (!nodep->lhsp()->castVarRef()) {
clearOptimizable(nodep, "LHS isn't simple variable");
@@ -723,7 +743,7 @@ private:
break;
}
string format = string("%") + pos[0];
result += nump->displayed(format);
result += nump->displayed(nodep->fileline(), format);
} else {
switch (tolower(pos[0])) {
case '%':
+9 -15
View File
@@ -99,7 +99,9 @@ class SliceCloneVisitor : public AstNVisitor {
// Reassign the bitp()
if (nodep->length() > 1) {
if (AstConst* bitp = nodep->bitp()->castConst()) {
unsigned idx = nodep->start() + m_selBits[m_vecIdx][m_depth];
AstUnpackArrayDType* adtypep = nodep->fromp()->dtypep()->skipRefp()->castUnpackArrayDType();
if (!adtypep) nodep->v3fatalSrc("slice select tried to expand an array without an ArrayDType");
unsigned idx = nodep->start() + m_selBits[m_vecIdx][m_depth] - adtypep->lsb();
AstNode* constp = new AstConst(bitp->fileline(), V3Number(bitp->fileline(), bitp->castConst()->num().width(), idx));
bitp->replaceWith(constp);
} else {
@@ -272,7 +274,9 @@ class SliceVisitor : public AstNVisitor {
int x = msb; msb = lsb; lsb = x;
}
UINFO(9," ArraySel-child: "<<topp<<endl);
AstArraySel* newp = new AstArraySel(nodep->fileline(), topp, new AstConst(nodep->fileline(),lsb));
AstArraySel* newp = new AstArraySel(nodep->fileline(), topp,
// "lsb-lsb": Arrays are zero-based so index 0 is always lsb
new AstConst(nodep->fileline(), lsb-lsb));
if (!newp->dtypep()) {
newp->v3fatalSrc("ArraySel dtyping failed when resolving slice"); // see ArraySel constructor
}
@@ -361,6 +365,8 @@ class SliceVisitor : public AstNVisitor {
// The conditional must be a single bit so only look at the expressions
nodep->expr1p()->accept(*this);
nodep->expr2p()->accept(*this);
// Downstream data type may have changed; propagate up
nodep->dtypeFrom(nodep->expr1p());
}
// Return the first AstVarRef under the node
@@ -447,18 +453,6 @@ class SliceVisitor : public AstNVisitor {
// Unpacked dimensions are referenced first, make sure we have them all
nodep->v3error("Unary operator used across unpacked dimensions");
}
//Dead code
//else if ((int)(dim - (varDim.second)) < 0) {
// // Implicit packed dimensions are allowed, make them explicit
// uint32_t newDim = (varDim.second) - dim;
// AstNode* clonep = nodep->lhsp()->cloneTree(false);
// clonep->user1p(refp);
// AstNode* newp = insertImplicit(clonep, dim+1, newDim);
// nodep->lhsp()->replaceWith(newp); VL_DANGLING(refp);
// int clones = countClones(nodep->lhsp()->castArraySel());
// nodep->user2(clones);
// SliceCloneVisitor scv(nodep);
//}
}
}
virtual void visit(AstRedOr* nodep, AstNUser*) {
@@ -503,5 +497,5 @@ public:
void V3Slice::sliceAll(AstNetlist* rootp) {
UINFO(2,__FUNCTION__<<": "<<endl);
SliceVisitor visitor(rootp);
V3Global::dumpCheckGlobalTree("slices.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("slice.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+9
View File
@@ -77,6 +77,15 @@ string VString::downcase(const string& str) {
return out;
}
string VString::quotePercent(const string& str) {
string out;
for (string::const_iterator pos = str.begin(); pos != str.end(); ++pos) {
if (*pos == '%') out += '%';
out += *pos;
}
return out;
}
//######################################################################
// VHashSha1
+1
View File
@@ -35,6 +35,7 @@ public:
// METHODS (generic string utilities)
static bool wildmatch(const char* s, const char* p);
static string downcase(const string& str);
static string quotePercent(const string& str);
};
//######################################################################
+1
View File
@@ -1114,6 +1114,7 @@ class TristateVisitor : public TristateBaseVisitor {
AstPin* outpinp;
{
AstVar* outModVarp = (AstVar*) nodep->modVarp()->user4p();
if (!outModVarp) nodep->v3fatalSrc("Unlinked");
AstNode* outexprp = nodep->exprp()->cloneTree(false); // Note has lvalue() set
outpinp = new AstPin(nodep->fileline(),
nodep->pinNum(),
+2 -10
View File
@@ -51,7 +51,6 @@ private:
AstVarScope* m_forVscp; // Iterator variable scope (NULL for generate pass)
AstConst* m_varValuep; // Current value of loop
AstNode* m_ignoreIncp; // Increment node to ignore
AstAttrOf* m_attrp; // Current attribute
bool m_varModeCheck; // Just checking RHS assignments
bool m_varModeReplace; // Replacing varrefs
bool m_varAssignHit; // Assign var hit
@@ -401,12 +400,6 @@ private:
nodep->v3error("V3Begin should have removed standard FORs");
}
}
virtual void visit(AstAttrOf* nodep, AstNUser*) {
AstAttrOf* oldAttr = m_attrp;
m_attrp = nodep;
nodep->iterateChildren(*this);
m_attrp = oldAttr;
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (m_varModeCheck
@@ -416,11 +409,11 @@ private:
UINFO(8," Itervar assigned to: "<<nodep<<endl);
m_varAssignHit = true;
}
if (m_varModeReplace
&& nodep->varp() == m_forVarp
&& nodep->varScopep() == m_forVscp
&& !nodep->lvalue()
&& !m_attrp) { // Most likely under a select
&& !nodep->lvalue()) {
AstNode* newconstp = m_varValuep->cloneTree(false);
nodep->replaceWith(newconstp);
pushDeletep(nodep);
@@ -447,7 +440,6 @@ public:
m_varModeReplace = false;
m_generate = generate;
m_beginName = beginName;
m_attrp = NULL;
//
nodep->accept(*this);
}
+31 -9
View File
@@ -1017,6 +1017,9 @@ private:
if (width < 1) { nodep->v3error("Size-changing cast to zero or negative size"); width=1; }
nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,PRELIM).p());
AstBasicDType* underDtp = nodep->lhsp()->dtypep()->castBasicDType();
if (!underDtp) {
underDtp = nodep->lhsp()->dtypep()->basicp();
}
if (!underDtp) {
nodep->v3error("Unsupported: Size-changing cast on non-basic data type");
underDtp = nodep->findLogicBoolDType()->castBasicDType();
@@ -1894,28 +1897,44 @@ private:
nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p());
//
UINFO(9," Display in "<<nodep->text()<<endl);
string dispout = "";
string newFormat;
bool inPct = false;
AstNode* argp = nodep->exprsp();
string txt = nodep->text();
string fmt;
for (string::const_iterator it = txt.begin(); it!=txt.end(); ++it) {
char ch = *it;
if (!inPct && ch=='%') {
inPct = true;
} else if (inPct && isdigit(ch)) {
fmt = ch;
} else if (inPct && (isdigit(ch) || ch=='.')) {
fmt += ch;
} else if (tolower(inPct)) {
inPct = false;
bool added = false;
switch (tolower(ch)) {
case '%': break; // %% - just output a %
case 'm': break; // %m - auto insert "name"
case 'l': break; // %m - auto insert "library"
case 'd': { // Convert decimal to either 'd' or 'u'
case 'd': { // Convert decimal to either 'd' or '#'
if (argp && argp->isSigned()) { // Convert it
ch = '~';
}
if (argp) argp=argp->nextp();
break;
}
case 'p': { // Packed
// Very hacky and non-compliant; print strings as strings, otherwise as hex
if (argp && argp->dtypep()->basicp()->isString()) { // Convert it
added = true;
newFormat += "\"%@\"";
} else {
added = true;
newFormat += "'h%0h";
}
if (argp) argp=argp->nextp();
break;
}
case 's': { // Convert string to pack string
if (argp && argp->dtypep()->basicp()->isString()) { // Convert it
ch = '@';
@@ -1928,10 +1947,15 @@ private:
break;
}
} // switch
if (!added) {
fmt += ch;
newFormat += fmt;
}
} else {
newFormat += ch;
}
dispout += ch;
}
nodep->text(dispout);
nodep->text(newFormat);
UINFO(9," Display out "<<nodep->text()<<endl);
}
virtual void visit(AstDisplay* nodep, AstNUser* vup) {
@@ -3520,8 +3544,7 @@ AstNode* V3Width::widthParamsEdit (AstNode* nodep) {
// We should do it in bottom-up module order, but it works in any order.
WidthVisitor visitor (true, false);
nodep = visitor.mainAcceptEdit(nodep);
WidthRemoveVisitor rvisitor;
nodep = rvisitor.mainAcceptEdit(nodep);
// No WidthRemoveVisitor, as don't want to drop $signed etc inside gen blocks
return nodep;
}
@@ -3540,8 +3563,7 @@ AstNode* V3Width::widthGenerateParamsEdit(
// We should do it in bottom-up module order, but it works in any order.
WidthVisitor visitor (true, true);
nodep = visitor.mainAcceptEdit(nodep);
WidthRemoveVisitor rvisitor;
nodep = rvisitor.mainAcceptEdit(nodep);
// No WidthRemoveVisitor, as don't want to drop $signed etc inside gen blocks
return nodep;
}
+1
View File
@@ -32,6 +32,7 @@
//######################################################################
/// Remove all $signed, $unsigned, we're done with them.
/// This step is only called on real V3Width, not intermediate e.g. widthParams
class WidthRemoveVisitor : public AstNVisitor {
private:
+1
View File
@@ -223,6 +223,7 @@ void process () {
if (!v3Global.opt.xmlOnly()) {
// Remove cell arrays (must be between V3Width and scoping)
V3Inst::dearrayAll(v3Global.rootp());
V3LinkDot::linkDotArrayed(v3Global.rootp());
}
if (!v3Global.opt.xmlOnly()) {
+2 -2
View File
@@ -239,8 +239,8 @@ void VlcTop::annotateOutputFiles(const string& dirname) {
first = false;
// Multiple columns on same line; print line just once
string indent = "";
for (const char* cp=line.c_str(); isspace(*cp); ++cp) {
indent += *cp;
for (string::const_iterator pos=line.begin(); pos!=line.end() && isspace(*pos); ++pos) {
indent += *pos;
}
line = indent + "verilator_coverage: (next point on previous line)\n";
}
+2 -5
View File
@@ -2060,7 +2060,7 @@ instnameParen<cellp>:
instRangeE<rangep>:
/* empty */ { $$ = NULL; }
| '[' constExpr ']' { $$ = new AstRange($1,$2,$2->cloneTree(true)); }
| '[' constExpr ']' { $$ = new AstRange($1,new AstConst($1,0),$2); }
| '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); }
;
@@ -3735,9 +3735,6 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstRange
return NULL;
}
AstVarType type = GRAMMARP->m_varIO;
if (dtypep->castIfaceRefDType()) {
if (arrayp) { fileline->v3error("Unsupported: Arrayed interfaces"); VL_DANGLING(arrayp); }
}
if (!dtypep) { // Created implicitly
dtypep = new AstBasicDType(fileline, LOGIC_IMPLICIT);
} else { // May make new variables with same type, so clone
@@ -3786,7 +3783,7 @@ string V3ParseGrammar::deQuote(FileLine* fileline, string text) {
string newtext;
unsigned char octal_val = 0;
int octal_digits = 0;
for (const char* cp=text.c_str(); *cp; ++cp) {
for (string::const_iterator cp=text.begin(); cp!=text.end(); ++cp) {
if (quoted) {
if (isdigit(*cp)) {
octal_val = octal_val*8 + (*cp-'0');
+2
View File
@@ -40,6 +40,8 @@ ifeq ($(CFG_WITH_LONGTESTS),yes)
DRIVER_FLAGS += -j 0
endif
.SUFFIXES:
######################################################################
.PHONY: test
+2
View File
@@ -42,6 +42,8 @@ ifeq ($(VM_SP_OR_SC),1)
LIBS += $(SC_LIBS)
endif
.SUFFIXES:
#Default compile, pick up OBJCACHE
%.o: %.cpp
$(OBJCACHE) $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
+2 -1
View File
@@ -1013,7 +1013,8 @@ sub _run {
if ($param{expect}) {
# Compare
my $quoted = quotemeta ($param{expect});
my $bad = ($wholefile !~ /$param{expect}/ms
my $bad = ($wholefile ne $param{expect}
&& $wholefile !~ /$param{expect}/ms
&& $wholefile !~ /$quoted/ms);
if ($bad) {
#print "**BAD $self->{name} $param{logfile} MT $moretry $try\n";
+10 -3
View File
@@ -17,6 +17,10 @@ intf.source intf_inst
assign intf_inst.logic_in_intf = value;
endmodule
function integer return_3();
return 3;
endfunction
module t
#(
parameter N = 6
@@ -27,16 +31,19 @@ module t
generate
genvar i;
for (i = 0;i < 4; i++) begin
for (i = 0;i < 3; i++) begin
assign ifs[i].logic_in_intf = data[i];
end
endgenerate
modify_interface m3 (
.value(data[return_3()]),
.intf_inst(ifs[return_3()]));
modify_interface m (
modify_interface m4 (
.value(data[4]),
.intf_inst(ifs[4]));
modify_interface m1 (
modify_interface m5 (
.value(~ifs[4].logic_in_intf),
.intf_inst(ifs[5]));
+10
View File
@@ -8,6 +8,15 @@ module t;
typedef logic [3:0] mc_t;
typedef mc_t tocast_t;
typedef struct packed {
logic [15:0] data;
} packed_t;
packed_t pdata;
assign pdata.data = 16'h1234;
logic [7:0] logic8bit;
assign logic8bit = $bits(logic8bit)'(pdata >> 8);
mc_t o;
logic [15:0] allones = 16'hffff;
@@ -31,6 +40,7 @@ module t;
(27'(coeff2 * samp2) >>> 11)); // 15' size casting to avoid synthesis/simulator warnings
initial begin
if (logic8bit != 8'h12) $stop;
if (4'shf > 4'sh0) $stop;
if (signed'(4'hf) > 4'sh0) $stop;
if (4'hf < 4'h0) $stop;
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2004 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;
+19
View File
@@ -0,0 +1,19 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2015 by Wilson Snyder.
module t (/*AUTOARG*/);
wire [32767:0] a;
initial begin
// verilator lint_off WIDTHCONCAT
a = {32768{1'b1}};
// verilator lint_on WIDTHCONCAT
if (a[32000] != 1'b1) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2004 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 => ["--lint-only"],
fails=>1,
expect=>
'%Warning-WIDTHCONCAT: t/t_concat_large_bad.v:\d+: More than a 8k bit replication is probably wrong: 32768
%Warning-WIDTHCONCAT: Use .*
%Error: Exiting due to.*',
);
ok(1);
1;
+14
View File
@@ -0,0 +1,14 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2015 by Wilson Snyder.
module t (/*AUTOARG*/);
wire [32767:0] a = {32768{1'b1}};
initial begin
$stop;
end
endmodule
+26 -11
View File
@@ -12,18 +12,33 @@ compile (
execute (
check_finished=>1,
expect=>quotemeta(dequote(
'[0] In top.v: Hi
[0] In top.v.sub
[0] In top.v.sub.subblock
[0] In top.v.sub2
[0] In top.v.sub2.subblock2
expect=>dequote(
q{[0] In top.v: Hi
[0] In top.v.sub (sub)
[0] In top.v.sub.subblock (sub)
[0] In top.v.sub2 (sub2)
[0] In top.v.sub2.subblock2 (sub2)
[0] Back \ Quote "
[0] %X=00c %0X=c %0O=14 %B=000001100
[0] %x=00c %0x=c %0o=14 %b=000001100
[0] %b=000001100 %0b=1100 %b=00000101010111011101110111100110011001100 %0b=101010111011101110111100110011001100 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000 %0b=1010101111000001001000110100010101100111100000010010001101000101011001111000
[0] %B=000001100 %0B=1100 %B=00000101010111011101110111100110011001100 %0B=101010111011101110111100110011001100 %B=000001010101111000001001000110100010101100111100000010010001101000101011001111000 %0B=1010101111000001001000110100010101100111100000010010001101000101011001111000
[0] %d= 12 %0d=12 %d= 46099320012 %0d=46099320012
[0] %D= 12 %0D=12 %D= 46099320012 %0D=46099320012
[0] %h=00c %0h=c %h=00abbbbcccc %0h=abbbbcccc %h=00abc1234567812345678 %0h=abc1234567812345678
[0] %H=00c %0H=c %H=00abbbbcccc %0H=abbbbcccc %H=00abc1234567812345678 %0H=abc1234567812345678
[0] %o=014 %0o=14 %o=00527356746314 %0o=527356746314 %o=012570110642547402215053170 %0o=12570110642547402215053170
[0] %O=014 %0O=14 %O=00527356746314 %0O=527356746314 %O=012570110642547402215053170 %0O=12570110642547402215053170
[0] %x=00c %0x=c %x=00abbbbcccc %0x=abbbbcccc %x=00abc1234567812345678 %0x=abc1234567812345678
[0] %X=00c %0X=c %X=00abbbbcccc %0X=abbbbcccc %X=00abc1234567812345678 %0X=abc1234567812345678
[0] %C=m %0C=m
[0] %c=m %0c=m
[0] %v=St0 St0 St0 St0 St0 St1 St1 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St1 St0 St0 %v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0
[0] %V=St0 St0 St0 St0 St0 St1 St1 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St1 St0 St0 %V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0
[0] %p='hc %0p='hc %p='habbbbcccc %0p='habbbbcccc %p='habc1234567812345678 %0p='habc1234567812345678
[0] %P='hc %0P='hc %P='habbbbcccc %0P='habbbbcccc %P='habc1234567812345678 %0P='habc1234567812345678
[0] %P="sv-str"
[0] %u=dcba %0u=dcba
[0] %U=dcba %0U=dcba
[0] %D= 12 %d= 12 %01d=12 %06d=000012 %6d= 12
[0] %x=00abbbbcccc %0x=abbbbcccc %o=00527356746314 %b=00000101010111011101110111100110011001100
[0] %x=00abc1234567812345678 %0x=abc1234567812345678 %o=012570110642547402215053170 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000
[0] %t= 0 %03t= 0 %0t=0
[0] %s=! %s= what! %s= hmmm!1234
@@ -35,7 +50,7 @@ extra argument: 0000000000000000
[0] Embedded
multiline
*-* All Finished *-*
')),
}),
);
ok(1);
+51 -14
View File
@@ -9,7 +9,8 @@ module t;
reg [31:0] str; initial str = "\000\277\021\n";
reg [47:0] str2; initial str2 = "\000what!";
reg [79:0] str3; initial str3 = "\000hmmm!1234";
reg [8:0] nine;
reg [8:0] nine; initial nine = 12;
string svs = "sv-str";
sub sub ();
sub2 sub2 ();
@@ -23,17 +24,53 @@ module t;
$display("[%0t] Back \\ Quote \"", $time); // Old bug when \" last on the line.
// Display formatting
nine = {3'd0,quad[5:0]};
$display("[%0t] %%X=%X %%0X=%0X %%0O=%0O %%B=%B", $time,
nine, nine, nine, nine);
$display("[%0t] %%x=%x %%0x=%0x %%0o=%0o %%b=%b", $time,
nine, nine, nine, nine);
$display("[%0t] %%b=%b %%0b=%0b %%b=%b %%0b=%0b %%b=%b %%0b=%0b", $time,
nine, nine, quad, quad, wide, wide);
$display("[%0t] %%B=%B %%0B=%0B %%B=%B %%0B=%0B %%B=%B %%0B=%0B", $time,
nine, nine, quad, quad, wide, wide);
$display("[%0t] %%d=%d %%0d=%0d %%d=%d %%0d=%0d", $time,
nine, nine, quad, quad);
$display("[%0t] %%D=%D %%0D=%0D %%D=%D %%0D=%0D", $time,
nine, nine, quad, quad);
$display("[%0t] %%h=%h %%0h=%0h %%h=%h %%0h=%0h %%h=%h %%0h=%0h", $time,
nine, nine, quad, quad, wide, wide);
$display("[%0t] %%H=%H %%0H=%0H %%H=%H %%0H=%0H %%H=%H %%0H=%0H", $time,
nine, nine, quad, quad, wide, wide);
$display("[%0t] %%o=%o %%0o=%0o %%o=%o %%0o=%0o %%o=%o %%0o=%0o", $time,
nine, nine, quad, quad, wide, wide);
$display("[%0t] %%O=%O %%0O=%0O %%O=%O %%0O=%0O %%O=%O %%0O=%0o", $time,
nine, nine, quad, quad, wide, wide);
$display("[%0t] %%x=%x %%0x=%0x %%x=%x %%0x=%0x %%x=%x %%0x=%0x", $time,
nine, nine, quad, quad, wide, wide);
$display("[%0t] %%X=%X %%0X=%0X %%X=%X %%0X=%0X %%X=%X %%0X=%0X", $time,
nine, nine, quad, quad, wide, wide);
//
// verilator lint_off WIDTH
$display("[%0t] %%C=%C %%0C=%0C", $time,
"a"+nine, "a"+nine);
$display("[%0t] %%c=%c %%0c=%0c", $time,
"a"+nine, "a"+nine);
// verilator lint_on WIDTH
$display("[%0t] %%v=%v %%0v=%0v %%v=%v %%0v=%0v %%v=%v %%0v=%0v", $time,
nine, nine, quad, quad, wide, wide);
$display("[%0t] %%V=%V %%0V=%0V %%V=%V %%0V=%0V %%V=%V %%0V=%0V", $time,
nine, nine, quad, quad, wide, wide);
$display("[%0t] %%p=%p %%0p=%0p %%p=%p %%0p=%0p %%p=%p %%0p=%0p", $time,
nine, nine, quad, quad, wide, wide);
$display("[%0t] %%P=%P %%0P=%0P %%P=%P %%0P=%0P %%P=%P %%0P=%0P", $time,
nine, nine, quad, quad, wide, wide);
$display("[%0t] %%P=%P", $time,
svs);
$display("[%0t] %%u=%u %%0u=%0u", $time,
{"a","b","c","d"}, {"a","b","c","d"}); // Avoid binary output
$display("[%0t] %%U=%U %%0U=%0U", $time,
{"a","b","c","d"}, {"a","b","c","d"}); // Avoid binary output
// %z is tested in t_sys_sformat.v
$display("[%0t] %%D=%D %%d=%d %%01d=%01d %%06d=%06d %%6d=%6d", $time,
nine, nine, nine, nine, nine);
$display("[%0t] %%x=%x %%0x=%0x %%o=%o %%b=%b", $time,
quad, quad, quad, quad);
$display("[%0t] %%x=%x %%0x=%0x %%o=%o %%b=%b", $time,
wide, wide, wide, wide);
$display("[%0t] %%t=%t %%03t=%03t %%0t=%0t", $time,
$time, $time, $time);
$display;
@@ -62,9 +99,9 @@ endmodule
module sub;
task write_m;
begin
$write("[%0t] In %m\n", $time);
$write("[%0t] In %m (%l)\n", $time);
begin : subblock
$write("[%0t] In %M\n", $time); // Uppercase %M test
$write("[%0t] In %M (%L)\n", $time); // Uppercase %M test
end
end
endtask
@@ -74,9 +111,9 @@ module sub2;
// verilator no_inline_module
task write_m;
begin
$write("[%0t] In %m\n", $time);
$write("[%0t] In %m (%l)\n", $time);
begin : subblock2
$write("[%0t] In %m\n", $time);
$write("[%0t] In %m (%L)\n", $time);
end
end
endtask
+26 -11
View File
@@ -15,18 +15,33 @@ compile (
execute (
check_finished=>1,
expect=>quotemeta(dequote(
'[0] In top.v: Hi
[0] In top.v.sub
[0] In top.v.sub.subblock
[0] In top.v.sub2
[0] In top.v.sub2.subblock2
expect=>dequote(
q{[0] In top.v: Hi
[0] In top.v.sub (sub)
[0] In top.v.sub.subblock (sub)
[0] In top.v.sub2 (sub2)
[0] In top.v.sub2.subblock2 (sub2)
[0] Back \ Quote "
[0] %X=00c %0X=c %0O=14 %B=000001100
[0] %x=00c %0x=c %0o=14 %b=000001100
[0] %b=000001100 %0b=1100 %b=00000101010111011101110111100110011001100 %0b=101010111011101110111100110011001100 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000 %0b=1010101111000001001000110100010101100111100000010010001101000101011001111000
[0] %B=000001100 %0B=1100 %B=00000101010111011101110111100110011001100 %0B=101010111011101110111100110011001100 %B=000001010101111000001001000110100010101100111100000010010001101000101011001111000 %0B=1010101111000001001000110100010101100111100000010010001101000101011001111000
[0] %d= 12 %0d=12 %d= 46099320012 %0d=46099320012
[0] %D= 12 %0D=12 %D= 46099320012 %0D=46099320012
[0] %h=00c %0h=c %h=00abbbbcccc %0h=abbbbcccc %h=00abc1234567812345678 %0h=abc1234567812345678
[0] %H=00c %0H=c %H=00abbbbcccc %0H=abbbbcccc %H=00abc1234567812345678 %0H=abc1234567812345678
[0] %o=014 %0o=14 %o=00527356746314 %0o=527356746314 %o=012570110642547402215053170 %0o=12570110642547402215053170
[0] %O=014 %0O=14 %O=00527356746314 %0O=527356746314 %O=012570110642547402215053170 %0O=12570110642547402215053170
[0] %x=00c %0x=c %x=00abbbbcccc %0x=abbbbcccc %x=00abc1234567812345678 %0x=abc1234567812345678
[0] %X=00c %0X=c %X=00abbbbcccc %0X=abbbbcccc %X=00abc1234567812345678 %0X=abc1234567812345678
[0] %C=m %0C=m
[0] %c=m %0c=m
[0] %v=St0 St0 St0 St0 St0 St1 St1 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St1 St0 St0 %v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 %0v=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0
[0] %V=St0 St0 St0 St0 St0 St1 St1 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St1 St0 St0 %V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St0 St1 St1 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 St1 St1 St0 St0 %V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 %0V=St0 St0 St0 St0 St0 St1 St0 St1 St0 St1 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0 St0 St0 St0 St1 St0 St0 St1 St0 St0 St0 St1 St1 St0 St1 St0 St0 St0 St1 St0 St1 St0 St1 St1 St0 St0 St1 St1 St1 St1 St0 St0 St0
[0] %p='hc %0p='hc %p='habbbbcccc %0p='habbbbcccc %p='habc1234567812345678 %0p='habc1234567812345678
[0] %P='hc %0P='hc %P='habbbbcccc %0P='habbbbcccc %P='habc1234567812345678 %0P='habc1234567812345678
[0] %P="sv-str"
[0] %u=dcba %0u=dcba
[0] %U=dcba %0U=dcba
[0] %D= 12 %d= 12 %01d=12 %06d=000012 %6d= 12
[0] %x=00abbbbcccc %0x=abbbbcccc %o=00527356746314 %b=00000101010111011101110111100110011001100
[0] %x=00abc1234567812345678 %0x=abc1234567812345678 %o=012570110642547402215053170 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000
[0] %t= 0 %03t= 0 %0t=0
[0] %s=! %s= what! %s= hmmm!1234
@@ -38,7 +53,7 @@ extra argument: 0000000000000000
[0] Embedded
multiline
*-* All Finished *-*
')),
}),
);
ok(1);
+43 -1
View File
@@ -3,6 +3,11 @@
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2009 by Wilson Snyder.
package testpackage;
localparam PARAM = 1024 >> 3;
endpackage
import testpackage::*;
module t;
localparam P4 = f_add(P3,1);
@@ -12,6 +17,20 @@ module t;
localparam P18 = f_case(P4);
localparam P6 = f_return(P4);
localparam P3 = 3;
localparam P128 = f_package();
typedef struct packed {
logic [7:0] data;
} type_t;
typedef type_t [1:0] flist;
localparam flist PLIST = {8'd4,8'd8};
localparam flist PARR = f_list_swap_2(PLIST);
typedef struct packed {
logic first;
logic second;
logic [31:0] data;
} bigstruct_t;
localparam bigstruct_t bigparam = f_return_struct(1'b1, 1'b0, 32'hfff12fff);
initial begin
`ifdef TEST_VERBOSE
@@ -24,10 +43,20 @@ module t;
if (P8 !== 8) $stop;
if (P16 !== 16) $stop;
if (P18 !== 18) $stop;
if (PARR[0] != PLIST[1]) $stop;
if (PARR[1] != PLIST[0]) $stop;
if (bigparam.first != 1'b1) $stop;
if (bigparam.second != 1'b0) $stop;
if (bigparam.data != 32'hfff12fff) $stop;
if (P128 != 128) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
function integer f_package();
return PARAM;
endfunction
function integer f_add(input [31:0] a, input [31:0] b);
f_add = a+b;
endfunction
@@ -36,7 +65,7 @@ module t;
function integer f_add2(input [31:0] a, input [31:0] b, input [31:0] c);
f_add2 = f_add(a,b)+c;
endfunction
// Speced ok: local variables
function integer f_for(input [31:0] a);
integer i;
@@ -84,4 +113,17 @@ module t;
end
f_return = 0;
endfunction
function flist f_list_swap_2(input flist in_list);
f_list_swap_2[0].data = in_list[1].data;
f_list_swap_2[1].data = in_list[0].data;
endfunction
function bigstruct_t f_return_struct(input first, input second, input [31:0] data);
bigstruct_t result;
result.data = data;
result.first = first;
result.second = second;
return result;
endfunction
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+31
View File
@@ -0,0 +1,31 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2015 by Johan Bjork.
parameter N = 5;
interface intf;
logic [N-1:0] data;
endinterface
module t (
input logic clk
);
intf localinterface [N-1:0]();
generate
genvar i,j;
for(i = 0; i < N; i++) begin
logic [N-1:0] dummy;
for(j = 0; j < N; j++) begin
assign dummy[j] = localinterface[j].data[i];
end
end
endgenerate
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+84
View File
@@ -0,0 +1,84 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2015 by Varun Koyyalagunta.
// bug1015
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 [1:0] i = crc[1:0];
logic [1:0] o [13:10] ;
Test test (/*AUTOINST*/
// Outputs
.o (o/*[1:0].[3:0]*/),
// Inputs
.i (i[1:0]));
// Aggregate outputs into a single result vector
wire [63:0] result = {32'h0, 6'h0,o[13], 6'h0,o[12], 6'h0,o[11], 6'h0,o[10]};
// Test loop
always @ (posedge clk) begin
`ifdef TEST_VERBOSE
$write("[%0t] cyc==%0d crc=%x result=%x sum=%x\n",$time, cyc, crc, result, sum);
`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 <= '0;
end
else if (cyc<10) begin
sum <= '0;
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'hb42b2f48a0a9375a
if (sum !== `EXPECTED_SUM) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module Test
(
output logic [1:0] o [3:0],
//but this works
//logic [N-1:0] o
input [1:0] i);
parameter N = 4;
logic [1:0] a [3:0]; initial a = '{2'h0,2'h1,2'h2,2'h3};
sub sub [N-1:0] (.o (o), // many-to-many
.a (a), // many-to-many
.i (i)); // many-to-one
endmodule
module sub
(
input logic [1:0] i,
input logic [1:0] a,
output logic [1:0] o
);
assign o = i + a;
endmodule
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 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_inst_slice.v");
compile (
v_flags2 => ["-Oi"],
);
execute (
check_finished=>1,
);
ok(1);
1;
-2
View File
@@ -12,8 +12,6 @@ compile (
expect=>
'%Error: t/t_interface_array_bad.v:\d+: Expecting expression to be constant, but variable isn\'t const: bar
%Error: t/t_interface_array_bad.v:\d+: Could not expand constant selection inside dotted reference: bar
%Error: t/t_interface_array_bad.v:\d+: Can\'t find definition of \'a\' in dotted signal: .a
%Error: Known scopes under \'a\':.*
%Error: Exiting due to.*',
);
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 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;
+33
View File
@@ -0,0 +1,33 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty.
// bug998
interface intf
#(parameter PARAM = 0)
();
logic val;
function integer func (); return 5; endfunction
endinterface
module t1(intf mod_intf);
initial begin
$display("%m %d", mod_intf.val);
end
endmodule
module t();
generate
begin : TestIf
intf #(.PARAM(1)) my_intf [0:0] ();
t1 t (.mod_intf(my_intf[0]));
end
endgenerate
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 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;
+39
View File
@@ -0,0 +1,39 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty.
// bug998
interface intf
#(parameter PARAM = 0)
();
logic val;
function integer func (); return 5; endfunction
endinterface
module t1(intf mod_intf);
initial begin
$display("%m %d", mod_intf.val);
end
endmodule
module t2(intf mod_intfs [1:0]);
generate
begin
t1 t(.mod_intf(mod_intfs[0]));
end
endgenerate
endmodule
module t();
intf #(.PARAM(1)) my_intf [1:0] ();
t2 t2 (.mod_intfs(my_intf));
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 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;
+29
View File
@@ -0,0 +1,29 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty.
// bug1005
module foo_module;
generate
for (genvar i = 0; i < 2; i = i + 1) begin : my_gen_block
logic baz;
end
endgenerate
endmodule
module bar_module;
foo_module foo();
endmodule
module t;
bar_module bar();
initial begin
bar.foo.my_gen_block[0].baz = 1;
if (bar.foo.my_gen_block[0].baz) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 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;
+60
View File
@@ -0,0 +1,60 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty.
// bug998
interface intf
#(parameter PARAM = 0)
();
logic val;
function integer func (); return 5; endfunction
endinterface
module t1(intf mod_intf);
initial begin
$display("%m %d", mod_intf.val);
end
endmodule
module t();
generate
begin : TestIf
intf #(.PARAM(1)) my_intf ();
assign my_intf.val = '0;
t1 t (.mod_intf(my_intf));
// initial $display("%0d", my_intf.func());
end
endgenerate
generate
begin
intf #(.PARAM(1)) my_intf ();
assign my_intf.val = '1;
t1 t (.mod_intf(my_intf));
// initial $display("%0d", my_intf.func());
end
endgenerate
localparam LP = 1;
logic val;
generate begin
if (LP) begin
intf #(.PARAM(2)) my_intf ();
assign my_intf.val = '1;
assign val = my_intf.val;
end else begin
intf #(.PARAM(3)) my_intf ();
assign my_intf.val = '1;
assign val = my_intf.val;
end
end endgenerate
initial begin
$display("%0d", val);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 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_interface_gen5.v");
compile (
v_flags2 => ["-Oi"],
);
execute (
check_finished=>1,
);
ok(1);
1;
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 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;
+56
View File
@@ -0,0 +1,56 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty.
// bug1001
interface intf
#(parameter PARAM = 0)
();
logic val;
endinterface
module t();
generate
if (1) begin
intf #(.PARAM(2)) my_intf ();
assign my_intf.val = '1;
end else begin
intf #(.PARAM(3)) my_intf ();
assign my_intf.val = '0;
end
endgenerate
generate
begin
if (1) begin
intf #(.PARAM(2)) my_intf ();
assign my_intf.val = '1;
end else begin
intf #(.PARAM(3)) my_intf ();
assign my_intf.val = '0;
end
end
endgenerate
generate
begin
begin
if (1) begin
intf #(.PARAM(2)) my_intf ();
assign my_intf.val = '1;
end else begin
intf #(.PARAM(3)) my_intf ();
assign my_intf.val = '0;
end
end
end
endgenerate
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 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;
+67
View File
@@ -0,0 +1,67 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty.
// bug998
interface intf
#(parameter PARAM = 0)
();
logic val;
function integer func (); return 5; endfunction
endinterface
module t1(intf mod_intf);
initial begin
$display("%m %d", mod_intf.val);
end
endmodule
module t();
intf #(.PARAM(1)) my_intf [1:0] ();
generate
genvar the_genvar;
begin
for (the_genvar = 0; the_genvar < 2; the_genvar++) begin : TestIf
begin
assign my_intf[the_genvar].val = '1;
t1 t (.mod_intf(my_intf[the_genvar]));
end
end
end
endgenerate
generate
genvar the_second_genvar;
begin
intf #(.PARAM(1)) my_intf [1:0] ();
for (the_second_genvar = 0; the_second_genvar < 2; the_second_genvar++) begin : TestIf
begin
assign my_intf[the_second_genvar].val = '1;
t1 t (.mod_intf(my_intf[the_second_genvar]));
end
end
end
endgenerate
generate
genvar the_third_genvar;
begin
for (the_third_genvar = 0; the_third_genvar < 2; the_third_genvar++) begin : TestIf
begin
intf #(.PARAM(1)) my_intf [1:0] ();
assign my_intf[the_third_genvar].val = '1;
t1 t (.mod_intf(my_intf[the_third_genvar]));
end
end
end
endgenerate
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 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;
+55
View File
@@ -0,0 +1,55 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty.
// bug998
interface intf
#(parameter PARAM = 0)
();
logic val;
function integer func (); return 5; endfunction
endinterface
module t1(intf mod_intf);
initial begin
$display("%m %d", mod_intf.val);
end
endmodule
module t();
//intf #(.PARAM(1)) my_intf [1:0] ();
intf #(.PARAM(1)) my_intf ();
generate
genvar the_genvar;
for (the_genvar = 0; the_genvar < 2; the_genvar++) begin : TestIf
//assign my_intf[the_genvar].val = '1;
//t1 t (.mod_intf(my_intf[the_genvar]));
t1 t (.mod_intf(my_intf));
end
endgenerate
// t1 t (.mod_intf(my_intf[1]));
// generate
// begin : TestIf
// assign my_intf[1].val = '1;
// t1 t (.mod_intf(my_intf[1]));
// end
// endgenerate
// generate
// begin
// assign my_intf[0].val = '1;
// t1 t (.mod_intf(my_intf[0]));
// end
// endgenerate
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 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;
+32
View File
@@ -0,0 +1,32 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty.
// bug998
module t1(input logic foo);
initial begin
$display("%m %d", foo);
end
endmodule
module t();
logic [1:0] my_foo;
generate
genvar the_genvar;
for (the_genvar = 0; the_genvar < 2; the_genvar++) begin : TestIf
//logic tmp_foo;
//assign tmp_foo = my_foo[the_genvar];
t1 t (.foo(my_foo[the_genvar]));
//t1 t (.foo(tmp_foo));
end
endgenerate
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+9 -3
View File
@@ -18,10 +18,16 @@ interface pads_if();
endinterface
module t();
pads_if padsif();
pads_if padsif[1:0]();
pads_if padsif_arr[1:0]();
initial begin
padsif.fOut(3);
if (padsif.fIn(3) != 33) $stop;
padsif[0].fOut(3);
if (padsif[0].fIn(3) != 33) $stop;
padsif_arr[0].fOut(3);
if (padsif_arr[0].fIn(3) != 33) $stop;
padsif_arr[1].fOut(3);
if (padsif_arr[1].fIn(3) != 33) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
+25 -25
View File
@@ -5,36 +5,36 @@
module t;
integer v = 19;
integer value = 19;
initial begin
if (v==1) begin end
else if (v==2) begin end
else if (v==3) begin end
else if (v==4) begin end
else if (v==5) begin end
else if (v==6) begin end
else if (v==7) begin end
else if (v==8) begin end
else if (v==9) begin end
else if (v==10) begin end
else if (v==11) begin end // Warn about this one
else if (v==12) begin end
if (value==1) begin end
else if (value==2) begin end
else if (value==3) begin end
else if (value==4) begin end
else if (value==5) begin end
else if (value==6) begin end
else if (value==7) begin end
else if (value==8) begin end
else if (value==9) begin end
else if (value==10) begin end
else if (value==11) begin end // Warn about this one
else if (value==12) begin end
end
initial begin
unique0 if (v==1) begin end
else if (v==2) begin end
else if (v==3) begin end
else if (v==4) begin end
else if (v==5) begin end
else if (v==6) begin end
else if (v==7) begin end
else if (v==8) begin end
else if (v==9) begin end
else if (v==10) begin end
else if (v==11) begin end // Warn about this one
else if (v==12) begin end
unique0 if (value==1) begin end
else if (value==2) begin end
else if (value==3) begin end
else if (value==4) begin end
else if (value==5) begin end
else if (value==6) begin end
else if (value==7) begin end
else if (value==8) begin end
else if (value==9) begin end
else if (value==10) begin end
else if (value==11) begin end // Warn about this one
else if (value==12) begin end
end
endmodule
+4 -1
View File
@@ -5,7 +5,7 @@
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
`define is_near_real(a,b) ($abs((a)-(b)) < (((a)/(b))*0.0001))
`define is_near_real(a,b) (( ((a)<(b)) ? (b)-(a) : (a)-(b)) < (((a)/(b))*0.0001))
module t (/*AUTOARG*/
// Inputs
@@ -78,6 +78,9 @@ module t (/*AUTOARG*/
i=0;
for (r=1.0; r<2.0; r=r+0.1) i++;
if (i!=10) $stop;
// bug
r = $bitstoreal($realtobits(1.414));
if (r != 1.414) $stop;
end
// Test loop
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+44
View File
@@ -0,0 +1,44 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2015 by Iztok Jeras.
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0)
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
reg alu_ltu, alu_lts;
logic [3:0] in_op1;
logic [3:0] in_op2;
reg aaa_ltu, aaa_lts;
always @(posedge clk) begin
in_op1 = 4'sb1110;
in_op2 = 4'b0010;
aaa_ltu = in_op1 < in_op2;
// bug999
aaa_lts = $signed(in_op1) < $signed(in_op2);
`checkh (aaa_ltu, 1'b0);
`checkh (aaa_lts, 1'b1);
end
generate if (1) begin
always @(posedge clk) begin
in_op1 = 4'sb1110;
in_op2 = 4'b0010;
alu_ltu = in_op1 < in_op2;
// bug999
alu_lts = $signed(in_op1) < $signed(in_op2);
`checkh (alu_ltu, 1'b0);
`checkh (alu_lts, 1'b1);
$write("*-* All Finished *-*\n");
$finish;
end
end
endgenerate
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+30
View File
@@ -0,0 +1,30 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2006 by Wilson Snyder.
module t (/*AUTOARG*/
// Outputs
b,
// Inputs
clk, en, a
);
// bug1017
input clk;
input en;
input a[1];
output logic b[1];
always_ff @ (posedge clk) begin
b <= en ? a : b;
end
always @ (posedge clk) begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+63
View File
@@ -0,0 +1,63 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2015 by Johan Bjork.
parameter N = 4;
interface a_if #(parameter PARAM = 0) ();
logic long_name;
modport source (output long_name);
modport sink (input long_name);
endinterface
module intf_source
(
input logic [N-1:0] intf_input,
a_if.source i_intf_source[N-1:0]
);
generate
for (genvar i=0; i < N;i++) begin
assign i_intf_source[i].long_name = intf_input[i];
end
endgenerate
endmodule
module intf_sink
(
output [N-1:0] a_out,
a_if.sink i_intf_sink[N-1:0]
);
generate
for (genvar i=0; i < N;i++) begin
assign a_out[i] = i_intf_sink[i].long_name;
end
endgenerate
endmodule
module t
(
clk
);
input clk;
logic [N-1:0] a_in;
logic [N-1:0] a_out;
logic [N-1:0] ack_out;
a_if #(.PARAM(1)) tl_intf [N-1:0] ();
intf_source source(a_in, tl_intf);
intf_sink sink(a_out, tl_intf);
initial a_in = '0;
always @(posedge clk) begin
a_in <= a_in + { {N-1 {1'b0}}, 1'b1 };
ack_out <= ack_out + { {N-1 {1'b0}}, 1'b1 };
if (ack_out != a_out) begin
$stop;
end
if (& a_in) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+65
View File
@@ -0,0 +1,65 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2015 by Johan Bjork.
parameter N = 4;
interface a_if #(parameter PARAM = 0) ();
logic long_name;
modport source (output long_name);
modport sink (input long_name);
endinterface
module intf_source
(
input logic [N-1:0] intf_input,
a_if.source i_intf_source[N-1:0]
);
generate
for (genvar i=0; i < N;i++) begin
assign i_intf_source[i].long_name = intf_input[i];
end
endgenerate
endmodule
module intf_sink
(
output [N-1:0] a_out,
a_if.sink i_intf_sink[N-1:0]
);
generate
for (genvar i=0; i < N;i++) begin
assign a_out[i] = i_intf_sink[i].long_name;
end
endgenerate
endmodule
module t
(
clk
);
input clk;
logic [N-1:0] a_in;
logic [N-1:0] a_out;
logic [N-1:0] ack_out;
// verilator lint_off LITENDIAN
a_if #(.PARAM(1)) tl_intf [N] ();
// verilator lint_on LITENDIAN
intf_source source(a_in, tl_intf);
intf_sink sink(a_out, tl_intf);
initial a_in = '0;
always @(posedge clk) begin
a_in <= a_in + { {N-1 {1'b0}}, 1'b1 };
ack_out <= ack_out + { {N-1 {1'b0}}, 1'b1 };
if (ack_out != a_out) begin
$stop;
end
if (& a_in) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+64
View File
@@ -0,0 +1,64 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2015 by Johan Bjork.
parameter N = 4;
// verilator lint_off LITENDIAN
interface a_if #(parameter PARAM = 0) ();
logic long_name;
modport source (output long_name);
modport sink (input long_name);
endinterface
module intf_source
(
input logic [0:N-1] intf_input,
a_if.source i_intf_source[0:N-1]
);
generate
for (genvar i=0; i < N;i++) begin
assign i_intf_source[i].long_name = intf_input[i];
end
endgenerate
endmodule
module intf_sink
(
output [0:N-1] a_out,
a_if.sink i_intf_sink[0:N-1]
);
generate
for (genvar i=0; i < N;i++) begin
assign a_out[i] = i_intf_sink[i].long_name;
end
endgenerate
endmodule
module t
(
clk
);
input clk;
logic [0:N-1] a_in;
logic [0:N-1] a_out;
logic [0:N-1] ack_out;
a_if #(.PARAM(1)) tl_intf [0:N-1] ();
intf_source source(a_in, tl_intf);
intf_sink sink(a_out, tl_intf);
initial a_in = '0;
always @(posedge clk) begin
a_in <= a_in + { {N-1 {1'b0}}, 1'b1 };
ack_out <= ack_out + { {N-1 {1'b0}}, 1'b1 };
if (ack_out != a_out) begin
$stop;
end
if (& a_in) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+26
View File
@@ -0,0 +1,26 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2015 by Johan Bjork
module mod #(
parameter real HZ = 0
);
//verilator no_inline_module
initial begin
if ((HZ-$floor(HZ)) - 0.45 > 0.01) $stop;
if ((HZ-$floor(HZ)) - 0.45 < -0.01) $stop;
end
endmodule
module t();
mod #(.HZ(123.45)) mod1();
mod #(.HZ(24.45)) mod2();
initial begin
if (mod1.HZ != 123.45) $stop;
if (mod2.HZ != 24.45) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+1 -1
View File
@@ -41,7 +41,7 @@ int main(int argc, char **argv, char **env) {
for (VerilatedScopeNameMap::const_iterator it = scopeMapp->begin(); it != scopeMapp->end(); it++) {
#ifdef TEST_VERBOSE
VL_PRINTF("---------------------------------------------\n");
VL_PRINTF("Scope = %s\n", it->first.c_str());
VL_PRINTF("Scope = %s\n", it->first);
it->second->scopeDump();
#endif
VerilatedVarNameMap * varNameMap = it->second->varsp();
+14 -3
View File
@@ -13,7 +13,7 @@ module t;
reg [63:0] q;
reg [16*8:1] wide;
reg [8:1] char;
reg [8:1] ochar;
reg [48*8:1] str;
reg [48*8:1] str2;
string str3;
@@ -55,8 +55,19 @@ module t;
if (str2 !== "mod=top.t") $stop;
`endif
$sformat(char,"%s","c");
if (char != "c") $stop;
$swrite(str2, "lib=%l");
`ifdef TEST_VERBOSE $display("chkl %0s",str2); `endif
if (str2 !== "lib=t") $stop;
str3 = $sformatf("u=%u", {"a","b","c","d"}); // Value selected so is printable
`ifdef TEST_VERBOSE $display("chku %0x %s",str3,str3); `endif
if (str3 !== "u=dcba") $stop;
str3 = $sformatf("v=%v", {"a","b","c","d"}); // Value selected so is printable
`ifdef TEST_VERBOSE $display("chkv %0x %s",str3,str3); `endif
$sformat(ochar,"%s","c");
if (ochar != "c") $stop;
$write("*-* All Finished *-*\n");
$finish;