00001
00021 #include "aig.h"
00022
00026
00027
00028 typedef enum {
00029 RTM_VAL_NONE,
00030 RTM_VAL_ZERO,
00031 RTM_VAL_ONE,
00032 RTM_VAL_VOID
00033 } Rtm_Init_t;
00034
00035 typedef struct Rtm_Man_t_ Rtm_Man_t;
00036 struct Rtm_Man_t_
00037 {
00038
00039 Vec_Ptr_t * vObjs;
00040 Vec_Ptr_t * vPis;
00041 Vec_Ptr_t * vPos;
00042 Aig_MmFlex_t * pMem;
00043
00044
00045 unsigned * pExtra;
00046 int nExtraCur;
00047 int nExtraAlloc;
00048 };
00049
00050 typedef struct Rtm_Edg_t_ Rtm_Edg_t;
00051 struct Rtm_Edg_t_
00052 {
00053 unsigned long nLats : 12;
00054 unsigned long LData : 20;
00055 };
00056
00057 typedef struct Rtm_Obj_t_ Rtm_Obj_t;
00058 struct Rtm_Obj_t_
00059 {
00060 void * pCopy;
00061 unsigned long Type : 3;
00062 unsigned long fMark : 1;
00063 unsigned long fAuto : 1;
00064 unsigned long fCompl0 : 1;
00065 unsigned long fCompl1 : 1;
00066 unsigned long nFanins : 8;
00067 unsigned Num : 17;
00068 int Id;
00069 int Temp;
00070 int nFanouts;
00071 void * pFanio[0];
00072 };
00073
00074 static inline Rtm_Obj_t * Rtm_ObjFanin( Rtm_Obj_t * pObj, int i ) { return (Rtm_Obj_t *)pObj->pFanio[2*i]; }
00075 static inline Rtm_Obj_t * Rtm_ObjFanout( Rtm_Obj_t * pObj, int i ) { return (Rtm_Obj_t *)pObj->pFanio[2*(pObj->nFanins+i)]; }
00076 static inline Rtm_Edg_t * Rtm_ObjEdge( Rtm_Obj_t * pObj, int i ) { return (Rtm_Edg_t *)(pObj->pFanio + 2*i + 1); }
00077 static inline Rtm_Edg_t * Rtm_ObjFanoutEdge( Rtm_Obj_t * pObj, int i ) { return (Rtm_Edg_t *)pObj->pFanio[2*(pObj->nFanins+i) + 1]; }
00078
00079 static inline Rtm_Init_t Rtm_InitNot( Rtm_Init_t Val ) { if ( Val == RTM_VAL_ZERO ) return RTM_VAL_ONE; if ( Val == RTM_VAL_ONE ) return RTM_VAL_ZERO; assert( 0 ); return -1; }
00080 static inline Rtm_Init_t Rtm_InitNotCond( Rtm_Init_t Val, int c ) { return c ? Rtm_InitNot(Val) : Val; }
00081 static inline Rtm_Init_t Rtm_InitAnd(Rtm_Init_t ValA, Rtm_Init_t ValB ) { if ( ValA == RTM_VAL_ONE && ValB == RTM_VAL_ONE ) return RTM_VAL_ONE; if ( ValA == RTM_VAL_ZERO || ValB == RTM_VAL_ZERO ) return RTM_VAL_ZERO; assert( 0 ); return -1; }
00082
00083 static inline int Rtm_InitWordsNum( int nLats ) { return (nLats >> 4) + ((nLats & 15) > 0); }
00084 static inline int Rtm_InitGetTwo( unsigned * p, int i ) { return (p[i>>4] >> ((i & 15)<<1)) & 3; }
00085 static inline void Rtm_InitSetTwo( unsigned * p, int i, int val ) { p[i>>4] |= (val << ((i & 15)<<1)); }
00086 static inline void Rtm_InitXorTwo( unsigned * p, int i, int val ) { p[i>>4] ^= (val << ((i & 15)<<1)); }
00087
00088 static inline Rtm_Init_t Rtm_ObjGetFirst1( Rtm_Edg_t * pEdge ) { return pEdge->LData & 3; }
00089 static inline Rtm_Init_t Rtm_ObjGetLast1( Rtm_Edg_t * pEdge ) { return (pEdge->LData >> ((pEdge->nLats-1)<<1)) & 3; }
00090 static inline Rtm_Init_t Rtm_ObjGetOne1( Rtm_Edg_t * pEdge, int i ) { assert( i < (int)pEdge->nLats ); return (pEdge->LData >> (i << 1)) & 3; }
00091 static inline Rtm_Init_t Rtm_ObjRemFirst1( Rtm_Edg_t * pEdge ) { int Val = pEdge->LData & 3; pEdge->LData >>= 2; assert(pEdge->nLats > 0); pEdge->nLats--; return Val; }
00092 static inline Rtm_Init_t Rtm_ObjRemLast1( Rtm_Edg_t * pEdge ) { int Val = (pEdge->LData >> ((pEdge->nLats-1)<<1)) & 3; pEdge->LData ^= Val << ((pEdge->nLats-1)<<1); assert(pEdge->nLats > 0); pEdge->nLats--; return Val; }
00093 static inline void Rtm_ObjAddFirst1( Rtm_Edg_t * pEdge, Rtm_Init_t Val ) { assert( Val > 0 && Val < 4 ); pEdge->LData = (pEdge->LData << 2) | Val; pEdge->nLats++; }
00094 static inline void Rtm_ObjAddLast1( Rtm_Edg_t * pEdge, Rtm_Init_t Val ) { assert( Val > 0 && Val < 4 ); pEdge->LData |= Val << (pEdge->nLats<<1); pEdge->nLats++; }
00095
00096 static inline Rtm_Init_t Rtm_ObjGetFirst2( Rtm_Man_t * p, Rtm_Edg_t * pEdge ) { return Rtm_InitGetTwo( p->pExtra + pEdge->LData, 0 ); }
00097 static inline Rtm_Init_t Rtm_ObjGetLast2( Rtm_Man_t * p, Rtm_Edg_t * pEdge ) { return Rtm_InitGetTwo( p->pExtra + pEdge->LData, pEdge->nLats - 1 ); }
00098 static inline Rtm_Init_t Rtm_ObjGetOne2( Rtm_Man_t * p, Rtm_Edg_t * pEdge, int i ) { return Rtm_InitGetTwo( p->pExtra + pEdge->LData, i ); }
00099 static Rtm_Init_t Rtm_ObjRemFirst2( Rtm_Man_t * p, Rtm_Edg_t * pEdge );
00100 static inline Rtm_Init_t Rtm_ObjRemLast2( Rtm_Man_t * p, Rtm_Edg_t * pEdge ) { Rtm_Init_t Val = Rtm_ObjGetLast2( p, pEdge ); Rtm_InitXorTwo( p->pExtra + pEdge->LData, pEdge->nLats - 1, Val ); pEdge->nLats--; return Val; }
00101 static void Rtm_ObjAddFirst2( Rtm_Man_t * p, Rtm_Edg_t * pEdge, Rtm_Init_t Val );
00102 static inline void Rtm_ObjAddLast2( Rtm_Man_t * p, Rtm_Edg_t * pEdge, Rtm_Init_t Val ) { Rtm_InitSetTwo( p->pExtra + pEdge->LData, pEdge->nLats, Val ); pEdge->nLats++; }
00103
00104 static void Rtm_ObjTransferToSmall( Rtm_Man_t * p, Rtm_Edg_t * pEdge );
00105 static void Rtm_ObjTransferToBig( Rtm_Man_t * p, Rtm_Edg_t * pEdge );
00106 static void Rtm_ObjTransferToBigger( Rtm_Man_t * p, Rtm_Edg_t * pEdge );
00107
00108 static inline Rtm_Init_t Rtm_ObjGetFirst( Rtm_Man_t * p, Rtm_Edg_t * pEdge ) { return pEdge->nLats > 10? Rtm_ObjGetFirst2(p, pEdge) : Rtm_ObjGetFirst1(pEdge); }
00109 static inline Rtm_Init_t Rtm_ObjGetLast( Rtm_Man_t * p, Rtm_Edg_t * pEdge ) { return pEdge->nLats > 10? Rtm_ObjGetLast2(p, pEdge) : Rtm_ObjGetLast1(pEdge); }
00110 static inline Rtm_Init_t Rtm_ObjGetOne( Rtm_Man_t * p, Rtm_Edg_t * pEdge, int i ) { return pEdge->nLats > 10? Rtm_ObjGetOne2(p, pEdge, i) : Rtm_ObjGetOne1(pEdge, i); }
00111 static Rtm_Init_t Rtm_ObjRemFirst( Rtm_Man_t * p, Rtm_Edg_t * pEdge ) { Rtm_Init_t Res = pEdge->nLats > 10 ? Rtm_ObjRemFirst2(p, pEdge) : Rtm_ObjRemFirst1(pEdge); if ( pEdge->nLats == 10 ) Rtm_ObjTransferToSmall(p, pEdge); return Res; }
00112 static Rtm_Init_t Rtm_ObjRemLast( Rtm_Man_t * p, Rtm_Edg_t * pEdge ) { Rtm_Init_t Res = pEdge->nLats > 10 ? Rtm_ObjRemLast2(p, pEdge) : Rtm_ObjRemLast1(pEdge); if ( pEdge->nLats == 10 ) Rtm_ObjTransferToSmall(p, pEdge); return Res; }
00113 static void Rtm_ObjAddFirst( Rtm_Man_t * p, Rtm_Edg_t * pEdge, Rtm_Init_t Val ) { if ( pEdge->nLats == 10 ) Rtm_ObjTransferToBig(p, pEdge); else if ( (pEdge->nLats & 15) == 15 ) Rtm_ObjTransferToBigger(p, pEdge); if ( pEdge->nLats >= 10 ) Rtm_ObjAddFirst2(p, pEdge, Val); else Rtm_ObjAddFirst1(pEdge, Val); }
00114 static void Rtm_ObjAddLast( Rtm_Man_t * p, Rtm_Edg_t * pEdge, Rtm_Init_t Val ) { if ( pEdge->nLats == 10 ) Rtm_ObjTransferToBig(p, pEdge); else if ( (pEdge->nLats & 15) == 15 ) Rtm_ObjTransferToBigger(p, pEdge); if ( pEdge->nLats >= 10 ) Rtm_ObjAddLast2(p, pEdge, Val); else Rtm_ObjAddLast1(pEdge, Val); }
00115
00116
00117
00118 #define Rtm_ManForEachPi( p, pObj, i ) \
00119 Vec_PtrForEachEntry( p->vPis, pObj, i )
00120
00121 #define Rtm_ManForEachPo( p, pObj, i ) \
00122 Vec_PtrForEachEntry( p->vPos, pObj, i )
00123
00124 #define Rtm_ManForEachObj( p, pObj, i ) \
00125 Vec_PtrForEachEntry( p->vObjs, pObj, i )
00126
00127 #define Rtm_ObjForEachFanin( pObj, pFanin, i ) \
00128 for ( i = 0; i < (int)(pObj)->nFanins && ((pFanin = Rtm_ObjFanin(pObj, i)), 1); i++ )
00129
00130 #define Rtm_ObjForEachFanout( pObj, pFanout, i ) \
00131 for ( i = 0; i < (int)(pObj)->nFanouts && ((pFanout = Rtm_ObjFanout(pObj, i)), 1); i++ )
00132
00133 #define Rtm_ObjForEachFaninEdge( pObj, pEdge, i ) \
00134 for ( i = 0; i < (int)(pObj)->nFanins && ((pEdge = Rtm_ObjEdge(pObj, i)), 1); i++ )
00135
00136 #define Rtm_ObjForEachFanoutEdge( pObj, pEdge, i ) \
00137 for ( i = 0; i < (int)(pObj)->nFanouts && ((pEdge = Rtm_ObjFanoutEdge(pObj, i)), 1); i++ )
00138
00142
00154 void Rtm_ObjTransferToSmall( Rtm_Man_t * p, Rtm_Edg_t * pEdge )
00155 {
00156 assert( pEdge->nLats == 10 );
00157 pEdge->LData = p->pExtra[pEdge->LData];
00158 }
00159
00171 void Rtm_ObjTransferToBig( Rtm_Man_t * p, Rtm_Edg_t * pEdge )
00172 {
00173 assert( pEdge->nLats == 10 );
00174 if ( p->nExtraCur + 1 > p->nExtraAlloc )
00175 {
00176 int nExtraAllocNew = AIG_MAX( 2 * p->nExtraAlloc, 1024 );
00177 p->pExtra = REALLOC( unsigned, p->pExtra, nExtraAllocNew );
00178 p->nExtraAlloc = nExtraAllocNew;
00179 }
00180 p->pExtra[p->nExtraCur] = pEdge->LData;
00181 pEdge->LData = p->nExtraCur++;
00182 }
00183
00195 void Rtm_ObjTransferToBigger( Rtm_Man_t * p, Rtm_Edg_t * pEdge )
00196 {
00197 int nWords;
00198 assert( (pEdge->nLats & 15) == 15 );
00199 nWords = (pEdge->nLats + 1) >> 4;
00200 if ( p->nExtraCur + nWords + 1 > p->nExtraAlloc )
00201 {
00202 int nExtraAllocNew = AIG_MAX( 2 * p->nExtraAlloc, 1024 );
00203 p->pExtra = REALLOC( unsigned, p->pExtra, nExtraAllocNew );
00204 p->nExtraAlloc = nExtraAllocNew;
00205 }
00206 memcpy( p->pExtra + p->nExtraCur, p->pExtra + pEdge->LData, sizeof(unsigned) * nWords );
00207 p->pExtra[p->nExtraCur + nWords] = 0;
00208 pEdge->LData = p->nExtraCur;
00209 p->nExtraCur += nWords + 1;
00210 }
00211
00223 Rtm_Init_t Rtm_ObjRemFirst2( Rtm_Man_t * p, Rtm_Edg_t * pEdge )
00224 {
00225 Rtm_Init_t Val = 0, Temp;
00226 unsigned * pB = p->pExtra + pEdge->LData, * pE = pB + Rtm_InitWordsNum( pEdge->nLats-- ) - 1;
00227 while ( pE >= pB )
00228 {
00229 Temp = *pE & 3;
00230 *pE = (*pE >> 2) | (Val << 30);
00231 Val = Temp;
00232 pE--;
00233 }
00234 assert( Val != 0 );
00235 return Val;
00236 }
00237
00249 void Rtm_ObjAddFirst2( Rtm_Man_t * p, Rtm_Edg_t * pEdge, Rtm_Init_t Val )
00250 {
00251 unsigned * pB = p->pExtra + pEdge->LData, * pE = pB + Rtm_InitWordsNum( ++pEdge->nLats );
00252 Rtm_Init_t Temp;
00253 assert( Val != 0 );
00254 while ( pB < pE )
00255 {
00256 Temp = *pB >> 30;
00257 *pB = (*pB << 2) | Val;
00258 Val = Temp;
00259 pB++;
00260 }
00261 }
00262
00274 void Rtm_PrintEdge( Rtm_Man_t * p, Rtm_Edg_t * pEdge )
00275 {
00276
00277 printf( "%d : ", pEdge->nLats );
00278
00279
00280
00281
00282
00283
00284 printf( "\n" );
00285 }
00286
00287
00299 Rtm_Man_t * Rtm_ManAlloc( Aig_Man_t * p )
00300 {
00301 Rtm_Man_t * pRtm;
00302
00303 pRtm = ALLOC( Rtm_Man_t, 1 );
00304 memset( pRtm, 0, sizeof(Rtm_Man_t) );
00305
00306 pRtm->vObjs = Vec_PtrAlloc( Aig_ManObjNum(p) );
00307 pRtm->vPis = Vec_PtrAlloc( Aig_ManPiNum(p) );
00308 pRtm->vPos = Vec_PtrAlloc( Aig_ManPoNum(p) );
00309 pRtm->pMem = Aig_MmFlexStart();
00310 return pRtm;
00311 }
00312
00324 void Rtm_ManFree( Rtm_Man_t * p )
00325 {
00326 Vec_PtrFree( p->vObjs );
00327 Vec_PtrFree( p->vPis );
00328 Vec_PtrFree( p->vPos );
00329 Aig_MmFlexStop( p->pMem, 0 );
00330 FREE( p->pExtra );
00331 free( p );
00332 }
00333
00345 int Rtm_ManLatchMax( Rtm_Man_t * p )
00346 {
00347 Rtm_Obj_t * pObj;
00348 Rtm_Edg_t * pEdge;
00349 int nLatchMax = 0, i, k;
00350 Rtm_ManForEachObj( p, pObj, i )
00351 Rtm_ObjForEachFaninEdge( pObj, pEdge, k )
00352 {
00353
00354
00355
00356
00357
00358
00359
00360 nLatchMax = AIG_MAX( nLatchMax, (int)pEdge->nLats );
00361 }
00362 return nLatchMax;
00363 }
00364
00376 Rtm_Obj_t * Rtm_ObjAlloc( Rtm_Man_t * pRtm, int nFanins, int nFanouts )
00377 {
00378 Rtm_Obj_t * pObj;
00379 int Size = sizeof(Rtm_Obj_t) + sizeof(Rtm_Obj_t *) * (nFanins + nFanouts) * 2;
00380 pObj = (Rtm_Obj_t *)Aig_MmFlexEntryFetch( pRtm->pMem, Size );
00381 memset( pObj, 0, sizeof(Rtm_Obj_t) );
00382 pObj->Type = (int)(nFanins == 1 && nFanouts == 0);
00383 pObj->Num = nFanins;
00384 pObj->Temp = nFanouts;
00385 pObj->Id = Vec_PtrSize(pRtm->vObjs);
00386 Vec_PtrPush( pRtm->vObjs, pObj );
00387 return pObj;
00388 }
00389
00401 void Rtm_ObjAddFanin( Rtm_Obj_t * pObj, Rtm_Obj_t * pFanin, int fCompl )
00402 {
00403 pObj->pFanio[ 2*pObj->nFanins ] = pFanin;
00404 pObj->pFanio[ 2*pObj->nFanins + 1 ] = NULL;
00405 pFanin->pFanio[ 2*(pFanin->Num + pFanin->nFanouts) ] = pObj;
00406 pFanin->pFanio[ 2*(pFanin->Num + pFanin->nFanouts) + 1 ] = pObj->pFanio + 2*pObj->nFanins + 1;
00407 if ( pObj->nFanins == 0 )
00408 pObj->fCompl0 = fCompl;
00409 else if ( pObj->nFanins == 1 )
00410 pObj->fCompl1 = fCompl;
00411 else
00412 assert( 0 );
00413 pObj->nFanins++;
00414 pFanin->nFanouts++;
00415 assert( pObj->nFanins <= pObj->Num );
00416 assert( pFanin->nFanouts <= pFanin->Temp );
00417 }
00418
00430 int Rtm_ObjCheckRetimeFwd( Rtm_Obj_t * pObj )
00431 {
00432 Rtm_Edg_t * pEdge;
00433 int i;
00434 Rtm_ObjForEachFaninEdge( pObj, pEdge, i )
00435 if ( pEdge->nLats == 0 )
00436 return 0;
00437 return 1;
00438 }
00439
00451 int Rtm_ObjCheckRetimeBwd( Rtm_Obj_t * pObj )
00452 {
00453 Rtm_Edg_t * pEdge;
00454 int i;
00455 Rtm_ObjForEachFanoutEdge( pObj, pEdge, i )
00456 if ( pEdge->nLats == 0 )
00457 return 0;
00458 return 1;
00459 }
00460
00472 int Rtm_ObjGetDegreeFwd( Rtm_Obj_t * pObj )
00473 {
00474 Rtm_Obj_t * pFanin;
00475 int i, Degree = 0;
00476 Rtm_ObjForEachFanin( pObj, pFanin, i )
00477 Degree = AIG_MAX( Degree, (int)pFanin->Num );
00478 return Degree + 1;
00479 }
00480
00492 int Rtm_ObjGetDegreeBwd( Rtm_Obj_t * pObj )
00493 {
00494 Rtm_Obj_t * pFanout;
00495 int i, Degree = 0;
00496 Rtm_ObjForEachFanout( pObj, pFanout, i )
00497 Degree = AIG_MAX( Degree, (int)pFanout->Num );
00498 return Degree + 1;
00499 }
00500
00512 void Rtm_ObjRetimeFwd( Rtm_Man_t * pRtm, Rtm_Obj_t * pObj )
00513 {
00514 Rtm_Init_t ValTotal, ValCur;
00515 Rtm_Edg_t * pEdge;
00516 int i;
00517 assert( Rtm_ObjCheckRetimeFwd(pObj) );
00518
00519 ValTotal = RTM_VAL_ONE;
00520 Rtm_ObjForEachFaninEdge( pObj, pEdge, i )
00521 {
00522 ValCur = Rtm_ObjRemFirst( pRtm, pEdge );
00523 ValCur = Rtm_InitNotCond( ValCur, i? pObj->fCompl1 : pObj->fCompl0 );
00524 ValTotal = Rtm_InitAnd( ValTotal, ValCur );
00525 }
00526
00527 Rtm_ObjForEachFanoutEdge( pObj, pEdge, i )
00528 Rtm_ObjAddLast( pRtm, pEdge, ValTotal );
00529 }
00530
00542 void Rtm_ObjRetimeBwd( Rtm_Man_t * pRtm, Rtm_Obj_t * pObj )
00543 {
00544 Rtm_Edg_t * pEdge;
00545 int i;
00546 assert( Rtm_ObjCheckRetimeBwd(pObj) );
00547
00548 Rtm_ObjForEachFanoutEdge( pObj, pEdge, i )
00549 Rtm_ObjRemLast( pRtm, pEdge );
00550
00551 Rtm_ObjForEachFaninEdge( pObj, pEdge, i )
00552 Rtm_ObjAddFirst( pRtm, pEdge, RTM_VAL_VOID );
00553 }
00554
00566 void Rtm_ObjMarkAutoFwd_rec( Rtm_Obj_t * pObj )
00567 {
00568 Rtm_Obj_t * pFanout;
00569 int i;
00570 if ( pObj->fAuto )
00571 return;
00572 pObj->fAuto = 1;
00573 Rtm_ObjForEachFanout( pObj, pFanout, i )
00574 Rtm_ObjMarkAutoFwd_rec( pFanout );
00575 }
00576
00588 int Rtm_ManMarkAutoFwd( Rtm_Man_t * pRtm )
00589 {
00590 Rtm_Obj_t * pObjRtm;
00591 int i, Counter = 0;
00592
00593 pObjRtm = Vec_PtrEntry( pRtm->vObjs, 0 );
00594 Rtm_ObjMarkAutoFwd_rec( pObjRtm );
00595 Rtm_ManForEachPi( pRtm, pObjRtm, i )
00596 Rtm_ObjMarkAutoFwd_rec( pObjRtm );
00597
00598 Rtm_ManForEachObj( pRtm, pObjRtm, i )
00599 {
00600 pObjRtm->fAuto = !pObjRtm->fAuto;
00601 Counter += pObjRtm->fAuto;
00602 }
00603
00604 return Counter;
00605 }
00606
00618 void Rtm_ObjMarkAutoBwd_rec( Rtm_Obj_t * pObj )
00619 {
00620 Rtm_Obj_t * pFanin;
00621 int i;
00622 if ( pObj->fAuto )
00623 return;
00624 pObj->fAuto = 1;
00625 Rtm_ObjForEachFanin( pObj, pFanin, i )
00626 Rtm_ObjMarkAutoBwd_rec( pFanin );
00627 }
00628
00640 int Rtm_ManMarkAutoBwd( Rtm_Man_t * pRtm )
00641 {
00642 Rtm_Obj_t * pObjRtm;
00643 int i, Counter = 0;
00644
00645 pObjRtm = Vec_PtrEntry( pRtm->vObjs, 0 );
00646 pObjRtm->fAuto = 1;
00647 Rtm_ManForEachPi( pRtm, pObjRtm, i )
00648 pObjRtm->fAuto = 1;
00649 Rtm_ManForEachPo( pRtm, pObjRtm, i )
00650 Rtm_ObjMarkAutoBwd_rec( pObjRtm );
00651
00652 Rtm_ManForEachObj( pRtm, pObjRtm, i )
00653 {
00654 pObjRtm->fAuto = !pObjRtm->fAuto;
00655 Counter += pObjRtm->fAuto;
00656 }
00657
00658 return Counter;
00659 }
00660
00672 Rtm_Man_t * Rtm_ManFromAig( Aig_Man_t * p )
00673 {
00674 Rtm_Man_t * pRtm;
00675 Aig_Obj_t * pObj, * pObjLi, * pObjLo;
00676 int i;
00677 assert( Aig_ManRegNum(p) > 0 );
00678 assert( Aig_ManBufNum(p) == 0 );
00679
00680 pRtm = Rtm_ManAlloc( p );
00681
00682 pObj = Aig_ManConst1(p);
00683 pObj->pData = Rtm_ObjAlloc( pRtm, 0, pObj->nRefs );
00684 Aig_ManForEachPiSeq( p, pObj, i )
00685 {
00686 pObj->pData = Rtm_ObjAlloc( pRtm, 0, pObj->nRefs );
00687 Vec_PtrPush( pRtm->vPis, pObj->pData );
00688 }
00689 Aig_ManForEachPoSeq( p, pObj, i )
00690 {
00691 pObj->pData = Rtm_ObjAlloc( pRtm, 1, 0 );
00692 Vec_PtrPush( pRtm->vPos, pObj->pData );
00693 }
00694 Aig_ManForEachLoSeq( p, pObj, i )
00695 pObj->pData = Rtm_ObjAlloc( pRtm, 1, pObj->nRefs );
00696 Aig_ManForEachLiSeq( p, pObj, i )
00697 pObj->pData = Rtm_ObjAlloc( pRtm, 1, 1 );
00698 Aig_ManForEachNode( p, pObj, i )
00699 pObj->pData = Rtm_ObjAlloc( pRtm, 2, pObj->nRefs );
00700
00701 Aig_ManForEachPoSeq( p, pObj, i )
00702 Rtm_ObjAddFanin( pObj->pData, Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) );
00703 Aig_ManForEachLiSeq( p, pObj, i )
00704 Rtm_ObjAddFanin( pObj->pData, Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) );
00705 Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
00706 Rtm_ObjAddFanin( pObjLo->pData, pObjLi->pData, 0 );
00707 Aig_ManForEachNode( p, pObj, i )
00708 {
00709 Rtm_ObjAddFanin( pObj->pData, Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) );
00710 Rtm_ObjAddFanin( pObj->pData, Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) );
00711 }
00712 return pRtm;
00713 }
00714
00726 Aig_Obj_t * Rtm_ManToAig_rec( Aig_Man_t * pNew, Rtm_Man_t * pRtm, Rtm_Obj_t * pObjRtm, int * pLatches )
00727 {
00728 Rtm_Edg_t * pEdge;
00729 Aig_Obj_t * pRes, * pFanin;
00730 int k, Val;
00731 if ( pObjRtm->pCopy )
00732 return pObjRtm->pCopy;
00733
00734 pRes = Aig_ManConst1( pNew );
00735 Rtm_ObjForEachFaninEdge( pObjRtm, pEdge, k )
00736 {
00737 if ( pEdge->nLats == 0 )
00738 pFanin = Rtm_ManToAig_rec( pNew, pRtm, Rtm_ObjFanin(pObjRtm, k), pLatches );
00739 else
00740 {
00741 Val = Rtm_ObjGetFirst( pRtm, pEdge );
00742 pFanin = Aig_ManPi( pNew, pLatches[2*pObjRtm->Id + k] + pEdge->nLats - 1 );
00743 pFanin = Aig_NotCond( pFanin, Val == RTM_VAL_ONE );
00744 }
00745 pFanin = Aig_NotCond( pFanin, k ? pObjRtm->fCompl1 : pObjRtm->fCompl0 );
00746 pRes = Aig_And( pNew, pRes, pFanin );
00747 }
00748 return pObjRtm->pCopy = pRes;
00749 }
00750
00762 Aig_Man_t * Rtm_ManToAig( Rtm_Man_t * pRtm )
00763 {
00764 Aig_Man_t * pNew;
00765 Aig_Obj_t * pObjNew;
00766 Rtm_Obj_t * pObjRtm;
00767 Rtm_Edg_t * pEdge;
00768 int i, k, m, Val, nLatches, * pLatches;
00769
00770 pLatches = ALLOC( int, 2 * Vec_PtrSize(pRtm->vObjs) );
00771 nLatches = 0;
00772 Rtm_ManForEachObj( pRtm, pObjRtm, i )
00773 Rtm_ObjForEachFaninEdge( pObjRtm, pEdge, k )
00774 {
00775 pLatches[2*pObjRtm->Id + k] = Vec_PtrSize(pRtm->vPis) + nLatches;
00776 nLatches += pEdge->nLats;
00777 }
00778
00779 pNew = Aig_ManStart( Vec_PtrSize(pRtm->vObjs) + nLatches );
00780
00781 pObjRtm = Vec_PtrEntry( pRtm->vObjs, 0 );
00782 pObjRtm->pCopy = Aig_ManConst1(pNew);
00783 Rtm_ManForEachPi( pRtm, pObjRtm, i )
00784 pObjRtm->pCopy = Aig_ObjCreatePi(pNew);
00785 for ( i = 0; i < nLatches; i++ )
00786 Aig_ObjCreatePi(pNew);
00787
00788 Rtm_ManForEachObj( pRtm, pObjRtm, i )
00789 Rtm_ManToAig_rec( pNew, pRtm, pObjRtm, pLatches );
00790
00791 Rtm_ManForEachPo( pRtm, pObjRtm, i )
00792 Aig_ObjCreatePo( pNew, pObjRtm->pCopy );
00793
00794 Rtm_ManForEachObj( pRtm, pObjRtm, i )
00795 Rtm_ObjForEachFaninEdge( pObjRtm, pEdge, k )
00796 {
00797 if ( pEdge->nLats == 0 )
00798 continue;
00799 pObjNew = Rtm_ObjFanin( pObjRtm, k )->pCopy;
00800 for ( m = 0; m < (int)pEdge->nLats; m++ )
00801 {
00802 Val = Rtm_ObjGetOne( pRtm, pEdge, pEdge->nLats - 1 - m );
00803 assert( Val == RTM_VAL_ZERO || Val == RTM_VAL_ONE || Val == RTM_VAL_VOID );
00804 pObjNew = Aig_NotCond( pObjNew, Val == RTM_VAL_ONE );
00805 Aig_ObjCreatePo( pNew, pObjNew );
00806 pObjNew = Aig_ManPi( pNew, pLatches[2*pObjRtm->Id + k] + m );
00807 pObjNew = Aig_NotCond( pObjNew, Val == RTM_VAL_ONE );
00808 }
00809
00810 }
00811 free( pLatches );
00812 pNew->nRegs = nLatches;
00813
00814 Aig_ManCleanup( pNew );
00815 if ( !Aig_ManCheck( pNew ) )
00816 printf( "Rtm_ManToAig: The network check has failed.\n" );
00817 return pNew;
00818 }
00819
00831 Aig_Man_t * Rtm_ManRetime( Aig_Man_t * p, int fForward, int nStepsMax, int fVerbose )
00832 {
00833 Vec_Ptr_t * vQueue;
00834 Aig_Man_t * pNew;
00835 Rtm_Man_t * pRtm;
00836 Rtm_Obj_t * pObj, * pNext;
00837 Aig_Obj_t * pObjAig;
00838 int i, k, nAutos, Degree, DegreeMax = 0;
00839 int clk;
00840
00841
00842 clk = clock();
00843 pRtm = Rtm_ManFromAig( p );
00844
00845 Aig_ManForEachLoSeq( p, pObjAig, i )
00846 Rtm_ObjAddFirst( pRtm, Rtm_ObjEdge(pObjAig->pData, 0), fForward? RTM_VAL_ZERO : RTM_VAL_VOID );
00847
00848 if ( fForward )
00849 nAutos = Rtm_ManMarkAutoFwd( pRtm );
00850 else
00851 nAutos = Rtm_ManMarkAutoBwd( pRtm );
00852 if ( fVerbose )
00853 {
00854 printf( "Detected %d autonomous objects. ", nAutos );
00855 PRT( "Time", clock() - clk );
00856 }
00857
00858
00859 Rtm_ManForEachObj( pRtm, pObj, i )
00860 {
00861 assert( pObj->nFanins == pObj->Num );
00862 assert( pObj->nFanouts == pObj->Temp );
00863 pObj->Num = 0;
00864 }
00865
00866 clk = clock();
00867
00868 vQueue = Vec_PtrAlloc( 1000 );
00869 if ( fForward )
00870 {
00871 Aig_ManForEachLoSeq( p, pObjAig, i )
00872 {
00873 pObj = pObjAig->pData;
00874 if ( pObj->fAuto )
00875 continue;
00876 pObj->fMark = 1;
00877 Vec_PtrPush( vQueue, pObj );
00878 }
00879 }
00880 else
00881 {
00882 Aig_ManForEachLiSeq( p, pObjAig, i )
00883 {
00884 pObj = pObjAig->pData;
00885 if ( pObj->fAuto )
00886 continue;
00887 pObj->fMark = 1;
00888 Vec_PtrPush( vQueue, pObj );
00889 }
00890 }
00891
00892 DegreeMax = 0;
00893 Vec_PtrForEachEntry( vQueue, pObj, i )
00894 {
00895 pObj->fMark = 0;
00896
00897 if ( fForward )
00898 {
00899 Rtm_ObjRetimeFwd( pRtm, pObj );
00900
00901 Rtm_ObjForEachFanout( pObj, pNext, k )
00902 {
00903 if ( pNext->fMark )
00904 continue;
00905 if ( pNext->Type )
00906 continue;
00907 if ( !Rtm_ObjCheckRetimeFwd( pNext ) )
00908 continue;
00909 Degree = Rtm_ObjGetDegreeFwd( pNext );
00910 DegreeMax = AIG_MAX( DegreeMax, Degree );
00911 if ( Degree > nStepsMax )
00912 continue;
00913 pNext->fMark = 1;
00914 pNext->Num = Degree;
00915 Vec_PtrPush( vQueue, pNext );
00916 }
00917 }
00918 else
00919 {
00920 Rtm_ObjRetimeBwd( pRtm, pObj );
00921
00922 Rtm_ObjForEachFanin( pObj, pNext, k )
00923 {
00924 if ( pNext->fMark )
00925 continue;
00926 if ( pNext->nFanins == 0 )
00927 continue;
00928 if ( !Rtm_ObjCheckRetimeBwd( pNext ) )
00929 continue;
00930 Degree = Rtm_ObjGetDegreeBwd( pNext );
00931 DegreeMax = AIG_MAX( DegreeMax, Degree );
00932 if ( Degree > nStepsMax )
00933 continue;
00934 pNext->fMark = 1;
00935 pNext->Num = Degree;
00936 Vec_PtrPush( vQueue, pNext );
00937 }
00938 }
00939 }
00940
00941 if ( fVerbose )
00942 {
00943 printf( "Performed %d %s latch moves of max depth %d and max latch count %d.\n",
00944 Vec_PtrSize(vQueue), fForward? "fwd":"bwd", DegreeMax, Rtm_ManLatchMax(pRtm) );
00945 printf( "Memory usage = %d. ", pRtm->nExtraCur );
00946 PRT( "Time", clock() - clk );
00947 }
00948 Vec_PtrFree( vQueue );
00949
00950
00951 pNew = Rtm_ManToAig( pRtm );
00952 pNew->pName = Aig_UtilStrsav( p->pName );
00953 Rtm_ManFree( pRtm );
00954
00955 clk = clock();
00956 pNew = Aig_ManReduceLaches( pNew, fVerbose );
00957 if ( fVerbose )
00958 {
00959 PRT( "Register sharing time", clock() - clk );
00960 }
00961 return pNew;
00962 }
00963
00964
00968
00969