forked from github/verilator
Fix internal error on xrefs into unrolled functions, bug1387.
This commit is contained in:
parent
aaf5b7c2c0
commit
62a7d713a7
2
Changes
2
Changes
@ -19,6 +19,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
**** Fix uninitialized data in verFiles and unroller, bug1385. bug1386. [Al Grant]
|
||||
|
||||
**** Fix internal error on xrefs into unrolled functions, bug1387. [Al Grant]
|
||||
|
||||
|
||||
* Verilator 4.008 2018-12-01
|
||||
|
||||
|
@ -452,10 +452,10 @@ implementation is not found, the system will look in turn for overloaded
|
||||
implementations up the inheritance hierarchy. For example calling C<accept>
|
||||
on C<AstIf> will look in turn for:
|
||||
|
||||
void visit (AstIf* nodep)
|
||||
void visit (AstNodeIf* nodep)
|
||||
void visit (AstNodeStmt* nodep)
|
||||
void visit (AstNode* nodep)
|
||||
void visit(AstIf* nodep)
|
||||
void visit(AstNodeIf* nodep)
|
||||
void visit(AstNodeStmt* nodep)
|
||||
void visit(AstNode* nodep)
|
||||
|
||||
There are three ways data is passed between visitor functions.
|
||||
|
||||
|
@ -1642,6 +1642,7 @@ public:
|
||||
: AstNode(fl) {}
|
||||
ASTNODE_BASE_FUNCS(NodeStmt)
|
||||
// METHODS
|
||||
virtual bool isStatement() const { return true; } // Really a statement
|
||||
virtual void addNextStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here
|
||||
virtual void addBeforeStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here
|
||||
};
|
||||
@ -2067,8 +2068,9 @@ public:
|
||||
bool pure() const { return m_pure; }
|
||||
};
|
||||
|
||||
class AstNodeFTaskRef : public AstNode {
|
||||
class AstNodeFTaskRef : public AstNodeStmt {
|
||||
// A reference to a task (or function)
|
||||
// Functions are not statements, while tasks are. AstNodeStmt needs isStatement() to deal.
|
||||
private:
|
||||
AstNodeFTask* m_taskp; // [AfterLink] Pointer to task referenced
|
||||
string m_name; // Name of variable
|
||||
@ -2077,12 +2079,12 @@ private:
|
||||
AstPackage* m_packagep; // Package hierarchy
|
||||
public:
|
||||
AstNodeFTaskRef(FileLine* fl, AstNode* namep, AstNode* pinsp)
|
||||
: AstNode(fl)
|
||||
: AstNodeStmt(fl)
|
||||
, m_taskp(NULL), m_packagep(NULL) {
|
||||
setOp1p(namep); addNOp2p(pinsp);
|
||||
}
|
||||
AstNodeFTaskRef(FileLine* fl, const string& name, AstNode* pinsp)
|
||||
: AstNode(fl)
|
||||
: AstNodeStmt(fl)
|
||||
, m_taskp(NULL), m_name(name), m_packagep(NULL) {
|
||||
addNOp2p(pinsp);
|
||||
}
|
||||
|
@ -2026,6 +2026,7 @@ public:
|
||||
AstTaskRef(FileLine* fl, const string& name, AstNode* pinsp)
|
||||
:AstNodeFTaskRef(fl, name, pinsp) {}
|
||||
ASTNODE_NODE_FUNCS(TaskRef)
|
||||
virtual bool isStatement() const { return true; } // A statement, unlike FuncRef
|
||||
};
|
||||
|
||||
class AstFuncRef : public AstNodeFTaskRef {
|
||||
@ -2036,6 +2037,7 @@ public:
|
||||
AstFuncRef(FileLine* fl, const string& name, AstNode* pinsp)
|
||||
:AstNodeFTaskRef(fl, name, pinsp) {}
|
||||
ASTNODE_NODE_FUNCS(FuncRef)
|
||||
virtual bool isStatement() const { return false; } // Not a statement, unlike TaskRef
|
||||
virtual bool hasDType() const { return true; }
|
||||
};
|
||||
|
||||
|
@ -273,6 +273,10 @@ class GaterBodyVisitor : public GaterBaseVisitor {
|
||||
// (We may get empty IFs but the constant propagater will rip them up for us)
|
||||
|
||||
virtual void visit(AstNodeStmt* nodep) {
|
||||
if (!nodep->isStatement()) {
|
||||
iterateChildren(nodep);
|
||||
return;
|
||||
}
|
||||
uint32_t oldstate = m_state;
|
||||
// Find if children want to delete this or not.
|
||||
// Note children may bicker, and want to both keep and delete (branches on a if)
|
||||
|
@ -433,6 +433,10 @@ private:
|
||||
m_funcp = NULL;
|
||||
}
|
||||
virtual void visit(AstNodeStmt* nodep) {
|
||||
if (!nodep->isStatement()) {
|
||||
iterateChildren(nodep);
|
||||
return;
|
||||
}
|
||||
if (m_state == STATE_HASH && m_funcp) {
|
||||
hashStatement(nodep);
|
||||
}
|
||||
|
@ -102,7 +102,11 @@ private:
|
||||
m_stmtp = NULL;
|
||||
}
|
||||
virtual void visit(AstNodeStmt* nodep) {
|
||||
visitStmt(nodep);
|
||||
if (!nodep->isStatement()) {
|
||||
iterateChildren(nodep);
|
||||
} else {
|
||||
visitStmt(nodep);
|
||||
}
|
||||
}
|
||||
// Operators
|
||||
virtual void visit(AstNodeTermop* nodep) {
|
||||
|
@ -107,7 +107,11 @@ private:
|
||||
m_depth--;
|
||||
}
|
||||
virtual void visit(AstNodeStmt* nodep) {
|
||||
visitStmt(nodep);
|
||||
if (!nodep->isStatement()) {
|
||||
iterateChildren(nodep);
|
||||
} else {
|
||||
visitStmt(nodep);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeMath* nodep) {} // Accelerate
|
||||
|
@ -871,6 +871,10 @@ private:
|
||||
|
||||
virtual void visit(AstNodeStmt* nodep) {
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
if (!nodep->isStatement()) {
|
||||
iterateChildren(nodep);
|
||||
return;
|
||||
}
|
||||
m_stmtp = nodep;
|
||||
iterateChildren(nodep);
|
||||
m_stmtp = NULL;
|
||||
|
@ -241,8 +241,12 @@ private:
|
||||
m_stmtp = NULL;
|
||||
}
|
||||
virtual void visit(AstNodeStmt* nodep) {
|
||||
UINFO(4," STMT "<<nodep<<endl);
|
||||
startStatement(nodep);
|
||||
if (!nodep->isStatement()) {
|
||||
iterateChildren(nodep);
|
||||
return;
|
||||
}
|
||||
UINFO(4," STMT "<<nodep<<endl);
|
||||
startStatement(nodep);
|
||||
iterateChildren(nodep);
|
||||
m_stmtp = NULL;
|
||||
}
|
||||
|
@ -96,6 +96,10 @@ private:
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeStmt* nodep) {
|
||||
if (!nodep->isStatement()) {
|
||||
iterateChildren(nodep);
|
||||
return;
|
||||
}
|
||||
UINFO(6," CL STMT "<<nodep<<endl);
|
||||
bool oldKeep = m_keepStmt;
|
||||
{
|
||||
|
@ -1256,6 +1256,10 @@ private:
|
||||
nodep->v3fatalSrc("For statements should have been converted to while statements in V3Begin.cpp");
|
||||
}
|
||||
virtual void visit(AstNodeStmt* nodep) {
|
||||
if (!nodep->isStatement()) {
|
||||
iterateChildren(nodep);
|
||||
return;
|
||||
}
|
||||
m_insMode = IM_BEFORE;
|
||||
m_insStmtp = nodep;
|
||||
iterateChildren(nodep);
|
||||
|
@ -135,10 +135,10 @@ private:
|
||||
new AstVarRef(fl, varp, false)))),
|
||||
NULL);
|
||||
newp->branchPred(AstBranchPred::BP_LIKELY);
|
||||
if (debug()>=9) newp->dumpTree(cout," _new: ");
|
||||
abovep->addNextStmt(newp,abovep);
|
||||
prep->user2p(newp); // Save so we may LogAnd it next time
|
||||
}
|
||||
if (debug()>=9) newp->dumpTree(cout," _new: ");
|
||||
abovep->addNextStmt(newp, abovep);
|
||||
prep->user2p(newp); // Save so we may LogAnd it next time
|
||||
}
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
|
20
test_regress/t/t_func_unit.pl
Executable file
20
test_regress/t/t_func_unit.pl
Executable file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2019 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
23
test_regress/t/t_func_unit.v
Normal file
23
test_regress/t/t_func_unit.v
Normal file
@ -0,0 +1,23 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2019 by Wilson Snyder.
|
||||
|
||||
task tsk(output fo);
|
||||
assign fo = 1'b0;
|
||||
endtask
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Outputs
|
||||
to
|
||||
);
|
||||
output to[2:0];
|
||||
|
||||
integer i = 0;
|
||||
|
||||
initial begin
|
||||
tsk(to[i]);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user