#include "abc.h"
#include "if.h"
#include "kit.h"
Go to the source code of this file.
Functions | |
static If_Man_t * | Abc_NtkToIf (Abc_Ntk_t *pNtk, If_Par_t *pPars) |
static Abc_Ntk_t * | Abc_NtkFromIf (If_Man_t *pIfMan, Abc_Ntk_t *pNtk) |
Abc_Obj_t * | Abc_NodeFromIf_rec (Abc_Ntk_t *pNtkNew, If_Man_t *pIfMan, If_Obj_t *pIfObj, Vec_Int_t *vCover) |
static Hop_Obj_t * | Abc_NodeIfToHop (Hop_Man_t *pHopMan, If_Man_t *pIfMan, If_Obj_t *pIfObj) |
static Vec_Ptr_t * | Abc_NtkFindGoodOrder (Abc_Ntk_t *pNtk) |
void | Abc_NtkBddReorder (Abc_Ntk_t *pNtk, int fVerbose) |
Abc_Ntk_t * | Abc_NtkIf (Abc_Ntk_t *pNtk, If_Par_t *pPars) |
Hop_Obj_t * | Abc_NodeIfToHop_rec (Hop_Man_t *pHopMan, If_Man_t *pIfMan, If_Obj_t *pIfObj, Vec_Ptr_t *vVisited) |
int | Abc_ObjCompareFlow (Abc_Obj_t **ppNode0, Abc_Obj_t **ppNode1) |
void | Abc_NtkFindGoodOrder_rec (Abc_Obj_t *pNode, Vec_Ptr_t *vNodes) |
Abc_Obj_t * Abc_NodeFromIf_rec | ( | Abc_Ntk_t * | pNtkNew, | |
If_Man_t * | pIfMan, | |||
If_Obj_t * | pIfObj, | |||
Vec_Int_t * | vCover | |||
) |
Function*************************************************************
Synopsis [Derive one node after FPGA mapping.]
Description []
SideEffects []
SeeAlso []
Definition at line 240 of file abcIf.c.
00241 { 00242 Abc_Obj_t * pNodeNew; 00243 If_Cut_t * pCutBest; 00244 If_Obj_t * pIfLeaf; 00245 int i; 00246 // return if the result if known 00247 pNodeNew = (Abc_Obj_t *)If_ObjCopy( pIfObj ); 00248 if ( pNodeNew ) 00249 return pNodeNew; 00250 assert( pIfObj->Type == IF_AND ); 00251 // get the parameters of the best cut 00252 // create a new node 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 // set the level of the new node 00266 pNodeNew->Level = Abc_ObjLevelNew( pNodeNew ); 00267 // derive the function of this node 00268 if ( pIfMan->pPars->fTruth ) 00269 { 00270 if ( pIfMan->pPars->fUseBdds ) 00271 { 00272 // transform truth table into the BDD 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 // transform truth table into the BDD 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 // transform truth table into the SOP 00283 int RetValue = Kit_TruthIsop( If_CutTruth(pCutBest), If_CutLeaveNum(pCutBest), vCover, 1 ); 00284 assert( RetValue == 0 || RetValue == 1 ); 00285 // check the case of constant cover 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 // derive the AIG for that tree 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 // complement the node if the cut was complemented 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 }
Function*************************************************************
Synopsis [Derives the truth table for one cut.]
Description []
SideEffects []
SeeAlso []
Definition at line 358 of file abcIf.c.
00359 { 00360 If_Cut_t * pCut; 00361 Hop_Obj_t * gFunc; 00362 If_Obj_t * pLeaf; 00363 int i; 00364 // get the best cut 00365 pCut = If_ObjCutBest(pIfObj); 00366 assert( pCut->nLeaves > 1 ); 00367 // set the leaf variables 00368 If_CutForEachLeaf( pIfMan, pCut, pLeaf, i ) 00369 If_CutSetData( If_ObjCutBest(pLeaf), Hop_IthVar(pHopMan, i) ); 00370 // recursively compute the function while collecting visited cuts 00371 Vec_PtrClear( pIfMan->vTemp ); 00372 gFunc = Abc_NodeIfToHop_rec( pHopMan, pIfMan, pIfObj, pIfMan->vTemp ); 00373 // printf( "%d ", Vec_PtrSize(p->vTemp) ); 00374 // clean the cuts 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 }
Hop_Obj_t* Abc_NodeIfToHop_rec | ( | Hop_Man_t * | pHopMan, | |
If_Man_t * | pIfMan, | |||
If_Obj_t * | pIfObj, | |||
Vec_Ptr_t * | vVisited | |||
) |
Function*************************************************************
Synopsis [Recursively derives the truth table for the cut.]
Description []
SideEffects []
SeeAlso []
Definition at line 326 of file abcIf.c.
00327 { 00328 If_Cut_t * pCut; 00329 Hop_Obj_t * gFunc, * gFunc0, * gFunc1; 00330 // get the best cut 00331 pCut = If_ObjCutBest(pIfObj); 00332 // if the cut is visited, return the result 00333 if ( If_CutData(pCut) ) 00334 return If_CutData(pCut); 00335 // compute the functions of the children 00336 gFunc0 = Abc_NodeIfToHop_rec( pHopMan, pIfMan, pIfObj->pFanin0, vVisited ); 00337 gFunc1 = Abc_NodeIfToHop_rec( pHopMan, pIfMan, pIfObj->pFanin1, vVisited ); 00338 // get the function of the cut 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 // add this cut to the visited list 00343 Vec_PtrPush( vVisited, pCut ); 00344 return gFunc; 00345 }
void Abc_NtkBddReorder | ( | Abc_Ntk_t * | pNtk, | |
int | fVerbose | |||
) |
Function*************************************************************
Synopsis [Reorders BDDs of the local functions.]
Description []
SideEffects []
SeeAlso []
Definition at line 75 of file abcReorder.c.
00076 { 00077 reo_man * p; 00078 Abc_Obj_t * pNode; 00079 int i; 00080 p = Extra_ReorderInit( Abc_NtkGetFaninMax(pNtk), 100 ); 00081 Abc_NtkForEachNode( pNtk, pNode, i ) 00082 { 00083 if ( Abc_ObjFaninNum(pNode) < 3 ) 00084 continue; 00085 if ( fVerbose ) 00086 fprintf( stdout, "%10s: ", Abc_ObjName(pNode) ); 00087 if ( fVerbose ) 00088 fprintf( stdout, "Before = %5d BDD nodes. ", Cudd_DagSize(pNode->pData) ); 00089 Abc_NodeBddReorder( p, pNode ); 00090 if ( fVerbose ) 00091 fprintf( stdout, "After = %5d BDD nodes.\n", Cudd_DagSize(pNode->pData) ); 00092 } 00093 Extra_ReorderQuit( p ); 00094 }
Function*************************************************************
Synopsis [Orders AIG nodes so that nodes from larger cones go first.]
Description []
SideEffects []
SeeAlso []
Definition at line 444 of file abcIf.c.
00445 { 00446 Vec_Ptr_t * vNodes, * vCos; 00447 Abc_Obj_t * pNode, * pFanin0, * pFanin1; 00448 float Flow0, Flow1; 00449 int i; 00450 00451 // initialize the flow 00452 Abc_AigConst1(pNtk)->pCopy = NULL; 00453 Abc_NtkForEachCi( pNtk, pNode, i ) 00454 pNode->pCopy = NULL; 00455 // compute the flow 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 // find the flow of the COs 00465 vCos = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) ); 00466 Abc_NtkForEachCo( pNtk, pNode, i ) 00467 { 00468 pNode->pCopy = Abc_ObjFanin0(pNode)->pCopy; 00469 // pNode->pCopy = (Abc_Obj_t *)Abc_Float2Int((float)Abc_ObjFanin0(pNode)->Level); 00470 Vec_PtrPush( vCos, pNode ); 00471 } 00472 00473 // sort nodes in the increasing order of the flow 00474 qsort( (Abc_Obj_t **)Vec_PtrArray(vCos), Abc_NtkCoNum(pNtk), 00475 sizeof(Abc_Obj_t *), (int (*)(const void *, const void *))Abc_ObjCompareFlow ); 00476 // verify sorting 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 // collect the nodes in the topological order from the new array 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 // printf( "%.2f ", Abc_Int2Float((int)pNode->pCopy) ); 00488 } 00489 Vec_PtrFree( vCos ); 00490 return vNodes; 00491 }
Function*************************************************************
Synopsis [Orders AIG nodes so that nodes from larger cones go first.]
Description []
SideEffects []
SeeAlso []
Definition at line 416 of file abcIf.c.
00417 { 00418 if ( !Abc_ObjIsNode(pNode) ) 00419 return; 00420 assert( Abc_ObjIsNode( pNode ) ); 00421 // if this node is already visited, skip 00422 if ( Abc_NodeIsTravIdCurrent( pNode ) ) 00423 return; 00424 // mark the node as visited 00425 Abc_NodeSetTravIdCurrent( pNode ); 00426 // visit the transitive fanin of the node 00427 Abc_NtkFindGoodOrder_rec( Abc_ObjFanin0(pNode), vNodes ); 00428 Abc_NtkFindGoodOrder_rec( Abc_ObjFanin1(pNode), vNodes ); 00429 // add the node after the fanins have been added 00430 Vec_PtrPush( vNodes, pNode ); 00431 }
Function*************************************************************
Synopsis [Creates the mapped network.]
Description [Assuming the copy field of the mapped nodes are NULL.]
SideEffects []
SeeAlso []
Definition at line 180 of file abcIf.c.
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 // create the new network 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 // prepare the mapping manager 00195 If_ManCleanNodeCopy( pIfMan ); 00196 If_ManCleanCutData( pIfMan ); 00197 // make the mapper point to the new network 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 // process the nodes in topological order 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 // remove the constant node if not used 00214 pNodeNew = (Abc_Obj_t *)If_ObjCopy( If_ManConst1(pIfMan) ); 00215 if ( Abc_ObjFanoutNum(pNodeNew) == 0 ) 00216 Abc_NtkDeleteObj( pNodeNew ); 00217 // minimize the node 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 // decouple the PO driver nodes to reduce the number of levels 00223 nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 ); 00224 // if ( nDupGates && If_ManReadVerbose(pIfMan) ) 00225 // printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates ); 00226 return pNtkNew; 00227 }
FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [Interface with the FPGA mapping package.]
Description []
SideEffects []
SeeAlso []
Definition at line 52 of file abcIf.c.
00053 { 00054 Abc_Ntk_t * pNtkNew; 00055 If_Man_t * pIfMan; 00056 00057 assert( Abc_NtkIsStrash(pNtk) ); 00058 00059 // get timing information 00060 pPars->pTimesArr = Abc_NtkGetCiArrivalFloats(pNtk); 00061 pPars->pTimesReq = NULL; 00062 00063 // set the latch paths 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 // perform FPGA mapping 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 // transform the result of mapping into the new network 00082 pNtkNew = Abc_NtkFromIf( pIfMan, pNtk ); 00083 if ( pNtkNew == NULL ) 00084 return NULL; 00085 If_ManStop( pIfMan ); 00086 00087 // duplicate EXDC 00088 if ( pNtk->pExdc ) 00089 pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc ); 00090 00091 // make sure that everything is okay 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 }
CFile****************************************************************
FileName [abcIf.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Interface with the FPGA mapping package.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - November 21, 2006.]
Revision [
] DECLARATIONS ///
Function*************************************************************
Synopsis [Load the network into FPGA manager.]
Description []
SideEffects []
SeeAlso []
Definition at line 112 of file abcIf.c.
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 // vNodes = Abc_NtkFindGoodOrder( pNtk ); 00122 vNodes = Abc_AigDfs( pNtk, 0, 0 ); 00123 00124 // start the mapping manager and set its parameters 00125 pIfMan = If_ManStart( pPars ); 00126 00127 // print warning about excessive memory usage 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 // create PIs and remember them in the old nodes 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 //printf( "AIG CI %2d -> IF CI %2d\n", pNode->Id, ((If_Obj_t *)pNode->pCopy)->Id ); 00138 } 00139 00140 // load the AIG into the mapper 00141 pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) ); 00142 // Abc_AigForEachAnd( pNtk, pNode, i ) 00143 Vec_PtrForEachEntry( vNodes, pNode, i ) 00144 { 00145 Extra_ProgressBarUpdate( pProgress, i, "Initial" ); 00146 // add the node to the mapper 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 // set up the choice node 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 //printf( "AIG node %2d -> IF node %2d\n", pNode->Id, ((If_Obj_t *)pNode->pCopy)->Id ); 00159 } 00160 Extra_ProgressBarStop( pProgress ); 00161 Vec_PtrFree( vNodes ); 00162 00163 // set the primary outputs without copying the phase 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 }
Function*************************************************************
Synopsis [Comparison for two nodes with the flow.]
Description []
SideEffects []
SeeAlso []
Definition at line 394 of file abcIf.c.
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 }