src/aig/ivy/ivySeq.c File Reference

#include "ivy.h"
#include "deco.h"
#include "rwt.h"
Include dependency graph for ivySeq.c:

Go to the source code of this file.

Functions

static int Ivy_NodeRewriteSeq (Ivy_Man_t *pMan, Rwt_Man_t *p, Ivy_Obj_t *pNode, int fUseZeroCost)
static void Ivy_GraphPrepare (Dec_Graph_t *pGraph, Ivy_Cut_t *pCut, Vec_Ptr_t *vFanins, char *pPerm)
static unsigned Ivy_CutGetTruth (Ivy_Man_t *p, Ivy_Obj_t *pObj, int *pNums, int nNums)
static Dec_Graph_tRwt_CutEvaluateSeq (Ivy_Man_t *pMan, Rwt_Man_t *p, Ivy_Obj_t *pRoot, Ivy_Cut_t *pCut, char *pPerm, Vec_Ptr_t *vFaninsCur, int nNodesSaved, int *pGainBest, unsigned uTruth)
static int Ivy_GraphToNetworkSeqCountSeq (Ivy_Man_t *p, Ivy_Obj_t *pRoot, Dec_Graph_t *pGraph, int NodeMax)
static Ivy_Obj_tIvy_GraphToNetworkSeq (Ivy_Man_t *p, Dec_Graph_t *pGraph)
static void Ivy_GraphUpdateNetworkSeq (Ivy_Man_t *p, Ivy_Obj_t *pRoot, Dec_Graph_t *pGraph, int nGain)
static Ivy_Store_tIvy_CutComputeForNode (Ivy_Man_t *p, Ivy_Obj_t *pObj, int nLeaves)
static int Ivy_CutHashValue (int NodeId)
int Ivy_ManRewriteSeq (Ivy_Man_t *p, int fUseZeroCost, int fVerbose)
unsigned Ivy_CutGetTruth_rec (Ivy_Man_t *p, int Leaf, int *pNums, int nNums)
static int Ivy_CutPrescreen (Ivy_Cut_t *pCut, int Id0, int Id1)
static int Ivy_CutDeriveNew2 (Ivy_Cut_t *pCut, Ivy_Cut_t *pCutNew, int IdOld, int IdNew0, int IdNew1)
static int Ivy_CutDeriveNew (Ivy_Cut_t *pCut, Ivy_Cut_t *pCutNew, int IdOld, int IdNew0, int IdNew1)
static unsigned Ivy_NodeCutHash (Ivy_Cut_t *pCut)
static int Ivy_CutDeriveNew3 (Ivy_Cut_t *pCut, Ivy_Cut_t *pCutNew, int IdOld, int IdNew0, int IdNew1)
static int Ivy_CutCheckDominance (Ivy_Cut_t *pDom, Ivy_Cut_t *pCut)
int Ivy_CutFindOrAddFilter (Ivy_Store_t *pCutStore, Ivy_Cut_t *pCutNew)
void Ivy_CutCompactAll (Ivy_Store_t *pCutStore)
void Ivy_CutPrintForNode (Ivy_Cut_t *pCut)
void Ivy_CutPrintForNodes (Ivy_Store_t *pCutStore)
static int Ivy_CutReadLeaf (Ivy_Obj_t *pFanin)
void Ivy_CutComputeAll (Ivy_Man_t *p, int nInputs)

Function Documentation

static int Ivy_CutCheckDominance ( Ivy_Cut_t pDom,
Ivy_Cut_t pCut 
) [inline, static]

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

Synopsis [Returns 1 if pDom is contained in pCut.]

Description []

SideEffects []

SeeAlso []

Definition at line 839 of file ivySeq.c.

00840 {
00841     int i, k;
00842     for ( i = 0; i < pDom->nSize; i++ )
00843     {
00844         assert( i==0 || pDom->pArray[i-1] < pDom->pArray[i] );
00845         for ( k = 0; k < pCut->nSize; k++ )
00846             if ( pDom->pArray[i] == pCut->pArray[k] )
00847                 break;
00848         if ( k == pCut->nSize ) // node i in pDom is not contained in pCut
00849             return 0;
00850     }
00851     // every node in pDom is contained in pCut
00852     return 1;
00853 }

void Ivy_CutCompactAll ( Ivy_Store_t pCutStore  ) 

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

Synopsis [Compresses the cut representation.]

Description []

SideEffects []

SeeAlso []

Definition at line 929 of file ivySeq.c.

00930 {
00931     Ivy_Cut_t * pCut;
00932     int i, k;
00933     pCutStore->nCutsM = 0;
00934     for ( i = k = 0; i < pCutStore->nCuts; i++ )
00935     {
00936         pCut = pCutStore->pCuts + i;
00937         if ( pCut->nSize == 0 )
00938             continue;
00939         if ( pCut->nSize < pCut->nSizeMax )
00940             pCutStore->nCutsM++;
00941         pCutStore->pCuts[k++] = *pCut;
00942     }
00943     pCutStore->nCuts = k;
00944 }

void Ivy_CutComputeAll ( Ivy_Man_t p,
int  nInputs 
)

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 1102 of file ivySeq.c.

