mirror of
https://github.com/verilator/verilator.git
synced 2026-09-03 06:53:38 +02:00
This commit is contained in:
+36
-9
@@ -836,10 +836,17 @@ public:
|
||||
// If this is AstVarRef and referred in the sensitivity list of always@,
|
||||
// return the sensitivity item
|
||||
AstSenItem* backSenItemp() const {
|
||||
if (const AstVarRef* const refp = VN_CAST(m_nodep, VarRef)) {
|
||||
return VN_CAST(refp->backp(), SenItem);
|
||||
}
|
||||
return nullptr;
|
||||
const AstVarRef* const refp = VN_CAST(m_nodep, VarRef);
|
||||
if (!refp) return nullptr;
|
||||
return VN_CAST(refp->backp(), SenItem);
|
||||
}
|
||||
AstNodeAssign* backCResetp() const {
|
||||
const AstVarRef* const refp = VN_CAST(m_nodep, VarRef);
|
||||
if (!refp) return nullptr;
|
||||
AstNodeAssign* const assp = VN_CAST(refp->backp(), NodeAssign);
|
||||
if (!assp) return nullptr;
|
||||
if (!VN_IS(assp->rhsp(), CReset)) return nullptr;
|
||||
return assp;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1027,7 +1034,8 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
||||
UINFO(4, var.varp()->prettyNameQ() << "[" << msb << ":" << lsb << "] used for "
|
||||
<< ref.nodep()->prettyNameQ() << '\n');
|
||||
// LSB of varp is always 0. "lsb - var.lsb()" means this. see also SplitNewVar
|
||||
return new AstSel{fl, refp, lsb - var.lsb(), bitwidth};
|
||||
AstNodeExpr* const newp = new AstSel{fl, refp, lsb - var.lsb(), bitwidth};
|
||||
return newp;
|
||||
}
|
||||
}
|
||||
static void connectPortAndVar(const std::vector<SplitNewVar>& vars, AstVar* portp,
|
||||
@@ -1083,6 +1091,7 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
||||
dtypep->rangep(new AstRange{
|
||||
varp->fileline(), VNumRange{newvar.msb(), newvar.lsb(), basicp->ascending()}});
|
||||
newvar.varp(new AstVar{varp->fileline(), VVarType::VAR, name, dtypep});
|
||||
newvar.varp()->lifetime(varp->lifetime());
|
||||
newvar.varp()->propagateAttrFrom(varp);
|
||||
newvar.varp()->funcLocal(varp->isFuncLocal() || varp->isFuncReturn());
|
||||
// Enable this line to trace split variable directly:
|
||||
@@ -1092,6 +1101,15 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
||||
UINFO(4, newvar.varp()->prettyNameQ() << " is added for " << varp->prettyNameQ());
|
||||
}
|
||||
}
|
||||
static AstAssign* newAssignCReset(AstNodeAssign* cresetAssp, AstVar* attachVarp) {
|
||||
AstCReset* const cresetp = VN_AS(cresetAssp->rhsp(), CReset);
|
||||
AstCReset* const newCResetp = cresetp->cloneTree(false);
|
||||
newCResetp->dtypeFrom(attachVarp);
|
||||
AstAssign* const newp = new AstAssign{
|
||||
cresetAssp->fileline(),
|
||||
new AstVarRef{cresetAssp->fileline(), attachVarp, VAccess::WRITE}, newCResetp};
|
||||
return newp;
|
||||
}
|
||||
static void updateReferences(AstVar* varp, PackedVarRef& pref,
|
||||
const std::vector<SplitNewVar>& vars) {
|
||||
for (const bool lvalue : {false, true}) { // Refer the new split variables
|
||||
@@ -1102,9 +1120,14 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
||||
UASSERT_OBJ(varit != vars.end(), ref.nodep(), "Not found");
|
||||
UASSERT(!(varit->msb() < ref.lsb() || ref.msb() < varit->lsb()),
|
||||
"wrong search result");
|
||||
AstNode* prevp;
|
||||
AstNode* prevp = nullptr;
|
||||
bool inSentitivityList = false;
|
||||
if (AstSenItem* const senitemp = ref.backSenItemp()) {
|
||||
AstNodeAssign* const cresetAssp = ref.backCResetp();
|
||||
if (cresetAssp) {
|
||||
// ASSIGN(VARREF old, CRESET) convert to a creset of each new var
|
||||
cresetAssp->addNextHere(newAssignCReset(cresetAssp, varit->varp()));
|
||||
} else if (AstSenItem* const senitemp = ref.backSenItemp()) {
|
||||
// SENITEM(VARREF old) convert to a list of separate SenItems for each new var
|
||||
AstNode* const oldsenrefp = senitemp->sensp();
|
||||
oldsenrefp->replaceWith(
|
||||
new AstVarRef{senitemp->fileline(), varit->varp(), VAccess::READ});
|
||||
@@ -1118,7 +1141,9 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
||||
residue -= varit->bitwidth()) {
|
||||
++varit;
|
||||
UASSERT_OBJ(varit != vars.end(), ref.nodep(), "not enough split variables");
|
||||
if (AstSenItem* const senitemp = VN_CAST(prevp, SenItem)) {
|
||||
if (cresetAssp) {
|
||||
cresetAssp->addNextHere(newAssignCReset(cresetAssp, varit->varp()));
|
||||
} else if (AstSenItem* const senitemp = VN_CAST(prevp, SenItem)) {
|
||||
prevp = new AstSenItem{
|
||||
senitemp->fileline(), senitemp->edgeType(),
|
||||
new AstVarRef{senitemp->fileline(), varit->varp(), VAccess::READ}};
|
||||
@@ -1135,7 +1160,9 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
||||
// split()
|
||||
if (varp->isIO() && (varp->isFuncLocal() || varp->isFuncReturn()))
|
||||
connectPortAndVar(vars, varp, ref.nodep());
|
||||
if (!inSentitivityList) ref.replaceNodeWith(prevp);
|
||||
if (!inSentitivityList && !cresetAssp) ref.replaceNodeWith(prevp);
|
||||
if (cresetAssp)
|
||||
VL_DO_DANGLING(cresetAssp->unlinkFrBack()->deleteTree(), cresetAssp);
|
||||
UASSERT_OBJ(varit->msb() >= ref.msb(), varit->varp(), "Out of range");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user