src/base/abci/abcRestruct.c File Reference

#include "abc.h"
#include "dec.h"
#include "dsd.h"
#include "cut.h"
Include dependency graph for abcRestruct.c:

Go to the source code of this file.

Data Structures

struct  Abc_ManRst_t_

Defines

#define RST_RANDOM_UNSIGNED   ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand()))

Typedefs

typedef struct Abc_ManRst_t_ Abc_ManRst_t

Functions

static Dec_Graph_tAbc_NodeResubstitute (Abc_ManRst_t *p, Abc_Obj_t *pNode, Cut_Cut_t *pCutList)
static Dec_Graph_tAbc_NodeRestructure (Abc_ManRst_t *p, Abc_Obj_t *pNode, Cut_Cut_t *pCutList)
static Dec_Graph_tAbc_NodeRestructureCut (Abc_ManRst_t *p, Abc_Obj_t *pNode, Cut_Cut_t *pCut)
static Dec_Graph_tAbc_NodeEvaluateDsd (Abc_ManRst_t *pManRst, Dsd_Node_t *pNodeDsd, Abc_Obj_t *pRoot, int Required, int nNodesSaved, int *pnNodesAdded)
static Cut_Man_tAbc_NtkStartCutManForRestruct (Abc_Ntk_t *pNtk, int nCutMax, int fDag)
static Abc_ManRst_tAbc_NtkManRstStart (int nCutMax, bool fUpdateLevel, bool fUseZeros, bool fVerbose)
static void Abc_NtkManRstStop (Abc_ManRst_t *p)
static void Abc_NtkManRstPrintStats (Abc_ManRst_t *p)
int Abc_NtkRestructure (Abc_Ntk_t *pNtk, int nCutMax, bool fUpdateLevel, bool fUseZeros, bool fVerbose)
void Abc_RestructNodeDivisors (Abc_ManRst_t *p, Abc_Obj_t *pRoot, int nNodesSaved)
void Abc_NodeEdgeDsdPermute (Dec_Graph_t *pGraph, Abc_ManRst_t *pManRst, Vec_Int_t *vEdges, int fExor)
void Abc_NodeEdgeDsdPushOrdered (Dec_Graph_t *pGraph, Vec_Int_t *vEdges, int Edge)
Dec_Edge_t Abc_NodeEvaluateDsd_rec (Dec_Graph_t *pGraph, Abc_ManRst_t *pManRst, Dsd_Node_t *pNodeDsd, int Required, int nNodesSaved, int *pnNodesAdded)
int Abc_Abc_NodeResubCollectDivs (Abc_ManRst_t *p, Abc_Obj_t *pRoot, Cut_Cut_t *pCut)
int Abc_NodeResubMffc_rec (Abc_Obj_t *pNode)
int Abc_NodeResubMffc (Abc_ManRst_t *p, Vec_Ptr_t *vDecs, int nLeaves, Abc_Obj_t *pRoot)
void Abc_NodeMffcSimulate (Vec_Ptr_t *vDecs, int nLeaves, Vec_Int_t *vRands, Vec_Int_t *vSims)
int Abc_NodeCheckFull (Abc_ManRst_t *p, Dec_Graph_t *pGraph)
Dec_Graph_tAbc_NodeMffcConstants (Abc_ManRst_t *p, Vec_Int_t *vSims)
Dec_Graph_tAbc_NodeMffcSingleVar (Abc_ManRst_t *p, Vec_Int_t *vSims, int nNodes, Vec_Int_t *vOnes)
Dec_Graph_tAbc_NodeMffcSingleNode (Abc_ManRst_t *p, Vec_Int_t *vSims, int nNodes, Vec_Int_t *vOnes)
Dec_Graph_tAbc_NodeMffcDoubleNode (Abc_ManRst_t *p, Vec_Int_t *vSims, int nNodes, Vec_Int_t *vOnes)
Dec_Graph_tAbc_NodeResubEval (Abc_ManRst_t *p, Abc_Obj_t *pRoot, Cut_Cut_t *pCut)

Define Documentation

#define RST_RANDOM_UNSIGNED   ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand()))

CFile****************************************************************

FileName [abcRestruct.c]

SystemName [ABC: Logic synthesis and verification system.]

PackageName [Network and node package.]

Synopsis []

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

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

Revision [

Id
abcRestruct.c,v 1.00 2005/06/20 00:00:00 alanmi Exp

] DECLARATIONS ///

Definition at line 30 of file abcRestruct.c.


Typedef Documentation

typedef struct Abc_ManRst_t_ Abc_ManRst_t

Definition at line 32 of file abcRestruct.c.


Function Documentation

int Abc_Abc_NodeResubCollectDivs ( Abc_ManRst_t p,
Abc_Obj_t pRoot,
Cut_Cut_t pCut 
)

Function*************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 1095 of file abcRestruct.c.

01096 {
01097     Abc_Obj_t * pNode, * pFanout;
01098     int i, k;
01099     // collect the leaves of the cut
01100     Vec_PtrClear( p->vDecs );
01101     Abc_NtkIncrementTravId( pRoot->pNtk );
01102     for ( i = 0; i < (int)pCut->nLeaves; i++ )
01103     {
01104         pNode = Abc_NtkObj(pRoot->pNtk, pCut->pLeaves[i]);
01105         if ( pNode == NULL )  // the so-called "bad cut phenomenon" is due to removed nodes
01106             return 0;
01107         Vec_PtrPush( p->vDecs, pNode );
01108         Abc_NodeSetTravIdCurrent( pNode );        
01109     }
01110     // explore the fanouts
01111     Vec_PtrForEachEntry( p->vDecs, pNode, i )
01112     {
01113         // if the fanout has both fanins in the set, add it
01114         Abc_ObjForEachFanout( pNode, pFanout, k )
01115         {
01116             if ( Abc_NodeIsTravIdCurrent(pFanout) || Abc_ObjIsPo(pFanout) )
01117                 continue;
01118             if ( Abc_NodeIsTravIdCurrent(Abc_ObjFanin0(pFanout)) && Abc_NodeIsTravIdCurrent(Abc_ObjFanin1(pFanout)) )
01119             {
01120                 Vec_PtrPush( p->vDecs, pFanout );
01121                 Abc_NodeSetTravIdCurrent( pFanout );     
01122             }
01123         }
01124     }
01125     return 1;
01126 }

int Abc_NodeCheckFull ( Abc_ManRst_t p,
Dec_Graph_t pGraph 
)

Function*************************************************************

Synopsis [Full equality check.]

Description []

SideEffects []

SeeAlso []

Definition at line 1233 of file abcRestruct.c.

01234 {
01235     return 1;
01236 }

void Abc_NodeEdgeDsdPermute ( Dec_Graph_t pGraph,
Abc_ManRst_t pManRst,
Vec_Int_t vEdges,
int  fExor 
)

Function*************************************************************

Synopsis [Moves closer to the end the node that is best for sharing.]

Description [If the flag is set, tries to find an EXOR, otherwise, tries to find an OR.]

SideEffects []

SeeAlso []

Definition at line 482 of file abcRestruct.c.

