2008-01-31 05:01:00 +01:00
/**CFile****************************************************************
FileName [ abcRec . c ]
SystemName [ ABC : Logic synthesis and verification system . ]
PackageName [ Network and node package . ]
Synopsis [ Record of semi - canonical AIG subgraphs . ]
2011-12-30 03:54:30 +01:00
Author [ Allan Yang , Alan Mishchenko ]
2008-01-31 05:01:00 +01:00
2011-12-30 03:54:30 +01:00
Affiliation [ Fudan University in Shanghai , UC Berkeley ]
2008-01-31 05:01:00 +01:00
Date [ Ver . 1.0 . Started - June 20 , 2005. ]
Revision [ $ Id : abcRec . c , v 1.00 2005 / 06 / 20 00 : 00 : 00 alanmi Exp $ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "abc.h"
# include "if.h"
# include "kit.h"
2010-11-01 09:35:04 +01:00
ABC_NAMESPACE_IMPL_START
2012-01-12 07:08:35 +01:00
//#define LibOut
2008-01-31 05:01:00 +01:00
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
2011-12-29 15:14:01 +01:00
# define IF_BIG_CHAR 120
2008-01-31 05:01:00 +01:00
typedef struct Abc_ManRec_t_ Abc_ManRec_t ;
2011-12-29 15:14:01 +01:00
typedef struct Rec_Obj_t_ Rec_Obj_t ;
typedef enum {
2012-01-12 07:08:35 +01:00
REC_ERROR , //0: error
REC_SMALL , //1: smaller than
REC_EQUAL , //2: equal with
2011-12-29 15:14:01 +01:00
REC_BIG , //3: bigger than
2012-01-12 07:08:35 +01:00
REC_DOMINANCE , //4: dominance
2011-12-29 15:14:01 +01:00
REC_BEDOMINANCED //5: be dominated
} Abc_LookUpStatus_t ;
struct Rec_Obj_t_
{
2012-01-12 07:08:35 +01:00
Abc_Obj_t * obj ; // the actual structure in the library
Rec_Obj_t * pNext ; // link to the next structure of the same functional class
Rec_Obj_t * pCopy ; // link to the next functional class in the same bucket
int Id ; // structure's ID
unsigned nFrequency ; // appear times of this functional class among benchmarks
unsigned char cost ; // structure's cost
2011-12-29 15:14:01 +01:00
char * pinToPinDelay ; // structure's pin-to-pin delay
} ;
2008-01-31 05:01:00 +01:00
struct Abc_ManRec_t_
{
2012-01-12 07:08:35 +01:00
Abc_Ntk_t * pNtk ; // the record
Vec_Ptr_t * vTtElems ; // the elementary truth tables
Vec_Ptr_t * vTtNodes ; // the node truth tables
2011-12-30 07:11:52 +01:00
Mem_Fixed_t * pMmTruth ; // memory manager for truth tables
2011-12-29 15:14:01 +01:00
Rec_Obj_t * * pBins ; // hash table mapping truth tables into nodes
int nBins ; // the number of allocated bins
int nVars ; // the number of variables
int nVarsInit ; // the number of variables requested initially
2012-01-12 07:08:35 +01:00
int nWords ; // the number of TT words
2011-12-29 15:14:01 +01:00
int nCuts ; // the max number of cuts to use
2012-01-12 07:08:35 +01:00
Mem_Fixed_t * pMemObj ; // memory manager for Rec objects
int recObjSize ; // size for one Rec object
int fTrim ; // filter the library or not.
2008-01-31 05:01:00 +01:00
// temporaries
2012-01-12 07:08:35 +01:00
int * pBytes ; // temporary storage for minterms
int * pMints ; // temporary storage for minterm counters
unsigned * pTemp1 ; // temporary truth table
unsigned * pTemp2 ; // temporary truth table
Vec_Ptr_t * vNodes ; // the temporary nodes
Vec_Ptr_t * vTtTemps ; // the truth tables for the internal nodes of the cut
Vec_Ptr_t * vLabels ; // temporary storage for AIG node labels
Vec_Str_t * vCosts ; // temporary storage for costs
Vec_Int_t * vMemory ; // temporary memory for truth tables
2008-01-31 05:01:00 +01:00
// statistics
2012-01-12 07:08:35 +01:00
int nTried ; // the number of cuts tried
int nFilterSize ; // the number of same structures
2011-12-29 15:14:01 +01:00
int nFilterRedund ; // the number of same structures
int nFilterVolume ; // the number of same structures
2012-01-12 07:08:35 +01:00
int nFilterTruth ; // the number of same structures
int nFilterError ; // the number of same structures
int nFilterSame ; // the number of same structures
int nAdded ; // the number of subgraphs added
int nAddedFuncs ; // the number of functions added
int nIfMapTried ;
int nIfMapError ;
int nTrimed ; // the number of structures filtered
2008-01-31 05:01:00 +01:00
// rewriting
2012-01-12 07:08:35 +01:00
int nFunsFound ; // the found functions
2011-12-29 15:14:01 +01:00
int nFunsNotFound ; // the missing functions
2012-01-12 07:08:35 +01:00
int nFunsTried ;
int nFunsFilteredBysupport ; // the function filtered when rewriting because not all supports are in use.
int nFunsDelayComput ; // the times delay computed, just for statistics
2011-12-29 15:14:01 +01:00
// rewriting runtime
2012-01-12 07:08:35 +01:00
int timeIfTotal ; // time used on the whole process of rewriting a structure.
int timeIfComputDelay ; // time used on the structure's delay computation.
int timeIfCanonicize ; // time used on canonicize the function
int timeIfDerive ; // time used on derive the final network;
int timeIfOther ; // time used on other things
2011-12-29 15:14:01 +01:00
// record runtime
2012-01-12 07:08:35 +01:00
int timeTrim ; // the runtime to filter the library
int timeCollect ; // the runtime to collect the node of a structure.
2011-12-29 15:14:01 +01:00
int timeTruth ; // the runtime to compute truth table.
int timeCanon ; // the runtime to canonicize
2012-01-12 07:08:35 +01:00
int timeInsert ; // the runtime to insert a structure.
int timeBuild ; // the runtime to build a new structure in the library.
int timeMerge ; // the runtime to merge libraries;
2011-12-29 15:14:01 +01:00
int timeOther ; // the runtime of other
int timeTotal ; // the runtime to total.
2008-01-31 05:01:00 +01:00
} ;
2011-12-29 15:14:01 +01:00
2008-01-31 05:01:00 +01:00
// the truth table is canonicized in such a way that for (00000) its value is 0
2011-12-29 15:14:01 +01:00
static Rec_Obj_t * * Abc_NtkRecTableLookup ( Abc_ManRec_t * p , unsigned * pTruth , int nVars ) ;
2008-01-31 05:01:00 +01:00
static int Abc_NtkRecComputeTruth ( Abc_Obj_t * pObj , Vec_Ptr_t * vTtNodes , int nVars ) ;
static int Abc_NtkRecAddCutCheckCycle_rec ( Abc_Obj_t * pRoot , Abc_Obj_t * pObj ) ;
2012-01-12 07:08:35 +01:00
static void Abc_NtkRecAddFromLib ( Abc_Ntk_t * pNtk , Abc_Obj_t * pRoot , int nVars ) ;
2008-01-31 05:01:00 +01:00
static Abc_ManRec_t * s_pMan = NULL ;
2011-12-29 15:14:01 +01:00
static inline void Abc_ObjSetMax ( Abc_Obj_t * pObj , int Value ) { assert ( pObj - > Level < 0xff ) ; pObj - > Level = ( Value < < 8 ) | ( pObj - > Level & 0xff ) ; }
static inline void Abc_ObjClearMax ( Abc_Obj_t * pObj ) { pObj - > Level = ( pObj - > Level & 0xff ) ; }
static inline int Abc_ObjGetMax ( Abc_Obj_t * pObj ) { return ( pObj - > Level > > 8 ) & 0xff ; }
2012-01-12 07:08:35 +01:00
static inline void Abc_NtkRecFrequencyInc ( Rec_Obj_t * entry )
{
// the hit number of this functional class increased
if ( entry ! = NULL & & entry - > nFrequency < 0xffffffff )
entry - > nFrequency + = 1 ;
}
2008-01-31 05:01:00 +01:00
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
2011-12-29 15:14:01 +01:00
Synopsis [ stretch the truthtable to have more input variables . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void If_CutTruthStretch ( unsigned * pInOut , int nVarS , int nVarB )
{
int w , i ;
int step = Kit_TruthWordNum ( nVarS ) ;
int nWords = Kit_TruthWordNum ( nVarB ) ;
assert ( step < = nWords ) ;
if ( step = = nWords )
return ;
for ( w = 0 ; w < nWords ; w + = step )
for ( i = 0 ; i < step ; i + + )
2012-01-12 07:08:35 +01:00
pInOut [ w + i ] = pInOut [ i ] ;
2011-12-29 15:14:01 +01:00
}
/**Function*************************************************************
Synopsis [ Alloc the Rec object from its manger . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Rec_Obj_t * Rec_ObjAlloc ( Abc_ManRec_t * p , Abc_Obj_t * pObj , char * pinToPinDelay , char cost , int nVar )
{
int i ;
Rec_Obj_t * pRecObj ;
pRecObj = ( Rec_Obj_t * ) Mem_FixedEntryFetch ( p - > pMemObj ) ;
pRecObj - > pinToPinDelay = ( char * ) ( pRecObj + 1 ) ;
pRecObj - > pNext = NULL ;
pRecObj - > pCopy = NULL ;
pRecObj - > obj = pObj ;
pRecObj - > Id = pObj - > Id ;
for ( i = 0 ; i < nVar ; i + + )
pRecObj - > pinToPinDelay [ i ] = pinToPinDelay [ i ] ;
2012-01-12 07:08:35 +01:00
pRecObj - > cost = cost ;
pRecObj - > nFrequency = 0 ;
2011-12-29 15:14:01 +01:00
return pRecObj ;
}
/**Function*************************************************************
Synopsis [ set the property of a Rec object . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Rec_ObjSet ( Abc_ManRec_t * p , Rec_Obj_t * pRecObj , Abc_Obj_t * pObj , char * newDelay , unsigned char cost , int nVar )
{
int i ;
pRecObj - > obj = pObj ;
pRecObj - > Id = pObj - > Id ;
pRecObj - > cost = cost ;
for ( i = 0 ; i < nVar ; i + + )
pRecObj - > pinToPinDelay [ i ] = newDelay [ i ] ;
}
/**Function*************************************************************
Synopsis [ Compute the delay of the structure recursively . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* int If_CutDelayRecComput_rec(Abc_Obj_t* pObj, Vec_Str_t* vCosts)
{
2012-01-12 07:08:35 +01:00
char Delay0 , Delay1 , Delay ;
Abc_Obj_t * pFanin0 , * pFanin1 ;
pObj = Abc_ObjRegular ( pObj ) ;
if ( Abc_NodeIsTravIdCurrent ( pObj ) | | pObj - > Type = = ABC_OBJ_PI )
return Vec_StrEntry ( vCosts , pObj - > Id ) ;
Abc_NodeSetTravIdCurrent ( pObj ) ;
Delay0 = If_CutDelayRecComput_rec ( Abc_ObjFanin0 ( pObj ) , vCosts ) ;
Delay1 = If_CutDelayRecComput_rec ( Abc_ObjFanin1 ( pObj ) , vCosts ) ;
Delay = ABC_MAX ( Delay0 , Delay1 ) + 1 ;
Vec_StrWriteEntry ( vCosts , pObj - > Id , Delay ) ;
return Delay ;
2011-12-29 15:14:01 +01:00
} */
/**Function*************************************************************
Synopsis [ Compute delay of the structure using pin - to - pin delay . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int If_CutComputDelay ( If_Man_t * p , Rec_Obj_t * entry , If_Cut_t * pCut , char * pCanonPerm , int nVars )
{
If_Obj_t * pLeaf ;
int i , delayTemp , delayMax = - ABC_INFINITY ;
for ( i = 0 ; i < nVars ; i + + )
{
pLeaf = If_ManObj ( p , ( pCut ) - > pLeaves [ pCanonPerm [ i ] ] ) ;
pLeaf = If_Regular ( pLeaf ) ;
delayTemp = entry - > pinToPinDelay [ i ] + If_ObjCutBest ( pLeaf ) - > Delay ;
if ( delayTemp > delayMax )
delayMax = delayTemp ;
}
// plus each pin's delay with its pin-to-output delay, the biggest one is the delay of the structure.
return delayMax ;
}
/**Function*************************************************************
Synopsis [ Compute pin - to - pin delay of the structure . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char If_CutDepthRecComput_rec ( Abc_Obj_t * pObj , int iLeaf )
{
char Depth0 , Depth1 , Depth ;
pObj = Abc_ObjRegular ( pObj ) ;
if ( pObj - > Id = = iLeaf )
return 0 ;
if ( pObj - > Type = = ABC_OBJ_PI )
return - IF_BIG_CHAR ;
Depth0 = If_CutDepthRecComput_rec ( Abc_ObjFanin0 ( pObj ) , iLeaf ) ;
Depth1 = If_CutDepthRecComput_rec ( Abc_ObjFanin1 ( pObj ) , iLeaf ) ;
Depth = ABC_MAX ( Depth0 , Depth1 ) ;
Depth = ( Depth = = - IF_BIG_CHAR ) ? - IF_BIG_CHAR : Depth + 1 ;
assert ( Depth < = 127 ) ;
return Depth ;
}
/**Function*************************************************************
Synopsis [ Compute area of the structure . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
unsigned char If_CutAreaRecComput_rec ( Abc_Obj_t * pObj )
{
unsigned char Area0 , Area1 , Area ;
pObj = Abc_ObjRegular ( pObj ) ;
if ( pObj - > Type = = ABC_OBJ_PI )
return 0 ;
Area0 = If_CutAreaRecComput_rec ( Abc_ObjFanin0 ( pObj ) ) ;
Area1 = If_CutAreaRecComput_rec ( Abc_ObjFanin1 ( pObj ) ) ;
Area = Area1 + Area0 + 1 ;
assert ( Area < = 255 ) ;
return Area ;
}
/**Function*************************************************************
Synopsis [ Compare delay profile of two structures . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Abc_LookUpStatus_t ABC_NtkRecDelayCompare ( char * delayFromStruct , char * delayFromTable , int nVar )
{
int i , bigThan = 0 , smallThan = 0 , equal = 1 , dominace = 1 , beDominaced = 1 ;
for ( i = 0 ; i < nVar ; i + + )
{
if ( delayFromStruct [ i ] < delayFromTable [ i ] )
{
equal = 0 ;
beDominaced = 0 ;
if ( bigThan = = 0 )
smallThan = 1 ;
}
else if ( delayFromStruct [ i ] > delayFromTable [ i ] )
{
equal = 0 ;
dominace = 0 ;
if ( smallThan = = 0 )
bigThan = 1 ;
2012-01-12 07:08:35 +01:00
}
2011-12-29 15:14:01 +01:00
}
2012-01-12 07:08:35 +01:00
if ( equal )
return REC_EQUAL ;
else if ( dominace )
return REC_DOMINANCE ;
else if ( beDominaced )
return REC_BEDOMINANCED ;
2011-12-29 15:14:01 +01:00
if ( bigThan )
return REC_BIG ;
else if ( smallThan )
return REC_SMALL ;
else
return REC_SMALL ;
}
/**Function*************************************************************
Synopsis [ link a useless PO to constant 0. ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkRecReplacePO ( Abc_Obj_t * pObj )
{
Abc_Obj_t * pConst0 , * pFaninNew ;
Abc_Ntk_t * pNtk = pObj - > pNtk ;
if ( Abc_ObjFanin0 ( pObj ) = = Abc_AigConst1 ( pNtk ) )
{
if ( ! Abc_ObjFaninC0 ( pObj ) )
Abc_ObjXorFaninC ( pObj , 0 ) ;
return ;
}
pConst0 = Abc_ObjNot ( Abc_AigConst1 ( pNtk ) ) ;
pFaninNew = Abc_ObjNotCond ( pConst0 , Abc_ObjFaninC0 ( pObj ) ) ;
Abc_ObjPatchFanin ( pObj , Abc_ObjFanin0 ( pObj ) , pFaninNew ) ;
assert ( Abc_ObjChild0 ( pObj ) = = pConst0 ) ;
//Abc_AigCleanup( (Abc_Aig_t *)pNtk->pManFunc );
}
/**Function*************************************************************
Synopsis [ Delete a useless structure in the library . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkRecDeleteSubGragh ( Abc_ManRec_t * p , Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanOut ;
int i , deleted = 0 ;
Abc_ObjForEachFanout ( pObj , pFanOut , i )
{
if ( Abc_ObjIsCo ( pFanOut ) )
{
Abc_NtkRecReplacePO ( pFanOut ) ;
deleted + + ;
p - > nTrimed + + ;
2012-01-12 07:08:35 +01:00
}
2011-12-29 15:14:01 +01:00
}
assert ( deleted = = 1 ) ;
}
/**Function*************************************************************
Synopsis [ Check if the structure is dominant or not . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int ABC_NtkRecIsDominant ( char * delayFromStruct , char * delayFromTable , int nVar )
{
int i ;
for ( i = 0 ; i < nVar ; i + + )
{
if ( delayFromStruct [ i ] > delayFromTable [ i ] )
return 0 ;
}
return 1 ;
}
/**Function*************************************************************
Synopsis [ Sweep the dominated structures . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkRecSweepDominance ( Abc_ManRec_t * p , Rec_Obj_t * previous , Rec_Obj_t * current , char * delayFromStruct , int nVars , int fTrim )
{
Abc_Obj_t * pObj ;
while ( current ! = NULL )
{
if ( ABC_NtkRecIsDominant ( delayFromStruct , current - > pinToPinDelay , nVars ) )
{
pObj = current - > obj ;
previous - > pNext = current - > pNext ;
current - > pNext = NULL ;
Mem_FixedEntryRecycle ( p - > pMemObj , ( char * ) current ) ;
current = previous - > pNext ;
p - > nAdded - - ;
// if filter the library is needed, then point the PO to a constant.
if ( fTrim )
Abc_NtkRecDeleteSubGragh ( p , pObj ) ;
}
else
{
previous = current ;
current = current - > pNext ;
}
}
}
/**Function*************************************************************
Synopsis [ Insert a structure into the look up table . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkRecInsertToLookUpTable ( Abc_ManRec_t * p , Rec_Obj_t * * ppSpot , Abc_Obj_t * pObj , int nVars , int fTrim )
{
char delayFromStruct [ 16 ] ;
2012-01-12 07:08:35 +01:00
int i ;
2011-12-29 15:14:01 +01:00
Abc_Obj_t * pLeaf ;
Rec_Obj_t * entry , * previous = NULL , * current = * ppSpot ;
unsigned char costFromStruct = If_CutAreaRecComput_rec ( pObj ) ;
Abc_LookUpStatus_t result ;
for ( i = 0 ; i < nVars ; i + + )
{
pLeaf = Abc_NtkPi ( p - > pNtk , i ) ;
pLeaf = Abc_ObjRegular ( pLeaf ) ;
delayFromStruct [ i ] = If_CutDepthRecComput_rec ( pObj , pLeaf - > Id ) ;
2012-01-12 07:08:35 +01:00
}
if ( fTrim )
{
while ( 1 )
2011-12-29 15:14:01 +01:00
{
2012-01-12 07:08:35 +01:00
if ( current = = NULL )
2011-12-29 15:14:01 +01:00
{
2012-01-12 07:08:35 +01:00
p - > nAdded + + ;
entry = Rec_ObjAlloc ( p , pObj , delayFromStruct , costFromStruct , nVars ) ;
if ( previous ! = NULL )
{
previous - > pNext = entry ;
}
else
{
// new functional class found
p - > nAddedFuncs + + ;
* ppSpot = entry ;
entry - > nFrequency = 1 ;
}
break ;
2011-12-29 15:14:01 +01:00
}
2012-01-12 07:08:35 +01:00
result = ABC_NtkRecDelayCompare ( delayFromStruct , current - > pinToPinDelay , nVars ) ;
if ( result = = REC_EQUAL )
2011-12-29 15:14:01 +01:00
{
2012-01-12 07:08:35 +01:00
// when delay profile is equal, replace only if it has smaller cost.
if ( costFromStruct < current - > cost )
{
2011-12-29 15:14:01 +01:00
Abc_NtkRecDeleteSubGragh ( p , current - > obj ) ;
2012-01-12 07:08:35 +01:00
Rec_ObjSet ( p , current , pObj , delayFromStruct , costFromStruct , nVars ) ;
}
else
2011-12-29 15:14:01 +01:00
Abc_NtkRecDeleteSubGragh ( p , pObj ) ;
2012-01-12 07:08:35 +01:00
break ;
2011-12-29 15:14:01 +01:00
}
2012-01-12 07:08:35 +01:00
// when the new structure can dominate others, sweep them out of the library, delete them if required.
else if ( result = = REC_DOMINANCE )
{
2011-12-29 15:14:01 +01:00
Abc_NtkRecDeleteSubGragh ( p , current - > obj ) ;
2012-01-12 07:08:35 +01:00
Rec_ObjSet ( p , current , pObj , delayFromStruct , costFromStruct , nVars ) ;
Abc_NtkRecSweepDominance ( p , current , current - > pNext , delayFromStruct , nVars , fTrim ) ;
break ;
}
// when the new structure is domianted by an existed one, don't store it.
else if ( result = = REC_BEDOMINANCED )
{
2011-12-29 15:14:01 +01:00
Abc_NtkRecDeleteSubGragh ( p , pObj ) ;
2012-01-12 07:08:35 +01:00
break ;
}
// when the new structure's delay profile is big than the current, test the next one
else if ( result = = REC_BIG )
{
previous = current ;
current = current - > pNext ;
}
// insert the new structure to the right position, sweep the ones it can dominate.
else if ( result = = REC_SMALL )
{
p - > nAdded + + ;
entry = Rec_ObjAlloc ( p , pObj , delayFromStruct , costFromStruct , nVars ) ;
if ( previous ! = NULL )
{
previous - > pNext = entry ;
entry - > pNext = current ;
}
else
{
entry - > pNext = current ;
entry - > pCopy = ( * ppSpot ) - > pCopy ;
entry - > nFrequency = ( * ppSpot ) - > nFrequency ;
( * ppSpot ) - > pCopy = NULL ;
( * ppSpot ) - > nFrequency = 0 ;
* ppSpot = entry ;
}
Abc_NtkRecSweepDominance ( p , current , current - > pNext , delayFromStruct , nVars , fTrim ) ;
break ;
}
else
assert ( 0 ) ;
}
}
else
{
if ( current = = NULL )
{
p - > nAdded + + ;
entry = Rec_ObjAlloc ( p , pObj , delayFromStruct , costFromStruct , nVars ) ;
p - > nAddedFuncs + + ;
* ppSpot = entry ;
entry - > nFrequency = 1 ;
}
else
{
p - > nAdded + + ;
entry = Rec_ObjAlloc ( p , pObj , delayFromStruct , costFromStruct , nVars ) ;
entry - > pNext = ( * ppSpot ) - > pNext ;
( * ppSpot ) - > pNext = entry ;
}
2011-12-29 15:14:01 +01:00
}
}
/**Function*************************************************************
Synopsis [ Build up the structure using library . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Hop_Obj_t * Abc_NtkRecBuildUp_rec ( Hop_Man_t * pMan , Abc_Obj_t * pObj , Vec_Ptr_t * vNodes )
{
2012-01-12 07:08:35 +01:00
Hop_Obj_t * pRes0 , * pRes1 , * pRes ;
Abc_Obj_t * pRegular = Abc_ObjRegular ( pObj ) ;
if ( Abc_NodeIsTravIdCurrent ( pRegular ) | | pRegular - > Type = = ABC_OBJ_PI )
return ( Hop_Obj_t * ) Vec_PtrEntry ( vNodes , pRegular - > Id ) ;
Abc_NodeSetTravIdCurrent ( pRegular ) ;
pRes0 = Abc_NtkRecBuildUp_rec ( pMan , Abc_ObjFanin0 ( pRegular ) , vNodes ) ;
2011-12-29 15:14:01 +01:00
pRes0 = Hop_NotCond ( pRes0 , pRegular - > fCompl0 ) ;
2012-01-12 07:08:35 +01:00
pRes1 = Abc_NtkRecBuildUp_rec ( pMan , Abc_ObjFanin1 ( pRegular ) , vNodes ) ;
2011-12-29 15:14:01 +01:00
pRes1 = Hop_NotCond ( pRes1 , pRegular - > fCompl1 ) ;
2012-01-12 07:08:35 +01:00
pRes = Hop_And ( pMan , pRes0 , pRes1 ) ;
Vec_PtrWriteEntry ( vNodes , pRegular - > Id , pRes ) ;
return pRes ;
2011-12-29 15:14:01 +01:00
}
/**Function*************************************************************
Synopsis [ Derive the final network from the library . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Hop_Obj_t * Abc_RecToHop ( Hop_Man_t * pMan , If_Man_t * pIfMan , If_Cut_t * pCut )
{
Rec_Obj_t * pCand , * pCandMin , * * ppSpot ;
Hop_Obj_t * pHopObj ;
Abc_Obj_t * pAbcObj ;
Abc_Ntk_t * pAig = s_pMan - > pNtk ;
int nLeaves , i , DelayMin = ABC_INFINITY , Delay = - ABC_INFINITY ;
unsigned uCanonPhase ;
Vec_Ptr_t * vNodes = s_pMan - > vLabels ;
int nVars = s_pMan - > nVars ;
char pCanonPerm [ 16 ] ;
unsigned * pInOut = s_pMan - > pTemp1 ;
unsigned * pTemp = s_pMan - > pTemp2 ;
int time = clock ( ) ;
2012-01-12 07:08:35 +01:00
int fCompl = 0 ;
2011-12-29 15:14:01 +01:00
# ifdef Dervie
static FILE * pFile ;
# endif
nLeaves = If_CutLeaveNum ( pCut ) ;
2012-01-12 07:08:35 +01:00
// if (nLeaves < 3)
// return Abc_NodeTruthToHop(pMan, pIfMan, pCut);
2011-12-29 15:14:01 +01:00
Kit_TruthCopy ( pInOut , If_CutTruth ( pCut ) , pCut - > nLimit ) ;
for ( i = 0 ; i < nLeaves ; i + + )
pCanonPerm [ i ] = i ;
uCanonPhase = Kit_TruthSemiCanonicize ( pInOut , pTemp , nLeaves , pCanonPerm , ( short * ) s_pMan - > pMints ) ;
If_CutTruthStretch ( pInOut , nLeaves , nVars ) ;
ppSpot = Abc_NtkRecTableLookup ( s_pMan , pInOut , nVars ) ;
2012-01-12 07:08:35 +01:00
if ( * ppSpot = = NULL )
{
Kit_TruthNot ( pInOut , pInOut , nVars ) ;
ppSpot = Abc_NtkRecTableLookup ( s_pMan , pInOut , nVars ) ;
fCompl = 1 ;
}
2011-12-29 15:14:01 +01:00
assert ( * ppSpot ! = NULL ) ;
DelayMin = ABC_INFINITY ;
pCandMin = NULL ;
// find the best one
for ( pCand = * ppSpot ; pCand ; pCand = pCand - > pNext )
{
2012-01-12 07:08:35 +01:00
s_pMan - > nFunsDelayComput + + ;
2011-12-29 15:14:01 +01:00
Delay = If_CutComputDelay ( pIfMan , pCand , pCut , pCanonPerm , nLeaves ) ;
if ( DelayMin > Delay )
{
DelayMin = Delay ;
pCandMin = pCand ;
}
else if ( Delay = = DelayMin )
{
if ( pCand - > cost < pCandMin - > cost )
pCandMin = pCand ;
}
}
assert ( pCandMin ! = NULL ) ;
if ( s_pMan - > vLabels = = NULL )
2012-01-12 07:08:35 +01:00
s_pMan - > vLabels = Vec_PtrStart ( Abc_NtkObjNumMax ( pAig ) ) ;
else
{
Vec_PtrGrow ( s_pMan - > vLabels , Abc_NtkObjNumMax ( pAig ) ) ;
s_pMan - > vLabels - > nSize = s_pMan - > vLabels - > nCap ;
}
2011-12-29 15:14:01 +01:00
for ( i = 0 ; i < nLeaves ; i + + )
{
pAbcObj = Abc_NtkPi ( pAig , i ) ;
pHopObj = Hop_IthVar ( pMan , pCanonPerm [ i ] ) ;
pHopObj = Hop_NotCond ( pHopObj , ( ( uCanonPhase & ( 1 < < i ) ) > 0 ) ) ;
Vec_PtrWriteEntry ( s_pMan - > vLabels , pAbcObj - > Id , pHopObj ) ;
}
Abc_NtkIncrementTravId ( pAig ) ;
//derive the best structure in the library.
pHopObj = Abc_NtkRecBuildUp_rec ( pMan , pCandMin - > obj , s_pMan - > vLabels ) ;
s_pMan - > timeIfDerive + = clock ( ) - time ;
s_pMan - > timeIfTotal + = clock ( ) - time ;
2012-01-12 07:08:35 +01:00
return Hop_NotCond ( pHopObj , ( pCut - > fCompl ) ^ ( ( ( uCanonPhase & ( 1 < < nLeaves ) ) > 0 ) ) ^ fCompl ) ;
2011-12-29 15:14:01 +01:00
}
2011-12-30 03:54:30 +01:00
/**Function*************************************************************
Synopsis [ Duplicates non - danglingn nodes and POs driven by constants . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkDupWithoutDangling_rec ( Abc_Ntk_t * pNtkNew , Abc_Obj_t * pObj )
{
if ( pObj - > pCopy ! = NULL )
return ;
assert ( Abc_ObjIsNode ( pObj ) ) ;
Abc_NtkDupWithoutDangling_rec ( pNtkNew , Abc_ObjFanin0 ( pObj ) ) ;
Abc_NtkDupWithoutDangling_rec ( pNtkNew , Abc_ObjFanin1 ( pObj ) ) ;
pObj - > pCopy = Abc_AigAnd ( ( Abc_Aig_t * ) pNtkNew - > pManFunc , Abc_ObjChild0Copy ( pObj ) , Abc_ObjChild1Copy ( pObj ) ) ;
}
/**Function*************************************************************
Synopsis [ Duplicates non - danglingn nodes and POs driven by constants . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Abc_Ntk_t * Abc_NtkDupWithoutDangling ( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkNew ;
Abc_Obj_t * pObj ;
int i ;
2011-12-30 05:27:12 +01:00
assert ( Abc_NtkIsStrash ( pNtk ) ) ;
2011-12-30 03:54:30 +01:00
// start the network
pNtkNew = Abc_NtkAlloc ( pNtk - > ntkType , pNtk - > ntkFunc , 1 ) ;
// duplicate the name and the spec
pNtkNew - > pName = Extra_UtilStrsav ( pNtk - > pName ) ;
pNtkNew - > pSpec = Extra_UtilStrsav ( pNtk - > pSpec ) ;
// clean the node copy fields
Abc_NtkCleanCopy ( pNtk ) ;
// map the constant nodes
2011-12-30 05:27:12 +01:00
Abc_AigConst1 ( pNtk ) - > pCopy = Abc_AigConst1 ( pNtkNew ) ;
2011-12-30 03:54:30 +01:00
// clone PIs
Abc_NtkForEachPi ( pNtk , pObj , i )
Abc_NtkDupObj ( pNtkNew , pObj , 0 ) ;
// recursively add non-dangling logic
Abc_NtkForEachPo ( pNtk , pObj , i )
if ( Abc_ObjFanin0 ( pObj ) ! = Abc_AigConst1 ( pNtk ) )
Abc_NtkDupWithoutDangling_rec ( pNtkNew , Abc_ObjFanin0 ( pObj ) ) ;
// clone POs
Abc_NtkForEachPo ( pNtk , pObj , i )
if ( Abc_ObjFanin0 ( pObj ) ! = Abc_AigConst1 ( pNtk ) )
{
Abc_NtkDupObj ( pNtkNew , pObj , 0 ) ;
Abc_ObjAddFanin ( pObj - > pCopy , Abc_ObjFanin0 ( pObj ) - > pCopy ) ;
2011-12-30 05:36:25 +01:00
}
Abc_NtkAddDummyPiNames ( pNtkNew ) ;
Abc_NtkAddDummyPoNames ( pNtkNew ) ;
2011-12-30 05:27:12 +01:00
if ( ! Abc_NtkCheck ( pNtkNew ) )
fprintf ( stdout , " Abc_NtkDupWithoutDangling(): Network check has failed. \n " ) ;
pNtk - > pCopy = pNtkNew ;
2011-12-30 03:54:30 +01:00
return pNtkNew ;
}
2011-12-30 05:27:12 +01:00
/**Function*************************************************************
Synopsis [ Filter the library . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_RecUpdateHashTable ( )
{
Abc_ManRec_t * p = s_pMan ;
Rec_Obj_t * pEntry , * pTemp ;
int i ;
for ( i = 0 ; i < p - > nBins ; i + + )
for ( pEntry = p - > pBins [ i ] ; pEntry ; pEntry = pEntry - > pCopy )
for ( pTemp = pEntry ; pTemp ; pTemp = pTemp - > pNext )
pTemp - > obj = pTemp - > obj - > pCopy ;
}
2011-12-29 15:14:01 +01:00
/**Function*************************************************************
Synopsis [ Filter the library . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkRecFilter ( int nLimit )
{
Rec_Obj_t * previous = NULL , * entry = NULL , * pTemp ;
2012-01-12 07:08:35 +01:00
int i ;
2011-12-29 15:14:01 +01:00
Abc_Ntk_t * pNtk = s_pMan - > pNtk ;
int time = clock ( ) ;
if ( nLimit > 0 )
{
for ( i = 0 ; i < s_pMan - > nBins ; i + + )
{
previous = NULL ;
for ( entry = s_pMan - > pBins [ i ] ; entry ; entry = entry - > pCopy )
{
2012-01-12 07:08:35 +01:00
assert ( entry - > nFrequency ! = 0 ) ;
// only filter the functional classed with frequency less than nLimit.
if ( ( int ) entry - > nFrequency > nLimit )
2011-12-29 15:14:01 +01:00
{
previous = entry ;
continue ;
}
if ( previous = = NULL )
{
s_pMan - > pBins [ i ] = entry - > pCopy ;
previous = NULL ;
}
else
previous - > pCopy = entry - > pCopy ;
s_pMan - > nAddedFuncs - - ;
//delete all the subgragh.
for ( pTemp = entry ; pTemp ; pTemp = pTemp - > pNext )
2012-01-12 07:08:35 +01:00
{
2011-12-29 15:14:01 +01:00
s_pMan - > nAdded - - ;
Abc_NtkRecDeleteSubGragh ( s_pMan , pTemp - > obj ) ;
2012-01-12 07:08:35 +01:00
Mem_FixedEntryRecycle ( s_pMan - > pMemObj , ( char * ) pTemp ) ;
2011-12-29 15:14:01 +01:00
}
}
}
}
2011-12-30 03:54:30 +01:00
// remove dangling nodes and POs driven by constants
s_pMan - > pNtk = Abc_NtkDupWithoutDangling ( pNtk ) ;
2011-12-30 05:27:12 +01:00
Abc_RecUpdateHashTable ( ) ;
2011-12-30 03:54:30 +01:00
Abc_NtkDelete ( pNtk ) ;
2011-12-30 05:27:12 +01:00
// collect runtime stats
2011-12-29 15:14:01 +01:00
s_pMan - > timeTrim + = clock ( ) - time ;
s_pMan - > timeTotal + = clock ( ) - time ;
}
/**Function*************************************************************
Synopsis [ Test if the record is running . ]
2008-01-31 05:01:00 +01:00
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int Abc_NtkRecIsRunning ( )
{
return s_pMan ! = NULL ;
}
/**Function*************************************************************
2011-12-29 15:14:01 +01:00
Synopsis [ Test if the record is working in trim mode . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int Abc_NtkRecIsInTrimMode ( )
{
return ( s_pMan ! = NULL & & s_pMan - > fTrim ) ;
}
/**Function*************************************************************
Synopsis [ ]
2008-01-31 05:01:00 +01:00
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int Abc_NtkRecVarNum ( )
{
return ( s_pMan ! = NULL ) ? s_pMan - > nVars : - 1 ;
}
/**Function*************************************************************
2011-12-29 15:14:01 +01:00
Synopsis [ ]
2008-01-31 05:01:00 +01:00
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Vec_Int_t * Abc_NtkRecMemory ( )
{
return s_pMan - > vMemory ;
}
2012-01-12 07:08:35 +01:00
/**Function*************************************************************
Synopsis [ Starts the record for the given network . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkRecLibMerge ( Abc_Ntk_t * pNtk )
{
int i ;
Abc_Obj_t * pObj ;
Abc_ManRec_t * p = s_pMan ;
int clk = clock ( ) ;
if ( Abc_NtkPiNum ( pNtk ) > s_pMan - > nVars )
{
printf ( " The library has more inputs than the record. \n " ) ;
return ;
}
Abc_NtkForEachPi ( pNtk , pObj , i )
Abc_ObjSetMax ( pObj , i + 1 ) ;
Abc_AigForEachAnd ( pNtk , pObj , i )
Abc_ObjSetMax ( pObj , ABC_MAX ( Abc_ObjGetMax ( Abc_ObjFanin0 ( pObj ) ) , Abc_ObjGetMax ( Abc_ObjFanin1 ( pObj ) ) ) ) ;
// insert the PO nodes into the table
Abc_NtkForEachPo ( pNtk , pObj , i )
{
p - > nTried + + ;
//if the PO's input is a constant, skip it.
if ( Abc_ObjChild0 ( pObj ) = = Abc_ObjNot ( Abc_AigConst1 ( pNtk ) ) )
{
p - > nTrimed + + ;
continue ;
}
pObj = Abc_ObjFanin0 ( pObj ) ;
Abc_NtkRecAddFromLib ( pNtk , pObj , Abc_ObjGetMax ( pObj ) ) ;
}
Abc_NtkForEachObj ( pNtk , pObj , i )
{
Abc_ObjClearMax ( pObj ) ;
}
s_pMan - > timeMerge + = clock ( ) - clk ;
s_pMan - > timeTotal + = clock ( ) - clk ;
}
2008-01-31 05:01:00 +01:00
/**Function*************************************************************
Synopsis [ Starts the record for the given network . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-12-29 15:14:01 +01:00
void Abc_NtkRecStart ( Abc_Ntk_t * pNtk , int nVars , int nCuts , int fTrim )
2008-01-31 05:01:00 +01:00
{
Abc_ManRec_t * p ;
2011-12-29 15:14:01 +01:00
Abc_Obj_t * pObj ;
Rec_Obj_t * * ppSpot ;
2008-01-31 05:01:00 +01:00
char Buffer [ 10 ] ;
unsigned * pTruth ;
int i , RetValue ;
2011-12-29 15:14:01 +01:00
int clkTotal = clock ( ) , clk , timeInsert ;
int testNum = 0 ;
2008-01-31 05:01:00 +01:00
assert ( s_pMan = = NULL ) ;
if ( pNtk = = NULL )
{
assert ( nVars > 2 & & nVars < = 16 ) ;
pNtk = Abc_NtkAlloc ( ABC_NTK_STRASH , ABC_FUNC_AIG , 1 ) ;
pNtk - > pName = Extra_UtilStrsav ( " record " ) ;
}
else
{
if ( Abc_NtkGetChoiceNum ( pNtk ) > 0 )
{
printf ( " The starting record should be a network without choice nodes. \n " ) ;
return ;
}
if ( Abc_NtkPiNum ( pNtk ) > 16 )
{
printf ( " The starting record should be a network with no more than %d primary inputs. \n " , 16 ) ;
return ;
}
if ( Abc_NtkPiNum ( pNtk ) > nVars )
printf ( " The starting record has %d inputs (warning only). \n " , Abc_NtkPiNum ( pNtk ) ) ;
pNtk = Abc_NtkDup ( pNtk ) ;
}
// create the primary inputs
for ( i = Abc_NtkPiNum ( pNtk ) ; i < nVars ; i + + )
{
pObj = Abc_NtkCreatePi ( pNtk ) ;
Buffer [ 0 ] = ' a ' + i ;
Buffer [ 1 ] = 0 ;
Abc_ObjAssignName ( pObj , Buffer , NULL ) ;
}
Abc_NtkCleanCopy ( pNtk ) ;
Abc_NtkCleanEquiv ( pNtk ) ;
// start the manager
2009-02-15 17:01:00 +01:00
p = ABC_ALLOC ( Abc_ManRec_t , 1 ) ;
2008-01-31 05:01:00 +01:00
memset ( p , 0 , sizeof ( Abc_ManRec_t ) ) ;
p - > pNtk = pNtk ;
p - > nVars = Abc_NtkPiNum ( pNtk ) ;
p - > nWords = Kit_TruthWordNum ( p - > nVars ) ;
p - > nCuts = nCuts ;
p - > nVarsInit = nVars ;
2011-12-29 15:14:01 +01:00
p - > recObjSize = sizeof ( Rec_Obj_t ) + sizeof ( char ) * p - > nVars ;
p - > pMemObj = Mem_FixedStart ( p - > recObjSize ) ;
p - > fTrim = fTrim ;
2008-01-31 05:01:00 +01:00
// create elementary truth tables
p - > vTtElems = Vec_PtrAlloc ( 0 ) ; assert ( p - > vTtElems - > pArray = = NULL ) ;
p - > vTtElems - > nSize = p - > nVars ;
p - > vTtElems - > nCap = p - > nVars ;
2011-12-07 01:06:59 +01:00
p - > vTtElems - > pArray = ( void * * ) Extra_TruthElementary ( p - > nVars ) ;
2011-12-09 09:37:05 +01:00
/*
2008-01-31 05:01:00 +01:00
// allocate room for node truth tables
if ( Abc_NtkObjNum ( pNtk ) > ( 1 < < 14 ) )
p - > vTtNodes = Vec_PtrAllocSimInfo ( 2 * Abc_NtkObjNum ( pNtk ) , p - > nWords ) ;
else
p - > vTtNodes = Vec_PtrAllocSimInfo ( 1 < < 14 , p - > nWords ) ;
2011-12-09 09:37:05 +01:00
*/
p - > vTtNodes = Vec_PtrAlloc ( 1000 ) ;
2011-12-30 07:11:52 +01:00
p - > pMmTruth = Mem_FixedStart ( sizeof ( unsigned ) * p - > nWords ) ;
2011-12-09 09:37:05 +01:00
for ( i = 0 ; i < Abc_NtkObjNumMax ( pNtk ) ; i + + )
2011-12-30 07:11:52 +01:00
// Vec_PtrPush( p->vTtNodes, ABC_ALLOC(unsigned, p->nWords) );
Vec_PtrPush ( p - > vTtNodes , Mem_FixedEntryFetch ( p - > pMmTruth ) ) ;
2008-01-31 05:01:00 +01:00
// create hash table
2011-12-29 15:14:01 +01:00
//p->nBins = 50011;
p - > nBins = 500011 ;
p - > pBins = ABC_ALLOC ( Rec_Obj_t * , p - > nBins ) ;
memset ( p - > pBins , 0 , sizeof ( Rec_Obj_t * ) * p - > nBins ) ;
2008-01-31 05:01:00 +01:00
// set elementary tables
2011-12-07 01:06:59 +01:00
Kit_TruthFill ( ( unsigned * ) Vec_PtrEntry ( p - > vTtNodes , 0 ) , p - > nVars ) ;
2008-01-31 05:01:00 +01:00
Abc_NtkForEachPi ( pNtk , pObj , i )
2011-12-07 01:06:59 +01:00
Kit_TruthCopy ( ( unsigned * ) Vec_PtrEntry ( p - > vTtNodes , pObj - > Id ) , ( unsigned * ) Vec_PtrEntry ( p - > vTtElems , i ) , p - > nVars ) ;
2008-01-31 05:01:00 +01:00
// compute the tables
clk = clock ( ) ;
2011-12-29 15:14:01 +01:00
2008-01-31 05:01:00 +01:00
Abc_AigForEachAnd ( pNtk , pObj , i )
{
RetValue = Abc_NtkRecComputeTruth ( pObj , p - > vTtNodes , p - > nVars ) ;
assert ( RetValue ) ;
}
p - > timeTruth + = clock ( ) - clk ;
2011-12-29 15:14:01 +01:00
Abc_NtkForEachPi ( pNtk , pObj , i )
Abc_ObjSetMax ( pObj , i + 1 ) ;
Abc_AigForEachAnd ( pNtk , pObj , i )
Abc_ObjSetMax ( pObj , ABC_MAX ( Abc_ObjGetMax ( Abc_ObjFanin0 ( pObj ) ) , Abc_ObjGetMax ( Abc_ObjFanin1 ( pObj ) ) ) ) ;
2008-01-31 05:01:00 +01:00
// insert the PO nodes into the table
2011-12-29 15:14:01 +01:00
timeInsert = clock ( ) ;
2008-01-31 05:01:00 +01:00
Abc_NtkForEachPo ( pNtk , pObj , i )
{
p - > nTried + + ;
2011-12-29 15:14:01 +01:00
//if the PO's input is a constant, skip it.
if ( Abc_ObjChild0 ( pObj ) = = Abc_ObjNot ( Abc_AigConst1 ( pNtk ) ) )
{
p - > nTrimed + + ;
continue ;
2012-01-12 07:08:35 +01:00
}
pObj = Abc_ObjFanin0 ( pObj ) ;
2011-12-07 01:06:59 +01:00
pTruth = ( unsigned * ) Vec_PtrEntry ( p - > vTtNodes , pObj - > Id ) ;
2008-01-31 05:01:00 +01:00
// add the resulting truth table to the hash table
ppSpot = Abc_NtkRecTableLookup ( p , pTruth , p - > nVars ) ;
2011-12-29 15:14:01 +01:00
Abc_NtkRecInsertToLookUpTable ( p , ppSpot , pObj , Abc_ObjGetMax ( pObj ) , p - > fTrim ) ;
}
p - > timeInsert + = clock ( ) - timeInsert ;
Abc_NtkForEachObj ( pNtk , pObj , i )
{
Abc_ObjClearMax ( pObj ) ;
2008-01-31 05:01:00 +01:00
}
// temporaries
2009-02-15 17:01:00 +01:00
p - > pBytes = ABC_ALLOC ( int , 4 * p - > nWords ) ;
p - > pMints = ABC_ALLOC ( int , 2 * p - > nVars ) ;
p - > pTemp1 = ABC_ALLOC ( unsigned , p - > nWords ) ;
p - > pTemp2 = ABC_ALLOC ( unsigned , p - > nWords ) ;
2008-01-31 05:01:00 +01:00
p - > vNodes = Vec_PtrAlloc ( 100 ) ;
2012-01-12 07:08:35 +01:00
p - > vTtTemps = Vec_PtrAllocSimInfo ( 1024 , p - > nWords ) ;
2008-01-31 05:01:00 +01:00
p - > vMemory = Vec_IntAlloc ( Abc_TruthWordNum ( p - > nVars ) * 1000 ) ;
// set the manager
s_pMan = p ;
2011-12-29 15:14:01 +01:00
p - > timeTotal + = clock ( ) - clkTotal ;
2008-01-31 05:01:00 +01:00
}
2011-12-09 09:37:05 +01:00
/**Function*************************************************************
Synopsis [ Dump truth tables into a file . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkRecDumpTruthTables ( Abc_ManRec_t * p )
{
2011-12-09 10:05:18 +01:00
int nVars = 10 ;
2011-12-09 09:37:05 +01:00
FILE * pFile ;
2011-12-29 15:14:01 +01:00
Rec_Obj_t * pObj ;
2011-12-09 09:37:05 +01:00
unsigned * pTruth ;
int i ;
2011-12-09 10:05:18 +01:00
pFile = fopen ( " tt10.txt " , " wb " ) ;
2011-12-09 09:37:05 +01:00
for ( i = 0 ; i < p - > nBins ; i + + )
for ( pObj = p - > pBins [ i ] ; pObj ; pObj = pObj - > pCopy )
{
2011-12-29 15:14:01 +01:00
pTruth = Vec_PtrEntry ( p - > vTtNodes , pObj - > Id ) ;
2011-12-09 10:05:18 +01:00
if ( ( int ) Kit_TruthSupport ( pTruth , nVars ) ! = ( 1 < < nVars ) - 1 )
2011-12-09 09:37:05 +01:00
continue ;
2011-12-09 10:05:18 +01:00
Extra_PrintHex ( pFile , pTruth , nVars ) ;
2011-12-09 09:37:05 +01:00
fprintf ( pFile , " " ) ;
2011-12-09 10:05:18 +01:00
Kit_DsdPrintFromTruth2 ( pFile , pTruth , nVars ) ;
2011-12-09 09:37:05 +01:00
fprintf ( pFile , " \n " ) ;
}
fclose ( pFile ) ;
}
2008-01-31 05:01:00 +01:00
/**Function*************************************************************
Synopsis [ Returns the given record . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkRecStop ( )
{
assert ( s_pMan ! = NULL ) ;
2011-12-09 10:05:18 +01:00
// Abc_NtkRecDumpTruthTables( s_pMan );
2008-01-31 05:01:00 +01:00
if ( s_pMan - > pNtk )
Abc_NtkDelete ( s_pMan - > pNtk ) ;
2011-12-30 07:11:52 +01:00
// Vec_PtrFreeFree( s_pMan->vTtNodes );
Mem_FixedStop ( s_pMan - > pMmTruth , 0 ) ;
Vec_PtrFree ( s_pMan - > vTtNodes ) ;
2008-01-31 05:01:00 +01:00
Vec_PtrFree ( s_pMan - > vTtElems ) ;
2009-02-15 17:01:00 +01:00
ABC_FREE ( s_pMan - > pBins ) ;
2008-01-31 05:01:00 +01:00
// temporaries
2009-02-15 17:01:00 +01:00
ABC_FREE ( s_pMan - > pBytes ) ;
ABC_FREE ( s_pMan - > pMints ) ;
ABC_FREE ( s_pMan - > pTemp1 ) ;
ABC_FREE ( s_pMan - > pTemp2 ) ;
2008-01-31 05:01:00 +01:00
Vec_PtrFree ( s_pMan - > vNodes ) ;
Vec_PtrFree ( s_pMan - > vTtTemps ) ;
if ( s_pMan - > vLabels )
Vec_PtrFree ( s_pMan - > vLabels ) ;
if ( s_pMan - > vCosts )
Vec_StrFree ( s_pMan - > vCosts ) ;
2011-12-29 15:14:01 +01:00
if ( s_pMan - > pMemObj )
Mem_FixedStop ( s_pMan - > pMemObj , 0 ) ;
2008-01-31 05:01:00 +01:00
Vec_IntFree ( s_pMan - > vMemory ) ;
2012-01-12 07:08:35 +01:00
// if(s_pMan->vFiltered)
// Vec_StrFree(s_pMan->vFiltered);
2011-12-29 15:14:01 +01:00
2009-02-15 17:01:00 +01:00
ABC_FREE ( s_pMan ) ;
2008-01-31 05:01:00 +01:00
s_pMan = NULL ;
}
/**Function*************************************************************
Synopsis [ Returns the given record . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Abc_Ntk_t * Abc_NtkRecUse ( )
{
Abc_ManRec_t * p = s_pMan ;
Abc_Ntk_t * pNtk = p - > pNtk ;
assert ( p ! = NULL ) ;
Abc_NtkRecPs ( ) ;
p - > pNtk = NULL ;
Abc_NtkRecStop ( ) ;
2011-12-06 23:29:32 +01:00
Abc_NtkCleanData ( pNtk ) ;
2008-01-31 05:01:00 +01:00
return pNtk ;
}
/**Function*************************************************************
Synopsis [ Print statistics about the current record . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkRecPs ( )
{
int Counter , Counters [ 17 ] = { 0 } ;
int CounterS , CountersS [ 17 ] = { 0 } ;
Abc_ManRec_t * p = s_pMan ;
Abc_Ntk_t * pNtk = p - > pNtk ;
2011-12-29 15:14:01 +01:00
Rec_Obj_t * pEntry , * pTemp ;
Abc_Obj_t * pObj ;
2008-01-31 05:01:00 +01:00
int i ;
2012-01-12 07:08:35 +01:00
# ifdef LibOut
FILE * pFile ;
unsigned * pTruth ;
Rec_Obj_t * entry ;
int j ;
int nVars = 6 ;
# endif
2008-01-31 05:01:00 +01:00
// set the max PI number
Abc_NtkForEachPi ( pNtk , pObj , i )
Abc_ObjSetMax ( pObj , i + 1 ) ;
Abc_AigForEachAnd ( pNtk , pObj , i )
Abc_ObjSetMax ( pObj , ABC_MAX ( Abc_ObjGetMax ( Abc_ObjFanin0 ( pObj ) ) , Abc_ObjGetMax ( Abc_ObjFanin1 ( pObj ) ) ) ) ;
2012-01-12 07:08:35 +01:00
# ifdef LibOut
pFile = fopen ( " tt10.txt " , " wb " ) ;
for ( i = 0 ; i < p - > nBins ; i + + )
for ( entry = p - > pBins [ i ] ; entry ; entry = entry - > pCopy )
{
int tmp = 0 ;
pTruth = Vec_PtrEntry ( p - > vTtNodes , entry - > Id ) ;
/*if ( (int)Kit_TruthSupport(pTruth, nVars) != (1<<nVars)-1 )
continue ; */
Extra_PrintHex ( pFile , pTruth , nVars ) ;
fprintf ( pFile , " : nVars: %d, Frequency:%d : " , Abc_ObjGetMax ( entry - > obj ) , entry - > nFrequency ) ;
Kit_DsdPrintFromTruth2 ( pFile , pTruth , Abc_ObjGetMax ( entry - > obj ) ) ;
fprintf ( pFile , " \n " ) ;
for ( pTemp = entry ; pTemp ; pTemp = pTemp - > pNext )
{
fprintf ( pFile , " %d : " , tmp ) ;
for ( j = 0 ; j < Abc_ObjGetMax ( pTemp - > obj ) ; j + + )
{
fprintf ( pFile , " %d, " , pTemp - > pinToPinDelay [ j ] ) ;
}
fprintf ( pFile , " cost = %d \n " , pTemp - > cost ) ;
tmp + + ;
}
fprintf ( pFile , " \n " ) ;
fprintf ( pFile , " \n " ) ;
}
fclose ( pFile ) ;
# endif
2008-01-31 05:01:00 +01:00
// go through the table
Counter = CounterS = 0 ;
for ( i = 0 ; i < p - > nBins ; i + + )
for ( pEntry = p - > pBins [ i ] ; pEntry ; pEntry = pEntry - > pCopy )
{
2011-12-29 15:14:01 +01:00
assert ( Abc_ObjGetMax ( pEntry - > obj ) > = 2 ) ;
Counters [ Abc_ObjGetMax ( pEntry - > obj ) ] + + ;
2008-01-31 05:01:00 +01:00
Counter + + ;
2011-12-29 15:14:01 +01:00
for ( pTemp = pEntry ; pTemp ; pTemp = pTemp - > pNext )
2008-01-31 05:01:00 +01:00
{
2011-12-29 15:14:01 +01:00
assert ( Abc_ObjGetMax ( pTemp - > obj ) = = Abc_ObjGetMax ( pEntry - > obj ) ) ;
CountersS [ Abc_ObjGetMax ( pTemp - > obj ) ] + + ;
2008-01-31 05:01:00 +01:00
CounterS + + ;
}
}
2011-12-29 15:14:01 +01:00
//printf( "Functions = %d. Expected = %d.\n", Counter, p->nAddedFuncs );
//printf( "Subgraphs = %d. Expected = %d.\n", CounterS, p->nAdded );
2008-01-31 05:01:00 +01:00
assert ( Counter = = p - > nAddedFuncs ) ;
assert ( CounterS = = p - > nAdded ) ;
// clean
Abc_NtkForEachObj ( pNtk , pObj , i )
{
Abc_ObjClearMax ( pObj ) ;
}
printf ( " The record with %d AND nodes in %d subgraphs for %d functions with %d inputs: \n " ,
Abc_NtkNodeNum ( pNtk ) , Abc_NtkPoNum ( pNtk ) , p - > nAddedFuncs , Abc_NtkPiNum ( pNtk ) ) ;
for ( i = 0 ; i < = 16 ; i + + )
{
if ( Counters [ i ] )
printf ( " Inputs = %2d. Funcs = %8d. Subgrs = %8d. Ratio = %6.2f. \n " , i , Counters [ i ] , CountersS [ i ] , 1.0 * CountersS [ i ] / Counters [ i ] ) ;
}
2011-12-07 00:37:09 +01:00
printf ( " Subgraphs tried = %10d. (%6.2f %%) \n " , p - > nTried , ! p - > nTried ? 0 : 100.0 * p - > nTried / p - > nTried ) ;
printf ( " Subgraphs filtered by support size = %10d. (%6.2f %%) \n " , p - > nFilterSize , ! p - > nTried ? 0 : 100.0 * p - > nFilterSize / p - > nTried ) ;
printf ( " Subgraphs filtered by structural redundancy = %10d. (%6.2f %%) \n " , p - > nFilterRedund , ! p - > nTried ? 0 : 100.0 * p - > nFilterRedund / p - > nTried ) ;
printf ( " Subgraphs filtered by volume = %10d. (%6.2f %%) \n " , p - > nFilterVolume , ! p - > nTried ? 0 : 100.0 * p - > nFilterVolume / p - > nTried ) ;
printf ( " Subgraphs filtered by TT redundancy = %10d. (%6.2f %%) \n " , p - > nFilterTruth , ! p - > nTried ? 0 : 100.0 * p - > nFilterTruth / p - > nTried ) ;
printf ( " Subgraphs filtered by error = %10d. (%6.2f %%) \n " , p - > nFilterError , ! p - > nTried ? 0 : 100.0 * p - > nFilterError / p - > nTried ) ;
printf ( " Subgraphs filtered by isomorphism = %10d. (%6.2f %%) \n " , p - > nFilterSame , ! p - > nTried ? 0 : 100.0 * p - > nFilterSame / p - > nTried ) ;
printf ( " Subgraphs added = %10d. (%6.2f %%) \n " , p - > nAdded , ! p - > nTried ? 0 : 100.0 * p - > nAdded / p - > nTried ) ;
printf ( " Functions added = %10d. (%6.2f %%) \n " , p - > nAddedFuncs , ! p - > nTried ? 0 : 100.0 * p - > nAddedFuncs / p - > nTried ) ;
2011-12-29 15:14:01 +01:00
if ( s_pMan - > fTrim )
printf ( " Functions trimed = %10d. (%6.2f %%) \n " , p - > nTrimed , ! p - > nTried ? 0 : 100.0 * p - > nTrimed / p - > nTried ) ;
2012-01-12 07:08:35 +01:00
p - > timeOther = p - > timeTotal - p - > timeCollect - p - > timeTruth - p - > timeCanon - p - > timeInsert - p - > timeBuild - p - > timeTrim - p - > timeMerge ;
2011-12-29 15:14:01 +01:00
ABC_PRTP ( " Collecting nodes " , p - > timeCollect , p - > timeTotal ) ;
2009-02-15 17:01:00 +01:00
ABC_PRTP ( " Computing truth " , p - > timeTruth , p - > timeTotal ) ;
ABC_PRTP ( " Canonicizing " , p - > timeCanon , p - > timeTotal ) ;
2011-12-29 15:14:01 +01:00
ABC_PRTP ( " Building " , p - > timeBuild , p - > timeTotal ) ;
2012-01-12 07:08:35 +01:00
ABC_PRTP ( " Merge " , p - > timeMerge , p - > timeTotal ) ;
2011-12-29 15:14:01 +01:00
ABC_PRTP ( " Insert " , p - > timeInsert , p - > timeTotal ) ;
if ( s_pMan - > fTrim )
ABC_PRTP ( " Filter " , p - > timeTrim , p - > timeTotal ) ;
2009-02-15 17:01:00 +01:00
ABC_PRTP ( " Other " , p - > timeOther , p - > timeTotal ) ;
ABC_PRTP ( " TOTAL " , p - > timeTotal , p - > timeTotal ) ;
2011-12-29 15:14:01 +01:00
2008-01-31 05:01:00 +01:00
if ( p - > nFunsFound )
2011-12-29 15:14:01 +01:00
{
printf ( " \n " ) ;
printf ( " During rewriting found = %d and not found = %d functions. \n " , p - > nFunsFound , p - > nFunsNotFound ) ;
printf ( " Functions tried = %10d. (%6.2f %%) \n " , p - > nFunsTried , ! p - > nFunsTried ? 0 : 100.0 * p - > nFunsTried / p - > nFunsTried ) ;
printf ( " Functions filtered by support = %10d. (%6.2f %%) \n " , p - > nFunsFilteredBysupport , ! p - > nFunsFilteredBysupport ? 0 : 100.0 * p - > nFunsFilteredBysupport / p - > nFunsTried ) ;
printf ( " Functions not found in lib = %10d. (%6.2f %%) \n " , p - > nFunsNotFound , ! p - > nFunsNotFound ? 0 : 100.0 * p - > nFunsNotFound / p - > nFunsTried ) ;
printf ( " Functions founded = %10d. (%6.2f %%) \n " , p - > nFunsFound , ! p - > nFunsFound ? 0 : 100.0 * p - > nFunsFound / p - > nFunsTried ) ;
2012-01-12 07:08:35 +01:00
printf ( " Functions delay computed = %10d. Ratio = %6.2f. \n " , p - > nFunsDelayComput , ! p - > nFunsDelayComput ? 0 : 1.0 * p - > nFunsDelayComput / p - > nFunsFound ) ;
2011-12-29 15:14:01 +01:00
p - > timeIfOther = p - > timeIfTotal - p - > timeIfCanonicize - p - > timeIfComputDelay - p - > timeIfDerive ;
ABC_PRTP ( " Canonicize " , p - > timeIfCanonicize , p - > timeIfTotal ) ;
ABC_PRTP ( " Compute Delay " , p - > timeIfComputDelay , p - > timeIfTotal ) ;
ABC_PRTP ( " Derive " , p - > timeIfDerive , p - > timeIfTotal ) ;
ABC_PRTP ( " Other " , p - > timeIfOther , p - > timeIfTotal ) ;
ABC_PRTP ( " TOTAL " , p - > timeIfTotal , p - > timeIfTotal ) ;
}
2008-01-31 05:01:00 +01:00
}
/**Function*************************************************************
Synopsis [ Returns the hash key . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static inline unsigned Abc_NtkRecTableHash ( unsigned * pTruth , int nVars , int nBins , int * pPrimes )
{
int i , nWords = Kit_TruthWordNum ( nVars ) ;
unsigned uHash = 0 ;
for ( i = 0 ; i < nWords ; i + + )
uHash ^ = pTruth [ i ] * pPrimes [ i & 0x7 ] ;
return uHash % nBins ;
}
/**Function*************************************************************
Synopsis [ Returns the given record . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-12-29 15:14:01 +01:00
Rec_Obj_t * * Abc_NtkRecTableLookup ( Abc_ManRec_t * p , unsigned * pTruth , int nVars )
2008-01-31 05:01:00 +01:00
{
static int s_Primes [ 10 ] = { 1291 , 1699 , 2357 , 4177 , 5147 , 5647 , 6343 , 7103 , 7873 , 8147 } ;
2011-12-29 15:14:01 +01:00
Rec_Obj_t * * ppSpot , * pEntry ;
2008-01-31 05:01:00 +01:00
ppSpot = p - > pBins + Abc_NtkRecTableHash ( pTruth , nVars , p - > nBins , s_Primes ) ;
for ( pEntry = * ppSpot ; pEntry ; ppSpot = & pEntry - > pCopy , pEntry = pEntry - > pCopy )
2011-12-07 01:06:59 +01:00
if ( Kit_TruthIsEqualWithPhase ( ( unsigned * ) Vec_PtrEntry ( p - > vTtNodes , pEntry - > Id ) , pTruth , nVars ) )
2008-01-31 05:01:00 +01:00
return ppSpot ;
return ppSpot ;
}
/**Function*************************************************************
Synopsis [ Computes the truth table of the node . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int Abc_NtkRecComputeTruth ( Abc_Obj_t * pObj , Vec_Ptr_t * vTtNodes , int nVars )
{
unsigned * pTruth , * pTruth0 , * pTruth1 ;
int RetValue ;
assert ( Abc_ObjIsNode ( pObj ) ) ;
2011-12-07 01:06:59 +01:00
pTruth = ( unsigned * ) Vec_PtrEntry ( vTtNodes , pObj - > Id ) ;
pTruth0 = ( unsigned * ) Vec_PtrEntry ( vTtNodes , Abc_ObjFaninId0 ( pObj ) ) ;
pTruth1 = ( unsigned * ) Vec_PtrEntry ( vTtNodes , Abc_ObjFaninId1 ( pObj ) ) ;
2008-01-31 05:01:00 +01:00
Kit_TruthAndPhase ( pTruth , pTruth0 , pTruth1 , nVars , Abc_ObjFaninC0 ( pObj ) , Abc_ObjFaninC1 ( pObj ) ) ;
assert ( ( pTruth [ 0 ] & 1 ) = = pObj - > fPhase ) ;
RetValue = ( ( pTruth [ 0 ] & 1 ) = = pObj - > fPhase ) ;
return RetValue ;
}
/**Function*************************************************************
Synopsis [ Performs renoding as technology mapping . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkRecAdd ( Abc_Ntk_t * pNtk )
{
extern Abc_Ntk_t * Abc_NtkIf ( Abc_Ntk_t * pNtk , If_Par_t * pPars ) ;
extern int Abc_NtkRecAddCut ( If_Man_t * pIfMan , If_Obj_t * pRoot , If_Cut_t * pCut ) ;
If_Par_t Pars , * pPars = & Pars ;
Abc_Ntk_t * pNtkNew ;
int clk = clock ( ) ;
if ( Abc_NtkGetChoiceNum ( pNtk ) )
printf ( " Performing renoding with choices. \n " ) ;
// set defaults
memset ( pPars , 0 , sizeof ( If_Par_t ) ) ;
// user-controlable paramters
pPars - > nLutSize = s_pMan - > nVarsInit ;
pPars - > nCutsMax = s_pMan - > nCuts ;
pPars - > nFlowIters = 0 ;
pPars - > nAreaIters = 0 ;
pPars - > DelayTarget = - 1 ;
2008-05-17 17:01:00 +02:00
pPars - > Epsilon = ( float ) 0.005 ;
2008-01-31 05:01:00 +01:00
pPars - > fPreprocess = 0 ;
pPars - > fArea = 1 ;
pPars - > fFancy = 0 ;
pPars - > fExpRed = 0 ;
pPars - > fLatchPaths = 0 ;
pPars - > fSeqMap = 0 ;
pPars - > fVerbose = 0 ;
// internal parameters
pPars - > fTruth = 0 ;
pPars - > fUsePerm = 0 ;
pPars - > nLatches = 0 ;
pPars - > pLutLib = NULL ; // Abc_FrameReadLibLut();
pPars - > pTimesArr = NULL ;
pPars - > pTimesArr = NULL ;
pPars - > fUseBdds = 0 ;
pPars - > fUseSops = 0 ;
pPars - > fUseCnfs = 0 ;
pPars - > fUseMv = 0 ;
2012-01-12 07:08:35 +01:00
pPars - > fSkipCutFilter = 1 ;
2008-01-31 05:01:00 +01:00
pPars - > pFuncCost = NULL ;
pPars - > pFuncUser = Abc_NtkRecAddCut ;
// perform recording
pNtkNew = Abc_NtkIf ( pNtk , pPars ) ;
Abc_NtkDelete ( pNtkNew ) ;
s_pMan - > timeTotal + = clock ( ) - clk ;
// if ( !Abc_NtkCheck( s_pMan->pNtk ) )
// printf( "Abc_NtkRecAdd: The network check has failed.\n" );
}
/**Function*************************************************************
Synopsis [ Adds the cut function to the internal storage . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkRecCollectNodes_rec ( If_Obj_t * pNode , Vec_Ptr_t * vNodes )
{
if ( pNode - > fMark )
return ;
pNode - > fMark = 1 ;
assert ( If_ObjIsAnd ( pNode ) ) ;
Abc_NtkRecCollectNodes_rec ( If_ObjFanin0 ( pNode ) , vNodes ) ;
Abc_NtkRecCollectNodes_rec ( If_ObjFanin1 ( pNode ) , vNodes ) ;
Vec_PtrPush ( vNodes , pNode ) ;
}
2012-01-12 07:08:35 +01:00
/**Function*************************************************************
Synopsis [ Adds the cut function to the internal storage . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkRecCollectNodesFromLib_rec ( Abc_Obj_t * pNode , Vec_Ptr_t * vNodes )
{
if ( Abc_ObjIsPi ( pNode ) )
return ;
Abc_NtkRecCollectNodesFromLib_rec ( Abc_ObjFanin0 ( pNode ) , vNodes ) ;
Abc_NtkRecCollectNodesFromLib_rec ( Abc_ObjFanin1 ( pNode ) , vNodes ) ;
Vec_PtrPush ( vNodes , pNode ) ;
}
2008-01-31 05:01:00 +01:00
/**Function*************************************************************
Synopsis [ Adds the cut function to the internal storage . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int Abc_NtkRecCollectNodes ( If_Man_t * pIfMan , If_Obj_t * pRoot , If_Cut_t * pCut , Vec_Ptr_t * vNodes )
{
If_Obj_t * pLeaf ;
int i , RetValue = 1 ;
// collect the internal nodes of the cut
Vec_PtrClear ( vNodes ) ;
If_CutForEachLeaf ( pIfMan , pCut , pLeaf , i )
{
Vec_PtrPush ( vNodes , pLeaf ) ;
assert ( pLeaf - > fMark = = 0 ) ;
pLeaf - > fMark = 1 ;
}
// collect other nodes
Abc_NtkRecCollectNodes_rec ( pRoot , vNodes ) ;
// check if there are leaves, such that both of their fanins are marked
// this indicates a redundant cut
If_CutForEachLeaf ( pIfMan , pCut , pLeaf , i )
{
if ( ! If_ObjIsAnd ( pLeaf ) )
continue ;
if ( If_ObjFanin0 ( pLeaf ) - > fMark & & If_ObjFanin1 ( pLeaf ) - > fMark )
{
RetValue = 0 ;
break ;
}
}
// clean the mark
2010-11-01 09:35:04 +01:00
Vec_PtrForEachEntry ( If_Obj_t * , vNodes , pLeaf , i )
2008-01-31 05:01:00 +01:00
pLeaf - > fMark = 0 ;
/*
if ( pRoot - > Id = = 2639 )
{
// print the cut
2010-11-01 09:35:04 +01:00
Vec_PtrForEachEntry ( If_Obj_t * , vNodes , pLeaf , i )
2008-01-31 05:01:00 +01:00
{
if ( If_ObjIsAnd ( pLeaf ) )
printf ( " %4d = %c%4d & %c%4d \n " , pLeaf - > Id ,
( If_ObjFaninC0 ( pLeaf ) ? ' - ' : ' + ' ) , If_ObjFanin0 ( pLeaf ) - > Id ,
( If_ObjFaninC1 ( pLeaf ) ? ' - ' : ' + ' ) , If_ObjFanin1 ( pLeaf ) - > Id ) ;
else
printf ( " %4d = pi \n " , pLeaf - > Id ) ;
}
printf ( " \n " ) ;
}
*/
return RetValue ;
}
2012-01-12 07:08:35 +01:00
/**Function*************************************************************
Synopsis [ Adds the cut function to the internal storage . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkRecCollectNodesFromLib ( Abc_Ntk_t * pNtk , Abc_Obj_t * pRoot , Vec_Ptr_t * vNodes , int nVars )
{
int i ;
// collect the internal nodes of the cut
Vec_PtrClear ( vNodes ) ;
for ( i = 0 ; i < nVars ; i + + )
Vec_PtrPush ( vNodes , Abc_NtkPi ( pNtk , i ) ) ;
// collect other nodes
Abc_NtkRecCollectNodesFromLib_rec ( pRoot , vNodes ) ;
}
2008-01-31 05:01:00 +01:00
/**Function*************************************************************
Synopsis [ Computes truth tables of nodes in the cut . ]
Description [ Returns 0 if the TT does not depend on some cut variables .
Or if the TT can be expressed simpler using other nodes . ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int Abc_NtkRecCutTruth ( Vec_Ptr_t * vNodes , int nLeaves , Vec_Ptr_t * vTtTemps , Vec_Ptr_t * vTtElems )
{
unsigned * pSims , * pSims0 , * pSims1 ;
unsigned * pTemp = s_pMan - > pTemp2 ;
unsigned uWord ;
If_Obj_t * pObj , * pObj2 , * pRoot ;
int i , k , nLimit , nInputs = s_pMan - > nVars ;
assert ( Vec_PtrSize ( vNodes ) > nLeaves ) ;
// set the elementary truth tables and compute the truth tables of the nodes
2010-11-01 09:35:04 +01:00
Vec_PtrForEachEntry ( If_Obj_t * , vNodes , pObj , i )
2008-01-31 05:01:00 +01:00
{
pObj - > pCopy = Vec_PtrEntry ( vTtTemps , i ) ;
pSims = ( unsigned * ) pObj - > pCopy ;
if ( i < nLeaves )
{
2011-12-07 01:06:59 +01:00
Kit_TruthCopy ( pSims , ( unsigned * ) Vec_PtrEntry ( vTtElems , i ) , nInputs ) ;
2008-01-31 05:01:00 +01:00
continue ;
}
assert ( If_ObjIsAnd ( pObj ) ) ;
// get hold of the simulation information
pSims0 = ( unsigned * ) If_ObjFanin0 ( pObj ) - > pCopy ;
pSims1 = ( unsigned * ) If_ObjFanin1 ( pObj ) - > pCopy ;
// simulate the node
Kit_TruthAndPhase ( pSims , pSims0 , pSims1 , nInputs , If_ObjFaninC0 ( pObj ) , If_ObjFaninC1 ( pObj ) ) ;
}
// check the support size
2011-12-07 01:06:59 +01:00
pRoot = ( If_Obj_t * ) Vec_PtrEntryLast ( vNodes ) ;
2008-01-31 05:01:00 +01:00
pSims = ( unsigned * ) pRoot - > pCopy ;
if ( Kit_TruthSupport ( pSims , nInputs ) ! = Kit_BitMask ( nLeaves ) )
return 0 ;
// make sure none of the nodes has the same simulation info as the output
// check pairwise comparisons
nLimit = Vec_PtrSize ( vNodes ) - 1 ;
2010-11-01 09:35:04 +01:00
Vec_PtrForEachEntryStop ( If_Obj_t * , vNodes , pObj , i , nLimit )
2008-01-31 05:01:00 +01:00
{
pSims0 = ( unsigned * ) pObj - > pCopy ;
if ( Kit_TruthIsEqualWithPhase ( pSims , pSims0 , nInputs ) )
return 0 ;
2010-11-01 09:35:04 +01:00
Vec_PtrForEachEntryStop ( If_Obj_t * , vNodes , pObj2 , k , i )
2008-01-31 05:01:00 +01:00
{
if ( ( If_ObjFanin0 ( pRoot ) = = pObj & & If_ObjFanin1 ( pRoot ) = = pObj2 ) | |
( If_ObjFanin1 ( pRoot ) = = pObj & & If_ObjFanin0 ( pRoot ) = = pObj2 ) )
continue ;
pSims1 = ( unsigned * ) pObj2 - > pCopy ;
uWord = pSims0 [ 0 ] & pSims1 [ 0 ] ;
if ( pSims [ 0 ] = = uWord | | pSims [ 0 ] = = ~ uWord )
{
Kit_TruthAndPhase ( pTemp , pSims0 , pSims1 , nInputs , 0 , 0 ) ;
if ( Kit_TruthIsEqualWithPhase ( pSims , pTemp , nInputs ) )
return 0 ;
}
uWord = pSims0 [ 0 ] & ~ pSims1 [ 0 ] ;
if ( pSims [ 0 ] = = uWord | | pSims [ 0 ] = = ~ uWord )
{
Kit_TruthAndPhase ( pTemp , pSims0 , pSims1 , nInputs , 0 , 1 ) ;
if ( Kit_TruthIsEqualWithPhase ( pSims , pTemp , nInputs ) )
return 0 ;
}
uWord = ~ pSims0 [ 0 ] & pSims1 [ 0 ] ;
if ( pSims [ 0 ] = = uWord | | pSims [ 0 ] = = ~ uWord )
{
Kit_TruthAndPhase ( pTemp , pSims0 , pSims1 , nInputs , 1 , 0 ) ;
if ( Kit_TruthIsEqualWithPhase ( pSims , pTemp , nInputs ) )
return 0 ;
}
uWord = ~ pSims0 [ 0 ] & ~ pSims1 [ 0 ] ;
if ( pSims [ 0 ] = = uWord | | pSims [ 0 ] = = ~ uWord )
{
Kit_TruthAndPhase ( pTemp , pSims0 , pSims1 , nInputs , 1 , 1 ) ;
if ( Kit_TruthIsEqualWithPhase ( pSims , pTemp , nInputs ) )
return 0 ;
}
}
}
return 1 ;
}
2012-01-12 07:08:35 +01:00
/**Function*************************************************************
Synopsis [ Computes truth tables of nodes in the cut . ]
Description [ Returns 0 if the TT does not depend on some cut variables .
Or if the TT can be expressed simpler using other nodes . ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkRecCutTruthFromLib ( Vec_Ptr_t * vNodes , int nLeaves , Vec_Ptr_t * vTtTemps , Vec_Ptr_t * vTtElems )
{
unsigned * pSims , * pSims0 , * pSims1 ;
unsigned * pTemp = s_pMan - > pTemp2 ;
Abc_Obj_t * pObj , * pRoot ;
int i , nInputs = s_pMan - > nVars ;
assert ( Vec_PtrSize ( vNodes ) > nLeaves ) ;
// set the elementary truth tables and compute the truth tables of the nodes
Vec_PtrForEachEntry ( Abc_Obj_t * , vNodes , pObj , i )
{
pObj - > pTemp = Vec_PtrEntry ( vTtTemps , i ) ;
pSims = ( unsigned * ) pObj - > pTemp ;
if ( i < nLeaves )
{
Kit_TruthCopy ( pSims , ( unsigned * ) Vec_PtrEntry ( vTtElems , i ) , nInputs ) ;
continue ;
}
// get hold of the simulation information
pSims0 = ( unsigned * ) Abc_ObjFanin0 ( pObj ) - > pTemp ;
pSims1 = ( unsigned * ) Abc_ObjFanin1 ( pObj ) - > pTemp ;
// simulate the node
Kit_TruthAndPhase ( pSims , pSims0 , pSims1 , nInputs , Abc_ObjFaninC0 ( pObj ) , Abc_ObjFaninC1 ( pObj ) ) ;
}
// check the support size
pRoot = ( Abc_Obj_t * ) Vec_PtrEntryLast ( vNodes ) ;
pSims = ( unsigned * ) pRoot - > pTemp ;
assert ( Kit_TruthSupport ( pSims , nInputs ) = = Kit_BitMask ( nLeaves ) ) ;
}
2008-01-31 05:01:00 +01:00
/**Function*************************************************************
Synopsis [ Adds the cut function to the internal storage . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int Abc_NtkRecAddCutCheckCycle_rec ( Abc_Obj_t * pRoot , Abc_Obj_t * pObj )
{
assert ( pRoot - > Level > 0 ) ;
if ( pObj - > Level < pRoot - > Level )
return 1 ;
if ( pObj = = pRoot )
return 0 ;
if ( ! Abc_NtkRecAddCutCheckCycle_rec ( pRoot , Abc_ObjFanin0 ( pObj ) ) )
return 0 ;
if ( ! Abc_NtkRecAddCutCheckCycle_rec ( pRoot , Abc_ObjFanin1 ( pObj ) ) )
return 0 ;
return 1 ;
}
/**Function*************************************************************
Synopsis [ Adds the cut function to the internal storage . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int Abc_NtkRecAddCut ( If_Man_t * pIfMan , If_Obj_t * pRoot , If_Cut_t * pCut )
{
static int s_MaxSize [ 16 ] = { 0 } ;
char Buffer [ 40 ] , Name [ 20 ] , Truth [ 20 ] ;
char pCanonPerm [ 16 ] ;
2011-12-29 15:14:01 +01:00
Abc_Obj_t * pObj = NULL , * pFanin0 , * pFanin1 , * pObjPo ;
Rec_Obj_t * * ppSpot ;
2008-01-31 05:01:00 +01:00
Abc_Ntk_t * pAig = s_pMan - > pNtk ;
If_Obj_t * pIfObj ;
Vec_Ptr_t * vNodes = s_pMan - > vNodes ;
unsigned * pInOut = s_pMan - > pTemp1 ;
unsigned * pTemp = s_pMan - > pTemp2 ;
unsigned * pTruth ;
int i , RetValue , nNodes , nNodesBeg , nInputs = s_pMan - > nVars , nLeaves = If_CutLeaveNum ( pCut ) ;
unsigned uCanonPhase ;
2011-12-29 15:14:01 +01:00
int clk , timeInsert , timeBuild ;
2012-01-12 07:08:35 +01:00
int begin = clock ( ) ;
2008-01-31 05:01:00 +01:00
assert ( nInputs < = 16 ) ;
assert ( nInputs = = ( int ) pCut - > nLimit ) ;
s_pMan - > nTried + + ;
// skip small cuts
2011-12-29 15:14:01 +01:00
if ( nLeaves < 2 )
{
2008-01-31 05:01:00 +01:00
s_pMan - > nFilterSize + + ;
return 1 ;
2011-12-29 15:14:01 +01:00
}
2012-01-12 07:08:35 +01:00
2008-01-31 05:01:00 +01:00
// collect internal nodes and skip redundant cuts
clk = clock ( ) ;
RetValue = Abc_NtkRecCollectNodes ( pIfMan , pRoot , pCut , vNodes ) ;
2011-12-29 15:14:01 +01:00
2008-01-31 05:01:00 +01:00
s_pMan - > timeCollect + = clock ( ) - clk ;
if ( ! RetValue )
{
s_pMan - > nFilterRedund + + ;
return 1 ;
}
// skip cuts with very large volume
if ( Vec_PtrSize ( vNodes ) > nLeaves + 3 * ( nLeaves - 1 ) + s_MaxSize [ nLeaves ] )
{
s_pMan - > nFilterVolume + + ;
return 1 ;
}
// compute truth table and skip the redundant structures
clk = clock ( ) ;
RetValue = Abc_NtkRecCutTruth ( vNodes , nLeaves , s_pMan - > vTtTemps , s_pMan - > vTtElems ) ;
2011-12-29 15:14:01 +01:00
s_pMan - > timeTruth + = clock ( ) - clk ;
2008-01-31 05:01:00 +01:00
if ( ! RetValue )
{
2011-12-29 15:14:01 +01:00
//fprintf(file,"redundant structures\n");
//fclose(file);
2008-01-31 05:01:00 +01:00
s_pMan - > nFilterTruth + + ;
return 1 ;
}
// copy the truth table
Kit_TruthCopy ( pInOut , ( unsigned * ) pRoot - > pCopy , nInputs ) ;
// set permutation
2011-12-29 15:14:01 +01:00
for ( i = 0 ; i < nLeaves ; i + + )
2008-01-31 05:01:00 +01:00
pCanonPerm [ i ] = i ;
// semi-canonicize the truth table
clk = clock ( ) ;
2011-12-29 15:14:01 +01:00
uCanonPhase = Kit_TruthSemiCanonicize ( pInOut , pTemp , nLeaves , pCanonPerm , ( short * ) s_pMan - > pMints ) ;
If_CutTruthStretch ( pInOut , nLeaves , s_pMan - > nVars ) ;
s_pMan - > timeCanon + = clock ( ) - clk ;
2008-01-31 05:01:00 +01:00
// pCanonPerm and uCanonPhase show what was the variable corresponding to each var in the current truth
// go through the variables in the new truth table
2011-12-29 15:14:01 +01:00
timeBuild = clock ( ) ;
2008-01-31 05:01:00 +01:00
for ( i = 0 ; i < nLeaves ; i + + )
{
// get hold of the corresponding leaf
2008-07-02 17:01:00 +02:00
pIfObj = If_ManObj ( pIfMan , pCut - > pLeaves [ ( int ) pCanonPerm [ i ] ] ) ;
2008-01-31 05:01:00 +01:00
// get hold of the corresponding new node
pObj = Abc_NtkPi ( pAig , i ) ;
pObj = Abc_ObjNotCond ( pObj , ( uCanonPhase & ( 1 < < i ) ) ) ;
// map them
pIfObj - > pCopy = pObj ;
}
// build the node and compute its truth table
nNodesBeg = Abc_NtkObjNumMax ( pAig ) ;
2010-11-01 09:35:04 +01:00
Vec_PtrForEachEntryStart ( If_Obj_t * , vNodes , pIfObj , i , nLeaves )
2008-01-31 05:01:00 +01:00
{
2011-12-07 01:06:59 +01:00
pFanin0 = Abc_ObjNotCond ( ( Abc_Obj_t * ) If_ObjFanin0 ( pIfObj ) - > pCopy , If_ObjFaninC0 ( pIfObj ) ) ;
pFanin1 = Abc_ObjNotCond ( ( Abc_Obj_t * ) If_ObjFanin1 ( pIfObj ) - > pCopy , If_ObjFaninC1 ( pIfObj ) ) ;
2008-01-31 05:01:00 +01:00
nNodes = Abc_NtkObjNumMax ( pAig ) ;
2011-12-07 01:06:59 +01:00
pObj = Abc_AigAnd ( ( Abc_Aig_t * ) pAig - > pManFunc , pFanin0 , pFanin1 ) ;
2008-01-31 05:01:00 +01:00
assert ( ! Abc_ObjIsComplement ( pObj ) ) ;
pIfObj - > pCopy = pObj ;
if ( pObj - > Id = = nNodes )
{
// increase storage for truth tables
2011-12-09 09:37:05 +01:00
// if ( Vec_PtrSize(s_pMan->vTtNodes) <= pObj->Id )
// Vec_PtrDoubleSimInfo(s_pMan->vTtNodes);
while ( Vec_PtrSize ( s_pMan - > vTtNodes ) < = pObj - > Id )
2011-12-30 07:11:52 +01:00
// Vec_PtrPush( s_pMan->vTtNodes, ABC_ALLOC(unsigned, s_pMan->nWords) );
Vec_PtrPush ( s_pMan - > vTtNodes , Mem_FixedEntryFetch ( s_pMan - > pMmTruth ) ) ;
2011-12-09 09:37:05 +01:00
2008-01-31 05:01:00 +01:00
// compute the truth table
RetValue = Abc_NtkRecComputeTruth ( pObj , s_pMan - > vTtNodes , nInputs ) ;
if ( RetValue = = 0 )
{
s_pMan - > nFilterError + + ;
printf ( " T " ) ;
return 1 ;
}
}
}
2008-07-02 17:01:00 +02:00
assert ( pObj ) ;
2012-01-12 07:08:35 +01:00
s_pMan - > timeBuild + = clock ( ) - timeBuild ;
2011-12-07 01:06:59 +01:00
pTruth = ( unsigned * ) Vec_PtrEntry ( s_pMan - > vTtNodes , pObj - > Id ) ;
2008-01-31 05:01:00 +01:00
if ( Kit_TruthSupport ( pTruth , nInputs ) ! = Kit_BitMask ( nLeaves ) )
{
s_pMan - > nFilterError + + ;
printf ( " S " ) ;
return 1 ;
}
// compare the truth tables
if ( ! Kit_TruthIsEqualWithPhase ( pTruth , pInOut , nInputs ) )
{
s_pMan - > nFilterError + + ;
printf ( " F " ) ;
return 1 ;
}
// Extra_PrintBinary( stdout, pInOut, 8 ); printf( "\n" );
2012-01-12 07:08:35 +01:00
// look up in the hash table and increase the hit number of the functional class
ppSpot = Abc_NtkRecTableLookup ( s_pMan , pTruth , nInputs ) ;
Abc_NtkRecFrequencyInc ( * ppSpot ) ;
2008-01-31 05:01:00 +01:00
// if not new nodes were added and the node has a CO fanout
if ( nNodesBeg = = Abc_NtkObjNumMax ( pAig ) & & Abc_NodeFindCoFanout ( pObj ) ! = NULL )
{
s_pMan - > nFilterSame + + ;
2012-01-12 07:08:35 +01:00
assert ( * ppSpot ! = NULL ) ;
2008-01-31 05:01:00 +01:00
return 1 ;
}
// create PO for this node
pObjPo = Abc_NtkCreatePo ( pAig ) ;
Abc_ObjAddFanin ( pObjPo , pObj ) ;
// assign the name to this PO
sprintf ( Name , " %d_%06d " , nLeaves , Abc_NtkPoNum ( pAig ) ) ;
if ( ( nInputs < = 6 ) & & 0 )
{
Extra_PrintHexadecimalString ( Truth , pInOut , nInputs ) ;
sprintf ( Buffer , " %s_%s " , Name , Truth ) ;
}
else
{
sprintf ( Buffer , " %s " , Name ) ;
}
Abc_ObjAssignName ( pObjPo , Buffer , NULL ) ;
// add the resulting truth table to the hash table
2011-12-29 15:14:01 +01:00
timeInsert = clock ( ) ;
Abc_NtkRecInsertToLookUpTable ( s_pMan , ppSpot , pObj , nLeaves , s_pMan - > fTrim ) ;
s_pMan - > timeInsert + = clock ( ) - timeInsert ;
return 1 ;
}
2012-01-12 07:08:35 +01:00
/**Function*************************************************************
Synopsis [ Adds the cut function to the internal storage . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_NtkRecAddFromLib ( Abc_Ntk_t * pNtk , Abc_Obj_t * pRoot , int nVars )
{
char Buffer [ 40 ] , Name [ 20 ] , Truth [ 20 ] ;
Abc_Obj_t * pObj = NULL , * pFanin0 , * pFanin1 , * pObjPo ;
Rec_Obj_t * * ppSpot ;
Abc_Ntk_t * pAig = s_pMan - > pNtk ;
Abc_Obj_t * pAbcObj ;
Vec_Ptr_t * vNodes = s_pMan - > vNodes ;
unsigned * pInOut = s_pMan - > pTemp1 ;
unsigned * pTemp = s_pMan - > pTemp2 ;
unsigned * pTruth ;
int i , RetValue , nNodes , nNodesBeg , nInputs = s_pMan - > nVars , nLeaves = nVars ;
assert ( nInputs < = 16 ) ;
// collect internal nodes and skip redundant cuts
Abc_NtkRecCollectNodesFromLib ( pNtk , pRoot , vNodes , nLeaves ) ;
Abc_NtkRecCutTruthFromLib ( vNodes , nLeaves , s_pMan - > vTtTemps , s_pMan - > vTtElems ) ;
// copy the truth table
Kit_TruthCopy ( pInOut , ( unsigned * ) pRoot - > pTemp , nInputs ) ;
// go through the variables in the new truth table
for ( i = 0 ; i < nLeaves ; i + + )
{
// get hold of the corresponding leaf
pAbcObj = Abc_NtkPi ( pNtk , i ) ;
// get hold of the corresponding new node
pObj = Abc_NtkPi ( pAig , i ) ;
// map them
pAbcObj - > pCopy = pObj ;
}
// build the node and compute its truth table
nNodesBeg = Abc_NtkObjNumMax ( pAig ) ;
Vec_PtrForEachEntryStart ( Abc_Obj_t * , vNodes , pAbcObj , i , nLeaves )
{
pFanin0 = Abc_ObjNotCond ( ( Abc_Obj_t * ) Abc_ObjFanin0 ( pAbcObj ) - > pCopy , Abc_ObjFaninC0 ( pAbcObj ) ) ;
pFanin1 = Abc_ObjNotCond ( ( Abc_Obj_t * ) Abc_ObjFanin1 ( pAbcObj ) - > pCopy , Abc_ObjFaninC1 ( pAbcObj ) ) ;
nNodes = Abc_NtkObjNumMax ( pAig ) ;
pObj = Abc_AigAnd ( ( Abc_Aig_t * ) pAig - > pManFunc , pFanin0 , pFanin1 ) ;
assert ( ! Abc_ObjIsComplement ( pObj ) ) ;
pAbcObj - > pCopy = pObj ;
if ( pObj - > Id = = nNodes )
{
// increase storage for truth tables
// if ( Vec_PtrSize(s_pMan->vTtNodes) <= pObj->Id )
// Vec_PtrDoubleSimInfo(s_pMan->vTtNodes);
while ( Vec_PtrSize ( s_pMan - > vTtNodes ) < = pObj - > Id )
// Vec_PtrPush( s_pMan->vTtNodes, ABC_ALLOC(unsigned, s_pMan->nWords) );
Vec_PtrPush ( s_pMan - > vTtNodes , Mem_FixedEntryFetch ( s_pMan - > pMmTruth ) ) ;
// compute the truth table
RetValue = Abc_NtkRecComputeTruth ( pObj , s_pMan - > vTtNodes , nInputs ) ;
if ( RetValue = = 0 )
{
s_pMan - > nFilterError + + ;
printf ( " T " ) ;
}
}
}
assert ( pObj ) ;
pTruth = ( unsigned * ) Vec_PtrEntry ( s_pMan - > vTtNodes , pObj - > Id ) ;
assert ( Kit_TruthSupport ( pTruth , nInputs ) = = Kit_BitMask ( nLeaves ) ) ;
// compare the truth tables
assert ( Kit_TruthIsEqual ( pTruth , pInOut , nInputs ) ) ;
// Extra_PrintBinary( stdout, pInOut, 8 ); printf( "\n" );
// look up in the hash table and increase the hit number of the functional class
ppSpot = Abc_NtkRecTableLookup ( s_pMan , pTruth , nInputs ) ;
// if not new nodes were added and the node has a CO fanout
if ( nNodesBeg = = Abc_NtkObjNumMax ( pAig ) & & Abc_NodeFindCoFanout ( pObj ) ! = NULL )
{
s_pMan - > nFilterSame + + ;
assert ( * ppSpot ! = NULL ) ;
return ;
}
// create PO for this node
pObjPo = Abc_NtkCreatePo ( pAig ) ;
Abc_ObjAddFanin ( pObjPo , pObj ) ;
// assign the name to this PO
sprintf ( Name , " %d_%06d " , nLeaves , Abc_NtkPoNum ( pAig ) ) ;
if ( ( nInputs < = 6 ) & & 0 )
{
Extra_PrintHexadecimalString ( Truth , pInOut , nInputs ) ;
sprintf ( Buffer , " %s_%s " , Name , Truth ) ;
}
else
{
sprintf ( Buffer , " %s " , Name ) ;
}
Abc_ObjAssignName ( pObjPo , Buffer , NULL ) ;
// add the resulting truth table to the hash table
Abc_NtkRecInsertToLookUpTable ( s_pMan , ppSpot , pObj , nLeaves , s_pMan - > fTrim ) ;
}
2011-12-29 15:14:01 +01:00
/**Function*************************************************************
Synopsis [ Computes the delay using library . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int If_CutDelayRecCost ( If_Man_t * p , If_Cut_t * pCut )
{
int timeDelayComput , timeTotal = clock ( ) , timeCanonicize ;
int nLeaves , i , DelayMin = ABC_INFINITY , Delay = - ABC_INFINITY ;
char pCanonPerm [ 16 ] ;
unsigned uCanonPhase ;
unsigned * pTruthRec ;
Rec_Obj_t * pCand , * pCandMin , * * ppSpot ;
Abc_Ntk_t * pAig = s_pMan - > pNtk ;
unsigned * pInOut = s_pMan - > pTemp1 ;
unsigned * pTemp = s_pMan - > pTemp2 ;
int nVars = s_pMan - > nVars ;
assert ( s_pMan ! = NULL ) ;
nLeaves = If_CutLeaveNum ( pCut ) ;
s_pMan - > nFunsTried + + ;
assert ( nLeaves > = 2 & & nLeaves < = nVars ) ;
Kit_TruthCopy ( pInOut , If_CutTruth ( pCut ) , nLeaves ) ;
//if not every variables are in the support, skip this cut.
if ( Kit_TruthSupport ( pInOut , nLeaves ) ! = Kit_BitMask ( nLeaves ) )
{
s_pMan - > nFunsFilteredBysupport + + ;
pCut - > fUser = 1 ;
pCut - > Cost = IF_COST_MAX ;
return ABC_INFINITY ;
}
timeCanonicize = clock ( ) ;
//canonicize
for ( i = 0 ; i < nLeaves ; i + + )
pCanonPerm [ i ] = i ;
uCanonPhase = Kit_TruthSemiCanonicize ( pInOut , pTemp , nLeaves , pCanonPerm , ( short * ) s_pMan - > pMints ) ;
If_CutTruthStretch ( pInOut , nLeaves , nVars ) ;
2012-01-12 07:08:35 +01:00
s_pMan - > timeIfCanonicize + = clock ( ) - timeCanonicize ;
2011-12-29 15:14:01 +01:00
ppSpot = Abc_NtkRecTableLookup ( s_pMan , pInOut , nVars ) ;
2012-01-12 07:08:35 +01:00
if ( * ppSpot = = NULL )
{
Kit_TruthNot ( pInOut , pInOut , nVars ) ;
ppSpot = Abc_NtkRecTableLookup ( s_pMan , pInOut , nVars ) ;
}
assert ( ! ( * ppSpot = = NULL & & nLeaves = = 2 ) ) ;
2011-12-29 15:14:01 +01:00
//functional class not found in the library.
2008-01-31 05:01:00 +01:00
if ( * ppSpot = = NULL )
{
2011-12-29 15:14:01 +01:00
s_pMan - > nFunsNotFound + + ;
pCut - > Cost = IF_COST_MAX ;
pCut - > fUser = 1 ;
return ABC_INFINITY ;
2008-01-31 05:01:00 +01:00
}
2011-12-29 15:14:01 +01:00
s_pMan - > nFunsFound + + ;
// make sure the truth table is the same
pTruthRec = ( unsigned * ) Vec_PtrEntry ( s_pMan - > vTtNodes , ( * ppSpot ) - > Id ) ;
if ( ! Kit_TruthIsEqualWithPhase ( pTruthRec , pInOut , nLeaves ) )
2008-01-31 05:01:00 +01:00
{
2011-12-29 15:14:01 +01:00
assert ( 0 ) ;
return - 1 ;
s_pMan - > nIfMapError + + ;
2008-01-31 05:01:00 +01:00
}
2011-12-29 15:14:01 +01:00
// mark as user cut.
pCut - > fUser = 1 ;
DelayMin = ABC_INFINITY ;
pCandMin = NULL ;
timeDelayComput = clock ( ) ;
//find the best structure of the functional class.
for ( pCand = * ppSpot ; pCand ; pCand = pCand - > pNext )
{
s_pMan - > nFunsDelayComput + + ;
Delay = If_CutComputDelay ( p , pCand , pCut , pCanonPerm , nLeaves ) ;
if ( DelayMin > Delay )
{
// printf( "%d ", Cost );
DelayMin = Delay ;
pCandMin = pCand ;
}
else if ( Delay = = DelayMin )
{
if ( pCand - > cost < pCandMin - > cost )
pCandMin = pCand ;
}
}
s_pMan - > timeIfComputDelay + = clock ( ) - timeDelayComput ;
assert ( pCandMin ! = NULL ) ;
for ( i = 0 ; i < nLeaves ; i + + )
{
pCut - > pPerm [ pCanonPerm [ i ] ] = pCandMin - > pinToPinDelay [ i ] ;
}
s_pMan - > timeIfTotal + = clock ( ) - timeTotal ;
pCut - > Cost = pCandMin - > cost ;
return DelayMin ;
2008-01-31 05:01:00 +01:00
}
/**Function*************************************************************
Synopsis [ Labels the record AIG with the corresponding new AIG nodes . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-12-29 15:14:01 +01:00
/*Abc_Obj_t * Abc_NtkRecStrashNodeLabel_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fBuild, Vec_Ptr_t * vLabels )
2008-01-31 05:01:00 +01:00
{
Abc_Obj_t * pFanin0New , * pFanin1New , * pLabel ;
assert ( ! Abc_ObjIsComplement ( pObj ) ) ;
// if this node is already visited, skip
if ( Abc_NodeIsTravIdCurrent ( pObj ) )
2011-12-07 01:06:59 +01:00
return ( Abc_Obj_t * ) Vec_PtrEntry ( vLabels , pObj - > Id ) ;
2008-01-31 05:01:00 +01:00
assert ( Abc_ObjIsNode ( pObj ) ) ;
// mark the node as visited
Abc_NodeSetTravIdCurrent ( pObj ) ;
// label the fanins
pFanin0New = Abc_NtkRecStrashNodeLabel_rec ( pNtkNew , Abc_ObjFanin0 ( pObj ) , fBuild , vLabels ) ;
pFanin1New = Abc_NtkRecStrashNodeLabel_rec ( pNtkNew , Abc_ObjFanin1 ( pObj ) , fBuild , vLabels ) ;
// label the node if possible
pLabel = NULL ;
if ( pFanin0New & & pFanin1New )
{
pFanin0New = Abc_ObjNotCond ( pFanin0New , Abc_ObjFaninC0 ( pObj ) ) ;
pFanin1New = Abc_ObjNotCond ( pFanin1New , Abc_ObjFaninC1 ( pObj ) ) ;
if ( fBuild )
2011-12-07 01:06:59 +01:00
pLabel = Abc_AigAnd ( ( Abc_Aig_t * ) pNtkNew - > pManFunc , pFanin0New , pFanin1New ) ;
2008-01-31 05:01:00 +01:00
else
2011-12-07 01:06:59 +01:00
pLabel = Abc_AigAndLookup ( ( Abc_Aig_t * ) pNtkNew - > pManFunc , pFanin0New , pFanin1New ) ;
2008-01-31 05:01:00 +01:00
}
Vec_PtrWriteEntry ( vLabels , pObj - > Id , pLabel ) ;
return pLabel ;
2011-12-29 15:14:01 +01:00
} */
2008-01-31 05:01:00 +01:00
/**Function*************************************************************
Synopsis [ Counts the area of the given node . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-12-29 15:14:01 +01:00
/*int Abc_NtkRecStrashNodeCount_rec( Abc_Obj_t * pObj, Vec_Str_t * vCosts, Vec_Ptr_t * vLabels )
2008-01-31 05:01:00 +01:00
{
int Cost0 , Cost1 ;
if ( Vec_PtrEntry ( vLabels , pObj - > Id ) )
return 0 ;
assert ( Abc_ObjIsNode ( pObj ) ) ;
// if this node is already visited, skip
if ( Abc_NodeIsTravIdCurrent ( pObj ) )
return Vec_StrEntry ( vCosts , pObj - > Id ) ;
// mark the node as visited
Abc_NodeSetTravIdCurrent ( pObj ) ;
// count for the fanins
Cost0 = Abc_NtkRecStrashNodeCount_rec ( Abc_ObjFanin0 ( pObj ) , vCosts , vLabels ) ;
Cost1 = Abc_NtkRecStrashNodeCount_rec ( Abc_ObjFanin1 ( pObj ) , vCosts , vLabels ) ;
Vec_StrWriteEntry ( vCosts , pObj - > Id , ( char ) ( Cost0 + Cost1 + 1 ) ) ;
return Cost0 + Cost1 + 1 ;
2011-12-29 15:14:01 +01:00
} */
2008-01-31 05:01:00 +01:00
/**Function*************************************************************
Synopsis [ Strashes the given node using its local function . ]
Description [ Assumes that the fanins are already strashed .
Returns 0 if the function is not found in the table . ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-12-29 15:14:01 +01:00
/*int Abc_NtkRecStrashNode( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, unsigned * pTruth, int nVars )
2008-01-31 05:01:00 +01:00
{
char pCanonPerm [ 16 ] ;
Abc_Ntk_t * pAig = s_pMan - > pNtk ;
unsigned * pInOut = s_pMan - > pTemp1 ;
unsigned * pTemp = s_pMan - > pTemp2 ;
unsigned * pTruthRec ;
Abc_Obj_t * pCand , * pCandMin , * pLeaf , * pFanin , * * ppSpot ;
unsigned uCanonPhase ;
int i , nLeaves , CostMin , Cost , nOnes , fCompl ;
// check if the record works
nLeaves = Abc_ObjFaninNum ( pObj ) ;
assert ( nLeaves > = 3 & & nLeaves < = s_pMan - > nVars ) ;
pFanin = Abc_ObjFanin0 ( pObj ) ;
assert ( Abc_ObjRegular ( pFanin - > pCopy ) - > pNtk = = pNtkNew ) ;
assert ( s_pMan ! = NULL ) ;
assert ( nVars = = s_pMan - > nVars ) ;
// copy the truth table
Kit_TruthCopy ( pInOut , pTruth , nVars ) ;
// set permutation
for ( i = 0 ; i < nVars ; i + + )
pCanonPerm [ i ] = i ;
// canonicize the truth table
uCanonPhase = Kit_TruthSemiCanonicize ( pInOut , pTemp , nVars , pCanonPerm , ( short * ) s_pMan - > pMints ) ;
// get hold of the curresponding class
ppSpot = Abc_NtkRecTableLookup ( s_pMan , pInOut , nVars ) ;
if ( * ppSpot = = NULL )
{
s_pMan - > nFunsNotFound + + ;
// printf( "The class of a function with %d inputs is not found.\n", nLeaves );
return 0 ;
}
s_pMan - > nFunsFound + + ;
// make sure the truth table is the same
2011-12-07 01:06:59 +01:00
pTruthRec = ( unsigned * ) Vec_PtrEntry ( s_pMan - > vTtNodes , ( * ppSpot ) - > Id ) ;
2008-01-31 05:01:00 +01:00
if ( ! Kit_TruthIsEqualWithPhase ( pTruthRec , pInOut , nVars ) )
{
assert ( 0 ) ;
return 0 ;
}
// allocate storage for costs
if ( s_pMan - > vLabels & & Vec_PtrSize ( s_pMan - > vLabels ) < Abc_NtkObjNumMax ( pAig ) )
{
Vec_PtrFree ( s_pMan - > vLabels ) ;
s_pMan - > vLabels = NULL ;
}
if ( s_pMan - > vLabels = = NULL )
s_pMan - > vLabels = Vec_PtrStart ( Abc_NtkObjNumMax ( pAig ) ) ;
// go through the variables in the new truth table
Abc_NtkIncrementTravId ( pAig ) ;
for ( i = 0 ; i < nLeaves ; i + + )
{
// get hold of the corresponding fanin
pFanin = Abc_ObjFanin ( pObj , pCanonPerm [ i ] ) - > pCopy ;
pFanin = Abc_ObjNotCond ( pFanin , ( uCanonPhase & ( 1 < < i ) ) ) ;
// label the PI of the AIG subgraphs with this fanin
pLeaf = Abc_NtkPi ( pAig , i ) ;
Vec_PtrWriteEntry ( s_pMan - > vLabels , pLeaf - > Id , pFanin ) ;
Abc_NodeSetTravIdCurrent ( pLeaf ) ;
}
// go through the candidates - and recursively label them
2011-12-06 21:42:00 +01:00
for ( pCand = * ppSpot ; pCand ; pCand = ( Abc_Obj_t * ) pCand - > pData )
2008-01-31 05:01:00 +01:00
Abc_NtkRecStrashNodeLabel_rec ( pNtkNew , pCand , 0 , s_pMan - > vLabels ) ;
// allocate storage for costs
if ( s_pMan - > vCosts & & Vec_StrSize ( s_pMan - > vCosts ) < Abc_NtkObjNumMax ( pAig ) )
{
Vec_StrFree ( s_pMan - > vCosts ) ;
s_pMan - > vCosts = NULL ;
}
if ( s_pMan - > vCosts = = NULL )
s_pMan - > vCosts = Vec_StrStart ( Abc_NtkObjNumMax ( pAig ) ) ;
// find the best subgraph
CostMin = ABC_INFINITY ;
pCandMin = NULL ;
2011-12-06 21:42:00 +01:00
for ( pCand = * ppSpot ; pCand ; pCand = ( Abc_Obj_t * ) pCand - > pData )
2008-01-31 05:01:00 +01:00
{
// label the leaves
Abc_NtkIncrementTravId ( pAig ) ;
// count the number of non-labeled nodes
Cost = Abc_NtkRecStrashNodeCount_rec ( pCand , s_pMan - > vCosts , s_pMan - > vLabels ) ;
if ( CostMin > Cost )
{
// printf( "%d ", Cost );
CostMin = Cost ;
pCandMin = pCand ;
}
}
// printf( "\n" );
assert ( pCandMin ! = NULL ) ;
if ( pCandMin = = NULL )
return 0 ;
// label the leaves
Abc_NtkIncrementTravId ( pAig ) ;
for ( i = 0 ; i < nLeaves ; i + + )
Abc_NodeSetTravIdCurrent ( Abc_NtkPi ( pAig , i ) ) ;
// implement the subgraph
pObj - > pCopy = Abc_NtkRecStrashNodeLabel_rec ( pNtkNew , pCandMin , 1 , s_pMan - > vLabels ) ;
assert ( Abc_ObjRegular ( pObj - > pCopy ) - > pNtk = = pNtkNew ) ;
// determine phase difference
nOnes = Kit_TruthCountOnes ( pTruth , nVars ) ;
fCompl = ( nOnes > ( 1 < < nVars ) / 2 ) ;
// assert( fCompl == ((uCanonPhase & (1 << nVars)) > 0) );
nOnes = Kit_TruthCountOnes ( pTruthRec , nVars ) ;
fCompl ^ = ( nOnes > ( 1 < < nVars ) / 2 ) ;
// complement
pObj - > pCopy = Abc_ObjNotCond ( pObj - > pCopy , fCompl ) ;
return 1 ;
2011-12-29 15:14:01 +01:00
} */
2008-01-31 05:01:00 +01:00
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
2010-11-01 09:35:04 +01:00
ABC_NAMESPACE_IMPL_END