mirror of
https://github.com/verilator/verilator.git
synced 2026-10-07 02:23:19 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c72d473e96 | ||
|
|
c8a91bd46f | ||
|
|
498f19a6a1 | ||
|
|
c7a2138ece | ||
|
|
4078902543 | ||
|
|
9e38ed9a39 | ||
|
|
183cabc77d | ||
|
|
b582e481c6 | ||
|
|
ad39931e87 | ||
|
|
1ae22e1365 | ||
|
|
b748ddfe06 | ||
|
|
e52f5f1b63 | ||
|
|
bda4b326ab | ||
|
|
70ddf32719 | ||
|
|
3edba7b662 | ||
|
|
f74ef650ac | ||
|
|
f093c3d78b | ||
|
|
d933f33bdb |
@@ -3,6 +3,21 @@ Revision history for Verilator
|
||||
The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
|
||||
* Verilator 3.890 2016-11-25
|
||||
|
||||
*** Honor --output-split on coverage constructors, bug1098. [Johan Bjork]
|
||||
|
||||
**** Fix various issues when making outside of the kit.
|
||||
|
||||
**** Fix flex 2.6.2 bug, bug1103. [Sergey Kvachonok]
|
||||
|
||||
**** Fix error on bad interface name, bug1097. [Todd Strader]
|
||||
|
||||
**** Fix error on referencing variable in parent, bug1099. [Ian Thompson]
|
||||
|
||||
**** Fix type parameters with low optimization, bug1101. [Stefan Wallentowitz]
|
||||
|
||||
|
||||
* Verilator 3.888 2016-10-14
|
||||
|
||||
** Support foreach, bug1078. [Xuan Guo]
|
||||
|
||||
+4
-5
@@ -42,9 +42,6 @@
|
||||
# reconstructed with this Makefile. This typically includes
|
||||
# everything deleted by distclean, plus more: C source files
|
||||
# produced by Bison, tags tables, info files, and so on.
|
||||
#
|
||||
# make extraclean
|
||||
# Still more severe - delete backup and autosave files, too.
|
||||
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
@@ -71,7 +68,7 @@ exec_prefix = @exec_prefix@
|
||||
# Directory in which to install scripts.
|
||||
bindir = @bindir@
|
||||
|
||||
# Directory in which to install scripts.
|
||||
# Directory in which to install manpages.
|
||||
mandir = @mandir@
|
||||
|
||||
# Directory in which to install library files.
|
||||
@@ -273,6 +270,7 @@ VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg verilator_coverage
|
||||
VL_INST_MAN_FILES = verilator.1 verilator_coverage.1 verilator_profcfunc.1
|
||||
|
||||
VL_INST_INC_BLDDIR_FILES = \
|
||||
include/verilated_config.h \
|
||||
include/verilated.mk \
|
||||
|
||||
# Files under srcdir, instead of build time
|
||||
@@ -300,7 +298,8 @@ installbin:
|
||||
# So important we use $< so VPATH is searched
|
||||
installman: $(VL_INST_MAN_FILES)
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(mandir)/man1
|
||||
for p in $^ ; do \
|
||||
cd $(srcdir) \
|
||||
; for p in $(VL_INST_MAN_FILES) ; do \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(mandir)/man1/$$p; \
|
||||
done
|
||||
|
||||
|
||||
+14
-2
@@ -6,7 +6,7 @@
|
||||
|
||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[3.888 2016-10-14])
|
||||
AC_INIT([Verilator],[3.890 2016-11-25])
|
||||
# When releasing, also update header of Changes file
|
||||
|
||||
AC_CONFIG_HEADER(src/config_build.h)
|
||||
@@ -15,7 +15,7 @@ AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk incl
|
||||
AC_MSG_RESULT([configuring for $PACKAGE_STRING])
|
||||
|
||||
# Special Substitutions - CFG_WITH_DEFENV
|
||||
AC_MSG_CHECKING(whether to disable hardcoded paths)
|
||||
AC_MSG_CHECKING(whether to use hardcoded paths)
|
||||
AC_ARG_ENABLE([defenv],
|
||||
[AS_HELP_STRING([--disable-defenv],
|
||||
[disable using some hardcoded data paths extracted from some default environment variables (the default is to use hardcoded paths)])],
|
||||
@@ -120,6 +120,18 @@ AC_DEFUN([_MY_CXX_CHECK_OPT],
|
||||
fi
|
||||
fi],
|
||||
[_my_result=no])
|
||||
# GCC is annoying, trying to be helpful, it postpones unknown -Wno-
|
||||
# options if there's no error We want to see them regardless, so try
|
||||
# forcing an error and see if we get a gcc warning
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[an_error "intentional-error-for-test.h"
|
||||
]],[])],
|
||||
[], # Ignore ok exit
|
||||
[if test -s conftest.err; then
|
||||
if grep -e "$2" conftest.err >/dev/null; then
|
||||
_my_result=no
|
||||
fi
|
||||
fi])
|
||||
AC_MSG_RESULT($_my_result)
|
||||
if test "$_my_result" = "yes" ; then
|
||||
$1="$$1 $2"
|
||||
|
||||
+2
-1
@@ -115,7 +115,8 @@ sub write_verilog {
|
||||
|
||||
sub cleanenv {
|
||||
foreach my $var (keys %ENV) {
|
||||
if ($var eq "VERILATOR_ROOT") {
|
||||
if ($var eq "VERILATOR_ROOT"
|
||||
|| $var eq "VERILATOR_INCLUDE") {
|
||||
print "unset $var # Was '$ENV{$var}'\n";
|
||||
delete $ENV{$var}
|
||||
}
|
||||
|
||||
+2
-2
@@ -166,6 +166,7 @@ RAW_OBJS = \
|
||||
V3Begin.o \
|
||||
V3Branch.o \
|
||||
V3Broken.o \
|
||||
V3CCtors.o \
|
||||
V3Case.o \
|
||||
V3Cast.o \
|
||||
V3Cdc.o \
|
||||
@@ -237,7 +238,6 @@ RAW_OBJS = \
|
||||
V3Undriven.o \
|
||||
V3Unknown.o \
|
||||
V3Unroll.o \
|
||||
V3VarResets.o \
|
||||
V3Width.o \
|
||||
V3WidthSel.o \
|
||||
|
||||
@@ -302,7 +302,7 @@ serial:: V3Ast__gen_classes.h V3ParseBison.c
|
||||
|
||||
serial_vlcov:: vlcovgen.d
|
||||
|
||||
vlcovgen.d: $(VLCOVGEN) $(srcdir)/include/verilated_cov_key.h
|
||||
vlcovgen.d: $(VLCOVGEN) $(srcdir)/../include/verilated_cov_key.h
|
||||
$(PERL) $(VLCOVGEN) --srcdir $(srcdir)
|
||||
touch $@
|
||||
|
||||
|
||||
+4
-4
@@ -205,8 +205,8 @@ private:
|
||||
// Note: if this ends with an 'else', then we don't need to validate that one of the
|
||||
// predicates evaluates to true.
|
||||
AstNode* ohot = ((allow_none || hasDefaultElse)
|
||||
? (new AstOneHot0(nodep->fileline(), propp))->castNode()
|
||||
: (new AstOneHot (nodep->fileline(), propp))->castNode());
|
||||
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
|
||||
: static_cast<AstNode*>(new AstOneHot (nodep->fileline(), propp)));
|
||||
AstIf* checkifp = new AstIf (nodep->fileline(),
|
||||
new AstLogNot (nodep->fileline(), ohot),
|
||||
newFireAssert(nodep, "'unique if' statement violated"),
|
||||
@@ -254,8 +254,8 @@ private:
|
||||
}
|
||||
bool allow_none = has_default || nodep->unique0Pragma();
|
||||
AstNode* ohot = (allow_none
|
||||
? (new AstOneHot0(nodep->fileline(), propp))->castNode()
|
||||
: (new AstOneHot (nodep->fileline(), propp))->castNode());
|
||||
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
|
||||
: static_cast<AstNode*>(new AstOneHot (nodep->fileline(), propp)));
|
||||
AstIf* ifp = new AstIf (nodep->fileline(),
|
||||
new AstLogNot (nodep->fileline(), ohot),
|
||||
newFireAssert(nodep, "synthesis parallel_case, but multiple matches found"),
|
||||
|
||||
+2
-2
@@ -816,7 +816,7 @@ void AstNode::iterateAndNextConst(AstNVisitor& v, AstNUser* vup) {
|
||||
}
|
||||
}
|
||||
|
||||
AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
|
||||
AstNode* AstNode::iterateSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
|
||||
// Some visitors perform tree edits (such as V3Const), and may even
|
||||
// replace/delete the exact nodep that the visitor is called with. If
|
||||
// this happens, the parent will lose the handle to the node that was
|
||||
@@ -858,7 +858,7 @@ void AstNode::cloneRelinkTree() {
|
||||
// private: Cleanup clone() operation on whole tree. Publicly call cloneTree() instead.
|
||||
for (AstNode* nodep=this; nodep; nodep=nodep->m_nextp) {
|
||||
if (m_dtypep && m_dtypep->clonep()) {
|
||||
m_dtypep = m_dtypep->clonep()->castNodeDType();
|
||||
m_dtypep = m_dtypep->clonep();
|
||||
}
|
||||
nodep->cloneRelink();
|
||||
if (nodep->m_op1p) nodep->m_op1p->cloneRelinkTree();
|
||||
|
||||
+34
-34
@@ -1272,10 +1272,9 @@ public:
|
||||
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next
|
||||
void iterateChildrenBackwards(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next
|
||||
void iterateChildrenConst(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next
|
||||
AstNode* acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup=NULL); // Return edited nodep; see comments in V3Ast.cpp
|
||||
AstNode* iterateSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup=NULL); // Return edited nodep; see comments in V3Ast.cpp
|
||||
|
||||
// CONVERSION
|
||||
AstNode* castNode() { return this; }
|
||||
#include "V3Ast__gen_interface.h" // From ./astgen
|
||||
// Things like:
|
||||
// AstAlways* castAlways();
|
||||
@@ -1290,7 +1289,8 @@ inline void AstNRelinker::relink(AstNode* newp) { newp->AstNode::relink(this); }
|
||||
|
||||
#define ASTNODE_BASE_FUNCS(name) \
|
||||
virtual ~Ast ##name() {} \
|
||||
Ast ##name * cloneTree(bool cloneNext) { return AstNode::cloneTree(cloneNext)->cast ##name(); }
|
||||
Ast ##name * cloneTree(bool cloneNext) { return static_cast<Ast ##name *>(AstNode::cloneTree(cloneNext)); } \
|
||||
Ast ##name * clonep() const { return static_cast<Ast ##name *>(AstNode::clonep()); }
|
||||
|
||||
class AstNodeMath : public AstNode {
|
||||
// Math -- anything that's part of an expression tree
|
||||
@@ -1329,7 +1329,7 @@ public:
|
||||
dtypeFrom(lhsp);
|
||||
setOp1p(lhsp); }
|
||||
ASTNODE_BASE_FUNCS(NodeUniop)
|
||||
AstNode* lhsp() const { return op1p()->castNode(); }
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
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
|
||||
@@ -1352,8 +1352,8 @@ public:
|
||||
ASTNODE_BASE_FUNCS(NodeBiop)
|
||||
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp)=0; // Clone single node, just get same type back.
|
||||
// ACCESSORS
|
||||
AstNode* lhsp() const { return op1p()->castNode(); }
|
||||
AstNode* rhsp() const { return op2p()->castNode(); }
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
AstNode* rhsp() const { return op2p(); }
|
||||
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
|
||||
void rhsp(AstNode* nodep) { return setOp2p(nodep); }
|
||||
// METHODS
|
||||
@@ -1377,9 +1377,9 @@ public:
|
||||
: AstNodeMath(fl) {
|
||||
setOp1p(lhs); setOp2p(rhs); setOp3p(ths); }
|
||||
ASTNODE_BASE_FUNCS(NodeTriop)
|
||||
AstNode* lhsp() const { return op1p()->castNode(); }
|
||||
AstNode* rhsp() const { return op2p()->castNode(); }
|
||||
AstNode* thsp() const { return op3p()->castNode(); }
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
AstNode* rhsp() const { return op2p(); }
|
||||
AstNode* thsp() const { return op3p(); }
|
||||
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
|
||||
void rhsp(AstNode* nodep) { return setOp2p(nodep); }
|
||||
void thsp(AstNode* nodep) { return setOp3p(nodep); }
|
||||
@@ -1421,9 +1421,9 @@ public:
|
||||
ASTNODE_BASE_FUNCS(NodeCond)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, const V3Number& ths) {
|
||||
if (lhs.isNeqZero()) out.opAssign(rhs); else out.opAssign(ths); }
|
||||
AstNode* condp() const { return op1p()->castNode(); } // op1 = Condition
|
||||
AstNode* expr1p() const { return op2p()->castNode(); } // op2 = If true...
|
||||
AstNode* expr2p() const { return op3p()->castNode(); } // op3 = If false...
|
||||
AstNode* condp() const { return op1p(); } // op1 = Condition
|
||||
AstNode* expr1p() const { return op2p(); } // op2 = If true...
|
||||
AstNode* expr2p() const { return op3p(); } // op3 = If false...
|
||||
virtual string emitVerilog() { return "%k(%l %f? %r %k: %t)"; }
|
||||
virtual string emitC() { return "VL_COND_%nq%lq%rq%tq(%nw,%lw,%rw,%tw, %P, %li, %ri, %ti)"; }
|
||||
virtual bool cleanOut() { return false; } // clean if e1 & e2 clean
|
||||
@@ -1441,10 +1441,10 @@ public:
|
||||
: AstNode(fl) {
|
||||
setOp1p(lhs); setOp2p(rhs); setNOp3p(ths); }
|
||||
ASTNODE_BASE_FUNCS(NodePreSel)
|
||||
AstNode* lhsp() const { return op1p()->castNode(); }
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
AstNode* fromp() const { return lhsp(); }
|
||||
AstNode* rhsp() const { return op2p()->castNode(); }
|
||||
AstNode* thsp() const { return op3p()->castNode(); }
|
||||
AstNode* rhsp() const { return op2p(); }
|
||||
AstNode* thsp() const { return op3p(); }
|
||||
AstAttrOf* attrp() const { return op4p()->castAttrOf(); }
|
||||
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
|
||||
void rhsp(AstNode* nodep) { return setOp2p(nodep); }
|
||||
@@ -1476,8 +1476,8 @@ public:
|
||||
ASTNODE_BASE_FUNCS(NodeAssign)
|
||||
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp)=0; // Clone single node, just get same type back.
|
||||
// So iteration hits the RHS which is "earlier" in execution order, it's op1, not op2
|
||||
AstNode* rhsp() const { return op1p()->castNode(); } // op1 = Assign from
|
||||
AstNode* lhsp() const { return op2p()->castNode(); } // op2 = Assign to
|
||||
AstNode* rhsp() const { return op1p(); } // op1 = Assign from
|
||||
AstNode* lhsp() const { return op2p(); } // op2 = Assign to
|
||||
void rhsp(AstNode* np) { setOp1p(np); }
|
||||
void lhsp(AstNode* np) { setOp2p(np); }
|
||||
virtual bool hasDType() const { return true; }
|
||||
@@ -1496,10 +1496,10 @@ public:
|
||||
addNOp1p(initsp); setOp2p(condp); addNOp3p(incsp); addNOp4p(bodysp);
|
||||
}
|
||||
ASTNODE_BASE_FUNCS(NodeFor)
|
||||
AstNode* initsp() const { return op1p()->castNode(); } // op1= initial statements
|
||||
AstNode* condp() const { return op2p()->castNode(); } // op2= condition to continue
|
||||
AstNode* incsp() const { return op3p()->castNode(); } // op3= increment statements
|
||||
AstNode* bodysp() const { return op4p()->castNode(); } // op4= body of loop
|
||||
AstNode* initsp() const { return op1p(); } // op1= initial statements
|
||||
AstNode* condp() const { return op2p(); } // op2= condition to continue
|
||||
AstNode* incsp() const { return op3p(); } // op3= increment statements
|
||||
AstNode* bodysp() const { return op4p(); } // op4= body of loop
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual int instrCount() const { return instrCountBranch(); }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
@@ -1538,9 +1538,9 @@ public:
|
||||
}
|
||||
ASTNODE_BASE_FUNCS(NodeCase)
|
||||
virtual int instrCount() const { return instrCountBranch(); }
|
||||
AstNode* exprp() const { return op1p()->castNode(); } // op1 = case condition <expression>
|
||||
AstNode* exprp() const { return op1p(); } // op1 = case condition <expression>
|
||||
AstCaseItem* itemsp() const { return op2p()->castCaseItem(); } // op2 = list of case expressions
|
||||
AstNode* notParallelp() const { return op3p()->castNode(); } // op3 = assertion code for non-full case's
|
||||
AstNode* notParallelp() const { return op3p(); } // op3 = assertion code for non-full case's
|
||||
void addItemsp(AstNode* nodep) { addOp2p(nodep); }
|
||||
void addNotParallelp(AstNode* nodep) { setOp3p(nodep); }
|
||||
};
|
||||
@@ -1733,7 +1733,7 @@ public:
|
||||
virtual const char* broken() const { BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|
||||
|| (!m_refDTypep && childDTypep()))); return NULL; }
|
||||
virtual void cloneRelink() { if (m_refDTypep && m_refDTypep->clonep()) {
|
||||
m_refDTypep = m_refDTypep->clonep()->castNodeDType();
|
||||
m_refDTypep = m_refDTypep->clonep();
|
||||
}}
|
||||
virtual bool same(AstNode* samep) const {
|
||||
AstNodeArrayDType* sp = samep->castNodeArrayDType();
|
||||
@@ -1769,9 +1769,9 @@ public:
|
||||
AstNodeSel(FileLine* fl, AstNode* fromp, AstNode* bitp)
|
||||
:AstNodeBiop(fl, fromp, bitp) {}
|
||||
ASTNODE_BASE_FUNCS(NodeSel)
|
||||
AstNode* fromp() const { return op1p()->castNode(); } // op1 = Extracting what (NULL=TBD during parsing)
|
||||
AstNode* fromp() const { return op1p(); } // op1 = Extracting what (NULL=TBD during parsing)
|
||||
void fromp(AstNode* nodep) { setOp1p(nodep); }
|
||||
AstNode* bitp() const { return op2p()->castNode(); } // op2 = Msb selection expression
|
||||
AstNode* bitp() const { return op2p(); } // op2 = Msb selection expression
|
||||
void bitp(AstNode* nodep) { setOp2p(nodep); }
|
||||
int bitConst() const;
|
||||
virtual bool hasDType() const { return true; }
|
||||
@@ -1823,11 +1823,11 @@ public:
|
||||
string cname() const { return m_cname; }
|
||||
void cname(const string& cname) { m_cname = cname; }
|
||||
// op1 = Output variable (functions only, NULL for tasks)
|
||||
AstNode* fvarp() const { return op1p()->castNode(); }
|
||||
AstNode* fvarp() const { return op1p(); }
|
||||
void addFvarp(AstNode* nodep) { addNOp1p(nodep); }
|
||||
bool isFunction() const { return fvarp()!=NULL; }
|
||||
// op3 = Statements/Ports/Vars
|
||||
AstNode* stmtsp() const { return op3p()->castNode(); } // op3 = List of statements
|
||||
AstNode* stmtsp() const { return op3p(); } // op3 = List of statements
|
||||
void addStmtsp(AstNode* nodep) { addNOp3p(nodep); }
|
||||
// op4 = scope name
|
||||
AstScopeName* scopeNamep() const { return op4p()->castScopeName(); }
|
||||
@@ -1872,7 +1872,7 @@ public:
|
||||
ASTNODE_BASE_FUNCS(NodeFTaskRef)
|
||||
virtual const char* broken() const { BROKEN_RTN(m_taskp && !m_taskp->brokeExists()); return NULL; }
|
||||
virtual void cloneRelink() { if (m_taskp && m_taskp->clonep()) {
|
||||
m_taskp = m_taskp->clonep()->castNodeFTask();
|
||||
m_taskp = m_taskp->clonep();
|
||||
}}
|
||||
virtual void dump(ostream& str=cout);
|
||||
virtual string name() const { return m_name; } // * = Var name
|
||||
@@ -1890,7 +1890,7 @@ public:
|
||||
// op1 = namep
|
||||
AstNode* namep() const { return op1p(); }
|
||||
// op2 = Pin interconnection list
|
||||
AstNode* pinsp() const { return op2p()->castNode(); }
|
||||
AstNode* pinsp() const { return op2p(); }
|
||||
void addPinsp(AstNode* nodep) { addOp2p(nodep); }
|
||||
// op3 = scope tracking
|
||||
AstScopeName* scopeNamep() const { return op3p()->castScopeName(); }
|
||||
@@ -1922,7 +1922,7 @@ public:
|
||||
virtual void dump(ostream& str);
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
virtual string name() const { return m_name; }
|
||||
AstNode* stmtsp() const { return op2p()->castNode(); } // op2 = List of statements
|
||||
AstNode* stmtsp() const { return op2p(); } // op2 = List of statements
|
||||
AstActive* activesp() const { return op3p()->castActive(); } // op3 = List of i/sblocks
|
||||
// METHODS
|
||||
void addInlinesp(AstNode* nodep) { addOp1p(nodep); }
|
||||
@@ -1984,8 +1984,8 @@ inline int AstNodeArrayDType::elementsConst() const { return rangep()->elementsC
|
||||
inline VNumRange AstNodeArrayDType::declRange() const { return VNumRange(msb(), lsb(), rangep()->littleEndian()); }
|
||||
|
||||
inline void AstIfaceRefDType::cloneRelink() {
|
||||
if (m_cellp && m_cellp->clonep()) m_cellp = m_cellp->clonep()->castCell();
|
||||
if (m_ifacep && m_ifacep->clonep()) m_ifacep = m_ifacep->clonep()->castIface();
|
||||
if (m_modportp && m_modportp->clonep()) m_modportp = m_modportp->clonep()->castModport(); }
|
||||
if (m_cellp && m_cellp->clonep()) m_cellp = m_cellp->clonep();
|
||||
if (m_ifacep && m_ifacep->clonep()) m_ifacep = m_ifacep->clonep();
|
||||
if (m_modportp && m_modportp->clonep()) m_modportp = m_modportp->clonep(); }
|
||||
|
||||
#endif // Guard
|
||||
|
||||
+4
-4
@@ -53,7 +53,7 @@ const char* AstNodeVarRef::broken() const {
|
||||
}
|
||||
|
||||
void AstNodeVarRef::cloneRelink() {
|
||||
if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep()->castVar(); }
|
||||
if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep(); }
|
||||
}
|
||||
|
||||
int AstNodeSel::bitConst() const {
|
||||
@@ -495,9 +495,9 @@ const char* AstScope::broken() const {
|
||||
}
|
||||
|
||||
void AstScope::cloneRelink() {
|
||||
if (m_aboveScopep && m_aboveScopep->clonep()) m_aboveScopep->clonep()->castScope();
|
||||
if (m_aboveCellp && m_aboveCellp->clonep()) m_aboveCellp->clonep()->castCell();
|
||||
if (m_modp && ((AstNode*)m_modp)->clonep()) ((AstNode*)m_modp)->clonep()->castNodeModule();
|
||||
if (m_aboveScopep && m_aboveScopep->clonep()) m_aboveScopep->clonep();
|
||||
if (m_aboveCellp && m_aboveCellp->clonep()) m_aboveCellp->clonep();
|
||||
if (m_modp && ((AstNode*)m_modp)->clonep()) ((AstNode*)m_modp)->clonep();
|
||||
}
|
||||
|
||||
string AstScope::nameDotless() const {
|
||||
|
||||
+345
-344
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Generate AstCReset nodes.
|
||||
// DESCRIPTION: Verilator: Generate C language constructors and AstCReset nodes.
|
||||
//
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
@@ -17,9 +17,12 @@
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3VarReset's Transformations:
|
||||
// Iterates over all modules and creates a _ctor_var_reset AstCFunc
|
||||
// V3CCtors's Transformations:
|
||||
// Iterates over all modules and
|
||||
// for all AstVar, create a creates a AstCReset node in an _ctor_var_reset AstCFunc.
|
||||
// for all AstCoverDecl, move the declaration into a _configure_coverage AstCFunc.
|
||||
// For each variable that needs reset, add a AstCReset node.
|
||||
//
|
||||
// This transformation honors outputSplitCFuncs.
|
||||
//*************************************************************************
|
||||
#include "config_build.h"
|
||||
@@ -33,62 +36,82 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "V3Global.h"
|
||||
#include "V3VarResets.h"
|
||||
#include "V3EmitCBase.h"
|
||||
#include "V3CCtors.h"
|
||||
|
||||
class V3VarReset {
|
||||
class V3CCtorsVisitor {
|
||||
private:
|
||||
string m_basename;
|
||||
string m_argsp;
|
||||
string m_callargsp;
|
||||
AstNodeModule* m_modp; // Current module
|
||||
AstCFunc* m_tlFuncp; // Top level function being built
|
||||
AstCFunc* m_funcp; // Current function
|
||||
int m_numStmts; // Number of statements output
|
||||
int m_funcNum; // Function number being built
|
||||
|
||||
void initializeVar(AstVar* nodep) {
|
||||
public:
|
||||
void add(AstNode* nodep) {
|
||||
if (v3Global.opt.outputSplitCFuncs()
|
||||
&& v3Global.opt.outputSplitCFuncs() < m_numStmts) {
|
||||
m_funcp = NULL;
|
||||
}
|
||||
if (!m_funcp) {
|
||||
m_funcp = new AstCFunc(m_modp->fileline(), "_ctor_var_reset_" + cvtToStr(++m_funcNum), NULL, "void");
|
||||
m_funcp = new AstCFunc(m_modp->fileline(), m_basename + "_" + cvtToStr(++m_funcNum), NULL, "void");
|
||||
m_funcp->isStatic(false);
|
||||
m_funcp->declPrivate(true);
|
||||
m_funcp->slow(true);
|
||||
m_funcp->argTypes(m_argsp);
|
||||
m_modp->addStmtp(m_funcp);
|
||||
|
||||
// Add a top call to it
|
||||
AstCCall* callp = new AstCCall(m_modp->fileline(), m_funcp);
|
||||
callp->argTypes(m_callargsp);
|
||||
|
||||
m_tlFuncp->addStmtsp(callp);
|
||||
m_numStmts = 0;
|
||||
}
|
||||
m_funcp->addStmtsp(new AstCReset(nodep->fileline(), new AstVarRef(nodep->fileline(), nodep, true)));
|
||||
m_funcp->addStmtsp(nodep);
|
||||
m_numStmts += 1;
|
||||
}
|
||||
|
||||
public:
|
||||
V3VarReset(AstNodeModule* nodep) {
|
||||
V3CCtorsVisitor(AstNodeModule* nodep, string basename, string argsp="", string callargsp="") {
|
||||
m_basename = basename;
|
||||
m_argsp = argsp;
|
||||
m_callargsp = callargsp;
|
||||
m_modp = nodep;
|
||||
m_numStmts = 0;
|
||||
m_funcNum = 0;
|
||||
m_tlFuncp = new AstCFunc(nodep->fileline(), "_ctor_var_reset", NULL, "void");
|
||||
m_tlFuncp = new AstCFunc(nodep->fileline(), basename, NULL, "void");
|
||||
m_tlFuncp->declPrivate(true);
|
||||
m_tlFuncp->isStatic(false);
|
||||
m_tlFuncp->slow(true);
|
||||
m_tlFuncp->argTypes(m_argsp);
|
||||
m_funcp = m_tlFuncp;
|
||||
m_modp->addStmtp(m_tlFuncp);
|
||||
for (AstNode* np = m_modp->stmtsp(); np; np = np->nextp()) {
|
||||
AstVar* varp = np->castVar();
|
||||
if (varp) initializeVar(varp);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
void V3VarResets::emitResets() {
|
||||
void V3CCtors::cctorsAll() {
|
||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) {
|
||||
// Process each module in turn
|
||||
V3VarReset v(nodep);
|
||||
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=modp->nextp()->castNodeModule()) {
|
||||
// Process each module in turn
|
||||
V3CCtorsVisitor var_reset (modp, "_ctor_var_reset");
|
||||
V3CCtorsVisitor configure_coverage (modp, "_configure_coverage",
|
||||
EmitCBaseVisitor::symClassVar()+ ", bool first", "vlSymsp, first");
|
||||
|
||||
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
|
||||
AstVar* varp = np->castVar();
|
||||
if (varp) var_reset.add(new AstCReset(varp->fileline(), new AstVarRef(varp->fileline(), varp, true)));
|
||||
AstCoverDecl* coverp = np->castCoverDecl();
|
||||
if (coverp) {
|
||||
AstNode* backp = coverp->backp();
|
||||
coverp->unlinkFrBack();
|
||||
configure_coverage.add(coverp);
|
||||
np = backp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit C++ code for module tree
|
||||
// DESCRIPTION: Verilator: Emit CFunc's for class construction and configuration
|
||||
//
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
@@ -18,8 +18,8 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#ifndef _V3VARRESETS_H_
|
||||
#define _V3VARRESETS_H_ 1
|
||||
#ifndef _V3CCTORS_H_
|
||||
#define _V3CCTORS_H_ 1
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include "V3Error.h"
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
//============================================================================
|
||||
|
||||
class V3VarResets {
|
||||
class V3CCtors {
|
||||
public:
|
||||
static void emitResets();
|
||||
static void cctorsAll();
|
||||
};
|
||||
|
||||
|
||||
+3
-3
@@ -808,8 +808,8 @@ private:
|
||||
// like a AstExtend{$rhsp}, but we need to set the width correctly from base node
|
||||
arg0p->unlinkFrBack();
|
||||
AstNode* newp = (nodep->castExtendS()
|
||||
? (new AstExtendS(nodep->fileline(), arg0p))->castNode()
|
||||
: (new AstExtend (nodep->fileline(), arg0p))->castNode());
|
||||
? static_cast<AstNode*>(new AstExtendS(nodep->fileline(), arg0p))
|
||||
: static_cast<AstNode*>(new AstExtend (nodep->fileline(), arg0p)));
|
||||
newp->dtypeFrom(nodep);
|
||||
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
@@ -2329,7 +2329,7 @@ public:
|
||||
virtual ~ConstVisitor() {}
|
||||
AstNode* mainAcceptEdit(AstNode* nodep) {
|
||||
// Operate starting at a random place
|
||||
return nodep->acceptSubtreeReturnEdits(*this);
|
||||
return nodep->iterateSubtreeReturnEdits(*this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+8
-16
@@ -1501,7 +1501,7 @@ void EmitCImp::emitCtorImp(AstNodeModule* modp) {
|
||||
}
|
||||
putsDecoration("// Reset structure values\n");
|
||||
puts("_ctor_var_reset();\n");
|
||||
emitTextSection(AstType::atSCCTOR);
|
||||
emitTextSection(AstType::atScCtor);
|
||||
if (optSystemPerl()) puts("SP_AUTO_CTOR;\n");
|
||||
puts("}\n");
|
||||
}
|
||||
@@ -1510,16 +1510,8 @@ void EmitCImp::emitConfigureImp(AstNodeModule* modp) {
|
||||
puts("\nvoid "+modClassName(modp)+"::__Vconfigure("+symClassName()+"* vlSymsp, bool first) {\n");
|
||||
puts( "if (0 && first) {} // Prevent unused\n");
|
||||
puts( "this->__VlSymsp = vlSymsp;\n"); // First, as later stuff needs it.
|
||||
bool first=true;
|
||||
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (nodep->castCoverDecl()) {
|
||||
if (first) {
|
||||
first = false;
|
||||
putsDecoration("// Coverage Declarations\n");
|
||||
}
|
||||
nodep->accept(*this);
|
||||
splitSizeInc(nodep);
|
||||
}
|
||||
if (v3Global.opt.coverage() ) {
|
||||
puts("this->_configure_coverage(vlSymsp, first);\n");
|
||||
}
|
||||
puts("}\n");
|
||||
splitSizeInc(10);
|
||||
@@ -1553,7 +1545,7 @@ void EmitCImp::emitCoverageImp(AstNodeModule* modp) {
|
||||
void EmitCImp::emitDestructorImp(AstNodeModule* modp) {
|
||||
puts("\n");
|
||||
puts(modClassName(modp)+"::~"+modClassName(modp)+"() {\n");
|
||||
emitTextSection(AstType::atSCDTOR);
|
||||
emitTextSection(AstType::atScDtor);
|
||||
if (modp->isTop()) puts("delete __VlSymsp; __VlSymsp=NULL;\n");
|
||||
puts("}\n");
|
||||
splitSizeInc(10);
|
||||
@@ -1872,7 +1864,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
|
||||
}
|
||||
|
||||
puts("\n//----------\n\n");
|
||||
emitTextSection(AstType::atSCHDR);
|
||||
emitTextSection(AstType::atScHdr);
|
||||
|
||||
if (optSystemC() && modp->isTop()) {
|
||||
puts("SC_MODULE("+modClassName(modp)+") {\n");
|
||||
@@ -1989,7 +1981,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
|
||||
|
||||
puts("\n// USER METHODS\n");
|
||||
if (optSystemPerl()) puts("/*AUTOMETHODS*/\n");
|
||||
emitTextSection(AstType::atSCINT);
|
||||
emitTextSection(AstType::atScInt);
|
||||
|
||||
puts("\n// API METHODS\n");
|
||||
if (modp->isTop()) {
|
||||
@@ -2067,7 +2059,7 @@ void EmitCImp::emitImp(AstNodeModule* modp) {
|
||||
puts("SP_MODULE_CONTINUED("+modClassName(modp)+");\n");
|
||||
}
|
||||
|
||||
emitTextSection(AstType::atSCIMPHDR);
|
||||
emitTextSection(AstType::atScImpHdr);
|
||||
|
||||
if (m_slow && splitFilenum()==0) {
|
||||
puts("\n//--------------------\n");
|
||||
@@ -2076,7 +2068,7 @@ void EmitCImp::emitImp(AstNodeModule* modp) {
|
||||
}
|
||||
|
||||
if (m_fast && splitFilenum()==0) {
|
||||
emitTextSection(AstType::atSCIMP);
|
||||
emitTextSection(AstType::atScImp);
|
||||
emitStaticDecl(modp);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -509,7 +509,7 @@ private:
|
||||
// need an alias to trace correctly. If tracing is disabled, we'll
|
||||
// delete it in later optimizations.
|
||||
AstVar* pinOldVarp = pinp->modVarp();
|
||||
AstVar* pinNewVarp = pinOldVarp->clonep()->castVar();
|
||||
AstVar* pinNewVarp = pinOldVarp->clonep();
|
||||
|
||||
AstNode* connectRefp = pinp->exprp();
|
||||
if (!connectRefp->castConst() && !connectRefp->castVarRef()) {
|
||||
|
||||
+2
-2
@@ -390,8 +390,8 @@ private:
|
||||
static AstNode* extendOrSel(FileLine* fl, AstNode* rhsp, AstNode* cmpWidthp) {
|
||||
if (cmpWidthp->width() > rhsp->width()) {
|
||||
rhsp = (rhsp->isSigned()
|
||||
? (new AstExtendS(fl, rhsp))->castNode()
|
||||
: (new AstExtend (fl, rhsp))->castNode());
|
||||
? static_cast<AstNode*>(new AstExtendS(fl, rhsp))
|
||||
: static_cast<AstNode*>(new AstExtend (fl, rhsp)));
|
||||
rhsp->dtypeFrom(cmpWidthp); // Need proper widthMin, which may differ from AstSel created above
|
||||
} else if (cmpWidthp->width() < rhsp->width()) {
|
||||
rhsp = new AstSel (fl, rhsp, 0, cmpWidthp->width());
|
||||
|
||||
+13
-1
@@ -391,6 +391,9 @@ public:
|
||||
} else {
|
||||
ifacerefp->v3fatalSrc("Unlinked interface");
|
||||
}
|
||||
} else if (ifacerefp->ifaceViaCellp()->dead()) {
|
||||
ifacerefp->v3error("Parent cell's interface is not found: "<<AstNode::prettyName(ifacerefp->ifaceName()));
|
||||
continue;
|
||||
}
|
||||
VSymEnt* ifaceSymp = getNodeSym(ifacerefp->ifaceViaCellp());
|
||||
VSymEnt* ifOrPortSymp = ifaceSymp;
|
||||
@@ -487,7 +490,7 @@ public:
|
||||
}
|
||||
}
|
||||
UINFO(8," id "<<ident<<" alt "<<altIdent<<" left "<<leftname<<" at se"<<lookupSymp<<endl);
|
||||
// Spec says; Look at exiting module (cellnames then modname),
|
||||
// Spec says; Look at existing module (cellnames then modname),
|
||||
// then look up (inst name or modname)
|
||||
if (firstId) {
|
||||
// Check this module - subcellnames
|
||||
@@ -501,18 +504,26 @@ public:
|
||||
|| (inlinep && inlinep->origModName() == ident)) {}
|
||||
// Move up and check cellname + modname
|
||||
else {
|
||||
bool crossedCell = false; // Crossed a cell boundary
|
||||
while (lookupSymp) {
|
||||
lookupSymp = lookupSymp->parentp();
|
||||
cellp = lookupSymp ? lookupSymp->nodep()->castCell() : NULL; // Replicated above
|
||||
inlinep = lookupSymp ? lookupSymp->nodep()->castCellInline() : NULL; // Replicated above
|
||||
if (lookupSymp) {
|
||||
UINFO(9,"\t\tUp to "<<lookupSymp<<endl);
|
||||
if (cellp || inlinep) {
|
||||
crossedCell = true;
|
||||
}
|
||||
if ((cellp && cellp->modp()->origName() == ident)
|
||||
|| (inlinep && inlinep->origModName() == ident)) {
|
||||
break;
|
||||
}
|
||||
else if (VSymEnt* findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) {
|
||||
lookupSymp = findSymp;
|
||||
if (crossedCell && lookupSymp->nodep()->castVar()) {
|
||||
UINFO(9,"\t\tNot found but matches var name in parent "<<lookupSymp<<endl);
|
||||
return NULL; // Not found (but happens to be var name in parent)
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else break;
|
||||
@@ -740,6 +751,7 @@ class LinkDotFindVisitor : public AstNVisitor {
|
||||
m_scope = m_scope+"."+nodep->name();
|
||||
m_curSymp = m_modSymp = m_statep->insertCell(aboveSymp, m_modSymp, nodep, m_scope);
|
||||
m_beginp = NULL;
|
||||
// We don't report NotFoundModule, as may be a unused module in a generate
|
||||
if (nodep->modp()) nodep->modp()->accept(*this);
|
||||
}
|
||||
m_scope = oldscope;
|
||||
|
||||
+2
-2
@@ -320,7 +320,7 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstConcat* nodep, AstNUser* wp) {
|
||||
virtual void visit(AstConcat* nodep, AstNUser*) {
|
||||
if (m_inAss) {
|
||||
nodep->lhsp()->iterateAndNext(*this);
|
||||
int lw = m_childClkWidth;
|
||||
@@ -329,7 +329,7 @@ private:
|
||||
m_childClkWidth = lw + rw; // Pass up
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeSel* nodep, AstNUser* wp) {
|
||||
virtual void visit(AstNodeSel* nodep, AstNUser*) {
|
||||
if (m_inAss) {
|
||||
nodep->iterateChildren(*this);
|
||||
// Pass up result width
|
||||
|
||||
+7
-3
@@ -128,6 +128,10 @@ private:
|
||||
varp->user4(usedLetter[static_cast<int>(ch)]*256 + ch);
|
||||
usedLetter[static_cast<int>(ch)]++;
|
||||
}
|
||||
} else if (AstParamTypeDType* typep = stmtp->castParamTypeDType()) {
|
||||
char ch = 'T';
|
||||
typep->user4(usedLetter[static_cast<int>(ch)]*256 + ch);
|
||||
usedLetter[static_cast<int>(ch)]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,14 +176,14 @@ private:
|
||||
if (AstVar* varp = stmtp->castVar()) {
|
||||
if (varp->isIO() || varp->isGParam() || varp->isIfaceRef()) {
|
||||
// Cloning saved a pointer to the new node for us, so just follow that link.
|
||||
AstVar* oldvarp = varp->clonep()->castVar();
|
||||
AstVar* oldvarp = varp->clonep();
|
||||
//UINFO(8,"Clone list 0x"<<hex<<(uint32_t)oldvarp<<" -> 0x"<<(uint32_t)varp<<endl);
|
||||
clonemapp->insert(make_pair(oldvarp, varp));
|
||||
}
|
||||
}
|
||||
else if (AstParamTypeDType* ptp = stmtp->castParamTypeDType()) {
|
||||
if (ptp->isGParam()) {
|
||||
AstParamTypeDType* oldptp = ptp->clonep()->castParamTypeDType();
|
||||
AstParamTypeDType* oldptp = ptp->clonep();
|
||||
clonemapp->insert(make_pair(oldptp, ptp));
|
||||
}
|
||||
}
|
||||
@@ -633,7 +637,7 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
||||
for (IfaceRefRefs::iterator it=ifaceRefRefs.begin(); it!=ifaceRefRefs.end(); ++it) {
|
||||
AstIfaceRefDType* portIrefp = it->first;
|
||||
AstIfaceRefDType* pinIrefp = it->second;
|
||||
AstIfaceRefDType* cloneIrefp = portIrefp->clonep()->castIfaceRefDType();
|
||||
AstIfaceRefDType* cloneIrefp = portIrefp->clonep();
|
||||
UINFO(8," IfaceOld "<<portIrefp<<endl);
|
||||
UINFO(8," IfaceTo "<<pinIrefp<<endl);
|
||||
if (!cloneIrefp) portIrefp->v3fatalSrc("parameter clone didn't hit AstIfaceRefDType");
|
||||
|
||||
+1
-1
@@ -210,7 +210,7 @@ drop [\032]
|
||||
<ARGMODE>[(] { LEXP->m_parenLevel++;
|
||||
// Note paren level 0 means before "(" of starting args
|
||||
// Level 1 means "," between arguments
|
||||
// Level 2+ means one argument's internal ()
|
||||
// Level 2+ means one inside the () of an argument
|
||||
if (LEXP->m_parenLevel>1) {
|
||||
appendDefValue(yytext,yyleng);
|
||||
} else {
|
||||
|
||||
+2
-2
@@ -715,7 +715,7 @@ private:
|
||||
if (!m_params) { badNodeType(nodep); return; }
|
||||
}
|
||||
|
||||
virtual void visit(AstSFormatF *nodep, AstNUser *) {
|
||||
virtual void visit(AstSFormatF *nodep, AstNUser*) {
|
||||
if (jumpingOver(nodep)) return;
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_params) {
|
||||
@@ -759,7 +759,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstDisplay *nodep, AstNUser *) {
|
||||
virtual void visit(AstDisplay *nodep, AstNUser*) {
|
||||
if (jumpingOver(nodep)) return;
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_params) {
|
||||
|
||||
+8
-8
@@ -147,16 +147,16 @@ class SliceCloneVisitor : public AstNVisitor {
|
||||
if (!lhsp) lhsp = clonep;
|
||||
else {
|
||||
switch (nodep->type()) {
|
||||
case AstType::atREDOR:
|
||||
case AstType::atRedOr:
|
||||
lhsp = new AstOr(nodep->fileline(), lhsp, clonep);
|
||||
break;
|
||||
case AstType::atREDAND:
|
||||
case AstType::atRedAnd:
|
||||
lhsp = new AstAnd(nodep->fileline(), lhsp, clonep);
|
||||
break;
|
||||
case AstType::atREDXOR:
|
||||
case AstType::atRedXor:
|
||||
lhsp = new AstXor(nodep->fileline(), lhsp, clonep);
|
||||
break;
|
||||
case AstType::atREDXNOR:
|
||||
case AstType::atRedXnor:
|
||||
lhsp = new AstXnor(nodep->fileline(), lhsp, clonep);
|
||||
break;
|
||||
default:
|
||||
@@ -492,12 +492,12 @@ class SliceVisitor : public AstNVisitor {
|
||||
if (!logp) logp = clonep;
|
||||
else {
|
||||
switch (nodep->type()) {
|
||||
case AstType::atEQ: // FALLTHRU
|
||||
case AstType::atEQCASE:
|
||||
case AstType::atEq: // FALLTHRU
|
||||
case AstType::atEqCase:
|
||||
logp = new AstLogAnd(nodep->fileline(), logp, clonep);
|
||||
break;
|
||||
case AstType::atNEQ: // FALLTHRU
|
||||
case AstType::atNEQCASE:
|
||||
case AstType::atNeq: // FALLTHRU
|
||||
case AstType::atNeqCase:
|
||||
logp = new AstLogOr(nodep->fileline(), logp, clonep);
|
||||
break;
|
||||
default:
|
||||
|
||||
+6
-4
@@ -133,10 +133,12 @@ private:
|
||||
prep->replaceWith(new AstVarRef(fl, varp, true));
|
||||
AstNode* newp = new AstIf(fl, condp,
|
||||
(needDly
|
||||
? ((new AstAssignDly(fl, prep,
|
||||
new AstVarRef(fl, varp, false)))->castNode())
|
||||
: ((new AstAssign (fl, prep,
|
||||
new AstVarRef(fl, varp, false)))->castNode())),
|
||||
? static_cast<AstNode*>
|
||||
(new AstAssignDly(fl, prep,
|
||||
new AstVarRef(fl, varp, false)))
|
||||
: static_cast<AstNode*>
|
||||
(new AstAssign (fl, prep,
|
||||
new AstVarRef(fl, varp, false)))),
|
||||
NULL);
|
||||
if (debug()>=9) newp->dumpTree(cout," _new: ");
|
||||
abovep->addNextStmt(newp,abovep);
|
||||
|
||||
+70
-68
@@ -64,7 +64,7 @@
|
||||
// same value on each nextp().
|
||||
//*************************************************************************
|
||||
// See notes in internal.txt about misuse of iterateAndNext and use of
|
||||
// acceptSubtreeReturnEdits.
|
||||
// iterateSubtreeReturnEdits.
|
||||
//*************************************************************************
|
||||
|
||||
#include "config_build.h"
|
||||
@@ -171,6 +171,8 @@ public:
|
||||
|
||||
//######################################################################
|
||||
|
||||
#define accept in_WidthVisitor_use_AstNode_iterate_instead_of_AstNode_accept
|
||||
|
||||
class WidthVisitor : public AstNVisitor {
|
||||
private:
|
||||
// TYPES
|
||||
@@ -990,7 +992,7 @@ private:
|
||||
AstNode* newp = new AstCastSize(nodep->fileline(), nodep->lhsp()->unlinkFrBack(), constp);
|
||||
nodep->replaceWith(newp);
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
newp->accept(*this,vup);
|
||||
newp->iterate(*this,vup);
|
||||
} else {
|
||||
nodep->v3error("Unsupported: Cast to "<<nodep->dtp()->prettyTypeName());
|
||||
nodep->replaceWith(nodep->lhsp()->unlinkFrBack());
|
||||
@@ -1405,7 +1407,7 @@ private:
|
||||
AstNode* newp = new AstMethodSel(nodep->fileline(), nodep->fromp()->unlinkFrBack(), nodep->name(), NULL);
|
||||
nodep->replaceWith(newp);
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
newp->accept(*this,vup);
|
||||
newp->iterate(*this,vup);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
@@ -1439,9 +1441,9 @@ private:
|
||||
UINFO(5," METHODSEL "<<nodep<<endl);
|
||||
if (debug()>=9) nodep->dumpTree("-mts-in: ");
|
||||
// Should check types the method requires, but at present we don't do much
|
||||
nodep->fromp()->accept(*this,WidthVP(SELF,BOTH).p());
|
||||
nodep->fromp()->iterate(*this,WidthVP(SELF,BOTH).p());
|
||||
for (AstArg* argp = nodep->pinsp()->castArg(); argp; argp = argp->nextp()->castArg()) {
|
||||
if (argp->exprp()) argp->exprp()->accept(*this,WidthVP(SELF,BOTH).p());
|
||||
if (argp->exprp()) argp->exprp()->iterate(*this,WidthVP(SELF,BOTH).p());
|
||||
}
|
||||
// Find the fromp dtype - should be a class
|
||||
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
|
||||
@@ -1636,7 +1638,7 @@ private:
|
||||
// Determine initial values
|
||||
vdtypep = memp;
|
||||
patp->dtypep(memp);
|
||||
patp->accept(*this,WidthVP(memp,BOTH).p()); // See visit(AstPatMember*
|
||||
patp->iterate(*this,WidthVP(memp,BOTH).p()); // See visit(AstPatMember*
|
||||
|
||||
// Convert to concat for now
|
||||
AstNode* valuep = patp->lhssp()->unlinkFrBack();
|
||||
@@ -1691,7 +1693,7 @@ private:
|
||||
// Don't want the RHS an array
|
||||
patp->dtypep(vdtypep);
|
||||
// Determine values - might be another InitArray
|
||||
patp->accept(*this,WidthVP(patp->dtypep(),BOTH).p()); // See visit(AstPatMember*
|
||||
patp->iterate(*this,WidthVP(patp->dtypep(),BOTH).p()); // See visit(AstPatMember*
|
||||
// Convert to InitArray or constify immediately
|
||||
AstNode* valuep = patp->lhssp()->unlinkFrBack();
|
||||
if (valuep->castConst()) {
|
||||
@@ -1759,7 +1761,7 @@ private:
|
||||
// Don't want the RHS an array
|
||||
patp->dtypep(vdtypep);
|
||||
// Determine values - might be another InitArray
|
||||
patp->accept(*this,WidthVP(patp->dtypep(),BOTH).p());
|
||||
patp->iterate(*this,WidthVP(patp->dtypep(),BOTH).p());
|
||||
// Convert to InitArray or constify immediately
|
||||
AstNode* valuep = patp->lhssp()->unlinkFrBack();
|
||||
if (valuep->castConst()) {
|
||||
@@ -2309,7 +2311,7 @@ private:
|
||||
pinp = newp;
|
||||
}
|
||||
// AstPattern requires assignments to pass datatype on PRELIM
|
||||
pinp->accept(*this,WidthVP(portp->dtypep(),PRELIM).p()); VL_DANGLING(pinp);
|
||||
pinp->iterate(*this,WidthVP(portp->dtypep(),PRELIM).p()); VL_DANGLING(pinp);
|
||||
} else if (accept_mode==1) {
|
||||
// Change data types based on above accept completion
|
||||
if (portp->isDouble()) {
|
||||
@@ -2317,7 +2319,7 @@ private:
|
||||
}
|
||||
} else if (accept_mode==2) {
|
||||
// Do PRELIM again, because above accept may have exited early due to node replacement
|
||||
pinp->accept(*this,WidthVP(portp->dtypep(),PRELIM).p());
|
||||
pinp->iterate(*this,WidthVP(portp->dtypep(),PRELIM).p());
|
||||
if ((portp->isOutput() || portp->isInout())
|
||||
&& pinp->width() != portp->width()) {
|
||||
pinp->v3error("Unsupported: Function output argument '"<<portp->prettyName()<<"'"
|
||||
@@ -2328,7 +2330,7 @@ private:
|
||||
// (get an ASSIGN with EXTEND on the lhs instead of rhs)
|
||||
}
|
||||
if (!portp->basicp() || portp->basicp()->isOpaque()) {
|
||||
pinp->accept(*this,WidthVP(portp->dtypep(),FINAL).p());
|
||||
pinp->iterate(*this,WidthVP(portp->dtypep(),FINAL).p());
|
||||
} else {
|
||||
iterateCheckAssign(nodep,"Function Argument",pinp,FINAL,portp->dtypep());
|
||||
}
|
||||
@@ -2809,8 +2811,8 @@ private:
|
||||
default: nodep->v3fatalSrc("bad case");
|
||||
}
|
||||
AstNode* newp = (doSigned
|
||||
? (new AstExtendS(nodep->fileline(), nodep))->castNode()
|
||||
: (new AstExtend (nodep->fileline(), nodep))->castNode());
|
||||
? static_cast<AstNode*>(new AstExtendS(nodep->fileline(), nodep))
|
||||
: static_cast<AstNode*>(new AstExtend (nodep->fileline(), nodep)));
|
||||
linker.relink(newp);
|
||||
nodep=newp;
|
||||
}
|
||||
@@ -2876,7 +2878,7 @@ private:
|
||||
void iterateCheckFileDesc (AstNode* nodep, AstNode* underp, Stage stage) {
|
||||
if (stage != BOTH) nodep->v3fatalSrc("Bad call");
|
||||
// underp may change as a result of replacement
|
||||
underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p());
|
||||
underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p());
|
||||
AstNodeDType* expDTypep = underp->findUInt32DType();
|
||||
underp = iterateCheck(nodep,"file_descriptor",underp,SELF,FINAL,expDTypep,EXTEND_EXP);
|
||||
if (underp) {} // cppcheck
|
||||
@@ -2889,7 +2891,7 @@ private:
|
||||
// otherwise self-determined was correct
|
||||
// underp may change as a result of replacement
|
||||
if (stage & PRELIM) {
|
||||
underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p());
|
||||
underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p());
|
||||
}
|
||||
if (stage & FINAL) {
|
||||
AstNodeDType* expDTypep = nodep->findDoubleDType();
|
||||
@@ -2899,7 +2901,7 @@ private:
|
||||
}
|
||||
void iterateCheckString (AstNode* nodep, const char* side, AstNode* underp, Stage stage) {
|
||||
if (stage & PRELIM) {
|
||||
underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p());
|
||||
underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p());
|
||||
}
|
||||
if (stage & FINAL) {
|
||||
AstNodeDType* expDTypep = nodep->findStringDType();
|
||||
@@ -2914,7 +2916,7 @@ private:
|
||||
if (determ != SELF) nodep->v3fatalSrc("Bad call");
|
||||
if (stage != FINAL && stage != BOTH) nodep->v3fatalSrc("Bad call");
|
||||
// underp may change as a result of replacement
|
||||
if (stage & PRELIM) underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p());
|
||||
if (stage & PRELIM) underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p());
|
||||
underp = checkCvtUS(underp);
|
||||
AstNodeDType* expDTypep = underp->dtypep();
|
||||
underp = iterateCheck(nodep,side,underp,SELF,FINAL,expDTypep,EXTEND_EXP);
|
||||
@@ -2939,7 +2941,7 @@ private:
|
||||
// stage is always BOTH so not passed as argument
|
||||
// underp may change as a result of replacement
|
||||
if (!underp) underp->v3fatalSrc("Node has no type");
|
||||
underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,BOTH).p());
|
||||
underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,BOTH).p());
|
||||
if (!underp || !underp->dtypep()) underp->v3fatalSrc("Node has no type"); // Perhaps forgot to do a prelim visit on it?
|
||||
//
|
||||
// For DOUBLE under a logical op, add implied test against zero, never a warning
|
||||
@@ -2983,18 +2985,18 @@ private:
|
||||
if (stage != FINAL) nodep->v3fatalSrc("Bad state to iterateCheck");
|
||||
if (!underp || !underp->dtypep()) underp->v3fatalSrc("Node has no type"); // Perhaps forgot to do a prelim visit on it?
|
||||
if (expDTypep == underp->dtypep()) { // Perfect
|
||||
underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p());
|
||||
underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p());
|
||||
} else if (expDTypep->isDouble() && underp->isDouble()) { // Also good
|
||||
underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p());
|
||||
underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p());
|
||||
} else if (expDTypep->isDouble() && !underp->isDouble()) {
|
||||
underp = spliceCvtD(underp);
|
||||
underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p());
|
||||
underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p());
|
||||
} else if (!expDTypep->isDouble() && underp->isDouble()) {
|
||||
underp = spliceCvtS(underp, true); // Round RHS
|
||||
underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p());
|
||||
underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p());
|
||||
} else if (expDTypep->isString() && !underp->dtypep()->isString()) {
|
||||
underp = spliceCvtString(underp);
|
||||
underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p());
|
||||
underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p());
|
||||
} else {
|
||||
AstBasicDType* expBasicp = expDTypep->basicp();
|
||||
AstBasicDType* underBasicp = underp->dtypep()->basicp();
|
||||
@@ -3004,7 +3006,7 @@ private:
|
||||
// is e.g. an ADD, the ADD will auto-adjust to the proper data type
|
||||
// or if another operation e.g. ATOI will not.
|
||||
if (determ == SELF) {
|
||||
underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p());
|
||||
underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p());
|
||||
} else if (determ == ASSIGN) {
|
||||
// IEEE: Signedness is solely determined by the RHS (underp), not by the LHS (expDTypep)
|
||||
if (underp->isSigned() != subDTypep->isSigned()
|
||||
@@ -3014,9 +3016,9 @@ private:
|
||||
AstNumeric::fromBool(underp->isSigned()));
|
||||
UINFO(9,"Assignment of opposite-signed RHS to LHS: "<<nodep<<endl);
|
||||
}
|
||||
underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(subDTypep,FINAL).p());
|
||||
underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(subDTypep,FINAL).p());
|
||||
} else {
|
||||
underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(subDTypep,FINAL).p());
|
||||
underp = underp->iterateSubtreeReturnEdits(*this,WidthVP(subDTypep,FINAL).p());
|
||||
}
|
||||
// Note the check uses the expected size, not the child's subDTypep as we want the
|
||||
// child node's width to end up correct for the assignment (etc)
|
||||
@@ -3162,13 +3164,13 @@ private:
|
||||
if (!nodep->dtypep()) nodep->dtypeFrom(nodep->lhsp());
|
||||
// To simplify callers, some node types don't need to change
|
||||
switch (nodep->type()) {
|
||||
case AstType::atEQ: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL;
|
||||
case AstType::atNEQ: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL;
|
||||
case AstType::atEQCASE: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL;
|
||||
case AstType::atNEQCASE: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL;
|
||||
case AstType::atADD: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL;
|
||||
case AstType::atSUB: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL;
|
||||
case AstType::atSHIFTL: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL;
|
||||
case AstType::atEq: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL;
|
||||
case AstType::atNeq: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL;
|
||||
case AstType::atEqCase: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL;
|
||||
case AstType::atNeqCase: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL;
|
||||
case AstType::atAdd: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL;
|
||||
case AstType::atSub: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL;
|
||||
case AstType::atShiftL: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL;
|
||||
default: break;
|
||||
}
|
||||
FileLine* fl = nodep->fileline();
|
||||
@@ -3176,22 +3178,22 @@ private:
|
||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNodeBiop* newp = NULL;
|
||||
switch (nodep->type()) {
|
||||
case AstType::atGT: newp = new AstGtS (fl,lhsp,rhsp); break;
|
||||
case AstType::atGTS: newp = new AstGt (fl,lhsp,rhsp); break;
|
||||
case AstType::atGTE: newp = new AstGteS (fl,lhsp,rhsp); break;
|
||||
case AstType::atGTES: newp = new AstGte (fl,lhsp,rhsp); break;
|
||||
case AstType::atLT: newp = new AstLtS (fl,lhsp,rhsp); break;
|
||||
case AstType::atLTS: newp = new AstLt (fl,lhsp,rhsp); break;
|
||||
case AstType::atLTE: newp = new AstLteS (fl,lhsp,rhsp); break;
|
||||
case AstType::atLTES: newp = new AstLte (fl,lhsp,rhsp); break;
|
||||
case AstType::atDIV: newp = new AstDivS (fl,lhsp,rhsp); break;
|
||||
case AstType::atDIVS: newp = new AstDiv (fl,lhsp,rhsp); break;
|
||||
case AstType::atMODDIV: newp = new AstModDivS (fl,lhsp,rhsp); break;
|
||||
case AstType::atMODDIVS: newp = new AstModDiv (fl,lhsp,rhsp); break;
|
||||
case AstType::atMUL: newp = new AstMulS (fl,lhsp,rhsp); break;
|
||||
case AstType::atMULS: newp = new AstMul (fl,lhsp,rhsp); break;
|
||||
case AstType::atSHIFTR: newp = new AstShiftRS (fl,lhsp,rhsp); break;
|
||||
case AstType::atSHIFTRS: newp = new AstShiftR (fl,lhsp,rhsp); break;
|
||||
case AstType::atGt: newp = new AstGtS (fl,lhsp,rhsp); break;
|
||||
case AstType::atGtS: newp = new AstGt (fl,lhsp,rhsp); break;
|
||||
case AstType::atGte: newp = new AstGteS (fl,lhsp,rhsp); break;
|
||||
case AstType::atGteS: newp = new AstGte (fl,lhsp,rhsp); break;
|
||||
case AstType::atLt: newp = new AstLtS (fl,lhsp,rhsp); break;
|
||||
case AstType::atLtS: newp = new AstLt (fl,lhsp,rhsp); break;
|
||||
case AstType::atLte: newp = new AstLteS (fl,lhsp,rhsp); break;
|
||||
case AstType::atLteS: newp = new AstLte (fl,lhsp,rhsp); break;
|
||||
case AstType::atDiv: newp = new AstDivS (fl,lhsp,rhsp); break;
|
||||
case AstType::atDivS: newp = new AstDiv (fl,lhsp,rhsp); break;
|
||||
case AstType::atModDiv: newp = new AstModDivS (fl,lhsp,rhsp); break;
|
||||
case AstType::atModDivS: newp = new AstModDiv (fl,lhsp,rhsp); break;
|
||||
case AstType::atMul: newp = new AstMulS (fl,lhsp,rhsp); break;
|
||||
case AstType::atMulS: newp = new AstMul (fl,lhsp,rhsp); break;
|
||||
case AstType::atShiftR: newp = new AstShiftRS (fl,lhsp,rhsp); break;
|
||||
case AstType::atShiftRS: newp = new AstShiftR (fl,lhsp,rhsp); break;
|
||||
default:
|
||||
nodep->v3fatalSrc("Node needs sign change, but bad case: "<<nodep<<endl);
|
||||
break;
|
||||
@@ -3214,17 +3216,17 @@ private:
|
||||
AstNodeBiop* newp = NULL;
|
||||
// No width change on output;... // All below have bool or double outputs
|
||||
switch (nodep->type()) {
|
||||
case AstType::atADD: newp = new AstAddD (fl,lhsp,rhsp); break;
|
||||
case AstType::atSUB: newp = new AstSubD (fl,lhsp,rhsp); break;
|
||||
case AstType::atPOW: newp = new AstPowD (fl,lhsp,rhsp); break;
|
||||
case AstType::atEQ: case AstType::atEQCASE: newp = new AstEqD (fl,lhsp,rhsp); break;
|
||||
case AstType::atNEQ: case AstType::atNEQCASE: newp = new AstNeqD (fl,lhsp,rhsp); break;
|
||||
case AstType::atGT: case AstType::atGTS: newp = new AstGtD (fl,lhsp,rhsp); break;
|
||||
case AstType::atGTE: case AstType::atGTES: newp = new AstGteD (fl,lhsp,rhsp); break;
|
||||
case AstType::atLT: case AstType::atLTS: newp = new AstLtD (fl,lhsp,rhsp); break;
|
||||
case AstType::atLTE: case AstType::atLTES: newp = new AstLteD (fl,lhsp,rhsp); break;
|
||||
case AstType::atDIV: case AstType::atDIVS: newp = new AstDivD (fl,lhsp,rhsp); break;
|
||||
case AstType::atMUL: case AstType::atMULS: newp = new AstMulD (fl,lhsp,rhsp); break;
|
||||
case AstType::atAdd: newp = new AstAddD (fl,lhsp,rhsp); break;
|
||||
case AstType::atSub: newp = new AstSubD (fl,lhsp,rhsp); break;
|
||||
case AstType::atPow: newp = new AstPowD (fl,lhsp,rhsp); break;
|
||||
case AstType::atEq: case AstType::atEqCase: newp = new AstEqD (fl,lhsp,rhsp); break;
|
||||
case AstType::atNeq: case AstType::atNeqCase: newp = new AstNeqD (fl,lhsp,rhsp); break;
|
||||
case AstType::atGt: case AstType::atGtS: newp = new AstGtD (fl,lhsp,rhsp); break;
|
||||
case AstType::atGte: case AstType::atGteS: newp = new AstGteD (fl,lhsp,rhsp); break;
|
||||
case AstType::atLt: case AstType::atLtS: newp = new AstLtD (fl,lhsp,rhsp); break;
|
||||
case AstType::atLte: case AstType::atLteS: newp = new AstLteD (fl,lhsp,rhsp); break;
|
||||
case AstType::atDiv: case AstType::atDivS: newp = new AstDivD (fl,lhsp,rhsp); break;
|
||||
case AstType::atMul: case AstType::atMulS: newp = new AstMulD (fl,lhsp,rhsp); break;
|
||||
default:
|
||||
nodep->v3fatalSrc("Node needs conversion to double, but bad case: "<<nodep<<endl);
|
||||
break;
|
||||
@@ -3247,12 +3249,12 @@ private:
|
||||
AstNodeBiop* newp = NULL;
|
||||
// No width change on output;... // All below have bool or double outputs
|
||||
switch (nodep->type()) {
|
||||
case AstType::atEQ: case AstType::atEQCASE: newp = new AstEqN (fl,lhsp,rhsp); break;
|
||||
case AstType::atNEQ: case AstType::atNEQCASE: newp = new AstNeqN (fl,lhsp,rhsp); break;
|
||||
case AstType::atGT: case AstType::atGTS: newp = new AstGtN (fl,lhsp,rhsp); break;
|
||||
case AstType::atGTE: case AstType::atGTES: newp = new AstGteN (fl,lhsp,rhsp); break;
|
||||
case AstType::atLT: case AstType::atLTS: newp = new AstLtN (fl,lhsp,rhsp); break;
|
||||
case AstType::atLTE: case AstType::atLTES: newp = new AstLteN (fl,lhsp,rhsp); break;
|
||||
case AstType::atEq: case AstType::atEqCase: newp = new AstEqN (fl,lhsp,rhsp); break;
|
||||
case AstType::atNeq: case AstType::atNeqCase: newp = new AstNeqN (fl,lhsp,rhsp); break;
|
||||
case AstType::atGt: case AstType::atGtS: newp = new AstGtN (fl,lhsp,rhsp); break;
|
||||
case AstType::atGte: case AstType::atGteS: newp = new AstGteN (fl,lhsp,rhsp); break;
|
||||
case AstType::atLt: case AstType::atLtS: newp = new AstLtN (fl,lhsp,rhsp); break;
|
||||
case AstType::atLte: case AstType::atLteS: newp = new AstLteN (fl,lhsp,rhsp); break;
|
||||
default:
|
||||
nodep->v3fatalSrc("Node needs conversion to string, but bad case: "<<nodep<<endl);
|
||||
break;
|
||||
@@ -3273,7 +3275,7 @@ private:
|
||||
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
|
||||
AstNodeUniop* newp = NULL;
|
||||
switch (nodep->type()) {
|
||||
case AstType::atNEGATE: newp = new AstNegateD (fl,lhsp); break;
|
||||
case AstType::atNegate: newp = new AstNegateD (fl,lhsp); break;
|
||||
default:
|
||||
nodep->v3fatalSrc("Node needs conversion to double, but bad case: "<<nodep<<endl);
|
||||
break;
|
||||
@@ -3547,7 +3549,7 @@ public:
|
||||
m_dtTables = 0;
|
||||
}
|
||||
AstNode* mainAcceptEdit(AstNode* nodep) {
|
||||
return nodep->acceptSubtreeReturnEdits(*this, WidthVP(SELF,BOTH).p());
|
||||
return nodep->iterateSubtreeReturnEdits(*this, WidthVP(SELF,BOTH).p());
|
||||
}
|
||||
virtual ~WidthVisitor() {}
|
||||
};
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ public:
|
||||
WidthRemoveVisitor() {}
|
||||
virtual ~WidthRemoveVisitor() {}
|
||||
AstNode* mainAcceptEdit(AstNode* nodep) {
|
||||
return nodep->acceptSubtreeReturnEdits(*this);
|
||||
return nodep->iterateSubtreeReturnEdits(*this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -462,7 +462,7 @@ public:
|
||||
// CONSTUCTORS
|
||||
WidthSelVisitor() {}
|
||||
AstNode* mainAcceptEdit(AstNode* nodep) {
|
||||
return nodep->acceptSubtreeReturnEdits(*this);
|
||||
return nodep->iterateSubtreeReturnEdits(*this);
|
||||
}
|
||||
virtual ~WidthSelVisitor() {}
|
||||
};
|
||||
|
||||
+2
-2
@@ -39,7 +39,7 @@
|
||||
#include "V3Const.h"
|
||||
#include "V3Coverage.h"
|
||||
#include "V3CoverageJoin.h"
|
||||
#include "V3VarResets.h"
|
||||
#include "V3CCtors.h"
|
||||
#include "V3Dead.h"
|
||||
#include "V3Delayed.h"
|
||||
#include "V3Depth.h"
|
||||
@@ -500,7 +500,7 @@ void process () {
|
||||
V3Error::abortIfErrors();
|
||||
if (!v3Global.opt.lintOnly()
|
||||
&& !v3Global.opt.xmlOnly()) {
|
||||
V3VarResets::emitResets();
|
||||
V3CCtors::cctorsAll();
|
||||
}
|
||||
|
||||
// Output the text
|
||||
|
||||
+2
-3
@@ -253,8 +253,7 @@ sub write_impl {
|
||||
printf $fh "inline Ast%-16s AstNode::cast${type}() { return (dynamic_cast<Ast${type}*>(this)); }\n"
|
||||
,$type."*";
|
||||
} else {
|
||||
my $ucType = uc $type;
|
||||
printf $fh "inline Ast%-16s AstNode::cast${type}() { return (this && this->type() == AstType::at${ucType}) ? static_cast<Ast${type}*>(this) : NULL; }\n"
|
||||
printf $fh "inline Ast%-16s AstNode::cast${type}() { return (this && this->type() == AstType::at${type}) ? static_cast<Ast${type}*>(this) : NULL; }\n"
|
||||
,$type."*";
|
||||
}
|
||||
}
|
||||
@@ -268,7 +267,7 @@ sub write_types {
|
||||
# Add "at" prefix to avoid conflicting with FOPEN and other macros in include files
|
||||
foreach my $type (sort (keys %Classes)) {
|
||||
next if $type =~ /^Node/;
|
||||
print $fh "\tat",uc $type,",\n";
|
||||
print $fh "\tat",$type,",\n";
|
||||
}
|
||||
printf $fh "\t_ENUM_END\n";
|
||||
printf $fh " };\n";
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ my $Opt_Prefix = $ARGV[0] or die "%Error: No prefix specified,";
|
||||
|
||||
foreach my $line (<STDIN>) {
|
||||
# Fix flex 2.6.0 warning
|
||||
$line =~ s/ > YY_CURRENT_BUFFER_LVALUE->yy_buf_size/ > (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size/;
|
||||
$line =~ s/\(\(int\) \(\(yy_n_chars\) \+ number_to_move\) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size\)/((int) ((yy_n_chars) + number_to_move) > (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size)/g;
|
||||
$line =~ s/ number_to_move == YY_MORE_ADJ / (int)number_to_move == (int)YY_MORE_ADJ /;
|
||||
# Fix flex 2.5.4 namespace omission
|
||||
$line =~ s/^class istream;/\#include <iostream>\nusing namespace std;\n/;
|
||||
|
||||
+1
-1
@@ -821,7 +821,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
||||
// Push rest for later parse
|
||||
PARSEP->unputString(yytext+shortlen, yyleng-shortlen);
|
||||
FL; LINECHECKS(yytext,shortlen);
|
||||
// Return is stuff before '
|
||||
// Return is stuff before the tick
|
||||
yytext[shortlen] = '\0';
|
||||
yylval.nump = PARSEP->newNumber(yylval.fl, (char*)yytext);
|
||||
return yaINTNUM;
|
||||
|
||||
+10
-8
@@ -2282,15 +2282,17 @@ statement_item<nodep>: // IEEE: statement_item
|
||||
//
|
||||
// // IEEE: conditional_statement
|
||||
| unique_priorityE yIF '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE
|
||||
{ $$ = new AstIf($2,$4,$6,NULL);
|
||||
if ($1 == uniq_UNIQUE) $$->castIf()->uniquePragma(true);
|
||||
if ($1 == uniq_UNIQUE0) $$->castIf()->unique0Pragma(true);
|
||||
if ($1 == uniq_PRIORITY) $$->castIf()->priorityPragma(true); }
|
||||
{ AstIf* newp = new AstIf($2,$4,$6,NULL);
|
||||
$$ = newp;
|
||||
if ($1 == uniq_UNIQUE) newp->uniquePragma(true);
|
||||
if ($1 == uniq_UNIQUE0) newp->unique0Pragma(true);
|
||||
if ($1 == uniq_PRIORITY) newp->priorityPragma(true); }
|
||||
| unique_priorityE yIF '(' expr ')' stmtBlock yELSE stmtBlock
|
||||
{ $$ = new AstIf($2,$4,$6,$8);
|
||||
if ($1 == uniq_UNIQUE) $$->castIf()->uniquePragma(true);
|
||||
if ($1 == uniq_UNIQUE0) $$->castIf()->unique0Pragma(true);
|
||||
if ($1 == uniq_PRIORITY) $$->castIf()->priorityPragma(true); }
|
||||
{ AstIf* newp = new AstIf($2,$4,$6,$8);
|
||||
$$ = newp;
|
||||
if ($1 == uniq_UNIQUE) newp->uniquePragma(true);
|
||||
if ($1 == uniq_UNIQUE0) newp->unique0Pragma(true);
|
||||
if ($1 == uniq_PRIORITY) newp->priorityPragma(true); }
|
||||
//
|
||||
| finc_or_dec_expression ';' { $$ = $1; }
|
||||
// // IEEE: inc_or_dec_expression
|
||||
|
||||
Executable
+25
@@ -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 2005 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 (
|
||||
verilator_flags2 => ["--lint-only"],
|
||||
verilator_make_gcc => 0,
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
fails => 1,
|
||||
# Used to be %Error: t/t_order_wireloop.v:\d+: Wire inputs its own output, creating circular logic .wire x=x.
|
||||
# However we no longer gate optimize this
|
||||
expect=>
|
||||
q{%Error: t/t_interface_typo_bad.v:\d+: Parent cell's interface is not found: foo_intf
|
||||
%Warning-IMPLICIT: t/t_interface_typo_bad.v:\d+: Signal definition not found, creating implicitly: the_foo
|
||||
.*},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,29 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2016 by Todd Strader.
|
||||
|
||||
//bug1097
|
||||
|
||||
interface foo_intf;
|
||||
endinterface
|
||||
|
||||
module submod
|
||||
(
|
||||
foo_intf foo
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
// Intentional typo, compiler should point this out, or that fo_intf does
|
||||
// not match foo_intf on the submod port map
|
||||
fo_intf the_foo;
|
||||
|
||||
submod
|
||||
submod_inst
|
||||
(
|
||||
.foo (the_foo)
|
||||
);
|
||||
|
||||
endmodule
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/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->{vlt} or $Self->skip("Verilator only test");
|
||||
compile (
|
||||
v_flags2 => ["--lint-only"],
|
||||
fails => 1,
|
||||
verilator_make_gcc => 0,
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
expect=>
|
||||
'%Error: t/t_param_up_bad.v:\d+: Can\'t find definition of scope/variable: bar
|
||||
.*%Error: Exiting due to.*',
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,31 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2016 by Ian Thompson.
|
||||
|
||||
//bug1099
|
||||
|
||||
typedef struct packed {
|
||||
logic foo;
|
||||
} some_struct_t;
|
||||
|
||||
module child ();
|
||||
logic a_bad;
|
||||
// bar is in the parent module, but illegal to reference without module name
|
||||
assign a_bad = bar.foo;
|
||||
endmodule
|
||||
|
||||
module parent
|
||||
#(
|
||||
parameter PARAM = 0
|
||||
)
|
||||
(
|
||||
);
|
||||
some_struct_t bar;
|
||||
child c ();
|
||||
endmodule
|
||||
|
||||
module t ();
|
||||
// The parameter must be anything other than the default
|
||||
parent #( 1 ) p ();
|
||||
endmodule
|
||||
Reference in New Issue
Block a user