00483 {
00484     Dec_Edge_t eNode1, eNode2, eNode3;
00485     Abc_Obj_t * pNode1, * pNode2, * pNode3, * pTemp;
00486     int LeftBound = 0, RightBound, i;
00487     // get the right bound
00488     RightBound = Vec_IntSize(vEdges) - 2;
00489     assert( LeftBound <= RightBound );
00490     if ( LeftBound == RightBound )
00491         return;
00492     // get the two last nodes
00493     eNode1 = Dec_IntToEdge( Vec_IntEntry(vEdges, RightBound + 1) );
00494     eNode2 = Dec_IntToEdge( Vec_IntEntry(vEdges, RightBound    ) );
00495     pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc;
00496     pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc;
00497     pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl );
00498     pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl );
00499     // quit if the last node does not exist
00500     if ( pNode1 == NULL )
00501         return;
00502     // find the first node that can be shared
00503     for ( i = RightBound; i >= LeftBound; i-- )
00504     {
00505         // get the third node
00506         eNode3 = Dec_IntToEdge( Vec_IntEntry(vEdges, i) );
00507         pNode3 = Dec_GraphNode( pGraph, eNode3.Node )->pFunc;
00508         pNode3 = !pNode3? NULL : Abc_ObjNotCond( pNode3, eNode3.fCompl );
00509         if ( pNode3 == NULL )
00510             continue;
00511         // check if the node exists
00512         if ( fExor )
00513         {
00514             if ( pNode1 && pNode3 )
00515             {
00516                 pTemp = Abc_AigXorLookup( pManRst->pNtk->pManFunc, pNode1, pNode3, NULL );
00517                 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00518                     continue;
00519 
00520                 if ( pNode3 == pNode2 )
00521                     return;
00522                 Vec_IntWriteEntry( vEdges, i,          Dec_EdgeToInt(eNode2) );
00523                 Vec_IntWriteEntry( vEdges, RightBound, Dec_EdgeToInt(eNode3) );
00524                 return;
00525             }
00526         }
00527         else
00528         {
00529             if ( pNode1 && pNode3 )
00530             {
00531                 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode3) );
00532                 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00533                     continue;
00534 
00535                 if ( eNode3.Node == eNode2.Node )
00536                     return;
00537                 Vec_IntWriteEntry( vEdges, i,          Dec_EdgeToInt(eNode2) );
00538                 Vec_IntWriteEntry( vEdges, RightBound, Dec_EdgeToInt(eNode3) );
00539                 return;
00540             }
00541         }
00542     }
00543 }

void Abc_NodeEdgeDsdPushOrdered ( Dec_Graph_t pGraph,
Vec_Int_t vEdges,
int  Edge 
)

Function*************************************************************

Synopsis [Adds the new edge in the given order.]

Description [Similar to Vec_IntPushOrder, except in decreasing order.]

SideEffects []

SeeAlso []

Definition at line 556 of file abcRestruct.c.

00557 {
00558     int i, NodeOld, NodeNew;
00559     vEdges->nSize++;
00560     for ( i = vEdges->nSize-2; i >= 0; i-- )
00561     {
00562         NodeOld = Dec_IntToEdge(vEdges->pArray[i]).Node;
00563         NodeNew = Dec_IntToEdge(Edge).Node;
00564         // use <= because we are trying to push the new (non-existent) nodes as far as possible
00565         if ( Dec_GraphNode(pGraph, NodeOld)->Level <= Dec_GraphNode(pGraph, NodeNew)->Level )
00566             vEdges->pArray[i+1] = vEdges->pArray[i];
00567         else
00568             break;
00569     }
00570     vEdges->pArray[i+1] = Edge;
00571 }

Dec_Graph_t * Abc_NodeEvaluateDsd ( Abc_ManRst_t pManRst,
Dsd_Node_t pNodeDsd,
Abc_Obj_t pRoot,
int  Required,
int  nNodesSaved,
int *  pnNodesAdded 
) [static]

Function*************************************************************

Synopsis [Evaluation one DSD.]

Description []

SideEffects []

SeeAlso []

Definition at line 902 of file abcRestruct.c.

00903 {
00904     Dec_Graph_t * pGraph;
00905     Dec_Edge_t gEdge;
00906     Abc_Obj_t * pLeaf;
00907     Dec_Node_t * pNode;
00908     int i;
00909 
00910     // create the graph and set the leaves
00911     pGraph = Dec_GraphCreate( Vec_PtrSize(pManRst->vLeaves) );
00912     Dec_GraphForEachLeaf( pGraph, pNode, i )
00913     {
00914         pLeaf = Vec_PtrEntry( pManRst->vLeaves, i );
00915         pNode->pFunc = pLeaf;
00916         pNode->Level = pLeaf->Level;
00917     }
00918 
00919     // create the decomposition structure from the DSD
00920     *pnNodesAdded = 0;
00921     gEdge = Abc_NodeEvaluateDsd_rec( pGraph, pManRst, pNodeDsd, Required, nNodesSaved, pnNodesAdded );
00922     if ( gEdge.Node > 1000 ) // infeasible
00923     {
00924         *pnNodesAdded = -1;
00925         Dec_GraphFree( pGraph );
00926         return NULL;
00927     }
00928 
00929     // quit if the root node is the same
00930     pLeaf = Dec_GraphNode( pGraph, gEdge.Node )->pFunc;
00931     if ( Abc_ObjRegular(pLeaf) == pRoot )
00932     {
00933         *pnNodesAdded = -1;
00934         Dec_GraphFree( pGraph );
00935         return NULL;
00936     }
00937 
00938     Dec_GraphSetRoot( pGraph, gEdge );
00939     return pGraph;
00940 }

Dec_Edge_t Abc_NodeEvaluateDsd_rec ( Dec_Graph_t pGraph,
Abc_ManRst_t pManRst,
Dsd_Node_t pNodeDsd,
int  Required,
int  nNodesSaved,
int *  pnNodesAdded 
)

Function*************************************************************

Synopsis [Evaluation one DSD.]

Description []

SideEffects []

SeeAlso []

Definition at line 584 of file abcRestruct.c.

