Пример #1
0
/**Function*************************************************************

  Synopsis    [Starts the monolithic image computation.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Extra_ImageTree2_t * Extra_bddImageStart2( 
    DdManager * dd, DdNode * bCare,
    int nParts, DdNode ** pbParts,
    int nVars, DdNode ** pbVars, int fVerbose )
{
    Extra_ImageTree2_t * pTree;
    DdNode * bCubeAll, * bCubeNot, * bTemp;
    int i;

    pTree = ABC_ALLOC( Extra_ImageTree2_t, 1 );
    pTree->dd = dd;
    pTree->bImage = NULL;

    bCubeAll = Extra_bddComputeCube( dd, dd->vars, dd->size );      Cudd_Ref( bCubeAll );
    bCubeNot = Extra_bddComputeCube( dd, pbVars,   nVars );         Cudd_Ref( bCubeNot );
    pTree->bCube = Cudd_bddExistAbstract( dd, bCubeAll, bCubeNot ); Cudd_Ref( pTree->bCube );
    Cudd_RecursiveDeref( dd, bCubeAll );
    Cudd_RecursiveDeref( dd, bCubeNot );

    // derive the monolithic relation
    pTree->bRel = b1;   Cudd_Ref( pTree->bRel );
    for ( i = 0; i < nParts; i++ )
    {
        pTree->bRel = Cudd_bddAnd( dd, bTemp = pTree->bRel, pbParts[i] ); Cudd_Ref( pTree->bRel );
        Cudd_RecursiveDeref( dd, bTemp );
    }
    Extra_bddImageCompute2( pTree, bCare );
    return pTree;
}
Пример #2
0
static keyvalue_table_ptr cudd_equant(shadow_mgr mgr,
				      set_ptr roots, set_ptr vars) {
    DdNode *cube = cudd_lit_cube(mgr, vars);
    keyvalue_table_ptr etable = word_keyvalue_new();
    word_t w;
    set_iterstart(roots);
    while (set_iternext(roots, &w)) {
	ref_t r = (ref_t) w;
	DdNode *n = get_ddnode(mgr, r);
	DdNode *nr = Cudd_bddExistAbstract(mgr->bdd_manager, n, cube);
	reference_dd(mgr, nr);
	keyvalue_insert(etable, w, (word_t) nr);
    }
    unreference_dd(mgr, cube, IS_BDD);
    return etable;
}
Пример #3
0
/**Function*************************************************************

  Synopsis    [Recompute the image.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Extra_bddImageCompute_rec( Extra_ImageTree_t * pTree, Extra_ImageNode_t * pNode )
{
    DdManager * dd = pNode->dd;
    DdNode * bTemp;
    int nNodes;

    // trivial case
    if ( pNode->pNode1 == NULL )
    {
        if ( pNode->bCube )
        {
            pNode->bImage = Cudd_bddExistAbstract( dd, bTemp = pNode->bImage, pNode->bCube ); 
            Cudd_Ref( pNode->bImage );
            Cudd_RecursiveDeref( dd, bTemp );
        }
        return;
    }

    // compute the children
    if ( pNode->pNode1 )
        Extra_bddImageCompute_rec( pTree, pNode->pNode1 );
    if ( pNode->pNode2 )
        Extra_bddImageCompute_rec( pTree, pNode->pNode2 );

    // clean the old image
    if ( pNode->bImage )
        Cudd_RecursiveDeref( dd, pNode->bImage );
    pNode->bImage = NULL;

    // compute the new image
    if ( pNode->bCube )
        pNode->bImage = Cudd_bddAndAbstract( dd, 
            pNode->pNode1->bImage, pNode->pNode2->bImage, pNode->bCube );
    else
        pNode->bImage = Cudd_bddAnd( dd, pNode->pNode1->bImage, pNode->pNode2->bImage );
    Cudd_Ref( pNode->bImage );

    if ( pTree->fVerbose )
    {
        nNodes = Cudd_DagSize( pNode->bImage );
        if ( pTree->nNodesMax < nNodes )
            pTree->nNodesMax = nNodes;
    }
}
Пример #4
0
/**Function*************************************************************

  Synopsis    [Compute the image.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
DdNode * Extra_bddImageCompute( Extra_ImageTree_t * pTree, DdNode * bCare )
{
    DdManager * dd = pTree->pCare->dd;
    DdNode * bSupp, * bRem;

    pTree->nIter++;

    // make sure the supports are okay
    bSupp = Cudd_Support( dd, bCare );        Cudd_Ref( bSupp );
    if ( bSupp != pTree->bCareSupp )
    {
        bRem = Cudd_bddExistAbstract( dd, bSupp, pTree->bCareSupp );  Cudd_Ref( bRem );
        if ( bRem != b1 )
        {
printf( "Original care set support: " );
ABC_PRB( dd, pTree->bCareSupp );
printf( "Current care set support: " );
ABC_PRB( dd, bSupp );
            Cudd_RecursiveDeref( dd, bSupp );
            Cudd_RecursiveDeref( dd, bRem );
            printf( "The care set depends on some vars that were not in the care set during scheduling.\n" );
            return NULL;
        }
        Cudd_RecursiveDeref( dd, bRem );
    }
    Cudd_RecursiveDeref( dd, bSupp );

    // remove the previous image
    Cudd_RecursiveDeref( dd, pTree->pCare->bImage );
    pTree->pCare->bImage = bCare;   Cudd_Ref( bCare );

    // compute the image
    pTree->nNodesMax = 0;
    Extra_bddImageCompute_rec( pTree, pTree->pRoot );
    if ( pTree->nNodesMaxT < pTree->nNodesMax )
        pTree->nNodesMaxT = pTree->nNodesMax;

//    if ( pTree->fVerbose )
//        printf( "Iter %2d : Max nodes = %5d.\n", pTree->nIter, pTree->nNodesMax );
    return pTree->pRoot->bImage;
}
Пример #5
0
    Abc_NtkForEachLatch( pNtk, pNode, i )
    {
        bVar  = Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + i );
//        bProd = Cudd_bddXnor( dd, bVar, pNtk->vFuncsGlob->pArray[i] );  Cudd_Ref( bProd );
        bProd = Cudd_bddXnor( dd, bVar, Abc_ObjGlobalBdd(Abc_ObjFanin0(pNode)) );  Cudd_Ref( bProd );
        bRel  = Cudd_bddAnd( dd, bTemp = bRel, bProd );                 Cudd_Ref( bRel );
        Cudd_RecursiveDeref( dd, bTemp ); 
        Cudd_RecursiveDeref( dd, bProd ); 
    }
    // free the global BDDs
//    Abc_NtkFreeGlobalBdds( pNtk );
    Abc_NtkFreeGlobalBdds( pNtk, 0 );

    // quantify the PI variables
    bInputs = Extra_bddComputeRangeCube( dd, 0, Abc_NtkPiNum(pNtk) );    Cudd_Ref( bInputs );
    bRel    = Cudd_bddExistAbstract( dd, bTemp = bRel, bInputs );    Cudd_Ref( bRel );
    Cudd_RecursiveDeref( dd, bTemp ); 
    Cudd_RecursiveDeref( dd, bInputs ); 

    // reorder and disable reordering
    if ( fReorder )
    {
        if ( fVerbose )
            fprintf( stdout, "BDD nodes in the transition relation before reordering %d.\n", Cudd_DagSize(bRel) );
        Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 );
        Cudd_AutodynDisable( dd );
        if ( fVerbose )
            fprintf( stdout, "BDD nodes in the transition relation after reordering %d.\n", Cudd_DagSize(bRel) );
    }
    Cudd_Deref( bRel );
    return bRel;
Пример #6
0
/**Function********************************************************************

  Synopsis [BDD restrict according to Coudert and Madre's algorithm
  (ICCAD90).]

  Description [BDD restrict according to Coudert and Madre's algorithm
  (ICCAD90). Returns the restricted BDD if successful; otherwise NULL.]

  SideEffects [None]

  SeeAlso     [Cudd_bddRestrict]

******************************************************************************/
DdNode*
Cuddaux_bddRestrict(DdManager * dd, DdNode * f, DdNode * c)
{
  DdNode *one,*zero;
  DdNode *suppF, *suppC, *commonSupp, *onlyC;
  DdNode *cplus, *res;
  int retval;
  
  one = DD_ONE(dd);
  zero = Cudd_Not(one);
  /* Check terminal cases here to avoid computing supports in trivial cases.
  ** This also allows us notto check later for the case c == 0, in which
  ** there is no common support. */
  if (c == one) return(f);
  if (c == zero){
    fprintf(stderr,"Cuddaux_bddRestrict: warning: false careset\n");
    return(zero);
  }
  if (Cudd_IsConstant(f)) return(f);
  if (f == c) return(one);
  if (f == Cudd_Not(c)) return(zero);
  
  /* Check if supports intersect. */
  suppF = Cuddaux_Support(dd,f);
  if (suppF==NULL) return(NULL);
  cuddRef(suppF);

  suppC = Cuddaux_Support(dd,c);
  if (suppC==NULL){
    Cudd_IterDerefBdd(dd,suppF);
    return(NULL);
  }
  cuddRef(suppC);

  commonSupp = Cudd_bddLiteralSetIntersection(dd,suppF,suppC);
  if (commonSupp==NULL){
    Cudd_IterDerefBdd(dd,suppF);
    Cudd_IterDerefBdd(dd,suppC); 
    return(NULL);
  }
  if (commonSupp == one) {
    Cudd_IterDerefBdd(dd,suppF);
    Cudd_IterDerefBdd(dd,suppC); 
    return(f);
  }
  cuddRef(commonSupp);

  Cudd_IterDerefBdd(dd,suppF);
  /* Abstract from c the variables that do not appear in f. */
  onlyC = Cudd_Cofactor(dd,suppC,commonSupp);
  if (onlyC == NULL) {
    Cudd_IterDerefBdd(dd,suppC); 
    Cudd_IterDerefBdd(dd,commonSupp); 
    return(NULL);
  }
  cuddRef(onlyC);
  Cudd_IterDerefBdd(dd,suppC); 
  Cudd_IterDerefBdd(dd,commonSupp); 
  cplus = Cudd_bddExistAbstract(dd, c, onlyC);
  if (cplus == NULL) {
    Cudd_IterDerefBdd(dd,onlyC); 
    return(NULL);
  }
  cuddRef(cplus);
  Cudd_IterDerefBdd(dd,onlyC);
  
  do {
    dd->reordered = 0;
    res = cuddBddRestrictRecur(dd, f, cplus);
  } while (dd->reordered == 1);
  if (res == NULL) {
    Cudd_IterDerefBdd(dd,cplus);
    return(NULL);
  }
  cuddRef(res);
  Cudd_IterDerefBdd(dd,cplus);
  cuddDeref(res);
  return(res);
} /* end of Cuddaux_bddRestrict */
Пример #7
0
/**Function*************************************************************

  Synopsis    [Builds the tree.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Extra_BuildTreeNode( DdManager * dd, 
    int nNodes, Extra_ImageNode_t ** pNodes, 
    int nVars,  Extra_ImageVar_t ** pVars )
{
    Extra_ImageNode_t * pNode1, * pNode2;
    Extra_ImageVar_t * pVar;
    Extra_ImageNode_t * pNode;
    DdNode * bCube, * bTemp, * bSuppTemp, * bParts;
    int iNode1, iNode2;
    int iVarBest, nSupp, v;

    // find the best variable
    iVarBest = Extra_FindBestVariable( dd, nNodes, pNodes, nVars, pVars );
    if ( iVarBest == -1 )
        return 0;

    pVar = pVars[iVarBest];

    // this var cannot appear in one partition only
    nSupp = Extra_bddSuppSize( dd, pVar->bParts );
    assert( nSupp == pVar->nParts );
    assert( nSupp != 1 );

    // if it appears in only two partitions, quantify it
    if ( pVar->nParts == 2 )
    {
        // get the nodes
        iNode1 = pVar->bParts->index;
        iNode2 = cuddT(pVar->bParts)->index;
        pNode1 = pNodes[iNode1];
        pNode2 = pNodes[iNode2];

        // get the quantification cube
        bCube = dd->vars[pVar->iNum];    Cudd_Ref( bCube );
        // add the variables that appear only in these partitions
        for ( v = 0; v < nVars; v++ )
            if ( pVars[v] && v != iVarBest && pVars[v]->bParts == pVars[iVarBest]->bParts )
            {
                // add this var
                bCube = Cudd_bddAnd( dd, bTemp = bCube, dd->vars[pVars[v]->iNum] );   Cudd_Ref( bCube );
                Cudd_RecursiveDeref( dd, bTemp );
                // clean this var
                Cudd_RecursiveDeref( dd, pVars[v]->bParts );
                ABC_FREE( pVars[v] );
            }
        // clean the best var
        Cudd_RecursiveDeref( dd, pVars[iVarBest]->bParts );
        ABC_FREE( pVars[iVarBest] );

        // combines two nodes
        pNode = Extra_CombineTwoNodes( dd, bCube, pNode1, pNode2 );
        Cudd_RecursiveDeref( dd, bCube );
    }
    else // if ( pVar->nParts > 2 )
    {
        // find two smallest BDDs that have this var
        Extra_FindBestPartitions( dd, pVar->bParts, nNodes, pNodes, &iNode1, &iNode2 );
        pNode1 = pNodes[iNode1];
        pNode2 = pNodes[iNode2];

        // it is not possible that a var appears only in these two
        // otherwise, it would have a different cost
        bParts = Cudd_bddAnd( dd, dd->vars[iNode1], dd->vars[iNode2] ); Cudd_Ref( bParts );
        for ( v = 0; v < nVars; v++ )
            if ( pVars[v] && pVars[v]->bParts == bParts )
                assert( 0 );
        Cudd_RecursiveDeref( dd, bParts );

        // combines two nodes
        pNode = Extra_CombineTwoNodes( dd, b1, pNode1, pNode2 );
    }

    // clean the old nodes
    pNodes[iNode1] = pNode;
    pNodes[iNode2] = NULL;
    
    // update the variables that appear in pNode[iNode2]
    for ( bSuppTemp = pNode2->pPart->bSupp; bSuppTemp != b1; bSuppTemp = cuddT(bSuppTemp) )
    {
        pVar = pVars[bSuppTemp->index];
        if ( pVar == NULL ) // this variable is not be quantified
            continue;
        // quantify this var
        assert( Cudd_bddLeq( dd, pVar->bParts, dd->vars[iNode2] ) );
        pVar->bParts = Cudd_bddExistAbstract( dd, bTemp = pVar->bParts, dd->vars[iNode2] ); Cudd_Ref( pVar->bParts );
        Cudd_RecursiveDeref( dd, bTemp );
        // add the new var
        pVar->bParts = Cudd_bddAnd( dd, bTemp = pVar->bParts, dd->vars[iNode1] ); Cudd_Ref( pVar->bParts );
        Cudd_RecursiveDeref( dd, bTemp );
        // update the score
        pVar->nParts = Extra_bddSuppSize( dd, pVar->bParts );
    }
    return 1;
}