mirror of
https://github.com/verilator/verilator.git
synced 2026-10-05 01:23:37 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
314ffd9353 | ||
|
|
2c953dc37f | ||
|
|
9b9e4e5a3f | ||
|
|
50f835c701 | ||
|
|
cbb3351d97 | ||
|
|
fb81721e7e | ||
|
|
2cedef1333 | ||
|
|
4a1697a1b5 | ||
|
|
86f08a341c | ||
|
|
3d85cbe6b5 | ||
|
|
6d3dd98e77 | ||
|
|
9b2004d6b7 | ||
|
|
eb072da81c | ||
|
|
38669d0a10 | ||
|
|
202a8bc3bb | ||
|
|
45e8ed6b49 | ||
|
|
96692e8a5b | ||
|
|
ecb08b0cf3 | ||
|
|
71bdfd9710 | ||
|
|
193dcf38f4 | ||
|
|
09091781cf |
@@ -3,6 +3,30 @@ 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]
|
||||
|
||||
*** Add SYSTEMPERL_INCLUDE envvar to assist RPM builds. [Chitlesh Goorah]
|
||||
|
||||
**** Report errors when duplicate labels are used, bug72. [Vasu Kandadi]
|
||||
|
||||
**** Fix the SC_MODULE name() to not include __PVT__. [Bob Fredieu]
|
||||
|
||||
* Verilator 3.701 2009/02/26
|
||||
|
||||
** Support repeat and forever statements. [Jeremy Bennett]
|
||||
|
||||
+29
-7
@@ -212,6 +212,7 @@ descriptions in the next sections for more information.
|
||||
-O<optimization-letter> Selectable optimizations
|
||||
--output-split <bytes> Split .cpp files into pieces
|
||||
--output-split-cfuncs <statements> Split .ccp functions
|
||||
--pins-bv <bits> Specify types for top level ports
|
||||
--prefix <topname> Name of top level class
|
||||
--profile-cfuncs Name functions for profiling
|
||||
--private Debugging; see docs
|
||||
@@ -459,9 +460,7 @@ the same as --prefix.
|
||||
|
||||
=item --no-pins64
|
||||
|
||||
Specifies SystemC outputs of 33-64 bits wide should use sc_bv's instead of
|
||||
uint64_t's. Uint64's are faster, but sc_bvs were the default until
|
||||
Verilator 3.671.
|
||||
Backward compatible alias for "--pins-bv 33".
|
||||
|
||||
=item --no-skip-identical
|
||||
|
||||
@@ -507,6 +506,17 @@ worse with decreasing split values. Note that this option is stronger than
|
||||
--output-split in the sense that --output-split will not split inside a
|
||||
function.
|
||||
|
||||
=item --pins64
|
||||
|
||||
Backward compatible alias for "--pins-bv 65". Note that's a 65, not a 64.
|
||||
|
||||
=item --pins-bv I<width>
|
||||
|
||||
Specifies SystemC outputs of greater than or equal to I<width> bits wide
|
||||
should use sc_bv's instead of uint32/uint64_t's. The default is "--pins-bv
|
||||
65". Versions before Verilator 3.671 defaulted to "--pins-bv 33". The
|
||||
more sc_bv is used, the worse for performance.
|
||||
|
||||
=item --prefix I<topname>
|
||||
|
||||
Specifies the name of the top level class and makefile. Defaults to V
|
||||
@@ -943,10 +953,18 @@ building the SystemC model.
|
||||
|
||||
=item SYSTEMPERL
|
||||
|
||||
Specifies the directory containing the Verilog-Perl distribution kit. This
|
||||
is used to find the Verilog-Perl library and include files. If not
|
||||
Specifies the directory containing the SystemPerl distribution kit. This
|
||||
is used to find the SystemPerl library and include files. If not
|
||||
specified, it will come from a default optionally specified at configure
|
||||
time (before Verilator was compiled).
|
||||
time (before Verilator was compiled). See also SYSTEMPERL_INCLUDE.
|
||||
|
||||
=item SYSTEMPERL_INCLUDE
|
||||
|
||||
Specifies the directory containing the Verilog-Perl include .cpp files,
|
||||
from the src/ directory of the SystemPerl kit. If not specified, it will
|
||||
be computed from the SYSTEMPERL environment variable if it is set, and if
|
||||
SYSTEMPERL is not set SYSTEMPERL_INCLUDE will come from a default
|
||||
optionally specified at configure time (before Verilator was compiled).
|
||||
|
||||
=item VCS_HOME
|
||||
|
||||
@@ -1153,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([])
|
||||
|
||||
+76
-70
@@ -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) {
|
||||
@@ -359,35 +359,45 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
|
||||
|
||||
//===================================================================
|
||||
// SYSTEMC OPERATORS
|
||||
// Copying verilog format to/from systemc integers and bit vectors.
|
||||
|
||||
#define VL_ASSIGN_IS(obits,vvar,svar) { (vvar) = VL_CLEAN_II((obits),(obits),(svar).read()); }
|
||||
#define VL_ASSIGN_SI(obits,svar,vvar) { (svar).write(vvar); }
|
||||
// Copying verilog format to systemc integers and bit vectors.
|
||||
|
||||
#define VL_ASSIGN_ISI(obits,vvar,svar) { (vvar) = VL_CLEAN_II((obits),(obits),(svar).read()); }
|
||||
#define VL_ASSIGN_QSQ(obits,vvar,svar) { (vvar) = VL_CLEAN_QQ((obits),(obits),(svar).read()); }
|
||||
|
||||
#define VL_ASSIGN_ISW(obits,od,svar) { \
|
||||
od = (svar.read().get_word(0)) & VL_MASK_I(obits); \
|
||||
}
|
||||
#define VL_ASSIGN_QSW(obits,od,svar) { \
|
||||
od = (((QData)svar.read().get_word(1))<<VL_WORDSIZE | svar.read().get_word(0)) \
|
||||
& VL_MASK_Q(obits); \
|
||||
}
|
||||
#define VL_ASSIGN_WSW(obits,owp,svar) { \
|
||||
int words = VL_WORDS_I(obits); \
|
||||
for (int i=0; i < words; i++) owp[i] = svar.read().get_word(i); \
|
||||
owp[words-1] &= VL_MASK_I(obits); \
|
||||
}
|
||||
|
||||
// Copying verilog format from systemc integers and bit vectors.
|
||||
|
||||
#define VL_ASSIGN_SII(obits,svar,vvar) { (svar).write(vvar); }
|
||||
#define VL_ASSIGN_SQQ(obits,svar,vvar) { (svar).write(vvar); }
|
||||
|
||||
#define VL_ASSIGN_SQ(obits,svar,rd) { \
|
||||
#define VL_ASSIGN_SWI(obits,svar,rd) { \
|
||||
sc_bv<obits> _bvtemp; \
|
||||
_bvtemp.set_word(0,rd); \
|
||||
svar.write(_bvtemp); \
|
||||
}
|
||||
#define VL_ASSIGN_SWQ(obits,svar,rd) { \
|
||||
sc_bv<obits> _bvtemp; \
|
||||
_bvtemp.set_word(0,rd); \
|
||||
_bvtemp.set_word(1,rd>>VL_WORDSIZE); \
|
||||
svar.write(_bvtemp); \
|
||||
}
|
||||
#define VL_ASSIGN_QS(obits,od,svar) { \
|
||||
od = (((QData)svar.read().get_word(1))<<VL_WORDSIZE | svar.read().get_word(0)) \
|
||||
& VL_MASK_Q(obits); \
|
||||
}
|
||||
|
||||
#define VL_ASSIGN_SW(obits,svar,rwp) { \
|
||||
#define VL_ASSIGN_SWW(obits,svar,rwp) { \
|
||||
sc_bv<obits> _bvtemp; \
|
||||
for (int i=0; i < VL_WORDS_I(obits); i++) _bvtemp.set_word(i,rwp[i]); \
|
||||
svar.write(_bvtemp); \
|
||||
}
|
||||
#define VL_ASSIGN_WS(obits,owp,svar) { \
|
||||
int words = VL_WORDS_I(obits); \
|
||||
for (int i=0; i < words; i++) owp[i] = svar.read().get_word(i); \
|
||||
owp[words-1] &= VL_MASK_I(obits); \
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
// Extending sizes
|
||||
@@ -431,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);
|
||||
}
|
||||
@@ -446,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);
|
||||
}
|
||||
@@ -526,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
|
||||
@@ -612,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
|
||||
|
||||
@@ -981,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;
|
||||
}
|
||||
}
|
||||
@@ -1178,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);
|
||||
@@ -1354,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
|
||||
|
||||
|
||||
@@ -89,8 +89,8 @@ endif
|
||||
##### SystemPerl builds
|
||||
|
||||
ifeq ($(VM_SP),1)
|
||||
CPPFLAGS += -I$(SYSTEMPERL)/src -DSYSTEMPERL
|
||||
VPATH += $(SYSTEMPERL)/src
|
||||
CPPFLAGS += -I$(SYSTEMPERL_INCLUDE) -DSYSTEMPERL
|
||||
VPATH += $(SYSTEMPERL_INCLUDE)
|
||||
LIBS += -lm -lstdc++
|
||||
|
||||
VK_CLASSES_SP = $(addsuffix .sp, $(VM_CLASSES))
|
||||
@@ -110,8 +110,8 @@ endif
|
||||
ifeq ($(VM_SC),1)
|
||||
LIBS += -lm -lstdc++
|
||||
ifeq ($(VM_TRACE),1)
|
||||
CPPFLAGS += -I$(SYSTEMPERL)/src
|
||||
VPATH += $(SYSTEMPERL)/src
|
||||
CPPFLAGS += -I$(SYSTEMPERL_INCLUDE)
|
||||
VPATH += $(SYSTEMPERL_INCLUDE)
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -121,8 +121,8 @@ endif
|
||||
ifeq ($(VM_PCLI),1)
|
||||
LIBS += -lm -lstdc++
|
||||
ifeq ($(VM_TRACE),1)
|
||||
CPPFLAGS += -I$(SYSTEMPERL)/src
|
||||
VPATH += $(SYSTEMPERL)/src
|
||||
CPPFLAGS += -I$(SYSTEMPERL_INCLUDE)
|
||||
VPATH += $(SYSTEMPERL_INCLUDE)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
+5
-4
@@ -116,8 +116,9 @@ If you will be using SystemC, download and install Verilog-Perl,
|
||||
If you will be using SystemC, download and install System-Perl,
|
||||
@url{http://search.cpan.org/search?module=SystemC::Netlist}. Note
|
||||
you'll need to set a @samp{SYSTEMPERL} environment variable to point
|
||||
to the downloaded kit (not the installed files.) Also, make sure to
|
||||
do a @code{make sc_patch}.
|
||||
to the downloaded kit. Optionally also set @samp{SYSTEMPERL_INCLUDE}
|
||||
to point to the installed headers. Also, make sure to do a @code{make
|
||||
sc_patch}.
|
||||
|
||||
@item
|
||||
@code{cd} to the Verilator directory containing this README.
|
||||
@@ -128,8 +129,8 @@ Type @samp{./configure} to configure Verilator for your system.
|
||||
If you are configuring Verilator to be part of a RPM or other
|
||||
distribution package system, you may want to use the --enable-defenv
|
||||
configure flag. This will take the current value of VERILATOR_ROOT,
|
||||
SYSTEMC, SYSTEMC_ARCH, and SYSTEMPERL and build them as defaults into
|
||||
the executable.
|
||||
SYSTEMC, SYSTEMC_ARCH, SYSTEMPERL, and SYSTEMPERL_INCLUDE and build
|
||||
them as defaults into the executable.
|
||||
|
||||
@item
|
||||
Type @samp{make} to compile Verilator.
|
||||
|
||||
+9
-1
@@ -81,12 +81,19 @@ CPPFLAGS += -W -Wall -Wno-unused-parameter -Wno-char-subscripts -Werror
|
||||
#CPPFLAGS += -pedantic-errors
|
||||
endif
|
||||
|
||||
ifneq ($(SYSTEMPERL),) # Intuit SYSTEMPERL_INCLUDE as it's new
|
||||
SYSTEMPERL_INCLUDE ?= $(SYSTEMPERL)/src
|
||||
#else if set, leave as-is.
|
||||
#else if SYSTEMPERL="" don't set _INCLUDE so source will figure it out
|
||||
endif
|
||||
|
||||
# Allow RPM builds to specify hardcoded data directories
|
||||
# To do this:
|
||||
ifeq ($(CFG_WITH_DEFENV),yes)
|
||||
CPPFLAGS += -DDEFENV_SYSTEMC=\"$(SYSTEMC)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMC_ARCH=\"$(SYSTEMC_ARCH)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMPERL=\"$(SYSTEMPERL)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMPERL_INCLUDE=\"$(SYSTEMPERL_INCLUDE)\"
|
||||
ifeq ($(VERILATOR_ROOT),) # Use what we're given, or intuit
|
||||
CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(pkgdatadir)\"
|
||||
else
|
||||
@@ -262,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
|
||||
@@ -280,4 +289,3 @@ DEPS := $(wildcard *.d)
|
||||
ifneq ($(DEPS),)
|
||||
include $(DEPS)
|
||||
endif
|
||||
|
||||
|
||||
+7
-7
@@ -51,11 +51,11 @@ bool AstVar::isSigPublic() const {
|
||||
}
|
||||
|
||||
bool AstVar::isScQuad() const {
|
||||
return (isSc()&&isQuad()&&v3Global.opt.pins64());
|
||||
return (isSc() && isQuad() && !isScBv());
|
||||
}
|
||||
|
||||
bool AstVar::isScWide() const {
|
||||
return (isWide() || isSc()&&isQuad()&&!v3Global.opt.pins64());
|
||||
bool AstVar::isScBv() const {
|
||||
return (isSc() && width() >= v3Global.opt.pinsBv());
|
||||
}
|
||||
|
||||
void AstVar::combineType(AstVarType type) {
|
||||
@@ -108,7 +108,7 @@ string AstVar::cType() const {
|
||||
return "bool";
|
||||
} else if (widthMin() <= VL_WORDSIZE) {
|
||||
return "uint32_t";
|
||||
} else if (isScWide()) {
|
||||
} else if (isWide()) {
|
||||
return "uint32_t"; // []'s added later
|
||||
} else {
|
||||
return "uint64_t";
|
||||
@@ -116,12 +116,12 @@ string AstVar::cType() const {
|
||||
}
|
||||
|
||||
string AstVar::scType() const {
|
||||
if (widthMin() == 1) {
|
||||
if (isScBv()) {
|
||||
return (string("sc_bv<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
|
||||
} else if (widthMin() == 1) {
|
||||
return "bool";
|
||||
} else if (widthMin() <= VL_WORDSIZE) {
|
||||
return "uint32_t";
|
||||
} else if (isScWide()) {
|
||||
return (string("sc_bv<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
|
||||
} else {
|
||||
return "uint64_t";
|
||||
}
|
||||
|
||||
+1
-1
@@ -341,7 +341,7 @@ public:
|
||||
bool isUsedParam() const { return m_usedParam; }
|
||||
bool isSc() const { return m_sc; }
|
||||
bool isScQuad() const;
|
||||
bool isScWide() const;
|
||||
bool isScBv() const;
|
||||
bool isScSensitive() const { return m_scSensitive; }
|
||||
bool isSigPublic() const;
|
||||
bool isSigModPublic() const { return m_sigModPublic; }
|
||||
|
||||
+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);
|
||||
}
|
||||
}
|
||||
|
||||
+17
-14
@@ -75,6 +75,9 @@ public:
|
||||
void emitIQW(AstNode* nodep) {
|
||||
puts (nodep->isWide()?"W":(nodep->isQuad()?"Q":"I"));
|
||||
}
|
||||
void emitScIQW(AstVar* nodep) {
|
||||
puts (nodep->isScBv()?"SW":(nodep->isScQuad()?"SQ":"SI"));
|
||||
}
|
||||
void emitOpName(AstNode* nodep, const string& format,
|
||||
AstNode* lhsp, AstNode* rhsp, AstNode* thsp);
|
||||
|
||||
@@ -130,8 +133,7 @@ public:
|
||||
} else if (nodep->lhsp()->castVarRef()
|
||||
&& nodep->lhsp()->castVarRef()->varp()->isSc()) {
|
||||
putbs("VL_ASSIGN_"); // Set a systemC variable
|
||||
if (nodep->lhsp()->castVarRef()->varp()->isScQuad()) puts("SQ");
|
||||
else puts("S");
|
||||
emitScIQW(nodep->lhsp()->castVarRef()->varp());
|
||||
emitIQW(nodep);
|
||||
puts("(");
|
||||
puts(cvtToStr(nodep->widthMin())+",");
|
||||
@@ -140,8 +142,8 @@ public:
|
||||
&& nodep->rhsp()->castVarRef()->varp()->isSc()) {
|
||||
putbs("VL_ASSIGN_"); // Get a systemC variable
|
||||
emitIQW(nodep);
|
||||
if (nodep->rhsp()->castVarRef()->varp()->isScQuad()) puts("SQ(");
|
||||
else puts("S(");
|
||||
emitScIQW(nodep->rhsp()->castVarRef()->varp());
|
||||
puts("(");
|
||||
puts(cvtToStr(nodep->widthMin())+",");
|
||||
nodep->lhsp()->iterateAndNext(*this); puts(", ");
|
||||
} else if (nodep->isWide()
|
||||
@@ -475,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);
|
||||
@@ -485,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");
|
||||
}
|
||||
@@ -1412,7 +1415,7 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
|
||||
int sigbytes = varp->widthAlignBytes();
|
||||
if (varp->isUsedClock() && varp->widthMin()==1) sigbytes = 0;
|
||||
else if (varp->arraysp()) sigbytes=7;
|
||||
else if (varp->isScWide()) sigbytes=6;
|
||||
else if (varp->isScBv()) sigbytes=6;
|
||||
else if (sigbytes==8) sigbytes=5;
|
||||
else if (sigbytes==4) sigbytes=4;
|
||||
else if (sigbytes==2) sigbytes=2;
|
||||
@@ -1544,7 +1547,7 @@ void EmitCImp::emitInt(AstModule* modp) {
|
||||
if (!varp->initp()) nodep->v3fatalSrc("No init for a param?");
|
||||
// These should be static const values, however microsloth VC++ doesn't
|
||||
// support them. They also cause problems with GDB under GCC2.95.
|
||||
if (varp->isScWide()) { // Unsupported for output
|
||||
if (varp->isWide()) { // Unsupported for output
|
||||
puts("// enum WData "+varp->name()+" //wide");
|
||||
} else if (!varp->initp()->castConst()) { // Unsupported for output
|
||||
puts("// enum IData "+varp->name()+" //not simple value");
|
||||
@@ -1816,11 +1819,11 @@ class EmitCTrace : EmitCStmts {
|
||||
puts("\n//======================\n\n");
|
||||
}
|
||||
|
||||
bool emitTraceIsScWide(AstTraceInc* nodep) {
|
||||
bool emitTraceIsScBv(AstTraceInc* nodep) {
|
||||
AstVarRef* varrefp = nodep->valuep()->castVarRef();
|
||||
if (!varrefp) return false;
|
||||
AstVar* varp = varrefp->varp();
|
||||
return varp->isSc() && varp->isScWide();
|
||||
return varp->isSc() && varp->isScBv();
|
||||
}
|
||||
void emitTraceInitOne(AstTraceDecl* nodep) {
|
||||
if (nodep->isWide()) {
|
||||
@@ -1851,7 +1854,7 @@ class EmitCTrace : EmitCStmts {
|
||||
string full = ((m_funcp->funcType() == AstCFuncType::TRACE_FULL
|
||||
|| m_funcp->funcType() == AstCFuncType::TRACE_FULL_SUB)
|
||||
? "full":"chg");
|
||||
if (nodep->isWide() || emitTraceIsScWide(nodep)) {
|
||||
if (nodep->isWide() || emitTraceIsScBv(nodep)) {
|
||||
puts("vcdp->"+full+"Array");
|
||||
} else if (nodep->isQuad()) {
|
||||
puts("vcdp->"+full+"Quad ");
|
||||
@@ -1873,7 +1876,7 @@ class EmitCTrace : EmitCStmts {
|
||||
if (nodep->valuep()->castVarRef()) {
|
||||
AstVarRef* varrefp = nodep->valuep()->castVarRef();
|
||||
AstVar* varp = varrefp->varp();
|
||||
if (emitTraceIsScWide(nodep)) puts("(uint32_t*)");
|
||||
if (emitTraceIsScBv(nodep)) puts("(uint32_t*)");
|
||||
puts("(");
|
||||
varrefp->iterate(*this); // Put var name out
|
||||
if (varp->arraysp()) {
|
||||
@@ -1882,7 +1885,7 @@ class EmitCTrace : EmitCStmts {
|
||||
else puts("["+cvtToStr(arrayindex)+"]");
|
||||
}
|
||||
if (varp->isSc()) puts(".read()");
|
||||
if (emitTraceIsScWide(nodep)) puts(".get_datap()");
|
||||
if (emitTraceIsScBv(nodep)) puts(".get_datap()");
|
||||
puts(")");
|
||||
} else {
|
||||
puts("(");
|
||||
|
||||
+1
-3
@@ -207,11 +207,9 @@ void EmitCSyms::emitImp() {
|
||||
AstScope* scopep = it->first; AstModule* modp = it->second;
|
||||
if (modp->isTop()) {
|
||||
} else {
|
||||
string arrow = scopep->name();
|
||||
if (arrow.substr(0,4) == "TOP.") arrow.replace(0,4,".");
|
||||
ofp()->printf("\t%c %-30s ", comma, scopep->nameDotless().c_str());
|
||||
puts("(Verilated::catName(topp->name(),\"");
|
||||
puts(arrow);
|
||||
puts("."+scopep->prettyName());
|
||||
puts("\"))\n");
|
||||
comma=',';
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ public:
|
||||
of.puts("PERL = "+V3Options::getenvPERL()+"\n");
|
||||
of.puts("VERILATOR_ROOT = "+V3Options::getenvVERILATOR_ROOT()+"\n");
|
||||
of.puts("SYSTEMPERL = "+V3Options::getenvSYSTEMPERL()+"\n");
|
||||
of.puts("SYSTEMPERL_INCLUDE = "+V3Options::getenvSYSTEMPERL_INCLUDE()+"\n");
|
||||
|
||||
of.puts("\n# Switches...\n");
|
||||
of.puts(string("VM_SP = ")+(v3Global.opt.systemPerl()?"1":"0")+"\n");
|
||||
|
||||
+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) {
|
||||
|
||||
+98
-58
@@ -29,6 +29,7 @@
|
||||
#include "verilatedos.h"
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <cctype>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
@@ -49,10 +50,11 @@ private:
|
||||
// AstModule::user1p() // V3SymTable* Module's Symbol table
|
||||
// AstNodeFTask::user1p() // V3SymTable* Local Symbol table
|
||||
// AstBegin::user1p() // V3SymTable* Local Symbol table
|
||||
// AstVar::user1p() // V3SymTable* Table used to create this variable
|
||||
// AstVar::user2p() // bool True if port set for this variable
|
||||
// AstVar/Module::user3p() // V3SymTable* Table used to create this variable
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
AstUser3InUse m_inuser3;
|
||||
|
||||
// ENUMS
|
||||
enum IdState { // Which loop through the tree
|
||||
@@ -69,6 +71,7 @@ private:
|
||||
V3SymTable* m_curVarsp; // Symbol table of variables and tasks under table we're inserting into
|
||||
V3SymTable* m_cellVarsp; // Symbol table of variables under cell's module
|
||||
int m_beginNum; // Begin block number, 0=none seen
|
||||
bool m_inGenerate; // Inside a generate
|
||||
vector<V3SymTable*> m_delSymps; // Symbol tables to delete
|
||||
|
||||
static int debug() {
|
||||
@@ -78,22 +81,74 @@ private:
|
||||
}
|
||||
|
||||
// METHODS
|
||||
V3SymTable* symsFindNew(AstNode* nodep, V3SymTable* upperVarsp) {
|
||||
// Find or create symbol table for this node
|
||||
if (V3SymTable* symsp = nodep->user1p()->castSymTable()) {
|
||||
return symsp;
|
||||
} else {
|
||||
V3SymTable* symsp = new V3SymTable(upperVarsp);
|
||||
m_delSymps.push_back(symsp);
|
||||
nodep->user1p(symsp);
|
||||
return symsp;
|
||||
}
|
||||
}
|
||||
|
||||
void symsInsert(const string& name, AstNode* nodep) {
|
||||
// Insert into symbol table, and remember what table the node is in
|
||||
m_curVarsp->insert(name, nodep);
|
||||
nodep->user3p(m_curVarsp);
|
||||
}
|
||||
|
||||
void linkVarName (AstVarRef* nodep) {
|
||||
if (!nodep->varp()) {
|
||||
AstVar* varp = m_curVarsp->findIdName(nodep->name())->castVar();
|
||||
AstVar* varp = m_curVarsp->findIdUpward(nodep->name())->castVar();
|
||||
nodep->varp(varp);
|
||||
}
|
||||
}
|
||||
|
||||
const char* varTextType(AstNode* nodep) {
|
||||
const char* nodeTextType(AstNode* nodep) {
|
||||
const char* what = "node";
|
||||
if (nodep->castVar()) what = "variable";
|
||||
else if (nodep->castCell()) what = "cell";
|
||||
else if (nodep->castTask()) what = "task";
|
||||
else if (nodep->castFunc()) what = "function";
|
||||
else if (nodep->castBegin()) what = "block";
|
||||
return what;
|
||||
}
|
||||
|
||||
string ucfirst(const string& text) {
|
||||
string out = text;
|
||||
out[0] = toupper(out[0]);
|
||||
return out;
|
||||
}
|
||||
|
||||
void findAndInsertAndCheck(AstNode* nodep, const string& name) {
|
||||
// Lookup the given name under current symbol table
|
||||
// Insert if not found
|
||||
// Report error if there's a duplicate
|
||||
//
|
||||
// Note we only check for conflicts at the same level; it's ok if one block hides another
|
||||
// We also wouldn't want to not insert it even though it's lower down
|
||||
AstNode* foundp = m_curVarsp->findIdFlat(name);
|
||||
if (!foundp) {
|
||||
symsInsert(nodep->name(), nodep);
|
||||
foundp = nodep;
|
||||
} else if (nodep==foundp) { // Already inserted.
|
||||
// Good.
|
||||
} else if ((nodep->castBegin() || foundp->castBegin())
|
||||
&& m_inGenerate) {
|
||||
// Begin: ... blocks often replicate under genif/genfor, so simply suppress duplicate checks
|
||||
// See t_gen_forif.v for an example.
|
||||
} else if (nodep->type() == foundp->type()) {
|
||||
nodep->v3error("Duplicate declaration of "<<nodeTextType(foundp)<<": "<<nodep->prettyName());
|
||||
foundp->v3error("... Location of original declaration");
|
||||
} else {
|
||||
nodep->v3error("Unsupported in C: "<<ucfirst(nodeTextType(nodep))<<" has the same name as "
|
||||
<<nodeTextType(foundp)<<": "<<nodep->prettyName());
|
||||
foundp->v3error("... Location of original declaration");
|
||||
}
|
||||
}
|
||||
|
||||
void createImplicitVar (AstVarRef* forrefp, bool noWarn) {
|
||||
// Create implicit after warning
|
||||
linkVarName(forrefp);
|
||||
@@ -115,9 +170,7 @@ private:
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
// Look at all modules, and store pointers to all module names
|
||||
for (AstModule* modp = v3Global.rootp()->modulesp(); modp; modp=modp->nextp()->castModule()) {
|
||||
V3SymTable* symp = new V3SymTable(NULL);
|
||||
m_delSymps.push_back(symp);
|
||||
modp->user1p(symp);
|
||||
symsFindNew(modp, NULL);
|
||||
}
|
||||
// And recurse...
|
||||
m_idState = ID_FIND;
|
||||
@@ -134,7 +187,7 @@ private:
|
||||
UINFO(2,"Link Module: "<<nodep<<endl);
|
||||
m_modp = nodep;
|
||||
// This state must be save/restored in the cell visitor function
|
||||
m_curVarsp = nodep->user1p()->castSymTable();
|
||||
m_curVarsp = symsFindNew(nodep, NULL);
|
||||
if (!m_curVarsp) nodep->v3fatalSrc("NULL");
|
||||
m_cellVarsp = NULL;
|
||||
m_paramNum = 0;
|
||||
@@ -144,6 +197,18 @@ private:
|
||||
m_curVarsp = NULL;
|
||||
m_modp = NULL;
|
||||
}
|
||||
|
||||
virtual void visit(AstGenerate* nodep, AstNUser*) {
|
||||
// Begin: ... blocks often replicate under genif/genfor, so simply suppress duplicate checks
|
||||
// See t_gen_forif.v for an example.
|
||||
bool lastInGen = m_inGenerate;
|
||||
{
|
||||
m_inGenerate = true;
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
m_inGenerate = lastInGen;
|
||||
}
|
||||
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {
|
||||
// Var: Remember its name for later resolution
|
||||
if (!m_curVarsp) nodep->v3fatalSrc("Var not under module??\n");
|
||||
@@ -157,17 +222,17 @@ private:
|
||||
nodep->trace(false);
|
||||
}
|
||||
// Find under either a task or the module's vars
|
||||
AstNode* findidp = m_curVarsp->findIdName(nodep->name());
|
||||
AstVar* findvarp = findidp->castVar();
|
||||
AstNode* foundp = m_curVarsp->findIdUpward(nodep->name());
|
||||
AstVar* findvarp = foundp->castVar();
|
||||
bool ins=false;
|
||||
if (!findidp) {
|
||||
if (!foundp) {
|
||||
ins=true;
|
||||
} else if (!findvarp) {
|
||||
nodep->v3error("Unsupported in C: Variable has same name as "
|
||||
<<varTextType(findidp)<<": "<<nodep->prettyName());
|
||||
<<nodeTextType(foundp)<<": "<<nodep->prettyName());
|
||||
} else if (findvarp != nodep) {
|
||||
UINFO(4,"DupVar: "<<nodep<<" ;; "<<findvarp<<endl);
|
||||
if (findvarp->user1p() == m_curVarsp) { // Only when on same level
|
||||
if (findvarp->user3p() == m_curVarsp) { // Only when on same level
|
||||
if ((findvarp->isIO() && nodep->isSignal())
|
||||
|| (findvarp->isSignal() && nodep->isIO())) {
|
||||
findvarp->combineType(nodep);
|
||||
@@ -188,11 +253,10 @@ private:
|
||||
}
|
||||
}
|
||||
if (ins) {
|
||||
m_curVarsp->insert(nodep->name(), nodep);
|
||||
nodep->user1p(m_curVarsp);
|
||||
symsInsert(nodep->name(), nodep);
|
||||
if (nodep->isGParam()) {
|
||||
m_paramNum++;
|
||||
m_curVarsp->insert("__paramNumber"+cvtToStr(m_paramNum), nodep);
|
||||
symsInsert("__paramNumber"+cvtToStr(m_paramNum), nodep);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,13 +288,8 @@ private:
|
||||
V3SymTable* upperVarsp = m_curVarsp;
|
||||
{
|
||||
// Create symbol table for the task's vars
|
||||
if (V3SymTable* localVarsp = nodep->user1p()->castSymTable()) {
|
||||
m_curVarsp = localVarsp;
|
||||
} else {
|
||||
m_curVarsp = new V3SymTable(upperVarsp);
|
||||
m_delSymps.push_back(m_curVarsp);
|
||||
nodep->user1p(m_curVarsp);
|
||||
}
|
||||
m_curVarsp = symsFindNew(nodep, upperVarsp);
|
||||
|
||||
// Convert the func's range to the output variable
|
||||
// This should probably be done in the Parser instead, as then we could
|
||||
// just attact normal signal attributes to it.
|
||||
@@ -245,7 +304,7 @@ private:
|
||||
newvarp->attrIsolateAssign(funcp->attrIsolateAssign());
|
||||
funcp->addFvarp(newvarp);
|
||||
// Explicit insert required, as the var name shadows the upper level's task name
|
||||
m_curVarsp->insert(newvarp->name(), newvarp);
|
||||
symsInsert(newvarp->name(), newvarp);
|
||||
}
|
||||
}
|
||||
m_ftaskp = nodep;
|
||||
@@ -254,16 +313,7 @@ private:
|
||||
}
|
||||
m_curVarsp = upperVarsp;
|
||||
if (m_idState==ID_FIND) {
|
||||
AstNode* findidp = m_curVarsp->findIdName(nodep->name());
|
||||
AstNodeFTask* findtaskp = findidp->castNodeFTask();
|
||||
if (!findidp) {
|
||||
m_curVarsp->insert(nodep->name(), nodep);
|
||||
} else if (!findtaskp) {
|
||||
nodep->v3error("Unsupported in C: Task/function has same name as "
|
||||
<<varTextType(findidp)<<": "<<nodep->prettyName());
|
||||
} else if (findtaskp!=nodep) {
|
||||
nodep->v3error("Duplicate declaration of task/function: "<<nodep->prettyName());
|
||||
}
|
||||
findAndInsertAndCheck(nodep, nodep->name());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstBegin* nodep, AstNUser*) {
|
||||
@@ -277,18 +327,16 @@ private:
|
||||
++m_beginNum;
|
||||
nodep->name(nodep->name()+cvtToStr(m_beginNum));
|
||||
}
|
||||
// Check naming (we don't really care, but some tools do, so better to warn)
|
||||
if (m_idState==ID_FIND) {
|
||||
findAndInsertAndCheck(nodep, nodep->name());
|
||||
}
|
||||
// Recurse
|
||||
int oldNum = m_beginNum;
|
||||
m_beginNum = 0;
|
||||
{
|
||||
// Create symbol table for the task's vars
|
||||
if (V3SymTable* localVarsp = nodep->user1p()->castSymTable()) {
|
||||
m_curVarsp = localVarsp;
|
||||
} else {
|
||||
m_curVarsp = new V3SymTable(upperVarsp);
|
||||
m_delSymps.push_back(m_curVarsp);
|
||||
nodep->user1p(m_curVarsp);
|
||||
}
|
||||
m_curVarsp = symsFindNew(nodep, upperVarsp);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
m_curVarsp = upperVarsp;
|
||||
@@ -298,7 +346,7 @@ private:
|
||||
// NodeFTaskRef: Resolve its reference
|
||||
if (m_idState==ID_RESOLVE && !nodep->taskp()) {
|
||||
if (nodep->dotted() == "") {
|
||||
AstNodeFTask* taskp = m_curVarsp->findIdName(nodep->name())->castNodeFTask();
|
||||
AstNodeFTask* taskp = m_curVarsp->findIdUpward(nodep->name())->castNodeFTask();
|
||||
if (!taskp) { nodep->v3error("Can't find definition of task/function: "<<nodep->prettyName()); }
|
||||
nodep->taskp(taskp);
|
||||
}
|
||||
@@ -310,16 +358,7 @@ private:
|
||||
// Cell: Resolve its filename. If necessary, parse it.
|
||||
if (m_idState==ID_FIND) {
|
||||
// Add to list of all cells, for error checking and defparam's
|
||||
AstNode* findidp = m_curVarsp->findIdName(nodep->name());
|
||||
AstCell* findcellp = findidp->castCell();
|
||||
if (!findidp) {
|
||||
m_curVarsp->insert(nodep->name(), nodep);
|
||||
} else if (!findcellp) {
|
||||
nodep->v3error("Unsupported in C: Cell has same name as "
|
||||
<<varTextType(findidp)<<": "<<nodep->prettyName());
|
||||
} else if (findcellp != nodep) {
|
||||
nodep->v3error("Duplicate name of cell: "<<nodep->prettyName());
|
||||
}
|
||||
findAndInsertAndCheck(nodep, nodep->name());
|
||||
}
|
||||
if (!nodep->modp()) {
|
||||
nodep->v3fatalSrc("Cell has unlinked module"); // V3LinkCell should have errored out
|
||||
@@ -343,13 +382,13 @@ private:
|
||||
if (m_idState==ID_PARAM) {
|
||||
// Need to set pin numbers after varnames are created
|
||||
// But before we do the final resolution based on names
|
||||
AstVar* refp = m_curVarsp->findIdName(nodep->name())->castVar();
|
||||
AstVar* refp = m_curVarsp->findIdFlat(nodep->name())->castVar();
|
||||
if (!refp) {
|
||||
nodep->v3error("Input/output/inout declaration not found for port: "<<nodep->prettyName());
|
||||
} else if (!refp->isIO()) {
|
||||
nodep->v3error("Pin is not a in/out/inout: "<<nodep->prettyName());
|
||||
nodep->v3error("Pin is not an in/out/inout: "<<nodep->prettyName());
|
||||
} else {
|
||||
m_curVarsp->insert("__pinNumber"+cvtToStr(nodep->pinNum()), refp);
|
||||
symsInsert("__pinNumber"+cvtToStr(nodep->pinNum()), refp);
|
||||
refp->user2(true);
|
||||
}
|
||||
// Ports not needed any more
|
||||
@@ -377,11 +416,11 @@ private:
|
||||
// Pin: Link to submodule's pin
|
||||
if (!m_cellVarsp) nodep->v3fatalSrc("Pin not under cell?\n");
|
||||
if (m_idState==ID_RESOLVE && !nodep->modVarp()) {
|
||||
AstVar* refp = m_cellVarsp->findIdName(nodep->name())->castVar();
|
||||
AstVar* refp = m_cellVarsp->findIdFlat(nodep->name())->castVar();
|
||||
if (!refp) {
|
||||
nodep->v3error("Pin not found: "<<nodep->prettyName());
|
||||
} else if (!refp->isIO() && !refp->isParam()) {
|
||||
nodep->v3error("Pin is not a in/out/inout/param: "<<nodep->prettyName());
|
||||
nodep->v3error("Pin is not an in/out/inout/param: "<<nodep->prettyName());
|
||||
} else {
|
||||
nodep->modVarp(refp);
|
||||
}
|
||||
@@ -407,8 +446,8 @@ private:
|
||||
virtual void visit(AstDefParam* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_idState==ID_PARAM) {
|
||||
AstNode* findidp = m_curVarsp->findIdName(nodep->path());
|
||||
AstCell* cellp = findidp->castCell();
|
||||
AstNode* foundp = m_curVarsp->findIdUpward(nodep->path());
|
||||
AstCell* cellp = foundp->castCell();
|
||||
if (!cellp) {
|
||||
nodep->v3error("In defparam, cell "<<nodep->path()<<" never declared");
|
||||
} else {
|
||||
@@ -440,6 +479,7 @@ public:
|
||||
m_ftaskp = NULL;
|
||||
m_paramNum = 0;
|
||||
m_beginNum = 0;
|
||||
m_inGenerate = false;
|
||||
//
|
||||
rootp->accept(*this);
|
||||
}
|
||||
|
||||
+30
-9
@@ -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);
|
||||
}
|
||||
@@ -144,7 +163,9 @@ private:
|
||||
// Cell: Resolve its filename. If necessary, parse it.
|
||||
if (!nodep->modp()) {
|
||||
UINFO(4,"Link Cell: "<<nodep<<endl);
|
||||
AstModule* modp = m_mods.findIdName(nodep->modName())->castModule();
|
||||
// Use findIdUpward instead of findIdFlat; it doesn't matter for now
|
||||
// but we might support modules-under-modules someday.
|
||||
AstModule* modp = m_mods.findIdUpward(nodep->modName())->castModule();
|
||||
if (!modp) {
|
||||
// Read-subfile
|
||||
V3Read reader (v3Global.rootp());
|
||||
@@ -153,7 +174,7 @@ private:
|
||||
// We've read new modules, grab new pointers to their names
|
||||
readModNames();
|
||||
// Check again
|
||||
modp = m_mods.findIdName(nodep->modName())->castModule();
|
||||
modp = m_mods.findIdUpward(nodep->modName())->castModule();
|
||||
if (!modp) {
|
||||
nodep->v3error("Can't resolve module reference: "<<nodep->modName());
|
||||
}
|
||||
@@ -171,7 +192,7 @@ private:
|
||||
V3SymTable ports; // Symbol table of all connected port names
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
if (pinp->name()=="") pinp->v3error("Connect by position is illegal in .* connected cells");
|
||||
if (!ports.findIdName(pinp->name())) {
|
||||
if (!ports.findIdFlat(pinp->name())) {
|
||||
ports.insert(pinp->name(), pinp);
|
||||
}
|
||||
}
|
||||
@@ -179,7 +200,7 @@ private:
|
||||
// and it's easier to do it now than in V3Link when we'd need to repeat steps.
|
||||
for (AstNode* portnodep = nodep->modp()->stmtsp(); portnodep; portnodep=portnodep->nextp()) {
|
||||
if (AstPort* portp = portnodep->castPort()) {
|
||||
if (!ports.findIdName(portp->name())) {
|
||||
if (!ports.findIdFlat(portp->name())) {
|
||||
UINFO(9," need PORT "<<portp<<endl);
|
||||
// Create any not already connected
|
||||
AstPin* newp = new AstPin(nodep->fileline(),0,portp->name(),
|
||||
@@ -214,7 +235,7 @@ private:
|
||||
void readModNames() {
|
||||
// Look at all modules, and store pointers to all module names
|
||||
for (AstModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castModule()) {
|
||||
AstNode* foundp = m_mods.findIdName(nodep->name());
|
||||
AstNode* foundp = m_mods.findIdUpward(nodep->name());
|
||||
if (foundp && foundp != nodep) {
|
||||
nodep->v3error("Duplicate declaration of module: "<<nodep->prettyName());
|
||||
foundp->v3error("... Location of original declaration");
|
||||
@@ -229,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);
|
||||
}
|
||||
|
||||
+1
-1
@@ -360,7 +360,7 @@ public:
|
||||
<<((cellVxp->symPrefix()=="") ? "" : cellVxp->symPrefix()+dotname)
|
||||
<<" at "<<cellVxp
|
||||
<<endl);
|
||||
AstNode* nodep = cellVxp->syms().findIdName(cellVxp->symPrefix() + dotname); // Might be NULL
|
||||
AstNode* nodep = cellVxp->syms().findIdFlat(cellVxp->symPrefix() + dotname); // Might be NULL
|
||||
if (!nodep) baddot = dotname;
|
||||
return nodep;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
+61
-21
@@ -303,23 +303,31 @@ void V3Options::unlinkRegexp(const string& dir, const string& regexp) {
|
||||
//######################################################################
|
||||
// Environment
|
||||
|
||||
string V3Options::getenvStr(const char* envvar, const char* defaultValue) {
|
||||
if (const char* envvalue = getenv(envvar)) {
|
||||
string V3Options::getenvStr(const string& envvar, const string& defaultValue) {
|
||||
if (const char* envvalue = getenv(envvar.c_str())) {
|
||||
return envvalue;
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
void V3Options::setenvStr(const string& envvar, const string& value, const string& why) {
|
||||
if (why != "") {
|
||||
UINFO(1,"export "<<envvar<<"="<<value<<" # "<<why<<endl);
|
||||
} else {
|
||||
UINFO(1,"export "<<envvar<<"="<<value<<endl);
|
||||
}
|
||||
setenv(envvar.c_str(),value.c_str(),true);
|
||||
}
|
||||
|
||||
string V3Options::getenvSYSTEMC() {
|
||||
string var = getenvStr("SYSTEMC","");
|
||||
if (var == "" && string(DEFENV_SYSTEMC) != "") {
|
||||
var = DEFENV_SYSTEMC;
|
||||
UINFO(1,"export SYSTEMC="<<var<<" # Hardcoded at build time"<<endl);
|
||||
setenv("SYSTEMC", var.c_str(), false);
|
||||
setenvStr("SYSTEMC", var, "Hardcoded at build time");
|
||||
}
|
||||
// Only correct or check it if we really need the value
|
||||
if ((v3Global.opt.systemPerl() || v3Global.opt.systemC())
|
||||
&& !v3Global.opt.lintOnly()) {
|
||||
if (v3Global.opt.usingSystemCLibs()) {
|
||||
if (var == "") {
|
||||
v3fatal("Need $SYSTEMC in environment\n"
|
||||
"Probably System-C isn't installed, see http://www.systemc.org\n");
|
||||
@@ -327,12 +335,12 @@ string V3Options::getenvSYSTEMC() {
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
string V3Options::getenvSYSTEMC_ARCH() {
|
||||
string var = getenvStr("SYSTEMC_ARCH","");
|
||||
if (var == "" && string(DEFENV_SYSTEMC_ARCH) != "") {
|
||||
var = DEFENV_SYSTEMC_ARCH;
|
||||
UINFO(1,"export SYSTEMC_ARCH="<<var<<" # Hardcoded at build time"<<endl);
|
||||
setenv("SYSTEMC_ARCH", var.c_str(), false);
|
||||
setenvStr("SYSTEMC_ARCH", var, "Hardcoded at build time");
|
||||
}
|
||||
if (var == "") {
|
||||
struct utsname uts;
|
||||
@@ -341,45 +349,73 @@ string V3Options::getenvSYSTEMC_ARCH() {
|
||||
if (wildmatch(sysname.c_str(), "*solaris*")) { var = "gccsparcOS5"; }
|
||||
else if (wildmatch(sysname.c_str(), "*cygwin*")) { var ="cygwin"; }
|
||||
else { var = "linux"; }
|
||||
UINFO(1,"export SYSTEMC_ARCH="<<var<<" # From sysname '"<<sysname<<"'"<<endl);
|
||||
setenv("SYSTEMC_ARCH", var.c_str(), false);
|
||||
setenvStr("SYSTEMC_ARCH", var,"From sysname '"+sysname+"'");
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
string V3Options::getenvSYSTEMPERL() {
|
||||
// Must be careful to set SYSTEMPERL_INCLUDE first else we'd setenv
|
||||
// SYSTEMPERL which would override a DEFENVed SYSTEMPERL_INCLUDE.
|
||||
V3Options::getenvSYSTEMPERL_INCLUDE();
|
||||
return V3Options::getenvSYSTEMPERLGuts();
|
||||
}
|
||||
|
||||
string V3Options::getenvSYSTEMPERLGuts() {
|
||||
// Get SYSTEMPERL when SYSTEMPERL_INCLUDE has already been tested
|
||||
string var = getenvStr("SYSTEMPERL","");
|
||||
if (var == "" && string(DEFENV_SYSTEMPERL) != "") {
|
||||
var = DEFENV_SYSTEMPERL;
|
||||
UINFO(1,"export SYSTEMPERL="<<var<<" # Hardcoded at build time"<<endl);
|
||||
setenv("SYSTEMC_PERL", var.c_str(), false);
|
||||
setenvStr("SYSTEMPERL", var, "Hardcoded at build time");
|
||||
}
|
||||
// Only correct or check it if we really need the value
|
||||
if ((v3Global.opt.systemPerl() || v3Global.opt.trace()) && !v3Global.opt.lintOnly()) {
|
||||
if (v3Global.opt.usingSystemPerlLibs()) {
|
||||
if (var == "") {
|
||||
string testdir = V3Options::getenvW() + "/hw/utils/perltools/SystemC"; // Hack for internal testing
|
||||
if (V3Options::fileStatDir(testdir)) {
|
||||
var = testdir;
|
||||
UINFO(1,"export SYSTEMPERL="<<var<<endl);
|
||||
setenv ("SYSTEMPERL", var.c_str(), false);
|
||||
setenvStr ("SYSTEMPERL", var, "From W");
|
||||
}
|
||||
}
|
||||
// Test for correctness in SYSTEMPERL_INCLUDE
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
string V3Options::getenvSYSTEMPERL_INCLUDE() {
|
||||
string var = getenvStr("SYSTEMPERL_INCLUDE","");
|
||||
if (var == "" && string(DEFENV_SYSTEMPERL_INCLUDE) != "") {
|
||||
// Note if SYSTEMPERL is DEFENVed, then SYSTEMPERL_INCLUDE is also DEFENVed
|
||||
// So we don't need to sweat testing SYSTEMPERL also
|
||||
var = DEFENV_SYSTEMPERL_INCLUDE;
|
||||
setenvStr("SYSTEMPERL_INCLUDE", var, "Hardcoded at build time");
|
||||
}
|
||||
// Only correct or check it if we really need the value
|
||||
if (v3Global.opt.usingSystemPerlLibs()) {
|
||||
if (var == "") {
|
||||
string sp = V3Options::getenvSYSTEMPERLGuts();
|
||||
var = sp+"/src";
|
||||
setenvStr ("SYSTEMPERL_INCLUDE", var, "From $SYSTEMPERL/src");
|
||||
}
|
||||
// We warn about $SYSTEMPERL instead of _INCLUDE since that's more likely
|
||||
// what users will want to set.
|
||||
if (var == "") {
|
||||
v3fatal("Need $SYSTEMPERL in environment for --sp or --trace\n"
|
||||
"Probably System-Perl isn't installed, see http://www.veripool.org/systemperl\n");
|
||||
}
|
||||
if (var != ""
|
||||
&& !V3Options::fileStatNormal(var+"/src/systemperl.h")) {
|
||||
v3fatal("$SYSTEMPERL environment var doesn't seem to point to System-Perl kit\n");
|
||||
&& !V3Options::fileStatNormal(var+"/systemperl.h")) {
|
||||
v3fatal("Neither $SYSTEMPERL nor $SYSTEMPERL_INCLUDE environment vars to point to System-Perl kit: "<<var<<endl);
|
||||
}
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
string V3Options::getenvVERILATOR_ROOT() {
|
||||
string var = getenvStr("VERILATOR_ROOT","");
|
||||
if (var == "" && string(DEFENV_VERILATOR_ROOT) != "") {
|
||||
var = DEFENV_VERILATOR_ROOT;
|
||||
UINFO(1,"export VERILATOR_ROOT="<<var<<" # Hardcoded at build time"<<endl);
|
||||
setenv("VERILATOR_ROOT", var.c_str(), false);
|
||||
setenvStr("VERILATOR_ROOT", var.c_str(), "Hardcoded at build time");
|
||||
}
|
||||
if (var == "") {
|
||||
v3fatal("$VERILATOR_ROOT needs to be in environment\n");
|
||||
@@ -622,7 +658,8 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
else if ( onoff (sw, "-inhibit-sim", flag/*ref*/)){ m_inhibitSim = flag; }
|
||||
else if ( onoff (sw, "-l2name", flag/*ref*/) ) { m_l2Name = flag; }
|
||||
else if ( onoff (sw, "-lint-only", flag/*ref*/) ) { m_lintOnly = flag; }
|
||||
else if ( onoff (sw, "-pins64", flag/*ref*/) ) { m_pins64 = flag; }
|
||||
else if ( !strcmp (sw, "-no-pins64") ) { m_pinsBv = 33; }
|
||||
else if ( !strcmp (sw, "-pins64") ) { m_pinsBv = 65; }
|
||||
else if ( !strcmp (sw, "-private") ) { m_public = false; }
|
||||
else if ( onoff (sw, "-profile-cfuncs", flag/*ref*/) ) { m_profileCFuncs = flag; }
|
||||
else if ( onoff (sw, "-psl", flag/*ref*/) ) { m_psl = flag; }
|
||||
@@ -740,6 +777,9 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
else if ( !strcmp (sw, "-mod-prefix") && (i+1)<argc ) {
|
||||
shift; m_modPrefix = argv[i];
|
||||
}
|
||||
else if ( !strcmp (sw, "-pins-bv") && (i+1)<argc ) {
|
||||
shift; m_pinsBv = atoi(argv[i]);
|
||||
}
|
||||
else if ( !strcmp (sw, "-prefix") && (i+1)<argc ) {
|
||||
shift; m_prefix = argv[i];
|
||||
if (m_modPrefix=="") m_modPrefix = m_prefix;
|
||||
@@ -872,7 +912,7 @@ V3Options::V3Options() {
|
||||
m_makeDepend = true;
|
||||
m_makePhony = false;
|
||||
m_outFormatOk = false;
|
||||
m_pins64 = true;
|
||||
m_pinsBv = 65;
|
||||
m_profileCFuncs = false;
|
||||
m_preprocOnly = false;
|
||||
m_psl = false;
|
||||
|
||||
+8
-3
@@ -104,7 +104,6 @@ class V3Options {
|
||||
bool m_l2Name; // main switch: --l2name
|
||||
bool m_lintOnly; // main switch: --lint-only
|
||||
bool m_outFormatOk; // main switch: --cc, --sc or --sp was specified
|
||||
bool m_pins64; // main switch: --pins64
|
||||
bool m_profileCFuncs;// main switch: --profile-cfuncs
|
||||
bool m_psl; // main switch: --psl
|
||||
bool m_public; // main switch: --public
|
||||
@@ -121,6 +120,7 @@ class V3Options {
|
||||
int m_outputSplit; // main switch: --output-split
|
||||
int m_outputSplitCFuncs;// main switch: --output-split-cfuncs
|
||||
int m_outputSplitCTrace;// main switch: --output-split-ctrace
|
||||
int m_pinsBv; // main switch: --pins-bv
|
||||
int m_traceDepth; // main switch: --trace-depth
|
||||
int m_unrollCount; // main switch: --unroll-count
|
||||
int m_unrollStmts; // main switch: --unroll-stmts
|
||||
@@ -168,7 +168,9 @@ class V3Options {
|
||||
void coverage(bool flag) { m_coverageLine = m_coverageToggle = m_coverageUser = flag; }
|
||||
bool onoff(const char* sw, const char* arg, bool& flag);
|
||||
static bool wildmatchi(const char* s, const char* p);
|
||||
static string getenvStr(const char* envvar, const char* defaultValue);
|
||||
static string getenvStr(const string& envvar, const string& defaultValue);
|
||||
static void setenvStr(const string& envvar, const string& value, const string& why);
|
||||
static string getenvSYSTEMPERLGuts();
|
||||
|
||||
public:
|
||||
// CREATORS
|
||||
@@ -192,6 +194,8 @@ class V3Options {
|
||||
string flags() const { return m_flags; }
|
||||
bool systemC() const { return m_systemC; }
|
||||
bool systemPerl() const { return m_systemPerl; }
|
||||
bool usingSystemCLibs() const { return !lintOnly() && (systemPerl() || systemC()); }
|
||||
bool usingSystemPerlLibs() const { return !lintOnly() && (systemPerl() || trace()); }
|
||||
bool skipIdentical() const { return m_skipIdentical; }
|
||||
bool stats() const { return m_stats; }
|
||||
bool assertOn() const { return m_assert; } // assertOn as __FILE__ may be defined
|
||||
@@ -207,7 +211,6 @@ class V3Options {
|
||||
bool traceDups() const { return m_traceDups; }
|
||||
bool outFormatOk() const { return m_outFormatOk; }
|
||||
bool keepTempFiles() const { return (V3Error::debugDefault()!=0); }
|
||||
bool pins64() const { return m_pins64; }
|
||||
bool profileCFuncs() const { return m_profileCFuncs; }
|
||||
bool psl() const { return m_psl; }
|
||||
bool allPublic() const { return m_public; }
|
||||
@@ -221,6 +224,7 @@ class V3Options {
|
||||
int outputSplit() const { return m_outputSplit; }
|
||||
int outputSplitCFuncs() const { return m_outputSplitCFuncs; }
|
||||
int outputSplitCTrace() const { return m_outputSplitCTrace; }
|
||||
int pinsBv() const { return m_pinsBv; }
|
||||
int traceDepth() const { return m_traceDepth; }
|
||||
int unrollCount() const { return m_unrollCount; }
|
||||
int unrollStmts() const { return m_unrollStmts; }
|
||||
@@ -289,6 +293,7 @@ class V3Options {
|
||||
static string getenvSYSTEMC();
|
||||
static string getenvSYSTEMC_ARCH();
|
||||
static string getenvSYSTEMPERL();
|
||||
static string getenvSYSTEMPERL_INCLUDE();
|
||||
static string getenvVERILATOR_ROOT();
|
||||
static string getenvW() { return getenvStr("W",""); }
|
||||
|
||||
|
||||
+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
|
||||
|
||||
+10
-2
@@ -1,3 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Symbol table
|
||||
//
|
||||
@@ -55,13 +56,20 @@ class V3SymTable : public AstNUser {
|
||||
m_idNameMap.insert(make_pair(name, nodep));
|
||||
}
|
||||
}
|
||||
AstNode* findIdName(const string& name) {
|
||||
AstNode* findIdFlat(const string& name) {
|
||||
// Find identifier without looking upward through symbol hierarchy
|
||||
//UINFO(9, " SymFind "<<this<<" '"<<name<<"' "<<endl);
|
||||
// First, scan this begin/end block or module for the name
|
||||
IdNameMap::iterator iter = m_idNameMap.find(name);
|
||||
if (iter != m_idNameMap.end()) return (iter->second);
|
||||
return NULL;
|
||||
}
|
||||
AstNode* findIdUpward(const string& name) {
|
||||
// Find identifier looking upward through symbol hierarchy
|
||||
// First, scan this begin/end block or module for the name
|
||||
if (AstNode* nodep = findIdFlat(name)) return nodep;
|
||||
// Then scan the upper begin/end block or module for the name
|
||||
if (m_upperp) return m_upperp->findIdName(name);
|
||||
if (m_upperp) return m_upperp->findIdUpward(name);
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
+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();
|
||||
|
||||
@@ -538,6 +538,7 @@ int main(int argc, char** argv, char** env) {
|
||||
V3Options::getenvSYSTEMC();
|
||||
V3Options::getenvSYSTEMC_ARCH();
|
||||
V3Options::getenvSYSTEMPERL();
|
||||
V3Options::getenvSYSTEMPERL_INCLUDE();
|
||||
|
||||
V3Error::abortIfErrors();
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
//**********************************************************************
|
||||
//**** Version and host name
|
||||
|
||||
#define DTVERSION "Verilator 3.701 2009/02/26"
|
||||
#define DTVERSION "Verilator 3.703 2009/05/02"
|
||||
|
||||
//**********************************************************************
|
||||
//**** Functions
|
||||
@@ -73,6 +73,9 @@
|
||||
#ifndef DEFENV_SYSTEMPERL
|
||||
# define DEFENV_SYSTEMPERL ""
|
||||
#endif
|
||||
#ifndef DEFENV_SYSTEMPERL_INCLUDE
|
||||
# define DEFENV_SYSTEMPERL_INCLUDE ""
|
||||
#endif
|
||||
#ifndef DEFENV_VERILATOR_ROOT
|
||||
# define DEFENV_VERILATOR_ROOT ""
|
||||
#endif
|
||||
|
||||
+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,";
|
||||
|
||||
@@ -32,6 +32,7 @@ endif
|
||||
# Needed by tracing routines
|
||||
CPPFLAGS += -DVL_DEBUG=1
|
||||
CPPFLAGS += -DVM_PREFIX=$(VM_PREFIX)
|
||||
CPPFLAGS += $(CPPFLAGS_DRIVER)
|
||||
CPPFLAGS += $(CPPFLAGS_ADD)
|
||||
|
||||
#######################################################################
|
||||
|
||||
@@ -167,7 +167,7 @@ sub parameter {
|
||||
$_Parameter_Next_Level = $param;
|
||||
}
|
||||
else {
|
||||
warn "%Error: Unknown parameter: $param\n";
|
||||
die "%Error: Unknown parameter: $param\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,6 +434,7 @@ sub compile {
|
||||
cmd=>["cd $self->{obj_dir} && ",
|
||||
"make", "-f".getcwd()."/Makefile_obj",
|
||||
"VM_PREFIX=$self->{VM_PREFIX}",
|
||||
"CPPFLAGS_DRIVER=-D".uc($self->{name}),
|
||||
($param{make_main}?"":"MAKE_MAIN=0"),
|
||||
($param{benchmark}?"OPT_FAST=-O2":""),
|
||||
"$self->{VM_PREFIX}", # bypass default rule, as we don't need archive
|
||||
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
v_flags2 => ["--lint-only"],
|
||||
fails=>1,
|
||||
expect=>
|
||||
'%Error: t/t_assert_dup_bad.v:\d+: Duplicate declaration of block: covlabel
|
||||
%Error: t/t_assert_dup_bad.v:\d+: ... Location of original declaration
|
||||
%Error: Exiting due to.*',
|
||||
);
|
||||
|
||||
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, 2007 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
|
||||
input clk;
|
||||
integer cyc = 0;
|
||||
|
||||
covlabel:
|
||||
cover property (@(posedge clk) cyc==5);
|
||||
covlabel: // Error: Duplicate block_identifier
|
||||
cover property (@(posedge clk) cyc==5);
|
||||
|
||||
endmodule
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-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 => [$Self->{v3}?'--assert --sp --coverage-user':''],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
#if ($Self->{nc}) ... # See t_assert_cover.pl for NC version
|
||||
|
||||
# Allow old Perl format dump, or new binary dump
|
||||
# Check that the hierarchy doesn't include __PVT__
|
||||
# Otherwise our coverage reports would look really ugly
|
||||
file_grep ($Self->{coverage_filename}, qr/(TOP\.v\.sub.*.cyc_eq_5)/);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,59 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2007 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
|
||||
input clk;
|
||||
reg toggle;
|
||||
integer cyc; initial cyc=1;
|
||||
|
||||
Test suba (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.toggle (toggle),
|
||||
.cyc (cyc[31:0]));
|
||||
Test subb (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.toggle (toggle),
|
||||
.cyc (cyc[31:0]));
|
||||
Test subc (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.toggle (toggle),
|
||||
.cyc (cyc[31:0]));
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (cyc!=0) begin
|
||||
cyc <= cyc + 1;
|
||||
toggle <= !cyc[0];
|
||||
if (cyc==9) begin
|
||||
end
|
||||
if (cyc==10) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module Test
|
||||
(
|
||||
input clk,
|
||||
input toggle,
|
||||
input [31:0] cyc
|
||||
);
|
||||
|
||||
// Don't flatten out these modules please:
|
||||
// verilator no_inline_module
|
||||
|
||||
// Labeled cover
|
||||
cyc_eq_5: cover property (@(posedge clk) cyc==5) $display("*COVER: Cyc==5");
|
||||
|
||||
endmodule
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 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)
|
||||
|
||||
@@ -9,12 +9,16 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
compile (
|
||||
fails=>1,
|
||||
expect=>
|
||||
'%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Cell has same name as variable: varfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Task/function has same name as variable: varfirst
|
||||
'%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Cell has the same name as variable: varfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: ... Location of original declaration
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Task has the same name as variable: varfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: ... Location of original declaration
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Variable has same name as cell: cellfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Task/function has same name as cell: cellfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Task has the same name as cell: cellfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: ... Location of original declaration
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Variable has same name as task: taskfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Cell has same name as task: taskfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Cell has the same name as task: taskfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: ... Location of original declaration
|
||||
%Error: Exiting due to.*',
|
||||
);
|
||||
|
||||
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/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.
|
||||
|
||||
top_filename("t/t_var_pinsizes.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ["-sp -pins-bv 1 --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
|
||||
make_main => 0,
|
||||
) if $Self->{v3};
|
||||
|
||||
if ($Self->{v3}) {
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ i1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<8>\s> \s+ i8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ i16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<32>\s> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<8>\s> \s+ o8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ o16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<32>\s> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
}
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/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.
|
||||
|
||||
top_filename("t/t_var_pinsizes.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ["-sp -pins-bv 2 --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
|
||||
make_main => 0,
|
||||
) if $Self->{v3};
|
||||
|
||||
if ($Self->{v3}) {
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<8>\s> \s+ i8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ i16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<32>\s> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<8>\s> \s+ o8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ o16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<32>\s> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
}
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -9,24 +9,24 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
top_filename("t/t_var_pinsizes.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['-sp -no-pins64'],
|
||||
verilator_make_gcc => 0,
|
||||
v_flags2 => ["-sp -no-pins64 --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
|
||||
make_main => 0,
|
||||
) if $Self->{v3};
|
||||
|
||||
if ($Self->{v3}) {
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_in<bool> \s+ i1;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_in<uint32_t> \s+ i8;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_in<uint32_t> \s+ i16;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_in<uint32_t> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_out<uint32_t> \s+ o8;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_out<uint32_t> \s+ o16;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_out<uint32_t> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
}
|
||||
|
||||
ok(1);
|
||||
|
||||
@@ -9,24 +9,24 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
top_filename("t/t_var_pinsizes.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['-sp -pins64'],
|
||||
verilator_make_gcc => 0,
|
||||
v_flags2 => ["-sp -pins64 --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
|
||||
make_main => 0,
|
||||
) if $Self->{v3};
|
||||
|
||||
if ($Self->{v3}) {
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_in<bool> \s+ i1;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_in<uint32_t> \s+ i8;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_in<uint32_t> \s+ i16;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_in<uint32_t> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_in<uint64_t> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint64_t> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_out<uint32_t> \s+ o8;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_out<uint32_t> \s+ o16;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_out<uint32_t> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_out<uint64_t> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint64_t> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
}
|
||||
|
||||
ok(1);
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifdef T_VAR_PINS_CC
|
||||
# include "Vt_var_pins_cc.h"
|
||||
#elif defined(T_VAR_PINS_SC1)
|
||||
# include "Vt_var_pins_sc1.h"
|
||||
#elif defined(T_VAR_PINS_SC2)
|
||||
# include "Vt_var_pins_sc2.h"
|
||||
#elif defined(T_VAR_PINS_SC32)
|
||||
# include "Vt_var_pins_sc32.h"
|
||||
#elif defined(T_VAR_PINS_SC64)
|
||||
# include "Vt_var_pins_sc64.h"
|
||||
#else
|
||||
# error "Unknown test"
|
||||
#endif
|
||||
|
||||
VM_PREFIX* tb = NULL;
|
||||
|
||||
double sc_time_stamp() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Verilated::debug(0);
|
||||
tb = new VM_PREFIX("tb");
|
||||
|
||||
cout << "*-* All Finished *-*" << endl;
|
||||
tb->final();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user