01103 {
01104     Ivy_Store_t * pStore;
01105     Ivy_Obj_t * pObj;
01106     int i, nCutsTotal, nCutsTotalM, nNodeTotal, nNodeOver;
01107     int clk = clock();
01108     if ( nInputs > IVY_CUT_INPUT )
01109     {
01110         printf( "Cannot compute cuts for more than %d inputs.\n", IVY_CUT_INPUT );
01111         return;
01112     }
01113     nNodeTotal = nNodeOver = 0;
01114     nCutsTotal = nCutsTotalM = -Ivy_ManNodeNum(p);
01115     Ivy_ManForEachObj( p, pObj, i )
01116     {
01117         if ( !Ivy_ObjIsNode(pObj) )
01118             continue;
01119         pStore = Ivy_CutComputeForNode( p, pObj, nInputs );
01120         nCutsTotal  += pStore->nCuts;
01121         nCutsTotalM += pStore->nCutsM;
01122         nNodeOver   += pStore->fSatur;
01123         nNodeTotal++;
01124     }
01125     printf( "All = %6d. Minus = %6d. Triv = %6d.   Node = %6d. Satur = %6d.  ", 
01126         nCutsTotal, nCutsTotalM, Ivy_ManPiNum(p) + Ivy_ManNodeNum(p), nNodeTotal, nNodeOver );
01127     PRT( "Time", clock() - clk );
01128 }

Ivy_Store_t * Ivy_CutComputeForNode ( Ivy_Man_t p,
Ivy_Obj_t pObj,
int  nLeaves 
) [static]

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 1020 of file ivySeq.c.

01021 {
01022     static Ivy_Store_t CutStore, * pCutStore = &CutStore;
01023     Ivy_Cut_t CutNew, * pCutNew = &CutNew, * pCut;
01024     Ivy_Man_t * pMan = p;
01025     Ivy_Obj_t * pLeaf;
01026     int i, k, Temp, nLats, iLeaf0, iLeaf1;
01027 
01028     assert( nLeaves <= IVY_CUT_INPUT );
01029 
01030     // start the structure
01031     pCutStore->nCuts = 0;
01032     pCutStore->nCutsMax = IVY_CUT_LIMIT;
01033     // start the trivial cut
01034     pCutNew->uHash = 0;
01035     pCutNew->nSize = 1;
01036     pCutNew->nSizeMax = nLeaves;
01037     pCutNew->pArray[0] = Ivy_LeafCreate( pObj->Id, 0 );
01038     pCutNew->uHash = Ivy_CutHashValue( pCutNew->pArray[0] );
01039     // add the trivial cut
01040     pCutStore->pCuts[pCutStore->nCuts++] = *pCutNew;
01041     assert( pCutStore->nCuts == 1 );
01042 
01043     // explore the cuts
01044     for ( i = 0; i < pCutStore->nCuts; i++ )
01045     {
01046         // expand this cut
01047         pCut = pCutStore->pCuts + i;
01048         if ( pCut->nSize == 0 )
01049             continue;
01050         for ( k = 0; k < pCut->nSize; k++ )
01051         {
01052             pLeaf = Ivy_ManObj( p, Ivy_LeafId(pCut->pArray[k]) );
01053             if ( Ivy_ObjIsCi(pLeaf) || Ivy_ObjIsConst1(pLeaf) )
01054                 continue;
01055             assert( Ivy_ObjIsNode(pLeaf) );
01056             nLats = Ivy_LeafLat(pCut->pArray[k]);
01057 
01058             // get the fanins fanins
01059             iLeaf0 = Ivy_CutReadLeaf( Ivy_ObjFanin0(pLeaf) );
01060             iLeaf1 = Ivy_CutReadLeaf( Ivy_ObjFanin1(pLeaf) );
01061             assert( nLats + Ivy_LeafLat(iLeaf0) < IVY_LEAF_MASK && nLats + Ivy_LeafLat(iLeaf1) < IVY_LEAF_MASK );
01062             iLeaf0 = nLats + iLeaf0;
01063             iLeaf1 = nLats + iLeaf1;
01064             if ( !Ivy_CutPrescreen( pCut, iLeaf0, iLeaf1 ) )
01065                 continue;
01066             // the given cut exist
01067             if ( iLeaf0 > iLeaf1 )
01068                 Temp = iLeaf0, iLeaf0 = iLeaf1, iLeaf1 = Temp;
01069             // create the new cut
01070             if ( !Ivy_CutDeriveNew( pCut, pCutNew, pCut->pArray[k], iLeaf0, iLeaf1 ) )
01071                 continue;
01072             // add the cut
01073             Ivy_CutFindOrAddFilter( pCutStore, pCutNew );
01074             if ( pCutStore->nCuts == IVY_CUT_LIMIT )
01075                 break;
01076         }
01077         if ( pCutStore->nCuts == IVY_CUT_LIMIT )
01078             break;
01079     }
01080     if ( pCutStore->nCuts == IVY_CUT_LIMIT )
01081         pCutStore->fSatur = 1;
01082     else
01083         pCutStore->fSatur = 0;
01084 //    printf( "%d ", pCutStore->nCuts );
01085     Ivy_CutCompactAll( pCutStore );
01086 //    printf( "%d \n", pCutStore->nCuts );
01087 //    Ivy_CutPrintForNodes( pCutStore );
01088     return pCutStore;
01089 }

static int Ivy_CutDeriveNew ( Ivy_Cut_t pCut,
Ivy_Cut_t pCutNew,
int  IdOld,
int  IdNew0,
int  IdNew1 
) [inline, static]

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

