diff --git a/src/commands/img_fanout.hpp b/src/commands/img_fanout.hpp new file mode 100644 index 0000000..1fb515b --- /dev/null +++ b/src/commands/img_fanout.hpp @@ -0,0 +1,63 @@ +#pragma once +#ifndef IMG_FANOUT_HPP +#define IMG_FANOUT_HPP + +#include +#include "../networks/img/img.hpp" +#include "../core/fanout.hpp" +#include "../networks/img/fc_cost.hpp" + +using namespace also; + +namespace alice +{ + + class img_fanout_command : public command + { + public: + explicit img_fanout_command(const environment::ptr& env) : command(env, "Performs IMG fanout") + { + } + + std::array get_children(img_network img, img_network::node const& n ) const + { + std::array children; + img.foreach_fanin( n, [&children]( auto const& f, auto i ) { children[i] = f; } ); + return children; + } + + + int not_imply_gate(const img_network& img ) + { + int num=0; + img.foreach_node([&](auto n){ + auto cs = get_children(img,n); + if(cs[1].index == 0 ) num++; + }); + return num; + } + + protected: + void execute() + { + img_network img = store().current(); + + while(total_fc_cost(img)!=0) + { + img = cleanup_dangling(img); + depth_view img11{img}; + img_fanout_rewriting(img11); + } + + std::cout<<"[cost_function] pulse: "<().extend(); + store().current() = img; + } + + }; + ALICE_ADD_COMMAND(img_fanout, "Rewriting") +} +#endif + diff --git a/src/core/fanout.hpp b/src/core/fanout.hpp new file mode 100644 index 0000000..62e9798 --- /dev/null +++ b/src/core/fanout.hpp @@ -0,0 +1,150 @@ + +#pragma once +#include +#include +#include "../networks/img/img.hpp" +#include + +namespace mockturtle +{ + +namespace detail +{ + + template + class img_fanout_rewriting_impl + { + public: + img_fanout_rewriting_impl(Ntk& ntk) + : ntk(ntk) + { + } + + void run() + { + topo_view topo(ntk); + topo.foreach_node([&](auto n){ + if (!ntk.is_constant(n)&& !ntk.is_pi(n) && !is_not(n)) + { + deal_with(ntk,n); + } + }); + } + + void deal_with(Ntk& ntk, node const& n) + { + auto cs = get_children(n); + auto n1 = ntk.get_node(cs[1]); + + std::vector> parents_right, parents_left; + if (ntk.fanout_size(n1) >= 2u ) + { + ntk.foreach_node([&](auto p) { + auto ocs = get_children(p); + if(ntk.get_node(ocs[0])==n1) + { + parents_right.push_back(p); + } + else if (ntk.get_node(ocs[1])==n1) + { + parents_left.push_back(p); + } + }); + + + if (parents_left.size() == 1u ) + { + auto p = parents_left[0]; + assert(p == n); + + for (auto i : parents_right) + { + auto ics = get_children(i); + if (ics[0] == cs[1] && ics[1] == cs[0]) //confliting fanout + { + if (is_not(n1)) + { + fanout_bn(n); + } + fanout(n); + } + } + } + else if (parents_left.size() > 1u) + { + // if (is_not(n1)) + // { + // fanout_bn(n); + // } + // else + // { + fanout(n); + // } + } + } + + } + + void fanout(node const& n) + { + const auto cs = get_children(n); + + auto opt = ntk.create_imp(ntk.create_not(cs[1]), ntk.create_not(cs[0])); + ntk.substitute_node(n, opt); + ntk.update_levels(); + + } + + void fanout_bn(node const& n) + { + auto cs = get_children(n); + auto cs1 = get_children(ntk.get_node(cs[1])); + assert(cs1[1].index == 0); + + auto opt = ntk.create_imp(cs1[0], ntk.create_not(cs[0])); + ntk.substitute_node(n, opt); + ntk.update_levels(); + } + + std::array, 2> get_children(node const& n) const + { + std::array, 2> children; + ntk.foreach_fanin(n, [&children](auto const& f, auto i) { children[i] = f; }); + return children; + } + + bool is_not(node const& n) + { + auto cs = get_children(n); + if (cs[1].index == 0) return true; + return false; + } + + private: + Ntk& ntk; + std::pair,node> conflicting_node; + }; + + +} + template + void img_fanout_rewriting(Ntk& ntk) + { + static_assert(is_network_type_v, "Ntk is not a network type"); + static_assert(has_get_node_v, "Ntk does not implement the get_node method"); + static_assert(has_level_v, "Ntk does not implement the level method"); + static_assert(has_substitute_node_v, "Ntk does not implement the substitute_node method"); + static_assert(has_update_levels_v, "Ntk does not implement the update_levels method"); + static_assert(has_foreach_node_v, "Ntk does not implement the foreach_node method"); + static_assert(has_foreach_po_v, "Ntk does not implement the foreach_po method"); + static_assert(has_foreach_fanin_v, "Ntk does not implement the foreach_fanin method"); + static_assert(has_clear_values_v, "Ntk does not implement the clear_values method"); + static_assert(has_set_value_v, "Ntk does not implement the set_value method"); + static_assert(has_value_v, "Ntk does not implement the value method"); + static_assert(has_fanout_size_v, "Ntk does not implement the fanout_size method"); + + detail::img_fanout_rewriting_impl p(ntk); + p.run(); + } +} +