mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a9bea6980 | ||
|
|
bfddd80f43 | ||
|
|
84a778719a | ||
|
|
829d80d5b5 | ||
|
|
d6a5c97f3a | ||
|
|
4ba00bd256 | ||
|
|
c18f9da400 | ||
|
|
5b620a8dc5 | ||
|
|
9c968c590c | ||
|
|
dff5d5c4e4 | ||
|
|
1265e8cce8 | ||
|
|
2b5d7eeb50 |
@@ -3,6 +3,18 @@ Revision history for Verilator
|
|||||||
The contributors that suggested a given feature are shown in []. [by ...]
|
The contributors that suggested a given feature are shown in []. [by ...]
|
||||||
indicates the contributor was also the author of the fix; Thanks!
|
indicates the contributor was also the author of the fix; Thanks!
|
||||||
|
|
||||||
|
* Verilator 3.652 6/21/2007
|
||||||
|
|
||||||
|
**** Report as many warning types as possible before exiting.
|
||||||
|
|
||||||
|
**** Support V2K portlists with "input a,b,...". [Mark Nodine]
|
||||||
|
|
||||||
|
**** Support V2K function/task argument lists.
|
||||||
|
|
||||||
|
**** Optimize constant $display arguments.
|
||||||
|
|
||||||
|
**** Fix Preprocessor dropping some `line directives. [Mark Nodine]
|
||||||
|
|
||||||
* Verilator 3.651 5/22/2007
|
* Verilator 3.651 5/22/2007
|
||||||
|
|
||||||
*** Added verilator_profcfunc utility. [Gene Weber]
|
*** Added verilator_profcfunc utility. [Gene Weber]
|
||||||
|
|||||||
+88
-3
@@ -214,6 +214,66 @@ C++, and linked with the Verilated files.
|
|||||||
|
|
||||||
The resulting executable will perform the actual simulation.
|
The resulting executable will perform the actual simulation.
|
||||||
|
|
||||||
|
=head1 ARGUMENT SUMMARY
|
||||||
|
|
||||||
|
This is a short summary of the arguments to Verilator. See the detailed
|
||||||
|
descriptions in the next sections for more information.
|
||||||
|
|
||||||
|
{file.v} Verilog top level filenames
|
||||||
|
{file.c/cc/cpp} Optional C++ files to link in
|
||||||
|
|
||||||
|
--assert Enable all assertions
|
||||||
|
--bin <filename> Override Verilator binary
|
||||||
|
--cc Create C++ output
|
||||||
|
--compiler <compiler-name> Tune for specified C++ compiler
|
||||||
|
--coverage Enable all coverage
|
||||||
|
--coverage-line Enable line coverage
|
||||||
|
--coverage-user Enable PSL/SVL user coverage
|
||||||
|
-D<var>[=<value>] Set preprocessor define
|
||||||
|
--debug Enable debugging
|
||||||
|
--debug-check Enable debugging assertions
|
||||||
|
--dump-tree Enable dumping .tree files
|
||||||
|
-E Preprocess, but do not compile
|
||||||
|
--exe Link to create executable
|
||||||
|
-f <file> Parse options from a file
|
||||||
|
--help Display this help.
|
||||||
|
-I<dir> Directory to search for includes
|
||||||
|
--inhibit-sim Create function to turn off sim
|
||||||
|
--inline-mult <value> Tune module inlining
|
||||||
|
--lint-only Lint, but do not make output
|
||||||
|
--MMD Create .d dependency files
|
||||||
|
--MP Create phony dependency targets
|
||||||
|
--Mdir <directory> Name of output object directory
|
||||||
|
--mod-prefix <topname> Name to prepend to lower classes
|
||||||
|
--no-skip-identical Disable skipping identical output
|
||||||
|
-O0 Disable optimizations
|
||||||
|
-O3 High performance optimizations
|
||||||
|
-O<optimization-letter> Selectable optimizations
|
||||||
|
--output-split <bytes> Split .cpp files into pieces
|
||||||
|
--output-split-cfuncs <statements> Split .ccp functions
|
||||||
|
--pins64 Use uint64_t's for 33-64 bit sigs
|
||||||
|
--prefix <topname> Name of top level class
|
||||||
|
--profile-cfuncs Name functions for profiling
|
||||||
|
--private Debugging; see docs
|
||||||
|
--psl Enable PSL parsing
|
||||||
|
--public Debugging; see docs
|
||||||
|
--sc Create SystemC output
|
||||||
|
--sp Create SystemPerl output
|
||||||
|
--stats Create statistics file
|
||||||
|
--trace Enable waveform creation
|
||||||
|
--trace-depth <levels> Depth of tracing
|
||||||
|
-U<var> Undefine preprocessor define
|
||||||
|
--underline-zero Zero signals with leading _'s
|
||||||
|
-v <filename> Verilog library
|
||||||
|
-Werror-<message> Convert warning to error
|
||||||
|
-Wno-<message> Disable warning
|
||||||
|
-x-assign <mode> Initially assign Xs to this value
|
||||||
|
-y <dir> Directory to search for modules
|
||||||
|
|
||||||
|
+define+<var>+<value> Set preprocessor define
|
||||||
|
+incdir+<dir> Directory to search for includes
|
||||||
|
+libext+<ext>+[ext]... Extensions for finding modules
|
||||||
|
|
||||||
=head1 ARGUMENTS
|
=head1 ARGUMENTS
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
@@ -320,6 +380,12 @@ internal assertions, debugging messages, and intermediate form dump files.
|
|||||||
Rarely needed. Enable internal debugging assertion checks, without
|
Rarely needed. Enable internal debugging assertion checks, without
|
||||||
changing debug verbosity. Enabled automatically when --debug specified.
|
changing debug verbosity. Enabled automatically when --debug specified.
|
||||||
|
|
||||||
|
=item --dump-tree
|
||||||
|
|
||||||
|
Rarely needed. Enable writing .tree debug files. This is enabled with
|
||||||
|
--debug, so "--debug --no-dump-tree" may be useful if the dump files are
|
||||||
|
large and not desired.
|
||||||
|
|
||||||
=item -E
|
=item -E
|
||||||
|
|
||||||
Preprocess the source code, but do not compile, as with 'gcc -E'. Output
|
Preprocess the source code, but do not compile, as with 'gcc -E'. Output
|
||||||
@@ -577,7 +643,7 @@ We'll compile this example into C++.
|
|||||||
int main(int argc, char **argv, char **env) {
|
int main(int argc, char **argv, char **env) {
|
||||||
Vour* top = new Vour;
|
Vour* top = new Vour;
|
||||||
while (!Verilated::gotFinish()) { top->eval(); }
|
while (!Verilated::gotFinish()) { top->eval(); }
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@@ -637,7 +703,7 @@ This is an example similar to the above, but using SystemPerl.
|
|||||||
top = new Vour("top"); // SP_CELL (top, Vour);
|
top = new Vour("top"); // SP_CELL (top, Vour);
|
||||||
top->clk(clk); // SP_PIN (top, clk, clk);
|
top->clk(clk); // SP_PIN (top, clk, clk);
|
||||||
while (!Verilated::gotFinish()) { sc_start(1); }
|
while (!Verilated::gotFinish()) { sc_start(1); }
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@@ -1195,7 +1261,7 @@ lint_restore*/. For example:
|
|||||||
If SOME_WARNING was on before the lint_off, it will now be restored to on,
|
If SOME_WARNING was on before the lint_off, it will now be restored to on,
|
||||||
and if it was off before the lint_off it will remain off.
|
and if it was off before the lint_off it will remain off.
|
||||||
|
|
||||||
=item /*verilator no_inline_task*/
|
=item /*verilator no_inline_task*/
|
||||||
|
|
||||||
Used in a function or task variable definition section to specify the
|
Used in a function or task variable definition section to specify the
|
||||||
function or task should not be inlined into where it is used. This may
|
function or task should not be inlined into where it is used. This may
|
||||||
@@ -1870,6 +1936,25 @@ so your simulator shouldn't have to be -- and Verilator is closer to the
|
|||||||
synthesis interpretation, so this is a good thing for getting working
|
synthesis interpretation, so this is a good thing for getting working
|
||||||
silicon.
|
silicon.
|
||||||
|
|
||||||
|
=item May programs I create with Verilator remain under my own copyright?
|
||||||
|
|
||||||
|
Yes, it's just like using GCC on your programs. If you change Verilator
|
||||||
|
itself, you must make the source code available under the GNU Public
|
||||||
|
License. However, the include and generated files use the GNU Lesser
|
||||||
|
Public License, which means that files using them are NOT required to be released.
|
||||||
|
|
||||||
|
You also have the option of using the Perl Artistic License, which again
|
||||||
|
does not require you release your Verilog or generated code.
|
||||||
|
|
||||||
|
=item Why is running Verilator so slow?
|
||||||
|
|
||||||
|
Verilator needs more memory then the resulting simulator will require, as
|
||||||
|
Verilator creates internally all of the state of the resulting simulator in
|
||||||
|
order to optimize it. If it takes more then a minute or so (and you're not
|
||||||
|
using --debug), see if your machine is paging; most likely you need to run
|
||||||
|
it on a machine with more memory. Verilator is a full 64 bit application
|
||||||
|
and may use more then 4GB, but about 1GB is the maximum typically needed.
|
||||||
|
|
||||||
=item How do I generate waveforms (traces) in C++?
|
=item How do I generate waveforms (traces) in C++?
|
||||||
|
|
||||||
See the next question for SystemC mode.
|
See the next question for SystemC mode.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// General Public License or the Perl Artistic License.
|
// Lesser General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
// Verilator is distributed in the hope that it will be useful,
|
// Verilator is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Global variables
|
// Global variables
|
||||||
|
|
||||||
int Verilated::s_randReset = false;
|
int Verilated::s_randReset = 0;
|
||||||
int Verilated::s_debug = 1;
|
int Verilated::s_debug = 1;
|
||||||
bool Verilated::s_calcUnusedSigs = false;
|
bool Verilated::s_calcUnusedSigs = false;
|
||||||
bool Verilated::s_gotFinish = false;
|
bool Verilated::s_gotFinish = false;
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// General Public License or the Perl Artistic License.
|
// Lesser General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
// Verilator is distributed in the hope that it will be useful,
|
// Verilator is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||||
# redistribute it and/or modify it under the terms of either the GNU
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
# General Public License or the Perl Artistic License.
|
# Lesser General Public License or the Perl Artistic License.
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
PERL = @PERL@
|
PERL = @PERL@
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// General Public License or the Perl Artistic License.
|
// Lesser General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
// This is distributed in the hope that it will be useful,
|
// This is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// General Public License or the Perl Artistic License.
|
// Lesser General Public License or the Perl Artistic License.
|
||||||
//
|
//
|
||||||
// Verilator is distributed in the hope that it will be useful,
|
// Verilator is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ private:
|
|||||||
AstNode* timesp = nodep->exprsp(); if (timesp) timesp->unlinkFrBack();
|
AstNode* timesp = nodep->exprsp(); if (timesp) timesp->unlinkFrBack();
|
||||||
timesp = timesp->addNext(new AstTime(nodep->fileline()));
|
timesp = timesp->addNext(new AstTime(nodep->fileline()));
|
||||||
nodep->exprsp(timesp);
|
nodep->exprsp(timesp);
|
||||||
|
if (!nodep->scopeNamep() && nodep->name().find("%m") != string::npos) {
|
||||||
|
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode* newIfAssertOn(AstNode* nodep) {
|
AstNode* newIfAssertOn(AstNode* nodep) {
|
||||||
|
|||||||
+18
-5
@@ -1271,11 +1271,8 @@ public:
|
|||||||
bool addNewline() const { return displayType().addNewline(); } // * = Add a newline for $display
|
bool addNewline() const { return displayType().addNewline(); } // * = Add a newline for $display
|
||||||
AstNode* filep() const { return op2p(); }
|
AstNode* filep() const { return op2p(); }
|
||||||
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
|
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
|
||||||
AstNode* scopeAttrp() const { return op3p(); }
|
AstScopeName* scopeNamep() const { return op3p()->castScopeName(); }
|
||||||
AstText* scopeTextp() const { return op3p()->castText(); }
|
void scopeNamep(AstNode* nodep) { setNOp3p(nodep); }
|
||||||
void scopeAttrp(AstNode* nodep) { addOp3p(nodep); }
|
|
||||||
bool needScopeTracking() { return (displayType().needScopeTracking()
|
|
||||||
|| name().find("%m") != string::npos); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AstFClose : public AstNodeStmt {
|
struct AstFClose : public AstNodeStmt {
|
||||||
@@ -1726,6 +1723,22 @@ public:
|
|||||||
int dimension() const { return m_dimension; }
|
int dimension() const { return m_dimension; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AstScopeName : public AstNode {
|
||||||
|
// For display %m
|
||||||
|
// Parents: DISPLAY
|
||||||
|
// Children: TEXT
|
||||||
|
AstScopeName(FileLine* fl)
|
||||||
|
: AstNode(fl) {}
|
||||||
|
virtual ~AstScopeName() {}
|
||||||
|
virtual AstType type() const { return AstType::SCOPENAME;}
|
||||||
|
virtual AstNode* clone() { return new AstScopeName(*this); }
|
||||||
|
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||||
|
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||||
|
virtual bool same(AstNode* samep) const { return true; }
|
||||||
|
AstText* scopeAttrp() const { return op1p()->castText(); }
|
||||||
|
void scopeAttrp(AstNode* nodep) { addOp1p(nodep); }
|
||||||
|
};
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// non-ary ops
|
// non-ary ops
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -131,10 +131,10 @@ private:
|
|||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
nodep->deleteTree(); nodep=NULL;
|
nodep->deleteTree(); nodep=NULL;
|
||||||
}
|
}
|
||||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||||
// Similar code in V3Inline
|
// Similar code in V3Inline
|
||||||
if (m_beginScope != "" && nodep->needScopeTracking()) {
|
if (m_beginScope != "") {
|
||||||
// To keep correct visual order, must add before other Text's
|
// To keep correct visual order, must add before other Text's
|
||||||
AstNode* afterp = nodep->scopeAttrp();
|
AstNode* afterp = nodep->scopeAttrp();
|
||||||
if (afterp) afterp->unlinkFrBackWithNext();
|
if (afterp) afterp->unlinkFrBackWithNext();
|
||||||
|
|||||||
@@ -196,6 +196,9 @@ private:
|
|||||||
virtual void visit(AstText* nodep, AstNUser*) {
|
virtual void visit(AstText* nodep, AstNUser*) {
|
||||||
setClean (nodep, true);
|
setClean (nodep, true);
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||||
|
setClean (nodep, true);
|
||||||
|
}
|
||||||
virtual void visit(AstSel* nodep, AstNUser*) {
|
virtual void visit(AstSel* nodep, AstNUser*) {
|
||||||
operandTriop(nodep);
|
operandTriop(nodep);
|
||||||
setClean (nodep, nodep->cleanOut());
|
setClean (nodep, nodep->cleanOut());
|
||||||
|
|||||||
+63
-1
@@ -802,7 +802,12 @@ private:
|
|||||||
if (nodep->sensp()->castConst()
|
if (nodep->sensp()->castConst()
|
||||||
|| (nodep->varrefp() && nodep->varrefp()->varp()->isParam())) {
|
|| (nodep->varrefp() && nodep->varrefp()->varp()->isParam())) {
|
||||||
// Constants in sensitivity lists may be removed (we'll simplify later)
|
// Constants in sensitivity lists may be removed (we'll simplify later)
|
||||||
AstSenItem* newp = new AstSenItem(nodep->fileline(), AstSenItem::Never());
|
AstSenItem* newp;
|
||||||
|
if (nodep->isClocked()) { // A constant can never get a pos/negexge
|
||||||
|
newp = new AstSenItem(nodep->fileline(), AstSenItem::Never());
|
||||||
|
} else { // Otherwise it may compute a result that needs to settle out
|
||||||
|
newp = new AstSenItem(nodep->fileline(), AstSenItem::Combo());
|
||||||
|
}
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
nodep->deleteTree(); nodep=NULL;
|
nodep->deleteTree(); nodep=NULL;
|
||||||
} else if (nodep->sensp()->castNot()) {
|
} else if (nodep->sensp()->castNot()) {
|
||||||
@@ -938,6 +943,63 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||||
|
// Substitute constants into displays. The main point of this is to
|
||||||
|
// simplify assertion methodologies which call functions with display's.
|
||||||
|
// This eliminates a pile of wide temps, and makes the C a whole lot more readable.
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
bool anyconst = false;
|
||||||
|
for (AstNode* argp = nodep->exprsp(); argp; argp=argp->nextp()) {
|
||||||
|
if (argp->castConst()) { anyconst=true; break; }
|
||||||
|
}
|
||||||
|
if (anyconst) {
|
||||||
|
//UINFO(9," Display in "<<nodep->text()<<endl);
|
||||||
|
string dispout = "";
|
||||||
|
string fmt = "";
|
||||||
|
bool inPct = false;
|
||||||
|
AstNode* argp = nodep->exprsp();
|
||||||
|
for (const char* inp = nodep->text().c_str(); *inp; inp++) {
|
||||||
|
char ch = *inp; // Breaks with iterators...
|
||||||
|
if (!inPct && ch=='%') {
|
||||||
|
inPct = true;
|
||||||
|
fmt = ch;
|
||||||
|
} else if (inPct && isdigit(ch)) {
|
||||||
|
fmt += ch;
|
||||||
|
} else if (inPct) {
|
||||||
|
inPct = false;
|
||||||
|
fmt += ch;
|
||||||
|
switch (tolower(ch)) {
|
||||||
|
case '%': break; // %% - just output a %
|
||||||
|
case 'm': break; // %m - auto insert "name"
|
||||||
|
default: // Most operators, just move to next argument
|
||||||
|
if (argp) {
|
||||||
|
AstNode* nextp=argp->nextp();
|
||||||
|
if (argp && argp->castConst()) { // Convert it
|
||||||
|
string out = argp->castConst()->num().displayed(fmt);
|
||||||
|
UINFO(9," DispConst: "<<fmt<<" -> "<<out<<" for "<<argp<<endl);
|
||||||
|
{ // fmt = out w/ replace % with %% as it must be literal.
|
||||||
|
fmt = "";
|
||||||
|
for (string::iterator pos = out.begin(); pos != out.end(); pos++) {
|
||||||
|
if (*pos == '%') fmt += '%';
|
||||||
|
fmt += *pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argp->unlinkFrBack()->deleteTree();
|
||||||
|
}
|
||||||
|
argp=nextp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} // switch
|
||||||
|
dispout += fmt;
|
||||||
|
} else {
|
||||||
|
dispout += ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nodep->text(dispout);
|
||||||
|
//UINFO(9," Display out "<<nodep->text()<<endl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void visit(AstWhile* nodep, AstNUser*) {
|
virtual void visit(AstWhile* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
if (nodep->condp()->isZero()) {
|
if (nodep->condp()->isZero()) {
|
||||||
|
|||||||
+4
-3
@@ -388,7 +388,7 @@ public:
|
|||||||
}
|
}
|
||||||
virtual void visit(AstMulS* nodep, AstNUser* vup) {
|
virtual void visit(AstMulS* nodep, AstNUser* vup) {
|
||||||
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
|
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
|
||||||
nodep->v3error("Signed multiply of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h\n");
|
nodep->v3error("Unsupported: Signed multiply of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h\n");
|
||||||
}
|
}
|
||||||
visit(nodep->castNodeBiop(), vup);
|
visit(nodep->castNodeBiop(), vup);
|
||||||
}
|
}
|
||||||
@@ -1052,16 +1052,17 @@ void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
|
|||||||
// Spec: h d o b c l
|
// Spec: h d o b c l
|
||||||
case 'b': displayArg(nodep,&elistp,fmt,'b'); break;
|
case 'b': displayArg(nodep,&elistp,fmt,'b'); break;
|
||||||
case 'c': displayArg(nodep,&elistp,fmt,'c'); break;
|
case 'c': displayArg(nodep,&elistp,fmt,'c'); break;
|
||||||
|
case 't':
|
||||||
case 'd': displayArg(nodep,&elistp,fmt,'u'); break; // Unsigned decimal
|
case 'd': displayArg(nodep,&elistp,fmt,'u'); break; // Unsigned decimal
|
||||||
case 'o': displayArg(nodep,&elistp,fmt,'o'); break;
|
case 'o': displayArg(nodep,&elistp,fmt,'o'); break;
|
||||||
case 'h':
|
case 'h':
|
||||||
case 'x': displayArg(nodep,&elistp,fmt,'x'); break;
|
case 'x': displayArg(nodep,&elistp,fmt,'x'); break;
|
||||||
case 's': displayArg(nodep,&elistp,fmt,'s'); break;
|
case 's': displayArg(nodep,&elistp,fmt,'s'); break;
|
||||||
case 't': displayArg(nodep,&elistp,fmt,'u'); break;
|
|
||||||
case 'm': {
|
case 'm': {
|
||||||
emitDispState.pushFormat("%s");
|
emitDispState.pushFormat("%s");
|
||||||
emitDispState.pushArg(NULL, "vlSymsp->name(");
|
emitDispState.pushArg(NULL, "vlSymsp->name(");
|
||||||
for (AstText* textp=nodep->scopeTextp(); textp; textp=textp->nextp()->castText()) {
|
if (!nodep->scopeNamep()) nodep->v3fatalSrc("Display with %m but no AstScopeName");
|
||||||
|
for (AstText* textp=nodep->scopeNamep()->scopeAttrp(); textp; textp=textp->nextp()->castText()) {
|
||||||
emitDispState.pushFormat(textp->text());
|
emitDispState.pushFormat(textp->text());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -246,6 +246,8 @@ public:
|
|||||||
virtual void visit(AstText* nodep, AstNUser*) {
|
virtual void visit(AstText* nodep, AstNUser*) {
|
||||||
ofp()->putsNoTracking(nodep->text());
|
ofp()->putsNoTracking(nodep->text());
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||||
|
}
|
||||||
virtual void visit(AstCStmt* nodep, AstNUser*) {
|
virtual void visit(AstCStmt* nodep, AstNUser*) {
|
||||||
putbs("$_CSTMT(");
|
putbs("$_CSTMT(");
|
||||||
nodep->bodysp()->iterateAndNext(*this);
|
nodep->bodysp()->iterateAndNext(*this);
|
||||||
|
|||||||
+30
-7
@@ -34,7 +34,8 @@
|
|||||||
|
|
||||||
FileLine FileLine::s_defaultFileLine = FileLine(EmptySecret());
|
FileLine FileLine::s_defaultFileLine = FileLine(EmptySecret());
|
||||||
|
|
||||||
int V3Error::s_errcnt = 0;
|
int V3Error::s_errCount = 0;
|
||||||
|
int V3Error::s_warnCount = 0;
|
||||||
int V3Error::s_debugDefault = 0;
|
int V3Error::s_debugDefault = 0;
|
||||||
ostringstream V3Error::s_errorStr; // Error string being formed
|
ostringstream V3Error::s_errorStr; // Error string being formed
|
||||||
V3ErrorCode V3Error::s_errorCode = V3ErrorCode::FATAL;
|
V3ErrorCode V3Error::s_errorCode = V3ErrorCode::FATAL;
|
||||||
@@ -187,25 +188,46 @@ string V3Error::lineStr (const char* filename, int lineno) {
|
|||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void V3Error::incWarnings() {
|
||||||
|
s_warnCount++;
|
||||||
|
if (errorOrWarnCount() == MAX_ERRORS) { // Not >= as would otherwise recurse
|
||||||
|
v3fatal ("Exiting due to too many errors encountered\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void V3Error::incErrors() {
|
void V3Error::incErrors() {
|
||||||
s_errcnt++;
|
s_errCount++;
|
||||||
if (errorCount() == MAX_ERRORS) { // Not >= as would otherwise recurse
|
if (errorOrWarnCount() == MAX_ERRORS) { // Not >= as would otherwise recurse
|
||||||
v3fatal ("Exiting due to too many errors encountered\n");
|
v3fatal ("Exiting due to too many errors encountered\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void V3Error::abortIfErrors() {
|
void V3Error::abortIfErrors() {
|
||||||
if (errorCount()) {
|
if (errorCount()) {
|
||||||
v3fatal ("Exiting due to "<<dec<<errorCount()<<" warning(s)\n");
|
v3fatal ("Exiting due to "<<dec<<errorOrWarnCount()<<" warning(s)\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void V3Error::abortIfWarnings() {
|
||||||
|
if (errorOrWarnCount()) {
|
||||||
|
v3fatal ("Exiting due to "<<dec<<errorOrWarnCount()<<" warning(s)\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool V3Error::isError(V3ErrorCode code) {
|
||||||
|
if (code==V3ErrorCode::SUPPRESS) return false;
|
||||||
|
else if (code==V3ErrorCode::FATAL) return true;
|
||||||
|
else if (code==V3ErrorCode::ERROR) return true;
|
||||||
|
else if (code<V3ErrorCode::FIRST_WARN
|
||||||
|
|| s_pretendError[code]) return true;
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
|
||||||
string V3Error::msgPrefix(V3ErrorCode code) {
|
string V3Error::msgPrefix(V3ErrorCode code) {
|
||||||
if (code==V3ErrorCode::SUPPRESS) return "-arning-suppressed: ";
|
if (code==V3ErrorCode::SUPPRESS) return "-arning-suppressed: ";
|
||||||
else if (code==V3ErrorCode::FATAL) return "%Error: ";
|
else if (code==V3ErrorCode::FATAL) return "%Error: ";
|
||||||
else if (code==V3ErrorCode::ERROR) return "%Error: ";
|
else if (code==V3ErrorCode::ERROR) return "%Error: ";
|
||||||
else if (code<V3ErrorCode::FIRST_WARN
|
else if (isError(code)) return "%Error-"+(string)code.ascii()+": ";
|
||||||
|| s_pretendError[code]) return "%Error-"+(string)code.ascii()+": ";
|
|
||||||
else return "%Warning-"+(string)code.ascii()+": ";
|
else return "%Warning-"+(string)code.ascii()+": ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,7 +280,8 @@ void V3Error::v3errorEnd (ostringstream& sstr) {
|
|||||||
cerr<<msgPrefix()<<"else you may end up with different sim results."<<endl;
|
cerr<<msgPrefix()<<"else you may end up with different sim results."<<endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
incErrors();
|
if (isError(s_errorCode)) incErrors();
|
||||||
|
else incWarnings();
|
||||||
if (s_errorCode==V3ErrorCode::FATAL) {
|
if (s_errorCode==V3ErrorCode::FATAL) {
|
||||||
static bool inFatal = false;
|
static bool inFatal = false;
|
||||||
if (!inFatal) {
|
if (!inFatal) {
|
||||||
|
|||||||
+8
-2
@@ -104,11 +104,13 @@ class V3Error {
|
|||||||
static bool s_describedEachWarn[V3ErrorCode::MAX]; // Told user specifics about this warning
|
static bool s_describedEachWarn[V3ErrorCode::MAX]; // Told user specifics about this warning
|
||||||
static bool s_pretendError[V3ErrorCode::MAX]; // Pretend this warning is an error
|
static bool s_pretendError[V3ErrorCode::MAX]; // Pretend this warning is an error
|
||||||
static int s_debugDefault; // Default debugging level
|
static int s_debugDefault; // Default debugging level
|
||||||
static int s_errcnt; // Error count
|
static int s_errCount; // Error count
|
||||||
|
static int s_warnCount; // Error count
|
||||||
static ostringstream s_errorStr; // Error string being formed
|
static ostringstream s_errorStr; // Error string being formed
|
||||||
static V3ErrorCode s_errorCode; // Error string being formed will abort
|
static V3ErrorCode s_errorCode; // Error string being formed will abort
|
||||||
enum MaxErrors { MAX_ERRORS = 50 }; // Fatal after this may errors
|
enum MaxErrors { MAX_ERRORS = 50 }; // Fatal after this may errors
|
||||||
static void incErrors();
|
static void incErrors();
|
||||||
|
static void incWarnings();
|
||||||
|
|
||||||
V3Error() { cerr<<("Static class"); abort(); }
|
V3Error() { cerr<<("Static class"); abort(); }
|
||||||
|
|
||||||
@@ -118,12 +120,16 @@ class V3Error {
|
|||||||
static void debugDefault(int level) { s_debugDefault = level; }
|
static void debugDefault(int level) { s_debugDefault = level; }
|
||||||
static int debugDefault() { return s_debugDefault; }
|
static int debugDefault() { return s_debugDefault; }
|
||||||
static string msgPrefix(V3ErrorCode code=s_errorCode); // returns %Error/%Warn
|
static string msgPrefix(V3ErrorCode code=s_errorCode); // returns %Error/%Warn
|
||||||
static int errorCount() { return s_errcnt; }
|
static int errorCount() { return s_errCount; }
|
||||||
|
static int warnCount() { return s_warnCount; }
|
||||||
|
static int errorOrWarnCount() { return errorCount()+warnCount(); }
|
||||||
// METHODS
|
// METHODS
|
||||||
static void init();
|
static void init();
|
||||||
static void abortIfErrors();
|
static void abortIfErrors();
|
||||||
|
static void abortIfWarnings();
|
||||||
static void suppressThisWarning(); // Suppress next %Warn if user has it off
|
static void suppressThisWarning(); // Suppress next %Warn if user has it off
|
||||||
static void pretendError(V3ErrorCode code, bool flag) { s_pretendError[code]=flag; }
|
static void pretendError(V3ErrorCode code, bool flag) { s_pretendError[code]=flag; }
|
||||||
|
static bool isError(V3ErrorCode code);
|
||||||
static string v3sform (const char* format, ...);
|
static string v3sform (const char* format, ...);
|
||||||
static string lineStr (const char* filename, int lineno);
|
static string lineStr (const char* filename, int lineno);
|
||||||
static V3ErrorCode errorCode() { return s_errorCode; }
|
static V3ErrorCode errorCode() { return s_errorCode; }
|
||||||
|
|||||||
+2
-2
@@ -233,10 +233,10 @@ private:
|
|||||||
}
|
}
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||||
// Similar code in V3Begin
|
// Similar code in V3Begin
|
||||||
if (m_cellp && nodep->needScopeTracking()) {
|
if (m_cellp) {
|
||||||
// To keep correct visual order, must add before other Text's
|
// To keep correct visual order, must add before other Text's
|
||||||
AstNode* afterp = nodep->scopeAttrp();
|
AstNode* afterp = nodep->scopeAttrp();
|
||||||
if (afterp) afterp->unlinkFrBackWithNext();
|
if (afterp) afterp->unlinkFrBackWithNext();
|
||||||
|
|||||||
@@ -335,6 +335,10 @@ private:
|
|||||||
|| nodep->displayType() == AstDisplayType::FATAL)) {
|
|| nodep->displayType() == AstDisplayType::FATAL)) {
|
||||||
nodep->v3error(nodep->verilogKwd()+" only allowed under a assertion.");
|
nodep->v3error(nodep->verilogKwd()+" only allowed under a assertion.");
|
||||||
}
|
}
|
||||||
|
if (nodep->displayType().needScopeTracking()
|
||||||
|
|| nodep->name().find("%m") != string::npos) {
|
||||||
|
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void visit(AstScCtor* nodep, AstNUser*) {
|
virtual void visit(AstScCtor* nodep, AstNUser*) {
|
||||||
|
|||||||
+114
-27
@@ -303,7 +303,7 @@ V3Number& V3Number::setMask(int nbits) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// ACCESSORS
|
// ACCESSORS - as strings
|
||||||
|
|
||||||
string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
|
string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
|
||||||
ostringstream out;
|
ostringstream out;
|
||||||
@@ -334,34 +334,115 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
|
|||||||
|
|
||||||
if (binary) {
|
if (binary) {
|
||||||
out<<"b";
|
out<<"b";
|
||||||
int bit=width()-1;
|
out<<displayed("%0b");
|
||||||
while (bit && bitIs0(bit)) bit--;
|
|
||||||
for(; bit>=0; --bit) {
|
|
||||||
if (bitIs0(bit)) out<<'0';
|
|
||||||
else if (bitIs1(bit)) out<<'1';
|
|
||||||
else if (bitIsZ(bit)) out<<'z';
|
|
||||||
else out<<'x';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (prefixed) out<<"h";
|
if (prefixed) out<<"h";
|
||||||
// Always deal with 4 bits at once. Note no 4-state, it's above.
|
// Always deal with 4 bits at once. Note no 4-state, it's above.
|
||||||
int hexStart = width()-1;
|
out<<displayed("%0h");
|
||||||
while (hexStart && bitIs0(hexStart)) hexStart--;
|
|
||||||
while ((hexStart&3)!=3) hexStart++;
|
|
||||||
for(int bit=hexStart; bit>0; ) {
|
|
||||||
int v = 0;
|
|
||||||
if (bitIs1(bit)) v |= 8; bit--;
|
|
||||||
if (bitIs1(bit)) v |= 4; bit--;
|
|
||||||
if (bitIs1(bit)) v |= 2; bit--;
|
|
||||||
if (bitIs1(bit)) v |= 1; bit--;
|
|
||||||
if (v>=10) out<<(char)('a'+v-10);
|
|
||||||
else out<<(char)('0'+v);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string V3Number::displayed(const string& vformat) const {
|
||||||
|
string::const_iterator pos = vformat.begin();
|
||||||
|
UASSERT(pos != vformat.end() && pos[0]=='%', "display with non format argument "<<*this);
|
||||||
|
pos++;
|
||||||
|
string fmtsize;
|
||||||
|
for (; pos != vformat.end() && isdigit(pos[0]); pos++) {
|
||||||
|
fmtsize += pos[0];
|
||||||
|
}
|
||||||
|
string str;
|
||||||
|
char code = tolower(pos[0]);
|
||||||
|
switch (code) {
|
||||||
|
case 'b': {
|
||||||
|
int bit = width()-1;
|
||||||
|
if (fmtsize == "0") while (bit && bitIs0(bit)) bit--;
|
||||||
|
for (; bit>=0; bit--) {
|
||||||
|
if (bitIs0(bit)) str+='0';
|
||||||
|
else if (bitIs1(bit)) str+='1';
|
||||||
|
else if (bitIsZ(bit)) str+='z';
|
||||||
|
else str+='x';
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
case 'o': {
|
||||||
|
int bit = width()-1;
|
||||||
|
if (fmtsize == "0") while (bit && bitIs0(bit)) bit--;
|
||||||
|
while ((bit%3)!=2) bit++;
|
||||||
|
for (; bit>0; bit -= 3) {
|
||||||
|
int v = bitsValue(bit-2, 3);
|
||||||
|
str += (char)('0'+v);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
case 'h':
|
||||||
|
case 'x': {
|
||||||
|
int bit = width()-1;
|
||||||
|
if (fmtsize == "0") while (bit && bitIs0(bit)) bit--;
|
||||||
|
while ((bit%4)!=3) bit++;
|
||||||
|
for (; bit>0; bit -= 4) {
|
||||||
|
int v = bitsValue(bit-3, 4);
|
||||||
|
if (v>=10) str += (char)('a'+v-10);
|
||||||
|
else str += (char)('0'+v);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
case 'c': {
|
||||||
|
if (this->width()>8) m_fileline->v3error("$display of char format of > 8 bit value");
|
||||||
|
int v = bitsValue(0, 8);
|
||||||
|
str += (char)(v);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
case 's': {
|
||||||
|
// Spec says always drop leading zeros, this isn't quite right, we space pad.
|
||||||
|
int bit=this->width()-1;
|
||||||
|
bool start=true;
|
||||||
|
while ((bit%8)!=7) bit++;
|
||||||
|
for (; bit>=0; bit -= 8) {
|
||||||
|
int v = bitsValue(bit-7, 8);
|
||||||
|
if (!start || v) {
|
||||||
|
str += (char)((v==0)?' ':v);
|
||||||
|
start = false; // Drop leading 0s
|
||||||
|
} else {
|
||||||
|
if (fmtsize != "0") str += ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
case '~': // Signed decimal
|
||||||
|
case 't':
|
||||||
|
case 'd': { // Unsigned decimal
|
||||||
|
bool issigned = (code == '~');
|
||||||
|
if (fmtsize == "") {
|
||||||
|
double mantissabits = this->width() - (issigned?1:0);
|
||||||
|
double maxval = pow(2.0, mantissabits);
|
||||||
|
double dchars = log10(maxval)+1.0;
|
||||||
|
if (issigned) dchars++; // space for sign
|
||||||
|
fmtsize = cvtToStr(int(dchars));
|
||||||
|
}
|
||||||
|
if (width() > 64) {
|
||||||
|
m_fileline->v3error("Unsupported: $display of dec format of > 64 bit results (use hex format instead)");
|
||||||
|
return "ERR";
|
||||||
|
}
|
||||||
|
if (issigned) {
|
||||||
|
str = cvtToStr(asSQuad());
|
||||||
|
} else {
|
||||||
|
str = cvtToStr(asQuad());
|
||||||
|
}
|
||||||
|
int intfmtsize = atoi(fmtsize.c_str());
|
||||||
|
while ((int)(str.length()) < intfmtsize) str = " "+str;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
m_fileline->v3fatalSrc("Unknown $display format code for number: %"<<pos[0]);
|
||||||
|
return "ERR";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
// ACCESSORS - as numbers
|
||||||
|
|
||||||
uint32_t V3Number::asInt() const {
|
uint32_t V3Number::asInt() const {
|
||||||
UASSERT(!isFourState(),"asInt with 4-state "<<*this);
|
UASSERT(!isFourState(),"asInt with 4-state "<<*this);
|
||||||
UASSERT((width()<33 || (width()<65 && m_value[1]==0)), "Value too wide "<<*this);
|
UASSERT((width()<33 || (width()<65 && m_value[1]==0)), "Value too wide "<<*this);
|
||||||
@@ -369,18 +450,24 @@ uint32_t V3Number::asInt() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vlsint32_t V3Number::asSInt() const {
|
vlsint32_t V3Number::asSInt() const {
|
||||||
UASSERT(!isFourState(),"asSInt with 4-state "<<*this);
|
uint32_t v = asInt();
|
||||||
UASSERT((width()<33 || (width()<65 && m_value[1]==0)), "Value too wide "<<*this);
|
uint32_t signExtend = (-(v & (1UL<<(width()-1))));
|
||||||
uint32_t signExtend = (-((m_value[0]) & (1UL<<(width()-1))));
|
uint32_t extended = v | signExtend;
|
||||||
uint32_t extended = m_value[0] | signExtend;
|
|
||||||
return (vlsint32_t)(extended);
|
return (vlsint32_t)(extended);
|
||||||
}
|
}
|
||||||
|
|
||||||
vluint64_t V3Number::asQuad() const {
|
vluint64_t V3Number::asQuad() const {
|
||||||
UASSERT(!isFourState(),"asQuad with 4-state "<<*this);
|
UASSERT(!isFourState(),"asQuad with 4-state "<<*this);
|
||||||
UASSERT(width()<65, "Value too wide "<<*this);
|
UASSERT(width()<65, "Value too wide "<<*this);
|
||||||
if (width()<=32) return ((vluint64_t)m_value[0]);
|
if (width()<=32) return ((vluint64_t)(asInt()));
|
||||||
else return ((vluint64_t)m_value[1]<<VL_ULL(32)) | ((vluint64_t)m_value[0]);
|
return ((vluint64_t)m_value[1]<<VL_ULL(32)) | ((vluint64_t)m_value[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
vlsint64_t V3Number::asSQuad() const {
|
||||||
|
vluint64_t v = asQuad();
|
||||||
|
vluint64_t signExtend = (-(v & (VL_ULL(1)<<(width()-1))));
|
||||||
|
vluint64_t extended = v | signExtend;
|
||||||
|
return (vlsint64_t)(extended);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t V3Number::asHash() const {
|
uint32_t V3Number::asHash() const {
|
||||||
|
|||||||
@@ -94,6 +94,12 @@ private:
|
|||||||
bool bitIsZ (int bit) const {
|
bool bitIsZ (int bit) const {
|
||||||
if (bit>=m_width) return bitIsZ(m_width-1);
|
if (bit>=m_width) return bitIsZ(m_width-1);
|
||||||
return ( (~m_value[bit/32] & (1UL<<(bit&31))) && (m_valueX[bit/32] & (1UL<<(bit&31))) ); }
|
return ( (~m_value[bit/32] & (1UL<<(bit&31))) && (m_valueX[bit/32] & (1UL<<(bit&31))) ); }
|
||||||
|
uint32_t bitsValue(int lsb, int nbits) const {
|
||||||
|
uint32_t v=0;
|
||||||
|
for (int bitn=0; bitn<nbits; bitn++) { v |= (bitIs1(lsb+bitn)<<bitn); }
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
int words() const { return ((width()+31)/32); }
|
int words() const { return ((width()+31)/32); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -112,6 +118,7 @@ public:
|
|||||||
|
|
||||||
// ACCESSORS
|
// ACCESSORS
|
||||||
string ascii(bool prefixed=true, bool cleanVerilog=false) const;
|
string ascii(bool prefixed=true, bool cleanVerilog=false) const;
|
||||||
|
string displayed(const string& format) const;
|
||||||
int width() const { return m_width; }
|
int width() const { return m_width; }
|
||||||
int minWidth() const; // Minimum width that can represent this number (~== log2(num)+1)
|
int minWidth() const; // Minimum width that can represent this number (~== log2(num)+1)
|
||||||
bool sized() const { return m_sized; }
|
bool sized() const { return m_sized; }
|
||||||
@@ -129,6 +136,7 @@ public:
|
|||||||
uint32_t asInt() const;
|
uint32_t asInt() const;
|
||||||
vlsint32_t asSInt() const;
|
vlsint32_t asSInt() const;
|
||||||
vluint64_t asQuad() const;
|
vluint64_t asQuad() const;
|
||||||
|
vlsint64_t asSQuad() const;
|
||||||
uint32_t asHash() const;
|
uint32_t asHash() const;
|
||||||
uint32_t dataWord(int word) const;
|
uint32_t dataWord(int word) const;
|
||||||
uint32_t countOnes() const;
|
uint32_t countOnes() const;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#define VP_DEFINE 261
|
#define VP_DEFINE 261
|
||||||
#define VP_ELSE 262
|
#define VP_ELSE 262
|
||||||
#define VP_ELSIF 263
|
#define VP_ELSIF 263
|
||||||
|
#define VP_LINE 264
|
||||||
|
|
||||||
#define VP_SYMBOL 300
|
#define VP_SYMBOL 300
|
||||||
#define VP_STRING 301
|
#define VP_STRING 301
|
||||||
|
|||||||
+2
-1
@@ -73,7 +73,8 @@ psl [p]sl
|
|||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
%%
|
%%
|
||||||
|
|
||||||
<INITIAL>^{ws}*"`line"{ws}+.*{crnl} { V3PreLex::s_currentLexp->lineDirective(yytext); }
|
<INITIAL>^{ws}*"`line"{ws}+.*{crnl} { V3PreLex::s_currentLexp->lineDirective(yytext);
|
||||||
|
return(VP_LINE); }
|
||||||
|
|
||||||
/* Special directives we recognise */
|
/* Special directives we recognise */
|
||||||
<INITIAL>"`include" { return(VP_INCLUDE); }
|
<INITIAL>"`include" { return(VP_INCLUDE); }
|
||||||
|
|||||||
@@ -328,6 +328,7 @@ const char* V3PreProcImp::tokenName(int tok) {
|
|||||||
case VP_DEFINE : return("DEFINE");
|
case VP_DEFINE : return("DEFINE");
|
||||||
case VP_ELSE : return("ELSE");
|
case VP_ELSE : return("ELSE");
|
||||||
case VP_ELSIF : return("ELSIF");
|
case VP_ELSIF : return("ELSIF");
|
||||||
|
case VP_LINE : return("LINE");
|
||||||
case VP_SYMBOL : return("SYMBOL");
|
case VP_SYMBOL : return("SYMBOL");
|
||||||
case VP_STRING : return("STRING");
|
case VP_STRING : return("STRING");
|
||||||
case VP_DEFVALUE : return("DEFVALUE");
|
case VP_DEFVALUE : return("DEFVALUE");
|
||||||
@@ -583,6 +584,10 @@ int V3PreProcImp::getToken() {
|
|||||||
for (int len=0; len<yyleng; len++) { if (yytext[len]=='\n') m_lineAdd++; }
|
for (int len=0; len<yyleng; len++) { if (yytext[len]=='\n') m_lineAdd++; }
|
||||||
goto next_tok;
|
goto next_tok;
|
||||||
}
|
}
|
||||||
|
if (tok==VP_LINE) {
|
||||||
|
addLineComment(0);
|
||||||
|
goto next_tok;
|
||||||
|
}
|
||||||
// Deal with some special parser states
|
// Deal with some special parser states
|
||||||
switch (m_state) {
|
switch (m_state) {
|
||||||
case ps_TOP: {
|
case ps_TOP: {
|
||||||
|
|||||||
+10
-12
@@ -198,19 +198,17 @@ private:
|
|||||||
nodep->taskp(NULL);
|
nodep->taskp(NULL);
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||||
if (nodep->name().find("%m") != string::npos) {
|
string prefix = (string)(".")+m_scopep->prettyName();
|
||||||
string prefix = (string)(".")+m_scopep->prettyName();
|
// TOP and above will be the user's name().
|
||||||
// TOP and above will be the user's name().
|
// Note 'TOP.'is stripped by prettyName, but not 'TOP'.
|
||||||
// Note 'TOP.'is stripped by prettyName, but not 'TOP'.
|
if (prefix != ".TOP") {
|
||||||
if (prefix != ".TOP") {
|
// To keep correct visual order, must add before other Text's
|
||||||
// To keep correct visual order, must add before other Text's
|
AstNode* afterp = nodep->scopeAttrp();
|
||||||
AstNode* afterp = nodep->scopeAttrp();
|
if (afterp) afterp->unlinkFrBackWithNext();
|
||||||
if (afterp) afterp->unlinkFrBackWithNext();
|
nodep->scopeAttrp(new AstText(nodep->fileline(), prefix));
|
||||||
nodep->scopeAttrp(new AstText(nodep->fileline(), prefix));
|
if (afterp) nodep->scopeAttrp(afterp);
|
||||||
if (afterp) nodep->scopeAttrp(afterp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -385,6 +385,9 @@ private:
|
|||||||
virtual void visit(AstText* nodep, AstNUser* vup) {
|
virtual void visit(AstText* nodep, AstNUser* vup) {
|
||||||
// Only used in CStmts which don't care....
|
// Only used in CStmts which don't care....
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstScopeName* nodep, AstNUser* vup) {
|
||||||
|
// Only used in Displays which don't care....
|
||||||
|
}
|
||||||
virtual void visit(AstVar* nodep, AstNUser* vup) {
|
virtual void visit(AstVar* nodep, AstNUser* vup) {
|
||||||
//if (debug()) nodep->dumpTree(cout," InitPre: ");
|
//if (debug()) nodep->dumpTree(cout," InitPre: ");
|
||||||
// Must have deterministic constant width
|
// Must have deterministic constant width
|
||||||
|
|||||||
+1
-1
@@ -538,7 +538,7 @@ int main(int argc, char** argv, char** env) {
|
|||||||
|
|
||||||
// Final steps
|
// Final steps
|
||||||
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("final.tree",99));
|
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("final.tree",99));
|
||||||
V3Error::abortIfErrors();
|
V3Error::abortIfWarnings();
|
||||||
|
|
||||||
if (!v3Global.opt.lintOnly() && v3Global.opt.makeDepend()) {
|
if (!v3Global.opt.lintOnly() && v3Global.opt.makeDepend()) {
|
||||||
V3File::writeDepend(v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__ver.d");
|
V3File::writeDepend(v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__ver.d");
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
//**********************************************************************
|
//**********************************************************************
|
||||||
//**** Version and host name
|
//**** Version and host name
|
||||||
|
|
||||||
#define DTVERSION "Verilator 3.651 4/20/2007"
|
#define DTVERSION "Verilator 3.652 6/21/2007"
|
||||||
|
|
||||||
//**********************************************************************
|
//**********************************************************************
|
||||||
//**** Functions
|
//**** Functions
|
||||||
|
|||||||
+1
-1
@@ -718,7 +718,7 @@ escid \\[^ \t\f\r\n]+
|
|||||||
|
|
||||||
<V95,V01,V05,S05,PSL>{
|
<V95,V01,V05,S05,PSL>{
|
||||||
"`"[a-zA-Z_0-9]+ { yyerrorf("Define or directive not defined: %s",yytext); }
|
"`"[a-zA-Z_0-9]+ { yyerrorf("Define or directive not defined: %s",yytext); }
|
||||||
"//"[^\n]+ { } /* throw away single line comments */
|
"//"[^\n]* { } /* throw away single line comments */
|
||||||
. {yylval.fileline = CRELINE(); return yytext[0];} /* return single char ops. */
|
. {yylval.fileline = CRELINE(); return yytext[0];} /* return single char ops. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+24
-11
@@ -288,7 +288,7 @@ class AstSenTree;
|
|||||||
// Trailing E indicates this type may have empty match
|
// Trailing E indicates this type may have empty match
|
||||||
%type<modulep> modHdr
|
%type<modulep> modHdr
|
||||||
%type<nodep> modPortsE portList port
|
%type<nodep> modPortsE portList port
|
||||||
%type<nodep> portV2kList portV2kSig
|
%type<nodep> portV2kArgs portV2kList portV2kSecond portV2kSig
|
||||||
%type<nodep> portV2kDecl ioDecl varDecl
|
%type<nodep> portV2kDecl ioDecl varDecl
|
||||||
%type<nodep> modParDecl modParList modParE
|
%type<nodep> modParDecl modParList modParE
|
||||||
%type<nodep> modItem modItemList modItemListE modOrGenItem
|
%type<nodep> modItem modItemList modItemListE modOrGenItem
|
||||||
@@ -325,7 +325,7 @@ class AstSenTree;
|
|||||||
%type<nodep> taskDecl
|
%type<nodep> taskDecl
|
||||||
%type<nodep> varDeclList
|
%type<nodep> varDeclList
|
||||||
%type<funcp> funcDecl
|
%type<funcp> funcDecl
|
||||||
%type<nodep> funcBody funcVarList funcVar
|
%type<nodep> funcBody funcGuts funcVarList funcVar
|
||||||
%type<rangep> funcTypeE
|
%type<rangep> funcTypeE
|
||||||
%type<rangep> instRangeE
|
%type<rangep> instRangeE
|
||||||
%type<nodep> gateDecl
|
%type<nodep> gateDecl
|
||||||
@@ -386,7 +386,7 @@ modParList: modParDecl { $$ = $1; }
|
|||||||
modPortsE: /* empty */ { $$ = NULL; }
|
modPortsE: /* empty */ { $$ = NULL; }
|
||||||
| '(' ')' { $$ = NULL; }
|
| '(' ')' { $$ = NULL; }
|
||||||
| '(' {V3Parse::s_pinNum=1;} portList ')' { $$ = $3; }
|
| '(' {V3Parse::s_pinNum=1;} portList ')' { $$ = $3; }
|
||||||
| '(' {V3Parse::s_pinNum=1;} portV2kList ')' { $$ = $3; }
|
| '(' {V3Parse::s_pinNum=1;} portV2kArgs ')' { $$ = $3; }
|
||||||
;
|
;
|
||||||
|
|
||||||
portList: port { $$ = $1; }
|
portList: port { $$ = $1; }
|
||||||
@@ -396,8 +396,17 @@ portList: port { $$ = $1; }
|
|||||||
port: yaID portRangeE { $$ = new AstPort(CRELINE(),V3Parse::s_pinNum++,*$1); }
|
port: yaID portRangeE { $$ = new AstPort(CRELINE(),V3Parse::s_pinNum++,*$1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
portV2kList: portV2kDecl { $$ = $1; }
|
portV2kArgs: portV2kDecl { $$ = $1; }
|
||||||
| portV2kList ',' portV2kDecl { $$ = $1->addNext($3); }
|
| portV2kDecl ',' portV2kList { $$ = $1->addNext($3); }
|
||||||
|
;
|
||||||
|
|
||||||
|
portV2kList: portV2kSecond { $$ = $1; }
|
||||||
|
| portV2kList ',' portV2kSecond { $$ = $1->addNext($3); }
|
||||||
|
;
|
||||||
|
|
||||||
|
// Called only after a comma in a v2k list, to allow parsing "input a,b"
|
||||||
|
portV2kSecond: portV2kDecl { $$ = $1; }
|
||||||
|
| portV2kSig { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
portV2kSig: sigAndAttr { $$=$1; $$->addNext(new AstPort(CRELINE(),V3Parse::s_pinNum++, V3Parse::s_varAttrp->name())); }
|
portV2kSig: sigAndAttr { $$=$1; $$->addNext(new AstPort(CRELINE(),V3Parse::s_pinNum++, V3Parse::s_varAttrp->name())); }
|
||||||
@@ -849,21 +858,25 @@ taskRef: idDotted { $$ = new AstTaskRef(CRELINE(),new AstParseRef($1->fileli
|
|||||||
funcRef: idDotted '(' exprList ')' { $$ = new AstFuncRef($2,new AstParseRef($1->fileline(), AstParseRefExp::FUNC, $1), $3); }
|
funcRef: idDotted '(' exprList ')' { $$ = new AstFuncRef($2,new AstParseRef($1->fileline(), AstParseRefExp::FUNC, $1), $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
taskDecl: yTASK taskAutoE yaID ';' stmtBlock yENDTASK { $$ = new AstTask ($1,*$3,$5);}
|
taskDecl: yTASK taskAutoE yaID funcGuts yENDTASK { $$ = new AstTask ($1,*$3,$4);}
|
||||||
| yTASK taskAutoE yaID ';' funcVarList stmtBlock yENDTASK { $$ = new AstTask ($1,*$3,$5); $5->addNextNull($6); }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
funcDecl: yFUNCTION taskAutoE funcTypeE yaID ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$4,$6,$3); }
|
funcDecl: yFUNCTION taskAutoE funcTypeE yaID funcGuts yENDFUNCTION { $$ = new AstFunc ($1,*$4,$5,$3); }
|
||||||
| yFUNCTION taskAutoE ySIGNED funcTypeE yaID ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$5,$7,$4); $$->isSigned(true); }
|
| yFUNCTION taskAutoE ySIGNED funcTypeE yaID funcGuts yENDFUNCTION { $$ = new AstFunc ($1,*$5,$6,$4); $$->isSigned(true); }
|
||||||
| yFUNCTION taskAutoE funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$4,$7,$3); $$->attrIsolateAssign(true);}
|
| yFUNCTION taskAutoE funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS funcGuts yENDFUNCTION { $$ = new AstFunc ($1,*$4,$6,$3); $$->attrIsolateAssign(true);}
|
||||||
| yFUNCTION taskAutoE ySIGNED funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$5,$8,$4); $$->attrIsolateAssign(true); $$->isSigned(true); }
|
| yFUNCTION taskAutoE ySIGNED funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS funcGuts yENDFUNCTION { $$ = new AstFunc ($1,*$5,$7,$4); $$->attrIsolateAssign(true); $$->isSigned(true); }
|
||||||
;
|
;
|
||||||
|
|
||||||
taskAutoE: /* empty */ { }
|
taskAutoE: /* empty */ { }
|
||||||
| yAUTOMATIC { }
|
| yAUTOMATIC { }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
funcGuts: '(' {V3Parse::s_pinNum=1;} portV2kArgs ')' ';' funcBody { $$ = $3->addNextNull($6); }
|
||||||
|
| ';' funcBody { $$ = $2; }
|
||||||
|
;
|
||||||
|
|
||||||
funcBody: funcVarList stmtBlock { $$ = $1;$1->addNextNull($2); }
|
funcBody: funcVarList stmtBlock { $$ = $1;$1->addNextNull($2); }
|
||||||
|
| stmtBlock { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
funcTypeE: /* empty */ { $$ = NULL; }
|
funcTypeE: /* empty */ { $$ = NULL; }
|
||||||
|
|||||||
@@ -549,6 +549,7 @@ sub _make_main {
|
|||||||
print $fh " double sim_time = 1000;\n";
|
print $fh " double sim_time = 1000;\n";
|
||||||
}
|
}
|
||||||
print $fh " Verilated::debug(".($self->{verilated_debug}?1:0).");\n";
|
print $fh " Verilated::debug(".($self->{verilated_debug}?1:0).");\n";
|
||||||
|
print $fh " Verilated::randReset(".$self->{verilated_randReset}.");\n" if defined $self->{verilated_randReset};
|
||||||
print $fh " topp = new $VM_PREFIX (\"TOP\");\n";
|
print $fh " topp = new $VM_PREFIX (\"TOP\");\n";
|
||||||
my $set;
|
my $set;
|
||||||
if ($self->sp) {
|
if ($self->sp) {
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ execute (
|
|||||||
[0] %x=00abc1234567812345678 %0x=abc1234567812345678 %o=012570110642547402215053170 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000
|
[0] %x=00abc1234567812345678 %0x=abc1234567812345678 %o=012570110642547402215053170 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000
|
||||||
|
|
||||||
[0] %s=! %s= what! %s= hmmm!1234
|
[0] %s=! %s= what! %s= hmmm!1234
|
||||||
|
[0] hello, from a very long string. Percent %s are literally substituted in.
|
||||||
|
*-* All Finished *-*
|
||||||
'),
|
'),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ module t;
|
|||||||
$display("[%0t] %%s=%s %%s=%s %%s=%s", $time,
|
$display("[%0t] %%s=%s %%s=%s %%s=%s", $time,
|
||||||
str2[7:0], str2, str3);
|
str2[7:0], str2, str3);
|
||||||
|
|
||||||
|
$display("[%0t] %s%s%s", $time,
|
||||||
|
"hel", "lo, fr", "om a very long string. Percent %s are literally substituted in.");
|
||||||
|
|
||||||
// Str check
|
// Str check
|
||||||
`ifndef nc // NC-Verilog 5.3 chokes on this test
|
`ifndef nc // NC-Verilog 5.3 chokes on this test
|
||||||
if (str !== 32'h00_bf_11_0a) $stop;
|
if (str !== 32'h00_bf_11_0a) $stop;
|
||||||
|
|||||||
Executable
+36
@@ -0,0 +1,36 @@
|
|||||||
|
#!/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_display.v");
|
||||||
|
|
||||||
|
compile (
|
||||||
|
v_flags2 => [$Last_Self->{v3}?"-O0":""],
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
expect=>quotemeta(
|
||||||
|
'[0] In TOP.v: Hi
|
||||||
|
[0] In TOP.v.sub
|
||||||
|
[0] In TOP.v.sub.subblock
|
||||||
|
[0] In TOP.v.sub2
|
||||||
|
[0] In TOP.v.sub2.subblock2
|
||||||
|
[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
|
||||||
|
[0] %x=00abc1234567812345678 %0x=abc1234567812345678 %o=012570110642547402215053170 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000
|
||||||
|
|
||||||
|
[0] %s=! %s= what! %s= hmmm!1234
|
||||||
|
[0] hello, from a very long string. Percent %s are literally substituted in.
|
||||||
|
*-* All Finished *-*
|
||||||
|
'),
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
@@ -13,12 +13,12 @@ compile (
|
|||||||
execute (
|
execute (
|
||||||
check_finished=>1,
|
check_finished=>1,
|
||||||
expect=> quotemeta(
|
expect=> quotemeta(
|
||||||
'[0] %x=0bbccc %x=0bbccc %o=2736314 %b=010111011110011001100 %0d=769228 %d= 769228
|
'[0] lp %x=0bbccc %x=0bbccc %o=2736314 %b=010111011110011001100 %0d=769228 %d= 769228
|
||||||
[0] %x=1bbccc %x=1bbccc %o=6736314 %b=110111011110011001100 %0d=-279348 %d= -279348
|
[0] ln %x=1bbccc %x=1bbccc %o=6736314 %b=110111011110011001100 %0d=-279348 %d= -279348
|
||||||
[0] %x=000bbbbcccc %x=000bbbbcccc %o=00027356746314 %b=00000000010111011101110111100110011001100 %0d=3149647052 %d= 3149647052
|
[0] qp %x=001bbbbcccc %x=001bbbbcccc %o=00067356746314 %b=00000000110111011101110111100110011001100 %0d=7444614348 %d= 7444614348
|
||||||
[0] %x=100bbbbcccc %x=100bbbbcccc %o=20027356746314 %b=10000000010111011101110111100110011001100 %0d=-1096361980724 %d=-1096361980724
|
[0] qn %x=101bbbbcccc %x=101bbbbcccc %o=20067356746314 %b=10000000110111011101110111100110011001100 %0d=-1092067013428 %d=-1092067013428
|
||||||
[0] %x=000bc1234567812345678 %x=000bc1234567812345678 %o=000570110642547402215053170 %b=000000000101111000001001000110100010101100111100000010010001101000101011001111000
|
[0] wp %x=000bc1234567812345678 %x=000bc1234567812345678 %o=000570110642547402215053170 %b=000000000101111000001001000110100010101100111100000010010001101000101011001111000
|
||||||
[0] %x=000bc1234577812345678 %x=000bc1234577812345678 %o=000570110642567402215053170 %b=000000000101111000001001000110100010101110111100000010010001101000101011001111000
|
[0] wn %x=000bc1234577812345678 %x=000bc1234577812345678 %o=000570110642567402215053170 %b=000000000101111000001001000110100010101110111100000010010001101000101011001111000
|
||||||
'),
|
'),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -7,24 +7,24 @@
|
|||||||
module t;
|
module t;
|
||||||
reg signed [20:0] longp; initial longp = 21'shbbccc;
|
reg signed [20:0] longp; initial longp = 21'shbbccc;
|
||||||
reg signed [20:0] longn; initial longn = 21'shbbccc; initial longn[20]=1'b1;
|
reg signed [20:0] longn; initial longn = 21'shbbccc; initial longn[20]=1'b1;
|
||||||
reg signed [40:0] quadp; initial quadp = 41'shbbbb_cccc;
|
reg signed [40:0] quadp; initial quadp = 41'sh1_bbbb_cccc;
|
||||||
reg signed [40:0] quadn; initial quadn = 41'shbbbb_cccc; initial quadn[40]=1'b1;
|
reg signed [40:0] quadn; initial quadn = 41'sh1_bbbb_cccc; initial quadn[40]=1'b1;
|
||||||
reg signed [80:0] widep; initial widep = 81'shbc_1234_5678_1234_5678;
|
reg signed [80:0] widep; initial widep = 81'shbc_1234_5678_1234_5678;
|
||||||
reg signed [80:0] widen; initial widen = 81'shbc_1234_5678_1234_5678; initial widen[40]=1'b1;
|
reg signed [80:0] widen; initial widen = 81'shbc_1234_5678_1234_5678; initial widen[40]=1'b1;
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
// Display formatting
|
// Display formatting
|
||||||
$display("[%0t] %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time,
|
$display("[%0t] lp %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time,
|
||||||
longp, longp, longp, longp, longp, longp);
|
longp, longp, longp, longp, longp, longp);
|
||||||
$display("[%0t] %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time,
|
$display("[%0t] ln %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time,
|
||||||
longn, longn, longn, longn, longn, longn);
|
longn, longn, longn, longn, longn, longn);
|
||||||
$display("[%0t] %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time,
|
$display("[%0t] qp %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time,
|
||||||
quadp, quadp, quadp, quadp, quadp, quadp);
|
quadp, quadp, quadp, quadp, quadp, quadp);
|
||||||
$display("[%0t] %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time,
|
$display("[%0t] qn %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time,
|
||||||
quadn, quadn, quadn, quadn, quadn, quadn);
|
quadn, quadn, quadn, quadn, quadn, quadn);
|
||||||
$display("[%0t] %%x=%x %%x=%x %%o=%o %%b=%b", $time,
|
$display("[%0t] wp %%x=%x %%x=%x %%o=%o %%b=%b", $time,
|
||||||
widep, widep, widep, widep);
|
widep, widep, widep, widep);
|
||||||
$display("[%0t] %%x=%x %%x=%x %%o=%o %%b=%b", $time,
|
$display("[%0t] wn %%x=%x %%x=%x %%o=%o %%b=%b", $time,
|
||||||
widen, widen, widen, widen);
|
widen, widen, widen, widen);
|
||||||
$display;
|
$display;
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
|
|||||||
Executable
+29
@@ -0,0 +1,29 @@
|
|||||||
|
#!/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_display_signed.v");
|
||||||
|
|
||||||
|
compile (
|
||||||
|
v_flags2 => [$Last_Self->{v3}?"-O0":""],
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
expect=> quotemeta(
|
||||||
|
'[0] lp %x=0bbccc %x=0bbccc %o=2736314 %b=010111011110011001100 %0d=769228 %d= 769228
|
||||||
|
[0] ln %x=1bbccc %x=1bbccc %o=6736314 %b=110111011110011001100 %0d=-279348 %d= -279348
|
||||||
|
[0] qp %x=001bbbbcccc %x=001bbbbcccc %o=00067356746314 %b=00000000110111011101110111100110011001100 %0d=7444614348 %d= 7444614348
|
||||||
|
[0] qn %x=101bbbbcccc %x=101bbbbcccc %o=20067356746314 %b=10000000110111011101110111100110011001100 %0d=-1092067013428 %d=-1092067013428
|
||||||
|
[0] wp %x=000bc1234567812345678 %x=000bc1234567812345678 %o=000570110642547402215053170 %b=000000000101111000001001000110100010101100111100000010010001101000101011001111000
|
||||||
|
[0] wn %x=000bc1234577812345678 %x=000bc1234577812345678 %o=000570110642567402215053170 %b=000000000101111000001001000110100010101110111100000010010001101000101011001111000
|
||||||
|
'),
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
@@ -67,10 +67,11 @@ module t;
|
|||||||
end
|
end
|
||||||
endtask
|
endtask
|
||||||
|
|
||||||
task incr;
|
task incr (
|
||||||
output [31:0] z;
|
// Check a V2K style input/output list
|
||||||
input [31:0] a;
|
output [31:0] z,
|
||||||
input [31:0] inc;
|
input [31:0] a, inc
|
||||||
|
);
|
||||||
z = a + inc;
|
z = a + inc;
|
||||||
endtask
|
endtask
|
||||||
|
|
||||||
|
|||||||
Executable
+20
@@ -0,0 +1,20 @@
|
|||||||
|
#!/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.
|
||||||
|
|
||||||
|
$Last_Self->{verilated_randReset} = 1;
|
||||||
|
|
||||||
|
compile (
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
// $Id$
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
|
||||||
|
// verilator lint_off WIDTH
|
||||||
|
// verilator lint_off VARHIDDEN
|
||||||
|
|
||||||
|
module t (
|
||||||
|
clk
|
||||||
|
);
|
||||||
|
input clk;
|
||||||
|
integer cyc=0;
|
||||||
|
reg [63:0] crc; initial crc = 64'h1;
|
||||||
|
|
||||||
|
chk chk (.clk (clk),
|
||||||
|
.rst_l (1'b1),
|
||||||
|
.expr (|crc),
|
||||||
|
);
|
||||||
|
|
||||||
|
always @ (posedge clk) begin
|
||||||
|
cyc <= cyc + 1;
|
||||||
|
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
|
||||||
|
if (cyc==0) begin
|
||||||
|
crc <= 64'h5aef0c8d_d70a4497;
|
||||||
|
end
|
||||||
|
else if (cyc<90) begin
|
||||||
|
end
|
||||||
|
else if (cyc==99) begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module chk (input clk, input rst_l, input expr);
|
||||||
|
|
||||||
|
integer errors; initial errors = 0;
|
||||||
|
|
||||||
|
task printerr;
|
||||||
|
input [8*64:1] msg;
|
||||||
|
begin
|
||||||
|
errors = errors + 1;
|
||||||
|
$write("%%Error: %0s\n", msg);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (rst_l) begin
|
||||||
|
if (expr == 1'b0) begin
|
||||||
|
printerr("expr not asserted");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
wire noxs = ((expr ^ expr) == 1'b0);
|
||||||
|
|
||||||
|
reg hasx;
|
||||||
|
always @ (noxs) begin
|
||||||
|
if (noxs) begin
|
||||||
|
hasx = 1'b0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
hasx = 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (rst_l) begin
|
||||||
|
if (hasx) begin
|
||||||
|
printerr("expr has unknowns");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
@@ -56,7 +56,7 @@ endmodule
|
|||||||
|
|
||||||
module ftest(
|
module ftest(
|
||||||
input [ 7:0 ] a,
|
input [ 7:0 ] a,
|
||||||
input [ 7:0 ] b,
|
b, // Test legal syntax
|
||||||
input clk,
|
input clk,
|
||||||
output [ 7:0 ] z
|
output [ 7:0 ] z
|
||||||
);
|
);
|
||||||
@@ -85,7 +85,7 @@ endmodule // ftest
|
|||||||
|
|
||||||
module mytop (
|
module mytop (
|
||||||
input [ 7:0 ] a,
|
input [ 7:0 ] a,
|
||||||
input [ 7:0 ] b,
|
b,
|
||||||
input clk,
|
input clk,
|
||||||
output [ 7:0 ] z
|
output [ 7:0 ] z
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ At file t/t_preproc_inc2.v line 4
|
|||||||
|
|
||||||
`line 1 "t/t_preproc_inc3.v" 1
|
`line 1 "t/t_preproc_inc3.v" 1
|
||||||
|
|
||||||
|
`line 2 "inc3_a_filename_from_line_directive" 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user