/**CFile****************************************************************

  FileName    [abcHie.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Network and node package.]

  Synopsis    [Procedures to handle hierarchy.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - June 20, 2005.]

  Revision    [$Id: abcHie.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]

***********************************************************************/

#include "abc.h"

ABC_NAMESPACE_IMPL_START


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

#define ABC_OBJ_VOID ((Abc_Obj_t *)(ABC_PTRINT_T)1)

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

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

  Synopsis    [Checks the the hie design has no duplicated networks.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_NtkCheckSingleInstance( Abc_Ntk_t * pNtk )
{
    Abc_Ntk_t * pTemp, * pModel;
    Abc_Obj_t * pBox;
    int i, k, RetValue = 1;
    if ( pNtk->pDesign == NULL )
        return 1;
    Vec_PtrForEachEntry( Abc_Ntk_t *, pNtk->pDesign->vModules, pTemp, i )
        pTemp->fHieVisited = 0;
    Vec_PtrForEachEntry( Abc_Ntk_t *, pNtk->pDesign->vModules, pTemp, i )
        Abc_NtkForEachBox( pTemp, pBox, k )
        {
            pModel = (Abc_Ntk_t *)pBox->pData;
            if ( pModel == NULL )
                continue;
            if ( Abc_NtkLatchNum(pModel) > 0 )
            {
                printf( "Network \"%s\" contains %d flops.\n",                     
                    Abc_NtkName(pNtk), Abc_NtkLatchNum(pModel) );
                RetValue = 0;
            }
            if ( pModel->fHieVisited )
            {
                printf( "Network \"%s\" contains box \"%s\" whose model \"%s\" is instantiated more than once.\n", 
                    Abc_NtkName(pNtk), Abc_ObjName(pBox), Abc_NtkName(pModel) );
                RetValue = 0;
            }
            pModel->fHieVisited = 1;
        }
    Vec_PtrForEachEntry( Abc_Ntk_t *, pNtk->pDesign->vModules, pTemp, i )
        pTemp->fHieVisited = 0;
    return RetValue;
}

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

  Synopsis    [Collect PIs and POs of internal networks in the topo order.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_NtkCollectPiPos_rec( Abc_Obj_t * pNet, Vec_Ptr_t * vLiMaps, Vec_Ptr_t * vLoMaps )
{
    extern int Abc_NtkCollectPiPos_int( Abc_Obj_t * pBox, Abc_Ntk_t * pNtk, Vec_Ptr_t * vLiMaps, Vec_Ptr_t * vLoMaps );
    Abc_Obj_t * pObj, * pFanin; 
    int i, Counter = 0;
    assert( Abc_ObjIsNet(pNet) );
    if ( Abc_NodeIsTravIdCurrent( pNet ) )
        return 0;
    Abc_NodeSetTravIdCurrent( pNet );
    pObj = Abc_ObjFanin0(pNet);
    if ( Abc_ObjIsNode(pObj) )
        Abc_ObjForEachFanin( pObj, pFanin, i )
            Counter += Abc_NtkCollectPiPos_rec( pFanin, vLiMaps, vLoMaps );
    if ( Abc_ObjIsNode(pObj) )
        return Counter;
    if ( Abc_ObjIsBo(pObj) )
        pObj = Abc_ObjFanin0(pObj);
    assert( Abc_ObjIsBox(pObj) );
    Abc_ObjForEachFanout( pObj, pFanin, i )
        Abc_NodeSetTravIdCurrent( Abc_ObjFanout0(pFanin) );
    Abc_ObjForEachFanin( pObj, pFanin, i )
        Counter += Abc_NtkCollectPiPos_rec( Abc_ObjFanin0(pFanin), vLiMaps, vLoMaps );
    Counter += Abc_NtkCollectPiPos_int( pObj, Abc_ObjModel(pObj), vLiMaps, vLoMaps );
    return Counter;
}
int Abc_NtkCollectPiPos_int( Abc_Obj_t * pBox, Abc_Ntk_t * pNtk, Vec_Ptr_t * vLiMaps, Vec_Ptr_t * vLoMaps )
{
    Abc_Obj_t * pObj; 
    int i, Counter = 0;
    // mark primary inputs
    Abc_NtkIncrementTravId( pNtk );
    Abc_NtkForEachPi( pNtk, pObj, i )
        Abc_NodeSetTravIdCurrent( Abc_ObjFanout0(pObj) );
    // add primary inputs
    if ( pBox )
    {
        Abc_ObjForEachFanin( pBox, pObj, i )
            Vec_PtrPush( vLiMaps, pObj );
        Abc_NtkForEachPi( pNtk, pObj, i )
            Vec_PtrPush( vLoMaps, pObj );
    }
    // visit primary outputs
    Abc_NtkForEachPo( pNtk, pObj, i )
        Counter += Abc_NtkCollectPiPos_rec( Abc_ObjFanin0(pObj), vLiMaps, vLoMaps );
    // add primary outputs
    if ( pBox )
    {
        Abc_NtkForEachPo( pNtk, pObj, i )
            Vec_PtrPush( vLiMaps, pObj );
        Abc_ObjForEachFanout( pBox, pObj, i )
            Vec_PtrPush( vLoMaps, pObj );
        Counter++;
    }
    return Counter;
}
int Abc_NtkCollectPiPos( Abc_Ntk_t * pNtk, Vec_Ptr_t ** pvLiMaps, Vec_Ptr_t ** pvLoMaps )
{
    assert( Abc_NtkIsNetlist(pNtk) );
    *pvLiMaps = Vec_PtrAlloc( 1000 );
    *pvLoMaps = Vec_PtrAlloc( 1000 );
    return Abc_NtkCollectPiPos_int( NULL, pNtk, *pvLiMaps, *pvLoMaps );
}

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

  Synopsis    [Derives logic network with barbufs from the netlist.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Obj_t * Abc_NtkToBarBufs_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNet )
{
    Abc_Obj_t * pObj, * pFanin; 
    int i;
    assert( Abc_ObjIsNet(pNet) );
    if ( pNet->pCopy )
        return pNet->pCopy;
    pObj = Abc_ObjFanin0(pNet);
    assert( Abc_ObjIsNode(pObj) );
    pNet->pCopy = Abc_NtkDupObj( pNtkNew, pObj, 0 );
    Abc_ObjForEachFanin( pObj, pFanin, i )
        Abc_ObjAddFanin( pObj->pCopy, Abc_NtkToBarBufs_rec(pNtkNew, pFanin) );
    return pNet->pCopy;
}
Abc_Ntk_t * Abc_NtkToBarBufs( Abc_Ntk_t * pNtk )
{
    char Buffer[1000];
    Vec_Ptr_t * vLiMaps, * vLoMaps;
    Abc_Ntk_t * pNtkNew, * pTemp;
    Abc_Obj_t * pLatch, * pObjLi, * pObjLo;
    Abc_Obj_t * pObj, * pLiMap, * pLoMap;
    int i, k, nBoxes;
    assert( Abc_NtkIsNetlist(pNtk) );
    if ( !Abc_NtkCheckSingleInstance(pNtk) )
        return NULL;
    assert( pNtk->pDesign != NULL );
    // start the network
    pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, pNtk->ntkFunc, 1 );
    pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
    pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
    // clone CIs/CIs/boxes
    Abc_NtkCleanCopy_rec( pNtk );
    Abc_NtkForEachPi( pNtk, pObj, i )
        Abc_ObjFanout0(pObj)->pCopy = Abc_NtkDupObj( pNtkNew, pObj, 1 );
    Abc_NtkForEachPo( pNtk, pObj, i )
        Abc_NtkDupObj( pNtkNew, pObj, 1 );
    // create latches and transfer copy labels
    nBoxes = Abc_NtkCollectPiPos( pNtk, &vLiMaps, &vLoMaps );
    Vec_PtrForEachEntryTwo( Abc_Obj_t *, vLiMaps, Abc_Obj_t *, vLoMaps, pLiMap, pLoMap, i )
    {
        pObjLi = Abc_NtkCreateBi(pNtkNew);
        pLatch = Abc_NtkCreateLatch(pNtkNew);
        pObjLo = Abc_NtkCreateBo(pNtkNew);
        Abc_ObjAddFanin( pLatch, pObjLi );
        Abc_ObjAddFanin( pObjLo, pLatch );
        pLatch->pData = (void *)ABC_INIT_ZERO;
        pTemp = NULL;
        if ( Abc_ObjFanin0(pLiMap)->pNtk != pNtk )
            pTemp = Abc_ObjFanin0(pLiMap)->pNtk;
        else if ( Abc_ObjFanout0(pLoMap)->pNtk != pNtk )
            pTemp = Abc_ObjFanout0(pLoMap)->pNtk;
        else assert( 0 );
        sprintf( Buffer, "_%s_in", Abc_NtkName(pTemp) );
        Abc_ObjAssignName( pObjLi, Abc_ObjName(Abc_ObjFanin0(pLiMap)), Buffer );
        sprintf( Buffer, "_%s_out", Abc_NtkName(pTemp) );
        Abc_ObjAssignName( pObjLo, Abc_ObjName(Abc_ObjFanout0(pLoMap)), Buffer );
        pLiMap->pCopy = pObjLi;
        Abc_ObjFanout0(pLoMap)->pCopy = pObjLo;
        assert( Abc_ObjIsNet(Abc_ObjFanout0(pLoMap)) );
    }
    Vec_PtrFree( vLiMaps );
    Vec_PtrFree( vLoMaps );
    // rebuild networks
    Vec_PtrForEachEntry( Abc_Ntk_t *, pNtk->pDesign->vModules, pTemp, i )
        Abc_NtkForEachCo( pTemp, pObj, k )
            Abc_ObjAddFanin( pObj->pCopy, Abc_NtkToBarBufs_rec(pNtkNew, Abc_ObjFanin0(pObj)) );
    pNtkNew->nBarBufs = Abc_NtkLatchNum(pNtkNew);
    printf( "Hierarchy reader flattened %d instances of logic boxes and introduced %d barbufs.\n", nBoxes, pNtkNew->nBarBufs );
    return pNtkNew;
}

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

  Synopsis    [Converts the logic with barbufs into a hierarchical network.]

  Description [The base network is the original hierarchical network. The
  second argument is the optimized network with barbufs.  This procedure
  reconstructs the original hierarcical network which adding logic from
  the optimized network.  It is assumed that the PIs/POs of the original
  network one-to-one mapping with the flops of the optimized network.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Obj_t * Abc_NtkFromBarBufs_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj )
{
    Abc_Obj_t * pFanin; 
    int i;
    if ( pObj->pCopy )
        return pObj->pCopy;
    Abc_NtkDupObj( pNtkNew, pObj, 0 );
    Abc_ObjForEachFanin( pObj, pFanin, i )
        Abc_ObjAddFanin( pObj->pCopy, Abc_NtkFromBarBufs_rec(pNtkNew, pFanin) );
    return pObj->pCopy;
}
Abc_Ntk_t * Abc_NtkFromBarBufs( Abc_Ntk_t * pNtkBase, Abc_Ntk_t * pNtk )
{
    Abc_Ntk_t * pNtkNew, * pTemp;
    Vec_Ptr_t * vLiMaps, * vLoMaps;
    Abc_Obj_t * pObj, * pLiMap, * pLoMap;
    int i, k;
    assert( pNtkBase->pDesign != NULL );
    assert( Abc_NtkIsNetlist(pNtk) );
    assert( Abc_NtkIsNetlist(pNtkBase) );
    assert( Abc_NtkLatchNum(pNtkBase) == 0 );
    assert( Abc_NtkLatchNum(pNtk) == pNtk->nBarBufs );
    assert( Abc_NtkWhiteboxNum(pNtk) == 0 );
    assert( Abc_NtkBlackboxNum(pNtk) == 0 );
    assert( Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkBase) );
    assert( Abc_NtkPoNum(pNtk) == Abc_NtkPoNum(pNtkBase) );
    // start networks
    Abc_NtkCleanCopy_rec( pNtkBase );
    Vec_PtrForEachEntry( Abc_Ntk_t *, pNtkBase->pDesign->vModules, pTemp, i )
        pTemp->pCopy = Abc_NtkStartFrom( pTemp, pNtk->ntkType, pNtk->ntkFunc );
    Vec_PtrForEachEntry( Abc_Ntk_t *, pNtkBase->pDesign->vModules, pTemp, i )
        pTemp->pCopy->pAltView = pTemp->pAltView ? pTemp->pAltView->pCopy : NULL;
    // update box models
    Vec_PtrForEachEntry( Abc_Ntk_t *, pNtkBase->pDesign->vModules, pTemp, i )
        Abc_NtkForEachBox( pTemp, pObj, k )
            if ( Abc_ObjIsWhitebox(pObj) || Abc_ObjIsBlackbox(pObj) )
                pObj->pCopy->pData = Abc_ObjModel(pObj)->pCopy;
    // create the design
    pNtkNew = pNtkBase->pCopy;
    pNtkNew->pDesign = Abc_DesCreate( pNtkBase->pDesign->pName );
    Vec_PtrForEachEntry( Abc_Ntk_t *, pNtkBase->pDesign->vModules, pTemp, i )
        Abc_DesAddModel( pNtkNew->pDesign, pTemp->pCopy );
    Vec_PtrForEachEntry( Abc_Ntk_t *, pNtkBase->pDesign->vTops, pTemp, i )
        Vec_PtrPush( pNtkNew->pDesign->vTops, pTemp->pCopy );
    assert( Vec_PtrEntry(pNtkNew->pDesign->vTops, 0) == pNtkNew );
    // transfer copy attributes to pNtk
    Abc_NtkCleanCopy( pNtk );
    Abc_NtkForEachPi( pNtk, pObj, i )
        pObj->pCopy = Abc_NtkPi(pNtkNew, i);
    Abc_NtkForEachPo( pNtk, pObj, i )
        pObj->pCopy = Abc_NtkPo(pNtkNew, i);
    Abc_NtkCollectPiPos( pNtkBase, &vLiMaps, &vLoMaps );
    assert( Vec_PtrSize(vLiMaps) == Abc_NtkLatchNum(pNtk) );
    assert( Vec_PtrSize(vLoMaps) == Abc_NtkLatchNum(pNtk) );
    Vec_PtrForEachEntryTwo( Abc_Obj_t *, vLiMaps, Abc_Obj_t *, vLoMaps, pLiMap, pLoMap, i )
    {
        pObj = Abc_NtkBox( pNtk, i );
        Abc_ObjFanin0(pObj)->pCopy = pLiMap->pCopy; 
        Abc_ObjFanout0(pObj)->pCopy = pLoMap->pCopy; 
    }
    Vec_PtrFree( vLiMaps );
    Vec_PtrFree( vLoMaps );
    // create internal nodes
    Abc_NtkForEachCo( pNtk, pObj, i )
        Abc_ObjAddFanin( pObj->pCopy, Abc_NtkFromBarBufs_rec(pObj->pCopy->pNtk, Abc_ObjFanin0(pObj)) );
    // transfer net names
    Abc_NtkForEachCi( pNtk, pObj, i )
    {
        if ( Abc_ObjFanoutNum(pObj->pCopy) == 0 ) // handle PI without fanout
            Abc_ObjAddFanin( Abc_NtkCreateNet(pObj->pCopy->pNtk), pObj->pCopy );
        Nm_ManStoreIdName( pObj->pCopy->pNtk->pManName, Abc_ObjFanout0(pObj->pCopy)->Id, Abc_ObjFanout0(pObj->pCopy)->Type, Abc_ObjName(Abc_ObjFanout0(pObj)), NULL );
    }
    Abc_NtkForEachCo( pNtk, pObj, i )
        Nm_ManStoreIdName( pObj->pCopy->pNtk->pManName, Abc_ObjFanin0(pObj->pCopy)->Id, Abc_ObjFanin0(pObj->pCopy)->Type, Abc_ObjName(Abc_ObjFanin0(pObj)), NULL );
    return pNtkNew;
}

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

  Synopsis    [Collect nodes in the barbuf-friendly order.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NtkToBarBufsCollect_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vNodes )
{
    Abc_Obj_t * pFanin; 
    int i;
    if ( Abc_NodeIsTravIdCurrent( pObj ) )
        return;
    Abc_NodeSetTravIdCurrent( pObj );
    assert( Abc_ObjIsNode(pObj) );
    Abc_ObjForEachFanin( pObj, pFanin, i )
        Abc_NtkToBarBufsCollect_rec( pFanin, vNodes );
    Vec_PtrPush( vNodes, pObj );
}
Vec_Ptr_t * Abc_NtkToBarBufsCollect( Abc_Ntk_t * pNtk )
{
    Vec_Ptr_t * vNodes;
    Abc_Obj_t * pObj;
    int i;
    assert( Abc_NtkIsLogic(pNtk) );
    assert( pNtk->nBarBufs > 0 );
    assert( pNtk->nBarBufs == Abc_NtkLatchNum(pNtk) );
    vNodes = Vec_PtrAlloc( Abc_NtkObjNum(pNtk) );
    Abc_NtkIncrementTravId( pNtk );
    Abc_NtkForEachCi( pNtk, pObj, i )
    {
        if ( i >= Abc_NtkCiNum(pNtk) - pNtk->nBarBufs )
            break;
        Vec_PtrPush( vNodes, pObj );
        Abc_NodeSetTravIdCurrent( pObj );
    }
    Abc_NtkForEachCo( pNtk, pObj, i )
    {
        if ( i < Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
            continue;
        Abc_NtkToBarBufsCollect_rec( Abc_ObjFanin0(pObj), vNodes );
        Vec_PtrPush( vNodes, pObj );
        Vec_PtrPush( vNodes, Abc_ObjFanout0(pObj) );
        Vec_PtrPush( vNodes, Abc_ObjFanout0(Abc_ObjFanout0(pObj)) );
        Abc_NodeSetTravIdCurrent( pObj );
        Abc_NodeSetTravIdCurrent( Abc_ObjFanout0(pObj) );
        Abc_NodeSetTravIdCurrent( Abc_ObjFanout0(Abc_ObjFanout0(pObj)) );
    }
    Abc_NtkForEachCo( pNtk, pObj, i )
    {
        if ( i >= Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
            break;
        Abc_NtkToBarBufsCollect_rec( Abc_ObjFanin0(pObj), vNodes );
        Vec_PtrPush( vNodes, pObj );
        Abc_NodeSetTravIdCurrent( pObj );
    }
    assert( Vec_PtrSize(vNodes) == Abc_NtkObjNum(pNtk) );
    return vNodes;
}

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

  Synopsis    [Count barrier buffers.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_NtkCountBarBufs( Abc_Ntk_t * pNtk )
{
    Abc_Obj_t * pObj;
    int i, Counter = 0;
    Abc_NtkForEachNode( pNtk, pObj, i )
        Counter += Abc_ObjIsBarBuf( pObj );
    return Counter;
}

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

  Synopsis    [Converts the network to dedicated barbufs and back.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Abc_NtkBarBufsToBuffers( Abc_Ntk_t * pNtk )
{
    Vec_Ptr_t * vNodes;
    Abc_Ntk_t * pNtkNew;
    Abc_Obj_t * pObj, * pFanin;
    int i, k;
    assert( Abc_NtkIsLogic(pNtk) );
    assert( pNtk->pDesign == NULL );
    assert( pNtk->nBarBufs > 0 );
    assert( pNtk->nBarBufs == Abc_NtkLatchNum(pNtk) );
    vNodes = Abc_NtkToBarBufsCollect( pNtk );
    // start the network
    pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, pNtk->ntkFunc, 1 );
    pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
    pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
    // create objects
    Abc_NtkCleanCopy( pNtk );
    Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
    {
        if ( Abc_ObjIsPi(pObj) )
            Abc_NtkDupObj( pNtkNew, pObj, 1 );
        else if ( Abc_ObjIsPo( pObj) )
            Abc_ObjAddFanin( Abc_NtkDupObj(pNtkNew, pObj, 1), Abc_ObjFanin0(pObj)->pCopy );
        else if ( Abc_ObjIsBi(pObj) || Abc_ObjIsBo(pObj) )
            pObj->pCopy = Abc_ObjFanin0(pObj)->pCopy;
        else if ( Abc_ObjIsLatch(pObj) )
            Abc_ObjAddFanin( (pObj->pCopy = Abc_NtkCreateNode(pNtkNew)), Abc_ObjFanin0(pObj)->pCopy );
        else if ( Abc_ObjIsNode(pObj) )
        {
            Abc_NtkDupObj( pNtkNew, pObj, 1 );
            Abc_ObjForEachFanin( pObj, pFanin, k )
                Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
        }
        else assert( 0 );
    }
    Vec_PtrFree( vNodes );
    return pNtkNew;
}
Abc_Ntk_t * Abc_NtkBarBufsFromBuffers( Abc_Ntk_t * pNtkBase, Abc_Ntk_t * pNtk )
{
    Abc_Ntk_t * pNtkNew;
    Abc_Obj_t * pObj, * pFanin, * pLatch;
    int i, k, nBarBufs;
    assert( Abc_NtkIsLogic(pNtkBase) );
    assert( Abc_NtkIsLogic(pNtk) );
    assert( pNtkBase->nBarBufs == Abc_NtkLatchNum(pNtkBase) );
    // start the network
    pNtkNew = Abc_NtkStartFrom( pNtkBase, pNtk->ntkType, pNtk->ntkFunc );
    // transfer PI pointers
    Abc_NtkForEachPi( pNtk, pObj, i )
        pObj->pCopy = Abc_NtkPi(pNtkNew, i);
    // assuming that the order/number of barbufs remains the same
    nBarBufs = 0;
    Abc_NtkForEachNode( pNtk, pObj, i )
    {
        if ( Abc_ObjIsBarBuf(pObj) )
        {
            pLatch = Abc_NtkBox(pNtkNew, nBarBufs++);
            Abc_ObjAddFanin( Abc_ObjFanin0(pLatch), Abc_ObjFanin0(pObj)->pCopy );
            pObj->pCopy = Abc_ObjFanout0(pLatch);
        }
        else
        {
            Abc_NtkDupObj( pNtkNew, pObj, 1 );
            Abc_ObjForEachFanin( pObj, pFanin, k )
                Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
        }
    }
    assert( nBarBufs == pNtkBase->nBarBufs );
    // connect POs
    Abc_NtkForEachPo( pNtk, pObj, i )
        Abc_ObjAddFanin( Abc_NtkPo(pNtkNew, i), Abc_ObjFanin0(pObj)->pCopy );
    return pNtkNew;
}
Abc_Ntk_t * Abc_NtkBarBufsOnOffTest( Abc_Ntk_t * pNtk )
{
    Abc_Ntk_t * pNtkNew, * pNtkNew2;
    pNtkNew  = Abc_NtkBarBufsToBuffers( pNtk );
    pNtkNew2 = Abc_NtkBarBufsFromBuffers( pNtk, pNtkNew );
    Abc_NtkDelete( pNtkNew );
    return pNtkNew2;
}

////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END

