update for exact synthesis

noah
panhongyang0 2024-03-04 18:12:13 +08:00
parent 5134f1969f
commit cc604d0906
8 changed files with 3936 additions and 2998 deletions

View File

@ -21,6 +21,7 @@
#include "../../core/exact/exact_dag.hpp" #include "../../core/exact/exact_dag.hpp"
#include "../../core/exact/exact_lut.hpp" #include "../../core/exact/exact_lut.hpp"
#include "../core/exact/lut_rewriting.hpp"
using namespace std; using namespace std;
using namespace percy; using namespace percy;
@ -38,6 +39,8 @@ class exact_command : public command {
"stp based cegar encoding and partial DAG structure"); "stp based cegar encoding and partial DAG structure");
add_flag("--dag_depth, -t", add_flag("--dag_depth, -t",
"cegar encoding and partial DAG structure for Delay"); "cegar encoding and partial DAG structure for Delay");
add_flag("--decomposition, -p",
"using decomposition before exact synthesis");
add_option("--output, -o", filename, "the verilog filename"); add_option("--output, -o", filename, "the verilog filename");
add_flag("--enumeration, -e", "enumerate all solutions"); add_flag("--enumeration, -e", "enumerate all solutions");
add_flag("--new_entry, -w", "adds k-LUT store entry"); add_flag("--new_entry, -w", "adds k-LUT store entry");
@ -46,6 +49,7 @@ class exact_command : public command {
add_flag("--xag, -g", "enable exact synthesis for XAG, 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("--npn, -n", "print result for NPN storing, default = false");
add_flag("--depth, -d", "print the depth of each result, default = false"); add_flag("--depth, -d", "print the depth of each result, default = false");
add_flag("--parallel, -l", "parallel exact synthesis");
add_flag("--verbose, -v", "verbose results, default = true"); add_flag("--verbose, -v", "verbose results, default = true");
} }
@ -200,6 +204,29 @@ class exact_command : public command {
} }
} }
void es_parallel(int nr_in, chain& result) {
spec spec;
chain c;
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;
spec.preprocess();
auto res = pd_ser_synthesize_parallel(spec, c, 4, "../src/pd/");
// auto res = pf_fence_synthesize(spec, c, 8);
if (res == success) result.copy(c);
}
void es_delay(int nr_in, list<chain>& chains) { void es_delay(int nr_in, list<chain>& chains) {
int node = nr_in - 1, max_level = 0, count = 0; int node = nr_in - 1, max_level = 0, count = 0;
bool target = false; bool target = false;
@ -338,6 +365,12 @@ class exact_command : public command {
return target; return target;
} }
void es_after_decomposition() {
dec_network = store<mockturtle::klut_network>().current();
phyLS::lut_rewriting_params ps;
dec_network = phyLS::lut_rewriting_c(dec_network, ps);
}
void execute() { void execute() {
t.clear(); t.clear();
t.push_back(binary_to_hex()); t.push_back(binary_to_hex());
@ -522,7 +555,7 @@ class exact_command : public command {
} }
cout << "[Total realization]: " << count << endl; cout << "[Total realization]: " << count << endl;
} else if (is_set("stp_cegar_dag")) { } else if (is_set("stp_cegar_dag")) {
if (is_set("map")){ if (is_set("map")) {
ps.gates = store<std::vector<mockturtle::gate>>().current(); ps.gates = store<std::vector<mockturtle::gate>>().current();
begin = clock(); begin = clock();
exact_lut_dag_enu_map(tt, nr_in, ps); exact_lut_dag_enu_map(tt, nr_in, ps);
@ -544,10 +577,45 @@ class exact_command : public command {
totalTime = (double)(end - begin) / CLOCKS_PER_SEC; totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
cout << "[Total realization]: " << nr_in << endl; cout << "[Total realization]: " << nr_in << endl;
} }
} else if (is_set("decomposition")) {
begin = clock();
es_after_decomposition();
end = clock();
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
} else if (is_set("parallel")) {
int64_t total_elapsed = 0;
auto start = std::chrono::steady_clock::now();
chain chain;
es_parallel(nr_in, chain);
const auto elapsed1 =
std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now() - start)
.count();
total_elapsed += elapsed1;
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;
}
}
printf("[Total CPU time] : %ldus\n", total_elapsed);
} else { } else {
if (is_set("enumeration")) { if (is_set("enumeration")) {
begin = clock(); begin = clock();
phyLS::exact_lut_enu(tt_h, nr_in); int cut_size = 0;
phyLS::exact_lut_enu(tt_h, nr_in, cut_size);
end = clock(); end = clock();
totalTime = (double)(end - begin) / CLOCKS_PER_SEC; totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
int count = 0; int count = 0;
@ -558,7 +626,8 @@ class exact_command : public command {
cout << "[Total realization]: " << count << endl; cout << "[Total realization]: " << count << endl;
} else { } else {
begin = clock(); begin = clock();
phyLS::exact_lut(tt_h, nr_in); int cut_size = 0;
phyLS::exact_lut(tt_h, nr_in, cut_size);
end = clock(); end = clock();
totalTime = (double)(end - begin) / CLOCKS_PER_SEC; totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
int count = 0; int count = 0;
@ -582,6 +651,7 @@ class exact_command : public command {
double min_delay = 0.00; double min_delay = 0.00;
int mapping_gate = 0; int mapping_gate = 0;
std::string filename = "techmap.v"; std::string filename = "techmap.v";
klut_network dec_network;
}; };
ALICE_ADD_COMMAND(exact, "Synthesis") ALICE_ADD_COMMAND(exact, "Synthesis")

View File

@ -0,0 +1,121 @@
#ifndef EXACT_MULTI_HPP
#define EXACT_MULTI_HPP
#include <alice/alice.hpp>
#include <iostream>
#include <mockturtle/algorithms/klut_to_graph.hpp>
#include <mockturtle/mockturtle.hpp>
#include <percy/percy.hpp>
#include <string>
#include <vector>
#include "../store.hpp"
using namespace std;
using namespace percy;
using namespace mockturtle;
using kitty::dynamic_truth_table;
using namespace std;
namespace alice {
class exact_window_command : public command {
public:
explicit exact_window_command(const environment::ptr& env)
: command(env, "using exact synthesis to find optimal window") {
add_flag("--cegar, -c", "cegar encoding");
add_option("--num_functions, -n", num_functions,
"set the number of functions to be synthesized, default = 1");
add_option("--file, -f", filename, "input filename");
add_flag("--verbose, -v", "print the information");
}
private:
int num_functions = 1;
std::string filename;
vector<string> iTT;
aig_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";
}
aig_network aig = convert_klut_to_graph<aig_network>(klut);
return aig;
}
protected:
void execute() {
spec spec;
aig_network aig;
if (is_set("file")) {
ifstream fin_bench(filename);
string tmp;
if (fin_bench.is_open()) {
while (getline(fin_bench, tmp)) {
iTT.push_back(tmp);
}
fin_bench.close();
int nr_in = 0, value = 0;
while (value < iTT[0].size()) {
value = pow(2, nr_in);
if (value == iTT[0].size()) break;
nr_in++;
}
for (int i = 0; i < iTT.size(); i++) {
kitty::dynamic_truth_table f(nr_in);
kitty::create_from_binary_string(f, iTT[i]);
spec[i] = f;
}
}
} else {
auto store_size = store<optimum_network>().size();
assert(store_size >= num_functions);
if (!is_set("num_functions")) num_functions = 1;
for (int i = 0; i < num_functions; i++) {
auto& opt = store<optimum_network>()[store_size - i - 1];
auto copy = opt.function;
spec[i] = copy;
}
}
stopwatch<>::duration time{0};
if (is_set("cegar")) {
bsat_wrapper solver;
msv_encoder encoder(solver);
chain c;
call_with_stopwatch(time, [&]() {
if (synthesize(spec, c, solver, encoder) == success) {
c.print_bench();
aig = create_network(c);
store<aig_network>().extend();
store<aig_network>().current() = aig;
}
});
} else {
bsat_wrapper solver;
ssv_encoder encoder(solver);
chain c;
call_with_stopwatch(time, [&]() {
if (synthesize(spec, c, solver, encoder) == success) {
c.print_bench();
aig = create_network(c);
store<aig_network>().extend();
store<aig_network>().current() = aig;
}
});
}
std::cout << fmt::format("[Total CPU time] : {:5.3f} seconds\n",
to_seconds(time));
}
};
ALICE_ADD_COMMAND(exact_window, "Synthesis")
} // namespace alice
#endif

View File

@ -95,7 +95,7 @@ class fr_command : public command {
} }
private: private:
int max_tfi_node = 10000; int max_tfi_node = 1000;
string filename = "pattern.log"; string filename = "pattern.log";
}; };