00585 {
00586     Dec_Edge_t eNode1, eNode2, eNode3, eResult, eQuit = { 0, 2006 };
00587     Abc_Obj_t * pNode1, * pNode2, * pNode3, * pNode4, * pTemp;
00588     Dsd_Node_t * pChildDsd;
00589     Dsd_Type_t DecType;
00590     Vec_Int_t * vEdges;
00591     int Level1, Level2, Level3, Level4;
00592     int i, Index, fCompl, Type;
00593 
00594     // remove the complemented attribute
00595     fCompl   = Dsd_IsComplement( pNodeDsd );
00596     pNodeDsd = Dsd_Regular( pNodeDsd );
00597 
00598     // consider the trivial case
00599     DecType = Dsd_NodeReadType( pNodeDsd );
00600     if ( DecType == DSD_NODE_BUF )
00601     {
00602         Index = Dsd_NodeReadFunc(pNodeDsd)->index;
00603         assert( Index < Dec_GraphLeaveNum(pGraph) );
00604         eResult = Dec_EdgeCreate( Index, fCompl );
00605         return eResult;
00606     }
00607     assert( DecType == DSD_NODE_OR || DecType == DSD_NODE_EXOR || DecType == DSD_NODE_PRIME );
00608 
00609     // solve the problem for the children
00610     vEdges = Vec_IntAlloc( Dsd_NodeReadDecsNum(pNodeDsd) );
00611     Dsd_NodeForEachChild( pNodeDsd, i, pChildDsd )
00612     {
00613         eResult = Abc_NodeEvaluateDsd_rec( pGraph, pManRst, pChildDsd, Required, nNodesSaved, pnNodesAdded );
00614         if ( eResult.Node == eQuit.Node ) // infeasible
00615         {
00616             Vec_IntFree( vEdges );
00617             return eQuit;
00618         }
00619         // order the inputs only if this is OR or EXOR
00620         if ( DecType == DSD_NODE_PRIME )
00621             Vec_IntPush( vEdges, Dec_EdgeToInt(eResult) );
00622         else
00623             Abc_NodeEdgeDsdPushOrdered( pGraph, vEdges, Dec_EdgeToInt(eResult) );
00624     }
00625     // the edges are sorted by the level of their nodes in decreasing order
00626 
00627 
00628     // consider special cases
00629     if ( DecType == DSD_NODE_OR )
00630     {
00631         // try to balance the nodes by delay
00632         assert( Vec_IntSize(vEdges) > 1 );
00633         while ( Vec_IntSize(vEdges) > 1 )
00634         {
00635             // permute the last two entries
00636             if ( Vec_IntSize(vEdges) > 2 )
00637                 Abc_NodeEdgeDsdPermute( pGraph, pManRst, vEdges, 0 );
00638             // get the two last nodes
00639             eNode1 = Dec_IntToEdge( Vec_IntPop(vEdges) );
00640             eNode2 = Dec_IntToEdge( Vec_IntPop(vEdges) );
00641             pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc;
00642             pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc;
00643             pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl );
00644             pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl );
00645             // check if the new node exists
00646             pNode3 = NULL;
00647             if ( pNode1 && pNode2 )
00648             {
00649                 pNode3 = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) ); 
00650                 pNode3 = !pNode3? NULL : Abc_ObjNot(pNode3);
00651             }
00652             // create the new node
00653             eNode3 = Dec_GraphAddNodeOr( pGraph, eNode1, eNode2 );
00654             // set level
00655             Level1 = Dec_GraphNode( pGraph, eNode1.Node )->Level;
00656             Level2 = Dec_GraphNode( pGraph, eNode2.Node )->Level;
00657             Dec_GraphNode( pGraph, eNode3.Node )->Level = 1 + ABC_MAX(Level1, Level2);
00658             // get the new node if possible
00659             if ( pNode3 )
00660             {
00661                 Dec_GraphNode( pGraph, eNode3.Node )->pFunc = Abc_ObjNotCond(pNode3, eNode3.fCompl);
00662                 Level3 = Dec_GraphNode( pGraph, eNode3.Node )->Level;
00663                 assert( Required == ABC_INFINITY || Level3 == (int)Abc_ObjRegular(pNode3)->Level );
00664             }
00665             if ( !pNode3 || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pNode3)) )
00666             {
00667                 (*pnNodesAdded)++;
00668                 if ( *pnNodesAdded > nNodesSaved )
00669                 {
00670                     Vec_IntFree( vEdges );
00671                     return eQuit;
00672                 }
00673             }
00674             // add the resulting node to the form
00675             Abc_NodeEdgeDsdPushOrdered( pGraph, vEdges, Dec_EdgeToInt(eNode3) );
00676         }
00677         // get the last node
00678         eResult = Dec_IntToEdge( Vec_IntPop(vEdges) );
00679         Vec_IntFree( vEdges );
00680         // complement the graph if the node was complemented
00681         eResult.fCompl ^= fCompl;
00682         return eResult;
00683     }
00684     if ( DecType == DSD_NODE_EXOR )
00685     {
00686         // try to balance the nodes by delay
00687         assert( Vec_IntSize(vEdges) > 1 );
00688         while ( Vec_IntSize(vEdges) > 1 )
00689         {
00690             // permute the last two entries
00691             if ( Vec_IntSize(vEdges) > 2 )
00692                 Abc_NodeEdgeDsdPermute( pGraph, pManRst, vEdges, 1 );
00693             // get the two last nodes
00694             eNode1 = Dec_IntToEdge( Vec_IntPop(vEdges) );
00695             eNode2 = Dec_IntToEdge( Vec_IntPop(vEdges) );
00696             pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc;
00697             pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc;
00698             pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl );
00699             pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl );
00700             // check if the new node exists
00701             Type = 0;
00702             pNode3 = NULL;
00703             if ( pNode1 && pNode2 )
00704                 pNode3 = Abc_AigXorLookup( pManRst->pNtk->pManFunc, pNode1, pNode2, &Type ); 
00705             // create the new node
00706             eNode3 = Dec_GraphAddNodeXor( pGraph, eNode1, eNode2, Type ); // should have the same structure as in AIG
00707             // set level
00708             Level1 = Dec_GraphNode( pGraph, eNode1.Node )->Level;
00709             Level2 = Dec_GraphNode( pGraph, eNode2.Node )->Level;
00710             Dec_GraphNode( pGraph, eNode3.Node )->Level = 2 + ABC_MAX(Level1, Level2);
00711             // get the new node if possible
00712             if ( pNode3 )
00713             {
00714                 Dec_GraphNode( pGraph, eNode3.Node )->pFunc = Abc_ObjNotCond(pNode3, eNode3.fCompl);
00715                 Level3 = Dec_GraphNode( pGraph, eNode3.Node )->Level;
00716                 assert( Required == ABC_INFINITY || Level3 == (int)Abc_ObjRegular(pNode3)->Level );
00717             }
00718             if ( !pNode3 || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pNode3)) )
00719             {
00720                 (*pnNodesAdded)++;
00721                 if ( !pNode1 || !pNode2 )
00722                     (*pnNodesAdded) += 2;
00723                 else if ( Type == 0 )
00724                 {
00725                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, Abc_ObjNot(pNode2) );
00726                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00727                         (*pnNodesAdded)++;
00728                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), pNode2 );
00729                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00730                         (*pnNodesAdded)++;
00731                 }
00732                 else
00733                 {
00734                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) );
00735                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00736                         (*pnNodesAdded)++;
00737                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, pNode2 );
00738                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00739                         (*pnNodesAdded)++;
00740                 }
00741                 if ( *pnNodesAdded > nNodesSaved )
00742                 {
00743                     Vec_IntFree( vEdges );
00744                     return eQuit;
00745                 }
00746             }
00747             // add the resulting node to the form
00748             Abc_NodeEdgeDsdPushOrdered( pGraph, vEdges, Dec_EdgeToInt(eNode3) );
00749         }
00750         // get the last node
00751         eResult = Dec_IntToEdge( Vec_IntPop(vEdges) );
00752         Vec_IntFree( vEdges );
00753         // complement the graph if the node is complemented
00754         eResult.fCompl ^= fCompl;
00755         return eResult;
00756     }
00757     if ( DecType == DSD_NODE_PRIME )
00758     {
00759         DdNode * bLocal, * bVar, * bCofT, * bCofE;
00760         bLocal = Dsd_TreeGetPrimeFunction( pManRst->dd, pNodeDsd );  Cudd_Ref( bLocal );
00761 //Extra_bddPrint( pManRst->dd, bLocal );
00762 
00763         bVar  = pManRst->dd->vars[0];
00764         bCofE = Cudd_Cofactor( pManRst->dd, bLocal, Cudd_Not(bVar) );  Cudd_Ref( bCofE );
00765         bCofT = Cudd_Cofactor( pManRst->dd, bLocal, bVar );            Cudd_Ref( bCofT );
00766         if ( !Extra_bddIsVar(bCofE) || !Extra_bddIsVar(bCofT) )
00767         {
00768             Cudd_RecursiveDeref( pManRst->dd, bCofE );
00769             Cudd_RecursiveDeref( pManRst->dd, bCofT );
00770             bVar  = pManRst->dd->vars[1];
00771             bCofE = Cudd_Cofactor( pManRst->dd, bLocal, Cudd_Not(bVar) );  Cudd_Ref( bCofE );
00772             bCofT = Cudd_Cofactor( pManRst->dd, bLocal, bVar );            Cudd_Ref( bCofT );
00773             if ( !Extra_bddIsVar(bCofE) || !Extra_bddIsVar(bCofT) )
00774             {
00775                 Cudd_RecursiveDeref( pManRst->dd, bCofE );
00776                 Cudd_RecursiveDeref( pManRst->dd, bCofT );
00777                 bVar  = pManRst->dd->vars[2];
00778                 bCofE = Cudd_Cofactor( pManRst->dd, bLocal, Cudd_Not(bVar) );  Cudd_Ref( bCofE );
00779                 bCofT = Cudd_Cofactor( pManRst->dd, bLocal, bVar );            Cudd_Ref( bCofT );
00780                 if ( !Extra_bddIsVar(bCofE) || !Extra_bddIsVar(bCofT) )
00781                 {
00782                     Cudd_RecursiveDeref( pManRst->dd, bCofE );
00783                     Cudd_RecursiveDeref( pManRst->dd, bCofT );
00784                     Cudd_RecursiveDeref( pManRst->dd, bLocal );
00785                     Vec_IntFree( vEdges );
00786                     return eQuit;
00787                 }
00788             }
00789         }
00790         Cudd_RecursiveDeref( pManRst->dd, bLocal );
00791         // we found the control variable (bVar) and the var-cofactors (bCofT, bCofE)
00792 
00793         // find the graph nodes
00794         eNode1 = Dec_IntToEdge( Vec_IntEntry(vEdges, bVar->index) );
00795         eNode2 = Dec_IntToEdge( Vec_IntEntry(vEdges, Cudd_Regular(bCofT)->index) );
00796         eNode3 = Dec_IntToEdge( Vec_IntEntry(vEdges, Cudd_Regular(bCofE)->index) );
00797         // add the complements to the graph nodes
00798         eNode2.fCompl ^= Cudd_IsComplement(bCofT);
00799         eNode3.fCompl ^= Cudd_IsComplement(bCofE);
00800 
00801         // because the cofactors are vars, we can just as well deref them here
00802         Cudd_RecursiveDeref( pManRst->dd, bCofE );
00803         Cudd_RecursiveDeref( pManRst->dd, bCofT );
00804 
00805         // find the ABC nodes
00806         pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc;
00807         pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc;
00808         pNode3 = Dec_GraphNode( pGraph, eNode3.Node )->pFunc;
00809         pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl );
00810         pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl );
00811         pNode3 = !pNode3? NULL : Abc_ObjNotCond( pNode3, eNode3.fCompl );
00812 
00813         // check if the new node exists
00814         Type = 0;
00815         pNode4 = NULL;
00816         if ( pNode1 && pNode2 && pNode3 )
00817             pNode4 = Abc_AigMuxLookup( pManRst->pNtk->pManFunc, pNode1, pNode2, pNode3, &Type ); 
00818 
00819         // create the new node
00820         eResult = Dec_GraphAddNodeMux( pGraph, eNode1, eNode2, eNode3, Type ); // should have the same structure as AIG
00821 
00822         // set level
00823         Level1 = Dec_GraphNode( pGraph, eNode1.Node )->Level;
00824         Level2 = Dec_GraphNode( pGraph, eNode2.Node )->Level;
00825         Level3 = Dec_GraphNode( pGraph, eNode3.Node )->Level;
00826         Dec_GraphNode( pGraph, eResult.Node )->Level = 2 + ABC_MAX( ABC_MAX(Level1, Level2), Level3 );
00827         // get the new node if possible
00828         if ( pNode4 )
00829         {
00830             Dec_GraphNode( pGraph, eResult.Node )->pFunc = Abc_ObjNotCond(pNode4, eResult.fCompl);
00831             Level4 = Dec_GraphNode( pGraph, eResult.Node )->Level;
00832             assert( Required == ABC_INFINITY || Level4 == (int)Abc_ObjRegular(pNode4)->Level );
00833         }
00834         if ( !pNode4 || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pNode4)) )
00835         {
00836             (*pnNodesAdded)++;
00837             if ( Type == 0 ) 
00838             {
00839                 if ( !pNode1 || !pNode2 )
00840                     (*pnNodesAdded)++;
00841                 else
00842                 {
00843                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, pNode2 );
00844                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00845                         (*pnNodesAdded)++;
00846                 }
00847                 if ( !pNode1 || !pNode3 )
00848                     (*pnNodesAdded)++;
00849                 else
00850                 {
00851                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), pNode3 );
00852                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00853                         (*pnNodesAdded)++;
00854                 }
00855             }
00856             else
00857             {
00858                 if ( !pNode1 || !pNode2 )
00859                     (*pnNodesAdded)++;
00860                 else
00861                 {
00862                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, Abc_ObjNot(pNode2) );
00863                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00864                         (*pnNodesAdded)++;
00865                 }
00866                 if ( !pNode1 || !pNode3 )
00867                     (*pnNodesAdded)++;
00868                 else
00869                 {
00870                     pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode3) );
00871                     if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00872                         (*pnNodesAdded)++;
00873                 }
00874             }
00875             if ( *pnNodesAdded > nNodesSaved )
00876             {
00877                 Vec_IntFree( vEdges );
00878                 return eQuit;
00879             }
00880         }
00881 
00882         Vec_IntFree( vEdges );
00883         // complement the graph if the node was complemented
00884         eResult.fCompl ^= fCompl;
00885         return eResult;
00886     }
00887     Vec_IntFree( vEdges );
00888     return eQuit;
00889 }

