diff --git a/Changes b/Changes index 05de8d4da..003312343 100644 --- a/Changes +++ b/Changes @@ -9,7 +9,7 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix isolate_assignments when many signals per always. [Mike Shinkarovsky] -**** Fix isolate_assignments across task temporaries. [Mike Shinkarovsky] +**** Fix isolate_assignments across task/func temporaries. [Mike Shinkarovsky] * Verilator 3.632 1/17/2007 diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 16ce01159..24f82468d 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -814,10 +814,13 @@ struct AstTask : public AstNodeFTask { }; struct AstFunc : public AstNodeFTask { + bool m_attrIsolateAssign:1;// User isolate_assignments attribute +public: // A function inside a module AstFunc(FileLine* fl, const string& name, AstNode* stmtp, AstNode* fvarsp) :AstNodeFTask(fl, name, stmtp) { addNOp1p(fvarsp); + m_attrIsolateAssign = false; } virtual ~AstFunc() {} virtual AstType type() const { return AstType::FUNC;} @@ -826,6 +829,8 @@ struct AstFunc : public AstNodeFTask { // op1 = Range output variable (functions only) AstNode* fvarp() const { return op1p()->castNode(); } void addFvarp(AstNode* nodep) { addOp1p(nodep); } + void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; } + bool attrIsolateAssign() const { return m_attrIsolateAssign; } }; struct AstTaskRef : public AstNodeFTaskRef { diff --git a/src/V3Link.cpp b/src/V3Link.cpp index 8dbbb4693..11bdd64c9 100644 --- a/src/V3Link.cpp +++ b/src/V3Link.cpp @@ -220,6 +220,8 @@ private: nodep->userp(m_curVarsp); } // Convert the func's range to the output variable + // This should probably be done in the Parser instead, as then we could + // just attact normal signal attributes to it. if (AstFunc* funcp = nodep->castFunc()) { if (!funcp->fvarp()->castVar()) { AstRange* rangep = funcp->fvarp()->castRange(); @@ -228,6 +230,7 @@ private: newvarp->isSigned(funcp->isSigned()); newvarp->funcReturn(true); newvarp->trace(false); // Not user visible + newvarp->attrIsolateAssign(funcp->attrIsolateAssign()); funcp->addFvarp(newvarp); // Explicit insert required, as the var name shadows the upper level's task name m_curVarsp->insert(newvarp->name(), newvarp); diff --git a/src/verilog.y b/src/verilog.y index ce6107da1..be06ea8c2 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -104,6 +104,7 @@ class AstSenTree; AstCase* casep; AstCaseItem* caseitemp; AstConst* constp; + AstFunc* funcp; AstFuncRef* funcrefp; AstModule* modulep; AstPin* pinp; @@ -246,7 +247,9 @@ class AstSenTree; %type idDotted %type strAsInt strAsText concIdList %type taskDecl -%type varDeclList funcDecl funcVarList funcVar +%type varDeclList +%type funcDecl +%type funcBody funcVarList funcVar %type funcRange %type gateDecl %type gateBufList gateNotList gateAndList gateNandList @@ -713,8 +716,13 @@ taskDecl: yTASK yID ';' stmtBlock yENDTASK { $$ = new AstTask ($1,* | yTASK yID ';' funcVarList stmtBlock yENDTASK { $$ = new AstTask ($1,*$2,$4); $4->addNextNull($5); } ; -funcDecl: yFUNCTION funcRange yID ';' funcVarList stmtBlock yENDFUNCTION { $$ = new AstFunc ($1,*$3,$5,$2); $5->addNextNull($6);} - | yFUNCTION ySIGNED funcRange yID ';' funcVarList stmtBlock yENDFUNCTION { $$ = new AstFunc ($1,*$4,$6,$3); $6->addNextNull($7); $$->isSigned(true); } +funcDecl: yFUNCTION funcRange yID ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$3,$5,$2); } + | yFUNCTION ySIGNED funcRange yID ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$4,$6,$3); $$->isSigned(true); } + | yFUNCTION funcRange yID yVL_ISOLATE_ASSIGNMENTS ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$3,$6,$2); $$->attrIsolateAssign(true);} + | yFUNCTION ySIGNED funcRange yID yVL_ISOLATE_ASSIGNMENTS ';' funcBody yENDFUNCTION { $$ = new AstFunc ($1,*$4,$7,$3); $$->attrIsolateAssign(true); $$->isSigned(true); } + ; + +funcBody: funcVarList stmtBlock { $$ = $1;$1->addNextNull($2); } ; funcRange: '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); } diff --git a/test_regress/t/t_unopt_combo.v b/test_regress/t/t_unopt_combo.v index 948d10ed1..56e90998c 100644 --- a/test_regress/t/t_unopt_combo.v +++ b/test_regress/t/t_unopt_combo.v @@ -82,7 +82,7 @@ module file (/*AUTOARG*/ // Note that while c and b depend on crc, b doesn't depend on c. casez (crc[3:0]) 4'b??01: begin - b = {crc[15:0],crc[31:16]}; + b = {crc[15:0],get_31_16(crc)}; d = c; end 4'b??00: begin @@ -95,6 +95,11 @@ module file (/*AUTOARG*/ endcase end + function [31:16] get_31_16 /* verilator isolate_assignments*/; + input [31:0] t_crc /* verilator isolate_assignments*/; + get_31_16 = t_crc[31:16]; + endfunction + task set_b_d; `ifdef ISOLATE input [31:0] t_crc /* verilator isolate_assignments*/; diff --git a/test_regress/t/t_unopt_combo_isolate.pl b/test_regress/t/t_unopt_combo_isolate.pl index d88c987f7..4c5021b57 100755 --- a/test_regress/t/t_unopt_combo_isolate.pl +++ b/test_regress/t/t_unopt_combo_isolate.pl @@ -14,7 +14,7 @@ compile ( ); if ($Last_Self->{v3}) { - file_grep ($Last_Self->{stats}, qr/Optimizations, isolate_assignments blocks\s+3/i); + file_grep ($Last_Self->{stats}, qr/Optimizations, isolate_assignments blocks\s+5/i); } execute (