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

  Synopsis    [Transforms the node to take fanout sharing into account.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Seq_NodeShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr_t * vNodes )
{
    Vec_Int_t * vNums  = Seq_ObjLNums( pNode );
    Vec_Ptr_t * vInits = Seq_NodeLats( pNode );
    Abc_Obj_t * pFanout, * pBuffer;
    Abc_InitType_t Type, InitNew;
    int i;
    // collect the fanouts that satisfy the property (have initial value Init or DC)
    InitNew = ABC_INIT_DC;
    Vec_PtrClear( vNodes );
    Abc_ObjForEachFanout( pNode, pFanout, i )
    {
        if ( Seq_ObjFanoutL(pNode, pFanout) == 0 )
            continue;
        Type = Seq_NodeGetInitLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) );
        if ( Type == Init )
            InitNew = Init;
        if ( Type == Init || Type == ABC_INIT_DC )
        {
            Vec_PtrPush( vNodes, pFanout );
            Seq_NodeDeleteLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) );
        }
    }
    // create the new buffer
    pBuffer = Abc_NtkCreateNode( pNode->pNtk );
    Abc_ObjAddFanin( pBuffer, pNode );

    // grow storage for initial states
    Vec_PtrGrow( vInits, 2 * pBuffer->Id + 2 );
    for ( i = Vec_PtrSize(vInits); i < 2 * (int)pBuffer->Id + 2; i++ )
        Vec_PtrPush( vInits, NULL );
    // grow storage for numbers of latches
    Vec_IntGrow( vNums, 2 * pBuffer->Id + 2 );
    for ( i = Vec_IntSize(vNums); i < 2 * (int)pBuffer->Id + 2; i++ )
        Vec_IntPush( vNums, 0 );
    // insert the new latch
    Seq_NodeInsertFirst( pBuffer, 0, InitNew );

    // redirect the fanouts
    Vec_PtrForEachEntry( vNodes, pFanout, i )
        Abc_ObjPatchFanin( pFanout, pNode, pBuffer );
}
Beispiel #2
0
ABC_NAMESPACE_IMPL_START


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

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

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Mpm_Man_t * Mpm_ManStart( Mig_Man_t * pMig, Mpm_Par_t * pPars )
{
    Mpm_Man_t * p;
    int i;
    assert( sizeof(Mpm_Uni_t) % sizeof(word) == 0 );      // aligned info to word boundary
    assert( pPars->nNumCuts <= MPM_CUT_MAX );
    assert( !pPars->fUseTruth || pPars->pLib->LutMax <= 16 );
    assert( !pPars->fUseDsd || pPars->pLib->LutMax <= 6 );
    Mig_ManSetRefs( pMig );
    // alloc
    p = ABC_CALLOC( Mpm_Man_t, 1 );
    p->pMig      = pMig;
    p->pPars     = pPars;
    p->pLibLut   = pPars->pLib;
    p->nLutSize  = pPars->pLib->LutMax;
    p->nTruWords = pPars->fUseTruth ? Abc_Truth6WordNum(p->nLutSize) : 0;
    p->nNumCuts  = pPars->nNumCuts;
    // cuts
    assert( Mpm_CutWordNum(32) < 32 ); // using 5 bits for word count
    p->pManCuts  = Mmr_StepStart( 13, Abc_Base2Log(Mpm_CutWordNum(p->nLutSize) + 1) );
    Vec_PtrGrow( &p->vFreeUnits, p->nNumCuts + 1 );
    for ( i = p->nNumCuts; i >= 0; i-- )
        Vec_PtrPush( &p->vFreeUnits, p->pCutUnits + i );
    p->vTemp     = Vec_PtrAlloc( 1000 );
    // mapping attributes
    Vec_IntFill( &p->vCutBests, Mig_ManObjNum(pMig), 0 );
    Vec_IntFill( &p->vCutLists, Mig_ManObjNum(pMig), 0 );
    Vec_IntFill( &p->vMigRefs, Mig_ManObjNum(pMig), 0 );
    Vec_IntFill( &p->vMapRefs, Mig_ManObjNum(pMig), 0 );
    Vec_IntFill( &p->vEstRefs, Mig_ManObjNum(pMig), 0 );
    Vec_IntFill( &p->vRequireds, Mig_ManObjNum(pMig), ABC_INFINITY );
    Vec_IntFill( &p->vTimes, Mig_ManObjNum(pMig), 0 );
    Vec_IntFill( &p->vAreas, Mig_ManObjNum(pMig), 0 );
    Vec_IntFill( &p->vEdges, Mig_ManObjNum(pMig), 0 );
    // start DSD manager
    assert( !p->pPars->fUseTruth || !p->pPars->fUseDsd );
    if ( p->pPars->fUseTruth )
    { 
        p->vTtMem = Vec_MemAlloc( p->nTruWords, 12 ); // 32 KB/page for 6-var functions
        Vec_MemHashAlloc( p->vTtMem, 10000 );
        p->funcCst0 = Vec_MemHashInsert( p->vTtMem, p->Truth );
        Abc_TtUnit( p->Truth, p->nTruWords, 0 );
        p->funcVar0 = Vec_MemHashInsert( p->vTtMem, p->Truth );
    }
    else if ( p->pPars->fUseDsd )
    {
        Mpm_ManPrecomputePerms( p );
        p->funcVar0 = 1;
    }
    // finish
    p->timeTotal = Abc_Clock();
    pMig->pMan = p;
    return p;
}