Esempio n. 1
0
/**Function*************************************************************

  Synopsis    [Returns the array of nodes to be combined into one multi-input AND-gate.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_NtkCollectSupergate_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, int fFirst, int fStopAtMux )
{
    int RetValue1, RetValue2, i;
    // check if the node is visited
    if ( Abc_ObjRegular(pNode)->fMarkB )
    {
        // check if the node occurs in the same polarity
        for ( i = 0; i < vSuper->nSize; i++ )
            if ( vSuper->pArray[i] == pNode )
                return 1;
        // check if the node is present in the opposite polarity
        for ( i = 0; i < vSuper->nSize; i++ )
            if ( vSuper->pArray[i] == Abc_ObjNot(pNode) )
                return -1;
        assert( 0 );
        return 0;
    }
    // if the new node is complemented or a PI, another gate begins
    if ( !fFirst )
        if ( Abc_ObjIsComplement(pNode) || !Abc_ObjIsNode(pNode) || Abc_ObjFanoutNum(pNode) > 1 || (fStopAtMux && Abc_NodeIsMuxType(pNode)) )
        {
            Vec_PtrPush( vSuper, pNode );
            Abc_ObjRegular(pNode)->fMarkB = 1;
            return 0;
        }
    assert( !Abc_ObjIsComplement(pNode) );
    assert( Abc_ObjIsNode(pNode) );
    // go through the branches
    RetValue1 = Abc_NtkCollectSupergate_rec( Abc_ObjChild0(pNode), vSuper, 0, fStopAtMux );
    RetValue2 = Abc_NtkCollectSupergate_rec( Abc_ObjChild1(pNode), vSuper, 0, fStopAtMux );
    if ( RetValue1 == -1 || RetValue2 == -1 )
        return -1;
    // return 1 if at least one branch has a duplicate
    return RetValue1 || RetValue2;
}
ABC_NAMESPACE_IMPL_START


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

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

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

  Synopsis    [Find the array of nodes to be updated.]

  Description []

  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_SclFindWindow( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int_t ** pvEvals )
{
    Abc_Ntk_t * p = Abc_ObjNtk(pPivot);
    Abc_Obj_t * pObj, * pNext, * pNext2;
    Vec_Int_t * vNodes = *pvNodes;
    Vec_Int_t * vEvals = *pvEvals;
    int i, k;
    assert( Abc_ObjIsNode(pPivot) );
    // collect fanins, node, and fanouts
    Vec_IntClear( vNodes );
    Abc_ObjForEachFanin( pPivot, pNext, i )
//        if ( Abc_ObjIsNode(pNext) && Abc_ObjFaninNum(pNext) > 0 )
    if ( Abc_ObjIsCi(pNext) || Abc_ObjFaninNum(pNext) > 0 )
        Vec_IntPush( vNodes, Abc_ObjId(pNext) );
    Vec_IntPush( vNodes, Abc_ObjId(pPivot) );
    Abc_ObjForEachFanout( pPivot, pNext, i )
    if ( Abc_ObjIsNode(pNext) )
    {
        Vec_IntPush( vNodes, Abc_ObjId(pNext) );
        Abc_ObjForEachFanout( pNext, pNext2, k )
        if ( Abc_ObjIsNode(pNext2) )
            Vec_IntPush( vNodes, Abc_ObjId(pNext2) );
    }
    Vec_IntUniqify( vNodes );
    // label nodes
    Abc_NtkForEachObjVec( vNodes, p, pObj, i )
    {
        assert( pObj->fMarkB == 0 );
        pObj->fMarkB = 1;
    }
 // first add the nets to the CO drivers
 Abc_NtkForEachCo( pNtk, pObj, i )
 {
     pDriver = Abc_ObjFanin0(pObj);
     if ( Abc_ObjIsCi(pDriver) )
     {
         assert( !strcmp( Abc_ObjName(pDriver), Abc_ObjName(pObj) ) );
         Abc_ObjAddFanin( pObj->pCopy, pDriver->pCopy->pCopy );
         continue;
     }
     assert( Abc_ObjIsNode(pDriver) );
     // if the CO driver has no net, create it
     if ( pDriver->pCopy->pCopy == NULL )
     {
         // create the CO net and connect it to CO
         pNet = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pObj) );
         Abc_ObjAddFanin( pObj->pCopy, pNet );
         // connect the CO net to the new driver and remember it in the new driver
         Abc_ObjAddFanin( pNet, pDriver->pCopy );
         pDriver->pCopy->pCopy = pNet;
     }
     else
     {
         assert( !strcmp( Abc_ObjName(pDriver->pCopy->pCopy), Abc_ObjName(pObj) ) );
         Abc_ObjAddFanin( pObj->pCopy, pDriver->pCopy->pCopy );
     }
 }
Esempio n. 4
0
ABC_NAMESPACE_IMPL_START


/* 
    Implememented here is the algorithm for minimal-LUT decomposition
    described in the paper: T. Sasao et al. "On the number of LUTs 
    to implement logic functions", To appear in Proc. IWLS'09.
*/

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

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

