mirror of
https://github.com/verilator/verilator.git
synced 2026-10-07 10:33:13 +02:00
Internals: Refactor input/output to new class in prep for ref support.
This commit is contained in:
+46
-35
@@ -332,9 +332,9 @@ private:
|
||||
AstVarScope* createInputVar(AstCFunc* funcp, const string& name, AstBasicDTypeKwd kwd) {
|
||||
AstVar* newvarp = new AstVar(funcp->fileline(), AstVarType::BLOCKTEMP, name,
|
||||
funcp->findBasicDType(kwd));
|
||||
newvarp->funcLocal(true);
|
||||
newvarp->combineType(AstVarType::INPUT);
|
||||
funcp->addArgsp(newvarp);
|
||||
newvarp->funcLocal(true);
|
||||
newvarp->direction(VDirection::INPUT);
|
||||
funcp->addArgsp(newvarp);
|
||||
AstVarScope* newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp);
|
||||
m_scopep->addVarp(newvscp);
|
||||
return newvscp;
|
||||
@@ -378,10 +378,13 @@ private:
|
||||
pinp->unlinkFrBack(); // Relinked to assignment below
|
||||
argp->unlinkFrBack()->deleteTree(); // Args no longer needed
|
||||
//
|
||||
if ((portp->isInout() || portp->isOutput()) && VN_IS(pinp, Const)) {
|
||||
pinp->v3error("Function/task output connected to constant instead of variable: "+portp->prettyName());
|
||||
}
|
||||
else if (portp->isInout()) {
|
||||
if (portp->isWritable() && VN_IS(pinp, Const)) {
|
||||
pinp->v3error("Function/task "
|
||||
+portp->direction().prettyName() // e.g. "output"
|
||||
+" connected to constant instead of variable: "
|
||||
+portp->prettyName());
|
||||
}
|
||||
else if (portp->isInoutish()) {
|
||||
// Correct lvalue; see comments below
|
||||
V3LinkLValue::linkLValueSet(pinp);
|
||||
|
||||
@@ -393,9 +396,9 @@ private:
|
||||
} else {
|
||||
pinp->v3warn(E_TASKNSVAR,"Unsupported: Function/task input argument is not simple variable");
|
||||
}
|
||||
}
|
||||
else if (portp->isOutput()) {
|
||||
// Make output variables
|
||||
}
|
||||
else if (portp->isWritable()) {
|
||||
// Make output variables
|
||||
// Correct lvalue; we didn't know when we linked
|
||||
// This is slightly scary; are we sure no decisions were made
|
||||
// before here based on this not being a lvalue?
|
||||
@@ -412,9 +415,9 @@ private:
|
||||
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Ok if in <= block
|
||||
// Put assignment BEHIND of all other statements
|
||||
beginp->addNext(assp);
|
||||
}
|
||||
else if (portp->isInput()) {
|
||||
// Make input variable
|
||||
}
|
||||
else if (portp->isNonOutput()) {
|
||||
// Make input variable
|
||||
AstVarScope* inVscp = createVarScope(portp, namePrefix+"__"+portp->shortName());
|
||||
portp->user2p(inVscp);
|
||||
AstAssign* assp = new AstAssign(pinp->fileline(),
|
||||
@@ -483,10 +486,13 @@ private:
|
||||
} else {
|
||||
UINFO(9, " Port "<<portp<<endl);
|
||||
UINFO(9, " pin "<<pinp<<endl);
|
||||
if ((portp->isInout() || portp->isOutput()) && VN_IS(pinp, Const)) {
|
||||
pinp->v3error("Function/task output connected to constant instead of variable: "+portp->prettyName());
|
||||
}
|
||||
else if (portp->isInout()) {
|
||||
if (portp->isWritable() && VN_IS(pinp, Const)) {
|
||||
pinp->v3error("Function/task "
|
||||
+portp->direction().prettyName() // e.g. "output"
|
||||
+" connected to constant instead of variable: "
|
||||
+portp->prettyName());
|
||||
}
|
||||
else if (portp->isInoutish()) {
|
||||
// Correct lvalue; see comments below
|
||||
V3LinkLValue::linkLValueSet(pinp);
|
||||
|
||||
@@ -495,9 +501,9 @@ private:
|
||||
} else {
|
||||
pinp->v3warn(E_TASKNSVAR,"Unsupported: Function/task input argument is not simple variable");
|
||||
}
|
||||
}
|
||||
else if (portp->isOutput()) {
|
||||
// Make output variables
|
||||
}
|
||||
else if (portp->isWritable()) {
|
||||
// Make output variables
|
||||
// Correct lvalue; we didn't know when we linked
|
||||
// This is slightly scary; are we sure no decisions were made
|
||||
// before here based on this not being a lvalue?
|
||||
@@ -718,12 +724,17 @@ private:
|
||||
// No createDpiTemp; we make a real internal variable instead
|
||||
// SAME CODE BELOW
|
||||
args+= ", ";
|
||||
if (args != "") { argnodesp = argnodesp->addNext(new AstText(portp->fileline(), args, true)); args=""; }
|
||||
if (args != "") {
|
||||
argnodesp = argnodesp->addNext(
|
||||
new AstText(portp->fileline(), args, true));
|
||||
args="";
|
||||
}
|
||||
AstVarScope* outvscp = createFuncVar(dpip, portp->name()+"__Vcvt", portp);
|
||||
AstVarRef* refp = new AstVarRef(portp->fileline(), outvscp, portp->isOutput());
|
||||
argnodesp = argnodesp->addNextNull(refp);
|
||||
AstVarRef* refp = new AstVarRef(portp->fileline(), outvscp,
|
||||
portp->isWritable());
|
||||
argnodesp = argnodesp->addNextNull(refp);
|
||||
|
||||
if (portp->isInput()) {
|
||||
if (portp->isNonOutput()) {
|
||||
dpip->addStmtsp(createAssignDpiToInternal(outvscp, portp->name(), false));
|
||||
}
|
||||
}
|
||||
@@ -736,9 +747,9 @@ private:
|
||||
args+= ", ";
|
||||
if (args != "") { argnodesp = argnodesp->addNext(new AstText(portp->fileline(), args, true)); args=""; }
|
||||
AstVarScope* outvscp = createFuncVar(dpip, portp->name()+"__Vcvt", portp);
|
||||
AstVarRef* refp = new AstVarRef(portp->fileline(), outvscp, portp->isOutput());
|
||||
argnodesp = argnodesp->addNextNull(refp);
|
||||
}
|
||||
AstVarRef* refp = new AstVarRef(portp->fileline(), outvscp, portp->isWritable());
|
||||
argnodesp = argnodesp->addNextNull(refp);
|
||||
}
|
||||
|
||||
{// Call the user function
|
||||
// Add the variables referenced as VarRef's so that lifetime analysis
|
||||
@@ -755,11 +766,11 @@ private:
|
||||
// Convert output/inout arguments back to internal type
|
||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO() && portp->isOutput() && !portp->isFuncReturn()) {
|
||||
dpip->addStmtsp(createAssignInternalToDpi(portp,false,true,"__Vcvt",""));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (portp->isIO() && portp->isWritable() && !portp->isFuncReturn()) {
|
||||
dpip->addStmtsp(createAssignInternalToDpi(portp,false,true,"__Vcvt",""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rtnvarp) {
|
||||
dpip->addStmtsp(createDpiTemp(rtnvarp,""));
|
||||
@@ -867,14 +878,14 @@ private:
|
||||
else {
|
||||
if (bitvec) {}
|
||||
else if (logicvec) {}
|
||||
else if (portp->isOutput()) args += "&";
|
||||
else if (portp->isWritable()) args += "&";
|
||||
else if (portp->basicp() && portp->basicp()->keyword().isDpiBitVal()
|
||||
&& portp->width() != 1) args += "&"; // it's a svBitVecVal (2-32 bits wide)
|
||||
|
||||
args += portp->name()+"__Vcvt";
|
||||
|
||||
cfuncp->addStmtsp(createDpiTemp(portp,"__Vcvt"));
|
||||
if (portp->isInput()) {
|
||||
if (portp->isNonOutput()) {
|
||||
cfuncp->addStmtsp(createAssignInternalToDpi(portp,false,false,"","__Vcvt"));
|
||||
}
|
||||
}
|
||||
@@ -900,7 +911,7 @@ private:
|
||||
// Convert output/inout arguments back to internal type
|
||||
for (AstNode* stmtp = cfuncp->argsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO() && (portp->isOutput() || portp->isFuncReturn())
|
||||
if (portp->isIO() && (portp->isWritable() || portp->isFuncReturn())
|
||||
&& !portp->isDpiOpenArray()) {
|
||||
AstVarScope* portvscp = VN_CAST(portp->user2p(), VarScope); // Remembered when we created it earlier
|
||||
cfuncp->addStmtsp(createAssignDpiToInternal(portvscp,portp->name()+"__Vcvt",true));
|
||||
|
||||
Reference in New Issue
Block a user