Synopsis [Derives new cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 715 of file ivySeq.c.

00716 {
00717     unsigned uHash = 0;
00718     int i, k; 
00719     assert( pCut->nSize > 0 );
00720     assert( IdNew0 < IdNew1 );
00721     for ( i = k = 0; i < pCut->nSize; i++ )
00722     {
00723         if ( pCut->pArray[i] == IdOld )
00724             continue;
00725         if ( IdNew0 <= pCut->pArray[i] )
00726         {
00727             if ( IdNew0 < pCut->pArray[i] )
00728             {
00729                 pCutNew->pArray[ k++ ] = IdNew0;
00730                 uHash |= Ivy_CutHashValue( IdNew0 );
00731             }
00732             IdNew0 = 0x7FFFFFFF;
00733         }
00734         if ( IdNew1 <= pCut->pArray[i] )
00735         {
00736             if ( IdNew1 < pCut->pArray[i] )
00737             {
00738                 pCutNew->pArray[ k++ ] = IdNew1;
00739                 uHash |= Ivy_CutHashValue( IdNew1 );
00740             }
00741             IdNew1 = 0x7FFFFFFF;
00742         }
00743         pCutNew->pArray[ k++ ] = pCut->pArray[i];
00744         uHash |= Ivy_CutHashValue( pCut->pArray[i] );
00745     }
00746     if ( IdNew0 < 0x7FFFFFFF )
00747     {
00748         pCutNew->pArray[ k++ ] = IdNew0;
00749         uHash |= Ivy_CutHashValue( IdNew0 );
00750     }
00751     if ( IdNew1 < 0x7FFFFFFF )
00752     {
00753         pCutNew->pArray[ k++ ] = IdNew1;
00754         uHash |= Ivy_CutHashValue( IdNew1 );
00755     }
00756     pCutNew->nSize = k;
00757     pCutNew->uHash = uHash;
00758     assert( pCutNew->nSize <= pCut->nSizeMax );
00759 //    for ( i = 1; i < pCutNew->nSize; i++ )
00760 //        assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] );
00761     return 1;
00762 }

static int Ivy_CutDeriveNew2 ( Ivy_Cut_t pCut,
Ivy_Cut_t pCutNew,
int  IdOld,
int  IdNew0,
int  IdNew1 
) [inline, static]

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

Synopsis [Derives new cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 639 of file ivySeq.c.

00640 {
00641     unsigned uHash = 0;
00642     int i, k;
00643     assert( pCut->nSize > 0 );
00644     assert( IdNew0 < IdNew1 );
00645     for ( i = k = 0; i < pCut->nSize; i++ )
00646     {
00647         if ( pCut->pArray[i] == IdOld )
00648             continue;
00649         if ( IdNew0 >= 0 )
00650         {
00651             if ( IdNew0 <= pCut->pArray[i] )
00652             {
00653                 if ( IdNew0 < pCut->pArray[i] )
00654                 {
00655                     if ( k == pCut->nSizeMax )
00656                         return 0;
00657                     pCutNew->pArray[ k++ ] = IdNew0;
00658                     uHash |= Ivy_CutHashValue( IdNew0 );
00659                 }
00660                 IdNew0 = -1;
00661             }
00662         }
00663         if ( IdNew1 >= 0 )
00664         {
00665             if ( IdNew1 <= pCut->pArray[i] )
00666             {
00667                 if ( IdNew1 < pCut->pArray[i] )
00668                 {
00669                     if ( k == pCut->nSizeMax )
00670                         return 0;
00671                     pCutNew->pArray[ k++ ] = IdNew1;
00672                     uHash |= Ivy_CutHashValue( IdNew1 );
00673                 }
00674                 IdNew1 = -1;
00675             }
00676         }
00677         if ( k == pCut->nSizeMax )
00678             return 0;
00679         pCutNew->pArray[ k++ ] = pCut->pArray[i];
00680         uHash |= Ivy_CutHashValue( pCut->pArray[i] );
00681     }
00682     if ( IdNew0 >= 0 )
00683     {
00684         if ( k == pCut->nSizeMax )
00685             return 0;
00686         pCutNew->pArray[ k++ ] = IdNew0;
00687         uHash |= Ivy_CutHashValue( IdNew0 );
00688     }
00689     if ( IdNew1 >= 0 )
00690     {
00691         if ( k == pCut->nSizeMax )
00692             return 0;
00693         pCutNew->pArray[ k++ ] = IdNew1;
00694         uHash |= Ivy_CutHashValue( IdNew1 );
00695     }
00696     pCutNew->nSize = k;
00697     pCutNew->uHash = uHash;
00698     assert( pCutNew->nSize <= pCut->nSizeMax );
00699     for ( i = 1; i < pCutNew->nSize; i++ )
00700         assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] );
00701     return 1;
00702 }

static int Ivy_CutDeriveNew3 ( Ivy_Cut_t pCut,
Ivy_Cut_t pCutNew,
int  IdOld,
int  IdNew0,
int  IdNew1 
) [inline, static]

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