Dec_Graph_t* Abc_NodeMffcConstants ( Abc_ManRst_t p,
Vec_Int_t vSims 
)

Function*************************************************************

Synopsis [Detect contants.]

Description []

SideEffects []

SeeAlso []

Definition at line 1248 of file abcRestruct.c.

01249 {
01250     Dec_Graph_t * pGraph;
01251     unsigned uRoot;
01252     // get the root node
01253     uRoot = (unsigned)Vec_IntEntryLast( vSims );
01254     // get the graph if the node looks constant
01255     if ( uRoot == 0 )
01256         pGraph = Dec_GraphCreateConst0();
01257     else if ( uRoot == ~(unsigned)0 )
01258         pGraph = Dec_GraphCreateConst1();
01259     // check the graph
01260     if ( Abc_NodeCheckFull( p, pGraph ) )
01261         return pGraph;
01262     Dec_GraphFree( pGraph );
01263     return NULL;
01264 }

Dec_Graph_t* Abc_NodeMffcDoubleNode ( Abc_ManRst_t p,
Vec_Int_t vSims,
int  nNodes,
Vec_Int_t vOnes 
)

Function*************************************************************

Synopsis [Detect single non-overlaps.]

Description []

SideEffects []

SeeAlso []

Definition at line 1356 of file abcRestruct.c.

01357 {
01358 //    Dec_Graph_t * pGraph;
01359 //    unsigned uRoot, uNode;
01360 //    int i;
01361 
01362 
01363     return NULL;
01364 }

void Abc_NodeMffcSimulate ( Vec_Ptr_t vDecs,
int  nLeaves,
Vec_Int_t vRands,
Vec_Int_t vSims 
)

Function*************************************************************

Synopsis [Performs simulation.]

Description []

SideEffects []

SeeAlso []

Definition at line 1198 of file abcRestruct.c.

01199 {
01200     Abc_Obj_t * pObj;
01201     unsigned uData0, uData1, uData;
01202     int i;
01203     // initialize random simulation data
01204     Vec_IntClear( vSims );
01205     Vec_PtrForEachEntryStop( vDecs, pObj, i, nLeaves )
01206     {
01207         uData = (unsigned)Vec_IntEntry( vRands, i );
01208         pObj->pData = (void *)uData;
01209         Vec_IntPush( vSims, uData );
01210     }
01211     // simulate
01212     Vec_PtrForEachEntryStart( vDecs, pObj, i, nLeaves )
01213     {
01214         uData0 = (unsigned)Abc_ObjFanin0(pObj)->pData;
01215         uData1 = (unsigned)Abc_ObjFanin1(pObj)->pData;
01216         uData = (Abc_ObjFaninC0(pObj)? ~uData0 : uData0) & (Abc_ObjFaninC1(pObj)? ~uData1 : uData1);
01217         pObj->pData = (void *)uData;
01218         Vec_IntPush( vSims, uData );
01219     }
01220 }

Dec_Graph_t* Abc_NodeMffcSingleNode ( Abc_ManRst_t p,
Vec_Int_t vSims,
int  nNodes,
Vec_Int_t vOnes 
)

Function*************************************************************

Synopsis [Detect single non-overlaps.]

Description []

SideEffects []

SeeAlso []

Definition at line 1320 of file abcRestruct.c.

