ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Mig_Man_t * Mig_ManStart() { Mig_Man_t * p; assert( sizeof(Mig_Obj_t) >= 16 ); assert( (1 << MIG_BASE) == MIG_MASK + 1 ); p = ABC_CALLOC( Mig_Man_t, 1 ); Vec_IntGrow( &p->vCis, 1024 ); Vec_IntGrow( &p->vCos, 1024 ); Mig_ManAppendObj( p ); // const0 return p; }
/**Function************************************************************* Synopsis [Working with models.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Wlc_Ntk_t * Wlc_NtkAlloc( char * pName, int nObjsAlloc ) { Wlc_Ntk_t * p; p = ABC_CALLOC( Wlc_Ntk_t, 1 ); p->pName = pName ? Extra_FileNameGeneric( pName ) : NULL; Vec_IntGrow( &p->vPis, 111 ); Vec_IntGrow( &p->vPos, 111 ); Vec_IntGrow( &p->vCis, 111 ); Vec_IntGrow( &p->vCos, 111 ); Vec_IntGrow( &p->vFfs, 111 ); p->pMemFanin = Mem_FlexStart(); p->nObjsAlloc = nObjsAlloc; p->pObjs = ABC_CALLOC( Wlc_Obj_t, p->nObjsAlloc ); p->iObj = 1; return p; }
static inline int Pdr_ObjSatVar2FindOrAdd( Pdr_Man_t * p, int k, Aig_Obj_t * pObj ) { Vec_Int_t * vId2Vars = p->pvId2Vars + Aig_ObjId(pObj); assert( p->pCnf2->pObj2Count[Aig_ObjId(pObj)] >= 0 ); if ( Vec_IntSize(vId2Vars) == 0 ) Vec_IntGrow(vId2Vars, 2 * k + 1); if ( Vec_IntGetEntry(vId2Vars, k) == 0 ) { sat_solver * pSat = Pdr_ManSolver(p, k); Vec_Int_t * vVar2Ids = (Vec_Int_t *)Vec_PtrEntry(&p->vVar2Ids, k); int iVarNew = Vec_IntSize( vVar2Ids ); assert( iVarNew > 0 ); Vec_IntPush( vVar2Ids, Aig_ObjId(pObj) ); Vec_IntWriteEntry( vId2Vars, k, iVarNew << 2 ); sat_solver_setnvars( pSat, iVarNew + 1 ); if ( k == 0 && Saig_ObjIsLo(p->pAig, pObj) ) // initialize the register output { int Lit = toLitCond( iVarNew, 1 ); int RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 ); assert( RetValue == 1 ); (void) RetValue; sat_solver_compress( pSat ); } } return Vec_IntEntry( vId2Vars, k ); }
Vec_Wec_t * Gia_ManComputeMffcs( Gia_Man_t * p, int LimitMin, int LimitMax, int SuppMax, int RatioBest ) { Gia_Obj_t * pObj; Vec_Wec_t * vMffcs; Vec_Int_t * vNodes, * vLeaves, * vInners, * vMffc; int i, iPivot; assert( p->pMuxes ); vNodes = Vec_IntAlloc( 2 * LimitMax ); vLeaves = Vec_IntAlloc( 2 * LimitMax ); vInners = Vec_IntAlloc( 2 * LimitMax ); vMffcs = Vec_WecAlloc( 1000 ); Gia_ManCreateRefs( p ); Gia_ManForEachAnd( p, pObj, i ) { if ( !Gia_ObjRefNum(p, pObj) ) continue; if ( !Gia_ObjCheckMffc(p, pObj, LimitMax, vNodes, vLeaves, vInners) ) continue; if ( Vec_IntSize(vInners) < LimitMin ) continue; if ( Vec_IntSize(vLeaves) > SuppMax ) continue; // improve cut // collect cut vMffc = Vec_WecPushLevel( vMffcs ); Vec_IntGrow( vMffc, Vec_IntSize(vLeaves) + Vec_IntSize(vInners) + 20 ); Vec_IntPush( vMffc, i ); Vec_IntPush( vMffc, Vec_IntSize(vLeaves) ); Vec_IntPush( vMffc, Vec_IntSize(vInners) ); Vec_IntAppend( vMffc, vLeaves ); // Vec_IntAppend( vMffc, vInners ); // add last entry equal to the ratio Vec_IntPush( vMffc, 1000 * Vec_IntSize(vInners) / Vec_IntSize(vLeaves) ); } Vec_IntFree( vNodes ); Vec_IntFree( vLeaves ); Vec_IntFree( vInners ); // sort MFFCs by their inner/leaf ratio Vec_WecSortByLastInt( vMffcs, 1 ); Vec_WecForEachLevel( vMffcs, vMffc, i ) Vec_IntPop( vMffc ); // remove those whose ratio is not good iPivot = RatioBest * Vec_WecSize(vMffcs) / 100; Vec_WecForEachLevelStart( vMffcs, vMffc, i, iPivot ) Vec_IntErase( vMffc ); assert( iPivot <= Vec_WecSize(vMffcs) ); Vec_WecShrink( vMffcs, iPivot ); return vMffcs; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Sfm_CreateFanout( Vec_Wec_t * vFanins, Vec_Wec_t * vFanouts ) { Vec_Int_t * vArray; int i, k, Fanin; // count fanouts Vec_WecInit( vFanouts, Vec_WecSize(vFanins) ); Vec_WecForEachLevel( vFanins, vArray, i ) Vec_IntForEachEntry( vArray, Fanin, k ) Vec_WecEntry( vFanouts, Fanin )->nSize++; // allocate fanins Vec_WecForEachLevel( vFanouts, vArray, i ) { k = vArray->nSize; vArray->nSize = 0; Vec_IntGrow( vArray, k ); }
/**Function************************************************************* Synopsis [Transforms the node to take fanout sharing into account.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Seq_NodeShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr_t * vNodes ) { Vec_Int_t * vNums = Seq_ObjLNums( pNode ); Vec_Ptr_t * vInits = Seq_NodeLats( pNode ); Abc_Obj_t * pFanout, * pBuffer; Abc_InitType_t Type, InitNew; int i; // collect the fanouts that satisfy the property (have initial value Init or DC) InitNew = ABC_INIT_DC; Vec_PtrClear( vNodes ); Abc_ObjForEachFanout( pNode, pFanout, i ) { if ( Seq_ObjFanoutL(pNode, pFanout) == 0 ) continue; Type = Seq_NodeGetInitLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) ); if ( Type == Init ) InitNew = Init; if ( Type == Init || Type == ABC_INIT_DC ) { Vec_PtrPush( vNodes, pFanout ); Seq_NodeDeleteLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) ); } } // create the new buffer pBuffer = Abc_NtkCreateNode( pNode->pNtk ); Abc_ObjAddFanin( pBuffer, pNode ); // grow storage for initial states Vec_PtrGrow( vInits, 2 * pBuffer->Id + 2 ); for ( i = Vec_PtrSize(vInits); i < 2 * (int)pBuffer->Id + 2; i++ ) Vec_PtrPush( vInits, NULL ); // grow storage for numbers of latches Vec_IntGrow( vNums, 2 * pBuffer->Id + 2 ); for ( i = Vec_IntSize(vNums); i < 2 * (int)pBuffer->Id + 2; i++ ) Vec_IntPush( vNums, 0 ); // insert the new latch Seq_NodeInsertFirst( pBuffer, 0, InitNew ); // redirect the fanouts Vec_PtrForEachEntry( vNodes, pFanout, i ) Abc_ObjPatchFanin( pFanout, pNode, pBuffer ); }
/**Function************************************************************* Synopsis [Computes truth table of the node.] Description [Assumes that the structural support is no more than 8 inputs. Uses array vTruth to store temporary truth tables. The returned pointer should be used immediately.] SideEffects [] SeeAlso [] ***********************************************************************/ unsigned * Hop_ManConvertAigToTruth( Hop_Man_t * p, Hop_Obj_t * pRoot, int nVars, Vec_Int_t * vTruth, int fMsbFirst ) { static unsigned uTruths[8][8] = { // elementary truth tables { 0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA }, { 0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC }, { 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 }, { 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 }, { 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 }, { 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF }, { 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF }, { 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF } }; Hop_Obj_t * pObj; unsigned * pTruth, * pTruth2; int i, nWords, nNodes; Vec_Ptr_t * vTtElems; // if the number of variables is more than 8, allocate truth tables if ( nVars > 8 ) vTtElems = Vec_PtrAllocTruthTables( nVars ); else vTtElems = NULL; // clear the data fields and set marks nNodes = Hop_ManConvertAigToTruth_rec1( Hop_Regular(pRoot) ); // prepare memory nWords = Hop_TruthWordNum( nVars ); Vec_IntClear( vTruth ); Vec_IntGrow( vTruth, nWords * (nNodes+1) ); pTruth = Vec_IntFetch( vTruth, nWords ); // check the case of a constant if ( Hop_ObjIsConst1( Hop_Regular(pRoot) ) ) { assert( nNodes == 0 ); if ( Hop_IsComplement(pRoot) ) Hop_ManTruthClear( pTruth, nVars ); else Hop_ManTruthFill( pTruth, nVars ); return pTruth; } // set elementary truth tables at the leaves assert( nVars <= Hop_ManPiNum(p) ); // assert( Hop_ManPiNum(p) <= 8 ); if ( fMsbFirst ) { // Hop_ManForEachPi( p, pObj, i ) for ( i = 0; i < nVars; i++ ) { pObj = Hop_ManPi( p, i ); if ( vTtElems ) pObj->pData = Vec_PtrEntry(vTtElems, nVars-1-i); else pObj->pData = (void *)uTruths[nVars-1-i]; } } else { // Hop_ManForEachPi( p, pObj, i ) for ( i = 0; i < nVars; i++ ) { pObj = Hop_ManPi( p, i ); if ( vTtElems ) pObj->pData = Vec_PtrEntry(vTtElems, i); else pObj->pData = (void *)uTruths[i]; } } // clear the marks and compute the truth table pTruth2 = Hop_ManConvertAigToTruth_rec2( Hop_Regular(pRoot), vTruth, nWords ); // copy the result Hop_ManTruthCopy( pTruth, pTruth2, nVars ); if ( Hop_IsComplement(pRoot) ) Hop_ManTruthNot( pTruth, pTruth, nVars ); if ( vTtElems ) Vec_PtrFree( vTtElems ); return pTruth; }