/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose ) { Wlc_Obj_t * pObj; int i, k, nNum, nRange, nBits = 0; Abc_Ntk_t * pMainNtk = NULL; Abc_Obj_t * pMainObj, * pMainTemp; char Buffer[5000]; // start the network pMainNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); // duplicate the name and the spec pMainNtk->pName = Extra_UtilStrsav(pNtk->pName); // create primary inputs Wlc_NtkForEachCi( pNtk, pObj, i ) { if ( pObj->Type != WLC_OBJ_FO ) continue; nRange = Wlc_ObjRange(pObj); for ( k = 0; k < nRange; k++ ) { nNum = Vec_IntEntry(vInv, nBits + k); if ( nNum ) break; } if ( k == nRange ) { nBits += nRange; continue; } //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg ); for ( k = 0; k < nRange; k++ ) { nNum = Vec_IntEntry( vInv, nBits + k ); if ( nNum == 0 ) continue; //printf( " [%d] -> %d", k, nNum ); pMainObj = Abc_NtkCreatePi( pMainNtk ); sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k ); Abc_ObjAssignName( pMainObj, Buffer, NULL ); } //printf( "\n"); nBits += nRange; } //printf( "%d %d\n", Vec_IntSize(vInv), nBits ); assert( Vec_IntSize(vInv) == nBits ); // create node pMainObj = Abc_NtkCreateNode( pMainNtk ); Abc_NtkForEachPi( pMainNtk, pMainTemp, i ) Abc_ObjAddFanin( pMainObj, pMainTemp ); pMainObj->pData = Abc_SopRegister( (Mem_Flex_t *)pMainNtk->pManFunc, Vec_StrArray(vSop) ); // create PO pMainTemp = Abc_NtkCreatePo( pMainNtk ); Abc_ObjAddFanin( pMainTemp, pMainObj ); Abc_ObjAssignName( pMainTemp, "inv", NULL ); return pMainNtk; }
/**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 [Creates PO terminal and net.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Obj_t * Io_ReadCreatePo( Abc_Ntk_t * pNtk, char * pName ) { Abc_Obj_t * pNet, * pTerm; // get the PO net pNet = Abc_NtkFindNet( pNtk, pName ); if ( pNet && Abc_ObjFaninNum(pNet) == 0 ) printf( "Warning: PO \"%s\" appears twice in the list.\n", pName ); pNet = Abc_NtkFindOrCreateNet( pNtk, pName ); // add the PO node pTerm = Abc_NtkCreatePo( pNtk ); Abc_ObjAddFanin( pTerm, pNet ); return pTerm; }
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 [Prepares the network for mitering.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb, int nPartSize, int fMulti ) { Abc_Obj_t * pObj, * pObjNew; int i; // clean the copy field in all objects // Abc_NtkCleanCopy( pNtk1 ); // Abc_NtkCleanCopy( pNtk2 ); Abc_AigConst1(pNtk1)->pCopy = Abc_AigConst1(pNtkMiter); Abc_AigConst1(pNtk2)->pCopy = Abc_AigConst1(pNtkMiter); if ( fComb ) { // create new PIs and remember them in the old PIs Abc_NtkForEachCi( pNtk1, pObj, i ) { pObjNew = Abc_NtkCreatePi( pNtkMiter ); // remember this PI in the old PIs pObj->pCopy = pObjNew; pObj = Abc_NtkCi(pNtk2, i); pObj->pCopy = pObjNew; // add name Abc_ObjAssignName( pObjNew, Abc_ObjName(pObj), NULL ); } if ( nPartSize <= 0 ) { // create POs if ( fMulti ) { Abc_NtkForEachCo( pNtk1, pObj, i ) { pObjNew = Abc_NtkCreatePo( pNtkMiter ); Abc_ObjAssignName( pObjNew, "miter", Abc_ObjName(pObjNew) ); } } else {
/**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; }
} if ( nPartSize <= 0 ) { // create POs if ( fMulti ) { Abc_NtkForEachCo( pNtk1, pObj, i ) { pObjNew = Abc_NtkCreatePo( pNtkMiter ); Abc_ObjAssignName( pObjNew, "miter", Abc_ObjName(pObjNew) ); } } else { pObjNew = Abc_NtkCreatePo( pNtkMiter ); Abc_ObjAssignName( pObjNew, "miter", NULL ); } } } else { // create new PIs and remember them in the old PIs Abc_NtkForEachPi( pNtk1, pObj, i ) { pObjNew = Abc_NtkCreatePi( pNtkMiter ); // remember this PI in the old PIs pObj->pCopy = pObjNew; pObj = Abc_NtkPi(pNtk2, i); pObj->pCopy = pObjNew; // add name
/**Function************************************************************* Synopsis [Adds a gate to the circuit.] Description [The meaning of the parameters are: type: the type of the gate to be added name: the name of the gate to be added, name should be unique in a circuit. nofi: number of fanins of the gate to be added; fanins: the name array of fanins of the gate to be added.] SideEffects [] SeeAlso [] ***********************************************************************/ int ABC_AddGate( ABC_Manager mng, enum GateType type, char * name, int nofi, char ** fanins, int dc_attr ) { Abc_Obj_t * pObj = NULL; // Suppress "might be used uninitialized" Abc_Obj_t * pFanin; char * pSop = NULL; // Suppress "might be used uninitialized" char * pNewName; int i; // save the name in the local memory manager pNewName = Mem_FlexEntryFetch( mng->pMmNames, strlen(name) + 1 ); strcpy( pNewName, name ); name = pNewName; // consider different cases, create the node, and map the node into the name switch( type ) { case CSAT_BPI: case CSAT_BPPI: if ( nofi != 0 ) { printf( "ABC_AddGate: The PI/PPI gate \"%s\" has fanins.\n", name ); return 0; } // create the PI pObj = Abc_NtkCreatePi( mng->pNtk ); stmm_insert( mng->tNode2Name, (char *)pObj, name ); break; case CSAT_CONST: case CSAT_BAND: case CSAT_BNAND: case CSAT_BOR: case CSAT_BNOR: case CSAT_BXOR: case CSAT_BXNOR: case CSAT_BINV: case CSAT_BBUF: // create the node pObj = Abc_NtkCreateNode( mng->pNtk ); // create the fanins for ( i = 0; i < nofi; i++ ) { if ( !stmm_lookup( mng->tName2Node, fanins[i], (char **)&pFanin ) ) { printf( "ABC_AddGate: The fanin gate \"%s\" is not in the network.\n", fanins[i] ); return 0; } Abc_ObjAddFanin( pObj, pFanin ); } // create the node function switch( type ) { case CSAT_CONST: if ( nofi != 0 ) { printf( "ABC_AddGate: The constant gate \"%s\" has fanins.\n", name ); return 0; } pSop = Abc_SopCreateConst1( (Mem_Flex_t *)mng->pNtk->pManFunc ); break; case CSAT_BAND: if ( nofi < 1 ) { printf( "ABC_AddGate: The AND gate \"%s\" no fanins.\n", name ); return 0; } pSop = Abc_SopCreateAnd( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi, NULL ); break; case CSAT_BNAND: if ( nofi < 1 ) { printf( "ABC_AddGate: The NAND gate \"%s\" no fanins.\n", name ); return 0; } pSop = Abc_SopCreateNand( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi ); break; case CSAT_BOR: if ( nofi < 1 ) { printf( "ABC_AddGate: The OR gate \"%s\" no fanins.\n", name ); return 0; } pSop = Abc_SopCreateOr( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi, NULL ); break; case CSAT_BNOR: if ( nofi < 1 ) { printf( "ABC_AddGate: The NOR gate \"%s\" no fanins.\n", name ); return 0; } pSop = Abc_SopCreateNor( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi ); break; case CSAT_BXOR: if ( nofi < 1 ) { printf( "ABC_AddGate: The XOR gate \"%s\" no fanins.\n", name ); return 0; } if ( nofi > 2 ) { printf( "ABC_AddGate: The XOR gate \"%s\" has more than two fanins.\n", name ); return 0; } pSop = Abc_SopCreateXor( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi ); break; case CSAT_BXNOR: if ( nofi < 1 ) { printf( "ABC_AddGate: The XNOR gate \"%s\" no fanins.\n", name ); return 0; } if ( nofi > 2 ) { printf( "ABC_AddGate: The XNOR gate \"%s\" has more than two fanins.\n", name ); return 0; } pSop = Abc_SopCreateNxor( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi ); break; case CSAT_BINV: if ( nofi != 1 ) { printf( "ABC_AddGate: The inverter gate \"%s\" does not have exactly one fanin.\n", name ); return 0; } pSop = Abc_SopCreateInv( (Mem_Flex_t *)mng->pNtk->pManFunc ); break; case CSAT_BBUF: if ( nofi != 1 ) { printf( "ABC_AddGate: The buffer gate \"%s\" does not have exactly one fanin.\n", name ); return 0; } pSop = Abc_SopCreateBuf( (Mem_Flex_t *)mng->pNtk->pManFunc ); break; default : break; } Abc_ObjSetData( pObj, pSop ); break; case CSAT_BPPO: case CSAT_BPO: if ( nofi != 1 ) { printf( "ABC_AddGate: The PO/PPO gate \"%s\" does not have exactly one fanin.\n", name ); return 0; } // create the PO pObj = Abc_NtkCreatePo( mng->pNtk ); stmm_insert( mng->tNode2Name, (char *)pObj, name ); // connect to the PO fanin if ( !stmm_lookup( mng->tName2Node, fanins[0], (char **)&pFanin ) ) { printf( "ABC_AddGate: The fanin gate \"%s\" is not in the network.\n", fanins[0] ); return 0; } Abc_ObjAddFanin( pObj, pFanin ); break; default: printf( "ABC_AddGate: Unknown gate type.\n" ); break; } // map the name into the node if ( stmm_insert( mng->tName2Node, name, (char *)pObj ) ) { printf( "ABC_AddGate: The same gate \"%s\" is added twice.\n", name ); return 0; } return 1; }
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; }