Fix initial values for local variables, bug210
This commit is contained in:
parent
295faf726b
commit
4360fe492e
|
|
@ -77,6 +77,7 @@ private:
|
|||
int m_beginNum; // Begin block number, 0=none seen
|
||||
int m_modBeginNum; // Begin block number in module, 0=none seen
|
||||
bool m_inGenerate; // Inside a generate
|
||||
AstNodeModule* m_valueModp; // If set, move AstVar->valuep() initial values to this module
|
||||
vector<V3SymTable*> m_delSymps; // Symbol tables to delete
|
||||
|
||||
static int debug() {
|
||||
|
|
@ -223,6 +224,7 @@ private:
|
|||
V3SymTable* upperVarsp = m_curVarsp;
|
||||
{
|
||||
m_modp = nodep;
|
||||
m_valueModp = nodep;
|
||||
if (!m_curVarsp) nodep->v3fatalSrc("NULL");
|
||||
if (nodep->castPackage()) m_packagep = nodep->castPackage();
|
||||
if (m_packagep && m_packagep->isDollarUnit()) { // $unit goes on "top"
|
||||
|
|
@ -242,6 +244,7 @@ private:
|
|||
nodep->iterateChildren(*this);
|
||||
// Prep for next
|
||||
m_modp = NULL;
|
||||
m_valueModp = NULL;
|
||||
m_packagep = NULL;
|
||||
}
|
||||
m_curVarsp = upperVarsp;
|
||||
|
|
@ -314,6 +317,24 @@ private:
|
|||
if (nodep->isIO() && !m_ftaskp && !nodep->user2()) {
|
||||
nodep->v3error("Input/output/inout does not appear in port list: "<<nodep->prettyName());
|
||||
}
|
||||
if (nodep->valuep()) {
|
||||
// A variable with a = value can be three things:
|
||||
FileLine* fl = nodep->valuep()->fileline();
|
||||
// 1. Parameters and function inputs: It's a default to use if not overridden
|
||||
if (nodep->isParam() || nodep->isInOnly()) {
|
||||
// 2. Under modules, it's an initial value to be loaded at time 0 via an AstInitial
|
||||
} else if (m_valueModp) {
|
||||
nodep->addNextHere
|
||||
(new AstInitial (fl, new AstAssign (fl,
|
||||
new AstVarRef(fl, nodep, true),
|
||||
nodep->valuep()->unlinkFrBack())));
|
||||
// 3. Under blocks, it's an initial value to be under an assign
|
||||
} else {
|
||||
nodep->addNextHere
|
||||
(new AstAssign (fl, new AstVarRef(fl, nodep, true),
|
||||
nodep->valuep()->unlinkFrBack()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
|
|
@ -367,7 +388,10 @@ private:
|
|||
if (!m_curVarsp) nodep->v3fatalSrc("Function/Task not under module??\n");
|
||||
// Remember the existing symbol table scope
|
||||
V3SymTable* upperVarsp = m_curVarsp;
|
||||
AstNodeModule* upperValueModp = m_valueModp;
|
||||
{
|
||||
m_valueModp = NULL;
|
||||
|
||||
// Create symbol table for the task's vars
|
||||
m_curVarsp = symsFindNew(nodep, upperVarsp);
|
||||
|
||||
|
|
@ -395,6 +419,7 @@ private:
|
|||
m_ftaskp = NULL;
|
||||
}
|
||||
m_curVarsp = upperVarsp;
|
||||
m_valueModp = upperValueModp;
|
||||
if (m_idState==ID_FIND) {
|
||||
findAndInsertAndCheck(nodep, nodep->name());
|
||||
}
|
||||
|
|
@ -660,6 +685,26 @@ private:
|
|||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
}
|
||||
|
||||
void visitIterateNoValueMod(AstNode* nodep) {
|
||||
// Iterate a node which shouldn't have any local variables moved to an Initial
|
||||
AstNodeModule* upperValueModp = m_valueModp;
|
||||
m_valueModp = NULL;
|
||||
nodep->iterateChildren(*this);
|
||||
m_valueModp = upperValueModp;
|
||||
}
|
||||
virtual void visit(AstInitial* nodep, AstNUser*) {
|
||||
visitIterateNoValueMod(nodep);
|
||||
}
|
||||
virtual void visit(AstFinal* nodep, AstNUser*) {
|
||||
visitIterateNoValueMod(nodep);
|
||||
}
|
||||
virtual void visit(AstAlways* nodep, AstNUser*) {
|
||||
visitIterateNoValueMod(nodep);
|
||||
}
|
||||
virtual void visit(AstPslCover* nodep, AstNUser*) {
|
||||
visitIterateNoValueMod(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
// Default: Just iterate
|
||||
nodep->iterateChildren(*this);
|
||||
|
|
@ -678,6 +723,7 @@ public:
|
|||
m_beginNum = 0;
|
||||
m_modBeginNum = 0;
|
||||
m_inGenerate = false;
|
||||
m_valueModp = NULL;
|
||||
//
|
||||
rootp->accept(*this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,11 +96,6 @@ public:
|
|||
nodep->addNext(new AstStop(fileline));
|
||||
return nodep;
|
||||
}
|
||||
AstNode* newVarInit(FileLine* fileline, AstNode* varp, AstNode* initp) {
|
||||
return new AstInitial(fileline, new AstAssign(fileline,
|
||||
new AstVarRef(fileline, varp->name(),true),
|
||||
initp));
|
||||
}
|
||||
void setDType(AstNodeDType* dtypep) {
|
||||
if (m_varDTypep) { m_varDTypep->deleteTree(); m_varDTypep=NULL; } // It was cloned, so this is safe.
|
||||
m_varDTypep = dtypep;
|
||||
|
|
@ -817,13 +812,13 @@ port<nodep>: // ==IEEE: port
|
|||
{ $$=$2; /*VARDTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); }
|
||||
//
|
||||
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
|
||||
{ $$=$3; VARDTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); $$->addNextNull(GRAMMARP->newVarInit($6,$$,$7)); }
|
||||
{ $$=$3; VARDTYPE($2); AstVar* vp=VARDONEP($$,$4,$5); $$->addNextNull(vp); vp->valuep($7); }
|
||||
| portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
|
||||
{ $$=$3; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); $$->addNextNull(GRAMMARP->newVarInit($7,$$,$8)); }
|
||||
{ $$=$3; VARDTYPE($3); AstVar* vp=VARDONEP($$,$5,$6); $$->addNextNull(vp); vp->valuep($8); }
|
||||
| portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE '=' constExpr
|
||||
{ $$=$3; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); $$->addNextNull(GRAMMARP->newVarInit($7,$$,$8)); }
|
||||
{ $$=$3; VARDTYPE($3); AstVar* vp=VARDONEP($$,$5,$6); $$->addNextNull(vp); vp->valuep($8); }
|
||||
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr
|
||||
{ $$=$3; /*VARDTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); $$->addNextNull(GRAMMARP->newVarInit($5,$$,$6)); }
|
||||
{ $$=$3; /*VARDTYPE-same*/ AstVar* vp=VARDONEP($$,$3,$4); $$->addNextNull(vp); vp->valuep($6); }
|
||||
;
|
||||
|
||||
portDirNetE: // IEEE: part of port, optional net type and/or direction
|
||||
|
|
@ -1115,8 +1110,7 @@ variable_decl_assignment<varp>: // ==IEEE: variable_decl_assignment
|
|||
id variable_dimensionListE sigAttrListE
|
||||
{ $$ = VARDONEA(*$1,$2,$3); }
|
||||
| id variable_dimensionListE sigAttrListE '=' variable_declExpr
|
||||
{ $$ = VARDONEA(*$1,$2,$3);
|
||||
$$->addNext(new AstInitial($4,new AstAssign($4, new AstVarRef($4, *$1, true), $5))); }
|
||||
{ $$ = VARDONEA(*$1,$2,$3); $$->valuep($5); }
|
||||
| idSVKwd { $$ = NULL; }
|
||||
//
|
||||
// // IEEE: "dynamic_array_variable_identifier '[' ']' [ '=' dynamic_array_new ]"
|
||||
|
|
@ -2195,7 +2189,7 @@ tf_item_declarationVerilator<nodep>: // Verilator extensions
|
|||
tf_port_listE<nodep>: // IEEE: tf_port_list + empty
|
||||
// // Empty covered by tf_port_item
|
||||
{VARRESET_LIST(UNKNOWN); VARIO(INPUT); }
|
||||
tf_port_listList { $$ = $2; VARRESET_NONLIST(UNKNOWN); }
|
||||
tf_port_listList { $$ = $2; VARRESET_NONLIST(UNKNOWN); }
|
||||
;
|
||||
|
||||
tf_port_listList<nodep>: // IEEE: part of tf_port_list
|
||||
|
|
|
|||
|
|
@ -6,20 +6,32 @@
|
|||
module t;
|
||||
|
||||
integer top;
|
||||
integer top_assign=1;
|
||||
|
||||
task automatic tsk;
|
||||
integer task_assign = 1;
|
||||
if (task_assign != 1) $stop;
|
||||
task_assign = 2;
|
||||
if (task_assign != 2) $stop;
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
begin : a
|
||||
integer lower;
|
||||
integer lower_assign=1;
|
||||
lower = 1;
|
||||
top = 1;
|
||||
if (lower != 1) $stop;
|
||||
if (lower_assign != 1) $stop;
|
||||
begin : aa
|
||||
integer lev2;
|
||||
lev2 = 1;
|
||||
lower = 2;
|
||||
lower_assign = 2;
|
||||
top = 2;
|
||||
end
|
||||
if (lower != 2) $stop;
|
||||
if (lower_assign != 2) $stop;
|
||||
end
|
||||
begin : b
|
||||
integer lower;
|
||||
|
|
@ -30,6 +42,8 @@ module t;
|
|||
end
|
||||
end
|
||||
end
|
||||
tsk;
|
||||
tsk; // Second time to insure we reinit the initial value
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue