Compare commits

...
9 Commits
Author SHA1 Message Date
Wilson Snyder e3f17e7853 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@791 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-20 13:25:03 +00:00
Wilson Snyder 73c897ac69 Fix printf ULL warnings with a cast.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@790 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-20 13:24:18 +00:00
Wilson Snyder a4db880809 Use vluint8/16/64 in source code
git-svn-id: file://localhost/svn/verilator/trunk/verilator@789 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-19 15:27:15 +00:00
Wilson Snyder f9697463cc Have preprocessor strip all DOS returns
git-svn-id: file://localhost/svn/verilator/trunk/verilator@788 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-13 14:38:48 +00:00
Wilson Snyder f283076570 Rename {newline} in lex; no functional change
git-svn-id: file://localhost/svn/verilator/trunk/verilator@787 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-13 13:18:24 +00:00
Wilson Snyder e15228498d Define VL_PRINTF by default, and remove old coverageRequest
git-svn-id: file://localhost/svn/verilator/trunk/verilator@786 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-12 00:55:27 +00:00
Wilson Snyder 53155b3a36 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@783 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-11 20:44:54 +00:00
Wilson Snyder 12ae70ba95 Prep for removing begin under first generate, but doesn't work. Commentary instead
git-svn-id: file://localhost/svn/verilator/trunk/verilator@782 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-11 20:42:47 +00:00
Wilson Snyder 88809587f9 Fix function references under top inlined module.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@781 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-08 16:16:30 +00:00
23 changed files with 240 additions and 143 deletions
+17 -1
View File
@@ -3,7 +3,23 @@ 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.601 09/06/2006
* Verilator 3.610 09/20/2006
*** Verilator now works under DJGPP (Pentium GCC). [John Stroebel]
**** Add default define for VL_PRINTF. [John Stroebel]
**** Removed coverage request variable; see Coverage limitations in docs.
**** Fix DOS carrage returns in multiline defines. [Ralf Karge]
**** Fix printf format warnings on 64-bit linux.
* Verilator 3.602 09/11/2006 Stable
**** Fix function references under top inlined module. [David Hewson]
* Verilator 3.601 09/06/2006 Beta
*** Added --inhibit-sim flag for environments using old __Vm_inhibitSim.
+1
View File
@@ -97,6 +97,7 @@ Performance:
Track recirculation and convert into clock-enables
Clock enables should become new clocking domains for speed
If floped(a) & flopped(b) and no other a&b, then instead flop(a&b).
Sort by output bitselects so can combine more assignments (see DDP example dx_dm signal)
//**********************************************************************
//* Detailed notes on 'todo' features
+45 -15
View File
@@ -248,9 +248,9 @@ Specifies basic block line coverage analysis code should be inserted.
Coverage analysis adds statements at each code flow change point, which are
the branches of IF and CASE statements, a superset of normal Verilog Line
Coverage. At each such branch a C++ macro is called, which SystemPerl uses
to increment an array. At the end of a test, logs/coverage.pl is written
with the data from the array.
Coverage. At each such branch a unique counter is incremented. At the end
of a test, the counters along with the filename and line number
corresponding to each counter are written into logs/coverage.pl.
After running multiple tests, the vcoverage utility (from the SystemPerl
package) is executed. Vcoverage reads the logs/coverage.pl file(s), and
@@ -261,6 +261,10 @@ them, as it is assumed $stop branches contain an error check that should
not occur. A /*verilator coverage_block_off*/ comment will perform a
similar function on any code in that block or below.
Note Verilator may over-count combinatorial (non-clocked) blocks when those
blocks receive signals which have had the UNOPTFLAT warning disabled; for
most accurate results do not disable this warning when using coverage.
For an example, after running 'make test' in the Verilator distribution,
see the test_sp/logs/coverage_source directory. Grep for lines starting
with '%' to see what lines Verilator believes need more coverage.
@@ -398,11 +402,14 @@ enable functional coverage.
=item --public
This is only for debug, and may result in mis-simulation of generated
clocks.
Declares all signals and modules public. This will turn off signal
optimizations as if all signals had a /*verilator public*/ comments. This
will also turn off inlining as if all modules had a /*verilator
public_module*/, unless the module specifically enabled it with /*verilator
inline_module*/.
optimizations as if all signals had a /*verilator public*/ comments and
inlining. This will also turn off inlining as if all modules had a
/*verilator public_module*/, unless the module specifically enabled it with
/*verilator inline_module*/.
=item --sc
@@ -936,9 +943,9 @@ each different output width.
=item $display, $write, $fdisplay, $fwrite
$display format arguments may use C fprintf sizes after the % escape. Per
the Verilog standard, %x prints a number with the natural width, %0x prints
a number with minimum width, however %5x prints 5 digits per the C standard
Format arguments may use C fprintf sizes after the % escape. Per the
Verilog standard, %x prints a number with the natural width, %0x prints a
number with minimum width, however %5x prints 5 digits per the C standard
(it's unspecified in Verilog).
=item $fopen, $fclose, $fdisplay, $fwrite
@@ -1057,7 +1064,7 @@ Re-enable waveform tracing for all future signals that are declared.
Used after a input, output, register, or wire declaration to indicate the
signal should be declared so that C code may read or write the value
of the signal. Set for all signals when using the --public switch.
of the signal.
=item /*verilator public*/ (task/function)
@@ -1116,10 +1123,25 @@ always @* to prevent these issues.)
Verilator supports dotted references to variables, functions and tasks in
different modules. However, references into named blocks and function-local
variables are not supported. References into generate statements and
arrayed instances are possible, but may use different names from the
Verilog standard; arrayed instances are named {cellName}__{instanceNumber},
while for generates, it's genblk{instanceNumber} or genfor{loopCount}.
variables are not supported. References into arrayed and generated
instances work, but still require some work-arounds in the Verilog code:
References into arrayed instances use different names from the Verilog
standard; arrayed instances are named {cellName}__{instanceNumber}. For
example a[2] is instead a__2. Thus you cannot use a parameter or variable
to select the index number; expand it into a case statement manually.
References into generate statements also use different names from the
Verilog standard; the top level generate, any begin statement, and any
place where there is a implied begin statement (under each generate-if or
generate-case) adds a hierarchy level named genblkI<instanceNumber>. And
each generate-for adds genforI<loopCount>. The best bet is to comment out
the references and run with --debug and look in the at the _begin.tree
file, and see the hierarchy by looking at the names of all of the CELLs in
question. Replace __DOT__ with . in your program. For example most cells
under a for loop would be something like
"genblk__DOT__genfor0__DOT__I<cellname>"; so use genblk.genfor0.I<cellname> to
see inside that cell.
=head2 Latches
@@ -1233,6 +1255,11 @@ will give a width warning and wrap around the power-of-2 size. For
non-power-of-2 sizes, it will return a unspecified constant of the
appropriate width.
=item $display, $write, $fdisplay, $fwrite
$display and friends must have a constant format string as the first
argument (as with C's printf), you cannot simply list variables standalone.
=head1 ERRORS
Warnings may be disabled in two ways. First, when the warning is
@@ -1354,6 +1381,9 @@ For significantly better performance, split this into 2 separate signals:
wire [2:1] x_21 = x[1:0];
wire [0:0] x_0 = shift_in;
This warning may also be due to clock enables. To fix these, use the
clock_enable meta comment described above.
=item UNSIGNED
Warns that you are comparing a unsigned value in a way that implies it is
+12 -5
View File
@@ -40,11 +40,11 @@ using namespace std;
//=========================================================================
// Basic types
typedef uint8_t CData; ///< Verilated data, 1-8 bits
typedef uint16_t SData; ///< Verilated data, 9-16 bits
typedef uint32_t IData; ///< Verilated data, 17-32 bits
typedef vluint64_t QData; ///< Verilated data, 33-64 bits
typedef uint32_t WData; ///< Verilated data, >64 bits, as an array
typedef vluint8_t CData; ///< Verilated data, 1-8 bits
typedef vluint16_t SData; ///< Verilated data, 9-16 bits
typedef vluint32_t IData; ///< Verilated data, 17-32 bits
typedef vluint64_t QData; ///< Verilated data, 33-64 bits
typedef vluint32_t WData; ///< Verilated data, >64 bits, as an array
typedef const WData* WDataInP; ///< Array input to a function
typedef WData* WDataOutP; ///< Array output from a function
@@ -115,6 +115,13 @@ public:
#endif
//=========================================================================
// Functions overridable by user defines
#ifndef VL_PRINTF
# define VL_PRINTF printf ///< Print ala printf; may redefine if desired
#endif
//===========================================================================
/// Verilator global static information class
+20 -11
View File
@@ -68,24 +68,33 @@
#ifdef VL_UINTS_DEFINED
#elif defined(__CYGWIN__)
# include <stdint.h>
typedef unsigned char uint8_t; ///< 8-bit basic type
typedef unsigned short int uint16_t; ///< 16-bit basic type
typedef unsigned long uint32_t; ///< 32-bit basic type
typedef unsigned long long vluint64_t; ///< 64-bit basic type
typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward compatibility)
typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility)
typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility)
typedef unsigned char vluint8_t; ///< 8-bit unsigned type
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
typedef long vlsint32_t; ///< 32-bit signed type
typedef unsigned long vluint32_t; ///< 32-bit unsigned type
typedef long long vlsint64_t; ///< 64-bit signed type
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
#elif defined(_WIN32)
typedef unsigned char uint8_t; ///< 8-bit basic type
typedef unsigned short int uint16_t; ///< 16-bit basic type
typedef unsigned int uint32_t; ///< 32-bit basic type
typedef unsigned __int64 vluint64_t; ///< 64-bit basic type
typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward compatibility)
typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility)
typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility)
typedef unsigned char vluint8_t; ///< 8-bit unsigned type
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
typedef int vlsint32_t; ///< 32-bit signed type
typedef unsigned int vluint32_t; ///< 32-bit unsigned type
typedef __int64 vlsint64_t; ///< 64-bit signed type
#else // Linux or compliant Unix flavors
typedef unsigned __int64 vluint64_t; ///< 64-bit unsigned type
#else // Linux or compliant Unix flavors, -m64
# include <stdint.h>
typedef unsigned long long vluint64_t; ///< 64-bit basic type
typedef long vlsint32_t; ///< 32-bit signed type
typedef uint8_t vluint8_t; ///< 32-bit unsigned type
typedef uint16_t vluint16_t; ///< 32-bit unsigned type
typedef int vlsint32_t; ///< 32-bit signed type
typedef uint32_t vluint32_t; ///< 32-bit signed type
typedef long long vlsint64_t; ///< 64-bit signed type
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
#endif
//=========================================================================
+2 -2
View File
@@ -33,8 +33,8 @@
//======================================================================
// Statics
uint64_t AstNode::s_editCntGbl=0;
uint64_t AstNode::s_editCntLast=0;
vluint64_t AstNode::s_editCntGbl=0;
vluint64_t AstNode::s_editCntLast=0;
// To allow for fast clearing of all user pointers, we keep a "timestamp"
// along with each userp, and thus by bumping this count we can make it look
+6 -6
View File
@@ -391,9 +391,9 @@ private:
static int s_cloneCntGbl; // Count of which userp is set
FileLine* m_fileline; // Where it was declared
uint64_t m_editCount; // When it was last edited
static uint64_t s_editCntGbl;// Global edit counter
static uint64_t s_editCntLast;// Global edit counter, last value for printing * near node #s
vluint64_t m_editCount; // When it was last edited
static vluint64_t s_editCntGbl; // Global edit counter
static vluint64_t s_editCntLast;// Global edit counter, last value for printing * near node #s
// Attributes
bool m_signed; // Node is signed
@@ -539,10 +539,10 @@ public:
void user5(int val) { user5p(AstNUser::fromInt(val)); }
static void user5ClearTree() { s_user5CntGbl++; } // Clear userp()'s across the entire tree
uint64_t editCount() const { return m_editCount; }
vluint64_t editCount() const { return m_editCount; }
void editCountInc() { m_editCount = s_editCntGbl++; }
static uint64_t editCountLast() { return s_editCntLast; }
static uint64_t editCountGbl() { return s_editCntGbl; }
static vluint64_t editCountLast() { return s_editCntLast; }
static vluint64_t editCountGbl() { return s_editCntGbl; }
static void editCountSetLast() { s_editCntLast = editCountGbl(); }
// ACCESSORS for specific types
+1 -29
View File
@@ -49,25 +49,6 @@ private:
string m_beginScope; // Name of begin blocks above us
//int debug() { return 9; }
bool nameMatchesGen(const char* namep, string& numr) {
numr = "";
bool needbar = false;
for (const char* cp=namep; *cp; ) {
if (0==strncmp(cp,"genblk",6) || 0==strncmp(cp,"genfor",6)) {
cp += 6;
} else if (isdigit(*cp)) {
if (needbar) { numr += '_'; needbar = false; }
numr += *cp++;
} else if (*cp=='_') {
cp++;
needbar = true;
} else {
return false; // Not exact match
}
}
return true;
}
// VISITORS
virtual void visit(AstModule* nodep, AstNUser*) {
m_modp = nodep;
@@ -84,15 +65,6 @@ private:
UINFO(8," "<<nodep<<endl);
string oldScope = m_beginScope;
{
//string nameNum;
//string oldNum;
//if (nameMatchesGen(oldScope.c_str(), oldNum/*ref*/)
// && nameMatchesGen(nodep->name().c_str(), nameNum/*ref*/)
// && 0) { // Messes up V3Link
// // Need to leave the dot or we mess up later V3LinkDot
// // gen[blk|for]##_gen[blk|for]## -> gen[blk|for]##__DOT__##...
// m_beginScope = oldScope + "__DOT__"+nameNum;
//UINFO(8,"nname "<<m_beginScope<<endl);
// Create data for dotted variable resolution
string dottedname = nodep->name() + "__DOT__"; // So always found
@@ -100,7 +72,7 @@ private:
while ((pos=dottedname.find("__DOT__")) != string::npos) {
string ident = dottedname.substr(0,pos);
dottedname = dottedname.substr(pos+strlen("__DOT__"));
if (m_beginScope=="") m_beginScope = nodep->name();
if (m_beginScope=="") m_beginScope = ident;
else m_beginScope = m_beginScope + "__DOT__"+ident;
// Create CellInline for dotted resolution
AstCellInline* inlinep = new AstCellInline(nodep->fileline(),
+13 -9
View File
@@ -217,8 +217,7 @@ public:
puts(");\n");
}
virtual void visit(AstCoverInc* nodep, AstNUser*) {
puts("if (VL_LIKELY(vlSymsp->__Vm_coverageRequest))");
puts(" ++this->__Vcoverage[");
puts("++this->__Vcoverage[");
puts(cvtToStr(m_coverIds.remap(nodep->declp()))); puts("];\n");
}
virtual void visit(AstCReturn* nodep, AstNUser*) {
@@ -910,7 +909,6 @@ string EmitCStmts::displayFormat(AstNode* widthNodep, string in,
} else {
fmt=in;
}
if (widthNodep->isQuad() && fmtLetter!='c' && fmtLetter!='s' && !reallyString) fmt+="ll";
return fmt;
}
@@ -941,10 +939,20 @@ void EmitCStmts::displayArg(AstDisplay* dispp, AstNode** elistp, string fmt, cha
emitDispState.pushFormat(pfmt);
emitDispState.pushArg(*elistp,func);
} else {
string func;
string nfmt = displayFormat(*elistp, fmt, fmtLetter, true, false);
if ((*elistp)->isQuad() && (fmtLetter=='d')) {
nfmt+="ll";
func="(long long)("; // Must match %ll to avoid warnings
}
if ((*elistp)->isQuad() && (fmtLetter=='u'||fmtLetter=='o'||fmtLetter=='x')) {
nfmt+="ll";
func="(unsigned long long)("; // Must match %ull to avoid warnings
}
string pfmt = "%"+nfmt+fmtLetter;
emitDispState.pushFormat(pfmt);
emitDispState.pushArg(*elistp,"");
emitDispState.pushArg(*elistp,func);
}
// Next parameter
*elistp = (*elistp)->nextp();
@@ -1246,12 +1254,8 @@ void EmitCImp::emitWrapEval(AstModule* modp) {
puts("while (VL_LIKELY(__Vchange)) {\n");
puts( "VL_DEBUG_IF(cout<<\" Clock loop\"<<endl;);\n");
#endif
// Not exactly correct for coverage. w/combo logic interspersed, this is complicated. Punt.
// Perhaps have temp & each _combo_ turn it on or off
if (v3Global.opt.coverage()) puts( "vlSymsp->__Vm_coverageRequest = true;\n");
puts( "vlSymsp->__Vm_activity = true;\n");
puts( "_eval(vlSymsp);\n");
if (v3Global.opt.coverage()) puts( "vlSymsp->__Vm_coverageRequest = false;\n");
#ifndef NEW_ORDERING
puts( "__Vchange = _change_request(vlSymsp);\n");
puts( "if (++__VclockLoop > 100) vl_fatal(__FILE__,__LINE__,__FILE__,\"Verilated model didn't converge\");\n");
@@ -1284,7 +1288,7 @@ void EmitCImp::emitWrapEval(AstModule* modp) {
void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& prefixIfImp) {
// Put out a list of signal declarations
// in order of 0:clocks, 1:uint8, 2:uint16, 4:uint32, 5:uint64, 6:wide, 7:arrays
// in order of 0:clocks, 1:vluint8, 2:vluint16, 4:vluint32, 5:vluint64, 6:wide, 7:arrays
// This aids cache packing and locality
// Largest->smallest reduces the number of pad variables.
// But for now, Smallest->largest makes it more likely a small offset will allow access to the signal.
+2 -7
View File
@@ -124,18 +124,14 @@ void EmitCSyms::emitInt() {
//puts("\n// STATIC STATE\n");
puts("\n// LOCAL STATE\n");
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(uint64_t));
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(vluint64_t));
puts("const char* __Vm_namep;\n"); // Must be before subcells, as constructor order needed before _vlCoverInsert.
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
puts("bool\t__Vm_activity;\t\t///< Used by trace routines to determine change occurred\n");
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
puts("bool\t__Vm_didInit;\n");
if (v3Global.opt.coverage()) {
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
puts("bool __Vm_coverageRequest;\n");
}
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(uint64_t));
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(vluint64_t));
puts("\n// SUBCELL STATE\n");
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
AstScope* scopep = it->first; AstModule* modp = it->second;
@@ -184,7 +180,6 @@ void EmitCSyms::emitImp() {
puts("\t: __Vm_namep(namep)\n"); // No leak, as we get destroyed when the top is destroyed
puts("\t, __Vm_activity(false)\n");
puts("\t, __Vm_didInit(false)\n");
if (v3Global.opt.coverage()) puts("\t, __Vm_coverageRequest(false)\n");
puts("\t// Setup submodule names\n");
char comma=',';
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
+1 -1
View File
@@ -64,7 +64,7 @@ class GraphNfaToDfa : GraphAlg {
private:
// TYPES
typedef deque<DfaVertex*> DfaStates;
typedef multimap<uint64_t,DfaVertex*> HashMap;
typedef multimap<vluint64_t,DfaVertex*> HashMap;
// MEMBERS
uint32_t m_step; // Processing step, so we can avoid clearUser all the time
+5 -2
View File
@@ -546,7 +546,8 @@ private:
string baddot;
LinkDotBaseVertex* dotVxp = m_cellVxp; // Start search at current scope
if (nodep->inlinedDots()!="") { // Correct for current scope
dotVxp = m_statep->findDotted(dotVxp, nodep->inlinedDots(), baddot);
string inl = AstNode::prettyName(nodep->inlinedDots());
dotVxp = m_statep->findDotted(dotVxp, inl, baddot);
if (!dotVxp) nodep->v3fatalSrc("Couldn't resolve inlined scope '"<<baddot<<"' in: "<<nodep->inlinedDots());
}
dotVxp = m_statep->findDotted(dotVxp, nodep->dotted(), baddot); // Maybe NULL
@@ -589,7 +590,9 @@ private:
string baddot;
LinkDotBaseVertex* dotVxp = m_cellVxp; // Start search at current scope
if (nodep->inlinedDots()!="") { // Correct for current scope
dotVxp = m_statep->findDotted(dotVxp, nodep->inlinedDots(), baddot);
string inl = AstNode::prettyName(nodep->inlinedDots());
UINFO(8,"\t\tInlined "<<inl<<endl);
dotVxp = m_statep->findDotted(dotVxp, inl, baddot);
if (!dotVxp) nodep->v3fatalSrc("Couldn't resolve inlined scope '"<<baddot<<"' in: "<<nodep->inlinedDots());
}
dotVxp = m_statep->findDotted(dotVxp, nodep->dotted(), baddot); // Maybe NULL
+4 -4
View File
@@ -62,7 +62,7 @@ private:
// "this" must be a element inside of *basep
// Use that to determine a structure offset, then apply to the new base
// to get our new pointer information
return (V3ListEnt*) ( ((uint8_t*)newbasep) + offset);
return (V3ListEnt*) ( ((vluint8_t*)newbasep) + offset);
}
public:
V3ListEnt()
@@ -78,7 +78,7 @@ public:
// METHODS
void pushBack (V3List<T>& listr, T newp) {
// "this" must be a element inside of *newp
uint32_t offset = (uint8_t*)(this) - (uint8_t*)(newp);
uint32_t offset = (vluint8_t*)(this) - (vluint8_t*)(newp);
m_nextp = NULL;
if (!listr.m_headp) listr.m_headp = newp;
m_prevp = listr.m_tailp;
@@ -87,7 +87,7 @@ public:
}
void pushFront (V3List<T>& listr, T newp) {
// "this" must be a element inside of *newp
uint32_t offset = (uint8_t*)(this) - (uint8_t*)(newp);
uint32_t offset = (vluint8_t*)(this) - (vluint8_t*)(newp);
m_nextp = listr.m_headp;
if (m_nextp) baseToListEnt(m_nextp,offset)->m_prevp = newp;
listr.m_headp = newp;
@@ -97,7 +97,7 @@ public:
// Unlink from side
void unlink (V3List<T>& listr, T oldp) {
// "this" must be a element inside of *oldp
uint32_t offset = (uint8_t*)(this) - (uint8_t*)(oldp);
uint32_t offset = (vluint8_t*)(this) - (vluint8_t*)(oldp);
if (m_nextp) baseToListEnt(m_nextp,offset)->m_prevp = m_prevp;
else listr.m_tailp = m_prevp;
if (m_prevp) baseToListEnt(m_prevp,offset)->m_nextp = m_nextp;
+7 -3
View File
@@ -127,10 +127,14 @@ private:
nodep->iterateChildren(*this);
// After expanding the generate, all statements under it can be moved
// up, and the generate block deleted as it's not relevant
AstNode* stmtsp = nodep->stmtsp()->unlinkFrBackWithNext();
nodep->replaceWith(stmtsp);
if (AstNode* stmtsp = nodep->stmtsp()) {
stmtsp->unlinkFrBackWithNext();
nodep->replaceWith(stmtsp);
if (debug()>=9) stmtsp->dumpTree(cout,"-genout: ");
} else {
nodep->unlinkFrBack();
}
nodep->deleteTree(); nodep=NULL;
if (debug()>=9) stmtsp->dumpTree(cout,"-genout: ");
}
virtual void visit(AstGenIf* nodep, AstNUser*) {
V3Width::widthParams(nodep); // Param typed widthing will NOT recurse the body
+24 -24
View File
@@ -58,8 +58,9 @@ static void pslMoreNeeded(bool flag) { V3PreLex::s_currentLexp->m_pslMoreNeeded
%x ARGMODE
%x INCMODE
ws [ \t\r\f]
newline [\n]
ws [ \t\f\r]
wsn [ \t\f]
crnl [\r]*[\n]
quote [\"]
backslash [\\]
symb [a-zA-Z_][a-zA-Z0-9_$]*
@@ -68,7 +69,7 @@ psl [p]sl
/**************************************************************/
%%
<INITIAL>^{ws}*"`line"{ws}+.*{newline} { V3PreLex::s_currentLexp->lineDirective(yytext); }
<INITIAL>^{ws}*"`line"{ws}+.*{crnl} { V3PreLex::s_currentLexp->lineDirective(yytext); }
/* Special directives we recognise */
<INITIAL>"`include" { return(VP_INCLUDE); }
@@ -95,7 +96,7 @@ psl [p]sl
/* Pass-through strings */
<INITIAL,PSLMULM,PSLONEM>{quote} { yy_push_state(STRMODE); yymore(); }
<STRMODE><<EOF>> { linenoInc(); yyerror("EOF in unterminated string"); yyleng=0; yyterminate(); }
<STRMODE>{newline} { linenoInc(); yyerror("Unterminated string"); BEGIN(INITIAL); }
<STRMODE>{crnl} { linenoInc(); yyerror("Unterminated string"); BEGIN(INITIAL); }
<STRMODE>[^\"\\] { yymore(); }
<STRMODE>{backslash}. { yymore(); }
<STRMODE>{quote} { yy_pop_state();
@@ -104,28 +105,26 @@ psl [p]sl
/* Pass-through include <> filenames */
<INCMODE><<EOF>> { linenoInc(); yyerror("EOF in unterminated include filename"); yyleng=0; yyterminate(); }
<INCMODE>{newline} { linenoInc(); yyerror("Unterminated include filename"); BEGIN(INITIAL); }
<INCMODE>{crnl} { linenoInc(); yyerror("Unterminated include filename"); BEGIN(INITIAL); }
<INCMODE>[^\>\\] { yymore(); }
<INCMODE>{backslash}. { yymore(); }
<INCMODE>[\>] { yy_pop_state(); return (VP_STRING); }
/* Reading definition */
<DEFMODE>"/*" { yy_push_state(CMTMODE); yymore(); }
<DEFMODE>"//"[^\n]* { return (VP_COMMENT);}
<DEFMODE>"//"[^\n\r]* { return (VP_COMMENT);}
<DEFMODE><<EOF>> { linenoInc(); yyerror("EOF (missing return?) in define value"); yyleng=0; yyterminate(); }
<DEFMODE>{newline} { linenoInc();
yy_pop_state();
return (VP_DEFVALUE); } /* Note contains a return */
<DEFMODE>[^\/\*\n\m\\]+ |
<DEFMODE>[\\][^\n] |
<DEFMODE>{crnl} { linenoInc(); yy_pop_state(); yytext="\n"; yyleng=1; return (VP_DEFVALUE); }
<DEFMODE>[\\]{crnl} { linenoInc(); appendDefValue("\n",1); } /* Include return so can maintain output line count */
<DEFMODE>[^\/\*\n\r\\]+ |
<DEFMODE>[\\][^\n\r] |
<DEFMODE>. { appendDefValue(yytext,yyleng); }
<DEFMODE>[\\]\n { linenoInc(); appendDefValue("\n",1); }
/* Define arguments */
<ARGMODE>"/*" { yy_push_state(CMTMODE); yymore(); }
<ARGMODE>"//"[^\n]* { return (VP_COMMENT);}
<ARGMODE>"//"[^\n\r]* { return (VP_COMMENT);}
<ARGMODE><<EOF>> { yyerror("EOF in define argument list\n"); yyleng = 0; yyterminate(); }
<ARGMODE>{newline} { linenoInc(); yytext="\n"; yyleng=1; return(VP_WHITE); }
<ARGMODE>{crnl} { linenoInc(); yytext="\n"; yyleng=1; return(VP_WHITE); }
<ARGMODE>{quote} { yy_push_state(STRMODE); yymore(); }
<ARGMODE>[(] { V3PreLex::s_currentLexp->m_parenLevel++; appendDefValue(yytext,yyleng); }
<ARGMODE>[,)] { if (V3PreLex::s_currentLexp->m_parenLevel>1) {
@@ -134,26 +133,26 @@ psl [p]sl
} else {
unput(yytext[0]); yy_pop_state(); return (VP_DEFARG);
}}
<ARGMODE>[^\/\*\n\m\\(,)\"]+ |
<ARGMODE>[^\/\*\n\r\\(,)\"]+ |
<ARGMODE>. { appendDefValue(yytext,yyleng); }
/* One line comments. */
<INITIAL>"//"{ws}*{psl} { if (optPsl()) { pslMoreNeeded(true); yy_push_state(PSLONEM); return(VP_PSL); }
else { yy_push_state(CMTONEM); yymore(); } }
<INITIAL>"//"{newline} { linenoInc(); yytext="\n"; yyleng=1; return (VP_WHITE); }
<INITIAL>"//"{ws}*{crnl} { linenoInc(); yytext="\n"; yyleng=1; return (VP_WHITE); }
<INITIAL>"//" { if (pslMoreNeeded()) { pslMoreNeeded(true); yy_push_state(PSLONEM); return(VP_PSL); }
else { yy_push_state(CMTONEM); yymore(); } }
<CMTONEM>[^\n]* { yy_pop_state(); return (VP_COMMENT); }
<CMTONEM>[^\n\r]* { yy_pop_state(); return (VP_COMMENT); }
/* Psl oneline comments */
<PSLONEM>[{(] { pslParenLevelInc(); return (VP_TEXT); }
<PSLONEM>[})] { pslParenLevelDec(); return (VP_TEXT); }
<PSLONEM>[;] { if (!pslParenLevel()) {BEGIN PSLONEE; pslMoreNeeded(false);} return (VP_TEXT); }
<PSLONEM><<EOF>> { yyerror("EOF in '/* ... */' psl comment\n"); yyleng=0; yyterminate(); }
<PSLONEM>{newline} { linenoInc(); yy_pop_state(); return(VP_WHITE); }
<PSLONEM>{crnl} { linenoInc(); yy_pop_state(); yytext="\n"; yyleng=1; return(VP_WHITE); }
/* Completed psl oneline comments */
<PSLONEE>{newline} { linenoInc(); yy_pop_state(); return(VP_WHITE); }
<PSLONEE>{crnl} { linenoInc(); yy_pop_state(); yytext="\n"; yyleng=1; return(VP_WHITE); }
<PSLONEE>{ws}+ { yymore(); }
<PSLONEE>. { yyerror("Unexpected text following psl assertion\n"); }
@@ -163,24 +162,25 @@ psl [p]sl
<CMTBEGM>{psl} { yyleng -= 3; BEGIN PSLMUL1; return (VP_COMMENT); }
<CMTBEGM>{ws}+ { yymore(); }
<CMTBEGM,CMTMODE>"*/" { yy_pop_state(); return(VP_COMMENT); }
<CMTBEGM,CMTMODE>{newline} { linenoInc(); yymore(); }
<CMTBEGM,CMTMODE>{crnl} { linenoInc(); yymore(); }
<CMTBEGM,CMTMODE><<EOF>> { yyerror("EOF in '/* ... */' block comment\n"); yyleng=0; yyterminate(); }
<CMTBEGM>. { BEGIN CMTMODE; yymore(); } /* Non 'psl' beginning in comment */
<CMTMODE>. { yymore(); }
/* Psl C-style comments. */
<PSLMUL1>.|{newline} { yyless(0); BEGIN PSLMULM; return(VP_PSL); }
<PSLMUL1>.|{crnl} { yyless(0); BEGIN PSLMULM; return(VP_PSL); }
<PSLMULM>"*/" { yy_pop_state(); return(VP_COMMENT); }
<PSLMULM>"//"[^\n]* { return (VP_COMMENT); } /* Comments inside block comments get literal inclusion (later removal) */
<PSLMULM>"//"[^\n\r]* { return (VP_COMMENT); } /* Comments inside block comments get literal inclusion (later removal) */
<PSLMULM><<EOF>> { yyerror("EOF in '/* ... */' psl comment\n"); yyleng=0; yyterminate(); }
/* Define calls */
<INITIAL,PSLMULM,PSLONEM>"`"{symb} { return (VP_DEFREF); }
/* Generics */
<INITIAL,PSLMULM>{newline} { linenoInc(); return(VP_WHITE); }
<INITIAL,PSLMULM>{crnl} { linenoInc(); yytext="\n"; yyleng=1; return(VP_WHITE); }
<INITIAL,PSLMULM,PSLONEM>{symb} { return (VP_SYMBOL); }
<INITIAL,PSLMULM,PSLONEM>{ws}+ { return (VP_WHITE); }
<INITIAL,PSLMULM,PSLONEM>[\r] { }
<INITIAL,PSLMULM,PSLONEM>{wsn}+ { return (VP_WHITE); }
<INITIAL,PSLMULM,PSLONEM>. { return (VP_TEXT); }
%%
+10 -8
View File
@@ -537,10 +537,12 @@ int V3PreProcImp::getRawToken() {
int tok = yylex();
if (debug()>4) {
char buf[10000]; strncpy(buf, yytext, yyleng); buf[yyleng] = '\0';
for (char* cp=buf; *cp; cp++) if (*cp=='\n') *cp='$';
string buf = string (yytext, yyleng);
string::size_type pos;
while ((pos=buf.find("\n")) != string::npos) { buf.replace(pos, 1, "\\n"); }
while ((pos=buf.find("\r")) != string::npos) { buf.replace(pos, 1, "\\r"); }
fprintf (stderr, "%d: RAW %d %d: %-10s: %s\n",
fileline()->lineno(), m_off, m_state, tokenName(tok), buf);
fileline()->lineno(), m_off, m_state, tokenName(tok), buf.c_str());
}
// On EOF, try to pop to upper level includes, as needed.
@@ -867,12 +869,12 @@ string V3PreProcImp::getline() {
while (NULL==(rtnp=strchr(m_lineChars.c_str(),'\n'))) {
int tok = getToken();
if (debug()>4) {
char buf[100000];
strncpy(buf, yytext, yyleng);
buf[yyleng] = '\0';
for (char* cp=buf; *cp; cp++) if (*cp=='\n') *cp='$';
string buf = string (yytext, yyleng);
string::size_type pos;
while ((pos=buf.find("\n")) != string::npos) { buf.replace(pos, 1, "\\n"); }
while ((pos=buf.find("\r")) != string::npos) { buf.replace(pos, 1, "\\r"); }
fprintf (stderr,"%d: GETFETC: %-10s: %s\n",
fileline()->lineno(), tokenName(tok), buf);
fileline()->lineno(), tokenName(tok), buf.c_str());
}
if (tok==VP_EOF) {
// Add a final newline, in case the user forgot the final \n.
+1 -1
View File
@@ -36,7 +36,7 @@ public:
~V3Double0() {}
// Implicit conversion operators:
inline V3Double0 (const uint64_t v) : m_d(v) { };
inline V3Double0 (const vluint64_t v) : m_d(v) { };
inline operator const double () const { return m_d; };
// Explicit operators:
+1 -1
View File
@@ -24,7 +24,7 @@
//**********************************************************************
//**** Version and host name
#define DTVERSION "Verilator 3.601 09/06/2006"
#define DTVERSION "Verilator 3.610 09/20/2006"
//**********************************************************************
//**** Functions
+3 -3
View File
@@ -222,7 +222,7 @@ class AstSenTree;
%type<nodep> v2kPort ioDecl varDecl
%type<nodep> modParDecl modParList modParE
%type<nodep> modItem modItemList modItemListOrNone modOrGenItem
%type<nodep> genItem genItemList genItemBegin genItemBlock genItemsBlock genCaseList
%type<nodep> genItem genItemList genItemBegin genItemBlock genTopBlock genCaseList
%type<nodep> dterm
%type<varp> onesig sigId sigIdRange paramId sigList regsig regsigList regSigId
%type<varp> netSig netSigList
@@ -399,7 +399,7 @@ modItemList: modItem { $$ = $1; }
;
modItem: modOrGenItem { $$ = $1; }
| yGENERATE genItemsBlock yENDGENERATE { $$ = new AstGenerate($1, $2); }
| yGENERATE genTopBlock yENDGENERATE { $$ = new AstGenerate($1, $2); }
| ySCHDR { $$ = new AstScHdr(CRELINE(),*$1); }
| ySCINT { $$ = new AstScInt(CRELINE(),*$1); }
| ySCIMP { $$ = new AstScImp(CRELINE(),*$1); }
@@ -437,7 +437,7 @@ genItemBlock: genItem { $$ = new AstBegin(CRELINE(),"genblk",$1); }
| genItemBegin { $$ = $1; }
;
genItemsBlock: genItemList { $$ = new AstBegin(CRELINE(),"genblk",$1); }
genTopBlock: genItemList { $$ = new AstBegin(CRELINE(),"genblk",$1); }
| genItemBegin { $$ = $1; }
;
+18 -9
View File
@@ -253,7 +253,7 @@ sub read {
sub write_status {
my $self = shift;
my $filename = $self->{status_filename};
my $fh = IO::File->new($filename,"w") or die "%Error: $! $filename,";
my $fh = IO::File->new(">$filename") or die "%Error: $! $filename,";
print $fh Dumper($self);
print $fh "1;";
$fh->close();
@@ -373,7 +373,7 @@ sub execute {
my %param = (%{$self}, @_); # Default arguments are from $self
$self->oprint("Run\n");
if ($param{vcs}) {
#my $fh = IO::File->new("simv.key","w") or die "%Error: $! simv.key,";
#my $fh = IO::File->new(">simv.key") or die "%Error: $! simv.key,";
#$fh->print("quit\n"); $fh->close;
$self->_run(logfile=>"obj_dir/".$self->{name}."_simv.log",
cmd=>["./simv",],
@@ -462,7 +462,7 @@ sub _run {
sleep 1 if ($try!=7);
my $moretry = $try!=0;
my $fh = IO::File->new($param{logfile},"r");
my $fh = IO::File->new("<$param{logfile}");
next if !$fh && $moretry;
local $/; undef $/;
my $wholefile = <$fh>;
@@ -508,7 +508,7 @@ sub _make_main {
$self->_read_inputs();
my $filename = "obj_dir/$self->{VM_PREFIX}__main.cpp";
my $fh = IO::File->new($filename,"w") or die "%Error: $! $filename,";
my $fh = IO::File->new(">$filename") or die "%Error: $! $filename,";
my $VM_PREFIX = $self->{VM_PREFIX};
print $fh "#include \"$VM_PREFIX.h\"\n";
@@ -587,7 +587,7 @@ sub _make_top {
$self->_read_inputs();
my $fh = IO::File->new($self->{top_shell_filename},"w") or die "%Error: $! $self->{top_shell_filename},";
my $fh = IO::File->new(">$self->{top_shell_filename}") or die "%Error: $! $self->{top_shell_filename},";
print $fh "module top;\n";
foreach my $inp (sort (keys %{$self->{inputs}})) {
print $fh " reg ${inp};\n";
@@ -640,7 +640,7 @@ sub _read_inputs {
my $self = shift;
my $filename = $self->{top_filename};
$filename = "t/$filename" if !-r $filename;
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename,";
while (defined(my $line = $fh->getline)) {
if ($line =~ /^\s*input\s*(\S+)\s*(\/[^\/]+\/|)\s*;/) {
$self->{inputs}{$1} = $1;
@@ -673,8 +673,8 @@ sub verilator_version {
sub files_identical {
my $fn1 = shift;
my $fn2 = shift;
my $f1 = IO::File->new ($fn1) or die "%Error: $! $fn1,";
my $f2 = IO::File->new ($fn2) or die "%Error: $! $fn2,";
my $f1 = IO::File->new ("<$fn1") or die "%Error: $! $fn1,";
my $f2 = IO::File->new ("<$fn2") or die "%Error: $! $fn2,";
my @l1 = $f1->getlines();
my @l2 = $f2->getlines();
my $nl = $#l1; $nl = $#l2 if ($#l2 > $nl);
@@ -720,7 +720,7 @@ sub file_contents {
my $filename = shift;
if (!$_File_Contents_Cache{$filename}) {
my $fh = IO::File->new($filename,"r");
my $fh = IO::File->new("<$filename");
if (!$fh) {
$_File_Contents_Cache{$filename} = "_Already_Errored_";
$self->error("File_grep file not found: ".$filename."\n");
@@ -735,6 +735,15 @@ sub file_contents {
return $_File_Contents_Cache{$filename};
}
sub write_wholefile {
my $self = (ref $_[0]? shift : $Last_Self);
my $filename = shift;
my $contents = shift;
my $fh = IO::File->new(">$filename") or die "%Error: $! writing $filename,";
print $fh $contents;
$fh->close;
}
#######################################################################
#######################################################################
#######################################################################
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id$
# 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 (
);
# No execute
ok(1);
1;
+3 -2
View File
@@ -7,6 +7,7 @@ if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
$golden_out ||= "t/$Last_Self->{name}.out";
my $stdout_filename = "obj_dir/$Last_Self->{name}__test.vpp";
if (!$Last_Self->{v3}) {
@@ -17,8 +18,8 @@ if (!$Last_Self->{v3}) {
verilator_make_gcc=>0,
stdout_filename => $stdout_filename,
);
ok(preproc_check("t/$Last_Self->{name}.v", $stdout_filename)
&& files_identical($stdout_filename, "t/$Last_Self->{name}.out"));
ok(preproc_check($Last_Self->{top_filename}, $stdout_filename)
&& files_identical($stdout_filename, $golden_out));
}
sub preproc_check {
+30
View File
@@ -0,0 +1,30 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id$
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2006-2006 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("obj_dir/$Last_Self->{name}.v");
# Rather then having to maintain a new .v and .out, simply add returns
# to all lines of the existing t_preproc test.
$golden_out ||= "obj_dir/$Last_Self->{name}.out";
{
my $wholefile = file_contents("t/t_preproc.v");
$wholefile =~ s/\n/\r\n/og;
write_wholefile("obj_dir/$Last_Self->{name}.v", $wholefile);
}
{
my $wholefile = file_contents("t/t_preproc.out");
$wholefile =~ s!t/t_preproc.v!obj_dir/t_preproc_dos.v!og; # Fix `line's
write_wholefile($golden_out, $wholefile);
}
require 't/t_preproc.pl';
1;