Compare commits

...
33 Commits
Author SHA1 Message Date
Wilson Snyder a20b4f2864 Version bump 2011-04-06 07:33:44 -04:00
Wilson Snyder 44a19d2a0a Fix missing test files 2011-04-06 07:33:32 -04:00
Wilson Snyder 02f3beb8db Add V3Number rotate functions; unused as yet 2011-03-30 21:31:29 -04:00
Wilson Snyder 3269cc3d90 Add +libext+.sv default 2011-03-30 21:30:36 -04:00
Wilson Snyder fb70a1f4ab Add --Wno-fatal to turn off abort on warnings. 2011-03-22 18:09:39 -04:00
Wilson Snyder df0aa483ce Support ${...} and $(...) env variables in .vc files 2011-03-21 12:25:31 -04:00
Wilson Snyder c83f12a55c Support simple cast operators, bug335. 2011-03-17 22:25:49 -04:00
Wilson Snyder 9704f59566 Internals: Rename AstCast to AstCCast 2011-03-17 21:09:52 -04:00
Wilson Snyder 2923893d34 Support loop unrolling on width mismatches, bug 333 2011-03-12 07:45:04 -05:00
Wilson Snyder 890dab0742 Write logfile on each failure 2011-03-12 07:44:29 -05:00
Wilson Snyder 607e26b041 Commentary 2011-03-08 06:49:45 -05:00
Wilson Snyder ea75290f65 Add error on circular parameter definitions, bug329 2011-03-07 20:44:19 -05:00
Wilson Snyder a176054118 Add --trace-max-width and --trace-max-array, bug 319. 2011-02-23 21:58:27 -05:00
Wilson Snyder 9a697dc5f5 Accelerate bit-selected inversions. 2011-02-23 21:36:38 -05:00
Wilson Snyder cfdb852843 Fix concatenates and vectored bufif1, bug326. 2011-02-23 21:21:59 -05:00
Wilson Snyder 2e67a91982 Support $bits(data_type), bug327. 2011-02-23 19:04:15 -05:00
Wilson Snyder 074ca9330d Make width violation on function outputs a fatal error 2011-02-18 20:52:26 -05:00
Wilson Snyder f0d7cdcb20 Commentary 2011-02-18 07:11:03 -05:00
Wilson Snyder 40d961e059 Version bump 2011-02-14 19:05:55 -05:00
Wilson Snyder e5de759236 Report error on function call output tied to constant.
Fix internal error on functions called as SV tasks.
2011-02-14 19:25:30 -05:00
Wilson Snyder e26a75c59d Fix internal error on non-inlined inout pins. 2011-02-07 19:15:58 -05:00
Wilson Snyder 8701145b40 Fix error on constants connected to outputs, bug323. 2011-01-31 07:05:04 -05:00
Wilson Snyder a2558886c8 Report errors on empty pins, bug321 2011-01-29 18:00:48 -05:00
Wilson Snyder f818ee86ae Report errors on duplicated pins, bug321. 2011-01-29 17:01:06 -05:00
Wilson Snyder ad0dbdaa9c CDC: Print nice net names instead of ___5f 2011-01-19 11:44:23 -05:00
Wilson Snyder a9f14b294f Internals: Cdc notes; marking submodules won't work 2011-01-18 21:37:53 -05:00
Wilson Snyder a435ae98f9 Throw UNUSED/UNDRIVEN only once per net in a parametrized module. 2011-01-18 21:28:51 -05:00
Wilson Snyder 481b261458 Internals: add a few userIncs, No functional change 2011-01-18 21:19:12 -05:00
Wilson Snyder 48df52d743 Reduce use of CRELINE so line numbers more closely match first parsed location 2011-01-18 21:12:31 -05:00
Wilson Snyder 0af0d3b171 Cleanup CDC reports, remove TOP-> signal prefixes 2011-01-17 14:58:58 -05:00
Wilson Snyder 8287cf35e7 Fix warnings to point to lowest net usage, not upper level ports. 2011-01-17 14:10:01 -05:00
Wilson Snyder fab7924cc2 Fix block comment not separating identifiers, bug311. 2011-01-11 18:46:21 -05:00
Wilson Snyder 0ab739e8b1 Fix false BLKSEQ on non-unrolled for loop indexes. 2011-01-06 06:46:19 -05:00
83 changed files with 1848 additions and 453 deletions
+40
View File
@@ -3,6 +3,46 @@ 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.812 2011/04/06
*** Add --trace-max-width and --trace-max-array, bug 319. [Alex Solomatnikov]
*** Add --Wno-fatal to turn off abort on warnings. [by Stefan Wallentowitz]
**** Support ${...} and $(...) env vars in .vc files. [by Stefan Wallentowitz]
**** Support $bits(data_type), bug327. [Alex Solomatnikov]
**** Support loop unrolling on width mismatches, bug 333. [Joe Eiler]
**** Support simple cast operators, bug335. [Alex Solomatnikov]
**** Accelerate bit-selected inversions.
**** Add error on circular parameter definitions, bug329. [Alex Solomatnikov]
**** Fix concatenates and vectored bufif1, bug326. [Iztok Jeras]
* Verilator 3.811 2011/02/14
**** Report errors on duplicated or empty pins, bug321. [Christian Leber]
**** Report error on function call output tied to constant. [Bernard Deadman]
**** Throw UNUSED/UNDRIVEN only once per net in a parametrized module.
**** Fix internal error on functions called as SV tasks. [Bernard Deadman]
**** Fix internal error on non-inlined inout pins. [Jeff Winston]
**** Fix false BLKSEQ on non-unrolled for loop indexes. [Jeff Winston]
**** Fix block comment not separating identifiers, bug311. [Gene Sullivan]
**** Fix warnings to point to lowest net usage, not upper level ports.
**** Fix error on constants connected to outputs, bug323. [Christian Leber]
* Verilator 3.810 2011/01/03
** Add limited support for VPI access to public signals, see docs.
+4
View File
@@ -67,6 +67,10 @@ Usability:
#### non-comment lines, ##### ops, ### KB model size
* Default the --l2name to remove extra "v" level of hierarchy (flag to make "top")
Lint:
* CDCRSTLOGIC should allow filtering with paths
"waive CDCRSTLOGIC --from a.b.sig --to a.c.sig --via OR"
Internal Code:
* Eliminate the AstNUser* passed to all visitors; its only needed in V3Width,
and removing it will speed up and simplify all the other code.
+79 -15
View File
@@ -252,7 +252,7 @@ descriptions in the next sections for more information.
--exe Link to create executable
-F <file> Parse options from a file, relatively
-f <file> Parse options from a file
--gdbbt Run Verilator under GDB for backtrace
--gdbbt Run Verilator under GDB for backtrace
--help Display this help
-I<dir> Directory to search for includes
--if-depth <value> Tune IFDEPTH warning
@@ -292,6 +292,8 @@ descriptions in the next sections for more information.
--top-module <topname> Name of top level input module
--trace Enable waveform creation
--trace-depth <levels> Depth of tracing
--trace-max-array <bits> Maximum bit width for tracing
--trace-max-width <depth> Maximum array depth for tracing
--trace-underscore Enable tracing of _signals
-U<var> Undefine preprocessor define
--unroll-count <loops> Tune maximum loop iterations
@@ -304,6 +306,7 @@ descriptions in the next sections for more information.
-Wno-<message> Disable warning
-Wno-lint Disable all lint warnings
-Wno-style Disable all style warnings
-Wno-fatal Disable fatal exit on warnings
-x-assign <mode> Initially assign Xs to this value
-y <dir> Directory to search for modules
@@ -534,14 +537,18 @@ the command line that implement the main loop for your simulation.
Read the specified file, and act as if all text inside it was specified as
command line parameters. Any relative paths are relative to the directory
containing the specified file. Note -F is fairly standard across Verilog
tools.
containing the specified file. See also -f. Note -F is fairly standard
across Verilog tools.
=item -f I<file>
Read the specified file, and act as if all text inside it was specified as
command line parameters. Any relative paths are relative to the current
directory. Note -f is fairly standard across Verilog tools.
directory. See also -F. Note -f is fairly standard across Verilog tools.
The file may contain // comments which are ignored to the end of the line.
Any $VAR, $(VAR), or ${VAR} will be replaced with the specified environment
variable.
=item --gdbbt
@@ -610,7 +617,7 @@ appropriate `begin_keywords.
Specify the extensions that should be used for finding modules. If for
example module I<x> is referenced, look in I<x>.I<ext>. Note +libext+ is
fairly standard across Verilog tools.
fairly standard across Verilog tools. Defaults to .v and .sv.
=item --lint-only
@@ -816,6 +823,18 @@ Specify the number of levels deep to enable tracing, for example
entire model. Using a small number will decrease visibility, but greatly
improve runtime and trace file size.
=item --trace-max-array I<bits>
Rarely needed. Specify the maximum array depth of a signal that may be
traced. Defaults to 32, as tracing large arrays may greatly slow traced
simulations.
=item --trace-max-width I<depth>
Rarely needed. Specify the maximum bit width of a signal that may be
traced. Defaults to 256, as tracing large vectors may greatly slow traced
simulations.
=item --trace-underscore
Enable tracing of signals that start with an underscore. Normally, these
@@ -865,11 +884,11 @@ example C<-Werror-NOUNOPTFLAT>.
=item -Wfuture-I<message>
Suppress unknown Verilator comments or warning messages with the given
message code. This is used to allow code written with pragmas for a later
version of Verilator to run under a older version; add -Wfuture- arguments
for each message code or comment that the new version supports which the
older version does not support.
Rarely needed. Suppress unknown Verilator comments or warning messages
with the given message code. This is used to allow code written with
pragmas for a later version of Verilator to run under a older version; add
-Wfuture- arguments for each message code or comment that the new version
supports which the older version does not support.
=item -Wno-I<message>
@@ -894,6 +913,14 @@ already disabled). This is equivalent to "-Wno-DECLFILENAME -Wno-DEFPARAM
-Wno-INCABSPATH -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNUSED
-Wno-VARHIDDEN".
=item -Wno-fatal
When warnings are detected, print them, but do not exit the simulator.
Having warning messages in builds is sloppy. It is strongly recommended
you cleanup your code, use inline lint_off, or use -Wno-... flags rather
than using this option.
=item -Wwarn-I<message>
Enables the specified warning message.
@@ -954,7 +981,7 @@ We'll compile this example into C++.
cat <<EOF >our.v
module our;
initial begin \$display("Hello World"); \$finish; end
initial begin $display("Hello World"); $finish; end
endmodule
EOF
@@ -976,7 +1003,7 @@ your operating system (as an RPM), first you need to point to the kit:
export PATH=$VERILATOR_ROOT/bin:$PATH
Now we run Verilator on our little example.
verilator -Wall --cc our.v --exe sim_main.cpp
We can see the source code under the "obj_dir" directory. See the FILES
@@ -1019,7 +1046,7 @@ This is an example similar to the above, but using SystemPerl.
module our (clk);
input clk; // Clock is required to get initial activation
always @ (posedge clk)
begin \$display("Hello World"); \$finish; end
begin $display("Hello World"); $finish; end
endmodule
EOF
@@ -1410,6 +1437,38 @@ The /*verilator sformat*/ indicates that this function accepts a $display
like format specifier followed by any number of arguments to satisfy the
format.
=head2 DPI Context Functions
Verilator supports IEEE DPI Context Functions. Context imports pass the
simulator context, including calling scope name, and filename and line
number to the C code. For example, in Verilog:
import "DPI-C" context function int dpic_line();
initial $display("This is line %d, again, line %d\n", `line, dpic_line());
This will call C++ code which may then use the svGet* functions to read
information, in this case the line number of the Verilog statement that
invoked the dpic_line function:
int dpic_line() {
// Get a scope: svScope scope = svGetScope();
const char* scopenamep = svGetNameFromScope(scope);
assert(scopenamep);
const char* filenamep = "";
int lineno = 0;
if (svGetCallerInfo(&filenamep, &lineno)) {
printf("dpic_line called from scope %s on line %d\n",
scopenamep, lineno);
return lineno;
} else {
return 0;
}
}
See the IEEE Standard for more information.
=head2 DPI Header Isolation
Verilator places the IEEE standard header files such as svdpi.h into a
@@ -1421,7 +1480,7 @@ svdpi.h and similar standard files with different contents, the vltstd
directory should not be included to prevent picking up incompatible
definitions.
=head2 Public Functions
=head2 Public Functions
Instead of DPI exporting, there's also Verilator public functions, which
are slightly faster, but less compatible.
@@ -2080,7 +2139,7 @@ of the form:
inout driver;
wire driver = (enable) ? output_value : 1'bz;
Will be converted to
input driver__in; // Value being driven in from "external" drivers
@@ -2189,6 +2248,11 @@ Increment/decrement can only be used as standalone statements or in for
loops. They cannot be used as side effect operators inside more complicate
expressions ("a = b++;").
=item cast operator
Casting is supported only between simple scalar types, signed and unsigned,
not arrays nor structs.
=item chandle
Treated as a "longint"; does not yet warn about operations that are
+1
View File
@@ -192,6 +192,7 @@ string AstNode::prettyName(const string& namein) {
}
}
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
if (pretty.substr(0,5) == "TOP->") pretty.replace(0,5,"");
return pretty;
}
+1
View File
@@ -976,6 +976,7 @@ struct AstNodeUniop : public AstNodeMath {
setOp1p(lhsp); }
ASTNODE_BASE_FUNCS(NodeUniop)
AstNode* lhsp() const { return op1p()->castNode(); }
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
// METHODS
virtual void numberOperate(V3Number& out, const V3Number& lhs) = 0; // Set out to evaluation of a AstConst'ed lhs
virtual bool cleanLhs() = 0;
+2 -1
View File
@@ -522,7 +522,7 @@ void AstBasicDType::dump(ostream& str) {
str<<" ["<<keyword().ascii()<<"]";
if (implicit()) str<<" [IMPLICIT]";
}
void AstCast::dump(ostream& str) {
void AstCCast::dump(ostream& str) {
this->AstNode::dump(str);
str<<" sz"<<size();
}
@@ -611,6 +611,7 @@ void AstVar::dump(ostream& str) {
}
if (isUsedClock()) str<<" [C]";
if (isSigPublic()) str<<" [P]";
if (isUsedLoopIdx()) str<<" [LOOP]";
if (attrClockEn()) str<<" [aCLKEN]";
if (attrIsolateAssign()) str<<" [aISO]";
if (attrFileDescr()) str<<" [aFD]";
+45 -8
View File
@@ -559,6 +559,8 @@ private:
bool m_attrClockEn:1;// User clock enable attribute
bool m_attrIsolateAssign:1;// User isolate_assignments attribute
bool m_attrSFormat:1;// User sformat attribute
bool m_didSigning:1; // V3Signed completed; can skip iteration
bool m_didWidth:1; // V3Width completed; can skip iteration
bool m_fileDescr:1; // File descriptor
bool m_isConst:1; // Table contains constant data
bool m_isStatic:1; // Static variable
@@ -572,6 +574,7 @@ private:
m_sigPublic=false; m_sigModPublic=false; m_sigUserRdPublic=false; m_sigUserRWPublic=false;
m_funcLocal=false; m_funcReturn=false;
m_attrClockEn=false; m_attrIsolateAssign=false; m_attrSFormat=false;
m_didSigning=false; m_didWidth=false;
m_fileDescr=false; m_isConst=false; m_isStatic=false;
m_trace=false;
}
@@ -634,6 +637,10 @@ public:
void attrScClocked(bool flag) { m_scClocked = flag; }
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
void attrSFormat(bool flag) { m_attrSFormat = flag; }
void didSigning(bool flag) { m_didSigning=flag; }
bool didSigning() const { return m_didSigning; }
void didWidth(bool flag) { m_didWidth=flag; }
bool didWidth() const { return m_didWidth; }
void usedClock(bool flag) { m_usedClock = flag; }
void usedParam(bool flag) { m_usedParam = flag; }
void usedLoopIdx(bool flag) { m_usedLoopIdx = flag; }
@@ -912,7 +919,9 @@ public:
,m_name(name), m_svImplicit(false) {
m_pinNum = pinNum;
m_modVarp = NULL;
setNOp1p(exprp); }
setNOp1p(exprp);
if (exprp) widthSignedFrom(exprp);
}
ASTNODE_NODE_FUNCS(Pin, PIN)
virtual void dump(ostream& str);
virtual bool broken() const { return (m_modVarp && !m_modVarp->brokeExists()); }
@@ -921,7 +930,7 @@ public:
bool dotStar() const { return name() == ".*"; } // Special fake name for .* connections until linked
int pinNum() const { return m_pinNum; }
void exprp(AstNode* nodep) { addOp1p(nodep); }
AstNode* exprp() const { return op1p()->castNode(); } // op1 = Expression connected to pin
AstNode* exprp() const { return op1p()->castNode(); } // op1 = Expression connected to pin, NULL if unconnected
AstVar* modVarp() const { return m_modVarp; } // [After Link] Pointer to variable
void modVarp(AstVar* varp) { m_modVarp=varp; }
bool svImplicit() const { return m_svImplicit; }
@@ -2613,27 +2622,42 @@ struct AstOneHot0 : public AstNodeUniop {
virtual int instrCount() const { return widthInstrs()*3; }
};
struct AstCast : public AstNodeUniop {
// Cast to appropriate data type
struct AstCast : public AstNode {
// Cast to appropriate data type - note lhsp is value, to match AstTypedef, AstCCast, etc
AstCast(FileLine* fl, AstNode* lhsp, AstNodeDType* dtypep) : AstNode(fl) {
setOp1p(lhsp); setOp2p(dtypep);
if (dtypep) { widthSignedFrom(dtypep); }
}
ASTNODE_NODE_FUNCS(Cast, CAST)
virtual string emitVerilog() { return "((%r)'(%l))"; }
virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() { V3ERROR_NA; return true;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;}
AstNode* lhsp() const { return op1p(); }
AstNodeDType* dtypep() const { return op2p()->castNodeDType(); }
};
struct AstCCast : public AstNodeUniop {
// Cast to C-based data type
private:
int m_size;
public:
AstCast(FileLine* fl, AstNode* lhsp, int setwidth) : AstNodeUniop(fl, lhsp) {
AstCCast(FileLine* fl, AstNode* lhsp, int setwidth) : AstNodeUniop(fl, lhsp) {
m_size=setwidth;
if (setwidth) { width(setwidth,setwidth); }
}
AstCast(FileLine* fl, AstNode* lhsp, AstNode* widthFromp) : AstNodeUniop(fl, lhsp) {
AstCCast(FileLine* fl, AstNode* lhsp, AstNode* widthFromp) : AstNodeUniop(fl, lhsp) {
if (widthFromp) { widthSignedFrom(widthFromp); }
m_size=width();
}
ASTNODE_NODE_FUNCS(Cast, CAST)
ASTNODE_NODE_FUNCS(CCast, CCAST)
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); }
virtual string emitVerilog() { return "%f$_CAST(%l)"; }
virtual string emitC() { return "VL_CAST_%nq%lq(%nw,%lw, %P, %li)"; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;} // Special cased in V3Cast
virtual V3Hash sameHash() const { return V3Hash(size()); }
virtual bool same(AstNode* samep) const { return size()==samep->castCast()->size(); }
virtual bool same(AstNode* samep) const { return size()==samep->castCCast()->size(); }
virtual void dump(ostream& str=cout);
//
int size() const { return m_size; }
@@ -3150,6 +3174,19 @@ struct AstReplicate : public AstNodeBiop {
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
virtual int instrCount() const { return widthInstrs()*2; }
};
struct AstBufIf1 : public AstNodeBiop {
// lhs is enable, rhs is data to drive
AstBufIf1(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
if (lhsp) widthSignedFrom(lhsp); }
ASTNODE_NODE_FUNCS(BufIf1, BUFIF1)
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opBufIf1(lhs,rhs); }
virtual string emitVerilog() { return "bufif(%r,%l)"; }
virtual string emitC() { V3ERROR_NA; return false;} // Lclean || Rclean
virtual string emitSimpleOperator() { V3ERROR_NA; return false;} // Lclean || Rclean
virtual bool cleanOut() {V3ERROR_NA; return false;} // Lclean || Rclean
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
};
struct AstFGetS : public AstNodeBiop {
AstFGetS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {}
ASTNODE_NODE_FUNCS(FGetS, FGETS)
+1 -1
View File
@@ -162,7 +162,7 @@ private:
m_ifDepth = -1;
} else if (++m_ifDepth > v3Global.opt.ifDepth()) {
nodep->v3warn(IFDEPTH,"Deep 'if' statement; suggest unique/priority to avoid slow logic");
nodep->fileline()->warnOn(V3ErrorCode::IFDEPTH, false); // Warn only once
nodep->fileline()->modifyWarnOff(V3ErrorCode::IFDEPTH, true); // Warn only once
m_ifDepth = -1;
}
nodep->iterateChildren(*this);
+5 -5
View File
@@ -77,7 +77,7 @@ private:
AstNRelinker relinkHandle;
nodep->unlinkFrBack(&relinkHandle);
//
AstCast* castp = new AstCast (nodep->fileline(), nodep, needsize);
AstCCast* castp = new AstCCast (nodep->fileline(), nodep, needsize);
castp->width(needsize, nodep->widthMin());
relinkHandle.relink(castp);
//if (debug()>8) castp->dumpTree(cout,"-castins: ");
@@ -97,13 +97,13 @@ private:
insertCast(nodep, castSize(nodep->backp()));
}
}
void insureLower32Cast(AstCast* nodep) {
void insureLower32Cast(AstCCast* nodep) {
// If we have uint64 = CAST(uint64(x)) then the upcasting
// really needs to be CAST(uint64(CAST(uint32(x))).
// Otherwise a (uint64)(a>b) would return wrong value, as
// less than has undeterministic signedness.
if (nodep->isQuad() && !nodep->lhsp()->isQuad()
&& !nodep->lhsp()->castCast()) {
&& !nodep->lhsp()->castCCast()) {
insertCast(nodep->lhsp(), VL_WORDSIZE);
}
}
@@ -130,7 +130,7 @@ private:
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
if (nodep->sizeMattersThs()) insureCast(nodep->thsp());
}
virtual void visit(AstCast* nodep, AstNUser*) {
virtual void visit(AstCCast* nodep, AstNUser*) {
nodep->iterateChildren(*this);
insureLower32Cast(nodep);
nodep->user1(1);
@@ -149,7 +149,7 @@ private:
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (!nodep->lvalue()
&& !nodep->backp()->castCast()
&& !nodep->backp()->castCCast()
&& nodep->backp()->castNodeMath()
&& nodep->backp()->width()
&& castSize(nodep) != castSize(nodep->varp())) {
+15 -10
View File
@@ -65,9 +65,9 @@ class CdcEitherVertex : public V3GraphVertex {
AstNode* m_nodep;
AstSenTree* m_srcDomainp;
AstSenTree* m_dstDomainp;
bool m_srcDomainSet;
bool m_dstDomainSet;
bool m_asyncPath;
bool m_srcDomainSet:1;
bool m_dstDomainSet:1;
bool m_asyncPath:1;
public:
CdcEitherVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep)
: V3GraphVertex(graphp), m_scopep(scopep), m_nodep(nodep)
@@ -109,11 +109,12 @@ public:
};
class CdcLogicVertex : public CdcEitherVertex {
bool m_hazard;
bool m_isFlop;
bool m_hazard:1;
bool m_isFlop:1;
public:
CdcLogicVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep, AstSenTree* sensenodep)
: CdcEitherVertex(graphp,scopep,nodep), m_hazard(false), m_isFlop(false)
: CdcEitherVertex(graphp,scopep,nodep)
, m_hazard(false), m_isFlop(false)
{ srcDomainp(sensenodep); dstDomainp(sensenodep); }
virtual ~CdcLogicVertex() {}
// Accessors
@@ -132,7 +133,7 @@ class CdcDumpVisitor : public CdcBaseVisitor {
private:
// NODE STATE
//Entire netlist:
// {statement}Node::user3p -> bool, indicating not hazard
// {statement}Node::user3 -> bool, indicating not hazard
ofstream* m_ofp; // Output file
string m_prefix;
@@ -290,9 +291,12 @@ private:
void setNodeHazard(AstNode* nodep) {
// Need to not clear if warnings are off (rather than when report it)
// as bypassing this warning may turn up another path that isn't warning off'ed.
// We can't modifyWarnOff here, as one instantiation might not be an issue until we find a hitting flop
// Furthermore, a module like a "Or" module would only get flagged once,
// even though the signals feeding it are radically different.
if (!m_domainp || m_domainp->hasCombo()) { // Source flop logic in a posedge block is OK for reset (not async though)
if (m_logicVertexp && !nodep->fileline()->warnIsOff(V3ErrorCode::CDCRSTLOGIC)) {
UINFO(9,"Set hazard "<<nodep<<endl);
UINFO(8,"Set hazard "<<nodep<<endl);
m_logicVertexp->setHazard(nodep);
}
}
@@ -335,7 +339,7 @@ private:
if (CdcVarVertex* vvertexp = dynamic_cast<CdcVarVertex*>(itp)) {
if (vvertexp->cntAsyncRst()) {
m_userGeneration++; // Effectively a userClearVertices()
UINFO(9, " Trace One async: "<<vvertexp<<endl);
UINFO(8, " Trace One async: "<<vvertexp<<endl);
// Twice, as we need to detect, then propagate
CdcEitherVertex* markp = traceAsyncRecurse(vvertexp, false);
if (markp) { // Mark is non-NULL if something bad on this path
@@ -351,7 +355,8 @@ private:
}
CdcEitherVertex* traceAsyncRecurse(CdcEitherVertex* vertexp, bool mark) {
// Return vertex of any hazardous stuff attached, or NULL if OK
// First pass: Return vertex of any hazardous stuff attached, or NULL if OK
// If first pass returns true, second pass calls asyncPath() on appropriate nodes
if (vertexp->user()>=m_userGeneration) return false; // Processed - prevent loop
vertexp->user(m_userGeneration);
+110 -8
View File
@@ -290,13 +290,61 @@ private:
// SEL(EXTEND(any,width,...),(width-1),0) -> ...
// Since select's return unsigned, this is always an extend
AstExtend* extendp = nodep->fromp()->castExtend();
return (m_doV
&& extendp
&& nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
&& nodep->lsbConst()==0
&& (int)nodep->widthConst()==extendp->lhsp()->width()
);
if (!(m_doV
&& extendp
&& nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
&& nodep->lsbConst()==0
&& (int)nodep->widthConst()==extendp->lhsp()->width()
)) return false;
replaceWChild(nodep, extendp->lhsp()); nodep=NULL;
return true;
}
bool operandSelBiLower(AstSel* nodep) {
// SEL(ADD(a,b),(width-1),0) -> ADD(SEL(a),SEL(b))
// Add or any operation which doesn't care if we discard top bits
AstNodeBiop* bip = nodep->fromp()->castNodeBiop();
if (!(m_doV
&& bip
&& nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
&& nodep->lsbConst()==0
)) return false;
if (debug()>=9) nodep->dumpTree(cout,"SEL(BI)-in:");
AstNode* bilhsp = bip->lhsp()->unlinkFrBack();
AstNode* birhsp = bip->rhsp()->unlinkFrBack();
bip->lhsp(new AstSel(nodep->fileline(), bilhsp, 0, nodep->widthConst()));
bip->rhsp(new AstSel(nodep->fileline(), birhsp, 0, nodep->widthConst()));
if (debug()>=9) bip->dumpTree(cout,"SEL(BI)-ou:");
replaceWChild(nodep, bip); nodep=NULL;
return true;
}
bool operandBiExtendConst(AstNodeBiop* nodep) {
// Loop unrolling likes standalone compares
// EQ(EXTEND(xx{width3}), const{width32}) -> EQ(xx{3},const{3})
// Beware that the constant must have zero bits (+ 1 if signed) or compare
// would be incorrect
AstExtend* extendp = nodep->lhsp()->castExtend();
if (!extendp) return false;
AstNode* smallerp = extendp->lhsp();
int subsize = smallerp->width();
AstConst* constp = nodep->rhsp()->castConst();
if (!constp) return false;
if (!constp->num().isBitsZero(constp->width()-1, subsize)) return false;
//
if (debug()>=9) nodep->dumpTree(cout,"BI(EXTEND)-in:");
smallerp->unlinkFrBack();
extendp->unlinkFrBack()->deleteTree(); // aka nodep->lhsp.
nodep->lhsp(smallerp);
constp->unlinkFrBack();
V3Number num (constp->fileline(), subsize);
num.opAssign(constp->num());
nodep->rhsp(new AstConst(constp->fileline(), num));
constp->deleteTree(); constp=NULL;
if (debug()>=9) nodep->dumpTree(cout,"BI(EXTEND)-ou:");
return true;
}
AstNode* afterComment(AstNode* nodep) {
@@ -1061,6 +1109,38 @@ private:
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
}
void replaceSelIntoBiop(AstSel* nodep) {
// SEL(BUFIF1(a,b),1,bit) => BUFIF1(SEL(a,1,bit),SEL(b,1,bit))
AstNodeBiop* fromp = nodep->fromp()->unlinkFrBack()->castNodeBiop();
if (!fromp) nodep->v3fatalSrc("Called on non biop");
AstNode* lsbp = nodep->lsbp()->unlinkFrBack();
AstNode* widthp = nodep->widthp()->unlinkFrBack();
//
AstNode* bilhsp = fromp->lhsp()->unlinkFrBack();
AstNode* birhsp = fromp->rhsp()->unlinkFrBack();
//
fromp->lhsp(new AstSel(nodep->fileline(),
bilhsp, lsbp->cloneTree(true), widthp->cloneTree(true)));
fromp->rhsp(new AstSel(nodep->fileline(),
birhsp, lsbp, widthp));
fromp->widthSignedFrom(nodep);
nodep->replaceWith(fromp); nodep->deleteTree(); nodep=NULL;
}
void replaceSelIntoUniop(AstSel* nodep) {
// SEL(NOT(a),1,bit) => NOT(SEL(a,bit))
AstNodeUniop* fromp = nodep->fromp()->unlinkFrBack()->castNodeUniop();
if (!fromp) nodep->v3fatalSrc("Called on non biop");
AstNode* lsbp = nodep->lsbp()->unlinkFrBack();
AstNode* widthp = nodep->widthp()->unlinkFrBack();
//
AstNode* bilhsp = fromp->lhsp()->unlinkFrBack();
//
fromp->lhsp(new AstSel(nodep->fileline(),
bilhsp, lsbp->cloneTree(true), widthp->cloneTree(true)));
fromp->widthSignedFrom(nodep);
nodep->replaceWith(fromp); nodep->deleteTree(); nodep=NULL;
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (!nodep->varp()) nodep->v3fatalSrc("Not linked");
@@ -1684,6 +1764,13 @@ private:
TREEOP ("AstShiftL{operandShiftShift(nodep)}", "replaceShiftShift(nodep)");
TREEOP ("AstShiftR{operandShiftShift(nodep)}", "replaceShiftShift(nodep)");
TREEOP ("AstWordSel{operandWordOOB(nodep)}", "replaceZero(nodep)");
// Compress out EXTENDs to appease loop unroller
TREEOPV("AstEq {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstNeq {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstGt {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstGte {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstLt {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstLte {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
// Identical operands on both sides
// AstLogAnd/AstLogOr already converted to AstAnd/AstOr for these rules
// AstAdd->ShiftL(#,1) but uncommon
@@ -1761,12 +1848,27 @@ private:
TREEOPV("AstReplicate{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs
// Next rule because AUTOINST puts the width of bits in
// to pins, even when the widths are exactly the same across the hierarchy.
TREEOPV("AstSel{operandSelExtend(nodep)}", "replaceWChild(nodep, nodep->fromp()->castExtend()->lhsp())");
TREEOPV("AstSel{operandSelExtend(nodep)}", "DONE");
TREEOPV("AstSel{operandSelFull(nodep)}", "replaceWChild(nodep, nodep->fromp())");
TREEOPV("AstSel{$fromp.castSel}", "replaceSelSel(nodep)");
TREEOPV("AstSel{$fromp.castAdd, operandSelBiLower(nodep)}", "DONE");
TREEOPV("AstSel{$fromp.castAnd, operandSelBiLower(nodep)}", "DONE");
TREEOPV("AstSel{$fromp.castOr, operandSelBiLower(nodep)}", "DONE");
TREEOPV("AstSel{$fromp.castSub, operandSelBiLower(nodep)}", "DONE");
TREEOPV("AstSel{$fromp.castXnor,operandSelBiLower(nodep)}", "DONE");
TREEOPV("AstSel{$fromp.castXor, operandSelBiLower(nodep)}", "DONE");
TREEOPC("AstSel{$fromp.castConst, $lsbp.castConst, $widthp.castConst, }", "replaceConst(nodep)");
TREEOPV("AstSel{$fromp.castConcat, $lsbp.castConst, $widthp.castConst, }", "replaceSelConcat(nodep)");
TREEOPV("AstSel{$fromp.castReplicate, $lsbp.castConst, $widthp.isOne, }", "replaceSelReplicate(nodep)");
// V3Tristate requires selects below BufIf1.
// Also do additional operators that are bit-independent, but only definite
// win if bit select is a constant (otherwise we may need to compute bit index several times)
TREEOPV("AstSel{$fromp.castBufIf1}", "replaceSelIntoBiop(nodep)");
TREEOPV("AstSel{$fromp.castNot}", "replaceSelIntoUniop(nodep)");
TREEOPV("AstSel{$fromp.castAnd,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
TREEOPV("AstSel{$fromp.castOr,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
TREEOPV("AstSel{$fromp.castXor,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
TREEOPV("AstSel{$fromp.castXnor,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
// Conversions
TREEOPV("AstRedXnor{$lhsp}", "AstNot{AstRedXor{$lhsp}}"); // Just eliminate XNOR's
TREEOPV("AstLogIf {$lhsp, $rhsp}", "AstLogOr{AstLogNot{$lhsp},$rhsp}");
+1 -3
View File
@@ -345,9 +345,7 @@ private:
m_nextDlyp = NULL;
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (!nodep->user2()) { // Not done yet
nodep->user2(true);
if (!nodep->user2Inc()) { // Not done yet
if (m_inDly && nodep->lvalue()) {
UINFO(4,"AssignDlyVar: "<<nodep<<endl);
markVarUsage(nodep->varScopep(), VU_DLY);
+1 -1
View File
@@ -475,7 +475,7 @@ public:
}
visit(nodep->castNodeBiop(), vup);
}
virtual void visit(AstCast* nodep, AstNUser*) {
virtual void visit(AstCCast* nodep, AstNUser*) {
// Extending a value of the same word width is just a NOP.
if (nodep->size()>VL_WORDSIZE) {
puts("(QData)(");
+6 -6
View File
@@ -74,7 +74,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
putfs(nodep, nodep->isFunction() ? "function":"task");
puts(" ");
puts(nodep->name());
puts(nodep->prettyName());
puts(";\n");
putqs(nodep, "begin\n"); // Only putfs the first time for each visitor; later for same node is putqs
nodep->stmtsp()->iterateAndNext(*this);
@@ -472,17 +472,17 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
virtual void visit(AstTypedef* nodep, AstNUser*) {
putfs(nodep,"typedef ");
nodep->dtypep()->iterateAndNext(*this); puts(" ");
puts(nodep->name());
puts(nodep->prettyName());
puts(";\n");
}
virtual void visit(AstBasicDType* nodep, AstNUser*) {
if (nodep->isSigned()) putfs(nodep,"signed ");
putfs(nodep,nodep->prettyName());
if (nodep->rangep()) { nodep->rangep()->iterateAndNext(*this); puts(" "); }
if (nodep->rangep()) { puts(" "); nodep->rangep()->iterateAndNext(*this); puts(" "); }
}
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
if (nodep->dotted()!="") { putfs(nodep,nodep->dotted()); puts("."); puts(nodep->name()); }
else { putfs(nodep,nodep->name()); }
if (nodep->dotted()!="") { putfs(nodep,nodep->dotted()); puts("."); puts(nodep->prettyName()); }
else { putfs(nodep,nodep->prettyName()); }
puts("(");
nodep->pinsp()->iterateAndNext(*this);
puts(")");
@@ -520,7 +520,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
putfs(nodep,nodep->verilogKwd());
puts(" ");
nodep->dtypep()->iterateAndNext(*this); puts(" ");
puts(nodep->name());
puts(nodep->prettyName());
puts(";\n");
}
virtual void visit(AstActive* nodep, AstNUser*) {
+1 -1
View File
@@ -309,7 +309,7 @@ void V3Error::abortIfErrors() {
}
void V3Error::abortIfWarnings() {
if (errorOrWarnCount()) {
if (v3Global.opt.warnFatal() ? errorOrWarnCount() : errorCount()) {
v3fatal ("Exiting due to "<<dec<<errorOrWarnCount()<<" warning(s)\n");
}
}
+20 -20
View File
@@ -127,18 +127,18 @@ private:
} else if (nodep->isQuad() && word==0) {
AstNode* quadfromp = nodep->cloneTree(true);
quadfromp->width(VL_QUADSIZE,quadfromp->widthMin());
return new AstCast (nodep->fileline(),
quadfromp,
VL_WORDSIZE);
return new AstCCast (nodep->fileline(),
quadfromp,
VL_WORDSIZE);
} else if (nodep->isQuad() && word==1) {
AstNode* quadfromp = nodep->cloneTree(true);
quadfromp->width(VL_QUADSIZE,quadfromp->widthMin());
return new AstCast (nodep->fileline(),
new AstShiftR (nodep->fileline(),
quadfromp,
new AstConst (nodep->fileline(), VL_WORDSIZE),
VL_WORDSIZE),
VL_WORDSIZE);
return new AstCCast (nodep->fileline(),
new AstShiftR (nodep->fileline(),
quadfromp,
new AstConst (nodep->fileline(), VL_WORDSIZE),
VL_WORDSIZE),
VL_WORDSIZE);
} else if (!nodep->isWide() && !nodep->isQuad() && word==0) {
return nodep->cloneTree(true);
} else { // Out of bounds
@@ -324,7 +324,7 @@ private:
nodep->v3fatalSrc("extending larger thing into smaller?");
} else {
UINFO(8," EXTEND(q<-l) "<<nodep<<endl);
newp = new AstCast (nodep->fileline(), lhsp, nodep);
newp = new AstCCast (nodep->fileline(), lhsp, nodep);
}
} else { // Long
if (lhsp->isQuad() || lhsp->isWide()) {
@@ -366,7 +366,7 @@ private:
AstNode* lowwordp = new AstWordSel (nodep->fromp()->fileline(),
nodep->fromp()->cloneTree(true),
newSelBitWord(nodep->lsbp(), 0));
if (nodep->isQuad() && !lowwordp->isQuad()) lowwordp = new AstCast(nodep->fileline(), lowwordp, nodep);
if (nodep->isQuad() && !lowwordp->isQuad()) lowwordp = new AstCCast(nodep->fileline(), lowwordp, nodep);
AstNode* lowp = new AstShiftR (nodep->fileline(),
lowwordp,
newSelBitBit(nodep->lsbp()),
@@ -379,7 +379,7 @@ private:
new AstWordSel (nodep->fromp()->fileline(),
nodep->fromp()->cloneTree(true),
newSelBitWord(nodep->lsbp(), 1));
if (nodep->isQuad() && !midwordp->isQuad()) midwordp = new AstCast(nodep->fileline(), midwordp, nodep);
if (nodep->isQuad() && !midwordp->isQuad()) midwordp = new AstCCast(nodep->fileline(), midwordp, nodep);
// If we're selecting bit zero, then all 32 bits in word 1 get shifted << by 32 bits
// else we need to form the lower word, so we << by 31 or less
// nbitsfromlow <= (lsb==0) ? 64-bitbit(lsb) : 32-bitbit(lsb)
@@ -417,7 +417,7 @@ private:
new AstWordSel (nodep->fromp()->fileline(),
nodep->fromp()->cloneTree(true),
newSelBitWord(nodep->lsbp(), 2));
if (nodep->isQuad() && !hiwordp->isQuad()) hiwordp = new AstCast(nodep->fileline(), hiwordp, nodep);
if (nodep->isQuad() && !hiwordp->isQuad()) hiwordp = new AstCCast(nodep->fileline(), hiwordp, nodep);
AstNode* himayp =
new AstShiftL (nodep->fileline(),
hiwordp,
@@ -445,14 +445,14 @@ private:
UINFO(8," SEL->SHIFT "<<nodep<<endl);
AstNode* fromp = nodep->fromp()->unlinkFrBack();
AstNode* lsbp = nodep->lsbp()->unlinkFrBack();
if (nodep->isQuad() && !fromp->isQuad()) fromp = new AstCast(nodep->fileline(), fromp, nodep);
if (nodep->isQuad() && !fromp->isQuad()) fromp = new AstCCast(nodep->fileline(), fromp, nodep);
AstNode* newp = new AstShiftR (nodep->fileline(),
fromp,
dropCondBound(lsbp),
nodep->width());
newp->widthSignedFrom(nodep);
if (!nodep->isQuad() && fromp->isQuad()) {
newp = new AstCast (newp->fileline(), newp, nodep);
newp = new AstCCast (newp->fileline(), newp, nodep);
}
newp->widthSignedFrom(nodep);
replaceWithDelete(nodep,newp); nodep=NULL;
@@ -546,7 +546,7 @@ private:
destp->deleteTree(); destp=NULL;
} else {
UINFO(8," ASSIGNSEL(const,narrow) "<<nodep<<endl);
if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCast(nodep->fileline(), rhsp, nodep);
if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep);
AstNode* oldvalp = destp->cloneTree(true);
fixCloneLvalue(oldvalp);
if (!ones) oldvalp = new AstAnd (lhsp->fileline(),
@@ -620,7 +620,7 @@ private:
V3Number maskwidth (nodep->fileline(), destp->widthMin());
for (int bit=0; bit<(int)lhsp->widthConst(); bit++) maskwidth.setBit(bit,1);
if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCast(nodep->fileline(), rhsp, nodep);
if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep);
if (!ones)
oldvalp = new AstAnd (lhsp->fileline(),
new AstNot (lhsp->fileline(),
@@ -655,8 +655,8 @@ private:
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
int rhsshift = rhsp->widthMin();
if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCast(nodep->fileline(), lhsp, nodep);
if (nodep->isQuad() && !rhsp->isQuad()) rhsp = new AstCast(nodep->fileline(), rhsp, nodep);
if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCCast(nodep->fileline(), lhsp, nodep);
if (nodep->isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep);
AstNode* newp = new AstOr (nodep->fileline(),
new AstShiftL (nodep->fileline(),
lhsp,
@@ -703,7 +703,7 @@ private:
AstConst* constp = nodep->rhsp()->castConst();
if (!constp) nodep->v3fatalSrc("Replication value isn't a constant. Checked earlier!");
uint32_t times = constp->toUInt();
if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCast(nodep->fileline(), lhsp, nodep);
if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCCast(nodep->fileline(), lhsp, nodep);
newp = lhsp->cloneTree(true);
for (unsigned repnum=1; repnum<times; repnum++) {
int rhsshift = repnum*lhswidth;
+6
View File
@@ -719,6 +719,12 @@ private:
// Prevent a infinite loop...
substp->v3fatalSrc("Replacing node with itself; perhaps circular logic?");
}
// Which fileline() to use?
// If replacing with logic, an error/warning is likely to want to point to the logic
// IE what we're replacing with.
// However a VARREF should point to the original as it's otherwise confusing
// to throw warnings that point to a PIN rather than where the pin us used.
if (substp->castVarRef()) substp->fileline(nodep->fileline());
nodep->replaceWith(substp);
nodep->deleteTree(); nodep=NULL;
}
+5 -1
View File
@@ -140,6 +140,10 @@ private:
if (!connectRefp->castConst() && !connectRefp->castVarRef()) {
pinp->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up\n");
}
if (pinNewVarp->isOutOnly() && connectRefp->castConst()) {
pinp->v3error("Output port is connected to a constant pin, electrical short");
}
// Propagate any attributes across the interconnect
pinNewVarp->propagateAttrFrom(pinOldVarp);
if (connectRefp->castVarRef()) {
@@ -180,7 +184,7 @@ private:
// user2p is either a const or a var.
AstConst* exprconstp = nodep->user2p()->castNode()->castConst();
AstVarRef* exprvarrefp = nodep->user2p()->castNode()->castVarRef();
UINFO(1,"connectto: "<<nodep->user2p()->castNode()<<endl);
UINFO(8,"connectto: "<<nodep->user2p()->castNode()<<endl);
if (!exprconstp && !exprvarrefp) {
nodep->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up\n");
}
+20 -1
View File
@@ -55,9 +55,11 @@ private:
// AstNodeModule::user4p() // V3SymTable* Module's Symbol table
// AstNodeFTask::user4p() // V3SymTable* Local Symbol table
// AstBegin::user4p() // V3SymTable* Local Symbol table
// AstVar::user5p() // AstPin* True if port attached to a pin
AstUser2InUse m_inuser2;
AstUser3InUse m_inuser3;
AstUser4InUse m_inuser4;
AstUser5InUse m_inuser5;
// ENUMS
enum IdState { // Which loop through the tree
@@ -498,6 +500,7 @@ private:
if (!taskp) { nodep->v3error("Can't find definition of task/function: "<<nodep->prettyName()); }
nodep->taskp(taskp);
nodep->packagep(packageFor(taskp));
if (taskp->castTask() && nodep->castFuncRef()) nodep->v3error("Illegal call of a task as a function: "<<nodep->prettyName());
}
}
nodep->iterateChildren(*this);
@@ -551,6 +554,7 @@ private:
virtual void visit(AstCell* nodep, AstNUser*) {
// Cell: Resolve its filename. If necessary, parse it.
m_cellp = nodep;
AstNode::user5ClearTree();
if (m_idState==ID_FIND) {
// Add to list of all cells, for error checking and defparam's
findAndInsertAndCheck(nodep, nodep->name());
@@ -635,11 +639,26 @@ private:
nodep->v3error("Pin is not an in/out/inout/param: "<<nodep->prettyName());
} else {
nodep->modVarp(refp);
if (refp->user5p() && refp->user5p()->castNode()!=nodep) {
nodep->v3error("Duplicate pin connection: "<<nodep->prettyName());
refp->user5p()->castNode()->v3error("... Location of original pin connection");
} else {
refp->user5p(nodep);
}
}
if (!nodep->exprp()) {
// It's an empty pin connection, done with it.
// (We used to not create pins for these, but we'd miss
// warns. Perhaps they should live even further...)
pushDeletep(nodep->unlinkFrBack()); nodep=NULL;
return;
}
nodep->iterateChildren(*this);
}
// Deal with implicit definitions - do before ID_RESOLVE stage as may be referenced above declaration
if (m_idState==ID_PARAM && !nodep->svImplicit()) { // SV 19.11.3: .name pins don't allow implicit decls
if (m_idState==ID_PARAM
&& nodep->exprp() // Else specifically unconnected pin
&& !nodep->svImplicit()) { // SV 19.11.3: .name pins don't allow implicit decls
pinImplicitExprRecurse(nodep->exprp());
}
// Early return() above when deleted
+12
View File
@@ -193,6 +193,18 @@ private:
new V3GraphEdge(&m_graph, vertex(m_modp), vertex(modp), 1, false);
}
}
// Remove AstCell(AstPin("",NULL)), it's a side effect of how we parse "()"
// the empty middle is identical to the empty rule that must find pins in "(,)".
if (nodep->pinsp() && !nodep->pinsp()->nextp()
&& nodep->pinsp()->name() == ""
&& !nodep->pinsp()->exprp()) {
pushDeletep(nodep->pinsp()->unlinkFrBackWithNext());
}
if (nodep->paramsp() && !nodep->paramsp()->nextp()
&& nodep->paramsp()->name() == ""
&& !nodep->paramsp()->exprp()) {
pushDeletep(nodep->paramsp()->unlinkFrBackWithNext());
}
// Convert .* to list of pins
bool pinStar = false;
for (AstPin* nextp, *pinp = nodep->pinsp(); pinp; pinp=nextp) {
+15 -1
View File
@@ -50,6 +50,7 @@ private:
AstModule* m_modp; // Current module
AstNodeFTask* m_ftaskp; // Current function/task
AstWhile* m_loopp; // Current loop
bool m_loopInc; // In loop increment
int m_repeatNum; // Repeat counter
BeginStack m_beginStack; // All begin blocks above current node
@@ -136,6 +137,7 @@ private:
AstLogicPacked(), 32);
varp->isSigned(true);
varp->dtypep()->isSigned(true);
varp->usedLoopIdx(true);
m_modp->addStmtp(varp);
AstNode* initsp = new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true),
countp);
@@ -158,8 +160,15 @@ private:
virtual void visit(AstWhile* nodep, AstNUser*) {
// Don't need to track AstRepeat/AstFor as they have already been converted
AstWhile* lastLoopp = m_loopp;
bool lastInc = m_loopInc;
m_loopp = nodep;
nodep->iterateChildren(*this);
m_loopInc = false;
nodep->precondsp()->iterateAndNext(*this);
nodep->condp()->iterateAndNext(*this);
nodep->bodysp()->iterateAndNext(*this);
m_loopInc = true;
nodep->incsp()->iterateAndNext(*this);
m_loopInc = lastInc;
m_loopp = lastLoopp;
}
virtual void visit(AstReturn* nodep, AstNUser*) {
@@ -202,7 +211,11 @@ private:
}
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (m_loopInc && nodep->varp()) nodep->varp()->usedLoopIdx(true);
}
virtual void visit(AstConst* nodep, AstNUser*) {}
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
@@ -212,6 +225,7 @@ public:
m_modp = NULL;
m_ftaskp = NULL;
m_loopp = NULL;
m_loopInc = false;
m_repeatNum = 0;
nodep->accept(*this);
}
+32 -1
View File
@@ -33,6 +33,7 @@
#include <cstdarg>
#include <unistd.h>
#include <map>
#include <set>
#include <algorithm>
#include <vector>
@@ -47,11 +48,14 @@ class LinkParseVisitor : public AstNVisitor {
private:
// NODE STATE
// Cleared on netlist
// AstNode::user() -> bool. True if processed
// AstNode::user1() -> bool. True if processed
// AstNode::user2() -> bool. True if fileline recomputed
AstUser1InUse m_inuser1;
AstUser2InUse m_inuser2;
// TYPES
typedef map <pair<void*,string>,AstTypedef*> ImplTypedefMap;
typedef set <FileLine*> FileLineSet;
// STATE
string m_dotText; // Dotted module text we are building for a dotted node, passed up
@@ -60,6 +64,7 @@ private:
AstText* m_baseTextp; // Lowest TEXT node that needs replacement with varref
AstVar* m_varp; // Variable we're under
ImplTypedefMap m_implTypedef; // Created typedefs for each <container,name>
FileLineSet m_filelines; // Filelines that have been seen
// METHODS
static int debug() {
@@ -68,6 +73,21 @@ private:
return level;
}
void cleanFileline(AstNode* nodep) {
if (!nodep->user2Inc()) { // Process once
// We make all filelines unique per AstNode. This allows us to
// later turn off messages on a fileline when an issue is found
// so that messages on replicated blocks occur only once,
// without suppressing other token's messages as a side effect.
// We could have verilog.l create a new one on every token,
// but that's a lot more structures than only doing AST nodes.
if (m_filelines.find(nodep->fileline()) != m_filelines.end()) {
nodep->fileline(new FileLine(nodep->fileline()));
}
m_filelines.insert(nodep->fileline());
}
}
void checkExpected(AstNode* nodep) {
if (m_exp != AstParseRefExp::PX_NONE) {
nodep->v3fatalSrc("Tree syntax error: Not expecting "<<nodep->type()<<" under a "<<nodep->backp()->type());
@@ -78,6 +98,7 @@ private:
// VISITs
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
if (!nodep->user1Inc()) { // Process only once.
cleanFileline(nodep);
UINFO(5," "<<nodep<<endl);
checkExpected(nodep);
// Due to a need to get the arguments, the ParseRefs are under here,
@@ -141,6 +162,7 @@ private:
}
virtual void visit(AstDot* nodep, AstNUser*) {
UINFO(5," "<<nodep<<endl);
cleanFileline(nodep);
if (m_inModDot) { // Already under dot, so this is {modulepart} DOT {modulepart}
m_dotText = "";
nodep->lhsp()->iterateAndNext(*this);
@@ -165,6 +187,7 @@ private:
}
virtual void visit(AstSelBit* nodep, AstNUser*) {
if (!nodep->user1Inc()) { // Process only once.
cleanFileline(nodep);
if (m_inModDot) { // Already under dot, so this is {modulepart} DOT {modulepart}
m_dotText = "";
nodep->lhsp()->iterateAndNext(*this);
@@ -193,6 +216,7 @@ private:
virtual void visit(AstNodePreSel* nodep, AstNUser*) {
// Excludes simple AstSel, see above
if (!nodep->user1Inc()) { // Process only once.
cleanFileline(nodep);
if (m_inModDot) { // Already under dot, so this is {modulepart} DOT {modulepart}
nodep->v3error("Syntax Error: Range ':', '+:' etc are not allowed in the cell part of a dotted reference");
} else if (m_exp==AstParseRefExp::PX_FUNC) {
@@ -215,6 +239,7 @@ private:
}
virtual void visit(AstText* nodep, AstNUser*) {
if (!nodep->user1Inc()) { // Process only once.
cleanFileline(nodep);
if (m_exp != AstParseRefExp::PX_NONE) {
UINFO(7," "<<nodep<<endl);
if (m_inModDot) { // Dotted part, just pass up
@@ -228,6 +253,7 @@ private:
}
virtual void visit(AstEnumItem* nodep, AstNUser*) {
// Expand ranges
cleanFileline(nodep);
nodep->iterateChildren(*this);
if (nodep->rangep()) {
if (!nodep->rangep()->msbp()->castConst()
@@ -251,12 +277,14 @@ private:
virtual void visit(AstVar* nodep, AstNUser*) {
cleanFileline(nodep);
m_varp = nodep;
nodep->iterateChildren(*this);
m_varp = NULL;
}
virtual void visit(AstAttrOf* nodep, AstNUser*) {
cleanFileline(nodep);
nodep->iterateChildren(*this);
if (nodep->attrType() == AstAttrType::VAR_CLOCK) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
@@ -303,6 +331,7 @@ private:
virtual void visit(AstAlwaysPublic* nodep, AstNUser*) {
// AlwaysPublic was attached under a var, but it's a statement that should be
// at the same level as the var
cleanFileline(nodep);
nodep->iterateChildren(*this);
if (m_varp) {
nodep->unlinkFrBack();
@@ -315,6 +344,7 @@ private:
}
virtual void visit(AstDefImplicitDType* nodep, AstNUser*) {
cleanFileline(nodep);
UINFO(8," DEFIMPLICIT "<<nodep<<endl);
// Must remember what names we've already created, and combine duplicates
// so that for "var enum {...} a,b" a & b will share a common typedef
@@ -351,6 +381,7 @@ private:
virtual void visit(AstNode* nodep, AstNUser*) {
// Default: Just iterate
cleanFileline(nodep);
checkExpected(nodep); // So we detect node types we forgot to list here
nodep->iterateChildren(*this);
}
+49 -1
View File
@@ -555,6 +555,12 @@ bool V3Number::isNeqZero() const {
}
return false;
}
bool V3Number::isBitsZero(int msb, int lsb) const {
for (int i=lsb; i<=msb; i++) {
if (VL_UNLIKELY(!bitIs0(i))) return false;
}
return true;
}
bool V3Number::isEqOne() const {
if (m_value[0]!=1 || m_valueX[0]) return false;
for (int i=1; i<words(); i++) {
@@ -1005,6 +1011,30 @@ V3Number& V3Number::opLteS (const V3Number& lhs, const V3Number& rhs) {
return opGteS(rhs,lhs);
}
V3Number& V3Number::opRotR (const V3Number& lhs, const V3Number& rhs) {
// L(lhs) bit return
if (rhs.isFourState()) return setAllBitsX();
setZero();
uint32_t rhsval = rhs.toUInt();
for (int bit=0; bit<this->width(); bit++) {
setBit(bit,lhs.bitIs((bit + rhsval) % this->width()));
}
return *this;
}
V3Number& V3Number::opRotL (const V3Number& lhs, const V3Number& rhs) {
// L(lhs) bit return
if (rhs.isFourState()) return setAllBitsX();
setZero();
uint32_t rhsval = rhs.toUInt();
for (int bit=0; bit<this->width(); bit++) {
if (bit >= (int)rhsval) {
setBit(bit,lhs.bitIs((bit - rhsval) % this->width()));
}
}
return *this;
}
V3Number& V3Number::opShiftR (const V3Number& lhs, const V3Number& rhs) {
// L(lhs) bit return
if (rhs.isFourState()) return setAllBitsX();
@@ -1032,8 +1062,8 @@ V3Number& V3Number::opShiftRS (const V3Number& lhs, const V3Number& rhs) {
V3Number& V3Number::opShiftL (const V3Number& lhs, const V3Number& rhs) {
// L(lhs) bit return
if (rhs.isFourState()) return setAllBitsX();
uint32_t rhsval = rhs.toUInt();
setZero();
uint32_t rhsval = rhs.toUInt();
for (int bit=0; bit<this->width(); bit++) {
if (bit >= (int)rhsval) {
setBit(bit,lhs.bitIs(bit - rhsval));
@@ -1045,6 +1075,15 @@ V3Number& V3Number::opShiftL (const V3Number& lhs, const V3Number& rhs) {
//======================================================================
// Ops - Arithmetic
V3Number& V3Number::opAbsS (const V3Number& lhs) {
// op i, L(lhs) bit return
if (lhs.isFourState()) return setAllBitsX();
if (lhs.isNegative()) {
return opUnaryMin(lhs);
} else {
return opAssign(lhs);
}
}
V3Number& V3Number::opUnaryMin (const V3Number& lhs) {
// op i, L(lhs) bit return
if (lhs.isFourState()) return setAllBitsX();
@@ -1318,6 +1357,15 @@ V3Number& V3Number::opPowS (const V3Number& lhs, const V3Number& rhs) {
return setAllBitsX();
}
V3Number& V3Number::opBufIf1 (const V3Number& ens, const V3Number& if1s) {
setZero();
for(int bit=0; bit<this->width(); bit++) {
if (ens.bitIs1(bit)) { setBit(bit, if1s.bitIs(bit)); }
else setBit(bit,'z');
}
return *this;
}
V3Number& V3Number::opAssign (const V3Number& lhs) {
// Note may be a width change during the assign
setZero();
+5
View File
@@ -138,6 +138,7 @@ public:
bool isAllZ() const { for(int i=0;i<width();i++) { if(!bitIsZ(i)){return false;} } return true; }
bool isEqZero() const;
bool isNeqZero() const;
bool isBitsZero(int msb, int lsb) const;
bool isEqOne() const;
bool isEqAllOnes(int optwidth=0) const;
bool isCaseEq(const V3Number& rhsp) const; // operator==
@@ -195,11 +196,13 @@ public:
V3Number& opCaseNeq (const V3Number& lhs, const V3Number& rhs);
V3Number& opWildEq (const V3Number& lhs, const V3Number& rhs);
V3Number& opWildNeq (const V3Number& lhs, const V3Number& rhs);
V3Number& opBufIf1 (const V3Number& lhs, const V3Number& rhs);
// "standard" math
V3Number& opNot (const V3Number& lhs);
V3Number& opLogNot (const V3Number& lhs);
V3Number& opLogAnd (const V3Number& lhs, const V3Number& rhs);
V3Number& opLogOr (const V3Number& lhs, const V3Number& rhs);
V3Number& opAbsS (const V3Number& lhs);
V3Number& opUnaryMin(const V3Number& lhs);
V3Number& opAdd (const V3Number& lhs, const V3Number& rhs);
V3Number& opSub (const V3Number& lhs, const V3Number& rhs);
@@ -216,6 +219,8 @@ public:
V3Number& opXor (const V3Number& lhs, const V3Number& rhs);
V3Number& opXnor (const V3Number& lhs, const V3Number& rhs);
V3Number& opOr (const V3Number& lhs, const V3Number& rhs);
V3Number& opRotR (const V3Number& lhs, const V3Number& rhs);
V3Number& opRotL (const V3Number& lhs, const V3Number& rhs);
V3Number& opShiftR (const V3Number& lhs, const V3Number& rhs);
V3Number& opShiftRS (const V3Number& lhs, const V3Number& rhs); // Arithmetic w/carry
V3Number& opShiftL (const V3Number& lhs, const V3Number& rhs);
+35 -4
View File
@@ -194,18 +194,33 @@ string V3Options::filenameNonExt (const string& filename) {
string V3Options::filenameSubstitute (const string& filename) {
string out;
enum { NONE, PAREN, CURLY } brackets = NONE;
for (string::size_type pos = 0; pos < filename.length(); ++pos) {
if (filename[pos] == '$') {
if ((filename[pos] == '$') && (pos+1 < filename.length())) {
switch (filename[pos+1]) {
case '{': brackets = CURLY; break;
case '(': brackets = PAREN; break;
default: brackets = NONE; break;
}
if (brackets != NONE) pos = pos+1;
string::size_type endpos = pos+1;
while ((endpos+1) < filename.length()
&& (isalnum(filename[endpos+1]) || filename[endpos+1]=='_'))
while (((endpos+1) < filename.length()) &&
(((brackets==NONE) && (isalnum(filename[endpos+1]) || filename[endpos+1]=='_')) ||
((brackets==CURLY) && (filename[endpos+1]!='}')) ||
((brackets==PAREN) && (filename[endpos+1]!=')'))))
++endpos;
// Catch bracket errors
if (((brackets==CURLY) && (filename[endpos+1]!='}')) ||
((brackets==PAREN) && (filename[endpos+1]!=')'))) {
v3fatal("Unmatched brackets in variable substitution in file: "+filename);
}
string envvar = filename.substr(pos+1,endpos-pos);
const char* envvalue = NULL;
if (envvar != "") envvalue = getenv(envvar.c_str());
if (envvalue) {
out += envvalue;
pos = endpos;
if (brackets==NONE) pos = endpos;
else pos = endpos+1;
} else {
out += filename[pos]; // *pos == '$'
}
@@ -214,6 +229,7 @@ string V3Options::filenameSubstitute (const string& filename) {
}
}
return out;
}
bool V3Options::filenameIsRel(const string& filename) {
@@ -756,6 +772,14 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
shift;
m_traceDepth = atoi(argv[i]);
}
else if ( !strcmp (sw, "-trace-max-array") && (i+1)<argc ) {
shift;
m_traceMaxArray = atoi(argv[i]);
}
else if ( !strcmp (sw, "-trace-max-width") && (i+1)<argc ) {
shift;
m_traceMaxWidth = atoi(argv[i]);
}
else if ( !strncmp (sw, "-U", 2)) {
V3PreShell::undef (string (sw+strlen("-U")));
}
@@ -807,6 +831,9 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if (!strcmp (sw, "-Wno-style")) {
FileLine::globalWarnStyleOff(true);
}
else if (!strcmp (sw, "-Wno-fatal")) {
m_warnFatal = false;
}
else {
string msg = sw+strlen("-Wno-");
if (!(FileLine::globalWarnOff(msg, true))) {
@@ -1056,6 +1083,7 @@ V3Options::V3Options() {
m_makeDepend = true;
m_makePhony = false;
m_outFormatOk = false;
m_warnFatal = true;
m_pinsBv = 65;
m_profileCFuncs = false;
m_preprocOnly = false;
@@ -1077,6 +1105,8 @@ V3Options::V3Options() {
m_outputSplitCFuncs = 0;
m_outputSplitCTrace = 0;
m_traceDepth = 0;
m_traceMaxArray = 32;
m_traceMaxWidth = 256;
m_unrollCount = 64;
m_unrollStmts = 30000;
@@ -1095,6 +1125,7 @@ V3Options::V3Options() {
// Default +libext+
addLibExt(""); // So include "filename.v" will find the same file
addLibExt(".v");
addLibExt(".sv");
// Default -I
addIncDir("."); // Looks better than {long_cwd_path}/...
}
+6
View File
@@ -113,6 +113,7 @@ class V3Options {
bool m_l2Name; // main switch: --l2name
bool m_lintOnly; // main switch: --lint-only
bool m_outFormatOk; // main switch: --cc, --sc or --sp was specified
bool m_warnFatal; // main switch: --warnFatal
bool m_pinsUint8; // main switch: --pins-uint8
bool m_profileCFuncs;// main switch: --profile-cfuncs
bool m_psl; // main switch: --psl
@@ -134,6 +135,8 @@ class V3Options {
int m_outputSplitCTrace;// main switch: --output-split-ctrace
int m_pinsBv; // main switch: --pins-bv
int m_traceDepth; // main switch: --trace-depth
int m_traceMaxArray;// main switch: --trace-max-array
int m_traceMaxWidth;// main switch: --trace-max-width
int m_unrollCount; // main switch: --unroll-count
int m_unrollStmts; // main switch: --unroll-stmts
@@ -238,6 +241,7 @@ class V3Options {
bool traceUnderscore() const { return m_traceUnderscore; }
bool outFormatOk() const { return m_outFormatOk; }
bool keepTempFiles() const { return (V3Error::debugDefault()!=0); }
bool warnFatal() const { return m_warnFatal; }
bool pinsUint8() const { return m_pinsUint8; }
bool profileCFuncs() const { return m_profileCFuncs; }
bool psl() const { return m_psl; }
@@ -255,6 +259,8 @@ class V3Options {
int outputSplitCTrace() const { return m_outputSplitCTrace; }
int pinsBv() const { return m_pinsBv; }
int traceDepth() const { return m_traceDepth; }
int traceMaxArray() const { return m_traceMaxArray; }
int traceMaxWidth() const { return m_traceMaxWidth; }
int unrollCount() const { return m_unrollCount; }
int unrollStmts() const { return m_unrollStmts; }
+1 -2
View File
@@ -131,8 +131,7 @@ private:
// Make sure all parameters are constantified
virtual void visit(AstVar* nodep, AstNUser*) {
if (!nodep->user5()) {
nodep->user5(1); // Mark done
if (!nodep->user5Inc()) { // Process once
nodep->iterateChildren(*this);
if (nodep->isParam()) {
if (!nodep->hasSimpleInit()) { nodep->v3fatalSrc("Parameter without initial value"); }
+6 -1
View File
@@ -848,8 +848,13 @@ int V3PreProcImp::getStateToken() {
if (m_lexp->m_keepComments == KEEPCMT_SUB) {
string rtn; rtn.assign(yyourtext(),yyourleng());
comment(rtn);
} else {
// Need to insure "foo/**/bar" becomes two tokens
insertUnreadback (" ");
} else if (m_lexp->m_keepComments) {
return (tok);
} else {
// Need to insure "foo/**/bar" becomes two tokens
insertUnreadback (" ");
}
}
// We're off or processed the comment specially. If there are newlines
+9
View File
@@ -98,6 +98,7 @@ private:
virtual void visit(AstLogOr* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
virtual void visit(AstLogIf* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
virtual void visit(AstLogIff* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
virtual void visit(AstBufIf1* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
// ... These shouldn't matter, just make unsigned
virtual void visit(AstScopeName* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
virtual void visit(AstText* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
@@ -148,6 +149,9 @@ private:
// Inherit from others
virtual void visit(AstVar* nodep, AstNUser*) {
// Avoid recursion; can't use user() as they're all full, and anyhow this is often called
if (nodep->didSigning()) return;
nodep->didSigning(true);
nodep->iterateChildren(*this);
nodep->signedFrom(nodep->dtypep());
}
@@ -159,6 +163,11 @@ private:
nodep->itemp()->iterate(*this);
nodep->signedFrom(nodep->itemp());
}
virtual void visit(AstCast* nodep, AstNUser*) {
nodep->lhsp()->iterate(*this);
nodep->dtypep()->iterate(*this);
nodep->signedFrom(nodep->dtypep());
}
virtual void visit(AstConst* nodep, AstNUser*) {
// The node got setup with the signed state of the node.
// However a later operation may have changed the node->signed w/o changing
+1 -1
View File
@@ -304,7 +304,7 @@ private:
if (debug()>5) nodep->dumpTree(cout," substw_old: ");
AstNode* newp = substp->cloneTree(true);
if (!nodep->isQuad() && newp->isQuad()) {
newp = new AstCast (newp->fileline(), newp, nodep);
newp = new AstCCast (newp->fileline(), newp, nodep);
}
if (debug()>5) newp->dumpTree(cout," w_new: ");
nodep->replaceWith(newp);
+37 -45
View File
@@ -380,7 +380,10 @@ private:
UINFO(9, " pin "<<pinp<<endl);
pinp->unlinkFrBack(); // Relinked to assignment below
//
if (portp->isInout()) {
if ((portp->isInout()||portp->isOutput()) && pinp->castConst()) {
pinp->v3error("Function/task output connected to constant instead of variable: "+portp->prettyName());
}
else if (portp->isInout()) {
if (AstVarRef* varrefp = pinp->castVarRef()) {
// Connect to this exact variable
AstVarScope* localVscp = varrefp->varScopep(); if (!localVscp) varrefp->v3fatalSrc("Null var scope");
@@ -390,9 +393,6 @@ private:
pinp->v3warn(E_TASKNSVAR,"Unsupported: Function/task input argument is not simple variable");
}
}
else if (portp->isOutput() && outvscp) {
refp->v3error("Outputs not allowed in function declarations");
}
else if (portp->isOutput()) {
// Make output variables
// Correct lvalue; we didn't know when we linked
@@ -456,7 +456,7 @@ private:
tempp->stmtsp()->unlinkFrBackWithNext(); tempp->deleteTree(); tempp=NULL;
}
//
if (debug()>=9) { beginp->dumpTree(cout,"-iotask: "); }
if (debug()>=9) { beginp->dumpTreeAndNext(cout,"-iotask: "); }
return beginp;
}
@@ -481,7 +481,10 @@ private:
} else {
UINFO(9, " Port "<<portp<<endl);
UINFO(9, " pin "<<pinp<<endl);
if (portp->isInout()) {
if ((portp->isInout()||portp->isOutput()) && pinp->castConst()) {
pinp->v3error("Function/task output connected to constant instead of variable: "+portp->prettyName());
}
else if (portp->isInout()) {
if (pinp->castVarRef()) {
// Connect to this exact variable
} else {
@@ -536,7 +539,7 @@ private:
ccallp->addArgsp(new AstVarRef(refp->fileline(), outvscp, true));
}
if (debug()>=9) { beginp->dumpTree(cout,"-nitask: "); }
if (debug()>=9) { beginp->dumpTreeAndNext(cout,"-nitask: "); }
return beginp;
}
@@ -1011,40 +1014,22 @@ private:
nodep->iterateChildren(*this);
m_scopep = NULL;
}
virtual void visit(AstTaskRef* nodep, AstNUser*) {
iterateIntoFTask(nodep->taskp()); // First, do hierarchical funcs
UINFO(4," Task REF "<<nodep<<endl);
if (debug()>=9) { nodep->dumpTree(cout,"-inltask:"); }
// Create cloned statements
string namePrefix = "__Vtask_"+nodep->taskp()->shortName()+"__"+cvtToStr(m_modNCalls++);
AstNode* beginp;
if (m_statep->ftaskNoInline(nodep->taskp())) {
beginp = createNonInlinedFTask(nodep, namePrefix, NULL);
} else {
beginp = createInlinedFTask(nodep, namePrefix, NULL);
}
// Replace the ref
nodep->replaceWith(beginp);
nodep->deleteTree(); nodep=NULL;
}
virtual void visit(AstFuncRef* nodep, AstNUser*) {
UINFO(4," Func REF "<<nodep<<endl);
if (debug()>=9) { nodep->dumpTree(cout,"-preref:"); }
// First, do hierarchical funcs
AstNodeFTask* funcp = nodep->taskp();
if (!funcp) nodep->v3fatalSrc("unlinked");
if (!funcp->isFunction()) nodep->v3fatalSrc("func reference to non-function");
if (!m_scopep) nodep->v3fatalSrc("func ref not under scope");
// Inline func refs in the function
iterateIntoFTask(funcp);
// Create output variable
string namePrefix = "__Vfunc_"+nodep->taskp()->shortName()+"__"+cvtToStr(m_modNCalls++);
AstVarScope* outvscp = createVarScope (funcp->fvarp()->castVar(),
namePrefix+"__Vfuncout");
// Create cloned statements
if (debug()>=9) { nodep->taskp()->dumpTree(cout,"-oldfunc:"); }
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked?");
iterateIntoFTask(nodep->taskp()); // First, do hierarchical funcs
UINFO(4," FTask REF "<<nodep<<endl);
if (debug()>=9) { nodep->dumpTree(cout,"-inlfunc:"); }
if (!m_scopep) nodep->v3fatalSrc("func ref not under scope");
string namePrefix = ((nodep->castFuncRef()?"__Vfunc_":"__Vtask_")
+nodep->taskp()->shortName()+"__"+cvtToStr(m_modNCalls++));
// Create output variable
AstVarScope* outvscp = NULL;
if (nodep->taskp()->isFunction()) {
// Not that it's a FUNCREF, but that we're calling a function (perhaps as a task)
outvscp = createVarScope (nodep->taskp()->fvarp()->castVar(),
namePrefix+"__Vfuncout");
}
// Create cloned statements
AstNode* beginp;
if (m_statep->ftaskNoInline(nodep->taskp())) {
// This may share VarScope's with a public task, if any. Yuk.
@@ -1053,13 +1038,20 @@ private:
beginp = createInlinedFTask(nodep, namePrefix, outvscp);
}
// Replace the ref
AstVarRef* outrefp = new AstVarRef (nodep->fileline(), outvscp, false);
nodep->replaceWith(outrefp);
// Insert new statements
insertBeforeStmt(nodep, beginp);
if (nodep->castFuncRef()) {
if (!nodep->taskp()->isFunction()) nodep->v3fatalSrc("func reference to non-function");
AstVarRef* outrefp = new AstVarRef (nodep->fileline(), outvscp, false);
nodep->replaceWith(outrefp);
// Insert new statements
insertBeforeStmt(nodep, beginp);
} else {
// outvscp maybe non-NULL if calling a function in a taskref,
// but if so we want to simply ignore the function result
nodep->replaceWith(beginp);
}
// Cleanup
nodep->deleteTree(); nodep=NULL;
UINFO(4," Func REF Done.\n");
UINFO(4," FTask REF Done.\n");
}
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
UINFO(4," Inline "<<nodep<<endl);
+2 -2
View File
@@ -75,8 +75,8 @@ private:
if (prettyName.find("._") != string::npos)
return "Inlined leading underscore";
}
if (nodep->width() > 256) return "Wide bus > 256 bits";
if (nodep->arrayElements() > 32) return "Wide memory > 32 ents";
if ((int)nodep->width() > v3Global.opt.traceMaxWidth()) return "Wide bus > --trace-max-width bits";
if ((int)nodep->arrayElements() > v3Global.opt.traceMaxArray()) return "Wide memory > --trace-max-array ents";
if (!(nodep->dtypeSkipRefp()->castBasicDType()
|| (nodep->dtypeSkipRefp()->castArrayDType()
&& nodep->dtypeSkipRefp()->castArrayDType()->dtypeSkipRefp()->castBasicDType()))) {
+38 -7
View File
@@ -159,8 +159,8 @@ private:
// assign x = (OE) ? 'hz : y;
// see if this a COND and separate out the __en logic from the output logic if it is
if (nodep->rhsp()->castCond()) {
AstCond* condp = nodep->rhsp()->castCond();
if (AstCond* condp = nodep->rhsp()->castCond()) {
//if (debug()>=9) nodep->dumpTree(cout,"- cond-in: ");
AstNode* oep = condp->condp();
AstNode* expr1p = condp->expr1p();
AstNode* expr2p = condp->expr2p();
@@ -192,17 +192,44 @@ private:
// replace the old assign logic with the new one
AstAssignW* newassp = new AstAssignW(nodep->fileline(), outp,outrhsp);
//if (debug()>=9) newassp->dumpTreeAndNext(cout,"- cond-out: ");
nodep->replaceWith(newassp);
nodep->deleteTree(); nodep=NULL;
newassp->iterateChildren(*this);
} else {
}
// How about a tri gate?
else if (AstBufIf1* bufp = nodep->rhsp()->castBufIf1()) {
//if (debug()>=9) nodep->dumpTree(cout,"- tri-in : ");
AstNode* enrhsp = bufp->lhsp()->unlinkFrBack();
AstNode* outrhsp = bufp->rhsp()->unlinkFrBack();
AstNode* outp = nodep->lhsp()->unlinkFrBack();;
AstVarRef* outrefp = NULL;
if (outp->castVarRef()) {
outrefp = outp->castVarRef();
} else if (outp->castSel()) {
outrefp = outp->castSel()->fromp()->castVarRef();
} else {
nodep->v3error("Can't find LHS varref");
}
createEnableVar(outp, outrefp, enrhsp, outrhsp->width());
// replace the old assign logic with the new one
AstAssignW* newassp = new AstAssignW(nodep->fileline(), outp,outrhsp);
//if (debug()>=9) newassp->dumpTreeAndNext(cout,"- tri-out: ");
nodep->replaceWith(newassp);
nodep->deleteTree(); nodep=NULL;
newassp->iterateChildren(*this);
}
else {
nodep->iterateChildren(*this);
}
}
AstVar* createEnableVar(AstNode* outp, AstVarRef* outrefp, AstNode* enrhsp, int width, string suffix="") {
// this function creates an __en Var that cooresponds to
// this function creates an __en Var that corresponds to
// the outp and outrefp and creates an assignw to enrhsp
AstVar* enp = new AstVar (outrefp->varp()->fileline(),
AstVarType::MODULETEMP,
@@ -218,10 +245,14 @@ private:
enrhsp->v3error("Don't know how to deal with selection logic wider than 1 bit");
}
}
AstNode* newassp = new AstAssignW (enp->fileline(),
new AstVarRef (enp->fileline(), enp, true),
enrhsp);
if (debug()>=9) enp->dumpTreeAndNext(cout,"- cev-out: ");
if (debug()>=9) newassp->dumpTreeAndNext(cout,"- cev-out: ");
m_modp->addStmtp(enp);
m_modp->addStmtp(new AstAssignW (enp->fileline(),
new AstVarRef (enp->fileline(), enp, true),
enrhsp));
m_modp->addStmtp(newassp);
outrefp->user1p(enp); // put __en signal into varref for later usage
outrefp->varp()->user1p(enp); // put __en signal into var as well in the event this is a single lhs driver and this needs passed up one level
+9
View File
@@ -170,27 +170,36 @@ public:
// thus undriven+unused bits get UNUSED warnings, as they're not as buggy.
if (!unusedMatch(nodep)) {
nodep->v3warn(UNUSED, "Signal is not driven, nor used: "<<nodep->prettyName());
nodep->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true); // Warn only once
}
} else if (allD && !anyU) {
if (!unusedMatch(nodep)) {
nodep->v3warn(UNUSED, "Signal is not used: "<<nodep->prettyName());
nodep->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true); // Warn only once
}
} else if (!anyD && allU) {
nodep->v3warn(UNDRIVEN, "Signal is not driven: "<<nodep->prettyName());
nodep->fileline()->modifyWarnOff(V3ErrorCode::UNDRIVEN, true); // Warn only once
} else {
// Bits have different dispositions
bool setU=false; bool setD=false;
if (anynotDU && !unusedMatch(nodep)) {
nodep->v3warn(UNUSED, "Bits of signal are not driven, nor used: "<<nodep->prettyName()
<<bitNames(BN_BOTH));
setU=true;
}
if (anyDnotU && !unusedMatch(nodep)) {
nodep->v3warn(UNUSED, "Bits of signal are not used: "<<nodep->prettyName()
<<bitNames(BN_UNUSED));
setU=true;
}
if (anyUnotD) {
nodep->v3warn(UNDRIVEN, "Bits of signal are not driven: "<<nodep->prettyName()
<<bitNames(BN_UNDRIVEN));
setD=true;
}
if (setU) nodep->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true); // Warn only once
if (setD) nodep->fileline()->modifyWarnOff(V3ErrorCode::UNDRIVEN, true); // Warn only once
}
}
}
+2 -1
View File
@@ -187,8 +187,9 @@ private:
UINFO(8," In Numbers: for (v="<<valInit<<"; v<"<<valStop<<"; v=v+"<<valInc<<")\n");
//
if (!m_generate) {
UINFO(8, " ~Iters: "<<((valStop - valInit)/valInc)<<" c="<<unrollCount()<<endl);
int loops = ((valStop - valInit)/valInc);
if (loops < 0) { loops += (1ULL<<constStopp->width()); } // Will roll around
UINFO(8, " ~Iters: "<<loops<<" c="<<unrollCount()<<endl);
if (loops > unrollCount())
return cantUnroll(nodep, "too many iterations");
+41 -1
View File
@@ -143,6 +143,7 @@ private:
virtual void visit(AstOr* nodep, AstNUser* vup) { width_Omax_L_Rlhs(nodep,vup); }
virtual void visit(AstXnor* nodep, AstNUser* vup) { width_Omax_L_Rlhs(nodep,vup); }
virtual void visit(AstXor* nodep, AstNUser* vup) { width_Omax_L_Rlhs(nodep,vup); }
virtual void visit(AstBufIf1* nodep, AstNUser* vup) { width_Omax_L_Rlhs(nodep,vup); }
// Multiple possible reasonable division width conversions. Just keep our code simple, they aren't common.
virtual void visit(AstModDiv* nodep, AstNUser* vup) { width_Omax_L_Rlhs(nodep,vup); }
virtual void visit(AstModDivS* nodep, AstNUser* vup) { width_Omax_L_Rlhs(nodep,vup); }
@@ -523,11 +524,41 @@ private:
nodep->iterateChildren(*this, vup);
nodep->widthFrom(nodep->dtypep()->skipRefp());
}
virtual void visit(AstCast* nodep, AstNUser* vup) {
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
nodep->dtypep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
// When more general casts are supported, the cast elimination will be done later.
// For now, replace it ASAP, so widthing can propagate easily
// The cast may change signing, but we don't know the sign yet. Make it so.
// Note we don't sign lhsp() that would make the algorithm O(n^2) if lots of casting.
V3Width::widthParamsEdit(nodep->dtypep()); // MAY CHANGE dtypep()
AstBasicDType* basicp = nodep->dtypep()->basicp(); if (!basicp) nodep->v3fatalSrc("Unimplemented: Casting non-simple data type");
nodep->widthSignedFrom(basicp);
widthCheck(nodep,"Cast",nodep->lhsp(),nodep->width(),nodep->width(),true);
AstNode* newp = nodep->lhsp()->unlinkFrBack();
if (basicp->isSigned()) {
newp = new AstSigned(nodep->fileline(), newp);
} else {
newp = new AstUnsigned(nodep->fileline(), newp);
}
nodep->replaceWith(newp);
}
virtual void visit(AstVar* nodep, AstNUser* vup) {
//if (debug()) nodep->dumpTree(cout," InitPre: ");
// Must have deterministic constant width
// We can't skip this step when width()!=0, as creating a AstVar
// with non-constant range gets size 1, not size 0.
// with non-constant range gets size 1, not size 0. So use didWidth().
if (nodep->didWidth()) { // Early exit if have circular parameter definition
if (!nodep->width()) {
if (!nodep->valuep()) nodep->v3fatalSrc("circular, but without value");
nodep->v3error("Variable's initial value is circular: "<<nodep->prettyName());
pushDeletep(nodep->valuep()->unlinkFrBack());
nodep->valuep(new AstConst(nodep->fileline(), 1));
} else {
return;
}
}
nodep->didWidth(true);
int width=1; int mwidth=1;
// Parameters if implicit untyped inherit from what they are assigned to
AstBasicDType* bdtypep = nodep->dtypep()->castBasicDType();
@@ -1007,6 +1038,15 @@ private:
} else {
// Do PRELIM again, because above accept may have exited early due to node replacement
pinp->accept(*this,WidthVP(portp->width(),portp->widthMin(),BOTH).p());
if ((portp->isOutput() || portp->isInout())
&& pinp->width() != portp->width()) {
pinp->v3error("Unsupported: Function output argument '"<<portp->prettyName()<<"'"
<<" requires "<<pinp->width()
<<" bits, but connection's "<<pinp->prettyTypeName()
<<" generates "<<portp->width()<<" bits.");
// otherwise would need some mess to force both sides to proper size
// (get an ASSIGN with EXTEND on the lhs instead of rhs)
}
if (portp->basicp() && !portp->basicp()->isOpaque()) {
widthCheck(nodep,"Function Argument",pinp,portp->width(),portp->widthMin());
}
+2
View File
@@ -630,6 +630,8 @@ int main(int argc, char** argv, char** env) {
V3File::writeTimes(v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__verFiles.dat", argString);
}
// Final writing shouldn't throw warnings, but...
V3Error::abortIfWarnings();
#ifdef VL_LEAK_CHECKS
// Cleanup memory for valgrind leak analysis
v3Global.clear();
+1 -1
View File
@@ -25,7 +25,7 @@
//**********************************************************************
//**** Version and host name
#define DTVERSION "Verilator 3.810 2010/07/10"
#define DTVERSION "Verilator 3.812 2011/04/06"
//**********************************************************************
//**** Functions
+96 -54
View File
@@ -151,7 +151,7 @@ const AstBasicDTypeKwd LOGIC_IMPLICIT = AstBasicDTypeKwd::LOGIC_IMPLICIT;
//======================================================================
// Macro functions
#define CRELINE() (PARSEP->copyOrSameFileLine())
#define CRELINE() (PARSEP->copyOrSameFileLine()) // Only use in empty rules, so lines point at beginnings
#define VARRESET_LIST(decl) { GRAMMARP->m_pinNum=1; VARRESET(); VARDECL(decl); } // Start of pinlist
#define VARRESET_NONLIST(decl) { GRAMMARP->m_pinNum=0; VARRESET(); VARDECL(decl); } // Not in a pinlist
@@ -160,7 +160,7 @@ const AstBasicDTypeKwd LOGIC_IMPLICIT = AstBasicDTypeKwd::LOGIC_IMPLICIT;
#define VARIO(type) { GRAMMARP->m_varIO = AstVarType::type; }
#define VARDTYPE(dtypep) { GRAMMARP->setDType(dtypep); }
#define VARDONEA(name,array,attrs) GRAMMARP->createVariable(CRELINE(),(name),(array),(attrs))
#define VARDONEA(fl,name,array,attrs) GRAMMARP->createVariable((fl),(name),(array),(attrs))
#define VARDONEP(portp,array,attrs) GRAMMARP->createVariable((portp)->fileline(),(portp)->name(),(array),(attrs))
#define PINNUMINC() (GRAMMARP->m_pinNum++)
@@ -777,10 +777,10 @@ port<nodep>: // ==IEEE: port
// // IEEE: interface_port_header port_identifier { unpacked_dimension }
// // Expanded interface_port_header
// // We use instantCb here because the non-port form looks just like a module instantiation
//UNSUP portDirNetE id/*interface*/ idAny/*port*/ rangeListE sigAttrListE { VARDTYPE($2); VARDONEA($3, $4); PARSEP->instantCb(CRELINE(), $2, $3, $4); PINNUMINC(); }
//UNSUP portDirNetE yINTERFACE idAny/*port*/ rangeListE sigAttrListE { VARDTYPE($2); VARDONEA($3, $4); PINNUMINC(); }
//UNSUP portDirNetE id/*interface*/ '.' idAny/*modport*/ idAny/*port*/ rangeListE sigAttrListE { VARDTYPE($2); VARDONEA($5, $6); PARSEP->instantCb(CRELINE(), $2, $5, $6); PINNUMINC(); }
//UNSUP portDirNetE yINTERFACE '.' idAny/*modport*/ idAny/*port*/ rangeListE sigAttrListE { VARDTYPE($2); VARDONEA($5, $6); PINNUMINC(); }
//UNSUP portDirNetE id/*interface*/ idAny/*port*/ rangeListE sigAttrListE { VARDTYPE($2); VARDONEA($<fl>3, $3, $4); PARSEP->instantCb($<fl>2, $2, $3, $4); PINNUMINC(); }
//UNSUP portDirNetE yINTERFACE idAny/*port*/ rangeListE sigAttrListE { VARDTYPE($2); VARDONEA($<fl>3, $3, $4); PINNUMINC(); }
//UNSUP portDirNetE id/*interface*/ '.' idAny/*modport*/ idAny/*port*/ rangeListE sigAttrListE { VARDTYPE($2); VARDONEA($<fl>5, $5, $6); PARSEP->instantCb($<fl>2, $2, $5, $6); PINNUMINC(); }
//UNSUP portDirNetE yINTERFACE '.' idAny/*modport*/ idAny/*port*/ rangeListE sigAttrListE { VARDTYPE($2); VARDONEA($<fl>5, $5, $6); PINNUMINC(); }
//
// // IEEE: ansi_port_declaration, with [port_direction] removed
// // IEEE: [ net_port_header | interface_port_header ] port_identifier { unpacked_dimension }
@@ -849,8 +849,8 @@ port_declNetE: // IEEE: part of port_declaration, optional net type
;
portSig<nodep>:
id/*port*/ { $$ = new AstPort(CRELINE(),PINNUMINC(),*$1); }
| idSVKwd { $$ = new AstPort(CRELINE(),PINNUMINC(),*$1); }
id/*port*/ { $$ = new AstPort($<fl>1,PINNUMINC(),*$1); }
| idSVKwd { $$ = new AstPort($<fl>1,PINNUMINC(),*$1); }
;
//**********************************************************************
@@ -926,7 +926,7 @@ list_of_genvar_identifiers<nodep>: // IEEE: list_of_genvar_identifiers (for decl
genvar_identifierDecl<nodep>: // IEEE: genvar_identifier (for declaration)
id/*new-genvar_identifier*/ sigAttrListE
{ VARRESET_NONLIST(GENVAR); VARDTYPE(new AstBasicDType($<fl>1,AstBasicDTypeKwd::INTEGER));
$$ = VARDONEA(*$1, NULL, $2); }
$$ = VARDONEA($<fl>1, *$1, NULL, $2); }
;
local_parameter_declaration<nodep>: // IEEE: local_parameter_declaration
@@ -1078,6 +1078,31 @@ signing<signstate>: // ==IEEE: signing
//************************************************
// Data Types
casting_type<dtypep>: // IEEE: casting_type
simple_type { $$ = $1; }
// // IEEE: constant_primary
// // In expr:cast this is expanded to just "expr"
//
// // IEEE: signing
//See where casting_type used
//^^ ySIGNED { $$ = new AstSigned($1,$3); }
//^^ yUNSIGNED { $$ = new AstUnsigned($1,$3); }
//UNSUP ySTRING { $$ = $1; }
//UNSUP yCONST__ETC/*then `*/ { $$ = $1; }
;
simple_type<dtypep>: // ==IEEE: simple_type
// // IEEE: integer_type
integer_atom_type { $$ = $1; }
| integer_vector_type { $$ = $1; }
//UNSUP non_integer_type { $$ = $1; }
// // IEEE: ps_type_identifier
// // IEEE: ps_parameter_identifier (presumably a PARAMETER TYPE)
| ps_type { $$ = $1; }
// // { generate_block_identifer ... } '.'
// // Need to determine if generate_block_identifier can be lex-detected
;
data_type<dtypep>: // ==IEEE: data_type
// // This expansion also replicated elsewhere, IE data_type__AndID
data_typeNoRef { $$ = $1; }
@@ -1121,9 +1146,9 @@ list_of_variable_decl_assignments<nodep>: // ==IEEE: list_of_variable_decl_assig
variable_decl_assignment<varp>: // ==IEEE: variable_decl_assignment
id variable_dimensionListE sigAttrListE
{ $$ = VARDONEA(*$1,$2,$3); }
{ $$ = VARDONEA($<fl>1,*$1,$2,$3); }
| id variable_dimensionListE sigAttrListE '=' variable_declExpr
{ $$ = VARDONEA(*$1,$2,$3); $$->valuep($5); }
{ $$ = VARDONEA($<fl>1,*$1,$2,$3); $$->valuep($5); }
| idSVKwd { $$ = NULL; }
//
// // IEEE: "dynamic_array_variable_identifier '[' ']' [ '=' dynamic_array_new ]"
@@ -1144,9 +1169,9 @@ list_of_tf_variable_identifiers<nodep>: // ==IEEE: list_of_tf_variable_identifie
tf_variable_identifier<varp>: // IEEE: part of list_of_tf_variable_identifiers
id variable_dimensionListE sigAttrListE
{ $$ = VARDONEA(*$1, $2, $3); }
{ $$ = VARDONEA($<fl>1,*$1, $2, $3); }
| id variable_dimensionListE sigAttrListE '=' expr
{ $$ = VARDONEA(*$1, $2, $3);
{ $$ = VARDONEA($<fl>1,*$1, $2, $3);
$$->addNext(new AstAssign($4, new AstVarRef($4, *$1, true), $5)); }
;
@@ -1384,7 +1409,7 @@ module_or_generate_item_declaration<nodep>: // ==IEEE: module_or_generate_item_d
generate_block_or_null<nodep>: // IEEE: generate_block_or_null
// ';' // is included in
// // IEEE: generate_block
genItem { $$ = new AstBegin(CRELINE(),"genblk",$1); }
genItem { $$ = $1 ? (new AstBegin($1->fileline(),"genblk",$1)) : NULL; }
| genItemBegin { $$ = $1; }
;
@@ -1515,18 +1540,18 @@ netSigList<varp>: // IEEE: list_of_port_identifiers
;
netSig<varp>: // IEEE: net_decl_assignment - one element from list_of_port_identifiers
netId sigAttrListE { $$ = VARDONEA(*$1, NULL, $2); }
| netId sigAttrListE '=' expr { $$ = VARDONEA(*$1, NULL, $2); $$->addNext(new AstAssignW($3,new AstVarRef($3,$$->name(),true),$4)); }
| netId rangeList sigAttrListE { $$ = VARDONEA(*$1, $2, $3); }
netId sigAttrListE { $$ = VARDONEA($<fl>1,*$1, NULL, $2); }
| netId sigAttrListE '=' expr { $$ = VARDONEA($<fl>1,*$1, NULL, $2); $$->addNext(new AstAssignW($3,new AstVarRef($3,$$->name(),true),$4)); }
| netId rangeList sigAttrListE { $$ = VARDONEA($<fl>1,*$1, $2, $3); }
;
netId<strp>:
id/*new-net*/ { $$ = $1; }
| idSVKwd { $$ = $1; }
id/*new-net*/ { $$ = $1; $<fl>$=$<fl>1; }
| idSVKwd { $$ = $1; $<fl>$=$<fl>1; }
;
sigId<varp>:
id { $$ = VARDONEA(*$1, NULL, NULL); }
id { $$ = VARDONEA($<fl>1,*$1, NULL, NULL); }
;
sigAttrListE<nodep>:
@@ -1564,7 +1589,7 @@ rangeList<rangep>: // IEEE: {packed_dimension}
wirerangeE<dtypep>:
/* empty */ { $$ = new AstBasicDType(CRELINE(), LOGIC); } // not implicit
| rangeList { $$ = GRAMMARP->addRange(new AstBasicDType(CRELINE(), LOGIC),$1,false); } // not implicit
| rangeList { $$ = GRAMMARP->addRange(new AstBasicDType($1->fileline(), LOGIC),$1,false); } // not implicit
;
// IEEE: select
@@ -1646,8 +1671,8 @@ instnameList<nodep>:
;
instnameParen<nodep>:
id instRangeE '(' cellpinList ')' { $$ = new AstCell($3, *$1,GRAMMARP->m_instModule,$4, GRAMMARP->m_instParamp,$2); }
| id instRangeE { $$ = new AstCell(CRELINE(),*$1,GRAMMARP->m_instModule,NULL,GRAMMARP->m_instParamp,$2); }
id instRangeE '(' cellpinList ')' { $$ = new AstCell($<fl>1,*$1,GRAMMARP->m_instModule,$4, GRAMMARP->m_instParamp,$2); }
| id instRangeE { $$ = new AstCell($<fl>1,*$1,GRAMMARP->m_instModule,NULL,GRAMMARP->m_instParamp,$2); }
//UNSUP instRangeE '(' cellpinList ')' { UNSUP } // UDP
;
@@ -1667,11 +1692,12 @@ cellpinItList<pinp>: // IEEE: list_of_port_connections + list_of_parameter_assi
;
cellpinItemE<pinp>: // IEEE: named_port_connection + named_parameter_assignment + empty
/* empty: ',,' is legal */ { $$ = NULL; PINNUMINC(); }
// Note empty can match either () or (,); V3LinkCells cleans up ()
/* empty: ',,' is legal */ { $$ = new AstPin(CRELINE(),PINNUMINC(),"",NULL); }
| yP_DOTSTAR { $$ = new AstPin($1,PINNUMINC(),".*",NULL); }
| '.' idSVKwd { $$ = NULL; PINNUMINC(); }
| '.' idSVKwd { $$ = new AstPin($1,PINNUMINC(),*$2,new AstVarRef($1,*$2,false)); $$->svImplicit(true);}
| '.' idAny { $$ = new AstPin($1,PINNUMINC(),*$2,new AstVarRef($1,*$2,false)); $$->svImplicit(true);}
| '.' idAny '(' ')' { $$ = NULL; PINNUMINC(); }
| '.' idAny '(' ')' { $$ = new AstPin($1,PINNUMINC(),*$2,NULL); }
// // mintypmax is expanded here, as it might be a UDP or gate primitive
| '.' idAny '(' expr ')' { $$ = new AstPin($1,PINNUMINC(),*$2,$4); }
//UNSUP '.' idAny '(' expr ':' expr ')' { }
@@ -1733,7 +1759,7 @@ senitem<senitemp>: // IEEE: part of event_expression, non-'OR' ',' terms
;
senitemVar<senitemp>:
idClassSel { $$ = new AstSenItem(CRELINE(),AstEdgeType::ET_ANYEDGE,$1); }
idClassSel { $$ = new AstSenItem($1->fileline(),AstEdgeType::ET_ANYEDGE,$1); }
;
senitemEdge<senitemp>: // IEEE: part of event_expression
@@ -2008,7 +2034,7 @@ for_initialization<nodep>: // ==IEEE: for_initialization + for_variable_declarat
// // IEEE: for_variable_declaration
varRESET data_type idAny/*new*/ '=' expr ';'
{ VARDTYPE($2);
$$ = VARDONEA(*$3,NULL,NULL);
$$ = VARDONEA($<fl>3,*$3,NULL,NULL);
$$->addNext(new AstAssign($4,new AstVarRef($4,*$3,true),$5));}
| varRefBase '=' expr ';' { $$ = new AstAssign($2,$1,$3); }
//UNSUP: List of initializations
@@ -2032,10 +2058,10 @@ for_step<nodep>: // IEEE: for_step
// Functions/tasks
taskRef<ftaskrefp>: // IEEE: part of tf_call
idDotted { $$ = new AstTaskRef(CRELINE(),new AstParseRef($1->fileline(), AstParseRefExp::PX_TASK, $1),NULL);}
| idDotted '(' list_of_argumentsE ')' { $$ = new AstTaskRef(CRELINE(),new AstParseRef($1->fileline(), AstParseRefExp::PX_TASK, $1),$3);}
//UNSUP: package_scopeIdFollows idDotted { $$ = new AstTaskRef(CRELINE(),new AstParseRef($2->fileline(), AstParseRefExp::PX_TASK, $2),NULL);}
//UNSUP: package_scopeIdFollows idDotted '(' list_of_argumentsE ')' { $$ = new AstTaskRef(CRELINE(),new AstParseRef($2->fileline(), AstParseRefExp::PX_TASK, $2),$4);}
idDotted { $$ = new AstTaskRef($1->fileline(),new AstParseRef($1->fileline(), AstParseRefExp::PX_TASK, $1),NULL);}
| idDotted '(' list_of_argumentsE ')' { $$ = new AstTaskRef($1->fileline(),new AstParseRef($1->fileline(), AstParseRefExp::PX_TASK, $1),$3);}
//UNSUP: package_scopeIdFollows idDotted { $$ = new AstTaskRef($1->fileline(),new AstParseRef($2->fileline(), AstParseRefExp::PX_TASK, $2),NULL);}
//UNSUP: package_scopeIdFollows idDotted '(' list_of_argumentsE ')' { $$ = new AstTaskRef($1->fileline(),new AstParseRef($2->fileline(), AstParseRefExp::PX_TASK, $2),$4);}
//UNSUP: idDotted is really just id to allow dotted method calls
;
@@ -2114,6 +2140,7 @@ system_f_call<nodep>: // IEEE: system_tf_call (as func)
| yaD_DPI '(' exprList ')' { $$ = new AstFuncRef($2,*$1,$3); }
//
| yD_BITS '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::EXPR_BITS,$3); }
| yD_BITS '(' data_type ')' { $$ = new AstAttrOf($1,AstAttrType::EXPR_BITS,$3); }
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCFunc($1,$3)); }
| yD_CLOG2 '(' expr ')' { $$ = new AstCLog2($1,$3); }
| yD_COUNTONES '(' expr ')' { $$ = new AstCountOnes($1,$3); }
@@ -2281,9 +2308,9 @@ tf_port_itemDir: // IEEE: part of tf_port_item, direction
tf_port_itemAssignment<varp>: // IEEE: part of tf_port_item, which has assignment
id variable_dimensionListE sigAttrListE
{ $$ = VARDONEA(*$1, $2, $3); }
{ $$ = VARDONEA($<fl>1, *$1, $2, $3); }
| id variable_dimensionListE sigAttrListE '=' expr
{ $$ = VARDONEA(*$1, $2, $3); $$->valuep($5); }
{ $$ = VARDONEA($<fl>1, *$1, $2, $3); $$->valuep($5); }
;
parenE:
@@ -2453,7 +2480,10 @@ expr<nodep>: // IEEE: part of expression/constant_expression/primary
| '_' '(' statePushVlg expr statePop ')' { $$ = $4; } // Arbitrary Verilog inside PSL
//
// // IEEE: cast/constant_cast
//UNSUP casting_type yP_TICK '(' expr ')' { UNSUP }
| casting_type yP_TICK '(' expr ')' { $$ = new AstCast($2,$4,$1); }
// // expanded from casting_type
| ySIGNED yP_TICK '(' expr ')' { $$ = new AstSigned($1,$4); }
| yUNSIGNED yP_TICK '(' expr ')' { $$ = new AstUnsigned($1,$4); }
// // Spec only allows primary with addition of a type reference
// // We'll be more general, and later assert LHS was a type.
//UNSUP ~l~expr yP_TICK '(' expr ')' { UNSUP }
@@ -2680,46 +2710,58 @@ gateUnsupList<nodep>:
;
gateBuf<nodep>:
gateIdE instRangeE '(' idClassSel ',' expr ')' { $$ = new AstAssignW ($3,$4,$6); }
gateIdE instRangeE '(' variable_lvalue ',' expr ')'
{ $$ = new AstAssignW ($3,$4,$6); }
;
gateBufif0<nodep>:
gateIdE instRangeE '(' idClassSel ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, new AstConst($3,V3Number($3,"1'bz")), $6)); }
gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')'
{ $$ = new AstAssignW ($3,$4,new AstBufIf1($3,new AstNot($3,$8),$6)); }
;
gateBufif1<nodep>:
gateIdE instRangeE '(' idClassSel ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, $6, new AstConst($3,V3Number($3,"1'bz")))); }
gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')'
{ $$ = new AstAssignW ($3,$4,new AstBufIf1($3,$8,$6)); }
;
gateNot<nodep>:
gateIdE instRangeE '(' idClassSel ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); }
gateIdE instRangeE '(' variable_lvalue ',' expr ')'
{ $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); }
;
gateNotif0<nodep>:
gateIdE instRangeE '(' idClassSel ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, new AstConst($3,V3Number($3,"1'bz")), new AstNot($3, $6))); }
gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')'
{ $$ = new AstAssignW ($3,$4,new AstBufIf1($3,new AstNot($3,$8), new AstNot($3, $6))); }
;
gateNotif1<nodep>:
gateIdE instRangeE '(' idClassSel ',' expr ',' expr ')' { $$ = new AstAssignW ($3,$4,new AstCond($3,$8, new AstNot($3,$6), new AstConst($3,V3Number($3,"1'bz")))); }
gateIdE instRangeE '(' variable_lvalue ',' expr ',' expr ')'
{ $$ = new AstAssignW ($3,$4,new AstBufIf1($3,$8, new AstNot($3,$6))); }
;
gateAnd<nodep>:
gateIdE instRangeE '(' idClassSel ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,$6); }
gateIdE instRangeE '(' variable_lvalue ',' gateAndPinList ')'
{ $$ = new AstAssignW ($3,$4,$6); }
;
gateNand<nodep>:
gateIdE instRangeE '(' idClassSel ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); }
gateIdE instRangeE '(' variable_lvalue ',' gateAndPinList ')'
{ $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); }
;
gateOr<nodep>:
gateIdE instRangeE '(' idClassSel ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,$6); }
gateIdE instRangeE '(' variable_lvalue ',' gateOrPinList ')'
{ $$ = new AstAssignW ($3,$4,$6); }
;
gateNor<nodep>:
gateIdE instRangeE '(' idClassSel ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); }
gateIdE instRangeE '(' variable_lvalue ',' gateOrPinList ')'
{ $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); }
;
gateXor<nodep>:
gateIdE instRangeE '(' idClassSel ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,$6); }
gateIdE instRangeE '(' variable_lvalue ',' gateXorPinList ')'
{ $$ = new AstAssignW ($3,$4,$6); }
;
gateXnor<nodep>:
gateIdE instRangeE '(' idClassSel ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); }
gateIdE instRangeE '(' variable_lvalue ',' gateXorPinList ')'
{ $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); }
;
gatePullup<nodep>:
gateIdE instRangeE '(' idClassSel ')' { $$ = new AstPull ($3, $4, true); }
gateIdE instRangeE '(' variable_lvalue ')' { $$ = new AstPull ($3, $4, true); }
;
gatePulldown<nodep>:
gateIdE instRangeE '(' idClassSel ')' { $$ = new AstPull ($3, $4, false); }
gateIdE instRangeE '(' variable_lvalue ')' { $$ = new AstPull ($3, $4, false); }
;
gateUnsup<nodep>:
gateIdE instRangeE '(' gateUnsupPinList ')' { $$ = new AstImplicit ($3,$4); }
@@ -2819,8 +2861,8 @@ idAny<strp>: // Any kind of identifier
idSVKwd<strp>: // Warn about non-forward compatible Verilog 2001 code
// // yBIT, yBYTE won't work here as causes conflicts
yDO { static string s = "do" ; $$ = &s; ERRSVKWD($1,*$$); }
| yFINAL { static string s = "final"; $$ = &s; ERRSVKWD($1,*$$); }
yDO { static string s = "do" ; $$ = &s; ERRSVKWD($1,*$$); $<fl>$=$<fl>1; }
| yFINAL { static string s = "final"; $$ = &s; ERRSVKWD($1,*$$); $<fl>$=$<fl>1; }
;
variable_lvalue<nodep>: // IEEE: variable_lvalue or net_lvalue
@@ -2872,7 +2914,7 @@ idDottedMore<nodep>:
// id below includes:
// enum_identifier
idArrayed<nodep>: // IEEE: id + select
id { $$ = new AstText(CRELINE(),*$1); }
id { $$ = new AstText($<fl>1,*$1); }
// // IEEE: id + part_select_range/constant_part_select_range
| idArrayed '[' expr ']' { $$ = new AstSelBit($2,$1,$3); } // Or AstArraySel, don't know yet.
| idArrayed '[' constExpr ':' constExpr ']' { $$ = new AstSelExtract($2,$1,$3,$5); }
@@ -2883,7 +2925,7 @@ idArrayed<nodep>: // IEEE: id + select
// VarRef without any dots or vectorizaion
varRefBase<varrefp>:
id { $$ = new AstVarRef(CRELINE(),*$1,false);}
id { $$ = new AstVarRef($<fl>1,*$1,false);}
;
// yaSTRING shouldn't be used directly, instead via an abstraction below
@@ -3091,7 +3133,7 @@ void V3ParseImp::parserClear() {
AstNode* V3ParseGrammar::createSupplyExpr(FileLine* fileline, string name, int value) {
FileLine* newfl = new FileLine (fileline);
newfl->warnOff(V3ErrorCode::WIDTH, true);
AstNode* nodep = new AstConst(newfl, V3Number(fileline));
AstNode* nodep = new AstConst(newfl, V3Number(newfl));
// Adding a NOT is less work than figuring out how wide to make it
if (value) nodep = new AstNot(newfl, nodep);
nodep = new AstAssignW(newfl, new AstVarRef(fileline, name, true),
+3 -2
View File
@@ -110,8 +110,8 @@ if ($#opt_tests<0) {
}
mkdir "obj_dir";
mkdir "logs";
our $Log_Filename = "obj_dir/driver_".strftime("%Y%m%d_%H%M%S.log", localtime);
my $leftcnt=0; my $okcnt=0; my $failcnt=0; my $skcnt=0;
my @fails;
@@ -161,6 +161,7 @@ sub one_test {
push @fails, "\t\tmake$j && test_regress/"
.$test->{pl_filename}." ".join(' ',@Orig_ARGV_Sw)."\n";
$failcnt++;
report(\@fails, $Log_Filename);
if ($opt_stop) { die "%Error: --stop and errors found\n"; }
}
$leftcnt--;
@@ -170,7 +171,7 @@ sub one_test {
}
report(\@fails, undef);
report(\@fails, "obj_dir/driver_".strftime("%Y%m%d_%H%M%S.log", localtime));
report(\@fails, $Log_Filename);
exit(10) if $failcnt;
+1 -1
View File
@@ -13,7 +13,7 @@
// please note it here, otherwise:**
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2010 by Wilson Snyder.
// without warranty, 2011 by Wilson Snyder.
module t (/*AUTOARG*/
// Inputs
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+26
View File
@@ -0,0 +1,26 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2011 by Wilson Snyder.
module t;
typedef logic [3:0] mc_t;
typedef mc_t tocast_t;
mc_t o;
initial begin
if (4'shf > 4'sh0) $stop;
if (signed'(4'hf) > 4'sh0) $stop;
if (4'hf < 4'h0) $stop;
if (unsigned'(4'shf) < 4'h0) $stop;
o = tocast_t'(4'b1);
if (o != 4'b1) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+4 -3
View File
@@ -12,11 +12,12 @@ compile (
verilator_make_gcc => 0,
fails => 1,
expect=>
'%Warning-CDCRSTLOGIC: t/t_cdc_async_bad.v:\d+: Logic in path that feeds async reset, via signal: TOP->v.rst2_bad_n
'%Warning-CDCRSTLOGIC: t/t_cdc_async_bad.v:\d+: Logic in path that feeds async reset, via signal: v.rst2_bad_n
%Warning-CDCRSTLOGIC: Use "/\* verilator lint_off CDCRSTLOGIC \*/" and lint_on around source to disable this message.
%Warning-CDCRSTLOGIC: See details in obj_dir/t_cdc_async_bad/Vt_cdc_async_bad__cdc.txt
%Warning-CDCRSTLOGIC: t/t_cdc_async_bad.v:\d+: Logic in path that feeds async reset, via signal: TOP->v.rst6a_bad_n
%Warning-CDCRSTLOGIC: t/t_cdc_async_bad.v:\d+: Logic in path that feeds async reset, via signal: TOP->v.rst3_bad_n
%Warning-CDCRSTLOGIC: t/t_cdc_async_bad.v:\d+: Logic in path that feeds async reset, via signal: v.rst6a_bad_n
%Warning-CDCRSTLOGIC: t/t_cdc_async_bad.v:\d+: Logic in path that feeds async reset, via signal: v.rst6b_bad_n
%Warning-CDCRSTLOGIC: t/t_cdc_async_bad.v:\d+: Logic in path that feeds async reset, via signal: v.rst3_bad_n
%Error: Exiting due to.*',
);
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vl_time_multiplier} = 1000;
compile (
);
execute (
check_finished=>1,
expect=> quotemeta(
'[1000.000] cyc==99 crc=2961926edde3e5c6018be970cdbf327b72b5f3c5eab42995891005eec8767e5fdf03051edbe9d222ee756ee34d8d6c83ee877aad65c487140ac87d26c636a66214b4a69acad924c568cc8e8c79f97d07a6eedf91011919d0e3cdda5215ee58c942f6c4dea48b3f38abc77bf47e4f6d6a859fcc5b5d46ec9d2f6a5bf7b978b1ba7ca15d0713a2eb06ade1570c4e3a12db687625eef8dfebcb4095ab4bdffe79c1298f609307a5ef773a6432b855e3e54deb88ca342bf5a7fecc5f2f3e165a59cdb9179718a2d11c9d55f14d69f40b01e41fcb7335a8872a6ba7876ec684d6a3af0b82aa31cca6e26340a2589cf7bf886faa8d23844596dc71233c7025c5250a968b770ab72db90b03d8c045fb8848159df544a3a3bf063269be0aa11d5507f5c8b328b760a6df9e3fbe276faad8eadee126443ad3f99d595b12d0ae514b20693298a58642a07718f9ab7ea8c66575f7f8d0e3ba77d992235b3d5a4e015a7ff9b97a8c4f48ebdbfc2365e6bca4dd3ba6bfc7e850f7c8e2842c717a1d85a977a033f564fc
[1000.000] cyc==99 crc=001010010110000110010010011011101101110111100011111001011100011000000001100010111110100101110000110011011011111100110010011110110111001010110101111100111100010111101010101101000010100110010101100010010001000000000101111011101100100001110110011111100101111111011111000000110000010100011110110110111110100111010010001000101110111001110101011011101110001101001101100011010110110010000011111011101000011101111010101011010110010111000100100001110001010000001010110010000111110100100110110001100011011010100110011000100001010010110100101001101001101011001010110110010010010011000101011010001100110010001110100011000111100111111001011111010000011110100110111011101101111110010001000000010001100100011001110100001110001111001101110110100101001000010101111011100101100011001001010000101111011011000100110111101010010010001011001111110011100010101011110001110111101111110100011111100100111101101101011010101000010110011111110011000101101101011101010001101110110010011101001011110110101001011011111101111011100101111000101100011011101001111100101000010101110100000111000100111010001011101011000001101010110111100001010101110000110001001110001110100001001011011011011010000111011000100101111011101111100011011111111010111100101101000000100101011010101101001011110111111111111001111001110000010010100110001111011000001001001100000111101001011110111101110111001110100110010000110010101110000101010111100011111001010100110111101011100010001100101000110100001010111111010110100111111111101100110001011111001011110011111000010110010110100101100111001101101110010001011110010111000110001010001011010001000111001001110101010101111100010100110101101001111101000000101100000001111001000001111111001011011100110011010110101000100001110010101001101011101001111000011101101110110001101000010011010110101000111010111100001011100000101010101000110001110011001010011011100010011000110100000010100010010110001001110011110111101111111000100001101111101010101000110100100011100001000100010110010110110111000111000100100011001111000111000000100101110001010010010100001010100101101000101101110111000010101011011100101101101110010000101100000011110110001100000001000101111110111000100001001000000101011001110111110101010001001010001110100011101111110000011000110010011010011011111000001010101000010001110101010101000001111111010111001000101100110010100010110111011000001010011011011111100111100011111110111110001001110110111110101010110110001110101011011110111000010010011001000100001110101101001111111001100111010101100101011011000100101101000010101110010100010100101100100000011010010011001010011000101001011000011001000010101000000111011100011000111110011010101101111110101010001100011001100101011101011111011111111000110100001110001110111010011101111101100110010010001000110101101100111101010110100100111000000001010110100111111111111001101110010111101010001100010011110100100011101011110110111111110000100011011001011110011010111100101001001101110100111011101001101011111111000111111010000101000011110111110010001110001010000100001011000111000101111010000111011000010110101001011101111010000000110011111101010110010011111100'
),
);
ok(1);
1;
+33
View File
@@ -0,0 +1,33 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2011 by Wilson Snyder.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc=0;
reg [4095:0] crc;
// Test loop
always @ (posedge clk) begin
cyc <= cyc + 1;
crc <= {crc[4094:0], crc[63]^crc[2]^crc[0]}; // not a good crc :)
if (cyc==0) begin
// Setup
crc <= 4096'h9f51804b5275c7b6ab9907144a58649bb778f9718062fa5c336fcc9edcad7cf17aad0a656244017bb21d9f97f7c0c147b6fa7488bb9d5bb8d3635b20fba1deab597121c502b21f49b18da998852d29a6b2b649315a3323a31e7e5f41e9bbb7e44046467438f37694857b963250bdb137a922cfce2af1defd1f93db5aa167f316d751bb274bda96fdee5e2c6eb21886633246b165341f0594c27697b06b62b1ad05ebe3c08909a54272de651296dcdd3d1774fc432d22210d8f6afa50b02cf23336f8cc3a0a2ebfd1a3a60366a1b66ef346e0379116d68caa01279ac2772d1f3cd76d2cbbc68ada6f83ec2441b2679b405486df8aa734ea1729b40c3f82210e8e42823eb3fd6ca77ee19f285741c4e8bac1ab7855c3138e84b6da1d897bbe37faf2d0256ad2f7ff9e704a63d824c1e97bddce990cae1578f9537ae2328d0afd69ffb317cbcf859696736e45e5c628b44727557c535a7d02c07907f2dccd6a21ca9ae9e1dbb1a135a8ebc2e0aa8c7329b898d02896273defe21beaa348e11165b71c48cf1c09714942a5a2ddc2adcb6e42c0f630117ee21205677d5128e8efc18c9a6f82a8475541fd722cca2dd829b7e78fef89dbeab63ab7b849910eb4fe675656c4b42b9452c81a4ca6296190a81dc63e6adfaa31995d7dfe3438ee9df66488d6cf569380569ffe6e5ea313d23af6ff08d979af29374ee9aff1fa143df238a1;
end
else if (cyc==99) begin
$write("[%0t] cyc==%0d crc=%x%x%x%x\n",$time, cyc, crc[4095:3072], crc[2071:2048], crc[2047:1024], crc[1023:0]);
$write("[%0t] cyc==%0d crc=%b%b%b%b\n",$time, cyc, crc[4095:3072], crc[2071:2048], crc[2047:1024], crc[1023:0]);
//Unsupported: $write("[%0t] cyc==%0d crc=%x\n",$time, cyc, crc);
if (crc != 4096'h2961926edde3e5c6018be970cdbf327b72b5f3c5eab42995891005eec8767e5fdf03051edbe9d222ee756ee34d8d6c83ee877aad65c487140ac87d26c636a66214b4a69acad924c568cc8e8c79f97d07a6eedf91011919d0e3cdda5215ee58c942f6c4dea48b3f38abc77bf47e4f6d6a859fcc5b5d46ec9d2f6a5bf7b978b1bac862198cc91ac594d07c165309da5ec1ad8ac6b417af8f0224269509cb79944a5b7374f45dd3f10cb48884363dabe942c0b3c8ccdbe330e828baff468e980d9a86d9bbcd1b80de445b5a32a8049e6b09dcb47cf35db4b2ef1a2b69be0fb09106c99e6d01521b7e2a9cd3a85ca6d030fe08843a390a08facff5b29dfb867ca15d0713a2eb06ade1570c4e3a12db687625eef8dfebcb4095ab4bdffe79c1298f609307a5ef773a6432b855e3e54deb88ca342bf5a7fecc5f2f3e165a59cdb9179718a2d11c9d55f14d69f40b01e41fcb7335a8872a6ba7876ec684d6a3af0b82aa31cca6e26340a2589cf7bf886faa8d23844596dc71233c7025c5250a968b770ab72db90b03d8c045fb8848159df544a3a3bf063269be0aa11d5507f5c8b328b760a6df9e3fbe276faad8eadee126443ad3f99d595b12d0ae514b20693298a58642a07718f9ab7ea8c66575f7f8d0e3ba77d992235b3d5a4e015a7ff9b97a8c4f48ebdbfc2365e6bca4dd3ba6bfc7e850f7c8e2842c717a1d85a977a033f564fc
) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
+1
View File
@@ -48,6 +48,7 @@ module t (/*AUTOARG*/);
if (three != 3'b111) $stop;
if ($bits(sized_based_on_enum) != 8) $stop;
if ($bits(three_t) != 3) $stop;
$write("*-* All Finished *-*\n");
$finish;
+2 -2
View File
@@ -1,6 +1,6 @@
// Test that environment substitutions work
-f $VERILATOR_ROOT/test_regress/t/t_flag_f__2.vc
// Env var with .v file
$VERILATOR_ROOT/test_regress/t/t_flag_f__3.v
// Env var with .v file, and parens
${VERILATOR_ROOT}/test_regress/t/t_flag_f__3.v
// Test -f
-F $VERILATOR_ROOT/test_regress/t/tsub/t_flag_f_tsub.vc
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
top_filename("t/t_flag_wfatal.v");
compile (
v_flags2 => ["--lint-only -Wno-fatal"],
fails=>0,
verilator_make_gcc => 0,
make_top_shell => 0,
make_main => 0,
expect=>
q{%Warning-WIDTH: t/t_flag_wfatal.v:\d+: Operator ASSIGNW expects 4 bits on the Assign RHS, but Assign RHS.s CONST '6'h2e' generates 6 bits.
%Warning-WIDTH: Use .* and lint_on around source to disable this message.
},
) if $Self->{v3};
ok(1);
1;
+11
View File
@@ -0,0 +1,11 @@
// 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*/);
// Width error below
wire [3:0] foo = 6'h2e;
endmodule
+14
View File
@@ -47,6 +47,14 @@ module t;
nil();
if (n !== 10) $stop;
// Functions called as tasks
rglobal = 32'h4;
if (inc_and_return(32'h2) != 32'h6) $stop;
if (rglobal !== 32'h6) $stop;
rglobal = 32'h6;
inc_and_return(32'h3);
if (rglobal !== 32'h9) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
@@ -133,4 +141,10 @@ module t;
toint = fa + 32'h1;
endfunction
function [31:0] inc_and_return;
input [31:0] inc;
rglobal = rglobal + inc;
return rglobal;
endfunction
endmodule
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2011 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
v_flags2 => ["--lint-only"],
fails=>1,
expect=>
q{%Error: t/t_func_task_bad.v:\d+: Illegal call of a task as a function: task_as_func
%Error: Exiting due to.*},
);
ok(1);
1;
+16
View File
@@ -0,0 +1,16 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2011 by Wilson Snyder.
module t (/*AUTOARG*/);
initial begin
if (task_as_func(1'b0)) $stop;
end
task task_as_func;
input ign;
endtask
endmodule
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2011 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
v_flags2 => ["--lint-only"],
fails=>1,
expect=>
q{%Error: t/t_func_tie_bad.v:\d+: Function/task output connected to constant instead of variable: b
%Error: Exiting due to.*},
);
ok(1);
1;
+19
View File
@@ -0,0 +1,19 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2011 by Wilson Snyder.
module t (/*AUTOARG*/);
initial begin
func(0, 1'b1);
end
function automatic int func
(
input int a,
output bit b );
return 0;
endfunction
endmodule
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
v_flags2 => ["--lint-only"],
fails=>1,
expect=>
q{%Error: t/t_func_wide_out_bad.v:\d+: Unsupported: Function output argument 'data' requires 4350 bits, but connection's VARREF 'msg' generates 4352 bits.
%Error: Exiting due to.*},
);
ok(1);
1;
+29
View File
@@ -0,0 +1,29 @@
// 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 ();
parameter MSG_PORT_WIDTH = 4350;
localparam PAYLOAD_MAX_BITS = 4352;
reg [MSG_PORT_WIDTH-1:0] msg;
initial begin
// Operator TASKREF 'func' expects 4352 bits on the Function Argument, but Function Argument's VARREF 'msg' generates 4350 bits.
// verilator lint_off WIDTH
func(msg);
// verilator lint_on WIDTH
if (msg !== {MSG_PORT_WIDTH{1'b1}}) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
function integer func (output bit [PAYLOAD_MAX_BITS-1:0] data);
/*verilator no_inline_task*/
data = {PAYLOAD_MAX_BITS{1'b1}};
return (1);
endfunction
endmodule
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2008 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
v_flags2 => ["--lint-only -Wwarn-BLKSEQ -Wwarn-COMBDLY"],
fails=>0,
verilator_make_gcc => 0,
make_top_shell => 0,
make_main => 0,
) if $Self->{v3};
ok(1);
1;
+102
View File
@@ -0,0 +1,102 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2010 by Wilson Snyder.
module t (/*AUTOARG*/
// Outputs
data_out,
// Inputs
wr, wa, rst_l, rd, ra, data_in, clk
);
input clk;
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input [31:0] data_in; // To sub of reg_1r1w.v
input [7:0] ra; // To sub of reg_1r1w.v
input rd; // To sub of reg_1r1w.v
input rst_l; // To sub of reg_1r1w.v
input [7:0] wa; // To sub of reg_1r1w.v
input wr; // To sub of reg_1r1w.v
// End of automatics
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output [31:0] data_out; // From sub of reg_1r1w.v
// End of automatics
reg_1r1w #(.WIDTH(32), .DEPTH(256), .ADRWID(8))
sub
(/*AUTOINST*/
// Outputs
.data_out (data_out[31:0]),
// Inputs
.data_in (data_in[31:0]),
.ra (ra[7:0]),
.wa (wa[7:0]),
.wr (wr),
.rd (rd),
.clk (clk),
.rst_l (rst_l));
endmodule
module reg_1r1w
#(
parameter WIDTH=32,
parameter ADRWID=10,
parameter DEPTH=1024,
parameter RST=0
)
(/*AUTOARG*/
// Outputs
data_out,
// Inputs
data_in, ra, wa, wr, rd, clk, rst_l
);
input [WIDTH-1:0] data_in;
input [ADRWID-1:0] ra;
input [ADRWID-1:0] wa;
input wr;
input rd;
input clk;
input rst_l;
output [WIDTH-1:0] data_out;
reg [WIDTH-1:0] array [0:DEPTH-1];
reg [ADRWID-1:0] ra_r, wa_r;
reg [WIDTH-1:0] data_in_r;
reg wr_r;
reg rd_r;
integer x;
always @(posedge clk or negedge rst_l) begin
if (!rst_l) begin
for (x=0; x<DEPTH; x=x+1) begin // <== VERILATOR FLAGS THIS LINE
if (RST == 1) begin
array[x] <= 0;
end
end
ra_r <= 0;
wa_r <= 0;
wr_r <= 0;
rd_r <= 0;
data_in_r <= 0;
end
else begin
ra_r <= ra;
wa_r <= wa;
wr_r <= wr;
rd_r <= rd;
data_in_r <= data_in;
if (wr_r) array[wa_r] <= data_in_r;
end
end
endmodule
// Local Variables:
// verilog-auto-inst-param-value: t
// End:
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
make_top_shell => 0,
make_main => 0,
v_flags2 => ["--lint-only -Wwarn-UNUSED"],
verilator_make_gcc => 0,
fails=>1,
expect=>
'%Warning-UNUSED: t/t_lint_once_bad.v:\d+: Signal is not driven, nor used: unus1
%Warning-UNUSED: Use .* to disable this message.
%Warning-UNUSED: t/t_lint_once_bad.v:\d+: Signal is not driven, nor used: unus2
%Error: Exiting due to.*',
) if $Self->{v3};
ok(1);
1;
+19
View File
@@ -0,0 +1,19 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2006 by Wilson Snyder.
// Check that we report warnings only once on parameterized modules
// Also check that we don't suppress warnings on the same line
module t ();
sub #(.A(1)) sub1();
sub #(.A(2)) sub2();
sub #(.A(3)) sub3();
endmodule
module sub;
parameter A = 0;
reg [A:0] unus1; reg [A:0] unus2;
endmodule
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# 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
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
v_flags2 => ["--lint-only"],
fails=>1,
verilator_make_gcc => 0,
make_top_shell => 0,
make_main => 0,
expect=>
'%Error: t/t_lint_pindup_bad.v:\d+: Duplicate pin connection: i
%Error: t/t_lint_pindup_bad.v:\d+: ... Location of original pin connection
%Error: t/t_lint_pindup_bad.v:\d+: Pin not found: __pinNumber4
%Error: t/t_lint_pindup_bad.v:\d+: Duplicate pin connection: P
%Error: t/t_lint_pindup_bad.v:\d+: ... Location of original pin connection
%Error: t/t_lint_pindup_bad.v:\d+: Duplicate pin connection: P
%Error: t/t_lint_pindup_bad.v:\d+: ... Location of original pin connection
%Error: Exiting due to.*',
) if $Self->{v3};
ok(1);
1;
+31
View File
@@ -0,0 +1,31 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2010 by Wilson Snyder.
module t
(
output wire o,
input wire i,
input wire i2
);
sub
#(, .P(2), .P(3))
sub (.o(o),
.i(i),
.i(i2),
);
endmodule
module sub
#(parameter P=1)
(
output wire o,
input wire i
);
assign o = ~i;
endmodule
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# 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
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
v_flags2 => ["--lint-only"],
fails=>1,
verilator_make_gcc => 0,
make_top_shell => 0,
make_main => 0,
expect=>
'%Error: t/t_lint_setout_bad.v:\d+: Output port is connected to a constant pin, electrical short
.*',
) if $Self->{v3};
ok(1);
1;
+34
View File
@@ -0,0 +1,34 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2011 by Wilson Snyder.
module t
(
input wire reset_l,
input wire clk
);
sub sub_I
(
.clk(clk),
.reset_l(reset_l),
.cpu_if_timeout(1'b0)
);
endmodule
module sub
(
input wire clk, reset_l,
output reg cpu_if_timeout
);
always @(posedge clk) begin
if (!reset_l) begin
cpu_if_timeout <= 1'b0;
end
else begin
cpu_if_timeout <= 1'b0;
end
end
endmodule
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# 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
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
top_filename("t/t_lint_setout_bad.v");
compile (
v_flags2 => ["--lint-only -Oi"],
fails=>1,
verilator_make_gcc => 0,
make_top_shell => 0,
make_main => 0,
expect=>
'%Error: t/t_lint_setout_bad.v:\d+: Output port is connected to a constant pin, electrical short
.*',
) if $Self->{v3};
ok(1);
1;
+1 -1
View File
@@ -14,7 +14,7 @@ compile (
make_top_shell => 0,
make_main => 0,
expect=>
'%Warning-SYNCASYNCNET: t/t_lint_syncasyncnet_bad.v:\d+: Signal flopped as both synchronous and async: TOP->rst_both_l
'%Warning-SYNCASYNCNET: t/t_lint_syncasyncnet_bad.v:\d+: Signal flopped as both synchronous and async: rst_both_l
%Warning-SYNCASYNCNET: Use .* around source to disable this message.
%Warning-SYNCASYNCNET: t/t_lint_syncasyncnet_bad.v:\d+: ... Location of async usage
%Warning-SYNCASYNCNET: t/t_lint_syncasyncnet_bad.v:\d+: ... Location of sync usage
+1 -1
View File
@@ -62,7 +62,7 @@ module t (/*AUTOARG*/
// We never read past bounds, or get unspecific results
// We also never read lowest indexes, as writing outside of range may corrupt them
if (index0>=0+1 && index0<=2 && index1>=1+1 && index1<=3 && index2>=2+1 && index2<=5) begin
if (index0>=0+1 && index0<=2 && index1>=1+1 /*&& index1<=3 CMPCONST*/ && index2>=2+1 && index2<=5) begin
narrow <= ({narrow[6:0], narrow[7]^narrow[0]}
^ {memn[index0][index1][index2]});
wread = memw[index0][index1][index2];
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# 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
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
v_flags2 => ["--lint-only"],
fails=>1,
verilator_make_gcc => 0,
make_top_shell => 0,
make_main => 0,
expect=>
'%Error: t/t_param_circ_bad.v:\d+: Variable\'s initial value is circular: X
%Error: Exiting due to.*',
) if $Self->{v3};
ok(1);
1;
+12
View File
@@ -0,0 +1,12 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2011 by Wilson Snyder.
module t (/*AUTOARG*/);
sub sub ();
endmodule
module sub #(parameter WIDTH=X, parameter X=WIDTH)
();
endmodule
+21 -17
View File
@@ -1,11 +1,13 @@
`line 1 "t/t_pipe_filter.v" 1
`line 3 "t/t_pipe_filter.v" 0
`line 6 "t/t_pipe_filter.v" 0
`line 10 "t/t_pipe_filter.v" 0
@@ -19,37 +21,39 @@ example line 11;
int lint_off_line_7 = 1;
`line 2 "t/t_pipe_filter_inc.vh" 0
int lint_off_line_8 = 1;
`line 5 "t/t_pipe_filter_inc.vh" 0
`line 8 "t/t_pipe_filter_inc.vh" 0
inc line 6;
inc line 7;
inc line 8;
inc line 7;
inc line 8;
inc line 9;
`line 13 "t/t_pipe_filter_inc.vh" 2
`line 13 "t/t_pipe_filter.v" 0
`line 15 "t/t_pipe_filter.v" 0
`line 14 "t/t_pipe_filter.v" 0
`line 15 "t/t_pipe_filter.v" 0
`line 1 "t/t_pipe_filter_inc.vh" 1
int lint_off_line_7 = 1;
`line 2 "t/t_pipe_filter_inc.vh" 0
int lint_off_line_8 = 1;
`line 5 "t/t_pipe_filter_inc.vh" 0
`line 8 "t/t_pipe_filter_inc.vh" 0
inc line 6;
inc line 7;
inc line 8;
inc line 7;
inc line 8;
inc line 9;
`line 13 "t/t_pipe_filter_inc.vh" 2
+141 -133
View File
@@ -1,39 +1,38 @@
`line 1 "t/t_preproc.v" 1
`line 7 "t/t_preproc.v" 0
`line 5 "t/t_preproc.v" 0
`line 7 "t/t_preproc.v" 0
`line 1 "t/t_preproc_inc2.vh" 1
`line 3 "t/t_preproc_inc2.vh" 0
`line 4 "t/t_preproc_inc2.vh" 0
`line 2 "t/t_preproc_inc2.vh" 0
At file "t/t_preproc_inc2.vh" line 4
`line 6 "t/t_preproc_inc2.vh" 0
`line 1 "t/t_preproc_inc3.vh" 1
`line 2 "inc3_a_filename_from_line_directive" 0
`line 6 "inc3_a_filename_from_line_directive" 0
At file "inc3_a_filename_from_line_directive" line 10
`line 12 "inc3_a_filename_from_line_directive" 0
`line 15 "inc3_a_filename_from_line_directive" 0
@@ -48,23 +47,24 @@ At file "t/t_preproc_inc2.vh" line 4
`line 7 "t/t_preproc.v" 0
`line 9 "t/t_preproc.v" 0
`line 12 "t/t_preproc.v" 0
/*verilator pass_thru comment*/
/*verilator pass_thru comment*/
`line 14 "t/t_preproc.v" 0
/*verilator pass_thru_comment2*/
/*verilator pass_thru_comment2*/
`line 16 "t/t_preproc.v" 0
`line 19 "t/t_preproc.v" 0
`line 22 "t/t_preproc.v" 0
wire [3:0] q = {
1'b1 ,
1'b0 ,
@@ -78,7 +78,7 @@ text.
`line 31 "t/t_preproc.v" 0
foo bar
foo bar
foobar2
`line 36 "t/t_preproc.v" 0
@@ -92,8 +92,8 @@ foobar2
`line 46 "t/t_preproc.v" 0
`line 45 "t/t_preproc.v" 0
first part
`line 46 "t/t_preproc.v" 0
second part
@@ -108,7 +108,8 @@ first part
c}
Line_Preproc_Check 48
`line 50 "t/t_preproc.v" 0
`line 52 "t/t_preproc.v" 0
@@ -160,11 +161,13 @@ bar_suffix more
`line 86 "t/t_preproc.v" 0
$c("Zap(\"","bug2","\");");;
`line 88 "t/t_preproc.v" 0
`line 91 "t/t_preproc.v" 0
`line 94 "t/t_preproc.v" 0
@@ -174,7 +177,7 @@ bar_suffix more
initial begin
$display("pre thrupre thrumid thrupost post: \"right side\"");
$display("left side: \"right side\"");
$display("left side: \"right side\"");
@@ -182,25 +185,26 @@ bar_suffix more
$display("na: \"right_side\"");
$display("prep ( midp1 left_side midp2 ( outp ) ): \"right_side\"");
$display("na: \"nana\"");
$display("left_side right_side: \"left_side right_side\"");
$display(": \"\"");
$display("left_side right_side: \"left_side right_side\"");
$display(": \"\"");
$display("left side: \"right side\"");
$display("left side: \"right side\"");
$display("standalone");
`line 115 "t/t_preproc.v" 0
$display("twoline: \"first second\"");
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
`line 125 "t/t_preproc.v" 0
`line 128 "t/t_preproc.v" 0
@@ -216,7 +220,7 @@ wire tmp_d1 = d1;
`line 134 "t/t_preproc.v" 0
wire tmp_o1 = tmp_d1 + 1;
`line 134 "t/t_preproc.v" 0
assign o1 = tmp_o1 ;
assign o1 = tmp_o1 ;
endmodule
module add2 ( input wire d2, output wire o2);
@@ -225,7 +229,7 @@ wire tmp_d2 = d2;
`line 137 "t/t_preproc.v" 0
wire tmp_o2 = tmp_d2 + 1;
`line 137 "t/t_preproc.v" 0
assign o2 = tmp_o2 ;
assign o2 = tmp_o2 ;
endmodule
`line 140 "t/t_preproc.v" 0
@@ -235,8 +239,8 @@ endmodule
`line 147 "t/t_preproc.v" 0
`line 146 "t/t_preproc.v" 0
@@ -250,11 +254,11 @@ endmodule
`line 151 "t/t_preproc.v" 0
psl cover { ~m5k.f .ctl._ctl_mvldx_m1.d[i] & m5k.f .ctl._ctl_mvldx_m1.q[i] & !m5k.f .ctl._ctl_mvldx_m1.cond & ((m5k.f .ctl.alive & m5k.f .ctl.alive_m1))} report "fondNoFall: m5kc_fcl._ctl_mvldx_m1";
`line 151 "t/t_preproc.v" 0
end endgenerate
end endgenerate
`line 155 "t/t_preproc.v" 0
`line 153 "t/t_preproc.v" 0
module prot();
`protected
I!#r#e6<_Q{{E2+]I3<[3s)1@D|'E''i!O?]jD>Jo_![Cl)
@@ -262,11 +266,11 @@ module prot();
`endprotected
`line 160 "t/t_preproc.v" 0
endmodule
`line 165 "t/t_preproc.v" 0
`line 163 "t/t_preproc.v" 0
@@ -280,17 +284,17 @@ begin addr <= (({regs[6], regs[7]} + 1)); rd <= 1; end and begin addr <= (({regs
begin addr <= ({regs[6], regs[7]} + 1); rd <= 1; end
begin addr <= ({regs[6], regs[7]}); wdata <= (rdata); wr <= 1; end more
`line 179 "t/t_preproc.v" 0
`line 177 "t/t_preproc.v" 0
`line 180 "t/t_preproc.v" 0
`line 1 "t/t_preproc_inc4.vh" 1
`line 3 "t/t_preproc_inc4.vh" 0
`line 2 "t/t_preproc_inc4.vh" 0
`line 5 "t/t_preproc_inc4.vh" 0
@@ -310,8 +314,9 @@ begin addr <= ({regs[6], regs[7]}); wdata <= (rdata); wr <= 1; end more
`line 190 "t/t_preproc.v" 0
`line 193 "t/t_preproc.v" 0
@@ -320,16 +325,18 @@ $blah(this.logfile,vec);
$blah(this.logfile,vec[1,2,3]);
$blah(this.logfile,{blah.name(), " is not foo"});
`line 199 "t/t_preproc.v" 0
`line 202 "t/t_preproc.v" 0
`pragma foo = 1
`default_nettype none
`default_nettype uwire
`line 206 "t/t_preproc.v" 0
`line 209 "t/t_preproc.v" 0
@@ -339,11 +346,12 @@ $blah(this.logfile,{blah.name(), " is not foo"});
`line 213 "t/t_preproc.v" 0
Line_Preproc_Check 213
`line 215 "t/t_preproc.v" 0
`line 218 "t/t_preproc.v" 0
(p,q)
@@ -354,21 +362,22 @@ Line_Preproc_Check 213
(x,y)
Line_Preproc_Check 226
`line 228 "t/t_preproc.v" 0
`line 231 "t/t_preproc.v" 0
beginend
beginend
"beginend"
beginend
"beginend"
`line 241 "t/t_preproc.v" 0
`line 239 "t/t_preproc.v" 0
`\esc`def
@@ -376,24 +385,24 @@ beginend
`line 245 "t/t_preproc.v" 0
Not a \`define
`line 249 "t/t_preproc.v" 0
`line 247 "t/t_preproc.v" 0
x,y)--bee submacro has comma paren
`line 257 "t/t_preproc.v" 0
`line 255 "t/t_preproc.v" 0
$display("bits %d %d", $bits(foo), `10);
`line 262 "t/t_preproc.v" 0
`line 260 "t/t_preproc.v" 0
@@ -401,9 +410,9 @@ $display("bits %d %d", $bits(foo), `10);
`line 270 "t/t_preproc.v" 0
`line 268 "t/t_preproc.v" 0
@@ -441,7 +450,8 @@ $display("bits %d %d", $bits(foo), `10);
`line 284 "t/t_preproc.v" 0
\
\
@@ -449,17 +459,16 @@ $display("bits %d %d", $bits(foo), `10);
`line 293 "t/t_preproc.v" 0
`line 293 "t/t_preproc.v" 0
`line 293 "t/t_preproc.v" 0
`line 293 "t/t_preproc.v" 0
def i
`line 295 "t/t_preproc.v" 0
`line 297 "t/t_preproc.v" 0
@@ -475,17 +484,17 @@ $display("bits %d %d", $bits(foo), `10);
`line 307 "t/t_preproc.v" 0
1 /*verilator NOT IN DEFINE*/ (nodef)
2 /*verilator PART OF DEFINE*/ (hasdef)
1 /*verilator NOT IN DEFINE*/ (nodef)
2 /*verilator PART OF DEFINE*/ (hasdef)
3
`line 309 "t/t_preproc.v" 0
/*verilator NOT PART
OF DEFINE*/ (nodef)
OF DEFINE*/ (nodef)
`line 310 "t/t_preproc.v" 0
4
`line 310 "t/t_preproc.v" 0
/*verilator PART
OF DEFINE*/ (nodef)
OF DEFINE*/ (nodef)
`line 311 "t/t_preproc.v" 0
5 also in
`line 311 "t/t_preproc.v" 0
@@ -496,7 +505,8 @@ HAS a NEW
`line 314 "t/t_preproc.v" 0
LINE
`line 316 "t/t_preproc.v" 0
`line 318 "t/t_preproc.v" 0
@@ -527,7 +537,7 @@ EXP: do if (start("verilog/inc1.v", 25)) begin message({"Blah-", "clx_scen", "
`line 340 "t/t_preproc.v" 0
do
`line 340 "t/t_preproc.v" 0
`line 340 "t/t_preproc.v" 0
`line 340 "t/t_preproc.v" 0
@@ -543,11 +553,12 @@ EXP: do if (start("verilog/inc1.v", 25)) begin message({"Blah-", "clx_scen", "
`line 340 "t/t_preproc.v" 0
end
`line 340 "t/t_preproc.v" 0
`line 340 "t/t_preproc.v" 0
while(0);
`line 342 "t/t_preproc.v" 0
`line 344 "t/t_preproc.v" 0
@@ -562,21 +573,19 @@ EXP: do if (start("verilog/inc1.v", 25)) begin message({"Blah-", "clx_scen", "
`line 349 "t/t_preproc.v" 0
`line 351 "t/t_preproc.v" 0
EXP: This is fooed
This is fooed
EXP: This is fooed_2
This is fooed_2
`line 357 "t/t_preproc.v" 0
`line 356 "t/t_preproc.v" 0
np
np
`line 362 "t/t_preproc.v" 0
@@ -586,9 +595,9 @@ np
`line 372 "t/t_preproc.v" 0
`line 370 "t/t_preproc.v" 0
@@ -603,18 +612,17 @@ np
`line 382 "t/t_preproc.v" 0
hello3hello3hello3
hello4hello4hello4hello4
`line 386 "t/t_preproc.v" 0
`line 388 "t/t_preproc.v" 0
`line 1 "t/t_preproc_inc4.vh" 1
`line 3 "t/t_preproc_inc4.vh" 0
`line 2 "t/t_preproc_inc4.vh" 0
`line 5 "t/t_preproc_inc4.vh" 0
@@ -624,10 +632,9 @@ hello4hello4hello4hello4
`line 389 "t/t_preproc.v" 0
`line 393 "t/t_preproc.v" 0
@@ -639,9 +646,8 @@ hello4hello4hello4hello4
Line_Preproc_Check 401
`line 404 "t/t_preproc.v" 0
@@ -652,15 +658,14 @@ Line_Preproc_Check 407
BAR "
`line 410 "t/t_preproc.v" 0
Line_Preproc_Check 410
`line 414 "t/t_preproc.v" 0
`line 418 "t/t_preproc.v" 0
abc
@@ -679,15 +684,14 @@ sonet_frame
EXP: sonet_frame
sonet_frame
`line 435 "t/t_preproc.v" 0
EXP: sonet_frame
sonet_frame
`line 441 "t/t_preproc.v" 0
`line 440 "t/t_preproc.v" 0
EXP: module zzz ; endmodule
@@ -700,6 +704,10 @@ EXP: module a_b ; endmodule
module a_b ; endmodule
module a_b ; endmodule
`line 452 "t/t_preproc.v" 0
integer foo;
`line 454 "t/t_preproc.v" 2
`line 457 "t/t_preproc.v" 2
+3
View File
@@ -450,3 +450,6 @@ module `Q1 ; endmodule
module `Q1 ; endmodule
//======================================================================
// bug311
integer/*NEED_SPACE*/foo;
//======================================================================
+21 -19
View File
@@ -1,14 +1,15 @@
`line 1 "t/t_preproc_def09.v" 1
`line 3 "t/t_preproc_def09.v" 0
`line 10 "t/t_preproc_def09.v" 0
`line 8 "t/t_preproc_def09.v" 0
'initial $display("start", "msg1" , "msg2", "end");'
'initial $display("start", "msg1" , "msg2" , "end");'
@@ -20,12 +21,12 @@
'initial $display("start", , , "end");'
'initial $display("start", , , "end");'
'initial $display("start", , , "end");'
`line 26 "t/t_preproc_def09.v" 0
`line 25 "t/t_preproc_def09.v" 0
'$display(5,,2,,3);'
'$display(5,,2,,3);'
@@ -33,7 +34,7 @@
'$display(1 ,,"B",,3 );'
'$display(5,,2,,);'
'$display(5,,2,,);'
`line 35 "t/t_preproc_def09.v" 0
@@ -50,21 +51,21 @@
'$display(1 ,,0,,"C");'
'$display(5,,0,,"C");'
'$display(5,,0,,"C");'
`line 50 "t/t_preproc_def09.v" 0
'b + 1 + 42 + a'
'b + 1 + 42 + a'
`line 55 "t/t_preproc_def09.v" 0
`line 54 "t/t_preproc_def09.v" 0
'"==)" "((((" () ';
'"==)" "((((" () ';
`line 60 "t/t_preproc_def09.v" 0
`line 59 "t/t_preproc_def09.v" 0
@@ -79,6 +80,7 @@
'(6) (eq=al) ZOT'
HERE-71 - Line71
`line 73 "t/t_preproc_def09.v" 0
`line 75 "t/t_preproc_def09.v" 2
+39 -38
View File
@@ -1,29 +1,29 @@
`line 1 "t/t_preproc_psl.v" 1
`line 4 "t/t_preproc_psl.v" 0
`line 7 "t/t_preproc_psl.v" 0
/*verilator metacomment preserved*/
`line 9 "t/t_preproc_psl.v" 0
/*verilator metacomment also_preserved*/
/*verilator metacomment preserved*/
/*verilator metacomment also_preserved*/
`line 11 "t/t_preproc_psl.v" 0
Hello in t_preproc_psl.v
`line 17 "t/t_preproc_psl.v" 0
`line 28 "t/t_preproc_psl.v" 0
@@ -34,13 +34,13 @@ Hello in t_preproc_psl.v
`line 28 "t/t_preproc_psl.v" 0
`line 29 "t/t_preproc_psl.v" 0
`line 28 "t/t_preproc_psl.v" 0
29
`line 31 "t/t_preproc_psl.v" 0
`line 40 "t/t_preproc_psl.v" 0
@@ -53,36 +53,37 @@ Hello in t_preproc_psl.v
`line 40 "t/t_preproc_psl.v" 0
`line 41 "t/t_preproc_psl.v" 0
`line 40 "t/t_preproc_psl.v" 0
41
`line 43 "t/t_preproc_psl.v" 0
`line 45 "t/t_preproc_psl.v" 0
`line 50 "t/t_preproc_psl.v" 0
`line 49 "t/t_preproc_psl.v" 0
`line 55 "t/t_preproc_psl.v" 0
`line 57 "t/t_preproc_psl.v" 0
`line 62 "t/t_preproc_psl.v" 0
`line 61 "t/t_preproc_psl.v" 0
`line 65 "t/t_preproc_psl.v" 0
@@ -91,8 +92,8 @@ psl assert always sig!=90;
`verilog
`line 72 "t/t_preproc_psl.v" 0
`line 71 "t/t_preproc_psl.v" 0
72
`line 74 "t/t_preproc_psl.v" 2
+28 -28
View File
@@ -1,22 +1,22 @@
`line 1 "t/t_preproc_psl.v" 1
`line 4 "t/t_preproc_psl.v" 0
`line 7 "t/t_preproc_psl.v" 0
/*verilator metacomment preserved*/
`line 9 "t/t_preproc_psl.v" 0
/*verilator metacomment also_preserved*/
/*verilator metacomment preserved*/
/*verilator metacomment also_preserved*/
`line 11 "t/t_preproc_psl.v" 0
Hello in t_preproc_psl.v
`line 17 "t/t_preproc_psl.v" 0
psl default clock = (posedge clk);
@@ -24,27 +24,26 @@ Hello in t_preproc_psl.v
psl assert always cyc!=10;
psl assert always cyc==3 -> mask==8'h2;
psl failsx: cover {cyc==3 && mask==8'h1};
psl fails2:
psl fails2:
cover {
cyc==3 && mask==8'h9};
fails3: always assert {
cyc==3 && mask==8'h10 };
29
`line 31 "t/t_preproc_psl.v" 0
psl
`line 35 "t/t_preproc_psl.v" 0
psl
fails_ml:
assert always
cyc==3 -> mask==8'h21;
psl
fails_mlalso: assert always cyc==3 -> mask==8'h21;
41
`line 43 "t/t_preproc_psl.v" 0
@@ -53,24 +52,25 @@ Hello in t_preproc_psl.v
`line 45 "t/t_preproc_psl.v" 0
psl fails3: assert always
psl cyc==3 -> mask==8'h21;
`line 50 "t/t_preproc_psl.v" 0
`line 49 "t/t_preproc_psl.v" 0
psl assert always
psl {[*]; cyc==3;
psl cyc==4; cyc==6};
`line 55 "t/t_preproc_psl.v" 0
`line 57 "t/t_preproc_psl.v" 0
`line 62 "t/t_preproc_psl.v" 0
`line 61 "t/t_preproc_psl.v" 0
psl assert always cyc!=10;
@@ -81,8 +81,8 @@ psl assert always sig!=90;
`verilog
`line 72 "t/t_preproc_psl.v" 0
`line 71 "t/t_preproc_psl.v" 0
72
`line 74 "t/t_preproc_psl.v" 2
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+116
View File
@@ -0,0 +1,116 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2011 by Wilson Snyder.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc=0;
reg [63:0] crc;
reg [63:0] sum;
parameter DW = 4;
wire [3:0] drv_a = crc[3:0];
wire [3:0] drv_b = crc[7:4];
wire [3:0] drv_e = crc[19:16];
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [DW-1:0] drv; // To/From test1 of Test1.v
wire [DW-1:0] drv2; // From test2 of Test2.v
// End of automatics
Test1 test1 (/*AUTOINST*/
// Inouts
.drv (drv[DW-1:0]),
// Inputs
.drv_a (drv_a[DW-1:0]),
.drv_b (drv_b[DW-1:0]),
.drv_e (drv_e[DW-1:0]));
Test2 test2 (/*AUTOINST*/
// Outputs
.drv2 (drv2[DW-1:0]),
// Inputs
.drv_a (drv_a[DW-1:0]),
.drv_b (drv_b[DW-1:0]),
.drv_e (drv_e[DW-1:0]));
// Aggregate outputs into a single result vector
wire [63:0] result = {60'h0, drv};
// Test loop
always @ (posedge clk) begin
`ifdef TEST_VERBOSE
$write("[%0t] cyc==%0d crc=%x drv=%x %x (%b??%b:%b)\n",$time, cyc, crc, drv, drv2, drv_e,drv_a,drv_b);
`endif
cyc <= cyc + 1;
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]};
if (cyc==0) begin
// Setup
crc <= 64'h5aef0c8d_d70a4497;
sum <= 64'h0;
end
else if (cyc<10) begin
sum <= 64'h0;
end
else if (cyc<90) begin
if (drv2 != drv) $stop;
end
else if (cyc==99) begin
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
if (crc !== 64'hc77bb9b3784ea091) $stop;
// What checksum will we end up with (above print should match)
`define EXPECTED_SUM 64'hd95d216c5a2945d0
if (sum !== `EXPECTED_SUM) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module Test1 #(
parameter DW = 4
)(
input wire [DW-1:0] drv_a,
input wire [DW-1:0] drv_b,
input wire [DW-1:0] drv_e,
inout wire [DW-1:0] drv
);
wire drv_0, drv_1, drv_2, drv_3;
bufif1 bufa0 (drv_0, drv_a[0], drv_e[0]);
bufif1 bufb0 (drv_0, drv_b[0], ~drv_e[0]);
bufif1 bufa1 (drv_1, drv_a[1], drv_e[1]);
bufif1 bufb1 (drv_1, drv_b[1], ~drv_e[1]);
bufif1 bufa2 (drv_2, drv_a[2], drv_e[2]);
bufif1 bufb2 (drv_2, drv_b[2], ~drv_e[2]);
bufif1 bufa3 (drv_3, drv_a[3], drv_e[3]);
bufif1 bufb3 (drv_3, drv_b[3], ~drv_e[3]);
assign drv = {drv_3,drv_2,drv_1,drv_0};
endmodule
module Test2 #(
parameter DW = 4
)(
input wire [DW-1:0] drv_a,
input wire [DW-1:0] drv_b,
input wire [DW-1:0] drv_e,
inout wire [DW-1:0] drv2
);
wire [DW-1:0] drv_all;
bufif1 bufa [DW-1:0] (drv_all, drv_a, drv_e);
// Below ~= bufif1 bufb [DW-1:0] (drv_all, drv_b, ~drv_e);
bufif1 bufb [DW-1:0] ({drv_all[3], drv_all[2], drv_all[1], drv_all[0]},
{drv_b[3], drv_b[2], drv_b[1], drv_b[0]},
{~drv_e[3], ~drv_e[2], ~drv_e[1], ~drv_e[0]});
assign drv2 = drv_all;
endmodule
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+31
View File
@@ -0,0 +1,31 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2011 by Wilson Snyder.
module t (/*AUTOARG*/
// Inouts
AVDD, AVSS
);
inout AVDD;
inout AVSS;
sub sub (/*AUTOINST*/
// Inouts
.AVDD (AVDD),
.AVSS (AVSS));
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
module sub (/*AUTOARG*/
// Inouts
AVDD, AVSS
);
// verilator no_inline_module
inout AVDD;
inout AVSS;
endmodule
+4 -4
View File
@@ -12,13 +12,13 @@ top_filename("t/t_unopt_combo.v");
compile (
fails=>$Self->{v3},
expect=>
'%Warning-UNOPTFLAT: t/t_unopt_combo.v:\d+: Signal unoptimizable: Feedback to clock or circular logic: TOP->v.c
'%Warning-UNOPTFLAT: t/t_unopt_combo.v:\d+: Signal unoptimizable: Feedback to clock or circular logic: v.c
%Warning-UNOPTFLAT: Use "/\* verilator lint_off UNOPTFLAT \*/" and lint_on around source to disable this message.
%Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: TOP->v.c
%Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: v.c
%Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: ALWAYS
%Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: TOP->v.b
%Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: v.b
%Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: ALWAYS
%Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: TOP->v.c
%Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: v.c
%Error: Exiting due to '
);
+1 -1
View File
@@ -11,7 +11,7 @@ top_filename("t/t_unopt_converge.v");
compile (
fails=>1,
expect=> '%Warning-UNOPT: t/t_unopt_converge.v:\d+: Signal unoptimizable: Feedback to public clock or circular logic: TOP->x
expect=> '%Warning-UNOPT: t/t_unopt_converge.v:\d+: Signal unoptimizable: Feedback to public clock or circular logic: x
.*
%Error: Exiting due to '
) if $Self->{v3};
+23
View File
@@ -118,6 +118,29 @@ module t (/*AUTOARG*/
if (total != -28) $stop;
end
//===
10: begin
// mostly cover a small index
total = 0;
for (i3=0; i3<3'd7; i3=i3+3'd1) begin
total = total - {29'd0,i3} -1;
dly_to_insure_was_unrolled[i3[0]] <= 0;
end
if (total != -28) $stop;
end
//===
11: begin
// width violation on <, causes extend
total = 0;
for (i3=3'd0; i3<7; i3=i3+1) begin
total = total - {29'd0,i3} -1;
dly_to_insure_was_unrolled[i3[0]] <= 0;
end
if (total != -28) $stop;
end
//===
// width violation on <, causes extend signed
// Unsupported as yet
//===
19: begin
$write("*-* All Finished *-*\n");
$finish;