Fix task output pin connected to non-variables.

git-svn-id: file://localhost/svn/verilator/trunk/verilator@1016 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
Wilson Snyder 2008-03-28 21:55:23 +00:00
parent 280eb48ba4
commit 957f495314
6 changed files with 47 additions and 19 deletions

View File

@ -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

View File

@ -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__<<": "<<endl);
LinkLValueVisitor visitor(rootp);
LinkLValueVisitor visitor(rootp, false);
}
void V3LinkLValue::linkLValueSet(AstNode* nodep) {
// Called by later link functions when it is known a node needs
// to be converted to a lvalue.
UINFO(9,__FUNCTION__<<": "<<endl);
LinkLValueVisitor visitor(nodep, true);
}

View File

@ -31,6 +31,7 @@
class V3LinkLValue {
public:
static void linkLValue(AstNetlist* nodep);
static void linkLValueSet(AstNode* nodep);
};
#endif // Guard

View File

@ -41,6 +41,7 @@
#include "V3Ast.h"
#include "V3EmitCBase.h"
#include "V3Graph.h"
#include "V3LinkLValue.h"
//######################################################################
// Graph subclasses
@ -360,11 +361,11 @@ 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());
@ -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);
}
}
}

View File

@ -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

View File

@ -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',
);