01321 {
01322     Dec_Graph_t * pGraph;
01323     Dec_Edge_t eNode0, eNode1, eRoot;
01324     unsigned uRoot;
01325     int i, k;
01326     uRoot = (unsigned)Vec_IntEntryLast( vSims );
01327     for ( i = 0; i < vOnes->nSize; i++ )
01328         for ( k = i+1; k < vOnes->nSize; k++ )
01329             if ( ~uRoot == ((unsigned)vOnes->pArray[i] | (unsigned)vOnes->pArray[k]) )
01330             {
01331                 eNode0 = Dec_IntToEdge( vOnes->pArray[i] ^ 1 );
01332                 eNode1 = Dec_IntToEdge( vOnes->pArray[k] ^ 1 );
01333                 pGraph = Dec_GraphCreate( 2 );
01334                 Dec_GraphNode( pGraph, 0 )->pFunc = Vec_PtrEntry( p->vDecs, eNode0.Node );
01335                 Dec_GraphNode( pGraph, 1 )->pFunc = Vec_PtrEntry( p->vDecs, eNode1.Node );
01336                 eRoot = Dec_GraphAddNodeAnd( pGraph, eNode0, eNode1 );
01337                 Dec_GraphSetRoot( pGraph, eRoot );
01338                 if ( Abc_NodeCheckFull( p, pGraph ) )
01339                     return pGraph;
01340                 Dec_GraphFree( pGraph );
01341             }
01342     return NULL;
01343 }

Dec_Graph_t* Abc_NodeMffcSingleVar ( Abc_ManRst_t p,
Vec_Int_t vSims,
int  nNodes,
Vec_Int_t vOnes 
)

Function*************************************************************

Synopsis [Detect single non-overlaps.]

Description []

SideEffects []

SeeAlso []

Definition at line 1277 of file abcRestruct.c.

01278 {
01279     Dec_Graph_t * pGraph;
01280     unsigned uRoot, uNode;
01281     int i;
01282 
01283     Vec_IntClear( vOnes );
01284     Vec_IntClear( p->vBinate );
01285     uRoot = (unsigned)Vec_IntEntryLast( vSims );
01286     for ( i = 0; i < nNodes; i++ )
01287     {
01288         uNode = (unsigned)Vec_IntEntry( vSims, i );
01289         if ( uRoot == uNode || uRoot == ~uNode )
01290         {
01291             pGraph = Dec_GraphCreate( 1 );
01292             Dec_GraphNode( pGraph, 0 )->pFunc = Vec_PtrEntry( p->vDecs, i );
01293             Dec_GraphSetRoot( pGraph, Dec_IntToEdge( (int)(uRoot == ~uNode) ) );
01294             // check the graph
01295             if ( Abc_NodeCheckFull( p, pGraph ) )
01296                 return pGraph;
01297             Dec_GraphFree( pGraph );
01298         }
01299         if ( (uRoot & uNode) == 0 )
01300             Vec_IntPush( vOnes, i << 1 );
01301         else if ( (uRoot & ~uNode) == 0 )
01302             Vec_IntPush( vOnes, (i << 1) + 1 );
01303         else
01304             Vec_IntPush( p->vBinate, i );
01305     }    
01306     return NULL;
01307 }

Dec_Graph_t * Abc_NodeRestructure ( Abc_ManRst_t p,
Abc_Obj_t pNode,
Cut_Cut_t pCutList 
) [static]

Function*************************************************************

Synopsis [Starts the cut manager for rewriting.]

Description []

SideEffects []

SeeAlso []

Definition at line 278 of file abcRestruct.c.

00279 {
00280     Dec_Graph_t * pGraph;
00281     Cut_Cut_t * pCut;
00282 //    int nCuts;
00283     p->nNodesConsidered++;
00284 /*
00285     // count the number of cuts with four inputs or more
00286     nCuts = 0;
00287     for ( pCut = pCutList; pCut; pCut = pCut->pNext )
00288         nCuts += (int)(pCut->nLeaves > 3);
00289     printf( "-----------------------------------\n" );
00290     printf( "Node %6d : Factor-cuts = %5d.\n", pNode->Id, nCuts );
00291 */
00292     // go through the interesting cuts
00293     for ( pCut = pCutList; pCut; pCut = pCut->pNext )
00294     {
00295         if ( pCut->nLeaves < 4 )
00296             continue;
00297         if ( pGraph = Abc_NodeRestructureCut( p, pNode, pCut ) )
00298             return pGraph;
00299     }
00300     return NULL;
00301 }

Dec_Graph_t * Abc_NodeRestructureCut ( Abc_ManRst_t p,
Abc_Obj_t pRoot,
Cut_Cut_t pCut 
) [static]

Function*************************************************************

Synopsis [Starts the cut manager for rewriting.]

Description []

SideEffects []

SeeAlso []

Definition at line 314 of file abcRestruct.c.

