src/aig/csw/cswCut.c File Reference

#include "cswInt.h"
Include dependency graph for cswCut.c:

Go to the source code of this file.

Functions

static int Csw_CutFindCost (Csw_Man_t *p, Csw_Cut_t *pCut)
static float Csw_CutFindCost2 (Csw_Man_t *p, Csw_Cut_t *pCut)
static Csw_Cut_tCsw_CutFindFree (Csw_Man_t *p, Aig_Obj_t *pObj)
static unsigned Cut_TruthPhase (Csw_Cut_t *pCut, Csw_Cut_t *pCut1)
unsigned * Csw_CutComputeTruth (Csw_Man_t *p, Csw_Cut_t *pCut, Csw_Cut_t *pCut0, Csw_Cut_t *pCut1, int fCompl0, int fCompl1)
int Csw_CutSupportMinimize (Csw_Man_t *p, Csw_Cut_t *pCut)
static int Csw_CutCheckDominance (Csw_Cut_t *pDom, Csw_Cut_t *pCut)
int Csw_CutFilter (Csw_Man_t *p, Aig_Obj_t *pObj, Csw_Cut_t *pCut)
static int Csw_CutMergeOrdered (Csw_Man_t *p, Csw_Cut_t *pC0, Csw_Cut_t *pC1, Csw_Cut_t *pC)
int Csw_CutMerge (Csw_Man_t *p, Csw_Cut_t *pCut0, Csw_Cut_t *pCut1, Csw_Cut_t *pCut)
Aig_Obj_tCsw_ObjTwoVarCut (Csw_Man_t *p, Csw_Cut_t *pCut)
Csw_Cut_tCsw_ObjPrepareCuts (Csw_Man_t *p, Aig_Obj_t *pObj, int fTriv)
Aig_Obj_tCsw_ObjSweep (Csw_Man_t *p, Aig_Obj_t *pObj, int fTriv)

Function Documentation

static int Csw_CutCheckDominance ( Csw_Cut_t pDom,
Csw_Cut_t pCut 
) [inline, static]

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

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

Description []

SideEffects []

SeeAlso []

Definition at line 214 of file cswCut.c.

00215 {
00216     int i, k;
00217     for ( i = 0; i < (int)pDom->nFanins; i++ )
00218     {
00219         for ( k = 0; k < (int)pCut->nFanins; k++ )
00220             if ( pDom->pFanins[i] == pCut->pFanins[k] )
00221                 break;
00222         if ( k == (int)pCut->nFanins ) // node i in pDom is not contained in pCut
00223             return 0;
00224     }
00225     // every node in pDom is contained in pCut
00226     return 1;
00227 }

unsigned* Csw_CutComputeTruth ( Csw_Man_t p,
Csw_Cut_t pCut,
Csw_Cut_t pCut0,
Csw_Cut_t pCut1,
int  fCompl0,
int  fCompl1 
)

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

Synopsis [Performs truth table computation.]

Description []

SideEffects []

SeeAlso []

Definition at line 146 of file cswCut.c.

00147 {
00148     // permute the first table
00149     if ( fCompl0 ) 
00150         Kit_TruthNot( p->puTemp[0], Csw_CutTruth(pCut0), p->nLeafMax );
00151     else
00152         Kit_TruthCopy( p->puTemp[0], Csw_CutTruth(pCut0), p->nLeafMax );
00153     Kit_TruthStretch( p->puTemp[2], p->puTemp[0], pCut0->nFanins, p->nLeafMax, Cut_TruthPhase(pCut, pCut0), 0 );
00154     // permute the second table
00155     if ( fCompl1 ) 
00156         Kit_TruthNot( p->puTemp[1], Csw_CutTruth(pCut1), p->nLeafMax );
00157     else
00158         Kit_TruthCopy( p->puTemp[1], Csw_CutTruth(pCut1), p->nLeafMax );
00159     Kit_TruthStretch( p->puTemp[3], p->puTemp[1], pCut1->nFanins, p->nLeafMax, Cut_TruthPhase(pCut, pCut1), 0 );
00160     // produce the resulting table
00161     Kit_TruthAnd( Csw_CutTruth(pCut), p->puTemp[2], p->puTemp[3], p->nLeafMax );
00162 //    assert( pCut->nFanins >= Kit_TruthSupportSize( Csw_CutTruth(pCut), p->nLeafMax ) );
00163     return Csw_CutTruth(pCut);
00164 }

int Csw_CutFilter ( Csw_Man_t p,
Aig_Obj_t pObj,
Csw_Cut_t pCut 
)

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

Synopsis [Returns 1 if the cut is contained.]