View File

@ -34,10 +34,12 @@ class lut_mapping_command : public command {
: command(env, "LUT mapping [default = AIG]") { : command(env, "LUT mapping [default = AIG]") {
add_option("cut_size, -k", cut_size, add_option("cut_size, -k", cut_size,
"set the cut size from 2 to 8, default = 4"); "set the cut size from 2 to 8, default = 4");
add_flag("--verbose, -v", "print the information");
add_flag("--satlut, -s", "satlut mapping"); add_flag("--satlut, -s", "satlut mapping");
add_flag("--xag, -g", "LUT mapping for XAG"); add_flag("--xag, -g", "LUT mapping for XAG");
add_flag("--mig, -m", "LUT mapping for MIG"); add_flag("--mig, -m", "LUT mapping for MIG");
add_flag("--klut, -l", "LUT mapping for k-LUT");
add_flag("--area, -a", "area-oriented mapping, default = no");
add_flag("--verbose, -v", "print the information");
} }
protected: protected:
@ -45,6 +47,9 @@ class lut_mapping_command : public command {
clock_t begin, end; clock_t begin, end;
double totalTime; double totalTime;
lut_mapping_params ps; lut_mapping_params ps;
if (is_set("area")){
ps.rounds_ela = 4u;
}
if (is_set("mig")) { if (is_set("mig")) {
/* derive some MIG */ /* derive some MIG */
@ -78,6 +83,22 @@ class lut_mapping_command : public command {
totalTime = (double)(end - begin) / CLOCKS_PER_SEC; totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
store<klut_network>().extend(); store<klut_network>().extend();
store<klut_network>().current() = klut; store<klut_network>().current() = klut;
} else if (is_set("klut")) {
/* derive some kLUT */
assert(store<klut_network>().size() > 0);
begin = clock();
klut_network klut = store<klut_network>().current();
mapping_view<klut_network, true> mapped_klut{klut};
ps.cut_enumeration_ps.cut_size = cut_size;
lut_mapping<mapping_view<klut_network, true>, true>(mapped_klut, ps);
/* collapse into k-LUT network */
const auto klut_new = *collapse_mapped_network<klut_network>(mapped_klut);
end = clock();
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
store<klut_network>().extend();
store<klut_network>().current() = klut_new;
} else { } else {
if (store<aig_network>().size() == 0) { if (store<aig_network>().size() == 0) {
assert(false && "Error: Empty AIG network\n"); assert(false && "Error: Empty AIG network\n");

View File

@ -1,14 +1,14 @@
/* phyLS: powerful heightened yielded Logic Synthesis /* phyLS: powerful heightened yielded Logic Synthesis
* Copyright (C) 2022 */ * Copyright (C) 2022 */
/** /**
* @file techmap.hpp * @file techmap.hpp
* *
* @brief Standard cell mapping * @brief Standard cell mapping
* *
* @author Homyoung * @author Homyoung
* @since 2022/12/14 * @since 2022/12/14
*/ */
#ifndef TECHMAP_HPP #ifndef TECHMAP_HPP
#define TECHMAP_HPP #define TECHMAP_HPP
@ -26,118 +26,115 @@
namespace alice { namespace alice {
class techmap_command: public command { class techmap_command : public command {
public: public:
explicit techmap_command(const environment::ptr& env) explicit techmap_command(const environment::ptr& env)
: command(env, "Standard cell mapping [default = AIG]") { : command(env, "Standard cell mapping [default = AIG]") {
add_flag("--xmg, -x", "Standard cell mapping for XMG"); add_flag("--xmg, -x", "Standard cell mapping for XMG");
add_flag("--mig, -m", "Standard cell mapping for MIG"); add_flag("--mig, -m", "Standard cell mapping for MIG");
add_flag("--lut, -l", "Standard cell mapping for k-LUT"); add_flag("--lut, -l", "Standard cell mapping for k-LUT");
add_option("--output, -o", filename, "the verilog filename"); add_option("--output, -o", filename, "the verilog filename");
add_flag("--verbose, -v", "print the information"); add_flag("--verbose, -v", "print the information");
} }
rules validity_rules() const { rules validity_rules() const {
return { has_store_element<std::vector<mockturtle::gate>>(env) }; return {has_store_element<std::vector<mockturtle::gate>>(env)};
} }
private: private:
std::string filename = "techmap.v"; std::string filename = "techmap.v";
protected: protected:
void execute() { void execute() {
/* derive genlib */ /* derive genlib */
std::vector<mockturtle::gate> gates = std::vector<mockturtle::gate> gates =
store<std::vector<mockturtle::gate>>().current(); store<std::vector<mockturtle::gate>>().current();
mockturtle::tech_library<5> lib(gates);
mockturtle::tech_library<5> lib(gates); mockturtle::map_params ps;
mockturtle::map_params ps; mockturtle::map_stats st;
mockturtle::map_stats st;
if (is_set("xmg")) { if (is_set("xmg")) {
if (store<xmg_network>().size() == 0u) if (store<xmg_network>().size() == 0u)
std::cerr << "[e] no XMG in the store\n"; std::cerr << "[e] no XMG in the store\n";
else { else {
auto xmg = store<xmg_network>().current(); auto xmg = store<xmg_network>().current();
xmg_gate_stats stats; xmg_gate_stats stats;
xmg_profile_gates(xmg, stats); xmg_profile_gates(xmg, stats);
std::cout << "[i] "; std::cout << "[i] ";
stats.report(); stats.report();
phyLS::xmg_critical_path_stats critical_stats; phyLS::xmg_critical_path_stats critical_stats;
phyLS::xmg_critical_path_profile_gates(xmg, critical_stats); phyLS::xmg_critical_path_profile_gates(xmg, critical_stats);
std::cout << "[i] "; std::cout << "[i] ";
critical_stats.report(); critical_stats.report();
auto res = mockturtle::map(xmg, lib, ps, &st); auto res = mockturtle::map(xmg, lib, ps, &st);
if (is_set("output")) { if (is_set("output")) {
write_verilog_with_binding(res, filename); write_verilog_with_binding(res, filename);
} }
std::cout << fmt::format( std::cout << fmt::format(
"[i] Mapped XMG into #gates = {} area = {:.2f} delay = {:.2f}\n", "[i] Mapped XMG into #gates = {} area = {:.2f} delay = {:.2f}\n",
res.num_gates(), st.area, st.delay); res.num_gates(), st.area, st.delay);
}
} }
else if (is_set("mig")) { } else if (is_set("mig")) {
if (store<mig_network>().size() == 0u) { if (store<mig_network>().size() == 0u) {
std::cerr << "[e] no MIG in the store\n"; std::cerr << "[e] no MIG in the store\n";
} else {
auto mig = store<mig_network>().current();
auto res = mockturtle::map(mig, lib, ps, &st);
if (is_set("output")) {
write_verilog_with_binding(res, filename);
} }
else {
auto mig = store<mig_network>().current();
auto res = mockturtle::map(mig, lib, ps, &st); std::cout << fmt::format(
if (is_set("output")) {
write_verilog_with_binding(res, filename);
}
std::cout << fmt::format(
"Mapped MIG into #gates = {} area = {:.2f} delay = {:.2f}\n", "Mapped MIG into #gates = {} area = {:.2f} delay = {:.2f}\n",
res.num_gates(), st.area, st.delay); res.num_gates(), st.area, st.delay);
}
} }
else if (is_set("lut")) { } else if (is_set("lut")) {
if (store<klut_network>().size() == 0u) { if (store<klut_network>().size() == 0u) {
std::cerr << "[e] no k-LUT in the store\n"; std::cerr << "[e] no k-LUT in the store\n";
} else {
auto lut = store<klut_network>().current();
auto res = mockturtle::map(lut, lib, ps, &st);
if (is_set("output")) {
write_verilog_with_binding(res, filename);
} }
else {
auto lut = store<klut_network>().current();
auto res = mockturtle::map(lut, lib, ps, &st); std::cout << fmt::format(
if (is_set("output")) {
write_verilog_with_binding(res, filename);
}
std::cout << fmt::format(
"Mapped k-LUT into #gates = {} area = {:.2f} delay = {:.2f}\n", "Mapped k-LUT into #gates = {} area = {:.2f} delay = {:.2f}\n",
res.num_gates(), st.area, st.delay); res.num_gates(), st.area, st.delay);
}
} }
else { } else {
if (store<aig_network>().size() == 0u) { if (store<aig_network>().size() == 0u) {
std::cerr << "[e] no AIG in the store\n"; std::cerr << "[e] no AIG in the store\n";
} } else {
else { auto aig = store<aig_network>().current();
auto aig = store<aig_network>().current(); auto res = mockturtle::map(aig, lib, ps, &st);
auto res = mockturtle::map(aig, lib, ps, &st); if (is_set("output")) write_verilog_with_binding(res, filename);
if (is_set("output")) { // std::cout << fmt::format(
write_verilog_with_binding(res, filename); // "Mapped AIG into #gates = {}, area = {:.2f}, delay = {:.2f}, "
} // "power = {:.2f}\n",
// res.num_gates(), st.area, st.delay, st.power);
std::cout << fmt::format(
"Mapped AIG into #gates = {} area = {:.2f} delay = {:.2f}\n",
res.num_gates(), st.area, st.delay);
}
} }
} }
}; if (is_set("verbose")) {
st.report();
cout << "Cut enumeration stats: " << endl;
st.cut_enumeration_st.report();
}
}
};
ALICE_ADD_COMMAND(techmap, "Mapping") ALICE_ADD_COMMAND(techmap, "Mapping")
} // namespace alice } // namespace alice

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -76,7 +76,7 @@
#include "commands/xag/xagrs.hpp" #include "commands/xag/xagrs.hpp"
#include "commands/xmg/xmgrs.hpp" #include "commands/xmg/xmgrs.hpp"
#include "commands/xmg/xmgrw.hpp" #include "commands/xmg/xmgrw.hpp"
#include "commands/exact/exact_multi.hpp" // #include "commands/exact/exact_multi.hpp"
#include "commands/exact/exact_klut.hpp" #include "commands/exact/exact_klut.hpp"
#include "commands/exact/exactlut.hpp" #include "commands/exact/exactlut.hpp"
#include "commands/to_npz.hpp" #include "commands/to_npz.hpp"