00315 {
00316     Dec_Graph_t * pGraph;
00317     Dsd_Node_t * pNodeDsd;
00318     Abc_Obj_t * pLeaf;
00319     DdNode * bFunc;
00320     int nNodesSaved, nNodesAdded;
00321     int Required, nMaxSize, clk, i;
00322     int fVeryVerbose = 0;
00323 
00324     p->nCutsConsidered++;
00325 
00326     // get the required time for the node
00327     Required = p->fUpdateLevel? Abc_ObjRequiredLevel(pRoot) : ABC_INFINITY;
00328 
00329     // collect the leaves of the cut
00330     Vec_PtrClear( p->vLeaves );
00331     for ( i = 0; i < (int)pCut->nLeaves; i++ )
00332     {
00333         pLeaf = Abc_NtkObj(pRoot->pNtk, pCut->pLeaves[i]);
00334         if ( pLeaf == NULL )  // the so-called "bad cut phenomenon" is due to removed nodes
00335             return NULL;
00336         Vec_PtrPush( p->vLeaves, pLeaf );
00337     }
00338 
00339     if ( pRoot->Id == 29 )
00340     {
00341         int x = 0;
00342     }
00343 
00344 clk = clock();
00345     // collect the internal nodes of the cut
00346 //    Abc_NodeConeCollect( &pRoot, 1, p->vLeaves, p->vVisited, 0 );
00347     // derive the BDD of the cut
00348     bFunc = Abc_NodeConeBdd( p->dd, p->dd->vars, pRoot, p->vLeaves, p->vVisited );  Cudd_Ref( bFunc );
00349 p->timeBdd += clock() - clk;
00350 
00351     // consider the special case, when the function is a constant
00352     if ( Cudd_IsConstant(bFunc) )
00353     {
00354         p->nLastGain = Abc_NodeMffcSize( pRoot );
00355         p->nNodesGained += p->nLastGain;
00356         p->nNodesRestructured++;
00357         Cudd_RecursiveDeref( p->dd, bFunc );
00358         if ( Cudd_IsComplement(bFunc) )
00359             return Dec_GraphCreateConst0();
00360         return Dec_GraphCreateConst1();
00361     }
00362 
00363 clk = clock();
00364     // try disjoint support decomposition
00365     pNodeDsd = Dsd_DecomposeOne( p->pManDsd, bFunc );
00366 p->timeDsd += clock() - clk;
00367 
00368     // skip nodes with non-decomposable blocks
00369     Dsd_TreeNodeGetInfoOne( pNodeDsd, NULL, &nMaxSize );
00370     if ( nMaxSize > 3 )
00371     {
00372         Cudd_RecursiveDeref( p->dd, bFunc );
00373         return NULL;
00374     }
00375 
00376 
00377 /*
00378     // skip nodes that cannot be improved
00379     if ( Vec_PtrSize(p->vVisited) <= Dsd_TreeGetAigCost(pNodeDsd) )
00380     {
00381         Cudd_RecursiveDeref( p->dd, bFunc );
00382         return NULL;
00383     }
00384 */
00385 
00386     p->nCutsExplored++;
00387 
00388     // mark the fanin boundary 
00389     // (can mark only essential fanins, belonging to bNodeFunc!)
00390     Vec_PtrForEachEntry( p->vLeaves, pLeaf, i )
00391         pLeaf->vFanouts.nSize++;
00392     // label MFFC with current traversal ID
00393     Abc_NtkIncrementTravId( pRoot->pNtk );
00394     nNodesSaved = Abc_NodeMffcLabelAig( pRoot );
00395     // unmark the fanin boundary and set the fanins as leaves in the form
00396     Vec_PtrForEachEntry( p->vLeaves, pLeaf, i )
00397         pLeaf->vFanouts.nSize--;
00398 /*
00399     if ( nNodesSaved < 3 )
00400     {
00401         Cudd_RecursiveDeref( p->dd, bFunc );
00402         return NULL;
00403     }
00404 */
00405 
00406 /* 
00407     printf( "%5d : Cut-size = %d.  Old AIG = %2d.  New AIG = %2d.  Old MFFC = %2d.\n",
00408         pRoot->Id, pCut->nLeaves, Vec_PtrSize(p->vVisited), Dsd_TreeGetAigCost(pNodeDsd), 
00409         nNodesSaved );
00410     Dsd_NodePrint( stdout, pNodeDsd );
00411 
00412     Abc_RestructNodeDivisors( p, pRoot );
00413 
00414     if ( pRoot->Id == 433 )
00415     {
00416         int x = 0;
00417     }
00418 */
00419 //    Abc_RestructNodeDivisors( p, pRoot, nNodesSaved );
00420 
00421 
00422     // detect how many new nodes will be added (while taking into account reused nodes)
00423 clk = clock();
00424     if ( nMaxSize > 3 )
00425         pGraph = NULL;
00426     else
00427         pGraph = Abc_NodeEvaluateDsd( p, pNodeDsd, pRoot, Required, nNodesSaved, &nNodesAdded );
00428 //    pGraph = NULL;
00429 p->timeEval += clock() - clk;
00430 
00431     // quit if there is no improvement
00432     if ( pGraph == NULL || nNodesAdded == -1 || nNodesAdded == nNodesSaved && !p->fUseZeros )
00433     {
00434         Cudd_RecursiveDeref( p->dd, bFunc );
00435         if ( pGraph ) Dec_GraphFree( pGraph );
00436         return NULL;
00437     }
00438 
00439 /*
00440     // print stats
00441     printf( "%5d : Cut-size = %d.  Old AIG = %2d.  New AIG = %2d.  Old MFFC = %2d.  New MFFC = %2d. Gain = %d.\n",
00442         pRoot->Id, pCut->nLeaves, Vec_PtrSize(p->vVisited), Dsd_TreeGetAigCost(pNodeDsd), 
00443         nNodesSaved, nNodesAdded, (nNodesAdded == -1)? 0 : nNodesSaved-nNodesAdded );
00444 //    Dsd_NodePrint( stdout, pNodeDsd );
00445 //    Dec_GraphPrint( stdout, pGraph, NULL, NULL );
00446 */
00447 
00448     // compute the total gain in the number of nodes
00449     p->nLastGain = nNodesSaved - nNodesAdded;
00450     p->nNodesGained += p->nLastGain;
00451     p->nNodesRestructured++;
00452 
00453     // report the progress
00454     if ( fVeryVerbose )
00455     {
00456         printf( "Node %6s : ",  Abc_ObjName(pRoot) );
00457         printf( "Cone = %2d. ", p->vLeaves->nSize );
00458         printf( "BDD = %2d. ",  Cudd_DagSize(bFunc) );
00459         printf( "FF = %2d. ",   1 + Dec_GraphNodeNum(pGraph) );
00460         printf( "MFFC = %2d. ", nNodesSaved );
00461         printf( "Add = %2d. ",  nNodesAdded );
00462         printf( "GAIN = %2d. ", p->nLastGain );
00463         printf( "\n" );
00464     }
00465     Cudd_RecursiveDeref( p->dd, bFunc );
00466     return pGraph;
00467 }

Dec_Graph_t* Abc_NodeResubEval ( Abc_ManRst_t p,
Abc_Obj_t pRoot,
Cut_Cut_t pCut 
)

Function*************************************************************

Synopsis [Evaluates resubstution of one cut.]

Description [Returns the graph to add if any.]

SideEffects []

SeeAlso []

Definition at line 1377 of file abcRestruct.c.

01378 {
01379     Dec_Graph_t * pGraph;
01380     int nNodesSaved;
01381 
01382     // collect the nodes in the cut
01383     if ( !Abc_Abc_NodeResubCollectDivs( p, pRoot, pCut ) )
01384         return NULL;
01385 
01386     // label MFFC and count its size
01387     nNodesSaved = Abc_NodeResubMffc( p, p->vDecs, pCut->nLeaves, pRoot );
01388     assert( nNodesSaved > 0 );
01389 
01390     // simulate MFFC
01391     Abc_NodeMffcSimulate( p->vDecs, pCut->nLeaves, p->vRands, p->vSims );
01392 
01393     // check for constant output
01394     pGraph = Abc_NodeMffcConstants( p, p->vSims );
01395     if ( pGraph )
01396     {
01397         p->nNodesGained += nNodesSaved;
01398         p->nNodesRestructured++;
01399         return pGraph;
01400     }
01401 
01402     // check for one literal (fill up the ones array)
01403     pGraph = Abc_NodeMffcSingleVar( p, p->vSims, Vec_IntSize(p->vSims) - nNodesSaved, p->vOnes );
01404     if ( pGraph )
01405     {
01406         p->nNodesGained += nNodesSaved;
01407         p->nNodesRestructured++;
01408         return pGraph;
01409     }
01410     if ( nNodesSaved == 1 )
01411         return NULL;
01412 
01413     // look for one node
01414     pGraph = Abc_NodeMffcSingleNode( p, p->vSims, Vec_IntSize(p->vSims) - nNodesSaved, p->vOnes );
01415     if ( pGraph )
01416     {
01417         p->nNodesGained += nNodesSaved - 1;
01418         p->nNodesRestructured++;
01419         return pGraph;
01420     }
01421     if ( nNodesSaved == 2 )
01422         return NULL;
01423 
01424     // look for two nodes
01425     pGraph = Abc_NodeMffcDoubleNode( p, p->vSims, Vec_IntSize(p->vSims) - nNodesSaved, p->vOnes );
01426     if ( pGraph )
01427     {
01428         p->nNodesGained += nNodesSaved - 2;
01429         p->nNodesRestructured++;
01430         return pGraph;
01431     }
01432     if ( nNodesSaved == 3 )
01433         return NULL;
01434 /*
01435     // look for MUX/EXOR
01436     pGraph = Abc_NodeMffcMuxNode( p, p->vSims, Vec_IntSize(p->vSims) - nNodesSaved );
01437     if ( pGraph )
01438     {
01439         p->nNodesGained += nNodesSaved - 1;
01440         p->nNodesRestructured++;
01441         return pGraph;
01442     }
01443 */
01444     return NULL;
01445 }

int Abc_NodeResubMffc ( Abc_ManRst_t p,
Vec_Ptr_t vDecs,
int  nLeaves,
Abc_Obj_t pRoot 
)

Function*************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 1159 of file abcRestruct.c.

01160 {
01161     Abc_Obj_t * pObj;
01162     int Counter, i, k;
01163     // increment the traversal ID for the leaves
01164     Abc_NtkIncrementTravId( pRoot->pNtk );
01165     // label the leaves
01166     Vec_PtrForEachEntryStop( vDecs, pObj, i, nLeaves )
01167         Abc_NodeSetTravIdCurrent( pObj ); 
01168     // make sure the node is in the cone and is no one of the leaves
01169     assert( Abc_NodeIsTravIdPrevious(pRoot) );
01170     Counter = Abc_NodeResubMffc_rec( pRoot );
01171     // move the labeled nodes to the end 
01172     Vec_PtrClear( p->vTemp );
01173     k = 0;
01174     Vec_PtrForEachEntryStart( vDecs, pObj, i, nLeaves )
01175         if ( Abc_NodeIsTravIdCurrent(pObj) )
01176             Vec_PtrPush( p->vTemp, pObj );
01177         else
01178             Vec_PtrWriteEntry( vDecs, k++, pObj );
01179     // add the labeled nodes
01180     Vec_PtrForEachEntry( p->vTemp, pObj, i )
01181         Vec_PtrWriteEntry( vDecs, k++, pObj );
01182     assert( k == Vec_PtrSize(p->vDecs) );
01183     assert( pRoot == Vec_PtrEntryLast(p->vDecs) );
01184     return Counter;
01185 }

