mirror of
https://github.com/verilator/verilator.git
synced 2026-10-05 01:23:37 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8edbad18c | ||
|
|
c86fec5307 | ||
|
|
6e476255ca | ||
|
|
27af9b6b06 | ||
|
|
f8208fa961 | ||
|
|
87b9cb49ad | ||
|
|
b2da0772e6 | ||
|
|
4f73e0850e | ||
|
|
b6a39db627 | ||
|
|
3a83b06572 | ||
|
|
fe5bf01b25 | ||
|
|
5559ec903b | ||
|
|
18750028b2 | ||
|
|
6b88648c67 | ||
|
|
58ee803cb4 | ||
|
|
894ff73c7d | ||
|
|
8031f0ed7f | ||
|
|
3a56b5da47 |
@@ -3,6 +3,31 @@ 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.864 2014-09-21
|
||||
|
||||
*** Support power operator with real, bug809. [Jonathon Donaldson]
|
||||
|
||||
**** Improve verilator_profcfunc time attributions. [Jonathon Donaldson]
|
||||
|
||||
**** Fix duplicate anonymous structures in $root, bug788. [Bob Newgard]
|
||||
|
||||
**** Fix mis-optimization of bit-swap in wide signal, bug800. [Jie Xu]
|
||||
|
||||
**** Fix error when tracing public parameters, bug722. [Jonathon Donaldson]
|
||||
|
||||
**** Fix dpiGetContext in dotted scopes, bug740. [Geoff Barrett]
|
||||
|
||||
**** Fix over-shift structure optimization error, bug803. [Jeff Bush]
|
||||
|
||||
**** Fix optional parameter keyword in module #(), bug810. [Iztok Jeras]
|
||||
|
||||
**** Fix $warning/$error multi-argument ordering, bug816. [Jonathon Donaldson]
|
||||
|
||||
**** Fix clang warnings, bug818. [Iztok Jeras]
|
||||
|
||||
**** Fix string formats under deep expressions, bug820. [Iztok Jeras]
|
||||
|
||||
|
||||
* Verilator 3.862 2014-06-10
|
||||
|
||||
*** Using command line -Wno-{WARNING} now overrides file-local lint_on.
|
||||
|
||||
+6
-4
@@ -782,8 +782,10 @@ Disables optimization of the model.
|
||||
|
||||
=item -O3
|
||||
|
||||
Enables slow optimizations. This may reduce simulation runtimes at the
|
||||
cost of compile time. This currently sets --inline-mult -1.
|
||||
Enables slow optimizations for the code Verilator itself generates (as
|
||||
opposed to "-CFLAGS -O3" which effects the C compiler's optimization. -O3
|
||||
may reduce simulation runtimes at the cost of compile time. This currently
|
||||
sets --inline-mult -1.
|
||||
|
||||
=item -OI<optimization-letter>
|
||||
|
||||
@@ -2968,8 +2970,8 @@ simulators.
|
||||
Warns that an `include filename specifies an absolute path. This means the
|
||||
code will not work on any other system with a different file system layout.
|
||||
Instead of using absolute paths, relative paths (preferably without any
|
||||
directory specified whatever) should be used, and +include used on the
|
||||
command line to specify the top include source directory.
|
||||
directory specified whatever) should be used, and +incdir used on the
|
||||
command line to specify the top include source directories.
|
||||
|
||||
Disabled by default as this is a code style warning; it will simulate
|
||||
correctly.
|
||||
|
||||
+15
-1
@@ -118,6 +118,18 @@ sub profcfunc {
|
||||
$groups{type}{"Common code under $design"} += $pct;
|
||||
$groups{design}{$design} += $pct;
|
||||
$groups{module}{$design." common code"} += $pct;
|
||||
} elsif ($func =~ /^VL_[A-Z0-9_]+/
|
||||
|| $func =~ /^_?vl_[a-zA-Z0-9_]+/
|
||||
|| $func =~ /^verilated/i) {
|
||||
$vfunc = sprintf("VLib %s", $func);
|
||||
$groups{type}{'VLib'} += $pct;
|
||||
$groups{design}{'VLib'} += $pct;
|
||||
$groups{module}{'VLib'} += $pct;
|
||||
} elsif ($func =~ /^_mcount_private/) {
|
||||
$vfunc = sprintf("Prof %s", $func);
|
||||
$groups{type}{'Prof'} += $pct;
|
||||
$groups{design}{'Prof'} += $pct;
|
||||
$groups{module}{'Prof'} += $pct;
|
||||
} else {
|
||||
$vfunc = sprintf("C++ %s", $func);
|
||||
$groups{type}{'C++'} += $pct;
|
||||
@@ -129,7 +141,7 @@ sub profcfunc {
|
||||
}
|
||||
|
||||
|
||||
foreach my $type qw(type design module) {
|
||||
foreach my $type (qw(type design module)) {
|
||||
my $missing = 100;
|
||||
foreach (sort (keys %{$groups{$type}})) {
|
||||
$missing -= $groups{$type}{$_};
|
||||
@@ -150,8 +162,10 @@ sub profcfunc {
|
||||
print("Verilog code profile:\n");
|
||||
print(" These are split into three categories:\n");
|
||||
print(" C++: Time in non-Verilated C++ code\n");
|
||||
print(" Prof: Time in profile overhead\n");
|
||||
print(" VBlock: Time attributable to a block in a Verilog file and line\n");
|
||||
print(" VCommon: Time in a Verilated module, due to all parts of the design\n");
|
||||
print(" VLib: Time in Verilated common libraries, called by the Verilated code\n");
|
||||
print("\n");
|
||||
|
||||
print(" % cumulative self \n");
|
||||
|
||||
+4
-2
@@ -6,7 +6,7 @@
|
||||
|
||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[3.862 2014-06-10])
|
||||
AC_INIT([Verilator],[3.864 2014-09-21])
|
||||
AC_CONFIG_HEADER(src/config_build.h)
|
||||
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h)
|
||||
|
||||
@@ -122,15 +122,17 @@ AC_DEFUN([_MY_CXX_CHECK_OPT],
|
||||
|
||||
# For example, -Wno-div-by-zero isn't in 4.1.2
|
||||
_MY_CXX_CHECK_OPT(-Wno-char-subscripts)
|
||||
_MY_CXX_CHECK_OPT(-Wno-parentheses-equality)
|
||||
# Random code often does / 0. Unfortunately VL_DIV_I(0,0) will warn
|
||||
# without this flag, even though there's a conditional to prevent the divide.
|
||||
# We still don't add no-div-by-zero as it throws message to stdout, though doesn't die.
|
||||
#_MY_CXX_CHECK_OPT(-Wno-div-by-zero)
|
||||
_MY_CXX_CHECK_OPT(-Wno-sign-compare)
|
||||
_MY_CXX_CHECK_OPT(-Wno-uninitialized)
|
||||
_MY_CXX_CHECK_OPT(-Wno-unused-but-set-variable)
|
||||
_MY_CXX_CHECK_OPT(-Wno-unused-parameter)
|
||||
_MY_CXX_CHECK_OPT(-Wno-unused-variable)
|
||||
_MY_CXX_CHECK_OPT(-Wno-unused-but-set-variable)
|
||||
_MY_CXX_CHECK_OPT(-fbracket-depth=4096)
|
||||
AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
|
||||
|
||||
# Checks for library functions.
|
||||
|
||||
@@ -74,6 +74,9 @@ void vl_fatal (const char* filename, int linenum, const char* hier, const char*
|
||||
Verilated::gotFinish(true);
|
||||
VL_PRINTF("%%Error: %s:%d: %s\n", filename, linenum, msg);
|
||||
Verilated::flushCall();
|
||||
|
||||
VL_PRINTF("Aborting...\n");
|
||||
Verilated::flushCall(); // Second flush in case VL_PRINTF does something needing a flush
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -43,14 +43,14 @@ VK_CPPFLAGS_ALWAYS += \
|
||||
-DVL_PRINTF=printf \
|
||||
-DVM_TRACE=$(VM_TRACE) \
|
||||
-DVM_COVERAGE=$(VM_COVERAGE) \
|
||||
$(CFG_CXXFLAGS_NO_UNUSED) \
|
||||
|
||||
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||
VK_CPPFLAGS_WALL += -Wall \
|
||||
$(CFG_CXXFLAGS_NO_UNUSED) \
|
||||
-Werror
|
||||
endif
|
||||
|
||||
CPPFLAGS += -I. $(VK_CPPFLAGS_ALWAYS) $(VK_CPPFLAGS_WALL)
|
||||
CPPFLAGS += -I. $(VK_CPPFLAGS_WALL) $(VK_CPPFLAGS_ALWAYS)
|
||||
|
||||
VPATH += ..
|
||||
VPATH += $(VERILATOR_ROOT)/include
|
||||
@@ -195,6 +195,7 @@ debug-make::
|
||||
@echo VM_SUPPORT_SLOW: $(VM_SUPPORT_SLOW)
|
||||
@echo VM_GLOBAL_FAST: $(VM_GLOBAL_FAST)
|
||||
@echo VM_GLOBAL_SLOW: $(VM_GLOBAL_SLOW)
|
||||
@echo CPPFLAGS: $(CPPFLAGS)
|
||||
@echo
|
||||
|
||||
######################################################################
|
||||
|
||||
@@ -703,5 +703,5 @@ main() {
|
||||
|
||||
//********************************************************************
|
||||
// Local Variables:
|
||||
// compile-command: "mkdir -p ../test_dir && cd ../test_dir && g++ -DVERILATED_VCD_TEST ../src/verilated_vcd_c.cpp -o verilated_vcd_c && ./verilated_vcd_c && cat test.vcd"
|
||||
// compile-command: "mkdir -p ../test_dir && cd ../test_dir && c++ -DVERILATED_VCD_TEST ../src/verilated_vcd_c.cpp -o verilated_vcd_c && ./verilated_vcd_c && cat test.vcd"
|
||||
// End:
|
||||
|
||||
+11
-11
@@ -97,8 +97,8 @@ public:
|
||||
virtual const char* fullname() { return "<null>"; }
|
||||
virtual const char* defname() { return "<null>"; }
|
||||
virtual const vluint32_t type() { return 0; }
|
||||
virtual const vluint32_t size() { return 0; }
|
||||
virtual const VerilatedRange* rangep() { return 0; }
|
||||
virtual const vluint32_t size() const { return 0; }
|
||||
virtual const VerilatedRange* rangep() const { return NULL; }
|
||||
virtual vpiHandle dovpi_scan() { return 0; }
|
||||
};
|
||||
|
||||
@@ -136,7 +136,7 @@ public:
|
||||
|
||||
class VerilatedVpioRange : public VerilatedVpio {
|
||||
const VerilatedRange* m_range;
|
||||
bool m_iteration;
|
||||
vlsint32_t m_iteration;
|
||||
public:
|
||||
VerilatedVpioRange(const VerilatedRange* range) : m_range(range), m_iteration(0) {}
|
||||
virtual ~VerilatedVpioRange() {}
|
||||
@@ -182,7 +182,7 @@ class VerilatedVpioVar : public VerilatedVpio {
|
||||
protected:
|
||||
void* m_varDatap; // varp()->datap() adjusted for array entries
|
||||
vlsint32_t m_index;
|
||||
const VerilatedRange& get_range() {
|
||||
const VerilatedRange& get_range() const {
|
||||
// Determine number of dimensions and return outermost
|
||||
return (m_varp->dims()>1) ? m_varp->array() : m_varp->range();
|
||||
}
|
||||
@@ -208,8 +208,8 @@ public:
|
||||
if (varp()->vldir() != vpiNoDirection) return vpiPort;
|
||||
return (varp()->dims()>1) ? vpiMemory : vpiReg; /* but might be wire, logic */
|
||||
}
|
||||
virtual const vluint32_t size() { return get_range().elements(); }
|
||||
virtual const VerilatedRange* rangep() { return &get_range(); }
|
||||
virtual const vluint32_t size() const { return get_range().elements(); }
|
||||
virtual const VerilatedRange* rangep() const { return &get_range(); }
|
||||
virtual const char* name() { return m_varp->name(); }
|
||||
virtual const char* fullname() {
|
||||
VL_STATIC_OR_THREAD string out;
|
||||
@@ -237,8 +237,8 @@ public:
|
||||
virtual ~VerilatedVpioMemoryWord() {}
|
||||
static inline VerilatedVpioMemoryWord* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioMemoryWord*>((VerilatedVpio*)h); }
|
||||
virtual const vluint32_t type() { return vpiMemoryWord; }
|
||||
virtual const vluint32_t size() { return varp()->range().elements(); }
|
||||
virtual const VerilatedRange* rangep() { return &(varp()->range()); }
|
||||
virtual const vluint32_t size() const { return varp()->range().elements(); }
|
||||
virtual const VerilatedRange* rangep() const { return &(varp()->range()); }
|
||||
virtual const char* fullname() {
|
||||
VL_STATIC_OR_THREAD string out;
|
||||
char num[20]; sprintf(num,"%d",m_index);
|
||||
@@ -919,9 +919,9 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
|
||||
value_p->value.str = outStr;
|
||||
switch (vop->varp()->vltype()) {
|
||||
// outStrSz does not include NULL termination so add one
|
||||
case VLVT_UINT8 : snprintf(outStr, outStrSz+1, "%hhu", (unsigned int)*((CData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT16: snprintf(outStr, outStrSz+1, "%hu", (unsigned int)*((SData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT32: snprintf(outStr, outStrSz+1, "%u", (unsigned int)*((IData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT8 : snprintf(outStr, outStrSz+1, "%hhu", (unsigned char )*((CData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT16: snprintf(outStr, outStrSz+1, "%hu", (unsigned short)*((SData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT32: snprintf(outStr, outStrSz+1, "%u", (unsigned int )*((IData*)(vop->varDatap()))); return;
|
||||
case VLVT_UINT64: snprintf(outStr, outStrSz+1, "%llu", (unsigned long long)*((QData*)(vop->varDatap()))); return;
|
||||
default:
|
||||
strcpy(outStr, "-1");
|
||||
|
||||
+6
-3
@@ -61,10 +61,13 @@ private:
|
||||
void replaceDisplay(AstDisplay* nodep, const string& prefix) {
|
||||
nodep->displayType(AstDisplayType::DT_WRITE);
|
||||
nodep->fmtp()->text(assertDisplayMessage(nodep, prefix, nodep->fmtp()->text()));
|
||||
AstNode* timesp = nodep->fmtp()->exprsp(); if (timesp) timesp->unlinkFrBack();
|
||||
// cppcheck-suppress nullPointer
|
||||
timesp = timesp->addNext(new AstTime(nodep->fileline()));
|
||||
nodep->fmtp()->exprsp(timesp);
|
||||
AstNode* timenewp = new AstTime(nodep->fileline());
|
||||
if (AstNode* timesp = nodep->fmtp()->exprsp()) {
|
||||
timesp->unlinkFrBackWithNext();
|
||||
timenewp->addNext(timesp);
|
||||
}
|
||||
nodep->fmtp()->exprsp(timenewp);
|
||||
if (!nodep->fmtp()->scopeNamep() && nodep->fmtp()->formatScopeTracking()) {
|
||||
nodep->fmtp()->scopeNamep(new AstScopeName(nodep->fileline()));
|
||||
}
|
||||
|
||||
+44
-26
@@ -1216,8 +1216,9 @@ inline void AstNRelinker::relink(AstNode* newp) { newp->AstNode::relink(this); }
|
||||
virtual ~Ast ##name() {} \
|
||||
Ast ##name * cloneTree(bool cloneNext) { return AstNode::cloneTree(cloneNext)->cast ##name(); }
|
||||
|
||||
struct AstNodeMath : public AstNode {
|
||||
class AstNodeMath : public AstNode {
|
||||
// Math -- anything that's part of an expression tree
|
||||
public:
|
||||
AstNodeMath(FileLine* fl)
|
||||
: AstNode(fl) {}
|
||||
ASTNODE_BASE_FUNCS(NodeMath)
|
||||
@@ -1232,8 +1233,9 @@ struct AstNodeMath : public AstNode {
|
||||
bool isOpaque() { return castCvtPackString()!=NULL; }
|
||||
};
|
||||
|
||||
struct AstNodeTermop : public AstNodeMath {
|
||||
class AstNodeTermop : public AstNodeMath {
|
||||
// Terminal operator -- a operator with no "inputs"
|
||||
public:
|
||||
AstNodeTermop(FileLine* fl)
|
||||
: AstNodeMath(fl) {}
|
||||
ASTNODE_BASE_FUNCS(NodeTermop)
|
||||
@@ -1243,8 +1245,9 @@ struct AstNodeTermop : public AstNodeMath {
|
||||
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
|
||||
};
|
||||
|
||||
struct AstNodeUniop : public AstNodeMath {
|
||||
class AstNodeUniop : public AstNodeMath {
|
||||
// Unary math
|
||||
public:
|
||||
AstNodeUniop(FileLine* fl, AstNode* lhsp)
|
||||
: AstNodeMath(fl) {
|
||||
dtypeFrom(lhsp);
|
||||
@@ -1263,8 +1266,9 @@ struct AstNodeUniop : public AstNodeMath {
|
||||
virtual bool same(AstNode*) const { return true; }
|
||||
};
|
||||
|
||||
struct AstNodeBiop : public AstNodeMath {
|
||||
class AstNodeBiop : public AstNodeMath {
|
||||
// Binary math
|
||||
public:
|
||||
AstNodeBiop(FileLine* fl, AstNode* lhs, AstNode* rhs)
|
||||
: AstNodeMath(fl) {
|
||||
setOp1p(lhs); setOp2p(rhs); }
|
||||
@@ -1286,8 +1290,9 @@ struct AstNodeBiop : public AstNodeMath {
|
||||
virtual bool same(AstNode*) const { return true; }
|
||||
};
|
||||
|
||||
struct AstNodeTriop : public AstNodeMath {
|
||||
class AstNodeTriop : public AstNodeMath {
|
||||
// Trinary math
|
||||
public:
|
||||
AstNodeTriop(FileLine* fl, AstNode* lhs, AstNode* rhs, AstNode* ths)
|
||||
: AstNodeMath(fl) {
|
||||
setOp1p(lhs); setOp2p(rhs); setOp3p(ths); }
|
||||
@@ -1311,20 +1316,23 @@ struct AstNodeTriop : public AstNodeMath {
|
||||
virtual bool same(AstNode*) const { return true; }
|
||||
};
|
||||
|
||||
struct AstNodeBiCom : public AstNodeBiop {
|
||||
class AstNodeBiCom : public AstNodeBiop {
|
||||
// Binary math with commutative properties
|
||||
public:
|
||||
AstNodeBiCom(FileLine* fl, AstNode* lhs, AstNode* rhs)
|
||||
: AstNodeBiop(fl, lhs, rhs) {}
|
||||
ASTNODE_BASE_FUNCS(NodeBiCom)
|
||||
};
|
||||
|
||||
struct AstNodeBiComAsv : public AstNodeBiCom {
|
||||
class AstNodeBiComAsv : public AstNodeBiCom {
|
||||
// Binary math with commutative & associative properties
|
||||
public:
|
||||
AstNodeBiComAsv(FileLine* fl, AstNode* lhs, AstNode* rhs)
|
||||
: AstNodeBiCom(fl, lhs, rhs) {}
|
||||
ASTNODE_BASE_FUNCS(NodeBiComAsv)
|
||||
};
|
||||
struct AstNodeCond : public AstNodeTriop {
|
||||
class AstNodeCond : public AstNodeTriop {
|
||||
public:
|
||||
AstNodeCond(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p)
|
||||
: AstNodeTriop(fl, condp, expr1p, expr2p) {
|
||||
if (expr1p) dtypeFrom(expr1p);
|
||||
@@ -1346,8 +1354,9 @@ struct AstNodeCond : public AstNodeTriop {
|
||||
virtual int instrCount() const { return instrCountBranch(); }
|
||||
};
|
||||
|
||||
struct AstNodePreSel : public AstNode {
|
||||
class AstNodePreSel : public AstNode {
|
||||
// Something that becomes an AstSel
|
||||
public:
|
||||
AstNodePreSel(FileLine* fl, AstNode* lhs, AstNode* rhs, AstNode* ths)
|
||||
: AstNode(fl) {
|
||||
setOp1p(lhs); setOp2p(rhs); setNOp3p(ths); }
|
||||
@@ -1366,8 +1375,9 @@ struct AstNodePreSel : public AstNode {
|
||||
virtual bool same(AstNode*) const { return true; }
|
||||
};
|
||||
|
||||
struct AstNodeStmt : public AstNode {
|
||||
class AstNodeStmt : public AstNode {
|
||||
// Statement -- anything that's directly under a function
|
||||
public:
|
||||
AstNodeStmt(FileLine* fl)
|
||||
: AstNode(fl) {}
|
||||
ASTNODE_BASE_FUNCS(NodeStmt)
|
||||
@@ -1376,7 +1386,8 @@ struct AstNodeStmt : public AstNode {
|
||||
virtual void addBeforeStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here
|
||||
};
|
||||
|
||||
struct AstNodeAssign : public AstNodeStmt {
|
||||
class AstNodeAssign : public AstNodeStmt {
|
||||
public:
|
||||
AstNodeAssign(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
||||
: AstNodeStmt(fl) {
|
||||
setOp1p(rhsp); setOp2p(lhsp);
|
||||
@@ -1397,7 +1408,8 @@ struct AstNodeAssign : public AstNodeStmt {
|
||||
virtual string verilogKwd() const { return "="; }
|
||||
};
|
||||
|
||||
struct AstNodeFor : public AstNodeStmt {
|
||||
class AstNodeFor : public AstNodeStmt {
|
||||
public:
|
||||
AstNodeFor(FileLine* fileline, AstNode* initsp, AstNode* condp,
|
||||
AstNode* incsp, AstNode* bodysp)
|
||||
: AstNodeStmt(fileline) {
|
||||
@@ -1414,7 +1426,7 @@ struct AstNodeFor : public AstNodeStmt {
|
||||
virtual bool same(AstNode* samep) const { return true; }
|
||||
};
|
||||
|
||||
struct AstNodeIf : public AstNodeStmt {
|
||||
class AstNodeIf : public AstNodeStmt {
|
||||
private:
|
||||
AstBranchPred m_branchPred; // Branch prediction as taken/untaken?
|
||||
public:
|
||||
@@ -1438,7 +1450,8 @@ public:
|
||||
AstBranchPred branchPred() const { return m_branchPred; }
|
||||
};
|
||||
|
||||
struct AstNodeCase : public AstNodeStmt {
|
||||
class AstNodeCase : public AstNodeStmt {
|
||||
public:
|
||||
AstNodeCase(FileLine* fl, AstNode* exprp, AstNode* casesp)
|
||||
: AstNodeStmt(fl) {
|
||||
setOp1p(exprp); addNOp2p(casesp);
|
||||
@@ -1452,8 +1465,9 @@ struct AstNodeCase : public AstNodeStmt {
|
||||
void addNotParallelp(AstNode* nodep) { setOp3p(nodep); }
|
||||
};
|
||||
|
||||
struct AstNodeSenItem : public AstNode {
|
||||
class AstNodeSenItem : public AstNode {
|
||||
// An AstSenItem or AstSenGate
|
||||
public:
|
||||
AstNodeSenItem(FileLine* fl) : AstNode(fl) {}
|
||||
ASTNODE_BASE_FUNCS(NodeSenItem)
|
||||
virtual bool isClocked() const = 0;
|
||||
@@ -1511,7 +1525,7 @@ public:
|
||||
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
|
||||
};
|
||||
|
||||
struct AstNodeText : public AstNode {
|
||||
class AstNodeText : public AstNode {
|
||||
private:
|
||||
string m_text;
|
||||
public:
|
||||
@@ -1528,11 +1542,11 @@ public:
|
||||
const string& text() const { return m_text; }
|
||||
};
|
||||
|
||||
struct AstNodeDType : public AstNode {
|
||||
private:
|
||||
class AstNodeDType : public AstNode {
|
||||
// Ideally width() would migrate to BasicDType as that's where it makes sense,
|
||||
// but it's currently so prevalent in the code we leave it here.
|
||||
// Note the below members are included in AstTypeTable::Key lookups
|
||||
private:
|
||||
int m_width; // (also in AstTypeTable::Key) Bit width of operation
|
||||
int m_widthMin; // (also in AstTypeTable::Key) If unsized, bitwidth of minimum implementation
|
||||
AstNumeric m_numeric; // (also in AstTypeTable::Key) Node is signed
|
||||
@@ -1581,7 +1595,7 @@ public:
|
||||
static int uniqueNumInc() { return ++s_uniqueNum; }
|
||||
};
|
||||
|
||||
struct AstNodeClassDType : public AstNodeDType {
|
||||
class AstNodeClassDType : public AstNodeDType {
|
||||
private:
|
||||
// TYPES
|
||||
typedef map<string,AstMemberDType*> MemberNameMap;
|
||||
@@ -1620,7 +1634,7 @@ public:
|
||||
VNumRange declRange() const { return VNumRange(msb(), lsb(), false); }
|
||||
};
|
||||
|
||||
struct AstNodeArrayDType : public AstNodeDType {
|
||||
class AstNodeArrayDType : public AstNodeDType {
|
||||
// Array data type, ie "some_dtype var_name [2:0]"
|
||||
// Children: DTYPE (moved to refDTypep() in V3Width)
|
||||
// Children: RANGE (array bounds)
|
||||
@@ -1666,8 +1680,9 @@ public:
|
||||
VNumRange declRange() const;
|
||||
};
|
||||
|
||||
struct AstNodeSel : public AstNodeBiop {
|
||||
class AstNodeSel : public AstNodeBiop {
|
||||
// Single bit range extraction, perhaps with non-constant selection or array selection
|
||||
public:
|
||||
AstNodeSel(FileLine* fl, AstNode* fromp, AstNode* bitp)
|
||||
:AstNodeBiop(fl, fromp, bitp) {}
|
||||
ASTNODE_BASE_FUNCS(NodeSel)
|
||||
@@ -1679,8 +1694,9 @@ struct AstNodeSel : public AstNodeBiop {
|
||||
virtual bool hasDType() const { return true; }
|
||||
};
|
||||
|
||||
struct AstNodeStream : public AstNodeBiop {
|
||||
class AstNodeStream : public AstNodeBiop {
|
||||
// Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp()
|
||||
public:
|
||||
AstNodeStream(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
if (lhsp->dtypep()) {
|
||||
dtypeSetLogicSized(lhsp->dtypep()->width(), lhsp->dtypep()->width(), AstNumeric::UNSIGNED);
|
||||
@@ -1692,7 +1708,7 @@ struct AstNodeStream : public AstNodeBiop {
|
||||
//######################################################################
|
||||
// Tasks/functions common handling
|
||||
|
||||
struct AstNodeFTask : public AstNode {
|
||||
class AstNodeFTask : public AstNode {
|
||||
private:
|
||||
string m_name; // Name of task
|
||||
string m_cname; // Name of task if DPI import
|
||||
@@ -1750,7 +1766,7 @@ public:
|
||||
bool pure() const { return m_pure; }
|
||||
};
|
||||
|
||||
struct AstNodeFTaskRef : public AstNode {
|
||||
class AstNodeFTaskRef : public AstNode {
|
||||
// A reference to a task (or function)
|
||||
private:
|
||||
AstNodeFTask* m_taskp; // [AfterLink] Pointer to task referenced
|
||||
@@ -1796,7 +1812,7 @@ public:
|
||||
void scopeNamep(AstNode* nodep) { setNOp3p(nodep); }
|
||||
};
|
||||
|
||||
struct AstNodeModule : public AstNode {
|
||||
class AstNodeModule : public AstNode {
|
||||
// A module, package, program or interface declaration;
|
||||
// something that can live directly under the TOP,
|
||||
// excluding $unit package stuff
|
||||
@@ -1810,12 +1826,13 @@ private:
|
||||
bool m_internal:1; // Internally created
|
||||
int m_level; // 1=top module, 2=cell off top module, ...
|
||||
int m_varNum; // Incrementing variable number
|
||||
int m_typeNum; // Incrementing implicit type number
|
||||
public:
|
||||
AstNodeModule(FileLine* fl, const string& name)
|
||||
: AstNode (fl)
|
||||
,m_name(name), m_origName(name)
|
||||
,m_modPublic(false), m_modTrace(false), m_inLibrary(false), m_dead(false), m_internal(false)
|
||||
,m_level(0), m_varNum(0) { }
|
||||
,m_level(0), m_varNum(0), m_typeNum(0) { }
|
||||
ASTNODE_BASE_FUNCS(NodeModule)
|
||||
virtual void dump(ostream& str);
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
@@ -1835,6 +1852,7 @@ public:
|
||||
int level() const { return m_level; }
|
||||
bool isTop() const { return level()==1; }
|
||||
int varNumGetInc() { return ++m_varNum; }
|
||||
int typeNumGetInc() { return ++m_typeNum; }
|
||||
void modPublic(bool flag) { m_modPublic = flag; }
|
||||
bool modPublic() const { return m_modPublic; }
|
||||
void modTrace(bool flag) { m_modTrace = flag; }
|
||||
|
||||
@@ -515,6 +515,24 @@ string AstScopeName::scopeSymName() const {
|
||||
return out;
|
||||
}
|
||||
|
||||
string AstScopeName::scopeDpiName() const {
|
||||
string out;
|
||||
for (AstText* textp=scopeEntrp(); textp; textp=textp->nextp()->castText()) {
|
||||
out += textp->text();
|
||||
}
|
||||
if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,"");
|
||||
if (out.substr(0,7) == "__DOT__") out.replace(0,7,"");
|
||||
if (out.substr(0,1) == ".") out.replace(0,1,"");
|
||||
string::size_type pos;
|
||||
while ((pos=out.find(".")) != string::npos) {
|
||||
out.replace(pos, 1, "__");
|
||||
}
|
||||
while ((pos=out.find("__DOT__")) != string::npos) {
|
||||
out.replace(pos, 7, "__");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
bool AstSenTree::hasClocked() {
|
||||
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
|
||||
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
|
||||
|
||||
+411
-245
File diff suppressed because it is too large
Load Diff
+5
-1
@@ -226,7 +226,9 @@ public:
|
||||
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||
// For use under AstCCalls for dpiImports. ScopeNames under displays are handled in AstDisplay
|
||||
if (!nodep->dpiExport()) {
|
||||
putbs("(&(vlSymsp->__Vscope_"+nodep->scopeSymName()+"))");
|
||||
// this is where the DPI import context scope is set
|
||||
string scope = nodep->scopeDpiName();
|
||||
putbs("(&(vlSymsp->__Vscope_"+scope+"))");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSFormat* nodep, AstNUser*) {
|
||||
@@ -783,6 +785,7 @@ class EmitCImp : EmitCStmts {
|
||||
|
||||
//---------------------------------------
|
||||
// VISITORS
|
||||
using EmitCStmts::visit; // Suppress hidden overloaded virtual function warnng
|
||||
virtual void visit(AstCFunc* nodep, AstNUser*) {
|
||||
// TRACE_* and DPI handled elsewhere
|
||||
if (nodep->funcType().isTrace()) return;
|
||||
@@ -2303,6 +2306,7 @@ class EmitCTrace : EmitCStmts {
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
using EmitCStmts::visit; // Suppress hidden overloaded virtual function warnng
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
// Top module only
|
||||
nodep->topModulep()->accept(*this);
|
||||
|
||||
+1
-2
@@ -685,7 +685,6 @@ public:
|
||||
class EmitVPrefixedVisitor : public EmitVBaseVisitor {
|
||||
// MEMBERS
|
||||
EmitVPrefixedFormatter m_formatter; // Special verilog formatter (Way down the inheritance is another unused V3OutFormatter)
|
||||
bool m_user3mark; // nodep->user3() if set means mark with %%
|
||||
// METHODS
|
||||
virtual void putsNoTracking(const string& str) { m_formatter.putsNoTracking(str); }
|
||||
virtual void puts(const string& str) { m_formatter.puts(str); }
|
||||
@@ -706,7 +705,7 @@ class EmitVPrefixedVisitor : public EmitVBaseVisitor {
|
||||
public:
|
||||
EmitVPrefixedVisitor(AstNode* nodep, ostream& os, const string& prefix, int flWidth,
|
||||
AstSenTree* domainp, bool user3mark)
|
||||
: EmitVBaseVisitor(domainp), m_formatter(os, prefix, flWidth), m_user3mark(user3mark) {
|
||||
: EmitVBaseVisitor(domainp), m_formatter(os, prefix, flWidth) {
|
||||
if (user3mark) { AstUser3InUse::check(); }
|
||||
nodep->accept(*this);
|
||||
}
|
||||
|
||||
+5
-1
@@ -583,11 +583,15 @@ private:
|
||||
newSelBitBit(lhsp->lsbp()),
|
||||
VL_WORDSIZE)),
|
||||
oldvalp);
|
||||
|
||||
// Restrict the shift amount to 0-31, see bug804.
|
||||
AstNode* shiftp = new AstAnd(nodep->fileline(), lhsp->lsbp()->cloneTree(true),
|
||||
new AstConst(nodep->fileline(), VL_WORDSIZE-1));
|
||||
AstNode* newp = new AstOr (lhsp->fileline(),
|
||||
oldvalp,
|
||||
new AstShiftL (lhsp->fileline(),
|
||||
rhsp,
|
||||
lhsp->lsbp()->cloneTree(true),
|
||||
shiftp,
|
||||
VL_WORDSIZE));
|
||||
newp = new AstAssign (nodep->fileline(),
|
||||
new AstWordSel (nodep->fileline(),
|
||||
|
||||
+1
-1
@@ -567,7 +567,7 @@ const char* V3OutFormatter::indentStr(int num) {
|
||||
static char str[MAXSPACE+20];
|
||||
char* cp = str;
|
||||
if (num>MAXSPACE) num=MAXSPACE;
|
||||
if (!m_lang==LA_VERILOG) { // verilogPrefixedTree doesn't want tabs
|
||||
if (m_lang!=LA_VERILOG) { // verilogPrefixedTree doesn't want tabs
|
||||
while (num>=8) {
|
||||
*cp++ = '\t';
|
||||
num -= 8;
|
||||
|
||||
@@ -96,6 +96,7 @@ public:
|
||||
DfaVertex(DfaGraph* graphp, bool start=false, bool accepting=false)
|
||||
: V3GraphVertex(graphp)
|
||||
, m_start(start), m_accepting(accepting) {}
|
||||
using V3GraphVertex::clone; // We are overriding, not overloading clone(V3Graph*)
|
||||
virtual DfaVertex* clone(DfaGraph* graphp) {
|
||||
return new DfaVertex(graphp, start(), accepting()); }
|
||||
virtual ~DfaVertex() {}
|
||||
|
||||
@@ -387,6 +387,10 @@ private:
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->scopeAttrp(new AstText(nodep->fileline(), (string)"__DOT__"+m_cellp->name()));
|
||||
if (afterp) nodep->scopeAttrp(afterp);
|
||||
afterp = nodep->scopeEntrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->scopeEntrp(new AstText(nodep->fileline(), (string)"__DOT__"+m_cellp->name()));
|
||||
if (afterp) nodep->scopeEntrp(afterp);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstCoverDecl* nodep, AstNUser*) {
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ private:
|
||||
bool bitIsXZ(int bit) const {
|
||||
if (bit<0) return false;
|
||||
if (bit>=m_width) return bitIsXZ(m_width-1);
|
||||
return ( (m_valueX[bit/32] & (1UL<<(bit&31))) && 1);
|
||||
return ( (m_valueX[bit/32] & (1UL<<(bit&31))));
|
||||
}
|
||||
bool bitIsZ (int bit) const {
|
||||
if (bit<0) return false;
|
||||
|
||||
+2
-1
@@ -210,7 +210,8 @@ private:
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
if (nodep->dead()) {
|
||||
UINFO(4," MOD-dead. "<<nodep<<endl); // Marked by LinkDot
|
||||
} else if (nodep->level() <= 2) { // Haven't added top yet, so level 2 is the top
|
||||
} else if (nodep->level() <= 2 // Haven't added top yet, so level 2 is the top
|
||||
|| nodep->castPackage()) { // Likewise haven't done wrapTopPackages yet
|
||||
// Add request to END of modules left to process
|
||||
m_todoModps.insert(make_pair(nodep->level(),nodep));
|
||||
visitModules();
|
||||
|
||||
+66
-1
@@ -40,6 +40,60 @@
|
||||
#include "V3Premit.h"
|
||||
#include "V3Ast.h"
|
||||
|
||||
|
||||
//######################################################################
|
||||
// Structure for global state
|
||||
|
||||
class PremitAssignVisitor : public AstNVisitor {
|
||||
private:
|
||||
// NODE STATE
|
||||
// AstVar::user4() // bool; occurs on LHS of current assignment
|
||||
AstUser4InUse m_inuser4;
|
||||
|
||||
// STATE
|
||||
bool m_noopt; // Disable optimization of variables in this block
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
||||
//AstNode::user4ClearTree(); // Implied by AstUser4InUse
|
||||
// LHS first as fewer varrefs
|
||||
nodep->lhsp()->iterateAndNext(*this);
|
||||
// Now find vars marked as lhs
|
||||
nodep->rhsp()->iterateAndNext(*this);
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
// it's LHS var is used so need a deep temporary
|
||||
if (nodep->lvalue()) {
|
||||
nodep->varp()->user4(true);
|
||||
} else {
|
||||
if (nodep->varp()->user4()) {
|
||||
if (!m_noopt) UINFO(4, "Block has LHS+RHS var: "<<nodep<<endl);
|
||||
m_noopt = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
PremitAssignVisitor(AstNodeAssign* nodep) {
|
||||
UINFO(4," PremitAssignVisitor on "<<nodep<<endl);
|
||||
m_noopt = false;
|
||||
nodep->accept(*this);
|
||||
}
|
||||
virtual ~PremitAssignVisitor() {}
|
||||
bool noOpt() const { return m_noopt; }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// Premit state, as a visitor of each AstNode
|
||||
|
||||
@@ -49,6 +103,7 @@ private:
|
||||
// AstNodeMath::user() -> bool. True if iterated already
|
||||
// AstShiftL::user2() -> bool. True if converted to conditional
|
||||
// AstShiftR::user2() -> bool. True if converted to conditional
|
||||
// *::user4() -> See PremitAssignVisitor
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
|
||||
@@ -115,11 +170,13 @@ private:
|
||||
m_inWhilep->addPrecondsp(newp);
|
||||
} else if (m_inTracep) {
|
||||
m_inTracep->addPrecondsp(newp);
|
||||
} else {
|
||||
} else if (m_stmtp) {
|
||||
AstNRelinker linker;
|
||||
m_stmtp->unlinkFrBack(&linker);
|
||||
newp->addNext(m_stmtp);
|
||||
linker.relink(newp);
|
||||
} else {
|
||||
newp->v3fatalSrc("No statement insertion point.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,6 +231,14 @@ private:
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
||||
startStatement(nodep);
|
||||
{
|
||||
bool noopt = PremitAssignVisitor(nodep).noOpt();
|
||||
if (noopt && !nodep->user1()) {
|
||||
// Need to do this even if not wide, as e.g. a select may be on a wide operator
|
||||
UINFO(4,"Deep temp for LHS/RHS\n");
|
||||
createDeepTemp(nodep->rhsp());
|
||||
}
|
||||
}
|
||||
nodep->rhsp()->iterateAndNext(*this);
|
||||
m_assignLhs = true;
|
||||
nodep->lhsp()->iterateAndNext(*this);
|
||||
|
||||
@@ -270,6 +270,10 @@ private:
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->scopeAttrp(new AstText(nodep->fileline(), prefix));
|
||||
if (afterp) nodep->scopeAttrp(afterp);
|
||||
afterp = nodep->scopeEntrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->scopeEntrp(new AstText(nodep->fileline(), prefix));
|
||||
if (afterp) nodep->scopeEntrp(afterp);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||
|
||||
@@ -233,7 +233,6 @@ private:
|
||||
SplitPliVertex* m_pliVertexp; // Element specifying PLI ordering
|
||||
V3Graph m_graph; // Scoreboard of var usages/dependencies
|
||||
bool m_inDly; // Inside ASSIGNDLY
|
||||
uint32_t m_stepNum; // Step number we need to ignore a edge in
|
||||
V3Double0 m_statSplits; // Statistic tracking
|
||||
|
||||
// METHODS
|
||||
|
||||
@@ -43,7 +43,6 @@ private:
|
||||
// NODE STATE
|
||||
|
||||
// STATE
|
||||
AstNodeModule* m_modp; // Current module
|
||||
AstScope* m_scopetopp; // Current top scope
|
||||
AstCFunc* m_initFuncp; // Trace function being built
|
||||
AstCFunc* m_initSubFuncp; // Trace function being built (under m_init)
|
||||
|
||||
+11
-4
@@ -690,15 +690,21 @@ private:
|
||||
// Pow is special, output sign only depends on LHS sign, but function result depends on both signs
|
||||
// RHS is self-determined (IEEE)
|
||||
// Real if either side is real (as with AstAdd)
|
||||
iterate_shift_prelim(nodep, vup); // Iterate rhsp() as self-determined
|
||||
|
||||
if (vup->c()->prelim()) {
|
||||
nodep->lhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p());
|
||||
nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p());
|
||||
if (nodep->lhsp()->isDouble() || nodep->rhsp()->isDouble()) {
|
||||
spliceCvtD(nodep->lhsp());
|
||||
spliceCvtD(nodep->rhsp());
|
||||
replaceWithDVersion(nodep); nodep=NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
checkCvtUS(nodep->lhsp());
|
||||
iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH);
|
||||
nodep->dtypeFrom(nodep->lhsp());
|
||||
}
|
||||
|
||||
if (vup->c()->final()) {
|
||||
AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep());
|
||||
nodep->dtypeFrom(expDTypep);
|
||||
@@ -902,7 +908,7 @@ private:
|
||||
} else if (!basicp->isSigned() && newp->isSigned()) {
|
||||
newp = new AstUnsigned(nodep->fileline(), newp);
|
||||
} else {
|
||||
newp = newp; // Can just remove cast
|
||||
//newp = newp; // Can just remove cast
|
||||
}
|
||||
nodep->replaceWith(newp);
|
||||
pushDeletep(nodep); nodep=NULL;
|
||||
@@ -2297,7 +2303,7 @@ private:
|
||||
if (newp) {} // Ununused
|
||||
}
|
||||
void iterate_shift_prelim(AstNodeBiop* nodep, AstNUser* vup) {
|
||||
// Shifts, Pow
|
||||
// Shifts
|
||||
// See IEEE-2012 11.4.10 and Table 11-21.
|
||||
// RHS is self-determined. RHS is always treated as unsigned, has no effect on result.
|
||||
if (vup->c()->prelim()) {
|
||||
@@ -2885,6 +2891,7 @@ private:
|
||||
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;
|
||||
|
||||
+15
-18
@@ -62,8 +62,8 @@ public:
|
||||
int m_pinNum; // Pin number currently parsing
|
||||
string m_instModule; // Name of module referenced for instantiations
|
||||
AstPin* m_instParamp; // Parameters for instantiations
|
||||
AstNodeModule* m_modp; // Module
|
||||
int m_modTypeImpNum; // Implicit type number, incremented each module
|
||||
|
||||
static int s_modTypeImpNum; // Implicit type number, incremented each module
|
||||
|
||||
// CONSTRUCTORS
|
||||
V3ParseGrammar() {
|
||||
@@ -76,8 +76,6 @@ public:
|
||||
m_pinNum = -1;
|
||||
m_instModule = "";
|
||||
m_instParamp = NULL;
|
||||
m_modp = NULL;
|
||||
m_modTypeImpNum = 0;
|
||||
m_varAttrp = NULL;
|
||||
m_caseAttrp = NULL;
|
||||
}
|
||||
@@ -121,7 +119,6 @@ public:
|
||||
AstPackage* pkgp = SYMP->symRootp()->findIdFlat(AstPackage::dollarUnitName())->nodep()->castPackage();
|
||||
if (!pkgp) {
|
||||
pkgp = PARSEP->rootp()->dollarUnitPkgAddp();
|
||||
GRAMMARP->m_modp = pkgp; GRAMMARP->m_modTypeImpNum = 0;
|
||||
SYMP->reinsert(pkgp, SYMP->symRootp()); // Don't push/pop scope as they're global
|
||||
}
|
||||
return pkgp;
|
||||
@@ -167,6 +164,8 @@ public:
|
||||
const AstBasicDTypeKwd LOGIC = AstBasicDTypeKwd::LOGIC; // Shorthand "LOGIC"
|
||||
const AstBasicDTypeKwd LOGIC_IMPLICIT = AstBasicDTypeKwd::LOGIC_IMPLICIT;
|
||||
|
||||
int V3ParseGrammar::s_modTypeImpNum = 0;
|
||||
|
||||
//======================================================================
|
||||
// Macro functions
|
||||
|
||||
@@ -697,7 +696,6 @@ packageFront<modulep>:
|
||||
{ $$ = new AstPackage($1,*$2);
|
||||
$$->inLibrary(true); // packages are always libraries; don't want to make them a "top"
|
||||
$$->modTrace(v3Global.opt.trace());
|
||||
GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
|
||||
PARSEP->rootp()->addModulep($$);
|
||||
SYMP->pushNew($$); }
|
||||
;
|
||||
@@ -793,7 +791,6 @@ modFront<modulep>:
|
||||
yMODULE lifetimeE idAny
|
||||
{ $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine());
|
||||
$$->modTrace(v3Global.opt.trace());
|
||||
GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
|
||||
PARSEP->rootp()->addModulep($$);
|
||||
SYMP->pushNew($$); }
|
||||
;
|
||||
@@ -810,7 +807,6 @@ udpFront<modulep>:
|
||||
$$->modTrace(false);
|
||||
$$->addStmtp(new AstPragma($1,AstPragmaType::INLINE_MODULE));
|
||||
PARSEP->fileline()->tracingOn(false);
|
||||
GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
|
||||
PARSEP->rootp()->addModulep($$);
|
||||
SYMP->pushNew($$); }
|
||||
;
|
||||
@@ -845,8 +841,7 @@ paramPortDeclOrArgList<nodep>: // IEEE: list_of_param_assignments + { parameter_
|
||||
|
||||
paramPortDeclOrArg<nodep>: // IEEE: param_assignment + parameter_port_declaration
|
||||
// // We combine the two as we can't tell which follows a comma
|
||||
param_assignment { $$ = $1; }
|
||||
| parameter_port_declarationFront param_assignment { $$ = $2; }
|
||||
parameter_port_declarationFrontE param_assignment { $$ = $2; }
|
||||
;
|
||||
|
||||
portsStarE<nodep>: // IEEE: .* + list_of_ports + list_of_port_declarations + empty
|
||||
@@ -1029,7 +1024,6 @@ pgmFront<modulep>:
|
||||
yPROGRAM lifetimeE idAny/*new_program*/
|
||||
{ $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine());
|
||||
$$->modTrace(v3Global.opt.trace());
|
||||
GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
|
||||
PARSEP->rootp()->addModulep($$);
|
||||
SYMP->pushNew($$); }
|
||||
;
|
||||
@@ -1154,10 +1148,13 @@ parameter_declarationFront: // IEEE: parameter_declaration w/o assignment
|
||||
//UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
|
||||
;
|
||||
|
||||
parameter_port_declarationFront: // IEEE: parameter_port_declaration w/o assignment
|
||||
parameter_port_declarationFrontE: // IEEE: parameter_port_declaration w/o assignment
|
||||
// // IEEE: parameter_declaration (minus assignment)
|
||||
parameter_declarationFront { }
|
||||
//
|
||||
varGParamReset implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
|
||||
| varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
|
||||
| implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($1); }
|
||||
| data_type { /*VARRESET-in-varGParam*/ VARDTYPE($1); }
|
||||
//UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE($2); }
|
||||
//UNSUP data_type { VARDTYPE($1); }
|
||||
//UNSUP yTYPE { VARDTYPE($1); }
|
||||
;
|
||||
@@ -1344,10 +1341,10 @@ data_typeBasic<dtypep>: // IEEE: part of data_type
|
||||
|
||||
data_typeNoRef<dtypep>: // ==IEEE: data_type, excluding class_type etc references
|
||||
data_typeBasic { $$ = $1; }
|
||||
| struct_unionDecl packed_dimensionListE { $$ = GRAMMARP->createArray(new AstDefImplicitDType($1->fileline(),"__typeimpsu"+cvtToStr(GRAMMARP->m_modTypeImpNum++),
|
||||
GRAMMARP->m_modp,VFlagChildDType(),$1),$2,true); }
|
||||
| enumDecl { $$ = new AstDefImplicitDType($1->fileline(),"__typeimpenum"+cvtToStr(GRAMMARP->m_modTypeImpNum++),
|
||||
GRAMMARP->m_modp,VFlagChildDType(),$1); }
|
||||
| struct_unionDecl packed_dimensionListE { $$ = GRAMMARP->createArray(new AstDefImplicitDType($1->fileline(),"__typeimpsu"+cvtToStr(GRAMMARP->s_modTypeImpNum++),
|
||||
SYMP,VFlagChildDType(),$1),$2,true); }
|
||||
| enumDecl { $$ = new AstDefImplicitDType($1->fileline(),"__typeimpenum"+cvtToStr(GRAMMARP->s_modTypeImpNum++),
|
||||
SYMP,VFlagChildDType(),$1); }
|
||||
| ySTRING { $$ = new AstBasicDType($1,AstBasicDTypeKwd::STRING); }
|
||||
| yCHANDLE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::CHANDLE); }
|
||||
//UNSUP yEVENT { UNSUP }
|
||||
|
||||
@@ -673,7 +673,7 @@ sub compile {
|
||||
|
||||
if ($param{make_pli}) {
|
||||
$self->oprint("Compile vpi\n");
|
||||
my @cmd = ('g++', @{$param{pli_flags}}, "-DIS_VPI", "$self->{t_dir}/$self->{name}.cpp");
|
||||
my @cmd = ('c++', @{$param{pli_flags}}, "-DIS_VPI", "$self->{t_dir}/$self->{name}.cpp");
|
||||
|
||||
$self->_run(logfile=>"$self->{obj_dir}/pli_compile.log",
|
||||
fails=>$param{fails},
|
||||
|
||||
@@ -54,10 +54,10 @@ module t (/*AUTOARG*/
|
||||
if (cyc==0) begin
|
||||
// Setup
|
||||
crc <= 64'h5aef0c8d_d70a4497;
|
||||
sum <= 64'h0;
|
||||
sum <= '0;
|
||||
end
|
||||
else if (cyc<10) begin
|
||||
sum <= 64'h0;
|
||||
sum <= '0;
|
||||
end
|
||||
else if (cyc<90) begin
|
||||
end
|
||||
|
||||
@@ -33,7 +33,7 @@ module t (/*AUTOARG*/
|
||||
assert (0) else $info;
|
||||
assert (0) else $info("Info message");
|
||||
assert (0) else $info("Info message, cyc=%d", cyc);
|
||||
InWarningBlock: assert (0) else $warning("Warning....");
|
||||
InWarningBlock: assert (0) else $warning("Warning.... 1.0=%f 2.0=%f", 1.0, 2.0);
|
||||
InErrorBlock: assert (0) else $error("Error....");
|
||||
assert (0) else $fatal(1,"Fatal....");
|
||||
`endif
|
||||
|
||||
@@ -8,17 +8,17 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
# Version 2.0.
|
||||
|
||||
compile (
|
||||
verilator_flags2 => ["--stats --profile-cfuncs"],
|
||||
);
|
||||
verilator_flags2 => ["--stats"],
|
||||
);
|
||||
|
||||
if ($Self->{vlt}) {
|
||||
file_grep ($Self->{stats}, qr/Optimizations, Tables created\s+(\d+)/i, 10);
|
||||
file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 10);
|
||||
file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 9);
|
||||
}
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
#!/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");
|
||||
|
||||
top_filename("t/t_case_huge.v");
|
||||
|
||||
compile (
|
||||
verilator_flags2 => ["--stats --profile-cfuncs -CFLAGS '-pg' -LDFLAGS '-pg'"],
|
||||
);
|
||||
|
||||
if ($Self->{vlt}) {
|
||||
file_grep ($Self->{stats}, qr/Optimizations, Tables created\s+(\d+)/i, 10);
|
||||
file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 10);
|
||||
}
|
||||
|
||||
unlink $_ foreach (glob "$Self->{obj_dir}/gmon.out.*");
|
||||
$ENV{GMON_OUT_PREFIX} = "$Self->{obj_dir}/gmon.out";
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
my $gmon_path;
|
||||
$gmon_path = $_ foreach (glob "$Self->{obj_dir}/gmon.out.*");
|
||||
$gmon_path or $Self->error("Profiler did not create a gmon.out");
|
||||
(my $gmon_base = $gmon_path) =~ s!.*[/\\]!!;
|
||||
|
||||
$Self->_run(cmd=>["cd $Self->{obj_dir} && gprof $Self->{VM_PREFIX} $gmon_base > gprof.out"],
|
||||
check_finished=>0);
|
||||
|
||||
$Self->_run(cmd=>["cd $Self->{obj_dir} && $ENV{VERILATOR_ROOT}/bin/verilator_profcfunc gprof.out > cfuncs.out"],
|
||||
check_finished=>0);
|
||||
|
||||
file_grep ("$Self->{obj_dir}/cfuncs.out", qr/Overall summary by/);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -27,6 +27,7 @@ module sub (input integer inst);
|
||||
import "DPI-C" context function int dpic_line();
|
||||
import "DPI-C" context function int dpic_save(int value);
|
||||
import "DPI-C" context function int dpic_restore();
|
||||
import "DPI-C" context function int unsigned dpic_getcontext();
|
||||
|
||||
int result;
|
||||
|
||||
@@ -49,4 +50,17 @@ module sub (input integer inst);
|
||||
if (dpic_restore() != 23+inst) $stop;
|
||||
endtask
|
||||
|
||||
int unsigned cntxt1;
|
||||
int unsigned cntxt2;
|
||||
|
||||
initial begin
|
||||
cntxt1 = dpic_getcontext();
|
||||
begin : caller_context
|
||||
// call from a different scope - should still get the context of the function declaration
|
||||
cntxt2 = dpic_getcontext();
|
||||
end
|
||||
// svContext should be the context of the function declaration, not the context of the function call
|
||||
if (cntxt1 != cntxt2) $stop;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -42,6 +42,7 @@ extern "C" {
|
||||
extern int dpic_line();
|
||||
extern int dpic_save(int value);
|
||||
extern int dpic_restore();
|
||||
extern unsigned dpic_getcontext();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -126,3 +127,9 @@ int dpic_restore() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned dpic_getcontext() {
|
||||
svScope scope = svGetScope();
|
||||
printf("%%Info: svGetScope returned scope (%p) with name %s\n", scope, svGetNameFromScope(scope));
|
||||
return (unsigned) (uintptr_t) scope;
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
$Self->{vlt} or $Self->skip("Verilator only test");
|
||||
|
||||
$Self->_run (cmd=>["cd $Self->{obj_dir}"
|
||||
." && g++ -c ../../t/t_flag_ldflags_a.cpp"
|
||||
." && c++ -c ../../t/t_flag_ldflags_a.cpp"
|
||||
." && ar r t_flag_ldflags_a.a t_flag_ldflags_a.o"
|
||||
." && ranlib t_flag_ldflags_a.a "],
|
||||
check_finished=>0);
|
||||
$Self->_run (cmd=>["cd $Self->{obj_dir}"
|
||||
." && g++ -fPIC -c ../../t/t_flag_ldflags_so.cpp"
|
||||
." && g++ -shared -o t_flag_ldflags_so.so -lc t_flag_ldflags_so.o"],
|
||||
." && c++ -fPIC -c ../../t/t_flag_ldflags_so.cpp"
|
||||
." && c++ -shared -o t_flag_ldflags_so.so -lc t_flag_ldflags_so.o"],
|
||||
check_finished=>0);
|
||||
|
||||
compile (
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
`define is_near_real(a,b) ($abs((a)-(b)) < (((a)/(b))*0.0001))
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
|
||||
@@ -25,6 +25,7 @@ module t (/*AUTOARG*/
|
||||
|
||||
initial begin
|
||||
// Check constant propagation
|
||||
// Note $abs is not defined in SystemVerilog (as of 2012)
|
||||
check(`__LINE__, $ceil(-1.2), -1);
|
||||
check(`__LINE__, $ceil(1.2), 2);
|
||||
check(`__LINE__, $exp(1.2), 3.3201169227365472380597566370852291584014892578125);
|
||||
@@ -43,6 +44,7 @@ module t (/*AUTOARG*/
|
||||
//check(`__LINE__, $pow(-2.3,1.2),0); // Bad value
|
||||
check(`__LINE__, $sqrt(1.2), 1.095445115010332148841598609578795731067657470703125);
|
||||
//check(`__LINE__, $sqrt(-1.2), 0); // Bad value
|
||||
check(`__LINE__, ((1.5)**(1.25)), 1.660023);
|
||||
`ifndef VERILATOR
|
||||
check(`__LINE__, $acos (0.2), 1.369438406); // Arg1 is -1..1
|
||||
check(`__LINE__, $acosh(1.2), 0.622362503);
|
||||
|
||||
@@ -46,8 +46,8 @@ module m1;
|
||||
initial if (PACKED_PARAM != 8'h36) $stop;
|
||||
endmodule
|
||||
|
||||
module m2;
|
||||
parameter PAR2 = 10;
|
||||
// bug 810
|
||||
module m2 #(/*parameter*/ integer PAR2 = 10);
|
||||
initial begin
|
||||
$display("%x",PAR2);
|
||||
if (PAR2 !== 2) $stop;
|
||||
|
||||
Executable
+18
@@ -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 (
|
||||
v_flags2 => ["--lint-only"],
|
||||
verilator_make_gcc => 0,
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,26 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2013 by Wilson Snyder.
|
||||
|
||||
// Anonymous
|
||||
struct packed {
|
||||
logic [31:0] val1;
|
||||
logic [31:0] val2;
|
||||
} struct1;
|
||||
|
||||
struct packed {
|
||||
logic [31:0] val3;
|
||||
logic [31:0] val4;
|
||||
} struct2;
|
||||
|
||||
module t (
|
||||
output [63:0] s1,
|
||||
output [63:0] s2
|
||||
);
|
||||
initial struct1 = 64'h123456789_abcdef0;
|
||||
always_comb s1 = struct1;
|
||||
initial struct2 = 64'h123456789_abcdef0;
|
||||
always_comb s2 = struct2;
|
||||
endmodule
|
||||
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/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.
|
||||
|
||||
# Note: need to run at a higher optimization level to reproduce the issue
|
||||
$Self->{benchmark} = 1;
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,35 @@
|
||||
// DESCRIPTION: Verilator:
|
||||
// Test an error where a shift amount was out of bounds and the compiler treats the
|
||||
// value as undefined (Issue #803)
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2014 by Jeff Bush.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
struct packed {
|
||||
logic flag;
|
||||
logic [130:0] data;
|
||||
} foo[1];
|
||||
|
||||
integer cyc=0;
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
foo[0].data <= 0;
|
||||
foo[0].flag <= !foo[0].flag;
|
||||
if (cyc==10) begin
|
||||
if (foo[0].data != 0) begin
|
||||
$display("bad data value %x", foo[0].data);
|
||||
$stop;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2013 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 => ["--trace"],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,36 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2014 by Jonathon Donaldson.
|
||||
|
||||
package my_funcs;
|
||||
function automatic int simple_func (input int value);
|
||||
begin
|
||||
simple_func = value;
|
||||
end
|
||||
endfunction
|
||||
endpackage
|
||||
|
||||
package my_module_types;
|
||||
import my_funcs::*;
|
||||
|
||||
localparam MY_PARAM = 3;
|
||||
localparam MY_PARAM2 /*verilator public*/ = simple_func(12);
|
||||
endpackage
|
||||
|
||||
module t
|
||||
import my_module_types::*;
|
||||
(
|
||||
input i_clk,
|
||||
input [MY_PARAM-1:0] i_d,
|
||||
output logic [MY_PARAM-1:0] o_q
|
||||
);
|
||||
|
||||
always_ff @(posedge i_clk)
|
||||
o_q <= i_d;
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Executable
+18
@@ -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;
|
||||
@@ -0,0 +1,102 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// Use this file as a template for submitting bugs, etc.
|
||||
// This module takes a single clock input, and should either
|
||||
// $write("*-* All Finished *-*\n");
|
||||
// $finish;
|
||||
// on success, or $stop.
|
||||
//
|
||||
// The code as shown applies a random vector to the Test
|
||||
// module, then calculates a CRC on the Test module's outputs.
|
||||
//
|
||||
// **If you do not wish for your code to be released to the public
|
||||
// please note it here, otherwise:**
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2014 by ____YOUR_NAME_HERE____.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
integer cyc=0;
|
||||
reg [63:0] crc;
|
||||
reg [255:0] sum;
|
||||
|
||||
// Take CRC data and apply to testblock inputs
|
||||
wire [127:0] in = {~crc[63:0], crc[63:0]};
|
||||
|
||||
/*AUTOWIRE*/
|
||||
// Beginning of automatic wires (for undeclared instantiated-module outputs)
|
||||
wire [127:0] o1; // From test of Test.v
|
||||
wire [127:0] o2; // From test of Test.v
|
||||
// End of automatics
|
||||
|
||||
Test test (/*AUTOINST*/
|
||||
// Outputs
|
||||
.o1 (o1[127:0]),
|
||||
.o2 (o2[127:0]),
|
||||
// Inputs
|
||||
.in (in[127:0]));
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("[%0t] cyc==%0d crc=%x result=%x %x\n",$time, cyc, crc, o1, o2);
|
||||
`endif
|
||||
cyc <= cyc + 1;
|
||||
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
|
||||
sum <= {o1,o2} ^ {sum[254:0],sum[255]^sum[2]^sum[0]};
|
||||
if (cyc==0) begin
|
||||
// Setup
|
||||
crc <= 64'h5aef0c8d_d70a4497;
|
||||
sum <= '0;
|
||||
end
|
||||
else if (cyc<10) begin
|
||||
sum <= '0;
|
||||
end
|
||||
else if (cyc<90) begin
|
||||
end
|
||||
else if (cyc==99) begin
|
||||
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
|
||||
if (crc !== 64'hc77bb9b3784ea091) $stop;
|
||||
// What checksum will we end up with (above print should match)
|
||||
`define EXPECTED_SUM 256'h008a080aaa000000140550404115dc7b008a080aaae7c8cd897bc1ca49c9350a
|
||||
if (sum !== `EXPECTED_SUM) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module Test (/*AUTOARG*/
|
||||
// Outputs
|
||||
o1, o2,
|
||||
// Inputs
|
||||
in
|
||||
);
|
||||
|
||||
input [127:0] in;
|
||||
output logic [127:0] o1;
|
||||
output logic [127:0] o2;
|
||||
|
||||
always_comb begin: b_test
|
||||
logic [127:0] tmpp;
|
||||
logic [127:0] tmp;
|
||||
tmp = '0;
|
||||
tmpp = '0;
|
||||
|
||||
tmp[63:0] = in[63:0];
|
||||
tmpp[63:0] = in[63:0];
|
||||
|
||||
tmpp[63:0] = {tmp[0+:32], tmp[32+:32]};
|
||||
tmp[63:0] = {tmp[0+:32], tmp[32+:32]};
|
||||
|
||||
o1 = tmp;
|
||||
o2 = tmpp;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -152,7 +152,7 @@ struct params {
|
||||
unsigned int size;
|
||||
unsigned int direction;
|
||||
unsigned int scalar;
|
||||
unsigned int type;
|
||||
int type;
|
||||
} attributes, children;
|
||||
} values[] = {
|
||||
{"onebit", {1, vpiNoDirection, 1, vpiReg}, {0, 0, 0, 0}},
|
||||
|
||||
@@ -133,7 +133,7 @@ int _mon_check_memory() {
|
||||
// iterate and store
|
||||
iter_h = vpi_iterate(vpiMemoryWord, mem_h);
|
||||
cnt = 0;
|
||||
while (lcl_h = vpi_scan(iter_h)) {
|
||||
while ((lcl_h = vpi_scan(iter_h))) {
|
||||
value.value.integer = ++cnt;
|
||||
vpi_put_value(lcl_h, &value, NULL, vpiNoDelay);
|
||||
// check size and range
|
||||
@@ -143,7 +143,7 @@ int _mon_check_memory() {
|
||||
// iterate and accumulate
|
||||
iter_h = vpi_iterate(vpiMemoryWord, mem_h);
|
||||
cnt = 0;
|
||||
while (lcl_h = vpi_scan(iter_h)) {
|
||||
while ((lcl_h = vpi_scan(iter_h))) {
|
||||
++cnt;
|
||||
vpi_get_value(lcl_h, &value);
|
||||
CHECK_RESULT(value.value.integer, cnt);
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 885 B |
Reference in New Issue
Block a user