Synopsis [Derives new cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 795 of file ivySeq.c.

00796 {
00797     int i, k; 
00798     assert( pCut->nSize > 0 );
00799     assert( IdNew0 < IdNew1 );
00800     for ( i = k = 0; i < pCut->nSize; i++ )
00801     {
00802         if ( pCut->pArray[i] == IdOld )
00803             continue;
00804         if ( IdNew0 <= pCut->pArray[i] )
00805         {
00806             if ( IdNew0 < pCut->pArray[i] )
00807                 pCutNew->pArray[ k++ ] = IdNew0;
00808             IdNew0 = 0x7FFFFFFF;
00809         }
00810         if ( IdNew1 <= pCut->pArray[i] )
00811         {
00812             if ( IdNew1 < pCut->pArray[i] )
00813                 pCutNew->pArray[ k++ ] = IdNew1;
00814             IdNew1 = 0x7FFFFFFF;
00815         }
00816         pCutNew->pArray[ k++ ] = pCut->pArray[i];
00817     }
00818     if ( IdNew0 < 0x7FFFFFFF )
00819         pCutNew->pArray[ k++ ] = IdNew0;
00820     if ( IdNew1 < 0x7FFFFFFF )
00821         pCutNew->pArray[ k++ ] = IdNew1;
00822     pCutNew->nSize = k;
00823     assert( pCutNew->nSize <= pCut->nSizeMax );
00824     Ivy_NodeCutHash( pCutNew );
00825     return 1;
00826 }

int Ivy_CutFindOrAddFilter ( Ivy_Store_t pCutStore,
Ivy_Cut_t pCutNew 
)

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

Synopsis [Check if the cut exists.]

Description [Returns 1 if the cut exists.]

SideEffects []

SeeAlso []

Definition at line 866 of file ivySeq.c.

00867 {
00868     Ivy_Cut_t * pCut;
00869     int i, k;
00870     assert( pCutNew->uHash );
00871     // try to find the cut
00872     for ( i = 0; i < pCutStore->nCuts; i++ )
00873     {
00874         pCut = pCutStore->pCuts + i;
00875         if ( pCut->nSize == 0 )
00876             continue;
00877         if ( pCut->nSize == pCutNew->nSize )
00878         {
00879             if ( pCut->uHash == pCutNew->uHash )
00880             {
00881                 for ( k = 0; k < pCutNew->nSize; k++ )
00882                     if ( pCut->pArray[k] != pCutNew->pArray[k] )
00883                         break;
00884                 if ( k == pCutNew->nSize )
00885                     return 1;
00886             }
00887             continue;
00888         }
00889         if ( pCut->nSize < pCutNew->nSize )
00890         {
00891             // skip the non-contained cuts
00892             if ( (pCut->uHash & pCutNew->uHash) != pCut->uHash )
00893                 continue;
00894             // check containment seriously
00895             if ( Ivy_CutCheckDominance( pCut, pCutNew ) )
00896                 return 1;
00897             continue;
00898         }
00899         // check potential containment of other cut
00900 
00901         // skip the non-contained cuts
00902         if ( (pCut->uHash & pCutNew->uHash) != pCutNew->uHash )
00903             continue;
00904         // check containment seriously
00905         if ( Ivy_CutCheckDominance( pCutNew, pCut ) )
00906         {
00907             // remove the current cut
00908             pCut->nSize = 0;
00909         }
00910     }
00911     assert( pCutStore->nCuts < pCutStore->nCutsMax );
00912     // add the cut
00913     pCut = pCutStore->pCuts + pCutStore->nCuts++;
00914     *pCut = *pCutNew;
00915     return 0;
00916 }

unsigned Ivy_CutGetTruth ( Ivy_Man_t p,
Ivy_Obj_t pObj,
int *  pNums,
int  nNums 
) [static]

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

Synopsis [Computes the truth table.]

Description []

SideEffects []

SeeAlso []

Definition at line 595 of file ivySeq.c.

00596 {
00597     assert( Ivy_ObjIsNode(pObj) );
00598     assert( nNums < 6 );
00599     return Ivy_CutGetTruth_rec( p, Ivy_LeafCreate(pObj->Id, 0), pNums, nNums );
00600 }

unsigned Ivy_CutGetTruth_rec ( Ivy_Man_t p,
int  Leaf,
int *  pNums,
int  nNums 
)

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

Synopsis [Computes the truth table.]

Description []

SideEffects []

SeeAlso []

Definition at line 553 of file ivySeq.c.

00554 {
00555     static unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
00556     unsigned uTruth0, uTruth1;
00557     Ivy_Obj_t * pObj;
00558     int i;
00559     for ( i = 0; i < nNums; i++ )
00560         if ( Leaf == pNums[i] )
00561             return uMasks[i];
00562     pObj = Ivy_ManObj( p, Ivy_LeafId(Leaf) );
00563     if ( Ivy_ObjIsLatch(pObj) )
00564     {
00565         assert( !Ivy_ObjFaninC0(pObj) );
00566         Leaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pObj), Ivy_LeafLat(Leaf) + 1 );
00567         return Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums );
00568     }
00569     assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj) );
00570     Leaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pObj), Ivy_LeafLat(Leaf) );
00571     uTruth0 = Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums );
00572     if ( Ivy_ObjFaninC0(pObj) )
00573         uTruth0 = ~uTruth0;
00574     if ( Ivy_ObjIsBuf(pObj) )
00575         return uTruth0;
00576     Leaf = Ivy_LeafCreate( Ivy_ObjFaninId1(pObj), Ivy_LeafLat(Leaf) );
00577     uTruth1 = Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums );
00578     if ( Ivy_ObjFaninC1(pObj) )
00579         uTruth1 = ~uTruth1;
00580     return uTruth0 & uTruth1;
00581 }

static int Ivy_CutHashValue ( int  NodeId  )  [inline, static]

Definition at line 38 of file ivySeq.c.

00038 { return 1 << (NodeId % 31); }

static int Ivy_CutPrescreen ( Ivy_Cut_t pCut,
int  Id0,
int  Id1 
) [inline, static]

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

Synopsis [Returns 1 if the cut can be constructed; 0 otherwise.]

Description []

SideEffects []

SeeAlso []

Definition at line 617 of file ivySeq.c.

00618 {
00619     int i;
00620     if ( pCut->nSize < pCut->nSizeMax )
00621         return 1;
00622     for ( i = 0; i < pCut->nSize; i++ )
00623         if ( pCut->pArray[i] == Id0 || pCut->pArray[i] == Id1 )
00624             return 1;
00625     return 0;
00626 }

void Ivy_CutPrintForNode ( Ivy_Cut_t pCut  ) 

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

