diff --git a/sim_resubstitution.cpp b/sim_resubstitution.cpp new file mode 100644 index 0000000..98a5ded --- /dev/null +++ b/sim_resubstitution.cpp @@ -0,0 +1,183 @@ +/* mockturtle: C++ logic network library + * Copyright (C) 2018-2022 EPFL + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +//#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +int main( int argc, char* argv[] ) +{ + if ( argc != 2 ) + { + std::cout << "Received " << argc << "\n"; + std::cout << "[e] Please give exactly one argument, which is a AIG file to be processed\n"; + std::cout << " For example: ./sim_resubstition test.aig\n"; + return -1; + } + + using namespace experiments; + using namespace mockturtle; + + experiment exp( "sim_resubstitution", "benchmark", "size", "gain", "runtime"); + + std::string benchmark( argv[1] ); + std::string filename_trimed; + + fmt::print( "[i] processing {}\n", benchmark ); + muxig_network muxig; + cover_network temp; + + + if ( benchmark.size() > 5 && benchmark.substr( benchmark.size() - 5, 5 ) == ".blif" ) + { + filename_trimed = benchmark.substr( 0, benchmark.size() - 5 ); + + std::cout << "received: " << benchmark << "\n"; + + if ( lorina::read_blif( benchmark, blif_reader( temp ) ) != lorina::return_code::success ) + { + std::cout << "Error in reading file\n"; + return 1; + } + } else + { + std::cout << "received: " << benchmark << "\n"; + std::cout << "[e] Argument does not end with .aig\n"; + std::cout << "[i] Usage: ./muxig_rewriting_with_resynthesis [AIGER or Verilog filename]\n"; + return -1; + } + muxig = convert_cover_to_graph(temp); + + resubstitution_params ps; + resubstitution_stats st; + mockturtle::write_blif(muxig, filename_trimed + "_direct_conversion.blif"); + + //mockturtle::print(muxig); + + //ps.pattern_filename = "1024sa1/" + benchmark + ".pat"; + ps.max_inserts = 20; + ps.max_pis = 10; + ps.progress = true; + ps.verbose = true; + + ps.max_divisors = std::numeric_limits::max(); + + const uint32_t size_before = muxig.num_gates(); + sim_resubstitution( muxig, ps, &st ); + //mockturtle::print(muxig); + muxig = cleanup_dangling( muxig ); + + fanout_view fnntk(muxig); + + muxig.foreach_node( [&]( auto node ) { + if(muxig.is_mux(node) && (muxig.fanin_size(node)==3)){ + std::cout << "running normalization on node " << node << "\n"; + muxig_network::normalization_result results = muxig.normalized_fanins(muxig._storage->nodes[node].children[0],muxig._storage->nodes[node].children[1],muxig._storage->nodes[node].children[2]); + }}); + + + muxig.foreach_node( [&]( auto node ) { + if(muxig.is_mux(node) && (muxig.fanin_size(node)==3)){ + uint32_t inv = muxig.fanout_size(node); + std::cout << "now in node " << node << " with fanout size " << inv << "\n"; + + std::vector> fanout_stack; + + fnntk.foreach_fanout(node, [&]( auto fan_out ){ + std::cout << "Currently in fanout " << fan_out << "\n"; + int i = 0; + muxig.foreach_fanin(fan_out, [&]( auto signal ) { + + if(muxig.get_node(signal)==node){ + if(signal.complement){ + inv--; + } + fanout_stack.emplace_back(fan_out,i); + } + + i++; + + }); + }); + + if(inv == 0 && muxig.fanout_size(node) != 0){ + std::cout << "Found complemented output, will normalize\n"; + if(muxig._storage->nodes[node].children[1] == 0 && muxig.is_complemented(muxig._storage->nodes[node].children[1]) == 0 && muxig._storage->nodes[node].children[2] != 0){ + std::cout << "switching ANDNOT to ORNOT internal\n"; + std::swap(muxig._storage->nodes[node].children[0],muxig._storage->nodes[node].children[2]); + std::swap(muxig._storage->nodes[node].children[1],muxig._storage->nodes[node].children[2]); + muxig._storage->nodes[node].children[2] = muxig.get_constant(true); + for (const auto& [node, child] : fanout_stack) { + muxig._storage->nodes[node].children[child] = muxig.create_not(muxig._storage->nodes[node].children[child]); + } + } + if(muxig._storage->nodes[node].children[2] == 0 && muxig.is_complemented(muxig._storage->nodes[node].children[2]) == 1 && muxig._storage->nodes[node].children[1] != 0){ + std::cout << "switching ORNOT to ANDNOT internal\n"; + std::swap(muxig._storage->nodes[node].children[0],muxig._storage->nodes[node].children[1]); + std::swap(muxig._storage->nodes[node].children[1],muxig._storage->nodes[node].children[2]); + muxig._storage->nodes[node].children[1] = muxig.get_constant(false); + for (const auto& [node, child] : fanout_stack) { + muxig._storage->nodes[node].children[child] = muxig.create_not(muxig._storage->nodes[node].children[child]); + } + } + + + + //std::swap(,muxig._storage->nodes[node].children[1]); + //muxig.normalized_fanout(muxig._storage->nodes[node].children[0],muxig._storage->nodes[node].children[1],muxig._storage->nodes[node].children[2]); + } + } + }); + + //mockturtle::print(muxig); + mockturtle::write_blif(muxig, filename_trimed + "_mockturtle.blif"); + mockturtle::write_dot(muxig,filename_trimed + "_mockturtle.dot"); + exp( benchmark, size_before, size_before - muxig.num_gates(), to_seconds( st.time_total )); + exp.save(); + exp.table(); + + return 0; +} \ No newline at end of file diff --git a/yosys/bruteforce.ys b/yosys/bruteforce.ys index b9df483..9e50cb9 100644 --- a/yosys/bruteforce.ys +++ b/yosys/bruteforce.ys @@ -1,38 +1,38 @@ read_verilog {{FILE}} #map to basic cells proc;; techmap;; opt;; aigmap;; splitnets;; #show -prefix ./temp/{{MODULE}}_bruteforce_aig_{{LIBERTY_USED}} -color orange t:$_NOT_ -color darkred t:$_AND_ -color purple t:$ge -color darkblue t:$ne -color blue t:$le -color maroon t:$add -enum write_blif ./temp/{{FILE_BASENAME}}.blif -exec -- ./abc/abc -c "read_blif ./temp/{{FILE_BASENAME}}.blif; compress2rs; write_blif ./temp/{{FILE_BASENAME}}_abc.blif" +#exec -- ./abc/abc -c "read_blif ./temp/{{FILE_BASENAME}}.blif; compress2rs; write_blif ./temp/{{FILE_BASENAME}}_abc.blif" #abc -liberty ./nem_liberty/{{LIBERTY_FILE}} -script "+strash; &get -n; collapse; write_eqn ./temp/{{FILE_BASENAME}}.eqn; &write_truths -x ./temp/{{FILE_BASENAME}}.truth" delete -exec -- ./mockturtle/debug/experiments/sim_resubstitution ./temp/{{FILE_BASENAME}}_abc.blif -exec -- python3 ./yosys/map_ports.py ./temp/{{FILE_BASENAME}}.blif ./temp/{{FILE_BASENAME}}_abc_mockturtle.blif +exec -- ./mockturtle/debug/experiments/sim_resubstitution ./temp/{{FILE_BASENAME}}.blif +exec -- python3 ./yosys/map_ports.py ./temp/{{FILE_BASENAME}}.blif ./temp/{{FILE_BASENAME}}_mockturtle.blif -read_blif ./temp/mapped_{{FILE_BASENAME}}_abc_mockturtle.blif +read_blif ./temp/mapped_{{FILE_BASENAME}}_mockturtle.blif rename top {{MODULE}}_nem techmap -map ./yosys/mockturtle_map.v techmap opt_expr clean -purge abc -liberty ./nem_liberty/{{LIBERTY_FILE}} -script "+attach" clean -purge write_verilog -selected ./temp/{{FILE_BASENAME}}_nem.v #Output stats tee -o ./temp/{{FILE_BASENAME}}_MUX.stat stat -liberty ./nem_liberty/{{LIBERTY_FILE}}