/**Function************************************************************* Synopsis [Derives the miter of two sequential networks.] Description [Assumes that the networks are strashed.] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb, int nPartSize, int fImplic, int fMulti ) { char Buffer[1000]; Abc_Ntk_t * pNtkMiter; assert( Abc_NtkIsStrash(pNtk1) ); assert( Abc_NtkIsStrash(pNtk2) ); // start the new network pNtkMiter = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 ); sprintf( Buffer, "%s_%s_miter", pNtk1->pName, pNtk2->pName ); pNtkMiter->pName = Extra_UtilStrsav(Buffer); // perform strashing Abc_NtkMiterPrepare( pNtk1, pNtk2, pNtkMiter, fComb, nPartSize, fMulti ); Abc_NtkMiterAddOne( pNtk1, pNtkMiter ); Abc_NtkMiterAddOne( pNtk2, pNtkMiter ); Abc_NtkMiterFinalize( pNtk1, pNtk2, pNtkMiter, fComb, nPartSize, fImplic, fMulti ); Abc_AigCleanup((Abc_Aig_t *)pNtkMiter->pManFunc); // make sure that everything is okay if ( !Abc_NtkCheck( pNtkMiter ) ) { printf( "Abc_NtkMiter: The network check has failed.\n" ); Abc_NtkDelete( pNtkMiter ); return NULL; } return pNtkMiter; }
/**Function************************************************************* Synopsis [Transform the netlist into a logic network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkToLogic( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkNew; Abc_Obj_t * pObj, * pFanin; int i, k; // consider the case of the AIG if ( Abc_NtkIsStrash(pNtk) ) return Abc_NtkAigToLogicSop( pNtk ); assert( Abc_NtkIsNetlist(pNtk) ); // consider simple case when there is hierarchy // assert( pNtk->pDesign == NULL ); assert( Abc_NtkWhiteboxNum(pNtk) == 0 ); assert( Abc_NtkBlackboxNum(pNtk) == 0 ); // start the network pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, pNtk->ntkFunc ); // duplicate the nodes Abc_NtkForEachNode( pNtk, pObj, i ) Abc_NtkDupObj(pNtkNew, pObj, 0); // reconnect the internal nodes in the new network Abc_NtkForEachNode( pNtk, pObj, i ) Abc_ObjForEachFanin( pObj, pFanin, k ) Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pFanin)->pCopy ); // collect the CO nodes Abc_NtkFinalize( pNtk, pNtkNew ); // fix the problem with CO pointing directly to CIs Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); // duplicate EXDC if ( pNtk->pExdc ) pNtkNew->pExdc = Abc_NtkToLogic( pNtk->pExdc ); if ( !Abc_NtkCheck( pNtkNew ) ) fprintf( stdout, "Abc_NtkToLogic(): Network check has failed.\n" ); return pNtkNew; }
/**Function************************************************************* Synopsis [Gives the current ABC network to AIG manager for processing.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkMiniBalance( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkAig; Hop_Man_t * pMan, * pTemp; assert( Abc_NtkIsStrash(pNtk) ); // convert to the AIG manager pMan = Abc_NtkToMini( pNtk ); if ( pMan == NULL ) return NULL; if ( !Hop_ManCheck( pMan ) ) { printf( "AIG check has failed.\n" ); Hop_ManStop( pMan ); return NULL; } // perform balance Hop_ManPrintStats( pMan ); // Hop_ManDumpBlif( pMan, "aig_temp.blif" ); pMan = Hop_ManBalance( pTemp = pMan, 1 ); Hop_ManStop( pTemp ); Hop_ManPrintStats( pMan ); // convert from the AIG manager pNtkAig = Abc_NtkFromMini( pNtk, pMan ); if ( pNtkAig == NULL ) return NULL; Hop_ManStop( pMan ); // make sure everything is okay if ( !Abc_NtkCheck( pNtkAig ) ) { printf( "Abc_NtkStrash: The network check has failed.\n" ); Abc_NtkDelete( pNtkAig ); return NULL; } return pNtkAig; }
/**Function************************************************************* Synopsis [Extracts sequential DCs of the network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNtk, int fVerbose ) { int fReorder = 1; DdManager * dd; DdNode * bRelation, * bInitial, * bUnreach; // remove EXDC network if present if ( pNtk->pExdc ) { Abc_NtkDelete( pNtk->pExdc ); pNtk->pExdc = NULL; } // compute the global BDDs of the latches dd = Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose ); if ( dd == NULL ) return 0; if ( fVerbose ) printf( "Shared BDD size = %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); // create the transition relation (dereferenced global BDDs) bRelation = Abc_NtkTransitionRelation( dd, pNtk, fVerbose ); Cudd_Ref( bRelation ); // create the initial state and the variable map bInitial = Abc_NtkInitStateAndVarMap( dd, pNtk, fVerbose ); Cudd_Ref( bInitial ); // compute the unreachable states bUnreach = Abc_NtkComputeUnreachable( dd, pNtk, bRelation, bInitial, fVerbose ); Cudd_Ref( bUnreach ); Cudd_RecursiveDeref( dd, bRelation ); Cudd_RecursiveDeref( dd, bInitial ); // reorder and disable reordering if ( fReorder ) { if ( fVerbose ) fprintf( stdout, "BDD nodes in the unreachable states before reordering %d.\n", Cudd_DagSize(bUnreach) ); Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 ); Cudd_AutodynDisable( dd ); if ( fVerbose ) fprintf( stdout, "BDD nodes in the unreachable states after reordering %d.\n", Cudd_DagSize(bUnreach) ); } // allocate ZDD variables Cudd_zddVarsFromBddVars( dd, 2 ); // create the EXDC network representing the unreachable states if ( pNtk->pExdc ) Abc_NtkDelete( pNtk->pExdc ); pNtk->pExdc = Abc_NtkConstructExdc( dd, pNtk, bUnreach ); Cudd_RecursiveDeref( dd, bUnreach ); Extra_StopManager( dd ); // pNtk->pManGlob = NULL; // make sure that everything is okay if ( pNtk->pExdc && !Abc_NtkCheck( pNtk->pExdc ) ) { printf( "Abc_NtkExtractSequentialDcs: The network check has failed.\n" ); Abc_NtkDelete( pNtk->pExdc ); return 0; } return 1; }
/**Function************************************************************* Synopsis [Interface with the FPGA mapping package.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int fSwitching, int fLatchPaths, int fVerbose ) { int fShowSwitching = 1; Abc_Ntk_t * pNtkNew; Fpga_Man_t * pMan; Vec_Int_t * vSwitching; float * pSwitching = NULL; assert( Abc_NtkIsStrash(pNtk) ); // print a warning about choice nodes if ( Abc_NtkGetChoiceNum( pNtk ) ) printf( "Performing FPGA mapping with choices.\n" ); // compute switching activity fShowSwitching |= fSwitching; if ( fShowSwitching ) { extern Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns ); vSwitching = Sim_NtkComputeSwitching( pNtk, 4096 ); pSwitching = (float *)vSwitching->pArray; } // perform FPGA mapping pMan = Abc_NtkToFpga( pNtk, fRecovery, pSwitching, fLatchPaths, fVerbose ); if ( pSwitching ) Vec_IntFree( vSwitching ); if ( pMan == NULL ) return NULL; Fpga_ManSetSwitching( pMan, fSwitching ); Fpga_ManSetLatchPaths( pMan, fLatchPaths ); Fpga_ManSetLatchNum( pMan, Abc_NtkLatchNum(pNtk) ); Fpga_ManSetDelayTarget( pMan, DelayTarget ); if ( !Fpga_Mapping( pMan ) ) { Fpga_ManFree( pMan ); return NULL; } // transform the result of mapping into a BDD network pNtkNew = Abc_NtkFromFpga( pMan, pNtk ); if ( pNtkNew == NULL ) return NULL; Fpga_ManFree( pMan ); // make the network minimum base Abc_NtkMinimumBase( pNtkNew ); if ( pNtk->pExdc ) pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc ); // make sure that everything is okay if ( !Abc_NtkCheck( pNtkNew ) ) { printf( "Abc_NtkFpga: The network check has failed.\n" ); Abc_NtkDelete( pNtkNew ); return NULL; } return pNtkNew; }
/**Function************************************************************* Synopsis [Transforms the AIG into nodes.] Description [Threhold is the max number of nodes duplicated at a node.] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkMulti( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple, int fFactor ) { Abc_Ntk_t * pNtkNew; assert( Abc_NtkIsStrash(pNtk) ); assert( nThresh >= 0 ); assert( nFaninMax > 1 ); // print a warning about choice nodes if ( Abc_NtkGetChoiceNum( pNtk ) ) printf( "Warning: The choice nodes in the AIG are removed by renoding.\n" ); // define the boundary if ( fCnf ) Abc_NtkMultiSetBoundsCnf( pNtk ); else if ( fMulti ) Abc_NtkMultiSetBoundsMulti( pNtk, nThresh ); else if ( fSimple ) Abc_NtkMultiSetBoundsSimple( pNtk ); else if ( fFactor ) Abc_NtkMultiSetBoundsFactor( pNtk ); else Abc_NtkMultiSetBounds( pNtk, nThresh, nFaninMax ); // perform renoding for this boundary pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_BDD ); Abc_NtkMultiInt( pNtk, pNtkNew ); Abc_NtkFinalize( pNtk, pNtkNew ); // make the network minimum base Abc_NtkMinimumBase( pNtkNew ); // fix the problem with complemented and duplicated CO edges Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); // report the number of CNF objects if ( fCnf ) { // int nClauses = Abc_NtkGetClauseNum(pNtkNew) + 2*Abc_NtkPoNum(pNtkNew) + 2*Abc_NtkLatchNum(pNtkNew); // printf( "CNF variables = %d. CNF clauses = %d.\n", Abc_NtkNodeNum(pNtkNew), nClauses ); } //printf( "Maximum fanin = %d.\n", Abc_NtkGetFaninMax(pNtkNew) ); if ( pNtk->pExdc ) pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc ); // make sure everything is okay if ( !Abc_NtkCheck( pNtkNew ) ) { printf( "Abc_NtkMulti: The network check has failed.\n" ); Abc_NtkDelete( pNtkNew ); return NULL; } return pNtkNew; }
/**Function************************************************************* Synopsis [Constructs the network isomorphic to the given BDD.] Description [Assumes that the BDD depends on the variables whose indexes correspond to the names in the array (pNamesPi). Otherwise, returns NULL. The resulting network comes with one node, whose functionality is equal to the given BDD. To decompose this BDD into the network of multiplexers use Abc_NtkBddToMuxes(). To decompose this BDD into an And-Inverter Graph, use Abc_NtkStrash().] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkDeriveFromBdd( void * dd0, void * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi ) { DdManager * dd = (DdManager *)dd0; Abc_Ntk_t * pNtk; Vec_Ptr_t * vNamesPiFake = NULL; Abc_Obj_t * pNode, * pNodePi, * pNodePo; DdNode * bSupp, * bTemp; char * pName; int i; // supply fake names if real names are not given if ( pNamePo == NULL ) pNamePo = "F"; if ( vNamesPi == NULL ) { vNamesPiFake = Abc_NodeGetFakeNames( dd->size ); vNamesPi = vNamesPiFake; } // make sure BDD depends on the variables whose index // does not exceed the size of the array with PI names bSupp = Cudd_Support( dd, (DdNode *)bFunc ); Cudd_Ref( bSupp ); for ( bTemp = bSupp; bTemp != Cudd_ReadOne(dd); bTemp = cuddT(bTemp) ) if ( (int)Cudd_NodeReadIndex(bTemp) >= Vec_PtrSize(vNamesPi) ) break; Cudd_RecursiveDeref( dd, bSupp ); if ( bTemp != Cudd_ReadOne(dd) ) return NULL; // start the network pNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_BDD, 1 ); pNtk->pName = Extra_UtilStrsav(pNamePo); // make sure the new manager has enough inputs Cudd_bddIthVar( (DdManager *)pNtk->pManFunc, Vec_PtrSize(vNamesPi) ); // add the PIs corresponding to the names Vec_PtrForEachEntry( char *, vNamesPi, pName, i ) Abc_ObjAssignName( Abc_NtkCreatePi(pNtk), pName, NULL ); // create the node pNode = Abc_NtkCreateNode( pNtk ); pNode->pData = (DdNode *)Cudd_bddTransfer( dd, (DdManager *)pNtk->pManFunc, (DdNode *)bFunc ); Cudd_Ref((DdNode *)pNode->pData); Abc_NtkForEachPi( pNtk, pNodePi, i ) Abc_ObjAddFanin( pNode, pNodePi ); // create the only PO pNodePo = Abc_NtkCreatePo( pNtk ); Abc_ObjAddFanin( pNodePo, pNode ); Abc_ObjAssignName( pNodePo, pNamePo, NULL ); // make the network minimum base Abc_NtkMinimumBase( pNtk ); if ( vNamesPiFake ) Abc_NodeFreeNames( vNamesPiFake ); if ( !Abc_NtkCheck( pNtk ) ) fprintf( stdout, "Abc_NtkDeriveFromBdd(): Network check has failed.\n" ); return pNtk; }
/**Function************************************************************* Synopsis [Interface with the mapping package.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkNew; Map_Man_t * pMan; assert( Abc_NtkIsStrash(pNtk) ); // check that the library is available if ( Abc_FrameReadLibGen() == NULL ) { printf( "The current library is not available.\n" ); return 0; } // derive the supergate library if ( Abc_FrameReadLibSuper() == NULL && Abc_FrameReadLibGen() ) { // printf( "A simple supergate library is derived from gate library \"%s\".\n", // Mio_LibraryReadName((Mio_Library_t *)Abc_FrameReadLibGen()) ); Map_SuperLibDeriveFromGenlib( (Mio_Library_t *)Abc_FrameReadLibGen(), 0 ); } // print a warning about choice nodes if ( Abc_NtkGetChoiceNum( pNtk ) ) printf( "Performing mapping with choices.\n" ); // perform the mapping pMan = Abc_NtkToMap( pNtk, -1, 1, NULL, 0 ); if ( pMan == NULL ) return NULL; if ( !Map_Mapping( pMan ) ) { Map_ManFree( pMan ); return NULL; } // reconstruct the network after mapping pNtkNew = Abc_NtkFromMapSuperChoice( pMan, pNtk ); if ( pNtkNew == NULL ) return NULL; Map_ManFree( pMan ); // make sure that everything is okay if ( !Abc_NtkCheck( pNtkNew ) ) { printf( "Abc_NtkMap: The network check has failed.\n" ); Abc_NtkDelete( pNtkNew ); return NULL; } return pNtkNew; }
/**Function************************************************************* Synopsis [Performs retiming in one direction.] Description [Currently does not retime over black boxes.] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkRetimeIncremental( Abc_Ntk_t * pNtk, int nDelayLim, int fForward, int fMinDelay, int fOneStep, int fVerbose ) { Abc_Ntk_t * pNtkCopy = NULL; Vec_Ptr_t * vBoxes; st__table * tLatches; int nLatches = Abc_NtkLatchNum(pNtk); int nIdMaxStart = Abc_NtkObjNumMax(pNtk); int RetValue; int nIterLimit = -1; // Suppress "might be used uninitialized" if ( Abc_NtkNodeNum(pNtk) == 0 ) return 0; // reorder CI/CO/latch inputs Abc_NtkOrderCisCos( pNtk ); if ( fMinDelay ) { nIterLimit = fOneStep? 1 : 2 * Abc_NtkLevel(pNtk); pNtkCopy = Abc_NtkDup( pNtk ); tLatches = Abc_NtkRetimePrepareLatches( pNtkCopy ); st__free_table( tLatches ); } // collect latches and remove CIs/COs tLatches = Abc_NtkRetimePrepareLatches( pNtk ); // share the latches Abc_NtkRetimeShareLatches( pNtk, 0 ); // save boxes vBoxes = pNtk->vBoxes; pNtk->vBoxes = NULL; // perform the retiming if ( fMinDelay ) Abc_NtkRetimeMinDelay( pNtk, pNtkCopy, nDelayLim, nIterLimit, fForward, fVerbose ); else Abc_NtkRetimeOneWay( pNtk, fForward, fVerbose ); if ( fMinDelay ) Abc_NtkDelete( pNtkCopy ); // share the latches Abc_NtkRetimeShareLatches( pNtk, 0 ); // restore boxes pNtk->vBoxes = vBoxes; // finalize the latches RetValue = Abc_NtkRetimeFinalizeLatches( pNtk, tLatches, nIdMaxStart ); st__free_table( tLatches ); if ( RetValue == 0 ) return 0; // fix the COs // Abc_NtkLogicMakeSimpleCos( pNtk, 0 ); // check for correctness if ( !Abc_NtkCheck( pNtk ) ) fprintf( stdout, "Abc_NtkRetimeForward(): Network check has failed.\n" ); // return the number of latches saved return nLatches - Abc_NtkLatchNum(pNtk); }
/**Function************************************************************* Synopsis [Creates the network isomorphic to the union of local BDDs of the nodes.] Description [The nodes of the local BDDs are converted into the network nodes with logic functions equal to the MUX.] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkNew; assert( Abc_NtkIsBddLogic(pNtk) ); pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); Abc_NtkBddToMuxesPerform( pNtk, pNtkNew ); Abc_NtkFinalize( pNtk, pNtkNew ); // make sure everything is okay if ( !Abc_NtkCheck( pNtkNew ) ) { printf( "Abc_NtkBddToMuxes: The network check has failed.\n" ); Abc_NtkDelete( pNtkNew ); return NULL; } return pNtkNew; }
Abc_Ntk_t * Abc_NtkFromMiniAig( Mini_Aig_t * p ) { Abc_Ntk_t * pNtk; Abc_Obj_t * pObj; Vec_Int_t * vCopies; int i, nNodes; // get the number of nodes nNodes = Mini_AigNodeNum(p); // create ABC network pNtk = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 ); pNtk->pName = Abc_UtilStrsav( "MiniAig" ); // create mapping from MiniAIG objects into ABC objects vCopies = Vec_IntAlloc( nNodes ); Vec_IntPush( vCopies, Abc_LitNot(Abc_ObjToLit(Abc_AigConst1(pNtk))) ); // iterate through the objects for ( i = 1; i < nNodes; i++ ) { if ( Mini_AigNodeIsPi( p, i ) ) pObj = Abc_NtkCreatePi(pNtk); else if ( Mini_AigNodeIsPo( p, i ) ) Abc_ObjAddFanin( (pObj = Abc_NtkCreatePo(pNtk)), Abc_NodeFanin0Copy(pNtk, vCopies, p, i) ); else if ( Mini_AigNodeIsAnd( p, i ) ) pObj = Abc_AigAnd((Abc_Aig_t *)pNtk->pManFunc, Abc_NodeFanin0Copy(pNtk, vCopies, p, i), Abc_NodeFanin1Copy(pNtk, vCopies, p, i)); else assert( 0 ); Vec_IntPush( vCopies, Abc_ObjToLit(pObj) ); } assert( Vec_IntSize(vCopies) == nNodes ); Abc_AigCleanup( (Abc_Aig_t *)pNtk->pManFunc ); Vec_IntFree( vCopies ); Abc_NtkAddDummyPiNames( pNtk ); Abc_NtkAddDummyPoNames( pNtk ); if ( !Abc_NtkCheck( pNtk ) ) fprintf( stdout, "Abc_NtkFromMini(): Network check has failed.\n" ); // add latches if ( Mini_AigRegNum(p) > 0 ) { extern Abc_Ntk_t * Abc_NtkRestrashWithLatches( Abc_Ntk_t * pNtk, int nLatches ); Abc_Ntk_t * pTemp; pNtk = Abc_NtkRestrashWithLatches( pTemp = pNtk, Mini_AigRegNum(p) ); Abc_NtkDelete( pTemp ); } return pNtk; }
/**Function************************************************************* Synopsis [Performs fast FPGA mapping of the network.] Description [Takes the AIG to be mapped, the LUT size, and verbosity flag. Produces the new network by fast FPGA mapping of the current network. If the current network in ABC in not an AIG, the user should run command "strash" to make sure that the current network into an AIG before calling this procedure.] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkFpgaFast( Abc_Ntk_t * pNtk, int nLutSize, int fRecovery, int fVerbose ) { Ivy_Man_t * pMan; Abc_Ntk_t * pNtkNew; // make sure the network is an AIG assert( Abc_NtkIsStrash(pNtk) ); // convert the network into the AIG pMan = Abc_NtkIvyBefore( pNtk, 0, 0 ); // perform fast FPGA mapping Ivy_FastMapPerform( pMan, nLutSize, fRecovery, fVerbose ); // convert back into the ABC network pNtkNew = Ivy_ManFpgaToAbc( pNtk, pMan ); Ivy_FastMapStop( pMan ); Ivy_ManStop( pMan ); // make sure that the final network passes the test if ( pNtkNew != NULL && !Abc_NtkCheck( pNtkNew ) ) { printf( "Abc_NtkFastMap: The network check has failed.\n" ); Abc_NtkDelete( pNtkNew ); return NULL; } return pNtkNew; }
/**Function************************************************************* Synopsis [Converts the network from the AIG manager into ABC.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkFromMini( Abc_Ntk_t * pNtk, Hop_Man_t * pMan ) { Vec_Ptr_t * vNodes; Abc_Ntk_t * pNtkNew; Hop_Obj_t * pObj; int i; // perform strashing pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG ); // transfer the pointers to the basic nodes Hop_ManConst1(pMan)->pData = Abc_AigConst1(pNtkNew); Hop_ManForEachPi( pMan, pObj, i ) pObj->pData = Abc_NtkCi(pNtkNew, i); // rebuild the AIG vNodes = Hop_ManDfs( pMan ); Vec_PtrForEachEntry( Hop_Obj_t *, vNodes, pObj, i ) pObj->pData = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, (Abc_Obj_t *)Hop_ObjChild0Copy(pObj), (Abc_Obj_t *)Hop_ObjChild1Copy(pObj) ); Vec_PtrFree( vNodes ); // connect the PO nodes Hop_ManForEachPo( pMan, pObj, i ) Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), (Abc_Obj_t *)Hop_ObjChild0Copy(pObj) ); if ( !Abc_NtkCheck( pNtkNew ) ) fprintf( stdout, "Abc_NtkFromMini(): Network check has failed.\n" ); return pNtkNew; }
/**Function************************************************************* Synopsis [Prepares the IVY package.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkIvyAfter( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, int fSeq, int fHaig ) { Abc_Ntk_t * pNtkAig; int nNodes, fCleanup = 1; // convert from the AIG manager if ( fSeq ) pNtkAig = Abc_NtkFromIvySeq( pNtk, pMan, fHaig ); else pNtkAig = Abc_NtkFromIvy( pNtk, pMan ); // report the cleanup results if ( !fHaig && fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) ) 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 ); // make sure everything is okay if ( !Abc_NtkCheck( pNtkAig ) ) { printf( "Abc_NtkStrash: The network check has failed.\n" ); Abc_NtkDelete( pNtkAig ); return NULL; } return pNtkAig; }
ABC_NAMESPACE_IMPL_START // For description of Binary BLIF format, refer to "abc/src/aig/bbl/bblif.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Fnction************************************************************* Synopsis [Constructs ABC network from the manager.] Description [The ABC network is started, as well as the array vCopy, which will map the new ID of each object in the BBLIF manager into the ponter ot the corresponding object in the ABC. For each internal node, determined by Bbl_ObjIsLut(), the SOP representation is created by retrieving the SOP representation of the BBLIF object. Finally, the objects are connected using fanin/fanout creation, and the dummy names are assigned because ABC requires each CI/CO to have a name.] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Bbl_ManToAbc( Bbl_Man_t * p ) { Abc_Ntk_t * pNtk; Abc_Obj_t * pObjNew; Bbl_Obj_t * pObj, * pFanin; Vec_Ptr_t * vCopy; // start the network pNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); pNtk->pName = Extra_UtilStrsav( Bbl_ManName(p) ); // create objects vCopy = Vec_PtrStart( 1000 ); Bbl_ManForEachObj( p, pObj ) { if ( Bbl_ObjIsInput(pObj) ) pObjNew = Abc_NtkCreatePi( pNtk ); else if ( Bbl_ObjIsOutput(pObj) ) pObjNew = Abc_NtkCreatePo( pNtk ); else if ( Bbl_ObjIsLut(pObj) ) pObjNew = Abc_NtkCreateNode( pNtk ); else assert( 0 ); if ( Bbl_ObjIsLut(pObj) ) pObjNew->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, Bbl_ObjSop(p, pObj) ); Vec_PtrSetEntry( vCopy, Bbl_ObjId(pObj), pObjNew ); } // connect objects Bbl_ManForEachObj( p, pObj ) Bbl_ObjForEachFanin( pObj, pFanin ) Abc_ObjAddFanin( (Abc_Obj_t *)Vec_PtrEntry(vCopy, Bbl_ObjId(pObj)), (Abc_Obj_t *)Vec_PtrEntry(vCopy, Bbl_ObjId(pFanin)) ); // finalize Vec_PtrFree( vCopy ); Abc_NtkAddDummyPiNames( pNtk ); Abc_NtkAddDummyPoNames( pNtk ); if ( !Abc_NtkCheck( pNtk ) ) printf( "Bbl_ManToAbc(): Network check has failed.\n" ); return pNtk; }
/**Function************************************************************* Synopsis [Structurally hashes the given window.] Description [The first PO is the observability condition. The second is the node's function. The remaining POs are the candidate divisors.] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Res_WndStrash( Res_Win_t * p ) { Vec_Ptr_t * vPairs; Abc_Ntk_t * pAig; Abc_Obj_t * pObj, * pMiter; int i; assert( Abc_NtkHasAig(p->pNode->pNtk) ); // Abc_NtkCleanCopy( p->pNode->pNtk ); // create the network pAig = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 ); pAig->pName = Extra_UtilStrsav( "window" ); // create the inputs Vec_PtrForEachEntry( Abc_Obj_t *, p->vLeaves, pObj, i ) pObj->pCopy = Abc_NtkCreatePi( pAig ); Vec_PtrForEachEntry( Abc_Obj_t *, p->vBranches, pObj, i ) pObj->pCopy = Abc_NtkCreatePi( pAig ); // go through the nodes in the topological order Vec_PtrForEachEntry( Abc_Obj_t *, p->vNodes, pObj, i ) { pObj->pCopy = Abc_ConvertAigToAig( pAig, pObj ); if ( pObj == p->pNode ) pObj->pCopy = Abc_ObjNot( pObj->pCopy ); } // collect the POs vPairs = Vec_PtrAlloc( 2 * Vec_PtrSize(p->vRoots) ); Vec_PtrForEachEntry( Abc_Obj_t *, p->vRoots, pObj, i ) { Vec_PtrPush( vPairs, pObj->pCopy ); Vec_PtrPush( vPairs, NULL ); } // mark the TFO of the node Abc_NtkIncrementTravId( p->pNode->pNtk ); Res_WinSweepLeafTfo_rec( p->pNode, (int)p->pNode->Level + p->nWinTfoMax ); // update strashing of the node p->pNode->pCopy = Abc_ObjNot( p->pNode->pCopy ); Abc_NodeSetTravIdPrevious( p->pNode ); // redo strashing in the TFO Vec_PtrForEachEntry( Abc_Obj_t *, p->vNodes, pObj, i ) { if ( Abc_NodeIsTravIdCurrent(pObj) ) pObj->pCopy = Abc_ConvertAigToAig( pAig, pObj ); } // collect the POs Vec_PtrForEachEntry( Abc_Obj_t *, p->vRoots, pObj, i ) Vec_PtrWriteEntry( vPairs, 2 * i + 1, pObj->pCopy ); // add the miter pMiter = Abc_AigMiter( (Abc_Aig_t *)pAig->pManFunc, vPairs, 0 ); Abc_ObjAddFanin( Abc_NtkCreatePo(pAig), pMiter ); Vec_PtrFree( vPairs ); // add the node Abc_ObjAddFanin( Abc_NtkCreatePo(pAig), p->pNode->pCopy ); // add the fanins Abc_ObjForEachFanin( p->pNode, pObj, i ) Abc_ObjAddFanin( Abc_NtkCreatePo(pAig), pObj->pCopy ); // add the divisors Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs, pObj, i ) Abc_ObjAddFanin( Abc_NtkCreatePo(pAig), pObj->pCopy ); // add the names Abc_NtkAddDummyPiNames( pAig ); Abc_NtkAddDummyPoNames( pAig ); // check the resulting network if ( !Abc_NtkCheck( pAig ) ) fprintf( stdout, "Res_WndStrash(): Network check has failed.\n" ); return pAig; }
/**Function************************************************************* Synopsis [Interface with the mapping package.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, double AreaMulti, double DelayMulti, float LogFan, float Slew, float Gain, int nGatesMin, int fRecovery, int fSwitching, int fSkipFanout, int fVerbose ) { static int fUseMulti = 0; int fShowSwitching = 1; Abc_Ntk_t * pNtkNew; Map_Man_t * pMan; Vec_Int_t * vSwitching = NULL; float * pSwitching = NULL; abctime clk, clkTotal = Abc_Clock(); Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen(); assert( Abc_NtkIsStrash(pNtk) ); // derive library from SCL // if the library is created here, it will be deleted when pSuperLib is deleted in Map_SuperLibFree() if ( Abc_FrameReadLibScl() && Abc_SclHasDelayInfo( Abc_FrameReadLibScl() ) ) { pLib = Abc_SclDeriveGenlib( Abc_FrameReadLibScl(), Slew, Gain, nGatesMin, fVerbose ); if ( Abc_FrameReadLibGen() ) Mio_LibraryTransferDelays( (Mio_Library_t *)Abc_FrameReadLibGen(), pLib ); // remove supergate library Map_SuperLibFree( (Map_SuperLib_t *)Abc_FrameReadLibSuper() ); Abc_FrameSetLibSuper( NULL ); } // quit if there is no library if ( pLib == NULL ) { printf( "The current library is not available.\n" ); return 0; } if ( AreaMulti != 0.0 ) fUseMulti = 1, printf( "The cell areas are multiplied by the factor: <num_fanins> ^ (%.2f).\n", AreaMulti ); if ( DelayMulti != 0.0 ) fUseMulti = 1, printf( "The cell delays are multiplied by the factor: <num_fanins> ^ (%.2f).\n", DelayMulti ); // penalize large gates by increasing their area if ( AreaMulti != 0.0 ) Mio_LibraryMultiArea( pLib, AreaMulti ); if ( DelayMulti != 0.0 ) Mio_LibraryMultiDelay( pLib, DelayMulti ); // derive the supergate library if ( fUseMulti || Abc_FrameReadLibSuper() == NULL ) { if ( fVerbose ) printf( "Converting \"%s\" into supergate library \"%s\".\n", Mio_LibraryReadName(pLib), Extra_FileNameGenericAppend(Mio_LibraryReadName(pLib), ".super") ); // compute supergate library to be used for mapping Map_SuperLibDeriveFromGenlib( pLib, fVerbose ); } // return the library to normal if ( AreaMulti != 0.0 ) Mio_LibraryMultiArea( (Mio_Library_t *)Abc_FrameReadLibGen(), -AreaMulti ); if ( DelayMulti != 0.0 ) Mio_LibraryMultiDelay( (Mio_Library_t *)Abc_FrameReadLibGen(), -DelayMulti ); // print a warning about choice nodes if ( fVerbose && Abc_NtkGetChoiceNum( pNtk ) ) printf( "Performing mapping with choices.\n" ); // compute switching activity fShowSwitching |= fSwitching; if ( fShowSwitching ) { extern Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns ); vSwitching = Sim_NtkComputeSwitching( pNtk, 4096 ); pSwitching = (float *)vSwitching->pArray; } // perform the mapping pMan = Abc_NtkToMap( pNtk, DelayTarget, fRecovery, pSwitching, fVerbose ); if ( pSwitching ) Vec_IntFree( vSwitching ); if ( pMan == NULL ) return NULL; clk = Abc_Clock(); Map_ManSetSwitching( pMan, fSwitching ); Map_ManSetSkipFanout( pMan, fSkipFanout ); if ( LogFan != 0 ) Map_ManCreateNodeDelays( pMan, LogFan ); if ( !Map_Mapping( pMan ) ) { Map_ManFree( pMan ); return NULL; } // Map_ManPrintStatsToFile( pNtk->pSpec, Map_ManReadAreaFinal(pMan), Map_ManReadRequiredGlo(pMan), Abc_Clock()-clk ); // reconstruct the network after mapping pNtkNew = Abc_NtkFromMap( pMan, pNtk ); Map_ManFree( pMan ); if ( pNtkNew == NULL ) return NULL; if ( pNtk->pExdc ) pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc ); if ( fVerbose ) { ABC_PRT( "Total runtime", Abc_Clock() - clkTotal ); } // make sure that everything is okay if ( !Abc_NtkCheck( pNtkNew ) ) { printf( "Abc_NtkMap: The network check has failed.\n" ); Abc_NtkDelete( pNtkNew ); return NULL; } return pNtkNew; }