ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
rewire_miaig.h
Go to the documentation of this file.
1
20
21#ifndef REWIRE_MIAIG_H
22#define REWIRE_MIAIG_H
23
24#define RW_ABC
25
26#ifdef RW_ABC
27#include "base/abc/abc.h"
28#include "aig/miniaig/miniaig.h"
29#include "rewire_map.h"
30#define RW_INT_MAX ABC_INT_MAX
31#define Rw_MaxInt Abc_MaxInt
32#define Rw_MinInt Abc_MinInt
33#define Rw_Var2Lit Abc_Var2Lit
34#define Rw_Lit2Var Abc_Lit2Var
35#define Rw_LitIsCompl Abc_LitIsCompl
36#define Rw_LitNot Abc_LitNot
37#define Rw_LitNotCond Abc_LitNotCond
38#define Rw_LitRegular Abc_LitRegular
39#else
40#ifdef _WIN32
41typedef unsigned __int64 word; // 32-bit windows
42#else
43typedef long long unsigned word; // other platforms
44#endif
45#ifdef _WIN32
46typedef __int64 iword; // 32-bit windows
47#else
48typedef long long iword; // other platforms
49#endif
50#define RW_INT_MAX (2147483647)
51static inline int Rw_MaxInt( int a, int b ) { return a > b ? a : b; }
52static inline int Rw_MinInt( int a, int b ) { return a < b ? a : b; }
53static inline int Rw_Var2Lit( int Var, int c ) { assert(Var >= 0 && !(c >> 1)); return Var + Var + c; }
54static inline int Rw_Lit2Var( int Lit ) { assert(Lit >= 0); return Lit >> 1; }
55static inline int Rw_LitIsCompl( int Lit ) { assert(Lit >= 0); return Lit & 1; }
56static inline int Rw_LitNot( int Lit ) { assert(Lit >= 0); return Lit ^ 1; }
57static inline int Rw_LitNotCond( int Lit, int c ) { assert(Lit >= 0); return Lit ^ (int)(c > 0); }
58static inline int Rw_LitRegular( int Lit ) { assert(Lit >= 0); return Lit & ~01; }
59#endif // RW_ABC
60#include "rewire_vec.h"
61#include "rewire_tt.h"
62#include "rewire_time.h"
63
64
65#include <vector>
66#include <algorithm>
67
68#ifdef RW_ABC
70#endif // RW_ABC
71
72namespace Rewire {
73
74#if RW_THREADS
75// exchange-add operation for atomic operations on reference counters
76#if defined __riscv && !defined __riscv_atomic
77// riscv target without A extension
78static inline int RW_XADD(int *addr, int delta) {
79 int tmp = *addr;
80 *addr += delta;
81 return tmp;
82}
83#elif defined __INTEL_COMPILER && !(defined WIN32 || defined _WIN32)
84// atomic increment on the linux version of the Intel(tm) compiler
85#define RW_XADD(addr, delta) \
86 (int)_InterlockedExchangeAdd( \
87 const_cast<void *>(reinterpret_cast<volatile void *>(addr)), delta)
88#elif defined __GNUC__
89#if defined __clang__ && __clang_major__ >= 3 && !defined __ANDROID__ && !defined __EMSCRIPTEN__ && !defined(__CUDACC__)
90#ifdef __ATOMIC_ACQ_REL
91#define RW_XADD(addr, delta) \
92 __c11_atomic_fetch_add((_Atomic(int) *)(addr), delta, __ATOMIC_ACQ_REL)
93#else
94#define RW_XADD(addr, delta) \
95 __atomic_fetch_add((_Atomic(int) *)(addr), delta, 4)
96#endif
97#else
98#if defined __ATOMIC_ACQ_REL && !defined __clang__
99// version for gcc >= 4.7
100#define RW_XADD(addr, delta) \
101 (int)__atomic_fetch_add((unsigned *)(addr), (unsigned)(delta), \
102 __ATOMIC_ACQ_REL)
103#else
104#define RW_XADD(addr, delta) \
105 (int)__sync_fetch_and_add((unsigned *)(addr), (unsigned)(delta))
106#endif
107#endif
108#elif defined _MSC_VER && !defined RC_INVOKED
109#define RW_XADD(addr, delta) \
110 (int)_InterlockedExchangeAdd((long volatile *)addr, delta)
111#else
112// thread-unsafe branch
113static inline int RW_XADD(int *addr, int delta) {
114 int tmp = *addr;
115 *addr += delta;
116 return tmp;
117}
118#endif
119#else // RW_THREADS
120static inline int RW_XADD(int *addr, int delta) {
121 int tmp = *addr;
122 *addr += delta;
123 return tmp;
124}
125#endif // RW_THREADS
126
127#define Miaig_CustomForEachConstInput(p, i) for (i = 0; i <= p->nIns; i++)
128#define Miaig_CustomForEachInput(p, i) for (i = 1; i <= p->nIns; i++)
129#define Miaig_CustomForEachNode(p, i) for (i = 1 + p->nIns; i < p->nObjs - p->nOuts; i++)
130#define Miaig_CustomForEachNodeReverse(p, i) for (i = p->nObjs - p->nOuts - 1; i > 1 + p->nIns; i--)
131#define Miaig_CustomForEachInputNode(p, i) for (i = 1; i < p->nObjs - p->nOuts; i++)
132#define Miaig_CustomForEachNodeStart(p, i, s) for (i = s; i < p->nObjs - p->nOuts; i++)
133#define Miaig_CustomForEachOutput(p, i) for (i = p->nObjs - p->nOuts; i < p->nObjs; i++)
134#define Miaig_CustomForEachNodeOutput(p, i) for (i = 1 + p->nIns; i < p->nObjs; i++)
135#define Miaig_CustomForEachNodeOutputStart(p, i, s) for (i = s; i < p->nObjs; i++)
136#define Miaig_CustomForEachObj(p, i) for (i = 0; i < p->nObjs; i++)
137#define Miaig_CustomForEachObjFanin(p, i, iLit, k) Vi_ForEachEntry(&p->pvFans[i], iLit, k)
138
139#define Miaig_ForEachConstInput(i) for (i = 0; i <= _data->nIns; i++)
140#define Miaig_ForEachInput(i) for (i = 1; i <= _data->nIns; i++)
141#define Miaig_ForEachNode(i) for (i = 1 + _data->nIns; i < _data->nObjs - _data->nOuts; i++)
142#define Miaig_ForEachNodeReverse(i) for (i = _data->nObjs - p->nOuts - 1; i > 1 + _data->nIns; i--)
143#define Miaig_ForEachInputNode(i) for (i = 1; i < _data->nObjs - _data->nOuts; i++)
144#define Miaig_ForEachNodeStart(i, s) for (i = s; i < _data->nObjs - _data->nOuts; i++)
145#define Miaig_ForEachOutput(i) for (i = _data->nObjs - _data->nOuts; i < _data->nObjs; i++)
146#define Miaig_ForEachNodeOutput(i) for (i = 1 + _data->nIns; i < _data->nObjs; i++)
147#define Miaig_ForEachNodeOutputStart(i, s) for (i = s; i < _data->nObjs; i++)
148#define Miaig_ForEachObj(i) for (i = 0; i < _data->nObjs; i++)
149#define Miaig_ForEachObjFanin(i, iLit, k) Vi_ForEachEntry(&_data->pvFans[i], iLit, k)
150#define Miaig_ForEachObjFaninStart(i, iLit, k, s) Vi_ForEachEntryStart(&_data->pvFans[i], iLit, k, s)
151
152static inline int Rw_Lit2LitV(int *pMapV2V, int Lit) {
153 assert(Lit >= 0);
154 return Rw_Var2Lit(pMapV2V[Rw_Lit2Var(Lit)], Rw_LitIsCompl(Lit));
155}
156
157static inline int Rw_Lit2LitL(int *pMapV2L, int Lit) {
158 assert(Lit >= 0);
159 return Rw_LitNotCond(pMapV2L[Rw_Lit2Var(Lit)], Rw_LitIsCompl(Lit));
160}
161
163 char *pName; // network name
164 int refcount; // Reference counter
165 int nIns; // primary inputs
166 int nOuts; // primary outputs
167 int nObjs; // all objects
168 int nObjsAlloc; // allocated space
169 int nWords; // the truth table size
170 int nTravIds; // traversal ID counter
171 int *pTravIds; // traversal IDs
172 int *pCopy; // temp copy
173 int *pRefs; // reference counters
174 int *pLevel; // levels
175 int *pDist; // distances
176 word *pTruths[3]; // truth tables
177 word *pCare; // careset
178 word *pProd; // product
179 word *pExc; // Exc
180 vi *vOrder; // node order
181 vi *vOrderF; // fanin order
182 vi *vOrderF2; // fanin order
183 vi *vTfo; // transitive fanout cone
184 vi *pvFans; // the array of objects' fanins
185 int *pTable; // structural hashing table
186 int TableSize; // the size of the hash table
187 float nTransistor; // objective value
188 vi *pNtkMapped; // mapped network
189};
190
191class Miaig {
192public:
193 Miaig(void);
194 ~Miaig(void);
195 Miaig(const Miaig &m);
196 Miaig &operator=(const Miaig &m);
197 Miaig(int nIns, int nOuts, int nObjsAlloc);
198#ifdef RW_ABC
199 Miaig(Gia_Man_t *pGia);
200 Miaig(Abc_Ntk_t *pNtk);
201 Miaig(Mini_Aig_t *pMiniAig);
202#endif // RW_ABC
203
204public:
205#ifdef RW_ABC
206 void setExc(Gia_Man_t *pExc);
207#endif // RW_ABC
208
209public:
210 void addref(void);
211 void release(void);
212 bool operator==(const Miaig &m) const;
213
214private:
215 void create(int nIns, int nOuts, int nObjsAlloc);
216
217public:
218 int fromGia(Gia_Man_t *pGia);
219 int fromMiniAig(Mini_Aig_t *pMiniAig);
220
221public:
222 int &nIns(void);
223 int &nOuts(void);
224 int &nObjs(void);
225 int &nObjsAlloc(void);
226 int objIsPi(int i);
227 int objIsPo(int i);
228 int objIsNode(int i);
229 int objPiIdx(int i); // No check isPi
230 int objPoIdx(int i); // No check isPo
231 void print(void);
232 int appendObj(void);
233 void appendFanin(int i, int iLit);
234 int objFaninNum(int i);
235 int objFanin0(int i);
236 int objFanin1(int i);
237 int &objLevel(int i);
238 int &objRef(int i);
239 int &objTravId(int i);
240 int &objCopy(int i);
241 int &objDist(int i);
242 int &nTravIds(void);
243 word *objTruth(int i, int n);
244 vi *objFanins(int i);
245 int objType(int i);
246 int nWords(void);
247 void refObj(int iObj);
248 void derefObj(int iObj);
249 void derefObj_rec(int iObj, int iLitSkip);
250 void setName(char *pName);
251
252private:
253 int initializeLevels_rec(int iObj);
254 void initializeLevels(void);
255 void initializeRefs(void);
256 void verifyRefs(void);
257 void initializeTruth(void);
258 void initializeDists(void);
259
260private:
261 void markDfs_rec(int iObj);
262 int markDfs(void);
263 void markDistanceN_rec(int iObj, int n, int limit);
264 void markDistanceN(int Obj, int n);
265 void markCritical(void);
266 void markCritical_rec(int iObj);
267 void topoCollect_rec(int iObj);
268 vi *topoCollect(void);
269 void reduceFanins(vi *v);
270 int *createStops(void);
271 void collectSuper_rec(int iLit, int *pStop, vi *vSuper);
272 int checkConst(int iObj, word *pCare, word *pExc, int fCheck, int fVerbose);
273 void truthSimNode(int i);
274 word *truthSimNodeSubset(int i, int m);
275 word *truthSimNodeSubset2(int i, vi *vFanins, int nFanins);
276 void truthUpdate(vi *vTfo, word *pExc = NULL, int fCheck = 0);
277 int computeTfo_rec(int iObj);
278 vi *computeTfo(int iObj);
279 word *computeCareSet(int iObj, word *pExc = NULL);
280 vi *createRandomOrder(void);
281 void addPair(vi *vPair, int iFan1, int iFan2);
282 int findPair(vi *vPair);
283 int updateFanins(vi *vFans, int iFan1, int iFan2, int iLit);
284 void extractBest(vi *vPairs);
285 vi *findPairs(word *pSto, int nWords);
286 int findShared(int nNewNodesMax);
287 int hashTwo(int l0, int l1, int TableSize);
288 int *hashLookup(int *pTable, int l0, int l1, int TableSize);
289
290public:
291 float countAnd2(int reset = 0, int fDummy = 0);
292 // 0: amap 1: &nf 2: &simap
293 float countTransistors(int reset = 0, int nMode = 0);
294 int countLevel(int min = 0);
295
296private:
297 void dupDfs_rec(Miaig &pNew, int iObj);
298 int buildNodeBalance_rec(Miaig &pNew, vi *vFanins, int begin, int end, int fCprop, int fStrash);
299
300private:
301 int buildNode(int l0, int l1, int fCprop, int fStrash);
302 int buildNodeBalance(Miaig &pNew, vi *vFanins, int fCprop, int fStrash);
303 int buildNodeCascade(Miaig &pNew, vi *vFanins, int fCprop, int fStrash);
304
305private:
306 int expandOne(int iObj, int nAddedMax, int nDist, int nExpandableLevel, word *pExc, int fCheck, int fVerbose);
307 int reduceOne(int iObj, int fOnlyConst, int fOnlyBuffer, int fHeuristic, word *pExc, int fCheck, int fVerbose);
308 int expandThenReduceOne(int iNode, int nFaninAddLimit, int nDist, int nExpandableLevel, word *pExc, int fCheck, int fVerbose);
309
310public:
311 Miaig dup(int fRemDangle, int fMapped = 0);
312 Miaig dupDfs(void);
313 Miaig dupStrash(int fCprop, int fStrash, int fCascade);
314 Miaig dupMulti(int nFaninMax_, int nGrowth);
315 Miaig expand(int nFaninAddLimitAll, int nDist, int nExpandableLevel, word *pExc, int fCheck, int nVerbose);
316 Miaig share(int nNewNodesMax);
317 Miaig reduce(word *pExc, int fCheck, int fVerbose);
318 Miaig expandThenReduce(int nFaninAddLimit, int nDist, int nExpandableLevel, word *pExc, int fCheck, int fVerbose);
319 Miaig expandShareReduce(int nFaninAddLimitAll, int nDivs, int nDist, int nExpandableLevel, word *pExc, int fCheck, int nVerbose);
320 Miaig rewire(int nIters, float levelGrowRatio, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nMappedMode, int nDist, int fCheck, Gia_ChMan_t *pChMan, int nVerbose);
321#ifdef RW_ABC
322 Gia_Man_t *toGia(void);
323 Abc_Ntk_t *toNtk(int fMapped = 0);
324 Mini_Aig_t *toMiniAig(void);
325#endif // RW_ABC
326
327private:
328 int *_refcount;
329 Miaig_Data *_data;
330};
331
332inline Miaig::Miaig(void)
333 : _refcount(nullptr), _data(nullptr) {
334}
335
336inline Miaig::Miaig(int nIns, int nOuts, int nObjsAlloc)
337 : Miaig() {
338 create(nIns, nOuts, nObjsAlloc);
339}
340
341#ifdef RW_ABC
342inline Miaig::Miaig(Gia_Man_t *pGia) : Miaig() {
343 fromGia(pGia);
344}
345
346inline Miaig::Miaig(Abc_Ntk_t *pNtk) : Miaig() {
347 Mini_Aig_t *pMiniAig = Abc_ManRewireMiniAigFromNtk(pNtk);
348 fromMiniAig(pMiniAig);
349 Mini_AigStop(pMiniAig);
350}
351
352inline Miaig::Miaig(Mini_Aig_t *pMiniAig) : Miaig() {
353 fromMiniAig(pMiniAig);
354}
355#endif // RW_ABC
356
357inline Miaig::~Miaig(void) {
358 release();
359}
360
361inline Miaig::Miaig(const Miaig &m)
362 : _refcount(m._refcount), _data(m._data) {
363 addref();
364}
365
366inline Miaig &Miaig::operator=(const Miaig &m) {
367 if (this == &m) {
368 return *this;
369 }
370
371 if (m._refcount) {
372 RW_XADD(m._refcount, 1);
373 }
374
375 release();
376
377 _refcount = m._refcount;
378 _data = m._data;
379
380 return *this;
381}
382
383inline void Miaig::addref(void) {
384 if (_refcount) {
385 RW_XADD(_refcount, 1);
386 }
387}
388
389inline void Miaig::release(void) {
390 if (_refcount && RW_XADD(_refcount, -1) == 1) {
391 if (_data) {
392 if (_data->pName) free(_data->pName);
393 for (int i = 0; i < _data->nObjsAlloc; ++i)
394 if (_data->pvFans[i].ptr)
395 free(_data->pvFans[i].ptr);
396 free(_data->pvFans);
397 Vi_Free(_data->vOrder);
398 Vi_Free(_data->vOrderF);
399 Vi_Free(_data->vOrderF2);
400 Vi_Free(_data->vTfo);
401 free(_data->pTravIds);
402 free(_data->pCopy);
403 free(_data->pRefs);
404 free(_data->pTruths[0]);
405 if (_data->pCare) free(_data->pCare);
406 if (_data->pProd) free(_data->pProd);
407 if (_data->pExc) free(_data->pExc);
408 if (_data->pLevel) free(_data->pLevel);
409 if (_data->pDist) free(_data->pDist);
410 if (_data->pTable) free(_data->pTable);
411 if (_data->pNtkMapped) Vi_Free(_data->pNtkMapped);
412 delete _data;
413 }
414 }
415
416 _data = nullptr;
417 _refcount = nullptr;
418}
419
420inline bool Miaig::operator==(const Miaig &m) const {
421 return (_data == m._data);
422}
423
424inline int &Miaig::nIns(void) {
425 return _data->nIns;
426}
427
428inline int &Miaig::nOuts(void) {
429 return _data->nOuts;
430}
431
432inline int &Miaig::nObjs(void) {
433 return _data->nObjs;
434}
435
436inline int &Miaig::nObjsAlloc(void) {
437 return _data->nObjsAlloc;
438}
439
440inline int Miaig::objIsPi(int i) {
441 return i > 0 && i <= nIns();
442}
443
444inline int Miaig::objIsPo(int i) {
445 return i >= nObjs() - nOuts();
446}
447
448inline int Miaig::objIsNode(int i) {
449 return i > nIns() && i < nObjs() - nOuts();
450}
451
452inline int Miaig::objPiIdx(int i) {
453 // assert(objIsPi(i));
454 return i - 1;
455}
456
457inline int Miaig::objPoIdx(int i) {
458 // assert(objIsPo(i));
459 return i - (nObjs() - nOuts());
460}
461
462inline int Miaig::appendObj(void) {
463 assert(nObjs() < nObjsAlloc());
464 return nObjs()++;
465}
466
467inline void Miaig::appendFanin(int i, int iLit) {
468 Vi_PushOrder(objFanins(i), iLit);
469}
470
471inline int Miaig::objFaninNum(int i) {
472 return Vi_Size(objFanins(i));
473}
474
475inline int Miaig::objFanin0(int i) {
476 return Vi_Read(objFanins(i), 0);
477}
478
479inline int Miaig::objFanin1(int i) {
480 assert(objFaninNum(i) == 2);
481 return Vi_Read(objFanins(i), 1);
482}
483
484inline int &Miaig::objLevel(int i) {
485 return _data->pLevel[i];
486}
487
488inline int &Miaig::objRef(int i) {
489 return _data->pRefs[i];
490}
491
492inline int &Miaig::objTravId(int i) {
493 return _data->pTravIds[i];
494}
495
496inline int &Miaig::objCopy(int i) {
497 return _data->pCopy[i];
498}
499
500inline int &Miaig::objDist(int i) {
501 return _data->pDist[i];
502}
503
504inline int &Miaig::nTravIds(void) {
505 return _data->nTravIds;
506}
507
508inline int Miaig::nWords(void) {
509 return _data->nWords;
510}
511
512inline float Miaig::countAnd2(int reset, int fDummy) {
513 int i, Counter = 0;
515 Counter += objFaninNum(i) - 1;
516 }
517 return Counter;
518}
519
520inline int Miaig::countLevel(int min) {
521 initializeLevels();
522 int i, Level = (min) ? RW_INT_MAX : -1;
523 int (*compareFunc)(int, int) = (min) ? Rw_MinInt : Rw_MaxInt;
525 Level = compareFunc(Level, objLevel(i));
526 }
527 return Level;
528}
529
530inline word *Miaig::objTruth(int i, int n) {
531 return _data->pTruths[n] + nWords() * i;
532}
533
534inline vi *Miaig::objFanins(int i) {
535 return _data->pvFans + i;
536}
537
538inline int Miaig::objType(int i) {
539 return objTravId(i) == nTravIds();
540}
541
542} // namespace Rewire
543
544#ifdef RW_ABC
546#endif // RW_ABC
547
548#endif // REWIRE_MIAIG_H
struct Abc_Ntk_t_ Abc_Ntk_t
Definition abc.h:115
ABC_INT64_T iword
Definition abc_global.h:244
#define ABC_NAMESPACE_CXX_HEADER_START
#define ABC_NAMESPACE_CXX_HEADER_END
int & objLevel(int i)
void derefObj_rec(int iObj, int iLitSkip)
Miaig dup(int fRemDangle, int fMapped=0)
int & objRef(int i)
Miaig share(int nNewNodesMax)
int fromGia(Gia_Man_t *pGia)
int objFanin0(int i)
Gia_Man_t * toGia(void)
void refObj(int iObj)
int & objDist(int i)
int nWords(void)
int appendObj(void)
vi * objFanins(int i)
int & objCopy(int i)
word * objTruth(int i, int n)
int & nObjsAlloc(void)
int & nObjs(void)
void release(void)
int objFanin1(int i)
void addref(void)
Miaig dupDfs(void)
int countLevel(int min=0)
int objPoIdx(int i)
void appendFanin(int i, int iLit)
int & nOuts(void)
int & objTravId(int i)
Mini_Aig_t * toMiniAig(void)
float countAnd2(int reset=0, int fDummy=0)
Miaig expandShareReduce(int nFaninAddLimitAll, int nDivs, int nDist, int nExpandableLevel, word *pExc, int fCheck, int nVerbose)
int objFaninNum(int i)
bool operator==(const Miaig &m) const
void derefObj(int iObj)
Miaig expandThenReduce(int nFaninAddLimit, int nDist, int nExpandableLevel, word *pExc, int fCheck, int fVerbose)
void print(void)
Miaig rewire(int nIters, float levelGrowRatio, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nMappedMode, int nDist, int fCheck, Gia_ChMan_t *pChMan, int nVerbose)
void setExc(Gia_Man_t *pExc)
Abc_Ntk_t * toNtk(int fMapped=0)
int & nIns(void)
Miaig dupMulti(int nFaninMax_, int nGrowth)
int fromMiniAig(Mini_Aig_t *pMiniAig)
int objType(int i)
void setName(char *pName)
int objPiIdx(int i)
int & nTravIds(void)
int objIsPi(int i)
int objIsNode(int i)
int objIsPo(int i)
Miaig & operator=(const Miaig &m)
Miaig dupStrash(int fCprop, int fStrash, int fCascade)
float countTransistors(int reset=0, int nMode=0)
pcover expand()
pcover reduce()
int Var
Definition exorList.c:228
struct Gia_Man_t_ Gia_Man_t
Definition gia.h:96
struct Gia_ChMan_t_ Gia_ChMan_t
Definition gia.h:1416
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
struct Mini_Aig_t_ Mini_Aig_t
BASIC TYPES ///.
Definition miniaig.h:48
Mini_Aig_t * Abc_ManRewireMiniAigFromNtk(Abc_Ntk_t *pNtk)
Definition rewire_map.c:86
#define Rw_Var2Lit
#define Rw_Lit2Var
#define Rw_LitNot
#define Rw_LitIsCompl
#define Miaig_ForEachOutput(i)
#define Rw_LitRegular
#define Rw_LitNotCond
#define Rw_MaxInt
#define RW_INT_MAX
#define Miaig_ForEachNode(i)
#define Rw_MinInt
struct vi_ vi
#define assert(ex)
Definition util_old.h:213
VOID_HACK free()