Compare commits

...
12 Commits
29 changed files with 379 additions and 112 deletions
+14
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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();
+1 -1
View File
@@ -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
View File
@@ -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,";
+1 -1
View File
@@ -167,7 +167,7 @@ sub parameter {
$_Parameter_Next_Level = $param;
}
else {
warn "%Error: Unknown parameter: $param\n";
die "%Error: Unknown parameter: $param\n";
}
}
+19
View File
@@ -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;
+31
View File
@@ -0,0 +1,31 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 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
+1 -1
View File
@@ -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 (
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 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;
+29
View File
@@ -0,0 +1,29 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 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
+17
View File
@@ -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;
+113
View File
@@ -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
+1 -1
View File
@@ -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
+22 -10
View File
@@ -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
+1 -1
View File
@@ -9,7 +9,7 @@ module t (
);
neg neg (.clk(CLK));
glbl glbl;
glbl glbl ();
initial RESET = 1'b1;
always @ (posedge CLK)