示例#1
0
ABC_NAMESPACE_IMPL_START


////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////


/**Function*************************************************************

  Synopsis    [Trasnforms AIG to transition into the init state.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Int2_ManDupInit( Gia_Man_t * p, int fVerbose )
{
    Gia_Man_t * pNew, * pTemp;
    Gia_Obj_t * pObj, * pObjRi, * pObjRo;
    int i, iCtrl;
    assert( Gia_ManRegNum(p) > 0 );
    pNew = Gia_ManStart( 10000 );
    pNew->pName = Abc_UtilStrsav( p->pName );
    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
    Gia_ManConst0(p)->Value = 0;
    Gia_ManForEachCi( p, pObj, i )
    {
        if ( i == Gia_ManPiNum(p) )
            iCtrl = Gia_ManAppendCi( pNew );
        pObj->Value = Gia_ManAppendCi( pNew );
    }
    Gia_ManHashAlloc( pNew );
    Gia_ManForEachAnd( p, pObj, i )
        pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
    Gia_ManForEachPo( p, pObj, i )
        pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
    Gia_ManForEachRiRo( p, pObjRi, pObjRo, i )
        Gia_ManAppendCo( pNew, Gia_ManHashMux( pNew, iCtrl, pObjRo->Value, Gia_ObjFanin0Copy(pObjRi) ) );
    Gia_ManHashStop( pNew );
    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
    // remove dangling
    pNew = Gia_ManCleanup( pTemp = pNew );
    if ( fVerbose )
        printf( "Before cleanup = %d nodes. After cleanup = %d nodes.\n", 
            Gia_ManAndNum(pTemp), Gia_ManAndNum(pNew) );
    Gia_ManStop( pTemp );
    return pNew;
}
示例#2
0
/**Function*************************************************************

  Synopsis    [Prints stats for the AIG.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Gia_ManPrintStats( Gia_Man_t * p, int fTents, int fSwitch )
{
    if ( p->pName )
        printf( "%-8s : ", p->pName );
    printf( "i/o =%7d/%7d", Gia_ManPiNum(p), Gia_ManPoNum(p) );
    if ( Gia_ManConstrNum(p) )
        printf( "(c=%d)", Gia_ManConstrNum(p) );
    if ( Gia_ManRegNum(p) )
        printf( "  ff =%7d", Gia_ManRegNum(p) );
    printf( "  and =%8d", Gia_ManAndNum(p) );
    printf( "  lev =%5d", Gia_ManLevelNum(p) ); Vec_IntFreeP( &p->vLevels );
    printf( "  cut =%5d", Gia_ManCrossCut(p) );
//    printf( "  mem =%5.2f MB", 1.0*(sizeof(Gia_Obj_t)*p->nObjs + sizeof(int)*(Vec_IntSize(p->vCis) + Vec_IntSize(p->vCos)))/(1<<20) );
    printf( "  mem =%5.2f MB", 1.0*(sizeof(Gia_Obj_t)*p->nObjsAlloc + sizeof(int)*(Vec_IntCap(p->vCis) + Vec_IntCap(p->vCos)))/(1<<20) );
    if ( Gia_ManHasDangling(p) )
        printf( "  ch =%5d", Gia_ManEquivCountClasses(p) );
    if ( fSwitch )
    {
        if ( p->pSwitching )
            printf( "  power =%7.2f", Gia_ManEvaluateSwitching(p) );
        else
            printf( "  power =%7.2f", Gia_ManComputeSwitching(p, 48, 16, 0) );
    }
//    printf( "obj =%5d  ", Gia_ManObjNum(p) );
    printf( "\n" );

//    Gia_ManSatExperiment( p );
    if ( p->pReprs && p->pNexts )
        Gia_ManEquivPrintClasses( p, 0, 0.0 );
    if ( p->pMapping )
        Gia_ManPrintMappingStats( p );
    if ( p->pPlacement )
        Gia_ManPrintPlacement( p );
    // print register classes
    Gia_ManPrintFlopClasses( p );
    Gia_ManPrintGateClasses( p );
    Gia_ManPrintObjClasses( p );
    if ( fTents )
    {
/*
        int k, Entry, Prev = 1;
        Vec_Int_t * vLimit = Vec_IntAlloc( 1000 );
        Gia_Man_t * pNew = Gia_ManUnrollDup( p, vLimit );
        printf( "Tents:  " );
        Vec_IntForEachEntryStart( vLimit, Entry, k, 1 )
            printf( "%d=%d  ", k, Entry-Prev ), Prev = Entry;
        printf( " Unused=%d.", Gia_ManObjNum(p) - Gia_ManObjNum(pNew) );
        printf( "\n" );
        Vec_IntFree( vLimit );
        Gia_ManStop( pNew );
*/
        Gia_ManPrintTents( p );
    }
}
示例#3
0
/**Function*************************************************************

  Synopsis    [Duplicates AIG in the DFS order while putting CIs first.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Gia_ManDupNormalize( Gia_Man_t * p )
{
    int fHashMapping = 0;
    Gia_Man_t * pNew;
    Gia_Obj_t * pObj;
    int i;
    Gia_ManFillValue( p );
    pNew = Gia_ManStart( Gia_ManObjNum(p) );
    pNew->pName = Abc_UtilStrsav( p->pName );
    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
    Gia_ManConst0(p)->Value = 0;
    if ( !Gia_ManIsSeqWithBoxes(p) )
    {
        Gia_ManForEachCi( p, pObj, i )
            pObj->Value = Gia_ManAppendCi(pNew);
    }
    else
    {
        // current CI order:  PIs + FOs + NewCIs
        // desired reorder:   PIs + NewCIs + FOs
        int nCIs = Tim_ManPiNum( (Tim_Man_t *)p->pManTime );
        int nAll = Tim_ManCiNum( (Tim_Man_t *)p->pManTime );
        int nPis = nCIs - Gia_ManRegNum(p);
        assert( nAll == Gia_ManCiNum(p) );
        assert( nPis > 0 );
        // copy PIs first
        for ( i = 0; i < nPis; i++ )
            Gia_ManCi(p, i)->Value = Gia_ManAppendCi(pNew);
       // copy new CIs second
        for ( i = nCIs; i < nAll; i++ )
            Gia_ManCi(p, i)->Value = Gia_ManAppendCi(pNew);
        // copy flops last
        for ( i = nCIs - Gia_ManRegNum(p); i < nCIs; i++ )
            Gia_ManCi(p, i)->Value = Gia_ManAppendCi(pNew);
        printf( "Warning: Shuffled CI order to be correct sequential AIG.\n" );
    }
    if ( fHashMapping ) Gia_ManHashAlloc( pNew );
    Gia_ManForEachAnd( p, pObj, i )
        if ( Gia_ObjIsBuf(pObj) )
            pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) );
        else if ( fHashMapping )
            pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
        else
            pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
    if ( fHashMapping ) Gia_ManHashStop( pNew );
    Gia_ManForEachCo( p, pObj, i )
        pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
    pNew->nConstrs = p->nConstrs;
    assert( Gia_ManIsNormalized(pNew) );
    Gia_ManDupRemapEquiv( pNew, p );
    return pNew;
}
示例#4
0
文件: giaTim.c 项目: aakarsh/ABC
/**Function*************************************************************

  Synopsis    [Duplicates AIG according to the timing manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Gia_ManDupUnnormalize( Gia_Man_t * p )
{
    Vec_Int_t * vNodes;
    Gia_Man_t * pNew;
    Gia_Obj_t * pObj;
    int i;
    vNodes = Gia_ManOrderWithBoxes( p );
    if ( vNodes == NULL )
        return NULL;
    Gia_ManFillValue( p );
    pNew = Gia_ManStart( Gia_ManObjNum(p) );
    pNew->pName = Abc_UtilStrsav( p->pName );
    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
    if ( p->pSibls )
        pNew->pSibls = ABC_CALLOC( int, Gia_ManObjNum(p) );
    Gia_ManForEachObjVec( vNodes, p, pObj, i )
    {
        if ( Gia_ObjIsAnd(pObj) )
        {
            pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
            if ( Gia_ObjSibl(p, Gia_ObjId(p, pObj)) )
                pNew->pSibls[Abc_Lit2Var(pObj->Value)] = Abc_Lit2Var(Gia_ObjSiblObj(p, Gia_ObjId(p, pObj))->Value);        
        }
        else if ( Gia_ObjIsCi(pObj) )
            pObj->Value = Gia_ManAppendCi( pNew );
        else if ( Gia_ObjIsCo(pObj) )
            pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
        else if ( Gia_ObjIsConst0(pObj) )
            pObj->Value = 0;
        else assert( 0 );
    }
    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
    Vec_IntFree( vNodes );
    return pNew;
}
示例#5
0
/**Function*************************************************************

  Synopsis    [Starts the process of returning values for internal nodes.]

  Description [Should be called when pCex is available, before probing 
  any object for its value using Gia_ManCounterExampleValueLookup().]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Gia_ManCounterExampleValueStart( Gia_Man_t * pGia, Abc_Cex_t * pCex )
{
    Gia_Obj_t * pObj, * pObjRi, * pObjRo;
    int Val0, Val1, nObjs, i, k, iBit = 0;
    assert( Gia_ManRegNum(pGia) > 0 ); // makes sense only for sequential AIGs
    assert( pGia->pData2 == NULL );    // if this fail, there may be a memory leak
    // allocate memory to store simulation bits for internal nodes
    pGia->pData2 = ABC_CALLOC( unsigned, Abc_BitWordNum( (pCex->iFrame + 1) * Gia_ManObjNum(pGia) ) );
    // the register values in the counter-example should be zero
    Gia_ManForEachRo( pGia, pObj, k )
        assert( Abc_InfoHasBit(pCex->pData, iBit++) == 0 );
    // iterate through the timeframes
    nObjs = Gia_ManObjNum(pGia);
    for ( i = 0; i <= pCex->iFrame; i++ )
    {
        // no need to set constant-0 node
        // set primary inputs according to the counter-example
        Gia_ManForEachPi( pGia, pObj, k )
            if ( Abc_InfoHasBit(pCex->pData, iBit++) )
                Abc_InfoSetBit( (unsigned *)pGia->pData2, nObjs * i + Gia_ObjId(pGia, pObj) );
        // compute values for each node
        Gia_ManForEachAnd( pGia, pObj, k )
        {
            Val0 = Abc_InfoHasBit( (unsigned *)pGia->pData2, nObjs * i + Gia_ObjFaninId0p(pGia, pObj) );
            Val1 = Abc_InfoHasBit( (unsigned *)pGia->pData2, nObjs * i + Gia_ObjFaninId1p(pGia, pObj) );
            if ( (Val0 ^ Gia_ObjFaninC0(pObj)) & (Val1 ^ Gia_ObjFaninC1(pObj)) )
                Abc_InfoSetBit( (unsigned *)pGia->pData2, nObjs * i + Gia_ObjId(pGia, pObj) );
        }
        // derive values for combinational outputs
        Gia_ManForEachCo( pGia, pObj, k )
        {
            Val0 = Abc_InfoHasBit( (unsigned *)pGia->pData2, nObjs * i + Gia_ObjFaninId0p(pGia, pObj) );
            if ( Val0 ^ Gia_ObjFaninC0(pObj) )
                Abc_InfoSetBit( (unsigned *)pGia->pData2, nObjs * i + Gia_ObjId(pGia, pObj) );
        }
示例#6
0
void Gia_ManMarkSeqGiaWithBoxes( Gia_Man_t * p, int fSeq )
{
    // CI order: real PIs + flop outputs + box outputs
    // CO order: box inputs + real POs + flop inputs
    Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
    Vec_Int_t * vRoots;
    Gia_Obj_t * pObj;
    int nRealCis = Tim_ManPiNum(pManTime);
    int nRealCos = Tim_ManPoNum(pManTime);
    int i, nRegs = fSeq ? Gia_ManRegBoxNum(p) : 0;
    assert( Gia_ManRegNum(p) == 0 );
    assert( Gia_ManBoxNum(p) > 0 );
    // mark the terminals
    Gia_ManIncrementTravId( p );
    Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
    for ( i = 0; i < nRealCis - nRegs; i++ )
        Gia_ObjSetTravIdCurrent( p, Gia_ManPi(p, i) );
    // collect flops reachable from the POs
    vRoots = Vec_IntAlloc( Gia_ManRegBoxNum(p) );
    for ( i = Gia_ManPoNum(p) - nRealCos; i < Gia_ManPoNum(p) - nRegs; i++ )
    {
        Gia_ObjSetTravIdCurrent( p, Gia_ManPo(p, i) );
        Gia_ManMarkSeqGiaWithBoxes_rec( p, Gia_ObjFanin0(Gia_ManPo(p, i)), vRoots );
    }
    // collect flops reachable from roots
    if ( fSeq )
    {
        Gia_ManForEachObjVec( vRoots, p, pObj, i )
        {
            assert( Gia_ObjIsCo(pObj) );
            Gia_ObjSetTravIdCurrent( p, pObj );
            Gia_ManMarkSeqGiaWithBoxes_rec( p, Gia_ObjFanin0(pObj), vRoots );
        }
        //printf( "Explored %d flops\n", Vec_IntSize(vRoots) );
    }
示例#7
0
/**Function*************************************************************

  Synopsis    [Prints stats for the AIG.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Gia_ManPrintStatsShort( Gia_Man_t * p )
{
    printf( "i/o =%7d/%7d  ", Gia_ManPiNum(p), Gia_ManPoNum(p) );
    printf( "ff =%7d  ", Gia_ManRegNum(p) );
    printf( "and =%8d  ", Gia_ManAndNum(p) );
    printf( "lev =%5d  ", Gia_ManLevelNum(p) );
//    printf( "mem =%5.2f MB", 12.0*Gia_ManObjNum(p)/(1<<20) );
    printf( "\n" );
}
示例#8
0
/**Function*************************************************************

  Synopsis    [Reorders flops for sequential AIGs with boxes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Gia_ManDupUnshuffleInputs( Gia_Man_t * p )
{
    Gia_Man_t * pNew;
    Gia_Obj_t * pObj;
    int i, nCIs, nAll, nPis;
    // sanity checks
    assert( Gia_ManIsNormalized(p) );
    assert( Gia_ManIsSeqWithBoxes(p) );
    Gia_ManFillValue( p );
    pNew = Gia_ManStart( Gia_ManObjNum(p) );
    pNew->pName = Abc_UtilStrsav( p->pName );
    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
    Gia_ManConst0(p)->Value = 0;
    // change input order
    // desired reorder:   PIs + NewCIs + FOs
    // current CI order:  PIs + FOs + NewCIs
    nCIs = Tim_ManPiNum( (Tim_Man_t *)p->pManTime );
    nAll = Tim_ManCiNum( (Tim_Man_t *)p->pManTime );
    nPis = nCIs - Gia_ManRegNum(p);
    assert( nAll == Gia_ManCiNum(p) );
    assert( nPis > 0 );
    // copy PIs first
    for ( i = 0; i < nPis; i++ )
        Gia_ManCi(p, i)->Value = Gia_ManAppendCi(pNew);
    // copy flops second
    for ( i = nAll - Gia_ManRegNum(p); i < nAll; i++ )
        Gia_ManCi(p, i)->Value = Gia_ManAppendCi(pNew);
    // copy new CIs last
    for ( i = nPis; i < nAll - Gia_ManRegNum(p); i++ )
        Gia_ManCi(p, i)->Value = Gia_ManAppendCi(pNew);
    printf( "Warning: Unshuffled CI order to be correct AIG with boxes.\n" );
    // other things
    Gia_ManForEachAnd( p, pObj, i )
        pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
    Gia_ManForEachCo( p, pObj, i )
        pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
    pNew->nConstrs = p->nConstrs;
    assert( Gia_ManIsNormalized(pNew) );
    Gia_ManDupRemapEquiv( pNew, p );
    return pNew;
}
示例#9
0
/**Function*************************************************************

  Synopsis    [Returns 1 if AIG has transition into init state.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Int2_ManCheckInit( Gia_Man_t * p )
{
    sat_solver * pSat;
    Cnf_Dat_t * pCnf;
    Gia_Man_t * pNew;
    Gia_Obj_t * pObj;
    Vec_Int_t * vLits;
    int i, Lit, RetValue = 0;
    assert( Gia_ManRegNum(p) > 0 );
    pNew = Jf_ManDeriveCnf( p, 0 );  
    pCnf = (Cnf_Dat_t *)pNew->pData; pNew->pData = NULL;
    pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
    if ( pSat != NULL )
    {
        vLits = Vec_IntAlloc( Gia_ManRegNum(p) );
        Gia_ManForEachRi( pNew, pObj, i )
        {
            Lit = pCnf->pVarNums[ Gia_ObjId(pNew, Gia_ObjFanin0(pObj)) ];
            Lit = Abc_Var2Lit( Lit, Gia_ObjFaninC0(pObj) );
            Vec_IntPush( vLits, Abc_LitNot(Lit) );
        }
示例#10
0
/**Function*************************************************************

  Synopsis    [Reparameterized to get rid of useless primary inputs.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Abs_RpmPerformOld( Gia_Man_t * p, int fVerbose )
{
//    extern Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, int fForwardOnly, int fBackwardOnly, int fInitial, int fVerbose );
    Aig_Man_t * pMan, * pTemp;
    Gia_Man_t * pNew, * pTmp;
    int nFlopsOld = Gia_ManRegNum(p);
    if ( fVerbose )
    {
        printf( "Original AIG:\n" );
        Gia_ManPrintStats( p, NULL );
    }

    // perform input trimming
    pNew = Gia_ManDupTrimmed( p, 1, 0, 0, -1 );
    if ( fVerbose )
    {
        printf( "After PI trimming:\n" );
        Gia_ManPrintStats( pNew, NULL );
    }
    // transform GIA
    pNew = Gia_ManDupIn2Ff( pTmp = pNew );
    Gia_ManStop( pTmp );
    if ( fVerbose )
    {
        printf( "After PI-2-FF transformation:\n" );
        Gia_ManPrintStats( pNew, NULL );
    }

    // derive AIG
    pMan = Gia_ManToAigSimple( pNew );
    Gia_ManStop( pNew );
    // perform min-reg retiming
    pMan = Saig_ManRetimeMinArea( pTemp = pMan, 10, 0, 0, 1, 0 );
    Aig_ManStop( pTemp );
    // derive GIA
    pNew = Gia_ManFromAigSimple( pMan );
    Aig_ManStop( pMan );
    if ( fVerbose )
    {
        printf( "After min-area retiming:\n" );
        Gia_ManPrintStats( pNew, NULL );
    }

    // transform back
    pNew = Gia_ManDupFf2In( pTmp = pNew, nFlopsOld );
    Gia_ManStop( pTmp );
    if ( fVerbose )
    {
        printf( "After FF-2-PI tranformation:\n" );
        Gia_ManPrintStats( pNew, NULL );
    }
    return pNew;
}
示例#11
0
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Gia_ManDetectSeqSignals( Gia_Man_t * p, int fSetReset, int fVerbose )
{
    Vec_Int_t * vSuper;
    Gia_Obj_t * pFlop, * pObjC, * pObj0, * pObj1, * pNode, * pTemp;
    int i, k, Ent, * pSets, * pResets, * pEnables;
    int nHaveSetReset = 0, nHaveEnable = 0;
    assert( Gia_ManRegNum(p) > 0 );
    pSets    = ABC_CALLOC( int, Gia_ManObjNum(p) );
    pResets  = ABC_CALLOC( int, Gia_ManObjNum(p) );
    pEnables = ABC_CALLOC( int, Gia_ManObjNum(p) );
    vSuper   = Vec_IntAlloc( 100 );
    Gia_ManForEachRi( p, pFlop, i )
    {
        pNode = Gia_ObjFanin0(pFlop);
        if ( !Gia_ObjIsAnd(pNode) )
            continue;
        // detect sets/resets
        Gia_CollectSuper( p, pNode, vSuper );
        if ( Gia_ObjFaninC0(pFlop) )
            Vec_IntForEachEntry( vSuper, Ent, k )
                pSets[Ent]++;
        else
            Vec_IntForEachEntry( vSuper, Ent, k )
                pResets[Ent]++;
        // detect enables
        if ( !Gia_ObjIsMuxType(pNode) )
            continue;
        pObjC = Gia_ObjRecognizeMux( pNode, &pObj0, &pObj1 );
        pTemp = Gia_ObjRiToRo( p, pFlop );
        if ( Gia_Regular(pObj0) != pTemp && Gia_Regular(pObj1) != pTemp )
            continue;
        if ( !Gia_ObjFaninC0(pFlop) )
        {
            pObj0 = Gia_Not(pObj0);
            pObj1 = Gia_Not(pObj1);
        }
        if ( Gia_IsComplement(pObjC) )
        {
            pObjC = Gia_Not(pObjC);
            pTemp = pObj0;
            pObj0 = pObj1;
            pObj1 = pTemp;
        }
        // detect controls
//        Gia_CollectSuper( p, pObjC, vSuper );
//        Vec_IntForEachEntry( vSuper, Ent, k )
//            pEnables[Ent]++;
        pEnables[Gia_ObjId(p, pObjC)]++;
        nHaveEnable++;
    }
示例#12
0
文件: giaTim.c 项目: aakarsh/ABC
ABC_NAMESPACE_IMPL_START


////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

  Synopsis    [Duplicates AIG in the DFS order while putting CIs first.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Gia_ManDupNormalize( Gia_Man_t * p )
{
    Gia_Man_t * pNew;
    Gia_Obj_t * pObj;
    int i;
    Gia_ManFillValue( p );
    pNew = Gia_ManStart( Gia_ManObjNum(p) );
    pNew->pName = Abc_UtilStrsav( p->pName );
    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
    Gia_ManConst0(p)->Value = 0;
    Gia_ManForEachCi( p, pObj, i )
        pObj->Value = Gia_ManAppendCi(pNew);
    Gia_ManForEachAnd( p, pObj, i )
        pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
    Gia_ManForEachCo( p, pObj, i )
        pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
    pNew->nConstrs = p->nConstrs;
    assert( Gia_ManIsNormalized(pNew) );
    Gia_ManDupRemapEquiv( pNew, p );
    return pNew;
}
示例#13
0
/**Function*************************************************************

  Synopsis    [Converts GIA into MiniAIG.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Mini_Aig_t * Gia_ManToMiniAig( Gia_Man_t * pGia )
{
    Mini_Aig_t * p;
    Gia_Obj_t * pObj;
    int i;
    // create the manager
    p = Mini_AigStart();
    Gia_ManConst0(pGia)->Value = Mini_AigLitConst0();
    // create primary inputs
    Gia_ManForEachCi( pGia, pObj, i )
        pObj->Value = Mini_AigCreatePi(p);
    // create internal nodes
    Gia_ManForEachAnd( pGia, pObj, i )
        pObj->Value = Mini_AigAnd( p, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
    // create primary outputs
    Gia_ManForEachCo( pGia, pObj, i )
        pObj->Value = Mini_AigCreatePo( p, Gia_ObjFanin0Copy(pObj) );
    // set registers
    Mini_AigSetRegNum( p, Gia_ManRegNum(pGia) );
    return p;
}
示例#14
0
/**Function*************************************************************

  Synopsis    [Creates AIG.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Cec_ManSim_t * Cec_ManSimStart( Gia_Man_t * pAig, Cec_ParSim_t *  pPars )  
{ 
    Cec_ManSim_t * p;
    p = ABC_ALLOC( Cec_ManSim_t, 1 );
    memset( p, 0, sizeof(Cec_ManSim_t) );
    p->pAig  = pAig;
    p->pPars = pPars;
    p->nWords = pPars->nWords;
    p->pSimInfo = ABC_CALLOC( int, Gia_ManObjNum(pAig) );
    p->vClassOld  = Vec_IntAlloc( 1000 );
    p->vClassNew  = Vec_IntAlloc( 1000 );
    p->vClassTemp = Vec_IntAlloc( 1000 );
    p->vRefinedC  = Vec_IntAlloc( 10000 );
    p->vCiSimInfo = Vec_PtrAllocSimInfo( Gia_ManCiNum(p->pAig), pPars->nWords );
    if ( pPars->fCheckMiter || Gia_ManRegNum(p->pAig) )
    {
        p->vCoSimInfo = Vec_PtrAllocSimInfo( Gia_ManCoNum(p->pAig), pPars->nWords );
        Vec_PtrCleanSimInfo( p->vCoSimInfo, 0, pPars->nWords );
    }
    p->iOut = -1;
    return p;
}
示例#15
0
/**Function*************************************************************

  Synopsis    [Create target with quantified inputs.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Bmc_CexTarget( Gia_Man_t * p, int nFrames )
{
    Gia_Man_t * pNew, * pTemp;
    int i, Limit = nFrames * Gia_ManPiNum(p);
    pNew = Bmc_CexTargetEnlarge( p, nFrames );
    for ( i = 0; i < Limit; i++ )
    {
        printf( "%3d : ", i );
        if ( i % Gia_ManPiNum(p) == 0 )
            Gia_ManPrintStats( pNew, NULL );
        pNew = Gia_ManDupExist( pTemp = pNew, i );
        Gia_ManStop( pTemp );
    }
    Gia_ManPrintStats( pNew, NULL );
    pNew = Gia_ManDupLastPis( pTemp = pNew, Gia_ManRegNum(p) );
    Gia_ManStop( pTemp );  
    Gia_ManPrintStats( pNew, NULL );
    pTemp = Gia_ManDupAppendCones( p, &pNew, 1, 1 );
    Gia_ManStop( pNew );
    Gia_AigerWrite( pTemp, "miter3.aig", 0, 0 );
    return pTemp;
}
示例#16
0
/**Function*************************************************************

  Synopsis    [Derives GIA without MUXes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Gia_ManDupNoMuxes( Gia_Man_t * p )
{
    Gia_Man_t * pNew, * pTemp;
    Gia_Obj_t * pObj;
    int i;
    assert( p->pMuxes != NULL );
    // start the new manager
    pNew = Gia_ManStart( 5000 );
    pNew->pName = Abc_UtilStrsav( p->pName );
    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
    // create constant
    Gia_ManConst0(p)->Value = 0;
    // create PIs
    Gia_ManForEachCi( p, pObj, i )
        pObj->Value = Gia_ManAppendCi( pNew );
    // create internal nodes
    Gia_ManHashStart( pNew );
    Gia_ManForEachAnd( p, pObj, i )
    {
        if ( Gia_ObjIsMuxId(p, i) )
            pObj->Value = Gia_ManHashMux( pNew, Gia_ObjFanin2Copy(p, pObj), Gia_ObjFanin1Copy(pObj), Gia_ObjFanin0Copy(pObj) );
        else if ( Gia_ObjIsXor(pObj) )
            pObj->Value = Gia_ManHashXor( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
        else 
            pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
    }
    Gia_ManHashStop( pNew );
    // create ROs
    Gia_ManForEachCo( p, pObj, i )
        pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
    // perform cleanup
    pNew = Gia_ManCleanup( pTemp = pNew );
    Gia_ManStop( pTemp );
    return pNew;
}
示例#17
0
文件: sscCore.c 项目: cloudcalvin/abc
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Ssc_PerformSweeping( Gia_Man_t * pAig, Gia_Man_t * pCare, Ssc_Pars_t * pPars )
{
    Ssc_Man_t * p;
    Gia_Man_t * pResult, * pTemp;
    Gia_Obj_t * pObj, * pRepr;
    abctime clk, clkTotal = Abc_Clock();
    int i, fCompl, nRefined, status;
clk = Abc_Clock();
    assert( Gia_ManRegNum(pCare) == 0 );
    assert( Gia_ManCiNum(pAig) == Gia_ManCiNum(pCare) );
    assert( Gia_ManIsNormalized(pAig) );
    assert( Gia_ManIsNormalized(pCare) );
    // reset random numbers
    Gia_ManRandom( 1 );
    // sweeping manager
    p = Ssc_ManStart( pAig, pCare, pPars );
    if ( p == NULL )
        return Gia_ManDup( pAig );
    if ( p->pPars->fVerbose )
        printf( "Care set produced %d hits out of %d.\n", Ssc_GiaEstimateCare(p->pFraig, 5), 640 );
    // perform simulation 
    while ( 1 ) 
    {
        // simulate care set
        Ssc_GiaRandomPiPattern( p->pFraig, 5, NULL );
        Ssc_GiaSimRound( p->pFraig );
        // transfer care patterns to user's AIG
        if ( !Ssc_GiaTransferPiPattern( pAig, p->pFraig, p->vPivot ) )
            break;
        // simulate the main AIG
        Ssc_GiaSimRound( pAig );
        nRefined = Ssc_GiaClassesRefine( pAig );
        if ( pPars->fVerbose ) 
            Gia_ManEquivPrintClasses( pAig, 0, 0 );
        if ( nRefined <= Gia_ManCandNum(pAig) / 100 )
            break;
    }
p->timeSimInit += Abc_Clock() - clk;

    // prepare user's AIG
    Gia_ManFillValue(pAig);
    Gia_ManConst0(pAig)->Value = 0;
    Gia_ManForEachCi( pAig, pObj, i )
        pObj->Value = Gia_Obj2Lit( p->pFraig, Gia_ManCi(p->pFraig, i) );
//    Gia_ManLevelNum(pAig);
    // prepare swept AIG (should be done after starting SAT solver in Ssc_ManStart)
    Gia_ManHashStart( p->pFraig );
    // perform sweeping
    Ssc_GiaResetPiPattern( pAig, pPars->nWords );
    Ssc_GiaSavePiPattern( pAig, p->vPivot );
    Gia_ManForEachCand( pAig, pObj, i )
    {
        if ( pAig->iPatsPi == 64 * pPars->nWords )
        {
clk = Abc_Clock();
            Ssc_GiaSimRound( pAig );
            Ssc_GiaClassesRefine( pAig );
            if ( pPars->fVerbose ) 
                Gia_ManEquivPrintClasses( pAig, 0, 0 );
            Ssc_GiaClassesCheckPairs( pAig, p->vDisPairs );
            Vec_IntClear( p->vDisPairs );
            // prepare next patterns
            Ssc_GiaResetPiPattern( pAig, pPars->nWords );
            Ssc_GiaSavePiPattern( pAig, p->vPivot );
p->timeSimSat += Abc_Clock() - clk;
//printf( "\n" );
        }
        if ( Gia_ObjIsAnd(pObj) )
            pObj->Value = Gia_ManHashAnd( p->pFraig, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
        if ( !Gia_ObjHasRepr(pAig, i) )
            continue;
        pRepr = Gia_ObjReprObj(pAig, i);
        if ( (int)pObj->Value == Abc_LitNotCond( pRepr->Value, pRepr->fPhase ^ pObj->fPhase ) )
        {
            Gia_ObjSetProved( pAig, i );
            continue;
        }
        assert( Abc_Lit2Var(pRepr->Value) != Abc_Lit2Var(pObj->Value) );
        fCompl = pRepr->fPhase ^ pObj->fPhase ^ Abc_LitIsCompl(pRepr->Value) ^ Abc_LitIsCompl(pObj->Value);

        // perform SAT call
clk = Abc_Clock();
        p->nSatCalls++;
        status = Ssc_ManCheckEquivalence( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl );
        if ( status == l_False )
        {
            p->nSatCallsUnsat++;
            pObj->Value = Abc_LitNotCond( pRepr->Value, pRepr->fPhase ^ pObj->fPhase );
            Gia_ObjSetProved( pAig, i );
        }
        else if ( status == l_True )
        {
            p->nSatCallsSat++;
            Ssc_GiaSavePiPattern( pAig, p->vPattern );
            Vec_IntPush( p->vDisPairs, Gia_ObjRepr(p->pAig, i) );
            Vec_IntPush( p->vDisPairs, i );
//            printf( "Try %2d and %2d: ", Gia_ObjRepr(p->pAig, i), i );
//            Vec_IntPrint( p->vPattern );
            if ( Gia_ObjRepr(p->pAig, i) > 0 )
                Ssc_GiaResimulateOneClass( p, Gia_ObjRepr(p->pAig, i), i );
        }
        else if ( status == l_Undef )
            p->nSatCallsUndec++;
        else assert( 0 );
p->timeSat += Abc_Clock() - clk;
    }
    if ( pAig->iPatsPi > 1 )
    {
clk = Abc_Clock();
        while ( pAig->iPatsPi < 64 * pPars->nWords )
            Ssc_GiaSavePiPattern( pAig, p->vPivot );
        Ssc_GiaSimRound( pAig );
        Ssc_GiaClassesRefine( pAig );
        if ( pPars->fVerbose ) 
            Gia_ManEquivPrintClasses( pAig, 0, 0 );
        Ssc_GiaClassesCheckPairs( pAig, p->vDisPairs );
        Vec_IntClear( p->vDisPairs );
p->timeSimSat += Abc_Clock() - clk;
    }
//    Gia_ManEquivPrintClasses( pAig, 1, 0 );
//    Gia_ManPrint( pAig );

    // generate the resulting AIG
    pResult = Gia_ManEquivReduce( pAig, 0, 0, 1, 0 );
    if ( pResult == NULL )
    {
        printf( "There is no equivalences.\n" );
        ABC_FREE( pAig->pReprs );
        ABC_FREE( pAig->pNexts );
        pResult = Gia_ManDup( pAig );
    }
    pResult = Gia_ManCleanup( pTemp = pResult );
    Gia_ManStop( pTemp );
    p->timeTotal = Abc_Clock() - clkTotal;
    if ( pPars->fVerbose )
        Ssc_ManPrintStats( p );
    Ssc_ManStop( p );
    // count the number of representatives
    if ( pPars->fVerbose ) 
    {
        Abc_Print( 1, "Reduction in AIG nodes:%8d  ->%8d (%6.2f %%).  ", 
            Gia_ManAndNum(pAig), Gia_ManAndNum(pResult), 
            100.0 - 100.0 * Gia_ManAndNum(pResult) / Gia_ManAndNum(pAig) );
        Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal );
    }
    return pResult;
}
示例#18
0
ABC_NAMESPACE_IMPL_START


////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

  Synopsis    [Derives GIA with MUXes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Gia_ManTisDupMuxes( Gia_Man_t * p )
{
    Gia_Man_t * pNew, * pTemp;
    Gia_Obj_t * pObj, * pFan0, * pFan1, * pFanC;
    int i;
    assert( p->pMuxes == NULL );
    ABC_FREE( p->pRefs );
    Gia_ManCreateRefs( p ); 
    // start the new manager
    pNew = Gia_ManStart( 5000 );
    pNew->pName = Abc_UtilStrsav( p->pName );
    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
    pNew->pMuxes = ABC_CALLOC( unsigned, pNew->nObjsAlloc );
    // create constant
    Gia_ManConst0(p)->Value = 0;
    // create PIs
    Gia_ManForEachCi( p, pObj, i )
        pObj->Value = Gia_ManAppendCi( pNew );
    // create internal nodes
    Gia_ManHashStart( pNew );
    Gia_ManForEachAnd( p, pObj, i )
    {
        if ( !Gia_ObjIsMuxType(pObj) || (Gia_ObjRefNum(p, Gia_ObjFanin0(pObj)) > 1 && Gia_ObjRefNum(p, Gia_ObjFanin1(pObj)) > 1) )
            pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
        else if ( Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
            pObj->Value = Gia_ManHashXorReal( pNew, Gia_ObjLitCopy(p, Gia_ObjToLit(p, pFan0)), Gia_ObjLitCopy(p, Gia_ObjToLit(p, pFan1)) );
        else
        {
            pFanC = Gia_ObjRecognizeMux( pObj, &pFan1, &pFan0 );
            pObj->Value = Gia_ManHashMuxReal( pNew, Gia_ObjLitCopy(p, Gia_ObjToLit(p, pFanC)), Gia_ObjLitCopy(p, Gia_ObjToLit(p, pFan1)), Gia_ObjLitCopy(p, Gia_ObjToLit(p, pFan0)) );
        }
    }
    Gia_ManHashStop( pNew );
    // create ROs
    Gia_ManForEachCo( p, pObj, i )
        pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
    // perform cleanup
    pNew = Gia_ManCleanup( pTemp = pNew );
    Gia_ManStop( pTemp );
    return pNew;
}
示例#19
0
/**Function*************************************************************

  Synopsis    [Performs structural hashing on the LUT functions.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void * Dsm_ManDeriveGia( void * pGia, int fUseMuxes )
{
    Gia_Man_t * p = (Gia_Man_t *)pGia;
    Gia_Man_t * pNew, * pTemp;
    Vec_Int_t * vCover, * vLeaves;
    Gia_Obj_t * pObj; 
    int k, i, iLut, iVar;
    word * pTruth;
    assert( Gia_ManHasMapping(p) );   
    // create new manager
    pNew = Gia_ManStart( 6*Gia_ManObjNum(p)/5 + 100 );
    pNew->pName = Abc_UtilStrsav( p->pName );
    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
    pNew->vLevels = Vec_IntStart( 6*Gia_ManObjNum(p)/5 + 100 );
    if ( fUseMuxes )
        pNew->pMuxes = ABC_CALLOC( unsigned, pNew->nObjsAlloc );
    // map primary inputs
    Gia_ManFillValue(p);
    Gia_ManConst0(p)->Value = 0;
    Gia_ManForEachCi( p, pObj, i )
        pObj->Value = Gia_ManAppendCi(pNew);
    // iterate through nodes used in the mapping
    vLeaves = Vec_IntAlloc( 16 );
    vCover  = Vec_IntAlloc( 1 << 16 );
    Gia_ManHashStart( pNew );
    Gia_ObjComputeTruthTableStart( p, Gia_ManLutSizeMax(p) );
    Gia_ManForEachAnd( p, pObj, iLut )
    {
        if ( Gia_ObjIsBuf(pObj) )
        {
            pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) );
            continue;
        }
        if ( !Gia_ObjIsLut(p, iLut) )
            continue;
        // collect leaves
        Vec_IntClear( vLeaves );
        Gia_LutForEachFanin( p, iLut, iVar, k )
            Vec_IntPush( vLeaves, iVar );
        pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ManObj(p, iLut), vLeaves );
        // collect incoming literals
        Vec_IntClear( vLeaves );
        Gia_LutForEachFanin( p, iLut, iVar, k )
            Vec_IntPush( vLeaves, Gia_ManObj(p, iVar)->Value );
        Gia_ManObj(p, iLut)->Value = Dsm_ManTruthToGia( pNew, pTruth, vLeaves, vCover );
    }
    Gia_ObjComputeTruthTableStop( p );
    Gia_ManForEachCo( p, pObj, i )
        pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
    Gia_ManHashStop( pNew );
    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
    Vec_IntFree( vLeaves );
    Vec_IntFree( vCover );
/*
    Gia_ManForEachAnd( pNew, pObj, i )
    {
        int iLev  = Gia_ObjLevelId(pNew, i);
        int iLev0 = Gia_ObjLevelId(pNew, Gia_ObjFaninId0(pObj, i));
        int iLev1 = Gia_ObjLevelId(pNew, Gia_ObjFaninId1(pObj, i));
        assert( iLev == 1 + Abc_MaxInt(iLev0, iLev1) );
    }
*/
    // perform cleanup
    pNew = Gia_ManCleanup( pTemp = pNew );
    Gia_ManStop( pTemp );
    return pNew;
}
示例#20
0
    Gia_ManForEachPi( p, pObj, i )
        pObj->Value = Gia_ManAppendCi( pNew );
    Gia_ManForEachAnd( p, pObj, i )
    {
        iCtrl = Gia_ManAppendCi(pNew);
        iThis = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
        if ( fUseMuxes )
            pObj->Value = Gia_ManHashMux( pNew, iCtrl, pObj->Value, iThis );
        else
            pObj->Value = iThis;
    }
    Gia_ManForEachCo( p, pObj, i )
        pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
    pNew = Gia_ManCleanup( pTemp = pNew );
    Gia_ManStop( pTemp );
    assert( Gia_ManPiNum(pNew) == Gia_ManRegNum(p) + 2 * Gia_ManPiNum(p) + Gia_ManAndNum(p) );
    return pNew;
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Gia_ManStuckAtUnfold( Gia_Man_t * p )
示例#21
0
/**Function*************************************************************

  Synopsis    [Returns one if this is a seq AIG with non-trivial boxes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Gia_ManIsSeqWithBoxes( Gia_Man_t * p )
{
    return (Gia_ManRegNum(p) > 0 && Gia_ManBoxNum(p) > 0);
}
示例#22
0
/**Function*************************************************************

  Synopsis    [Core procedure for SAT sweeping.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars, int fSilent )
{
    int fOutputResult = 0;
    Cec_ParSat_t ParsSat, * pParsSat = &ParsSat;
    Cec_ParSim_t ParsSim, * pParsSim = &ParsSim;
    Gia_Man_t * pIni, * pSrm, * pTemp;
    Cec_ManFra_t * p;
    Cec_ManSim_t * pSim;
    Cec_ManPat_t * pPat;
    int i, fTimeOut = 0, nMatches = 0;
    abctime clk, clk2, clkTotal = Abc_Clock();

    // duplicate AIG and transfer equivalence classes
    Gia_ManRandom( 1 );
    pIni = Gia_ManDup(pAig);
    pIni->pReprs = pAig->pReprs; pAig->pReprs = NULL;
    pIni->pNexts = pAig->pNexts; pAig->pNexts = NULL;

    // prepare the managers
    // SAT sweeping
    p = Cec_ManFraStart( pIni, pPars );
    if ( pPars->fDualOut )
        pPars->fColorDiff = 1;
    // simulation
    Cec_ManSimSetDefaultParams( pParsSim );
    pParsSim->nWords      = pPars->nWords;
    pParsSim->nFrames     = pPars->nRounds;
    pParsSim->fCheckMiter = pPars->fCheckMiter;
    pParsSim->fDualOut    = pPars->fDualOut;
    pParsSim->fVerbose    = pPars->fVerbose;
    pSim = Cec_ManSimStart( p->pAig, pParsSim );
    // SAT solving
    Cec_ManSatSetDefaultParams( pParsSat );
    pParsSat->nBTLimit = pPars->nBTLimit;
    pParsSat->fVerbose = pPars->fVeryVerbose;
    // simulation patterns
    pPat = Cec_ManPatStart();
    pPat->fVerbose = pPars->fVeryVerbose;

    // start equivalence classes
clk = Abc_Clock();
    if ( p->pAig->pReprs == NULL )
    {
        if ( Cec_ManSimClassesPrepare(pSim, -1) || Cec_ManSimClassesRefine(pSim) )
        {
            Gia_ManStop( p->pAig );
            p->pAig = NULL;
            goto finalize;
        }
    }
p->timeSim += Abc_Clock() - clk;
    // perform solving
    for ( i = 1; i <= pPars->nItersMax; i++ )
    {
        clk2 = Abc_Clock();
        nMatches = 0;
        if ( pPars->fDualOut )
        {
            nMatches = Gia_ManEquivSetColors( p->pAig, pPars->fVeryVerbose );
//            p->pAig->pIso = Cec_ManDetectIsomorphism( p->pAig );
//            Gia_ManEquivTransform( p->pAig, 1 );
        }
        pSrm = Cec_ManFraSpecReduction( p ); 

//        Gia_AigerWrite( pSrm, "gia_srm.aig", 0, 0 );

        if ( pPars->fVeryVerbose )
            Gia_ManPrintStats( pSrm, NULL );
        if ( Gia_ManCoNum(pSrm) == 0 )
        {
            Gia_ManStop( pSrm );
            if ( p->pPars->fVerbose )
                Abc_Print( 1, "Considered all available candidate equivalences.\n" );
            if ( pPars->fDualOut && Gia_ManAndNum(p->pAig) > 0 )
            {
                if ( pPars->fColorDiff )
                {
                    if ( p->pPars->fVerbose )
                        Abc_Print( 1, "Switching into reduced mode.\n" );
                    pPars->fColorDiff = 0;
                }
                else
                {
                    if ( p->pPars->fVerbose )
                        Abc_Print( 1, "Switching into normal mode.\n" );
                    pPars->fDualOut = 0;
                }
                continue;
            }
            break;
        }
clk = Abc_Clock();
        if ( pPars->fRunCSat )
            Cec_ManSatSolveCSat( pPat, pSrm, pParsSat ); 
        else
            Cec_ManSatSolve( pPat, pSrm, pParsSat ); 
p->timeSat += Abc_Clock() - clk;
        if ( Cec_ManFraClassesUpdate( p, pSim, pPat, pSrm ) )
        {
            Gia_ManStop( pSrm );
            Gia_ManStop( p->pAig );
            p->pAig = NULL;
            goto finalize;
        }
        Gia_ManStop( pSrm );

        // update the manager
        pSim->pAig = p->pAig = Gia_ManEquivReduceAndRemap( pTemp = p->pAig, 0, pParsSim->fDualOut );
        if ( p->pAig == NULL )
        {
            p->pAig = pTemp;
            break;
        }
        Gia_ManStop( pTemp );
        if ( p->pPars->fVerbose )
        {
            Abc_Print( 1, "%3d : P =%7d. D =%7d. F =%6d. M = %7d. And =%8d. ", 
                i, p->nAllProved, p->nAllDisproved, p->nAllFailed, nMatches, Gia_ManAndNum(p->pAig) );
            Abc_PrintTime( 1, "Time", Abc_Clock() - clk2 );
        }
        if ( Gia_ManAndNum(p->pAig) == 0 )
        {
            if ( p->pPars->fVerbose )
                Abc_Print( 1, "Network after reduction is empty.\n" );
            break;
        }
        // check resource limits
        if ( p->pPars->TimeLimit && (Abc_Clock() - clkTotal)/CLOCKS_PER_SEC >= p->pPars->TimeLimit )
        {
            fTimeOut = 1;
            break;
        }
//        if ( p->nAllFailed && !p->nAllProved && !p->nAllDisproved )
        if ( p->nAllFailed > p->nAllProved + p->nAllDisproved )
        {
            if ( pParsSat->nBTLimit >= 10001 )
                break;
            if ( pPars->fSatSweeping )
            {
                if ( p->pPars->fVerbose )
                    Abc_Print( 1, "Exceeded the limit on the number of conflicts (%d).\n", pParsSat->nBTLimit );
                break;
            }
            pParsSat->nBTLimit *= 10;
            if ( p->pPars->fVerbose )
            {
                if ( p->pPars->fVerbose )
                    Abc_Print( 1, "Increasing conflict limit to %d.\n", pParsSat->nBTLimit );
                if ( fOutputResult )
                {
                    Gia_AigerWrite( p->pAig, "gia_cec_temp.aig", 0, 0 );
                    Abc_Print( 1,"The result is written into file \"%s\".\n", "gia_cec_temp.aig" );
                }
            }
        }
        if ( pPars->fDualOut && pPars->fColorDiff && (Gia_ManAndNum(p->pAig) < 100000 || p->nAllProved + p->nAllDisproved < 10) )
        {
            if ( p->pPars->fVerbose )
                Abc_Print( 1, "Switching into reduced mode.\n" );
            pPars->fColorDiff = 0;
        }
//        if ( pPars->fDualOut && Gia_ManAndNum(p->pAig) < 20000 )
        else if ( pPars->fDualOut && (Gia_ManAndNum(p->pAig) < 20000 || p->nAllProved + p->nAllDisproved < 10) )
        {
            if ( p->pPars->fVerbose )
                Abc_Print( 1, "Switching into normal mode.\n" );
            pPars->fColorDiff = 0;
            pPars->fDualOut = 0;
        }
    }
finalize:
    if ( p->pPars->fVerbose && p->pAig )
    {
        Abc_Print( 1, "NBeg = %d. NEnd = %d. (Gain = %6.2f %%).  RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n", 
            Gia_ManAndNum(pAig), Gia_ManAndNum(p->pAig), 
            100.0*(Gia_ManAndNum(pAig)-Gia_ManAndNum(p->pAig))/(Gia_ManAndNum(pAig)?Gia_ManAndNum(pAig):1), 
            Gia_ManRegNum(pAig), Gia_ManRegNum(p->pAig), 
            100.0*(Gia_ManRegNum(pAig)-Gia_ManRegNum(p->pAig))/(Gia_ManRegNum(pAig)?Gia_ManRegNum(pAig):1) );
        Abc_PrintTimeP( 1, "Sim ", p->timeSim, Abc_Clock() - (int)clkTotal );
        Abc_PrintTimeP( 1, "Sat ", p->timeSat-pPat->timeTotalSave, Abc_Clock() - (int)clkTotal );
        Abc_PrintTimeP( 1, "Pat ", p->timePat+pPat->timeTotalSave, Abc_Clock() - (int)clkTotal );
        Abc_PrintTime( 1, "Time", (int)(Abc_Clock() - clkTotal) );
    }

    pTemp = p->pAig; p->pAig = NULL;
    if ( pTemp == NULL && pSim->iOut >= 0 )
    {
        if ( !fSilent )
        Abc_Print( 1, "Disproved at least one output of the miter (zero-based number %d).\n", pSim->iOut );
        pPars->iOutFail = pSim->iOut;
    }
    else if ( pSim->pCexes && !fSilent )
        Abc_Print( 1, "Disproved %d outputs of the miter.\n", pSim->nOuts );
    if ( fTimeOut && !fSilent )
        Abc_Print( 1, "Timed out after %d seconds.\n", (int)((double)Abc_Clock() - clkTotal)/CLOCKS_PER_SEC );

    pAig->pCexComb = pSim->pCexComb; pSim->pCexComb = NULL;
    Cec_ManSimStop( pSim );
    Cec_ManPatStop( pPat );
    Cec_ManFraStop( p );
    return pTemp;
}