version 3 with more ABC commands
parent
90b00aa4bc
commit
1f63163872
Binary file not shown.
|
@ -2,7 +2,7 @@
|
||||||
* Copyright (C) 2023 */
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file get.hpp
|
* @file &get.hpp
|
||||||
*
|
*
|
||||||
* @brief converts the current network into GIA
|
* @brief converts the current network into GIA
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
/* LogicMap: powerful technology-mapping tool in logic synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file &if.hpp
|
||||||
|
*
|
||||||
|
* @brief performs FPGA mapping of the GIA
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ABC_GIA_IF_HPP
|
||||||
|
#define ABC_GIA_IF_HPP
|
||||||
|
|
||||||
|
#include "aig/gia/gia.h"
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
|
||||||
|
using namespace mockturtle;
|
||||||
|
using namespace std;
|
||||||
|
using namespace pabc;
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class Aif_command : public command {
|
||||||
|
public:
|
||||||
|
explicit Aif_command(const environment::ptr &env)
|
||||||
|
: command(env, "performs FPGA mapping of the AIG") {
|
||||||
|
add_flag("--verbose, -v", "print the information");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void execute() {
|
||||||
|
clock_t begin, end;
|
||||||
|
double totalTime;
|
||||||
|
begin = clock();
|
||||||
|
Gia_Man_t *pGia, *pNew;
|
||||||
|
If_Par_t Pars, *pPars = &Pars;
|
||||||
|
Gia_ManSetIfParsDefault(pPars);
|
||||||
|
if (store<pabc::Gia_Man_t *>().size() == 0u)
|
||||||
|
std::cerr << "Error: Empty GIA network.\n";
|
||||||
|
else {
|
||||||
|
pGia = store<pabc::Gia_Man_t *>().current();
|
||||||
|
// set defaults
|
||||||
|
pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut();
|
||||||
|
if (Gia_ManHasMapping(pGia)) {
|
||||||
|
printf("Current AIG has mapping. Run \"&st\".\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pPars->nLutSize == -1) {
|
||||||
|
if (pPars->pLutLib == NULL) {
|
||||||
|
printf("The LUT library is not given.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pPars->nLutSize = pPars->pLutLib->LutMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pPars->nLutSize < 2 || pPars->nLutSize > IF_MAX_LUTSIZE) {
|
||||||
|
printf("Incorrect LUT size (%d).\n", pPars->nLutSize);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pPars->nCutsMax < 1 || pPars->nCutsMax >= (1 << 12)) {
|
||||||
|
printf("Incorrect number of cuts.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the new network
|
||||||
|
pNew = Gia_ManPerformMapping(pGia, pPars);
|
||||||
|
if (pNew == NULL) {
|
||||||
|
printf("Mapping of GIA has failed..\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
store<pabc::Gia_Man_t *>().extend();
|
||||||
|
store<pabc::Gia_Man_t *>().current() = pNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(Aif, "Gia")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,72 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file &nf.hpp
|
||||||
|
*
|
||||||
|
* @brief performs technology-independent mapping of the GIA
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ABC_NF_HPP
|
||||||
|
#define ABC_NF_HPP
|
||||||
|
|
||||||
|
#include "aig/gia/gia.h"
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
#include "aig/gia/giaNf.c"
|
||||||
|
|
||||||
|
using namespace mockturtle;
|
||||||
|
using namespace std;
|
||||||
|
using namespace pabc;
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class Anf_command : public command {
|
||||||
|
public:
|
||||||
|
explicit Anf_command(const environment::ptr &env)
|
||||||
|
: command(env, "performs technology mapping of the GIA network") {
|
||||||
|
add_flag("--verbose, -v", "print the information");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void execute() {
|
||||||
|
clock_t begin, end;
|
||||||
|
double totalTime;
|
||||||
|
|
||||||
|
begin = clock();
|
||||||
|
char Buffer[200];
|
||||||
|
pabc::Jf_Par_t Pars, *pPars = &Pars;
|
||||||
|
pabc::Gia_Man_t *pGia, *pNew;
|
||||||
|
pabc::Nf_ManSetDefaultPars(pPars);
|
||||||
|
|
||||||
|
if (store<pabc::Gia_Man_t *>().size() == 0u)
|
||||||
|
std::cerr << "Error: Empty GIA network.\n";
|
||||||
|
else {
|
||||||
|
pGia = store<pabc::Gia_Man_t *>().current();
|
||||||
|
if (pabc::Abc_FrameReadLibGen() == NULL) {
|
||||||
|
pabc::Abc_Print(-1, "Current library is not available.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pNew = pabc::Nf_ManPerformMapping(pGia, pPars);
|
||||||
|
store<pabc::Gia_Man_t *>().extend();
|
||||||
|
store<pabc::Gia_Man_t *>().current() = pNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(Anf, "Gia")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,105 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
/**
|
||||||
|
* @file amap.hpp
|
||||||
|
*
|
||||||
|
* @brief performs technology-independent mapping of the AIG
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ABC_AMAP_HPP
|
||||||
|
#define ABC_AMAP_HPP
|
||||||
|
|
||||||
|
#include "map/amap/amap.h"
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
#include "base/abci/abcSweep.c"
|
||||||
|
|
||||||
|
using namespace mockturtle;
|
||||||
|
using namespace std;
|
||||||
|
using namespace pabc;
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class amap_command : public command {
|
||||||
|
public:
|
||||||
|
explicit amap_command(const environment::ptr &env)
|
||||||
|
: command(env, "performs standard cell mapping of the current network") {
|
||||||
|
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 {
|
||||||
|
Abc_Ntk_t *pNtk = store<pabc::Abc_Ntk_t *>().current();
|
||||||
|
|
||||||
|
// set defaults
|
||||||
|
Amap_Par_t Pars, *pPars = &Pars;
|
||||||
|
Abc_Ntk_t *pNtkRes;
|
||||||
|
int fSweep = 0;
|
||||||
|
Amap_ManSetDefaultParams(pPars);
|
||||||
|
|
||||||
|
if (!Abc_NtkIsStrash(pNtk)) {
|
||||||
|
pNtk = Abc_NtkStrash(pNtk, 0, 0, 0);
|
||||||
|
if (pNtk == NULL) {
|
||||||
|
printf("Strashing before mapping has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pNtk = Abc_NtkBalance(pNtkRes = pNtk, 0, 0, 1);
|
||||||
|
Abc_NtkDelete(pNtkRes);
|
||||||
|
if (pNtk == NULL) {
|
||||||
|
printf("Balancing before mapping has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("The network was strashed and balanced before mapping.\n");
|
||||||
|
// get the new network
|
||||||
|
pNtkRes = Abc_NtkDarAmap(pNtk, pPars);
|
||||||
|
if (pNtkRes == NULL) {
|
||||||
|
Abc_NtkDelete(pNtk);
|
||||||
|
printf("Mapping has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Abc_NtkDelete(pNtk);
|
||||||
|
} else {
|
||||||
|
// get the new network
|
||||||
|
pNtkRes = Abc_NtkDarAmap(pNtk, pPars);
|
||||||
|
if (pNtkRes == NULL) {
|
||||||
|
printf("Mapping has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fSweep) {
|
||||||
|
Abc_NtkFraigSweep(pNtkRes, 0, 0, 0, 0);
|
||||||
|
if (Abc_NtkHasMapping(pNtkRes)) {
|
||||||
|
pNtkRes = Abc_NtkDupDfs(pNtk = pNtkRes);
|
||||||
|
Abc_NtkDelete(pNtk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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(amap, "ABC")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,107 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
/**
|
||||||
|
* @file balance.hpp
|
||||||
|
*
|
||||||
|
* @brief transforms the current network into a well-balanced AIG
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ABC_BALANCE_HPP
|
||||||
|
#define ABC_BALANCE_HPP
|
||||||
|
|
||||||
|
// #include "base/abci/abc.c"
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
#include "base/abci/abcBalance.c"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace mockturtle;
|
||||||
|
using namespace pabc;
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class abalance_command : public command {
|
||||||
|
public:
|
||||||
|
explicit abalance_command(const environment::ptr &env)
|
||||||
|
: command(env,
|
||||||
|
"transforms the current network into a well-balanced 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 AIG network.\n";
|
||||||
|
else {
|
||||||
|
Abc_Ntk_t *pNtk, *pNtkRes, *pNtkTemp;
|
||||||
|
pNtk = store<pabc::Abc_Ntk_t *>().current();
|
||||||
|
int c;
|
||||||
|
int fDuplicate;
|
||||||
|
int fSelective;
|
||||||
|
int fUpdateLevel;
|
||||||
|
int fExor;
|
||||||
|
int fVerbose;
|
||||||
|
// set defaults
|
||||||
|
fDuplicate = 0;
|
||||||
|
fSelective = 0;
|
||||||
|
fUpdateLevel = 1;
|
||||||
|
fExor = 0;
|
||||||
|
fVerbose = 0;
|
||||||
|
Extra_UtilGetoptReset();
|
||||||
|
if (pNtk == NULL) {
|
||||||
|
Abc_Print(-1, "Empty network.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// get the new network
|
||||||
|
if (Abc_NtkIsStrash(pNtk)) {
|
||||||
|
if (fExor)
|
||||||
|
pNtkRes = Abc_NtkBalanceExor(pNtk, fUpdateLevel, fVerbose);
|
||||||
|
else
|
||||||
|
pNtkRes = Abc_NtkBalance(pNtk, fDuplicate, fSelective, fUpdateLevel);
|
||||||
|
} else {
|
||||||
|
pNtkTemp = Abc_NtkStrash(pNtk, 0, 0, 0);
|
||||||
|
if (pNtkTemp == NULL) {
|
||||||
|
Abc_Print(-1, "Strashing before balancing has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fExor)
|
||||||
|
pNtkRes = Abc_NtkBalanceExor(pNtkTemp, fUpdateLevel, fVerbose);
|
||||||
|
else
|
||||||
|
pNtkRes =
|
||||||
|
Abc_NtkBalance(pNtkTemp, fDuplicate, fSelective, fUpdateLevel);
|
||||||
|
Abc_NtkDelete(pNtkTemp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if balancing worked
|
||||||
|
if (pNtkRes == NULL) {
|
||||||
|
Abc_Print(-1, "Balancing has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// replace the current network
|
||||||
|
// Abc_FrameReplaceCurrentNetwork(pAbc, pNtkRes);
|
||||||
|
|
||||||
|
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(abalance, "ABC")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -77,7 +77,7 @@ class acec_command : public command {
|
||||||
string filename_2;
|
string filename_2;
|
||||||
};
|
};
|
||||||
|
|
||||||
ALICE_ADD_COMMAND(acec, "Verification")
|
ALICE_ADD_COMMAND(acec, "ABC")
|
||||||
|
|
||||||
} // namespace alice
|
} // namespace alice
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,290 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
/**
|
||||||
|
* @file compress2rs.hpp
|
||||||
|
*
|
||||||
|
* @brief combination optimization script
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMPRESS2RS_HPP
|
||||||
|
#define COMPRESS2RS_HPP
|
||||||
|
|
||||||
|
// #include "base/abci/abc.c"
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
// #include "base/abci/abcDar.c"
|
||||||
|
#include "base/abci/abcResub.c"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace mockturtle;
|
||||||
|
using namespace pabc;
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class compress2rs_command : public command {
|
||||||
|
public:
|
||||||
|
explicit compress2rs_command(const environment::ptr &env)
|
||||||
|
: command(env, "usage: synthesis scripts.") {
|
||||||
|
add_flag("--verbose, -v", "print the information");
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
void Dar_ManDefaultResParams(Dar_ResPar_t *pPars) {
|
||||||
|
memset(pPars, 0, sizeof(Dar_ResPar_t));
|
||||||
|
pPars->nCutsMax = 8; // 8
|
||||||
|
pPars->nNodesMax = 1;
|
||||||
|
pPars->nLevelsOdc = 0;
|
||||||
|
pPars->fUpdateLevel = 1;
|
||||||
|
pPars->fUseZeros = 0;
|
||||||
|
pPars->fVerbose = 0;
|
||||||
|
pPars->fVeryVerbose = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Aig_Man_t *Dar_ManCompress2rs(Abc_Ntk_t *pNtk, Aig_Man_t *pAig, int fBalance,
|
||||||
|
int fUpdateLevel, int fFanout, int fPower,
|
||||||
|
int fVerbose, int nMinSaved) {
|
||||||
|
// alias compress2rs "b -l; rs -K 6 -l; rw -l; rs -K 6 -N 2 -l; rf -l; rs
|
||||||
|
// -K 8 -l; b -l; rs -K 8 -N 2 -l; rw -l; rs -K 10 -l; rwz -l; rs -K 10
|
||||||
|
// -N 2 -l; b -l; rs -K 12 -l; rfz -l; rs -K 12 -N 2 -l; rwz -l; b -l"
|
||||||
|
Aig_Man_t *pTemp;
|
||||||
|
Abc_Ntk_t *pNtkAig;
|
||||||
|
Dar_RwrPar_t ParsRwr, *pParsRwr = &ParsRwr;
|
||||||
|
Dar_RefPar_t ParsRef, *pParsRef = &ParsRef;
|
||||||
|
Dar_ResPar_t ParsRes, *pParsRes = &ParsRes;
|
||||||
|
|
||||||
|
Dar_ManDefaultRwrParams(pParsRwr);
|
||||||
|
Dar_ManDefaultRefParams(pParsRef);
|
||||||
|
Dar_ManDefaultResParams(pParsRes);
|
||||||
|
|
||||||
|
pParsRwr->fUpdateLevel = fUpdateLevel;
|
||||||
|
pParsRef->fUpdateLevel = fUpdateLevel;
|
||||||
|
|
||||||
|
pParsRes->fUpdateLevel = fUpdateLevel;
|
||||||
|
// pParsRes->nCutsMax = nCutsMax;
|
||||||
|
// pParsRes->nNodesMax = nNodesMax;
|
||||||
|
|
||||||
|
pParsRwr->fFanout = fFanout;
|
||||||
|
pParsRwr->fPower = fPower;
|
||||||
|
pParsRwr->fVerbose = 0; // fVerbose;
|
||||||
|
pParsRef->fVerbose = 0; // fVerbose;
|
||||||
|
pParsRes->fVerbose = 0; // fVerbose;
|
||||||
|
|
||||||
|
pAig = Aig_ManDupDfs(pAig);
|
||||||
|
if (fVerbose) printf("Starting: "), Aig_ManPrintStats(pAig);
|
||||||
|
// b -l;
|
||||||
|
fUpdateLevel = 0;
|
||||||
|
pAig = Dar_ManBalance(pTemp = pAig, fUpdateLevel);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Balance: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 6 -l;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 6;
|
||||||
|
pParsRes->fUpdateLevel = 0;
|
||||||
|
pParsRes->nNodesMax = 1;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rw -l;
|
||||||
|
pParsRwr->fUpdateLevel = 0;
|
||||||
|
Dar_ManRewrite(pAig, pParsRwr);
|
||||||
|
pAig = Aig_ManDupDfs(pTemp = pAig);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Rewrite: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 6 -N 2 -l;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 6;
|
||||||
|
pParsRes->fUpdateLevel = 0;
|
||||||
|
pParsRes->nNodesMax = 2;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rf -l;
|
||||||
|
pParsRef->fUpdateLevel = 0;
|
||||||
|
Dar_ManRefactor(pAig, pParsRef);
|
||||||
|
pAig = Aig_ManDupDfs(pTemp = pAig);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Refactor: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 8 -l;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 8;
|
||||||
|
pParsRes->fUpdateLevel = 0;
|
||||||
|
pParsRes->nNodesMax = 1;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// b -l;
|
||||||
|
fUpdateLevel = 0;
|
||||||
|
pAig = Dar_ManBalance(pTemp = pAig, fUpdateLevel);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Balance: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 8 -N 2 -l;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 8;
|
||||||
|
pParsRes->fUpdateLevel = 0;
|
||||||
|
pParsRes->nNodesMax = 2;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rw -l;
|
||||||
|
pParsRwr->fUpdateLevel = 0;
|
||||||
|
Dar_ManRewrite(pAig, pParsRwr);
|
||||||
|
pAig = Aig_ManDupDfs(pTemp = pAig);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Rewrite: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 10 -l;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 10;
|
||||||
|
pParsRes->fUpdateLevel = 0;
|
||||||
|
pParsRes->nNodesMax = 1;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rwz -l;
|
||||||
|
pParsRwr->fUpdateLevel = 0;
|
||||||
|
pParsRwr->fUseZeros = 1;
|
||||||
|
Dar_ManRewrite(pAig, pParsRwr);
|
||||||
|
pAig = Aig_ManDupDfs(pTemp = pAig);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Rewrite_zerocost: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 10 -N 2 -l;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 10;
|
||||||
|
pParsRes->fUpdateLevel = 0;
|
||||||
|
pParsRes->nNodesMax = 2;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// b -l;
|
||||||
|
fUpdateLevel = 0;
|
||||||
|
pAig = Dar_ManBalance(pTemp = pAig, fUpdateLevel);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Balance: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 12 -l;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 12;
|
||||||
|
pParsRes->fUpdateLevel = 0;
|
||||||
|
pParsRes->nNodesMax = 1;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rfz -l;
|
||||||
|
pParsRef->fUpdateLevel = 0;
|
||||||
|
pParsRef->fUseZeros = 1;
|
||||||
|
Dar_ManRefactor(pAig, pParsRef);
|
||||||
|
pAig = Aig_ManDupDfs(pTemp = pAig);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Refactor_zerocost: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 12 -N 2 -l;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 12;
|
||||||
|
pParsRes->fUpdateLevel = 0;
|
||||||
|
pParsRes->nNodesMax = 2;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rwz -l;
|
||||||
|
pParsRwr->fUpdateLevel = 0;
|
||||||
|
pParsRwr->fUseZeros = 1;
|
||||||
|
Dar_ManRewrite(pAig, pParsRwr);
|
||||||
|
pAig = Aig_ManDupDfs(pTemp = pAig);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Rewrite_zerocost: "), Aig_ManPrintStats(pAig);
|
||||||
|
// b -l;
|
||||||
|
fUpdateLevel = 0;
|
||||||
|
pAig = Dar_ManBalance(pTemp = pAig, fUpdateLevel);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Balance: "), Aig_ManPrintStats(pAig);
|
||||||
|
return pAig;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void execute() {
|
||||||
|
clock_t begin, end;
|
||||||
|
double totalTime;
|
||||||
|
|
||||||
|
begin = clock();
|
||||||
|
|
||||||
|
if (store<pabc::Abc_Ntk_t *>().size() == 0u)
|
||||||
|
std::cerr << "Error: Empty AIG network.\n";
|
||||||
|
else {
|
||||||
|
Abc_Ntk_t *pNtk, *pNtkAig;
|
||||||
|
pNtk = store<pabc::Abc_Ntk_t *>().current();
|
||||||
|
int fVerbose;
|
||||||
|
int fUpdateLevel;
|
||||||
|
int fFanout;
|
||||||
|
int fPower;
|
||||||
|
int c;
|
||||||
|
int fBalance;
|
||||||
|
int nMinSaved;
|
||||||
|
// set defaults
|
||||||
|
fVerbose = 0;
|
||||||
|
fUpdateLevel = 0;
|
||||||
|
fFanout = 1;
|
||||||
|
fPower = 0;
|
||||||
|
fBalance = 0;
|
||||||
|
nMinSaved = 1;
|
||||||
|
Extra_UtilGetoptReset();
|
||||||
|
if (is_set("verbose")) {
|
||||||
|
fVerbose = 1;
|
||||||
|
}
|
||||||
|
if (pNtk == NULL) {
|
||||||
|
Abc_Print(-1, "Empty network.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Abc_NtkIsStrash(pNtk)) {
|
||||||
|
Abc_Print(-1, "This command works only for strashed networks.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Aig_Man_t *pMan, *pTemp;
|
||||||
|
abctime clk;
|
||||||
|
assert(Abc_NtkIsStrash(pNtk));
|
||||||
|
pMan = Abc_NtkToDar(pNtk, 0, 0);
|
||||||
|
if (pMan == NULL) return;
|
||||||
|
clk = Abc_Clock();
|
||||||
|
pMan = Dar_ManCompress2rs(pNtk, pTemp = pMan, fBalance, fUpdateLevel,
|
||||||
|
fFanout, fPower, fVerbose, nMinSaved);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pMan);
|
||||||
|
Aig_ManStop(pMan);
|
||||||
|
if (pNtkAig == NULL) {
|
||||||
|
Abc_Print(-1, "Command has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
store<pabc::Abc_Ntk_t *>().extend();
|
||||||
|
store<pabc::Abc_Ntk_t *>().current() = pNtkAig;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(compress2rs, "ABC")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,86 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
/**
|
||||||
|
* @file dc2.hpp
|
||||||
|
*
|
||||||
|
* @brief combination optimization script
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DC2_HPP
|
||||||
|
#define DC2_HPP
|
||||||
|
|
||||||
|
// #include "base/abci/abc.c"
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
// #include "base/abci/abcDar.c"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace mockturtle;
|
||||||
|
using namespace pabc;
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class dc2_command : public command {
|
||||||
|
public:
|
||||||
|
explicit dc2_command(const environment::ptr &env)
|
||||||
|
: command(env, "usage: dc2 [-blfpvh]") {
|
||||||
|
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 AIG network.\n";
|
||||||
|
else {
|
||||||
|
Abc_Ntk_t *pNtk, *pNtkRes;
|
||||||
|
int fBalance, fVerbose, fUpdateLevel, fFanout, fPower, c;
|
||||||
|
pNtk = store<pabc::Abc_Ntk_t *>().current();
|
||||||
|
// set defaults
|
||||||
|
fBalance = 0;
|
||||||
|
fVerbose = 0;
|
||||||
|
fUpdateLevel = 0;
|
||||||
|
fFanout = 1;
|
||||||
|
fPower = 0;
|
||||||
|
Extra_UtilGetoptReset();
|
||||||
|
if (pNtk == NULL) {
|
||||||
|
Abc_Print(-1, "Empty network.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Abc_NtkIsStrash(pNtk)) {
|
||||||
|
Abc_Print(-1, "This command works only for strashed networks.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pNtkRes =
|
||||||
|
Abc_NtkDC2(pNtk, fBalance, fUpdateLevel, fFanout, fPower, fVerbose);
|
||||||
|
if (pNtkRes == NULL) {
|
||||||
|
Abc_Print(-1, "Command has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// replace the current network
|
||||||
|
// Abc_FrameReplaceCurrentNetwork(pAbc, pNtkRes);
|
||||||
|
|
||||||
|
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(dc2, "ABC")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,115 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file if.hpp
|
||||||
|
*
|
||||||
|
* @brief performs FPGA technology mapping of the network
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/08/03
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ABC_IF_HPP
|
||||||
|
#define ABC_IF_HPP
|
||||||
|
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
#include "base/abci/abcIf.c"
|
||||||
|
#include "base/main/main.h"
|
||||||
|
#include "map/if/if.h"
|
||||||
|
|
||||||
|
using namespace mockturtle;
|
||||||
|
using namespace std;
|
||||||
|
using namespace pabc;
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class if_command : public command {
|
||||||
|
public:
|
||||||
|
explicit if_command(const environment::ptr &env)
|
||||||
|
: command(env, "performs FPGA mapping 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 {
|
||||||
|
Abc_Ntk_t *pNtk = store<pabc::Abc_Ntk_t *>().current();
|
||||||
|
// set defaults
|
||||||
|
Abc_Ntk_t *pNtkRes;
|
||||||
|
If_Par_t Pars, *pPars = &Pars;
|
||||||
|
If_ManSetDefaultPars(pPars);
|
||||||
|
pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut();
|
||||||
|
if (pPars->nLutSize == -1) {
|
||||||
|
if (pPars->pLutLib == NULL) {
|
||||||
|
printf("The LUT library is not given.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pPars->nLutSize = pPars->pLutLib->LutMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pPars->nLutSize < 2 || pPars->nLutSize > IF_MAX_LUTSIZE) {
|
||||||
|
printf("Incorrect LUT size (%d).\n", pPars->nLutSize);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pPars->nCutsMax < 1 || pPars->nCutsMax >= (1 << 12)) {
|
||||||
|
printf("Incorrect number of cuts.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Abc_NtkIsStrash(pNtk)) {
|
||||||
|
// strash and balance the network
|
||||||
|
pNtk = Abc_NtkStrash(pNtk, 0, 0, 0);
|
||||||
|
if (pNtk == NULL) {
|
||||||
|
printf("Strashing before FPGA mapping has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pNtk = Abc_NtkBalance(pNtkRes = pNtk, 0, 0, 1);
|
||||||
|
Abc_NtkDelete(pNtkRes);
|
||||||
|
if (pNtk == NULL) {
|
||||||
|
printf("Balancing before FPGA mapping has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Abc_FrameReadFlag("silentmode"))
|
||||||
|
printf(
|
||||||
|
"The network was strashed and balanced before FPGA mapping.\n");
|
||||||
|
// get the new network
|
||||||
|
pNtkRes = Abc_NtkIf(pNtk, pPars);
|
||||||
|
if (pNtkRes == NULL) {
|
||||||
|
Abc_NtkDelete(pNtk);
|
||||||
|
printf("FPGA mapping has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Abc_NtkDelete(pNtk);
|
||||||
|
} else {
|
||||||
|
// get the new network
|
||||||
|
pNtkRes = Abc_NtkIf(pNtk, pPars);
|
||||||
|
if (pNtkRes == NULL) {
|
||||||
|
printf("FPGA mapping has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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(if, "ABC")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,95 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file map.hpp
|
||||||
|
*
|
||||||
|
* @brief performs technology-independent mapping of the AIG
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ABC_MAP_HPP
|
||||||
|
#define ABC_MAP_HPP
|
||||||
|
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
#include "base/abci/abcMap.c"
|
||||||
|
|
||||||
|
using namespace mockturtle;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class map_command : public command {
|
||||||
|
public:
|
||||||
|
explicit map_command(const environment::ptr &env)
|
||||||
|
: command(env, "performs standard cell mapping of the current network") {
|
||||||
|
add_flag("--verbose, -v", "print the information");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void execute() {
|
||||||
|
clock_t begin, end;
|
||||||
|
double totalTime;
|
||||||
|
|
||||||
|
begin = clock();
|
||||||
|
pabc::Abc_Ntk_t *pNtkRes;
|
||||||
|
double DelayTarget;
|
||||||
|
double AreaMulti;
|
||||||
|
double DelayMulti;
|
||||||
|
float LogFan = 0;
|
||||||
|
float Slew = 0; // choose based on the library
|
||||||
|
float Gain = 250;
|
||||||
|
int nGatesMin = 0;
|
||||||
|
int fAreaOnly;
|
||||||
|
int fRecovery;
|
||||||
|
int fSweep;
|
||||||
|
int fSwitching;
|
||||||
|
int fSkipFanout;
|
||||||
|
int fUseProfile;
|
||||||
|
int fUseBuffs;
|
||||||
|
int fVerbose;
|
||||||
|
|
||||||
|
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
|
||||||
|
DelayTarget = -1;
|
||||||
|
AreaMulti = 0;
|
||||||
|
DelayMulti = 0;
|
||||||
|
fAreaOnly = 0;
|
||||||
|
fRecovery = 1;
|
||||||
|
fSweep = 0;
|
||||||
|
fSwitching = 0;
|
||||||
|
fSkipFanout = 0;
|
||||||
|
fUseProfile = 0;
|
||||||
|
fUseBuffs = 0;
|
||||||
|
fVerbose = 0;
|
||||||
|
|
||||||
|
if (is_set("verbose")) fVerbose ^= 1;
|
||||||
|
|
||||||
|
pNtkRes = Abc_NtkMap(pNtk, DelayTarget, AreaMulti, DelayMulti, LogFan,
|
||||||
|
Slew, Gain, nGatesMin, fRecovery, fSwitching,
|
||||||
|
fSkipFanout, fUseProfile, fUseBuffs, fVerbose);
|
||||||
|
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(map, "ABC")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,163 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
/**
|
||||||
|
* @file put.hpp
|
||||||
|
*
|
||||||
|
* @brief converts the current GIA network into Ntk
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ABC_PUT_HPP
|
||||||
|
#define ABC_PUT_HPP
|
||||||
|
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
// #include "base/abci/abcDar.c"
|
||||||
|
// #include "aig/gia/gia.h"
|
||||||
|
#include "aig/gia/giaAig.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace mockturtle;
|
||||||
|
using namespace pabc;
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class put_command : public command {
|
||||||
|
public:
|
||||||
|
explicit put_command(const environment::ptr &env)
|
||||||
|
: command(env, "converts the current network into AIG") {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void execute() {
|
||||||
|
clock_t begin, end;
|
||||||
|
double totalTime;
|
||||||
|
begin = clock();
|
||||||
|
|
||||||
|
Aig_Man_t *pMan;
|
||||||
|
Abc_Ntk_t *pNtk;
|
||||||
|
if (store<pabc::Abc_Ntk_t *>().size() == 0u)
|
||||||
|
std::cerr << "Error: Empty ABC AIG network\n";
|
||||||
|
else
|
||||||
|
pNtk = store<pabc::Abc_Ntk_t *>().current();
|
||||||
|
|
||||||
|
if (store<pabc::Gia_Man_t *>().size() == 0u)
|
||||||
|
std::cerr << "Error: Empty ABC GIA network\n";
|
||||||
|
else {
|
||||||
|
Gia_Man_t *pGia = store<pabc::Gia_Man_t *>().current();
|
||||||
|
|
||||||
|
int fStatusClear = 1;
|
||||||
|
int fUseBuffs = 0;
|
||||||
|
int fFindEnables = 0;
|
||||||
|
int fVerbose = 0;
|
||||||
|
if (fFindEnables)
|
||||||
|
pNtk = Abc_NtkFromMappedGia(pGia, 1, fUseBuffs);
|
||||||
|
else if (Gia_ManHasCellMapping(pGia))
|
||||||
|
pNtk = Abc_NtkFromCellMappedGia(pGia, fUseBuffs);
|
||||||
|
else if (Gia_ManHasMapping(pGia) || pGia->pMuxes)
|
||||||
|
pNtk = Abc_NtkFromMappedGia(pGia, 0, fUseBuffs);
|
||||||
|
else if (Gia_ManHasDangling(pGia) == 0) {
|
||||||
|
pMan = Gia_ManToAig(pGia, 0);
|
||||||
|
pNtk = Abc_NtkFromAigPhase(pMan);
|
||||||
|
pNtk->pName = Extra_UtilStrsav(pMan->pName);
|
||||||
|
Aig_ManStop(pMan);
|
||||||
|
} else {
|
||||||
|
Abc_Ntk_t *pNtkNoCh;
|
||||||
|
Abc_Print(-1, "Transforming AIG with %d choice nodes.\n",
|
||||||
|
Gia_ManEquivCountClasses(pGia));
|
||||||
|
// create network without choices
|
||||||
|
pMan = Gia_ManToAig(pGia, 0);
|
||||||
|
pNtkNoCh = Abc_NtkFromAigPhase(pMan);
|
||||||
|
pNtkNoCh->pName = Extra_UtilStrsav(pMan->pName);
|
||||||
|
Aig_ManStop(pMan);
|
||||||
|
// derive network with choices
|
||||||
|
pMan = Gia_ManToAig(pGia, 1);
|
||||||
|
pNtk = Abc_NtkFromDarChoices(pNtkNoCh, pMan);
|
||||||
|
Abc_NtkDelete(pNtkNoCh);
|
||||||
|
Aig_ManStop(pMan);
|
||||||
|
}
|
||||||
|
// transfer PI names to pNtk
|
||||||
|
// if ( pGia->vNamesIn )
|
||||||
|
// {
|
||||||
|
// Abc_Obj_t * pObj;
|
||||||
|
// int i;
|
||||||
|
// Abc_NtkForEachCi( pNtk, pObj, i ) {
|
||||||
|
// if (i < Vec_PtrSize(pGia->vNamesIn)) {
|
||||||
|
// Nm_ManDeleteIdName(pNtk->pManName, pObj->Id);
|
||||||
|
// Abc_ObjAssignName( pObj, (char
|
||||||
|
// *)Vec_PtrEntry(pGia->vNamesIn, i), NULL );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// transfer PO names to pNtk
|
||||||
|
// if ( pGia->vNamesOut )
|
||||||
|
// {
|
||||||
|
// char pSuffix[100];
|
||||||
|
// Abc_Obj_t * pObj;
|
||||||
|
// int i, nDigits = Abc_Base10Log( Abc_NtkLatchNum(pNtk) );
|
||||||
|
// Abc_NtkForEachCo( pNtk, pObj, i ) {
|
||||||
|
// if (i < Vec_PtrSize(pGia->vNamesOut)) {
|
||||||
|
// Nm_ManDeleteIdName(pNtk->pManName, pObj->Id);
|
||||||
|
// if ( Abc_ObjIsPo(pObj) )
|
||||||
|
// Abc_ObjAssignName( pObj, (char
|
||||||
|
// *)Vec_PtrEntry(pGia->vNamesOut, i), NULL );
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// assert( i >= Abc_NtkPoNum(pNtk) );
|
||||||
|
// sprintf( pSuffix, "_li%0*d", nDigits,
|
||||||
|
// i-Abc_NtkPoNum(pNtk) ); Abc_ObjAssignName( pObj, (char
|
||||||
|
// *)Vec_PtrEntry(pGia->vNamesOut, i), pSuffix );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if ( pGia->vNamesNode )
|
||||||
|
// Abc_Print( 0, "Internal nodes names are not transferred.\n" );
|
||||||
|
|
||||||
|
// // decouple CI/CO with the same name
|
||||||
|
// if ( pGia->vNamesIn || pGia->vNamesOut )
|
||||||
|
// Abc_NtkRedirectCiCo( pNtk );
|
||||||
|
|
||||||
|
// // transfer timing information
|
||||||
|
// if ( pGia->vInArrs || pGia->vOutReqs )
|
||||||
|
// {
|
||||||
|
// Abc_Obj_t * pObj; int i;
|
||||||
|
// Abc_NtkTimeInitialize( pNtk, NULL );
|
||||||
|
// Abc_NtkTimeSetDefaultArrival( pNtk, pGia->DefInArrs,
|
||||||
|
// pGia->DefInArrs ); Abc_NtkTimeSetDefaultRequired( pNtk,
|
||||||
|
// pGia->DefOutReqs, pGia->DefOutReqs ); if ( pGia->vInArrs )
|
||||||
|
// Abc_NtkForEachCi( pNtk, pObj, i )
|
||||||
|
// Abc_NtkTimeSetArrival( pNtk, Abc_ObjId(pObj),
|
||||||
|
// Vec_FltEntry(pGia->vInArrs, i), Vec_FltEntry(pGia->vInArrs,
|
||||||
|
// i) );
|
||||||
|
// if ( pGia->vOutReqs )
|
||||||
|
// Abc_NtkForEachCo( pNtk, pObj, i )
|
||||||
|
// Abc_NtkTimeSetRequired( pNtk, Abc_ObjId(pObj),
|
||||||
|
// Vec_FltEntry(pGia->vOutReqs, i),
|
||||||
|
// Vec_FltEntry(pGia->vOutReqs, i) );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// replace the current network
|
||||||
|
// Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
|
||||||
|
// if ( fStatusClear )
|
||||||
|
// Abc_FrameClearVerifStatus( pAbc );
|
||||||
|
|
||||||
|
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(put, "ABC")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,108 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file read_genlib.hpp
|
||||||
|
*
|
||||||
|
* @brief read the library from a genlib file
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ABC_READ_GENLIB_HPP
|
||||||
|
#define ABC_READ_GENLIB_HPP
|
||||||
|
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
#include "base/io/ioAbc.h"
|
||||||
|
#include "base/main/abcapis.h"
|
||||||
|
#include "base/main/main.h"
|
||||||
|
#include "map/amap/amap.h"
|
||||||
|
#include "map/mapper/mapper.h"
|
||||||
|
#include "map/mio/mio.h"
|
||||||
|
#include "misc/extra/extra.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace mockturtle;
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class read_agenlib_command : public command {
|
||||||
|
public:
|
||||||
|
explicit read_agenlib_command(const environment::ptr &env)
|
||||||
|
: command(env, "read the library from a genlib file") {
|
||||||
|
add_option("filename,-f", file_name, "name of input file");
|
||||||
|
add_flag("--verbose, -v", "print the information");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void execute() {
|
||||||
|
clock_t begin, end;
|
||||||
|
double totalTime;
|
||||||
|
begin = clock();
|
||||||
|
|
||||||
|
pabc::Abc_Frame_t *pAbc;
|
||||||
|
pAbc = pabc::Abc_FrameGetGlobalFrame();
|
||||||
|
|
||||||
|
// set defaults
|
||||||
|
FILE *pFile;
|
||||||
|
// FILE * pOut, * pErr;
|
||||||
|
pabc::Mio_Library_t *pLib;
|
||||||
|
pabc::Amap_Lib_t *pLib2;
|
||||||
|
char *pFileName;
|
||||||
|
char *pExcludeFile = NULL;
|
||||||
|
int fVerbose = 1;
|
||||||
|
|
||||||
|
// get the input file name
|
||||||
|
pFileName = (char *)malloc(file_name.length() + 1);
|
||||||
|
if (pFileName != NULL) {
|
||||||
|
strcpy(pFileName, file_name.c_str());
|
||||||
|
} else {
|
||||||
|
printf("Memory allocation failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// if ( (pFile = pabc::Io_FileOpen( pFileName, "open_path", "r", 0 )) ==
|
||||||
|
// NULL )
|
||||||
|
// {
|
||||||
|
// printf("Cannot open input file \"%s\". ", pFileName );
|
||||||
|
// if ( (pFileName = pabc::Extra_FileGetSimilarName( pFileName,
|
||||||
|
// ".genlib", ".lib", ".scl", ".g", NULL )) )
|
||||||
|
// printf( "Did you mean \"%s\"?", pFileName );
|
||||||
|
// printf( "\n" );
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// fclose( pFile );
|
||||||
|
|
||||||
|
// set the new network
|
||||||
|
pLib = pabc::Mio_LibraryRead(pFileName, NULL, pExcludeFile, fVerbose);
|
||||||
|
if (pLib == NULL) {
|
||||||
|
// fprintf( pErr, "Reading genlib library has failed.\n" );
|
||||||
|
printf("Reading genlib library has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fVerbose)
|
||||||
|
printf("Entered genlib library with %d gates from file \"%s\".\n",
|
||||||
|
Mio_LibraryReadGateNum(pLib), pFileName);
|
||||||
|
|
||||||
|
// prepare libraries
|
||||||
|
pabc::Mio_UpdateGenlib(pLib);
|
||||||
|
|
||||||
|
// replace the current library
|
||||||
|
pLib2 = pabc::Amap_LibReadAndPrepare(pFileName, NULL, 0, 0);
|
||||||
|
if (pLib2 == NULL) {
|
||||||
|
// fprintf( pErr, "Reading second genlib library has failed.\n" );
|
||||||
|
printf("Reading second genlib library has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Abc_FrameSetLibGen2(pLib2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string file_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
ALICE_ADD_COMMAND(read_agenlib, "I/O")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,124 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
/**
|
||||||
|
* @file refactor.hpp
|
||||||
|
*
|
||||||
|
* @brief performs technology-independent refactoring of the AIG
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ABC_REFACTOR_HPP
|
||||||
|
#define ABC_REFACTOR_HPP
|
||||||
|
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
#include "base/abci/abc.c"
|
||||||
|
#include "base/abci/abcRefactor.c"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace mockturtle;
|
||||||
|
using namespace pabc;
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class arefactor_command : public command {
|
||||||
|
public:
|
||||||
|
explicit arefactor_command(const environment::ptr &env)
|
||||||
|
: command(env, "performs technology-independent refactoring 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 AIG network.\n";
|
||||||
|
else {
|
||||||
|
pabc::Abc_Ntk_t *pNtk, *pDup;
|
||||||
|
pNtk = store<pabc::Abc_Ntk_t *>().current();
|
||||||
|
int c, RetValue;
|
||||||
|
int nNodeSizeMax;
|
||||||
|
int nConeSizeMax;
|
||||||
|
int fUpdateLevel;
|
||||||
|
int fUseZeros;
|
||||||
|
int fUseDcs;
|
||||||
|
int fVerbose;
|
||||||
|
int nMinSaved;
|
||||||
|
|
||||||
|
// set defaults
|
||||||
|
nNodeSizeMax = 10;
|
||||||
|
nConeSizeMax = 16;
|
||||||
|
fUpdateLevel = 1;
|
||||||
|
fUseZeros = 0;
|
||||||
|
fUseDcs = 0;
|
||||||
|
fVerbose = 0;
|
||||||
|
nMinSaved = 1;
|
||||||
|
Extra_UtilGetoptReset();
|
||||||
|
if (pNtk == NULL) {
|
||||||
|
Abc_Print(-1, "Empty network.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Abc_NtkIsStrash(pNtk)) {
|
||||||
|
Abc_Print(
|
||||||
|
-1,
|
||||||
|
"This command can only be applied to an AIG (run \"strash\").\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Abc_NtkGetChoiceNum(pNtk)) {
|
||||||
|
Abc_Print(
|
||||||
|
-1,
|
||||||
|
"AIG resynthesis cannot be applied to AIGs with choice nodes.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (nNodeSizeMax > 15) {
|
||||||
|
Abc_Print(-1, "The cone size cannot exceed 15.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fUseDcs && nNodeSizeMax >= nConeSizeMax) {
|
||||||
|
Abc_Print(-1,
|
||||||
|
"For don't-care to work, containing cone should be larger "
|
||||||
|
"than collapsed node.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// modify the current network
|
||||||
|
pDup = Abc_NtkDup(pNtk);
|
||||||
|
RetValue = Abc_NtkRefactor(pNtk, nNodeSizeMax, nMinSaved, nConeSizeMax,
|
||||||
|
fUpdateLevel, fUseZeros, fUseDcs, fVerbose);
|
||||||
|
if (RetValue == -1) {
|
||||||
|
// Abc_FrameReplaceCurrentNetwork(pAbc, pDup);
|
||||||
|
printf(
|
||||||
|
"An error occurred during computation. The original network is "
|
||||||
|
"restored.\n");
|
||||||
|
} else {
|
||||||
|
Abc_NtkDelete(pDup);
|
||||||
|
if (RetValue == 0) {
|
||||||
|
Abc_Print(0, "Refactoring has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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(arefactor, "ABC")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,291 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
/**
|
||||||
|
* @file resyn2rs.hpp
|
||||||
|
*
|
||||||
|
* @brief combination optimization script
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RESYN2RS_HPP
|
||||||
|
#define RESYN2RS_HPP
|
||||||
|
|
||||||
|
// #include "base/abci/abc.c"
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
// #include "base/abci/abcDar.c"
|
||||||
|
// #include "base/abci/abcResub.c"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace mockturtle;
|
||||||
|
using namespace pabc;
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class resyn2rs_command : public command {
|
||||||
|
public:
|
||||||
|
explicit resyn2rs_command(const environment::ptr &env)
|
||||||
|
: command(env, "usage: synthesis scripts.") {
|
||||||
|
add_flag("--verbose, -v", "print the information");
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
void Dar_ManDefaultResParams(Dar_ResPar_t *pPars) {
|
||||||
|
memset(pPars, 0, sizeof(Dar_ResPar_t));
|
||||||
|
pPars->nCutsMax = 8; // 8
|
||||||
|
pPars->nNodesMax = 1;
|
||||||
|
pPars->nLevelsOdc = 0;
|
||||||
|
pPars->fUpdateLevel = 1;
|
||||||
|
pPars->fUseZeros = 0;
|
||||||
|
pPars->fVerbose = 0;
|
||||||
|
pPars->fVeryVerbose = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Aig_Man_t *Dar_ManResyn2rs(Abc_Ntk_t *pNtk, Aig_Man_t *pAig, int fBalance,
|
||||||
|
int fUpdateLevel, int fFanout, int fPower,
|
||||||
|
int fVerbose, int nMinSaved) {
|
||||||
|
// alias resyn2rs "b; rs -K 6; rw; rs -K 6 -N 2; rf; rs -K 8; b; rs -K
|
||||||
|
// 8 -N 2; rw; rs -K 10; rwz; rs -K 10 -N 2; b; rs -K 12; rfz; rs -K 12
|
||||||
|
// -N 2; rwz; b"
|
||||||
|
|
||||||
|
Aig_Man_t *pTemp;
|
||||||
|
Abc_Ntk_t *pNtkAig;
|
||||||
|
Dar_RwrPar_t ParsRwr, *pParsRwr = &ParsRwr;
|
||||||
|
Dar_RefPar_t ParsRef, *pParsRef = &ParsRef;
|
||||||
|
Dar_ResPar_t ParsRes, *pParsRes = &ParsRes;
|
||||||
|
|
||||||
|
Dar_ManDefaultRwrParams(pParsRwr);
|
||||||
|
Dar_ManDefaultRefParams(pParsRef);
|
||||||
|
Dar_ManDefaultResParams(pParsRes);
|
||||||
|
|
||||||
|
pParsRwr->fUpdateLevel = fUpdateLevel;
|
||||||
|
pParsRef->fUpdateLevel = fUpdateLevel;
|
||||||
|
|
||||||
|
pParsRes->fUpdateLevel = fUpdateLevel;
|
||||||
|
// pParsRes->nCutsMax = nCutsMax;
|
||||||
|
// pParsRes->nNodesMax = nNodesMax;
|
||||||
|
|
||||||
|
pParsRwr->fFanout = fFanout;
|
||||||
|
pParsRwr->fPower = fPower;
|
||||||
|
pParsRwr->fVerbose = 0; // fVerbose;
|
||||||
|
pParsRef->fVerbose = 0; // fVerbose;
|
||||||
|
pParsRes->fVerbose = 0; // fVerbose;
|
||||||
|
|
||||||
|
pAig = Aig_ManDupDfs(pAig);
|
||||||
|
if (fVerbose) printf("Starting: "), Aig_ManPrintStats(pAig);
|
||||||
|
// b;
|
||||||
|
fUpdateLevel = 1;
|
||||||
|
pAig = Dar_ManBalance(pTemp = pAig, fUpdateLevel);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Balance: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 6;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 6;
|
||||||
|
pParsRes->fUpdateLevel = 1;
|
||||||
|
pParsRes->nNodesMax = 1;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rw;
|
||||||
|
pParsRwr->fUpdateLevel = 1;
|
||||||
|
Dar_ManRewrite(pAig, pParsRwr);
|
||||||
|
pAig = Aig_ManDupDfs(pTemp = pAig);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Rewrite: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 6 -N 2;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 6;
|
||||||
|
pParsRes->fUpdateLevel = 1;
|
||||||
|
pParsRes->nNodesMax = 2;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rf;
|
||||||
|
pParsRef->fUpdateLevel = 1;
|
||||||
|
Dar_ManRefactor(pAig, pParsRef);
|
||||||
|
pAig = Aig_ManDupDfs(pTemp = pAig);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Refactor: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 8;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 8;
|
||||||
|
pParsRes->fUpdateLevel = 1;
|
||||||
|
pParsRes->nNodesMax = 1;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// b;
|
||||||
|
fUpdateLevel = 1;
|
||||||
|
pAig = Dar_ManBalance(pTemp = pAig, fUpdateLevel);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Balance: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 8 -N 2;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 8;
|
||||||
|
pParsRes->fUpdateLevel = 1;
|
||||||
|
pParsRes->nNodesMax = 2;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rw;
|
||||||
|
pParsRwr->fUpdateLevel = 1;
|
||||||
|
Dar_ManRewrite(pAig, pParsRwr);
|
||||||
|
pAig = Aig_ManDupDfs(pTemp = pAig);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Rewrite: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 10;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 10;
|
||||||
|
pParsRes->fUpdateLevel = 1;
|
||||||
|
pParsRes->nNodesMax = 1;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rwz;
|
||||||
|
pParsRwr->fUpdateLevel = 1;
|
||||||
|
pParsRwr->fUseZeros = 1;
|
||||||
|
Dar_ManRewrite(pAig, pParsRwr);
|
||||||
|
pAig = Aig_ManDupDfs(pTemp = pAig);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Rewrite_zerocost: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 10 -N 2;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 10;
|
||||||
|
pParsRes->fUpdateLevel = 1;
|
||||||
|
pParsRes->nNodesMax = 2;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// b;
|
||||||
|
fUpdateLevel = 1;
|
||||||
|
pAig = Dar_ManBalance(pTemp = pAig, fUpdateLevel);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Balance: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 12;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 12;
|
||||||
|
pParsRes->fUpdateLevel = 1;
|
||||||
|
pParsRes->nNodesMax = 1;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rfz;
|
||||||
|
pParsRef->fUpdateLevel = 1;
|
||||||
|
pParsRef->fUseZeros = 1;
|
||||||
|
Dar_ManRefactor(pAig, pParsRef);
|
||||||
|
pAig = Aig_ManDupDfs(pTemp = pAig);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Refactor_zerocost: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rs -K 12 -N 2;
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pAig);
|
||||||
|
pParsRes->nCutsMax = 12;
|
||||||
|
pParsRes->fUpdateLevel = 1;
|
||||||
|
pParsRes->nNodesMax = 2;
|
||||||
|
Abc_NtkResubstitute(pNtkAig, pParsRes->nCutsMax, pParsRes->nNodesMax,
|
||||||
|
nMinSaved, pParsRes->nLevelsOdc, fUpdateLevel, fVerbose,
|
||||||
|
pParsRes->fVeryVerbose);
|
||||||
|
pAig = Abc_NtkToDar(pNtkAig, 0, 0);
|
||||||
|
if (fVerbose) printf("Resub: "), Aig_ManPrintStats(pAig);
|
||||||
|
// rwz;
|
||||||
|
pParsRwr->fUpdateLevel = 1;
|
||||||
|
pParsRwr->fUseZeros = 1;
|
||||||
|
Dar_ManRewrite(pAig, pParsRwr);
|
||||||
|
pAig = Aig_ManDupDfs(pTemp = pAig);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Rewrite_zerocost: "), Aig_ManPrintStats(pAig);
|
||||||
|
// b;
|
||||||
|
fUpdateLevel = 1;
|
||||||
|
pAig = Dar_ManBalance(pTemp = pAig, fUpdateLevel);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
if (fVerbose) printf("Balance: "), Aig_ManPrintStats(pAig);
|
||||||
|
return pAig;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void execute() {
|
||||||
|
clock_t begin, end;
|
||||||
|
double totalTime;
|
||||||
|
|
||||||
|
begin = clock();
|
||||||
|
|
||||||
|
if (store<pabc::Abc_Ntk_t *>().size() == 0u)
|
||||||
|
std::cerr << "Error: Empty AIG network.\n";
|
||||||
|
else {
|
||||||
|
Abc_Ntk_t *pNtk, *pNtkAig;
|
||||||
|
pNtk = store<pabc::Abc_Ntk_t *>().current();
|
||||||
|
int fVerbose;
|
||||||
|
int fUpdateLevel;
|
||||||
|
int fFanout;
|
||||||
|
int fPower;
|
||||||
|
int c;
|
||||||
|
int fBalance;
|
||||||
|
int nMinSaved;
|
||||||
|
// set defaults
|
||||||
|
fVerbose = 0;
|
||||||
|
fUpdateLevel = 1;
|
||||||
|
fFanout = 1;
|
||||||
|
fPower = 0;
|
||||||
|
fBalance = 0;
|
||||||
|
nMinSaved = 1;
|
||||||
|
Extra_UtilGetoptReset();
|
||||||
|
if (is_set("verbose")) {
|
||||||
|
fVerbose = 1;
|
||||||
|
}
|
||||||
|
if (pNtk == NULL) {
|
||||||
|
Abc_Print(-1, "Empty network.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Abc_NtkIsStrash(pNtk)) {
|
||||||
|
Abc_Print(-1, "This command works only for strashed networks.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Aig_Man_t *pMan, *pTemp;
|
||||||
|
abctime clk;
|
||||||
|
assert(Abc_NtkIsStrash(pNtk));
|
||||||
|
pMan = Abc_NtkToDar(pNtk, 0, 0);
|
||||||
|
if (pMan == NULL) return;
|
||||||
|
clk = Abc_Clock();
|
||||||
|
pMan = Dar_ManResyn2rs(pNtk, pTemp = pMan, fBalance, fUpdateLevel,
|
||||||
|
fFanout, fPower, fVerbose, nMinSaved);
|
||||||
|
Aig_ManStop(pTemp);
|
||||||
|
pNtkAig = Abc_NtkFromDar(pNtk, pMan);
|
||||||
|
Aig_ManStop(pMan);
|
||||||
|
if (pNtkAig == NULL) {
|
||||||
|
Abc_Print(-1, "Command has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
store<pabc::Abc_Ntk_t *>().extend();
|
||||||
|
store<pabc::Abc_Ntk_t *>().current() = pNtkAig;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(resyn2rs, "ABC")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,111 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
/**
|
||||||
|
* @file rewrite.hpp
|
||||||
|
*
|
||||||
|
* @brief performs technology-independent rewriting of the AIG
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ABC_REWRITE_HPP
|
||||||
|
#define ABC_REWRITE_HPP
|
||||||
|
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
#include "base/abci/abcRewrite.c"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace mockturtle;
|
||||||
|
using namespace pabc;
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class arewrite_command : public command {
|
||||||
|
public:
|
||||||
|
explicit arewrite_command(const environment::ptr &env)
|
||||||
|
: command(env, "performs technology-independent rewriting 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 AIG network.\n";
|
||||||
|
else {
|
||||||
|
Abc_Ntk_t *pNtk, *pDup;
|
||||||
|
pNtk = store<pabc::Abc_Ntk_t *>().current();
|
||||||
|
int c, RetValue;
|
||||||
|
int fUpdateLevel;
|
||||||
|
int fPrecompute;
|
||||||
|
int fUseZeros;
|
||||||
|
int fVerbose;
|
||||||
|
int fVeryVerbose;
|
||||||
|
int fPlaceEnable;
|
||||||
|
|
||||||
|
// set defaults
|
||||||
|
fUpdateLevel = 1;
|
||||||
|
fUseZeros = 0;
|
||||||
|
fVerbose = 0;
|
||||||
|
fVeryVerbose = 0;
|
||||||
|
fPlaceEnable = 0;
|
||||||
|
Extra_UtilGetoptReset();
|
||||||
|
|
||||||
|
if (pNtk == NULL) {
|
||||||
|
Abc_Print(-1, "Empty network.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Abc_NtkIsStrash(pNtk)) {
|
||||||
|
Abc_Print(
|
||||||
|
-1,
|
||||||
|
"This command can only be applied to an AIG (run \"strash\").\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Abc_NtkGetChoiceNum(pNtk)) {
|
||||||
|
Abc_Print(
|
||||||
|
-1,
|
||||||
|
"AIG resynthesis cannot be applied to AIGs with choice nodes.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// modify the current network
|
||||||
|
pDup = Abc_NtkDup(pNtk);
|
||||||
|
RetValue = Abc_NtkRewrite(pNtk, fUpdateLevel, fUseZeros, fVerbose,
|
||||||
|
fVeryVerbose, fPlaceEnable);
|
||||||
|
if (RetValue == -1) {
|
||||||
|
// Abc_FrameReplaceCurrentNetwork(pAbc, pDup);
|
||||||
|
printf(
|
||||||
|
"An error occurred during computation. The original network is "
|
||||||
|
"restored.\n");
|
||||||
|
} else {
|
||||||
|
Abc_NtkDelete(pDup);
|
||||||
|
if (RetValue == 0) {
|
||||||
|
Abc_Print(0, "Rewriting has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(arewrite, "ABC")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,84 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
/**
|
||||||
|
* @file sop.hpp
|
||||||
|
*
|
||||||
|
* @brief converts node functions to SOP
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SOP_HPP
|
||||||
|
#define SOP_HPP
|
||||||
|
|
||||||
|
// #include "base/abci/abc.c"
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
#include "base/abc/abcFunc.c"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace mockturtle;
|
||||||
|
using namespace pabc;
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class sop_command : public command {
|
||||||
|
public:
|
||||||
|
explicit sop_command(const environment::ptr &env)
|
||||||
|
: command(env, "converts node functions to SOP") {
|
||||||
|
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 AIG network.\n";
|
||||||
|
else {
|
||||||
|
Abc_Ntk_t *pNtk;
|
||||||
|
pNtk = store<pabc::Abc_Ntk_t *>().current();
|
||||||
|
int c, fCubeSort = 1, fMode = -1, nCubeLimit = 1000000;
|
||||||
|
// set defaults
|
||||||
|
Extra_UtilGetoptReset();
|
||||||
|
|
||||||
|
if (pNtk == NULL) {
|
||||||
|
Abc_Print(-1, "Empty network.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Abc_NtkIsLogic(pNtk)) {
|
||||||
|
Abc_Print(-1,
|
||||||
|
"Converting to SOP is possible only for logic networks.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!fCubeSort && Abc_NtkHasBdd(pNtk) &&
|
||||||
|
!Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY, 0)) {
|
||||||
|
Abc_Print(-1, "Converting to SOP has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Abc_NtkToSop(pNtk, fMode, nCubeLimit)) {
|
||||||
|
Abc_Print(-1, "Converting to SOP has failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(sop, "ABC")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,5 +1,5 @@
|
||||||
/* phyLS: Advanced Logic Synthesis and Optimization tool
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
* Copyright (C) 2019-2021 Ningbo University, Ningbo, China */
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file exact_lut.hpp
|
* @file exact_lut.hpp
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* phyLS: Advanced Logic Synthesis and Optimization tool
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
* Copyright (C) 2019-2021 Ningbo University, Ningbo, China */
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file lutrw.hpp
|
* @file lutrw.hpp
|
||||||
|
|
|
@ -48,6 +48,7 @@ class fr_command : public command {
|
||||||
double totalTime;
|
double totalTime;
|
||||||
|
|
||||||
functional_reduction_params ps;
|
functional_reduction_params ps;
|
||||||
|
ps.max_iterations = 0;
|
||||||
if (is_set("--filename")) ps.pattern_filename = filename;
|
if (is_set("--filename")) ps.pattern_filename = filename;
|
||||||
if (is_set("--tfi_node")) ps.max_TFI_nodes = max_tfi_node;
|
if (is_set("--tfi_node")) ps.max_TFI_nodes = max_tfi_node;
|
||||||
if (is_set("--pattern")) ps.save_patterns = "pattern.log";
|
if (is_set("--pattern")) ps.save_patterns = "pattern.log";
|
||||||
|
@ -94,7 +95,7 @@ class fr_command : public command {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int max_tfi_node = 500;
|
int max_tfi_node = 10000;
|
||||||
string filename = "pattern.log";
|
string filename = "pattern.log";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,515 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file ps2.hpp
|
||||||
|
*
|
||||||
|
* @brief Show statistics in the stored network
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PS2_HPP
|
||||||
|
#define PS2_HPP
|
||||||
|
#include <../core/ps2.hpp>
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
using namespace mockturtle;
|
||||||
|
class ps2_command : public command {
|
||||||
|
public:
|
||||||
|
explicit ps2_command(const environment::ptr& env)
|
||||||
|
: command(env, "Show statistics in the stored network.") {
|
||||||
|
add_flag("--aig,-a", "Display stats for stored AIG");
|
||||||
|
add_flag("--mig,-m", "Display stats for stored MIG");
|
||||||
|
add_flag("--xag,-g", "Display stats for stored XAG");
|
||||||
|
add_flag("--xmg,-x", "Display stats for stored XMG");
|
||||||
|
add_flag("--criti,-c", "Display critical path node index and gate");
|
||||||
|
add_flag("--fanout,-f", "Display fanout histogram");
|
||||||
|
add_flag("--cone,-o", "Dispaly logic cones from PO to PI(only for AIG)");
|
||||||
|
add_flag("--level,-l", "Display level histigram");
|
||||||
|
add_flag("--skip,-k", "Display skip histogram");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename network>
|
||||||
|
void dump_stats(std::string name) {
|
||||||
|
if (store<network>().empty()) {
|
||||||
|
env->err() << "[e] " << name << " network not stored\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto ntk = store<network>().current();
|
||||||
|
mockturtle::depth_view dag_depth{ntk};
|
||||||
|
|
||||||
|
/*critical_path*/
|
||||||
|
phyLS::critical_node_view<mockturtle::names_view<network>> critical{ntk};
|
||||||
|
auto critical_path = critical.get_critical_path();
|
||||||
|
auto critical_nums = critical.get_critical_nums();
|
||||||
|
phyLS::function_counts counts;
|
||||||
|
for (auto curr_node : critical_path) {
|
||||||
|
update_counts(counts, ntk, curr_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*fanin_histogram*/
|
||||||
|
mockturtle::fanout_view<network> fanout{ntk};
|
||||||
|
uint32_t times = 0;
|
||||||
|
fanout.foreach_node([&](auto node) {
|
||||||
|
bool pure = true;
|
||||||
|
fanout.foreach_fanin(node, [&](auto fi) {
|
||||||
|
uint32_t focount = 0;
|
||||||
|
auto node = fanout.get_node(fi);
|
||||||
|
fanout.foreach_fanout(node, [&](auto fo) { focount++; });
|
||||||
|
bool isolated_fanin = (focount == 1) ? 1 : 0;
|
||||||
|
pure = pure && (fanout.is_constant(node) || isolated_fanin);
|
||||||
|
});
|
||||||
|
if (!pure) times++;
|
||||||
|
});
|
||||||
|
|
||||||
|
/*fanout_histogram*/
|
||||||
|
std::vector<int> fanout_vec;
|
||||||
|
double average_fanout = 0;
|
||||||
|
fanout.foreach_node([&](auto node) {
|
||||||
|
uint32_t foc = 0;
|
||||||
|
if (ntk.is_constant(node)) return;
|
||||||
|
fanout.foreach_fanout(node, [&](auto fo) { foc++; });
|
||||||
|
fanout_vec.emplace_back(foc);
|
||||||
|
if (foc > max_fanout) {
|
||||||
|
max_fanout = foc;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
int po = 0;
|
||||||
|
fanout.foreach_po([&](auto o) { po++; });
|
||||||
|
average_fanout = std::accumulate(fanout_vec.begin(), fanout_vec.end(), 0.0,
|
||||||
|
[](double acc, int i) {
|
||||||
|
return acc + static_cast<double>(i);
|
||||||
|
}) /
|
||||||
|
(fanout_vec.size() - 1 - po);
|
||||||
|
|
||||||
|
/*function_stats*/
|
||||||
|
phyLS::function_counts counts1 = phyLS::node_functions(ntk);
|
||||||
|
|
||||||
|
/*skip_histogram*/
|
||||||
|
std::vector<uint32_t> skip_histogram(dag_depth.depth(), 0);
|
||||||
|
uint32_t mismatch_levels = 0;
|
||||||
|
fanout.foreach_node([&](auto node) {
|
||||||
|
uint32_t last_level = 0;
|
||||||
|
bool mismatched = false;
|
||||||
|
fanout.foreach_fanout(node, [&](auto f) {
|
||||||
|
if (last_level != 0 && last_level != dag_depth.level(f)) {
|
||||||
|
mismatched = true;
|
||||||
|
}
|
||||||
|
last_level = dag_depth.level(f);
|
||||||
|
uint32_t skip = dag_depth.level(f) - dag_depth.level(node);
|
||||||
|
skip_histogram[skip]++;
|
||||||
|
});
|
||||||
|
if (mismatched) {
|
||||||
|
mismatch_levels++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
int max_skip = 0;
|
||||||
|
double average_skip = 0.0;
|
||||||
|
double dividend = 0.0;
|
||||||
|
double divisor = 0.0;
|
||||||
|
for (int i = 0; i < skip_histogram.size(); i++) {
|
||||||
|
dividend += i * skip_histogram[i];
|
||||||
|
divisor += skip_histogram[i];
|
||||||
|
}
|
||||||
|
average_skip = dividend / divisor;
|
||||||
|
max_skip = skip_histogram.size() - 1;
|
||||||
|
|
||||||
|
env->out() << "************************************************************"
|
||||||
|
"*******************\n"
|
||||||
|
<< "* Statistic information "
|
||||||
|
" *\n"
|
||||||
|
<< "************************************************************"
|
||||||
|
"*******************\n"
|
||||||
|
<< std::setw(2) << std::left << " " << std::setw(70) << std::left
|
||||||
|
<< "Total size of critical path nodes : " << std::setw(5)
|
||||||
|
<< std::left << critical_path.size() << "\n"
|
||||||
|
<< std::setw(2) << std::left << " " << std::setw(70) << std::left
|
||||||
|
<< "Number of critical paths : " << std::setw(5) << std::left
|
||||||
|
<< critical_nums << "\n"
|
||||||
|
<< std::setw(2) << std::left << " " << std::setw(70) << std::left
|
||||||
|
<< "Number of pure nodes (at least one child node has multiple "
|
||||||
|
"fanouts) : "
|
||||||
|
<< std::setw(5) << std::left << times << "\n"
|
||||||
|
<< "------------------------------------------------------------"
|
||||||
|
"-------------------\n"
|
||||||
|
<< " +Node fanout : "
|
||||||
|
<< "\n"
|
||||||
|
<< std::setw(3) << std::left << " "
|
||||||
|
<< "| Max Fanout | = " << max_fanout << std::setw(10) << " "
|
||||||
|
<< "| Average Fanout | = " << average_fanout << "\n"
|
||||||
|
<< "------------------------------------------------------------"
|
||||||
|
"-------------------\n"
|
||||||
|
<< " +Function_statistic : "
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(61) << ""
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
std::cout << std::setw(3) << " "
|
||||||
|
<< "| " << std::left << std::setw(4) << "Name"
|
||||||
|
<< " |" << std::setw(4) << "MAJ"
|
||||||
|
<< " |" << std::setw(4) << "AND"
|
||||||
|
<< " |" << std::setw(4) << "OR"
|
||||||
|
<< " |" << std::setw(4) << "XOR3"
|
||||||
|
<< " |" << std::setw(4) << "XOR"
|
||||||
|
<< " |" << std::setw(4) << "XNOR"
|
||||||
|
<< " |" << std::setw(7) << "Unknown"
|
||||||
|
<< " |" << std::setw(7) << "Input"
|
||||||
|
<< " |" << std::endl;
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(61) << ""
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
std::cout
|
||||||
|
<< std::setw(3) << " "
|
||||||
|
<< "| " << std::left << std::setw(4) << "nums"
|
||||||
|
<< " |" << std::setw(4)
|
||||||
|
<< (counts1.maj_num == 0 ? " / " : std::to_string(counts1.maj_num))
|
||||||
|
<< " |" << std::setw(4)
|
||||||
|
<< (counts1.and_num == 0 ? " / " : std::to_string(counts1.and_num))
|
||||||
|
<< " |" << std::setw(4)
|
||||||
|
<< (counts1.or_num == 0 ? " / " : std::to_string(counts1.or_num))
|
||||||
|
<< " |" << std::setw(4)
|
||||||
|
<< (counts1.xor3_num == 0 ? " / " : std::to_string(counts1.xor3_num))
|
||||||
|
<< " |" << std::setw(4)
|
||||||
|
<< (counts1.xor_num == 0 ? " / " : std::to_string(counts1.xor_num))
|
||||||
|
<< " |" << std::setw(4)
|
||||||
|
<< (counts1.xnor_num == 0 ? " / " : std::to_string(counts1.xnor_num))
|
||||||
|
<< " |" << std::setw(7)
|
||||||
|
<< (counts1.unknown_num == 0 ? " / "
|
||||||
|
: std::to_string(counts1.unknown_num))
|
||||||
|
<< " |" << std::setw(7)
|
||||||
|
<< (counts1.input_num == 0 ? " / " : std::to_string(counts1.input_num))
|
||||||
|
<< " |" << std::endl;
|
||||||
|
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(61) << ""
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
std::cout << "-------------------------------------------------------------"
|
||||||
|
"------------------\n";
|
||||||
|
std::cout << " +Skip level : "
|
||||||
|
<< "\n"
|
||||||
|
<< " | Number of nodes with inconsistent levels of fanout "
|
||||||
|
"nodes (skip) : "
|
||||||
|
<< mismatch_levels << "\n"
|
||||||
|
<< std::setw(3) << std::left << " "
|
||||||
|
<< "| Max skip Level | = " << max_skip << std::setw(10) << " "
|
||||||
|
<< "| Average skip Level | = " << average_skip << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename network>
|
||||||
|
void critical_path(std::string name) {
|
||||||
|
if (store<network>().empty()) return;
|
||||||
|
auto ntk = store<network>().current();
|
||||||
|
phyLS::critical_node_view<mockturtle::names_view<network>> c{ntk};
|
||||||
|
auto cp = c.get_critical_path();
|
||||||
|
phyLS::function_counts cou;
|
||||||
|
for (auto it : cp) {
|
||||||
|
update_counts(cou, ntk, it);
|
||||||
|
}
|
||||||
|
std::cout << " +Node in critical paths : "
|
||||||
|
<< "\n";
|
||||||
|
for (auto it : cp) {
|
||||||
|
std::cout << std::setw(3) << " ";
|
||||||
|
std::cout << ntk.node_to_index(it) << " ";
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << " +Node type in critical paths : "
|
||||||
|
<< "\n";
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(61) << ""
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
std::cout << std::setw(3) << " "
|
||||||
|
<< "| " << std::left << std::setw(4) << "Name"
|
||||||
|
<< " |" << std::setw(4) << "MAJ"
|
||||||
|
<< " |" << std::setw(4) << "AND"
|
||||||
|
<< " |" << std::setw(4) << "OR"
|
||||||
|
<< " |" << std::setw(4) << "XOR3"
|
||||||
|
<< " |" << std::setw(4) << "XOR"
|
||||||
|
<< " |" << std::setw(4) << "XNOR"
|
||||||
|
<< " |" << std::setw(7) << "Unknown"
|
||||||
|
<< " |" << std::setw(7) << "Input"
|
||||||
|
<< " |" << std::endl;
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(61) << ""
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
std::cout << std::setw(3) << " "
|
||||||
|
<< "| " << std::left << std::setw(4) << "nums"
|
||||||
|
<< " |" << std::setw(4)
|
||||||
|
<< (cou.maj_num == 0 ? " / " : std::to_string(cou.maj_num))
|
||||||
|
<< " |" << std::setw(4)
|
||||||
|
<< (cou.and_num == 0 ? " /" : std::to_string(cou.and_num)) << " |"
|
||||||
|
<< std::setw(4)
|
||||||
|
<< (cou.or_num == 0 ? " /" : std::to_string(cou.or_num)) << " |"
|
||||||
|
<< std::setw(4)
|
||||||
|
<< (cou.xor3_num == 0 ? " /" : std::to_string(cou.xor3_num))
|
||||||
|
<< " |" << std::setw(4)
|
||||||
|
<< (cou.xor_num == 0 ? " /" : std::to_string(cou.xor_num)) << " |"
|
||||||
|
<< std::setw(4)
|
||||||
|
<< (cou.xnor_num == 0 ? " /" : std::to_string(cou.xnor_num))
|
||||||
|
<< " |" << std::setw(7)
|
||||||
|
<< (cou.unknown_num == 0 ? " /" : std::to_string(cou.unknown_num))
|
||||||
|
<< " |" << std::setw(7)
|
||||||
|
<< (cou.input_num == 0 ? " /" : std::to_string(cou.input_num))
|
||||||
|
<< " |" << std::endl;
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(61) << ""
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename network>
|
||||||
|
void fanout_histogram(std::string name) {
|
||||||
|
if (store<network>().empty()) return;
|
||||||
|
auto ntk = store<network>().current();
|
||||||
|
mockturtle::fanout_view<network> fanoutP{ntk};
|
||||||
|
std::vector<uint32_t> fanout_histogram(max_fanout + 1, 0);
|
||||||
|
fanoutP.foreach_node([&](auto node) {
|
||||||
|
uint32_t foc = 0;
|
||||||
|
if (ntk.is_constant(node)) return;
|
||||||
|
fanoutP.foreach_fanout(node, [&](auto fo) { foc++; });
|
||||||
|
if (foc >= fanout_histogram.size() - 1) {
|
||||||
|
fanout_histogram[fanout_histogram.size() - 1]++;
|
||||||
|
} else {
|
||||||
|
fanout_histogram[foc]++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
std::cout << " +Node counts by number of fanouts." << std::endl;
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(22) << ""
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
std::cout << std::setw(3) << " "
|
||||||
|
<< "| " << std::left << std::setw(10) << "Fanout" << std::right
|
||||||
|
<< " | " << std::setw(5) << "Nodes"
|
||||||
|
<< " |" << std::endl;
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(22) << ""
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
for (int i = 0; i < fanout_histogram.size(); i++) {
|
||||||
|
if (fanout_histogram[i] == 0) continue;
|
||||||
|
std::cout << std::setw(3) << " "
|
||||||
|
<< "| " << std::left << std::setw(10) << i << std::right
|
||||||
|
<< " | " << std::setw(5) << fanout_histogram[i] << " |"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(22) << ""
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename network>
|
||||||
|
void get_cones(std::string name) {
|
||||||
|
if (!store<network>().empty()) {
|
||||||
|
auto aig = store<network>().current();
|
||||||
|
// map with number of nodes in each logical cone
|
||||||
|
std::unordered_map<int, int> po_nodes;
|
||||||
|
// number of inputs for each cone
|
||||||
|
std::unordered_map<int, int> po_ins;
|
||||||
|
// first processing logical cones for POs
|
||||||
|
std::cout << " +Logic cones from PO2PI." << std::endl;
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(44)
|
||||||
|
<< "" << std::setfill(' ') << std::endl;
|
||||||
|
std::cout << std::setw(3) << " "
|
||||||
|
<< "| " << std::left << std::setw(10) << "Name" << std::right
|
||||||
|
<< " | " << std::setw(5) << "Index"
|
||||||
|
<< " |" << std::setw(5) << "Nodes"
|
||||||
|
<< " |" << std::setw(5) << "Level"
|
||||||
|
<< " |" << std::setw(6) << "Inputs"
|
||||||
|
<< " |" << std::endl;
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(44)
|
||||||
|
<< "" << std::setfill(' ') << std::endl;
|
||||||
|
for (int outIndex = 0; outIndex < aig.num_pos(); outIndex++) {
|
||||||
|
aig.foreach_node([&](auto node) {
|
||||||
|
// set all nodes as not visited
|
||||||
|
aig._storage->nodes[node].data[1].h1 = 0;
|
||||||
|
});
|
||||||
|
// start counter for a given output index
|
||||||
|
po_nodes.insert(std::make_pair(outIndex, 0));
|
||||||
|
// starting the counter of inputs
|
||||||
|
po_ins.insert(std::make_pair(outIndex, 0));
|
||||||
|
// calculate the index of the node driving the output
|
||||||
|
auto inIdx = aig._storage->outputs[outIndex].data;
|
||||||
|
if (aig._storage->outputs[outIndex].data & 1) {
|
||||||
|
inIdx = aig._storage->outputs[outIndex].data - 1;
|
||||||
|
}
|
||||||
|
inIdx = inIdx >> 1;
|
||||||
|
// call DFS
|
||||||
|
phyLS::compute_cone(aig, inIdx, po_nodes, outIndex, po_ins);
|
||||||
|
aig.foreach_node([&](auto node) {
|
||||||
|
// set all nodes as not visited
|
||||||
|
aig._storage->nodes[node].data[1].h1 = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
int level = phyLS::computeLevel<network>(aig, inIdx);
|
||||||
|
int nodes = 0;
|
||||||
|
int inputs = 0;
|
||||||
|
|
||||||
|
// for each output prints index, nodes, depth and number of inputs,
|
||||||
|
// respectively
|
||||||
|
std::unordered_map<int, int>::iterator it;
|
||||||
|
it = po_nodes.find(outIndex);
|
||||||
|
|
||||||
|
if (it != po_nodes.end()) nodes = it->second;
|
||||||
|
|
||||||
|
std::unordered_map<int, int>::iterator init;
|
||||||
|
init = po_ins.find(outIndex);
|
||||||
|
|
||||||
|
if (it != po_ins.end()) inputs = init->second;
|
||||||
|
|
||||||
|
std::cout << std::setw(3) << " "
|
||||||
|
<< "| " << std::left << std::setw(10) << "Output"
|
||||||
|
<< std::right << " | " << std::setw(5) << outIndex << " |"
|
||||||
|
<< std::setw(5) << nodes << " |" << std::setw(5) << level
|
||||||
|
<< " |" << std::setw(6) << inputs << " |" << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(44)
|
||||||
|
<< "" << std::setfill(' ') << std::endl;
|
||||||
|
} else {
|
||||||
|
env->err() << "There is not an AIG network stored.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ntk>
|
||||||
|
void level_size(std::string name) {
|
||||||
|
if (store<ntk>().empty()) {
|
||||||
|
env->err() << name << " network not stored\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto dag = store<ntk>().current();
|
||||||
|
mockturtle::depth_view dag_view(dag);
|
||||||
|
std::vector<uint32_t> levels(dag_view.depth() + 1, 0);
|
||||||
|
dag_view.foreach_node([&](auto node) { levels[dag_view.level(node)]++; });
|
||||||
|
std::cout << " +Nodes per level." << std::endl;
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(22) << ""
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
std::cout << std::setw(3) << " "
|
||||||
|
<< "| " << std::left << std::setw(10) << "Level" << std::right
|
||||||
|
<< " | " << std::setw(5) << "Nodes"
|
||||||
|
<< " |" << std::endl;
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(22) << ""
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
for (int i = 0; i < levels.size(); i++) {
|
||||||
|
std::cout << std::setw(3) << " "
|
||||||
|
<< "| " << std::left << std::setw(10) << i << std::right
|
||||||
|
<< " | " << std::setw(5) << levels[i] << " |" << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(22) << ""
|
||||||
|
<< std::setfill(' ') << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ntk>
|
||||||
|
void skip_histogram(std::string name) {
|
||||||
|
if (!store<ntk>().empty()) {
|
||||||
|
auto dag = store<ntk>().current();
|
||||||
|
mockturtle::depth_view dag_depth{dag};
|
||||||
|
mockturtle::fanout_view dag_fanout{dag};
|
||||||
|
std::vector<uint32_t> skip_histogram(dag_depth.depth(), 0);
|
||||||
|
uint32_t mismatch_levels = 0;
|
||||||
|
dag_fanout.foreach_node([&](auto node) {
|
||||||
|
uint32_t last_level = 0;
|
||||||
|
bool mismatched = false;
|
||||||
|
dag_fanout.foreach_fanout(node, [&](auto f) {
|
||||||
|
if (last_level != 0 && last_level != dag_depth.level(f)) {
|
||||||
|
mismatched = true;
|
||||||
|
}
|
||||||
|
last_level = dag_depth.level(f);
|
||||||
|
uint32_t skip = dag_depth.level(f) - dag_depth.level(node);
|
||||||
|
skip_histogram[skip]++;
|
||||||
|
});
|
||||||
|
if (mismatched) {
|
||||||
|
mismatch_levels++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
std::cout << " +Nodes whose fanout skip levels : " << mismatch_levels
|
||||||
|
<< std::endl;
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(22)
|
||||||
|
<< "" << std::setfill(' ') << std::endl;
|
||||||
|
std::cout << std::setw(3) << " "
|
||||||
|
<< "| " << std::left << std::setw(11) << "Skip_levels"
|
||||||
|
<< std::right << " | " << std::setw(5) << "Nodes"
|
||||||
|
<< " |" << std::endl;
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(22)
|
||||||
|
<< "" << std::setfill(' ') << std::endl;
|
||||||
|
for (int i = 0; i < skip_histogram.size(); i++) {
|
||||||
|
std::cout << std::setw(3) << " "
|
||||||
|
<< "| " << std::left << std::setw(11) << i << std::right
|
||||||
|
<< " | " << std::setw(5) << skip_histogram[i] << " |"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
std::cout << std::setw(3) << " " << std::setfill('-') << std::setw(22)
|
||||||
|
<< "" << std::setfill(' ') << std::endl;
|
||||||
|
} else {
|
||||||
|
env->err() << "There is not an " << name << " network stored.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void execute() {
|
||||||
|
if (is_set("mig")) {
|
||||||
|
dump_stats<mockturtle::mig_network>("MIG");
|
||||||
|
if (is_set("criti")) {
|
||||||
|
critical_path<mockturtle::mig_network>("MIG");
|
||||||
|
}
|
||||||
|
if (is_set("fanout")) {
|
||||||
|
fanout_histogram<mockturtle::mig_network>("MIG");
|
||||||
|
}
|
||||||
|
if (is_set("level")) {
|
||||||
|
level_size<mockturtle::mig_network>("MIG");
|
||||||
|
}
|
||||||
|
if (is_set("skip")) {
|
||||||
|
skip_histogram<mockturtle::mig_network>("MIG");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (is_set("xag")) {
|
||||||
|
dump_stats<mockturtle::xag_network>("XAG");
|
||||||
|
if (is_set("criti")) {
|
||||||
|
critical_path<mockturtle::xag_network>("XAG");
|
||||||
|
}
|
||||||
|
if (is_set("fanout")) {
|
||||||
|
fanout_histogram<mockturtle::xag_network>("XAG");
|
||||||
|
}
|
||||||
|
if (is_set("level")) {
|
||||||
|
level_size<mockturtle::xag_network>("XAG");
|
||||||
|
}
|
||||||
|
if (is_set("skip")) {
|
||||||
|
skip_histogram<mockturtle::xag_network>("XAG");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (is_set("xmg")) {
|
||||||
|
dump_stats<mockturtle::xmg_network>("XMG");
|
||||||
|
if (is_set("criti")) {
|
||||||
|
critical_path<mockturtle::xmg_network>("XMG");
|
||||||
|
}
|
||||||
|
if (is_set("fanout")) {
|
||||||
|
fanout_histogram<mockturtle::xmg_network>("XMG");
|
||||||
|
}
|
||||||
|
if (is_set("level")) {
|
||||||
|
level_size<mockturtle::xmg_network>("XMG");
|
||||||
|
}
|
||||||
|
if (is_set("skip")) {
|
||||||
|
skip_histogram<mockturtle::xmg_network>("XMG");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (is_set("aig")) {
|
||||||
|
dump_stats<mockturtle::aig_network>("AIG");
|
||||||
|
} else {
|
||||||
|
// default
|
||||||
|
dump_stats<mockturtle::aig_network>("AIG");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_set("criti")) {
|
||||||
|
critical_path<mockturtle::aig_network>("AIG");
|
||||||
|
}
|
||||||
|
if (is_set("fanout")) {
|
||||||
|
fanout_histogram<mockturtle::aig_network>("AIG");
|
||||||
|
}
|
||||||
|
if (is_set("cone")) {
|
||||||
|
get_cones<mockturtle::aig_network>("AIG");
|
||||||
|
}
|
||||||
|
if (is_set("level")) {
|
||||||
|
level_size<mockturtle::aig_network>("AIG");
|
||||||
|
}
|
||||||
|
if (is_set("skip")) {
|
||||||
|
skip_histogram<mockturtle::aig_network>("AIG");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int max_fanout = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
ALICE_ADD_COMMAND(ps2, "General");
|
||||||
|
} // namespace alice
|
||||||
|
#endif
|
|
@ -13,6 +13,7 @@
|
||||||
#ifndef SIM_HPP
|
#ifndef SIM_HPP
|
||||||
#define SIM_HPP
|
#define SIM_HPP
|
||||||
|
|
||||||
|
#include <kitty/static_truth_table.hpp>
|
||||||
#include <mockturtle/algorithms/simulation.hpp>
|
#include <mockturtle/algorithms/simulation.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -83,7 +84,7 @@ class sim_command : public command {
|
||||||
begin = clock();
|
begin = clock();
|
||||||
aig_network aig = store<aig_network>().current();
|
aig_network aig = store<aig_network>().current();
|
||||||
if (is_set("partial_simulate")){
|
if (is_set("partial_simulate")){
|
||||||
partial_simulator sim(aig.num_pis(), 100000);
|
partial_simulator sim(aig.num_pis(), 10000);
|
||||||
unordered_node_map<kitty::partial_truth_table, aig_network>
|
unordered_node_map<kitty::partial_truth_table, aig_network>
|
||||||
node_to_value(aig);
|
node_to_value(aig);
|
||||||
simulate_nodes(aig, node_to_value, sim);
|
simulate_nodes(aig, node_to_value, sim);
|
||||||
|
@ -103,8 +104,7 @@ class sim_command : public command {
|
||||||
// });
|
// });
|
||||||
} else {
|
} else {
|
||||||
default_simulator<kitty::dynamic_truth_table> sim(aig.num_pis());
|
default_simulator<kitty::dynamic_truth_table> sim(aig.num_pis());
|
||||||
unordered_node_map<kitty::dynamic_truth_table, aig_network>
|
unordered_node_map<kitty::dynamic_truth_table, aig_network> node_to_value(aig);
|
||||||
node_to_value(aig);
|
|
||||||
simulate_nodes<kitty::dynamic_truth_table>(aig, node_to_value, sim);
|
simulate_nodes<kitty::dynamic_truth_table>(aig, node_to_value, sim);
|
||||||
}
|
}
|
||||||
end = clock();
|
end = clock();
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file stpfr.hpp
|
||||||
|
*
|
||||||
|
* @brief STP-based functional reduction
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/03/14
|
||||||
|
*/
|
||||||
#ifndef STPFR_HPP
|
#ifndef STPFR_HPP
|
||||||
#define STPFR_HPP
|
#define STPFR_HPP
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file window_rewriting.hpp
|
||||||
|
*
|
||||||
|
* @brief Window rewriting
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/09/27
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WINDOW_REWRITING_HPP
|
||||||
|
#define WINDOW_REWRITING_HPP
|
||||||
|
|
||||||
|
#include <mockturtle/algorithms/cleanup.hpp>
|
||||||
|
#include <mockturtle/algorithms/experimental/boolean_optimization.hpp>
|
||||||
|
#include <mockturtle/algorithms/experimental/sim_resub.hpp>
|
||||||
|
#include <mockturtle/algorithms/experimental/window_resub.hpp>
|
||||||
|
#include <mockturtle/algorithms/window_rewriting.hpp>
|
||||||
|
#include <mockturtle/networks/aig.hpp>
|
||||||
|
#include <mockturtle/networks/mig.hpp>
|
||||||
|
#include <mockturtle/networks/xag.hpp>
|
||||||
|
#include <mockturtle/networks/xmg.hpp>
|
||||||
|
#include <mockturtle/traits.hpp>
|
||||||
|
#include <mockturtle/views/depth_view.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace mockturtle;
|
||||||
|
using namespace mockturtle::experimental;
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class wr_command : public command {
|
||||||
|
public:
|
||||||
|
explicit wr_command(const environment::ptr& env)
|
||||||
|
: command(env, "window rewriting") {
|
||||||
|
add_option("cut_size, -k", cut_size,
|
||||||
|
"set the cut size from 2 to 6, default = 4");
|
||||||
|
add_option("num_levels, -l", num_levels,
|
||||||
|
"set the window level, default = 5");
|
||||||
|
add_flag("--gain, -g", "optimize until there is no gain");
|
||||||
|
add_flag("--resub, -r", "window resub");
|
||||||
|
add_flag("--mffw, -w", "MFFW rewriting");
|
||||||
|
add_flag("--verbose, -v", "print the information");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void execute() {
|
||||||
|
clock_t begin, end;
|
||||||
|
double totalTime;
|
||||||
|
|
||||||
|
begin = clock();
|
||||||
|
auto aig = store<aig_network>().current();
|
||||||
|
|
||||||
|
window_rewriting_params ps;
|
||||||
|
ps.cut_size = cut_size;
|
||||||
|
ps.num_levels = num_levels;
|
||||||
|
|
||||||
|
if (is_set("resub")) {
|
||||||
|
window_resub_params ps_r;
|
||||||
|
if (is_set("gain")) {
|
||||||
|
window_aig_enumerative_resub(aig, ps_r);
|
||||||
|
} else {
|
||||||
|
window_aig_heuristic_resub(aig, ps_r);
|
||||||
|
}
|
||||||
|
aig = cleanup_dangling(aig);
|
||||||
|
} else {
|
||||||
|
if (is_set("gain")) {
|
||||||
|
uint64_t const size_before{aig.num_gates()};
|
||||||
|
uint64_t size_current{};
|
||||||
|
do {
|
||||||
|
size_current = aig.num_gates();
|
||||||
|
window_rewriting_stats win_st;
|
||||||
|
window_rewriting(aig, ps, &win_st);
|
||||||
|
if (is_set("verbose")) win_st.report();
|
||||||
|
aig = cleanup_dangling(aig);
|
||||||
|
} while (aig.num_gates() < size_current);
|
||||||
|
} else if (is_set("mffw")) {
|
||||||
|
window_rewriting_stats win_st;
|
||||||
|
mffw_rewriting(aig, ps, &win_st);
|
||||||
|
aig = cleanup_dangling(aig);
|
||||||
|
} else {
|
||||||
|
window_rewriting_stats win_st;
|
||||||
|
window_rewriting(aig, ps, &win_st);
|
||||||
|
aig = cleanup_dangling(aig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
phyLS::print_stats(aig);
|
||||||
|
store<aig_network>().extend();
|
||||||
|
store<aig_network>().current() = aig;
|
||||||
|
|
||||||
|
end = clock();
|
||||||
|
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
cout.setf(ios::fixed);
|
||||||
|
cout << "[CPU time] " << setprecision(2) << totalTime << " s" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned cut_size = 4u;
|
||||||
|
unsigned num_levels = 5u;
|
||||||
|
};
|
||||||
|
|
||||||
|
ALICE_ADD_COMMAND(wr, "Synthesis")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,55 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file xmginv.hpp
|
||||||
|
*
|
||||||
|
* @brief Inversion optimization of xmg
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XMGINV_HPP
|
||||||
|
#define XMGINV_HPP
|
||||||
|
|
||||||
|
#include <mockturtle/mockturtle.hpp>
|
||||||
|
#include <mockturtle/utils/stopwatch.hpp>
|
||||||
|
|
||||||
|
#include "../core/xmginv.hpp"
|
||||||
|
|
||||||
|
namespace alice {
|
||||||
|
|
||||||
|
class xmginv_command : public command {
|
||||||
|
public:
|
||||||
|
explicit xmginv_command(const environment::ptr& env)
|
||||||
|
: command(env, "inversion optimization of xmg") {
|
||||||
|
add_flag("--verbose, -v", "print the information");
|
||||||
|
}
|
||||||
|
|
||||||
|
rules validity_rules() const { return {has_store_element<xmg_network>(env)}; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void execute() {
|
||||||
|
/* derive some XMG */
|
||||||
|
xmg_network xmg = store<xmg_network>().current();
|
||||||
|
xmg_network xmg_opt;
|
||||||
|
|
||||||
|
stopwatch<>::duration time{0};
|
||||||
|
call_with_stopwatch(
|
||||||
|
time, [&]() { xmg_opt = phyLS::xmg_inv_optimization(xmg); });
|
||||||
|
|
||||||
|
store<xmg_network>().extend();
|
||||||
|
store<xmg_network>().current() = xmg_opt;
|
||||||
|
|
||||||
|
phyLS::print_stats(xmg_opt);
|
||||||
|
|
||||||
|
std::cout << fmt::format("[time]: {:5.2f} seconds\n", to_seconds(time));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ALICE_ADD_COMMAND(xmginv, "Synthesis")
|
||||||
|
|
||||||
|
} // namespace alice
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,5 +1,5 @@
|
||||||
/* phyLS: Advanced Logic Synthesis and Optimization tool
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
* Copyright (C) 2019-2021 Ningbo University, Ningbo, China */
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file exact_dag.hpp
|
* @file exact_dag.hpp
|
||||||
|
|
|
@ -77,7 +77,7 @@ class lut_rewriting_manager {
|
||||||
});
|
});
|
||||||
|
|
||||||
// clean all redundant luts
|
// clean all redundant luts
|
||||||
auto klut_opt = mockturtle::cleanup_luts(klut);
|
auto klut_opt = mockturtle::cleanup_dangling(klut);
|
||||||
return klut_opt;
|
return klut_opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,43 +341,17 @@ class lut_rewriting_manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
void es(int nr_in, std::string tt, percy::chain& result) {
|
void es(int nr_in, std::string tt, percy::chain& result) {
|
||||||
int node = nr_in - 1;
|
spec spec;
|
||||||
bool target = false;
|
chain c;
|
||||||
while (true) {
|
spec.verbosity = 0;
|
||||||
spec spec;
|
|
||||||
bsat_wrapper solver;
|
|
||||||
percy::partial_dag_encoder encoder2(solver);
|
|
||||||
encoder2.reset_sim_tts(nr_in);
|
|
||||||
|
|
||||||
spec.add_alonce_clauses = false;
|
kitty::dynamic_truth_table f(nr_in);
|
||||||
spec.add_nontriv_clauses = false;
|
kitty::create_from_hex_string(f, tt);
|
||||||
spec.add_lex_func_clauses = false;
|
spec[0] = f;
|
||||||
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);
|
spec.preprocess();
|
||||||
kitty::create_from_hex_string(f, tt);
|
auto res = pd_ser_synthesize_parallel(spec, c, 4, "../src/pd/");
|
||||||
spec[0] = f;
|
if (res == success) result.copy(c);
|
||||||
|
|
||||||
auto dags = percy::pd_generate_filtered(node, nr_in);
|
|
||||||
spec.preprocess();
|
|
||||||
for (auto& dag : dags) {
|
|
||||||
percy::chain c;
|
|
||||||
synth_result status;
|
|
||||||
status = percy::pd_cegar_synthesize(spec, c, dag, solver, encoder2);
|
|
||||||
if (status == success) {
|
|
||||||
result.copy(c);
|
|
||||||
target = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (target) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
node++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -0,0 +1,277 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file ps2.hpp
|
||||||
|
*
|
||||||
|
* @brief Show statistics in the stored network
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <alice/alice.hpp>
|
||||||
|
#include <mockturtle/mockturtle.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
namespace phyLS {
|
||||||
|
using aig_names = mockturtle::names_view<mockturtle::aig_network>;
|
||||||
|
using mig_names = mockturtle::names_view<mockturtle::mig_network>;
|
||||||
|
using xag_names = mockturtle::names_view<mockturtle::xag_network>;
|
||||||
|
using xmg_names = mockturtle::names_view<mockturtle::xmg_network>;
|
||||||
|
|
||||||
|
struct function_counts {
|
||||||
|
int maj_num = 0;
|
||||||
|
int xor_num = 0;
|
||||||
|
int xnor_num = 0;
|
||||||
|
int xor3_num = 0;
|
||||||
|
int and_num = 0;
|
||||||
|
int or_num = 0;
|
||||||
|
int input_num = 0;
|
||||||
|
int unknown_num = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum reconfig_function { AND, OR, XOR, XNOR, XOR3, MAJ, INPUT, UNKNOWN };
|
||||||
|
|
||||||
|
template <typename network>
|
||||||
|
reconfig_function node_function(const network& ntk,
|
||||||
|
const typename network::node& node) {
|
||||||
|
if (ntk.is_pi(node) || ntk.is_constant(node)) {
|
||||||
|
return reconfig_function::INPUT;
|
||||||
|
} else if (ntk.is_and(node)) {
|
||||||
|
return reconfig_function::AND;
|
||||||
|
} else if (ntk.is_or(node)) {
|
||||||
|
return reconfig_function::OR;
|
||||||
|
} else if (ntk.is_xor(node)) {
|
||||||
|
return reconfig_function::XOR;
|
||||||
|
} else if (ntk.is_maj(node)) {
|
||||||
|
typename network::signal first_signal =
|
||||||
|
ntk._storage->nodes[node].children[0];
|
||||||
|
typename network::node first_fanin = ntk.get_node(first_signal);
|
||||||
|
|
||||||
|
if (ntk.is_constant(first_fanin)) {
|
||||||
|
if (first_signal.complement) {
|
||||||
|
return reconfig_function::OR;
|
||||||
|
} else {
|
||||||
|
return reconfig_function::AND;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return reconfig_function::MAJ;
|
||||||
|
}
|
||||||
|
} else if (ntk.is_xor3(node)) {
|
||||||
|
typename network::signal first_signal =
|
||||||
|
ntk._storage->nodes[node].children[0];
|
||||||
|
typename network::node first_fanin = ntk.get_node(first_signal);
|
||||||
|
if (ntk.is_constant(first_fanin)) {
|
||||||
|
if (first_signal.complement) {
|
||||||
|
return reconfig_function::XNOR;
|
||||||
|
} else {
|
||||||
|
return reconfig_function::XOR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return reconfig_function::XOR3;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return reconfig_function::UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <typename network>
|
||||||
|
void update_counts(function_counts& counts, const network& ntk,
|
||||||
|
const typename network::node& node) {
|
||||||
|
reconfig_function func = node_function(ntk, node);
|
||||||
|
switch (func) {
|
||||||
|
case AND:
|
||||||
|
counts.and_num++;
|
||||||
|
break;
|
||||||
|
case OR:
|
||||||
|
counts.or_num++;
|
||||||
|
break;
|
||||||
|
case XOR:
|
||||||
|
counts.xor_num++;
|
||||||
|
break;
|
||||||
|
case XNOR:
|
||||||
|
counts.xnor_num++;
|
||||||
|
break;
|
||||||
|
case XOR3:
|
||||||
|
counts.xor3_num++;
|
||||||
|
break;
|
||||||
|
case MAJ:
|
||||||
|
counts.maj_num++;
|
||||||
|
break;
|
||||||
|
case INPUT:
|
||||||
|
counts.input_num++;
|
||||||
|
break;
|
||||||
|
case UNKNOWN:
|
||||||
|
default:
|
||||||
|
counts.unknown_num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename network>
|
||||||
|
function_counts node_functions(const network& ntk) {
|
||||||
|
function_counts counts;
|
||||||
|
ntk.foreach_node([&](auto node) { update_counts(counts, ntk, node); });
|
||||||
|
return counts;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Ntk>
|
||||||
|
class critical_node_view : public Ntk {
|
||||||
|
public:
|
||||||
|
using storage = typename Ntk::storage;
|
||||||
|
using node = typename Ntk::node;
|
||||||
|
using signal = typename Ntk::signal;
|
||||||
|
|
||||||
|
public:
|
||||||
|
critical_node_view() {}
|
||||||
|
explicit critical_node_view(Ntk const& ntk) : Ntk(ntk), ntk(ntk) {
|
||||||
|
int depth = depth_ntk.depth();
|
||||||
|
depth_ntk.clear_visited();
|
||||||
|
nums_criti = 0;
|
||||||
|
depth_ntk.foreach_po([&](auto const& po, auto i) {
|
||||||
|
node pon = depth_ntk.get_node(po);
|
||||||
|
if (depth_ntk.level(pon) != depth) return;
|
||||||
|
nums_criti++;
|
||||||
|
recursive(pon, critical_path, i);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
std::vector<node> recursive(node& n, std::vector<node>& critical, int i) {
|
||||||
|
if (depth_ntk.visited(n) != 0) return critical;
|
||||||
|
depth_ntk.set_visited(n, i + 1);
|
||||||
|
critical.emplace_back(n);
|
||||||
|
depth_ntk.foreach_fanin(n, [&](auto fi) {
|
||||||
|
node fin = depth_ntk.get_node(fi);
|
||||||
|
int level = depth_ntk.level(n);
|
||||||
|
if (depth_ntk.level(fin) == level - 1) {
|
||||||
|
recursive(fin, critical, i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return critical;
|
||||||
|
}
|
||||||
|
std::vector<node> get_critical_path() { return critical_path; }
|
||||||
|
uint32_t get_critical_nums() { return nums_criti; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t nums_criti;
|
||||||
|
std::vector<node> critical_path;
|
||||||
|
Ntk const& ntk;
|
||||||
|
mockturtle::depth_view<Ntk> depth_ntk{ntk};
|
||||||
|
};
|
||||||
|
|
||||||
|
static void compute_cone(mockturtle::aig_network aig, uint64_t index,
|
||||||
|
std::unordered_map<int, int>& nodes, int outindex,
|
||||||
|
std::unordered_map<int, int>& ins) {
|
||||||
|
if (aig._storage->nodes[index].data[1].h1 == 0) {
|
||||||
|
// increment number of nodes in this cone
|
||||||
|
std::unordered_map<int, int>::iterator it = nodes.find(outindex);
|
||||||
|
|
||||||
|
if (it != nodes.end() && index > aig.num_pis()) {
|
||||||
|
// increment the number of nodes
|
||||||
|
it->second++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set node as visited
|
||||||
|
aig._storage->nodes[index].data[1].h1 = 1;
|
||||||
|
|
||||||
|
// traverse one side to the PIs
|
||||||
|
if (!aig.is_pi(aig._storage->nodes[index].children[0].index) &&
|
||||||
|
index > aig.num_pis()) {
|
||||||
|
if (aig._storage->nodes[index].children[0].data & 1)
|
||||||
|
aig._storage->nodes[index].children[0].data =
|
||||||
|
aig._storage->nodes[index].children[0].data - 1;
|
||||||
|
|
||||||
|
// calculate input node index
|
||||||
|
auto inIndex = aig._storage->nodes[index].children[0].data >> 1;
|
||||||
|
|
||||||
|
// im ignoring latches
|
||||||
|
if (inIndex > aig.num_pis()) {
|
||||||
|
// call recursion
|
||||||
|
compute_cone(aig, inIndex, nodes, outindex, ins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// traverse the other side to the PIs
|
||||||
|
if (!aig.is_pi(aig._storage->nodes[index].children[1].index) &&
|
||||||
|
index > aig.num_pis()) {
|
||||||
|
if (aig._storage->nodes[index].children[1].data & 1)
|
||||||
|
aig._storage->nodes[index].children[1].data =
|
||||||
|
aig._storage->nodes[index].children[1].data - 1;
|
||||||
|
|
||||||
|
// calculate input node index
|
||||||
|
auto inIndex = aig._storage->nodes[index].children[1].data >> 1;
|
||||||
|
|
||||||
|
// im ignoring latches
|
||||||
|
if (inIndex > aig.num_pis()) {
|
||||||
|
// call recursion
|
||||||
|
compute_cone(aig, inIndex, nodes, outindex, ins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if my child is PI and was not visited yet, I increase the input counter
|
||||||
|
if (aig.is_ci(aig._storage->nodes[index].children[0].index) &&
|
||||||
|
aig._storage->nodes[aig._storage->nodes[index].children[0].index]
|
||||||
|
.data[1]
|
||||||
|
.h1 == 0) {
|
||||||
|
aig._storage->nodes[aig._storage->nodes[index].children[0].index]
|
||||||
|
.data[1]
|
||||||
|
.h1 = 1;
|
||||||
|
|
||||||
|
std::unordered_map<int, int>::iterator it = ins.find(outindex);
|
||||||
|
if (it != ins.end()) {
|
||||||
|
// increment the number of inputs
|
||||||
|
it->second++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if my other child is PI and was not visited yet, I phyLS increase the
|
||||||
|
// input counter
|
||||||
|
if (aig.is_ci(aig._storage->nodes[index].children[1].index) &&
|
||||||
|
aig._storage->nodes[aig._storage->nodes[index].children[1].index]
|
||||||
|
.data[1]
|
||||||
|
.h1 == 0) {
|
||||||
|
aig._storage->nodes[aig._storage->nodes[index].children[1].index]
|
||||||
|
.data[1]
|
||||||
|
.h1 = 1;
|
||||||
|
|
||||||
|
std::unordered_map<int, int>::iterator it = ins.find(outindex);
|
||||||
|
if (it != ins.end()) {
|
||||||
|
// increment the number of inputs
|
||||||
|
it->second++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Ntk>
|
||||||
|
static int computeLevel(Ntk const& ntk, int index) {
|
||||||
|
// if node not visited
|
||||||
|
if (ntk._storage->nodes[index].data[1].h1 == 0) {
|
||||||
|
// set node as visited
|
||||||
|
ntk._storage->nodes[index].data[1].h1 = 1;
|
||||||
|
|
||||||
|
// if is input
|
||||||
|
if (ntk.is_ci(index)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto inIdx2 = ntk._storage->nodes[index].children[1].data;
|
||||||
|
if (inIdx2 & 1) inIdx2 = inIdx2 - 1;
|
||||||
|
|
||||||
|
// calculate input node index
|
||||||
|
auto inNode1 = inIdx2 >> 1;
|
||||||
|
int levelNode1 = computeLevel<Ntk>(ntk, inNode1);
|
||||||
|
|
||||||
|
auto inIdx = ntk._storage->nodes[index].children[0].data;
|
||||||
|
if (inIdx & 1) inIdx = inIdx - 1;
|
||||||
|
|
||||||
|
// calculate input node index
|
||||||
|
auto inNode0 = inIdx >> 1;
|
||||||
|
int levelNode0 = computeLevel<Ntk>(ntk, inNode0);
|
||||||
|
|
||||||
|
int level = 1 + std::max(levelNode0, levelNode1);
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace phyLS
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
namespace phyLS {
|
namespace phyLS {
|
||||||
simulator::simulator(CircuitGraph& graph) : graph(graph) {
|
simulator::simulator(CircuitGraph& graph) : graph(graph) {
|
||||||
pattern_num = 100; // 随机产生100个仿真向量
|
pattern_num = 10000; // 随机产生100个仿真向量
|
||||||
// max_branch = int( log2(pattern_num) ); //做cut的界
|
// max_branch = int( log2(pattern_num) ); //做cut的界
|
||||||
max_branch = 8;
|
max_branch = 8;
|
||||||
sim_info.resize(graph.get_lines().size()); // 按照lines的id记录仿真向量的信息
|
sim_info.resize(graph.get_lines().size()); // 按照lines的id记录仿真向量的信息
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file utils.hpp
|
||||||
|
*
|
||||||
|
* @brief TODO
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UTILS_HPP
|
||||||
|
#define UTILS_HPP
|
||||||
|
|
||||||
|
#include <mockturtle/networks/xag.hpp>
|
||||||
|
#include <mockturtle/networks/xmg.hpp>
|
||||||
|
|
||||||
|
using namespace mockturtle;
|
||||||
|
|
||||||
|
namespace phyLS {
|
||||||
|
|
||||||
|
std::array<xmg_network::signal, 3> get_children(xmg_network const& xmg,
|
||||||
|
xmg_network::node const& n) {
|
||||||
|
std::array<xmg_network::signal, 3> children;
|
||||||
|
xmg.foreach_fanin(n, [&children](auto const& f, auto i) { children[i] = f; });
|
||||||
|
std::sort(
|
||||||
|
children.begin(), children.end(),
|
||||||
|
[&](auto const& c1, auto const& c2) { return c1.index < c2.index; });
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<xag_network::signal, 2> get_xag_children(
|
||||||
|
xag_network const& xag, xag_network::node const& n) {
|
||||||
|
std::array<xag_network::signal, 2> children;
|
||||||
|
xag.foreach_fanin(n, [&children](auto const& f, auto i) { children[i] = f; });
|
||||||
|
std::sort(
|
||||||
|
children.begin(), children.end(),
|
||||||
|
[&](auto const& c1, auto const& c2) { return c1.index < c2.index; });
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_children(std::array<xmg_network::signal, 3> const& children) {
|
||||||
|
auto i = 0u;
|
||||||
|
for (auto child : children) {
|
||||||
|
std::cout << "children " << i << " is " << child.index << " complemented ? "
|
||||||
|
<< child.complement << std::endl;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace phyLS
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,344 @@
|
||||||
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file xmginv.hpp
|
||||||
|
*
|
||||||
|
* @brief Inversion optimization of xmg
|
||||||
|
*
|
||||||
|
* @author Homyoung
|
||||||
|
* @since 2023/11/16
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XMG_INV_HPP
|
||||||
|
#define XMG_INV_HPP
|
||||||
|
|
||||||
|
#include <mockturtle/algorithms/cleanup.hpp>
|
||||||
|
#include <mockturtle/networks/xmg.hpp>
|
||||||
|
#include <mockturtle/properties/migcost.hpp>
|
||||||
|
|
||||||
|
#include "utils.hpp"
|
||||||
|
|
||||||
|
using namespace mockturtle;
|
||||||
|
|
||||||
|
namespace phyLS {
|
||||||
|
|
||||||
|
/* use substitue method for inveters propagation */
|
||||||
|
xmg_network complement_node(xmg_network& xmg, xmg_network::node const& n) {
|
||||||
|
xmg_network::signal opt;
|
||||||
|
auto children = get_children(xmg, n);
|
||||||
|
|
||||||
|
if (xmg.is_maj(n)) {
|
||||||
|
children[0] = !children[0];
|
||||||
|
children[1] = !children[1];
|
||||||
|
children[2] = !children[2];
|
||||||
|
|
||||||
|
opt = xmg.create_maj_without_complement_opt(children[0], children[1],
|
||||||
|
children[2]) ^
|
||||||
|
true;
|
||||||
|
} else {
|
||||||
|
if (xmg.is_complemented(children[2])) {
|
||||||
|
children[2] = !children[2];
|
||||||
|
} else {
|
||||||
|
children[1] = !children[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
opt =
|
||||||
|
xmg.create_xor_without_complement_opt(children[1], children[2]) ^ true;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmg.substitute_node_without_complement_opt(n, opt);
|
||||||
|
|
||||||
|
return xmg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* print information */
|
||||||
|
void print_node(xmg_network const& xmg, xmg_network::node const& n) {
|
||||||
|
std::cout << " node " << n << " inverters infro: ";
|
||||||
|
xmg.foreach_fanin(n, [&](auto s) {
|
||||||
|
std::cout << " { " << s.index << " , " << s.complement << " } ";
|
||||||
|
});
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_network(xmg_network const& xmg) {
|
||||||
|
xmg.foreach_gate([&](auto n) { print_node(xmg, n); });
|
||||||
|
}
|
||||||
|
/******************************************************************************
|
||||||
|
* Types *
|
||||||
|
******************************************************************************/
|
||||||
|
class inv_manager {
|
||||||
|
public:
|
||||||
|
inv_manager(xmg_network xmg);
|
||||||
|
|
||||||
|
void compute_parents();
|
||||||
|
|
||||||
|
std::vector<xmg_network::node> get_parents(xmg_network::node const& n);
|
||||||
|
int num_invs_fanins(xmg_network::node const& n);
|
||||||
|
int num_invs_fanouts(xmg_network::node const& n);
|
||||||
|
int num_in_edges(xmg_network::node const& n);
|
||||||
|
int num_out_edges(xmg_network::node const& n);
|
||||||
|
int num_edges(xmg_network::node const& n);
|
||||||
|
int num_invs(xmg_network::node const& n);
|
||||||
|
int one_level_savings(xmg_network::node const& n);
|
||||||
|
int one_level_savings_nni(xmg_network::node const& n);
|
||||||
|
int two_level_savings(xmg_network::node const& n);
|
||||||
|
void xor_jump();
|
||||||
|
|
||||||
|
void one_level_optimization(const int& thres1, const int& thres2);
|
||||||
|
void two_level_optimization(const int& thres1, const int& thres2);
|
||||||
|
xmg_network run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
xmg_network xmg;
|
||||||
|
std::map<xmg_network::node, std::vector<xmg_network::node>> pmap;
|
||||||
|
|
||||||
|
unsigned num_inv_origin{0u}, num_inv_opt{0u};
|
||||||
|
};
|
||||||
|
|
||||||
|
inv_manager::inv_manager(xmg_network xmg) : xmg(xmg) { compute_parents(); }
|
||||||
|
|
||||||
|
/* compute the node parents information and save it */
|
||||||
|
void inv_manager::compute_parents() {
|
||||||
|
xmg.foreach_gate([&](auto n) {
|
||||||
|
xmg.foreach_fanin(n, [&](auto c) {
|
||||||
|
auto it = pmap.find(xmg.get_node(c));
|
||||||
|
|
||||||
|
if (it == pmap.end()) {
|
||||||
|
std::vector<xmg_network::node> fout;
|
||||||
|
fout.push_back(n);
|
||||||
|
pmap[xmg.get_node(c)] = fout;
|
||||||
|
} else {
|
||||||
|
auto& f = it->second;
|
||||||
|
if (std::find(f.begin(), f.end(), n) == f.end()) {
|
||||||
|
f.push_back(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<xmg_network::node> inv_manager::get_parents(
|
||||||
|
xmg_network::node const& n) {
|
||||||
|
return pmap[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
int inv_manager::num_invs_fanins(xmg_network::node const& n) {
|
||||||
|
int cost = 0;
|
||||||
|
|
||||||
|
xmg.foreach_fanin(n, [&](auto s) {
|
||||||
|
if (xmg.is_complemented(s)) {
|
||||||
|
cost++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
int inv_manager::num_invs_fanouts(xmg_network::node const& n) {
|
||||||
|
int cost = 0u;
|
||||||
|
|
||||||
|
/* ordinary fanouts */
|
||||||
|
auto parents = get_parents(n);
|
||||||
|
for (const auto pn : parents) {
|
||||||
|
xmg.foreach_fanin(pn, [&](auto s) {
|
||||||
|
if (xmg.get_node(s) == n && xmg.is_complemented(s)) {
|
||||||
|
cost++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* POs */
|
||||||
|
xmg.foreach_po([&](auto const& f) {
|
||||||
|
if (xmg.get_node(f) == n && xmg.is_complemented(f)) {
|
||||||
|
cost++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
int inv_manager::num_in_edges(xmg_network::node const& n) {
|
||||||
|
auto num_in = (xmg.is_maj(n) ? 3 : 2);
|
||||||
|
return num_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
int inv_manager::num_out_edges(xmg_network::node const& n) {
|
||||||
|
/* pos */
|
||||||
|
int num_po = 0;
|
||||||
|
xmg.foreach_po([&](auto const& f) {
|
||||||
|
if (xmg.get_node(f) == n) {
|
||||||
|
num_po++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return get_parents(n).size() + num_po;
|
||||||
|
}
|
||||||
|
|
||||||
|
int inv_manager::num_edges(xmg_network::node const& n) {
|
||||||
|
assert(xmg.is_maj(n) || xmg.is_xor3(n));
|
||||||
|
return num_in_edges(n) + num_out_edges(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
int inv_manager::num_invs(xmg_network::node const& n) {
|
||||||
|
return num_invs_fanins(n) + num_invs_fanouts(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
int inv_manager::one_level_savings(xmg_network::node const& n) {
|
||||||
|
int before, after;
|
||||||
|
|
||||||
|
before = num_invs(n);
|
||||||
|
|
||||||
|
if (xmg.is_maj(n)) {
|
||||||
|
after = num_edges(n) - before;
|
||||||
|
} else {
|
||||||
|
int in, out;
|
||||||
|
|
||||||
|
out = num_out_edges(n) - num_invs_fanouts(n);
|
||||||
|
|
||||||
|
auto tmp = num_invs_fanins(n);
|
||||||
|
|
||||||
|
if (tmp == 1 || tmp == 3) {
|
||||||
|
in = 0;
|
||||||
|
} else if (tmp == 2 || tmp == 0) {
|
||||||
|
in = 1;
|
||||||
|
} else {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
after = in + out;
|
||||||
|
}
|
||||||
|
|
||||||
|
return before - after;
|
||||||
|
}
|
||||||
|
|
||||||
|
int inv_manager::one_level_savings_nni(xmg_network::node const& n) {
|
||||||
|
int before, after, after_nni;
|
||||||
|
|
||||||
|
before = num_invs(n);
|
||||||
|
|
||||||
|
if (xmg.is_maj(n)) {
|
||||||
|
after = num_edges(n) - before;
|
||||||
|
|
||||||
|
if (num_invs_fanins(n) == 2) {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int in, out;
|
||||||
|
|
||||||
|
out = num_out_edges(n) - num_invs_fanouts(n);
|
||||||
|
|
||||||
|
auto tmp = num_invs_fanins(n);
|
||||||
|
|
||||||
|
if (tmp == 1 || tmp == 3) {
|
||||||
|
in = 0;
|
||||||
|
} else if (tmp == 2 || tmp == 0) {
|
||||||
|
in = 1;
|
||||||
|
} else {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
after = in + out;
|
||||||
|
}
|
||||||
|
|
||||||
|
return before - after;
|
||||||
|
}
|
||||||
|
|
||||||
|
int inv_manager::two_level_savings(xmg_network::node const& n) {
|
||||||
|
assert(!xmg.is_pi(n));
|
||||||
|
|
||||||
|
auto parents = get_parents(n);
|
||||||
|
int total_savings = 0;
|
||||||
|
|
||||||
|
/* no parents */
|
||||||
|
if (parents.size() == 0) {
|
||||||
|
return one_level_savings(n);
|
||||||
|
} else {
|
||||||
|
auto child_savings = one_level_savings(n);
|
||||||
|
|
||||||
|
for (const auto& p : parents) {
|
||||||
|
total_savings += one_level_savings(p);
|
||||||
|
|
||||||
|
xmg.foreach_fanin(p, [&](auto s) {
|
||||||
|
if (xmg.get_node(s) == n && xmg.is_complemented(s)) {
|
||||||
|
if (xmg.is_complemented(s)) {
|
||||||
|
total_savings -= 2;
|
||||||
|
} else {
|
||||||
|
total_savings += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
total_savings += child_savings;
|
||||||
|
}
|
||||||
|
|
||||||
|
return total_savings;
|
||||||
|
}
|
||||||
|
|
||||||
|
void inv_manager::one_level_optimization(const int& thres1, const int& thres2) {
|
||||||
|
xmg.foreach_gate([&](auto n) {
|
||||||
|
if (one_level_savings(n) >= thres1) {
|
||||||
|
xmg.complement_node(n, pmap[n]);
|
||||||
|
} else if (two_level_savings(n) >= thres2) {
|
||||||
|
auto parents = pmap[n];
|
||||||
|
xmg.complement_node(n, pmap[n]);
|
||||||
|
|
||||||
|
for (const auto& p : parents) {
|
||||||
|
xmg.complement_node(p, pmap[p]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void inv_manager::two_level_optimization(const int& thres1, const int& thres2) {
|
||||||
|
xmg.foreach_gate([&](auto n) {
|
||||||
|
auto parents = pmap[n];
|
||||||
|
auto savings = two_level_savings(n);
|
||||||
|
|
||||||
|
if (savings >= thres1) {
|
||||||
|
xmg.complement_node(n, pmap[n]);
|
||||||
|
|
||||||
|
for (const auto& p : parents) {
|
||||||
|
xmg.complement_node(p, pmap[p]);
|
||||||
|
}
|
||||||
|
} else if (one_level_savings(n) >= thres2) {
|
||||||
|
xmg.complement_node(n, pmap[n]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void inv_manager::xor_jump() {
|
||||||
|
xmg.foreach_gate([&](const auto& n) {
|
||||||
|
if (xmg.is_xor3(n)) {
|
||||||
|
xmg.xor_inv_jump(n);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
xmg_network inv_manager::run() {
|
||||||
|
num_inv_origin = num_inverters(xmg);
|
||||||
|
|
||||||
|
one_level_optimization(0, 1);
|
||||||
|
two_level_optimization(1, 0);
|
||||||
|
|
||||||
|
one_level_optimization(0, 1);
|
||||||
|
two_level_optimization(1, 1);
|
||||||
|
|
||||||
|
num_inv_opt = num_inverters(xmg);
|
||||||
|
|
||||||
|
xor_jump();
|
||||||
|
|
||||||
|
std::cout << "[xmginv] "
|
||||||
|
<< " num_inv_origin: " << num_inv_origin
|
||||||
|
<< " num_opt_inv: " << num_inv_opt << std::endl;
|
||||||
|
auto xmg_opt = mockturtle::cleanup_dangling(xmg);
|
||||||
|
return xmg_opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* public function */
|
||||||
|
xmg_network xmg_inv_optimization(xmg_network& xmg) {
|
||||||
|
inv_manager mgr(xmg);
|
||||||
|
return mgr.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace phyLS
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
||||||
/* phyLS: Advanced Logic Synthesis and Optimization tool
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
* Copyright (C) 2019- Ningbo University, Ningbo, China */
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file build_xag_db.hpp
|
* @file build_xag_db.hpp
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* phyLS: Advanced Logic Synthesis and Optimization tool
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
* Copyright (C) 2019- Ningbo University, Ningbo, China */
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file xag_dec.hpp
|
* @file xag_dec.hpp
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* phyLS: Advanced Logic Synthesis and Optimization tool
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
* Copyright (C) 2019- Ningbo University, Ningbo, China */
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file xag_lut_dec.hpp
|
* @file xag_lut_dec.hpp
|
||||||
|
|
|
@ -1,27 +1,5 @@
|
||||||
/* phyLS: Advanced Logic Synthesis and Optimization tool
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
* Copyright (C) 2019- Ningbo University, Ningbo, China
|
* Copyright (C) 2023 */
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person
|
|
||||||
* obtaining a copy of this software and associated documentation
|
|
||||||
* files (the "Software"), to deal in the Software without
|
|
||||||
* restriction, including without limitation the rights to use,
|
|
||||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following
|
|
||||||
* conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\file mg.hpp
|
\file mg.hpp
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* phyLS: Advanced Logic Synthesis and Optimization tool
|
/* phyLS: powerful heightened yielded Logic Synthesis
|
||||||
* Copyright (C) 2019- Ningbo University, Ningbo, China
|
* Copyright (C) 2023 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
\file stp_npn.hpp
|
\file stp_npn.hpp
|
||||||
\brief Replace with size-optimum STP-based exact synthesis from NPN
|
\brief Replace with size-optimum STP-based exact synthesis from NPN
|
||||||
|
@ -72,7 +73,7 @@ class stp_npn_resynthesis {
|
||||||
std::unordered_map<std::string, std::vector<std::string>> opt_klut;
|
std::unordered_map<std::string, std::vector<std::string>> opt_klut;
|
||||||
|
|
||||||
void load_optimal_klut() {
|
void load_optimal_klut() {
|
||||||
std::ifstream infile("../src/networks/stp/opt_stp.txt");
|
std::ifstream infile("../src/networks/stp/opt_map.txt");
|
||||||
if (!infile) {
|
if (!infile) {
|
||||||
std::cout << " Cannot open file " << std::endl;
|
std::cout << " Cannot open file " << std::endl;
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -53,5 +53,22 @@
|
||||||
#include "commands/stpfr.hpp"
|
#include "commands/stpfr.hpp"
|
||||||
#include "commands/exact/exact_lut.hpp"
|
#include "commands/exact/exact_lut.hpp"
|
||||||
#include "commands/exact/lutrw.hpp"
|
#include "commands/exact/lutrw.hpp"
|
||||||
|
#include "commands/abc/if.hpp"
|
||||||
|
#include "commands/abc/map.hpp"
|
||||||
|
#include "commands/window_rewriting.hpp"
|
||||||
|
#include "commands/ps2.hpp"
|
||||||
|
#include "commands/xmg/xmginv.hpp"
|
||||||
|
#include "commands/abc/read_genlib.hpp"
|
||||||
|
#include "commands/abc/&nf.hpp"
|
||||||
|
#include "commands/abc/&if.hpp"
|
||||||
|
#include "commands/abc/put.hpp"
|
||||||
|
#include "commands/abc/amap.hpp"
|
||||||
|
#include "commands/abc/compress2rs.hpp"
|
||||||
|
#include "commands/abc/resyn2rs.hpp"
|
||||||
|
#include "commands/abc/dc2.hpp"
|
||||||
|
#include "commands/abc/sop.hpp"
|
||||||
|
#include "commands/abc/balance.hpp"
|
||||||
|
#include "commands/abc/refactor.hpp"
|
||||||
|
#include "commands/abc/rewrite.hpp"
|
||||||
|
|
||||||
ALICE_MAIN(phyLS)
|
ALICE_MAIN(phyLS)
|
Loading…
Reference in New Issue