int Abc_NodeResubMffc_rec ( Abc_Obj_t pNode  ) 

Function*************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 1139 of file abcRestruct.c.

01140 {
01141     if ( Abc_NodeIsTravIdCurrent(pNode) )
01142         return 0;
01143     Abc_NodeSetTravIdCurrent( pNode ); 
01144     return 1 + Abc_NodeResubMffc_rec( Abc_ObjFanin0(pNode) ) +
01145         Abc_NodeResubMffc_rec( Abc_ObjFanin1(pNode) );
01146 }

Dec_Graph_t * Abc_NodeResubstitute ( Abc_ManRst_t p,
Abc_Obj_t pNode,
Cut_Cut_t pCutList 
) [static]

Function*************************************************************

Synopsis [Performs resubstution.]

Description []

SideEffects []

SeeAlso []

Definition at line 1458 of file abcRestruct.c.

01459 {
01460     Dec_Graph_t * pGraph, * pGraphBest = NULL;
01461     Cut_Cut_t * pCut;
01462     int nCuts;
01463     p->nNodesConsidered++;
01464 
01465     // count the number of cuts with four inputs or more
01466     nCuts = 0;
01467     for ( pCut = pCutList; pCut; pCut = pCut->pNext )
01468         nCuts += (int)(pCut->nLeaves > 3);
01469     printf( "-----------------------------------\n" );
01470     printf( "Node %6d : Factor-cuts = %5d.\n", pNode->Id, nCuts );
01471 
01472     // go through the interesting cuts
01473     for ( pCut = pCutList; pCut; pCut = pCut->pNext )
01474     {
01475         if ( pCut->nLeaves < 4 )
01476             continue;
01477         pGraph = Abc_NodeResubEval( p, pNode, pCut );
01478         if ( pGraph == NULL )
01479             continue;
01480         if ( !pGraphBest || Dec_GraphNodeNum(pGraph) < Dec_GraphNodeNum(pGraphBest) )
01481         {
01482             if ( pGraphBest ) 
01483                 Dec_GraphFree(pGraphBest);
01484             pGraphBest = pGraph;
01485         }
01486         else
01487             Dec_GraphFree(pGraph);
01488     }
01489     return pGraphBest;
01490 }

void Abc_NtkManRstPrintStats ( Abc_ManRst_t p  )  [static]

Function*************************************************************

