mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
DFG: Special case representation of AstSel
AstSel is a ternary node, but the 'widthp' is always constant and is hence redundant, and 'lsbp' is very often constant. As AstSel is fairly common, we special case as a DfgSel for the constant 'lsbp', and as 'DfgMux` for the non-constant 'lsbp'.
This commit is contained in:
+32
-6
@@ -187,15 +187,12 @@ class AstToDfgVisitor final : public VNVisitor {
|
||||
if (AstConcat* const concatp = VN_CAST(nodep, Concat)) {
|
||||
AstNode* const lhsp = concatp->lhsp();
|
||||
AstNode* const rhsp = concatp->rhsp();
|
||||
const uint32_t lWidth = lhsp->width();
|
||||
const uint32_t rWidth = rhsp->width();
|
||||
|
||||
{
|
||||
FileLine* const lFlp = lhsp->fileline();
|
||||
DfgSel* const lVtxp = new DfgSel{*m_dfgp, lFlp, DfgVertex::dtypeFor(lhsp)};
|
||||
lVtxp->fromp(vtxp);
|
||||
lVtxp->lsbp(new DfgConst{*m_dfgp, new AstConst{lFlp, rWidth}});
|
||||
lVtxp->widthp(new DfgConst{*m_dfgp, new AstConst{lFlp, lWidth}});
|
||||
lVtxp->lsb(rhsp->width());
|
||||
if (!convertAssignment(flp, lhsp, lVtxp)) return false;
|
||||
}
|
||||
|
||||
@@ -203,8 +200,7 @@ class AstToDfgVisitor final : public VNVisitor {
|
||||
FileLine* const rFlp = rhsp->fileline();
|
||||
DfgSel* const rVtxp = new DfgSel{*m_dfgp, rFlp, DfgVertex::dtypeFor(rhsp)};
|
||||
rVtxp->fromp(vtxp);
|
||||
rVtxp->lsbp(new DfgConst{*m_dfgp, new AstConst{rFlp, 0u}});
|
||||
rVtxp->widthp(new DfgConst{*m_dfgp, new AstConst{rFlp, rWidth}});
|
||||
rVtxp->lsb(0);
|
||||
return convertAssignment(flp, rhsp, rVtxp);
|
||||
}
|
||||
}
|
||||
@@ -467,6 +463,36 @@ class AstToDfgVisitor final : public VNVisitor {
|
||||
nodep->user1p(vtxp);
|
||||
}
|
||||
|
||||
void visit(AstSel* nodep) override {
|
||||
UASSERT_OBJ(!nodep->user1p(), nodep, "Already has Dfg vertex");
|
||||
if (unhandled(nodep)) return;
|
||||
if (!VN_IS(nodep->widthp(), Const)) { // This should never be taken, but paranoia
|
||||
m_foundUnhandled = true;
|
||||
++m_ctx.m_nonRepNode;
|
||||
return;
|
||||
}
|
||||
iterate(nodep->fromp());
|
||||
if (m_foundUnhandled) return;
|
||||
|
||||
FileLine* const flp = nodep->fileline();
|
||||
DfgVertex* vtxp = nullptr;
|
||||
if (AstConst* const constp = VN_CAST(nodep->lsbp(), Const)) {
|
||||
DfgSel* const selp = new DfgSel{*m_dfgp, flp, DfgVertex::dtypeFor(nodep)};
|
||||
selp->fromp(nodep->fromp()->user1u().to<DfgVertex*>());
|
||||
selp->lsb(constp->toUInt());
|
||||
vtxp = selp;
|
||||
} else {
|
||||
iterate(nodep->lsbp());
|
||||
if (m_foundUnhandled) return;
|
||||
DfgMux* const muxp = new DfgMux{*m_dfgp, flp, DfgVertex::dtypeFor(nodep)};
|
||||
muxp->fromp(nodep->fromp()->user1u().to<DfgVertex*>());
|
||||
muxp->lsbp(nodep->lsbp()->user1u().to<DfgVertex*>());
|
||||
vtxp = muxp;
|
||||
}
|
||||
m_uncommittedVertices.push_back(vtxp);
|
||||
nodep->user1p(vtxp);
|
||||
}
|
||||
|
||||
// The rest of the 'visit' methods are generated by 'astgen'
|
||||
#include "V3Dfg__gen_ast_to_dfg.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user