Synopsis [Print the cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 957 of file ivySeq.c.

00958 {
00959     int i;
00960     assert( pCut->nSize > 0 );
00961     printf( "%d : {", pCut->nSize );
00962     for ( i = 0; i < pCut->nSize; i++ )
00963         printf( " %d", pCut->pArray[i] );
00964     printf( " }\n" );
00965 }

void Ivy_CutPrintForNodes ( Ivy_Store_t pCutStore  ) 

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 978 of file ivySeq.c.

00979 {
00980     int i;
00981     printf( "Node %d\n", pCutStore->pCuts[0].pArray[0] );
00982     for ( i = 0; i < pCutStore->nCuts; i++ )
00983         Ivy_CutPrintForNode( pCutStore->pCuts + i );
00984 }

static int Ivy_CutReadLeaf ( Ivy_Obj_t pFanin  )  [inline, static]

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 997 of file ivySeq.c.

00998 {
00999     int nLats, iLeaf;
01000     assert( !Ivy_IsComplement(pFanin) );
01001     if ( !Ivy_ObjIsLatch(pFanin) )
01002         return Ivy_LeafCreate( pFanin->Id, 0 );
01003     iLeaf = Ivy_CutReadLeaf(Ivy_ObjFanin0(pFanin));
01004     nLats = Ivy_LeafLat(iLeaf);
01005     assert( nLats < IVY_LEAF_MASK );
01006     return 1 + iLeaf;
01007 }

void Ivy_GraphPrepare ( Dec_Graph_t pGraph,
Ivy_Cut_t pCut,
Vec_Ptr_t vFanins,
char *  pPerm 
) [static]

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 357 of file ivySeq.c.

00358 {
00359     Dec_Node_t * pNode, * pNode0, * pNode1;
00360     int i;
00361     assert( Dec_GraphLeaveNum(pGraph) == pCut->nSize );
00362     assert( Vec_PtrSize(vFanins) == pCut->nSize );
00363     // label the leaves with latch numbers
00364     Dec_GraphForEachLeaf( pGraph, pNode, i )
00365     {
00366         pNode->pFunc = Vec_PtrEntry( vFanins, i );
00367         pNode->nLat2 = Ivy_LeafLat( pCut->pArray[pPerm[i]] );
00368     }
00369     // propagate latches through the nodes
00370     Dec_GraphForEachNode( pGraph, pNode, i )
00371     {
00372         // get the children of this node
00373         pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node );
00374         pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node );
00375         // distribute the latches
00376         pNode->nLat2 = IVY_MIN( pNode0->nLat2, pNode1->nLat2 );
00377         pNode->nLat0 = pNode0->nLat2 - pNode->nLat2;
00378         pNode->nLat1 = pNode1->nLat2 - pNode->nLat2;
00379     }
00380 }

Ivy_Obj_t * Ivy_GraphToNetworkSeq ( Ivy_Man_t p,
Dec_Graph_t pGraph 
) [static]

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

Synopsis [Transforms the decomposition graph into the AIG.]

Description [AIG nodes for the fanins should be assigned to pNode->pFunc of the leaves of the graph before calling this procedure.]

SideEffects []

SeeAlso []

Definition at line 470 of file ivySeq.c.

00471 {
00472     Ivy_Obj_t * pAnd0, * pAnd1;
00473     Dec_Node_t * pNode;
00474     int i, k;
00475     // check for constant function
00476     if ( Dec_GraphIsConst(pGraph) )
00477         return Ivy_NotCond( Ivy_ManConst1(p), Dec_GraphIsComplement(pGraph) );
00478     // check for a literal
00479     if ( Dec_GraphIsVar(pGraph) )
00480     {
00481         // get the variable node
00482         pNode = Dec_GraphVar(pGraph);
00483         // add the remaining latches
00484         for ( k = 0; k < (int)pNode->nLat2; k++ )
00485             pNode->pFunc = Ivy_Latch( p, pNode->pFunc, IVY_INIT_DC );
00486         return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) );
00487     }
00488     // build the AIG nodes corresponding to the AND gates of the graph
00489     Dec_GraphForEachNode( pGraph, pNode, i )
00490     {
00491         pAnd0 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); 
00492         pAnd1 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); 
00493         // add the latches
00494         for ( k = 0; k < (int)pNode->nLat0; k++ )
00495             pAnd0 = Ivy_Latch( p, pAnd0, IVY_INIT_DC );
00496         for ( k = 0; k < (int)pNode->nLat1; k++ )
00497             pAnd1 = Ivy_Latch( p, pAnd1, IVY_INIT_DC );
00498         // create the node
00499         pNode->pFunc = Ivy_And( p, pAnd0, pAnd1 );
00500     }
00501     // add the remaining latches
00502     for ( k = 0; k < (int)pNode->nLat2; k++ )
00503         pNode->pFunc = Ivy_Latch( p, pNode->pFunc, IVY_INIT_DC );
00504     // complement the result if necessary
00505     return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) );
00506 }

int Ivy_GraphToNetworkSeqCountSeq ( Ivy_Man_t p,
Ivy_Obj_t pRoot,
Dec_Graph_t pGraph,
int  NodeMax 
) [static]

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

Synopsis [Counts the number of new nodes added when using this graph.]

Description [AIG nodes for the fanins should be assigned to pNode->pFunc of the leaves of the graph before calling this procedure. Returns -1 if the number of nodes and levels exceeded the given limit or the number of levels exceeded the maximum allowed level.]

SideEffects []

SeeAlso []

Definition at line 396 of file ivySeq.c.

