diff --git a/src/commands/cut_rewriting.hpp b/src/commands/cut_rewriting.hpp new file mode 100644 index 0000000..2b54810 --- /dev/null +++ b/src/commands/cut_rewriting.hpp @@ -0,0 +1,178 @@ +/* phyLS: powerful heightened yielded Logic Synthesis + * Copyright (C) 2022 */ + +/** + * @file cut_rewriting.hpp + * + * @brief on-the-fly DAG-aware logic rewriting + * + * @author Homyoung + * @since 2022/12/15 + */ + +#ifndef CUT_REWRITING_HPP +#define CUT_REWRITING_HPP + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../core/misc.hpp" + +using namespace std; +using namespace mockturtle; + +namespace alice { +class rewrite_command : public command { + public: + explicit rewrite_command(const environment::ptr& env) + : command(env, "on-the-fly DAG-aware logic rewriting") { + add_flag("--xmg, -x", "rewriting for XMG"); + add_flag("--mig, -m", "rewriting for MIG"); + add_flag("--xag, -g", "rewriting for XAG"); + add_flag("--klut, -l", "rewriting for k-LUT"); + add_flag("--akers, -a", "Cut rewriting with Akers synthesis for MIG"); + add_flag("--compatibility_graph, -c", "In-place cut rewriting"); + add_flag("--verbose, -v", "print the information"); + } + + protected: + void execute() { + clock_t begin, end; + double totalTime; + + if (is_set("xmg")) { + if (store().size() == 0u) + std::cerr << "Error: Empty XMG network\n"; + else { + auto xmg = store().current(); + begin = clock(); + xmg_npn_resynthesis resyn; + cut_rewriting_params ps; + ps.cut_enumeration_ps.cut_size = 4u; + if (is_set("compatibility_graph")) + cut_rewriting_with_compatibility_graph(xmg, resyn, ps); + else + xmg = cut_rewriting(xmg, resyn, ps); + xmg = cleanup_dangling(xmg); + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; + phyLS::print_stats(xmg); + store().extend(); + store().current() = xmg; + } + } else if (is_set("mig")) { + if (store().size() == 0u) + std::cerr << "Error: Empty MIG network\n"; + else { + auto mig = store().current(); + begin = clock(); + if (is_set("akers")) { + akers_resynthesis resyn; + cut_rewriting_params ps; + ps.cut_enumeration_ps.cut_size = 4u; + if (is_set("compatibility_graph")) + cut_rewriting_with_compatibility_graph(mig, resyn, ps); + else + mig = cut_rewriting(mig, resyn, ps); + } else { + mig_npn_resynthesis resyn; + cut_rewriting_params ps; + ps.cut_enumeration_ps.cut_size = 4u; + if (is_set("compatibility_graph")) + cut_rewriting_with_compatibility_graph(mig, resyn, ps); + else + mig = cut_rewriting(mig, resyn, ps); + } + mig = cleanup_dangling(mig); + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; + phyLS::print_stats(mig); + store().extend(); + store().current() = mig; + } + } else if (is_set("xag")) { + if (store().size() == 0u) + std::cerr << "Error: Empty XAG network\n"; + else { + auto xag = store().current(); + begin = clock(); + xag_npn_resynthesis resyn; + cut_rewriting_params ps; + ps.cut_enumeration_ps.cut_size = 4u; + ps.min_cand_cut_size = 2; + ps.min_cand_cut_size_override = 3; + if (is_set("compatibility_graph")) { + cut_rewriting_with_compatibility_graph(xag, resyn, ps, nullptr, + mc_cost()); + } else { + xag = cut_rewriting(xag, resyn, ps); + } + xag = cleanup_dangling(xag); + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; + phyLS::print_stats(xag); + store().extend(); + store().current() = xag; + } + } else if (is_set("klut")) { + if (store().size() == 0u) + std::cerr << "Error: Empty k-LUT network\n"; + else { + auto klut = store().current(); + begin = clock(); + exact_resynthesis resyn(3u); + if (is_set("compatibility_graph")) + cut_rewriting_with_compatibility_graph(klut, resyn); + else + klut = cut_rewriting(klut, resyn); + klut = cleanup_dangling(klut); + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; + phyLS::print_stats(klut); + store().extend(); + store().current() = klut; + } + } else { + if (store().size() == 0u) + std::cerr << "Error: Empty AIG network\n"; + else { + auto aig = store().current(); + begin = clock(); + xag_npn_resynthesis resyn; + cut_rewriting_params ps; + ps.cut_enumeration_ps.cut_size = 4; + aig = cut_rewriting(aig, resyn, ps); + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; + phyLS::print_stats(aig); + store().extend(); + store().current() = aig; + } + } + + cout.setf(ios::fixed); + cout << "[CPU time] " << setprecision(2) << totalTime << " s" << endl; + } +}; + +ALICE_ADD_COMMAND(rewrite, "Logic synthesis") + +} // namespace alice + +#endif diff --git a/src/commands/node_resynthesis.hpp b/src/commands/node_resynthesis.hpp index 3ac97e2..40ebdfd 100644 --- a/src/commands/node_resynthesis.hpp +++ b/src/commands/node_resynthesis.hpp @@ -40,7 +40,8 @@ class resyn_command : public command { public: explicit resyn_command(const environment::ptr& env) : command(env, - "performs technology-independent restructuring : using MIG as default") { + "performs technology-independent restructuring : using MIG as " + "default") { add_flag("--xmg, -x", "Resubstitution for XMG"); add_flag("--xag, -g", "Resubstitution for XAG"); add_flag("--direct, -d", "Node resynthesis with direct synthesis"); @@ -74,8 +75,8 @@ class resyn_command : public command { totalTime = (double)(end - begin) / CLOCKS_PER_SEC; } else if (is_set("xag")) { begin = clock(); - direct_resynthesis xag_resyn; - const auto xag = node_resynthesis(klut, xag_resyn); + xag_npn_resynthesis resyn; + const auto xag = node_resynthesis(klut, resyn); store().extend(); store().current() = cleanup_dangling(xag); phyLS::print_stats(xag); diff --git a/src/commands/refactor.hpp b/src/commands/refactor.hpp index 8369112..37f0ec3 100644 --- a/src/commands/refactor.hpp +++ b/src/commands/refactor.hpp @@ -49,14 +49,21 @@ class refactor_command : public command { std::cerr << "Error: Empty MIG network\n"; else { auto mig = store().current(); + begin = clock(); if (is_set("akers")) { akers_resynthesis resyn; - refactoring(mig, resyn); + refactoring_params ps; + ps.max_pis = 4u; + refactoring(mig, resyn, ps); } else { mig_npn_resynthesis resyn; - refactoring(mig, resyn); + refactoring_params ps; + ps.max_pis = 4u; + refactoring(mig, resyn, ps); } mig = cleanup_dangling(mig); + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; phyLS::print_stats(mig); store().extend(); store().current() = mig; @@ -66,9 +73,14 @@ class refactor_command : public command { std::cerr << "Error: Empty XAG network\n"; else { auto xag = store().current(); + begin = clock(); bidecomposition_resynthesis resyn; - refactoring(xag, resyn); + refactoring_params ps; + ps.max_pis = 4u; + refactoring(xag, resyn, ps); xag = cleanup_dangling(xag); + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; phyLS::print_stats(xag); store().extend(); store().current() = xag; @@ -78,9 +90,14 @@ class refactor_command : public command { std::cerr << "Error: Empty XMG network\n"; else { auto xmg = store().current(); + begin = clock(); xmg_npn_resynthesis resyn; - refactoring(xmg, resyn); + refactoring_params ps; + ps.max_pis = 4u; + refactoring(xmg, resyn, ps); xmg = cleanup_dangling(xmg); + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; phyLS::print_stats(xmg); store().extend(); store().current() = xmg; @@ -90,9 +107,14 @@ class refactor_command : public command { std::cerr << "Error: Empty AIG network\n"; else { auto aig = store().current(); + begin = clock(); direct_resynthesis aig_resyn; - refactoring(aig, aig_resyn); + refactoring_params ps; + ps.max_pis = 4u; + refactoring(aig, aig_resyn, ps); aig = cleanup_dangling(aig); + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; phyLS::print_stats(aig); store().extend(); store().current() = aig; diff --git a/src/phyLS.cpp b/src/phyLS.cpp index bf5dfcb..8cae23f 100644 --- a/src/phyLS.cpp +++ b/src/phyLS.cpp @@ -35,5 +35,6 @@ #include "commands/techmap.hpp" #include "commands/write_dot.hpp" #include "commands/refactor.hpp" +#include "commands/cut_rewriting.hpp" ALICE_MAIN(phyLS) \ No newline at end of file