Fix forcing unpacked variables (#7149)
This commit is contained in:
parent
df6b808c49
commit
6f892d58ac
|
|
@ -442,40 +442,30 @@ class ForceConvertVisitor final : public VNVisitor {
|
|||
// continuous assignment shall reestablish that assignment and schedule a reevaluation in
|
||||
// the continuous assignment's scheduling region.
|
||||
AstAssign* const resetRdp
|
||||
= new AstAssign{flp, lhsp->cloneTreePure(false), lhsp->unlinkFrBack()};
|
||||
= new AstAssign{flp, lhsp->unlinkFrBack(), lhsp->cloneTreePure(false)};
|
||||
resetRdp->user2(true);
|
||||
// Replace write refs on the LHS
|
||||
resetRdp->lhsp()->foreach([this](AstVarRef* refp) {
|
||||
if (refp->access() != VAccess::WRITE) return;
|
||||
AstVarScope* const vscp = refp->varScopep();
|
||||
if (vscp->varp()->isContinuously()) {
|
||||
AstVarRef* const newpRefp = new AstVarRef{
|
||||
refp->fileline(), m_state.getForceComponents(vscp).m_rdVscp, VAccess::WRITE};
|
||||
refp->replaceWith(newpRefp);
|
||||
VL_DO_DANGLING(refp->deleteTree(), refp);
|
||||
}
|
||||
});
|
||||
// Replace write refs on RHS
|
||||
if (VN_IS(resetRdp->rhsp(), ArraySel) || VN_IS(resetRdp->rhsp(), StructSel)) {
|
||||
AstVarRef* const refp
|
||||
= VN_AS(AstNodeVarRef::varRefLValueRecurse(resetRdp->rhsp()), VarRef);
|
||||
AstVarScope* const vscp = refp->varScopep();
|
||||
AstNodeExpr* const origRhsp = resetRdp->rhsp();
|
||||
origRhsp->replaceWith(
|
||||
m_state.getForceComponents(vscp).forcedUpdate(vscp, origRhsp, refp));
|
||||
VL_DO_DANGLING(origRhsp->deleteTree(), origRhsp);
|
||||
AstVarRef* const refp = VN_AS(AstNodeVarRef::varRefLValueRecurse(lhsp), VarRef);
|
||||
AstVarScope* const vscp = refp->varScopep();
|
||||
AstVarRef* const rhsRefp = refp->clonep();
|
||||
|
||||
if (vscp->varp()->isContinuously()) {
|
||||
AstVarRef* const lhsRefp = new AstVarRef{
|
||||
refp->fileline(), m_state.getForceComponents(vscp).m_rdVscp, VAccess::WRITE};
|
||||
refp->replaceWith(lhsRefp);
|
||||
VL_DO_DANGLING(refp->deleteTree(), refp);
|
||||
rhsRefp->access(VAccess::READ);
|
||||
ForceState::markNonReplaceable(rhsRefp);
|
||||
} else {
|
||||
resetRdp->rhsp()->foreach([this](AstVarRef* refp) {
|
||||
if (refp->access() != VAccess::WRITE) return;
|
||||
AstVarScope* const vscp = refp->varScopep();
|
||||
if (vscp->varp()->isContinuously()) {
|
||||
refp->access(VAccess::READ);
|
||||
ForceState::markNonReplaceable(refp);
|
||||
} else {
|
||||
refp->replaceWith(m_state.getForceComponents(vscp).forcedUpdate(vscp));
|
||||
VL_DO_DANGLING(refp->deleteTree(), refp);
|
||||
}
|
||||
});
|
||||
if (rhsRefp->dtypep()->skipRefp()->isIntegralOrPacked()) {
|
||||
// In this case var ref can be replaced with expression
|
||||
rhsRefp->replaceWith(m_state.getForceComponents(vscp).forcedUpdate(vscp));
|
||||
VL_DO_DANGLING(rhsRefp->deleteTree(), rhsRefp);
|
||||
} else {
|
||||
AstNodeExpr* const origRhsp = resetRdp->rhsp();
|
||||
origRhsp->replaceWith(
|
||||
m_state.getForceComponents(vscp).forcedUpdate(vscp, origRhsp, rhsRefp));
|
||||
VL_DO_DANGLING(origRhsp->deleteTree(), origRhsp);
|
||||
}
|
||||
}
|
||||
|
||||
resetRdp->addNext(resetEnp);
|
||||
|
|
|
|||
|
|
@ -16,8 +16,17 @@ module t (
|
|||
|
||||
integer cyc = 0;
|
||||
|
||||
typedef union packed {
|
||||
int x;
|
||||
bit [31:0] y;
|
||||
} union_t;
|
||||
|
||||
logic logic_arr[2][-2:2][-3:-5];
|
||||
int int_arr[-1:2][1][3];
|
||||
bit [5:0] bit_arr[5];
|
||||
union_t union_arr[4];
|
||||
|
||||
assign bit_arr[2][3] = 1;
|
||||
|
||||
// Test loop
|
||||
always @(posedge clk) begin
|
||||
|
|
@ -25,38 +34,54 @@ module t (
|
|||
if (cyc == 0) begin
|
||||
logic_arr[0][2][-4] <= 1;
|
||||
int_arr[0][0][2] <= 1;
|
||||
union_arr[1].x <= 1;
|
||||
end
|
||||
else if (cyc == 1) begin
|
||||
`checkh(logic_arr[0][2][-4], 1);
|
||||
`checkh(int_arr[0][0][2], 1);
|
||||
`checkh(bit_arr[2][3], 1);
|
||||
`checkh(union_arr[1].x, 1);
|
||||
end
|
||||
else if (cyc == 2) begin
|
||||
force logic_arr[0][2][-4] = 0;
|
||||
force int_arr[0][0][2] = 0;
|
||||
force bit_arr[2][3] = 0;
|
||||
force union_arr[1].y = 2;
|
||||
end
|
||||
else if (cyc == 3) begin
|
||||
`checkh(logic_arr[0][2][-4], 0);
|
||||
logic_arr[0][2][-4] <= 1;
|
||||
`checkh(int_arr[0][0][2], 0);
|
||||
int_arr[0][0][2] <= 1;
|
||||
`checkh(bit_arr[2][3], 0);
|
||||
`checkh(union_arr[1].x, 2);
|
||||
union_arr[1].x <= 3;
|
||||
end
|
||||
else if (cyc == 4) begin
|
||||
`checkh(logic_arr[0][2][-4], 0);
|
||||
`checkh(int_arr[0][0][2], 0);
|
||||
`checkh(union_arr[1].y, 2);
|
||||
end
|
||||
else if (cyc == 5) begin
|
||||
release logic_arr[0][2][-4];
|
||||
release int_arr[0][0][2];
|
||||
release bit_arr[2][3];
|
||||
`checkh(bit_arr[2][3], 1);
|
||||
release union_arr[1].x;
|
||||
end
|
||||
else if (cyc == 6) begin
|
||||
`checkh(logic_arr[0][2][-4], 0);
|
||||
logic_arr[0][2][-4] <= 1;
|
||||
`checkh(int_arr[0][0][2], 0);
|
||||
int_arr[0][0][2] <= 1;
|
||||
`checkh(bit_arr[2][3], 1);
|
||||
`checkh(union_arr[1].x, 2);
|
||||
union_arr[1].y <= 4;
|
||||
end
|
||||
else if (cyc == 7) begin
|
||||
`checkh(logic_arr[0][2][-4], 1);
|
||||
`checkh(int_arr[0][0][2], 1);
|
||||
`checkh(union_arr[1].x, 4);
|
||||
end
|
||||
else if (cyc == 8) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
|
|
|
|||
Loading…
Reference in New Issue