00397 {
00398     Dec_Node_t * pNode, * pNode0, * pNode1;
00399     Ivy_Obj_t * pAnd, * pAnd0, * pAnd1;
00400     int i, k, Counter, fCompl;
00401     // check for constant function or a literal
00402     if ( Dec_GraphIsConst(pGraph) || Dec_GraphIsVar(pGraph) )
00403         return 0;
00404     // compute the AIG size after adding the internal nodes
00405     Counter = 0;
00406     Dec_GraphForEachNode( pGraph, pNode, i )
00407     {
00408         // get the children of this node
00409         pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node );
00410         pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node );
00411         // get the AIG nodes corresponding to the children 
00412         pAnd0 = pNode0->pFunc; 
00413         pAnd1 = pNode1->pFunc; 
00414         // skip the latches
00415         for ( k = 0; pAnd0 && k < (int)pNode->nLat0; k++ )
00416         {
00417             fCompl = Ivy_IsComplement(pAnd0);
00418             pAnd0 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Regular(pAnd0), NULL, IVY_LATCH, IVY_INIT_DC) );
00419             if ( pAnd0 )
00420                 pAnd0 = Ivy_NotCond( pAnd0, fCompl );
00421         }
00422         for ( k = 0; pAnd1 && k < (int)pNode->nLat1; k++ )
00423         {
00424             fCompl = Ivy_IsComplement(pAnd1);
00425             pAnd1 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Regular(pAnd1), NULL, IVY_LATCH, IVY_INIT_DC) );
00426             if ( pAnd1 )
00427                 pAnd1 = Ivy_NotCond( pAnd1, fCompl );
00428         }
00429         // get the new node
00430         if ( pAnd0 && pAnd1 )
00431         {
00432             // if they are both present, find the resulting node
00433             pAnd0 = Ivy_NotCond( pAnd0, pNode->eEdge0.fCompl );
00434             pAnd1 = Ivy_NotCond( pAnd1, pNode->eEdge1.fCompl );
00435             assert( !Ivy_ObjIsLatch(Ivy_Regular(pAnd0)) || !Ivy_ObjIsLatch(Ivy_Regular(pAnd1)) );
00436             if ( Ivy_Regular(pAnd0) == Ivy_Regular(pAnd1) || Ivy_ObjIsConst1(Ivy_Regular(pAnd0)) || Ivy_ObjIsConst1(Ivy_Regular(pAnd1)) )
00437                 pAnd = Ivy_And( p, pAnd0, pAnd1 );
00438             else
00439                 pAnd = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, pAnd0, pAnd1, IVY_AND, IVY_INIT_NONE) );
00440             // return -1 if the node is the same as the original root
00441             if ( Ivy_Regular(pAnd) == pRoot )
00442                 return -1;
00443         }
00444         else
00445             pAnd = NULL;
00446         // count the number of added nodes
00447         if ( pAnd == NULL || Ivy_ObjIsTravIdCurrent(p, Ivy_Regular(pAnd)) )
00448         {
00449             if ( ++Counter > NodeMax )
00450                 return -1;
00451         }
00452         pNode->pFunc = pAnd;
00453     }
00454     return Counter;
00455 }

void Ivy_GraphUpdateNetworkSeq ( Ivy_Man_t p,
Ivy_Obj_t pRoot,
Dec_Graph_t pGraph,
int  nGain 
) [static]

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

Synopsis [Replaces MFFC of the node by the new factored form.]

Description []

SideEffects []

SeeAlso []

Definition at line 519 of file ivySeq.c.

00520 {
00521     Ivy_Obj_t * pRootNew;
00522     int nNodesNew, nNodesOld;
00523     nNodesOld = Ivy_ManNodeNum(p);
00524     // create the new structure of nodes
00525     pRootNew = Ivy_GraphToNetworkSeq( p, pGraph );
00526     Ivy_ObjReplace( p, pRoot, pRootNew, 1, 0, 0 );
00527     // compare the gains
00528     nNodesNew = Ivy_ManNodeNum(p);
00529     assert( nGain <= nNodesOld - nNodesNew );
00530     // propagate the buffer
00531     Ivy_ManPropagateBuffers( p, 0 );
00532 }

int Ivy_ManRewriteSeq ( Ivy_Man_t p,
int  fUseZeroCost,
int  fVerbose 
)

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

Synopsis [Performs incremental rewriting of the AIG.]

Description []

SideEffects []

SeeAlso []

Definition at line 60 of file ivySeq.c.

00061 { 
00062     Rwt_Man_t * pManRwt;
00063     Ivy_Obj_t * pNode;
00064     int i, nNodes, nGain;
00065     int clk, clkStart = clock();
00066 
00067     // set the DC latch values
00068     Ivy_ManForEachLatch( p, pNode, i )
00069         pNode->Init = IVY_INIT_DC;
00070     // start the rewriting manager
00071     pManRwt = Rwt_ManStart( 0 );
00072     p->pData = pManRwt;
00073     if ( pManRwt == NULL )
00074         return 0; 
00075     // create fanouts
00076     if ( p->fFanout == 0 )
00077         Ivy_ManStartFanout( p );
00078     // resynthesize each node once
00079     nNodes = Ivy_ManObjIdMax(p);
00080     Ivy_ManForEachNode( p, pNode, i )
00081     {
00082         assert( !Ivy_ObjIsBuf(pNode) );
00083         assert( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) );
00084         assert( !Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) );
00085         // fix the fanin buffer problem
00086 //        Ivy_NodeFixBufferFanins( p, pNode );
00087 //        if ( Ivy_ObjIsBuf(pNode) )
00088 //            continue;
00089         // stop if all nodes have been tried once
00090         if ( i > nNodes ) 
00091             break;
00092         // for each cut, try to resynthesize it
00093         nGain = Ivy_NodeRewriteSeq( p, pManRwt, pNode, fUseZeroCost );
00094         if ( nGain > 0 || nGain == 0 && fUseZeroCost )
00095         {
00096             Dec_Graph_t * pGraph = Rwt_ManReadDecs(pManRwt);
00097             int fCompl           = Rwt_ManReadCompl(pManRwt);
00098             // complement the FF if needed
00099 clk = clock();
00100             if ( fCompl ) Dec_GraphComplement( pGraph );
00101             Ivy_GraphUpdateNetworkSeq( p, pNode, pGraph, nGain );
00102             if ( fCompl ) Dec_GraphComplement( pGraph );
00103 Rwt_ManAddTimeUpdate( pManRwt, clock() - clk );
00104         }
00105     }
00106 Rwt_ManAddTimeTotal( pManRwt, clock() - clkStart );
00107     // print stats
00108     if ( fVerbose )
00109         Rwt_ManPrintStats( pManRwt );
00110     // delete the managers
00111     Rwt_ManStop( pManRwt );
00112     p->pData = NULL;
00113     // fix the levels
00114     Ivy_ManResetLevels( p );
00115 //    if ( Ivy_ManCheckFanoutNums(p) )
00116 //        printf( "Ivy_ManRewritePre(): The check has failed.\n" );
00117     // check
00118     if ( !Ivy_ManCheck(p) )
00119         printf( "Ivy_ManRewritePre(): The check has failed.\n" );
00120     return 1;
00121 }

