diff options
Diffstat (limited to 'src/base')
58 files changed, 2965 insertions, 3180 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index 3a619965..58c9c65b 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -82,7 +82,8 @@ typedef enum { ABC_OBJ_LATCH, // 3: latch ABC_OBJ_PI, // 4: primary input terminal ABC_OBJ_PO, // 5: primary output terminal - ABC_OBJ_OTHER // 6: unused + ABC_OBJ_BOX, // 6: abstract box + ABC_OBJ_OTHER // 7: unused } Abc_ObjType_t; // latch initial values @@ -90,7 +91,8 @@ typedef enum { ABC_INIT_NONE = 0, // 0: unknown ABC_INIT_ZERO, // 1: zero ABC_INIT_ONE, // 2: one - ABC_INIT_DC // 3: don't-care + ABC_INIT_DC, // 3: don't-care + ABC_INIT_OTHER // 4: unused } Abc_InitType_t; //////////////////////////////////////////////////////////////////////// @@ -154,6 +156,7 @@ struct Abc_Ntk_t_ Vec_Ptr_t * vCis; // the array of combinational inputs (PIs followed by latches) Vec_Ptr_t * vCos; // the array of combinational outputs (POs followed by latches) Vec_Ptr_t * vLats; // the array of latches (or the cutset in the sequential network) + Vec_Ptr_t * vCutSet; // the array of cutset nodes (used in the sequential AIG) // the stats about the number of living objects int nObjs; // the number of live objs int nNets; // the number of live nets @@ -177,8 +180,6 @@ struct Abc_Ntk_t_ Vec_Ptr_t * vSupps; // the satisfiable assignment of the miter int * pModel; - // initial states - Vec_Int_t * vInits; // the external don't-care if given Abc_Ntk_t * pExdc; // the EXDC network // miscellaneous data members @@ -205,6 +206,10 @@ struct Abc_Ntk_t_ #define ABC_MAX(a,b) (((a) > (b))? (a) : (b)) #define ABC_INFINITY (10000000) +// transforming floats into ints and back +static inline int Abc_Float2Int( float Val ) { return *((int *)&Val); } +static inline float Abc_Int2Float( int Num ) { return *((float *)&Num); } + // checking the network type static inline bool Abc_NtkIsNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_NETLIST; } static inline bool Abc_NtkIsLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_LOGIC; } @@ -224,12 +229,13 @@ static inline bool Abc_NtkIsMappedLogic( Abc_Ntk_t * pNtk ) { return pN static inline bool Abc_NtkIsComb( Abc_Ntk_t * pNtk ) { return pNtk->nLatches == 0; } // reading data members of the network -static inline char * Abc_NtkName( Abc_Ntk_t * pNtk ) { return pNtk->pName; } -static inline char * Abc_NtkSpec( Abc_Ntk_t * pNtk ) { return pNtk->pSpec; } -static inline int Abc_NtkTravId( Abc_Ntk_t * pNtk ) { return pNtk->nTravIds; } -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 char * Abc_NtkName( Abc_Ntk_t * pNtk ) { return pNtk->pName; } +static inline char * Abc_NtkSpec( Abc_Ntk_t * pNtk ) { return pNtk->pSpec; } +static inline int Abc_NtkTravId( Abc_Ntk_t * pNtk ) { return pNtk->nTravIds; } +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 pNtk->vObjs->pArray[0]; } // setting data members of the network static inline void Abc_NtkSetName ( Abc_Ntk_t * pNtk, char * pName ) { pNtk->pName = pName; } @@ -243,18 +249,20 @@ static inline int Abc_NtkObjNum( Abc_Ntk_t * pNtk ) { return pN static inline int Abc_NtkNetNum( Abc_Ntk_t * pNtk ) { return pNtk->nNets; } static inline int Abc_NtkNodeNum( Abc_Ntk_t * pNtk ) { return pNtk->nNodes; } static inline int Abc_NtkLatchNum( Abc_Ntk_t * pNtk ) { return pNtk->nLatches; } +static inline int Abc_NtkCutSetNodeNum( Abc_Ntk_t * pNtk ) { return Vec_PtrSize(pNtk->vCutSet); } static inline int Abc_NtkPiNum( Abc_Ntk_t * pNtk ) { return pNtk->nPis; } static inline int Abc_NtkPoNum( Abc_Ntk_t * pNtk ) { return pNtk->nPos; } static inline int Abc_NtkCiNum( Abc_Ntk_t * pNtk ) { return pNtk->vCis->nSize; } static inline int Abc_NtkCoNum( Abc_Ntk_t * pNtk ) { return pNtk->vCos->nSize; } // reading objects -static inline Abc_Obj_t * Abc_NtkObj( Abc_Ntk_t * pNtk, int i ) { assert( i < Vec_PtrSize(pNtk->vObjs) ); return (Abc_Obj_t *)pNtk->vObjs->pArray[i]; } -static inline Abc_Obj_t * Abc_NtkLatch( Abc_Ntk_t * pNtk, int i ) { assert( i < Vec_PtrSize(pNtk->vLats) ); return (Abc_Obj_t *)pNtk->vLats->pArray[i]; } -static inline Abc_Obj_t * Abc_NtkPi( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPiNum(pNtk) ); return (Abc_Obj_t *)pNtk->vCis->pArray[i]; } -static inline Abc_Obj_t * Abc_NtkPo( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPoNum(pNtk) ); return (Abc_Obj_t *)pNtk->vCos->pArray[i]; } -static inline Abc_Obj_t * Abc_NtkCi( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkCiNum(pNtk) ); return (Abc_Obj_t *)pNtk->vCis->pArray[i]; } -static inline Abc_Obj_t * Abc_NtkCo( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkCoNum(pNtk) ); return (Abc_Obj_t *)pNtk->vCos->pArray[i]; } +static inline Abc_Obj_t * Abc_NtkObj( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vObjs, i ); } +static inline Abc_Obj_t * Abc_NtkLatch( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vLats, i ); } +static inline Abc_Obj_t * Abc_NtkCutSetNode( Abc_Ntk_t * pNtk, int i){ return Vec_PtrEntry( pNtk->vCutSet, i ); } +static inline Abc_Obj_t * Abc_NtkCi( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vCis, i ); } +static inline Abc_Obj_t * Abc_NtkCo( Abc_Ntk_t * pNtk, int i ) { return Vec_PtrEntry( pNtk->vCos, i ); } +static inline Abc_Obj_t * Abc_NtkPi( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPiNum(pNtk) ); return Abc_NtkCi( pNtk, i ); } +static inline Abc_Obj_t * Abc_NtkPo( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPoNum(pNtk) ); return Abc_NtkCo( pNtk, i ); } // reading data members of the object static inline unsigned Abc_ObjType( Abc_Obj_t * pObj ) { return pObj->Type; } @@ -293,6 +301,7 @@ static inline int Abc_ObjFanoutNum( Abc_Obj_t * pObj ) { return pO static inline int Abc_ObjFaninId( Abc_Obj_t * pObj, int i) { return pObj->vFanins.pArray[i].iFan; } static inline int Abc_ObjFaninId0( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[0].iFan; } static inline int Abc_ObjFaninId1( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[1].iFan; } +static inline int Abc_ObjFanoutEdgeNum( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) { assert( Abc_NtkHasAig(pObj->pNtk) ); if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id ) return 0; if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id ) return 1; assert( 0 ); return -1; } static inline Abc_Obj_t * Abc_ObjFanout( Abc_Obj_t * pObj, int i ) { return (Abc_Obj_t *)pObj->pNtk->vObjs->pArray[ pObj->vFanouts.pArray[i].iFan ]; } static inline Abc_Obj_t * Abc_ObjFanout0( Abc_Obj_t * pObj ) { return (Abc_Obj_t *)pObj->pNtk->vObjs->pArray[ pObj->vFanouts.pArray[0].iFan ]; } static inline Abc_Obj_t * Abc_ObjFanin( Abc_Obj_t * pObj, int i ) { return (Abc_Obj_t *)pObj->pNtk->vObjs->pArray[ pObj->vFanins.pArray[i].iFan ]; } @@ -303,7 +312,6 @@ static inline Abc_Obj_t * Abc_ObjFanout0Ntk( Abc_Obj_t * pObj ) { return (A static inline bool Abc_ObjFaninC( Abc_Obj_t * pObj, int i ) { return pObj->vFanins.pArray[i].fCompl; } static inline bool Abc_ObjFaninC0( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[0].fCompl; } static inline bool Abc_ObjFaninC1( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[1].fCompl; } -static inline bool Abc_ObjFanoutC( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) { assert( !Abc_NtkIsLogic(pObj->pNtk) ); return (Abc_ObjFaninId0(pFanout) == (int)pObj->Id)? Abc_ObjFaninC0(pFanout) : Abc_ObjFaninC1(pFanout); } static inline int Abc_ObjFaninL( Abc_Obj_t * pObj, int i ) { return pObj->vFanins.pArray[i].nLats; } static inline int Abc_ObjFaninL0( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[0].nLats; } static inline int Abc_ObjFaninL1( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[1].nLats; } @@ -315,8 +323,6 @@ static inline Abc_Obj_t * Abc_ObjChild1( Abc_Obj_t * pObj ) { return Ab static inline Abc_Obj_t * Abc_ObjChildCopy( Abc_Obj_t * pObj, int i ){ return Abc_ObjNotCond( Abc_ObjFanin(pObj,i)->pCopy, Abc_ObjFaninC(pObj,i) );} 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) ); } -static inline Abc_Obj_t * Abc_ObjGetCopy( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjRegular(pObj)->pCopy, Abc_ObjIsComplement(pObj) ); } -static inline Abc_Obj_t * Abc_ObjFanoutFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) { assert( !Abc_NtkIsLogic(pObj->pNtk) ); return (Abc_ObjFaninId0(pFanout) == (int)pObj->Id)? Abc_ObjChild0(pFanout) : Abc_ObjChild1(pFanout); } static inline void Abc_ObjSetFaninC( Abc_Obj_t * pObj, int i ){ pObj->vFanins.pArray[i].fCompl = 1; } static inline void Abc_ObjXorFaninC( Abc_Obj_t * pObj, int i ){ pObj->vFanins.pArray[i].fCompl ^= 1; } static inline void Abc_ObjSetFaninL( Abc_Obj_t * pObj, int i, int nLats ) { pObj->vFanins.pArray[i].nLats = nLats; } @@ -325,6 +331,9 @@ static inline void Abc_ObjSetFaninL1( Abc_Obj_t * pObj, int nLats ) static inline void Abc_ObjAddFaninL( Abc_Obj_t * pObj, int i, int nLats ) { pObj->vFanins.pArray[i].nLats += nLats; } static inline void Abc_ObjAddFaninL0( Abc_Obj_t * pObj, int nLats ) { pObj->vFanins.pArray[0].nLats += nLats; } static inline void Abc_ObjAddFaninL1( Abc_Obj_t * pObj, int nLats ) { pObj->vFanins.pArray[1].nLats += nLats; } +static inline int Abc_ObjFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) { return Abc_ObjFaninL( pFanout, Abc_ObjFanoutEdgeNum(pObj,pFanout) ); } +static inline void Abc_ObjSetFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats ) { Abc_ObjSetFaninL( pFanout, Abc_ObjFanoutEdgeNum(pObj,pFanout), nLats ); } +static inline void Abc_ObjAddFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats ) { Abc_ObjAddFaninL( pFanout, Abc_ObjFanoutEdgeNum(pObj,pFanout), nLats ); } // checking the node type static inline bool Abc_NodeIsAigAnd( Abc_Obj_t * pNode ) { assert(Abc_NtkHasAig(pNode->pNtk)); return Abc_ObjFaninNum(pNode) == 2; } @@ -361,42 +370,42 @@ static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Ab //////////////////////////////////////////////////////////////////////// // objects of the network -#define Abc_NtkForEachObj( pNtk, pObj, i ) \ - for ( i = 0; i < Vec_PtrSize(pNtk->vObjs); i++ ) \ - if ( pObj = Abc_NtkObj(pNtk, i) ) -#define Abc_NtkForEachNet( pNtk, pNet, i ) \ - for ( i = 0; i < Vec_PtrSize(pNtk->vObjs); i++ ) \ - if ( (pNet = Abc_NtkObj(pNtk, i)) && Abc_ObjIsNet(pNet) ) -#define Abc_NtkForEachNode( pNtk, pNode, i ) \ - for ( i = 0; i < Vec_PtrSize(pNtk->vObjs); i++ ) \ - if ( (pNode = Abc_NtkObj(pNtk, i)) && Abc_ObjIsNode(pNode) ) -#define Abc_NtkForEachLatch( pNtk, pObj, i ) \ - for ( i = 0; i < Vec_PtrSize(pNtk->vLats); i++ ) \ - if ( pObj = Abc_NtkLatch(pNtk, i) ) -#define Abc_AigForEachAnd( pNtk, pNode, i ) \ - for ( i = 0; i < Vec_PtrSize(pNtk->vObjs); i++ ) \ - if ( (pNode = Abc_NtkObj(pNtk, i)) && Abc_NodeIsAigAnd(pNode) ) -#define Abc_SeqForEachCutsetNode( pNtk, pNode, i ) \ - for ( i = 0; i < Vec_PtrSize(pNtk->vLats); i++ ) \ - if ( (pNode = Abc_NtkLatch(pNtk, i)) ) +#define Abc_NtkForEachObj( pNtk, pObj, i ) \ + for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pObj) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ + if ( (pObj) == NULL ) {} else +#define Abc_NtkForEachNet( pNtk, pNet, i ) \ + for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNet) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ + if ( (pNet) == NULL || !Abc_ObjIsNet(pNet) ) {} else +#define Abc_NtkForEachLatch( pNtk, pLatch, i ) \ + for ( i = 0; (i < Vec_PtrSize((pNtk)->vLats)) && (((pLatch) = Abc_NtkLatch(pNtk, i)), 1); i++ )\ + if ( (pLatch) == NULL ) {} else +#define Abc_NtkForEachNode( pNtk, pNode, i ) \ + for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \ + 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 +#define Abc_SeqForEachCutsetNode( pNtk, pNode, i ) \ + for ( i = 0; (i < Abc_NtkCutSetNodeNum(pNtk)) && (((pNode) = Abc_NtkCutSetNode(pNtk, i)), 1); i++ )\ + if ( (pNode) == NULL ) {} else // inputs and outputs -#define Abc_NtkForEachPi( pNtk, pPi, i ) \ +#define Abc_NtkForEachPi( pNtk, pPi, i ) \ for ( i = 0; (i < Abc_NtkPiNum(pNtk)) && (((pPi) = Abc_NtkPi(pNtk, i)), 1); i++ ) -#define Abc_NtkForEachPo( pNtk, pPo, i ) \ +#define Abc_NtkForEachPo( pNtk, pPo, i ) \ for ( i = 0; (i < Abc_NtkPoNum(pNtk)) && (((pPo) = Abc_NtkPo(pNtk, i)), 1); i++ ) -#define Abc_NtkForEachCi( pNtk, pCi, i ) \ +#define Abc_NtkForEachCi( pNtk, pCi, i ) \ for ( i = 0; (i < Abc_NtkCiNum(pNtk)) && (((pCi) = Abc_NtkCi(pNtk, i)), 1); i++ ) -#define Abc_NtkForEachCo( pNtk, pCo, i ) \ +#define Abc_NtkForEachCo( pNtk, pCo, i ) \ for ( i = 0; (i < Abc_NtkCoNum(pNtk)) && (((pCo) = Abc_NtkCo(pNtk, i)), 1); i++ ) // fanin and fanouts -#define Abc_ObjForEachFanin( pObj, pFanin, i ) \ +#define Abc_ObjForEachFanin( pObj, pFanin, i ) \ for ( i = 0; (i < Abc_ObjFaninNum(pObj)) && (((pFanin) = Abc_ObjFanin(pObj, i)), 1); i++ ) -#define Abc_ObjForEachFanout( pObj, pFanout, i ) \ +#define Abc_ObjForEachFanout( pObj, pFanout, i ) \ for ( i = 0; (i < Abc_ObjFanoutNum(pObj)) && (((pFanout) = Abc_ObjFanout(pObj, i)), 1); i++ ) // cubes and literals -#define Abc_SopForEachCube( pSop, nFanins, pCube ) \ +#define Abc_SopForEachCube( pSop, nFanins, pCube ) \ for ( pCube = (pSop); *pCube; pCube += (nFanins) + 3 ) -#define Abc_CubeForEachVar( pCube, Value, i ) \ +#define Abc_CubeForEachVar( pCube, Value, i ) \ for ( i = 0; (pCube[i] != ' ') && (Value = pCube[i]); i++ ) @@ -406,12 +415,10 @@ static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Ab /*=== abcAig.c ==========================================================*/ extern Abc_Aig_t * Abc_AigAlloc( Abc_Ntk_t * pNtk ); -extern Abc_Aig_t * Abc_AigDup( Abc_Aig_t * pMan, Abc_Aig_t * pManNew ); 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_Aig_t * pMan ); 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_AigOr( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ); @@ -496,8 +503,6 @@ 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_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ); -extern Abc_Obj_t * Abc_NtkDupConst1( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew ); -extern Abc_Obj_t * Abc_NtkDupReset( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew ); extern void Abc_NtkDeleteObj( 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 ); @@ -515,6 +520,9 @@ extern Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFani extern Abc_Obj_t * Abc_NodeCreateOr( 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 ); /*=== abcNames.c ====================================================*/ extern char * Abc_NtkRegisterName( Abc_Ntk_t * pNtk, char * pName ); extern char * Abc_NtkRegisterNamePlus( Abc_Ntk_t * pNtk, char * pName, char * pSuffix ); @@ -632,7 +640,7 @@ extern char * Abc_SopFromTruthBin( char * pTruth ); extern char * Abc_SopFromTruthHex( char * pTruth ); /*=== abcStrash.c ==========================================================*/ extern Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup ); -extern Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode ); +extern Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode ); extern int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ); /*=== abcSweep.c ==========================================================*/ extern int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose ); diff --git a/src/base/abc/abcAig.c b/src/base/abc/abcAig.c index 0132a506..9f5ebb64 100644 --- a/src/base/abc/abcAig.c +++ b/src/base/abc/abcAig.c @@ -30,6 +30,8 @@ - there are no dangling nodes (the nodes without fanout) - the level of each AND gate reflects the levels of this fanins - the EXOR-status of each node is up-to-date + - 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 (Abc_AigAnd) - performing elementary Boolean operations (Abc_AigOr, Abc_AigXor, etc) @@ -48,8 +50,6 @@ struct Abc_Aig_t_ { Abc_Ntk_t * pNtkAig; // the AIG network - Abc_Obj_t * pConst1; // the constant 1 node -// Abc_Obj_t * pReset; // the sequential reset 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 @@ -123,74 +123,11 @@ Abc_Aig_t * Abc_AigAlloc( Abc_Ntk_t * pNtkAig ) pMan->vLevelsR = Vec_VecAlloc( 100 ); // save the current network pMan->pNtkAig = pNtkAig; - // allocate constant nodes - pMan->pConst1 = Abc_NtkCreateNode( pNtkAig ); - // subtract these nodes from the total number - pNtkAig->nNodes -= 1; return pMan; } /**Function************************************************************* - Synopsis [Duplicated the AIG manager.] - - Description [Assumes that CI/CO nodes are already created. - Transfers the latch attributes on the edges.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Aig_t * Abc_AigDup( Abc_Aig_t * pMan, Abc_Aig_t * pManNew ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj; - int i; - assert( Abc_NtkCiNum(pMan->pNtkAig) == Abc_NtkCiNum(pManNew->pNtkAig) ); - assert( Abc_NtkCoNum(pMan->pNtkAig) == Abc_NtkCoNum(pManNew->pNtkAig) ); - assert( Abc_NtkLatchNum(pMan->pNtkAig) == Abc_NtkLatchNum(pManNew->pNtkAig) ); - // set mapping of the constant nodes - Abc_AigConst1( pMan )->pCopy = Abc_AigConst1( pManNew ); - // set the mapping of CIs/COs - Abc_NtkForEachPi( pMan->pNtkAig, pObj, i ) - pObj->pCopy = Abc_NtkPi( pManNew->pNtkAig, i ); - Abc_NtkForEachPo( pMan->pNtkAig, pObj, i ) - pObj->pCopy = Abc_NtkPo( pManNew->pNtkAig, i ); - Abc_NtkForEachLatch( pMan->pNtkAig, pObj, i ) - pObj->pCopy = Abc_NtkLatch( pManNew->pNtkAig, i ); - // copy internal nodes - vNodes = Abc_AigDfs( pMan->pNtkAig, 0, 0 ); - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - if ( !Abc_NodeIsAigAnd(pObj) ) - continue; - pObj->pCopy = Abc_AigAnd( pManNew, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); -// printf( "Old = %4d. New = %4d.\n", pObj->Id, pObj->pCopy->Id ); - // transfer latch attributes - Abc_ObjSetFaninL0( pObj->pCopy, Abc_ObjFaninL0(pObj) ); - Abc_ObjSetFaninL1( pObj->pCopy, Abc_ObjFaninL1(pObj) ); - } - // relink the choice nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) - if ( pObj->pData ) - pObj->pCopy->pData = ((Abc_Obj_t *)pObj->pData)->pCopy; - Vec_PtrFree( vNodes ); - // relink the CO nodes - Abc_NtkForEachCo( pMan->pNtkAig, pObj, i ) - { - Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) ); - Abc_ObjSetFaninL0( pObj->pCopy, Abc_ObjFaninL0(pObj) ); - } - // get the number of nodes before and after - if ( Abc_NtkNodeNum(pMan->pNtkAig) != Abc_NtkNodeNum(pManNew->pNtkAig) ) - printf( "Warning: Structural hashing during duplication reduced %d nodes (to fix later).\n", - Abc_NtkNodeNum(pMan->pNtkAig) - Abc_NtkNodeNum(pManNew->pNtkAig) ); - return pManNew; -} - -/**Function************************************************************* - Synopsis [Deallocates the local AIG manager.] Description [] @@ -263,7 +200,7 @@ bool Abc_AigCheck( Abc_Aig_t * pMan ) nFanins = Abc_ObjFaninNum(pObj); if ( nFanins == 0 ) { - if ( pObj != pMan->pConst1 ) + if ( pObj != Abc_NtkConst1(pMan->pNtkAig) ) { printf( "Abc_AigCheck: The AIG has non-standard constant nodes.\n" ); return 0; @@ -323,23 +260,6 @@ int Abc_AigGetLevelNum( Abc_Ntk_t * pNtk ) return LevelsMax; } -/**Function************************************************************* - - Synopsis [Read the constant 1 node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_AigConst1( Abc_Aig_t * pMan ) -{ - return pMan->pConst1; -} - - /**Function************************************************************* @@ -429,24 +349,25 @@ Abc_Obj_t * Abc_AigAndCreateFrom( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * ***********************************************************************/ Abc_Obj_t * Abc_AigAndLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ) { - Abc_Obj_t * pAnd; + Abc_Obj_t * pAnd, * pConst1; unsigned Key; // check for trivial cases + pConst1 = Abc_NtkConst1(pMan->pNtkAig); if ( p0 == p1 ) return p0; if ( p0 == Abc_ObjNot(p1) ) - return Abc_ObjNot(pMan->pConst1); - if ( Abc_ObjRegular(p0) == pMan->pConst1 ) + return Abc_ObjNot(pConst1); + if ( Abc_ObjRegular(p0) == pConst1 ) { - if ( p0 == pMan->pConst1 ) + if ( p0 == pConst1 ) return p1; - return Abc_ObjNot(pMan->pConst1); + return Abc_ObjNot(pConst1); } - if ( Abc_ObjRegular(p1) == pMan->pConst1 ) + if ( Abc_ObjRegular(p1) == pConst1 ) { - if ( p1 == pMan->pConst1 ) + if ( p1 == pConst1 ) return p0; - return Abc_ObjNot(pMan->pConst1); + return Abc_ObjNot(pConst1); } // order the arguments if ( Abc_ObjRegular(p0)->Id > Abc_ObjRegular(p1)->Id ) @@ -667,7 +588,7 @@ Abc_Obj_t * Abc_AigMiter( 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(pMan->pConst1); + pMiter = Abc_ObjNot( Abc_NtkConst1(pMan->pNtkAig) ); for ( i = 0; i < vPairs->nSize; i += 2 ) { pXor = Abc_AigXor( pMan, vPairs->pArray[i], vPairs->pArray[i+1] ); @@ -1252,7 +1173,7 @@ void Abc_AigSetNodePhases( Abc_Ntk_t * pNtk ) Abc_Obj_t * pObj; int i; assert( Abc_NtkIsDfsOrdered(pNtk) ); - Abc_AigConst1(pNtk->pManFunc)->fPhase = 1; + Abc_NtkConst1(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 4f360071..dbd3e5fa 100644 --- a/src/base/abc/abcDfs.c +++ b/src/base/abc/abcDfs.c @@ -219,8 +219,8 @@ void Abc_NtkDfsReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) ***********************************************************************/ bool Abc_NtkIsDfsOrdered( Abc_Ntk_t * pNtk ) { - Abc_Obj_t * pNode; - int i; + Abc_Obj_t * pNode, * pFanin; + int i, k; // set the traversal ID Abc_NtkIncrementTravId( pNtk ); // mark the CIs @@ -229,12 +229,11 @@ bool Abc_NtkIsDfsOrdered( Abc_Ntk_t * pNtk ) // go through the nodes Abc_NtkForEachNode( pNtk, pNode, i ) { - if ( Abc_ObjFaninNum(pNode) == 0 ) - continue; - if ( !Abc_NodeIsTravIdCurrent(Abc_ObjFanin0(pNode)) ) - return 0; - if ( !Abc_NodeIsTravIdCurrent(Abc_ObjFanin1(pNode)) ) - return 0; + Abc_ObjForEachFanin( pNode, pFanin, k ) + { + if ( !Abc_NodeIsTravIdCurrent(pFanin) ) + return 0; + } Abc_NodeSetTravIdCurrent( pNode ); } return 1; @@ -672,7 +671,7 @@ int Abc_AigSetChoiceLevels( Abc_Ntk_t * pNtk ) Abc_NodeSetTravIdCurrent( pObj ); pObj->pCopy = NULL; } - pObj = Abc_AigConst1( pNtk->pManFunc ); + pObj = Abc_NtkConst1( pNtk ); Abc_NodeSetTravIdCurrent( pObj ); pObj->pCopy = NULL; // set levels of all other nodes diff --git a/src/base/abc/abcInt.h b/src/base/abc/abcInt.h index adf26345..967f5695 100644 --- a/src/base/abc/abcInt.h +++ b/src/base/abc/abcInt.h @@ -43,11 +43,6 @@ /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -/*=== 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 ); - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcNetlist.c b/src/base/abc/abcNetlist.c index c9533166..7d397060 100644 --- a/src/base/abc/abcNetlist.c +++ b/src/base/abc/abcNetlist.c @@ -19,7 +19,7 @@ ***********************************************************************/ #include "abc.h" -#include "abcs.h" +#include "seq.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -158,10 +158,7 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk ) Abc_NtkBddToSop(pNtk); // start the netlist by creating PI/PO/Latch objects - if ( Abc_NtkIsSopLogic(pNtk) ) - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_NETLIST, ABC_FUNC_SOP ); - else - pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_NETLIST, ABC_FUNC_BDD ); + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_NETLIST, pNtk->ntkFunc ); // create the CI nets and remember them in the new CI nodes Abc_NtkForEachCi( pNtk, pObj, i ) @@ -240,8 +237,6 @@ 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 ); - // create the constant node - Abc_NtkDupConst1( pNtk, pNtkNew ); // duplicate the nodes and create node functions Abc_NtkForEachNode( pNtk, pObj, i ) { @@ -317,8 +312,6 @@ Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk ) printf( "Warning: Choice nodes are skipped.\n" ); // start the network pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); - // create the constant node - Abc_NtkDupConst1( pNtk, pNtkNew ); // 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 diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c index 89215bbd..1afc2038 100644 --- a/src/base/abc/abcNtk.c +++ b/src/base/abc/abcNtk.c @@ -22,6 +22,7 @@ #include "abcInt.h" #include "main.h" #include "mio.h" +#include "seq.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -52,6 +53,7 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func ) // start the object storage pNtk->vObjs = Vec_PtrAlloc( 100 ); pNtk->vLats = Vec_PtrAlloc( 100 ); + pNtk->vCutSet = Vec_PtrAlloc( 100 ); pNtk->vCis = Vec_PtrAlloc( 100 ); pNtk->vCos = Vec_PtrAlloc( 100 ); pNtk->vPtrTemp = Vec_PtrAlloc( 100 ); @@ -75,11 +77,22 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func ) { if ( Abc_NtkIsStrash(pNtk) ) pNtk->pManFunc = Abc_AigAlloc( pNtk ); + else + pNtk->pManFunc = Seq_Create( pNtk ); } else if ( Abc_NtkHasMapping(pNtk) ) pNtk->pManFunc = Abc_FrameReadLibGen(); else 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 ); return pNtk; } @@ -106,6 +119,12 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_ // duplicate the name and the spec pNtkNew->pName = util_strsav(pNtk->pName); pNtkNew->pSpec = util_strsav(pNtk->pSpec); + // clean the node copy fields + Abc_NtkForEachNode( pNtk, pObj, i ) + pObj->pCopy = NULL; + // map the constant nodes + if ( Abc_NtkConst1(pNtk) ) + Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew); // clone the PIs/POs/latches Abc_NtkForEachPi( pNtk, pObj, i ) Abc_NtkDupObj(pNtkNew, pObj); @@ -117,12 +136,13 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_ Vec_PtrPush( pNtkNew->vCis, pObjNew ); Vec_PtrPush( pNtkNew->vCos, pObjNew ); } - // clean the node copy fields - Abc_NtkForEachNode( pNtk, pObj, i ) - pObj->pCopy = NULL; // transfer the names Abc_NtkDupCioNamesTable( pNtk, pNtkNew ); Abc_ManTimeDup( pNtk, pNtkNew ); + // check that the CI/CO/latches are copied correctly + assert( Abc_NtkCiNum(pNtk) == Abc_NtkCiNum(pNtkNew) ); + assert( Abc_NtkCoNum(pNtk) == Abc_NtkCoNum(pNtkNew) ); + assert( Abc_NtkLatchNum(pNtk) == Abc_NtkLatchNum(pNtkNew) ); return pNtkNew; } @@ -270,7 +290,43 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk ) pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc ); // copy the internal nodes if ( Abc_NtkIsStrash(pNtk) ) - Abc_AigDup( pNtk->pManFunc, pNtkNew->pManFunc ); + { + // copy the AND gates + Abc_AigForEachAnd( pNtk, pObj, i ) + pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); + // relink the choice nodes + Abc_AigForEachAnd( pNtk, pObj, i ) + if ( pObj->pData ) + pObj->pCopy->pData = ((Abc_Obj_t *)pObj->pData)->pCopy; + // relink the CO nodes + Abc_NtkForEachCo( pNtk, pObj, i ) + Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) ); + // get the number of nodes before and after + if ( Abc_NtkNodeNum(pNtk) != Abc_NtkNodeNum(pNtkNew) ) + printf( "Warning: Structural hashing during duplication reduced %d nodes (this is a minor bug).\n", + Abc_NtkNodeNum(pNtk) - Abc_NtkNodeNum(pNtkNew) ); + } + else if ( Abc_NtkIsSeq(pNtk) ) + { + // start the storage for initial states + Seq_Resize( pNtkNew->pManFunc, Abc_NtkObjNumMax(pNtk) ); + // copy the nodes + Abc_NtkForEachObj( pNtk, pObj, i ) + if ( pObj->pCopy == NULL ) + Abc_NtkDupObj(pNtkNew, pObj); + // connect the nodes + Abc_NtkForEachObj( pNtk, pObj, i ) + { + Abc_ObjForEachFanin( pObj, pFanin, k ) + { + Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); + if ( Abc_ObjFaninC(pObj, k) ) + Abc_ObjSetFaninC( pObj->pCopy, k ); + if ( Abc_ObjFaninL(pObj, k) > 0 ) + Seq_NodeDupLats( pObj->pCopy, pObj, k ); + } + } + } else { // duplicate the nets and nodes (CIs/COs/latches already dupped) @@ -281,23 +337,6 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk ) Abc_NtkForEachObj( pNtk, pObj, i ) Abc_ObjForEachFanin( pObj, pFanin, k ) Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); - // if it is a sequential networ, transfer attributes on edges - if ( Abc_NtkIsSeq(pNtk) ) - { - pNtkNew->vInits = Vec_IntStart( 2 * Abc_NtkObjNumMax(pNtkNew) ); - Abc_NtkForEachObj( pNtk, pObj, i ) - { - Abc_ObjForEachFanin( pObj, pFanin, k ) - { - if ( Abc_ObjFaninC(pObj, k) ) - Abc_ObjSetFaninC( pObj->pCopy, k ); - if ( Abc_ObjFaninL(pObj, k) > 0 ) - Abc_ObjSetFaninL( pObj->pCopy, k, Abc_ObjFaninL(pObj, k) ); - } - Vec_IntWriteEntry( pNtkNew->vInits, 2*pObj->pCopy->Id+0, Vec_IntEntry(pNtk->vInits, 2*pObj->Id+0) ); - Vec_IntWriteEntry( pNtkNew->vInits, 2*pObj->pCopy->Id+1, Vec_IntEntry(pNtk->vInits, 2*pObj->Id+1) ); - } - } } // duplicate the EXDC Ntk if ( pNtk->pExdc ) @@ -335,7 +374,10 @@ Abc_Ntk_t * Abc_NtkCreateOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAl sprintf( Buffer, "%s_%s", pNtk->pName, Abc_ObjName(pNode) ); pNtkNew->pName = util_strsav(Buffer); - // collect the nodes in the TFI of the output + // establish connection between the constant nodes + Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew); + + // collect the nodes in the TFI of the output (mark the TFI) vNodes = Abc_NtkDfsNodes( pNtk, &pNode, 1 ); // create the PIs Abc_NtkForEachCi( pNtk, pObj, i ) @@ -346,9 +388,6 @@ Abc_Ntk_t * Abc_NtkCreateOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAl Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) ); } } - // establish connection between the constant nodes - if ( Abc_NtkIsStrash(pNtk) ) - Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkNew->pManFunc); // copy the nodes Vec_PtrForEachEntry( vNodes, pObj, i ) @@ -412,11 +451,11 @@ Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * } // copy the nodes Vec_PtrForEachEntry( vNodes, pObj, i ) - pObj->pCopy = Abc_NodeStrash( pNtkNew->pManFunc, pObj ); + pObj->pCopy = Abc_NodeStrash( pNtkNew, pObj ); Vec_PtrFree( vNodes ); // add the PO - pFinal = Abc_AigConst1( pNtkNew->pManFunc ); + pFinal = Abc_NtkConst1( pNtkNew ); Vec_PtrForEachEntry( vRoots, pObj, i ) { if ( Abc_ObjIsCo(pObj) ) @@ -558,14 +597,14 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) if ( pNtk->pExdc ) Abc_NtkDelete( pNtk->pExdc ); // free the arrays - Vec_PtrFree( pNtk->vObjs ); - Vec_PtrFree( pNtk->vLats ); Vec_PtrFree( pNtk->vCis ); Vec_PtrFree( pNtk->vCos ); + Vec_PtrFree( pNtk->vObjs ); + Vec_PtrFree( pNtk->vLats ); + Vec_PtrFree( pNtk->vCutSet ); Vec_PtrFree( pNtk->vPtrTemp ); Vec_IntFree( pNtk->vIntTemp ); Vec_StrFree( pNtk->vStrTemp ); - if ( pNtk->vInits ) Vec_IntFree( pNtk->vInits ); if ( pNtk->pModel ) free( pNtk->pModel ); // free the hash table of Obj name into Obj ID stmm_free_table( pNtk->tName2Net ); @@ -591,6 +630,8 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) { if ( Abc_NtkIsStrash(pNtk) ) Abc_AigFree( pNtk->pManFunc ); + else + Seq_Delete( pNtk->pManFunc ); } else if ( !Abc_NtkHasMapping(pNtk) ) assert( 0 ); diff --git a/src/base/abc/abcObj.c b/src/base/abc/abcObj.c index 91b78f7c..b144066f 100644 --- a/src/base/abc/abcObj.c +++ b/src/base/abc/abcObj.c @@ -158,7 +158,7 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ) pObjNew->pData = Cudd_bddTransfer(pObj->pNtk->pManFunc, pNtkNew->pManFunc, pObj->pData), Cudd_Ref(pObjNew->pData); else if ( Abc_NtkHasMapping(pNtkNew) ) pObjNew->pData = pObj->pData; - else if ( Abc_NtkIsStrash(pNtkNew) ) + else if ( !Abc_NtkHasAig(pNtkNew) ) assert( 0 ); } } @@ -172,34 +172,6 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ) return pObjNew; } -/**Function************************************************************* - - Synopsis [Creates a new constant node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkDupConst1( Abc_Ntk_t * pNtkAig, Abc_Ntk_t * pNtkNew ) -{ - Abc_Obj_t * pConst1; - assert( Abc_NtkHasAig(pNtkAig) ); - assert( Abc_NtkIsLogic(pNtkNew) ); - pConst1 = Abc_AigConst1(pNtkAig->pManFunc); - if ( Abc_ObjFanoutNum(pConst1) > 0 ) - pConst1->pCopy = Abc_NodeCreateConst1( pNtkNew ); - else - { - // skip the 0-th entry to allow one-to-one match of object IDs - if ( pConst1->Id == 0 && pNtkNew->nNodes == 0 ) - Vec_PtrPush( pNtkNew->vObjs, NULL ); - } - - return pConst1->pCopy; -} /**Function************************************************************* @@ -518,9 +490,9 @@ Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk ) Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pNode; - if ( Abc_NtkHasAig(pNtk) ) - return Abc_AigConst1(pNtk->pManFunc); 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) ) @@ -759,7 +731,7 @@ bool Abc_NodeIsConst0( Abc_Obj_t * pNode ) if ( Abc_NtkHasBdd(pNtk) ) return Cudd_IsComplement(pNode->pData); if ( Abc_NtkHasAig(pNtk) ) - return Abc_ObjNot(pNode) == Abc_AigConst1(pNode->pNtk->pManFunc); + return Abc_ObjNot(pNode) == Abc_NtkConst1(pNode->pNtk); if ( Abc_NtkHasMapping(pNtk) ) return pNode->pData == Mio_LibraryReadConst0(Abc_FrameReadLibSuper()); assert( 0 ); @@ -787,7 +759,7 @@ bool Abc_NodeIsConst1( Abc_Obj_t * pNode ) if ( Abc_NtkHasBdd(pNtk) ) return !Cudd_IsComplement(pNode->pData); if ( Abc_NtkHasAig(pNtk) ) - return pNode == Abc_AigConst1(pNode->pNtk->pManFunc); + return pNode == Abc_NtkConst1(pNode->pNtk); if ( Abc_NtkHasMapping(pNtk) ) return pNode->pData == Mio_LibraryReadConst1(Abc_FrameReadLibSuper()); assert( 0 ); diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index 591f9055..5d7b4302 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -22,7 +22,7 @@ #include "main.h" #include "mio.h" #include "dec.h" -#include "abcs.h" +#include "seq.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -938,18 +938,15 @@ void Abc_NtkReassignIds( Abc_Ntk_t * pNtk ) { Vec_Ptr_t * vNodes; Vec_Ptr_t * vObjsNew; - Abc_Obj_t * pNode, * pTemp; - Abc_Obj_t * pConst1 = NULL, * pReset = NULL; + Abc_Obj_t * pNode, * pTemp, * pConst1; int i, k; + assert( Abc_NtkIsStrash(pNtk) ); // start the array of objects with new IDs vObjsNew = Vec_PtrAlloc( pNtk->nObjs ); - // put constant nodes (if present) first - if ( Abc_NtkIsStrash(pNtk) ) - { - pConst1 = Abc_AigConst1(pNtk->pManFunc); - pConst1->Id = Vec_PtrSize( vObjsNew ); - Vec_PtrPush( vObjsNew, pConst1 ); - } + // put constant node first + pConst1 = Abc_NtkConst1(pNtk); + assert( pConst1->Id == 0 ); + Vec_PtrPush( vObjsNew, pConst1 ); // put PI nodes next Abc_NtkForEachPi( pNtk, pNode, i ) { @@ -972,7 +969,7 @@ void Abc_NtkReassignIds( Abc_Ntk_t * pNtk ) vNodes = Abc_NtkDfs( pNtk, 1 ); Vec_PtrForEachEntry( vNodes, pNode, i ) { - if ( pNode == pReset || pNode == pConst1 ) + if ( pNode == pConst1 ) continue; pNode->Id = Vec_PtrSize( vObjsNew ); Vec_PtrPush( vObjsNew, pNode ); @@ -992,6 +989,9 @@ void Abc_NtkReassignIds( Abc_Ntk_t * pNtk ) // replace the array of objs Vec_PtrFree( pNtk->vObjs ); pNtk->vObjs = vObjsNew; + + // rehash the AIG + Abc_AigRehash( pNtk->pManFunc ); } //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 073a7e21..d67daacc 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -25,7 +25,7 @@ #include "fpga.h" #include "pga.h" #include "cut.h" -#include "abcs.h" +#include "seq.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -4474,6 +4474,7 @@ int Abc_CommandPga( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } + if ( !Abc_NtkIsStrash(pNtk) ) { // strash and balance the network @@ -4599,7 +4600,7 @@ int Abc_CommandInit( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( Abc_NtkIsComb(pNtk) ) { fprintf( pErr, "The current network is combinational.\n" ); - return 1; + return 0; } if ( fZeros ) @@ -4712,7 +4713,7 @@ int Abc_CommandPipe( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: fprintf( pErr, "usage: pipe [-L num] [-h]\n" ); - fprintf( pErr, "\t inserts the given number of latches at the PIs\n" ); + fprintf( pErr, "\t inserts the given number of latches at each PI for pipelining\n" ); fprintf( pErr, "\t-L num : the number of latches to insert [default = %d]\n", nLatches ); fprintf( pErr, "\t-h : print the command usage\n"); return 1; @@ -4758,8 +4759,11 @@ int Abc_CommandSeq( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } -// printf( "This command is not yet implemented.\n" ); -// return 0; + if ( Abc_NtkIsSeq(pNtk) ) + { + fprintf( pErr, "The current network is already a sequential AIG.\n" ); + return 1; + } if ( !Abc_NtkIsStrash(pNtk) ) { @@ -4769,7 +4773,7 @@ int Abc_CommandSeq( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( Abc_NtkCountSelfFeedLatches(pNtk) ) { - fprintf( pErr, "Works AIG has self-feeding latches. Cannot continue.\n" ); + fprintf( pErr, "Sequential AIG cannot be created for designs with self-feeding latches.\n" ); return 1; } @@ -4844,7 +4848,7 @@ int Abc_CommandUnseq( Abc_Frame_t * pAbc, int argc, char ** argv ) // share the latches on the fanout edges if ( fShare ) - Abc_NtkSeqShareFanouts(pNtk); + Seq_NtkSeqShareFanouts(pNtk); // get the new network pNtkRes = Abc_NtkSeqToLogicSop( pNtk ); @@ -4893,7 +4897,7 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) // set defaults fForward = 0; fBackward = 0; - fInitial = 0; + fInitial = 1; fVerbose = 0; util_getopt_reset(); while ( ( c = util_getopt( argc, argv, "fbivh" ) ) != EOF ) @@ -4933,21 +4937,19 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) // get the new network if ( fForward ) - Abc_NtkSeqRetimeForward( pNtk, fVerbose ); + Seq_NtkSeqRetimeForward( pNtk, fInitial, fVerbose ); else if ( fBackward ) - Abc_NtkSeqRetimeBackward( pNtk, fVerbose ); - else if ( fInitial ) - Abc_NtkSeqRetimeInitial( pNtk, fVerbose ); + Seq_NtkSeqRetimeBackward( pNtk, fInitial, fVerbose ); else - Abc_NtkSeqRetimeDelay( pNtk, fVerbose ); + Seq_NtkSeqRetimeDelay( pNtk, fInitial, fVerbose ); return 0; usage: - fprintf( pErr, "usage: retime [-fbh]\n" ); + fprintf( pErr, "usage: retime [-fbih]\n" ); fprintf( pErr, "\t retimes sequential AIG (default is Pan's delay-optimal retiming)\n" ); fprintf( pErr, "\t-f : toggle forward retiming [default = %s]\n", fForward? "yes": "no" ); fprintf( pErr, "\t-b : toggle backward retiming [default = %s]\n", fBackward? "yes": "no" ); -// fprintf( pErr, "\t-i : toggle retiming for initial state [default = %s]\n", fInitial? "yes": "no" ); + fprintf( pErr, "\t-i : toggle computation of initial state [default = %s]\n", fInitial? "yes": "no" ); fprintf( pErr, "\t-h : print the command usage\n"); return 1; } @@ -5003,7 +5005,10 @@ int Abc_CommandSeqFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "Works only for sequential AIG (run \"seq\").\n" ); return 1; } -return 0; + + printf( "This command is not yet implemented.\n" ); + return 0; + // get the new network pNtkRes = Abc_NtkFpgaSeq( pNtk, fVerbose ); @@ -5075,7 +5080,11 @@ int Abc_CommandSeqMap( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "Works only for sequential AIG (run \"seq\").\n" ); return 1; } -return 0; + + printf( "This command is not yet implemented.\n" ); + return 0; + + // get the new network pNtkRes = Abc_NtkMapSeq( pNtk, fVerbose ); diff --git a/src/base/abci/abcBalance.c b/src/base/abci/abcBalance.c index 67aa0743..1adbfef7 100644 --- a/src/base/abci/abcBalance.c +++ b/src/base/abci/abcBalance.c @@ -83,8 +83,6 @@ void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplica Abc_Obj_t * pNode, * pDriver; int i; - // copy the constant node - Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkAig->pManFunc); // set the level of PIs of AIG according to the arrival times of the old network Abc_NtkSetNodeLevelsArrival( pNtk ); // allocate temporary storage for supergates @@ -128,7 +126,7 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_ vSuper = Abc_NodeBalanceCone( pNodeOld, vStorage, Level, fDuplicate ); if ( vSuper->nSize == 0 ) { // it means that the supergate contains two nodes in the opposite polarity - pNodeOld->pCopy = Abc_ObjNot(Abc_AigConst1(pMan)); + pNodeOld->pCopy = Abc_ObjNot(Abc_NtkConst1(pNtkNew)); return pNodeOld->pCopy; } // for each old node, derive the new well-balanced node diff --git a/src/base/abci/abcCut.c b/src/base/abci/abcCut.c index f61b40ea..f9be9cc5 100644 --- a/src/base/abci/abcCut.c +++ b/src/base/abci/abcCut.c @@ -56,6 +56,7 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) extern void Abc_NtkBalanceDetach( Abc_Ntk_t * pNtk ); assert( Abc_NtkIsStrash(pNtk) ); + if ( pParams->fMulti ) Abc_NtkBalanceAttach(pNtk); diff --git a/src/base/abci/abcDsd.c b/src/base/abci/abcDsd.c index 37e360e8..5c7f0d48 100644 --- a/src/base/abci/abcDsd.c +++ b/src/base/abci/abcDsd.c @@ -168,7 +168,7 @@ void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t * { Dsd_Node_t ** ppNodesDsd; Dsd_Node_t * pNodeDsd; - Abc_Obj_t * pNode, * pNodeNew, * pDriver, * pConst1; + Abc_Obj_t * pNode, * pNodeNew, * pDriver; int i, nNodesDsd; // save the CI nodes in the DSD nodes @@ -177,10 +177,6 @@ void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t * pNodeDsd = Dsd_ManagerReadInput( pManDsd, i ); Dsd_NodeSetMark( pNodeDsd, (int)pNode->pCopy ); } - // set the constant node - pConst1 = Abc_AigConst1(pNtk->pManFunc); - if ( Abc_ObjFanoutNum(pConst1) > 0 ) - pConst1->pCopy = Abc_NodeCreateConst1(pNtkNew); // collect DSD nodes in DFS order (leaves and const1 are not collected) ppNodesDsd = Dsd_TreeCollectNodesDfs( pManDsd, &nNodesDsd ); diff --git a/src/base/abci/abcFpga.c b/src/base/abci/abcFpga.c index 29a532c3..d70a1e97 100644 --- a/src/base/abci/abcFpga.c +++ b/src/base/abci/abcFpga.c @@ -150,7 +150,7 @@ Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, // consider the case of a constant if ( Abc_NodeIsConst(pNode) ) { - Abc_AigConst1(pNtk->pManFunc)->pCopy = (Abc_Obj_t *)Fpga_ManReadConst1(pMan); + Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Fpga_ManReadConst1(pMan); continue; } // add the node to the mapper @@ -204,8 +204,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 - if ( Abc_ObjFanoutNum( Abc_AigConst1(pNtk->pManFunc) ) > 0 ) - Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NodeCreateConst1(pNtkNew) ); + Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NtkConst1(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 0625660d..ac0d06be 100644 --- a/src/base/abci/abcFraig.c +++ b/src/base/abci/abcFraig.c @@ -35,7 +35,7 @@ static void Abc_NtkFraigRemapUsingExdc( Fraig_Man_t * pMan, Abc_Ntk_t static int Abc_NtkFraigTrustCheck( Abc_Ntk_t * pNtk ); static void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); -static Abc_Obj_t * Abc_NodeFraigTrust( Abc_Aig_t * pMan, Abc_Obj_t * pNode ); +static Abc_Obj_t * Abc_NodeFraigTrust( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -110,7 +110,7 @@ void * Abc_NtkToFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes, int fExd // map the constant node Abc_NtkCleanCopy( pNtk ); - Abc_AigConst1(pNtk->pManFunc)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan); + Abc_NtkConst1(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); @@ -165,7 +165,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_AigConst1(pNtkStrash->pManFunc)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan); + Abc_NtkConst1(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 ) @@ -282,7 +282,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_AigConst1(pNtkNew->pManFunc) ); + Fraig_NodeSetData1( Fraig_ManReadConst1(pMan), (Fraig_Node_t *)Abc_NtkConst1(pNtkNew) ); // process the nodes in topological order pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); Abc_NtkForEachCo( pNtk, pNode, i ) @@ -380,7 +380,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_AigConst1(pNtk->pManFunc); + pNode = Abc_NtkConst1(pNtk); if ( !stmm_find_or_add( tTable, (char *)Fraig_Regular(pNode->pCopy), (char ***)&ppSlot ) ) *ppSlot = pNode; Abc_NtkForEachCi( pNtk, pNode, i ) @@ -408,7 +408,6 @@ Abc_Ntk_t * Abc_NtkFromFraig2( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk ) // create the new network pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG ); - Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkNew->pManFunc); // perform strashing Abc_AigSetNodePhases( pNtk ); @@ -552,7 +551,6 @@ int Abc_NtkFraigTrustCheck( Abc_Ntk_t * pNtk ) void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) { ProgressBar * pProgress; - Abc_Aig_t * pMan = pNtkNew->pManFunc; Vec_Ptr_t * vNodes; Abc_Obj_t * pNode, * pNodeNew, * pObj; int i; @@ -566,7 +564,7 @@ void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) // get the node assert( Abc_ObjIsNode(pNode) ); // strash the node - pNodeNew = Abc_NodeFraigTrust( pMan, pNode ); + pNodeNew = Abc_NodeFraigTrust( pNtkNew, pNode ); // get the old object if ( Abc_NtkIsNetlist(pNtk) ) pObj = Abc_ObjFanout0( pNode ); // the fanout net @@ -592,10 +590,9 @@ void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NodeFraigTrust( Abc_Aig_t * pMan, Abc_Obj_t * pNode ) +Abc_Obj_t * Abc_NodeFraigTrust( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode ) { Abc_Obj_t * pSum, * pFanin; - Abc_Obj_t * pConst1 = Abc_AigConst1(pMan); void ** ppTail; int i, nFanins, fCompl; @@ -605,11 +602,11 @@ Abc_Obj_t * Abc_NodeFraigTrust( Abc_Aig_t * pMan, Abc_Obj_t * pNode ) assert( nFanins == Abc_SopGetVarNum(pNode->pData) ); // check if it is a constant if ( nFanins == 0 ) - return Abc_ObjNotCond( pConst1, Abc_SopIsConst0(pNode->pData) ); + return Abc_ObjNotCond( Abc_NtkConst1(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) ) - return Abc_AigAnd( pMan, + return Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, !Abc_SopGetIthCareLit(pNode->pData,0) ), Abc_ObjNotCond( Abc_ObjFanin1(pNode)->pCopy, !Abc_SopGetIthCareLit(pNode->pData,1) ) ); assert( Abc_SopIsOrType(pNode->pData) ); diff --git a/src/base/abci/abcMap.c b/src/base/abci/abcMap.c index ec832430..39bf15aa 100644 --- a/src/base/abci/abcMap.c +++ b/src/base/abci/abcMap.c @@ -56,11 +56,11 @@ static Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Sup ***********************************************************************/ Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fSwitching, int fVerbose ) { + int fShowSwitching = 1; Abc_Ntk_t * pNtkNew; Map_Man_t * pMan; Vec_Int_t * vSwitching; float * pSwitching = NULL; - int fShowSwitching = 0; int clk; assert( Abc_NtkIsStrash(pNtk) ); @@ -176,7 +176,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f // consider the case of a constant if ( Abc_NodeIsConst(pNode) ) { - Abc_AigConst1(pNtk->pManFunc)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan); + Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan); continue; } // add the node to the mapper @@ -231,8 +231,7 @@ Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk ) Abc_NtkForEachCi( pNtk, pNode, i ) Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy ); // set the constant node - if ( Abc_ObjFanoutNum( Abc_AigConst1(pNtk->pManFunc) ) > 0 ) - Map_NodeSetData( Map_ManReadConst1(pMan), 1, (char *)Abc_NodeCreateConst1(pNtkNew) ); + 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) ); diff --git a/src/base/abci/abcMiter.c b/src/base/abci/abcMiter.c index ae2a9ede..b5338127 100644 --- a/src/base/abci/abcMiter.c +++ b/src/base/abci/abcMiter.c @@ -29,7 +29,7 @@ static void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Ab static void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter ); static void Abc_NtkMiterAddCone( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pNode ); static void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb ); -static void Abc_NtkAddFrame( Abc_Ntk_t * pNetNew, Abc_Ntk_t * pNet, int iFrame, Vec_Ptr_t * vNodes ); +static void Abc_NtkAddFrame( Abc_Ntk_t * pNetNew, Abc_Ntk_t * pNet, int iFrame ); // to be exported typedef void (*AddFrameMapping)( Abc_Obj_t*, Abc_Obj_t*, int, void*); @@ -126,6 +126,9 @@ 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); + if ( fComb ) { // create new PIs and remember them in the old PIs @@ -194,26 +197,11 @@ void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtk ***********************************************************************/ void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter ) { - ProgressBar * pProgress; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode, * pConst1, * pConst1New; + Abc_Obj_t * pNode; int i; - // get the constant nodes - pConst1 = Abc_AigConst1( pNtk->pManFunc ); - pConst1New = Abc_AigConst1( pNtkMiter->pManFunc ); - // perform strashing - vNodes = Abc_NtkDfs( pNtk, 0 ); - pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - if ( pNode == pConst1 ) - pNode->pCopy = pConst1New; - else - pNode->pCopy = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); - } - Vec_PtrFree( vNodes ); - Extra_ProgressBarStop( pProgress ); + assert( Abc_NtkIsDfsOrdered(pNtk) ); + Abc_AigForEachAnd( pNtk, pNode, i ) + pNode->pCopy = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); } /**Function************************************************************* @@ -230,22 +218,15 @@ void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter ) void Abc_NtkMiterAddCone( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pRoot ) { Vec_Ptr_t * vNodes; - Abc_Obj_t * pNode, * pNodeNew, * pConst1, * pConst1New; + Abc_Obj_t * pNode; int i; - // get the constant nodes - pConst1 = Abc_AigConst1( pNtk->pManFunc ); - pConst1New = Abc_AigConst1( pNtkMiter->pManFunc ); + // map the constant nodes + Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkMiter); // perform strashing vNodes = Abc_NtkDfsNodes( pNtk, &pRoot, 1 ); - for ( i = 0; i < vNodes->nSize; i++ ) - { - pNode = vNodes->pArray[i]; - if ( pNode == pConst1 ) - pNodeNew = pConst1New; - else - pNodeNew = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); - pNode->pCopy = pNodeNew; - } + Vec_PtrForEachEntry( vNodes, pNode, i ) + if ( Abc_NodeIsAigAnd(pNode) ) + pNode->pCopy = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); Vec_PtrFree( vNodes ); } @@ -335,9 +316,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_AigConst1(pNtkMiter->pManFunc) ); + Abc_NtkCi(pNtk, In1)->pCopy = Abc_ObjNot( Abc_NtkConst1(pNtkMiter) ); if ( In2 >= 0 ) - Abc_NtkCi(pNtk, In2)->pCopy = Abc_AigConst1( pNtkMiter->pManFunc ); + Abc_NtkCi(pNtk, In2)->pCopy = Abc_NtkConst1( pNtkMiter ); // add the first cofactor Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot ); @@ -345,9 +326,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_AigConst1( pNtkMiter->pManFunc ); + Abc_NtkCi(pNtk, In1)->pCopy = Abc_NtkConst1( pNtkMiter ); if ( In2 >= 0 ) - Abc_NtkCi(pNtk, In2)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter->pManFunc) ); + Abc_NtkCi(pNtk, In2)->pCopy = Abc_ObjNot( Abc_NtkConst1(pNtkMiter) ); // add the second cofactor Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot ); @@ -395,7 +376,7 @@ int Abc_NtkMiterIsConstant( Abc_Ntk_t * pMiter ) pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,i) ); if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) ) { - assert( Abc_ObjRegular(pChild) == Abc_AigConst1(pMiter->pManFunc) ); + assert( Abc_ObjRegular(pChild) == Abc_NtkConst1(pMiter) ); if ( !Abc_ObjIsComplement(pChild) ) { // if the miter is constant 1, return immediately @@ -475,11 +456,11 @@ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial ) char Buffer[100]; ProgressBar * pProgress; Abc_Ntk_t * pNtkFrames; - Vec_Ptr_t * vNodes; Abc_Obj_t * pLatch, * pLatchNew; int i, Counter; assert( nFrames > 0 ); assert( Abc_NtkIsStrash(pNtk) ); + assert( Abc_NtkIsDfsOrdered(pNtk) ); // start the new network pNtkFrames = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG ); sprintf( Buffer, "%s_%d_frames", pNtk->pName, nFrames ); @@ -502,22 +483,20 @@ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial ) Counter++; } else - pLatch->pCopy = Abc_ObjNotCond( Abc_AigConst1(pNtkFrames->pManFunc), Abc_LatchIsInit0(pLatch) ); + pLatch->pCopy = Abc_ObjNotCond( Abc_NtkConst1(pNtkFrames), Abc_LatchIsInit0(pLatch) ); } if ( Counter ) printf( "Warning: %d uninitialized latches are replaced by free PI variables.\n", Counter ); } // create the timeframes - vNodes = Abc_NtkDfs( pNtk, 0 ); pProgress = Extra_ProgressBarStart( stdout, nFrames ); for ( i = 0; i < nFrames; i++ ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); - Abc_NtkAddFrame( pNtkFrames, pNtk, i, vNodes ); + Abc_NtkAddFrame( pNtkFrames, pNtk, i ); } Extra_ProgressBarStop( pProgress ); - Vec_PtrFree( vNodes ); // connect the new latches to the outputs of the last frame if ( !fInitial ) @@ -561,38 +540,26 @@ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial ) SeeAlso [] ***********************************************************************/ -void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame, Vec_Ptr_t * vNodes ) +void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame ) { char Buffer[10]; - Abc_Obj_t * pNode, * pNodeNew, * pLatch; - Abc_Obj_t * pConst1, * pConst1New; + Abc_Obj_t * pNode, * pLatch; int i; - // get the constant nodes - pConst1 = Abc_AigConst1( pNtk->pManFunc ); - pConst1New = Abc_AigConst1( pNtkFrames->pManFunc ); // 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); // add the new PI nodes Abc_NtkForEachPi( pNtk, pNode, i ) - { - pNodeNew = Abc_NtkDupObj( pNtkFrames, pNode ); - Abc_NtkLogicStoreNamePlus( pNodeNew, Abc_ObjName(pNode), Buffer ); - } + Abc_NtkLogicStoreNamePlus( Abc_NtkDupObj(pNtkFrames, pNode), Abc_ObjName(pNode), Buffer ); // add the internal nodes - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - if ( pNode == pConst1 ) - pNodeNew = pConst1New; - else - pNodeNew = Abc_AigAnd( pNtkFrames->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); - pNode->pCopy = pNodeNew; - } + Abc_AigForEachAnd( pNtk, pNode, i ) + pNode->pCopy = Abc_AigAnd( pNtkFrames->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); // add the new POs Abc_NtkForEachPo( pNtk, pNode, i ) { - pNodeNew = Abc_NtkDupObj( pNtkFrames, pNode ); - Abc_ObjAddFanin( pNodeNew, Abc_ObjChild0Copy(pNode) ); - Abc_NtkLogicStoreNamePlus( pNodeNew, Abc_ObjName(pNode), Buffer ); + Abc_NtkLogicStoreNamePlus( Abc_NtkDupObj(pNtkFrames, pNode), Abc_ObjName(pNode), Buffer ); + Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild0Copy(pNode) ); } // transfer the implementation of the latch drivers to the latches Abc_NtkForEachLatch( pNtk, pLatch, i ) @@ -648,7 +615,7 @@ Abc_Ntk_t * Abc_NtkFrames2( Abc_Ntk_t * pNtk, int nFrames, int fInitial, AddFram Counter++; } else { - pLatch->pCopy = Abc_ObjNotCond( Abc_AigConst1(pNtkFrames->pManFunc), Abc_LatchIsInit0(pLatch) ); + pLatch->pCopy = Abc_ObjNotCond( Abc_NtkConst1(pNtkFrames), Abc_LatchIsInit0(pLatch) ); } if (addFrameMapping) addFrameMapping(pLatch->pCopy, pLatch, 0, arg); @@ -718,8 +685,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_AigConst1( pNtk->pManFunc ); - pConst1New = Abc_AigConst1( pNtkFrames->pManFunc ); + pConst1 = Abc_NtkConst1( pNtk ); + pConst1New = Abc_NtkConst1( pNtkFrames ); // create the prefix to be added to the node names sprintf( Buffer, "_%02d", iFrame ); // add the new PI nodes diff --git a/src/base/abci/abcNtbdd.c b/src/base/abci/abcNtbdd.c index a09fde0f..fbc5e3ee 100644 --- a/src/base/abci/abcNtbdd.c +++ b/src/base/abci/abcNtbdd.c @@ -25,7 +25,7 @@ //////////////////////////////////////////////////////////////////////// static void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); -static Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pConst1 ); +static Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew ); static Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * pNtkNew, st_table * tBdd2Node ); static DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode ); @@ -149,11 +149,9 @@ void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) { ProgressBar * pProgress; DdManager * dd = pNtk->pManFunc; - Abc_Obj_t * pNode, * pNodeNew, * pConst1; + Abc_Obj_t * pNode, * pNodeNew; Vec_Ptr_t * vNodes; int i; - // create the constant one node - pConst1 = Abc_NodeCreateConst1( pNtkNew ); // perform conversion in the topological order vNodes = Abc_NtkDfs( pNtk, 0 ); pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); @@ -162,7 +160,7 @@ void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) Extra_ProgressBarUpdate( pProgress, i, NULL ); // convert one node assert( Abc_ObjIsNode(pNode) ); - pNodeNew = Abc_NodeBddToMuxes( pNode, pNtkNew, pConst1 ); + pNodeNew = Abc_NodeBddToMuxes( pNode, pNtkNew ); // mark the old node with the new one assert( pNode->pCopy == NULL ); pNode->pCopy = pNodeNew; @@ -182,7 +180,7 @@ void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pConst1 ) +Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew ) { DdManager * dd = pNodeOld->pNtk->pManFunc; DdNode * bFunc = pNodeOld->pData; @@ -192,7 +190,7 @@ Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew, Abc_O // 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 *)pConst1 ); + st_insert( tBdd2Node, (char *)b1, (char *)Abc_NtkConst1(pNtkNew) ); Abc_ObjForEachFanin( pNodeOld, pFaninOld, i ) st_insert( tBdd2Node, (char *)Cudd_bddIthVar(dd, i), (char *)pFaninOld->pCopy ); // create the new nodes recursively @@ -266,7 +264,7 @@ DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int fLatchOnly ) Abc_NtkForEachCi( pNtk, pNode, i ) pNode->pCopy = (Abc_Obj_t *)dd->vars[i]; // assign the constant node BDD - pNode = Abc_AigConst1( pNtk->pManFunc ); + pNode = Abc_NtkConst1( pNtk ); pNode->pCopy = (Abc_Obj_t *)dd->one; Cudd_Ref( dd->one ); // collect the global functions of the COs diff --git a/src/base/abci/abcPga.c b/src/base/abci/abcPga.c index dfec3b73..1227d7b8 100644 --- a/src/base/abci/abcPga.c +++ b/src/base/abci/abcPga.c @@ -112,10 +112,6 @@ Abc_Ntk_t * Abc_NtkFromPga( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodeCuts ) // create the new network pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_BDD ); dd = pNtkNew->pManFunc; - // set the constant node - pNode = Abc_AigConst1(pNtk->pManFunc); - if ( Abc_ObjFanoutNum(pNode) > 0 ) - pNode->pCopy = Abc_NodeCreateConst1(pNtkNew); // add new nodes in topologic order vLeaves = Vec_PtrAlloc( 6 ); vVisited = Vec_PtrAlloc( 100 ); diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c index d8f5dd98..2bdd419d 100644 --- a/src/base/abci/abcPrint.c +++ b/src/base/abci/abcPrint.c @@ -20,7 +20,7 @@ #include "abc.h" #include "dec.h" -#include "abcs.h" +#include "seq.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -51,7 +51,7 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored ) if ( !Abc_NtkIsSeq(pNtk) ) fprintf( pFile, " lat = %4d", Abc_NtkLatchNum(pNtk) ); else - fprintf( pFile, " lat = %4d(%d)", Abc_NtkSeqLatchNum(pNtk), Abc_NtkSeqLatchNumShared(pNtk) ); + fprintf( pFile, " lat = %4d(%d,%d)", Seq_NtkLatchNum(pNtk), Seq_NtkLatchNumShared(pNtk), Seq_NtkLatchNumMax(pNtk) ); if ( Abc_NtkIsNetlist(pNtk) ) { @@ -150,7 +150,7 @@ void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk ) assert( !Abc_NtkIsNetlist(pNtk) ); if ( Abc_NtkIsSeq(pNtk) ) { - Abc_NtkSeqLatchGetInitNums( pNtk, InitNums ); + Seq_NtkLatchGetInitNums( pNtk, InitNums ); fprintf( pFile, "%-15s: ", pNtk->pName ); fprintf( pFile, "Latch = %6d. No = %4d. Zero = %4d. One = %4d. DC = %4d.\n", Abc_NtkLatchNum(pNtk), InitNums[0], InitNums[1], InitNums[2], InitNums[3] ); diff --git a/src/base/abci/abcRefactor.c b/src/base/abci/abcRefactor.c index 1bd3a843..c968025f 100644 --- a/src/base/abci/abcRefactor.c +++ b/src/base/abci/abcRefactor.c @@ -144,7 +144,6 @@ pManRef->timeTotal = clock() - clkStart; Abc_NtkManRefStop( pManRef ); // put the nodes into the DFS order and reassign their IDs Abc_NtkReassignIds( pNtk ); - Abc_AigRehash( pNtk->pManFunc ); // Abc_AigCheckFaninOrder( pNtk->pManFunc ); // fix the levels if ( fUpdateLevel ) diff --git a/src/base/abci/abcRenode.c b/src/base/abci/abcRenode.c index e3f09d6b..c1f83e1f 100644 --- a/src/base/abci/abcRenode.c +++ b/src/base/abci/abcRenode.c @@ -121,7 +121,7 @@ void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) int i; // set the constant node - pConst1 = Abc_AigConst1(pNtk->pManFunc); + pConst1 = Abc_NtkConst1(pNtk); if ( Abc_ObjFanoutNum(pConst1) > 0 ) { pNodeNew = Abc_NtkCreateNode( pNtkNew ); diff --git a/src/base/abci/abcRewrite.c b/src/base/abci/abcRewrite.c index c8cc722c..ab594667 100644 --- a/src/base/abci/abcRewrite.c +++ b/src/base/abci/abcRewrite.c @@ -115,7 +115,6 @@ Rwr_ManAddTimeTotal( pManRwr, clock() - clkStart ); pNtk->pManCut = NULL; // put the nodes into the DFS order and reassign their IDs Abc_NtkReassignIds( pNtk ); - Abc_AigRehash( pNtk->pManFunc ); // Abc_AigCheckFaninOrder( pNtk->pManFunc ); // fix the levels if ( fUpdateLevel ) diff --git a/src/base/abci/abcStrash.c b/src/base/abci/abcStrash.c index 8f2e71d6..c19376bd 100644 --- a/src/base/abci/abcStrash.c +++ b/src/base/abci/abcStrash.c @@ -28,8 +28,8 @@ // static functions static void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fAllNodes ); -static Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop ); -static Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop ); +static Abc_Obj_t * Abc_NodeStrashSop( 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 ); @@ -55,6 +55,7 @@ Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup ) int nNodes; assert( !Abc_NtkIsNetlist(pNtk) ); + assert( !Abc_NtkIsSeq(pNtk) ); if ( Abc_NtkIsBddLogic(pNtk) ) Abc_NtkBddToSop(pNtk); // print warning about choice nodes @@ -62,13 +63,15 @@ Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup ) printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" ); // perform strashing 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( "The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) ); + printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) ); if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) ) - printf( "Cleanup has removed %d nodes.\n", 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 ); @@ -139,7 +142,6 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ) void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes ) { ProgressBar * pProgress; - Abc_Aig_t * pMan = pNtkNew->pManFunc; Vec_Ptr_t * vNodes; Abc_Obj_t * pNode, * pNodeNew, * pObj; int i; @@ -153,7 +155,7 @@ void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes // get the node assert( Abc_ObjIsNode(pNode) ); // strash the node - pNodeNew = Abc_NodeStrash( pMan, pNode ); + pNodeNew = Abc_NodeStrash( pNtkNew, pNode ); // get the old object pObj = Abc_ObjFanout0Ntk( pNode ); // make sure the node is not yet strashed @@ -176,7 +178,7 @@ void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode ) +Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode ) { int fUseFactor = 1; char * pSop; @@ -187,8 +189,8 @@ Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode ) if ( Abc_NtkIsStrash(pNode->pNtk) ) { if ( Abc_NodeIsConst(pNode) ) - return Abc_AigConst1(pMan); - return Abc_AigAnd( pMan, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); + return Abc_NtkConst1(pNtkNew); + return Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); } // get the SOP of the node @@ -199,12 +201,12 @@ Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode ) // consider the constant node if ( Abc_NodeIsConst(pNode) ) - return Abc_ObjNotCond( Abc_AigConst1(pMan), Abc_SopIsConst0(pSop) ); + return Abc_ObjNotCond( Abc_NtkConst1(pNtkNew), Abc_SopIsConst0(pSop) ); // decide when to use factoring if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 ) - return Abc_NodeStrashFactor( pMan, pNode, pSop ); - return Abc_NodeStrashSop( pMan, pNode, pSop ); + return Abc_NodeStrashFactor( pNtkNew, pNode, pSop ); + return Abc_NodeStrashSop( pNtkNew, pNode, pSop ); } /**Function************************************************************* @@ -218,10 +220,10 @@ Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop ) +Abc_Obj_t * Abc_NodeStrashSop( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, char * pSop ) { + Abc_Aig_t * pMan = pNtkNew->pManFunc; Abc_Obj_t * pFanin, * pAnd, * pSum; - Abc_Obj_t * pConst1 = Abc_AigConst1(pMan); char * pCube; int i, nFanins; @@ -229,11 +231,11 @@ Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop nFanins = Abc_ObjFaninNum( pNode ); assert( nFanins == Abc_SopGetVarNum(pSop) ); // go through the cubes of the node's SOP - pSum = Abc_ObjNot(pConst1); + pSum = Abc_ObjNot( Abc_NtkConst1(pNtkNew) ); Abc_SopForEachCube( pSop, nFanins, pCube ) { // create the AND of literals - pAnd = pConst1; + pAnd = Abc_NtkConst1(pNtkNew); Abc_ObjForEachFanin( pNode, pFanin, i ) // pFanin can be a net { if ( pCube[i] == '1' ) @@ -261,7 +263,7 @@ Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, char * pSop ) +Abc_Obj_t * Abc_NodeStrashFactor( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pRoot, char * pSop ) { Dec_Graph_t * pFForm; Dec_Node_t * pNode; @@ -273,7 +275,7 @@ Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, char * pS Dec_GraphForEachLeaf( pFForm, pNode, i ) pNode->pFunc = Abc_ObjFanin(pRoot,i)->pCopy; // perform strashing - pAnd = Dec_GraphToNetwork( pMan, pFForm ); + pAnd = Dec_GraphToNetwork( pNtkNew, pFForm ); Dec_GraphFree( pFForm ); return pAnd; } diff --git a/src/base/abci/abcSweep.c b/src/base/abci/abcSweep.c index a6a4fc5c..2b62d40f 100644 --- a/src/base/abci/abcSweep.c +++ b/src/base/abci/abcSweep.c @@ -459,7 +459,7 @@ int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose ) Vec_PtrFree( vNodes ); // if it is an AIG, also mark the constant 1 node if ( Abc_NtkIsStrash(pNtk) ) - Abc_AigConst1(pNtk->pManFunc)->fMarkA = 1; + Abc_NtkConst1(pNtk)->fMarkA = 1; // remove the non-marked nodes Counter = 0; Abc_NtkForEachNode( pNtk, pNode, i ) diff --git a/src/base/abci/abcVanEijk.c b/src/base/abci/abcVanEijk.c index fc1593fc..f8d659a0 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 = util_strsav(Buffer); } // map the constant nodes - Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkFrames->pManFunc); + Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkFrames); // create new latches and remember them in the new latches Abc_NtkForEachLatch( pNtk, pLatch, i ) Abc_NtkDupObj( pNtkFrames, pLatch ); @@ -591,7 +591,7 @@ void Abc_NtkVanEijkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFram // remember the CI mapping if ( vCorresp ) { - pNode = Abc_AigConst1(pNtk->pManFunc); + pNode = Abc_NtkConst1(pNtk); Abc_NodeVanEijkWriteCorresp( pNode, vCorresp, iFrame, Abc_ObjRegular(pNode->pCopy) ); Abc_NtkForEachCi( pNtk, pNode, i ) Abc_NodeVanEijkWriteCorresp( pNode, vCorresp, iFrame, Abc_ObjRegular(pNode->pCopy) ); @@ -669,7 +669,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_AigConst1(pMulti->pManFunc)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan); + Abc_NtkConst1(pMulti)->pCopy = (Abc_Obj_t *)Fraig_ManReadConst1(pMan); if ( fInit ) { // map the PI nodes @@ -726,14 +726,14 @@ Abc_Ntk_t * Abc_NtkVanEijkDeriveExdc( Abc_Ntk_t * pNtk, Vec_Ptr_t * vClasses ) pNtkNew->pSpec = NULL; // map the constant nodes - Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkNew->pManFunc); + Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(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_AigConst1(pNtkNew->pManFunc) ); + pTotal = Abc_ObjNot( Abc_NtkConst1(pNtkNew) ); Vec_PtrForEachEntry( vClasses, pClass, i ) { assert( pClass->pNext ); diff --git a/src/base/abci/abcVanImp.c b/src/base/abci/abcVanImp.c index 8188cb01..693d0af7 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_AigConst1( p->pNtkSingle->pManFunc ); + pConst1 = Abc_NtkConst1( 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_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkNew->pManFunc); + Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(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_AigConst1(pNtkNew->pManFunc) ); + pTotal = Abc_ObjNot( Abc_NtkConst1(pNtkNew) ); Vec_PtrForEachEntry( vZeros, pNode, i ) { // build the logic cone for the node diff --git a/src/base/abcs/abcFpgaDelay.c b/src/base/abcs/abcFpgaDelay.c deleted file mode 100644 index 65ea4789..00000000 --- a/src/base/abcs/abcFpgaDelay.c +++ /dev/null @@ -1,327 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcFpgaDelay.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Utilities working sequential AIGs.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcFpgaDelay.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abcs.h" -#include "cut.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -// the internal procedures -static int Abc_NtkFpgaRetimeSearch_rec( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose ); -static int Abc_NtkFpgaRetimeForPeriod( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtk, int Fi, int fVerbose ); -static int Abc_NodeFpgaUpdateLValue( Seq_FpgaMan_t * p, Abc_Obj_t * pObj, int Fi ); -static void Abc_NtkFpgaCollect( Seq_FpgaMan_t * p ); - -// node status after updating its arrival time -enum { ABC_FPGA_UPDATE_FAIL, ABC_FPGA_UPDATE_NO, ABC_FPGA_UPDATE_YES }; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Retimes AIG for optimal delay.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFpgaSeqRetimeDelayLags( Seq_FpgaMan_t * p ) -{ - Abc_Ntk_t * pNtk = p->pNtk; - int fVerbose = p->fVerbose; - Abc_Obj_t * pNode; - int i, FiMax, FiBest, RetValue; - - // start storage for sequential arrival times - assert( pNtk->pData == NULL ); - pNtk->pData = p->vArrivals; - - // get the upper bound on the clock period -// FiMax = Abc_NtkNodeNum(pNtk); - FiMax = 0; - Abc_AigForEachAnd( pNtk, pNode, i ) - if ( FiMax < (int)pNode->Level ) - FiMax = pNode->Level; - FiMax += 2; - - // make sure this clock period is feasible - assert( Abc_NtkFpgaRetimeForPeriod( p, pNtk, FiMax, fVerbose ) ); - - // search for the optimal clock period between 0 and nLevelMax - FiBest = Abc_NtkFpgaRetimeSearch_rec( p, pNtk, 0, FiMax, fVerbose ); - - // recompute the best LValues - RetValue = Abc_NtkFpgaRetimeForPeriod( p, pNtk, FiBest, fVerbose ); - assert( RetValue ); - - // print the result - if ( fVerbose ) - printf( "The best clock period is %3d.\n", FiBest ); - - // convert to lags - Abc_AigForEachAnd( pNtk, pNode, i ) - Vec_StrWriteEntry( p->vLagsMap, i, (char)Abc_NodeGetLag(Abc_NodeReadLValue(pNode), FiBest) ); -/* - printf( "LValues : " ); - Abc_AigForEachAnd( pNtk, pNode, i ) - printf( "%d=%d ", i, Abc_NodeReadLValue(pNode) ); - printf( "\n" ); - printf( "Lags : " ); - Abc_AigForEachAnd( pNtk, pNode, i ) - if ( Vec_StrEntry(vLags,i) != 0 ) - printf( "%d=%d(%d)(%d) ", i, Vec_StrEntry(vLags,i), Abc_NodeReadLValue(pNode), Abc_NodeReadLValue(pNode) - FiBest * Vec_StrEntry(vLags,i) ); - printf( "\n" ); -*/ - Abc_NtkFpgaCollect( p ); - - pNtk->pData = NULL; - - Cut_ManStop( p->pMan ); - p->pMan = NULL; -} - -/**Function************************************************************* - - Synopsis [Performs binary search for the optimal clock period.] - - Description [Assumes that FiMin is infeasible while FiMax is feasible.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkFpgaRetimeSearch_rec( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose ) -{ - int Median; - assert( FiMin < FiMax ); - if ( FiMin + 1 == FiMax ) - return FiMax; - Median = FiMin + (FiMax - FiMin)/2; - if ( Abc_NtkFpgaRetimeForPeriod( p, pNtk, Median, fVerbose ) ) - return Abc_NtkFpgaRetimeSearch_rec( p, pNtk, FiMin, Median, fVerbose ); // Median is feasible - else - return Abc_NtkFpgaRetimeSearch_rec( p, pNtk, Median, FiMax, fVerbose ); // Median is infeasible -} - -/**Function************************************************************* - - Synopsis [Returns 1 if retiming with this clock period is feasible.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkFpgaRetimeForPeriod( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtk, int Fi, int fVerbose ) -{ - Abc_Obj_t * pObj; - int i, c, RetValue, fChange, Counter; - char * pReason = ""; - - // set l-values of all nodes to be minus infinity - Vec_IntFill( p->vArrivals, Abc_NtkObjNumMax(pNtk), -ABC_INFINITY ); - Vec_PtrFill( p->vBestCuts, Abc_NtkObjNumMax(pNtk), NULL ); - - // set l-values for the constant and PIs - pObj = Abc_NtkObj( pNtk, 0 ); - Abc_NodeSetLValue( pObj, 0 ); - Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_NodeSetLValue( pObj, 0 ); - - // update all values iteratively - Counter = 0; - for ( c = 0; c < 20; c++ ) - { - fChange = 0; - Abc_NtkForEachObj( pNtk, pObj, i ) - { - if ( Abc_ObjIsPi(pObj) ) - continue; - if ( Abc_ObjFaninNum(pObj) == 0 ) - continue; - RetValue = Abc_NodeFpgaUpdateLValue( p, pObj, Fi ); - Counter++; - if ( RetValue == ABC_FPGA_UPDATE_FAIL ) - break; - if ( RetValue == ABC_FPGA_UPDATE_NO ) - continue; - fChange = 1; - } - if ( RetValue == ABC_FPGA_UPDATE_FAIL ) - break; - if ( fChange == 0 ) - break; - } - if ( c == 20 ) - { - RetValue = ABC_FPGA_UPDATE_FAIL; - pReason = "(timeout)"; - } - - // report the results - if ( fVerbose ) - { - if ( RetValue == ABC_FPGA_UPDATE_FAIL ) - printf( "Period = %3d. Iterations = %3d. Updates = %6d. Infeasible %s\n", Fi, c, Counter, pReason ); - else - printf( "Period = %3d. Iterations = %3d. Updates = %6d. Feasible\n", Fi, c, Counter ); - } - return RetValue != ABC_FPGA_UPDATE_FAIL; -} - -/**Function************************************************************* - - Synopsis [Computes the l-value of the node.] - - Description [The node can be internal or a PO.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeFpgaUpdateLValue( Seq_FpgaMan_t * p, Abc_Obj_t * pObj, int Fi ) -{ - Abc_Obj_t * pFanin; - Cut_Cut_t * pList, * pCut, * pCutBest; - int lValueNew, lValueOld, lValueCur, lValueFan; - int i; - - assert( !Abc_ObjIsPi(pObj) ); - assert( Abc_ObjFaninNum(pObj) > 0 ); - - if ( Abc_ObjIsPo(pObj) ) - { - lValueOld = Abc_NodeReadLValue(Abc_ObjFanin0(pObj)); - lValueNew = lValueOld - Fi * Abc_ObjFaninL0(pObj); - return (lValueNew > Fi)? ABC_FPGA_UPDATE_FAIL : ABC_FPGA_UPDATE_NO; - } - - pCutBest = NULL; - lValueNew = ABC_INFINITY; - pList = Abc_NodeReadCuts( p->pMan, pObj ); - for ( pCut = pList; pCut; pCut = pCut->pNext ) - { - if ( pCut->nLeaves < 2 ) - continue; - lValueCur = -ABC_INFINITY; - for ( i = 0; i < (int)pCut->nLeaves; i++ ) - { - pFanin = Abc_NtkObj( pObj->pNtk, (pCut->pLeaves[i] >> CUT_SHIFT) ); - lValueFan = Abc_NodeReadLValue(pFanin) - Fi * (pCut->pLeaves[i] & CUT_MASK); - lValueCur = ABC_MAX( lValueCur, lValueFan ); - } - lValueCur += 1; - lValueNew = ABC_MIN( lValueNew, lValueCur ); - if ( lValueNew == lValueCur ) - pCutBest = pCut; - } - - lValueOld = Abc_NodeReadLValue(pObj); -// if ( lValueNew == lValueOld ) - if ( lValueNew <= lValueOld ) - return ABC_FPGA_UPDATE_NO; - - Abc_NodeSetLValue( pObj, lValueNew ); - Vec_PtrWriteEntry( p->vBestCuts, pObj->Id, pCutBest ); - return ABC_FPGA_UPDATE_YES; -} - - - -/**Function************************************************************* - - Synopsis [Select nodes visible in the mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeFpgaCollect_rec( Seq_FpgaMan_t * p, Abc_Obj_t * pNode ) -{ - Cut_Cut_t * pCutBest; - Abc_Obj_t * pFanin; - Vec_Int_t * vLeaves; - int i; - // skip the CI - if ( Abc_ObjIsCi(pNode) ) - return; - // if this node is already visited, skip - if ( Abc_NodeIsTravIdCurrent( pNode ) ) - return; - // mark the node as visited - Abc_NodeSetTravIdCurrent( pNode ); - // get the best cut of the node - pCutBest = Vec_PtrEntry( p->vBestCuts, pNode->Id ); - for ( i = 0; i < (int)pCutBest->nLeaves; i++ ) - { - pFanin = Abc_NtkObj( pNode->pNtk, (pCutBest->pLeaves[i] >> CUT_SHIFT) ); - Abc_NodeFpgaCollect_rec( p, pFanin ); - } - // collect the node and its cut - vLeaves = Vec_IntAlloc( pCutBest->nLeaves ); - for ( i = 0; i < (int)pCutBest->nLeaves; i++ ) - Vec_IntPush( vLeaves, pCutBest->pLeaves[i] ); - Vec_PtrPush( p->vMapCuts, vLeaves ); - Vec_PtrPush( p->vMapping, pNode ); -} - -/**Function************************************************************* - - Synopsis [Select nodes visible in the mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFpgaCollect( Seq_FpgaMan_t * p ) -{ - Abc_Ntk_t * pNtk = p->pNtk; - Abc_Obj_t * pObj; - int i; - Vec_PtrClear( p->vMapping ); - Vec_PtrClear( p->vMapCuts ); - Abc_NtkIncrementTravId( pNtk ); - Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_NodeFpgaCollect_rec( p, Abc_ObjFanin0(pObj) ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abcs/abcFpgaSeq.c b/src/base/abcs/abcFpgaSeq.c deleted file mode 100644 index 2fff1b14..00000000 --- a/src/base/abcs/abcFpgaSeq.c +++ /dev/null @@ -1,201 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcFpgaSeq.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Mapping for FPGAs using sequential cuts.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcFpgaSeq.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abcs.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -Abc_Ntk_t * Abc_NtkMapSeq( Abc_Ntk_t * pNtk, int fVerbose ) { return 0; } - -extern Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ); -extern void Abc_NtkFpgaSeqRetimeDelayLags( Seq_FpgaMan_t * p ); - -static Seq_FpgaMan_t * Abc_NtkFpgaSeqStart( Abc_Ntk_t * pNtk, int fVerbose ); -static void Abc_NtkFpgaSeqStop( Seq_FpgaMan_t * p ); - -static Abc_Ntk_t * Abc_NtkFpgaSeqConstruct( Seq_FpgaMan_t * p ); -static void Abc_NtkFpgaSeqRetime( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtkNew ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Retimes AIG for optimal delay.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkFpgaSeq( Abc_Ntk_t * pNtk, int fVerbose ) -{ - Abc_Ntk_t * pNtkNew; - Seq_FpgaMan_t * p; - Cut_Params_t Params, * pParams = &Params; - int clk; - - assert( Abc_NtkIsSeq( pNtk ) ); - - // get the sequential FPGA manager - p = Abc_NtkFpgaSeqStart( pNtk, fVerbose ); - - // create the cuts - memset( pParams, 0, sizeof(Cut_Params_t) ); - pParams->nVarsMax = 5; // the max cut size ("k" of the k-feasible cuts) - pParams->nKeepMax = 1000; // the max number of cuts kept at a node - pParams->fTruth = 0; // compute truth tables - pParams->fFilter = 1; // filter dominated cuts - pParams->fSeq = 1; // compute sequential cuts - pParams->fVerbose = 0; // the verbosiness flag - -clk = clock(); - p->pMan = Abc_NtkSeqCuts( pNtk, pParams ); -p->timeCuts += clock() - clk; - - // find best arrival times (p->vArrivals) and free the cuts - // select mapping (p->vMapping) and remember best cuts (p->vMapCuts) -clk = clock(); - Abc_NtkFpgaSeqRetimeDelayLags( p ); -p->timeDelay += clock() - clk; - -return NULL; - - // construct the network -clk = clock(); - pNtkNew = Abc_NtkFpgaSeqConstruct( p ); -p->timeNtk += clock() - clk; - - // retime the network -clk = clock(); - Abc_NtkFpgaSeqRetime( p, pNtkNew ); -p->timeRet += clock() - clk; - - // remove temporaries - Abc_NtkFpgaSeqStop( p ); - - // check the resulting network - if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkFpgaSeq(): Network check has failed.\n" ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Starts sequential FPGA mapper.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Seq_FpgaMan_t * Abc_NtkFpgaSeqStart( Abc_Ntk_t * pNtk, int fVerbose ) -{ - Seq_FpgaMan_t * p; - // create the FPGA mapping manager - p = ALLOC( Seq_FpgaMan_t, 1 ); - memset( p, 0, sizeof(Seq_FpgaMan_t) ); - p->pNtk = pNtk; - p->pMan = NULL; - p->vArrivals = Vec_IntAlloc( 0 ); - p->vBestCuts = Vec_PtrAlloc( 0 ); - p->vMapping = Vec_PtrAlloc( 0 ); - p->vMapCuts = Vec_PtrAlloc( 0 ); - p->vLagsMap = Vec_StrStart( Abc_NtkObjNumMax(pNtk) ); - p->fVerbose = fVerbose; - return p; -} - -/**Function************************************************************* - - Synopsis [Stops sequential FPGA mapper.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFpgaSeqStop( Seq_FpgaMan_t * p ) -{ - if ( p->fVerbose ) - { - printf( "Sequential FPGA mapping stats:\n" ); -// printf( "Total allocated = %8d.\n", p->nCutsAlloc ); -// printf( "Cuts per node = %8.1f\n", ((float)(p->nCutsCur-p->nCutsTriv))/p->nNodes ); - PRT( "Cuts ", p->timeCuts ); - PRT( "Arrival", p->timeDelay ); - PRT( "Network", p->timeNtk ); - PRT( "Retime ", p->timeRet ); - } - Vec_IntFree( p->vArrivals ); - Vec_PtrFree( p->vBestCuts ); - Vec_PtrFree( p->vMapping ); - Vec_VecFree( (Vec_Vec_t *)p->vMapCuts ); - Vec_StrFree( p->vLagsMap ); - free( p ); -} - - -/**Function************************************************************* - - Synopsis [Construct the final network after mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkFpgaSeqConstruct( Seq_FpgaMan_t * p ) -{ - Abc_Ntk_t * pNtk = NULL; - return pNtk; -} - -/**Function************************************************************* - - Synopsis [Retimes the final network after mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkFpgaSeqRetime( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtkNew ) -{ -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abcs/abcRetCore.c b/src/base/abcs/abcRetCore.c deleted file mode 100644 index f6d26e0d..00000000 --- a/src/base/abcs/abcRetCore.c +++ /dev/null @@ -1,145 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcForBack.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Simple forward/backward retiming procedures.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcForBack.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abcs.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/* - Retiming can be represented in three equivalent forms: - - as a set of integer lags for each node (array of chars by node ID) - - as a set of node numbers with lag for each, fwd and bwd (two arrays of Abc_RetStep_t_) - - as a set of node moves, fwd and bwd (two arrays arrays of Abc_Obj_t *) -*/ - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs most forward retiming.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk, int fVerbose ) -{ - Vec_Ptr_t * vMoves; - Abc_Obj_t * pNode; - int i; - // get the forward moves - vMoves = Abc_NtkUtilRetimingTry( pNtk, 1 ); - // undo the forward moves - Vec_PtrForEachEntryReverse( vMoves, pNode, i ) - Abc_ObjRetimeBackwardTry( pNode, 1 ); - // implement this forward retiming - Abc_NtkImplementRetimingForward( pNtk, vMoves ); - Vec_PtrFree( vMoves ); -} - -/**Function************************************************************* - - Synopsis [Performs most backward retiming.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk, int fVerbose ) -{ - Vec_Ptr_t * vMoves; - Abc_Obj_t * pNode; - int i, RetValue; - // get the backward moves - vMoves = Abc_NtkUtilRetimingTry( pNtk, 0 ); - // undo the backward moves - Vec_PtrForEachEntryReverse( vMoves, pNode, i ) - Abc_ObjRetimeForwardTry( pNode, 1 ); - // implement this backward retiming - RetValue = Abc_NtkImplementRetimingBackward( pNtk, vMoves, fVerbose ); - Vec_PtrFree( vMoves ); - if ( RetValue == 0 ) - printf( "Retiming completed but initial state computation has failed.\n" ); -} - -/**Function************************************************************* - - Synopsis [Performs performs optimal delay retiming.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk, int fVerbose ) -{ - Vec_Str_t * vLags; - int RetValue; - // get the retiming vector - vLags = Abc_NtkSeqRetimeDelayLags( pNtk, fVerbose ); - // implement this retiming - RetValue = Abc_NtkImplementRetiming( pNtk, vLags, fVerbose ); - Vec_StrFree( vLags ); - if ( RetValue == 0 ) - printf( "Retiming completed but initial state computation has failed.\n" ); -} - -/**Function************************************************************* - - Synopsis [Performs retiming for initial state computation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkSeqRetimeInitial( Abc_Ntk_t * pNtk, int fVerbose ) -{ - Vec_Str_t * vLags; - int RetValue; - // get the retiming vector - vLags = Abc_NtkSeqRetimeDelayLags( pNtk, fVerbose ); - // implement this retiming - RetValue = Abc_NtkImplementRetiming( pNtk, vLags, fVerbose ); - Vec_StrFree( vLags ); - if ( RetValue == 0 ) - printf( "Retiming completed but initial state computation has failed.\n" ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abcs/abcRetDelay.c b/src/base/abcs/abcRetDelay.c deleted file mode 100644 index 15138510..00000000 --- a/src/base/abcs/abcRetDelay.c +++ /dev/null @@ -1,504 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcSeqRetime.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Peforms retiming for optimal clock cycle.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcSeqRetime.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abcs.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -// the internal procedures -static int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose ); -static int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose ); -static int Abc_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi ); - -// node status after updating its arrival time -enum { ABC_UPDATE_FAIL, ABC_UPDATE_NO, ABC_UPDATE_YES }; - -static void Abc_RetimingExperiment( Abc_Ntk_t * pNtk, Vec_Str_t * vLags ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Retimes AIG for optimal delay.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Str_t * Abc_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose ) -{ - Vec_Str_t * vLags; - Abc_Obj_t * pNode; - int i, FiMax, FiBest, RetValue; - assert( Abc_NtkIsSeq( pNtk ) ); - - // start storage for sequential arrival times - assert( pNtk->pData == NULL ); - pNtk->pData = Vec_IntAlloc( 0 ); - - // get the upper bound on the clock period -// FiMax = Abc_NtkNodeNum(pNtk); - FiMax = 0; - Abc_AigForEachAnd( pNtk, pNode, i ) - if ( FiMax < (int)pNode->Level ) - FiMax = pNode->Level; - FiMax += 2; - - // make sure this clock period is feasible - assert( Abc_NtkRetimeForPeriod( pNtk, FiMax, fVerbose ) ); - - // search for the optimal clock period between 0 and nLevelMax - FiBest = Abc_NtkRetimeSearch_rec( pNtk, 0, FiMax, fVerbose ); - - // recompute the best LValues - RetValue = Abc_NtkRetimeForPeriod( pNtk, FiBest, fVerbose ); - assert( RetValue ); - - // print the result - if ( fVerbose ) - printf( "The best clock period is %3d.\n", FiBest ); - - // convert to lags - vLags = Vec_StrStart( Abc_NtkObjNumMax(pNtk) ); - Abc_AigForEachAnd( pNtk, pNode, i ) - Vec_StrWriteEntry( vLags, i, (char)Abc_NodeGetLag(Abc_NodeReadLValue(pNode), FiBest) ); -/* - printf( "LValues : " ); - Abc_AigForEachAnd( pNtk, pNode, i ) - printf( "%d=%d ", i, Abc_NodeReadLValue(pNode) ); - printf( "\n" ); - printf( "Lags : " ); - Abc_AigForEachAnd( pNtk, pNode, i ) - if ( Vec_StrEntry(vLags,i) != 0 ) - printf( "%d=%d(%d)(%d) ", i, Vec_StrEntry(vLags,i), Abc_NodeReadLValue(pNode), Abc_NodeReadLValue(pNode) - FiBest * Vec_StrEntry(vLags,i) ); - printf( "\n" ); -*/ - - // free storage - Vec_IntFree( pNtk->pData ); - pNtk->pData = NULL; - return vLags; -} - -/**Function************************************************************* - - Synopsis [Performs binary search for the optimal clock period.] - - Description [Assumes that FiMin is infeasible while FiMax is feasible.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose ) -{ - int Median; - assert( FiMin < FiMax ); - if ( FiMin + 1 == FiMax ) - return FiMax; - Median = FiMin + (FiMax - FiMin)/2; - if ( Abc_NtkRetimeForPeriod( pNtk, Median, fVerbose ) ) - return Abc_NtkRetimeSearch_rec( pNtk, FiMin, Median, fVerbose ); // Median is feasible - else - return Abc_NtkRetimeSearch_rec( pNtk, Median, FiMax, fVerbose ); // Median is infeasible -} - -/**Function************************************************************* - - Synopsis [Returns 1 if retiming with this clock period is feasible.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeForPeriod2( Abc_Ntk_t * pNtk, int Fi ) -{ - Vec_Ptr_t * vFrontier; - Abc_Obj_t * pObj, * pFanout; - char * pReason = ""; - int RetValue, i, k; - int Limit; - - // set l-values of all nodes to be minus infinity - Vec_IntFill( pNtk->pData, Abc_NtkObjNumMax(pNtk), -ABC_INFINITY ); - - // start the frontier by setting PI l-values to 0 and including PI fanouts - vFrontier = Vec_PtrAlloc( 100 ); - pObj = Abc_NtkObj( pNtk, 0 ); - if ( Abc_ObjFanoutNum(pObj) > 0 ) - { - Abc_NodeSetLValue( pObj, 0 ); - Abc_ObjForEachFanout( pObj, pFanout, k ) - if ( pFanout->fMarkA == 0 ) - { - Vec_PtrPush( vFrontier, pFanout ); - pFanout->fMarkA = 1; - } - } - Abc_NtkForEachPi( pNtk, pObj, i ) - { - Abc_NodeSetLValue( pObj, 0 ); - Abc_ObjForEachFanout( pObj, pFanout, k ) - if ( pFanout->fMarkA == 0 ) - { - Vec_PtrPush( vFrontier, pFanout ); - pFanout->fMarkA = 1; - } - } - - // iterate until convergence - Limit = Abc_NtkObjNumMax(pNtk) * 20; - Vec_PtrForEachEntry( vFrontier, pObj, i ) - { - pObj->fMarkA = 0; - RetValue = Abc_NodeUpdateLValue( pObj, Fi ); - if ( RetValue == ABC_UPDATE_FAIL ) - break; - if ( i == Limit ) - { - RetValue = ABC_UPDATE_FAIL; - pReason = "(timeout)"; - break; - } - if ( RetValue == ABC_UPDATE_NO ) - continue; - assert( RetValue == ABC_UPDATE_YES ); - // arrival times have changed - add fanouts to the frontier - Abc_ObjForEachFanout( pObj, pFanout, k ) - if ( pFanout->fMarkA == 0 && pFanout != pObj ) - { - Vec_PtrPush( vFrontier, pFanout ); - pFanout->fMarkA = 1; - } - } - // clean the nodes - Vec_PtrForEachEntryStart( vFrontier, pObj, k, i ) - pObj->fMarkA = 0; - - // report the results - if ( RetValue == ABC_UPDATE_FAIL ) - printf( "Period = %3d. Updated nodes = %6d. Infeasible %s\n", Fi, vFrontier->nSize, pReason ); - else - printf( "Period = %3d. Updated nodes = %6d. Feasible\n", Fi, vFrontier->nSize ); - Vec_PtrFree( vFrontier ); - return RetValue != ABC_UPDATE_FAIL; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if retiming with this clock period is feasible.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose ) -{ - Abc_Obj_t * pObj; - int i, c, RetValue, fChange, Counter; - char * pReason = ""; - - // set l-values of all nodes to be minus infinity - Vec_IntFill( pNtk->pData, Abc_NtkObjNumMax(pNtk), -ABC_INFINITY ); - - // set l-values for the constant and PIs - pObj = Abc_NtkObj( pNtk, 0 ); - Abc_NodeSetLValue( pObj, 0 ); - Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_NodeSetLValue( pObj, 0 ); - - // update all values iteratively - Counter = 0; - for ( c = 0; c < 20; c++ ) - { - fChange = 0; - Abc_NtkForEachObj( pNtk, pObj, i ) - { - if ( Abc_ObjIsPi(pObj) ) - continue; - if ( Abc_ObjFaninNum(pObj) == 0 ) - continue; - RetValue = Abc_NodeUpdateLValue( pObj, Fi ); - Counter++; - if ( RetValue == ABC_UPDATE_FAIL ) - break; - if ( RetValue == ABC_UPDATE_NO ) - continue; - fChange = 1; - } - if ( RetValue == ABC_UPDATE_FAIL ) - break; - if ( fChange == 0 ) - break; - } - if ( c == 20 ) - { - RetValue = ABC_UPDATE_FAIL; - pReason = "(timeout)"; - } - - // report the results - if ( fVerbose ) - { - if ( RetValue == ABC_UPDATE_FAIL ) - printf( "Period = %3d. Iterations = %3d. Updates = %6d. Infeasible %s\n", Fi, c, Counter, pReason ); - else - printf( "Period = %3d. Iterations = %3d. Updates = %6d. Feasible\n", Fi, c, Counter ); - } - return RetValue != ABC_UPDATE_FAIL; -} - -/**Function************************************************************* - - Synopsis [Computes the l-value of the node.] - - Description [The node can be internal or a PO.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi ) -{ - int lValueNew, lValueOld, lValue0, lValue1; - assert( !Abc_ObjIsPi(pObj) ); - assert( Abc_ObjFaninNum(pObj) > 0 ); - lValue0 = Abc_NodeReadLValue(Abc_ObjFanin0(pObj)) - Fi * Abc_ObjFaninL0(pObj); - if ( Abc_ObjIsPo(pObj) ) - return (lValue0 > Fi)? ABC_UPDATE_FAIL : ABC_UPDATE_NO; - if ( Abc_ObjFaninNum(pObj) == 2 ) - lValue1 = Abc_NodeReadLValue(Abc_ObjFanin1(pObj)) - Fi * Abc_ObjFaninL1(pObj); - else - lValue1 = -ABC_INFINITY; - lValueNew = 1 + ABC_MAX( lValue0, lValue1 ); - lValueOld = Abc_NodeReadLValue(pObj); -// if ( lValueNew == lValueOld ) - if ( lValueNew <= lValueOld ) - return ABC_UPDATE_NO; - Abc_NodeSetLValue( pObj, lValueNew ); - return ABC_UPDATE_YES; -} - - - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_RetimingPrint_rec( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanin0, * pFanin1; - int Depth0, Depth1; - - if ( Abc_ObjIsPi(pObj) ) - { - printf( "%d -> ", pObj->Id ); - return 0; - } - - pFanin0 = Abc_ObjFanin0(pObj); - pFanin1 = Abc_ObjFanin1(pObj); - - if ( Abc_ObjFaninL0(pObj) == 0 && Abc_ObjFaninL1(pObj) > 0 ) - Abc_RetimingPrint_rec( pFanin0 ); - else if ( Abc_ObjFaninL1(pObj) == 0 && Abc_ObjFaninL0(pObj) > 0 ) - Abc_RetimingPrint_rec( pFanin1 ); - else if ( Abc_ObjFaninL0(pObj) == 0 && Abc_ObjFaninL1(pObj) == 0 ) - { - Depth0 = (int)pFanin0->pCopy; - Depth1 = (int)pFanin1->pCopy; - - if ( Depth0 > Depth1 ) - Abc_RetimingPrint_rec( pFanin0 ); - else - Abc_RetimingPrint_rec( pFanin1 ); - } - - printf( "%d (%d) -> ", pObj->Id, (int)pObj->pCopy ); - return 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_Retiming_rec( Abc_Obj_t * pObj ) -{ - int Depth0, Depth1, Depth; - if ( Abc_ObjIsPi(pObj) ) - { - pObj->pCopy = 0; - return 0; - } - // if this node is already visited, skip - if ( Abc_NodeIsTravIdCurrent( pObj ) ) - return (int)pObj->pCopy; - // mark the node as visited - Abc_NodeSetTravIdCurrent( pObj ); - if ( Abc_ObjFaninL0(pObj) == 0 ) - Depth0 = Abc_Retiming_rec( Abc_ObjFanin0(pObj) ); - else - Depth0 = 0; - if ( Abc_ObjFaninL1(pObj) == 0 ) - Depth1 = Abc_Retiming_rec( Abc_ObjFanin1(pObj) ); - else - Depth1 = 0; - Depth = 1 + ABC_MAX( Depth0, Depth1 ); - pObj->pCopy = (void *)Depth; - return Depth; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetiming( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i, Depth; - Abc_NtkForEachObj( pNtk, pObj, i ) - { - if ( Abc_ObjFaninNum(pObj) != 2 ) - continue; - if ( Abc_ObjFaninL0(pObj) > 0 ) - { - Abc_NtkIncrementTravId(pNtk); - Depth = Abc_Retiming_rec( Abc_ObjFanin0(pObj) ); - if ( Depth > 30 ) - { - printf( "Depth is %d. ", Depth ); - Abc_RetimingPrint_rec( Abc_ObjFanin0(pObj) ); - printf( "\n\n" ); - } - } - if ( Abc_ObjFaninL1(pObj) > 0 ) - { - Abc_NtkIncrementTravId(pNtk); - Depth = Abc_Retiming_rec( Abc_ObjFanin1(pObj) ); - if ( Depth > 30 ) - { - printf( "Depth is %d. ", Depth ); - Abc_RetimingPrint_rec( Abc_ObjFanin1(pObj) ); - printf( "\n\n" ); - } - } - } - return 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_RetimingExperiment( Abc_Ntk_t * pNtk, Vec_Str_t * vLags ) -{ - Abc_Obj_t * pObj; - char Lag; - int i; - - Vec_StrForEachEntry( vLags, Lag, i ) - { - if ( Lag == 0 ) - continue; - pObj = Abc_NtkObj( pNtk, i ); - if ( Lag < 0 ) - Abc_ObjRetimeForwardTry( pObj, -Lag ); - else - Abc_ObjRetimeBackwardTry( pObj, Lag ); - } - - // make sure there are no negative latches - Abc_NtkForEachObj( pNtk, pObj, i ) - { - if ( Abc_ObjFaninNum(pObj) == 0 ) - continue; - assert( Abc_ObjFaninL0(pObj) >= 0 ); - if ( Abc_ObjFaninNum(pObj) == 1 ) - continue; - assert( Abc_ObjFaninL1(pObj) >= 0 ); -// printf( "%d=(%d,%d) ", i, Abc_ObjFaninL0(pObj), Abc_ObjFaninL1(pObj) ); - } -// printf( "\n" ); - - Abc_NtkRetiming( pNtk ); - - Vec_StrForEachEntry( vLags, Lag, i ) - { - if ( Lag == 0 ) - continue; - pObj = Abc_NtkObj( pNtk, i ); - if ( Lag < 0 ) - Abc_ObjRetimeBackwardTry( pObj, -Lag ); - else - Abc_ObjRetimeForwardTry( pObj, Lag ); - } - -// Abc_NtkSeqRetimeDelayLags( pNtk ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/base/abcs/abcRetImpl.c b/src/base/abcs/abcRetImpl.c deleted file mode 100644 index 07e6d24e..00000000 --- a/src/base/abcs/abcRetImpl.c +++ /dev/null @@ -1,450 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcRetImpl.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Implementation of retiming.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcRetImpl.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abcs.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Abc_ObjRetimeForward( Abc_Obj_t * pObj ); -static int Abc_ObjRetimeBackward( Abc_Obj_t * pObj, Abc_Ntk_t * pNtk, stmm_table * tTable, Vec_Int_t * vValues ); -static void Abc_ObjRetimeBackwardUpdateEdge( Abc_Obj_t * pObj, int Edge, stmm_table * tTable ); -static void Abc_NtkRetimeSetInitialValues( Abc_Ntk_t * pNtk, stmm_table * tTable, int * pModel ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Implements the retiming on the sequential AIG.] - - Description [Split the retiming into forward and backward.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags, int fVerbose ) -{ - Vec_Int_t * vSteps; - Vec_Ptr_t * vMoves; - int RetValue; - - // forward retiming - vSteps = Abc_NtkUtilRetimingSplit( vLags, 1 ); - // translate each set of steps into moves - if ( fVerbose ) - printf( "The number of forward steps = %6d.\n", Vec_IntSize(vSteps) ); - vMoves = Abc_NtkUtilRetimingGetMoves( pNtk, vSteps, 1 ); - if ( fVerbose ) - printf( "The number of forward moves = %6d.\n", Vec_PtrSize(vMoves) ); - // implement this retiming - Abc_NtkImplementRetimingForward( pNtk, vMoves ); - Vec_IntFree( vSteps ); - Vec_PtrFree( vMoves ); - - // backward retiming - vSteps = Abc_NtkUtilRetimingSplit( vLags, 0 ); - // translate each set of steps into moves - if ( fVerbose ) - printf( "The number of backward steps = %6d.\n", Vec_IntSize(vSteps) ); - vMoves = Abc_NtkUtilRetimingGetMoves( pNtk, vSteps, 0 ); - if ( fVerbose ) - printf( "The number of backward moves = %6d.\n", Vec_PtrSize(vMoves) ); - // implement this retiming - RetValue = Abc_NtkImplementRetimingBackward( pNtk, vMoves, fVerbose ); - Vec_IntFree( vSteps ); - Vec_PtrFree( vMoves ); - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Implements the given retiming on the sequential AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkImplementRetimingForward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves ) -{ - Abc_Obj_t * pNode; - int i; - Vec_PtrForEachEntry( vMoves, pNode, i ) - Abc_ObjRetimeForward( pNode ); -} - -/**Function************************************************************* - - Synopsis [Retimes node forward by one latch.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_ObjRetimeForward( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanout; - int Init0, Init1, Init, i; - assert( Abc_ObjFaninNum(pObj) == 2 ); - assert( Abc_ObjFaninL0(pObj) >= 1 ); - assert( Abc_ObjFaninL1(pObj) >= 1 ); - // remove the init values from the fanins - Init0 = Abc_ObjFaninLDeleteFirst( pObj, 0 ); - Init1 = Abc_ObjFaninLDeleteFirst( pObj, 1 ); - assert( Init0 != ABC_INIT_NONE ); - assert( Init1 != ABC_INIT_NONE ); - // take into account the complements in the node - if ( Abc_ObjFaninC0(pObj) ) - { - if ( Init0 == ABC_INIT_ZERO ) - Init0 = ABC_INIT_ONE; - else if ( Init0 == ABC_INIT_ONE ) - Init0 = ABC_INIT_ZERO; - } - if ( Abc_ObjFaninC1(pObj) ) - { - if ( Init1 == ABC_INIT_ZERO ) - Init1 = ABC_INIT_ONE; - else if ( Init1 == ABC_INIT_ONE ) - Init1 = ABC_INIT_ZERO; - } - // compute the value at the output of the node - if ( Init0 == ABC_INIT_ZERO || Init1 == ABC_INIT_ZERO ) - Init = ABC_INIT_ZERO; - else if ( Init0 == ABC_INIT_ONE && Init1 == ABC_INIT_ONE ) - Init = ABC_INIT_ONE; - else - Init = ABC_INIT_DC; - // add the init values to the fanouts - Abc_ObjForEachFanout( pObj, pFanout, i ) - Abc_ObjFaninLInsertLast( pFanout, Abc_ObjEdgeNum(pObj, pFanout), Init ); -} - - - -/**Function************************************************************* - - Synopsis [Implements the given retiming on the sequential AIG.] - - Description [Returns 0 of initial state computation fails.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int fVerbose ) -{ - Abc_RetEdge_t RetEdge; - stmm_table * tTable; - stmm_generator * gen; - Vec_Int_t * vValues; - Abc_Ntk_t * pNtkProb, * pNtkMiter, * pNtkCnf; - Abc_Obj_t * pNode, * pNodeNew; - int * pModel, RetValue, i, clk; - - // return if the retiming is trivial - if ( Vec_PtrSize(vMoves) == 0 ) - return 1; - - // create the network for the initial state computation - // start the table and the array of PO values - pNtkProb = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP ); - tTable = stmm_init_table( stmm_numcmp, stmm_numhash ); - vValues = Vec_IntAlloc( 100 ); - - // perform the backward moves and build the network for initial state computation - RetValue = 0; - Vec_PtrForEachEntry( vMoves, pNode, i ) - RetValue |= Abc_ObjRetimeBackward( pNode, pNtkProb, tTable, vValues ); - - // add the PIs corresponding to the white spots - stmm_foreach_item( tTable, gen, (char **)&RetEdge, (char **)&pNodeNew ) - Abc_ObjAddFanin( pNodeNew, Abc_NtkCreatePi(pNtkProb) ); - - // add the PI/PO names - Abc_NtkAddDummyPiNames( pNtkProb ); - Abc_NtkAddDummyPoNames( pNtkProb ); - - // make sure everything is okay with the network structure - if ( !Abc_NtkDoCheck( pNtkProb ) ) - { - printf( "Abc_NtkImplementRetimingBackward: The internal network check has failed.\n" ); - Abc_NtkRetimeSetInitialValues( pNtk, tTable, NULL ); - Abc_NtkDelete( pNtkProb ); - stmm_free_table( tTable ); - Vec_IntFree( vValues ); - return 0; - } - - // check if conflict is found - if ( RetValue ) - { - printf( "Abc_NtkImplementRetimingBackward: A top level conflict is detected. DC latch values are used.\n" ); - Abc_NtkRetimeSetInitialValues( pNtk, tTable, NULL ); - Abc_NtkDelete( pNtkProb ); - stmm_free_table( tTable ); - Vec_IntFree( vValues ); - return 0; - } - - // get the miter cone - pNtkMiter = Abc_NtkCreateCone( pNtkProb, pNtkProb->vCos, vValues ); - Abc_NtkDelete( pNtkProb ); - Vec_IntFree( vValues ); - - if ( fVerbose ) - printf( "The number of ANDs in the AIG = %5d.\n", Abc_NtkNodeNum(pNtkMiter) ); - - // transform the miter into a logic network for efficient CNF construction - pNtkCnf = Abc_NtkRenode( pNtkMiter, 0, 100, 1, 0, 0 ); - Abc_NtkDelete( pNtkMiter ); - - // solve the miter -clk = clock(); - RetValue = Abc_NtkMiterSat( pNtkCnf, 30, 0 ); -if ( fVerbose ) -if ( clock() - clk > 500 ) -{ -PRT( "SAT solving time", clock() - clk ); -} - pModel = pNtkCnf->pModel; pNtkCnf->pModel = NULL; - Abc_NtkDelete( pNtkCnf ); - - // analyze the result - if ( RetValue == -1 || RetValue == 1 ) - { - Abc_NtkRetimeSetInitialValues( pNtk, tTable, NULL ); - if ( RetValue == 1 ) - printf( "Abc_NtkImplementRetimingBackward: The problem is unsatisfiable. DC latch values are used.\n" ); - else - printf( "Abc_NtkImplementRetimingBackward: The SAT problem timed out. DC latch values are used.\n" ); - stmm_free_table( tTable ); - return 0; - } - - // set the values of the latches - Abc_NtkRetimeSetInitialValues( pNtk, tTable, pModel ); - stmm_free_table( tTable ); - free( pModel ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Retimes node backward by one latch.] - - Description [Constructs the problem for initial state computation. - Returns 1 if the conflict is found.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_ObjRetimeBackward( Abc_Obj_t * pObj, Abc_Ntk_t * pNtkNew, stmm_table * tTable, Vec_Int_t * vValues ) -{ - Abc_Obj_t * pFanout; - Abc_InitType_t Init, Value; - Abc_RetEdge_t RetEdge; - Abc_Obj_t * pNodeNew, * pFanoutNew, * pBuffer; - int i, Edge, fMet0, fMet1, fMetN; - - // make sure the node can be retimed - assert( Abc_ObjFanoutLMin(pObj) > 0 ); - // get the fanout values - fMet0 = fMet1 = fMetN = 0; - Abc_ObjForEachFanout( pObj, pFanout, i ) - { - Init = Abc_ObjFaninLGetInitLast( pFanout, Abc_ObjEdgeNum(pObj, pFanout) ); - if ( Init == ABC_INIT_ZERO ) - fMet0 = 1; - else if ( Init == ABC_INIT_ONE ) - fMet1 = 1; - else if ( Init == ABC_INIT_NONE ) - fMetN = 1; - } - - // consider the case when all fanout latchs have don't-care values - // the new values on the fanin edges will be don't-cares - if ( !fMet0 && !fMet1 && !fMetN ) - { - // update the fanout edges - Abc_ObjForEachFanout( pObj, pFanout, i ) - Abc_ObjFaninLDeleteLast( pFanout, Abc_ObjEdgeNum(pObj, pFanout) ); - // update the fanin edges - Abc_ObjRetimeBackwardUpdateEdge( pObj, 0, tTable ); - Abc_ObjRetimeBackwardUpdateEdge( pObj, 1, tTable ); - Abc_ObjFaninLInsertFirst( pObj, 0, ABC_INIT_DC ); - Abc_ObjFaninLInsertFirst( pObj, 1, ABC_INIT_DC ); - return 0; - } - // the initial values on the fanout edges contain 0, 1, or unknown - // the new values on the fanin edges will be unknown - - // add new AND-gate to the network - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - pNodeNew->pData = Abc_SopCreateAnd2( pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); - - // add PO fanouts if any - if ( fMet0 ) - { - Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew ); - Vec_IntPush( vValues, 0 ); - } - if ( fMet1 ) - { - Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew ); - Vec_IntPush( vValues, 1 ); - } - - // perform the changes - Abc_ObjForEachFanout( pObj, pFanout, i ) - { - Edge = Abc_ObjEdgeNum( pObj, pFanout ); - Value = Abc_ObjFaninLDeleteLast( pFanout, Edge ); - if ( Value != ABC_INIT_NONE ) - continue; - // value is unknown, remove it from the table - RetEdge.iNode = pFanout->Id; - RetEdge.iEdge = Edge; - RetEdge.iLatch = Abc_ObjFaninL( pFanout, Edge ); // after edge is removed - if ( !stmm_delete( tTable, (char **)&RetEdge, (char **)&pFanoutNew ) ) - assert( 0 ); - // create the fanout of the AND gate - Abc_ObjAddFanin( pFanoutNew, pNodeNew ); - } - - // update the fanin edges - Abc_ObjRetimeBackwardUpdateEdge( pObj, 0, tTable ); - Abc_ObjRetimeBackwardUpdateEdge( pObj, 1, tTable ); - Abc_ObjFaninLInsertFirst( pObj, 0, ABC_INIT_NONE ); - Abc_ObjFaninLInsertFirst( pObj, 1, ABC_INIT_NONE ); - - // add the buffer - pBuffer = Abc_NtkCreateNode( pNtkNew ); - pBuffer->pData = Abc_SopCreateBuf( pNtkNew->pManFunc ); - Abc_ObjAddFanin( pNodeNew, pBuffer ); - // point to it from the table - RetEdge.iNode = pObj->Id; - RetEdge.iEdge = 0; - RetEdge.iLatch = 0; - if ( stmm_insert( tTable, (char *)Abc_RetEdge2Int(RetEdge), (char *)pBuffer ) ) - assert( 0 ); - - // add the buffer - pBuffer = Abc_NtkCreateNode( pNtkNew ); - pBuffer->pData = Abc_SopCreateBuf( pNtkNew->pManFunc ); - Abc_ObjAddFanin( pNodeNew, pBuffer ); - // point to it from the table - RetEdge.iNode = pObj->Id; - RetEdge.iEdge = 1; - RetEdge.iLatch = 0; - if ( stmm_insert( tTable, (char *)Abc_RetEdge2Int(RetEdge), (char *)pBuffer ) ) - assert( 0 ); - - // report conflict is found - return fMet0 && fMet1; -} - -/**Function************************************************************* - - Synopsis [Generates the printable edge label with the initial state.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_ObjRetimeBackwardUpdateEdge( Abc_Obj_t * pObj, int Edge, stmm_table * tTable ) -{ - Abc_Obj_t * pFanoutNew; - Abc_RetEdge_t RetEdge; - Abc_InitType_t Init; - int nLatches, i; - - // get the number of latches on the edge - nLatches = Abc_ObjFaninL( pObj, Edge ); - assert( nLatches <= ABC_MAX_EDGE_LATCH ); - for ( i = nLatches - 1; i >= 0; i-- ) - { - // get the value of this latch - Init = Abc_ObjFaninLGetInitOne( pObj, Edge, i ); - if ( Init != ABC_INIT_NONE ) - continue; - // get the retiming edge - RetEdge.iNode = pObj->Id; - RetEdge.iEdge = Edge; - RetEdge.iLatch = i; - // remove entry from table and add it with a different key - if ( !stmm_delete( tTable, (char **)&RetEdge, (char **)&pFanoutNew ) ) - assert( 0 ); - RetEdge.iLatch++; - if ( stmm_insert( tTable, (char *)Abc_RetEdge2Int(RetEdge), (char *)pFanoutNew ) ) - assert( 0 ); - } -} - -/**Function************************************************************* - - Synopsis [Sets the initial values.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRetimeSetInitialValues( Abc_Ntk_t * pNtk, stmm_table * tTable, int * pModel ) -{ - Abc_Obj_t * pNode; - stmm_generator * gen; - Abc_RetEdge_t RetEdge; - Abc_InitType_t Init; - int i; - - i = 0; - stmm_foreach_item( tTable, gen, (char **)&RetEdge, NULL ) - { - pNode = Abc_NtkObj( pNtk, RetEdge.iNode ); - Init = pModel? (pModel[i]? ABC_INIT_ONE : ABC_INIT_ZERO) : ABC_INIT_DC; - Abc_ObjFaninLSetInitOne( pNode, RetEdge.iEdge, RetEdge.iLatch, Init ); - i++; - } -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abcs/abcRetUtil.c b/src/base/abcs/abcRetUtil.c deleted file mode 100644 index 9a283e03..00000000 --- a/src/base/abcs/abcRetUtil.c +++ /dev/null @@ -1,244 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcRetUtil.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Retiming utilities.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcRetUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abcs.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs forward retiming of the sequential AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkUtilRetimingTry( Abc_Ntk_t * pNtk, bool fForward ) -{ - Vec_Ptr_t * vNodes, * vMoves; - Abc_Obj_t * pNode, * pFanout, * pFanin; - int i, k, nLatches; - assert( Abc_NtkIsSeq( pNtk ) ); - // assume that all nodes can be retimed - vNodes = Vec_PtrAlloc( 100 ); - Abc_AigForEachAnd( pNtk, pNode, i ) - { - Vec_PtrPush( vNodes, pNode ); - pNode->fMarkA = 1; - } - // process the nodes - vMoves = Vec_PtrAlloc( 100 ); - Vec_PtrForEachEntry( vNodes, pNode, i ) - { -// printf( "(%d,%d) ", Abc_ObjFaninL0(pNode), Abc_ObjFaninL0(pNode) ); - // unmark the node as processed - pNode->fMarkA = 0; - // get the number of latches to retime - if ( fForward ) - nLatches = Abc_ObjFaninLMin(pNode); - else - nLatches = Abc_ObjFanoutLMin(pNode); - if ( nLatches == 0 ) - continue; - assert( nLatches > 0 ); - // retime the latches forward - if ( fForward ) - Abc_ObjRetimeForwardTry( pNode, nLatches ); - else - Abc_ObjRetimeBackwardTry( pNode, nLatches ); - // write the moves - for ( k = 0; k < nLatches; k++ ) - Vec_PtrPush( vMoves, pNode ); - // schedule fanouts for updating - if ( fForward ) - { - Abc_ObjForEachFanout( pNode, pFanout, k ) - { - if ( Abc_ObjFaninNum(pFanout) != 2 || pFanout->fMarkA ) - continue; - pFanout->fMarkA = 1; - Vec_PtrPush( vNodes, pFanout ); - } - } - else - { - Abc_ObjForEachFanin( pNode, pFanin, k ) - { - if ( Abc_ObjFaninNum(pFanin) != 2 || pFanin->fMarkA ) - continue; - pFanin->fMarkA = 1; - Vec_PtrPush( vNodes, pFanin ); - } - } - } - Vec_PtrFree( vNodes ); - // make sure the marks are clean the the retiming is final - Abc_AigForEachAnd( pNtk, pNode, i ) - { - assert( pNode->fMarkA == 0 ); - if ( fForward ) - assert( Abc_ObjFaninLMin(pNode) == 0 ); - else - assert( Abc_ObjFanoutLMin(pNode) == 0 ); - } - return vMoves; -} - -/**Function************************************************************* - - Synopsis [Translates retiming steps into retiming moves.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkUtilRetimingGetMoves( Abc_Ntk_t * pNtk, Vec_Int_t * vSteps, bool fForward ) -{ - Abc_RetStep_t RetStep; - Vec_Ptr_t * vMoves; - Abc_Obj_t * pNode; - int i, k, iNode, nLatches, Number; - int fChange; - assert( Abc_NtkIsSeq( pNtk ) ); - // process the nodes - vMoves = Vec_PtrAlloc( 100 ); - while ( Vec_IntSize(vSteps) > 0 ) - { - iNode = 0; - fChange = 0; - Vec_IntForEachEntry( vSteps, Number, i ) - { - // get the retiming step - RetStep = Abc_Int2RetStep( Number ); - // get the node to be retimed - pNode = Abc_NtkObj( pNtk, RetStep.iNode ); - assert( RetStep.nLatches > 0 ); - // get the number of latches that can be retimed - if ( fForward ) - nLatches = Abc_ObjFaninLMin(pNode); - else - nLatches = Abc_ObjFanoutLMin(pNode); - if ( nLatches == 0 ) - { - Vec_IntWriteEntry( vSteps, iNode++, Abc_RetStep2Int(RetStep) ); - continue; - } - assert( nLatches > 0 ); - fChange = 1; - // get the number of latches to be retimed over this node - nLatches = ABC_MIN( nLatches, (int)RetStep.nLatches ); - // retime the latches forward - if ( fForward ) - Abc_ObjRetimeForwardTry( pNode, nLatches ); - else - Abc_ObjRetimeBackwardTry( pNode, nLatches ); - // write the moves - for ( k = 0; k < nLatches; k++ ) - Vec_PtrPush( vMoves, pNode ); - // subtract the retiming performed - RetStep.nLatches -= nLatches; - // store the node if it is not retimed completely - if ( RetStep.nLatches > 0 ) - Vec_IntWriteEntry( vSteps, iNode++, Abc_RetStep2Int(RetStep) ); - } - // reduce the array - Vec_IntShrink( vSteps, iNode ); - if ( !fChange ) - { - printf( "Warning: %d strange steps.\n", Vec_IntSize(vSteps) ); - /* - Vec_IntForEachEntry( vSteps, Number, i ) - { - RetStep = Abc_Int2RetStep( Number ); - printf( "%d(%d) ", RetStep.iNode, RetStep.nLatches ); - } - printf( "\n" ); - */ - break; - } - } - // undo the tentative retiming - if ( fForward ) - { - Vec_PtrForEachEntryReverse( vMoves, pNode, i ) - Abc_ObjRetimeBackwardTry( pNode, 1 ); - } - else - { - Vec_PtrForEachEntryReverse( vMoves, pNode, i ) - Abc_ObjRetimeForwardTry( pNode, 1 ); - } - return vMoves; -} - - -/**Function************************************************************* - - Synopsis [Splits retiming into forward and backward.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Abc_NtkUtilRetimingSplit( Vec_Str_t * vLags, int fForward ) -{ - Vec_Int_t * vNodes; - Abc_RetStep_t RetStep; - int Value, i; - vNodes = Vec_IntAlloc( 100 ); - Vec_StrForEachEntry( vLags, Value, i ) - { -// assert( Value <= ABC_MAX_EDGE_LATCH ); - if ( Value < 0 && fForward ) - { - RetStep.iNode = i; - RetStep.nLatches = -Value; - Vec_IntPush( vNodes, Abc_RetStep2Int(RetStep) ); - } - else if ( Value > 0 && !fForward ) - { - RetStep.iNode = i; - RetStep.nLatches = Value; - Vec_IntPush( vNodes, Abc_RetStep2Int(RetStep) ); - } - } - return vNodes; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abcs/abcSeqMan.c b/src/base/abcs/abcSeqMan.c deleted file mode 100644 index 181d8c29..00000000 --- a/src/base/abcs/abcSeqMan.c +++ /dev/null @@ -1,218 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcSeqMan.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Manager of sequential AIGs.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcSeqMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abcs.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Abc_SeqLat_t_ Abc_SeqLat_t; -struct Abc_SeqLat_t_ -{ - Abc_SeqLat_t * pNext; // the next Lat in the ring - Abc_SeqLat_t * pPrev; // the prev Lat in the ring -}; - -typedef struct Abc_SeqMan_t_ Abc_SeqMan_t; -struct Abc_SeqMan_t_ -{ - int nSize; // the number of entries in all internal arrays - Vec_Ptr_t * vInits; // the initial states for each edge in the AIG - Extra_MmFixed_t * pMmInits; // memory manager for initial states of the Lates - -}; - -// reading the contents of the lat -static inline Abc_InitType_t Abc_SeqLatInit( Abc_SeqLat_t * pLat ) { return ((unsigned)pLat->pPrev) & 3; } -static inline Abc_SeqLat_t * Abc_SeqLatNext( Abc_SeqLat_t * pLat ) { return pLat->pNext; } -static inline Abc_SeqLat_t * Abc_SeqLatPrev( Abc_SeqLat_t * pLat ) { return (void *)(((unsigned)pLat->pPrev) & (ABC_FULL_MASK << 2)); } - -// setting the contents of the lat -static inline void Abc_SeqLatSetInit( Abc_SeqLat_t * pLat, Abc_InitType_t Init ) { pLat->pPrev = (void *)( (3 & Init) | (((unsigned)pLat->pPrev) & (ABC_FULL_MASK << 2)) ); } -static inline void Abc_SeqLatSetNext( Abc_SeqLat_t * pLat, Abc_SeqLat_t * pNext ) { pLat->pNext = pNext; } -static inline void Abc_SeqLatSetPrev( Abc_SeqLat_t * pLat, Abc_SeqLat_t * pPrev ) { Abc_InitType_t Init = Abc_SeqLatInit(pLat); pLat->pPrev = pPrev; Abc_SeqLatSetInit(pLat, Init); } - -// accessing initial state datastructure -static inline Vec_Ptr_t * Abc_SeqNodeInits( Abc_Obj_t * pObj ) { return ((Abc_SeqMan_t*)pObj->pNtk->pManFunc)->vInits; } -static inline Abc_SeqLat_t * Abc_SeqNodeReadInit( Abc_Obj_t * pObj, int Edge ) { return Vec_PtrEntry( Abc_SeqNodeInits(pObj), (pObj->Id<<1)+Edge ); } -static inline void Abc_SeqNodeSetInit ( Abc_Obj_t * pObj, int Edge, Abc_SeqLat_t * pInit ) { Vec_PtrWriteEntry( Abc_SeqNodeInits(pObj), (pObj->Id<<1)+Edge, pInit ); } -static inline Abc_SeqLat_t * Abc_SeqNodeCreateLat( Abc_Obj_t * pObj ) { return (Abc_SeqLat_t *)Extra_MmFixedEntryFetch( ((Abc_SeqMan_t*)pObj->pNtk->pManFunc)->pMmInits ); } -static inline void Abc_SeqNodeRecycleLat( Abc_Obj_t * pObj, Abc_SeqLat_t * pLat ) { Extra_MmFixedEntryRecycle( ((Abc_SeqMan_t*)pObj->pNtk->pManFunc)->pMmInits, (char *)pLat ); } - -// getting the Lat with the given number -static inline Abc_SeqLat_t * Abc_SeqNodeGetLat( Abc_Obj_t * pObj, int Edge, int iLat ) -{ - int Counter; - Abc_SeqLat_t * pLat = Abc_SeqNodeReadInit(pObj, Edge); - for ( Counter = 0; Counter != iLat; Counter++ ) - pLat = pLat->pNext; - return pLat; -} -// getting the first Lat -static inline Abc_SeqLat_t * Abc_SeqNodeGetLatFirst( Abc_Obj_t * pObj, int Edge ) -{ - return Abc_SeqNodeReadInit(pObj, Edge); -} -// getting the last Lat -static inline Abc_SeqLat_t * Abc_SeqNodeGetLatLast( Abc_Obj_t * pObj, int Edge ) -{ - return Abc_SeqLatPrev( Abc_SeqNodeReadInit(pObj, Edge) ); -} - -// getting the init value of the given Lat on the edge -static inline Abc_InitType_t Abc_SeqNodeGetInitOne( Abc_Obj_t * pObj, int Edge, int iLat ) -{ - return Abc_SeqLatInit( Abc_SeqNodeGetLat(pObj, Edge, iLat) ); -} -// geting the init value of the first Lat on the edge -static inline Abc_InitType_t Abc_SeqNodeGetInitFirst( Abc_Obj_t * pObj, int Edge ) -{ - return Abc_SeqLatInit( Abc_SeqNodeGetLatFirst(pObj, Edge) ); -} -// geting the init value of the last Lat on the edge -static inline Abc_InitType_t Abc_SeqNodeGetInitLast( Abc_Obj_t * pObj, int Edge ) -{ - return Abc_SeqLatInit( Abc_SeqNodeGetLatLast(pObj, Edge) ); -} - - -// setting the init value of the given Lat on the edge -static inline void Abc_SeqNodeSetInitOne( Abc_Obj_t * pObj, int Edge, int iLat, Abc_InitType_t Init ) -{ - Abc_SeqLatSetInit( Abc_SeqNodeGetLat(pObj, Edge, iLat), Init ); -} - - -// insert the first Lat on the edge -static inline void Abc_SeqNodeInsertFirst( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init ) -{ - Abc_SeqLat_t * pLat, * pRing, * pPrev; - pLat = Abc_SeqNodeCreateLat( pObj ); - pRing = Abc_SeqNodeReadInit( pObj, Edge ); - if ( pRing == NULL ) - { - pLat->pNext = pLat->pPrev = pLat; - Abc_SeqNodeSetInit( pObj, Edge, pLat ); - } - else - { - Abc_SeqLatSetPrev( pRing, pLat ); - Abc_SeqLatSetNext( pLat, pRing ); - pPrev = Abc_SeqLatPrev( pRing ); - Abc_SeqLatSetPrev( pLat, pPrev ); - Abc_SeqLatSetNext( pPrev, pLat ); - Abc_SeqNodeSetInit( pObj, Edge, pLat ); // rotate the ring to make pLat the first - } - Abc_SeqLatSetInit( pLat, Init ); -} - -// insert the last Lat on the edge -static inline void Abc_SeqNodeInsertLast( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init ) -{ - Abc_SeqLat_t * pLat, * pRing, * pPrev; - pLat = Abc_SeqNodeCreateLat( pObj ); - pRing = Abc_SeqNodeReadInit( pObj, Edge ); - if ( pRing == NULL ) - { - pLat->pNext = pLat->pPrev = pLat; - Abc_SeqNodeSetInit( pObj, Edge, pLat ); - } - else - { - Abc_SeqLatSetPrev( pRing, pLat ); - Abc_SeqLatSetNext( pLat, pRing ); - pPrev = Abc_SeqLatPrev( pRing ); - Abc_SeqLatSetPrev( pLat, pPrev ); - Abc_SeqLatSetNext( pPrev, pLat ); - } - Abc_SeqLatSetInit( pLat, Init ); -} - -// delete the first Lat on the edge -static inline Abc_InitType_t Abc_SeqNodeDeleteFirst( Abc_Obj_t * pObj, int Edge ) -{ - Abc_SeqLat_t * pLat, * pRing, * pPrev, * pNext; - pRing = Abc_SeqNodeReadInit( pObj, Edge ); - pLat = pRing; // consider the first latch - if ( pLat->pNext == pLat ) - Abc_SeqNodeSetInit( pObj, Edge, NULL ); - else - { - pPrev = Abc_SeqLatPrev( pLat ); - pNext = Abc_SeqLatNext( pLat ); - Abc_SeqLatSetPrev( pNext, pPrev ); - Abc_SeqLatSetNext( pPrev, pNext ); - Abc_SeqNodeSetInit( pObj, Edge, pNext ); // rotate the ring - } - Abc_SeqNodeRecycleLat( pObj, pLat ); -} - -// delete the last Lat on the edge -static inline Abc_InitType_t Abc_SeqNodeDeleteLast( Abc_Obj_t * pObj, int Edge ) -{ - Abc_SeqLat_t * pLat, * pRing, * pPrev, * pNext; - pRing = Abc_SeqNodeReadInit( pObj, Edge ); - pLat = Abc_SeqLatPrev( pRing ); // consider the last latch - if ( pLat->pNext == pLat ) - Abc_SeqNodeSetInit( pObj, Edge, NULL ); - else - { - pPrev = Abc_SeqLatPrev( pLat ); - pNext = Abc_SeqLatNext( pLat ); - Abc_SeqLatSetPrev( pNext, pPrev ); - Abc_SeqLatSetNext( pPrev, pNext ); - } - Abc_SeqNodeRecycleLat( pObj, pLat ); -} - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_SeqMan_t * Abc_SeqCreate( int nMaxId ) -{ - Abc_SeqMan_t * p; - // start the manager - p = ALLOC( Abc_SeqMan_t, 1 ); - memset( p, 0, sizeof(Abc_SeqMan_t) ); - p->nSize = nMaxId + 1; - // create internal data structures - p->vInits = Vec_PtrStart( 2 * p->nSize ); - p->pMmInits = Extra_MmFixedStart( sizeof(Abc_SeqLat_t) ); - return p; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abcs/abcUtils.c b/src/base/abcs/abcUtils.c deleted file mode 100644 index 412098b1..00000000 --- a/src/base/abcs/abcUtils.c +++ /dev/null @@ -1,172 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcUtils.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Utilities working sequential AIGs.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcUtils.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abcs.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Counts the number of latches in the sequential AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkSeqLatchNum( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i, Counter; - assert( Abc_NtkIsSeq( pNtk ) ); - Counter = 0; - Abc_NtkForEachNode( pNtk, pObj, i ) - Counter += Abc_ObjFaninLSum( pObj ); - Abc_NtkForEachPo( pNtk, pObj, i ) - Counter += Abc_ObjFaninLSum( pObj ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [Counts the number of latches in the sequential AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkSeqLatchNumShared( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i, Counter; - assert( Abc_NtkIsSeq( pNtk ) ); - Counter = 0; - Abc_NtkForEachPi( pNtk, pObj, i ) - Counter += Abc_ObjFanoutLMax( pObj ); - Abc_NtkForEachNode( pNtk, pObj, i ) - Counter += Abc_ObjFanoutLMax( pObj ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [Counts the number of latches in the sequential AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_ObjLatchGetInitNums( Abc_Obj_t * pObj, int Edge, int * pInits ) -{ - Abc_InitType_t Init; - int nLatches, i; - nLatches = Abc_ObjFaninL( pObj, Edge ); - assert( nLatches <= ABC_MAX_EDGE_LATCH ); - for ( i = 0; i < nLatches; i++ ) - { - Init = Abc_ObjFaninLGetInitOne( pObj, Edge, i ); - pInits[Init]++; - } -} - -/**Function************************************************************* - - Synopsis [Counts the number of latches in the sequential AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkSeqLatchGetInitNums( Abc_Ntk_t * pNtk, int * pInits ) -{ - Abc_Obj_t * pObj; - int i; - assert( Abc_NtkIsSeq( pNtk ) ); - for ( i = 0; i < 4; i++ ) - pInits[i] = 0; - Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_ObjLatchGetInitNums( pObj, 0, pInits ); - Abc_NtkForEachNode( pNtk, pObj, i ) - { - if ( Abc_ObjFaninNum(pObj) > 0 ) - Abc_ObjLatchGetInitNums( pObj, 0, pInits ); - if ( Abc_ObjFaninNum(pObj) > 1 ) - Abc_ObjLatchGetInitNums( pObj, 1, pInits ); - } -} - -/**Function************************************************************* - - Synopsis [Generates the printable edge label with the initial state.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Abc_ObjFaninGetInitPrintable( Abc_Obj_t * pObj, int Edge ) -{ - static char Buffer[ABC_MAX_EDGE_LATCH + 1]; - Abc_InitType_t Init; - int nLatches, i; - - nLatches = Abc_ObjFaninL( pObj, Edge ); - assert( nLatches <= ABC_MAX_EDGE_LATCH ); - for ( i = 0; i < nLatches; i++ ) - { - Init = Abc_ObjFaninLGetInitOne( pObj, Edge, i ); - if ( Init == ABC_INIT_NONE ) - Buffer[i] = '_'; - else if ( Init == ABC_INIT_ZERO ) - Buffer[i] = '0'; - else if ( Init == ABC_INIT_ONE ) - Buffer[i] = '1'; - else if ( Init == ABC_INIT_DC ) - Buffer[i] = 'x'; - else assert( 0 ); - } - Buffer[nLatches] = 0; - return Buffer; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/abcs/abcs.h b/src/base/abcs/abcs.h deleted file mode 100644 index a85556ac..00000000 --- a/src/base/abcs/abcs.h +++ /dev/null @@ -1,355 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcs.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Sequential synthesis package.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcs.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __ABCS_H__ -#define __ABCS_H__ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include "abc.h" -#include "cut.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -// the maximum number of latches on the edge -#define ABC_MAX_EDGE_LATCH 16 -#define ABC_FULL_MASK 0xFFFFFFFF - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Seq_FpgaMan_t_ Seq_FpgaMan_t; -struct Seq_FpgaMan_t_ -{ - Abc_Ntk_t * pNtk; // the network to be mapped - Cut_Man_t * pMan; // the cut manager - Vec_Int_t * vArrivals; // the arrival times (L-Values of nodes) - Vec_Ptr_t * vBestCuts; // the best cuts for nodes - Vec_Ptr_t * vMapping; // the nodes used in the mapping - Vec_Ptr_t * vMapCuts; // the info about the cut of each mapped node - Vec_Str_t * vLagsMap; // the lags of the mapped nodes - int fVerbose; // the verbose flag - // runtime stats - int timeCuts; // runtime to compute the cuts - int timeDelay; // runtime to compute the L-values - int timeRet; // runtime to retime the resulting network - int timeNtk; // runtime to create the final network -}; - - -// representation of latch on the edge -typedef struct Abc_RetEdge_t_ Abc_RetEdge_t; -struct Abc_RetEdge_t_ // 1 word -{ - unsigned iNode : 24; // the ID of the node - unsigned iEdge : 1; // the edge of the node - unsigned iLatch : 7; // the latch number counting from the node -}; - -// representation of one retiming step -typedef struct Abc_RetStep_t_ Abc_RetStep_t; -struct Abc_RetStep_t_ // 1 word -{ - unsigned iNode : 24; // the ID of the node - unsigned nLatches : 8; // the number of latches to retime -}; - -static inline int Abc_RetEdge2Int( Abc_RetEdge_t Str ) { return *((int *)&Str); } -static inline Abc_RetEdge_t Abc_Int2RetEdge( int Num ) { return *((Abc_RetEdge_t *)&Num); } - -static inline int Abc_RetStep2Int( Abc_RetStep_t Str ) { return *((int *)&Str); } -static inline Abc_RetStep_t Abc_Int2RetStep( int Num ) { return *((Abc_RetStep_t *)&Num); } - -// storing arrival times in the nodes -static inline int Abc_NodeReadLValue( Abc_Obj_t * pNode ) { return Vec_IntEntry( (pNode)->pNtk->pData, (pNode)->Id ); } -static inline void Abc_NodeSetLValue( Abc_Obj_t * pNode, int Value ) { Vec_IntWriteEntry( (pNode)->pNtk->pData, (pNode)->Id, (Value) ); } -//static inline int Abc_NodeGetLag( int LValue, int Fi ) { return LValue/Fi - (int)(LValue % Fi == 0); } -static inline int Abc_NodeGetLag( int LValue, int Fi ) { return (LValue + 256*Fi)/Fi - 256 - (int)(LValue % Fi == 0); } - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -// getting the number of the edge for this fanout -static inline int Abc_ObjEdgeNum( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) -{ - assert( Abc_NtkIsSeq(pObj->pNtk) ); - if ( Abc_ObjFaninId0(pFanout) == (int)pObj->Id ) - return 0; - else if ( Abc_ObjFaninId1(pFanout) == (int)pObj->Id ) - return 1; - assert( 0 ); - return -1; -} - -// getting the latch number of the fanout -static inline int Abc_ObjFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout ) -{ - return Abc_ObjFaninL( pFanout, Abc_ObjEdgeNum(pObj,pFanout) ); -} - -// setting the latch number of the fanout -static inline void Abc_ObjSetFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats ) -{ - Abc_ObjSetFaninL( pFanout, Abc_ObjEdgeNum(pObj,pFanout), nLats ); -} - -// adding to the latch number of the fanout -static inline void Abc_ObjAddFanoutL( Abc_Obj_t * pObj, Abc_Obj_t * pFanout, int nLats ) -{ - Abc_ObjAddFaninL( pFanout, Abc_ObjEdgeNum(pObj,pFanout), nLats ); -} - -// returns the latch number of the fanout -static inline int Abc_ObjFanoutLMax( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanout; - int i, nLatchCur, nLatchRes; - if ( Abc_ObjFanoutNum(pObj) == 0 ) - return 0; - nLatchRes = 0; - Abc_ObjForEachFanout( pObj, pFanout, i ) - { - nLatchCur = Abc_ObjFanoutL(pObj, pFanout); - if ( nLatchRes < nLatchCur ) - nLatchRes = nLatchCur; - } - assert( nLatchRes >= 0 ); - return nLatchRes; -} - -// returns the latch number of the fanout -static inline int Abc_ObjFanoutLMin( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanout; - int i, nLatchCur, nLatchRes; - if ( Abc_ObjFanoutNum(pObj) == 0 ) - return 0; - nLatchRes = ABC_INFINITY; - Abc_ObjForEachFanout( pObj, pFanout, i ) - { - nLatchCur = Abc_ObjFanoutL(pObj, pFanout); - if ( nLatchRes > nLatchCur ) - nLatchRes = nLatchCur; - } - assert( nLatchRes < ABC_INFINITY ); - return nLatchRes; -} - -// returns the sum of latches on the fanout edges -static inline int Abc_ObjFanoutLSum( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanout; - int i, nSum = 0; - Abc_ObjForEachFanout( pObj, pFanout, i ) - nSum += Abc_ObjFanoutL(pObj, pFanout); - return nSum; -} - -// returns the sum of latches on the fanin edges -static inline int Abc_ObjFaninLSum( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanin; - int i, nSum = 0; - Abc_ObjForEachFanin( pObj, pFanin, i ) - nSum += Abc_ObjFaninL(pObj, i); - return nSum; -} - - -// getting the bit-string of init values of the edge -static inline unsigned Abc_ObjFaninLGetInit( Abc_Obj_t * pObj, int Edge ) -{ - return (unsigned)Vec_IntEntry( pObj->pNtk->vInits, 2 * pObj->Id + Edge ); -} - -// setting bit-string of init values of the edge -static inline void Abc_ObjFaninLSetInit( Abc_Obj_t * pObj, int Edge, unsigned Init ) -{ - Vec_IntWriteEntry( pObj->pNtk->vInits, 2 * pObj->Id + Edge, Init ); -} - -// getting the init value of the given latch on the edge -static inline Abc_InitType_t Abc_ObjFaninLGetInitOne( Abc_Obj_t * pObj, int Edge, int iLatch ) -{ - return 0x3 & (Abc_ObjFaninLGetInit(pObj, Edge) >> (2*iLatch)); -} - -// setting the init value of the given latch on the edge -static inline void Abc_ObjFaninLSetInitOne( Abc_Obj_t * pObj, int Edge, int iLatch, Abc_InitType_t Init ) -{ - unsigned EntryCur = Abc_ObjFaninLGetInit(pObj, Edge); - unsigned EntryNew = (EntryCur & ~(0x3 << (2*iLatch))) | (Init << (2*iLatch)); - assert( iLatch < Abc_ObjFaninL(pObj, Edge) ); - Abc_ObjFaninLSetInit( pObj, Edge, EntryNew ); -} - -// geting the init value of the first latch on the edge -static inline Abc_InitType_t Abc_ObjFaninLGetInitFirst( Abc_Obj_t * pObj, int Edge ) -{ - return 0x3 & Abc_ObjFaninLGetInit( pObj, Edge ); -} - -// geting the init value of the last latch on the edge -static inline Abc_InitType_t Abc_ObjFaninLGetInitLast( Abc_Obj_t * pObj, int Edge ) -{ - assert( Abc_ObjFaninL(pObj, Edge) > 0 ); - return 0x3 & (Abc_ObjFaninLGetInit(pObj, Edge) >> (2 * (Abc_ObjFaninL(pObj, Edge) - 1))); -} - -// insert the first latch on the edge -static inline void Abc_ObjFaninLInsertFirst( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init ) -{ - unsigned EntryCur = Abc_ObjFaninLGetInit(pObj, Edge); - unsigned EntryNew = ((EntryCur << 2) | Init); - assert( Init >= 0 && Init < 4 ); - assert( Abc_ObjFaninL(pObj, Edge) < ABC_MAX_EDGE_LATCH ); - Abc_ObjFaninLSetInit( pObj, Edge, EntryNew ); - Abc_ObjAddFaninL( pObj, Edge, 1 ); -} - -// insert the last latch on the edge -static inline void Abc_ObjFaninLInsertLast( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init ) -{ - unsigned EntryCur = Abc_ObjFaninLGetInit(pObj, Edge); - unsigned EntryNew = EntryCur | (Init << (2 * Abc_ObjFaninL(pObj, Edge))); - assert( Init >= 0 && Init < 4 ); - assert( Abc_ObjFaninL(pObj, Edge) < ABC_MAX_EDGE_LATCH ); - if ( Abc_ObjFaninL(pObj, Edge) >= ABC_MAX_EDGE_LATCH ) - printf( "The limit on latched on the edge (%d) is exceeded.\n", ABC_MAX_EDGE_LATCH ); - Abc_ObjFaninLSetInit( pObj, Edge, EntryNew ); - Abc_ObjAddFaninL( pObj, Edge, 1 ); -} - -// delete the first latch on the edge -static inline Abc_InitType_t Abc_ObjFaninLDeleteFirst( Abc_Obj_t * pObj, int Edge ) -{ - unsigned EntryCur = Abc_ObjFaninLGetInit(pObj, Edge); - Abc_InitType_t Init = 0x3 & EntryCur; - unsigned EntryNew = EntryCur >> 2; - assert( Abc_ObjFaninL(pObj, Edge) > 0 ); - Abc_ObjFaninLSetInit( pObj, Edge, EntryNew ); - Abc_ObjAddFaninL( pObj, Edge, -1 ); - return Init; -} - -// delete the last latch on the edge -static inline Abc_InitType_t Abc_ObjFaninLDeleteLast( Abc_Obj_t * pObj, int Edge ) -{ - unsigned EntryCur = Abc_ObjFaninLGetInit(pObj, Edge); - Abc_InitType_t Init = 0x3 & (EntryCur >> (2 * (Abc_ObjFaninL(pObj, Edge) - 1))); - unsigned EntryNew = EntryCur & ~(((unsigned)0x3) << (2 * (Abc_ObjFaninL(pObj, Edge)-1))); - assert( Abc_ObjFaninL(pObj, Edge) > 0 ); - Abc_ObjFaninLSetInit( pObj, Edge, EntryNew ); - Abc_ObjAddFaninL( pObj, Edge, -1 ); - return Init; -} - -// retime node forward without initial states -static inline void Abc_ObjRetimeForwardTry( Abc_Obj_t * pObj, int nLatches ) -{ - Abc_Obj_t * pFanout; - int i; - // make sure it is an AND gate - assert( Abc_ObjFaninNum(pObj) == 2 ); - // make sure it has enough latches -// assert( Abc_ObjFaninL0(pObj) >= nLatches ); -// assert( Abc_ObjFaninL1(pObj) >= nLatches ); - // subtract these latches on the fanin side - Abc_ObjAddFaninL0( pObj, -nLatches ); - Abc_ObjAddFaninL1( pObj, -nLatches ); - // add these latches on the fanout size - Abc_ObjForEachFanout( pObj, pFanout, i ) - Abc_ObjAddFanoutL( pObj, pFanout, nLatches ); -} - -// retime node backward without initial states -static inline void Abc_ObjRetimeBackwardTry( Abc_Obj_t * pObj, int nLatches ) -{ - Abc_Obj_t * pFanout; - int i; - // make sure it is an AND gate - assert( Abc_ObjFaninNum(pObj) == 2 ); - // subtract these latches on the fanout side - Abc_ObjForEachFanout( pObj, pFanout, i ) - { -// assert( Abc_ObjFanoutL(pObj, pFanout) >= nLatches ); - Abc_ObjAddFanoutL( pObj, pFanout, -nLatches ); - } - // add these latches on the fanin size - Abc_ObjAddFaninL0( pObj, nLatches ); - Abc_ObjAddFaninL1( pObj, nLatches ); -} - - -//////////////////////////////////////////////////////////////////////// -/// ITERATORS /// -//////////////////////////////////////////////////////////////////////// - -// iterating through the initial values of the edge -#define Abc_ObjFaninLForEachValue( pObj, Edge, Init, i, Value ) \ - for ( i = 0, Init = Abc_ObjFaninLGetInit(pObj, Edge); \ - i < Abc_ObjFaninL(pObj, Edge) && ((Value = ((Init >> (2*i)) & 0x3)), 1); i++ ) - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== abcRetCore.c ===========================================================*/ -extern void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk, int fVerbose ); -extern void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk, int fVerbose ); -extern void Abc_NtkSeqRetimeInitial( Abc_Ntk_t * pNtk, int fVerbose ); -extern void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk, int fVerbose ); -/*=== abcRetDelay.c ==========================================================*/ -extern Vec_Str_t * Abc_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose ); -/*=== abcRetImpl.c ===========================================================*/ -extern int Abc_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags, int fVerbose ); -extern void Abc_NtkImplementRetimingForward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves ); -extern int Abc_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int fVerbose ); -/*=== abcRetUtil.c ===========================================================*/ -extern Vec_Ptr_t * Abc_NtkUtilRetimingTry( Abc_Ntk_t * pNtk, bool fForward ); -extern Vec_Ptr_t * Abc_NtkUtilRetimingGetMoves( Abc_Ntk_t * pNtk, Vec_Int_t * vNodes, bool fForward ); -extern Vec_Int_t * Abc_NtkUtilRetimingSplit( Vec_Str_t * vLags, int fForward ); -/*=== abcSeq.c ===============================================================*/ -extern Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk ); -extern Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk ); -/*=== abcShare.c =============================================================*/ -extern void Abc_NtkSeqShareFanouts( Abc_Ntk_t * pNtk ); -/*=== abcUtil.c ==============================================================*/ -extern int Abc_NtkSeqLatchNum( Abc_Ntk_t * pNtk ); -extern int Abc_NtkSeqLatchNumShared( Abc_Ntk_t * pNtk ); -extern void Abc_NtkSeqLatchGetInitNums( Abc_Ntk_t * pNtk, int * pInits ); -extern char * Abc_ObjFaninGetInitPrintable( Abc_Obj_t * pObj, int Edge ); - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - -#endif - diff --git a/src/base/abcs/module.make b/src/base/abcs/module.make deleted file mode 100644 index e8d5a8db..00000000 --- a/src/base/abcs/module.make +++ /dev/null @@ -1,9 +0,0 @@ -SRC += src/base/abcs/abcFpgaDelay.c \ - src/base/abcs/abcFpgaSeq.c \ - src/base/abcs/abcRetCore.c \ - src/base/abcs/abcRetDelay.c \ - src/base/abcs/abcRetImpl.c \ - src/base/abcs/abcRetUtil.c \ - src/base/abcs/abcSeq.c \ - src/base/abcs/abcShare.c \ - src/base/abcs/abcUtils.c diff --git a/src/base/io/io.c b/src/base/io/io.c index 1022c882..e5f8b9a1 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -42,6 +42,7 @@ static int IoCommandWriteCnf ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteDot ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteEqn ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteGml ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int IoCommandWriteList ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWritePla ( Abc_Frame_t * pAbc, int argc, char **argv ); //////////////////////////////////////////////////////////////////////// @@ -78,6 +79,7 @@ void Io_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "I/O", "write_dot", IoCommandWriteDot, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_eqn", IoCommandWriteEqn, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_gml", IoCommandWriteGml, 0 ); + Cmd_CommandAdd( pAbc, "I/O", "write_list", IoCommandWriteList, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_pla", IoCommandWritePla, 0 ); } @@ -1253,6 +1255,71 @@ usage: SeeAlso [] ***********************************************************************/ +int IoCommandWriteList( Abc_Frame_t * pAbc, int argc, char **argv ) +{ + char * FileName; + int fUseHost; + int c; + + fUseHost = 1; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "nh" ) ) != EOF ) + { + switch ( c ) + { + case 'n': + fUseHost ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pAbc->pNtkCur == NULL ) + { + fprintf( pAbc->Out, "Empty network.\n" ); + return 0; + } + + if ( !Abc_NtkIsSeq(pAbc->pNtkCur) ) + { + fprintf( stdout, "IoCommandWriteList(): Can write adjacency list for sequential AIGs only.\n" ); + return 0; + } + + if ( argc != util_optind + 1 ) + { + goto usage; + } + + // get the input file name + FileName = argv[util_optind]; + // write the file + Io_WriteList( pAbc->pNtkCur, FileName, fUseHost ); + return 0; + +usage: + fprintf( pAbc->Err, "usage: write_list [-nh] <file>\n" ); + fprintf( pAbc->Err, "\t write network using graph representation formal GML\n" ); + fprintf( pAbc->Err, "\t-n : toggle writing host node [default = %s]\n", fUseHost? "yes":"no" ); + fprintf( pAbc->Err, "\t-h : print the help massage\n" ); + fprintf( pAbc->Err, "\tfile : the name of the file to write\n" ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv ) { Abc_Ntk_t * pNtk, * pNtkTemp; diff --git a/src/base/io/io.h b/src/base/io/io.h index 6505a57d..21bb9214 100644 --- a/src/base/io/io.h +++ b/src/base/io/io.h @@ -85,6 +85,8 @@ extern void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec extern void Io_WriteEqn( Abc_Ntk_t * pNtk, char * pFileName ); /*=== abcWriteGml.c ==========================================================*/ extern void Io_WriteGml( Abc_Ntk_t * pNtk, char * pFileName ); +/*=== abcWriteList.c ==========================================================*/ +extern void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost ); /*=== abcWritePla.c ==========================================================*/ extern int Io_WritePla( Abc_Ntk_t * pNtk, char * FileName ); diff --git a/src/base/io/ioReadBaf.c b/src/base/io/ioReadBaf.c index 4a62f397..2d6c3ca6 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_AigConst1(pNtkNew->pManFunc) ); + Vec_PtrPush( vNodes, Abc_NtkConst1(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 b2132f28..06f32f38 100644 --- a/src/base/io/ioWriteDot.c +++ b/src/base/io/ioWriteDot.c @@ -19,7 +19,7 @@ ***********************************************************************/ #include "io.h" -#include "abcs.h" +#include "seq.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -316,7 +316,7 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, fprintf( pFile, " [" ); fprintf( pFile, "style = %s", Abc_ObjFaninC0(pNode)? "dotted" : "bold" ); if ( Abc_ObjFaninL0(pNode) > 0 ) - fprintf( pFile, ", label = \"%s\"", Abc_ObjFaninGetInitPrintable(pNode,0) ); + fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,0) ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } @@ -331,7 +331,7 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, fprintf( pFile, " [" ); fprintf( pFile, "style = %s", Abc_ObjFaninC1(pNode)? "dotted" : "bold" ); if ( Abc_ObjFaninL1(pNode) > 0 ) - fprintf( pFile, ", label = \"%s\"", Abc_ObjFaninGetInitPrintable(pNode,1) ); + fprintf( pFile, ", label = \"%s\"", Seq_ObjFaninGetInitPrintable(pNode,1) ); fprintf( pFile, "]" ); fprintf( pFile, ";\n" ); } diff --git a/src/base/io/ioWriteList.c b/src/base/io/ioWriteList.c new file mode 100644 index 00000000..fefe9b0e --- /dev/null +++ b/src/base/io/ioWriteList.c @@ -0,0 +1,212 @@ +/**CFile**************************************************************** + + FileName [ioWriteList.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Command processing package.] + + Synopsis [Procedures to write the graph structure of sequential AIG.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: ioWriteList.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "io.h" + +/* +-------- Original Message -------- +Subject: Re: abc release and retiming +Date: Sun, 13 Nov 2005 20:31:18 -0500 (EST) +From: Luca Carloni <luca@cs.columbia.edu> +To: Alan Mishchenko <alanmi@eecs.berkeley.edu> + +Alan, + +My graph-representation file format is based on an adjacency list +representation and is indeed quite simple, in fact maybe too simple... I +used it in order to reason on relatively small weighed direct graphs. I +simply list all vertices, one per line and for each vertex "V_source" I +list all vertices that are "sinks" with respect to it, i.e. such that +there is a distinct arc between "V_source" and each of them (in +paranthesis I list the name of the edge and its weight (number of latency +on that path). For instance, if you look at the following graph, you have +that vertex "v_5" is connected to vertex "v_6" through a directed arc +called "v_5_to_v_6" whose latency is equal to 3, i.e. there are three +flip-flops on this arc. Still, notice that I sometime interpret the graph +also as the representation of a LIS where each node corresponds to a +shell encapsulating a sequential core module (i.e. a module which does not +contain any combinational path between its inputs and its outputs). With +this representation an arc of latency 3 is interpreted as a wire where two +relay stations have been inserted in addition to the flip-flop terminating +the output of the core module. + +Finally, notice that the name of the arc does not necessarily have to be +"v_5_to_v_6", but it could have been something like "arc_222" or "xyz" as +long as it is a unique name in the graph. + +Thanks, +Luca + +Example of graph representation +----------------------------------------------------------------------------- +v_5 > v_6 ([v_5_to_v_6] = 3), v_12 ([v_5_to_v_12] = 2). +v_2 > v_4 ([v_2_to_v_4] = 1), v_10_s0 ([v_2_to_v_10_s0] = 6), v_12 ([v_2_to_v_12] = 3). +v_9 > v_10_s0 ([v_9_to_v_10_s0] = 5), v_12 ([v_9_to_v_12] = 2). +v_12 > v_13 ([v_12_to_v_13] = 5). +v_13 > v_14 ([v_13_to_v_14] = 1). +v_6 > v_7 ([v_6_to_v_7] = 2). +v_4 > v_5 ([v_4_to_v_5] = 2). +v_1 > v_2 ([v_1_to_v_2] = 1). +v_7 > v_8 ([v_7_to_v_8] = 2). +t > . +v_14 > t ([v_14_to_t] = 1), v_5 ([v_14_to_v_5] = 1). +v_8 > v_9 ([v_8_to_v_9] = 2). +s > v_1 ([s_to_v_1] = 1). +v_10_s0 > v_10_s1 ([v_10_s0_to_v_10_s1] = 1). +v_10_s1 > v_4 ([v_10_s1__v_4] = 1), v_8 ([v_10_s1__v_8] = 1). +----------------------------------------------------------------------------- +*/ + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Io_WriteListEdge( FILE * pFile, Abc_Obj_t * pObj ); +static void Io_WriteListHost( FILE * pFile, Abc_Ntk_t * pNtk ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Writes the adjacency list for a sequential AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost ) +{ + FILE * pFile; + Abc_Obj_t * pObj; + int i; + + assert( Abc_NtkIsSeq(pNtk) ); + + // start the output stream + pFile = fopen( pFileName, "w" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Io_WriteList(): Cannot open the output file \"%s\".\n", pFileName ); + return; + } + + fprintf( pFile, "# Adjacency list for sequential AIG \"%s\"\n", pNtk->pName ); + 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) ); + + // write the PO edges + Abc_NtkForEachCi( pNtk, pObj, i ) + Io_WriteListEdge( pFile, pObj ); + + // write the internal nodes + Abc_AigForEachAnd( pNtk, pObj, i ) + Io_WriteListEdge( pFile, pObj ); + + // write the host node + if ( fUseHost ) + Io_WriteListHost( pFile, pNtk ); + else + Abc_NtkForEachCo( pNtk, pObj, i ) + Io_WriteListEdge( pFile, pObj ); + + fprintf( pFile, "\n" ); + fclose( pFile ); +} + +/**Function************************************************************* + + Synopsis [Writes the adjacency list for one edge in a sequential AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_WriteListEdge( FILE * pFile, Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFanout; + int i; + fprintf( pFile, "%-10s > ", Abc_ObjName(pObj) ); + Abc_ObjForEachFanout( pObj, pFanout, i ) + { + fprintf( pFile, " %s ([%s_to_%s] = %d)", Abc_ObjName(pFanout), Abc_ObjName(pObj), Abc_ObjName(pFanout), Abc_ObjFanoutL(pObj, pFanout) ); + if ( i == Abc_ObjFanoutNum(pObj) - 1 ) + fprintf( pFile, "." ); + else + fprintf( pFile, "," ); + } + fprintf( pFile, "\n" ); +} + +/**Function************************************************************* + + Synopsis [Writes the adjacency list for one edge in a sequential AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_WriteListHost( FILE * pFile, Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i; + + Abc_NtkForEachPo( pNtk, pObj, i ) + { + fprintf( pFile, "%-10s > ", Abc_ObjName(pObj) ); + fprintf( pFile, " %s ([%s_to_%s] = %d)", "HOST", Abc_ObjName(pObj), "HOST", 0 ); + if ( i == Abc_NtkPoNum(pNtk) - 1 ) + fprintf( pFile, "." ); + else + fprintf( pFile, "," ); + } + fprintf( pFile, "\n" ); + + fprintf( pFile, "%-10s > ", "HOST" ); + Abc_NtkForEachPi( pNtk, pObj, i ) + { + fprintf( pFile, " %s ([%s_to_%s] = %d)", Abc_ObjName(pObj), "HOST", Abc_ObjName(pObj), 0 ); + if ( i == Abc_NtkPiNum(pNtk) - 1 ) + fprintf( pFile, "." ); + else + fprintf( pFile, "," ); + } + fprintf( pFile, "\n" ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/io/module.make b/src/base/io/module.make index 9938af12..21579266 100644 --- a/src/base/io/module.make +++ b/src/base/io/module.make @@ -15,4 +15,5 @@ SRC += src/base/io/io.c \ src/base/io/ioWriteDot.c \ src/base/io/ioWriteEqn.c \ src/base/io/ioWriteGml.c \ + src/base/io/ioWriteList.c \ src/base/io/ioWritePla.c diff --git a/src/base/main/libSupport.c b/src/base/main/libSupport.c index 51c137cf..feb7a47e 100644 --- a/src/base/main/libSupport.c +++ b/src/base/main/libSupport.c @@ -40,7 +40,7 @@ void open_libs() { int curr_lib = 0; #ifdef WIN32 - printf("Warning: open_libs WIN32 not implemented.\n"); +// printf("Warning: open_libs WIN32 not implemented.\n"); #else DIR* dirp; struct dirent* dp; diff --git a/src/base/main/main.c b/src/base/main/main.c index a7506db0..561dc3b6 100644 --- a/src/base/main/main.c +++ b/src/base/main/main.c @@ -21,7 +21,7 @@ #include "mainInt.h" // this line should be included in the library project -//#define _LIB +#define _LIB //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -261,7 +261,7 @@ void Abc_Start() pAbc = Abc_FrameGetGlobalFrame(); // source the resource file - Abc_UtilsSource( pAbc ); +// Abc_UtilsSource( pAbc ); } /**Function************************************************************* diff --git a/src/base/seq/module.make b/src/base/seq/module.make new file mode 100644 index 00000000..2bb176dc --- /dev/null +++ b/src/base/seq/module.make @@ -0,0 +1,11 @@ +SRC += src/base/seq/seqCreate.c \ + src/base/seq/seqFpgaCore.c \ + src/base/seq/seqFpgaIter.c \ + src/base/seq/seqLatch.c \ + src/base/seq/seqMan.c \ + src/base/seq/seqMapCore.c \ + src/base/seq/seqMapIter.c \ + src/base/seq/seqRetCore.c \ + src/base/seq/seqRetIter.c \ + src/base/seq/seqShare.c \ + src/base/seq/seqUtil.c diff --git a/src/base/seq/seq.h b/src/base/seq/seq.h new file mode 100644 index 00000000..8e0d9c09 --- /dev/null +++ b/src/base/seq/seq.h @@ -0,0 +1,74 @@ +/**CFile**************************************************************** + + FileName [seq.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Construction and manipulation of sequential AIGs.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: seq.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __SEQ_H__ +#define __SEQ_H__ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Abc_Seq_t_ Abc_Seq_t; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== seqLatch.c ===============================================================*/ +extern void Seq_NodeDupLats( Abc_Obj_t * pObjNew, Abc_Obj_t * pObj, int Edge ); +/*=== seqMan.c ===============================================================*/ +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 ); +/*=== abcSeq.c ===============================================================*/ +extern Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk ); +extern Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk ); +/*=== seqShare.c =============================================================*/ +extern void Seq_NtkSeqShareFanouts( Abc_Ntk_t * pNtk ); +/*=== seqRetCore.c ===========================================================*/ +extern void Seq_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk, int fInitial, int fVerbose ); +extern void Seq_NtkSeqRetimeForward( Abc_Ntk_t * pNtk, int fInitial, int fVerbose ); +extern void Seq_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk, int fInitial, int fVerbose ); +/*=== seqUtil.c ==============================================================*/ +extern char * Seq_ObjFaninGetInitPrintable( Abc_Obj_t * pObj, int Edge ); +extern void Seq_NtkLatchSetValues( Abc_Ntk_t * pNtk, Abc_InitType_t Init ); +extern int Seq_NtkLatchNum( Abc_Ntk_t * pNtk ); +extern int Seq_NtkLatchNumMax( Abc_Ntk_t * pNtk ); +extern int Seq_NtkLatchNumShared( Abc_Ntk_t * pNtk ); +extern void Seq_NtkLatchGetInitNums( Abc_Ntk_t * pNtk, int * pInits ); + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/src/base/abcs/abcSeq.c b/src/base/seq/seqCreate.c index 8e701c09..4c66576b 100644 --- a/src/base/abcs/abcSeq.c +++ b/src/base/seq/seqCreate.c @@ -1,12 +1,12 @@ /**CFile**************************************************************** - FileName [abcSeq.c] + FileName [seqCreate.c] SystemName [ABC: Logic synthesis and verification system.] - PackageName [Network and node package.] + PackageName [Construction and manipulation of sequential AIGs.] - Synopsis [Procedures to derive sequential AIG from combinational AIG with latches.] + Synopsis [] Author [Alan Mishchenko] @@ -14,11 +14,11 @@ Date [Ver. 1.0. Started - June 20, 2005.] - Revision [$Id: abcSeq.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + Revision [$Id: seqCreate.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ -#include "abcs.h" +#include "seqInt.h" /* A sequential network is similar to AIG in that it contains only @@ -33,29 +33,29 @@ - The attributes contain information about the number of latches and their initial states. - The number of latches is stored directly on the edges. The initial - states are stored in a special array associated with the network. + states are stored in the sequential AIG manager. - The AIG of sequential network is static in the sense that the - new AIG nodes are never created. + In the current version of the code, the sequential AIG is static + in the sense that the new AIG nodes are never created. The retiming (or retiming/mapping) is performed by moving the latches over the static nodes of the AIG. - The new initial state after forward retiming is computed in a - straight-forward manner. After backward retiming it is computed - by setting up a SAT problem. + The new initial state after backward retiming is computed + by setting up and solving a SAT problem. */ //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static Vec_Ptr_t * Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk ); -static Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pAnd, int Num, int * pnLatches, unsigned * pnInit ); -static Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, int nLatches, unsigned Init ); +static Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObjNew, Abc_Obj_t * pObj, int Edge, Vec_Int_t * vInitValues ); +static void Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk ); +static Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, Seq_Lat_t * pRing, int nLatches ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// + /**Function************************************************************* Synopsis [Converts combinational AIG with latches into sequential AIG.] @@ -72,88 +72,96 @@ static Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkNew; - Vec_Ptr_t * vNodes; Abc_Obj_t * pObj, * pFaninNew; - unsigned Init; - int i, nLatches; + Vec_Int_t * vInitValues; + Abc_InitType_t Init; + int i, k; + // make sure it is an AIG without self-feeding latches assert( Abc_NtkIsStrash(pNtk) ); assert( Abc_NtkCountSelfFeedLatches(pNtk) == 0 ); + assert( Abc_NtkIsDfsOrdered(pNtk) ); + // start the network - Abc_NtkCleanCopy( pNtk ); pNtkNew = Abc_NtkAlloc( ABC_NTK_SEQ, ABC_FUNC_AIG ); // duplicate the name and the spec pNtkNew->pName = util_strsav(pNtk->pName); pNtkNew->pSpec = util_strsav(pNtk->pSpec); - // clone const/PIs/POs - Abc_NtkDupObj(pNtkNew, Abc_AigConst1(pNtk->pManFunc) ); - pNtkNew->nNodes -= 1; - Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_NtkDupObj(pNtkNew, pObj); - Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_NtkDupObj(pNtkNew, pObj); -// Abc_NtkForEachLatch( pNtk, pObj, i ) -// Vec_PtrPush( pNtkNew->vObjs, NULL ); - // copy the PI/PO names + + // map the constant nodes + Abc_NtkCleanCopy( pNtk ); + Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(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 ); + Abc_NtkForEachObj( pNtk, pObj, i ) + { + if ( i == 0 || Abc_ObjIsLatch(pObj) ) + continue; + pObj->pCopy = Abc_ObjAlloc( pNtkNew, pObj->Type ); + pObj->pCopy->Id = pObj->Id; + pObj->pCopy->fPhase = pObj->fPhase; + pObj->pCopy->Level = pObj->Level; + Vec_PtrWriteEntry( pNtkNew->vObjs, pObj->pCopy->Id, pObj->pCopy ); + pNtkNew->nObjs++; + } + pNtkNew->nNodes = pNtk->nNodes; + pNtkNew->nPis = pNtk->nPis; + pNtkNew->nPos = pNtk->nPos; + + // create PI/PO and their names Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(pObj) ); + { + Vec_PtrPush( pNtkNew->vCis, pObj->pCopy ); + Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) ); + } Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_NtkLogicStoreName( Abc_NtkPo(pNtkNew,i), Abc_ObjName(pObj) ); - // copy the internal nodes, including choices, excluding dangling - vNodes = Abc_AigDfs( pNtk, 0, 0 ); - Vec_PtrForEachEntry( vNodes, pObj, i ) { - if ( Abc_ObjFaninNum(pObj) != 2 ) - continue; - Abc_NtkDupObj(pNtkNew, pObj); -// assert( pObj->Id == pObj->pCopy->Id ); - pObj->pCopy->fPhase = pObj->fPhase; // needed for choices - pObj->pCopy->Level = pObj->Level; + Vec_PtrPush( pNtkNew->vCos, pObj->pCopy ); + Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) ); } + // relink the choice nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) + Abc_AigForEachAnd( pNtk, pObj, i ) if ( pObj->pData ) pObj->pCopy->pData = ((Abc_Obj_t *)pObj->pData)->pCopy; - Vec_PtrFree( vNodes ); + // start the storage for initial states - pNtkNew->vInits = Vec_IntStart( 2 * Abc_NtkObjNumMax(pNtkNew) ); + Seq_Resize( pNtkNew->pManFunc, Abc_NtkObjNumMax(pNtkNew) ); // reconnect the internal nodes + vInitValues = Vec_IntAlloc( 100 ); Abc_NtkForEachObj( pNtk, pObj, i ) { - // skip the constant and the PIs - if ( Abc_ObjFaninNum(pObj) == 0 ) - continue; - if ( Abc_ObjIsLatch(pObj) ) + // skip constants, PIs, and latches + if ( Abc_ObjFaninNum(pObj) == 0 || Abc_ObjIsLatch(pObj) ) continue; // process the first fanin - pFaninNew = Abc_NodeAigToSeq( pObj, 0, &nLatches, &Init ); - if ( nLatches > ABC_MAX_EDGE_LATCH ) - { - printf( "The number of latches on an edge (%d) exceeds the limit (%d).\n", nLatches, ABC_MAX_EDGE_LATCH ); - nLatches = ABC_MAX_EDGE_LATCH; - } + Vec_IntClear( vInitValues ); + pFaninNew = Abc_NodeAigToSeq( pObj->pCopy, pObj, 0, vInitValues ); Abc_ObjAddFanin( pObj->pCopy, pFaninNew ); - Abc_ObjAddFaninL0( pObj->pCopy, nLatches ); - Vec_IntWriteEntry( pNtkNew->vInits, 2 * pObj->pCopy->Id + 0, Init ); + // store the initial values + Vec_IntForEachEntry( vInitValues, Init, k ) + Seq_NodeInsertFirst( pObj->pCopy, 0, Init ); + // skip single-input nodes if ( Abc_ObjFaninNum(pObj) == 1 ) continue; // process the second fanin - pFaninNew = Abc_NodeAigToSeq( pObj, 1, &nLatches, &Init ); - if ( nLatches > ABC_MAX_EDGE_LATCH ) - { - printf( "The number of latches on an edge (%d) exceeds the limit (%d).\n", nLatches, ABC_MAX_EDGE_LATCH ); - nLatches = ABC_MAX_EDGE_LATCH; - } + Vec_IntClear( vInitValues ); + pFaninNew = Abc_NodeAigToSeq( pObj->pCopy, pObj, 1, vInitValues ); Abc_ObjAddFanin( pObj->pCopy, pFaninNew ); - Abc_ObjAddFaninL1( pObj->pCopy, nLatches ); - Vec_IntWriteEntry( pNtkNew->vInits, 2 * pObj->pCopy->Id + 1, Init ); + // store the initial values + Vec_IntForEachEntry( vInitValues, Init, k ) + Seq_NodeInsertFirst( pObj->pCopy, 1, Init ); } + Vec_IntFree( vInitValues ); + // set the cutset composed of latch drivers - Vec_PtrFree( pNtkNew->vLats ); - pNtkNew->vLats = Abc_NtkAigCutsetCopy( pNtk ); + Abc_NtkAigCutsetCopy( pNtk ); + // copy EXDC and check correctness if ( pNtkNew->pExdc ) - fprintf( stdout, "Warning: EXDC is dropped when converting to sequential AIG.\n" ); + fprintf( stdout, "Warning: EXDC is not copied when converting to sequential AIG.\n" ); if ( !Abc_NtkCheck( pNtkNew ) ) fprintf( stdout, "Abc_NtkAigToSeq(): Network check has failed.\n" ); return pNtkNew; @@ -161,35 +169,6 @@ Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk ) /**Function************************************************************* - Synopsis [Collects the cut set nodes.] - - Description [These are internal AND gates that fanins into latches.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pLatch, * pDriver; - int i; - vNodes = Vec_PtrAlloc( Abc_NtkLatchNum(pNtk) ); - Abc_NtkIncrementTravId(pNtk); - Abc_NtkForEachLatch( pNtk, pLatch, i ) - { - pDriver = Abc_ObjFanin0(pLatch); - if ( Abc_NodeIsTravIdCurrent(pDriver) || !Abc_NodeIsAigAnd(pDriver) ) - continue; - Abc_NodeSetTravIdCurrent(pDriver); - Vec_PtrPush( vNodes, pDriver->pCopy ); - } - return vNodes; -} - -/**Function************************************************************* - Synopsis [Determines the fanin that is transparent for latches.] Description [] @@ -199,22 +178,18 @@ Vec_Ptr_t * Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObj, int Num, int * pnLatches, unsigned * pnInit ) +Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObjNew, Abc_Obj_t * pObj, int Edge, Vec_Int_t * vInitValues ) { Abc_Obj_t * pFanin, * pFaninNew; Abc_InitType_t Init; // get the given fanin of the node - pFanin = Abc_ObjFanin( pObj, Num ); + pFanin = Abc_ObjFanin( pObj, Edge ); // if fanin is the internal node, return its copy in the corresponding polarity if ( !Abc_ObjIsLatch(pFanin) ) - { - *pnLatches = 0; - *pnInit = 0; - return Abc_ObjNotCond( pFanin->pCopy, Abc_ObjFaninC(pObj, Num) ); - } + return Abc_ObjNotCond( pFanin->pCopy, Abc_ObjFaninC(pObj, Edge) ); // fanin is a latch // get the new fanins - pFaninNew = Abc_NodeAigToSeq( pFanin, 0, pnLatches, pnInit ); + pFaninNew = Abc_NodeAigToSeq( pObjNew, pFanin, 0, vInitValues ); // get the initial state Init = Abc_LatchInit(pFanin); // complement the initial state if the inv is retimed over the latch @@ -227,13 +202,37 @@ Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObj, int Num, int * pnLatches, unsign else if ( Init != ABC_INIT_DC ) assert( 0 ); } - // update the latch number and initial state - (*pnLatches)++; - (*pnInit) = ((*pnInit) << 2) | Init; - return Abc_ObjNotCond( pFaninNew, Abc_ObjFaninC(pObj, Num) ); + // record the initial state + Vec_IntPush( vInitValues, Init ); + return Abc_ObjNotCond( pFaninNew, Abc_ObjFaninC(pObj, Edge) ); } +/**Function************************************************************* + Synopsis [Collects the cut set nodes.] + + Description [These are internal AND gates that have latch fanouts.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkAigCutsetCopy( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pLatch, * pDriver, * pDriverNew; + int i; + Abc_NtkIncrementTravId(pNtk); + Abc_NtkForEachLatch( pNtk, pLatch, i ) + { + pDriver = Abc_ObjFanin0(pLatch); + if ( Abc_NodeIsTravIdCurrent(pDriver) || !Abc_NodeIsAigAnd(pDriver) ) + continue; + Abc_NodeSetTravIdCurrent(pDriver); + pDriverNew = pDriver->pCopy; + Vec_PtrPush( pDriverNew->pNtk->vCutSet, pDriverNew ); + } +} /**Function************************************************************* @@ -250,23 +249,12 @@ Abc_Obj_t * Abc_NodeAigToSeq( Abc_Obj_t * pObj, int Num, int * pnLatches, unsign Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pObjNew, * pFaninNew, * pConst1; - int i, nCutNodes; - unsigned Init; - int nLatchMax = 0; + Abc_Obj_t * pObj, * pObjNew, * pFaninNew; + int i; assert( Abc_NtkIsSeq(pNtk) ); // start the network without latches - nCutNodes = pNtk->vLats->nSize; pNtk->vLats->nSize = 0; pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); - pNtk->vLats->nSize = nCutNodes; - // create the constant node -// Abc_NtkDupConst1( pNtk, pNtkNew ); - pConst1 = Abc_NtkObj(pNtk,0); - if ( !Abc_ObjIsNode(pConst1) ) - pConst1 = NULL; - if ( pConst1 && Abc_ObjFanoutNum(pConst1) > 0 ) - pConst1->pCopy = Abc_NodeCreateConst1( pNtkNew ); // duplicate the nodes, create node functions Abc_NtkForEachNode( pNtk, pObj, i ) @@ -291,12 +279,8 @@ Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk ) // skip PIs and the constant if ( Abc_ObjFaninNum(pObj) == 0 ) continue; - if ( nLatchMax < Abc_ObjFaninL0(pObj) ) - nLatchMax = Abc_ObjFaninL0(pObj); - // get the initial states of the latches on the fanin edge of this node - Init = Vec_IntEntry( pNtk->vInits, 2 * pObj->Id ); // create the edge - pFaninNew = Abc_NodeSeqToLogic( pNtkNew, Abc_ObjFanin0(pObj), Abc_ObjFaninL0(pObj), Init ); + pFaninNew = Abc_NodeSeqToLogic( pNtkNew, Abc_ObjFanin0(pObj), Seq_NodeGetRing(pObj,0), Abc_ObjFaninL0(pObj) ); Abc_ObjAddFanin( pObj->pCopy, pFaninNew ); if ( Abc_ObjFaninNum(pObj) == 1 ) { @@ -305,16 +289,11 @@ Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk ) Abc_ObjSetFaninC( pObj->pCopy, 0 ); continue; } - if ( nLatchMax < Abc_ObjFaninL0(pObj) ) - nLatchMax = Abc_ObjFaninL0(pObj); - // get the initial states of the latches on the fanin edge of this node - Init = Vec_IntEntry( pNtk->vInits, 2 * pObj->Id + 1 ); // create the edge - pFaninNew = Abc_NodeSeqToLogic( pNtkNew, Abc_ObjFanin1(pObj), Abc_ObjFaninL1(pObj), Init ); + pFaninNew = Abc_NodeSeqToLogic( pNtkNew, Abc_ObjFanin1(pObj), Seq_NodeGetRing(pObj,1), Abc_ObjFaninL1(pObj) ); Abc_ObjAddFanin( pObj->pCopy, pFaninNew ); // the complemented edges are subsumed by the node function } -// printf( "The max edge latch num = %d.\n", nLatchMax ); // add the latches and their names Abc_NtkAddDummyLatchNames( pNtkNew ); Abc_NtkForEachLatch( pNtkNew, pObjNew, i ) @@ -328,7 +307,7 @@ Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk ) fprintf( stdout, "Abc_NtkSeqToLogicSop(): Network check has failed.\n" ); return pNtkNew; } - + /**Function************************************************************* @@ -341,7 +320,7 @@ Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, int nLatches, unsigned Init ) +Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, Seq_Lat_t * pRing, int nLatches ) { Abc_Obj_t * pLatch; if ( nLatches == 0 ) @@ -349,15 +328,13 @@ Abc_Obj_t * Abc_NodeSeqToLogic( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pFanin, int nLa assert( pFanin->pCopy ); return pFanin->pCopy; } - pFanin = Abc_NodeSeqToLogic( pNtkNew, pFanin, nLatches - 1, Init >> 2 ); + pFanin = Abc_NodeSeqToLogic( pNtkNew, pFanin, Seq_LatNext(pRing), nLatches - 1 ); pLatch = Abc_NtkCreateLatch( pNtkNew ); - pLatch->pData = (void *)(Init & 3); + pLatch->pData = (void *)Seq_LatInit( pRing ); Abc_ObjAddFanin( pLatch, pFanin ); return pLatch; } - - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/seq/seqFpgaCore.c b/src/base/seq/seqFpgaCore.c new file mode 100644 index 00000000..37ef6cb7 --- /dev/null +++ b/src/base/seq/seqFpgaCore.c @@ -0,0 +1,170 @@ +/**CFile**************************************************************** + + FileName [seqFpgaCore.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Construction and manipulation of sequential AIGs.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: seqFpgaCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "seqInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static Abc_Ntk_t * Seq_NtkSeqFpgaDup( Abc_Ntk_t * pNtk ); +static Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs FPGA mapping and retiming.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Seq_NtkSeqFpgaRetime( Abc_Ntk_t * pNtk, int fVerbose ) +{ + Abc_Seq_t * p; + Abc_Ntk_t * pNtkNew; + Abc_Ntk_t * pNtkMap; + int RetValue; + // find the best mapping and retiming (p->vMapping, p->vLags) + Seq_NtkSeqFpgaMapping( pNtk, fVerbose ); + // duplicate the nodes contained in multiple cuts + pNtkNew = Seq_NtkSeqFpgaDup( pNtk ); + // implement this retiming + p = pNtkNew->pManFunc; + RetValue = Seq_NtkImplementRetiming( pNtkNew, p->vLags, fVerbose ); + if ( RetValue == 0 ) + printf( "Retiming completed but initial state computation has failed.\n" ); + // create the final mapped network + pNtkMap = Seq_NtkSeqFpgaMapped( pNtkNew, pNtk ); + Abc_NtkDelete( pNtkNew ); + return pNtkMap; +} + +/**Function************************************************************* + + Synopsis [Derives the network by duplicating some of the nodes.] + + Description [Information about mapping is given as + (1) array of mapping nodes (p->vMapAnds), + (2) array of best cuts for each node (p->vMapCuts), + (3) array of nodes subsumed by each cut (p->vMapBags), + (4) array of lags of each node in the cut (p->vMapLags).] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Seq_NtkSeqFpgaDup( Abc_Ntk_t * pNtk ) +{ + Abc_Seq_t * p = pNtk->pManFunc; + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObj, * pLeaf, * pNode, * pDriver, * pDriverNew; + Vec_Ptr_t * vLeaves, * vInside, * vLags; + int i, k, TotalLag; + + assert( Abc_NtkIsSeq(pNtk) ); + + // start the network + pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc ); + + // set the next pointers + Abc_NtkForEachPi( pNtk, pObj, i ) + pObj->pNext = pObj->pCopy; + Abc_NtkForEachNode( pNtk, pObj, i ) + pObj->pNext = NULL; + + // start the new sequential AIG manager + Seq_Resize( pNtkNew->pManFunc, 10 + Abc_NtkPiNum(pNtk) + Abc_NtkPoNum(pNtk) + Vec_VecSizeSize(p->vMapBags) ); + + // create the nodes + Vec_PtrForEachEntry( p->vMapAnds, pObj, i ) + { + // make sure the leaves are assigned + vLeaves = Vec_VecEntry( p->vMapCuts, i ); + Vec_PtrForEachEntry( vLeaves, pLeaf, k ) + { + assert( pLeaf->pNext ); + pLeaf->pCopy = pLeaf->pNext; + } + // recursively construct the internals + vInside = Vec_VecEntry( p->vMapBags, i ); + vLags = Vec_VecEntry( p->vMapLags, i ); + Vec_PtrForEachEntry( vInside, pNode, k ) + { + Abc_NtkDupObj( pNtkNew, pNode ); + Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild0Copy(pNode) ); + Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild1Copy(pNode) ); + Abc_ObjSetFaninL( pNode->pCopy, 0, Abc_ObjFaninL(pNode, 0) ); + Abc_ObjSetFaninL( pNode->pCopy, 1, Abc_ObjFaninL(pNode, 1) ); + Seq_NodeDupLats( pNode->pCopy, pNode, 0 ); + Seq_NodeDupLats( pNode->pCopy, pNode, 1 ); + // set the lag of the new node + TotalLag = Seq_NodeGetLag(pObj) + (char)Vec_PtrEntry(vLags, k); + Seq_NodeSetLag( pNode->pCopy, (char)TotalLag ); + } + // set the copy of the last node + pObj->pNext = pObj->pCopy; + } + + // set the POs + Abc_NtkForEachPo( pNtk, pObj, i ) + { + pDriver = Abc_ObjFanin0(pObj); + pDriverNew = Abc_ObjNotCond(pDriver->pNext, Abc_ObjFaninC0(pObj)); + Abc_ObjAddFanin( pObj->pCopy, pDriverNew ); + } + + if ( !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Seq_NtkSeqFpgaDup(): Network check has failed.\n" ); + return pNtkNew; +} + +/**Function************************************************************* + + Synopsis [Derives the final mapped network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk ) +{ + Abc_Ntk_t * pNtkMap; + pNtkMap = NULL; + if ( !Abc_NtkCheck( pNtkMap ) ) + fprintf( stdout, "Seq_NtkSeqFpgaMapped(): Network check has failed.\n" ); + return pNtkMap; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/seq/seqFpgaIter.c b/src/base/seq/seqFpgaIter.c new file mode 100644 index 00000000..cb0c739b --- /dev/null +++ b/src/base/seq/seqFpgaIter.c @@ -0,0 +1,50 @@ +/**CFile**************************************************************** + + FileName [seqFpgaIter.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Construction and manipulation of sequential AIGs.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: seqFpgaIter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "seqInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_NtkSeqFpgaMapping( Abc_Ntk_t * pNtk, int fVerbose ) +{ +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/seq/seqInt.h b/src/base/seq/seqInt.h new file mode 100644 index 00000000..2159480a --- /dev/null +++ b/src/base/seq/seqInt.h @@ -0,0 +1,167 @@ +/**CFile**************************************************************** + + FileName [seqInt.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Construction and manipulation of sequential AIGs.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: seqInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __SEQ_INT_H__ +#define __SEQ_INT_H__ + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include "abc.h" +#include "seq.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +#define SEQ_FULL_MASK 0xFFFFFFFF + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +// manager of sequential AIG +struct Abc_Seq_t_ +{ + Abc_Ntk_t * pNtk; // the network + int nSize; // the number of entries in all internal arrays + Vec_Ptr_t * vInits; // the initial states for each edge in the AIG + Extra_MmFixed_t * pMmInits; // memory manager for latch structures used to remember init states + int fVerbose; // the verbose flag + // the arrival times + Vec_Int_t * vLValues; // the arrival times (L-Values of nodes) + Vec_Ptr_t * vBestCuts; // the best cuts for nodes + Vec_Str_t * vLags; // the lags of the mapped nodes + // representation of the mapping + Vec_Ptr_t * vMapAnds; // nodes visible in the mapping + Vec_Vec_t * vMapCuts; // best cuts for each node + Vec_Vec_t * vMapBags; // nodes subsumed by each cut + Vec_Vec_t * vMapLags; // the internal lags of each node in the bag + // runtime stats + int timeCuts; // runtime to compute the cuts + int timeDelay; // runtime to compute the L-values + int timeRet; // runtime to retime the resulting network + int timeNtk; // runtime to create the final network + +}; + +// data structure to store initial state +typedef struct Seq_Lat_t_ Seq_Lat_t; +struct Seq_Lat_t_ +{ + Seq_Lat_t * pNext; // the next Lat in the ring + Seq_Lat_t * pPrev; // the prev Lat in the ring +}; + +// representation of latch on the edge +typedef struct Seq_RetEdge_t_ Seq_RetEdge_t; +struct Seq_RetEdge_t_ // 1 word +{ + unsigned iNode : 24; // the ID of the node + unsigned iEdge : 1; // the edge of the node + unsigned iLatch : 7; // the latch number counting from the node +}; + +// representation of one retiming step +typedef struct Seq_RetStep_t_ Seq_RetStep_t; +struct Seq_RetStep_t_ // 1 word +{ + unsigned iNode : 24; // the ID of the node + unsigned nLatches : 8; // the number of latches to retime +}; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +// transforming retedges into ints and back +static inline int Seq_RetEdge2Int( Seq_RetEdge_t Val ) { return *((int *)&Val); } +static inline Seq_RetEdge_t Seq_Int2RetEdge( int Num ) { return *((Seq_RetEdge_t *)&Num); } +// transforming retsteps into ints and back +static inline int Seq_RetStep2Int( Seq_RetStep_t Val ) { return *((int *)&Val); } +static inline Seq_RetStep_t Seq_Int2RetStep( int Num ) { return *((Seq_RetStep_t *)&Num); } + +// storing arrival times in the nodes +static inline Vec_Int_t * Seq_NodeLValues( Abc_Obj_t * pNode ) { return ((Abc_Seq_t *)(pNode)->pNtk->pManFunc)->vLValues; } +static inline int Seq_NodeGetLValue( Abc_Obj_t * pNode ) { return Vec_IntEntry( Seq_NodeLValues(pNode), (pNode)->Id ); } +static inline void Seq_NodeSetLValue( Abc_Obj_t * pNode, int Value ) { Vec_IntWriteEntry( Seq_NodeLValues(pNode), (pNode)->Id, (Value) ); } +static inline int Seq_NodeComputeLag( int LValue, int Fi ) { return (LValue + 1024*Fi)/Fi - 1024 - (int)(LValue % Fi == 0); } + +// reading the contents of the lat +static inline Abc_InitType_t Seq_LatInit( Seq_Lat_t * pLat ) { return ((unsigned)pLat->pPrev) & 3; } +static inline Seq_Lat_t * Seq_LatNext( Seq_Lat_t * pLat ) { return pLat->pNext; } +static inline Seq_Lat_t * Seq_LatPrev( Seq_Lat_t * pLat ) { return (void *)(((unsigned)pLat->pPrev) & (SEQ_FULL_MASK << 2)); } + +// setting the contents of the lat +static inline void Seq_LatSetInit( Seq_Lat_t * pLat, Abc_InitType_t Init ) { pLat->pPrev = (void *)( (3 & Init) | (((unsigned)pLat->pPrev) & (SEQ_FULL_MASK << 2)) ); } +static inline void Seq_LatSetNext( Seq_Lat_t * pLat, Seq_Lat_t * pNext ) { pLat->pNext = pNext; } +static inline void Seq_LatSetPrev( Seq_Lat_t * pLat, Seq_Lat_t * pPrev ) { Abc_InitType_t Init = Seq_LatInit(pLat); pLat->pPrev = pPrev; Seq_LatSetInit(pLat, Init); } + +// accessing retiming lags +static inline Vec_Str_t * Seq_NodeLags( Abc_Obj_t * pNode ) { return ((Abc_Seq_t *)(pNode)->pNtk->pManFunc)->vLags; } +static inline char Seq_NodeGetLag( Abc_Obj_t * pNode ) { return Vec_StrEntry( Seq_NodeLags(pNode), (pNode)->Id ); } +static inline void Seq_NodeSetLag( Abc_Obj_t * pNode, char Value ) { Vec_StrWriteEntry( Seq_NodeLags(pNode), (pNode)->Id, (Value) ); } + +// accessing initial states +static inline Vec_Ptr_t * Seq_NodeLats( Abc_Obj_t * pObj ) { return ((Abc_Seq_t*)pObj->pNtk->pManFunc)->vInits; } +static inline Seq_Lat_t * Seq_NodeGetRing( Abc_Obj_t * pObj, int Edge ) { return Vec_PtrEntry( Seq_NodeLats(pObj), (pObj->Id<<1)+Edge ); } +static inline void Seq_NodeSetRing( Abc_Obj_t * pObj, int Edge, Seq_Lat_t * pLat ) { Vec_PtrWriteEntry( Seq_NodeLats(pObj), (pObj->Id<<1)+Edge, pLat ); } +static inline Seq_Lat_t * Seq_NodeCreateLat( Abc_Obj_t * pObj ) { return (Seq_Lat_t *)Extra_MmFixedEntryFetch( ((Abc_Seq_t*)pObj->pNtk->pManFunc)->pMmInits ); } +static inline void Seq_NodeRecycleLat( Abc_Obj_t * pObj, Seq_Lat_t * pLat ) { Extra_MmFixedEntryRecycle( ((Abc_Seq_t*)pObj->pNtk->pManFunc)->pMmInits, (char *)pLat ); } + +// getting hold of the structure storing initial states of the latches +static inline Seq_Lat_t * Seq_NodeGetLatFirst( Abc_Obj_t * pObj, int Edge ) { return Seq_NodeGetRing(pObj, Edge); } +static inline Seq_Lat_t * Seq_NodeGetLatLast( Abc_Obj_t * pObj, int Edge ) { return Seq_LatPrev( Seq_NodeGetRing(pObj, Edge) ); } +static inline Seq_Lat_t * Seq_NodeGetLat( Abc_Obj_t * pObj, int Edge, int iLat ) { int c; Seq_Lat_t * pLat = Seq_NodeGetRing(pObj, Edge); for ( c = 0; c != iLat; c++ ) pLat = pLat->pNext; return pLat; } +static inline int Seq_NodeCountLats( Abc_Obj_t * pObj, int Edge ) { int c; Seq_Lat_t * pLat, * pRing = Seq_NodeGetRing(pObj, Edge); if ( pRing == NULL ) return 0; for ( c = 0, pLat = pRing; !c || pLat != pRing; c++ ) pLat = pLat->pNext; return c; } + +// getting/setting initial states of the latches +static inline Abc_InitType_t Seq_NodeGetInitOne( Abc_Obj_t * pObj, int Edge, int iLat ) { return Seq_LatInit( Seq_NodeGetLat(pObj, Edge, iLat) ); } +static inline Abc_InitType_t Seq_NodeGetInitFirst( Abc_Obj_t * pObj, int Edge ) { return Seq_LatInit( Seq_NodeGetLatFirst(pObj, Edge) ); } +static inline Abc_InitType_t Seq_NodeGetInitLast( Abc_Obj_t * pObj, int Edge ) { return Seq_LatInit( Seq_NodeGetLatLast(pObj, Edge) ); } +static inline void Seq_NodeSetInitOne( Abc_Obj_t * pObj, int Edge, int iLat, Abc_InitType_t Init ) { Seq_LatSetInit( Seq_NodeGetLat(pObj, Edge, iLat), Init ); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== seqLatch.c ===============================================================*/ +extern void Seq_NodeInsertFirst( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init ); +extern void Seq_NodeInsertLast( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init ); +extern Abc_InitType_t Seq_NodeDeleteFirst( Abc_Obj_t * pObj, int Edge ); +extern Abc_InitType_t Seq_NodeDeleteLast( Abc_Obj_t * pObj, int Edge ); +/*=== seqFpgaIter.c ============================================================*/ +extern void Seq_NtkSeqFpgaMapping( Abc_Ntk_t * pNtk, int fVerbose ); +/*=== seqRetIter.c =============================================================*/ +extern void Seq_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose ); +extern int Seq_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags, int fVerbose ); +/*=== seqUtil.c ================================================================*/ +extern int Seq_ObjFanoutLMax( Abc_Obj_t * pObj ); +extern int Seq_ObjFanoutLMin( Abc_Obj_t * pObj ); +extern int Seq_ObjFanoutLSum( Abc_Obj_t * pObj ); +extern int Seq_ObjFaninLSum( Abc_Obj_t * pObj ); + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/src/base/seq/seqLatch.c b/src/base/seq/seqLatch.c new file mode 100644 index 00000000..61a71fef --- /dev/null +++ b/src/base/seq/seqLatch.c @@ -0,0 +1,192 @@ +/**CFile**************************************************************** + + FileName [seqLatch.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Construction and manipulation of sequential AIGs.] + + Synopsis [Manipulation of latch data structures representing initial states.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: seqLatch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "seqInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Insert the first Lat on the edge.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_NodeInsertFirst( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init ) +{ + Seq_Lat_t * pLat, * pRing, * pPrev; + pRing = Seq_NodeGetRing( pObj, Edge ); + pLat = Seq_NodeCreateLat( pObj ); + if ( pRing == NULL ) + { + Seq_LatSetPrev( pLat, pLat ); + Seq_LatSetNext( pLat, pLat ); + Seq_NodeSetRing( pObj, Edge, pLat ); + } + else + { + pPrev = Seq_LatPrev( pRing ); + Seq_LatSetPrev( pLat, pPrev ); + Seq_LatSetNext( pPrev, pLat ); + Seq_LatSetPrev( pRing, pLat ); + Seq_LatSetNext( pLat, pRing ); + Seq_NodeSetRing( pObj, Edge, pLat ); // rotate the ring to make pLat the first + } + Seq_LatSetInit( pLat, Init ); + Abc_ObjAddFaninL( pObj, Edge, 1 ); +} + +/**Function************************************************************* + + Synopsis [Insert the last Lat on the edge.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_NodeInsertLast( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init ) +{ + Seq_Lat_t * pLat, * pRing, * pPrev; + pRing = Seq_NodeGetRing( pObj, Edge ); + pLat = Seq_NodeCreateLat( pObj ); + if ( pRing == NULL ) + { + Seq_LatSetPrev( pLat, pLat ); + Seq_LatSetNext( pLat, pLat ); + Seq_NodeSetRing( pObj, Edge, pLat ); + } + else + { + pPrev = Seq_LatPrev( pRing ); + Seq_LatSetPrev( pLat, pPrev ); + Seq_LatSetNext( pPrev, pLat ); + Seq_LatSetPrev( pRing, pLat ); + Seq_LatSetNext( pLat, pRing ); + } + Seq_LatSetInit( pLat, Init ); + Abc_ObjAddFaninL( pObj, Edge, 1 ); +} + +/**Function************************************************************* + + Synopsis [Delete the first Lat on the edge.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_InitType_t Seq_NodeDeleteFirst( Abc_Obj_t * pObj, int Edge ) +{ + Abc_InitType_t Init; + Seq_Lat_t * pLat, * pRing, * pPrev, * pNext; + pRing = Seq_NodeGetRing( pObj, Edge ); + pLat = pRing; // consider the first latch + if ( pLat->pNext == pLat ) + Seq_NodeSetRing( pObj, Edge, NULL ); + else + { + pPrev = Seq_LatPrev( pLat ); + pNext = Seq_LatNext( pLat ); + Seq_LatSetPrev( pNext, pPrev ); + Seq_LatSetNext( pPrev, pNext ); + Seq_NodeSetRing( pObj, Edge, pNext ); // rotate the ring + } + Init = Seq_LatInit( pLat ); + Seq_NodeRecycleLat( pObj, pLat ); + Abc_ObjAddFaninL( pObj, Edge, -1 ); + return Init; +} + +/**Function************************************************************* + + Synopsis [Delete the last Lat on the edge.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_InitType_t Seq_NodeDeleteLast( Abc_Obj_t * pObj, int Edge ) +{ + Abc_InitType_t Init; + Seq_Lat_t * pLat, * pRing, * pPrev, * pNext; + pRing = Seq_NodeGetRing( pObj, Edge ); + pLat = Seq_LatPrev( pRing ); // consider the last latch + if ( pLat->pNext == pLat ) + Seq_NodeSetRing( pObj, Edge, NULL ); + else + { + pPrev = Seq_LatPrev( pLat ); + pNext = Seq_LatNext( pLat ); + Seq_LatSetPrev( pNext, pPrev ); + Seq_LatSetNext( pPrev, pNext ); + } + Init = Seq_LatInit( pLat ); + Seq_NodeRecycleLat( pObj, pLat ); + Abc_ObjAddFaninL( pObj, Edge, -1 ); + return Init; +} + +/**Function************************************************************* + + Synopsis [Insert the last Lat on the edge.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_NodeDupLats( Abc_Obj_t * pObjNew, Abc_Obj_t * pObj, int Edge ) +{ + Seq_Lat_t * pRing, * pLat; + int i, nLatches; + pRing = Seq_NodeGetRing( pObj, Edge ); + if ( pRing == NULL ) + return; + nLatches = Seq_NodeCountLats( pObj, Edge ); + for ( i = 0, pLat = pRing; i < nLatches; i++, pLat = pLat->pNext ) + Seq_NodeInsertLast( pObjNew, Edge, Seq_LatInit(pLat) ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/seq/seqMan.c b/src/base/seq/seqMan.c new file mode 100644 index 00000000..95192ae2 --- /dev/null +++ b/src/base/seq/seqMan.c @@ -0,0 +1,110 @@ +/**CFile**************************************************************** + + FileName [seqMan.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Construction and manipulation of sequential AIGs.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: seqMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "seqInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Allocates sequential AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Seq_t * Seq_Create( Abc_Ntk_t * pNtk ) +{ + Abc_Seq_t * p; + // start the manager + p = ALLOC( Abc_Seq_t, 1 ); + memset( p, 0, sizeof(Abc_Seq_t) ); + p->pNtk = pNtk; + p->nSize = 1000; + // create internal data structures + p->vInits = Vec_PtrStart( 2 * p->nSize ); + p->pMmInits = Extra_MmFixedStart( sizeof(Seq_Lat_t) ); + p->vLValues = Vec_IntStart( p->nSize ); + p->vLags = Vec_StrStart( p->nSize ); + return p; +} + +/**Function************************************************************* + + Synopsis [Deallocates sequential AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_Resize( Abc_Seq_t * p, int nMaxId ) +{ + if ( p->nSize > nMaxId ) + return; + p->nSize = nMaxId + 1; + Vec_PtrFill( p->vInits, 2 * p->nSize, NULL ); + Vec_IntFill( p->vLValues, p->nSize, 0 ); + Vec_StrFill( p->vLags, p->nSize, 0 ); +} + + +/**Function************************************************************* + + Synopsis [Deallocates sequential AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_Delete( Abc_Seq_t * p ) +{ + if ( p->vMapAnds ) Vec_PtrFree( p->vMapAnds ); // the nodes used in the mapping + if ( p->vMapCuts ) Vec_VecFree( p->vMapCuts ); // the cuts used in the mapping + if ( p->vMapBags ) Vec_VecFree( p->vMapBags ); // the nodes included in the cuts used in the mapping + if ( p->vMapLags ) Vec_VecFree( p->vMapLags ); // the lags of the mapped nodes + + if ( p->vBestCuts ) Vec_PtrFree( p->vBestCuts ); // the best cuts for nodes + if ( p->vLValues ) Vec_IntFree( p->vLValues ); // the arrival times (L-Values of nodes) + if ( p->vLags ) Vec_StrFree( p->vLags ); // the lags of the mapped nodes + Vec_PtrFree( p->vInits ); + Extra_MmFixedStop( p->pMmInits, 0 ); + free( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/seq/seqMapCore.c b/src/base/seq/seqMapCore.c new file mode 100644 index 00000000..be02d4a7 --- /dev/null +++ b/src/base/seq/seqMapCore.c @@ -0,0 +1,47 @@ +/**CFile**************************************************************** + + FileName [seqMapCore.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Construction and manipulation of sequential AIGs.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: seqMapCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "seqInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/seq/seqMapIter.c b/src/base/seq/seqMapIter.c new file mode 100644 index 00000000..ec954d68 --- /dev/null +++ b/src/base/seq/seqMapIter.c @@ -0,0 +1,47 @@ +/**CFile**************************************************************** + + FileName [seqMapIter.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Construction and manipulation of sequential AIGs.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: seqMapIter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "seqInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/seq/seqRetCore.c b/src/base/seq/seqRetCore.c new file mode 100644 index 00000000..94c2b944 --- /dev/null +++ b/src/base/seq/seqRetCore.c @@ -0,0 +1,822 @@ +/**CFile**************************************************************** + + FileName [seqRetCore.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Construction and manipulation of sequential AIGs.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: seqRetCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "seqInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/* + Retiming can be represented in three equivalent forms: + - as a set of integer lags for each node (array of chars by node ID) + - as a set of node numbers with lag for each, fwd and bwd (two arrays of Seq_RetStep_t_) + - as a set of latch moves over the nodes, fwd and bwd (two arrays of node pointers Abc_Obj_t *) +*/ + +static void Abc_ObjRetimeForward( Abc_Obj_t * pObj ); +static int Abc_ObjRetimeBackward( Abc_Obj_t * pObj, Abc_Ntk_t * pNtk, stmm_table * tTable, Vec_Int_t * vValues ); +static void Abc_ObjRetimeBackwardUpdateEdge( Abc_Obj_t * pObj, int Edge, stmm_table * tTable ); +static void Abc_NtkRetimeSetInitialValues( Abc_Ntk_t * pNtk, stmm_table * tTable, int * pModel ); + +static void Seq_NtkImplementRetimingForward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves ); +static int Seq_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int fVerbose ); +static void Abc_ObjRetimeForward( Abc_Obj_t * pObj ); +static int Abc_ObjRetimeBackward( Abc_Obj_t * pObj, Abc_Ntk_t * pNtk, stmm_table * tTable, Vec_Int_t * vValues ); +static void Abc_ObjRetimeBackwardUpdateEdge( Abc_Obj_t * pObj, int Edge, stmm_table * tTable ); +static void Abc_NtkRetimeSetInitialValues( Abc_Ntk_t * pNtk, stmm_table * tTable, int * pModel ); + +static Vec_Ptr_t * Abc_NtkUtilRetimingTry( Abc_Ntk_t * pNtk, bool fForward ); +static Vec_Ptr_t * Abc_NtkUtilRetimingGetMoves( Abc_Ntk_t * pNtk, Vec_Int_t * vSteps, bool fForward ); +static Vec_Int_t * Abc_NtkUtilRetimingSplit( Vec_Str_t * vLags, int fForward ); +static void Abc_ObjRetimeForwardTry( Abc_Obj_t * pObj, int nLatches ); +static void Abc_ObjRetimeBackwardTry( Abc_Obj_t * pObj, int nLatches ); + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs performs optimal delay retiming.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk, int fInitial, int fVerbose ) +{ + Abc_Seq_t * p = pNtk->pManFunc; + int RetValue; + if ( !fInitial ) + Seq_NtkLatchSetValues( pNtk, ABC_INIT_DC ); + // get the retiming lags + Seq_NtkSeqRetimeDelayLags( pNtk, fVerbose ); + // implement this retiming + RetValue = Seq_NtkImplementRetiming( pNtk, p->vLags, fVerbose ); + if ( RetValue == 0 ) + printf( "Retiming completed but initial state computation has failed.\n" ); +} + +/**Function************************************************************* + + Synopsis [Performs most forward retiming.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_NtkSeqRetimeForward( Abc_Ntk_t * pNtk, int fInitial, int fVerbose ) +{ + Vec_Ptr_t * vMoves; + Abc_Obj_t * pNode; + int i; + if ( !fInitial ) + Seq_NtkLatchSetValues( pNtk, ABC_INIT_DC ); + // get the forward moves + vMoves = Abc_NtkUtilRetimingTry( pNtk, 1 ); + // undo the forward moves + Vec_PtrForEachEntryReverse( vMoves, pNode, i ) + Abc_ObjRetimeBackwardTry( pNode, 1 ); + // implement this forward retiming + Seq_NtkImplementRetimingForward( pNtk, vMoves ); + Vec_PtrFree( vMoves ); +} + +/**Function************************************************************* + + Synopsis [Performs most backward retiming.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk, int fInitial, int fVerbose ) +{ + Vec_Ptr_t * vMoves; + Abc_Obj_t * pNode; + int i, RetValue; + if ( !fInitial ) + Seq_NtkLatchSetValues( pNtk, ABC_INIT_DC ); + // get the backward moves + vMoves = Abc_NtkUtilRetimingTry( pNtk, 0 ); + // undo the backward moves + Vec_PtrForEachEntryReverse( vMoves, pNode, i ) + Abc_ObjRetimeForwardTry( pNode, 1 ); + // implement this backward retiming + RetValue = Seq_NtkImplementRetimingBackward( pNtk, vMoves, fVerbose ); + Vec_PtrFree( vMoves ); + if ( RetValue == 0 ) + printf( "Retiming completed but initial state computation has failed.\n" ); +} + + + + +/**Function************************************************************* + + Synopsis [Implements the retiming on the sequential AIG.] + + Description [Split the retiming into forward and backward.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Seq_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags, int fVerbose ) +{ + Vec_Int_t * vSteps; + Vec_Ptr_t * vMoves; + int RetValue; + + // forward retiming + vSteps = Abc_NtkUtilRetimingSplit( vLags, 1 ); + // translate each set of steps into moves + if ( fVerbose ) + printf( "The number of forward steps = %6d.\n", Vec_IntSize(vSteps) ); + vMoves = Abc_NtkUtilRetimingGetMoves( pNtk, vSteps, 1 ); + if ( fVerbose ) + printf( "The number of forward moves = %6d.\n", Vec_PtrSize(vMoves) ); + // implement this retiming + Seq_NtkImplementRetimingForward( pNtk, vMoves ); + Vec_IntFree( vSteps ); + Vec_PtrFree( vMoves ); + + // backward retiming + vSteps = Abc_NtkUtilRetimingSplit( vLags, 0 ); + // translate each set of steps into moves + if ( fVerbose ) + printf( "The number of backward steps = %6d.\n", Vec_IntSize(vSteps) ); + vMoves = Abc_NtkUtilRetimingGetMoves( pNtk, vSteps, 0 ); + if ( fVerbose ) + printf( "The number of backward moves = %6d.\n", Vec_PtrSize(vMoves) ); + // implement this retiming + RetValue = Seq_NtkImplementRetimingBackward( pNtk, vMoves, fVerbose ); + Vec_IntFree( vSteps ); + Vec_PtrFree( vMoves ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Implements the given retiming on the sequential AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_NtkImplementRetimingForward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves ) +{ + Abc_Obj_t * pNode; + int i; + Vec_PtrForEachEntry( vMoves, pNode, i ) + Abc_ObjRetimeForward( pNode ); +} + +/**Function************************************************************* + + Synopsis [Retimes node forward by one latch.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ObjRetimeForward( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFanout; + int Init0, Init1, Init, i; + assert( Abc_ObjFaninNum(pObj) == 2 ); + assert( Abc_ObjFaninL0(pObj) >= 1 ); + assert( Abc_ObjFaninL1(pObj) >= 1 ); + // remove the init values from the fanins + Init0 = Seq_NodeDeleteFirst( pObj, 0 ); + Init1 = Seq_NodeDeleteFirst( pObj, 1 ); + assert( Init0 != ABC_INIT_NONE ); + assert( Init1 != ABC_INIT_NONE ); + // take into account the complements in the node + if ( Abc_ObjFaninC0(pObj) ) + { + if ( Init0 == ABC_INIT_ZERO ) + Init0 = ABC_INIT_ONE; + else if ( Init0 == ABC_INIT_ONE ) + Init0 = ABC_INIT_ZERO; + } + if ( Abc_ObjFaninC1(pObj) ) + { + if ( Init1 == ABC_INIT_ZERO ) + Init1 = ABC_INIT_ONE; + else if ( Init1 == ABC_INIT_ONE ) + Init1 = ABC_INIT_ZERO; + } + // compute the value at the output of the node + if ( Init0 == ABC_INIT_ZERO || Init1 == ABC_INIT_ZERO ) + Init = ABC_INIT_ZERO; + else if ( Init0 == ABC_INIT_ONE && Init1 == ABC_INIT_ONE ) + Init = ABC_INIT_ONE; + else + Init = ABC_INIT_DC; + // add the init values to the fanouts + Abc_ObjForEachFanout( pObj, pFanout, i ) + Seq_NodeInsertLast( pFanout, Abc_ObjFanoutEdgeNum(pObj, pFanout), Init ); +} + + + +/**Function************************************************************* + + Synopsis [Implements the given retiming on the sequential AIG.] + + Description [Returns 0 of initial state computation fails.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Seq_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int fVerbose ) +{ + Seq_RetEdge_t RetEdge; + stmm_table * tTable; + stmm_generator * gen; + Vec_Int_t * vValues; + Abc_Ntk_t * pNtkProb, * pNtkMiter, * pNtkCnf; + Abc_Obj_t * pNode, * pNodeNew; + int * pModel, RetValue, i, clk; + + // return if the retiming is trivial + if ( Vec_PtrSize(vMoves) == 0 ) + return 1; + + // create the network for the initial state computation + // start the table and the array of PO values + pNtkProb = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP ); + tTable = stmm_init_table( stmm_numcmp, stmm_numhash ); + vValues = Vec_IntAlloc( 100 ); + + // perform the backward moves and build the network for initial state computation + RetValue = 0; + Vec_PtrForEachEntry( vMoves, pNode, i ) + RetValue |= Abc_ObjRetimeBackward( pNode, pNtkProb, tTable, vValues ); + + // add the PIs corresponding to the white spots + stmm_foreach_item( tTable, gen, (char **)&RetEdge, (char **)&pNodeNew ) + Abc_ObjAddFanin( pNodeNew, Abc_NtkCreatePi(pNtkProb) ); + + // add the PI/PO names + Abc_NtkAddDummyPiNames( pNtkProb ); + Abc_NtkAddDummyPoNames( pNtkProb ); + + // make sure everything is okay with the network structure + if ( !Abc_NtkDoCheck( pNtkProb ) ) + { + printf( "Seq_NtkImplementRetimingBackward: The internal network check has failed.\n" ); + Abc_NtkRetimeSetInitialValues( pNtk, tTable, NULL ); + Abc_NtkDelete( pNtkProb ); + stmm_free_table( tTable ); + Vec_IntFree( vValues ); + return 0; + } + + // check if conflict is found + if ( RetValue ) + { + printf( "Seq_NtkImplementRetimingBackward: A top level conflict is detected. DC latch values are used.\n" ); + Abc_NtkRetimeSetInitialValues( pNtk, tTable, NULL ); + Abc_NtkDelete( pNtkProb ); + stmm_free_table( tTable ); + Vec_IntFree( vValues ); + return 0; + } + + // get the miter cone + pNtkMiter = Abc_NtkCreateCone( pNtkProb, pNtkProb->vCos, vValues ); + Abc_NtkDelete( pNtkProb ); + Vec_IntFree( vValues ); + + if ( fVerbose ) + printf( "The number of ANDs in the AIG = %5d.\n", Abc_NtkNodeNum(pNtkMiter) ); + + // transform the miter into a logic network for efficient CNF construction + pNtkCnf = Abc_NtkRenode( pNtkMiter, 0, 100, 1, 0, 0 ); + Abc_NtkDelete( pNtkMiter ); + + // solve the miter +clk = clock(); + RetValue = Abc_NtkMiterSat( pNtkCnf, 30, 0 ); +if ( fVerbose ) +if ( clock() - clk > 100 ) +{ +PRT( "SAT solving time", clock() - clk ); +} + pModel = pNtkCnf->pModel; pNtkCnf->pModel = NULL; + Abc_NtkDelete( pNtkCnf ); + + // analyze the result + if ( RetValue == -1 || RetValue == 1 ) + { + Abc_NtkRetimeSetInitialValues( pNtk, tTable, NULL ); + if ( RetValue == 1 ) + printf( "Seq_NtkImplementRetimingBackward: The problem is unsatisfiable. DC latch values are used.\n" ); + else + printf( "Seq_NtkImplementRetimingBackward: The SAT problem timed out. DC latch values are used.\n" ); + stmm_free_table( tTable ); + return 0; + } + + // set the values of the latches + Abc_NtkRetimeSetInitialValues( pNtk, tTable, pModel ); + stmm_free_table( tTable ); + free( pModel ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Retimes node backward by one latch.] + + Description [Constructs the problem for initial state computation. + Returns 1 if the conflict is found.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_ObjRetimeBackward( Abc_Obj_t * pObj, Abc_Ntk_t * pNtkNew, stmm_table * tTable, Vec_Int_t * vValues ) +{ + Abc_Obj_t * pFanout; + Abc_InitType_t Init, Value; + Seq_RetEdge_t RetEdge; + Abc_Obj_t * pNodeNew, * pFanoutNew, * pBuffer; + int i, Edge, fMet0, fMet1, fMetN; + + // make sure the node can be retimed + assert( Seq_ObjFanoutLMin(pObj) > 0 ); + // get the fanout values + fMet0 = fMet1 = fMetN = 0; + Abc_ObjForEachFanout( pObj, pFanout, i ) + { + Init = Seq_NodeGetInitLast( pFanout, Abc_ObjFanoutEdgeNum(pObj, pFanout) ); + if ( Init == ABC_INIT_ZERO ) + fMet0 = 1; + else if ( Init == ABC_INIT_ONE ) + fMet1 = 1; + else if ( Init == ABC_INIT_NONE ) + fMetN = 1; + } + + // consider the case when all fanout latchs have don't-care values + // the new values on the fanin edges will be don't-cares + if ( !fMet0 && !fMet1 && !fMetN ) + { + // update the fanout edges + Abc_ObjForEachFanout( pObj, pFanout, i ) + Seq_NodeDeleteLast( pFanout, Abc_ObjFanoutEdgeNum(pObj, pFanout) ); + // update the fanin edges + Abc_ObjRetimeBackwardUpdateEdge( pObj, 0, tTable ); + Abc_ObjRetimeBackwardUpdateEdge( pObj, 1, tTable ); + Seq_NodeInsertFirst( pObj, 0, ABC_INIT_DC ); + Seq_NodeInsertFirst( pObj, 1, ABC_INIT_DC ); + return 0; + } + // the initial values on the fanout edges contain 0, 1, or unknown + // the new values on the fanin edges will be unknown + + // add new AND-gate to the network + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + pNodeNew->pData = Abc_SopCreateAnd2( pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); + + // add PO fanouts if any + if ( fMet0 ) + { + Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew ); + Vec_IntPush( vValues, 0 ); + } + if ( fMet1 ) + { + Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew ); + Vec_IntPush( vValues, 1 ); + } + + // perform the changes + Abc_ObjForEachFanout( pObj, pFanout, i ) + { + Edge = Abc_ObjFanoutEdgeNum( pObj, pFanout ); + Value = Seq_NodeDeleteLast( pFanout, Edge ); + if ( Value != ABC_INIT_NONE ) + continue; + // value is unknown, remove it from the table + RetEdge.iNode = pFanout->Id; + RetEdge.iEdge = Edge; + RetEdge.iLatch = Abc_ObjFaninL( pFanout, Edge ); // after edge is removed + if ( !stmm_delete( tTable, (char **)&RetEdge, (char **)&pFanoutNew ) ) + assert( 0 ); + // create the fanout of the AND gate + Abc_ObjAddFanin( pFanoutNew, pNodeNew ); + } + + // update the fanin edges + Abc_ObjRetimeBackwardUpdateEdge( pObj, 0, tTable ); + Abc_ObjRetimeBackwardUpdateEdge( pObj, 1, tTable ); + Seq_NodeInsertFirst( pObj, 0, ABC_INIT_NONE ); + Seq_NodeInsertFirst( pObj, 1, ABC_INIT_NONE ); + + // add the buffer + pBuffer = Abc_NtkCreateNode( pNtkNew ); + pBuffer->pData = Abc_SopCreateBuf( pNtkNew->pManFunc ); + Abc_ObjAddFanin( pNodeNew, pBuffer ); + // point to it from the table + RetEdge.iNode = pObj->Id; + RetEdge.iEdge = 0; + RetEdge.iLatch = 0; + if ( stmm_insert( tTable, (char *)Seq_RetEdge2Int(RetEdge), (char *)pBuffer ) ) + assert( 0 ); + + // add the buffer + pBuffer = Abc_NtkCreateNode( pNtkNew ); + pBuffer->pData = Abc_SopCreateBuf( pNtkNew->pManFunc ); + Abc_ObjAddFanin( pNodeNew, pBuffer ); + // point to it from the table + RetEdge.iNode = pObj->Id; + RetEdge.iEdge = 1; + RetEdge.iLatch = 0; + if ( stmm_insert( tTable, (char *)Seq_RetEdge2Int(RetEdge), (char *)pBuffer ) ) + assert( 0 ); + + // report conflict is found + return fMet0 && fMet1; +} + +/**Function************************************************************* + + Synopsis [Generates the printable edge label with the initial state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ObjRetimeBackwardUpdateEdge( Abc_Obj_t * pObj, int Edge, stmm_table * tTable ) +{ + Abc_Obj_t * pFanoutNew; + Seq_RetEdge_t RetEdge; + Abc_InitType_t Init; + int nLatches, i; + + // get the number of latches on the edge + nLatches = Abc_ObjFaninL( pObj, Edge ); + for ( i = nLatches - 1; i >= 0; i-- ) + { + // get the value of this latch + Init = Seq_NodeGetInitOne( pObj, Edge, i ); + if ( Init != ABC_INIT_NONE ) + continue; + // get the retiming edge + RetEdge.iNode = pObj->Id; + RetEdge.iEdge = Edge; + RetEdge.iLatch = i; + // remove entry from table and add it with a different key + if ( !stmm_delete( tTable, (char **)&RetEdge, (char **)&pFanoutNew ) ) + assert( 0 ); + RetEdge.iLatch++; + if ( stmm_insert( tTable, (char *)Seq_RetEdge2Int(RetEdge), (char *)pFanoutNew ) ) + assert( 0 ); + } +} + +/**Function************************************************************* + + Synopsis [Sets the initial values.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkRetimeSetInitialValues( Abc_Ntk_t * pNtk, stmm_table * tTable, int * pModel ) +{ + Abc_Obj_t * pNode; + stmm_generator * gen; + Seq_RetEdge_t RetEdge; + Abc_InitType_t Init; + int i; + + i = 0; + stmm_foreach_item( tTable, gen, (char **)&RetEdge, NULL ) + { + pNode = Abc_NtkObj( pNtk, RetEdge.iNode ); + Init = pModel? (pModel[i]? ABC_INIT_ONE : ABC_INIT_ZERO) : ABC_INIT_DC; + Seq_NodeSetInitOne( pNode, RetEdge.iEdge, RetEdge.iLatch, Init ); + i++; + } +} + + + +/**Function************************************************************* + + Synopsis [Performs forward retiming of the sequential AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NtkUtilRetimingTry( Abc_Ntk_t * pNtk, bool fForward ) +{ + Vec_Ptr_t * vNodes, * vMoves; + Abc_Obj_t * pNode, * pFanout, * pFanin; + int i, k, nLatches; + assert( Abc_NtkIsSeq( pNtk ) ); + // assume that all nodes can be retimed + vNodes = Vec_PtrAlloc( 100 ); + Abc_AigForEachAnd( pNtk, pNode, i ) + { + Vec_PtrPush( vNodes, pNode ); + pNode->fMarkA = 1; + } + // process the nodes + vMoves = Vec_PtrAlloc( 100 ); + Vec_PtrForEachEntry( vNodes, pNode, i ) + { +// printf( "(%d,%d) ", Abc_ObjFaninL0(pNode), Abc_ObjFaninL0(pNode) ); + // unmark the node as processed + pNode->fMarkA = 0; + // get the number of latches to retime + if ( fForward ) + nLatches = Abc_ObjFaninLMin(pNode); + else + nLatches = Seq_ObjFanoutLMin(pNode); + if ( nLatches == 0 ) + continue; + assert( nLatches > 0 ); + // retime the latches forward + if ( fForward ) + Abc_ObjRetimeForwardTry( pNode, nLatches ); + else + Abc_ObjRetimeBackwardTry( pNode, nLatches ); + // write the moves + for ( k = 0; k < nLatches; k++ ) + Vec_PtrPush( vMoves, pNode ); + // schedule fanouts for updating + if ( fForward ) + { + Abc_ObjForEachFanout( pNode, pFanout, k ) + { + if ( Abc_ObjFaninNum(pFanout) != 2 || pFanout->fMarkA ) + continue; + pFanout->fMarkA = 1; + Vec_PtrPush( vNodes, pFanout ); + } + } + else + { + Abc_ObjForEachFanin( pNode, pFanin, k ) + { + if ( Abc_ObjFaninNum(pFanin) != 2 || pFanin->fMarkA ) + continue; + pFanin->fMarkA = 1; + Vec_PtrPush( vNodes, pFanin ); + } + } + } + Vec_PtrFree( vNodes ); + // make sure the marks are clean the the retiming is final + Abc_AigForEachAnd( pNtk, pNode, i ) + { + assert( pNode->fMarkA == 0 ); + if ( fForward ) + assert( Abc_ObjFaninLMin(pNode) == 0 ); + else + assert( Seq_ObjFanoutLMin(pNode) == 0 ); + } + return vMoves; +} + +/**Function************************************************************* + + Synopsis [Translates retiming steps into retiming moves.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NtkUtilRetimingGetMoves( Abc_Ntk_t * pNtk, Vec_Int_t * vSteps, bool fForward ) +{ + Seq_RetStep_t RetStep; + Vec_Ptr_t * vMoves; + Abc_Obj_t * pNode; + int i, k, iNode, nLatches, Number; + int fChange; + assert( Abc_NtkIsSeq( pNtk ) ); + // process the nodes + vMoves = Vec_PtrAlloc( 100 ); + while ( Vec_IntSize(vSteps) > 0 ) + { + iNode = 0; + fChange = 0; + Vec_IntForEachEntry( vSteps, Number, i ) + { + // get the retiming step + RetStep = Seq_Int2RetStep( Number ); + // get the node to be retimed + pNode = Abc_NtkObj( pNtk, RetStep.iNode ); + assert( RetStep.nLatches > 0 ); + // get the number of latches that can be retimed + if ( fForward ) + nLatches = Abc_ObjFaninLMin(pNode); + else + nLatches = Seq_ObjFanoutLMin(pNode); + if ( nLatches == 0 ) + { + Vec_IntWriteEntry( vSteps, iNode++, Seq_RetStep2Int(RetStep) ); + continue; + } + assert( nLatches > 0 ); + fChange = 1; + // get the number of latches to be retimed over this node + nLatches = ABC_MIN( nLatches, (int)RetStep.nLatches ); + // retime the latches forward + if ( fForward ) + Abc_ObjRetimeForwardTry( pNode, nLatches ); + else + Abc_ObjRetimeBackwardTry( pNode, nLatches ); + // write the moves + for ( k = 0; k < nLatches; k++ ) + Vec_PtrPush( vMoves, pNode ); + // subtract the retiming performed + RetStep.nLatches -= nLatches; + // store the node if it is not retimed completely + if ( RetStep.nLatches > 0 ) + Vec_IntWriteEntry( vSteps, iNode++, Seq_RetStep2Int(RetStep) ); + } + // reduce the array + Vec_IntShrink( vSteps, iNode ); + if ( !fChange ) + { + printf( "Warning: %d strange steps (a minor bug to be fixed later).\n", Vec_IntSize(vSteps) ); + /* + Vec_IntForEachEntry( vSteps, Number, i ) + { + RetStep = Seq_Int2RetStep( Number ); + printf( "%d(%d) ", RetStep.iNode, RetStep.nLatches ); + } + printf( "\n" ); + */ + break; + } + } + // undo the tentative retiming + if ( fForward ) + { + Vec_PtrForEachEntryReverse( vMoves, pNode, i ) + Abc_ObjRetimeBackwardTry( pNode, 1 ); + } + else + { + Vec_PtrForEachEntryReverse( vMoves, pNode, i ) + Abc_ObjRetimeForwardTry( pNode, 1 ); + } + return vMoves; +} + + +/**Function************************************************************* + + Synopsis [Splits retiming into forward and backward.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Abc_NtkUtilRetimingSplit( Vec_Str_t * vLags, int fForward ) +{ + Vec_Int_t * vNodes; + Seq_RetStep_t RetStep; + int Value, i; + vNodes = Vec_IntAlloc( 100 ); + Vec_StrForEachEntry( vLags, Value, i ) + { + if ( Value < 0 && fForward ) + { + RetStep.iNode = i; + RetStep.nLatches = -Value; + Vec_IntPush( vNodes, Seq_RetStep2Int(RetStep) ); + } + else if ( Value > 0 && !fForward ) + { + RetStep.iNode = i; + RetStep.nLatches = Value; + Vec_IntPush( vNodes, Seq_RetStep2Int(RetStep) ); + } + } + return vNodes; +} + +/**Function************************************************************* + + Synopsis [Retime node forward without initial states.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ObjRetimeForwardTry( Abc_Obj_t * pObj, int nLatches ) +{ + Abc_Obj_t * pFanout; + int i; + // make sure it is an AND gate + assert( Abc_ObjFaninNum(pObj) == 2 ); + // make sure it has enough latches +// assert( Abc_ObjFaninL0(pObj) >= nLatches ); +// assert( Abc_ObjFaninL1(pObj) >= nLatches ); + // subtract these latches on the fanin side + Abc_ObjAddFaninL0( pObj, -nLatches ); + Abc_ObjAddFaninL1( pObj, -nLatches ); + // add these latches on the fanout size + Abc_ObjForEachFanout( pObj, pFanout, i ) + Abc_ObjAddFanoutL( pObj, pFanout, nLatches ); +} + +/**Function************************************************************* + + Synopsis [Retime node backward without initial states.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ObjRetimeBackwardTry( Abc_Obj_t * pObj, int nLatches ) +{ + Abc_Obj_t * pFanout; + int i; + // make sure it is an AND gate + assert( Abc_ObjFaninNum(pObj) == 2 ); + // subtract these latches on the fanout side + Abc_ObjForEachFanout( pObj, pFanout, i ) + { +// assert( Abc_ObjFanoutL(pObj, pFanout) >= nLatches ); + Abc_ObjAddFanoutL( pObj, pFanout, -nLatches ); + } + // add these latches on the fanin size + Abc_ObjAddFaninL0( pObj, nLatches ); + Abc_ObjAddFaninL1( pObj, nLatches ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/seq/seqRetIter.c b/src/base/seq/seqRetIter.c new file mode 100644 index 00000000..ee2c31b2 --- /dev/null +++ b/src/base/seq/seqRetIter.c @@ -0,0 +1,226 @@ +/**CFile**************************************************************** + + FileName [seqRetIter.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Construction and manipulation of sequential AIGs.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: seqRetIter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "seqInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// the internal procedures +static int Seq_RetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose ); +static int Seq_RetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose ); +static int Seq_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi ); + +// node status after updating its arrival time +enum { SEQ_UPDATE_FAIL, SEQ_UPDATE_NO, SEQ_UPDATE_YES }; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Retimes AIG for optimal delay using Pan's algorithm.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose ) +{ + Abc_Seq_t * p = pNtk->pManFunc; + Abc_Obj_t * pNode; + int i, FiMax, FiBest, RetValue; + + assert( Abc_NtkIsSeq( pNtk ) ); + + // get the upper bound on the clock period +// FiMax = Abc_NtkNodeNum(pNtk); + FiMax = 0; + Abc_AigForEachAnd( pNtk, pNode, i ) + if ( FiMax < (int)pNode->Level ) + FiMax = pNode->Level; + FiMax += 2; + + // make sure this clock period is feasible + assert( Seq_RetimeForPeriod( pNtk, FiMax, fVerbose ) ); + + // search for the optimal clock period between 0 and nLevelMax + FiBest = Seq_RetimeSearch_rec( pNtk, 0, FiMax, fVerbose ); + + // recompute the best LValues + RetValue = Seq_RetimeForPeriod( pNtk, FiBest, fVerbose ); + assert( RetValue ); + + // write the retiming lags + Vec_StrFill( p->vLags, p->nSize, 0 ); + Abc_AigForEachAnd( pNtk, pNode, i ) + Seq_NodeSetLag( pNode, (char)Seq_NodeComputeLag(Seq_NodeGetLValue(pNode), FiBest) ); + + // print the result + if ( fVerbose ) + printf( "The best clock period is %3d.\n", FiBest ); + +/* + printf( "LValues : " ); + Abc_AigForEachAnd( pNtk, pNode, i ) + printf( "%d=%d ", i, Seq_NodeGetLValue(pNode) ); + printf( "\n" ); + printf( "Lags : " ); + Abc_AigForEachAnd( pNtk, pNode, i ) + if ( Vec_StrEntry(p->vLags,i) != 0 ) + printf( "%d=%d(%d)(%d) ", i, Vec_StrEntry(p->vLags,i), Seq_NodeGetLValue(pNode), Seq_NodeGetLValue(pNode) - FiBest * Vec_StrEntry(p->vLags,i) ); + printf( "\n" ); +*/ +} + +/**Function************************************************************* + + Synopsis [Performs binary search for the optimal clock period.] + + Description [Assumes that FiMin is infeasible while FiMax is feasible.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Seq_RetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose ) +{ + int Median; + assert( FiMin < FiMax ); + if ( FiMin + 1 == FiMax ) + return FiMax; + Median = FiMin + (FiMax - FiMin)/2; + if ( Seq_RetimeForPeriod( pNtk, Median, fVerbose ) ) + return Seq_RetimeSearch_rec( pNtk, FiMin, Median, fVerbose ); // Median is feasible + else + return Seq_RetimeSearch_rec( pNtk, Median, FiMax, fVerbose ); // Median is infeasible +} + +/**Function************************************************************* + + Synopsis [Returns 1 if retiming with this clock period is feasible.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Seq_RetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose ) +{ + Abc_Seq_t * p = pNtk->pManFunc; + Abc_Obj_t * pObj; + int i, c, RetValue, fChange, Counter; + char * pReason = ""; + + // set l-values of all nodes to be minus infinity + Vec_IntFill( p->vLValues, p->nSize, -ABC_INFINITY ); + + // set l-values for the constant and PIs + pObj = Abc_NtkObj( pNtk, 0 ); + Seq_NodeSetLValue( pObj, 0 ); + Abc_NtkForEachPi( pNtk, pObj, i ) + Seq_NodeSetLValue( pObj, 0 ); + + // update all values iteratively + Counter = 0; + for ( c = 0; c < 20; c++ ) + { + fChange = 0; + Abc_NtkForEachObj( pNtk, pObj, i ) + { + if ( Abc_ObjIsPi(pObj) ) + continue; + if ( Abc_ObjFaninNum(pObj) == 0 ) + continue; + RetValue = Seq_NodeUpdateLValue( pObj, Fi ); + Counter++; + if ( RetValue == SEQ_UPDATE_FAIL ) + break; + if ( RetValue == SEQ_UPDATE_NO ) + continue; + fChange = 1; + } + if ( RetValue == SEQ_UPDATE_FAIL ) + break; + if ( fChange == 0 ) + break; + } + if ( c == 20 ) + { + RetValue = SEQ_UPDATE_FAIL; + pReason = "(timeout)"; + } + + // report the results + if ( fVerbose ) + { + if ( RetValue == SEQ_UPDATE_FAIL ) + printf( "Period = %3d. Iterations = %3d. Updates = %10d. Infeasible %s\n", Fi, c, Counter, pReason ); + else + printf( "Period = %3d. Iterations = %3d. Updates = %10d. Feasible\n", Fi, c, Counter ); + } + return RetValue != SEQ_UPDATE_FAIL; +} + +/**Function************************************************************* + + Synopsis [Computes the l-value of the node.] + + Description [The node can be internal or a PO.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Seq_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi ) +{ + int lValueNew, lValueOld, lValue0, lValue1; + assert( !Abc_ObjIsPi(pObj) ); + assert( Abc_ObjFaninNum(pObj) > 0 ); + lValue0 = Seq_NodeGetLValue(Abc_ObjFanin0(pObj)) - Fi * Abc_ObjFaninL0(pObj); + if ( Abc_ObjIsPo(pObj) ) + return (lValue0 > Fi)? SEQ_UPDATE_FAIL : SEQ_UPDATE_NO; + if ( Abc_ObjFaninNum(pObj) == 2 ) + lValue1 = Seq_NodeGetLValue(Abc_ObjFanin1(pObj)) - Fi * Abc_ObjFaninL1(pObj); + else + lValue1 = -ABC_INFINITY; + lValueNew = 1 + ABC_MAX( lValue0, lValue1 ); + lValueOld = Seq_NodeGetLValue(pObj); +// if ( lValueNew == lValueOld ) + if ( lValueNew <= lValueOld ) + return SEQ_UPDATE_NO; + Seq_NodeSetLValue( pObj, lValueNew ); + return SEQ_UPDATE_YES; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abcs/abcShare.c b/src/base/seq/seqShare.c index 43424705..8f7432f0 100644 --- a/src/base/abcs/abcShare.c +++ b/src/base/seq/seqShare.c @@ -1,12 +1,12 @@ /**CFile**************************************************************** - FileName [abcShare.c] + FileName [seqShare.c] SystemName [ABC: Logic synthesis and verification system.] - PackageName [Procedures for latch sharing on the fanout edges.] + PackageName [Construction and manipulation of sequential AIGs.] - Synopsis [Utilities working sequential AIGs.] + Synopsis [] Author [Alan Mishchenko] @@ -14,11 +14,11 @@ Date [Ver. 1.0. Started - June 20, 2005.] - Revision [$Id: abcShare.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + Revision [$Id: seqShare.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ -#include "abcs.h" +#include "seqInt.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -42,7 +42,7 @@ static void Abc_NodeSeqShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr SeeAlso [] ***********************************************************************/ -void Abc_NtkSeqShareFanouts( Abc_Ntk_t * pNtk ) +void Seq_NtkSeqShareFanouts( Abc_Ntk_t * pNtk ) { Vec_Ptr_t * vNodes; Abc_Obj_t * pObj; @@ -84,7 +84,7 @@ void Abc_NodeSeqShareFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) { if ( Abc_ObjFanoutL(pNode, pFanout) == 0 ) continue; - Type = Abc_ObjFaninLGetInitLast( pFanout, Abc_ObjEdgeNum(pNode, pFanout) ); + Type = Seq_NodeGetInitLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) ); nLatches[Type]++; } // decide what to do @@ -119,7 +119,7 @@ void Abc_NodeSeqShareFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) ***********************************************************************/ void Abc_NodeSeqShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr_t * vNodes ) { - Vec_Int_t * vInits = pNode->pNtk->vInits; + Vec_Ptr_t * vInits = Seq_NodeLats( pNode ); Abc_Obj_t * pFanout, * pBuffer; Abc_InitType_t Type, InitNew; int i; @@ -130,29 +130,30 @@ void Abc_NodeSeqShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr_t * vN { if ( Abc_ObjFanoutL(pNode, pFanout) == 0 ) continue; - Type = Abc_ObjFaninLGetInitLast( pFanout, Abc_ObjEdgeNum(pNode, pFanout) ); + Type = Seq_NodeGetInitLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) ); if ( Type == Init ) InitNew = Init; if ( Type == Init || Type == ABC_INIT_DC ) { Vec_PtrPush( vNodes, pFanout ); - Abc_ObjFaninLDeleteLast( pFanout, Abc_ObjEdgeNum(pNode, pFanout) ); + Seq_NodeDeleteLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) ); } } // create the new buffer pBuffer = Abc_NtkCreateNode( pNode->pNtk ); Abc_ObjAddFanin( pBuffer, pNode ); - Abc_ObjSetFaninL( pBuffer, 0, 1 ); - // add the initial state - assert( Vec_IntSize(vInits) == 2 * (int)pBuffer->Id ); - Vec_IntPush( vInits, InitNew ); - Vec_IntPush( vInits, 0 ); + + // grow storage for initial states + Vec_PtrGrow( vInits, 2 * pBuffer->Id + 2 ); + for ( i = Vec_PtrSize(vInits); i < 2 * (int)pBuffer->Id + 2; i++ ) + Vec_PtrPush( vInits, NULL ); + Seq_NodeInsertFirst( pBuffer, 0, InitNew ); + // redirect the fanouts Vec_PtrForEachEntry( vNodes, pFanout, i ) Abc_ObjPatchFanin( pFanout, pNode, pBuffer ); } - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/seq/seqUtil.c b/src/base/seq/seqUtil.c new file mode 100644 index 00000000..ce92bd33 --- /dev/null +++ b/src/base/seq/seqUtil.c @@ -0,0 +1,345 @@ +/**CFile**************************************************************** + + FileName [seqUtil.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Construction and manipulation of sequential AIGs.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: seqUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "seqInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Returns the maximum latch number on any of the fanouts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Seq_ObjFanoutLMax( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFanout; + int i, nLatchCur, nLatchRes; + if ( Abc_ObjFanoutNum(pObj) == 0 ) + return 0; + nLatchRes = 0; + Abc_ObjForEachFanout( pObj, pFanout, i ) + { + nLatchCur = Abc_ObjFanoutL(pObj, pFanout); + if ( nLatchRes < nLatchCur ) + nLatchRes = nLatchCur; + } + assert( nLatchRes >= 0 ); + return nLatchRes; +} + +/**Function************************************************************* + + Synopsis [Returns the minimum latch number on any of the fanouts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Seq_ObjFanoutLMin( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFanout; + int i, nLatchCur, nLatchRes; + if ( Abc_ObjFanoutNum(pObj) == 0 ) + return 0; + nLatchRes = ABC_INFINITY; + Abc_ObjForEachFanout( pObj, pFanout, i ) + { + nLatchCur = Abc_ObjFanoutL(pObj, pFanout); + if ( nLatchRes > nLatchCur ) + nLatchRes = nLatchCur; + } + assert( nLatchRes < ABC_INFINITY ); + return nLatchRes; +} + +/**Function************************************************************* + + Synopsis [Returns the sum of latches on the fanout edges.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Seq_ObjFanoutLSum( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFanout; + int i, nSum = 0; + Abc_ObjForEachFanout( pObj, pFanout, i ) + nSum += Abc_ObjFanoutL(pObj, pFanout); + return nSum; +} + +/**Function************************************************************* + + Synopsis [Returns the sum of latches on the fanin edges.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Seq_ObjFaninLSum( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFanin; + int i, nSum = 0; + Abc_ObjForEachFanin( pObj, pFanin, i ) + nSum += Abc_ObjFaninL(pObj, i); + return nSum; +} + +/**Function************************************************************* + + Synopsis [Generates the printable edge label with the initial state.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Seq_ObjFaninGetInitPrintable( Abc_Obj_t * pObj, int Edge ) +{ + static char Buffer[1000]; + Abc_InitType_t Init; + int nLatches, i; + nLatches = Abc_ObjFaninL( pObj, Edge ); + for ( i = 0; i < nLatches; i++ ) + { + Init = Seq_LatInit( Seq_NodeGetLat(pObj, Edge, i) ); + if ( Init == ABC_INIT_NONE ) + Buffer[i] = '_'; + else if ( Init == ABC_INIT_ZERO ) + Buffer[i] = '0'; + else if ( Init == ABC_INIT_ONE ) + Buffer[i] = '1'; + else if ( Init == ABC_INIT_DC ) + Buffer[i] = 'x'; + else assert( 0 ); + } + Buffer[nLatches] = 0; + return Buffer; +} + +/**Function************************************************************* + + Synopsis [Sets the given value to all the latches of the edge.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_NodeLatchSetValues( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init ) +{ + Seq_Lat_t * pLat, * pRing; + int c; + pRing = Seq_NodeGetRing(pObj, Edge); + if ( pRing == NULL ) + return; + for ( c = 0, pLat = pRing; !c || pLat != pRing; c++, pLat = pLat->pNext ) + Seq_LatSetInit( pLat, Init ); +} + +/**Function************************************************************* + + Synopsis [Sets the given value to all the latches of the edge.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_NtkLatchSetValues( Abc_Ntk_t * pNtk, Abc_InitType_t Init ) +{ + Abc_Obj_t * pObj; + int i; + assert( Abc_NtkIsSeq( pNtk ) ); + Abc_NtkForEachPo( pNtk, pObj, i ) + Seq_NodeLatchSetValues( pObj, 0, Init ); + Abc_NtkForEachNode( pNtk, pObj, i ) + { + Seq_NodeLatchSetValues( pObj, 0, Init ); + Seq_NodeLatchSetValues( pObj, 1, Init ); + } +} + + +/**Function************************************************************* + + Synopsis [Counts the number of latches in the sequential AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Seq_NtkLatchNum( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i, Counter; + assert( Abc_NtkIsSeq( pNtk ) ); + Counter = 0; + Abc_NtkForEachNode( pNtk, pObj, i ) + Counter += Seq_ObjFaninLSum( pObj ); + Abc_NtkForEachPo( pNtk, pObj, i ) + Counter += Seq_ObjFaninLSum( pObj ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Counts the number of latches in the sequential AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Seq_NtkLatchNumMax( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i, Max, Cur; + assert( Abc_NtkIsSeq( pNtk ) ); + Max = 0; + Abc_AigForEachAnd( pNtk, pObj, i ) + { + Cur = Abc_ObjFaninLMax( pObj ); + if ( Max < Cur ) + Max = Cur; + } + Abc_NtkForEachPo( pNtk, pObj, i ) + { + Cur = Abc_ObjFaninL0( pObj ); + if ( Max < Cur ) + Max = Cur; + } + return Max; +} + +/**Function************************************************************* + + Synopsis [Counts the number of latches in the sequential AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Seq_NtkLatchNumShared( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i, Counter; + assert( Abc_NtkIsSeq( pNtk ) ); + Counter = 0; + Abc_NtkForEachPi( pNtk, pObj, i ) + Counter += Seq_ObjFanoutLMax( pObj ); + Abc_NtkForEachNode( pNtk, pObj, i ) + Counter += Seq_ObjFanoutLMax( pObj ); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Counts the number of latches in the sequential AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_ObjLatchGetInitNums( Abc_Obj_t * pObj, int Edge, int * pInits ) +{ + Abc_InitType_t Init; + int nLatches, i; + nLatches = Abc_ObjFaninL( pObj, Edge ); + for ( i = 0; i < nLatches; i++ ) + { + Init = Seq_NodeGetInitOne( pObj, Edge, i ); + pInits[Init]++; + } +} + +/**Function************************************************************* + + Synopsis [Counts the number of latches in the sequential AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Seq_NtkLatchGetInitNums( Abc_Ntk_t * pNtk, int * pInits ) +{ + Abc_Obj_t * pObj; + int i; + assert( Abc_NtkIsSeq( pNtk ) ); + for ( i = 0; i < 4; i++ ) + pInits[i] = 0; + Abc_NtkForEachPo( pNtk, pObj, i ) + Seq_ObjLatchGetInitNums( pObj, 0, pInits ); + Abc_NtkForEachNode( pNtk, pObj, i ) + { + if ( Abc_ObjFaninNum(pObj) > 0 ) + Seq_ObjLatchGetInitNums( pObj, 0, pInits ); + if ( Abc_ObjFaninNum(pObj) > 1 ) + Seq_ObjLatchGetInitNums( pObj, 1, pInits ); + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |