00001
00021 #include "abc.h"
00022 #include "if.h"
00023 #include "kit.h"
00024
00028
00029 static If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars );
00030 static Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk );
00031 extern Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Int_t * vCover );
00032 static Hop_Obj_t * Abc_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj );
00033 static Vec_Ptr_t * Abc_NtkFindGoodOrder( Abc_Ntk_t * pNtk );
00034
00035 extern void Abc_NtkBddReorder( Abc_Ntk_t * pNtk, int fVerbose );
00036
00040
00052 Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
00053 {
00054 Abc_Ntk_t * pNtkNew;
00055 If_Man_t * pIfMan;
00056
00057 assert( Abc_NtkIsStrash(pNtk) );
00058
00059
00060 pPars->pTimesArr = Abc_NtkGetCiArrivalFloats(pNtk);
00061 pPars->pTimesReq = NULL;
00062
00063
00064 if ( pPars->fLatchPaths && pPars->pTimesArr )
00065 {
00066 int c;
00067 for ( c = 0; c < Abc_NtkPiNum(pNtk); c++ )
00068 pPars->pTimesArr[c] = -ABC_INFINITY;
00069 }
00070
00071
00072 pIfMan = Abc_NtkToIf( pNtk, pPars );
00073 if ( pIfMan == NULL )
00074 return NULL;
00075 if ( !If_ManPerformMapping( pIfMan ) )
00076 {
00077 If_ManStop( pIfMan );
00078 return NULL;
00079 }
00080
00081
00082 pNtkNew = Abc_NtkFromIf( pIfMan, pNtk );
00083 if ( pNtkNew == NULL )
00084 return NULL;
00085 If_ManStop( pIfMan );
00086
00087
00088 if ( pNtk->pExdc )
00089 pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
00090
00091
00092 if ( !Abc_NtkCheck( pNtkNew ) )
00093 {
00094 printf( "Abc_NtkIf: The network check has failed.\n" );
00095 Abc_NtkDelete( pNtkNew );
00096 return NULL;
00097 }
00098 return pNtkNew;
00099 }
00100
00112 If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
00113 {
00114 ProgressBar * pProgress;
00115 If_Man_t * pIfMan;
00116 Abc_Obj_t * pNode, * pFanin, * pPrev;
00117 Vec_Ptr_t * vNodes;
00118 int i;
00119
00120 assert( Abc_NtkIsStrash(pNtk) );
00121
00122 vNodes = Abc_AigDfs( pNtk, 0, 0 );
00123
00124
00125 pIfMan = If_ManStart( pPars );
00126
00127
00128 if ( 1.0 * Abc_NtkObjNum(pNtk) * pIfMan->nObjBytes / (1<<30) > 1.0 )
00129 printf( "Warning: The mapper will allocate %.1f Gb for to represent the subject graph with %d AIG nodes.\n",
00130 1.0 * Abc_NtkObjNum(pNtk) * pIfMan->nObjBytes / (1<<30), Abc_NtkObjNum(pNtk) );
00131
00132
00133 Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)If_ManConst1( pIfMan );
00134 Abc_NtkForEachCi( pNtk, pNode, i )
00135 {
00136 pNode->pCopy = (Abc_Obj_t *)If_ManCreateCi( pIfMan );
00137
00138 }
00139
00140
00141 pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
00142
00143 Vec_PtrForEachEntry( vNodes, pNode, i )
00144 {
00145 Extra_ProgressBarUpdate( pProgress, i, "Initial" );
00146
00147 pNode->pCopy = (Abc_Obj_t *)If_ManCreateAnd( pIfMan,
00148 If_NotCond( (If_Obj_t *)Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
00149 If_NotCond( (If_Obj_t *)Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) );
00150
00151 if ( Abc_AigNodeIsChoice( pNode ) )
00152 {
00153 pIfMan->nChoices++;
00154 for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData )
00155 If_ObjSetChoice( (If_Obj_t *)pPrev->pCopy, (If_Obj_t *)pFanin->pCopy );
00156 If_ManCreateChoice( pIfMan, (If_Obj_t *)pNode->pCopy );
00157 }
00158
00159 }
00160 Extra_ProgressBarStop( pProgress );
00161 Vec_PtrFree( vNodes );
00162
00163
00164 Abc_NtkForEachCo( pNtk, pNode, i )
00165 If_ManCreateCo( pIfMan, If_NotCond( (If_Obj_t *)Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ) );
00166 return pIfMan;
00167 }
00168
00180 Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk )
00181 {
00182 ProgressBar * pProgress;
00183 Abc_Ntk_t * pNtkNew;
00184 Abc_Obj_t * pNode, * pNodeNew;
00185 Vec_Int_t * vCover;
00186 int i, nDupGates;
00187
00188 if ( pIfMan->pPars->fUseBdds || pIfMan->pPars->fUseCnfs || pIfMan->pPars->fUseMv )
00189 pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_BDD );
00190 else if ( pIfMan->pPars->fUseSops )
00191 pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
00192 else
00193 pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_AIG );
00194
00195 If_ManCleanNodeCopy( pIfMan );
00196 If_ManCleanCutData( pIfMan );
00197
00198 If_ObjSetCopy( If_ManConst1(pIfMan), Abc_NtkCreateNodeConst1(pNtkNew) );
00199 Abc_NtkForEachCi( pNtk, pNode, i )
00200 If_ObjSetCopy( If_ManCi(pIfMan, i), pNode->pCopy );
00201
00202 vCover = Vec_IntAlloc( 1 << 16 );
00203 pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
00204 Abc_NtkForEachCo( pNtk, pNode, i )
00205 {
00206 Extra_ProgressBarUpdate( pProgress, i, "Final" );
00207 pNodeNew = Abc_NodeFromIf_rec( pNtkNew, pIfMan, If_ObjFanin0(If_ManCo(pIfMan, i)), vCover );
00208 pNodeNew = Abc_ObjNotCond( pNodeNew, If_ObjFaninC0(If_ManCo(pIfMan, i)) );
00209 Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
00210 }
00211 Extra_ProgressBarStop( pProgress );
00212 Vec_IntFree( vCover );
00213
00214 pNodeNew = (Abc_Obj_t *)If_ObjCopy( If_ManConst1(pIfMan) );
00215 if ( Abc_ObjFanoutNum(pNodeNew) == 0 )
00216 Abc_NtkDeleteObj( pNodeNew );
00217
00218 if ( pIfMan->pPars->fUseBdds || pIfMan->pPars->fUseCnfs || pIfMan->pPars->fUseMv )
00219 Abc_NtkSweep( pNtkNew, 0 );
00220 if ( pIfMan->pPars->fUseBdds )
00221 Abc_NtkBddReorder( pNtkNew, 0 );
00222
00223 nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
00224
00225
00226 return pNtkNew;
00227 }
00228
00240 Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Int_t * vCover )
00241 {
00242 Abc_Obj_t * pNodeNew;
00243 If_Cut_t * pCutBest;
00244 If_Obj_t * pIfLeaf;
00245 int i;
00246
00247 pNodeNew = (Abc_Obj_t *)If_ObjCopy( pIfObj );
00248 if ( pNodeNew )
00249 return pNodeNew;
00250 assert( pIfObj->Type == IF_AND );
00251
00252
00253 pNodeNew = Abc_NtkCreateNode( pNtkNew );
00254 pCutBest = If_ObjCutBest( pIfObj );
00255 if ( pIfMan->pPars->fUseCnfs || pIfMan->pPars->fUseMv )
00256 {
00257 If_CutForEachLeafReverse( pIfMan, pCutBest, pIfLeaf, i )
00258 Abc_ObjAddFanin( pNodeNew, Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf, vCover) );
00259 }
00260 else
00261 {
00262 If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, i )
00263 Abc_ObjAddFanin( pNodeNew, Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf, vCover) );
00264 }
00265
00266 pNodeNew->Level = Abc_ObjLevelNew( pNodeNew );
00267
00268 if ( pIfMan->pPars->fTruth )
00269 {
00270 if ( pIfMan->pPars->fUseBdds )
00271 {
00272
00273 pNodeNew->pData = Kit_TruthToBdd( pNtkNew->pManFunc, If_CutTruth(pCutBest), If_CutLeaveNum(pCutBest), 0 ); Cudd_Ref(pNodeNew->pData);
00274 }
00275 else if ( pIfMan->pPars->fUseCnfs || pIfMan->pPars->fUseMv )
00276 {
00277
00278 pNodeNew->pData = Kit_TruthToBdd( pNtkNew->pManFunc, If_CutTruth(pCutBest), If_CutLeaveNum(pCutBest), 1 ); Cudd_Ref(pNodeNew->pData);
00279 }
00280 else if ( pIfMan->pPars->fUseSops )
00281 {
00282
00283 int RetValue = Kit_TruthIsop( If_CutTruth(pCutBest), If_CutLeaveNum(pCutBest), vCover, 1 );
00284 assert( RetValue == 0 || RetValue == 1 );
00285
00286 if ( Vec_IntSize(vCover) == 0 || (Vec_IntSize(vCover) == 1 && Vec_IntEntry(vCover,0) == 0) )
00287 {
00288 assert( RetValue == 0 );
00289 pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, If_CutLeaveNum(pCutBest), NULL );
00290 pNodeNew = (Vec_IntSize(vCover) == 0) ? Abc_NtkCreateNodeConst0(pNtkNew) : Abc_NtkCreateNodeConst1(pNtkNew);
00291 }
00292 else
00293 {
00294
00295 pNodeNew->pData = Abc_SopCreateFromIsop( pNtkNew->pManFunc, If_CutLeaveNum(pCutBest), vCover );
00296 if ( RetValue )
00297 Abc_SopComplement( pNodeNew->pData );
00298 }
00299 }
00300 else
00301 {
00302 extern Hop_Obj_t * Kit_TruthToHop( Hop_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory );
00303 pNodeNew->pData = Kit_TruthToHop( pNtkNew->pManFunc, If_CutTruth(pCutBest), If_CutLeaveNum(pCutBest), vCover );
00304 }
00305
00306 if ( pCutBest->fCompl )
00307 Abc_NodeComplement( pNodeNew );
00308 }
00309 else
00310 pNodeNew->pData = Abc_NodeIfToHop( pNtkNew->pManFunc, pIfMan, pIfObj );
00311 If_ObjSetCopy( pIfObj, pNodeNew );
00312 return pNodeNew;
00313 }
00314
00326 Hop_Obj_t * Abc_NodeIfToHop_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Ptr_t * vVisited )
00327 {
00328 If_Cut_t * pCut;
00329 Hop_Obj_t * gFunc, * gFunc0, * gFunc1;
00330
00331 pCut = If_ObjCutBest(pIfObj);
00332
00333 if ( If_CutData(pCut) )
00334 return If_CutData(pCut);
00335
00336 gFunc0 = Abc_NodeIfToHop_rec( pHopMan, pIfMan, pIfObj->pFanin0, vVisited );
00337 gFunc1 = Abc_NodeIfToHop_rec( pHopMan, pIfMan, pIfObj->pFanin1, vVisited );
00338
00339 gFunc = Hop_And( pHopMan, Hop_NotCond(gFunc0, pIfObj->fCompl0), Hop_NotCond(gFunc1, pIfObj->fCompl1) );
00340 assert( If_CutData(pCut) == NULL );
00341 If_CutSetData( pCut, gFunc );
00342
00343 Vec_PtrPush( vVisited, pCut );
00344 return gFunc;
00345 }
00346
00358 Hop_Obj_t * Abc_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj )
00359 {
00360 If_Cut_t * pCut;
00361 Hop_Obj_t * gFunc;
00362 If_Obj_t * pLeaf;
00363 int i;
00364
00365 pCut = If_ObjCutBest(pIfObj);
00366 assert( pCut->nLeaves > 1 );
00367
00368 If_CutForEachLeaf( pIfMan, pCut, pLeaf, i )
00369 If_CutSetData( If_ObjCutBest(pLeaf), Hop_IthVar(pHopMan, i) );
00370
00371 Vec_PtrClear( pIfMan->vTemp );
00372 gFunc = Abc_NodeIfToHop_rec( pHopMan, pIfMan, pIfObj, pIfMan->vTemp );
00373
00374
00375 If_CutForEachLeaf( pIfMan, pCut, pLeaf, i )
00376 If_CutSetData( If_ObjCutBest(pLeaf), NULL );
00377 Vec_PtrForEachEntry( pIfMan->vTemp, pCut, i )
00378 If_CutSetData( pCut, NULL );
00379 return gFunc;
00380 }
00381
00382
00394 int Abc_ObjCompareFlow( Abc_Obj_t ** ppNode0, Abc_Obj_t ** ppNode1 )
00395 {
00396 float Flow0 = Abc_Int2Float((int)(*ppNode0)->pCopy);
00397 float Flow1 = Abc_Int2Float((int)(*ppNode1)->pCopy);
00398 if ( Flow0 > Flow1 )
00399 return -1;
00400 if ( Flow0 < Flow1 )
00401 return 1;
00402 return 0;
00403 }
00404
00416 void Abc_NtkFindGoodOrder_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
00417 {
00418 if ( !Abc_ObjIsNode(pNode) )
00419 return;
00420 assert( Abc_ObjIsNode( pNode ) );
00421
00422 if ( Abc_NodeIsTravIdCurrent( pNode ) )
00423 return;
00424
00425 Abc_NodeSetTravIdCurrent( pNode );
00426
00427 Abc_NtkFindGoodOrder_rec( Abc_ObjFanin0(pNode), vNodes );
00428 Abc_NtkFindGoodOrder_rec( Abc_ObjFanin1(pNode), vNodes );
00429
00430 Vec_PtrPush( vNodes, pNode );
00431 }
00432
00444 Vec_Ptr_t * Abc_NtkFindGoodOrder( Abc_Ntk_t * pNtk )
00445 {
00446 Vec_Ptr_t * vNodes, * vCos;
00447 Abc_Obj_t * pNode, * pFanin0, * pFanin1;
00448 float Flow0, Flow1;
00449 int i;
00450
00451
00452 Abc_AigConst1(pNtk)->pCopy = NULL;
00453 Abc_NtkForEachCi( pNtk, pNode, i )
00454 pNode->pCopy = NULL;
00455
00456 Abc_AigForEachAnd( pNtk, pNode, i )
00457 {
00458 pFanin0 = Abc_ObjFanin0(pNode);
00459 pFanin1 = Abc_ObjFanin1(pNode);
00460 Flow0 = Abc_Int2Float((int)pFanin0->pCopy)/Abc_ObjFanoutNum(pFanin0);
00461 Flow1 = Abc_Int2Float((int)pFanin1->pCopy)/Abc_ObjFanoutNum(pFanin1);
00462 pNode->pCopy = (Abc_Obj_t *)Abc_Float2Int(Flow0 + Flow1+(float)1.0);
00463 }
00464
00465 vCos = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) );
00466 Abc_NtkForEachCo( pNtk, pNode, i )
00467 {
00468 pNode->pCopy = Abc_ObjFanin0(pNode)->pCopy;
00469
00470 Vec_PtrPush( vCos, pNode );
00471 }
00472
00473
00474 qsort( (Abc_Obj_t **)Vec_PtrArray(vCos), Abc_NtkCoNum(pNtk),
00475 sizeof(Abc_Obj_t *), (int (*)(const void *, const void *))Abc_ObjCompareFlow );
00476
00477 pFanin0 = Vec_PtrEntry(vCos, 0);
00478 pFanin1 = Vec_PtrEntryLast(vCos);
00479 assert( Abc_Int2Float((int)pFanin0->pCopy) >= Abc_Int2Float((int)pFanin1->pCopy) );
00480
00481
00482 Abc_NtkIncrementTravId( pNtk );
00483 vNodes = Vec_PtrAlloc( 100 );
00484 Vec_PtrForEachEntry( vCos, pNode, i )
00485 {
00486 Abc_NtkFindGoodOrder_rec( Abc_ObjFanin0(pNode), vNodes );
00487
00488 }
00489 Vec_PtrFree( vCos );
00490 return vNodes;
00491 }
00492
00496
00497