Commit eb2a5b43 by Alan Mishchenko

Version abc60812

parent 6b44b18e
......@@ -2102,6 +2102,10 @@ SOURCE=.\src\temp\ivy\ivyCut.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\ivy\ivyCutTrav.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\ivy\ivyDfs.c
# End Source File
# Begin Source File
......@@ -2114,6 +2118,10 @@ SOURCE=.\src\temp\ivy\ivyFanout.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\ivy\ivyHaig.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\ivy\ivyIsop.c
# End Source File
# Begin Source File
......@@ -2205,50 +2213,6 @@ SOURCE=.\src\temp\esop\esopMin.c
SOURCE=.\src\temp\esop\esopUtil.c
# End Source File
# End Group
# Begin Group "xyz"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\temp\xyz\xyz.h
# End Source File
# Begin Source File
SOURCE=.\src\temp\xyz\xyzBuild.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\xyz\xyzCore.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\xyz\xyzInt.h
# End Source File
# Begin Source File
SOURCE=.\src\temp\xyz\xyzMan.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\xyz\xyzMinEsop.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\xyz\xyzMinMan.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\xyz\xyzMinSop.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\xyz\xyzMinUtil.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\xyz\xyzTest.c
# End Source File
# End Group
# Begin Group "rwt"
# PROP Default_Filter ""
......
......@@ -3,7 +3,8 @@
#set checkfio # prints warnings when fanins/fanouts are duplicated
#set checkread # checks new networks after reading from file
#set backup # saves backup networks retrived by "undo" and "recall"
#set savesteps 1 # sets the maximum number of backup networks to save
#set savesteps 1 # sets the maximum number of backup networks to save
set progressbar # display the progress bar
# program names for internal calls
set dotwin dot.exe
......
......@@ -93,6 +93,7 @@ static int Abc_CommandICut ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandIRewrite ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandIRewriteSeq ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandIResyn ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandHaig ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandFraigTrust ( Abc_Frame_t * pAbc, int argc, char ** argv );
......@@ -210,6 +211,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "New AIG", "irw", Abc_CommandIRewrite, 1 );
Cmd_CommandAdd( pAbc, "New AIG", "irws", Abc_CommandIRewriteSeq, 1 );
Cmd_CommandAdd( pAbc, "New AIG", "iresyn", Abc_CommandIResyn, 1 );
Cmd_CommandAdd( pAbc, "New AIG", "haig", Abc_CommandHaig, 1 );
Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 );
Cmd_CommandAdd( pAbc, "Fraiging", "fraig_trust", Abc_CommandFraigTrust, 1 );
......@@ -5088,6 +5090,75 @@ usage:
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandHaig( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk, * pNtkRes;
int c, fUpdateLevel, fVerbose;
extern Abc_Ntk_t * Abc_NtkIvyHaig( Abc_Ntk_t * pNtk, int fVerbose );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
fUpdateLevel = 1;
fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "zvh" ) ) != EOF )
{
switch ( c )
{
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
if ( Abc_NtkIsSeq(pNtk) )
{
fprintf( pErr, "Only works for non-sequential networks.\n" );
return 1;
}
pNtkRes = Abc_NtkIvyHaig( pNtk, fVerbose );
if ( pNtkRes == NULL )
{
fprintf( pErr, "Command has failed.\n" );
return 0;
}
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
return 0;
usage:
fprintf( pErr, "usage: haig [-vh]\n" );
fprintf( pErr, "\t prints HAIG stats after one round of sequential rewriting\n" );
// fprintf( pErr, "\t-l : toggle preserving the number of levels [default = %s]\n", fUpdateLevel? "yes": "no" );
fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
......
......@@ -179,6 +179,36 @@ Abc_Ntk_t * Abc_NtkIvyStrash( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkIvyHaig( Abc_Ntk_t * pNtk, int fVerbose )
{
Abc_Ntk_t * pNtkAig;
Ivy_Man_t * pMan;
pMan = Abc_NtkIvyBefore( pNtk, 1, 1 );
if ( pMan == NULL )
return NULL;
Ivy_ManHaigStart( pMan );
Ivy_ManRewriteSeq( pMan, 0, fVerbose );
Ivy_ManHaigPrintStats( pMan );
Ivy_ManHaigStop( pMan );
// pNtkAig = Abc_NtkIvyAfterHaig( pNtk, pMan, 1 );
pNtkAig = Abc_NtkIvyAfter( pNtk, pMan, 1 );
Ivy_ManStop( pMan );
return pNtkAig;
}
/**Function*************************************************************
Synopsis [Gives the current ABC network to AIG manager for processing.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkIvyCuts( Abc_Ntk_t * pNtk, int nInputs )
{
extern void Ivy_CutComputeAll( Ivy_Man_t * p, int nInputs );
......@@ -276,10 +306,10 @@ Abc_Ntk_t * Abc_NtkIvyResyn( Abc_Ntk_t * pNtk, int fUpdateLevel, int fVerbose )
***********************************************************************/
Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkAig;
// Abc_Ntk_t * pNtkAig;
Ivy_Man_t * pMan;//, * pTemp;
int fCleanup = 1;
int nNodes;
// int nNodes;
int nLatches = Abc_NtkLatchNum(pNtk);
int * pInit = Abc_NtkCollectLatchValues( pNtk, 0 );
......@@ -329,6 +359,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
// Ivy_ManStop( pTemp );
// Ivy_ManTestCutsAll( pMan );
// Ivy_ManTestCutsTravAll( pMan );
// Ivy_ManPrintStats( pMan );
......@@ -344,7 +375,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
// Ivy_ManRequiredLevels( pMan );
// Pla_ManFastLutMap( pMan, 8 );
// Ivy_ManStop( pMan );
Ivy_ManStop( pMan );
return NULL;
......
......@@ -148,7 +148,6 @@ Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk )
void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
{
ProgressBar * pProgress;
DdManager * dd = pNtk->pManFunc;
Abc_Obj_t * pNode, * pNodeNew;
Vec_Ptr_t * vNodes;
int i;
......
......@@ -111,7 +111,6 @@ Abc_Frame_t * Abc_FrameAllocate()
// set the starting step
p->nSteps = 1;
p->fBatchMode = 0;
p->fProgress = 1;
// initialize decomposition manager
define_cube_size(20);
set_espresso_flags();
......@@ -176,7 +175,7 @@ void Abc_FrameRestart( Abc_Frame_t * p )
***********************************************************************/
bool Abc_FrameShowProgress( Abc_Frame_t * p )
{
return p->fProgress;
return Abc_FrameIsFlagEnabled( "progressbar" );
}
......
......@@ -55,7 +55,6 @@ struct Abc_Frame_t_
int nSteps; // the counter of different network processed
int fAutoexac; // marks the autoexec mode
int fBatchMode; // are we invoked in batch mode?
int fProgress; // shows progress bars
// output streams
FILE * Out;
FILE * Err;
......
......@@ -27,6 +27,8 @@ extern "C" {
#include <stdlib.h>
#include "extra.h"
//#pragma warning( disable : 4514 )
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
......@@ -91,9 +93,9 @@ struct _reo_plane
struct _reo_hash
{
int Sign; // signature of the current cache operation
unsigned Arg1; // the first argument
unsigned Arg2; // the second argument
unsigned Arg3; // the second argument
reo_unit * Arg1; // the first argument
reo_unit * Arg2; // the second argument
reo_unit * Arg3; // the third argument
};
struct _reo_man
......
......@@ -330,7 +330,7 @@ void reoProfileWidthPrint( reo_man * p )
WidthMax = p->pPlanes[i].statsWidth;
TotalWidth += p->pPlanes[i].statsWidth;
}
assert( p->nWidthCur = TotalWidth );
assert( p->nWidthCur == TotalWidth );
printf( "WIDTH: " );
printf( "Maximum = %5d. ", WidthMax );
printf( "Total = %7d. ", p->nWidthCur );
......
......@@ -271,9 +271,9 @@ double reoReorderSwapAdjacentVars( reo_man * p, int lev0, int fMovingUp )
HKey = (HKey+1) % p->nTableSize );
assert( p->HTable[HKey].Sign != p->Signature );
p->HTable[HKey].Sign = p->Signature;
p->HTable[HKey].Arg1 = (unsigned)pUnitE;
p->HTable[HKey].Arg2 = (unsigned)pUnitT;
p->HTable[HKey].Arg3 = (unsigned)pUnit;
p->HTable[HKey].Arg1 = pUnitE;
p->HTable[HKey].Arg2 = pUnitT;
p->HTable[HKey].Arg3 = pUnit;
nNodesUpMovedDown++;
......@@ -512,10 +512,10 @@ double reoReorderSwapAdjacentVars( reo_man * p, int lev0, int fMovingUp )
for ( HKey = hashKey3(p->Signature, pNew1E, pNew1T, p->nTableSize);
p->HTable[HKey].Sign == p->Signature;
HKey = (HKey+1) % p->nTableSize )
if ( p->HTable[HKey].Arg1 == (unsigned)pNew1E && p->HTable[HKey].Arg2 == (unsigned)pNew1T )
if ( p->HTable[HKey].Arg1 == pNew1E && p->HTable[HKey].Arg2 == pNew1T )
{ // the entry is present
// assign this entry
pNewPlane20 = (reo_unit *)p->HTable[HKey].Arg3;
pNewPlane20 = p->HTable[HKey].Arg3;
assert( pNewPlane20->lev == lev1 );
fFound = 1;
p->HashSuccess++;
......@@ -549,9 +549,9 @@ double reoReorderSwapAdjacentVars( reo_man * p, int lev0, int fMovingUp )
// add this entry to cache
assert( p->HTable[HKey].Sign != p->Signature );
p->HTable[HKey].Sign = p->Signature;
p->HTable[HKey].Arg1 = (unsigned)pNew1E;
p->HTable[HKey].Arg2 = (unsigned)pNew1T;
p->HTable[HKey].Arg3 = (unsigned)pNewPlane20;
p->HTable[HKey].Arg1 = pNew1E;
p->HTable[HKey].Arg2 = pNew1T;
p->HTable[HKey].Arg3 = pNewPlane20;
nNodesUnrefAdded++;
......@@ -637,10 +637,10 @@ double reoReorderSwapAdjacentVars( reo_man * p, int lev0, int fMovingUp )
for ( HKey = hashKey3(p->Signature, pNew2E, pNew2T, p->nTableSize);
p->HTable[HKey].Sign == p->Signature;
HKey = (HKey+1) % p->nTableSize )
if ( p->HTable[HKey].Arg1 == (unsigned)pNew2E && p->HTable[HKey].Arg2 == (unsigned)pNew2T )
if ( p->HTable[HKey].Arg1 == pNew2E && p->HTable[HKey].Arg2 == pNew2T )
{ // the entry is present
// assign this entry
pNewPlane21 = (reo_unit *)p->HTable[HKey].Arg3;
pNewPlane21 = p->HTable[HKey].Arg3;
assert( pNewPlane21->lev == lev1 );
fFound = 1;
p->HashSuccess++;
......@@ -675,9 +675,9 @@ double reoReorderSwapAdjacentVars( reo_man * p, int lev0, int fMovingUp )
// add this entry to cache
assert( p->HTable[HKey].Sign != p->Signature );
p->HTable[HKey].Sign = p->Signature;
p->HTable[HKey].Arg1 = (unsigned)pNew2E;
p->HTable[HKey].Arg2 = (unsigned)pNew2T;
p->HTable[HKey].Arg3 = (unsigned)pNewPlane21;
p->HTable[HKey].Arg1 = pNew2E;
p->HTable[HKey].Arg2 = pNew2T;
p->HTable[HKey].Arg3 = pNewPlane21;
nNodesUnrefAdded++;
......
......@@ -51,9 +51,9 @@ reo_unit * reoTransferNodesToUnits_rec( reo_man * p, DdNode * F )
{
// search cache - use linear probing
for ( HKey = hashKey2(p->Signature,F,p->nTableSize); p->HTable[HKey].Sign == p->Signature; HKey = (HKey+1) % p->nTableSize )
if ( p->HTable[HKey].Arg1 == (unsigned)F )
if ( p->HTable[HKey].Arg1 == (reo_unit *)F )
{
pUnit = (reo_unit*) p->HTable[HKey].Arg2;
pUnit = p->HTable[HKey].Arg2;
assert( pUnit );
// increment the edge counter
pUnit->n++;
......@@ -93,8 +93,8 @@ reo_unit * reoTransferNodesToUnits_rec( reo_man * p, DdNode * F )
// might have been used. Make sure that its signature is different.
for ( ; p->HTable[HKey].Sign == p->Signature; HKey = (HKey+1) % p->nTableSize );
p->HTable[HKey].Sign = p->Signature;
p->HTable[HKey].Arg1 = (unsigned)F;
p->HTable[HKey].Arg2 = (unsigned)pUnit;
p->HTable[HKey].Arg1 = (reo_unit *)F;
p->HTable[HKey].Arg2 = pUnit;
}
// increment the counter of nodes
......@@ -126,7 +126,7 @@ DdNode * reoTransferUnitsToNodes_rec( reo_man * p, reo_unit * pUnit )
if ( pUnit->n != 1 )
{
for ( HKey = hashKey2(p->Signature,pUnit,p->nTableSize); p->HTable[HKey].Sign == p->Signature; HKey = (HKey+1) % p->nTableSize )
if ( p->HTable[HKey].Arg1 == (unsigned)pUnit )
if ( p->HTable[HKey].Arg1 == pUnit )
{
bRes = (DdNode*) p->HTable[HKey].Arg2;
assert( bRes );
......@@ -179,8 +179,8 @@ DdNode * reoTransferUnitsToNodes_rec( reo_man * p, reo_unit * pUnit )
// might have been used. Make sure that its signature is different.
for ( ; p->HTable[HKey].Sign == p->Signature; HKey = (HKey+1) % p->nTableSize );
p->HTable[HKey].Sign = p->Signature;
p->HTable[HKey].Arg1 = (unsigned)pUnit;
p->HTable[HKey].Arg2 = (unsigned)bRes;
p->HTable[HKey].Arg1 = pUnit;
p->HTable[HKey].Arg2 = (reo_unit *)bRes;
// add the DD to the referenced DD list in order to be able to store it in cache
p->pRefNodes[p->nRefNodes++] = bRes; Cudd_Ref( bRes );
......
......@@ -341,7 +341,7 @@ extern int Extra_MmStepReadMemUsage( Extra_MmStep_t * p );
/*=== extraUtilMisc.c ========================================================*/
/* finds the smallest integer larger of equal than the logarithm. */
/* finds the smallest integer larger or equal than the logarithm */
extern int Extra_Base2Log( unsigned Num );
extern int Extra_Base2LogDouble( double Num );
extern int Extra_Base10Log( unsigned Num );
......@@ -400,7 +400,15 @@ static inline void Extra_ProgressBarUpdate( ProgressBar * p, int nItemsCur, char
/*=== extraUtilTruth.c ================================================================*/
static inline int Extra_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
static inline int Extra_Float2Int( float Val ) { return *((int *)&Val); }
static inline float Extra_Int2Float( int Num ) { return *((float *)&Num); }
static inline int Extra_BitWordNum( int nBits ) { return nBits/(8*sizeof(unsigned)) + ((nBits%(8*sizeof(unsigned))) > 0); }
static inline int Extra_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
static inline void Extra_TruthSetBit( unsigned * p, int Bit ) { p[Bit>>5] |= (1<<(Bit & 31)); }
static inline void Extra_TruthXorBit( unsigned * p, int Bit ) { p[Bit>>5] ^= (1<<(Bit & 31)); }
static inline int Extra_TruthHasBit( unsigned * p, int Bit ) { return (p[Bit>>5] & (1<<(Bit & 31))) > 0; }
static inline int Extra_WordCountOnes( unsigned uWord )
{
uWord = (uWord & 0x55555555) + ((uWord>>1) & 0x55555555);
......@@ -409,6 +417,13 @@ static inline int Extra_WordCountOnes( unsigned uWord )
uWord = (uWord & 0x00FF00FF) + ((uWord>>8) & 0x00FF00FF);
return (uWord & 0x0000FFFF) + (uWord>>16);
}
static inline int Extra_TruthCountOnes( unsigned * pIn, int nVars )
{
int w, Counter = 0;
for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
Counter += Extra_WordCountOnes(pIn[w]);
return Counter;
}
static inline int Extra_TruthIsEqual( unsigned * pIn0, unsigned * pIn1, int nVars )
{
int w;
......@@ -504,18 +519,26 @@ extern void Extra_TruthForall( unsigned * pTruth, int nVars, int iVar );
extern void Extra_TruthMux( unsigned * pOut, unsigned * pCof0, unsigned * pCof1, int nVars, int iVar );
extern void Extra_TruthChangePhase( unsigned * pTruth, int nVars, int iVar );
extern int Extra_TruthMinCofSuppOverlap( unsigned * pTruth, int nVars, int * pVarMin );
extern int Extra_TruthCountOnes( unsigned * pTruth, int nVars );
extern void Extra_TruthCountOnesInCofs( unsigned * pTruth, int nVars, short * pStore );
extern unsigned Extra_TruthHash( unsigned * pIn, int nWords );
extern unsigned Extra_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars, char * pCanonPerm, short * pStore );
/*=== extraUtilUtil.c ================================================================*/
#ifndef ALLOC
#define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
#endif
#ifndef FREE
#define FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
#endif
#ifndef REALLOC
#define REALLOC(type, obj, num) \
((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
((type *) malloc(sizeof(type) * (num))))
#endif
extern long Extra_CpuTime();
extern int Extra_GetSoftDataLimit();
......
/**CFile****************************************************************
FileName [extraUtil.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [extra]
Synopsis [Various reusable software utilities.]
Description []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: extraUtil.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __EXTRA_UTIL_H__
#define __EXTRA_UTIL_H__
/*---------------------------------------------------------------------------*/
/* Nested includes */
/*---------------------------------------------------------------------------*/
#include <string.h>
#include <time.h>
/*---------------------------------------------------------------------------*/
/* Constant declarations */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Stucture declarations */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Type declarations */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Variable declarations */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Macro declarations */
/*---------------------------------------------------------------------------*/
/*===========================================================================*/
/* Various Utilities */
/*===========================================================================*/
/**AutomaticEnd***************************************************************/
#endif /* __EXTRA_UTIL_H__ */
......@@ -782,26 +782,6 @@ void Extra_TruthChangePhase( unsigned * pTruth, int nVars, int iVar )
/**Function*************************************************************
Synopsis [Changes phase of the function w.r.t. one variable.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Extra_TruthCountOnes( unsigned * pTruth, int nVars )
{
int nWords = Extra_TruthWordNum( nVars );
int i, Counter = 0;
for ( i = 0; i < nWords; i++ )
Counter += Extra_WordCountOnes( pTruth[i] );
return Counter;
}
/**Function*************************************************************
Synopsis [Computes minimum overlap in supports of cofactors.]
Description []
......
......@@ -88,13 +88,13 @@ Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData )
printf( "The current network does not have SOPs to perform extraction.\n" );
return NULL;
}
/*
if ( nPairsStore > 10000000 )
{
printf( "The problem is too large to be solved by \"fxu\" (%d cubes and %d cube pairs)\n", nCubesTotal, nPairsStore );
return NULL;
}
*/
// start the matrix
p = Fxu_MatrixAllocate();
// create the column labels
......
......@@ -110,14 +110,17 @@ struct Ivy_Man_t_
int nTravIds; // the traversal ID
int nLevelMax; // the maximum level
Vec_Int_t * vRequired; // required times
// Vec_Ptr_t * vFanouts; // representation of the fanouts
int fFanout; // fanout is allocated
void * pData; // the temporary data
void * pCopy; // the temporary data
Ivy_Man_t * pHaig; // history AIG if present
// memory management
Vec_Ptr_t * vChunks; // allocated memory pieces
Vec_Ptr_t * vPages; // memory pages used by nodes
Ivy_Obj_t * pListFree; // the list of free nodes
// timing statistics
int time1;
int time2;
};
......@@ -197,51 +200,54 @@ static inline int Ivy_ManNodeNum( Ivy_Man_t * p ) { return p->nO
static inline int Ivy_ManHashObjNum( Ivy_Man_t * p ) { return p->nObjs[IVY_AND]+p->nObjs[IVY_EXOR]+p->nObjs[IVY_LATCH]; }
static inline int Ivy_ManGetCost( Ivy_Man_t * p ) { return p->nObjs[IVY_AND]+3*p->nObjs[IVY_EXOR]+8*p->nObjs[IVY_LATCH]; }
static inline Ivy_Type_t Ivy_ObjType( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type; }
static inline Ivy_Init_t Ivy_ObjInit( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Init; }
static inline int Ivy_ObjIsConst1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Id == 0; }
static inline int Ivy_ObjIsGhost( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Id < 0; }
static inline int Ivy_ObjIsNone( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_NONE; }
static inline int Ivy_ObjIsPi( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PI; }
static inline int Ivy_ObjIsPo( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PO; }
static inline int Ivy_ObjIsCi( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PI || pObj->Type == IVY_LATCH; }
static inline int Ivy_ObjIsCo( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PO || pObj->Type == IVY_LATCH; }
static inline int Ivy_ObjIsAssert( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_ASSERT; }
static inline int Ivy_ObjIsLatch( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_LATCH; }
static inline int Ivy_ObjIsAnd( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_AND; }
static inline int Ivy_ObjIsExor( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_EXOR; }
static inline int Ivy_ObjIsBuf( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_BUF; }
static inline int Ivy_ObjIsNode( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_AND || pObj->Type == IVY_EXOR; }
static inline int Ivy_ObjIsTerm( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PI || pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT; }
static inline int Ivy_ObjIsHash( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_AND || pObj->Type == IVY_EXOR || pObj->Type == IVY_LATCH; }
static inline int Ivy_ObjIsOneFanin( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT || pObj->Type == IVY_BUF || pObj->Type == IVY_LATCH; }
static inline int Ivy_ObjIsMarkA( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->fMarkA; }
static inline void Ivy_ObjSetMarkA( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->fMarkA = 1; }
static inline void Ivy_ObjClearMarkA( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->fMarkA = 0; }
static inline Ivy_Type_t Ivy_ObjType( Ivy_Obj_t * pObj ) { return pObj->Type; }
static inline Ivy_Init_t Ivy_ObjInit( Ivy_Obj_t * pObj ) { return pObj->Init; }
static inline int Ivy_ObjIsConst1( Ivy_Obj_t * pObj ) { return pObj->Id == 0; }
static inline int Ivy_ObjIsGhost( Ivy_Obj_t * pObj ) { return pObj->Id < 0; }
static inline int Ivy_ObjIsNone( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_NONE; }
static inline int Ivy_ObjIsPi( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_PI; }
static inline int Ivy_ObjIsPo( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_PO; }
static inline int Ivy_ObjIsCi( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_PI || pObj->Type == IVY_LATCH; }
static inline int Ivy_ObjIsCo( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_PO || pObj->Type == IVY_LATCH; }
static inline int Ivy_ObjIsAssert( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_ASSERT; }
static inline int Ivy_ObjIsLatch( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_LATCH; }
static inline int Ivy_ObjIsAnd( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_AND; }
static inline int Ivy_ObjIsExor( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_EXOR; }
static inline int Ivy_ObjIsBuf( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_BUF; }
static inline int Ivy_ObjIsNode( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_AND || pObj->Type == IVY_EXOR; }
static inline int Ivy_ObjIsTerm( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_PI || pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT; }
static inline int Ivy_ObjIsHash( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_AND || pObj->Type == IVY_EXOR || pObj->Type == IVY_LATCH; }
static inline int Ivy_ObjIsOneFanin( Ivy_Obj_t * pObj ) { return pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT || pObj->Type == IVY_BUF || pObj->Type == IVY_LATCH; }
static inline int Ivy_ObjIsMarkA( Ivy_Obj_t * pObj ) { return pObj->fMarkA; }
static inline void Ivy_ObjSetMarkA( Ivy_Obj_t * pObj ) { pObj->fMarkA = 1; }
static inline void Ivy_ObjClearMarkA( Ivy_Obj_t * pObj ) { pObj->fMarkA = 0; }
static inline void Ivy_ObjSetTravId( Ivy_Obj_t * pObj, int TravId ) { assert( !Ivy_IsComplement(pObj) ); pObj->TravId = TravId; }
static inline void Ivy_ObjSetTravIdCurrent( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->TravId = p->nTravIds; }
static inline void Ivy_ObjSetTravIdPrevious( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->TravId = p->nTravIds - 1; }
static inline int Ivy_ObjIsTravIdCurrent( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return (int )((int)pObj->TravId == p->nTravIds); }
static inline int Ivy_ObjIsTravIdPrevious( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return (int )((int)pObj->TravId == p->nTravIds - 1); }
static inline int Ivy_ObjId( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Id; }
static inline int Ivy_ObjPhase( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->fPhase; }
static inline int Ivy_ObjExorFanout( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->fExFan; }
static inline int Ivy_ObjRefs( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->nRefs; }
static inline void Ivy_ObjRefsInc( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->nRefs++; }
static inline void Ivy_ObjRefsDec( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); assert( pObj->nRefs > 0 ); pObj->nRefs--; }
static inline int Ivy_ObjFaninId0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->pFanin0? Ivy_ObjId(Ivy_Regular(pObj->pFanin0)) : 0; }
static inline int Ivy_ObjFaninId1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->pFanin1? Ivy_ObjId(Ivy_Regular(pObj->pFanin1)) : 0; }
static inline int Ivy_ObjFaninC0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_IsComplement(pObj->pFanin0); }
static inline int Ivy_ObjFaninC1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_IsComplement(pObj->pFanin1); }
static inline Ivy_Obj_t * Ivy_ObjFanin0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_Regular(pObj->pFanin0); }
static inline Ivy_Obj_t * Ivy_ObjFanin1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_Regular(pObj->pFanin1); }
static inline Ivy_Obj_t * Ivy_ObjChild0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->pFanin0; }
static inline Ivy_Obj_t * Ivy_ObjChild1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->pFanin1; }
static inline int Ivy_ObjLevel( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Level; }
static inline int Ivy_ObjLevelNew( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return 1 + Ivy_ObjIsExor(pObj) + IVY_MAX(Ivy_ObjFanin0(pObj)->Level, Ivy_ObjFanin1(pObj)->Level); }
static inline void Ivy_ObjSetTravId( Ivy_Obj_t * pObj, int TravId ) { pObj->TravId = TravId; }
static inline void Ivy_ObjSetTravIdCurrent( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { pObj->TravId = p->nTravIds; }
static inline void Ivy_ObjSetTravIdPrevious( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { pObj->TravId = p->nTravIds - 1; }
static inline int Ivy_ObjIsTravIdCurrent( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { return (int )((int)pObj->TravId == p->nTravIds); }
static inline int Ivy_ObjIsTravIdPrevious( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { return (int )((int)pObj->TravId == p->nTravIds - 1); }
static inline int Ivy_ObjId( Ivy_Obj_t * pObj ) { return pObj->Id; }
static inline int Ivy_ObjTravId( Ivy_Obj_t * pObj ) { return pObj->TravId; }
static inline int Ivy_ObjPhase( Ivy_Obj_t * pObj ) { return pObj->fPhase; }
static inline int Ivy_ObjExorFanout( Ivy_Obj_t * pObj ) { return pObj->fExFan; }
static inline int Ivy_ObjRefs( Ivy_Obj_t * pObj ) { return pObj->nRefs; }
static inline void Ivy_ObjRefsInc( Ivy_Obj_t * pObj ) { pObj->nRefs++; }
static inline void Ivy_ObjRefsDec( Ivy_Obj_t * pObj ) { assert( pObj->nRefs > 0 ); pObj->nRefs--; }
static inline int Ivy_ObjFaninId0( Ivy_Obj_t * pObj ) { return pObj->pFanin0? Ivy_ObjId(Ivy_Regular(pObj->pFanin0)) : 0; }
static inline int Ivy_ObjFaninId1( Ivy_Obj_t * pObj ) { return pObj->pFanin1? Ivy_ObjId(Ivy_Regular(pObj->pFanin1)) : 0; }
static inline int Ivy_ObjFaninC0( Ivy_Obj_t * pObj ) { return Ivy_IsComplement(pObj->pFanin0); }
static inline int Ivy_ObjFaninC1( Ivy_Obj_t * pObj ) { return Ivy_IsComplement(pObj->pFanin1); }
static inline Ivy_Obj_t * Ivy_ObjFanin0( Ivy_Obj_t * pObj ) { return Ivy_Regular(pObj->pFanin0); }
static inline Ivy_Obj_t * Ivy_ObjFanin1( Ivy_Obj_t * pObj ) { return Ivy_Regular(pObj->pFanin1); }
static inline Ivy_Obj_t * Ivy_ObjChild0( Ivy_Obj_t * pObj ) { return pObj->pFanin0; }
static inline Ivy_Obj_t * Ivy_ObjChild1( Ivy_Obj_t * pObj ) { return pObj->pFanin1; }
static inline Ivy_Obj_t * Ivy_ObjChild0Equiv( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_ObjFanin0(pObj)? Ivy_NotCond(Ivy_ObjFanin0(pObj)->pEquiv, Ivy_ObjFaninC0(pObj)) : NULL; }
static inline Ivy_Obj_t * Ivy_ObjChild1Equiv( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_ObjFanin1(pObj)? Ivy_NotCond(Ivy_ObjFanin1(pObj)->pEquiv, Ivy_ObjFaninC1(pObj)) : NULL; }
static inline int Ivy_ObjLevel( Ivy_Obj_t * pObj ) { return pObj->Level; }
static inline int Ivy_ObjLevelNew( Ivy_Obj_t * pObj ) { return 1 + Ivy_ObjIsExor(pObj) + IVY_MAX(Ivy_ObjFanin0(pObj)->Level, Ivy_ObjFanin1(pObj)->Level); }
static inline void Ivy_ObjClean( Ivy_Obj_t * pObj )
{
int IdSaved = pObj->Id;
......@@ -415,10 +421,19 @@ extern void Ivy_ObjPatchFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_
extern void Ivy_ObjCollectFanouts( Ivy_Man_t * p, Ivy_Obj_t * pObj, Vec_Ptr_t * vArray );
extern Ivy_Obj_t * Ivy_ObjReadFirstFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj );
extern int Ivy_ObjFanoutNum( Ivy_Man_t * p, Ivy_Obj_t * pObj );
/*=== ivyHaig.c ==========================================================*/
extern void Ivy_ManHaigStart( Ivy_Man_t * p );
extern void Ivy_ManHaigTrasfer( Ivy_Man_t * p, Ivy_Man_t * pNew );
extern void Ivy_ManHaigStop( Ivy_Man_t * p );
extern void Ivy_ManHaigPrintStats( Ivy_Man_t * p );
extern void Ivy_ManHaigCreateObj( Ivy_Man_t * p, Ivy_Obj_t * pObj );
extern void Ivy_ManHaigCreateChoice( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew );
extern void Ivy_ManHaigSimulate( Ivy_Man_t * p );
/*=== ivyIsop.c ==========================================================*/
extern int Ivy_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vCover, int fTryBoth );
/*=== ivyMan.c ==========================================================*/
extern Ivy_Man_t * Ivy_ManStart();
extern Ivy_Man_t * Ivy_ManDup( Ivy_Man_t * p );
extern void Ivy_ManStop( Ivy_Man_t * p );
extern int Ivy_ManCleanup( Ivy_Man_t * p );
extern int Ivy_ManPropagateBuffers( Ivy_Man_t * p, int fUpdateLevel );
......
......@@ -59,6 +59,9 @@ Ivy_Man_t * Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel )
Ivy_ManConst1(p)->TravId = Ivy_EdgeFromNode( Ivy_ManConst1(pNew) );
Ivy_ManForEachPi( p, pObj, i )
pObj->TravId = Ivy_EdgeFromNode( Ivy_ObjCreatePi(pNew) );
// if HAIG is defined, trasfer the pointers to the PIs/latches
// if ( p->pHaig )
// Ivy_ManHaigTrasfer( p, pNew );
// balance the AIG
vStore = Vec_VecAlloc( 50 );
Ivy_ManForEachPo( p, pObj, i )
......@@ -327,10 +330,18 @@ void Ivy_NodeBalancePermute( Ivy_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, i
// get the two last nodes
pObj1 = Vec_PtrEntry( vSuper, RightBound + 1 );
pObj2 = Vec_PtrEntry( vSuper, RightBound );
if ( Ivy_Regular(pObj1) == p->pConst1 || Ivy_Regular(pObj2) == p->pConst1 )
return;
// find the first node that can be shared
for ( i = RightBound; i >= LeftBound; i-- )
{
pObj3 = Vec_PtrEntry( vSuper, i );
if ( Ivy_Regular(pObj3) == p->pConst1 )
{
Vec_PtrWriteEntry( vSuper, i, pObj2 );
Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
return;
}
pGhost = Ivy_ObjCreateGhost( p, pObj1, pObj3, fExor? IVY_EXOR : IVY_AND, IVY_INIT_NONE );
if ( Ivy_TableLookup( p, pGhost ) )
{
......
......@@ -889,7 +889,6 @@ Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves
{
static Ivy_Store_t CutStore, * pCutStore = &CutStore;
Ivy_Cut_t CutNew, * pCutNew = &CutNew, * pCut;
Ivy_Man_t * pMan = p;
Ivy_Obj_t * pLeaf;
int i, k, iLeaf0, iLeaf1;
......
/**CFile****************************************************************
FileName [ivyCutTrav.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - May 11, 2006.]
Revision [$Id: ivyCutTrav.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ivy.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static unsigned * Ivy_NodeCutElementary( Vec_Int_t * vStore, int nWords, int NodeId );
static void Ivy_NodeComputeVolume( Ivy_Obj_t * pObj, int nNodeLimit, Vec_Ptr_t * vNodes, Vec_Ptr_t * vFront );
static void Ivy_NodeFindCutsMerge( Vec_Ptr_t * vCuts0, Vec_Ptr_t * vCuts1, Vec_Ptr_t * vCuts, int nLeaves, int nWords, Vec_Int_t * vStore );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes cuts for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ivy_Store_t * Ivy_NodeFindCutsTravAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves, int nNodeLimit,
Vec_Ptr_t * vNodes, Vec_Ptr_t * vFront, Vec_Int_t * vStore, Vec_Vec_t * vBitCuts )
{
static Ivy_Store_t CutStore, * pCutStore = &CutStore;
Vec_Ptr_t * vCuts, * vCuts0, * vCuts1;
unsigned * pBitCut;
Ivy_Obj_t * pLeaf;
Ivy_Cut_t * pCut;
int i, k, nWords, nNodes;
assert( nLeaves <= IVY_CUT_INPUT );
// find the given number of nodes in the TFI
Ivy_NodeComputeVolume( pObj, nNodeLimit - 1, vNodes, vFront );
nNodes = Vec_PtrSize(vNodes);
// assert( nNodes <= nNodeLimit );
// make sure vBitCuts has enough room
Vec_VecExpand( vBitCuts, nNodes-1 );
Vec_VecClear( vBitCuts );
// prepare the memory manager
Vec_IntClear( vStore );
Vec_IntGrow( vStore, 64000 );
// set elementary cuts for the leaves
nWords = Extra_BitWordNum( nNodes );
Vec_PtrForEachEntry( vFront, pLeaf, i )
{
assert( Ivy_ObjTravId(pLeaf) < nNodes );
// get the new bitcut
pBitCut = Ivy_NodeCutElementary( vStore, nWords, Ivy_ObjTravId(pLeaf) );
// set it as the cut of this leaf
Vec_VecPush( vBitCuts, Ivy_ObjTravId(pLeaf), pBitCut );
}
// compute the cuts for each node
Vec_PtrForEachEntry( vNodes, pLeaf, i )
{
// skip the leaves
vCuts = Vec_VecEntry( vBitCuts, Ivy_ObjTravId(pLeaf) );
if ( Vec_PtrSize(vCuts) > 0 )
continue;
// add elementary cut
pBitCut = Ivy_NodeCutElementary( vStore, nWords, Ivy_ObjTravId(pLeaf) );
// set it as the cut of this leaf
Vec_VecPush( vBitCuts, Ivy_ObjTravId(pLeaf), pBitCut );
// get the fanin cuts
vCuts0 = Vec_VecEntry( vBitCuts, Ivy_ObjTravId( Ivy_ObjFanin0(pLeaf) ) );
vCuts1 = Vec_VecEntry( vBitCuts, Ivy_ObjTravId( Ivy_ObjFanin1(pLeaf) ) );
assert( Vec_PtrSize(vCuts0) > 0 );
assert( Vec_PtrSize(vCuts1) > 0 );
// merge the cuts
Ivy_NodeFindCutsMerge( vCuts0, vCuts1, vCuts, nLeaves, nWords, vStore );
}
// start the structure
pCutStore->nCuts = 0;
pCutStore->nCutsMax = IVY_CUT_LIMIT;
// collect the cuts of the root node
vCuts = Vec_VecEntry( vBitCuts, Ivy_ObjTravId(pObj) );
Vec_PtrForEachEntry( vCuts, pBitCut, i )
{
pCut = pCutStore->pCuts + pCutStore->nCuts++;
pCut->nSize = 0;
pCut->nSizeMax = nLeaves;
pCut->uHash = 0;
for ( k = 0; k < nNodes; k++ )
if ( Extra_TruthHasBit(pBitCut, k) )
pCut->pArray[ pCut->nSize++ ] = Ivy_ObjId( Vec_PtrEntry(vNodes, k) );
assert( pCut->nSize <= nLeaves );
if ( pCutStore->nCuts == pCutStore->nCutsMax )
break;
}
// clean the travIds
Vec_PtrForEachEntry( vNodes, pLeaf, i )
pLeaf->TravId = 0;
return pCutStore;
}
/**Function*************************************************************
Synopsis [Creates elementary bit-cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned * Ivy_NodeCutElementary( Vec_Int_t * vStore, int nWords, int NodeId )
{
unsigned * pBitCut;
pBitCut = Vec_IntFetch( vStore, nWords );
memset( pBitCut, 0, 4 * nWords );
Extra_TruthSetBit( pBitCut, NodeId );
return pBitCut;
}
/**Function*************************************************************
Synopsis [Compares the node by level.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ivy_CompareNodesByLevel( Ivy_Obj_t ** ppObj1, Ivy_Obj_t ** ppObj2 )
{
Ivy_Obj_t * pObj1 = *ppObj1;
Ivy_Obj_t * pObj2 = *ppObj2;
if ( pObj1->Level < pObj2->Level )
return -1;
if ( pObj1->Level > pObj2->Level )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis [Mark all nodes up to the given depth.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ivy_NodeComputeVolumeTrav1_rec( Ivy_Obj_t * pObj, int Depth )
{
if ( Ivy_ObjIsCi(pObj) || Depth == 0 )
return;
Ivy_NodeComputeVolumeTrav1_rec( Ivy_ObjFanin0(pObj), Depth - 1 );
Ivy_NodeComputeVolumeTrav1_rec( Ivy_ObjFanin1(pObj), Depth - 1 );
pObj->fMarkA = 1;
}
/**Function*************************************************************
Synopsis [Collect the marked nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ivy_NodeComputeVolumeTrav2_rec( Ivy_Obj_t * pObj, Vec_Ptr_t * vNodes )
{
if ( !pObj->fMarkA )
return;
Ivy_NodeComputeVolumeTrav2_rec( Ivy_ObjFanin0(pObj), vNodes );
Ivy_NodeComputeVolumeTrav2_rec( Ivy_ObjFanin1(pObj), vNodes );
Vec_PtrPush( vNodes, pObj );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ivy_NodeComputeVolume( Ivy_Obj_t * pObj, int nNodeLimit, Vec_Ptr_t * vNodes, Vec_Ptr_t * vFront )
{
Ivy_Obj_t * pTemp, * pFanin;
int i, nNodes;
// mark nodes up to the given depth
Ivy_NodeComputeVolumeTrav1_rec( pObj, 6 );
// collect the marked nodes
Vec_PtrClear( vFront );
Ivy_NodeComputeVolumeTrav2_rec( pObj, vFront );
// find the fanins that are not marked
Vec_PtrClear( vNodes );
Vec_PtrForEachEntry( vFront, pTemp, i )
{
pFanin = Ivy_ObjFanin0(pTemp);
if ( !pFanin->fMarkA )
{
pFanin->fMarkA = 1;
Vec_PtrPush( vNodes, pFanin );
}
pFanin = Ivy_ObjFanin1(pTemp);
if ( !pFanin->fMarkA )
{
pFanin->fMarkA = 1;
Vec_PtrPush( vNodes, pFanin );
}
}
// remember the number of nodes in the frontier
nNodes = Vec_PtrSize( vNodes );
// add the remaining nodes
Vec_PtrForEachEntry( vFront, pTemp, i )
Vec_PtrPush( vNodes, pTemp );
// unmark the nodes
Vec_PtrForEachEntry( vNodes, pTemp, i )
{
pTemp->fMarkA = 0;
pTemp->TravId = i;
}
// collect the frontier nodes
Vec_PtrClear( vFront );
Vec_PtrForEachEntryStop( vNodes, pTemp, i, nNodes )
Vec_PtrPush( vFront, pTemp );
// printf( "%d ", Vec_PtrSize(vNodes) );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ivy_NodeComputeVolume2( Ivy_Obj_t * pObj, int nNodeLimit, Vec_Ptr_t * vNodes, Vec_Ptr_t * vFront )
{
Ivy_Obj_t * pLeaf, * pPivot, * pFanin;
int LevelMax, i;
assert( Ivy_ObjIsNode(pObj) );
// clear arrays
Vec_PtrClear( vNodes );
Vec_PtrClear( vFront );
// add the root
pObj->fMarkA = 1;
Vec_PtrPush( vNodes, pObj );
Vec_PtrPush( vFront, pObj );
// expand node with maximum level
LevelMax = pObj->Level;
do {
// get the node to expand
pPivot = NULL;
Vec_PtrForEachEntryReverse( vFront, pLeaf, i )
{
if ( (int)pLeaf->Level == LevelMax )
{
pPivot = pLeaf;
break;
}
}
// decrease level if we did not find the node
if ( pPivot == NULL )
{
if ( --LevelMax == 0 )
break;
continue;
}
// the node to expand is found
// remove it from frontier
Vec_PtrRemove( vFront, pPivot );
// add fanins
pFanin = Ivy_ObjFanin0(pPivot);
if ( !pFanin->fMarkA )
{
pFanin->fMarkA = 1;
Vec_PtrPush( vNodes, pFanin );
Vec_PtrPush( vFront, pFanin );
}
pFanin = Ivy_ObjFanin1(pPivot);
if ( pFanin && !pFanin->fMarkA )
{
pFanin->fMarkA = 1;
Vec_PtrPush( vNodes, pFanin );
Vec_PtrPush( vFront, pFanin );
}
// quit if we collected enough nodes
} while ( Vec_PtrSize(vNodes) < nNodeLimit );
// sort nodes by level
Vec_PtrSort( vNodes, Ivy_CompareNodesByLevel );
// make sure the nodes are ordered in the increasing number of levels
pFanin = Vec_PtrEntry( vNodes, 0 );
pPivot = Vec_PtrEntryLast( vNodes );
assert( pFanin->Level <= pPivot->Level );
// clean the marks and remember node numbers in the TravId
Vec_PtrForEachEntry( vNodes, pFanin, i )
{
pFanin->fMarkA = 0;
pFanin->TravId = i;
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Extra_TruthOrWords( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nWords )
{
int w;
for ( w = nWords-1; w >= 0; w-- )
pOut[w] = pIn0[w] | pIn1[w];
}
static inline int Extra_TruthIsImplyWords( unsigned * pIn1, unsigned * pIn2, int nWords )
{
int w;
for ( w = nWords-1; w >= 0; w-- )
if ( pIn1[w] & ~pIn2[w] )
return 0;
return 1;
}
/**Function*************************************************************
Synopsis [Merges two sets of bit-cuts at a node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ivy_NodeFindCutsMerge( Vec_Ptr_t * vCuts0, Vec_Ptr_t * vCuts1, Vec_Ptr_t * vCuts,
int nLeaves, int nWords, Vec_Int_t * vStore )
{
unsigned * pBitCut, * pBitCut0, * pBitCut1, * pBitCutTest;
int i, k, c, w, Counter;
// iterate through the cut pairs
Vec_PtrForEachEntry( vCuts0, pBitCut0, i )
Vec_PtrForEachEntry( vCuts1, pBitCut1, k )
{
// skip infeasible cuts
Counter = 0;
for ( w = 0; w < nWords; w++ )
{
Counter += Extra_WordCountOnes( pBitCut0[w] | pBitCut1[w] );
if ( Counter > nLeaves )
break;
}
if ( Counter > nLeaves )
continue;
// the new cut is feasible - create it
pBitCutTest = Vec_IntFetch( vStore, nWords );
Extra_TruthOrWords( pBitCutTest, pBitCut0, pBitCut1, nWords );
// filter contained cuts; try to find containing cut
w = 0;
Vec_PtrForEachEntry( vCuts, pBitCut, c )
{
if ( Extra_TruthIsImplyWords( pBitCut, pBitCutTest, nWords ) )
break;
if ( Extra_TruthIsImplyWords( pBitCutTest, pBitCut, nWords ) )
continue;
Vec_PtrWriteEntry( vCuts, w++, pBitCut );
}
if ( c != Vec_PtrSize(vCuts) )
continue;
Vec_PtrShrink( vCuts, w );
// add the cut
Vec_PtrPush( vCuts, pBitCutTest );
}
}
/**Function*************************************************************
Synopsis [Compute the set of all cuts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ivy_ManTestCutsTravAll( Ivy_Man_t * p )
{
Ivy_Store_t * pStore;
Ivy_Obj_t * pObj;
Vec_Ptr_t * vNodes, * vFront;
Vec_Int_t * vStore;
Vec_Vec_t * vBitCuts;
int i, nCutsCut, nCutsTotal, nNodeTotal, nNodeOver;
int clk = clock();
vNodes = Vec_PtrAlloc( 100 );
vFront = Vec_PtrAlloc( 100 );
vStore = Vec_IntAlloc( 100 );
vBitCuts = Vec_VecAlloc( 100 );
nNodeTotal = nNodeOver = 0;
nCutsTotal = -Ivy_ManNodeNum(p);
Ivy_ManForEachObj( p, pObj, i )
{
if ( !Ivy_ObjIsNode(pObj) )
continue;
pStore = Ivy_NodeFindCutsTravAll( p, pObj, 4, 60, vNodes, vFront, vStore, vBitCuts );
nCutsCut = pStore->nCuts;
nCutsTotal += nCutsCut;
nNodeOver += (nCutsCut == IVY_CUT_LIMIT);
nNodeTotal++;
}
printf( "Total cuts = %6d. Trivial = %6d. Nodes = %6d. Satur = %6d. ",
nCutsTotal, Ivy_ManPiNum(p) + Ivy_ManNodeNum(p), nNodeTotal, nNodeOver );
PRT( "Time", clock() - clk );
Vec_PtrFree( vNodes );
Vec_PtrFree( vFront );
Vec_IntFree( vStore );
Vec_VecFree( vBitCuts );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -119,7 +119,7 @@ Vec_Int_t * Ivy_ManDfsSeq( Ivy_Man_t * p, Vec_Int_t ** pvLatches )
Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
Ivy_ObjClearMarkA(pObj);
// make sure network does not have dangling nodes
assert( Vec_IntSize(vNodes) == Ivy_ManNodeNum(p) + Ivy_ManBufNum(p) );
// assert( Vec_IntSize(vNodes) == Ivy_ManNodeNum(p) + Ivy_ManBufNum(p) );
*pvLatches = vLatches;
return vNodes;
}
......
/**CFile****************************************************************
FileName [ivyHaig.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis [HAIG management procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - May 11, 2006.]
Revision [$Id: ivyHaig.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ivy.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*
HAIGing rules in working AIG:
- The node points to the representative of its class
- The pointer can be complemented if they have different polarity
Choice node rules in HAIG:
- Equivalent nodes are linked into a ring
- Exactly one node in the ring has fanouts (this node is called representative)
- Pointer going from a node to the next node in the ring is complemented
if the first node is complemented, compared to the representative node
- The representative node always has non-complemented pointer to the next node
- New nodes are inserted into the ring before the representative node
*/
// returns the representative node of the given HAIG node
static inline Ivy_Obj_t * Ivy_HaigObjRepr( Ivy_Obj_t * pObj )
{
Ivy_Obj_t * pTemp;
assert( !Ivy_IsComplement(pObj) );
// if the node has no equivalent or has fanout, it is representative
if ( pObj->pEquiv == NULL || Ivy_ObjRefs(pObj) > 0 )
return pObj;
// the node belongs to a class and is not a representative
// complemented edge (pObj->pEquiv) tells if it is complemented w.r.t. the repr
for ( pTemp = Ivy_Regular(pObj->pEquiv); pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) )
if ( Ivy_ObjRefs(pTemp) > 0 )
break;
// return the representative node
assert( pTemp != pObj );
return Ivy_NotCond( pTemp, Ivy_IsComplement(pObj->pEquiv) );
}
// counts the number of nodes in the equivalence class
static inline int Ivy_HaigObjCountClass( Ivy_Obj_t * pObj )
{
Ivy_Obj_t * pTemp;
int Counter;
assert( !Ivy_IsComplement(pObj) );
assert( Ivy_ObjRefs(pObj) > 0 );
if ( pObj->pEquiv == NULL )
return 1;
Counter = 1;
assert( !Ivy_IsComplement(pObj->pEquiv) );
for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) )
Counter++;
return Counter;
}
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Starts HAIG for the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ivy_ManHaigStart( Ivy_Man_t * p )
{
assert( p->pHaig == NULL );
p->pHaig = Ivy_ManDup( p );
}
/**Function*************************************************************
Synopsis [Transfers the HAIG to the newly created manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ivy_ManHaigTrasfer( Ivy_Man_t * p, Ivy_Man_t * pNew )
{
Ivy_Obj_t * pObj;
int i;
assert( p->pHaig != NULL );
Ivy_ManConst1(pNew)->pEquiv = Ivy_ManConst1(p)->pEquiv;
Ivy_ManForEachPi( pNew, pObj, i )
pObj->pEquiv = Ivy_ManPi( p, i )->pEquiv;
pNew->pHaig = p->pHaig;
}
/**Function*************************************************************
Synopsis [Stops HAIG for the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ivy_ManHaigStop( Ivy_Man_t * p )
{
Ivy_Obj_t * pObj;
int i;
assert( p->pHaig != NULL );
Ivy_ManStop( p->pHaig );
p->pHaig = NULL;
// remove dangling pointers to the HAIG objects
Ivy_ManForEachObj( p, pObj, i )
pObj->pEquiv = NULL;
}
/**Function*************************************************************
Synopsis [Creates a new node in HAIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ivy_ManHaigCreateObj( Ivy_Man_t * p, Ivy_Obj_t * pObj )
{
assert( p->pHaig != NULL );
assert( !Ivy_IsComplement(pObj) );
if ( Ivy_ObjType(pObj) == IVY_BUF )
pObj->pEquiv = Ivy_ObjChild0Equiv(pObj);
else if ( Ivy_ObjType(pObj) == IVY_LATCH )
pObj->pEquiv = Ivy_Latch( p->pHaig, Ivy_ObjChild0Equiv(pObj), pObj->Init );
else if ( Ivy_ObjType(pObj) == IVY_AND )
pObj->pEquiv = Ivy_And( p->pHaig, Ivy_ObjChild0Equiv(pObj), Ivy_ObjChild1Equiv(pObj) );
else assert( 0 );
// make sure the node points to the representative
pObj->pEquiv = Ivy_NotCond( Ivy_HaigObjRepr(Ivy_Regular(pObj->pEquiv)), Ivy_IsComplement(pObj->pEquiv) );
}
/**Function*************************************************************
Synopsis [Sets the pair of equivalent nodes in HAIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ivy_ManHaigCreateChoice( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew )
{
Ivy_Obj_t * pObjOldHaig, * pObjNewHaig;
Ivy_Obj_t * pObjOldHaigR, * pObjNewHaigR;
int fCompl;
assert( p->pHaig != NULL );
// get pointers to the classes
pObjOldHaig = pObjOld->pEquiv;
pObjNewHaig = Ivy_NotCond( Ivy_Regular(pObjNew)->pEquiv, Ivy_IsComplement(pObjNew) );
// get regular pointers
pObjOldHaigR = Ivy_Regular(pObjOldHaig);
pObjNewHaigR = Ivy_Regular(pObjNewHaig);
// check if there is phase difference between them
fCompl = (Ivy_IsComplement(pObjOldHaig) != Ivy_IsComplement(pObjNewHaig));
// if the class is the same, nothing to do
if ( pObjOldHaigR == pObjNewHaigR )
return;
// combine classes
// assume the second node does not belong to a class
assert( pObjNewHaigR->pEquiv == NULL );
// add this node to the class of pObjOldHaig
if ( pObjOldHaigR->pEquiv == NULL )
pObjNewHaigR->pEquiv = Ivy_NotCond( pObjOldHaigR, fCompl );
else
pObjNewHaigR->pEquiv = Ivy_NotCond( pObjOldHaigR->pEquiv, fCompl );
pObjOldHaigR->pEquiv = pObjNewHaigR;
// update the class of the new node
Ivy_Regular(pObjNew)->pEquiv = Ivy_NotCond( pObjOldHaigR, fCompl ^ Ivy_IsComplement(pObjNew) );
}
/**Function*************************************************************
Synopsis [Count the number of choices and choice nodes in HAIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ivy_ManHaigCountChoices( Ivy_Man_t * p, int * pnChoices )
{
Ivy_Obj_t * pObj;
int nChoices, nChoiceNodes, Counter, i;
assert( p->pHaig != NULL );
nChoices = nChoiceNodes = 0;
Ivy_ManForEachObj( p->pHaig, pObj, i )
{
if ( Ivy_ObjIsTerm(pObj) || i == 0 )
continue;
if ( Ivy_ObjRefs(pObj) == 0 )
{
assert( pObj->pEquiv == Ivy_HaigObjRepr(pObj) );
continue;
}
Counter = Ivy_HaigObjCountClass( pObj );
nChoiceNodes += (int)(Counter > 1);
nChoices += Counter - 1;
}
*pnChoices = nChoices;
return nChoiceNodes;
}
/**Function*************************************************************
Synopsis [Prints statistics of the HAIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ivy_ManHaigPrintStats( Ivy_Man_t * p )
{
int nChoices, nChoiceNodes;
assert( p->pHaig != NULL );
printf( "Original : " );
Ivy_ManPrintStats( p );
printf( "HAIG : " );
Ivy_ManPrintStats( p->pHaig );
// print choice node stats
nChoiceNodes = Ivy_ManHaigCountChoices( p, &nChoices );
printf( "Total choice nodes = %d. Total choices = %d.\n", nChoiceNodes, nChoices );
Ivy_ManHaigSimulate( p );
}
/**Function*************************************************************
Synopsis [Applies the simulation rules.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Ivy_Init_t Ivy_ManHaigSimulateAnd( Ivy_Init_t In0, Ivy_Init_t In1 )
{
assert( In0 != IVY_INIT_NONE && In1 != IVY_INIT_NONE );
if ( In0 == IVY_INIT_DC || In1 == IVY_INIT_DC )
return IVY_INIT_DC;
if ( In0 == IVY_INIT_1 && In1 == IVY_INIT_1 )
return IVY_INIT_1;
return IVY_INIT_0;
}
/**Function*************************************************************
Synopsis [Simulate HAIG using modified 3-valued simulation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ivy_ManHaigSimulate( Ivy_Man_t * p )
{
Vec_Int_t * vNodes, * vLatches;
Ivy_Obj_t * pObj;
Ivy_Init_t In0, In1;
int i, k, Counter;
assert( p->pHaig != NULL );
p = p->pHaig;
// collect latches and nodes in the DFS order
vNodes = Ivy_ManDfsSeq( p, &vLatches );
// set the PI values
Ivy_ManConst1(p)->Init = IVY_INIT_0;
Ivy_ManForEachPi( p, pObj, i )
pObj->Init = IVY_INIT_0;
// set the latch values
Ivy_ManForEachNodeVec( p, vLatches, pObj, i )
pObj->Init = IVY_INIT_DC;
// perform several rounds of simulation
for ( k = 0; k < 5; k++ )
{
// count the number of non-determinate values
Counter = 0;
Ivy_ManForEachNodeVec( p, vLatches, pObj, i )
Counter += ( pObj->Init == IVY_INIT_DC );
printf( "Iter %d : Non-determinate = %d\n", k, Counter );
// simulate the internal nodes
Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
{
In0 = Ivy_InitNotCond( Ivy_ObjFanin0(pObj)->Init, Ivy_ObjFaninC0(pObj) );
In1 = Ivy_InitNotCond( Ivy_ObjFanin1(pObj)->Init, Ivy_ObjFaninC1(pObj) );
pObj->Init = Ivy_ManHaigSimulateAnd( In0, In1 );
}
// simulate the latches
Ivy_ManForEachNodeVec( p, vLatches, pObj, i )
pObj->Level = Ivy_ObjFanin0(pObj)->Init;
Ivy_ManForEachNodeVec( p, vLatches, pObj, i )
pObj->Init = pObj->Level, pObj->Level = 0;
}
// free arrays
Vec_IntFree( vNodes );
Vec_IntFree( vLatches );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -70,6 +70,62 @@ Ivy_Man_t * Ivy_ManStart()
/**Function*************************************************************
Synopsis [Duplicates the AIG manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ivy_Man_t * Ivy_ManDup( Ivy_Man_t * p )
{
Vec_Int_t * vNodes, * vLatches;
Ivy_Man_t * pNew;
Ivy_Obj_t * pObj;
int i;
// collect latches and nodes in the DFS order
vNodes = Ivy_ManDfsSeq( p, &vLatches );
// create the new manager
pNew = Ivy_ManStart();
// create the PIs
Ivy_ManConst1(p)->pEquiv = Ivy_ManConst1(pNew);
Ivy_ManForEachPi( p, pObj, i )
pObj->pEquiv = Ivy_ObjCreatePi(pNew);
// create the fake PIs for latches
Ivy_ManForEachNodeVec( p, vLatches, pObj, i )
pObj->pEquiv = Ivy_ObjCreatePi(pNew);
// duplicate internal nodes
Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
pObj->pEquiv = Ivy_And( pNew, Ivy_ObjChild0Equiv(pObj), Ivy_ObjChild1Equiv(pObj) );
// add the POs
Ivy_ManForEachPo( p, pObj, i )
Ivy_ObjCreatePo( pNew, Ivy_ObjChild0Equiv(pObj) );
// transform additional PI nodes into latches and connect them
Ivy_ManForEachNodeVec( p, vLatches, pObj, i )
{
assert( !Ivy_ObjFaninC0(pObj) );
pObj->pEquiv->Type = IVY_LATCH;
pObj->pEquiv->Init = pObj->Init;
Ivy_ObjConnect( pNew, pObj->pEquiv, Ivy_ObjChild0Equiv(pObj), NULL );
}
// shrink the arrays
Vec_PtrShrink( pNew->vPis, Ivy_ManPiNum(p) );
// update the counters of different objects
pNew->nObjs[IVY_PI] -= Ivy_ManLatchNum(p);
pNew->nObjs[IVY_LATCH] += Ivy_ManLatchNum(p);
// free arrays
Vec_IntFree( vNodes );
Vec_IntFree( vLatches );
// check the resulting network
if ( !Ivy_ManCheck(pNew) )
printf( "Ivy_ManMakeSeq(): The check has failed.\n" );
return pNew;
}
/**Function*************************************************************
Synopsis [Stops the AIG manager.]
Description []
......@@ -81,6 +137,8 @@ Ivy_Man_t * Ivy_ManStart()
***********************************************************************/
void Ivy_ManStop( Ivy_Man_t * p )
{
if ( p->time1 ) { PRT( "Update lev ", p->time1 ); }
if ( p->time2 ) { PRT( "Update levR ", p->time2 ); }
// Ivy_TableProfile( p );
// if ( p->vFanouts ) Ivy_ManStopFanout( p );
if ( p->vChunks ) Ivy_ManStopMemory( p );
......
......@@ -89,7 +89,7 @@ void Ivy_ManAddMemory( Ivy_Man_t * p )
int i, nBytes;
assert( sizeof(Ivy_Obj_t) <= 64 );
assert( p->pListFree == NULL );
assert( (Ivy_ManObjNum(p) & IVY_PAGE_MASK) == 0 );
// assert( (Ivy_ManObjNum(p) & IVY_PAGE_MASK) == 0 );
// allocate new memory page
nBytes = sizeof(Ivy_Obj_t) * (1<<IVY_PAGE_SIZE) + 64;
pMemory = ALLOC( char, nBytes );
......
......@@ -294,45 +294,6 @@ int Ivy_MultiCover( Ivy_Man_t * p, Ivy_Eva_t * pEvals, int nLeaves, int nEvals,
}
}
/**Function*************************************************************
Synopsis [Constructs the well-balanced tree of gates.]
Description [Disregards levels and possible logic sharing.]
SideEffects []
SeeAlso []
***********************************************************************/
Ivy_Obj_t * Ivy_Multi_rec( Ivy_Man_t * p, Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type )
{
Ivy_Obj_t * pObj1, * pObj2;
if ( nObjs == 1 )
return ppObjs[0];
pObj1 = Ivy_Multi_rec( p, ppObjs, nObjs/2, Type );
pObj2 = Ivy_Multi_rec( p, ppObjs + nObjs/2, nObjs - nObjs/2, Type );
return Ivy_Oper( p, pObj1, pObj2, Type );
}
/**Function*************************************************************
Synopsis [Old code.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ivy_Obj_t * Ivy_Multi( Ivy_Man_t * p, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
{
assert( Type == IVY_AND || Type == IVY_EXOR );
assert( nArgs > 0 );
return Ivy_Multi_rec( p, pArgs, nArgs, Type );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -79,7 +79,6 @@ Ivy_Obj_t * Ivy_ObjCreate( Ivy_Man_t * p, Ivy_Obj_t * pGhost )
assert( Ivy_TableLookup(p, pGhost) == NULL );
// get memory for the new object
pObj = Ivy_ManFetchMemory( p );
//printf( "Reusing %p.\n", pObj );
assert( Ivy_ObjIsNone(pObj) );
pObj->Id = Vec_PtrSize(p->vObjs);
Vec_PtrPush( p->vObjs, pObj );
......@@ -115,6 +114,9 @@ Ivy_Obj_t * Ivy_ObjCreate( Ivy_Man_t * p, Ivy_Obj_t * pGhost )
// update node counters of the manager
p->nObjs[Ivy_ObjType(pObj)]++;
p->nCreated++;
// if HAIG is defined, create a corresponding node
if ( p->pHaig )
Ivy_ManHaigCreateObj( p, pObj );
return pObj;
}
......@@ -258,7 +260,6 @@ void Ivy_ObjDelete( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop )
// free the node
Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL );
Ivy_ManRecycleMemory( p, pObj );
//printf( "Recycling after delete %p.\n", pObj );
}
else
{
......@@ -312,7 +313,7 @@ void Ivy_ObjDelete_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop )
***********************************************************************/
void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop, int fUpdateLevel )
{
int nRefsOld;
int nRefsOld;//, clk;
// the object to be replaced cannot be complemented
assert( !Ivy_IsComplement(pObjOld) );
// the object to be replaced cannot be a terminal
......@@ -321,12 +322,16 @@ void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, in
assert( !Ivy_ObjIsBuf(Ivy_Regular(pObjNew)) );
// the object cannot be the same
assert( pObjOld != Ivy_Regular(pObjNew) );
// if HAIG is defined, create the choice node
if ( p->pHaig )
Ivy_ManHaigCreateChoice( p, pObjOld, pObjNew );
// if the new object is complemented or already used, add the buffer
if ( Ivy_IsComplement(pObjNew) || Ivy_ObjIsLatch(pObjNew) || Ivy_ObjRefs(pObjNew) > 0 || Ivy_ObjIsPi(pObjNew) || Ivy_ObjIsConst1(pObjNew) )
pObjNew = Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, pObjNew, NULL, IVY_BUF, IVY_INIT_NONE) );
assert( !Ivy_IsComplement(pObjNew) );
if ( fUpdateLevel )
{
//clk = clock();
// if the new node's arrival time is different, recursively update arrival time of the fanouts
if ( p->fFanout && !Ivy_ObjIsBuf(pObjNew) && pObjOld->Level != pObjNew->Level )
{
......@@ -334,7 +339,9 @@ void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, in
pObjOld->Level = pObjNew->Level;
Ivy_ObjUpdateLevel_rec( p, pObjOld );
}
//p->time1 += clock() - clk;
// if the new node's required time has changed, recursively update required time of the fanins
//clk = clock();
if ( p->vRequired )
{
int ReqNew = Vec_IntEntry(p->vRequired, pObjOld->Id);
......@@ -344,6 +351,7 @@ void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, in
Ivy_ObjUpdateLevelR_rec( p, pObjNew, ReqNew );
}
}
//p->time2 += clock() - clk;
}
// delete the old object
if ( fDeleteOld )
......@@ -375,7 +383,6 @@ void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, in
// recycle the object that was taken over by pObjOld
Vec_PtrWriteEntry( p->vObjs, pObjNew->Id, NULL );
Ivy_ManRecycleMemory( p, pObjNew );
//printf( "Recycling after patch %p.\n", pObjNew );
// if the new node is the buffer propagate it
if ( p->fFanout && Ivy_ObjIsBuf(pObjOld) )
Vec_PtrPush( p->vBufs, pObjOld );
......
......@@ -210,6 +210,45 @@ Ivy_Obj_t * Ivy_Maj( Ivy_Man_t * p, Ivy_Obj_t * pA, Ivy_Obj_t * pB, Ivy_Obj_t *
/**Function*************************************************************
Synopsis [Constructs the well-balanced tree of gates.]
Description [Disregards levels and possible logic sharing.]
SideEffects []
SeeAlso []
***********************************************************************/
Ivy_Obj_t * Ivy_Multi_rec( Ivy_Man_t * p, Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type )
{
Ivy_Obj_t * pObj1, * pObj2;
if ( nObjs == 1 )
return ppObjs[0];
pObj1 = Ivy_Multi_rec( p, ppObjs, nObjs/2, Type );
pObj2 = Ivy_Multi_rec( p, ppObjs + nObjs/2, nObjs - nObjs/2, Type );
return Ivy_Oper( p, pObj1, pObj2, Type );
}
/**Function*************************************************************
Synopsis [Old code.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ivy_Obj_t * Ivy_Multi( Ivy_Man_t * p, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type )
{
assert( Type == IVY_AND || Type == IVY_EXOR );
assert( nArgs > 0 );
return Ivy_Multi_rec( p, pArgs, nArgs, Type );
}
/**Function*************************************************************
Synopsis [Implements the miter.]
Description []
......
......@@ -80,10 +80,6 @@ int Ivy_ManRewriteSeq( Ivy_Man_t * p, int fUseZeroCost, int fVerbose )
// stop if all nodes have been tried once
if ( i > nNodes )
break;
if ( i == 8648 )
{
int x = 0;
}
// for each cut, try to resynthesize it
nGain = Ivy_NodeRewriteSeq( p, pManRwt, pNode, fUseZeroCost );
if ( nGain > 0 || nGain == 0 && fUseZeroCost )
......
......@@ -446,7 +446,7 @@ static inline int Abc_NodePlayerCost( int nFanins )
SeeAlso []
***********************************************************************/
static inline int Abc_NtkPlayerCostOne( int nCost, int RankCost )
static inline int Abc_NtkPlayerCostOneLevel( int nCost, int RankCost )
{
return (nCost / RankCost) + ((nCost % RankCost) > 0);
}
......@@ -466,7 +466,8 @@ int Abc_NtkPlayerCost( Abc_Ntk_t * pNtk, int RankCost, int fVerbose )
{
Abc_Obj_t * pObj;
int * pLevelCosts, * pLevelCostsR;
int nFanins, nLevels, LevelR, Cost, CostTotal, CostTotalR, nRanksTotal, nRanksTotalR, i;
int Cost, CostTotal, CostTotalR, nRanksTotal, nRanksTotalR;
int nFanins, nLevels, LevelR, i;
// compute the reverse levels
Abc_NtkStartReverseLevels( pNtk );
// compute the costs for each level
......@@ -491,17 +492,19 @@ int Abc_NtkPlayerCost( Abc_Ntk_t * pNtk, int RankCost, int fVerbose )
{
CostTotal += pLevelCosts[i];
CostTotalR += pLevelCostsR[i];
nRanksTotal += Abc_NtkPlayerCostOne( pLevelCosts[i], RankCost );
nRanksTotalR += Abc_NtkPlayerCostOne( pLevelCostsR[i], RankCost );
nRanksTotal += Abc_NtkPlayerCostOneLevel( pLevelCosts[i], RankCost );
nRanksTotalR += Abc_NtkPlayerCostOneLevel( pLevelCostsR[i], RankCost );
}
assert( CostTotal == CostTotalR );
// print out statistics
if ( fVerbose )
{
for ( i = 1; i <= nLevels; i++ )
{
printf( "Level %2d : Cost = %7d. Ranks = %6.3f. Cost = %7d. Ranks = %6.3f.\n", i,
pLevelCosts[i], ((double)pLevelCosts[i])/RankCost,
pLevelCostsR[nLevels+1-i], ((double)pLevelCostsR[nLevels+1-i])/RankCost );
}
printf( "TOTAL : Cost = %7d. Ranks = %6d. RanksR = %5d. RanksBest = %5d.\n",
CostTotal, nRanksTotal, nRanksTotalR, nLevels );
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment