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:
parent
280eb48ba4
commit
957f495314
2
Changes
2
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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
class V3LinkLValue {
|
||||
public:
|
||||
static void linkLValue(AstNetlist* nodep);
|
||||
static void linkLValueSet(AstNode* nodep);
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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',
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue