Compare commits

...
14 Commits
43 changed files with 390 additions and 45 deletions
+16
View File
@@ -3,6 +3,20 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. [by ...]
indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.681 2008/11/12
*** Add SystemVerilog unique and priority case.
**** Include Verilog file's directory name in coverage reports.
**** Fix 'for' under 'generate-for' causing error; bug38. [Rafael Shirakawa]
**** Fix coverage hierarchy being backwards with inlining. [Vasu Arasanipalai]
**** Fix GCC 4.3 compile error; bug35. [Lane Brooks]
**** Fix MSVC compile error; bug42. [John Stroebel]
* Verilator 3.680 2008/10/08
** Support negative bit indexes. [Stephane Laurent]
@@ -11,6 +25,8 @@ indicates the contributor was also the author of the fix; Thanks!
*** Suppress width warnings between constant strings and wider vectors.
[Rodney Sinclair]
**** Ignore SystemVerilog timeunit and timeprecision.
**** Expand environment variables in -f input files. [Lawrence Butcher]
**** Report error if port declaration is missing; bug32. [Guy-Armand Kamendje]
+1 -1
View File
@@ -111,7 +111,7 @@ DISTFILES_INC = $(INFOS) .gitignore COPYING *.in *.ac \
include/.*ignore \
.*attributes */.*attributes */*/.*attributes \
src/.*ignore src/*.in src/*.cpp src/*.[chly] src/astgen src/bisonpre src/*fix \
src/*.pl \
src/*.pl src/*.pod \
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
test_*/*.pl test_*/*.v test_*/*.vc test_*/vlint \
test_verilated/vgen*.pl \
+33 -4
View File
@@ -1038,7 +1038,8 @@ including function call-like preprocessor defines.
Verilator supports ==? and !=? operators, $bits, $countones, $error,
$fatal, $info, $isunknown, $onehot, $onehot0, $warning, always_comb,
always_ff, always_latch, do-while, and final.
always_ff, always_latch, do-while, final, priority case/if, and unique
case/if.
It also supports .name and .* interconnection.
@@ -1084,6 +1085,10 @@ formally prove the directive to be true, or failing that, will insert the
appropriate code to detect failing cases at runtime and print an "Assertion
failed" error message.
Verilator likewise also asserts any "unique" or "priority" SystemVerilog
keywords on case statements. However, "unique if" and "priority if" are
currently simply ignored.
=head1 LANGUAGE EXTENSIONS
The following additional constructs are the extensions Verilator supports
@@ -1545,10 +1550,19 @@ while, wire, xnor, xor
Generally supported.
=item priority if, unique if
Priority and unique if's are treated as normal ifs and not asserted to be
full nor unique.
=item specify specparam
All specify blocks and timing checks are ignored.
=item timeunit, timeprecision
All timing control statements are ignored.
=item uwire
Verilator does not perform warning checking on uwires, it treats the uwire
@@ -2020,9 +2034,9 @@ Visual C++ Version 7 or newer, but this is not tested by the author.
=item Can you provide binaries?
Verilator is available as a RPM for SuSE and perhaps other systems; this is
done by porters and may slightly lag the primary distribution. If there
isn't a binary build for your distribution, how about you set one up?
Verilator is available as a RPM for SuSE, Redhat and perhaps other systems;
this is done by porters and may slightly lag the primary distribution. If
there isn't a binary build for your distribution, how about you set one up?
Please contact the authors for assistance.
Note people sometimes request binaries when they are having problems with
@@ -2097,6 +2111,21 @@ Verilator makes standard VCD (Value Change Dump) files. They are viewable
with the public domain Dinotrace or GtkWave programs, or any of the many
commercial offerings.
=item How do I reduce the size of large waveform (trace) files?
First, instead of calling SpTraceVcdCFile->open at the beginning of time,
delay calling it until the time stamp where you want to tracing to begin.
Likewise you can also call SpTraceVcdCFile->open before the end of time
(perhaps a short period after you detect a verification error.)
Next, add /*verilator tracing_off*/ to any very low level modules you never
want to trace (such as perhaps library cells). Finally, use the
--trace-depth option to limit the depth of tracing, for example
--trace-depth 1 to see only the top level signals.
Also be sure you write your trace files to a local disk, instead of to a
network disk. Network disks are generally far slower.
=item How do I do coverage analysis?
Verilator supports both block (line) coverage and user inserted functional
+5 -1
View File
@@ -539,7 +539,11 @@ IData VL_FGETS_IXQ(int obits, void* destp, QData fpq) {
// any read data. This means we can't know in what location the first
// character will finally live, so we need to copy. Yuk.
IData bytes = VL_BYTES_I(obits);
char buffer[bytes];
char buffer[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
// V3Emit has static check that bytes < VL_TO_STRING_MAX_WORDS, but be safe
if (VL_UNLIKELY(bytes > VL_TO_STRING_MAX_WORDS*VL_WORDSIZE)) {
vl_fatal(__FILE__,__LINE__,"","Internal: fgets buffer overrun");
}
// We don't use fgets, as we must read \0s.
IData got = 0;
+2 -2
View File
@@ -86,10 +86,10 @@ 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) && !defined(__MINGW32__)
#elif defined(_WIN32) && defined(_MSC_VER)
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 int 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
+60
View File
@@ -0,0 +1,60 @@
=pod
=head1 NAME
Verilator Source Code Notes
=head1 INTRODUCTION
See also the Verilator internals presentation at http://www.veripool.org.
=head1 VISITOR FUNCTIONS
=head2 Passing Variables
There's three ways data is passed between visitor functions.
1. A visitor-class member variable. This is generally for passing "parent"
information down to children. m_modp is a common example. It's set to
NULL in the constructor, where that node (AstModule visitor) sets it, then
the children are iterated, then it's cleared. Children under an AstModule
will see it set, while nodes elsewhere will see it clear. If there can be
nested items (for example an AstFor under an AstFor) the variable needs to
be save-set-restored in the AstFor visitor, otherwise exiting the lower for
will loose the upper for's setting.
2. User() attributes. Each node has 4 ->user() number or ->userp() pointer
utility values (a common technique lifted from graph traversal packages).
A visitor first clears the one it wants to use by calling
AstNode::user#ClearTree(), then it can mark any node's user() with whatever
data it wants. Readers just call nodep->user(), but may need to cast
appropriately, so you'll often see nodep->userp()->castSOMETYPE(). At the
top of each visitor are comments describing how the user() stuff applies to
that visitor class. For example:
// NODE STATE
// Cleared entire netlist
// AstModule::userp() // bool. True to inline this module
This says that at the AstNetlist userClearTree() is called. Each
AstModule's is user() is used to indicate if we're going to inline it.
These comments are important to make sure a user#() on a given AstNode type
is never being used for two different purposes.
Note that calling user#ClearTree is fast, it doesn't walk the tree, so it's
ok to call fairly often. For example, it's commonly called on every
module.
3. Parameters can be passed between the visitors in close to the "normal"
function caller to callee way. This is the second "vup" parameter that is
ignored on most of the visitor functions. V3Width does this, but it proved
more messy than the above and is deprecated. (V3Width was nearly the first
module written. Someday this scheme may be removed, as it slows the
program down to have to pass vup everywhere.)
=head1 DISTRIBUTION
Copyright 2008-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.
+1 -1
View File
@@ -115,7 +115,7 @@ private:
} else {
// V3Coverage assigned us a bucket to increment.
AstCoverInc* covincp = snodep->coverincp()->castCoverInc();
if (!covincp) snodep->v3fatalSrc("Missing coverage in PSL");
if (!covincp) snodep->v3fatalSrc("Missing AstCoverInc under assertion");
covincp->unlinkFrBack();
if (message!="") covincp->declp()->comment(message);
bodysp = covincp;
+5 -1
View File
@@ -31,7 +31,6 @@
#include <cstdio>
#include <cstdarg>
#include <unistd.h>
#include <cstring>
#include <algorithm>
#include <vector>
@@ -143,6 +142,11 @@ private:
}
nodep->iterateChildren(*this);
}
virtual void visit(AstCoverDecl* nodep, AstNUser*) {
// Don't need to fix path in coverage statements, they're not under
// any BEGINs, but V3Coverage adds them all under the module itself.
nodep->iterateChildren(*this);
}
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
+1
View File
@@ -155,6 +155,7 @@ private:
virtual void visit(AstModule* nodep, AstNUser*) {
m_modp = nodep;
nodep->iterateChildren(*this);
m_modp = NULL;
}
virtual void visit(AstNodeUniop* nodep, AstNUser*) {
nodep->iterateChildren(*this);
+1
View File
@@ -245,6 +245,7 @@ private:
m_modp = nodep;
m_stableNum = 0;
nodep->iterateChildren(*this);
m_modp= NULL;
}
virtual void visit(AstScope* nodep, AstNUser*) {
//UINFO(4," SCOPE "<<nodep<<endl);
+1
View File
@@ -407,6 +407,7 @@ private:
nodep->iterateChildren(*this);
m_state = STATE_IDLE;
}
m_modp = NULL;
}
virtual void visit(AstCFunc* nodep, AstNUser*) {
m_funcp = nodep;
+29 -7
View File
@@ -52,11 +52,13 @@ private:
bool m_checkBlock; // Should this block get covered?
AstModule* m_modp; // Current module to add statement to
FileMap m_fileps; // Column counts for each fileline
string m_beginHier; // AstBegin hier name for user coverage points
//int debug() { return 9; }
// METHODS
AstCoverInc* newCoverInc(FileLine* fl, const string& type, const string& comment) {
AstCoverInc* newCoverInc(FileLine* fl, const string& hier,
const string& type, const string& comment) {
int column = 0;
FileMap::iterator it = m_fileps.find(fl);
if (it == m_fileps.end()) {
@@ -66,6 +68,7 @@ private:
}
AstCoverDecl* declp = new AstCoverDecl(fl, column, type, comment);
declp->hier(hier);
m_modp->addStmtp(declp);
return new AstCoverInc(fl, declp);
@@ -86,7 +89,7 @@ private:
if (!nodep->backp()->castIf()
|| nodep->backp()->castIf()->elsesp()!=nodep) { // Ignore if else; did earlier
UINFO(4," COVER: "<<nodep<<endl);
nodep->addIfsp(newCoverInc(nodep->fileline(), "block", "if"));
nodep->addIfsp(newCoverInc(nodep->fileline(), "", "block", "if"));
}
}
// Don't do empty else's, only empty if/case's
@@ -96,9 +99,9 @@ private:
if (m_checkBlock && v3Global.opt.coverageLine()) { // if a "else" branch didn't disable it
UINFO(4," COVER: "<<nodep<<endl);
if (nodep->elsesp()->castIf()) {
nodep->addElsesp(newCoverInc(nodep->elsesp()->fileline(), "block", "elsif"));
nodep->addElsesp(newCoverInc(nodep->elsesp()->fileline(), "", "block", "elsif"));
} else {
nodep->addElsesp(newCoverInc(nodep->elsesp()->fileline(), "block", "else"));
nodep->addElsesp(newCoverInc(nodep->elsesp()->fileline(), "", "block", "else"));
}
}
}
@@ -111,18 +114,20 @@ private:
nodep->bodysp()->iterateAndNext(*this);
if (m_checkBlock) { // if the case body didn't disable it
UINFO(4," COVER: "<<nodep<<endl);
nodep->addBodysp(newCoverInc(nodep->fileline(), "block", "case"));
nodep->addBodysp(newCoverInc(nodep->fileline(), "", "block", "case"));
}
m_checkBlock = true; // Reset as a child may have cleared it
}
}
virtual void visit(AstPslCover* nodep, AstNUser*) {
UINFO(4," PSLCOVER: "<<nodep<<endl);
m_checkBlock = true; // Always do cover blocks, even if there's a $stop
nodep->iterateChildren(*this);
if (!nodep->coverincp()) {
// Note the name may be overridden by V3Assert processing
nodep->coverincp(newCoverInc(nodep->fileline(), "psl_cover", "cover"));
nodep->coverincp(newCoverInc(nodep->fileline(), m_beginHier, "psl_cover", "cover"));
}
m_checkBlock = true; // Reset as a child may have cleared it
}
virtual void visit(AstStop* nodep, AstNUser*) {
UINFO(4," STOP: "<<nodep<<endl);
@@ -134,8 +139,24 @@ private:
UINFO(4," OFF: "<<nodep<<endl);
m_checkBlock = false;
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
} else {
if (m_checkBlock) nodep->iterateChildren(*this);
}
if (m_checkBlock) nodep->iterateChildren(*this);
}
virtual void visit(AstBegin* nodep, AstNUser*) {
// Record the hiearchy 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
// covers the code in that line.)
string oldHier = m_beginHier;
{
if (nodep->name()!="") {
m_beginHier = m_beginHier + (m_beginHier!=""?".":"") + nodep->name();
}
nodep->iterateChildren(*this);
}
m_beginHier = oldHier;
}
virtual void visit(AstNode* nodep, AstNUser*) {
// Default: Just iterate
@@ -150,6 +171,7 @@ public:
CoverageVisitor(AstNetlist* rootp) {
// Operate on all modules
m_checkBlock = true;
m_beginHier = "";
rootp->iterateChildren(*this);
}
virtual ~CoverageVisitor() {}
+1
View File
@@ -85,6 +85,7 @@ private:
m_modp = nodep;
m_funcp = NULL;
nodep->iterateChildren(*this);
m_modp = NULL;
}
virtual void visit(AstCFunc* nodep, AstNUser*) {
m_funcp = nodep;
+1
View File
@@ -77,6 +77,7 @@ private:
m_modp = nodep;
m_deepNum = 0;
nodep->iterateChildren(*this);
m_modp = NULL;
}
virtual void visit(AstCFunc* nodep, AstNUser*) {
// We recurse into this.
+1
View File
@@ -177,6 +177,7 @@ private:
m_modFuncs.clear();
nodep->iterateChildren(*this);
makePublicFuncWrappers();
m_modp = NULL;
}
virtual void visit(AstScope* nodep, AstNUser*) {
m_scopep = nodep;
+6 -2
View File
@@ -214,10 +214,10 @@ public:
puts("__vlCoverInsert("); // As Declared in emitCoverageDecl
puts("&__Vcoverage[");
puts(cvtToStr(m_coverIds.remap(nodep))); puts("]");
puts(", \""); puts(nodep->fileline()->filebasename()); puts("\"");
puts(", \""); puts(nodep->fileline()->filename()); puts("\"");
puts(", "); puts(cvtToStr(nodep->fileline()->lineno()));
puts(", "); puts(cvtToStr(nodep->column()));
puts(", \""); puts(nodep->hier()); puts("\"");
puts(", \""); puts((nodep->hier()!=""?".":"")+nodep->hier()); puts("\"");
puts(", \""); puts(nodep->typeText()); puts("\"");
puts(", \""); puts(nodep->comment()); puts("\"");
puts(");\n");
@@ -242,6 +242,10 @@ public:
virtual void visit(AstSScanF* nodep, AstNUser*) {
displayNode(nodep, nodep->text(), nodep->exprsp(), true);
}
virtual void visit(AstFGetS* nodep, AstNUser*) {
checkMaxWords(nodep);
emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), NULL);
}
void checkMaxWords(AstNode* nodep) {
if (nodep->widthWords() > VL_TO_STRING_MAX_WORDS) {
+1
View File
@@ -78,6 +78,7 @@ class EmitCSyms : EmitCBaseVisitor {
nameCheck(nodep);
m_modp = nodep;
nodep->iterateChildren(*this);
m_modp = NULL;
}
virtual void visit(AstScope* nodep, AstNUser*) {
nameCheck(nodep);
+1
View File
@@ -53,6 +53,7 @@ public:
putbs("module "+modClassName(nodep)+";\n");
nodep->iterateChildren(*this);
puts("endmodule\n");
m_modp = NULL;
}
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
putbs(nodep->castTask() ? "task ":"function ");
+1
View File
@@ -316,6 +316,7 @@ private:
m_modp = nodep;
m_activeReducible = true;
nodep->iterateChildren(*this);
m_modp = NULL;
}
virtual void visit(AstScope* nodep, AstNUser*) {
UINFO(4," SCOPE "<<nodep<<endl);
+3 -1
View File
@@ -249,7 +249,9 @@ private:
virtual void visit(AstCoverDecl* nodep, AstNUser*) {
// Fix path in coverage statements
if (m_cellp) {
nodep->hier(nodep->hier()+"."+m_cellp->prettyName());
nodep->hier(m_cellp->prettyName()
+ (nodep->hier()!="" ? ".":"")
+ nodep->hier());
}
nodep->iterateChildren(*this);
}
+1
View File
@@ -61,6 +61,7 @@ private:
//if (nodep->name() == "t_chg") m_debug = 9; else m_debug=0;
m_modp = nodep;
nodep->iterateChildren(*this);
m_modp = NULL;
}
virtual void visit(AstCell* nodep, AstNUser*) {
UINFO(4," CELL "<<nodep<<endl);
-1
View File
@@ -32,7 +32,6 @@
#include "verilatedos.h"
#include <cstdio>
#include <cstdarg>
#include <cstring>
#include <unistd.h>
#include <map>
#include <algorithm>
+1
View File
@@ -47,6 +47,7 @@ private:
virtual void visit(AstModule* nodep, AstNUser*) {
m_modp = nodep;
nodep->iterateChildren(*this);
m_modp = NULL;
}
virtual void visit(AstCell* nodep, AstNUser*) {
// Track module depths, so can sort list from parent down to children
+1 -2
View File
@@ -18,12 +18,11 @@
//
//*************************************************************************
#include <config_build.h>
#include "config_build.h"
#include "verilatedos.h"
#include <cmath>
#include <cstdio>
#include <cstdarg>
#include <cstring>
#include <algorithm>
#include "V3Number.h"
-1
View File
@@ -24,7 +24,6 @@
#include <sys/stat.h>
#include <sys/utsname.h>
#include <cctype>
#include <cstring>
#include <dirent.h>
#include <unistd.h>
#include <set>
+1
View File
@@ -461,6 +461,7 @@ private:
virtual void visit(AstModule* nodep, AstNUser*) {
m_modp = nodep;
nodep->iterateChildren(*this);
m_modp = NULL;
}
virtual void visit(AstScope* nodep, AstNUser*) {
UINFO(4," SCOPE "<<nodep<<endl);
+1
View File
@@ -142,6 +142,7 @@ private:
m_modp = nodep;
m_funcp = NULL;
nodep->iterateChildren(*this);
m_modp = NULL;
}
virtual void visit(AstCFunc* nodep, AstNUser*) {
m_funcp = nodep;
+5
View File
@@ -31,6 +31,11 @@ class V3Lexer;
class V3Number;
class AstNode;
//======================================================================
// Types (between parser & lexer)
typedef enum { uniq_NONE, uniq_UNIQUE, uniq_PRIORITY } V3UniqState;
//============================================================================
class V3Read {
+1
View File
@@ -70,6 +70,7 @@ private:
m_modp = nodep;
m_constXCvt = true;
nodep->iterateChildren(*this);
m_modp = NULL;
}
virtual void visit(AstCaseItem* nodep, AstNUser*) {
m_constXCvt = false; // Avoid loosing the X's in casex
+5 -1
View File
@@ -336,7 +336,11 @@ private:
}
}
virtual void visit(AstNodeFor* nodep, AstNUser*) {
nodep->v3error("V3Task should have removed standard FORs");
if (m_generate) { // Ignore for's when expanding genfor's
nodep->iterateChildren(*this);
} else {
nodep->v3error("V3Task should have removed standard FORs");
}
}
virtual void visit(AstBegin* nodep, AstNUser*) {
+2 -1
View File
@@ -24,7 +24,7 @@
//**********************************************************************
//**** Version and host name
#define DTVERSION "Verilator 3.680 2008/10/08"
#define DTVERSION "Verilator 3.681 2008/11/12"
//**********************************************************************
//**** Functions
@@ -84,6 +84,7 @@
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std;
+5 -5
View File
@@ -355,7 +355,11 @@ escid \\[^ \t\f\r\n]+
"endproperty" {yylval.fileline = CRELINE(); return yENDPROPERTY;}
"final" {yylval.fileline = CRELINE(); return yFINAL;}
"iff" {yylval.fileline = CRELINE(); return yIFF;}
"priority" {yylval.fileline = CRELINE(); return yPRIORITY;}
"static" {yylval.fileline = CRELINE(); return ySTATIC;}
"timeprecision" {yylval.fileline = CRELINE(); return yTIMEPRECISION;}
"timeunit" {yylval.fileline = CRELINE(); return yTIMEUNIT;}
"unique" {yylval.fileline = CRELINE(); return yUNIQUE;}
/* Generic unsupported warnings */
/* Note assert_strobe was in SystemVerilog 3.1, but removed for SystemVerilog 2005 */
"alias" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
@@ -406,7 +410,6 @@ escid \\[^ \t\f\r\n]+
"null" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"package" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"packed" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"priority" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"program" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"protected" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"pure" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
@@ -425,11 +428,8 @@ escid \\[^ \t\f\r\n]+
"tagged" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"this" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"throughout" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"timeprecision" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"timeunit" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"type" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"typedef" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"unique" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"var" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"virtual" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"void" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
@@ -694,7 +694,7 @@ escid \\[^ \t\f\r\n]+
}
[0-9][_0-9]*(\.[_0-9]+)?(fs|ps|ns|us|ms|s|step) {
yylval.cdouble = 0; /* Only for times, not used yet */
return yaFLOATNUM;
return yaTIMENUM;
}
}
+38 -6
View File
@@ -57,6 +57,7 @@ public:
static string s_instModule; // Name of module referenced for instantiations
static AstPin* s_instParamp; // Parameters for instantiations
static bool s_trace; // Tracing is turned on
static int s_uniqueAttr; // Bitmask of unique/priority keywords
static AstVar* createVariable(FileLine* fileline, string name, AstRange* arrayp);
static AstNode* createSupplyExpr(FileLine* fileline, string name, int value);
@@ -107,6 +108,7 @@ class AstSenTree;
string* strp;
int cint;
double cdouble;
V3UniqState uniqstate;
AstNode* nodep;
@@ -139,6 +141,8 @@ class AstSenTree;
// IEEE: integral_number
%token<nump> yaINTNUM "INTEGER NUMBER"
// IEEE: time_literal + time_unit
%token<cdouble> yaTIMENUM "TIME NUMBER"
// IEEE: string_literal
%token<strp> yaSTRING "STRING"
%token<fileline> yaTIMINGSPEC "TIMING SPEC ELEMENT"
@@ -201,6 +205,7 @@ class AstSenTree;
%token<fileline> yOUTPUT "output"
%token<fileline> yPARAMETER "parameter"
%token<fileline> yPOSEDGE "posedge"
%token<fileline> yPRIORITY "priority"
%token<fileline> yPROPERTY "property"
%token<fileline> yREG "reg"
%token<fileline> ySCALARED "scalared"
@@ -210,8 +215,11 @@ class AstSenTree;
%token<fileline> ySUPPLY0 "supply0"
%token<fileline> ySUPPLY1 "supply1"
%token<fileline> yTASK "task"
%token<fileline> yTIMEPRECISION "timeprecision"
%token<fileline> yTIMEUNIT "timeunit"
%token<fileline> yTRI "tri"
%token<fileline> yTRUE "true"
%token<fileline> yUNIQUE "unique"
%token<fileline> yUNSIGNED "unsigned"
%token<fileline> yVECTORED "vectored"
%token<fileline> yWHILE "while"
@@ -425,7 +433,7 @@ statePop: /* empty */ { V3Read::statePop(); }
// Files
fileE: /* empty */ { }
| file { }
| timeunitsDeclE file { }
;
file: description { }
@@ -436,13 +444,26 @@ file: description { }
description: moduleDecl { }
;
// IEEE: timeunits_declaration + empty
timeunitsDeclE: /*empty*/ { }
| yTIMEUNIT yaTIMENUM ';' { }
| yTIMEPRECISION yaTIMENUM ';' { }
| yTIMEUNIT yaTIMENUM ';' yTIMEPRECISION yaTIMENUM ';' { }
| yTIMEPRECISION yaTIMENUM ';' yTIMEUNIT yaTIMENUM ';' { }
;
//**********************************************************************
// Module headers
// IEEE: module_declaration:
moduleDecl: modHdr modParE modPortsE ';' modItemListE yENDMODULE endLabelE
moduleDecl: modHeader timeunitsDeclE modItemListE yENDMODULE endLabelE
{ if ($3) $1->addStmtp($3); }
;
modHeader<modulep>:
modHdr modParE modPortsE ';'
{ $1->modTrace(V3Parse::s_trace); // Stash for implicit wires, etc
if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); }
if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); }
;
modHdr<modulep>:
@@ -719,6 +740,7 @@ dlyTerm<nodep>:
yaID { $$ = NULL; }
| yaINTNUM { $$ = NULL; }
| yaFLOATNUM { $$ = NULL; }
| yaTIMENUM { $$ = NULL; }
;
// IEEE: mintypmax_expression and constant_mintypmax_expression
@@ -982,10 +1004,20 @@ stmt<nodep>:
//************************************************
// Case/If
unique_priorityE<uniqstate>:
/*empty*/ { $$ = uniq_NONE; }
| yPRIORITY { $$ = uniq_PRIORITY; }
| yUNIQUE { $$ = uniq_UNIQUE; }
;
stateCaseForIf<nodep>:
caseStmt caseAttrE caseListE yENDCASE { $$ = $1; if ($3) $1->addItemsp($3); }
| yIF '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstIf($1,$3,$5,NULL); }
| yIF '(' expr ')' stmtBlock yELSE stmtBlock { $$ = new AstIf($1,$3,$5,$7); }
unique_priorityE caseStmt caseAttrE caseListE yENDCASE { $$ = $2; if ($4) $2->addItemsp($4);
if ($1 == uniq_UNIQUE) $2->parallelPragma(true);
if ($1 == uniq_PRIORITY) $2->fullPragma(true); }
| unique_priorityE yIF '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE
{ $$ = new AstIf($2,$4,$6,NULL); }
| unique_priorityE yIF '(' expr ')' stmtBlock yELSE stmtBlock
{ $$ = new AstIf($2,$4,$6,$8); }
| yFOR '(' varRefBase '=' expr ';' expr ';' varRefBase '=' expr ')' stmtBlock
{ $$ = new AstFor($1, new AstAssign($4,$3,$5)
,$7, new AstAssign($10,$9,$11)
+3 -1
View File
@@ -481,7 +481,9 @@ sub _run {
my %param = (tee=>1,
@_);
my $command = join(' ',@{$param{cmd}});
print "\t$command\n";
print "\t$command";
print " > $param{logfile}" if $param{logfile};
print "\n";
if ($param{logfile}) {
open(SAVEOUT, ">&STDOUT") or die "%Error: Can't dup stdout";
+5 -3
View File
@@ -23,8 +23,8 @@ if ($Last_Self->{nc}) {
{
my $fh = IO::File->new(">$cf") or die "%Error: $! writing $cf,";
$fh->printf("report_summary -module *\n");
$fh->printf("report_detail -both -module *\n");
$fh->printf("report_html -both -module * > obj_dir/${name}__nccover.html\n");
$fh->printf("report_detail -both -instance *\n");
$fh->printf("report_html -both -instance * > obj_dir/${name}__nccover.html\n");
$fh->close;
}
$Last_Self->_run (logfile=>"obj_dir/${name}__nccover.log",
@@ -36,7 +36,9 @@ if ($Last_Self->{nc}) {
file_grep ("obj_dir/$Last_Self->{name}_simx.log", qr/COVER: Cyc==4/);
file_grep ("obj_dir/$Last_Self->{name}_simx.log", qr/COVER: Cyc==5/);
file_grep ("obj_dir/$Last_Self->{name}_simx.log", qr/COVER: Cyc==6/);
file_grep ($Last_Self->{coverage_filename}, qr/cyc_eq_5.*,c=>[^0]/);
# Allow old Perl format dump, or new binary dump
file_grep ($Last_Self->{coverage_filename}, qr/(cyc_eq_5.*,c=>[^0]|cyc_eq_5.* [1-9][0-9]*\n)/);
ok(1);
1;
+15
View File
@@ -64,7 +64,22 @@ module Test
cover property (@(posedge clk) disable iff (!toggle) cyc==8)
$stop;
//============================================================
// Using a macro and generate
wire reset = (cyc < 2);
`define covclk(eqn) cover property (@(posedge clk) disable iff (reset) (eqn))
genvar i;
generate
for (i=0; i<32; i=i+1)
begin: cycval
CycCover_i: `covclk( cyc[i] );
end
endgenerate
`ifndef verilator // Unsupported
//============================================================
// Using a more complicated property
property C1;
@(posedge clk)
+6
View File
@@ -32,6 +32,12 @@ module t (/*AUTOARG*/
2'b1_0: ;
// Note no default
endcase
priority case ({a,b_fc})
2'b0_0: ;
2'b0_1: ;
2'b1_0: ;
// Note no default
endcase
end
always @* begin
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+87
View File
@@ -0,0 +1,87 @@
// DESCRIPTION: Verilator: Verilog Test module
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 [9:0] in = crc[9:0];
/*AUTOWIRE*/
Test test (/*AUTOINST*/
// Inputs
.clk (clk),
.in (in[9:0]));
// Aggregate outputs into a single result vector
wire [63:0] result = {64'h0};
// 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;
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'h0
if (sum !== `EXPECTED_SUM) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module Test (/*AUTOARG*/
// Inputs
clk, in
);
input clk;
input [9:0] in;
reg a [9:0];
integer ai;
always @* begin
for (ai=0;ai<10;ai=ai+1) begin
a[ai]=in[ai];
end
end
reg [1:0] b [9:0];
integer j;
generate
genvar i;
for (i=0; i<2; i=i+1) begin
always @(posedge clk) begin
for (j=0; j<10; j=j+1) begin
if (a[j])
b[i][j] <= 1'b0;
else
b[i][j] <= 1'b1;
end
end
end
endgenerate
endmodule
+5
View File
@@ -8,6 +8,11 @@ module t (/*AUTOARG*/
clk
);
`ifdef verilator // Otherwise need it in every module, including test, but that'll make a mess
timeunit 1ns;
timeprecision 1ns;
`endif
input clk;
integer cyc; initial cyc=1;
+4 -3
View File
@@ -16,9 +16,10 @@ execute (
check_finished=>1,
);
file_grep ($Last_Self->{coverage_filename}, qr/,o=>'cover'.*,c=>2\);/);
file_grep ($Last_Self->{coverage_filename}, qr/DefaultClock.*,c=>1\);/);
file_grep ($Last_Self->{coverage_filename}, qr/ToggleLogIf.*,c=>9\);/);
# Allow old Perl format dump, or new binary dump
file_grep ($Last_Self->{coverage_filename}, qr/(,o=>'cover'.*,c=>2\)|o.cover.* 2\n)/);
file_grep ($Last_Self->{coverage_filename}, qr/(DefaultClock.*,c=>1\)|DefaultClock.* 1\n)/);
file_grep ($Last_Self->{coverage_filename}, qr/(ToggleLogIf.*,c=>9\)|ToggleLogIf.* 9\n)/);
ok(1);
1;
+1 -1
View File
@@ -31,7 +31,7 @@ VERILATOR_FLAGS = --sc $(V_FLAGS) top.v
precopy: obj_dir obj_dir/sc_main.cpp
obj_dir/sc_main.cpp: ../test_sp/sc_main.cpp
mkdir obj_dir
mkdir -p obj_dir
cp $^ $@
prep:
+16
View File
@@ -16,6 +16,8 @@ module t_clk_two (/*AUTOARG*/
// verilator lint_on GENCLK
reg [31:0] count;
t_clk_twob tb (.*);
wire reset_h = ~reset_l;
always @ (posedge fastclk) begin
if (reset_h) clk2 <= 0;
@@ -26,3 +28,17 @@ module t_clk_two (/*AUTOARG*/
else count <= count + 1;
end
endmodule
module t_clk_twob (/*AUTOARG*/
// Inputs
fastclk, reset_l
);
input fastclk;
input reset_l;
always @ (posedge fastclk) begin
// Extra line coverage point, just to make sure coverage
// hierarchy under inlining lands properly
if (reset_l) ;
end
endmodule