static unsigned Ivy_NodeCutHash ( Ivy_Cut_t pCut  )  [inline, static]

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

Synopsis [Find the hash value of the cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 775 of file ivySeq.c.

00776 {
00777     int i;
00778     pCut->uHash = 0;
00779     for ( i = 0; i < pCut->nSize; i++ )
00780         pCut->uHash |= (1 << (pCut->pArray[i] % 31));
00781     return pCut->uHash;
00782 }

int Ivy_NodeRewriteSeq ( Ivy_Man_t pMan,
Rwt_Man_t p,
Ivy_Obj_t pNode,
int  fUseZeroCost 
) [static]

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

FileName [ivySeq.c]

SystemName [ABC: Logic synthesis and verification system.]

PackageName [And-Inverter Graph package.]

Synopsis []

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 1.0. Started - May 11, 2006.]

Revision [

Id
ivySeq.c,v 1.00 2006/05/11 00:00:00 alanmi Exp

] DECLARATIONS ///

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

Synopsis [Performs rewriting for one node.]

Description [This procedure considers all the cuts computed for the node and tries to rewrite each of them using the "forest" of different AIG structures precomputed and stored in the RWR manager. Determines the best rewriting and computes the gain in the number of AIG nodes in the final network. In the end, p->vFanins contains information about the best cut that can be used for rewriting, while p->pGraph gives the decomposition dag (represented using decomposition graph data structure). Returns gain in the number of nodes or -1 if node cannot be rewritten.]

SideEffects []

SeeAlso []

Definition at line 142 of file ivySeq.c.

