update for exact synthesis
parent
b0ca41c4aa
commit
ed84ad922e
|
@ -3,7 +3,7 @@
|
||||||
url = https://github.com/msoeken/alice.git
|
url = https://github.com/msoeken/alice.git
|
||||||
[submodule "lib/mockturtle"]
|
[submodule "lib/mockturtle"]
|
||||||
path = lib/mockturtle
|
path = lib/mockturtle
|
||||||
url = https://github.com/lsils/mockturtle.git
|
url = https://github.com/panhomyoung/mockturtle.git
|
||||||
[submodule "lib/abc"]
|
[submodule "lib/abc"]
|
||||||
path = lib/abc
|
path = lib/abc
|
||||||
url = https://github.com/berkeley-abc/abc.git
|
url = https://github.com/berkeley-abc/abc.git
|
|
@ -1 +1 @@
|
||||||
Subproject commit da2b5e697d2dc988746fb94aceaebb277d385b83
|
Subproject commit fac58aa217f7b4c4d5327b201f5e9fe8cbf9ee6a
|
|
@ -0,0 +1,134 @@
|
||||||
|
/* phyLS: Advanced Logic Synthesis and Optimization tool
|
||||||
|
* Copyright (C) 2019- Ningbo University, Ningbo, China */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file cutrw.hpp
|
||||||
|
*
|
||||||
|
* @brief cut rewriting
|
||||||
|
*
|
||||||
|
* @author Zhufei Chu
|
||||||
|
* @since 0.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CUTRW_HPP
|
||||||
|
#define CUTRW_HPP
|
||||||
|
|
||||||
|
#include <mockturtle/algorithms/node_resynthesis/bidecomposition.hpp>
|
||||||
|
#include <mockturtle/mockturtle.hpp>
|
||||||
|
|
||||||
|
#include "../core/misc.hpp"
|
||||||
|
#include "../networks/aoig/xag_lut_npn.hpp"
|
||||||
|
#include "../networks/stp/stp_npn.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class cutrw_command : public command {
|
||||||
|
public:
|
||||||
|
explicit cutrw_command(const environment::ptr& env)
|
||||||
|
: command(env, "Performs cut rewriting") {
|
||||||
|
add_flag("--xag_npn_lut,-g", "cut rewriting based on xag_npn_lut");
|
||||||
|
add_flag("--xag_npn,-p", "cut rewriting based on xag_npn");
|
||||||
|
add_flag("--klut_npn,-l", "cut rewriting based on klut_npn");
|
||||||
|
add_flag("--compatibility_graph, -c", "In-place cut rewriting");
|
||||||
|
}
|
||||||
|
|
||||||
|
void execute() {
|
||||||
|
clock_t begin, end;
|
||||||
|
double totalTime = 0.0;
|
||||||
|
begin = clock();
|
||||||
|
/* parameters */
|
||||||
|
if (is_set("xag_npn_lut")) {
|
||||||
|
xag_network xag = store<xag_network>().current();
|
||||||
|
|
||||||
|
phyLS::print_stats(xag);
|
||||||
|
|
||||||
|
xag_npn_lut_resynthesis resyn;
|
||||||
|
cut_rewriting_params ps;
|
||||||
|
ps.cut_enumeration_ps.cut_size = 4u;
|
||||||
|
xag = cut_rewriting(xag, resyn, ps);
|
||||||
|
|
||||||
|
xag = cleanup_dangling(xag);
|
||||||
|
|
||||||
|
// bidecomposition refactoring
|
||||||
|
bidecomposition_resynthesis<xag_network> resyn2;
|
||||||
|
refactoring(xag, resyn2);
|
||||||
|
|
||||||
|
xag = cleanup_dangling(xag);
|
||||||
|
|
||||||
|
phyLS::print_stats(xag);
|
||||||
|
|
||||||
|
store<xag_network>().extend();
|
||||||
|
store<xag_network>().current() = cleanup_dangling(xag);
|
||||||
|
} else if (is_set("xag_npn")) {
|
||||||
|
begin = clock();
|
||||||
|
xag_network xag = store<xag_network>().current();
|
||||||
|
|
||||||
|
phyLS::print_stats(xag);
|
||||||
|
|
||||||
|
xag_npn_resynthesis<xag_network> 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;
|
||||||
|
xag = cut_rewriting(xag, resyn, ps);
|
||||||
|
xag = cleanup_dangling(xag);
|
||||||
|
|
||||||
|
phyLS::print_stats(xag);
|
||||||
|
end = clock();
|
||||||
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
store<xag_network>().extend();
|
||||||
|
store<xag_network>().current() = cleanup_dangling(xag);
|
||||||
|
} else if (is_set("klut_npn")) {
|
||||||
|
klut_network klut = store<klut_network>().current();
|
||||||
|
phyLS::print_stats(klut);
|
||||||
|
|
||||||
|
stp_npn_resynthesis resyn;
|
||||||
|
cut_rewriting_params ps;
|
||||||
|
ps.cut_enumeration_ps.cut_size = 4u;
|
||||||
|
ps.allow_zero_gain = false;
|
||||||
|
if (is_set("compatibility_graph"))
|
||||||
|
cut_rewriting_with_compatibility_graph(klut, resyn);
|
||||||
|
else
|
||||||
|
klut = cut_rewriting(klut, resyn, ps);
|
||||||
|
klut = cleanup_dangling(klut);
|
||||||
|
|
||||||
|
phyLS::print_stats(klut);
|
||||||
|
store<klut_network>().extend();
|
||||||
|
store<klut_network>().current() = cleanup_dangling(klut);
|
||||||
|
} else {
|
||||||
|
xmg_network xmg = store<xmg_network>().current();
|
||||||
|
|
||||||
|
phyLS::print_stats(xmg);
|
||||||
|
|
||||||
|
xmg_npn_resynthesis resyn;
|
||||||
|
cut_rewriting_params ps;
|
||||||
|
ps.cut_enumeration_ps.cut_size = 4u;
|
||||||
|
xmg = cut_rewriting(xmg, resyn, ps);
|
||||||
|
xmg = cleanup_dangling(xmg);
|
||||||
|
|
||||||
|
phyLS::print_stats(xmg);
|
||||||
|
|
||||||
|
store<xmg_network>().extend();
|
||||||
|
store<xmg_network>().current() = cleanup_dangling(xmg);
|
||||||
|
}
|
||||||
|
|
||||||
|
end = clock();
|
||||||
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
cout.setf(ios::fixed);
|
||||||
|
cout << "[Total CPU time] : " << setprecision(3) << totalTime << " s"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool verbose = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
ALICE_ADD_COMMAND(cutrw, "Synthesis")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,590 @@
|
||||||
|
/* phyLS: Advanced Logic Synthesis and Optimization tool
|
||||||
|
* Copyright (C) 2019-2021 Ningbo University, Ningbo, China */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file exact_lut.hpp
|
||||||
|
*
|
||||||
|
* @brief STP based exact synthesis
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2022/11/23
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EXACTLUT_HPP
|
||||||
|
#define EXACTLUT_HPP
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <alice/alice.hpp>
|
||||||
|
#include <mockturtle/mockturtle.hpp>
|
||||||
|
#include <percy/percy.hpp>
|
||||||
|
|
||||||
|
#include "../../core/exact/exact_dag.hpp"
|
||||||
|
#include "../../core/exact/exact_lut.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace percy;
|
||||||
|
using namespace mockturtle;
|
||||||
|
using kitty::dynamic_truth_table;
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
class exact_command : public command {
|
||||||
|
public:
|
||||||
|
explicit exact_command(const environment::ptr& env)
|
||||||
|
: command(env, "exact synthesis to find optimal 2-LUTs") {
|
||||||
|
add_option("function, -f", tt, "exact synthesis of function in hex");
|
||||||
|
add_flag("--cegar_dag, -c", "cegar encoding and partial DAG structure");
|
||||||
|
add_flag("--stp_cegar_dag, -s",
|
||||||
|
"stp based cegar encoding and partial DAG structure");
|
||||||
|
add_flag("--dag_depth, -t",
|
||||||
|
"cegar encoding and partial DAG structure for Delay");
|
||||||
|
add_option("--output, -o", filename, "the verilog filename");
|
||||||
|
add_flag("--enumeration, -e", "enumerate all solutions");
|
||||||
|
add_flag("--new_entry, -w", "adds k-LUT store entry");
|
||||||
|
add_flag("--map, -m", "ASIC map each k-LUT");
|
||||||
|
add_flag("--aig, -a", "enable exact synthesis for AIG, default = false");
|
||||||
|
add_flag("--xag, -g", "enable exact synthesis for XAG, default = false");
|
||||||
|
add_flag("--npn, -n", "print result for NPN storing, default = false");
|
||||||
|
add_flag("--depth, -d", "print the depth of each result, default = false");
|
||||||
|
add_flag("--verbose, -v", "verbose results, default = true");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
string binary_to_hex() {
|
||||||
|
string t_temp;
|
||||||
|
for (int i = 0; i < tt.length(); i++) {
|
||||||
|
switch (tt[i]) {
|
||||||
|
case '0':
|
||||||
|
t_temp += "0000";
|
||||||
|
continue;
|
||||||
|
case '1':
|
||||||
|
t_temp += "0001";
|
||||||
|
continue;
|
||||||
|
case '2':
|
||||||
|
t_temp += "0010";
|
||||||
|
continue;
|
||||||
|
case '3':
|
||||||
|
t_temp += "0011";
|
||||||
|
continue;
|
||||||
|
case '4':
|
||||||
|
t_temp += "0100";
|
||||||
|
continue;
|
||||||
|
case '5':
|
||||||
|
t_temp += "0101";
|
||||||
|
continue;
|
||||||
|
case '6':
|
||||||
|
t_temp += "0110";
|
||||||
|
continue;
|
||||||
|
case '7':
|
||||||
|
t_temp += "0111";
|
||||||
|
continue;
|
||||||
|
case '8':
|
||||||
|
t_temp += "1000";
|
||||||
|
continue;
|
||||||
|
case '9':
|
||||||
|
t_temp += "1001";
|
||||||
|
continue;
|
||||||
|
case 'a':
|
||||||
|
t_temp += "1010";
|
||||||
|
continue;
|
||||||
|
case 'b':
|
||||||
|
t_temp += "1011";
|
||||||
|
continue;
|
||||||
|
case 'c':
|
||||||
|
t_temp += "1100";
|
||||||
|
continue;
|
||||||
|
case 'd':
|
||||||
|
t_temp += "1101";
|
||||||
|
continue;
|
||||||
|
case 'e':
|
||||||
|
t_temp += "1110";
|
||||||
|
continue;
|
||||||
|
case 'f':
|
||||||
|
t_temp += "1111";
|
||||||
|
continue;
|
||||||
|
case 'A':
|
||||||
|
t_temp += "1010";
|
||||||
|
continue;
|
||||||
|
case 'B':
|
||||||
|
t_temp += "1011";
|
||||||
|
continue;
|
||||||
|
case 'C':
|
||||||
|
t_temp += "1100";
|
||||||
|
continue;
|
||||||
|
case 'D':
|
||||||
|
t_temp += "1101";
|
||||||
|
continue;
|
||||||
|
case 'E':
|
||||||
|
t_temp += "1110";
|
||||||
|
continue;
|
||||||
|
case 'F':
|
||||||
|
t_temp += "1111";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return t_temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void enu_es(int nr_in, list<chain>& chains) {
|
||||||
|
int node = nr_in - 1;
|
||||||
|
bool target = false;
|
||||||
|
while (true) {
|
||||||
|
spec spec;
|
||||||
|
bsat_wrapper solver;
|
||||||
|
partial_dag_encoder encoder2(solver);
|
||||||
|
encoder2.reset_sim_tts(nr_in);
|
||||||
|
|
||||||
|
spec.add_alonce_clauses = false;
|
||||||
|
spec.add_nontriv_clauses = false;
|
||||||
|
spec.add_lex_func_clauses = false;
|
||||||
|
spec.add_colex_clauses = false;
|
||||||
|
spec.add_noreapply_clauses = false;
|
||||||
|
spec.add_symvar_clauses = false;
|
||||||
|
spec.verbosity = 0;
|
||||||
|
|
||||||
|
kitty::dynamic_truth_table f(nr_in);
|
||||||
|
kitty::create_from_hex_string(f, tt);
|
||||||
|
spec[0] = f;
|
||||||
|
|
||||||
|
auto dags = pd_generate_filter(node, nr_in);
|
||||||
|
spec.preprocess();
|
||||||
|
for (auto& dag : dags) {
|
||||||
|
chain c;
|
||||||
|
synth_result status;
|
||||||
|
status = pd_cegar_synthesize(spec, c, dag, solver, encoder2);
|
||||||
|
if (status == success) {
|
||||||
|
chains.push_back(c);
|
||||||
|
target = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (target) break;
|
||||||
|
node++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void es(int nr_in, chain& result) {
|
||||||
|
int node = nr_in - 1;
|
||||||
|
bool target = false;
|
||||||
|
while (true) {
|
||||||
|
spec spec;
|
||||||
|
bsat_wrapper solver;
|
||||||
|
partial_dag_encoder encoder2(solver);
|
||||||
|
encoder2.reset_sim_tts(nr_in);
|
||||||
|
|
||||||
|
spec.add_alonce_clauses = false;
|
||||||
|
spec.add_nontriv_clauses = false;
|
||||||
|
spec.add_lex_func_clauses = false;
|
||||||
|
spec.add_colex_clauses = false;
|
||||||
|
spec.add_noreapply_clauses = false;
|
||||||
|
spec.add_symvar_clauses = false;
|
||||||
|
spec.verbosity = 0;
|
||||||
|
|
||||||
|
kitty::dynamic_truth_table f(nr_in);
|
||||||
|
kitty::create_from_hex_string(f, tt);
|
||||||
|
spec[0] = f;
|
||||||
|
|
||||||
|
auto dags = pd_generate_filter(node, nr_in);
|
||||||
|
spec.preprocess();
|
||||||
|
for (auto& dag : dags) {
|
||||||
|
chain c;
|
||||||
|
synth_result status;
|
||||||
|
status = pd_cegar_synthesize(spec, c, dag, solver, encoder2);
|
||||||
|
if (status == success) {
|
||||||
|
result.copy(c);
|
||||||
|
target = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (target) break;
|
||||||
|
node++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void es_delay(int nr_in, list<chain>& chains) {
|
||||||
|
int node = nr_in - 1, max_level = 0, count = 0;
|
||||||
|
bool target = false;
|
||||||
|
while (true) {
|
||||||
|
spec spec;
|
||||||
|
spec.add_alonce_clauses = false;
|
||||||
|
spec.add_nontriv_clauses = false;
|
||||||
|
spec.add_lex_func_clauses = false;
|
||||||
|
spec.add_colex_clauses = false;
|
||||||
|
spec.add_noreapply_clauses = false;
|
||||||
|
spec.add_symvar_clauses = false;
|
||||||
|
spec.verbosity = 0;
|
||||||
|
bsat_wrapper solver;
|
||||||
|
partial_dag_encoder encoder2(solver);
|
||||||
|
encoder2.reset_sim_tts(nr_in);
|
||||||
|
kitty::dynamic_truth_table f(nr_in);
|
||||||
|
kitty::create_from_hex_string(f, tt);
|
||||||
|
spec[0] = f;
|
||||||
|
|
||||||
|
auto dags = pd_generate_filter(node, nr_in);
|
||||||
|
spec.preprocess();
|
||||||
|
for (auto dag : dags) {
|
||||||
|
chain c;
|
||||||
|
const auto status = pd_cegar_synthesize(spec, c, dag, solver, encoder2);
|
||||||
|
if (status == success) {
|
||||||
|
target = true;
|
||||||
|
int level_temp = c.get_nr_level();
|
||||||
|
if (max_level == 0) {
|
||||||
|
chains.push_back(c);
|
||||||
|
max_level = level_temp;
|
||||||
|
} else if (level_temp == max_level) {
|
||||||
|
chains.push_back(c);
|
||||||
|
} else if (level_temp < max_level) {
|
||||||
|
chains.clear();
|
||||||
|
chains.push_back(c);
|
||||||
|
max_level = level_temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (target) break;
|
||||||
|
node++;
|
||||||
|
}
|
||||||
|
while (true) {
|
||||||
|
if (max_level == 2 || count > 2) break;
|
||||||
|
bool target_count = false;
|
||||||
|
spec spec;
|
||||||
|
spec.add_alonce_clauses = false;
|
||||||
|
spec.add_nontriv_clauses = false;
|
||||||
|
spec.add_lex_func_clauses = false;
|
||||||
|
spec.add_colex_clauses = false;
|
||||||
|
spec.add_noreapply_clauses = false;
|
||||||
|
spec.add_symvar_clauses = false;
|
||||||
|
spec.verbosity = 0;
|
||||||
|
bsat_wrapper solver;
|
||||||
|
partial_dag_encoder encoder2(solver);
|
||||||
|
encoder2.reset_sim_tts(nr_in);
|
||||||
|
kitty::dynamic_truth_table f(nr_in);
|
||||||
|
kitty::create_from_hex_string(f, tt);
|
||||||
|
spec[0] = f;
|
||||||
|
|
||||||
|
node++;
|
||||||
|
auto dags = pd_generate_filter(node, nr_in);
|
||||||
|
spec.preprocess();
|
||||||
|
for (auto dag : dags) {
|
||||||
|
if (dag.nr_level() > max_level) continue;
|
||||||
|
chain c;
|
||||||
|
const auto status = pd_cegar_synthesize(spec, c, dag, solver, encoder2);
|
||||||
|
if (status == success) {
|
||||||
|
int level_temp = c.get_nr_level();
|
||||||
|
if (level_temp == max_level) {
|
||||||
|
chains.push_back(c);
|
||||||
|
} else if (level_temp < max_level) {
|
||||||
|
max_level = level_temp;
|
||||||
|
chains.clear();
|
||||||
|
chains.push_back(c);
|
||||||
|
target_count = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!target_count) count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
klut_network create_network(chain& c) {
|
||||||
|
klut_network klut;
|
||||||
|
c.store_bench(0);
|
||||||
|
std::string filename = "r_0.bench";
|
||||||
|
if (lorina::read_bench(filename, mockturtle::bench_reader(klut)) !=
|
||||||
|
lorina::return_code::success) {
|
||||||
|
std::cout << "[w] parse error\n";
|
||||||
|
}
|
||||||
|
return klut;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compare_min_area(double area_temp, double delay_temp, int gate) {
|
||||||
|
bool target = false;
|
||||||
|
if (min_area == 0.00 && min_delay == 0.00) {
|
||||||
|
min_area = area_temp;
|
||||||
|
min_delay = delay_temp;
|
||||||
|
mapping_gate = gate;
|
||||||
|
target = true;
|
||||||
|
} else if (area_temp < min_area) {
|
||||||
|
min_area = area_temp;
|
||||||
|
min_delay = delay_temp;
|
||||||
|
mapping_gate = gate;
|
||||||
|
target = true;
|
||||||
|
} else if (area_temp == min_area) {
|
||||||
|
if (delay_temp < min_delay) {
|
||||||
|
min_delay = delay_temp;
|
||||||
|
mapping_gate = gate;
|
||||||
|
target = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compare_min_delay(double area_temp, double delay_temp, int gate) {
|
||||||
|
bool target = false;
|
||||||
|
if (min_area == 0.00 && min_delay == 0.00) {
|
||||||
|
min_area = area_temp;
|
||||||
|
min_delay = delay_temp;
|
||||||
|
mapping_gate = gate;
|
||||||
|
target = true;
|
||||||
|
} else if (delay_temp < min_delay) {
|
||||||
|
min_area = area_temp;
|
||||||
|
min_delay = delay_temp;
|
||||||
|
mapping_gate = gate;
|
||||||
|
target = true;
|
||||||
|
} else if (delay_temp == min_delay) {
|
||||||
|
if (area_temp < min_area) {
|
||||||
|
min_area = area_temp;
|
||||||
|
mapping_gate = gate;
|
||||||
|
target = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
void execute() {
|
||||||
|
t.clear();
|
||||||
|
t.push_back(binary_to_hex());
|
||||||
|
vector<string>& tt_h = t;
|
||||||
|
|
||||||
|
int nr_in = 0, value = 0;
|
||||||
|
while (value < tt.size()) {
|
||||||
|
value = pow(2, nr_in);
|
||||||
|
if (value == tt.size()) break;
|
||||||
|
nr_in++;
|
||||||
|
}
|
||||||
|
nr_in += 2;
|
||||||
|
|
||||||
|
cout << "Running exact synthesis for " << nr_in << "-input function."
|
||||||
|
<< endl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
clock_t begin, end;
|
||||||
|
double totalTime = 0.0;
|
||||||
|
|
||||||
|
phyLS::exact_lut_params ps;
|
||||||
|
|
||||||
|
if (is_set("verbose")) ps.verbose = false;
|
||||||
|
if (is_set("aig")) ps.aig = true;
|
||||||
|
if (is_set("xag")) ps.xag = true;
|
||||||
|
if (is_set("npn")) ps.npn = true;
|
||||||
|
if (is_set("depth")) ps.depth = true;
|
||||||
|
if (is_set("map")) ps.map = true;
|
||||||
|
|
||||||
|
if (is_set("cegar_dag")) {
|
||||||
|
if (is_set("enumeration")) {
|
||||||
|
begin = clock();
|
||||||
|
list<chain> chains;
|
||||||
|
enu_es(nr_in, chains);
|
||||||
|
end = clock();
|
||||||
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
|
int count = 0;
|
||||||
|
chain best_chain;
|
||||||
|
for (auto x : chains) {
|
||||||
|
count += 1;
|
||||||
|
if (ps.verbose) {
|
||||||
|
x.print_bench();
|
||||||
|
if (ps.depth)
|
||||||
|
std::cout << "level = " << x.get_nr_level() << std::endl;
|
||||||
|
}
|
||||||
|
if (ps.npn) {
|
||||||
|
x.print_npn();
|
||||||
|
if (ps.depth) {
|
||||||
|
std::cout << ": l{" << x.get_nr_level() << "}" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_set("map")) {
|
||||||
|
std::vector<mockturtle::gate> gates =
|
||||||
|
store<std::vector<mockturtle::gate>>().current();
|
||||||
|
mockturtle::tech_library<5> lib(gates);
|
||||||
|
mockturtle::map_params ps;
|
||||||
|
mockturtle::map_stats st;
|
||||||
|
klut_network klut = create_network(x);
|
||||||
|
auto res = mockturtle::map(klut, lib, ps, &st);
|
||||||
|
if (compare_min_area(st.area, st.delay, res.num_gates())) {
|
||||||
|
if (is_set("output")) {
|
||||||
|
write_verilog_with_binding(res, filename);
|
||||||
|
}
|
||||||
|
best_chain.copy(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_set("map")) {
|
||||||
|
best_chain.print_npn();
|
||||||
|
if (ps.depth) {
|
||||||
|
std::cout << ": l{" << best_chain.get_nr_level() << "}"
|
||||||
|
<< std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "Mapped gates = " << mapping_gate
|
||||||
|
<< ", area = " << min_area << ", delay = " << min_delay
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
cout << "[Total realization]: " << count << endl;
|
||||||
|
} else {
|
||||||
|
begin = clock();
|
||||||
|
chain chain;
|
||||||
|
es(nr_in, chain);
|
||||||
|
end = clock();
|
||||||
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
|
if (is_set("new_entry")) {
|
||||||
|
klut_network klut = create_network(chain);
|
||||||
|
store<klut_network>().extend();
|
||||||
|
store<klut_network>().current() = klut;
|
||||||
|
}
|
||||||
|
if (ps.verbose) {
|
||||||
|
chain.print_bench();
|
||||||
|
if (ps.depth) {
|
||||||
|
klut_network klut = create_network(chain);
|
||||||
|
mockturtle::depth_view depth_lut{klut};
|
||||||
|
std::cout << "level = " << depth_lut.depth() - 1 << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ps.npn) {
|
||||||
|
chain.print_npn();
|
||||||
|
if (ps.depth) {
|
||||||
|
klut_network klut = create_network(chain);
|
||||||
|
mockturtle::depth_view depth_lut{klut};
|
||||||
|
std::cout << "l{" << depth_lut.depth() - 1 << "}" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_set("map")) {
|
||||||
|
std::vector<mockturtle::gate> gates =
|
||||||
|
store<std::vector<mockturtle::gate>>().current();
|
||||||
|
mockturtle::tech_library<5> lib(gates);
|
||||||
|
mockturtle::map_params ps;
|
||||||
|
mockturtle::map_stats st;
|
||||||
|
klut_network klut = create_network(chain);
|
||||||
|
auto res = mockturtle::map(klut, lib, ps, &st);
|
||||||
|
compare_min_area(st.area, st.delay, res.num_gates());
|
||||||
|
chain.print_npn();
|
||||||
|
if (is_set("output")) {
|
||||||
|
write_verilog_with_binding(res, filename);
|
||||||
|
}
|
||||||
|
if (is_set("depth")) {
|
||||||
|
klut_network klut = create_network(chain);
|
||||||
|
mockturtle::depth_view depth_lut{klut};
|
||||||
|
std::cout << ": l{" << depth_lut.depth() - 1 << "}" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "Mapped gates = " << mapping_gate
|
||||||
|
<< ", area = " << min_area << ", delay = " << min_delay
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (is_set("dag_depth")) {
|
||||||
|
begin = clock();
|
||||||
|
list<chain> chains;
|
||||||
|
es_delay(nr_in, chains);
|
||||||
|
end = clock();
|
||||||
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
|
int count = 0;
|
||||||
|
chain best_chain;
|
||||||
|
for (auto x : chains) {
|
||||||
|
count += 1;
|
||||||
|
if (is_set("verbose")) {
|
||||||
|
x.print_bench();
|
||||||
|
if (ps.depth)
|
||||||
|
std::cout << "level = " << x.get_nr_level() << std::endl;
|
||||||
|
}
|
||||||
|
if (is_set("npn")) {
|
||||||
|
x.print_npn();
|
||||||
|
if (ps.depth) {
|
||||||
|
std::cout << ": l{" << x.get_nr_level() << "}" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_set("map")) {
|
||||||
|
std::vector<mockturtle::gate> gates =
|
||||||
|
store<std::vector<mockturtle::gate>>().current();
|
||||||
|
mockturtle::tech_library<5> lib(gates);
|
||||||
|
mockturtle::map_params ps;
|
||||||
|
mockturtle::map_stats st;
|
||||||
|
klut_network klut = create_network(x);
|
||||||
|
auto res = mockturtle::map(klut, lib, ps, &st);
|
||||||
|
if (compare_min_delay(st.area, st.delay, res.num_gates()))
|
||||||
|
best_chain.copy(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_set("map")) {
|
||||||
|
best_chain.print_npn();
|
||||||
|
if (ps.depth) {
|
||||||
|
std::cout << ": l{" << best_chain.get_nr_level() << "}" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "Mapped gates = " << mapping_gate
|
||||||
|
<< ", area = " << min_area << ", delay = " << min_delay
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
cout << "[Total realization]: " << count << endl;
|
||||||
|
} else if (is_set("stp_cegar_dag")) {
|
||||||
|
if (is_set("map")){
|
||||||
|
ps.gates = store<std::vector<mockturtle::gate>>().current();
|
||||||
|
begin = clock();
|
||||||
|
exact_lut_dag_enu_map(tt, nr_in, ps);
|
||||||
|
end = clock();
|
||||||
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
|
std::cout << "Mapped gates = " << ps.mapping_gate
|
||||||
|
<< ", area = " << ps.min_area << ", delay = " << ps.min_delay
|
||||||
|
<< std::endl;
|
||||||
|
} else if (is_set("enumeration")) {
|
||||||
|
begin = clock();
|
||||||
|
exact_lut_dag_enu(tt, nr_in, ps);
|
||||||
|
end = clock();
|
||||||
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
|
cout << "[Total realization]: " << nr_in << endl;
|
||||||
|
} else {
|
||||||
|
begin = clock();
|
||||||
|
exact_lut_dag(tt, nr_in, ps);
|
||||||
|
end = clock();
|
||||||
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
|
cout << "[Total realization]: " << nr_in << endl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (is_set("enumeration")) {
|
||||||
|
begin = clock();
|
||||||
|
phyLS::exact_lut_enu(tt_h, nr_in);
|
||||||
|
end = clock();
|
||||||
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
|
int count = 0;
|
||||||
|
for (auto x : tt_h) {
|
||||||
|
if (ps.verbose) cout << x << endl;
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
cout << "[Total realization]: " << count << endl;
|
||||||
|
} else {
|
||||||
|
begin = clock();
|
||||||
|
phyLS::exact_lut(tt_h, nr_in);
|
||||||
|
end = clock();
|
||||||
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
|
int count = 0;
|
||||||
|
for (auto x : tt_h) {
|
||||||
|
if (ps.verbose) cout << x << endl;
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
cout << "[Total realization]: " << count << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cout.setf(ios::fixed);
|
||||||
|
cout << "[Total CPU time] : " << setprecision(3) << totalTime << " s"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
string tt;
|
||||||
|
vector<string> t;
|
||||||
|
double min_area = 0.00;
|
||||||
|
double min_delay = 0.00;
|
||||||
|
int mapping_gate = 0;
|
||||||
|
std::string filename = "techmap.v";
|
||||||
|
};
|
||||||
|
|
||||||
|
ALICE_ADD_COMMAND(exact, "Synthesis")
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,94 @@
|
||||||
|
/* phyLS: Advanced Logic Synthesis and Optimization tool
|
||||||
|
* Copyright (C) 2019-2021 Ningbo University, Ningbo, China */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file lutrw.hpp
|
||||||
|
*
|
||||||
|
* @brief 2-lut rewriting with STP based exact synthesis
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2022/11/30
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LUTRW_COMMAND_HPP
|
||||||
|
#define LUTRW_COMMAND_HPP
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <alice/alice.hpp>
|
||||||
|
#include <mockturtle/mockturtle.hpp>
|
||||||
|
#include <mockturtle/networks/klut.hpp>
|
||||||
|
#include <percy/percy.hpp>
|
||||||
|
|
||||||
|
#include "../../core/exact/lut_rewriting.hpp"
|
||||||
|
#include "../../core/misc.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace percy;
|
||||||
|
using kitty::dynamic_truth_table;
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
class lutrw_command : public command {
|
||||||
|
public:
|
||||||
|
explicit lutrw_command(const environment::ptr& env)
|
||||||
|
: command(env, "Performs 2-LUT rewriting") {
|
||||||
|
add_flag("--techmap, -t", "rewriting by the lowest cost of realization");
|
||||||
|
add_flag("--enumeration_techmap, -e",
|
||||||
|
"rewriting by the lowest cost of enumerated realization");
|
||||||
|
add_flag("--cec, -c,", "apply equivalence checking in rewriting");
|
||||||
|
add_flag("--xag, -g", "enable exact synthesis for XAG, default = false");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void execute() {
|
||||||
|
mockturtle::klut_network klut = store<mockturtle::klut_network>().current();
|
||||||
|
mockturtle::klut_network klut_orig, klut_opt;
|
||||||
|
klut_orig = klut;
|
||||||
|
phyLS::lut_rewriting_params ps;
|
||||||
|
if (is_set("xag")) ps.xag = true;
|
||||||
|
|
||||||
|
clock_t begin, end;
|
||||||
|
double totalTime;
|
||||||
|
if (is_set("techmap")) {
|
||||||
|
begin = clock();
|
||||||
|
klut_opt = phyLS::lut_rewriting_s(klut, ps);
|
||||||
|
end = clock();
|
||||||
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
|
} else if (is_set("enumeration_techmap")) {
|
||||||
|
begin = clock();
|
||||||
|
klut_opt = phyLS::lut_rewriting_s_enu(klut, ps);
|
||||||
|
end = clock();
|
||||||
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
|
} else {
|
||||||
|
begin = clock();
|
||||||
|
klut_opt = phyLS::lut_rewriting_c(klut, ps);
|
||||||
|
end = clock();
|
||||||
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_set("cec")) {
|
||||||
|
/* equivalence checking */
|
||||||
|
const auto miter_klut = *miter<klut_network>(klut_orig, klut_opt);
|
||||||
|
equivalence_checking_stats eq_st;
|
||||||
|
const auto result = equivalence_checking(miter_klut, {}, &eq_st);
|
||||||
|
assert(*result);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "[lutrw] ";
|
||||||
|
phyLS::print_stats(klut_opt);
|
||||||
|
|
||||||
|
store<mockturtle::klut_network>().extend();
|
||||||
|
store<mockturtle::klut_network>().current() = klut_opt;
|
||||||
|
|
||||||
|
cout.setf(ios::fixed);
|
||||||
|
cout << "[Total CPU time] : " << setprecision(3) << totalTime << " s"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
ALICE_ADD_COMMAND(lutrw, "Synthesis")
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -43,12 +43,27 @@ class lutmap_command : public command {
|
||||||
add_flag("--recompute_cuts, -c",
|
add_flag("--recompute_cuts, -c",
|
||||||
"recompute cuts at each step [default = true]");
|
"recompute cuts at each step [default = true]");
|
||||||
add_flag("--edge, -e", "Use edge count reduction [default = true]");
|
add_flag("--edge, -e", "Use edge count reduction [default = true]");
|
||||||
|
add_flag("--cost_function, -f",
|
||||||
|
"LUT map with cost function [default = false]");
|
||||||
add_flag("--dominated_cuts, -d",
|
add_flag("--dominated_cuts, -d",
|
||||||
"Remove the cuts that are contained in others [default = true]");
|
"Remove the cuts that are contained in others [default = true]");
|
||||||
add_flag("--verbose, -v", "print the information");
|
add_flag("--verbose, -v", "print the information");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
struct lut_custom_cost {
|
||||||
|
std::pair<uint32_t, uint32_t> operator()(uint32_t num_leaves) const {
|
||||||
|
if (num_leaves < 2u) return {0u, 0u};
|
||||||
|
return {num_leaves, 1u}; /* area, delay */
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<uint32_t, uint32_t> operator()(
|
||||||
|
kitty::dynamic_truth_table const& tt) const {
|
||||||
|
if (tt.num_vars() < 2u) return {0u, 0u};
|
||||||
|
return {tt.num_vars(), 1u}; /* area, delay */
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void execute() {
|
void execute() {
|
||||||
if (is_set("mig")) {
|
if (is_set("mig")) {
|
||||||
if (store<mig_network>().size() == 0u)
|
if (store<mig_network>().size() == 0u)
|
||||||
|
@ -109,7 +124,7 @@ class lutmap_command : public command {
|
||||||
std::cerr << "Error: Empty AIG network\n";
|
std::cerr << "Error: Empty AIG network\n";
|
||||||
else {
|
else {
|
||||||
auto aig = store<aig_network>().current();
|
auto aig = store<aig_network>().current();
|
||||||
mapping_view mapped_aig{aig};
|
mapping_view<aig_network, true> mapped_aig{aig};
|
||||||
phyLS::lut_map_params ps;
|
phyLS::lut_map_params ps;
|
||||||
if (is_set("area")) ps.area_oriented_mapping = true;
|
if (is_set("area")) ps.area_oriented_mapping = true;
|
||||||
if (is_set("relax_required")) ps.relax_required = relax_required;
|
if (is_set("relax_required")) ps.relax_required = relax_required;
|
||||||
|
@ -119,7 +134,11 @@ class lutmap_command : public command {
|
||||||
if (is_set("edge")) ps.edge_optimization = false;
|
if (is_set("edge")) ps.edge_optimization = false;
|
||||||
if (is_set("dominated_cuts")) ps.remove_dominated_cuts = false;
|
if (is_set("dominated_cuts")) ps.remove_dominated_cuts = false;
|
||||||
cout << "Mapped AIG into " << cut_size << "-LUT : ";
|
cout << "Mapped AIG into " << cut_size << "-LUT : ";
|
||||||
phyLS::lut_map(mapped_aig, ps);
|
if (is_set("cost_function"))
|
||||||
|
phyLS::lut_map<decltype(mapped_aig), true, lut_custom_cost>(
|
||||||
|
mapped_aig, ps);
|
||||||
|
else
|
||||||
|
phyLS::lut_map(mapped_aig, ps);
|
||||||
mapped_aig.clear_mapping();
|
mapped_aig.clear_mapping();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ class resyn_command : public command {
|
||||||
"performs technology-independent restructuring [default = MIG]") {
|
"performs technology-independent restructuring [default = MIG]") {
|
||||||
add_flag("--xmg, -x", "Resubstitution for XMG");
|
add_flag("--xmg, -x", "Resubstitution for XMG");
|
||||||
add_flag("--xag, -g", "Resubstitution for XAG");
|
add_flag("--xag, -g", "Resubstitution for XAG");
|
||||||
|
add_flag("--aig, -a", "Resubstitution for AIG");
|
||||||
add_flag("--direct, -d", "Node resynthesis with direct synthesis");
|
add_flag("--direct, -d", "Node resynthesis with direct synthesis");
|
||||||
add_flag("--verbose, -v", "print the information");
|
add_flag("--verbose, -v", "print the information");
|
||||||
}
|
}
|
||||||
|
@ -81,6 +82,19 @@ class resyn_command : public command {
|
||||||
phyLS::print_stats(xag);
|
phyLS::print_stats(xag);
|
||||||
end = clock();
|
end = clock();
|
||||||
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
|
} else if (is_set("aig")) {
|
||||||
|
begin = clock();
|
||||||
|
exact_resynthesis_params ps;
|
||||||
|
ps.cache = std::make_shared<exact_resynthesis_params::cache_map_t>();
|
||||||
|
exact_aig_resynthesis<aig_network> exact_resyn(false, ps);
|
||||||
|
node_resynthesis_stats nrst;
|
||||||
|
dsd_resynthesis<aig_network, decltype(exact_resyn)> resyn(exact_resyn);
|
||||||
|
const auto aig = node_resynthesis<aig_network>(klut, resyn, {}, &nrst);
|
||||||
|
store<aig_network>().extend();
|
||||||
|
store<aig_network>().current() = cleanup_dangling(aig);
|
||||||
|
phyLS::print_stats(aig);
|
||||||
|
end = clock();
|
||||||
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
} else {
|
} else {
|
||||||
begin = clock();
|
begin = clock();
|
||||||
if (is_set("direct")) {
|
if (is_set("direct")) {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef EXACT_LUT_HPP
|
||||||
|
#define EXACT_LUT_HPP
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <numeric>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace phyLS {
|
||||||
|
void exact_lut(vector<string>& tt, int& input);
|
||||||
|
void exact_lut_enu(vector<string>& tt, int& input);
|
||||||
|
} // namespace phyLS
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,408 @@
|
||||||
|
#ifndef LUT_REWRITING_HPP
|
||||||
|
#define LUT_REWRITING_HPP
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <mockturtle/algorithms/cleanup.hpp>
|
||||||
|
#include <mockturtle/mockturtle.hpp>
|
||||||
|
#include <mockturtle/networks/klut.hpp>
|
||||||
|
#include <percy/percy.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "exact_dag.hpp"
|
||||||
|
|
||||||
|
using namespace percy;
|
||||||
|
using namespace mockturtle;
|
||||||
|
|
||||||
|
namespace phyLS {
|
||||||
|
|
||||||
|
struct lut_rewriting_params {
|
||||||
|
/*! \brief Enable exact synthesis for XAG. */
|
||||||
|
bool xag{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
class lut_rewriting_manager {
|
||||||
|
public:
|
||||||
|
lut_rewriting_manager(klut_network klut, lut_rewriting_params const& ps)
|
||||||
|
: klut(klut), ps(ps) {}
|
||||||
|
|
||||||
|
klut_network run_c() {
|
||||||
|
klut.foreach_node([&](auto const& n) {
|
||||||
|
if (klut.is_constant(n) || klut.is_pi(n)) return true; /* continue */
|
||||||
|
std::string func = kitty::to_hex(klut.node_function(n));
|
||||||
|
std::vector<klut_network::node> lut_inputs;
|
||||||
|
|
||||||
|
klut.foreach_fanin(
|
||||||
|
n, [&](auto const& c) { lut_inputs.push_back(klut.get_node(c)); });
|
||||||
|
if (lut_inputs.size() <= 2) return true; /* continue */
|
||||||
|
|
||||||
|
// exact synthesis for each node
|
||||||
|
int input_num = lut_inputs.size();
|
||||||
|
percy::chain chain;
|
||||||
|
es(input_num, func, chain);
|
||||||
|
std::vector<int> node;
|
||||||
|
std::vector<int> right;
|
||||||
|
std::vector<int> left;
|
||||||
|
std::vector<std::string> tt;
|
||||||
|
chain.bench_infor(node, left, right, tt);
|
||||||
|
if (tt.size() != node.size()) {
|
||||||
|
tt.pop_back();
|
||||||
|
hex_invert(tt[tt.size() - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rewrite origin node by the optimal Boolean chains of exact synthesis
|
||||||
|
std::vector<mockturtle::klut_network::node> new_lut;
|
||||||
|
for (int i = 0; i < node.size(); i++) {
|
||||||
|
kitty::dynamic_truth_table node_tt(2u);
|
||||||
|
kitty::create_from_hex_string(node_tt, tt[i]);
|
||||||
|
if (left[i] <= input_num && right[i] <= input_num) {
|
||||||
|
const auto node_new = klut.create_node(
|
||||||
|
{lut_inputs[left[i] - 1], lut_inputs[right[i] - 1]}, node_tt);
|
||||||
|
new_lut.push_back(node_new);
|
||||||
|
} else if (left[i] <= input_num && right[i] > input_num) {
|
||||||
|
const auto node_new = klut.create_node(
|
||||||
|
{lut_inputs[left[i] - 1], new_lut[right[i] - 1 - input_num]},
|
||||||
|
node_tt);
|
||||||
|
new_lut.push_back(node_new);
|
||||||
|
} else if (left[i] > input_num && right[i] > input_num) {
|
||||||
|
const auto node_new =
|
||||||
|
klut.create_node({new_lut[left[i] - 1 - input_num],
|
||||||
|
new_lut[right[i] - 1 - input_num]},
|
||||||
|
node_tt);
|
||||||
|
new_lut.push_back(node_new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
klut.substitute_node(n, new_lut[new_lut.size() - 1]);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// clean all redundant luts
|
||||||
|
auto klut_opt = mockturtle::cleanup_luts(klut);
|
||||||
|
return klut_opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
klut_network run_s() {
|
||||||
|
klut.foreach_node([&](auto const& n) {
|
||||||
|
if (klut.is_constant(n) || klut.is_pi(n)) return true; /* continue */
|
||||||
|
std::string func = kitty::to_hex(klut.node_function(n));
|
||||||
|
std::vector<klut_network::node> lut_inputs;
|
||||||
|
|
||||||
|
klut.foreach_fanin(
|
||||||
|
n, [&](auto const& c) { lut_inputs.push_back(klut.get_node(c)); });
|
||||||
|
if (lut_inputs.size() <= 2) return true; /* continue */
|
||||||
|
|
||||||
|
// exact synthesis for each node
|
||||||
|
int input_num = lut_inputs.size();
|
||||||
|
phyLS::exact_lut_params ps;
|
||||||
|
dag_impl mgr(func, input_num, ps);
|
||||||
|
mgr.run_rewrite();
|
||||||
|
|
||||||
|
// compute the techmap costs of all realizations
|
||||||
|
float cost = 0;
|
||||||
|
int min_cost_realization = 0;
|
||||||
|
for (int i = 0; i < mgr.exact_synthesis_results.size(); i++) {
|
||||||
|
float cost_temp = 0;
|
||||||
|
for (auto y : mgr.exact_synthesis_results[i])
|
||||||
|
cost_temp += bench_cost_area(y.tt);
|
||||||
|
if (cost_temp < cost || cost == 0) {
|
||||||
|
cost = cost_temp;
|
||||||
|
min_cost_realization = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::vector<int> nodes;
|
||||||
|
std::vector<int> rights;
|
||||||
|
std::vector<int> lefts;
|
||||||
|
std::vector<std::string> tts;
|
||||||
|
for (auto x : mgr.exact_synthesis_results[min_cost_realization]) {
|
||||||
|
nodes.push_back(x.node);
|
||||||
|
lefts.push_back(x.left);
|
||||||
|
rights.push_back(x.right);
|
||||||
|
tts.push_back(x.tt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rewrite origin node by the optimal Boolean chains of exact synthesis
|
||||||
|
std::vector<mockturtle::klut_network::node> new_lut;
|
||||||
|
for (int i = nodes.size() - 1; i >= 0; i--) {
|
||||||
|
kitty::dynamic_truth_table node_tt(2u);
|
||||||
|
kitty::create_from_binary_string(node_tt, tts[i]);
|
||||||
|
if (lefts[i] <= input_num && rights[i] <= input_num) {
|
||||||
|
const auto node_new = klut.create_node(
|
||||||
|
{lut_inputs[lefts[i] - 1], lut_inputs[rights[i] - 1]}, node_tt);
|
||||||
|
new_lut.push_back(node_new);
|
||||||
|
} else if (lefts[i] <= input_num && rights[i] > input_num) {
|
||||||
|
const auto node_new = klut.create_node(
|
||||||
|
{lut_inputs[lefts[i] - 1], new_lut[rights[i] - 1 - input_num]},
|
||||||
|
node_tt);
|
||||||
|
new_lut.push_back(node_new);
|
||||||
|
} else if (lefts[i] > input_num && rights[i] > input_num) {
|
||||||
|
const auto node_new =
|
||||||
|
klut.create_node({new_lut[lefts[i] - 1 - input_num],
|
||||||
|
new_lut[rights[i] - 1 - input_num]},
|
||||||
|
node_tt);
|
||||||
|
new_lut.push_back(node_new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
klut.substitute_node(n, new_lut[new_lut.size() - 1]);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// clean all redundant luts
|
||||||
|
auto klut_opt = mockturtle::cleanup_luts(klut);
|
||||||
|
return klut_opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
klut_network run_s_enu() {
|
||||||
|
klut.foreach_node([&](auto const& n) {
|
||||||
|
if (klut.is_constant(n) || klut.is_pi(n)) return true; /* continue */
|
||||||
|
std::string func = kitty::to_hex(klut.node_function(n));
|
||||||
|
std::vector<klut_network::node> lut_inputs;
|
||||||
|
|
||||||
|
klut.foreach_fanin(
|
||||||
|
n, [&](auto const& c) { lut_inputs.push_back(klut.get_node(c)); });
|
||||||
|
if (lut_inputs.size() <= 2) return true; /* continue */
|
||||||
|
|
||||||
|
// exact synthesis for each node
|
||||||
|
int input_num = lut_inputs.size();
|
||||||
|
phyLS::exact_lut_params ps;
|
||||||
|
dag_impl mgr(func, input_num, ps);
|
||||||
|
mgr.run_rewrite_enu();
|
||||||
|
|
||||||
|
// compute the techmap costs of all realizations
|
||||||
|
float cost = 0;
|
||||||
|
int min_cost_realization = 0;
|
||||||
|
for (int i = 0; i < mgr.exact_synthesis_results.size(); i++) {
|
||||||
|
float cost_temp = 0;
|
||||||
|
for (auto y : mgr.exact_synthesis_results[i])
|
||||||
|
cost_temp += bench_cost_area(y.tt);
|
||||||
|
if (cost_temp < cost || cost == 0) {
|
||||||
|
cost = cost_temp;
|
||||||
|
min_cost_realization = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::vector<int> nodes;
|
||||||
|
std::vector<int> rights;
|
||||||
|
std::vector<int> lefts;
|
||||||
|
std::vector<std::string> tts;
|
||||||
|
for (auto x : mgr.exact_synthesis_results[min_cost_realization]) {
|
||||||
|
nodes.push_back(x.node);
|
||||||
|
lefts.push_back(x.left);
|
||||||
|
rights.push_back(x.right);
|
||||||
|
tts.push_back(x.tt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rewrite origin node by the optimal Boolean chains of exact synthesis
|
||||||
|
std::vector<mockturtle::klut_network::node> new_lut;
|
||||||
|
for (int i = nodes.size() - 1; i >= 0; i--) {
|
||||||
|
kitty::dynamic_truth_table node_tt(2u);
|
||||||
|
kitty::create_from_binary_string(node_tt, tts[i]);
|
||||||
|
if (lefts[i] <= input_num && rights[i] <= input_num) {
|
||||||
|
const auto node_new = klut.create_node(
|
||||||
|
{lut_inputs[lefts[i] - 1], lut_inputs[rights[i] - 1]}, node_tt);
|
||||||
|
new_lut.push_back(node_new);
|
||||||
|
} else if (lefts[i] <= input_num && rights[i] > input_num) {
|
||||||
|
const auto node_new = klut.create_node(
|
||||||
|
{lut_inputs[lefts[i] - 1], new_lut[rights[i] - 1 - input_num]},
|
||||||
|
node_tt);
|
||||||
|
new_lut.push_back(node_new);
|
||||||
|
} else if (lefts[i] > input_num && rights[i] > input_num) {
|
||||||
|
const auto node_new =
|
||||||
|
klut.create_node({new_lut[lefts[i] - 1 - input_num],
|
||||||
|
new_lut[rights[i] - 1 - input_num]},
|
||||||
|
node_tt);
|
||||||
|
new_lut.push_back(node_new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
klut.substitute_node(n, new_lut[new_lut.size() - 1]);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// clean all redundant luts
|
||||||
|
auto klut_opt = mockturtle::cleanup_luts(klut);
|
||||||
|
return klut_opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void hex_invert(std::string& tt_temp) {
|
||||||
|
if (tt_temp == "1")
|
||||||
|
tt_temp = "e";
|
||||||
|
else if (tt_temp == "2")
|
||||||
|
tt_temp = "d";
|
||||||
|
else if (tt_temp == "3")
|
||||||
|
tt_temp = "c";
|
||||||
|
else if (tt_temp == "4")
|
||||||
|
tt_temp = "b";
|
||||||
|
else if (tt_temp == "5")
|
||||||
|
tt_temp = "a";
|
||||||
|
else if (tt_temp == "6")
|
||||||
|
tt_temp = "9";
|
||||||
|
else if (tt_temp == "7")
|
||||||
|
tt_temp = "8";
|
||||||
|
else if (tt_temp == "8")
|
||||||
|
tt_temp = "7";
|
||||||
|
else if (tt_temp == "9")
|
||||||
|
tt_temp = "6";
|
||||||
|
else if (tt_temp == "a")
|
||||||
|
tt_temp = "5";
|
||||||
|
else if (tt_temp == "b")
|
||||||
|
tt_temp = "4";
|
||||||
|
else if (tt_temp == "c")
|
||||||
|
tt_temp = "3";
|
||||||
|
else if (tt_temp == "d")
|
||||||
|
tt_temp = "2";
|
||||||
|
else if (tt_temp == "e")
|
||||||
|
tt_temp = "1";
|
||||||
|
else
|
||||||
|
tt_temp = "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
float techmap_cost(std::vector<std::vector<std::string>> tt) {
|
||||||
|
float cost = 0;
|
||||||
|
for (auto x : tt) {
|
||||||
|
float cost_temp = 0;
|
||||||
|
for (auto y : x) {
|
||||||
|
cost_temp += bench_cost_area(y);
|
||||||
|
}
|
||||||
|
if (cost_temp < cost || cost == 0) cost = cost_temp;
|
||||||
|
}
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
float bench_cost_area(std::string tt) {
|
||||||
|
float area_cost = 0;
|
||||||
|
if (tt == "0001")
|
||||||
|
area_cost = 2;
|
||||||
|
else if (tt == "0010")
|
||||||
|
area_cost = 3;
|
||||||
|
else if (tt == "0011")
|
||||||
|
area_cost = 1;
|
||||||
|
else if (tt == "0100")
|
||||||
|
area_cost = 3;
|
||||||
|
else if (tt == "0101")
|
||||||
|
area_cost = 1;
|
||||||
|
else if (tt == "0110")
|
||||||
|
area_cost = 5;
|
||||||
|
else if (tt == "0111")
|
||||||
|
area_cost = 2;
|
||||||
|
else if (tt == "1000")
|
||||||
|
area_cost = 3;
|
||||||
|
else if (tt == "1001")
|
||||||
|
area_cost = 5;
|
||||||
|
else if (tt == "1010")
|
||||||
|
area_cost = 1;
|
||||||
|
else if (tt == "1011")
|
||||||
|
area_cost = 3;
|
||||||
|
else if (tt == "1100")
|
||||||
|
area_cost = 1;
|
||||||
|
else if (tt == "1101")
|
||||||
|
area_cost = 3;
|
||||||
|
else if (tt == "1110")
|
||||||
|
area_cost = 4;
|
||||||
|
else
|
||||||
|
area_cost = 0;
|
||||||
|
return area_cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
float bench_cost_depth(std::string tt) {
|
||||||
|
float depth_cost = 0;
|
||||||
|
if (tt == "0001")
|
||||||
|
depth_cost = 1.4;
|
||||||
|
else if (tt == "0010")
|
||||||
|
depth_cost = 2.3;
|
||||||
|
else if (tt == "0011")
|
||||||
|
depth_cost = 0.9;
|
||||||
|
else if (tt == "0100")
|
||||||
|
depth_cost = 2.3;
|
||||||
|
else if (tt == "0101")
|
||||||
|
depth_cost = 0.9;
|
||||||
|
else if (tt == "0110")
|
||||||
|
depth_cost = 1.9;
|
||||||
|
else if (tt == "0111")
|
||||||
|
depth_cost = 1;
|
||||||
|
else if (tt == "1000")
|
||||||
|
depth_cost = 1.9;
|
||||||
|
else if (tt == "1001")
|
||||||
|
depth_cost = 2.1;
|
||||||
|
else if (tt == "1010")
|
||||||
|
depth_cost = 1;
|
||||||
|
else if (tt == "1011")
|
||||||
|
depth_cost = 1.9;
|
||||||
|
else if (tt == "1100")
|
||||||
|
depth_cost = 1;
|
||||||
|
else if (tt == "1101")
|
||||||
|
depth_cost = 1.9;
|
||||||
|
else if (tt == "1110")
|
||||||
|
depth_cost = 1.9;
|
||||||
|
else
|
||||||
|
depth_cost = 0;
|
||||||
|
return depth_cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
void es(int nr_in, std::string tt, percy::chain& result) {
|
||||||
|
int node = nr_in - 1;
|
||||||
|
bool target = false;
|
||||||
|
while (true) {
|
||||||
|
spec spec;
|
||||||
|
bsat_wrapper solver;
|
||||||
|
percy::partial_dag_encoder encoder2(solver);
|
||||||
|
encoder2.reset_sim_tts(nr_in);
|
||||||
|
|
||||||
|
spec.add_alonce_clauses = false;
|
||||||
|
spec.add_nontriv_clauses = false;
|
||||||
|
spec.add_lex_func_clauses = false;
|
||||||
|
spec.add_colex_clauses = false;
|
||||||
|
spec.add_noreapply_clauses = false;
|
||||||
|
spec.add_symvar_clauses = false;
|
||||||
|
spec.verbosity = 0;
|
||||||
|
|
||||||
|
kitty::dynamic_truth_table f(nr_in);
|
||||||
|
kitty::create_from_hex_string(f, tt);
|
||||||
|
spec[0] = f;
|
||||||
|
|
||||||
|
auto dags = percy::pd_generate_filtered(node, nr_in);
|
||||||
|
spec.preprocess();
|
||||||
|
for (auto& dag : dags) {
|
||||||
|
percy::chain c;
|
||||||
|
synth_result status;
|
||||||
|
status = percy::pd_cegar_synthesize(spec, c, dag, solver, encoder2);
|
||||||
|
if (status == success) {
|
||||||
|
result.copy(c);
|
||||||
|
target = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (target) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
node++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
klut_network klut;
|
||||||
|
lut_rewriting_params const& ps;
|
||||||
|
};
|
||||||
|
|
||||||
|
klut_network lut_rewriting_c(klut_network& klut,
|
||||||
|
lut_rewriting_params const& ps = {}) {
|
||||||
|
lut_rewriting_manager mgr(klut, ps);
|
||||||
|
return mgr.run_c();
|
||||||
|
}
|
||||||
|
|
||||||
|
klut_network lut_rewriting_s(klut_network& klut,
|
||||||
|
lut_rewriting_params const& ps = {}) {
|
||||||
|
lut_rewriting_manager mgr(klut, ps);
|
||||||
|
return mgr.run_s();
|
||||||
|
}
|
||||||
|
|
||||||
|
klut_network lut_rewriting_s_enu(klut_network& klut,
|
||||||
|
lut_rewriting_params const& ps = {}) {
|
||||||
|
lut_rewriting_manager mgr(klut, ps);
|
||||||
|
return mgr.run_s_enu();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace phyLS
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,644 @@
|
||||||
|
#pragma once
|
||||||
|
/*!
|
||||||
|
\file aoig.hpp
|
||||||
|
\brief aoig logic network implementation
|
||||||
|
*/
|
||||||
|
#include <mockturtle/mockturtle.hpp>
|
||||||
|
#include <kitty/kitty.hpp>
|
||||||
|
|
||||||
|
namespace mockturtle
|
||||||
|
{
|
||||||
|
struct aoig_storage_data
|
||||||
|
{
|
||||||
|
truth_table_cache<kitty::dynamic_truth_table> cache;
|
||||||
|
uint32_t num_pis = 0u;
|
||||||
|
uint32_t num_pos = 0u;
|
||||||
|
std::vector<int8_t> latches;
|
||||||
|
uint32_t trav_id = 0u;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*! \brief k-LUT node
|
||||||
|
*
|
||||||
|
* `data[0].h1`: Fan-out size
|
||||||
|
* `data[0].h2`: Application-specific value
|
||||||
|
* `data[1].h1`: Function literal in truth table cache
|
||||||
|
* `data[2].h2`: Visited flags
|
||||||
|
*/
|
||||||
|
struct aoig_storage_node : mixed_fanin_node<2>
|
||||||
|
{
|
||||||
|
bool operator==(aoig_storage_node const& other) const
|
||||||
|
{
|
||||||
|
return data[1].h1 == other.data[1].h1 && children == other.children;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*! \brief k-LUT storage container */
|
||||||
|
using aoig_storage = storage<aoig_storage_node, aoig_storage_data>;
|
||||||
|
|
||||||
|
class aoig_network
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
#pragma region Types and constructors
|
||||||
|
static constexpr auto min_fanin_size = 1;
|
||||||
|
static constexpr auto max_fanin_size = 3;
|
||||||
|
|
||||||
|
using base_type = aoig_network;
|
||||||
|
using storage = std::shared_ptr<aoig_storage>;
|
||||||
|
using node = uint64_t;
|
||||||
|
using signal = uint64_t;
|
||||||
|
|
||||||
|
aoig_network()
|
||||||
|
: _storage(std::make_shared<aoig_storage>()),
|
||||||
|
_events(std::make_shared<decltype(_events)::element_type>())
|
||||||
|
{
|
||||||
|
_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
aoig_network(std::shared_ptr<aoig_storage> storage)
|
||||||
|
: _storage(storage),
|
||||||
|
_events(std::make_shared<decltype(_events)::element_type>())
|
||||||
|
{
|
||||||
|
_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline void _init()
|
||||||
|
{
|
||||||
|
/* reserve the second node for constant 1 */
|
||||||
|
_storage->nodes.emplace_back();
|
||||||
|
|
||||||
|
/* reserve some truth tables for nodes */
|
||||||
|
kitty::dynamic_truth_table tt_zero(0);
|
||||||
|
_storage->data.cache.insert(tt_zero);
|
||||||
|
|
||||||
|
static uint64_t _not = 0x1;
|
||||||
|
kitty::dynamic_truth_table tt_not(1);
|
||||||
|
kitty::create_from_words(tt_not, &_not, &_not + 1);
|
||||||
|
_storage->data.cache.insert(tt_not);
|
||||||
|
|
||||||
|
static uint64_t _and = 0x8;
|
||||||
|
kitty::dynamic_truth_table tt_and(2);
|
||||||
|
kitty::create_from_words(tt_and, &_and, &_and + 1);
|
||||||
|
_storage->data.cache.insert(tt_and);
|
||||||
|
|
||||||
|
static uint64_t _or = 0xe;
|
||||||
|
kitty::dynamic_truth_table tt_or(2);
|
||||||
|
kitty::create_from_words(tt_or, &_or, &_or + 1);
|
||||||
|
_storage->data.cache.insert(tt_or);
|
||||||
|
|
||||||
|
static uint64_t _xor = 0x6;
|
||||||
|
kitty::dynamic_truth_table tt_xor(2);
|
||||||
|
kitty::create_from_words(tt_xor, &_xor, &_xor + 1);
|
||||||
|
_storage->data.cache.insert(tt_xor);
|
||||||
|
|
||||||
|
static uint64_t _mux= 0xd8;
|
||||||
|
kitty::dynamic_truth_table tt_mux(3);
|
||||||
|
kitty::create_from_words(tt_mux, &_mux, &_mux + 1);
|
||||||
|
_storage->data.cache.insert(tt_mux);
|
||||||
|
|
||||||
|
|
||||||
|
/* truth tables for constants */
|
||||||
|
_storage->nodes[0].data[1].h1 = 0;
|
||||||
|
_storage->nodes[1].data[1].h1 = 1;
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Primary I / O and constants
|
||||||
|
public:
|
||||||
|
signal get_constant(bool value = false) const
|
||||||
|
{
|
||||||
|
return value ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal create_pi(std::string const& name = std::string())
|
||||||
|
{
|
||||||
|
(void)name;
|
||||||
|
|
||||||
|
const auto index = _storage->nodes.size();
|
||||||
|
_storage->nodes.emplace_back();
|
||||||
|
_storage->inputs.emplace_back(index);
|
||||||
|
_storage->nodes[index].data[1].h1 = 2;
|
||||||
|
++_storage->data.num_pis;
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t create_po(signal const& f, std::string const& name = std::string())
|
||||||
|
{
|
||||||
|
(void)name;
|
||||||
|
|
||||||
|
/* increase ref-count to children */
|
||||||
|
_storage->nodes[f].data[0].h1++;
|
||||||
|
|
||||||
|
auto const po_index = _storage->outputs.size();
|
||||||
|
_storage->outputs.emplace_back(f);
|
||||||
|
++_storage->data.num_pos;
|
||||||
|
return po_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t create_ri(signal const& f, int8_t reset = 0, std::string const& name = std::string())
|
||||||
|
{
|
||||||
|
(void)name;
|
||||||
|
|
||||||
|
/* increase ref-count to children */
|
||||||
|
_storage->nodes[f].data[0].h1++;
|
||||||
|
auto const ri_index = _storage->outputs.size();
|
||||||
|
_storage->outputs.emplace_back(f);
|
||||||
|
_storage->data.latches.emplace_back(reset);
|
||||||
|
return ri_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t latch_reset(uint32_t index) const
|
||||||
|
{
|
||||||
|
assert(index < _storage->data.latches.size());
|
||||||
|
return _storage->data.latches[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_combinational() const
|
||||||
|
{
|
||||||
|
return (static_cast<uint32_t>(_storage->inputs.size()) == _storage->data.num_pis &&
|
||||||
|
static_cast<uint32_t>(_storage->outputs.size()) == _storage->data.num_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_constant(node const& n) const
|
||||||
|
{
|
||||||
|
return n <= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_ci(node const& n) const
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
detail::foreach_element(_storage->inputs.begin(), _storage->inputs.end(), [&found, &n](auto const& node) {
|
||||||
|
if (node == n)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_pi(node const& n) const
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
detail::foreach_element(_storage->inputs.begin(), _storage->inputs.begin() + _storage->data.num_pis, [&found, &n](auto const& node) {
|
||||||
|
if (node == n)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool constant_value(node const& n) const
|
||||||
|
{
|
||||||
|
return n == 1;
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Create unary functions
|
||||||
|
signal create_buf(signal const& a)
|
||||||
|
{
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal create_not(signal const& a)
|
||||||
|
{
|
||||||
|
return _create_node({ a }, 3);
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Create binary/ternary functions
|
||||||
|
signal create_and(signal a, signal b)
|
||||||
|
{
|
||||||
|
return _create_node({ a, b }, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal create_or(signal a, signal b)
|
||||||
|
{
|
||||||
|
return _create_node({ a, b }, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal create_xor(signal a, signal b)
|
||||||
|
{
|
||||||
|
return _create_node({ a, b }, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal create_mux(signal a, signal b, signal c)
|
||||||
|
{
|
||||||
|
return _create_node({ a, b, c }, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Create arbitrary functions
|
||||||
|
signal _create_node(std::vector<signal> const& children, uint32_t literal)
|
||||||
|
{
|
||||||
|
storage::element_type::node_type node;
|
||||||
|
std::copy(children.begin(), children.end(), std::back_inserter(node.children));
|
||||||
|
node.data[1].h1 = literal;
|
||||||
|
|
||||||
|
const auto it = _storage->hash.find(node);
|
||||||
|
if (it != _storage->hash.end())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto index = _storage->nodes.size();
|
||||||
|
_storage->nodes.push_back(node);
|
||||||
|
_storage->hash[node] = index;
|
||||||
|
|
||||||
|
/* increase ref-count to children */
|
||||||
|
for (auto c : children)
|
||||||
|
{
|
||||||
|
_storage->nodes[c].data[0].h1++;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_value(index, 0);
|
||||||
|
|
||||||
|
for (auto const& fn : _events->on_add)
|
||||||
|
{
|
||||||
|
(*fn)(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal create_node(std::vector<signal> const& children, kitty::dynamic_truth_table const& function)
|
||||||
|
{
|
||||||
|
if (children.size() == 0u)
|
||||||
|
{
|
||||||
|
assert(function.num_vars() == 0u);
|
||||||
|
return get_constant(!kitty::is_const0(function));
|
||||||
|
}
|
||||||
|
return _create_node(children, _storage->data.cache.insert(function));
|
||||||
|
}
|
||||||
|
|
||||||
|
signal clone_node(aoig_network const& other, node const& source, std::vector<signal> const& children)
|
||||||
|
{
|
||||||
|
assert(!children.empty());
|
||||||
|
const auto tt = other._storage->data.cache[other._storage->nodes[source].data[1].h1];
|
||||||
|
return create_node(children, tt);
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Restructuring
|
||||||
|
void substitute_node(node const& old_node, signal const& new_signal)
|
||||||
|
{
|
||||||
|
/* find all parents from old_node */
|
||||||
|
for (auto i = 0u; i < _storage->nodes.size(); ++i)
|
||||||
|
{
|
||||||
|
auto& n = _storage->nodes[i];
|
||||||
|
for (auto& child : n.children)
|
||||||
|
{
|
||||||
|
if (child == old_node)
|
||||||
|
{
|
||||||
|
std::vector<signal> old_children(n.children.size());
|
||||||
|
std::transform(n.children.begin(), n.children.end(), old_children.begin(), [](auto c) { return c.index; });
|
||||||
|
child = new_signal;
|
||||||
|
|
||||||
|
// increment fan-out of new node
|
||||||
|
_storage->nodes[new_signal].data[0].h1++;
|
||||||
|
|
||||||
|
for (auto const& fn : _events->on_modified)
|
||||||
|
{
|
||||||
|
(*fn)(i, old_children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check outputs */
|
||||||
|
for (auto& output : _storage->outputs)
|
||||||
|
{
|
||||||
|
if (output == old_node)
|
||||||
|
{
|
||||||
|
output = new_signal;
|
||||||
|
|
||||||
|
// increment fan-out of new node
|
||||||
|
_storage->nodes[new_signal].data[0].h1++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset fan-out of old node
|
||||||
|
_storage->nodes[old_node].data[0].h1 = 0;
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Structural properties
|
||||||
|
auto size() const
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t>(_storage->nodes.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto num_cis() const
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t>(_storage->inputs.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto num_cos() const
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t>(_storage->outputs.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto num_pis() const
|
||||||
|
{
|
||||||
|
return _storage->data.num_pis;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto num_pos() const
|
||||||
|
{
|
||||||
|
return _storage->data.num_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
auto num_gates() const
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t>(_storage->nodes.size() - _storage->inputs.size() - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fanin_size(node const& n) const
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t>(_storage->nodes[n].children.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fanout_size(node const& n) const
|
||||||
|
{
|
||||||
|
return _storage->nodes[n].data[0].h1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_function(node const& n) const
|
||||||
|
{
|
||||||
|
return n > 1 && !is_ci(n);
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Functional properties
|
||||||
|
kitty::dynamic_truth_table node_function(const node& n) const
|
||||||
|
{
|
||||||
|
return _storage->data.cache[_storage->nodes[n].data[1].h1];
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Nodes and signals
|
||||||
|
node get_node(signal const& f) const
|
||||||
|
{
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_complemented( signal const& f ) const
|
||||||
|
{
|
||||||
|
(void)f;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal make_signal(node const& n) const
|
||||||
|
{
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t node_to_index(node const& n) const
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t>(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
node index_to_node(uint32_t index) const
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
node ci_at(uint32_t index) const
|
||||||
|
{
|
||||||
|
assert(index < _storage->inputs.size());
|
||||||
|
return *(_storage->inputs.begin() + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal co_at(uint32_t index) const
|
||||||
|
{
|
||||||
|
assert(index < _storage->outputs.size());
|
||||||
|
return (_storage->outputs.begin() + index)->index;
|
||||||
|
}
|
||||||
|
|
||||||
|
node pi_at(uint32_t index) const
|
||||||
|
{
|
||||||
|
assert(index < _storage->data.num_pis);
|
||||||
|
return *(_storage->inputs.begin() + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal po_at(uint32_t index) const
|
||||||
|
{
|
||||||
|
assert(index < _storage->data.num_pos);
|
||||||
|
return (_storage->outputs.begin() + index)->index;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ci_index(node const& n) const
|
||||||
|
{
|
||||||
|
assert(_storage->nodes[n].children[0].data == _storage->nodes[n].children[1].data);
|
||||||
|
return (_storage->nodes[n].children[0].data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t co_index(signal const& s) const
|
||||||
|
{
|
||||||
|
uint32_t i = -1;
|
||||||
|
foreach_co([&](const auto& x, auto index) {
|
||||||
|
if (x == s)
|
||||||
|
{
|
||||||
|
i = index;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t pi_index(node const& n) const
|
||||||
|
{
|
||||||
|
assert(_storage->nodes[n].children[0].data == _storage->nodes[n].children[1].data);
|
||||||
|
return (_storage->nodes[n].children[0].data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t po_index(signal const& s) const
|
||||||
|
{
|
||||||
|
uint32_t i = -1;
|
||||||
|
foreach_po([&](const auto& x, auto index) {
|
||||||
|
if (x == s)
|
||||||
|
{
|
||||||
|
i = index;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Node and signal iterators
|
||||||
|
template<typename Fn>
|
||||||
|
void foreach_node(Fn&& fn) const
|
||||||
|
{
|
||||||
|
detail::foreach_element(ez::make_direct_iterator<uint64_t>(0),
|
||||||
|
ez::make_direct_iterator<uint64_t>(_storage->nodes.size()),
|
||||||
|
fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Fn>
|
||||||
|
void foreach_ci(Fn&& fn) const
|
||||||
|
{
|
||||||
|
detail::foreach_element(_storage->inputs.begin(), _storage->inputs.end(), fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Fn>
|
||||||
|
void foreach_co(Fn&& fn) const
|
||||||
|
{
|
||||||
|
using IteratorType = decltype(_storage->outputs.begin());
|
||||||
|
detail::foreach_element_transform<IteratorType, uint32_t>(_storage->outputs.begin(), _storage->outputs.end(), [](auto o) { return o.index; }, fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Fn>
|
||||||
|
void foreach_pi(Fn&& fn) const
|
||||||
|
{
|
||||||
|
detail::foreach_element(_storage->inputs.begin(), _storage->inputs.begin() + _storage->data.num_pis, fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Fn>
|
||||||
|
void foreach_po(Fn&& fn) const
|
||||||
|
{
|
||||||
|
using IteratorType = decltype(_storage->outputs.begin());
|
||||||
|
detail::foreach_element_transform<IteratorType, uint32_t>(_storage->outputs.begin(), _storage->outputs.begin() + _storage->data.num_pos, [](auto o) { return o.index; }, fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Fn>
|
||||||
|
void foreach_gate(Fn&& fn) const
|
||||||
|
{
|
||||||
|
detail::foreach_element_if(ez::make_direct_iterator<uint64_t>(2), /* start from 2 to avoid constants */
|
||||||
|
ez::make_direct_iterator<uint64_t>(_storage->nodes.size()),
|
||||||
|
[this](auto n) { return !is_ci(n); },
|
||||||
|
fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Fn>
|
||||||
|
void foreach_fanin(node const& n, Fn&& fn) const
|
||||||
|
{
|
||||||
|
if (n == 0 || is_ci(n))
|
||||||
|
return;
|
||||||
|
|
||||||
|
using IteratorType = decltype(_storage->outputs.begin());
|
||||||
|
detail::foreach_element_transform<IteratorType, uint32_t>(_storage->nodes[n].children.begin(), _storage->nodes[n].children.end(), [](auto f) { return f.index; }, fn);
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Simulate values
|
||||||
|
template<typename Iterator>
|
||||||
|
iterates_over_t<Iterator, bool>
|
||||||
|
compute(node const& n, Iterator begin, Iterator end) const
|
||||||
|
{
|
||||||
|
uint32_t index{ 0 };
|
||||||
|
while (begin != end)
|
||||||
|
{
|
||||||
|
index <<= 1;
|
||||||
|
index ^= *begin++ ? 1 : 0;
|
||||||
|
}
|
||||||
|
return kitty::get_bit(_storage->data.cache[_storage->nodes[n].data[1].h1], index);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator>
|
||||||
|
iterates_over_truth_table_t<Iterator>
|
||||||
|
compute(node const& n, Iterator begin, Iterator end) const
|
||||||
|
{
|
||||||
|
const auto nfanin = _storage->nodes[n].children.size();
|
||||||
|
std::vector<typename Iterator::value_type> tts(begin, end);
|
||||||
|
|
||||||
|
assert(nfanin != 0);
|
||||||
|
assert(tts.size() == nfanin);
|
||||||
|
|
||||||
|
/* resulting truth table has the same size as any of the children */
|
||||||
|
auto result = tts.front().construct();
|
||||||
|
const auto gate_tt = _storage->data.cache[_storage->nodes[n].data[1].h1];
|
||||||
|
|
||||||
|
for (auto i = 0u; i < result.num_bits(); ++i)
|
||||||
|
{
|
||||||
|
uint32_t pattern = 0u;
|
||||||
|
for (auto j = 0u; j < nfanin; ++j)
|
||||||
|
{
|
||||||
|
pattern |= kitty::get_bit(tts[j], i) << j;
|
||||||
|
}
|
||||||
|
if (kitty::get_bit(gate_tt, pattern))
|
||||||
|
{
|
||||||
|
kitty::set_bit(result, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Custom node values
|
||||||
|
void clear_values() const
|
||||||
|
{
|
||||||
|
std::for_each(_storage->nodes.begin(), _storage->nodes.end(), [](auto& n) { n.data[0].h2 = 0; });
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t value(node const& n) const
|
||||||
|
{
|
||||||
|
return _storage->nodes[n].data[0].h2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_value(node const& n, uint32_t v) const
|
||||||
|
{
|
||||||
|
_storage->nodes[n].data[0].h2 = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t incr_value(node const& n) const
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t>(_storage->nodes[n].data[0].h2++);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t decr_value(node const& n) const
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t>(--_storage->nodes[n].data[0].h2);
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Visited flags
|
||||||
|
void clear_visited() const
|
||||||
|
{
|
||||||
|
std::for_each(_storage->nodes.begin(), _storage->nodes.end(), [](auto& n) { n.data[1].h2 = 0; });
|
||||||
|
}
|
||||||
|
|
||||||
|
auto visited(node const& n) const
|
||||||
|
{
|
||||||
|
return _storage->nodes[n].data[1].h2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_visited(node const& n, uint32_t v) const
|
||||||
|
{
|
||||||
|
_storage->nodes[n].data[1].h2 = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t trav_id() const
|
||||||
|
{
|
||||||
|
return _storage->data.trav_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void incr_trav_id() const
|
||||||
|
{
|
||||||
|
++_storage->data.trav_id;
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region General methods
|
||||||
|
auto& events() const
|
||||||
|
{
|
||||||
|
return *_events;
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::shared_ptr<aoig_storage> _storage;
|
||||||
|
std::shared_ptr<network_events<base_type>> _events;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mockturtle
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,220 @@
|
||||||
|
0x3cc3 ![d[bc]]
|
||||||
|
0x1ee1 ![{ab}[cd]]
|
||||||
|
0x1be4 [c[d(!a[bc])]]
|
||||||
|
0x19e6 [[ad](b!(ac))]
|
||||||
|
0x19e1 ![[a(c!d)](b!(a!(!cd)))]
|
||||||
|
0x18e7 ![d([ac][bc])]
|
||||||
|
0x1798 [d{(ab)(c![d[ab]])}]
|
||||||
|
0x1796 [a{[bc](d![ab])}]
|
||||||
|
0x177e [(ab){[cd][d[ab]]}]
|
||||||
|
0x16e9 ![d(!(ab)[c{ab}])]
|
||||||
|
0x169b ![[b[ad]]([c(a[b[ad]])][d(a[b[ad]])])]
|
||||||
|
0x1699 ![b[a(d!(c!(ab)))]]
|
||||||
|
0x1696 [a[b(c!(b(ad)))]]
|
||||||
|
0x017e [d{[a(b!(ad))][c(b!(ad))]}]
|
||||||
|
0x168e (!(c[d[ac]])[b([ac]!(b!d))])
|
||||||
|
0x0666 ([ab]!(cd))
|
||||||
|
0x1687 ![c([a(d!(a!c))][b(d!(a!c))])]
|
||||||
|
0x016f !{(c![ab])(d{ab})}
|
||||||
|
0x166e [(cd)[a(b!(a![cd]))]]
|
||||||
|
0x1683 ![{bc}(![a(bc)][d(bc)])]
|
||||||
|
0x1681 ![([ad][bd]){c[[ad]{b([ad][bd])}]}]
|
||||||
|
0x17e8 [d({ab}!(!c[ab]))]
|
||||||
|
0x166a [[a(!d[bc])]{[bc](c!(!ad))}]
|
||||||
|
0x168b ![[c(b![ac])](d![b{a(b![ac])}])]
|
||||||
|
0x1669 ![[b[ac]](d!(c(ab)))]
|
||||||
|
0x16ac {([bc][ad])([bd][a[bc]])}
|
||||||
|
0x07f8 [d{c(ab)}]
|
||||||
|
0x07b5 !{(cd)([ac]!(!b[cd]))}
|
||||||
|
0x07b4 [c{(!ab)(d!(b!c))}]
|
||||||
|
0x001f !{d(c{ab})}
|
||||||
|
0x03c7 !{(bd)({ac}[bc])}
|
||||||
|
0x0ff0 [cd]
|
||||||
|
0x03d7 !({ad}[b(c!(bd))])
|
||||||
|
0x07b1 !{(b![ad])[d(!c{ad})]}
|
||||||
|
0x077e (!(cd){[a[cd]][b[cd]]})
|
||||||
|
0x0778 [d[c(b(a!(cd)))]]
|
||||||
|
0x06f0 ([cd]!(d![ab]))
|
||||||
|
0x06f9 ![d(!c[ab])]
|
||||||
|
0x07b0 ([cd]!(b[ac]))
|
||||||
|
0x06f6 [d{c[b[ad]]}]
|
||||||
|
0x06b6 ([c[a{b(ac)}]]!(d![a{b(ac)}]))
|
||||||
|
0x06b4 (!(cd)[[bc](a{bd})])
|
||||||
|
0x019a [a{(ad)(!b[cd])}]
|
||||||
|
0x06b0 ([cd]{(ac)[a[bc]]})
|
||||||
|
0x07e3 ![(b!(!ad))(c!(a![bd]))]
|
||||||
|
0x0697 !(!(!c[b(a!c)]){d[a[b(a!c)]]})
|
||||||
|
0x06b5 !({d[ac]}!([cd][b[ac]]))
|
||||||
|
0x0696 (!(cd)[b[ac]])
|
||||||
|
0x178e [c{[a[cd]][b[cd]]}]
|
||||||
|
0x0691 !{[b[ad]](![cd]{c[ad]})}
|
||||||
|
0x169a (!(c(bd))[(!bc)[a(bd)]])
|
||||||
|
0x077a (!(cd)[{cd}(a!(!b{cd}))])
|
||||||
|
0x0679 ![d([b[ac]]!(c!(b!d)))]
|
||||||
|
0x0678 [[c(ab)](d{[ab][c(ab)]})]
|
||||||
|
0x0672 (!(cd)[{ac}(b{ad})])
|
||||||
|
0x066b !({b{cd}}!(!(cd)[a(b{cd})]))
|
||||||
|
0x0662 ([ab]![c(!d{bc})])
|
||||||
|
0x6996 [d[c[ab]]]
|
||||||
|
0x0661 !{({ac}![cd])[a[b[cd]]]}
|
||||||
|
0x07e0 ([cd]!([ac][bc]))
|
||||||
|
0x0690 ([cd][b[ac]])
|
||||||
|
0x0660 ([ab][cd])
|
||||||
|
0x011e [{cd}{b{a(cd)}}]
|
||||||
|
0x03dd ![{bc}(!d{b[ac]})]
|
||||||
|
0x1668 [[ac](![bd]{[ab][ac]})]
|
||||||
|
0x0007 !{d{c(ab)}}
|
||||||
|
0x06b1 ![(!c[b[ac]]){d(b[ac])}]
|
||||||
|
0x03dc [d{b(c!(a!d))}]
|
||||||
|
0x0667 !(!(!c[b{ac}]){d[a[b{ac}]]})
|
||||||
|
0x01eb !{(d{ab})(!a[bc])}
|
||||||
|
0x03d5 !({ad}!(![bc][cd]))
|
||||||
|
0x066f ![(!c[b[ac]]){d[b[ac]]}]
|
||||||
|
0x03d8 ([d[c(a[bc])]]!([bc]![c(a[bc])]))
|
||||||
|
0x06b3 !{(cd)[(!ad)(b!(ac))]}
|
||||||
|
0x03d6 [{bc}{d(a!(bc))}]
|
||||||
|
0x0180 ([bd]([ad][cd]))
|
||||||
|
0x03fc [d{bc}]
|
||||||
|
0x03d4 [{bc}{d(a[bc])}]
|
||||||
|
0x016a (!(d{bc})[(bc)[ad]])
|
||||||
|
0x07e9 ![{c(ab)}(!d{ab})]
|
||||||
|
0x06b9 ![d([ab]!(c!(b!d)))]
|
||||||
|
0x03c6 [(!c{ad})(b!(d!(!c{ad})))]
|
||||||
|
0x0669 !{(cd)[b[a{cd}]]}
|
||||||
|
0x03c1 !{[bc]({ad}![cd])}
|
||||||
|
0x036f ![{bc}(!d[b(ac)])]
|
||||||
|
0x036e {(!c[bd])(!d[a[bd]])}
|
||||||
|
0x07f2 [d{c(a![bd])}]
|
||||||
|
0x03db !({bc}!(!d[c(a!(bc))]))
|
||||||
|
0x036d ![{(b!c)(a!d)}[c(b!d)]]
|
||||||
|
0x0189 ![{b(!ac)}(a!(d{b(!ac)}))]
|
||||||
|
0x0369 !{[c[b(a!d)]](d[b(a!d)])}
|
||||||
|
0x035e [c{(a!d)[d(b!c)]}]
|
||||||
|
0x035b !({bc}!(!d[ac]))
|
||||||
|
0x033f !{(bc)(d[bc])}
|
||||||
|
0x01fe [d{c{ab}}]
|
||||||
|
0x01ee [d{b{a(cd)}}]
|
||||||
|
0x003d !{d[b(!c{ab})]}
|
||||||
|
0x06bd ![d([ab]![c(b!d)])]
|
||||||
|
0x035f !{(ac)(d{bc})}
|
||||||
|
0x1bd8 [a[c(![bc][ad])]]
|
||||||
|
0x0116 (!(c{ab})(!(ab)[c[d{ab}]]))
|
||||||
|
0x03d9 ![b{(a!d)(c[bd])}]
|
||||||
|
0x06f2 ([(a!c){bc}]{(a!c)[cd]})
|
||||||
|
0x0358 [c({ad}{c[bd]})]
|
||||||
|
0x033d !{(bc)[d(!b(!c{ad}))]}
|
||||||
|
0x006f !{d(c![ab])}
|
||||||
|
0x019e (!(c![b[ac]])[d{a[b[ac]]}])
|
||||||
|
0x01e8 ([d{ab}]!(!(ab)[c{ab}]))
|
||||||
|
0x07f0 [d{c(b(ad))}]
|
||||||
|
0x01af !{(!ac)(d{ab})}
|
||||||
|
0x0197 ![{d[ab]}(!c[d{ab}])]
|
||||||
|
0x01bf !{(c(!a[bd]))(d!(!a[bd]))}
|
||||||
|
0x03c5 ![{c(a!d)}(b[cd])]
|
||||||
|
0x01bd ![{bc}({a[bc]}!(d{bc}))]
|
||||||
|
0x011f !({cd}{b{a(cd)}})
|
||||||
|
0x06b7 ![d([b(ad)][c{ad}])]
|
||||||
|
0x013f !{(bc)(d{a[bc]})}
|
||||||
|
0x01bc ([d{a[bc]}]!(![bc][c{a[bc]}]))
|
||||||
|
0x036a [{bc}{d[a[bc]]}]
|
||||||
|
0x036c [[b(ac)](d!(c![b(ac)]))]
|
||||||
|
0x167e (!(d![c[ab]]){[ab][b[c[ab]]]})
|
||||||
|
0x06b2 (!(!a[bd])[d{c[a[bd]]}])
|
||||||
|
0x01ad ![a{(!ac)({bc}[ad])}]
|
||||||
|
0x035a [{ad}{c(bd)}]
|
||||||
|
0x01ab ![{bc}(a[d{bc}])]
|
||||||
|
0x018b !{(ad)[c(b![ac])]}
|
||||||
|
0x01ac ([a(!c[b{ad}])]!(d!(!c[b{ad}])))
|
||||||
|
0x01be (!(bd)[d{a[bc]}])
|
||||||
|
0x16ad ![(bd)[[cd](a!(b![cd]))]]
|
||||||
|
0x0186 (![c(ab)][d{ab}])
|
||||||
|
0x01aa ([ad]!(d{bc}))
|
||||||
|
0x1686 ([b[ac]]!(c![ad]))
|
||||||
|
0x01a9 ![a({bc}!(ad))]
|
||||||
|
0x07b6 [{c(a![bd])}{d(!a[bd])}]
|
||||||
|
0x01a8 (![a{bc}][d{bc}])
|
||||||
|
0x007e (!d{[ab][ac]})
|
||||||
|
0x019f !{(d!(!a[cd]))[(!a[cd])(!b[cd])]}
|
||||||
|
0x0676 (!(cd)[a{b(!ac)}])
|
||||||
|
0x0663 !{(cd)[b(!a[cd])]}
|
||||||
|
0x013d ![(!d[bc]){b{a[bc]}}]
|
||||||
|
0x019b !{(cd)[b(a{c[bd]})]}
|
||||||
|
0x0119 ![{a(cd)}(b!({cd}{a(cd)}))]
|
||||||
|
0x0168 (![c[ab]][d{ab}])
|
||||||
|
0x16a9 ![{bc}[a(d!(!a(bc)))]]
|
||||||
|
0x0368 [(a!d)(![bc][d{c(a!d)}])]
|
||||||
|
0x0198 (![ab][d{ac}])
|
||||||
|
0x018f !{(c!(ab))(d{ab})}
|
||||||
|
0x06f1 ![d(!c[a(b!(a!d))])]
|
||||||
|
0x0183 !{[bc][b(a[cd])]}
|
||||||
|
0x0182 (!(bd)(![bc][ad]))
|
||||||
|
0x0181 !{[a(b!(ad))][c(b!(ad))]}
|
||||||
|
0x07bc [[cd](b![d(a[cd])])]
|
||||||
|
0x03c3 ![b(c!(bd))]
|
||||||
|
0x0199 !{[ab](d{bc})}
|
||||||
|
0x19e3 ![{b(ac)}(!(!ad)[cd])]
|
||||||
|
0x003c (!d[bc])
|
||||||
|
0x0016 (!{d(ab)}[a[bc]])
|
||||||
|
0x0779 !({c[b[a[cd]]]}!([cd]!(a[b[a[cd]]])))
|
||||||
|
0x0359 ![{ad}(!c[bd])]
|
||||||
|
0x0006 ([ab]!{cd})
|
||||||
|
0x016e (!(c![ab])[d{ab}])
|
||||||
|
0x1698 ({b[ac]}![[bd]{a(d[ac])}])
|
||||||
|
0x01e9 ![{c(ab)}({ab}!(d{c(ab)}))]
|
||||||
|
0x16bc [c[b(a[d(bc)])]]
|
||||||
|
0x166b ![d([a[bc]]!(a![bd]))]
|
||||||
|
0x0118 (![a(b!(ac))][c[d(b!(ac))]])
|
||||||
|
0x017f ![d([cd]([ad][bd]))]
|
||||||
|
0x0001 !{{ab}{cd}}
|
||||||
|
0x0187 !{[c(ab)](d{ab})}
|
||||||
|
0x07e1 ![c{(a!d)(b![d(a!c)])}]
|
||||||
|
0x067e [d{[c(a!d)][a[bd]]}]
|
||||||
|
0x0117 ![(!d(!(ab)[c{ab}])){{ab}(!(ab)[c{ab}])}]
|
||||||
|
0x013e [{d(bc)}{a{bc}}]
|
||||||
|
0x033c [b[c(d!(bc))]]
|
||||||
|
0x07e6 [{c(ab)}{d[c{ab}]}]
|
||||||
|
0x036b !({bc}!(!d[a(bc)]))
|
||||||
|
0x012f !{(b[cd])[c(a[cd])]}
|
||||||
|
0x0356 [{bc}{ad}]
|
||||||
|
0x011b ![{b{a(cd)}}(!{cd}{a(cd)})]
|
||||||
|
0x01ef ![d(!b(!a[cd]))]
|
||||||
|
0x037c [{bc}{d(a(bc))}]
|
||||||
|
0x012d !{(d{ab})[b[c{ab}]]}
|
||||||
|
0x169e [c[a(b!(a![cd]))]]
|
||||||
|
0x01ae (!(!ac)[d{ab}])
|
||||||
|
0x01ea ([d{ab}]!(!a[bc]))
|
||||||
|
0x0019 !{d[a(b!(ac))]}
|
||||||
|
0x067a {(!d[a[cd]])([cd]![b[a[cd]]])}
|
||||||
|
0x007f !{d(c(ab))}
|
||||||
|
0x0776 (!(cd)[a{b(!a{cd})}])
|
||||||
|
0x006b !{d[c[b(a{bc})]]}
|
||||||
|
0x17ac [[d{bc}](!a[c(bd)])]
|
||||||
|
0x011a ([d[ac]][c{a[bd]}])
|
||||||
|
0x013c ([c[bd]]!(d!(!a[bd])))
|
||||||
|
0x07f1 ![d(!c{[ad][bd]})]
|
||||||
|
0x067b ![{d(a![bc])}(!c[a[bc]])]
|
||||||
|
0x037d ![d({ad}!{[bc](cd)})]
|
||||||
|
0x0003 !{d{bc}}
|
||||||
|
0x0069 !{d[c[ab]]}
|
||||||
|
0x003f !{d(bc)}
|
||||||
|
0x012c ([b[cd]]![d(!a[cd])])
|
||||||
|
0x0196 (!(d!(!b[ad]))[b[c[ad]]])
|
||||||
|
0x001e (!d[c{ab}])
|
||||||
|
0x0169 !{(d{ab})[b[ac]]}
|
||||||
|
0x07e2 (!(cd)[{ad}(b[ac])])
|
||||||
|
0x0693 ![(a[cd])[b(d!(bc))]]
|
||||||
|
0x016b ![{bc}([a(bc)][d{bc}])]
|
||||||
|
0x03c0 ([bd][cd])
|
||||||
|
0x037e [d{[b(a!d)][c(a!d)]}]
|
||||||
|
0x000f !{cd}
|
||||||
|
0x001b !{d[b(a[bc])]}
|
||||||
|
0x0357 !({bc}{ad})
|
||||||
|
0x0018 (!d([ac][bc]))
|
||||||
|
0x1689 ![[ad]{[b(!ac)](c![ad])}]
|
||||||
|
0x0673 !({bd}!([ab][cd]))
|
||||||
|
0x03cf ![c(b[cd])]
|
||||||
|
0x069f ![c(![ab][cd])]
|
||||||
|
0x1697 ![c(![ab]{[ad][cd]})]
|
||||||
|
0x03de [d{b[c(a!d)]}]
|
||||||
|
0x179a [a[{c[b(!ad)]}(b!(d[b(!ad)]))]]
|
||||||
|
0x0017 !{(ab){d(c[ab])}}
|
|
@ -0,0 +1,339 @@
|
||||||
|
/* phyLS: Advanced Logic Synthesis and Optimization tool
|
||||||
|
* Copyright (C) 2019- Ningbo University, Ningbo, China */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file xag_dec.hpp
|
||||||
|
*
|
||||||
|
* @brief Deompose a truth table into an XAG signal by combined
|
||||||
|
* decompostion methods (DSD, Shannon, and NPN )
|
||||||
|
*
|
||||||
|
* @author Zhufei Chu
|
||||||
|
* @since 0.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XAG_DEC_HPP
|
||||||
|
#define XAG_DEC_HPP
|
||||||
|
|
||||||
|
#include "../../core/misc.hpp"
|
||||||
|
#include "build_xag_db.hpp"
|
||||||
|
|
||||||
|
namespace phyLS
|
||||||
|
{
|
||||||
|
/*! \brief Parameters for xag_dec */
|
||||||
|
struct xag_dec_params
|
||||||
|
{
|
||||||
|
/*! \brief Apply NPN4. */
|
||||||
|
bool with_npn4{true};
|
||||||
|
};
|
||||||
|
|
||||||
|
class xag_dec_impl
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::vector<uint8_t> get_func_supports( kitty::dynamic_truth_table const& spec )
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> supports;
|
||||||
|
|
||||||
|
for( auto i = 0u; i < spec.num_vars(); ++i )
|
||||||
|
{
|
||||||
|
if( kitty::has_var( spec, i ) )
|
||||||
|
{
|
||||||
|
supports.push_back( i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return supports;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
xag_dec_impl( xag_network& ntk, kitty::dynamic_truth_table const& func, std::vector<xag_network::signal> const& children,
|
||||||
|
std::unordered_map<std::string, std::string>& opt_xags,
|
||||||
|
xag_dec_params const& ps )
|
||||||
|
: _ntk( ntk ),
|
||||||
|
_func( func ),
|
||||||
|
pis( children ),
|
||||||
|
opt_xags( opt_xags ),
|
||||||
|
_ps( ps )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
xag_network::signal decompose( kitty::dynamic_truth_table& remainder, std::vector<xag_network::signal> const& children )
|
||||||
|
{
|
||||||
|
auto sup = get_func_supports( remainder );
|
||||||
|
|
||||||
|
/* check constants */
|
||||||
|
if ( kitty::is_const0( remainder ) )
|
||||||
|
{
|
||||||
|
return _ntk.get_constant( false );
|
||||||
|
}
|
||||||
|
if ( kitty::is_const0( ~remainder ) )
|
||||||
|
{
|
||||||
|
return _ntk.get_constant( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check primary inputs */
|
||||||
|
if( sup.size() == 1u )
|
||||||
|
{
|
||||||
|
auto var = remainder.construct();
|
||||||
|
|
||||||
|
kitty::create_nth_var( var, sup.front() );
|
||||||
|
if( remainder == var )
|
||||||
|
{
|
||||||
|
return children[sup.front()];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert( remainder == ~var );
|
||||||
|
return _ntk.create_not( children[sup.front()] );
|
||||||
|
}
|
||||||
|
assert( false && "ERROR for primary inputs" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* top decomposition */
|
||||||
|
for( auto var : sup )
|
||||||
|
{
|
||||||
|
if ( auto res = kitty::is_top_decomposable( remainder, var, &remainder, true );
|
||||||
|
res != kitty::top_decomposition::none )
|
||||||
|
{
|
||||||
|
const auto right = decompose( remainder, children );
|
||||||
|
|
||||||
|
switch ( res )
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
assert( false );
|
||||||
|
case kitty::top_decomposition::and_:
|
||||||
|
return _ntk.create_and( children[var], right );
|
||||||
|
case kitty::top_decomposition::or_:
|
||||||
|
return _ntk.create_or( children[var], right );
|
||||||
|
case kitty::top_decomposition::lt_:
|
||||||
|
return _ntk.create_lt( children[var], right );
|
||||||
|
case kitty::top_decomposition::le_:
|
||||||
|
return _ntk.create_le( children[var], right );
|
||||||
|
case kitty::top_decomposition::xor_:
|
||||||
|
return _ntk.create_xor( children[var], right );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bottom decomposition */
|
||||||
|
for ( auto j = 1u; j < sup.size(); ++j )
|
||||||
|
{
|
||||||
|
for ( auto i = 0u; i < j; ++i )
|
||||||
|
{
|
||||||
|
if ( auto res = kitty::is_bottom_decomposable( remainder, sup[i], sup[j], &remainder, true );
|
||||||
|
res != kitty::bottom_decomposition::none ) /* allow XOR */
|
||||||
|
{
|
||||||
|
auto copy = children;
|
||||||
|
switch ( res )
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
assert( false );
|
||||||
|
case kitty::bottom_decomposition::and_:
|
||||||
|
copy[sup[i]] = _ntk.create_and( copy[sup[i]], copy[sup[j]] );
|
||||||
|
break;
|
||||||
|
case kitty::bottom_decomposition::or_:
|
||||||
|
copy[sup[i]] = _ntk.create_or( copy[sup[i]], copy[sup[j]] );
|
||||||
|
break;
|
||||||
|
case kitty::bottom_decomposition::lt_:
|
||||||
|
copy[sup[i]] = _ntk.create_lt( copy[sup[i]], copy[sup[j]] );
|
||||||
|
break;
|
||||||
|
case kitty::bottom_decomposition::le_:
|
||||||
|
copy[sup[i]] = _ntk.create_le( copy[sup[i]], copy[sup[j]] );
|
||||||
|
break;
|
||||||
|
case kitty::bottom_decomposition::xor_:
|
||||||
|
copy[sup[i]] = _ntk.create_xor( copy[sup[i]], copy[sup[j]] );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return decompose( remainder, copy );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sup.size() > 4u || !_ps.with_npn4 )
|
||||||
|
{
|
||||||
|
/* shannon decomposition */
|
||||||
|
auto var = sup.front();
|
||||||
|
auto c0 = kitty::cofactor0( remainder, var );
|
||||||
|
auto c1 = kitty::cofactor1( remainder, var );
|
||||||
|
|
||||||
|
const auto f0 = decompose( c0, children );
|
||||||
|
const auto f1 = decompose( c1, children );
|
||||||
|
|
||||||
|
return _ntk.create_ite( children[var], f1, f0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* NPN transformation */
|
||||||
|
return xag_from_npn( remainder, children );
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
xag_network::signal xag_from_npn( kitty::dynamic_truth_table const& remainder, std::vector<xag_network::signal> const& children )
|
||||||
|
{
|
||||||
|
/* get pi signals */
|
||||||
|
auto sup = get_func_supports( remainder );
|
||||||
|
std::vector<xag_network::signal> small_pis;
|
||||||
|
for( auto const i : sup )
|
||||||
|
{
|
||||||
|
small_pis.push_back( children[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
auto copy = remainder;
|
||||||
|
const auto support = kitty::min_base_inplace( copy );
|
||||||
|
const auto small_func = kitty::shrink_to( copy, static_cast<unsigned int>( support.size() ) );
|
||||||
|
|
||||||
|
auto tt = small_func;
|
||||||
|
|
||||||
|
auto ttsup = get_func_supports( tt );
|
||||||
|
|
||||||
|
const auto config = kitty::exact_npn_canonization( tt );
|
||||||
|
|
||||||
|
auto func_str = "0x" + kitty::to_hex( std::get<0>( config ) );
|
||||||
|
//std::cout << " process function " << func_str << std::endl;
|
||||||
|
|
||||||
|
const auto it = opt_xags.find( func_str );
|
||||||
|
assert( it != opt_xags.end() );
|
||||||
|
|
||||||
|
std::vector<xag_network::signal> pis( support.size(), _ntk.get_constant( false ) );
|
||||||
|
std::copy( small_pis.begin(), small_pis.end(), pis.begin() );
|
||||||
|
|
||||||
|
std::vector<xag_network::signal> pis_perm( support.size() );
|
||||||
|
auto perm = std::get<2>( config );
|
||||||
|
for ( auto i = 0; i < support.size(); ++i )
|
||||||
|
{
|
||||||
|
pis_perm[i] = pis[perm[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& phase = std::get<1>( config );
|
||||||
|
for ( auto i = 0; i < support.size(); ++i )
|
||||||
|
{
|
||||||
|
if ( ( phase >> perm[i] ) & 1 )
|
||||||
|
{
|
||||||
|
pis_perm[i] = !pis_perm[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto res = create_xag_from_str( it->second, pis_perm );
|
||||||
|
|
||||||
|
return ( ( phase >> support.size() ) & 1 ) ? !res : res;
|
||||||
|
}
|
||||||
|
|
||||||
|
xag_network::signal create_xag_from_str( const std::string& str, const std::vector<xag_network::signal>& pis_perm )
|
||||||
|
{
|
||||||
|
std::stack<int> polar;
|
||||||
|
std::stack<xag_network::signal> inputs;
|
||||||
|
|
||||||
|
for ( auto i = 0ul; i < str.size(); i++ )
|
||||||
|
{
|
||||||
|
// operators polarity
|
||||||
|
if ( str[i] == '[' || str[i] == '(' || str[i] == '{' )
|
||||||
|
{
|
||||||
|
polar.push( (i > 0 && str[i - 1] == '!') ? 1 : 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//input signals
|
||||||
|
if ( str[i] >= 'a' && str[i] <= 'd' )
|
||||||
|
{
|
||||||
|
inputs.push( pis_perm[str[i] - 'a'] );
|
||||||
|
|
||||||
|
polar.push( ( i > 0 && str[i - 1] == '!' ) ? 1 : 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//create signals
|
||||||
|
if ( str[i] == ']' )
|
||||||
|
{
|
||||||
|
assert( inputs.size() >= 2u );
|
||||||
|
auto x1 = inputs.top();
|
||||||
|
inputs.pop();
|
||||||
|
auto x2 = inputs.top();
|
||||||
|
inputs.pop();
|
||||||
|
|
||||||
|
assert( polar.size() >= 3u );
|
||||||
|
auto p1 = polar.top();
|
||||||
|
polar.pop();
|
||||||
|
auto p2 = polar.top();
|
||||||
|
polar.pop();
|
||||||
|
|
||||||
|
auto p3 = polar.top();
|
||||||
|
polar.pop();
|
||||||
|
|
||||||
|
inputs.push( _ntk.create_xor( x1 ^ p1, x2 ^ p2 ) ^ p3 );
|
||||||
|
polar.push( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( str[i] == ')' )
|
||||||
|
{
|
||||||
|
assert( inputs.size() >= 2u );
|
||||||
|
auto x1 = inputs.top();
|
||||||
|
inputs.pop();
|
||||||
|
auto x2 = inputs.top();
|
||||||
|
inputs.pop();
|
||||||
|
|
||||||
|
assert( polar.size() >= 3u );
|
||||||
|
auto p1 = polar.top();
|
||||||
|
polar.pop();
|
||||||
|
auto p2 = polar.top();
|
||||||
|
polar.pop();
|
||||||
|
|
||||||
|
auto p3 = polar.top();
|
||||||
|
polar.pop();
|
||||||
|
|
||||||
|
inputs.push( _ntk.create_and( x1 ^ p1, x2 ^ p2 ) ^ p3 );
|
||||||
|
polar.push( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( str[i] == '}' )
|
||||||
|
{
|
||||||
|
assert( inputs.size() >= 2u );
|
||||||
|
auto x1 = inputs.top();
|
||||||
|
inputs.pop();
|
||||||
|
auto x2 = inputs.top();
|
||||||
|
inputs.pop();
|
||||||
|
|
||||||
|
assert( polar.size() >= 3u );
|
||||||
|
auto p1 = polar.top();
|
||||||
|
polar.pop();
|
||||||
|
auto p2 = polar.top();
|
||||||
|
polar.pop();
|
||||||
|
|
||||||
|
auto p3 = polar.top();
|
||||||
|
polar.pop();
|
||||||
|
|
||||||
|
inputs.push( _ntk.create_or( x1 ^ p1, x2 ^ p2 ) ^ p3 );
|
||||||
|
polar.push( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( !polar.empty() );
|
||||||
|
auto po = polar.top();
|
||||||
|
polar.pop();
|
||||||
|
return inputs.top() ^ po;
|
||||||
|
}
|
||||||
|
|
||||||
|
xag_network::signal run()
|
||||||
|
{
|
||||||
|
return decompose( _func, pis );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
xag_network& _ntk;
|
||||||
|
kitty::dynamic_truth_table _func;
|
||||||
|
std::vector<xag_network::signal> pis;
|
||||||
|
std::unordered_map<std::string, std::string>& opt_xags;
|
||||||
|
xag_dec_params const& _ps;
|
||||||
|
};
|
||||||
|
|
||||||
|
xag_network::signal xag_dec( xag_network& ntk, kitty::dynamic_truth_table const& func, std::vector<xag_network::signal> const& children,
|
||||||
|
std::unordered_map<std::string, std::string>& opt_xags,
|
||||||
|
xag_dec_params const& ps = {} )
|
||||||
|
{
|
||||||
|
xag_dec_impl impl( ntk, func, children, opt_xags, ps );
|
||||||
|
return impl.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} //end of namespace
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,45 @@
|
||||||
|
/* phyLS: Advanced Logic Synthesis and Optimization tool
|
||||||
|
* Copyright (C) 2019- Ningbo University, Ningbo, China */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file xag_lut_dec.hpp
|
||||||
|
*
|
||||||
|
* @brief resynthesis using xag decomposition
|
||||||
|
*
|
||||||
|
* @author Zhufei
|
||||||
|
* @since 0.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XAG_LUT_DEC_HPP
|
||||||
|
#define XAG_LUT_DEC_HPP
|
||||||
|
|
||||||
|
#include "xag_dec.hpp"
|
||||||
|
#include "build_xag_db.hpp"
|
||||||
|
|
||||||
|
namespace mockturtle
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class Ntk>
|
||||||
|
class xag_lut_dec_resynthesis
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit xag_lut_dec_resynthesis( std::unordered_map<std::string, std::string>& opt_xags )
|
||||||
|
: opt_xags( opt_xags )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename LeavesIterator, typename Fn>
|
||||||
|
void operator()( Ntk& ntk, kitty::dynamic_truth_table const& function, LeavesIterator begin, LeavesIterator end, Fn&& fn ) const
|
||||||
|
{
|
||||||
|
const auto f = phyLS::xag_dec( ntk, function, std::vector<signal<Ntk>>( begin, end ), opt_xags );
|
||||||
|
fn( f );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<std::string, std::string>& opt_xags;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,129 @@
|
||||||
|
/* mockturtle: C++ logic network library
|
||||||
|
* Copyright (C) 2018-2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\file xag_lut_npn.hpp
|
||||||
|
\brief Replace with size-optimum XAGs from NPN
|
||||||
|
|
||||||
|
\author Zhufei Chu
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stack>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <kitty/dynamic_truth_table.hpp>
|
||||||
|
#include <kitty/npn.hpp>
|
||||||
|
#include <kitty/print.hpp>
|
||||||
|
|
||||||
|
#include "build_xag_db.hpp"
|
||||||
|
|
||||||
|
namespace mockturtle
|
||||||
|
{
|
||||||
|
|
||||||
|
/*! \brief Resynthesis function based on pre-computed size-optimum xags.
|
||||||
|
*
|
||||||
|
* This resynthesis function can be passed to ``node_resynthesis``,
|
||||||
|
* ``cut_rewriting``, and ``refactoring``. It will produce an xag based on
|
||||||
|
* pre-computed size-optimum xags with up to at most 4 variables.
|
||||||
|
* Consequently, the nodes' fan-in sizes in the input network must not exceed
|
||||||
|
* 4.
|
||||||
|
*
|
||||||
|
\verbatim embed:rst
|
||||||
|
|
||||||
|
Example
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
const klut_network klut = ...;
|
||||||
|
xag_npn_lut_resynthesis resyn;
|
||||||
|
const auto xag = node_resynthesis<xag_network>( klut, resyn );
|
||||||
|
\endverbatim
|
||||||
|
*/
|
||||||
|
class xag_npn_lut_resynthesis
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*! \brief Default constructor.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
xag_npn_lut_resynthesis()
|
||||||
|
{
|
||||||
|
class2signal = phyLS::get_xag_db( db );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename LeavesIterator, typename Fn>
|
||||||
|
void operator()( xag_network& xag, kitty::dynamic_truth_table const& function, LeavesIterator begin, LeavesIterator end, Fn&& fn ) const
|
||||||
|
{
|
||||||
|
assert( function.num_vars() <= 4 );
|
||||||
|
const auto fe = kitty::extend_to( function, 4 );
|
||||||
|
const auto config = kitty::exact_npn_canonization( fe );
|
||||||
|
|
||||||
|
auto func_str = "0x" + kitty::to_hex( std::get<0>( config ) );
|
||||||
|
const auto it = class2signal.find( func_str );
|
||||||
|
assert( it != class2signal.end() );
|
||||||
|
|
||||||
|
//const auto it = class2signal.find( static_cast<uint16_t>( std::get<0>( config )._bits[0] ) );
|
||||||
|
|
||||||
|
std::vector<xag_network::signal> pis( 4, xag.get_constant( false ) );
|
||||||
|
std::copy( begin, end, pis.begin() );
|
||||||
|
|
||||||
|
std::vector<xag_network::signal> pis_perm( 4 );
|
||||||
|
auto perm = std::get<2>( config );
|
||||||
|
for ( auto i = 0; i < 4; ++i )
|
||||||
|
{
|
||||||
|
pis_perm[i] = pis[perm[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& phase = std::get<1>( config );
|
||||||
|
for ( auto i = 0; i < 4; ++i )
|
||||||
|
{
|
||||||
|
if ( ( phase >> perm[i] ) & 1 )
|
||||||
|
{
|
||||||
|
pis_perm[i] = !pis_perm[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( auto const& po : it->second )
|
||||||
|
{
|
||||||
|
topo_view topo{db, po};
|
||||||
|
auto f = cleanup_dangling( topo, xag, pis_perm.begin(), pis_perm.end() ).front();
|
||||||
|
|
||||||
|
if ( !fn( ( ( phase >> 4 ) & 1 ) ? !f : f ) )
|
||||||
|
{
|
||||||
|
return; /* quit */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
xag_network db;
|
||||||
|
std::unordered_map<std::string, std::vector<xag_network::signal>> class2signal;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace mockturtle */
|
|
@ -0,0 +1,592 @@
|
||||||
|
/* phyLS: Advanced Logic Synthesis and Optimization tool
|
||||||
|
* Copyright (C) 2019- Ningbo University, Ningbo, China
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\file mg.hpp
|
||||||
|
\brief Matrix logic network implementation
|
||||||
|
\brief Inspired from aig.hpp in mockturtle
|
||||||
|
\author Homyoung
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <kitty/dynamic_truth_table.hpp>
|
||||||
|
#include <kitty/operators.hpp>
|
||||||
|
#include <kitty/partial_truth_table.hpp>
|
||||||
|
#include <memory>
|
||||||
|
#include <mockturtle/networks/detail/foreach.hpp>
|
||||||
|
#include <mockturtle/networks/events.hpp>
|
||||||
|
#include <mockturtle/networks/storage.hpp>
|
||||||
|
#include <mockturtle/traits.hpp>
|
||||||
|
#include <mockturtle/utils/algorithm.hpp>
|
||||||
|
#include <optional>
|
||||||
|
#include <stack>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace mockturtle {
|
||||||
|
|
||||||
|
/*! \brief Hash function for AIGs (from ABC) */
|
||||||
|
template <class Node>
|
||||||
|
struct mg_hash {
|
||||||
|
uint64_t operator()(Node const& n) const {
|
||||||
|
uint64_t seed = -2011;
|
||||||
|
seed += n.children[0].index * 7937;
|
||||||
|
seed += n.children[1].index * 2971;
|
||||||
|
seed += n.children[0].weight * 911;
|
||||||
|
seed += n.children[1].weight * 353;
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using mg_storage = storage<regular_node<2, 2, 1>, empty_storage_data,
|
||||||
|
mg_hash<regular_node<2, 2, 1>>>;
|
||||||
|
|
||||||
|
class mg_network {
|
||||||
|
public:
|
||||||
|
#pragma region Types and constructors
|
||||||
|
static constexpr auto min_fanin_size = 2u;
|
||||||
|
static constexpr auto max_fanin_size = 2u;
|
||||||
|
|
||||||
|
using base_type = mg_network;
|
||||||
|
using storage = std::shared_ptr<mg_storage>;
|
||||||
|
using node = uint64_t;
|
||||||
|
|
||||||
|
struct signal {
|
||||||
|
signal() = default;
|
||||||
|
|
||||||
|
signal(uint64_t index, uint64_t complement)
|
||||||
|
: complement(complement), index(index) {}
|
||||||
|
|
||||||
|
explicit signal(uint64_t data) : data(data) {}
|
||||||
|
|
||||||
|
signal(mg_storage::node_type::pointer_type const& p)
|
||||||
|
: complement(p.weight), index(p.index) {}
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint64_t complement : 1;
|
||||||
|
uint64_t index : 63;
|
||||||
|
};
|
||||||
|
uint64_t data;
|
||||||
|
};
|
||||||
|
|
||||||
|
signal operator!() const { return signal(data ^ 1); }
|
||||||
|
|
||||||
|
signal operator+() const { return {index, 0}; }
|
||||||
|
|
||||||
|
signal operator-() const { return {index, 1}; }
|
||||||
|
|
||||||
|
signal operator^(bool complement) const {
|
||||||
|
return signal(data ^ (complement ? 1 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(signal const& other) const { return data == other.data; }
|
||||||
|
|
||||||
|
bool operator!=(signal const& other) const { return data != other.data; }
|
||||||
|
|
||||||
|
bool operator<(signal const& other) const { return data < other.data; }
|
||||||
|
|
||||||
|
operator mg_storage::node_type::pointer_type() const {
|
||||||
|
return {index, complement};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus > 201703L
|
||||||
|
bool operator==(mg_storage::node_type::pointer_type const& other) const {
|
||||||
|
return data == other.data;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
mg_network()
|
||||||
|
: _storage(std::make_shared<mg_storage>()),
|
||||||
|
_events(std::make_shared<decltype(_events)::element_type>()) {}
|
||||||
|
|
||||||
|
mg_network(std::shared_ptr<mg_storage> storage)
|
||||||
|
: _storage(storage),
|
||||||
|
_events(std::make_shared<decltype(_events)::element_type>()) {}
|
||||||
|
|
||||||
|
mg_network clone() const { return {std::make_shared<mg_storage>(*_storage)}; }
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Primary I / O and constants
|
||||||
|
signal get_constant(bool value) const {
|
||||||
|
return {0, static_cast<uint64_t>(value ? 1 : 0)};
|
||||||
|
}
|
||||||
|
|
||||||
|
signal create_pi() {
|
||||||
|
const auto index = _storage->nodes.size();
|
||||||
|
auto& node = _storage->nodes.emplace_back();
|
||||||
|
node.children[0].data = node.children[1].data = _storage->inputs.size();
|
||||||
|
_storage->inputs.emplace_back(index);
|
||||||
|
return {index, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t create_po(signal const& f) {
|
||||||
|
/* increase ref-count to children */
|
||||||
|
_storage->nodes[f.index].data[0].h1++;
|
||||||
|
auto const po_index = _storage->outputs.size();
|
||||||
|
_storage->outputs.emplace_back(f.index, f.complement);
|
||||||
|
return static_cast<uint32_t>(po_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_combinational() const { return true; }
|
||||||
|
|
||||||
|
bool is_constant(node const& n) const { return n == 0; }
|
||||||
|
|
||||||
|
bool is_ci(node const& n) const {
|
||||||
|
return _storage->nodes[n].children[0].data ==
|
||||||
|
_storage->nodes[n].children[1].data;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_pi(node const& n) const {
|
||||||
|
return _storage->nodes[n].children[0].data ==
|
||||||
|
_storage->nodes[n].children[1].data &&
|
||||||
|
!is_constant(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool constant_value(node const& n) const {
|
||||||
|
(void)n;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Create unary functions
|
||||||
|
signal create_buf(signal const& a) { return a; }
|
||||||
|
signal create_not(signal const& a) { return !a; }
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Create binary functions
|
||||||
|
signal create_node(signal a, signal b, uint32_t literal) {
|
||||||
|
storage::element_type::node_type node;
|
||||||
|
node.children[0] = a;
|
||||||
|
node.children[1] = b;
|
||||||
|
node.data[1].h1 = literal;
|
||||||
|
|
||||||
|
/* structural hashing */
|
||||||
|
const auto it = _storage->hash.find(node);
|
||||||
|
if (it != _storage->hash.end()) return {it->second, 0};
|
||||||
|
|
||||||
|
const auto index = _storage->nodes.size();
|
||||||
|
|
||||||
|
if (index >= .9 * _storage->nodes.capacity()) {
|
||||||
|
_storage->nodes.reserve(static_cast<uint64_t>(3.1415f * index));
|
||||||
|
_storage->hash.reserve(static_cast<uint64_t>(3.1415f * index));
|
||||||
|
}
|
||||||
|
|
||||||
|
_storage->nodes.push_back(node);
|
||||||
|
_storage->hash[node] = index;
|
||||||
|
|
||||||
|
/* increase ref-count to children */
|
||||||
|
_storage->nodes[a.index].data[0].h1++;
|
||||||
|
_storage->nodes[b.index].data[0].h1++;
|
||||||
|
|
||||||
|
for (auto const& fn : _events->on_add) (*fn)(index);
|
||||||
|
|
||||||
|
return {index, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
signal create_0(signal a, signal b) { return get_constant(false); }
|
||||||
|
signal create_1(signal a, signal b) {
|
||||||
|
if (a.index > b.index) std::swap(a, b);
|
||||||
|
if (a.index == b.index) {
|
||||||
|
return create_not(a);
|
||||||
|
} else if (a.index == 0) {
|
||||||
|
return create_not(b);
|
||||||
|
} else if (a.index == 1) {
|
||||||
|
return get_constant(false);
|
||||||
|
} else if (b.index == 0) {
|
||||||
|
return create_not(a);
|
||||||
|
} else if (b.index == 1) {
|
||||||
|
return get_constant(false);
|
||||||
|
}
|
||||||
|
return create_node(a, b, 1);
|
||||||
|
}
|
||||||
|
signal create_2(signal a, signal b) { return create_node(a, b, 2); }
|
||||||
|
signal create_not(signal a, signal b) { return create_node(a, b, 3); }
|
||||||
|
signal create_and(signal a, signal b) { return create_node(a, b, 4); }
|
||||||
|
signal create_nand(signal a, signal b) { return create_node(a, b, 5); }
|
||||||
|
signal create_or(signal a, signal b) { return create_node(a, b, 6); }
|
||||||
|
signal create_7(signal a, signal b) { return create_node(a, b, 7); }
|
||||||
|
signal create_lt(signal a, signal b) { return create_node(a, b, 8); }
|
||||||
|
signal create_9(signal a, signal b) { return create_node(a, b, 9); }
|
||||||
|
signal create_a(signal a, signal b) { return create_node(a, b, 10); }
|
||||||
|
signal create_le(signal a, signal b) { return create_node(a, b, 11); }
|
||||||
|
signal create_xor(signal a, signal b) { return create_node(a, b, 12); }
|
||||||
|
signal create_d(signal a, signal b) { return create_node(a, b, 13); }
|
||||||
|
signal create_e(signal a, signal b) { return create_node(a, b, 14); }
|
||||||
|
signal create_f(signal a, signal b) { return get_constant(true); }
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Createy ternary functions
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Create nary functions
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Create arbitrary functions
|
||||||
|
signal clone_node(mg_network const& other, node const& source,
|
||||||
|
std::vector<signal> const& children) {
|
||||||
|
(void)other;
|
||||||
|
(void)source;
|
||||||
|
assert(children.size() == 2u);
|
||||||
|
const auto tt = other._storage->nodes[source].data[1].h1;
|
||||||
|
return create_node(children[0u], children[1u], tt);
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Restructuring
|
||||||
|
void substitute_node(node const& old_node, signal const& new_signal) {
|
||||||
|
/* find all parents from old_node */
|
||||||
|
for (auto i = 0u; i < _storage->nodes.size(); ++i) {
|
||||||
|
auto& n = _storage->nodes[i];
|
||||||
|
for (auto& child : n.children) {
|
||||||
|
if (child == old_node) {
|
||||||
|
std::vector<signal> old_children(n.children.size());
|
||||||
|
std::transform(n.children.begin(), n.children.end(),
|
||||||
|
old_children.begin(), [](auto c) { return c.index; });
|
||||||
|
child = new_signal;
|
||||||
|
|
||||||
|
// increment fan-out of new node
|
||||||
|
_storage->nodes[new_signal].data[0].h1++;
|
||||||
|
|
||||||
|
for (auto const& fn : _events->on_modified) {
|
||||||
|
(*fn)(i, old_children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check outputs */
|
||||||
|
for (auto& output : _storage->outputs) {
|
||||||
|
if (output == old_node) {
|
||||||
|
output = new_signal;
|
||||||
|
|
||||||
|
// increment fan-out of new node
|
||||||
|
_storage->nodes[new_signal].data[0].h1++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset fan-out of old node
|
||||||
|
_storage->nodes[old_node].data[0].h1 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool is_dead(node const& n) const { return false; }
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Structural properties
|
||||||
|
auto size() const { return static_cast<uint32_t>(_storage->nodes.size()); }
|
||||||
|
|
||||||
|
auto num_cis() const {
|
||||||
|
return static_cast<uint32_t>(_storage->inputs.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto num_cos() const {
|
||||||
|
return static_cast<uint32_t>(_storage->outputs.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto num_pis() const {
|
||||||
|
return static_cast<uint32_t>(_storage->inputs.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto num_pos() const {
|
||||||
|
return static_cast<uint32_t>(_storage->outputs.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto num_gates() const {
|
||||||
|
return static_cast<uint32_t>(_storage->hash.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fanin_size(node const& n) const {
|
||||||
|
if (is_constant(n) || is_ci(n)) return 0;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fanout_size(node const& n) const {
|
||||||
|
return _storage->nodes[n].data[0].h1 & UINT32_C(0x7FFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t incr_fanout_size(node const& n) const {
|
||||||
|
return _storage->nodes[n].data[0].h1++ & UINT32_C(0x7FFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t decr_fanout_size(node const& n) const {
|
||||||
|
return --_storage->nodes[n].data[0].h1 & UINT32_C(0x7FFFFFFF);
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Functional properties
|
||||||
|
// kitty::dynamic_truth_table node_function(const node& n) const {
|
||||||
|
// return _storage->nodes[n].data[1].h1;
|
||||||
|
// }
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Nodes and signals
|
||||||
|
node get_node(signal const& f) const { return f.index; }
|
||||||
|
|
||||||
|
signal make_signal(node const& n) const { return signal(n, 0); }
|
||||||
|
|
||||||
|
bool is_complemented(signal const& f) const { return f.complement; }
|
||||||
|
|
||||||
|
uint32_t node_to_index(node const& n) const {
|
||||||
|
return static_cast<uint32_t>(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
node index_to_node(uint32_t index) const { return index; }
|
||||||
|
|
||||||
|
node ci_at(uint32_t index) const {
|
||||||
|
assert(index < _storage->inputs.size());
|
||||||
|
return *(_storage->inputs.begin() + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal co_at(uint32_t index) const {
|
||||||
|
assert(index < _storage->outputs.size());
|
||||||
|
return *(_storage->outputs.begin() + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
node pi_at(uint32_t index) const {
|
||||||
|
assert(index < _storage->inputs.size());
|
||||||
|
return *(_storage->inputs.begin() + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal po_at(uint32_t index) const {
|
||||||
|
assert(index < _storage->outputs.size());
|
||||||
|
return *(_storage->outputs.begin() + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ci_index(node const& n) const {
|
||||||
|
assert(_storage->nodes[n].children[0].data ==
|
||||||
|
_storage->nodes[n].children[1].data);
|
||||||
|
return static_cast<uint32_t>(_storage->nodes[n].children[0].data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t co_index(signal const& s) const {
|
||||||
|
uint32_t i = -1;
|
||||||
|
foreach_co([&](const auto& x, auto index) {
|
||||||
|
if (x == s) {
|
||||||
|
i = index;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t pi_index(node const& n) const {
|
||||||
|
assert(_storage->nodes[n].children[0].data ==
|
||||||
|
_storage->nodes[n].children[1].data);
|
||||||
|
return static_cast<uint32_t>(_storage->nodes[n].children[0].data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t po_index(signal const& s) const {
|
||||||
|
uint32_t i = -1;
|
||||||
|
foreach_po([&](const auto& x, auto index) {
|
||||||
|
if (x == s) {
|
||||||
|
i = index;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Node and signal iterators
|
||||||
|
template <typename Fn>
|
||||||
|
void foreach_node(Fn&& fn) const {
|
||||||
|
auto r = range<uint64_t>(_storage->nodes.size());
|
||||||
|
detail::foreach_element_if(
|
||||||
|
r.begin(), r.end(), [this](auto n) { return !is_dead(n); }, fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Fn>
|
||||||
|
void foreach_ci(Fn&& fn) const {
|
||||||
|
detail::foreach_element(_storage->inputs.begin(), _storage->inputs.end(),
|
||||||
|
fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Fn>
|
||||||
|
void foreach_co(Fn&& fn) const {
|
||||||
|
detail::foreach_element(_storage->outputs.begin(), _storage->outputs.end(),
|
||||||
|
fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Fn>
|
||||||
|
void foreach_pi(Fn&& fn) const {
|
||||||
|
detail::foreach_element(_storage->inputs.begin(), _storage->inputs.end(),
|
||||||
|
fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Fn>
|
||||||
|
void foreach_po(Fn&& fn) const {
|
||||||
|
detail::foreach_element(_storage->outputs.begin(), _storage->outputs.end(),
|
||||||
|
fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Fn>
|
||||||
|
void foreach_gate(Fn&& fn) const {
|
||||||
|
auto r = range<uint64_t>(
|
||||||
|
1u, _storage->nodes.size()); /* start from 1 to avoid constant */
|
||||||
|
detail::foreach_element_if(
|
||||||
|
r.begin(), r.end(), [this](auto n) { return !is_ci(n) && !is_dead(n); },
|
||||||
|
fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Fn>
|
||||||
|
void foreach_fanin(node const& n, Fn&& fn) const {
|
||||||
|
if (n == 0 || is_ci(n)) return;
|
||||||
|
|
||||||
|
static_assert(detail::is_callable_without_index_v<Fn, signal, bool> ||
|
||||||
|
detail::is_callable_with_index_v<Fn, signal, bool> ||
|
||||||
|
detail::is_callable_without_index_v<Fn, signal, void> ||
|
||||||
|
detail::is_callable_with_index_v<Fn, signal, void>);
|
||||||
|
|
||||||
|
/* we don't use foreach_element here to have better performance */
|
||||||
|
if constexpr (detail::is_callable_without_index_v<Fn, signal, bool>) {
|
||||||
|
if (!fn(signal{_storage->nodes[n].children[0]})) return;
|
||||||
|
fn(signal{_storage->nodes[n].children[1]});
|
||||||
|
} else if constexpr (detail::is_callable_with_index_v<Fn, signal, bool>) {
|
||||||
|
if (!fn(signal{_storage->nodes[n].children[0]}, 0)) return;
|
||||||
|
fn(signal{_storage->nodes[n].children[1]}, 1);
|
||||||
|
} else if constexpr (detail::is_callable_without_index_v<Fn, signal,
|
||||||
|
void>) {
|
||||||
|
fn(signal{_storage->nodes[n].children[0]});
|
||||||
|
fn(signal{_storage->nodes[n].children[1]});
|
||||||
|
} else if constexpr (detail::is_callable_with_index_v<Fn, signal, void>) {
|
||||||
|
fn(signal{_storage->nodes[n].children[0]}, 0);
|
||||||
|
fn(signal{_storage->nodes[n].children[1]}, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Value simulation
|
||||||
|
template <typename Iterator>
|
||||||
|
iterates_over_t<Iterator, bool> compute(node const& n, Iterator begin,
|
||||||
|
Iterator end) const {
|
||||||
|
(void)end;
|
||||||
|
|
||||||
|
assert(n != 0 && !is_ci(n));
|
||||||
|
|
||||||
|
auto const& c1 = _storage->nodes[n].children[0];
|
||||||
|
auto const& c2 = _storage->nodes[n].children[1];
|
||||||
|
|
||||||
|
auto v1 = *begin++;
|
||||||
|
auto v2 = *begin++;
|
||||||
|
|
||||||
|
if (c2.index == 0) {
|
||||||
|
return ~v1 ^ c1.weight;
|
||||||
|
} else {
|
||||||
|
return (~v1 ^ c1.weight) || (v2 ^ c2.weight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
iterates_over_truth_table_t<Iterator> compute(node const& n, Iterator begin,
|
||||||
|
Iterator end) const {
|
||||||
|
(void)end;
|
||||||
|
|
||||||
|
assert(n != 0 && !is_ci(n));
|
||||||
|
|
||||||
|
auto const& c1 = _storage->nodes[n].children[0];
|
||||||
|
auto const& c2 = _storage->nodes[n].children[1];
|
||||||
|
|
||||||
|
auto tt1 = *begin++;
|
||||||
|
auto tt2 = *begin++;
|
||||||
|
|
||||||
|
if (c2.index == 0) {
|
||||||
|
return c1.weight ? tt1 : ~tt1;
|
||||||
|
} else {
|
||||||
|
return (c1.weight ? tt1 : ~tt1) | (c2.weight ? ~tt2 : tt2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Custom node values
|
||||||
|
void clear_values() const {
|
||||||
|
std::for_each(_storage->nodes.begin(), _storage->nodes.end(),
|
||||||
|
[](auto& n) { n.data[0].h2 = 0; });
|
||||||
|
}
|
||||||
|
|
||||||
|
auto value(node const& n) const { return _storage->nodes[n].data[0].h2; }
|
||||||
|
|
||||||
|
void set_value(node const& n, uint32_t v) const {
|
||||||
|
_storage->nodes[n].data[0].h2 = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto incr_value(node const& n) const {
|
||||||
|
return _storage->nodes[n].data[0].h2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto decr_value(node const& n) const {
|
||||||
|
return --_storage->nodes[n].data[0].h2;
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Visited flags
|
||||||
|
void clear_visited() const {
|
||||||
|
std::for_each(_storage->nodes.begin(), _storage->nodes.end(),
|
||||||
|
[](auto& n) { n.data[1].h1 = 0; });
|
||||||
|
}
|
||||||
|
|
||||||
|
auto visited(node const& n) const { return _storage->nodes[n].data[1].h1; }
|
||||||
|
|
||||||
|
void set_visited(node const& n, uint32_t v) const {
|
||||||
|
_storage->nodes[n].data[1].h1 = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t trav_id() const { return _storage->trav_id; }
|
||||||
|
|
||||||
|
void incr_trav_id() const { ++_storage->trav_id; }
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region General methods
|
||||||
|
auto& events() const { return *_events; }
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::shared_ptr<mg_storage> _storage;
|
||||||
|
std::shared_ptr<network_events<base_type>> _events;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mockturtle
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<mockturtle::mg_network::signal> {
|
||||||
|
uint64_t operator()(mockturtle::mg_network::signal const& s) const noexcept {
|
||||||
|
uint64_t k = s.data;
|
||||||
|
k ^= k >> 33;
|
||||||
|
k *= 0xff51afd7ed558ccd;
|
||||||
|
k ^= k >> 33;
|
||||||
|
k *= 0xc4ceb9fe1a85ec53;
|
||||||
|
k ^= k >> 33;
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
}; /* hash */
|
||||||
|
|
||||||
|
} // namespace std
|
|
@ -0,0 +1,222 @@
|
||||||
|
0x0000 5-1-3-4 6-1-4-5 7-8-4-6
|
||||||
|
0x0001 5-14-2-3 6-14-1-4 7-1-5-6
|
||||||
|
0x0003 5-14-2-4 6-4-2-3 7-1-5-6
|
||||||
|
0x0006 5-6-1-2 6-4-4-5 7-4-3-6
|
||||||
|
0x0007 5-14-3-4 6-8-1-2 7-1-5-6
|
||||||
|
0x000f 5-14-3-4 6-4-2-3 7-1-5-6
|
||||||
|
0x0016 5-14-2-3 6-6-1-5 7-8-2-3 8-14-4-7 9-2-6-8
|
||||||
|
0x0017 5-6-2-3 6-14-2-3 7-4-1-5 8-6-6-7 9-1-4-8
|
||||||
|
0x0018 5-6-1-3 6-6-2-3 7-4-4-5 8-8-6-7
|
||||||
|
0x0019 5-8-1-3 6-6-1-2 7-14-4-5 8-1-6-7
|
||||||
|
0x001b 5-8-1-3 6-4-1-2 7-6-5-6 8-1-4-7
|
||||||
|
0x001e 5-14-1-2 6-6-3-5 7-4-4-6
|
||||||
|
0x001f 5-14-1-2 6-8-3-5 7-1-4-6
|
||||||
|
0x003c 5-10-3-4 6-6-2-5 7-4-4-6
|
||||||
|
0x003d 5-6-2-3 6-14-1-2 7-4-5-6 8-1-4-7
|
||||||
|
0x003f 5-14-3-4 6-14-2-4 7-7-5-6
|
||||||
|
0x0069 5-6-1-3 6-6-2-5 7-1-4-6
|
||||||
|
0x006b 5-14-2-3 6-8-1-5 7-6-3-6 8-6-2-7 9-1-4-8
|
||||||
|
0x006f 5-6-1-2 6-2-3-5 7-1-4-6
|
||||||
|
0x007e 5-6-1-3 6-6-1-2 7-14-5-6 8-4-4-7
|
||||||
|
0x007f 5-8-1-3 6-8-2-5 7-1-4-6
|
||||||
|
0x00ff 5-8-3-4 6-4-3-4 7-1-5-6
|
||||||
|
0x0116 5-8-3-4 6-14-2-5 7-14-1-6 8-8-1-2 9-14-4-8 10-14-3-9 11-6-7-10
|
||||||
|
0x0117 5-8-3-4 6-14-3-4 7-14-1-5 8-6-2-7 9-6-6-7 10-2-8-9 11-9-2-10
|
||||||
|
0x0118 5-14-3-4 6-6-1-5 7-8-3-4 8-14-2-7 9-6-1-8 10-2-6-9
|
||||||
|
0x0119 5-8-2-4 6-14-2-4 7-6-1-2 8-14-3-5 9-8-6-8 10-1-7-9
|
||||||
|
0x011a 5-8-3-4 6-14-3-4 7-14-2-5 8-4-1-7 9-2-6-8 10-6-1-9
|
||||||
|
0x011b 5-14-3-4 6-6-3-4 7-4-1-2 8-4-1-6 9-6-5-8 10-1-7-9
|
||||||
|
0x011e 5-8-3-4 6-14-3-4 7-14-1-5 8-14-2-7 9-6-6-8
|
||||||
|
0x011f 5-6-3-4 6-14-3-4 7-14-1-2 8-2-5-7 9-13-6-8
|
||||||
|
0x012c 5-14-2-3 6-6-4-5 7-2-1-2 8-6-3-7 9-2-6-8
|
||||||
|
0x012d 5-6-2-3 6-14-1-2 7-8-4-5 8-2-6-7 9-9-5-8
|
||||||
|
0x012f 5-2-1-2 6-2-3-5 7-14-1-2 8-8-4-7 9-1-6-8
|
||||||
|
0x013c 5-14-1-3 6-14-3-4 7-8-4-5 8-14-2-7 9-6-6-8
|
||||||
|
0x013d 5-14-1-3 6-6-2-3 7-4-4-6 8-14-5-6 9-11-7-8
|
||||||
|
0x013e 5-8-2-3 6-14-4-5 7-14-2-3 8-14-1-7 9-6-6-8
|
||||||
|
0x013f 5-14-2-3 6-14-1-5 7-8-2-3 8-14-4-7 9-7-6-8
|
||||||
|
0x0168 5-6-1-3 6-6-2-5 7-14-1-3 8-6-4-7 9-4-6-8
|
||||||
|
0x0169 5-6-1-3 6-6-2-5 7-14-1-2 8-8-4-7 9-1-6-8
|
||||||
|
0x016a 5-14-2-3 6-8-4-5 7-8-2-3 8-14-4-7 9-6-1-8 10-4-6-9
|
||||||
|
0x016b 5-14-2-3 6-8-2-3 7-6-1-6 8-4-4-7 9-14-5-7 10-11-8-9
|
||||||
|
0x016e 5-14-1-2 6-6-4-5 7-6-1-2 8-2-3-7 9-2-6-8
|
||||||
|
0x016f 5-14-1-2 6-8-4-5 7-6-1-2 8-2-3-7 9-1-6-8
|
||||||
|
0x017e 5-14-2-3 6-14-1-5 7-8-2-3 8-8-1-7 9-14-4-8 10-6-6-9
|
||||||
|
0x017f 5-7-1-3 6-2-2-5 7-1-2-3 8-11-1-7 9-7-4-8 10-4-6-9
|
||||||
|
0x0180 5-6-1-4 6-6-2-3 7-6-3-4 8-2-5-6 9-8-7-8
|
||||||
|
0x0181 5-6-1-3 6-8-1-4 7-6-2-3 8-14-5-6 9-1-7-8
|
||||||
|
0x0182 5-6-2-3 6-4-1-2 7-6-1-4 8-14-5-6 9-2-7-8
|
||||||
|
0x0183 5-4-1-3 6-8-1-4 7-6-2-3 8-14-5-7 9-1-6-8
|
||||||
|
0x0186 5-8-1-2 6-6-3-5 7-14-1-2 8-6-4-7 9-4-6-8
|
||||||
|
0x0187 5-8-1-2 6-6-3-5 7-14-1-2 8-8-4-7 9-1-6-8
|
||||||
|
0x0189 5-8-2-4 6-2-1-5 7-4-2-3 8-14-6-7 9-9-2-8
|
||||||
|
0x018b 5-8-1-4 6-4-2-3 7-4-1-2 8-6-5-7 9-1-6-8
|
||||||
|
0x018f 5-14-1-2 6-8-4-5 7-8-1-2 8-2-3-7 9-1-6-8
|
||||||
|
0x0196 5-14-1-3 6-6-1-2 7-14-3-4 8-8-4-5 9-14-6-8 10-6-7-9
|
||||||
|
0x0197 5-6-2-3 6-14-1-2 7-6-1-5 8-8-4-7 9-2-6-7 10-9-8-9
|
||||||
|
0x0198 5-14-1-3 6-6-1-2 7-6-4-5 8-4-6-7
|
||||||
|
0x0199 5-14-2-3 6-6-1-2 7-8-4-5 8-1-6-7
|
||||||
|
0x019a 5-6-3-4 6-8-1-4 7-4-2-5 8-14-6-7 9-6-1-8
|
||||||
|
0x019b 5-14-2-3 6-6-1-2 7-8-4-5 8-6-4-5 9-8-6-8 10-9-7-9
|
||||||
|
0x019e 5-14-2-3 6-14-1-5 7-6-1-2 8-8-3-7 9-14-4-8 10-6-6-9
|
||||||
|
0x019f 5-14-2-3 6-6-1-2 7-8-3-6 8-14-5-6 9-8-4-8 10-1-7-9
|
||||||
|
0x01a8 5-14-2-3 6-6-1-4 7-6-1-5 8-2-6-7
|
||||||
|
0x01a9 5-14-2-3 6-8-1-4 7-2-5-6 8-9-1-7
|
||||||
|
0x01aa 5-14-2-3 6-6-1-4 7-4-1-5 8-2-6-7
|
||||||
|
0x01ab 5-2-1-4 6-14-1-3 7-14-2-6 8-11-5-7
|
||||||
|
0x01ac 5-14-2-3 6-14-3-4 7-8-1-4 8-4-1-6 9-2-5-7 10-6-8-9
|
||||||
|
0x01ad 5-14-2-3 6-14-1-2 7-4-1-3 8-4-4-5 9-2-6-8 10-1-7-9
|
||||||
|
0x01ae 5-14-1-2 6-4-1-3 7-6-4-5 8-4-6-7
|
||||||
|
0x01af 5-14-1-2 6-4-1-3 7-8-4-5 8-1-6-7
|
||||||
|
0x01bc 5-14-2-3 6-6-2-3 7-6-1-5 8-6-4-5 9-4-6-7 10-2-8-9
|
||||||
|
0x01bd 5-6-1-3 6-14-2-3 7-8-4-6 8-6-2-3 9-2-5-8 10-1-7-9
|
||||||
|
0x01be 5-8-3-4 6-6-2-3 7-14-1-5 8-14-6-7 9-6-4-8
|
||||||
|
0x01bf 5-6-2-3 6-6-3-4 7-14-1-5 8-8-6-7 9-9-3-8
|
||||||
|
0x01e8 5-14-2-3 6-8-2-3 7-6-1-5 8-6-4-5 9-4-6-7 10-2-8-9
|
||||||
|
0x01e9 5-8-1-3 6-14-1-3 7-14-2-5 8-8-4-7 9-2-6-8 10-9-7-9
|
||||||
|
0x01ea 5-14-1-3 6-14-1-2 7-6-4-6 8-6-5-6 9-2-7-8
|
||||||
|
0x01eb 5-14-1-3 6-14-1-2 7-8-4-5 8-2-6-7 9-9-5-8
|
||||||
|
0x01ee 5-8-3-4 6-14-1-2 7-14-5-6 8-6-4-7
|
||||||
|
0x01ef 5-6-3-4 6-14-1-2 7-2-5-6 8-9-4-7
|
||||||
|
0x01fe 5-14-2-3 6-14-1-5 7-6-4-6
|
||||||
|
0x033c 5-14-3-4 6-8-3-4 7-14-2-6 8-6-5-7
|
||||||
|
0x033d 5-14-2-3 6-8-2-3 7-14-1-4 8-14-4-6 9-4-5-7 10-9-8-9
|
||||||
|
0x033f 5-6-3-4 6-14-3-4 7-4-2-5 8-13-6-7
|
||||||
|
0x0356 5-14-2-3 6-14-1-4 7-6-5-6
|
||||||
|
0x0357 5-14-1-4 6-14-2-3 7-7-5-6
|
||||||
|
0x0358 5-14-1-4 6-14-2-3 7-14-3-4 8-8-5-6 9-6-7-8
|
||||||
|
0x0359 5-6-2-4 6-14-1-4 7-4-3-5 8-9-6-7
|
||||||
|
0x035a 5-14-1-4 6-8-2-4 7-14-3-6 8-6-5-7
|
||||||
|
0x035b 5-6-1-3 6-14-2-3 7-4-4-5 8-13-6-7
|
||||||
|
0x035e 5-6-1-3 6-4-4-5 7-6-2-4 8-4-3-7 9-14-6-8
|
||||||
|
0x035f 5-14-2-3 6-8-1-3 7-8-4-5 8-1-6-7
|
||||||
|
0x0368 5-8-2-3 6-14-2-3 7-14-4-5 8-14-1-4 9-8-6-8 10-6-7-9
|
||||||
|
0x0369 5-6-1-3 6-4-4-5 7-8-3-4 8-14-2-7 9-9-6-8
|
||||||
|
0x036a 5-6-2-3 6-6-2-4 7-2-1-4 8-4-5-6 9-6-7-8
|
||||||
|
0x036b 5-14-2-3 6-8-2-3 7-6-1-6 8-4-4-7 9-13-5-8
|
||||||
|
0x036c 5-8-1-3 6-14-4-5 7-8-3-4 8-14-2-7 9-6-6-8
|
||||||
|
0x036d 5-2-1-4 6-2-2-3 7-2-2-4 8-14-5-6 9-6-3-8 10-9-7-9
|
||||||
|
0x036e 5-6-2-4 6-4-3-5 7-6-1-2 8-4-4-7 9-14-6-8
|
||||||
|
0x036f 5-8-1-3 6-6-2-5 7-4-4-6 8-14-2-3 9-11-7-8
|
||||||
|
0x037c 5-8-1-3 6-14-2-3 7-8-2-5 8-14-4-7 9-6-6-8
|
||||||
|
0x037d 5-14-2-4 6-8-2-4 7-6-3-5 8-14-1-4 9-4-7-8 10-1-6-9
|
||||||
|
0x037e 5-6-2-3 6-14-2-3 7-2-1-5 8-14-4-7 9-6-6-8
|
||||||
|
0x03c0 5-6-3-4 6-6-2-4 7-8-5-6
|
||||||
|
0x03c1 5-6-3-4 6-14-1-2 7-6-2-3 8-4-5-6 9-1-7-8
|
||||||
|
0x03c3 5-8-3-4 6-2-2-5 7-9-3-6
|
||||||
|
0x03c5 5-2-1-4 6-14-3-5 7-6-3-4 8-8-2-7 9-9-6-8
|
||||||
|
0x03c6 5-8-3-4 6-14-2-5 7-2-1-3 8-14-4-7 9-6-6-8
|
||||||
|
0x03c7 5-2-1-3 6-14-2-3 7-2-2-5 8-4-4-7 9-13-6-8
|
||||||
|
0x03cf 5-4-2-3 6-8-2-4 7-9-5-6
|
||||||
|
0x03d4 5-6-2-3 6-8-1-5 7-14-2-3 8-6-4-7 9-4-6-8
|
||||||
|
0x03d5 5-6-2-4 6-6-3-4 7-14-1-4 8-8-5-6 9-13-7-8
|
||||||
|
0x03d6 5-8-2-3 6-14-2-3 7-2-1-5 8-14-4-7 9-6-6-8
|
||||||
|
0x03d7 5-8-2-3 6-14-2-3 7-2-1-5 8-14-4-7 9-7-6-8
|
||||||
|
0x03d8 5-14-1-4 6-8-2-5 7-2-1-4 8-2-3-7 9-14-6-8 10-6-4-9
|
||||||
|
0x03d9 5-6-2-4 6-2-1-4 7-8-3-5 8-14-6-7 9-9-2-8
|
||||||
|
0x03db 5-14-1-3 6-2-1-2 7-14-2-3 8-14-4-6 9-2-5-8 10-13-7-9
|
||||||
|
0x03dc 5-2-1-4 6-2-3-5 7-14-2-6 8-6-4-7
|
||||||
|
0x03dd 5-14-1-4 6-8-3-4 7-4-2-5 8-4-6-7 9-9-4-8
|
||||||
|
0x03de 5-2-1-2 6-14-2-3 7-14-4-5 8-6-6-7
|
||||||
|
0x03fc 5-4-2-3 6-6-2-5 7-6-4-6
|
||||||
|
0x0660 5-6-3-4 6-6-1-2 7-8-5-6
|
||||||
|
0x0661 5-6-3-4 6-14-1-4 7-6-1-2 8-4-5-6 9-14-7-8 10-9-5-9
|
||||||
|
0x0662 5-6-3-4 6-14-2-3 7-6-1-2 8-4-5-6 9-2-7-8
|
||||||
|
0x0663 5-8-3-4 6-14-3-4 7-4-1-6 8-6-2-7 9-1-5-8
|
||||||
|
0x0666 5-8-3-4 6-6-1-2 7-4-5-6
|
||||||
|
0x0667 5-14-2-4 6-8-3-4 7-6-1-2 8-14-3-5 9-4-7-8 10-1-6-9
|
||||||
|
0x0669 5-7-3-4 6-1-3-4 7-9-1-6 8-6-2-7 9-2-5-8
|
||||||
|
0x066b 5-14-3-4 6-8-3-4 7-2-1-2 8-4-1-2 9-2-5-7 10-6-8-9 11-1-6-10
|
||||||
|
0x066f 5-6-3-4 6-6-1-2 7-14-3-4 8-8-5-6 9-9-7-8
|
||||||
|
0x0672 5-8-3-4 6-14-1-4 7-14-1-3 8-14-2-5 9-8-6-8 10-6-7-9
|
||||||
|
0x0673 5-6-3-4 6-6-1-2 7-14-2-4 8-8-5-6 9-13-7-8
|
||||||
|
0x0676 5-4-1-3 6-6-1-2 7-8-3-4 8-14-5-6 9-4-7-8
|
||||||
|
0x0678 5-6-2-3 6-6-1-2 7-4-3-6 8-14-5-6 9-4-4-8 10-6-7-9
|
||||||
|
0x0679 5-8-2-3 6-6-1-2 7-4-3-6 8-2-5-6 9-14-4-8 10-9-7-9
|
||||||
|
0x067a 5-6-1-3 6-6-3-4 7-6-1-2 8-4-4-5 9-8-6-7 10-14-8-9
|
||||||
|
0x067b 5-2-1-4 6-6-3-5 7-2-2-6 8-2-1-3 9-2-4-8 10-9-7-9
|
||||||
|
0x067e 5-6-2-3 6-8-3-4 7-6-1-2 8-4-4-5 9-4-6-7 10-14-8-9
|
||||||
|
0x0690 5-6-2-4 6-6-3-4 7-6-1-5 8-2-6-7
|
||||||
|
0x0691 5-14-1-4 6-4-3-5 7-6-1-2 8-6-4-7 9-6-6-7 10-1-8-9
|
||||||
|
0x0693 5-4-1-4 6-8-1-3 7-6-5-6 8-6-2-7 9-8-3-4 10-1-8-9
|
||||||
|
0x0696 5-6-1-2 6-2-4-5 7-2-3-6 8-6-5-7
|
||||||
|
0x0697 5-2-2-3 6-6-1-2 7-14-4-5 8-6-3-7 9-8-6-8 10-9-7-9
|
||||||
|
0x069f 5-6-3-4 6-6-1-2 7-8-5-6 8-9-4-7
|
||||||
|
0x06b0 5-2-1-4 6-6-3-4 7-2-2-5 8-14-1-3 9-6-7-8 10-8-6-9
|
||||||
|
0x06b1 5-6-1-3 6-8-2-5 7-14-1-2 8-4-3-7 9-6-4-8 10-1-6-9
|
||||||
|
0x06b2 5-6-2-4 6-6-1-5 7-14-3-6 8-8-5-6 9-14-4-8 10-6-7-9
|
||||||
|
0x06b3 5-2-1-3 6-2-4-5 7-14-1-4 8-8-3-7 9-2-2-8 10-9-6-9
|
||||||
|
0x06b4 5-14-2-4 6-8-1-5 7-6-2-6 8-2-4-7 9-2-3-8 10-6-7-9
|
||||||
|
0x06b5 5-2-1-3 6-2-2-3 7-4-1-2 8-14-4-7 9-4-6-8 10-9-5-9
|
||||||
|
0x06b6 5-13-3-4 6-6-1-2 7-4-1-2 8-4-3-6 9-1-5-7 10-14-8-9
|
||||||
|
0x06b7 5-2-1-3 6-2-2-3 7-4-1-2 8-14-4-7 9-4-5-8 10-9-6-9
|
||||||
|
0x06b9 5-6-1-2 6-14-1-4 7-8-3-6 8-2-5-7 9-9-4-8
|
||||||
|
0x06bd 5-4-1-2 6-14-4-5 7-6-1-2 8-4-3-7 9-9-6-8
|
||||||
|
0x06f0 5-6-1-2 6-6-3-4 7-14-3-5 8-8-6-7
|
||||||
|
0x06f1 5-2-1-4 6-6-1-2 7-14-5-6 8-4-3-7 9-9-4-8
|
||||||
|
0x06f2 5-2-3-4 6-14-1-4 7-8-2-6 8-6-1-7 9-4-3-8 10-14-5-9
|
||||||
|
0x06f6 5-2-3-4 6-6-1-2 7-4-3-6 8-14-5-7
|
||||||
|
0x06f9 5-6-1-2 6-4-3-5 7-9-4-6
|
||||||
|
0x0776 5-6-3-4 6-14-1-2 7-8-1-2 8-4-4-6 9-14-5-8 10-4-7-9
|
||||||
|
0x0778 5-8-3-4 6-8-1-2 7-14-3-4 8-14-5-6 9-6-7-8
|
||||||
|
0x0779 5-14-3-4 6-8-1-2 7-6-5-6 8-8-3-4 9-14-1-2 10-4-7-9 11-1-8-10
|
||||||
|
0x077a 5-14-3-4 6-8-3-4 7-6-1-5 8-2-1-2 9-14-7-8 10-4-6-9
|
||||||
|
0x077e 5-14-3-4 6-8-3-4 7-6-1-2 8-6-2-5 9-14-7-8 10-4-6-9
|
||||||
|
0x07b0 5-6-1-4 6-2-2-5 7-6-3-4 8-4-6-7
|
||||||
|
0x07b1 5-6-1-4 6-14-1-4 7-6-3-4 8-2-2-5 9-2-6-7 10-1-8-9
|
||||||
|
0x07b4 5-2-2-3 6-4-1-2 7-2-4-5 8-14-6-7 9-6-3-8
|
||||||
|
0x07b5 5-14-3-4 6-6-1-3 7-8-3-4 8-4-2-5 9-2-6-8 10-1-7-9
|
||||||
|
0x07b6 5-4-1-2 6-14-4-5 7-6-2-4 8-2-1-7 9-14-3-8 10-6-6-9
|
||||||
|
0x07bc 5-8-1-2 6-14-3-5 7-4-1-2 8-14-4-7 9-6-6-8
|
||||||
|
0x07e0 5-6-2-4 6-6-1-2 7-6-3-4 8-14-5-6 9-8-7-8
|
||||||
|
0x07e1 5-14-1-2 6-8-1-2 7-4-4-5 8-2-6-7 9-14-3-8 10-9-7-9
|
||||||
|
0x07e2 5-6-2-4 6-2-1-5 7-14-2-4 8-8-3-7 9-14-6-8 10-6-4-9
|
||||||
|
0x07e3 5-4-1-4 6-2-2-5 7-6-4-6 8-2-1-7 9-2-3-8 10-9-6-9
|
||||||
|
0x07e6 5-8-1-2 6-14-3-5 7-14-1-2 8-6-3-7 9-14-4-8 10-6-6-9
|
||||||
|
0x07e9 5-8-1-2 6-14-3-5 7-14-1-2 8-4-4-7 9-9-6-8
|
||||||
|
0x07f0 5-2-1-3 6-8-2-5 7-2-4-6 8-6-3-7
|
||||||
|
0x07f1 5-6-1-4 6-6-1-2 7-14-5-6 8-4-3-7 9-9-4-8
|
||||||
|
0x07f2 5-6-2-4 6-2-1-5 7-14-3-6 8-6-4-7
|
||||||
|
0x07f8 5-8-1-2 6-14-3-5 7-6-4-6
|
||||||
|
0x0ff0 5-6-2-4 6-6-2-3 7-6-5-6
|
||||||
|
0x1668 5-6-2-3 6-6-1-2 7-6-1-4 8-14-5-6 9-4-7-8 10-6-5-9
|
||||||
|
0x1669 5-8-2-4 6-8-3-5 7-2-1-6 8-6-4-7 9-6-2-8 10-9-3-9
|
||||||
|
0x166a 5-8-2-3 6-8-4-5 7-14-1-6 8-6-2-3 9-8-4-8 10-6-5-9 11-6-7-10
|
||||||
|
0x166b 5-6-2-3 6-6-3-4 7-6-1-2 8-2-1-5 9-14-6-8 10-9-7-9
|
||||||
|
0x166e 5-6-3-4 6-6-1-2 7-8-3-4 8-2-2-5 9-14-6-8 10-6-7-9
|
||||||
|
0x167e 5-6-1-3 6-6-2-5 7-2-4-6 8-6-2-3 9-14-5-8 10-4-7-9
|
||||||
|
0x1681 5-6-1-3 6-2-2-4 7-8-1-3 8-4-2-4 9-14-5-6 10-14-7-8 11-9-9-10
|
||||||
|
0x1683 5-6-1-4 6-6-2-3 7-4-1-4 8-2-3-5 9-14-6-8 10-9-7-9
|
||||||
|
0x1686 5-6-2-4 6-6-1-2 7-2-3-5 8-14-6-7 9-6-3-8
|
||||||
|
0x1687 5-6-2-4 6-4-3-4 7-6-1-2 8-14-5-6 9-4-7-8 10-9-3-9
|
||||||
|
0x1689 5-6-1-4 6-2-3-5 7-8-3-4 8-6-2-7 9-14-6-8 10-9-5-9
|
||||||
|
0x168b 5-8-2-3 6-2-1-4 7-4-1-4 8-2-2-6 9-14-5-7 10-6-3-9 11-9-8-10
|
||||||
|
0x168e 5-6-1-2 6-2-2-5 7-2-3-6 8-14-2-3 9-4-4-8 10-14-5-9 11-6-7-10
|
||||||
|
0x1696 5-8-2-3 6-6-2-3 7-8-4-5 8-2-1-7 9-6-6-8
|
||||||
|
0x1697 5-6-3-4 6-6-2-3 7-6-1-3 8-14-5-6 9-4-7-8 10-9-2-9
|
||||||
|
0x1698 5-14-1-2 6-8-1-2 7-4-4-5 8-2-3-7 9-2-5-7 10-14-6-8 11-6-9-10
|
||||||
|
0x1699 5-8-1-2 6-2-3-5 7-2-4-6 8-6-2-7 9-9-1-8
|
||||||
|
0x169a 5-8-2-4 6-8-3-5 7-14-1-6 8-4-2-3 9-6-5-8 10-6-7-9
|
||||||
|
0x169b 5-6-3-4 6-2-1-5 7-14-2-6 8-6-4-7 9-8-3-4 10-14-1-9 11-9-8-10
|
||||||
|
0x169e 5-6-3-4 6-6-1-2 7-2-1-5 8-14-6-7 9-6-3-8
|
||||||
|
0x16a9 5-8-3-4 6-8-2-5 7-14-1-6 8-14-2-3 9-6-7-8 10-9-4-9
|
||||||
|
0x16ac 5-8-1-3 6-14-2-5 7-4-1-6 8-14-4-7 9-14-1-3 10-8-8-9 11-6-6-10
|
||||||
|
0x16ad 5-8-2-4 6-14-1-5 7-8-1-2 8-14-3-7 9-6-4-8 10-9-6-9
|
||||||
|
0x16bc 5-8-1-3 6-8-1-4 7-2-2-5 8-6-3-7 9-6-6-8
|
||||||
|
0x16e9 5-14-2-3 6-8-2-3 7-14-1-6 8-6-4-7 9-9-5-8
|
||||||
|
0x177e 5-6-3-4 6-6-1-2 7-8-3-4 8-6-2-5 9-14-6-8 10-6-7-9
|
||||||
|
0x178e 5-6-2-4 6-6-1-2 7-6-3-5 8-2-6-7 9-6-5-8
|
||||||
|
0x1796 5-6-2-3 6-6-1-2 7-2-4-5 8-14-6-7 9-6-3-8
|
||||||
|
0x1798 5-8-1-2 6-14-1-2 7-6-4-6 8-2-3-7 9-14-5-8 10-6-4-9
|
||||||
|
0x179a 5-4-3-4 6-8-1-4 7-4-2-3 8-14-1-5 9-8-2-6 10-2-8-9 11-6-7-10
|
||||||
|
0x17ac 5-8-1-3 6-14-2-5 7-6-3-4 8-4-1-7 9-2-6-8 10-6-4-9
|
||||||
|
0x17e8 5-6-2-3 6-14-2-3 7-4-1-5 8-6-6-7 9-6-4-8
|
||||||
|
0x18e7 5-6-2-3 6-6-1-3 7-8-5-6 8-9-4-7
|
||||||
|
0x19e1 5-6-3-4 6-8-1-2 7-14-1-2 8-14-3-6 9-8-5-8 10-9-7-9
|
||||||
|
0x19e3 5-8-2-3 6-14-3-4 7-2-1-5 8-2-6-7 9-6-2-8 10-9-4-9
|
||||||
|
0x19e6 5-8-2-3 6-6-2-4 7-2-1-5 8-6-6-7
|
||||||
|
0x1bd8 5-6-2-3 6-6-1-3 7-6-1-4 8-4-5-7 9-6-6-8
|
||||||
|
0x1be4 5-2-1-3 6-1-1-2 7-1-5-6 8-6-4-7
|
||||||
|
0x1ee1 5-14-1-2 6-6-4-5 7-9-3-6
|
||||||
|
0x3cc3 5-6-1-4 6-6-1-3 7-6-2-5 8-9-6-7
|
||||||
|
0x6996 5-6-1-4 6-6-2-5 7-6-3-6
|
|
@ -0,0 +1,222 @@
|
||||||
|
0x0000 5-2-3-4 6-2-3-4 7-2-5-6
|
||||||
|
0x0001 5-14-1-3 6-1-2-4 7-4-5-6
|
||||||
|
0x0003 5-12-2-4 6-1-3-5 7-12-2-6
|
||||||
|
0x0006 5-14-3-4 6-6-1-2 7-4-5-6
|
||||||
|
0x0007 5-14-3-4 6-7-1-2 7-4-5-6
|
||||||
|
0x000f 5-3-2-4 6-13-3-4 7-10-5-6
|
||||||
|
0x0016 5-6-1-3 6-7-1-2 7-9-2-5 8-1-4-7 9-8-6-8
|
||||||
|
0x0017 5-9-1-2 6-7-1-2 7-2-3-5 8-1-4-7 9-8-6-8
|
||||||
|
0x0018 5-9-1-3 6-9-1-2 7-1-4-5 8-8-6-7
|
||||||
|
0x0019 5-8-2-3 6-9-1-2 7-1-4-5 8-8-6-7
|
||||||
|
0x001b 5-8-1-3 6-11-1-2 7-1-4-5 8-8-6-7
|
||||||
|
0x001e 5-14-1-2 6-6-3-5 7-4-4-6
|
||||||
|
0x001f 5-14-1-2 6-7-3-5 7-4-4-6
|
||||||
|
0x003c 5-10-3-4 6-3-2-5 7-9-4-6
|
||||||
|
0x003d 5-6-2-3 6-1-1-3 7-1-5-6 8-1-4-7
|
||||||
|
0x003f 5-10-3-4 6-3-2-5 7-13-4-6
|
||||||
|
0x0069 5-9-2-3 6-6-1-5 7-4-4-6
|
||||||
|
0x006b 5-9-1-3 6-2-1-2 7-6-2-5 8-1-6-7 9-1-4-8
|
||||||
|
0x006f 5-9-1-2 6-7-3-5 7-4-4-6
|
||||||
|
0x007e 5-6-1-3 6-6-2-3 7-1-5-6 8-1-4-7
|
||||||
|
0x007f 5-8-2-3 6-7-1-5 7-4-4-6
|
||||||
|
0x00ff 5-1-1-3 6-1-1-2 7-1-5-6 8-5-4-7
|
||||||
|
0x0116 5-1-3-4 6-7-1-2 7-6-2-5 8-6-1-7 9-7-3-4 10-7-6-9 11-1-8-10
|
||||||
|
0x0117 5-6-1-4 6-7-2-3 7-4-3-5 8-4-2-7 9-1-1-4 10-7-6-9 11-9-8-10
|
||||||
|
0x0118 5-7-3-4 6-1-3-4 7-9-1-2 8-6-2-6 9-7-5-7 10-1-8-9
|
||||||
|
0x0119 5-1-3-4 6-7-3-4 7-9-1-2 8-2-1-5 9-7-6-7 10-1-8-9
|
||||||
|
0x011a 5-7-3-4 6-1-3-4 7-11-1-2 8-6-1-6 9-7-5-7 10-1-8-9
|
||||||
|
0x011b 5-1-3-4 6-11-1-2 7-7-3-4 8-2-1-5 9-7-6-7 10-1-8-9
|
||||||
|
0x011e 5-7-3-4 6-1-1-2 7-1-3-4 8-7-5-6 9-9-7-8
|
||||||
|
0x011f 5-7-3-4 6-1-1-2 7-1-3-4 8-7-5-6 9-11-7-8
|
||||||
|
0x012c 5-6-3-4 6-6-2-5 7-14-1-2 8-6-4-7 9-8-6-8
|
||||||
|
0x012d 5-1-2-3 6-13-4-5 7-13-1-2 8-6-3-7 9-8-6-8
|
||||||
|
0x012f 5-1-1-2 6-13-4-5 7-13-1-2 8-7-3-7 9-8-6-8
|
||||||
|
0x013c 5-1-1-2 6-1-2-4 7-13-4-5 8-4-3-7 9-6-6-8
|
||||||
|
0x013d 5-1-1-2 6-1-2-4 7-9-4-5 8-4-3-7 9-6-6-8
|
||||||
|
0x013e 5-9-2-3 6-7-2-3 7-4-1-5 8-6-4-7 9-2-6-8
|
||||||
|
0x013f 5-1-1-3 6-7-2-3 7-11-2-5 8-7-4-7 9-8-6-8
|
||||||
|
0x0168 5-6-1-3 6-9-2-5 7-14-1-3 8-6-4-7 9-8-6-8
|
||||||
|
0x0169 5-1-2-3 6-13-4-5 7-9-1-2 8-6-3-7 9-8-6-8
|
||||||
|
0x016a 5-1-2-3 6-6-1-4 7-7-2-3 8-2-4-5 9-6-6-7 10-1-8-9
|
||||||
|
0x016b 5-1-2-3 6-4-1-5 7-7-2-3 8-9-1-7 9-4-4-8 10-6-6-9
|
||||||
|
0x016e 5-1-1-2 6-9-4-5 7-9-1-2 8-7-3-7 9-8-6-8
|
||||||
|
0x016f 5-1-1-2 6-13-4-5 7-9-1-2 8-7-3-7 9-8-6-8
|
||||||
|
0x017e 5-7-1-4 6-6-2-3 7-6-1-3 8-1-6-7 9-7-5-8 10-6-4-9
|
||||||
|
0x017f 5-1-1-3 6-4-2-5 7-7-2-3 8-13-1-7 9-4-4-8 10-14-6-9
|
||||||
|
0x0180 5-2-3-4 6-6-1-2 7-6-3-4 8-6-2-5 9-4-6-7 10-4-8-9
|
||||||
|
0x0181 5-8-2-4 6-9-1-3 7-6-1-2 8-4-5-6 9-4-7-8
|
||||||
|
0x0182 5-6-1-4 6-4-1-2 7-9-2-3 8-7-5-7 9-1-6-8
|
||||||
|
0x0183 5-9-2-4 6-6-2-3 7-2-1-5 8-6-3-7 9-1-6-8
|
||||||
|
0x0186 5-7-1-2 6-9-3-5 7-14-1-2 8-6-4-7 9-4-6-8
|
||||||
|
0x0187 5-1-1-2 6-13-4-5 7-8-1-2 8-6-3-7 9-2-6-8
|
||||||
|
0x0189 5-8-1-4 6-4-1-3 7-2-2-5 8-1-6-7 9-6-1-8
|
||||||
|
0x018b 5-11-2-3 6-7-1-4 7-4-1-2 8-7-5-6 9-1-7-8
|
||||||
|
0x018f 5-7-1-2 6-7-3-5 7-14-1-2 8-7-4-7 9-8-6-8
|
||||||
|
0x0196 5-1-2-3 6-6-1-2 7-9-3-4 8-2-4-5 9-6-6-7 10-1-8-9
|
||||||
|
0x0197 5-1-1-3 6-6-2-3 7-6-4-5 8-14-6-7 9-1-1-4 10-9-8-9
|
||||||
|
0x0198 5-14-1-3 6-6-1-2 7-6-4-5 8-4-6-7
|
||||||
|
0x0199 5-14-2-3 6-6-1-2 7-7-4-5 8-4-6-7
|
||||||
|
0x019a 5-6-3-4 6-7-1-4 7-11-2-5 8-9-1-7 9-8-6-8
|
||||||
|
0x019b 5-6-2-4 6-6-1-4 7-11-2-3 8-1-1-5 9-7-6-7 10-9-8-9
|
||||||
|
0x019e 5-1-1-3 6-4-2-5 7-6-1-2 8-8-3-7 9-1-4-8 10-6-6-9
|
||||||
|
0x019f 5-1-2-3 6-6-1-2 7-9-3-4 8-2-4-5 9-2-6-7 10-1-8-9
|
||||||
|
0x01a8 5-14-2-3 6-9-1-4 7-6-4-5 8-4-6-7
|
||||||
|
0x01a9 5-14-2-3 6-7-1-4 7-6-1-5 8-2-6-7
|
||||||
|
0x01aa 5-14-2-3 6-9-1-4 7-7-4-5 8-4-6-7
|
||||||
|
0x01ab 5-14-1-3 6-2-1-4 7-1-2-5 8-6-6-7
|
||||||
|
0x01ac 5-4-1-3 6-7-1-4 7-1-2-3 8-1-4-5 9-7-6-7 10-9-8-9
|
||||||
|
0x01ad 5-4-1-3 6-6-1-4 7-1-2-3 8-1-4-5 9-7-6-7 10-9-8-9
|
||||||
|
0x01ae 5-14-1-2 6-11-1-3 7-6-4-5 8-8-6-7
|
||||||
|
0x01af 5-14-1-2 6-11-1-3 7-7-4-5 8-8-6-7
|
||||||
|
0x01bc 5-1-2-3 6-6-2-3 7-6-4-5 8-9-1-4 9-4-6-8 10-1-7-9
|
||||||
|
0x01bd 5-14-2-3 6-6-1-2 7-6-1-3 8-8-4-5 9-8-6-7 10-1-8-9
|
||||||
|
0x01be 5-6-2-3 6-7-2-4 7-14-1-5 8-6-4-7 9-8-6-8
|
||||||
|
0x01bf 5-6-3-4 6-9-2-3 7-4-1-5 8-7-6-7 9-6-4-8
|
||||||
|
0x01e8 5-1-2-3 6-6-1-4 7-7-2-3 8-6-4-5 9-4-6-7 10-1-8-9
|
||||||
|
0x01e9 5-14-2-3 6-8-2-3 7-6-1-5 8-8-4-5 9-4-6-7 10-1-8-9
|
||||||
|
0x01ea 5-1-1-3 6-9-4-5 7-9-2-3 8-1-1-7 9-2-6-8
|
||||||
|
0x01eb 5-9-2-3 6-1-1-5 7-14-1-2 8-7-4-7 9-4-6-8
|
||||||
|
0x01ee 5-14-1-2 6-7-3-4 7-6-4-5 8-8-6-7
|
||||||
|
0x01ef 5-9-3-4 6-1-1-2 7-1-5-6 8-9-3-7
|
||||||
|
0x01fe 5-14-2-3 6-1-1-5 7-9-4-6
|
||||||
|
0x033c 5-8-2-3 6-6-2-3 7-2-4-5 8-6-6-7
|
||||||
|
0x033d 5-6-2-3 6-13-1-4 7-1-2-3 8-4-4-5 9-7-6-7 10-9-8-9
|
||||||
|
0x033f 5-6-3-4 6-14-3-4 7-4-2-5 8-13-6-7
|
||||||
|
0x0356 5-14-1-4 6-1-2-3 7-9-5-6
|
||||||
|
0x0357 5-14-1-4 6-1-2-3 7-13-5-6
|
||||||
|
0x0358 5-1-2-3 6-1-1-4 7-1-3-4 8-1-5-6 9-9-7-8
|
||||||
|
0x0359 5-9-1-3 6-1-2-3 7-1-4-5 8-6-6-7
|
||||||
|
0x035a 5-8-2-4 6-1-1-4 7-1-3-5 8-6-6-7
|
||||||
|
0x035b 5-9-1-3 6-1-2-3 7-1-4-5 8-14-6-7
|
||||||
|
0x035e 5-13-1-4 6-13-2-3 7-6-3-4 8-7-5-6 9-6-7-8
|
||||||
|
0x035f 5-8-2-4 6-1-1-4 7-1-3-5 8-14-6-7
|
||||||
|
0x0368 5-1-2-3 6-9-2-3 7-13-1-4 8-6-4-5 9-9-6-7 10-4-8-9
|
||||||
|
0x0369 5-9-2-3 6-13-1-4 7-7-2-4 8-9-5-6 9-8-7-8
|
||||||
|
0x036a 5-6-2-3 6-1-2-3 7-9-1-5 8-4-4-7 9-6-6-8
|
||||||
|
0x036b 5-6-1-3 6-1-2-3 7-9-2-5 8-4-4-7 9-14-6-8
|
||||||
|
0x036c 5-6-2-4 6-7-1-3 7-7-3-4 8-6-5-6 9-2-7-8
|
||||||
|
0x036d 5-2-2-4 6-13-1-4 7-13-2-3 8-6-3-5 9-7-6-7 10-9-8-9
|
||||||
|
0x036e 5-6-2-4 6-4-3-5 7-9-1-2 8-1-4-7 9-14-6-8
|
||||||
|
0x036f 5-7-1-3 6-1-2-3 7-9-2-5 8-4-4-7 9-6-6-8
|
||||||
|
0x037c 5-7-2-3 6-1-2-3 7-13-1-5 8-4-4-7 9-6-6-8
|
||||||
|
0x037d 5-1-2-3 6-13-1-4 7-6-2-3 8-2-4-5 9-1-6-7 10-1-8-9
|
||||||
|
0x037e 5-6-2-3 6-1-2-3 7-13-1-5 8-4-4-7 9-6-6-8
|
||||||
|
0x03c0 5-6-3-4 6-6-2-4 7-8-5-6
|
||||||
|
0x03c1 5-6-2-3 6-6-3-4 7-1-1-2 8-1-6-7 9-1-5-8
|
||||||
|
0x03c3 5-1-1-3 6-8-2-4 7-1-5-6 8-7-3-7 9-6-2-8
|
||||||
|
0x03c5 5-2-1-3 6-1-2-3 7-9-2-5 8-1-4-7 9-6-6-8
|
||||||
|
0x03c6 5-1-1-4 6-7-2-4 7-14-3-5 8-6-2-7 9-2-6-8
|
||||||
|
0x03c7 5-11-1-2 6-8-2-4 7-4-3-5 8-1-6-7 9-9-2-8
|
||||||
|
0x03cf 5-12-1-4 6-9-3-4 7-1-2-6 8-6-5-7 9-3-1-8
|
||||||
|
0x03d4 5-6-2-3 6-1-2-3 7-8-1-5 8-1-4-7 9-6-6-8
|
||||||
|
0x03d5 5-9-2-3 6-6-3-4 7-8-5-6 8-1-1-4 9-14-7-8
|
||||||
|
0x03d6 5-7-2-3 6-1-2-3 7-8-1-5 8-1-4-7 9-6-6-8
|
||||||
|
0x03d7 5-1-1-4 6-7-2-4 7-9-2-3 8-1-5-7 9-2-6-8
|
||||||
|
0x03d8 5-7-3-4 6-4-2-5 7-9-2-3 8-14-1-7 9-4-4-8 10-6-6-9
|
||||||
|
0x03d9 5-6-2-4 6-13-1-4 7-7-3-5 8-7-6-7 9-9-2-8
|
||||||
|
0x03db 5-6-2-4 6-2-1-4 7-2-3-5 8-9-2-3 9-1-6-8 10-9-7-9
|
||||||
|
0x03dc 5-13-1-4 6-8-3-5 7-1-2-6 8-9-4-7
|
||||||
|
0x03dd 5-14-1-4 6-7-3-4 7-4-2-5 8-7-6-7 9-6-4-8
|
||||||
|
0x03de 5-13-1-2 6-1-2-3 7-4-4-5 8-6-6-7
|
||||||
|
0x03fc 5-1-2-3 6-9-4-5 7-3-1-6 8-3-6-7
|
||||||
|
0x0660 5-9-3-4 6-6-1-2 7-4-5-6
|
||||||
|
0x0661 5-6-3-4 6-14-1-4 7-6-1-2 8-4-5-6 9-14-7-8 10-9-5-9
|
||||||
|
0x0662 5-6-3-4 6-1-2-4 7-14-5-6 8-6-1-2 9-8-7-8
|
||||||
|
0x0663 5-9-3-4 6-7-3-4 7-14-1-5 8-9-2-7 9-2-6-8
|
||||||
|
0x0666 5-8-3-4 6-6-1-2 7-4-5-6
|
||||||
|
0x0667 5-1-3-4 6-7-3-4 7-6-1-2 8-4-1-5 9-7-6-7 10-11-8-9
|
||||||
|
0x0669 5-7-3-4 6-6-1-2 7-1-3-4 8-7-5-6 9-9-7-8
|
||||||
|
0x066b 5-6-3-4 6-6-1-2 7-4-1-2 8-14-3-4 9-8-5-6 10-14-7-8 11-9-9-10
|
||||||
|
0x066f 5-7-3-4 6-6-1-2 7-1-3-4 8-7-5-6 9-11-7-8
|
||||||
|
0x0672 5-7-3-4 6-4-2-5 7-2-2-4 8-9-3-7 9-4-1-8 10-6-6-9
|
||||||
|
0x0673 5-6-3-4 6-6-1-2 7-1-2-4 8-7-5-6 9-11-7-8
|
||||||
|
0x0676 5-4-2-3 6-1-1-5 7-9-2-6 8-7-3-4 9-8-7-8
|
||||||
|
0x0678 5-6-1-2 6-7-1-2 7-9-3-4 8-2-4-5 9-6-6-7 10-4-8-9
|
||||||
|
0x0679 5-2-1-4 6-13-1-3 7-2-3-5 8-13-2-7 9-9-6-8 10-6-4-9
|
||||||
|
0x067a 5-6-1-3 6-6-1-2 7-6-3-4 8-4-4-5 9-7-6-7 10-11-8-9
|
||||||
|
0x067b 5-6-1-3 6-2-2-5 7-9-2-3 8-7-1-7 9-7-4-8 10-6-6-9
|
||||||
|
0x067e 5-6-2-3 6-7-3-4 7-6-1-2 8-4-4-5 9-7-6-7 10-11-8-9
|
||||||
|
0x0690 5-9-1-3 6-6-3-4 7-6-2-5 8-2-6-7
|
||||||
|
0x0691 5-6-1-4 6-1-1-2 7-6-2-5 8-9-3-4 9-4-6-8 10-1-7-9
|
||||||
|
0x0693 5-1-3-4 6-8-3-4 7-14-1-5 8-6-2-7 9-1-6-8 10-9-3-9
|
||||||
|
0x0696 5-9-2-3 6-7-3-4 7-6-1-5 8-2-6-7
|
||||||
|
0x0697 5-9-3-4 6-6-1-2 7-2-1-3 8-13-5-7 9-4-6-8 10-9-3-9
|
||||||
|
0x069f 5-9-3-4 6-6-1-2 7-1-5-6 8-9-3-7
|
||||||
|
0x06b0 5-1-2-4 6-2-1-5 7-6-4-6 8-9-2-7 9-6-3-4 10-8-8-9
|
||||||
|
0x06b1 5-6-1-4 6-2-2-5 7-1-1-2 8-14-3-7 9-6-4-8 10-4-6-9
|
||||||
|
0x06b2 5-2-2-4 6-9-1-2 7-6-3-5 8-14-6-7 9-2-3-4 10-9-8-9
|
||||||
|
0x06b3 5-2-1-3 6-2-4-5 7-1-1-4 8-2-3-7 9-13-2-8 10-6-6-9
|
||||||
|
0x06b4 5-1-2-4 6-8-3-4 7-2-1-5 8-6-2-7 9-1-6-8 10-9-3-9
|
||||||
|
0x06b5 5-6-3-4 6-8-1-3 7-8-2-5 8-9-1-7 9-1-6-8 10-9-4-9
|
||||||
|
0x06b6 5-2-1-2 6-11-1-2 7-7-3-4 8-1-3-5 9-7-6-7 10-9-8-9
|
||||||
|
0x06b7 5-6-1-3 6-7-2-5 7-9-1-2 8-14-3-7 9-7-4-8 10-8-6-9
|
||||||
|
0x06b9 5-1-1-4 6-6-1-2 7-13-3-5 8-7-6-7 9-6-4-8
|
||||||
|
0x06bd 5-2-2-4 6-6-1-2 7-9-3-5 8-7-6-7 9-6-4-8
|
||||||
|
0x06f0 5-9-1-2 6-6-3-4 7-4-3-5 8-2-6-7
|
||||||
|
0x06f1 5-13-1-4 6-9-1-2 7-8-5-6 8-1-3-7 9-9-4-8
|
||||||
|
0x06f2 5-1-1-4 6-9-1-4 7-2-2-5 8-9-6-7 9-1-3-8 10-9-4-9
|
||||||
|
0x06f6 5-9-1-2 6-2-3-4 7-1-3-5 8-6-6-7
|
||||||
|
0x06f9 5-9-1-2 6-1-3-5 7-9-4-6
|
||||||
|
0x0776 5-6-3-4 6-7-3-4 7-6-1-2 8-4-1-5 9-7-6-7 10-11-8-9
|
||||||
|
0x0778 5-7-3-4 6-7-1-2 7-1-3-4 8-7-5-6 9-9-7-8
|
||||||
|
0x0779 5-2-1-3 6-6-3-4 7-6-2-5 8-1-4-7 9-7-1-2 10-7-6-9 11-11-8-10
|
||||||
|
0x077a 5-2-1-3 6-6-3-4 7-7-1-2 8-4-4-5 9-7-6-7 10-9-8-9
|
||||||
|
0x077e 5-6-2-4 6-6-1-2 7-6-3-5 8-14-6-7 9-7-3-4 10-8-8-9
|
||||||
|
0x07b0 5-9-1-4 6-6-3-4 7-7-2-5 8-8-6-7
|
||||||
|
0x07b1 5-1-1-3 6-1-4-5 7-6-3-6 8-6-1-4 9-2-2-8 10-1-7-9
|
||||||
|
0x07b4 5-2-2-3 6-11-1-2 7-13-4-5 8-7-6-7 9-6-3-8
|
||||||
|
0x07b5 5-13-2-3 6-7-4-5 7-4-2-3 8-14-1-7 9-7-6-8 10-6-3-9
|
||||||
|
0x07b6 5-4-1-2 6-1-4-5 7-9-2-4 8-8-1-7 9-1-3-8 10-6-6-9
|
||||||
|
0x07bc 5-6-3-4 6-7-1-2 7-2-2-4 8-7-5-6 9-9-7-8
|
||||||
|
0x07e0 5-6-1-4 6-9-2-3 7-6-3-4 8-1-5-6 9-2-7-8
|
||||||
|
0x07e1 5-2-2-3 6-14-1-2 7-7-1-5 8-7-4-7 9-7-6-8 10-6-3-9
|
||||||
|
0x07e2 5-9-2-4 6-8-1-5 7-1-2-4 8-2-3-7 9-1-6-8 10-9-4-9
|
||||||
|
0x07e3 5-4-1-4 6-2-2-5 7-9-2-4 8-7-1-7 9-7-3-8 10-6-6-9
|
||||||
|
0x07e6 5-1-1-2 6-1-4-5 7-7-1-2 8-6-4-7 9-1-3-8 10-6-6-9
|
||||||
|
0x07e9 5-1-1-2 6-1-4-5 7-8-1-2 8-1-3-7 9-6-6-8
|
||||||
|
0x07f0 5-8-2-4 6-6-3-4 7-7-1-5 8-8-6-7
|
||||||
|
0x07f1 5-9-2-4 6-9-1-4 7-8-5-6 8-1-3-7 9-9-4-8
|
||||||
|
0x07f2 5-9-2-4 6-8-1-5 7-1-3-6 8-9-4-7
|
||||||
|
0x07f8 5-8-1-2 6-1-3-5 7-9-4-6
|
||||||
|
0x0ff0 5-1-1-3 6-1-2-5 7-5-3-6 8-9-4-7
|
||||||
|
0x1668 5-6-2-3 6-6-1-2 7-6-1-4 8-14-5-6 9-4-7-8 10-6-5-9
|
||||||
|
0x1669 5-7-2-3 6-9-1-3 7-9-2-4 8-2-1-5 9-9-6-7 10-4-8-9
|
||||||
|
0x166a 5-4-1-4 6-6-2-4 7-6-2-3 8-6-1-4 9-14-5-6 10-4-7-9 11-6-8-10
|
||||||
|
0x166b 5-6-3-4 6-6-2-3 7-2-1-5 8-14-6-7 9-6-1-4 10-9-8-9
|
||||||
|
0x166e 5-6-3-4 6-8-3-4 7-2-1-5 8-13-2-7 9-6-6-8 10-9-1-9
|
||||||
|
0x167e 5-6-1-3 6-6-2-5 7-2-4-6 8-6-2-3 9-14-5-8 10-4-7-9
|
||||||
|
0x1681 5-4-1-4 6-9-1-4 7-6-2-5 8-6-3-7 9-1-2-3 10-6-6-9 11-1-8-10
|
||||||
|
0x1683 5-6-1-4 6-9-2-3 7-11-1-4 8-2-2-5 9-9-6-7 10-4-8-9
|
||||||
|
0x1686 5-9-1-4 6-9-1-2 7-7-3-5 8-7-6-7 9-6-3-8
|
||||||
|
0x1687 5-6-1-2 6-4-3-4 7-6-1-4 8-1-6-7 9-1-5-8 10-9-3-9
|
||||||
|
0x1689 5-6-2-4 6-9-1-4 7-1-2-3 8-2-3-5 9-6-6-7 10-1-8-9
|
||||||
|
0x168b 5-14-1-3 6-6-1-2 7-6-1-4 8-14-2-3 9-8-5-6 10-2-7-9 11-9-8-10
|
||||||
|
0x168e 5-6-2-4 6-6-1-4 7-14-1-3 8-14-2-3 9-8-5-6 10-2-7-9 11-6-8-10
|
||||||
|
0x1696 5-7-1-4 6-6-1-2 7-13-2-5 8-7-3-7 9-9-6-8
|
||||||
|
0x1697 5-6-2-4 6-6-1-2 7-6-1-3 8-1-5-6 9-1-7-8 10-9-2-9
|
||||||
|
0x1698 5-4-3-4 6-6-1-2 7-8-1-4 8-14-2-3 9-6-5-6 10-6-7-8 11-4-9-10
|
||||||
|
0x1699 5-7-1-2 6-6-1-2 7-8-3-5 8-2-4-7 9-9-6-8
|
||||||
|
0x169a 5-4-2-3 6-4-1-3 7-7-2-4 8-6-1-5 9-1-6-7 10-6-8-9
|
||||||
|
0x169b 5-4-3-4 6-8-2-4 7-2-1-3 8-6-2-5 9-2-1-6 10-14-7-8 11-9-9-10
|
||||||
|
0x169e 5-9-3-4 6-6-1-3 7-8-1-5 8-13-2-7 9-9-6-8
|
||||||
|
0x16a9 5-7-2-3 6-9-1-4 7-1-2-3 8-2-4-5 9-6-6-7 10-1-8-9
|
||||||
|
0x16ac 5-14-2-3 6-8-1-4 7-4-1-3 8-4-2-4 9-6-5-6 10-2-7-8 11-6-9-10
|
||||||
|
0x16ad 5-7-2-4 6-7-1-2 7-9-3-4 8-6-1-5 9-7-6-7 10-6-8-9
|
||||||
|
0x16bc 5-7-2-3 6-6-2-3 7-6-4-5 8-2-1-7 9-6-6-8
|
||||||
|
0x16e9 5-9-1-3 6-7-2-3 7-9-2-5 8-7-6-7 9-6-4-8
|
||||||
|
0x177e 5-6-1-3 6-6-2-3 7-6-4-5 8-14-6-7 9-7-1-4 10-9-8-9
|
||||||
|
0x178e 5-6-3-4 6-6-1-2 7-6-1-5 8-1-6-7 9-9-3-8
|
||||||
|
0x1796 5-6-2-3 6-9-1-2 7-13-4-5 8-7-6-7 9-6-3-8
|
||||||
|
0x1798 5-6-1-4 6-8-1-2 7-6-2-5 8-2-3-7 9-14-6-8 10-6-4-9
|
||||||
|
0x179a 5-6-1-4 6-8-3-4 7-2-1-2 8-4-2-3 9-2-5-6 10-14-7-9 11-6-8-10
|
||||||
|
0x17ac 5-4-1-4 6-8-1-3 7-6-3-5 8-13-2-7 9-4-6-8 10-9-4-9
|
||||||
|
0x17e8 5-6-1-2 6-1-1-2 7-11-3-5 8-6-4-7 9-6-6-8
|
||||||
|
0x18e7 5-6-2-3 6-9-1-2 7-7-5-6 8-6-4-7
|
||||||
|
0x19e1 5-4-3-4 6-13-3-4 7-2-1-5 8-13-2-7 9-9-6-8 10-6-1-9
|
||||||
|
0x19e3 5-7-2-3 6-1-3-4 7-8-1-5 8-6-4-7 9-1-6-8 10-9-2-9
|
||||||
|
0x19e6 5-8-1-3 6-6-1-4 7-2-2-5 8-6-6-7
|
||||||
|
0x1bd8 5-6-2-3 6-9-1-4 7-6-1-3 8-1-5-6 9-6-7-8
|
||||||
|
0x1be4 5-9-2-3 6-6-3-4 7-1-1-5 8-6-6-7
|
||||||
|
0x1ee1 5-9-3-4 6-1-1-2 7-9-5-6
|
||||||
|
0x3cc3 5-3-1-3 6-12-1-2 7-6-4-6 8-6-5-7
|
||||||
|
0x6996 5-9-1-3 6-6-2-4 7-9-5-6
|
|
@ -0,0 +1,58 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <kitty/operations.hpp>
|
||||||
|
|
||||||
|
#include <mockturtle/traits.hpp>
|
||||||
|
#include <mockturtle/utils/node_map.hpp>
|
||||||
|
#include <mockturtle/views/topo_view.hpp>
|
||||||
|
|
||||||
|
namespace mockturtle
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename NtkSource, typename NtkDest, typename LeavesIterator>
|
||||||
|
std::vector<signal<NtkDest>> stp_cleanup_dangling( NtkSource const& ntk, NtkDest& dest, LeavesIterator begin, LeavesIterator end )
|
||||||
|
{
|
||||||
|
(void)end;
|
||||||
|
|
||||||
|
node_map<signal<NtkDest>, NtkSource> old_to_new( ntk );
|
||||||
|
old_to_new[ntk.get_constant( false )] = dest.get_constant( false );
|
||||||
|
|
||||||
|
/* create inputs in same order */
|
||||||
|
auto it = begin;
|
||||||
|
ntk.foreach_pi( [&]( auto node ) {
|
||||||
|
old_to_new[node] = *it++;
|
||||||
|
} );
|
||||||
|
assert( it == end );
|
||||||
|
|
||||||
|
/* foreach node in topological order */
|
||||||
|
topo_view topo{ntk};
|
||||||
|
topo.foreach_node( [&]( auto node ) {
|
||||||
|
if ( ntk.is_constant( node ) || ntk.is_pi( node ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* collect children */
|
||||||
|
std::vector<signal<NtkDest>> children;
|
||||||
|
ntk.foreach_fanin( node, [&]( auto child, auto ) {
|
||||||
|
const auto f = old_to_new[child];
|
||||||
|
children.push_back( f );
|
||||||
|
} );
|
||||||
|
|
||||||
|
old_to_new[node] = dest.clone_node( ntk, node, children );
|
||||||
|
} );
|
||||||
|
|
||||||
|
/* create outputs in same order */
|
||||||
|
std::vector<signal<NtkDest>> fs;
|
||||||
|
ntk.foreach_po( [&]( auto po ) {
|
||||||
|
const auto f = old_to_new[po];
|
||||||
|
fs.push_back( f );
|
||||||
|
} );
|
||||||
|
|
||||||
|
return fs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace mockturtle
|
|
@ -0,0 +1,216 @@
|
||||||
|
/* phyLS: Advanced Logic Synthesis and Optimization tool
|
||||||
|
* Copyright (C) 2019- Ningbo University, Ningbo, China
|
||||||
|
/*
|
||||||
|
\file stp_npn.hpp
|
||||||
|
\brief Replace with size-optimum STP-based exact synthesis from NPN
|
||||||
|
|
||||||
|
\author Homyoung
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <kitty/dynamic_truth_table.hpp>
|
||||||
|
#include <kitty/npn.hpp>
|
||||||
|
#include <kitty/print.hpp>
|
||||||
|
#include <mockturtle/mockturtle.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../../core/misc.hpp"
|
||||||
|
#include "stp_cleanup.hpp"
|
||||||
|
|
||||||
|
namespace mockturtle {
|
||||||
|
|
||||||
|
class stp_npn_resynthesis {
|
||||||
|
public:
|
||||||
|
/*! \brief Default constructor.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
stp_npn_resynthesis() { build_db(); }
|
||||||
|
|
||||||
|
template <typename LeavesIterator, typename Fn>
|
||||||
|
void operator()(klut_network& klut,
|
||||||
|
kitty::dynamic_truth_table const& function,
|
||||||
|
LeavesIterator begin, LeavesIterator end, Fn&& fn) const {
|
||||||
|
assert(function.num_vars() <= 4);
|
||||||
|
const auto fe = kitty::extend_to(function, 4);
|
||||||
|
const auto config = kitty::exact_npn_canonization(fe);
|
||||||
|
|
||||||
|
auto func_str = "0x" + kitty::to_hex(std::get<0>(config));
|
||||||
|
const auto it = class2signal.find(func_str);
|
||||||
|
assert(it != class2signal.end());
|
||||||
|
|
||||||
|
std::vector<klut_network::signal> pis(4, klut.get_constant(false));
|
||||||
|
std::copy(begin, end, pis.begin());
|
||||||
|
|
||||||
|
std::vector<klut_network::signal> pis_perm(4);
|
||||||
|
auto perm = std::get<2>(config);
|
||||||
|
for (auto i = 0; i < 4; ++i) {
|
||||||
|
pis_perm[i] = pis[perm[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// const auto& phase = std::get<1>(config);
|
||||||
|
// for (auto i = 0; i < 4; ++i) {
|
||||||
|
// if ((phase >> perm[i]) & 1) {
|
||||||
|
// pis_perm[i] = !pis_perm[i];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
for (auto const& po : it->second) {
|
||||||
|
topo_view topo{db, po};
|
||||||
|
auto f =
|
||||||
|
stp_cleanup_dangling(topo, klut, pis_perm.begin(), pis_perm.end())
|
||||||
|
.front();
|
||||||
|
|
||||||
|
if (!fn(f)) return; /* quit */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<std::string, std::vector<std::string>> opt_klut;
|
||||||
|
|
||||||
|
void load_optimal_klut() {
|
||||||
|
std::ifstream infile("../src/networks/stp/opt_stp.txt");
|
||||||
|
if (!infile) {
|
||||||
|
std::cout << " Cannot open file " << std::endl;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
std::vector<std::string> v;
|
||||||
|
while (std::getline(infile, line)) {
|
||||||
|
v.clear();
|
||||||
|
auto strs = phyLS::split_by_delim(line, ' ');
|
||||||
|
for (auto i = 1u; i < strs.size(); i++) v.push_back(strs[i]);
|
||||||
|
opt_klut.insert(std::make_pair(strs[0], v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<klut_network::signal> create_klut_from_str_vec(
|
||||||
|
const std::vector<std::string> strs,
|
||||||
|
const std::vector<klut_network::signal>& signals) {
|
||||||
|
auto sig = signals;
|
||||||
|
std::vector<klut_network::signal> result;
|
||||||
|
|
||||||
|
int a, b;
|
||||||
|
for (auto i = 0; i < strs.size(); i++) {
|
||||||
|
const auto substrs = phyLS::split_by_delim(strs[i], '-');
|
||||||
|
assert(substrs.size() == 4u);
|
||||||
|
|
||||||
|
a = std::stoi(substrs[2]);
|
||||||
|
b = std::stoi(substrs[3]);
|
||||||
|
switch (std::stoi(substrs[1])) {
|
||||||
|
case 0: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 15));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 14));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 13));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 3: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 12));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 4: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 11));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 5: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 10));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 6: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 9));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 7: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 8));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 8: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 7));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 9: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 6));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 10: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 5));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 11: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 4));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 12: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 3));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 13: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 2));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 14: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 15: {
|
||||||
|
sig.push_back(db._create_node({sig[a], sig[b]}, 0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto driver = sig[sig.size() - 1];
|
||||||
|
db.create_po(driver);
|
||||||
|
result.push_back(driver);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void build_db() {
|
||||||
|
std::vector<klut_network::signal> signals;
|
||||||
|
signals.push_back(db.get_constant(false));
|
||||||
|
|
||||||
|
for (auto i = 0u; i < 4; ++i) signals.push_back(db.create_pi());
|
||||||
|
|
||||||
|
load_optimal_klut();
|
||||||
|
|
||||||
|
for (const auto e : opt_klut) {
|
||||||
|
class2signal.insert(
|
||||||
|
std::make_pair(e.first, create_klut_from_str_vec(e.second, signals)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
klut_network db;
|
||||||
|
std::unordered_map<std::string, std::vector<klut_network::signal>>
|
||||||
|
class2signal;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace mockturtle */
|
|
@ -51,5 +51,8 @@
|
||||||
#include "commands/simulator.hpp"
|
#include "commands/simulator.hpp"
|
||||||
#include "commands/abc/cec.hpp"
|
#include "commands/abc/cec.hpp"
|
||||||
#include "commands/stpfr.hpp"
|
#include "commands/stpfr.hpp"
|
||||||
|
#include "commands/cutrw.hpp"
|
||||||
|
#include "commands/exact/exact_lut.hpp"
|
||||||
|
#include "commands/exact/lutrw.hpp"
|
||||||
|
|
||||||
ALICE_MAIN(phyLS)
|
ALICE_MAIN(phyLS)
|
Loading…
Reference in New Issue