Synopsis [Stops the resynthesis manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 1066 of file abcRestruct.c.

01067 {
01068     printf( "Refactoring statistics:\n" );
01069     printf( "Nodes considered   = %8d.\n", p->nNodesConsidered   );
01070     printf( "Cuts considered    = %8d.\n", p->nCutsConsidered    );
01071     printf( "Cuts explored      = %8d.\n", p->nCutsExplored      );
01072     printf( "Nodes restructured = %8d.\n", p->nNodesRestructured );
01073     printf( "Calculated gain    = %8d.\n", p->nNodesGained       );
01074     PRT( "Cuts       ", p->timeCut );
01075     PRT( "Resynthesis", p->timeRes );
01076     PRT( "    BDD    ", p->timeBdd );
01077     PRT( "    DSD    ", p->timeDsd );
01078     PRT( "    Eval   ", p->timeEval );
01079     PRT( "AIG update ", p->timeNtk );
01080     PRT( "TOTAL      ", p->timeTotal );
01081 }

Abc_ManRst_t * Abc_NtkManRstStart ( int  nCutMax,
bool  fUpdateLevel,
bool  fUseZeros,
bool  fVerbose 
) [static]

Function*************************************************************

Synopsis [Starts the resynthesis manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 994 of file abcRestruct.c.

00995 {
00996     Abc_ManRst_t * p;
00997     p = ALLOC( Abc_ManRst_t, 1 );
00998     memset( p, 0, sizeof(Abc_ManRst_t) );
00999     // set the parameters
01000     p->nCutMax      = nCutMax;
01001     p->fUpdateLevel = fUpdateLevel;
01002     p->fUseZeros    = fUseZeros;
01003     p->fVerbose     = fVerbose;
01004     // start the BDD manager
01005     p->dd = Cudd_Init( p->nCutMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
01006     Cudd_zddVarsFromBddVars( p->dd, 2 );
01007     // start the DSD manager
01008     p->pManDsd = Dsd_ManagerStart( p->dd, p->dd->size, 0 );
01009     // other temp datastructures
01010     p->vVisited     = Vec_PtrAlloc( 100 );
01011     p->vLeaves      = Vec_PtrAlloc( 100 );
01012     p->vDecs        = Vec_PtrAlloc( 100 );
01013     p->vTemp        = Vec_PtrAlloc( 100 );
01014     p->vSims        = Vec_IntAlloc( 100 );
01015     p->vOnes        = Vec_IntAlloc( 100 );
01016     p->vBinate      = Vec_IntAlloc( 100 );
01017     p->vTwos        = Vec_IntAlloc( 100 );
01018     p->vRands       = Vec_IntAlloc( 20 );
01019     
01020     {
01021         int i;
01022         for ( i = 0; i < 20; i++ )
01023             Vec_IntPush( p->vRands, (int)RST_RANDOM_UNSIGNED );
01024     }
01025     return p;
01026 }

void Abc_NtkManRstStop ( Abc_ManRst_t p  )  [static]

Function*************************************************************

Synopsis [Stops the resynthesis manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 1039 of file abcRestruct.c.

01040 {
01041     Dsd_ManagerStop( p->pManDsd );
01042     Extra_StopManager( p->dd );
01043     Vec_PtrFree( p->vDecs );
01044     Vec_PtrFree( p->vLeaves );
01045     Vec_PtrFree( p->vVisited );
01046     Vec_PtrFree( p->vTemp );
01047     Vec_IntFree( p->vSims );
01048     Vec_IntFree( p->vOnes );
01049     Vec_IntFree( p->vBinate );
01050     Vec_IntFree( p->vTwos );
01051     Vec_IntFree( p->vRands );
01052     free( p );
01053 }

int Abc_NtkRestructure ( Abc_Ntk_t pNtk,
int  nCutMax,
bool  fUpdateLevel,
bool  fUseZeros,
bool  fVerbose 
)

FUNCTION DEFINITIONS ///Function*************************************************************

Synopsis [Implements AIG restructuring.]

Description []

SideEffects []

SeeAlso []

Definition at line 97 of file abcRestruct.c.

00098 {
00099     ProgressBar * pProgress;
00100     Abc_ManRst_t * pManRst;
00101     Cut_Man_t * pManCut;
00102     Cut_Cut_t * pCutList;
00103     Dec_Graph_t * pGraph;
00104     Abc_Obj_t * pNode;
00105     int clk, clkStart = clock();
00106     int fMulti = 1;
00107     int fResub = 0;
00108     int i, nNodes;
00109 
00110     assert( Abc_NtkIsStrash(pNtk) );
00111     // cleanup the AIG
00112     Abc_AigCleanup(pNtk->pManFunc);
00113     Abc_NtkCleanCopy(pNtk);
00114 
00115     // compute the reverse levels if level update is requested
00116     if ( fUpdateLevel )
00117         Abc_NtkStartReverseLevels( pNtk, 0 );
00118 
00119     // start the restructuring manager
00120     pManRst = Abc_NtkManRstStart( nCutMax, fUpdateLevel, fUseZeros, fVerbose );
00121     pManRst->pNtk = pNtk;
00122     // start the cut manager
00123 clk = clock();
00124     pManCut = Abc_NtkStartCutManForRestruct( pNtk, nCutMax, fMulti );
00125 pManRst->timeCut += clock() - clk;
00126 //    pNtk->pManCut = pManCut;
00127 
00128     // resynthesize each node once
00129     nNodes = Abc_NtkObjNumMax(pNtk);
00130     pProgress = Extra_ProgressBarStart( stdout, nNodes );
00131     Abc_NtkForEachNode( pNtk, pNode, i )
00132     {
00133         Extra_ProgressBarUpdate( pProgress, i, NULL );
00134         // skip the constant node
00135 //        if ( Abc_NodeIsConst(pNode) )
00136 //            continue;
00137         // skip persistant nodes
00138         if ( Abc_NodeIsPersistant(pNode) )
00139             continue;
00140         // skip the node if it is inside the tree
00141 //        if ( Abc_ObjFanoutNum(pNode) < 2 )
00142 //            continue;
00143         // skip the nodes with too many fanouts
00144         if ( Abc_ObjFanoutNum(pNode) > 1000 )
00145             continue;
00146         // stop if all nodes have been tried once
00147         if ( i >= nNodes )
00148             break;
00149         // get the cuts for the given node
00150 clk = clock();
00151         pCutList = Abc_NodeGetCutsRecursive( pManCut, pNode, fMulti, 0 ); 
00152 pManRst->timeCut += clock() - clk;
00153 
00154         // perform restructuring
00155 clk = clock();
00156         if ( fResub )
00157             pGraph = Abc_NodeResubstitute( pManRst, pNode, pCutList );
00158         else
00159             pGraph = Abc_NodeRestructure( pManRst, pNode, pCutList );
00160 pManRst->timeRes += clock() - clk;
00161         if ( pGraph == NULL )
00162             continue;
00163 
00164         // acceptable replacement found, update the graph
00165 clk = clock();
00166         Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, pManRst->nLastGain );
00167 pManRst->timeNtk += clock() - clk;
00168         Dec_GraphFree( pGraph );
00169     }
00170     Extra_ProgressBarStop( pProgress );
00171 pManRst->timeTotal = clock() - clkStart;
00172 
00173     // print statistics of the manager
00174 //    if ( fVerbose )
00175         Abc_NtkManRstPrintStats( pManRst );
00176     // delete the managers
00177     Cut_ManStop( pManCut );
00178     Abc_NtkManRstStop( pManRst );
00179     // put the nodes into the DFS order and reassign their IDs
00180     Abc_NtkReassignIds( pNtk );
00181 //    Abc_AigCheckFaninOrder( pNtk->pManFunc );
00182     // fix the levels
00183     if ( fUpdateLevel )
00184         Abc_NtkStopReverseLevels( pNtk );
00185     else
00186         Abc_NtkLevel( pNtk );
00187     // check
00188     if ( !Abc_NtkCheck( pNtk ) )
00189     {
00190         printf( "Abc_NtkRefactor: The network check has failed.\n" );
00191         return 0;
00192     }
00193     return 1;
00194 }

Cut_Man_t * Abc_NtkStartCutManForRestruct ( Abc_Ntk_t pNtk,
int  nCutMax,
int  fDag 
) [static]

Function*************************************************************

Synopsis [Starts the cut manager for rewriting.]

Description []

SideEffects []

SeeAlso []

Definition at line 955 of file abcRestruct.c.

00956 {
00957     static Cut_Params_t Params, * pParams = &Params;
00958     Cut_Man_t * pManCut;
00959     Abc_Obj_t * pObj;
00960     int i;
00961     // start the cut manager
00962     memset( pParams, 0, sizeof(Cut_Params_t) );
00963     pParams->nVarsMax  = nCutMax; // the max cut size ("k" of the k-feasible cuts)
00964     pParams->nKeepMax  = 250;     // the max number of cuts kept at a node
00965     pParams->fTruth    = 0;       // compute truth tables
00966     pParams->fFilter   = 1;       // filter dominated cuts
00967     pParams->fSeq      = 0;       // compute sequential cuts
00968     pParams->fDrop     = 0;       // drop cuts on the fly
00969     pParams->fDag      = fDag;    // compute DAG cuts
00970     pParams->fTree     = 0;       // compute tree cuts
00971     pParams->fVerbose  = 0;       // the verbosiness flag
00972     pParams->nIdsMax   = Abc_NtkObjNumMax( pNtk );
00973     pManCut = Cut_ManStart( pParams );
00974     if ( pParams->fDrop )
00975         Cut_ManSetFanoutCounts( pManCut, Abc_NtkFanoutCounts(pNtk) );
00976     // set cuts for PIs
00977     Abc_NtkForEachCi( pNtk, pObj, i )
00978         if ( Abc_ObjFanoutNum(pObj) > 0 )
00979             Cut_NodeSetTriv( pManCut, pObj->Id );
00980     return pManCut;
00981 }

void Abc_RestructNodeDivisors ( Abc_ManRst_t p,
Abc_Obj_t pRoot,
int  nNodesSaved 
)

Function*************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 207 of file abcRestruct.c.

00208 {
00209     Abc_Obj_t * pNode, * pFanout;//, * pFanin;
00210     int i, k;
00211     // start with the leaves
00212     Vec_PtrClear( p->vDecs );
00213     Vec_PtrForEachEntry( p->vLeaves, pNode, i )
00214     {
00215         Vec_PtrPush( p->vDecs, pNode );
00216         assert( pNode->fMarkC == 0 );
00217         pNode->fMarkC = 1;
00218     }
00219     // explore the fanouts
00220     Vec_PtrForEachEntry( p->vDecs, pNode, i )
00221     {
00222         // if the fanout has both fanins in the set, add it
00223         Abc_ObjForEachFanout( pNode, pFanout, k )
00224         {
00225             if ( pFanout->fMarkC || Abc_ObjIsPo(pFanout) )
00226                 continue;
00227             if ( Abc_ObjFanin0(pFanout)->fMarkC && Abc_ObjFanin1(pFanout)->fMarkC )
00228             {
00229                 Vec_PtrPush( p->vDecs, pFanout );
00230                 pFanout->fMarkC = 1;
00231             }
00232         }
00233     }
00234     // unmark the nodes
00235     Vec_PtrForEachEntry( p->vDecs, pNode, i )
00236         pNode->fMarkC = 0;
00237 /*
00238     // print the nodes
00239     Vec_PtrForEachEntryStart( p->vDecs, pNode, i, Vec_PtrSize(p->vLeaves) )
00240     {
00241         printf( "%2d %s = ", i, Abc_NodeIsTravIdCurrent(pNode)? "*" : " " );
00242         // find the first fanin
00243         Vec_PtrForEachEntry( p->vDecs, pFanin, k )
00244             if ( Abc_ObjFanin0(pNode) == pFanin )
00245                 break;
00246         if ( k < Vec_PtrSize(p->vLeaves) )
00247             printf( "%c", 'a' + k );
00248         else
00249             printf( "%d", k );
00250         printf( "%s ", Abc_ObjFaninC0(pNode)? "\'" : "" );
00251         // find the second fanin
00252         Vec_PtrForEachEntry( p->vDecs, pFanin, k )
00253             if ( Abc_ObjFanin1(pNode) == pFanin )
00254                 break;
00255         if ( k < Vec_PtrSize(p->vLeaves) )
00256             printf( "%c", 'a' + k );
00257         else
00258             printf( "%d", k );
00259         printf( "%s ", Abc_ObjFaninC1(pNode)? "\'" : "" );
00260         printf( "\n" );
00261     }
00262 */
00263     printf( "%d\n", Vec_PtrSize(p->vDecs)-nNodesSaved-Vec_PtrSize(p->vLeaves) );
00264 }


Generated on Tue Jan 5 12:18:41 2010 for abc70930 by  doxygen 1.6.1