00143 {
00144     int fVeryVerbose = 0;
00145     Dec_Graph_t * pGraph;
00146     Ivy_Store_t * pStore;
00147     Ivy_Cut_t * pCut;
00148     Ivy_Obj_t * pFanin;//, * pFanout;
00149     Vec_Ptr_t * vFanout;
00150     unsigned uPhase, uTruthBest, uTruth;//, nNewClauses;
00151     char * pPerm;
00152     int nNodesSaved, nNodesSaveCur;
00153     int i, c, GainCur, GainBest = -1;
00154     int clk, clk2;//, clk3;
00155 
00156     p->nNodesConsidered++;
00157     // get the node's cuts
00158 clk = clock();
00159     pStore = Ivy_CutComputeForNode( pMan, pNode, 5 );
00160 p->timeCut += clock() - clk;
00161 
00162     // go through the cuts
00163 clk = clock();
00164     vFanout = Vec_PtrAlloc( 100 );
00165     for ( c = 1; c < pStore->nCuts; c++ )
00166     {
00167         pCut = pStore->pCuts + c;
00168         // consider only 4-input cuts
00169         if ( pCut->nSize != 4 )
00170             continue;
00171         // skip the cuts with buffers
00172         for ( i = 0; i < (int)pCut->nSize; i++ )
00173             if ( Ivy_ObjIsBuf( Ivy_ManObj(pMan, Ivy_LeafId(pCut->pArray[i])) ) )
00174                 break;
00175         if ( i != pCut->nSize )
00176         {
00177             p->nCutsBad++;
00178             continue;
00179         }
00180         p->nCutsGood++;
00181         // get the fanin permutation
00182 clk2 = clock();
00183         uTruth = 0xFFFF & Ivy_CutGetTruth( pMan, pNode, pCut->pArray, pCut->nSize );  // truth table
00184 p->timeTruth += clock() - clk2;
00185         pPerm = p->pPerms4[ p->pPerms[uTruth] ];
00186         uPhase = p->pPhases[uTruth];
00187         // collect fanins with the corresponding permutation/phase
00188         Vec_PtrClear( p->vFaninsCur );
00189         Vec_PtrFill( p->vFaninsCur, (int)pCut->nSize, 0 );
00190         for ( i = 0; i < (int)pCut->nSize; i++ )
00191         {
00192             pFanin = Ivy_ManObj( pMan, Ivy_LeafId( pCut->pArray[pPerm[i]] ) );
00193             assert( Ivy_ObjIsNode(pFanin) || Ivy_ObjIsCi(pFanin) || Ivy_ObjIsConst1(pFanin) );
00194             pFanin = Ivy_NotCond(pFanin, ((uPhase & (1<<i)) > 0) );
00195             Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin );
00196         }
00197 clk2 = clock();
00198         // mark the fanin boundary 
00199         Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
00200             Ivy_ObjRefsInc( Ivy_Regular(pFanin) );
00201         // label MFFC with current ID
00202         Ivy_ManIncrementTravId( pMan );
00203         nNodesSaved = Ivy_ObjMffcLabel( pMan, pNode );
00204         // label fanouts with the current ID
00205 //        Ivy_ObjForEachFanout( pMan, pNode, vFanout, pFanout, i )
00206 //            Ivy_ObjSetTravIdCurrent( pMan, pFanout );
00207         // unmark the fanin boundary
00208         Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
00209             Ivy_ObjRefsDec( Ivy_Regular(pFanin) );
00210 p->timeMffc += clock() - clk2;
00211 
00212         // evaluate the cut
00213 clk2 = clock();
00214         pGraph = Rwt_CutEvaluateSeq( pMan, p, pNode, pCut, pPerm, p->vFaninsCur, nNodesSaved, &GainCur, uTruth );
00215 p->timeEval += clock() - clk2;
00216 
00217 
00218         // check if the cut is better than the current best one
00219         if ( pGraph != NULL && GainBest < GainCur )
00220         {
00221             // save this form
00222             nNodesSaveCur = nNodesSaved;
00223             GainBest   = GainCur;
00224             p->pGraph  = pGraph;
00225             p->pCut    = pCut;
00226             p->pPerm   = pPerm;
00227             p->fCompl  = ((uPhase & (1<<4)) > 0);
00228             uTruthBest = uTruth;
00229             // collect fanins in the
00230             Vec_PtrClear( p->vFanins );
00231             Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
00232                 Vec_PtrPush( p->vFanins, pFanin );
00233         }
00234     }
00235     Vec_PtrFree( vFanout );
00236 p->timeRes += clock() - clk;
00237 
00238     if ( GainBest == -1 )
00239         return -1;
00240 /*
00241     {
00242     Ivy_Cut_t * pCut = p->pCut;
00243     printf( "Node %5d. Using cut : {", Ivy_ObjId(pNode) );
00244     for ( i = 0; i < pCut->nSize; i++ )
00245         printf( " %d(%d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) );
00246     printf( " }\n" );
00247     }
00248 */
00249 
00250 //clk3 = clock();
00251 //nNewClauses = Ivy_CutTruthPrint( pMan, p->pCut, uTruth );
00252 //timeInv += clock() - clk;
00253 
00254 //    nClauses += nNewClauses;
00255 //    nMoves++;
00256 //    if ( nNewClauses > 0 )
00257 //        nMovesS++;
00258 
00259     // copy the leaves
00260     Ivy_GraphPrepare( p->pGraph, p->pCut, p->vFanins, p->pPerm );
00261 
00262     p->nScores[p->pMap[uTruthBest]]++;
00263     p->nNodesGained += GainBest;
00264     if ( fUseZeroCost || GainBest > 0 )
00265         p->nNodesRewritten++;
00266 
00267 /*
00268     if ( GainBest > 0 )
00269     {
00270         Ivy_Cut_t * pCut = p->pCut;
00271         printf( "Node %5d. Using cut : {", Ivy_ObjId(pNode) );
00272         for ( i = 0; i < pCut->nSize; i++ )
00273             printf( " %5d(%2d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) );
00274         printf( " }\n" );
00275     }
00276 */
00277 
00278     // report the progress
00279     if ( fVeryVerbose && GainBest > 0 )
00280     {
00281         printf( "Node %6d :   ", Ivy_ObjId(pNode) );
00282         printf( "Fanins = %d. ", p->vFanins->nSize );
00283         printf( "Save = %d.  ", nNodesSaveCur );
00284         printf( "Add = %d.  ",  nNodesSaveCur-GainBest );
00285         printf( "GAIN = %d.  ", GainBest );
00286         printf( "Cone = %d.  ", p->pGraph? Dec_GraphNodeNum(p->pGraph) : 0 );
00287         printf( "Class = %d.  ", p->pMap[uTruthBest] );
00288         printf( "\n" );
00289     }
00290     return GainBest;
00291 }

Dec_Graph_t * Rwt_CutEvaluateSeq ( Ivy_Man_t pMan,
Rwt_Man_t p,
Ivy_Obj_t pRoot,
Ivy_Cut_t pCut,
char *  pPerm,
Vec_Ptr_t vFaninsCur,
int  nNodesSaved,
int *  pGainBest,
unsigned  uTruth 
) [static]

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

Synopsis [Evaluates the cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 305 of file ivySeq.c.

00306 {
00307     Vec_Ptr_t * vSubgraphs;
00308     Dec_Graph_t * pGraphBest, * pGraphCur;
00309     Rwt_Node_t * pNode;
00310     int nNodesAdded, GainBest, i;
00311     // find the matching class of subgraphs
00312     vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] );
00313     p->nSubgraphs += vSubgraphs->nSize;
00314     // determine the best subgraph
00315     GainBest = -1;
00316     Vec_PtrForEachEntry( vSubgraphs, pNode, i )
00317     {
00318         // get the current graph
00319         pGraphCur = (Dec_Graph_t *)pNode->pNext;
00320 
00321 //        if ( pRoot->Id == 8648 )
00322 //        Dec_GraphPrint( stdout, pGraphCur, NULL, NULL );
00323         // copy the leaves
00324 //        Vec_PtrForEachEntry( vFaninsCur, pFanin, k )
00325 //            Dec_GraphNode(pGraphCur, k)->pFunc = pFanin;
00326         Ivy_GraphPrepare( pGraphCur, pCut, vFaninsCur, pPerm );
00327 
00328         // detect how many unlabeled nodes will be reused
00329         nNodesAdded = Ivy_GraphToNetworkSeqCountSeq( pMan, pRoot, pGraphCur, nNodesSaved );
00330         if ( nNodesAdded == -1 )
00331             continue;
00332         assert( nNodesSaved >= nNodesAdded );
00333         // count the gain at this node
00334         if ( GainBest < nNodesSaved - nNodesAdded )
00335         {
00336             GainBest   = nNodesSaved - nNodesAdded;
00337             pGraphBest = pGraphCur;
00338         }
00339     }
00340     if ( GainBest == -1 )
00341         return NULL;
00342     *pGainBest = GainBest;
00343     return pGraphBest;
00344 }


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