mirror of
https://github.com/verilator/verilator.git
synced 2026-10-03 00:23:35 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
314ffd9353 | ||
|
|
2c953dc37f | ||
|
|
9b9e4e5a3f | ||
|
|
50f835c701 | ||
|
|
cbb3351d97 | ||
|
|
fb81721e7e | ||
|
|
2cedef1333 | ||
|
|
4a1697a1b5 | ||
|
|
86f08a341c | ||
|
|
3d85cbe6b5 | ||
|
|
6d3dd98e77 | ||
|
|
9b2004d6b7 |
@@ -3,6 +3,20 @@ 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.703 2009/05/02
|
||||
|
||||
*** Fix $clog2 calculation error with powers-of-2, bug81. [Patricio Kaplan]
|
||||
|
||||
**** Fix error with tasks that have output first, bug78. [Andrea Foletto]
|
||||
|
||||
**** Fix "cloning" error with -y/--top-module, bug76. [Dimitris Nalbantis]
|
||||
|
||||
**** Fix segfault with error on bad --top-module, bug79. [Dimitris Nalbantis]
|
||||
|
||||
**** Fix "redefining I" error with complex includes. [Duraid Madina]
|
||||
|
||||
**** Fix GCC 4.3.2 compile warnings.
|
||||
|
||||
* Verilator 3.702 2009/03/28
|
||||
|
||||
*** Add --pins-bv option to use sc_bv for all ports. [Brian Small]
|
||||
|
||||
+5
-1
@@ -1171,10 +1171,14 @@ or `ifdef's may break other tools.
|
||||
=item `__FILE__
|
||||
|
||||
The __FILE__ define expands to the current filename, like C++'s __FILE__.
|
||||
This is in the draft SystemVerilog 2009 standard (but supported by
|
||||
Verilator since 2006!)
|
||||
|
||||
=item `__LINE__
|
||||
|
||||
The __LINE__ define expands to the current line number, like C++'s __LINE__.
|
||||
The __LINE__ define expands to the current line number, like C++'s
|
||||
__LINE__. This is in the draft SystemVerilog 2009 standard (but supported
|
||||
by Verilator since 2006!)
|
||||
|
||||
=item `error I<string>
|
||||
|
||||
|
||||
+1
-1
@@ -72,5 +72,5 @@ AC_SUBST(pkgdatadir)
|
||||
AC_OUTPUT(Makefile src/Makefile src/Makefile_obj include/verilated.mk)
|
||||
|
||||
AC_MSG_RESULT([])
|
||||
AC_MSG_RESULT([Now type 'make'])
|
||||
AC_MSG_RESULT([Now type 'gmake'])
|
||||
AC_MSG_RESULT([])
|
||||
|
||||
+50
-54
@@ -336,8 +336,8 @@ static inline void VL_ASSIGNBIT_QI(int, int bit, QData& lhsr, QData rhs) {
|
||||
}
|
||||
static inline void VL_ASSIGNBIT_WI(int, int bit, WDataOutP owp, IData rhs) {
|
||||
IData orig = owp[VL_BITWORD_I(bit)];
|
||||
owp[VL_BITWORD_I(bit)] = (orig & ~(VL_UL(1)<<VL_BITBIT_I(bit))
|
||||
| (rhs<<VL_BITBIT_I(bit)));
|
||||
owp[VL_BITWORD_I(bit)] = ((orig & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
|
||||
| (rhs<<VL_BITBIT_I(bit)));
|
||||
}
|
||||
// Alternative form that is an instruction faster when rhs is constant one.
|
||||
static inline void VL_ASSIGNBIT_IO(int, int bit, CData& lhsr, IData) {
|
||||
@@ -441,7 +441,7 @@ static inline QData VL_EXTENDS_QQ(int, int lbits, QData lhs) {
|
||||
|
||||
static inline WDataOutP VL_EXTENDS_WI(int obits, int lbits, WDataOutP owp, IData ld) {
|
||||
IData sign = VL_SIGNONES_I(lbits,ld);
|
||||
owp[0] = ld | sign & ~VL_MASK_I(lbits);
|
||||
owp[0] = ld | (sign & ~VL_MASK_I(lbits));
|
||||
for (int i=1; i < VL_WORDS_I(obits); i++) owp[i] = sign;
|
||||
return(owp);
|
||||
}
|
||||
@@ -456,7 +456,7 @@ static inline WDataOutP VL_EXTENDS_WW(int obits, int lbits, WDataOutP owp, WData
|
||||
for (int i=0; i < VL_WORDS_I(lbits)-1; i++) owp[i] = lwp[i];
|
||||
int lmsw=VL_WORDS_I(lbits)-1;
|
||||
IData sign = VL_SIGNONES_I(lbits,lwp[lmsw]);
|
||||
owp[lmsw] = lwp[lmsw] | sign & ~VL_MASK_I(lbits);
|
||||
owp[lmsw] = lwp[lmsw] | (sign & ~VL_MASK_I(lbits));
|
||||
for (int i=VL_WORDS_I(lbits); i < VL_WORDS_I(obits); i++) owp[i] = sign;
|
||||
return(owp);
|
||||
}
|
||||
@@ -536,38 +536,6 @@ static inline IData VL_REDXOR_W(int words, WDataInP lwp) {
|
||||
return VL_REDXOR_32(r);
|
||||
}
|
||||
|
||||
static inline IData VL_CLOG2_I(IData lhs) {
|
||||
// Perhaps can do better using fls GCC4 builtins
|
||||
int n=1;
|
||||
IData chk;
|
||||
if (!lhs) return 0;
|
||||
chk = lhs >> VL_UL(16); if (chk) { n += 16; lhs = chk; }
|
||||
chk = lhs >> VL_UL(8); if (chk) { n += 8; lhs = chk; }
|
||||
chk = lhs >> VL_UL(4); if (chk) { n += 4; lhs = chk; }
|
||||
chk = lhs >> VL_UL(2); if (chk) { n += 2; lhs = chk; }
|
||||
chk = lhs >> VL_UL(1); if (chk) { n += 1; lhs = chk; }
|
||||
return n;
|
||||
}
|
||||
static inline IData VL_CLOG2_Q(QData lhs) {
|
||||
// Perhaps can do better using fls GCC4 builtins
|
||||
int n=1;
|
||||
QData chk;
|
||||
if (!lhs) return 0;
|
||||
chk = lhs >> VL_ULL(32); if (chk) { n += 32; lhs = chk; }
|
||||
chk = lhs >> VL_ULL(16); if (chk) { n += 16; lhs = chk; }
|
||||
chk = lhs >> VL_ULL(8); if (chk) { n += 8; lhs = chk; }
|
||||
chk = lhs >> VL_ULL(4); if (chk) { n += 4; lhs = chk; }
|
||||
chk = lhs >> VL_ULL(2); if (chk) { n += 2; lhs = chk; }
|
||||
chk = lhs >> VL_ULL(1); if (chk) { n += 1; lhs = chk; }
|
||||
return n;
|
||||
}
|
||||
static inline IData VL_CLOG2_W(int words, WDataInP lwp) {
|
||||
for (int i=words-1; i>=0; i--) {
|
||||
if (lwp[i]) return VL_CLOG2_I(lwp[i])+i*VL_WORDSIZE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EMIT_RULE: VL_COUNTONES_II: oclean = false; lhs clean
|
||||
static inline IData VL_COUNTONES_I(IData lhs) {
|
||||
// This is faster than __builtin_popcountl
|
||||
@@ -622,6 +590,36 @@ static inline IData VL_ONEHOT0_W(int words, WDataInP lwp) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline IData VL_CLOG2_I(IData lhs) {
|
||||
// There are faster algorithms, or fls GCC4 builtins, but rarely used
|
||||
if (!lhs) return 0;
|
||||
lhs--;
|
||||
int shifts=0;
|
||||
for (; lhs!=0; shifts++) lhs = lhs >> 1;
|
||||
return shifts;
|
||||
}
|
||||
static inline IData VL_CLOG2_Q(QData lhs) {
|
||||
if (!lhs) return 0;
|
||||
lhs--;
|
||||
int shifts=0;
|
||||
for (; lhs!=0; shifts++) lhs = lhs >> VL_ULL(1);
|
||||
return shifts;
|
||||
}
|
||||
static inline IData VL_CLOG2_W(int words, WDataInP lwp) {
|
||||
IData adjust = (VL_COUNTONES_W(words,lwp)==1) ? 0 : 1;
|
||||
for (int i=words-1; i>=0; i--) {
|
||||
if (lwp[i]) {
|
||||
for (int bit=31; bit>=0; bit--) {
|
||||
if (VL_UNLIKELY(VL_BITISSET_I(lwp[i],bit))) {
|
||||
return i*VL_WORDSIZE + bit + adjust;
|
||||
}
|
||||
}
|
||||
// Can't get here - one bit must be set
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
// SIMPLE LOGICAL OPERATORS
|
||||
|
||||
@@ -991,16 +989,16 @@ static inline void _VL_INSERT_WW(int, WDataOutP owp, WDataInP lwp, int hbit, int
|
||||
{ // Lower word
|
||||
int oword = lword+i;
|
||||
IData d = lwp[i]<<loffset;
|
||||
IData od = owp[oword] & ~linsmask | d & linsmask;
|
||||
if (oword==hword) owp[oword] = owp[oword] & ~hinsmask | od & hinsmask;
|
||||
IData od = (owp[oword] & ~linsmask) | (d & linsmask);
|
||||
if (oword==hword) owp[oword] = (owp[oword] & ~hinsmask) | (od & hinsmask);
|
||||
else owp[oword] = od;
|
||||
}
|
||||
{ // Upper word
|
||||
int oword = lword+i+1;
|
||||
if (oword <= hword) {
|
||||
IData d = lwp[i]>>nbitsonright;
|
||||
IData od = d & ~linsmask | owp[oword] & linsmask;
|
||||
if (oword==hword) owp[oword] = owp[oword] & ~hinsmask | od & hinsmask;
|
||||
IData od = (d & ~linsmask) | (owp[oword] & linsmask);
|
||||
if (oword==hword) owp[oword] = (owp[oword] & ~hinsmask) | (od & hinsmask);
|
||||
else owp[oword] = od;
|
||||
}
|
||||
}
|
||||
@@ -1188,12 +1186,12 @@ static inline IData VL_SHIFTRS_III(int obits, int, int, IData lhs, IData rhs) {
|
||||
// Note the C standard does not specify the >> operator as a arithmetic shift!
|
||||
IData sign = -(lhs >> (obits-1)); // ffff_ffff if negative
|
||||
IData signext = ~(VL_MASK_I(obits) >> rhs); // One with bits where we've shifted "past"
|
||||
return (lhs >> rhs) | sign & VL_CLEAN_II(obits,obits,signext);
|
||||
return (lhs >> rhs) | (sign & VL_CLEAN_II(obits,obits,signext));
|
||||
}
|
||||
static inline QData VL_SHIFTRS_QQI(int obits, int, int, QData lhs, IData rhs) {
|
||||
QData sign = -(lhs >> (obits-1));
|
||||
QData signext = ~(VL_MASK_Q(obits) >> rhs);
|
||||
return (lhs >> rhs) | sign & VL_CLEAN_QQ(obits,obits,signext);
|
||||
return (lhs >> rhs) | (sign & VL_CLEAN_QQ(obits,obits,signext));
|
||||
}
|
||||
static inline WDataOutP VL_SHIFTRS_WWI(int obits,int,int,WDataOutP owp,WDataInP lwp, IData rd) {
|
||||
int word_shift = VL_BITWORD_I(rd);
|
||||
@@ -1364,61 +1362,59 @@ static inline WDataOutP VL_COND_WIWW(int obits, int, int, int,
|
||||
|
||||
// If changing the number of functions here, also change EMITCINLINES_NUM_CONSTW
|
||||
|
||||
#define I IData
|
||||
#define _END(obits,wordsSet) \
|
||||
for(int i=(wordsSet);i<VL_WORDS_I(obits);i++) o[i] = (IData)0x0; \
|
||||
return o
|
||||
|
||||
#define VL_HAVE_CONST_W_1X
|
||||
static inline WDataOutP VL_CONST_W_1X(int obits, WDataOutP o,
|
||||
I d0) {
|
||||
IData d0) {
|
||||
o[0]=d0;
|
||||
_END(obits,1); }
|
||||
#define VL_HAVE_CONST_W_2X
|
||||
static inline WDataOutP VL_CONST_W_2X(int obits, WDataOutP o,
|
||||
I d1,I d0) {
|
||||
IData d1,IData d0) {
|
||||
o[0]=d0; o[1]=d1;
|
||||
_END(obits,2); }
|
||||
#define VL_HAVE_CONST_W_3X
|
||||
static inline WDataOutP VL_CONST_W_3X(int obits, WDataOutP o,
|
||||
I d2,I d1,I d0) {
|
||||
IData d2,IData d1,IData d0) {
|
||||
o[0]=d0; o[1]=d1; o[2]=d2;
|
||||
_END(obits,3); }
|
||||
#define VL_HAVE_CONST_W_4X
|
||||
static inline WDataOutP VL_CONST_W_4X(int obits, WDataOutP o,
|
||||
I d3,I d2,I d1,I d0) {
|
||||
IData d3,IData d2,IData d1,IData d0) {
|
||||
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3;
|
||||
_END(obits,4); }
|
||||
#define VL_HAVE_CONST_W_5X
|
||||
static inline WDataOutP VL_CONST_W_5X(int obits, WDataOutP o,
|
||||
I d4,I d3,I d2,I d1,I d0) {
|
||||
IData d4,IData d3,IData d2,IData d1,IData d0) {
|
||||
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4;
|
||||
_END(obits,5); }
|
||||
#define VL_HAVE_CONST_W_6X
|
||||
static inline WDataOutP VL_CONST_W_6X(int obits, WDataOutP o,
|
||||
I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||
IData d5,IData d4,IData d3,IData d2,IData d1,IData d0) {
|
||||
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5;
|
||||
_END(obits,6); }
|
||||
#define VL_HAVE_CONST_W_7X
|
||||
static inline WDataOutP VL_CONST_W_7X(int obits, WDataOutP o,
|
||||
I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||
IData d6,IData d5,IData d4,IData d3,IData d2,IData d1,IData d0) {
|
||||
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6;
|
||||
_END(obits,7); }
|
||||
#define VL_HAVE_CONST_W_8X
|
||||
static inline WDataOutP VL_CONST_W_8X(int obits, WDataOutP o,
|
||||
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||
IData d7,IData d6,IData d5,IData d4,IData d3,IData d2,IData d1,IData d0) {
|
||||
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
||||
_END(obits,8); }
|
||||
#define VL_HAVE_CONST_W_9X
|
||||
static inline WDataOutP VL_CONST_W_9X(int obits, WDataOutP o,
|
||||
I d8,
|
||||
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||
IData d8,
|
||||
IData d7,IData d6,IData d5,IData d4,IData d3,IData d2,IData d1,IData d0) {
|
||||
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
||||
o[8]=d8;
|
||||
_END(obits,9); }
|
||||
|
||||
#undef _END
|
||||
#undef I
|
||||
|
||||
// Debugging
|
||||
|
||||
|
||||
@@ -269,12 +269,14 @@ y.tab.c: verilog.y $(HEADERS) bisonpre
|
||||
$(PERL) $(BISONPRE) --yacc ${YACC} -d -v -o y.tab.c $<
|
||||
|
||||
V3Lexer_pregen.yy.cpp: verilog.l y.tab.h $(HEADERS)
|
||||
${LEX} --version
|
||||
${LEX} ${LFLAGS} -o$@ $<
|
||||
|
||||
V3Lexer.yy.cpp: V3Lexer_pregen.yy.cpp
|
||||
$(PERL) $(srcdir)/flexfix <$< >$@
|
||||
|
||||
V3PreLex_pregen.yy.cpp: V3PreLex.l $(HEADERS)
|
||||
${LEX} --version
|
||||
${LEX} ${LFLAGS} -o$@ $<
|
||||
|
||||
V3PreLex.yy.cpp: V3PreLex_pregen.yy.cpp
|
||||
|
||||
+1
-1
@@ -1225,7 +1225,7 @@ private:
|
||||
AstSenItem* litemp = senp->castSenItem();
|
||||
AstSenItem* ritemp = cmpp->castSenItem();
|
||||
if (litemp && ritemp) {
|
||||
if (litemp->varrefp() && ritemp->varrefp() && litemp->varrefp()->sameTree(ritemp->varrefp())
|
||||
if ((litemp->varrefp() && ritemp->varrefp() && litemp->varrefp()->sameTree(ritemp->varrefp()))
|
||||
|| (!litemp->varrefp() && !ritemp->varrefp())) {
|
||||
// We've sorted in the order ANY, BOTH, POS, NEG, so we don't need to try opposite orders
|
||||
if (( litemp->edgeType()==AstEdgeType::ANYEDGE) // ANY or {BOTH|POS|NEG} -> ANY
|
||||
|
||||
+1
-1
@@ -280,7 +280,7 @@ private:
|
||||
}
|
||||
}
|
||||
virtual void visit(AstBegin* nodep, AstNUser*) {
|
||||
// Record the hiearchy of any named begins, so we can apply to user
|
||||
// Record the hierarchy of any named begins, so we can apply to user
|
||||
// coverage points. This is because there may be cov points inside
|
||||
// generate blocks; each point should get separate consideration.
|
||||
// (Currently ignored for line coverage, since any generate iteration
|
||||
|
||||
@@ -415,6 +415,7 @@ private:
|
||||
else if (!m_inDly && nodep->lvalue()) {
|
||||
//UINFO(9,"NBA "<<nodep<<endl);
|
||||
if (!m_inInitial) {
|
||||
UINFO(4,"AssignNDlyVar: "<<nodep<<endl);
|
||||
markVarUsage(nodep->varp(), VU_NONDLY);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -477,9 +477,10 @@ public:
|
||||
assigntop->iterateAndNext(*this);
|
||||
}
|
||||
for (int word=VL_WORDS_I(nodep->num().minWidth())-1; word>0; word--) {
|
||||
ofp()->printf(",0x%08x", nodep->num().dataWord(word));
|
||||
// Only 32 bits - llx + long long here just to appease CPP format warning
|
||||
ofp()->printf(",0x%08llx", (long long)(nodep->num().dataWord(word)));
|
||||
}
|
||||
ofp()->printf(",0x%08x)", nodep->num().dataWord(0));
|
||||
ofp()->printf(",0x%08llx)", (long long)(nodep->num().dataWord(0)));
|
||||
} else if (nodep->isQuad()) {
|
||||
vluint64_t num = nodep->toUQuad();
|
||||
if (num<10) ofp()->printf("VL_ULL(%lld)", (long long)num);
|
||||
@@ -487,7 +488,7 @@ public:
|
||||
} else {
|
||||
uint32_t num = nodep->toUInt();
|
||||
if (num<10) puts(cvtToStr(num));
|
||||
else ofp()->printf("0x%x", num);
|
||||
else ofp()->printf("0x%llx", (long long)num);
|
||||
//Unneeded-Causes %lx format warnings:
|
||||
// if (!nodep->num().isSigned() && (num & (1UL<<31))) puts("U");
|
||||
}
|
||||
|
||||
+4
-4
@@ -319,10 +319,10 @@ private:
|
||||
int refs = nodep->user3();
|
||||
// Should we automatically inline this module?
|
||||
// inlineMult = 2000 by default. If a mod*#instances is < this # nodes, can inline it
|
||||
bool doit = (userinline || allowed && (refs==1
|
||||
|| m_stmtCnt < INLINE_MODS_SMALLER
|
||||
|| v3Global.opt.inlineMult() < 1
|
||||
|| refs*m_stmtCnt < v3Global.opt.inlineMult()));
|
||||
bool doit = (userinline || (allowed && (refs==1
|
||||
|| m_stmtCnt < INLINE_MODS_SMALLER
|
||||
|| v3Global.opt.inlineMult() < 1
|
||||
|| refs*m_stmtCnt < v3Global.opt.inlineMult())));
|
||||
UINFO(4, " Inline="<<doit<<" Possible="<<allowed<<" Usr="<<userinline<<" Refs="<<refs<<" Stmts="<<m_stmtCnt
|
||||
<<" "<<nodep<<endl);
|
||||
if (doit) {
|
||||
|
||||
+23
-4
@@ -95,6 +95,7 @@ private:
|
||||
V3SymTable m_mods; // Symbol table of all module names
|
||||
LinkCellsGraph m_graph; // Linked graph of all cell interconnects
|
||||
LibraryVertex* m_libVertexp; // Vertex at root of all libraries
|
||||
V3GraphVertex* m_topVertexp; // Vertex of top module
|
||||
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
@@ -123,15 +124,33 @@ private:
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) {
|
||||
if (LinkCellsVertex* vvertexp = dynamic_cast<LinkCellsVertex*>(itp)) {
|
||||
// +1 so we leave level 1 for the new wrapper we'll make in a moment
|
||||
vvertexp->modp()->level(vvertexp->rank()+1);
|
||||
AstModule* modp = vvertexp->modp();
|
||||
modp->level(vvertexp->rank()+1);
|
||||
if (vvertexp == m_topVertexp && modp->level() != 2) {
|
||||
v3error("Specified --top-module '"<<v3Global.opt.topModule()<<"' isn't at the top level, it's under another cell.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (v3Global.opt.topModule()!=""
|
||||
&& !m_topVertexp) {
|
||||
v3error("Specified --top-module '"<<v3Global.opt.topModule()<<"' was not found in design.");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstModule* nodep, AstNUser*) {
|
||||
// Module: Pick up modnames, so we can resolve cells later
|
||||
m_modp = nodep;
|
||||
UINFO(2,"Link Module: "<<nodep<<endl);
|
||||
if (nodep->inLibrary()) {
|
||||
bool topMatch = (v3Global.opt.topModule()==nodep->name());
|
||||
if (topMatch) {
|
||||
m_topVertexp = vertex(nodep);
|
||||
UINFO(2,"Link --top-module: "<<nodep<<endl);
|
||||
nodep->inLibrary(false); // Safer to make sure it doesn't disappear
|
||||
}
|
||||
if (v3Global.opt.topModule()==""
|
||||
? nodep->inLibrary() // Library cells are lower
|
||||
: !topMatch) { // Any non-specified module is lower
|
||||
// Put under a fake vertex so that the graph ranking won't indicate
|
||||
// this is a top level module
|
||||
if (!m_libVertexp) m_libVertexp = new LibraryVertex(&m_graph);
|
||||
new V3GraphEdge(&m_graph, m_libVertexp, vertex(nodep), 1, false);
|
||||
}
|
||||
@@ -231,9 +250,9 @@ public:
|
||||
LinkCellsVisitor() {
|
||||
m_modp = NULL;
|
||||
m_libVertexp = NULL;
|
||||
m_topVertexp = NULL;
|
||||
}
|
||||
virtual ~LinkCellsVisitor() {
|
||||
}
|
||||
virtual ~LinkCellsVisitor() {}
|
||||
void main(AstNetlist* rootp) {
|
||||
rootp->accept(*this);
|
||||
}
|
||||
|
||||
@@ -211,10 +211,10 @@ private:
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (portp->isIO()) {
|
||||
if (portp->isInput()) {
|
||||
pinp->iterateAndNext(*this);
|
||||
pinp->iterate(*this);
|
||||
} else { // Output or Inout
|
||||
m_setRefLvalue = true;
|
||||
pinp->iterateAndNext(*this);
|
||||
pinp->iterate(*this);
|
||||
m_setRefLvalue = false;
|
||||
}
|
||||
// Advance pin
|
||||
|
||||
+1
-14
@@ -50,20 +50,6 @@ void V3LinkLevel::modSortByLevel() {
|
||||
// Calculate levels again in case we added modules
|
||||
UINFO(2,"modSortByLevel()\n");
|
||||
|
||||
if (v3Global.opt.topModule()!="") {
|
||||
bool hit = false;
|
||||
for (AstModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castModule()) {
|
||||
if (nodep->name() == v3Global.opt.topModule()) {
|
||||
hit = true;
|
||||
} else {
|
||||
nodep->level(3);
|
||||
}
|
||||
}
|
||||
if (!hit) {
|
||||
v3error("Specified --top-module '"<<v3Global.opt.topModule()<<"' was not found in design.");
|
||||
}
|
||||
}
|
||||
|
||||
// level() was computed for us in V3LinkCells
|
||||
|
||||
vector<AstModule*> vec;
|
||||
@@ -98,6 +84,7 @@ void V3LinkLevel::wrapTop(AstNetlist* netlistp) {
|
||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||
// We do ONLY the top module
|
||||
AstModule* oldmodp = netlistp->modulesp();
|
||||
if (!oldmodp) netlistp->v3fatalSrc("No module found to process");
|
||||
AstModule* newmodp = new AstModule(oldmodp->fileline(), (string)"TOP_"+oldmodp->name());
|
||||
// Make the new module first in the list
|
||||
oldmodp->unlinkFrBackWithNext();
|
||||
|
||||
+8
-7
@@ -675,10 +675,11 @@ V3Number& V3Number::opOneHot0 (const V3Number& lhs) {
|
||||
}
|
||||
V3Number& V3Number::opCLog2 (const V3Number& lhs) {
|
||||
if (lhs.isFourState()) return setAllBitsX();
|
||||
int bit;
|
||||
for (bit=lhs.width()-1; bit>=0; bit--) {
|
||||
// IE if 4, this algorithm didn't pre-subtract 1, so we need to post-correct now
|
||||
int adjust = (lhs.countOnes()==1) ? 0 : 1;
|
||||
for (int bit=lhs.width()-1; bit>=0; bit--) {
|
||||
if (lhs.bitIs1(bit)) {
|
||||
setLong(bit+1);
|
||||
setLong(bit+adjust);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
@@ -1063,8 +1064,8 @@ V3Number& V3Number::opMulS (const V3Number& lhs, const V3Number& rhs) {
|
||||
V3Number lhsNoSign = lhs; if (lhs.isNegative()) lhsNoSign.opUnaryMin(lhs);
|
||||
V3Number rhsNoSign = rhs; if (rhs.isNegative()) rhsNoSign.opUnaryMin(rhs);
|
||||
V3Number qNoSign = opMul(lhsNoSign,rhsNoSign);
|
||||
if (lhs.isNegative() && !rhs.isNegative()
|
||||
|| !lhs.isNegative() && rhs.isNegative()) {
|
||||
if ((lhs.isNegative() && !rhs.isNegative())
|
||||
|| (!lhs.isNegative() && rhs.isNegative())) {
|
||||
opUnaryMin(qNoSign);
|
||||
} else {
|
||||
opAssign(qNoSign);
|
||||
@@ -1087,8 +1088,8 @@ V3Number& V3Number::opDivS (const V3Number& lhs, const V3Number& rhs) {
|
||||
V3Number lhsNoSign = lhs; if (lhs.isNegative()) lhsNoSign.opUnaryMin(lhs);
|
||||
V3Number rhsNoSign = rhs; if (rhs.isNegative()) rhsNoSign.opUnaryMin(rhs);
|
||||
V3Number qNoSign = opDiv(lhsNoSign,rhsNoSign);
|
||||
if (lhs.isNegative() && !rhs.isNegative()
|
||||
|| !lhs.isNegative() && rhs.isNegative()) {
|
||||
if ((lhs.isNegative() && !rhs.isNegative())
|
||||
|| (!lhs.isNegative() && rhs.isNegative())) {
|
||||
opUnaryMin(qNoSign);
|
||||
} else {
|
||||
opAssign(qNoSign);
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ public:
|
||||
|
||||
// Implicit conversion operators:
|
||||
inline V3Double0 (const vluint64_t v) : m_d(v) { };
|
||||
inline operator const double () const { return m_d; };
|
||||
inline operator double () const { return m_d; };
|
||||
|
||||
// Explicit operators:
|
||||
inline V3Double0& operator++() { ++m_d; return *this; }; // prefix
|
||||
|
||||
+1
-1
@@ -156,7 +156,7 @@ private:
|
||||
// assign x = (OE) ? y : 'hZ;
|
||||
// assign x = (OE) ? 'hz : y;
|
||||
|
||||
// see if this a COND and seperate out the __en logic from the output logic if it is
|
||||
// see if this a COND and separate out the __en logic from the output logic if it is
|
||||
if (nodep->rhsp()->castCond()) {
|
||||
AstCond* condp = nodep->rhsp()->castCond();
|
||||
AstNode* oep = condp->condp();
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
//**********************************************************************
|
||||
//**** Version and host name
|
||||
|
||||
#define DTVERSION "Verilator 3.702 2009/03/28"
|
||||
#define DTVERSION "Verilator 3.703 2009/05/02"
|
||||
|
||||
//**********************************************************************
|
||||
//**** Functions
|
||||
|
||||
+6
-3
@@ -23,11 +23,11 @@
|
||||
my $dir = $ARGV[0]; defined $dir or die "%Error: No directory argument,";
|
||||
chdir $dir;
|
||||
|
||||
my $rev = 'UNKNOWN_REV';
|
||||
my $data = `git log | head -1`;
|
||||
if ($data !~ /commit\s*([a-z0-9]+)/i) {
|
||||
die "%Error: No git revision found,";
|
||||
if ($data =~ /commit\s*([a-z0-9]+)/i) {
|
||||
$rev = $1;
|
||||
}
|
||||
my $rev = $1;
|
||||
|
||||
$data = `git status`;
|
||||
if ($data !~ /nothing to commit/i) {
|
||||
@@ -35,3 +35,6 @@ if ($data !~ /nothing to commit/i) {
|
||||
}
|
||||
|
||||
print "static const char* DTVERSION_rev = \"$rev\";\n";
|
||||
|
||||
# Die after the print, so at least the header has good contents
|
||||
$rev =~ /UNKNOWN/ and die "%Error: No git revision found,";
|
||||
|
||||
@@ -167,7 +167,7 @@ sub parameter {
|
||||
$_Parameter_Next_Level = $param;
|
||||
}
|
||||
else {
|
||||
warn "%Error: Unknown parameter: $param\n";
|
||||
die "%Error: Unknown parameter: $param\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2008 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
v_flags2 => ["--top-module a "],
|
||||
fails=>$Self->{v3},
|
||||
nc=>0, # Need to get it not to give the prompt
|
||||
expect=>
|
||||
'%Error: Specified --top-module \'a\' isn.t at the top level, it.s under another cell.
|
||||
%Error: Exiting due to.*',
|
||||
) if $Self->{v3};
|
||||
|
||||
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, 2008 by Wilson Snyder.
|
||||
|
||||
module a_top;
|
||||
a a ();
|
||||
initial begin
|
||||
$write("Bad top modules\n");
|
||||
$stop;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module a;
|
||||
b b ();
|
||||
c c ();
|
||||
d d ();
|
||||
endmodule
|
||||
|
||||
module b;
|
||||
endmodule
|
||||
|
||||
module c;
|
||||
endmodule
|
||||
|
||||
module d;
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -7,7 +7,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
v_flags2 => ["--top-module b"],
|
||||
v_flags2 => ["--top-module b "],
|
||||
) if $Self->{v3};
|
||||
|
||||
execute (
|
||||
|
||||
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 2008 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
v_flags2 => ["--top-module b"],
|
||||
) if $Self->{v3};
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
) if $Self->{v3};
|
||||
|
||||
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, 2008 by Wilson Snyder.
|
||||
|
||||
module a;
|
||||
a2 a2 (.tmp(1'b0));
|
||||
initial begin
|
||||
$write("Bad top modules\n");
|
||||
$stop;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module a2 (input tmp);
|
||||
l3 l3 (.tmp(tmp));
|
||||
endmodule
|
||||
|
||||
module b;
|
||||
l3 l3 (.tmp(1'b1));
|
||||
endmodule
|
||||
|
||||
module l3 (input tmp);
|
||||
initial begin
|
||||
if (tmp) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/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
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,113 @@
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2009 by Wilson Snyder.
|
||||
|
||||
`define DDIFF_BITS 9
|
||||
`define AOA_BITS 8
|
||||
`define HALF_DDIFF `DDIFF_BITS'd256
|
||||
`define MAX_AOA `AOA_BITS'd255
|
||||
`define BURP_DIVIDER 9'd16
|
||||
|
||||
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 [`DDIFF_BITS-1:0] DDIFF_B = crc[`DDIFF_BITS-1:0];
|
||||
wire reset = (cyc<7);
|
||||
|
||||
/*AUTOWIRE*/
|
||||
// Beginning of automatic wires (for undeclared instantiated-module outputs)
|
||||
wire [`AOA_BITS-1:0] AOA_B; // From test of Test.v
|
||||
// End of automatics
|
||||
|
||||
Test test (/*AUTOINST*/
|
||||
// Outputs
|
||||
.AOA_B (AOA_B[`AOA_BITS-1:0]),
|
||||
// Inputs
|
||||
.DDIFF_B (DDIFF_B[`DDIFF_BITS-1:0]),
|
||||
.reset (reset),
|
||||
.clk (clk));
|
||||
|
||||
// Aggregate outputs into a single result vector
|
||||
wire [63:0] result = {56'h0, AOA_B};
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result);
|
||||
`endif
|
||||
cyc <= cyc + 1;
|
||||
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
|
||||
sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]};
|
||||
if (cyc==0) begin
|
||||
// Setup
|
||||
crc <= 64'h5aef0c8d_d70a4497;
|
||||
sum <= 64'h0;
|
||||
end
|
||||
else if (cyc<10) begin
|
||||
sum <= 64'h0;
|
||||
end
|
||||
else if (cyc<90) begin
|
||||
end
|
||||
else if (cyc==99) begin
|
||||
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
|
||||
if (crc !== 64'hc77bb9b3784ea091) $stop;
|
||||
// What checksum will we end up with (above print should match)
|
||||
`define EXPECTED_SUM 64'h3a74e9d34771ad93
|
||||
if (sum !== `EXPECTED_SUM) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module Test (/*AUTOARG*/
|
||||
// Outputs
|
||||
AOA_B,
|
||||
// Inputs
|
||||
DDIFF_B, reset, clk
|
||||
);
|
||||
|
||||
input [`DDIFF_BITS-1:0] DDIFF_B;
|
||||
input reset;
|
||||
input clk;
|
||||
output reg [`AOA_BITS-1:0] AOA_B;
|
||||
|
||||
reg [`AOA_BITS-1:0] AOA_NEXT_B;
|
||||
reg [`AOA_BITS-1:0] tmp;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
AOA_B <= 8'h80;
|
||||
end
|
||||
else begin
|
||||
AOA_B <= AOA_NEXT_B;
|
||||
end
|
||||
end
|
||||
|
||||
always @* begin
|
||||
// verilator lint_off WIDTH
|
||||
tmp = ((`HALF_DDIFF-DDIFF_B)/`BURP_DIVIDER);
|
||||
t_aoa_update(AOA_NEXT_B, AOA_B, ((`HALF_DDIFF-DDIFF_B)/`BURP_DIVIDER));
|
||||
// verilator lint_on WIDTH
|
||||
end
|
||||
|
||||
task t_aoa_update;
|
||||
output [`AOA_BITS-1:0] aoa_reg_next;
|
||||
input [`AOA_BITS-1:0] aoa_reg;
|
||||
input [`AOA_BITS-1:0] aoa_delta_update;
|
||||
begin
|
||||
if ((`MAX_AOA-aoa_reg)<aoa_delta_update) //Overflow protection
|
||||
aoa_reg_next=`MAX_AOA;
|
||||
else
|
||||
aoa_reg_next=aoa_reg+aoa_delta_update;
|
||||
end
|
||||
endtask
|
||||
endmodule
|
||||
@@ -70,7 +70,7 @@ module Test
|
||||
#(parameter SAMPLE_WIDTH = 5 )
|
||||
(
|
||||
`ifdef verilator // UNSUPPORTED
|
||||
output reg [$clog2(SAMPLE_WIDTH-1)-1:0] pos,
|
||||
output reg [$clog2(SAMPLE_WIDTH)-1:0] pos,
|
||||
`else
|
||||
output reg [log2(SAMPLE_WIDTH-1)-1:0] pos,
|
||||
`endif
|
||||
|
||||
@@ -19,13 +19,19 @@ module t (/*AUTOARG*/
|
||||
reg [63:0] crc;
|
||||
reg [63:0] sum;
|
||||
|
||||
wire [31:0] out = `CLOG2(crc[31:0]);
|
||||
// Need temp wires as function has different width rules than $clog2
|
||||
wire [127:0] pows = 128'h1<<crc[7:0];
|
||||
wire [127:0] npows = ~pows;
|
||||
|
||||
wire [31:0] out = `CLOG2(crc[7:0]);
|
||||
wire [31:0] out2 = `CLOG2(crc);
|
||||
wire [31:0] out3 = `CLOG2(pows);
|
||||
wire [31:0] out4 = `CLOG2(npows);
|
||||
|
||||
// Aggregate outputs into a single result vector
|
||||
wire [63:0] result = {out2, out};
|
||||
wire [63:0] result = {out4[15:0], out3[15:0], out2[15:0], out[15:0]};
|
||||
|
||||
`define EXPECTED_SUM 64'hc402f59e3d971718
|
||||
`define EXPECTED_SUM 64'h73c48afee4f0cb57
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
@@ -38,28 +44,33 @@ module t (/*AUTOARG*/
|
||||
if (cyc==0) begin
|
||||
crc <= 64'h0;
|
||||
if (`CLOG2(32'h0) != 0) $stop;
|
||||
if (`CLOG2(32'h1) != 1) $stop;
|
||||
if (`CLOG2(32'h1) != 0) $stop;
|
||||
if (`CLOG2(32'h4) != 2) $stop;
|
||||
if (`CLOG2(32'h7) != 3) $stop;
|
||||
if (`CLOG2(32'h8) != 4) $stop;
|
||||
if (`CLOG2(32'h8) != 3) $stop;
|
||||
if (`CLOG2(32'h9) != 4) $stop;
|
||||
if (`CLOG2({32{1'b1}}) != 32) $stop;
|
||||
if (`CLOG2({1'b1,32'b0}) != 32) $stop;
|
||||
if (`CLOG2({64{1'b1}}) != 64) $stop;
|
||||
if (`CLOG2({1'b1,64'b0}) != 64) $stop;
|
||||
if (`CLOG2({128{1'b1}}) != 128) $stop;
|
||||
if (`CLOG2({1'b1,128'b0}) != 128) $stop;
|
||||
if (`CLOG2({2'b10,128'b0}) != 129) $stop;
|
||||
end
|
||||
else if (cyc==1) begin
|
||||
crc <= 64'h1;
|
||||
if (result != {32'd0, 32'd0}) $stop;
|
||||
if (result[31:0] != {16'd0, 16'd0}) $stop;
|
||||
end
|
||||
else if (cyc==2) begin
|
||||
crc <= 64'h3;
|
||||
if (result != {32'd1, 32'd1}) $stop;
|
||||
if (result[31:0] != {16'd0, 16'd0}) $stop;
|
||||
end
|
||||
else if (cyc==3) begin
|
||||
crc <= {64{1'b1}};
|
||||
if (result != {32'd2, 32'd2}) $stop;
|
||||
if (result[31:0] != {16'd2, 16'd2}) $stop;
|
||||
end
|
||||
else if (cyc==4) begin
|
||||
if (result != {32'd64, 32'd32}) $stop;
|
||||
if (result[31:0] != {16'd64, 16'd8}) $stop;
|
||||
end
|
||||
else if (cyc==8) begin
|
||||
crc <= 64'h5aef0c8d_d70a4497;
|
||||
@@ -80,7 +91,8 @@ module t (/*AUTOARG*/
|
||||
|
||||
function integer clog2_emulate(input [130:0] arg);
|
||||
begin
|
||||
for(clog2_emulate=0; arg>0; clog2_emulate=clog2_emulate+1)
|
||||
if (arg!=0) arg = arg - 1;
|
||||
for (clog2_emulate=0; arg!=0; clog2_emulate=clog2_emulate+1)
|
||||
arg = (arg >> 1);
|
||||
end
|
||||
endfunction
|
||||
|
||||
@@ -9,7 +9,7 @@ module t (
|
||||
);
|
||||
|
||||
neg neg (.clk(CLK));
|
||||
glbl glbl;
|
||||
glbl glbl ();
|
||||
|
||||
initial RESET = 1'b1;
|
||||
always @ (posedge CLK)
|
||||
|
||||
Reference in New Issue
Block a user