#ifdef ABC_USE_CUDD

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

  Synopsis    [Check if a LUT can absort a fanin.]

  Description [The fanins are (c, d0, d1).]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_ObjCheckAbsorb( Abc_Obj_t * pObj, Abc_Obj_t * pPivot, int nLutSize, Vec_Ptr_t * vFanins )
{
    Abc_Obj_t * pFanin;
    int i;
    assert( Abc_ObjIsNode(pObj) && Abc_ObjIsNode(pPivot) );
    // add fanins of the node
    Vec_PtrClear( vFanins );
    Abc_ObjForEachFanin( pObj, pFanin, i )
        if ( pFanin != pPivot )
            Vec_PtrPush( vFanins, pFanin );
    // add fanins of the fanin
    Abc_ObjForEachFanin( pPivot, pFanin, i )
    {
        Vec_PtrPushUnique( vFanins, pFanin );
        if ( Vec_PtrSize(vFanins) > nLutSize )
            return 0;
    }
Esempio n. 5
0
ABC_NAMESPACE_IMPL_START

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

#define TIM_TEST_BOX_RATIO 200

// assume that every TIM_TEST_BOX_RATIO'th object is a white box
static inline int Abc_NodeIsWhiteBox( Abc_Obj_t * pObj )  { assert( Abc_ObjIsNode(pObj) ); return Abc_ObjId(pObj) % TIM_TEST_BOX_RATIO == 0 && Abc_ObjFaninNum(pObj) > 0 && Abc_ObjFaninNum(pObj) < 10; }
Esempio n. 6
0
ABC_NAMESPACE_IMPL_START

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

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

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

  Synopsis    [Node type conversions.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
char * Ptr_HopToType( Abc_Obj_t * pObj )
{
    static word uTruth, uTruths6[3] = {
        ABC_CONST(0xAAAAAAAAAAAAAAAA),
        ABC_CONST(0xCCCCCCCCCCCCCCCC),
        ABC_CONST(0xF0F0F0F0F0F0F0F0),
    };
    assert( Abc_ObjIsNode(pObj) );
    uTruth = Hop_ManComputeTruth6( (Hop_Man_t *)Abc_ObjNtk(pObj)->pManFunc, (Hop_Obj_t *)pObj->pData, Abc_ObjFaninNum(pObj) );
/*
    if ( uTruth ==  0 )                           return "BAC_BOX_C0";
    if ( uTruth == ~(word)0 )                     return "BAC_BOX_C1";
    if ( uTruth ==  uTruths6[0] )                 return "BAC_BOX_BUF";
    if ( uTruth == ~uTruths6[0] )                 return "BAC_BOX_INV";
    if ( uTruth == (uTruths6[0] & uTruths6[1]) )  return "BAC_BOX_AND";
    if ( uTruth ==~(uTruths6[0] & uTruths6[1]) )  return "BAC_BOX_NAND";
    if ( uTruth == (uTruths6[0] | uTruths6[1]) )  return "BAC_BOX_OR";
    if ( uTruth ==~(uTruths6[0] | uTruths6[1]) )  return "BAC_BOX_NOR";
    if ( uTruth == (uTruths6[0] ^ uTruths6[1]) )  return "BAC_BOX_XOR";
    if ( uTruth ==~(uTruths6[0] ^ uTruths6[1]) )  return "BAC_BOX_XNOR";
*/
    if ( uTruth ==  0 )                           return "Const0T";
    if ( uTruth == ~(word)0 )                     return "Const1T";
    if ( uTruth ==  uTruths6[0] )                 return "BufT";
    if ( uTruth == ~uTruths6[0] )                 return "InvT";
    if ( uTruth == (uTruths6[0] & uTruths6[1]) )  return "AndT";
    if ( uTruth ==~(uTruths6[0] & uTruths6[1]) )  return "NandT";
    if ( uTruth == (uTruths6[0] | uTruths6[1]) )  return "OrT";
    if ( uTruth ==~(uTruths6[0] | uTruths6[1]) )  return "NorT";
    if ( uTruth == (uTruths6[0] ^ uTruths6[1]) )  return "XorT";
    if ( uTruth ==~(uTruths6[0] ^ uTruths6[1]) )  return "XnorT";
    assert( 0 );
    return NULL;
}
Esempio n. 7
0
/**Function*************************************************************

  Synopsis    [Create Ptr from Abc_Ntk_t.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
char * Ptr_AbcObjName( Abc_Obj_t * pObj )
{
    if ( Abc_ObjIsNet(pObj) || Abc_ObjIsBox(pObj) )
        return Abc_ObjName(pObj);
    if ( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) )
        return Ptr_AbcObjName(Abc_ObjFanout0(pObj));
    if ( Abc_ObjIsCo(pObj) )
        return Ptr_AbcObjName(Abc_ObjFanin0(pObj));
    assert( 0 );
    return NULL;
}
Esempio n. 8
0
/**Function*************************************************************

  Synopsis    [Adds trivial clause.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_NtkClauseAnd( sat_solver * pSat, Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, Vec_Int_t * vVars )
{
    int fComp1, Var, Var1, i;
//printf( "Adding AND %d.  (%d)    %d\n", pNode->Id, vSuper->nSize+1, (int)pSat->sat_solver_stats.clauses );

    assert( !Abc_ObjIsComplement( pNode ) );
    assert( Abc_ObjIsNode( pNode ) );

//    nVars = sat_solver_nvars(pSat);
    Var = (int)(ABC_PTRINT_T)pNode->pCopy;
//    Var = pNode->Id;

//    assert( Var  < nVars ); 
    for ( i = 0; i < vSuper->nSize; i++ )
    {
        // get the predecessor nodes
        // get the complemented attributes of the nodes
        fComp1 = Abc_ObjIsComplement((Abc_Obj_t *)vSuper->pArray[i]);
        // determine the variable numbers
        Var1 = (int)(ABC_PTRINT_T)Abc_ObjRegular((Abc_Obj_t *)vSuper->pArray[i])->pCopy;
//        Var1 = (int)Abc_ObjRegular(vSuper->pArray[i])->Id;

        // check that the variables are in the SAT manager
//        assert( Var1 < nVars );

        // suppose the AND-gate is A * B = C
        // add !A => !C   or   A + !C
    //  fprintf( pFile, "%d %d 0%c", Var1, -Var, 10 );
        vVars->nSize = 0;
        Vec_IntPush( vVars, toLitCond(Var1, fComp1) );
        Vec_IntPush( vVars, toLitCond(Var,  1     ) );
        if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
            return 0;
    }

    // add A & B => C   or   !A + !B + C
//  fprintf( pFile, "%d %d %d 0%c", -Var1, -Var2, Var, 10 );
    vVars->nSize = 0;
    for ( i = 0; i < vSuper->nSize; i++ )
    {
        // get the predecessor nodes
        // get the complemented attributes of the nodes
        fComp1 = Abc_ObjIsComplement((Abc_Obj_t *)vSuper->pArray[i]);
        // determine the variable numbers
        Var1 = (int)(ABC_PTRINT_T)Abc_ObjRegular((Abc_Obj_t *)vSuper->pArray[i])->pCopy;
//        Var1 = (int)Abc_ObjRegular(vSuper->pArray[i])->Id;
        // add this variable to the array
        Vec_IntPush( vVars, toLitCond(Var1, !fComp1) );
    }
    Vec_IntPush( vVars, toLitCond(Var, 0) );
    return sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
}
Esempio n. 9
0
/**Function*************************************************************

  Synopsis    [Collect nodes reachable from this box.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NtkTestTimCollectCone_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vNodes )
{
    Abc_Obj_t * pFanin;
    int i;
    if ( Abc_NodeIsTravIdCurrent( pObj ) )
        return;
    Abc_NodeSetTravIdCurrent( pObj );
    if ( Abc_ObjIsCi(pObj) )
        return;
    assert( Abc_ObjIsNode( pObj ) );
    Abc_ObjForEachFanin( pObj, pFanin, i )
        Abc_NtkTestTimCollectCone_rec( pFanin, vNodes );
    Vec_PtrPush( vNodes, pObj );
}
Esempio n. 10
0
Vec_Ptr_t * Ptr_AbcDeriveNode( Abc_Obj_t * pObj )
{
    Abc_Obj_t * pFanin; int i;
    Vec_Ptr_t * vNode = Vec_PtrAllocExact( 2 + 2 * (1 + Abc_ObjFaninNum(pObj)) );
    assert( Abc_ObjIsNode(pObj) );
    if ( Abc_NtkHasAig(pObj->pNtk) )
        Vec_PtrPush( vNode, Ptr_HopToType(pObj) );
    else if ( Abc_NtkHasSop(pObj->pNtk) )
        Vec_PtrPush( vNode, Ptr_SopToTypeName((char *)pObj->pData) );
    else assert( 0 );
    Vec_PtrPush( vNode, Ptr_AbcObjName(pObj) );
    assert( Abc_ObjFaninNum(pObj) <= 2 );
    Abc_ObjForEachFanin( pObj, pFanin, i )
    {
        Vec_PtrPush( vNode, (void*)(i ? "r" : "l") );
        Vec_PtrPush( vNode, Ptr_AbcObjName(pFanin) );
    }
Esempio n. 11
0
/**Function*************************************************************

  Synopsis    [Minimizes SOP representation of one node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NodeEspresso( Abc_Obj_t * pNode )
{
    extern void define_cube_size( int n );
    pset_family Cover;
    int fCompl;

    assert( Abc_ObjIsNode(pNode) );
    // define the cube for this node
    define_cube_size( Abc_ObjFaninNum(pNode) );
    // create the Espresso cover
    fCompl = Abc_SopIsComplement( pNode->pData );
    Cover = Abc_SopToEspresso( pNode->pData );
    // perform minimization
    Cover = Abc_EspressoMinimize( Cover, NULL ); // deletes also cover
    // convert back onto the node's SOP representation
    pNode->pData = Abc_SopFromEspresso( pNode->pNtk->pManFunc, Cover );
    if ( fCompl ) Abc_SopComplement( pNode->pData );
    sf_free(Cover);
}
Esempio n. 12
0
/**Function*************************************************************

  Synopsis    [Converts the network to MUXes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
{
    ProgressBar * pProgress;
    Abc_Obj_t * pNode, * pNodeNew;
    Vec_Ptr_t * vNodes;
    int i;
    // perform conversion in the topological order
    vNodes = Abc_NtkDfs( pNtk, 0 );
    pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
    Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
    {
        Extra_ProgressBarUpdate( pProgress, i, NULL );
        // convert one node
        assert( Abc_ObjIsNode(pNode) );
        pNodeNew = Abc_NodeBddToMuxes( pNode, pNtkNew );
        // mark the old node with the new one
        assert( pNode->pCopy == NULL );
        pNode->pCopy = pNodeNew;
    }
Esempio n. 13
0
ABC_NAMESPACE_IMPL_START


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

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

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

  Synopsis    [Performs DFS for one node.]

  Description []

  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
{
    Abc_Obj_t * pFanin;
    int i;
    assert( !Abc_ObjIsNet(pNode) );
    // if this node is already visited, skip
    if ( Abc_NodeIsTravIdCurrent( pNode ) )
        return;
    // mark the node as visited
    Abc_NodeSetTravIdCurrent( pNode );
    // skip the CI
    if ( Abc_ObjIsCi(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsConst(pNode)) )
        return;
    assert( Abc_ObjIsNode( pNode ) || Abc_ObjIsBox( pNode ) );
    // visit the transitive fanin of the node
    Abc_ObjForEachFanin( pNode, pFanin, i )
    {
//        pFanin = Abc_ObjFanin( pNode, Abc_ObjFaninNum(pNode)-1-i );
        Abc_NtkDfs_rec( Abc_ObjFanin0Ntk(pFanin), vNodes );
    }
Esempio n. 14
0
ABC_NAMESPACE_IMPL_START


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

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

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

  Synopsis    [Marks and collects the TFI cone of the node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_MfsWinMarkTfi_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vCone )
{
    Abc_Obj_t * pFanin;
    int i;
    if ( Abc_NodeIsTravIdCurrent(pObj) )
        return;
    Abc_NodeSetTravIdCurrent( pObj );
    if ( Abc_ObjIsCi(pObj) )
    {
        Vec_PtrPush( vCone, pObj );
        return;
    }
    assert( Abc_ObjIsNode(pObj) );
    // visit the fanins of the node
    Abc_ObjForEachFanin( pObj, pFanin, i )
        Abc_MfsWinMarkTfi_rec( pFanin, vCone );
    Vec_PtrPush( vCone, pObj );
}
Esempio n. 15
0
Vec_Ptr_t * Abc_NtkTestTimCollectCone( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj )
{
    Vec_Ptr_t * vCone = Vec_PtrAlloc( 1000 );
    if ( pObj != NULL )
    {
        // collect for one node
        assert( Abc_ObjIsNode(pObj) );
        assert( !Abc_NodeIsTravIdCurrent( pObj ) );
        Abc_NtkTestTimCollectCone_rec( pObj, vCone );
        // remove the node because it is a white box
        Vec_PtrPop( vCone );
    }
    else
    {
        // collect for all COs
        Abc_Obj_t * pObj;
        int i;
        Abc_NtkForEachCo( pNtk, pObj, i )
            Abc_NtkTestTimCollectCone_rec( Abc_ObjFanin0(pObj), vCone );
    }
    return vCone;

}
Esempio n. 16
0
int Abc_NtkTestTimNodeStrash( Gia_Man_t * pGia, Abc_Obj_t * pNode )
{
    Hop_Man_t * pMan;
    Hop_Obj_t * pRoot;
    Abc_Obj_t * pFanin;
    int i;
    assert( Abc_ObjIsNode(pNode) );
    assert( Abc_NtkIsAigLogic(pNode->pNtk) );
    // get the local AIG manager and the local root node
    pMan = (Hop_Man_t *)pNode->pNtk->pManFunc;
    pRoot = (Hop_Obj_t *)pNode->pData;
    // check the constant case
    if ( Abc_NodeIsConst(pNode) || Hop_Regular(pRoot) == Hop_ManConst1(pMan) )
        return !Hop_IsComplement(pRoot);
    // set elementary variables
    Abc_ObjForEachFanin( pNode, pFanin, i )
        Hop_IthVar(pMan, i)->iData = pFanin->iTemp;
    // strash the AIG of this node
    Abc_NtkTestTimNodeStrash_rec( pGia, Hop_Regular(pRoot) );
    Hop_ConeUnmark_rec( Hop_Regular(pRoot) );
    // return the final node with complement if needed
    return Abc_LitNotCond( Hop_Regular(pRoot)->iData, Hop_IsComplement(pRoot) );
}
Esempio n. 17
0
/**Function*************************************************************

  Synopsis    [Load the network into manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, float * pSwitching, int fVerbose )
{
    Map_Man_t * pMan;
    Map_Node_t * pNodeMap;
    Vec_Ptr_t * vNodes;
    Abc_Obj_t * pNode, * pFanin, * pPrev;
    int i;

    assert( Abc_NtkIsStrash(pNtk) );

    // start the mapping manager and set its parameters
    pMan = Map_ManCreate( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk) - pNtk->nBarBufs, Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk) - pNtk->nBarBufs, fVerbose );
    if ( pMan == NULL )
        return NULL;
    Map_ManSetAreaRecovery( pMan, fRecovery );
    Map_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) );
    Map_ManSetDelayTarget( pMan, (float)DelayTarget );
    Map_ManSetInputArrivals( pMan, Abc_NtkMapCopyCiArrival(pNtk, Abc_NtkGetCiArrivalTimes(pNtk)) );
    Map_ManSetOutputRequireds( pMan, Abc_NtkMapCopyCoRequired(pNtk, Abc_NtkGetCoRequiredTimes(pNtk)) );

    // create PIs and remember them in the old nodes
    Abc_NtkCleanCopy( pNtk );
    Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan);
    Abc_NtkForEachCi( pNtk, pNode, i )
    {
        if ( i == Abc_NtkCiNum(pNtk) - pNtk->nBarBufs )
            break;
        pNodeMap = Map_ManReadInputs(pMan)[i];
        pNode->pCopy = (Abc_Obj_t *)pNodeMap;
        if ( pSwitching )
            Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] );
    }

    // load the AIG into the mapper
    vNodes = Abc_AigDfsMap( pNtk );
    Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
    {
        if ( Abc_ObjIsLatch(pNode) )
        {
            pFanin = Abc_ObjFanin0(pNode);
            pNodeMap = Map_NodeBuf( pMan, Map_NotCond( Abc_ObjFanin0(pFanin)->pCopy, (int)Abc_ObjFaninC0(pFanin) ) );
            Abc_ObjFanout0(pNode)->pCopy = (Abc_Obj_t *)pNodeMap;
            continue;
        }
        assert( Abc_ObjIsNode(pNode) );
        // add the node to the mapper
        pNodeMap = Map_NodeAnd( pMan, 
            Map_NotCond( Abc_ObjFanin0(pNode)->pCopy, (int)Abc_ObjFaninC0(pNode) ),
            Map_NotCond( Abc_ObjFanin1(pNode)->pCopy, (int)Abc_ObjFaninC1(pNode) ) );
        assert( pNode->pCopy == NULL );
        // remember the node
        pNode->pCopy = (Abc_Obj_t *)pNodeMap;
        if ( pSwitching )
            Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] );
        // set up the choice node
        if ( Abc_AigNodeIsChoice( pNode ) )
            for ( pPrev = pNode, pFanin = (Abc_Obj_t *)pNode->pData; pFanin; pPrev = pFanin, pFanin = (Abc_Obj_t *)pFanin->pData )
            {
                Map_NodeSetNextE( (Map_Node_t *)pPrev->pCopy, (Map_Node_t *)pFanin->pCopy );
                Map_NodeSetRepr( (Map_Node_t *)pFanin->pCopy, (Map_Node_t *)pNode->pCopy );
            }
    }
    assert( Map_ManReadBufNum(pMan) == pNtk->nBarBufs );
    Vec_PtrFree( vNodes );

    // set the primary outputs in the required phase
    Abc_NtkForEachCo( pNtk, pNode, i )
    {
        if ( i == Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
            break;
        Map_ManReadOutputs(pMan)[i] = Map_NotCond( (Map_Node_t *)Abc_ObjFanin0(pNode)->pCopy, (int)Abc_ObjFaninC0(pNode) );
    }
    return pMan;
}
Esempio n. 18
0
/**Function*************************************************************

  Synopsis    [Writes the graph structure of network for DOT.]

  Description [Useful for graph visualization using tools such as GraphViz: 
  http://www.graphviz.org/]
  
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fGateNames, int fUseReverse )
{
    FILE * pFile;
    Abc_Obj_t * pNode, * pFanin;
    char * pSopString;
    int LevelMin, LevelMax, fHasCos, Level, i, k, fHasBdds, fCompl;
    int Limit = 300;

    assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsLogic(pNtk) );

    if ( vNodes->nSize < 1 )
    {
        printf( "The set has no nodes. DOT file is not written.\n" );
        return;
    }

    if ( vNodes->nSize > Limit )
    {
        printf( "The set has more than %d nodes. DOT file is not written.\n", Limit );
        return;
    }

    // start the stream
    if ( (pFile = fopen( pFileName, "w" )) == NULL )
    {
        fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName );
        return;
    }

    // transform logic functions from BDD to SOP
    if ( fHasBdds = Abc_NtkIsBddLogic(pNtk) )
    {
        if ( !Abc_NtkBddToSop(pNtk, 0) )
        {
            printf( "Io_WriteDotNtk(): Converting to SOPs has failed.\n" );
            return;
        }
    }

    // mark the nodes from the set
    Vec_PtrForEachEntry( vNodes, pNode, i )
        pNode->fMarkC = 1;
    if ( vNodesShow )
        Vec_PtrForEachEntry( vNodesShow, pNode, i )
            pNode->fMarkB = 1;

    // get the levels of nodes
    LevelMax = Abc_NtkLevel( pNtk );
    if ( fUseReverse )
    {
        LevelMin = Abc_NtkLevelReverse( pNtk );
        assert( LevelMax == LevelMin );
        Vec_PtrForEachEntry( vNodes, pNode, i )
            if ( Abc_ObjIsNode(pNode) )
                pNode->Level = LevelMax - pNode->Level + 1;
    }

    // find the largest and the smallest levels
    LevelMin = 10000;
    LevelMax = -1;
    fHasCos  = 0;
    Vec_PtrForEachEntry( vNodes, pNode, i )
    {
        if ( Abc_ObjIsCo(pNode) )
        {
            fHasCos = 1;
            continue;
        }
        if ( LevelMin > (int)pNode->Level )
            LevelMin = pNode->Level;
        if ( LevelMax < (int)pNode->Level )
            LevelMax = pNode->Level;
    }

    // set the level of the CO nodes
    if ( fHasCos )
    {
        LevelMax++;
        Vec_PtrForEachEntry( vNodes, pNode, i )
        {
            if ( Abc_ObjIsCo(pNode) )
                pNode->Level = LevelMax;
        }
    }

    // write the DOT header
    fprintf( pFile, "# %s\n",  "Network structure generated by ABC" );
    fprintf( pFile, "\n" );
    fprintf( pFile, "digraph network {\n" );
    fprintf( pFile, "size = \"7.5,10\";\n" );
//    fprintf( pFile, "size = \"10,8.5\";\n" );
//    fprintf( pFile, "size = \"14,11\";\n" );
//    fprintf( pFile, "page = \"8,11\";\n" );
//  fprintf( pFile, "ranksep = 0.5;\n" );
//  fprintf( pFile, "nodesep = 0.5;\n" );
    fprintf( pFile, "center = true;\n" );
//    fprintf( pFile, "orientation = landscape;\n" );
//  fprintf( pFile, "edge [fontsize = 10];\n" );
//  fprintf( pFile, "edge [dir = none];\n" );
    fprintf( pFile, "edge [dir = back];\n" );
    fprintf( pFile, "\n" );

    // labels on the left of the picture
    fprintf( pFile, "{\n" );
    fprintf( pFile, "  node [shape = plaintext];\n" );
    fprintf( pFile, "  edge [style = invis];\n" );
    fprintf( pFile, "  LevelTitle1 [label=\"\"];\n" );
    fprintf( pFile, "  LevelTitle2 [label=\"\"];\n" );
    // generate node names with labels
    for ( Level = LevelMax; Level >= LevelMin; Level-- )
    {
        // the visible node name
        fprintf( pFile, "  Level%d", Level );
        fprintf( pFile, " [label = " );
        // label name
        fprintf( pFile, "\"" );
        fprintf( pFile, "\"" );
        fprintf( pFile, "];\n" );
    }

    // genetate the sequence of visible/invisible nodes to mark levels
    fprintf( pFile, "  LevelTitle1 ->  LevelTitle2 ->" );
    for ( Level = LevelMax; Level >= LevelMin; Level-- )
    {
        // the visible node name
        fprintf( pFile, "  Level%d",  Level );
        // the connector
        if ( Level != LevelMin )
            fprintf( pFile, " ->" );
        else
            fprintf( pFile, ";" );
    }
    fprintf( pFile, "\n" );
    fprintf( pFile, "}" );
    fprintf( pFile, "\n" );
    fprintf( pFile, "\n" );

    // generate title box on top
    fprintf( pFile, "{\n" );
    fprintf( pFile, "  rank = same;\n" );
    fprintf( pFile, "  LevelTitle1;\n" );
    fprintf( pFile, "  title1 [shape=plaintext,\n" );
    fprintf( pFile, "          fontsize=20,\n" );
    fprintf( pFile, "          fontname = \"Times-Roman\",\n" );
    fprintf( pFile, "          label=\"" );
    fprintf( pFile, "%s", "Network structure visualized by ABC" );
    fprintf( pFile, "\\n" );
    fprintf( pFile, "Benchmark \\\"%s\\\". ", pNtk->pName );
    fprintf( pFile, "Time was %s. ",  Extra_TimeStamp() );
    fprintf( pFile, "\"\n" );
    fprintf( pFile, "         ];\n" );
    fprintf( pFile, "}" );
    fprintf( pFile, "\n" );
    fprintf( pFile, "\n" );

    // generate statistics box
    fprintf( pFile, "{\n" );
    fprintf( pFile, "  rank = same;\n" );
    fprintf( pFile, "  LevelTitle2;\n" );
    fprintf( pFile, "  title2 [shape=plaintext,\n" );
    fprintf( pFile, "          fontsize=18,\n" );
    fprintf( pFile, "          fontname = \"Times-Roman\",\n" );
    fprintf( pFile, "          label=\"" );
    if ( Abc_NtkObjNum(pNtk) == Vec_PtrSize(vNodes) )
        fprintf( pFile, "The network contains %d logic nodes and %d latches.", Abc_NtkNodeNum(pNtk), Abc_NtkLatchNum(pNtk) );
    else
        fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Abc_NtkCountLogicNodes(vNodes), LevelMax - LevelMin + 1 );
    fprintf( pFile, "\\n" );
    fprintf( pFile, "\"\n" );
    fprintf( pFile, "         ];\n" );
    fprintf( pFile, "}" );
    fprintf( pFile, "\n" );
    fprintf( pFile, "\n" );

    // generate the POs
    if ( fHasCos )
    {
        fprintf( pFile, "{\n" );
        fprintf( pFile, "  rank = same;\n" );
        // the labeling node of this level
        fprintf( pFile, "  Level%d;\n",  LevelMax );
        // generate the PO nodes
        Vec_PtrForEachEntry( vNodes, pNode, i )
        {
            if ( !Abc_ObjIsCo(pNode) )
                continue;
            fprintf( pFile, "  Node%d [label = \"%s%s\"", 
                pNode->Id, 
                (Abc_ObjIsBi(pNode)? Abc_ObjName(Abc_ObjFanout0(pNode)):Abc_ObjName(pNode)), 
                (Abc_ObjIsBi(pNode)? "_in":"") );
            fprintf( pFile, ", shape = %s", (Abc_ObjIsBi(pNode)? "box":"invtriangle") );
            if ( pNode->fMarkB )
                fprintf( pFile, ", style = filled" );
            fprintf( pFile, ", color = coral, fillcolor = coral" );
            fprintf( pFile, "];\n" );
        }
        fprintf( pFile, "}" );
        fprintf( pFile, "\n" );
        fprintf( pFile, "\n" );
    }

    // generate nodes of each rank
    for ( Level = LevelMax - fHasCos; Level >= LevelMin && Level > 0; Level-- )
    {
        fprintf( pFile, "{\n" );
        fprintf( pFile, "  rank = same;\n" );
        // the labeling node of this level
        fprintf( pFile, "  Level%d;\n",  Level );
        Vec_PtrForEachEntry( vNodes, pNode, i )
        {
            if ( (int)pNode->Level != Level )
                continue;
            if ( Abc_ObjFaninNum(pNode) == 0 )
                continue;
//            fprintf( pFile, "  Node%d [label = \"%d\"", pNode->Id, pNode->Id );
            if ( Abc_NtkIsStrash(pNtk) )
                pSopString = "";
            else if ( Abc_NtkHasMapping(pNtk) && fGateNames )
                pSopString = Mio_GateReadName(pNode->pData);
            else if ( Abc_NtkHasMapping(pNtk) )
                pSopString = Abc_NtkPrintSop(Mio_GateReadSop(pNode->pData));
            else
                pSopString = Abc_NtkPrintSop(pNode->pData);
            fprintf( pFile, "  Node%d [label = \"%d\\n%s\"", pNode->Id, pNode->Id, pSopString );

            fprintf( pFile, ", shape = ellipse" );
            if ( pNode->fMarkB )
                fprintf( pFile, ", style = filled" );
            fprintf( pFile, "];\n" );
        }
        fprintf( pFile, "}" );
        fprintf( pFile, "\n" );
        fprintf( pFile, "\n" );
    }

    // generate the PI nodes if any
    if ( LevelMin == 0 )
    {
        fprintf( pFile, "{\n" );
        fprintf( pFile, "  rank = same;\n" );
        // the labeling node of this level
        fprintf( pFile, "  Level%d;\n",  LevelMin );
        // generate the PO nodes
        Vec_PtrForEachEntry( vNodes, pNode, i )
        {
            if ( !Abc_ObjIsCi(pNode) )
            {
                // check if the costant node is present
                if ( Abc_ObjFaninNum(pNode) == 0 && Abc_ObjFanoutNum(pNode) > 0 )
                {
                    fprintf( pFile, "  Node%d [label = \"Const%d\"", pNode->Id, Abc_NtkIsStrash(pNode->pNtk) || Abc_NodeIsConst1(pNode) );
                    fprintf( pFile, ", shape = ellipse" );
                    if ( pNode->fMarkB )
                        fprintf( pFile, ", style = filled" );
                    fprintf( pFile, ", color = coral, fillcolor = coral" );
                    fprintf( pFile, "];\n" );
                }
                continue;
            }
            fprintf( pFile, "  Node%d [label = \"%s\"", 
                pNode->Id, 
                (Abc_ObjIsBo(pNode)? Abc_ObjName(Abc_ObjFanin0(pNode)):Abc_ObjName(pNode)) );
            fprintf( pFile, ", shape = %s", (Abc_ObjIsBo(pNode)? "box":"triangle") );
            if ( pNode->fMarkB )
                fprintf( pFile, ", style = filled" );
            fprintf( pFile, ", color = coral, fillcolor = coral" );
            fprintf( pFile, "];\n" );
        }
        fprintf( pFile, "}" );
        fprintf( pFile, "\n" );
        fprintf( pFile, "\n" );
    }
Esempio n. 19
0
/**Function*************************************************************

  Synopsis    [Strashes one node in the BLIF-MV netlist.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_NodeStrashBlifMv( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj )
{
    int fAddFreeVars = 1;
    char * pSop;
    Abc_Obj_t ** pValues, ** pValuesF, ** pValuesF2;
    Abc_Obj_t * pTemp, * pTemp2, * pFanin, * pFanin2, * pNet;
    int k, v, Def, DefIndex, Index, nValues, nValuesF, nValuesF2;

    // start the output values
    assert( Abc_ObjIsNode(pObj) );
    pNet = Abc_ObjFanout0(pObj);
    nValues = Abc_ObjMvVarNum(pNet);
    pValues = ABC_ALLOC( Abc_Obj_t *, nValues );
    for ( k = 0; k < nValues; k++ )
        pValues[k] = Abc_ObjNot( Abc_AigConst1(pNtkNew) );

    // get the BLIF-MV formula
    pSop = (char *)pObj->pData;
    // skip the value line
//    while ( *pSop++ != '\n' );

    // handle the constant
    if ( Abc_ObjFaninNum(pObj) == 0 )
    {
        // skip the default if present
        if ( *pSop == 'd' )
            while ( *pSop++ != '\n' );
        // skip space if present
        if ( *pSop == ' ' )
            pSop++;
        // assume don't-care constant to be zero
        if ( *pSop == '-' )
            Index = 0;
        else
            Index = Abc_StringGetNumber( &pSop );
        assert( Index < nValues );
        ////////////////////////////////////////////
        // adding free variables for binary ND-constants
        if ( fAddFreeVars && nValues == 2 && *pSop == '-' )
        {
            pValues[1] = Abc_NtkCreatePi(pNtkNew);
            pValues[0] = Abc_ObjNot( pValues[1] );
            Abc_ObjAssignName( pValues[1], "free_var_", Abc_ObjName(pValues[1]) );
        }
        else
            pValues[Index] = Abc_AigConst1(pNtkNew);
        ////////////////////////////////////////////
        // save the values in the fanout net
        pNet->pCopy = (Abc_Obj_t *)pValues;
        return 1;
    }

    // parse the default line
    Def = DefIndex = -1;
    if ( *pSop == 'd' )
    {
        pSop++;
        if ( *pSop == '=' )
        {
            pSop++;
            DefIndex = Abc_StringGetNumber( &pSop );
            assert( DefIndex < Abc_ObjFaninNum(pObj) );
        }
        else if ( *pSop == '-' )
        {
            pSop++;
            Def = 0;
        }
        else
        {
            Def = Abc_StringGetNumber( &pSop );
            assert( Def < nValues );
        }
        assert( *pSop == '\n' );
        pSop++;
    }

    // convert the values
    while ( *pSop )
    {
        // extract the values for each cube
        pTemp = Abc_AigConst1(pNtkNew); 
        Abc_ObjForEachFanin( pObj, pFanin, k )
        {
            if ( *pSop == '-' )
            {
                pSop += 2;
                continue;
            }
            if ( *pSop == '!' )
            {
                ABC_FREE( pValues );
                printf( "Abc_NodeStrashBlifMv(): Cannot handle complement in the MV function of node %s.\n", Abc_ObjName(Abc_ObjFanout0(pObj)) );
                return 0;
            }
            if ( *pSop == '{' )
            {
                ABC_FREE( pValues );
                printf( "Abc_NodeStrashBlifMv(): Cannot handle braces in the MV function of node %s.\n", Abc_ObjName(Abc_ObjFanout0(pObj)) );
                return 0;
            }
            // get the value set
            nValuesF = Abc_ObjMvVarNum(pFanin);
            pValuesF = (Abc_Obj_t **)pFanin->pCopy;
            if ( *pSop == '(' )
            {
                pSop++;
                pTemp2 = Abc_ObjNot( Abc_AigConst1(pNtkNew) );
                while ( *pSop != ')' )
                {
                    Index = Abc_StringGetNumber( &pSop );
                    assert( Index < nValuesF );
                    pTemp2 = Abc_AigOr( (Abc_Aig_t *)pNtkNew->pManFunc, pTemp2, pValuesF[Index] );
                    assert( *pSop == ')' || *pSop == ',' );
                    if ( *pSop == ',' )
                        pSop++;
                }
                assert( *pSop == ')' );
                pSop++;
            }
            else if ( *pSop == '=' )
            {
                pSop++;
                // get the fanin index
                Index = Abc_StringGetNumber( &pSop );
                assert( Index < Abc_ObjFaninNum(pObj) );
                assert( Index != k );
                // get the fanin
                pFanin2 = Abc_ObjFanin( pObj, Index );
                nValuesF2 = Abc_ObjMvVarNum(pFanin2);
                pValuesF2 = (Abc_Obj_t **)pFanin2->pCopy;
                // create the sum of products of values
                assert( nValuesF == nValuesF2 );
                pTemp2 = Abc_ObjNot( Abc_AigConst1(pNtkNew) );
                for ( v = 0; v < nValues; v++ )
                    pTemp2 = Abc_AigOr( (Abc_Aig_t *)pNtkNew->pManFunc, pTemp2, Abc_AigAnd((Abc_Aig_t *)pNtkNew->pManFunc, pValuesF[v], pValuesF2[v]) );
            }
            else
            {
                Index = Abc_StringGetNumber( &pSop );
                assert( Index < nValuesF );
                pTemp2 = pValuesF[Index];
            }
            // compute the compute
            pTemp = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, pTemp, pTemp2 );
            // advance the reading point
            assert( *pSop == ' ' );
            pSop++;
        }
        // check if the output value is an equal construct
        if ( *pSop == '=' )
        {
            pSop++;
            // get the output value
            Index = Abc_StringGetNumber( &pSop );
            assert( Index < Abc_ObjFaninNum(pObj) );
            // add values of the given fanin with the given cube
            pFanin = Abc_ObjFanin( pObj, Index );
            nValuesF = Abc_ObjMvVarNum(pFanin);
            pValuesF = (Abc_Obj_t **)pFanin->pCopy;
            assert( nValuesF == nValues ); // should be guaranteed by the parser
            for ( k = 0; k < nValuesF; k++ )
                pValues[k] = Abc_AigOr( (Abc_Aig_t *)pNtkNew->pManFunc, pValues[k], Abc_AigAnd((Abc_Aig_t *)pNtkNew->pManFunc, pTemp, pValuesF[k]) );
        }
        else
        {
            // get the output value
            Index = Abc_StringGetNumber( &pSop );
            assert( Index < nValues );
            pValues[Index] = Abc_AigOr( (Abc_Aig_t *)pNtkNew->pManFunc, pValues[Index], pTemp );
        }
        // advance the reading point
        assert( *pSop == '\n' );
        pSop++;
    }

    // compute the default value
    if ( Def >= 0 || DefIndex >= 0 )
    {
        pTemp = Abc_AigConst1(pNtkNew);
        for ( k = 0; k < nValues; k++ )
        {
            if ( k == Def )
                continue;
            pTemp = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, pTemp, Abc_ObjNot(pValues[k]) );
        }

        // assign the default value
        if ( Def >= 0 )
            pValues[Def] = pTemp;
        else
        {
            assert( DefIndex >= 0 );
            // add values of the given fanin with the given cube
            pFanin = Abc_ObjFanin( pObj, DefIndex );
            nValuesF = Abc_ObjMvVarNum(pFanin);
            pValuesF = (Abc_Obj_t **)pFanin->pCopy;
            assert( nValuesF == nValues ); // should be guaranteed by the parser
            for ( k = 0; k < nValuesF; k++ )
                pValues[k] = Abc_AigOr( (Abc_Aig_t *)pNtkNew->pManFunc, pValues[k], Abc_AigAnd((Abc_Aig_t *)pNtkNew->pManFunc, pTemp, pValuesF[k]) );
        }

    }

    // save the values in the fanout net
    pNet->pCopy = (Abc_Obj_t *)pValues;
    return 1;
}
Esempio n. 20
0
File: abcCheck.c Progetto: mrkj/abc
static inline char * Abc_ObjNameNet( Abc_Obj_t * pObj ) { return (Abc_ObjIsNode(pObj) && Abc_NtkIsNetlist(pObj->pNtk)) ? Abc_ObjName(Abc_ObjFanout0(pObj)) : Abc_ObjName(pObj); }