diff options
58 files changed, 6891 insertions, 1748 deletions
| @@ -12,7 +12,7 @@ MODULES := \  	src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr \  	src/bdd/parse src/bdd/reo src/bdd/cas \  	src/map/fpga src/map/mapper src/map/mio src/map/super \ -	src/map/if src/map/amap \ +	src/map/if src/map/amap src/map/cov \  	src/misc/extra src/misc/mvc src/misc/st src/misc/util \  	src/misc/nm src/misc/vec src/misc/hash \  	src/misc/bzlib src/misc/zlib \ @@ -1954,14 +1954,6 @@ SOURCE=.\src\map\if\ifTruth.c  SOURCE=.\src\map\if\ifUtil.c  # End Source File  # End Group -# Begin Group "ply" - -# PROP Default_Filter "" -# End Group -# Begin Group "pcm" - -# PROP Default_Filter "" -# End Group  # Begin Group "amap"  # PROP Default_Filter "" @@ -2026,6 +2018,46 @@ SOURCE=.\src\map\amap\amapRule.c  SOURCE=.\src\map\amap\amapUniq.c  # End Source File  # End Group +# Begin Group "cov" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\map\cov\cov.h +# End Source File +# Begin Source File + +SOURCE=.\src\map\cov\covBuild.c +# End Source File +# Begin Source File + +SOURCE=.\src\map\cov\covCore.c +# End Source File +# Begin Source File + +SOURCE=.\src\map\cov\covInt.h +# End Source File +# Begin Source File + +SOURCE=.\src\map\cov\covMan.c +# End Source File +# Begin Source File + +SOURCE=.\src\map\cov\covMinEsop.c +# End Source File +# Begin Source File + +SOURCE=.\src\map\cov\covMinMan.c +# End Source File +# Begin Source File + +SOURCE=.\src\map\cov\covMinSop.c +# End Source File +# Begin Source File + +SOURCE=.\src\map\cov\covMinUtil.c +# End Source File +# End Group  # End Group  # Begin Group "misc" @@ -3547,6 +3579,10 @@ SOURCE=.\src\aig\cec\cecCec.c  # End Source File  # Begin Source File +SOURCE=.\src\aig\cec\cecChoice.c +# End Source File +# Begin Source File +  SOURCE=.\src\aig\cec\cecClass.c  # End Source File  # Begin Source File @@ -3555,6 +3591,10 @@ SOURCE=.\src\aig\cec\cecCore.c  # End Source File  # Begin Source File +SOURCE=.\src\aig\cec\cecCorr.c +# End Source File +# Begin Source File +  SOURCE=.\src\aig\cec\cecInt.h  # End Source File  # Begin Source File @@ -3651,6 +3691,10 @@ SOURCE=.\src\aig\gia\giaCof.c  # End Source File  # Begin Source File +SOURCE=.\src\aig\gia\giaCSat.c +# End Source File +# Begin Source File +  SOURCE=.\src\aig\gia\giaDfs.c  # End Source File  # Begin Source File @@ -3703,6 +3747,10 @@ SOURCE=.\src\aig\gia\giaMap.c  # End Source File  # Begin Source File +SOURCE=.\src\aig\gia\giaPat.c +# End Source File +# Begin Source File +  SOURCE=.\src\aig\gia\giaRetime.c  # End Source File  # Begin Source File diff --git a/src/aig/aig/aig.h b/src/aig/aig/aig.h index d9e57f7e..1f51f300 100644 --- a/src/aig/aig/aig.h +++ b/src/aig/aig/aig.h @@ -647,7 +647,7 @@ extern void            Aig_ManCleanPioNumbers( Aig_Man_t * p );  extern int             Aig_ManChoiceNum( Aig_Man_t * p );  extern char *          Aig_FileNameGenericAppend( char * pBase, char * pSuffix );  extern unsigned        Aig_ManRandom( int fReset ); -extern void            Aig_ManRandomInfo( Vec_Ptr_t * vInfo, int iWordStart, int iWordStop ); +extern void            Aig_ManRandomInfo( Vec_Ptr_t * vInfo, int iInputStart, int iWordStart, int iWordStop );  extern void            Aig_NodeUnionLists( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr );  extern void            Aig_NodeIntersectLists( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr ); diff --git a/src/aig/aig/aigMffc.c b/src/aig/aig/aigMffc.c index 10887712..f681c76a 100644 --- a/src/aig/aig/aigMffc.c +++ b/src/aig/aig/aigMffc.c @@ -176,9 +176,15 @@ void Aig_NodeMffsSupp_rec( Aig_Man_t * p, Aig_Obj_t * pNode, unsigned LevelMin,  int Aig_NodeMffsSupp( Aig_Man_t * p, Aig_Obj_t * pNode, int LevelMin, Vec_Ptr_t * vSupp )  {      int ConeSize1, ConeSize2; +    if ( vSupp ) Vec_PtrClear( vSupp ); +    if ( !Aig_ObjIsNode(pNode) ) +    { +        if ( Aig_ObjIsPi(pNode) && vSupp ) +            Vec_PtrPush( vSupp, pNode ); +        return 0; +    }      assert( !Aig_IsComplement(pNode) );      assert( Aig_ObjIsNode(pNode) ); -    if ( vSupp ) Vec_PtrClear( vSupp );      Aig_ManIncrementTravId( p );      ConeSize1 = Aig_NodeDeref_rec( pNode, LevelMin, NULL, NULL );      Aig_NodeMffsSupp_rec( p, pNode, LevelMin, vSupp, 1, NULL ); diff --git a/src/aig/aig/aigRepr.c b/src/aig/aig/aigRepr.c index 0ab02144..2d2f2f3d 100644 --- a/src/aig/aig/aigRepr.c +++ b/src/aig/aig/aigRepr.c @@ -287,6 +287,10 @@ Aig_Man_t * Aig_ManDupRepr( Aig_Man_t * p, int fOrdered )      }      else      { +//        Aig_ManForEachObj( p, pObj, i ) +//            if ( p->pReprs[i] ) +//                printf( "Substituting %d for %d.\n", p->pReprs[i]->Id, pObj->Id ); +          Aig_ManForEachPo( p, pObj, i )              Aig_ManDupRepr_rec( pNew, p, Aig_ObjFanin0(pObj) );      } diff --git a/src/aig/aig/aigTable.c b/src/aig/aig/aigTable.c index 7ca4bb32..81635357 100644 --- a/src/aig/aig/aigTable.c +++ b/src/aig/aig/aigTable.c @@ -236,6 +236,7 @@ void Aig_TableProfile( Aig_Man_t * p )  {      Aig_Obj_t * pEntry;      int i, Counter; +    printf( "Table size = %d. Entries = %d.\n", p->nTableSize, Aig_ManNodeNum(p) );      for ( i = 0; i < p->nTableSize; i++ )      {          Counter = 0; diff --git a/src/aig/aig/aigUtil.c b/src/aig/aig/aigUtil.c index 1852ff03..80d1f527 100644 --- a/src/aig/aig/aigUtil.c +++ b/src/aig/aig/aigUtil.c @@ -1189,11 +1189,11 @@ unsigned Aig_ManRandom( int fReset )    SeeAlso     []  ***********************************************************************/ -void Aig_ManRandomInfo( Vec_Ptr_t * vInfo, int iWordStart, int iWordStop ) +void Aig_ManRandomInfo( Vec_Ptr_t * vInfo, int iInputStart, int iWordStart, int iWordStop )  {      unsigned * pInfo;      int i, w; -    Vec_PtrForEachEntry( vInfo, pInfo, i ) +    Vec_PtrForEachEntryStart( vInfo, pInfo, i, iInputStart )          for ( w = iWordStart; w < iWordStop; w++ )              pInfo[w] = Aig_ManRandom(0);  } diff --git a/src/aig/cec/cec.h b/src/aig/cec/cec.h index a97bd958..e26455ba 100644 --- a/src/aig/cec/cec.h +++ b/src/aig/cec/cec.h @@ -61,6 +61,7 @@ struct Cec_ParSim_t_      int              fCheckMiter;   // the circuit is the miter      int              fFirstStop;    // stop on the first sat output      int              fSeqSimulate;  // performs sequential simulation +    int              fLatchCorr;    // consider only latch outputs      int              fVeryVerbose;  // verbose stats      int              fVerbose;      // verbose stats  }; @@ -113,6 +114,36 @@ struct Cec_ParCec_t_      int              fVerbose;      // verbose stats  }; +// sequential register correspodence parameters +typedef struct Cec_ParCor_t_ Cec_ParCor_t; +struct Cec_ParCor_t_ +{ +    int              nWords;        // the number of simulation words +    int              nRounds;       // the number of simulation rounds +    int              nFrames;       // the number of time frames +    int              nBTLimit;      // conflict limit at a node +    int              fLatchCorr;    // consider only latch outputs +    int              fUseRings;     // use rings +    int              fUseCSat;      // use circuit-based solver +    int              fFirstStop;    // stop on the first sat output +    int              fUseSmartCnf;  // use smart CNF computation +    int              fVeryVerbose;  // verbose stats +    int              fVerbose;      // verbose stats +}; + +// sequential register correspodence parameters +typedef struct Cec_ParChc_t_ Cec_ParChc_t; +struct Cec_ParChc_t_ +{ +    int              nWords;        // the number of simulation words +    int              nRounds;       // the number of simulation rounds +    int              nBTLimit;      // conflict limit at a node +    int              fFirstStop;    // stop on the first sat output +    int              fUseSmartCnf;  // use smart CNF computation +    int              fVeryVerbose;  // verbose stats +    int              fVerbose;      // verbose stats +}; +  ////////////////////////////////////////////////////////////////////////  ///                      MACRO DEFINITIONS                           ///  //////////////////////////////////////////////////////////////////////// @@ -124,12 +155,18 @@ struct Cec_ParCec_t_  /*=== cecCec.c ==========================================================*/  extern int           Cec_ManVerify( Gia_Man_t * p, Cec_ParCec_t * pPars );  extern int           Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose ); +/*=== cecChoice.c ==========================================================*/ +extern Gia_Man_t *   Cec_ManChoiceComputation( Gia_Man_t * pAig, Cec_ParChc_t * pPars ); +/*=== cecCorr.c ==========================================================*/ +extern Gia_Man_t *   Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars );  /*=== cecCore.c ==========================================================*/  extern void          Cec_ManSatSetDefaultParams( Cec_ParSat_t * p );  extern void          Cec_ManSimSetDefaultParams( Cec_ParSim_t * p );  extern void          Cec_ManSmfSetDefaultParams( Cec_ParSmf_t * p );  extern void          Cec_ManFraSetDefaultParams( Cec_ParFra_t * p );  extern void          Cec_ManCecSetDefaultParams( Cec_ParCec_t * p ); +extern void          Cec_ManCorSetDefaultParams( Cec_ParCor_t * p ); +extern void          Cec_ManChcSetDefaultParams( Cec_ParChc_t * p );  extern Gia_Man_t *   Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars );  extern Gia_Man_t *   Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars );  extern void          Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars ); diff --git a/src/aig/cec/cecChoice.c b/src/aig/cec/cecChoice.c new file mode 100644 index 00000000..ff30e1bb --- /dev/null +++ b/src/aig/cec/cecChoice.c @@ -0,0 +1,51 @@ +/**CFile**************************************************************** + +  FileName    [cecChoice.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Combinatinoal equivalence checking.] + +  Synopsis    [Computation of structural choices.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: cecChoice.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Gia_Man_t * Cec_ManChoiceComputation( Gia_Man_t * pAig, Cec_ParChc_t * pPars ) +{ +    return NULL; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/cec/cecClass.c b/src/aig/cec/cecClass.c index 26ff543a..a8ed017a 100644 --- a/src/aig/cec/cecClass.c +++ b/src/aig/cec/cecClass.c @@ -293,6 +293,48 @@ int Cec_ManSimClassRefineOne( Cec_ManSim_t * p, int i )  /**Function************************************************************* +  Synopsis    [Refines one equivalence class.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Cec_ManSimClassRemoveOne( Cec_ManSim_t * p, int i ) +{ +    int iRepr, Ent; +    if ( Gia_ObjIsConst(p->pAig, i) ) +    { +        Gia_ObjSetRepr( p->pAig, i, GIA_VOID ); +        return 1; +    } +    if ( !Gia_ObjIsClass(p->pAig, i) ) +        return 0; +    assert( Gia_ObjIsClass(p->pAig, i) ); +    iRepr = Gia_ObjRepr( p->pAig, i ); +    if ( iRepr == GIA_VOID ) +        iRepr = i; +    // collect nodes +    Vec_IntClear( p->vClassOld ); +    Vec_IntClear( p->vClassNew ); +    Gia_ClassForEachObj( p->pAig, iRepr, Ent ) +    { +        if ( Ent == i ) +            Vec_IntPush( p->vClassNew, Ent ); +        else +            Vec_IntPush( p->vClassOld, Ent ); +    } +    assert( Vec_IntSize( p->vClassNew ) == 1 ); +    Cec_ManSimClassCreate( p->pAig, p->vClassOld ); +    Cec_ManSimClassCreate( p->pAig, p->vClassNew ); +    assert( !Gia_ObjIsClass(p->pAig, i) ); +    return 1; +} + +/**Function************************************************************* +    Synopsis    [Computes hash key of the simuation info.]    Description [] @@ -797,8 +839,12 @@ int Cec_ManSimClassesPrepare( Cec_ManSim_t * p )      p->pAig->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p->pAig) );      p->pAig->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p->pAig) );      // set starting representative of internal nodes to be constant 0 -    Gia_ManForEachObj( p->pAig, pObj, i ) -        Gia_ObjSetRepr( p->pAig, i, Gia_ObjIsAnd(pObj) ? 0 : GIA_VOID ); +    if ( p->pPars->fLatchCorr ) +        Gia_ManForEachObj( p->pAig, pObj, i ) +            Gia_ObjSetRepr( p->pAig, i, GIA_VOID ); +    else +        Gia_ManForEachObj( p->pAig, pObj, i ) +            Gia_ObjSetRepr( p->pAig, i, Gia_ObjIsAnd(pObj) ? 0 : GIA_VOID );      // if sequential simulation, set starting representative of ROs to be constant 0      if ( p->pPars->fSeqSimulate )          Gia_ManForEachRo( p->pAig, pObj, i ) diff --git a/src/aig/cec/cecCore.c b/src/aig/cec/cecCore.c index 9274dcb8..d3c54948 100644 --- a/src/aig/cec/cecCore.c +++ b/src/aig/cec/cecCore.c @@ -156,6 +156,56 @@ void Cec_ManCecSetDefaultParams( Cec_ParCec_t * p )  /**Function************************************************************* +  Synopsis    [This procedure sets default parameters.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Cec_ManCorSetDefaultParams( Cec_ParCor_t * p ) +{ +    memset( p, 0, sizeof(Cec_ParCor_t) ); +    p->nWords         =      15;  // the number of simulation words +    p->nRounds        =      15;  // the number of simulation rounds +    p->nFrames        =       1;  // the number of time frames +    p->nBTLimit       =     100;  // conflict limit at a node +    p->fLatchCorr     =       0;  // consider only latch outputs +    p->fUseRings      =       1;  // combine classes into rings +    p->fUseCSat       =       1;  // use circuit-based solver +    p->fFirstStop     =       0;  // stop on the first sat output +    p->fUseSmartCnf   =       0;  // use smart CNF computation +    p->fVeryVerbose   =       0;  // verbose stats +    p->fVerbose       =       0;  // verbose stats +}   + +/**Function************************************************************* + +  Synopsis    [This procedure sets default parameters.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Cec_ManChcSetDefaultParams( Cec_ParChc_t * p ) +{ +    memset( p, 0, sizeof(Cec_ParChc_t) ); +    p->nWords         =      15;  // the number of simulation words +    p->nRounds        =      15;  // the number of simulation rounds +    p->nBTLimit       =    1000;  // conflict limit at a node +    p->fFirstStop     =       0;  // stop on the first sat output +    p->fUseSmartCnf   =       0;  // use smart CNF computation +    p->fVeryVerbose   =       0;  // verbose stats +    p->fVerbose       =       0;  // verbose stats +}   + +/**Function************************************************************* +    Synopsis    [Core procedure for SAT sweeping.]    Description [] @@ -171,7 +221,8 @@ Gia_Man_t * Cec_ManSatSolving( Gia_Man_t * pAig, Cec_ParSat_t * pPars )      Cec_ManPat_t * pPat;      pPat = Cec_ManPatStart();      Cec_ManSatSolve( pPat, pAig, pPars ); -    pNew = Gia_ManDupDfsSkip( pAig ); +//    pNew = Gia_ManDupDfsSkip( pAig ); +    pNew = Gia_ManDup( pAig );      Cec_ManPatStop( pPat );      return pNew;  } @@ -193,7 +244,7 @@ void Cec_ManSimulation( Gia_Man_t * pAig, Cec_ParSim_t * pPars )      int RetValue, clkTotal = clock();      if ( pPars->fSeqSimulate )          printf( "Performing sequential simulation of %d frames with %d words.\n",  -            pPars->nWords, pPars->nRounds ); +            pPars->nRounds, pPars->nWords );      Aig_ManRandom( 1 );      pSim = Cec_ManSimStart( pAig, pPars );      if ( pAig->pReprs == NULL ) @@ -286,7 +337,7 @@ p->timeSim += clock() - clk;  //        Gia_WriteAiger( pSrm, "gia_srm.aig", 0, 0 );          if ( pPars->fVeryVerbose ) -            Gia_ManPrintStats( pSrm ); +            Gia_ManPrintStats( pSrm, 0 );          if ( Gia_ManCoNum(pSrm) == 0 )          {              Gia_ManStop( pSrm ); diff --git a/src/aig/cec/cecCorr.c b/src/aig/cec/cecCorr.c new file mode 100644 index 00000000..abc76416 --- /dev/null +++ b/src/aig/cec/cecCorr.c @@ -0,0 +1,757 @@ +/**CFile**************************************************************** + +  FileName    [cecLcorr.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Combinatinoal equivalence checking.] + +  Synopsis    [Flop correspondence computation.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: cecLcorr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cecInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +static void Gia_ManCorrSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f ); + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Computes the real value of the literal w/o spec reduction.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Gia_ManCorrSpecReal( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f ) +{ +    if ( Gia_ObjIsAnd(pObj) ) +    { +        Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), f ); +        Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin1(pObj), f ); +        return Gia_ManHashAnd( pNew, Gia_ObjFanin0CopyF(p, f, pObj), Gia_ObjFanin1CopyF(p, f, pObj) ); +    } +    assert( f && Gia_ObjIsRo(p, pObj) ); +    pObj = Gia_ObjRoToRi( p, pObj ); +    Gia_ManCorrSpecReduce_rec( pNew, p, Gia_ObjFanin0(pObj), f-1 ); +    return Gia_ObjFanin0CopyF( p, f-1, pObj ); +} + +/**Function************************************************************* + +  Synopsis    [Recursively performs speculative reduction for the object.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Gia_ManCorrSpecReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int f ) +{ +    Gia_Obj_t * pRepr; +    int iLitNew; +    if ( ~Gia_ObjCopyF(p, f, pObj) ) +        return; +    if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) ) +    { +        if ( !Gia_ObjIsFailedPair(p, Gia_ObjId(p, pRepr), Gia_ObjId(p, pObj)) ) +        { +            Gia_ManCorrSpecReduce_rec( pNew, p, pRepr, f ); +            iLitNew = Gia_LitNotCond( Gia_ObjCopyF(p, f, pRepr), Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) ); +            Gia_ObjSetCopyF( p, f, pObj, iLitNew ); +            return; +        } +    } +    assert( Gia_ObjIsCand(pObj) ); +    iLitNew = Gia_ManCorrSpecReal( pNew, p, pObj, f ); +    Gia_ObjSetCopyF( p, f, pObj, iLitNew ); +} + +/**Function************************************************************* + +  Synopsis    [Derives SRM for signal correspondence.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCorrSpecReduce( Gia_Man_t * p, int nFrames, int fScorr, Vec_Int_t ** pvOutputs, int fRings ) +{ +    Gia_Man_t * pNew, * pTemp; +    Gia_Obj_t * pObj, * pRepr; +    Vec_Int_t * vXorLits; +    int f, i, iPrev, iObj, iPrevNew, iObjNew; +    assert( nFrames > 0 ); +    assert( Gia_ManRegNum(p) > 0 ); +    assert( p->pReprs != NULL ); +    p->pCopies = ABC_FALLOC( int, (nFrames+fScorr)*Gia_ManObjNum(p) ); +    Gia_ManSetPhase( p ); +    pNew = Gia_ManStart( nFrames * Gia_ManObjNum(p) ); +    pNew->pName = Aig_UtilStrsav( p->pName ); +    Gia_ManHashAlloc( pNew ); +    Gia_ObjSetCopyF( p, 0, Gia_ManConst0(p), 0 ); +    Gia_ManForEachRo( p, pObj, i ) +        Gia_ObjSetCopyF( p, 0, pObj, Gia_ManAppendCi(pNew) ); +    Gia_ManForEachRo( p, pObj, i ) +        if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) ) +        { +            if ( !Gia_ObjIsFailedPair(p, Gia_ObjId(p, pRepr), Gia_ObjId(p, pObj)) ) +                Gia_ObjSetCopyF( p, 0, pObj, Gia_ObjCopyF(p, 0, pRepr) ); +        } +    for ( f = 0; f < nFrames+fScorr; f++ ) +    {  +        Gia_ObjSetCopyF( p, f, Gia_ManConst0(p), 0 ); +        Gia_ManForEachPi( p, pObj, i ) +            Gia_ObjSetCopyF( p, f, pObj, Gia_ManAppendCi(pNew) ); +    } +    *pvOutputs = Vec_IntAlloc( 1000 ); +    vXorLits = Vec_IntAlloc( 1000 ); +    if ( fRings ) +    { +        Gia_ManForEachObj1( p, pObj, i ) +        { +            if ( Gia_ObjIsConst( p, i ) ) +            { +                if ( Gia_ObjIsFailedPair(p, 0, i) ) +                    continue; +                iObjNew = Gia_ManCorrSpecReal( pNew, p, pObj, nFrames ); +                iObjNew = Gia_LitNotCond( iObjNew, Gia_ObjPhase(pObj) ); +                if ( iObjNew != 0 ) +                { +                    Vec_IntPush( *pvOutputs, 0 ); +                    Vec_IntPush( *pvOutputs, i ); +                    Vec_IntPush( vXorLits, iObjNew ); +                } +            } +            else if ( Gia_ObjIsHead( p, i ) ) +            { +                iPrev = i; +                Gia_ClassForEachObj1( p, i, iObj ) +                { +                    if ( Gia_ObjIsFailedPair(p, iPrev, iObj) ) +                    { +                        iPrev = iObj; +                        continue; +                    } +                    iPrevNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames ); +                    iObjNew  = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames ); +                    iPrevNew = Gia_LitNotCond( iPrevNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) ); +                    iObjNew  = Gia_LitNotCond( iObjNew,  Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iObj)) ); +                    if ( iPrevNew != iObjNew && iPrevNew != 0 && iObjNew != 1 ) +                    { +                        Vec_IntPush( *pvOutputs, iPrev ); +                        Vec_IntPush( *pvOutputs, iObj ); +                        Vec_IntPush( vXorLits, Gia_ManHashAnd(pNew, iPrevNew, Gia_LitNot(iObjNew)) ); +                    } +                    iPrev = iObj; +                } +                iObj = i; +                if ( Gia_ObjIsFailedPair(p, iPrev, iObj) ) +                    continue; +                iPrevNew = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iPrev), nFrames ); +                iObjNew  = Gia_ManCorrSpecReal( pNew, p, Gia_ManObj(p, iObj), nFrames ); +                iPrevNew = Gia_LitNotCond( iPrevNew, Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iPrev)) ); +                iObjNew  = Gia_LitNotCond( iObjNew,  Gia_ObjPhase(pObj) ^ Gia_ObjPhase(Gia_ManObj(p, iObj)) ); +                if ( iPrevNew != iObjNew && iPrevNew != 0 && iObjNew != 1 ) +                { +                    Vec_IntPush( *pvOutputs, iPrev ); +                    Vec_IntPush( *pvOutputs, iObj ); +                    Vec_IntPush( vXorLits, Gia_ManHashAnd(pNew, iPrevNew, Gia_LitNot(iObjNew)) ); +                } +            } +        } +    } +    else +    { +        Gia_ManForEachObj1( p, pObj, i ) +        { +            pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) ); +            if ( pRepr == NULL ) +                continue; +            if ( Gia_ObjIsFailedPair(p, Gia_ObjRepr(p, i), i) ) +                continue; +            iPrevNew = Gia_ObjIsConst(p, i)? 0 : Gia_ManCorrSpecReal( pNew, p, pRepr, nFrames ); +            iObjNew  = Gia_ManCorrSpecReal( pNew, p, pObj, nFrames ); +            iObjNew  = Gia_LitNotCond( iObjNew, Gia_ObjPhase(pRepr) ^ Gia_ObjPhase(pObj) ); +            if ( iPrevNew != iObjNew ) +            { +                Vec_IntPush( *pvOutputs, Gia_ObjId(p, pRepr) ); +                Vec_IntPush( *pvOutputs, Gia_ObjId(p, pObj) ); +                Vec_IntPush( vXorLits, Gia_ManHashXor(pNew, iPrevNew, iObjNew) ); +            } +        } +    } +    Vec_IntForEachEntry( vXorLits, iObjNew, i ) +        Gia_ManAppendCo( pNew, iObjNew ); +    Vec_IntFree( vXorLits ); +    Gia_ManHashStop( pNew ); +    ABC_FREE( p->pCopies ); +//printf( "Before sweeping = %d\n", Gia_ManAndNum(pNew) ); +    pNew = Gia_ManCleanup( pTemp = pNew ); +//printf( "After sweeping = %d\n", Gia_ManAndNum(pNew) ); +    Gia_ManStop( pTemp ); +    return pNew; +} + +/**Function************************************************************* + +  Synopsis    [Remaps simulation info from SRM to the original AIG.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Gia_ManCorrRemapSimInfo( Gia_Man_t * p, Vec_Ptr_t * vInfo ) +{ +    Gia_Obj_t * pObj, * pRepr; +    unsigned * pInfoObj, * pInfoRepr; +    int i, w, nWords; +    nWords = Vec_PtrReadWordsSimInfo( vInfo ); +    Gia_ManForEachRo( p, pObj, i ) +    { +        // skip ROs without representatives +        pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) ); +        if ( pRepr == NULL || Gia_ObjFailed(p, Gia_ObjId(p,pObj)) ) +            continue; +        pInfoObj = Vec_PtrEntry( vInfo, i ); +        for ( w = 0; w < nWords; w++ ) +            assert( pInfoObj[w] == 0 ); +        // skip ROs with constant representatives +        if ( Gia_ObjIsConst0(pRepr) ) +            continue; +        assert( Gia_ObjIsRo(p, pRepr) ); +//        printf( "%d -> %d    ", i, Gia_ObjId(p, pRepr) ); +        // transfer info from the representative +        pInfoRepr = Vec_PtrEntry( vInfo, Gia_ObjCioId(pRepr) - Gia_ManPiNum(p) ); +        for ( w = 0; w < nWords; w++ ) +            pInfoObj[w] = pInfoRepr[w]; +    } +//    printf( "\n" ); +} + +/**Function************************************************************* + +  Synopsis    [Remaps simulation info from SRM to the original AIG.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Vec_Int_t * Gia_ManCorrCreateRemapping( Gia_Man_t * p ) +{ +    Vec_Int_t * vPairs; +    Gia_Obj_t * pObj, * pRepr; +    int i; +    vPairs = Vec_IntAlloc( 100 ); +    Gia_ManForEachRo( p, pObj, i ) +    { +        // skip ROs without representatives +        pRepr = Gia_ObjReprObj( p, Gia_ObjId(p,pObj) ); +//        if ( pRepr == NULL || Gia_ObjIsConst0(pRepr) || Gia_ObjFailed(p, Gia_ObjId(p,pObj)) ) +        if ( pRepr == NULL || Gia_ObjIsConst0(pRepr) || Gia_ObjIsFailedPair(p, Gia_ObjId(p, pRepr), Gia_ObjId(p, pObj)) ) +            continue; +        assert( Gia_ObjIsRo(p, pRepr) ); +//        printf( "%d -> %d    ", Gia_ObjId(p,pObj), Gia_ObjId(p, pRepr) ); +        // remember the pair +        Vec_IntPush( vPairs, Gia_ObjCioId(pRepr) - Gia_ManPiNum(p) ); +        Vec_IntPush( vPairs, i ); +    } +    return vPairs; +} + +/**Function************************************************************* + +  Synopsis    [Remaps simulation info from SRM to the original AIG.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Gia_ManCorrPerformRemapping( Vec_Int_t * vPairs, Vec_Ptr_t * vInfo ) +{ +    unsigned * pInfoObj, * pInfoRepr; +    int w, i, iObj, iRepr, nWords; +    nWords = Vec_PtrReadWordsSimInfo( vInfo ); +    Vec_IntForEachEntry( vPairs, iRepr, i ) +    { +        iObj = Vec_IntEntry( vPairs, ++i ); +        pInfoObj = Vec_PtrEntry( vInfo, iObj ); +        pInfoRepr = Vec_PtrEntry( vInfo, iRepr ); +        for ( w = 0; w < nWords; w++ ) +        { +            assert( pInfoObj[w] == 0 ); +            pInfoObj[w] = pInfoRepr[w]; +        } +    } +} + +/**Function************************************************************* + +  Synopsis    [Updates equivalence classes by marking those that timed out.] + +  Description [Returns 1 if all ndoes are proved.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Gia_ManCheckRefinements( Gia_Man_t * p, Vec_Str_t * vStatus, Vec_Int_t * vOutputs, Cec_ManSim_t * pSim, int fRings ) +{ +    int i, status, iRepr, iObj; +    assert( 2 * Vec_StrSize(vStatus) == Vec_IntSize(vOutputs) ); +    Vec_StrForEachEntry( vStatus, status, i ) +    { +        iRepr = Vec_IntEntry( vOutputs, 2*i ); +        iObj  = Vec_IntEntry( vOutputs, 2*i+1 ); +        if ( status == 1 ) +            continue; +        if ( status == 0 ) +        { +//            if ( Gia_ObjHasSameRepr(p, iRepr, iObj) ) +//                printf( "Gia_ManCheckRefinements(): Disproved equivalence (%d,%d) is not refined!\n", iRepr, iObj ); +            if ( Gia_ObjHasSameRepr(p, iRepr, iObj) ) +                Cec_ManSimClassRemoveOne( pSim, iObj ); +            continue; +        } +        if ( status == -1 ) +        { +//            if ( !Gia_ObjFailed( p, iObj ) ) +//                printf( "Gia_ManCheckRefinements(): Failed equivalence is not marked as failed!\n" ); +//            Gia_ObjSetFailed( p, iRepr ); +//            Gia_ObjSetFailed( p, iObj );         +            if ( fRings ) +            Cec_ManSimClassRemoveOne( pSim, iRepr ); +            Cec_ManSimClassRemoveOne( pSim, iObj ); +            continue; +        } +    } +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Marks all the nodes as proved.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Gia_ManSetProvedNodes( Gia_Man_t * p ) +{ +    Gia_Obj_t * pObj; +    int i, nLits = 0; +    Gia_ManForEachObj1( p, pObj, i ) +    { +        if ( Gia_ObjRepr(p, i) == GIA_VOID ) +            continue; +        if ( Gia_ObjIsFailedPair( p, Gia_ObjRepr(p, i), i ) ) +            continue; +        Gia_ObjSetProved( p, i ); +        nLits++; +    } +//    printf( "Identified %d proved literals.\n", nLits ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Cec_ManLCorrPrintStats( Gia_Man_t * p, Vec_Str_t * vStatus, int iIter, int Time ) +{  +    int nLits, CounterX = 0, Counter0 = 0, Counter = 0; +    int i, Entry, nProve = 0, nDispr = 0, nFail = 0; +    for ( i = 1; i < Gia_ManObjNum(p); i++ ) +    { +        if ( Gia_ObjIsNone(p, i) ) +            CounterX++; +        else if ( Gia_ObjIsConst(p, i) ) +            Counter0++; +        else if ( Gia_ObjIsHead(p, i) ) +            Counter++; +    } +    CounterX -= Gia_ManCoNum(p); +    nLits = Gia_ManCiNum(p) + Gia_ManAndNum(p) - Counter - CounterX; +    printf( "%3d : c =%8d  cl =%7d  lit =%8d  ", iIter, Counter0, Counter, nLits ); +    if ( vStatus ) +    Vec_StrForEachEntry( vStatus, Entry, i ) +    { +        if ( Entry == 1 ) +            nProve++; +        else if ( Entry == 0 ) +            nDispr++; +        else if ( Entry == -1 ) +            nFail++; +    } +    printf( "p =%6d  d =%6d  f =%6d  ", nProve, nDispr, nFail ); +    ABC_PRT( "T", Time ); +} + +/**Function************************************************************* + +  Synopsis    [Sets register values from the counter-example.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Cec_ManStartSimInfo( Vec_Ptr_t * vInfo, int nFlops ) +{ +    unsigned * pInfo; +    int k, w, nWords; +    nWords = Vec_PtrReadWordsSimInfo( vInfo ); +    assert( nFlops <= Vec_PtrSize(vInfo) ); +    for ( k = 0; k < nFlops; k++ ) +    { +        pInfo = Vec_PtrEntry( vInfo, k ); +        for ( w = 0; w < nWords; w++ ) +            pInfo[w] = 0; +    } +    for ( k = nFlops; k < Vec_PtrSize(vInfo); k++ ) +    { +        pInfo = Vec_PtrEntry( vInfo, k ); +        for ( w = 0; w < nWords; w++ ) +            pInfo[w] = Aig_ManRandom( 0 ); +    } +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Cec_ManLoadCounterExamples2( Vec_Ptr_t * vInfo, Vec_Int_t * vCexStore, int iStart ) +{  +    unsigned * pInfo; +    int nBits = 32 * Vec_PtrReadWordsSimInfo(vInfo);  +    int k, iLit, nLits, Out, iBit = 1; +    while ( iStart < Vec_IntSize(vCexStore) ) +    { +        // skip the output number +//        iStart++; +        Out = Vec_IntEntry( vCexStore, iStart++ ); +//        printf( "iBit = %d. Out = %d.\n", iBit, Out ); +        // get the number of items +        nLits = Vec_IntEntry( vCexStore, iStart++ ); +        if ( nLits <= 0 ) +            continue; +        // add pattern to storage +        for ( k = 0; k < nLits; k++ ) +        { +            iLit = Vec_IntEntry( vCexStore, iStart++ ); +            pInfo = Vec_PtrEntry( vInfo, Gia_Lit2Var(iLit) ); +            if ( Aig_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(iLit) ) +                Aig_InfoXorBit( pInfo, iBit ); +        } +        if ( ++iBit == nBits ) +            break; +    } +//    printf( "added %d bits\n", iBit-1 ); +    return iStart; +} + +/**Function************************************************************* + +  Synopsis    [Packs patterns into array of simulation info.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +*************************************`**********************************/ +int Cec_ManLoadCounterExamplesTry( Vec_Ptr_t * vInfo, Vec_Ptr_t * vPres, int iBit, int * pLits, int nLits ) +{ +    unsigned * pInfo, * pPres; +    int i; +    for ( i = 0; i < nLits; i++ ) +    { +        pInfo = Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); +        pPres = Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); +        if ( Aig_InfoHasBit( pPres, iBit ) &&  +             Aig_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) +             return 0; +    } +    for ( i = 0; i < nLits; i++ ) +    { +        pInfo = Vec_PtrEntry(vInfo, Gia_Lit2Var(pLits[i])); +        pPres = Vec_PtrEntry(vPres, Gia_Lit2Var(pLits[i])); +        Aig_InfoSetBit( pPres, iBit ); +        if ( Aig_InfoHasBit( pInfo, iBit ) == Gia_LitIsCompl(pLits[i]) ) +            Aig_InfoXorBit( pInfo, iBit ); +    } +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Cec_ManLoadCounterExamples( Vec_Ptr_t * vInfo, Vec_Int_t * vCexStore, int iStart ) +{  +    Vec_Int_t * vPat; +    Vec_Ptr_t * vPres; +    int nWords = Vec_PtrReadWordsSimInfo(vInfo); +    int nBits = 32 * nWords;  +    int k, nSize, iBit = 1, kMax = 0; +    vPat  = Vec_IntAlloc( 100 ); +    vPres = Vec_PtrAllocSimInfo( Vec_PtrSize(vInfo), nWords ); +    Vec_PtrCleanSimInfo( vPres, 0, nWords ); +    while ( iStart < Vec_IntSize(vCexStore) ) +    { +        // skip the output number +        iStart++; +        // get the number of items +        nSize = Vec_IntEntry( vCexStore, iStart++ ); +        if ( nSize <= 0 ) +            continue; +        // extract pattern +        Vec_IntClear( vPat ); +        for ( k = 0; k < nSize; k++ ) +        { +            Vec_IntPush( vPat, Vec_IntEntry( vCexStore, iStart++ ) ); +//            printf( "%d(%d) ", Vec_IntEntryLast(vPat)/2, (Vec_IntEntryLast(vPat)&1)==0 ); +        } +//        printf( "\n" ); +        // add pattern to storage +        for ( k = 1; k < nBits; k++ ) +            if ( Cec_ManLoadCounterExamplesTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ) ) +                break; +//        for ( i = 0; i < 27; i++ ) +//            printf( "%d(%d) ", i, Aig_InfoHasBit(Vec_PtrEntry(vInfo,i), k) ); +//        printf( "\n" ); + +        kMax = AIG_MAX( kMax, k ); +        if ( k == nBits-1 ) +            break; +    } +//        printf( "\n" ); +//    printf( "kMax = %d.\n", kMax ); +    Vec_PtrFree( vPres ); +    Vec_IntFree( vPat ); +    return iStart; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Cec_ManResimulateCounterExamples( Cec_ManSim_t * pSim, Vec_Int_t * vCexStore, int nFrames ) +{  +    Vec_Int_t * vPairs; +    Vec_Ptr_t * vSimInfo;  +    int RetValue = 0, iStart = 0; +    vPairs = Gia_ManCorrCreateRemapping( pSim->pAig ); +    Gia_ManSetRefs( pSim->pAig ); +//    pSim->pPars->nWords  = 63; +    pSim->pPars->nRounds = nFrames; +    vSimInfo = Vec_PtrAllocSimInfo( Gia_ManRegNum(pSim->pAig) + Gia_ManPiNum(pSim->pAig) * nFrames, pSim->pPars->nWords ); +    while ( iStart < Vec_IntSize(vCexStore) ) +    { +//Gia_ManEquivPrintOne( pSim->pAig, 85, 0 ); +        Cec_ManStartSimInfo( vSimInfo, Gia_ManRegNum(pSim->pAig) ); +        iStart = Cec_ManLoadCounterExamples( vSimInfo, vCexStore, iStart ); +//        iStart = Cec_ManLoadCounterExamples2( vSimInfo, vCexStore, iStart ); +//        Gia_ManCorrRemapSimInfo( pSim->pAig, vSimInfo ); +        Gia_ManCorrPerformRemapping( vPairs, vSimInfo ); +        RetValue |= Cec_ManSeqResimulate( pSim, vSimInfo ); +//        Cec_ManSeqResimulateInfo( pSim->pAig, vSimInfo, NULL ); +    } +//Gia_ManEquivPrintOne( pSim->pAig, 85, 0 ); +    assert( iStart == Vec_IntSize(vCexStore) ); +    Vec_PtrFree( vSimInfo ); +    Vec_IntFree( vPairs ); +    return RetValue; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Gia_Man_t * Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) +{   +    int nAddFrames = 2; // additional timeframes to simulate +    Vec_Str_t * vStatus; +    Vec_Int_t * vOutputs; +    Vec_Int_t * vCexStore; +    Gia_Man_t * pNew, * pTemp; +    Cec_ParSim_t ParsSim, * pParsSim = &ParsSim; +    Cec_ParSat_t ParsSat, * pParsSat = &ParsSat; +    Cec_ManSim_t * pSim; +    Gia_Man_t * pSrm; +    int r, RetValue; +    int clkSat = 0, clkSim = 0, clkSrm = 0, clkTotal = clock(); +    int clk2, clk = clock(); +    ABC_FREE( pAig->pReprs ); +    ABC_FREE( pAig->pNexts ); +    if ( Gia_ManRegNum(pAig) == 0 ) +    { +        printf( "Cec_ManLatchCorrespondence(): Not a sequential AIG.\n" ); +        return NULL; +    } +    Aig_ManRandom( 1 ); +    // prepare simulation manager +    Cec_ManSimSetDefaultParams( pParsSim ); +    pParsSim->nWords     = pPars->nWords; +    pParsSim->nRounds    = pPars->nRounds; +    pParsSim->fVerbose   = pPars->fVerbose; +    pParsSim->fLatchCorr = pPars->fLatchCorr; +    pParsSim->fSeqSimulate = 1; +    // create equivalence classes of registers +    pSim = Cec_ManSimStart( pAig, pParsSim ); +    Cec_ManSimClassesPrepare( pSim ); +    Cec_ManSimClassesRefine( pSim ); +    // prepare SAT solving +    Cec_ManSatSetDefaultParams( pParsSat ); +    pParsSat->nBTLimit = pPars->nBTLimit; +    pParsSat->fVerbose = pPars->fVerbose; +    if ( pPars->fVerbose ) +    { +        printf( "Obj = %7d. And = %7d. Conf = %5d. Fr = %d. Lcorr = %d. Ring = %d. CSat = %d.\n", +            Gia_ManObjNum(pAig), Gia_ManAndNum(pAig),  +            pPars->nBTLimit, pPars->nFrames, pPars->fLatchCorr, pPars->fUseRings, pPars->fUseCSat ); +        Cec_ManLCorrPrintStats( pAig, NULL, 0, clock() - clk ); +    } +    // perform refinement of equivalence classes +    for ( r = 0; r < 100000; r++ ) +    {  +        clk = clock(); +        // perform speculative reduction +        clk2 = clock(); +        pSrm = Gia_ManCorrSpecReduce( pAig, pPars->nFrames, !pPars->fLatchCorr, &vOutputs, pPars->fUseRings ); +        assert( Gia_ManRegNum(pSrm) == 0 && Gia_ManPiNum(pSrm) == Gia_ManRegNum(pAig)+(pPars->nFrames+!pPars->fLatchCorr)*Gia_ManPiNum(pAig) ); +        clkSrm += clock() - clk2; +        if ( Gia_ManCoNum(pSrm) == 0 ) +        { +            Vec_IntFree( vOutputs ); +            Gia_ManStop( pSrm );             +            break; +        } +//Gia_DumpAiger( pSrm, "corrsrm", r, 2 ); + +        // found counter-examples to speculation +        clk2 = clock(); +        if ( pPars->fUseCSat ) +            vCexStore = Cbs_ManSolveMiter( pSrm, pPars->nBTLimit, &vStatus ); +        else +            vCexStore = Cec_ManSatSolveMiter( pSrm, pParsSat, &vStatus ); +        Gia_ManStop( pSrm ); +        clkSat += clock() - clk2; +        if ( Vec_IntSize(vCexStore) == 0 ) +        { +            Vec_IntFree( vCexStore ); +            Vec_StrFree( vStatus ); +            Vec_IntFree( vOutputs ); +            break; +        } +        // refine classes with these counter-examples +        clk2 = clock(); +        RetValue = Cec_ManResimulateCounterExamples( pSim, vCexStore, pPars->nFrames + 1 + nAddFrames ); +        Vec_IntFree( vCexStore ); +        clkSim += clock() - clk2; +        Gia_ManCheckRefinements( pAig, vStatus, vOutputs, pSim, pPars->fUseRings ); +        if ( pPars->fVerbose ) +            Cec_ManLCorrPrintStats( pAig, vStatus, r+1, clock() - clk ); +//Gia_ManEquivPrintClasses( pAig, 1, 0 ); +        Vec_StrFree( vStatus ); +        Vec_IntFree( vOutputs ); +    } +    Cec_ManSimStop( pSim ); +    clkTotal = clock() - clkTotal; +    if ( pPars->fVerbose ) +        Cec_ManLCorrPrintStats( pAig, NULL, r+1, clock() - clk ); +    if ( pPars->fVerbose ) +    { +        ABC_PRTP( "Srm  ", clkSrm,                        clkTotal ); +        ABC_PRTP( "Sat  ", clkSat,                        clkTotal ); +        ABC_PRTP( "Sim  ", clkSim,                        clkTotal ); +        ABC_PRTP( "Other", clkTotal-clkSat-clkSrm-clkSim, clkTotal ); +        ABC_PRT( "TOTAL",  clkTotal ); +    } +    // derive reduced AIG +    Gia_ManSetProvedNodes( pAig ); +    pNew = Gia_ManEquivReduce( pAig, 0, 0, 0 ); +//Gia_WriteAiger( pNew, "reduced.aig", 0, 0 ); +    pNew = Gia_ManSeqCleanup( pTemp = pNew ); +    Gia_ManStop( pTemp ); +    return pNew; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/cec/cecInt.h b/src/aig/cec/cecInt.h index ae4c6ff4..86af2614 100644 --- a/src/aig/cec/cecInt.h +++ b/src/aig/cec/cecInt.h @@ -85,15 +85,19 @@ struct Cec_ManSat_t_      int              nRecycles;      // the number of times SAT solver was recycled      int              nCallsSince;    // the number of calls since the last recycle      Vec_Ptr_t *      vFanins;        // fanins of the CNF node +    // counter-examples +    Vec_Int_t *      vCex;           // the latest counter-example +    Vec_Int_t *      vVisits;        // temporary array for visited nodes        // SAT calls statistics      int              nSatUnsat;      // the number of proofs      int              nSatSat;        // the number of failure      int              nSatUndec;      // the number of timeouts      int              nSatTotal;      // the number of calls +    int              nCexLits;      // conflicts -    int              nConfUnsat; -    int              nConfSat; -    int              nConfUndec; +    int              nConfUnsat;     // conflicts in unsat problems +    int              nConfSat;       // conflicts in sat problems +    int              nConfUndec;     // conflicts in undec problems      // runtime stats      int              timeSatUnsat;   // unsat      int              timeSatSat;     // sat @@ -164,6 +168,7 @@ struct Cec_ManFra_t_  /*=== cecCore.c ============================================================*/  /*=== cecClass.c ============================================================*/ +extern int                  Cec_ManSimClassRemoveOne( Cec_ManSim_t * p, int i );  extern int                  Cec_ManSimClassesPrepare( Cec_ManSim_t * p );  extern int                  Cec_ManSimClassesRefine( Cec_ManSim_t * p );  extern int                  Cec_ManSimSimulateRound( Cec_ManSim_t * p, Vec_Ptr_t * vInfoCis, Vec_Ptr_t * vInfoCos ); @@ -183,10 +188,16 @@ extern void                 Cec_ManFraStop( Cec_ManFra_t * p );  /*=== cecPat.c ============================================================*/  extern void                 Cec_ManPatSavePattern( Cec_ManPat_t *  pPat, Cec_ManSat_t *  p, Gia_Obj_t * pObj );  extern Vec_Ptr_t *          Cec_ManPatCollectPatterns( Cec_ManPat_t *  pMan, int nInputs, int nWords ); +extern Vec_Ptr_t *          Cec_ManPatPackPatterns( Vec_Int_t * vCexStore, int nInputs, int nRegs, int nWordsInit ); +/*=== cecSeq.c ============================================================*/ +extern int                  Cec_ManSeqResimulate( Cec_ManSim_t * p, Vec_Ptr_t * vInfo ); +extern int                  Cec_ManSeqResimulateInfo( Gia_Man_t * pAig, Vec_Ptr_t * vSimInfo, Gia_Cex_t * pBestState ); +extern void                 Cec_ManSeqDeriveInfoInitRandom( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Gia_Cex_t * pCex );  /*=== cecSolve.c ============================================================*/  extern int                  Cec_ObjSatVarValue( Cec_ManSat_t * p, Gia_Obj_t * pObj );  extern void                 Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars ); -extern void                 Cec_ManSatSolveSeq( Vec_Ptr_t * vPatts, Gia_Man_t * pAig, Cec_ParSat_t * pPars, int nRegs, int * pnPats ); +extern Vec_Str_t *          Cec_ManSatSolveSeq( Vec_Ptr_t * vPatts, Gia_Man_t * pAig, Cec_ParSat_t * pPars, int nRegs, int * pnPats ); +extern Vec_Int_t *          Cec_ManSatSolveMiter( Gia_Man_t * pAig, Cec_ParSat_t * pPars, Vec_Str_t ** pvStatus );  /*=== ceFraeep.c ============================================================*/  extern Gia_Man_t *          Cec_ManFraSpecReduction( Cec_ManFra_t * p );  extern int                  Cec_ManFraClassesUpdate( Cec_ManFra_t * p, Cec_ManSim_t * pSim, Cec_ManPat_t * pPat, Gia_Man_t * pNew ); diff --git a/src/aig/cec/cecMan.c b/src/aig/cec/cecMan.c index 14f2493e..430d961e 100644 --- a/src/aig/cec/cecMan.c +++ b/src/aig/cec/cecMan.c @@ -52,6 +52,8 @@ Cec_ManSat_t * Cec_ManSatCreate( Gia_Man_t * pAig, Cec_ParSat_t * pPars )      p->pSatVars     = ABC_CALLOC( int, Gia_ManObjNum(pAig) );      p->vUsedNodes   = Vec_PtrAlloc( 1000 );      p->vFanins      = Vec_PtrAlloc( 100 ); +    p->vCex         = Vec_IntAlloc( 100 ); +    p->vVisits      = Vec_IntAlloc( 100 );      return p;  } @@ -81,6 +83,7 @@ void Cec_ManSatPrintStats( Cec_ManSat_t * p )      printf( "Undef calls %6d  (%6.2f %%)   Ave conf = %8.1f   ",           p->nSatUndec, 100.0*p->nSatUndec/p->nSatTotal, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 );      ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal ); +    ABC_PRT( "Total time", p->timeTotal );  }  /**Function************************************************************* @@ -98,6 +101,8 @@ void Cec_ManSatStop( Cec_ManSat_t * p )  {      if ( p->pSat )          sat_solver_delete( p->pSat ); +    Vec_IntFree( p->vCex ); +    Vec_IntFree( p->vVisits );      Vec_PtrFree( p->vUsedNodes );      Vec_PtrFree( p->vFanins );      ABC_FREE( p->pSatVars ); diff --git a/src/aig/cec/cecPat.c b/src/aig/cec/cecPat.c index b80f1e44..dacc5daf 100644 --- a/src/aig/cec/cecPat.c +++ b/src/aig/cec/cecPat.c @@ -450,7 +450,7 @@ Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t *  pMan, int nInputs, int nW      int nBits = 32 * nWords;      int clk = clock();      vInfo = Vec_PtrAllocSimInfo( nInputs, nWords ); -    Aig_ManRandomInfo( vInfo, 0, nWords ); +    Aig_ManRandomInfo( vInfo, 0, 0, nWords );      vPres = Vec_PtrAllocSimInfo( nInputs, nWords );      Vec_PtrCleanSimInfo( vPres, 0, nWords );      while ( pMan->iStart < Vec_StrSize(pMan->vStorage) ) @@ -464,7 +464,7 @@ Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t *  pMan, int nInputs, int nW          if ( k == nBits-1 )          {              Vec_PtrReallocSimInfo( vInfo ); -            Aig_ManRandomInfo( vInfo, nWords, 2*nWords ); +            Aig_ManRandomInfo( vInfo, 0, nWords, 2*nWords );              Vec_PtrReallocSimInfo( vPres );              Vec_PtrCleanSimInfo( vPres, nWords, 2*nWords );              nWords *= 2; @@ -486,6 +486,77 @@ Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t *  pMan, int nInputs, int nW      return vInfo;  } + +/**Function************************************************************* + +  Synopsis    [Packs patterns into array of simulation info.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Vec_Ptr_t * Cec_ManPatPackPatterns( Vec_Int_t * vCexStore, int nInputs, int nRegs, int nWordsInit ) +{ +    Vec_Int_t * vPat; +    Vec_Ptr_t * vInfo, * vPres; +    int k, nSize, iStart, kMax = 0, nPatterns = 0; +    int nWords = nWordsInit; +    int nBits = 32 * nWords; +//    int RetValue; +    assert( nRegs <= nInputs ); +    vPat  = Vec_IntAlloc( 100 ); + +    vInfo = Vec_PtrAllocSimInfo( nInputs, nWords ); +    Vec_PtrCleanSimInfo( vInfo, 0, nWords ); +    Aig_ManRandomInfo( vInfo, nRegs, 0, nWords ); + +    vPres = Vec_PtrAllocSimInfo( nInputs, nWords ); +    Vec_PtrCleanSimInfo( vPres, 0, nWords ); +    iStart = 0; +    while ( iStart < Vec_IntSize(vCexStore) ) +    { +        nPatterns++; +        // skip the output number +        iStart++; +        // get the number of items +        nSize = Vec_IntEntry( vCexStore, iStart++ ); +        if ( nSize <= 0 ) +            continue; +        // extract pattern +        Vec_IntClear( vPat ); +        for ( k = 0; k < nSize; k++ ) +            Vec_IntPush( vPat, Vec_IntEntry( vCexStore, iStart++ ) ); +        // add pattern to storage +        for ( k = 1; k < nBits; k++, k += ((k % (32 * nWordsInit)) == 0) ) +            if ( Cec_ManPatCollectTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ) ) +                break; + +//        k = kMax + 1; +//        RetValue = Cec_ManPatCollectTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ); +//        assert( RetValue == 1 ); + +        kMax = AIG_MAX( kMax, k ); +        if ( k == nBits-1 ) +        { +            Vec_PtrReallocSimInfo( vInfo ); +            Vec_PtrCleanSimInfo( vInfo, nWords, 2*nWords ); +            Aig_ManRandomInfo( vInfo, nRegs, nWords, 2*nWords ); + +            Vec_PtrReallocSimInfo( vPres ); +            Vec_PtrCleanSimInfo( vPres, nWords, 2*nWords ); +            nWords *= 2; +            nBits *= 2; +        } +    } +//    printf( "packed %d patterns into %d vectors (out of %d)\n", nPatterns, kMax, nBits ); +    Vec_PtrFree( vPres ); +    Vec_IntFree( vPat ); +    return vInfo; +} +  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                ///  //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/cec/cecSeq.c b/src/aig/cec/cecSeq.c index 1a398e2e..e69b526e 100644 --- a/src/aig/cec/cecSeq.c +++ b/src/aig/cec/cecSeq.c @@ -42,23 +42,32 @@  void Cec_ManSeqDeriveInfoFromCex( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Gia_Cex_t * pCex )  {      unsigned * pInfo; -    int k, w, nWords; +    int k, i, w, nWords;      assert( pCex->nBits == pCex->nRegs + pCex->nPis * (pCex->iFrame + 1) ); -    assert( pCex->nBits <= Vec_PtrSize(vInfo) ); +    assert( pCex->nBits - pCex->nRegs + Gia_ManRegNum(pAig) <= Vec_PtrSize(vInfo) );      nWords = Vec_PtrReadWordsSimInfo( vInfo ); +/*      for ( k = 0; k < pCex->nRegs; k++ )      {          pInfo = Vec_PtrEntry( vInfo, k );          for ( w = 0; w < nWords; w++ )              pInfo[w] = Aig_InfoHasBit( pCex->pData, k )? ~0 : 0;      } -    for ( ; k < pCex->nBits; k++ ) +*/ +    for ( k = 0; k < Gia_ManRegNum(pAig); k++ )      {          pInfo = Vec_PtrEntry( vInfo, k );          for ( w = 0; w < nWords; w++ ) +            pInfo[w] = 0; +    } + +    for ( i = pCex->nRegs; i < pCex->nBits; i++ ) +    { +        pInfo = Vec_PtrEntry( vInfo, k++ ); +        for ( w = 0; w < nWords; w++ )              pInfo[w] = Aig_ManRandom(0);          // set simulation pattern and make sure it is second (first will be erased during simulation) -        pInfo[0] = (pInfo[0] << 1) | Aig_InfoHasBit( pCex->pData, k );  +        pInfo[0] = (pInfo[0] << 1) | Aig_InfoHasBit( pCex->pData, i );           pInfo[0] <<= 1;      }      for ( ; k < Vec_PtrSize(vInfo); k++ ) @@ -85,13 +94,13 @@ void Cec_ManSeqDeriveInfoInitRandom( Vec_Ptr_t * vInfo, Gia_Man_t * pAig, Gia_Ce      unsigned * pInfo;      int k, w, nWords;      nWords = Vec_PtrReadWordsSimInfo( vInfo ); -    assert( Gia_ManRegNum(pAig) == pCex->nRegs ); +    assert( pCex == NULL || Gia_ManRegNum(pAig) == pCex->nRegs );      assert( Gia_ManRegNum(pAig) <= Vec_PtrSize(vInfo) );      for ( k = 0; k < Gia_ManRegNum(pAig); k++ )      {          pInfo = Vec_PtrEntry( vInfo, k );          for ( w = 0; w < nWords; w++ ) -            pInfo[w] = Aig_InfoHasBit( pCex->pData, k )? ~0 : 0; +            pInfo[w] = (pCex && Aig_InfoHasBit(pCex->pData, k))? ~0 : 0;      }      for ( ; k < Vec_PtrSize(vInfo); k++ ) @@ -212,9 +221,10 @@ int Cec_ManSeqResimulateCounter( Gia_Man_t * pAig, Cec_ParSim_t * pPars, Gia_Cex          printf( "Cec_ManSeqResimulateCounter(): Not a sequential AIG.\n" );          return -1;      } -    if ( Gia_ManRegNum(pAig) != pCex->nRegs || Gia_ManPiNum(pAig) != pCex->nPis ) +//    if ( Gia_ManRegNum(pAig) != pCex->nRegs || Gia_ManPiNum(pAig) != pCex->nPis ) +    if ( Gia_ManPiNum(pAig) != pCex->nPis )      { -        printf( "Cec_ManSeqResimulateCounter(): Parameters of the ccounter-example differ.\n" ); +        printf( "Cec_ManSeqResimulateCounter(): The number of PIs in the AIG and the counter-example differ.\n" );          return -1;      }      if ( pPars->fVerbose ) @@ -251,6 +261,7 @@ int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars )      int nAddFrames = 10; // additional timeframes to simulate      Cec_ParSat_t ParsSat, * pParsSat = &ParsSat;      Vec_Ptr_t * vSimInfo;  +    Vec_Str_t * vStatus;      Gia_Cex_t * pState;      Gia_Man_t * pSrm;      int r, nPats, RetValue = -1; @@ -284,13 +295,14 @@ int Cec_ManSeqSemiformal( Gia_Man_t * pAig, Cec_ParSmf_t * pPars )  //        Gia_ManPrintCounterExample( pState );          // derive speculatively reduced model          pSrm = Gia_ManSpecReduceInit( pAig, pState, pPars->nFrames, pPars->fDualOut ); -        assert( Gia_ManRegNum(pSrm) == 0 && Gia_ManPiNum(pSrm) == Gia_ManPiNum(pAig) * pPars->nFrames ); +        assert( Gia_ManRegNum(pSrm) == 0 && Gia_ManPiNum(pSrm) == (Gia_ManPiNum(pAig) * pPars->nFrames) );          // allocate room for simulation info          vSimInfo = Vec_PtrAllocSimInfo( Gia_ManRegNum(pAig) +               Gia_ManPiNum(pAig) * (pPars->nFrames + nAddFrames), pPars->nWords );          Cec_ManSeqDeriveInfoInitRandom( vSimInfo, pAig, pState );          // fill in simulation info with counter-examples -        Cec_ManSatSolveSeq( vSimInfo, pSrm, pParsSat, Gia_ManRegNum(pAig), &nPats ); +        vStatus = Cec_ManSatSolveSeq( vSimInfo, pSrm, pParsSat, Gia_ManRegNum(pAig), &nPats ); +        Vec_StrFree( vStatus );          Gia_ManStop( pSrm );          // resimulate and refine the classes          RetValue = Cec_ManSeqResimulateInfo( pAig, vSimInfo, pState ); diff --git a/src/aig/cec/cecSolve.c b/src/aig/cec/cecSolve.c index 24d5c3ed..a69d1d2a 100644 --- a/src/aig/cec/cecSolve.c +++ b/src/aig/cec/cecSolve.c @@ -556,18 +556,10 @@ p->timeSatUndec += clock() - clk;  ***********************************************************************/  void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPars )  { -    static int Counter; -//    char Buffer[1000]; -      Bar_Progress_t * pProgress = NULL;      Cec_ManSat_t * p;      Gia_Obj_t * pObj;      int i, status, clk = clock(), clk2; - -//    sprintf( Buffer, "gia%03d.aig", Counter++ ); -//Gia_WriteAiger( pAig, Buffer, 0, 0 ); -//printf( "Dumpted slice into file \"%s\".\n", Buffer ); -      // reset the manager      if ( pPat )      { @@ -595,13 +587,6 @@ clk2 = clock();          pObj->fMark0 = (status == 0);          pObj->fMark1 = (status == 1);  /* -printf( "Output %6d : ", i ); -printf( "conf = %6d ", p->pSat->stats.conflicts ); -printf( "prop = %6d ", p->pSat->stats.propagations ); -ABC_PRT( "time", clock() - clk2 ); -*/ - -/*          if ( status == -1 )          {              Gia_Man_t * pTemp = Gia_ManDupDfsCone( pAig, pObj ); @@ -653,6 +638,8 @@ void Cec_ManSatSolveSeq_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * pOb          unsigned * pInfo = Vec_PtrEntry( vInfo, nRegs + Gia_ObjCioId(pObj) );          if ( Cec_ObjSatVarValue( pSat, pObj ) != Aig_InfoHasBit( pInfo, iPat ) )              Aig_InfoXorBit( pInfo, iPat ); +        pSat->nCexLits++; +//        Vec_IntPush( pSat->vCex, Gia_Var2Lit( Gia_ObjCioId(pObj), !Cec_ObjSatVarValue(pSat, pObj) ) );          return;      }      assert( Gia_ObjIsAnd(pObj) ); @@ -672,44 +659,207 @@ void Cec_ManSatSolveSeq_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * pOb    SeeAlso     []  ***********************************************************************/ -void Cec_ManSatSolveSeq( Vec_Ptr_t * vPatts, Gia_Man_t * pAig, Cec_ParSat_t * pPars, int nRegs, int * pnPats ) +Vec_Str_t * Cec_ManSatSolveSeq( Vec_Ptr_t * vPatts, Gia_Man_t * pAig, Cec_ParSat_t * pPars, int nRegs, int * pnPats )  {      Bar_Progress_t * pProgress = NULL; +    Vec_Str_t * vStatus;      Cec_ManSat_t * p;      Gia_Obj_t * pObj; -    int iPat = 1, nPats = 32 * Vec_PtrReadWordsSimInfo(vPatts); +    int iPat = 0, nPatsInit, nPats;      int i, status, clk = clock(); +    nPatsInit = nPats = 32 * Vec_PtrReadWordsSimInfo(vPatts);      Gia_ManSetPhase( pAig );      Gia_ManLevelNum( pAig );      Gia_ManResetTravId( pAig );      p = Cec_ManSatCreate( pAig, pPars ); +    vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) );      pProgress = Bar_ProgressStart( stdout, Gia_ManPoNum(pAig) );      Gia_ManForEachCo( pAig, pObj, i )      { +        Bar_ProgressUpdate( pProgress, i, "SAT..." );          if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) ) +        { +            if ( Gia_ObjFaninC0(pObj) ) +            { +                printf( "Constant 1 output of SRM!!!\n" ); +                Vec_StrPush( vStatus, 0 ); +            } +            else +            { +                printf( "Constant 0 output of SRM!!!\n" ); +                Vec_StrPush( vStatus, 1 ); +            }              continue; -        Bar_ProgressUpdate( pProgress, i, "BMC..." ); +        }          status = Cec_ManSatCheckNode( p, pObj ); +//printf( "output %d   status = %d\n", i, status ); +        Vec_StrPush( vStatus, (char)status );          if ( status != 0 )              continue; +        // resize storage +        if ( iPat == nPats ) +        { +            int nWords = Vec_PtrReadWordsSimInfo(vPatts); +            Vec_PtrReallocSimInfo( vPatts ); +            Vec_PtrCleanSimInfo( vPatts, nWords, 2*nWords ); +            nPats = 32 * Vec_PtrReadWordsSimInfo(vPatts); +        } +        if ( iPat % nPatsInit == 0 ) +            iPat++;          // save the pattern          Gia_ManIncrementTravId( pAig ); +//        Vec_IntClear( p->vCex );          Cec_ManSatSolveSeq_rec( p, pAig, Gia_ObjFanin0(pObj), vPatts, iPat++, nRegs ); -        if ( iPat == nPats ) -            break; +//        Gia_SatVerifyPattern( pAig, pObj, p->vCex, p->vVisits ); +//        Cec_ManSatAddToStore( p->vCexStore, p->vCex ); +//        if ( iPat == nPats ) +//            break;          // quit if one of them is solved -        if ( pPars->fFirstStop ) -            break; +//        if ( pPars->fFirstStop ) +//            break; +//        if ( iPat == 32 * 15 * 16 - 1 ) +//            break;      }      p->timeTotal = clock() - clk;      Bar_ProgressStop( pProgress );      if ( pPars->fVerbose )          Cec_ManSatPrintStats( p ); +//    printf( "Total number of cex literals = %d. (Ave = %d)\n", p->nCexLits, p->nCexLits/p->nSatSat );      Cec_ManSatStop( p );      if ( pnPats )          *pnPats = iPat-1; +    return vStatus; +} + + +/**Function************************************************************* + +  Synopsis    [Save values in the cone of influence.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out ) +{ +    int i, Entry; +    Vec_IntPush( vCexStore, Out ); +    if ( vCex == NULL ) // timeout +    { +        Vec_IntPush( vCexStore, -1 ); +        return; +    } +    // write the counter-example +    Vec_IntPush( vCexStore, Vec_IntSize(vCex) ); +    Vec_IntForEachEntry( vCex, Entry, i ) +        Vec_IntPush( vCexStore, Entry ); +} + +/**Function************************************************************* + +  Synopsis    [Save values in the cone of influence.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Cec_ManSatSolveMiter_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ +    if ( Gia_ObjIsTravIdCurrent(p, pObj) ) +        return; +    Gia_ObjSetTravIdCurrent(p, pObj); +    if ( Gia_ObjIsCi(pObj) ) +    { +        pSat->nCexLits++; +        Vec_IntPush( pSat->vCex, Gia_Var2Lit( Gia_ObjCioId(pObj), !Cec_ObjSatVarValue(pSat, pObj) ) ); +        return; +    } +    assert( Gia_ObjIsAnd(pObj) ); +    Cec_ManSatSolveMiter_rec( pSat, p, Gia_ObjFanin0(pObj) ); +    Cec_ManSatSolveMiter_rec( pSat, p, Gia_ObjFanin1(pObj) ); +} + +/**Function************************************************************* + +  Synopsis    [Performs one round of solving for the POs of the AIG.] + +  Description [Labels the nodes that have been proved (pObj->fMark1)  +  and returns the set of satisfying assignments.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Vec_Int_t * Cec_ManSatSolveMiter( Gia_Man_t * pAig, Cec_ParSat_t * pPars, Vec_Str_t ** pvStatus ) +{ +    Bar_Progress_t * pProgress = NULL; +    Vec_Int_t * vCexStore; +    Vec_Str_t * vStatus; +    Cec_ManSat_t * p; +    Gia_Obj_t * pObj; +    int i, status, clk = clock(); +    // prepare AIG +    Gia_ManSetPhase( pAig ); +    Gia_ManLevelNum( pAig ); +    Gia_ManResetTravId( pAig ); +    // create resulting data-structures +    vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) ); +    vCexStore = Vec_IntAlloc( 10000 ); +    // perform solving +    p = Cec_ManSatCreate( pAig, pPars ); +    pProgress = Bar_ProgressStart( stdout, Gia_ManPoNum(pAig) ); +    Gia_ManForEachCo( pAig, pObj, i ) +    { +        Vec_IntClear( p->vCex ); +        Bar_ProgressUpdate( pProgress, i, "SAT..." ); +        if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) ) +        { +            if ( Gia_ObjFaninC0(pObj) ) +            { +                printf( "Constant 1 output of SRM!!!\n" ); +                Cec_ManSatAddToStore( vCexStore, p->vCex, i ); // trivial counter-example +                Vec_StrPush( vStatus, 0 ); +            } +            else +            { +                printf( "Constant 0 output of SRM!!!\n" ); +                Vec_StrPush( vStatus, 1 ); +            } +            continue; +        } +        status = Cec_ManSatCheckNode( p, pObj ); +        Vec_StrPush( vStatus, (char)status ); +        if ( status == -1 ) +        { +            Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout +            continue; +        } +        if ( status == 1 ) +            continue; +        assert( status == 0 ); +        // save the pattern +        Gia_ManIncrementTravId( pAig ); +        Cec_ManSatSolveMiter_rec( p, pAig, Gia_ObjFanin0(pObj) ); +//        Gia_SatVerifyPattern( pAig, pObj, p->vCex, p->vVisits ); +        Cec_ManSatAddToStore( vCexStore, p->vCex, i ); +    } +    p->timeTotal = clock() - clk; +    Bar_ProgressStop( pProgress ); +//    if ( pPars->fVerbose ) +//        Cec_ManSatPrintStats( p ); +    Cec_ManSatStop( p ); +    *pvStatus = vStatus; +    return vCexStore;  } +  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                ///  //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/cec/module.make b/src/aig/cec/module.make index 1fc9861c..35a18cae 100644 --- a/src/aig/cec/module.make +++ b/src/aig/cec/module.make @@ -1,6 +1,8 @@  SRC +=    src/aig/cec/cecCec.c \ +    src/aig/cec/cecChoice.c \      src/aig/cec/cecClass.c \      src/aig/cec/cecCore.c \ +    src/aig/cec/cecCorr.c \      src/aig/cec/cecIso.c \      src/aig/cec/cecMan.c \      src/aig/cec/cecPat.c \ diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 28d610e9..87c85516 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -52,6 +52,15 @@ struct Gia_Rpr_t_      unsigned       fColorB :  1;  // marks cone of B  }; +typedef struct Gia_Plc_t_ Gia_Plc_t; +struct Gia_Plc_t_ +{ +    unsigned       fFixed  :  1;  // the placement of this object is fixed +    unsigned       xCoord  : 15;  // x-ooordinate of the placement +    unsigned       fUndef  :  1;  // the placement of this object is not assigned +    unsigned       yCoord  : 15;  // y-ooordinate of the placement +}; +  typedef struct Gia_Obj_t_ Gia_Obj_t;  struct Gia_Obj_t_  { @@ -117,6 +126,8 @@ struct Gia_Man_t_      Gia_Cex_t *    pCexComb;      // combinational counter-example      int *          pCopies;       // intermediate copies      Vec_Int_t *    vFlopClasses;  // classes of flops for retiming/merging/etc +    unsigned char* pSwitching;    // switching activity for each object +    Gia_Plc_t *    pPlacement;    // placement of the objects  }; @@ -247,7 +258,7 @@ static inline int          Gia_ObjFanin0CopyF( Gia_Man_t * p, int f, Gia_Obj_t *  static inline int          Gia_ObjFanin1CopyF( Gia_Man_t * p, int f, Gia_Obj_t * pObj )         { return Gia_LitNotCond(Gia_ObjCopyF(p, f, Gia_ObjFanin1(pObj)), Gia_ObjFaninC1(pObj));  }  static inline Gia_Obj_t *  Gia_ObjFromLit( Gia_Man_t * p, int iLit )           { return Gia_NotCond( Gia_ManObj(p, Gia_Lit2Var(iLit)), Gia_LitIsCompl(iLit) );  } -static inline int          Gia_ObjToLit( Gia_Man_t * p, Gia_Obj_t * pObj )     { return Gia_Var2Lit( Gia_ObjId(p, pObj), Gia_IsComplement(pObj) );              } +static inline int          Gia_ObjToLit( Gia_Man_t * p, Gia_Obj_t * pObj )     { return Gia_Var2Lit( Gia_ObjId(p, Gia_Regular(pObj)), Gia_IsComplement(pObj) ); }  static inline int          Gia_ObjPhaseRealLit( Gia_Man_t * p, int iLit )      { return Gia_ObjPhaseReal( Gia_ObjFromLit(p, iLit) );        }  static inline int          Gia_ObjValue( Gia_Obj_t * pObj )                    { return pObj->Value;                                        } @@ -375,8 +386,10 @@ static inline void        Gia_ObjSetNext( Gia_Man_t * p, int Id, int Num )   { p  static inline int         Gia_ObjIsConst( Gia_Man_t * p, int Id )            { return Gia_ObjRepr(p, Id) == 0;                                   }  static inline int         Gia_ObjIsHead( Gia_Man_t * p, int Id )             { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) > 0;  }  static inline int         Gia_ObjIsNone( Gia_Man_t * p, int Id )             { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) == 0; } -static inline int         Gia_ObjIsTail( Gia_Man_t * p, int Id )             { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) == 0;          } -static inline int         Gia_ObjIsClass( Gia_Man_t * p, int Id )            { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) || Gia_ObjNext(p, Id) > 0;           } +static inline int         Gia_ObjIsTail( Gia_Man_t * p, int Id )             { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) == 0;                  } +static inline int         Gia_ObjIsClass( Gia_Man_t * p, int Id )            { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) || Gia_ObjNext(p, Id) > 0;                   } +static inline int         Gia_ObjHasSameRepr( Gia_Man_t * p, int i, int k )  { assert( k ); return i? (Gia_ObjRepr(p, i) == Gia_ObjRepr(p, k) && Gia_ObjRepr(p, i) != GIA_VOID) : Gia_ObjRepr(p, k) == 0;  } +static inline int         Gia_ObjIsFailedPair( Gia_Man_t * p, int i, int k ) { assert( k ); return i? (Gia_ObjFailed(p, i) || Gia_ObjFailed(p, k)) : Gia_ObjFailed(p, k);                     }  #define Gia_ManForEachConst( p, i )                            \      for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsConst(p, i) ) {} else @@ -419,6 +432,8 @@ static inline int *      Gia_ObjGateFanins( Gia_Man_t * p, int Id )         { re      for ( i = 0; (i < Vec_IntSize(p->vCis)) && ((pObj) = Gia_ManCi(p, i)); i++ )  #define Gia_ManForEachCo( p, pObj, i )                                  \      for ( i = 0; (i < Vec_IntSize(p->vCos)) && ((pObj) = Gia_ManCo(p, i)); i++ ) +#define Gia_ManForEachCoReverse( p, pObj, i )                           \ +    for ( i = Vec_IntSize(p->vCos) - 1; (i >= 0) && ((pObj) = Gia_ManCo(p, i)); i-- )  #define Gia_ManForEachCoDriver( p, pObj, i )                            \      for ( i = 0; (i < Vec_IntSize(p->vCos)) && ((pObj) = Gia_ObjFanin0(Gia_ManCo(p, i))); i++ )  #define Gia_ManForEachPi( p, pObj, i )                                  \ @@ -443,7 +458,9 @@ extern Aig_Man_t *         Gia_ManToAig( Gia_Man_t * p );  /*=== giaAiger.c ===========================================================*/  extern Gia_Man_t *         Gia_ReadAiger( char * pFileName, int fCheck );  extern void                Gia_WriteAiger( Gia_Man_t * p, char * pFileName, int fWriteSymbols, int fCompact ); +extern void                Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits );  /*=== giaCsat.c ============================================================*/ +extern Vec_Int_t *         Cbs_ManSolveMiter( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus );  /*=== giaCof.c =============================================================*/  extern void                Gia_ManPrintFanio( Gia_Man_t * pGia, int nNodes );  extern Gia_Man_t *         Gia_ManDupCof( Gia_Man_t * p, int iVar ); @@ -455,6 +472,10 @@ extern void                Gia_ManCollectAnds( Gia_Man_t * p, int * pNodes, int  extern int                 Gia_ManSuppSize( Gia_Man_t * p, int * pNodes, int nNodes );  extern int                 Gia_ManConeSize( Gia_Man_t * p, int * pNodes, int nNodes );  /*=== giaDup.c ============================================================*/ +extern Gia_Man_t *         Gia_ManDupOrderDfs( Gia_Man_t * p ); +extern Gia_Man_t *         Gia_ManDupOrderDfsReverse( Gia_Man_t * p ); +extern Gia_Man_t *         Gia_ManDupOrderAiger( Gia_Man_t * p ); +  extern Gia_Man_t *         Gia_ManDup( Gia_Man_t * p );    extern Gia_Man_t *         Gia_ManDupSelf( Gia_Man_t * p );  extern Gia_Man_t *         Gia_ManDupFlopClass( Gia_Man_t * p, int iClass ); @@ -508,19 +529,22 @@ extern int                 Gia_ManHashXor( Gia_Man_t * p, int iLit0, int iLit1 )  extern int                 Gia_ManHashMux( Gia_Man_t * p, int iCtrl, int iData1, int iData0 );  extern int                 Gia_ManHashAndTry( Gia_Man_t * p, int iLit0, int iLit1 );  extern Gia_Man_t *         Gia_ManRehash( Gia_Man_t * p ); +extern void                Gia_ManHashProfile( Gia_Man_t * p );  /*=== giaLogic.c ===========================================================*/  extern void                Gia_ManTestDistance( Gia_Man_t * p );  extern void                Gia_ManSolveProblem( Gia_Man_t * pGia, Emb_Par_t * pPars );   /*=== giaMan.c ===========================================================*/  extern Gia_Man_t *         Gia_ManStart( int nObjsMax );   extern void                Gia_ManStop( Gia_Man_t * p );   -extern void                Gia_ManPrintStats( Gia_Man_t * p );  +extern void                Gia_ManPrintStats( Gia_Man_t * p, int fSwitch );   extern void                Gia_ManPrintStatsShort( Gia_Man_t * p );   extern void                Gia_ManPrintMiterStatus( Gia_Man_t * p );   extern void                Gia_ManSetRegNum( Gia_Man_t * p, int nRegs );  extern void                Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew );  /*=== giaMap.c ===========================================================*/  extern void                Gia_ManPrintMappingStats( Gia_Man_t * p ); +/*=== giaPat.c ===========================================================*/ +extern void                Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, Vec_Int_t * vVisit );  /*=== giaRetime.c ===========================================================*/  extern Gia_Man_t *         Gia_ManRetimeForward( Gia_Man_t * p, int nMaxIters, int fVerbose );  /*=== giaSat.c ============================================================*/ @@ -535,6 +559,9 @@ extern Gia_Man_t *         Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int  extern int *               Gia_SortFloats( float * pArray, int * pPerm, int nSize );  /*=== giaSim.c ============================================================*/  extern int                 Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars ); +/*=== giaSwitch.c ============================================================*/ +extern float               Gia_ManEvaluateSwitching( Gia_Man_t * p ); +extern float               Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbOne );  /*=== giaTsim.c ============================================================*/  extern Gia_Man_t *         Gia_ManReduceConst( Gia_Man_t * pAig, int fVerbose );  /*=== giaUtil.c ===========================================================*/ diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index da1a8c9f..adc58e6c 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -194,6 +194,25 @@ int Gia_ReadInt( unsigned char * pPos )  /**Function************************************************************* +  Synopsis    [Reads decoded value.] + +  Description [] +   +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev ) +{ +    int Item = Gia_ReadAigerDecode( ppPos ); +    if ( Item & 1 ) +        return iPrev + (Item >> 1); +    return iPrev - (Item >> 1); +} + +/**Function************************************************************* +    Synopsis    [Read equivalence classes from the string.]    Description [] @@ -238,7 +257,7 @@ Gia_Rpr_t * Gia_ReadEquivClasses( unsigned char ** ppPos, int nSize )  /**Function************************************************************* -  Synopsis    [Reads decoded value.] +  Synopsis    [Read flop classes from the string.]    Description [] @@ -247,12 +266,13 @@ Gia_Rpr_t * Gia_ReadEquivClasses( unsigned char ** ppPos, int nSize )    SeeAlso     []  ***********************************************************************/ -unsigned Gia_ReadDiffValue( char ** ppPos, int iPrev ) +void Gia_ReadFlopClasses( unsigned char ** ppPos, Vec_Int_t * vClasses, int nSize )  { -    int Item = Gia_ReadAigerDecode( ppPos ); -    if ( Item & 1 ) -        return iPrev + (Item >> 1); -    return iPrev - (Item >> 1); +    int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; +    assert( nAlloc/4 == nSize ); +    assert( Vec_IntSize(vClasses) == nSize ); +    memcpy( Vec_IntArray(vClasses), *ppPos, 4*nSize ); +    *ppPos += 4 * nSize;  }  /**Function************************************************************* @@ -290,6 +310,50 @@ int * Gia_ReadMapping( unsigned char ** ppPos, int nSize )  /**Function************************************************************* +  Synopsis    [Read switching from the string.] + +  Description [] +   +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +unsigned char * Gia_ReadSwitching( unsigned char ** ppPos, int nSize ) +{ +    unsigned char * pSwitching; +    int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; +    assert( nAlloc == nSize ); +    pSwitching = ABC_ALLOC( unsigned char, nSize ); +    memcpy( pSwitching, *ppPos, nSize ); +    *ppPos += nSize; +    return pSwitching; +} + +/**Function************************************************************* + +  Synopsis    [Read placement from the string.] + +  Description [] +   +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Gia_Plc_t * Gia_ReadPlacement( unsigned char ** ppPos, int nSize ) +{ +    Gia_Plc_t * pPlacement; +    int nAlloc = Gia_ReadInt( *ppPos ); *ppPos += 4; +    assert( nAlloc/4 == nSize ); +    pPlacement = ABC_ALLOC( Gia_Plc_t, nSize ); +    memcpy( pPlacement, *ppPos, 4*nSize ); +    *ppPos += 4 * nSize; +    return pPlacement; +} + +/**Function************************************************************* +    Synopsis    [Reads the AIG in the binary AIGER format.]    Description [] @@ -455,6 +519,13 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck )              pNew->pReprs = Gia_ReadEquivClasses( &pCur, Gia_ManObjNum(pNew) );              pNew->pNexts = Gia_ManDeriveNexts( pNew );          } +        if ( *pCur == 'f' ) +        { +            pCur++; +            // read flop classes +            pNew->vFlopClasses = Vec_IntStart( Gia_ManRegNum(pNew) ); +            Gia_ReadFlopClasses( &pCur, pNew->vFlopClasses, Gia_ManRegNum(pNew) ); +        }          if ( *pCur == 'm' )          {              pCur++; @@ -465,6 +536,13 @@ Gia_Man_t * Gia_ReadAiger( char * pFileName, int fCheck )          {              pCur++;              // read placement +            pNew->pPlacement = Gia_ReadPlacement( &pCur, Gia_ManObjNum(pNew) ); +        } +        if ( *pCur == 's' ) +        { +            pCur++; +            // read switching activity +            pNew->pSwitching = Gia_ReadSwitching( &pCur, Gia_ManObjNum(pNew) );          }          if ( *pCur == 'n' )          { @@ -762,7 +840,10 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int      // create normalized AIG      if ( !Gia_ManIsNormalized(pInit) ) +    { +        printf( "Gia_WriteAiger(): Normalizing AIG for writing.\n" );          p = Gia_ManDupNormalized( pInit ); +    }      else          p = pInit; @@ -831,6 +912,15 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int          fwrite( pEquivs, 1, nEquivSize, pFile );          ABC_FREE( pEquivs );      } +    // write flop classes +    if ( p->vFlopClasses ) +    { +        char Buffer[10]; +        int nSize = 4*Gia_ManRegNum(p); +        fprintf( pFile, "f" ); +        fwrite( Buffer, 1, 4, pFile ); +        fwrite( Vec_IntArray(p->vFlopClasses), 1, nSize, pFile ); +    }      // write mapping      if ( p->pMapping )      { @@ -841,6 +931,26 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int          ABC_FREE( pMaps );      }      // write placement +    if ( p->pPlacement ) +    { +        char Buffer[10]; +        int nSize = 4*Gia_ManObjNum(p); +        Gia_WriteInt( Buffer, nSize ); +        fprintf( pFile, "p" ); +        fwrite( Buffer, 1, 4, pFile ); +        fwrite( p->pPlacement, 1, nSize, pFile ); +    } +    // write flop classes +    if ( p->pSwitching ) +    { +        char Buffer[10]; +        int nSize = Gia_ManObjNum(p); +        Gia_WriteInt( Buffer, nSize ); +        fprintf( pFile, "s" ); +        fwrite( Buffer, 1, 4, pFile ); +        fwrite( p->pSwitching, 1, nSize, pFile ); +    } +    // write name      if ( p->pName )          fprintf( pFile, "n%s%c", p->pName, '\0' );      fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() ); @@ -850,6 +960,24 @@ void Gia_WriteAiger( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int          Gia_ManStop( p );  } +/**Function************************************************************* + +  Synopsis    [Writes the AIG in the binary AIGER format.] + +  Description [] +   +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits ) +{ +    char Buffer[100]; +    sprintf( Buffer, "%s%0*d.aig", pFilePrefix, nFileNumDigits, iFileNum ); +    Gia_WriteAiger( p, Buffer, 0, 0 ); +} +  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                ///  //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaCSat2.c b/src/aig/gia/giaCSat.c index 1e7cc949..5fa9f40f 100644 --- a/src/aig/gia/giaCSat2.c +++ b/src/aig/gia/giaCSat.c @@ -1,6 +1,6 @@  /**CFile**************************************************************** -  FileName    [giaCSat2.c] +  FileName    [giaCSat.c]    SystemName  [ABC: Logic synthesis and verification system.] @@ -14,7 +14,7 @@    Date        [Ver. 1.0. Started - June 20, 2005.] -  Revision    [$Id: giaCSat2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] +  Revision    [$Id: giaCSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]  ***********************************************************************/ @@ -48,10 +48,10 @@ struct Cbs_Que_t_  {      int           iHead;        // beginning of the queue      int           iTail;        // end of the queue -    int           nSize;        // allocated size +   int           nSize;        // allocated size      Gia_Obj_t **  pData;        // nodes stored in the queue  }; - +   typedef struct Cbs_Man_t_ Cbs_Man_t;  struct Cbs_Man_t_  { @@ -60,6 +60,20 @@ struct Cbs_Man_t_      Cbs_Que_t     pProp;        // propagation queue      Cbs_Que_t     pJust;        // justification queue      Vec_Int_t *   vModel;       // satisfying assignment +    // SAT calls statistics +    int           nSatUnsat;    // the number of proofs +    int           nSatSat;      // the number of failure +    int           nSatUndec;    // the number of timeouts +    int           nSatTotal;    // the number of calls +    // conflicts +    int           nConfUnsat;   // conflicts in unsat problems +    int           nConfSat;     // conflicts in sat problems +    int           nConfUndec;   // conflicts in undec problems +    // runtime stats +    int           timeSatUnsat; // unsat +    int           timeSatSat;   // sat +    int           timeSatUndec; // undecided +    int           timeTotal;    // total runtime  };  static inline int   Cbs_VarIsAssigned( Gia_Obj_t * pVar )      { return pVar->fMark0;                        } @@ -196,7 +210,8 @@ static inline void Cbs_ManSaveModel( Cbs_Man_t * p, Vec_Int_t * vCex )      p->pProp.iHead = 0;      Cbs_QueForEachEntry( p->pProp, pVar, i )          if ( Gia_ObjIsCi(pVar) ) -            Vec_IntPush( vCex, Gia_Var2Lit(Gia_ObjId(p->pAig,pVar), !Cbs_VarValue(pVar)) ); +//            Vec_IntPush( vCex, Gia_Var2Lit(Gia_ObjId(p->pAig,pVar), !Cbs_VarValue(pVar)) ); +            Vec_IntPush( vCex, Gia_Var2Lit(Gia_ObjCioId(pVar), !Cbs_VarValue(pVar)) );  }   /**Function************************************************************* @@ -714,7 +729,7 @@ void Cbs_ManSolveTest( Gia_Man_t * pGia )              CountUndec++;          else           { -            int iLit, k; +//            int iLit, k;              vCex = Cbs_ReadModel( p );  //        printf( "complemented = %d.  ", Gia_ObjFaninC0(pRoot) ); @@ -738,6 +753,132 @@ void Cbs_ManSolveTest( Gia_Man_t * pGia )  } +/**Function************************************************************* + +  Synopsis    [Prints statistics of the manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Cbs_ManSatPrintStats( Cbs_Man_t * p ) +{ +    printf( "CO = %6d  ", Gia_ManCoNum(p->pAig) ); +    printf( "Conf = %5d  ", p->Pars.nBTLimit ); +    printf( "JustMax = %5d  ", p->Pars.nJustLimit ); +    printf( "\n" ); +    printf( "Unsat calls %6d  (%6.2f %%)   Ave conf = %8.1f   ",  +        p->nSatUnsat, 100.0*p->nSatUnsat/p->nSatTotal, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 ); +    ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal ); +    printf( "Sat   calls %6d  (%6.2f %%)   Ave conf = %8.1f   ",  +        p->nSatSat,   100.0*p->nSatSat/p->nSatTotal, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 ); +    ABC_PRTP( "Time", p->timeSatSat,   p->timeTotal ); +    printf( "Undef calls %6d  (%6.2f %%)   Ave conf = %8.1f   ",  +        p->nSatUndec, 100.0*p->nSatUndec/p->nSatTotal, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 ); +    ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal ); +    ABC_PRT( "Total time", p->timeTotal ); +} + +/**Function************************************************************* + +  Synopsis    [Procedure to test the new SAT solver.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Vec_Int_t * Cbs_ManSolveMiter( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus ) +{ +    extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out ); +    Cbs_Man_t * p;  +    Vec_Int_t * vCex, * vVisit, * vCexStore; +    Vec_Str_t * vStatus; +    Gia_Obj_t * pRoot;  +    int i, status, clk, clkTotal = clock(); +    assert( Gia_ManRegNum(pAig) == 0 ); +    // prepare AIG +    Gia_ManCreateRefs( pAig ); +    Gia_ManCleanMark0( pAig ); +    Gia_ManCleanMark1( pAig ); +    // create logic network +    p = Cbs_ManAlloc(); +    p->Pars.nBTLimit = nConfs; +    p->pAig   = pAig; +    // create resulting data-structures +    vStatus   = Vec_StrAlloc( Gia_ManPoNum(pAig) ); +    vCexStore = Vec_IntAlloc( 10000 ); +    vVisit    = Vec_IntAlloc( 100 ); +    vCex      = Cbs_ReadModel( p ); +    // solve for each output +    Gia_ManForEachCo( pAig, pRoot, i ) +    { +        Vec_IntClear( vCex ); +        if ( Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ) +        { +            if ( Gia_ObjFaninC0(pRoot) ) +            { +                printf( "Constant 1 output of SRM!!!\n" ); +                Cec_ManSatAddToStore( vCexStore, vCex, i ); // trivial counter-example +                Vec_StrPush( vStatus, 0 ); +            } +            else +            { +                printf( "Constant 0 output of SRM!!!\n" ); +                Vec_StrPush( vStatus, 1 ); +            } +            continue; +        } +        clk = clock(); +        p->Pars.fUseHighest = 1; +        p->Pars.fUseLowest  = 0; +        status = Cbs_ManSolve( p, Gia_ObjChild0(pRoot) ); +        if ( status == -1 ) +        { +            p->Pars.fUseHighest = 0; +            p->Pars.fUseLowest  = 1; +            status = Cbs_ManSolve( p, Gia_ObjChild0(pRoot) ); +        } +        Vec_StrPush( vStatus, (char)status ); +        if ( status == -1 ) +        { +            p->nSatUndec++; +            p->nConfUndec += p->Pars.nBTThis; +            Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout +            p->timeSatUndec += clock() - clk; +            continue; +        } +        if ( status == 1 ) +        { +            p->nSatUnsat++; +            p->nConfUnsat += p->Pars.nBTThis; +            p->timeSatUnsat += clock() - clk; +            continue; +        } +        p->nSatSat++; +        p->nConfUnsat += p->Pars.nBTThis; +//        Gia_SatVerifyPattern( pAig, pRoot, vCex, vVisit ); +        Cec_ManSatAddToStore( vCexStore, vCex, i ); +        p->timeSatSat += clock() - clk; +    } +    Vec_IntFree( vVisit ); +    p->nSatTotal = Gia_ManPoNum(pAig); +    p->timeTotal = clock() - clkTotal; +//    Cbs_ManSatPrintStats( p ); +    Cbs_ManStop( p ); +    *pvStatus = vStatus; +//    printf( "Total number of cex literals = %d. (Ave = %d)\n",  +//         Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat,  +//        (Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat)/p->nSatSat ); +    return vCexStore; +} + +  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                ///  //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaCSat0.c b/src/aig/gia/giaCSat0.c deleted file mode 100644 index a0d567a2..00000000 --- a/src/aig/gia/giaCSat0.c +++ /dev/null @@ -1,328 +0,0 @@ -/**CFile**************************************************************** - -  FileName    [giaCsat0.c] - -  SystemName  [ABC: Logic synthesis and verification system.] - -  PackageName [Scalable AIG package.] - -  Synopsis    [Circuit-based SAT solver.] - -  Author      [Alan Mishchenko] -   -  Affiliation [UC Berkeley] - -  Date        [Ver. 1.0. Started - June 20, 2005.] - -  Revision    [$Id: giaCsat0.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" - -//////////////////////////////////////////////////////////////////////// -///                        DECLARATIONS                              /// -//////////////////////////////////////////////////////////////////////// - -static inline int          Sat_ObjXValue( Gia_Obj_t * pObj )          { return (pObj->fMark1 << 1) | pObj->fMark0; } -static inline void         Sat_ObjSetXValue( Gia_Obj_t * pObj, int v) { pObj->fMark0 = (v & 1); pObj->fMark1 = ((v >> 1) & 1); } - -static inline int          Sat_VarIsAssigned( Gia_Obj_t * pVar )      { return pVar->Value > 0;                    } -static inline void         Sat_VarAssign( Gia_Obj_t * pVar, int i )   { assert(!pVar->Value); pVar->Value = i;     } -static inline void         Sat_VarUnassign( Gia_Obj_t * pVar )        { assert(pVar->Value);  pVar->Value = 0;     } -static inline int          Sat_VarValue( Gia_Obj_t * pVar )           { assert(pVar->Value);  return pVar->fMark0; } -static inline void         Sat_VarSetValue( Gia_Obj_t * pVar, int v ) { assert(pVar->Value);  pVar->fMark0 = v;    } - -//////////////////////////////////////////////////////////////////////// -///                     FUNCTION DEFINITIONS                         /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - -  Synopsis    [Collects nodes in the cone and initialized them to x.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Gia_SatCollectCone_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vVisit ) -{ -    if ( Sat_ObjXValue(pObj) == GIA_UND ) -        return; -    assert( pObj->Value == 0 ); -    if ( Gia_ObjIsAnd(pObj) ) -    { -        Gia_SatCollectCone_rec( p, Gia_ObjFanin0(pObj), vVisit ); -        Gia_SatCollectCone_rec( p, Gia_ObjFanin1(pObj), vVisit ); -    } -    assert( Sat_ObjXValue(pObj) == 0 ); -    Sat_ObjSetXValue( pObj, GIA_UND ); -    Vec_IntPush( vVisit, Gia_ObjId(p, pObj) ); -} - -/**Function************************************************************* - -  Synopsis    [Collects nodes in the cone and initialized them to x.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Gia_SatCollectCone( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vVisit ) -{ -    assert( !Gia_IsComplement(pObj) ); -    assert( !Gia_ObjIsConst0(pObj) ); -    assert( Sat_ObjXValue(pObj) == 0 ); -    Vec_IntClear( vVisit ); -    Gia_SatCollectCone_rec( p, pObj, vVisit ); -} - -/**Function************************************************************* - -  Synopsis    [Collects nodes in the cone.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, Vec_Int_t * vVisit ) -{ -    Gia_Obj_t * pObj; -    int i, Entry, Value, Value0, Value1; -    assert( Gia_ObjIsCo(pRoot) ); -    assert( !Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ); -    // collect nodes and initialized them to x -    Gia_SatCollectCone( p, Gia_ObjFanin0(pRoot), vVisit ); -    // set binary values to nodes in the counter-example -    Vec_IntForEachEntry( vCex, Entry, i ) -    { -        pObj = Gia_NotCond( Gia_ManObj( p, Gia_Lit2Var(Entry) ), Gia_LitIsCompl(Entry) ); -        Sat_ObjSetXValue( Gia_Regular(pObj), Gia_IsComplement(pObj)? GIA_ZER : GIA_ONE ); -        assert( Sat_ObjXValue(Gia_Regular(pObj)) == (Gia_IsComplement(pObj)? GIA_ZER : GIA_ONE) ); -    } -    // simulate -    Gia_ManForEachObjVec( vVisit, p, pObj, i ) -    { -        if ( Gia_ObjIsCi(pObj) ) -            continue; -        assert( Gia_ObjIsAnd(pObj) ); -        Value0 = Sat_ObjXValue( Gia_ObjFanin0(pObj) ); -        Value1 = Sat_ObjXValue( Gia_ObjFanin1(pObj) ); -        Value = Gia_XsimAndCond( Value0, Gia_ObjFaninC0(pObj), Value1, Gia_ObjFaninC1(pObj) ); -        Sat_ObjSetXValue( pObj, Value ); -    } -    Value = Gia_XsimNotCond( Value, Gia_ObjFaninC0(pRoot) ); -    if ( Value != GIA_ONE ) -        printf( "Gia_SatVerifyPattern(): Verification FAILED.\n" ); -//    else -//        printf( "Gia_SatVerifyPattern(): Verification succeeded.\n" ); -//    assert( Value == GIA_ONE ); -    // clean the nodes -    Gia_ManForEachObjVec( vVisit, p, pObj, i ) -        Sat_ObjSetXValue( pObj, 0 ); -} - - -/**Function************************************************************* - -  Synopsis    [Undoes the assignment since the given value.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Gia_SatUndo_rec( Gia_Obj_t * pObj, unsigned Value, Vec_Int_t * vCex ) -{ -    if ( pObj->Value < Value ) -        return; -    pObj->Value = 0; -    if ( Gia_ObjIsCi(pObj) ) -    { -        if ( vCex ) Vec_IntPush( vCex, Gia_Var2Lit(Gia_ObjCioId(pObj), !pObj->fPhase) ); -        return; -    } -    Gia_SatUndo_rec( Gia_ObjFanin0(pObj), Value, vCex ); -    Gia_SatUndo_rec( Gia_ObjFanin1(pObj), Value, vCex ); -} - -/**Function************************************************************* - -  Synopsis    [Propagates assignments.] - -  Description [Returns 1 if UNSAT, 0 if SAT.] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -int Gia_SatProp_rec( Gia_Obj_t * pObj, unsigned Phase, unsigned * pValue, int * pnConfs ) -{ -    int Value = *pValue; -    if ( pObj->Value ) -        return pObj->fPhase != Phase; -    if ( Gia_ObjIsCi(pObj) ) -    { -        pObj->Value = Value; -        pObj->fPhase = Phase; -        return 0; -    } -    if ( Phase ) // output of AND should be 1 -    { -        if ( Gia_SatProp_rec( Gia_ObjFanin0(pObj), !Gia_ObjFaninC0(pObj), pValue, pnConfs ) ) -            return 1; -        if ( Gia_SatProp_rec( Gia_ObjFanin1(pObj), !Gia_ObjFaninC1(pObj), pValue, pnConfs ) ) -        { -            Gia_SatUndo_rec( Gia_ObjFanin0(pObj), Value, NULL ); -            return 1; -        } -/* -        if ( Gia_SatProp_rec( Gia_ObjFanin1(pObj), !Gia_ObjFaninC1(pObj), pValue, pnConfs ) ) -            return 1; -        if ( Gia_SatProp_rec( Gia_ObjFanin0(pObj), !Gia_ObjFaninC0(pObj), pValue, pnConfs ) ) -        { -            Gia_SatUndo_rec( Gia_ObjFanin1(pObj), Value, NULL ); -            return 1; -        } -*/ -        pObj->Value = Value; -        pObj->fPhase = 1; -        return 0;  -    } -    // output of AND should be 0 - -    (*pValue)++; -    if ( !Gia_SatProp_rec( Gia_ObjFanin1(pObj), Gia_ObjFaninC1(pObj), pValue, pnConfs ) ) -    { -        pObj->Value = Value; -        pObj->fPhase = 0; -        return 0; -    } -    if ( !*pnConfs ) -        return 1; - -    (*pValue)++; -    if ( !Gia_SatProp_rec( Gia_ObjFanin0(pObj), Gia_ObjFaninC0(pObj), pValue, pnConfs ) ) -    { -        pObj->Value = Value; -        pObj->fPhase = 0; -        return 0; -    } -    if ( !*pnConfs ) -        return 1; -    // cannot be satisfied -    (*pnConfs)--; -    return 1; -} - -/**Function************************************************************* - -  Synopsis    [Procedure to solve SAT for the node.] - -  Description [Returns 1 if UNSAT, 0 if SAT, and -1 if undecided.] -                -  SideEffects [Precondition: pObj->Value should be 0.] - -  SeeAlso     [] - -***********************************************************************/ -int Gia_SatSolve( Gia_Obj_t * pObj, unsigned Phase, int nConfsMax, Vec_Int_t * vCex ) -{ -    int Value = 1; -    int nConfs = nConfsMax? nConfsMax : (1<<30); -    assert( !Gia_IsComplement(pObj) ); -    assert( !Gia_ObjIsConst0(pObj) ); -    assert( pObj->Value == 0 ); -    if ( Gia_SatProp_rec( pObj, Phase, &Value, &nConfs ) ) -    { -//        if ( nConfs ) -//            printf( "UNSAT after %d conflicts\n", nConfsMax - nConfs ); -//        else -//            printf( "UNDEC after %d conflicts\n", nConfsMax ); -        return nConfs? 1 : -1; -    } -    Vec_IntClear( vCex ); -    Gia_SatUndo_rec( pObj, 1, vCex ); -//    printf( "SAT after %d conflicts\n", nConfsMax - nConfs ); -    return 0; -} - - - -/**Function************************************************************* - -  Synopsis    [Procedure to test the new SAT solver.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Gia_SatSolveTest( Gia_Man_t * p ) -{ -    int nConfsMax = 1000; -    int CountUnsat, CountSat, CountUndec; -    Vec_Int_t * vCex; -    Vec_Int_t * vVisit; -    Gia_Obj_t * pRoot;  -    int i, RetValue, clk = clock(); -    // prepare AIG -    Gia_ManCleanValue( p ); -    Gia_ManCleanMark0( p ); -    Gia_ManCleanMark1( p ); -    vCex   = Vec_IntAlloc( 100 ); -    vVisit = Vec_IntAlloc( 100 ); -    // solve for each output -    CountUnsat = CountSat = CountUndec = 0; -    Gia_ManForEachCo( p, pRoot, i ) -    { -        if ( Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ) -            continue; -//printf( "Output %6d : ", i ); -        RetValue = Gia_SatSolve( Gia_ObjFanin0(pRoot), !Gia_ObjFaninC0(pRoot), nConfsMax, vCex ); -        if ( RetValue == 1 ) -            CountUnsat++; -        else if ( RetValue == -1 ) -            CountUndec++; -        else  -        { -//            Gia_Obj_t * pTemp; -//            int k; -            assert( RetValue == 0 ); -            CountSat++; -/* -            Vec_IntForEachEntry( vCex, pTemp, k ) -//                printf( "%s%d ", Gia_IsComplement(pTemp)? "!": "", Gia_ObjCioId(Gia_Regular(pTemp)) ); -                printf( "%s%d ", Gia_IsComplement(pTemp)? "!": "", Gia_ObjId(p,Gia_Regular(pTemp)) ); -            printf( "\n" ); -*/ -//            Gia_SatVerifyPattern( p, pRoot, vCex, vVisit ); -        } -//        Gia_ManCheckMark0( p ); -//        Gia_ManCheckMark1( p ); -    } -    Vec_IntFree( vCex ); -    Vec_IntFree( vVisit ); -    printf( "Unsat = %d. Sat = %d. Undec = %d.  ", CountUnsat, CountSat, CountUndec ); -    ABC_PRT( "Time", clock() - clk ); -} - -//////////////////////////////////////////////////////////////////////// -///                       END OF FILE                                /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/gia/giaCSat1.c b/src/aig/gia/giaCSat1.c deleted file mode 100644 index 12b7071f..00000000 --- a/src/aig/gia/giaCSat1.c +++ /dev/null @@ -1,602 +0,0 @@ -/**CFile**************************************************************** - -  FileName    [giaCsat1.c] - -  SystemName  [ABC: Logic synthesis and verification system.] - -  PackageName [Scalable AIG package.] - -  Synopsis    [Circuit-based SAT solver.] - -  Author      [Alan Mishchenko] -   -  Affiliation [UC Berkeley] - -  Date        [Ver. 1.0. Started - June 20, 2005.] - -  Revision    [$Id: giaCsat1.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" - -//////////////////////////////////////////////////////////////////////// -///                        DECLARATIONS                              /// -//////////////////////////////////////////////////////////////////////// - - -typedef struct Css_Fan_t_ Css_Fan_t; -struct Css_Fan_t_ -{ -    unsigned       iFan     : 31;    // ID of the fanin/fanout -    unsigned       fCompl   :  1;    // complemented attribute -}; - -typedef struct Css_Obj_t_ Css_Obj_t; -struct Css_Obj_t_ -{ -    unsigned       fCi      :  1;    // terminal node CI -    unsigned       fCo      :  1;    // terminal node CO -    unsigned       fAssign  :  1;    // assigned variable -    unsigned       fValue   :  1;    // variable value -    unsigned       fPhase   :  1;    // value under 000 pattern -    unsigned       nFanins  :  5;    // the number of fanins -    unsigned       nFanouts : 22;    // total number of fanouts -    unsigned       hHandle;          // application specific data -    union { -    unsigned       iFanouts;         // application specific data -    int            TravId;           // ID of the node -    }; -    Css_Fan_t      Fanios[0];        // the array of fanins/fanouts -}; - -typedef struct Css_Man_t_ Css_Man_t; -struct Css_Man_t_ -{ -    Gia_Man_t *    pGia;             // the original AIG manager -    Vec_Int_t *    vCis;             // the vector of CIs (PIs + LOs) -    Vec_Int_t *    vCos;             // the vector of COs (POs + LIs) -    int            nObjs;            // the number of objects -    int            nNodes;           // the number of nodes -    int *          pObjData;         // the logic network defined for the AIG -    int            nObjData;         // the size of array to store the logic network -    int *          pLevels;          // the linked lists of levels -    int            nLevels;          // the max number of logic levels -    int            nTravIds;         // traversal ID to mark the cones -    Vec_Int_t *    vTrail;           // sequence of assignments -    int            nConfsMax;         // max number of conflicts -}; - -static inline unsigned    Gia_ObjHandle( Gia_Obj_t * pObj )                           { return pObj->Value;                                 }  - -static inline int         Css_ObjIsCi( Css_Obj_t * pObj )                             { return pObj->fCi;                                   }  -static inline int         Css_ObjIsCo( Css_Obj_t * pObj )                             { return pObj->fCo;                                   }  -static inline int         Css_ObjIsNode( Css_Obj_t * pObj )                           { return!pObj->fCi &&!pObj->fCo && pObj->nFanins > 0; }  -static inline int         Css_ObjIsConst0( Css_Obj_t * pObj )                         { return!pObj->fCi &&!pObj->fCo && pObj->nFanins == 0;}  - -static inline int         Css_ObjFaninNum( Css_Obj_t * pObj )                         { return pObj->nFanins;                               }  -static inline int         Css_ObjFanoutNum( Css_Obj_t * pObj )                        { return pObj->nFanouts;                              }  -static inline int         Css_ObjSize( Css_Obj_t * pObj )                             { return sizeof(Css_Obj_t) / 4 + pObj->nFanins + pObj->nFanouts;  }  -static inline int         Css_ObjId( Css_Obj_t * pObj )                               { assert( 0 ); return -1;                             }  - -static inline Css_Obj_t * Css_ManObj( Css_Man_t * p, unsigned iHandle )               { return (Css_Obj_t *)(p->pObjData + iHandle);        }  -static inline Css_Obj_t * Css_ObjFanin( Css_Obj_t * pObj, int i )                     { return (Css_Obj_t *)(((int *)pObj) - pObj->Fanios[i].iFan);               }  -static inline Css_Obj_t * Css_ObjFanout( Css_Obj_t * pObj, int i )                    { return (Css_Obj_t *)(((int *)pObj) + pObj->Fanios[pObj->nFanins+i].iFan); }  -static inline int         Css_ObjFaninC( Css_Obj_t * pObj, int i )                    { return pObj->Fanios[i].fCompl;                      }  -static inline int         Css_ObjFanoutC( Css_Obj_t * pObj, int i )                   { return pObj->Fanios[pObj->nFanins+i].fCompl;        }  - -static inline int         Css_ManObjNum( Css_Man_t * p )                              { return p->nObjs;                                    }  -static inline int         Css_ManNodeNum( Css_Man_t * p )                             { return p->nNodes;                                   }  -  -static inline void        Css_ManIncrementTravId( Css_Man_t * p )                     { p->nTravIds++;                                      } -static inline void        Css_ObjSetTravId( Css_Obj_t * pObj, int TravId )            { pObj->TravId = TravId;                              } -static inline void        Css_ObjSetTravIdCurrent( Css_Man_t * p, Css_Obj_t * pObj )  { pObj->TravId = p->nTravIds;                         } -static inline void        Css_ObjSetTravIdPrevious( Css_Man_t * p, Css_Obj_t * pObj ) { pObj->TravId = p->nTravIds - 1;                     } -static inline int         Css_ObjIsTravIdCurrent( Css_Man_t * p, Css_Obj_t * pObj )   { return ((int)pObj->TravId == p->nTravIds);          } -static inline int         Css_ObjIsTravIdPrevious( Css_Man_t * p, Css_Obj_t * pObj )  { return ((int)pObj->TravId == p->nTravIds - 1);      } - -static inline int   Css_VarIsAssigned( Css_Obj_t * pVar )      { return pVar->fAssign;                        } -static inline void  Css_VarAssign( Css_Obj_t * pVar )          { assert(!pVar->fAssign); pVar->fAssign = 1;   } -static inline void  Css_VarUnassign( Css_Obj_t * pVar )        { assert(pVar->fAssign);  pVar->fAssign = 0;   } -static inline int   Css_VarValue( Css_Obj_t * pVar )           { assert(pVar->fAssign);  return pVar->fValue; } -static inline void  Css_VarSetValue( Css_Obj_t * pVar, int v ) { assert(pVar->fAssign);  pVar->fValue = v;    } - -#define Css_ManForEachObj( p, pObj, i )               \ -    for ( i = 0; (i < p->nObjData) && (pObj = Css_ManObj(p,i)); i += Css_ObjSize(pObj) ) -#define Css_ManForEachObjVecStart( vVec, p, pObj, i, iStart )            \ -    for ( i = iStart; (i < Vec_IntSize(vVec)) && (pObj = Css_ManObj(p,Vec_IntEntry(vVec,i))); i++ ) -#define Css_ManForEachNode( p, pObj, i )              \ -    for ( i = 0; (i < p->nObjData) && (pObj = Css_ManObj(p,i)); i += Css_ObjSize(pObj) ) if ( Css_ObjIsTerm(pObj) ) {} else -#define Css_ObjForEachFanin( pObj, pNext, i )         \ -    for ( i = 0; (i < (int)pObj->nFanins) && (pNext = Css_ObjFanin(pObj,i)); i++ ) -#define Css_ObjForEachFanout( pObj, pNext, i )        \ -    for ( i = 0; (i < (int)pObj->nFanouts) && (pNext = Css_ObjFanout(pObj,i)); i++ ) -#define Css_ObjForEachFaninLit( pObj, pNext, fCompl, i )         \ -    for ( i = 0; (i < (int)pObj->nFanins) && (pNext = Css_ObjFanin(pObj,i)) && ((fCompl = Css_ObjFaninC(pObj,i)),1); i++ ) -#define Css_ObjForEachFanoutLit( pObj, pNext, fCompl, i )        \ -    for ( i = 0; (i < (int)pObj->nFanouts) && (pNext = Css_ObjFanout(pObj,i)) && ((fCompl = Css_ObjFanoutC(pObj,i)),1); i++ ) - -//////////////////////////////////////////////////////////////////////// -///                     FUNCTION DEFINITIONS                         /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - -  Synopsis    [Creates logic network isomorphic to the given AIG.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -Css_Man_t * Css_ManCreateLogicSimple( Gia_Man_t * pGia ) -{ -    Css_Man_t * p; -    Css_Obj_t * pObjLog, * pFanLog; -    Gia_Obj_t * pObj; -    int i, iHandle = 0; -    p = ABC_CALLOC( Css_Man_t, 1 ); -    p->pGia = pGia; -    p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) ); -    p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) ); -    p->nObjData = (sizeof(Css_Obj_t) / 4) * Gia_ManObjNum(pGia) + 4 * Gia_ManAndNum(pGia) + 2 * Gia_ManCoNum(pGia); -    p->pObjData = ABC_CALLOC( int, p->nObjData ); -    ABC_FREE( pGia->pRefs ); -    Gia_ManCreateRefs( pGia ); -    Gia_ManForEachObj( pGia, pObj, i ) -    { -        pObj->Value = iHandle; -        pObjLog = Css_ManObj( p, iHandle ); -        pObjLog->nFanins  = 0; -        pObjLog->nFanouts = Gia_ObjRefs( pGia, pObj ); -        pObjLog->hHandle  = iHandle; -        pObjLog->iFanouts = 0; -        if ( Gia_ObjIsAnd(pObj) ) -        { -            pFanLog = Css_ManObj( p, Gia_ObjHandle(Gia_ObjFanin0(pObj)) );  -            pFanLog->Fanios[pFanLog->nFanins + pFanLog->iFanouts].iFan =  -                pObjLog->Fanios[pObjLog->nFanins].iFan = pObjLog->hHandle - pFanLog->hHandle; -            pFanLog->Fanios[pFanLog->nFanins + pFanLog->iFanouts++].fCompl = -                pObjLog->Fanios[pObjLog->nFanins++].fCompl = Gia_ObjFaninC0(pObj); - -            pFanLog = Css_ManObj( p, Gia_ObjHandle(Gia_ObjFanin1(pObj)) );  -            pFanLog->Fanios[pFanLog->nFanins + pFanLog->iFanouts].iFan =  -                pObjLog->Fanios[pObjLog->nFanins].iFan = pObjLog->hHandle - pFanLog->hHandle; -            pFanLog->Fanios[pFanLog->nFanins + pFanLog->iFanouts++].fCompl = -                pObjLog->Fanios[pObjLog->nFanins++].fCompl = Gia_ObjFaninC1(pObj); - -            p->nNodes++; -        } -        else if ( Gia_ObjIsCo(pObj) ) -        { -            pFanLog = Css_ManObj( p, Gia_ObjHandle(Gia_ObjFanin0(pObj)) );  -            pFanLog->Fanios[pFanLog->nFanins + pFanLog->iFanouts].iFan =  -                pObjLog->Fanios[pObjLog->nFanins].iFan = pObjLog->hHandle - pFanLog->hHandle; -            pFanLog->Fanios[pFanLog->nFanins + pFanLog->iFanouts++].fCompl = -                pObjLog->Fanios[pObjLog->nFanins++].fCompl = Gia_ObjFaninC0(pObj); - -            pObjLog->fCo = 1; -            Vec_IntPush( p->vCos, iHandle ); -        } -        else if ( Gia_ObjIsCi(pObj) ) -        { -            pObjLog->fCi = 1; -            Vec_IntPush( p->vCis, iHandle ); -        } -        iHandle += Css_ObjSize( pObjLog ); -        p->nObjs++; -    } -    assert( iHandle == p->nObjData ); -    Gia_ManForEachObj( pGia, pObj, i ) -    { -        pObjLog = Css_ManObj( p, Gia_ObjHandle(pObj) ); -        assert( pObjLog->nFanouts == pObjLog->iFanouts ); -        pObjLog->TravId = 0; -    } -    p->nTravIds = 1; -    p->vTrail = Vec_IntAlloc( 100 ); -    return p; -} - -/**Function************************************************************* - -  Synopsis    [Creates logic network isomorphic to the given AIG.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Css_ManStop( Css_Man_t * p ) -{ -    Vec_IntFree( p->vTrail ); -    Vec_IntFree( p->vCis ); -    Vec_IntFree( p->vCos ); -    ABC_FREE( p->pObjData ); -    ABC_FREE( p->pLevels ); -    ABC_FREE( p ); -} - -/**Function************************************************************* - -  Synopsis    [Propagates implications for the net.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -int Css_ManImplyNet_rec( Css_Man_t * p, Css_Obj_t * pVar, unsigned Value ) -{ -    static inline Css_ManImplyNode_rec( Css_Man_t * p, Css_Obj_t * pVar ); -    Css_Obj_t * pNext; -    int i; -    if ( !Css_ObjIsTravIdCurrent(p, pVar) ) -        return 0; -    // assign the variable -    assert( !Css_VarIsAssigned(pVar) ); -    Css_VarAssign( pVar ); -    Css_VarSetValue( pVar, Value ); -    Vec_IntPush( p->vTrail, pVar->hHandle ); -    // propagate fanouts, then fanins -    Css_ObjForEachFanout( pVar, pNext, i ) -        if ( Css_ManImplyNode_rec( p, pNext ) ) -            return 1; -    Css_ObjForEachFanin( pVar, pNext, i ) -        if ( Css_ManImplyNode_rec( p, pNext ) ) -            return 1; -    return 0; -} -  -/**Function************************************************************* - -  Synopsis    [Propagates implications for the node.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -int Css_ManImplyNode_rec( Css_Man_t * p, Css_Obj_t * pVar ) -{ -    Css_Obj_t * pFan0, * pFan1; -    if ( Css_ObjIsCi(pVar) ) -        return 0; -    pFan0 = Css_ObjFanin(pVar, 0); -    pFan1 = Css_ObjFanin(pVar, 1); -    if ( !Css_VarIsAssigned(pVar) ) -    { -        if ( Css_VarIsAssigned(pFan0) ) -        { -            if ( Css_VarValue(pFan0) == Css_ObjFaninC(pVar,0) ) // negative -> propagate -                return Css_ManImplyNet_rec(p, pVar, 0); -            // assigned positive -            if ( Css_VarIsAssigned(pFan1) ) -            { -                if ( Css_VarValue(pFan1) == Css_ObjFaninC(pVar,1) ) // negative -> propagate -                    return Css_ManImplyNet_rec(p, pVar, 0); -                // asigned positive -> propagate -                return Css_ManImplyNet_rec(p, pVar, 1); -            } -            return 0; -        } -        if ( Css_VarIsAssigned(pFan1) ) -        { -            if ( Css_VarValue(pFan1) == Css_ObjFaninC(pVar,1) ) // negative -> propagate -                return Css_ManImplyNet_rec(p, pVar, 0); -            return 0; -        } -        assert( 0 ); -        return 0; -    } -    if ( Css_VarValue(pVar) ) // positive -    { -        if ( Css_VarIsAssigned(pFan0) ) -        { -            if ( Css_VarValue(pFan0) == Css_ObjFaninC(pVar,0) ) // negative -> conflict -                return 1; -            // check second var -            if ( Css_VarIsAssigned(pFan1) ) -            { -                if ( Css_VarValue(pFan1) == Css_ObjFaninC(pVar,1) ) // negative -> conflict -                    return 1; -                // positive + positive -> nothing to do -                return 0; -            } -        } -        else -        { -            // pFan0 unassigned -> enqueue first var -//            Css_ManEnqueue( p, pFan0, !Css_ObjFaninC(pVar,0) ); -            if ( Css_ManImplyNet_rec( p, pFan0, !Css_ObjFaninC(pVar,0) ) ) -                return 1; -            // check second var -            if ( Css_VarIsAssigned(pFan1) ) -            { -                if ( Css_VarValue(pFan1) == Css_ObjFaninC(pVar,1) ) // negative -> conflict -                    return 1; -                // positive + positive -> nothing to do -                return 0; -            } -        } -        // unassigned -> enqueue second var -//        Css_ManEnqueue( p, pFan1, !Css_ObjFaninC(pVar,1) ); -        return Css_ManImplyNet_rec( p, pFan1, !Css_ObjFaninC(pVar,1) ); -    } -    else // negative -    { -        if ( Css_VarIsAssigned(pFan0) ) -        { -            if ( Css_VarValue(pFan0) == Css_ObjFaninC(pVar,0) ) // negative -> nothing to do -                return 0; -            if ( Css_VarIsAssigned(pFan1) ) -            { -                if ( Css_VarValue(pFan1) == Css_ObjFaninC(pVar,1) ) // negative -> nothing to do -                    return 0; -                // positive + positive -> conflict -                return 1; -            } -            // positive + unassigned -> enqueue second var -//            Css_ManEnqueue( p, pFan1, Css_ObjFaninC(pVar,1) ); -            return Css_ManImplyNet_rec( p, pFan1, Css_ObjFaninC(pVar,1) ); -        } -        else -        { -            if ( Css_VarIsAssigned(pFan1) ) -            { -                if ( Css_VarValue(pFan1) == Css_ObjFaninC(pVar,1) ) // negative -> nothing to do -                    return 0; -                // unassigned + positive -> enqueue first var -//                Css_ManEnqueue( p, pFan0, Css_ObjFaninC(pVar,0) ); -                return Css_ManImplyNet_rec( p, pFan0, Css_ObjFaninC(pVar,0) ); -            } -        } -    } -    return 0; -} - -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -static inline void Css_ManCancelUntil( Css_Man_t * p, int iBound, Vec_Int_t * vCex ) -{ -    Css_Obj_t * pVar; -    int i; -    Css_ManForEachObjVecStart( p->vTrail, p, pVar, i, iBound ) -    { -        if ( vCex )   -            Vec_IntPush( vCex, Gia_Var2Lit(Css_ObjId(pVar), !pVar->fValue) ); -        Css_VarUnassign( pVar ); -    } -    Vec_IntShrink( p->vTrail, iBound ); -} - -/**Function************************************************************* - -  Synopsis    [Justifies assignments.] - -  Description [Returns 1 for UNSAT, 0 for SAT, -1 for UNDECIDED.] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -int Css_ManJustify( Css_Man_t * p, int iBegin ) -{ -    Css_Obj_t * pVar, * pFan0, * pFan1; -    int iState, iThis; -    if ( p->nConfsMax == 0 ) -        return 1; -    // get the next variable to justify -    Css_ManForEachObjVecStart( p->vTrail, p, pVar, iThis, iBegin ) -    { -        assert( Css_VarIsAssigned(pVar) ); -        if ( Css_VarValue(pVar) || Css_ObjIsCi(pVar) ) -            continue; -        pFan0 = Css_ObjFanin(pVar,0); -        pFan1 = Css_ObjFanin(pVar,0); -        if ( !Css_VarIsAssigned(pFan0) && !Css_VarIsAssigned(pFan1) ) -            break; -    } -    if ( iThis == Vec_IntSize(p->vTrail) ) // could not find -        return 0; -    // found variable to justify -    assert( !Css_VarValue(pVar) && !Css_VarIsAssigned(pFan0) && !Css_VarIsAssigned(pFan1) ); -    // remember the state of the stack -    iState = Vec_IntSize( p->vTrail ); -    // try to justify by setting first fanin to 0 -    if ( !Css_ManImplyNet_rec(p, pFan0, 0) && !Css_ManJustify(p, iThis) ) -        return 0; -    Css_ManCancelUntil( p, iState, NULL ); -    if ( p->nConfsMax == 0 ) -        return 1; -    // try to justify by setting second fanin to 0 -    if ( !Css_ManImplyNet_rec(p, pFan1, 0) && !Css_ManJustify(p, iThis) ) -        return 0; -    Css_ManCancelUntil( p, iState, NULL ); -    if ( p->nConfsMax == 0 ) -        return 1; -    p->nConfsMax--; -    return 1; -} - -/**Function************************************************************* - -  Synopsis    [Marsk logic cone.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Css_ManMarkCone_rec( Css_Man_t * p, Css_Obj_t * pVar ) -{ -    if ( Css_ObjIsTravIdCurrent(p, pVar) ) -        return; -    Css_ObjSetTravIdCurrent(p, pVar); -    assert( !Css_VarIsAssigned(pVar) ); -    if ( Css_ObjIsCi(pVar) ) -        return; -    else -    { -        Css_Obj_t * pNext; -        int i; -        Css_ObjForEachFanin( pVar, pNext, i ) -            Css_ManMarkCone_rec( p, pNext ); -    } -} - -/**Function************************************************************* - -  Synopsis    [Runs one call to the SAT solver.] - -  Description [Returns 1 for UNSAT, 0 for SAT, -1 for UNDECIDED.] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -int Css_ManPrepare( Css_Man_t * p, int * pLits, int nLits ) -{ -    Css_Obj_t * pVar; -    int i; -    // mark the cone -    Css_ManIncrementTravId( p ); -    for ( i = 0; i < nLits; i++ ) -    { -        pVar = Css_ManObj( p, Gia_Lit2Var(pLits[i]) ); -        Css_ManMarkCone_rec( p, pVar ); -    } -    // assign literals -    Vec_IntClear( p->vTrail ); -    for ( i = 0; i < nLits; i++ ) -    { -        pVar = Css_ManObj( p, Gia_Lit2Var(pLits[i]) ); -        if ( Css_ManImplyNet_rec( p, pVar, !Gia_LitIsCompl(pLits[i]) ) ) -        { -            Css_ManCancelUntil( p, 0, NULL ); -            return 1; -        } -    } -    return 0; -} -  - -/**Function************************************************************* - -  Synopsis    [Runs one call to the SAT solver.] - -  Description [Returns 1 for UNSAT, 0 for SAT, -1 for UNDECIDED.] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -int Css_ManSolve( Css_Man_t * p, int * pLits, int nLits, int nConfsMax, Vec_Int_t * vCex ) -{ -    // propagate the assignments -    if ( Css_ManPrepare( p, pLits, nLits ) ) -        return 1; -    // justify the assignments -    p->nConfsMax = nConfsMax; -    if ( Css_ManJustify( p, 0 ) ) -        return p->nConfsMax? 1 : -1; -    // derive model and return the solver to the initial state -    Vec_IntClear( vCex ); -    Css_ManCancelUntil( p, 0, vCex ); -    return 0; -} - -/**Function************************************************************* - -  Synopsis    [Procedure to test the new SAT solver.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Gia_SatSolveTest2( Gia_Man_t * pGia ) -{ -    extern void Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, Vec_Int_t * vVisit ); -    int nConfsMax = 1000; -    int CountUnsat, CountSat, CountUndec; -    Css_Man_t * p;  -    Vec_Int_t * vCex; -    Vec_Int_t * vVisit; -    Gia_Obj_t * pRoot;  -    int i, RetValue, iLit, clk = clock(); -    // create logic network -    p = Css_ManCreateLogicSimple( pGia ); -    // prepare AIG -    Gia_ManCleanValue( pGia ); -    Gia_ManCleanMark0( pGia ); -    Gia_ManCleanMark1( pGia ); -    vCex   = Vec_IntAlloc( 100 ); -    vVisit = Vec_IntAlloc( 100 ); -    // solve for each output -    CountUnsat = CountSat = CountUndec = 0; -    Gia_ManForEachCo( pGia, pRoot, i ) -    { -        if ( Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ) -            continue; -//printf( "Output %6d : ", i ); -        iLit = Gia_Var2Lit( Gia_ObjHandle(Gia_ObjFanin0(pRoot)), Gia_ObjFaninC0(pRoot) ); -        RetValue = Css_ManSolve( p, &iLit, 1, nConfsMax, vCex ); -        if ( RetValue == 1 ) -            CountUnsat++; -        else if ( RetValue == -1 ) -            CountUndec++; -        else  -        { -//            Gia_Obj_t * pTemp; -//            int k; -            assert( RetValue == 0 ); -            CountSat++; -/* -            Vec_PtrForEachEntry( vCex, pTemp, k ) -//                printf( "%s%d ", Gia_IsComplement(pTemp)? "!": "", Gia_ObjCioId(Gia_Regular(pTemp)) ); -                printf( "%s%d ", Gia_IsComplement(pTemp)? "!": "", Gia_ObjId(p,Gia_Regular(pTemp)) ); -            printf( "\n" ); -*/ -            Gia_SatVerifyPattern( pGia, pRoot, vCex, vVisit ); -        } -//        Gia_ManCheckMark0( p ); -//        Gia_ManCheckMark1( p ); -    } -    Css_ManStop( p ); -    Vec_IntFree( vCex ); -    Vec_IntFree( vVisit ); -    printf( "Unsat = %d. Sat = %d. Undec = %d.  ", CountUnsat, CountSat, CountUndec ); -    ABC_PRT( "Time", clock() - clk ); -} - - -//////////////////////////////////////////////////////////////////////// -///                       END OF FILE                                /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/gia/giaCSatA.c b/src/aig/gia/giaCSatA.c deleted file mode 100644 index 12f6895a..00000000 --- a/src/aig/gia/giaCSatA.c +++ /dev/null @@ -1,103 +0,0 @@ -/**CFile**************************************************************** - -  FileName    [giaSolver.c] - -  SystemName  [ABC: Logic synthesis and verification system.] - -  PackageName [Scalable AIG package.] - -  Synopsis    [Circuit-based SAT solver.] - -  Author      [Alan Mishchenko] -   -  Affiliation [UC Berkeley] - -  Date        [Ver. 1.0. Started - June 20, 2005.] - -  Revision    [$Id: giaSolver.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" - -//////////////////////////////////////////////////////////////////////// -///                        DECLARATIONS                              /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Sat_Cla_t_ Sat_Cla_t; -struct Sat_Cla_t_ -{ -    unsigned       hWatch0;          // watched list for 0 literal -    unsigned       hWatch1;          // watched list for 1 literal -    int            Activity;         // activity of the clause -    int            nLits;            // the number of literals -    int            pLits[0];         // the array of literals   -}; - -typedef struct Sat_Fan_t_ Sat_Fan_t; -struct Sat_Fan_t_ -{ -    unsigned       iFan      : 31;   // ID of the fanin/fanout -    unsigned       fCompl    :  1;   // complemented attribute -}; - -typedef struct Sat_Obj_t_ Sat_Obj_t; -struct Sat_Obj_t_ -{ -    unsigned       hHandle;          // node handle -    unsigned       fAssign   :  1;   // terminal node (CI/CO) -    unsigned       fValue    :  1;   // value under 000 pattern -    unsigned       fMark0    :  1;   // first user-controlled mark -    unsigned       fMark1    :  1;   // second user-controlled mark -    unsigned       nFanouuts : 28;   // the number of fanouts -    unsigned       nFanins   :  8;   // the number of fanins -    unsigned       Level     : 24;   // logic level -    unsigned       hNext;            // next one on this level  -    unsigned       hWatch0;          // watched list for 0 literal -    unsigned       hWatch1;          // watched list for 1 literal -    unsigned       hReason;          // reason for this variable -    unsigned       Depth;            // decision depth -    Sat_Fan_t      Fanios[0];        // the array of fanins/fanouts -}; - -typedef struct Sat_Man_t_ Sat_Man_t; -struct Sat_Man_t_ -{ -    Gia_Man_t *    pGia;             // the original AIG manager -    // circuit -    Vec_Int_t      vCis;             // the vector of CIs (PIs + LOs) -    Vec_Int_t      vObjs;            // the vector of objects -    // learned clauses          -    Vec_Int_t      vClauses;         // the vector of clauses -    // solver data -    Vec_Int_t      vTrail;           // variable queue                -    Vec_Int_t      vTrailLim;        // pointer into the trail                -    int            iHead;            // variable queue  -    int            iTail;            // variable queue -    int            iRootLevel;       // first decision -    // levelized order -    int            iLevelTop;        // the largest unassigned level  -    Vec_Int_t      vLevels;          // the linked lists of levels -}; - -//////////////////////////////////////////////////////////////////////// -///                     FUNCTION DEFINITIONS                         /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ - -//////////////////////////////////////////////////////////////////////// -///                       END OF FILE                                /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/gia/giaCSatB.c b/src/aig/gia/giaCSatB.c deleted file mode 100644 index e1f68c6f..00000000 --- a/src/aig/gia/giaCSatB.c +++ /dev/null @@ -1,490 +0,0 @@ -/**CFile**************************************************************** - -  FileName    [giaSolver.c] - -  SystemName  [ABC: Logic synthesis and verification system.] - -  PackageName [Scalable AIG package.] - -  Synopsis    [Circuit-based SAT solver.] - -  Author      [Alan Mishchenko] -   -  Affiliation [UC Berkeley] - -  Date        [Ver. 1.0. Started - June 20, 2005.] - -  Revision    [$Id: giaSolver.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "gia.h" - -//////////////////////////////////////////////////////////////////////// -///                        DECLARATIONS                              /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Sat_Man_t_ Sat_Man_t; -struct Sat_Man_t_ -{ -    Gia_Man_t *    pGia;             // the original AIG manager -    Vec_Int_t *    vModel;           // satisfying PI assignment -    int            nConfs;           // cur number of conflicts -    int            nConfsMax;        // max number of conflicts -    int            iHead;            // variable queue  -    int            iTail;            // variable queue -    int            iJust;            // head of justification -    int            nTrail;           // variable queue size -    int            pTrail[0];        // variable queue data -}; - -static inline int          Sat_VarIsAssigned( Gia_Obj_t * pVar )      { return pVar->fMark0;                        } -static inline void         Sat_VarAssign( Gia_Obj_t * pVar )          { assert(!pVar->fMark0); pVar->fMark0 = 1;    } -static inline void         Sat_VarUnassign( Gia_Obj_t * pVar )        { assert(pVar->fMark0);  pVar->fMark0 = 0;    } -static inline int          Sat_VarValue( Gia_Obj_t * pVar )           { assert(pVar->fMark0);  return pVar->fMark1; } -static inline void         Sat_VarSetValue( Gia_Obj_t * pVar, int v ) { assert(pVar->fMark0);  pVar->fMark1 = v;    } - -extern void Cec_ManPatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat ); -extern void Cec_ManPatCleanMark0( Gia_Man_t * p, Gia_Obj_t * pObj ); - -//////////////////////////////////////////////////////////////////////// -///                     FUNCTION DEFINITIONS                         /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -Sat_Man_t * Sat_ManCreate( Gia_Man_t * pGia ) -{ -    Sat_Man_t * p; -    p = (Sat_Man_t *)ABC_ALLOC( char, sizeof(Sat_Man_t) + sizeof(int)*Gia_ManObjNum(pGia) ); -    memset( p, 0, sizeof(Sat_Man_t) ); -    p->pGia   = pGia; -    p->nTrail = Gia_ManObjNum(pGia); -    p->vModel = Vec_IntAlloc( 1000 ); -    return p; -} - -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Sat_ManDelete( Sat_Man_t * p ) -{ -    Vec_IntFree( p->vModel ); -    ABC_FREE( p ); -} - -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -static inline void Sat_ManCancelUntil( Sat_Man_t * p, int iBound ) -{ -    Gia_Obj_t * pVar; -    int i; -    for ( i = p->iTail-1; i >= iBound; i-- ) -    { -        pVar = Gia_ManObj( p->pGia, p->pTrail[i] ); -        Sat_VarUnassign( pVar ); -    } -    p->iTail = p->iTail = iBound; -} - -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -static inline void Sat_ManDeriveModel( Sat_Man_t * p ) -{ -    Gia_Obj_t * pVar; -    int i; -    Vec_IntClear( p->vModel ); -    for ( i = 0; i < p->iTail; i++ ) -    { -        pVar = Gia_ManObj( p->pGia, p->pTrail[i] ); -        if ( Gia_ObjIsCi(pVar) ) -            Vec_IntPush( p->vModel, Gia_ObjCioId(pVar) ); -    } -} - -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -static inline void Sat_ManEnqueue( Sat_Man_t * p, Gia_Obj_t * pVar, int Value ) -{ -    assert( p->iTail < p->nTrail ); -    Sat_VarAssign( pVar ); -    Sat_VarSetValue( pVar, Value ); -    p->pTrail[p->iTail++] = Gia_ObjId(p->pGia, pVar); -} - -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -static inline void Sat_ManAssume( Sat_Man_t * p, Gia_Obj_t * pVar, int Value ) -{ -    assert( p->iHead == p->iTail ); -    Sat_ManEnqueue( p, pVar, Value ); -} - -/**Function************************************************************* - -  Synopsis    [Propagates one assignment.] - -  Description [Returns 1 if there is no conflict, 0 otherwise.] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -static inline int Sat_ManPropagateOne( Sat_Man_t * p, int iPos ) -{ -    Gia_Obj_t * pVar, * pFan0, * pFan1; -    pVar = Gia_ManObj( p->pGia, p->pTrail[iPos] ); -    if ( Gia_ObjIsCi(pVar) ) -        return 1; -    pFan0 = Gia_ObjFanin0(pVar); -    pFan1 = Gia_ObjFanin1(pVar); -    if ( Sat_VarValue(pVar) ) // positive -    { -        if ( Sat_VarIsAssigned(pFan0) ) -        { -            if ( Sat_VarValue(pFan0) == Gia_ObjFaninC0(pVar) ) // negative -> conflict -                return 0; -            // check second var -            if ( Sat_VarIsAssigned(pFan1) ) -            { -                if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> conflict -                    return 0; -                // positive + positive -> nothing to do -                return 1; -            } -        } -        else -        { -            // pFan0 unassigned -> enqueue first var -            Sat_ManEnqueue( p, pFan0, !Gia_ObjFaninC0(pVar) ); -            // check second var -            if ( Sat_VarIsAssigned(pFan1) ) -            { -                if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> conflict -                    return 0; -                // positive + positive -> nothing to do -                return 1; -            } -        } -        // unassigned -> enqueue second var -        Sat_ManEnqueue( p, pFan1, !Gia_ObjFaninC1(pVar) ); -    } -    else // negative -    { -        if ( Sat_VarIsAssigned(pFan0) ) -        { -            if ( Sat_VarValue(pFan0) == Gia_ObjFaninC0(pVar) ) // negative -> nothing to do -                return 1; -            if ( Sat_VarIsAssigned(pFan1) ) -            { -                if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> nothing to do -                    return 1; -                // positive + positive -> conflict -                return 0; -            } -            // positive + unassigned -> enqueue second var -            Sat_ManEnqueue( p, pFan1, Gia_ObjFaninC1(pVar) ); -        } -        else -        { -            if ( Sat_VarIsAssigned(pFan1) ) -            { -                if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> nothing to do -                    return 1; -                // unassigned + positive -> enqueue first var -                Sat_ManEnqueue( p, pFan0, Gia_ObjFaninC0(pVar) ); -            } -        } -    } -    return 1; -} - -/**Function************************************************************* - -  Synopsis    [Propagates assignments.] - -  Description [Returns 1 if there is no conflict.] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -static inline int Sat_ManPropagate( Sat_Man_t * p ) -{ -    assert( p->iHead <= p->iTail ); -    for ( ; p->iHead < p->iTail; p->iHead++ ) -        if ( !Sat_ManPropagateOne( p, p->pTrail[p->iHead] ) ) -            return 0; -    return 1; -} - -/**Function************************************************************* - -  Synopsis    [Propagates one assignment.] - -  Description [Returns 1 if justified, 0 if conflict, -1 if needs justification.] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -static inline int Sat_ManJustifyNextOne( Sat_Man_t * p, int iPos ) -{ -    Gia_Obj_t * pVar, * pFan0, * pFan1; -    pVar = Gia_ManObj( p->pGia, p->pTrail[iPos] ); -    if ( Gia_ObjIsCi(pVar) ) -        return 1; -    pFan0 = Gia_ObjFanin0(pVar); -    pFan1 = Gia_ObjFanin1(pVar); -    if ( Sat_VarValue(pVar) ) // positive -        return 1; -    // nevative -    if ( Sat_VarIsAssigned(pFan0) ) -    { -        if ( Sat_VarValue(pFan0) == Gia_ObjFaninC0(pVar) ) // negative -> already justified -            return 1; -        // positive -        if ( Sat_VarIsAssigned(pFan1) ) -        { -            if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> already justified -                return 1; -            // positive -> conflict -            return 0; -        } -        // unasigned -> propagate -        Sat_ManAssume( p, pFan1, Gia_ObjFaninC1(pVar) ); -        return Sat_ManPropagate(p); -    } -    if ( Sat_VarIsAssigned(pFan1) ) -    { -        if ( Sat_VarValue(pFan1) == Gia_ObjFaninC1(pVar) ) // negative -> already justified -            return 1; -        // positive -        assert( !Sat_VarIsAssigned(pFan0) ); -        // unasigned -> propagate -        Sat_ManAssume( p, pFan0, Gia_ObjFaninC0(pVar) ); -        return Sat_ManPropagate(p); -    } -    return -1; -} - -/**Function************************************************************* - -  Synopsis    [Justifies assignments.] - -  Description [Returns 1 for UNSAT, 0 for SAT, -1 for UNDECIDED.] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -int Sat_ManJustify( Sat_Man_t * p ) -{ -    Gia_Obj_t * pVar, * pFan0, * pFan1; -    int RetValue, iState, iJustState; -    if ( p->nConfs && p->nConfs >= p->nConfsMax ) -        return -1; -    // get the next variable to justify -    assert( p->iJust <= p->iTail ); -    iJustState = p->iJust; -    for ( ; p->iJust < p->iTail; p->iJust++ ) -    { -        RetValue = Sat_ManJustifyNextOne( p, p->pTrail[p->iJust] ); -        if ( RetValue == 0 ) -            return 1; -        if ( RetValue == -1 ) -            break; -    } -    if ( p->iJust == p->iTail ) // could not find -        return 0; -    // found variable to justify -    pVar = Gia_ManObj( p->pGia, p->pTrail[p->iJust] ); -    pFan0 = Gia_ObjFanin0(pVar); -    pFan1 = Gia_ObjFanin1(pVar); -    assert( !Sat_VarValue(pVar) && !Sat_VarIsAssigned(pFan0) && !Sat_VarIsAssigned(pFan1) ); -    // remember the state of the stack -    iState = p->iHead; -    // try to justify by setting first fanin to 0 -    Sat_ManAssume( p, pFan0, Gia_ObjFaninC0(pVar) ); -    if ( Sat_ManPropagate(p) )  -    { -        RetValue = Sat_ManJustify(p); -        if ( RetValue != 1 ) -            return RetValue; -    } -    Sat_ManCancelUntil( p, iState ); -    // try to justify by setting second fanin to 0 -    Sat_ManAssume( p, pFan1, Gia_ObjFaninC1(pVar) ); -    if ( Sat_ManPropagate(p) )  -    { -        RetValue = Sat_ManJustify(p); -        if ( RetValue != 1 ) -            return RetValue; -    } -    Sat_ManCancelUntil( p, iState ); -    p->iJust = iJustState; -    p->nConfs++; -    return 1; -} - -/**Function************************************************************* - -  Synopsis    [Runs one call to the SAT solver.] - -  Description [Returns 1 for UNSAT, 0 for SAT, -1 for UNDECIDED.] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -int Sat_ManPrepare( Sat_Man_t * p, int * pLits, int nLits, int nConfsMax ) -{ -    Gia_Obj_t * pVar; -    int i; -    // double check that vars are unassigned -    Gia_ManForEachObj( p->pGia, pVar, i ) -        assert( !Sat_VarIsAssigned(pVar) ); -    // prepare -    p->iHead = p->iTail = p->iJust = 0; -    p->nConfsMax = nConfsMax; -    // assign literals -    for ( i = 0; i < nLits; i++ ) -    { -        pVar = Gia_ManObj( p->pGia, Gia_Lit2Var(pLits[i]) ); -        if ( Sat_VarIsAssigned(pVar) ) // assigned -        { -            if ( Sat_VarValue(pVar) != Gia_LitIsCompl(pLits[i]) ) // compatible assignment -                continue; -        } -        else // unassigned -        { -            Sat_ManAssume( p, pVar, !Gia_LitIsCompl(pLits[i]) ); -            if ( Sat_ManPropagate(p) )  -                continue; -        } -        // conflict -        Sat_ManCancelUntil( p, 0 ); -        return 1; -    } -    assert( p->iHead == p->iTail ); -    return 0; -} - - -/**Function************************************************************* - -  Synopsis    [Runs one call to the SAT solver.] - -  Description [Returns 1 for UNSAT, 0 for SAT, -1 for UNDECIDED.] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -int Sat_ManSolve( Sat_Man_t * p, int * pLits, int nLits, int nConfsMax ) -{ -    int RetValue; -    // propagate the assignments -    if ( Sat_ManPrepare( p, pLits, nLits, nConfsMax ) ) -        return 1; -    // justify the assignments -    RetValue = Sat_ManJustify( p ); -    if ( RetValue == 0 ) // SAT -        Sat_ManDeriveModel( p ); -    // return the solver to the initial state -    Sat_ManCancelUntil( p, 0 ); -    return RetValue; -} - -/**Function************************************************************* - -  Synopsis    [Testing the SAT solver.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -int Sat_ManTest( Gia_Man_t * pGia, Gia_Obj_t * pObj, int nConfsMax ) -{ -    Sat_Man_t * p; -    int RetValue, iLit; -    assert( Gia_ObjIsCo(pObj) ); -    p = Sat_ManCreate( pGia ); -    iLit = Gia_LitNot( Gia_ObjFaninLit0p(pGia, pObj) ); -    RetValue = Sat_ManSolve( p, &iLit, 1, nConfsMax ); -    if ( RetValue == 0 ) -    { -        Cec_ManPatVerifyPattern( pGia, pObj, p->vModel ); -        Cec_ManPatCleanMark0( pGia, pObj ); -    } -    Sat_ManDelete( p ); -    return RetValue; -} - -//////////////////////////////////////////////////////////////////////// -///                       END OF FILE                                /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/aig/gia/giaCof.c b/src/aig/gia/giaCof.c index c5efa839..b256100c 100644 --- a/src/aig/gia/giaCof.c +++ b/src/aig/gia/giaCof.c @@ -859,7 +859,7 @@ Gia_Man_t * Gia_ManDupCofAllInt( Gia_Man_t * p, Vec_Int_t * vSigs, int fVerbose      if ( fVerbose )      {           printf( "Cofactoring %d signals.\n", Vec_IntSize(vSigs) ); -        Gia_ManPrintStats( p ); +        Gia_ManPrintStats( p, 0 );      }      if ( Vec_IntSize( vSigs ) > 200 )      { @@ -885,7 +885,7 @@ Gia_Man_t * Gia_ManDupCofAllInt( Gia_Man_t * p, Vec_Int_t * vSigs, int fVerbose          if ( fVerbose )              printf( "Cofactored variable %d.\n", iVar );          if ( fVerbose ) -            Gia_ManPrintStats( pAig ); +            Gia_ManPrintStats( pAig, 0 );      }      Vec_IntFree( vSigsNew );      return pAig; diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 0c536dab..2510f572 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -30,6 +30,226 @@  /**Function************************************************************* +  Synopsis    [Removes pointers to the unmarked nodes..] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Gia_ManDupRemapEquiv( Gia_Man_t * pNew, Gia_Man_t * p ) +{ +    Vec_Int_t * vClass; +    int i, k, iNode, iRepr, iPrev; +    if ( p->pReprs == NULL ) +        return; +    assert( pNew->pReprs == NULL && pNew->pNexts == NULL ); +    // start representatives +    pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pNew) ); +    for ( i = 0; i < Gia_ManObjNum(pNew); i++ ) +        Gia_ObjSetRepr( pNew, i, GIA_VOID ); +    // iterate over constant candidates +    Gia_ManForEachConst( p, i ) +        Gia_ObjSetRepr( pNew, Gia_Lit2Var(Gia_ManObj(p, i)->Value), 0 ); +    // iterate over class candidates +    vClass = Vec_IntAlloc( 100 ); +    Gia_ManForEachClass( p, i ) +    { +        Vec_IntClear( vClass ); +        Gia_ClassForEachObj( p, i, k ) +            Vec_IntPushUnique( vClass, Gia_Lit2Var(Gia_ManObj(p, k)->Value) ); +        assert( Vec_IntSize( vClass ) > 1 ); +        Vec_IntSort( vClass, 0 ); +        iRepr = iPrev = Vec_IntEntry( vClass, 0 ); +        Vec_IntForEachEntryStart( vClass, iNode, k, 1 ) +        { +            Gia_ObjSetRepr( pNew, iNode, iRepr ); +            assert( iPrev < iNode ); +            iPrev = iNode; +        } +    } +    Vec_IntFree( vClass ); +    pNew->pNexts = Gia_ManDeriveNexts( pNew ); +} + +/**Function************************************************************* + +  Synopsis    [Remaps combinational inputs when objects are DFS ordered.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Gia_ManDupRemapCis( Gia_Man_t * pNew, Gia_Man_t * p ) +{ +    Gia_Obj_t * pObj, * pObjNew; +    int i; +    assert( Vec_IntSize(p->vCis) == Vec_IntSize(pNew->vCis) ); +    Gia_ManForEachCi( p, pObj, i ) +    { +        assert( Gia_ObjCioId(pObj) == i ); +        pObjNew = Gia_ObjFromLit( pNew, pObj->Value ); +        assert( !Gia_IsComplement(pObjNew) ); +        Vec_IntWriteEntry( pNew->vCis, i, Gia_ObjId(pNew, pObjNew) ); +        Gia_ObjSetCioId( pObjNew, i ); +    } +} + +/**Function************************************************************* + +  Synopsis    [Remaps combinational outputs when objects are DFS ordered.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Gia_ManDupRemapCos( Gia_Man_t * pNew, Gia_Man_t * p ) +{ +    Gia_Obj_t * pObj, * pObjNew; +    int i; +    assert( Vec_IntSize(p->vCos) == Vec_IntSize(pNew->vCos) ); +    Gia_ManForEachCo( p, pObj, i ) +    { +        assert( Gia_ObjCioId(pObj) == i ); +        pObjNew = Gia_ObjFromLit( pNew, pObj->Value ); +        assert( !Gia_IsComplement(pObjNew) ); +        Vec_IntWriteEntry( pNew->vCos, i, Gia_ObjId(pNew, pObjNew) ); +        Gia_ObjSetCioId( pObjNew, i ); +    } +} + +/**Function************************************************************* + +  Synopsis    [Duplicates the AIG in the DFS order.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Gia_ManDupOrderDfs_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ +    if ( ~pObj->Value ) +        return pObj->Value; +    if ( Gia_ObjIsCi(pObj) ) +        return pObj->Value = Gia_ManAppendCi(pNew); +    Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin0(pObj) ); +    if ( Gia_ObjIsCo(pObj) ) +        return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); +    Gia_ManDupOrderDfs_rec( pNew, p, Gia_ObjFanin1(pObj) ); +    return pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +}  + +/**Function************************************************************* + +  Synopsis    [Duplicates AIG while putting objects in the DFS order.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupOrderDfs( 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 = Aig_UtilStrsav( p->pName ); +    Gia_ManConst0(p)->Value = 0; +    Gia_ManForEachCo( p, pObj, i ) +        Gia_ManDupOrderDfs_rec( pNew, p, pObj ); +    Gia_ManForEachCi( p, pObj, i ) +        if ( !~pObj->Value ) +            pObj->Value = Gia_ManAppendCi(pNew); +    assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) ); +    Gia_ManDupRemapCis( pNew, p ); +    Gia_ManDupRemapEquiv( pNew, p ); +    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); +    return pNew; +} + +/**Function************************************************************* + +  Synopsis    [Duplicates AIG while putting objects in the DFS order.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupOrderDfsReverse( 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 = Aig_UtilStrsav( p->pName ); +    Gia_ManConst0(p)->Value = 0; +    Gia_ManForEachCoReverse( p, pObj, i ) +        Gia_ManDupOrderDfs_rec( pNew, p, pObj ); +    Gia_ManForEachCi( p, pObj, i ) +        if ( !~pObj->Value ) +            pObj->Value = Gia_ManAppendCi(pNew); +    assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) ); +    Gia_ManDupRemapCis( pNew, p ); +    Gia_ManDupRemapCos( pNew, p ); +    Gia_ManDupRemapEquiv( pNew, p ); +    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); +    return pNew; +} + +/**Function************************************************************* + +  Synopsis    [Duplicates AIG while putting first PIs, then nodes, then POs.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupOrderAiger( Gia_Man_t * p ) +{ +    Gia_Man_t * pNew; +    Gia_Obj_t * pObj; +    int i; +    pNew = Gia_ManStart( Gia_ManObjNum(p) ); +    pNew->pName = Aig_UtilStrsav( p->pName ); +    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_ManDupRemapEquiv( pNew, p ); +    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); +    assert( Gia_ManIsNormalized(pNew) ); +    return pNew; +} + + + +/**Function************************************************************* +    Synopsis    [Duplicates AIG without any changes.]    Description [] @@ -296,7 +516,7 @@ int Gia_ManDupDfs2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )      if ( pNew->pHTable )          return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );      return pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); -} +}   /**Function************************************************************* diff --git a/src/aig/gia/giaEmbed.c b/src/aig/gia/giaEmbed.c index 6c2f00df..fa172f70 100644 --- a/src/aig/gia/giaEmbed.c +++ b/src/aig/gia/giaEmbed.c @@ -36,6 +36,8 @@  ///                        DECLARATIONS                              ///  //////////////////////////////////////////////////////////////////////// +#define GIA_PLACE_SIZE 0x7fff  +// objects will be placed in box [0, GIA_PLACE_SIZE] x [0, GIA_PLACE_SIZE]  typedef float  Emb_Dat_t; @@ -247,6 +249,7 @@ Emb_Man_t * Emb_ManStartSimple( Gia_Man_t * pGia )          Emb_ObjAddFanin( Emb_ManObj(p,Gia_ObjValue(pObjRo)), Emb_ManObj(p,Gia_ObjValue(pObjRi)) );      assert( nNodes  == Emb_ManNodeNum(p) );      assert( hHandle == p->nObjData ); +    assert( p->nObjs == Gia_ManObjNum(pGia) );      if ( hHandle != p->nObjData )          printf( "Emb_ManStartSimple(): Fatal error in internal representation.\n" );      // make sure the fanin/fanout counters are correct @@ -1407,7 +1410,7 @@ void Emb_ManComputeSolutions( Emb_Man_t * p, int nDims, int nSols )  /**Function************************************************************* -  Synopsis    [Projects into square of size [0;0xffff] x [0;0xffff].] +  Synopsis    [Projects into square of size [0;GIA_PLACE_SIZE] x [0;GIA_PLACE_SIZE].]    Description [] @@ -1432,7 +1435,7 @@ void Emb_ManDerivePlacement( Emb_Man_t * p, int nSols )          Min0 = ABC_MIN( Min0, pY0[k] );          Max0 = ABC_MAX( Max0, pY0[k] );      } -    Str0 = 1.0*0xffff/(Max0 - Min0); +    Str0 = 1.0*GIA_PLACE_SIZE/(Max0 - Min0);      // update the coordinates      for ( k = 0; k < p->nObjs; k++ )          pY0[k] = (pY0[k] != 0.0) ? ((pY0[k] - Min0) * Str0) : 0.0; @@ -1446,7 +1449,7 @@ void Emb_ManDerivePlacement( Emb_Man_t * p, int nSols )          Min1 = ABC_MIN( Min1, pY1[k] );          Max1 = ABC_MAX( Max1, pY1[k] );      } -    Str1 = 1.0*0xffff/(Max1 - Min1); +    Str1 = 1.0*GIA_PLACE_SIZE/(Max1 - Min1);      // update the coordinates      for ( k = 0; k < p->nObjs; k++ )          pY1[k] = (pY1[k] != 0.0) ? ((pY1[k] - Min1) * Str1) : 0.0; @@ -1455,12 +1458,12 @@ void Emb_ManDerivePlacement( Emb_Man_t * p, int nSols )      pPerm0 = Gia_SortFloats( pY0, NULL, p->nObjs );      pPerm1 = Gia_SortFloats( pY1, NULL, p->nObjs ); -    // average solutions and project them into square [0;0xffff] x [0;0xffff] +    // average solutions and project them into square [0;GIA_PLACE_SIZE] x [0;GIA_PLACE_SIZE]      p->pPlacement = ABC_ALLOC( unsigned short, 2 * p->nObjs );      for ( k = 0; k < p->nObjs; k++ )      { -        p->pPlacement[2*pPerm0[k]+0] = (unsigned short)(int)(1.0 * k * 0xffff / p->nObjs); -        p->pPlacement[2*pPerm1[k]+1] = (unsigned short)(int)(1.0 * k * 0xffff / p->nObjs); +        p->pPlacement[2*pPerm0[k]+0] = (unsigned short)(int)(1.0 * k * GIA_PLACE_SIZE / p->nObjs); +        p->pPlacement[2*pPerm1[k]+1] = (unsigned short)(int)(1.0 * k * GIA_PLACE_SIZE / p->nObjs);      }      ABC_FREE( pPerm0 );      ABC_FREE( pPerm1 ); @@ -1568,8 +1571,8 @@ void Emb_ManPlacementRefine( Emb_Man_t * p, int nIters, int fVerbose )          pPermY = Gia_SortFloats( pVertY, NULL, p->nObjs );          for ( k = 0; k < p->nObjs; k++ )          { -            p->pPlacement[2*pPermX[k]+0] = (unsigned short)(int)(1.0 * k * 0xffff / p->nObjs); -            p->pPlacement[2*pPermY[k]+1] = (unsigned short)(int)(1.0 * k * 0xffff / p->nObjs); +            p->pPlacement[2*pPermX[k]+0] = (unsigned short)(int)(1.0 * k * GIA_PLACE_SIZE / p->nObjs); +            p->pPlacement[2*pPermY[k]+1] = (unsigned short)(int)(1.0 * k * GIA_PLACE_SIZE / p->nObjs);          }          ABC_FREE( pPermX );          ABC_FREE( pPermY ); @@ -1783,7 +1786,7 @@ void Emb_ManDumpGnuplot( Emb_Man_t * p, char * pName, int fDumpLarge, int fShowI  void Gia_ManSolveProblem( Gia_Man_t * pGia, Emb_Par_t * pPars )  {      Emb_Man_t * p; -    int clk, clkSetup; +    int i, clk, clkSetup;  //   Gia_ManTestDistance( pGia );      // transform AIG into internal data-structure @@ -1843,6 +1846,17 @@ if ( pPars->fVerbose )  ABC_PRT( "Image dump", clock() - clk );      } +    // transfer placement +    if ( Gia_ManObjNum(pGia) == p->nObjs ) +    { +        // assuming normalized ordering of the AIG +        pGia->pPlacement = ABC_CALLOC( Gia_Plc_t, p->nObjs ); +        for ( i = 0; i < p->nObjs; i++ )  +        { +            pGia->pPlacement[i].xCoord = p->pPlacement[2*i+0]; +            pGia->pPlacement[i].yCoord = p->pPlacement[2*i+1]; +        } +    }      Emb_ManStop( p );  } diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index b87c77e5..79345fd0 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -226,6 +226,10 @@ void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem )      assert( Gia_ManEquivCheckLits( p, nLits ) );      if ( fVerbose )      { +        printf( "Const0 = " ); +        Gia_ManForEachConst( p, i ) +            printf( "%d ", i ); +        printf( "\n" );          Counter = 0;          Gia_ManForEachClass( p, i )              Gia_ManEquivPrintOne( p, i, ++Counter ); @@ -275,15 +279,15 @@ static inline Gia_Obj_t * Gia_ManEquivRepr( Gia_Man_t * p, Gia_Obj_t * pObj, int  void Gia_ManEquivReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int fUseAll, int fDualOut )  {      Gia_Obj_t * pRepr; -    if ( ~pObj->Value ) -        return; -    assert( Gia_ObjIsAnd(pObj) );      if ( (pRepr = Gia_ManEquivRepr(p, pObj, fUseAll, fDualOut)) )      {          Gia_ManEquivReduce_rec( pNew, p, pRepr, fUseAll, fDualOut );          pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) );          return;      } +    if ( ~pObj->Value ) +        return; +    assert( Gia_ObjIsAnd(pObj) );      Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin0(pObj), fUseAll, fDualOut );      Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin1(pObj), fUseAll, fDualOut );      pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); @@ -303,18 +307,25 @@ void Gia_ManEquivReduce_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj,  Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fVerbose )  {      Gia_Man_t * pNew; -    Gia_Obj_t * pObj, * pRepr; +    Gia_Obj_t * pObj;      int i; +    if ( !p->pReprs ) +    { +        printf( "Gia_ManEquivReduce(): Equivalence classes are not available.\n" ); +        return NULL; +    }      if ( fDualOut && (Gia_ManPoNum(p) & 1) )      {          printf( "Gia_ManEquivReduce(): Dual-output miter should have even number of POs.\n" );          return NULL;      } +/*      if ( !Gia_ManCheckTopoOrder( p ) )      {          printf( "Gia_ManEquivReduce(): AIG is not in a correct topological order.\n" );          return NULL;      } +*/      Gia_ManSetPhase( p );      if ( fDualOut )          Gia_ManEquivSetColors( p, fVerbose ); @@ -323,11 +334,7 @@ Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fV      Gia_ManFillValue( p );      Gia_ManConst0(p)->Value = 0;      Gia_ManForEachCi( p, pObj, i ) -    {          pObj->Value = Gia_ManAppendCi(pNew); -        if ( (pRepr = Gia_ManEquivRepr(p, pObj, fUseAll, fDualOut)) ) -            pObj->Value = Gia_LitNotCond( pRepr->Value, Gia_ObjPhaseReal(pRepr) ^ Gia_ObjPhaseReal(pObj) ); -    }      Gia_ManHashAlloc( pNew );      Gia_ManForEachCo( p, pObj, i )          Gia_ManEquivReduce_rec( pNew, p, Gia_ObjFanin0(pObj), fUseAll, fDualOut ); @@ -662,11 +669,13 @@ Gia_Man_t * Gia_ManSpecReduce( Gia_Man_t * p, int fDualOut, int fVerbose )          printf( "Gia_ManSpecReduce(): Dual-output miter should have even number of POs.\n" );          return NULL;      } +/*      if ( !Gia_ManCheckTopoOrder( p ) )      {          printf( "Gia_ManSpecReduce(): AIG is not in a correct topological order.\n" );          return NULL;      } +*/      vXorLits = Vec_IntAlloc( 1000 );      Gia_ManSetPhase( p );      Gia_ManFillValue( p ); @@ -786,11 +795,13 @@ Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Gia_Cex_t * pInit, int nFrames          printf( "Gia_ManSpecReduceInit(): Dual-output miter should have even number of POs.\n" );          return NULL;      } +/*      if ( !Gia_ManCheckTopoOrder( p ) )      {          printf( "Gia_ManSpecReduceInit(): AIG is not in a correct topological order.\n" );          return NULL;      } +*/      assert( pInit->nRegs == Gia_ManRegNum(p) && pInit->nPis == 0 );      p->pCopies = ABC_FALLOC( int, nFrames * Gia_ManObjNum(p) );      vXorLits = Vec_IntAlloc( 1000 ); diff --git a/src/aig/gia/giaHash.c b/src/aig/gia/giaHash.c index 8bc38ed9..a7cae8fe 100644 --- a/src/aig/gia/giaHash.c +++ b/src/aig/gia/giaHash.c @@ -86,7 +86,7 @@ static inline int * Gia_ManHashFind( Gia_Man_t * p, int iLit0, int iLit1 )  void Gia_ManHashAlloc( Gia_Man_t * p )    {      assert( p->pHTable == NULL ); -    p->nHTable = Aig_PrimeCudd( p->nObjsAlloc / 3 ); +    p->nHTable = Aig_PrimeCudd( p->nObjsAlloc );      p->pHTable = ABC_CALLOC( int, p->nHTable );  } @@ -174,6 +174,34 @@ void Gia_ManHashResize( Gia_Man_t * p )      ABC_FREE( pHTableOld );  } +/**Function******************************************************************** + +  Synopsis    [Profiles the hash table.] + +  Description [] + +  SideEffects [] + +  SeeAlso     [] + +******************************************************************************/ +void Gia_ManHashProfile( Gia_Man_t * p ) +{ +    Gia_Obj_t * pEntry; +    int i, Counter; +    printf( "Table size = %d. Entries = %d.\n", p->nHTable, Gia_ManAndNum(p) ); +    for ( i = 0; i < p->nHTable; i++ ) +    { +        Counter = 0; +        for ( pEntry = (p->pHTable[i]? Gia_ManObj(p, Gia_Lit2Var(p->pHTable[i])) : NULL);  +              pEntry;  +              pEntry = (pEntry->Value? Gia_ManObj(p, Gia_Lit2Var(pEntry->Value)) : NULL) ) +            Counter++; +        if ( Counter )  +            printf( "%d ", Counter ); +    } +    printf( "\n" ); +}  /**Function************************************************************* diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index 4439453d..dba90507 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -70,6 +70,8 @@ void Gia_ManStop( Gia_Man_t * p )      Vec_IntFree( p->vFlopClasses );      Vec_IntFree( p->vCis );      Vec_IntFree( p->vCos ); +    ABC_FREE( p->pPlacement ); +    ABC_FREE( p->pSwitching );      ABC_FREE( p->pCexComb );      ABC_FREE( p->pIso );      ABC_FREE( p->pMapping ); @@ -128,17 +130,48 @@ void Gia_ManPrintClasses( Gia_Man_t * p )    SeeAlso     []  ***********************************************************************/ -void Gia_ManPrintStats( Gia_Man_t * p ) +void Gia_ManPrintPlacement( Gia_Man_t * p ) +{ +    int i, nFixed = 0, nUndef = 0; +    if ( p->pPlacement == NULL ) +        return; +    for ( i = 0; i < Gia_ManObjNum(p); i++ ) +    { +        nFixed += p->pPlacement[i].fFixed; +        nUndef += p->pPlacement[i].fUndef; +    } +    printf( "Placement:  Objects = %8d.  Fixed = %8d.  Undef = %8d.\n", Gia_ManObjNum(p), nFixed, nUndef ); +} + +/**Function************************************************************* + +  Synopsis    [Prints stats for the AIG.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Gia_ManPrintStats( Gia_Man_t * p, int fSwitch )  {      if ( p->pName )          printf( "%8s : ", p->pName ); -    printf( "i/o =%7d/%7d  ", Gia_ManPiNum(p), Gia_ManPoNum(p) ); +    printf( "i/o =%7d/%7d", Gia_ManPiNum(p), Gia_ManPoNum(p) );      if ( Gia_ManRegNum(p) ) -        printf( "ff =%7d  ", Gia_ManRegNum(p) ); -    printf( "and =%8d  ", Gia_ManAndNum(p) ); -    printf( "lev =%5d  ", Gia_ManLevelNum(p) ); -    printf( "cut =%5d  ", Gia_ManCrossCut(p) ); -    printf( "mem =%5.2f Mb", 12.0*Gia_ManObjNum(p)/(1<<20) ); +        printf( "  ff =%7d", Gia_ManRegNum(p) ); +    printf( "  and =%8d", Gia_ManAndNum(p) ); +    printf( "  lev =%5d", Gia_ManLevelNum(p) ); +    printf( "  cut =%5d", Gia_ManCrossCut(p) ); +    printf( "  mem =%5.2f Mb", 12.0*Gia_ManObjNum(p)/(1<<20) ); +    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" ); @@ -147,6 +180,8 @@ void Gia_ManPrintStats( Gia_Man_t * p )          Gia_ManEquivPrintClasses( p, 0, 0.0 );      if ( p->pMapping )          Gia_ManPrintMappingStats( p ); +    if ( p->pPlacement ) +        Gia_ManPrintPlacement( p );      // print register classes  //    Gia_ManPrintClasses( p );  } diff --git a/src/aig/gia/giaPat.c b/src/aig/gia/giaPat.c new file mode 100644 index 00000000..7968932c --- /dev/null +++ b/src/aig/gia/giaPat.c @@ -0,0 +1,129 @@ +/**CFile**************************************************************** + +  FileName    [gia.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Scalable AIG package.] + +  Synopsis    [] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +static inline int   Sat_ObjXValue( Gia_Obj_t * pObj )          { return (pObj->fMark1 << 1) | pObj->fMark0;             } +static inline void  Sat_ObjSetXValue( Gia_Obj_t * pObj, int v) { pObj->fMark0 = (v & 1); pObj->fMark1 = ((v >> 1) & 1); } + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Collects nodes in the cone and initialized them to x.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Gia_SatCollectCone_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vVisit ) +{ +    if ( Sat_ObjXValue(pObj) == GIA_UND ) +        return; +    if ( Gia_ObjIsAnd(pObj) ) +    { +        Gia_SatCollectCone_rec( p, Gia_ObjFanin0(pObj), vVisit ); +        Gia_SatCollectCone_rec( p, Gia_ObjFanin1(pObj), vVisit ); +    } +    assert( Sat_ObjXValue(pObj) == 0 ); +    Sat_ObjSetXValue( pObj, GIA_UND ); +    Vec_IntPush( vVisit, Gia_ObjId(p, pObj) ); +} + +/**Function************************************************************* + +  Synopsis    [Collects nodes in the cone and initialized them to x.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Gia_SatCollectCone( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vVisit ) +{ +    assert( !Gia_IsComplement(pObj) ); +    assert( !Gia_ObjIsConst0(pObj) ); +    assert( Sat_ObjXValue(pObj) == 0 ); +    Vec_IntClear( vVisit ); +    Gia_SatCollectCone_rec( p, pObj, vVisit ); +} + +/**Function************************************************************* + +  Synopsis    [Checks if the counter-examples asserts the output.] + +  Description [Assumes that fMark0 and fMark1 are clean. Leaves them clean.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, Vec_Int_t * vVisit ) +{ +    Gia_Obj_t * pObj; +    int i, Entry, Value, Value0, Value1; +    assert( Gia_ObjIsCo(pRoot) ); +    assert( !Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ); +    // collect nodes and initialized them to x +    Gia_SatCollectCone( p, Gia_ObjFanin0(pRoot), vVisit ); +    // set binary values to nodes in the counter-example +    Vec_IntForEachEntry( vCex, Entry, i ) +//        Sat_ObjSetXValue( Gia_ManObj(p, Gia_Lit2Var(Entry)), Gia_LitIsCompl(Entry)? GIA_ZER : GIA_ONE ); +        Sat_ObjSetXValue( Gia_ManCi(p, Gia_Lit2Var(Entry)), Gia_LitIsCompl(Entry)? GIA_ZER : GIA_ONE ); +    // simulate +    Gia_ManForEachObjVec( vVisit, p, pObj, i ) +    { +        if ( Gia_ObjIsCi(pObj) ) +            continue; +        assert( Gia_ObjIsAnd(pObj) ); +        Value0 = Sat_ObjXValue( Gia_ObjFanin0(pObj) ); +        Value1 = Sat_ObjXValue( Gia_ObjFanin1(pObj) ); +        Value = Gia_XsimAndCond( Value0, Gia_ObjFaninC0(pObj), Value1, Gia_ObjFaninC1(pObj) ); +        Sat_ObjSetXValue( pObj, Value ); +    } +    Value = Gia_XsimNotCond( Value, Gia_ObjFaninC0(pRoot) ); +    if ( Value != GIA_ONE ) +        printf( "Gia_SatVerifyPattern(): Verification FAILED.\n" ); +//    else +//        printf( "Gia_SatVerifyPattern(): Verification succeeded.\n" ); +//    assert( Value == GIA_ONE ); +    // clean the nodes +    Gia_ManForEachObjVec( vVisit, p, pObj, i ) +        Sat_ObjSetXValue( pObj, 0 ); +} + + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/gia/giaSwitch.c b/src/aig/gia/giaSwitch.c index 71aefec3..713f224b 100644 --- a/src/aig/gia/giaSwitch.c +++ b/src/aig/gia/giaSwitch.c @@ -73,13 +73,13 @@ static inline unsigned * Gia_SwiDataCo( Gia_ManSwi_t * p, int i )  { return p->p  void Gia_ManSetDefaultParamsSwi( Gia_ParSwi_t * p )  {      memset( p, 0, sizeof(Gia_ParSwi_t) ); -    p->nWords        =   1;  // the number of machine words of simulatation data  +    p->nWords        =  10;  // the number of machine words of simulatation data       p->nIters        =  48;  // the number of all timeframes to simulate      p->nPref         =  16;  // the number of first timeframes to skip when computing switching      p->nRandPiFactor =   2;  // primary input transition probability (-1=3/8; 0=1/2; 1=1/4; 2=1/8, etc)      p->fProbOne      =   0;  // compute probability of signal being one (if 0, compute probability of switching)      p->fProbTrans    =   1;  // compute signal transition probability (if 0, compute transition probability using probability of being one) -    p->fVerbose      =   1;  // enables verbose output +    p->fVerbose      =   0;  // enables verbose output  }  /**Function************************************************************* @@ -483,12 +483,14 @@ static inline void Gia_ManSwiSimulateRound( Gia_ManSwi_t * p, int fCount )          else if ( Gia_ObjIsCo(pObj) )          {              assert( Gia_ObjValue(pObj) == GIA_NONE ); -            Gia_ManSwiSimulateCo( p, iCos++, pObj ); +//            Gia_ManSwiSimulateCo( p, iCos++, pObj ); +            Gia_ManSwiSimulateCo( p, Gia_ObjCioId(pObj), pObj );          }          else // if ( Gia_ObjIsCi(pObj) )          {              assert( Gia_ObjValue(pObj) < p->pAig->nFront ); -            Gia_ManSwiSimulateCi( p, pObj, iCis++ ); +//            Gia_ManSwiSimulateCi( p, pObj, iCis++ ); +            Gia_ManSwiSimulateCi( p, pObj, Gia_ObjCioId(pObj) );          }          if ( fCount && !Gia_ObjIsCo(pObj) )          { @@ -498,8 +500,8 @@ static inline void Gia_ManSwiSimulateRound( Gia_ManSwi_t * p, int fCount )                  p->pData1[i] += Gia_ManSwiSimInfoCountOnes( p, Gia_ObjValue(pObj) );          }      } -    assert( Gia_ManCiNum(p->pAig) == iCis ); -    assert( Gia_ManCoNum(p->pAig) == iCos ); +//    assert( Gia_ManCiNum(p->pAig) == iCis ); +//    assert( Gia_ManCoNum(p->pAig) == iCos );  }  /**Function************************************************************* @@ -633,12 +635,10 @@ Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * pAig, int nFrames, int nPref      // set the default parameters      Gia_ManSetDefaultParamsSwi( pPars );       // override some of the defaults -    pPars->nWords   = 10;       // set number machine words to simulate      pPars->nIters   = nFrames;  // set number of total timeframes      if ( Abc_FrameReadFlag("seqsimframes") )          pPars->nIters = atoi( Abc_FrameReadFlag("seqsimframes") );      pPars->nPref    = nPref;    // set number of first timeframes to skip   -    pPars->fVerbose = 0;        // disable verbose output      // decide what should be computed      if ( fProbOne )      { @@ -666,7 +666,94 @@ Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * pAig, int nFrames, int nPref      return vResult;  } -  //////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + +  Synopsis    [Computes probability of switching (or of being 1).] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +float Gia_ManEvaluateSwitching( Gia_Man_t * p ) +{ +    Gia_Obj_t * pObj; +    float SwitchTotal = 0.0; +    int i; +    assert( p->pSwitching ); +    ABC_FREE( p->pRefs ); +    Gia_ManCreateRefs( p ); +    Gia_ManForEachObj( p, pObj, i ) +        SwitchTotal += (float)Gia_ObjRefs(p, pObj) * p->pSwitching[i] / 255; +    return SwitchTotal; +} + +/**Function************************************************************* + +  Synopsis    [Computes probability of switching (or of being 1).] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +float Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbOne ) +{ +    Gia_Man_t * pDfs; +    Gia_Obj_t * pObj, * pObjDfs; +    Vec_Int_t * vSwitching; +    float * pSwitching, Switch, SwitchTotal = 0.0, SwitchTotal2 = 0.0; +    int i; +    Gia_ParSwi_t Pars, * pPars = &Pars; +    ABC_FREE( p->pSwitching ); +    // set the default parameters +    Gia_ManSetDefaultParamsSwi( pPars );  +    // override some of the defaults +    pPars->nIters   = nFrames;  // set number of total timeframes +    pPars->nPref    = nPref;    // set number of first timeframes to skip   +    // decide what should be computed +    if ( fProbOne ) +    { +        // if the user asked to compute propability of 1, we do not need transition information +        pPars->fProbOne   = 1;  // enable computing probabiblity of being one +        pPars->fProbTrans = 0;  // disable computing transition probability  +    } +    else +    { +        // if the user asked for transition propabability, we do not need to compute probability of 1 +        pPars->fProbOne   = 0;  // disable computing probabiblity of being one +        pPars->fProbTrans = 1;  // enable computing transition probability  +    } +    // derives the DFS ordered AIG +    Gia_ManCreateRefs( p ); +//    pDfs = Gia_ManDupOrderDfs( p ); +    pDfs = Gia_ManDup( p ); +    assert( Gia_ManObjNum(pDfs) == Gia_ManObjNum(p) ); +    // perform the computation of switching activity +    vSwitching = Gia_ManSwiSimulate( pDfs, pPars ); +    // transfer the computed result to the original AIG +    p->pSwitching = ABC_CALLOC( unsigned char, Gia_ManObjNum(p) ); +    pSwitching = (float *)vSwitching->pArray; +    Gia_ManForEachObj( p, pObj, i ) +    { +        pObjDfs = Gia_ObjFromLit( pDfs, pObj->Value ); +        Switch = pSwitching[ Gia_ObjId(pDfs, pObjDfs) ]; +        p->pSwitching[i] = (char)((Switch >= 1.0) ? 255 : (int)((0.002 + Switch) * 255)); // 0.00196 = (1/255)/2 +        SwitchTotal += (float)Gia_ObjRefs(p, pObj) * p->pSwitching[i] / 255; +//        SwitchTotal2 += Gia_ObjRefs(p, pObj) * Switch; +//        printf( "%d = %.2f\n", i, Gia_ObjRefs(p, pObj) * Switch ); +    } +//    printf( "\nSwitch float = %f. Switch char = %f.\n", SwitchTotal2, SwitchTotal ); +    Vec_IntFree( vSwitching ); +    Gia_ManStop( pDfs ); +    return SwitchTotal; +} + +////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                ///  //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index d5ff628a..055d7580 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -2,6 +2,7 @@ SRC +=    src/aig/gia/gia.c \      src/aig/gia/giaAig.c \      src/aig/gia/giaAiger.c \      src/aig/gia/giaCof.c \ +    src/aig/gia/giaCSat.c \      src/aig/gia/giaDfs.c \      src/aig/gia/giaDup.c \      src/aig/gia/giaEmbed.c \ @@ -15,6 +16,7 @@ SRC +=    src/aig/gia/gia.c \      src/aig/gia/giaHash.c \      src/aig/gia/giaMan.c \      src/aig/gia/giaMap.c \ +    src/aig/gia/giaPat.c \      src/aig/gia/giaRetime.c \      src/aig/gia/giaScl.c \      src/aig/gia/giaSim.c \ diff --git a/src/aig/int/intCtrex.c b/src/aig/int/intCtrex.c index 98c01de6..c0bbec1c 100644 --- a/src/aig/int/intCtrex.c +++ b/src/aig/int/intCtrex.c @@ -111,6 +111,8 @@ void * Inter_ManGetCounterExample( Aig_Man_t * pAig, int nFrames, int fVerbose )      Cnf_DataFree( pCnf );      if ( pSat == NULL )      { +        printf( "Counter-example generation in command \"int\" has failed.\n" ); +        printf( "Use command \"bmc2\" to produce a valid counter-example.\n" );          Vec_IntFree( vCiIds );          return NULL;      } diff --git a/src/aig/ssw/sswClass.c b/src/aig/ssw/sswClass.c index 5d0be217..967d29e9 100644 --- a/src/aig/ssw/sswClass.c +++ b/src/aig/ssw/sswClass.c @@ -391,7 +391,8 @@ void Ssw_ClassesPrintOne( Ssw_Cla_t * p, Aig_Obj_t * pRepr )      int i;      printf( "{ " );      Ssw_ClassForEachNode( p, pRepr, pObj, i ) -        printf( "%d(%d,%d) ", pObj->Id, pObj->Level, Aig_SupportSize(p->pAig,pObj) ); +        printf( "%d(%d,%d,%d) ", pObj->Id, pObj->Level,  +        Aig_SupportSize(p->pAig,pObj), Aig_NodeMffsSupp(p->pAig,pObj,0,NULL) );      printf( "}\n" );  } @@ -418,7 +419,8 @@ void Ssw_ClassesPrint( Ssw_Cla_t * p, int fVeryVerbose )      printf( "Constants { " );      Aig_ManForEachObj( p->pAig, pObj, i )          if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) ) -            printf( "%d(%d,%d) ", pObj->Id, pObj->Level, Aig_SupportSize(p->pAig,pObj) ); +            printf( "%d(%d,%d,%d) ", pObj->Id, pObj->Level,  +            Aig_SupportSize(p->pAig,pObj), Aig_NodeMffsSupp(p->pAig,pObj,0,NULL) );      printf( "}\n" );      Ssw_ManForEachClass( p, ppClass, i )      { diff --git a/src/aig/ssw/sswCore.c b/src/aig/ssw/sswCore.c index 03df38e1..9a31a056 100644 --- a/src/aig/ssw/sswCore.c +++ b/src/aig/ssw/sswCore.c @@ -216,6 +216,7 @@ clk = clock();  p->timeTotal = clock() - clkTotal;      pAigNew = Aig_ManDupRepr( p->pAig, 0 );      Aig_ManSeqCleanup( pAigNew ); +//Ssw_ClassesPrint( p->ppClasses, 1 );      // get the final stats      p->nLitsEnd  = Ssw_ClassesLitNum( p->ppClasses );      p->nNodesEnd = Aig_ManNodeNum(pAigNew); diff --git a/src/aig/ssw/sswLcorr.c b/src/aig/ssw/sswLcorr.c index 8cb8b81b..80bc5853 100644 --- a/src/aig/ssw/sswLcorr.c +++ b/src/aig/ssw/sswLcorr.c @@ -308,6 +308,9 @@ int Ssw_ManSweepLatch( Ssw_Man_t * p )              p->nRecycleCalls = 0;          }      } +//    ABC_PRT( "reduce", p->timeReduce ); +//    Aig_TableProfile( p->pFrames ); +//    printf( "And gates = %d\n", Aig_ManNodeNum(p->pFrames) );      // resimulate      if ( p->nPatterns > 0 )          Ssw_ManSweepResimulate( p ); diff --git a/src/base/abc/abcFunc.c b/src/base/abc/abcFunc.c index 758bc1e2..df46fc06 100644 --- a/src/base/abc/abcFunc.c +++ b/src/base/abc/abcFunc.c @@ -595,6 +595,7 @@ Hop_Obj_t * Abc_ConvertSopToAigInternal( Hop_Man_t * pMan, char * pSop )      Hop_Obj_t * pAnd, * pSum;      int i, Value, nFanins;      char * pCube; +    int fExor = Abc_SopIsExorType(pSop);      // get the number of variables      nFanins = Abc_SopGetVarNum(pSop);      // go through the cubes of the node's SOP @@ -611,7 +612,10 @@ Hop_Obj_t * Abc_ConvertSopToAigInternal( Hop_Man_t * pMan, char * pSop )                  pAnd = Hop_And( pMan, pAnd, Hop_Not(Hop_IthVar(pMan,i)) );          }          // add to the sum of cubes -        pSum = Hop_Or( pMan, pSum, pAnd ); +        if ( fExor ) +            pSum = Hop_Exor( pMan, pSum, pAnd ); +        else +            pSum = Hop_Or( pMan, pSum, pAnd );      }      // decide whether to complement the result      if ( Abc_SopIsComplement(pSop) ) @@ -637,11 +641,8 @@ Hop_Obj_t * Abc_ConvertSopToAig( Hop_Man_t * pMan, char * pSop )      // consider the constant node      if ( Abc_SopGetVarNum(pSop) == 0 )          return Hop_NotCond( Hop_ManConst1(pMan), Abc_SopIsConst0(pSop) ); -    // consider the special case of EXOR function -    if ( Abc_SopIsExorType(pSop) ) -        return Hop_NotCond( Hop_CreateExor(pMan, Abc_SopGetVarNum(pSop)), Abc_SopIsComplement(pSop) );      // decide when to use factoring -    if ( fUseFactor && Abc_SopGetVarNum(pSop) > 2 && Abc_SopGetCubeNum(pSop) > 1 ) +    if ( fUseFactor && Abc_SopGetVarNum(pSop) > 2 && Abc_SopGetCubeNum(pSop) > 1 && !Abc_SopIsExorType(pSop) )          return Dec_GraphFactorSop( pMan, pSop );      return Abc_ConvertSopToAigInternal( pMan, pSop );  } diff --git a/src/base/abc/abcLib.c b/src/base/abc/abcLib.c index 850e59e0..138dc9a1 100644 --- a/src/base/abc/abcLib.c +++ b/src/base/abc/abcLib.c @@ -82,6 +82,8 @@ void Abc_LibFree( Abc_Lib_t * pLib, Abc_Ntk_t * pNtkSave )                  continue;  //            pNtk->pManFunc = NULL;              pNtk->pDesign = NULL; +            if ( pNtk->pManFunc == pNtkSave->pManFunc ) +                pNtk->pManFunc = NULL;              Abc_NtkDelete( pNtk );          }          Vec_PtrFree( pLib->vModules ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index cf574ecb..876266af 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -128,7 +128,7 @@ static int Abc_CommandCareSet        ( Abc_Frame_t * pAbc, int argc, char ** arg  static int Abc_CommandCut            ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int Abc_CommandEspresso       ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int Abc_CommandGen            ( Abc_Frame_t * pAbc, int argc, char ** argv ); -//static int Abc_CommandXyz            ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandCover          ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int Abc_CommandDouble         ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int Abc_CommandInter          ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int Abc_CommandTest           ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -297,6 +297,9 @@ static int Abc_CommandAbc9Retime     ( Abc_Frame_t * pAbc, int argc, char ** arg  static int Abc_CommandAbc9Enable     ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int Abc_CommandAbc9Miter      ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int Abc_CommandAbc9Scl        ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Lcorr      ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Scorr      ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Choice     ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int Abc_CommandAbc9Sat        ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int Abc_CommandAbc9Fraig      ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int Abc_CommandAbc9Srm        ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -448,7 +451,7 @@ void Abc_Init( Abc_Frame_t * pAbc )      Cmd_CommandAdd( pAbc, "Various",      "cut",           Abc_CommandCut,              0 );      Cmd_CommandAdd( pAbc, "Various",      "espresso",      Abc_CommandEspresso,         1 );      Cmd_CommandAdd( pAbc, "Various",      "gen",           Abc_CommandGen,              0 ); -//    Cmd_CommandAdd( pAbc, "Various",      "xyz",           Abc_CommandXyz,              1 ); +    Cmd_CommandAdd( pAbc, "Various",      "cover",         Abc_CommandCover,            1 );      Cmd_CommandAdd( pAbc, "Various",      "double",        Abc_CommandDouble,           1 );      Cmd_CommandAdd( pAbc, "Various",      "inter",         Abc_CommandInter,            1 );      Cmd_CommandAdd( pAbc, "Various",      "test",          Abc_CommandTest,             0 ); @@ -610,6 +613,9 @@ void Abc_Init( Abc_Frame_t * pAbc )      Cmd_CommandAdd( pAbc, "AIG",          "&enable",       Abc_CommandAbc9Enable,       0 );      Cmd_CommandAdd( pAbc, "AIG",          "&miter",        Abc_CommandAbc9Miter,        0 );      Cmd_CommandAdd( pAbc, "AIG",          "&scl",          Abc_CommandAbc9Scl,          0 ); +    Cmd_CommandAdd( pAbc, "AIG",          "&lcorr",        Abc_CommandAbc9Lcorr,        0 ); +    Cmd_CommandAdd( pAbc, "AIG",          "&scorr",        Abc_CommandAbc9Scorr,        0 ); +    Cmd_CommandAdd( pAbc, "AIG",          "&choice",       Abc_CommandAbc9Choice,       0 );      Cmd_CommandAdd( pAbc, "AIG",          "&sat",          Abc_CommandAbc9Sat,          0 );      Cmd_CommandAdd( pAbc, "AIG",          "&fraig",        Abc_CommandAbc9Fraig,        0 );      Cmd_CommandAdd( pAbc, "AIG",          "&srm",          Abc_CommandAbc9Srm,          0 ); @@ -7575,7 +7581,7 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )      return 0;  usage: -    fprintf( pErr, "usage: cut [-K num] [-M num] [-tfdxyzamjvh]\n" ); +    fprintf( pErr, "usage: cut [-K num] [-M num] [-tfdcovamjvh]\n" );      fprintf( pErr, "\t         computes k-feasible cuts for the AIG\n" );      fprintf( pErr, "\t-K num : max number of leaves (%d <= num <= %d) [default = %d]\n",   CUT_SIZE_MIN, CUT_SIZE_MAX, pParams->nVarsMax );      fprintf( pErr, "\t-M num : max number of cuts stored at a node [default = %d]\n",      pParams->nKeepMax ); @@ -7785,6 +7791,7 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )      int fMesh;      int fFpga;      int fOneHot; +    int fRandom;      int fVerbose;      char * FileName;      extern void Abc_GenAdder( char * pFileName, int nVars ); @@ -7792,7 +7799,7 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )      extern void Abc_GenMesh( char * pFileName, int nVars );      extern void Abc_GenFpga( char * pFileName, int nLutSize, int nLuts, int nVars );      extern void Abc_GenOneHot( char * pFileName, int nVars ); - +    extern void Abc_GenRandom( char * pFileName, int nPis );      pNtk = Abc_FrameReadNtk(pAbc);      pOut = Abc_FrameReadOut(pAbc); @@ -7805,9 +7812,10 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )      fMesh = 0;      fFpga = 0;      fOneHot = 0; +    fRandom = 0;      fVerbose = 0;      Extra_UtilGetoptReset(); -    while ( ( c = Extra_UtilGetopt( argc, argv, "Nasmftvh" ) ) != EOF ) +    while ( ( c = Extra_UtilGetopt( argc, argv, "Nasmftrvh" ) ) != EOF )      {          switch ( c )          { @@ -7837,6 +7845,9 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )          case 't':              fOneHot ^= 1;              break; +        case 'r': +            fRandom ^= 1; +            break;          case 'v':              fVerbose ^= 1;              break; @@ -7866,12 +7877,14 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )  //        Abc_GenFpga( FileName, 3, 2, 5 );      else if ( fOneHot )          Abc_GenOneHot( FileName, nVars ); +    else if ( fRandom ) +        Abc_GenRandom( FileName, nVars );      else          printf( "Type of circuit is not specified.\n" );      return 0;  usage: -    fprintf( pErr, "usage: gen [-N num] [-asmftvh] <file>\n" ); +    fprintf( pErr, "usage: gen [-N num] [-asmftrvh] <file>\n" );      fprintf( pErr, "\t         generates simple circuits\n" );      fprintf( pErr, "\t-N num : the number of variables [default = %d]\n", nVars );        fprintf( pErr, "\t-a     : generate ripple-carry adder [default = %s]\n", fAdder? "yes": "no" );   @@ -7879,13 +7892,13 @@ usage:      fprintf( pErr, "\t-m     : generate a mesh [default = %s]\n", fMesh? "yes": "no" );        fprintf( pErr, "\t-f     : generate a LUT FPGA structure [default = %s]\n", fFpga? "yes": "no" );        fprintf( pErr, "\t-t     : generate one-hotness conditions [default = %s]\n", fOneHot? "yes": "no" );   +    fprintf( pErr, "\t-r     : generate random single-output function [default = %s]\n", fRandom? "yes": "no" );        fprintf( pErr, "\t-v     : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );        fprintf( pErr, "\t-h     : print the command usage\n");      fprintf( pErr, "\t<file> : output file name\n");      return 1;  } -  /**Function*************************************************************    Synopsis    [] @@ -7897,79 +7910,52 @@ usage:    SeeAlso     []  ***********************************************************************/ -int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv ) +int Abc_CommandCover( Abc_Frame_t * pAbc, int argc, char ** argv )  {      FILE * pOut, * pErr; -    Abc_Ntk_t * pNtk, * pNtkRes;//, * pNtkTemp; +    Abc_Ntk_t * pNtk, * pNtkRes;      int c; -    int nLutMax; -    int nPlaMax; -    int RankCost; -    int fFastMode; -    int fRewriting; -    int fSynthesis;      int fVerbose; -//    extern Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nPlaMax, bool fEsop, bool fSop, bool fInvs, bool fVerbose ); -    extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fRewriting, int fSynthesis, int fVerbose ); +    int fUseSop; +    int fUseEsop; +    int fUseInvs; +    int nFaninMax; +    extern Abc_Ntk_t * Abc_NtkSopEsopCover( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose );      pNtk = Abc_FrameReadNtk(pAbc);      pOut = Abc_FrameReadOut(pAbc);      pErr = Abc_FrameReadErr(pAbc);      // set defaults -    nLutMax    = 8; -    nPlaMax    = 128; -    RankCost   = 96000; -    fFastMode  = 1; -    fRewriting = 0; -    fSynthesis = 0; -    fVerbose   = 0; +    fUseSop   =  1; +    fUseEsop  =  0; +    fVerbose  =  0; +    fUseInvs  =  1; +    nFaninMax =  8;      Extra_UtilGetoptReset(); -    while ( ( c = Extra_UtilGetopt( argc, argv, "LPRfrsvh" ) ) != EOF ) +    while ( ( c = Extra_UtilGetopt( argc, argv, "Nsxivh" ) ) != EOF )      {          switch ( c )          { -        case 'L': -            if ( globalUtilOptind >= argc ) -            { -                fprintf( pErr, "Command line switch \"-L\" should be followed by an integer.\n" ); -                goto usage; -            } -            nLutMax = atoi(argv[globalUtilOptind]); -            globalUtilOptind++; -            if ( nLutMax < 0 )  -                goto usage; -            break; -        case 'P': -            if ( globalUtilOptind >= argc ) -            { -                fprintf( pErr, "Command line switch \"-P\" should be followed by an integer.\n" ); -                goto usage; -            } -            nPlaMax = atoi(argv[globalUtilOptind]); -            globalUtilOptind++; -            if ( nPlaMax < 0 )  -                goto usage; -            break; -        case 'R': +        case 'N':              if ( globalUtilOptind >= argc )              { -                fprintf( pErr, "Command line switch \"-R\" should be followed by an integer.\n" ); +                fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );                  goto usage;              } -            RankCost = atoi(argv[globalUtilOptind]); +            nFaninMax = atoi(argv[globalUtilOptind]);              globalUtilOptind++; -            if ( RankCost < 0 )  +            if ( nFaninMax < 0 )                   goto usage;              break; -        case 'f': -            fFastMode ^= 1; +        case 's': +            fUseSop ^= 1;              break; -        case 'r': -            fRewriting ^= 1; +        case 'x': +            fUseEsop ^= 1;              break; -        case 's': -            fSynthesis ^= 1; +        case 'i': +            fUseInvs ^= 1;              break;          case 'v':              fVerbose ^= 1; @@ -7991,26 +7977,9 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv )          fprintf( pErr, "Only works for strashed networks.\n" );          return 1;      } -/* -    if ( nLutMax < 2 || nLutMax > 12 || nPlaMax < 8 || nPlaMax > 128  ) -    { -        fprintf( pErr, "Incorrect LUT/PLA parameters.\n" ); -        return 1; -    } -*/ +      // run the command -//    pNtkRes = Abc_NtkXyz( pNtk, nPlaMax, 1, 0, fInvs, fVerbose ); -/* -    if ( !Abc_NtkIsStrash(pNtk) ) -    { -        pNtkTemp = Abc_NtkStrash( pNtk, 0, 1, 0 ); -        pNtkRes = Abc_NtkPlayer( pNtkTemp, nLutMax, nPlaMax, RankCost, fFastMode, fRewriting, fSynthesis, fVerbose ); -        Abc_NtkDelete( pNtkTemp ); -    } -    else -        pNtkRes = Abc_NtkPlayer( pNtk, nLutMax, nPlaMax, RankCost, fFastMode, fRewriting, fSynthesis, fVerbose ); -*/ -    pNtkRes = NULL; +    pNtkRes = Abc_NtkSopEsopCover( pNtk, nFaninMax, fUseEsop, fUseSop, fUseInvs, fVerbose );      if ( pNtkRes == NULL )      {          fprintf( pErr, "Command has failed.\n" ); @@ -8021,20 +7990,17 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv )      return 0;  usage: -    fprintf( pErr, "usage: xyz [-L num] [-P num] [-R num] [-frsvh]\n" ); -    fprintf( pErr, "\t         specilized LUT/PLA decomposition\n" ); -    fprintf( pErr, "\t-L num : maximum number of LUT inputs (2<=num<=8) [default = %d]\n", nLutMax ); -    fprintf( pErr, "\t-P num : maximum number of PLA inputs/cubes (8<=num<=128) [default = %d]\n", nPlaMax ); -    fprintf( pErr, "\t-R num : maximum are of one decomposition rank [default = %d]\n", RankCost ); -    fprintf( pErr, "\t-f     : toggle using fast LUT mapping mode [default = %s]\n", fFastMode? "yes": "no" ); -    fprintf( pErr, "\t-r     : toggle using one pass of AIG rewriting [default = %s]\n", fRewriting? "yes": "no" ); -    fprintf( pErr, "\t-s     : toggle using synthesis by AIG rewriting [default = %s]\n", fSynthesis? "yes": "no" ); +    fprintf( pErr, "usage: cover [-N num] [-sxvh]\n" ); +    fprintf( pErr, "\t         decomposition into a network of SOP/ESOP PLAs\n" ); +    fprintf( pErr, "\t-N num : maximum number of inputs [default = %d]\n", nFaninMax ); +    fprintf( pErr, "\t-s     : toggle the use of SOPs [default = %s]\n", fUseSop? "yes": "no" ); +    fprintf( pErr, "\t-x     : toggle the use of ESOPs [default = %s]\n", fUseEsop? "yes": "no" ); +//    fprintf( pErr, "\t-i     : toggle the use of interters [default = %s]\n", fUseInvs? "yes": "no" );      fprintf( pErr, "\t-v     : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );      fprintf( pErr, "\t-h     : print the command usage\n");      return 1;  } -  /**Function*************************************************************    Synopsis    [] @@ -21930,11 +21896,15 @@ usage:  int Abc_CommandAbc9Ps( Abc_Frame_t * pAbc, int argc, char ** argv )  {      int c; +    int fSwitch = 0;      Extra_UtilGetoptReset(); -    while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) +    while ( ( c = Extra_UtilGetopt( argc, argv, "ph" ) ) != EOF )      {          switch ( c )          { +        case 'p': +            fSwitch ^= 1; +            break;          case 'h':              goto usage;          default: @@ -21946,12 +21916,13 @@ int Abc_CommandAbc9Ps( Abc_Frame_t * pAbc, int argc, char ** argv )          printf( "Abc_CommandAbc9Ps(): There is no AIG.\n" );          return 1;      }  -    Gia_ManPrintStats( pAbc->pAig ); +    Gia_ManPrintStats( pAbc->pAig, fSwitch );      return 0;  usage: -    fprintf( stdout, "usage: &ps [-h]\n" ); +    fprintf( stdout, "usage: &ps [-ph]\n" );      fprintf( stdout, "\t        prints stats of the current AIG\n" ); +    fprintf( stdout, "\t-p    : toggle printing switching activity [default = %s]\n", fSwitch? "yes": "no" );      fprintf( stdout, "\t-h    : print the command usage\n");      return 1;  } @@ -22393,11 +22364,23 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv )  {      Gia_Man_t * pTemp;      int c; +    int fNormal  = 0; +    int fReverse = 0; +    int fVerbose = 0;      Extra_UtilGetoptReset(); -    while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) +    while ( ( c = Extra_UtilGetopt( argc, argv, "nrvh" ) ) != EOF )      {          switch ( c )          { +        case 'n': +            fNormal ^= 1; +            break; +        case 'r': +            fReverse ^= 1; +            break; +        case 'v': +            fVerbose ^= 1; +            break;          case 'h':              goto usage;          default: @@ -22409,13 +22392,33 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv )          printf( "Abc_CommandAbc9Dfs(): There is no AIG.\n" );          return 1;      }  -    pAbc->pAig = Gia_ManDupDfs( pTemp = pAbc->pAig ); +    if ( fNormal ) +    { +        pAbc->pAig = Gia_ManDupOrderAiger( pTemp = pAbc->pAig ); +        if ( fVerbose ) +            printf( "AIG objects are reordered as follows: CIs, ANDs, COs.\n" ); +    } +    else if ( fReverse ) +    { +        pAbc->pAig = Gia_ManDupOrderDfsReverse( pTemp = pAbc->pAig ); +        if ( fVerbose ) +            printf( "AIG objects are reordered in the reserve DFS order.\n" ); +    } +    else  +    { +        pAbc->pAig = Gia_ManDupOrderDfs( pTemp = pAbc->pAig ); +        if ( fVerbose ) +            printf( "AIG objects are reordered in the DFS order.\n" ); +    }      Gia_ManStop( pTemp );      return 0;  usage: -    fprintf( stdout, "usage: &dfs [-h]\n" ); +    fprintf( stdout, "usage: &dfs [-nrvh]\n" );      fprintf( stdout, "\t        orders objects in the DFS order\n" ); +    fprintf( stdout, "\t-n    : toggle using normalized ordering [default = %s]\n", fNormal? "yes": "no" ); +    fprintf( stdout, "\t-r    : toggle using reverse DFS ordering [default = %s]\n", fReverse? "yes": "no" ); +    fprintf( stdout, "\t-v    : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );      fprintf( stdout, "\t-h    : print the command usage\n");      return 1;  } @@ -23218,14 +23221,258 @@ usage:    SeeAlso     []  ***********************************************************************/ +int Abc_CommandAbc9Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ +    Cec_ParCor_t Pars, * pPars = &Pars; +    Gia_Man_t * pTemp; +    int c; +    Cec_ManCorSetDefaultParams( pPars ); +    pPars->fLatchCorr = 1; +    Extra_UtilGetoptReset(); +    while ( ( c = Extra_UtilGetopt( argc, argv, "FCfrcvh" ) ) != EOF ) +    { +        switch ( c ) +        { +        case 'F': +            if ( globalUtilOptind >= argc ) +            { +                fprintf( stdout, "Command line switch \"-F\" should be followed by an integer.\n" ); +                goto usage; +            } +            pPars->nFrames = atoi(argv[globalUtilOptind]); +            globalUtilOptind++; +            if ( pPars->nFrames < 0 )  +                goto usage; +            break; +        case 'C': +            if ( globalUtilOptind >= argc ) +            { +                fprintf( stdout, "Command line switch \"-C\" should be followed by an integer.\n" ); +                goto usage; +            } +            pPars->nBTLimit = atoi(argv[globalUtilOptind]); +            globalUtilOptind++; +            if ( pPars->nBTLimit < 0 )  +                goto usage; +            break; +        case 'f': +            pPars->fFirstStop ^= 1; +            break; +        case 'r': +            pPars->fUseRings ^= 1; +            break; +        case 'c': +            pPars->fUseCSat ^= 1; +            break; +        case 'v': +            pPars->fVerbose ^= 1; +            break; +        default: +            goto usage; +        } +    } +    if ( pAbc->pAig == NULL ) +    { +        printf( "Abc_CommandAbc9Lcorr(): There is no AIG.\n" ); +        return 1; +    }  +    pAbc->pAig = Cec_ManLSCorrespondence( pTemp = pAbc->pAig, pPars ); +    if ( pAbc->pAig == NULL ) +    { +        pAbc->pAig = pTemp; +        printf( "Abc_CommandAbc9Lcorr(): Command has failed.\n" ); +    } +    else  +        Gia_ManStop( pTemp ); +    return 0; + +usage: +    fprintf( stdout, "usage: &lcorr [-FC num] [-frcvh]\n" ); +    fprintf( stdout, "\t         performs latch correpondence computation\n" ); +    fprintf( stdout, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); +    fprintf( stdout, "\t-F num : the number of timeframes in inductive case [default = %d]\n", pPars->nFrames ); +    fprintf( stdout, "\t-f     : toggle quitting when one PO is asserted [default = %s]\n", pPars->fFirstStop? "yes": "no" ); +    fprintf( stdout, "\t-r     : toggle using implication rings for equivalence classes [default = %s]\n", pPars->fUseRings? "yes": "no" ); +    fprintf( stdout, "\t-c     : toggle using circuit-based SAT solver [default = %s]\n", pPars->fUseCSat? "yes": "no" ); +    fprintf( stdout, "\t-v     : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); +    fprintf( stdout, "\t-h     : print the command usage\n"); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ +    Cec_ParCor_t Pars, * pPars = &Pars; +    Gia_Man_t * pTemp; +    int c; +    Cec_ManCorSetDefaultParams( pPars ); +    Extra_UtilGetoptReset(); +    while ( ( c = Extra_UtilGetopt( argc, argv, "FCfrcvh" ) ) != EOF ) +    { +        switch ( c ) +        { +        case 'F': +            if ( globalUtilOptind >= argc ) +            { +                fprintf( stdout, "Command line switch \"-F\" should be followed by an integer.\n" ); +                goto usage; +            } +            pPars->nFrames = atoi(argv[globalUtilOptind]); +            globalUtilOptind++; +            if ( pPars->nFrames < 0 )  +                goto usage; +            break; +        case 'C': +            if ( globalUtilOptind >= argc ) +            { +                fprintf( stdout, "Command line switch \"-C\" should be followed by an integer.\n" ); +                goto usage; +            } +            pPars->nBTLimit = atoi(argv[globalUtilOptind]); +            globalUtilOptind++; +            if ( pPars->nBTLimit < 0 )  +                goto usage; +            break; +        case 'f': +            pPars->fFirstStop ^= 1; +            break; +        case 'r': +            pPars->fUseRings ^= 1; +            break; +        case 'c': +            pPars->fUseCSat ^= 1; +            break; +        case 'v': +            pPars->fVerbose ^= 1; +            break; +        default: +            goto usage; +        } +    } +    if ( pAbc->pAig == NULL ) +    { +        printf( "Abc_CommandAbc9Scorr(): There is no AIG.\n" ); +        return 1; +    }  +    pAbc->pAig = Cec_ManLSCorrespondence( pTemp = pAbc->pAig, pPars ); +    if ( pAbc->pAig == NULL ) +    { +        pAbc->pAig = pTemp; +        printf( "Abc_CommandAbc9Scorr(): Command has failed.\n" ); +    } +    else  +        Gia_ManStop( pTemp ); +    return 0; + +usage: +    fprintf( stdout, "usage: &scorr [-FC num] [-frcvh]\n" ); +    fprintf( stdout, "\t         performs signal correpondence computation\n" ); +    fprintf( stdout, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); +    fprintf( stdout, "\t-F num : the number of timeframes in inductive case [default = %d]\n", pPars->nFrames ); +    fprintf( stdout, "\t-f     : toggle quitting when one PO is asserted [default = %s]\n", pPars->fFirstStop? "yes": "no" ); +    fprintf( stdout, "\t-r     : toggle using implication rings for equivalence classes [default = %s]\n", pPars->fUseRings? "yes": "no" ); +    fprintf( stdout, "\t-c     : toggle using circuit-based SAT solver [default = %s]\n", pPars->fUseCSat? "yes": "no" ); +    fprintf( stdout, "\t-v     : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); +    fprintf( stdout, "\t-h     : print the command usage\n"); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Abc_CommandAbc9Choice( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ +    Cec_ParChc_t Pars, * pPars = &Pars; +    Gia_Man_t * pTemp; +    int c; +    Cec_ManChcSetDefaultParams( pPars ); +    Extra_UtilGetoptReset(); +    while ( ( c = Extra_UtilGetopt( argc, argv, "Cvh" ) ) != EOF ) +    { +        switch ( c ) +        { +        case 'C': +            if ( globalUtilOptind >= argc ) +            { +                fprintf( stdout, "Command line switch \"-C\" should be followed by an integer.\n" ); +                goto usage; +            } +            pPars->nBTLimit = atoi(argv[globalUtilOptind]); +            globalUtilOptind++; +            if ( pPars->nBTLimit < 0 )  +                goto usage; +            break; +        case 'v': +            pPars->fVerbose ^= 1; +            break; +        default: +            goto usage; +        } +    } +    if ( pAbc->pAig == NULL ) +    { +        printf( "Abc_CommandAbc9Choice(): There is no AIG.\n" ); +        return 1; +    }  +    printf("The command is not yet ready.\n" ); +    return 0; +    pAbc->pAig = Cec_ManChoiceComputation( pTemp = pAbc->pAig, pPars ); +    if ( pAbc->pAig == NULL ) +    { +        pAbc->pAig = pTemp; +        printf( "Abc_CommandAbc9Choice(): Command has failed.\n" ); +    } +    else  +        Gia_ManStop( pTemp ); +    return 0; + +usage: +    fprintf( stdout, "usage: &choice [-C num] [-vh]\n" ); +    fprintf( stdout, "\t         performs computation of structural choices\n" ); +    fprintf( stdout, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); +    fprintf( stdout, "\t-v     : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); +    fprintf( stdout, "\t-h     : print the command usage\n"); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/  int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv )  {      Cec_ParSat_t ParsSat, * pPars = &ParsSat;      Gia_Man_t * pTemp;      int c; +    int fCSat = 0;      Cec_ManSatSetDefaultParams( pPars );      Extra_UtilGetoptReset(); -    while ( ( c = Extra_UtilGetopt( argc, argv, "CSNmfvh" ) ) != EOF ) +    while ( ( c = Extra_UtilGetopt( argc, argv, "CSNmfcvh" ) ) != EOF )      {          switch ( c )          { @@ -23268,6 +23515,9 @@ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv )          case 'f':              pPars->fFirstStop ^= 1;              break; +        case 'c': +            fCSat ^= 1; +            break;          case 'v':              pPars->fVerbose ^= 1;              break; @@ -23280,18 +23530,30 @@ int Abc_CommandAbc9Sat( Abc_Frame_t * pAbc, int argc, char ** argv )          printf( "Abc_CommandAbc9Sat(): There is no AIG.\n" );          return 1;      }  -    pAbc->pAig = Cec_ManSatSolving( pTemp = pAbc->pAig, pPars ); -    Gia_ManStop( pTemp ); +    if ( fCSat ) +    { +        Vec_Int_t * vCounters; +        Vec_Str_t * vStatus; +        vCounters = Cbs_ManSolveMiter( pAbc->pAig, 10*pPars->nBTLimit, &vStatus ); +        Vec_IntFree( vCounters ); +        Vec_StrFree( vStatus ); +    } +    else +    { +        pAbc->pAig = Cec_ManSatSolving( pTemp = pAbc->pAig, pPars ); +        Gia_ManStop( pTemp ); +    }      return 0;  usage: -    fprintf( stdout, "usage: &sat [-CSN <num>] [-mfvh]\n" ); +    fprintf( stdout, "usage: &sat [-CSN <num>] [-mfcvh]\n" );      fprintf( stdout, "\t         performs SAT solving for the combinational outputs\n" );      fprintf( stdout, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );      fprintf( stdout, "\t-S num : the min number of variables to recycle the solver [default = %d]\n", pPars->nSatVarMax );      fprintf( stdout, "\t-N num : the min number of calls to recycle the solver [default = %d]\n", pPars->nCallsRecycle );      fprintf( stdout, "\t-m     : toggle miter vs. any circuit [default = %s]\n", pPars->fCheckMiter? "yes": "no" );      fprintf( stdout, "\t-f     : toggle quitting when one PO is asserted [default = %s]\n", pPars->fFirstStop? "yes": "no" ); +    fprintf( stdout, "\t-c     : toggle using circuit-based SAT solver [default = %s]\n", fCSat? "yes": "no" );      fprintf( stdout, "\t-v     : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );      fprintf( stdout, "\t-h     : print the command usage\n");      return 1; @@ -23545,7 +23807,11 @@ int Abc_CommandAbc9Reduce( Abc_Frame_t * pAbc, int argc, char ** argv )      if ( pAbc->pAig == NULL )          pAbc->pAig = pTemp;      else +    {          Gia_ManStop( pTemp ); +        pAbc->pAig = Gia_ManSeqStructSweep( pTemp = pAbc->pAig, 1, 1, 0 ); +        Gia_ManStop( pTemp ); +    }      return 0;  usage: diff --git a/src/base/abci/abcGen.c b/src/base/abci/abcGen.c index e40c21d6..f6111dfd 100644 --- a/src/base/abci/abcGen.c +++ b/src/base/abci/abcGen.c @@ -599,6 +599,56 @@ void Abc_GenOneHotIntervals( char * pFileName, int nPis, int nRegs, Vec_Ptr_t *      fclose( pFile );  } +#include "aig.h" + +/**Function************************************************************* + +  Synopsis    [Generates structure of L K-LUTs implementing an N-var function.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Abc_GenRandom( char * pFileName, int nPis ) +{ +    FILE * pFile; +    unsigned * pTruth; +    int i, b, w, nWords = Aig_TruthWordNum( nPis ); +    int nDigitsIn; +    Aig_ManRandom( 1 ); +    pTruth = ABC_ALLOC( unsigned, nWords ); +    for ( w = 0; w < nWords; w++ ) +        pTruth[w] = Aig_ManRandom( 0 ); +    pFile = fopen( pFileName, "w" ); +    fprintf( pFile, "# Random function with %d inputs generated by ABC on %s\n", nPis, Extra_TimeStamp() ); +    fprintf( pFile, ".model rand%d\n", nPis ); +    fprintf( pFile, ".inputs" ); +    nDigitsIn = Extra_Base10Log( nPis ); +    for ( i = 0; i < nPis; i++ ) +        fprintf( pFile, " i%0*d", nDigitsIn, i ); +    fprintf( pFile, "\n" ); +    fprintf( pFile, ".outputs f\n" ); +    fprintf( pFile, ".names" ); +    nDigitsIn = Extra_Base10Log( nPis ); +    for ( i = 0; i < nPis; i++ ) +        fprintf( pFile, " i%0*d", nDigitsIn, i ); +    fprintf( pFile, " f\n" ); +    for ( i = 0; i < (1<<nPis); i++ ) +        if ( Aig_InfoHasBit(pTruth, i) ) +        { +            for ( b = nPis-1; b >= 0; b-- ) +                fprintf( pFile, "%d", (i>>b)&1 ); +            fprintf( pFile, " 1\n" ); +        } +    fprintf( pFile, ".end\n" );  +    fprintf( pFile, "\n" );  +    fclose( pFile ); +    ABC_FREE( pTruth ); +} +  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                /// diff --git a/src/base/abci/abcIvy.c b/src/base/abci/abcIvy.c index c7fa5a1e..9e0347d5 100644 --- a/src/base/abci/abcIvy.c +++ b/src/base/abci/abcIvy.c @@ -946,12 +946,8 @@ Ivy_Obj_t * Abc_NodeStrashAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode )      if ( Abc_NodeIsConst(pNode) )          return Ivy_NotCond( Ivy_ManConst1(pMan), Abc_SopIsConst0(pSop) ); -    // consider the special case of EXOR function -    if ( Abc_SopIsExorType(pSop) ) -        return Abc_NodeStrashAigExorAig( pMan, pNode, pSop ); -      // decide when to use factoring -    if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 ) +    if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 && !Abc_SopIsExorType(pSop) )          return Abc_NodeStrashAigFactorAig( pMan, pNode, pSop );      return Abc_NodeStrashAigSopAig( pMan, pNode, pSop );  } @@ -973,6 +969,7 @@ Ivy_Obj_t * Abc_NodeStrashAigSopAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char *      Ivy_Obj_t * pAnd, * pSum;      char * pCube;      int i, nFanins; +    int fExor = Abc_SopIsExorType(pSop);      // get the number of node's fanins      nFanins = Abc_ObjFaninNum( pNode ); @@ -991,7 +988,10 @@ Ivy_Obj_t * Abc_NodeStrashAigSopAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char *                  pAnd = Ivy_And( pMan, pAnd, Ivy_Not((Ivy_Obj_t *)pFanin->pCopy) );          }          // add to the sum of cubes -        pSum = Ivy_Or( pMan, pSum, pAnd ); +        if ( fExor ) +            pSum = Ivy_Exor( pMan, pSum, pAnd ); +        else +            pSum = Ivy_Or( pMan, pSum, pAnd );      }      // decide whether to complement the result      if ( Abc_SopIsComplement(pSop) ) diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c index b869f067..e65ce11a 100644 --- a/src/base/abci/abcPrint.c +++ b/src/base/abci/abcPrint.c @@ -135,8 +135,10 @@ float Abc_NtkMfsTotalSwitching( Abc_Ntk_t * pNtk )      Abc_NtkForEachObj( pNtk, pObjAbc, i )      {          if ( (pObjAbc2 = Abc_ObjRegular(pObjAbc->pTemp)) && (pObjAig = Aig_Regular(pObjAbc2->pTemp)) ) +        {              Result += Abc_ObjFanoutNum(pObjAbc) * pSwitching[pObjAig->Id]; -//            Result += pSwitching[pObjAig->Id]; +//            printf( "%d = %.2f\n", i, Abc_ObjFanoutNum(pObjAbc) * pSwitching[pObjAig->Id] ); +        }      }      Vec_IntFree( vSwitching );      Aig_ManStop( pAig ); diff --git a/src/base/io/io.c b/src/base/io/io.c index e8af161e..20f412e0 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -1849,6 +1849,7 @@ int IoCommandWriteCounter( Abc_Frame_t * pAbc, int argc, char **argv )      if ( argc != globalUtilOptind + 1 )      { +        printf( "File name is missing on the command line.\n" );          goto usage;      }      // get the input file name diff --git a/src/base/io/ioReadBlifMv.c b/src/base/io/ioReadBlifMv.c index 95ea4fe5..34ea4294 100644 --- a/src/base/io/ioReadBlifMv.c +++ b/src/base/io/ioReadBlifMv.c @@ -1615,7 +1615,7 @@ static char * Io_MvParseTableBlif( Io_MvMod_t * p, char * pTable, int nFanins )  {      Vec_Ptr_t * vTokens = p->pMan->vTokens;      Vec_Str_t * vFunc = p->pMan->vFunc; -    char * pProduct, * pOutput; +    char * pProduct, * pOutput, c;      int i, Polarity = -1;      p->pMan->nTablesRead++; @@ -1626,7 +1626,8 @@ static char * Io_MvParseTableBlif( Io_MvMod_t * p, char * pTable, int nFanins )      if ( Vec_PtrSize(vTokens) == 1 )      {          pOutput = Vec_PtrEntry( vTokens, 0 ); -        if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] ) +        c = pOutput[0]; +        if ( (c!='0'&&c!='1'&&c!='x'&&c!='n') || pOutput[1] )          {              sprintf( p->pMan->sError, "Line %d: Constant table has wrong output value \"%s\".", Io_MvGetLine(p->pMan, pOutput), pOutput );              return NULL; @@ -1650,14 +1651,15 @@ static char * Io_MvParseTableBlif( Io_MvMod_t * p, char * pTable, int nFanins )              sprintf( p->pMan->sError, "Line %d: Cube \"%s\" has size different from the fanin count (%d).", Io_MvGetLine(p->pMan, pProduct), pProduct, nFanins );              return NULL;          } -        if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] ) +        c = pOutput[0]; +        if ( (c!='0'&&c!='1'&&c!='x'&&c!='n') || pOutput[1] )          {              sprintf( p->pMan->sError, "Line %d: Output value \"%s\" is incorrect.", Io_MvGetLine(p->pMan, pProduct), pOutput );              return NULL;          }          if ( Polarity == -1 ) -            Polarity = pOutput[0] - '0'; -        else if ( Polarity != pOutput[0] - '0' ) +            Polarity = (c=='1' || c=='x'); +        else if ( Polarity != (c=='1' || c=='x') )          {              sprintf( p->pMan->sError, "Line %d: Output value \"%s\" differs from the value in the first line of the table (%d).", Io_MvGetLine(p->pMan, pProduct), pOutput, Polarity );              return NULL; diff --git a/src/base/ver/verCore.c b/src/base/ver/verCore.c index aa213010..c318545b 100644 --- a/src/base/ver/verCore.c +++ b/src/base/ver/verCore.c @@ -2042,6 +2042,11 @@ int Ver_ParseConnectBox( Ver_Man_t * pMan, Abc_Obj_t * pBox )      assert( !Ver_ObjIsConnected(pBox) );      assert( Ver_NtkIsDefined(pNtkBox) );      assert( !Abc_NtkHasBlackbox(pNtkBox) || Abc_NtkBoxNum(pNtkBox) == 1 ); + +    if ( !strcmp(pNtkBox->pName,"add_4u_4u") ) +    { +        int s = 0; +    }  /*      // clean the PI/PO nets      Abc_NtkForEachPi( pNtkBox, pTerm, i ) @@ -2134,7 +2139,7 @@ int Ver_ParseConnectBox( Ver_Man_t * pMan, Abc_Obj_t * pBox )                  if ( Length > 0 )                  {                      Vec_PtrForEachEntry( vBundles, pBundle, j ) -                        if ( !strncmp(pBundle->pNameFormal, pNameFormal, Length) ) +                        if ( !strncmp(pBundle->pNameFormal, pNameFormal, Length) && (int)strlen(pBundle->pNameFormal) == Length )                              break;                      if ( j == Vec_PtrSize(vBundles) )                          pBundle = NULL; @@ -2185,7 +2190,7 @@ int Ver_ParseConnectBox( Ver_Man_t * pMan, Abc_Obj_t * pBox )                  if ( Length > 0 )                  {                      Vec_PtrForEachEntry( vBundles, pBundle, j ) -                        if ( !strncmp(pBundle->pNameFormal, pNameFormal, Length) ) +                        if ( !strncmp(pBundle->pNameFormal, pNameFormal, Length) && (int)strlen(pBundle->pNameFormal) == Length )                               break;                      if ( j == Vec_PtrSize(vBundles) )                          pBundle = NULL; @@ -2193,8 +2198,14 @@ int Ver_ParseConnectBox( Ver_Man_t * pMan, Abc_Obj_t * pBox )              }              if ( pBundle == NULL )              { +                char Buffer[1000];  //                printf( "Warning: The formal output %s is not driven when instantiating network %s in box %s.",   //                    pNameFormal, pNtkBox->pName, Abc_ObjName(pBox) ); +                pTermNew = Abc_NtkCreateBo( pNtk ); +                sprintf( Buffer, "_temp_net%d", Abc_ObjId(pTermNew) ); +                pNetAct = Abc_NtkFindOrCreateNet( pNtk, Buffer ); +                Abc_ObjAddFanin( pTermNew, pBox ); +                Abc_ObjAddFanin( pNetAct, pTermNew );                  continue;              }          } diff --git a/src/map/cov/cov.h b/src/map/cov/cov.h new file mode 100644 index 00000000..8ca81740 --- /dev/null +++ b/src/map/cov/cov.h @@ -0,0 +1,111 @@ +/**CFile**************************************************************** + +  FileName    [cov.h] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Mapping into network of SOPs/ESOPs.] + +  Synopsis    [External declarations.] + +  Author      [Alan Mishchenko] +    +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: cov.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __COV_H__ +#define __COV_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "abc.h" +#include "covInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Cov_Man_t_  Cov_Man_t; +typedef struct Cov_Obj_t_  Cov_Obj_t; + +// storage for node information +struct Cov_Obj_t_ +{ +    Min_Cube_t *      pCover[3];    // pos/neg/esop +    Vec_Int_t *       vSupp;        // computed support (all nodes except CIs) +}; + +// storage for additional information +struct Cov_Man_t_ +{ +    // general characteristics +    int               nFaninMax;    // the number of vars +    int               nCubesMax;    // the limit on the number of cubes in the intermediate covers +    int               nWords;       // the number of words +    Vec_Int_t *       vFanCounts;   // fanout counts +    Vec_Ptr_t *       vObjStrs;     // object structures +    void *            pMemory;      // memory for the internal data strctures +    Min_Man_t *       pManMin;      // the cube manager +    int               fUseEsop;     // enables ESOPs +    int               fUseSop;      // enables SOPs +    // arrays to map local variables +    Vec_Int_t *       vComTo0;      // mapping of common variables into first fanin +    Vec_Int_t *       vComTo1;      // mapping of common variables into second fanin +    Vec_Int_t *       vPairs0;      // the first var in each pair of common vars +    Vec_Int_t *       vPairs1;      // the second var in each pair of common vars +    Vec_Int_t *       vTriv0;       // trival support of the first node +    Vec_Int_t *       vTriv1;       // trival support of the second node +    // statistics +    int               nSupps;       // supports created +    int               nSuppsMax;    // the maximum number of supports +    int               nBoundary;    // the boundary size +    int               nNodes;       // the number of nodes processed +}; + +static inline Cov_Obj_t *  Abc_ObjGetStr( Abc_Obj_t * pObj )                       { return Vec_PtrEntry(((Cov_Man_t *)pObj->pNtk->pManCut)->vObjStrs, pObj->Id); } + +static inline void         Abc_ObjSetSupp( Abc_Obj_t * pObj, Vec_Int_t * vVec )    { Abc_ObjGetStr(pObj)->vSupp = vVec;   } +static inline Vec_Int_t *  Abc_ObjGetSupp( Abc_Obj_t * pObj )                      { return Abc_ObjGetStr(pObj)->vSupp;   } + +static inline void         Abc_ObjSetCover2( Abc_Obj_t * pObj, Min_Cube_t * pCov ) { Abc_ObjGetStr(pObj)->pCover[2] = pCov; } +static inline Min_Cube_t * Abc_ObjGetCover2( Abc_Obj_t * pObj )                    { return Abc_ObjGetStr(pObj)->pCover[2]; } + +static inline void         Abc_ObjSetCover( Abc_Obj_t * pObj, Min_Cube_t * pCov, int Pol ) { Abc_ObjGetStr(pObj)->pCover[Pol] = pCov; } +static inline Min_Cube_t * Abc_ObjGetCover( Abc_Obj_t * pObj, int Pol )                    { return Abc_ObjGetStr(pObj)->pCover[Pol]; } + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/*=== covBuild.c ==========================================================*/ +extern Abc_Ntk_t * Abc_NtkCovDerive( Cov_Man_t * p, Abc_Ntk_t * pNtk ); +extern Abc_Ntk_t * Abc_NtkCovDeriveClean( Cov_Man_t * p, Abc_Ntk_t * pNtk ); +extern Abc_Ntk_t * Abc_NtkCovDeriveRegular( Cov_Man_t * p, Abc_Ntk_t * pNtk ); +/*=== covCore.c ===========================================================*/ +extern Abc_Ntk_t * Abc_NtkSopEsopCover( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose ); +/*=== covMan.c ============================================================*/ +extern Cov_Man_t * Cov_ManAlloc( Abc_Ntk_t * pNtk, int nFaninMax ); +extern void        Cov_ManFree( Cov_Man_t * p ); +extern void        Abc_NodeCovDropData( Cov_Man_t * p, Abc_Obj_t * pObj ); +/*=== covTest.c ===========================================================*/ +extern Abc_Ntk_t * Abc_NtkCovTestSop( Abc_Ntk_t * pNtk ); + +#ifdef __cplusplus +} +#endif + +#endif + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + + diff --git a/src/map/cov/covBuild.c b/src/map/cov/covBuild.c new file mode 100644 index 00000000..560178be --- /dev/null +++ b/src/map/cov/covBuild.c @@ -0,0 +1,539 @@ +/**CFile**************************************************************** + +  FileName    [covBuild.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Mapping into network of SOPs/ESOPs.] + +  Synopsis    [Network construction procedures.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: covBuild.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cov.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Derives the decomposed network.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCovDeriveCube( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_Cube_t * pCube, Vec_Int_t * vSupp, int fCompl ) +{ +    Vec_Int_t * vLits; +    Abc_Obj_t * pNodeNew, * pFanin; +    int i, iFanin, Lit; +    // create empty cube +    if ( pCube->nLits == 0 ) +    { +        if ( fCompl ) +            return Abc_NtkCreateNodeConst0(pNtkNew); +        return Abc_NtkCreateNodeConst1(pNtkNew); +    } +    // get the literals of this cube +    vLits = Vec_IntAlloc( 10 ); +    Min_CubeGetLits( pCube, vLits ); +    assert( pCube->nLits == (unsigned)vLits->nSize ); +    // create special case when there is only one literal +    if ( pCube->nLits == 1 ) +    { +        iFanin = Vec_IntEntry(vLits,0); +        pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); +        Lit = Min_CubeGetVar(pCube, iFanin); +        assert( Lit == 1 || Lit == 2 ); +        Vec_IntFree( vLits ); +        if ( (Lit == 1) ^ fCompl )// negative +            return Abc_NtkCreateNodeInv( pNtkNew, pFanin->pCopy ); +        return pFanin->pCopy; +    } +    assert( pCube->nLits > 1 ); +    // create the AND cube +    pNodeNew = Abc_NtkCreateNode( pNtkNew ); +    for ( i = 0; i < vLits->nSize; i++ ) +    { +        iFanin = Vec_IntEntry(vLits,i); +        pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); +        Lit = Min_CubeGetVar(pCube, iFanin); +        assert( Lit == 1 || Lit == 2 ); +        Vec_IntWriteEntry( vLits, i, Lit==1 ); +        Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); +    } +    pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, vLits->pArray ); +    if ( fCompl ) +        Abc_SopComplement( pNodeNew->pData ); +    Vec_IntFree( vLits ); +    return pNodeNew; +} + +/**Function************************************************************* + +  Synopsis    [Derives the decomposed network.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCovDeriveNode_rec( Cov_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int Level ) +{ +    Min_Cube_t * pCover, * pCube; +    Abc_Obj_t * pFaninNew, * pNodeNew, * pFanin; +    Vec_Int_t * vSupp; +    int Entry, nCubes, i; + +    if ( Abc_ObjIsCi(pObj) ) +        return pObj->pCopy; +    assert( Abc_ObjIsNode(pObj) ); +    // skip if already computed +    if ( pObj->pCopy ) +        return pObj->pCopy; + +    // get the support and the cover +    vSupp  = Abc_ObjGetSupp( pObj );  +    pCover = Abc_ObjGetCover2( pObj ); +    assert( vSupp ); +/* +    if ( pCover &&  pCover->nVars - Min_CoverSuppVarNum(p->pManMin, pCover) > 0 ) +    { +        printf( "%d\n ", pCover->nVars - Min_CoverSuppVarNum(p->pManMin, pCover) ); +        Min_CoverWrite( stdout, pCover ); +    } +*/ +/* +    // print the support of this node +    printf( "{ " ); +    Vec_IntForEachEntry( vSupp, Entry, i ) +        printf( "%d ", Entry ); +    printf( "}  cubes = %d\n", Min_CoverCountCubes( pCover ) ); +*/ +    // process the fanins +    Vec_IntForEachEntry( vSupp, Entry, i ) +    { +        pFanin = Abc_NtkObj(pObj->pNtk, Entry); +        Abc_NtkCovDeriveNode_rec( p, pNtkNew, pFanin, Level+1 ); +    } + +    // for each cube, construct the node +    nCubes = Min_CoverCountCubes( pCover ); +    if ( nCubes == 0 ) +        pNodeNew = Abc_NtkCreateNodeConst0(pNtkNew); +    else if ( nCubes == 1 ) +        pNodeNew = Abc_NtkCovDeriveCube( pNtkNew, pObj, pCover, vSupp, 0 ); +    else +    { +        pNodeNew = Abc_NtkCreateNode( pNtkNew ); +        Min_CoverForEachCube( pCover, pCube ) +        { +            pFaninNew = Abc_NtkCovDeriveCube( pNtkNew, pObj, pCube, vSupp, 0 ); +            Abc_ObjAddFanin( pNodeNew, pFaninNew ); +        } +        pNodeNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nCubes ); +    } +/* +    printf( "Created node %d(%d) at level %d: ", pNodeNew->Id, pObj->Id, Level ); +    Vec_IntForEachEntry( vSupp, Entry, i ) +    { +        pFanin = Abc_NtkObj(pObj->pNtk, Entry); +        printf( "%d(%d) ", pFanin->pCopy->Id, pFanin->Id ); +    } +    printf( "\n" ); +    Min_CoverWrite( stdout, pCover ); +*/ +    pObj->pCopy = pNodeNew; +    return pNodeNew; +} + +/**Function************************************************************* + +  Synopsis    [Derives the decomposed network.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCovDerive( Cov_Man_t * p, Abc_Ntk_t * pNtk ) +{ +    Abc_Ntk_t * pNtkNew; +    Abc_Obj_t * pObj; +    int i; +    assert( Abc_NtkIsStrash(pNtk) ); +    // perform strashing +    pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); +    // reconstruct the network +    Abc_NtkForEachCo( pNtk, pObj, i ) +    { +        Abc_NtkCovDeriveNode_rec( p, pNtkNew, Abc_ObjFanin0(pObj), 0 ); +//        printf( "*** CO %s : %d -> %d \n", Abc_ObjName(pObj), pObj->pCopy->Id, Abc_ObjFanin0(pObj)->pCopy->Id ); +    } +    // add the COs +    Abc_NtkFinalize( pNtk, pNtkNew ); +    Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 ); +    // make sure everything is okay +    if ( !Abc_NtkCheck( pNtkNew ) ) +    { +        printf( "Abc_NtkCovDerive: The network check has failed.\n" ); +        Abc_NtkDelete( pNtkNew ); +        return NULL; +    } +    return pNtkNew; +} + + + + +/**Function************************************************************* + +  Synopsis    [Derives the decomposed network.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCovDeriveInv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCompl ) +{ +    assert( pObj->pCopy ); +    if ( !fCompl ) +        return pObj->pCopy; +    if ( pObj->pCopy->pCopy == NULL ) +        pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy ); +    return pObj->pCopy->pCopy; + } + +/**Function************************************************************* + +  Synopsis    [Derives the decomposed network.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCovDeriveCubeInv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, Min_Cube_t * pCube, Vec_Int_t * vSupp ) +{ +    Vec_Int_t * vLits; +    Abc_Obj_t * pNodeNew, * pFanin; +    int i, iFanin, Lit; +    // create empty cube +    if ( pCube->nLits == 0 ) +        return Abc_NtkCreateNodeConst1(pNtkNew); +    // get the literals of this cube +    vLits = Vec_IntAlloc( 10 ); +    Min_CubeGetLits( pCube, vLits ); +    assert( pCube->nLits == (unsigned)vLits->nSize ); +    // create special case when there is only one literal +    if ( pCube->nLits == 1 ) +    { +        iFanin = Vec_IntEntry(vLits,0); +        pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); +        Lit = Min_CubeGetVar(pCube, iFanin); +        assert( Lit == 1 || Lit == 2 ); +        Vec_IntFree( vLits ); +//        if ( Lit == 1 )// negative +//            return Abc_NtkCreateNodeInv( pNtkNew, pFanin->pCopy ); +//        return pFanin->pCopy; +        return Abc_NtkCovDeriveInv( pNtkNew, pFanin, Lit==1 ); +    } +    assert( pCube->nLits > 1 ); +    // create the AND cube +    pNodeNew = Abc_NtkCreateNode( pNtkNew ); +    for ( i = 0; i < vLits->nSize; i++ ) +    { +        iFanin = Vec_IntEntry(vLits,i); +        pFanin = Abc_NtkObj( pObj->pNtk, Vec_IntEntry(vSupp, iFanin) ); +        Lit = Min_CubeGetVar(pCube, iFanin); +        assert( Lit == 1 || Lit == 2 ); +        Vec_IntWriteEntry( vLits, i, Lit==1 ); +//        Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); +        Abc_ObjAddFanin( pNodeNew, Abc_NtkCovDeriveInv( pNtkNew, pFanin, Lit==1 ) ); +    } +//    pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, vLits->pArray ); +    pNodeNew->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, vLits->nSize, NULL ); +    Vec_IntFree( vLits ); +    return pNodeNew; +} + +/**Function************************************************************* + +  Synopsis    [Derives the decomposed network.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCovDeriveNodeInv_rec( Cov_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCompl ) +{ +    Min_Cube_t * pCover, * pCube; +    Abc_Obj_t * pFaninNew, * pNodeNew, * pFanin; +    Vec_Int_t * vSupp; +    int Entry, nCubes, i; + +    // skip if already computed +    if ( pObj->pCopy ) +        return Abc_NtkCovDeriveInv( pNtkNew, pObj, fCompl ); +    assert( Abc_ObjIsNode(pObj) ); + +    // get the support and the cover +    vSupp  = Abc_ObjGetSupp( pObj );  +    pCover = Abc_ObjGetCover2( pObj ); +    assert( vSupp ); + +    // process the fanins +    Vec_IntForEachEntry( vSupp, Entry, i ) +    { +        pFanin = Abc_NtkObj(pObj->pNtk, Entry); +        Abc_NtkCovDeriveNodeInv_rec( p, pNtkNew, pFanin, 0 ); +    } + +    // for each cube, construct the node +    nCubes = Min_CoverCountCubes( pCover ); +    if ( nCubes == 0 ) +        pNodeNew = Abc_NtkCreateNodeConst0(pNtkNew); +    else if ( nCubes == 1 ) +        pNodeNew = Abc_NtkCovDeriveCubeInv( pNtkNew, pObj, pCover, vSupp ); +    else +    { +        pNodeNew = Abc_NtkCreateNode( pNtkNew ); +        Min_CoverForEachCube( pCover, pCube ) +        { +            pFaninNew = Abc_NtkCovDeriveCubeInv( pNtkNew, pObj, pCube, vSupp ); +            Abc_ObjAddFanin( pNodeNew, pFaninNew ); +        } +        pNodeNew->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, nCubes ); +    } + +    pObj->pCopy = pNodeNew; +    return Abc_NtkCovDeriveInv( pNtkNew, pObj, fCompl ); +} + +/**Function************************************************************* + +  Synopsis    [Derives the decomposed network.] + +  Description [The resulting network contains only pure AND/OR/EXOR gates +  and inverters. This procedure is usedful to generate Verilog.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCovDeriveClean( Cov_Man_t * p, Abc_Ntk_t * pNtk ) +{ +    Abc_Ntk_t * pNtkNew; +    Abc_Obj_t * pObj, * pNodeNew; +    int i; +    assert( Abc_NtkIsStrash(pNtk) ); +    // perform strashing +    pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); +    // reconstruct the network +    Abc_NtkForEachCo( pNtk, pObj, i ) +    { +        pNodeNew = Abc_NtkCovDeriveNodeInv_rec( p, pNtkNew, Abc_ObjFanin0(pObj), Abc_ObjFaninC0(pObj) ); +        Abc_ObjAddFanin( pObj->pCopy, pNodeNew ); +    } +    // add the COs +    Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); +    // make sure everything is okay +    if ( !Abc_NtkCheck( pNtkNew ) ) +    { +        printf( "Abc_NtkCovDeriveInv: The network check has failed.\n" ); +        Abc_NtkDelete( pNtkNew ); +        return NULL; +    } +    return pNtkNew; +} + + + +/**Function************************************************************* + +  Synopsis    [Derives the decomposed network.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkCovDerive_rec( Cov_Man_t * p, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ) +{ +    int fVerbose = 0; +    Min_Cube_t * pCover, * pCovers[3]; +    Abc_Obj_t * pNodeNew, * pFanin; +    Vec_Int_t * vSupp; +    Vec_Str_t * vCover; +    int i, Entry, nCubes, Type; +    // skip if already computed +    if ( pObj->pCopy ) +        return pObj->pCopy; +    assert( Abc_ObjIsNode(pObj) ); +    // get the support and the cover +    vSupp  = Abc_ObjGetSupp( pObj );  +    assert( vSupp ); +    // choose the cover to implement +    pCovers[0] = Abc_ObjGetCover( pObj, 0 ); +    pCovers[1] = Abc_ObjGetCover( pObj, 1 ); +    pCovers[2] = Abc_ObjGetCover2( pObj ); +    // use positive polarity +    if ( pCovers[0]  +        && (!pCovers[1] || Min_CoverCountCubes(pCovers[0]) <= Min_CoverCountCubes(pCovers[1])) +        && (!pCovers[2] || Min_CoverCountCubes(pCovers[0]) <= Min_CoverCountCubes(pCovers[2]))   ) +    { +        pCover = pCovers[0]; +        Type = '1'; +    } +    else  +    // use negative polarity +    if ( pCovers[1]  +        && (!pCovers[0] || Min_CoverCountCubes(pCovers[1]) <= Min_CoverCountCubes(pCovers[0])) +        && (!pCovers[2] || Min_CoverCountCubes(pCovers[1]) <= Min_CoverCountCubes(pCovers[2]))   ) +    { +        pCover = pCovers[1]; +        Type = '0'; +    } +    else  +    // use XOR polarity +    if ( pCovers[2]  +        && (!pCovers[0] || Min_CoverCountCubes(pCovers[2]) < Min_CoverCountCubes(pCovers[0])) +        && (!pCovers[1] || Min_CoverCountCubes(pCovers[2]) < Min_CoverCountCubes(pCovers[1]))   ) +    { +        pCover = pCovers[2]; +        Type = 'x'; +    } +    else +        assert( 0 ); +    // print the support of this node +    if ( fVerbose ) +    { +        printf( "{ " ); +        Vec_IntForEachEntry( vSupp, Entry, i ) +            printf( "%d ", Entry ); +        printf( "}  cubes = %d\n", Min_CoverCountCubes( pCover ) ); +    } +    // process the fanins +    Vec_IntForEachEntry( vSupp, Entry, i ) +    { +        pFanin = Abc_NtkObj(pObj->pNtk, Entry); +        Abc_NtkCovDerive_rec( p, pNtkNew, pFanin ); +    } +    // for each cube, construct the node +    nCubes = Min_CoverCountCubes( pCover ); +    if ( nCubes == 0 ) +        pNodeNew = Abc_NtkCreateNodeConst0(pNtkNew); +    else if ( nCubes == 1 ) +        pNodeNew = Abc_NtkCovDeriveCube( pNtkNew, pObj, pCover, vSupp, Type == '0' ); +    else +    { +        // create the node +        pNodeNew = Abc_NtkCreateNode( pNtkNew ); +        Vec_IntForEachEntry( vSupp, Entry, i ) +        { +            pFanin = Abc_NtkObj(pObj->pNtk, Entry); +            Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); +        } +        // derive the function +        vCover = Vec_StrAlloc( 100 ); +        Min_CoverCreate( vCover, pCover, (char)Type ); +        pNodeNew->pData = Abc_SopRegister( pNtkNew->pManFunc, Vec_StrArray(vCover) ); +        Vec_StrFree( vCover ); +    } + +/* +    printf( "Created node %d(%d) at level %d: ", pNodeNew->Id, pObj->Id, Level ); +    Vec_IntForEachEntry( vSupp, Entry, i ) +    { +        pFanin = Abc_NtkObj(pObj->pNtk, Entry); +        printf( "%d(%d) ", pFanin->pCopy->Id, pFanin->Id ); +    } +    printf( "\n" ); +    Min_CoverWrite( stdout, pCover ); +*/ +    return pObj->pCopy = pNodeNew; +} + +/**Function************************************************************* + +  Synopsis    [Derives the decomposed network.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCovDeriveRegular( Cov_Man_t * p, Abc_Ntk_t * pNtk ) +{ +    Abc_Ntk_t * pNtkNew; +    Abc_Obj_t * pObj, * pNodeNew; +    int i; +    assert( Abc_NtkIsStrash(pNtk) ); +    // perform strashing +    pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); +    // reconstruct the network +    if ( Abc_ObjFanoutNum(Abc_AigConst1(pNtk)) > 0 ) +        Abc_AigConst1(pNtk)->pCopy = Abc_NtkCreateNodeConst1(pNtkNew); +    Abc_NtkForEachCo( pNtk, pObj, i ) +    { +        pNodeNew = Abc_NtkCovDerive_rec( p, pNtkNew, Abc_ObjFanin0(pObj) ); +        if ( Abc_ObjFaninC0(pObj) ) +        { +            if ( pNodeNew->pData && Abc_ObjFanoutNum(Abc_ObjFanin0(pObj)) == 1 ) +                Abc_SopComplement( pNodeNew->pData ); +            else +                pNodeNew = Abc_NtkCreateNodeInv( pNtkNew, pNodeNew ); +        } +        Abc_ObjAddFanin( pObj->pCopy, pNodeNew ); +    } +    // add the COs +    Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 ); +    // make sure everything is okay +    if ( !Abc_NtkCheck( pNtkNew ) ) +    { +        printf( "Abc_NtkCovDerive: The network check has failed.\n" ); +        Abc_NtkDelete( pNtkNew ); +        return NULL; +    } +    return pNtkNew; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covCore.c b/src/map/cov/covCore.c new file mode 100644 index 00000000..e36a4d2d --- /dev/null +++ b/src/map/cov/covCore.c @@ -0,0 +1,1023 @@ +/**CFile**************************************************************** + +  FileName    [covCore.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Mapping into network of SOPs/ESOPs.] + +  Synopsis    [Core procedures.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: covCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cov.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +static void         Abc_NtkCovCovers( Cov_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ); +static int          Abc_NtkCovCoversOne( Cov_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ); +static void         Abc_NtkCovCovers_rec( Cov_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vBoundary ); +/* +static int          Abc_NodeCovPropagateEsop( Cov_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ); +static int          Abc_NodeCovPropagateSop( Cov_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ); +static int          Abc_NodeCovUnionEsop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); +static int          Abc_NodeCovUnionSop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); +static int          Abc_NodeCovProductEsop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); +static int          Abc_NodeCovProductSop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ); +*/ +static int          Abc_NodeCovPropagate( Cov_Man_t * p, Abc_Obj_t * pObj ); +static Min_Cube_t * Abc_NodeCovProduct( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ); +static Min_Cube_t * Abc_NodeCovSum( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ); + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Performs decomposition.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkSopEsopCover( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose ) +{ +    Abc_Ntk_t * pNtkNew; +    Cov_Man_t * p; + +    assert( Abc_NtkIsStrash(pNtk) ); + +    // create the manager +    p = Cov_ManAlloc( pNtk, nFaninMax ); +    p->fUseEsop = fUseEsop; +    p->fUseSop  = fUseSop; +    pNtk->pManCut = p; + +    // perform mapping +    Abc_NtkCovCovers( p, pNtk, fVerbose ); + +    // derive the final network +//    if ( fUseInvs ) +//        pNtkNew = Abc_NtkCovDeriveClean( p, pNtk ); +//      else +//       pNtkNew = Abc_NtkCovDerive( p, pNtk ); +//    pNtkNew = NULL; +    pNtkNew = Abc_NtkCovDeriveRegular( p, pNtk ); + +    Cov_ManFree( p ); +    pNtk->pManCut = NULL; + +    // make sure that everything is okay +    if ( pNtkNew && !Abc_NtkCheck( pNtkNew ) ) +    { +        printf( "Abc_NtkCov: The network check has failed.\n" ); +        Abc_NtkDelete( pNtkNew ); +        return NULL; +    } +    return pNtkNew; +} + +/**Function************************************************************* + +  Synopsis    [Compute the supports.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Abc_NtkCovCovers( Cov_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ) +{ +    Abc_Obj_t * pObj; +    int i, clk = clock(); + +    // start the manager +    p->vFanCounts = Abc_NtkFanoutCounts(pNtk); + +    // set trivial cuts for the constant and the CIs +    pObj = Abc_AigConst1(pNtk); +    pObj->fMarkA = 1; +    Abc_NtkForEachCi( pNtk, pObj, i ) +        pObj->fMarkA = 1; + +    // perform iterative decomposition +    for ( i = 0; ; i++ ) +    { +        if ( fVerbose ) +        printf( "Iter %d : ", i+1 ); +        if ( Abc_NtkCovCoversOne(p, pNtk, fVerbose) ) +            break; +    } + +    // clean the cut-point markers +    Abc_NtkForEachObj( pNtk, pObj, i ) +        pObj->fMarkA = 0; + +if ( fVerbose ) +{ +ABC_PRT( "Total", clock() - clk ); +} +} + +/**Function************************************************************* + +  Synopsis    [Compute the supports.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Abc_NtkCovCoversOne( Cov_Man_t * p, Abc_Ntk_t * pNtk, bool fVerbose ) +{ +    ProgressBar * pProgress; +    Abc_Obj_t * pObj; +    Vec_Ptr_t * vBoundary; +    int i, clk = clock(); +    int Counter = 0; +    int fStop = 1; + +    // array to collect the nodes in the new boundary +    vBoundary = Vec_PtrAlloc( 100 ); + +    // start from the COs and mark visited nodes using pObj->fMarkB +    pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) ); +    Abc_NtkForEachCo( pNtk, pObj, i ) +    { +        Extra_ProgressBarUpdate( pProgress, i, NULL ); +        // skip the solved nodes (including the CIs) +        pObj = Abc_ObjFanin0(pObj); +        if ( pObj->fMarkA ) +        { +            Counter++; +            continue; +        }  + +        // traverse the cone starting from this node +        if ( Abc_ObjGetSupp(pObj) == NULL ) +            Abc_NtkCovCovers_rec( p, pObj, vBoundary ); + +        // count the number of solved cones +        if ( Abc_ObjGetSupp(pObj) == NULL ) +            fStop = 0; +        else +            Counter++; + +/* +        printf( "%-15s : ", Abc_ObjName(pObj) );  +        printf( "lev = %5d  ", pObj->Level ); +        if ( Abc_ObjGetSupp(pObj) == NULL ) +        { +            printf( "\n" ); +            continue; +        } +        printf( "supp = %3d  ", Abc_ObjGetSupp(pObj)->nSize );  +        printf( "esop = %3d  ", Min_CoverCountCubes( Abc_ObjGetCover2(pObj) ) );  +        printf( "\n" ); +*/ +    } +    Extra_ProgressBarStop( pProgress ); + +    // clean visited nodes +    Abc_NtkForEachObj( pNtk, pObj, i ) +        pObj->fMarkB = 0; + +    // create the new boundary +    p->nBoundary = 0; +    Vec_PtrForEachEntry( vBoundary, pObj, i ) +    { +        if ( !pObj->fMarkA ) +        { +            pObj->fMarkA = 1; +            p->nBoundary++; +        } +    } +    Vec_PtrFree( vBoundary ); + +if ( fVerbose ) +{ +    printf( "Outs = %4d (%4d) Node = %6d (%6d) Max = %6d  Bound = %4d  ",  +        Counter, Abc_NtkCoNum(pNtk), p->nSupps, Abc_NtkNodeNum(pNtk), p->nSuppsMax, p->nBoundary ); +ABC_PRT( "T", clock() - clk ); +} +    return fStop; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Abc_NtkCovCovers_rec( Cov_Man_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vBoundary ) +{ +    Abc_Obj_t * pObj0, * pObj1; +    // return if the support is already computed +    if ( pObj->fMarkB || pObj->fMarkA )//|| Abc_ObjGetSupp(pObj) ) // why do we need Supp check here??? +        return; +    // mark as visited +    pObj->fMarkB = 1; +    // get the fanins +    pObj0 = Abc_ObjFanin0(pObj); +    pObj1 = Abc_ObjFanin1(pObj); +    // solve for the fanins +    Abc_NtkCovCovers_rec( p, pObj0, vBoundary ); +    Abc_NtkCovCovers_rec( p, pObj1, vBoundary ); +    // skip the node that spaced out +    if ( !pObj0->fMarkA && !Abc_ObjGetSupp(pObj0) ||  // fanin is not ready +         !pObj1->fMarkA && !Abc_ObjGetSupp(pObj1) ||  // fanin is not ready +         !Abc_NodeCovPropagate( p, pObj ) )           // node's support or covers cannot be computed +    { +        // save the nodes of the future boundary +        if ( !pObj0->fMarkA && Abc_ObjGetSupp(pObj0) ) +            Vec_PtrPush( vBoundary, pObj0 ); +        if ( !pObj1->fMarkA && Abc_ObjGetSupp(pObj1) ) +            Vec_PtrPush( vBoundary, pObj1 ); +        return; +    } +    // consider dropping the fanin supports +//    Abc_NodeCovDropData( p, pObj0 ); +//    Abc_NodeCovDropData( p, pObj1 ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Vec_Int_t * Abc_NodeCovSupport( Cov_Man_t * p, Vec_Int_t * vSupp0, Vec_Int_t * vSupp1 ) +{ +    Vec_Int_t * vSupp; +    int k0, k1; + +    assert( vSupp0 && vSupp1 ); +    Vec_IntFill( p->vComTo0, vSupp0->nSize + vSupp1->nSize, -1 ); +    Vec_IntFill( p->vComTo1, vSupp0->nSize + vSupp1->nSize, -1 ); +    Vec_IntClear( p->vPairs0 ); +    Vec_IntClear( p->vPairs1 ); + +    vSupp = Vec_IntAlloc( vSupp0->nSize + vSupp1->nSize ); +    for ( k0 = k1 = 0; k0 < vSupp0->nSize && k1 < vSupp1->nSize; ) +    { +        if ( vSupp0->pArray[k0] == vSupp1->pArray[k1] ) +        { +            Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); +            Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); +            Vec_IntPush( p->vPairs0, k0 ); +            Vec_IntPush( p->vPairs1, k1 ); +            Vec_IntPush( vSupp, vSupp0->pArray[k0] ); +            k0++; k1++; +        } +        else if ( vSupp0->pArray[k0] < vSupp1->pArray[k1] ) +        { +            Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); +            Vec_IntPush( vSupp, vSupp0->pArray[k0] ); +            k0++; +        } +        else  +        { +            Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); +            Vec_IntPush( vSupp, vSupp1->pArray[k1] ); +            k1++; +        } +    } +    for ( ; k0 < vSupp0->nSize; k0++ ) +    { +        Vec_IntWriteEntry( p->vComTo0, vSupp->nSize, k0 ); +        Vec_IntPush( vSupp, vSupp0->pArray[k0] ); +    } +    for ( ; k1 < vSupp1->nSize; k1++ ) +    { +        Vec_IntWriteEntry( p->vComTo1, vSupp->nSize, k1 ); +        Vec_IntPush( vSupp, vSupp1->pArray[k1] ); +    } +/* +    printf( "Zero : " ); +    for ( k0 = 0; k0 < vSupp0->nSize; k0++ ) +        printf( "%d ", vSupp0->pArray[k0] ); +    printf( "\n" ); + +    printf( "One  : " ); +    for ( k1 = 0; k1 < vSupp1->nSize; k1++ ) +        printf( "%d ", vSupp1->pArray[k1] ); +    printf( "\n" ); + +    printf( "Sum  : " ); +    for ( k0 = 0; k0 < vSupp->nSize; k0++ ) +        printf( "%d ", vSupp->pArray[k0] ); +    printf( "\n" ); +    printf( "\n" ); +*/ +    return vSupp; +} + +/**Function************************************************************* + +  Synopsis    [Propagates all types of covers.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Abc_NodeCovPropagate( Cov_Man_t * p, Abc_Obj_t * pObj ) +{ +    Min_Cube_t * pCoverP = NULL, * pCoverN = NULL, * pCoverX = NULL; +    Min_Cube_t * pCov0, * pCov1, * pCover0, * pCover1; +    Vec_Int_t * vSupp, * vSupp0, * vSupp1; +    Abc_Obj_t * pObj0, * pObj1; +    int fCompl0, fCompl1; + +    pObj0 = Abc_ObjFanin0( pObj ); +    pObj1 = Abc_ObjFanin1( pObj ); + +    if ( pObj0->fMarkA )  Vec_IntWriteEntry( p->vTriv0, 0, pObj0->Id ); +    if ( pObj1->fMarkA )  Vec_IntWriteEntry( p->vTriv1, 0, pObj1->Id ); +  +    // get the resulting support +    vSupp0 = pObj0->fMarkA? p->vTriv0 : Abc_ObjGetSupp(pObj0); +    vSupp1 = pObj1->fMarkA? p->vTriv1 : Abc_ObjGetSupp(pObj1); +    vSupp  = Abc_NodeCovSupport( p, vSupp0, vSupp1 ); + +    // quit if support if too large +    if ( vSupp->nSize > p->nFaninMax ) +    { +        Vec_IntFree( vSupp ); +        return 0; +    } + +    // get the complemented attributes +    fCompl0 = Abc_ObjFaninC0( pObj ); +    fCompl1 = Abc_ObjFaninC1( pObj ); + +    // propagate ESOP +    if ( p->fUseEsop ) +    { +        // get the covers +        pCov0 = pObj0->fMarkA? p->pManMin->pTriv0[0] : Abc_ObjGetCover2(pObj0); +        pCov1 = pObj1->fMarkA? p->pManMin->pTriv1[0] : Abc_ObjGetCover2(pObj1); +        if ( pCov0 && pCov1 ) +        { +            // complement the first if needed +            if ( !fCompl0 ) +                pCover0 = pCov0; +            else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube +                pCover0 = pCov0->pNext; +            else +                pCover0 = p->pManMin->pOne0, p->pManMin->pOne0->pNext = pCov0; + +            // complement the second if needed +            if ( !fCompl1 ) +                pCover1 = pCov1; +            else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube +                pCover1 = pCov1->pNext; +            else +                pCover1 = p->pManMin->pOne1, p->pManMin->pOne1->pNext = pCov1; + +            // derive the new cover +            pCoverX = Abc_NodeCovProduct( p, pCover0, pCover1, 1, vSupp->nSize ); +        } +    } +    // propagate SOPs +    if ( p->fUseSop ) +    { +        // get the covers for the direct polarity +        pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[fCompl0] : Abc_ObjGetCover(pObj0, fCompl0); +        pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[fCompl1] : Abc_ObjGetCover(pObj1, fCompl1); +        // derive the new cover +        if ( pCover0 && pCover1 ) +            pCoverP = Abc_NodeCovProduct( p, pCover0, pCover1, 0, vSupp->nSize ); + +        // get the covers for the inverse polarity +        pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[!fCompl0] : Abc_ObjGetCover(pObj0, !fCompl0); +        pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[!fCompl1] : Abc_ObjGetCover(pObj1, !fCompl1); +        // derive the new cover +        if ( pCover0 && pCover1 ) +            pCoverN = Abc_NodeCovSum( p, pCover0, pCover1, 0, vSupp->nSize ); +    } + +    // if none of the covers can be computed quit +    if ( !pCoverX && !pCoverP && !pCoverN ) +    { +        Vec_IntFree( vSupp ); +        return 0; +    } + +    // set the covers +    assert( Abc_ObjGetSupp(pObj) == NULL ); +    Abc_ObjSetSupp( pObj, vSupp ); +    Abc_ObjSetCover( pObj, pCoverP, 0 ); +    Abc_ObjSetCover( pObj, pCoverN, 1 ); +    Abc_ObjSetCover2( pObj, pCoverX ); +//printf( "%3d : %4d  %4d  %4d\n", pObj->Id, Min_CoverCountCubes(pCoverP), Min_CoverCountCubes(pCoverN), Min_CoverCountCubes(pCoverX) ); + +    // count statistics +    p->nSupps++; +    p->nSuppsMax = ABC_MAX( p->nSuppsMax, p->nSupps ); +    return 1; +} + + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Min_Cube_t * Abc_NodeCovProduct( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ) +{ +    Min_Cube_t * pCube, * pCube0, * pCube1; +    Min_Cube_t * pCover; +    int i, Val0, Val1; +    assert( pCover0 && pCover1 ); + +    // clean storage +    Min_ManClean( p->pManMin, nSupp ); +    // go through the cube pairs +    Min_CoverForEachCube( pCover0, pCube0 ) +    Min_CoverForEachCube( pCover1, pCube1 ) +    { +        // go through the support variables of the cubes +        for ( i = 0; i < p->vPairs0->nSize; i++ ) +        { +            Val0 = Min_CubeGetVar( pCube0, p->vPairs0->pArray[i] ); +            Val1 = Min_CubeGetVar( pCube1, p->vPairs1->pArray[i] ); +            if ( (Val0 & Val1) == 0 ) +                break; +        } +        // check disjointness +        if ( i < p->vPairs0->nSize ) +            continue; + +        if ( p->pManMin->nCubes > p->nCubesMax ) +        { +            pCover = Min_CoverCollect( p->pManMin, nSupp ); +//Min_CoverWriteFile( pCover, "large", 1 ); +            Min_CoverRecycle( p->pManMin, pCover ); +            return NULL; +        } + +        // create the product cube +        pCube = Min_CubeAlloc( p->pManMin ); + +        // add the literals +        pCube->nLits = 0; +        for ( i = 0; i < nSupp; i++ ) +        { +            if ( p->vComTo0->pArray[i] == -1 ) +                Val0 = 3; +            else +                Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); + +            if ( p->vComTo1->pArray[i] == -1 ) +                Val1 = 3; +            else +                Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); + +            if ( (Val0 & Val1) == 3 ) +                continue; + +            Min_CubeXorVar( pCube, i, (Val0 & Val1) ^ 3 ); +            pCube->nLits++; +        } +        // add the cube to storage +        if ( fEsop )  +            Min_EsopAddCube( p->pManMin, pCube ); +        else +            Min_SopAddCube( p->pManMin, pCube ); +    } + +    // minimize the cover +    if ( fEsop )  +        Min_EsopMinimize( p->pManMin ); +    else +        Min_SopMinimize( p->pManMin ); +    pCover = Min_CoverCollect( p->pManMin, nSupp ); + +    // quit if the cover is too large +    if ( Min_CoverCountCubes(pCover) > p->nFaninMax ) +    { +/*         +Min_CoverWriteFile( pCover, "large", 1 ); +        Min_CoverExpand( p->pManMin, pCover ); +        Min_EsopMinimize( p->pManMin ); +        Min_EsopMinimize( p->pManMin ); +        Min_EsopMinimize( p->pManMin ); +        Min_EsopMinimize( p->pManMin ); +        Min_EsopMinimize( p->pManMin ); +        Min_EsopMinimize( p->pManMin ); +        Min_EsopMinimize( p->pManMin ); +        Min_EsopMinimize( p->pManMin ); +        Min_EsopMinimize( p->pManMin ); +        pCover = Min_CoverCollect( p->pManMin, nSupp ); +*/ +        Min_CoverRecycle( p->pManMin, pCover ); +        return NULL; +    } +    return pCover; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Min_Cube_t * Abc_NodeCovSum( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int fEsop, int nSupp ) +{ +    Min_Cube_t * pCube, * pCube0, * pCube1; +    Min_Cube_t * pCover; +    int i, Val0, Val1; +    assert( pCover0 && pCover1 ); + +    // clean storage +    Min_ManClean( p->pManMin, nSupp ); +    Min_CoverForEachCube( pCover0, pCube0 ) +    { +        // create the cube +        pCube = Min_CubeAlloc( p->pManMin ); +        pCube->nLits = 0; +        for ( i = 0; i < p->vComTo0->nSize; i++ ) +        { +            if ( p->vComTo0->pArray[i] == -1 ) +                continue; +            Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); +            if ( Val0 == 3 ) +                continue; +            Min_CubeXorVar( pCube, i, Val0 ^ 3 ); +            pCube->nLits++; +        } +        if ( p->pManMin->nCubes > p->nCubesMax ) +        { +            pCover = Min_CoverCollect( p->pManMin, nSupp ); +            Min_CoverRecycle( p->pManMin, pCover ); +            return NULL; +        } +        // add the cube to storage +        if ( fEsop ) +            Min_EsopAddCube( p->pManMin, pCube ); +        else +            Min_SopAddCube( p->pManMin, pCube ); +    } +    Min_CoverForEachCube( pCover1, pCube1 ) +    { +        // create the cube +        pCube = Min_CubeAlloc( p->pManMin ); +        pCube->nLits = 0; +        for ( i = 0; i < p->vComTo1->nSize; i++ ) +        { +            if ( p->vComTo1->pArray[i] == -1 ) +                continue; +            Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); +            if ( Val1 == 3 ) +                continue; +            Min_CubeXorVar( pCube, i, Val1 ^ 3 ); +            pCube->nLits++; +        } +        if ( p->pManMin->nCubes > p->nCubesMax ) +        { +            pCover = Min_CoverCollect( p->pManMin, nSupp ); +            Min_CoverRecycle( p->pManMin, pCover ); +            return NULL; +        } +        // add the cube to storage +        if ( fEsop ) +            Min_EsopAddCube( p->pManMin, pCube ); +        else +            Min_SopAddCube( p->pManMin, pCube ); +    } + +    // minimize the cover +    if ( fEsop )  +        Min_EsopMinimize( p->pManMin ); +    else +        Min_SopMinimize( p->pManMin ); +    pCover = Min_CoverCollect( p->pManMin, nSupp ); + +    // quit if the cover is too large +    if ( Min_CoverCountCubes(pCover) > p->nFaninMax ) +    { +        Min_CoverRecycle( p->pManMin, pCover ); +        return NULL; +    } +    return pCover; +} + + + + + + + +#if 0 + + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Abc_NodeCovPropagateEsop( Cov_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ) +{ +    Min_Cube_t * pCover, * pCover0, * pCover1, * pCov0, * pCov1; +    Vec_Int_t * vSupp, * vSupp0, * vSupp1; + +    if ( pObj0->fMarkA )  Vec_IntWriteEntry( p->vTriv0, 0, pObj0->Id ); +    if ( pObj1->fMarkA )  Vec_IntWriteEntry( p->vTriv1, 0, pObj1->Id ); + +    // get the resulting support +    vSupp0 = pObj0->fMarkA? p->vTriv0 : Abc_ObjGetSupp(pObj0); +    vSupp1 = pObj1->fMarkA? p->vTriv1 : Abc_ObjGetSupp(pObj1); +    vSupp  = Abc_NodeCovSupport( p, vSupp0, vSupp1 ); + +    // quit if support if too large +    if ( vSupp->nSize > p->nFaninMax ) +    { +        Vec_IntFree( vSupp ); +        return 0; +    } +    +    // get the covers +    pCov0 = pObj0->fMarkA? p->pManMin->pTriv0[0] : Abc_ObjGetCover2(pObj0); +    pCov1 = pObj1->fMarkA? p->pManMin->pTriv1[0] : Abc_ObjGetCover2(pObj1); + +    // complement the first if needed +    if ( !Abc_ObjFaninC0(pObj) ) +        pCover0 = pCov0; +    else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube +        pCover0 = pCov0->pNext; +    else +        pCover0 = p->pManMin->pOne0, p->pManMin->pOne0->pNext = pCov0; + +    // complement the second if needed +    if ( !Abc_ObjFaninC1(pObj) ) +        pCover1 = pCov1; +    else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube +        pCover1 = pCov1->pNext; +    else +        pCover1 = p->pManMin->pOne1, p->pManMin->pOne1->pNext = pCov1; + +    // derive and minimize the cover (quit if too large) +    if ( !Abc_NodeCovProductEsop( p, pCover0, pCover1, vSupp->nSize ) ) +    { +        pCover = Min_CoverCollect( p->pManMin, vSupp->nSize ); +        Min_CoverRecycle( p->pManMin, pCover ); +        Vec_IntFree( vSupp ); +        return 0; +    } + +    // minimize the cover +    Min_EsopMinimize( p->pManMin ); +    pCover = Min_CoverCollect( p->pManMin, vSupp->nSize ); + +    // quit if the cover is too large +    if ( Min_CoverCountCubes(pCover) > p->nFaninMax ) +    { +        Min_CoverRecycle( p->pManMin, pCover ); +        Vec_IntFree( vSupp ); +        return 0; +    } + +    // count statistics +    p->nSupps++; +    p->nSuppsMax = ABC_MAX( p->nSuppsMax, p->nSupps ); + +    // set the covers +    assert( Abc_ObjGetSupp(pObj) == NULL ); +    Abc_ObjSetSupp( pObj, vSupp ); +    Abc_ObjSetCover2( pObj, pCover ); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Abc_NodeCovPropagateSop( Cov_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 ) +{ +    Min_Cube_t * pCoverP, * pCoverN, * pCover0, * pCover1; +    Vec_Int_t * vSupp, * vSupp0, * vSupp1; +    int fCompl0, fCompl1; + +    if ( pObj0->fMarkA )  Vec_IntWriteEntry( p->vTriv0, 0, pObj0->Id ); +    if ( pObj1->fMarkA )  Vec_IntWriteEntry( p->vTriv1, 0, pObj1->Id ); + +    // get the resulting support +    vSupp0 = pObj0->fMarkA? p->vTriv0 : Abc_ObjGetSupp(pObj0); +    vSupp1 = pObj1->fMarkA? p->vTriv1 : Abc_ObjGetSupp(pObj1); +    vSupp  = Abc_NodeCovSupport( p, vSupp0, vSupp1 ); + +    // quit if support if too large +    if ( vSupp->nSize > p->nFaninMax ) +    { +        Vec_IntFree( vSupp ); +        return 0; +    } + +    // get the complemented attributes +    fCompl0 = Abc_ObjFaninC0(pObj); +    fCompl1 = Abc_ObjFaninC1(pObj); +    +    // prepare the positive cover +    pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[fCompl0] : Abc_ObjGetCover(pObj0, fCompl0); +    pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[fCompl1] : Abc_ObjGetCover(pObj1, fCompl1); + +    // derive and minimize the cover (quit if too large) +    if ( !pCover0 || !pCover1 ) +        pCoverP = NULL; +    else if ( !Abc_NodeCovProductSop( p, pCover0, pCover1, vSupp->nSize ) ) +    { +        pCoverP = Min_CoverCollect( p->pManMin, vSupp->nSize ); +        Min_CoverRecycle( p->pManMin, pCoverP ); +        pCoverP = NULL; +    } +    else +    { +        Min_SopMinimize( p->pManMin ); +        pCoverP = Min_CoverCollect( p->pManMin, vSupp->nSize ); +        // quit if the cover is too large +        if ( Min_CoverCountCubes(pCoverP) > p->nFaninMax ) +        { +            Min_CoverRecycle( p->pManMin, pCoverP ); +            pCoverP = NULL; +        } +    } +    +    // prepare the negative cover +    pCover0 = pObj0->fMarkA? p->pManMin->pTriv0[!fCompl0] : Abc_ObjGetCover(pObj0, !fCompl0); +    pCover1 = pObj1->fMarkA? p->pManMin->pTriv1[!fCompl1] : Abc_ObjGetCover(pObj1, !fCompl1); + +    // derive and minimize the cover (quit if too large) +    if ( !pCover0 || !pCover1 ) +        pCoverN = NULL; +    else if ( !Abc_NodeCovUnionSop( p, pCover0, pCover1, vSupp->nSize ) ) +    { +        pCoverN = Min_CoverCollect( p->pManMin, vSupp->nSize ); +        Min_CoverRecycle( p->pManMin, pCoverN ); +        pCoverN = NULL; +    } +    else +    { +        Min_SopMinimize( p->pManMin ); +        pCoverN = Min_CoverCollect( p->pManMin, vSupp->nSize ); +        // quit if the cover is too large +        if ( Min_CoverCountCubes(pCoverN) > p->nFaninMax ) +        { +            Min_CoverRecycle( p->pManMin, pCoverN ); +            pCoverN = NULL; +        } +    } + +    if ( pCoverP == NULL && pCoverN == NULL ) +    { +        Vec_IntFree( vSupp ); +        return 0; +    } + +    // count statistics +    p->nSupps++; +    p->nSuppsMax = ABC_MAX( p->nSuppsMax, p->nSupps ); + +    // set the covers +    assert( Abc_ObjGetSupp(pObj) == NULL ); +    Abc_ObjSetSupp( pObj, vSupp ); +    Abc_ObjSetCover( pObj, pCoverP, 0 ); +    Abc_ObjSetCover( pObj, pCoverN, 1 ); +    return 1; +} + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Abc_NodeCovProductEsop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) +{ +    Min_Cube_t * pCube, * pCube0, * pCube1; +    int i, Val0, Val1; + +    // clean storage +    Min_ManClean( p->pManMin, nSupp ); +    if ( pCover0 == NULL || pCover1 == NULL ) +        return 1; + +    // go through the cube pairs +    Min_CoverForEachCube( pCover0, pCube0 ) +    Min_CoverForEachCube( pCover1, pCube1 ) +    { +        // go through the support variables of the cubes +        for ( i = 0; i < p->vPairs0->nSize; i++ ) +        { +            Val0 = Min_CubeGetVar( pCube0, p->vPairs0->pArray[i] ); +            Val1 = Min_CubeGetVar( pCube1, p->vPairs1->pArray[i] ); +            if ( (Val0 & Val1) == 0 ) +                break; +        } +        // check disjointness +        if ( i < p->vPairs0->nSize ) +            continue; + +        if ( p->pManMin->nCubes >= p->nCubesMax ) +            return 0; + +        // create the product cube +        pCube = Min_CubeAlloc( p->pManMin ); + +        // add the literals +        pCube->nLits = 0; +        for ( i = 0; i < nSupp; i++ ) +        { +            if ( p->vComTo0->pArray[i] == -1 ) +                Val0 = 3; +            else +                Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); + +            if ( p->vComTo1->pArray[i] == -1 ) +                Val1 = 3; +            else +                Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); + +            if ( (Val0 & Val1) == 3 ) +                continue; + +            Min_CubeXorVar( pCube, i, (Val0 & Val1) ^ 3 ); +            pCube->nLits++; +        } +        // add the cube to storage +        Min_EsopAddCube( p->pManMin, pCube ); +    } +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Abc_NodeCovProductSop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) +{ +    return 1; +} + + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Abc_NodeCovUnionEsop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) +{ +    Min_Cube_t * pCube, * pCube0, * pCube1; +    int i, Val0, Val1; + +    // clean storage +    Min_ManClean( p->pManMin, nSupp ); +    if ( pCover0 ) +    { +        Min_CoverForEachCube( pCover0, pCube0 ) +        { +            // create the cube +            pCube = Min_CubeAlloc( p->pManMin ); +            pCube->nLits = 0; +            for ( i = 0; i < p->vComTo0->nSize; i++ ) +            { +                if ( p->vComTo0->pArray[i] == -1 ) +                    continue; +                Val0 = Min_CubeGetVar( pCube0, p->vComTo0->pArray[i] ); +                if ( Val0 == 3 ) +                    continue; +                Min_CubeXorVar( pCube, i, Val0 ^ 3 ); +                pCube->nLits++; +            } +            if ( p->pManMin->nCubes >= p->nCubesMax ) +                return 0; +            // add the cube to storage +            Min_EsopAddCube( p->pManMin, pCube ); +        } +    } +    if ( pCover1 ) +    { +        Min_CoverForEachCube( pCover1, pCube1 ) +        { +            // create the cube +            pCube = Min_CubeAlloc( p->pManMin ); +            pCube->nLits = 0; +            for ( i = 0; i < p->vComTo1->nSize; i++ ) +            { +                if ( p->vComTo1->pArray[i] == -1 ) +                    continue; +                Val1 = Min_CubeGetVar( pCube1, p->vComTo1->pArray[i] ); +                if ( Val1 == 3 ) +                    continue; +                Min_CubeXorVar( pCube, i, Val1 ^ 3 ); +                pCube->nLits++; +            } +            if ( p->pManMin->nCubes >= p->nCubesMax ) +                return 0; +            // add the cube to storage +            Min_EsopAddCube( p->pManMin, pCube ); +        } +    } +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Abc_NodeCovUnionSop( Cov_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1, int nSupp ) +{ +    return 1; +} + + +#endif + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covInt.h b/src/map/cov/covInt.h new file mode 100644 index 00000000..a06519c0 --- /dev/null +++ b/src/map/cov/covInt.h @@ -0,0 +1,643 @@ +/**CFile**************************************************************** + +  FileName    [covInt.h] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Mapping into network of SOPs/ESOPs.] + +  Synopsis    [Internal declarations.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: covInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Min_Man_t_  Min_Man_t; +typedef struct Min_Cube_t_ Min_Cube_t; + +struct Min_Man_t_ +{ +    int               nVars;          // the number of vars +    int               nWords;         // the number of words +    Extra_MmFixed_t * pMemMan;        // memory manager for cubes +    // temporary cubes +    Min_Cube_t *      pOne0;          // tautology cube +    Min_Cube_t *      pOne1;          // tautology cube +    Min_Cube_t *      pTriv0[2];      // trivial cube +    Min_Cube_t *      pTriv1[2];      // trivial cube +    Min_Cube_t *      pTemp;          // cube for computing the distance +    Min_Cube_t *      pBubble;        // cube used as a separator +    // temporary storage for the new cover +    int               nCubes;         // the number of cubes +    Min_Cube_t **     ppStore;        // storage for cubes by number of literals +}; + +struct Min_Cube_t_ +{ +    Min_Cube_t *      pNext;          // the pointer to the next cube in the cover +    unsigned          nVars    : 10;  // the number of variables +    unsigned          nWords   : 12;  // the number of machine words +    unsigned          nLits    : 10;  // the number of literals in the cube +    unsigned          uData[1];       // the bit-data for the cube +}; + + +// iterators through the entries in the linked lists of cubes +#define Min_CoverForEachCube( pCover, pCube )                   \ +    for ( pCube = pCover;                                       \ +          pCube;                                                \ +          pCube = pCube->pNext ) +#define Min_CoverForEachCubeSafe( pCover, pCube, pCube2 )       \ +    for ( pCube = pCover,                                       \ +          pCube2 = pCube? pCube->pNext: NULL;                   \ +          pCube;                                                \ +          pCube = pCube2,                                       \ +          pCube2 = pCube? pCube->pNext: NULL ) +#define Min_CoverForEachCubePrev( pCover, pCube, ppPrev )       \ +    for ( pCube = pCover,                                       \ +          ppPrev = &(pCover);                                   \ +          pCube;                                                \ +          ppPrev = &pCube->pNext,                               \ +          pCube = pCube->pNext ) + +// macros to get hold of bits and values in the cubes +static inline int  Min_CubeHasBit( Min_Cube_t * p, int i )              { return (p->uData[(i)>>5] & (1<<((i) & 31))) > 0;     } +static inline void Min_CubeSetBit( Min_Cube_t * p, int i )              { p->uData[(i)>>5] |= (1<<((i) & 31));                 } +static inline void Min_CubeXorBit( Min_Cube_t * p, int i )              { p->uData[(i)>>5] ^= (1<<((i) & 31));                 } +static inline int  Min_CubeGetVar( Min_Cube_t * p, int Var )            { return 3 & (p->uData[(2*Var)>>5] >> ((2*Var) & 31)); } +static inline void Min_CubeXorVar( Min_Cube_t * p, int Var, int Value ) { p->uData[(2*Var)>>5] ^= (Value<<((2*Var) & 31));     } + +/*=== covMinEsop.c ==========================================================*/ +extern void         Min_EsopMinimize( Min_Man_t * p ); +extern void         Min_EsopAddCube( Min_Man_t * p, Min_Cube_t * pCube ); +/*=== covMinSop.c ==========================================================*/ +extern void         Min_SopMinimize( Min_Man_t * p ); +extern void         Min_SopAddCube( Min_Man_t * p, Min_Cube_t * pCube ); +/*=== covMinMan.c ==========================================================*/ +extern Min_Man_t *  Min_ManAlloc( int nVars ); +extern void         Min_ManClean( Min_Man_t * p, int nSupp ); +extern void         Min_ManFree( Min_Man_t * p ); +/*=== covMinUtil.c ==========================================================*/ +extern void         Min_CoverCreate( Vec_Str_t * vCover, Min_Cube_t * pCover, char Type ); +extern void         Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube ); +extern void         Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover ); +extern void         Min_CoverWriteStore( FILE * pFile, Min_Man_t * p ); +extern void         Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop ); +extern void         Min_CoverCheck( Min_Man_t * p ); +extern int          Min_CubeCheck( Min_Cube_t * pCube ); +extern Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize ); +extern void         Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover ); +extern int          Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover ); + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Creates the cube.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Min_Cube_t * Min_CubeAlloc( Min_Man_t * p ) +{ +    Min_Cube_t * pCube; +    pCube = (Min_Cube_t *)Extra_MmFixedEntryFetch( p->pMemMan ); +    pCube->pNext  = NULL; +    pCube->nVars  = p->nVars; +    pCube->nWords = p->nWords; +    pCube->nLits  = 0; +    memset( pCube->uData, 0xff, sizeof(unsigned) * p->nWords ); +    return pCube; +} + +/**Function************************************************************* + +  Synopsis    [Creates the cube representing elementary var.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Min_Cube_t * Min_CubeAllocVar( Min_Man_t * p, int iVar, int fCompl ) +{ +    Min_Cube_t * pCube; +    pCube = Min_CubeAlloc( p ); +    Min_CubeXorBit( pCube, iVar*2+fCompl ); +    pCube->nLits = 1; +    return pCube; +} + +/**Function************************************************************* + +  Synopsis    [Creates the cube.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Min_Cube_t * Min_CubeDup( Min_Man_t * p, Min_Cube_t * pCopy ) +{ +    Min_Cube_t * pCube; +    pCube = Min_CubeAlloc( p ); +    memcpy( pCube->uData, pCopy->uData, sizeof(unsigned) * p->nWords ); +    pCube->nLits = pCopy->nLits; +    return pCube; +} + +/**Function************************************************************* + +  Synopsis    [Recycles the cube.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Min_CubeRecycle( Min_Man_t * p, Min_Cube_t * pCube ) +{ +    Extra_MmFixedEntryRecycle( p->pMemMan, (char *)pCube ); +} + +/**Function************************************************************* + +  Synopsis    [Recycles the cube cover.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Min_CoverRecycle( Min_Man_t * p, Min_Cube_t * pCover ) +{ +    Min_Cube_t * pCube, * pCube2; +    Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) +        Extra_MmFixedEntryRecycle( p->pMemMan, (char *)pCube ); +} + + +/**Function************************************************************* + +  Synopsis    [Counts the number of cubes in the cover.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Min_CubeCountLits( Min_Cube_t * pCube ) +{ +    unsigned uData; +    int Count = 0, i, w; +    for ( w = 0; w < (int)pCube->nWords; w++ ) +    { +        uData = pCube->uData[w] ^ (pCube->uData[w] >> 1); +        for ( i = 0; i < 32; i += 2 ) +            if ( uData & (1 << i) ) +                Count++; +    } +    return Count; +} + +/**Function************************************************************* + +  Synopsis    [Counts the number of cubes in the cover.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Min_CubeGetLits( Min_Cube_t * pCube, Vec_Int_t * vLits ) +{ +    unsigned uData; +    int i, w; +    Vec_IntClear( vLits ); +    for ( w = 0; w < (int)pCube->nWords; w++ ) +    { +        uData = pCube->uData[w] ^ (pCube->uData[w] >> 1); +        for ( i = 0; i < 32; i += 2 ) +            if ( uData & (1 << i) ) +                Vec_IntPush( vLits, w*16 + i/2 ); +    } +} + +/**Function************************************************************* + +  Synopsis    [Counts the number of cubes in the cover.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Min_CoverCountCubes( Min_Cube_t * pCover ) +{ +    Min_Cube_t * pCube; +    int Count = 0; +    Min_CoverForEachCube( pCover, pCube ) +        Count++; +    return Count; +} + + +/**Function************************************************************* + +  Synopsis    [Checks if two cubes are disjoint.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Min_CubesDisjoint( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) +{ +    unsigned uData; +    int i; +    assert( pCube0->nVars == pCube1->nVars ); +    for ( i = 0; i < (int)pCube0->nWords; i++ ) +    { +        uData = pCube0->uData[i] & pCube1->uData[i]; +        uData = (uData | (uData >> 1)) & 0x55555555; +        if ( uData != 0x55555555 ) +            return 1; +    } +    return 0; +} + +/**Function************************************************************* + +  Synopsis    [Collects the disjoint variables of the two cubes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Min_CoverGetDisjVars( Min_Cube_t * pThis, Min_Cube_t * pCube, Vec_Int_t * vVars ) +{ +    unsigned uData; +    int i, w; +    Vec_IntClear( vVars ); +    for ( w = 0; w < (int)pCube->nWords; w++ ) +    { +        uData  = pThis->uData[w] & (pThis->uData[w] >> 1) & 0x55555555; +        uData &= (pCube->uData[w] ^ (pCube->uData[w] >> 1)); +        if ( uData == 0 ) +            continue; +        for ( i = 0; i < 32; i += 2 ) +            if ( uData & (1 << i) ) +                Vec_IntPush( vVars, w*16 + i/2 ); +    } +} + +/**Function************************************************************* + +  Synopsis    [Checks if two cubes are disjoint.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Min_CubesDistOne( Min_Cube_t * pCube0, Min_Cube_t * pCube1, Min_Cube_t * pTemp ) +{ +    unsigned uData; +    int i, fFound = 0; +    for ( i = 0; i < (int)pCube0->nWords; i++ ) +    { +        uData = pCube0->uData[i] ^ pCube1->uData[i]; +        if ( uData == 0 ) +        { +            if ( pTemp ) pTemp->uData[i] = 0; +            continue; +        } +        if ( fFound ) +            return 0; +        uData = (uData | (uData >> 1)) & 0x55555555; +        if ( (uData & (uData-1)) > 0 ) // more than one 1 +            return 0; +        if ( pTemp ) pTemp->uData[i] = uData | (uData << 1); +        fFound = 1; +    } +    if ( fFound == 0 ) +    { +        printf( "\n" ); +        Min_CubeWrite( stdout, pCube0 ); +        Min_CubeWrite( stdout, pCube1 ); +        printf( "Error: Min_CubesDistOne() looks at two equal cubes!\n" ); +    } +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Checks if two cubes are disjoint.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Min_CubesDistTwo( Min_Cube_t * pCube0, Min_Cube_t * pCube1, int * pVar0, int * pVar1 ) +{ +    unsigned uData;//, uData2; +    int i, k, Var0 = -1, Var1 = -1; +    for ( i = 0; i < (int)pCube0->nWords; i++ ) +    { +        uData = pCube0->uData[i] ^ pCube1->uData[i]; +        if ( uData == 0 ) +            continue; +        if ( Var0 >= 0 && Var1 >= 0 ) // more than two 1s +            return 0; +        uData = (uData | (uData >> 1)) & 0x55555555; +        if ( (Var0 >= 0 || Var1 >= 0) && (uData & (uData-1)) > 0 ) +            return 0; +        for ( k = 0; k < 32; k += 2 ) +            if ( uData & (1 << k) ) +            { +                if ( Var0 == -1 ) +                    Var0 = 16 * i + k/2; +                else if ( Var1 == -1 ) +                    Var1 = 16 * i + k/2; +                else +                    return 0; +            } +        /* +        if ( Var0 >= 0 ) +        { +            uData &= 0xFFFF; +            uData2 = (uData >> 16); +            if ( uData && uData2 ) +                return 0; +            if ( uData ) +            { +            } +            uData }= uData2; +            uData &= 0x +        } +        */ +    } +    if ( Var0 >= 0 && Var1 >= 0 ) +    { +        *pVar0 = Var0; +        *pVar1 = Var1; +        return 1; +    } +    if ( Var0 == -1 || Var1 == -1 ) +    { +        printf( "\n" ); +        Min_CubeWrite( stdout, pCube0 ); +        Min_CubeWrite( stdout, pCube1 ); +        printf( "Error: Min_CubesDistTwo() looks at two equal cubes or dist1 cubes!\n" ); +    } +    return 0; +} + +/**Function************************************************************* + +  Synopsis    [Makes the produce of two cubes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Min_Cube_t * Min_CubesProduct( Min_Man_t * p, Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) +{ +    Min_Cube_t * pCube; +    int i; +    assert( pCube0->nVars == pCube1->nVars ); +    pCube = Min_CubeAlloc( p ); +    for ( i = 0; i < p->nWords; i++ ) +        pCube->uData[i] = pCube0->uData[i] & pCube1->uData[i]; +    pCube->nLits = Min_CubeCountLits( pCube ); +    return pCube; +} + +/**Function************************************************************* + +  Synopsis    [Makes the produce of two cubes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Min_Cube_t * Min_CubesXor( Min_Man_t * p, Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) +{ +    Min_Cube_t * pCube; +    int i; +    assert( pCube0->nVars == pCube1->nVars ); +    pCube = Min_CubeAlloc( p ); +    for ( i = 0; i < p->nWords; i++ ) +        pCube->uData[i] = pCube0->uData[i] ^ pCube1->uData[i]; +    pCube->nLits = Min_CubeCountLits( pCube ); +    return pCube; +} + +/**Function************************************************************* + +  Synopsis    [Makes the produce of two cubes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Min_CubesAreEqual( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) +{ +    int i; +    for ( i = 0; i < (int)pCube0->nWords; i++ ) +        if ( pCube0->uData[i] != pCube1->uData[i] ) +            return 0; +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Returns 1 if pCube1 is contained in pCube0, bitwise.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Min_CubeIsContained( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) +{ +    int i; +    for ( i = 0; i < (int)pCube0->nWords; i++ ) +        if ( (pCube0->uData[i] & pCube1->uData[i]) != pCube1->uData[i] ) +            return 0; +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Transforms the cube into the result of merging.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Min_CubesTransform( Min_Cube_t * pCube, Min_Cube_t * pDist, Min_Cube_t * pMask ) +{ +    int w; +    for ( w = 0; w < (int)pCube->nWords; w++ ) +    { +        pCube->uData[w]  =  pCube->uData[w] ^ pDist->uData[w]; +        pCube->uData[w] |= (pDist->uData[w] & ~pMask->uData[w]); +    } +} + +/**Function************************************************************* + +  Synopsis    [Transforms the cube into the result of distance-1 merging.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Min_CubesTransformOr( Min_Cube_t * pCube, Min_Cube_t * pDist ) +{ +    int w; +    for ( w = 0; w < (int)pCube->nWords; w++ ) +        pCube->uData[w] |= pDist->uData[w]; +} + + + +/**Function************************************************************* + +  Synopsis    [Sorts the cover in the increasing number of literals.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Min_CoverExpandRemoveEqual( Min_Man_t * p, Min_Cube_t * pCover ) +{ +    Min_Cube_t * pCube, * pCube2, * pThis; +    if ( pCover == NULL ) +    { +        Min_ManClean( p, p->nVars ); +        return; +    } +    Min_ManClean( p, pCover->nVars ); +    Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) +    { +        // go through the linked list +        Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) +            if ( Min_CubesAreEqual( pCube, pThis ) ) +            { +                Min_CubeRecycle( p, pCube ); +                break; +            } +        if ( pThis != NULL ) +            continue; +        pCube->pNext = p->ppStore[pCube->nLits]; +        p->ppStore[pCube->nLits] = pCube; +        p->nCubes++; +    } +} + +/**Function************************************************************* + +  Synopsis    [Returns 1 if the given cube is contained in one of the cubes of the cover.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Min_CoverContainsCube( Min_Man_t * p, Min_Cube_t * pCube ) +{ +    Min_Cube_t * pThis; +    int i; +/* +    // this cube cannot be equal to any cube +    Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) +    { +        if ( Min_CubesAreEqual( pCube, pThis ) ) +        { +            Min_CubeWrite( stdout, pCube ); +            assert( 0 ); +        } +    } +*/ +    // try to find a containing cube +    for ( i = 0; i <= (int)pCube->nLits; i++ ) +    Min_CoverForEachCube( p->ppStore[i], pThis ) +    { +        // skip the bubble +        if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) ) +            return 1; +    } +    return 0; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covMan.c b/src/map/cov/covMan.c new file mode 100644 index 00000000..74a5cf8a --- /dev/null +++ b/src/map/cov/covMan.c @@ -0,0 +1,144 @@ +/**CFile**************************************************************** + +  FileName    [covMan.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Mapping into network of SOPs/ESOPs.] + +  Synopsis    [Decomposition manager.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: covMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cov.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Cov_Man_t * Cov_ManAlloc( Abc_Ntk_t * pNtk, int nFaninMax ) +{ +    Cov_Man_t * pMan; +    Cov_Obj_t * pMem; +    Abc_Obj_t * pObj; +    int i; +    assert( pNtk->pManCut == NULL ); + +    // start the manager +    pMan = ABC_ALLOC( Cov_Man_t, 1 ); +    memset( pMan, 0, sizeof(Cov_Man_t) ); +    pMan->nFaninMax = nFaninMax; +    pMan->nCubesMax = 2 * pMan->nFaninMax; +    pMan->nWords    = Abc_BitWordNum( nFaninMax * 2 ); + +    // get the cubes +    pMan->vComTo0 = Vec_IntAlloc( 2*nFaninMax ); +    pMan->vComTo1 = Vec_IntAlloc( 2*nFaninMax ); +    pMan->vPairs0 = Vec_IntAlloc( nFaninMax ); +    pMan->vPairs1 = Vec_IntAlloc( nFaninMax ); +    pMan->vTriv0  = Vec_IntAlloc( 1 );  Vec_IntPush( pMan->vTriv0, -1 );  +    pMan->vTriv1  = Vec_IntAlloc( 1 );  Vec_IntPush( pMan->vTriv1, -1 );  + +    // allocate memory for object structures +    pMan->pMemory = pMem = ABC_ALLOC( Cov_Obj_t, sizeof(Cov_Obj_t) * Abc_NtkObjNumMax(pNtk) ); +    memset( pMem, 0, sizeof(Cov_Obj_t) * Abc_NtkObjNumMax(pNtk) ); +    // allocate storage for the pointers to the memory +    pMan->vObjStrs = Vec_PtrAlloc( Abc_NtkObjNumMax(pNtk) ); +    Vec_PtrFill( pMan->vObjStrs, Abc_NtkObjNumMax(pNtk), NULL ); +    Abc_NtkForEachObj( pNtk, pObj, i ) +        Vec_PtrWriteEntry( pMan->vObjStrs, i, pMem + i ); +    // create the cube manager +    pMan->pManMin = Min_ManAlloc( nFaninMax ); +    return pMan; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Cov_ManFree( Cov_Man_t * p ) +{ +    Vec_Int_t * vSupp; +    int i; +    for ( i = 0; i < p->vObjStrs->nSize; i++ ) +    { +        vSupp = ((Cov_Obj_t *)p->vObjStrs->pArray[i])->vSupp; +        if ( vSupp ) Vec_IntFree( vSupp ); +    } + +    Min_ManFree( p->pManMin ); +    Vec_PtrFree( p->vObjStrs ); +    Vec_IntFree( p->vFanCounts ); +    Vec_IntFree( p->vTriv0 ); +    Vec_IntFree( p->vTriv1 ); +    Vec_IntFree( p->vComTo0 ); +    Vec_IntFree( p->vComTo1 ); +    Vec_IntFree( p->vPairs0 ); +    Vec_IntFree( p->vPairs1 ); +    ABC_FREE( p->pMemory ); +    ABC_FREE( p ); +} + +/**Function************************************************************* + +  Synopsis    [Drop the covers at the node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Abc_NodeCovDropData( Cov_Man_t * p, Abc_Obj_t * pObj ) +{ +    int nFanouts; +    assert( p->vFanCounts ); +    nFanouts = Vec_IntEntry( p->vFanCounts, pObj->Id ); +    assert( nFanouts > 0 ); +    if ( --nFanouts == 0 ) +    { +        Vec_IntFree( Abc_ObjGetSupp(pObj) ); +        Abc_ObjSetSupp( pObj, NULL ); +        Min_CoverRecycle( p->pManMin, Abc_ObjGetCover2(pObj) ); +        Abc_ObjSetCover2( pObj, NULL ); +        p->nSupps--; +    } +    Vec_IntWriteEntry( p->vFanCounts, pObj->Id, nFanouts ); +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covMinEsop.c b/src/map/cov/covMinEsop.c new file mode 100644 index 00000000..7dd3db30 --- /dev/null +++ b/src/map/cov/covMinEsop.c @@ -0,0 +1,299 @@ +/**CFile**************************************************************** + +  FileName    [covMinEsop.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Mapping into network of SOPs/ESOPs.] + +  Synopsis    [ESOP manipulation.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: covMinEsop.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "covInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +static void Min_EsopRewrite( Min_Man_t * p ); + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_EsopMinimize( Min_Man_t * p ) +{ +    int nCubesInit, nCubesOld, nIter; +    if ( p->nCubes < 3 ) +        return; +    nIter = 0; +    nCubesInit = p->nCubes; +    do { +        nCubesOld = p->nCubes; +        Min_EsopRewrite( p ); +        nIter++; +    } +    while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 ); + +//    printf( "%d:%d->%d ", nIter, nCubesInit, p->nCubes ); +} + +/**Function************************************************************* + +  Synopsis    [Performs one round of rewriting using distance 2 cubes.] + +  Description [The weakness of this procedure is that it tries each cube +  with only one distance-2 cube. If this pair does not lead to improvement +  the cube is inserted into the cover anyhow, and we try another pair. +  A possible improvement would be to try this cube with all distance-2 +  cubes, until an improvement is found, or until all such cubes are tried.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_EsopRewrite( Min_Man_t * p ) +{ +    Min_Cube_t * pCube, ** ppPrev; +    Min_Cube_t * pThis, ** ppPrevT; +    int v00, v01, v10, v11, Var0, Var1, Index, nCubesOld; +    int nPairs = 0; + +    // insert the bubble before the first cube +    p->pBubble->pNext = p->ppStore[0]; +    p->ppStore[0] = p->pBubble; +    p->pBubble->nLits = 0; + +    // go through the cubes +    while ( 1 ) +    { +        // get the index of the bubble +        Index = p->pBubble->nLits; + +        // find the bubble +        Min_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev ) +            if ( pCube == p->pBubble ) +                break; +        assert( pCube == p->pBubble ); + +        // remove the bubble, get the next cube after the bubble +        *ppPrev = p->pBubble->pNext; +        pCube = p->pBubble->pNext; +        if ( pCube == NULL ) +            for ( Index++; Index <= p->nVars; Index++ ) +                if ( p->ppStore[Index] ) +                { +                    ppPrev = &(p->ppStore[Index]); +                    pCube = p->ppStore[Index]; +                    break; +                } +        // stop if there is no more cubes +        if ( pCube == NULL ) +            break; + +        // find the first dist2 cube +        Min_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT ) +            if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) +                break; +        if ( pThis == NULL && Index < p->nVars ) +        Min_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT ) +            if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) +                break; +        if ( pThis == NULL && Index < p->nVars - 1 ) +        Min_CoverForEachCubePrev( p->ppStore[Index+2], pThis, ppPrevT ) +            if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) +                break; +        // continue if there is no dist2 cube +        if ( pThis == NULL ) +        { +            // insert the bubble after the cube +            p->pBubble->pNext = pCube->pNext; +            pCube->pNext = p->pBubble; +            p->pBubble->nLits = pCube->nLits; +            continue; +        } +        nPairs++; + +        // remove the cubes, insert the bubble instead of pCube +        *ppPrevT = pThis->pNext; +        *ppPrev = p->pBubble; +        p->pBubble->pNext = pCube->pNext; +        p->pBubble->nLits = pCube->nLits; +        p->nCubes -= 2; + +        // Exorlink-2: +        // A{v00}     B{v01}      +  A{v10}     B{v11}     = +        // A{v00+v10} B{v01}      +  A{v10}     B{v01+v11} = +        // A{v00}     B{v01+v11}  +  A{v00+v10} B{v11} + +        // save the dist2 parameters +        v00 = Min_CubeGetVar( pCube, Var0 ); +        v01 = Min_CubeGetVar( pCube, Var1 ); +        v10 = Min_CubeGetVar( pThis, Var0 ); +        v11 = Min_CubeGetVar( pThis, Var1 ); +//printf( "\n" ); +//Min_CubeWrite( stdout, pCube ); +//Min_CubeWrite( stdout, pThis ); + +        // derive the first pair of resulting cubes +        Min_CubeXorVar( pCube, Var0, v10 ); +        pCube->nLits -= (v00 != 3); +        pCube->nLits += ((v00 ^ v10) != 3); +        Min_CubeXorVar( pThis, Var1, v01 ); +        pThis->nLits -= (v11 != 3); +        pThis->nLits += ((v01 ^ v11) != 3); + +        // add the cubes +        nCubesOld = p->nCubes; +        Min_EsopAddCube( p, pCube ); +        Min_EsopAddCube( p, pThis ); +        // check if the cubes were absorbed +        if ( p->nCubes < nCubesOld + 2 ) +            continue; + +        // pull out both cubes +        assert( pThis == p->ppStore[pThis->nLits] ); +        p->ppStore[pThis->nLits] = pThis->pNext; +        assert( pCube == p->ppStore[pCube->nLits] ); +        p->ppStore[pCube->nLits] = pCube->pNext; +        p->nCubes -= 2; + +        // derive the second pair of resulting cubes +        Min_CubeXorVar( pCube, Var0, v10 ); +        pCube->nLits -= ((v00 ^ v10) != 3); +        pCube->nLits += (v00 != 3); +        Min_CubeXorVar( pCube, Var1, v11 ); +        pCube->nLits -= (v01 != 3); +        pCube->nLits += ((v01 ^ v11) != 3); + +        Min_CubeXorVar( pThis, Var0, v00 ); +        pThis->nLits -= (v10 != 3); +        pThis->nLits += ((v00 ^ v10) != 3); +        Min_CubeXorVar( pThis, Var1, v01 ); +        pThis->nLits -= ((v01 ^ v11) != 3); +        pThis->nLits += (v11 != 3); + +        // add them anyhow +        Min_EsopAddCube( p, pCube ); +        Min_EsopAddCube( p, pThis ); +    } +//    printf( "Pairs = %d  ", nPairs ); +} + +/**Function************************************************************* + +  Synopsis    [Adds the cube to storage.] + +  Description [Returns 0 if the cube is added or removed. Returns 1 +  if the cube is glued with some other cube and has to be added again. +  Do not forget to clean the storage!] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Min_EsopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube ) +{ +    Min_Cube_t * pThis, ** ppPrev; +    // try to find the identical cube +    Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) +    { +        if ( Min_CubesAreEqual( pCube, pThis ) ) +        { +            *ppPrev = pThis->pNext; +            Min_CubeRecycle( p, pCube ); +            Min_CubeRecycle( p, pThis ); +            p->nCubes--; +            return 0; +        } +    } +    // find a distance-1 cube if it exists +    if ( pCube->nLits < pCube->nVars ) +    Min_CoverForEachCubePrev( p->ppStore[pCube->nLits+1], pThis, ppPrev ) +    { +        if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) ) +        { +            *ppPrev = pThis->pNext; +            Min_CubesTransform( pCube, pThis, p->pTemp ); +            pCube->nLits++; +            Min_CubeRecycle( p, pThis ); +            p->nCubes--; +            return 1; +        } +    } +    Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) +    { +        if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) ) +        { +            *ppPrev = pThis->pNext; +            Min_CubesTransform( pCube, pThis, p->pTemp ); +            pCube->nLits--; +            Min_CubeRecycle( p, pThis ); +            p->nCubes--; +            return 1; +        } +    } +    if ( pCube->nLits > 0 ) +    Min_CoverForEachCubePrev( p->ppStore[pCube->nLits-1], pThis, ppPrev ) +    { +        if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) ) +        { +            *ppPrev = pThis->pNext; +            Min_CubesTransform( pCube, pThis, p->pTemp ); +            Min_CubeRecycle( p, pThis ); +            p->nCubes--; +            return 1; +        } +    } +    // add the cube +    pCube->pNext = p->ppStore[pCube->nLits]; +    p->ppStore[pCube->nLits] = pCube; +    p->nCubes++; +    return 0; +} + +/**Function************************************************************* + +  Synopsis    [Adds the cube to storage.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_EsopAddCube( Min_Man_t * p, Min_Cube_t * pCube ) +{ +    assert( pCube != p->pBubble ); +    assert( (int)pCube->nLits == Min_CubeCountLits(pCube) ); +    while ( Min_EsopAddCubeInt( p, pCube ) ); +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covMinMan.c b/src/map/cov/covMinMan.c new file mode 100644 index 00000000..74aa2e8c --- /dev/null +++ b/src/map/cov/covMinMan.c @@ -0,0 +1,113 @@ +/**CFile**************************************************************** + +  FileName    [covMinMan.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Mapping into network of SOPs/ESOPs.] + +  Synopsis    [SOP manipulation.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: covMinMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "covInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Starts the minimization manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Min_Man_t * Min_ManAlloc( int nVars ) +{ +    Min_Man_t * pMan; +    // start the manager +    pMan = ABC_ALLOC( Min_Man_t, 1 ); +    memset( pMan, 0, sizeof(Min_Man_t) ); +    pMan->nVars   = nVars; +    pMan->nWords  = Abc_BitWordNum( nVars * 2 ); +    pMan->pMemMan = Extra_MmFixedStart( sizeof(Min_Cube_t) + sizeof(unsigned) * (pMan->nWords - 1) ); +    // allocate storage for the temporary cover +    pMan->ppStore = ABC_ALLOC( Min_Cube_t *, pMan->nVars + 1 ); +    // create tautology cubes +    Min_ManClean( pMan, nVars ); +    pMan->pOne0  = Min_CubeAlloc( pMan ); +    pMan->pOne1  = Min_CubeAlloc( pMan ); +    pMan->pTemp  = Min_CubeAlloc( pMan ); +    pMan->pBubble = Min_CubeAlloc( pMan );  pMan->pBubble->uData[0] = 0; +    // create trivial cubes +    Min_ManClean( pMan, 1 ); +    pMan->pTriv0[0] = Min_CubeAllocVar( pMan, 0, 0 ); +    pMan->pTriv0[1] = Min_CubeAllocVar( pMan, 0, 1 );    +    pMan->pTriv1[0] = Min_CubeAllocVar( pMan, 0, 0 ); +    pMan->pTriv1[1] = Min_CubeAllocVar( pMan, 0, 1 );    +    Min_ManClean( pMan, nVars ); +    return pMan; +} + +/**Function************************************************************* + +  Synopsis    [Cleans the minimization manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_ManClean( Min_Man_t * p, int nSupp ) +{ +    // set the size of the cube manager +    p->nVars  = nSupp; +    p->nWords = Abc_BitWordNum(2*nSupp); +    // clean the storage +    memset( p->ppStore, 0, sizeof(Min_Cube_t *) * (nSupp + 1) ); +    p->nCubes = 0; +} + +/**Function************************************************************* + +  Synopsis    [Stops the minimization manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_ManFree( Min_Man_t * p ) +{ +    Extra_MmFixedStop( p->pMemMan ); +    ABC_FREE( p->ppStore ); +    ABC_FREE( p ); +} + + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covMinSop.c b/src/map/cov/covMinSop.c new file mode 100644 index 00000000..731a6698 --- /dev/null +++ b/src/map/cov/covMinSop.c @@ -0,0 +1,615 @@ +/**CFile**************************************************************** + +  FileName    [covMinSop.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Mapping into network of SOPs/ESOPs.] + +  Synopsis    [SOP manipulation.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: covMinSop.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "covInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +static void Min_SopRewrite( Min_Man_t * p ); + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_SopMinimize( Min_Man_t * p ) +{ +    int nCubesInit, nCubesOld, nIter; +    if ( p->nCubes < 3 ) +        return; +    nIter = 0; +    nCubesInit = p->nCubes; +    do { +        nCubesOld = p->nCubes; +        Min_SopRewrite( p ); +        nIter++; +//    printf( "%d:%d->%d ", nIter, nCubesInit, p->nCubes ); +    } +    while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 ); +//    printf( "\n" ); + +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_SopRewrite( Min_Man_t * p ) +{ +    Min_Cube_t * pCube, ** ppPrev; +    Min_Cube_t * pThis, ** ppPrevT; +    Min_Cube_t * pTemp; +    int v00, v01, v10, v11, Var0, Var1, Index, fCont0, fCont1, nCubesOld; +    int nPairs = 0; +/*     +    { +        Min_Cube_t * pCover; +        pCover = Min_CoverCollect( p, p->nVars ); +printf( "\n\n" ); +Min_CoverWrite( stdout, pCover ); +        Min_CoverExpand( p, pCover ); +    } +*/ + +    // insert the bubble before the first cube +    p->pBubble->pNext = p->ppStore[0]; +    p->ppStore[0] = p->pBubble; +    p->pBubble->nLits = 0; + +    // go through the cubes +    while ( 1 ) +    { +        // get the index of the bubble +        Index = p->pBubble->nLits; + +        // find the bubble +        Min_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev ) +            if ( pCube == p->pBubble ) +                break; +        assert( pCube == p->pBubble ); + +        // remove the bubble, get the next cube after the bubble +        *ppPrev = p->pBubble->pNext; +        pCube = p->pBubble->pNext; +        if ( pCube == NULL ) +            for ( Index++; Index <= p->nVars; Index++ ) +                if ( p->ppStore[Index] ) +                { +                    ppPrev = &(p->ppStore[Index]); +                    pCube = p->ppStore[Index]; +                    break; +                } +        // stop if there is no more cubes +        if ( pCube == NULL ) +            break; + +        // find the first dist2 cube +        Min_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT ) +            if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) +                break; +        if ( pThis == NULL && Index < p->nVars ) +        Min_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT ) +            if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) +                break; +        // continue if there is no dist2 cube +        if ( pThis == NULL ) +        { +            // insert the bubble after the cube +            p->pBubble->pNext = pCube->pNext; +            pCube->pNext = p->pBubble; +            p->pBubble->nLits = pCube->nLits; +            continue; +        } +        nPairs++; +/* +printf( "\n" ); +Min_CubeWrite( stdout, pCube ); +Min_CubeWrite( stdout, pThis ); +*/ +        // remove the cubes, insert the bubble instead of pCube +        *ppPrevT = pThis->pNext; +        *ppPrev = p->pBubble; +        p->pBubble->pNext = pCube->pNext; +        p->pBubble->nLits = pCube->nLits; +        p->nCubes -= 2; + +        assert( pCube != p->pBubble && pThis != p->pBubble ); + + +        // save the dist2 parameters +        v00 = Min_CubeGetVar( pCube, Var0 ); +        v01 = Min_CubeGetVar( pCube, Var1 ); +        v10 = Min_CubeGetVar( pThis, Var0 ); +        v11 = Min_CubeGetVar( pThis, Var1 ); +        assert( v00 != v10 && v01 != v11 ); +        assert( v00 != 3   || v01 != 3 ); +        assert( v10 != 3   || v11 != 3 ); + +//printf( "\n" ); +//Min_CubeWrite( stdout, pCube ); +//Min_CubeWrite( stdout, pThis ); + +//printf( "\n" ); +//Min_CubeWrite( stdout, pCube ); +//Min_CubeWrite( stdout, pThis ); + +        // consider the case when both cubes have non-empty literals +        if ( v00 != 3 && v01 != 3 && v10 != 3 && v11 != 3 ) +        { +            assert( v00 == (v10 ^ 3) ); +            assert( v01 == (v11 ^ 3) ); +            // create the temporary cube equal to the first corner +            Min_CubeXorVar( pCube, Var0, 3 ); +            // check if this cube is contained +            fCont0 = Min_CoverContainsCube( p, pCube ); +            // create the temporary cube equal to the first corner +            Min_CubeXorVar( pCube, Var0, 3 ); +            Min_CubeXorVar( pCube, Var1, 3 ); +//printf( "\n" ); +//Min_CubeWrite( stdout, pCube ); +//Min_CubeWrite( stdout, pThis ); +            // check if this cube is contained +            fCont1 = Min_CoverContainsCube( p, pCube ); +            // undo the change +            Min_CubeXorVar( pCube, Var1, 3 ); + +            // check if the cubes can be overwritten +            if ( fCont0 && fCont1 ) +            { +                // one of the cubes can be recycled, the other expanded and added +                Min_CubeRecycle( p, pThis ); +                // remove the literals +                Min_CubeXorVar( pCube, Var0, v00 ^ 3 ); +                Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); +                pCube->nLits -= 2; +                Min_SopAddCube( p, pCube ); +            } +            else if ( fCont0 ) +            { +                // expand both cubes and add them +                Min_CubeXorVar( pCube, Var0, v00 ^ 3 ); +                pCube->nLits--; +                Min_SopAddCube( p, pCube ); +                Min_CubeXorVar( pThis, Var1, v11 ^ 3 ); +                pThis->nLits--; +                Min_SopAddCube( p, pThis ); +            } +            else if ( fCont1 ) +            { +                // expand both cubes and add them +                Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); +                pCube->nLits--; +                Min_SopAddCube( p, pCube ); +                Min_CubeXorVar( pThis, Var0, v10 ^ 3 ); +                pThis->nLits--; +                Min_SopAddCube( p, pThis ); +            } +            else +            { +                Min_SopAddCube( p, pCube ); +                Min_SopAddCube( p, pThis ); +            } +            // otherwise, no change is possible +            continue; +        } + +        // if one of them does not have DC lit, move it +        if ( v00 != 3 && v01 != 3 ) +        { +            assert( v10 == 3 || v11 == 3 ); +            pTemp = pCube; pCube = pThis; pThis = pTemp; +            Index = v00; v00 = v10; v10 = Index; +            Index = v01; v01 = v11; v11 = Index; +        } + +        // make sure the first cube has first var DC +        if ( v00 != 3 ) +        { +            assert( v01 == 3 ); +            Index = Var0; Var0 = Var1; Var1 = Index; +            Index = v00; v00 = v01; v01 = Index; +            Index = v10; v10 = v11; v11 = Index; +        } + +        // consider both cases: both have DC lit +        if ( v00 == 3 && v11 == 3 ) +        { +            assert( v01 != 3 && v10 != 3 ); +            // try the remaining minterm +            // create the temporary cube equal to the first corner +            Min_CubeXorVar( pCube, Var0, v10 ); +            Min_CubeXorVar( pCube, Var1, 3   ); +            pCube->nLits++; +            // check if this cube is contained +            fCont0 = Min_CoverContainsCube( p, pCube ); +            // undo the cube transformations +            Min_CubeXorVar( pCube, Var0, v10 ); +            Min_CubeXorVar( pCube, Var1, 3   ); +            pCube->nLits--; +            // check the case when both are covered +            if ( fCont0 ) +            { +                // one of the cubes can be recycled, the other expanded and added +                Min_CubeRecycle( p, pThis ); +                // remove the literals +                Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); +                pCube->nLits--; +                Min_SopAddCube( p, pCube ); +            } +            else +            { +                // try two reduced cubes +                Min_CubeXorVar( pCube, Var0, v10 ); +                pCube->nLits++; +                // remember the cubes +                nCubesOld = p->nCubes; +                Min_SopAddCube( p, pCube ); +                // check if the cube is absorbed +                if ( p->nCubes < nCubesOld + 1 ) +                { // absorbed - add the second cube +                    Min_SopAddCube( p, pThis ); +                } +                else +                { // remove this cube, and try another one +                    assert( pCube == p->ppStore[pCube->nLits] ); +                    p->ppStore[pCube->nLits] = pCube->pNext; +                    p->nCubes--; + +                    // return the cube to the previous state +                    Min_CubeXorVar( pCube, Var0, v10 ); +                    pCube->nLits--; + +                    // generate another reduced cube +                    Min_CubeXorVar( pThis, Var1, v01 ); +                    pThis->nLits++; + +                    // add both cubes +                    Min_SopAddCube( p, pCube ); +                    Min_SopAddCube( p, pThis ); +                } +            } +        } +        else // the first cube has DC lit +        { +            assert( v01 != 3 && v10 != 3 && v11 != 3 ); +            // try the remaining minterm +            // create the temporary cube equal to the minterm +            Min_CubeXorVar( pThis, Var0, 3 ); +            // check if this cube is contained +            fCont0 = Min_CoverContainsCube( p, pThis ); +            // undo the cube transformations +            Min_CubeXorVar( pThis, Var0, 3 ); +            // check the case when both are covered +            if ( fCont0 ) +            { +                // one of the cubes can be recycled, the other expanded and added +                Min_CubeRecycle( p, pThis ); +                // remove the literals +                Min_CubeXorVar( pCube, Var1, v01 ^ 3 ); +                pCube->nLits--; +                Min_SopAddCube( p, pCube ); +            } +            else +            { +                // try reshaping the cubes +                // reduce the first cube +                Min_CubeXorVar( pCube, Var0, v10 ); +                pCube->nLits++; +                // expand the second cube +                Min_CubeXorVar( pThis, Var1, v11 ^ 3 ); +                pThis->nLits--; +                // add both cubes +                Min_SopAddCube( p, pCube ); +                Min_SopAddCube( p, pThis ); +            } +        } +    } +//    printf( "Pairs = %d  ", nPairs ); +} + +/**Function************************************************************* + +  Synopsis    [Adds cube to the SOP cover stored in the manager.] + +  Description [Returns 0 if the cube is added or removed. Returns 1 +  if the cube is glued with some other cube and has to be added again.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Min_SopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube ) +{ +    Min_Cube_t * pThis, * pThis2, ** ppPrev; +    int i; +    // try to find the identical cube +    Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) +    { +        if ( Min_CubesAreEqual( pCube, pThis ) ) +        { +            Min_CubeRecycle( p, pCube ); +            return 0; +        } +    } +    // try to find a containing cube +    for ( i = 0; i < (int)pCube->nLits; i++ ) +    Min_CoverForEachCube( p->ppStore[i], pThis ) +    { +        if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) ) +        { +            Min_CubeRecycle( p, pCube ); +            return 0; +        } +    } +    // try to find distance one in the same bin +    Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) +    { +        if ( Min_CubesDistOne( pCube, pThis, NULL ) ) +        { +            *ppPrev = pThis->pNext; +            Min_CubesTransformOr( pCube, pThis ); +            pCube->nLits--; +            Min_CubeRecycle( p, pThis ); +            p->nCubes--; +            return 1; +        } +    } + +    // clean the other cubes using this one +    for ( i = pCube->nLits + 1; i <= (int)pCube->nVars; i++ ) +    { +        ppPrev = &p->ppStore[i]; +        Min_CoverForEachCubeSafe( p->ppStore[i], pThis, pThis2 ) +        { +            if ( pThis != p->pBubble && Min_CubeIsContained( pCube, pThis ) ) +            { +                *ppPrev = pThis->pNext; +                Min_CubeRecycle( p, pThis ); +                p->nCubes--; +            } +            else +                ppPrev = &pThis->pNext; +        } +    } + +    // add the cube +    pCube->pNext = p->ppStore[pCube->nLits]; +    p->ppStore[pCube->nLits] = pCube; +    p->nCubes++; +    return 0; +} + +/**Function************************************************************* + +  Synopsis    [Adds the cube to storage.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_SopAddCube( Min_Man_t * p, Min_Cube_t * pCube ) +{ +    assert( Min_CubeCheck( pCube ) ); +    assert( pCube != p->pBubble ); +    assert( (int)pCube->nLits == Min_CubeCountLits(pCube) ); +    while ( Min_SopAddCubeInt( p, pCube ) ); +} + + + + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_SopContain( Min_Man_t * p ) +{ +    Min_Cube_t * pCube, * pCube2, ** ppPrev; +    int i, k; +    for ( i = 0; i <= p->nVars; i++ ) +    { +        Min_CoverForEachCube( p->ppStore[i], pCube ) +        Min_CoverForEachCubePrev( pCube->pNext, pCube2, ppPrev ) +        { +            if ( !Min_CubesAreEqual( pCube, pCube2 ) ) +                continue; +            *ppPrev = pCube2->pNext; +            Min_CubeRecycle( p, pCube2 ); +            p->nCubes--; +        } +        for ( k = i + 1; k <= p->nVars; k++ ) +        Min_CoverForEachCubePrev( p->ppStore[k], pCube2, ppPrev ) +        { +            if ( !Min_CubeIsContained( pCube, pCube2 ) ) +                continue; +            *ppPrev = pCube2->pNext; +            Min_CubeRecycle( p, pCube2 ); +            p->nCubes--; +        } +    } +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_SopDist1Merge( Min_Man_t * p ) +{ +    Min_Cube_t * pCube, * pCube2, * pCubeNew; +    int i; +    for ( i = p->nVars; i >= 0; i-- ) +    { +        Min_CoverForEachCube( p->ppStore[i], pCube ) +        Min_CoverForEachCube( pCube->pNext, pCube2 ) +        { +            assert( pCube->nLits == pCube2->nLits ); +            if ( !Min_CubesDistOne( pCube, pCube2, NULL ) ) +                continue; +            pCubeNew = Min_CubesXor( p, pCube, pCube2 ); +            assert( pCubeNew->nLits == pCube->nLits - 1 ); +            pCubeNew->pNext = p->ppStore[pCubeNew->nLits]; +            p->ppStore[pCubeNew->nLits] = pCubeNew; +            p->nCubes++; +        } +    } +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Min_Cube_t * Min_SopComplement( Min_Man_t * p, Min_Cube_t * pSharp ) +{ +     Vec_Int_t * vVars; +     Min_Cube_t * pCover, * pCube, * pNext, * pReady, * pThis, ** ppPrev; +     int Num, Value, i; + +     // get the variables +     vVars = Vec_IntAlloc( 100 ); +    // create the tautology cube +     pCover = Min_CubeAlloc( p ); +     // sharp it with all cubes +     Min_CoverForEachCube( pSharp, pCube ) +     Min_CoverForEachCubePrev( pCover, pThis, ppPrev ) +     { +        if ( Min_CubesDisjoint( pThis, pCube ) ) +            continue; +        // remember the next pointer +        pNext = pThis->pNext; +        // get the variables, in which pThis is '-' while pCube is fixed +        Min_CoverGetDisjVars( pThis, pCube, vVars ); +        // generate the disjoint cubes +        pReady = pThis; +        Vec_IntForEachEntryReverse( vVars, Num, i ) +        { +            // correct the literal +            Min_CubeXorVar( pReady, vVars->pArray[i], 3 ); +            if ( i == 0 ) +                break; +            // create the new cube and clean this value +            Value = Min_CubeGetVar( pReady, vVars->pArray[i] ); +            pReady = Min_CubeDup( p, pReady ); +            Min_CubeXorVar( pReady, vVars->pArray[i], 3 ^ Value ); +            // add to the cover +            *ppPrev = pReady; +            ppPrev = &pReady->pNext; +        } +        pThis = pReady; +        pThis->pNext = pNext; +     } +     Vec_IntFree( vVars ); + +     // perform dist-1 merge and contain +     Min_CoverExpandRemoveEqual( p, pCover ); +     Min_SopDist1Merge( p ); +     Min_SopContain( p ); +     return Min_CoverCollect( p, p->nVars ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Min_SopCheck( Min_Man_t * p ) +{ +    Min_Cube_t * pCube, * pThis; +    int i; + +    pCube = Min_CubeAlloc( p ); +    Min_CubeXorBit( pCube, 2*0+1 ); +    Min_CubeXorBit( pCube, 2*1+1 ); +    Min_CubeXorBit( pCube, 2*2+0 ); +    Min_CubeXorBit( pCube, 2*3+0 ); +    Min_CubeXorBit( pCube, 2*4+0 ); +    Min_CubeXorBit( pCube, 2*5+1 ); +    Min_CubeXorBit( pCube, 2*6+1 ); +    pCube->nLits = 7; + +//    Min_CubeWrite( stdout, pCube ); + +    // check that the cubes contain it +    for ( i = 0; i <= p->nVars; i++ ) +        Min_CoverForEachCube( p->ppStore[i], pThis ) +            if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) ) +            { +                Min_CubeRecycle( p, pCube ); +                return 1; +            } +    Min_CubeRecycle( p, pCube ); +    return 0; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covMinUtil.c b/src/map/cov/covMinUtil.c new file mode 100644 index 00000000..c383a3e8 --- /dev/null +++ b/src/map/cov/covMinUtil.c @@ -0,0 +1,338 @@ +/**CFile**************************************************************** + +  FileName    [covMinUtil.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Mapping into network of SOPs/ESOPs.] + +  Synopsis    [Utilities.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: covMinUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "covInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_CubeCreate( Vec_Str_t * vCover, Min_Cube_t * pCube, char Type ) +{ +    int i; +    assert( (int)pCube->nLits == Min_CubeCountLits(pCube) ); +    for ( i = 0; i < (int)pCube->nVars; i++ ) +        if ( Min_CubeHasBit(pCube, i*2) ) +        { +            if ( Min_CubeHasBit(pCube, i*2+1) ) +//                fprintf( pFile, "-" ); +                Vec_StrPush( vCover, '-' ); +            else +//                fprintf( pFile, "0" ); +                Vec_StrPush( vCover, '0' ); +        } +        else +        { +            if ( Min_CubeHasBit(pCube, i*2+1) ) + //               fprintf( pFile, "1" ); +                Vec_StrPush( vCover, '1' ); +            else +//                fprintf( pFile, "?" ); +                Vec_StrPush( vCover, '?' ); +        } +//    fprintf( pFile, " 1\n" ); +    Vec_StrPush( vCover, ' ' ); +    Vec_StrPush( vCover, Type ); +    Vec_StrPush( vCover, '\n' ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_CoverCreate( Vec_Str_t * vCover, Min_Cube_t * pCover, char Type ) +{ +    Min_Cube_t * pCube; +    assert( pCover != NULL ); +    Vec_StrClear( vCover ); +    Min_CoverForEachCube( pCover, pCube ) +        Min_CubeCreate( vCover, pCube, Type ); +    Vec_StrPush( vCover, 0 ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube ) +{ +    int i; +    assert( (int)pCube->nLits == Min_CubeCountLits(pCube) ); +    for ( i = 0; i < (int)pCube->nVars; i++ ) +        if ( Min_CubeHasBit(pCube, i*2) ) +        { +            if ( Min_CubeHasBit(pCube, i*2+1) ) +                fprintf( pFile, "-" ); +            else +                fprintf( pFile, "0" ); +        } +        else +        { +            if ( Min_CubeHasBit(pCube, i*2+1) ) +                fprintf( pFile, "1" ); +            else +                fprintf( pFile, "?" ); +        } +    fprintf( pFile, " 1\n" ); +//    fprintf( pFile, " %d\n", pCube->nLits ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover ) +{ +    Min_Cube_t * pCube; +    Min_CoverForEachCube( pCover, pCube ) +        Min_CubeWrite( pFile, pCube ); +    printf( "\n" ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p ) +{ +    Min_Cube_t * pCube; +    int i; +    for ( i = 0; i <= p->nVars; i++ ) +    { +        Min_CoverForEachCube( p->ppStore[i], pCube ) +        { +            printf( "%2d : ", i ); +            if ( pCube == p->pBubble ) +            { +                printf( "Bubble\n" ); +                continue; +            } +            Min_CubeWrite( pFile, pCube ); +        } +    } +    printf( "\n" ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop ) +{ +    char Buffer[1000]; +    Min_Cube_t * pCube; +    FILE * pFile; +    int i; +    sprintf( Buffer, "%s.%s", pName, fEsop? "esop" : "pla" ); +    for ( i = strlen(Buffer) - 1; i >= 0; i-- ) +        if ( Buffer[i] == '<' || Buffer[i] == '>' ) +            Buffer[i] = '_'; +    pFile = fopen( Buffer, "w" ); +    fprintf( pFile, "# %s cover for output %s generated by ABC on %s\n", fEsop? "ESOP":"SOP", pName, Extra_TimeStamp() ); +    fprintf( pFile, ".i %d\n", pCover? pCover->nVars : 0 ); +    fprintf( pFile, ".o %d\n", 1 ); +    fprintf( pFile, ".p %d\n", Min_CoverCountCubes(pCover) ); +    if ( fEsop ) fprintf( pFile, ".type esop\n" ); +    Min_CoverForEachCube( pCover, pCube ) +        Min_CubeWrite( pFile, pCube ); +    fprintf( pFile, ".e\n" ); +    fclose( pFile ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_CoverCheck( Min_Man_t * p ) +{ +    Min_Cube_t * pCube; +    int i; +    for ( i = 0; i <= p->nVars; i++ ) +        Min_CoverForEachCube( p->ppStore[i], pCube ) +            assert( i == (int)pCube->nLits ); +} + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Min_CubeCheck( Min_Cube_t * pCube ) +{ +    int i; +    for ( i = 0; i < (int)pCube->nVars; i++ ) +        if ( Min_CubeGetVar( pCube, i ) == 0 ) +            return 0; +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Converts the cover from the sorted structure.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize ) +{ +    Min_Cube_t * pCov = NULL, ** ppTail = &pCov; +    Min_Cube_t * pCube, * pCube2; +    int i; +    for ( i = 0; i <= nSuppSize; i++ ) +    { +        Min_CoverForEachCubeSafe( p->ppStore[i], pCube, pCube2 ) +        { +            assert( i == (int)pCube->nLits ); +            *ppTail = pCube;  +            ppTail = &pCube->pNext; +            assert( pCube->uData[0] ); // not a bubble +        } +    } +    *ppTail = NULL; +    return pCov; +} + +/**Function************************************************************* + +  Synopsis    [Sorts the cover in the increasing number of literals.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover ) +{ +    Min_Cube_t * pCube, * pCube2; +    Min_ManClean( p, p->nVars ); +    Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) +    { +        pCube->pNext = p->ppStore[pCube->nLits]; +        p->ppStore[pCube->nLits] = pCube; +        p->nCubes++; +    } +} + +/**Function************************************************************* + +  Synopsis    [Sorts the cover in the increasing number of literals.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover ) +{ +    Min_Cube_t * pCube; +    int i, Counter; +    if ( pCover == NULL ) +        return 0; +    // clean the cube +    for ( i = 0; i < (int)pCover->nWords; i++ ) +        p->pTemp->uData[i]  = ~((unsigned)0); +    // add the bit data +    Min_CoverForEachCube( pCover, pCube ) +        for ( i = 0; i < (int)pCover->nWords; i++ ) +            p->pTemp->uData[i] &= pCube->uData[i]; +    // count the vars +    Counter = 0; +    for ( i = 0; i < (int)pCover->nVars; i++ ) +        Counter += ( Min_CubeGetVar(p->pTemp, i) != 3 ); +    return Counter; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/covTest.c b/src/map/cov/covTest.c new file mode 100644 index 00000000..39432c90 --- /dev/null +++ b/src/map/cov/covTest.c @@ -0,0 +1,417 @@ +/**CFile**************************************************************** + +  FileName    [covTest.c] + +  SystemName  [ABC: Logic synthesis and verification system.] +  +  PackageName [Mapping into network of SOPs/ESOPs.] + +  Synopsis    [Testing procedures.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: covTest.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cov.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Min_Cube_t * Abc_NodeDeriveCoverPro( Min_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1 ) +{ +    Min_Cube_t * pCover; +    Min_Cube_t * pCube0, * pCube1, * pCube; +    if ( pCover0 == NULL || pCover1 == NULL ) +        return NULL; +    // clean storage +    Min_ManClean( p, p->nVars ); +    // go through the cube pairs +    Min_CoverForEachCube( pCover0, pCube0 ) +    Min_CoverForEachCube( pCover1, pCube1 ) +    { +        if ( Min_CubesDisjoint( pCube0, pCube1 ) ) +            continue; +        pCube = Min_CubesProduct( p, pCube0, pCube1 ); +        // add the cube to storage +        Min_SopAddCube( p, pCube ); +    } +    Min_SopMinimize( p ); +    pCover = Min_CoverCollect( p, p->nVars ); +    assert( p->nCubes == Min_CoverCountCubes(pCover) ); +    return pCover; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Min_Cube_t * Abc_NodeDeriveCoverSum( Min_Man_t * p, Min_Cube_t * pCover0, Min_Cube_t * pCover1 ) +{ +    Min_Cube_t * pCover; +    Min_Cube_t * pThis, * pCube; +    if ( pCover0 == NULL || pCover1 == NULL ) +        return NULL; +    // clean storage +    Min_ManClean( p, p->nVars ); +    // add the cubes to storage +    Min_CoverForEachCube( pCover0, pThis ) +    { +        pCube = Min_CubeDup( p, pThis ); +        Min_SopAddCube( p, pCube ); +    } +    Min_CoverForEachCube( pCover1, pThis ) +    { +        pCube = Min_CubeDup( p, pThis ); +        Min_SopAddCube( p, pCube ); +    } +    Min_SopMinimize( p ); +    pCover = Min_CoverCollect( p, p->nVars ); +    assert( p->nCubes == Min_CoverCountCubes(pCover) ); +    return pCover; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Abc_NodeDeriveSops( Min_Man_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vSupp, Vec_Ptr_t * vNodes ) +{ +    Min_Cube_t * pCov0[2], * pCov1[2]; +    Min_Cube_t * pCoverP, * pCoverN; +    Abc_Obj_t * pObj; +    int i, nCubes, fCompl0, fCompl1; + +    // set elementary vars +    Vec_PtrForEachEntry( vSupp, pObj, i ) +    { +        pObj->pCopy = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 0 ); +        pObj->pNext = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 1 ); +    } + +    // get the cover for each node in the array +    Vec_PtrForEachEntry( vNodes, pObj, i ) +    { +        // get the complements +        fCompl0 = Abc_ObjFaninC0(pObj); +        fCompl1 = Abc_ObjFaninC1(pObj); +        // get the covers +        pCov0[0] = (Min_Cube_t *)Abc_ObjFanin0(pObj)->pCopy; +        pCov0[1] = (Min_Cube_t *)Abc_ObjFanin0(pObj)->pNext; +        pCov1[0] = (Min_Cube_t *)Abc_ObjFanin1(pObj)->pCopy; +        pCov1[1] = (Min_Cube_t *)Abc_ObjFanin1(pObj)->pNext; +        // compute the covers +        pCoverP = Abc_NodeDeriveCoverPro( p, pCov0[ fCompl0], pCov1[ fCompl1] ); +        pCoverN = Abc_NodeDeriveCoverSum( p, pCov0[!fCompl0], pCov1[!fCompl1] ); +        // set the covers +        pObj->pCopy = (Abc_Obj_t *)pCoverP; +        pObj->pNext = (Abc_Obj_t *)pCoverN; +    } + +     nCubes = ABC_MIN( Min_CoverCountCubes(pCoverN), Min_CoverCountCubes(pCoverP) ); + +/* +printf( "\n\n" ); +Min_CoverWrite( stdout, pCoverP ); +printf( "\n\n" ); +Min_CoverWrite( stdout, pCoverN ); +*/ + +//    printf( "\n" ); +//    Min_CoverWrite( stdout, pCoverP ); + +//    Min_CoverExpand( p, pCoverP ); +//    Min_SopMinimize( p ); +//    pCoverP = Min_CoverCollect( p, p->nVars ); + +//    printf( "\n" ); +//    Min_CoverWrite( stdout, pCoverP ); + +//    nCubes = Min_CoverCountCubes(pCoverP); + +    // clean the copy fields +    Vec_PtrForEachEntry( vNodes, pObj, i ) +        pObj->pCopy = pObj->pNext = NULL; +    Vec_PtrForEachEntry( vSupp, pObj, i ) +        pObj->pCopy = pObj->pNext = NULL; + +//    Min_CoverWriteFile( pCoverP, Abc_ObjName(pRoot), 0 ); +//    printf( "\n" ); +//    Min_CoverWrite( stdout, pCoverP ); + +//    printf( "\n" ); +//    Min_CoverWrite( stdout, pCoverP ); +//    printf( "\n" ); +//    Min_CoverWrite( stdout, pCoverN ); +    return nCubes; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Abc_NtkTestSop( Abc_Ntk_t * pNtk ) +{ +    Min_Man_t * p; +    Vec_Ptr_t * vSupp, * vNodes; +    Abc_Obj_t * pObj; +    int i, nCubes; +    assert( Abc_NtkIsStrash(pNtk) ); + +    Abc_NtkCleanCopy(pNtk); +    Abc_NtkCleanNext(pNtk); +    Abc_NtkForEachCo( pNtk, pObj, i ) +    { +        if ( !Abc_ObjIsNode(Abc_ObjFanin0(pObj)) ) +        { +            printf( "%-20s :  Trivial.\n", Abc_ObjName(pObj) ); +            continue; +        } + +        vSupp  = Abc_NtkNodeSupport( pNtk, &pObj, 1 ); +        vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 ); + +        printf( "%20s :  Cone = %5d.  Supp = %5d.  ",  +            Abc_ObjName(pObj), vNodes->nSize, vSupp->nSize ); +//        if ( vSupp->nSize <= 128 ) +        { +            p = Min_ManAlloc( vSupp->nSize ); +            nCubes = Abc_NodeDeriveSops( p, pObj, vSupp, vNodes ); +            printf( "Cubes = %5d.  ", nCubes ); +            Min_ManFree( p ); +        } +        printf( "\n" ); + + +        Vec_PtrFree( vNodes ); +        Vec_PtrFree( vSupp ); +    } +} + + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Min_Cube_t * Abc_NodeDeriveCover( Min_Man_t * p, Min_Cube_t * pCov0, Min_Cube_t * pCov1, int fComp0, int fComp1 ) +{ +    Min_Cube_t * pCover0, * pCover1, * pCover; +    Min_Cube_t * pCube0, * pCube1, * pCube; + +    // complement the first if needed +    if ( !fComp0 ) +        pCover0 = pCov0; +    else if ( pCov0 && pCov0->nLits == 0 ) // topmost one is the tautology cube +        pCover0 = pCov0->pNext; +    else +        pCover0 = p->pOne0, p->pOne0->pNext = pCov0; + +    // complement the second if needed +    if ( !fComp1 ) +        pCover1 = pCov1; +    else if ( pCov1 && pCov1->nLits == 0 ) // topmost one is the tautology cube +        pCover1 = pCov1->pNext; +    else +        pCover1 = p->pOne1, p->pOne1->pNext = pCov1; + +    if ( pCover0 == NULL || pCover1 == NULL ) +        return NULL; + +    // clean storage +    Min_ManClean( p, p->nVars ); +    // go through the cube pairs +    Min_CoverForEachCube( pCover0, pCube0 ) +    Min_CoverForEachCube( pCover1, pCube1 ) +    { +        if ( Min_CubesDisjoint( pCube0, pCube1 ) ) +            continue; +        pCube = Min_CubesProduct( p, pCube0, pCube1 ); +        // add the cube to storage +        Min_EsopAddCube( p, pCube ); +    } +  +    if ( p->nCubes > 10 ) +    { +//        printf( "(%d,", p->nCubes ); +        Min_EsopMinimize( p ); +//        printf( "%d) ", p->nCubes ); +    } + +    pCover = Min_CoverCollect( p, p->nVars ); +    assert( p->nCubes == Min_CoverCountCubes(pCover) ); + +//    if ( p->nCubes > 1000 ) +//        printf( "%d ", p->nCubes ); +    return pCover; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Abc_NodeDeriveEsops( Min_Man_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vSupp, Vec_Ptr_t * vNodes ) +{ +    Min_Cube_t * pCover, * pCube; +    Abc_Obj_t * pObj; +    int i; + +    // set elementary vars +    Vec_PtrForEachEntry( vSupp, pObj, i ) +        pObj->pCopy = (Abc_Obj_t *)Min_CubeAllocVar( p, i, 0 ); + +    // get the cover for each node in the array +    Vec_PtrForEachEntry( vNodes, pObj, i ) +    { +        pCover = Abc_NodeDeriveCover( p,   +            (Min_Cube_t *)Abc_ObjFanin0(pObj)->pCopy,   +            (Min_Cube_t *)Abc_ObjFanin1(pObj)->pCopy, +            Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); +        pObj->pCopy = (Abc_Obj_t *)pCover; +        if ( p->nCubes > 3000 ) +            return -1; +    } + +    // add complement if needed +    if ( Abc_ObjFaninC0(pRoot) ) +    { +        if ( pCover && pCover->nLits == 0 ) // topmost one is the tautology cube +        { +            pCube = pCover; +            pCover = pCover->pNext; +            Min_CubeRecycle( p, pCube ); +            p->nCubes--; +        } +        else +        { +            pCube = Min_CubeAlloc( p ); +            pCube->pNext = pCover; +            p->nCubes++; +        } +    } +/* +    Min_CoverExpand( p, pCover ); +    Min_EsopMinimize( p ); +    pCover = Min_CoverCollect( p, p->nVars ); +*/ +    // clean the copy fields +    Vec_PtrForEachEntry( vNodes, pObj, i ) +        pObj->pCopy = NULL; +    Vec_PtrForEachEntry( vSupp, pObj, i ) +        pObj->pCopy = NULL; + +//    Min_CoverWriteFile( pCover, Abc_ObjName(pRoot), 1 ); +//    Min_CoverWrite( stdout, pCover ); +    return p->nCubes; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Abc_NtkTestEsop( Abc_Ntk_t * pNtk ) +{ +    Min_Man_t * p; +    Vec_Ptr_t * vSupp, * vNodes; +    Abc_Obj_t * pObj; +    int i, nCubes; +    assert( Abc_NtkIsStrash(pNtk) ); + +    Abc_NtkCleanCopy(pNtk); +    Abc_NtkForEachCo( pNtk, pObj, i ) +    { +        if ( !Abc_ObjIsNode(Abc_ObjFanin0(pObj)) ) +        { +            printf( "%-20s :  Trivial.\n", Abc_ObjName(pObj) ); +            continue; +        } + +        vSupp  = Abc_NtkNodeSupport( pNtk, &pObj, 1 ); +        vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 ); + +        printf( "%20s :  Cone = %5d.  Supp = %5d.  ",  +            Abc_ObjName(pObj), vNodes->nSize, vSupp->nSize ); +//        if ( vSupp->nSize <= 128 ) +        { +            p = Min_ManAlloc( vSupp->nSize ); +            nCubes = Abc_NodeDeriveEsops( p, pObj, vSupp, vNodes ); +            printf( "Cubes = %5d.  ", nCubes ); +            Min_ManFree( p ); +        } +        printf( "\n" ); + + +        Vec_PtrFree( vNodes ); +        Vec_PtrFree( vSupp ); +    } +} + + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/map/cov/module.make b/src/map/cov/module.make new file mode 100644 index 00000000..5b68c64c --- /dev/null +++ b/src/map/cov/module.make @@ -0,0 +1,7 @@ +SRC +=    src/map/cov/covBuild.c \ +    src/map/cov/covCore.c \ +    src/map/cov/covMan.c \ +    src/map/cov/covMinEsop.c \ +    src/map/cov/covMinMan.c \ +    src/map/cov/covMinSop.c \ +    src/map/cov/covMinUtil.c | 
