From 9635c0de3c134a0425e5eb264bc10dd7544e4e3f Mon Sep 17 00:00:00 2001 From: panhongyang Date: Tue, 14 Mar 2023 20:59:24 +0800 Subject: [PATCH] add abc as a submodule --- .gitmodules | 3 + lib/CMakeLists.txt | 5 + lib/abc | 1 + src/CMakeLists.txt | 2 +- src/commands/abc/&fraig.hpp | 80 ++++ src/commands/abc/&get.hpp | 70 ++++ src/commands/abc/fraig.hpp | 97 +++++ src/commands/abc/read.hpp | 64 +++ src/commands/abc/resub.hpp | 67 ++++ src/commands/abc/strash.hpp | 66 ++++ src/commands/abc/write.hpp | 51 +++ src/core/abc2mockturtle.hpp | 751 ++++++++++++++++++++++++++++++++++++ src/phyLS.cpp | 7 + src/store.hpp | 107 +++++ 14 files changed, 1370 insertions(+), 1 deletion(-) create mode 160000 lib/abc create mode 100644 src/commands/abc/&fraig.hpp create mode 100644 src/commands/abc/&get.hpp create mode 100644 src/commands/abc/fraig.hpp create mode 100644 src/commands/abc/read.hpp create mode 100644 src/commands/abc/resub.hpp create mode 100644 src/commands/abc/strash.hpp create mode 100644 src/commands/abc/write.hpp create mode 100644 src/core/abc2mockturtle.hpp diff --git a/.gitmodules b/.gitmodules index a9e961a..f4287fe 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "lib/mockturtle"] path = lib/mockturtle url = https://github.com/lsils/mockturtle.git +[submodule "lib/abc"] + path = lib/abc + url = https://github.com/berkeley-abc/abc.git diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 1d4dd25..260b8fb 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,3 +1,8 @@ # Add alice and mockturtle sub directories add_subdirectory(alice) add_subdirectory(mockturtle) + +set(ABC_USE_NAMESPACE "pabc") + +add_subdirectory(abc EXCLUDE_FROM_ALL) +target_compile_definitions(libabc-pic PUBLIC "LIN64") \ No newline at end of file diff --git a/lib/abc b/lib/abc new file mode 160000 index 0000000..a5f4841 --- /dev/null +++ b/lib/abc @@ -0,0 +1 @@ +Subproject commit a5f4841486d4a491913943c5b92167a9e988abac diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1c23536..f1945da 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,4 +5,4 @@ file(GLOB_RECURSE FILENAMES *.cpp) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) add_executable(phyLS phyLS.cpp ${FILENAMES}) -target_link_libraries(phyLS alice mockturtle) +target_link_libraries(phyLS alice mockturtle libabc-pic) diff --git a/src/commands/abc/&fraig.hpp b/src/commands/abc/&fraig.hpp new file mode 100644 index 0000000..9618988 --- /dev/null +++ b/src/commands/abc/&fraig.hpp @@ -0,0 +1,80 @@ +/* phyLS: powerful heightened yielded Logic Synthesis + * Copyright (C) 2023 */ + +/** + * @file &fraig.hpp + * + * @brief performs combinational SAT sweeping + * + * @author Homyoung + * @since 2023/03/14 + */ + +#ifndef AFRAIG_HPP +#define AFRAIG_HPP + +#include "aig/gia/gia.h" +#include "proof/cec/cec.h" + +using namespace std; +using namespace mockturtle; + +namespace alice { + +class Afraig_command : public command { + public: + explicit Afraig_command(const environment::ptr &env) + : command(env, "performs combinational SAT sweeping") { + add_flag("--verbose, -v", "print the information"); + } + + protected: + void execute() { + clock_t begin, end; + double totalTime; + + begin = clock(); + + if (store().size() == 0u) + std::cerr << "Error: Empty GIA network.\n"; + else { + pabc::Gia_Man_t *pNtk, *pTemp; + pNtk = store().current(); + + pabc::Cec_ParFra_t ParsFra, *pPars = &ParsFra; + // set defaults + memset(pPars, 0, sizeof(pabc::Cec_ParFra_t)); + pPars->jType = 2; // solver type + pPars->fSatSweeping = 1; // conflict limit at a node + pPars->nWords = 4; // simulation words + pPars->nRounds = 10; // simulation rounds + pPars->nItersMax = 2000; // this is a miter + pPars->nBTLimit = 1000000; // use logic cones + pPars->nBTLimitPo = 0; // use logic outputs + pPars->nSatVarMax = + 1000; // the max number of SAT variables before recycling SAT solver + pPars->nCallsRecycle = + 500; // calls to perform before recycling SAT solver + pPars->nGenIters = 100; // pattern generation iterations + + pTemp = Cec_ManSatSweeping(pNtk, pPars, 0); + + store().extend(); + store().current() = pTemp; + } + + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; + + cout.setf(ios::fixed); + cout << "[CPU time] " << setprecision(2) << totalTime << " s" << endl; + } + + private: +}; + +ALICE_ADD_COMMAND(Afraig, "Gia") + +} // namespace alice + +#endif \ No newline at end of file diff --git a/src/commands/abc/&get.hpp b/src/commands/abc/&get.hpp new file mode 100644 index 0000000..d1fc0a0 --- /dev/null +++ b/src/commands/abc/&get.hpp @@ -0,0 +1,70 @@ +/* phyLS: powerful heightened yielded Logic Synthesis + * Copyright (C) 2023 */ + +/** + * @file get.hpp + * + * @brief converts the current network into GIA + * + * @author Homyoung + * @since 2023/03/14 + */ + +#ifndef AGET_HPP +#define AGET_HPP + +#include "aig/gia/giaAig.h" +#include "base/abc/abc.h" +#include "base/abci/abcDar.c" + +using namespace std; +using namespace mockturtle; + +namespace alice { + +class Aget_command : public command { + public: + explicit Aget_command(const environment::ptr &env) + : command(env, "converts the current network into GIA") {} + + protected: + void execute() { + clock_t begin, end; + double totalTime; + + begin = clock(); + + if (store().size() == 0u) + std::cerr << "Error: Empty ABC AIG network\n"; + else { + pabc::Abc_Ntk_t *pNtk = store().current(); + + pabc::Aig_Man_t *pAig; + pabc::Gia_Man_t *pGia; + + if (pabc::Abc_NtkGetChoiceNum(pNtk)) + pAig = Abc_NtkToDarChoices(pNtk); + else + pAig = Abc_NtkToDar(pNtk, 0, 1); + + pGia = Gia_ManFromAig(pAig); + pabc::Aig_ManStop(pAig); + store().extend(); + store().current() = pGia; + } + + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; + + cout.setf(ios::fixed); + cout << "[CPU time] " << setprecision(2) << totalTime << " s" << endl; + } + + private: +}; + +ALICE_ADD_COMMAND(Aget, "Gia") + +} // namespace alice + +#endif \ No newline at end of file diff --git a/src/commands/abc/fraig.hpp b/src/commands/abc/fraig.hpp new file mode 100644 index 0000000..fd086e2 --- /dev/null +++ b/src/commands/abc/fraig.hpp @@ -0,0 +1,97 @@ +/* phyLS: powerful heightened yielded Logic Synthesis + * Copyright (C) 2023 */ + +/** + * @file fraig.hpp + * + * @brief transforms a logic network into a functionally reduced AIG + * + * @author Homyoung + * @since 2023/03/14 + */ + +#ifndef FRAIG_HPP +#define FRAIG_HPP + +#include "base/abc/abc.h" +#include "proof/fraig/fraig.h" + +using namespace std; +using namespace mockturtle; + +namespace alice { + +class fraig_command : public command { + public: + explicit fraig_command(const environment::ptr &env) + : command(env, + "transforms a logic network into a functionally reduced AIG") { + add_flag("--verbose, -v", "print the information"); + } + + protected: + void execute() { + clock_t begin, end; + double totalTime; + + begin = clock(); + + if (store().size() == 0u) + std::cerr << "Error: Empty ABC AIG network.\n"; + else { + pabc::Abc_Ntk_t *pNtk, *pNtkRes; + pNtk = store().current(); + if (!pabc::Abc_NtkIsLogic(pNtk) && !pabc::Abc_NtkIsStrash(pNtk)) + std::cerr << "Can only fraig a logic network or an AIG.\n"; + + pabc::Fraig_Params_t Params, *pParams = &Params; + + // set defaults + int fAllNodes = 0, fExdc = 0; + + memset(pParams, 0, sizeof(pabc::Fraig_Params_t)); + pParams->nPatsRand = + 2048; // the number of words of random simulation info + pParams->nPatsDyna = + 2048; // the number of words of dynamic simulation info + pParams->nBTLimit = 100; // the max number of backtracks to perform + pParams->fFuncRed = 1; // performs only one level hashing + pParams->fFeedBack = 1; // enables solver feedback + pParams->fDist1Pats = 1; // enables distance-1 patterns + pParams->fDoSparse = 1; // performs equiv tests for sparse functions + pParams->fChoicing = 0; // enables recording structural choices + pParams->fTryProve = 0; // tries to solve the final miter + pParams->fVerbose = 0; // the verbosiness flag + pParams->fVerboseP = 0; // the verbosiness flag + + if (is_set("verbose")) pParams->fVerbose ^= 1; + + if (pabc::Abc_NtkIsStrash(pNtk)) + pNtkRes = pabc::Abc_NtkFraig(pNtk, &Params, fAllNodes, fExdc); + else { + pNtk = pabc::Abc_NtkStrash(pNtk, fAllNodes, !fAllNodes, 0); + pNtkRes = pabc::Abc_NtkFraig(pNtk, &Params, fAllNodes, fExdc); + pabc::Abc_NtkDelete(pNtk); + } + + if (pNtkRes == NULL) std::cerr << "Fraiging has failed.\n"; + + store().extend(); + store().current() = pNtkRes; + } + + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; + + cout.setf(ios::fixed); + cout << "[CPU time] " << setprecision(2) << totalTime << " s" << endl; + } + + private: +}; + +ALICE_ADD_COMMAND(fraig, "ABC") + +} // namespace alice + +#endif \ No newline at end of file diff --git a/src/commands/abc/read.hpp b/src/commands/abc/read.hpp new file mode 100644 index 0000000..e91ce20 --- /dev/null +++ b/src/commands/abc/read.hpp @@ -0,0 +1,64 @@ +/* phyLS: powerful heightened yielded Logic Synthesis + * Copyright (C) 2023 */ + +/** + * @file read.hpp + * + * @brief replaces the current network by the network read from file + * + * @author Homyoung + * @since 2023/03/14 + */ + +#ifndef READ_HPP +#define READ_HPP + +#include "base/abc/abc.h" + +using namespace std; +using namespace mockturtle; + +namespace alice { + +class read_command : public command { + public: + explicit read_command(const environment::ptr &env) + : command(env, + "replaces the current network by the network read from file by " + "ABC parser") { + add_option("filename,-f", file_name, "name of input file"); + add_flag("--check, -c", "Disable network check after reading"); + add_flag("--buffer, -b", "Reading barrier buffers"); + } + + protected: + void execute() override { + int fCheck = 1, fBarBufs = 0; + if (is_set("check")) fCheck ^= 1; + if (is_set("buffer")) fBarBufs ^= 1; + + // fix the wrong symbol + for (auto &x : file_name) { + if (x == '>' || x == '\\') x = '/'; + } + + assert(strlen((char *)(file_name.c_str())) < 900); + + pabc::Abc_Ntk_t *pNtk = pabc::Io_Read( + (char *)(file_name.c_str()), + pabc::Io_ReadFileType((char *)(file_name.c_str())), fCheck, fBarBufs); + + if (pNtk == NULL) std::cerr << "Error: Empty input format.\n"; + store().extend(); + store().current() = pNtk; + } + + private: + std::string file_name; +}; + +ALICE_ADD_COMMAND(read, "I/O") + +} // namespace alice + +#endif \ No newline at end of file diff --git a/src/commands/abc/resub.hpp b/src/commands/abc/resub.hpp new file mode 100644 index 0000000..4aba68a --- /dev/null +++ b/src/commands/abc/resub.hpp @@ -0,0 +1,67 @@ +/* phyLS: powerful heightened yielded Logic Synthesis + * Copyright (C) 2023 */ + +/** + * @file resub.hpp + * + * @brief performs technology-independent restructuring of the AIG + * + * @author Homyoung + * @since 2023/02/28 + */ + +#ifndef ABC_RESUB_HPP +#define ABC_RESUB_HPP + +#include "base/abci/abcRestruct.c" + +using namespace std; +using namespace mockturtle; + +namespace alice { + +class aresub_command : public command { + public: + explicit aresub_command(const environment::ptr &env) + : command(env, + "performs technology-independent restructuring of the AIG") { + add_flag("--verbose, -v", "print the information"); + } + + protected: + void execute() { + clock_t begin, end; + double totalTime; + + begin = clock(); + + if (store().size() == 0u) + std::cerr << "Error: Empty ABC AIG network\n"; + else { + pabc::Abc_Ntk_t *pNtk = store().current(); + + // set defaults + int nCutsMax = 5, fUpdateLevel = 0, fUseZeros = 0, fVerbose = 0; + + if (is_set("verbose")) fVerbose ^= 1; + + Abc_NtkRestructure(pNtk, nCutsMax, fUpdateLevel, fUseZeros, fVerbose); + store().extend(); + store().current() = pNtk; + } + + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; + + cout.setf(ios::fixed); + cout << "[CPU time] " << setprecision(2) << totalTime << " s" << endl; + } + + private: +}; + +ALICE_ADD_COMMAND(aresub, "ABC") + +} // namespace alice + +#endif \ No newline at end of file diff --git a/src/commands/abc/strash.hpp b/src/commands/abc/strash.hpp new file mode 100644 index 0000000..a0d5f12 --- /dev/null +++ b/src/commands/abc/strash.hpp @@ -0,0 +1,66 @@ +/* phyLS: powerful heightened yielded Logic Synthesis + * Copyright (C) 2022 */ + +/** + * @file strash.hpp + * + * @brief transforms combinational logic into an AIG + * + * @author Homyoung + * @since 2023/03/01 + */ + +#ifndef STRASH_HPP +#define STRASH_HPP + +#include "base/abc/abc.h" + +using namespace std; +using namespace mockturtle; + +namespace alice { + +class strash_command : public command { + public: + explicit strash_command(const environment::ptr &env) + : command(env, "transforms combinational logic into an AIG") {} + + protected: + void execute() { + clock_t begin, end; + double totalTime; + + begin = clock(); + + if (store().size() == 0u) + std::cerr << "Error: Empty ABC AIG network\n"; + else { + pabc::Abc_Ntk_t *pNtk = store().current(); + + // set defaults + int fAllNodes = 0; + int fRecord = 1; + int fCleanup = 0; + + pabc::Abc_Ntk_t *pNtkRes; + + pNtkRes = Abc_NtkStrash(pNtk, fAllNodes, fCleanup, fRecord); + store().extend(); + store().current() = pNtkRes; + } + + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; + + cout.setf(ios::fixed); + cout << "[CPU time] " << setprecision(2) << totalTime << " s" << endl; + } + + private: +}; + +ALICE_ADD_COMMAND(strash, "ABC") + +} // namespace alice + +#endif \ No newline at end of file diff --git a/src/commands/abc/write.hpp b/src/commands/abc/write.hpp new file mode 100644 index 0000000..71e8f2b --- /dev/null +++ b/src/commands/abc/write.hpp @@ -0,0 +1,51 @@ +/* phyLS: powerful heightened yielded Logic Synthesis + * Copyright (C) 2023 */ + +/** + * @file write.hpp + * + * @brief writes the current network into file + * + * @author Homyoung + * @since 2023/03/14 + */ + +#ifndef WRITE_HPP +#define WRITE_HPP + +#include "base/abc/abc.h" + +using namespace std; +using namespace mockturtle; + +namespace alice { + +class write_command : public command { + public: + explicit write_command(const environment::ptr &env) + : command(env, "writes the current network into file by ABC parser") { + add_option("filename,-f", file_name, "name of output file"); + } + + protected: + void execute() override { + assert(strlen((char *)(file_name.c_str())) < 900); + + if (store().size() == 0u) + std::cerr << "Error: Empty network.\n"; + else { + auto pNtk = store().current(); + pabc::Io_Write(pNtk, (char *)(file_name.c_str()), + pabc::Io_ReadFileType((char *)(file_name.c_str()))); + } + } + + private: + std::string file_name; +}; + +ALICE_ADD_COMMAND(write, "I/O") + +} // namespace alice + +#endif \ No newline at end of file diff --git a/src/core/abc2mockturtle.hpp b/src/core/abc2mockturtle.hpp new file mode 100644 index 0000000..7b135d9 --- /dev/null +++ b/src/core/abc2mockturtle.hpp @@ -0,0 +1,751 @@ +/* phyLS: powerful heightened yielded Logic Synthesis + * Copyright (C) 2022 */ + +/** + * @file abc2mockturtle.hpp + * + * @brief convert format between abc and mockturtle + * + * @author Homyoung + * @since 2023/02/27 + */ + +#ifndef ABC2MOCKTURTLE_HPP +#define ABC2MOCKTURTLE_HPP + +#include +#include + +#include +#include +#include +#include + +namespace phyLS { + +mockturtle::aig_network aig_new; +pabc::Abc_Ntk_t* abc_ntk_; +std::map pi_names; +std::map po_names; + +mockturtle::aig_network& abc2mockturtle_a(pabc::Abc_Ntk_t* abc_ntk_new) { + // Convert abc aig network to the aig network in also + pabc::Abc_Ntk_t* abc_ntk_aig; + abc_ntk_aig = abc_ntk_new; + mockturtle::aig_network aig; + using sig = mockturtle::aig_network::signal; + std::map signals; + signals.clear(); + pi_names.clear(); + po_names.clear(); + + // create also network + // process the also network primary input + int i; + pabc::Abc_Obj_t* pObj1; + for (i = 0; (i < pabc::Abc_NtkPiNum(abc_ntk_aig)) && + (((pObj1) = pabc::Abc_NtkPi(abc_ntk_aig, i)), 1); + i++) { + sig pi = aig.create_pi(); + signals.insert(std::pair(pObj1->Id, pi)); + unsigned int a = pi.index; + pi_names.insert(std::pair(a, pabc::Abc_ObjName(pObj1))); + } + + // process the also network node + int j, k; + pabc::Abc_Obj_t *pNode, *pFanin1; + for (i = 0; (i < pabc::Vec_PtrSize((abc_ntk_aig)->vObjs)) && + (((pNode) = pabc::Abc_NtkObj(abc_ntk_aig, i)), 1); + i++) { + if ((pNode) == NULL || !pabc::Abc_ObjIsNode(pNode)) { + } else { + std::vector children; + children.clear(); + + if (pabc::Abc_AigNodeIsConst(pabc::Abc_ObjFanin0(pNode))) + children.push_back((pNode->fCompl0) + ? aig.create_not(aig.get_constant(true)) + : aig.get_constant(true)); + else + children.push_back( + (pNode->fCompl0) + ? aig.create_not(signals[pabc::Abc_ObjFaninId0(pNode)]) + : signals[pabc::Abc_ObjFaninId0(pNode)]); + + if (pabc::Abc_AigNodeIsConst(pabc::Abc_ObjFanin1(pNode))) + children.push_back((pNode->fCompl1) + ? aig.create_not(aig.get_constant(true)) + : aig.get_constant(true)); + else + children.push_back( + (pNode->fCompl1) + ? aig.create_not(signals[pabc::Abc_ObjFaninId1(pNode)]) + : signals[pabc::Abc_ObjFaninId1(pNode)]); + + assert(children.size() == 2u); + signals.insert(std::pair( + pNode->Id, aig.create_and(children[0], children[1]))); + } + } + + // process the also network primary output + int m, n, n1; + pabc::Abc_Obj_t *pObj2, *pFanin2; + for (i = 0; (i < pabc::Abc_NtkPoNum(abc_ntk_aig)) && + (((pObj2) = pabc::Abc_NtkPo(abc_ntk_aig, i)), 1); + i++) { + if (pabc::Abc_AigNodeIsConst(pabc::Abc_ObjFanin0(pObj2))) { + auto const o = (pObj2->fCompl0) ? aig.create_not(aig.get_constant(true)) + : aig.get_constant(true); + aig.create_po(o); + } else { + auto const o = (pObj2->fCompl0) + ? aig.create_not(signals[pabc::Abc_ObjFaninId0(pObj2)]) + : signals[pabc::Abc_ObjFaninId0(pObj2)]; + aig.create_po(o); + } + po_names.insert(std::pair(i, pabc::Abc_ObjName(pObj2))); + } + + aig_new = aig; + return aig_new; +} + +pabc::Abc_Ntk_t* mockturtle2abc_x(const mockturtle::xmg_network& xmg) { + // Convert xmg network to the netlist network in abc + const int MAX = 3; + bool const0_created = false; + std::string constant_name = "1\'b0"; + // Initialize the abc network + abc_ntk_ = pabc::Abc_NtkAlloc(pabc::ABC_NTK_NETLIST, pabc::ABC_FUNC_SOP, 1); + abc_ntk_->pName = strdup("netlist"); + + mockturtle::topo_view topo_xmg{xmg}; + + // create abc network + // process the abc network primary input + topo_xmg.foreach_pi([&](auto const& n, auto index) { + const auto index1 = topo_xmg.node_to_index(n); + unsigned int a = index1; + std::string input_name = pi_names[a]; + pabc::Io_ReadCreatePi(abc_ntk_, (char*)(input_name.c_str())); + }); + + // process the abc network node + topo_xmg.foreach_node([&](auto n) { + if (topo_xmg.is_constant(n) || topo_xmg.is_pi(n)) return true; + + auto func = topo_xmg.node_function(n); + std::string node_name = std::to_string(topo_xmg.node_to_index(n)); + + std::vector children; + children.clear(); + char* pNamesIn[MAX]; + topo_xmg.foreach_fanin(n, [&](auto const& f) { + auto index = topo_xmg.node_to_index(topo_xmg.get_node(f)); + std::string fanin_name = std::to_string(index); + + if (topo_xmg.is_pi(topo_xmg.get_node(f))) { + unsigned int b = index; + children.push_back(pi_names[b]); + } else if (topo_xmg.is_constant(topo_xmg.get_node(f))) { + // process the abc network constant node + if (!const0_created) { + pabc::Abc_NtkFindOrCreateNet(abc_ntk_, + (char*)(constant_name.c_str())); + pabc::Io_ReadCreateConst(abc_ntk_, (char*)(constant_name.c_str()), 0); + const0_created = true; + } + children.push_back(constant_name); + } else + children.push_back(fanin_name); + }); + + for (size_t i = 0; i < children.size(); i++) + pNamesIn[i] = (char*)(children[i].c_str()); + + pabc::Abc_Obj_t* pNode; + pNode = pabc::Io_ReadCreateNode(abc_ntk_, (char*)(node_name.c_str()), + pNamesIn, topo_xmg.fanin_size(n)); + std::string abc_func = ""; + int count = 0; + for (auto cube : kitty::isop(func)) { + topo_xmg.foreach_fanin(n, [&](auto const& f, auto index) { + if (cube.get_mask(index) && topo_xmg.is_complemented(f)) + cube.flip_bit(index); + }); + + for (auto i = 0u; i < topo_xmg.fanin_size(n); ++i) + abc_func += (cube.get_mask(i) ? (cube.get_bit(i) ? '1' : '0') : '-'); + abc_func += " 1\n"; + count++; + } + + pabc::Abc_ObjSetData( + pNode, pabc::Abc_SopRegister((pabc::Mem_Flex_t*)abc_ntk_->pManFunc, + abc_func.c_str())); + return true; + }); + + // process the abc network primary output + std::vector children1; + topo_xmg.foreach_po([&](auto const& f, auto index) { + auto a = topo_xmg.node_to_index(topo_xmg.get_node(f)); + std::string fanin_name = std::to_string(a); + + pabc::Io_ReadCreatePo(abc_ntk_, (char*)(po_names[index].c_str())); + + if (topo_xmg.is_complemented(f)) { + children1.clear(); + if (topo_xmg.is_pi(topo_xmg.get_node(f))) { + unsigned int b = a; + children1.push_back(pi_names[b]); + } else if (topo_xmg.is_constant(topo_xmg.get_node(f))) { + // process the abc network constant node + if (!const0_created) { + pabc::Abc_NtkFindOrCreateNet(abc_ntk_, + (char*)(constant_name.c_str())); + pabc::Io_ReadCreateConst(abc_ntk_, (char*)(constant_name.c_str()), 0); + const0_created = true; + } + children1.push_back(constant_name); + } else + children1.push_back(fanin_name); + pabc::Io_ReadCreateInv(abc_ntk_, (char*)(children1[0].c_str()), + (char*)(po_names[index].c_str())); + } else { + children1.clear(); + if (topo_xmg.is_pi(topo_xmg.get_node(f))) { + unsigned int b = a; + children1.push_back(pi_names[b]); + } else if (topo_xmg.is_constant(topo_xmg.get_node(f))) { + // process the abc network constant node + if (!const0_created) { + pabc::Abc_NtkFindOrCreateNet(abc_ntk_, + (char*)(constant_name.c_str())); + pabc::Io_ReadCreateConst(abc_ntk_, (char*)(constant_name.c_str()), 0); + const0_created = true; + } + children1.push_back(constant_name); + } else + children1.push_back(fanin_name); + + pabc::Io_ReadCreateBuf(abc_ntk_, (char*)(children1[0].c_str()), + (char*)(po_names[index].c_str())); + } + }); + + return abc_ntk_; +} + +pabc::Abc_Ntk_t* mockturtle2abc_a(const mockturtle::aig_network& aig) { + // Convert aig network to the netlist network in abc + const int MAX = 3; + bool const0_created = false; + std::string constant_name = "1\'b0"; + // Initialize the abc network + abc_ntk_ = pabc::Abc_NtkAlloc(pabc::ABC_NTK_NETLIST, pabc::ABC_FUNC_SOP, 1); + abc_ntk_->pName = strdup("netlist"); + + mockturtle::topo_view topo_aig{aig}; + + // create abc network + // process the abc network primary input + topo_aig.foreach_pi([&](auto const& n, auto index) { + const auto index1 = topo_aig.node_to_index(n); + unsigned int a = index1; + std::string input_name = pi_names[a]; + pabc::Io_ReadCreatePi(abc_ntk_, (char*)(input_name.c_str())); + }); + + // process the abc network node + topo_aig.foreach_node([&](auto n) { + if (topo_aig.is_constant(n) || topo_aig.is_pi(n)) return true; + + auto func = topo_aig.node_function(n); + std::string node_name = std::to_string(topo_aig.node_to_index(n)); + + std::vector children; + children.clear(); + char* pNamesIn[MAX]; + topo_aig.foreach_fanin(n, [&](auto const& f) { + auto index = topo_aig.node_to_index(topo_aig.get_node(f)); + std::string fanin_name = std::to_string(index); + + if (topo_aig.is_pi(topo_aig.get_node(f))) { + unsigned int b = index; + children.push_back(pi_names[b]); + } else if (topo_aig.is_constant(topo_aig.get_node(f))) { + // process the abc network constant node + if (!const0_created) { + pabc::Abc_NtkFindOrCreateNet(abc_ntk_, + (char*)(constant_name.c_str())); + pabc::Io_ReadCreateConst(abc_ntk_, (char*)(constant_name.c_str()), 0); + const0_created = true; + } + children.push_back(constant_name); + } else + children.push_back(fanin_name); + }); + + for (size_t i = 0; i < children.size(); i++) + pNamesIn[i] = (char*)(children[i].c_str()); + + pabc::Abc_Obj_t* pNode; + pNode = pabc::Io_ReadCreateNode(abc_ntk_, (char*)(node_name.c_str()), + pNamesIn, topo_aig.fanin_size(n)); + std::string abc_func = ""; + int count = 0; + for (auto cube : kitty::isop(func)) { + topo_aig.foreach_fanin(n, [&](auto const& f, auto index) { + if (cube.get_mask(index) && topo_aig.is_complemented(f)) + cube.flip_bit(index); + }); + + for (auto i = 0u; i < topo_aig.fanin_size(n); ++i) + abc_func += (cube.get_mask(i) ? (cube.get_bit(i) ? '1' : '0') : '-'); + abc_func += " 1\n"; + count++; + } + + pabc::Abc_ObjSetData( + pNode, pabc::Abc_SopRegister((pabc::Mem_Flex_t*)abc_ntk_->pManFunc, + abc_func.c_str())); + return true; + }); + + // process the abc network primary output + std::vector children1; + topo_aig.foreach_po([&](auto const& f, auto index) { + auto a = topo_aig.node_to_index(topo_aig.get_node(f)); + std::string fanin_name = std::to_string(a); + + pabc::Io_ReadCreatePo(abc_ntk_, (char*)(po_names[index].c_str())); + + if (topo_aig.is_complemented(f)) { + children1.clear(); + if (topo_aig.is_pi(topo_aig.get_node(f))) { + unsigned int b = a; + children1.push_back(pi_names[b]); + } else if (topo_aig.is_constant(topo_aig.get_node(f))) { + // process the abc network constant node + if (!const0_created) { + pabc::Abc_NtkFindOrCreateNet(abc_ntk_, + (char*)(constant_name.c_str())); + pabc::Io_ReadCreateConst(abc_ntk_, (char*)(constant_name.c_str()), 0); + const0_created = true; + } + children1.push_back(constant_name); + } else + children1.push_back(fanin_name); + pabc::Io_ReadCreateInv(abc_ntk_, (char*)(children1[0].c_str()), + (char*)(po_names[index].c_str())); + } else { + children1.clear(); + if (topo_aig.is_pi(topo_aig.get_node(f))) { + unsigned int b = a; + children1.push_back(pi_names[b]); + } else if (topo_aig.is_constant(topo_aig.get_node(f))) { + // process the abc network constant node + if (!const0_created) { + pabc::Abc_NtkFindOrCreateNet(abc_ntk_, + (char*)(constant_name.c_str())); + pabc::Io_ReadCreateConst(abc_ntk_, (char*)(constant_name.c_str()), 0); + const0_created = true; + } + children1.push_back(constant_name); + } else + children1.push_back(fanin_name); + + pabc::Io_ReadCreateBuf(abc_ntk_, (char*)(children1[0].c_str()), + (char*)(po_names[index].c_str())); + } + }); + + return abc_ntk_; +} + +pabc::Abc_Ntk_t* mockturtle2abc_m(const mockturtle::mig_network& mig) { + // Convert mig network to the netlist network in abc + const int MAX = 3; + bool const0_created = false; + std::string constant_name = "1\'b0"; + // Initialize the abc network + abc_ntk_ = pabc::Abc_NtkAlloc(pabc::ABC_NTK_NETLIST, pabc::ABC_FUNC_SOP, 1); + abc_ntk_->pName = strdup("netlist"); + + mockturtle::topo_view topo_mig{mig}; + + // create abc network + // process the abc network primary input + topo_mig.foreach_pi([&](auto const& n, auto index) { + const auto index1 = topo_mig.node_to_index(n); + unsigned int a = index1; + std::string input_name = pi_names[a]; + pabc::Io_ReadCreatePi(abc_ntk_, (char*)(input_name.c_str())); + }); + + // process the abc network node + topo_mig.foreach_node([&](auto n) { + if (topo_mig.is_constant(n) || topo_mig.is_pi(n)) return true; + + auto func = topo_mig.node_function(n); + std::string node_name = std::to_string(topo_mig.node_to_index(n)); + + std::vector children; + children.clear(); + char* pNamesIn[MAX]; + topo_mig.foreach_fanin(n, [&](auto const& f) { + auto index = topo_mig.node_to_index(topo_mig.get_node(f)); + std::string fanin_name = std::to_string(index); + + if (topo_mig.is_pi(topo_mig.get_node(f))) { + unsigned int b = index; + children.push_back(pi_names[b]); + } else if (topo_mig.is_constant(topo_mig.get_node(f))) { + // process the abc network constant node + if (!const0_created) { + pabc::Abc_NtkFindOrCreateNet(abc_ntk_, + (char*)(constant_name.c_str())); + pabc::Io_ReadCreateConst(abc_ntk_, (char*)(constant_name.c_str()), 0); + const0_created = true; + } + children.push_back(constant_name); + } else + children.push_back(fanin_name); + }); + + for (size_t i = 0; i < children.size(); i++) + pNamesIn[i] = (char*)(children[i].c_str()); + + pabc::Abc_Obj_t* pNode; + pNode = pabc::Io_ReadCreateNode(abc_ntk_, (char*)(node_name.c_str()), + pNamesIn, topo_mig.fanin_size(n)); + std::string abc_func = ""; + int count = 0; + for (auto cube : kitty::isop(func)) { + topo_mig.foreach_fanin(n, [&](auto const& f, auto index) { + if (cube.get_mask(index) && topo_mig.is_complemented(f)) + cube.flip_bit(index); + }); + + for (auto i = 0u; i < topo_mig.fanin_size(n); ++i) + abc_func += (cube.get_mask(i) ? (cube.get_bit(i) ? '1' : '0') : '-'); + abc_func += " 1\n"; + count++; + } + + pabc::Abc_ObjSetData( + pNode, pabc::Abc_SopRegister((pabc::Mem_Flex_t*)abc_ntk_->pManFunc, + abc_func.c_str())); + return true; + }); + + // process the abc network primary output + std::vector children1; + topo_mig.foreach_po([&](auto const& f, auto index) { + auto a = topo_mig.node_to_index(topo_mig.get_node(f)); + std::string fanin_name = std::to_string(a); + + pabc::Io_ReadCreatePo(abc_ntk_, (char*)(po_names[index].c_str())); + + if (topo_mig.is_complemented(f)) { + children1.clear(); + if (topo_mig.is_pi(topo_mig.get_node(f))) { + unsigned int b = a; + children1.push_back(pi_names[b]); + } else if (topo_mig.is_constant(topo_mig.get_node(f))) { + // process the abc network constant node + if (!const0_created) { + pabc::Abc_NtkFindOrCreateNet(abc_ntk_, + (char*)(constant_name.c_str())); + pabc::Io_ReadCreateConst(abc_ntk_, (char*)(constant_name.c_str()), 0); + const0_created = true; + } + children1.push_back(constant_name); + } else + children1.push_back(fanin_name); + pabc::Io_ReadCreateInv(abc_ntk_, (char*)(children1[0].c_str()), + (char*)(po_names[index].c_str())); + } else { + children1.clear(); + if (topo_mig.is_pi(topo_mig.get_node(f))) { + unsigned int b = a; + children1.push_back(pi_names[b]); + } else if (topo_mig.is_constant(topo_mig.get_node(f))) { + // process the abc network constant node + if (!const0_created) { + pabc::Abc_NtkFindOrCreateNet(abc_ntk_, + (char*)(constant_name.c_str())); + pabc::Io_ReadCreateConst(abc_ntk_, (char*)(constant_name.c_str()), 0); + const0_created = true; + } + children1.push_back(constant_name); + } else + children1.push_back(fanin_name); + + pabc::Io_ReadCreateBuf(abc_ntk_, (char*)(children1[0].c_str()), + (char*)(po_names[index].c_str())); + } + }); + + return abc_ntk_; +} + +pabc::Abc_Ntk_t* mockturtle2abc_g(const mockturtle::xag_network& xag) { + // Convert xag network to the netlist network in abc + const int MAX = 3; + bool const0_created = false; + std::string constant_name = "1\'b0"; + // Initialize the abc network + abc_ntk_ = pabc::Abc_NtkAlloc(pabc::ABC_NTK_NETLIST, pabc::ABC_FUNC_SOP, 1); + abc_ntk_->pName = strdup("netlist"); + + mockturtle::topo_view topo_xag{xag}; + + // create abc network + // process the abc network primary input + topo_xag.foreach_pi([&](auto const& n, auto index) { + const auto index1 = topo_xag.node_to_index(n); + unsigned int a = index1; + std::string input_name = pi_names[a]; + pabc::Io_ReadCreatePi(abc_ntk_, (char*)(input_name.c_str())); + }); + + // process the abc network node + topo_xag.foreach_node([&](auto n) { + if (topo_xag.is_constant(n) || topo_xag.is_pi(n)) return true; + + auto func = topo_xag.node_function(n); + std::string node_name = std::to_string(topo_xag.node_to_index(n)); + + std::vector children; + children.clear(); + char* pNamesIn[MAX]; + topo_xag.foreach_fanin(n, [&](auto const& f) { + auto index = topo_xag.node_to_index(topo_xag.get_node(f)); + std::string fanin_name = std::to_string(index); + + if (topo_xag.is_pi(topo_xag.get_node(f))) { + unsigned int b = index; + children.push_back(pi_names[b]); + } else if (topo_xag.is_constant(topo_xag.get_node(f))) { + // process the abc network constant node + if (!const0_created) { + pabc::Abc_NtkFindOrCreateNet(abc_ntk_, + (char*)(constant_name.c_str())); + pabc::Io_ReadCreateConst(abc_ntk_, (char*)(constant_name.c_str()), 0); + const0_created = true; + } + children.push_back(constant_name); + } else + children.push_back(fanin_name); + }); + + for (size_t i = 0; i < children.size(); i++) + pNamesIn[i] = (char*)(children[i].c_str()); + + pabc::Abc_Obj_t* pNode; + pNode = pabc::Io_ReadCreateNode(abc_ntk_, (char*)(node_name.c_str()), + pNamesIn, topo_xag.fanin_size(n)); + std::string abc_func = ""; + int count = 0; + for (auto cube : kitty::isop(func)) { + topo_xag.foreach_fanin(n, [&](auto const& f, auto index) { + if (cube.get_mask(index) && topo_xag.is_complemented(f)) + cube.flip_bit(index); + }); + + for (auto i = 0u; i < topo_xag.fanin_size(n); ++i) + abc_func += (cube.get_mask(i) ? (cube.get_bit(i) ? '1' : '0') : '-'); + abc_func += " 1\n"; + count++; + } + + pabc::Abc_ObjSetData( + pNode, pabc::Abc_SopRegister((pabc::Mem_Flex_t*)abc_ntk_->pManFunc, + abc_func.c_str())); + return true; + }); + + // process the abc network primary output + std::vector children1; + topo_xag.foreach_po([&](auto const& f, auto index) { + auto a = topo_xag.node_to_index(topo_xag.get_node(f)); + std::string fanin_name = std::to_string(a); + + pabc::Io_ReadCreatePo(abc_ntk_, (char*)(po_names[index].c_str())); + + if (topo_xag.is_complemented(f)) { + children1.clear(); + if (topo_xag.is_pi(topo_xag.get_node(f))) { + unsigned int b = a; + children1.push_back(pi_names[b]); + } else if (topo_xag.is_constant(topo_xag.get_node(f))) { + // process the abc network constant node + if (!const0_created) { + pabc::Abc_NtkFindOrCreateNet(abc_ntk_, + (char*)(constant_name.c_str())); + pabc::Io_ReadCreateConst(abc_ntk_, (char*)(constant_name.c_str()), 0); + const0_created = true; + } + children1.push_back(constant_name); + } else + children1.push_back(fanin_name); + pabc::Io_ReadCreateInv(abc_ntk_, (char*)(children1[0].c_str()), + (char*)(po_names[index].c_str())); + } else { + children1.clear(); + if (topo_xag.is_pi(topo_xag.get_node(f))) { + unsigned int b = a; + children1.push_back(pi_names[b]); + } else if (topo_xag.is_constant(topo_xag.get_node(f))) { + // process the abc network constant node + if (!const0_created) { + pabc::Abc_NtkFindOrCreateNet(abc_ntk_, + (char*)(constant_name.c_str())); + pabc::Io_ReadCreateConst(abc_ntk_, (char*)(constant_name.c_str()), 0); + const0_created = true; + } + children1.push_back(constant_name); + } else + children1.push_back(fanin_name); + + pabc::Io_ReadCreateBuf(abc_ntk_, (char*)(children1[0].c_str()), + (char*)(po_names[index].c_str())); + } + }); + + return abc_ntk_; +} + +pabc::Abc_Ntk_t* mockturtle2abc_l(const mockturtle::klut_network& klut) { + // Convert klut network to the netlist network in abc + const int MAX = 3; + bool const0_created = false; + std::string constant_name = "1\'b0"; + // Initialize the abc network + abc_ntk_ = pabc::Abc_NtkAlloc(pabc::ABC_NTK_NETLIST, pabc::ABC_FUNC_SOP, 1); + abc_ntk_->pName = strdup("netlist"); + + mockturtle::topo_view topo_klut{klut}; + + // create abc network + // process the abc network primary input + topo_klut.foreach_pi([&](auto const& n, auto index) { + const auto index1 = topo_klut.node_to_index(n); + unsigned int a = index1; + std::string input_name = pi_names[a]; + pabc::Io_ReadCreatePi(abc_ntk_, (char*)(input_name.c_str())); + }); + + // process the abc network node + topo_klut.foreach_node([&](auto n) { + if (topo_klut.is_constant(n) || topo_klut.is_pi(n)) return true; + + auto func = topo_klut.node_function(n); + std::string node_name = std::to_string(topo_klut.node_to_index(n)); + + std::vector children; + children.clear(); + char* pNamesIn[MAX]; + topo_klut.foreach_fanin(n, [&](auto const& f) { + auto index = topo_klut.node_to_index(topo_klut.get_node(f)); + std::string fanin_name = std::to_string(index); + + if (topo_klut.is_pi(topo_klut.get_node(f))) { + unsigned int b = index; + children.push_back(pi_names[b]); + } else if (topo_klut.is_constant(topo_klut.get_node(f))) { + // process the abc network constant node + if (!const0_created) { + pabc::Abc_NtkFindOrCreateNet(abc_ntk_, + (char*)(constant_name.c_str())); + pabc::Io_ReadCreateConst(abc_ntk_, (char*)(constant_name.c_str()), 0); + const0_created = true; + } + children.push_back(constant_name); + } else + children.push_back(fanin_name); + }); + + for (size_t i = 0; i < children.size(); i++) + pNamesIn[i] = (char*)(children[i].c_str()); + + pabc::Abc_Obj_t* pNode; + pNode = pabc::Io_ReadCreateNode(abc_ntk_, (char*)(node_name.c_str()), + pNamesIn, topo_klut.fanin_size(n)); + std::string abc_func = ""; + int count = 0; + for (auto cube : kitty::isop(func)) { + topo_klut.foreach_fanin(n, [&](auto const& f, auto index) { + if (cube.get_mask(index) && topo_klut.is_complemented(f)) + cube.flip_bit(index); + }); + + for (auto i = 0u; i < topo_klut.fanin_size(n); ++i) + abc_func += (cube.get_mask(i) ? (cube.get_bit(i) ? '1' : '0') : '-'); + abc_func += " 1\n"; + count++; + } + + pabc::Abc_ObjSetData( + pNode, pabc::Abc_SopRegister((pabc::Mem_Flex_t*)abc_ntk_->pManFunc, + abc_func.c_str())); + return true; + }); + + // process the abc network primary output + std::vector children1; + topo_klut.foreach_po([&](auto const& f, auto index) { + auto a = topo_klut.node_to_index(topo_klut.get_node(f)); + std::string fanin_name = std::to_string(a); + + pabc::Io_ReadCreatePo(abc_ntk_, (char*)(po_names[index].c_str())); + + if (topo_klut.is_complemented(f)) { + children1.clear(); + if (topo_klut.is_pi(topo_klut.get_node(f))) { + unsigned int b = a; + children1.push_back(pi_names[b]); + } else if (topo_klut.is_constant(topo_klut.get_node(f))) { + // process the abc network constant node + if (!const0_created) { + pabc::Abc_NtkFindOrCreateNet(abc_ntk_, + (char*)(constant_name.c_str())); + pabc::Io_ReadCreateConst(abc_ntk_, (char*)(constant_name.c_str()), 0); + const0_created = true; + } + children1.push_back(constant_name); + } else + children1.push_back(fanin_name); + pabc::Io_ReadCreateInv(abc_ntk_, (char*)(children1[0].c_str()), + (char*)(po_names[index].c_str())); + } else { + children1.clear(); + if (topo_klut.is_pi(topo_klut.get_node(f))) { + unsigned int b = a; + children1.push_back(pi_names[b]); + } else if (topo_klut.is_constant(topo_klut.get_node(f))) { + // process the abc network constant node + if (!const0_created) { + pabc::Abc_NtkFindOrCreateNet(abc_ntk_, + (char*)(constant_name.c_str())); + pabc::Io_ReadCreateConst(abc_ntk_, (char*)(constant_name.c_str()), 0); + const0_created = true; + } + children1.push_back(constant_name); + } else + children1.push_back(fanin_name); + + pabc::Io_ReadCreateBuf(abc_ntk_, (char*)(children1[0].c_str()), + (char*)(po_names[index].c_str())); + } + }); + + return abc_ntk_; +} +} // namespace phyLS + +#endif diff --git a/src/phyLS.cpp b/src/phyLS.cpp index 9b94b0b..0b38ae2 100644 --- a/src/phyLS.cpp +++ b/src/phyLS.cpp @@ -40,5 +40,12 @@ #include "commands/functional_reduction.hpp" #include "commands/convert_graph.hpp" #include "commands/lutmap.hpp" +#include "commands/abc/read.hpp" +#include "commands/abc/write.hpp" +#include "commands/abc/strash.hpp" +#include "commands/abc/resub.hpp" +#include "commands/abc/fraig.hpp" +#include "commands/abc/&get.hpp" +#include "commands/abc/&fraig.hpp" ALICE_MAIN(phyLS) \ No newline at end of file diff --git a/src/store.hpp b/src/store.hpp index aa90431..8fc0b08 100644 --- a/src/store.hpp +++ b/src/store.hpp @@ -26,6 +26,10 @@ #ifndef STORE_HPP #define STORE_HPP +#include +#include +#include +#include #include #include @@ -40,6 +44,8 @@ #include #include +#include "./core/abc2mockturtle.hpp" + using namespace mockturtle; namespace alice { @@ -500,6 +506,107 @@ ALICE_CONVERT(xmg_network, element, mig_network) { return mig; } +/* ABC aiger */ +ALICE_ADD_STORE(pabc::Abc_Ntk_t *, "abc", "b", "ABC", "ABCs") + +ALICE_DESCRIBE_STORE(pabc::Abc_Ntk_t *, abc) { + const auto name = pabc::Abc_NtkName(abc); + const auto pi_num = pabc::Abc_NtkPiNum(abc); + const auto po_num = pabc::Abc_NtkPoNum(abc); + return fmt::format("{} i/o = {}/{}", name, pi_num, po_num); +} + +ALICE_PRINT_STORE(pabc::Abc_Ntk_t *, os, abc) { + os << "AIG PI/PO = " << pabc::Abc_NtkPiNum(abc) << "/" + << pabc::Abc_NtkPoNum(abc) << "\n"; +} + +ALICE_PRINT_STORE_STATISTICS(pabc::Abc_Ntk_t *, os, abc) { + Abc_NtkPrintStats(abc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1); +} + +ALICE_LOG_STORE_STATISTICS(pabc::Abc_Ntk_t *, abc) { + return {{"name", pabc::Abc_NtkName(abc)}, + {"inputs", pabc::Abc_NtkPiNum(abc)}, + {"outputs", pabc::Abc_NtkPoNum(abc)}, + {"nodes", pabc::Abc_NtkNodeNum(abc)}, + {"levels", pabc::Abc_NtkLevel(abc)}}; +} + +ALICE_CONVERT(pabc::Abc_Ntk_t *, element, aig_network) { + pabc::Abc_Ntk_t *pNtk = element; + aig_network aig = phyLS::abc2mockturtle_a(pNtk); + return aig; +} + +ALICE_CONVERT(xmg_network, element, pabc::Abc_Ntk_t *) { + xmg_network xmg = element; + pabc::Abc_Ntk_t *pNtk = phyLS::mockturtle2abc_x(xmg); + return pNtk; +} + +ALICE_CONVERT(aig_network, element, pabc::Abc_Ntk_t *) { + aig_network aig = element; + pabc::Abc_Ntk_t *pNtk = phyLS::mockturtle2abc_a(aig); + return pNtk; +} + +ALICE_CONVERT(mig_network, element, pabc::Abc_Ntk_t *) { + mig_network mig = element; + pabc::Abc_Ntk_t *pNtk = phyLS::mockturtle2abc_m(mig); + return pNtk; +} + +ALICE_CONVERT(xag_network, element, pabc::Abc_Ntk_t *) { + xag_network xag = element; + pabc::Abc_Ntk_t *pNtk = phyLS::mockturtle2abc_g(xag); + return pNtk; +} + +ALICE_CONVERT(klut_network, element, pabc::Abc_Ntk_t *) { + klut_network klut = element; + pabc::Abc_Ntk_t *pNtk = phyLS::mockturtle2abc_l(klut); + return pNtk; +} + +/* ABC Gia */ +ALICE_ADD_STORE(pabc::Gia_Man_t *, "gia", "i", "GIA", "GIAs") + +ALICE_DESCRIBE_STORE(pabc::Gia_Man_t *, gia) { + const auto name = pabc::Gia_ManName(gia); + const auto pi_num = pabc::Gia_ManPiNum(gia); + const auto po_num = pabc::Gia_ManPoNum(gia); + return fmt::format("{} i/o = {}/{}", name, pi_num, po_num); +} + +ALICE_PRINT_STORE(pabc::Gia_Man_t *, os, gia) { + os << "GIA PI/PO = " << pabc::Gia_ManPiNum(gia) << "/" + << pabc::Gia_ManPoNum(gia) << "\n"; +} + +ALICE_PRINT_STORE_STATISTICS(pabc::Gia_Man_t *, os, gia) { + pabc::Gps_Par_t Pars{}; + pabc::Gia_ManPrintStats(gia, &Pars); +} + +ALICE_LOG_STORE_STATISTICS(pabc::Gia_Man_t *, gia) { + return {{"name", pabc::Gia_ManName(gia)}, + {"inputs", pabc::Gia_ManPiNum(gia)}, + {"outputs", pabc::Gia_ManPoNum(gia)}, + {"nodes", pabc::Gia_ManAndNum(gia)}, + {"levels", pabc::Gia_ManLevelNum(gia)}}; +} + +ALICE_ADD_FILE_TYPE(gia, "Gia"); + +ALICE_READ_FILE(pabc::Gia_Man_t *, gia, filename, cmd) { + return pabc::Gia_AigerRead((char *)filename.c_str(), 0, 0, 0); +} + +ALICE_WRITE_FILE(pabc::Gia_Man_t *, gia, gia, filename, cmd) { + pabc::Gia_AigerWrite(gia, (char *)filename.c_str(), 1, 0, 0); +} + } // namespace alice #endif