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

  Synopsis    [Creates a primary input node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Fraig_Node_t * Fraig_NodeCreatePi( Fraig_Man_t * p )
{
    Fraig_Node_t * pNode, * pNodeRes;
    int i, clk;

    // create the node
    pNode = (Fraig_Node_t *)Fraig_MemFixedEntryFetch( p->mmNodes );
    memset( pNode, 0, sizeof(Fraig_Node_t) );
    pNode->puSimR = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims );
    pNode->puSimD = pNode->puSimR + p->nWordsRand;
    memset( pNode->puSimD, 0, sizeof(unsigned) * p->nWordsDyna );

    // assign the number and add to the array of nodes
    pNode->Num   = p->vNodes->nSize;
    Fraig_NodeVecPush( p->vNodes,  pNode );

    // assign the PI number and add to the array of primary inputs
    pNode->NumPi = p->vInputs->nSize;   
    Fraig_NodeVecPush( p->vInputs, pNode );

    pNode->Level =  0;  // PI has 0 level
    pNode->nRefs =  1;  // it is a persistent node, which comes referenced
    pNode->fInv  =  0;  // the simulation info of the PI is not complemented

    // derive the simulation info for the new node
clk = clock();
    // set the random simulation info for the primary input
    pNode->uHashR = 0;
    for ( i = 0; i < p->nWordsRand; i++ )
    {
        // generate the simulation info
        pNode->puSimR[i] = FRAIG_RANDOM_UNSIGNED;
        // for reasons that take very long to explain, it makes sense to have (0000000...) 
        // pattern in the set (this helps if we need to return the counter-examples)
        if ( i == 0 )
            pNode->puSimR[i] <<= 1;
        // compute the hash key
        pNode->uHashR ^= pNode->puSimR[i] * s_FraigPrimes[i];
    }
    // count the number of ones in the simulation vector
    pNode->nOnes = Fraig_BitStringCountOnes( pNode->puSimR, p->nWordsRand );

    // set the systematic simulation info for the primary input
    pNode->uHashD = 0;
    for ( i = 0; i < p->iWordStart; i++ )
    {
        // generate the simulation info
        pNode->puSimD[i] = FRAIG_RANDOM_UNSIGNED;
        // compute the hash key
        pNode->uHashD ^= pNode->puSimD[i] * s_FraigPrimes[i];
    }
p->timeSims += clock() - clk;

    // insert it into the hash table
    pNodeRes = Fraig_HashTableLookupF( p, pNode );
    assert( pNodeRes == NULL );
    // add to the runtime of simulation
    return pNode;
}
/**Function*************************************************************

  Synopsis    [Creates the constant 1 node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Fraig_Node_t * Fraig_NodeCreateConst( Fraig_Man_t * p )
{
    Fraig_Node_t * pNode;

    // create the node
    pNode = (Fraig_Node_t *)Fraig_MemFixedEntryFetch( p->mmNodes );
    memset( pNode, 0, sizeof(Fraig_Node_t) );

    // assign the number and add to the array of nodes
    pNode->Num   = p->vNodes->nSize;
    Fraig_NodeVecPush( p->vNodes,  pNode );
    pNode->NumPi = -1;  // this is not a PI, so its number is -1
    pNode->Level =  0;  // just like a PI, it has 0 level
    pNode->nRefs =  1;  // it is a persistent node, which comes referenced
    pNode->fInv  =  1;  // the simulation info is complemented

    // create the simulation info
    pNode->puSimR = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims );
    pNode->puSimD = pNode->puSimR + p->nWordsRand;
    memset( pNode->puSimR, 0, sizeof(unsigned) * p->nWordsRand );
    memset( pNode->puSimD, 0, sizeof(unsigned) * p->nWordsDyna );

    // count the number of ones in the simulation vector
    pNode->nOnes = p->nWordsRand * sizeof(unsigned) * 8;

    // insert it into the hash table
    Fraig_HashTableLookupF0( p, pNode );
    return pNode;
}
Exemple #3
0
/**Function*************************************************************

  Synopsis    [Add the element while ensuring uniqueness.]

  Description [Returns 1 if the element was found, and 0 if it was new. ]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fraig_NodeVecPushUnique( Fraig_NodeVec_t * p, Fraig_Node_t * Entry )
{
    int i;
    for ( i = 0; i < p->nSize; i++ )
        if ( p->pArray[i] == Entry )
            return 1;
    Fraig_NodeVecPush( p, Entry );
    return 0;
}
/**Function*************************************************************

  Synopsis    [Creates a new node.]

  Description [This procedure should be called to create the constant
  node and the PI nodes first.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Fraig_Node_t * Fraig_NodeCreate( Fraig_Man_t * p, Fraig_Node_t * p1, Fraig_Node_t * p2 )
{
    Fraig_Node_t * pNode;
    int clk;

    // create the node
    pNode = (Fraig_Node_t *)Fraig_MemFixedEntryFetch( p->mmNodes );
    memset( pNode, 0, sizeof(Fraig_Node_t) );

    // assign the children
    pNode->p1  = p1;  Fraig_Ref(p1);  Fraig_Regular(p1)->nRefs++;
    pNode->p2  = p2;  Fraig_Ref(p2);  Fraig_Regular(p2)->nRefs++;

    // assign the number and add to the array of nodes
    pNode->Num = p->vNodes->nSize;
    Fraig_NodeVecPush( p->vNodes,  pNode );

    // assign the PI number
    pNode->NumPi = -1;

    // compute the level of this node
    pNode->Level = 1 + FRAIG_MAX(Fraig_Regular(p1)->Level, Fraig_Regular(p2)->Level);
    pNode->fInv  = Fraig_NodeIsSimComplement(p1) & Fraig_NodeIsSimComplement(p2);
    pNode->fFailTfo = Fraig_Regular(p1)->fFailTfo | Fraig_Regular(p2)->fFailTfo;

    // derive the simulation info 
clk = clock();
    // allocate memory for the simulation info
    pNode->puSimR = (unsigned *)Fraig_MemFixedEntryFetch( p->mmSims );
    pNode->puSimD = pNode->puSimR + p->nWordsRand;
    // derive random simulation info
    pNode->uHashR = 0;
    Fraig_NodeSimulate( pNode, 0, p->nWordsRand, 1 );
    // derive dynamic simulation info
    pNode->uHashD = 0;
    Fraig_NodeSimulate( pNode, 0, p->iWordStart, 0 );
    // count the number of ones in the random simulation info
    pNode->nOnes = Fraig_BitStringCountOnes( pNode->puSimR, p->nWordsRand );
    if ( pNode->fInv )
        pNode->nOnes = p->nWordsRand * 32 - pNode->nOnes;
    // add to the runtime of simulation
p->timeSims += clock() - clk;

#ifdef FRAIG_ENABLE_FANOUTS
    // create the fanout info
    Fraig_NodeAddFaninFanout( Fraig_Regular(p1), pNode );
    Fraig_NodeAddFaninFanout( Fraig_Regular(p2), pNode );
#endif
    return pNode;
}
Exemple #5
0
/**Function*************************************************************

  Synopsis    [Counts the number of EXOR type nodes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fraig_ManPrintRefs( Fraig_Man_t * pMan )
{
    Fraig_NodeVec_t * vPivots;
    Fraig_Node_t * pNode, * pNode2;
    int i, k, Counter, nProved;
    abctime clk;

    vPivots = Fraig_NodeVecAlloc( 1000 );
    for ( i = 0; i < pMan->vNodes->nSize; i++ )
    {
        pNode = pMan->vNodes->pArray[i];

        if ( pNode->nOnes == 0 || pNode->nOnes == (unsigned)pMan->nWordsRand * 32 )
            continue;

        if ( pNode->nRefs > 5 )
        {
            Fraig_NodeVecPush( vPivots, pNode );
//            printf( "Node %6d : nRefs = %2d   Level = %3d.\n", pNode->Num, pNode->nRefs, pNode->Level );
        }
    }
    printf( "Total nodes = %d. Referenced nodes = %d.\n", pMan->vNodes->nSize, vPivots->nSize );

clk = Abc_Clock();
    // count implications
    Counter = nProved = 0;
    for ( i = 0; i < vPivots->nSize; i++ )
        for ( k = i+1; k < vPivots->nSize; k++ )
        {
            pNode  = vPivots->pArray[i];
            pNode2 = vPivots->pArray[k];
            if ( Fraig_NodeSimsContained( pMan, pNode, pNode2 ) )
            {
                if ( Fraig_NodeIsImplication( pMan, pNode, pNode2, -1 ) )
                    nProved++;
                Counter++;
            }
            else if ( Fraig_NodeSimsContained( pMan, pNode2, pNode ) )
            {
                if ( Fraig_NodeIsImplication( pMan, pNode2, pNode, -1 ) )
                    nProved++;
                Counter++;
            }
        }
    printf( "Number of candidate pairs = %d.  Proved = %d.\n", Counter, nProved );
//ABC_PRT( "Time", Abc_Clock() - clk );
    return 0;
}
Exemple #6
0
/**Function*************************************************************

  Synopsis    [Inserts a new node in the order by arrival times.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fraig_NodeVecPushOrderByLevel( Fraig_NodeVec_t * p, Fraig_Node_t * pNode )
{
    Fraig_Node_t * pNode1, * pNode2;
    int i;
    Fraig_NodeVecPush( p, pNode );
    // find the p of the node
    for ( i = p->nSize-1; i > 0; i-- )
    {
        pNode1 = p->pArray[i  ];
        pNode2 = p->pArray[i-1];
        if ( Fraig_Regular(pNode1)->Level <= Fraig_Regular(pNode2)->Level )
            break;
        p->pArray[i  ] = pNode2;
        p->pArray[i-1] = pNode1;
    }
}
Exemple #7
0
/**Function*************************************************************

  Synopsis    [Inserts a new node in the order by arrival times.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fraig_NodeVecPushOrder( Fraig_NodeVec_t * p, Fraig_Node_t * pNode )
{
    Fraig_Node_t * pNode1, * pNode2;
    int i;
    Fraig_NodeVecPush( p, pNode );
    // find the p of the node
    for ( i = p->nSize-1; i > 0; i-- )
    {
        pNode1 = p->pArray[i  ];
        pNode2 = p->pArray[i-1];
        if ( pNode1 >= pNode2 )
            break;
        p->pArray[i  ] = pNode2;
        p->pArray[i-1] = pNode1;
    }
}
Exemple #8
0
/**Function*************************************************************

  Synopsis    [Recursively computes the DFS ordering of the nodes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fraig_Dfs_rec( Fraig_Man_t * pMan, Fraig_Node_t * pNode, Fraig_NodeVec_t * vNodes, int fEquiv )
{
    assert( !Fraig_IsComplement(pNode) );
    // skip the visited node
    if ( pNode->TravId == pMan->nTravIds )
        return;
    pNode->TravId = pMan->nTravIds;
    // visit the transitive fanin
    if ( Fraig_NodeIsAnd(pNode) )
    {
        Fraig_Dfs_rec( pMan, Fraig_Regular(pNode->p1), vNodes, fEquiv );
        Fraig_Dfs_rec( pMan, Fraig_Regular(pNode->p2), vNodes, fEquiv );
    }
    if ( fEquiv && pNode->pNextE )
        Fraig_Dfs_rec( pMan, pNode->pNextE, vNodes, fEquiv );
    // save the node
    Fraig_NodeVecPush( vNodes, pNode );
}
Exemple #9
0
/**Function*************************************************************

  Synopsis    [Creates a new PO node.]

  Description [This procedure may take a complemented node.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fraig_ManSetPo( Fraig_Man_t * p, Fraig_Node_t * pNode )
{
    // internal node may be a PO two times
    Fraig_Regular(pNode)->fNodePo = 1;
    Fraig_NodeVecPush( p->vOutputs, pNode );
}