diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index 7d4a3842d..06cda4604 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -5784,6 +5784,7 @@ public: }; class AstOneHot final : public AstNodeUniop { // True if only single bit set in vector + // @astgen makeDfgVertex public: AstOneHot(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_OneHot(fl, lhsp) { @@ -5801,6 +5802,7 @@ public: }; class AstOneHot0 final : public AstNodeUniop { // True if only single bit, or no bits set in vector + // @astgen makeDfgVertex public: AstOneHot0(FileLine* fl, AstNodeExpr* lhsp) : ASTGEN_SUPER_OneHot0(fl, lhsp) { diff --git a/src/V3Dfg.cpp b/src/V3Dfg.cpp index df68246aa..d51250bc3 100644 --- a/src/V3Dfg.cpp +++ b/src/V3Dfg.cpp @@ -774,7 +774,9 @@ void DfgVertex::typeCheck(const DfgGraph& dfg) const { case VDfgType::LogNot: case VDfgType::RedAnd: case VDfgType::RedOr: - case VDfgType::RedXor: { + case VDfgType::RedXor: + case VDfgType::OneHot: + case VDfgType::OneHot0: { CHECK(dtype() == DfgDataType::packed(1), "Should be 1-bit"); CHECK(inputp(0)->isPacked(), "Operand should be Packed type"); return; diff --git a/src/V3DfgCse.cpp b/src/V3DfgCse.cpp index abce554ba..40aa85190 100644 --- a/src/V3DfgCse.cpp +++ b/src/V3DfgCse.cpp @@ -110,6 +110,8 @@ class V3DfgCse final { case VDfgType::NeqCase: case VDfgType::NeqWild: case VDfgType::Not: + case VDfgType::OneHot: + case VDfgType::OneHot0: case VDfgType::Or: case VDfgType::Pow: case VDfgType::PowSS: @@ -232,6 +234,8 @@ class V3DfgCse final { case VDfgType::NeqCase: case VDfgType::NeqWild: case VDfgType::Not: + case VDfgType::OneHot: + case VDfgType::OneHot0: case VDfgType::Or: case VDfgType::Pow: case VDfgType::PowSS: diff --git a/src/V3DfgPeephole.cpp b/src/V3DfgPeephole.cpp index f8a9a2b46..7c0fc7e25 100644 --- a/src/V3DfgPeephole.cpp +++ b/src/V3DfgPeephole.cpp @@ -143,6 +143,8 @@ template <> void foldOp (V3Number& out, const V3Number& src) { ou template <> void foldOp (V3Number& out, const V3Number& src) { out.opLogNot(src); } template <> void foldOp (V3Number& out, const V3Number& src) { out.opNegate(src); } template <> void foldOp (V3Number& out, const V3Number& src) { out.opNot(src); } +template <> void foldOp (V3Number& out, const V3Number& src) { out.opOneHot(src); } +template <> void foldOp (V3Number& out, const V3Number& src) { out.opOneHot0(src); } template <> void foldOp (V3Number& out, const V3Number& src) { out.opRedAnd(src); } template <> void foldOp (V3Number& out, const V3Number& src) { out.opRedOr(src); } template <> void foldOp (V3Number& out, const V3Number& src) { out.opRedXor(src); } @@ -1325,6 +1327,14 @@ class V3DfgPeephole final : public DfgVisitor { } } + void visit(DfgOneHot* const vtxp) override { + if (foldUnary(vtxp)) return; + } + + void visit(DfgOneHot0* const vtxp) override { + if (foldUnary(vtxp)) return; + } + void visit(DfgRedOr* const vtxp) override { if (optimizeReduction(vtxp)) return; } diff --git a/test_regress/t/t_dfg_peephole.v b/test_regress/t/t_dfg_peephole.v index aa15acf60..9e5c64da4 100644 --- a/test_regress/t/t_dfg_peephole.v +++ b/test_regress/t/t_dfg_peephole.v @@ -62,6 +62,12 @@ module t ( //verilator lint_on WIDTH `signal(FOLD_UNARY_Extend, tmp_FOLD_UNARY_Extend); `signal(FOLD_UNARY_ExtendS, tmp_FOLD_UNARY_ExtendS); + `signal(FOLD_UNARY_OneHot, $onehot(const_a)); + `signal(FOLD_UNARY_OneHot0, $onehot0(const_a)); + `signal(FOLD_UNARY_OneHot_A, $onehot(const_a[0])); + `signal(FOLD_UNARY_OneHot_B, $onehot(~const_a[0])); + `signal(FOLD_UNARY_OneHot0_A, $onehot0(const_a[0])); + `signal(FOLD_UNARY_OneHot0_B, $onehot0(~const_a[0])); `signal(FOLD_BINARY_Add, const_a + const_b); `signal(FOLD_BINARY_And, const_a & const_b);