Beispiel #1
0
ABC_NAMESPACE_IMPL_START


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

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

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

  Synopsis    [Converts pNode->pData gates into array of SC_Lit gate IDs and back.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_SclMioGates2SclGates( SC_Lib * pLib, Abc_Ntk_t * p )
{
    Abc_Obj_t * pObj;
    int i, gateId, bufferId;
    // find buffer
    if ( Mio_LibraryReadBuf((Mio_Library_t *)p->pManFunc) == NULL )
    {
        printf( "Cannot find buffer in the current library. Quitting.\n" );
        return;
    }
    bufferId = Abc_SclCellFind( pLib, Mio_GateReadName(Mio_LibraryReadBuf((Mio_Library_t *)p->pManFunc)) );
    assert( bufferId >= 0 );
    // remap cells
    assert( p->vGates == NULL );
    p->vGates = Vec_IntStartFull( Abc_NtkObjNumMax(p) );
    Abc_NtkForEachNodeNotBarBuf1( p, pObj, i )
    {
        gateId = Abc_SclCellFind( pLib, Mio_GateReadName((Mio_Gate_t *)pObj->pData) );
        assert( gateId >= 0 );
        Vec_IntWriteEntry( p->vGates, i, gateId );
    }
/**Function*************************************************************

  Synopsis    [Replaces a fanin of the node.]

  Description [The node is pObj. An old fanin of this node (pFaninOld) has to be
  replaced by a new fanin (pFaninNew). Assumes that the node and the old fanin 
  are not complemented. The new fanin can be complemented. In this case, the
  polarity of the new fanin will change, compared to the polarity of the old fanin.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_ObjPatchFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFaninOld, Abc_Obj_t * pFaninNew )
{
    Abc_Obj_t * pFaninNewR = Abc_ObjRegular(pFaninNew);
    int iFanin;//, nLats;//, fCompl;
    assert( !Abc_ObjIsComplement(pObj) );
    assert( !Abc_ObjIsComplement(pFaninOld) );
    assert( pFaninOld != pFaninNewR );
//    assert( pObj != pFaninOld );
//    assert( pObj != pFaninNewR );
    assert( pObj->pNtk == pFaninOld->pNtk );
    assert( pObj->pNtk == pFaninNewR->pNtk );
    if ( (iFanin = Vec_IntFind( &pObj->vFanins, pFaninOld->Id )) == -1 )
    {
        printf( "Node %s is not among", Abc_ObjName(pFaninOld) );
        printf( " the fanins of node %s...\n", Abc_ObjName(pObj) );
        return;
    }

    // remember the attributes of the old fanin
//    fCompl = Abc_ObjFaninC(pObj, iFanin);
    // replace the old fanin entry by the new fanin entry (removes attributes)
    Vec_IntWriteEntry( &pObj->vFanins, iFanin, pFaninNewR->Id );
    // set the attributes of the new fanin
//    if ( fCompl ^ Abc_ObjIsComplement(pFaninNew) )
//        Abc_ObjSetFaninC( pObj, iFanin );
    if ( Abc_ObjIsComplement(pFaninNew) )
        Abc_ObjXorFaninC( pObj, iFanin );

//    if ( Abc_NtkIsSeq(pObj->pNtk) && (nLats = Seq_ObjFaninL(pObj, iFanin)) )
//        Seq_ObjSetFaninL( pObj, iFanin, nLats );
    // update the fanout of the fanin
    if ( !Vec_IntRemove( &pFaninOld->vFanouts, pObj->Id ) )
    {
        printf( "Node %s is not among", Abc_ObjName(pObj) );
        printf( " the fanouts of its old fanin %s...\n", Abc_ObjName(pFaninOld) );
//        return;
    }
    Vec_IntPushMem( pObj->pNtk->pMmStep, &pFaninNewR->vFanouts, pObj->Id );
}
Beispiel #3
0
void Wlc_WriteTables( FILE * pFile, Wlc_Ntk_t * p )
{
    Vec_Int_t * vNodes;
    Wlc_Obj_t * pObj, * pFanin;
    word * pTable;
    int i;
    if ( p->vTables == NULL || Vec_PtrSize(p->vTables) == 0 )
        return;
    // map tables into their nodes
    vNodes = Vec_IntStart( Vec_PtrSize(p->vTables) );
    Wlc_NtkForEachObj( p, pObj, i )
        if ( pObj->Type == WLC_OBJ_TABLE )
            Vec_IntWriteEntry( vNodes, Wlc_ObjTableId(pObj), i );
    // write tables
    Vec_PtrForEachEntry( word *, p->vTables, pTable, i )
    {
        pObj = Wlc_NtkObj( p, Vec_IntEntry(vNodes, i) );
        assert( pObj->Type == WLC_OBJ_TABLE );
        pFanin = Wlc_ObjFanin0( p, pObj );
        Wlc_WriteTableOne( pFile, Wlc_ObjRange(pFanin), Wlc_ObjRange(pObj), pTable, i );
    }
    Vec_IntFree( vNodes );
}
Beispiel #4
0
/**Function*************************************************************

  Synopsis    [For each cut, returns PIs that can be quantified.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Ptr_t * Llb_ManCutMap( Aig_Man_t * p, Vec_Ptr_t * vResult, Vec_Ptr_t * vSupps )
{
    int fShowMatrix = 1;
    Vec_Ptr_t * vMaps, * vOne;
    Vec_Int_t * vMap, * vPrev, * vNext;
    Aig_Obj_t * pObj;
    int * piFirst, * piLast;
    int i, k, CounterPlus, CounterMinus, Counter;

    vMaps = Vec_PtrAlloc( 100 );
    Vec_PtrForEachEntry( Vec_Ptr_t *, vResult, vOne, i )
    {
        vMap = Vec_IntStart( Aig_ManObjNumMax(p) );
        Vec_PtrForEachEntry( Aig_Obj_t *, vOne, pObj, k )
        {
            if ( !Saig_ObjIsPi(p, pObj) )
                Vec_IntWriteEntry( vMap, pObj->Id, 1 );
//            else
//printf( "*" );
//printf( "%d ", pObj->Id );
        }
        Vec_PtrPush( vMaps, vMap );
//printf( "\n" );
    }
Beispiel #5
0
/**Function*************************************************************

  Synopsis    [Create mapping of node IDs of pNtk into equiv classes of pMiter.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Int_t * Abc_NtkDressMapClasses( Aig_Man_t * pMiter, Abc_Ntk_t * pNtk )
{
    Vec_Int_t * vId2Lit;
    Abc_Obj_t * pObj, * pAnd;
    Aig_Obj_t * pObjMan, * pObjMiter, * pObjRepr;
    int i;
    vId2Lit = Vec_IntAlloc( 0 );
    Vec_IntFill( vId2Lit, Abc_NtkObjNumMax(pNtk), -1 );
    Abc_NtkForEachNode( pNtk, pObj, i )
    {
        // get the pointer to the miter node corresponding to pObj
        if ( (pAnd = Abc_ObjRegular(pObj->pCopy)) && Abc_ObjType(pAnd) != ABC_OBJ_NONE &&          // strashed node is present and legal
             (pObjMan = Aig_Regular((Aig_Obj_t *)pAnd->pCopy)) && Aig_ObjType(pObjMan) != AIG_OBJ_NONE &&       // AIG node is present and legal
             (pObjMiter = Aig_Regular((Aig_Obj_t *)pObjMan->pData)) && Aig_ObjType(pObjMiter) != AIG_OBJ_NONE ) // miter node is present and legal
        {
            // get the representative of the miter node
            pObjRepr = Aig_ObjRepr( pMiter, pObjMiter );
            pObjRepr = pObjRepr? pObjRepr : pObjMiter;
            // map pObj (whose ID is i) into the repr node ID (i.e. equiv class)
            Vec_IntWriteEntry( vId2Lit, i, Aig_ObjId(pObjRepr) );
        }
    }
    return vId2Lit;
}
Beispiel #6
0
/**Function*************************************************************

  Synopsis    [Performs induction by unrolling timeframes backward.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fUnique, int fUniqueAll, int fGetCex, int fVerbose, int fVeryVerbose )
{
    sat_solver * pSat;
    Aig_Man_t * pAigPart;
    Cnf_Dat_t * pCnfPart;
    Vec_Int_t * vTopVarNums, * vState, * vTopVarIds = NULL;
    Vec_Ptr_t * vTop, * vBot;
    Aig_Obj_t * pObjPi, * pObjPiCopy, * pObjPo;
    int i, k, f, clk, Lits[2], status, RetValue, nSatVarNum, nConfPrev;
    int nOldSize, iReg, iLast, fAdded, nConstrs = 0, nClauses = 0;
    assert( fUnique == 0 || fUniqueAll == 0 );
    assert( Saig_ManPoNum(p) == 1 );
    Aig_ManSetPioNumbers( p );

    // start the top by including the PO
    vBot = Vec_PtrAlloc( 100 );
    vTop = Vec_PtrAlloc( 100 );
    vState = Vec_IntAlloc( 1000 );
    Vec_PtrPush( vTop, Aig_ManPo(p, 0) );
    // start the array of CNF variables
    vTopVarNums = Vec_IntAlloc( 100 );
    // start the solver
    pSat = sat_solver_new();
    sat_solver_setnvars( pSat, 1000 );

    // iterate backward unrolling
    RetValue = -1;
    nSatVarNum = 0;
    if ( fVerbose )
        printf( "Induction parameters: FramesMax = %5d. ConflictMax = %6d.\n", nFramesMax, nConfMax );
    for ( f = 0; ; f++ )
    { 
        if ( f > 0 )
        {
            Aig_ManStop( pAigPart );
            Cnf_DataFree( pCnfPart );
        }
        clk = clock();
        // get the bottom
        Aig_SupportNodes( p, (Aig_Obj_t **)Vec_PtrArray(vTop), Vec_PtrSize(vTop), vBot );
        // derive AIG for the part between top and bottom
        pAigPart = Aig_ManDupSimpleDfsPart( p, vBot, vTop );
        // convert it into CNF
        pCnfPart = Cnf_Derive( pAigPart, Aig_ManPoNum(pAigPart) );
        Cnf_DataLift( pCnfPart, nSatVarNum );
        nSatVarNum += pCnfPart->nVars;
        nClauses   += pCnfPart->nClauses;

        // remember top frame var IDs
        if ( fGetCex && vTopVarIds == NULL )
        {
            vTopVarIds = Vec_IntStartFull( Aig_ManPiNum(p) );
            Aig_ManForEachPi( p, pObjPi, i )
            {
                if ( pObjPi->pData == NULL )
                    continue;
                pObjPiCopy = (Aig_Obj_t *)pObjPi->pData;
                assert( Aig_ObjIsPi(pObjPiCopy) );
                if ( Saig_ObjIsPi(p, pObjPi) )
                    Vec_IntWriteEntry( vTopVarIds, Aig_ObjPioNum(pObjPi) + Saig_ManRegNum(p), pCnfPart->pVarNums[Aig_ObjId(pObjPiCopy)] );
                else if ( Saig_ObjIsLo(p, pObjPi) )
                    Vec_IntWriteEntry( vTopVarIds, Aig_ObjPioNum(pObjPi) - Saig_ManPiNum(p), pCnfPart->pVarNums[Aig_ObjId(pObjPiCopy)] );
                else assert( 0 );
            }
        }

        // stitch variables of top and bot
        assert( Aig_ManPoNum(pAigPart)-1 == Vec_IntSize(vTopVarNums) );
        Aig_ManForEachPo( pAigPart, pObjPo, i )
        {
            if ( i == 0 )
            {
                // do not perform inductive strengthening
//                if ( f > 0 )
//                    continue;
                // add topmost literal
                Lits[0] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], f>0 );
                if ( !sat_solver_addclause( pSat, Lits, Lits+1 ) )
                    assert( 0 );
                nClauses++;
                continue;
            }
            Lits[0] = toLitCond( Vec_IntEntry(vTopVarNums, i-1), 0 );
            Lits[1] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], 1 );
            if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) )
                assert( 0 );
            Lits[0] = toLitCond( Vec_IntEntry(vTopVarNums, i-1), 1 );
            Lits[1] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], 0 );
            if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) )
                assert( 0 );
            nClauses += 2;
        }
        // add CNF to the SAT solver
        for ( i = 0; i < pCnfPart->nClauses; i++ )
            if ( !sat_solver_addclause( pSat, pCnfPart->pClauses[i], pCnfPart->pClauses[i+1] ) )
                break;
        if ( i < pCnfPart->nClauses )
        {
//            printf( "SAT solver became UNSAT after adding clauses.\n" );
            RetValue = 1;
            break;
        }

        // create new set of POs to derive new top
        Vec_PtrClear( vTop );
        Vec_PtrPush( vTop, Aig_ManPo(p, 0) );
        Vec_IntClear( vTopVarNums );
        nOldSize = Vec_IntSize(vState);
        Vec_IntFillExtra( vState, nOldSize + Aig_ManRegNum(p), -1 );
        Vec_PtrForEachEntry( Aig_Obj_t *, vBot, pObjPi, i )
        {
            assert( Aig_ObjIsPi(pObjPi) );
            if ( Saig_ObjIsLo(p, pObjPi) )
            {
                pObjPiCopy = (Aig_Obj_t *)pObjPi->pData;
                assert( pObjPiCopy != NULL );
                Vec_PtrPush( vTop, Saig_ObjLoToLi(p, pObjPi) );
                Vec_IntPush( vTopVarNums, pCnfPart->pVarNums[pObjPiCopy->Id] );

                iReg = pObjPi->PioNum - Saig_ManPiNum(p);
                assert( iReg >= 0 && iReg < Aig_ManRegNum(p) );
                Vec_IntWriteEntry( vState, nOldSize+iReg, pCnfPart->pVarNums[pObjPiCopy->Id] );
            }
        } 
Beispiel #7
0
static inline void Gia_ObjEdgeClean( int iObj, Vec_Int_t * vEdge1, Vec_Int_t * vEdge2 )
{
    Vec_IntWriteEntry( vEdge1, iObj, 0 );
    Vec_IntWriteEntry( vEdge2, iObj, 0 );
}
Beispiel #8
0
static inline void  Kf_ObjSetCuts( Kf_Man_t * p, int i, Vec_Int_t * vVec ) { Vec_IntWriteEntry(&p->vCuts, i, Vec_SetAppend(&p->pMem, Vec_IntArray(vVec), Vec_IntSize(vVec)));  }
Beispiel #9
0
static inline void  Gia_ObjSetDom( Gia_Man_t * p, Gia_Obj_t * pObj, int d )  { Vec_IntWriteEntry(p->vDoms, Gia_ObjId(p, pObj), d);  }
Beispiel #10
0
/**Function*************************************************************

  Synopsis    [Replaces one object by another.]

  Description [Both objects are currently in the manager. The new object
  (pObjNew) should be used instead of the old object (pObjOld). If the 
  new object is complemented or used, the buffer is added.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop, int fUpdateLevel )
{
    int nRefsOld;//, clk;
    // the object to be replaced cannot be complemented
    assert( !Ivy_IsComplement(pObjOld) );
    // the object to be replaced cannot be a terminal
    assert( Ivy_ObjIsNone(pObjOld) || !Ivy_ObjIsPi(pObjOld) );
    // the object to be used cannot be a PO or assert
    assert( !Ivy_ObjIsBuf(Ivy_Regular(pObjNew)) );
    // the object cannot be the same
    assert( pObjOld != Ivy_Regular(pObjNew) );
//printf( "Replacing %d by %d.\n", Ivy_Regular(pObjOld)->Id, Ivy_Regular(pObjNew)->Id );

    // if HAIG is defined, create the choice node
    if ( p->pHaig )
    {
//        if ( pObjOld->Id == 31 )
//        {
//            Ivy_ManShow( p, 0 );
//            Ivy_ManShow( p->pHaig, 1 );
//        }
        Ivy_ManHaigCreateChoice( p, pObjOld, pObjNew );
    }
    // if the new object is complemented or already used, add the buffer
    if ( Ivy_IsComplement(pObjNew) || Ivy_ObjIsLatch(pObjNew) || Ivy_ObjRefs(pObjNew) > 0 || Ivy_ObjIsPi(pObjNew) || Ivy_ObjIsConst1(pObjNew) )
        pObjNew = Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, pObjNew, NULL, IVY_BUF, IVY_INIT_NONE) );
    assert( !Ivy_IsComplement(pObjNew) );
    if ( fUpdateLevel )
    {
//clk = clock();
        // if the new node's arrival time is different, recursively update arrival time of the fanouts
        if ( p->fFanout && !Ivy_ObjIsBuf(pObjNew) && pObjOld->Level != pObjNew->Level )
        {
            assert( Ivy_ObjIsNode(pObjOld) );
            pObjOld->Level = pObjNew->Level;
            Ivy_ObjUpdateLevel_rec( p, pObjOld );
        }
//p->time1 += clock() - clk;
        // if the new node's required time has changed, recursively update required time of the fanins
//clk = clock();
        if ( p->vRequired )
        {
            int ReqNew = Vec_IntEntry(p->vRequired, pObjOld->Id);
            if ( ReqNew < Vec_IntEntry(p->vRequired, pObjNew->Id) )
            {
                Vec_IntWriteEntry( p->vRequired, pObjNew->Id, ReqNew );
                Ivy_ObjUpdateLevelR_rec( p, pObjNew, ReqNew );
            }
        }
//p->time2 += clock() - clk;
    }
    // delete the old object
    if ( fDeleteOld )
        Ivy_ObjDelete_rec( p, pObjOld, fFreeTop );
    // make sure object is not pointing to itself
    assert( Ivy_ObjFanin0(pObjNew) == NULL || pObjOld != Ivy_ObjFanin0(pObjNew) );
    assert( Ivy_ObjFanin1(pObjNew) == NULL || pObjOld != Ivy_ObjFanin1(pObjNew) );
    // make sure the old node has no fanin fanout pointers
    if ( p->fFanout )
    {
        assert( pObjOld->pFanout != NULL );
        assert( pObjNew->pFanout == NULL );
        pObjNew->pFanout = pObjOld->pFanout;
    }
    // transfer the old object
    assert( Ivy_ObjRefs(pObjNew) == 0 );
    nRefsOld = pObjOld->nRefs;  
    Ivy_ObjOverwrite( pObjOld, pObjNew );
    pObjOld->nRefs = nRefsOld;
    // patch the fanout of the fanins 
    if ( p->fFanout )
    {
        Ivy_ObjPatchFanout( p, Ivy_ObjFanin0(pObjOld), pObjNew, pObjOld );
        if ( Ivy_ObjFanin1(pObjOld) )
        Ivy_ObjPatchFanout( p, Ivy_ObjFanin1(pObjOld), pObjNew, pObjOld );
    }
    // update the hash table
    Ivy_TableUpdate( p, pObjNew, pObjOld->Id );
    // recycle the object that was taken over by pObjOld
    Vec_PtrWriteEntry( p->vObjs, pObjNew->Id, NULL );
    Ivy_ManRecycleMemory( p, pObjNew );
    // if the new node is the buffer propagate it
    if ( p->fFanout && Ivy_ObjIsBuf(pObjOld) )
        Vec_PtrPush( p->vBufs, pObjOld );
//    Ivy_ManCheckFanouts( p );
//    printf( "\n" );
/*
    if ( p->pHaig )
    {
        int x;
        Ivy_ManShow( p, 0, NULL );
        Ivy_ManShow( p->pHaig, 1, NULL );
        x = 0;
    }
*/
//    if ( Ivy_ManCheckFanoutNums(p) )
//    {
//        int x = 0;
//    }
}
Beispiel #11
0
 Vec_IntForEachEntry( vSigs, NameId, i )
 {
     assert( Vec_IntEntry(vMap, NameId) != -1 );
     Vec_IntWriteEntry( vSigs, i++, Vec_IntEntry(vMap, NameId) );
 }
Beispiel #12
0
 Psr_NtkForEachPo( pNtkBox, NameId, i )
 {
     assert( Vec_IntEntry(vMap, NameId) == -1 );
     Vec_IntWriteEntry( vMap, NameId, Psr_NtkPiNum(pNtkBox) + i + 1 ); // +1 to keep 1st form input non-zero
 }
Beispiel #13
0
static inline void  Sfm_ObjSetTravIdCurrent2( Sfm_Ntk_t * p, int Id )  { Vec_IntWriteEntry( &p->vTravIds2, Id, p->nTravIds2 );     }
Beispiel #14
0
ABC_NAMESPACE_IMPL_START


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

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

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

  Synopsis    []

  Description []
  
  SideEffects []

  SeeAlso     []

***********************************************************************/
/*
Vec_Int_t * Gia_WriteDotAigMarks( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds )
{
    int i;
    Vec_Int_t * vMarks = Vec_IntStart( Gia_ManObjNum(p) );
    for ( i = 0; i < Vec_IntSize(vHadds)/2; i++ )
    {
        Vec_IntWriteEntry( vMarks, Vec_IntEntry(vHadds, 2*i+0), Abc_Var2Lit(i+1, 0) );
        Vec_IntWriteEntry( vMarks, Vec_IntEntry(vHadds, 2*i+1), Abc_Var2Lit(i+1, 0) );
    }
    for ( i = 0; i < Vec_IntSize(vFadds)/5; i++ )
    {
        Vec_IntWriteEntry( vMarks, Vec_IntEntry(vFadds, 5*i+3), Abc_Var2Lit(i+1, 1) );
        Vec_IntWriteEntry( vMarks, Vec_IntEntry(vFadds, 5*i+4), Abc_Var2Lit(i+1, 1) );
    }
    return vMarks;
}
int Gia_WriteDotAigLevel_rec( Gia_Man_t * p, Vec_Int_t * vMarks, Vec_Int_t * vFadds, Vec_Int_t * vHadds, int Id, Vec_Int_t * vLevel )
{
    int Level = Vec_IntEntry(vLevel, Id), Mark = Vec_IntEntry(vMarks, Id);
    if ( Level || Mark == -1 )
        return Level;
    if ( Mark == 0 )
    {
        Gia_Obj_t * pObj = Gia_ManObj( p, Id );
        int Level0 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId0(pObj, Id), vLevel );
        int Level1 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId1(pObj, Id), vLevel );
        Level = Abc_MaxInt(Level0, Level1) + 1;
        Vec_IntWriteEntry( vLevel, Id, Level );
        Vec_IntWriteEntry( vMarks, Id, -1 );
    }
    else if ( Abc_LitIsCompl(Mark) ) // FA
    {
        int i, * pFanins = Vec_IntEntryP( vFadds, 5*(Abc_Lit2Var(Mark)-1) );
        assert( pFanins[3] == Id || pFanins[4] == Id );
        for ( i = 0; i < 3; i++ )
            Level = Abc_MaxInt( Level, Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, pFanins[i], vLevel ) );
        Vec_IntWriteEntry( vLevel, pFanins[3], Level+1 );
        Vec_IntWriteEntry( vLevel, pFanins[4], Level+1 );
    }
    else  // HA
    {
        int * pFanins = Vec_IntEntryP( vHadds, 2*(Abc_Lit2Var(Mark)-1) );
        Gia_Obj_t * pObj = Gia_ManObj( p, pFanins[1] );
        int Level0 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId0(pObj, Id), vLevel );
        int Level1 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId1(pObj, Id), vLevel );
        assert( pFanins[0] == Id || pFanins[1] == Id );
        Level = Abc_MaxInt(Level0, Level1) + 1;
        Vec_IntWriteEntry( vLevel, pFanins[0], Level );
        Vec_IntWriteEntry( vLevel, pFanins[1], Level );
    }
    return Level;
}
int Gia_WriteDotAigLevel( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds, Vec_Int_t ** pvMarks, Vec_Int_t ** pvLevel )
{
    Vec_Int_t * vMarks = Gia_WriteDotAigMarks( p, vFadds, vHadds );
    Vec_Int_t * vLevel = Vec_IntStart( Gia_ManObjNum(p) );
    int i, Id, Level = 0;
    Vec_IntWriteEntry( vMarks, 0, -1 );
    Gia_ManForEachCiId( p, Id, i )
        Vec_IntWriteEntry( vMarks, Id, -1 );
    Gia_ManForEachCoDriverId( p, Id, i )
        Level = Abc_MaxInt( Level, Gia_WriteDotAigLevel_rec(p, vMarks, vFadds, vHadds, Id, vLevel) );
    Gia_ManForEachCoId( p, Id, i )
        Vec_IntWriteEntry( vMarks, Id, -1 );
    *pvMarks = vMarks;
    *pvLevel = vLevel;
    return Level;
}
*/
int Gia_WriteDotAigLevel( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds, Vec_Int_t * vRecord, Vec_Int_t ** pvLevel, Vec_Int_t ** pvMarks, Vec_Int_t ** pvRemap )
{
    Vec_Int_t * vLevel = Vec_IntStart( Gia_ManObjNum(p) );
    Vec_Int_t * vMarks = Vec_IntStart( Gia_ManObjNum(p) );
    Vec_Int_t * vRemap = Vec_IntStartNatural( Gia_ManObjNum(p) );
    int i, k, Id, Entry, LevelMax = 0;

    Vec_IntWriteEntry( vMarks, 0, -1 );
    Gia_ManForEachCiId( p, Id, i )
        Vec_IntWriteEntry( vMarks, Id, -1 );
    Gia_ManForEachCoId( p, Id, i )
        Vec_IntWriteEntry( vMarks, Id, -1 );

    Vec_IntForEachEntry( vRecord, Entry, i )
    {
        int Level = 0;
        int Node = Abc_Lit2Var2(Entry);
        int Attr = Abc_Lit2Att2(Entry);
        if ( Attr == 2 )
        {
            int * pFanins = Vec_IntEntryP( vFadds, 5*Node );
            for ( k = 0; k < 3; k++ )
                Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, pFanins[k]) );
            Vec_IntWriteEntry( vLevel, pFanins[3], Level+1 );
            Vec_IntWriteEntry( vLevel, pFanins[4], Level+1 );
            Vec_IntWriteEntry( vMarks, pFanins[4], Entry );
            Vec_IntWriteEntry( vRemap, pFanins[3], pFanins[4] );
            //printf( "Making FA output %d.\n", pFanins[4] );
        }
        else if ( Attr == 1 )
        {
            int * pFanins = Vec_IntEntryP( vHadds, 2*Node );
            Gia_Obj_t * pObj = Gia_ManObj( p, pFanins[1] );
            int pFaninsIn[2] = { Gia_ObjFaninId0(pObj, pFanins[1]), Gia_ObjFaninId1(pObj, pFanins[1]) };
            for ( k = 0; k < 2; k++ )
                Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, pFaninsIn[k]) );
            Vec_IntWriteEntry( vLevel, pFanins[0], Level+1 );
            Vec_IntWriteEntry( vLevel, pFanins[1], Level+1 );
            Vec_IntWriteEntry( vMarks, pFanins[1], Entry );
            Vec_IntWriteEntry( vRemap, pFanins[0], pFanins[1] );
            //printf( "Making HA output %d.\n", pFanins[1] );
        }
        else // if ( Attr == 3 || Attr == 0 )
        {
            Gia_Obj_t * pObj = Gia_ManObj( p, Node );
            int pFaninsIn[2] = { Gia_ObjFaninId0(pObj, Node), Gia_ObjFaninId1(pObj, Node) };
            for ( k = 0; k < 2; k++ )
                Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, pFaninsIn[k]) );
            Vec_IntWriteEntry( vLevel, Node, Level+1 );
            Vec_IntWriteEntry( vMarks, Node, -1 );
            //printf( "Making node %d.\n", Node );
        }
        LevelMax = Abc_MaxInt( LevelMax, Level+1 );
    }
