diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2006-08-22 08:01:00 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2006-08-22 08:01:00 -0700 |
commit | 956842d9cc321eee3907889b820132e6e2b5ec62 (patch) | |
tree | 67a2a804c594eabc54d290cbd607a6ae65e583f6 /src | |
parent | 2fd3c1a25bb7a7ce334d2de5bac96bce446855d8 (diff) | |
download | abc-956842d9cc321eee3907889b820132e6e2b5ec62.tar.gz abc-956842d9cc321eee3907889b820132e6e2b5ec62.tar.bz2 abc-956842d9cc321eee3907889b820132e6e2b5ec62.zip |
Version abc60822
Diffstat (limited to 'src')
118 files changed, 6870 insertions, 7047 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index 8bd48874..10e2eb41 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -36,6 +36,7 @@ extern "C" { #include <time.h> #include "cuddInt.h" +#include "aig.h" #include "extra.h" #include "solver.h" #include "vec.h" @@ -71,9 +72,9 @@ typedef enum { /*------------------------------------------| | | SOP | BDD | AIG | Map | |-----------|-------|-------|-------|-------| -| Netlist | x | | | x | +| Netlist | x | | x | x | |-----------|-------|-------|-------|-------| -| Logic | x | x | | x | +| Logic | x | x | x | x | |-----------|-------|-------|-------|-------| | Strash | | | x | | |-----------|-------|-------|-------|-------| @@ -82,15 +83,19 @@ typedef enum { // object types typedef enum { - ABC_OBJ_NONE = 0, // 0: unknown - ABC_OBJ_NET, // 1: net - ABC_OBJ_NODE, // 2: node - ABC_OBJ_LATCH, // 3: latch - ABC_OBJ_PI, // 4: primary input terminal - ABC_OBJ_PO, // 5: primary output terminal - ABC_OBJ_ASSERT, // 6: assertion output - ABC_OBJ_BOX, // 7: box - ABC_OBJ_OTHER // 8: unused + ABC_OBJ_NONE = 0, // 0: unknown + ABC_OBJ_CONST1, // 1: constant 1 node (AIG only) + ABC_OBJ_PIO, // 2: inout terminal + ABC_OBJ_PI, // 3: primary input terminal + ABC_OBJ_PO, // 4: primary output terminal + ABC_OBJ_BI, // 5: box input terminal + ABC_OBJ_BO, // 6: box output terminal + ABC_OBJ_NET, // 7: net + ABC_OBJ_NODE, // 8: node + ABC_OBJ_LATCH, // 9: latch + ABC_OBJ_ASSERT, // 10: assertion output + ABC_OBJ_BOX, // 11: box + ABC_OBJ_OTHER // 12: unused } Abc_ObjType_t; // latch initial values @@ -113,8 +118,9 @@ typedef enum { #endif #endif -typedef struct Abc_Obj_t_ Abc_Obj_t; +typedef struct Abc_Lib_t_ Abc_Lib_t; typedef struct Abc_Ntk_t_ Abc_Ntk_t; +typedef struct Abc_Obj_t_ Abc_Obj_t; typedef struct Abc_Aig_t_ Abc_Aig_t; typedef struct Abc_ManTime_t_ Abc_ManTime_t; typedef struct Abc_ManCut_t_ Abc_ManCut_t; @@ -133,7 +139,7 @@ struct Abc_Obj_t_ // 12 words Abc_Ntk_t * pNtk; // the host network int Id; // the object ID // internal information - unsigned Type : 3; // the object type + unsigned Type : 4; // the object type unsigned fMarkA : 1; // the multipurpose mark unsigned fMarkB : 1; // the multipurpose mark unsigned fMarkC : 1; // the multipurpose mark @@ -142,7 +148,7 @@ struct Abc_Obj_t_ // 12 words unsigned fPersist: 1; // marks the persistant AIG node unsigned fCompl0 : 1; // complemented attribute of the first fanin in the AIG unsigned fCompl1 : 1; // complemented attribute of the second fanin in the AIG - unsigned TravId : 9; // the traversal ID (if changed, update Abc_NtkIncrementTravId) + unsigned TravId : 8; // the traversal ID (if changed, update Abc_NtkIncrementTravId) unsigned Level : 12; // the level of the node // connectivity Vec_Int_t vFanins; // the array of fanins @@ -168,8 +174,10 @@ struct Abc_Ntk_t_ Vec_Ptr_t * vCos; // the array of combinational outputs (POs, asserts, latches) Vec_Ptr_t * vPis; // the array of PIs Vec_Ptr_t * vPos; // the array of POs + Vec_Ptr_t * vPios; // the array of PIOs Vec_Ptr_t * vLatches; // the array of latches (or the cutset in the sequential network) Vec_Ptr_t * vAsserts; // the array of assertions + Vec_Ptr_t * vBoxes; // the array of boxes Vec_Ptr_t * vCutSet; // the array of cutset nodes (used in the sequential AIG) // the number of living objects int nObjs; // the number of live objs @@ -198,6 +206,17 @@ struct Abc_Ntk_t_ Vec_Ptr_t * vSupps; // CO support information int * pModel; // counter-example (for miters) Abc_Ntk_t * pExdc; // the EXDC network (if given) + // skew values (for latches) + float maxMeanCycle; // maximum mean cycle time + float globalSkew; // global skewing + Vec_Flt_t * vSkews; // endpoint skewing +}; + +struct Abc_Lib_t_ +{ + char * pName; // the name of the library + void * pManFunc; // functionality manager for the gates + st_table * tModules; // the table hashing gate/module names into their networks }; //////////////////////////////////////////////////////////////////////// @@ -227,9 +246,11 @@ static inline bool Abc_NtkHasMapping( Abc_Ntk_t * pNtk ) { return pN static inline bool Abc_NtkHasBlackbox( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BLACKBOX; } static inline bool Abc_NtkIsSopNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_SOP && pNtk->ntkType == ABC_NTK_NETLIST; } +static inline bool Abc_NtkIsAigNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_AIG && pNtk->ntkType == ABC_NTK_NETLIST; } static inline bool Abc_NtkIsMappedNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_MAP && pNtk->ntkType == ABC_NTK_NETLIST; } static inline bool Abc_NtkIsSopLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_SOP && pNtk->ntkType == ABC_NTK_LOGIC ; } static inline bool Abc_NtkIsBddLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BDD && pNtk->ntkType == ABC_NTK_LOGIC ; } +static inline bool Abc_NtkIsAigLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_AIG && pNtk->ntkType == ABC_NTK_LOGIC ; } static inline bool Abc_NtkIsMappedLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_MAP && pNtk->ntkType == ABC_NTK_LOGIC ; } static inline bool Abc_NtkIsComb( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vLatches) == 0; } @@ -240,7 +261,6 @@ static inline int Abc_NtkTravId( Abc_Ntk_t * pNtk ) { return pN static inline Abc_Ntk_t * Abc_NtkExdc( Abc_Ntk_t * pNtk ) { return pNtk->pExdc; } static inline Abc_Ntk_t * Abc_NtkBackup( Abc_Ntk_t * pNtk ) { return pNtk->pNetBackup; } static inline int Abc_NtkStep ( Abc_Ntk_t * pNtk ) { return pNtk->iStep; } -static inline Abc_Obj_t * Abc_NtkConst1( Abc_Ntk_t * pNtk ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vObjs, 0 ); } // setting data members of the network static inline void Abc_NtkSetName ( Abc_Ntk_t * pNtk, char * pName ) { pNtk->pName = pName; } @@ -260,6 +280,7 @@ static inline int Abc_NtkPiNum( Abc_Ntk_t * pNtk ) { return Ve static inline int Abc_NtkPoNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vPos); } static inline int Abc_NtkCiNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vCis); } static inline int Abc_NtkCoNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vCos); } +static inline int Abc_NtkBoxNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vBoxes); } // reading objects static inline Abc_Obj_t * Abc_NtkObj( Abc_Ntk_t * pNtk, int i ) { return (Abc_Obj_t *)Vec_PtrEntry( pNtk->vObjs, i ); } @@ -292,21 +313,23 @@ static inline Abc_Obj_t * Abc_ObjNot( Abc_Obj_t * p ) { return (A static inline Abc_Obj_t * Abc_ObjNotCond( Abc_Obj_t * p, int c ) { return (Abc_Obj_t *)((unsigned long)p ^ (unsigned long)(c!=0)); } // checking the object type -static inline bool Abc_ObjIsNode( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NODE; } -static inline bool Abc_ObjIsBox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BOX; } -static inline bool Abc_ObjIsNet( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NET; } -static inline bool Abc_ObjIsLatch( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_LATCH; } -static inline bool Abc_ObjIsAssert( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_ASSERT; } static inline bool Abc_ObjIsPi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI; } static inline bool Abc_ObjIsPo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO; } +static inline bool Abc_ObjIsBi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BI; } +static inline bool Abc_ObjIsBo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BO; } static inline bool Abc_ObjIsPio( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_PO; } -static inline bool Abc_ObjIsCi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_LATCH; } -static inline bool Abc_ObjIsCo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_LATCH || pObj->Type == ABC_OBJ_ASSERT; } +static inline bool Abc_ObjIsCi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_BI || pObj->Type == ABC_OBJ_LATCH; } +static inline bool Abc_ObjIsCo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_BO || pObj->Type == ABC_OBJ_LATCH || pObj->Type == ABC_OBJ_ASSERT; } static inline bool Abc_ObjIsCio( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_LATCH || pObj->Type == ABC_OBJ_ASSERT; } +static inline bool Abc_ObjIsAssert( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_ASSERT; } +static inline bool Abc_ObjIsNet( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NET; } +static inline bool Abc_ObjIsNode( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NODE; } +static inline bool Abc_ObjIsLatch( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_LATCH; } +static inline bool Abc_ObjIsBox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BOX; } // working with fanin/fanout edges -static inline int Abc_ObjFaninNum( Abc_Obj_t * pObj ) { return pObj->vFanins.nSize; } -static inline int Abc_ObjFanoutNum( Abc_Obj_t * pObj ) { return pObj->vFanouts.nSize; } +static inline int Abc_ObjFaninNum( Abc_Obj_t * pObj ) { return pObj->vFanins.nSize; } +static inline int Abc_ObjFanoutNum( Abc_Obj_t * pObj ) { return pObj->vFanouts.nSize; } static inline int Abc_ObjFaninId( Abc_Obj_t * pObj, int i) { return pObj->vFanins.pArray[i]; } static inline int Abc_ObjFaninId0( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[0]; } static inline int Abc_ObjFaninId1( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[1]; } @@ -330,19 +353,15 @@ static inline Abc_Obj_t * Abc_ObjChildCopy( Abc_Obj_t * pObj, int i ){ return Ab static inline Abc_Obj_t * Abc_ObjChild0Copy( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin0(pObj)->pCopy, Abc_ObjFaninC0(pObj) ); } static inline Abc_Obj_t * Abc_ObjChild1Copy( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin1(pObj)->pCopy, Abc_ObjFaninC1(pObj) ); } -// checking the node type -static inline bool Abc_NodeIsAigAnd( Abc_Obj_t * pNode ) { assert(Abc_NtkHasAig(pNode->pNtk)); return Abc_ObjFaninNum(pNode) == 2; } -static inline bool Abc_NodeIsAigChoice( Abc_Obj_t * pNode ) { assert(Abc_NtkHasAig(pNode->pNtk)); return pNode->pData != NULL && Abc_ObjFanoutNum(pNode) > 0; } -static inline bool Abc_NodeIsConst( Abc_Obj_t * pNode ) { assert(Abc_ObjIsNode(Abc_ObjRegular(pNode))); return Abc_ObjFaninNum(Abc_ObjRegular(pNode)) == 0; } -extern bool Abc_NodeIsConst0( Abc_Obj_t * pNode ); -extern bool Abc_NodeIsConst1( Abc_Obj_t * pNode ); -extern bool Abc_NodeIsBuf( Abc_Obj_t * pNode ); -extern bool Abc_NodeIsInv( Abc_Obj_t * pNode ); +// checking the AIG node types +static inline bool Abc_AigNodeIsConst( Abc_Obj_t * pNode ) { assert(Abc_NtkIsStrash(Abc_ObjRegular(pNode)->pNtk)||Abc_NtkIsSeq(Abc_ObjRegular(pNode)->pNtk)); return Abc_ObjRegular(pNode)->Type == ABC_OBJ_CONST1; } +static inline bool Abc_AigNodeIsAnd( Abc_Obj_t * pNode ) { assert(!Abc_ObjIsComplement(pNode)); assert(Abc_NtkIsStrash(pNode->pNtk)||Abc_NtkIsSeq(pNode->pNtk)); return Abc_ObjFaninNum(pNode) == 2; } +static inline bool Abc_AigNodeIsChoice( Abc_Obj_t * pNode ) { assert(!Abc_ObjIsComplement(pNode)); assert(Abc_NtkIsStrash(pNode->pNtk)||Abc_NtkIsSeq(pNode->pNtk)); return pNode->pData != NULL && Abc_ObjFanoutNum(pNode) > 0; } // handling persistent nodes -static inline int Abc_NodeIsPersistant( Abc_Obj_t * pNode ) { assert( Abc_NodeIsAigAnd(pNode) ); return pNode->fPersist; } -static inline void Abc_NodeSetPersistant( Abc_Obj_t * pNode ) { assert( Abc_NodeIsAigAnd(pNode) ); pNode->fPersist = 1; } -static inline void Abc_NodeClearPersistant( Abc_Obj_t * pNode ) { assert( Abc_NodeIsAigAnd(pNode) ); pNode->fPersist = 0; } +static inline int Abc_NodeIsPersistant( Abc_Obj_t * pNode ) { assert( Abc_AigNodeIsAnd(pNode) ); return pNode->fPersist; } +static inline void Abc_NodeSetPersistant( Abc_Obj_t * pNode ) { assert( Abc_AigNodeIsAnd(pNode) ); pNode->fPersist = 1; } +static inline void Abc_NodeClearPersistant( Abc_Obj_t * pNode ) { assert( Abc_AigNodeIsAnd(pNode) ); pNode->fPersist = 0; } // working with the traversal ID static inline void Abc_NodeSetTravId( Abc_Obj_t * pNode, int TravId ) { pNode->TravId = TravId; } @@ -362,6 +381,10 @@ static inline bool Abc_LatchIsInit1( Abc_Obj_t * pLatch ) { assert(Ab static inline bool Abc_LatchIsInitDc( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return pLatch->pData == (void *)ABC_INIT_DC; } static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Abc_ObjIsLatch(pLatch)); return (int)pLatch->pData; } +// skewing latches +static inline void Abc_NtkSetLatSkew ( Abc_Ntk_t * pNtk, int lat, float skew ) { Vec_FltWriteEntry( pNtk->vSkews, lat, skew ); } +static inline float Abc_NtkGetLatSkew ( Abc_Ntk_t * pNtk, int lat ) { if (lat >= Vec_FltSize( pNtk->vSkews )) return 0; else return Vec_FltEntry( pNtk->vSkews, lat ); } + // outputs the runtime in seconds #define PRT(a,t) printf("%s = ", (a)); printf("%6.2f sec\n", (float)(t)/(float)(CLOCKS_PER_SEC)) @@ -381,7 +404,7 @@ static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Ab if ( (pNode) == NULL || !Abc_ObjIsNode(pNode) ) {} else #define Abc_AigForEachAnd( pNtk, pNode, i ) \ for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ - if ( (pNode) == NULL || !Abc_NodeIsAigAnd(pNode) ) {} else + if ( (pNode) == NULL || !Abc_AigNodeIsAnd(pNode) ) {} else #define Abc_NtkForEachBox( pNtk, pNode, i ) \ for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ if ( (pNode) == NULL || !Abc_ObjIsBox(pNode) ) {} else @@ -423,6 +446,7 @@ extern void Abc_AigFree( Abc_Aig_t * pMan ); extern int Abc_AigCleanup( Abc_Aig_t * pMan ); extern bool Abc_AigCheck( Abc_Aig_t * pMan ); extern int Abc_AigGetLevelNum( Abc_Ntk_t * pNtk ); +extern Abc_Obj_t * Abc_AigConst1( Abc_Ntk_t * pNtk ); extern Abc_Obj_t * Abc_AigAnd( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ); extern Abc_Obj_t * Abc_AigAndLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ); extern Abc_Obj_t * Abc_AigXorLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1, int * pType ); @@ -491,12 +515,20 @@ extern int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fDirect ); extern void Abc_NodeBddToCnf( Abc_Obj_t * pNode, Extra_MmFlex_t * pMmMan, Vec_Str_t * vCube, char ** ppSop0, char ** ppSop1 ); extern int Abc_CountZddCubes( DdManager * dd, DdNode * zCover ); extern void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk ); +extern int Abc_NtkSopToAig( Abc_Ntk_t * pNtk ); +extern int Abc_NtkAigToBdd( Abc_Ntk_t * pNtk ); +extern int Abc_NtkMapToSop( Abc_Ntk_t * pNtk ); +extern int Abc_NtkLogicToSop( Abc_Ntk_t * pNtk, int fDirect ); +extern int Abc_NtkLogicToBdd( Abc_Ntk_t * pNtk ); +extern int Abc_NtkLogicToAig( Abc_Ntk_t * pNtk ); /*=== abcLatch.c ==========================================================*/ extern bool Abc_NtkLatchIsSelfFeed( Abc_Obj_t * pLatch ); extern int Abc_NtkCountSelfFeedLatches( Abc_Ntk_t * pNtk ); extern int Abc_NtkRemoveSelfFeedLatches( Abc_Ntk_t * pNtk ); -/*=== abcMap.c ==========================================================*/ -extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk ); +/*=== abcLib.c ==========================================================*/ +extern Abc_Lib_t * Abc_LibCreate( char * pName ); +extern void Abc_LibFree( Abc_Lib_t * pLib ); +extern Abc_Ntk_t * Abc_LibDeriveRoot( Abc_Lib_t * pLib ); /*=== abcMiter.c ==========================================================*/ extern int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk ); extern int Abc_NodeMinimumBase( Abc_Obj_t * pNode ); @@ -515,11 +547,14 @@ extern void Abc_NtkMiterReport( Abc_Ntk_t * pMiter ); extern int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ); extern Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial ); /*=== abcObj.c ==========================================================*/ +extern Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ); +extern void Abc_ObjRecycle( Abc_Obj_t * pObj ); +extern void Abc_ObjAdd( Abc_Obj_t * pObj ); extern Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ); +extern Abc_Obj_t * Abc_NtkCloneObj( Abc_Obj_t * pNode ); extern void Abc_NtkDeleteObj( Abc_Obj_t * pObj ); extern void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj ); extern Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName ); -extern Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName ); extern Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName ); extern Abc_Obj_t * Abc_NtkFindTerm( Abc_Ntk_t * pNtk, char * pName ); extern Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName ); @@ -535,11 +570,14 @@ extern Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFani extern Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ); extern Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ); extern Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ); +extern Abc_Obj_t * Abc_NodeCreateExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ); extern Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 ); -extern Abc_Obj_t * Abc_NodeClone( Abc_Obj_t * pNode ); -extern Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ); -extern void Abc_ObjRecycle( Abc_Obj_t * pObj ); -extern void Abc_ObjAdd( Abc_Obj_t * pObj ); +extern bool Abc_NodeIsConst( Abc_Obj_t * pNode ); +extern bool Abc_NodeIsConst0( Abc_Obj_t * pNode ); +extern bool Abc_NodeIsConst1( Abc_Obj_t * pNode ); +extern bool Abc_NodeIsBuf( Abc_Obj_t * pNode ); +extern bool Abc_NodeIsInv( Abc_Obj_t * pNode ); +extern void Abc_NodeComplement( Abc_Obj_t * pNode ); /*=== abcNames.c ====================================================*/ extern char * Abc_ObjName( Abc_Obj_t * pNode ); extern char * Abc_ObjNameSuffix( Abc_Obj_t * pObj, char * pSuffix ); @@ -598,6 +636,7 @@ extern void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk, in extern void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode, int fUseRealNames ); extern void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListNodes ); extern void Abc_NodePrintLevel( FILE * pFile, Abc_Obj_t * pNode ); +extern void Abc_NtkPrintSkews( FILE * pFile, Abc_Ntk_t * pNtk, int fPrintAll); /*=== abcProve.c ==========================================================*/ extern int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pParams ); /*=== abcReconv.c ==========================================================*/ @@ -657,6 +696,7 @@ extern bool Abc_SopIsBuf( char * pSop ); extern bool Abc_SopIsInv( char * pSop ); extern bool Abc_SopIsAndType( char * pSop ); extern bool Abc_SopIsOrType( char * pSop ); +extern int Abc_SopIsExorType( char * pSop ); extern bool Abc_SopCheck( char * pSop, int nFanins ); extern void Abc_SopWriteCnf( FILE * pFile, char * pClauses, Vec_Int_t * vVars ); extern void Abc_SopAddCnfToSolver( solver * pSat, char * pClauses, Vec_Int_t * vVars, Vec_Int_t * vTemp ); @@ -692,19 +732,6 @@ extern void Abc_NtkStopReverseLevels( Abc_Ntk_t * pNtk ); extern void Abc_NodeSetReverseLevel( Abc_Obj_t * pObj, int LevelR ); extern int Abc_NodeReadReverseLevel( Abc_Obj_t * pObj ); extern int Abc_NodeReadRequiredLevel( Abc_Obj_t * pObj ); -/*=== abcTrace.c ==========================================================*/ -extern void Abc_HManStart(); -extern void Abc_HManStop(); -extern int Abc_HManIsRunning(); -extern int Abc_HManGetNewNtkId(); -extern void Abc_HManAddObj( Abc_Obj_t * pObj ); -extern void Abc_HManAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin ); -extern void Abc_HManXorFaninC( Abc_Obj_t * pObj, int iFanin ); -extern void Abc_HManRemoveFanins( Abc_Obj_t * pObj ); -extern void Abc_HManAddProto( Abc_Obj_t * pObj, Abc_Obj_t * pProto ); -extern void Abc_HManMapAddEqu( Abc_Obj_t * pObj, Abc_Obj_t * pEqu ); -extern int Abc_HManPopulate( Abc_Ntk_t * pNtk ); -extern int Abc_HManVerify( int NtkIdOld, int NtkIdNew ); /*=== abcUtil.c ==========================================================*/ extern void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk ); extern void Abc_NtkOrderCisCos( Abc_Ntk_t * pNtk ); @@ -712,6 +739,7 @@ extern int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetLitNum( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetLitFactNum( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk ); +extern int Abc_NtkGetAigNodeNum( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetClauseNum( Abc_Ntk_t * pNtk ); extern double Abc_NtkGetMappedArea( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetExorNum( Abc_Ntk_t * pNtk ); diff --git a/src/base/abc/abcAig.c b/src/base/abc/abcAig.c index 67209a31..75e0292e 100644 --- a/src/base/abc/abcAig.c +++ b/src/base/abc/abcAig.c @@ -50,6 +50,7 @@ struct Abc_Aig_t_ { Abc_Ntk_t * pNtkAig; // the AIG network + Abc_Obj_t * pConst1; // the constant 1 object (not a node!) Abc_Obj_t ** pBins; // the table bins int nBins; // the size of the table int nEntries; // the total number of entries in the table @@ -130,10 +131,17 @@ Abc_Aig_t * Abc_AigAlloc( Abc_Ntk_t * pNtkAig ) pMan->pBins = ALLOC( Abc_Obj_t *, pMan->nBins ); memset( pMan->pBins, 0, sizeof(Abc_Obj_t *) * pMan->nBins ); pMan->vNodes = Vec_PtrAlloc( 100 ); + pMan->vLevels = Vec_VecAlloc( 100 ); + pMan->vLevelsR = Vec_VecAlloc( 100 ); pMan->vStackReplaceOld = Vec_PtrAlloc( 100 ); pMan->vStackReplaceNew = Vec_PtrAlloc( 100 ); - pMan->vLevels = Vec_VecAlloc( 100 ); - pMan->vLevelsR = Vec_VecAlloc( 100 ); + // create the constant node + pMan->pConst1 = Abc_ObjAlloc( pNtkAig, ABC_OBJ_CONST1 ); + // add to the array of objects, count it as object but not as node + assert( pNtkAig->vObjs->nSize == 0 ); + pMan->pConst1->Id = pNtkAig->vObjs->nSize; + Vec_PtrPush( pNtkAig->vObjs, pMan->pConst1 ); + pNtkAig->nObjs++; // save the current network pMan->pNtkAig = pNtkAig; return pMan; @@ -216,7 +224,7 @@ bool Abc_AigCheck( Abc_Aig_t * pMan ) nFanins = Abc_ObjFaninNum(pObj); if ( nFanins == 0 ) { - if ( pObj != Abc_NtkConst1(pMan->pNtkAig) ) + if ( !Abc_AigNodeIsConst(pObj) ) { printf( "Abc_AigCheck: The AIG has non-standard constant nodes.\n" ); return 0; @@ -370,7 +378,7 @@ Abc_Obj_t * Abc_AigAndLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ) Abc_Obj_t * pAnd, * pConst1; unsigned Key; // check for trivial cases - pConst1 = Abc_NtkConst1(pMan->pNtkAig); + pConst1 = Abc_AigConst1(pMan->pNtkAig); if ( p0 == p1 ) return p0; if ( p0 == Abc_ObjNot(p1) ) @@ -642,6 +650,23 @@ void Abc_AigRehash( Abc_Aig_t * pMan ) SeeAlso [] ***********************************************************************/ +Abc_Obj_t * Abc_AigConst1( Abc_Ntk_t * pNtk ) +{ + assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsSeq(pNtk) ); + return ((Abc_Aig_t *)pNtk->pManFunc)->pConst1; +} + +/**Function************************************************************* + + Synopsis [Performs canonicization step.] + + Description [The argument nodes can be complemented.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ Abc_Obj_t * Abc_AigAnd( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ) { Abc_Obj_t * pAnd; @@ -719,7 +744,7 @@ Abc_Obj_t * Abc_AigMiter( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs ) { int i; if ( vPairs->nSize == 0 ) - return Abc_ObjNot( Abc_NtkConst1(pMan->pNtkAig) ); + return Abc_ObjNot( Abc_AigConst1(pMan->pNtkAig) ); assert( vPairs->nSize % 2 == 0 ); // go through the cubes of the node's SOP for ( i = 0; i < vPairs->nSize; i += 2 ) @@ -745,7 +770,7 @@ Abc_Obj_t * Abc_AigMiter2( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs ) int i; assert( vPairs->nSize % 2 == 0 ); // go through the cubes of the node's SOP - pMiter = Abc_ObjNot( Abc_NtkConst1(pMan->pNtkAig) ); + pMiter = Abc_ObjNot( Abc_AigConst1(pMan->pNtkAig) ); for ( i = 0; i < vPairs->nSize; i += 2 ) { pXor = Abc_AigXor( pMan, vPairs->pArray[i], vPairs->pArray[i+1] ); @@ -850,7 +875,6 @@ void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, i Abc_AigAndDelete( pMan, pFanout ); // remove the fanins of the old fanout Abc_ObjRemoveFanins( pFanout ); - Abc_HManRemoveFanins( pFanout ); // recreate the old fanout with new fanins and add it to the table Abc_AigAndCreateFrom( pMan, pFanin1, pFanin2, pFanout ); assert( Abc_AigNodeIsAcyclic(pFanout, pFanout) ); @@ -872,7 +896,7 @@ void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, i // the fanout has changed, update EXOR status of its fanouts Abc_ObjForEachFanout( pFanout, pFanoutFanout, v ) - if ( Abc_NodeIsAigAnd(pFanoutFanout) ) + if ( Abc_AigNodeIsAnd(pFanoutFanout) ) pFanoutFanout->fExor = Abc_NodeIsExorType(pFanoutFanout); } // if the node has no fanouts left, remove its MFFC @@ -1199,7 +1223,7 @@ void Abc_AigPrintNode( Abc_Obj_t * pNode ) printf( "CI %4s%s.\n", Abc_ObjName(pNodeR), Abc_ObjIsComplement(pNode)? "\'" : "" ); return; } - if ( Abc_NodeIsConst(pNodeR) ) + if ( Abc_AigNodeIsConst(pNodeR) ) { printf( "Constant 1 %s.\n", Abc_ObjIsComplement(pNode)? "(complemented)" : "" ); return; @@ -1230,7 +1254,7 @@ bool Abc_AigNodeIsAcyclic( Abc_Obj_t * pNode, Abc_Obj_t * pRoot ) Abc_Obj_t * pFanin0, * pFanin1; Abc_Obj_t * pChild00, * pChild01; Abc_Obj_t * pChild10, * pChild11; - if ( !Abc_NodeIsAigAnd(pNode) ) + if ( !Abc_AigNodeIsAnd(pNode) ) return 1; pFanin0 = Abc_ObjFanin0(pNode); pFanin1 = Abc_ObjFanin1(pNode); @@ -1306,7 +1330,7 @@ void Abc_AigSetNodePhases( Abc_Ntk_t * pNtk ) Abc_Obj_t * pObj; int i; assert( Abc_NtkIsDfsOrdered(pNtk) ); - Abc_NtkConst1(pNtk)->fPhase = 1; + Abc_AigConst1(pNtk)->fPhase = 1; // Abc_NtkForEachCi( pNtk, pObj, i ) // pObj->fPhase = 0; Abc_NtkForEachPi( pNtk, pObj, i ) diff --git a/src/base/abc/abcDfs.c b/src/base/abc/abcDfs.c index 8448578e..54676e9d 100644 --- a/src/base/abc/abcDfs.c +++ b/src/base/abc/abcDfs.c @@ -127,7 +127,7 @@ void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) // mark the node as visited Abc_NodeSetTravIdCurrent( pNode ); // skip the CI - if ( Abc_ObjIsCi(pNode) ) + if ( Abc_ObjIsCi(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsConst(pNode)) ) return; assert( Abc_ObjIsNode( pNode ) || Abc_ObjIsBox( pNode ) ); // visit the transitive fanin of the node @@ -167,9 +167,10 @@ Vec_Ptr_t * Abc_NtkDfsReverse( Abc_Ntk_t * pNtk ) Abc_NtkDfsReverse_rec( pFanout, vNodes ); } // add constant nodes in the end - Abc_NtkForEachNode( pNtk, pObj, i ) - if ( Abc_NodeIsConst(pObj) ) - Vec_PtrPush( vNodes, pObj ); + if ( !Abc_NtkIsStrash(pNtk) ) + Abc_NtkForEachNode( pNtk, pObj, i ) + if ( Abc_NodeIsConst(pObj) ) + Vec_PtrPush( vNodes, pObj ); return vNodes; } @@ -235,7 +236,7 @@ bool Abc_NtkIsDfsOrdered( Abc_Ntk_t * pNtk ) if ( !Abc_NodeIsTravIdCurrent(pFanin) ) return 0; // check the choices of the node - if ( Abc_NtkIsStrash(pNtk) && Abc_NodeIsAigChoice(pNode) ) + if ( Abc_NtkIsStrash(pNtk) && Abc_AigNodeIsChoice(pNode) ) for ( pFanin = pNode->pData; pFanin; pFanin = pFanin->pData ) if ( !Abc_NodeIsTravIdCurrent(pFanin) ) return 0; @@ -399,14 +400,14 @@ void Abc_AigDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) // mark the node as visited Abc_NodeSetTravIdCurrent( pNode ); // skip the PI - if ( Abc_ObjIsCi(pNode) ) + if ( Abc_ObjIsCi(pNode) || Abc_AigNodeIsConst(pNode) ) return; assert( Abc_ObjIsNode( pNode ) ); // visit the transitive fanin of the node Abc_ObjForEachFanin( pNode, pFanin, i ) Abc_AigDfs_rec( pFanin, vNodes ); // visit the equivalent nodes - if ( Abc_NodeIsAigChoice( pNode ) ) + if ( Abc_AigNodeIsChoice( pNode ) ) for ( pFanin = pNode->pData; pFanin; pFanin = pFanin->pData ) Abc_AigDfs_rec( pFanin, vNodes ); // add the node after the fanins have been added @@ -712,7 +713,7 @@ int Abc_AigSetChoiceLevels( Abc_Ntk_t * pNtk ) Abc_NodeSetTravIdCurrent( pObj ); pObj->pCopy = NULL; } - pObj = Abc_NtkConst1( pNtk ); + pObj = Abc_AigConst1( pNtk ); Abc_NodeSetTravIdCurrent( pObj ); pObj->pCopy = NULL; // set levels of all other nodes diff --git a/src/base/abc/abcFanio.c b/src/base/abc/abcFanio.c index 2a84212e..1d2ae23b 100644 --- a/src/base/abc/abcFanio.c +++ b/src/base/abc/abcFanio.c @@ -50,7 +50,6 @@ void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin ) Vec_IntPushMem( pObj->pNtk->pMmStep, &pFaninR->vFanouts, pObj->Id ); if ( Abc_ObjIsComplement(pFanin) ) Abc_ObjSetFaninC( pObj, Abc_ObjFaninNum(pObj)-1 ); -// Abc_HManAddFanin( pObj, pFanin ); } diff --git a/src/base/abc/abcFunc.c b/src/base/abc/abcFunc.c index da50a9aa..7ffe7eac 100644 --- a/src/base/abc/abcFunc.c +++ b/src/base/abc/abcFunc.c @@ -19,6 +19,8 @@ ***********************************************************************/ #include "abc.h" +#include "main.h" +#include "mio.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -26,7 +28,9 @@ #define ABC_MUX_CUBES 100000 -static int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase ); +static int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase ); +static DdNode * Abc_ConvertAigToBdd( DdManager * dd, Aig_Obj_t * pRoot); +static Aig_Obj_t * Abc_ConvertSopToAig( Aig_Man_t * pMan, char * pSop ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -95,7 +99,6 @@ DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop ) DdNode * bSum, * bCube, * bTemp, * bVar; char * pCube; int nVars, Value, v; - extern int Abc_SopIsExorType( char * pSop ); // start the cover nVars = Abc_SopGetVarNum(pSop); @@ -516,6 +519,374 @@ int Abc_CountZddCubes( DdManager * dd, DdNode * zCover ) } +/**Function************************************************************* + + Synopsis [Converts the network from SOP to AIG representation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkSopToAig( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode; + Aig_Man_t * pMan; + int i; + + assert( Abc_NtkIsSopLogic(pNtk) ); + + // start the functionality manager + pMan = Aig_ManStart(); + + // convert each node from SOP to BDD + Abc_NtkForEachNode( pNtk, pNode, i ) + { + assert( pNode->pData ); + pNode->pData = Abc_ConvertSopToAig( pMan, pNode->pData ); + if ( pNode->pData == NULL ) + { + printf( "Abc_NtkSopToAig: Error while converting SOP into AIG.\n" ); + return 0; + } + } + Extra_MmFlexStop( pNtk->pManFunc, 0 ); + pNtk->pManFunc = pMan; + + // update the network type + pNtk->ntkFunc = ABC_FUNC_AIG; + return 1; +} + + +/**Function************************************************************* + + Synopsis [Strashes one logic node using its SOP.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Abc_ConvertSopToAigInternal( Aig_Man_t * pMan, char * pSop ) +{ + Aig_Obj_t * pAnd, * pSum; + int i, Value, nFanins; + char * pCube; + // get the number of variables + nFanins = Abc_SopGetVarNum(pSop); + // go through the cubes of the node's SOP + pSum = Aig_ManConst0(pMan); + Abc_SopForEachCube( pSop, nFanins, pCube ) + { + // create the AND of literals + pAnd = Aig_ManConst1(pMan); + Abc_CubeForEachVar( pCube, Value, i ) + { + if ( Value == '1' ) + pAnd = Aig_And( pMan, pAnd, Aig_IthVar(pMan,i) ); + else if ( Value == '0' ) + pAnd = Aig_And( pMan, pAnd, Aig_Not(Aig_IthVar(pMan,i)) ); + } + // add to the sum of cubes + pSum = Aig_Or( pMan, pSum, pAnd ); + } + // decide whether to complement the result + if ( Abc_SopIsComplement(pSop) ) + pSum = Aig_Not(pSum); + return pSum; +} + +/**Function************************************************************* + + Synopsis [Converts the network from AIG to BDD representation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Abc_ConvertSopToAig( Aig_Man_t * pMan, char * pSop ) +{ + extern Aig_Obj_t * Dec_GraphFactorSop( Aig_Man_t * pMan, char * pSop ); + int fUseFactor = 1; + // consider the constant node + if ( Abc_SopGetVarNum(pSop) == 0 ) + return Aig_NotCond( Aig_ManConst1(pMan), Abc_SopIsConst0(pSop) ); + // consider the special case of EXOR function + if ( Abc_SopIsExorType(pSop) ) + return Aig_NotCond( Aig_CreateExor(pMan, Abc_SopGetVarNum(pSop)), Abc_SopIsComplement(pSop) ); + // decide when to use factoring + if ( fUseFactor && Abc_SopGetVarNum(pSop) > 2 && Abc_SopGetCubeNum(pSop) > 1 ) + return Dec_GraphFactorSop( pMan, pSop ); + return Abc_ConvertSopToAigInternal( pMan, pSop ); +} + +/**Function************************************************************* + + Synopsis [Converts the network from AIG to BDD representation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkAigToBdd( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode; + Aig_Man_t * pMan; + DdManager * dd; + int nFaninsMax, i; + + assert( Abc_NtkIsAigLogic(pNtk) ); + + // start the functionality manager + nFaninsMax = Abc_NtkGetFaninMax( pNtk ); + if ( nFaninsMax == 0 ) + printf( "Warning: The network has only constant nodes.\n" ); + + dd = Cudd_Init( nFaninsMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); + + // set the mapping of AIG nodes into the BDD nodes + pMan = pNtk->pManFunc; + assert( Aig_ManPiNum(pMan) >= nFaninsMax ); + for ( i = 0; i < nFaninsMax; i++ ) + Aig_ManPi(pMan, i)->pData = Cudd_bddIthVar(dd, i); + + // convert each node from SOP to BDD + Abc_NtkForEachNode( pNtk, pNode, i ) + { + assert( pNode->pData ); + pNode->pData = Abc_ConvertAigToBdd( dd, pNode->pData ); + if ( pNode->pData == NULL ) + { + printf( "Abc_NtkSopToBdd: Error while converting SOP into BDD.\n" ); + return 0; + } + Cudd_Ref( pNode->pData ); + } + + Aig_ManStop( pNtk->pManFunc ); + pNtk->pManFunc = dd; + + // update the network type + pNtk->ntkFunc = ABC_FUNC_BDD; + return 1; +} + +/**Function************************************************************* + + Synopsis [Construct BDDs and mark AIG nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ConvertAigToBdd_rec1( DdManager * dd, Aig_Obj_t * pObj ) +{ + assert( !Aig_IsComplement(pObj) ); + if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) ) + return; + Abc_ConvertAigToBdd_rec1( dd, Aig_ObjFanin0(pObj) ); + Abc_ConvertAigToBdd_rec1( dd, Aig_ObjFanin1(pObj) ); + pObj->pData = Cudd_bddAnd( dd, (DdNode *)Aig_ObjChild0Copy(pObj), (DdNode *)Aig_ObjChild1Copy(pObj) ); + Cudd_Ref( pObj->pData ); + assert( !Aig_ObjIsMarkA(pObj) ); // loop detection + Aig_ObjSetMarkA( pObj ); +} + +/**Function************************************************************* + + Synopsis [Dereference BDDs and unmark AIG nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ConvertAigToBdd_rec2( DdManager * dd, Aig_Obj_t * pObj ) +{ + assert( !Aig_IsComplement(pObj) ); + if ( !Aig_ObjIsNode(pObj) || !Aig_ObjIsMarkA(pObj) ) + return; + Abc_ConvertAigToBdd_rec2( dd, Aig_ObjFanin0(pObj) ); + Abc_ConvertAigToBdd_rec2( dd, Aig_ObjFanin1(pObj) ); + Cudd_RecursiveDeref( dd, pObj->pData ); + pObj->pData = NULL; + assert( Aig_ObjIsMarkA(pObj) ); // loop detection + Aig_ObjClearMarkA( pObj ); +} + +/**Function************************************************************* + + Synopsis [Converts the network from AIG to BDD representation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Abc_ConvertAigToBdd( DdManager * dd, Aig_Obj_t * pRoot ) +{ + DdNode * bFunc; + // construct BDD + Abc_ConvertAigToBdd_rec1( dd, Aig_Regular(pRoot) ); + // hold on to the result + bFunc = Cudd_NotCond( Aig_Regular(pRoot)->pData, Aig_IsComplement(pRoot) ); Cudd_Ref( bFunc ); + // dereference BDD + Abc_ConvertAigToBdd_rec2( dd, Aig_Regular(pRoot) ); + // return the result + Cudd_Deref( bFunc ); + return bFunc; +} + +/**Function************************************************************* + + Synopsis [Unmaps the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkMapToSop( Abc_Ntk_t * pNtk ) +{ + extern void * Abc_FrameReadLibGen(); + Abc_Obj_t * pNode; + char * pSop; + int i; + + assert( Abc_NtkIsMappedLogic(pNtk) ); + // update the functionality manager + assert( pNtk->pManFunc == Abc_FrameReadLibGen() ); + pNtk->pManFunc = Extra_MmFlexStart(); + pNtk->ntkFunc = ABC_FUNC_SOP; + // update the nodes + Abc_NtkForEachNode( pNtk, pNode, i ) + { + pSop = Mio_GateReadSop(pNode->pData); + assert( Abc_SopGetVarNum(pSop) == Abc_ObjFaninNum(pNode) ); + pNode->pData = Abc_SopRegister( pNtk->pManFunc, pSop ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Convers logic network to the SOP form.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkLogicToSop( Abc_Ntk_t * pNtk, int fDirect ) +{ + assert( Abc_NtkIsLogic(pNtk) ); + if ( Abc_NtkIsSopLogic(pNtk) ) + { + if ( !fDirect ) + return 1; + if ( !Abc_NtkSopToBdd(pNtk) ) + return 0; + return Abc_NtkBddToSop(pNtk, fDirect); + } + if ( Abc_NtkIsMappedLogic(pNtk) ) + return Abc_NtkMapToSop(pNtk); + if ( Abc_NtkIsBddLogic(pNtk) ) + return Abc_NtkBddToSop(pNtk, fDirect); + if ( Abc_NtkIsAigLogic(pNtk) ) + { + if ( !Abc_NtkAigToBdd(pNtk) ) + return 0; + return Abc_NtkBddToSop(pNtk, fDirect); + } + assert( 0 ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Convers logic network to the SOP form.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkLogicToBdd( Abc_Ntk_t * pNtk ) +{ + assert( Abc_NtkIsLogic(pNtk) ); + if ( Abc_NtkIsBddLogic(pNtk) ) + return 1; + if ( Abc_NtkIsMappedLogic(pNtk) ) + { + Abc_NtkMapToSop(pNtk); + return Abc_NtkSopToBdd(pNtk); + } + if ( Abc_NtkIsSopLogic(pNtk) ) + return Abc_NtkSopToBdd(pNtk); + if ( Abc_NtkIsAigLogic(pNtk) ) + return Abc_NtkAigToBdd(pNtk); + assert( 0 ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Convers logic network to the SOP form.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkLogicToAig( Abc_Ntk_t * pNtk ) +{ + assert( Abc_NtkIsLogic(pNtk) ); + if ( Abc_NtkIsAigLogic(pNtk) ) + return 1; + if ( Abc_NtkIsMappedLogic(pNtk) ) + { + Abc_NtkMapToSop(pNtk); + return Abc_NtkSopToAig(pNtk); + } + if ( Abc_NtkIsBddLogic(pNtk) ) + { + if ( !Abc_NtkBddToSop(pNtk,0) ) + return 0; + return Abc_NtkSopToAig(pNtk); + } + if ( Abc_NtkIsSopLogic(pNtk) ) + return Abc_NtkSopToAig(pNtk); + assert( 0 ); + return 0; +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcLatch.c b/src/base/abc/abcLatch.c index 610e311a..be487051 100644 --- a/src/base/abc/abcLatch.c +++ b/src/base/abc/abcLatch.c @@ -110,14 +110,18 @@ int Abc_NtkCountSelfFeedLatches( Abc_Ntk_t * pNtk ) ***********************************************************************/ int Abc_NtkRemoveSelfFeedLatches( Abc_Ntk_t * pNtk ) { - Abc_Obj_t * pLatch; + Abc_Obj_t * pLatch, * pConst1; int i, Counter; Counter = 0; Abc_NtkForEachLatch( pNtk, pLatch, i ) { if ( Abc_NtkLatchIsSelfFeed( pLatch ) ) { - Abc_ObjPatchFanin( pLatch, Abc_ObjFanin0(pLatch), Abc_NtkConst1(pNtk) ); + if ( Abc_NtkIsStrash(pNtk) || Abc_NtkIsSeq(pNtk) ) + pConst1 = Abc_AigConst1(pNtk); + else + pConst1 = Abc_NodeCreateConst1(pNtk); + Abc_ObjPatchFanin( pLatch, Abc_ObjFanin0(pLatch), pConst1 ); Counter++; } } diff --git a/src/base/abc/abcLib.c b/src/base/abc/abcLib.c new file mode 100644 index 00000000..80bcc516 --- /dev/null +++ b/src/base/abc/abcLib.c @@ -0,0 +1,116 @@ +/**CFile**************************************************************** + + FileName [abcLib.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Functions to manipulate verilog libraries.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcLib.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Create the library.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Lib_t * Abc_LibCreate( char * pName ) +{ + Abc_Lib_t * p; + p = ALLOC( Abc_Lib_t, 1 ); + memset( p, 0, sizeof(Abc_Lib_t) ); + p->pName = Extra_UtilStrsav( pName ); + p->tModules = st_init_table( strcmp, st_strhash ); + p->pManFunc = Aig_ManStart(); + return p; +} + +/**Function************************************************************* + + Synopsis [Frees the library.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_LibFree( Abc_Lib_t * pLib ) +{ + st_generator * gen; + Abc_Ntk_t * pNtk; + char * pName; + if ( pLib->pName ) + free( pLib->pName ); + if ( pLib->pManFunc ) + Aig_ManStop( pLib->pManFunc ); + if ( pLib->tModules ) + { + st_foreach_item( pLib->tModules, gen, (char**)&pName, (char**)&pNtk ) + Abc_NtkDelete( pNtk ); + st_free_table( pLib->tModules ); + } + free( pLib ); +} + +/**Function************************************************************* + + Synopsis [Frees the library.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_LibDeriveRoot( Abc_Lib_t * pLib ) +{ + st_generator * gen; + Abc_Ntk_t * pNtk; + char * pName; + if ( st_count(pLib->tModules) > 1 ) + { + printf( "The design includes more than one module and is currently not used.\n" ); + return NULL; + } + // find the network + st_foreach_item( pLib->tModules, gen, (char**)&pName, (char**)&pNtk ) + { + st_free_gen(gen); + break; + } + return pNtk; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abc/abcNames.c b/src/base/abc/abcNames.c index e2172872..ef1d0980 100644 --- a/src/base/abc/abcNames.c +++ b/src/base/abc/abcNames.c @@ -45,6 +45,7 @@ char * Abc_ObjName( Abc_Obj_t * pObj ) { static char Buffer[500]; char * pName; + int Counter; // check if the object is in the lookup table // if ( stmm_lookup( pObj->pNtk->tObj2Name, (char *)pObj, &pName ) ) @@ -63,7 +64,11 @@ char * Abc_ObjName( Abc_Obj_t * pObj ) if ( pObj->pData ) sprintf( Buffer, "%s", pObj->pData ); else + { sprintf( Buffer, "[%d]", pObj->Id ); // make sure this name is unique!!! + for ( Counter = 1; Nm_ManFindIdByName(pObj->pNtk->pManName, Buffer, NULL) >= 0; Counter++ ) + sprintf( Buffer, "[%d]_%d", pObj->Id, Counter ); + } } else { @@ -71,6 +76,8 @@ char * Abc_ObjName( Abc_Obj_t * pObj ) // internal nodes have made up names assert( Abc_ObjIsNode(pObj) || Abc_ObjIsLatch(pObj) ); sprintf( Buffer, "[%d]", pObj->Id ); + for ( Counter = 1; Nm_ManFindIdByName(pObj->pNtk->pManName, Buffer, NULL) >= 0; Counter++ ) + sprintf( Buffer, "[%d]_%d", pObj->Id, Counter ); } return Buffer; } diff --git a/src/base/abc/abcNetlist.c b/src/base/abc/abcNetlist.c index f9e529c7..456d2aa2 100644 --- a/src/base/abc/abcNetlist.c +++ b/src/base/abc/abcNetlist.c @@ -264,8 +264,18 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk, int fDirect ) pNtkNew = Abc_NtkLogicSopToNetlist( pNtk ); Abc_NtkSopToBdd(pNtk); } - else + else if ( Abc_NtkIsAigLogic(pNtk) ) + { + if ( !Abc_NtkAigToBdd(pNtk) ) + return NULL; + if ( !Abc_NtkBddToSop(pNtk, fDirect) ) + return NULL; + pNtkNew = Abc_NtkLogicSopToNetlist( pNtk ); + Abc_NtkSopToAig(pNtk); + } + else if ( Abc_NtkIsSopLogic(pNtk) || Abc_NtkIsMappedLogic(pNtk) ) pNtkNew = Abc_NtkLogicSopToNetlist( pNtk ); + else assert( 0 ); return pNtkNew; } @@ -408,20 +418,20 @@ Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk ) assert( Abc_NtkIsStrash(pNtk) ); // start the network pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); + // if the constant node is used, duplicate it + pObj = Abc_AigConst1(pNtk); + if ( Abc_ObjFanoutNum(pObj) > 0 ) + pObj->pCopy = Abc_NodeCreateConst1(pNtkNew); // duplicate the nodes and create node functions Abc_NtkForEachNode( pNtk, pObj, i ) { - if ( Abc_NodeIsConst(pObj) ) - continue; Abc_NtkDupObj(pNtkNew, pObj); pObj->pCopy->pData = Abc_SopCreateAnd2( pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); } // create the choice nodes Abc_NtkForEachNode( pNtk, pObj, i ) { - if ( Abc_NodeIsConst(pObj) ) - continue; - if ( !Abc_NodeIsAigChoice(pObj) ) + if ( !Abc_AigNodeIsChoice(pObj) ) continue; // create an OR gate pNodeNew = Abc_NtkCreateNode(pNtkNew); @@ -497,17 +507,20 @@ Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk ) // collect the nodes to be used (marks all nodes with current TravId) vNodes = Abc_NtkDfs( pNtk, 0 ); // create inverters for the CI and remember them + pObj = Abc_AigConst1(pNtk); + if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) ) + { + pObj->pCopy = Abc_NodeCreateConst1(pNtkNew); + pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy ); + } Abc_NtkForEachCi( pNtk, pObj, i ) if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) ) pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy ); // duplicate the nodes, create node functions, and inverters Vec_PtrForEachEntry( vNodes, pObj, i ) { - if ( !Abc_NodeIsConst(pObj) ) - { - Abc_NtkDupObj( pNtkNew, pObj ); - pObj->pCopy->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, 2, NULL ); - } + Abc_NtkDupObj( pNtkNew, pObj ); + pObj->pCopy->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, 2, NULL ); if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) ) pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy ); } diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c index 1a07ebf2..f21d79be 100644 --- a/src/base/abc/abcNtk.c +++ b/src/base/abc/abcNtk.c @@ -50,49 +50,40 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func ) memset( pNtk, 0, sizeof(Abc_Ntk_t) ); pNtk->ntkType = Type; pNtk->ntkFunc = Func; - pNtk->Id = !Abc_HManIsRunning()? 0 : Abc_HManGetNewNtkId(); // start the object storage pNtk->vObjs = Vec_PtrAlloc( 100 ); pNtk->vLatches = Vec_PtrAlloc( 100 ); pNtk->vAsserts = Vec_PtrAlloc( 100 ); + pNtk->vPios = Vec_PtrAlloc( 100 ); pNtk->vPis = Vec_PtrAlloc( 100 ); pNtk->vPos = Vec_PtrAlloc( 100 ); pNtk->vCis = Vec_PtrAlloc( 100 ); pNtk->vCos = Vec_PtrAlloc( 100 ); pNtk->vCutSet = Vec_PtrAlloc( 100 ); + pNtk->vBoxes = Vec_PtrAlloc( 100 ); + pNtk->vSkews = Vec_FltAlloc( 100 ); // start the memory managers pNtk->pMmObj = Extra_MmFixedStart( sizeof(Abc_Obj_t) ); pNtk->pMmStep = Extra_MmStepStart( ABC_NUM_STEPS ); // get ready to assign the first Obj ID pNtk->nTravIds = 1; // start the functionality manager - if ( Abc_NtkHasSop(pNtk) ) + if ( Abc_NtkIsStrash(pNtk) ) + pNtk->pManFunc = Abc_AigAlloc( pNtk ); + else if ( Abc_NtkIsSeq(pNtk) ) + pNtk->pManFunc = Seq_Create( pNtk ); + else if ( Abc_NtkHasSop(pNtk) ) pNtk->pManFunc = Extra_MmFlexStart(); else if ( Abc_NtkHasBdd(pNtk) ) pNtk->pManFunc = Cudd_Init( 20, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); else if ( Abc_NtkHasAig(pNtk) ) - { - if ( Abc_NtkIsStrash(pNtk) ) - pNtk->pManFunc = Abc_AigAlloc( pNtk ); - else - pNtk->pManFunc = Seq_Create( pNtk ); - } + pNtk->pManFunc = Aig_ManStart(); else if ( Abc_NtkHasMapping(pNtk) ) pNtk->pManFunc = Abc_FrameReadLibGen(); else if ( !Abc_NtkHasBlackbox(pNtk) ) assert( 0 ); - // allocate constant node - if ( !Abc_NtkIsNetlist(pNtk) ) - { - Abc_NodeCreateConst1( pNtk ); - // do not count this node towards the total number of nodes - pNtk->nNodes -= 1; - } - else - Vec_PtrPush( pNtk->vObjs, NULL ); // name manager pNtk->pManName = Nm_ManCreate( 1000 ); -//printf( "Allocated newtork %p\n", pNtk ); return pNtk; } @@ -123,8 +114,8 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_ Abc_NtkForEachNode( pNtk, pObj, i ) pObj->pCopy = NULL; // map the constant nodes - if ( Abc_NtkConst1(pNtk) ) - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew); + if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) ) + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); // clone the PIs/POs/latches Abc_NtkForEachPi( pNtk, pObj, i ) Abc_NtkDupObj(pNtkNew, pObj); @@ -134,14 +125,6 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_ Abc_NtkDupObj(pNtkNew, pObj); Abc_NtkForEachLatch( pNtk, pObj, i ) Abc_NtkDupObj(pNtkNew, pObj); - if ( Abc_NtkIsStrash(pNtk) && Abc_HManIsRunning() ) - { - Abc_HManAddProto( Abc_NtkConst1(pNtk)->pCopy, Abc_NtkConst1(pNtk) ); - Abc_NtkForEachCi( pNtk, pObj, i ) - Abc_HManAddProto( pObj->pCopy, pObj ); - Abc_NtkForEachCo( pNtk, pObj, i ) - Abc_HManAddProto( pObj->pCopy, pObj ); - } // transfer the names if ( Type != ABC_NTK_NETLIST ) Abc_NtkDupCioNamesTable( pNtk, pNtkNew ); @@ -180,8 +163,8 @@ Abc_Ntk_t * Abc_NtkStartFromNoLatches( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc Abc_NtkForEachNode( pNtk, pObj, i ) pObj->pCopy = NULL; // map the constant nodes - if ( Abc_NtkConst1(pNtk) ) - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew); + if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) ) + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); // clone the PIs/POs/latches Abc_NtkForEachPi( pNtk, pObj, i ) Abc_NtkDupObj(pNtkNew, pObj); @@ -226,8 +209,8 @@ Abc_Ntk_t * Abc_NtkStartFromDual( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkF Abc_NtkForEachNode( pNtk, pObj, i ) pObj->pCopy = NULL; // map the constant nodes - if ( Abc_NtkConst1(pNtk) ) - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew); + if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) ) + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); // clone the PIs/POs/latches Abc_NtkForEachPi( pNtk, pObj, i ) Abc_NtkDupObj(pNtkNew, pObj); @@ -412,11 +395,6 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk ) Abc_ObjForEachFanin( pObj, pFanin, k ) Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); } - if ( Abc_NtkIsStrash(pNtk) && Abc_HManIsRunning() ) - { - Abc_AigForEachAnd( pNtk, pObj, i ) - Abc_HManAddProto( pObj->pCopy, pObj ); - } // duplicate the EXDC Ntk if ( pNtk->pExdc ) pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc ); @@ -454,7 +432,8 @@ Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, char * pNode pNtkNew->pName = Extra_UtilStrsav(Buffer); // establish connection between the constant nodes - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew); + if ( Abc_NtkIsStrash(pNtk) ) + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); // collect the nodes in the TFI of the output (mark the TFI) vNodes = Abc_NtkDfsNodes( pNtk, &pNode, 1 ); @@ -523,7 +502,8 @@ Abc_Ntk_t * Abc_NtkCreateMffc( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, char * pNode pNtkNew->pName = Extra_UtilStrsav(Buffer); // establish connection between the constant nodes - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew); + if ( Abc_NtkIsStrash(pNtk) ) + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); // collect the nodes in MFFC vCone = Vec_PtrAlloc( 100 ); @@ -584,6 +564,10 @@ Abc_Ntk_t * Abc_NtkCreateTarget( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t int i; assert( Abc_NtkIsLogic(pNtk) ); + + // convert the network into the AIG form + if ( !Abc_NtkLogicToAig(pNtk) ) + return NULL; // start the network Abc_NtkCleanCopy( pNtk ); @@ -604,7 +588,7 @@ Abc_Ntk_t * Abc_NtkCreateTarget( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t Vec_PtrFree( vNodes ); // add the PO - pFinal = Abc_NtkConst1( pNtkNew ); + pFinal = Abc_AigConst1( pNtkNew ); Vec_PtrForEachEntry( vRoots, pObj, i ) { if ( Abc_ObjIsCo(pObj) ) @@ -746,6 +730,7 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) if ( pNtk->pExdc ) Abc_NtkDelete( pNtk->pExdc ); // free the arrays + Vec_PtrFree( pNtk->vPios ); Vec_PtrFree( pNtk->vPis ); Vec_PtrFree( pNtk->vPos ); Vec_PtrFree( pNtk->vCis ); @@ -754,6 +739,8 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) Vec_PtrFree( pNtk->vLatches ); Vec_PtrFree( pNtk->vObjs ); Vec_PtrFree( pNtk->vCutSet ); + Vec_PtrFree( pNtk->vBoxes ); + Vec_FltFree( pNtk->vSkews ); if ( pNtk->pModel ) free( pNtk->pModel ); TotalMemory = 0; TotalMemory += Extra_MmFixedReadMemUsage(pNtk->pMmObj); @@ -762,25 +749,26 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) // free the storage Extra_MmFixedStop( pNtk->pMmObj, 0 ); Extra_MmStepStop ( pNtk->pMmStep, 0 ); + // name manager + Nm_ManFree( pNtk->pManName ); // free the timing manager if ( pNtk->pManTime ) Abc_ManTimeStop( pNtk->pManTime ); // start the functionality manager - if ( Abc_NtkHasSop(pNtk) ) + if ( Abc_NtkIsStrash(pNtk) ) + Abc_AigFree( pNtk->pManFunc ); + else if ( Abc_NtkIsSeq(pNtk) ) + Seq_Delete( pNtk->pManFunc ); + else if ( Abc_NtkHasSop(pNtk) ) Extra_MmFlexStop( pNtk->pManFunc, 0 ); else if ( Abc_NtkHasBdd(pNtk) ) Extra_StopManager( pNtk->pManFunc ); else if ( Abc_NtkHasAig(pNtk) ) - { - if ( Abc_NtkIsStrash(pNtk) ) - Abc_AigFree( pNtk->pManFunc ); - else - Seq_Delete( pNtk->pManFunc ); - } - else if ( !Abc_NtkHasMapping(pNtk) && !Abc_NtkHasBlackbox(pNtk) ) + Aig_ManStop( pNtk->pManFunc ); + else if ( Abc_NtkHasMapping(pNtk) ) + pNtk->pManFunc = NULL; + else if ( !Abc_NtkHasBlackbox(pNtk) ) assert( 0 ); - // name manager - Nm_ManFree( pNtk->pManName ); // free the hierarchy if ( Abc_NtkIsNetlist(pNtk) && pNtk->tName2Model ) { @@ -820,9 +808,7 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk ) if ( Abc_ObjFaninNum(pNet) > 0 ) continue; // add the constant 0 driver - pNode = Abc_NtkCreateNode( pNtk ); - // set the constant function - Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, " 0\n") ); + pNode = Abc_NodeCreateConst0( pNtk ); // add the fanout net Abc_ObjAddFanin( pNet, pNode ); // add the net to those for which the warning will be printed diff --git a/src/base/abc/abcObj.c b/src/base/abc/abcObj.c index 337ba428..2811be16 100644 --- a/src/base/abc/abcObj.c +++ b/src/base/abc/abcObj.c @@ -50,8 +50,6 @@ Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ) pObj->pNtk = pNtk; pObj->Type = Type; pObj->Id = -1; - if ( pNtk->ntkType != ABC_NTK_NETLIST ) - Abc_HManAddObj( pObj ); return pObj; } @@ -99,13 +97,13 @@ void Abc_ObjAdd( Abc_Obj_t * pObj ) Vec_PtrPush( pNtk->vObjs, pObj ); pNtk->nObjs++; // perform specialized operations depending on the object type - if ( Abc_ObjIsNet(pObj) ) + if ( Abc_ObjIsNode(pObj) ) { - pNtk->nNets++; + pNtk->nNodes++; } - else if ( Abc_ObjIsNode(pObj) ) + else if ( Abc_ObjIsNet(pObj) ) { - pNtk->nNodes++; + pNtk->nNets++; } else if ( Abc_ObjIsPi(pObj) ) { @@ -128,14 +126,20 @@ void Abc_ObjAdd( Abc_Obj_t * pObj ) Vec_PtrPush( pNtk->vAsserts, pObj ); Vec_PtrPush( pNtk->vCos, pObj ); } - else if ( Abc_ObjIsBox(pObj) ) + else if ( Abc_ObjIsBi(pObj) ) { - pNtk->nBoxes++; + Vec_PtrPush( pNtk->vCis, pObj ); } - else + else if ( Abc_ObjIsBo(pObj) ) { - assert( 0 ); + Vec_PtrPush( pNtk->vCos, pObj ); } + else if ( Abc_ObjIsBox(pObj) ) + { + pNtk->nBoxes++; + Vec_PtrPush( pNtk->vBoxes, pObj ); + } + else assert( 0 ); } /**Function************************************************************* @@ -161,14 +165,17 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ) { if ( pNtkNew->ntkFunc == pObj->pNtk->ntkFunc ) { - if ( Abc_NtkHasSop(pNtkNew) ) + if ( Abc_NtkIsStrash(pNtkNew) || Abc_NtkIsSeq(pNtkNew) ) + {} + else if ( Abc_NtkHasSop(pNtkNew) ) pObjNew->pData = Abc_SopRegister( pNtkNew->pManFunc, pObj->pData ); else if ( Abc_NtkHasBdd(pNtkNew) ) pObjNew->pData = Cudd_bddTransfer(pObj->pNtk->pManFunc, pNtkNew->pManFunc, pObj->pData), Cudd_Ref(pObjNew->pData); + else if ( Abc_NtkHasAig(pNtkNew) ) + pObjNew->pData = Aig_Transfer(pObj->pNtk->pManFunc, pNtkNew->pManFunc, pObj->pData, Abc_ObjFaninNum(pObj)); else if ( Abc_NtkHasMapping(pNtkNew) ) pObjNew->pData = pObj->pData; - else if ( !Abc_NtkHasAig(pNtkNew) ) - assert( 0 ); + else assert( 0 ); } } else if ( Abc_ObjIsNet(pObj) ) // copy the name @@ -181,6 +188,27 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ) return pObjNew; } +/**Function************************************************************* + + Synopsis [Clones the objects in the same network but does not assign its function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCloneObj( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pClone, * pFanin; + int i; + pClone = Abc_ObjAlloc( pObj->pNtk, pObj->Type ); + Abc_ObjAdd( pClone ); + Abc_ObjForEachFanin( pObj, pFanin, i ) + Abc_ObjAddFanin( pClone, pFanin ); + return pClone; +} /**Function************************************************************* @@ -249,6 +277,14 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj ) Vec_PtrRemove( pObj->pNtk->vPos, pObj ); Vec_PtrRemove( pObj->pNtk->vCos, pObj ); } + else if ( Abc_ObjIsBi(pObj) ) + { + Vec_PtrRemove( pObj->pNtk->vCis, pObj ); + } + else if ( Abc_ObjIsBo(pObj) ) + { + Vec_PtrRemove( pObj->pNtk->vCos, pObj ); + } else if ( Abc_ObjIsAssert(pObj) ) { Vec_PtrRemove( pObj->pNtk->vAsserts, pObj ); @@ -257,6 +293,7 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj ) else if ( Abc_ObjIsBox(pObj) ) { pNtk->nBoxes--; + Vec_PtrRemove( pObj->pNtk->vBoxes, pObj ); } else assert( 0 ); @@ -371,30 +408,6 @@ Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName ) -{ - Abc_Obj_t * pNode; - int i; - // search the node among COs - Abc_NtkForEachCo( pNtk, pNode, i ) - { - if ( strcmp( Abc_ObjName(pNode), pName ) == 0 ) - return pNode; - } - return NULL; -} - -/**Function************************************************************* - - Synopsis [Returns the net with the given name.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName ) { Abc_Obj_t * pNet; @@ -409,7 +422,7 @@ Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName ) /**Function************************************************************* - Synopsis [Returns the net with the given name.] + Synopsis [Returns the CI/CO terminal with the given name.] Description [] @@ -456,7 +469,7 @@ Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName ) /**Function************************************************************* - Synopsis [Create the new node.] + Synopsis [Create node.] Description [] @@ -472,10 +485,10 @@ Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk ) Abc_ObjAdd( pObj ); return pObj; } - + /**Function************************************************************* - Synopsis [Create the new node.] + Synopsis [Create multi-input/multi-output box.] Description [] @@ -494,7 +507,7 @@ Abc_Obj_t * Abc_NtkCreateBox( Abc_Ntk_t * pNtk ) /**Function************************************************************* - Synopsis [Create the new node.] + Synopsis [Create primary input.] Description [] @@ -513,7 +526,7 @@ Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk ) /**Function************************************************************* - Synopsis [Create the new node.] + Synopsis [Create primary output.] Description [] @@ -532,7 +545,7 @@ Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk ) /**Function************************************************************* - Synopsis [Create the new node.] + Synopsis [Creates latch.] Description [] @@ -552,7 +565,7 @@ Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk ) /**Function************************************************************* - Synopsis [Create the new node.] + Synopsis [Creates assert.] Description [] @@ -571,7 +584,7 @@ Abc_Obj_t * Abc_NtkCreateAssert( Abc_Ntk_t * pNtk ) /**Function************************************************************* - Synopsis [Creates inverter.] + Synopsis [Creates constant 0 node.] Description [] @@ -583,12 +596,14 @@ Abc_Obj_t * Abc_NtkCreateAssert( Abc_Ntk_t * pNtk ) Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pNode; - assert( !Abc_NtkHasAig(pNtk) ); + assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); pNode = Abc_NtkCreateNode( pNtk ); if ( Abc_NtkHasSop(pNtk) ) pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 0\n" ); else if ( Abc_NtkHasBdd(pNtk) ) pNode->pData = Cudd_ReadLogicZero(pNtk->pManFunc), Cudd_Ref( pNode->pData ); + else if ( Abc_NtkHasAig(pNtk) ) + pNode->pData = Aig_ManConst0(pNtk->pManFunc); else if ( Abc_NtkHasMapping(pNtk) ) pNode->pData = Mio_LibraryReadConst0(Abc_FrameReadLibGen()); else if ( !Abc_NtkHasBlackbox(pNtk) ) @@ -598,7 +613,7 @@ Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk ) /**Function************************************************************* - Synopsis [Creates inverter.] + Synopsis [Creates constant 1 node.] Description [] @@ -610,13 +625,14 @@ Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk ) Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pNode; + assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); pNode = Abc_NtkCreateNode( pNtk ); - if ( Abc_NtkHasAig(pNtk) ) - return pNode; if ( Abc_NtkHasSop(pNtk) ) pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 1\n" ); else if ( Abc_NtkHasBdd(pNtk) ) pNode->pData = Cudd_ReadOne(pNtk->pManFunc), Cudd_Ref( pNode->pData ); + else if ( Abc_NtkHasAig(pNtk) ) + pNode->pData = Aig_ManConst1(pNtk->pManFunc); else if ( Abc_NtkHasMapping(pNtk) ) pNode->pData = Mio_LibraryReadConst1(Abc_FrameReadLibGen()); else if ( !Abc_NtkHasBlackbox(pNtk) ) @@ -645,6 +661,8 @@ Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) pNode->pData = Abc_SopRegister( pNtk->pManFunc, "0 1\n" ); else if ( Abc_NtkHasBdd(pNtk) ) pNode->pData = Cudd_Not(Cudd_bddIthVar(pNtk->pManFunc,0)), Cudd_Ref( pNode->pData ); + else if ( Abc_NtkHasAig(pNtk) ) + pNode->pData = Aig_Not(Aig_IthVar(pNtk->pManFunc,0)); else if ( Abc_NtkHasMapping(pNtk) ) pNode->pData = Mio_LibraryReadInv(Abc_FrameReadLibGen()); else @@ -673,6 +691,8 @@ Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) pNode->pData = Abc_SopRegister( pNtk->pManFunc, "1 1\n" ); else if ( Abc_NtkHasBdd(pNtk) ) pNode->pData = Cudd_bddIthVar(pNtk->pManFunc,0), Cudd_Ref( pNode->pData ); + else if ( Abc_NtkHasAig(pNtk) ) + pNode->pData = Aig_IthVar(pNtk->pManFunc,0); else if ( Abc_NtkHasMapping(pNtk) ) pNode->pData = Mio_LibraryReadBuf(Abc_FrameReadLibGen()); else @@ -682,7 +702,7 @@ Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin ) /**Function************************************************************* - Synopsis [Creates inverter.] + Synopsis [Creates AND.] Description [] @@ -695,35 +715,16 @@ Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) { Abc_Obj_t * pNode; int i; - assert( Abc_NtkIsLogic(pNtk) ); + assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); pNode = Abc_NtkCreateNode( pNtk ); for ( i = 0; i < vFanins->nSize; i++ ) Abc_ObjAddFanin( pNode, vFanins->pArray[i] ); if ( Abc_NtkHasSop(pNtk) ) - { - char * pSop; - pSop = Extra_MmFlexEntryFetch( pNtk->pManFunc, vFanins->nSize + 4 ); - for ( i = 0; i < vFanins->nSize; i++ ) - pSop[i] = '1'; - pSop[i++] = ' '; - pSop[i++] = '1'; - pSop[i++] = '\n'; - pSop[i++] = 0; - assert( i == vFanins->nSize + 4 ); - pNode->pData = pSop; - } + pNode->pData = Abc_SopCreateAnd( pNtk->pManFunc, Vec_PtrSize(vFanins), NULL ); else if ( Abc_NtkHasBdd(pNtk) ) - { - DdManager * dd = pNtk->pManFunc; - DdNode * bFunc, * bTemp; - bFunc = Cudd_ReadOne(dd); Cudd_Ref( bFunc ); - for ( i = 0; i < vFanins->nSize; i++ ) - { - bFunc = Cudd_bddAnd( dd, bTemp = bFunc, Cudd_bddIthVar(pNtk->pManFunc,i) ); Cudd_Ref( bFunc ); - Cudd_RecursiveDeref( dd, bTemp ); - } - pNode->pData = bFunc; - } + pNode->pData = Extra_bddCreateAnd( pNtk->pManFunc, Vec_PtrSize(vFanins) ), Cudd_Ref(pNode->pData); + else if ( Abc_NtkHasAig(pNtk) ) + pNode->pData = Aig_CreateAnd( pNtk->pManFunc, Vec_PtrSize(vFanins) ); else assert( 0 ); return pNode; @@ -731,7 +732,7 @@ Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) /**Function************************************************************* - Synopsis [Creates inverter.] + Synopsis [Creates OR.] Description [] @@ -744,35 +745,16 @@ Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) { Abc_Obj_t * pNode; int i; - assert( Abc_NtkIsLogic(pNtk) ); + assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); pNode = Abc_NtkCreateNode( pNtk ); for ( i = 0; i < vFanins->nSize; i++ ) Abc_ObjAddFanin( pNode, vFanins->pArray[i] ); if ( Abc_NtkHasSop(pNtk) ) - { - char * pSop; - pSop = Extra_MmFlexEntryFetch( pNtk->pManFunc, vFanins->nSize + 4 ); - for ( i = 0; i < vFanins->nSize; i++ ) - pSop[i] = '0'; - pSop[i++] = ' '; - pSop[i++] = '0'; - pSop[i++] = '\n'; - pSop[i++] = 0; - assert( i == vFanins->nSize + 4 ); - pNode->pData = pSop; - } + pNode->pData = Abc_SopCreateOr( pNtk->pManFunc, Vec_PtrSize(vFanins), NULL ); else if ( Abc_NtkHasBdd(pNtk) ) - { - DdManager * dd = pNtk->pManFunc; - DdNode * bFunc, * bTemp; - bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc ); - for ( i = 0; i < vFanins->nSize; i++ ) - { - bFunc = Cudd_bddOr( dd, bTemp = bFunc, Cudd_bddIthVar(pNtk->pManFunc,i) ); Cudd_Ref( bFunc ); - Cudd_RecursiveDeref( dd, bTemp ); - } - pNode->pData = bFunc; - } + pNode->pData = Extra_bddCreateOr( pNtk->pManFunc, Vec_PtrSize(vFanins) ), Cudd_Ref(pNode->pData); + else if ( Abc_NtkHasAig(pNtk) ) + pNode->pData = Aig_CreateOr( pNtk->pManFunc, Vec_PtrSize(vFanins) ); else assert( 0 ); return pNode; @@ -780,7 +762,37 @@ Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) /**Function************************************************************* - Synopsis [Creates inverter.] + Synopsis [Creates EXOR.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NodeCreateExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins ) +{ + Abc_Obj_t * pNode; + int i; + assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); + pNode = Abc_NtkCreateNode( pNtk ); + for ( i = 0; i < vFanins->nSize; i++ ) + Abc_ObjAddFanin( pNode, vFanins->pArray[i] ); + if ( Abc_NtkHasSop(pNtk) ) + pNode->pData = Abc_SopCreateXorSpecial( pNtk->pManFunc, Vec_PtrSize(vFanins) ); + else if ( Abc_NtkHasBdd(pNtk) ) + pNode->pData = Extra_bddCreateExor( pNtk->pManFunc, Vec_PtrSize(vFanins) ), Cudd_Ref(pNode->pData); + else if ( Abc_NtkHasAig(pNtk) ) + pNode->pData = Aig_CreateExor( pNtk->pManFunc, Vec_PtrSize(vFanins) ); + else + assert( 0 ); + return pNode; +} + +/**Function************************************************************* + + Synopsis [Creates MUX.] Description [] @@ -801,14 +813,17 @@ Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode->pData = Abc_SopRegister( pNtk->pManFunc, "11- 1\n0-1 1\n" ); else if ( Abc_NtkHasBdd(pNtk) ) pNode->pData = Cudd_bddIte(pNtk->pManFunc,Cudd_bddIthVar(pNtk->pManFunc,0),Cudd_bddIthVar(pNtk->pManFunc,1),Cudd_bddIthVar(pNtk->pManFunc,2)), Cudd_Ref( pNode->pData ); + else if ( Abc_NtkHasAig(pNtk) ) + pNode->pData = Aig_Mux(pNtk->pManFunc,Aig_IthVar(pNtk->pManFunc,0),Aig_IthVar(pNtk->pManFunc,1),Aig_IthVar(pNtk->pManFunc,2)); else assert( 0 ); return pNode; } + /**Function************************************************************* - Synopsis [Clones the given node but does not assign the function.] + Synopsis [Returns 1 if the node is a constant 0 node.] Description [] @@ -817,22 +832,16 @@ Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NodeClone( Abc_Obj_t * pNode ) -{ - Abc_Obj_t * pClone, * pFanin; - int i; - assert( Abc_ObjIsNode(pNode) ); - pClone = Abc_NtkCreateNode( pNode->pNtk ); - Abc_ObjForEachFanin( pNode, pFanin, i ) - Abc_ObjAddFanin( pClone, pFanin ); - return pClone; +bool Abc_NodeIsConst( Abc_Obj_t * pNode ) +{ + assert( Abc_NtkIsLogic(pNode->pNtk) || Abc_NtkIsNetlist(pNode->pNtk) ); + assert( Abc_ObjIsNode(pNode) ); + return Abc_ObjFaninNum(pNode) == 0; } - - /**Function************************************************************* - Synopsis [] + Synopsis [Returns 1 if the node is a constant 0 node.] Description [] @@ -844,23 +853,25 @@ Abc_Obj_t * Abc_NodeClone( Abc_Obj_t * pNode ) bool Abc_NodeIsConst0( Abc_Obj_t * pNode ) { Abc_Ntk_t * pNtk = pNode->pNtk; - assert(Abc_ObjIsNode(pNode)); - assert(Abc_NodeIsConst(pNode)); + assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); + assert( Abc_ObjIsNode(pNode) ); + if ( !Abc_NodeIsConst(pNode) ) + return 0; if ( Abc_NtkHasSop(pNtk) ) return Abc_SopIsConst0(pNode->pData); if ( Abc_NtkHasBdd(pNtk) ) return Cudd_IsComplement(pNode->pData); if ( Abc_NtkHasAig(pNtk) ) - return Abc_ObjNot(pNode) == Abc_NtkConst1(pNode->pNtk); + return Aig_IsComplement(pNode->pData); if ( Abc_NtkHasMapping(pNtk) ) - return pNode->pData == Mio_LibraryReadConst0(Abc_FrameReadLibSuper()); + return pNode->pData == Mio_LibraryReadConst0(Abc_FrameReadLibGen()); assert( 0 ); return 0; } /**Function************************************************************* - Synopsis [] + Synopsis [Returns 1 if the node is a constant 1 node.] Description [] @@ -872,23 +883,25 @@ bool Abc_NodeIsConst0( Abc_Obj_t * pNode ) bool Abc_NodeIsConst1( Abc_Obj_t * pNode ) { Abc_Ntk_t * pNtk = pNode->pNtk; - assert(Abc_ObjIsNode(pNode)); - assert(Abc_NodeIsConst(pNode)); + assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); + assert( Abc_ObjIsNode(pNode) ); + if ( !Abc_NodeIsConst(pNode) ) + return 0; if ( Abc_NtkHasSop(pNtk) ) return Abc_SopIsConst1(pNode->pData); if ( Abc_NtkHasBdd(pNtk) ) return !Cudd_IsComplement(pNode->pData); if ( Abc_NtkHasAig(pNtk) ) - return pNode == Abc_NtkConst1(pNode->pNtk); + return !Aig_IsComplement(pNode->pData); if ( Abc_NtkHasMapping(pNtk) ) - return pNode->pData == Mio_LibraryReadConst1(Abc_FrameReadLibSuper()); + return pNode->pData == Mio_LibraryReadConst1(Abc_FrameReadLibGen()); assert( 0 ); return 0; } /**Function************************************************************* - Synopsis [] + Synopsis [Returns 1 if the node is a buffer.] Description [] @@ -900,7 +913,8 @@ bool Abc_NodeIsConst1( Abc_Obj_t * pNode ) bool Abc_NodeIsBuf( Abc_Obj_t * pNode ) { Abc_Ntk_t * pNtk = pNode->pNtk; - assert(Abc_ObjIsNode(pNode)); + assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); + assert( Abc_ObjIsNode(pNode) ); if ( Abc_ObjFaninNum(pNode) != 1 ) return 0; if ( Abc_NtkHasSop(pNtk) ) @@ -908,16 +922,16 @@ bool Abc_NodeIsBuf( Abc_Obj_t * pNode ) if ( Abc_NtkHasBdd(pNtk) ) return !Cudd_IsComplement(pNode->pData); if ( Abc_NtkHasAig(pNtk) ) - return 0; + return !Aig_IsComplement(pNode->pData); if ( Abc_NtkHasMapping(pNtk) ) - return pNode->pData == Mio_LibraryReadBuf(Abc_FrameReadLibSuper()); + return pNode->pData == Mio_LibraryReadBuf(Abc_FrameReadLibGen()); assert( 0 ); return 0; } /**Function************************************************************* - Synopsis [] + Synopsis [Returns 1 if the node is an inverter.] Description [] @@ -929,7 +943,8 @@ bool Abc_NodeIsBuf( Abc_Obj_t * pNode ) bool Abc_NodeIsInv( Abc_Obj_t * pNode ) { Abc_Ntk_t * pNtk = pNode->pNtk; - assert(Abc_ObjIsNode(pNode)); + assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) ); + assert( Abc_ObjIsNode(pNode) ); if ( Abc_ObjFaninNum(pNode) != 1 ) return 0; if ( Abc_NtkHasSop(pNtk) ) @@ -937,13 +952,38 @@ bool Abc_NodeIsInv( Abc_Obj_t * pNode ) if ( Abc_NtkHasBdd(pNtk) ) return Cudd_IsComplement(pNode->pData); if ( Abc_NtkHasAig(pNtk) ) - return 0; + return Aig_IsComplement(pNode->pData); if ( Abc_NtkHasMapping(pNtk) ) - return pNode->pData == Mio_LibraryReadInv(Abc_FrameReadLibSuper()); + return pNode->pData == Mio_LibraryReadInv(Abc_FrameReadLibGen()); assert( 0 ); return 0; } +/**Function************************************************************* + + Synopsis [Complements the local functions of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeComplement( Abc_Obj_t * pNode ) +{ + assert( Abc_NtkIsLogic(pNode->pNtk) || Abc_NtkIsNetlist(pNode->pNtk) ); + assert( Abc_ObjIsNode(pNode) ); + if ( Abc_NtkHasSop(pNode->pNtk) ) + Abc_SopComplement( pNode->pData ); + else if ( Abc_NtkHasBdd(pNode->pNtk) ) + pNode->pData = Cudd_Not( pNode->pData ); + else if ( Abc_NtkHasAig(pNode->pNtk) ) + pNode->pData = Aig_Not( pNode->pData ); + else + assert( 0 ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index f756ef89..33025292 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -47,7 +47,7 @@ void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pObj; int i; - if ( pNtk->nTravIds == (1<<9)-1 ) + if ( pNtk->nTravIds == (1<<8)-1 ) { pNtk->nTravIds = 0; Abc_NtkForEachObj( pNtk, pObj, i ) @@ -183,9 +183,9 @@ int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk ) assert( Abc_NtkIsBddLogic(pNtk) ); Abc_NtkForEachNode( pNtk, pNode, i ) { + assert( pNode->pData ); if ( Abc_NodeIsConst(pNode) ) continue; - assert( pNode->pData ); nNodes += pNode->pData? Cudd_DagSize( pNode->pData ) : 0; } return nNodes; @@ -202,6 +202,32 @@ int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ +int Abc_NtkGetAigNodeNum( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode; + int i, nNodes = 0; + assert( Abc_NtkIsAigLogic(pNtk) ); + Abc_NtkForEachNode( pNtk, pNode, i ) + { + assert( pNode->pData ); + if ( Abc_NodeIsConst(pNode) ) + continue; + nNodes += pNode->pData? Aig_DagSize( pNode->pData ) : 0; + } + return nNodes; +} + +/**Function************************************************************* + + Synopsis [Reads the number of BDD nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_NtkGetClauseNum( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pNode; @@ -321,7 +347,7 @@ int Abc_NtkGetChoiceNum( Abc_Ntk_t * pNtk ) return 0; Counter = 0; Abc_NtkForEachNode( pNtk, pNode, i ) - Counter += Abc_NodeIsAigChoice( pNode ); + Counter += Abc_AigNodeIsChoice( pNode ); return Counter; } @@ -525,13 +551,8 @@ int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, bool fDuplicate ) if ( Abc_ObjFaninC0(pNode) ) { // change polarity of the duplicated driver - if ( Abc_NtkHasSop(pNtk) ) - Abc_SopComplement( pDriverNew->pData ); - else if ( Abc_NtkHasBdd(pNtk) ) - pDriverNew->pData = Cudd_Not( pDriverNew->pData ); - else - assert( 0 ); - Abc_ObjXorFaninC(pNode, 0); + Abc_NodeComplement( pDriverNew ); + Abc_ObjXorFaninC( pNode, 0 ); } } else @@ -605,7 +626,7 @@ bool Abc_NodeIsExorType( Abc_Obj_t * pNode ) // check that the node is regular assert( !Abc_ObjIsComplement(pNode) ); // if the node is not AND, this is not EXOR - if ( !Abc_NodeIsAigAnd(pNode) ) + if ( !Abc_AigNodeIsAnd(pNode) ) return 0; // if the children are not complemented, this is not EXOR if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) ) @@ -638,7 +659,7 @@ bool Abc_NodeIsMuxType( Abc_Obj_t * pNode ) // check that the node is regular assert( !Abc_ObjIsComplement(pNode) ); // if the node is not AND, this is not MUX - if ( !Abc_NodeIsAigAnd(pNode) ) + if ( !Abc_AigNodeIsAnd(pNode) ) return 0; // if the children are not complemented, this is not MUX if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) ) @@ -1049,7 +1070,7 @@ void Abc_NtkReassignIds( Abc_Ntk_t * pNtk ) // start the array of objects with new IDs vObjsNew = Vec_PtrAlloc( pNtk->nObjs ); // put constant node first - pConst1 = Abc_NtkConst1(pNtk); + pConst1 = Abc_AigConst1(pNtk); assert( pConst1->Id == 0 ); Vec_PtrPush( vObjsNew, pConst1 ); // put PI nodes next diff --git a/src/base/abc/module.make b/src/base/abc/module.make index 649e71a2..113b1f08 100644 --- a/src/base/abc/module.make +++ b/src/base/abc/module.make @@ -4,6 +4,7 @@ SRC += src/base/abc/abcAig.c \ src/base/abc/abcFanio.c \ src/base/abc/abcFunc.c \ src/base/abc/abcLatch.c \ + src/base/abc/abcLib.c \ src/base/abc/abcMinBase.c \ src/base/abc/abcNames.c \ src/base/abc/abcNetlist.c \ diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index c1327f43..8cf0e0af 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -45,6 +45,7 @@ static int Abc_CommandPrintAuto ( Abc_Frame_t * pAbc, int argc, char ** arg static int Abc_CommandPrintKMap ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPrintGates ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPrintSharing ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPrintSkews ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandShowBdd ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandShowCut ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -73,6 +74,7 @@ static int Abc_CommandOrPos ( Abc_Frame_t * pAbc, int argc, char ** arg static int Abc_CommandFrames ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandSop ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBdd ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAig ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandReorder ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandOrder ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandMuxes ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -95,6 +97,7 @@ static int Abc_CommandIRewrite ( Abc_Frame_t * pAbc, int argc, char ** arg static int Abc_CommandIRewriteSeq ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIResyn ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandHaig ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandMini ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandFraigTrust ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -131,6 +134,9 @@ static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** arg static int Abc_CommandTraceStart ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTraceCheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandHoward ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandSkewForward ( Abc_Frame_t * pAbc, int argc, char ** argv ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -164,6 +170,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Printing", "print_kmap", Abc_CommandPrintKMap, 0 ); Cmd_CommandAdd( pAbc, "Printing", "print_gates", Abc_CommandPrintGates, 0 ); Cmd_CommandAdd( pAbc, "Printing", "print_sharing", Abc_CommandPrintSharing, 0 ); + Cmd_CommandAdd( pAbc, "Printing", "print_skews", Abc_CommandPrintSkews, 0 ); Cmd_CommandAdd( pAbc, "Printing", "show_bdd", Abc_CommandShowBdd, 0 ); Cmd_CommandAdd( pAbc, "Printing", "show_cut", Abc_CommandShowCut, 0 ); @@ -192,6 +199,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Various", "frames", Abc_CommandFrames, 1 ); Cmd_CommandAdd( pAbc, "Various", "sop", Abc_CommandSop, 0 ); Cmd_CommandAdd( pAbc, "Various", "bdd", Abc_CommandBdd, 0 ); + Cmd_CommandAdd( pAbc, "Various", "aig", Abc_CommandAig, 0 ); Cmd_CommandAdd( pAbc, "Various", "reorder", Abc_CommandReorder, 0 ); Cmd_CommandAdd( pAbc, "Various", "order", Abc_CommandOrder, 0 ); Cmd_CommandAdd( pAbc, "Various", "muxes", Abc_CommandMuxes, 1 ); @@ -214,6 +222,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "New AIG", "irws", Abc_CommandIRewriteSeq, 1 ); Cmd_CommandAdd( pAbc, "New AIG", "iresyn", Abc_CommandIResyn, 1 ); Cmd_CommandAdd( pAbc, "New AIG", "haig", Abc_CommandHaig, 1 ); + Cmd_CommandAdd( pAbc, "New AIG", "mini", Abc_CommandMini, 1 ); Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 ); Cmd_CommandAdd( pAbc, "Fraiging", "fraig_trust", Abc_CommandFraigTrust, 1 ); @@ -247,8 +256,11 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "sat", Abc_CommandSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 ); - Cmd_CommandAdd( pAbc, "Verification", "trace_start", Abc_CommandTraceStart, 0 ); - Cmd_CommandAdd( pAbc, "Verification", "trace_check", Abc_CommandTraceCheck, 0 ); +// Cmd_CommandAdd( pAbc, "Verification", "trace_start", Abc_CommandTraceStart, 0 ); +// Cmd_CommandAdd( pAbc, "Verification", "trace_check", Abc_CommandTraceCheck, 0 ); + + Cmd_CommandAdd( pAbc, "Sequential", "howard", Abc_CommandHoward, 0 ); + Cmd_CommandAdd( pAbc, "Sequential", "skew_fwd", Abc_CommandSkewForward, 0 ); // Rwt_Man4ExploreStart(); // Map_Var3Print(); @@ -1297,6 +1309,74 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandPrintSkews( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + int fPrintAll; + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fPrintAll = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "ah" ) ) != EOF ) + { + switch ( c ) + { + case 'a': + fPrintAll = 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if ( !Abc_NtkIsSeq(pNtk) && Abc_NtkLatchNum(pNtk) == 0 ) + { + fprintf( pErr, "The network has no latches.\n" ); + return 0; + } + + if ( pNtk->vSkews == NULL || pNtk->vSkews->nSize == 0 ) + { + fprintf( pErr, "The network has no clock skew schedule.\n" ); + return 0; + } + + Abc_NtkPrintSkews( pOut, pNtk, fPrintAll ); + return 0; + +usage: + fprintf( pErr, "usage: print_skews [-h] [-a]\n" ); + fprintf( pErr, "\t prints information about a clock skew schedule\n" ); + fprintf( pErr, "\t-a : dumps the skew of every latch [default = no]\n"); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandShowBdd( Abc_Frame_t * pAbc, int argc, char ** argv ) { FILE * pOut, * pErr; @@ -3309,29 +3389,26 @@ int Abc_CommandSop( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( pNtk == NULL ) { fprintf( pErr, "Empty network.\n" ); return 1; } - - // get the new network - if ( !Abc_NtkIsBddLogic(pNtk) ) + if ( !Abc_NtkIsLogic(pNtk) ) { - fprintf( pErr, "Converting to SOP is possible when node functions are BDDs.\n" ); + fprintf( pErr, "Converting to SOP is possible only for logic networks.\n" ); return 1; } - if ( !Abc_NtkBddToSop( pNtk, fDirect ) ) + if ( !Abc_NtkLogicToSop(pNtk, fDirect) ) { - fprintf( pErr, "Converting to SOP has failed.\n" ); + fprintf( pErr, "Converting to BDD has failed.\n" ); return 1; } return 0; usage: fprintf( pErr, "usage: sop [-dh]\n" ); - fprintf( pErr, "\t converts node functions from BDD to SOP\n" ); + fprintf( pErr, "\t converts node functions to SOP\n" ); fprintf( pErr, "\t-d : toggles using both phases or only positive [default = %s]\n", fDirect? "direct": "both" ); fprintf( pErr, "\t-h : print the command usage\n"); return 1; @@ -3370,19 +3447,22 @@ int Abc_CommandBdd( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( pNtk == NULL ) { fprintf( pErr, "Empty network.\n" ); return 1; } - - if ( !Abc_NtkIsSopLogic(pNtk) ) + if ( !Abc_NtkIsLogic(pNtk) ) { - fprintf( pErr, "Converting to BDD is possible when node functions are SOPs.\n" ); + fprintf( pErr, "Converting to BDD is possible only for logic networks.\n" ); return 1; } - if ( !Abc_NtkSopToBdd( pNtk ) ) + if ( Abc_NtkIsBddLogic(pNtk) ) + { + fprintf( pOut, "The logic network is already in the BDD form.\n" ); + return 0; + } + if ( !Abc_NtkLogicToBdd(pNtk) ) { fprintf( pErr, "Converting to BDD has failed.\n" ); return 1; @@ -3391,7 +3471,69 @@ int Abc_CommandBdd( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: fprintf( pErr, "usage: bdd [-h]\n" ); - fprintf( pErr, "\t converts node functions from SOP to BDD\n" ); + fprintf( pErr, "\t converts node functions to BDD\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAig( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + { + switch ( c ) + { + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if ( !Abc_NtkIsLogic(pNtk) ) + { + fprintf( pErr, "Converting to AIG is possible only for logic networks.\n" ); + return 1; + } + if ( Abc_NtkIsAigLogic(pNtk) ) + { + fprintf( pOut, "The logic network is already in the AIG form.\n" ); + return 0; + } + if ( !Abc_NtkLogicToAig(pNtk) ) + { + fprintf( pErr, "Converting to AIG has failed.\n" ); + return 1; + } + return 0; + +usage: + fprintf( pErr, "usage: aig [-h]\n" ); + fprintf( pErr, "\t converts node functions to AIG\n" ); fprintf( pErr, "\t-h : print the command usage\n"); return 1; } @@ -3759,7 +3901,7 @@ int Abc_CommandOneOutput( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( argc == globalUtilOptind + 1 ) { - pNodeCo = Abc_NtkFindCo( pNtk, argv[globalUtilOptind] ); + pNodeCo = Abc_NtkFindTerm( pNtk, argv[globalUtilOptind] ); pNode = Abc_NtkFindNode( pNtk, argv[globalUtilOptind] ); if ( pNode == NULL ) { @@ -5271,6 +5413,73 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandMini( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk, * pNtkRes; + int c; + extern Abc_Ntk_t * Abc_NtkMiniBalance( Abc_Ntk_t * pNtk ); + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + { + switch ( c ) + { + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + if ( Abc_NtkIsSeq(pNtk) ) + { + fprintf( pErr, "Only works for non-sequential networks.\n" ); + return 1; + } + if ( !Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "Only works for combinatinally strashed AIG networks.\n" ); + return 1; + } + + pNtkRes = Abc_NtkMiniBalance( pNtk ); + if ( pNtkRes == NULL ) + { + fprintf( pErr, "Command has failed.\n" ); + return 0; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + fprintf( pErr, "usage: mini [-h]\n" ); + fprintf( pErr, "\t perform balancing using new package\n" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* @@ -5913,7 +6122,6 @@ int Abc_CommandUnmap( Abc_Frame_t * pAbc, int argc, char ** argv ) FILE * pOut, * pErr; Abc_Ntk_t * pNtk; int c; - extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk ); pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); @@ -5944,7 +6152,7 @@ int Abc_CommandUnmap( Abc_Frame_t * pAbc, int argc, char ** argv ) } // get the new network - if ( !Abc_NtkUnmap( pNtk ) ) + if ( !Abc_NtkMapToSop( pNtk ) ) { fprintf( pErr, "Unmapping has failed.\n" ); return 1; @@ -5974,7 +6182,6 @@ int Abc_CommandAttach( Abc_Frame_t * pAbc, int argc, char ** argv ) FILE * pOut, * pErr; Abc_Ntk_t * pNtk; int c; - extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk ); pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); @@ -7982,13 +8189,14 @@ int Abc_CommandTraceStart( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "This command is applicable to AIGs.\n" ); return 1; } - +/* Abc_HManStart(); if ( !Abc_HManPopulate( pNtk ) ) { fprintf( pErr, "Failed to start the tracing database.\n" ); return 1; } +*/ return 0; usage: @@ -8042,7 +8250,7 @@ int Abc_CommandTraceCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "This command is applicable to AIGs.\n" ); return 1; } - +/* if ( !Abc_HManIsRunning(pNtk) ) { fprintf( pErr, "The tracing database is not available.\n" ); @@ -8052,6 +8260,7 @@ int Abc_CommandTraceCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( !Abc_HManVerify( 1, pNtk->Id ) ) fprintf( pErr, "Verification failed.\n" ); Abc_HManStop(); +*/ return 0; usage: @@ -8060,6 +8269,168 @@ usage: fprintf( pErr, "\t-h : print the command usage\n"); return 1; } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandHoward( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + int fVerbose; + double result; + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if ( !Abc_NtkIsSeq(pNtk) && Abc_NtkLatchNum(pNtk) == 0 ) + { + fprintf( pErr, "The network has no latches. Analysis is not performed.\n" ); + return 0; + } + + if ( Abc_NtkHasAig(pNtk) ) + { + // quit if there are choice nodes + if ( Abc_NtkGetChoiceNum(pNtk) ) + { + fprintf( pErr, "Currently cannot analyze networks with choice nodes.\n" ); + return 0; + } + + /* + if ( Abc_NtkIsStrash(pNtk) ) + pNtkRes = Abc_NtkAigToSeq(pNtk); + else + pNtkRes = Abc_NtkDup(pNtk); + + */ + + fprintf( pErr, "Currently cannot analyze unmapped networks.\n" ); + return 0; + } + + result = Seq_NtkHoward( pNtk, fVerbose ); + + if (result < 0) { + fprintf( pErr, "Analysis failed.\n" ); + return 0; + } + + printf("Maximum mean cycle time = %.2f\n", result); + + return 1; + +usage: + fprintf( pErr, "usage: howard [-h]\n" ); + fprintf( pErr, "\t computes the maximum mean cycle time using Howard's algorithm\n" ); + fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandSkewForward( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + int fMinimize; + float target; + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + target = pNtk->maxMeanCycle; + fMinimize = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "mh" ) ) != EOF ) + { + switch ( c ) + { + case 'm': + fMinimize ^= 1; + break; + default: + goto usage; + } + } + + + if ( pNtk == NULL ) + { + fprintf( pErr, "Empty network.\n" ); + return 1; + } + + if ( !Abc_NtkIsSeq(pNtk) && Abc_NtkLatchNum(pNtk) == 0 ) + { + fprintf( pErr, "The network has no latches.\n" ); + return 0; + } + + if ( pNtk->vSkews == NULL || pNtk->vSkews->nSize == 0 ) + { + fprintf( pErr, "The network has no clock skew schedule.\n" ); + return 0; + } + + Seq_NtkSkewForward( pNtk, target, fMinimize ); + + return 1; + +usage: + fprintf( pErr, "usage: skew_fwd [-h] [-m] [-t float]\n" ); + fprintf( pErr, "\t converts a skew schedule into a set of forward skews 0<skew<T\n" ); + fprintf( pErr, "\t-m : minimizes sum of skews [default = %s]\n", fMinimize? "yes": "no" ); + fprintf( pErr, "\t-t : clock period, T [default = maxMeanCycle] (unimplemented)\n"); + fprintf( pErr, "\t-h : print the command usage\n"); + return 1; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abcBalance.c b/src/base/abci/abcBalance.c index 389a7977..819974bf 100644 --- a/src/base/abci/abcBalance.c +++ b/src/base/abci/abcBalance.c @@ -233,7 +233,7 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_ vSuper = Abc_NodeBalanceCone( pNodeOld, vStorage, Level, fDuplicate, fSelective ); if ( vSuper->nSize == 0 ) { // it means that the supergate contains two nodes in the opposite polarity - pNodeOld->pCopy = Abc_ObjNot(Abc_NtkConst1(pNtkNew)); + pNodeOld->pCopy = Abc_ObjNot(Abc_AigConst1(pNtkNew)); return pNodeOld->pCopy; } // for each old node, derive the new well-balanced node @@ -263,9 +263,8 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_ assert( pNodeOld->pCopy == NULL ); // mark the old node with the new node pNodeOld->pCopy = vSuper->pArray[0]; - Abc_HManAddProto( pNodeOld->pCopy, pNodeOld ); vSuper->nSize = 0; -// if ( Abc_ObjRegular(pNodeOld->pCopy) == Abc_NtkConst1(pNtkNew) ) +// if ( Abc_ObjRegular(pNodeOld->pCopy) == Abc_AigConst1(pNtkNew) ) // printf( "Constant node\n" ); // assert( pNodeOld->Level >= Abc_ObjRegular(pNodeOld->pCopy)->Level ); return pNodeOld->pCopy; diff --git a/src/base/abci/abcCut.c b/src/base/abci/abcCut.c index c7c164b9..7024a970 100644 --- a/src/base/abci/abcCut.c +++ b/src/base/abci/abcCut.c @@ -95,8 +95,8 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) continue; } // skip constant node, it has no cuts - if ( Abc_NodeIsConst(pObj) ) - continue; +// if ( Abc_NodeIsConst(pObj) ) +// continue; Extra_ProgressBarUpdate( pProgress, i, NULL ); // compute the cuts to the internal node Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree ); @@ -107,7 +107,7 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId1(pObj) ); } // add cuts due to choices - if ( Abc_NodeIsAigChoice(pObj) ) + if ( Abc_AigNodeIsChoice(pObj) ) { Vec_IntClear( vChoices ); for ( pNode = pObj; pNode; pNode = pNode->pData ) @@ -171,8 +171,8 @@ void Abc_NtkCutsOracle( Abc_Ntk_t * pNtk, Cut_Oracle_t * p ) continue; } // skip constant node, it has no cuts - if ( Abc_NodeIsConst(pObj) ) - continue; +// if ( Abc_NodeIsConst(pObj) ) +// continue; // compute the cuts to the internal node Cut_OracleComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj), Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); @@ -218,7 +218,7 @@ Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) p = Cut_ManStart( pParams ); // set cuts for the constant node and the PIs - pObj = Abc_NtkConst1(pNtk); + pObj = Abc_AigConst1(pNtk); if ( Abc_ObjFanoutNum(pObj) > 0 ) Cut_NodeSetTriv( p, pObj->Id ); Abc_NtkForEachPi( pNtk, pObj, i ) @@ -247,7 +247,7 @@ Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) { Abc_NodeGetCutsSeq( p, pObj, nIters==0 ); // add cuts due to choices - if ( Abc_NodeIsAigChoice(pObj) ) + if ( Abc_AigNodeIsChoice(pObj) ) { Vec_IntClear( vChoices ); for ( pNode = pObj; pNode; pNode = pNode->pData ) diff --git a/src/base/abci/abcDsd.c b/src/base/abci/abcDsd.c index 79d2b729..cd8f9047 100644 --- a/src/base/abci/abcDsd.c +++ b/src/base/abci/abcDsd.c @@ -172,7 +172,7 @@ void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t * int i, nNodesDsd; // save the CI nodes in the DSD nodes - Dsd_NodeSetMark( Dsd_ManagerReadConst1(pManDsd), (int)Abc_NtkConst1(pNtk)->pCopy ); + Dsd_NodeSetMark( Dsd_ManagerReadConst1(pManDsd), (int)Abc_AigConst1(pNtkNew) ); Abc_NtkForEachCi( pNtk, pNode, i ) { pNodeDsd = Dsd_ManagerReadInput( pManDsd, i ); @@ -191,7 +191,7 @@ void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t * pDriver = Abc_ObjFanin0( pNode ); if ( !Abc_ObjIsNode(pDriver) ) continue; - if ( !Abc_NodeIsAigAnd(pDriver) ) + if ( !Abc_AigNodeIsAnd(pDriver) ) continue; pNodeDsd = Dsd_ManagerReadRoot( pManDsd, i ); pNodeNew = (Abc_Obj_t *)Dsd_NodeReadMark( Dsd_Regular(pNodeDsd) ); @@ -419,14 +419,14 @@ void Abc_NodeDecompDsdAndMux( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Dsd_Manager pNodeC = Abc_ObjFanin( pNode, iVar ); // get the negative cofactor - pNode1 = Abc_NodeClone( pNode ); + pNode1 = Abc_NtkCloneObj( pNode ); pNode1->pData = Cudd_Cofactor( dd, pNode->pData, Cudd_Not(dd->vars[iVar]) ); Cudd_Ref( pNode1->pData ); Abc_NodeMinimumBase( pNode1 ); if ( Abc_NodeIsForDsd(pNode1) ) Vec_PtrPush( vNodes, pNode1 ); // get the positive cofactor - pNode2 = Abc_NodeClone( pNode ); + pNode2 = Abc_NtkCloneObj( pNode ); pNode2->pData = Cudd_Cofactor( dd, pNode->pData, dd->vars[iVar] ); Cudd_Ref( pNode2->pData ); Abc_NodeMinimumBase( pNode2 ); if ( Abc_NodeIsForDsd(pNode2) ) diff --git a/src/base/abci/abcEspresso.c b/src/base/abci/abcEspresso.c index ad43534d..8f9c7277 100644 --- a/src/base/abci/abcEspresso.c +++ b/src/base/abci/abcEspresso.c @@ -52,12 +52,12 @@ void Abc_NtkEspresso( Abc_Ntk_t * pNtk, int fVerbose ) assert( Abc_NtkIsLogic(pNtk) ); // convert the network to have SOPs if ( Abc_NtkHasMapping(pNtk) ) - Abc_NtkUnmap(pNtk); + Abc_NtkMapToSop(pNtk); else if ( Abc_NtkHasBdd(pNtk) ) { if ( !Abc_NtkBddToSop(pNtk, 0) ) { - printf( "Converting to SOPs has failed.\n" ); + printf( "Abc_NtkEspresso(): Converting to SOPs has failed.\n" ); return; } } diff --git a/src/base/abci/abcFpga.c b/src/base/abci/abcFpga.c index a59ef2af..e5286487 100644 --- a/src/base/abci/abcFpga.c +++ b/src/base/abci/abcFpga.c @@ -143,6 +143,7 @@ Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, // create PIs and remember them in the old nodes Abc_NtkCleanCopy( pNtk ); + Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Fpga_ManReadConst1(pMan); Abc_NtkForEachCi( pNtk, pNode, i ) { pNodeFpga = Fpga_ManReadInputs(pMan)[i]; @@ -157,12 +158,6 @@ Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, Vec_PtrForEachEntry( vNodes, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); - // consider the case of a constant - if ( Abc_NodeIsConst(pNode) ) - { - Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Fpga_ManReadConst1(pMan); - continue; - } // add the node to the mapper pNodeFpga = Fpga_NodeAnd( pMan, Fpga_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ), @@ -173,7 +168,7 @@ Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, if ( pSwitching ) Fpga_NodeSetSwitching( pNodeFpga, pSwitching[pNode->Id] ); // set up the choice node - if ( Abc_NodeIsAigChoice( pNode ) ) + if ( Abc_AigNodeIsChoice( pNode ) ) for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData ) { Fpga_NodeSetNextE( (Fpga_Node_t *)pPrev->pCopy, (Fpga_Node_t *)pFanin->pCopy ); @@ -214,7 +209,7 @@ Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk ) Abc_NtkForEachCi( pNtk, pNode, i ) Fpga_NodeSetData0( Fpga_ManReadInputs(pMan)[i], (char *)pNode->pCopy ); // set the constant node - Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NtkConst1(pNtkNew) ); + Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NodeCreateConst1(pNtkNew) ); // process the nodes in topological order pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); Abc_NtkForEachCo( pNtk, pNode, i ) diff --git a/src/base/abci/abcFraig.c b/src/base/abci/abcFraig.c index 46f2cdf0..778c8284 100644 --- a/src/base/abci/abcFraig.c +++ b/src/base/abci/abcFraig.c @@ -113,7 +113,7 @@ void * Abc_NtkToFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes, int fExd // map the constant node Abc_NtkCleanCopy( pNtk ); - Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan); + Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan); // create PIs and remember them in the old nodes Abc_NtkForEachCi( pNtk, pNode, i ) pNode->pCopy = (Abc_Obj_t *)Fraig_ManReadIthVar(pMan, i); @@ -168,7 +168,7 @@ Fraig_Node_t * Abc_NtkToFraigExdc( Fraig_Man_t * pMan, Abc_Ntk_t * pNtkMain, Abc // strash the EXDC network pNtkStrash = Abc_NtkStrash( pNtkExdc, 0, 0 ); Abc_NtkCleanCopy( pNtkStrash ); - Abc_NtkConst1(pNtkStrash)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan); + Abc_AigConst1(pNtkStrash)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan); // set the mapping of the PI nodes ppNames = Abc_NtkCollectCioNames( pNtkMain, 0 ); Abc_NtkForEachCi( pNtkStrash, pObj, i ) @@ -285,7 +285,7 @@ Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk ) Abc_NtkForEachCi( pNtk, pNode, i ) Fraig_NodeSetData1( Fraig_ManReadIthVar(pMan, i), (Fraig_Node_t *)pNode->pCopy ); // set the constant node - Fraig_NodeSetData1( Fraig_ManReadConst1(pMan), (Fraig_Node_t *)Abc_NtkConst1(pNtkNew) ); + Fraig_NodeSetData1( Fraig_ManReadConst1(pMan), (Fraig_Node_t *)Abc_AigConst1(pNtkNew) ); // process the nodes in topological order pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); Abc_NtkForEachCo( pNtk, pNode, i ) @@ -384,7 +384,7 @@ Abc_Ntk_t * Abc_NtkFromFraig2( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk ) // map the nodes into their lowest level representives tTable = stmm_init_table(stmm_ptrcmp,stmm_ptrhash); - pNode = Abc_NtkConst1(pNtk); + pNode = Abc_AigConst1(pNtk); if ( !stmm_find_or_add( tTable, (char *)Fraig_Regular(pNode->pCopy), (char ***)&ppSlot ) ) *ppSlot = pNode; Abc_NtkForEachCi( pNtk, pNode, i ) @@ -607,7 +607,7 @@ Abc_Obj_t * Abc_NodeFraigTrust( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode ) assert( nFanins == Abc_SopGetVarNum(pNode->pData) ); // check if it is a constant if ( nFanins == 0 ) - return Abc_ObjNotCond( Abc_NtkConst1(pNtkNew), Abc_SopIsConst0(pNode->pData) ); + return Abc_ObjNotCond( Abc_AigConst1(pNtkNew), Abc_SopIsConst0(pNode->pData) ); if ( nFanins == 1 ) return Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_SopIsInv(pNode->pData) ); if ( nFanins == 2 && Abc_SopIsAndType(pNode->pData) ) diff --git a/src/base/abci/abcFxu.c b/src/base/abci/abcFxu.c index a8e656ce..b6d57a5c 100644 --- a/src/base/abci/abcFxu.c +++ b/src/base/abci/abcFxu.c @@ -53,22 +53,19 @@ static void Abc_NtkFxuReconstruct( Abc_Ntk_t * pNtk, Fxu_Data_t * p ); bool Abc_NtkFastExtract( Abc_Ntk_t * pNtk, Fxu_Data_t * p ) { assert( Abc_NtkIsLogic(pNtk) ); - // convert nodes to SOPs - if ( Abc_NtkIsMappedLogic(pNtk) ) - Abc_NtkUnmap(pNtk); - else if ( Abc_NtkIsBddLogic(pNtk) ) - { - if ( !Abc_NtkBddToSop(pNtk, 0) ) - { - printf( "Converting to SOPs has failed.\n" ); - return 0; - } - } - else + // if the network is already in the SOP form, it may come from BLIF file + // and it may not be SCC-free, in which case FXU will not work correctly + if ( Abc_NtkIsSopLogic(pNtk) ) { // to make sure the SOPs are SCC-free // Abc_NtkSopToBdd(pNtk); // Abc_NtkBddToSop(pNtk); } + // get the network in the SOP form + if ( !Abc_NtkLogicToSop(pNtk, 0) ) + { + printf( "Abc_NtkFastExtract(): Converting to SOPs has failed.\n" ); + return 0; + } // check if the network meets the requirements if ( !Abc_NtkFxuCheck(pNtk) ) { diff --git a/src/base/abci/abcIvy.c b/src/base/abci/abcIvy.c index 42d5173a..6538b360 100644 --- a/src/base/abci/abcIvy.c +++ b/src/base/abci/abcIvy.c @@ -77,7 +77,7 @@ Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq, int fUseDc ) { if ( !Abc_NtkBddToSop(pNtk, 0) ) { - printf( "Converting to SOPs has failed.\n" ); + printf( "Abc_NtkIvyBefore(): Converting to SOPs has failed.\n" ); return NULL; } } @@ -329,7 +329,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk ) if ( !Abc_NtkBddToSop(pNtk, 0) ) { FREE( pInit ); - printf( "Converting to SOPs has failed.\n" ); + printf( "Abc_NtkIvy(): Converting to SOPs has failed.\n" ); return NULL; } } @@ -437,7 +437,7 @@ Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan ) // perform strashing pNtk = Abc_NtkStartFrom( pNtkOld, ABC_NTK_STRASH, ABC_FUNC_AIG ); // transfer the pointers to the basic nodes - Ivy_ManConst1(pMan)->TravId = Abc_EdgeFromNode( Abc_NtkConst1(pNtk) ); + Ivy_ManConst1(pMan)->TravId = Abc_EdgeFromNode( Abc_AigConst1(pNtk) ); Abc_NtkForEachCi( pNtkOld, pObj, i ) Ivy_ManPi(pMan, i)->TravId = Abc_EdgeFromNode( pObj->pCopy ); // rebuild the AIG @@ -494,7 +494,7 @@ Abc_Ntk_t * Abc_NtkFromAigSeq( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan, int fHaig // perform strashing pNtk = Abc_NtkStartFromNoLatches( pNtkOld, ABC_NTK_STRASH, ABC_FUNC_AIG ); // transfer the pointers to the basic nodes - Ivy_ManConst1(pMan)->TravId = Abc_EdgeFromNode( Abc_NtkConst1(pNtk) ); + Ivy_ManConst1(pMan)->TravId = Abc_EdgeFromNode( Abc_AigConst1(pNtk) ); Abc_NtkForEachPi( pNtkOld, pObj, i ) Ivy_ManPi(pMan, i)->TravId = Abc_EdgeFromNode( pObj->pCopy ); // create latches of the new network @@ -583,10 +583,11 @@ Ivy_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtkOld ) Ivy_Obj_t * pFanin; int i; // create the manager - assert( Abc_NtkHasSop(pNtkOld) || Abc_NtkHasAig(pNtkOld) ); + assert( Abc_NtkHasSop(pNtkOld) || Abc_NtkIsStrash(pNtkOld) ); pMan = Ivy_ManStart(); // create the PIs - Abc_NtkConst1(pNtkOld)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan); + if ( Abc_NtkIsStrash(pNtkOld) ) + Abc_AigConst1(pNtkOld)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan); Abc_NtkForEachCi( pNtkOld, pObj, i ) pObj->pCopy = (Abc_Obj_t *)Ivy_ObjCreatePi(pMan); // perform the conversion of the internal nodes @@ -646,14 +647,13 @@ Ivy_Obj_t * Abc_NodeStrashAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode ) int fUseFactor = 1; char * pSop; Ivy_Obj_t * pFanin0, * pFanin1; - extern int Abc_SopIsExorType( char * pSop ); assert( Abc_ObjIsNode(pNode) ); // consider the case when the graph is an AIG if ( Abc_NtkIsStrash(pNode->pNtk) ) { - if ( Abc_NodeIsConst(pNode) ) + if ( Abc_AigNodeIsConst(pNode) ) return Ivy_ManConst1(pMan); pFanin0 = (Ivy_Obj_t *)Abc_ObjFanin0(pNode)->pCopy; pFanin0 = Ivy_NotCond( pFanin0, Abc_ObjFaninC0(pNode) ); diff --git a/src/base/abci/abcMap.c b/src/base/abci/abcMap.c index c579eb84..276e41d0 100644 --- a/src/base/abci/abcMap.c +++ b/src/base/abci/abcMap.c @@ -159,6 +159,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f // create PIs and remember them in the old nodes Abc_NtkCleanCopy( pNtk ); + Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan); Abc_NtkForEachCi( pNtk, pNode, i ) { pNodeMap = Map_ManReadInputs(pMan)[i]; @@ -173,12 +174,6 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f Vec_PtrForEachEntry( vNodes, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); - // consider the case of a constant - if ( Abc_NodeIsConst(pNode) ) - { - Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan); - continue; - } // add the node to the mapper pNodeMap = Map_NodeAnd( pMan, Map_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ), @@ -189,7 +184,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f if ( pSwitching ) Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] ); // set up the choice node - if ( Abc_NodeIsAigChoice( pNode ) ) + if ( Abc_AigNodeIsChoice( pNode ) ) for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData ) { Map_NodeSetNextE( (Map_Node_t *)pPrev->pCopy, (Map_Node_t *)pFanin->pCopy ); @@ -223,16 +218,12 @@ Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk ) Map_Node_t * pNodeMap; Abc_Obj_t * pNode, * pNodeNew; int i, nDupGates; - // create the new network pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_MAP ); // make the mapper point to the new network Map_ManCleanData( pMan ); Abc_NtkForEachCi( pNtk, pNode, i ) Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy ); - // set the constant node - Map_NodeSetData( Map_ManReadConst1(pMan), 1, (char *)Abc_NtkConst1(pNtkNew) ); - // assign the mapping of the required phase to the POs pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); Abc_NtkForEachCo( pNtk, pNode, i ) @@ -266,6 +257,10 @@ Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int { Abc_Obj_t * pNodeNew, * pNodeInv; + // check the case of constant node + if ( Map_NodeIsConst(pNodeMap) ) + return fPhase? Abc_NodeCreateConst1(pNtkNew) : Abc_NodeCreateConst0(pNtkNew); + // check if the phase is already implemented pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase ); if ( pNodeNew ) @@ -393,38 +388,6 @@ Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap } -/**Function************************************************************* - - Synopsis [Unmaps the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkUnmap( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pNode; - char * pSop; - int i; - - assert( Abc_NtkIsMappedLogic(pNtk) ); - // update the functionality manager - assert( pNtk->pManFunc == Abc_FrameReadLibGen() ); - pNtk->pManFunc = Extra_MmFlexStart(); - pNtk->ntkFunc = ABC_FUNC_SOP; - // update the nodes - Abc_NtkForEachNode( pNtk, pNode, i ) - { - pSop = Mio_GateReadSop(pNode->pData); - assert( Abc_SopGetVarNum(pSop) == Abc_ObjFaninNum(pNode) ); - pNode->pData = Abc_SopRegister( pNtk->pManFunc, pSop ); - } - return 1; -} - @@ -524,7 +487,7 @@ Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk ) pNtkNew = Abc_NtkRenode( pNtkNew2, 0, 20, 0, 0, 1, 0 ); if ( !Abc_NtkBddToSop( pNtkNew, 0 ) ) { - printf( "Converting to SOPs has failed.\n" ); + printf( "Abc_NtkFromMapSuperChoice(): Converting to SOPs has failed.\n" ); return NULL; } @@ -545,8 +508,8 @@ Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk ) } Abc_NtkForEachNode( pNtk, pNode, i ) { - if ( Abc_NodeIsConst(pNode) ) - continue; +// if ( Abc_NodeIsConst(pNode) ) +// continue; Map_NodeSetData( (Map_Node_t *)pNode->pNext, 0, (char *)Abc_NodeCreateInv(pNtkNew,pNode->pCopy) ); Map_NodeSetData( (Map_Node_t *)pNode->pNext, 1, (char *)pNode->pCopy ); } @@ -556,8 +519,8 @@ Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk ) Abc_NtkForEachNode( pNtk, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); - if ( Abc_NodeIsConst(pNode) ) - continue; +// if ( Abc_NodeIsConst(pNode) ) +// continue; Abc_NodeSuperChoice( pNtkNew, pNode ); } Extra_ProgressBarStop( pProgress ); diff --git a/src/base/abci/abcMini.c b/src/base/abci/abcMini.c new file mode 100644 index 00000000..037f058a --- /dev/null +++ b/src/base/abci/abcMini.c @@ -0,0 +1,152 @@ +/**CFile**************************************************************** + + FileName [abcMini.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Interface to the minimalistic AIG package.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcMini.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Aig_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtk ); +static Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Gives the current ABC network to AIG manager for processing.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkMiniBalance( Abc_Ntk_t * pNtk ) +{ + Abc_Ntk_t * pNtkAig; + Aig_Man_t * pMan, * pTemp; + assert( Abc_NtkIsStrash(pNtk) ); + // convert to the AIG manager + pMan = Abc_NtkToAig( pNtk ); + if ( pMan == NULL ) + return NULL; + if ( !Aig_ManCheck( pMan ) ) + { + printf( "AIG check has failed.\n" ); + Aig_ManStop( pMan ); + return NULL; + } + // perform balance + Aig_ManPrintStats( pMan ); + pMan = Aig_ManBalance( pTemp = pMan, 1 ); + Aig_ManStop( pTemp ); + Aig_ManPrintStats( pMan ); + // convert from the AIG manager + pNtkAig = Abc_NtkFromAig( pNtk, pMan ); + if ( pNtkAig == NULL ) + return NULL; + Aig_ManStop( pMan ); + // make sure everything is okay + if ( !Abc_NtkCheck( pNtkAig ) ) + { + printf( "Abc_NtkStrash: The network check has failed.\n" ); + Abc_NtkDelete( pNtkAig ); + return NULL; + } + return pNtkAig; +} + +/**Function************************************************************* + + Synopsis [Converts the network from the AIG manager into ABC.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtk ) +{ + Aig_Man_t * pMan; + Abc_Obj_t * pObj; + int i; + // create the manager + pMan = Aig_ManStart(); + // transfer the pointers to the basic nodes + Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Aig_ManConst1(pMan); + Abc_NtkForEachCi( pNtk, pObj, i ) + pObj->pCopy = (Abc_Obj_t *)Aig_ObjCreatePi(pMan); + // perform the conversion of the internal nodes (assumes DFS ordering) + Abc_NtkForEachNode( pNtk, pObj, i ) + pObj->pCopy = (Abc_Obj_t *)Aig_And( pMan, (Aig_Obj_t *)Abc_ObjChild0Copy(pObj), (Aig_Obj_t *)Abc_ObjChild1Copy(pObj) ); + // create the POs + Abc_NtkForEachCo( pNtk, pObj, i ) + Aig_ObjCreatePo( pMan, (Aig_Obj_t *)Abc_ObjChild0Copy(pObj) ); + Aig_ManCleanup( pMan ); + return pMan; +} + +/**Function************************************************************* + + Synopsis [Converts the network from the AIG manager into ABC.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtk, Aig_Man_t * pMan ) +{ + Vec_Ptr_t * vNodes; + Abc_Ntk_t * pNtkNew; + Aig_Obj_t * pObj; + int i; + // perform strashing + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG ); + // transfer the pointers to the basic nodes + Aig_ManConst1(pMan)->pData = Abc_AigConst1(pNtkNew); + Aig_ManForEachPi( pMan, pObj, i ) + pObj->pData = Abc_NtkCi(pNtkNew, i); + // rebuild the AIG + vNodes = Aig_ManDfs( pMan ); + Vec_PtrForEachEntry( vNodes, pObj, i ) + pObj->pData = Abc_AigAnd( pNtkNew->pManFunc, (Abc_Obj_t *)Aig_ObjChild0Copy(pObj), (Abc_Obj_t *)Aig_ObjChild1Copy(pObj) ); + Vec_PtrFree( vNodes ); + // connect the PO nodes + Aig_ManForEachPo( pMan, pObj, i ) + Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) ); + if ( !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Abc_NtkFromAig(): Network check has failed.\n" ); + return pNtkNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcMiter.c b/src/base/abci/abcMiter.c index ea1beb8c..dfd49f6e 100644 --- a/src/base/abci/abcMiter.c +++ b/src/base/abci/abcMiter.c @@ -125,8 +125,8 @@ void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtk // clean the copy field in all objects // Abc_NtkCleanCopy( pNtk1 ); // Abc_NtkCleanCopy( pNtk2 ); - Abc_NtkConst1(pNtk1)->pCopy = Abc_NtkConst1(pNtkMiter); - Abc_NtkConst1(pNtk2)->pCopy = Abc_NtkConst1(pNtkMiter); + Abc_AigConst1(pNtk1)->pCopy = Abc_AigConst1(pNtkMiter); + Abc_AigConst1(pNtk2)->pCopy = Abc_AigConst1(pNtkMiter); if ( fComb ) { @@ -216,11 +216,11 @@ void Abc_NtkMiterAddCone( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * p Abc_Obj_t * pNode; int i; // map the constant nodes - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkMiter); + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkMiter); // perform strashing vNodes = Abc_NtkDfsNodes( pNtk, &pRoot, 1 ); Vec_PtrForEachEntry( vNodes, pNode, i ) - if ( Abc_NodeIsAigAnd(pNode) ) + if ( Abc_AigNodeIsAnd(pNode) ) pNode->pCopy = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); Vec_PtrFree( vNodes ); } @@ -372,12 +372,12 @@ Abc_Ntk_t * Abc_NtkMiterCofactor( Abc_Ntk_t * pNtk, Vec_Int_t * vPiValues ) continue; if ( Value == 0 ) { - Abc_NtkCi(pNtk, i)->pCopy = Abc_ObjNot( Abc_NtkConst1(pNtkMiter) ); + Abc_NtkCi(pNtk, i)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter) ); continue; } if ( Value == 1 ) { - Abc_NtkCi(pNtk, i)->pCopy = Abc_NtkConst1(pNtkMiter); + Abc_NtkCi(pNtk, i)->pCopy = Abc_AigConst1(pNtkMiter); continue; } assert( 0 ); @@ -433,9 +433,9 @@ Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In // perform strashing Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1 ); // set the first cofactor - Abc_NtkCi(pNtk, In1)->pCopy = Abc_ObjNot( Abc_NtkConst1(pNtkMiter) ); + Abc_NtkCi(pNtk, In1)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter) ); if ( In2 >= 0 ) - Abc_NtkCi(pNtk, In2)->pCopy = Abc_NtkConst1( pNtkMiter ); + Abc_NtkCi(pNtk, In2)->pCopy = Abc_AigConst1(pNtkMiter); // add the first cofactor Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot ); @@ -443,9 +443,9 @@ Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In pOutput1 = Abc_ObjFanin0(pRoot)->pCopy; // set the second cofactor - Abc_NtkCi(pNtk, In1)->pCopy = Abc_NtkConst1( pNtkMiter ); + Abc_NtkCi(pNtk, In1)->pCopy = Abc_AigConst1(pNtkMiter); if ( In2 >= 0 ) - Abc_NtkCi(pNtk, In2)->pCopy = Abc_ObjNot( Abc_NtkConst1(pNtkMiter) ); + Abc_NtkCi(pNtk, In2)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter) ); // add the second cofactor Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot ); @@ -497,7 +497,7 @@ Abc_Ntk_t * Abc_NtkMiterQuantify( Abc_Ntk_t * pNtk, int In, int fExist ) // perform strashing Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1 ); // set the first cofactor - Abc_NtkCi(pNtk, In)->pCopy = Abc_ObjNot( Abc_NtkConst1(pNtkMiter) ); + Abc_NtkCi(pNtk, In)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter) ); // add the first cofactor Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot ); // save the output @@ -505,7 +505,7 @@ Abc_Ntk_t * Abc_NtkMiterQuantify( Abc_Ntk_t * pNtk, int In, int fExist ) pOutput1 = Abc_ObjNotCond( Abc_ObjFanin0(pRoot)->pCopy, Abc_ObjFaninC0(pRoot) ); // set the second cofactor - Abc_NtkCi(pNtk, In)->pCopy = Abc_NtkConst1( pNtkMiter ); + Abc_NtkCi(pNtk, In)->pCopy = Abc_AigConst1(pNtkMiter); // add the second cofactor Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot ); // save the output @@ -581,9 +581,9 @@ int Abc_NtkMiterIsConstant( Abc_Ntk_t * pMiter ) Abc_NtkForEachPo( pMiter, pNodePo, i ) { pChild = Abc_ObjChild0( pNodePo ); - if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) ) + if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_AigNodeIsConst(pChild) ) { - assert( Abc_ObjRegular(pChild) == Abc_NtkConst1(pMiter) ); + assert( Abc_ObjRegular(pChild) == Abc_AigConst1(pMiter) ); if ( !Abc_ObjIsComplement(pChild) ) { // if the miter is constant 1, return immediately @@ -617,7 +617,7 @@ void Abc_NtkMiterReport( Abc_Ntk_t * pMiter ) if ( Abc_NtkPoNum(pMiter) == 1 ) { pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,0) ); - if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) ) + if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_AigNodeIsConst(pChild) ) { if ( Abc_ObjIsComplement(pChild) ) printf( "Unsatisfiable.\n" ); @@ -633,7 +633,7 @@ void Abc_NtkMiterReport( Abc_Ntk_t * pMiter ) { pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,i) ); printf( "Output #%2d : ", i ); - if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) ) + if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_AigNodeIsConst(pChild) ) { if ( Abc_ObjIsComplement(pChild) ) printf( "Unsatisfiable.\n" ); @@ -690,7 +690,7 @@ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial ) Counter++; } else - pLatch->pCopy = Abc_ObjNotCond( Abc_NtkConst1(pNtkFrames), Abc_LatchIsInit0(pLatch) ); + pLatch->pCopy = Abc_ObjNotCond( Abc_AigConst1(pNtkFrames), Abc_LatchIsInit0(pLatch) ); } if ( Counter ) printf( "Warning: %d uninitialized latches are replaced by free PI variables.\n", Counter ); @@ -756,7 +756,7 @@ void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame ) // create the prefix to be added to the node names sprintf( Buffer, "_%02d", iFrame ); // map the constant nodes - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkFrames); + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkFrames); // add the new PI nodes Abc_NtkForEachPi( pNtk, pNode, i ) Abc_NtkLogicStoreNamePlus( Abc_NtkDupObj(pNtkFrames, pNode), Abc_ObjName(pNode), Buffer ); @@ -829,7 +829,7 @@ Abc_Ntk_t * Abc_NtkFrames2( Abc_Ntk_t * pNtk, int nFrames, int fInitial, AddFram Counter++; } else { - pLatch->pCopy = Abc_ObjNotCond( Abc_NtkConst1(pNtkFrames), Abc_LatchIsInit0(pLatch) ); + pLatch->pCopy = Abc_ObjNotCond( Abc_AigConst1(pNtkFrames), Abc_LatchIsInit0(pLatch) ); } if (addFrameMapping) addFrameMapping(pLatch->pCopy, pLatch, 0, arg); @@ -899,8 +899,8 @@ void Abc_NtkAddFrame2( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame, Vec Abc_Obj_t * pConst1, * pConst1New; int i; // get the constant nodes - pConst1 = Abc_NtkConst1( pNtk ); - pConst1New = Abc_NtkConst1( pNtkFrames ); + pConst1 = Abc_AigConst1(pNtk); + pConst1New = Abc_AigConst1(pNtkFrames); // create the prefix to be added to the node names sprintf( Buffer, "_%02d", iFrame ); // add the new PI nodes @@ -1037,7 +1037,7 @@ int Abc_NtkOrPos( Abc_Ntk_t * pNtk ) assert( Abc_NtkIsStrash(pNtk) ); assert( Abc_NtkLatchNum(pNtk) == 0 ); // OR the POs - pMiter = Abc_ObjNot( Abc_NtkConst1(pNtk) ); + pMiter = Abc_ObjNot( Abc_AigConst1(pNtk) ); Abc_NtkForEachPo( pNtk, pNode, i ) pMiter = Abc_AigOr( pNtk->pManFunc, pMiter, Abc_ObjChild0(pNode) ); // remove the POs and their names diff --git a/src/base/abci/abcNewAig.c b/src/base/abci/abcNewAig.c deleted file mode 100644 index 62ae51ed..00000000 --- a/src/base/abci/abcNewAig.c +++ /dev/null @@ -1,391 +0,0 @@ -/**CFile**************************************************************** - - FileName [aigNewAig.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Strashing of the current network.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: aigNewAig.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "extra.h" -#include "dec.h" -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan ); -static Aig_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtkOld ); - -static void Abc_NtkStrashPerformAig( Abc_Ntk_t * pNtk, Aig_Man_t * pMan ); -static Aig_Node_t * Abc_NodeStrashAig( Aig_Man_t * pMan, Abc_Obj_t * pNode ); -static Aig_Node_t * Abc_NodeStrashAigSopAig( Aig_Man_t * pMan, Abc_Obj_t * pNode, char * pSop ); -static Aig_Node_t * Abc_NodeStrashAigExorAig( Aig_Man_t * pMan, Abc_Obj_t * pNode, char * pSop ); -static Aig_Node_t * Abc_NodeStrashAigFactorAig( Aig_Man_t * pMan, Abc_Obj_t * pNode, char * pSop ); -extern char * Mio_GateReadSop( void * pGate ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Gives the current ABC network to AIG manager for processing.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkNewAig( Abc_Ntk_t * pNtk ) -{ - Aig_Man_t * pMan; - Abc_Ntk_t * pNtkAig; -// Aig_ProofType_t RetValue; - int fCleanup = 1; - int nNodes; - extern void Aig_MffcTest( Aig_Man_t * pMan ); - - - assert( !Abc_NtkIsNetlist(pNtk) ); - assert( !Abc_NtkIsSeq(pNtk) ); - if ( Abc_NtkIsBddLogic(pNtk) ) - { - if ( !Abc_NtkBddToSop(pNtk, 0) ) - { - printf( "Converting to SOPs has failed.\n" ); - return; - } - } - // print warning about choice nodes - if ( Abc_NtkGetChoiceNum( pNtk ) ) - printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" ); - - // convert to the AIG manager - pMan = Abc_NtkToAig( pNtk ); - - Aig_MffcTest( pMan ); - -/* - // execute a command in the AIG manager - RetValue = Aig_FraigProve( pMan ); - if ( RetValue == AIG_PROOF_SAT ) - printf( "Satisfiable.\n" ); - else if ( RetValue == AIG_PROOF_UNSAT ) - printf( "Unsatisfiable.\n" ); - else if ( RetValue == AIG_PROOF_TIMEOUT ) - printf( "Undecided.\n" ); - else - assert( 0 ); -*/ - - // convert from the AIG manager - pNtkAig = Abc_NtkFromAig( pNtk, pMan ); - Aig_ManStop( pMan ); - - // report the cleanup results - if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) ) - printf( "Warning: AIG cleanup removed %d nodes (this is not a bug).\n", nNodes ); - // duplicate EXDC - if ( pNtk->pExdc ) - pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc ); - // make sure everything is okay - if ( !Abc_NtkCheck( pNtkAig ) ) - { - printf( "Abc_NtkStrash: The network check has failed.\n" ); - Abc_NtkDelete( pNtkAig ); - return NULL; - } - return pNtkAig; -} - -/**Function************************************************************* - - Synopsis [Converts the network from the AIG manager into ABC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan ) -{ - Abc_Ntk_t * pNtk; - Abc_Obj_t * pObj, * pObjNew, * pFaninNew, * pFaninNew0, * pFaninNew1; - Aig_Node_t * pAnd; - int i; - // perform strashing - pNtk = Abc_NtkStartFrom( pNtkOld, ABC_NTK_STRASH, ABC_FUNC_AIG ); - // transfer the pointers to the basic nodes - Aig_ManConst1(pMan)->Data = Abc_NtkConst1(pNtk)->Id; - Abc_NtkForEachCi( pNtkOld, pObj, i ) - Aig_ManPi(pMan, i)->Data = pObj->pCopy->Id; - // rebuild the AIG - Aig_ManForEachAnd( pMan, pAnd, i ) - { - // add the first fanins - pFaninNew0 = Abc_NtkObj( pNtk, Aig_NodeFanin0(pAnd)->Data ); - pFaninNew0 = Abc_ObjNotCond( pFaninNew0, Aig_NodeFaninC0(pAnd) ); - // add the first second - pFaninNew1 = Abc_NtkObj( pNtk, Aig_NodeFanin1(pAnd)->Data ); - pFaninNew1 = Abc_ObjNotCond( pFaninNew1, Aig_NodeFaninC1(pAnd) ); - // create the new node - pObjNew = Abc_AigAnd( pNtk->pManFunc, pFaninNew0, pFaninNew1 ); - pAnd->Data = pObjNew->Id; - } - // connect the PO nodes - Abc_NtkForEachCo( pNtkOld, pObj, i ) - { - pAnd = Aig_ManPo( pMan, i ); - pFaninNew = Abc_NtkObj( pNtk, Aig_NodeFanin0(pAnd)->Data ); - pFaninNew = Abc_ObjNotCond( pFaninNew, Aig_NodeFaninC0(pAnd) ); - Abc_ObjAddFanin( pObj->pCopy, pFaninNew ); - } - return pNtk; -} - -/**Function************************************************************* - - Synopsis [Converts the network from the AIG manager into ABC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtkOld ) -{ - Aig_Param_t Params; - Aig_Man_t * pMan; - Abc_Obj_t * pObj; - Aig_Node_t * pFanin; - int i; - // create the manager - Aig_ManSetDefaultParams( &Params ); - pMan = Aig_ManStart( &Params ); - // create the PIs - Abc_NtkConst1(pNtkOld)->pCopy = (Abc_Obj_t *)Aig_ManConst1(pMan); - Abc_NtkForEachCi( pNtkOld, pObj, i ) - pObj->pCopy = (Abc_Obj_t *)Aig_NodeCreatePi(pMan); - Abc_NtkForEachCo( pNtkOld, pObj, i ) - pObj->pCopy = (Abc_Obj_t *)Aig_NodeCreatePo(pMan); - // perform the conversion of the internal nodes - Abc_NtkStrashPerformAig( pNtkOld, pMan ); - // create the POs - Abc_NtkForEachCo( pNtkOld, pObj, i ) - { - pFanin = (Aig_Node_t *)Abc_ObjFanin0(pObj)->pCopy; - pFanin = Aig_NotCond( pFanin, Abc_ObjFaninC0(pObj) ); - Aig_NodeConnectPo( pMan, (Aig_Node_t *)pObj->pCopy, pFanin ); - } - return pMan; -} - -/**Function************************************************************* - - Synopsis [Prepares the network for strashing.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkStrashPerformAig( Abc_Ntk_t * pNtk, Aig_Man_t * pMan ) -{ -// ProgressBar * pProgress; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode; - int i; - vNodes = Abc_NtkDfs( pNtk, 0 ); -// pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); - Vec_PtrForEachEntry( vNodes, pNode, i ) - { -// Extra_ProgressBarUpdate( pProgress, i, NULL ); - pNode->pCopy = (Abc_Obj_t *)Abc_NodeStrashAig( pMan, pNode ); - } -// Extra_ProgressBarStop( pProgress ); - Vec_PtrFree( vNodes ); -} - -/**Function************************************************************* - - Synopsis [Strashes one logic node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Abc_NodeStrashAig( Aig_Man_t * pMan, Abc_Obj_t * pNode ) -{ - int fUseFactor = 1; - char * pSop; - Aig_Node_t * pFanin0, * pFanin1; - extern int Abc_SopIsExorType( char * pSop ); - - assert( Abc_ObjIsNode(pNode) ); - - // consider the case when the graph is an AIG - if ( Abc_NtkIsStrash(pNode->pNtk) ) - { - if ( Abc_NodeIsConst(pNode) ) - return Aig_ManConst1(pMan); - pFanin0 = (Aig_Node_t *)Abc_ObjFanin0(pNode)->pCopy; - pFanin0 = Aig_NotCond( pFanin0, Abc_ObjFaninC0(pNode) ); - pFanin1 = (Aig_Node_t *)Abc_ObjFanin1(pNode)->pCopy; - pFanin1 = Aig_NotCond( pFanin1, Abc_ObjFaninC1(pNode) ); - return Aig_And( pMan, pFanin0, pFanin1 ); - } - - // get the SOP of the node - if ( Abc_NtkHasMapping(pNode->pNtk) ) - pSop = Mio_GateReadSop(pNode->pData); - else - pSop = pNode->pData; - - // consider the constant node - if ( Abc_NodeIsConst(pNode) ) - return Aig_NotCond( Aig_ManConst1(pMan), Abc_SopIsConst0(pSop) ); - - // consider the special case of EXOR function - if ( Abc_SopIsExorType(pSop) ) - return Abc_NodeStrashAigExorAig( pMan, pNode, pSop ); - - // decide when to use factoring - if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 ) - return Abc_NodeStrashAigFactorAig( pMan, pNode, pSop ); - return Abc_NodeStrashAigSopAig( pMan, pNode, pSop ); -} - -/**Function************************************************************* - - Synopsis [Strashes one logic node using its SOP.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Abc_NodeStrashAigSopAig( Aig_Man_t * pMan, Abc_Obj_t * pNode, char * pSop ) -{ - Abc_Obj_t * pFanin; - Aig_Node_t * pAnd, * pSum; - char * pCube; - int i, nFanins; - - // get the number of node's fanins - nFanins = Abc_ObjFaninNum( pNode ); - assert( nFanins == Abc_SopGetVarNum(pSop) ); - // go through the cubes of the node's SOP - pSum = Aig_Not( Aig_ManConst1(pMan) ); - Abc_SopForEachCube( pSop, nFanins, pCube ) - { - // create the AND of literals - pAnd = Aig_ManConst1(pMan); - Abc_ObjForEachFanin( pNode, pFanin, i ) // pFanin can be a net - { - if ( pCube[i] == '1' ) - pAnd = Aig_And( pMan, pAnd, (Aig_Node_t *)pFanin->pCopy ); - else if ( pCube[i] == '0' ) - pAnd = Aig_And( pMan, pAnd, Aig_Not((Aig_Node_t *)pFanin->pCopy) ); - } - // add to the sum of cubes - pSum = Aig_Or( pMan, pSum, pAnd ); - } - // decide whether to complement the result - if ( Abc_SopIsComplement(pSop) ) - pSum = Aig_Not(pSum); - return pSum; -} - -/**Function************************************************************* - - Synopsis [Strashed n-input XOR function.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Abc_NodeStrashAigExorAig( Aig_Man_t * pMan, Abc_Obj_t * pNode, char * pSop ) -{ - Abc_Obj_t * pFanin; - Aig_Node_t * pSum; - int i, nFanins; - // get the number of node's fanins - nFanins = Abc_ObjFaninNum( pNode ); - assert( nFanins == Abc_SopGetVarNum(pSop) ); - // go through the cubes of the node's SOP - pSum = Aig_Not( Aig_ManConst1(pMan) ); - for ( i = 0; i < nFanins; i++ ) - { - pFanin = Abc_ObjFanin( pNode, i ); - pSum = Aig_Xor( pMan, pSum, (Aig_Node_t *)pFanin->pCopy ); - } - if ( Abc_SopIsComplement(pSop) ) - pSum = Aig_Not(pSum); - return pSum; -} - -/**Function************************************************************* - - Synopsis [Strashes one logic node using its SOP.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Abc_NodeStrashAigFactorAig( Aig_Man_t * pMan, Abc_Obj_t * pRoot, char * pSop ) -{ - Dec_Graph_t * pFForm; - Dec_Node_t * pNode; - Aig_Node_t * pAnd; - int i; - extern Aig_Node_t * Dec_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph ); - - // perform factoring - pFForm = Dec_Factor( pSop ); - // collect the fanins - Dec_GraphForEachLeaf( pFForm, pNode, i ) - pNode->pFunc = Abc_ObjFanin(pRoot,i)->pCopy; - // perform strashing - pAnd = Dec_GraphToNetworkAig( pMan, pFForm ); - Dec_GraphFree( pFForm ); - return pAnd; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abci/abcNtbdd.c b/src/base/abci/abcNtbdd.c index 0976b652..99ed5636 100644 --- a/src/base/abci/abcNtbdd.c +++ b/src/base/abci/abcNtbdd.c @@ -189,7 +189,7 @@ Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew ) // create the table mapping BDD nodes into the ABC nodes tBdd2Node = st_init_table( st_ptrcmp, st_ptrhash ); // add the constant and the elementary vars - st_insert( tBdd2Node, (char *)b1, (char *)Abc_NtkConst1(pNtkNew) ); + st_insert( tBdd2Node, (char *)b1, (char *)Abc_AigConst1(pNtkNew) ); Abc_ObjForEachFanin( pNodeOld, pFaninOld, i ) st_insert( tBdd2Node, (char *)Cudd_bddIthVar(dd, i), (char *)pFaninOld->pCopy ); // create the new nodes recursively @@ -271,7 +271,7 @@ DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fLatchOnly Cudd_Ref( dd->vars[i] ); } // assign the constant node BDD - pNode = Abc_NtkConst1( pNtk ); + pNode = Abc_AigConst1(pNtk); if ( Abc_ObjFanoutNum(pNode) > 0 ) { pNode->pCopy = (Abc_Obj_t *)dd->one; diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c index cb32def5..cb1d2a38 100644 --- a/src/base/abci/abcPrint.c +++ b/src/base/abci/abcPrint.c @@ -68,7 +68,7 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored ) fprintf( pFile, " net = %5d", Abc_NtkNetNum(pNtk) ); fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) ); } - else if ( Abc_NtkHasAig(pNtk) ) + else if ( Abc_NtkIsStrash(pNtk) || Abc_NtkIsSeq(pNtk) ) { fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) ); if ( Num = Abc_NtkGetChoiceNum(pNtk) ) @@ -83,7 +83,10 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored ) else fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) ); - if ( Abc_NtkHasSop(pNtk) ) + if ( Abc_NtkIsStrash(pNtk) || Abc_NtkIsSeq(pNtk) ) + { + } + else if ( Abc_NtkHasSop(pNtk) ) { fprintf( pFile, " cube = %5d", Abc_NtkGetCubeNum(pNtk) ); @@ -91,6 +94,8 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored ) if ( fFactored ) fprintf( pFile, " lit(fac) = %5d", Abc_NtkGetLitFactNum(pNtk) ); } + else if ( Abc_NtkHasAig(pNtk) ) + fprintf( pFile, " aig = %5d", Abc_NtkGetAigNodeNum(pNtk) ); else if ( Abc_NtkHasBdd(pNtk) ) fprintf( pFile, " bdd = %5d", Abc_NtkGetBddNodeNum(pNtk) ); else if ( Abc_NtkHasMapping(pNtk) ) @@ -98,7 +103,7 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored ) fprintf( pFile, " area = %5.2f", Abc_NtkGetMappedArea(pNtk) ); fprintf( pFile, " delay = %5.2f", Abc_NtkDelayTrace(pNtk) ); } - else if ( !Abc_NtkHasAig(pNtk) ) + else if ( !Abc_NtkHasBlackbox(pNtk) ) { assert( 0 ); } @@ -661,12 +666,15 @@ void Abc_NtkPrintGates( Abc_Ntk_t * pNtk, int fUseLibrary ) return; } + if ( Abc_NtkIsAigLogic(pNtk) ) + return; + // transform logic functions from BDD to SOP if ( fHasBdds = Abc_NtkIsBddLogic(pNtk) ) { if ( !Abc_NtkBddToSop(pNtk, 0) ) { - printf( "Converting to SOPs has failed.\n" ); + printf( "Abc_NtkPrintGates(): Converting to SOPs has failed.\n" ); return; } } @@ -785,6 +793,40 @@ void Abc_NtkPrintStrSupports( Abc_Ntk_t * pNtk ) } } +/**Function************************************************************* + + Synopsis [Prints information about the clock skew schedule.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkPrintSkews( FILE * pFile, Abc_Ntk_t * pNtk, int fPrintAll ) { + + Abc_Obj_t * pObj; + int i; + int nNonZero = 0; + float skew, sum = 0.0, avg; + + if (fPrintAll) fprintf( pFile, "Full Clock Skew Schedule:\n\tGlobal Skew = %.2f\n", pNtk->globalSkew ); + + Abc_NtkForEachLatch( pNtk, pObj, i ) { + skew = Abc_NtkGetLatSkew( pNtk, i ); + if ( skew != 0.0 ) { + nNonZero++; + sum += ABS( skew ); + } + if (fPrintAll) fprintf( pFile, "\tLatch %d (Id = %d) \t Endpoint Skew = %.2f\n", i, pObj->Id, skew); + } + + avg = sum / Abc_NtkLatchNum( pNtk ); + + fprintf( pFile, "Endpoint Skews : Total |Skew| = %.2f\t Avg |Skew| = %.2f\t Non-Zero Skews = %d\n", + sum, avg, nNonZero ); +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abcRefactor.c b/src/base/abci/abcRefactor.c index 3dd6c519..3d301cd6 100644 --- a/src/base/abci/abcRefactor.c +++ b/src/base/abci/abcRefactor.c @@ -109,8 +109,8 @@ int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool { Extra_ProgressBarUpdate( pProgress, i, NULL ); // skip the constant node - if ( Abc_NodeIsConst(pNode) ) - continue; +// if ( Abc_NodeIsConst(pNode) ) +// continue; // skip persistant nodes if ( Abc_NodeIsPersistant(pNode) ) continue; diff --git a/src/base/abci/abcRenode.c b/src/base/abci/abcRenode.c index f7d351d2..2e448ce5 100644 --- a/src/base/abci/abcRenode.c +++ b/src/base/abci/abcRenode.c @@ -124,7 +124,7 @@ void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) int i; // set the constant node - pConst1 = Abc_NtkConst1(pNtk); + pConst1 = Abc_AigConst1(pNtk); if ( Abc_ObjFanoutNum(pConst1) > 0 ) { pNodeNew = Abc_NtkCreateNode( pNtkNew ); @@ -173,7 +173,7 @@ Abc_Obj_t * Abc_NtkRenode_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld ) if ( pNodeOld->pCopy ) return pNodeOld->pCopy; assert( Abc_ObjIsNode(pNodeOld) ); - assert( !Abc_NodeIsConst(pNodeOld) ); + assert( !Abc_AigNodeIsConst(pNodeOld) ); assert( pNodeOld->fMarkA ); //printf( "%d ", Abc_NodeMffcSizeSupp(pNodeOld) ); @@ -214,7 +214,7 @@ DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t Abc_Obj_t * pFaninOld; DdNode * bFunc; int i; - assert( !Abc_NodeIsConst(pNodeOld) ); + assert( !Abc_AigNodeIsConst(pNodeOld) ); assert( Abc_ObjIsNode(pNodeOld) ); // set the elementary BDD variables for the input nodes for ( i = 0; i < vFaninsOld->nSize; i++ ) @@ -389,8 +389,8 @@ void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax ) Abc_NtkForEachNode( pNtk, pNode, i ) { // skip PI/PO nodes - if ( Abc_NodeIsConst(pNode) ) - continue; +// if ( Abc_NodeIsConst(pNode) ) +// continue; // mark the nodes with multiple fanouts nFanouts = Abc_ObjFanoutNum(pNode); nConeSize = Abc_NodeMffcSize(pNode); @@ -406,8 +406,8 @@ void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax ) Abc_NtkForEachNode( pNtk, pNode, i ) { // skip PI/PO nodes - if ( Abc_NodeIsConst(pNode) ) - continue; +// if ( Abc_NodeIsConst(pNode) ) +// continue; if ( pNode->fMarkA == 0 ) continue; // continue cutting branches until it meets the fanin limit @@ -420,8 +420,8 @@ void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax ) Abc_NtkForEachNode( pNtk, pNode, i ) { // skip PI/PO nodes - if ( Abc_NodeIsConst(pNode) ) - continue; +// if ( Abc_NodeIsConst(pNode) ) +// continue; if ( pNode->fMarkA == 0 ) continue; Abc_NtkRenodeCone( pNode, vCone ); @@ -455,8 +455,8 @@ void Abc_NtkRenodeSetBoundsCnf( Abc_Ntk_t * pNtk ) Abc_NtkForEachNode( pNtk, pNode, i ) { // skip PI/PO nodes - if ( Abc_NodeIsConst(pNode) ) - continue; +// if ( Abc_NodeIsConst(pNode) ) +// continue; // mark the nodes with multiple fanouts if ( Abc_ObjFanoutNum(pNode) > 1 ) pNode->fMarkA = 1; @@ -487,8 +487,8 @@ void Abc_NtkRenodeSetBoundsCnf( Abc_Ntk_t * pNtk ) Abc_NtkForEachNode( pNtk, pNode, i ) { // skip PI/PO nodes - if ( Abc_NodeIsConst(pNode) ) - continue; +// if ( Abc_NodeIsConst(pNode) ) +// continue; if ( Abc_NodeIsMuxType(pNode) && Abc_ObjFanin0(pNode)->fMarkA == 0 && Abc_ObjFanin1(pNode)->fMarkA == 0 ) @@ -521,8 +521,8 @@ void Abc_NtkRenodeSetBoundsMulti( Abc_Ntk_t * pNtk, int nThresh ) Abc_NtkForEachNode( pNtk, pNode, i ) { // skip PI/PO nodes - if ( Abc_NodeIsConst(pNode) ) - continue; +// if ( Abc_NodeIsConst(pNode) ) +// continue; // mark the nodes with multiple fanouts // if ( Abc_ObjFanoutNum(pNode) > 1 ) // pNode->fMarkA = 1; diff --git a/src/base/abci/abcRestruct.c b/src/base/abci/abcRestruct.c index d738123a..9dc84999 100644 --- a/src/base/abci/abcRestruct.c +++ b/src/base/abci/abcRestruct.c @@ -132,8 +132,8 @@ pManRst->timeCut += clock() - clk; { Extra_ProgressBarUpdate( pProgress, i, NULL ); // skip the constant node - if ( Abc_NodeIsConst(pNode) ) - continue; +// if ( Abc_NodeIsConst(pNode) ) +// continue; // skip persistant nodes if ( Abc_NodeIsPersistant(pNode) ) continue; diff --git a/src/base/abci/abcResub.c b/src/base/abci/abcResub.c index b0061b61..9fcc6979 100644 --- a/src/base/abci/abcResub.c +++ b/src/base/abci/abcResub.c @@ -158,8 +158,8 @@ int Abc_NtkResubstitute( Abc_Ntk_t * pNtk, int nCutMax, int nStepsMax, bool fUpd { Extra_ProgressBarUpdate( pProgress, i, NULL ); // skip the constant node - if ( Abc_NodeIsConst(pNode) ) - continue; +// if ( Abc_NodeIsConst(pNode) ) +// continue; // skip persistant nodes if ( Abc_NodeIsPersistant(pNode) ) continue; diff --git a/src/base/abci/abcRewrite.c b/src/base/abci/abcRewrite.c index 703f05d9..2af10271 100644 --- a/src/base/abci/abcRewrite.c +++ b/src/base/abci/abcRewrite.c @@ -86,8 +86,8 @@ Rwr_ManAddTimeCuts( pManRwr, clock() - clk ); if ( i >= nNodes ) break; // skip the constant node - if ( Abc_NodeIsConst(pNode) ) - continue; +// if ( Abc_NodeIsConst(pNode) ) +// continue; // skip persistant nodes if ( Abc_NodeIsPersistant(pNode) ) continue; diff --git a/src/base/abci/abcRr.c b/src/base/abci/abcRr.c index b3788d31..61bc8b09 100644 --- a/src/base/abci/abcRr.c +++ b/src/base/abci/abcRr.c @@ -120,8 +120,8 @@ int Abc_NtkRR( Abc_Ntk_t * pNtk, int nFaninLevels, int nFanoutLevels, int fUseFa if ( i >= nNodes ) break; // skip the constant node - if ( Abc_NodeIsConst(pNode) ) - continue; +// if ( Abc_NodeIsConst(pNode) ) +// continue; // skip persistant nodes if ( Abc_NodeIsPersistant(pNode) ) continue; @@ -680,8 +680,7 @@ Abc_Ntk_t * Abc_NtkWindow( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vC // duplicate the name and the spec pNtkNew->pName = Extra_UtilStrsav( "temp" ); // map the constant nodes - if ( Abc_NtkConst1(pNtk) ) - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew); + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); // create and map the PIs Vec_PtrForEachEntry( vLeaves, pObj, i ) pObj->pCopy = Abc_NtkCreatePi(pNtkNew); @@ -728,7 +727,7 @@ void Abc_NtkRRSimulateStart( Abc_Ntk_t * pNtk ) Abc_Obj_t * pObj; unsigned uData, uData0, uData1; int i; - Abc_NtkConst1(pNtk)->pData = (void *)~((unsigned)0); + Abc_AigConst1(pNtk)->pData = (void *)~((unsigned)0); Abc_NtkForEachCi( pNtk, pObj, i ) pObj->pData = (void *)SIM_RANDOM_UNSIGNED; Abc_NtkForEachNode( pNtk, pObj, i ) @@ -801,7 +800,7 @@ Vec_Str_t * Abc_NtkRRSimulate( Abc_Ntk_t * pNtk ) } // simulate patters and store them in copy - Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)~((unsigned)0); + Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)~((unsigned)0); Abc_NtkForEachCi( pNtk, pObj, i ) pObj->pCopy = (Abc_Obj_t *)SIM_RANDOM_UNSIGNED; Abc_NtkForEachNode( pNtk, pObj, i ) diff --git a/src/base/abci/abcSat.c b/src/base/abci/abcSat.c index b8491d06..86f13884 100644 --- a/src/base/abci/abcSat.c +++ b/src/base/abci/abcSat.c @@ -452,7 +452,7 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront ) // vCircuit = Vec_VecStart( 184 ); // add the clause for the constant node - pNode = Abc_NtkConst1(pNtk); + pNode = Abc_AigConst1(pNtk); pNode->fMarkA = 1; pNode->pCopy = (Abc_Obj_t *)vNodes->nSize; Vec_PtrPush( vNodes, pNode ); @@ -488,7 +488,7 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront ) Vec_PtrForEachEntry( vNodes, pNode, i ) { assert( !Abc_ObjIsComplement(pNode) ); - if ( !Abc_NodeIsAigAnd(pNode) ) + if ( !Abc_AigNodeIsAnd(pNode) ) continue; //printf( "%d ", pNode->Id ); diff --git a/src/base/abci/abcStrash.c b/src/base/abci/abcStrash.c index b546d8be..c69aeabf 100644 --- a/src/base/abci/abcStrash.c +++ b/src/base/abci/abcStrash.c @@ -26,13 +26,7 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -// static functions -static void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fAllNodes ); -static Abc_Obj_t * Abc_NodeStrashSop( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, char * pSop ); -static Abc_Obj_t * Abc_NodeStrashExor( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, char * pSop ); -static Abc_Obj_t * Abc_NodeStrashFactor( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, char * pSop ); - -extern char * Mio_GateReadSop( void * pGate ); +static void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -40,10 +34,57 @@ extern char * Mio_GateReadSop( void * pGate ); /**Function************************************************************* - Synopsis [Creates the strashed AIG network.] + Synopsis [Reapplies structural hashing to the AIG.] + + Description [Because of the structural hashing, this procedure should not + change the number of nodes. It is useful to detect the bugs in the original AIG.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkRestrash( Abc_Ntk_t * pNtk, bool fCleanup ) +{ + Abc_Ntk_t * pNtkAig; + Abc_Obj_t * pObj; + int i, nNodes; + assert( Abc_NtkIsStrash(pNtk) ); + // print warning about choice nodes + if ( Abc_NtkGetChoiceNum( pNtk ) ) + printf( "Warning: The choice nodes in the original AIG are removed by strashing.\n" ); + // start the new network (constants and CIs are already mappined after this step + pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG ); + // restrash the nodes (assuming a topological order of the old network) + Abc_NtkForEachNode( pNtk, pObj, i ) + pObj->pCopy = Abc_AigAnd( pNtkAig->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); + // finalize the network + Abc_NtkFinalize( pNtk, pNtkAig ); + // print warning about self-feed latches +// if ( Abc_NtkCountSelfFeedLatches(pNtkAig) ) +// printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) ); + // perform cleanup if requested + if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) ) + printf( "Abc_NtkRestrash(): AIG cleanup removed %d nodes (this is a bug).\n", nNodes ); + // duplicate EXDC + if ( pNtk->pExdc ) + pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc ); + // make sure everything is okay + if ( !Abc_NtkCheck( pNtkAig ) ) + { + printf( "Abc_NtkStrash: The network check has failed.\n" ); + Abc_NtkDelete( pNtkAig ); + return NULL; + } + return pNtkAig; + +} + +/**Function************************************************************* + + Synopsis [Transforms logic network into structurally hashed AIG.] - Description [Converts the logic network or the AIG into a - structurally hashed AIG.] + Description [] SideEffects [] @@ -54,33 +95,28 @@ Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup ) { Abc_Ntk_t * pNtkAig; int nNodes; - - assert( !Abc_NtkIsNetlist(pNtk) ); - assert( !Abc_NtkIsSeq(pNtk) ); - if ( Abc_NtkIsBddLogic(pNtk) ) + assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) ); + // consider the special case when the network is already structurally hashed + if ( Abc_NtkIsStrash(pNtk) ) + return Abc_NtkRestrash( pNtk, fCleanup ); + // convert the node representation in the logic network to the AIG form + if ( !Abc_NtkLogicToAig(pNtk) ) { - if ( !Abc_NtkBddToSop(pNtk, 0) ) - { - printf( "Converting to SOPs has failed.\n" ); - return NULL; - } + printf( "Converting to AIGs has failed.\n" ); + return NULL; } - // print warning about choice nodes - if ( Abc_NtkGetChoiceNum( pNtk ) ) - printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" ); // perform strashing + Abc_NtkCleanCopy( pNtk ); pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG ); - if ( Abc_NtkConst1(pNtk) ) - Abc_NtkConst1(pNtk)->pCopy = NULL; Abc_NtkStrashPerform( pNtk, pNtkAig, fAllNodes ); Abc_NtkFinalize( pNtk, pNtkAig ); // print warning about self-feed latches // if ( Abc_NtkCountSelfFeedLatches(pNtkAig) ) // printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) ); - if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) ) - { + // perform cleanup if requested + nNodes = fCleanup? Abc_AigCleanup(pNtkAig->pManFunc) : 0; +// if ( nNodes ) // printf( "Warning: AIG cleanup removed %d nodes (this is not a bug).\n", nNodes ); - } // duplicate EXDC if ( pNtk->pExdc ) pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc ); @@ -115,13 +151,10 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ) // the first network should be an AIG assert( Abc_NtkIsStrash(pNtk1) ); assert( Abc_NtkIsLogic(pNtk2) || Abc_NtkIsStrash(pNtk2) ); - if ( Abc_NtkIsBddLogic(pNtk2) ) + if ( Abc_NtkIsLogic(pNtk2) && !Abc_NtkLogicToAig(pNtk2) ) { - if ( !Abc_NtkBddToSop(pNtk2, 0) ) - { - printf( "Converting to SOPs has failed.\n" ); - return 0; - } + printf( "Converting to AIGs has failed.\n" ); + return 0; } // check that the networks have the same PIs // reorder PIs of pNtk2 according to pNtk1 @@ -132,7 +165,11 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ) Abc_NtkForEachCi( pNtk2, pObj, i ) pObj->pCopy = Abc_NtkCi(pNtk1, i); // add pNtk2 to pNtk1 while strashing - Abc_NtkStrashPerform( pNtk2, pNtk1, 1 ); + if ( Abc_NtkIsLogic(pNtk2) ) + Abc_NtkStrashPerform( pNtk2, pNtk1, 1 ); + else + Abc_NtkForEachNode( pNtk2, pObj, i ) + pObj->pCopy = Abc_AigAnd( pNtk1->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); // make sure that everything is okay if ( !Abc_NtkCheck( pNtk1 ) ) { @@ -142,7 +179,6 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ) return 1; } - /**Function************************************************************* Synopsis [Prepares the network for strashing.] @@ -154,85 +190,28 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ) SeeAlso [] ***********************************************************************/ -void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes ) +void Abc_NtkStrashPerform( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew, bool fAllNodes ) { ProgressBar * pProgress; Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode, * pNodeNew, * pObj; + Abc_Obj_t * pNodeOld; int i; - - // perform strashing - vNodes = Abc_NtkDfs( pNtk, fAllNodes ); + assert( Abc_NtkIsLogic(pNtkOld) ); + assert( Abc_NtkIsStrash(pNtkNew) ); + vNodes = Abc_NtkDfs( pNtkOld, fAllNodes ); pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); - Vec_PtrForEachEntry( vNodes, pNode, i ) + Vec_PtrForEachEntry( vNodes, pNodeOld, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); - // get the node - assert( Abc_ObjIsNode(pNode) ); - // strash the node - pNodeNew = Abc_NodeStrash( pNtkNew, pNode ); - // get the old object - pObj = Abc_ObjFanout0Ntk( pNode ); - // make sure the node is not yet strashed - assert( pObj->pCopy == NULL ); - // mark the old object with the new AIG node - pObj->pCopy = pNodeNew; - Abc_HManAddProto( pObj->pCopy, pObj ); + pNodeOld->pCopy = Abc_NodeStrash( pNtkNew, pNodeOld ); } - Vec_PtrFree( vNodes ); Extra_ProgressBarStop( pProgress ); + Vec_PtrFree( vNodes ); } /**Function************************************************************* - Synopsis [Strashes one logic node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode ) -{ - int fUseFactor = 1; - char * pSop; - extern int Abc_SopIsExorType( char * pSop ); - - assert( Abc_ObjIsNode(pNode) ); - - // consider the case when the graph is an AIG - if ( Abc_NtkIsStrash(pNode->pNtk) ) - { - if ( Abc_NodeIsConst(pNode) ) - return Abc_NtkConst1(pNtkNew); - return Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); - } - - // get the SOP of the node - if ( Abc_NtkHasMapping(pNode->pNtk) ) - pSop = Mio_GateReadSop(pNode->pData); - else - pSop = pNode->pData; - - // consider the constant node - if ( Abc_NodeIsConst(pNode) ) - return Abc_ObjNotCond( Abc_NtkConst1(pNtkNew), Abc_SopIsConst0(pSop) ); - - // consider the special case of EXOR function - if ( Abc_SopIsExorType(pSop) ) - return Abc_NodeStrashExor( pNtkNew, pNode, pSop ); - - // decide when to use factoring - if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 ) - return Abc_NodeStrashFactor( pNtkNew, pNode, pSop ); - return Abc_NodeStrashSop( pNtkNew, pNode, pSop ); -} - -/**Function************************************************************* - - Synopsis [Strashes one logic node using its SOP.] + Synopsis [Transfers the AIG from one manager into another.] Description [] @@ -241,96 +220,56 @@ Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NodeStrashSop( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, char * pSop ) +void Abc_NodeStrash_rec( Abc_Aig_t * pMan, Aig_Obj_t * pObj ) { - Abc_Aig_t * pMan = pNtkNew->pManFunc; - Abc_Obj_t * pFanin, * pAnd, * pSum; - char * pCube; - int i, nFanins; - - // get the number of node's fanins - nFanins = Abc_ObjFaninNum( pNode ); - assert( nFanins == Abc_SopGetVarNum(pSop) ); - // go through the cubes of the node's SOP - pSum = Abc_ObjNot( Abc_NtkConst1(pNtkNew) ); - Abc_SopForEachCube( pSop, nFanins, pCube ) - { - // create the AND of literals - pAnd = Abc_NtkConst1(pNtkNew); - Abc_ObjForEachFanin( pNode, pFanin, i ) // pFanin can be a net - { - if ( pCube[i] == '1' ) - pAnd = Abc_AigAnd( pMan, pAnd, pFanin->pCopy ); - else if ( pCube[i] == '0' ) - pAnd = Abc_AigAnd( pMan, pAnd, Abc_ObjNot(pFanin->pCopy) ); - } - // add to the sum of cubes - pSum = Abc_AigOr( pMan, pSum, pAnd ); - } - // decide whether to complement the result - if ( Abc_SopIsComplement(pSop) ) - pSum = Abc_ObjNot(pSum); - return pSum; + assert( !Aig_IsComplement(pObj) ); + if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) ) + return; + Abc_NodeStrash_rec( pMan, Aig_ObjFanin0(pObj) ); + Abc_NodeStrash_rec( pMan, Aig_ObjFanin1(pObj) ); + pObj->pData = Abc_AigAnd( pMan, (Abc_Obj_t *)Aig_ObjChild0Copy(pObj), (Abc_Obj_t *)Aig_ObjChild1Copy(pObj) ); + assert( !Aig_ObjIsMarkA(pObj) ); // loop detection + Aig_ObjSetMarkA( pObj ); } /**Function************************************************************* - Synopsis [Strashed n-input XOR function.] + Synopsis [Strashes one logic node.] - Description [] + Description [Assume the network is in the AIG form] SideEffects [] - + SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NodeStrashExor( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, char * pSop ) +Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld ) { - Abc_Aig_t * pMan = pNtkNew->pManFunc; - Abc_Obj_t * pFanin, * pSum; - int i, nFanins; - // get the number of node's fanins - nFanins = Abc_ObjFaninNum( pNode ); - assert( nFanins == Abc_SopGetVarNum(pSop) ); - // go through the cubes of the node's SOP - pSum = Abc_ObjNot( Abc_NtkConst1(pNtkNew) ); - for ( i = 0; i < nFanins; i++ ) - { - pFanin = Abc_ObjFanin( pNode, i ); - pSum = Abc_AigXor( pMan, pSum, pFanin->pCopy ); - } - if ( Abc_SopIsComplement(pSop) ) - pSum = Abc_ObjNot(pSum); - return pSum; + Aig_Man_t * pMan; + Aig_Obj_t * pRoot; + Abc_Obj_t * pFanin; + int i; + assert( Abc_ObjIsNode(pNodeOld) ); + assert( Abc_NtkIsAigLogic(pNodeOld->pNtk) ); + // get the local AIG manager and the local root node + pMan = pNodeOld->pNtk->pManFunc; + pRoot = pNodeOld->pData; + // check the constant case + if ( Abc_NodeIsConst(pNodeOld) ) + return Abc_ObjNotCond( Abc_AigConst1(pNtkNew), Aig_IsComplement(pRoot) ); + // set elementary variables + Abc_ObjForEachFanin( pNodeOld, pFanin, i ) + Aig_IthVar(pMan, i)->pData = pFanin->pCopy; + // strash the AIG of this node + Abc_NodeStrash_rec( pNtkNew->pManFunc, Aig_Regular(pRoot) ); + Aig_ConeUnmark_rec( Aig_Regular(pRoot) ); + // return the final node + return Abc_ObjNotCond( Aig_Regular(pRoot)->pData, Aig_IsComplement(pRoot) ); } -/**Function************************************************************* - - Synopsis [Strashes one logic node using its SOP.] - Description [] - - SideEffects [] - SeeAlso [] -***********************************************************************/ -Abc_Obj_t * Abc_NodeStrashFactor( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pRoot, char * pSop ) -{ - Dec_Graph_t * pFForm; - Dec_Node_t * pNode; - Abc_Obj_t * pAnd; - int i; - // perform factoring - pFForm = Dec_Factor( pSop ); - // collect the fanins - Dec_GraphForEachLeaf( pFForm, pNode, i ) - pNode->pFunc = Abc_ObjFanin(pRoot,i)->pCopy; - // perform strashing - pAnd = Dec_GraphToNetwork( pNtkNew, pFForm ); - Dec_GraphFree( pFForm ); - return pAnd; -} @@ -380,7 +319,7 @@ Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels ) // start the network pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG ); pNtkNew->pName = Extra_UtilStrsav(pNtk->pName); - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew); + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); // create PIs below the cut and nodes above the cut Abc_NtkCleanCopy( pNtk ); pObjNew = Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin0(Abc_NtkPo(pNtk, 0)), LevelCut ); diff --git a/src/base/abci/abcSweep.c b/src/base/abci/abcSweep.c index 3665584e..8f1ab180 100644 --- a/src/base/abci/abcSweep.c +++ b/src/base/abci/abcSweep.c @@ -448,7 +448,7 @@ int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose ) { Vec_Ptr_t * vNodes; int Counter; - assert( !Abc_NtkHasAig(pNtk) ); + assert( Abc_NtkIsLogic(pNtk) ); // mark the nodes reachable from the POs vNodes = Abc_NtkDfs( pNtk, 0 ); Counter = Abc_NtkReduceNodes( pNtk, vNodes ); @@ -473,7 +473,7 @@ int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes ) { Abc_Obj_t * pNode; int i, Counter; - assert( !Abc_NtkIsStrash(pNtk) ); + assert( Abc_NtkIsLogic(pNtk) ); // mark the nodes reachable from the POs for ( i = 0; i < vNodes->nSize; i++ ) { @@ -481,9 +481,6 @@ int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes ) assert( Abc_ObjIsNode(pNode) ); pNode->fMarkA = 1; } - // if it is an AIG, also mark the constant 1 node - if ( Abc_NtkConst1(pNtk) ) - Abc_NtkConst1(pNtk)->fMarkA = 1; // remove the non-marked nodes Counter = 0; Abc_NtkForEachNode( pNtk, pNode, i ) diff --git a/src/base/abci/abcTiming.c b/src/base/abci/abcTiming.c index d2d731d9..5add0dda 100644 --- a/src/base/abci/abcTiming.c +++ b/src/base/abci/abcTiming.c @@ -37,9 +37,9 @@ struct Abc_ManTime_t_ // static functions static Abc_ManTime_t * Abc_ManTimeStart(); static void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive ); -static void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk ); +void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk ); -static void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode ); +void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode ); // accessing the arrival and required times of a node static inline Abc_Time_t * Abc_NodeArrival( Abc_Obj_t * pNode ) { return pNode->pNtk->pManTime->vArrs->pArray[pNode->Id]; } @@ -595,13 +595,12 @@ void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode ) // start the arrival time of the node pTimeOut = Abc_NodeArrival(pNode); - pTimeOut->Rise = pTimeOut->Fall = 0; + pTimeOut->Rise = pTimeOut->Fall = -ABC_INFINITY; // go through the pins of the gate pPin = Mio_GateReadPins(pNode->pData); Abc_ObjForEachFanin( pNode, pFanin, i ) { pTimeIn = Abc_NodeArrival(pFanin); - assert( pTimeIn->Worst != -ABC_INFINITY ); // get the interesting parameters of this pin PinPhase = Mio_PinReadPhase(pPin); tDelayBlockRise = (float)Mio_PinReadDelayBlockRise( pPin ); @@ -647,7 +646,7 @@ void Abc_NtkStartReverseLevels( Abc_Ntk_t * pNtk ) Vec_Ptr_t * vNodes; Abc_Obj_t * pObj, * pFanout; int i, k, nLevelsCur; -// assert( Abc_NtkIsStrash(pNtk) ); + assert( Abc_NtkIsStrash(pNtk) ); // remember the maximum number of direct levels // pNtk->LevelMax = Abc_AigGetLevelNum(pNtk); pNtk->LevelMax = Abc_NtkGetLevelNum(pNtk); diff --git a/src/base/abci/abcTrace.c b/src/base/abci/abcTrace.c deleted file mode 100644 index 4abe235e..00000000 --- a/src/base/abci/abcTrace.c +++ /dev/null @@ -1,804 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcHistory.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcHistory.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#define ABC_SIM_VARS 16 // the max number of variables in the cone -#define ABC_SIM_OBJS 200 // the max number of objects in the cone - -typedef struct Abc_HMan_t_ Abc_HMan_t; -typedef struct Abc_HObj_t_ Abc_HObj_t; -typedef struct Abc_HNum_t_ Abc_HNum_t; - -struct Abc_HNum_t_ -{ - unsigned fCompl : 1; // set to 1 if the node is complemented - unsigned NtkId : 6; // the network ID - unsigned ObjId : 24; // the node ID -}; - -struct Abc_HObj_t_ -{ - // object info - unsigned fProof : 1; // set to 1 if the node is proved - unsigned fPhase : 1; // set to 1 if the node's phase differs from Old - unsigned fPi : 1; // the node is a PI - unsigned fPo : 1; // the node is a PO - unsigned fConst : 1; // the node is a constant - unsigned fVisited: 1; // the flag shows if the node is visited - unsigned NtkId : 10; // the network ID - unsigned Num : 16; // a temporary number - // history record - Abc_HNum_t Fan0; // immediate fanin - Abc_HNum_t Fan1; // immediate fanin - Abc_HNum_t Proto; // old node if present -// Abc_HNum_t Equ; // equiv node if present -}; - -struct Abc_HMan_t_ -{ - // storage for history information - Vec_Vec_t * vNtks; // the history nodes belonging to each network - Vec_Int_t * vProof; // flags showing if the network is proved - // storage for simulation info - int nVarsMax; // the max number of cone leaves - int nObjsMax; // the max number of cone nodes - Vec_Ptr_t * vObjs; // the cone nodes - int nBits; // the number of simulation bits - int nWords; // the number of unsigneds for siminfo - int nWordsCur; // the current number of words - Vec_Ptr_t * vSims; // simulation info - unsigned * pInfo; // pointer to simulation info - // other info - Vec_Ptr_t * vCone0; - Vec_Ptr_t * vCone1; - // memory manager - Extra_MmFixed_t* pMmObj; // memory manager for objects -}; - -static Abc_HMan_t * s_pHMan = NULL; - -static inline int Abc_HObjProof( Abc_HObj_t * p ) { return p->fProof; } -static inline int Abc_HObjPhase( Abc_HObj_t * p ) { return p->fPhase; } -static inline int Abc_HObjPi ( Abc_HObj_t * p ) { return p->fPi; } -static inline int Abc_HObjPo ( Abc_HObj_t * p ) { return p->fPo; } -static inline int Abc_HObjConst( Abc_HObj_t * p ) { return p->fConst; } -static inline int Abc_HObjNtkId( Abc_HObj_t * p ) { return p->NtkId; } -static inline int Abc_HObjNum ( Abc_HObj_t * p ) { return p->Num; } -static inline Abc_HObj_t * Abc_HObjFanin0( Abc_HObj_t * p ) { return !p->Fan0.NtkId ? NULL : Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->Fan0.NtkId), p->Fan0.ObjId ); } -static inline Abc_HObj_t * Abc_HObjFanin1( Abc_HObj_t * p ) { return !p->Fan1.NtkId ? NULL : Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->Fan1.NtkId), p->Fan1.ObjId ); } -static inline Abc_HObj_t * Abc_HObjProto ( Abc_HObj_t * p ) { return !p->Proto.NtkId ? NULL : Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->Proto.NtkId), p->Proto.ObjId ); } -static inline int Abc_HObjFaninC0( Abc_HObj_t * p ) { return p->Fan0.fCompl; } -static inline int Abc_HObjFaninC1( Abc_HObj_t * p ) { return p->Fan1.fCompl; } - -static inline Abc_HObj_t * Abc_ObjHObj( Abc_Obj_t * p ) { return Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->pNtk->Id), p->Id ); } - -static int Abc_HManVerifyPair( int NtkIdOld, int NtkIdNew ); -static int Abc_HManVerifyNodes_rec( Abc_HObj_t * pHOld, Abc_HObj_t * pHNew ); - -static Vec_Ptr_t * Abc_HManCollectLeaves( Abc_HObj_t * pHNew ); -static Vec_Ptr_t * Abc_HManCollectCone( Abc_HObj_t * pHOld, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone ); -static int Abc_HManSimulate( Vec_Ptr_t * vCone0, Vec_Ptr_t * vCone1, int nLeaves, int * pPhase ); - - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_HManStart() -{ - Abc_HMan_t * p; - unsigned * pData; - int i, k; - assert( s_pHMan == NULL ); - assert( sizeof(unsigned) == 4 ); - // allocate manager - p = ALLOC( Abc_HMan_t, 1 ); - memset( p, 0, sizeof(Abc_HMan_t) ); - // allocate storage for all nodes - p->vNtks = Vec_VecStart( 1 ); - p->vProof = Vec_IntStart( 1 ); - // allocate temporary storage for objects - p->nVarsMax = ABC_SIM_VARS; - p->nObjsMax = ABC_SIM_OBJS; - p->vObjs = Vec_PtrAlloc( p->nObjsMax ); - // allocate simulation info - p->nBits = (1 << p->nVarsMax); - p->nWords = (p->nBits <= 32)? 1 : (p->nBits / 32); - p->pInfo = ALLOC( unsigned, p->nWords * p->nObjsMax ); - memset( p->pInfo, 0, sizeof(unsigned) * p->nWords * p->nVarsMax ); - p->vSims = Vec_PtrAlloc( p->nObjsMax ); - for ( i = 0; i < p->nObjsMax; i++ ) - Vec_PtrPush( p->vSims, p->pInfo + i * p->nWords ); - // set elementary truth tables - for ( k = 0; k < p->nVarsMax; k++ ) - { - pData = p->vSims->pArray[k]; - for ( i = 0; i < p->nBits; i++ ) - if ( i & (1 << k) ) - pData[i>>5] |= (1 << (i&31)); - } - // allocate storage for the nodes - p->pMmObj = Extra_MmFixedStart( sizeof(Abc_HObj_t) ); - p->vCone0 = Vec_PtrAlloc( p->nObjsMax ); - p->vCone1 = Vec_PtrAlloc( p->nObjsMax ); - s_pHMan = p; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_HManStop() -{ - assert( s_pHMan != NULL ); - Extra_MmFixedStop( s_pHMan->pMmObj, 0 ); - Vec_PtrFree( s_pHMan->vObjs ); - Vec_PtrFree( s_pHMan->vSims ); - Vec_VecFree( s_pHMan->vNtks ); - Vec_IntFree( s_pHMan->vProof ); - Vec_PtrFree( s_pHMan->vCone0 ); - Vec_PtrFree( s_pHMan->vCone1 ); - free( s_pHMan->pInfo ); - free( s_pHMan ); - s_pHMan = NULL; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_HManIsRunning() -{ - return s_pHMan != NULL; -} - -/**Function************************************************************* - - Synopsis [Called when a new network is created.] - - Description [Returns the new ID for the network.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_HManGetNewNtkId() -{ - if ( s_pHMan == NULL ) - return 0; - return Vec_VecSize( s_pHMan->vNtks ); // what if the new network has no nodes? -} - -/**Function************************************************************* - - Synopsis [Called when the object is created.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_HManAddObj( Abc_Obj_t * pObj ) -{ - Abc_HObj_t * pHObj; - if ( s_pHMan == NULL ) - return; - pHObj = (Abc_HObj_t *)Extra_MmFixedEntryFetch( s_pHMan->pMmObj ); - memset( pHObj, 0, sizeof(Abc_HObj_t) ); - // set the object type - pHObj->NtkId = pObj->pNtk->Id; - if ( Abc_ObjIsCi(pObj) ) - pHObj->fPi = 1; - else if ( Abc_ObjIsCo(pObj) ) - pHObj->fPo = 1; - Vec_VecPush( s_pHMan->vNtks, pObj->pNtk->Id, pHObj ); - // set the proof parameter for the network - if ( Vec_IntSize( s_pHMan->vProof ) == pObj->pNtk->Id ) - Vec_IntPush( s_pHMan->vProof, 0 ); -} - -/**Function************************************************************* - - Synopsis [Called when the fanin is added to the object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_HManAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin ) -{ - Abc_HObj_t * pHObj; - int fCompl; - if ( s_pHMan == NULL ) - return; - // take off the complemented attribute - assert( !Abc_ObjIsComplement(pObj) ); - fCompl = Abc_ObjIsComplement(pFanin); - pFanin = Abc_ObjRegular(pFanin); - // add the fanin - assert( pObj->pNtk == pFanin->pNtk ); - pHObj = Abc_ObjHObj(pObj); - if ( pHObj->Fan0.NtkId == 0 ) - { - pHObj->Fan0.NtkId = pFanin->pNtk->Id; - pHObj->Fan0.ObjId = pFanin->Id; - pHObj->Fan0.fCompl = fCompl; - } - else if ( pHObj->Fan1.NtkId == 0 ) - { - pHObj->Fan1.NtkId = pFanin->pNtk->Id; - pHObj->Fan1.ObjId = pFanin->Id; - pHObj->Fan1.fCompl = fCompl; - } - else assert( 0 ); -} - -/**Function************************************************************* - - Synopsis [Called when the fanin's input should be complemented.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_HManXorFaninC( Abc_Obj_t * pObj, int iFanin ) -{ - Abc_HObj_t * pHObj; - if ( s_pHMan == NULL ) - return; - assert( iFanin < 2 ); - pHObj = Abc_ObjHObj(pObj); - if ( iFanin == 0 ) - pHObj->Fan0.fCompl ^= 1; - else if ( iFanin == 1 ) - pHObj->Fan1.fCompl ^= 1; -} - -/**Function************************************************************* - - Synopsis [Called when the fanin is added to the object.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_HManRemoveFanins( Abc_Obj_t * pObj ) -{ - Abc_HObj_t * pHObj; - if ( s_pHMan == NULL ) - return; - assert( !Abc_ObjIsComplement(pObj) ); - pHObj = Abc_ObjHObj(pObj); - pHObj->Fan0.NtkId = 0; - pHObj->Fan0.ObjId = 0; - pHObj->Fan0.fCompl = 0; - pHObj->Fan1.NtkId = 0; - pHObj->Fan1.ObjId = 0; - pHObj->Fan1.fCompl = 0; -} - -/**Function************************************************************* - - Synopsis [Called when a new prototype of the old object is set.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_HManAddProto( Abc_Obj_t * pObj, Abc_Obj_t * pProto ) -{ - Abc_HObj_t * pHObj; - if ( s_pHMan == NULL ) - return; - // ignore polarity for now - pObj = Abc_ObjRegular(pObj); - pProto = Abc_ObjRegular(pProto); - // set the prototype - assert( pObj->pNtk != pProto->pNtk ); - if ( pObj->pNtk->Id == 0 ) - return; - pHObj = Abc_ObjHObj(pObj); - pHObj->Proto.NtkId = pProto->pNtk->Id; - pHObj->Proto.ObjId = pProto->Id; -} - -/**Function************************************************************* - - Synopsis [Called when an equivalent node is created.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_HManMapAddEqu( Abc_Obj_t * pObj, Abc_Obj_t * pEqu ) -{ -/* - Abc_HObj_t * pHObj; - if ( s_pHMan == NULL ) - return; - // ignore polarity for now - pObj = Abc_ObjRegular(pObj); - pEqu = Abc_ObjRegular(pEqu); - // set the equivalent node - assert( pObj->pNtk == pEqu->pNtk ); - pHObj = Abc_ObjHObj(pObj); - Abc_ObjHObj(pObj)->Equ.NtkId = pEqu->pNtk->Id; - Abc_ObjHObj(pObj)->Equ.ObjId = pEqu->Id; -*/ -} - - - -/**Function************************************************************* - - Synopsis [Starts the verification procedure.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_HManPopulate( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i; - if ( !Abc_NtkIsStrash(pNtk) ) - return 0; - // allocate the network ID - pNtk->Id = Abc_HManGetNewNtkId(); - assert( pNtk->Id == 1 ); - // create the objects - Abc_NtkForEachObj( pNtk, pObj, i ) - { - Abc_HManAddObj( pObj ); - if ( Abc_ObjFaninNum(pObj) > 0 ) - Abc_HManAddFanin( pObj, Abc_ObjChild0(pObj) ); - if ( Abc_ObjFaninNum(pObj) > 1 ) - Abc_HManAddFanin( pObj, Abc_ObjChild1(pObj) ); - } - return 1; -} - -/**Function************************************************************* - - Synopsis [The main verification procedure.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_HManVerify( int NtkIdOld, int NtkIdNew ) -{ - int i; - // prove the equality pairwise - for ( i = NtkIdOld; i < NtkIdNew; i++ ) - { - if ( Vec_IntEntry(s_pHMan->vProof, i) ) - continue; - if ( !Abc_HManVerifyPair( i, i+1 ) ) - return 0; - Vec_IntWriteEntry( s_pHMan->vProof, i, 1 ); - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Verifies two networks.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_HManVerifyPair( int NtkIdOld, int NtkIdNew ) -{ - Vec_Ptr_t * vNtkNew, * vNtkOld, * vPosNew; - Abc_HObj_t * pHObj; - int i; - // get hold of the network nodes - vNtkNew = Vec_VecEntry( s_pHMan->vNtks, NtkIdNew ); - vNtkOld = Vec_VecEntry( s_pHMan->vNtks, NtkIdOld ); - Vec_PtrForEachEntry( vNtkNew, pHObj, i ) - pHObj->fVisited = 0; - Vec_PtrForEachEntry( vNtkOld, pHObj, i ) - pHObj->fVisited = 0; - // collect new POs - vPosNew = Vec_PtrAlloc( 100 ); - Vec_PtrForEachEntry( vNtkNew, pHObj, i ) - if ( pHObj->fPo ) - Vec_PtrPush( vPosNew, pHObj ); - // prove them recursively (assuming PO ordering is the same) - Vec_PtrForEachEntry( vPosNew, pHObj, i ) - { - if ( Abc_HObjProto(pHObj) == NULL ) - { - printf( "History: PO %d has no prototype\n", i ); - return 0; - } - if ( !Abc_HManVerifyNodes_rec( Abc_HObjProto(pHObj), pHObj ) ) - { - printf( "History: Verification failed for outputs of PO pair number %d\n", i ); - return 0; - } - } - printf( "History: Verification succeeded.\n" ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Recursively verifies two nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_HManVerifyNodes_rec( Abc_HObj_t * pHOld, Abc_HObj_t * pHNew ) -{ - Vec_Ptr_t * vLeaves; - Abc_HObj_t * pHObj, * pHPro0, * pHPro1; - int i, fPhase; - - assert( Abc_HObjProto(pHNew) == pHOld ); - if ( pHNew->fProof ) - return 1; - pHNew->fProof = 1; - // consider simple cases - if ( pHNew->fPi || pHNew->fConst ) - return 1; - if ( pHNew->fPo ) - { - if ( !Abc_HManVerifyNodes_rec( Abc_HObjFanin0(pHOld), Abc_HObjFanin0(pHNew) ) ) - return 0; - if ( (Abc_HObjFaninC0(pHOld) ^ Abc_HObjFaninC0(pHNew)) != (int)pHNew->fPhase ) - { - printf( "History: Phase of PO nodes does not agree.\n" ); - return 0; - } - return 1; - } - // the elementary node - pHPro0 = Abc_HObjProto( Abc_HObjFanin0(pHNew) ); - pHPro1 = Abc_HObjProto( Abc_HObjFanin1(pHNew) ); - if ( pHPro0 && pHPro1 ) - { - if ( !Abc_HManVerifyNodes_rec( pHPro0, Abc_HObjFanin0(pHNew) ) ) - return 0; - if ( !Abc_HManVerifyNodes_rec( pHPro1, Abc_HObjFanin1(pHNew) ) ) - return 0; - if ( Abc_HObjFanin0(pHOld) != pHPro0 || Abc_HObjFanin1(pHOld) != pHPro1 ) - { - printf( "History: Internal node does not match.\n" ); - return 0; - } - if ( Abc_HObjFaninC0(pHOld) != Abc_HObjFaninC0(pHNew) || - Abc_HObjFaninC1(pHOld) != Abc_HObjFaninC1(pHNew) ) - { - printf( "History: Phase of internal node does not match.\n" ); - return 0; - } - return 1; - } - // collect the leaves - vLeaves = Abc_HManCollectLeaves( pHNew ); - if ( Vec_PtrSize(vLeaves) > 16 ) - { - printf( "History: The bound on the number of inputs is exceeded.\n" ); - return 0; - } - s_pHMan->nWordsCur = ((1 << Vec_PtrSize(vLeaves)) <= 32)? 1 : ((1 << Vec_PtrSize(vLeaves)) / 32); - // prove recursively - Vec_PtrForEachEntry( vLeaves, pHObj, i ) - if ( !Abc_HManVerifyNodes_rec( Abc_HObjProto(pHObj), pHObj ) ) - { - Vec_PtrFree( vLeaves ); - return 0; - } - // get the first node - Abc_HManCollectCone( pHNew, vLeaves, s_pHMan->vCone1 ); - if ( Vec_PtrSize(s_pHMan->vCone1) > ABC_SIM_OBJS - ABC_SIM_VARS - 1 ) - { - printf( "History: The bound on the number of cone nodes is exceeded.\n" ); - return 0; - } - // get the second cone - Vec_PtrForEachEntry( vLeaves, pHObj, i ) - Vec_PtrWriteEntry( vLeaves, i, Abc_HObjProto(pHObj) ); - Abc_HManCollectCone( pHOld, vLeaves, s_pHMan->vCone0 ); - if ( Vec_PtrSize(s_pHMan->vCone0) > ABC_SIM_OBJS - ABC_SIM_VARS - 1 ) - { - printf( "History: The bound on the number of cone nodes is exceeded.\n" ); - return 0; - } - // compare the truth tables - if ( !Abc_HManSimulate( s_pHMan->vCone0, s_pHMan->vCone1, Vec_PtrSize(vLeaves), &fPhase ) ) - { - Vec_PtrFree( vLeaves ); - printf( "History: Verification failed at an internal node.\n" ); - return 0; - } - printf( "Succeeded.\n" ); - pHNew->fPhase = fPhase; - Vec_PtrFree( vLeaves ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Finds the leaves of the TFI cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_HManCollectLeaves_rec( Abc_HObj_t * pHNew, Vec_Ptr_t * vLeaves ) -{ - Abc_HObj_t * pHPro; - if ( pHPro = Abc_HObjProto( pHNew ) ) - { - Vec_PtrPushUnique( vLeaves, pHNew ); - return; - } - assert( !pHNew->fPi && !pHNew->fPo && !pHNew->fConst ); - Abc_HManCollectLeaves_rec( Abc_HObjFanin0(pHNew), vLeaves ); - Abc_HManCollectLeaves_rec( Abc_HObjFanin1(pHNew), vLeaves ); -} - -/**Function************************************************************* - - Synopsis [Finds the leaves of the TFI cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_HManCollectLeaves( Abc_HObj_t * pHNew ) -{ - Vec_Ptr_t * vLeaves; - vLeaves = Vec_PtrAlloc( 100 ); - Abc_HManCollectLeaves_rec( Abc_HObjFanin0(pHNew), vLeaves ); - Abc_HManCollectLeaves_rec( Abc_HObjFanin1(pHNew), vLeaves ); - return vLeaves; -} - - -/**Function************************************************************* - - Synopsis [Collects the TFI cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_HManCollectCone_rec( Abc_HObj_t * pHObj, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone ) -{ - if ( pHObj->fVisited ) - return; - pHObj->fVisited = 1; - assert( !pHObj->fPi && !pHObj->fPo && !pHObj->fConst ); - Abc_HManCollectCone_rec( Abc_HObjFanin0(pHObj), vLeaves, vCone ); - Abc_HManCollectCone_rec( Abc_HObjFanin1(pHObj), vLeaves, vCone ); - pHObj->Num = Vec_PtrSize(vCone); - Vec_PtrPush( vCone, pHObj ); -} - -/**Function************************************************************* - - Synopsis [Collects the TFI cone.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_HManCollectCone( Abc_HObj_t * pHRoot, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone ) -{ - Abc_HObj_t * pHObj; - int i; - Vec_PtrClear( vCone ); - Vec_PtrForEachEntry( vLeaves, pHObj, i ) - { - pHObj->fVisited = 1; - pHObj->Num = Vec_PtrSize(vCone); - Vec_PtrPush( vCone, pHObj ); - } - Abc_HManCollectCone_rec( Abc_HObjFanin0(pHRoot), vLeaves, vCone ); - Abc_HManCollectCone_rec( Abc_HObjFanin1(pHRoot), vLeaves, vCone ); - return vCone; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_HManSimulateOne( Vec_Ptr_t * vCone, int nLeaves, int fUsePhase ) -{ - Abc_HObj_t * pHObj, * pHFan0, * pHFan1; - unsigned * puData0, * puData1, * puData; - int k, i, fComp0, fComp1; - // set the leaves - Vec_PtrForEachEntryStart( vCone, pHObj, i, nLeaves ) - { - pHFan0 = Abc_HObjFanin0(pHObj); - pHFan1 = Abc_HObjFanin1(pHObj); - // consider the case of interver or buffer - if ( pHFan1 == NULL ) - { - puData = Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+i-nLeaves); - puData0 = ((int)pHFan0->Num < nLeaves)? Vec_PtrEntry(s_pHMan->vSims, pHFan0->Num) : - Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+pHFan0->Num-nLeaves); - fComp0 = Abc_HObjFaninC0(pHObj) ^ (fUsePhase && (int)pHFan0->Num < nLeaves && pHFan0->fPhase); - if ( fComp0 ) - for ( k = 0; k < s_pHMan->nWordsCur; k++ ) - puData[k] = ~puData0[k]; - else - for ( k = 0; k < s_pHMan->nWordsCur; k++ ) - puData[k] = puData0[k]; - continue; - } - // get the pointers to simulation data - puData = Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+i-nLeaves); - puData0 = ((int)pHFan0->Num < nLeaves)? Vec_PtrEntry(s_pHMan->vSims, pHFan0->Num) : - Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+pHFan0->Num-nLeaves); - puData1 = ((int)pHFan1->Num < nLeaves)? Vec_PtrEntry(s_pHMan->vSims, pHFan1->Num) : - Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+pHFan1->Num-nLeaves); - // here are the phases - fComp0 = Abc_HObjFaninC0(pHObj) ^ (fUsePhase && (int)pHFan0->Num < nLeaves && pHFan0->fPhase); - fComp1 = Abc_HObjFaninC1(pHObj) ^ (fUsePhase && (int)pHFan1->Num < nLeaves && pHFan1->fPhase); - // simulate - if ( fComp0 && fComp1 ) - for ( k = 0; k < s_pHMan->nWordsCur; k++ ) - puData[k] = ~puData0[k] & ~puData1[k]; - else if ( fComp0 ) - for ( k = 0; k < s_pHMan->nWordsCur; k++ ) - puData[k] = ~puData0[k] & puData1[k]; - else if ( fComp1 ) - for ( k = 0; k < s_pHMan->nWordsCur; k++ ) - puData[k] = puData0[k] & ~puData1[k]; - else - for ( k = 0; k < s_pHMan->nWordsCur; k++ ) - puData[k] = puData0[k] & puData1[k]; - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_HManSimulate( Vec_Ptr_t * vCone0, Vec_Ptr_t * vCone1, int nLeaves, int * pPhase ) -{ - unsigned * pDataTop, * pDataLast; - int w; - // simulate the first one - Abc_HManSimulateOne( vCone0, nLeaves, 0 ); - // save the last simulation value - pDataTop = Vec_PtrEntry( s_pHMan->vSims, ((Abc_HObj_t *)Vec_PtrEntryLast(vCone0))->Num ); - pDataLast = Vec_PtrEntry( s_pHMan->vSims, Vec_PtrSize(s_pHMan->vSims)-1 ); - for ( w = 0; w < s_pHMan->nWordsCur; w++ ) - pDataLast[w] = pDataTop[w]; - // simulate the other one - Abc_HManSimulateOne( vCone1, nLeaves, 1 ); - // complement the output if needed - pDataTop = Vec_PtrEntry( s_pHMan->vSims, ((Abc_HObj_t *)Vec_PtrEntryLast(vCone1))->Num ); - // mask unused bits - if ( nLeaves < 5 ) - { - pDataTop[0] &= ((~((unsigned)0)) >> (32-(1<<nLeaves))); - pDataLast[0] &= ((~((unsigned)0)) >> (32-(1<<nLeaves))); - } - if ( *pPhase = ((pDataTop[0] & 1) != (pDataLast[0] & 1)) ) - for ( w = 0; w < s_pHMan->nWordsCur; w++ ) - pDataTop[w] = ~pDataTop[w]; - // compare - for ( w = 0; w < s_pHMan->nWordsCur; w++ ) - if ( pDataLast[w] != pDataTop[w] ) - return 0; - return 1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abci/abcUnreach.c b/src/base/abci/abcUnreach.c index f1ec3847..b5306bea 100644 --- a/src/base/abci/abcUnreach.c +++ b/src/base/abci/abcUnreach.c @@ -333,7 +333,7 @@ Abc_Ntk_t * Abc_NtkConstructExdc( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bUn // transform the network to the SOP representation if ( !Abc_NtkBddToSop( pNtkNew, 0 ) ) { - printf( "Converting to SOPs has failed.\n" ); + printf( "Abc_NtkConstructExdc(): Converting to SOPs has failed.\n" ); return NULL; } return pNtkNew; diff --git a/src/base/abci/abcVanEijk.c b/src/base/abci/abcVanEijk.c index 81423c30..58d9f64e 100644 --- a/src/base/abci/abcVanEijk.c +++ b/src/base/abci/abcVanEijk.c @@ -526,7 +526,7 @@ Abc_Ntk_t * Abc_NtkVanEijkFrames( Abc_Ntk_t * pNtk, Vec_Ptr_t * vCorresp, int nF pNtkFrames->pName = Extra_UtilStrsav(Buffer); } // map the constant nodes - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkFrames); + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkFrames); // create new latches and remember them in the new latches Abc_NtkForEachLatch( pNtk, pLatch, i ) Abc_NtkDupObj( pNtkFrames, pLatch ); @@ -589,7 +589,7 @@ void Abc_NtkVanEijkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFram // remember the CI mapping if ( vCorresp ) { - pNode = Abc_NtkConst1(pNtk); + pNode = Abc_AigConst1(pNtk); Abc_NodeVanEijkWriteCorresp( pNode, vCorresp, iFrame, Abc_ObjRegular(pNode->pCopy) ); Abc_NtkForEachCi( pNtk, pNode, i ) Abc_NodeVanEijkWriteCorresp( pNode, vCorresp, iFrame, Abc_ObjRegular(pNode->pCopy) ); @@ -667,7 +667,7 @@ Fraig_Man_t * Abc_NtkVanEijkFraig( Abc_Ntk_t * pMulti, int fInit ) // clean the copy fields in the old network Abc_NtkCleanCopy( pMulti ); // map the constant nodes - Abc_NtkConst1(pMulti)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan); + Abc_AigConst1(pMulti)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan); if ( fInit ) { // map the PI nodes @@ -724,14 +724,14 @@ Abc_Ntk_t * Abc_NtkVanEijkDeriveExdc( Abc_Ntk_t * pNtk, Vec_Ptr_t * vClasses ) pNtkNew->pSpec = NULL; // map the constant nodes - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew); + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); // for each CI, create PI Abc_NtkForEachCi( pNtk, pObj, i ) Abc_NtkLogicStoreName( pObj->pCopy = Abc_NtkCreatePi(pNtkNew), Abc_ObjName(pObj) ); // cannot add latches here because pLatch->pCopy pointers are used // create the cones for each pair of nodes in an equivalence class - pTotal = Abc_ObjNot( Abc_NtkConst1(pNtkNew) ); + pTotal = Abc_ObjNot( Abc_AigConst1(pNtkNew) ); Vec_PtrForEachEntry( vClasses, pClass, i ) { assert( pClass->pNext ); @@ -783,7 +783,7 @@ Abc_Ntk_t * Abc_NtkVanEijkDeriveExdc( Abc_Ntk_t * pNtk, Vec_Ptr_t * vClasses ) Abc_NtkDeleteObj( pObjNew ); // make the old network point to the new things - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew); + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); Abc_NtkForEachCi( pNtk, pObj, i ) pObj->pCopy = Abc_NtkPi( pNtkNew, i ); */ diff --git a/src/base/abci/abcVanImp.c b/src/base/abci/abcVanImp.c index 77de5185..29b5d3a6 100644 --- a/src/base/abci/abcVanImp.c +++ b/src/base/abci/abcVanImp.c @@ -487,7 +487,7 @@ printf( "PO = %d\n", pNode1->Id ); // go through the pairs of signals in the frames pProgress = Extra_ProgressBarStart( stdout, p->nIdMax ); - pConst1 = Abc_NtkConst1( p->pNtkSingle ); + pConst1 = Abc_AigConst1(p->pNtkSingle); p->vImps = Vec_IntAlloc( 100 ); p->vZeros = Vec_PtrAlloc( 100 ); Abc_NtkForEachObj( p->pNtkSingle, pNode1, i ) @@ -882,14 +882,14 @@ Abc_Ntk_t * Abc_NtkVanImpDeriveExdc( Abc_Ntk_t * pNtk, Vec_Ptr_t * vZeros, Vec_I pNtkNew->pSpec = NULL; // map the constant nodes - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew); + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); // for each CI, create PI Abc_NtkForEachCi( pNtk, pObj, i ) Abc_NtkLogicStoreName( pObj->pCopy = Abc_NtkCreatePi(pNtkNew), Abc_ObjName(pObj) ); // cannot add latches here because pLatch->pCopy pointers are used // build logic cone for zero nodes - pTotal = Abc_ObjNot( Abc_NtkConst1(pNtkNew) ); + pTotal = Abc_ObjNot( Abc_AigConst1(pNtkNew) ); Vec_PtrForEachEntry( vZeros, pNode, i ) { // build the logic cone for the node @@ -961,7 +961,7 @@ Abc_Ntk_t * Abc_NtkVanImpDeriveExdc( Abc_Ntk_t * pNtk, Vec_Ptr_t * vZeros, Vec_I Abc_NtkDeleteObj( pObjNew ); // make the old network point to the new things - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew); + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); Abc_NtkForEachCi( pNtk, pObj, i ) pObj->pCopy = Abc_NtkPi( pNtkNew, i ); */ diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c index d9478b04..c6782b07 100644 --- a/src/base/abci/abcVerify.c +++ b/src/base/abci/abcVerify.c @@ -422,9 +422,9 @@ int * Abc_NtkVerifySimulatePattern( Abc_Ntk_t * pNtk, int * pModel ) vNodes = Abc_NtkDfs( pNtk, 1 ); Vec_PtrForEachEntry( vNodes, pNode, i ) { - if ( Abc_NodeIsConst(pNode) ) - pNode->pCopy = NULL; - else +// if ( Abc_NodeIsConst(pNode) ) +// pNode->pCopy = NULL; +// else { Value0 = ((int)Abc_ObjFanin0(pNode)->pCopy) ^ Abc_ObjFaninC0(pNode); Value1 = ((int)Abc_ObjFanin1(pNode)->pCopy) ^ Abc_ObjFaninC1(pNode); diff --git a/src/base/abci/module.make b/src/base/abci/module.make index 2e338e48..54c6f05c 100644 --- a/src/base/abci/module.make +++ b/src/base/abci/module.make @@ -31,7 +31,6 @@ SRC += src/base/abci/abc.c \ src/base/abci/abcSweep.c \ src/base/abci/abcSymm.c \ src/base/abci/abcTiming.c \ - src/base/abci/abcTrace.c \ src/base/abci/abcUnate.c \ src/base/abci/abcUnreach.c \ src/base/abci/abcVanEijk.c \ diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index ac012516..41299790 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -1261,7 +1261,7 @@ int CmdCommandSis( Abc_Frame_t * pAbc, int argc, char **argv ) if ( Abc_NtkIsMappedLogic(pNtk) ) { - Abc_NtkUnmap(pNtk); + Abc_NtkMapToSop(pNtk); printf( "The current network is unmapped before calling SIS.\n" ); } @@ -1402,7 +1402,7 @@ int CmdCommandMvsis( Abc_Frame_t * pAbc, int argc, char **argv ) if ( Abc_NtkIsMappedLogic(pNtk) ) { - Abc_NtkUnmap(pNtk); + Abc_NtkMapToSop(pNtk); printf( "The current network is unmapped before calling MVSIS.\n" ); } @@ -1548,7 +1548,7 @@ int CmdCommandCapo( Abc_Frame_t * pAbc, int argc, char **argv ) if ( Abc_NtkIsMappedLogic(pNtk) ) { - Abc_NtkUnmap(pNtk); + Abc_NtkMapToSop(pNtk); printf( "The current network is unmapped before calling Capo.\n" ); } diff --git a/src/base/io/io.c b/src/base/io/io.c index 6da1f4d8..0cc3c7d9 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -667,13 +667,13 @@ usage: ***********************************************************************/ int IoCommandReadVer( Abc_Frame_t * pAbc, int argc, char ** argv ) { - Abc_Ntk_t * pNtk, * pTemp; - st_table * tDesign; + Abc_Ntk_t * pNtk; + Abc_Lib_t * pDesign; char * FileName; FILE * pFile; int fCheck; int c; - extern st_table * Ver_ParseFile( char * pFileName, st_table * pGateLib, int fCheck ); + extern Abc_Lib_t * Ver_ParseFile( char * pFileName, Abc_Lib_t * pGateLib, int fCheck ); fCheck = 1; Extra_UtilGetoptReset(); @@ -709,41 +709,21 @@ int IoCommandReadVer( Abc_Frame_t * pAbc, int argc, char ** argv ) fclose( pFile ); // set the new network - tDesign = Ver_ParseFile( FileName, Abc_FrameReadLibVer(), fCheck ); - if ( tDesign == NULL ) + pDesign = Ver_ParseFile( FileName, Abc_FrameReadLibVer(), fCheck ); + if ( pDesign == NULL ) { fprintf( pAbc->Err, "Reading network from the verilog file has failed.\n" ); return 1; } - - if ( st_count(tDesign) == 1 ) - { - st_generator * gen; - char * pName; - // find the network - st_foreach_item( tDesign, gen, (char**)&pName, (char**)&pNtk ) - { - st_free_gen(gen); - break; - } - st_free_table( tDesign ); - - // convert it into a logic network - pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk ); - Abc_NtkDelete( pTemp ); - if ( pNtk == NULL ) - { - fprintf( pAbc->Err, "Converting to logic network after reading has failed.\n" ); - return 1; - } - // replace the current network - Abc_FrameReplaceCurrentNetwork( pAbc, pNtk ); - } - else + // derive root design + pNtk = Abc_LibDeriveRoot( pDesign ); + if ( pNtk == NULL ) { - printf( "The design includes more than one module and is currently not used.\n" ); + fprintf( pAbc->Err, "Deriving root module has failed.\n" ); + return 1; } - + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtk ); return 0; usage: @@ -768,14 +748,12 @@ usage: ***********************************************************************/ int IoCommandReadVerLib( Abc_Frame_t * pAbc, int argc, char ** argv ) { - Abc_Ntk_t * pNtk, * pTemp; - st_table * tDesign; + Abc_Lib_t * pLibrary; char * FileName; FILE * pFile; int fCheck; int c; - extern st_table * Ver_ParseFile( char * pFileName, st_table * pGateLib, int fCheck ); - extern void Ver_ParseFreeLibrary( st_table * pLibVer ); + extern Abc_Lib_t * Ver_ParseFile( char * pFileName, Abc_Lib_t * pGateLib, int fCheck ); fCheck = 1; Extra_UtilGetoptReset(); @@ -811,41 +789,18 @@ int IoCommandReadVerLib( Abc_Frame_t * pAbc, int argc, char ** argv ) fclose( pFile ); // set the new network - tDesign = Ver_ParseFile( FileName, NULL, fCheck ); - if ( tDesign == NULL ) + pLibrary = Ver_ParseFile( FileName, NULL, fCheck ); + if ( pLibrary == NULL ) { fprintf( pAbc->Err, "Reading library from the verilog file has failed.\n" ); return 1; } - printf( "The library contains %d gates.\n", st_count(tDesign) ); - - // convert gates into AIGs - { - st_table * tLibrary; - st_generator * gen; - char * pName; - // transform the gates into the library AIGs - tLibrary = st_init_table( strcmp, st_strhash ); - st_foreach_item( tDesign, gen, (char**)&pName, (char**)&pNtk ) - { - // convert the netlist into SOP logic network - pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk ); - Abc_NtkDelete( pTemp ); - // perform structural hashing - pNtk = Abc_NtkStrash( pTemp = pNtk, 0, 1 ); - Abc_NtkDelete( pTemp ); - // insert the new network into the new library - st_insert( tLibrary, pNtk->pName, (char *)pNtk ); - } - st_free_table( tDesign ); - - // free old library - if ( Abc_FrameReadLibVer() ) - Ver_ParseFreeLibrary( Abc_FrameReadLibVer() ); - // read new library - Abc_FrameSetLibVer( tLibrary ); - } - + printf( "The library contains %d gates.\n", st_count(pLibrary->tModules) ); + // free old library + if ( Abc_FrameReadLibVer() ) + Abc_LibFree( Abc_FrameReadLibVer() ); + // read new library + Abc_FrameSetLibVer( pLibrary ); return 0; usage: diff --git a/src/base/io/ioReadBaf.c b/src/base/io/ioReadBaf.c index 8f4a8ec4..83b642a0 100644 --- a/src/base/io/ioReadBaf.c +++ b/src/base/io/ioReadBaf.c @@ -79,7 +79,7 @@ Abc_Ntk_t * Io_ReadBaf( char * pFileName, int fCheck ) // prepare the array of nodes vNodes = Vec_PtrAlloc( 1 + nInputs + nLatches + nAnds ); - Vec_PtrPush( vNodes, Abc_NtkConst1(pNtkNew) ); + Vec_PtrPush( vNodes, Abc_AigConst1(pNtkNew) ); // create the PIs for ( i = 0; i < nInputs; i++ ) diff --git a/src/base/io/ioWriteDot.c b/src/base/io/ioWriteDot.c index ed6acb24..8ce837e2 100644 --- a/src/base/io/ioWriteDot.c +++ b/src/base/io/ioWriteDot.c @@ -415,7 +415,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho { if ( !Abc_NtkBddToSop(pNtk, 0) ) { - printf( "Converting to SOPs has failed.\n" ); + printf( "Io_WriteDotNtk(): Converting to SOPs has failed.\n" ); return; } } diff --git a/src/base/io/ioWriteList.c b/src/base/io/ioWriteList.c index f0981a8e..c2bea884 100644 --- a/src/base/io/ioWriteList.c +++ b/src/base/io/ioWriteList.c @@ -117,8 +117,8 @@ void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost ) fprintf( pFile, "# written by ABC on %s\n", Extra_TimeStamp() ); // write the constant node - if ( Abc_ObjFanoutNum( Abc_NtkConst1(pNtk) ) > 0 ) - Io_WriteListEdge( pFile, Abc_NtkConst1(pNtk) ); + if ( Abc_ObjFanoutNum( Abc_AigConst1(pNtk) ) > 0 ) + Io_WriteListEdge( pFile, Abc_AigConst1(pNtk) ); // write the PI edges Abc_NtkForEachPi( pNtk, pObj, i ) diff --git a/src/base/io/ioWriteVerAux.c b/src/base/io/ioWriteVerAux.c index f0814c84..9fd71750 100644 --- a/src/base/io/ioWriteVerAux.c +++ b/src/base/io/ioWriteVerAux.c @@ -265,7 +265,6 @@ void Io_WriteVerilogAuxNodes( FILE * pFile, Abc_Ntk_t * pNtk ) Abc_Obj_t * pObj; int i, nCubes, nFanins, Counter, nDigits, fPadZeros; char * pName; - extern int Abc_SopIsExorType( char * pSop ); nDigits = Extra_Base10Log( Abc_NtkNodeNum(pNtk) ); Counter = 1; diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c index 068a8bfb..46834e3f 100644 --- a/src/base/main/mainFrame.c +++ b/src/base/main/mainFrame.c @@ -137,13 +137,12 @@ void Abc_FrameDeallocate( Abc_Frame_t * p ) { extern void Rwt_ManGlobalStop(); extern void undefine_cube_size(); - extern void Ver_ParseFreeLibrary( st_table * pLibVer ); // extern void Ivy_TruthManStop(); // Abc_HManStop(); undefine_cube_size(); Rwt_ManGlobalStop(); // Ivy_TruthManStop(); - if ( p->pLibVer ) Ver_ParseFreeLibrary( p->pLibVer ); + if ( p->pLibVer ) Abc_LibFree( p->pLibVer ); if ( p->pManDec ) Dec_ManStop( p->pManDec ); if ( p->dd ) Extra_StopManager( p->dd ); Abc_FrameDeleteAllNetworks( p ); @@ -427,7 +426,7 @@ void Abc_FrameUnmapAllNetworks( Abc_Frame_t * p ) Abc_Ntk_t * pNtk; for ( pNtk = p->pNtkCur; pNtk; pNtk = Abc_NtkBackup(pNtk) ) if ( Abc_NtkHasMapping(pNtk) ) - Abc_NtkUnmap( pNtk ); + Abc_NtkMapToSop( pNtk ); } /**Function************************************************************* diff --git a/src/base/seq/module.make b/src/base/seq/module.make index fbb1015a..c7716180 100644 --- a/src/base/seq/module.make +++ b/src/base/seq/module.make @@ -7,6 +7,7 @@ SRC += src/base/seq/seqAigCore.c \ src/base/seq/seqMan.c \ src/base/seq/seqMapCore.c \ src/base/seq/seqMapIter.c \ + src/base/seq/seqMaxMeanCycle.c \ src/base/seq/seqRetCore.c \ src/base/seq/seqRetIter.c \ src/base/seq/seqShare.c \ diff --git a/src/base/seq/seq.h b/src/base/seq/seq.h index b66799b5..d3c9abda 100644 --- a/src/base/seq/seq.h +++ b/src/base/seq/seq.h @@ -64,6 +64,9 @@ extern int Seq_NodeCompareLats( Abc_Obj_t * pObj1, int Edge1, Abc_Ob extern Abc_Seq_t * Seq_Create( Abc_Ntk_t * pNtk ); extern void Seq_Resize( Abc_Seq_t * p, int nMaxId ); extern void Seq_Delete( Abc_Seq_t * p ); +/*=== seqMaxMeanCycle.c ======================================================*/ +extern float Seq_NtkHoward( Abc_Ntk_t * pNtk, int fVerbose ); +extern void Seq_NtkSkewForward( Abc_Ntk_t * pNtk, float period, int fMinimize ); /*=== abcSeq.c ===============================================================*/ extern Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk ); extern Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk ); diff --git a/src/base/seq/seqCreate.c b/src/base/seq/seqCreate.c index a553e06f..30a21086 100644 --- a/src/base/seq/seqCreate.c +++ b/src/base/seq/seqCreate.c @@ -93,11 +93,11 @@ Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk ) // map the constant nodes Abc_NtkCleanCopy( pNtk ); - Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew); + Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); // copy all objects, except the latches and constant Vec_PtrFill( pNtkNew->vObjs, Abc_NtkObjNumMax(pNtk), NULL ); - Vec_PtrWriteEntry( pNtkNew->vObjs, 0, Abc_NtkConst1(pNtk)->pCopy ); + Vec_PtrWriteEntry( pNtkNew->vObjs, 0, Abc_AigConst1(pNtk)->pCopy ); Abc_NtkForEachObj( pNtk, pObj, i ) { if ( i == 0 || Abc_ObjIsLatch(pObj) ) @@ -236,7 +236,7 @@ void Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk ) Abc_NtkForEachLatch( pNtk, pLatch, i ) { pDriver = Abc_ObjFanin0(pLatch); - if ( Abc_NodeIsTravIdCurrent(pDriver) || !Abc_NodeIsAigAnd(pDriver) ) + if ( Abc_NodeIsTravIdCurrent(pDriver) || !Abc_AigNodeIsAnd(pDriver) ) continue; Abc_NodeSetTravIdCurrent(pDriver); pDriverNew = pDriver->pCopy; @@ -428,7 +428,7 @@ bool Abc_NtkSeqCheck( Abc_Ntk_t * pNtk ) nFanins = Abc_ObjFaninNum(pObj); if ( nFanins == 0 ) { - if ( pObj != Abc_NtkConst1(pNtk) ) + if ( pObj != Abc_AigConst1(pNtk) ) { printf( "Abc_SeqCheck: The AIG has non-standard constant nodes.\n" ); return 0; diff --git a/src/base/seq/seqFpgaCore.c b/src/base/seq/seqFpgaCore.c index 79e44caf..c6360363 100644 --- a/src/base/seq/seqFpgaCore.c +++ b/src/base/seq/seqFpgaCore.c @@ -382,7 +382,7 @@ int Seq_FpgaMappingCount_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vL if ( SeqEdge == (unsigned)pLeaf ) return 0; // continue unfolding - assert( Abc_NodeIsAigAnd(pObj) ); + assert( Abc_AigNodeIsAnd(pObj) ); // get new sequential edges assert( Lag + Seq_ObjFaninL0(pObj) < 255 ); assert( Lag + Seq_ObjFaninL1(pObj) < 255 ); @@ -417,7 +417,7 @@ Abc_Obj_t * Seq_FpgaMappingBuild_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, uns if ( SeqEdge == (unsigned)pLeaf ) return pObj->pCopy; // continue unfolding - assert( Abc_NodeIsAigAnd(pObj) ); + assert( Abc_AigNodeIsAnd(pObj) ); // get new sequential edges assert( Lag + Seq_ObjFaninL0(pObj) < 255 ); assert( Lag + Seq_ObjFaninL1(pObj) < 255 ); @@ -464,7 +464,7 @@ DdNode * Seq_FpgaMappingBdd_rec( DdManager * dd, Abc_Ntk_t * pNtk, unsigned SeqE if ( SeqEdge == (unsigned)pLeaf ) return Cudd_bddIthVar( dd, i ); // continue unfolding - assert( Abc_NodeIsAigAnd(pObj) ); + assert( Abc_AigNodeIsAnd(pObj) ); // get new sequential edges assert( Lag + Seq_ObjFaninL0(pObj) < 255 ); assert( Lag + Seq_ObjFaninL1(pObj) < 255 ); @@ -514,7 +514,7 @@ void Seq_FpgaMappingEdges_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * p } } // continue unfolding - assert( Abc_NodeIsAigAnd(pObj) ); + assert( Abc_AigNodeIsAnd(pObj) ); // get new sequential edges assert( Lag + Seq_ObjFaninL0(pObj) < 255 ); assert( Lag + Seq_ObjFaninL1(pObj) < 255 ); @@ -564,7 +564,7 @@ void Seq_FpgaMappingConnect_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * } } // continue unfolding - assert( Abc_NodeIsAigAnd(pObj) ); + assert( Abc_AigNodeIsAnd(pObj) ); // get new sequential edges assert( Lag + Seq_ObjFaninL0(pObj) < 255 ); assert( Lag + Seq_ObjFaninL1(pObj) < 255 ); @@ -616,7 +616,7 @@ DdNode * Seq_FpgaMappingConnectBdd_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_ } } // continue unfolding - assert( Abc_NodeIsAigAnd(pObj) ); + assert( Abc_AigNodeIsAnd(pObj) ); // get new sequential edges assert( Lag + Seq_ObjFaninL0(pObj) < 255 ); assert( Lag + Seq_ObjFaninL1(pObj) < 255 ); diff --git a/src/base/seq/seqFpgaIter.c b/src/base/seq/seqFpgaIter.c index ae411881..a300b362 100644 --- a/src/base/seq/seqFpgaIter.c +++ b/src/base/seq/seqFpgaIter.c @@ -116,7 +116,7 @@ void Seq_FpgaMappingCollectNode_rec( Abc_Obj_t * pAnd, Vec_Ptr_t * vMapping, Vec int k; // skip if this is a non-PI node - if ( !Abc_NodeIsAigAnd(pAnd) ) + if ( !Abc_AigNodeIsAnd(pAnd) ) return; // skip a visited node if ( Abc_NodeIsTravIdCurrent(pAnd) ) @@ -203,7 +203,7 @@ static inline int Seq_FpgaCutUpdateLValue( Cut_Cut_t * pCut, Abc_Obj_t * pObj, i { Abc_Obj_t * pFanin; int i, lValueMax, lValueCur; - assert( Abc_NodeIsAigAnd(pObj) ); + assert( Abc_AigNodeIsAnd(pObj) ); lValueMax = -ABC_INFINITY; for ( i = 0; i < (int)pCut->nLeaves; i++ ) { diff --git a/src/base/seq/seqMapCore.c b/src/base/seq/seqMapCore.c index a444ec58..3db29abd 100644 --- a/src/base/seq/seqMapCore.c +++ b/src/base/seq/seqMapCore.c @@ -474,7 +474,7 @@ int Seq_MapMappingCount_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vLe if ( SeqEdge == (unsigned)pLeaf ) return 0; // continue unfolding - assert( Abc_NodeIsAigAnd(pObj) ); + assert( Abc_AigNodeIsAnd(pObj) ); // get new sequential edges assert( Lag + Seq_ObjFaninL0(pObj) < 255 ); assert( Lag + Seq_ObjFaninL1(pObj) < 255 ); @@ -519,7 +519,7 @@ Abc_Obj_t * Seq_MapMappingBuild_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, unsi return pObj->pCopy; } // continue unfolding - assert( Abc_NodeIsAigAnd(pObj) ); + assert( Abc_AigNodeIsAnd(pObj) ); // get new sequential edges assert( Lag + Seq_ObjFaninL0(pObj) < 255 ); assert( Lag + Seq_ObjFaninL1(pObj) < 255 ); @@ -572,7 +572,7 @@ void Seq_MapMappingEdges_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * pP } } // continue unfolding - assert( Abc_NodeIsAigAnd(pObj) ); + assert( Abc_AigNodeIsAnd(pObj) ); // get new sequential edges assert( Lag + Seq_ObjFaninL0(pObj) < 255 ); assert( Lag + Seq_ObjFaninL1(pObj) < 255 ); @@ -625,7 +625,7 @@ DdNode * Seq_MapMappingConnectBdd_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_O } } // continue unfolding - assert( Abc_NodeIsAigAnd(pObj) ); + assert( Abc_AigNodeIsAnd(pObj) ); // get new sequential edges assert( Lag + Seq_ObjFaninL0(pObj) < 255 ); assert( Lag + Seq_ObjFaninL1(pObj) < 255 ); diff --git a/src/base/seq/seqMapIter.c b/src/base/seq/seqMapIter.c index 185c05f3..30333cea 100644 --- a/src/base/seq/seqMapIter.c +++ b/src/base/seq/seqMapIter.c @@ -540,7 +540,7 @@ float Seq_MapCollectNode_rec( Abc_Obj_t * pAnd, float FiBest, Vec_Ptr_t * vMappi } // skip if this is a PI or a constant - if ( !Abc_NodeIsAigAnd(pAnd) ) + if ( !Abc_AigNodeIsAnd(pAnd) ) { if ( Abc_ObjIsPi(pAnd) && fCompl ) return AreaInv; diff --git a/src/base/seq/seqMaxMeanCycle.c b/src/base/seq/seqMaxMeanCycle.c new file mode 100644 index 00000000..46d73cbd --- /dev/null +++ b/src/base/seq/seqMaxMeanCycle.c @@ -0,0 +1,567 @@ +/**CFile**************************************************************** + + FileName [seqMaxMeanCycle.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Construction and manipulation of sequential AIGs.] + + Synopsis [Efficient computation of maximum mean cycle times.] + + Author [Aaron P. Hurst] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 15, 2006.] + + Revision [$Id: seqMaxMeanCycle.c,v 1.00 2005/05/15 00:00:00 ahurst Exp $] + +***********************************************************************/ + +#include "seqInt.h" +#include "hash.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +struct Abc_ManTime_t_ +{ + Abc_Time_t tArrDef; + Abc_Time_t tReqDef; + Vec_Ptr_t * vArrs; + Vec_Ptr_t * vReqs; +}; + +typedef struct Seq_HowardData_t_ +{ + char visited; + int mark; + int policy; + float cycle; + float skew; + float delay; +} Seq_HowardData_t; + +// accessing the arrival and required times of a node +static inline Abc_Time_t * Abc_NodeArrival( Abc_Obj_t * pNode ) { return pNode->pNtk->pManTime->vArrs->pArray[pNode->Id]; } +static inline Abc_Time_t * Abc_NodeRequired( Abc_Obj_t * pNode ) { return pNode->pNtk->pManTime->vReqs->pArray[pNode->Id]; } + +Hash_Ptr_t * Seq_NtkPathDelays( Abc_Ntk_t * pNtk, int fVerbose ); +void Seq_NtkMergePios( Abc_Ntk_t * pNtk, Hash_Ptr_t * hFwdDelays, int fVerbose ); + +void Seq_NtkHowardLoop( Abc_Ntk_t * pNtk, Hash_Ptr_t * hFwdDelays, + Hash_Ptr_t * hNodeData, int node, + int *howardDepth, float *howardDelay, int *howardSink, + float *maxMeanCycle); +void Abc_NtkDfsReverse_rec2( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Vec_Ptr_t * vEndpoints ); + +#define Seq_NtkGetPathDelay( hFwdDelays, from, to ) \ + (Hash_PtrExists(hFwdDelays, from)?Hash_FltEntry( ((Hash_Flt_t *)Hash_PtrEntry(hFwdDelays, from, 0)), to, 0):0 ) + +#define HOWARD_EPSILON 1e-3 +#define ZERO_SLOP 1e-5 +#define REMOVE_ZERO_SLOP( x ) \ + (x = (x > -ZERO_SLOP && x < ZERO_SLOP)?0:x) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes maximum mean cycle time.] + + Description [Uses Howard's algorithm.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Seq_NtkHoward( Abc_Ntk_t * pNtk, int fVerbose ) { + + Abc_Obj_t * pObj; + Hash_Ptr_t * hFwdDelays; + Hash_Flt_t * hOutgoing; + Hash_Ptr_Entry_t * pSourceEntry, * pNodeEntry; + Hash_Flt_Entry_t * pSinkEntry; + int i, j, iteration = 0; + int source, sink; + int fChanged; + int howardDepth, howardSink = 0; + float delay, howardDelay, t; + float maxMeanCycle = -ABC_INFINITY; + Hash_Ptr_t * hNodeData; + Seq_HowardData_t * pNodeData, * pSourceData, * pSinkData; + + // gather timing constraints + hFwdDelays = Seq_NtkPathDelays( pNtk, fVerbose ); + Seq_NtkMergePios( pNtk, hFwdDelays, fVerbose ); + + // initialize data, create initial policy + hNodeData = Hash_PtrAlloc( hFwdDelays->nSize ); + Hash_PtrForEachEntry( hFwdDelays, pSourceEntry, i ) { + Hash_PtrWriteEntry( hNodeData, pSourceEntry->key, + (pNodeData = ALLOC(Seq_HowardData_t, 1)) ); + pNodeData->skew = 0.0; + pNodeData->policy = 0; + hOutgoing = (Hash_Flt_t *)(pSourceEntry->data); + assert(hOutgoing); + + Hash_FltForEachEntry( hOutgoing, pSinkEntry, j ) { + sink = pSinkEntry->key; + delay = pSinkEntry->data; + if (delay > pNodeData->skew) { + pNodeData->policy = sink; + pNodeData->skew = delay; + } + } + } + + // iteratively refine policy + do { + iteration++; + fChanged = 0; + howardDelay = 0.0; + howardDepth = 0; + + // reset data + Hash_PtrForEachEntry( hNodeData, pNodeEntry, i ) { + pNodeData = (Seq_HowardData_t *)pNodeEntry->data; + pNodeData->skew = -ABC_INFINITY; + pNodeData->cycle = -ABC_INFINITY; + pNodeData->mark = 0; + pNodeData->visited = 0; + } + + // find loops in policy graph + Hash_PtrForEachEntry( hNodeData, pNodeEntry, i ) { + pNodeData = (Seq_HowardData_t *)(pNodeEntry->data); + assert(pNodeData); + if (!pNodeData->visited) + Seq_NtkHowardLoop( pNtk, hFwdDelays, + hNodeData, pNodeEntry->key, + &howardDepth, &howardDelay, &howardSink, &maxMeanCycle); + } + + if (!howardSink) { + return -1; + } + + // improve policy by tightening loops + Hash_PtrForEachEntry( hFwdDelays, pSourceEntry, i ) { + source = pSourceEntry->key; + pSourceData = (Seq_HowardData_t *)Hash_PtrEntry( hNodeData, source, 0 ); + assert(pSourceData); + hOutgoing = (Hash_Flt_t *)(pSourceEntry->data); + assert(hOutgoing); + Hash_FltForEachEntry( hOutgoing, pSinkEntry, j ) { + sink = pSinkEntry->key; + pSinkData = (Seq_HowardData_t *)Hash_PtrEntry( hNodeData, sink, 0 ); + assert(pSinkData); + delay = pSinkEntry->data; + + if (pSinkData->cycle > pSourceData->cycle + HOWARD_EPSILON) { + fChanged = 1; + pSourceData->cycle = pSinkData->cycle; + pSourceData->policy = sink; + } + } + } + + // improve policy by correcting skews + if (!fChanged) { + Hash_PtrForEachEntry( hFwdDelays, pSourceEntry, i ) { + source = pSourceEntry->key; + pSourceData = (Seq_HowardData_t *)Hash_PtrEntry( hNodeData, source, 0 ); + assert(pSourceData); + hOutgoing = (Hash_Flt_t *)(pSourceEntry->data); + assert(hOutgoing); + Hash_FltForEachEntry( hOutgoing, pSinkEntry, j ) { + sink = pSinkEntry->key; + pSinkData = (Seq_HowardData_t *)Hash_PtrEntry( hNodeData, sink, 0 ); + assert(pSinkData); + delay = pSinkEntry->data; + + if (pSinkData->cycle < 0.0 || pSinkData->cycle < pSourceData->cycle) + continue; + + t = delay - pSinkData->cycle + pSinkData->skew; + if (t > pSourceData->skew + HOWARD_EPSILON) { + fChanged = 1; + pSourceData->skew = t; + pSourceData->policy = sink; + } + } + } + } + + if (fVerbose) printf("Iteration %d \t Period = %.2f\n", iteration, maxMeanCycle); + } while (fChanged); + + // set global skew, mmct + pNodeData = Hash_PtrEntry( hNodeData, -1, 0 ); + pNtk->globalSkew = -pNodeData->skew; + pNtk->maxMeanCycle = maxMeanCycle; + + // set endpoint skews + Vec_FltGrow( pNtk->vSkews, Abc_NtkLatchNum( pNtk ) ); + pNtk->vSkews->nSize = Abc_NtkLatchNum( pNtk ); + Abc_NtkForEachLatch( pNtk, pObj, i ) { + pNodeData = Hash_PtrEntry( hNodeData, pObj->Id, 0 ); + // skews are set based on latch # NOT id # + Abc_NtkSetLatSkew( pNtk, i, pNodeData->skew ); + } + + // free node data + Hash_PtrForEachEntry( hNodeData, pNodeEntry, i ) { + pNodeData = (Seq_HowardData_t *)(pNodeEntry->data); + FREE( pNodeData ); + } + Hash_PtrFree(hNodeData); + + // free delay data + Hash_PtrForEachEntry( hFwdDelays, pSourceEntry, i ) { + Hash_FltFree( (Hash_Flt_t *)(pSourceEntry->data) ); + } + Hash_PtrFree(hFwdDelays); + + return maxMeanCycle; +} + +/**Function************************************************************* + + Synopsis [Computes the mean cycle times of current policy graph.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_NtkHowardLoop( Abc_Ntk_t * pNtk, Hash_Ptr_t * hFwdDelays, + Hash_Ptr_t * hNodeData, int node, + int *howardDepth, float *howardDelay, int *howardSink, + float *maxMeanCycle) { + + Seq_HowardData_t * pNodeData, *pToData; + float delay, t; + + pNodeData = (Seq_HowardData_t *)Hash_PtrEntry( hNodeData, node, 0 ); + assert(pNodeData); + pNodeData->visited = 1; + pNodeData->mark = ++(*howardDepth); + pNodeData->delay = (*howardDelay); + if (pNodeData->policy) { + pToData = (Seq_HowardData_t *)Hash_PtrEntry( hNodeData, pNodeData->policy, 0 ); + assert(pToData); + delay = Seq_NtkGetPathDelay( hFwdDelays, node, pNodeData->policy ); + assert(delay > 0.0); + (*howardDelay) += delay; + if (pToData->mark) { + t = (*howardDelay - pToData->delay) / (*howardDepth - pToData->mark + 1); + pNodeData->cycle = t; + pNodeData->skew = 0.0; + if (*maxMeanCycle < t) { + *maxMeanCycle = t; + *howardSink = pNodeData->policy; + } + } else { + if(!pToData->visited) { + Seq_NtkHowardLoop(pNtk, hFwdDelays, hNodeData, pNodeData->policy, + howardDepth, howardDelay, howardSink, maxMeanCycle); + } + if(pToData->cycle > 0) { + t = delay - pToData->cycle + pToData->skew; + pNodeData->skew = t; + pNodeData->cycle = pToData->cycle; + } + } + } + *howardDelay = pNodeData->delay; + pNodeData->mark = 0; + --(*howardDepth); +} + +/**Function************************************************************* + + Synopsis [Computes the register-to-register delays.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Hash_Ptr_t * Seq_NtkPathDelays( Abc_Ntk_t * pNtk, int fVerbose ) { + + Abc_Time_t * pTime, ** ppTimes; + Abc_Obj_t * pObj, * pDriver, * pStart, * pFanout; + Vec_Ptr_t * vNodes, * vEndpoints; + int i, j, nPaths = 0; + Hash_Flt_t * hOutgoing; + Hash_Ptr_t * hFwdDelays; + float nMaxPath = 0, nSumPath = 0; + + extern void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk ); + extern void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode ); + + if (fVerbose) printf("Gathering path delays...\n"); + + hFwdDelays = Hash_PtrAlloc( Abc_NtkCiNum( pNtk ) ); + + assert( Abc_NtkIsMappedLogic(pNtk) ); + + Abc_NtkTimePrepare( pNtk ); + ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray; + vNodes = Vec_PtrAlloc( 100 ); + vEndpoints = Vec_PtrAlloc( 100 ); + + // set the initial times (i.e. ignore all inputs) + Abc_NtkForEachObj( pNtk, pObj, i) { + pTime = ppTimes[pObj->Id]; + pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY; + } + + // starting at each Ci, compute timing forward + Abc_NtkForEachCi( pNtk, pStart, j ) { + + hOutgoing = Hash_FltAlloc( 10 ); + Hash_PtrWriteEntry( hFwdDelays, pStart->Id, (void *)(hOutgoing) ); + + // seed the starting point of interest + pTime = ppTimes[pStart->Id]; + pTime->Fall = pTime->Rise = pTime->Worst = 0.0; + + // find a DFS ordering from the start + Abc_NtkIncrementTravId( pNtk ); + Abc_NodeSetTravIdCurrent( pStart ); + pObj = Abc_ObjFanout0Ntk(pStart); + Abc_ObjForEachFanout( pObj, pFanout, i ) + Abc_NtkDfsReverse_rec2( pFanout, vNodes, vEndpoints ); + if ( Abc_ObjIsCo( pStart ) ) + Vec_PtrPush( vEndpoints, pStart ); + + // do timing analysis + for ( i = vNodes->nSize-1; i >= 0; --i ) + Abc_NodeDelayTraceArrival( vNodes->pArray[i] ); + + // there is a path to each set of Co endpoints + Vec_PtrForEachEntry( vEndpoints, pObj, i ) + { + assert(pObj); + assert( Abc_ObjIsCo( pObj ) ); + pDriver = Abc_ObjFanin0(pObj); + pTime = Abc_NodeArrival(pDriver); + if ( pTime->Worst > 0 ) { + Hash_FltWriteEntry( hOutgoing, pObj->Id, pTime->Worst ); + nPaths++; + // if (fVerbose) printf("\tpath %d,%d delay = %f\n", pStart->Id, pObj->Id, pTime->Worst); + nSumPath += pTime->Worst; + if (pTime->Worst > nMaxPath) + nMaxPath = pTime->Worst; + } + } + + // clear the times that were altered + for ( i = 0; i < vNodes->nSize; i++ ) { + pObj = (Abc_Obj_t *)(vNodes->pArray[i]); + pTime = ppTimes[pObj->Id]; + pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY; + } + pTime = ppTimes[pStart->Id]; + pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY; + + Vec_PtrClear( vNodes ); + Vec_PtrClear( vEndpoints ); + } + + Vec_PtrFree( vNodes ); + + // rezero Cis (note: these should be restored to values if they were nonzero) + Abc_NtkForEachCi( pNtk, pObj, i) { + pTime = ppTimes[pObj->Id]; + pTime->Fall = pTime->Rise = pTime->Worst = 0.0; + } + + if (fVerbose) printf("Num. paths = %d\tMax. Path Delay = %.2f\tAvg. Path Delay = %.2f\n", nPaths, nMaxPath, nSumPath / nPaths); + return hFwdDelays; +} + + +/**Function************************************************************* + + Synopsis [Merges all the Pios together into one ID = -1.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_NtkMergePios( Abc_Ntk_t * pNtk, Hash_Ptr_t * hFwdDelays, + int fVerbose ) { + + Abc_Obj_t * pObj; + Hash_Flt_Entry_t * pSinkEntry; + Hash_Ptr_Entry_t * pSourceEntry; + Hash_Flt_t * hOutgoing, * hPioSource; + int i, j; + int source, sink, nMerges = 0; + float delay = 0, max_delay = 0; + Vec_Int_t * vFreeList; + + vFreeList = Vec_IntAlloc( 10 ); + + // create a new "-1" source entry for the Pios + hPioSource = Hash_FltAlloc( 100 ); + Hash_PtrWriteEntry( hFwdDelays, -1, (void *)(hPioSource) ); + + // merge all edges with a Pio as a source + Abc_NtkForEachPi( pNtk, pObj, i ) { + source = pObj->Id; + hOutgoing = (Hash_Flt_t *)Hash_PtrEntry( hFwdDelays, source, 0 ); + if (!hOutgoing) continue; + + Hash_PtrForEachEntry( hOutgoing, pSinkEntry, j ) { + nMerges++; + sink = pSinkEntry->key; + delay = pSinkEntry->data; + if (Hash_FltEntry( hPioSource, sink, 1 ) < delay) { + Hash_FltWriteEntry( hPioSource, sink, delay ); + } + } + + Hash_FltFree( hOutgoing ); + Hash_PtrRemove( hFwdDelays, source ); + } + + // merge all edges with a Pio as a sink + Hash_PtrForEachEntry( hFwdDelays, pSourceEntry, i ) { + hOutgoing = (Hash_Flt_t *)(pSourceEntry->data); + Hash_FltForEachEntry( hOutgoing, pSinkEntry, j ) { + sink = pSinkEntry->key; + delay = pSinkEntry->data; + + max_delay = -ABC_INFINITY; + if (Abc_ObjIsPo( Abc_NtkObj( pNtk, sink ) )) { + nMerges++; + if (delay > max_delay) + max_delay = delay; + Vec_IntPush( vFreeList, sink ); + } + } + if (max_delay != -ABC_INFINITY) + Hash_FltWriteEntry( hOutgoing, -1, delay ); + // do freeing + while( vFreeList->nSize > 0 ) { + Hash_FltRemove( hOutgoing, Vec_IntPop( vFreeList ) ); + } + } + + if (fVerbose) printf("Merged %d paths into one Pio node\n", nMerges); + +} + +/**Function************************************************************* + + Synopsis [This is a modification of routine from abcDfs.c] + + Description [Recursive DFS from a starting point. Keeps the endpoints.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkDfsReverse_rec2( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Vec_Ptr_t * vEndpoints ) +{ + Abc_Obj_t * pFanout; + int i; + assert( !Abc_ObjIsNet(pNode) ); + // if this node is already visited, skip + if ( Abc_NodeIsTravIdCurrent( pNode ) ) + return; + // mark the node as visited + Abc_NodeSetTravIdCurrent( pNode ); + // terminate at the Co + if ( Abc_ObjIsCo(pNode) ) { + Vec_PtrPush( vEndpoints, pNode ); + return; + } + assert( Abc_ObjIsNode( pNode ) ); + // visit the transitive fanin of the node + pNode = Abc_ObjFanout0Ntk(pNode); + Abc_ObjForEachFanout( pNode, pFanout, i ) + Abc_NtkDfsReverse_rec2( pFanout, vNodes, vEndpoints ); + // add the node after the fanins have been added + Vec_PtrPush( vNodes, pNode ); +} + +/**Function************************************************************* + + Synopsis [Converts all skews into forward skews 0<skew<T.] + + Description [Can also minimize total skew by changing global skew.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_NtkSkewForward( Abc_Ntk_t * pNtk, float period, int fMinimize ) { + + Abc_Obj_t * pObj; + int i; + float skew; + float currentSum = 0, bestSum = ABC_INFINITY; + float currentOffset = 0, nextStep, bestOffset = 0; + + assert( pNtk->vSkews->nSize >= Abc_NtkLatchNum( pNtk )-1 ); + + if (fMinimize) { + // search all offsets for the one that minimizes sum of skews + while(currentOffset < period) { + currentSum = 0; + nextStep = period; + Abc_NtkForEachLatch( pNtk, pObj, i ) { + skew = Abc_NtkGetLatSkew( pNtk, i ) + currentOffset; + skew = (float)(skew - period*floor(skew/period)); + currentSum += skew; + if (skew > ZERO_SLOP && skew < nextStep) { + nextStep = skew; + } + } + + if (currentSum < bestSum) { + bestSum = currentSum; + bestOffset = currentOffset; + } + currentOffset += nextStep; + } + printf("Offseting all skews by %.2f\n", bestOffset); + } + + // convert global skew into forward skew + pNtk->globalSkew = pNtk->globalSkew - bestOffset; + pNtk->globalSkew = (float)(pNtk->globalSkew - period*floor(pNtk->globalSkew/period)); + assert(pNtk->globalSkew>= 0 && pNtk->globalSkew < period); + + // convert endpoint skews into forward skews + Abc_NtkForEachLatch( pNtk, pObj, i ) { + skew = Abc_NtkGetLatSkew( pNtk, i ) + bestOffset; + skew = (float)(skew - period*floor(skew/period)); + REMOVE_ZERO_SLOP( skew ); + assert(skew >=0 && skew < period); + + Abc_NtkSetLatSkew( pNtk, i, skew ); + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/base/seq/seqRetCore.c b/src/base/seq/seqRetCore.c index ba66a881..080abcb2 100644 --- a/src/base/seq/seqRetCore.c +++ b/src/base/seq/seqRetCore.c @@ -110,7 +110,7 @@ Abc_Ntk_t * Seq_NtkRetimeDerive( Abc_Ntk_t * pNtk, int fVerbose ) { if ( !Abc_NtkBddToSop(pNtk, 0) ) { - printf( "Converting to SOPs has failed.\n" ); + printf( "Seq_NtkRetimeDerive(): Converting to SOPs has failed.\n" ); return NULL; } } @@ -140,7 +140,7 @@ Abc_Ntk_t * Seq_NtkRetimeDerive( Abc_Ntk_t * pNtk, int fVerbose ) { if ( pObj->Id == 0 ) { - pObj->pCopy = Abc_NtkConst1(pNtkNew); + pObj->pCopy = Abc_AigConst1(pNtkNew); continue; } pObj->pCopy = Abc_NtkCreateNode( pNtkNew ); @@ -275,9 +275,9 @@ Abc_Obj_t * Seq_NodeRetimeDerive( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pRoot, char * if ( nFanins < 2 ) { if ( Abc_SopIsConst1(pSop) ) - pFanin = Abc_NtkConst1(pNtkNew); + pFanin = Abc_AigConst1(pNtkNew); else if ( Abc_SopIsConst0(pSop) ) - pFanin = Abc_ObjNot( Abc_NtkConst1(pNtkNew) ); + pFanin = Abc_ObjNot( Abc_AigConst1(pNtkNew) ); else if ( Abc_SopIsBuf(pSop) ) pFanin = Abc_ObjFanin0(pRoot)->pCopy; else if ( Abc_SopIsInv(pSop) ) @@ -342,8 +342,8 @@ Abc_Ntk_t * Seq_NtkRetimeReconstruct( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkSeq ) pNtkNew = Abc_NtkStartFrom( pNtkSeq, pNtkOld->ntkType, pNtkOld->ntkFunc ); // transfer the pointers to the old network - if ( Abc_NtkConst1(pNtkOld) ) - Abc_NtkConst1(pNtkOld)->pCopy = Abc_NtkConst1(pNtkNew); + if ( Abc_AigConst1(pNtkOld) ) + Abc_AigConst1(pNtkOld)->pCopy = Abc_AigConst1(pNtkNew); Abc_NtkForEachPi( pNtkOld, pObj, i ) pObj->pCopy = pObj->pNext->pCopy; Abc_NtkForEachPo( pNtkOld, pObj, i ) @@ -433,7 +433,7 @@ Abc_Obj_t * Seq_EdgeReconstruct_rec( Abc_Obj_t * pGoal, Abc_Obj_t * pNode ) Seq_Lat_t * pRing; Abc_Obj_t * pFanin, * pRes = NULL; - if ( !Abc_NodeIsAigAnd(pNode) ) + if ( !Abc_AigNodeIsAnd(pNode) ) return NULL; // consider the first fanin diff --git a/src/base/seq/seqRetIter.c b/src/base/seq/seqRetIter.c index 512a521e..99c50914 100644 --- a/src/base/seq/seqRetIter.c +++ b/src/base/seq/seqRetIter.c @@ -316,7 +316,7 @@ int Seq_NtkNodeUpdateLValue( Abc_Obj_t * pObj, float Fi, Vec_Ptr_t * vLeaves, Ve void Seq_NodeRetimeSetLag_rec( Abc_Obj_t * pNode, char Lag ) { Abc_Obj_t * pFanin; - if ( !Abc_NodeIsAigAnd(pNode) ) + if ( !Abc_AigNodeIsAnd(pNode) ) return; Seq_NodeSetLag( pNode, Lag ); // consider the first fanin diff --git a/src/base/seq/seqShare.c b/src/base/seq/seqShare.c index fd2e8189..742de46b 100644 --- a/src/base/seq/seqShare.c +++ b/src/base/seq/seqShare.c @@ -319,7 +319,7 @@ void Seq_NtkShareLatchesMapping( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, Vec_Ptr_ // create the array of all nodes with sharable fanouts vNodes = Vec_PtrAlloc( 100 ); - Vec_PtrPush( vNodes, Abc_NtkConst1(pNtk) ); + Vec_PtrPush( vNodes, Abc_AigConst1(pNtk) ); Abc_NtkForEachPi( pNtk, pObj, i ) Vec_PtrPush( vNodes, pObj ); if ( fFpga ) diff --git a/src/base/seq/seqUtil.c b/src/base/seq/seqUtil.c index 39fde28e..af2a0a7a 100644 --- a/src/base/seq/seqUtil.c +++ b/src/base/seq/seqUtil.c @@ -476,7 +476,7 @@ int Seq_MapComputeAreaFlows( Abc_Ntk_t * pNtk, int fVerbose ) void Seq_NtkReachNodesFromPos_rec( Abc_Obj_t * pAnd, Vec_Ptr_t * vNodes ) { // skip if this is a non-PI node - if ( !Abc_NodeIsAigAnd(pAnd) ) + if ( !Abc_AigNodeIsAnd(pAnd) ) return; // skip a visited node if ( Abc_NodeIsTravIdCurrent(pAnd) ) @@ -505,7 +505,7 @@ void Seq_NtkReachNodesFromPis_rec( Abc_Obj_t * pAnd, Vec_Ptr_t * vNodes ) Abc_Obj_t * pFanout; int k; // skip if this is a non-PI node - if ( !Abc_NodeIsAigAnd(pAnd) ) + if ( !Abc_AigNodeIsAnd(pAnd) ) return; // skip a visited node if ( Abc_NodeIsTravIdCurrent(pAnd) ) @@ -546,7 +546,7 @@ Vec_Ptr_t * Seq_NtkReachNodes( Abc_Ntk_t * pNtk, int fFromPos ) else { // tranvers the reverse cone of the constant node - pObj = Abc_NtkConst1( pNtk ); + pObj = Abc_AigConst1( pNtk ); Abc_ObjForEachFanout( pObj, pFanout, k ) Seq_NtkReachNodesFromPis_rec( pFanout, vNodes ); // tranvers the reverse cone of the PIs diff --git a/src/map/pga/pgaMatch.c b/src/map/pga/pgaMatch.c index 086a85d4..186fbf64 100644 --- a/src/map/pga/pgaMatch.c +++ b/src/map/pga/pgaMatch.c @@ -69,8 +69,8 @@ void Pga_MappingMatches( Pga_Man_t * p, int Mode ) continue; } // skip constant node, it has no cuts - if ( Abc_NodeIsConst(pObj) ) - continue; +// if ( Abc_NodeIsConst(pObj) ) +// continue; // get the cuts clk = clock(); pList = Abc_NodeGetCutsRecursive( p->pManCut, pObj, 0, 0 ); diff --git a/src/misc/extra/extra.h b/src/misc/extra/extra.h index 8b20daae..8f08eaff 100644 --- a/src/misc/extra/extra.h +++ b/src/misc/extra/extra.h @@ -166,6 +166,9 @@ extern DdNode * Extra_bddComputeRangeCube( DdManager * dd, int iStart, int i extern DdNode * Extra_bddBitsToCube( DdManager * dd, int Code, int CodeWidth, DdNode ** pbVars, int fMsbFirst ); extern DdNode * Extra_bddSupportNegativeCube( DdManager * dd, DdNode * f ); extern int Extra_bddIsVar( DdNode * bFunc ); +extern DdNode * Extra_bddCreateAnd( DdManager * dd, int nVars ); +extern DdNode * Extra_bddCreateOr( DdManager * dd, int nVars ); +extern DdNode * Extra_bddCreateExor( DdManager * dd, int nVars ); /*=== extraBddKmap.c ================================================================*/ @@ -525,6 +528,18 @@ extern unsigned Extra_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, i /*=== extraUtilUtil.c ================================================================*/ +#ifndef ABS +#define ABS(a) ((a) < 0 ? -(a) : (a)) +#endif + +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + #ifndef ALLOC #define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num))) #endif diff --git a/src/misc/extra/extraBddMisc.c b/src/misc/extra/extraBddMisc.c index 00e2ac94..1c720061 100644 --- a/src/misc/extra/extraBddMisc.c +++ b/src/misc/extra/extraBddMisc.c @@ -802,9 +802,9 @@ DdNode * Extra_bddSupportNegativeCube( DdManager * dd, DdNode * f ) Description [] - SideEffects [None] + SideEffects [] - SeeAlso [Cudd_VectorSupport Cudd_Support] + SeeAlso [] ******************************************************************************/ int Extra_bddIsVar( DdNode * bFunc ) @@ -815,6 +815,82 @@ int Extra_bddIsVar( DdNode * bFunc ) return cuddIsConstant( cuddT(bFunc) ) && cuddIsConstant( Cudd_Regular(cuddE(bFunc)) ); } +/**Function******************************************************************** + + Synopsis [Creates AND composed of the first nVars of the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +DdNode * Extra_bddCreateAnd( DdManager * dd, int nVars ) +{ + DdNode * bFunc, * bTemp; + int i; + bFunc = Cudd_ReadOne(dd); Cudd_Ref( bFunc ); + for ( i = 0; i < nVars; i++ ) + { + bFunc = Cudd_bddAnd( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc ); + Cudd_RecursiveDeref( dd, bTemp ); + } + Cudd_Deref( bFunc ); + return bFunc; +} + +/**Function******************************************************************** + + Synopsis [Creates OR composed of the first nVars of the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +DdNode * Extra_bddCreateOr( DdManager * dd, int nVars ) +{ + DdNode * bFunc, * bTemp; + int i; + bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc ); + for ( i = 0; i < nVars; i++ ) + { + bFunc = Cudd_bddOr( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc ); + Cudd_RecursiveDeref( dd, bTemp ); + } + Cudd_Deref( bFunc ); + return bFunc; +} + +/**Function******************************************************************** + + Synopsis [Creates EXOR composed of the first nVars of the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +DdNode * Extra_bddCreateExor( DdManager * dd, int nVars ) +{ + DdNode * bFunc, * bTemp; + int i; + bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc ); + for ( i = 0; i < nVars; i++ ) + { + bFunc = Cudd_bddXor( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc ); + Cudd_RecursiveDeref( dd, bTemp ); + } + Cudd_Deref( bFunc ); + return bFunc; +} + + /*---------------------------------------------------------------------------*/ /* Definition of internal functions */ /*---------------------------------------------------------------------------*/ diff --git a/src/misc/hash/hash.h b/src/misc/hash/hash.h new file mode 100644 index 00000000..90e72868 --- /dev/null +++ b/src/misc/hash/hash.h @@ -0,0 +1,65 @@ +/**CFile**************************************************************** + + FileName [hash.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hash map.] + + Synopsis [External declarations.] + + Author [Aaron P. Hurst] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 16, 2005.] + + Revision [$Id: vec.h,v 1.00 2005/06/20 00:00:00 ahurst Exp $] + +***********************************************************************/ + +#ifndef __HASH_H__ +#define __HASH_H__ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#ifdef _WIN32 +#define inline __inline // compatible with MS VS 6.0 +#endif + +#include "hashInt.h" +#include "hashFlt.h" +#include "hashPtr.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +#ifndef ABS +#define ABS(a) ((a) < 0 ? -(a) : (a)) +#endif + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +int Hash_DefaultHashFunc(int key, int nBins) { + return ABS( ( (key+11)*(key)*7+3 ) % nBins ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/src/misc/hash/hashFlt.h b/src/misc/hash/hashFlt.h new file mode 100644 index 00000000..da20ee28 --- /dev/null +++ b/src/misc/hash/hashFlt.h @@ -0,0 +1,330 @@ +/**CFile**************************************************************** + + FileName [hashFlt.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hash maps.] + + Synopsis [Hash maps.] + + Author [Aaron P. Hurst] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 16, 2006.] + + Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 ahurst Exp $] + +***********************************************************************/ + +#ifndef __HASH_FLT_H__ +#define __HASH_FLT_H__ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include <stdio.h> +#include "extra.h" + +extern int Hash_DefaultHashFunc(int key, int nBins); + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Hash_Flt_t_ Hash_Flt_t; +typedef struct Hash_Flt_Entry_t_ Hash_Flt_Entry_t; + +struct Hash_Flt_Entry_t_ +{ + int key; + float data; + struct Hash_Flt_Entry_t_ * pNext; +}; + +struct Hash_Flt_t_ +{ + int nSize; + int nBins; + int (* fHash)(int key, int nBins); + Hash_Flt_Entry_t ** pArray; +}; + + + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +#define Hash_FltForEachEntry( pHash, pEntry, bin) \ + for(bin=-1, pEntry=NULL; bin < pHash->nBins; (!pEntry)?(pEntry=pHash->pArray[++bin]):(pEntry=pEntry->pNext)) \ + if (pEntry) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Allocates a hash map with the given number of bins.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Hash_Flt_t * Hash_FltAlloc( int nBins ) +{ + Hash_Flt_t * p; + int i; + assert(nBins > 0); + p = ALLOC( Hash_Flt_t, 1); + p->nBins = nBins; + p->fHash = Hash_DefaultHashFunc; + p->nSize = 0; + p->pArray = ALLOC( Hash_Flt_Entry_t *, nBins ); + for(i=0; i<nBins; i++) + p->pArray[i] = NULL; + + return p; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if a key already exists.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Hash_FltExists( Hash_Flt_t *p, int key ) +{ + int bin; + Hash_Flt_Entry_t *pEntry, **pLast; + + // find the bin where this key would live + bin = (*(p->fHash))(key, p->nBins); + + // search for key + pLast = &(p->pArray[bin]); + pEntry = p->pArray[bin]; + while(pEntry) { + if (pEntry->key == key) { + return 1; + } + pLast = &(pEntry->pNext); + pEntry = pEntry->pNext; + } + + return 0; +} + +/**Function************************************************************* + + Synopsis [Finds or creates an entry with a key and writes value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Hash_FltWriteEntry( Hash_Flt_t *p, int key, float data ) +{ + int bin; + Hash_Flt_Entry_t *pEntry, **pLast; + + // find the bin where this key would live + bin = (*(p->fHash))(key, p->nBins); + + // search for key + pLast = &(p->pArray[bin]); + pEntry = p->pArray[bin]; + while(pEntry) { + if (pEntry->key == key) { + pEntry->data = data; + return; + } + pLast = &(pEntry->pNext); + pEntry = pEntry->pNext; + } + + // this key does not currently exist + // create a new entry and add to bin + p->nSize++; + (*pLast) = pEntry = ALLOC( Hash_Flt_Entry_t, 1 ); + pEntry->pNext = NULL; + pEntry->key = key; + pEntry->data = data; + + return; +} + + +/**Function************************************************************* + + Synopsis [Finds or creates an entry with a key.] + + Description [fCreate specifies whether new entries should be created.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline float Hash_FltEntry( Hash_Flt_t *p, int key, int fCreate ) +{ + int bin; + Hash_Flt_Entry_t *pEntry, **pLast; + + // find the bin where this key would live + bin = (*(p->fHash))(key, p->nBins); + + // search for key + pLast = &(p->pArray[bin]); + pEntry = p->pArray[bin]; + while(pEntry) { + if (pEntry->key == key) + return pEntry->data; + pLast = &(pEntry->pNext); + pEntry = pEntry->pNext; + } + + // this key does not currently exist + if (fCreate) { + // create a new entry and add to bin + p->nSize++; + (*pLast) = pEntry = ALLOC( Hash_Flt_Entry_t, 1 ); + pEntry->pNext = NULL; + pEntry->key = key; + pEntry->data = 0.0; + return pEntry->data; + } + + return 0.0; +} + + +/**Function************************************************************* + + Synopsis [Finds or creates an entry with a key and returns the pointer to it.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline float* Hash_FltEntryPtr( Hash_Flt_t *p, int key ) +{ + int bin; + Hash_Flt_Entry_t *pEntry, **pLast; + + // find the bin where this key would live + bin = (*(p->fHash))(key, p->nBins); + + // search for key + pLast = &(p->pArray[bin]); + pEntry = p->pArray[bin]; + while(pEntry) { + if (pEntry->key == key) + return &(pEntry->data); + pLast = &(pEntry->pNext); + pEntry = pEntry->pNext; + } + + // this key does not currently exist + // create a new entry and add to bin + p->nSize++; + (*pLast) = pEntry = ALLOC( Hash_Flt_Entry_t, 1 ); + pEntry->pNext = NULL; + pEntry->key = key; + pEntry->data = 0.0; + + return &(pEntry->data); +} + +/**Function************************************************************* + + Synopsis [Deletes an entry.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Hash_FltRemove( Hash_Flt_t *p, int key ) +{ + int bin; + Hash_Flt_Entry_t *pEntry, **pLast; + + // find the bin where this key would live + bin = (*(p->fHash))(key, p->nBins); + + // search for key + pLast = &(p->pArray[bin]); + pEntry = p->pArray[bin]; + while(pEntry) { + if (pEntry->key == key) { + p->nSize--; + *pLast = pEntry->pNext; + FREE( pEntry ); + return; + } + pLast = &(pEntry->pNext); + pEntry = pEntry->pNext; + } + + // could not find key + return; +} + +/**Function************************************************************* + + Synopsis [Frees the hash.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Hash_FltFree( Hash_Flt_t *p ) { + int bin; + Hash_Flt_Entry_t *pEntry; + + // free bins + for(bin = 0; bin < p->nBins; bin++) { + pEntry = p->pArray[bin]; + while(pEntry) { + pEntry = pEntry->pNext; + FREE( pEntry ); + } + } + + // free hash + FREE( p->pArray ); + FREE( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + +#endif diff --git a/src/misc/hash/hashInt.h b/src/misc/hash/hashInt.h new file mode 100644 index 00000000..3b91f5df --- /dev/null +++ b/src/misc/hash/hashInt.h @@ -0,0 +1,293 @@ +/**CFile**************************************************************** + + FileName [hashInt.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hash maps.] + + Synopsis [Hash maps.] + + Author [Aaron P. Hurst] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 16, 2006.] + + Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 ahurst Exp $] + +***********************************************************************/ + +#ifndef __HASH_INT_H__ +#define __HASH_INT_H__ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include <stdio.h> +#include "extra.h" + +extern int Hash_DefaultHashFunc(int key, int nBins); + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Hash_Int_t_ Hash_Int_t; +typedef struct Hash_Int_Entry_t_ Hash_Int_Entry_t; + +struct Hash_Int_Entry_t_ +{ + int key; + int data; + struct Hash_Int_Entry_t_ * pNext; +}; + +struct Hash_Int_t_ +{ + int nSize; + int nBins; + int (* fHash)(int key, int nBins); + Hash_Int_Entry_t ** pArray; +}; + + + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +#define Hash_IntForEachEntry( pHash, pEntry, bin) \ + for(bin=-1, pEntry=NULL; bin < pHash->nBins; (!pEntry)?(pEntry=pHash->pArray[++bin]):(pEntry=pEntry->pNext)) \ + if (pEntry) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Allocates a hash map with the given number of bins.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Hash_Int_t * Hash_IntAlloc( int nBins ) +{ + Hash_Int_t * p; + int i; + assert(nBins > 0); + p = ALLOC( Hash_Int_t, 1); + p->nBins = nBins; + p->fHash = Hash_DefaultHashFunc; + p->nSize = 0; + p->pArray = ALLOC( Hash_Int_Entry_t *, nBins ); + for(i=0; i<nBins; i++) + p->pArray[i] = NULL; + + return p; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if a key already exists.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Hash_IntExists( Hash_Int_t *p, int key) +{ + int bin; + Hash_Int_Entry_t *pEntry, **pLast; + + // find the bin where this key would live + bin = (*(p->fHash))(key, p->nBins); + + // search for key + pLast = &(p->pArray[bin]); + pEntry = p->pArray[bin]; + while(pEntry) { + if (pEntry->key == key) { + return 1; + } + pLast = &(pEntry->pNext); + pEntry = pEntry->pNext; + } + + return 0; +} + +/**Function************************************************************* + + Synopsis [Finds or creates an entry with a key and writes value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Hash_IntWriteEntry( Hash_Int_t *p, int key, int data ) +{ + int bin; + Hash_Int_Entry_t *pEntry, **pLast; + + // find the bin where this key would live + bin = (*(p->fHash))(key, p->nBins); + + // search for key + pLast = &(p->pArray[bin]); + pEntry = p->pArray[bin]; + while(pEntry) { + if (pEntry->key == key) { + pEntry->data = data; + return; + } + pLast = &(pEntry->pNext); + pEntry = pEntry->pNext; + } + + // this key does not currently exist + // create a new entry and add to bin + p->nSize++; + (*pLast) = pEntry = ALLOC( Hash_Int_Entry_t, 1 ); + pEntry->pNext = NULL; + pEntry->key = key; + pEntry->data = data; + + return; +} + + +/**Function************************************************************* + + Synopsis [Finds or creates an entry with a key.] + + Description [fCreate specifies whether new entries will be created.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Hash_IntEntry( Hash_Int_t *p, int key, int fCreate ) +{ + int bin; + Hash_Int_Entry_t *pEntry, **pLast; + + // find the bin where this key would live + bin = (*(p->fHash))(key, p->nBins); + + // search for key + pLast = &(p->pArray[bin]); + pEntry = p->pArray[bin]; + while(pEntry) { + if (pEntry->key == key) + return pEntry->data; + pLast = &(pEntry->pNext); + pEntry = pEntry->pNext; + } + + // this key does not currently exist + if (fCreate) { + // create a new entry and add to bin + p->nSize++; + (*pLast) = pEntry = ALLOC( Hash_Int_Entry_t, 1 ); + pEntry->pNext = NULL; + pEntry->key = key; + pEntry->data = 0; + return pEntry->data; + } + + return 0; +} + + +/**Function************************************************************* + + Synopsis [Finds or creates an entry with a key and returns the pointer to it.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int* Hash_IntEntryPtr( Hash_Int_t *p, int key ) +{ + int bin; + Hash_Int_Entry_t *pEntry, **pLast; + + // find the bin where this key would live + bin = (*(p->fHash))(key, p->nBins); + + // search for key + pLast = &(p->pArray[bin]); + pEntry = p->pArray[bin]; + while(pEntry) { + if (pEntry->key == key) + return &(pEntry->data); + pLast = &(pEntry->pNext); + pEntry = pEntry->pNext; + } + + // this key does not currently exist + // create a new entry and add to bin + p->nSize++; + (*pLast) = pEntry = ALLOC( Hash_Int_Entry_t, 1 ); + pEntry->pNext = NULL; + pEntry->key = key; + pEntry->data = 0; + + return &(pEntry->data); +} + +/**Function************************************************************* + + Synopsis [Frees the hash.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Hash_IntFree( Hash_Int_t *p ) { + int bin; + Hash_Int_Entry_t *pEntry; + + // free bins + for(bin = 0; bin < p->nBins; bin++) { + pEntry = p->pArray[bin]; + while(pEntry) { + pEntry = pEntry->pNext; + FREE( pEntry ); + } + } + + // free hash + FREE( p->pArray ); + FREE( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + +#endif diff --git a/src/misc/hash/hashPtr.h b/src/misc/hash/hashPtr.h new file mode 100644 index 00000000..15398a8a --- /dev/null +++ b/src/misc/hash/hashPtr.h @@ -0,0 +1,331 @@ +/**CFile**************************************************************** + + FileName [hashFlt.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hash maps.] + + Synopsis [Hash maps.] + + Author [Aaron P. Hurst] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 16, 2006.] + + Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 ahurst Exp $] + +***********************************************************************/ + +#ifndef __HASH_PTR_H__ +#define __HASH_PTR_H__ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include <stdio.h> +#include "extra.h" + +extern int Hash_DefaultHashFunc(int key, int nBins); + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Hash_Ptr_t_ Hash_Ptr_t; +typedef struct Hash_Ptr_Entry_t_ Hash_Ptr_Entry_t; + +struct Hash_Ptr_Entry_t_ +{ + int key; + void * data; + struct Hash_Ptr_Entry_t_ * pNext; +}; + +struct Hash_Ptr_t_ +{ + int nSize; + int nBins; + int (* fHash)(int key, int nBins); + Hash_Ptr_Entry_t ** pArray; +}; + + + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +#define Hash_PtrForEachEntry( pHash, pEntry, bin ) \ + for(bin=-1, pEntry=NULL; bin < pHash->nBins; (!pEntry)?(pEntry=pHash->pArray[++bin]):(pEntry=pEntry->pNext)) \ + if (pEntry) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Allocates a hash map with the given number of bins.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Hash_Ptr_t * Hash_PtrAlloc( int nBins ) +{ + Hash_Ptr_t * p; + int i; + assert(nBins > 0); + p = ALLOC( Hash_Ptr_t, 1); + p->nBins = nBins; + p->fHash = Hash_DefaultHashFunc; + p->nSize = 0; + p->pArray = ALLOC( Hash_Ptr_Entry_t *, nBins ); + for(i=0; i<nBins; i++) + p->pArray[i] = NULL; + + return p; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if a key already exists.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Hash_PtrExists( Hash_Ptr_t *p, int key ) +{ + int bin; + Hash_Ptr_Entry_t *pEntry, **pLast; + + // find the bin where this key would live + bin = (*(p->fHash))(key, p->nBins); + + // search for key + pLast = &(p->pArray[bin]); + pEntry = p->pArray[bin]; + while(pEntry) { + if (pEntry->key == key) { + return 1; + } + pLast = &(pEntry->pNext); + pEntry = pEntry->pNext; + } + + return 0; +} + +/**Function************************************************************* + + Synopsis [Finds or creates an entry with a key and writes value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Hash_PtrWriteEntry( Hash_Ptr_t *p, int key, void * data ) +{ + int bin; + Hash_Ptr_Entry_t *pEntry, **pLast; + + // find the bin where this key would live + bin = (*(p->fHash))(key, p->nBins); + + // search for key + pLast = &(p->pArray[bin]); + pEntry = p->pArray[bin]; + while(pEntry) { + if (pEntry->key == key) { + pEntry->data = data; + return; + } + pLast = &(pEntry->pNext); + pEntry = pEntry->pNext; + } + + // this key does not currently exist + // create a new entry and add to bin + p->nSize++; + (*pLast) = pEntry = ALLOC( Hash_Ptr_Entry_t, 1 ); + pEntry->pNext = NULL; + pEntry->key = key; + pEntry->data = data; + + return; +} + + +/**Function************************************************************* + + Synopsis [Finds or creates an entry with a key.] + + Description [fCreate specifies whether a new entry should be created.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void * Hash_PtrEntry( Hash_Ptr_t *p, int key, int fCreate ) +{ + int bin; + Hash_Ptr_Entry_t *pEntry, **pLast; + + // find the bin where this key would live + bin = (*(p->fHash))(key, p->nBins); + + // search for key + pLast = &(p->pArray[bin]); + pEntry = p->pArray[bin]; + while(pEntry) { + if (pEntry->key == key) + return pEntry->data; + pLast = &(pEntry->pNext); + pEntry = pEntry->pNext; + } + + // this key does not currently exist + if (fCreate) { + // create a new entry and add to bin + p->nSize++; + (*pLast) = pEntry = ALLOC( Hash_Ptr_Entry_t, 1 ); + pEntry->pNext = NULL; + pEntry->key = key; + pEntry->data = NULL; + return pEntry->data; + } + + return NULL; +} + + +/**Function************************************************************* + + Synopsis [Finds or creates an entry with a key and returns the pointer to it.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void** Hash_PtrEntryPtr( Hash_Ptr_t *p, int key ) +{ + int bin; + Hash_Ptr_Entry_t *pEntry, **pLast; + + // find the bin where this key would live + bin = (*(p->fHash))(key, p->nBins); + + // search for key + pLast = &(p->pArray[bin]); + pEntry = p->pArray[bin]; + while(pEntry) { + if (pEntry->key == key) + return &(pEntry->data); + pLast = &(pEntry->pNext); + pEntry = pEntry->pNext; + } + + // this key does not currently exist + // create a new entry and add to bin + p->nSize++; + (*pLast) = pEntry = ALLOC( Hash_Ptr_Entry_t, 1 ); + pEntry->pNext = NULL; + pEntry->key = key; + pEntry->data = NULL; + + return &(pEntry->data); +} + +/**Function************************************************************* + + Synopsis [Deletes an entry.] + + Description [Returns data, if there was any.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void* Hash_PtrRemove( Hash_Ptr_t *p, int key ) +{ + int bin; + void * data; + Hash_Ptr_Entry_t *pEntry, **pLast; + + // find the bin where this key would live + bin = (*(p->fHash))(key, p->nBins); + + // search for key + pLast = &(p->pArray[bin]); + pEntry = p->pArray[bin]; + while(pEntry) { + if (pEntry->key == key) { + p->nSize--; + data = pEntry->data; + *pLast = pEntry->pNext; + return data; + } + pLast = &(pEntry->pNext); + pEntry = pEntry->pNext; + } + + // could not find key + return NULL; +} + +/**Function************************************************************* + + Synopsis [Frees the hash.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Hash_PtrFree( Hash_Ptr_t *p ) { + int bin; + Hash_Ptr_Entry_t *pEntry; + + // free bins + for(bin = 0; bin < p->nBins; bin++) { + pEntry = p->pArray[bin]; + while(pEntry) { + pEntry = pEntry->pNext; + FREE( pEntry ); + } + } + + // free hash + FREE( p->pArray ); + FREE( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + +#endif diff --git a/src/misc/hash/module.make b/src/misc/hash/module.make new file mode 100644 index 00000000..d6d908e7 --- /dev/null +++ b/src/misc/hash/module.make @@ -0,0 +1 @@ +SRC += diff --git a/src/misc/vec/vec.h b/src/misc/vec/vec.h index 6ab23298..a3943f2d 100644 --- a/src/misc/vec/vec.h +++ b/src/misc/vec/vec.h @@ -34,6 +34,7 @@ extern "C" { #endif #include "vecInt.h" +#include "vecFlt.h" #include "vecStr.h" #include "vecPtr.h" #include "vecVec.h" diff --git a/src/misc/vec/vecFlt.h b/src/misc/vec/vecFlt.h new file mode 100644 index 00000000..93f59af9 --- /dev/null +++ b/src/misc/vec/vecFlt.h @@ -0,0 +1,666 @@ +/**CFile**************************************************************** + + FileName [vecFlt.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Resizable arrays.] + + Synopsis [Resizable arrays of floats.] + + Author [Aaron P. Hurst] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __VEC_FLT_H__ +#define __VEC_FLT_H__ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include <stdio.h> +#include "extra.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Vec_Flt_t_ Vec_Flt_t; +struct Vec_Flt_t_ +{ + int nCap; + int nSize; + float * pArray; +}; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +#define Vec_FltForEachEntry( vVec, Entry, i ) \ + for ( i = 0; (i < Vec_FltSize(vVec)) && (((Entry) = Vec_FltEntry(vVec, i)), 1); i++ ) +#define Vec_FltForEachEntryStart( vVec, Entry, i, Start ) \ + for ( i = Start; (i < Vec_FltSize(vVec)) && (((Entry) = Vec_FltEntry(vVec, i)), 1); i++ ) +#define Vec_FltForEachEntryStartStop( vVec, Entry, i, Start, Stop ) \ + for ( i = Start; (i < Stop) && (((Entry) = Vec_FltEntry(vVec, i)), 1); i++ ) +#define Vec_FltForEachEntryReverse( vVec, pEntry, i ) \ + for ( i = Vec_FltSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_FltEntry(vVec, i)), 1); i-- ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Allocates a vector with the given capacity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Flt_t * Vec_FltAlloc( int nCap ) +{ + Vec_Flt_t * p; + p = ALLOC( Vec_Flt_t, 1 ); + if ( nCap > 0 && nCap < 16 ) + nCap = 16; + p->nSize = 0; + p->nCap = nCap; + p->pArray = p->nCap? ALLOC( float, p->nCap ) : NULL; + return p; +} + +/**Function************************************************************* + + Synopsis [Allocates a vector with the given size and cleans it.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Flt_t * Vec_FltStart( int nSize ) +{ + Vec_Flt_t * p; + p = Vec_FltAlloc( nSize ); + p->nSize = nSize; + memset( p->pArray, 0, sizeof(float) * nSize ); + return p; +} + +/**Function************************************************************* + + Synopsis [Creates the vector from a float array of the given size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Flt_t * Vec_FltAllocArray( float * pArray, int nSize ) +{ + Vec_Flt_t * p; + p = ALLOC( Vec_Flt_t, 1 ); + p->nSize = nSize; + p->nCap = nSize; + p->pArray = pArray; + return p; +} + +/**Function************************************************************* + + Synopsis [Creates the vector from a float array of the given size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Flt_t * Vec_FltAllocArrayCopy( float * pArray, int nSize ) +{ + Vec_Flt_t * p; + p = ALLOC( Vec_Flt_t, 1 ); + p->nSize = nSize; + p->nCap = nSize; + p->pArray = ALLOC( float, nSize ); + memcpy( p->pArray, pArray, sizeof(float) * nSize ); + return p; +} + +/**Function************************************************************* + + Synopsis [Duplicates the float array.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Flt_t * Vec_FltDup( Vec_Flt_t * pVec ) +{ + Vec_Flt_t * p; + p = ALLOC( Vec_Flt_t, 1 ); + p->nSize = pVec->nSize; + p->nCap = pVec->nCap; + p->pArray = p->nCap? ALLOC( float, p->nCap ) : NULL; + memcpy( p->pArray, pVec->pArray, sizeof(float) * pVec->nSize ); + return p; +} + +/**Function************************************************************* + + Synopsis [Transfers the array into another vector.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Vec_Flt_t * Vec_FltDupArray( Vec_Flt_t * pVec ) +{ + Vec_Flt_t * p; + p = ALLOC( Vec_Flt_t, 1 ); + p->nSize = pVec->nSize; + p->nCap = pVec->nCap; + p->pArray = pVec->pArray; + pVec->nSize = 0; + pVec->nCap = 0; + pVec->pArray = NULL; + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_FltFree( Vec_Flt_t * p ) +{ + FREE( p->pArray ); + FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline float * Vec_FltReleaseArray( Vec_Flt_t * p ) +{ + float * pArray = p->pArray; + p->nCap = 0; + p->nSize = 0; + p->pArray = NULL; + return pArray; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline float * Vec_FltArray( Vec_Flt_t * p ) +{ + return p->pArray; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_FltSize( Vec_Flt_t * p ) +{ + return p->nSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline float Vec_FltEntry( Vec_Flt_t * p, int i ) +{ + assert( i >= 0 && i < p->nSize ); + return p->pArray[i]; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_FltWriteEntry( Vec_Flt_t * p, int i, float Entry ) +{ + assert( i >= 0 && i < p->nSize ); + p->pArray[i] = Entry; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_FltAddToEntry( Vec_Flt_t * p, int i, float Addition ) +{ + assert( i >= 0 && i < p->nSize ); + p->pArray[i] += Addition; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline float Vec_FltEntryLast( Vec_Flt_t * p ) +{ + return p->pArray[p->nSize-1]; +} + +/**Function************************************************************* + + Synopsis [Resizes the vector to the given capacity.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_FltGrow( Vec_Flt_t * p, int nCapMin ) +{ + if ( p->nCap >= nCapMin ) + return; + p->pArray = REALLOC( float, p->pArray, nCapMin ); + p->nCap = nCapMin; +} + +/**Function************************************************************* + + Synopsis [Fills the vector with given number of entries.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_FltFill( Vec_Flt_t * p, int nSize, float Entry ) +{ + int i; + Vec_FltGrow( p, nSize ); + for ( i = 0; i < nSize; i++ ) + p->pArray[i] = Entry; + p->nSize = nSize; +} + +/**Function************************************************************* + + Synopsis [Fills the vector with given number of entries.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_FltFillExtra( Vec_Flt_t * p, int nSize, float Entry ) +{ + int i; + if ( p->nSize >= nSize ) + return; + Vec_FltGrow( p, nSize ); + for ( i = p->nSize; i < nSize; i++ ) + p->pArray[i] = Entry; + p->nSize = nSize; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_FltShrink( Vec_Flt_t * p, int nSizeNew ) +{ + assert( p->nSize >= nSizeNew ); + p->nSize = nSizeNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_FltClear( Vec_Flt_t * p ) +{ + p->nSize = 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_FltPush( Vec_Flt_t * p, float Entry ) +{ + if ( p->nSize == p->nCap ) + { + if ( p->nCap < 16 ) + Vec_FltGrow( p, 16 ); + else + Vec_FltGrow( p, 2 * p->nCap ); + } + p->pArray[p->nSize++] = Entry; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_FltPushMem( Extra_MmStep_t * pMemMan, Vec_Flt_t * p, float Entry ) +{ + if ( p->nSize == p->nCap ) + { + float * pArray; + int i; + + if ( p->nSize == 0 ) + p->nCap = 1; + pArray = (float *)Extra_MmStepEntryFetch( pMemMan, p->nCap * 8 ); +// pArray = ALLOC( float, p->nCap * 2 ); + if ( p->pArray ) + { + for ( i = 0; i < p->nSize; i++ ) + pArray[i] = p->pArray[i]; + Extra_MmStepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 ); +// free( p->pArray ); + } + p->nCap *= 2; + p->pArray = pArray; + } + p->pArray[p->nSize++] = Entry; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_FltPushOrder( Vec_Flt_t * p, float Entry ) +{ + int i; + if ( p->nSize == p->nCap ) + { + if ( p->nCap < 16 ) + Vec_FltGrow( p, 16 ); + else + Vec_FltGrow( p, 2 * p->nCap ); + } + p->nSize++; + for ( i = p->nSize-2; i >= 0; i-- ) + if ( p->pArray[i] > Entry ) + p->pArray[i+1] = p->pArray[i]; + else + break; + p->pArray[i+1] = Entry; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_FltPushUnique( Vec_Flt_t * p, float Entry ) +{ + int i; + for ( i = 0; i < p->nSize; i++ ) + if ( p->pArray[i] == Entry ) + return 1; + Vec_FltPush( p, Entry ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Returns the last entry and removes it from the list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline float Vec_FltPop( Vec_Flt_t * p ) +{ + assert( p->nSize > 0 ); + return p->pArray[--p->nSize]; +} + +/**Function************************************************************* + + Synopsis [Find entry.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_FltFind( Vec_Flt_t * p, float Entry ) +{ + int i; + for ( i = 0; i < p->nSize; i++ ) + if ( p->pArray[i] == Entry ) + return i; + return -1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_FltRemove( Vec_Flt_t * p, float Entry ) +{ + int i; + for ( i = 0; i < p->nSize; i++ ) + if ( p->pArray[i] == Entry ) + break; + if ( i == p->nSize ) + return 0; + assert( i < p->nSize ); + for ( i++; i < p->nSize; i++ ) + p->pArray[i-1] = p->pArray[i]; + p->nSize--; + return 1; +} + +/**Function************************************************************* + + Synopsis [Comparison procedure for two floats.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_FltSortCompare1( float * pp1, float * pp2 ) +{ + // for some reason commenting out lines (as shown) led to crashing of the release version + if ( *pp1 < *pp2 ) + return -1; + if ( *pp1 > *pp2 ) // + return 1; + return 0; // +} + +/**Function************************************************************* + + Synopsis [Comparison procedure for two floats.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Vec_FltSortCompare2( float * pp1, float * pp2 ) +{ + // for some reason commenting out lines (as shown) led to crashing of the release version + if ( *pp1 > *pp2 ) + return -1; + if ( *pp1 < *pp2 ) // + return 1; + return 0; // +} + +/**Function************************************************************* + + Synopsis [Sorting the entries by their value.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Vec_FltSort( Vec_Flt_t * p, int fReverse ) +{ + if ( fReverse ) + qsort( (void *)p->pArray, p->nSize, sizeof(float), + (int (*)(const void *, const void *)) Vec_FltSortCompare2 ); + else + qsort( (void *)p->pArray, p->nSize, sizeof(float), + (int (*)(const void *, const void *)) Vec_FltSortCompare1 ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/src/opt/cut/abcCut.c b/src/opt/cut/abcCut.c index b4b879a3..35814593 100644 --- a/src/opt/cut/abcCut.c +++ b/src/opt/cut/abcCut.c @@ -113,8 +113,8 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) continue; } // skip constant node, it has no cuts - if ( Abc_NodeIsConst(pObj) ) - continue; +// if ( Abc_NodeIsConst(pObj) ) +// continue; Extra_ProgressBarUpdate( pProgress, i, NULL ); // compute the cuts to the internal node Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree ); @@ -125,7 +125,7 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId1(pObj) ); } // add cuts due to choices - if ( Abc_NodeIsAigChoice(pObj) ) + if ( Abc_AigNodeIsChoice(pObj) ) { Vec_IntClear( vChoices ); for ( pNode = pObj; pNode; pNode = pNode->pData ) @@ -187,8 +187,8 @@ void Abc_NtkCutsOracle( Abc_Ntk_t * pNtk, Cut_Oracle_t * p ) continue; } // skip constant node, it has no cuts - if ( Abc_NodeIsConst(pObj) ) - continue; +// if ( Abc_NodeIsConst(pObj) ) +// continue; // compute the cuts to the internal node Cut_OracleComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj), Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); @@ -234,7 +234,7 @@ Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) p = Cut_ManStart( pParams ); // set cuts for the constant node and the PIs - pObj = Abc_NtkConst1(pNtk); + pObj = Abc_AigConst1(pNtk); if ( Abc_ObjFanoutNum(pObj) > 0 ) Cut_NodeSetTriv( p, pObj->Id ); Abc_NtkForEachPi( pNtk, pObj, i ) @@ -263,7 +263,7 @@ Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) { Abc_NodeGetCutsSeq( p, pObj, nIters==0 ); // add cuts due to choices - if ( Abc_NodeIsAigChoice(pObj) ) + if ( Abc_AigNodeIsChoice(pObj) ) { Vec_IntClear( vChoices ); for ( pNode = pObj; pNode; pNode = pNode->pData ) diff --git a/src/opt/dec/decAbc.c b/src/opt/dec/decAbc.c index 5311cec6..23d60826 100644 --- a/src/opt/dec/decAbc.c +++ b/src/opt/dec/decAbc.c @@ -18,7 +18,6 @@ #include "abc.h" #include "dec.h" -//#include "aig.h" #include "ivy.h" //////////////////////////////////////////////////////////////////////// @@ -48,7 +47,7 @@ Abc_Obj_t * Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph ) int i; // check for constant function if ( Dec_GraphIsConst(pGraph) ) - return Abc_ObjNotCond( Abc_NtkConst1(pNtk), Dec_GraphIsComplement(pGraph) ); + return Abc_ObjNotCond( Abc_AigConst1(pNtk), Dec_GraphIsComplement(pGraph) ); // check for a literal if ( Dec_GraphIsVar(pGraph) ) return Abc_ObjNotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) ); @@ -82,7 +81,7 @@ Abc_Obj_t * Dec_GraphToNetworkNoStrash( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph ) int i; // check for constant function if ( Dec_GraphIsConst(pGraph) ) - return Abc_ObjNotCond( Abc_NtkConst1(pNtk), Dec_GraphIsComplement(pGraph) ); + return Abc_ObjNotCond( Abc_AigConst1(pNtk), Dec_GraphIsComplement(pGraph) ); // check for a literal if ( Dec_GraphIsVar(pGraph) ) return Abc_ObjNotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) ); @@ -159,7 +158,7 @@ int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMa LevelNew = 1 + ABC_MAX( pNode0->Level, pNode1->Level ); if ( pAnd ) { - if ( Abc_ObjRegular(pAnd) == Abc_NtkConst1(pRoot->pNtk) ) + if ( Abc_ObjRegular(pAnd) == Abc_AigConst1(pRoot->pNtk) ) LevelNew = 0; else if ( Abc_ObjRegular(pAnd) == Abc_ObjRegular(pAnd0) ) LevelNew = (int)Abc_ObjRegular(pAnd0)->Level; @@ -215,11 +214,10 @@ void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, bool fUpda SeeAlso [] ***********************************************************************/ -/* -Aig_Node_t * Dec_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph ) +Aig_Obj_t * Dec_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph ) { Dec_Node_t * pNode; - Aig_Node_t * pAnd0, * pAnd1; + Aig_Obj_t * pAnd0, * pAnd1; int i; // check for constant function if ( Dec_GraphIsConst(pGraph) ) @@ -237,11 +235,10 @@ Aig_Node_t * Dec_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph ) // complement the result if necessary return Aig_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); } -*/ /**Function************************************************************* - Synopsis [Transforms the decomposition graph into the AIG.] + Synopsis [Strashes one logic node using its SOP.] Description [] @@ -250,7 +247,34 @@ Aig_Node_t * Dec_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph ) SeeAlso [] ***********************************************************************/ +Aig_Obj_t * Dec_GraphFactorSop( Aig_Man_t * pMan, char * pSop ) +{ + Aig_Obj_t * pFunc; + Dec_Graph_t * pFForm; + Dec_Node_t * pNode; + int i; + // perform factoring + pFForm = Dec_Factor( pSop ); + // collect the fanins + Dec_GraphForEachLeaf( pFForm, pNode, i ) + pNode->pFunc = Aig_IthVar( pMan, i ); + // perform strashing + pFunc = Dec_GraphToNetworkAig( pMan, pFForm ); + Dec_GraphFree( pFForm ); + return pFunc; +} + +/**Function************************************************************* + + Synopsis [Transforms the decomposition graph into the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] +***********************************************************************/ Ivy_Obj_t * Dec_GraphToNetworkIvy( Ivy_Man_t * pMan, Dec_Graph_t * pGraph ) { Dec_Node_t * pNode; diff --git a/src/opt/sim/simSeq.c b/src/opt/sim/simSeq.c index ba6b54d9..49fb939f 100644 --- a/src/opt/sim/simSeq.c +++ b/src/opt/sim/simSeq.c @@ -53,7 +53,7 @@ Vec_Ptr_t * Sim_SimulateSeqRandom( Abc_Ntk_t * pNtk, int nFrames, int nWords ) assert( Abc_NtkIsStrash(pNtk) ); vInfo = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), nWords * nFrames, 0 ); // set the constant data - pNode = Abc_NtkConst1(pNtk); + pNode = Abc_AigConst1(pNtk); Sim_UtilSetConst( Sim_SimInfoGet(vInfo,pNode), nWords * nFrames, 1 ); // set the random PI data Abc_NtkForEachPi( pNtk, pNode, i ) @@ -94,7 +94,7 @@ Vec_Ptr_t * Sim_SimulateSeqModel( Abc_Ntk_t * pNtk, int nFrames, int * pModel ) int i, k; vInfo = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), nFrames, 0 ); // set the constant data - pNode = Abc_NtkConst1(pNtk); + pNode = Abc_AigConst1(pNtk); Sim_UtilSetConst( Sim_SimInfoGet(vInfo,pNode), nFrames, 1 ); // set the random PI data Abc_NtkForEachPi( pNtk, pNode, i ) diff --git a/src/opt/sim/simSupp.c b/src/opt/sim/simSupp.c index dac0e5cf..f7048f4a 100644 --- a/src/opt/sim/simSupp.c +++ b/src/opt/sim/simSupp.c @@ -66,8 +66,8 @@ Vec_Ptr_t * Sim_ComputeStrSupp( Abc_Ntk_t * pNtk ) // derive the structural supports of the internal nodes Abc_NtkForEachNode( pNtk, pNode, i ) { - if ( Abc_NodeIsConst(pNode) ) - continue; +// if ( Abc_NodeIsConst(pNode) ) +// continue; pSimmNode = vSuppStr->pArray[ pNode->Id ]; pSimmNode1 = vSuppStr->pArray[ Abc_ObjFaninId0(pNode) ]; pSimmNode2 = vSuppStr->pArray[ Abc_ObjFaninId1(pNode) ]; diff --git a/src/opt/sim/simSymSim.c b/src/opt/sim/simSymSim.c index f0bf3633..ff0cafed 100644 --- a/src/opt/sim/simSymSim.c +++ b/src/opt/sim/simSymSim.c @@ -55,8 +55,8 @@ void Sim_SymmsSimulate( Sym_Man_t * p, unsigned * pPat, Vec_Ptr_t * vMatrsNonSym clk = clock(); Vec_PtrForEachEntry( p->vNodes, pNode, i ) { - if ( Abc_NodeIsConst(pNode) ) - continue; +// if ( Abc_NodeIsConst(pNode) ) +// continue; Sim_UtilSimulateNodeOne( pNode, p->vSim, p->nSimWords, 0 ); } p->timeSim += clock() - clk; @@ -65,7 +65,7 @@ clk = clock(); Abc_NtkForEachCo( p->pNtk, pNode, i ) { pNode = Abc_ObjFanin0(pNode); - if ( Abc_ObjIsCi(pNode) || Abc_NodeIsConst(pNode) ) + if ( Abc_ObjIsCi(pNode) || Abc_AigNodeIsConst(pNode) ) continue; nPairsTotal = Vec_IntEntry(p->vPairsTotal, i); nPairsSym = Vec_IntEntry(p->vPairsSym, i); diff --git a/src/opt/sim/simSymStr.c b/src/opt/sim/simSymStr.c index 90e6056e..d52c4328 100644 --- a/src/opt/sim/simSymStr.c +++ b/src/opt/sim/simSymStr.c @@ -74,8 +74,8 @@ void Sim_SymmsStructCompute( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMatrs, Vec_Ptr_t * v vNodes = Abc_NtkDfs( pNtk, 0 ); Vec_PtrForEachEntry( vNodes, pTemp, i ) { - if ( Abc_NodeIsConst(pTemp) ) - continue; +// if ( Abc_NodeIsConst(pTemp) ) +// continue; Sim_SymmsStructComputeOne( pNtk, pTemp, pMap ); } // collect the results for the COs; @@ -83,7 +83,7 @@ void Sim_SymmsStructCompute( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMatrs, Vec_Ptr_t * v { //printf( "Output %d:\n", i ); pTemp = Abc_ObjFanin0(pTemp); - if ( Abc_ObjIsCi(pTemp) || Abc_NodeIsConst(pTemp) ) + if ( Abc_ObjIsCi(pTemp) || Abc_AigNodeIsConst(pTemp) ) continue; Sim_SymmsTransferToMatrix( Vec_PtrEntry(vMatrs, i), SIM_READ_SYMMS(pTemp), Vec_PtrEntry(vSuppFun, i) ); } @@ -93,7 +93,7 @@ void Sim_SymmsStructCompute( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMatrs, Vec_Ptr_t * v Abc_NtkForEachCi( pNtk, pTemp, i ) Vec_IntFree( SIM_READ_SYMMS(pTemp) ); Vec_PtrForEachEntry( vNodes, pTemp, i ) - if ( !Abc_NodeIsConst(pTemp) ) +// if ( !Abc_NodeIsConst(pTemp) ) Vec_IntFree( SIM_READ_SYMMS(pTemp) ); Vec_PtrFree( vNodes ); free( pMap ); diff --git a/src/opt/sim/simUtils.c b/src/opt/sim/simUtils.c index 59d73412..b0660001 100644 --- a/src/opt/sim/simUtils.c +++ b/src/opt/sim/simUtils.c @@ -232,9 +232,6 @@ void Sim_UtilSimulateNode( Sim_Man_t * p, Abc_Obj_t * pNode, bool fType, bool fT // simulate the internal nodes if ( Abc_ObjIsNode(pNode) ) { - if ( Abc_NodeIsConst(pNode) ) - return; - if ( fType ) pSimmNode = p->vSim1->pArray[ pNode->Id ]; else @@ -305,8 +302,6 @@ void Sim_UtilSimulateNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimW int k, fComp1, fComp2; // simulate the internal nodes assert( Abc_ObjIsNode(pNode) ); - if ( Abc_NodeIsConst(pNode) ) - return; pSimmNode = Vec_PtrEntry(vSimInfo, pNode->Id); pSimmNode1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode)); pSimmNode2 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId1(pNode)); diff --git a/src/sat/aig/aig.h b/src/sat/aig/aig.h deleted file mode 100644 index a0d63ce9..00000000 --- a/src/sat/aig/aig.h +++ /dev/null @@ -1,377 +0,0 @@ -/**CFile**************************************************************** - - FileName [aig.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: aig.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __AIG_H__ -#define __AIG_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - AIG is an And-Inv Graph with structural hashing. - It is always structurally hashed. It means that at any time: - - for each AND gate, there are no other AND gates with the same children - - the constants are propagated - - there is no single-input nodes (inverters/buffers) - Additionally the following invariants are satisfied: - - there are no dangling nodes (the nodes without fanout) - - the level of each AND gate reflects the levels of this fanins - - the AND nodes are in the topological order - - the constant 1 node has always number 0 in the object list - The operations that are performed on AIGs: - - building new nodes (Aig_And) - - performing elementary Boolean operations (Aig_Or, Aig_Xor, etc) - - replacing one node by another (Abc_AigReplace) - - propagating constants (Abc_AigReplace) - - deleting dangling nodes (Abc_AigDelete) - When AIG is duplicated, the new graph is structurally hashed too. - If this repeated hashing leads to fewer nodes, it means the original - AIG was not strictly hashed (one of the conditions above is violated). -*/ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include <stdio.h> -#include "solver.h" -#include "vec.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -//typedef int bool; -#ifndef __cplusplus -#ifndef bool -#define bool int -#endif -#endif - -typedef struct Aig_Param_t_ Aig_Param_t; -typedef struct Aig_Man_t_ Aig_Man_t; -typedef struct Aig_Node_t_ Aig_Node_t; -typedef struct Aig_Edge_t_ Aig_Edge_t; -typedef struct Aig_MemFixed_t_ Aig_MemFixed_t; -typedef struct Aig_SimInfo_t_ Aig_SimInfo_t; -typedef struct Aig_Table_t_ Aig_Table_t; -typedef struct Aig_Pattern_t_ Aig_Pattern_t; - -// network types -typedef enum { - AIG_NONE = 0, // 0: unknown - AIG_PI, // 1: primary input - AIG_PO, // 2: primary output - AIG_AND // 3: internal node -} Aig_NodeType_t; - -// proof outcomes -typedef enum { - AIG_PROOF_NONE = 0, // 0: unknown - AIG_PROOF_SAT, // 1: primary input - AIG_PROOF_UNSAT, // 2: primary output - AIG_PROOF_TIMEOUT, // 3: primary output - AIG_PROOF_FAIL // 4: internal node -} Aig_ProofType_t; - - - -// the AIG parameters -struct Aig_Param_t_ -{ - int nPatsRand; // the number of random patterns - int nBTLimit; // backtrack limit at the intermediate nodes - int nSeconds; // the runtime limit at the final miter - int fVerbose; // verbosity - int fSatVerbose; // verbosity of SAT -}; - -// the AIG edge -struct Aig_Edge_t_ -{ - unsigned iNode : 31; // the node - unsigned fComp : 1; // the complemented attribute -}; - -// the AIG node -struct Aig_Node_t_ // 8 words -{ - // various numbers associated with the node - int Id; // the unique number (SAT var number) of this node - int nRefs; // the reference counter - unsigned Type : 2; // the node type - unsigned fPhase : 1; // the phase of this node - unsigned fMarkA : 1; // the mask - unsigned fMarkB : 1; // the mask - unsigned fMarkC : 1; // the mask - unsigned TravId : 26; // the traversal ID - unsigned Level : 16; // the direct level of the node - unsigned LevelR : 16; // the reverse level of the node - Aig_Edge_t Fans[2]; // the fanins - int NextH; // next node in the hash table - int Data; // miscelleneous data - Aig_Man_t * pMan; // the parent manager -}; - -// the AIG manager -struct Aig_Man_t_ -{ - // the AIG parameters - Aig_Param_t Param; // the full set of AIG parameters - Aig_Param_t * pParam; // the pointer to the above set - // the nodes - Aig_Node_t * pConst1; // the constant 1 node (ID=0) - Vec_Ptr_t * vNodes; // all nodes by ID - Vec_Ptr_t * vPis; // all PIs - Vec_Ptr_t * vPos; // all POs - Aig_Table_t * pTable; // structural hash table - int nLevelMax; // the maximum level - // SAT solver and related structures - solver * pSat; - Vec_Int_t * vVar2Sat; // mapping of nodes into their SAT var numbers (for each node num) - Vec_Int_t * vSat2Var; // mapping of the SAT var numbers into nodes (for each SAT var) - Vec_Int_t * vPiSatNums; // the SAT variable numbers (for each PI) - int * pModel; // the satisfying assignment (for each PI) - int nMuxes; // the number of MUXes - // fanout representation - Vec_Ptr_t * vFanPivots; // fanout pivots - Vec_Ptr_t * vFanFans0; // the next fanout of the first fanin - Vec_Ptr_t * vFanFans1; // the next fanout of the second fanin - // the memory managers - Aig_MemFixed_t * mmNodes; // the memory manager for nodes - int nTravIds; // the traversal ID - // simulation info - Aig_SimInfo_t * pInfo; // random and systematic sim info for PIs - Aig_SimInfo_t * pInfoPi; // temporary sim info for the PI nodes - Aig_SimInfo_t * pInfoTemp; // temporary sim info for all nodes - Aig_Pattern_t * pPatMask; // the mask which shows what patterns are used - // simulation patterns - int nPiWords; // the number of words in the PI info - int nPatsMax; // the max number of patterns - Vec_Ptr_t * vPats; // simulation patterns to try - // equivalence classes - Vec_Vec_t * vClasses; // the non-trival equivalence classes of nodes - // temporary data - Vec_Ptr_t * vFanouts; // temporary storage for fanouts of a node - Vec_Ptr_t * vToReplace; // the nodes to replace - Vec_Int_t * vClassTemp; // temporary class representatives -}; - -// the simulation patter -struct Aig_Pattern_t_ -{ - int nBits; - int nWords; - unsigned * pData; -}; - -// the AIG simulation info -struct Aig_SimInfo_t_ -{ - int Type; // the type (0 = PI, 1 = all) - int nNodes; // the number of nodes for which allocated - int nWords; // the number of words for each node - int nPatsMax; // the maximum number of patterns - int nPatsCur; // the current number of patterns - unsigned * pData; // the simulation data -}; - -// iterators over nodes, PIs, POs, ANDs -#define Aig_ManForEachNode( pMan, pNode, i ) \ - for ( i = 0; (i < Aig_ManNodeNum(pMan)) && (((pNode) = Aig_ManNode(pMan, i)), 1); i++ ) -#define Aig_ManForEachPi( pMan, pNode, i ) \ - for ( i = 0; (i < Aig_ManPiNum(pMan)) && (((pNode) = Aig_ManPi(pMan, i)), 1); i++ ) -#define Aig_ManForEachPo( pMan, pNode, i ) \ - for ( i = 0; (i < Aig_ManPoNum(pMan)) && (((pNode) = Aig_ManPo(pMan, i)), 1); i++ ) -#define Aig_ManForEachAnd( pMan, pNode, i ) \ - for ( i = 0; (i < Aig_ManNodeNum(pMan)) && (((pNode) = Aig_ManNode(pMan, i)), 1); i++ ) \ - if ( !Aig_NodeIsAnd(pNode) ) {} else - -// maximum/minimum operators -#define AIG_MIN(a,b) (((a) < (b))? (a) : (b)) -#define AIG_MAX(a,b) (((a) > (b))? (a) : (b)) - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -static inline int Aig_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); } -static inline int Aig_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; } -static inline void Aig_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); } -static inline void Aig_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); } - -static inline Aig_Node_t * Aig_ManConst1( Aig_Man_t * pMan ) { return pMan->pConst1; } -static inline Aig_Node_t * Aig_ManNode( Aig_Man_t * pMan, int i ) { return Vec_PtrEntry(pMan->vNodes, i); } -static inline Aig_Node_t * Aig_ManPi( Aig_Man_t * pMan, int i ) { return Vec_PtrEntry(pMan->vPis, i); } -static inline Aig_Node_t * Aig_ManPo( Aig_Man_t * pMan, int i ) { return Vec_PtrEntry(pMan->vPos, i); } - -static inline int Aig_ManNodeNum( Aig_Man_t * pMan ) { return Vec_PtrSize(pMan->vNodes); } -static inline int Aig_ManPiNum( Aig_Man_t * pMan ) { return Vec_PtrSize(pMan->vPis); } -static inline int Aig_ManPoNum( Aig_Man_t * pMan ) { return Vec_PtrSize(pMan->vPos); } -static inline int Aig_ManAndNum( Aig_Man_t * pMan ) { return Aig_ManNodeNum(pMan)-Aig_ManPiNum(pMan)-Aig_ManPoNum(pMan)-1; } - -static inline Aig_Node_t * Aig_Regular( Aig_Node_t * p ) { return (Aig_Node_t *)((unsigned)(p) & ~01); } -static inline Aig_Node_t * Aig_Not( Aig_Node_t * p ) { return (Aig_Node_t *)((unsigned)(p) ^ 01); } -static inline Aig_Node_t * Aig_NotCond( Aig_Node_t * p, int c ) { return (Aig_Node_t *)((unsigned)(p) ^ (c)); } -static inline bool Aig_IsComplement( Aig_Node_t * p ) { return (bool)(((unsigned)p) & 01); } - -static inline bool Aig_NodeIsConst( Aig_Node_t * pNode ) { return Aig_Regular(pNode)->Id == 0; } -static inline bool Aig_NodeIsPi( Aig_Node_t * pNode ) { return Aig_Regular(pNode)->Type == AIG_PI; } -static inline bool Aig_NodeIsPo( Aig_Node_t * pNode ) { return Aig_Regular(pNode)->Type == AIG_PO; } -static inline bool Aig_NodeIsAnd( Aig_Node_t * pNode ) { return Aig_Regular(pNode)->Type == AIG_AND; } - -static inline int Aig_NodeId( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->Id; } -static inline int Aig_NodeRefs( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->nRefs; } -static inline bool Aig_NodePhase( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->fPhase; } -static inline int Aig_NodeLevel( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->Level; } -static inline int Aig_NodeLevelR( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->LevelR; } -static inline int Aig_NodeData( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->Data; } -static inline Aig_Man_t * Aig_NodeMan( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->pMan; } -static inline int Aig_NodeFaninId0( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->Fans[0].iNode; } -static inline int Aig_NodeFaninId1( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->Fans[1].iNode; } -static inline bool Aig_NodeFaninC0( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->Fans[0].fComp; } -static inline bool Aig_NodeFaninC1( Aig_Node_t * pNode ) { assert( !Aig_IsComplement(pNode) ); return pNode->Fans[1].fComp; } -static inline Aig_Node_t * Aig_NodeFanin0( Aig_Node_t * pNode ) { return Aig_ManNode( Aig_NodeMan(pNode), Aig_NodeFaninId0(pNode) ); } -static inline Aig_Node_t * Aig_NodeFanin1( Aig_Node_t * pNode ) { return Aig_ManNode( Aig_NodeMan(pNode), Aig_NodeFaninId1(pNode) ); } -static inline Aig_Node_t * Aig_NodeChild0( Aig_Node_t * pNode ) { return Aig_NotCond( Aig_NodeFanin0(pNode), Aig_NodeFaninC0(pNode) ); } -static inline Aig_Node_t * Aig_NodeChild1( Aig_Node_t * pNode ) { return Aig_NotCond( Aig_NodeFanin1(pNode), Aig_NodeFaninC1(pNode) ); } -static inline Aig_Node_t * Aig_NodeNextH( Aig_Node_t * pNode ) { return pNode->NextH? Aig_ManNode(pNode->pMan, pNode->NextH) : NULL; } -static inline int Aig_NodeWhatFanin( Aig_Node_t * pNode, Aig_Node_t * pFanin ) { if ( Aig_NodeFaninId0(pNode) == pFanin->Id ) return 0; if ( Aig_NodeFaninId1(pNode) == pFanin->Id ) return 1; assert(0); return -1; } -static inline int Aig_NodeGetLevelNew( Aig_Node_t * pNode ) { return 1 + AIG_MAX(Aig_NodeFanin0(pNode)->Level, Aig_NodeFanin1(pNode)->Level); } -static inline int Aig_NodeRequiredLevel( Aig_Node_t * pNode ) { return pNode->pMan->nLevelMax + 1 - pNode->LevelR; } - -static inline unsigned * Aig_SimInfoForNodeId( Aig_SimInfo_t * p, int NodeId ) { assert( p->Type ); return p->pData + p->nWords * NodeId; } -static inline unsigned * Aig_SimInfoForNode( Aig_SimInfo_t * p, Aig_Node_t * pNode ) { assert( p->Type ); return p->pData + p->nWords * pNode->Id; } -static inline unsigned * Aig_SimInfoForPi( Aig_SimInfo_t * p, int Num ) { assert( !p->Type ); return p->pData + p->nWords * Num; } - -static inline void Aig_NodeSetTravId( Aig_Node_t * pNode, int TravId ) { pNode->TravId = TravId; } -static inline void Aig_NodeSetTravIdCurrent( Aig_Node_t * pNode ) { pNode->TravId = pNode->pMan->nTravIds; } -static inline void Aig_NodeSetTravIdPrevious( Aig_Node_t * pNode ) { pNode->TravId = pNode->pMan->nTravIds - 1; } -static inline bool Aig_NodeIsTravIdCurrent( Aig_Node_t * pNode ) { return (bool)((int)pNode->TravId == pNode->pMan->nTravIds); } -static inline bool Aig_NodeIsTravIdPrevious( Aig_Node_t * pNode ) { return (bool)((int)pNode->TravId == pNode->pMan->nTravIds - 1); } - - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== aigCheck.c ==========================================================*/ -extern bool Aig_ManCheck( Aig_Man_t * pMan ); -extern bool Aig_NodeIsAcyclic( Aig_Node_t * pNode, Aig_Node_t * pRoot ); -/*=== aigFanout.c ==========================================================*/ -extern void Aig_ManCreateFanouts( Aig_Man_t * p ); -extern void Aig_NodeAddFaninFanout( Aig_Node_t * pFanin, Aig_Node_t * pFanout ); -extern void Aig_NodeRemoveFaninFanout( Aig_Node_t * pFanin, Aig_Node_t * pFanoutToRemove ); -extern int Aig_NodeGetFanoutNum( Aig_Node_t * pNode ); -extern Vec_Ptr_t * Aig_NodeGetFanouts( Aig_Node_t * pNode ); -extern int Aig_NodeGetLevelRNew( Aig_Node_t * pNode ); -extern int Aig_ManSetLevelR( Aig_Man_t * pMan ); -extern int Aig_ManGetLevelMax( Aig_Man_t * pMan ); -extern int Aig_NodeUpdateLevel_int( Aig_Node_t * pNode ); -extern int Aig_NodeUpdateLevelR_int( Aig_Node_t * pNode ); -/*=== aigMem.c =============================================================*/ -extern Aig_MemFixed_t * Aig_MemFixedStart( int nEntrySize ); -extern void Aig_MemFixedStop( Aig_MemFixed_t * p, int fVerbose ); -extern char * Aig_MemFixedEntryFetch( Aig_MemFixed_t * p ); -extern void Aig_MemFixedEntryRecycle( Aig_MemFixed_t * p, char * pEntry ); -extern void Aig_MemFixedRestart( Aig_MemFixed_t * p ); -extern int Aig_MemFixedReadMemUsage( Aig_MemFixed_t * p ); -/*=== aigMan.c =============================================================*/ -extern void Aig_ManSetDefaultParams( Aig_Param_t * pParam ); -extern Aig_Man_t * Aig_ManStart( Aig_Param_t * pParam ); -extern int Aig_ManCleanup( Aig_Man_t * pMan ); -extern void Aig_ManStop( Aig_Man_t * p ); -/*=== aigNode.c =============================================================*/ -extern Aig_Node_t * Aig_NodeCreateConst( Aig_Man_t * p ); -extern Aig_Node_t * Aig_NodeCreatePi( Aig_Man_t * p ); -extern Aig_Node_t * Aig_NodeCreatePo( Aig_Man_t * p ); -extern Aig_Node_t * Aig_NodeCreateAnd( Aig_Man_t * p, Aig_Node_t * pFanin0, Aig_Node_t * pFanin1 ); -extern Aig_Node_t * Aig_NodeConnectPo( Aig_Man_t * p, Aig_Node_t * pNode, Aig_Node_t * pFanin ); -extern void Aig_NodeConnectAnd( Aig_Node_t * pFanin0, Aig_Node_t * pFanin1, Aig_Node_t * pNode ); -extern void Aig_NodeDisconnectAnd( Aig_Node_t * pNode ); -extern void Aig_NodeDeleteAnd_rec( Aig_Man_t * pMan, Aig_Node_t * pRoot ); -extern void Aig_NodePrint( Aig_Node_t * pNode ); -extern char * Aig_NodeName( Aig_Node_t * pNode ); -extern void Aig_PrintNode( Aig_Node_t * pNode ); -/*=== aigOper.c ==========================================================*/ -extern Aig_Node_t * Aig_And( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 ); -extern Aig_Node_t * Aig_Or( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 ); -extern Aig_Node_t * Aig_Xor( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 ); -extern Aig_Node_t * Aig_Mux( Aig_Man_t * pMan, Aig_Node_t * pC, Aig_Node_t * p1, Aig_Node_t * p0 ); -extern Aig_Node_t * Aig_Miter( Aig_Man_t * pMan, Vec_Ptr_t * vPairs ); -/*=== aigReplace.c ==========================================================*/ -extern void Aig_ManReplaceNode( Aig_Man_t * pMan, Aig_Node_t * pOld, Aig_Node_t * pNew, int fUpdateLevel ); -/*=== aigTable.c ==========================================================*/ -extern Aig_Table_t * Aig_TableCreate( int nSize ); -extern void Aig_TableFree( Aig_Table_t * p ); -extern int Aig_TableNumNodes( Aig_Table_t * p ); -extern Aig_Node_t * Aig_TableLookupNode( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 ); -extern Aig_Node_t * Aig_TableInsertNode( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1, Aig_Node_t * pAnd ); -extern void Aig_TableDeleteNode( Aig_Man_t * pMan, Aig_Node_t * pThis ); -extern void Aig_TableResize( Aig_Man_t * pMan ); -extern void Aig_TableRehash( Aig_Man_t * pMan ); -/*=== aigUtil.c ==========================================================*/ -extern void Aig_ManIncrementTravId( Aig_Man_t * pMan ); -extern bool Aig_NodeIsMuxType( Aig_Node_t * pNode ); -extern Aig_Node_t * Aig_NodeRecognizeMux( Aig_Node_t * pNode, Aig_Node_t ** ppNodeT, Aig_Node_t ** ppNodeE ); - - -/*=== fraigCore.c ==========================================================*/ -extern Aig_ProofType_t Aig_FraigProve( Aig_Man_t * pMan ); -/*=== fraigClasses.c ==========================================================*/ -extern Vec_Vec_t * Aig_ManDeriveClassesFirst( Aig_Man_t * p, Aig_SimInfo_t * pInfoAll ); -extern int Aig_ManUpdateClasses( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Vec_t * vClasses, Aig_Pattern_t * pPatMask ); -extern void Aig_ManCollectPatterns( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Aig_Pattern_t * pMask, Vec_Ptr_t * vPats ); -/*=== fraigCnf.c ==========================================================*/ -extern Aig_ProofType_t Aig_ClauseSolverStart( Aig_Man_t * pMan ); -/*=== fraigEngine.c ==========================================================*/ -extern void Aig_EngineSimulateRandomFirst( Aig_Man_t * p ); -extern void Aig_EngineSimulateFirst( Aig_Man_t * p ); -extern int Aig_EngineSimulate( Aig_Man_t * p ); -/*=== fraigSim.c ==========================================================*/ -extern Aig_SimInfo_t * Aig_SimInfoAlloc( int nNodes, int nBits, int Type ); -extern void Aig_SimInfoClean( Aig_SimInfo_t * p ); -extern void Aig_SimInfoRandom( Aig_SimInfo_t * p ); -extern void Aig_SimInfoFromPattern( Aig_SimInfo_t * p, Aig_Pattern_t * pPat ); -extern void Aig_SimInfoResize( Aig_SimInfo_t * p ); -extern void Aig_SimInfoFree( Aig_SimInfo_t * p ); -extern void Aig_ManSimulateInfo( Aig_Man_t * p, Aig_SimInfo_t * pInfoPi, Aig_SimInfo_t * pInfoAll ); -extern Aig_Pattern_t * Aig_PatternAlloc( int nBits ); -extern void Aig_PatternClean( Aig_Pattern_t * pPat ); -extern void Aig_PatternFill( Aig_Pattern_t * pPat ); -extern int Aig_PatternCount( Aig_Pattern_t * pPat ); -extern void Aig_PatternRandom( Aig_Pattern_t * pPat ); -extern void Aig_PatternFree( Aig_Pattern_t * pPat ); - -#ifdef __cplusplus -} -#endif - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/sat/aig/aigBalance.c b/src/sat/aig/aigBalance.c deleted file mode 100644 index 1dd8ab01..00000000 --- a/src/sat/aig/aigBalance.c +++ /dev/null @@ -1,47 +0,0 @@ -/**CFile**************************************************************** - - FileName [aigBalance.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: aigBalance.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/aigCheck.c b/src/sat/aig/aigCheck.c deleted file mode 100644 index a9facef3..00000000 --- a/src/sat/aig/aigCheck.c +++ /dev/null @@ -1,146 +0,0 @@ -/**CFile**************************************************************** - - FileName [aigCheck.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: aigCheck.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Makes sure that every node in the table is in the network and vice versa.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Aig_ManCheck( Aig_Man_t * pMan ) -{ - Aig_Node_t * pObj, * pAnd; - int i; - Aig_ManForEachNode( pMan, pObj, i ) - { - if ( pObj == pMan->pConst1 || Aig_NodeIsPi(pObj) ) - { - if ( pObj->Fans[0].iNode || pObj->Fans[1].iNode || pObj->Level ) - { - printf( "Aig_ManCheck: The AIG has non-standard constant or PI node \"%d\".\n", pObj->Id ); - return 0; - } - continue; - } - if ( Aig_NodeIsPo(pObj) ) - { - if ( pObj->Fans[1].iNode ) - { - printf( "Aig_ManCheck: The AIG has non-standard PO node \"%d\".\n", pObj->Id ); - return 0; - } - continue; - } - // consider the AND node - if ( !pObj->Fans[0].iNode || !pObj->Fans[1].iNode ) - { - printf( "Aig_ManCheck: The AIG has node \"%d\" with a constant fanin.\n", pObj->Id ); - return 0; - } - if ( pObj->Fans[0].iNode > pObj->Fans[1].iNode ) - { - printf( "Aig_ManCheck: The AIG has node \"%d\" with a wrong ordering of fanins.\n", pObj->Id ); - return 0; - } - if ( pObj->Level != 1 + AIG_MAX(Aig_NodeFanin0(pObj)->Level, Aig_NodeFanin1(pObj)->Level) ) - printf( "Aig_ManCheck: Node \"%d\" has level that does not agree with the fanin levels.\n", pObj->Id ); - pAnd = Aig_TableLookupNode( pMan, Aig_NodeChild0(pObj), Aig_NodeChild1(pObj) ); - if ( pAnd != pObj ) - printf( "Aig_ManCheck: Node \"%d\" is not in the structural hashing table.\n", pObj->Id ); - } - // count the number of nodes in the table - if ( Aig_TableNumNodes(pMan->pTable) != Aig_ManAndNum(pMan) ) - { - printf( "Aig_ManCheck: The number of nodes in the structural hashing table is wrong.\n" ); - return 0; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Check if the node has a combination loop of depth 1 or 2.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Aig_NodeIsAcyclic( Aig_Node_t * pNode, Aig_Node_t * pRoot ) -{ - Aig_Node_t * pFanin0, * pFanin1; - Aig_Node_t * pChild00, * pChild01; - Aig_Node_t * pChild10, * pChild11; - if ( !Aig_NodeIsAnd(pNode) ) - return 1; - pFanin0 = Aig_NodeFanin0(pNode); - pFanin1 = Aig_NodeFanin1(pNode); - if ( pRoot == pFanin0 || pRoot == pFanin1 ) - return 0; - if ( Aig_NodeIsPi(pFanin0) ) - { - pChild00 = NULL; - pChild01 = NULL; - } - else - { - pChild00 = Aig_NodeFanin0(pFanin0); - pChild01 = Aig_NodeFanin1(pFanin0); - if ( pRoot == pChild00 || pRoot == pChild01 ) - return 0; - } - if ( Aig_NodeIsPi(pFanin1) ) - { - pChild10 = NULL; - pChild11 = NULL; - } - else - { - pChild10 = Aig_NodeFanin0(pFanin1); - pChild11 = Aig_NodeFanin1(pFanin1); - if ( pRoot == pChild10 || pRoot == pChild11 ) - return 0; - } - return 1; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/aigFanout.c b/src/sat/aig/aigFanout.c deleted file mode 100644 index aed38426..00000000 --- a/src/sat/aig/aigFanout.c +++ /dev/null @@ -1,423 +0,0 @@ -/**CFile**************************************************************** - - FileName [aigFanout.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: aigFanout.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static inline Aig_Node_t * Aig_NodeFanPivot( Aig_Node_t * pNode ) { return Vec_PtrEntry(pNode->pMan->vFanPivots, pNode->Id); } -static inline Aig_Node_t * Aig_NodeFanFan0( Aig_Node_t * pNode ) { return Vec_PtrEntry(pNode->pMan->vFanFans0, pNode->Id); } -static inline Aig_Node_t * Aig_NodeFanFan1( Aig_Node_t * pNode ) { return Vec_PtrEntry(pNode->pMan->vFanFans1, pNode->Id); } -static inline Aig_Node_t ** Aig_NodeFanPivotPlace( Aig_Node_t * pNode ) { return ((Aig_Node_t **)pNode->pMan->vFanPivots->pArray) + pNode->Id; } -static inline Aig_Node_t ** Aig_NodeFanFan0Place( Aig_Node_t * pNode ) { return ((Aig_Node_t **)pNode->pMan->vFanFans0->pArray) + pNode->Id; } -static inline Aig_Node_t ** Aig_NodeFanFan1Place( Aig_Node_t * pNode ) { return ((Aig_Node_t **)pNode->pMan->vFanFans1->pArray) + pNode->Id; } -static inline void Aig_NodeSetFanPivot( Aig_Node_t * pNode, Aig_Node_t * pNode2 ) { Vec_PtrWriteEntry(pNode->pMan->vFanPivots, pNode->Id, pNode2); } -static inline void Aig_NodeSetFanFan0( Aig_Node_t * pNode, Aig_Node_t * pNode2 ) { Vec_PtrWriteEntry(pNode->pMan->vFanFans0, pNode->Id, pNode2); } -static inline void Aig_NodeSetFanFan1( Aig_Node_t * pNode, Aig_Node_t * pNode2 ) { Vec_PtrWriteEntry(pNode->pMan->vFanFans1, pNode->Id, pNode2); } -static inline Aig_Node_t * Aig_NodeNextFanout( Aig_Node_t * pNode, Aig_Node_t * pFanout ) { if ( pFanout == NULL ) return NULL; return Aig_NodeFaninId0(pFanout) == pNode->Id? Aig_NodeFanFan0(pFanout) : Aig_NodeFanFan1(pFanout); } -static inline Aig_Node_t ** Aig_NodeNextFanoutPlace( Aig_Node_t * pNode, Aig_Node_t * pFanout ) { return Aig_NodeFaninId0(pFanout) == pNode->Id? Aig_NodeFanFan0Place(pFanout) : Aig_NodeFanFan1Place(pFanout); } - -// iterator through the fanouts of the node -#define Aig_NodeForEachFanout( pNode, pFanout ) \ - for ( pFanout = Aig_NodeFanPivot(pNode); pFanout; \ - pFanout = Aig_NodeNextFanout(pNode, pFanout) ) -// safe iterator through the fanouts of the node -#define Aig_NodeForEachFanoutSafe( pNode, pFanout, pFanout2 ) \ - for ( pFanout = Aig_NodeFanPivot(pNode), \ - pFanout2 = Aig_NodeNextFanout(pNode, pFanout); \ - pFanout; \ - pFanout = pFanout2, \ - pFanout2 = Aig_NodeNextFanout(pNode, pFanout) ) - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Creates the fanouts for all nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_ManCreateFanouts( Aig_Man_t * p ) -{ - Aig_Node_t * pNode; - int i; - assert( p->vFanPivots == NULL ); - p->vFanPivots = Vec_PtrStart( Aig_ManNodeNum(p) ); - p->vFanFans0 = Vec_PtrStart( Aig_ManNodeNum(p) ); - p->vFanFans1 = Vec_PtrStart( Aig_ManNodeNum(p) ); - Aig_ManForEachNode( p, pNode, i ) - { - if ( Aig_NodeIsPi(pNode) || i == 0 ) - continue; - Aig_NodeAddFaninFanout( Aig_NodeFanin0(pNode), pNode ); - if ( Aig_NodeIsPo(pNode) ) - continue; - Aig_NodeAddFaninFanout( Aig_NodeFanin1(pNode), pNode ); - } -} - -/**Function************************************************************* - - Synopsis [Creates the fanouts for all nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Aig_ManResizeFanouts( Aig_Man_t * p, int nSizeNew ) -{ - assert( p->vFanPivots ); - if ( Vec_PtrSize(p->vFanPivots) < nSizeNew ) - { - Vec_PtrFillExtra( p->vFanPivots, nSizeNew + 1000, NULL ); - Vec_PtrFillExtra( p->vFanFans0, nSizeNew + 1000, NULL ); - Vec_PtrFillExtra( p->vFanFans1, nSizeNew + 1000, NULL ); - } -} - -/**Function************************************************************* - - Synopsis [Add the fanout to the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_NodeAddFaninFanout( Aig_Node_t * pFanin, Aig_Node_t * pFanout ) -{ - Aig_Node_t * pPivot; - - // check that they are not complemented - assert( !Aig_IsComplement(pFanin) ); - assert( !Aig_IsComplement(pFanout) ); - // check that pFanins is a fanin of pFanout - assert( Aig_NodeFaninId0(pFanout) == pFanin->Id || Aig_NodeFaninId1(pFanout) == pFanin->Id ); - - // resize the fanout manager - Aig_ManResizeFanouts( pFanin->pMan, 1 + AIG_MAX(pFanin->Id, pFanout->Id) ); - - // consider the case of the first fanout - pPivot = Aig_NodeFanPivot(pFanin); - if ( pPivot == NULL ) - { - Aig_NodeSetFanPivot( pFanin, pFanout ); - return; - } - - // consider the case of more than one fanouts - if ( Aig_NodeFaninId0(pPivot) == pFanin->Id ) - { - if ( Aig_NodeFaninId0(pFanout) == pFanin->Id ) - { - Aig_NodeSetFanFan0( pFanout, Aig_NodeFanFan0(pPivot) ); - Aig_NodeSetFanFan0( pPivot, pFanout ); - } - else // if ( Aig_NodeFaninId1(pFanout) == pFanin->Id ) - { - Aig_NodeSetFanFan1( pFanout, Aig_NodeFanFan0(pPivot) ); - Aig_NodeSetFanFan0( pPivot, pFanout ); - } - } - else // if ( Aig_NodeFaninId1(pPivot) == pFanin->Id ) - { - assert( Aig_NodeFaninId1(pPivot) == pFanin->Id ); - if ( Aig_NodeFaninId0(pFanout) == pFanin->Id ) - { - Aig_NodeSetFanFan0( pFanout, Aig_NodeFanFan1(pPivot) ); - Aig_NodeSetFanFan1( pPivot, pFanout ); - } - else // if ( Aig_NodeFaninId1(pFanout) == pFanin->Id ) - { - Aig_NodeSetFanFan1( pFanout, Aig_NodeFanFan1(pPivot) ); - Aig_NodeSetFanFan1( pPivot, pFanout ); - } - } -} - -/**Function************************************************************* - - Synopsis [Add the fanout to the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_NodeRemoveFaninFanout( Aig_Node_t * pFanin, Aig_Node_t * pFanoutToRemove ) -{ - Aig_Node_t * pFanout, * pFanout2, ** ppFanList; - // start the linked list of fanouts - ppFanList = Aig_NodeFanPivotPlace(pFanin); - // go through the fanouts - Aig_NodeForEachFanoutSafe( pFanin, pFanout, pFanout2 ) - { - // skip the fanout-to-remove - if ( pFanout == pFanoutToRemove ) - continue; - // add useful fanouts to the list - *ppFanList = pFanout; - ppFanList = Aig_NodeNextFanoutPlace( pFanin, pFanout ); - } - *ppFanList = NULL; -} - -/**Function************************************************************* - - Synopsis [Returns the number of fanouts of a node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_NodeGetFanoutNum( Aig_Node_t * pNode ) -{ - Aig_Node_t * pFanout; - int Counter = 0; - Aig_NodeForEachFanout( pNode, pFanout ) - Counter++; - return Counter; -} - -/**Function************************************************************* - - Synopsis [Collect fanouts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Aig_NodeGetFanouts( Aig_Node_t * pNode ) -{ - Aig_Node_t * pFanout; - Vec_PtrClear( pNode->pMan->vFanouts ); - Aig_NodeForEachFanout( pNode, pFanout ) - Vec_PtrPush( pNode->pMan->vFanouts, pFanout ); - return pNode->pMan->vFanouts; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the node has at least one complemented fanout.] - - Description [A fanout is complemented if the fanout's fanin edge pointing - to the given node is complemented.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Aig_NodeHasComplFanoutEdge( Aig_Node_t * pNode ) -{ - Aig_Node_t * pFanout; - int iFanin; - Aig_NodeForEachFanout( pNode, pFanout ) - { - iFanin = Aig_NodeWhatFanin( pFanout, pNode ); - assert( iFanin >= 0 ); - if ( iFanin && Aig_NodeFaninC1(pFanout) || !iFanin && Aig_NodeFaninC0(pFanout) ) - return 1; - } - return 0; -} - - - - -/**Function************************************************************* - - Synopsis [Recursively computes and assigns the reverse level of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static int Aig_NodeSetLevelR_rec( Aig_Node_t * pNode ) -{ - Aig_Node_t * pFanout; - int LevelR = 0; - if ( Aig_NodeIsPo(pNode) ) - return pNode->LevelR = 0; - Aig_NodeForEachFanout( pNode, pFanout ) - if ( LevelR < Aig_NodeSetLevelR_rec(pFanout) ) - LevelR = pFanout->LevelR; - return pNode->LevelR = 1 + LevelR; -} - -/**Function************************************************************* - - Synopsis [Computes the reverse level of all nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_ManSetLevelR( Aig_Man_t * pMan ) -{ - Aig_Node_t * pNode; - int i, LevelR = 0; - Aig_ManForEachPi( pMan, pNode, i ) - if ( LevelR < Aig_NodeSetLevelR_rec(pNode) ) - LevelR = pNode->LevelR; - return LevelR; -} - -/**Function************************************************************* - - Synopsis [Computes the global number of logic levels.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_ManGetLevelMax( Aig_Man_t * pMan ) -{ - Aig_Node_t * pNode; - int i, LevelsMax = 0; - Aig_ManForEachPo( pMan, pNode, i ) - if ( LevelsMax < (int)pNode->Level ) - LevelsMax = (int)pNode->Level; - return LevelsMax; -} - -/**Function************************************************************* - - Synopsis [Computes but does not assign the reverse level of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_NodeGetLevelRNew( Aig_Node_t * pNode ) -{ - Aig_Node_t * pFanout; - unsigned LevelR = 0; - Aig_NodeForEachFanout( pNode, pFanout ) - LevelR = AIG_MAX( LevelR, pFanout->LevelR ); - return LevelR + !Aig_NodeIsPi(pNode); -} - - -/**Function************************************************************* - - Synopsis [Updates the direct level of one node.] - - Description [Returns 1 if direct level of at least one CO was changed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_NodeUpdateLevel_int( Aig_Node_t * pNode ) -{ - Aig_Node_t * pFanout; - unsigned LevelNew, fStatus = 0; - Aig_NodeForEachFanout( pNode, pFanout ) - { - LevelNew = Aig_NodeGetLevelNew( pFanout ); - if ( pFanout->Level == LevelNew ) - continue; - // the level has changed - pFanout->Level = LevelNew; - if ( Aig_NodeIsPo(pNode) ) - fStatus = 1; - else - fStatus |= Aig_NodeUpdateLevel_int( pFanout ); - } - return fStatus; -} - - -/**Function************************************************************* - - Synopsis [Updates the reverse level of one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_NodeUpdateLevelR_int( Aig_Node_t * pNode ) -{ - Aig_Node_t * pFanin; - unsigned LevelNew; - assert( !Aig_NodeIsPo(pNode) ); - pFanin = Aig_NodeFanin0(pNode); - LevelNew = Aig_NodeGetLevelRNew(pFanin); - if ( pFanin->LevelR != LevelNew ) - { - pFanin->LevelR = LevelNew; - if ( Aig_NodeIsAnd(pFanin) ) - Aig_NodeUpdateLevelR_int( pFanin ); - } - pFanin = Aig_NodeFanin1(pNode); - LevelNew = Aig_NodeGetLevelRNew(pFanin); - if ( pFanin->LevelR != LevelNew ) - { - pFanin->LevelR = LevelNew; - if ( Aig_NodeIsAnd(pFanin) ) - Aig_NodeUpdateLevelR_int( pFanin ); - } - return 1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/aigMan.c b/src/sat/aig/aigMan.c deleted file mode 100644 index 4c64c897..00000000 --- a/src/sat/aig/aigMan.c +++ /dev/null @@ -1,157 +0,0 @@ -/**CFile**************************************************************** - - FileName [aigMan.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: aigMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Sets the default parameters.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_ManSetDefaultParams( Aig_Param_t * pParam ) -{ - memset( pParam, 0, sizeof(Aig_Param_t) ); - pParam->nPatsRand = 4096; // the number of random patterns - pParam->nBTLimit = 99; // backtrack limit at the intermediate nodes - pParam->nSeconds = 1; // the timeout for the final miter in seconds -} - -/**Function************************************************************* - - Synopsis [Starts the AIG manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Man_t * Aig_ManStart( Aig_Param_t * pParam ) -{ - Aig_Man_t * p; - // set the random seed for simulation - srand( 0xDEADCAFE ); - // start the manager - p = ALLOC( Aig_Man_t, 1 ); - memset( p, 0, sizeof(Aig_Man_t) ); - p->pParam = &p->Param; - p->nTravIds = 1; - p->nPatsMax = 25; - // set the defaults - *p->pParam = *pParam; - // start memory managers - p->mmNodes = Aig_MemFixedStart( sizeof(Aig_Node_t) ); - // allocate node arrays - p->vPis = Vec_PtrAlloc( 1000 ); // the array of primary inputs - p->vPos = Vec_PtrAlloc( 1000 ); // the array of primary outputs - p->vNodes = Vec_PtrAlloc( 1000 ); // the array of internal nodes - // start the table - p->pTable = Aig_TableCreate( 1000 ); - // create the constant node - p->pConst1 = Aig_NodeCreateConst( p ); - // initialize other variables - p->vFanouts = Vec_PtrAlloc( 10 ); - p->vToReplace = Vec_PtrAlloc( 10 ); - p->vClassTemp = Vec_IntAlloc( 10 ); - p->vPats = Vec_PtrAlloc( p->nPatsMax ); - return p; -} - -/**Function************************************************************* - - Synopsis [Returns the number of dangling nodes removed.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_ManCleanup( Aig_Man_t * pMan ) -{ - Aig_Node_t * pAnd; - int i, nNodesOld; - nNodesOld = Aig_ManAndNum(pMan); - Aig_ManForEachAnd( pMan, pAnd, i ) - if ( pAnd->nRefs == 0 ) - Aig_NodeDeleteAnd_rec( pMan, pAnd ); - return nNodesOld - Aig_ManAndNum(pMan); -} - -/**Function************************************************************* - - Synopsis [Stops the AIG manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_ManStop( Aig_Man_t * p ) -{ - // SAT solver - if ( p->pSat ) solver_delete( p->pSat ); - if ( p->vVar2Sat ) Vec_IntFree( p->vVar2Sat ); - if ( p->vSat2Var ) Vec_IntFree( p->vSat2Var ); - if ( p->vPiSatNums ) Vec_IntFree( p->vPiSatNums ); - // fanouts - if ( p->vFanPivots ) Vec_PtrFree( p->vFanPivots ); - if ( p->vFanFans0 ) Vec_PtrFree( p->vFanFans0 ); - if ( p->vFanFans1 ) Vec_PtrFree( p->vFanFans1 ); - if ( p->vClasses ) Vec_VecFree( p->vClasses ); - // patterns - if ( p->vPats ) Vec_PtrFree( p->vPats ); - if ( p->pPatMask ) Aig_PatternFree( p->pPatMask ); - // nodes - Aig_MemFixedStop( p->mmNodes, 0 ); - Vec_PtrFree( p->vNodes ); - Vec_PtrFree( p->vPis ); - Vec_PtrFree( p->vPos ); - // temporary - Vec_PtrFree( p->vFanouts ); - Vec_PtrFree( p->vToReplace ); - Vec_IntFree( p->vClassTemp ); - Aig_TableFree( p->pTable ); - free( p ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/aigMem.c b/src/sat/aig/aigMem.c deleted file mode 100644 index 32709bf6..00000000 --- a/src/sat/aig/aigMem.c +++ /dev/null @@ -1,246 +0,0 @@ -/**CFile**************************************************************** - - FileName [aigMem.c] - - PackageName [ABC: Logic synthesis and verification system.] - - Synopsis [Fixed-size-entry memory manager for the AIG package.] - - Author [Alan Mishchenko <alanmi@eecs.berkeley.edu>] - - Affiliation [UC Berkeley] - - Date [Ver. 2.0. Started - October 1, 2004] - - Revision [$Id: aigMem.c,v 1.4 2005/07/08 01:01:31 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -struct Aig_MemFixed_t_ -{ - // information about individual entries - int nEntrySize; // the size of one entry - int nEntriesAlloc; // the total number of entries allocated - int nEntriesUsed; // the number of entries in use - int nEntriesMax; // the max number of entries in use - char * pEntriesFree; // the linked list of free entries - - // this is where the memory is stored - int nChunkSize; // the size of one chunk - int nChunksAlloc; // the maximum number of memory chunks - int nChunks; // the current number of memory chunks - char ** pChunks; // the allocated memory - - // statistics - int nMemoryUsed; // memory used in the allocated entries - int nMemoryAlloc; // memory allocated -}; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Starts the internal memory manager.] - - Description [Can only work with entry size at least 4 byte long.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_MemFixed_t * Aig_MemFixedStart( int nEntrySize ) -{ - Aig_MemFixed_t * p; - - p = ALLOC( Aig_MemFixed_t, 1 ); - memset( p, 0, sizeof(Aig_MemFixed_t) ); - - p->nEntrySize = nEntrySize; - p->nEntriesAlloc = 0; - p->nEntriesUsed = 0; - p->pEntriesFree = NULL; - - if ( nEntrySize * (1 << 10) < (1<<16) ) - p->nChunkSize = (1 << 10); - else - p->nChunkSize = (1<<16) / nEntrySize; - if ( p->nChunkSize < 8 ) - p->nChunkSize = 8; - - p->nChunksAlloc = 64; - p->nChunks = 0; - p->pChunks = ALLOC( char *, p->nChunksAlloc ); - - p->nMemoryUsed = 0; - p->nMemoryAlloc = 0; - return p; -} - -/**Function************************************************************* - - Synopsis [Stops the internal memory manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_MemFixedStop( Aig_MemFixed_t * p, int fVerbose ) -{ - int i; - if ( p == NULL ) - return; - if ( fVerbose ) - { - printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n", - p->nEntrySize, p->nChunkSize, p->nChunks ); - printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n", - p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc ); - } - for ( i = 0; i < p->nChunks; i++ ) - free( p->pChunks[i] ); - free( p->pChunks ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Extracts one entry from the memory manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Aig_MemFixedEntryFetch( Aig_MemFixed_t * p ) -{ - char * pTemp; - int i; - - // check if there are still free entries - if ( p->nEntriesUsed == p->nEntriesAlloc ) - { // need to allocate more entries - assert( p->pEntriesFree == NULL ); - if ( p->nChunks == p->nChunksAlloc ) - { - p->nChunksAlloc *= 2; - p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc ); - } - p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize ); - p->nMemoryAlloc += p->nEntrySize * p->nChunkSize; - // transform these entries into a linked list - pTemp = p->pEntriesFree; - for ( i = 1; i < p->nChunkSize; i++ ) - { - *((char **)pTemp) = pTemp + p->nEntrySize; - pTemp += p->nEntrySize; - } - // set the last link - *((char **)pTemp) = NULL; - // add the chunk to the chunk storage - p->pChunks[ p->nChunks++ ] = p->pEntriesFree; - // add to the number of entries allocated - p->nEntriesAlloc += p->nChunkSize; - } - // incrememt the counter of used entries - p->nEntriesUsed++; - if ( p->nEntriesMax < p->nEntriesUsed ) - p->nEntriesMax = p->nEntriesUsed; - // return the first entry in the free entry list - pTemp = p->pEntriesFree; - p->pEntriesFree = *((char **)pTemp); - return pTemp; -} - -/**Function************************************************************* - - Synopsis [Returns one entry into the memory manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_MemFixedEntryRecycle( Aig_MemFixed_t * p, char * pEntry ) -{ - // decrement the counter of used entries - p->nEntriesUsed--; - // add the entry to the linked list of free entries - *((char **)pEntry) = p->pEntriesFree; - p->pEntriesFree = pEntry; -} - -/**Function************************************************************* - - Synopsis [Frees all associated memory and resets the manager.] - - Description [Relocates all the memory except the first chunk.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_MemFixedRestart( Aig_MemFixed_t * p ) -{ - int i; - char * pTemp; - - // deallocate all chunks except the first one - for ( i = 1; i < p->nChunks; i++ ) - free( p->pChunks[i] ); - p->nChunks = 1; - // transform these entries into a linked list - pTemp = p->pChunks[0]; - for ( i = 1; i < p->nChunkSize; i++ ) - { - *((char **)pTemp) = pTemp + p->nEntrySize; - pTemp += p->nEntrySize; - } - // set the last link - *((char **)pTemp) = NULL; - // set the free entry list - p->pEntriesFree = p->pChunks[0]; - // set the correct statistics - p->nMemoryAlloc = p->nEntrySize * p->nChunkSize; - p->nMemoryUsed = 0; - p->nEntriesAlloc = p->nChunkSize; - p->nEntriesUsed = 0; -} - -/**Function************************************************************* - - Synopsis [Reports the memory usage.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_MemFixedReadMemUsage( Aig_MemFixed_t * p ) -{ - return p->nMemoryAlloc; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/aigNode.c b/src/sat/aig/aigNode.c deleted file mode 100644 index ce458353..00000000 --- a/src/sat/aig/aigNode.c +++ /dev/null @@ -1,316 +0,0 @@ -/**CFile**************************************************************** - - FileName [aigNode.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: aigNode.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Creates the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Aig_Node_t * Aig_NodeCreate( Aig_Man_t * p ) -{ - Aig_Node_t * pNode; - // create the node - pNode = (Aig_Node_t *)Aig_MemFixedEntryFetch( p->mmNodes ); - memset( pNode, 0, sizeof(Aig_Node_t) ); - // assign the number and add to the array of nodes - pNode->pMan = p; - pNode->Id = p->vNodes->nSize; - Vec_PtrPush( p->vNodes, pNode ); - return pNode; -} - -/**Function************************************************************* - - Synopsis [Creates the constant 1 node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Aig_NodeCreateConst( Aig_Man_t * p ) -{ - Aig_Node_t * pNode; - pNode = Aig_NodeCreate( p ); - pNode->Type = AIG_NONE; - pNode->fPhase = 1; // sim value for 000... pattern - return pNode; -} - -/**Function************************************************************* - - Synopsis [Creates a primary input node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Aig_NodeCreatePi( Aig_Man_t * p ) -{ - Aig_Node_t * pNode; - pNode = Aig_NodeCreate( p ); - Vec_PtrPush( p->vPis, pNode ); - pNode->Type = AIG_PI; - pNode->fPhase = 0; // sim value for 000... pattern - return pNode; -} - -/**Function************************************************************* - - Synopsis [Creates a primary output node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Aig_NodeCreatePo( Aig_Man_t * p ) -{ - Aig_Node_t * pNode; - pNode = Aig_NodeCreate( p ); - pNode->Type = AIG_PO; - Vec_PtrPush( p->vPos, pNode ); - return pNode; -} - -/**Function************************************************************* - - Synopsis [Creates a primary output node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Aig_NodeConnectPo( Aig_Man_t * p, Aig_Node_t * pNode, Aig_Node_t * pFanin ) -{ - assert( Aig_NodeIsPo(pNode) ); - assert( !Aig_IsComplement(pNode) ); - // connect to the fanin - pNode->Fans[0].fComp = Aig_IsComplement(pFanin); - pNode->Fans[0].iNode = Aig_Regular(pFanin)->Id; - pNode->fPhase = pNode->Fans[0].fComp ^ Aig_Regular(pFanin)->fPhase; // sim value for 000... pattern - pNode->Level = Aig_Regular(pFanin)->Level; - Aig_Regular(pFanin)->nRefs++; - if ( pNode->pMan->vFanPivots ) Aig_NodeAddFaninFanout( pFanin, pNode ); - // update global level if needed - if ( p->nLevelMax < (int)pNode->Level ) - p->nLevelMax = pNode->Level; - return pNode; -} - -/**Function************************************************************* - - Synopsis [Creates a new node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Aig_NodeCreateAnd( Aig_Man_t * p, Aig_Node_t * pFanin0, Aig_Node_t * pFanin1 ) -{ - Aig_Node_t * pNode; - pNode = Aig_NodeCreate( p ); - pNode->Type = AIG_AND; - Aig_NodeConnectAnd( pFanin0, pFanin1, pNode ); - return pNode; -} - -/**Function************************************************************* - - Synopsis [Connects the nodes to the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_NodeConnectAnd( Aig_Node_t * pFanin0, Aig_Node_t * pFanin1, Aig_Node_t * pNode ) -{ - assert( !Aig_IsComplement(pNode) ); - assert( Aig_NodeIsAnd(pNode) ); - // add the fanins - pNode->Fans[0].fComp = Aig_IsComplement(pFanin0); - pNode->Fans[0].iNode = Aig_Regular(pFanin0)->Id; - pNode->Fans[1].fComp = Aig_IsComplement(pFanin1); - pNode->Fans[1].iNode = Aig_Regular(pFanin1)->Id; - // compute the phase (sim value for 000... pattern) - pNode->fPhase = (pNode->Fans[0].fComp ^ Aig_Regular(pFanin0)->fPhase) & - (pNode->Fans[1].fComp ^ Aig_Regular(pFanin1)->fPhase); - pNode->Level = Aig_NodeGetLevelNew(pNode); - // reference the fanins - Aig_Regular(pFanin0)->nRefs++; - Aig_Regular(pFanin1)->nRefs++; - // add the fanouts - if ( pNode->pMan->vFanPivots ) Aig_NodeAddFaninFanout( pFanin0, pNode ); - if ( pNode->pMan->vFanPivots ) Aig_NodeAddFaninFanout( pFanin1, pNode ); - // add the node to the structural hash table - Aig_TableInsertNode( pNode->pMan, pFanin0, pFanin1, pNode ); -} - -/**Function************************************************************* - - Synopsis [Connects the nodes to the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_NodeDisconnectAnd( Aig_Node_t * pNode ) -{ - Aig_Node_t * pFanin0, * pFanin1; - assert( !Aig_IsComplement(pNode) ); - assert( Aig_NodeIsAnd(pNode) ); - // get the fanins - pFanin0 = Aig_NodeFanin0(pNode); - pFanin1 = Aig_NodeFanin1(pNode); - // dereference the fanins - pFanin0->nRefs--; - pFanin0->nRefs--; - // remove the fanouts - if ( pNode->pMan->vFanPivots ) Aig_NodeRemoveFaninFanout( pFanin0, pNode ); - if ( pNode->pMan->vFanPivots ) Aig_NodeRemoveFaninFanout( pFanin1, pNode ); - // remove the node from the structural hash table - Aig_TableDeleteNode( pNode->pMan, pNode ); -} - -/**Function************************************************************* - - Synopsis [Performs internal deletion step.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_NodeDeleteAnd_rec( Aig_Man_t * pMan, Aig_Node_t * pRoot ) -{ - Aig_Node_t * pNode0, * pNode1; - // make sure the node is regular and dangling - assert( !Aig_IsComplement(pRoot) ); - assert( pRoot->nRefs == 0 ); - assert( Aig_NodeIsAnd(pRoot) ); - // remember the children - pNode0 = Aig_NodeFanin0(pRoot); - pNode1 = Aig_NodeFanin1(pRoot); - // disconnect the node - Aig_NodeDisconnectAnd( pRoot ); - // recycle the node - Vec_PtrWriteEntry( pMan->vNodes, pRoot->Id, NULL ); - memset( pRoot, 0, sizeof(Aig_Node_t) ); // this is a temporary hack to skip dead children below!!! - Aig_MemFixedEntryRecycle( pMan->mmNodes, (char *)pRoot ); - // call recursively - if ( Aig_NodeIsAnd(pNode0) && pNode0->nRefs == 0 ) - Aig_NodeDeleteAnd_rec( pMan, pNode0 ); - if ( Aig_NodeIsAnd(pNode1) && pNode1->nRefs == 0 ) - Aig_NodeDeleteAnd_rec( pMan, pNode1 ); -} - -/**Function************************************************************* - - Synopsis [Prints the AIG node for debugging purposes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_NodePrint( Aig_Node_t * pNode ) -{ - Aig_Node_t * pNodeR = Aig_Regular(pNode); - if ( Aig_NodeIsPi(pNode) ) - { - printf( "PI %4s%s.\n", Aig_NodeName(pNode), Aig_IsComplement(pNode)? "\'" : "" ); - return; - } - if ( Aig_NodeIsConst(pNode) ) - { - printf( "Constant 1 %s.\n", Aig_IsComplement(pNode)? "(complemented)" : "" ); - return; - } - // print the node's function - printf( "%7s%s", Aig_NodeName(pNodeR), Aig_IsComplement(pNode)? "\'" : "" ); - printf( " = " ); - printf( "%7s%s", Aig_NodeName(Aig_NodeFanin0(pNodeR)), Aig_NodeFaninC0(pNodeR)? "\'" : "" ); - printf( " * " ); - printf( "%7s%s", Aig_NodeName(Aig_NodeFanin1(pNodeR)), Aig_NodeFaninC1(pNodeR)? "\'" : "" ); - printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Returns the name of the node.] - - Description [The name should be used before this procedure is called again.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Aig_NodeName( Aig_Node_t * pNode ) -{ - static char Buffer[100]; - sprintf( Buffer, "%d", Aig_Regular(pNode)->Id ); - return Buffer; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/aigOper.c b/src/sat/aig/aigOper.c deleted file mode 100644 index a10cc7ff..00000000 --- a/src/sat/aig/aigOper.c +++ /dev/null @@ -1,175 +0,0 @@ -/**CFile**************************************************************** - - FileName [aigOper.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: aigOper.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs canonicization step.] - - Description [The argument nodes can be complemented.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Aig_And( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 ) -{ - Aig_Node_t * pAnd; - // check for trivial cases - if ( p0 == p1 ) - return p0; - if ( p0 == Aig_Not(p1) ) - return Aig_Not(pMan->pConst1); - if ( Aig_Regular(p0) == pMan->pConst1 ) - { - if ( p0 == pMan->pConst1 ) - return p1; - return Aig_Not(pMan->pConst1); - } - if ( Aig_Regular(p1) == pMan->pConst1 ) - { - if ( p1 == pMan->pConst1 ) - return p0; - return Aig_Not(pMan->pConst1); - } - // order the arguments - if ( Aig_Regular(p0)->Id > Aig_Regular(p1)->Id ) - { - if ( pAnd = Aig_TableLookupNode( pMan, p1, p0 ) ) - return pAnd; - return Aig_NodeCreateAnd( pMan, p1, p0 ); - } - else - { - if ( pAnd = Aig_TableLookupNode( pMan, p0, p1 ) ) - return pAnd; - return Aig_NodeCreateAnd( pMan, p0, p1 ); - } -} - -/**Function************************************************************* - - Synopsis [Implements Boolean OR.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Aig_Or( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 ) -{ - return Aig_Not( Aig_And( pMan, Aig_Not(p0), Aig_Not(p1) ) ); -} - -/**Function************************************************************* - - Synopsis [Implements Boolean XOR.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Aig_Xor( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 ) -{ - return Aig_Or( pMan, Aig_And(pMan, p0, Aig_Not(p1)), - Aig_And(pMan, p1, Aig_Not(p0)) ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Aig_Mux( Aig_Man_t * pMan, Aig_Node_t * pC, Aig_Node_t * p1, Aig_Node_t * p0 ) -{ - return Aig_Or( pMan, Aig_And(pMan, pC, p1), Aig_And(pMan, Aig_Not(pC), p0) ); -} - -/**Function************************************************************* - - Synopsis [Implements the miter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Aig_Miter_rec( Aig_Man_t * pMan, Aig_Node_t ** ppObjs, int nObjs ) -{ - Aig_Node_t * pObj1, * pObj2; - if ( nObjs == 1 ) - return ppObjs[0]; - pObj1 = Aig_Miter_rec( pMan, ppObjs, nObjs/2 ); - pObj2 = Aig_Miter_rec( pMan, ppObjs + nObjs/2, nObjs - nObjs/2 ); - return Aig_Or( pMan, pObj1, pObj2 ); -} - -/**Function************************************************************* - - Synopsis [Implements the miter.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Aig_Miter( Aig_Man_t * pMan, Vec_Ptr_t * vPairs ) -{ - int i; - if ( vPairs->nSize == 0 ) - return Aig_Not( pMan->pConst1 ); - assert( vPairs->nSize % 2 == 0 ); - // go through the cubes of the node's SOP - for ( i = 0; i < vPairs->nSize; i += 2 ) - vPairs->pArray[i/2] = Aig_Xor( pMan, vPairs->pArray[i], vPairs->pArray[i+1] ); - vPairs->nSize = vPairs->nSize/2; - return Aig_Miter_rec( pMan, (Aig_Node_t **)vPairs->pArray, vPairs->nSize ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/aigReplace.c b/src/sat/aig/aigReplace.c deleted file mode 100644 index d928fdf8..00000000 --- a/src/sat/aig/aigReplace.c +++ /dev/null @@ -1,133 +0,0 @@ -/**CFile**************************************************************** - - FileName [aigUpdate.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: aigUpdate.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs internal replacement step.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static void Abc_AigReplace_int( Aig_Man_t * pMan, int fUpdateLevel ) -{ - Vec_Ptr_t * vFanouts; - Aig_Node_t * pOld, * pNew, * pFanin0, * pFanin1, * pFanout, * pTemp, * pFanoutNew; - int k, iFanin; - // get the pair of nodes to replace - assert( Vec_PtrSize(pMan->vToReplace) > 0 ); - pNew = Vec_PtrPop( pMan->vToReplace ); - pOld = Vec_PtrPop( pMan->vToReplace ); - // make sure the old node is internal, regular, and has fanouts - // (the new node can be PI or internal, is complemented, and can have fanouts) - assert( !Aig_IsComplement(pOld) ); - assert( pOld->nRefs > 0 ); - assert( Aig_NodeIsAnd(pOld) ); - assert( Aig_NodeIsPo(pNew) ); - // look at the fanouts of old node - vFanouts = Aig_NodeGetFanouts( pOld ); - Vec_PtrForEachEntry( vFanouts, pFanout, k ) - { - if ( Aig_NodeIsPo(pFanout) ) - { - // patch the first fanin of the PO - pFanout->Fans[0].iNode = Aig_Regular(pNew)->Id; - pFanout->Fans[0].fComp ^= Aig_IsComplement(pNew); - continue; - } - // find the old node as a fanin of this fanout - iFanin = Aig_NodeWhatFanin( pFanout, pOld ); - assert( iFanin == 0 || iFanin == 1 ); - // get the new fanin - pFanin0 = Aig_NotCond( pNew, pFanout->Fans[iFanin].fComp ); - assert( Aig_Regular(pFanin0) != pFanout ); - // get another fanin - pFanin1 = iFanin? Aig_NodeChild0(pFanout) : Aig_NodeChild1(pFanout); - assert( Aig_Regular(pFanin1) != pFanout ); - assert( Aig_Regular(pFanin0) != Aig_Regular(pFanin1) ); - // order them - if ( Aig_Regular(pFanin0)->Id > Aig_Regular(pFanin1)->Id ) - pTemp = pFanin0, pFanin0 = pFanin1, pFanin1 = pTemp; - // check if the node with these fanins exists - if ( pFanoutNew = Aig_TableLookupNode( pMan, pFanin0, pFanin1 ) ) - { // such node exists (it may be a constant) - // schedule replacement of the old fanout by the new fanout - Vec_PtrPush( pMan->vToReplace, pFanout ); - Vec_PtrPush( pMan->vToReplace, pFanoutNew ); - continue; - } - // such node does not exist - modify the old fanout node - // (this way the change will not propagate all the way to the COs) - Aig_NodeDisconnectAnd( pFanout ); - Aig_NodeConnectAnd( pFanin0, pFanin1, pFanout ); - // recreate the old fanout with new fanins and add it to the table - assert( Aig_NodeIsAcyclic(pFanout, pFanout) ); - // update the level if requested - if ( fUpdateLevel ) - { - if ( Aig_NodeUpdateLevel_int(pFanout) ) - pMan->nLevelMax = Aig_ManGetLevelMax( pMan ); - //Aig_NodeGetLevelRNew( pFanout ); - Aig_NodeUpdateLevelR_int( pFanout ); - } - } - // if the node has no fanouts left, remove its MFFC - if ( pOld->nRefs == 0 ) - Aig_NodeDeleteAnd_rec( pMan, pOld ); -} - -/**Function************************************************************* - - Synopsis [Replaces one AIG node by the other.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_ManReplaceNode( Aig_Man_t * pMan, Aig_Node_t * pOld, Aig_Node_t * pNew, int fUpdateLevel ) -{ - assert( Vec_PtrSize(pMan->vToReplace) == 0 ); - Vec_PtrPush( pMan->vToReplace, pOld ); - Vec_PtrPush( pMan->vToReplace, pNew ); - while ( Vec_PtrSize(pMan->vToReplace) ) - Abc_AigReplace_int( pMan, fUpdateLevel ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/aigTable.c b/src/sat/aig/aigTable.c deleted file mode 100644 index e6fe87d6..00000000 --- a/src/sat/aig/aigTable.c +++ /dev/null @@ -1,334 +0,0 @@ -/**CFile**************************************************************** - - FileName [aigTable.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: aigTable.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -// the hash table -struct Aig_Table_t_ -{ - Aig_Node_t ** pBins; // the table bins - int nBins; // the size of the table - int nEntries; // the total number of entries in the table -}; - -// iterators through the entries in the linked lists of nodes -#define Aig_TableBinForEachEntry( pBin, pEnt ) \ - for ( pEnt = pBin; \ - pEnt; \ - pEnt = Aig_NodeNextH(pEnt) ) -#define Aig_TableBinForEachEntrySafe( pBin, pEnt, pEnt2 ) \ - for ( pEnt = pBin, \ - pEnt2 = pEnt? Aig_NodeNextH(pEnt) : NULL; \ - pEnt; \ - pEnt = pEnt2, \ - pEnt2 = pEnt? Aig_NodeNextH(pEnt) : NULL ) - -// hash key for the structural hash table -static inline unsigned Abc_HashKey2( Aig_Node_t * p0, Aig_Node_t * p1, int TableSize ) { return ((unsigned)(p0) + (unsigned)(p1) * 12582917) % TableSize; } -//static inline unsigned Abc_HashKey2( Aig_Node_t * p0, Aig_Node_t * p1, int TableSize ) { return ((unsigned)((a)->Id + (b)->Id) * ((a)->Id + (b)->Id + 1) / 2) % TableSize; } - -static unsigned int Cudd_PrimeAig( unsigned int p ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocates the hash table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Table_t * Aig_TableCreate( int nSize ) -{ - Aig_Table_t * p; - // allocate the table - p = ALLOC( Aig_Table_t, 1 ); - memset( p, 0, sizeof(Aig_Table_t) ); - // allocate and clean the bins - p->nBins = Cudd_PrimeAig(nSize); - p->pBins = ALLOC( Aig_Node_t *, p->nBins ); - memset( p->pBins, 0, sizeof(Aig_Node_t *) * p->nBins ); - return p; -} - -/**Function************************************************************* - - Synopsis [Deallocates the supergate hash table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_TableFree( Aig_Table_t * p ) -{ - FREE( p->pBins ); - FREE( p ); -} - -/**Function************************************************************* - - Synopsis [Returns the number of nodes in the table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_TableNumNodes( Aig_Table_t * p ) -{ - return p->nEntries; -} - -/**Function************************************************************* - - Synopsis [Performs canonicization step.] - - Description [The argument nodes can be complemented.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Aig_TableLookupNode( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1 ) -{ - Aig_Node_t * pAnd; - unsigned Key; - assert( Aig_Regular(p0)->Id < Aig_Regular(p1)->Id ); - // get the hash key for these two nodes - Key = Abc_HashKey2( p0, p1, pMan->pTable->nBins ); - // find the matching node in the table - Aig_TableBinForEachEntry( pMan->pTable->pBins[Key], pAnd ) - if ( p0 == Aig_NodeChild0(pAnd) && p1 == Aig_NodeChild1(pAnd) ) - return pAnd; - return NULL; -} - -/**Function************************************************************* - - Synopsis [Performs canonicization step.] - - Description [The argument nodes can be complemented.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Aig_TableInsertNode( Aig_Man_t * pMan, Aig_Node_t * p0, Aig_Node_t * p1, Aig_Node_t * pAnd ) -{ - unsigned Key; - assert( Aig_Regular(p0)->Id < Aig_Regular(p1)->Id ); - // check if it is a good time for table resizing - if ( pMan->pTable->nEntries > 2 * pMan->pTable->nBins ) - Aig_TableResize( pMan ); - // add the node to the corresponding linked list in the table - Key = Abc_HashKey2( p0, p1, pMan->pTable->nBins ); - pAnd->NextH = pMan->pTable->pBins[Key]? pMan->pTable->pBins[Key]->Id : 0; - pMan->pTable->pBins[Key] = pAnd; - pMan->pTable->nEntries++; - return pAnd; -} - - -/**Function************************************************************* - - Synopsis [Deletes an AIG node from the hash table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_TableDeleteNode( Aig_Man_t * pMan, Aig_Node_t * pThis ) -{ - Aig_Node_t * pAnd, * pPlace = NULL; - unsigned Key; - assert( !Aig_IsComplement(pThis) ); - assert( Aig_NodeIsAnd(pThis) ); - assert( pMan == pThis->pMan ); - // get the hash key for these two nodes - Key = Abc_HashKey2( Aig_NodeChild0(pThis), Aig_NodeChild1(pThis), pMan->pTable->nBins ); - // find the matching node in the table - Aig_TableBinForEachEntry( pMan->pTable->pBins[Key], pAnd ) - { - if ( pThis != pAnd ) - { - pPlace = pAnd; - continue; - } - if ( pPlace == NULL ) - pMan->pTable->pBins[Key] = Aig_NodeNextH(pThis); - else - pPlace->NextH = pThis->NextH; - break; - } - assert( pThis == pAnd ); - pMan->pTable->nEntries--; -} - -/**Function************************************************************* - - Synopsis [Resizes the hash table of AIG nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_TableResize( Aig_Man_t * pMan ) -{ - Aig_Node_t ** pBinsNew; - Aig_Node_t * pEnt, * pEnt2; - int nBinsNew, Counter, i, clk; - unsigned Key; - -clk = clock(); - // get the new table size - nBinsNew = Cudd_PrimeCopy( 3 * pMan->pTable->nBins ); - // allocate a new array - pBinsNew = ALLOC( Aig_Node_t *, nBinsNew ); - memset( pBinsNew, 0, sizeof(Aig_Node_t *) * nBinsNew ); - // rehash the entries from the old table - Counter = 0; - for ( i = 0; i < pMan->pTable->nBins; i++ ) - Aig_TableBinForEachEntrySafe( pMan->pTable->pBins[i], pEnt, pEnt2 ) - { - Key = Abc_HashKey2( Aig_NodeChild0(pEnt), Aig_NodeChild1(pEnt), nBinsNew ); - pEnt->NextH = pBinsNew[Key]? pBinsNew[Key]->Id : 0; - pBinsNew[Key] = pEnt; - Counter++; - } - assert( Counter == pMan->pTable->nEntries ); -// printf( "Increasing the structural table size from %6d to %6d. ", pMan->nBins, nBinsNew ); -// PRT( "Time", clock() - clk ); - // replace the table and the parameters - free( pMan->pTable->pBins ); - pMan->pTable->pBins = pBinsNew; - pMan->pTable->nBins = nBinsNew; -} - -/**Function************************************************************* - - Synopsis [Resizes the hash table of AIG nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_TableRehash( Aig_Man_t * pMan ) -{ - Aig_Node_t ** pBinsNew; - Aig_Node_t * pEnt, * pEnt2; - unsigned Key; - int Counter, Temp, i; - // allocate a new array - pBinsNew = ALLOC( Aig_Node_t *, pMan->pTable->nBins ); - memset( pBinsNew, 0, sizeof(Aig_Node_t *) * pMan->pTable->nBins ); - // rehash the entries from the old table - Counter = 0; - for ( i = 0; i < pMan->pTable->nBins; i++ ) - Aig_TableBinForEachEntrySafe( pMan->pTable->pBins[i], pEnt, pEnt2 ) - { - // swap the fanins if needed - if ( pEnt->Fans[0].iNode > pEnt->Fans[1].iNode ) - { - Temp = pEnt->Fans[0].iNode; - pEnt->Fans[0].iNode = pEnt->Fans[1].iNode; - pEnt->Fans[1].iNode = Temp; - Temp = pEnt->Fans[0].fComp; - pEnt->Fans[0].fComp = pEnt->Fans[1].fComp; - pEnt->Fans[1].fComp = Temp; - } - // rehash the node - Key = Abc_HashKey2( Aig_NodeChild0(pEnt), Aig_NodeChild1(pEnt), pMan->pTable->nBins ); - pEnt->NextH = pBinsNew[Key]? pBinsNew[Key]->Id : 0; - pBinsNew[Key] = pEnt; - Counter++; - } - assert( Counter == pMan->pTable->nEntries ); - // replace the table and the parameters - free( pMan->pTable->pBins ); - pMan->pTable->pBins = pBinsNew; -} - -/**Function************************************************************* - - Synopsis [Returns the smallest prime larger than the number.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned int Cudd_PrimeAig( unsigned int p ) -{ - int i,pn; - - p--; - do { - p++; - if (p&1) { - pn = 1; - i = 3; - while ((unsigned) (i * i) <= p) { - if (p % i == 0) { - pn = 0; - break; - } - i += 2; - } - } else { - pn = 0; - } - } while (!pn); - return(p); - -} /* end of Cudd_Prime */ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/aigUtil.c b/src/sat/aig/aigUtil.c deleted file mode 100644 index 40f7aba1..00000000 --- a/src/sat/aig/aigUtil.c +++ /dev/null @@ -1,190 +0,0 @@ -/**CFile**************************************************************** - - FileName [aigUtil.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: aigUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Increments the current traversal ID of the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_ManIncrementTravId( Aig_Man_t * pMan ) -{ - Aig_Node_t * pObj; - int i; - if ( pMan->nTravIds == (1<<24)-1 ) - { - pMan->nTravIds = 0; - Aig_ManForEachNode( pMan, pObj, i ) - pObj->TravId = 0; - } - pMan->nTravIds++; -} - - -/**Function************************************************************* - - Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Aig_NodeIsMuxType( Aig_Node_t * pNode ) -{ - Aig_Node_t * pNode0, * pNode1; - // check that the node is regular - assert( !Aig_IsComplement(pNode) ); - // if the node is not AND, this is not MUX - if ( !Aig_NodeIsAnd(pNode) ) - return 0; - // if the children are not complemented, this is not MUX - if ( !Aig_NodeFaninC0(pNode) || !Aig_NodeFaninC1(pNode) ) - return 0; - // get children - pNode0 = Aig_NodeFanin0(pNode); - pNode1 = Aig_NodeFanin1(pNode); - // if the children are not ANDs, this is not MUX - if ( !Aig_NodeIsAnd(pNode0) || !Aig_NodeIsAnd(pNode1) ) - return 0; - // otherwise the node is MUX iff it has a pair of equal grandchildren - return (Aig_NodeFaninId0(pNode0) == Aig_NodeFaninId0(pNode1) && (Aig_NodeFaninC0(pNode0) ^ Aig_NodeFaninC0(pNode1))) || - (Aig_NodeFaninId0(pNode0) == Aig_NodeFaninId1(pNode1) && (Aig_NodeFaninC0(pNode0) ^ Aig_NodeFaninC1(pNode1))) || - (Aig_NodeFaninId1(pNode0) == Aig_NodeFaninId0(pNode1) && (Aig_NodeFaninC1(pNode0) ^ Aig_NodeFaninC0(pNode1))) || - (Aig_NodeFaninId1(pNode0) == Aig_NodeFaninId1(pNode1) && (Aig_NodeFaninC1(pNode0) ^ Aig_NodeFaninC1(pNode1))); -} - -/**Function************************************************************* - - Synopsis [Recognizes what nodes are control and data inputs of a MUX.] - - Description [If the node is a MUX, returns the control variable C. - Assigns nodes T and E to be the then and else variables of the MUX. - Node C is never complemented. Nodes T and E can be complemented. - This function also recognizes EXOR/NEXOR gates as MUXes.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Aig_NodeRecognizeMux( Aig_Node_t * pNode, Aig_Node_t ** ppNodeT, Aig_Node_t ** ppNodeE ) -{ - Aig_Node_t * pNode0, * pNode1; - assert( !Aig_IsComplement(pNode) ); - assert( Aig_NodeIsMuxType(pNode) ); - // get children - pNode0 = Aig_NodeFanin0(pNode); - pNode1 = Aig_NodeFanin1(pNode); - // find the control variable -// if ( pNode1->p1 == Fraig_Not(pNode2->p1) ) - if ( Aig_NodeFaninId0(pNode0) == Aig_NodeFaninId0(pNode1) && (Aig_NodeFaninC0(pNode0) ^ Aig_NodeFaninC0(pNode1)) ) - { -// if ( Fraig_IsComplement(pNode1->p1) ) - if ( Aig_NodeFaninC0(pNode0) ) - { // pNode2->p1 is positive phase of C - *ppNodeT = Aig_Not(Aig_NodeChild1(pNode1));//pNode2->p2); - *ppNodeE = Aig_Not(Aig_NodeChild1(pNode0));//pNode1->p2); - return Aig_NodeChild0(pNode1);//pNode2->p1; - } - else - { // pNode1->p1 is positive phase of C - *ppNodeT = Aig_Not(Aig_NodeChild1(pNode0));//pNode1->p2); - *ppNodeE = Aig_Not(Aig_NodeChild1(pNode1));//pNode2->p2); - return Aig_NodeChild0(pNode0);//pNode1->p1; - } - } -// else if ( pNode1->p1 == Fraig_Not(pNode2->p2) ) - else if ( Aig_NodeFaninId0(pNode0) == Aig_NodeFaninId1(pNode1) && (Aig_NodeFaninC0(pNode0) ^ Aig_NodeFaninC1(pNode1)) ) - { -// if ( Fraig_IsComplement(pNode1->p1) ) - if ( Aig_NodeFaninC0(pNode0) ) - { // pNode2->p2 is positive phase of C - *ppNodeT = Aig_Not(Aig_NodeChild0(pNode1));//pNode2->p1); - *ppNodeE = Aig_Not(Aig_NodeChild1(pNode0));//pNode1->p2); - return Aig_NodeChild1(pNode1);//pNode2->p2; - } - else - { // pNode1->p1 is positive phase of C - *ppNodeT = Aig_Not(Aig_NodeChild1(pNode0));//pNode1->p2); - *ppNodeE = Aig_Not(Aig_NodeChild0(pNode1));//pNode2->p1); - return Aig_NodeChild0(pNode0);//pNode1->p1; - } - } -// else if ( pNode1->p2 == Fraig_Not(pNode2->p1) ) - else if ( Aig_NodeFaninId1(pNode0) == Aig_NodeFaninId0(pNode1) && (Aig_NodeFaninC1(pNode0) ^ Aig_NodeFaninC0(pNode1)) ) - { -// if ( Fraig_IsComplement(pNode1->p2) ) - if ( Aig_NodeFaninC1(pNode0) ) - { // pNode2->p1 is positive phase of C - *ppNodeT = Aig_Not(Aig_NodeChild1(pNode1));//pNode2->p2); - *ppNodeE = Aig_Not(Aig_NodeChild0(pNode0));//pNode1->p1); - return Aig_NodeChild0(pNode1);//pNode2->p1; - } - else - { // pNode1->p2 is positive phase of C - *ppNodeT = Aig_Not(Aig_NodeChild0(pNode0));//pNode1->p1); - *ppNodeE = Aig_Not(Aig_NodeChild1(pNode1));//pNode2->p2); - return Aig_NodeChild1(pNode0);//pNode1->p2; - } - } -// else if ( pNode1->p2 == Fraig_Not(pNode2->p2) ) - else if ( Aig_NodeFaninId1(pNode0) == Aig_NodeFaninId1(pNode1) && (Aig_NodeFaninC1(pNode0) ^ Aig_NodeFaninC1(pNode1)) ) - { -// if ( Fraig_IsComplement(pNode1->p2) ) - if ( Aig_NodeFaninC1(pNode0) ) - { // pNode2->p2 is positive phase of C - *ppNodeT = Aig_Not(Aig_NodeChild0(pNode1));//pNode2->p1); - *ppNodeE = Aig_Not(Aig_NodeChild0(pNode0));//pNode1->p1); - return Aig_NodeChild1(pNode1);//pNode2->p2; - } - else - { // pNode1->p2 is positive phase of C - *ppNodeT = Aig_Not(Aig_NodeChild0(pNode0));//pNode1->p1); - *ppNodeE = Aig_Not(Aig_NodeChild0(pNode1));//pNode2->p1); - return Aig_NodeChild1(pNode0);//pNode1->p2; - } - } - assert( 0 ); // this is not MUX - return NULL; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/fraigClass.c b/src/sat/aig/fraigClass.c deleted file mode 100644 index a8df9a72..00000000 --- a/src/sat/aig/fraigClass.c +++ /dev/null @@ -1,320 +0,0 @@ -/**CFile**************************************************************** - - FileName [fraigClass.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: fraigClass.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" -#include "stmm.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static unsigned Aig_ManHashKey( unsigned * pData, int nWords, bool fPhase ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Creates the equivalence classes of patterns.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Vec_t * Aig_ManDeriveClassesFirst( Aig_Man_t * p, Aig_SimInfo_t * pInfo ) -{ - Vec_Vec_t * vClasses; // equivalence classes - stmm_table * tSim2Node; // temporary hash table hashing key into the class number - Aig_Node_t * pNode; - unsigned uKey; - int i, * pSpot, Entry, ClassNum; - assert( pInfo->Type == 1 ); - // fill in the hash table - tSim2Node = stmm_init_table( stmm_numcmp, stmm_numhash ); - vClasses = Vec_VecAlloc( 100 ); - // enumerate the nodes considered in the equivalence classes -// Aig_ManForEachNode( p, pNode, i ) - Vec_IntForEachEntry( p->vSat2Var, Entry, i ) - { - pNode = Aig_ManNode( p, Entry ); - - if ( Aig_NodeIsPo(pNode) ) - continue; - uKey = Aig_ManHashKey( Aig_SimInfoForNode(pInfo, pNode), pInfo->nWords, pNode->fPhase ); - if ( !stmm_find_or_add( tSim2Node, (char *)uKey, (char ***)&pSpot ) ) // does not exist - *pSpot = (pNode->Id << 1) | 1; // save the node, and do nothing - else if ( (*pSpot) & 1 ) // this is a node - { - // create the class - ClassNum = Vec_VecSize( vClasses ); - Vec_VecPush( vClasses, ClassNum, (void *)((*pSpot) >> 1) ); - Vec_VecPush( vClasses, ClassNum, (void *)pNode->Id ); - // save the class - *pSpot = (ClassNum << 1); - } - else // this is a class - { - ClassNum = ((*pSpot) >> 1); - Vec_VecPush( vClasses, ClassNum, (void *)pNode->Id ); - } - } - stmm_free_table( tSim2Node ); -/* - // print the classes - { - Vec_Ptr_t * vVec; - printf( "PI/PO = %4d/%4d. Nodes = %7d. SatVars = %7d. Non-trivial classes = %5d: \n", - Aig_ManPiNum(p), Aig_ManPoNum(p), - Aig_ManNodeNum(p) - Aig_ManPoNum(p), - Vec_IntSize(p->vSat2Var), Vec_VecSize(vClasses) ); - - Vec_VecForEachLevel( vClasses, vVec, i ) - printf( "%d ", Vec_PtrSize(vVec) ); - printf( "\n" ); - } -*/ - printf( "Classes = %6d. Pairs = %6d.\n", Vec_VecSize(vClasses), Vec_VecSizeSize(vClasses) - Vec_VecSize(vClasses) ); - return vClasses; -} - -/**Function************************************************************* - - Synopsis [Computes the hash key of the simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned Aig_ManHashKey( unsigned * pData, int nWords, bool fPhase ) -{ - static int Primes[10] = { 1009, 2207, 3779, 4001, 4877, 5381, 6427, 6829, 7213, 7919 }; - unsigned uKey; - int i; - uKey = 0; - if ( fPhase ) - for ( i = 0; i < nWords; i++ ) - uKey ^= i * Primes[i%10] * pData[i]; - else - for ( i = 0; i < nWords; i++ ) - uKey ^= i * Primes[i%10] * ~pData[i]; - return uKey; -} - - - -/**Function************************************************************* - - Synopsis [Splits the equivalence class.] - - Description [Given an equivalence class (vClass) and the simulation info, - split the class into two based on the info.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_ManSplitClass( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Int_t * vClass, Vec_Int_t * vClass2, Aig_Pattern_t * pPat ) -{ - int NodeId, i, k, w; - Aig_Node_t * pRoot, * pTemp; - unsigned * pRootData, * pTempData; - assert( Vec_IntSize(vClass) > 1 ); - assert( pInfo->nPatsCur == pPat->nBits ); -// printf( "Class = %5d. --> ", Vec_IntSize(vClass) ); - // clear storage for the new classes - Vec_IntClear( vClass2 ); - // get the root member of the class - pRoot = Aig_ManNode( p, Vec_IntEntry(vClass, 0) ); - pRootData = Aig_SimInfoForNode( pInfo, pRoot ); - // sort the class members: - // (1) with the same siminfo as pRoot remain in vClass - // (2) nodes with other siminfo go to vClass2 - k = 1; - Vec_IntForEachEntryStart( vClass, NodeId, i, 1 ) - { - NodeId = Vec_IntEntry(vClass, i); - pTemp = Aig_ManNode( p, NodeId ); - pTempData = Aig_SimInfoForNode( pInfo, pTemp ); - if ( pRoot->fPhase == pTemp->fPhase ) - { - for ( w = 0; w < pInfo->nWords; w++ ) - if ( pRootData[w] != pTempData[w] ) - break; - if ( w == pInfo->nWords ) // the same info - Vec_IntWriteEntry( vClass, k++, NodeId ); - else - { - Vec_IntPush( vClass2, NodeId ); - // record the diffs if they are not distinguished by the first pattern - if ( ((pRootData[0] ^ pTempData[0]) & 1) == 0 ) - for ( w = 0; w < pInfo->nWords; w++ ) - pPat->pData[w] |= (pRootData[w] ^ pTempData[w]); - } - } - else - { - for ( w = 0; w < pInfo->nWords; w++ ) - if ( pRootData[w] != ~pTempData[w] ) - break; - if ( w == pInfo->nWords ) // the same info - Vec_IntWriteEntry( vClass, k++, NodeId ); - else - { - Vec_IntPush( vClass2, NodeId ); - // record the diffs if they are not distinguished by the first pattern - if ( ((pRootData[0] ^ ~pTempData[0]) & 1) == 0 ) - for ( w = 0; w < pInfo->nWords; w++ ) - pPat->pData[w] |= (pRootData[w] ^ ~pTempData[w]); - } - } - } - Vec_IntShrink( vClass, k ); -// printf( "Class1 = %5d. Class2 = %5d.\n", Vec_IntSize(vClass), Vec_IntSize(vClass2) ); -} - -/**Function************************************************************* - - Synopsis [Updates the equivalence classes using the simulation info.] - - Description [Records successful simulation patterns into the pattern - storage.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_ManUpdateClasses( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Vec_t * vClasses, Aig_Pattern_t * pPatMask ) -{ - Vec_Ptr_t * vClass; - int i, k, fSplit = 0; - assert( Vec_VecSize(vClasses) > 0 ); - // collect patterns that lead to changes - Aig_PatternClean( pPatMask ); - // split the classes using the new symmetry info - Vec_VecForEachLevel( vClasses, vClass, i ) - { - if ( i == 0 ) - continue; - // split vClass into two parts (vClass and vClassTemp) - Aig_ManSplitClass( p, pInfo, (Vec_Int_t *)vClass, p->vClassTemp, pPatMask ); - // check if there is any splitting - if ( Vec_IntSize(p->vClassTemp) > 0 ) - fSplit = 1; - // skip the new class if it is empty or trivial - if ( Vec_IntSize(p->vClassTemp) < 2 ) - continue; - // consider replacing the current class with the new one - if ( Vec_PtrSize(vClass) == 1 ) - { - assert( vClasses->pArray[i] == vClass ); - vClasses->pArray[i] = p->vClassTemp; - p->vClassTemp = (Vec_Int_t *)vClass; - i--; - continue; - } - // add the new non-trival class in the end - Vec_PtrPush( (Vec_Ptr_t *)vClasses, p->vClassTemp ); - p->vClassTemp = Vec_IntAlloc( 10 ); - } - // free trivial classes - k = 0; - Vec_VecForEachLevel( vClasses, vClass, i ) - { - assert( Vec_PtrSize(vClass) > 0 ); - if ( Vec_PtrSize(vClass) == 1 ) - Vec_PtrFree(vClass); - else - vClasses->pArray[k++] = vClass; - } - Vec_PtrShrink( (Vec_Ptr_t *)vClasses, k ); - // catch the patterns which led to splitting - printf( "Classes = %6d. Pairs = %6d. Patterns = %3d.\n", - Vec_VecSize(vClasses), - Vec_VecSizeSize(vClasses) - Vec_VecSize(vClasses), - Vec_PtrSize(p->vPats) ); - return fSplit; -} - -/**Function************************************************************* - - Synopsis [Collects useful patterns.] - - Description [If the flag fAddToVector is 1, creates and adds new patterns - to the internal storage of patterns.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_ManCollectPatterns( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Aig_Pattern_t * pMask, Vec_Ptr_t * vPats ) -{ - Aig_SimInfo_t * pInfoRes = p->pInfo; - Aig_Pattern_t * pPatNew; - Aig_Node_t * pNode; - int i, k; - - assert( Aig_InfoHasBit(pMask->pData, 0) == 0 ); - for ( i = 0; i < pMask->nBits; i++ ) - { - if ( vPats && Vec_PtrSize(vPats) >= p->nPatsMax ) - break; - if ( i == 0 || Aig_InfoHasBit(pMask->pData, i) ) - { - // expand storage if needed - if ( pInfoRes->nPatsCur == pInfoRes->nPatsMax ) - Aig_SimInfoResize( pInfoRes ); - // create a new pattern - if ( vPats ) - { - pPatNew = Aig_PatternAlloc( Aig_ManPiNum(p) ); - Aig_PatternClean( pPatNew ); - } - // go through the PIs - Aig_ManForEachPi( p, pNode, k ) - { - if ( Aig_InfoHasBit( Aig_SimInfoForNode(pInfo, pNode), i ) ) - { - Aig_InfoSetBit( Aig_SimInfoForPi(pInfoRes, k), pInfoRes->nPatsCur ); - if ( vPats ) Aig_InfoSetBit( pPatNew->pData, k ); - } - } - // store the new pattern - if ( vPats ) Vec_PtrPush( vPats, pPatNew ); - // increment the number of patterns stored - pInfoRes->nPatsCur++; - } - } -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/fraigCnf.c b/src/sat/aig/fraigCnf.c deleted file mode 100644 index 913165b2..00000000 --- a/src/sat/aig/fraigCnf.c +++ /dev/null @@ -1,476 +0,0 @@ -/**CFile**************************************************************** - - FileName [fraigCnf.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: fraigCnf.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Adds trivial clause.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_ClauseTriv( solver * pSat, Aig_Node_t * pNode, Vec_Int_t * vVars ) -{ -//printf( "Adding triv %d. %d\n", Aig_Regular(pNode)->Id, (int)pSat->solver_stats.clauses ); - vVars->nSize = 0; - Vec_IntPush( vVars, toLitCond( Aig_Regular(pNode)->Data, Aig_IsComplement(pNode) ) ); -// Vec_IntPush( vVars, toLitCond( (int)Aig_Regular(pNode)->Id, Aig_IsComplement(pNode) ) ); - return solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); -} - -/**Function************************************************************* - - Synopsis [Adds trivial clause.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_ClauseAnd( solver * pSat, Aig_Node_t * pNode, Vec_Ptr_t * vSuper, Vec_Int_t * vVars ) -{ - int fComp1, Var, Var1, i; -//printf( "Adding AND %d. (%d) %d\n", pNode->Id, vSuper->nSize+1, (int)pSat->solver_stats.clauses ); - - assert( !Aig_IsComplement( pNode ) ); - assert( Aig_NodeIsAnd( pNode ) ); - -// nVars = solver_nvars(pSat); - Var = pNode->Data; -// Var = pNode->Id; - -// assert( Var < nVars ); - for ( i = 0; i < vSuper->nSize; i++ ) - { - // get the predecessor nodes - // get the complemented attributes of the nodes - fComp1 = Aig_IsComplement(vSuper->pArray[i]); - // determine the variable numbers - Var1 = Aig_Regular(vSuper->pArray[i])->Data; -// Var1 = (int)Aig_Regular(vSuper->pArray[i])->Id; - - // check that the variables are in the SAT manager -// assert( Var1 < nVars ); - - // suppose the AND-gate is A * B = C - // add !A => !C or A + !C - // fprintf( pFile, "%d %d 0%c", Var1, -Var, 10 ); - vVars->nSize = 0; - Vec_IntPush( vVars, toLitCond(Var1, fComp1) ); - Vec_IntPush( vVars, toLitCond(Var, 1 ) ); - if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) ) - return 0; - } - - // add A & B => C or !A + !B + C -// fprintf( pFile, "%d %d %d 0%c", -Var1, -Var2, Var, 10 ); - vVars->nSize = 0; - for ( i = 0; i < vSuper->nSize; i++ ) - { - // get the predecessor nodes - // get the complemented attributes of the nodes - fComp1 = Aig_IsComplement(vSuper->pArray[i]); - // determine the variable numbers - Var1 = Aig_Regular(vSuper->pArray[i])->Data; -// Var1 = (int)Aig_Regular(vSuper->pArray[i])->Id; - // add this variable to the array - Vec_IntPush( vVars, toLitCond(Var1, !fComp1) ); - } - Vec_IntPush( vVars, toLitCond(Var, 0) ); - return solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); -} - -/**Function************************************************************* - - Synopsis [Adds trivial clause.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_ClauseMux( solver * pSat, Aig_Node_t * pNode, Aig_Node_t * pNodeC, Aig_Node_t * pNodeT, Aig_Node_t * pNodeE, Vec_Int_t * vVars ) -{ - int VarF, VarI, VarT, VarE, fCompT, fCompE; -//printf( "Adding mux %d. %d\n", pNode->Id, (int)pSat->solver_stats.clauses ); - - assert( !Aig_IsComplement( pNode ) ); - assert( Aig_NodeIsMuxType( pNode ) ); - // get the variable numbers - VarF = pNode->Data; - VarI = pNodeC->Data; - VarT = Aig_Regular(pNodeT)->Data; - VarE = Aig_Regular(pNodeE)->Data; -// VarF = (int)pNode->Id; -// VarI = (int)pNodeC->Id; -// VarT = (int)Aig_Regular(pNodeT)->Id; -// VarE = (int)Aig_Regular(pNodeE)->Id; - - // get the complementation flags - fCompT = Aig_IsComplement(pNodeT); - fCompE = Aig_IsComplement(pNodeE); - - // f = ITE(i, t, e) - // i' + t' + f - // i' + t + f' - // i + e' + f - // i + e + f' - // create four clauses - vVars->nSize = 0; - Vec_IntPush( vVars, toLitCond(VarI, 1) ); - Vec_IntPush( vVars, toLitCond(VarT, 1^fCompT) ); - Vec_IntPush( vVars, toLitCond(VarF, 0) ); - if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) ) - return 0; - vVars->nSize = 0; - Vec_IntPush( vVars, toLitCond(VarI, 1) ); - Vec_IntPush( vVars, toLitCond(VarT, 0^fCompT) ); - Vec_IntPush( vVars, toLitCond(VarF, 1) ); - if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) ) - return 0; - vVars->nSize = 0; - Vec_IntPush( vVars, toLitCond(VarI, 0) ); - Vec_IntPush( vVars, toLitCond(VarE, 1^fCompE) ); - Vec_IntPush( vVars, toLitCond(VarF, 0) ); - if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) ) - return 0; - vVars->nSize = 0; - Vec_IntPush( vVars, toLitCond(VarI, 0) ); - Vec_IntPush( vVars, toLitCond(VarE, 0^fCompE) ); - Vec_IntPush( vVars, toLitCond(VarF, 1) ); - if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) ) - return 0; - - if ( VarT == VarE ) - { -// assert( fCompT == !fCompE ); - return 1; - } - - // two additional clauses - // t' & e' -> f' t + e + f' - // t & e -> f t' + e' + f - vVars->nSize = 0; - Vec_IntPush( vVars, toLitCond(VarT, 0^fCompT) ); - Vec_IntPush( vVars, toLitCond(VarE, 0^fCompE) ); - Vec_IntPush( vVars, toLitCond(VarF, 1) ); - if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) ) - return 0; - vVars->nSize = 0; - Vec_IntPush( vVars, toLitCond(VarT, 1^fCompT) ); - Vec_IntPush( vVars, toLitCond(VarE, 1^fCompE) ); - Vec_IntPush( vVars, toLitCond(VarF, 0) ); - return solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); -} - -/**Function************************************************************* - - Synopsis [Returns the array of nodes to be combined into one multi-input AND-gate.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_ClauseCollectSupergate_rec( Aig_Node_t * pNode, Vec_Ptr_t * vSuper, int fFirst, int fStopAtMux ) -{ - int RetValue1, RetValue2, i; - // check if the node is visited - if ( Aig_Regular(pNode)->fMarkB ) - { - // check if the node occurs in the same polarity - for ( i = 0; i < vSuper->nSize; i++ ) - if ( vSuper->pArray[i] == pNode ) - return 1; - // check if the node is present in the opposite polarity - for ( i = 0; i < vSuper->nSize; i++ ) - if ( vSuper->pArray[i] == Aig_Not(pNode) ) - return -1; - assert( 0 ); - return 0; - } - // if the new node is complemented or a PI, another gate begins - if ( !fFirst ) - if ( Aig_IsComplement(pNode) || !Aig_NodeIsAnd(pNode) || Aig_NodeRefs(pNode) > 1 || fStopAtMux && Aig_NodeIsMuxType(pNode) ) - { - Vec_PtrPush( vSuper, pNode ); - Aig_Regular(pNode)->fMarkB = 1; - return 0; - } - assert( !Aig_IsComplement(pNode) ); - assert( Aig_NodeIsAnd(pNode) ); - // go through the branches - RetValue1 = Aig_ClauseCollectSupergate_rec( Aig_NodeChild0(pNode), vSuper, 0, fStopAtMux ); - RetValue2 = Aig_ClauseCollectSupergate_rec( Aig_NodeChild1(pNode), vSuper, 0, fStopAtMux ); - if ( RetValue1 == -1 || RetValue2 == -1 ) - return -1; - // return 1 if at least one branch has a duplicate - return RetValue1 || RetValue2; -} - -/**Function************************************************************* - - Synopsis [Returns the array of nodes to be combined into one multi-input AND-gate.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_ClauseCollectSupergate( Aig_Node_t * pNode, int fStopAtMux, Vec_Ptr_t * vNodes ) -{ - int RetValue, i; - assert( !Aig_IsComplement(pNode) ); - // collect the nodes in the implication supergate - Vec_PtrClear( vNodes ); - RetValue = Aig_ClauseCollectSupergate_rec( pNode, vNodes, 1, fStopAtMux ); - assert( vNodes->nSize > 1 ); - // unmark the visited nodes - for ( i = 0; i < vNodes->nSize; i++ ) - Aig_Regular((Aig_Node_t *)vNodes->pArray[i])->fMarkB = 0; - // if we found the node and its complement in the same implication supergate, - // return empty set of nodes (meaning that we should use constant-0 node) - if ( RetValue == -1 ) - vNodes->nSize = 0; -} - - -/**Function************************************************************* - - Synopsis [Sets up the SAT solver.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_ClauseCreateCnfInt( solver * pSat, Aig_Man_t * pNtk ) -{ - Aig_Node_t * pNode, * pFanin, * pNodeC, * pNodeT, * pNodeE; - Vec_Ptr_t * vNodes, * vSuper; - Vec_Int_t * vVars; - int i, k, fUseMuxes = 1; - - // start the data structures - vNodes = Vec_PtrAlloc( 1000 ); // the nodes corresponding to vars in the solver - vSuper = Vec_PtrAlloc( 100 ); // the nodes belonging to the given implication supergate - vVars = Vec_IntAlloc( 100 ); // the temporary array for variables in the clause - - // add the clause for the constant node - pNode = Aig_ManConst1(pNtk); - pNode->fMarkA = 1; - pNode->Data = vNodes->nSize; - Vec_PtrPush( vNodes, pNode ); - Aig_ClauseTriv( pSat, pNode, vVars ); - - // collect the nodes that need clauses and top-level assignments - Aig_ManForEachPo( pNtk, pNode, i ) - { - // get the fanin - pFanin = Aig_NodeFanin0(pNode); - // create the node's variable - if ( pFanin->fMarkA == 0 ) - { - pFanin->fMarkA = 1; - pFanin->Data = vNodes->nSize; - Vec_PtrPush( vNodes, pFanin ); - } - // add the trivial clause - if ( !Aig_ClauseTriv( pSat, Aig_NodeChild0(pNode), vVars ) ) - return 0; - } - - // add the clauses - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - assert( !Aig_IsComplement(pNode) ); - if ( !Aig_NodeIsAnd(pNode) ) - continue; -//printf( "%d ", pNode->Id ); - - // add the clauses - if ( fUseMuxes && Aig_NodeIsMuxType(pNode) ) - { - pNode->pMan->nMuxes++; - pNodeC = Aig_NodeRecognizeMux( pNode, &pNodeT, &pNodeE ); - Vec_PtrClear( vSuper ); - Vec_PtrPush( vSuper, pNodeC ); - Vec_PtrPush( vSuper, pNodeT ); - Vec_PtrPush( vSuper, pNodeE ); - // add the fanin nodes to explore - Vec_PtrForEachEntry( vSuper, pFanin, k ) - { - pFanin = Aig_Regular(pFanin); - if ( pFanin->fMarkA == 0 ) - { - pFanin->fMarkA = 1; - pFanin->Data = vNodes->nSize; - Vec_PtrPush( vNodes, pFanin ); - } - } - // add the clauses - if ( !Aig_ClauseMux( pSat, pNode, pNodeC, pNodeT, pNodeE, vVars ) ) - return 0; - } - else - { - // get the supergate - Aig_ClauseCollectSupergate( pNode, fUseMuxes, vSuper ); - // add the fanin nodes to explore - Vec_PtrForEachEntry( vSuper, pFanin, k ) - { - pFanin = Aig_Regular(pFanin); - if ( pFanin->fMarkA == 0 ) - { - pFanin->fMarkA = 1; - pFanin->Data = vNodes->nSize; - Vec_PtrPush( vNodes, pFanin ); - } - } - // add the clauses - if ( vSuper->nSize == 0 ) - { - if ( !Aig_ClauseTriv( pSat, Aig_Not(pNode), vVars ) ) - return 0; - } - else - { - if ( !Aig_ClauseAnd( pSat, pNode, vSuper, vVars ) ) - return 0; - } - } - } - - // delete - Vec_IntFree( vVars ); - Vec_PtrFree( vNodes ); - Vec_PtrFree( vSuper ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Sets up the SAT solver.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -solver * Aig_ClauseCreateCnf( Aig_Man_t * pMan ) -{ - solver * pSat; - Aig_Node_t * pNode; - int RetValue, i, clk = clock(); - // clean the marks - Aig_ManForEachNode( pMan, pNode, i ) - pNode->fMarkA = 0, pNode->Data = -1; - // create the solver - pMan->nMuxes = 0; - pSat = solver_new(); - RetValue = Aig_ClauseCreateCnfInt( pSat, pMan ); -// Asat_SolverWriteDimacs( pSat, "temp_sat.cnf", NULL, NULL, 1 ); - if ( RetValue == 0 ) - { - solver_delete(pSat); - Aig_ManForEachNode( pMan, pNode, i ) - pNode->fMarkA = 0; - return NULL; - } - printf( "The number of MUXes detected = %d (%5.2f %% of logic). ", - pNode->pMan->nMuxes, 300.0*pNode->pMan->nMuxes/Aig_ManNodeNum(pMan) ); - PRT( "Creating solver", clock() - clk ); - return pSat; -} - -/**Function************************************************************* - - Synopsis [Starts the SAT solver.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_ProofType_t Aig_ClauseSolverStart( Aig_Man_t * pMan ) -{ - Aig_Node_t * pNode; - int i; - - // make sure it has one PO - if ( Aig_ManPoNum(pMan) != 1 ) - { - printf( "The miter has other than 1 output.\n" ); - return AIG_PROOF_FAIL; - } - - // get the solver - assert( pMan->pSat == NULL ); - pMan->pSat = Aig_ClauseCreateCnf( pMan ); - if ( pMan->pSat == NULL ) - return AIG_PROOF_UNSAT; - - // get the variable mappings - pMan->vVar2Sat = Vec_IntStart( Aig_ManNodeNum(pMan) ); - pMan->vSat2Var = Vec_IntStart( solver_nvars(pMan->pSat) ); - Aig_ManForEachNode( pMan, pNode, i ) - { - Vec_IntWriteEntry( pMan->vVar2Sat, i, pNode->Data ); - if ( pNode->Data >= 0 ) Vec_IntWriteEntry( pMan->vSat2Var, pNode->Data, i ); - } - // get the SAT var numbers of the primary inputs - pMan->vPiSatNums = Vec_IntAlloc( Aig_ManPiNum(pMan) ); - Aig_ManForEachPi( pMan, pNode, i ) - Vec_IntPush( pMan->vPiSatNums, (pNode->Data >= 0)? pNode->Data : 0 ); - return AIG_PROOF_NONE; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/fraigCore.c b/src/sat/aig/fraigCore.c deleted file mode 100644 index 03781180..00000000 --- a/src/sat/aig/fraigCore.c +++ /dev/null @@ -1,129 +0,0 @@ -/**CFile**************************************************************** - - FileName [fraigCore.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: fraigCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static Aig_ProofType_t Aig_FraigProveOutput( Aig_Man_t * pMan ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Top-level equivalence checking procedure.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_ProofType_t Aig_FraigProve( Aig_Man_t * pMan ) -{ - Aig_ProofType_t RetValue; - int clk, status; - - // create the solver - RetValue = Aig_ClauseSolverStart( pMan ); - if ( RetValue != AIG_PROOF_NONE ) - return RetValue; - // perform solving - - // simplify the problem - clk = clock(); - status = solver_simplify(pMan->pSat); - if ( status == 0 ) - { -// printf( "The problem is UNSATISFIABLE after simplification.\n" ); - return AIG_PROOF_UNSAT; - } - - // try to prove the output - RetValue = Aig_FraigProveOutput( pMan ); - if ( RetValue != AIG_PROOF_TIMEOUT ) - return RetValue; - - // create equivalence classes - Aig_EngineSimulateRandomFirst( pMan ); - // reduce equivalence classes using simulation - Aig_EngineSimulateFirst( pMan ); - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Top-level equivalence checking procedure.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_ProofType_t Aig_FraigProveOutput( Aig_Man_t * pMan ) -{ - Aig_ProofType_t RetValue; - int clk, status; - - // solve the miter - clk = clock(); - pMan->pSat->verbosity = pMan->pParam->fSatVerbose; - status = solver_solve( pMan->pSat, NULL, NULL, 0, 0 );//pMan->pParam->nConfLimit, pMan->pParam->nInsLimit ); - if ( status == l_Undef ) - { -// printf( "The problem timed out.\n" ); - RetValue = AIG_PROOF_TIMEOUT; - } - else if ( status == l_True ) - { -// printf( "The problem is SATISFIABLE.\n" ); - RetValue = AIG_PROOF_SAT; - } - else if ( status == l_False ) - { -// printf( "The problem is UNSATISFIABLE.\n" ); - RetValue = AIG_PROOF_UNSAT; - } - else - assert( 0 ); -// PRT( "SAT solver time", clock() - clk ); - - // if the problem is SAT, get the counterexample - if ( status == l_True ) - { - if ( pMan->pModel ) free( pMan->pModel ); - pMan->pModel = solver_get_model( pMan->pSat, pMan->vPiSatNums->pArray, pMan->vPiSatNums->nSize ); - printf( "%d %d %d %d\n", pMan->pModel[0], pMan->pModel[1], pMan->pModel[2], pMan->pModel[3] ); - } - return RetValue; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/fraigEngine.c b/src/sat/aig/fraigEngine.c deleted file mode 100644 index 17468e8f..00000000 --- a/src/sat/aig/fraigEngine.c +++ /dev/null @@ -1,174 +0,0 @@ -/**CFile**************************************************************** - - FileName [fraigEngine.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: fraigEngine.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Simulates all nodes using random simulation for the first time.] - - Description [Assigns the original simulation info and the storage for the - future simulation info.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_EngineSimulateRandomFirst( Aig_Man_t * p ) -{ - Aig_SimInfo_t * pInfoPi, * pInfoAll; - assert( !p->pInfo && !p->pInfoTemp ); - // create random PI info - pInfoPi = Aig_SimInfoAlloc( Aig_ManPiNum(p), p->pParam->nPatsRand, 0 ); - Aig_SimInfoRandom( pInfoPi ); - // allocate sim info for all nodes - pInfoAll = Aig_SimInfoAlloc( Aig_ManNodeNum(p), p->pParam->nPatsRand, 1 ); - // simulate though the circuit - Aig_ManSimulateInfo( p, pInfoPi, pInfoAll ); - // detect classes - p->vClasses = Aig_ManDeriveClassesFirst( p, pInfoAll ); - Aig_SimInfoFree( pInfoAll ); - // save simulation info - p->pInfo = pInfoPi; - p->pInfoPi = Aig_SimInfoAlloc( Aig_ManPiNum(p), Aig_ManPiNum(p)+1, 0 ); - p->pInfoTemp = Aig_SimInfoAlloc( Aig_ManNodeNum(p), Aig_ManPiNum(p)+1, 1 ); - p->pPatMask = Aig_PatternAlloc( Aig_ManPiNum(p)+1 ); -} - -/**Function************************************************************* - - Synopsis [Starts the simulation engine for the first time.] - - Description [Tries several random patterns and their distance-1 - minterms hoping to get simulation started.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_EngineSimulateFirst( Aig_Man_t * p ) -{ - Aig_Pattern_t * pPat; - int i, Counter; - - // simulate the pattern of all zeros - pPat = Aig_PatternAlloc( Aig_ManPiNum(p) ); - Aig_PatternClean( pPat ); - Vec_PtrPush( p->vPats, pPat ); - if ( !Aig_EngineSimulate( p ) ) - return; - - // simulate the pattern of all ones - pPat = Aig_PatternAlloc( Aig_ManPiNum(p) ); - Aig_PatternFill( pPat ); - Vec_PtrPush( p->vPats, pPat ); - if ( !Aig_EngineSimulate( p ) ) - return; - - // simulate random until the number of new patterns is reasonable - do { - // generate random PI siminfo - Aig_SimInfoRandom( p->pInfoPi ); - // simulate this info - Aig_ManSimulateInfo( p, p->pInfoPi, p->pInfoTemp ); - // split the classes and collect the new patterns - if ( Aig_ManUpdateClasses( p, p->pInfoTemp, p->vClasses, p->pPatMask ) ) - Aig_ManCollectPatterns( p, p->pInfoTemp, p->pPatMask, NULL ); - if ( Vec_VecSize(p->vClasses) == 0 ) - return; - // count the number of useful patterns - Counter = Aig_PatternCount(p->pPatMask); - } - while ( Counter > p->nPatsMax/2 ); - - // perform targetted simulation - for ( i = 0; i < 3; i++ ) - { - assert( Vec_PtrSize(p->vPats) == 0 ); - // generate random PI siminfo - Aig_SimInfoRandom( p->pInfoPi ); - // simulate this info - Aig_ManSimulateInfo( p, p->pInfoPi, p->pInfoTemp ); - // split the classes and collect the new patterns - if ( Aig_ManUpdateClasses( p, p->pInfoTemp, p->vClasses, p->pPatMask ) ) - Aig_ManCollectPatterns( p, p->pInfoTemp, p->pPatMask, p->vPats ); - if ( Vec_VecSize(p->vClasses) == 0 ) - return; - // simulate the remaining patters - if ( Vec_PtrSize(p->vPats) > 0 ) - if ( !Aig_EngineSimulate( p ) ) - return; - } -} - -/**Function************************************************************* - - Synopsis [Implements intelligent simulation engine.] - - Description [Assumes that the good simulation patterns have been - assigned (p->vPats). Simulates until all of them are gone. Returns 1 - if some classes are left. Returns 0 if there is no more classes.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_EngineSimulate( Aig_Man_t * p ) -{ - Aig_Pattern_t * pPat; - if ( Vec_VecSize(p->vClasses) == 0 ) - return 0; - assert( Vec_PtrSize(p->vPats) > 0 ); - // process patterns - while ( Vec_PtrSize(p->vPats) > 0 && Vec_VecSize(p->vClasses) > 0 ) - { - // get the pattern and create new siminfo - pPat = Vec_PtrPop(p->vPats); - assert( pPat->nBits == Aig_ManPiNum(p) ); - // create the new siminfo - Aig_SimInfoFromPattern( p->pInfoPi, pPat ); - // free the pattern - Aig_PatternFree( pPat ); - - // simulate this info - Aig_ManSimulateInfo( p, p->pInfoPi, p->pInfoTemp ); - // split the classes and collect the new patterns - if ( Aig_ManUpdateClasses( p, p->pInfoTemp, p->vClasses, p->pPatMask ) ) - Aig_ManCollectPatterns( p, p->pInfoTemp, p->pPatMask, p->vPats ); - } - return Vec_VecSize(p->vClasses) > 0; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/fraigProve.c b/src/sat/aig/fraigProve.c deleted file mode 100644 index 901f2fe2..00000000 --- a/src/sat/aig/fraigProve.c +++ /dev/null @@ -1,47 +0,0 @@ -/**CFile**************************************************************** - - FileName [fraigProve.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: fraigProve.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/fraigSim.c b/src/sat/aig/fraigSim.c deleted file mode 100644 index 6d4f214c..00000000 --- a/src/sat/aig/fraigSim.c +++ /dev/null @@ -1,361 +0,0 @@ -/**CFile**************************************************************** - - FileName [fraigSim.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: fraigSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Simulates all nodes using the given simulation info.] - - Description [Returns the simulation info for all nodes.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_ManSimulateInfo( Aig_Man_t * p, Aig_SimInfo_t * pInfoPi, Aig_SimInfo_t * pInfoAll ) -{ - Aig_Node_t * pNode; - unsigned * pDataPi, * pDataPo, * pData0, * pData1, * pDataAnd; - int i, k, fComp0, fComp1; - - assert( !pInfoPi->Type ); // PI siminfo - // set the constant sim info - pData1 = Aig_SimInfoForNode( pInfoAll, p->pConst1 ); - for ( k = 0; k < pInfoPi->nWords; k++ ) - pData1[k] = ~((unsigned)0); - // set the PI siminfo - Aig_ManForEachPi( p, pNode, i ) - { - pDataPi = Aig_SimInfoForPi( pInfoPi, i ); - pDataAnd = Aig_SimInfoForNode( pInfoAll, pNode ); - for ( k = 0; k < pInfoPi->nWords; k++ ) - pDataAnd[k] = pDataPi[k]; - } - // simulate the nodes - Aig_ManForEachAnd( p, pNode, i ) - { - pData0 = Aig_SimInfoForNode( pInfoAll, Aig_NodeFanin0(pNode) ); - pData1 = Aig_SimInfoForNode( pInfoAll, Aig_NodeFanin1(pNode) ); - pDataAnd = Aig_SimInfoForNode( pInfoAll, pNode ); - fComp0 = Aig_NodeFaninC0(pNode); - fComp1 = Aig_NodeFaninC1(pNode); - if ( fComp0 && fComp1 ) - for ( k = 0; k < pInfoPi->nWords; k++ ) - pDataAnd[k] = ~pData0[k] & ~pData1[k]; - else if ( fComp0 ) - for ( k = 0; k < pInfoPi->nWords; k++ ) - pDataAnd[k] = ~pData0[k] & pData1[k]; - else if ( fComp1 ) - for ( k = 0; k < pInfoPi->nWords; k++ ) - pDataAnd[k] = pData0[k] & ~pData1[k]; - else - for ( k = 0; k < pInfoPi->nWords; k++ ) - pDataAnd[k] = pData0[k] & pData1[k]; - } - // derive the PO siminfo - Aig_ManForEachPo( p, pNode, i ) - { - pDataPo = Aig_SimInfoForNode( pInfoAll, pNode ); - pDataAnd = Aig_SimInfoForNode( pInfoAll, Aig_NodeFanin0(pNode) ); - if ( Aig_NodeFaninC0(pNode) ) - for ( k = 0; k < pInfoPi->nWords; k++ ) - pDataPo[k] = ~pDataAnd[k]; - else - for ( k = 0; k < pInfoPi->nWords; k++ ) - pDataPo[k] = pDataAnd[k]; - } -} - - - -/**Function************************************************************* - - Synopsis [Allocates the simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_SimInfo_t * Aig_SimInfoAlloc( int nNodes, int nBits, int Type ) -{ - Aig_SimInfo_t * p; - p = ALLOC( Aig_SimInfo_t, 1 ); - memset( p, 0, sizeof(Aig_SimInfo_t) ); - p->Type = Type; - p->nNodes = nNodes; - p->nWords = Aig_BitWordNum(nBits); - p->nPatsCur = nBits; - p->nPatsMax = p->nWords * sizeof(unsigned) * 8; - p->pData = ALLOC( unsigned, nNodes * p->nWords ); - return p; -} - -/**Function************************************************************* - - Synopsis [Sets the simulation info to zero.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_SimInfoClean( Aig_SimInfo_t * p ) -{ - int i, Size = p->nNodes * p->nWords; - p->nPatsCur = 0; - for ( i = 0; i < Size; i++ ) - p->pData[i] = 0; -} - -/**Function************************************************************* - - Synopsis [Sets the random simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_SimInfoRandom( Aig_SimInfo_t * p ) -{ - int i, Size = p->nNodes * p->nWords; - unsigned * pData; - for ( i = 0; i < Size; i++ ) - p->pData[i] = ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand())); - // make sure the first bit of all nodes is 0 - for ( i = 0; i < p->nNodes; i++ ) - { - pData = p->pData + p->nWords * i; - *pData <<= 1; - } -} - -/**Function************************************************************* - - Synopsis [Sets the random simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_SimInfoFromPattern( Aig_SimInfo_t * p, Aig_Pattern_t * pPat ) -{ - unsigned * pData; - int i, k; - assert( p->Type == 0 ); - assert( p->nPatsCur == pPat->nBits+1 ); - for ( i = 0; i < p->nPatsCur; i++ ) - { - // get the pointer to the bitdata for node i - pData = p->pData + p->nWords * i; - // fill in the bit data according to the pattern - if ( Aig_InfoHasBit(pPat->pData, i) ) // PI has bit set to 1 - for ( k = 0; k < p->nWords; k++ ) - pData[k] = ~((unsigned)0); - else - for ( k = 0; k < p->nWords; k++ ) - pData[k] = 0; - // flip one bit, starting from the first pattern - if ( i ) Aig_InfoXorBit( pData, i-1 ); - } -} - -/**Function************************************************************* - - Synopsis [Resizes the simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_SimInfoResize( Aig_SimInfo_t * p ) -{ - unsigned * pData; - int i, k; - assert( p->nPatsCur == p->nPatsMax ); - pData = ALLOC( unsigned, 2 * p->nNodes * p->nWords ); - for ( i = 0; i < p->nNodes; i++ ) - { - for ( k = 0; k < p->nWords; k++ ) - pData[2 * p->nWords * i + k] = p->pData[p->nWords * i + k]; - for ( k = 0; k < p->nWords; k++ ) - pData[2 * p->nWords * i + k + p->nWords] = 0; - } - p->nWords *= 2; - p->nPatsMax *= 2; - free( p->pData ); - p->pData = pData; -} - -/**Function************************************************************* - - Synopsis [Deallocates the simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_SimInfoFree( Aig_SimInfo_t * p ) -{ - free( p->pData ); - free( p ); -} - - -/**Function************************************************************* - - Synopsis [Allocates the simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Pattern_t * Aig_PatternAlloc( int nBits ) -{ - Aig_Pattern_t * pPat; - pPat = ALLOC( Aig_Pattern_t, 1 ); - memset( pPat, 0, sizeof(Aig_Pattern_t) ); - pPat->nBits = nBits; - pPat->nWords = Aig_BitWordNum(nBits); - pPat->pData = ALLOC( unsigned, pPat->nWords ); - return pPat; -} - -/**Function************************************************************* - - Synopsis [Cleans the pattern.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_PatternClean( Aig_Pattern_t * pPat ) -{ - memset( pPat->pData, 0, sizeof(unsigned) * pPat->nWords ); -} - -/**Function************************************************************* - - Synopsis [Cleans the pattern.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_PatternFill( Aig_Pattern_t * pPat ) -{ - memset( pPat->pData, 0xff, sizeof(unsigned) * pPat->nWords ); -} - -/**Function************************************************************* - - Synopsis [Sets the random pattern.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_PatternRandom( Aig_Pattern_t * pPat ) -{ - int i; - for ( i = 0; i < pPat->nWords; i++ ) - pPat->pData[i] = ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand())); -} - -/**Function************************************************************* - - Synopsis [Counts the number of 1s in the pattern.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_PatternCount( Aig_Pattern_t * pPat ) -{ - int i, Counter = 0; - for ( i = 0; i < pPat->nBits; i++ ) - Counter += Aig_InfoHasBit( pPat->pData, i ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [Deallocates the pattern.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_PatternFree( Aig_Pattern_t * pPat ) -{ - free( pPat->pData ); - free( pPat ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/fraigSolver.c b/src/sat/aig/fraigSolver.c deleted file mode 100644 index 12502951..00000000 --- a/src/sat/aig/fraigSolver.c +++ /dev/null @@ -1,47 +0,0 @@ -/**CFile**************************************************************** - - FileName [fraigSolver.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: fraigSolver.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/fraigTrav.c b/src/sat/aig/fraigTrav.c deleted file mode 100644 index d5a09259..00000000 --- a/src/sat/aig/fraigTrav.c +++ /dev/null @@ -1,47 +0,0 @@ -/**CFile**************************************************************** - - FileName [fraigTrav.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: fraigTrav.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/rwrMffc.c b/src/sat/aig/rwrMffc.c deleted file mode 100644 index 663534b3..00000000 --- a/src/sat/aig/rwrMffc.c +++ /dev/null @@ -1,303 +0,0 @@ -/**CFile**************************************************************** - - FileName [rwrMffc.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [Procedures working with Maximum Fanout-Free Cones.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: rwrMffc.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -extern int Aig_NodeDeref_rec( Aig_Node_t * pNode ); -extern int Aig_NodeRef_rec( Aig_Node_t * pNode ); -extern void Aig_NodeMffsConeSupp( Aig_Node_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp ); -extern void Aig_NodeFactorConeSupp( Aig_Node_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp ); - - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_MffcTest( Aig_Man_t * pMan ) -{ - Aig_Node_t * pNode, * pNodeA, * pNodeB, * pNodeC, * pLeaf; - Vec_Ptr_t * vCone, * vSupp; - int i, k;//, nNodes1, nNodes2; - int nSizes = 0; - int nCones = 0; - int nMuxes = 0; - int nExors = 0; - - vCone = Vec_PtrAlloc( 100 ); - vSupp = Vec_PtrAlloc( 100 ); - - // mark the multiple-fanout nodes - Aig_ManForEachAnd( pMan, pNode, i ) - if ( pNode->nRefs > 1 ) - pNode->fMarkA = 1; - // unmark the control inputs of MUXes and inputs of EXOR gates - Aig_ManForEachAnd( pMan, pNode, i ) - { - if ( !Aig_NodeIsMuxType(pNode) ) - continue; - - pNodeC = Aig_NodeRecognizeMux( pNode, &pNodeA, &pNodeB ); - // if real children are used, skip - if ( Aig_NodeFanin0(pNode)->nRefs > 1 || Aig_NodeFanin1(pNode)->nRefs > 1 ) - continue; -/* - - if ( pNodeC->nRefs == 2 ) - pNodeC->fMarkA = 0; - if ( Aig_Regular(pNodeA) == Aig_Regular(pNodeB) && Aig_Regular(pNodeA)->nRefs == 2 ) - Aig_Regular(pNodeA)->fMarkA = 0; -*/ - - if ( Aig_Regular(pNodeA) == Aig_Regular(pNodeB) ) - nExors++; - else - nMuxes++; - } - // mark the PO drivers - Aig_ManForEachPo( pMan, pNode, i ) - { - Aig_NodeFanin0(pNode)->fMarkA = 1; - Aig_NodeFanin0(pNode)->fMarkB = 1; - } - - - // print sizes of MFFCs - Aig_ManForEachAnd( pMan, pNode, i ) - { - if ( !pNode->fMarkA ) - continue; - -// nNodes1 = Aig_NodeDeref_rec( pNode ); -// Aig_NodeMffsConeSupp( pNode, vCone, vSupp ); -// nNodes2 = Aig_NodeRef_rec( pNode ); -// assert( nNodes1 == nNodes2 ); - - Aig_NodeFactorConeSupp( pNode, vCone, vSupp ); - - printf( "%6d : Fan = %4d. Co = %5d. Su = %5d. %s ", - pNode->Id, pNode->nRefs, Vec_PtrSize(vCone), Vec_PtrSize(vSupp), pNode->fMarkB? "po" : " " ); - - Vec_PtrForEachEntry( vSupp, pLeaf, k ) - printf( " %d", pLeaf->Id ); - - printf( "\n" ); - - nSizes += Vec_PtrSize(vCone); - nCones++; - } - printf( "Nodes = %6d. MFFC sizes = %6d. Cones = %6d. nExors = %6d. Muxes = %6d.\n", - Aig_ManAndNum(pMan), nSizes, nCones, nExors, nMuxes ); - - // unmark the nodes - Aig_ManForEachNode( pMan, pNode, i ) - { - pNode->fMarkA = 0; - pNode->fMarkB = 0; - pNode->fMarkC = 0; - } - - Vec_PtrFree( vCone ); - Vec_PtrFree( vSupp ); -} - -/**Function************************************************************* - - Synopsis [Dereferences the node's MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_NodeDeref_rec( Aig_Node_t * pNode ) -{ - Aig_Node_t * pNode0, * pNode1; - int Counter = 1; - if ( Aig_NodeIsPi(pNode) ) - return 0; - pNode0 = Aig_NodeFanin0(pNode); - pNode1 = Aig_NodeFanin1(pNode); - assert( pNode0->nRefs > 0 ); - assert( pNode1->nRefs > 0 ); - if ( --pNode0->nRefs == 0 ) - Counter += Aig_NodeDeref_rec( pNode0 ); - if ( --pNode1->nRefs == 0 ) - Counter += Aig_NodeDeref_rec( pNode1 ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [References the node's MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Aig_NodeRef_rec( Aig_Node_t * pNode ) -{ - Aig_Node_t * pNode0, * pNode1; - int Counter = 1; - if ( Aig_NodeIsPi(pNode) ) - return 0; - pNode0 = Aig_NodeFanin0(pNode); - pNode1 = Aig_NodeFanin1(pNode); - if ( pNode0->nRefs++ == 0 ) - Counter += Aig_NodeRef_rec( pNode0 ); - if ( pNode1->nRefs++ == 0 ) - Counter += Aig_NodeRef_rec( pNode1 ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [Collects the internal and leaf nodes in the derefed MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_NodeMffsConeSupp_rec( Aig_Node_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp, int fTopmost ) -{ - // skip visited nodes - if ( Aig_NodeIsTravIdCurrent(pNode) ) - return; - Aig_NodeSetTravIdCurrent(pNode); - // add to the new support nodes - if ( !fTopmost && (Aig_NodeIsPi(pNode) || pNode->nRefs > 0) ) - { - Vec_PtrPush( vSupp, pNode ); - return; - } - // recur on the children - Aig_NodeMffsConeSupp_rec( Aig_NodeFanin0(pNode), vCone, vSupp, 0 ); - Aig_NodeMffsConeSupp_rec( Aig_NodeFanin1(pNode), vCone, vSupp, 0 ); - // collect the internal node - Vec_PtrPush( vCone, pNode ); -} - -/**Function************************************************************* - - Synopsis [Collects the support of the derefed MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_NodeMffsConeSupp( Aig_Node_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp ) -{ - assert( Aig_NodeIsAnd(pNode) ); - assert( !Aig_IsComplement(pNode) ); - Vec_PtrClear( vCone ); - Vec_PtrClear( vSupp ); - Aig_ManIncrementTravId( pNode->pMan ); - Aig_NodeMffsConeSupp_rec( pNode, vCone, vSupp, 1 ); -} - - - - - -/**Function************************************************************* - - Synopsis [Collects the internal and leaf nodes of the factor-cut of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_NodeFactorConeSupp_rec( Aig_Node_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp, int fTopmost ) -{ - // skip visited nodes - if ( Aig_NodeIsTravIdCurrent(pNode) ) - return; - Aig_NodeSetTravIdCurrent(pNode); - // add to the new support nodes - if ( !fTopmost && (Aig_NodeIsPi(pNode) || pNode->fMarkA) ) - { - Vec_PtrPush( vSupp, pNode ); - return; - } - // recur on the children - Aig_NodeFactorConeSupp_rec( Aig_NodeFanin0(pNode), vCone, vSupp, 0 ); - Aig_NodeFactorConeSupp_rec( Aig_NodeFanin1(pNode), vCone, vSupp, 0 ); - // collect the internal node - assert( fTopmost || !pNode->fMarkA ); - Vec_PtrPush( vCone, pNode ); - - assert( pNode->fMarkC == 0 ); - pNode->fMarkC = 1; -} - -/**Function************************************************************* - - Synopsis [Collects the support of the derefed MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_NodeFactorConeSupp( Aig_Node_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp ) -{ - assert( Aig_NodeIsAnd(pNode) ); - assert( !Aig_IsComplement(pNode) ); - Vec_PtrClear( vCone ); - Vec_PtrClear( vSupp ); - Aig_ManIncrementTravId( pNode->pMan ); - Aig_NodeFactorConeSupp_rec( pNode, vCone, vSupp, 1 ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/sat/aig/rwrTruth.c b/src/sat/aig/rwrTruth.c deleted file mode 100644 index cb8d03e0..00000000 --- a/src/sat/aig/rwrTruth.c +++ /dev/null @@ -1,456 +0,0 @@ -/**CFile**************************************************************** - - FileName [rwrTruth.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [And-Inverter Graph package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: rwrTruth.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "aig.h" - -/* The code in this file was written with portability to 64-bits in mind. - The type "unsigned" is assumed to be 32-bit on any platform. -*/ - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#define ABCTMAX 8 // the max number of vars - -typedef struct Aig_Truth_t_ Aig_Truth_t; -struct Aig_Truth_t_ -{ - short nVars; // the number of variables - short nWords; // the number of 32-bit words - unsigned Truth[1<<(ABCTMAX-5)]; // the truth table - unsigned Cofs[2][1<<(ABCTMAX-6)]; // the truth table of cofactors - unsigned Data[4][1<<(ABCTMAX-7)]; // the truth table of cofactors - short Counts[ABCTMAX][2]; // the minterm counters - Aig_Node_t * pLeaves[ABCTMAX]; // the pointers to leaves - Aig_Man_t * pMan; // the AIG manager -}; - -static void Aig_TruthCount( Aig_Truth_t * p ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Creates the function given the truth table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Truth_t * Aig_TruthCreate( int nVars, unsigned * pTruth, Aig_Node_t ** pLeaves ) -{ - Aig_Truth_t * p; - int i; - p = ALLOC( Aig_Truth_t, 1 ); - memset( p, 0, sizeof(Aig_Truth_t) ); - p->nVars = nVars; - p->nWords = (nVars < 5)? 1 : (1 << (nVars-5)); - for ( i = 0; i < p->nWords; i++ ) - p->Truth[i] = pTruth[i]; - if ( nVars < 5 ) - p->Truth[0] &= (~0u >> (32-(1<<nVars))); - for ( i = 0; i < p->nVars; i++ ) - p->pLeaves[i] = pLeaves[i]; - Aig_TruthCount( p ); - return p; -} - -/**Function************************************************************* - - Synopsis [Counts the number of miterms in the cofactors.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Aig_WordCountOnes( unsigned val ) -{ - val = (val & 0x55555555) + ((val>>1) & 0x55555555); - val = (val & 0x33333333) + ((val>>2) & 0x33333333); - val = (val & 0x0F0F0F0F) + ((val>>4) & 0x0F0F0F0F); - val = (val & 0x00FF00FF) + ((val>>8) & 0x00FF00FF); - return (val & 0x0000FFFF) + (val>>16); -} - -/**Function************************************************************* - - Synopsis [Counts the number of miterms in the cofactors.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_TruthCount( Aig_Truth_t * p ) -{ - static unsigned Masks[5][2] = { - { 0x33333333, 0xAAAAAAAA }, - { 0x55555555, 0xCCCCCCCC }, - { 0x0F0F0F0F, 0xF0F0F0F0 }, - { 0x00FF00FF, 0xFF00FF00 }, - { 0x0000FFFF, 0xFFFF0000 } - }; - - int i, k; - assert( p->Counts[0][0] == 0 && p->Counts[0][1] == 0 ); - for ( i = 0; i < p->nVars; i++ ) - { - p->Counts[i][0] = p->Counts[i][1] = 0; - if ( i < 5 ) - { - for ( k = 0; k < p->nWords; k++ ) - { - p->Counts[i][0] += Aig_WordCountOnes( p->Truth[k] & Masks[i][0] ); - p->Counts[i][1] += Aig_WordCountOnes( p->Truth[k] & Masks[i][1] ); - } - } - else - { - for ( k = 0; k < p->nWords; k++ ) - if ( i & (1 << (k-5)) ) - p->Counts[i][1] += Aig_WordCountOnes( p->Truth[k] ); - else - p->Counts[i][0] += Aig_WordCountOnes( p->Truth[k] ); - } - } -/* - // normalize the variables - for ( i = 0; i < p->nVars; i++ ) - if ( p->Counts[i][0] > p->Counts[i][1] ) - { - k = p->Counts[i][0]; - p->Counts[i][0] = p->Counts[i][1]; - p->Counts[i][1] = k; - p->pLeaves[i] = Aig_Not( p->pLeaves[i] ); - } -*/ -} - -/**Function************************************************************* - - Synopsis [Extracts one part of the bitstring.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline unsigned Aig_WordGetPart( unsigned * p, int Start, int Size ) -{ - return (p[Start/5] >> (Start&31)) & (~0u >> (32-Size)); -} - -/**Function************************************************************* - - Synopsis [Inserts one part of the bitstring.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Aig_WordSetPart( unsigned * p, int Start, unsigned Part ) -{ - p[Start/5] |= (Part << (Start&31)); -} - -/**Function************************************************************* - - Synopsis [Computes the cofactor with respect to one variable.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_TruthCofactor( int Var, int Pol, int nVars, unsigned * pTruth, unsigned * pResult ) -{ - if ( Var < 5 ) - { - int nPartSize = ( 1 << Var ); - int nParts = ( 1 << (nVars-Var-1) ); - unsigned uPart; - int i; - for ( i = 0; i < nParts; i++ ) - { - uPart = Aig_WordGetPart( pTruth, (2*i+Pol)*nPartSize, nPartSize ); - Aig_WordSetPart( pResult, i*nPartSize, uPart ); - } - if ( nVars <= 5 ) - pResult[0] &= (~0u >> (32-(1<<(nVars-1)))); - } - else - { - int nWords = (1 << (nVars-5)); - int i, k = 0; - for ( i = 0; i < nWords; i++ ) - if ( (i & (1 << (Var-5))) == Pol ) - pResult[k++] = pTruth[i]; - assert( k == nWords/2 ); - } -} - - - - -/**Function************************************************************* - - Synopsis [Computes the BDD of the truth table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode * Aig_TruthToBdd_rec( DdManager * dd, unsigned * pTruth, int Shift, int nVars, int iVar ) -{ - DdNode * bCof0, * bCof1, * bRes; - if ( nVars == 1 ) - return Cudd_NotCond( Cudd_ReadOne(dd), !Aig_WordGetPart(pTruth, Shift, 1) ); - if ( nVars == 3 ) - { - unsigned char * pChar = ((char *)pTruth) + Shift/8; - assert( Shift % 8 == 0 ); - if ( *pChar == 0 ) - return Cudd_ReadLogicZero(dd); - if ( *pChar == 0xFF ) - return Cudd_ReadOne(dd); - } - if ( nVars == 5 ) - { - unsigned * pWord = pTruth + (Shift>>5); - assert( Shift % 32 == 0 ); - if ( *pWord == 0 ) - return Cudd_ReadLogicZero(dd); - if ( *pWord == 0xFFFFFFFF ) - return Cudd_ReadOne(dd); - } - bCof0 = Aig_TruthToBdd_rec( dd, pTruth, Shift, nVars-1, iVar+1 ); Cudd_Ref( bCof0 ); - bCof1 = Aig_TruthToBdd_rec( dd, pTruth, Shift + (1 << (nVars-1)), nVars-1, iVar+1 ); Cudd_Ref( bCof1 ); - bRes = Cudd_bddIte( dd, Cudd_bddIthVar(dd, iVar), bCof1, bCof0 ); Cudd_Ref( bRes ); - Cudd_RecursiveDeref( dd, bCof0 ); - Cudd_RecursiveDeref( dd, bCof1 ); - Cudd_Deref( bRes ); - return bRes; -} - -/**Function************************************************************* - - Synopsis [Computes the BDD of the truth table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode * Aig_TruthToBdd( DdManager * dd, Aig_Truth_t * p ) -{ - return Aig_TruthToBdd_rec( dd, p->Truth, 0, p->nVars, 0 ); -} - - - - -/**Function************************************************************* - - Synopsis [Compare bistrings.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Aig_WordCompare( unsigned * p0, unsigned * p1, int nWords ) -{ - int i; - for ( i = 0; i < nWords; i++ ) - if ( p0[i] != p1[i] ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Compare bistrings.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Aig_WordCompareCompl( unsigned * p0, unsigned * p1, int nWords ) -{ - int i; - for ( i = 0; i < nWords; i++ ) - if ( p0[i] != ~p1[i] ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Computes the cofactor with respect to one variable.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_TruthReplaceByCofactor( Aig_Truth_t * p, int iVar, unsigned * pTruth ) -{ -} - - -/**Function************************************************************* - - Synopsis [Computes the cofactor with respect to one variable.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Node_t * Aig_TruthDecompose( Aig_Truth_t * p ) -{ - Aig_Node_t * pVar; - int nOnesCof = ( 1 << (p->nVars-1) ); - int nWordsCof = (p->nWords == 1 ? 1 : p->nWords/2); - int i; - - // check for constant function - if ( p->nVars == 0 ) - return Aig_NotCond( Aig_ManConst1(p->pMan), (p->Truth[0]&1)==0 ); - - // count the number of minterms in the cofactors - Aig_TruthCount( p ); - - // remove redundant variables and EXORs - for ( i = p->nVars - 1; i >= 0; i-- ) - { - if ( p->Counts[i][0] == p->Counts[i][1] ) - { - // compute cofactors - Aig_TruthCofactor( i, 0, p->nVars, p->Truth, p->Cofs[0] ); - Aig_TruthCofactor( i, 1, p->nVars, p->Truth, p->Cofs[1] ); - if ( Aig_WordCompare( p->Cofs[0], p->Cofs[1], nWordsCof ) ) - { // equal - // remove redundant variable - Aig_TruthReplaceByCofactor( p, i, p->Cofs[0] ); - return Aig_TruthDecompose( p ); - } - } - // check the case of EXOR - if ( p->Counts[i][0] == nOnesCof - p->Counts[i][1] ) - { - // compute cofactors - Aig_TruthCofactor( i, 0, p->nVars, p->Truth, p->Cofs[0] ); - Aig_TruthCofactor( i, 1, p->nVars, p->Truth, p->Cofs[1] ); - if ( Aig_WordCompareCompl( p->Cofs[0], p->Cofs[1], nWordsCof ) ) - { // equal - pVar = p->pLeaves[i]; - // remove redundant variable - Aig_TruthReplaceByCofactor( p, i, p->Cofs[0] ); - // F = x' * F0 + x * F1 = x <+> F0 assuming that F0 == ~F1 - return Aig_Xor( p->pMan, pVar, Aig_TruthDecompose( p ) ); - } - } - } - - // process variables with constant cofactors - for ( i = p->nVars - 1; i >= 0; i-- ) - { - if ( p->Counts[i][0] != 0 && p->Counts[i][1] != 0 && - p->Counts[i][0] != nOnesCof && p->Counts[i][1] != nOnesCof ) - continue; - pVar = p->pLeaves[i]; - if ( p->Counts[i][0] == 0 ) - { - Aig_TruthCofactor( i, 1, p->nVars, p->Truth, p->Cofs[1] ); - // remove redundant variable - Aig_TruthReplaceByCofactor( p, i, p->Cofs[1] ); - // F = x' * 0 + x * F1 = x * F1 - return Aig_And( p->pMan, pVar, Aig_TruthDecompose( p ) ); - } - if ( p->Counts[i][1] == 0 ) - { - Aig_TruthCofactor( i, 0, p->nVars, p->Truth, p->Cofs[0] ); - // remove redundant variable - Aig_TruthReplaceByCofactor( p, i, p->Cofs[0] ); - // F = x' * F0 + x * 0 = x' * F0 - return Aig_And( p->pMan, Aig_Not(pVar), Aig_TruthDecompose( p ) ); - } - if ( p->Counts[i][0] == nOnesCof ) - { - Aig_TruthCofactor( i, 1, p->nVars, p->Truth, p->Cofs[1] ); - // remove redundant variable - Aig_TruthReplaceByCofactor( p, i, p->Cofs[1] ); - // F = x' * 1 + x * F1 = x' + F1 - return Aig_Or( p->pMan, Aig_Not(pVar), Aig_TruthDecompose( p ) ); - } - if ( p->Counts[i][1] == nOnesCof ) - { - Aig_TruthCofactor( i, 0, p->nVars, p->Truth, p->Cofs[0] ); - // remove redundant variable - Aig_TruthReplaceByCofactor( p, i, p->Cofs[0] ); - // F = x' * F0 + x * 1 = x + F0 - return Aig_Or( p->pMan, pVar, Aig_TruthDecompose( p ) ); - } - assert( 0 ); - } - - - return NULL; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/temp/aig/aig.h b/src/temp/aig/aig.h new file mode 100644 index 00000000..e3e35b0c --- /dev/null +++ b/src/temp/aig/aig.h @@ -0,0 +1,308 @@ +/**CFile**************************************************************** + + FileName [aig.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Minimalistic And-Inverter Graph package.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: aig.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __AIG_H__ +#define __AIG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include <stdio.h> +#include "vec.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Aig_Man_t_ Aig_Man_t; +typedef struct Aig_Obj_t_ Aig_Obj_t; +typedef int Aig_Edge_t; + +// object types +typedef enum { + AIG_NONE, // 0: non-existent object + AIG_CONST1, // 1: constant 1 + AIG_PI, // 2: primary input + AIG_PO, // 3: primary output + AIG_AND, // 4: AND node + AIG_EXOR, // 5: EXOR node + AIG_VOID // 6: unused object +} Aig_Type_t; + +// the AIG node +struct Aig_Obj_t_ // 4 words +{ + void * pData; // misc + Aig_Obj_t * pFanin0; // fanin + Aig_Obj_t * pFanin1; // fanin + unsigned long Type : 3; // object type + unsigned long fPhase : 1; // value under 000...0 pattern + unsigned long fMarkA : 1; // multipurpose mask + unsigned long fMarkB : 1; // multipurpose mask + unsigned long nRefs : 26; // reference count (level) +}; + +// the AIG manager +struct Aig_Man_t_ +{ + // AIG nodes + Vec_Ptr_t * vPis; // the array of PIs + Vec_Ptr_t * vPos; // the array of POs + Aig_Obj_t * pConst1; // the constant 1 node + Aig_Obj_t Ghost; // the ghost node + // AIG node counters + int nObjs[AIG_VOID];// the number of objects by type + int nCreated; // the number of created objects + int nDeleted; // the number of deleted objects + // stuctural hash table + Aig_Obj_t ** pTable; // structural hash table + int nTableSize; // structural hash table size + // various data members + void * pData; // the temporary data + int nTravIds; // the current traversal ID + int fRefCount; // enables reference counting + int fCatchExor; // enables EXOR nodes + // memory management + Vec_Ptr_t * vChunks; // allocated memory pieces + Vec_Ptr_t * vPages; // memory pages used by nodes + Aig_Obj_t * pListFree; // the list of free nodes + // timing statistics + int time1; + int time2; +}; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +#define AIG_MIN(a,b) (((a) < (b))? (a) : (b)) +#define AIG_MAX(a,b) (((a) > (b))? (a) : (b)) + +static inline int Aig_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); } +static inline int Aig_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); } +static inline int Aig_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; } +static inline void Aig_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); } +static inline void Aig_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); } + +static inline Aig_Obj_t * Aig_Regular( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned)(p) & ~01); } +static inline Aig_Obj_t * Aig_Not( Aig_Obj_t * p ) { return (Aig_Obj_t *)((unsigned)(p) ^ 01); } +static inline Aig_Obj_t * Aig_NotCond( Aig_Obj_t * p, int c ) { return (Aig_Obj_t *)((unsigned)(p) ^ (c)); } +static inline int Aig_IsComplement( Aig_Obj_t * p ) { return (int )(((unsigned)p) & 01); } + +static inline Aig_Obj_t * Aig_ManConst0( Aig_Man_t * p ) { return Aig_Not(p->pConst1); } +static inline Aig_Obj_t * Aig_ManConst1( Aig_Man_t * p ) { return p->pConst1; } +static inline Aig_Obj_t * Aig_ManGhost( Aig_Man_t * p ) { return &p->Ghost; } +static inline Aig_Obj_t * Aig_ManPi( Aig_Man_t * p, int i ) { return (Aig_Obj_t *)Vec_PtrEntry(p->vPis, i); } + +static inline Aig_Edge_t Aig_EdgeCreate( int Id, int fCompl ) { return (Id << 1) | fCompl; } +static inline int Aig_EdgeId( Aig_Edge_t Edge ) { return Edge >> 1; } +static inline int Aig_EdgeIsComplement( Aig_Edge_t Edge ) { return Edge & 1; } +static inline Aig_Edge_t Aig_EdgeRegular( Aig_Edge_t Edge ) { return (Edge >> 1) << 1; } +static inline Aig_Edge_t Aig_EdgeNot( Aig_Edge_t Edge ) { return Edge ^ 1; } +static inline Aig_Edge_t Aig_EdgeNotCond( Aig_Edge_t Edge, int fCond ) { return Edge ^ fCond; } + +static inline int Aig_ManPiNum( Aig_Man_t * p ) { return p->nObjs[AIG_PI]; } +static inline int Aig_ManPoNum( Aig_Man_t * p ) { return p->nObjs[AIG_PO]; } +static inline int Aig_ManAndNum( Aig_Man_t * p ) { return p->nObjs[AIG_AND]; } +static inline int Aig_ManExorNum( Aig_Man_t * p ) { return p->nObjs[AIG_EXOR]; } +static inline int Aig_ManNodeNum( Aig_Man_t * p ) { return p->nObjs[AIG_AND]+p->nObjs[AIG_EXOR];} +static inline int Aig_ManGetCost( Aig_Man_t * p ) { return p->nObjs[AIG_AND]+3*p->nObjs[AIG_EXOR]; } +static inline int Aig_ManObjNum( Aig_Man_t * p ) { return p->nCreated - p->nDeleted; } + +static inline Aig_Type_t Aig_ObjType( Aig_Obj_t * pObj ) { return pObj->Type; } +static inline int Aig_ObjIsNone( Aig_Obj_t * pObj ) { return pObj->Type == AIG_NONE; } +static inline int Aig_ObjIsConst1( Aig_Obj_t * pObj ) { return pObj->Type == AIG_CONST1; } +static inline int Aig_ObjIsPi( Aig_Obj_t * pObj ) { return pObj->Type == AIG_PI; } +static inline int Aig_ObjIsPo( Aig_Obj_t * pObj ) { return pObj->Type == AIG_PO; } +static inline int Aig_ObjIsAnd( Aig_Obj_t * pObj ) { return pObj->Type == AIG_AND; } +static inline int Aig_ObjIsExor( Aig_Obj_t * pObj ) { return pObj->Type == AIG_EXOR; } +static inline int Aig_ObjIsNode( Aig_Obj_t * pObj ) { return pObj->Type == AIG_AND || pObj->Type == AIG_EXOR; } +static inline int Aig_ObjIsTerm( Aig_Obj_t * pObj ) { return pObj->Type == AIG_PI || pObj->Type == AIG_PO || pObj->Type == AIG_CONST1; } +static inline int Aig_ObjIsHash( Aig_Obj_t * pObj ) { return pObj->Type == AIG_AND || pObj->Type == AIG_EXOR; } + +static inline int Aig_ObjIsMarkA( Aig_Obj_t * pObj ) { return pObj->fMarkA; } +static inline void Aig_ObjSetMarkA( Aig_Obj_t * pObj ) { pObj->fMarkA = 1; } +static inline void Aig_ObjClearMarkA( Aig_Obj_t * pObj ) { pObj->fMarkA = 0; } + +static inline void Aig_ObjSetTravId( Aig_Obj_t * pObj, int TravId ) { pObj->pData = (void *)TravId; } +static inline void Aig_ObjSetTravIdCurrent( Aig_Man_t * p, Aig_Obj_t * pObj ) { pObj->pData = (void *)p->nTravIds; } +static inline void Aig_ObjSetTravIdPrevious( Aig_Man_t * p, Aig_Obj_t * pObj ) { pObj->pData = (void *)(p->nTravIds - 1); } +static inline int Aig_ObjIsTravIdCurrent( Aig_Man_t * p, Aig_Obj_t * pObj ) { return (int )((int)pObj->pData == p->nTravIds); } +static inline int Aig_ObjIsTravIdPrevious( Aig_Man_t * p, Aig_Obj_t * pObj ) { return (int )((int)pObj->pData == p->nTravIds - 1); } + +static inline int Aig_ObjTravId( Aig_Obj_t * pObj ) { return (int)pObj->pData; } +static inline int Aig_ObjPhase( Aig_Obj_t * pObj ) { return pObj->fPhase; } +static inline int Aig_ObjRefs( Aig_Obj_t * pObj ) { return pObj->nRefs; } +static inline void Aig_ObjRef( Aig_Obj_t * pObj ) { pObj->nRefs++; } +static inline void Aig_ObjDeref( Aig_Obj_t * pObj ) { assert( pObj->nRefs > 0 ); pObj->nRefs--; } +static inline void Aig_ObjClearRef( Aig_Obj_t * pObj ) { pObj->nRefs = 0; } +static inline int Aig_ObjFaninC0( Aig_Obj_t * pObj ) { return Aig_IsComplement(pObj->pFanin0); } +static inline int Aig_ObjFaninC1( Aig_Obj_t * pObj ) { return Aig_IsComplement(pObj->pFanin1); } +static inline Aig_Obj_t * Aig_ObjFanin0( Aig_Obj_t * pObj ) { return Aig_Regular(pObj->pFanin0); } +static inline Aig_Obj_t * Aig_ObjFanin1( Aig_Obj_t * pObj ) { return Aig_Regular(pObj->pFanin1); } +static inline Aig_Obj_t * Aig_ObjChild0( Aig_Obj_t * pObj ) { return pObj->pFanin0; } +static inline Aig_Obj_t * Aig_ObjChild1( Aig_Obj_t * pObj ) { return pObj->pFanin1; } +static inline Aig_Obj_t * Aig_ObjChild0Copy( Aig_Obj_t * pObj ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj)) : NULL; } +static inline Aig_Obj_t * Aig_ObjChild1Copy( Aig_Obj_t * pObj ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond(Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj)) : NULL; } +static inline int Aig_ObjLevel( Aig_Obj_t * pObj ) { return pObj->nRefs; } +static inline int Aig_ObjLevelNew( Aig_Obj_t * pObj ) { return 1 + Aig_ObjIsExor(pObj) + AIG_MAX(Aig_ObjFanin0(pObj)->nRefs, Aig_ObjFanin1(pObj)->nRefs); } +static inline void Aig_ObjClean( Aig_Obj_t * pObj ) { memset( pObj, 0, sizeof(Aig_Obj_t) ); } +static inline int Aig_ObjWhatFanin( Aig_Obj_t * pObj, Aig_Obj_t * pFanin ) +{ + if ( Aig_ObjFanin0(pObj) == pFanin ) return 0; + if ( Aig_ObjFanin1(pObj) == pFanin ) return 1; + assert(0); return -1; +} +static inline int Aig_ObjFanoutC( Aig_Obj_t * pObj, Aig_Obj_t * pFanout ) +{ + if ( Aig_ObjFanin0(pFanout) == pObj ) return Aig_ObjFaninC0(pObj); + if ( Aig_ObjFanin1(pFanout) == pObj ) return Aig_ObjFaninC1(pObj); + assert(0); return -1; +} + +// create the ghost of the new node +static inline Aig_Obj_t * Aig_ObjCreateGhost( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1, Aig_Type_t Type ) +{ + Aig_Obj_t * pGhost; + assert( Type != AIG_AND || !Aig_ObjIsConst1(Aig_Regular(p0)) ); + assert( p1 == NULL || !Aig_ObjIsConst1(Aig_Regular(p1)) ); + assert( Type == AIG_PI || Aig_Regular(p0) != Aig_Regular(p1) ); + pGhost = Aig_ManGhost(p); + pGhost->Type = Type; + pGhost->pFanin0 = p0 < p1? p0 : p1; + pGhost->pFanin1 = p0 < p1? p1 : p0; + return pGhost; +} + +// internal memory manager +static inline Aig_Obj_t * Aig_ManFetchMemory( Aig_Man_t * p ) +{ + extern void Aig_ManAddMemory( Aig_Man_t * p ); + Aig_Obj_t * pTemp; + if ( p->pListFree == NULL ) + Aig_ManAddMemory( p ); + pTemp = p->pListFree; + p->pListFree = *((Aig_Obj_t **)pTemp); + memset( pTemp, 0, sizeof(Aig_Obj_t) ); + return pTemp; +} +static inline void Aig_ManRecycleMemory( Aig_Man_t * p, Aig_Obj_t * pEntry ) +{ + pEntry->Type = AIG_NONE; // distinquishes dead node from live node + *((Aig_Obj_t **)pEntry) = p->pListFree; + p->pListFree = pEntry; +} + + +//////////////////////////////////////////////////////////////////////// +/// ITERATORS /// +//////////////////////////////////////////////////////////////////////// + +// iterator over the primary inputs +#define Aig_ManForEachPi( p, pObj, i ) \ + Vec_PtrForEachEntry( p->vPis, pObj, i ) +// iterator over the primary outputs +#define Aig_ManForEachPo( p, pObj, i ) \ + Vec_PtrForEachEntry( p->vPos, pObj, i ) +// iterator over all objects, including those currently not used +#define Aig_ManForEachNode( p, pObj, i ) \ + for ( i = 0; i < p->nTableSize; i++ ) \ + if ( ((pObj) = p->pTable[i]) == NULL ) {} else + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== aigBalance.c ========================================================*/ +extern Aig_Man_t * Aig_ManBalance( Aig_Man_t * p, int fUpdateLevel ); +extern Aig_Obj_t * Aig_NodeBalanceBuildSuper( Aig_Man_t * p, Vec_Ptr_t * vSuper, Aig_Type_t Type, int fUpdateLevel ); +/*=== aigCheck.c ========================================================*/ +extern int Aig_ManCheck( Aig_Man_t * p ); +/*=== aigDfs.c ==========================================================*/ +extern Vec_Ptr_t * Aig_ManDfs( Aig_Man_t * p ); +extern Vec_Ptr_t * Aig_ManDfsNode( Aig_Man_t * p, Aig_Obj_t * pNode ); +extern int Aig_ManCountLevels( Aig_Man_t * p ); +extern void Aig_ManCreateRefs( Aig_Man_t * p ); +extern int Aig_DagSize( Aig_Obj_t * pObj ); +extern void Aig_ConeUnmark_rec( Aig_Obj_t * pObj ); +extern Aig_Obj_t * Aig_Transfer( Aig_Man_t * pSour, Aig_Man_t * pDest, Aig_Obj_t * pObj, int nVars ); +/*=== aigMan.c ==========================================================*/ +extern Aig_Man_t * Aig_ManStart(); +extern Aig_Man_t * Aig_ManDup( Aig_Man_t * p ); +extern void Aig_ManStop( Aig_Man_t * p ); +extern int Aig_ManCleanup( Aig_Man_t * p ); +extern void Aig_ManPrintStats( Aig_Man_t * p ); +/*=== aigMem.c ==========================================================*/ +extern void Aig_ManStartMemory( Aig_Man_t * p ); +extern void Aig_ManStopMemory( Aig_Man_t * p ); +/*=== aigObj.c ==========================================================*/ +extern Aig_Obj_t * Aig_ObjCreatePi( Aig_Man_t * p ); +extern Aig_Obj_t * Aig_ObjCreatePo( Aig_Man_t * p, Aig_Obj_t * pDriver ); +extern Aig_Obj_t * Aig_ObjCreate( Aig_Man_t * p, Aig_Obj_t * pGhost ); +extern void Aig_ObjConnect( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFan0, Aig_Obj_t * pFan1 ); +extern void Aig_ObjDisconnect( Aig_Man_t * p, Aig_Obj_t * pObj ); +extern void Aig_ObjDelete( Aig_Man_t * p, Aig_Obj_t * pObj ); +extern void Aig_ObjDelete_rec( Aig_Man_t * p, Aig_Obj_t * pObj ); +/*=== aigOper.c =========================================================*/ +extern Aig_Obj_t * Aig_IthVar( Aig_Man_t * p, int i ); +extern Aig_Obj_t * Aig_Oper( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1, Aig_Type_t Type ); +extern Aig_Obj_t * Aig_And( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 ); +extern Aig_Obj_t * Aig_Or( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 ); +extern Aig_Obj_t * Aig_Exor( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 ); +extern Aig_Obj_t * Aig_Mux( Aig_Man_t * p, Aig_Obj_t * pC, Aig_Obj_t * p1, Aig_Obj_t * p0 ); +extern Aig_Obj_t * Aig_Maj( Aig_Man_t * p, Aig_Obj_t * pA, Aig_Obj_t * pB, Aig_Obj_t * pC ); +extern Aig_Obj_t * Aig_Miter( Aig_Man_t * p, Vec_Ptr_t * vPairs ); +extern Aig_Obj_t * Aig_CreateAnd( Aig_Man_t * p, int nVars ); +extern Aig_Obj_t * Aig_CreateOr( Aig_Man_t * p, int nVars ); +extern Aig_Obj_t * Aig_CreateExor( Aig_Man_t * p, int nVars ); +/*=== aigTable.c ========================================================*/ +extern Aig_Obj_t * Aig_TableLookup( Aig_Man_t * p, Aig_Obj_t * pGhost ); +extern void Aig_TableInsert( Aig_Man_t * p, Aig_Obj_t * pObj ); +extern void Aig_TableDelete( Aig_Man_t * p, Aig_Obj_t * pObj ); +extern int Aig_TableCountEntries( Aig_Man_t * p ); +extern void Aig_TableProfile( Aig_Man_t * p ); +/*=== aigUtil.c =========================================================*/ +extern void Aig_ManIncrementTravId( Aig_Man_t * p ); +extern void Aig_ManCleanData( Aig_Man_t * p ); +extern int Aig_ObjMffcLabel( Aig_Man_t * p, Aig_Obj_t * pNode ); +extern int Aig_ObjIsMuxType( Aig_Obj_t * pObj ); +extern Aig_Obj_t * Aig_ObjRecognizeMux( Aig_Obj_t * pObj, Aig_Obj_t ** ppObjT, Aig_Obj_t ** ppObjE ); +extern void Aig_ObjPrintVerbose( Aig_Obj_t * pObj, int fHaig ); +extern void Aig_ManPrintVerbose( Aig_Man_t * p, int fHaig ); + +#ifdef __cplusplus +} +#endif + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/temp/aig/aigBalance.c b/src/temp/aig/aigBalance.c new file mode 100644 index 00000000..1abc672d --- /dev/null +++ b/src/temp/aig/aigBalance.c @@ -0,0 +1,391 @@ +/**CFile**************************************************************** + + FileName [aigBalance.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Minimalistic And-Inverter Graph package.] + + Synopsis [Algebraic AIG balancing.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: aigBalance.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Aig_Obj_t * Aig_NodeBalance_rec( Aig_Man_t * pNew, Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level, int fUpdateLevel ); +static Vec_Ptr_t * Aig_NodeBalanceCone( Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level ); +static int Aig_NodeBalanceFindLeft( Vec_Ptr_t * vSuper ); +static void Aig_NodeBalancePermute( Aig_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor ); +static void Aig_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Aig_Obj_t * pObj ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs algebraic balancing of the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Aig_ManBalance( Aig_Man_t * p, int fUpdateLevel ) +{ + Aig_Man_t * pNew; + Aig_Obj_t * pObj, * pObjNew; + Vec_Vec_t * vStore; + int i; + // create the new manager + pNew = Aig_ManStart(); + pNew->fRefCount = 0; + // map the PI nodes + Aig_ManCleanData( p ); + Aig_ManConst1(p)->pData = Aig_ManConst1(pNew); + Aig_ManForEachPi( p, pObj, i ) + pObj->pData = Aig_ObjCreatePi(pNew); + // balance the AIG + vStore = Vec_VecAlloc( 50 ); + Aig_ManForEachPo( p, pObj, i ) + { + pObjNew = Aig_NodeBalance_rec( pNew, Aig_ObjFanin0(pObj), vStore, 0, fUpdateLevel ); + Aig_ObjCreatePo( pNew, Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObj) ) ); + } + Vec_VecFree( vStore ); + // remove dangling nodes +// Aig_ManCreateRefs( pNew ); +// if ( i = Aig_ManCleanup( pNew ) ) +// printf( "Cleanup after balancing removed %d dangling nodes.\n", i ); + // check the resulting AIG + if ( !Aig_ManCheck(pNew) ) + printf( "Aig_ManBalance(): The check has failed.\n" ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Returns the new node constructed.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_NodeBalance_rec( Aig_Man_t * pNew, Aig_Obj_t * pObjOld, Vec_Vec_t * vStore, int Level, int fUpdateLevel ) +{ + Aig_Obj_t * pObjNew; + Vec_Ptr_t * vSuper; + int i; + assert( !Aig_IsComplement(pObjOld) ); + // return if the result is known + if ( pObjOld->pData ) + return pObjOld->pData; + assert( Aig_ObjIsNode(pObjOld) ); + // get the implication supergate + vSuper = Aig_NodeBalanceCone( pObjOld, vStore, Level ); + // check if supergate contains two nodes in the opposite polarity + if ( vSuper->nSize == 0 ) + return pObjOld->pData = Aig_ManConst0(pNew); + if ( Vec_PtrSize(vSuper) < 2 ) + printf( "BUG!\n" ); + // for each old node, derive the new well-balanced node + for ( i = 0; i < Vec_PtrSize(vSuper); i++ ) + { + pObjNew = Aig_NodeBalance_rec( pNew, Aig_Regular(vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel ); + vSuper->pArray[i] = Aig_NotCond( pObjNew, Aig_IsComplement(vSuper->pArray[i]) ); + } + // build the supergate + pObjNew = Aig_NodeBalanceBuildSuper( pNew, vSuper, Aig_ObjType(pObjOld), fUpdateLevel ); + // make sure the balanced node is not assigned +// assert( pObjOld->Level >= Aig_Regular(pObjNew)->Level ); + assert( pObjOld->pData == NULL ); + return pObjOld->pData = pObjNew; +} + +/**Function************************************************************* + + Synopsis [Collects the nodes of the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_NodeBalanceCone_rec( Aig_Obj_t * pRoot, Aig_Obj_t * pObj, Vec_Ptr_t * vSuper ) +{ + int RetValue1, RetValue2, i; + // check if the node is visited + if ( Aig_Regular(pObj)->fMarkB ) + { + // check if the node occurs in the same polarity + for ( i = 0; i < vSuper->nSize; i++ ) + if ( vSuper->pArray[i] == pObj ) + return 1; + // check if the node is present in the opposite polarity + for ( i = 0; i < vSuper->nSize; i++ ) + if ( vSuper->pArray[i] == Aig_Not(pObj) ) + return -1; + assert( 0 ); + return 0; + } + // if the new node is complemented or a PI, another gate begins + if ( pObj != pRoot && (Aig_IsComplement(pObj) || Aig_ObjType(pObj) != Aig_ObjType(pRoot) || Aig_ObjRefs(pObj) > 1) ) + { + Vec_PtrPush( vSuper, pObj ); + Aig_Regular(pObj)->fMarkB = 1; + return 0; + } + assert( !Aig_IsComplement(pObj) ); + assert( Aig_ObjIsNode(pObj) ); + // go through the branches + RetValue1 = Aig_NodeBalanceCone_rec( pRoot, Aig_ObjChild0(pObj), vSuper ); + RetValue2 = Aig_NodeBalanceCone_rec( pRoot, Aig_ObjChild1(pObj), vSuper ); + if ( RetValue1 == -1 || RetValue2 == -1 ) + return -1; + // return 1 if at least one branch has a duplicate + return RetValue1 || RetValue2; +} + +/**Function************************************************************* + + Synopsis [Collects the nodes of the supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Aig_NodeBalanceCone( Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level ) +{ + Vec_Ptr_t * vNodes; + int RetValue, i; + assert( !Aig_IsComplement(pObj) ); + // extend the storage + if ( Vec_VecSize( vStore ) <= Level ) + Vec_VecPush( vStore, Level, 0 ); + // get the temporary array of nodes + vNodes = Vec_VecEntry( vStore, Level ); + Vec_PtrClear( vNodes ); + // collect the nodes in the implication supergate + RetValue = Aig_NodeBalanceCone_rec( pObj, pObj, vNodes ); + assert( vNodes->nSize > 1 ); + // unmark the visited nodes + Vec_PtrForEachEntry( vNodes, pObj, i ) + Aig_Regular(pObj)->fMarkB = 0; + // if we found the node and its complement in the same implication supergate, + // return empty set of nodes (meaning that we should use constant-0 node) + if ( RetValue == -1 ) + vNodes->nSize = 0; + return vNodes; +} + +/**Function************************************************************* + + Synopsis [Procedure used for sorting the nodes in decreasing order of levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_NodeCompareLevelsDecrease( Aig_Obj_t ** pp1, Aig_Obj_t ** pp2 ) +{ + int Diff = Aig_ObjLevel(Aig_Regular(*pp1)) - Aig_ObjLevel(Aig_Regular(*pp2)); + if ( Diff > 0 ) + return -1; + if ( Diff < 0 ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [Builds implication supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_NodeBalanceBuildSuper( Aig_Man_t * p, Vec_Ptr_t * vSuper, Aig_Type_t Type, int fUpdateLevel ) +{ + Aig_Obj_t * pObj1, * pObj2; + int LeftBound; + assert( vSuper->nSize > 1 ); + // sort the new nodes by level in the decreasing order + Vec_PtrSort( vSuper, Aig_NodeCompareLevelsDecrease ); + // balance the nodes + while ( vSuper->nSize > 1 ) + { + // find the left bound on the node to be paired + LeftBound = (!fUpdateLevel)? 0 : Aig_NodeBalanceFindLeft( vSuper ); + // find the node that can be shared (if no such node, randomize choice) + Aig_NodeBalancePermute( p, vSuper, LeftBound, Type == AIG_EXOR ); + // pull out the last two nodes + pObj1 = Vec_PtrPop(vSuper); + pObj2 = Vec_PtrPop(vSuper); + Aig_NodeBalancePushUniqueOrderByLevel( vSuper, Aig_Oper(p, pObj1, pObj2, Type) ); + } + return Vec_PtrEntry(vSuper, 0); +} + +/**Function************************************************************* + + Synopsis [Finds the left bound on the next candidate to be paired.] + + Description [The nodes in the array are in the decreasing order of levels. + The last node in the array has the smallest level. By default it would be paired + with the next node on the left. However, it may be possible to pair it with some + other node on the left, in such a way that the new node is shared. This procedure + finds the index of the left-most node, which can be paired with the last node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_NodeBalanceFindLeft( Vec_Ptr_t * vSuper ) +{ + Aig_Obj_t * pObjRight, * pObjLeft; + int Current; + // if two or less nodes, pair with the first + if ( Vec_PtrSize(vSuper) < 3 ) + return 0; + // set the pointer to the one before the last + Current = Vec_PtrSize(vSuper) - 2; + pObjRight = Vec_PtrEntry( vSuper, Current ); + // go through the nodes to the left of this one + for ( Current--; Current >= 0; Current-- ) + { + // get the next node on the left + pObjLeft = Vec_PtrEntry( vSuper, Current ); + // if the level of this node is different, quit the loop + if ( Aig_ObjLevel(Aig_Regular(pObjLeft)) != Aig_ObjLevel(Aig_Regular(pObjRight)) ) + break; + } + Current++; + // get the node, for which the equality holds + pObjLeft = Vec_PtrEntry( vSuper, Current ); + assert( Aig_ObjLevel(Aig_Regular(pObjLeft)) == Aig_ObjLevel(Aig_Regular(pObjRight)) ); + return Current; +} + +/**Function************************************************************* + + Synopsis [Moves closer to the end the node that is best for sharing.] + + Description [If there is no node with sharing, randomly chooses one of + the legal nodes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_NodeBalancePermute( Aig_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor ) +{ + Aig_Obj_t * pObj1, * pObj2, * pObj3, * pGhost; + int RightBound, i; + // get the right bound + RightBound = Vec_PtrSize(vSuper) - 2; + assert( LeftBound <= RightBound ); + if ( LeftBound == RightBound ) + return; + // get the two last nodes + pObj1 = Vec_PtrEntry( vSuper, RightBound + 1 ); + pObj2 = Vec_PtrEntry( vSuper, RightBound ); + if ( Aig_Regular(pObj1) == p->pConst1 || Aig_Regular(pObj2) == p->pConst1 ) + return; + // find the first node that can be shared + for ( i = RightBound; i >= LeftBound; i-- ) + { + pObj3 = Vec_PtrEntry( vSuper, i ); + if ( Aig_Regular(pObj3) == p->pConst1 ) + { + Vec_PtrWriteEntry( vSuper, i, pObj2 ); + Vec_PtrWriteEntry( vSuper, RightBound, pObj3 ); + return; + } + pGhost = Aig_ObjCreateGhost( p, pObj1, pObj3, fExor? AIG_EXOR : AIG_AND ); + if ( Aig_TableLookup( p, pGhost ) ) + { + if ( pObj3 == pObj2 ) + return; + Vec_PtrWriteEntry( vSuper, i, pObj2 ); + Vec_PtrWriteEntry( vSuper, RightBound, pObj3 ); + return; + } + } +/* + // we did not find the node to share, randomize choice + { + int Choice = rand() % (RightBound - LeftBound + 1); + pObj3 = Vec_PtrEntry( vSuper, LeftBound + Choice ); + if ( pObj3 == pObj2 ) + return; + Vec_PtrWriteEntry( vSuper, LeftBound + Choice, pObj2 ); + Vec_PtrWriteEntry( vSuper, RightBound, pObj3 ); + } +*/ +} + +/**Function************************************************************* + + Synopsis [Inserts a new node in the order by levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Aig_Obj_t * pObj ) +{ + Aig_Obj_t * pObj1, * pObj2; + int i; + if ( Vec_PtrPushUnique(vStore, pObj) ) + return; + // find the p of the node + for ( i = vStore->nSize-1; i > 0; i-- ) + { + pObj1 = vStore->pArray[i ]; + pObj2 = vStore->pArray[i-1]; + if ( Aig_ObjLevel(Aig_Regular(pObj1)) <= Aig_ObjLevel(Aig_Regular(pObj2)) ) + break; + vStore->pArray[i ] = pObj2; + vStore->pArray[i-1] = pObj1; + } +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/aig/aigCheck.c b/src/temp/aig/aigCheck.c new file mode 100644 index 00000000..61e4cf78 --- /dev/null +++ b/src/temp/aig/aigCheck.c @@ -0,0 +1,110 @@ +/**CFile**************************************************************** + + FileName [aigCheck.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Minimalistic And-Inverter Graph package.] + + Synopsis [AIG checking procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: aigCheck.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Checks the consistency of the AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_ManCheck( Aig_Man_t * p ) +{ + Aig_Obj_t * pObj, * pObj2; + int i; + // check primary inputs + Aig_ManForEachPi( p, pObj, i ) + { + if ( Aig_ObjFanin0(pObj) || Aig_ObjFanin1(pObj) ) + { + printf( "Aig_ManCheck: The PI node \"%p\" has fanins.\n", pObj ); + return 0; + } + } + // check primary outputs + Aig_ManForEachPo( p, pObj, i ) + { + if ( !Aig_ObjFanin0(pObj) ) + { + printf( "Aig_ManCheck: The PO node \"%p\" has NULL fanin.\n", pObj ); + return 0; + } + if ( Aig_ObjFanin1(pObj) ) + { + printf( "Aig_ManCheck: The PO node \"%p\" has second fanin.\n", pObj ); + return 0; + } + } + // check internal nodes + Aig_ManForEachNode( p, pObj, i ) + { + if ( !Aig_ObjFanin0(pObj) || !Aig_ObjFanin1(pObj) ) + { + printf( "Aig_ManCheck: The AIG has internal node \"%p\" with a NULL fanin.\n", pObj ); + return 0; + } + if ( Aig_ObjFanin0(pObj) >= Aig_ObjFanin1(pObj) ) + { + printf( "Aig_ManCheck: The AIG has node \"%p\" with a wrong ordering of fanins.\n", pObj ); + return 0; + } + pObj2 = Aig_TableLookup( p, pObj ); + if ( pObj2 != pObj ) + { + printf( "Aig_ManCheck: Node \"%p\" is not in the structural hashing table.\n", pObj ); + return 0; + } + } + // count the total number of nodes + if ( Aig_ManObjNum(p) != 1 + Aig_ManPiNum(p) + Aig_ManPoNum(p) + Aig_ManAndNum(p) + Aig_ManExorNum(p) ) + { + printf( "Aig_ManCheck: The number of created nodes is wrong.\n" ); + return 0; + } + // count the number of nodes in the table + if ( Aig_TableCountEntries(p) != Aig_ManAndNum(p) + Aig_ManExorNum(p) ) + { + printf( "Aig_ManCheck: The number of nodes in the structural hashing table is wrong.\n" ); + return 0; + } +// if ( !Aig_ManIsAcyclic(p) ) +// return 0; + return 1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/aig/aigDfs.c b/src/temp/aig/aigDfs.c new file mode 100644 index 00000000..e289f6ec --- /dev/null +++ b/src/temp/aig/aigDfs.c @@ -0,0 +1,342 @@ +/**CFile**************************************************************** + + FileName [aigDfs.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Minimalistic And-Inverter Graph package.] + + Synopsis [DFS traversal procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: aigDfs.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Collects internal nodes in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManDfs_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vNodes ) +{ + assert( !Aig_IsComplement(pObj) ); + if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) ) + return; + Aig_ManDfs_rec( Aig_ObjFanin0(pObj), vNodes ); + Aig_ManDfs_rec( Aig_ObjFanin1(pObj), vNodes ); + assert( !Aig_ObjIsMarkA(pObj) ); // loop detection + Aig_ObjSetMarkA(pObj); + Vec_PtrPush( vNodes, pObj ); +} + +/**Function************************************************************* + + Synopsis [Collects internal nodes in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Aig_ManDfs( Aig_Man_t * p ) +{ + Vec_Ptr_t * vNodes; + Aig_Obj_t * pObj; + int i; + vNodes = Vec_PtrAlloc( Aig_ManNodeNum(p) ); + Aig_ManForEachNode( p, pObj, i ) + Aig_ManDfs_rec( pObj, vNodes ); + Aig_ManForEachNode( p, pObj, i ) + Aig_ObjClearMarkA(pObj); + return vNodes; +} + +/**Function************************************************************* + + Synopsis [Collects internal nodes in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Aig_ManDfsNode( Aig_Man_t * p, Aig_Obj_t * pNode ) +{ + Vec_Ptr_t * vNodes; + Aig_Obj_t * pObj; + int i; + assert( !Aig_IsComplement(pNode) ); + vNodes = Vec_PtrAlloc( 16 ); + Aig_ManDfs_rec( pNode, vNodes ); + Vec_PtrForEachEntry( vNodes, pObj, i ) + Aig_ObjClearMarkA(pObj); + return vNodes; +} + +/**Function************************************************************* + + Synopsis [Computes the max number of levels in the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_ManCountLevels( Aig_Man_t * p ) +{ + Vec_Ptr_t * vNodes; + Aig_Obj_t * pObj; + int i, LevelsMax, Level0, Level1; + // initialize the levels + Aig_ManConst1(p)->pData = NULL; + Aig_ManForEachPi( p, pObj, i ) + pObj->pData = NULL; + // compute levels in a DFS order + vNodes = Aig_ManDfs( p ); + Vec_PtrForEachEntry( vNodes, pObj, i ) + { + Level0 = (int)Aig_ObjFanin0(pObj)->pData; + Level1 = (int)Aig_ObjFanin1(pObj)->pData; + pObj->pData = (void *)(1 + Aig_ObjIsExor(pObj) + AIG_MAX(Level0, Level1)); + } + Vec_PtrFree( vNodes ); + // get levels of the POs + LevelsMax = 0; + Aig_ManForEachPo( p, pObj, i ) + LevelsMax = AIG_MAX( LevelsMax, (int)Aig_ObjFanin0(pObj)->pData ); + return LevelsMax; +} + +/**Function************************************************************* + + Synopsis [Creates correct reference counters at each node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManCreateRefs( Aig_Man_t * p ) +{ + Aig_Obj_t * pObj; + int i; + if ( p->fRefCount ) + return; + p->fRefCount = 1; + // clear refs + Aig_ObjClearRef( Aig_ManConst1(p) ); + Aig_ManForEachPi( p, pObj, i ) + Aig_ObjClearRef( pObj ); + Aig_ManForEachNode( p, pObj, i ) + Aig_ObjClearRef( pObj ); + Aig_ManForEachPo( p, pObj, i ) + Aig_ObjClearRef( pObj ); + // set refs + Aig_ManForEachNode( p, pObj, i ) + { + Aig_ObjRef( Aig_ObjFanin0(pObj) ); + Aig_ObjRef( Aig_ObjFanin1(pObj) ); + } + Aig_ManForEachPo( p, pObj, i ) + Aig_ObjRef( Aig_ObjFanin0(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Counts the number of AIG nodes rooted at this cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ConeMark_rec( Aig_Obj_t * pObj ) +{ + assert( !Aig_IsComplement(pObj) ); + if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) ) + return; + Aig_ConeMark_rec( Aig_ObjFanin0(pObj) ); + Aig_ConeMark_rec( Aig_ObjFanin1(pObj) ); + assert( !Aig_ObjIsMarkA(pObj) ); // loop detection + Aig_ObjSetMarkA( pObj ); +} + +/**Function************************************************************* + + Synopsis [Counts the number of AIG nodes rooted at this cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ConeCleanAndMark_rec( Aig_Obj_t * pObj ) +{ + assert( !Aig_IsComplement(pObj) ); + if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) ) + return; + Aig_ConeCleanAndMark_rec( Aig_ObjFanin0(pObj) ); + Aig_ConeCleanAndMark_rec( Aig_ObjFanin1(pObj) ); + assert( !Aig_ObjIsMarkA(pObj) ); // loop detection + Aig_ObjSetMarkA( pObj ); + pObj->pData = NULL; +} + +/**Function************************************************************* + + Synopsis [Counts the number of AIG nodes rooted at this cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_ConeCountAndMark_rec( Aig_Obj_t * pObj ) +{ + int Counter; + assert( !Aig_IsComplement(pObj) ); + if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) ) + return 0; + Counter = 1 + Aig_ConeCountAndMark_rec( Aig_ObjFanin0(pObj) ) + + Aig_ConeCountAndMark_rec( Aig_ObjFanin1(pObj) ); + assert( !Aig_ObjIsMarkA(pObj) ); // loop detection + Aig_ObjSetMarkA( pObj ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Counts the number of AIG nodes rooted at this cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ConeUnmark_rec( Aig_Obj_t * pObj ) +{ + assert( !Aig_IsComplement(pObj) ); + if ( !Aig_ObjIsNode(pObj) || !Aig_ObjIsMarkA(pObj) ) + return; + Aig_ConeUnmark_rec( Aig_ObjFanin0(pObj) ); + Aig_ConeUnmark_rec( Aig_ObjFanin1(pObj) ); + assert( Aig_ObjIsMarkA(pObj) ); // loop detection + Aig_ObjClearMarkA( pObj ); +} + +/**Function************************************************************* + + Synopsis [Counts the number of AIG nodes rooted at this cone.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_DagSize( Aig_Obj_t * pObj ) +{ + int Counter; + Counter = Aig_ConeCountAndMark_rec( Aig_Regular(pObj) ); + Aig_ConeUnmark_rec( Aig_Regular(pObj) ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Transfers the AIG from one manager into another.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_Transfer_rec( Aig_Man_t * pDest, Aig_Obj_t * pObj ) +{ + assert( !Aig_IsComplement(pObj) ); + if ( !Aig_ObjIsNode(pObj) || Aig_ObjIsMarkA(pObj) ) + return; + Aig_Transfer_rec( pDest, Aig_ObjFanin0(pObj) ); + Aig_Transfer_rec( pDest, Aig_ObjFanin1(pObj) ); + pObj->pData = Aig_And( pDest, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + assert( !Aig_ObjIsMarkA(pObj) ); // loop detection + Aig_ObjSetMarkA( pObj ); +} + +/**Function************************************************************* + + Synopsis [Transfers the AIG from one manager into another.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_Transfer( Aig_Man_t * pSour, Aig_Man_t * pDest, Aig_Obj_t * pRoot, int nVars ) +{ + Aig_Obj_t * pObj; + int i; + // solve simple cases + if ( pSour == pDest ) + return pRoot; + if ( Aig_ObjIsConst1( Aig_Regular(pRoot) ) ) + return Aig_NotCond( Aig_ManConst1(pDest), Aig_IsComplement(pRoot) ); + // set the PI mapping + Aig_ManForEachPi( pDest, pObj, i ) + if ( i < nVars ) + Aig_IthVar(pSour, i)->pData = Aig_IthVar(pDest, i); + // transfer and set markings + Aig_Transfer_rec( pDest, Aig_Regular(pRoot) ); + // clear the markings + Aig_ConeUnmark_rec( Aig_Regular(pRoot) ); + return Aig_NotCond( Aig_Regular(pRoot)->pData, Aig_IsComplement(pRoot) ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/aig/aigMan.c b/src/temp/aig/aigMan.c new file mode 100644 index 00000000..af6df62d --- /dev/null +++ b/src/temp/aig/aigMan.c @@ -0,0 +1,161 @@ +/**CFile**************************************************************** + + FileName [aigMan.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Minimalistic And-Inverter Graph package.] + + Synopsis [AIG manager.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: aig_.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Starts the AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Aig_ManStart() +{ + Aig_Man_t * p; + // start the manager + p = ALLOC( Aig_Man_t, 1 ); + memset( p, 0, sizeof(Aig_Man_t) ); + // perform initializations + p->nTravIds = 1; + p->fRefCount = 1; + p->fCatchExor = 0; + // allocate arrays for nodes + p->vPis = Vec_PtrAlloc( 100 ); + p->vPos = Vec_PtrAlloc( 100 ); + // prepare the internal memory manager + Aig_ManStartMemory( p ); + // create the constant node + p->pConst1 = Aig_ManFetchMemory( p ); + p->pConst1->fPhase = 1; + p->nCreated = 1; + // start the table + p->nTableSize = 10007; + p->pTable = ALLOC( Aig_Obj_t *, p->nTableSize ); + memset( p->pTable, 0, sizeof(Aig_Obj_t *) * p->nTableSize ); + return p; +} + +/**Function************************************************************* + + Synopsis [Stops the AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManStop( Aig_Man_t * p ) +{ + Aig_Obj_t * pObj; + int i; + // make sure the nodes have clean marks + pObj = Aig_ManConst1(p); + assert( !pObj->fMarkA && !pObj->fMarkB ); + Aig_ManForEachPi( p, pObj, i ) + assert( !pObj->fMarkA && !pObj->fMarkB ); + Aig_ManForEachPo( p, pObj, i ) + assert( !pObj->fMarkA && !pObj->fMarkB ); + Aig_ManForEachNode( p, pObj, i ) + assert( !pObj->fMarkA && !pObj->fMarkB ); + // print time + if ( p->time1 ) { PRT( "time1", p->time1 ); } + if ( p->time2 ) { PRT( "time2", p->time2 ); } +// Aig_TableProfile( p ); + if ( p->vChunks ) Aig_ManStopMemory( p ); + if ( p->vPis ) Vec_PtrFree( p->vPis ); + if ( p->vPos ) Vec_PtrFree( p->vPos ); + free( p->pTable ); + free( p ); +} + +/**Function************************************************************* + + Synopsis [Returns the number of dangling nodes removed.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_ManCleanup( Aig_Man_t * p ) +{ + Vec_Ptr_t * vNodes; + Aig_Obj_t * pNode; + int i, nNodesOld; + assert( p->fRefCount ); + nNodesOld = Aig_ManNodeNum(p); + // collect roots of dangling nodes + vNodes = Vec_PtrAlloc( 100 ); + Aig_ManForEachNode( p, pNode, i ) + if ( Aig_ObjRefs(pNode) == 0 ) + Vec_PtrPush( vNodes, pNode ); + // recursively remove dangling nodes + Vec_PtrForEachEntry( vNodes, pNode, i ) + Aig_ObjDelete_rec( p, pNode ); + Vec_PtrFree( vNodes ); + return nNodesOld - Aig_ManNodeNum(p); +} + +/**Function************************************************************* + + Synopsis [Stops the AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManPrintStats( Aig_Man_t * p ) +{ + printf( "PI/PO = %d/%d. ", Aig_ManPiNum(p), Aig_ManPoNum(p) ); + printf( "A = %7d. ", Aig_ManAndNum(p) ); + printf( "X = %5d. ", Aig_ManExorNum(p) ); + printf( "Cre = %7d. ", p->nCreated ); + printf( "Del = %7d. ", p->nDeleted ); + printf( "Lev = %3d. ", Aig_ManCountLevels(p) ); + printf( "\n" ); +} + + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/aig/aigMem.c b/src/temp/aig/aigMem.c new file mode 100644 index 00000000..1be78a88 --- /dev/null +++ b/src/temp/aig/aigMem.c @@ -0,0 +1,115 @@ +/**CFile**************************************************************** + + FileName [aigMem.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Minimalistic And-Inverter Graph package.] + + Synopsis [Memory management for the AIG nodes.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: aigMem.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// memory management +#define IVY_PAGE_SIZE 12 // page size containing 2^IVY_PAGE_SIZE nodes +#define IVY_PAGE_MASK 4095 // page bitmask (2^IVY_PAGE_SIZE)-1 + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Starts the internal memory manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManStartMemory( Aig_Man_t * p ) +{ + p->vChunks = Vec_PtrAlloc( 128 ); + p->vPages = Vec_PtrAlloc( 128 ); +} + +/**Function************************************************************* + + Synopsis [Stops the internal memory manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManStopMemory( Aig_Man_t * p ) +{ + void * pMemory; + int i; + Vec_PtrForEachEntry( p->vChunks, pMemory, i ) + free( pMemory ); + Vec_PtrFree( p->vChunks ); + Vec_PtrFree( p->vPages ); + p->pListFree = NULL; +} + +/**Function************************************************************* + + Synopsis [Allocates additional memory for the nodes.] + + Description [Allocates IVY_PAGE_SIZE nodes. Aligns memory by 32 bytes. + Records the pointer to the AIG manager in the -1 entry.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManAddMemory( Aig_Man_t * p ) +{ + char * pMemory; + int i, nBytes; + assert( sizeof(Aig_Obj_t) <= 64 ); + assert( p->pListFree == NULL ); +// assert( (Aig_ManObjNum(p) & IVY_PAGE_MASK) == 0 ); + // allocate new memory page + nBytes = sizeof(Aig_Obj_t) * (1<<IVY_PAGE_SIZE) + 64; + pMemory = ALLOC( char, nBytes ); + Vec_PtrPush( p->vChunks, pMemory ); + // align memory at the 32-byte boundary + pMemory = pMemory + 64 - (((int)pMemory) & 63); + // remember the manager in the first entry + Vec_PtrPush( p->vPages, pMemory ); + // break the memory down into nodes + p->pListFree = (Aig_Obj_t *)pMemory; + for ( i = 1; i <= IVY_PAGE_MASK; i++ ) + { + *((char **)pMemory) = pMemory + sizeof(Aig_Obj_t); + pMemory += sizeof(Aig_Obj_t); + } + *((char **)pMemory) = NULL; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/aig/aigObj.c b/src/temp/aig/aigObj.c new file mode 100644 index 00000000..51ce6008 --- /dev/null +++ b/src/temp/aig/aigObj.c @@ -0,0 +1,228 @@ +/**CFile**************************************************************** + + FileName [aigObj.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Minimalistic And-Inverter Graph package.] + + Synopsis [Adding/removing objects.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: aigObj.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates primary input.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_ObjCreatePi( Aig_Man_t * p ) +{ + Aig_Obj_t * pObj; + pObj = Aig_ManFetchMemory( p ); + pObj->Type = AIG_PI; + Vec_PtrPush( p->vPis, pObj ); + p->nObjs[AIG_PI]++; + p->nCreated++; + return pObj; +} + +/**Function************************************************************* + + Synopsis [Creates primary output with the given driver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_ObjCreatePo( Aig_Man_t * p, Aig_Obj_t * pDriver ) +{ + Aig_Obj_t * pObj; + pObj = Aig_ManFetchMemory( p ); + pObj->Type = AIG_PO; + Vec_PtrPush( p->vPos, pObj ); + // add connections + pObj->pFanin0 = pDriver; + if ( p->fRefCount ) + Aig_ObjRef( Aig_Regular(pDriver) ); + else + pObj->nRefs = Aig_ObjLevel( Aig_Regular(pDriver) ); + // update node counters of the manager + p->nObjs[AIG_PO]++; + p->nCreated++; + return pObj; +} + +/**Function************************************************************* + + Synopsis [Create the new node assuming it does not exist.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_ObjCreate( Aig_Man_t * p, Aig_Obj_t * pGhost ) +{ + Aig_Obj_t * pObj; + assert( !Aig_IsComplement(pGhost) ); + assert( Aig_ObjIsNode(pGhost) ); + assert( pGhost == &p->Ghost ); + // get memory for the new object + pObj = Aig_ManFetchMemory( p ); + pObj->Type = pGhost->Type; + // add connections + Aig_ObjConnect( p, pObj, pGhost->pFanin0, pGhost->pFanin1 ); + // update node counters of the manager + p->nObjs[Aig_ObjType(pObj)]++; + p->nCreated++; + return pObj; +} + +/**Function************************************************************* + + Synopsis [Connect the object to the fanin.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ObjConnect( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFan0, Aig_Obj_t * pFan1 ) +{ + assert( !Aig_IsComplement(pObj) ); + assert( Aig_ObjIsNode(pObj) ); + // add the first fanin + pObj->pFanin0 = pFan0; + pObj->pFanin1 = pFan1; + // increment references of the fanins and add their fanouts + if ( p->fRefCount ) + { + if ( pFan0 != NULL ) + Aig_ObjRef( Aig_ObjFanin0(pObj) ); + if ( pFan1 != NULL ) + Aig_ObjRef( Aig_ObjFanin1(pObj) ); + } + else + pObj->nRefs = Aig_ObjLevelNew( pObj ); + // add the node to the structural hash table + Aig_TableInsert( p, pObj ); +} + +/**Function************************************************************* + + Synopsis [Connect the object to the fanin.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ObjDisconnect( Aig_Man_t * p, Aig_Obj_t * pObj ) +{ + assert( !Aig_IsComplement(pObj) ); + assert( Aig_ObjIsNode(pObj) ); + // remove connections + if ( pObj->pFanin0 != NULL ) + Aig_ObjDeref(Aig_ObjFanin0(pObj)); + if ( pObj->pFanin1 != NULL ) + Aig_ObjDeref(Aig_ObjFanin1(pObj)); + // remove the node from the structural hash table + Aig_TableDelete( p, pObj ); + // add the first fanin + pObj->pFanin0 = NULL; + pObj->pFanin1 = NULL; +} + +/**Function************************************************************* + + Synopsis [Deletes the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ObjDelete( Aig_Man_t * p, Aig_Obj_t * pObj ) +{ + assert( !Aig_IsComplement(pObj) ); + assert( !Aig_ObjIsTerm(pObj) ); + assert( Aig_ObjRefs(pObj) == 0 ); + // update node counters of the manager + p->nObjs[pObj->Type]--; + p->nDeleted++; + // remove connections + Aig_ObjDisconnect( p, pObj ); + // remove PIs/POs from the arrays + if ( Aig_ObjIsPi(pObj) ) + Vec_PtrRemove( p->vPis, pObj ); + // free the node + Aig_ManRecycleMemory( p, pObj ); +} + +/**Function************************************************************* + + Synopsis [Deletes the MFFC of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ObjDelete_rec( Aig_Man_t * p, Aig_Obj_t * pObj ) +{ + Aig_Obj_t * pFanin0, * pFanin1; + assert( !Aig_IsComplement(pObj) ); + if ( Aig_ObjIsConst1(pObj) || Aig_ObjIsPi(pObj) ) + return; + assert( Aig_ObjIsNode(pObj) ); + pFanin0 = Aig_ObjFanin0(pObj); + pFanin1 = Aig_ObjFanin1(pObj); + Aig_ObjDelete( p, pObj ); + if ( pFanin0 && !Aig_ObjIsNone(pFanin0) && Aig_ObjRefs(pFanin0) == 0 ) + Aig_ObjDelete_rec( p, pFanin0 ); + if ( pFanin1 && !Aig_ObjIsNone(pFanin1) && Aig_ObjRefs(pFanin1) == 0 ) + Aig_ObjDelete_rec( p, pFanin1 ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/aig/aigOper.c b/src/temp/aig/aigOper.c new file mode 100644 index 00000000..cad240ae --- /dev/null +++ b/src/temp/aig/aigOper.c @@ -0,0 +1,369 @@ +/**CFile**************************************************************** + + FileName [aigOper.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Minimalistic And-Inverter Graph package.] + + Synopsis [AIG operations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: aigOper.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// procedure to detect an EXOR gate +static inline int Aig_ObjIsExorType( Aig_Obj_t * p0, Aig_Obj_t * p1, Aig_Obj_t ** ppFan0, Aig_Obj_t ** ppFan1 ) +{ + if ( !Aig_IsComplement(p0) || !Aig_IsComplement(p1) ) + return 0; + p0 = Aig_Regular(p0); + p1 = Aig_Regular(p1); + if ( !Aig_ObjIsAnd(p0) || !Aig_ObjIsAnd(p1) ) + return 0; + if ( Aig_ObjFanin0(p0) != Aig_ObjFanin0(p1) || Aig_ObjFanin1(p0) != Aig_ObjFanin1(p1) ) + return 0; + if ( Aig_ObjFaninC0(p0) == Aig_ObjFaninC0(p1) || Aig_ObjFaninC1(p0) == Aig_ObjFaninC1(p1) ) + return 0; + *ppFan0 = Aig_ObjChild0(p0); + *ppFan1 = Aig_ObjChild1(p0); + return 1; +} + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Returns i-th elementary variable.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_IthVar( Aig_Man_t * p, int i ) +{ + int v; + for ( v = Aig_ManPiNum(p); v <= i; v++ ) + Aig_ObjCreatePi( p ); + assert( i < Vec_PtrSize(p->vPis) ); + return Aig_ManPi( p, i ); +} + +/**Function************************************************************* + + Synopsis [Perform one operation.] + + Description [The argument nodes can be complemented.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_Oper( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1, Aig_Type_t Type ) +{ + if ( Type == AIG_AND ) + return Aig_And( p, p0, p1 ); + if ( Type == AIG_EXOR ) + return Aig_Exor( p, p0, p1 ); + assert( 0 ); + return NULL; +} + +/**Function************************************************************* + + Synopsis [Performs canonicization step.] + + Description [The argument nodes can be complemented.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_And( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 ) +{ + Aig_Obj_t * pGhost, * pResult; +// Aig_Obj_t * pFan0, * pFan1; + // check trivial cases + if ( p0 == p1 ) + return p0; + if ( p0 == Aig_Not(p1) ) + return Aig_Not(p->pConst1); + if ( Aig_Regular(p0) == p->pConst1 ) + return p0 == p->pConst1 ? p1 : Aig_Not(p->pConst1); + if ( Aig_Regular(p1) == p->pConst1 ) + return p1 == p->pConst1 ? p0 : Aig_Not(p->pConst1); + // check if it can be an EXOR gate +// if ( Aig_ObjIsExorType( p0, p1, &pFan0, &pFan1 ) ) +// return Aig_Exor( p, pFan0, pFan1 ); + // check the table + pGhost = Aig_ObjCreateGhost( p, p0, p1, AIG_AND ); + if ( pResult = Aig_TableLookup( p, pGhost ) ) + return pResult; + return Aig_ObjCreate( p, pGhost ); +} + +/**Function************************************************************* + + Synopsis [Performs canonicization step.] + + Description [The argument nodes can be complemented.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_Exor( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 ) +{ +/* + Aig_Obj_t * pGhost, * pResult; + // check trivial cases + if ( p0 == p1 ) + return Aig_Not(p->pConst1); + if ( p0 == Aig_Not(p1) ) + return p->pConst1; + if ( Aig_Regular(p0) == p->pConst1 ) + return Aig_NotCond( p1, p0 == p->pConst1 ); + if ( Aig_Regular(p1) == p->pConst1 ) + return Aig_NotCond( p0, p1 == p->pConst1 ); + // check the table + pGhost = Aig_ObjCreateGhost( p, p0, p1, AIG_EXOR ); + if ( pResult = Aig_TableLookup( p, pGhost ) ) + return pResult; + return Aig_ObjCreate( p, pGhost ); +*/ + return Aig_Or( p, Aig_And(p, p0, Aig_Not(p1)), Aig_And(p, Aig_Not(p0), p1) ); +} + +/**Function************************************************************* + + Synopsis [Implements Boolean OR.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_Or( Aig_Man_t * p, Aig_Obj_t * p0, Aig_Obj_t * p1 ) +{ + return Aig_Not( Aig_And( p, Aig_Not(p0), Aig_Not(p1) ) ); +} + +/**Function************************************************************* + + Synopsis [Implements ITE operation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_Mux( Aig_Man_t * p, Aig_Obj_t * pC, Aig_Obj_t * p1, Aig_Obj_t * p0 ) +{ + Aig_Obj_t * pTempA1, * pTempA2, * pTempB1, * pTempB2, * pTemp; + int Count0, Count1; + // consider trivial cases + if ( p0 == Aig_Not(p1) ) + return Aig_Exor( p, pC, p0 ); + // other cases can be added + // implement the first MUX (F = C * x1 + C' * x0) + pTempA1 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, pC, p1, AIG_AND) ); + pTempA2 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pC), p0, AIG_AND) ); + if ( pTempA1 && pTempA2 ) + { + pTemp = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pTempA1), Aig_Not(pTempA2), AIG_AND) ); + if ( pTemp ) return Aig_Not(pTemp); + } + Count0 = (pTempA1 != NULL) + (pTempA2 != NULL); + // implement the second MUX (F' = C * x1' + C' * x0') + pTempB1 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, pC, Aig_Not(p1), AIG_AND) ); + pTempB2 = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pC), Aig_Not(p0), AIG_AND) ); + if ( pTempB1 && pTempB2 ) + { + pTemp = Aig_TableLookup( p, Aig_ObjCreateGhost(p, Aig_Not(pTempB1), Aig_Not(pTempB2), AIG_AND) ); + if ( pTemp ) return pTemp; + } + Count1 = (pTempB1 != NULL) + (pTempB2 != NULL); + // compare and decide which one to implement + if ( Count0 >= Count1 ) + { + pTempA1 = pTempA1? pTempA1 : Aig_And(p, pC, p1); + pTempA2 = pTempA2? pTempA2 : Aig_And(p, Aig_Not(pC), p0); + return Aig_Or( p, pTempA1, pTempA2 ); + } + pTempB1 = pTempB1? pTempB1 : Aig_And(p, pC, Aig_Not(p1)); + pTempB2 = pTempB2? pTempB2 : Aig_And(p, Aig_Not(pC), Aig_Not(p0)); + return Aig_Not( Aig_Or( p, pTempB1, pTempB2 ) ); + +// return Aig_Or( Aig_And(pC, p1), Aig_And(Aig_Not(pC), p0) ); +} + +/**Function************************************************************* + + Synopsis [Implements ITE operation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_Maj( Aig_Man_t * p, Aig_Obj_t * pA, Aig_Obj_t * pB, Aig_Obj_t * pC ) +{ + return Aig_Or( p, Aig_Or(p, Aig_And(p, pA, pB), Aig_And(p, pA, pC)), Aig_And(p, pB, pC) ); +} + +/**Function************************************************************* + + Synopsis [Constructs the well-balanced tree of gates.] + + Description [Disregards levels and possible logic sharing.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_Multi_rec( Aig_Man_t * p, Aig_Obj_t ** ppObjs, int nObjs, Aig_Type_t Type ) +{ + Aig_Obj_t * pObj1, * pObj2; + if ( nObjs == 1 ) + return ppObjs[0]; + pObj1 = Aig_Multi_rec( p, ppObjs, nObjs/2, Type ); + pObj2 = Aig_Multi_rec( p, ppObjs + nObjs/2, nObjs - nObjs/2, Type ); + return Aig_Oper( p, pObj1, pObj2, Type ); +} + +/**Function************************************************************* + + Synopsis [Old code.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_Multi( Aig_Man_t * p, Aig_Obj_t ** pArgs, int nArgs, Aig_Type_t Type ) +{ + assert( Type == AIG_AND || Type == AIG_EXOR ); + assert( nArgs > 0 ); + return Aig_Multi_rec( p, pArgs, nArgs, Type ); +} + +/**Function************************************************************* + + Synopsis [Implements the miter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_Miter( Aig_Man_t * p, Vec_Ptr_t * vPairs ) +{ + int i; + assert( vPairs->nSize > 0 ); + assert( vPairs->nSize % 2 == 0 ); + // go through the cubes of the node's SOP + for ( i = 0; i < vPairs->nSize; i += 2 ) + vPairs->pArray[i/2] = Aig_Not( Aig_Exor( p, vPairs->pArray[i], vPairs->pArray[i+1] ) ); + vPairs->nSize = vPairs->nSize/2; + return Aig_Not( Aig_Multi_rec( p, (Aig_Obj_t **)vPairs->pArray, vPairs->nSize, AIG_AND ) ); +} + +/**Function************************************************************* + + Synopsis [Creates AND function with nVars inputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_CreateAnd( Aig_Man_t * p, int nVars ) +{ + Aig_Obj_t * pFunc; + int i; + pFunc = Aig_ManConst1( p ); + for ( i = 0; i < nVars; i++ ) + pFunc = Aig_And( p, pFunc, Aig_IthVar(p, i) ); + return pFunc; +} + +/**Function************************************************************* + + Synopsis [Creates AND function with nVars inputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_CreateOr( Aig_Man_t * p, int nVars ) +{ + Aig_Obj_t * pFunc; + int i; + pFunc = Aig_ManConst0( p ); + for ( i = 0; i < nVars; i++ ) + pFunc = Aig_Or( p, pFunc, Aig_IthVar(p, i) ); + return pFunc; +} + +/**Function************************************************************* + + Synopsis [Creates AND function with nVars inputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_CreateExor( Aig_Man_t * p, int nVars ) +{ + Aig_Obj_t * pFunc; + int i; + pFunc = Aig_ManConst0( p ); + for ( i = 0; i < nVars; i++ ) + pFunc = Aig_Exor( p, pFunc, Aig_IthVar(p, i) ); + return pFunc; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/aig/aigTable.c b/src/temp/aig/aigTable.c new file mode 100644 index 00000000..338faa45 --- /dev/null +++ b/src/temp/aig/aigTable.c @@ -0,0 +1,266 @@ +/**CFile**************************************************************** + + FileName [aigTable.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Minimalistic And-Inverter Graph package.] + + Synopsis [Structural hashing table.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006. ] + + Revision [$Id: aigTable.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// hashing the node +static unsigned long Aig_Hash( Aig_Obj_t * pObj, int TableSize ) +{ + unsigned long Key = Aig_ObjIsExor(pObj) * 1699; + Key ^= (long)Aig_ObjFanin0(pObj) * 7937; + Key ^= (long)Aig_ObjFanin1(pObj) * 2971; + Key ^= Aig_ObjFaninC0(pObj) * 911; + Key ^= Aig_ObjFaninC1(pObj) * 353; + return Key % TableSize; +} + +// returns the place where this node is stored (or should be stored) +static Aig_Obj_t ** Aig_TableFind( Aig_Man_t * p, Aig_Obj_t * pObj ) +{ + int i; + assert( Aig_ObjChild0(pObj) && Aig_ObjChild1(pObj) ); + assert( Aig_ObjChild0(pObj) < Aig_ObjChild1(pObj) ); + for ( i = Aig_Hash(pObj, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize ) + if ( p->pTable[i] == pObj ) + break; + return p->pTable + i; +} + +static void Aig_TableResize( Aig_Man_t * p ); +static unsigned int Cudd_PrimeAig( unsigned int p ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Checks if node with the given attributes is in the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_TableLookup( Aig_Man_t * p, Aig_Obj_t * pGhost ) +{ + int i; + assert( !Aig_IsComplement(pGhost) ); + assert( Aig_ObjChild0(pGhost) && Aig_ObjChild1(pGhost) ); + assert( Aig_ObjChild0(pGhost) < Aig_ObjChild1(pGhost) ); + if ( p->fRefCount && (!Aig_ObjRefs(Aig_ObjFanin0(pGhost)) || !Aig_ObjRefs(Aig_ObjFanin1(pGhost))) ) + return NULL; + for ( i = Aig_Hash(pGhost, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize ) + { + if ( Aig_ObjChild0(p->pTable[i]) == Aig_ObjChild0(pGhost) && + Aig_ObjChild1(p->pTable[i]) == Aig_ObjChild1(pGhost) && + Aig_ObjType(p->pTable[i]) == Aig_ObjType(pGhost) ) + return p->pTable[i]; + } + return NULL; +} + +/**Function************************************************************* + + Synopsis [Adds the new node to the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_TableInsert( Aig_Man_t * p, Aig_Obj_t * pObj ) +{ + Aig_Obj_t ** ppPlace; + assert( !Aig_IsComplement(pObj) ); + assert( Aig_TableLookup(p, pObj) == NULL ); + if ( p->nTableSize < 2 * Aig_ManNodeNum(p) ) + Aig_TableResize( p ); + ppPlace = Aig_TableFind( p, pObj ); + assert( *ppPlace == NULL ); + *ppPlace = pObj; +} + +/**Function************************************************************* + + Synopsis [Deletes the node from the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_TableDelete( Aig_Man_t * p, Aig_Obj_t * pObj ) +{ + Aig_Obj_t * pEntry, ** ppPlace; + int i; + assert( !Aig_IsComplement(pObj) ); + ppPlace = Aig_TableFind( p, pObj ); + assert( *ppPlace == pObj ); // node should be in the table + *ppPlace = NULL; + // rehash the adjacent entries + i = ppPlace - p->pTable; + for ( i = (i+1) % p->nTableSize; p->pTable[i]; i = (i+1) % p->nTableSize ) + { + pEntry = p->pTable[i]; + p->pTable[i] = 0; + Aig_TableInsert( p, pEntry ); + } +} + +/**Function************************************************************* + + Synopsis [Count the number of nodes in the table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_TableCountEntries( Aig_Man_t * p ) +{ + int i, Counter = 0; + for ( i = 0; i < p->nTableSize; i++ ) + Counter += (p->pTable[i] != NULL); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Resizes the table.] + + Description [Typically this procedure should not be called.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_TableResize( Aig_Man_t * p ) +{ + Aig_Obj_t ** pTableOld, ** ppPlace; + int nTableSizeOld, Counter, nEntries, e, clk; +clk = clock(); + // save the old table + pTableOld = p->pTable; + nTableSizeOld = p->nTableSize; + // get the new table + p->nTableSize = Cudd_PrimeAig( 5 * Aig_ManNodeNum(p) ); + p->pTable = ALLOC( Aig_Obj_t *, p->nTableSize ); + memset( p->pTable, 0, sizeof(Aig_Obj_t *) * p->nTableSize ); + // rehash the entries from the old table + Counter = 0; + for ( e = 0; e < nTableSizeOld; e++ ) + { + if ( pTableOld[e] == 0 ) + continue; + Counter++; + // get the place where this entry goes in the table table + ppPlace = Aig_TableFind( p, pTableOld[e] ); + assert( *ppPlace == NULL ); // should not be in the table + *ppPlace = pTableOld[e]; + } + nEntries = Aig_ManNodeNum(p); +// assert( Counter == nEntries ); +// printf( "Increasing the structural table size from %6d to %6d. ", nTableSizeOld, p->nTableSize ); +// PRT( "Time", clock() - clk ); + // replace the table and the parameters + free( pTableOld ); +} + +/**Function******************************************************************** + + Synopsis [Profiles the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void Aig_TableProfile( Aig_Man_t * p ) +{ + int i, Counter = 0; + for ( i = 0; i < p->nTableSize; i++ ) + { + if ( p->pTable[i] ) + Counter++; + else if ( Counter ) + { + printf( "%d ", Counter ); + Counter = 0; + } + } +} + +/**Function******************************************************************** + + Synopsis [Returns the next prime >= p.] + + Description [Copied from CUDD, for stand-aloneness.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +unsigned int Cudd_PrimeAig( unsigned int p) +{ + int i,pn; + + p--; + do { + p++; + if (p&1) { + pn = 1; + i = 3; + while ((unsigned) (i * i) <= p) { + if (p % i == 0) { + pn = 0; + break; + } + i += 2; + } + } else { + pn = 0; + } + } while (!pn); + return(p); + +} /* end of Cudd_Prime */ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/aig/aigUtil.c b/src/temp/aig/aigUtil.c new file mode 100644 index 00000000..eb93cba1 --- /dev/null +++ b/src/temp/aig/aigUtil.c @@ -0,0 +1,257 @@ +/**CFile**************************************************************** + + FileName [aigUtil.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [Various procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: aigUtil.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Increments the current traversal ID of the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManIncrementTravId( Aig_Man_t * p ) +{ + if ( p->nTravIds >= (1<<30)-1 ) + Aig_ManCleanData( p ); + p->nTravIds++; +} + +/**Function************************************************************* + + Synopsis [Sets the DFS ordering of the nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManCleanData( Aig_Man_t * p ) +{ + Aig_Obj_t * pObj; + int i; + p->nTravIds = 1; + Aig_ManConst1(p)->pData = NULL; + Aig_ManForEachPi( p, pObj, i ) + pObj->pData = NULL; + Aig_ManForEachPo( p, pObj, i ) + pObj->pData = NULL; + Aig_ManForEachNode( p, pObj, i ) + pObj->pData = NULL; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_ObjIsMuxType( Aig_Obj_t * pNode ) +{ + Aig_Obj_t * pNode0, * pNode1; + // check that the node is regular + assert( !Aig_IsComplement(pNode) ); + // if the node is not AND, this is not MUX + if ( !Aig_ObjIsAnd(pNode) ) + return 0; + // if the children are not complemented, this is not MUX + if ( !Aig_ObjFaninC0(pNode) || !Aig_ObjFaninC1(pNode) ) + return 0; + // get children + pNode0 = Aig_ObjFanin0(pNode); + pNode1 = Aig_ObjFanin1(pNode); + // if the children are not ANDs, this is not MUX + if ( !Aig_ObjIsAnd(pNode0) || !Aig_ObjIsAnd(pNode1) ) + return 0; + // otherwise the node is MUX iff it has a pair of equal grandchildren + return (Aig_ObjFanin0(pNode0) == Aig_ObjFanin0(pNode1) && (Aig_ObjFaninC0(pNode0) ^ Aig_ObjFaninC0(pNode1))) || + (Aig_ObjFanin0(pNode0) == Aig_ObjFanin1(pNode1) && (Aig_ObjFaninC0(pNode0) ^ Aig_ObjFaninC1(pNode1))) || + (Aig_ObjFanin1(pNode0) == Aig_ObjFanin0(pNode1) && (Aig_ObjFaninC1(pNode0) ^ Aig_ObjFaninC0(pNode1))) || + (Aig_ObjFanin1(pNode0) == Aig_ObjFanin1(pNode1) && (Aig_ObjFaninC1(pNode0) ^ Aig_ObjFaninC1(pNode1))); +} + +/**Function************************************************************* + + Synopsis [Recognizes what nodes are control and data inputs of a MUX.] + + Description [If the node is a MUX, returns the control variable C. + Assigns nodes T and E to be the then and else variables of the MUX. + Node C is never complemented. Nodes T and E can be complemented. + This function also recognizes EXOR/NEXOR gates as MUXes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Aig_ObjRecognizeMux( Aig_Obj_t * pNode, Aig_Obj_t ** ppNodeT, Aig_Obj_t ** ppNodeE ) +{ + Aig_Obj_t * pNode0, * pNode1; + assert( !Aig_IsComplement(pNode) ); + assert( Aig_ObjIsMuxType(pNode) ); + // get children + pNode0 = Aig_ObjFanin0(pNode); + pNode1 = Aig_ObjFanin1(pNode); + + // find the control variable + if ( Aig_ObjFanin1(pNode0) == Aig_ObjFanin1(pNode1) && (Aig_ObjFaninC1(pNode0) ^ Aig_ObjFaninC1(pNode1)) ) + { +// if ( Fraig_IsComplement(pNode1->p2) ) + if ( Aig_ObjFaninC1(pNode0) ) + { // pNode2->p2 is positive phase of C + *ppNodeT = Aig_Not(Aig_ObjChild0(pNode1));//pNode2->p1); + *ppNodeE = Aig_Not(Aig_ObjChild0(pNode0));//pNode1->p1); + return Aig_ObjChild1(pNode1);//pNode2->p2; + } + else + { // pNode1->p2 is positive phase of C + *ppNodeT = Aig_Not(Aig_ObjChild0(pNode0));//pNode1->p1); + *ppNodeE = Aig_Not(Aig_ObjChild0(pNode1));//pNode2->p1); + return Aig_ObjChild1(pNode0);//pNode1->p2; + } + } + else if ( Aig_ObjFanin0(pNode0) == Aig_ObjFanin0(pNode1) && (Aig_ObjFaninC0(pNode0) ^ Aig_ObjFaninC0(pNode1)) ) + { +// if ( Fraig_IsComplement(pNode1->p1) ) + if ( Aig_ObjFaninC0(pNode0) ) + { // pNode2->p1 is positive phase of C + *ppNodeT = Aig_Not(Aig_ObjChild1(pNode1));//pNode2->p2); + *ppNodeE = Aig_Not(Aig_ObjChild1(pNode0));//pNode1->p2); + return Aig_ObjChild0(pNode1);//pNode2->p1; + } + else + { // pNode1->p1 is positive phase of C + *ppNodeT = Aig_Not(Aig_ObjChild1(pNode0));//pNode1->p2); + *ppNodeE = Aig_Not(Aig_ObjChild1(pNode1));//pNode2->p2); + return Aig_ObjChild0(pNode0);//pNode1->p1; + } + } + else if ( Aig_ObjFanin0(pNode0) == Aig_ObjFanin1(pNode1) && (Aig_ObjFaninC0(pNode0) ^ Aig_ObjFaninC1(pNode1)) ) + { +// if ( Fraig_IsComplement(pNode1->p1) ) + if ( Aig_ObjFaninC0(pNode0) ) + { // pNode2->p2 is positive phase of C + *ppNodeT = Aig_Not(Aig_ObjChild0(pNode1));//pNode2->p1); + *ppNodeE = Aig_Not(Aig_ObjChild1(pNode0));//pNode1->p2); + return Aig_ObjChild1(pNode1);//pNode2->p2; + } + else + { // pNode1->p1 is positive phase of C + *ppNodeT = Aig_Not(Aig_ObjChild1(pNode0));//pNode1->p2); + *ppNodeE = Aig_Not(Aig_ObjChild0(pNode1));//pNode2->p1); + return Aig_ObjChild0(pNode0);//pNode1->p1; + } + } + else if ( Aig_ObjFanin1(pNode0) == Aig_ObjFanin0(pNode1) && (Aig_ObjFaninC1(pNode0) ^ Aig_ObjFaninC0(pNode1)) ) + { +// if ( Fraig_IsComplement(pNode1->p2) ) + if ( Aig_ObjFaninC1(pNode0) ) + { // pNode2->p1 is positive phase of C + *ppNodeT = Aig_Not(Aig_ObjChild1(pNode1));//pNode2->p2); + *ppNodeE = Aig_Not(Aig_ObjChild0(pNode0));//pNode1->p1); + return Aig_ObjChild0(pNode1);//pNode2->p1; + } + else + { // pNode1->p2 is positive phase of C + *ppNodeT = Aig_Not(Aig_ObjChild0(pNode0));//pNode1->p1); + *ppNodeE = Aig_Not(Aig_ObjChild1(pNode1));//pNode2->p2); + return Aig_ObjChild1(pNode0);//pNode1->p2; + } + } + assert( 0 ); // this is not MUX + return NULL; +} + +/**Function************************************************************* + + Synopsis [Prints node in HAIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ObjPrintVerbose( Aig_Obj_t * pObj, int fHaig ) +{ + assert( !Aig_IsComplement(pObj) ); + printf( "Node %p : ", pObj ); + if ( Aig_ObjIsConst1(pObj) ) + printf( "constant 1" ); + else if ( Aig_ObjIsPi(pObj) ) + printf( "PI" ); + else + printf( "AND( %p%s, %p%s )", + Aig_ObjFanin0(pObj), (Aig_ObjFaninC0(pObj)? "\'" : " "), + Aig_ObjFanin1(pObj), (Aig_ObjFaninC1(pObj)? "\'" : " ") ); + printf( " (refs = %3d)", Aig_ObjRefs(pObj) ); +} + +/**Function************************************************************* + + Synopsis [Prints node in HAIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManPrintVerbose( Aig_Man_t * p, int fHaig ) +{ + Vec_Ptr_t * vNodes; + Aig_Obj_t * pObj; + int i; + printf( "PIs: " ); + Aig_ManForEachPi( p, pObj, i ) + printf( " %p", pObj ); + printf( "\n" ); + vNodes = Aig_ManDfs( p ); + Vec_PtrForEachEntry( vNodes, pObj, i ) + Aig_ObjPrintVerbose( pObj, fHaig ), printf( "\n" ); + printf( "\n" ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/sat/aig/rwr_.c b/src/temp/aig/aig_.c index 45e76f75..468413fa 100644 --- a/src/sat/aig/rwr_.c +++ b/src/temp/aig/aig_.c @@ -1,10 +1,10 @@ /**CFile**************************************************************** - FileName [rwr_.c] + FileName [ivy_.c] SystemName [ABC: Logic synthesis and verification system.] - PackageName [And-Inverter Graph package.] + PackageName [Minimalistic And-Inverter Graph package.] Synopsis [] @@ -12,13 +12,13 @@ Affiliation [UC Berkeley] - Date [Ver. 1.0. Started - June 20, 2005.] + Date [Ver. 1.0. Started - May 11, 2006.] - Revision [$Id: rwr_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + Revision [$Id: ivy_.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] ***********************************************************************/ -#include "aig.h" +#include "ivy.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// diff --git a/src/temp/ivy/ivy.h b/src/temp/ivy/ivy.h index a3cb714e..fcf58cb4 100644 --- a/src/temp/ivy/ivy.h +++ b/src/temp/ivy/ivy.h @@ -46,7 +46,7 @@ typedef int Ivy_Edge_t; // object types typedef enum { - IVY_NONE, // 0: non-existant object + IVY_NONE, // 0: non-existent object IVY_PI, // 1: primary input (and constant 1 node) IVY_PO, // 2: primary output IVY_ASSERT, // 3: assertion diff --git a/src/temp/player/playerAbc.c b/src/temp/player/playerAbc.c index 8e3823d5..4f45b607 100644 --- a/src/temp/player/playerAbc.c +++ b/src/temp/player/playerAbc.c @@ -110,7 +110,7 @@ Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * pNtk ) // create the manager pMan = Ivy_ManStart( Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), Abc_NtkNodeNum(pNtk) + 10 ); // create the PIs - Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan); + Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan); Abc_NtkForEachCi( pNtk, pObj, i ) pObj->pCopy = (Abc_Obj_t *)Ivy_ManPi(pMan, i); // perform the conversion of the internal nodes @@ -148,7 +148,7 @@ Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan ) pNtkNew = Abc_NtkStartFrom( pNtkOld, ABC_NTK_LOGIC, ABC_FUNC_SOP ); // transfer the pointers to the basic nodes Ivy_ManCleanTravId(pMan); - Ivy_ManConst1(pMan)->TravId = Abc_NtkConst1(pNtkNew)->Id; + Ivy_ManConst1(pMan)->TravId = Abc_AigConst1(pNtkNew)->Id; Abc_NtkForEachCi( pNtkNew, pObjNew, i ) Ivy_ManPi(pMan, i)->TravId = pObjNew->Id; // construct the logic network isomorphic to logic network in the AIG manager @@ -199,7 +199,7 @@ Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan ) else { // clone the node - pObjNew = Abc_NodeClone( pFaninNew ); + pObjNew = Abc_NtkCloneObj( pFaninNew ); // set complemented functions pObjNew->pData = Abc_SopRegister( pNtkNew->pManFunc, pFaninNew->pData ); Abc_SopComplement(pObjNew->pData); diff --git a/src/temp/player/playerToAbc.c b/src/temp/player/playerToAbc.c index ca84ded1..d53ad291 100644 --- a/src/temp/player/playerToAbc.c +++ b/src/temp/player/playerToAbc.c @@ -132,7 +132,7 @@ Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * pNtk ) // create the manager pMan = Ivy_ManStart(); // create the PIs - Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan); + Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan); Abc_NtkForEachCi( pNtk, pObj, i ) pObj->pCopy = (Abc_Obj_t *)Ivy_ObjCreatePi(pMan); // perform the conversion of the internal nodes @@ -168,7 +168,7 @@ Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p, int // start the new ABC network pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); // transfer the pointers to the basic nodes - Abc_ObjSetIvy2Abc( pMan, Ivy_ManConst1(pMan)->Id, Abc_NtkConst1(pNtkNew) ); + Abc_ObjSetIvy2Abc( pMan, Ivy_ManConst1(pMan)->Id, Abc_AigConst1(pNtkNew) ); Abc_NtkForEachCi( pNtkNew, pObjAbc, i ) Abc_ObjSetIvy2Abc( pMan, Ivy_ManPi(pMan, i)->Id, pObjAbc ); // recursively construct the network @@ -189,7 +189,7 @@ Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p, int else { // clone the node - pObj = Abc_NodeClone( pObjAbc ); + pObj = Abc_NtkCloneObj( pObjAbc ); // set complemented functions pObj->pData = Abc_SopRegister( pNtkNew->pManFunc, pObjAbc->pData ); Abc_SopComplement(pObj->pData); diff --git a/src/temp/ver/ver.h b/src/temp/ver/ver.h index ea1613c0..3e351840 100644 --- a/src/temp/ver/ver.h +++ b/src/temp/ver/ver.h @@ -51,8 +51,8 @@ struct Ver_Man_t_ ProgressBar * pProgress; // current network and library Abc_Ntk_t * pNtkCur; // the network under construction - st_table * pLibrary; // the current design library - st_table * pGateLib; // the current technology library + Abc_Lib_t * pDesign; // the current design + Abc_Lib_t * pGateLib; // the current technology library // error recovery FILE * Output; int fTopLevel; @@ -77,10 +77,10 @@ struct Ver_Man_t_ //////////////////////////////////////////////////////////////////////// /*=== verCore.c ========================================================*/ -extern st_table * Ver_ParseFile( char * pFileName, st_table * pGateLib, int fCheck ); +extern Abc_Lib_t * Ver_ParseFile( char * pFileName, Abc_Lib_t * pGateLib, int fCheck ); extern void Ver_ParsePrintErrorMessage( Ver_Man_t * p ); /*=== verFormula.c ========================================================*/ -extern DdNode * Ver_FormulaParser( char * pFormula, DdManager * dd, Vec_Ptr_t * vNames, Vec_Ptr_t * vStackFn, Vec_Int_t * vStackOp, char * pErrorMessage ); +extern void * Ver_FormulaParser( char * pFormula, void * pMan, Vec_Ptr_t * vNames, Vec_Ptr_t * vStackFn, Vec_Int_t * vStackOp, char * pErrorMessage ); /*=== verParse.c ========================================================*/ extern int Ver_ParseSkipComments( Ver_Man_t * p ); extern char * Ver_ParseGetName( Ver_Man_t * p ); diff --git a/src/temp/ver/verCore.c b/src/temp/ver/verCore.c index 8ef38aad..e868c4e3 100644 --- a/src/temp/ver/verCore.c +++ b/src/temp/ver/verCore.c @@ -34,6 +34,8 @@ typedef enum { VER_SIG_WIRE } Ver_SignalType_t; +static Ver_Man_t * Ver_ParseStart( char * pFileName, Abc_Lib_t * pGateLib ); +static void Ver_ParseStop( Ver_Man_t * p ); static void Ver_ParseFreeData( Ver_Man_t * p ); static void Ver_ParseInternal( Ver_Man_t * p, int fCheck ); static int Ver_ParseModule( Ver_Man_t * p ); @@ -45,7 +47,6 @@ static int Ver_ParseGate( Ver_Man_t * p, Abc_Ntk_t * pNtkGate ); static Abc_Obj_t * Ver_ParseCreatePi( Abc_Ntk_t * pNtk, char * pName ); static Abc_Obj_t * Ver_ParseCreatePo( Abc_Ntk_t * pNtk, char * pName ); -static Abc_Obj_t * Ver_ParseCreateConst( Abc_Ntk_t * pNtk, char * pName, bool fConst1 ); static Abc_Obj_t * Ver_ParseCreateLatch( Abc_Ntk_t * pNtk, char * pNetLI, char * pNetLO ); //////////////////////////////////////////////////////////////////////// @@ -63,39 +64,25 @@ static Abc_Obj_t * Ver_ParseCreateLatch( Abc_Ntk_t * pNtk, char * pNetLI, char * SeeAlso [] ***********************************************************************/ -st_table * Ver_ParseFile( char * pFileName, st_table * pGateLib, int fCheck ) +Abc_Lib_t * Ver_ParseFile( char * pFileName, Abc_Lib_t * pGateLib, int fCheck ) { Ver_Man_t * p; - st_table * pLibrary; - // start the file reader - p = ALLOC( Ver_Man_t, 1 ); - memset( p, 0, sizeof(Ver_Man_t) ); - p->pFileName = pFileName; - p->pReader = Ver_StreamAlloc( pFileName ); - p->pLibrary = st_init_table( st_ptrcmp, st_ptrhash ); - p->pGateLib = pGateLib; - p->Output = stdout; - p->pProgress = Extra_ProgressBarStart( stdout, Ver_StreamGetFileSize(p->pReader) ); - p->vNames = Vec_PtrAlloc( 100 ); - p->vStackFn = Vec_PtrAlloc( 100 ); - p->vStackOp = Vec_IntAlloc( 100 ); + Abc_Lib_t * pDesign; + // start the parser + p = Ver_ParseStart( pFileName, pGateLib ); // parse the file Ver_ParseInternal( p, fCheck ); + // save the result + pDesign = p->pDesign; + p->pDesign = NULL; // stop the parser - assert( p->pNtkCur == NULL ); - pLibrary = p->pLibrary; - Ver_StreamFree( p->pReader ); - Extra_ProgressBarStop( p->pProgress ); - Vec_PtrFree( p->vNames ); - Vec_PtrFree( p->vStackFn ); - Vec_IntFree( p->vStackOp ); - free( p ); - return pLibrary; + Ver_ParseStop( p ); + return pDesign; } /**Function************************************************************* - Synopsis [File parser.] + Synopsis [Start parser.] Description [] @@ -104,19 +91,26 @@ st_table * Ver_ParseFile( char * pFileName, st_table * pGateLib, int fCheck ) SeeAlso [] ***********************************************************************/ -void Ver_ParseFreeLibrary( st_table * pLibVer ) +Ver_Man_t * Ver_ParseStart( char * pFileName, Abc_Lib_t * pGateLib ) { - st_generator * gen; - Abc_Ntk_t * pNtk; - char * pName; - st_foreach_item( pLibVer, gen, (char**)&pName, (char**)&pNtk ) - Abc_NtkDelete( pNtk ); - st_free_table( pLibVer ); + Ver_Man_t * p; + p = ALLOC( Ver_Man_t, 1 ); + memset( p, 0, sizeof(Ver_Man_t) ); + p->pFileName = pFileName; + p->pReader = Ver_StreamAlloc( pFileName ); + p->pDesign = Abc_LibCreate( pFileName ); + p->pGateLib = pGateLib; + p->Output = stdout; + p->pProgress = Extra_ProgressBarStart( stdout, Ver_StreamGetFileSize(p->pReader) ); + p->vNames = Vec_PtrAlloc( 100 ); + p->vStackFn = Vec_PtrAlloc( 100 ); + p->vStackOp = Vec_IntAlloc( 100 ); + return p; } /**Function************************************************************* - Synopsis [File parser.] + Synopsis [Stop parser.] Description [] @@ -125,18 +119,15 @@ void Ver_ParseFreeLibrary( st_table * pLibVer ) SeeAlso [] ***********************************************************************/ -void Ver_ParseFreeData( Ver_Man_t * p ) +void Ver_ParseStop( Ver_Man_t * p ) { - if ( p->pNtkCur ) - { - Abc_NtkDelete( p->pNtkCur ); - p->pNtkCur = NULL; - } - if ( p->pLibrary ) - { - Ver_ParseFreeLibrary( p->pLibrary ); - p->pLibrary = NULL; - } + assert( p->pNtkCur == NULL ); + Ver_StreamFree( p->pReader ); + Extra_ProgressBarStop( p->pProgress ); + Vec_PtrFree( p->vNames ); + Vec_PtrFree( p->vStackFn ); + Vec_IntFree( p->vStackOp ); + free( p ); } /**Function************************************************************* @@ -165,9 +156,11 @@ void Ver_ParseInternal( Ver_Man_t * pMan, int fCheck ) Ver_ParsePrintErrorMessage( pMan ); return; } + // parse the module if ( !Ver_ParseModule( pMan ) ) return; + // check the network for correctness if ( fCheck && !Abc_NtkCheckRead( pMan->pNtkCur ) ) { @@ -177,20 +170,45 @@ void Ver_ParseInternal( Ver_Man_t * pMan, int fCheck ) return; } // add the module to the hash table - if ( st_is_member( pMan->pLibrary, pMan->pNtkCur->pName ) ) + if ( st_is_member( pMan->pDesign->tModules, pMan->pNtkCur->pName ) ) { pMan->fTopLevel = 1; sprintf( pMan->sError, "Module \"%s\" is defined more than once.", pMan->pNtkCur->pName ); Ver_ParsePrintErrorMessage( pMan ); return; } - st_insert( pMan->pLibrary, pMan->pNtkCur->pName, (char *)pMan->pNtkCur ); + st_insert( pMan->pDesign->tModules, pMan->pNtkCur->pName, (char *)pMan->pNtkCur ); pMan->pNtkCur = NULL; } } /**Function************************************************************* + Synopsis [File parser.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ver_ParseFreeData( Ver_Man_t * p ) +{ + if ( p->pNtkCur ) + { + Abc_NtkDelete( p->pNtkCur ); + p->pNtkCur = NULL; + } + if ( p->pDesign ) + { + Abc_LibFree( p->pDesign ); + p->pDesign = NULL; + } +} + +/**Function************************************************************* + Synopsis [Prints the error message including the file name and line number.] Description [] @@ -229,26 +247,29 @@ int Ver_ParseModule( Ver_Man_t * pMan ) { Ver_Stream_t * p = pMan->pReader; Abc_Ntk_t * pNtk, * pNtkTemp; - char * pWord; + Abc_Obj_t * pNet; + char * pWord, Symbol; int RetValue; - char Symbol; // start the current network assert( pMan->pNtkCur == NULL ); pNtk = pMan->pNtkCur = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_BLACKBOX ); -// pNtk = pMan->pNtkCur = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_BDD ); + + pNtk->ntkFunc = ABC_FUNC_AIG; + assert( pNtk->pManFunc == NULL ); + pNtk->pManFunc = pMan->pDesign->pManFunc; // get the network name pWord = Ver_ParseGetName( pMan ); pNtk->pName = Extra_UtilStrsav( pWord ); - pNtk->pSpec = Extra_UtilStrsav( pMan->pFileName ); - + pNtk->pSpec = NULL; +/* // create constant nodes and nets - Abc_NtkFindOrCreateNet( pNtk, "1'b0" ); - Abc_NtkFindOrCreateNet( pNtk, "1'b1" ); - Ver_ParseCreateConst( pNtk, "1'b0", 0 ); - Ver_ParseCreateConst( pNtk, "1'b1", 1 ); - + pNet = Abc_NtkFindOrCreateNet( pNtk, "1'b0" ); + Abc_ObjAddFanin( pNet, xxxx AigAbc_AigConst1(pNtk) ); + pNet = Abc_NtkFindOrCreateNet( pNtk, "1'b1" ); + Abc_ObjAddFanin( pNet, Abc_AigConst1(pNtk) ); +*/ // make sure we stopped at the opening paranthesis if ( Ver_StreamScanChar(p) != '(' ) { @@ -313,9 +334,9 @@ int Ver_ParseModule( Ver_Man_t * pMan ) Abc_NtkFinalizeRead( pNtk ); break; } - else if ( pMan->pGateLib && st_lookup(pMan->pGateLib, pWord, (char**)&pNtkTemp) ) // gate library + else if ( pMan->pGateLib && st_lookup(pMan->pGateLib->tModules, pWord, (char**)&pNtkTemp) ) // gate library RetValue = Ver_ParseGate( pMan, pNtkTemp ); - else if ( pMan->pLibrary && st_lookup(pMan->pLibrary, pWord, (char**)&pNtkTemp) ) // current design + else if ( pMan->pDesign && st_lookup(pMan->pDesign->tModules, pWord, (char**)&pNtkTemp) ) // current design RetValue = Ver_ParseGate( pMan, pNtkTemp ); else { @@ -334,17 +355,6 @@ int Ver_ParseModule( Ver_Man_t * pMan ) if ( pWord == NULL ) return 0; } - - if ( pNtk->ntkFunc == ABC_FUNC_BDD ) - { - Abc_Obj_t * pObj; - pObj = Abc_ObjFanin0( Abc_NtkFindNet( pNtk, "1'b0" ) ); - pObj->pData = Cudd_ReadLogicZero( pNtk->pManFunc ); - pObj = Abc_ObjFanin0( Abc_NtkFindNet( pNtk, "1'b1" ) ); - pObj->pData = Cudd_ReadOne( pNtk->pManFunc ); - Cudd_Ref( Cudd_ReadOne( pNtk->pManFunc ) ); - Cudd_Ref( Cudd_ReadOne( pNtk->pManFunc ) ); - } return 1; } @@ -882,26 +892,6 @@ Abc_Obj_t * Ver_ParseCreatePo( Abc_Ntk_t * pNtk, char * pName ) /**Function************************************************************* - Synopsis [Create a constant 0 node driving the net with this name.] - - Description [Assumes that the net already exists.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Ver_ParseCreateConst( Abc_Ntk_t * pNtk, char * pName, bool fConst1 ) -{ - Abc_Obj_t * pNet, * pTerm; - pTerm = fConst1? Abc_NodeCreateConst1(pNtk) : Abc_NodeCreateConst0(pNtk); - pNet = Abc_NtkFindNet(pNtk, pName); assert( pNet ); - Abc_ObjAddFanin( pNet, pTerm ); - return pTerm; -} - -/**Function************************************************************* - Synopsis [Create a latch with the given input/output.] Description [By default, the latch value is unknown (ABC_INIT_NONE).] diff --git a/src/temp/ver/verFormula.c b/src/temp/ver/verFormula.c index 7edb5bd9..cfeb3e5f 100644 --- a/src/temp/ver/verFormula.c +++ b/src/temp/ver/verFormula.c @@ -38,23 +38,22 @@ #define VER_PARSE_SYM_MUX2 ':' // second symbol of MUX // the list of opcodes (also specifying operation precedence) -#define VER_PARSE_OPER_NEG 10 // negation -#define VER_PARSE_OPER_AND 9 // logic AND -#define VER_PARSE_OPER_XOR 8 // logic EXOR (a'b | ab') -#define VER_PARSE_OPER_OR 7 // logic OR -#define VER_PARSE_OPER_EQU 6 // equvalence (a'b'| ab ) -#define VER_PARSE_OPER_MUX 5 // MUX (a'b | ac ) +#define VER_PARSE_OPER_NEG 7 // negation (highest precedence) +#define VER_PARSE_OPER_AND 6 // logic AND +#define VER_PARSE_OPER_XOR 5 // logic EXOR (a'b | ab') +#define VER_PARSE_OPER_OR 4 // logic OR +#define VER_PARSE_OPER_EQU 3 // equvalence (a'b'| ab ) +#define VER_PARSE_OPER_MUX 2 // MUX(a,b,c) (ab | a'c ) #define VER_PARSE_OPER_MARK 1 // OpStack token standing for an opening paranthesis // these are values of the internal Flag #define VER_PARSE_FLAG_START 1 // after the opening parenthesis #define VER_PARSE_FLAG_VAR 2 // after operation is received #define VER_PARSE_FLAG_OPER 3 // after operation symbol is received -#define VER_PARSE_FLAG_OPERMUX 4 // after operation symbol is received -#define VER_PARSE_FLAG_ERROR 5 // when error is detected +#define VER_PARSE_FLAG_ERROR 4 // when error is detected -static DdNode * Ver_FormulaParserTopOper( DdManager * dd, Vec_Ptr_t * vStackFn, int Oper ); -static int Ver_FormulaParserFindVar( char * pString, Vec_Ptr_t * vNames ); +static Aig_Obj_t * Ver_FormulaParserTopOper( Aig_Man_t * pMan, Vec_Ptr_t * vStackFn, int Oper ); +static int Ver_FormulaParserFindVar( char * pString, Vec_Ptr_t * vNames ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -71,9 +70,9 @@ static int Ver_FormulaParserFindVar( char * pString, Vec_Ptr_t * vNames ); SeeAlso [] ***********************************************************************/ -DdNode * Ver_FormulaParser( char * pFormula, DdManager * dd, Vec_Ptr_t * vNames, Vec_Ptr_t * vStackFn, Vec_Int_t * vStackOp, char * pErrorMessage ) +void * Ver_FormulaParser( char * pFormula, void * pMan, Vec_Ptr_t * vNames, Vec_Ptr_t * vStackFn, Vec_Int_t * vStackOp, char * pErrorMessage ) { - DdNode * bFunc, * bTemp; + Aig_Obj_t * bFunc, * bTemp; char * pTemp; int nParans, Flag; int Oper, Oper1, Oper2; @@ -120,7 +119,7 @@ DdNode * Ver_FormulaParser( char * pFormula, DdManager * dd, Vec_Ptr_t * vNames, // treat Constant 0 as a variable case VER_PARSE_SYM_CONST0: - Vec_PtrPush( vStackFn, b0 ); Cudd_Ref( b0 ); + Vec_PtrPush( vStackFn, Aig_ManConst0(pMan) ); // Cudd_Ref( Aig_ManConst0(pMan) ); if ( Flag == VER_PARSE_FLAG_VAR ) { sprintf( pErrorMessage, "Parse_FormulaParser(): No operation symbol before constant 0." ); @@ -132,7 +131,7 @@ DdNode * Ver_FormulaParser( char * pFormula, DdManager * dd, Vec_Ptr_t * vNames, // the same for Constant 1 case VER_PARSE_SYM_CONST1: - Vec_PtrPush( vStackFn, b1 ); Cudd_Ref( b1 ); + Vec_PtrPush( vStackFn, Aig_ManConst1(pMan) ); // Cudd_Ref( Aig_ManConst1(pMan) ); if ( Flag == VER_PARSE_FLAG_VAR ) { sprintf( pErrorMessage, "Parse_FormulaParser(): No operation symbol before constant 1." ); @@ -211,7 +210,7 @@ DdNode * Ver_FormulaParser( char * pFormula, DdManager * dd, Vec_Ptr_t * vNames, // } // perform the given operation - if ( Ver_FormulaParserTopOper( dd, vStackFn, Oper ) == NULL ) + if ( Ver_FormulaParserTopOper( pMan, vStackFn, Oper ) == NULL ) { sprintf( pErrorMessage, "Parse_FormulaParser(): Unknown operation\n" ); return NULL; @@ -240,8 +239,8 @@ DdNode * Ver_FormulaParser( char * pFormula, DdManager * dd, Vec_Ptr_t * vNames, sprintf( pErrorMessage, "Parse_FormulaParser(): Incorrect state." ); return NULL; } - bTemp = Cudd_bddIthVar(dd, v); - Vec_PtrPush( vStackFn, bTemp ); Cudd_Ref( bTemp ); + bTemp = Aig_IthVar( pMan, v ); + Vec_PtrPush( vStackFn, bTemp ); // Cudd_Ref( bTemp ); Flag = VER_PARSE_FLAG_VAR; break; } @@ -263,7 +262,8 @@ DdNode * Ver_FormulaParser( char * pFormula, DdManager * dd, Vec_Ptr_t * vNames, } else { - Vec_PtrPush( vStackFn, Cudd_Not(Vec_PtrPop(vStackFn)) ); +// Vec_PtrPush( vStackFn, Cudd_Not(Vec_PtrPop(vStackFn)) ); + Vec_PtrPush( vStackFn, Aig_Not(Vec_PtrPop(vStackFn)) ); } } else // if ( Flag == VER_PARSE_FLAG_OPER ) @@ -279,7 +279,7 @@ DdNode * Ver_FormulaParser( char * pFormula, DdManager * dd, Vec_Ptr_t * vNames, Oper2 = Vec_IntPop( vStackOp ); // the operation before the last one if ( Oper2 >= Oper1 ) { // if Oper2 precedence is higher or equal, execute it - if ( Ver_FormulaParserTopOper( dd, vStackFn, Oper2 ) == NULL ) + if ( Ver_FormulaParserTopOper( pMan, vStackFn, Oper2 ) == NULL ) { sprintf( pErrorMessage, "Parse_FormulaParser(): Unknown operation\n" ); return NULL; @@ -303,7 +303,7 @@ DdNode * Ver_FormulaParser( char * pFormula, DdManager * dd, Vec_Ptr_t * vNames, if ( !Vec_PtrSize(vStackFn) ) if ( !Vec_IntSize(vStackOp) ) { - Cudd_Deref( bFunc ); +// Cudd_Deref( bFunc ); return bFunc; } else @@ -314,8 +314,8 @@ DdNode * Ver_FormulaParser( char * pFormula, DdManager * dd, Vec_Ptr_t * vNames, else sprintf( pErrorMessage, "Parse_FormulaParser(): The input string is empty\n" ); } - Cudd_Ref( bFunc ); - Cudd_RecursiveDeref( dd, bFunc ); +// Cudd_Ref( bFunc ); +// Cudd_RecursiveDeref( dd, bFunc ); return NULL; } @@ -330,32 +330,33 @@ DdNode * Ver_FormulaParser( char * pFormula, DdManager * dd, Vec_Ptr_t * vNames, SeeAlso [] ***********************************************************************/ -DdNode * Ver_FormulaParserTopOper( DdManager * dd, Vec_Ptr_t * vStackFn, int Oper ) +Aig_Obj_t * Ver_FormulaParserTopOper( Aig_Man_t * pMan, Vec_Ptr_t * vStackFn, int Oper ) { - DdNode * bArg0, * bArg1, * bArg2, * bFunc; + Aig_Obj_t * bArg0, * bArg1, * bArg2, * bFunc; // perform the given operation bArg2 = Vec_PtrPop( vStackFn ); bArg1 = Vec_PtrPop( vStackFn ); if ( Oper == VER_PARSE_OPER_AND ) - bFunc = Cudd_bddAnd( dd, bArg1, bArg2 ); + bFunc = Aig_And( pMan, bArg1, bArg2 ); else if ( Oper == VER_PARSE_OPER_XOR ) - bFunc = Cudd_bddXor( dd, bArg1, bArg2 ); + bFunc = Aig_Exor( pMan, bArg1, bArg2 ); else if ( Oper == VER_PARSE_OPER_OR ) - bFunc = Cudd_bddOr( dd, bArg1, bArg2 ); + bFunc = Aig_Or( pMan, bArg1, bArg2 ); else if ( Oper == VER_PARSE_OPER_EQU ) - bFunc = Cudd_bddXnor( dd, bArg1, bArg2 ); + bFunc = Aig_Not( Aig_Exor( pMan, bArg1, bArg2 ) ); else if ( Oper == VER_PARSE_OPER_MUX ) { bArg0 = Vec_PtrPop( vStackFn ); - bFunc = Cudd_bddIte( dd, bArg0, bArg1, bArg2 ); Cudd_Ref( bFunc ); - Cudd_RecursiveDeref( dd, bArg0 ); - Cudd_Deref( bFunc ); +// bFunc = Cudd_bddIte( dd, bArg0, bArg1, bArg2 ); Cudd_Ref( bFunc ); + bFunc = Aig_Mux( pMan, bArg0, bArg1, bArg2 ); +// Cudd_RecursiveDeref( dd, bArg0 ); +// Cudd_Deref( bFunc ); } else return NULL; - Cudd_Ref( bFunc ); - Cudd_RecursiveDeref( dd, bArg1 ); - Cudd_RecursiveDeref( dd, bArg2 ); +// Cudd_Ref( bFunc ); +// Cudd_RecursiveDeref( dd, bArg1 ); +// Cudd_RecursiveDeref( dd, bArg2 ); Vec_PtrPush( vStackFn, bFunc ); return bFunc; } |