mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 18:13:50 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa9dac29e8 | ||
|
|
afc432042f | ||
|
|
21cb29baf0 | ||
|
|
e8b5001cfe | ||
|
|
849c1e46a2 | ||
|
|
ebad6cde36 | ||
|
|
f920b3945e | ||
|
|
178028a70a | ||
|
|
5e54d3e41a | ||
|
|
f0af8726e3 | ||
|
|
57f2fe77ea | ||
|
|
d56ca25089 | ||
|
|
d39ce17dea | ||
|
|
373a68ec8b | ||
|
|
5613758ee3 | ||
|
|
2102f86909 | ||
|
|
d5ea785de7 | ||
|
|
9edd28d2ed | ||
|
|
7698af5178 | ||
|
|
52ae451f5c | ||
|
|
9254443cd4 | ||
|
|
4e4bc7b90f | ||
|
|
c7e0f2e196 | ||
|
|
acabaab6ac | ||
|
|
b0a249f338 | ||
|
|
0cb5d5cc5a | ||
|
|
9208c87f91 | ||
|
|
0081ce4a75 | ||
|
|
7850f49963 | ||
|
|
c72ee41142 | ||
|
|
bf5dee955d | ||
|
|
3df23a148a |
@@ -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]
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -46,6 +46,8 @@ obj_opt:
|
||||
obj_dbg:
|
||||
mkdir $@
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
.PHONY: ../verilator_bin ../verilator_bin_dbg ../verilator_coverage_bin_dbg
|
||||
|
||||
opt: ../verilator_bin
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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
@@ -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');
|
||||
|
||||
@@ -40,6 +40,8 @@ ifeq ($(CFG_WITH_LONGTESTS),yes)
|
||||
DRIVER_FLAGS += -j 0
|
||||
endif
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
######################################################################
|
||||
|
||||
.PHONY: test
|
||||
|
||||
@@ -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) $<
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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]));
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 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;
|
||||
@@ -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
|
||||
Executable
+20
@@ -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;
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,31 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 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
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,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
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-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;
|
||||
@@ -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.*',
|
||||
);
|
||||
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-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;
|
||||
@@ -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
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-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;
|
||||
@@ -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
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-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;
|
||||
@@ -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
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-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;
|
||||
@@ -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
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-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;
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-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;
|
||||
@@ -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
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-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;
|
||||
@@ -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
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-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;
|
||||
@@ -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
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-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;
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,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
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,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
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,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
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,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
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,64 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 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
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,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
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user