Beispiel #15
0
/**Function*************************************************************

  Synopsis    [Performs AIG shrinking using the current mapping.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Gia_Man_t * Gia_ManMapShrink4( Gia_Man_t * p, int fKeepLevel, int fVerbose )
{
    Vec_Int_t * vLeaves, * vTruth, * vVisited, * vLeavesBest;
    Gia_Man_t * pNew, * pTemp;
    Gia_Obj_t * pObj, * pFanin;
    unsigned * pTruth;
    int i, k, iFan;
    abctime clk = Abc_Clock();
//    int ClassCounts[222] = {0};
    int * pLutClass, Counter = 0;
    assert( p->pMapping != NULL );
    if ( Gia_ManLutSizeMax( p ) > 4 )
    {
        printf( "Resynthesis is not performed when nodes have more than 4 inputs.\n" );
        return NULL;
    }
    pLutClass   = ABC_CALLOC( int, Gia_ManObjNum(p) );
    vLeaves     = Vec_IntAlloc( 0 );
    vTruth      = Vec_IntAlloc( (1<<16) );
    vVisited    = Vec_IntAlloc( 0 );
    vLeavesBest = Vec_IntAlloc( 4 );
    // prepare the library
    Dar_LibPrepare( 5 ); 
    // clean the old manager
    Gia_ManCleanTruth( p );
    Gia_ManSetPhase( p );
    Gia_ManFillValue( p );
    Gia_ManConst0(p)->Value = 0;
    // start the new manager
    pNew = Gia_ManStart( Gia_ManObjNum(p) );
    pNew->pName = Abc_UtilStrsav( p->pName );
    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
    Gia_ManHashAlloc( pNew );
    Gia_ManCleanLevels( pNew, Gia_ManObjNum(p) );
    Gia_ManForEachObj1( p, pObj, i )
    {
        if ( Gia_ObjIsCi(pObj) )
        {
            pObj->Value = Gia_ManAppendCi( pNew );
            if ( p->vLevels )
                Gia_ObjSetLevel( pNew, Gia_ObjFromLit(pNew, Gia_ObjValue(pObj)), Gia_ObjLevel(p, pObj) );
        }
        else if ( Gia_ObjIsCo(pObj) )
        {
            pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
        }
        else if ( Gia_ObjIsLut(p, i) )
        {
            Counter++;
            // collect leaves of this gate
            Vec_IntClear( vLeaves );
            Gia_LutForEachFanin( p, i, iFan, k )
                Vec_IntPush( vLeaves, iFan );
            for ( ; k < 4; k++ )
                Vec_IntPush( vLeaves, 0 );
            //.compute the truth table 
            pTruth = Gia_ManConvertAigToTruth( p, pObj, vLeaves, vTruth, vVisited );
            // change from node IDs to their literals
            Gia_ManForEachObjVec( vLeaves, p, pFanin, k )
            {
                assert( Gia_ObjValue(pFanin) != ~0 ); 
                Vec_IntWriteEntry( vLeaves, k, Gia_ObjValue(pFanin) );
            }
            // derive new structre
            if ( Gia_ManTruthIsConst0(pTruth, Vec_IntSize(vLeaves)) )
                pObj->Value = 0;
            else if ( Gia_ManTruthIsConst1(pTruth, Vec_IntSize(vLeaves)) )
                pObj->Value = 1;
            else
            {
                pObj->Value = Dar_LibEvalBuild( pNew, vLeaves, 0xffff & *pTruth, fKeepLevel, vLeavesBest );
                pObj->Value = Abc_LitNotCond( pObj->Value, Gia_ObjPhaseRealLit(pNew, pObj->Value) ^ pObj->fPhase );
            }
        }
    }