add abc as a submodule

pull/1/head
panhongyang 2023-03-14 20:59:24 +08:00
parent 8766dc6ac8
commit 9635c0de3c
14 changed files with 1370 additions and 1 deletions

3
.gitmodules vendored
View File

@ -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

View File

@ -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")

1
lib/abc Submodule

@ -0,0 +1 @@
Subproject commit a5f4841486d4a491913943c5b92167a9e988abac

View File

@ -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)

View File

@ -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<pabc::Gia_Man_t *>().size() == 0u)
std::cerr << "Error: Empty GIA network.\n";
else {
pabc::Gia_Man_t *pNtk, *pTemp;
pNtk = store<pabc::Gia_Man_t *>().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<pabc::Gia_Man_t *>().extend();
store<pabc::Gia_Man_t *>().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

70
src/commands/abc/&get.hpp Normal file
View File

@ -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<pabc::Abc_Ntk_t *>().size() == 0u)
std::cerr << "Error: Empty ABC AIG network\n";
else {
pabc::Abc_Ntk_t *pNtk = store<pabc::Abc_Ntk_t *>().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<pabc::Gia_Man_t *>().extend();
store<pabc::Gia_Man_t *>().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

View File

@ -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<pabc::Abc_Ntk_t *>().size() == 0u)
std::cerr << "Error: Empty ABC AIG network.\n";
else {
pabc::Abc_Ntk_t *pNtk, *pNtkRes;
pNtk = store<pabc::Abc_Ntk_t *>().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<pabc::Abc_Ntk_t *>().extend();
store<pabc::Abc_Ntk_t *>().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

64
src/commands/abc/read.hpp Normal file
View File

@ -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<pabc::Abc_Ntk_t *>().extend();
store<pabc::Abc_Ntk_t *>().current() = pNtk;
}
private:
std::string file_name;
};
ALICE_ADD_COMMAND(read, "I/O")
} // namespace alice
#endif

View File

@ -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<pabc::Abc_Ntk_t *>().size() == 0u)
std::cerr << "Error: Empty ABC AIG network\n";
else {
pabc::Abc_Ntk_t *pNtk = store<pabc::Abc_Ntk_t *>().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<pabc::Abc_Ntk_t *>().extend();
store<pabc::Abc_Ntk_t *>().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

View File

@ -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<pabc::Abc_Ntk_t *>().size() == 0u)
std::cerr << "Error: Empty ABC AIG network\n";
else {
pabc::Abc_Ntk_t *pNtk = store<pabc::Abc_Ntk_t *>().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<pabc::Abc_Ntk_t *>().extend();
store<pabc::Abc_Ntk_t *>().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

View File

@ -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<pabc::Abc_Ntk_t *>().size() == 0u)
std::cerr << "Error: Empty network.\n";
else {
auto pNtk = store<pabc::Abc_Ntk_t *>().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

751
src/core/abc2mockturtle.hpp Normal file
View File

@ -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 <base/abc/abc.h>
#include <base/io/ioAbc.h>
#include <map>
#include <mockturtle/mockturtle.hpp>
#include <string>
#include <vector>
namespace phyLS {
mockturtle::aig_network aig_new;
pabc::Abc_Ntk_t* abc_ntk_;
std::map<int, std::string> pi_names;
std::map<int, std::string> 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<int, sig> 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<int, sig>(pObj1->Id, pi));
unsigned int a = pi.index;
pi_names.insert(std::pair<int, std::string>(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<sig> 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<int, sig>(
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<int, std::string>(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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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

View File

@ -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)

View File

@ -26,6 +26,10 @@
#ifndef STORE_HPP
#define STORE_HPP
#include <aig/gia/gia.h>
#include <aig/gia/giaAig.h>
#include <base/abc/abc.h>
#include <base/io/ioAbc.h>
#include <fmt/format.h>
#include <alice/alice.hpp>
@ -40,6 +44,8 @@
#include <mockturtle/mockturtle.hpp>
#include <mockturtle/views/names_view.hpp>
#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