Description []

SideEffects []

SeeAlso []

Definition at line 240 of file cswCut.c.

00241 { 
00242     Csw_Cut_t * pTemp;
00243     int i;
00244     // go through the cuts of the node
00245     Csw_ObjForEachCut( p, pObj, pTemp, i )
00246     {
00247         if ( pTemp->nFanins < 2 )
00248             continue;
00249         if ( pTemp == pCut )
00250             continue;
00251         if ( pTemp->nFanins > pCut->nFanins )
00252         {
00253             // skip the non-contained cuts
00254             if ( (pTemp->uSign & pCut->uSign) != pCut->uSign )
00255                 continue;
00256             // check containment seriously
00257             if ( Csw_CutCheckDominance( pCut, pTemp ) )
00258             {
00259                 // remove contained cut
00260                 pTemp->nFanins = 0;
00261             }
00262          }
00263         else
00264         {
00265             // skip the non-contained cuts
00266             if ( (pTemp->uSign & pCut->uSign) != pTemp->uSign )
00267                 continue;
00268             // check containment seriously
00269             if ( Csw_CutCheckDominance( pTemp, pCut ) )
00270             {
00271                 // remove the given
00272                 pCut->nFanins = 0;
00273                 return 1;
00274             }
00275         }
00276     }
00277     return 0;
00278 }

static int Csw_CutFindCost ( Csw_Man_t p,
Csw_Cut_t pCut 
) [inline, static]

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

FileName [cswCut.c]

SystemName [ABC: Logic synthesis and verification system.]

PackageName [Cut sweeping.]

Synopsis []

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 1.0. Started - July 11, 2007.]

Revision [

Id
cswCut.c,v 1.00 2007/07/11 00:00:00 alanmi Exp

] DECLARATIONS /// FUNCTION DEFINITIONS ///Function*************************************************************

