Compare commits

...
9 Commits
31 changed files with 545 additions and 178 deletions
+10
View File
@@ -3,6 +3,16 @@ 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.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]
+24 -6
View File
@@ -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
+26 -16
View File
@@ -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
+6 -6
View File
@@ -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
View File
@@ -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.
+7 -1
View File
@@ -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
@@ -280,4 +287,3 @@ DEPS := $(wildcard *.d)
ifneq ($(DEPS),)
include $(DEPS)
endif
+7 -7
View File
@@ -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
View File
@@ -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; }
+13 -11
View File
@@ -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()
@@ -1412,7 +1414,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 +1546,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 +1818,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 +1853,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 +1875,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 +1884,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
View File
@@ -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=',';
}
+1
View File
@@ -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");
+98 -58
View File
@@ -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);
}
+7 -5
View File
@@ -144,7 +144,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 +155,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 +173,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 +181,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 +216,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");
+1 -1
View File
@@ -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;
}
+61 -21
View File
@@ -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
View File
@@ -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",""); }
+10 -2
View File
@@ -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
View File
@@ -538,6 +538,7 @@ int main(int argc, char** argv, char** env) {
V3Options::getenvSYSTEMC();
V3Options::getenvSYSTEMC_ARCH();
V3Options::getenvSYSTEMPERL();
V3Options::getenvSYSTEMPERL_INCLUDE();
V3Error::abortIfErrors();
+4 -1
View File
@@ -24,7 +24,7 @@
//**********************************************************************
//**** Version and host name
#define DTVERSION "Verilator 3.701 2009/02/26"
#define DTVERSION "Verilator 3.702 2009/03/28"
//**********************************************************************
//**** 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
+1
View File
@@ -32,6 +32,7 @@ endif
# Needed by tracing routines
CPPFLAGS += -DVL_DEBUG=1
CPPFLAGS += -DVM_PREFIX=$(VM_PREFIX)
CPPFLAGS += $(CPPFLAGS_DRIVER)
CPPFLAGS += $(CPPFLAGS_ADD)
#######################################################################
+1
View File
@@ -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
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 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;
+19
View File
@@ -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
+25
View File
@@ -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;
+59
View File
@@ -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
+8 -4
View File
@@ -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.*',
);
+33
View File
@@ -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;
+33
View File
@@ -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;
+14 -14
View File
@@ -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);
+14 -14
View File
@@ -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);
+28
View File
@@ -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;
}