Internals: Add special Dfg vertex for replication (#7471)

This commit is contained in:
Geza Lore 2026-04-23 10:14:27 +01:00 committed by GitHub
parent cfebe805c9
commit 3149f43372
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 149 additions and 119 deletions

View File

@ -3695,7 +3695,6 @@ class AstReplicate final : public AstNodeBiop {
// Verilog {rhs{lhs}} - Note rhsp() is the replicate value, not the lhsp()
// @astgen alias op1 := srcp
// @astgen alias op2 := countp
// @astgen makeDfgVertex
public:
AstReplicate(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp)
: ASTGEN_SUPER_Replicate(fl, lhsp, rhsp) {

View File

@ -97,6 +97,11 @@ std::unique_ptr<DfgGraph> DfgGraph::clone() const {
vtxp2clonep.emplace(&vtx, cp);
break;
}
case VDfgType::Rep: {
DfgRep* const cp = new DfgRep{*clonep, vtx.fileline(), vtx.dtype()};
vtxp2clonep.emplace(&vtx, cp);
break;
}
case VDfgType::UnitArray: {
DfgUnitArray* const cp = new DfgUnitArray{*clonep, vtx.fileline(), vtx.dtype()};
vtxp2clonep.emplace(&vtx, cp);
@ -712,12 +717,10 @@ void DfgVertex::typeCheck(const DfgGraph& dfg) const {
return;
}
case VDfgType::Replicate: {
// TODO: model DfgReplicate without an explicit 'countp' which is always constant
const DfgReplicate& v = *as<DfgReplicate>();
case VDfgType::Rep: {
const DfgRep& v = *as<DfgRep>();
CHECK(v.isPacked(), "Should be Packed type");
CHECK(v.srcp()->isPacked(), "'srcp' should be same type");
CHECK(v.countp()->isPacked(), "'countp' should be Packed type");
CHECK(v.size() % v.srcp()->size() == 0, "Not a replicate");
return;
}

View File

@ -374,14 +374,13 @@ class TraceDriver final : public DfgVisitor {
SET_RESULT(resp);
}
void visit(DfgReplicate* vtxp) override {
void visit(DfgRep* vtxp) override {
DfgVertex* const srcp = vtxp->srcp();
const uint32_t sWidth = srcp->width();
// If we need more bits than the source, then we need the whole source
if (m_msb - m_lsb + 1 > sWidth) {
DfgReplicate* const repp = make<DfgReplicate>(vtxp, vtxp->width());
DfgRep* const repp = make<DfgRep>(vtxp, vtxp->width());
repp->srcp(trace(srcp, sWidth - 1, 0));
repp->countp(vtxp->countp()); // Always a DfgConst
DfgSel* const resp = make<DfgSel>(vtxp, m_msb - m_lsb + 1);
resp->fromp(repp);
resp->lsb(m_lsb);
@ -757,8 +756,8 @@ class IndependentBits final : public DfgVisitor {
m.opSelInto(MASK(lhsp), rhsp->width(), lhsp->width());
}
void visit(DfgReplicate* vtxp) override {
const uint32_t count = vtxp->countp()->as<DfgConst>()->toU32();
void visit(DfgRep* vtxp) override {
const uint32_t count = vtxp->count();
const DfgVertex* const srcp = vtxp->srcp();
const uint32_t sWidth = srcp->width();
V3Number& vMask = MASK(vtxp);

View File

@ -118,7 +118,7 @@ class V3DfgCse final {
case VDfgType::RedAnd:
case VDfgType::RedOr:
case VDfgType::RedXor:
case VDfgType::Replicate:
case VDfgType::Rep:
case VDfgType::ShiftL:
case VDfgType::ShiftR:
case VDfgType::ShiftRS:
@ -240,7 +240,7 @@ class V3DfgCse final {
case VDfgType::RedAnd:
case VDfgType::RedOr:
case VDfgType::RedXor:
case VDfgType::Replicate:
case VDfgType::Rep:
case VDfgType::ShiftL:
case VDfgType::ShiftR:
case VDfgType::ShiftRS:

View File

@ -228,6 +228,12 @@ class DfgToAstVisitor final : DfgVisitor {
m_resultp = new AstConst{vtxp->fileline(), vtxp->num()};
}
void visit(DfgRep* vtxp) override {
FileLine* const flp = vtxp->fileline();
AstNodeExpr* const srcp = convertDfgVertexToAstNodeExpr(vtxp->srcp());
m_resultp = new AstReplicate{flp, srcp, vtxp->count()};
}
void visit(DfgSel* vtxp) override {
FileLine* const flp = vtxp->fileline();
AstNodeExpr* const fromp = convertDfgVertexToAstNodeExpr(vtxp->fromp());

View File

@ -130,7 +130,6 @@ template <> const DfgDataType& resultDType<DfgPow> (const DfgVertex* lhsp
template <> const DfgDataType& resultDType<DfgPowSS> (const DfgVertex* lhsp, const DfgVertex* rhsp) { return lhsp->dtype(); }
template <> const DfgDataType& resultDType<DfgPowSU> (const DfgVertex* lhsp, const DfgVertex* rhsp) { return lhsp->dtype(); }
template <> const DfgDataType& resultDType<DfgPowUS> (const DfgVertex* lhsp, const DfgVertex* rhsp) { return lhsp->dtype(); }
// template <> const DfgDataType& resultDType<DfgReplicate> (const DfgVertex* lhsp, const DfgVertex* rhsp) { return ; }
template <> const DfgDataType& resultDType<DfgShiftL> (const DfgVertex* lhsp, const DfgVertex* rhsp) { return lhsp->dtype(); }
template <> const DfgDataType& resultDType<DfgShiftR> (const DfgVertex* lhsp, const DfgVertex* rhsp) { return lhsp->dtype(); }
template <> const DfgDataType& resultDType<DfgShiftRS> (const DfgVertex* lhsp, const DfgVertex* rhsp) { return lhsp->dtype(); }
@ -178,7 +177,6 @@ template <> void foldOp<DfgPow> (V3Number& out, const V3Number& lhs, cons
template <> void foldOp<DfgPowSS> (V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowSS(lhs, rhs); }
template <> void foldOp<DfgPowSU> (V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowSU(lhs, rhs); }
template <> void foldOp<DfgPowUS> (V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowUS(lhs, rhs); }
template <> void foldOp<DfgReplicate> (V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opRepl(lhs, rhs); }
template <> void foldOp<DfgShiftL> (V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftL(lhs, rhs); }
template <> void foldOp<DfgShiftR> (V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftR(lhs, rhs); }
template <> void foldOp<DfgShiftRS> (V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftRS(lhs, rhs, lhs.width()); }
@ -409,8 +407,9 @@ class V3DfgPeephole final : public DfgVisitor {
// Replicate 'bitp' to 'vtxp->width()' bits
DfgVertex* replicate(DfgVertex* vtxp, DfgVertex* bitp) {
UASSERT_OBJ(bitp->dtype() == m_bitDType, vtxp, "Expected 1-bit vertex");
if (vtxp->dtype() == m_bitDType) return bitp;
return make<DfgReplicate>(vtxp, bitp, makeI32(vtxp->fileline(), vtxp->width()));
return make<DfgRep>(vtxp, bitp);
}
// Check two vertex are the same, or the same constant value
@ -1127,7 +1126,7 @@ class V3DfgPeephole final : public DfgVisitor {
}
}
if (DfgReplicate* const repp = fromp->cast<DfgReplicate>()) {
if (DfgRep* const repp = fromp->cast<DfgRep>()) {
// If the Sel is wholly into the source of the Replicate, push the Sel through
// the Replicate and apply it directly to the source of the Replicate.
const uint32_t srcWidth = repp->srcp()->width();
@ -1135,7 +1134,7 @@ class V3DfgPeephole final : public DfgVisitor {
const uint32_t newLsb = lsb % srcWidth;
const uint32_t newMsb = newLsb + width - 1;
if (newMsb < srcWidth) {
APPLYING(PUSH_SEL_THROUGH_REPLICATE) {
APPLYING(PUSH_SEL_THROUGH_REP) {
fromp = repp->srcp();
lsb = newLsb;
continue;
@ -1488,10 +1487,10 @@ class V3DfgPeephole final : public DfgVisitor {
}
{
DfgReplicate* repp = lhsp->cast<DfgReplicate>();
DfgRep* repp = lhsp->cast<DfgRep>();
DfgCond* condp = rhsp->cast<DfgCond>();
if (!repp && !condp) {
repp = rhsp->cast<DfgReplicate>();
repp = rhsp->cast<DfgRep>();
condp = lhsp->cast<DfgCond>();
}
if (repp && condp && repp->srcp()->size() == 1 && !condp->hasMultipleSinks()
@ -1984,24 +1983,22 @@ class V3DfgPeephole final : public DfgVisitor {
// Convert various forms to REPLICATE
if (isSame(lhsp, rhsp)) {
APPLYING(REPLACE_CONCAT_SAME) {
replace(make<DfgReplicate>(vtxp, lhsp, makeI32(flp, 2)));
replace(make<DfgRep>(vtxp, lhsp));
return;
}
}
if (DfgReplicate* const lRepp = lhsp->cast<DfgReplicate>()) {
if (DfgRep* const lRepp = lhsp->cast<DfgRep>()) {
if (isSame(lRepp->srcp(), rhsp)) {
APPLYING(REPLACE_CONCAT_SAME_REP_ON_LHS) {
const uint32_t count = lRepp->countp()->as<DfgConst>()->toU32() + 1;
replace(make<DfgReplicate>(vtxp, rhsp, makeI32(flp, count)));
replace(make<DfgRep>(vtxp, rhsp));
return;
}
}
}
if (DfgReplicate* const rRepp = rhsp->cast<DfgReplicate>()) {
if (DfgRep* const rRepp = rhsp->cast<DfgRep>()) {
if (isSame(lhsp, rRepp->srcp())) {
APPLYING(REPLACE_CONCAT_SAME_REP_ON_RHS) {
const uint32_t count = rRepp->countp()->as<DfgConst>()->toU32() + 1;
replace(make<DfgReplicate>(vtxp, lhsp, makeI32(flp, count)));
replace(make<DfgRep>(vtxp, lhsp));
return;
}
}
@ -2278,23 +2275,34 @@ class V3DfgPeephole final : public DfgVisitor {
if (binary(vtxp)) return;
}
void visit(DfgReplicate* const vtxp) override {
if (DfgConst* const sConstp = vtxp->srcp()->cast<DfgConst>()) {
DfgConst* const cConstp = vtxp->countp()->as<DfgConst>();
APPLYING(FOLD_REPLICATE) {
DfgConst* const resultp = makeZero(vtxp->fileline(), vtxp->width());
foldOp<DfgReplicate>(resultp->num(), sConstp->num(), cConstp->num());
void visit(DfgRep* const vtxp) override {
DfgVertex* const srcp = vtxp->srcp();
FileLine* const flp = vtxp->fileline();
if (DfgConst* const sConstp = srcp->cast<DfgConst>()) {
APPLYING(FOLD_REP) {
DfgConst* const resultp = makeZero(flp, vtxp->width());
resultp->num().opRepl(sConstp->num(), vtxp->count());
replace(resultp);
return;
}
}
if (vtxp->dtype() == vtxp->srcp()->dtype()) {
APPLYING(REMOVE_REPLICATE_ONCE) {
if (vtxp->dtype() == srcp->dtype()) {
APPLYING(REMOVE_REP_ONCE) {
replace(vtxp->srcp());
return;
}
}
if (DfgRep* const sRepp = srcp->cast<DfgRep>()) {
if (!sRepp->hasMultipleSinks() || vtxp->width() <= VL_QUADSIZE) {
APPLYING(REPLACE_REP_REP) {
replace(make<DfgRep>(vtxp, sRepp->srcp()));
return;
}
}
}
}
void visit(DfgShiftL* const vtxp) override {
@ -2775,15 +2783,14 @@ class V3DfgPeephole final : public DfgVisitor {
if (isOnes(thenp) && isZero(elsep)) {
APPLYING(REPLACE_COND_CONST_ONES_ZERO) {
replace(make<DfgReplicate>(vtxp, condp, makeI32(flp, vtxp->width())));
replace(replicate(vtxp, condp));
return;
}
}
if (isZero(thenp) && isOnes(elsep)) {
APPLYING(REPLACE_COND_CONST_ZERO_ONES) {
replace(make<DfgReplicate>(vtxp, make<DfgNot>(condp, condp),
makeI32(flp, vtxp->width())));
replace(replicate(vtxp, make<DfgNot>(condp, condp)));
return;
}
}

View File

@ -32,7 +32,7 @@
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_BINARY) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_MUX_FROM_ONES) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_MUX_FROM_ZERO) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_REPLICATE) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_REP) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_SEL) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_SELF_EQ) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, FOLD_SELF_GT) \
@ -64,7 +64,7 @@
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, PUSH_REDUCTION_THROUGH_COND_WITH_CONST_BRANCH) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, PUSH_SEL_THROUGH_COND) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, PUSH_SEL_THROUGH_NOT) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, PUSH_SEL_THROUGH_REPLICATE) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, PUSH_SEL_THROUGH_REP) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, PUSH_SEL_THROUGH_SHIFTL) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, PUSH_SEL_THROUGH_SPLICE) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, PUSH_SHIFTL_THROUGH_COND) \
@ -84,7 +84,7 @@
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_NOT_NOT) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_OR_WITH_ZERO) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_REDUNDANT_ZEXT_ON_RHS_OF_SHIFT) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_REPLICATE_ONCE) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_REP_ONCE) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_SEL_FROM_LHS_OF_CONCAT) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_SEL_FROM_RHS_OF_CONCAT) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REMOVE_SHIFTL_ZERO) \
@ -144,6 +144,7 @@
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_OR_OF_NOT_AND_NEQ) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_OR_OF_NOT_AND_NOT) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_OR_WITH_ONES) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_REP_REP) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_SEL_FROM_SEL) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_SHIFTL_CAT) \
_FOR_EACH_DFG_PEEPHOLE_OPTIMIZATION_APPLY(macro, REPLACE_SHIFTL_OVER) \

View File

@ -384,6 +384,26 @@ class AstToDfgConverter final : public VNVisitor {
nodep->user2p(vtxp);
}
}
void visit(AstReplicate* nodep) override {
UASSERT_OBJ(m_converting, nodep, "AstToDfg visit called without m_converting");
UASSERT_OBJ(!nodep->user2p(), nodep, "Already has Dfg vertex");
if (unhandled(nodep)) return;
const DfgDataType* const dtypep = DfgDataType::fromAst(nodep->dtypep());
if (!dtypep) {
m_foundUnhandled = true;
++m_ctx.m_conv.nonRepDType;
return;
}
iterate(nodep->srcp());
if (m_foundUnhandled) return;
FileLine* const flp = nodep->fileline();
DfgRep* const vtxp = make<DfgRep>(flp, *dtypep);
vtxp->srcp(nodep->srcp()->user2u().to<DfgVertex*>());
nodep->user2p(vtxp);
}
void visit(AstSel* nodep) override {
UASSERT_OBJ(m_converting, nodep, "AstToDfg visit called without m_converting");
UASSERT_OBJ(!nodep->user2p(), nodep, "Already has Dfg vertex");
@ -426,6 +446,7 @@ class AstToDfgConverter final : public VNVisitor {
}
nodep->user2p(vtxp);
}
// The rest of the visit methods for expressions are generated by 'astgen'
#include "V3Dfg__gen_ast_to_dfg.h"

View File

@ -265,6 +265,17 @@ public:
std::string srcName(size_t) const override final { return ""; }
};
class DfgRep final : public DfgVertexUnary {
// AstReplicate is binary, but 'countp' is always constant. Represented in
// Dfg as a unary vertex, with the count determined by the data type,
// similar to Extend/ExtendS.
public:
DfgRep(DfgGraph& dfg, FileLine* flp, const DfgDataType& dtype)
: DfgVertexUnary{dfg, dfgType(), flp, dtype} {}
ASTGEN_MEMBERS_DfgRep;
uint32_t count() const { return width() / srcp()->width(); }
};
class DfgSel final : public DfgVertexUnary {
// AstSel is binary, but 'lsbp' is very often constant. As AstSel is fairly
// common, we special case as a DfgSel for the constant 'lsbp', and as

View File

@ -1,10 +1,10 @@
DFG patterns with depth 1
8 (CONCAT _:1 _:a):b
5 (CONST #A):a
5 (REDXOR _:a*):1
5 (VARPACKED _:a*):a
5 (REDXOR _:a):1
3 (NOT (VARPACKED):a):a*
3 (REDXOR _:a):1
3 (REDXOR _:a*):1
3 (REP _:1*):a
3 (VARPACKED _:a*):a
3 (VARPACKED):a
2 (AND _:a* _:a*):a
1 (AND _:a* _:a*):a*
@ -12,112 +12,94 @@ DFG patterns with depth 1
1 (CONCAT _:1* _:a):b
1 (NOT _:a*):a
1 (REDXOR _:a):1*
1 (REPLICATE _:1 (CONST #A):a):b*
1 (REPLICATE _:a (CONST #A):a):b*
1 (REPLICATE _:a* (CONST #A):a):b
1 (REPLICATE _:a* (CONST #A):b):b*
1 (REPLICATE _:a* (CONST #A):b):c*
1 (REP _:1*):a*
1 (REP _:a):b*
1 (SEL@0 _:a*):1
1 (SEL@0 _:a*):b
1 (SEL@A _:a*):1
1 (SEL@A _:a*):1*
1 (VARPACKED _:a):a
DFG patterns with depth 2
3 (CONCAT (REDXOR _:a*):1 (CONCAT _:1 _:b):c):d
4 (CONCAT (REDXOR _:a):1 (CONCAT _:1 _:b):c):d
3 (REP (SEL@A _:a*):1*):b
2 (AND (NOT (VARPACKED):a):a* (NOT (VARPACKED):a):a*):a
2 (CONCAT (REDXOR _:a):1 (CONCAT _:1 _:b):c):d
2 (REDXOR (AND _:a* _:a*):a):1
2 (REDXOR (REP _:1*):a):1
1 (AND (NOT (VARPACKED):a):a* (NOT (VARPACKED):a):a*):a*
1 (CONCAT (REDXOR _:a):1 (REDXOR _:b):1*):c
1 (CONCAT (REDXOR _:a):1* (CONCAT _:1 _:b):c):d
1 (CONCAT (REDXOR _:a*):1 (CONCAT _:1 _:1*):b):c
1 (CONCAT (REDXOR _:a*):1 (CONCAT _:1 _:b):c):d
1 (CONCAT (REDXOR _:a*):1 (CONCAT _:1* _:b):c):d
1 (CONCAT (SEL@0 _:a*):1 (CONCAT _:1 _:b):c):d
1 (NOT (REPLICATE _:a* (CONST #A):b):b*):b
1 (NOT (REP _:1*):a*):a
1 (REDXOR (AND _:a* _:a*):a*):1
1 (REDXOR (REPLICATE _:1 (CONST #A):a):b*):1
1 (REDXOR (REPLICATE _:a (CONST #A):a):b*):1
1 (REDXOR (REPLICATE _:a* (CONST #A):a):b):1*
1 (REDXOR (REPLICATE _:a* (CONST #A):b):b*):1
1 (REDXOR (REPLICATE _:a* (CONST #A):b):c*):1
1 (REDXOR (REP _:1*):a):1*
1 (REDXOR (REP _:1*):a*):1
1 (REDXOR (REP _:a):b*):1
1 (REDXOR (SEL@0 _:a*):b):1
1 (REPLICATE (NOT _:a*):a (CONST #A):a):b*
1 (REPLICATE (REPLICATE _:1 (CONST #A):a):b* (CONST #B):a):c*
1 (REPLICATE (REPLICATE _:a* (CONST #A):b):b* (CONST #A):b):c
1 (REPLICATE (REPLICATE _:a* (CONST #A):b):c* (CONST #A):b):b*
1 (REPLICATE (SEL@A _:a*):1 (CONST #A):b):c*
1 (REP (NOT _:a*):a):b*
1 (REP (SEL@A _:a*):1*):b*
1 (SEL@0 (AND _:a* _:a*):a*):1
1 (SEL@0 (REPLICATE _:a (CONST #A):a):b*):c
1 (SEL@A (AND _:a* _:a*):a*):1
1 (SEL@0 (REP _:a):b*):c
1 (SEL@A (AND _:a* _:a*):a*):1*
1 (VARPACKED (AND _:a* _:a*):a*):a
1 (VARPACKED (CONCAT _:1 _:a):b):b
1 (VARPACKED (REPLICATE _:1 (CONST #A):a):b*):b
1 (VARPACKED (REPLICATE _:a (CONST #A):a):b*):b
1 (VARPACKED (REPLICATE _:a* (CONST #A):b):b*):b
1 (VARPACKED (REPLICATE _:a* (CONST #A):b):c*):c
1 (VARPACKED (REP _:1*):a*):a
1 (VARPACKED (REP _:a):b*):b
DFG patterns with depth 3
3 (REP (SEL@A (AND _:a* _:a*):a*):1*):b
2 (REDXOR (AND (NOT (VARPACKED):a):a* (NOT (VARPACKED):a):a*):a):1
2 (REDXOR (REP (SEL@A _:a*):1*):b):1
1 (CONCAT (REDXOR (AND _:a* _:a*):a):1 (CONCAT (REDXOR _:a):1 (CONCAT _:1 _:b):c):d):e
1 (CONCAT (REDXOR (AND _:a* _:a*):a):1 (CONCAT (SEL@0 _:a*):1 (CONCAT _:1 _:b):c):d):e
1 (CONCAT (REDXOR (AND _:a* _:a*):a*):1 (CONCAT (REDXOR _:a):1 (CONCAT _:1 _:b):c):d):e
1 (CONCAT (REDXOR (REPLICATE _:1 (CONST #A):a):b*):1 (CONCAT (REDXOR _:c*):1 (CONCAT _:1 _:d):e):f):g
1 (CONCAT (REDXOR (REPLICATE _:a (CONST #A):a):b*):1 (CONCAT (REDXOR _:c):1 (REDXOR _:b):1*):d):e
1 (CONCAT (REDXOR (REPLICATE _:a* (CONST #A):b):b*):1 (CONCAT (REDXOR _:c):1* (CONCAT _:1 _:d):e):f):g
1 (CONCAT (REDXOR (REPLICATE _:a* (CONST #A):b):c*):1 (CONCAT (REDXOR _:b*):1 (CONCAT _:1* _:d):e):f):g
1 (CONCAT (REDXOR (SEL@0 _:a*):b):1 (REDXOR (REPLICATE _:c* (CONST #A):c):a):1*):d
1 (CONCAT (SEL@0 (AND _:a* _:a*):a*):1 (CONCAT (REDXOR _:b*):1 (CONCAT _:1 _:c):d):e):b
1 (CONCAT A:1* (CONCAT (REDXOR _:a*):1 (CONCAT _:1 A:1*):b):c):d | A is (REDXOR (REPLICATE _:e* (CONST #A):e):a):1*
1 (NOT (REPLICATE (REPLICATE _:a* (CONST #A):b):c* (CONST #A):b):b*):b
1 (CONCAT (REDXOR (REP _:1*):a):1 (CONCAT (REDXOR _:b):1 (CONCAT _:1 _:c):d):e):f
1 (CONCAT (REDXOR (REP _:1*):a):1 (CONCAT (REDXOR _:b*):1 (CONCAT _:1* _:c):d):e):f
1 (CONCAT (REDXOR (REP _:1*):a*):1 (CONCAT (REDXOR _:b):1* (CONCAT _:1 _:c):d):e):f
1 (CONCAT (REDXOR (REP _:a):b*):1 (CONCAT (REDXOR _:c):1 (REDXOR _:b):1*):d):e
1 (CONCAT (REDXOR (SEL@0 _:a*):b):1 (REDXOR (REP _:1*):a):1*):c
1 (CONCAT (SEL@0 (AND _:a* _:a*):a*):1 (CONCAT (REDXOR _:b):1 (CONCAT _:1 _:c):d):e):b
1 (CONCAT A:1* (CONCAT (REDXOR _:a*):1 (CONCAT _:1 A:1*):b):c):d | A is (REDXOR (REP _:1*):a):1*
1 (NOT (REP (SEL@A _:a*):1*):b*):b
1 (REDXOR (AND (NOT (VARPACKED):a):a* (NOT (VARPACKED):a):a*):a*):1
1 (REDXOR (REPLICATE (NOT _:a*):a (CONST #A):a):b*):1
1 (REDXOR (REPLICATE (REPLICATE _:1 (CONST #A):a):b* (CONST #B):a):c*):1
1 (REDXOR (REPLICATE (REPLICATE _:a* (CONST #A):b):b* (CONST #A):b):c):1*
1 (REDXOR (REPLICATE (REPLICATE _:a* (CONST #A):b):c* (CONST #A):b):b*):1
1 (REDXOR (REPLICATE (SEL@A _:a*):1 (CONST #A):b):c*):1
1 (REDXOR (SEL@0 (REPLICATE _:a (CONST #A):a):b*):c):1
1 (REPLICATE (NOT (REPLICATE _:a* (CONST #A):b):b*):b (CONST #A):b):c*
1 (REPLICATE (REPLICATE (REPLICATE _:1 (CONST #A):a):b* (CONST #B):a):c* (CONST #B):a):a*
1 (REPLICATE (REPLICATE (REPLICATE _:a* (CONST #A):b):c* (CONST #A):b):b* (CONST #A):b):d
1 (REPLICATE (REPLICATE (SEL@A _:a*):1 (CONST #A):b):c* (CONST #B):b):d*
1 (REPLICATE (SEL@A (AND _:a* _:a*):a*):1 (CONST #A):b):c*
1 (REDXOR (REP (NOT _:a*):a):b*):1
1 (REDXOR (REP (SEL@A _:a*):1*):b):1*
1 (REDXOR (REP (SEL@A _:a*):1*):b*):1
1 (REDXOR (SEL@0 (REP _:a):b*):c):1
1 (REP (NOT (REP _:1*):a*):a):b*
1 (REP (SEL@A (AND _:a* _:a*):a*):1*):b*
1 (SEL@0 (AND (NOT (VARPACKED):a):a* (NOT (VARPACKED):a):a*):a*):1
1 (SEL@0 (REPLICATE (NOT _:a*):a (CONST #A):a):b*):c
1 (SEL@A (AND (NOT (VARPACKED):a):a* (NOT (VARPACKED):a):a*):a*):1
1 (SEL@0 (REP (NOT _:a*):a):b*):c
1 (SEL@A (AND (NOT (VARPACKED):a):a* (NOT (VARPACKED):a):a*):a*):1*
1 (VARPACKED (AND (NOT (VARPACKED):a):a* (NOT (VARPACKED):a):a*):a*):a
1 (VARPACKED (CONCAT (REDXOR _:a*):1 (CONCAT _:1 _:b):c):d):d
1 (VARPACKED (REPLICATE (NOT _:a*):a (CONST #A):a):b*):b
1 (VARPACKED (REPLICATE (REPLICATE _:1 (CONST #A):a):b* (CONST #B):a):c*):c
1 (VARPACKED (REPLICATE (REPLICATE _:a* (CONST #A):b):c* (CONST #A):b):b*):b
1 (VARPACKED (REPLICATE (SEL@A _:a*):1 (CONST #A):b):c*):c
1 (VARPACKED (REP (NOT _:a*):a):b*):b
1 (VARPACKED (REP (SEL@A _:a*):1*):b*):b
DFG patterns with depth 4
3 (REP (SEL@A (AND (NOT (VARPACKED):a):a* (NOT (VARPACKED):a):a*):a*):1*):b
2 (REDXOR (REP (SEL@A (AND _:a* _:a*):a*):1*):b):1
1 (CONCAT (REDXOR (AND (NOT (VARPACKED):a):a* A:a*):a):1 (CONCAT (REDXOR (AND A:a* _:a*):a):1 (CONCAT (SEL@0 _:a*):1 (CONCAT _:1 _:b):c):d):e):f | A is (NOT (VARPACKED):a):a*
1 (CONCAT (REDXOR (AND (NOT (VARPACKED):a):a* A:a*):a):1 (CONCAT (SEL@0 (AND A:a* _:a*):a*):1 (CONCAT (REDXOR _:b*):1 (CONCAT _:1 _:c):d):e):b):f | A is (NOT (VARPACKED):a):a*
1 (CONCAT (REDXOR (AND (NOT (VARPACKED):a):a* A:a*):a):1 (CONCAT (SEL@0 (AND A:a* _:a*):a*):1 (CONCAT (REDXOR _:b):1 (CONCAT _:1 _:c):d):e):b):f | A is (NOT (VARPACKED):a):a*
1 (CONCAT (REDXOR (AND (NOT (VARPACKED):a):a* A:a*):a*):1 (CONCAT (REDXOR (AND A:a* _:a*):a):1 (CONCAT (REDXOR _:a):1 (CONCAT _:1 _:b):c):d):e):f | A is (NOT (VARPACKED):a):a*
1 (CONCAT (REDXOR (SEL@0 (REPLICATE _:a (CONST #A):a):b*):c):1 (REDXOR (REPLICATE (REPLICATE _:d* (CONST #A):a):a* (CONST #A):a):b):1*):e
1 (CONCAT (REDXOR A:a*):1 (CONCAT (REDXOR (REPLICATE A:a* (CONST #A):b):b*):1 (CONCAT (REDXOR _:c):1* (CONCAT _:1 _:d):e):f):g):h | A is (REPLICATE (REPLICATE _:1 (CONST #B):b):i* (CONST #A):b):a*
1 (CONCAT (REDXOR A:a*):1 (CONCAT (REDXOR (REPLICATE A:a* (CONST #A):b):c*):1 (CONCAT (REDXOR _:b*):1 (CONCAT _:1* _:d):e):f):g):h | A is (REPLICATE (SEL@A _:e*):1 (CONST #B):b):a*
1 (CONCAT (REDXOR A:a*):1 (CONCAT (REDXOR (SEL@0 A:a*):b):1 (REDXOR (REPLICATE B:c* (CONST #A):c):a):1*):d):e | A is (REPLICATE (NOT B:c*):c (CONST #A):c):a* | B is _:c*
1 (CONCAT (REDXOR A:a*):1 (CONCAT B:1* (CONCAT (REDXOR _:b*):1 (CONCAT _:1 B:1*):c):d):e):f | A is (REPLICATE (REPLICATE _:g* (CONST #A):a):h* (CONST #A):a):a* | B is (REDXOR (REPLICATE A:a* (CONST #A):a):b):1*
1 (CONCAT (SEL@0 (AND (NOT (VARPACKED):a):a* (NOT (VARPACKED):a):a*):a*):1 (CONCAT (REDXOR (REPLICATE _:1 (CONST #A):b):c*):1 (CONCAT (REDXOR _:d*):1 (CONCAT _:1 _:a):e):f):g):c
1 (CONCAT A:1* (CONCAT (REDXOR (REPLICATE _:a (CONST #A):a):b*):1 (CONCAT (REDXOR _:c):1 A:1*):d):e):f | A is (REDXOR B:b):1* | B is (REPLICATE (REPLICATE _:g* (CONST #A):a):a* (CONST #A):a):b
1 (NOT (REPLICATE (REPLICATE (REPLICATE _:1 (CONST #A):a):b* (CONST #B):a):c* (CONST #B):a):a*):a
1 (REDXOR (REPLICATE (NOT (REPLICATE _:a* (CONST #A):b):b*):b (CONST #A):b):c*):1
1 (REDXOR (REPLICATE (REPLICATE (REPLICATE _:1 (CONST #A):a):b* (CONST #B):a):c* (CONST #B):a):a*):1
1 (REDXOR (REPLICATE (REPLICATE (REPLICATE _:a* (CONST #A):b):c* (CONST #A):b):b* (CONST #A):b):d):1*
1 (REDXOR (REPLICATE (REPLICATE (SEL@A _:a*):1 (CONST #A):b):c* (CONST #B):b):d*):1
1 (REDXOR (REPLICATE (SEL@A (AND _:a* _:a*):a*):1 (CONST #A):b):c*):1
1 (REDXOR (SEL@0 (REPLICATE (NOT _:a*):a (CONST #A):a):b*):c):1
1 (REPLICATE (NOT (REPLICATE (REPLICATE _:a* (CONST #A):b):c* (CONST #A):b):b*):b (CONST #A):b):d*
1 (REPLICATE (REPLICATE (REPLICATE (REPLICATE _:1 (CONST #A):a):b* (CONST #B):a):c* (CONST #B):a):a* (CONST #B):a):d
1 (REPLICATE (REPLICATE (REPLICATE (SEL@A _:a*):1 (CONST #A):b):c* (CONST #B):b):d* (CONST #B):b):b*
1 (REPLICATE (REPLICATE (SEL@A (AND _:a* _:a*):a*):1 (CONST #A):b):c* (CONST #B):b):d*
1 (REPLICATE (SEL@A (AND (NOT (VARPACKED):a):a* (NOT (VARPACKED):a):a*):a*):1 (CONST #A):b):c*
1 (SEL@0 (REPLICATE (NOT (REPLICATE _:a* (CONST #A):b):b*):b (CONST #A):b):c*):d
1 (CONCAT (REDXOR (REP A:1*):a):1 (CONCAT (REDXOR (REP A:1*):b):1 (CONCAT (REDXOR _:c*):1 (CONCAT _:1* _:d):e):f):g):h | A is (SEL@A _:e*):1*
1 (CONCAT (REDXOR (REP A:1*):a):1 (CONCAT (REDXOR (REP A:1*):b*):1 (CONCAT (REDXOR _:c):1* (CONCAT _:1 _:d):e):f):g):h | A is (SEL@A _:f*):1*
1 (CONCAT (REDXOR (REP A:1*):a*):1 (CONCAT B:1* (CONCAT (REDXOR _:b*):1 (CONCAT _:1 B:1*):c):d):e):f | A is (SEL@A _:e*):1* | B is (REDXOR (REP A:1*):b):1*
1 (CONCAT (REDXOR (SEL@0 (REP _:a):b*):c):1 (REDXOR (REP (SEL@A _:d*):1*):b):1*):e
1 (CONCAT (REDXOR A:a*):1 (CONCAT (REDXOR (SEL@0 A:a*):b):1 (REDXOR (REP _:1*):a):1*):c):d | A is (REP (NOT _:e*):e):a*
1 (CONCAT (SEL@0 (AND (NOT (VARPACKED):a):a* (NOT (VARPACKED):a):a*):a*):1 (CONCAT (REDXOR (REP _:1*):b):1 (CONCAT (REDXOR _:c):1 (CONCAT _:1 _:a):d):e):f):b
1 (CONCAT A:1* (CONCAT (REDXOR (REP _:a):b*):1 (CONCAT (REDXOR _:c):1 A:1*):d):e):f | A is (REDXOR B:b):1* | B is (REP (SEL@A _:f*):1*):b
1 (NOT (REP (SEL@A (AND _:a* _:a*):a*):1*):b*):b
1 (REDXOR (REP (NOT (REP _:1*):a*):a):b*):1
1 (REDXOR (REP (SEL@A (AND _:a* _:a*):a*):1*):b):1*
1 (REDXOR (REP (SEL@A (AND _:a* _:a*):a*):1*):b*):1
1 (REDXOR (SEL@0 (REP (NOT _:a*):a):b*):c):1
1 (REP (NOT (REP (SEL@A _:a*):1*):b*):b):c*
1 (REP (SEL@A (AND (NOT (VARPACKED):a):a* (NOT (VARPACKED):a):a*):a*):1*):b*
1 (SEL@0 (REP (NOT (REP _:1*):a*):a):b*):c
1 (VARPACKED (CONCAT (REDXOR (AND _:a* _:a*):a*):1 (CONCAT (REDXOR _:a):1 (CONCAT _:1 _:b):c):d):e):e
1 (VARPACKED (REPLICATE (NOT (REPLICATE _:a* (CONST #A):b):b*):b (CONST #A):b):c*):c
1 (VARPACKED (REPLICATE (REPLICATE (REPLICATE _:1 (CONST #A):a):b* (CONST #B):a):c* (CONST #B):a):a*):a
1 (VARPACKED (REPLICATE (REPLICATE (SEL@A _:a*):1 (CONST #A):b):c* (CONST #B):b):d*):d
1 (VARPACKED (REPLICATE (SEL@A (AND _:a* _:a*):a*):1 (CONST #A):b):c*):c
1 (VARPACKED (REP (NOT (REP _:1*):a*):a):b*):b
1 (VARPACKED (REP (SEL@A (AND _:a* _:a*):a*):1*):b*):b

View File

@ -326,6 +326,7 @@ module t (
`signal(REMOVE_NEQ_BIT_0, 1'b0 != rand_a[0]);
`signal(REPLACE_NEQ_BIT_1, 1'b1 != rand_a[0]);
`signal(REPLACE_COND_INSERT, rand_a[0] ? {rand_b[63:40], {1'd0, rand_b[38:0]}} : rand_b);
`signal(REPLACE_REP_REP, {2{({3{rand_a[0]}})}});
// Operators that should work wiht mismatched widths
`signal(MISMATCHED_ShiftL,const_a << 4'd2);