From 957f495314d73fd2e42e3b88d55c2891b40ed2f2 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 28 Mar 2008 21:55:23 +0000 Subject: [PATCH] Fix task output pin connected to non-variables. git-svn-id: file://localhost/svn/verilator/trunk/verilator@1016 77ca24e4-aefa-0310-84f0-b9a241c72d87 --- Changes | 2 ++ src/V3LinkLValue.cpp | 14 ++++++++++---- src/V3LinkLValue.h | 1 + src/V3Task.cpp | 31 +++++++++++++++++++++---------- test_regress/t/t_func.v | 17 +++++++++++++---- test_regress/t/t_func_bad.pl | 1 - 6 files changed, 47 insertions(+), 19 deletions(-) diff --git a/Changes b/Changes index ccdebeccb..8e59fb571 100644 --- a/Changes +++ b/Changes @@ -19,6 +19,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix dropping of backslash quoted-quote at end of $display. +**** Fix task output pin connected to non-variables. [Jonathan Kimmitt] + **** Fix missing test_v in install datadir. [Holger Waechtler] * Verilator 3.660 2008/03/23 diff --git a/src/V3LinkLValue.cpp b/src/V3LinkLValue.cpp index 86eb241d5..ddac1cce7 100644 --- a/src/V3LinkLValue.cpp +++ b/src/V3LinkLValue.cpp @@ -166,10 +166,10 @@ private: public: // CONSTUCTORS - LinkLValueVisitor(AstNetlist* rootp) { - m_setRefLvalue = false; + LinkLValueVisitor(AstNode* nodep, bool start) { + m_setRefLvalue = start; m_ftaskp = NULL; - rootp->accept(*this); + nodep->accept(*this); } virtual ~LinkLValueVisitor() {} }; @@ -179,5 +179,11 @@ public: void V3LinkLValue::linkLValue(AstNetlist* rootp) { UINFO(4,__FUNCTION__<<": "<isOutput()) { // Make output variables // Correct lvalue; we didn't know when we linked - if (AstVarRef* varrefp = pinp->castVarRef()) { - varrefp->lvalue(true); - } else { - pinp->v3warn(TASKNSVAR,"Unsupported: Task output pin connected to non-variable"); - } + // This is slightly scary; are we sure no decisions were made + // before here based on this not being a lvalue? + // Doesn't seem so; V3Unknown uses it earlier, but works ok. + V3LinkLValue::linkLValueSet(pinp); + // Even if it's referencing a varref, we still make a temporary // Else task(x,x,x) might produce incorrect results AstVarScope* outvscp = createVarScope (portp, namePrefix+"__"+portp->shortName()); @@ -445,11 +446,21 @@ private: else if (portp->isOutput()) { // Make output variables // Correct lvalue; we didn't know when we linked - if (AstVarRef* varrefp = pinp->castVarRef()) { - varrefp->lvalue(true); - } else { - pinp->v3warn(TASKNSVAR,"Unsupported: Task output pin connected to non-variable"); - } + // This is slightly scary; are we sure no decisions were made + // before here based on this not being a lvalue? + // Doesn't seem so; V3Unknown uses it earlier, but works ok. + V3LinkLValue::linkLValueSet(pinp); + + // Even if it's referencing a varref, we still make a temporary + // Else task(x,x,x) might produce incorrect results + AstVarScope* outvscp = createVarScope (portp, namePrefix+"__"+portp->shortName()); + portp->user2p(outvscp); + pinp->replaceWith(new AstVarRef(outvscp->fileline(), outvscp, true)); + AstAssign* assp = new AstAssign (pinp->fileline(), + pinp, + new AstVarRef(outvscp->fileline(), outvscp, false)); + // Put assignment BEHIND of all other statements + beginp->addNext(assp); } } } diff --git a/test_regress/t/t_func.v b/test_regress/t/t_func.v index 0d353d0ff..8066959c6 100644 --- a/test_regress/t/t_func.v +++ b/test_regress/t/t_func.v @@ -7,6 +7,7 @@ module t; reg [2:0] value; reg [31:0] global; + reg [31:0] vec [1:0]; initial begin global = 1; @@ -32,14 +33,22 @@ module t; nil_task(32'h012,32'h112,global); if (global !== 32'h124) $stop; + vec[0] = 32'h333; + vec[1] = 32'habc; + incr(vec[1],vec[0],vec[1]); + if (vec[0] != 32'h333) $stop; + if (vec[1] != 32'hdef) $stop; + + incr(vec[2],vec[0],vec[2]); // Reading/Writing past end of vector! + $write("*-* All Finished *-*\n"); $finish; end function [2:0] add; - input [2:0] from; + input [2:0] fromv; begin - add = from + 3'd1; + add = fromv + 3'd1; begin : named reg [31:0] flocal; flocal = 1; @@ -49,13 +58,13 @@ module t; endfunction function [3:0] munge4; - input [3:0] from; // Different from the 'from' signal above + input [3:0] fromv; // Different fromv than the 'fromv' signal above reg one; begin : named reg [1:0] flocal; // Function calling a function one = 1'b1; - munge4 = {one, add(from[2:0])}; + munge4 = {one, add(fromv[2:0])}; end endfunction diff --git a/test_regress/t/t_func_bad.pl b/test_regress/t/t_func_bad.pl index 2aef402f8..5077610ac 100755 --- a/test_regress/t/t_func_bad.pl +++ b/test_regress/t/t_func_bad.pl @@ -14,7 +14,6 @@ compile ( '%Error: t/t_func_bad.v:\d+: Too few arguments in function call %Error: t/t_func_bad.v:\d+: Too many arguments in function call %Error: t/t_func_bad.v:\d+: Too few arguments in function call -%Error-TASKNSVAR: t/t_func_bad.v:\d+: Unsupported: Task output pin connected to non-variable %Error: t/t_func_bad.v:\d+: Outputs not allowed in function declarations %Error: Exiting due to', );