Synopsis [Compute the cost of the cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 42 of file cswCut.c.

00043 {
00044     Aig_Obj_t * pLeaf;
00045     int i, Cost = 0;
00046     assert( pCut->nFanins > 0 );
00047     Csw_CutForEachLeaf( p->pManRes, pCut, pLeaf, i )
00048     {
00049 //        Cost += pLeaf->nRefs;
00050         Cost += Csw_ObjRefs( p, pLeaf );
00051 //        printf( "%d ", pLeaf->nRefs );
00052     }
00053 //printf( "\n" );
00054     return Cost * 100 / pCut->nFanins;
00055 }

static float Csw_CutFindCost2 ( Csw_Man_t p,
Csw_Cut_t pCut 
) [inline, static]

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

Synopsis [Compute the cost of the cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 68 of file cswCut.c.

00069 {
00070     Aig_Obj_t * pLeaf;
00071     float Cost = 0.0;
00072     int i;
00073     assert( pCut->nFanins > 0 );
00074     Csw_CutForEachLeaf( p->pManRes, pCut, pLeaf, i )
00075         Cost += (float)1.0/pLeaf->nRefs;
00076     return 1/Cost;
00077 }

static Csw_Cut_t* Csw_CutFindFree ( Csw_Man_t p,
Aig_Obj_t pObj 
) [inline, static]

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

Synopsis [Returns the next free cut to use.]

Description []

SideEffects []

SeeAlso []

Definition at line 90 of file cswCut.c.

00091 {
00092     Csw_Cut_t * pCut, * pCutMax;
00093     int i;
00094     pCutMax = NULL;
00095     Csw_ObjForEachCut( p, pObj, pCut, i )
00096     {
00097         if ( pCut->nFanins == 0 )
00098             return pCut;
00099         if ( pCutMax == NULL || pCutMax->Cost < pCut->Cost )
00100             pCutMax = pCut;
00101     }
00102     assert( pCutMax != NULL );
00103     pCutMax->nFanins = 0;
00104     return pCutMax;
00105 }

int Csw_CutMerge ( Csw_Man_t p,
Csw_Cut_t pCut0,
Csw_Cut_t pCut1,
Csw_Cut_t pCut 
)

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

Synopsis [Prepares the object for FPGA mapping.]

Description []

SideEffects []

SeeAlso []

Definition at line 377 of file cswCut.c.

00378 { 
00379     assert( p->nLeafMax > 0 );
00380     // merge the nodes
00381     if ( pCut0->nFanins < pCut1->nFanins )
00382     {
00383         if ( !Csw_CutMergeOrdered( p, pCut1, pCut0, pCut ) )
00384             return 0;
00385     }
00386     else
00387     {
00388         if ( !Csw_CutMergeOrdered( p, pCut0, pCut1, pCut ) )
00389             return 0;
00390     }
00391     pCut->uSign = pCut0->uSign | pCut1->uSign;
00392     return 1;
00393 }

static int Csw_CutMergeOrdered ( Csw_Man_t p,
Csw_Cut_t pC0,
Csw_Cut_t pC1,
Csw_Cut_t pC 
) [inline, static]

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

Synopsis [Merges two cuts.]

Description []

SideEffects []

SeeAlso []

Definition at line 291 of file cswCut.c.

00292 { 
00293     int i, k, c;
00294     assert( pC0->nFanins >= pC1->nFanins );
00295     // the case of the largest cut sizes
00296     if ( pC0->nFanins == p->nLeafMax && pC1->nFanins == p->nLeafMax )
00297     {
00298         for ( i = 0; i < pC0->nFanins; i++ )
00299             if ( pC0->pFanins[i] != pC1->pFanins[i] )
00300                 return 0;
00301         for ( i = 0; i < pC0->nFanins; i++ )
00302             pC->pFanins[i] = pC0->pFanins[i];
00303         pC->nFanins = pC0->nFanins;
00304         return 1;
00305     }
00306     // the case when one of the cuts is the largest
00307     if ( pC0->nFanins == p->nLeafMax )
00308     {
00309         for ( i = 0; i < pC1->nFanins; i++ )
00310         {
00311             for ( k = pC0->nFanins - 1; k >= 0; k-- )
00312                 if ( pC0->pFanins[k] == pC1->pFanins[i] )
00313                     break;
00314             if ( k == -1 ) // did not find
00315                 return 0;
00316         }
00317         for ( i = 0; i < pC0->nFanins; i++ )
00318             pC->pFanins[i] = pC0->pFanins[i];
00319         pC->nFanins = pC0->nFanins;
00320         return 1;
00321     }
00322 
00323     // compare two cuts with different numbers
00324     i = k = 0;
00325     for ( c = 0; c < p->nLeafMax; c++ )
00326     {
00327         if ( k == pC1->nFanins )
00328         {
00329             if ( i == pC0->nFanins )
00330             {
00331                 pC->nFanins = c;
00332                 return 1;
00333             }
00334             pC->pFanins[c] = pC0->pFanins[i++];
00335             continue;
00336         }
00337         if ( i == pC0->nFanins )
00338         {
00339             if ( k == pC1->nFanins )
00340             {
00341                 pC->nFanins = c;
00342                 return 1;
00343             }
00344             pC->pFanins[c] = pC1->pFanins[k++];
00345             continue;
00346         }
00347         if ( pC0->pFanins[i] < pC1->pFanins[k] )
00348         {
00349             pC->pFanins[c] = pC0->pFanins[i++];
00350             continue;
00351         }
00352         if ( pC0->pFanins[i] > pC1->pFanins[k] )
00353         {
00354             pC->pFanins[c] = pC1->pFanins[k++];
00355             continue;
00356         }
00357         pC->pFanins[c] = pC0->pFanins[i++]; 
00358         k++;
00359     }
00360     if ( i < pC0->nFanins || k < pC1->nFanins )
00361         return 0;
00362     pC->nFanins = c;
00363     return 1;
00364 }

int Csw_CutSupportMinimize ( Csw_Man_t p,
Csw_Cut_t pCut 
)

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

Synopsis [Performs support minimization for the truth table.]

Description []

SideEffects []

SeeAlso []

Definition at line 177 of file cswCut.c.

00178 {
00179     unsigned * pTruth;
00180     int uSupp, nFansNew, i, k;
00181     // get truth table
00182     pTruth = Csw_CutTruth( pCut );
00183     // get support 
00184     uSupp = Kit_TruthSupport( pTruth, p->nLeafMax );
00185     // get the new support size
00186     nFansNew = Kit_WordCountOnes( uSupp );
00187     // check if there are redundant variables
00188     if ( nFansNew == pCut->nFanins )
00189         return nFansNew;
00190     assert( nFansNew < pCut->nFanins );
00191     // minimize support
00192     Kit_TruthShrink( p->puTemp[0], pTruth, nFansNew, p->nLeafMax, uSupp, 1 );
00193     for ( i = k = 0; i < pCut->nFanins; i++ )
00194         if ( uSupp & (1 << i) )
00195             pCut->pFanins[k++] = pCut->pFanins[i];
00196     assert( k == nFansNew );
00197     pCut->nFanins = nFansNew;
00198 //    assert( nFansNew == Kit_TruthSupportSize( pTruth, p->nLeafMax ) );
00199 //Extra_PrintBinary( stdout, pTruth, (1<<p->nLeafMax) ); printf( "\n" );
00200     return nFansNew;
00201 }

Csw_Cut_t* Csw_ObjPrepareCuts ( Csw_Man_t p,
Aig_Obj_t pObj,
int  fTriv 
)

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 450 of file cswCut.c.

00451 {
00452     Csw_Cut_t * pCutSet, * pCut;
00453     int i;
00454     // create the cutset of the node
00455     pCutSet = (Csw_Cut_t *)Aig_MmFixedEntryFetch( p->pMemCuts );
00456     Csw_ObjSetCuts( p, pObj, pCutSet );
00457     Csw_ObjForEachCut( p, pObj, pCut, i )
00458     {
00459         pCut->nFanins = 0;
00460         pCut->iNode = pObj->Id;
00461         pCut->nCutSize = p->nCutSize;
00462         pCut->nLeafMax = p->nLeafMax;
00463     }
00464     // add unit cut if needed
00465     if ( fTriv )
00466     {
00467         pCut = pCutSet;
00468         pCut->Cost = 0;
00469         pCut->iNode = pObj->Id;
00470         pCut->nFanins = 1;
00471         pCut->pFanins[0] = pObj->Id;
00472         pCut->uSign = Aig_ObjCutSign( pObj->Id );
00473         memset( Csw_CutTruth(pCut), 0xAA, sizeof(unsigned) * p->nTruthWords );
00474     }
00475     return pCutSet;
00476 }

Aig_Obj_t* Csw_ObjSweep ( Csw_Man_t p,
Aig_Obj_t pObj,
int  fTriv 
)

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

Synopsis [Derives cuts for one node and sweeps this node.]

Description []

SideEffects []

SeeAlso []

Definition at line 489 of file cswCut.c.

00490 {
00491     int fUseResub = 1;
00492     Csw_Cut_t * pCut0, * pCut1, * pCut, * pCutSet;
00493     Aig_Obj_t * pFanin0 = Aig_ObjFanin0(pObj);
00494     Aig_Obj_t * pFanin1 = Aig_ObjFanin1(pObj);
00495     Aig_Obj_t * pObjNew;
00496     unsigned * pTruth;
00497     int i, k, nVars, nFanins, iVar, clk;
00498 
00499     assert( !Aig_IsComplement(pObj) );
00500     if ( !Aig_ObjIsNode(pObj) )
00501         return pObj;
00502     if ( Csw_ObjCuts(p, pObj) )
00503         return pObj;
00504     // the node is not processed yet
00505     assert( Csw_ObjCuts(p, pObj) == NULL );
00506     assert( Aig_ObjIsNode(pObj) );
00507 
00508     // set up the first cut
00509     pCutSet = Csw_ObjPrepareCuts( p, pObj, fTriv );
00510 
00511     // compute pair-wise cut combinations while checking table
00512     Csw_ObjForEachCut( p, pFanin0, pCut0, i )
00513     if ( pCut0->nFanins > 0 )
00514     Csw_ObjForEachCut( p, pFanin1, pCut1, k )
00515     if ( pCut1->nFanins > 0 )
00516     {
00517         // make sure K-feasible cut exists
00518         if ( Kit_WordCountOnes(pCut0->uSign | pCut1->uSign) > p->nLeafMax )
00519             continue;
00520         // get the next cut of this node
00521         pCut = Csw_CutFindFree( p, pObj );
00522 clk = clock();
00523         // assemble the new cut
00524         if ( !Csw_CutMerge( p, pCut0, pCut1, pCut ) )
00525         {
00526             assert( pCut->nFanins == 0 );
00527             continue;
00528         }
00529         // check containment
00530         if ( Csw_CutFilter( p, pObj, pCut ) )
00531         {
00532             assert( pCut->nFanins == 0 );
00533             continue;
00534         }
00535         // create its truth table
00536         pTruth = Csw_CutComputeTruth( p, pCut, pCut0, pCut1, Aig_ObjFaninC0(pObj), Aig_ObjFaninC1(pObj) );
00537         // support minimize the truth table
00538         nFanins = pCut->nFanins;
00539 //        nVars = Csw_CutSupportMinimize( p, pCut ); // leads to quality degradation
00540         nVars = Kit_TruthSupportSize( pTruth, p->nLeafMax );
00541 p->timeCuts += clock() - clk;
00542 
00543         // check for trivial truth tables
00544         if ( nVars == 0 )
00545         {
00546             p->nNodesTriv0++;
00547             return Aig_NotCond( Aig_ManConst1(p->pManRes), !(pTruth[0] & 1) );
00548         }
00549         if ( nVars == 1 )
00550         {
00551             p->nNodesTriv1++;
00552             iVar = Kit_WordFindFirstBit( Kit_TruthSupport(pTruth, p->nLeafMax) );
00553             assert( iVar < pCut->nFanins );
00554             return Aig_NotCond( Aig_ManObj(p->pManRes, pCut->pFanins[iVar]), (pTruth[0] & 1) );
00555         }
00556         if ( nVars == 2 && nFanins > 2 && fUseResub )
00557         {
00558             if ( pObjNew = Csw_ObjTwoVarCut( p, pCut ) )
00559             {
00560                 p->nNodesTriv2++;
00561                 return pObjNew;
00562             }
00563         }
00564 
00565         // check if an equivalent node with the same cut exists
00566 clk = clock();
00567         pObjNew = pCut->nFanins > 2 ? Csw_TableCutLookup( p, pCut ) : NULL;
00568 p->timeHash += clock() - clk;
00569         if ( pObjNew )
00570         {
00571             p->nNodesCuts++;
00572             return pObjNew;
00573         }
00574 
00575         // assign the cost
00576         pCut->Cost = Csw_CutFindCost( p, pCut );
00577         assert( pCut->nFanins > 0 );
00578         assert( pCut->Cost > 0 );
00579     }
00580     p->nNodesTried++;
00581 
00582     // load the resulting cuts into the table
00583 clk = clock();
00584     Csw_ObjForEachCut( p, pObj, pCut, i )
00585     {
00586         if ( pCut->nFanins > 2 )
00587         {
00588             assert( pCut->Cost > 0 );
00589             Csw_TableCutInsert( p, pCut );
00590         }
00591     }
00592 p->timeHash += clock() - clk;
00593 
00594     // return the node if could not replace it
00595     return pObj;
00596 }

Aig_Obj_t* Csw_ObjTwoVarCut ( Csw_Man_t p,
Csw_Cut_t pCut 
)

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

Synopsis [Consider cut with more than 2 fanins having 2 true variables.]

Description []

SideEffects []

SeeAlso []

Definition at line 406 of file cswCut.c.

00407 {
00408     Aig_Obj_t * pRes, * pIn0, * pIn1;
00409     int nVars, uTruth, fCompl = 0;
00410     assert( pCut->nFanins > 2 );
00411     // minimize support of this cut
00412     nVars = Csw_CutSupportMinimize( p, pCut );
00413     assert( nVars == 2 );
00414     // get the fanins
00415     pIn0 = Aig_ManObj( p->pManRes, pCut->pFanins[0] );
00416     pIn1 = Aig_ManObj( p->pManRes, pCut->pFanins[1] );
00417     // derive the truth table
00418     uTruth = 0xF & *Csw_CutTruth(pCut);
00419     if ( uTruth == 14 || uTruth == 13 || uTruth == 11 || uTruth == 7 )
00420     {
00421         uTruth = 0xF & ~uTruth;
00422         fCompl = 1;
00423     }
00424     // compute the result
00425     pRes = NULL;
00426     if ( uTruth == 1  )  // 0001  // 1110  14
00427         pRes = Aig_And( p->pManRes, Aig_Not(pIn0), Aig_Not(pIn1) );
00428     if ( uTruth == 2  )  // 0010  // 1101  13 
00429         pRes = Aig_And( p->pManRes,         pIn0 , Aig_Not(pIn1) );
00430     if ( uTruth == 4  )  // 0100  // 1011  11
00431         pRes = Aig_And( p->pManRes, Aig_Not(pIn0),         pIn1  );
00432     if ( uTruth == 8  )  // 1000  // 0111   7
00433         pRes = Aig_And( p->pManRes,         pIn0 ,         pIn1  );
00434     if ( pRes )
00435         pRes = Aig_NotCond( pRes, fCompl );
00436     return pRes;
00437 }

static unsigned Cut_TruthPhase ( Csw_Cut_t pCut,
Csw_Cut_t pCut1 
) [inline, static]

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

Synopsis [Computes the stretching phase of the cut w.r.t. the merged cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 118 of file cswCut.c.

00119 {
00120     unsigned uPhase = 0;
00121     int i, k;
00122     for ( i = k = 0; i < pCut->nFanins; i++ )
00123     {
00124         if ( k == pCut1->nFanins )
00125             break;
00126         if ( pCut->pFanins[i] < pCut1->pFanins[k] )
00127             continue;
00128         assert( pCut->pFanins[i] == pCut1->pFanins[k] );
00129         uPhase |= (1 << i);
00130         k++;
00131     }
00132     return uPhase;
00133 }


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