Compare commits

..
14 Commits
Author SHA1 Message Date
Wilson Snyder 3a2f8224e4 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1022 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-04 18:30:51 +00:00
Wilson Snyder 15841fe5f6 Support functions with input
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1021 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-04 18:29:33 +00:00
Wilson Snyder 7e5a7b65a0 Unsized concatenates now give WIDTHCONCAT warnings.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1020 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-02 12:53:53 +00:00
Wilson Snyder 549bf876e4 Ignore delays attached to gate UDPs. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1019 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-01 19:26:06 +00:00
Wilson Snyder bd60cf12f8 Match Verilog-Perl: Fix parse error on min:typ:max delay pairs
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1018 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-31 21:03:56 +00:00
Wilson Snyder 61fbab1910 Fix internal error after MSB < LSB error reported to user. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1017 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-31 14:09:52 +00:00
Wilson Snyder 957f495314 Fix task output pin connected to non-variables.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1016 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-28 21:55:23 +00:00
Wilson Snyder 280eb48ba4 Add --language option for supporting older code. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1015 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-28 20:41:21 +00:00
Wilson Snyder ebe5711b40 The --enable-defenv configure option added in 3.660 is now the default.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1014 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-28 19:42:14 +00:00
Wilson Snyder a16477d84f Fix SystemVerilog parameterized defines and whitespace
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1013 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-27 13:21:49 +00:00
Wilson Snyder f6fb2362c6 Fix dropping of backslash quoted-quote at end of .
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1012 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-26 14:58:30 +00:00
Wilson Snyder 170427bba1 Fix r1010; bad prefix default
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1011 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-26 14:53:53 +00:00
Wilson Snyder 93531e520a Add --top-module option to select between multiple tops. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1010 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-25 19:57:41 +00:00
Wilson Snyder aa2db8fdde Fix no-module include files on command line. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1009 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-25 13:42:48 +00:00
51 changed files with 877 additions and 195 deletions
+30
View File
@@ -3,6 +3,36 @@ 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.661 2008/04/04
*** The --enable-defenv configure option added in 3.660 is now the default.
This hard-codes a default for VERILATOR_ROOT etc in the executables.
*** Add --language option for supporting older code. [Stefan Thiede]
*** Add --top-module option to select between multiple tops. [Stefan Thiede]
*** Unsized concatenates now give WIDTHCONCAT warnings. [Jonathan Kimmitt]
Previously they threw fatal errors, which in most cases is correct
according to spec, but can be incorrect in presence of parameter values.
**** Support functions with "input integer". [Johan Wouters]
**** Ignore delays attached to gate UDPs. [Stefan Thiede]
**** Fix SystemVerilog parameterized defines with `` expansion,
and fix extra whitespace inserted on substitution. [Vladimir Matveyenko]
**** Fix no-module include files on command line. [Stefan Thiede]
**** Fix dropping of backslash quoted-quote at end of $display.
**** Fix task output pin connected to non-variables. [Jonathan Kimmitt]
**** Fix missing test_v in install datadir. [Holger Waechtler]
**** Fix internal error after MSB < LSB error reported to user. [Stefan Thiede]
* Verilator 3.660 2008/03/23
*** Add support for hard-coding VERILATOR_ROOT etc in the executables,
+1
View File
@@ -227,6 +227,7 @@ installdata:
cp -r test_c $(pkgdatadir)/examples
cp -r test_sc $(pkgdatadir)/examples
cp -r test_sp $(pkgdatadir)/examples
cp -r test_v $(pkgdatadir)/examples
VL_INST_DATA_FILES = verilator.1
install: all_nomsg installbin installman installdata install-msg
+38 -2
View File
@@ -197,6 +197,7 @@ descriptions in the next sections for more information.
-I<dir> Directory to search for includes
--inhibit-sim Create function to turn off sim
--inline-mult <value> Tune module inlining
--language <lang> Language standard to parse
--lint-only Lint, but do not make output
--MMD Create .d dependency files
--MP Create phony dependency targets
@@ -217,6 +218,7 @@ descriptions in the next sections for more information.
--sc Create SystemC output
--sp Create SystemPerl output
--stats Create statistics file
--top-module <topname> Name of top level input module
--trace Enable waveform creation
--trace-depth <levels> Depth of tracing
-U<var> Undefine preprocessor define
@@ -379,6 +381,14 @@ values, or a value <= 1 will inline everything, will lead to longer compile
times, but potentially faster runtimes. This setting is ignored for very
small modules; they will always be inlined, if allowed.
=item --language I<value>
Select the language to be used when first processing each Verilog file.
The language value must be "1364-1995", "1364-2001", "1364-2001",
"1364-2005", or "1800-2005". This should only be used for legacy code, as
the preferable option is to edit the code to repair new keywords, or add
appropriate `begin_keywords.
=item --lint-only
Check the files for lint violations only, do not create any other output.
@@ -451,8 +461,9 @@ the backward-compatible default of sc_bv's.
=item --prefix I<topname>
Specifies the name of the top level class. Defaults to the name of the first
Verilog file passed on the command line.
Specifies the name of the top level class and makefile. Defaults to V
prepended to the name of the --top-module switch, or V prepended to the
first Verilog filename passed on the command line.
=item --profile-cfuncs
@@ -498,6 +509,13 @@ Specifies SystemPerl output mode; see also --cc and -sc.
Creates a dump file with statistics on the design in {prefix}__stats.txt.
=item --top-module I<topname>
When the input Verilog contains more than one top level module, specifies
the name of the top level Verilog module to become the top, and sets the
default for if --prefix is not used. This is not needed with standard
designs with only one top.
=item --trace
Adds waveform tracing code to the model, this will create additional
@@ -1875,6 +1893,24 @@ The best fix, which clarifies intent and will also make all tools happy is:
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item WIDTHCONCAT
Warns that based on width rules of Verilog, a concatenate or replication
has a undeterminate width. In most cases this violates the Verilog rule
that widths inside concatenates and replicates must be sized, and should be
fixed in the code.
wire [63:0] concat = {1,2};
An example where this is technically legal (though still bad form) is:
parameter PAR = 1;
wire [63:0] concat = {PAR,PAR};
The correct fix is to either size the 1 ("32'h1"), or add the width to the
parameter definition ("parameter [31:0]"), or add the width to the
parameter usage ("{PAR[31:0],PAR[31:0]}".
=back
The following describes the less obvious errors:
+3 -2
View File
@@ -10,8 +10,9 @@ AC_CONFIG_HEADER(src/config_build.h)
dnl Special Substitutions
AC_ARG_ENABLE(defenv,
[AS_HELP_STRING([--enable-defenv], [hardcode default environment variables])],
CFG_WITH_DEFENV=1,)
[AS_HELP_STRING([--disable-defenv], [disable hardcoded default environment variables])],
CFG_WITH_DEFENV=$enableval,
CFG_WITH_DEFENV=1)
AC_SUBST(CFG_WITH_DEFENV)
dnl Checks for programs.
+1 -1
View File
@@ -80,7 +80,7 @@ endif
# Allow RPM builds to specify hardcoded data directories
# To do this:
ifneq ($(CFG_WITH_DEFENV),)
ifeq ($(CFG_WITH_DEFENV),yes)
CPPFLAGS += -DDEFENV_SYSTEMC=\"$(SYSTEMC)\"
CPPFLAGS += -DDEFENV_SYSTEMC_ARCH=\"$(SYSTEMC_ARCH)\"
CPPFLAGS += -DDEFENV_SYSTEMPERL=\"$(SYSTEMPERL)\"
+4
View File
@@ -304,6 +304,10 @@ void AstCellInline::dump(ostream& str) {
this->AstNode::dump(str);
str<<" -> "<<origModName();
}
void AstDisplay::dump(ostream& str) {
this->AstNode::dump(str);
//str<<" "<<displayType().ascii();
}
void AstPin::dump(ostream& str) {
this->AstNode::dump(str);
if (modVarp()) { str<<" -> "; modVarp()->dump(str); }
+1
View File
@@ -1254,6 +1254,7 @@ public:
virtual AstType type() const { return AstType::DISPLAY;}
virtual AstNode* clone() { return new AstDisplay(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void dump(ostream& str);
virtual string verilogKwd() const { return (filep() ? (string)"$f"+(string)displayType().ascii()
: (string)"$"+(string)displayType().ascii()); }
virtual bool isGateOptimizable() const { return false; }
-2
View File
@@ -1027,10 +1027,8 @@ void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
emitDispState.clear();
string fmt = "";
string::iterator pos = vformat.begin();
if (*pos == '"') pos++;
bool inPct = false;
for (; pos != vformat.end(); ++pos) {
if (pos[0]=='"' && (pos+1)==vformat.end()) break;
if (inPct && pos[0]=='%') {
emitDispState.pushFormat("%%"); // We're printf'ing it, so need to quote the %
inPct = false;
+2 -1
View File
@@ -61,6 +61,7 @@ public:
UNUSED, // No receivers
VARHIDDEN, // Hiding variable
WIDTH, // Width mismatch
WIDTHCONCAT, // Unsized numbers/parameters in concatenations
MAX
// ***Add new elements below also***
};
@@ -81,7 +82,7 @@ public:
"COMBDLY", "STMTDLY", "GENCLK", "IMPLICIT", "IMPURE",
"MULTIDRIVEN", "REDEFMACRO",
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
"VARHIDDEN", "WIDTH",
"VARHIDDEN", "WIDTH", "WIDTHCONCAT",
" MAX"
};
return names[m_e];
+13 -10
View File
@@ -379,17 +379,20 @@ private:
// This may not be the module with isTop() set, as early in the steps,
// wrapTop may have not been created yet.
AstModule* topmodp = nodep->modulesp();
if (!topmodp) nodep->v3fatalSrc("No top level module");
UINFO(8,"Top Module: "<<topmodp<<endl);
m_scope = "TOP";
m_cellVxp = m_statep->insertTopCell(topmodp, m_scope);
m_inlineVxp = m_cellVxp;
{
topmodp->accept(*this);
if (!topmodp) {
nodep->v3error("No top level module found");
} else {
UINFO(8,"Top Module: "<<topmodp<<endl);
m_scope = "TOP";
m_cellVxp = m_statep->insertTopCell(topmodp, m_scope);
m_inlineVxp = m_cellVxp;
{
topmodp->accept(*this);
}
m_scope = "";
m_cellVxp = NULL;
m_inlineVxp = m_cellVxp;
}
m_scope = "";
m_cellVxp = NULL;
m_inlineVxp = m_cellVxp;
}
virtual void visit(AstModule* nodep, AstNUser*) {
UINFO(8," "<<nodep<<endl);
+10 -4
View File
@@ -166,10 +166,10 @@ private:
public:
// CONSTUCTORS
LinkLValueVisitor(AstNetlist* rootp) {
m_setRefLvalue = false;
LinkLValueVisitor(AstNode* nodep, bool start) {
m_setRefLvalue = start;
m_ftaskp = NULL;
rootp->accept(*this);
nodep->accept(*this);
}
virtual ~LinkLValueVisitor() {}
};
@@ -179,5 +179,11 @@ public:
void V3LinkLValue::linkLValue(AstNetlist* rootp) {
UINFO(4,__FUNCTION__<<": "<<endl);
LinkLValueVisitor visitor(rootp);
LinkLValueVisitor visitor(rootp, false);
}
void V3LinkLValue::linkLValueSet(AstNode* nodep) {
// Called by later link functions when it is known a node needs
// to be converted to a lvalue.
UINFO(9,__FUNCTION__<<": "<<endl);
LinkLValueVisitor visitor(nodep, true);
}
+1
View File
@@ -31,6 +31,7 @@
class V3LinkLValue {
public:
static void linkLValue(AstNetlist* nodep);
static void linkLValueSet(AstNode* nodep);
};
#endif // Guard
+20 -2
View File
@@ -85,6 +85,21 @@ void V3LinkLevel::modSortByLevel() {
// Sort modules by levels, root down to lowest children
// Calculate levels again in case we added modules
UINFO(2,"modSortByLevel()\n");
if (v3Global.opt.topModule()!="") {
bool hit = false;
for (AstModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castModule()) {
if (nodep->name() == v3Global.opt.topModule()) {
hit = true;
} else {
nodep->level(3);
}
}
if (!hit) {
v3error("Specified --top-module '"<<v3Global.opt.topModule()<<"' was not found in design.");
}
}
LinkLevelVisitor visitor;
visitor.main(v3Global.rootp());
@@ -92,8 +107,11 @@ void V3LinkLevel::modSortByLevel() {
AstModule* topp = NULL;
for (AstModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castModule()) {
if (nodep->level()<=2) {
if (topp) nodep->v3warn(MULTITOP, "Unsupported: Multiple top level modules: "
<<nodep->prettyName()<<" and "<<topp->prettyName());
if (topp) {
nodep->v3warn(MULTITOP, "Unsupported: Multiple top level modules: "
<<nodep->prettyName()<<" and "<<topp->prettyName());
nodep->v3warn(MULTITOP, "Fix, or use --top-module option to select which you want.");
}
topp = nodep;
}
vec.push_back(nodep);
+6 -3
View File
@@ -698,8 +698,10 @@ V3Number& V3Number::opXnor (const V3Number& lhs, const V3Number& rhs) {
V3Number& V3Number::opConcat (const V3Number& lhs, const V3Number& rhs) {
setZero();
if (!lhs.sized()) m_fileline->v3error("Unsized constants not allowed in concatenations: "<<lhs);
if (!rhs.sized()) m_fileline->v3error("Unsized constants not allowed in concatenations: "<<rhs);
// See also error in V3Width
if (!lhs.sized() || !rhs.sized()) {
m_fileline->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in concatenations.");
}
int obit = 0;
for(int bit=0; bit<rhs.width(); bit++) {
setBit(obit,rhs.bitIs(bit));
@@ -714,7 +716,8 @@ V3Number& V3Number::opConcat (const V3Number& lhs, const V3Number& rhs) {
V3Number& V3Number::opRepl (const V3Number& lhs, const V3Number& rhs) { // rhs is # of times to replicate
// Hopefully the using routine has a error check too.
if (!lhs.sized()) m_fileline->v3error("Unsized constants not allowed in concatenations: "<<lhs);
// See also error in V3Width
if (!lhs.sized()) m_fileline->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications.");
return opRepl(lhs, rhs.asInt());
}
+38 -9
View File
@@ -118,6 +118,20 @@ string V3Options::allArgsString() {
return out;
}
//######################################################################
// Language class
V3LangCode::V3LangCode (const char* textp) {
// Return code for given string, or ERROR, which is a bad code
for (int codei=V3LangCode::ERROR; codei<V3LangCode::MAX; codei++) {
V3LangCode code = (V3LangCode)codei;
if (0==strcasecmp(textp,code.ascii())) {
m_e = code; return;
}
}
m_e = V3LangCode::ERROR;
}
//######################################################################
// File searching
@@ -429,6 +443,7 @@ void V3Options::parseOpts (FileLine* fl, int argc, char** argv) {
}
// Default prefix to the filename
if (prefix()=="" && topModule()!="") m_prefix = string("V")+topModule();
if (prefix()=="") m_prefix = string("V")+filenameNonExt(*(vFiles().begin()));
if (modPrefix()=="") m_modPrefix = prefix();
@@ -497,15 +512,6 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
shift;
setDebugMode(atoi(argv[i]));
}
else if ( !strcmp (sw, "-v") ) {
shift;
V3Options::addLibraryFile(argv[i]);
}
else if ( !strcmp (sw, "-version") ) {
cout <<version();
cout <<endl;
exit(0);
}
else if ( !strcmp (sw, "-error-limit") ) {
shift;
m_inlineMult = atoi(argv[i]);
@@ -514,6 +520,15 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
shift;
m_inlineMult = atoi(argv[i]);
}
else if ( !strcmp (sw, "-language") ) {
shift;
V3LangCode optval = V3LangCode(argv[i]);
if (optval.legal()) {
m_language = optval;
} else {
fl->v3fatal("Unknown language specified: "<<argv[i]);
}
}
else if ( !strcmp (sw, "-output-split") ) {
shift;
m_outputSplit = atoi(argv[i]);
@@ -534,6 +549,15 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
shift;
m_unrollStmts = atoi(argv[i]);
}
else if ( !strcmp (sw, "-v") ) {
shift;
V3Options::addLibraryFile(argv[i]);
}
else if ( !strcmp (sw, "-version") ) {
cout <<version();
cout <<endl;
exit(0);
}
// Single switches
else if ( !strcmp (sw, "-E") ) { m_preprocOnly = true; }
else if ( onoff (sw, "-MMD", flag/*ref*/) ) { m_makeDepend = flag; }
@@ -654,6 +678,9 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
shift; m_prefix = argv[i];
if (m_modPrefix=="") m_modPrefix = m_prefix;
}
else if ( !strcmp (sw, "-top-module") && (i+1)<argc ) {
shift; m_topModule = argv[i];
}
else if ( !strcmp (sw, "-x-assign") && (i+1)<argc) {
shift;
if (!strcmp (argv[i], "0")) { m_xAssign="0"; }
@@ -790,6 +817,8 @@ V3Options::V3Options() {
m_flags = "";
m_xAssign = "unique";
m_language = V3LangCode::mostRecent();
optimize(true);
// Default +libext+
addLibExt(""); // So include "filename.v" will find the same file
+40 -1
View File
@@ -29,6 +29,41 @@
#include "V3Global.h"
//######################################################################
class V3LangCode {
public:
enum en {
ERROR, // Must be first.
L1364_1995,
L1364_2001,
L1364_2005,
L1800_2005,
// ***Add new elements below also***
MAX
};
const char* ascii() const {
const char* names[] = {
// These must match the `begin_keywords values.
" ERROR",
"1364-1995",
"1364-2001",
"1364-2005",
"1800-2005"
};
return names[m_e];
};
static V3LangCode mostRecent() { return V3LangCode(L1800_2005); }
bool legal() const { return m_e != ERROR; }
//
enum en m_e;
inline V3LangCode () : m_e(ERROR) {};
inline V3LangCode (en _e) : m_e(_e) {};
V3LangCode (const char* textp); // Return matching code or ERROR
explicit inline V3LangCode (int _e) : m_e(static_cast<en>(_e)) {};
operator en () const { return m_e; };
};
//######################################################################
// V3Options - Command line options
@@ -88,6 +123,9 @@ class V3Options {
string m_prefix; // main switch: --prefix
string m_modPrefix; // main switch: --mod-prefix
string m_xAssign; // main switch: --x-assign
string m_topModule; // main switch: --top-module
V3LangCode m_language; // main switch: --language
// MEMBERS (optimizations)
// // main switch: -Op: --public
@@ -175,11 +213,12 @@ class V3Options {
string makeDir() const { return m_makeDir; }
string prefix() const { return m_prefix; }
string modPrefix() const { return m_modPrefix; }
string topModule() const { return m_topModule; }
string xAssign() const { return m_xAssign; }
const V3StringSet& cppFiles() const { return m_cppFiles; }
const V3StringSet& libraryFiles() const { return m_libraryFiles; }
const V3StringSet& vFiles() const { return m_vFiles; }
const V3LangCode& language() const { return m_language; }
// ACCESSORS (optimization options)
bool oAcycSimp() const { return m_oAcycSimp; }
+3 -3
View File
@@ -133,9 +133,9 @@ class V3PreLex {
void lineDirective(const char* text);
void incLineno() { m_curFilelinep->incLineno(); }
// Called by V3PreProc.cpp to inform lexer
void setStateDefArg();
void setStateDefValue();
void setStateIncFilename();
void pushStateDefArg();
void pushStateDefValue();
void pushStateIncFilename();
void unputString(const char* textp);
};
+20 -9
View File
@@ -140,14 +140,25 @@ psl [p]sl
<ARGMODE><<EOF>> { yyerror("EOF in define argument list\n"); yyleng = 0; yyterminate(); }
<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) {
<ARGMODE>[(] { V3PreLex::s_currentLexp->m_parenLevel++;
if (V3PreLex::s_currentLexp->m_parenLevel>1) {
appendDefValue(yytext,yyleng);
if (yytext[0]==')') V3PreLex::s_currentLexp->m_parenLevel--;
} else {
unput(yytext[0]); yy_pop_state(); return (VP_DEFARG);
return (VP_TEXT);
}}
<ARGMODE>[^\/\*\n\r\\(,)\"]+ |
<ARGMODE>[)] { V3PreLex::s_currentLexp->m_parenLevel--;
if (V3PreLex::s_currentLexp->m_parenLevel>0) {
appendDefValue(yytext,yyleng);
} else {
yy_pop_state(); return (VP_DEFARG);
}}
<ARGMODE>[,] { if (V3PreLex::s_currentLexp->m_parenLevel>1) {
appendDefValue(yytext,yyleng);
} else {
yy_pop_state(); return (VP_DEFARG);
}}
<ARGMODE>"`"{symb} { return (VP_DEFREF); } /* defref in defref */
<ARGMODE>[^\/\*\n\r\\(,)\"`]+ |
<ARGMODE>. { appendDefValue(yytext,yyleng); }
/* One line comments. */
@@ -199,21 +210,21 @@ psl [p]sl
<INITIAL,PSLMULM,PSLONEM>. { return (VP_TEXT); }
%%
void V3PreLex::setStateDefArg() {
void V3PreLex::pushStateDefArg() {
// Enter define substitution argument state
yy_push_state(ARGMODE);
m_parenLevel = 1;
m_parenLevel = 0;
m_defValue = "";
}
void V3PreLex::setStateDefValue() {
void V3PreLex::pushStateDefValue() {
// Enter define value state
yy_push_state(DEFMODE);
m_parenLevel = 0;
m_defValue = "";
}
void V3PreLex::setStateIncFilename() {
void V3PreLex::pushStateIncFilename() {
// Enter include <> filename state
yy_push_state(INCMODE);
yymore();
+97 -51
View File
@@ -61,6 +61,28 @@ public:
string params() const { return m_params; }
};
//*************************************************************************
class V3DefineRef {
// One for each pending define substitution
string m_name; // Define last name being defined
string m_params; // Define parameter list for next expansion
string m_nextarg; // String being built for next argument
int m_parenLevel; // Parenthesis counting inside def args
vector<string> m_args; // List of define arguments
public:
string name() const { return m_name; }
string params() const { return m_params; }
string nextarg() const { return m_nextarg; }
void nextarg(const string& value) { m_nextarg = value; }
int parenLevel() const { return m_parenLevel; }
vector<string>& args() { return m_args; }
V3DefineRef(const string& name, const string& params, int pl)
: m_name(name), m_params(params), m_parenLevel(pl) {}
~V3DefineRef() {}
};
//*************************************************************************
// Data for a preprocessor instantiation.
@@ -88,14 +110,12 @@ struct V3PreProcImp : public V3PreProc {
bool m_rawAtBol; ///< Last rawToken left us at beginning of line
// For defines
string m_defName; // Define last name being defined
string m_defParams; // Define parameter list for next expansion
stack<V3DefineRef> m_defRefs; // Pending definine substitution
stack<bool> m_ifdefStack; // Stack of true/false emitting evaluations
vector<string> m_defArgs; // List of define arguments
unsigned m_defDepth; // How many `defines deep
// Defines list
DefinesMap m_defines; // Map of defines
DefinesMap m_defines; // Map of defines
// For getline()
string m_lineChars; // Characters left for next line
@@ -113,7 +133,7 @@ struct V3PreProcImp : public V3PreProc {
private:
// Internal methods
void eof();
string defineSubst();
string defineSubst(V3DefineRef* refp);
void addLineComment(int enter_exit_level);
bool defExists(const string& name);
@@ -122,6 +142,7 @@ private:
FileLine* defFileline(const string& name);
bool commentTokenMatch(string& cmdr, const char* strg);
string trimWhitespace(const string& strg);
void parsingOn() {
m_off--;
@@ -149,7 +170,6 @@ public:
V3PreProcImp(FileLine* fl) : V3PreProc(fl) {
m_lexp = NULL; // Closed.
m_state = ps_TOP;
m_defName = "";
m_off = 0;
m_lineChars = "";
m_lastSym = "";
@@ -348,33 +368,43 @@ const char* V3PreProcImp::tokenName(int tok) {
}
}
string V3PreProcImp::defineSubst() {
string V3PreProcImp::trimWhitespace(const string& strg) {
string out = strg;
while (out.length()>0 && isspace(out[0])) {
out.erase(0,1);
}
return out;
}
string V3PreProcImp::defineSubst(V3DefineRef* refp) {
// Substitute out defines in a argumented define reference.
// We could push the define text back into the lexer, but that's slow
// and would make recursive definitions and parameter handling nasty.
//
// Note we parse the definition parameters and value here. If a
// parameterized define is used many, many times, we could cache the
// parametrized define is used many, many times, we could cache the
// parsed result.
UINFO(4,"defineSubstIn `"<<m_defName<<" "<<m_defParams<<endl);
for (unsigned i=0; i<m_defArgs.size(); i++) {
UINFO(4,"defineArg["<<i<<"] = "<<m_defArgs[i]<<endl);
UINFO(4,"defineSubstIn `"<<refp->name()<<" "<<refp->params()<<endl);
for (unsigned i=0; i<refp->args().size(); i++) {
UINFO(4,"defineArg["<<i<<"] = "<<refp->args()[i]<<endl);
}
// Grab value
string value = defValue(m_defName);
UINFO(4,"defineValue `"<<value<<endl);
string value = defValue(refp->name());
UINFO(4,"defineValue '"<<value<<"'"<<endl);
map<string,string> argValueByName;
{ // Parse argument list into map
unsigned numArgs=0;
string argName;
for (const char* cp=m_defParams.c_str(); *cp; cp++) {
for (const char* cp=refp->params().c_str(); *cp; cp++) {
if (*cp=='(') {
} else if (argName=="" && isspace(*cp)) {
} else if (isspace(*cp) || *cp==')' || *cp==',') {
if (argName!="") {
if (m_defArgs.size() >= numArgs) {
argValueByName[argName] = m_defArgs[numArgs];
if (refp->args().size() > numArgs) {
// A call `def( a ) must be equivelent to `def(a ), so trimWhitespace
// Note other sims don't trim trailing whitespace, so we don't either.
argValueByName[argName] = trimWhitespace(refp->args()[numArgs]);
}
numArgs++;
//cout << " arg "<<argName<<endl;
@@ -385,13 +415,13 @@ string V3PreProcImp::defineSubst() {
argName += *cp;
}
}
if (m_defArgs.size() != numArgs) {
fileline()->v3error("Define passed wrong number of arguments: "+m_defName+"\n");
return " `"+m_defName+" ";
if (refp->args().size() != numArgs) {
fileline()->v3error("Define passed wrong number of arguments: "+refp->name()+"\n");
return " `"+refp->name()+" ";
}
}
string out = " ";
string out = "";
{ // Parse substitution define using arguments
string argName;
string prev;
@@ -447,8 +477,7 @@ string V3PreProcImp::defineSubst() {
}
}
out += " ";
UINFO(4,"defineSubstOut "<<out<<endl);
UINFO(4,"defineSubstOut '"<<out<<"'"<<endl);
return out;
}
@@ -533,7 +562,7 @@ int V3PreProcImp::getRawToken() {
if (m_lineAdd) {
m_lineAdd--;
m_rawAtBol = true;
yytext="\n"; yyleng=1;
yytext=(char*)"\n"; yyleng=1;
return (VP_TEXT);
}
if (m_lineCmt!="") {
@@ -565,8 +594,9 @@ int V3PreProcImp::getRawToken() {
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.c_str());
fprintf (stderr, "%d: RAW %s s%d dr%d: %-10s: %s\n",
fileline()->lineno(), m_off?"of":"on", m_state, (int)m_defRefs.size(),
tokenName(tok), buf.c_str());
}
// On EOF, try to pop to upper level includes, as needed.
@@ -651,7 +681,7 @@ int V3PreProcImp::getToken() {
else if (m_stateFor==VP_DEFINE) {
// m_lastSym already set.
m_state = ps_DEFVALUE;
m_lexp->setStateDefValue();
m_lexp->pushStateDefValue();
}
else fileline()->v3fatalSrc("Bad case\n");
goto next_tok;
@@ -698,7 +728,7 @@ int V3PreProcImp::getToken() {
&& isspace(m_lexp->m_defValue[m_lexp->m_defValue.length()-1-trailspace])) trailspace++;
if (trailspace) m_lexp->m_defValue.erase(m_lexp->m_defValue.length()-trailspace,trailspace);
// Define it
UINFO(4,"Define "<<m_lastSym<<" = "<<m_lexp->m_defValue<<endl);
UINFO(4,"Define "<<m_lastSym<<" = '"<<m_lexp->m_defValue<<"'"<<endl);
define(fileline(), m_lastSym, m_lexp->m_defValue, params);
}
} else {
@@ -712,40 +742,57 @@ int V3PreProcImp::getToken() {
}
case ps_DEFPAREN: {
if (tok==VP_TEXT && yyleng==1 && yytext[0]=='(') {
m_defArgs.clear();
m_state = ps_DEFARG;
m_lexp->setStateDefArg();
goto next_tok;
} else {
m_state = ps_TOP;
fileline()->v3error("Expecting ( to begin argument list for define reference `"<<m_defName);
if (m_defRefs.empty()) v3fatalSrc("Shouldn't be in DEFPAREN w/o active defref");
V3DefineRef* refp = &(m_defRefs.top());
fileline()->v3error("Expecting ( to begin argument list for define reference `"<<refp->name());
goto next_tok;
}
}
case ps_DEFARG: {
if (tok==VP_DEFARG) {
UINFO(4," Defarg "<<m_defName<<" arg="<<m_lexp->m_defValue<<endl);
goto next_tok; // Next is a , or )
} else if (tok==VP_TEXT && yyleng==1 && yytext[0]==',') {
m_defArgs.push_back(m_lexp->m_defValue);
if (m_defRefs.empty()) v3fatalSrc("Shouldn't be in DEFARG w/o active defref");
V3DefineRef* refp = &(m_defRefs.top());
refp->nextarg(refp->nextarg()+m_lexp->m_defValue); m_lexp->m_defValue="";
if (tok==VP_DEFARG && yyleng==1 && yytext[0]==',') {
refp->args().push_back(refp->nextarg());
m_state = ps_DEFARG;
m_lexp->setStateDefArg();
m_lexp->pushStateDefArg();
refp->nextarg("");
goto next_tok;
} else if (tok==VP_TEXT && yyleng==1 && yytext[0]==')') {
m_defArgs.push_back(m_lexp->m_defValue);
string out = defineSubst();
m_lexp->m_parenLevel = 0;
} else if (tok==VP_DEFARG && yyleng==1 && yytext[0]==')') {
refp->args().push_back(refp->nextarg());
string out = defineSubst(refp);
// Substitute in and prepare for next action
// Similar code in non-parenthesized define (Search for END_OF_DEFARG)
m_defRefs.pop();
m_lexp->unputString(out.c_str());
// Prepare for next action
m_defArgs.clear();
m_state = ps_TOP;
if (m_defRefs.empty()) {
m_state = ps_TOP;
m_lexp->m_parenLevel = 0;
}
else { // Finished a defref inside a upper defref
refp = &(m_defRefs.top()); // We popped, so new top
m_lexp->m_parenLevel = refp->parenLevel();
m_state = ps_DEFARG;
}
goto next_tok;
} else if (tok==VP_DEFREF) {
// Expand it, then state will come back here
// Value of building argument is data before the lower defref
// we'll append it when we push the argument.
break;
} else if (tok==VP_SYMBOL || tok==VP_STRING || VP_TEXT || VP_WHITE || VP_PSL) {
string rtn; rtn.assign(yytext,yyleng);
refp->nextarg(refp->nextarg()+rtn);
goto next_tok;
} else {
fileline()->v3error("Expecting ) or , to end argument list for define reference. Found: "<<tokenName(tok));
m_state = ps_TOP;
goto next_tok;
}
goto next_tok;
}
case ps_INCNAME: {
if (tok==VP_STRING) {
@@ -763,7 +810,7 @@ int V3PreProcImp::getToken() {
else if (tok==VP_TEXT && yyleng==1 && yytext[0]=='<') {
// include <filename>
m_state = ps_INCNAME; // Still
m_lexp->setStateIncFilename();
m_lexp->pushStateIncFilename();
goto next_tok;
}
else if (tok==VP_DEFREF) {
@@ -844,18 +891,17 @@ int V3PreProcImp::getToken() {
else {
string params = defParams(name);
if (params=="0" || params=="") { // Found, as simple substitution
// Pack spaces around the define value, as there must be token boundaries around it.
// It also makes it more obvious where defines got substituted.
string out = " "+defValue(name)+" ";
UINFO(4,"Defref `"<<name<<" => "<<out<<endl);
string out = defValue(name);
UINFO(4,"Defref `"<<name<<" => '"<<out<<"'"<<endl);
// Similar code in parenthesized define (Search for END_OF_DEFARG)
m_lexp->unputString(out.c_str());
goto next_tok;
}
else { // Found, with parameters
UINFO(4,"Defref `"<<name<<" => parameterized"<<endl);
m_defName = name;
m_defParams = params;
m_defRefs.push(V3DefineRef(name, params, m_lexp->m_parenLevel));
m_state = ps_DEFPAREN; m_stateFor = tok;
m_lexp->pushStateDefArg();
goto next_tok;
}
}
+7
View File
@@ -121,6 +121,13 @@ void V3Read::readFile(FileLine* fileline, const string& modfilename, bool inLibr
m_fileline = new FileLine(fileline);
m_inLibrary = inLibrary;
// Set language standard up front
if (!v3Global.opt.preprocOnly()) {
// Leting lex parse this saves us from having to specially en/decode
// from the V3LangCode to the various Lex BEGIN states.
ppPushText((string)"`begin_keywords \""+v3Global.opt.language().ascii()+"\"\n");
}
// Preprocess into m_ppBuffer
V3PreShell::preproc(fileline, modfilename, this);
+21 -10
View File
@@ -41,6 +41,7 @@
#include "V3Ast.h"
#include "V3EmitCBase.h"
#include "V3Graph.h"
#include "V3LinkLValue.h"
//######################################################################
// Graph subclasses
@@ -360,11 +361,11 @@ private:
else if (portp->isOutput()) {
// Make output variables
// Correct lvalue; we didn't know when we linked
if (AstVarRef* varrefp = pinp->castVarRef()) {
varrefp->lvalue(true);
} else {
pinp->v3warn(TASKNSVAR,"Unsupported: Task output pin connected to non-variable");
}
// This is slightly scary; are we sure no decisions were made
// before here based on this not being a lvalue?
// Doesn't seem so; V3Unknown uses it earlier, but works ok.
V3LinkLValue::linkLValueSet(pinp);
// Even if it's referencing a varref, we still make a temporary
// Else task(x,x,x) might produce incorrect results
AstVarScope* outvscp = createVarScope (portp, namePrefix+"__"+portp->shortName());
@@ -445,11 +446,21 @@ private:
else if (portp->isOutput()) {
// Make output variables
// Correct lvalue; we didn't know when we linked
if (AstVarRef* varrefp = pinp->castVarRef()) {
varrefp->lvalue(true);
} else {
pinp->v3warn(TASKNSVAR,"Unsupported: Task output pin connected to non-variable");
}
// This is slightly scary; are we sure no decisions were made
// before here based on this not being a lvalue?
// Doesn't seem so; V3Unknown uses it earlier, but works ok.
V3LinkLValue::linkLValueSet(pinp);
// Even if it's referencing a varref, we still make a temporary
// Else task(x,x,x) might produce incorrect results
AstVarScope* outvscp = createVarScope (portp, namePrefix+"__"+portp->shortName());
portp->user2p(outvscp);
pinp->replaceWith(new AstVarRef(outvscp->fileline(), outvscp, true));
AstAssign* assp = new AstAssign (pinp->fileline(),
pinp,
new AstVarRef(outvscp->fileline(), outvscp, false));
// Put assignment BEHIND of all other statements
beginp->addNext(assp);
}
}
}
+22 -8
View File
@@ -201,7 +201,10 @@ private:
nodep->lhsp()->widthMin() + nodep->rhsp()->widthMin());
}
if (vup->c()->final()) {
if (!nodep->widthSized()) nodep->v3error("Concat argument must have specific size. (No unsized numbers/parameters).");
if (!nodep->widthSized()) {
// See also error in V3Number
nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in concatenations.");
}
}
}
virtual void visit(AstReplicate* nodep, AstNUser* vup) {
@@ -217,7 +220,10 @@ private:
(nodep->lhsp()->widthMin() * times));
}
if (vup->c()->final()) {
if (!nodep->widthSized()) nodep->v3error("Replication expression must have specific size.");
if (!nodep->widthSized()) {
// See also error in V3Number
nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications.");
}
}
}
virtual void visit(AstRange* nodep, AstNUser* vup) {
@@ -243,15 +249,11 @@ private:
while (huntbackp->backp()->castRange()) huntbackp=huntbackp->backp();
if (huntbackp->backp()->castVar()
&& huntbackp->backp()->castVar()->arraysp()==huntbackp) {
AstNRelinker msbHandle;
AstNRelinker lsbHandle;
msbConstp->unlinkFrBack(&msbHandle);
lsbConstp->unlinkFrBack(&lsbHandle);
msbHandle.relink(lsbConstp);
lsbHandle.relink(msbConstp);
} else {
nodep->v3error("Unsupported: MSB < LSB of bit range: "<<msb<<"<"<<lsb);
}
// Correct it.
swap(msbConstp, lsbConstp);
int x=msb; msb=lsb; lsb=x;
}
int width = msb-lsb+1;
@@ -275,6 +277,10 @@ private:
&& nodep->msbConst() < nodep->lsbConst()) {
nodep->v3error("Unsupported: MSB < LSB of bit extract: "
<<nodep->msbConst()<<"<"<<nodep->lsbConst());
width = (nodep->lsbConst() - nodep->msbConst() + 1);
nodep->width(width,width);
nodep->widthp()->replaceWith(new AstConst(nodep->widthp()->fileline(),
width));
nodep->lsbp()->replaceWith(new AstConst(nodep->lsbp()->fileline(), 0));
}
// We're extracting, so just make sure the expression is at least wide enough.
@@ -720,6 +726,14 @@ private:
bool fixAutoExtend (AstNode*& nodepr, int expWidth);
void fixWidthExtend (AstNode* nodep, int expWidth);
void fixWidthReduce (AstNode* nodep, int expWidth);
void swap (AstNode* ap, AstNode* bp) {
AstNRelinker aHandle;
AstNRelinker bHandle;
ap->unlinkFrBack(&aHandle);
bp->unlinkFrBack(&bHandle);
aHandle.relink(bp);
bHandle.relink(ap);
}
public:
// CONSTUCTORS
+1 -1
View File
@@ -24,7 +24,7 @@
//**********************************************************************
//**** Version and host name
#define DTVERSION "Verilator 3.660 2008/03/23"
#define DTVERSION "Verilator 3.661 2008/04/04"
//**********************************************************************
//**** Functions
+25 -22
View File
@@ -382,7 +382,7 @@ class AstSenTree;
%type<nodep> modItem modItemList modItemListE modOrGenItem
%type<nodep> generateRegion
%type<nodep> genItem genItemList genItemBegin genItemBlock genTopBlock genCaseListE genCaseList
%type<nodep> dlyTerm
%type<nodep> dlyTerm minTypMax
%type<fileline> delay
%type<varp> sigAndAttr sigId sigIdRange sigList regsig regsigList regSigId
%type<varp> netSig netSigList
@@ -429,7 +429,7 @@ class AstSenTree;
%type<nodep> pslDecl
%type<nodep> pslSequence pslSere pslExpr
%start file
%start fileE
%%
//**********************************************************************
@@ -445,8 +445,12 @@ statePop: /* empty */ { V3Read::statePop(); }
//**********************************************************************
// Files
file: description { }
| file description { }
fileE: /* empty */ { }
| file { }
;
file: description { }
| file description { }
;
// IEEE: description
@@ -526,8 +530,8 @@ regsigList: regsig { $$ = $1; }
| regsigList ',' regsig { $$ = $1;$1->addNext($3); }
;
portV2kDecl: varRESET varInput v2kNetDeclE signingE regrangeE portV2kSig { $$ = $6; }
| varRESET varInout v2kNetDeclE signingE regrangeE portV2kSig { $$ = $6; }
portV2kDecl: varRESET varInput v2kVarDeclE signingE regrangeE portV2kSig { $$ = $6; }
| varRESET varInout v2kVarDeclE signingE regrangeE portV2kSig { $$ = $6; }
| varRESET varOutput v2kVarDeclE signingE regrangeE portV2kSig { $$ = $6; }
;
@@ -577,11 +581,8 @@ signingE: /*empty*/ { }
| yUNSIGNED { VARSIGNED(false); }
;
v2kNetDeclE: /*empty*/ { }
v2kVarDeclE: /*empty*/ { }
| varNet { }
;
v2kVarDeclE: v2kNetDeclE { }
| varReg { }
;
@@ -692,9 +693,9 @@ delayE: /* empty */ { }
;
delay: '#' dlyTerm { $$ = $1; } /* ignored */
| '#' '(' dlyInParen ')' { $$ = $1; } /* ignored */
| '#' '(' dlyInParen ',' dlyInParen ')' { $$ = $1; } /* ignored */
| '#' '(' dlyInParen ',' dlyInParen ',' dlyInParen ')' { $$ = $1; } /* ignored */
| '#' '(' minTypMax ')' { $$ = $1; } /* ignored */
| '#' '(' minTypMax ',' minTypMax ')' { $$ = $1; } /* ignored */
| '#' '(' minTypMax ',' minTypMax ',' minTypMax ')' { $$ = $1; } /* ignored */
;
dlyTerm: yaID { $$ = NULL; }
@@ -702,7 +703,9 @@ dlyTerm: yaID { $$ = NULL; }
| yaFLOATNUM { $$ = NULL; }
;
dlyInParen: dlyTerm { } /* ignored */
// IEEE: mintypmax_expression and constant_mintypmax_expression
minTypMax: dlyTerm { $$ = $1; } /* ignored */
| dlyTerm ':' dlyTerm ':' dlyTerm { $$ = $1; } /* ignored */
;
sigAndAttr: sigId sigAttrListE { $$ = $1; }
@@ -1118,14 +1121,14 @@ commaEListE: /* empty */ { $$ = NULL; }
//************************************************
// Gate declarations
gateDecl: yBUF gateBufList ';' { $$ = $2; }
| yNOT gateNotList ';' { $$ = $2; }
| yAND gateAndList ';' { $$ = $2; }
| yNAND gateNandList ';' { $$ = $2; }
| yOR gateOrList ';' { $$ = $2; }
| yNOR gateNorList ';' { $$ = $2; }
| yXOR gateXorList ';' { $$ = $2; }
| yXNOR gateXnorList ';' { $$ = $2; }
gateDecl: yBUF delayE gateBufList ';' { $$ = $3; }
| yNOT delayE gateNotList ';' { $$ = $3; }
| yAND delayE gateAndList ';' { $$ = $3; }
| yNAND delayE gateNandList ';' { $$ = $3; }
| yOR delayE gateOrList ';' { $$ = $3; }
| yNOR delayE gateNorList ';' { $$ = $3; }
| yXOR delayE gateXorList ';' { $$ = $3; }
| yXNOR delayE gateXnorList ';' { $$ = $3; }
;
gateBufList: gateBuf { $$ = $1; }
+1
View File
@@ -18,6 +18,7 @@ execute (
[0] In TOP.v.sub.subblock
[0] In TOP.v.sub2
[0] In TOP.v.sub2.subblock2
[0] Back \ Quote "
[0] %X=0c %D=12 %0X=c %0O=14 %B=001100
[0] %x=0c %d=12 %0x=c %0o=14 %b=001100
[0] %x=00abbbbcccc %0x=abbbbcccc %o=00527356746314 %b=00000101010111011101110111100110011001100
+3
View File
@@ -19,6 +19,9 @@ module t;
sub.write_m;
sub2.write_m;
// Escapes
$display("[%0t] Back \\ Quote \"", $time); // Old bug when \" last on the line.
// Display formatting
$display("[%0t] %%X=%X %%D=%D %%0X=%0X %%0O=%0O %%B=%B", $time,
quad[5:0], quad[5:0], quad[5:0], quad[5:0], quad[5:0]);
+1
View File
@@ -21,6 +21,7 @@ execute (
[0] In TOP.v.sub.subblock
[0] In TOP.v.sub2
[0] In TOP.v.sub2.subblock2
[0] Back \ Quote "
[0] %X=0c %D=12 %0X=c %0O=14 %B=001100
[0] %x=0c %d=12 %0x=c %0o=14 %b=001100
[0] %x=00abbbbcccc %0x=abbbbcccc %o=00527356746314 %b=00000101010111011101110111100110011001100
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
compile (
verilator_flags2 => ['--language 1364-2001'],
);
execute (
check_finished=>1,
);
ok(1);
1;
+17
View File
@@ -0,0 +1,17 @@
// $Id$
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2008 by Wilson Snyder.
module t (/*AUTOARG*/);
// See also t_preproc_kwd.v
integer bit; initial bit = 1;
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id$
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2008 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
compile (
v_flags2 => ["--lint-only"],
fails=>$Last_Self->{v3},
expect=>
'%Error: No top level module found
%Error: Exiting due to',
) if $Last_Self->{v3};
ok(1);
1;
+7
View File
@@ -0,0 +1,7 @@
// $Id$
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2008 by Wilson Snyder.
`define EMPTY 1
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id$
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2008 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
compile (
v_flags2 => ["--top-module b"],
) if $Last_Self->{v3};
execute (
check_finished=>1,
) if $Last_Self->{v3};
ok(1);
1;
+32
View File
@@ -0,0 +1,32 @@
// $Id$
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2008 by Wilson Snyder.
module a;
c c ();
initial begin
$write("Bad top modules\n");
$stop;
end
endmodule
module b;
d d ();
endmodule
module c;
initial begin
$write("Bad top modules\n");
$stop;
end
endmodule
module d;
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id$
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2008 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
top_filename("t/t_flag_topmodule.v");
compile (
fails=>$Last_Self->{v3},
nc=>0, # Need to get it not to give the prompt
expect=>
'%Error-MULTITOP: t/t_flag_topmodule.v:\d+: Unsupported: Multiple top level modules: .*
%Error-MULTITOP: t/t_flag_topmodule.v:\d+: Fix, or use --top-module option to select which you want.
%Error: Exiting due to.*',
) if $Last_Self->{v3};
ok(1);
1;
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id$
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2008 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
top_filename("t/t_flag_topmodule.v");
compile (
fails=>$Last_Self->{v3},
v_flags2 => ["--top-module notfound"],
nc=>0, # Need to get it not to give the prompt
expect=>
'%Error: Specified --top-module \'notfound\' was not found in design.
%Error: Exiting due to.*',
) if $Last_Self->{v3};
ok(1);
1;
+13 -4
View File
@@ -7,6 +7,7 @@
module t;
reg [2:0] value;
reg [31:0] global;
reg [31:0] vec [1:0];
initial begin
global = 1;
@@ -32,14 +33,22 @@ module t;
nil_task(32'h012,32'h112,global);
if (global !== 32'h124) $stop;
vec[0] = 32'h333;
vec[1] = 32'habc;
incr(vec[1],vec[0],vec[1]);
if (vec[0] != 32'h333) $stop;
if (vec[1] != 32'hdef) $stop;
incr(vec[2],vec[0],vec[2]); // Reading/Writing past end of vector!
$write("*-* All Finished *-*\n");
$finish;
end
function [2:0] add;
input [2:0] from;
input [2:0] fromv;
begin
add = from + 3'd1;
add = fromv + 3'd1;
begin : named
reg [31:0] flocal;
flocal = 1;
@@ -49,13 +58,13 @@ module t;
endfunction
function [3:0] munge4;
input [3:0] from; // Different from the 'from' signal above
input [3:0] fromv; // Different fromv than the 'fromv' signal above
reg one;
begin : named
reg [1:0] flocal;
// Function calling a function
one = 1'b1;
munge4 = {one, add(from[2:0])};
munge4 = {one, add(fromv[2:0])};
end
endfunction
-1
View File
@@ -14,7 +14,6 @@ compile (
'%Error: t/t_func_bad.v:\d+: Too few arguments in function call
%Error: t/t_func_bad.v:\d+: Too many arguments in function call
%Error: t/t_func_bad.v:\d+: Too few arguments in function call
%Error-TASKNSVAR: t/t_func_bad.v:\d+: Unsupported: Task output pin connected to non-variable
%Error: t/t_func_bad.v:\d+: Outputs not allowed in function declarations
%Error: Exiting due to',
);
@@ -8,13 +8,11 @@ if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# General Public License or the Perl Artistic License.
compile (
fails=>$Last_Self->{v3},
nc=>0, # Need to get it not to give the prompt
expect=>
'%Error-MULTITOP: t/t_mod_bad_twotop.v:\d+: Unsupported: Multiple top level modules: t2 and t
%Error: Exiting due to.*',
);
execute (
check_finished=>1,
);
ok(1);
1;
+97
View File
@@ -0,0 +1,97 @@
// $Id$
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2003 by Wilson Snyder.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc=0;
reg [63:0] crc;
reg [63:0] sum;
reg rst_n;
// Take CRC data and apply to testblock inputs
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [2:0] pos; // From test of Test.v
// End of automatics
Test test (
// Outputs
.pos (pos[2:0]),
/*AUTOINST*/
// Inputs
.clk (clk),
.rst_n (rst_n));
// Aggregate outputs into a single result vector
wire [63:0] result = {61'h0, pos};
// What checksum will we end up with
`define EXPECTED_SUM 64'h039ea4d039c2e70b
// 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]};
rst_n <= ~1'b0;
if (cyc==0) begin
// Setup
crc <= 64'h5aef0c8d_d70a4497;
rst_n <= ~1'b1;
end
else if (cyc<10) begin
sum <= 64'h0;
rst_n <= ~1'b1;
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;
if (sum !== `EXPECTED_SUM) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module Test
#(parameter SAMPLE_WIDTH = 4 )
(
`ifdef verilator // UNSUPPORTED
output reg [2:0] pos,
`else
output reg [log2(SAMPLE_WIDTH)-1:0] pos,
`endif
// System
input clk,
input rst_n
);
function integer log2(input integer arg);
begin
for(log2=0; arg>0; log2=log2+1)
arg = (arg >> 1);
end
endfunction
always @ (posedge clk or negedge rst_n)
if (!rst_n) begin
pos <= 0;
end
else begin
pos <= pos + 1;
end
endmodule
+2 -2
View File
@@ -20,8 +20,8 @@ module t (/*AUTOARG*/
// verilator lint_off IMPLICIT
not NT0 (nt0, a[0]);
and AN0 (an0, a[0], b[0]);
nand ND0 (nd0, a[0], b[0], b[1]);
and #1 AN0 (an0, a[0], b[0]);
nand #(2,3,4) ND0 (nd0, a[0], b[0], b[1]);
or OR0 (or0, a[0], b[0]);
nor NR0 (nr0, a[0], b[0], b[2]);
xor (xo0, a[0], b[0]);
-19
View File
@@ -1,19 +0,0 @@
// $Id:$
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2003 by Wilson Snyder.
module t;
initial begin
$write("Two top modules\n");
$stop;
end
endmodule
module t2;
initial begin
$write("Two top modules\n");
$stop;
end
endmodule
+19
View File
@@ -0,0 +1,19 @@
#!/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 (
verilator_flags2 => ["--Wno-WIDTHCONCAT"],
);
execute (
check_finished=>1,
);
ok(1);
1;
+28
View File
@@ -0,0 +1,28 @@
// $Id$
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2005 by Wilson Snyder.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
parameter UNSIZED = 10;
integer cyc=1;
always @ (posedge clk) begin
cyc <= cyc + 1;
if (cyc==1) begin
if ({UNSIZED,UNSIZED+1} != {32'd10, 32'd11}) $stop;
if ({2{UNSIZED}} != {32'd10, 32'd10}) $stop;
end
if (cyc==9) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
+24
View File
@@ -0,0 +1,24 @@
#!/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.
top_filename("t/t_param_concat.v");
compile (
fails=>1,
expect=>
'%Warning-WIDTHCONCAT: t/t_param_concat.v:\d+: Unsized numbers/parameters not allowed in concatenations.
%Warning-WIDTHCONCAT: Use "/\* verilator lint_off WIDTHCONCAT \*/" and lint_on around source to disable this message.
%Warning-WIDTHCONCAT: t/t_param_concat.v:\d+: Unsized numbers/parameters not allowed in replications.
%Warning-WIDTHCONCAT: t/t_param_concat.v:\d+: Unsized numbers/parameters not allowed in concatenations.
%Warning-WIDTHCONCAT: t/t_param_concat.v:\d+: Unsized numbers/parameters not allowed in replications.
%Error: Exiting due to.*',
);
ok(1);
1;
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id: t_delay.pl 965 2007-10-31 20:29:07Z wsnyder $
# 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,
expect=>quotemeta(
'pre thrupre thrumid thrupost post: "right side"
left side: "right side"
left side : "right side "
left_side : "left_side "
na : "left_side "
prep ( midp1 left_side midp2 ( outp ) ) : "left_side "
na: "nana"
left_side left_side : "left_side left_side "
: ""
left side: "right side"
left side : "right side "
twoline: "first second"
*-* All Finished *-*
'));
ok(1);
1;
+56
View File
@@ -0,0 +1,56 @@
// $Id: t_delay.v 965 2007-10-31 20:29:07Z wsnyder $
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2008 by Wilson Snyder.
module t;
wire d1 = 1'b1;
wire d2 = 1'b1;
wire d3 = 1'b1;
wire o1,o2,o3;
add1 add1 (d1,o1);
add2 add2 (d2,o2);
`define ls left_side
`define rs left_side
`define noarg na
`define thru(x) x
`define thruthru `ls `rs // Doesn't expand
`define msg(x,y) `"x: `\`"y`\`"`"
initial begin
//$display(`msg( \`, \`)); // Illegal
$display(`msg(pre `thru(thrupre `thru(thrumid) thrupost) post,right side));
$display(`msg(left side,right side));
$display(`msg( left side , right side ));
$display(`msg( `ls , `rs ));
$display(`msg( `noarg , `rs ));
$display(`msg( prep ( midp1 `ls midp2 ( outp ) ) , `rs ));
$display(`msg(`noarg,`noarg`noarg));
$display(`msg( `thruthru , `thruthru )); // Results vary between simulators
$display(`msg(`thru(),)); // Empty
$display(`msg(`thru(left side),`thru(right side)));
$display(`msg( `thru( left side ) , `thru( right side ) ));
`define twoline first \
second
$display(`msg(twoline, `twoline));
//$display(`msg(left side, \ right side \ )); // Not sure \{space} is legal.
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
`define ADD_UP(a,c) \
wire tmp_``a = a; \
wire tmp_``c = tmp_``a + 1; \
assign c = tmp_``c ;
module add1 ( input wire d1, output wire o1);
`ADD_UP(d1,o1) // expansion is OK
endmodule
module add2 ( input wire d2, output wire o2);
`ADD_UP( d2 , o2 ) // expansion is bad
endmodule
// `ADD_UP( \d3 , \o3 ) // This really is illegal
+28 -19
View File
@@ -15,7 +15,7 @@
At file t/t_preproc_inc2.v line 4
`line 6 "t/t_preproc_inc2.v" 0
`line 1 "t/t_preproc_inc3.v" 1
`line 2 "inc3_a_filename_from_line_directive" 0
@@ -41,7 +41,7 @@ At file t/t_preproc_inc2.v line 4
`line 18 "inc3_a_filename_from_line_directive" 2
`line 6 "t/t_preproc_inc2.v" 0
`line 7 "t/t_preproc_inc2.v" 2
`line 9 "t/t_preproc.v" 0
@@ -78,8 +78,8 @@ text.
foo bar
foobar2
foo bar
foobar2
@@ -91,7 +91,7 @@ text.
first part second part third part
first part second part third part
Line_Preproc_Check 49
@@ -100,37 +100,46 @@ Line_Preproc_Check 49
deep deep
deep deep
"Inside: `nosubst"
"`nosubst"
"`nosubst"
x y LLZZ x y
p q LLZZ p q r s LLZZ r s LLZZ p q LLZZ p q r s LLZZ r s
x y LLZZ x y
p q LLZZ p q r s LLZZ r s LLZZ p q LLZZ p q r s LLZZ r s
firstline comma","line LLZZ firstline comma","line
firstline comma","line LLZZ firstline comma","line
x y LLZZ "a" y
x y LLZZ "a" y
(a,b) (a,b)
(a,b)(a,b)
$display( "left side: \" right side\"" )
$display("left side: \"right side\"")
bar_suffix
bar_suffix
$c("Zap(\"",bug1,"\");"); ;
$c("Zap(\"","bug2","\");"); ;
$c("Zap(\"",bug1,"\");");;
$c("Zap(\"","bug2","\");");;
wire tmp_d1 = d1; wire tmp_o1 = tmp_d1 + 1; assign o1 = tmp_o1 ;
wire tmp_d2 = d2 ; wire tmp_o2 = tmp_d2 + 1; assign o2 = tmp_o2 ;
@@ -139,7 +148,7 @@ $display( "left side: \" right side\"" )
`line 95 "t/t_preproc.v" 0
`line 104 "t/t_preproc.v" 0
Line_Preproc_Check 96
`line 97 "t/t_preproc.v" 2
Line_Preproc_Check 105
`line 106 "t/t_preproc.v" 2
+9
View File
@@ -86,6 +86,15 @@ $display(`msg(left side, right side))
`zap(bug1);
`zap("bug2");
// rt.cpan.org bug34429
`define ADD_UP(a,c) \
wire tmp_``a = a; \
wire tmp_``c = tmp_``a + 1; \
assign c = tmp_``c ;
`ADD_UP(d1,o1) // expansion is OK
`ADD_UP( d2 , o2 ) // expansion is bad
//===========================================================================
// Ifdef
+1 -1
View File
@@ -63,7 +63,7 @@ Hello in t_preproc_psl.v
psl assert always cyc !=10;
psl assert always cyc!=10;
`psl
+3 -2
View File
@@ -1,6 +1,6 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id:$
# $Id$
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
@@ -10,7 +10,8 @@ if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
compile (
fails=>1,
expect=>
'%Error: t/t_select_bad_msb.v:\d+: Unsupported: MSB < LSB of bit extract.*
'%Error: t/t_select_bad_msb.v:\d+: Unsupported: MSB < LSB of bit range: 0<22
%Error: t/t_select_bad_msb.v:\d+: Unsupported: MSB < LSB of bit extract: 1<4
%Error: Exiting due to.*',
) if $Last_Self->{v3};
+1
View File
@@ -9,6 +9,7 @@ module t (clk);
reg [43:0] mi;
reg [3:0] sel2;
reg [0:22] backwd;
always @ (posedge clk) begin
mi = 44'h123;