00001
00021 #include "abc.h"
00022
00026
00030
00042 bool Abc_NtkLatchIsSelfFeed_rec( Abc_Obj_t * pLatch, Abc_Obj_t * pLatchRoot )
00043 {
00044 Abc_Obj_t * pFanin;
00045 assert( Abc_ObjIsLatch(pLatch) );
00046 if ( pLatch == pLatchRoot )
00047 return 1;
00048 pFanin = Abc_ObjFanin0(Abc_ObjFanin0(pLatch));
00049 if ( !Abc_ObjIsBo(pFanin) || !Abc_ObjIsLatch(Abc_ObjFanin0(pFanin)) )
00050 return 0;
00051 return Abc_NtkLatchIsSelfFeed_rec( Abc_ObjFanin0(pFanin), pLatch );
00052 }
00053
00065 bool Abc_NtkLatchIsSelfFeed( Abc_Obj_t * pLatch )
00066 {
00067 Abc_Obj_t * pFanin;
00068 assert( Abc_ObjIsLatch(pLatch) );
00069 pFanin = Abc_ObjFanin0(Abc_ObjFanin0(pLatch));
00070 if ( !Abc_ObjIsBo(pFanin) || !Abc_ObjIsLatch(Abc_ObjFanin0(pFanin)) )
00071 return 0;
00072 return Abc_NtkLatchIsSelfFeed_rec( Abc_ObjFanin0(pFanin), pLatch );
00073 }
00074
00086 int Abc_NtkCountSelfFeedLatches( Abc_Ntk_t * pNtk )
00087 {
00088 Abc_Obj_t * pLatch;
00089 int i, Counter;
00090 Counter = 0;
00091 Abc_NtkForEachLatch( pNtk, pLatch, i )
00092 {
00093
00094
00095 Counter += Abc_NtkLatchIsSelfFeed( pLatch );
00096 }
00097 return Counter;
00098 }
00099
00111 int Abc_NtkRemoveSelfFeedLatches( Abc_Ntk_t * pNtk )
00112 {
00113 Abc_Obj_t * pLatch, * pConst1;
00114 int i, Counter;
00115 Counter = 0;
00116 Abc_NtkForEachLatch( pNtk, pLatch, i )
00117 {
00118 if ( Abc_NtkLatchIsSelfFeed( pLatch ) )
00119 {
00120 if ( Abc_NtkIsStrash(pNtk) )
00121 pConst1 = Abc_AigConst1(pNtk);
00122 else
00123 pConst1 = Abc_NtkCreateNodeConst1(pNtk);
00124 Abc_ObjPatchFanin( Abc_ObjFanin0(pLatch), Abc_ObjFanin0(Abc_ObjFanin0(pLatch)), pConst1 );
00125 Counter++;
00126 }
00127 }
00128 return Counter;
00129 }
00130
00142 void Abc_NtkLatchPipe( Abc_Ntk_t * pNtk, int nLatches )
00143 {
00144 Vec_Ptr_t * vNodes;
00145 Abc_Obj_t * pObj, * pLatch, * pFanin, * pFanout;
00146 int i, k, nTotal, nDigits;
00147 if ( nLatches < 1 )
00148 return;
00149 nTotal = nLatches * Abc_NtkPiNum(pNtk);
00150 nDigits = Extra_Base10Log( nTotal );
00151 vNodes = Vec_PtrAlloc( 100 );
00152 Abc_NtkForEachPi( pNtk, pObj, i )
00153 {
00154
00155 Abc_NodeCollectFanouts( pObj, vNodes );
00156
00157 for ( pFanin = pObj, k = 0; k < nLatches; k++, pFanin = pLatch )
00158 {
00159 pLatch = Abc_NtkCreateLatch( pNtk );
00160 Abc_ObjAddFanin( pLatch, pFanin );
00161 Abc_LatchSetInitDc( pLatch );
00162
00163 Abc_ObjAssignName( pLatch, Abc_ObjNameDummy("LL", i*nLatches + k, nDigits), NULL );
00164 }
00165
00166 Vec_PtrForEachEntry( vNodes, pFanout, k )
00167 Abc_ObjPatchFanin( pFanout, pObj, pFanin );
00168 }
00169 Vec_PtrFree( vNodes );
00170 Abc_NtkLogicMakeSimpleCos( pNtk, 0 );
00171 }
00172
00184 Vec_Int_t * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk )
00185 {
00186 Vec_Int_t * vValues;
00187 Abc_Obj_t * pLatch;
00188 int i;
00189 vValues = Vec_IntAlloc( Abc_NtkLatchNum(pNtk) );
00190 Abc_NtkForEachLatch( pNtk, pLatch, i )
00191 Vec_IntPush( vValues, Abc_LatchIsInit1(pLatch) );
00192 return vValues;
00193 }
00194
00206 void Abc_NtkInsertLatchValues( Abc_Ntk_t * pNtk, Vec_Int_t * vValues )
00207 {
00208 Abc_Obj_t * pLatch;
00209 int i;
00210 Abc_NtkForEachLatch( pNtk, pLatch, i )
00211 pLatch->pData = (void *)(vValues? (Vec_IntEntry(vValues,i)? ABC_INIT_ONE : ABC_INIT_ZERO) : ABC_INIT_DC);
00212 }
00213
00225 Abc_Obj_t * Abc_NtkAddLatch( Abc_Ntk_t * pNtk, Abc_Obj_t * pDriver, Abc_InitType_t Init )
00226 {
00227 Abc_Obj_t * pLatchOut, * pLatch, * pLatchIn;
00228 pLatchOut = Abc_NtkCreateBo(pNtk);
00229 pLatch = Abc_NtkCreateLatch(pNtk);
00230 pLatchIn = Abc_NtkCreateBi(pNtk);
00231 Abc_ObjAssignName( pLatchOut, Abc_ObjName(pLatch), "_lo" );
00232 Abc_ObjAssignName( pLatchIn, Abc_ObjName(pLatch), "_li" );
00233 Abc_ObjAddFanin( pLatchOut, pLatch );
00234 Abc_ObjAddFanin( pLatch, pLatchIn );
00235 Abc_ObjAddFanin( pLatchIn, pDriver );
00236 pLatch->pData = (void *)Init;
00237 return pLatchOut;
00238 }
00239
00251 void Abc_NtkNodeConvertToMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0, Abc_Obj_t * pMux )
00252 {
00253 assert( Abc_NtkIsLogic(pNtk) );
00254 Abc_ObjAddFanin( pMux, pNodeC );
00255 Abc_ObjAddFanin( pMux, pNode1 );
00256 Abc_ObjAddFanin( pMux, pNode0 );
00257 if ( Abc_NtkHasSop(pNtk) )
00258 pMux->pData = Abc_SopRegister( pNtk->pManFunc, "11- 1\n0-1 1\n" );
00259 else if ( Abc_NtkHasBdd(pNtk) )
00260 pMux->pData = Cudd_bddIte(pNtk->pManFunc,Cudd_bddIthVar(pNtk->pManFunc,0),Cudd_bddIthVar(pNtk->pManFunc,1),Cudd_bddIthVar(pNtk->pManFunc,2)), Cudd_Ref( pMux->pData );
00261 else if ( Abc_NtkHasAig(pNtk) )
00262 pMux->pData = Hop_Mux(pNtk->pManFunc,Hop_IthVar(pNtk->pManFunc,0),Hop_IthVar(pNtk->pManFunc,1),Hop_IthVar(pNtk->pManFunc,2));
00263 else
00264 assert( 0 );
00265 }
00266
00278 void Abc_NtkConvertDcLatches( Abc_Ntk_t * pNtk )
00279 {
00280 Abc_Obj_t * pCtrl, * pLatch, * pMux, * pPi;
00281 Abc_InitType_t Init = ABC_INIT_ZERO;
00282 int i, fFound = 0, Counter;
00283
00284 Abc_NtkForEachLatch( pNtk, pLatch, i )
00285 if ( Abc_LatchIsInitDc(pLatch) )
00286 {
00287 fFound = 1;
00288 break;
00289 }
00290 if ( !fFound )
00291 return;
00292
00293 pCtrl = Abc_NtkAddLatch( pNtk, Abc_NtkCreateNodeConst1(pNtk), Init );
00294
00295 Counter = 0;
00296 Abc_NtkForEachLatch( pNtk, pLatch, i )
00297 {
00298 if ( !Abc_LatchIsInitDc(pLatch) )
00299 continue;
00300
00301 pLatch->pData = (void *)Init;
00302
00303 if ( Abc_NodeFindCoFanout( Abc_ObjFanout0(pLatch) ) )
00304 {
00305 Nm_ManDeleteIdName( pLatch->pNtk->pManName, Abc_ObjFanout0(pLatch)->Id );
00306 Abc_ObjAssignName( Abc_ObjFanout0(pLatch), Abc_ObjName(pLatch), "_lo" );
00307 }
00308
00309 pPi = Abc_NtkCreatePi( pNtk );
00310 Abc_ObjAssignName( pPi, Abc_ObjName(pLatch), "_pi" );
00311
00312 pMux = Abc_NtkCreateNode( pNtk );
00313 Abc_ObjTransferFanout( Abc_ObjFanout0(pLatch), pMux );
00314
00315 Abc_NtkNodeConvertToMux( pNtk, pCtrl, Abc_ObjFanout0(pLatch), pPi, pMux );
00316 Counter++;
00317 }
00318 printf( "The number of converted latches with DC values = %d.\n", Counter );
00319 }
00320
00321
00325
00326