mirror of https://github.com/YosysHQ/abc.git
Version abc60723
This commit is contained in:
parent
616bb095f1
commit
7e8e03206c
36
abc.dsp
36
abc.dsp
|
|
@ -1058,6 +1058,10 @@ SOURCE=.\src\sat\fraig\fraigCanon.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\fraig\fraigChoice.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\fraig\fraigFanout.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -2106,15 +2110,19 @@ SOURCE=.\src\temp\ivy\ivyDsd.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyFanout.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyMan.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyMulti.c
|
||||
SOURCE=.\src\temp\ivy\ivyMem.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyMulti8.c
|
||||
SOURCE=.\src\temp\ivy\ivyMulti.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
|
|
@ -2130,14 +2138,6 @@ SOURCE=.\src\temp\ivy\ivyResyn.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyRewrite.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyRwrAlg.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyRwrPre.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -2150,10 +2150,6 @@ SOURCE=.\src\temp\ivy\ivyTable.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyUndo.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\ivy\ivyUtil.c
|
||||
# End Source File
|
||||
# End Group
|
||||
|
|
@ -2166,14 +2162,6 @@ SOURCE=.\src\temp\player\player.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\player\playerAbc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\player\playerBuild.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\player\playerCore.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -2182,6 +2170,10 @@ SOURCE=.\src\temp\player\playerMan.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\player\playerToAbc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\temp\player\playerUtil.c
|
||||
# End Source File
|
||||
# End Group
|
||||
|
|
|
|||
|
|
@ -544,6 +544,7 @@ extern char * Abc_ObjNameDummy( char * pPrefix, int Num, int nDigits
|
|||
extern char * Abc_NtkLogicStoreName( Abc_Obj_t * pNodeNew, char * pNameOld );
|
||||
extern char * Abc_NtkLogicStoreNamePlus( Abc_Obj_t * pNodeNew, char * pNameOld, char * pSuffix );
|
||||
extern void Abc_NtkDupCioNamesTable( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
|
||||
extern void Abc_NtkDupCioNamesTableNoLatches( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
|
||||
extern void Abc_NtkDupCioNamesTableDual( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
|
||||
extern Vec_Ptr_t * Abc_NodeGetFaninNames( Abc_Obj_t * pNode );
|
||||
extern Vec_Ptr_t * Abc_NodeGetFakeNames( int nNames );
|
||||
|
|
@ -571,6 +572,7 @@ extern void Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk );
|
|||
/*=== abcNtk.c ==========================================================*/
|
||||
extern Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func );
|
||||
extern Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func );
|
||||
extern Abc_Ntk_t * Abc_NtkStartFromNoLatches( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func );
|
||||
extern Abc_Ntk_t * Abc_NtkStartFromDual( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func );
|
||||
extern void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
|
||||
extern Abc_Ntk_t * Abc_NtkStartRead( char * pName );
|
||||
|
|
|
|||
|
|
@ -78,9 +78,20 @@ struct Abc_Aig_t_
|
|||
pEnt2 = pEnt? pEnt->pNext: NULL )
|
||||
|
||||
// hash key for the structural hash table
|
||||
static inline unsigned Abc_HashKey2( Abc_Obj_t * p0, Abc_Obj_t * p1, int TableSize ) { return ((unsigned)(p0) + (unsigned)(p1) * 12582917) % TableSize; }
|
||||
//static inline unsigned Abc_HashKey2( Abc_Obj_t * p0, Abc_Obj_t * p1, int TableSize ) { return ((unsigned)(p0) + (unsigned)(p1) * 12582917) % TableSize; }
|
||||
//static inline unsigned Abc_HashKey2( Abc_Obj_t * p0, Abc_Obj_t * p1, int TableSize ) { return ((unsigned)((a)->Id + (b)->Id) * ((a)->Id + (b)->Id + 1) / 2) % TableSize; }
|
||||
|
||||
// hashing the node
|
||||
static unsigned Abc_HashKey2( Abc_Obj_t * p0, Abc_Obj_t * p1, int TableSize )
|
||||
{
|
||||
unsigned Key = 0;
|
||||
Key ^= Abc_ObjRegular(p0)->Id * 7937;
|
||||
Key ^= Abc_ObjRegular(p1)->Id * 2971;
|
||||
Key ^= Abc_ObjIsComplement(p0) * 911;
|
||||
Key ^= Abc_ObjIsComplement(p1) * 353;
|
||||
return Key % TableSize;
|
||||
}
|
||||
|
||||
// structural hash table procedures
|
||||
static Abc_Obj_t * Abc_AigAndCreate( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 );
|
||||
static Abc_Obj_t * Abc_AigAndCreateFrom( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1, Abc_Obj_t * pAnd );
|
||||
|
|
|
|||
|
|
@ -179,6 +179,35 @@ void Abc_NtkDupCioNamesTable( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
|
|||
Abc_NtkLogicStoreName( Abc_NtkLatch(pNtkNew,i), Abc_ObjName(Abc_ObjFanout0Ntk(pObj)) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the name arrays.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkDupCioNamesTableNoLatches( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
assert( Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkNew) );
|
||||
assert( Abc_NtkPoNum(pNtk) == Abc_NtkPoNum(pNtkNew) );
|
||||
assert( Abc_NtkAssertNum(pNtk) == Abc_NtkAssertNum(pNtkNew) );
|
||||
assert( Nm_ManNumEntries(pNtk->pManName) > 0 );
|
||||
assert( Nm_ManNumEntries(pNtkNew->pManName) == 0 );
|
||||
// copy the CI/CO names if given
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(Abc_ObjFanout0Ntk(pObj)) );
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
Abc_NtkLogicStoreName( Abc_NtkPo(pNtkNew,i), Abc_ObjName(Abc_ObjFanin0Ntk(pObj)) );
|
||||
Abc_NtkForEachAssert( pNtk, pObj, i )
|
||||
Abc_NtkLogicStoreName( Abc_NtkAssert(pNtkNew,i), Abc_ObjName(Abc_ObjFanin0Ntk(pObj)) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the name arrays.]
|
||||
|
|
|
|||
|
|
@ -153,6 +153,52 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_
|
|||
return pNtkNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts a new network using existing network as a model.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkStartFromNoLatches( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
if ( pNtk == NULL )
|
||||
return NULL;
|
||||
// start the network
|
||||
pNtkNew = Abc_NtkAlloc( Type, Func );
|
||||
// duplicate the name and the spec
|
||||
pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
|
||||
pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
|
||||
// clean the node copy fields
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
pObj->pCopy = NULL;
|
||||
// map the constant nodes
|
||||
if ( Abc_NtkConst1(pNtk) )
|
||||
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
|
||||
// clone the PIs/POs/latches
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_NtkDupObj(pNtkNew, pObj);
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
Abc_NtkDupObj(pNtkNew, pObj);
|
||||
Abc_NtkForEachAssert( pNtk, pObj, i )
|
||||
Abc_NtkDupObj(pNtkNew, pObj);
|
||||
// transfer the names
|
||||
if ( Type != ABC_NTK_NETLIST )
|
||||
Abc_NtkDupCioNamesTableNoLatches( pNtk, pNtkNew );
|
||||
Abc_ManTimeDup( pNtk, pNtkNew );
|
||||
// check that the CI/CO/latches are copied correctly
|
||||
assert( Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkNew) );
|
||||
assert( Abc_NtkPoNum(pNtk) == Abc_NtkPoNum(pNtkNew) );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts a new network using existing network as a model.]
|
||||
|
|
|
|||
|
|
@ -88,6 +88,11 @@ static int Abc_CommandGen ( Abc_Frame_t * pAbc, int argc, char ** arg
|
|||
static int Abc_CommandXyz ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
||||
static int Abc_CommandIStrash ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandICut ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandIRewrite ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandIResyn ( 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 );
|
||||
static int Abc_CommandFraigStore ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -199,6 +204,11 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "Various", "xyz", Abc_CommandXyz, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Various", "test", Abc_CommandTest, 0 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "New AIG", "istrash", Abc_CommandIStrash, 1 );
|
||||
Cmd_CommandAdd( pAbc, "New AIG", "icut", Abc_CommandICut, 0 );
|
||||
Cmd_CommandAdd( pAbc, "New AIG", "irw", Abc_CommandIRewrite, 1 );
|
||||
Cmd_CommandAdd( pAbc, "New AIG", "iresyn", Abc_CommandIResyn, 1 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Fraiging", "fraig_trust", Abc_CommandFraigTrust, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Fraiging", "fraig_store", Abc_CommandFraigStore, 0 );
|
||||
|
|
@ -4073,10 +4083,12 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
pParams->fDrop = 0; // drop cuts on the fly
|
||||
pParams->fDag = 0; // compute DAG cuts
|
||||
pParams->fTree = 0; // compute tree cuts
|
||||
pParams->fGlobal = 0; // compute global cuts
|
||||
pParams->fLocal = 0; // compute local cuts
|
||||
pParams->fFancy = 0; // compute something fancy
|
||||
pParams->fVerbose = 0; // the verbosiness flag
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KMtfdxyzvoh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KMtfdxyglzvoh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -4117,6 +4129,12 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
case 'y':
|
||||
pParams->fTree ^= 1;
|
||||
break;
|
||||
case 'g':
|
||||
pParams->fGlobal ^= 1;
|
||||
break;
|
||||
case 'l':
|
||||
pParams->fLocal ^= 1;
|
||||
break;
|
||||
case 'z':
|
||||
pParams->fFancy ^= 1;
|
||||
break;
|
||||
|
|
@ -4178,6 +4196,8 @@ usage:
|
|||
fprintf( pErr, "\t-d : toggle dropping when fanouts are done [default = %s]\n", pParams->fDrop? "yes": "no" );
|
||||
fprintf( pErr, "\t-x : toggle computing only DAG cuts [default = %s]\n", pParams->fDag? "yes": "no" );
|
||||
fprintf( pErr, "\t-y : toggle computing only tree cuts [default = %s]\n", pParams->fTree? "yes": "no" );
|
||||
fprintf( pErr, "\t-g : toggle computing only global cuts [default = %s]\n", pParams->fGlobal? "yes": "no" );
|
||||
fprintf( pErr, "\t-l : toggle computing only local cuts [default = %s]\n", pParams->fLocal? "yes": "no" );
|
||||
fprintf( pErr, "\t-z : toggle fancy computations [default = %s]\n", pParams->fFancy? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
|
|
@ -4462,7 +4482,7 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
int nPlaMax;
|
||||
int fVerbose;
|
||||
// extern Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nPlaMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose );
|
||||
extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose );
|
||||
extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
|
|
@ -4647,11 +4667,11 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
// Ivy_TruthTest();
|
||||
|
||||
|
||||
Ivy_TruthEstimateNodesTest();
|
||||
// Ivy_TruthEstimateNodesTest();
|
||||
|
||||
// pNtkRes = Abc_NtkIvy( pNtk );
|
||||
pNtkRes = Abc_NtkIvy( pNtk );
|
||||
// pNtkRes = Abc_NtkPlayer( pNtk, nLevels, 0 );
|
||||
pNtkRes = NULL;
|
||||
// pNtkRes = NULL;
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Command has failed.\n" );
|
||||
|
|
@ -4670,6 +4690,290 @@ usage:
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandIStrash( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes;
|
||||
int c;
|
||||
extern Abc_Ntk_t * Abc_NtkIvyStrash( Abc_Ntk_t * pNtk );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
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;
|
||||
}
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "Only works for combinatinally strashed AIG networks.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
pNtkRes = Abc_NtkIvyStrash( pNtk );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Command has failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
// replace the current network
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: istrash [-h]\n" );
|
||||
fprintf( pErr, "\t perform sequential structural hashing\n" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandICut( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk;
|
||||
int c, nInputs;
|
||||
extern void Abc_NtkIvyCuts( Abc_Ntk_t * pNtk, int nInputs );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
nInputs = 5;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Kh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'K':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-K\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nInputs = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nInputs < 0 )
|
||||
goto usage;
|
||||
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;
|
||||
}
|
||||
|
||||
Abc_NtkIvyCuts( pNtk, nInputs );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: icut [-K num] [-h]\n" );
|
||||
fprintf( pErr, "\t computes sequential cuts of the given size\n" );
|
||||
fprintf( pErr, "\t-K num : the number of cut inputs (2 <= num <= 6) [default = %d]\n", nInputs );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandIRewrite( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes;
|
||||
int c, fUpdateLevel, fUseZeroCost, fVerbose;
|
||||
extern Abc_Ntk_t * Abc_NtkIvyRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeroCost, int fVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
fUpdateLevel = 1;
|
||||
fUseZeroCost = 0;
|
||||
fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "lzvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'l':
|
||||
fUpdateLevel ^= 1;
|
||||
break;
|
||||
case 'z':
|
||||
fUseZeroCost ^= 1;
|
||||
break;
|
||||
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_NtkIvyRewrite( pNtk, fUpdateLevel, fUseZeroCost, fVerbose );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Command has failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
// replace the current network
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: irw [-lzvh]\n" );
|
||||
fprintf( pErr, "\t perform combinational AIG rewriting\n" );
|
||||
fprintf( pErr, "\t-l : toggle preserving the number of levels [default = %s]\n", fUpdateLevel? "yes": "no" );
|
||||
fprintf( pErr, "\t-z : toggle using zero-cost replacements [default = %s]\n", fUseZeroCost? "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*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandIResyn( 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_NtkIvyResyn( Abc_Ntk_t * pNtk, int fUpdateLevel, 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, "lzvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'l':
|
||||
fUpdateLevel ^= 1;
|
||||
break;
|
||||
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_NtkIvyResyn( pNtk, fUpdateLevel, fVerbose );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Command has failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
// replace the current network
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: iresyn [-lvh]\n" );
|
||||
fprintf( pErr, "\t performs combinational resynthesis\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*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -265,6 +265,9 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_
|
|||
pNodeOld->pCopy = vSuper->pArray[0];
|
||||
Abc_HManAddProto( pNodeOld->pCopy, pNodeOld );
|
||||
vSuper->nSize = 0;
|
||||
// if ( Abc_ObjRegular(pNodeOld->pCopy) == Abc_NtkConst1(pNtkNew) )
|
||||
// printf( "Constant node\n" );
|
||||
// assert( pNodeOld->Level >= Abc_ObjRegular(pNodeOld->pCopy)->Level );
|
||||
return pNodeOld->pCopy;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,9 +29,10 @@
|
|||
static void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq );
|
||||
static void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq );
|
||||
|
||||
|
||||
extern int nTotal, nGood, nEqual;
|
||||
|
||||
static Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -66,6 +67,13 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
|
|||
// start the manager
|
||||
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
|
||||
p = Cut_ManStart( pParams );
|
||||
// compute node attributes if local or global cuts are requested
|
||||
if ( pParams->fGlobal || pParams->fLocal )
|
||||
{
|
||||
extern Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk );
|
||||
Cut_ManSetNodeAttrs( p, Abc_NtkGetNodeAttributes(pNtk) );
|
||||
}
|
||||
// prepare for cut dropping
|
||||
if ( pParams->fDrop )
|
||||
Cut_ManSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) );
|
||||
// set cuts for PIs
|
||||
|
|
@ -316,6 +324,8 @@ void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
|
|||
int fDagNode, fTriv, TreeCode = 0;
|
||||
// assert( Abc_NtkIsStrash(pObj->pNtk) );
|
||||
assert( Abc_ObjFaninNum(pObj) == 2 );
|
||||
|
||||
|
||||
// check if the node is a DAG node
|
||||
fDagNode = (Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj));
|
||||
// increment the counter of DAG nodes
|
||||
|
|
@ -330,6 +340,25 @@ void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
|
|||
pFanin = Abc_ObjFanin1(pObj);
|
||||
TreeCode |= ((Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin)) << 1);
|
||||
}
|
||||
|
||||
|
||||
// changes due to the global/local cut computation
|
||||
{
|
||||
Cut_Params_t * pParams = Cut_ManReadParams(p);
|
||||
if ( pParams->fLocal )
|
||||
{
|
||||
Vec_Int_t * vNodeAttrs = Cut_ManReadNodeAttrs(p);
|
||||
fDagNode = Vec_IntEntry( vNodeAttrs, pObj->Id );
|
||||
if ( fDagNode ) Cut_ManIncrementDagNodes( p );
|
||||
// fTriv = fDagNode || !pParams->fGlobal;
|
||||
fTriv = !Vec_IntEntry( vNodeAttrs, pObj->Id );
|
||||
TreeCode = 0;
|
||||
pFanin = Abc_ObjFanin0(pObj);
|
||||
TreeCode |= Vec_IntEntry( vNodeAttrs, pFanin->Id );
|
||||
pFanin = Abc_ObjFanin1(pObj);
|
||||
TreeCode |= (Vec_IntEntry( vNodeAttrs, pFanin->Id ) << 1);
|
||||
}
|
||||
}
|
||||
return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
|
||||
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), fTriv, TreeCode );
|
||||
}
|
||||
|
|
@ -436,6 +465,95 @@ void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq )
|
|||
Cut_CutPrintList( pList, fSeq );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Assigns global attributes randomly.]
|
||||
|
||||
Description [Old code.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Abc_NtkGetNodeAttributes2( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Int_t * vAttrs;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
|
||||
vAttrs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 );
|
||||
// Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
// Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
{
|
||||
// if ( Abc_ObjIsNode(pObj) && (rand() % 4 == 0) )
|
||||
if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) && (rand() % 3 == 0) )
|
||||
Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
|
||||
}
|
||||
return vAttrs;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Assigns global attributes randomly.]
|
||||
|
||||
Description [Old code.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkSubDagSize_rec( Abc_Obj_t * pObj, Vec_Int_t * vAttrs )
|
||||
{
|
||||
if ( Abc_NodeIsTravIdCurrent(pObj) )
|
||||
return 0;
|
||||
Abc_NodeSetTravIdCurrent(pObj);
|
||||
if ( Vec_IntEntry( vAttrs, pObj->Id ) )
|
||||
return 0;
|
||||
if ( Abc_ObjIsCi(pObj) )
|
||||
return 1;
|
||||
assert( Abc_ObjFaninNum(pObj) == 2 );
|
||||
return 1 + Abc_NtkSubDagSize_rec(Abc_ObjFanin0(pObj), vAttrs) +
|
||||
Abc_NtkSubDagSize_rec(Abc_ObjFanin1(pObj), vAttrs);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Assigns global attributes randomly.]
|
||||
|
||||
Description [Old code.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Int_t * vAttrs;
|
||||
Abc_Obj_t * pObj;
|
||||
int i, nSize;
|
||||
assert( Abc_NtkIsDfsOrdered(pNtk) );
|
||||
vAttrs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 );
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
{
|
||||
// skip no-nodes and nodes without fanouts
|
||||
if ( pObj->Id == 0 || !(Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj)) )
|
||||
continue;
|
||||
// the node has more than one fanout - count its sub-DAG size
|
||||
Abc_NtkIncrementTravId( pNtk );
|
||||
nSize = Abc_NtkSubDagSize_rec( pObj, vAttrs );
|
||||
if ( nSize > 15 )
|
||||
Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
|
||||
}
|
||||
return vAttrs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -62,6 +62,9 @@ Abc_Ntk_t * Abc_NtkFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes, int f
|
|||
fExdc = 0, printf( "Warning: Networks has no EXDC.\n" );
|
||||
// perform fraiging
|
||||
pMan = Abc_NtkToFraig( pNtk, pParams, fAllNodes, fExdc );
|
||||
// add algebraic choices
|
||||
if ( pPars->fChoicing )
|
||||
Fraig_ManAddChoices( pMan, 0, 6 );
|
||||
// prove the miter if asked to
|
||||
if ( pPars->fTryProve )
|
||||
Fraig_ManProveMiter( pMan );
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan );
|
||||
static Abc_Ntk_t * Abc_NtkFromAigSeq( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan );
|
||||
static Ivy_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtkOld );
|
||||
|
||||
static void Abc_NtkStrashPerformAig( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan );
|
||||
|
|
@ -36,13 +37,28 @@ static Ivy_Obj_t * Abc_NodeStrashAigExorAig( Ivy_Man_t * pMan, Abc_Obj_t * pNod
|
|||
static Ivy_Obj_t * Abc_NodeStrashAigFactorAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char * pSop );
|
||||
extern char * Mio_GateReadSop( void * pGate );
|
||||
|
||||
typedef int Abc_Edge_t;
|
||||
static inline Abc_Edge_t Abc_EdgeCreate( int Id, int fCompl ) { return (Id << 1) | fCompl; }
|
||||
static inline int Abc_EdgeId( Abc_Edge_t Edge ) { return Edge >> 1; }
|
||||
static inline int Abc_EdgeIsComplement( Abc_Edge_t Edge ) { return Edge & 1; }
|
||||
static inline Abc_Edge_t Abc_EdgeRegular( Abc_Edge_t Edge ) { return (Edge >> 1) << 1; }
|
||||
static inline Abc_Edge_t Abc_EdgeNot( Abc_Edge_t Edge ) { return Edge ^ 1; }
|
||||
static inline Abc_Edge_t Abc_EdgeNotCond( Abc_Edge_t Edge, int fCond ) { return Edge ^ fCond; }
|
||||
static inline Abc_Edge_t Abc_EdgeFromNode( Abc_Obj_t * pNode ) { return Abc_EdgeCreate( Abc_ObjRegular(pNode)->Id, Abc_ObjIsComplement(pNode) ); }
|
||||
static inline Abc_Obj_t * Abc_EdgeToNode( Abc_Ntk_t * p, Abc_Edge_t Edge ) { return Abc_ObjNotCond( Abc_NtkObj(p, Abc_EdgeId(Edge)), Abc_EdgeIsComplement(Edge) ); }
|
||||
|
||||
static inline Abc_Obj_t * Abc_ObjFanin0Ivy( Abc_Ntk_t * p, Ivy_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_EdgeToNode(p, Ivy_ObjFanin0(pObj)->TravId), Ivy_ObjFaninC0(pObj) ); }
|
||||
static inline Abc_Obj_t * Abc_ObjFanin1Ivy( Abc_Ntk_t * p, Ivy_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_EdgeToNode(p, Ivy_ObjFanin1(pObj)->TravId), Ivy_ObjFaninC1(pObj) ); }
|
||||
|
||||
static int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Gives the current ABC network to AIG manager for processing.]
|
||||
Synopsis [Prepares the IVY package.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -51,13 +67,10 @@ extern char * Mio_GateReadSop( void * pGate );
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
|
||||
Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq )
|
||||
{
|
||||
Ivy_Man_t * pMan, * pTemp = NULL;
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
Ivy_Man_t * pMan;
|
||||
int fCleanup = 1;
|
||||
int nNodes;
|
||||
|
||||
assert( !Abc_NtkIsNetlist(pNtk) );
|
||||
assert( !Abc_NtkIsSeq(pNtk) );
|
||||
if ( Abc_NtkIsBddLogic(pNtk) )
|
||||
|
|
@ -68,10 +81,14 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
if ( Abc_NtkCountSelfFeedLatches(pNtk) )
|
||||
{
|
||||
printf( "Warning: The network has %d self-feeding latches. Quitting.\n", Abc_NtkCountSelfFeedLatches(pNtk) );
|
||||
return NULL;
|
||||
}
|
||||
// print warning about choice nodes
|
||||
if ( Abc_NtkGetChoiceNum( pNtk ) )
|
||||
printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" );
|
||||
|
||||
// convert to the AIG manager
|
||||
pMan = Abc_NtkToAig( pNtk );
|
||||
if ( !Ivy_ManCheck( pMan ) )
|
||||
|
|
@ -80,35 +97,38 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
|
|||
Ivy_ManStop( pMan );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Ivy_MffcTest( pMan );
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
if ( fSeq )
|
||||
{
|
||||
int nLatches = Abc_NtkLatchNum(pNtk);
|
||||
int * pInit = Abc_NtkCollectLatchValues( pNtk );
|
||||
Ivy_ManMakeSeq( pMan, nLatches, pInit );
|
||||
FREE( pInit );
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
}
|
||||
return pMan;
|
||||
}
|
||||
|
||||
// pMan = Ivy_ManBalance( pTemp = pMan, 1 );
|
||||
// Ivy_ManStop( pTemp );
|
||||
/**Function*************************************************************
|
||||
|
||||
// Ivy_ManSeqRewrite( pMan, 0, 0 );
|
||||
// Ivy_ManTestCutsAlg( pMan );
|
||||
// Ivy_ManTestCutsBool( pMan );
|
||||
// Ivy_ManRewriteAlg( pMan, 1, 1 );
|
||||
Synopsis [Prepares the IVY package.]
|
||||
|
||||
// pMan = Ivy_ManResyn( pTemp = pMan, 1 );
|
||||
// Ivy_ManStop( pTemp );
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
// Ivy_ManTestCutsAll( pMan );
|
||||
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
// Ivy_ManRewritePre( pMan, 1, 0, 0 );
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
|
||||
// Ivy_ManRequiredLevels( pMan );
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkIvyAfter( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, int fSeq )
|
||||
{
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
int nNodes, fCleanup = 1;
|
||||
// convert from the AIG manager
|
||||
pNtkAig = Abc_NtkFromAig( pNtk, pMan );
|
||||
Ivy_ManStop( pMan );
|
||||
|
||||
if ( fSeq )
|
||||
pNtkAig = Abc_NtkFromAigSeq( pNtk, pMan );
|
||||
else
|
||||
pNtkAig = Abc_NtkFromAig( pNtk, pMan );
|
||||
// report the cleanup results
|
||||
if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) )
|
||||
printf( "Warning: AIG cleanup removed %d nodes (this is not a bug).\n", nNodes );
|
||||
|
|
@ -125,6 +145,206 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
|
|||
return pNtkAig;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Gives the current ABC network to AIG manager for processing.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkIvyStrash( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
Ivy_Man_t * pMan;
|
||||
pMan = Abc_NtkIvyBefore( pNtk, 1 );
|
||||
if ( pMan == NULL )
|
||||
return NULL;
|
||||
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 );
|
||||
Ivy_Man_t * pMan;
|
||||
pMan = Abc_NtkIvyBefore( pNtk, 1 );
|
||||
if ( pMan == NULL )
|
||||
return;
|
||||
Ivy_CutComputeAll( pMan, nInputs );
|
||||
Ivy_ManStop( pMan );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Gives the current ABC network to AIG manager for processing.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkIvyRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeroCost, int fVerbose )
|
||||
{
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
Ivy_Man_t * pMan;
|
||||
pMan = Abc_NtkIvyBefore( pNtk, 0 );
|
||||
if ( pMan == NULL )
|
||||
return NULL;
|
||||
Ivy_ManRewritePre( pMan, fUpdateLevel, fUseZeroCost, fVerbose );
|
||||
pNtkAig = Abc_NtkIvyAfter( pNtk, pMan, 0 );
|
||||
Ivy_ManStop( pMan );
|
||||
return pNtkAig;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Gives the current ABC network to AIG manager for processing.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkIvyResyn( Abc_Ntk_t * pNtk, int fUpdateLevel, int fVerbose )
|
||||
{
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
Ivy_Man_t * pMan, * pTemp;
|
||||
pMan = Abc_NtkIvyBefore( pNtk, 0 );
|
||||
if ( pMan == NULL )
|
||||
return NULL;
|
||||
pMan = Ivy_ManResyn( pTemp = pMan, fUpdateLevel, fVerbose );
|
||||
Ivy_ManStop( pTemp );
|
||||
pNtkAig = Abc_NtkIvyAfter( pNtk, pMan, 0 );
|
||||
Ivy_ManStop( pMan );
|
||||
return pNtkAig;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Gives the current ABC network to AIG manager for processing.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
Ivy_Man_t * pMan, * pTemp;
|
||||
int fCleanup = 1;
|
||||
int nNodes;
|
||||
int nLatches = Abc_NtkLatchNum(pNtk);
|
||||
int * pInit = Abc_NtkCollectLatchValues( pNtk );
|
||||
|
||||
assert( !Abc_NtkIsNetlist(pNtk) );
|
||||
assert( !Abc_NtkIsSeq(pNtk) );
|
||||
if ( Abc_NtkIsBddLogic(pNtk) )
|
||||
{
|
||||
if ( !Abc_NtkBddToSop(pNtk, 0) )
|
||||
{
|
||||
FREE( pInit );
|
||||
printf( "Converting to SOPs has failed.\n" );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if ( Abc_NtkCountSelfFeedLatches(pNtk) )
|
||||
{
|
||||
printf( "Warning: The network has %d self-feeding latches. Quitting.\n", Abc_NtkCountSelfFeedLatches(pNtk) );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// print warning about choice nodes
|
||||
if ( Abc_NtkGetChoiceNum( pNtk ) )
|
||||
printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" );
|
||||
|
||||
// convert to the AIG manager
|
||||
pMan = Abc_NtkToAig( pNtk );
|
||||
if ( !Ivy_ManCheck( pMan ) )
|
||||
{
|
||||
FREE( pInit );
|
||||
printf( "AIG check has failed.\n" );
|
||||
Ivy_ManStop( pMan );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Ivy_MffcTest( pMan );
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
|
||||
// pMan = Ivy_ManBalance( pTemp = pMan, 1 );
|
||||
// Ivy_ManStop( pTemp );
|
||||
|
||||
// Ivy_ManSeqRewrite( pMan, 0, 0 );
|
||||
// Ivy_ManTestCutsAlg( pMan );
|
||||
// Ivy_ManTestCutsBool( pMan );
|
||||
// Ivy_ManRewriteAlg( pMan, 1, 1 );
|
||||
|
||||
// pMan = Ivy_ManResyn( pTemp = pMan, 1, 0 );
|
||||
// Ivy_ManStop( pTemp );
|
||||
|
||||
Ivy_ManTestCutsAll( pMan );
|
||||
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
// Ivy_ManRewritePre( pMan, 1, 0, 0 );
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
// printf( "\n" );
|
||||
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
// Ivy_ManMakeSeq( pMan, nLatches, pInit );
|
||||
// Ivy_ManPrintStats( pMan );
|
||||
|
||||
// Ivy_ManRequiredLevels( pMan );
|
||||
|
||||
// convert from the AIG manager
|
||||
pNtkAig = Abc_NtkFromAig( pNtk, pMan );
|
||||
// pNtkAig = Abc_NtkFromAigSeq( pNtk, pMan );
|
||||
Ivy_ManStop( pMan );
|
||||
|
||||
// report the cleanup results
|
||||
if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) )
|
||||
printf( "Warning: AIG cleanup removed %d nodes (this is not a bug).\n", nNodes );
|
||||
// duplicate EXDC
|
||||
if ( pNtk->pExdc )
|
||||
pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc );
|
||||
// make sure everything is okay
|
||||
if ( !Abc_NtkCheck( pNtkAig ) )
|
||||
{
|
||||
FREE( pInit );
|
||||
printf( "Abc_NtkStrash: The network check has failed.\n" );
|
||||
Abc_NtkDelete( pNtkAig );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FREE( pInit );
|
||||
return pNtkAig;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts the network from the AIG manager into ABC.]
|
||||
|
|
@ -142,47 +362,119 @@ Abc_Ntk_t * Abc_NtkFromAig( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan )
|
|||
Abc_Ntk_t * pNtk;
|
||||
Abc_Obj_t * pObj, * pObjNew, * pFaninNew, * pFaninNew0, * pFaninNew1;
|
||||
Ivy_Obj_t * pNode;
|
||||
int i, Fanin;
|
||||
int i;
|
||||
// perform strashing
|
||||
pNtk = Abc_NtkStartFrom( pNtkOld, ABC_NTK_STRASH, ABC_FUNC_AIG );
|
||||
// transfer the pointers to the basic nodes
|
||||
Ivy_ManConst1(pMan)->TravId = (Abc_NtkConst1(pNtk)->Id << 1);
|
||||
Ivy_ManConst1(pMan)->TravId = Abc_EdgeFromNode( Abc_NtkConst1(pNtk) );
|
||||
Abc_NtkForEachCi( pNtkOld, pObj, i )
|
||||
Ivy_ManPi(pMan, i)->TravId = (pObj->pCopy->Id << 1);
|
||||
Ivy_ManPi(pMan, i)->TravId = Abc_EdgeFromNode( pObj->pCopy );
|
||||
// rebuild the AIG
|
||||
vNodes = Ivy_ManDfs( pMan );
|
||||
Ivy_ManForEachNodeVec( pMan, vNodes, pNode, i )
|
||||
{
|
||||
// add the first fanins
|
||||
Fanin = Ivy_ObjFanin0(pNode)->TravId;
|
||||
pFaninNew0 = Abc_NtkObj( pNtk, Fanin >> 1 );
|
||||
pFaninNew0 = Abc_ObjNotCond( pFaninNew0, Ivy_ObjFaninC0(pNode) ^ (Fanin&1) );
|
||||
pFaninNew0 = Abc_ObjFanin0Ivy( pNtk, pNode );
|
||||
if ( Ivy_ObjIsBuf(pNode) )
|
||||
{
|
||||
pNode->TravId = (Abc_ObjRegular(pFaninNew0)->Id << 1) | Abc_ObjIsComplement(pFaninNew0);
|
||||
pNode->TravId = Abc_EdgeFromNode( pFaninNew0 );
|
||||
continue;
|
||||
}
|
||||
// add the first second
|
||||
Fanin = Ivy_ObjFanin1(pNode)->TravId;
|
||||
pFaninNew1 = Abc_NtkObj( pNtk, Fanin >> 1 );
|
||||
pFaninNew1 = Abc_ObjNotCond( pFaninNew1, Ivy_ObjFaninC1(pNode) ^ (Fanin&1) );
|
||||
pFaninNew1 = Abc_ObjFanin1Ivy( pNtk, pNode );
|
||||
// create the new node
|
||||
if ( Ivy_ObjIsExor(pNode) )
|
||||
pObjNew = Abc_AigXor( pNtk->pManFunc, pFaninNew0, pFaninNew1 );
|
||||
else
|
||||
pObjNew = Abc_AigAnd( pNtk->pManFunc, pFaninNew0, pFaninNew1 );
|
||||
pNode->TravId = (Abc_ObjRegular(pObjNew)->Id << 1) | Abc_ObjIsComplement(pObjNew);
|
||||
pNode->TravId = Abc_EdgeFromNode( pObjNew );
|
||||
}
|
||||
Vec_IntFree( vNodes );
|
||||
// connect the PO nodes
|
||||
Abc_NtkForEachCo( pNtkOld, pObj, i )
|
||||
{
|
||||
pNode = Ivy_ManPo(pMan, i);
|
||||
Fanin = Ivy_ObjFanin0(pNode)->TravId;
|
||||
pFaninNew = Abc_NtkObj( pNtk, Fanin >> 1 );
|
||||
pFaninNew = Abc_ObjNotCond( pFaninNew, Ivy_ObjFaninC0(pNode) ^ (Fanin&1) );
|
||||
pFaninNew = Abc_ObjFanin0Ivy( pNtk, Ivy_ManPo(pMan, i) );
|
||||
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
|
||||
}
|
||||
Vec_IntFree( vNodes );
|
||||
if ( !Abc_NtkCheck( pNtk ) )
|
||||
fprintf( stdout, "Abc_NtkFromAig(): Network check has failed.\n" );
|
||||
return pNtk;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts the network from the AIG manager into ABC.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkFromAigSeq( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan )
|
||||
{
|
||||
Vec_Int_t * vNodes, * vLatches;
|
||||
Abc_Ntk_t * pNtk;
|
||||
Abc_Obj_t * pObj, * pObjNew, * pFaninNew, * pFaninNew0, * pFaninNew1;
|
||||
Ivy_Obj_t * pNode;
|
||||
int i;
|
||||
assert( Ivy_ManLatchNum(pMan) > 0 );
|
||||
// perform strashing
|
||||
pNtk = Abc_NtkStartFromNoLatches( pNtkOld, ABC_NTK_STRASH, ABC_FUNC_AIG );
|
||||
// transfer the pointers to the basic nodes
|
||||
Ivy_ManConst1(pMan)->TravId = Abc_EdgeFromNode( Abc_NtkConst1(pNtk) );
|
||||
Abc_NtkForEachPi( pNtkOld, pObj, i )
|
||||
Ivy_ManPi(pMan, i)->TravId = Abc_EdgeFromNode( pObj->pCopy );
|
||||
// create latches of the new network
|
||||
vNodes = Ivy_ManDfsSeq( pMan, &vLatches );
|
||||
Ivy_ManForEachNodeVec( pMan, vLatches, pNode, i )
|
||||
{
|
||||
pObjNew = Abc_NtkCreateLatch( pNtk );
|
||||
if ( Ivy_ObjInit(pNode) == IVY_INIT_DC )
|
||||
Abc_LatchSetInitDc( pObjNew );
|
||||
else if ( Ivy_ObjInit(pNode) == IVY_INIT_1 )
|
||||
Abc_LatchSetInit1( pObjNew );
|
||||
else if ( Ivy_ObjInit(pNode) == IVY_INIT_0 )
|
||||
Abc_LatchSetInit0( pObjNew );
|
||||
else assert( 0 );
|
||||
pNode->TravId = Abc_EdgeFromNode( pObjNew );
|
||||
}
|
||||
// rebuild the AIG
|
||||
Ivy_ManForEachNodeVec( pMan, vNodes, pNode, i )
|
||||
{
|
||||
// add the first fanins
|
||||
pFaninNew0 = Abc_ObjFanin0Ivy( pNtk, pNode );
|
||||
if ( Ivy_ObjIsBuf(pNode) )
|
||||
{
|
||||
pNode->TravId = Abc_EdgeFromNode( pFaninNew0 );
|
||||
continue;
|
||||
}
|
||||
// add the first second
|
||||
pFaninNew1 = Abc_ObjFanin1Ivy( pNtk, pNode );
|
||||
// create the new node
|
||||
if ( Ivy_ObjIsExor(pNode) )
|
||||
pObjNew = Abc_AigXor( pNtk->pManFunc, pFaninNew0, pFaninNew1 );
|
||||
else
|
||||
pObjNew = Abc_AigAnd( pNtk->pManFunc, pFaninNew0, pFaninNew1 );
|
||||
pNode->TravId = Abc_EdgeFromNode( pObjNew );
|
||||
}
|
||||
// connect the PO nodes
|
||||
Abc_NtkForEachPo( pNtkOld, pObj, i )
|
||||
{
|
||||
pFaninNew = Abc_ObjFanin0Ivy( pNtk, Ivy_ManPo(pMan, i) );
|
||||
Abc_ObjAddFanin( pObj->pCopy, pFaninNew );
|
||||
}
|
||||
// connect the latches
|
||||
Ivy_ManForEachNodeVec( pMan, vLatches, pNode, i )
|
||||
{
|
||||
pFaninNew = Abc_ObjFanin0Ivy( pNtk, pNode );
|
||||
Abc_ObjAddFanin( Abc_NtkLatch(pNtk, i), pFaninNew );
|
||||
}
|
||||
Vec_IntFree( vLatches );
|
||||
Vec_IntFree( vNodes );
|
||||
if ( !Abc_NtkCheck( pNtk ) )
|
||||
fprintf( stdout, "Abc_NtkFromAigSeq(): Network check has failed.\n" );
|
||||
return pNtk;
|
||||
}
|
||||
|
||||
|
|
@ -205,14 +497,11 @@ Ivy_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtkOld )
|
|||
int i;
|
||||
// create the manager
|
||||
assert( Abc_NtkHasSop(pNtkOld) || Abc_NtkHasAig(pNtkOld) );
|
||||
if ( Abc_NtkHasSop(pNtkOld) )
|
||||
pMan = Ivy_ManStart( Abc_NtkCiNum(pNtkOld), Abc_NtkCoNum(pNtkOld), Abc_NtkGetLitNum(pNtkOld) + 1000 );
|
||||
else
|
||||
pMan = Ivy_ManStart( Abc_NtkCiNum(pNtkOld), Abc_NtkCoNum(pNtkOld), Abc_NtkNodeNum(pNtkOld) + 1000 );
|
||||
pMan = Ivy_ManStart();
|
||||
// create the PIs
|
||||
Abc_NtkConst1(pNtkOld)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan);
|
||||
Abc_NtkForEachCi( pNtkOld, pObj, i )
|
||||
pObj->pCopy = (Abc_Obj_t *)Ivy_ManPi(pMan, i);
|
||||
pObj->pCopy = (Abc_Obj_t *)Ivy_ObjCreatePi(pMan);
|
||||
// perform the conversion of the internal nodes
|
||||
Abc_NtkStrashPerformAig( pNtkOld, pMan );
|
||||
// create the POs
|
||||
|
|
@ -220,7 +509,7 @@ Ivy_Man_t * Abc_NtkToAig( Abc_Ntk_t * pNtkOld )
|
|||
{
|
||||
pFanin = (Ivy_Obj_t *)Abc_ObjFanin0(pObj)->pCopy;
|
||||
pFanin = Ivy_NotCond( pFanin, Abc_ObjFaninC0(pObj) );
|
||||
Ivy_ObjConnect( Ivy_ManPo(pMan, i), pFanin );
|
||||
Ivy_ObjCreatePo( pMan, pFanin );
|
||||
}
|
||||
Ivy_ManCleanup( pMan );
|
||||
return pMan;
|
||||
|
|
@ -283,7 +572,7 @@ Ivy_Obj_t * Abc_NodeStrashAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode )
|
|||
pFanin0 = Ivy_NotCond( pFanin0, Abc_ObjFaninC0(pNode) );
|
||||
pFanin1 = (Ivy_Obj_t *)Abc_ObjFanin1(pNode)->pCopy;
|
||||
pFanin1 = Ivy_NotCond( pFanin1, Abc_ObjFaninC1(pNode) );
|
||||
return Ivy_And( pFanin0, pFanin1 );
|
||||
return Ivy_And( pMan, pFanin0, pFanin1 );
|
||||
}
|
||||
|
||||
// get the SOP of the node
|
||||
|
|
@ -336,12 +625,12 @@ Ivy_Obj_t * Abc_NodeStrashAigSopAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char *
|
|||
Abc_ObjForEachFanin( pNode, pFanin, i ) // pFanin can be a net
|
||||
{
|
||||
if ( pCube[i] == '1' )
|
||||
pAnd = Ivy_And( pAnd, (Ivy_Obj_t *)pFanin->pCopy );
|
||||
pAnd = Ivy_And( pMan, pAnd, (Ivy_Obj_t *)pFanin->pCopy );
|
||||
else if ( pCube[i] == '0' )
|
||||
pAnd = Ivy_And( pAnd, Ivy_Not((Ivy_Obj_t *)pFanin->pCopy) );
|
||||
pAnd = Ivy_And( pMan, pAnd, Ivy_Not((Ivy_Obj_t *)pFanin->pCopy) );
|
||||
}
|
||||
// add to the sum of cubes
|
||||
pSum = Ivy_Or( pSum, pAnd );
|
||||
pSum = Ivy_Or( pMan, pSum, pAnd );
|
||||
}
|
||||
// decide whether to complement the result
|
||||
if ( Abc_SopIsComplement(pSop) )
|
||||
|
|
@ -373,7 +662,7 @@ Ivy_Obj_t * Abc_NodeStrashAigExorAig( Ivy_Man_t * pMan, Abc_Obj_t * pNode, char
|
|||
for ( i = 0; i < nFanins; i++ )
|
||||
{
|
||||
pFanin = Abc_ObjFanin( pNode, i );
|
||||
pSum = Ivy_Exor( pSum, (Ivy_Obj_t *)pFanin->pCopy );
|
||||
pSum = Ivy_Exor( pMan, pSum, (Ivy_Obj_t *)pFanin->pCopy );
|
||||
}
|
||||
if ( Abc_SopIsComplement(pSop) )
|
||||
pSum = Ivy_Not(pSum);
|
||||
|
|
@ -417,6 +706,35 @@ Ivy_Obj_t * Abc_NodeStrashAigFactorAig( Ivy_Man_t * pMan, Abc_Obj_t * pRoot, cha
|
|||
return pAnd;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Strashes one logic node using its SOP.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int * Abc_NtkCollectLatchValues( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pLatch;
|
||||
int * pArray, i;
|
||||
pArray = ALLOC( int, Abc_NtkLatchNum(pNtk) );
|
||||
Abc_NtkForEachLatch( pNtk, pLatch, i )
|
||||
{
|
||||
if ( Abc_LatchIsInitDc(pLatch) )
|
||||
pArray[i] = IVY_INIT_DC;
|
||||
else if ( Abc_LatchIsInit1(pLatch) )
|
||||
pArray[i] = IVY_INIT_1;
|
||||
else if ( Abc_LatchIsInit0(pLatch) )
|
||||
pArray[i] = IVY_INIT_0;
|
||||
else assert( 0 );
|
||||
}
|
||||
return pArray;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ void Abc_NtkPrintIo( FILE * pFile, Abc_Ntk_t * pNtk )
|
|||
fprintf( pFile, "Primary inputs (%d): ", Abc_NtkPiNum(pNtk) );
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
fprintf( pFile, " %s", Abc_ObjName(pObj) );
|
||||
// fprintf( pFile, " %s(%d)", Abc_ObjName(pObj), Abc_ObjFanoutNum(pObj) );
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
fprintf( pFile, "Primary outputs (%d):", Abc_NtkPoNum(pNtk) );
|
||||
|
|
|
|||
|
|
@ -321,6 +321,7 @@ int Abc_NodeBuildCutLevelOne_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int
|
|||
{
|
||||
CostCur = Abc_NodeGetLeafCostOne( pNode, nFaninLimit );
|
||||
//printf( " Fanin %s has cost %d.\n", Abc_ObjName(pNode), CostCur );
|
||||
// if ( CostBest > CostCur ) // performance improvement: expand the variable with the smallest level
|
||||
if ( CostBest > CostCur ||
|
||||
(CostBest == CostCur && pNode->Level > pFaninBest->Level) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -114,16 +114,15 @@ void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk )
|
|||
fprintf( pFile, " wire" );
|
||||
Io_WriteVerilogWires( pFile, pNtk, 4 );
|
||||
fprintf( pFile, ";\n" );
|
||||
// write registers
|
||||
Io_WriteVerilogLatches( pFile, pNtk );
|
||||
// write the nodes
|
||||
if ( Abc_NtkHasMapping(pNtk) )
|
||||
Io_WriteVerilogGates( pFile, pNtk );
|
||||
else
|
||||
Io_WriteVerilogNodes( pFile, pNtk );
|
||||
// write registers
|
||||
Io_WriteVerilogLatches( pFile, pNtk );
|
||||
// finalize the file
|
||||
fprintf( pFile, "endmodule\n\n" );
|
||||
fclose( pFile );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -354,6 +353,23 @@ void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk )
|
|||
}
|
||||
}
|
||||
|
||||
/* // fix by Zhihong
|
||||
void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pLatch;
|
||||
int i;
|
||||
Abc_NtkForEachLatch( pNtk, pLatch, i )
|
||||
{
|
||||
if ( Abc_LatchInit(pLatch) == ABC_INIT_ZERO )
|
||||
fprintf( pFile, " initial begin %s <= 1\'b0; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
|
||||
else if ( Abc_LatchInit(pLatch) == ABC_INIT_ONE )
|
||||
fprintf( pFile, " initial begin %s <= 1\'b1; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
|
||||
fprintf( pFile, " always@(posedge gclk) begin %s", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
|
||||
fprintf( pFile, " <= %s; end\n", Abc_ObjName(Abc_ObjFanin0(pLatch)) );
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the gates.]
|
||||
|
|
@ -423,8 +439,14 @@ void Io_WriteVerilogNodes2( FILE * pFile, Abc_Ntk_t * pNtk )
|
|||
}
|
||||
pName = Abc_SopIsComplement(pObj->pData)? "or" : "and";
|
||||
fprintf( pFile, " %s(%s, ", pName, Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)) );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
fprintf( pFile, "%s%s", Io_WriteVerilogGetName(pFanin), (k==nFanins-1? "" : ", ") );
|
||||
// Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
// fprintf( pFile, "%s%s", Io_WriteVerilogGetName(pFanin), (k==nFanins-1? "" : ", ") );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
{
|
||||
char *cube = pObj->pData;
|
||||
fprintf( pFile, "%s", cube[k] == '0' ? "~" : "");
|
||||
fprintf( pFile, "%s%s", Io_WriteVerilogGetName(pFanin), (k==nFanins-1? "" : ", ") );
|
||||
}
|
||||
fprintf( pFile, ");\n" );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,9 +134,11 @@ Abc_Frame_t * Abc_FrameAllocate()
|
|||
***********************************************************************/
|
||||
void Abc_FrameDeallocate( Abc_Frame_t * p )
|
||||
{
|
||||
extern void Rwt_ManGlobalStop();
|
||||
extern void undefine_cube_size();
|
||||
// Abc_HManStop();
|
||||
undefine_cube_size();
|
||||
Rwt_ManGlobalStop();
|
||||
if ( p->pManDec ) Dec_ManStop( p->pManDec );
|
||||
if ( p->dd ) Extra_StopManager( p->dd );
|
||||
Abc_FrameDeleteAllNetworks( p );
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ struct Fpga_CutTableStrutct_t
|
|||
};
|
||||
|
||||
// the largest number of cuts considered
|
||||
#define FPGA_CUTS_MAX_COMPUTE 500
|
||||
#define FPGA_CUTS_MAX_COMPUTE 5000
|
||||
// the largest number of cuts used
|
||||
#define FPGA_CUTS_MAX_USE 200
|
||||
#define FPGA_CUTS_MAX_USE 2000
|
||||
|
||||
// primes used to compute the hash key
|
||||
static int s_HashPrimes[10] = { 109, 499, 557, 619, 631, 709, 797, 881, 907, 991 };
|
||||
|
|
|
|||
|
|
@ -433,6 +433,14 @@ static inline int Extra_TruthIsConst1( unsigned * pIn, int nVars )
|
|||
return 0;
|
||||
return 1;
|
||||
}
|
||||
static inline int Extra_TruthIsImply( unsigned * pIn1, unsigned * pIn2, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
if ( pIn1[w] & ~pIn2[w] )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
static inline void Extra_TruthCopy( unsigned * pOut, unsigned * pIn, int nVars )
|
||||
{
|
||||
int w;
|
||||
|
|
@ -491,7 +499,9 @@ extern int Extra_TruthSupportSize( unsigned * pTruth, int nVars );
|
|||
extern int Extra_TruthSupport( unsigned * pTruth, int nVars );
|
||||
extern void Extra_TruthCofactor0( unsigned * pTruth, int nVars, int iVar );
|
||||
extern void Extra_TruthCofactor1( unsigned * pTruth, int nVars, int iVar );
|
||||
extern void Extra_TruthCombine( unsigned * pOut, unsigned * pCof0, unsigned * pCof1, int nVars, int iVar );
|
||||
extern void Extra_TruthExist( unsigned * pTruth, int nVars, int iVar );
|
||||
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 );
|
||||
|
|
|
|||
|
|
@ -506,6 +506,116 @@ void Extra_TruthCofactor0( unsigned * pTruth, int nVars, int iVar )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Existentially quantifies the variable.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Extra_TruthExist( unsigned * pTruth, int nVars, int iVar )
|
||||
{
|
||||
int nWords = Extra_TruthWordNum( nVars );
|
||||
int i, k, Step;
|
||||
|
||||
assert( iVar < nVars );
|
||||
switch ( iVar )
|
||||
{
|
||||
case 0:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] |= ((pTruth[i] & 0xAAAAAAAA) >> 1) | ((pTruth[i] & 0x55555555) << 1);
|
||||
return;
|
||||
case 1:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] |= ((pTruth[i] & 0xCCCCCCCC) >> 2) | ((pTruth[i] & 0x33333333) << 2);
|
||||
return;
|
||||
case 2:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] |= ((pTruth[i] & 0xF0F0F0F0) >> 4) | ((pTruth[i] & 0x0F0F0F0F) << 4);
|
||||
return;
|
||||
case 3:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] |= ((pTruth[i] & 0xFF00FF00) >> 8) | ((pTruth[i] & 0x00FF00FF) << 8);
|
||||
return;
|
||||
case 4:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] |= ((pTruth[i] & 0xFFFF0000) >> 16) | ((pTruth[i] & 0x0000FFFF) << 16);
|
||||
return;
|
||||
default:
|
||||
Step = (1 << (iVar - 5));
|
||||
for ( k = 0; k < nWords; k += 2*Step )
|
||||
{
|
||||
for ( i = 0; i < Step; i++ )
|
||||
{
|
||||
pTruth[i] |= pTruth[Step+i];
|
||||
pTruth[Step+i] = pTruth[i];
|
||||
}
|
||||
pTruth += 2*Step;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Existentially quantifies the variable.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Extra_TruthForall( unsigned * pTruth, int nVars, int iVar )
|
||||
{
|
||||
int nWords = Extra_TruthWordNum( nVars );
|
||||
int i, k, Step;
|
||||
|
||||
assert( iVar < nVars );
|
||||
switch ( iVar )
|
||||
{
|
||||
case 0:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] &= ((pTruth[i] & 0xAAAAAAAA) >> 1) | ((pTruth[i] & 0x55555555) << 1);
|
||||
return;
|
||||
case 1:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] &= ((pTruth[i] & 0xCCCCCCCC) >> 2) | ((pTruth[i] & 0x33333333) << 2);
|
||||
return;
|
||||
case 2:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] &= ((pTruth[i] & 0xF0F0F0F0) >> 4) | ((pTruth[i] & 0x0F0F0F0F) << 4);
|
||||
return;
|
||||
case 3:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] &= ((pTruth[i] & 0xFF00FF00) >> 8) | ((pTruth[i] & 0x00FF00FF) << 8);
|
||||
return;
|
||||
case 4:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] &= ((pTruth[i] & 0xFFFF0000) >> 16) | ((pTruth[i] & 0x0000FFFF) << 16);
|
||||
return;
|
||||
default:
|
||||
Step = (1 << (iVar - 5));
|
||||
for ( k = 0; k < nWords; k += 2*Step )
|
||||
{
|
||||
for ( i = 0; i < Step; i++ )
|
||||
{
|
||||
pTruth[i] &= pTruth[Step+i];
|
||||
pTruth[Step+i] = pTruth[i];
|
||||
}
|
||||
pTruth += 2*Step;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes negative cofactor of the function.]
|
||||
|
|
@ -517,7 +627,7 @@ void Extra_TruthCofactor0( unsigned * pTruth, int nVars, int iVar )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Extra_TruthCombine( unsigned * pOut, unsigned * pCof0, unsigned * pCof1, int nVars, int iVar )
|
||||
void Extra_TruthMux( unsigned * pOut, unsigned * pCof0, unsigned * pCof1, int nVars, int iVar )
|
||||
{
|
||||
int nWords = Extra_TruthWordNum( nVars );
|
||||
int i, k, Step;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ static unsigned Nm_HashString( char * pName, int TableSize )
|
|||
};
|
||||
unsigned i, Key = 0;
|
||||
for ( i = 0; pName[i] != '\0'; i++ )
|
||||
Key ^= s_Primes[i%10]*pName[i];
|
||||
Key ^= s_Primes[i%10]*pName[i]*pName[i];
|
||||
return Key % TableSize;
|
||||
}
|
||||
|
||||
|
|
@ -142,7 +142,7 @@ Nm_Entry_t * Nm_ManTableLookupId( Nm_Man_t * p, int ObjId )
|
|||
Nm_Entry_t * Nm_ManTableLookupName( Nm_Man_t * p, char * pName, Nm_Entry_t ** ppSecond )
|
||||
{
|
||||
Nm_Entry_t * pFirst, * pSecond;
|
||||
int i;
|
||||
int i, Counter = 0;
|
||||
pFirst = pSecond = NULL;
|
||||
for ( i = Nm_HashString(pName, p->nBins); p->pBinsN2I[i]; i = (i+1) % p->nBins )
|
||||
if ( strcmp(p->pBinsN2I[i]->Name, pName) == 0 )
|
||||
|
|
@ -154,6 +154,10 @@ Nm_Entry_t * Nm_ManTableLookupName( Nm_Man_t * p, char * pName, Nm_Entry_t ** pp
|
|||
else
|
||||
assert( 0 ); // name appears more than 2 times
|
||||
}
|
||||
else
|
||||
Counter++;
|
||||
if ( Counter > 100 )
|
||||
printf( "%d ", Counter );
|
||||
// save the names
|
||||
if ( ppSecond )
|
||||
*ppSecond = pSecond;
|
||||
|
|
|
|||
|
|
@ -282,6 +282,23 @@ static inline void * Vec_PtrEntry( Vec_Ptr_t * p, int i )
|
|||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void ** Vec_PtrEntryP( Vec_Ptr_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray + i;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -371,7 +388,10 @@ static inline void Vec_PtrFillExtra( Vec_Ptr_t * p, int nSize, void * Entry )
|
|||
int i;
|
||||
if ( p->nSize >= nSize )
|
||||
return;
|
||||
Vec_PtrGrow( p, nSize );
|
||||
if ( p->nSize < 2 * nSize )
|
||||
Vec_PtrGrow( p, 2 * nSize );
|
||||
else
|
||||
Vec_PtrGrow( p, p->nSize );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
|
|
|
|||
|
|
@ -1,988 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cutPre22.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Network and node package.]
|
||||
|
||||
Synopsis [Precomputes truth tables for the 2x2 macro cell.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: cutPre22.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "cutInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define CUT_CELL_MVAR 9
|
||||
|
||||
typedef struct Cut_Cell_t_ Cut_Cell_t;
|
||||
typedef struct Cut_CMan_t_ Cut_CMan_t;
|
||||
|
||||
struct Cut_Cell_t_
|
||||
{
|
||||
Cut_Cell_t * pNext; // pointer to the next cell in the table
|
||||
Cut_Cell_t * pNextVar; // pointer to the next cell of this support size
|
||||
Cut_Cell_t * pParent; // pointer to the cell used to derive this one
|
||||
int nUsed; // the number of times the cell is used
|
||||
char Box[4]; // functions in the boxes
|
||||
unsigned nVars : 4; // the number of variables
|
||||
unsigned CrossBar0 : 4; // the variable set equal
|
||||
unsigned CrossBar1 : 4; // the variable set equal
|
||||
unsigned CrossBarPhase : 2; // the phase of the cross bar (0, 1, or 2)
|
||||
unsigned CanonPhase : 18; // the canonical phase
|
||||
char CanonPerm[CUT_CELL_MVAR+3]; // semicanonical permutation
|
||||
short Store[2*CUT_CELL_MVAR]; // minterm counts in the cofactors
|
||||
unsigned uTruth[1<<(CUT_CELL_MVAR-5)]; // the current truth table
|
||||
};
|
||||
|
||||
struct Cut_CMan_t_
|
||||
{
|
||||
// storage for canonical cells
|
||||
Extra_MmFixed_t * pMem;
|
||||
st_table * tTable;
|
||||
Cut_Cell_t * pSameVar[CUT_CELL_MVAR+1];
|
||||
// elementary truth tables
|
||||
unsigned uInputs[CUT_CELL_MVAR][1<<(CUT_CELL_MVAR-5)];
|
||||
// temporary truth tables
|
||||
unsigned uTemp1[22][1<<(CUT_CELL_MVAR-5)];
|
||||
unsigned uTemp2[22][1<<(CUT_CELL_MVAR-5)];
|
||||
unsigned uTemp3[22][1<<(CUT_CELL_MVAR-5)];
|
||||
unsigned uFinal[1<<(CUT_CELL_MVAR-5)];
|
||||
unsigned puAux[1<<(CUT_CELL_MVAR-5)];
|
||||
// statistical variables
|
||||
int nTotal;
|
||||
int nGood;
|
||||
int nVarCounts[CUT_CELL_MVAR+1];
|
||||
int nSymGroups[CUT_CELL_MVAR+1];
|
||||
int nSymGroupsE[CUT_CELL_MVAR+1];
|
||||
int timeCanon;
|
||||
int timeSupp;
|
||||
int timeTable;
|
||||
int nCellFound;
|
||||
int nCellNotFound;
|
||||
};
|
||||
|
||||
// NP-classes of functions of 3 variables (22)
|
||||
static char * s_NP3[22] = {
|
||||
" 0\n", // 00 const 0 // 0 vars
|
||||
" 1\n", // 01 const 1 // 0 vars
|
||||
"1 1\n", // 02 a // 1 vars
|
||||
"11 1\n", // 03 ab // 2 vars
|
||||
"11 0\n", // 04 (ab)' // 2 vars
|
||||
"10 1\n01 1\n", // 05 a<+>b // 2 vars
|
||||
"111 1\n", // 06 0s abc // 3 vars
|
||||
"111 0\n", // 07 (abc)' //
|
||||
"11- 1\n1-1 1\n", // 08 1p a(b+c) //
|
||||
"11- 0\n1-1 0\n", // 09 (a(b+c))' //
|
||||
"111 1\n100 1\n010 1\n001 1\n", // 10 2s a<+>b<+>c //
|
||||
"10- 0\n1-0 0\n011 0\n", // 11 3p a<+>bc //
|
||||
"101 1\n110 1\n", // 12 4p a(b<+>c) //
|
||||
"101 0\n110 0\n", // 13 (a(b<+>c))' //
|
||||
"11- 1\n1-1 1\n-11 1\n", // 14 5s ab+bc+ac //
|
||||
"111 1\n000 1\n", // 15 6s abc+a'b'c' //
|
||||
"111 0\n000 0\n", // 16 (abc+a'b'c')' //
|
||||
"11- 1\n-11 1\n0-1 1\n", // 17 7 ab+bc+a'c //
|
||||
"011 1\n101 1\n110 1\n", // 18 8s a'bc+ab'c+abc' //
|
||||
"011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')' //
|
||||
"100 1\n-11 1\n", // 20 9p ab'c'+bc //
|
||||
"100 0\n-11 0\n" // 21 (ab'c'+bc)' //
|
||||
};
|
||||
|
||||
// NP-classes of functions of 3 variables (22)
|
||||
static char * s_NP3Names[22] = {
|
||||
" const 0 ",
|
||||
" const 1 ",
|
||||
" a ",
|
||||
" ab ",
|
||||
" (ab)' ",
|
||||
" a<+>b ",
|
||||
"0s abc ",
|
||||
" (abc)' ",
|
||||
"1p a(b+c) ",
|
||||
" (a(b+c))' ",
|
||||
"2s a<+>b<+>c ",
|
||||
"3p a<+>bc ",
|
||||
"4p a(b<+>c) ",
|
||||
" (a(b<+>c))' ",
|
||||
"5s ab+bc+ac ",
|
||||
"6s abc+a'b'c' ",
|
||||
" (abc+a'b'c')' ",
|
||||
"7 ab+bc+a'c ",
|
||||
"8s a'bc+ab'c+abc' ",
|
||||
" (a'bc+ab'c+abc')' ",
|
||||
"9p ab'c'+bc ",
|
||||
" (ab'c'+bc)' "
|
||||
};
|
||||
|
||||
// the number of variables in each function
|
||||
static int s_NP3VarNums[22] = { 0, 0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
|
||||
|
||||
// NPN classes of functions of exactly 3 inputs (10)
|
||||
static int s_NPNe3[10] = { 6, 8, 10, 11, 12, 14, 15, 17, 18, 20 };
|
||||
|
||||
// NPN classes of functions of exactly 3 inputs that are symmetric (5)
|
||||
static int s_NPNe3s[10] = { 6, 10, 14, 15, 18 };
|
||||
|
||||
// NPN classes of functions of exactly 3 inputs (4)
|
||||
static int s_NPNe3p[10] = { 8, 11, 12, 20 };
|
||||
|
||||
static Cut_CMan_t * Cut_CManStart();
|
||||
static void Cut_CManStop( Cut_CMan_t * p );
|
||||
static void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type );
|
||||
static void Cut_CellCanonicize( Cut_CMan_t * p, Cut_Cell_t * pCell );
|
||||
static int Cut_CellTableLookup( Cut_CMan_t * p, Cut_Cell_t * pCell );
|
||||
static void Cut_CellSuppMin( Cut_Cell_t * pCell );
|
||||
static void Cut_CellCrossBar( Cut_Cell_t * pCell );
|
||||
|
||||
|
||||
static Cut_CMan_t * s_pCMan = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Start the precomputation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cut_CellLoad()
|
||||
{
|
||||
FILE * pFile;
|
||||
char * pFileName = "cells22_daomap_iwls.txt";
|
||||
char pString[1000];
|
||||
Cut_CMan_t * p;
|
||||
Cut_Cell_t * pCell;
|
||||
int Length; //, i;
|
||||
pFile = fopen( pFileName, "r" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
printf( "Cannot open file \"%s\".\n", pFileName );
|
||||
return;
|
||||
}
|
||||
// start the manager
|
||||
p = Cut_CManStart();
|
||||
// load truth tables
|
||||
while ( fgets(pString, 1000, pFile) )
|
||||
{
|
||||
Length = strlen(pString);
|
||||
pString[Length--] = 0;
|
||||
if ( Length == 0 )
|
||||
continue;
|
||||
// derive the cell
|
||||
pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
|
||||
memset( pCell, 0, sizeof(Cut_Cell_t) );
|
||||
pCell->nVars = Extra_Base2Log(Length*4);
|
||||
pCell->nUsed = 1;
|
||||
// Extra_TruthCopy( pCell->uTruth, pTruth, nVars );
|
||||
Extra_ReadHexadecimal( pCell->uTruth, pString, pCell->nVars );
|
||||
Cut_CellSuppMin( pCell );
|
||||
/*
|
||||
// set the elementary permutation
|
||||
for ( i = 0; i < (int)pCell->nVars; i++ )
|
||||
pCell->CanonPerm[i] = i;
|
||||
// canonicize
|
||||
pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
|
||||
*/
|
||||
// add to the table
|
||||
p->nTotal++;
|
||||
|
||||
// Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars ); printf( "\n" );
|
||||
// if ( p->nTotal == 500 )
|
||||
// break;
|
||||
|
||||
if ( !Cut_CellTableLookup( p, pCell ) ) // new cell
|
||||
p->nGood++;
|
||||
}
|
||||
printf( "Read %d cells from file \"%s\". Added %d cells to the table.\n", p->nTotal, pFileName, p->nGood );
|
||||
fclose( pFile );
|
||||
// return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Precomputes truth tables for the 2x2 macro cell.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cut_CellPrecompute()
|
||||
{
|
||||
Cut_CMan_t * p;
|
||||
Cut_Cell_t * pCell, * pTemp;
|
||||
int i1, i2, i3, i, j, k, c, clk = clock(), clk2 = clock();
|
||||
|
||||
p = Cut_CManStart();
|
||||
|
||||
// precompute truth tables
|
||||
for ( i = 0; i < 22; i++ )
|
||||
Cut_CellTruthElem( p->uInputs[0], p->uInputs[1], p->uInputs[2], p->uTemp1[i], 9, i );
|
||||
for ( i = 0; i < 22; i++ )
|
||||
Cut_CellTruthElem( p->uInputs[3], p->uInputs[4], p->uInputs[5], p->uTemp2[i], 9, i );
|
||||
for ( i = 0; i < 22; i++ )
|
||||
Cut_CellTruthElem( p->uInputs[6], p->uInputs[7], p->uInputs[8], p->uTemp3[i], 9, i );
|
||||
/*
|
||||
if ( k == 8 && ((i1 == 6 && i2 == 14 && i3 == 20) || (i1 == 20 && i2 == 6 && i3 == 14)) )
|
||||
{
|
||||
Extra_PrintBinary( stdout, &pCell->CanonPhase, pCell->nVars+1 ); printf( " : " );
|
||||
for ( i = 0; i < pCell->nVars; i++ )
|
||||
printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
|
||||
Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars );
|
||||
printf( "\n" );
|
||||
}
|
||||
*/
|
||||
/*
|
||||
// go through symmetric roots
|
||||
for ( k = 0; k < 5; k++ )
|
||||
for ( i1 = 0; i1 < 22; i1++ )
|
||||
for ( i2 = i1; i2 < 22; i2++ )
|
||||
for ( i3 = i2; i3 < 22; i3++ )
|
||||
{
|
||||
// derive the cell
|
||||
pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
|
||||
memset( pCell, 0, sizeof(Cut_Cell_t) );
|
||||
pCell->nVars = 9;
|
||||
pCell->Box[0] = s_NPNe3s[k];
|
||||
pCell->Box[1] = i1;
|
||||
pCell->Box[2] = i2;
|
||||
pCell->Box[3] = i3;
|
||||
// fill in the truth table
|
||||
Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3s[k] );
|
||||
// canonicize
|
||||
Cut_CellCanonicize( pCell );
|
||||
|
||||
// add to the table
|
||||
p->nTotal++;
|
||||
if ( Cut_CellTableLookup( p, pCell ) ) // already exists
|
||||
Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
|
||||
else
|
||||
p->nGood++;
|
||||
}
|
||||
|
||||
// go through partially symmetric roots
|
||||
for ( k = 0; k < 4; k++ )
|
||||
for ( i1 = 0; i1 < 22; i1++ )
|
||||
for ( i2 = 0; i2 < 22; i2++ )
|
||||
for ( i3 = i2; i3 < 22; i3++ )
|
||||
{
|
||||
// derive the cell
|
||||
pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
|
||||
memset( pCell, 0, sizeof(Cut_Cell_t) );
|
||||
pCell->nVars = 9;
|
||||
pCell->Box[0] = s_NPNe3p[k];
|
||||
pCell->Box[1] = i1;
|
||||
pCell->Box[2] = i2;
|
||||
pCell->Box[3] = i3;
|
||||
// fill in the truth table
|
||||
Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3p[k] );
|
||||
// canonicize
|
||||
Cut_CellCanonicize( pCell );
|
||||
|
||||
// add to the table
|
||||
p->nTotal++;
|
||||
if ( Cut_CellTableLookup( p, pCell ) ) // already exists
|
||||
Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
|
||||
else
|
||||
p->nGood++;
|
||||
}
|
||||
|
||||
// go through non-symmetric functions
|
||||
for ( i1 = 0; i1 < 22; i1++ )
|
||||
for ( i2 = 0; i2 < 22; i2++ )
|
||||
for ( i3 = 0; i3 < 22; i3++ )
|
||||
{
|
||||
// derive the cell
|
||||
pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
|
||||
memset( pCell, 0, sizeof(Cut_Cell_t) );
|
||||
pCell->nVars = 9;
|
||||
pCell->Box[0] = 17;
|
||||
pCell->Box[1] = i1;
|
||||
pCell->Box[2] = i2;
|
||||
pCell->Box[3] = i3;
|
||||
// fill in the truth table
|
||||
Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, 17 );
|
||||
// canonicize
|
||||
Cut_CellCanonicize( pCell );
|
||||
|
||||
// add to the table
|
||||
p->nTotal++;
|
||||
if ( Cut_CellTableLookup( p, pCell ) ) // already exists
|
||||
Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
|
||||
else
|
||||
p->nGood++;
|
||||
}
|
||||
*/
|
||||
|
||||
// go through non-symmetric functions
|
||||
for ( k = 0; k < 10; k++ )
|
||||
for ( i1 = 0; i1 < 22; i1++ )
|
||||
for ( i2 = 0; i2 < 22; i2++ )
|
||||
for ( i3 = 0; i3 < 22; i3++ )
|
||||
{
|
||||
// derive the cell
|
||||
pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
|
||||
memset( pCell, 0, sizeof(Cut_Cell_t) );
|
||||
pCell->nVars = 9;
|
||||
pCell->Box[0] = s_NPNe3[k];
|
||||
pCell->Box[1] = i1;
|
||||
pCell->Box[2] = i2;
|
||||
pCell->Box[3] = i3;
|
||||
// set the elementary permutation
|
||||
for ( i = 0; i < (int)pCell->nVars; i++ )
|
||||
pCell->CanonPerm[i] = i;
|
||||
// fill in the truth table
|
||||
Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3[k] );
|
||||
// minimize the support
|
||||
Cut_CellSuppMin( pCell );
|
||||
|
||||
// canonicize
|
||||
pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
|
||||
|
||||
// add to the table
|
||||
p->nTotal++;
|
||||
if ( Cut_CellTableLookup( p, pCell ) ) // already exists
|
||||
Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
|
||||
else
|
||||
{
|
||||
p->nGood++;
|
||||
p->nVarCounts[pCell->nVars]++;
|
||||
|
||||
if ( pCell->nVars )
|
||||
for ( i = 0; i < (int)pCell->nVars-1; i++ )
|
||||
{
|
||||
if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric
|
||||
continue;
|
||||
// i and i+1 can be symmetric
|
||||
// find the end of this group
|
||||
for ( j = i+1; j < (int)pCell->nVars; j++ )
|
||||
if ( pCell->Store[2*i] != pCell->Store[2*j] )
|
||||
break;
|
||||
|
||||
if ( pCell->Store[2*i] == pCell->Store[2*i+1] )
|
||||
p->nSymGroupsE[j-i]++;
|
||||
else
|
||||
p->nSymGroups[j-i]++;
|
||||
i = j - 1;
|
||||
}
|
||||
/*
|
||||
if ( pCell->nVars == 3 )
|
||||
{
|
||||
Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" );
|
||||
for ( i = 0; i < (int)pCell->nVars; i++ )
|
||||
printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
|
||||
printf( "\n" );
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
printf( "BASIC: Total = %d. Good = %d. Entry = %d. ", p->nTotal, p->nGood, sizeof(Cut_Cell_t) );
|
||||
PRT( "Time", clock() - clk );
|
||||
printf( "Cells: " );
|
||||
for ( i = 0; i <= 9; i++ )
|
||||
printf( "%d=%d ", i, p->nVarCounts[i] );
|
||||
printf( "\nDiffs: " );
|
||||
for ( i = 0; i <= 9; i++ )
|
||||
printf( "%d=%d ", i, p->nSymGroups[i] );
|
||||
printf( "\nEquals: " );
|
||||
for ( i = 0; i <= 9; i++ )
|
||||
printf( "%d=%d ", i, p->nSymGroupsE[i] );
|
||||
printf( "\n" );
|
||||
|
||||
// continue adding new cells using support
|
||||
for ( k = CUT_CELL_MVAR; k > 3; k-- )
|
||||
{
|
||||
for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
|
||||
for ( i1 = 0; i1 < k; i1++ )
|
||||
for ( i2 = i1+1; i2 < k; i2++ )
|
||||
for ( c = 0; c < 3; c++ )
|
||||
{
|
||||
// derive the cell
|
||||
pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
|
||||
memset( pCell, 0, sizeof(Cut_Cell_t) );
|
||||
pCell->nVars = pTemp->nVars;
|
||||
pCell->pParent = pTemp;
|
||||
// set the elementary permutation
|
||||
for ( i = 0; i < (int)pCell->nVars; i++ )
|
||||
pCell->CanonPerm[i] = i;
|
||||
// fill in the truth table
|
||||
Extra_TruthCopy( pCell->uTruth, pTemp->uTruth, pTemp->nVars );
|
||||
// create the cross-bar
|
||||
pCell->CrossBar0 = i1;
|
||||
pCell->CrossBar1 = i2;
|
||||
pCell->CrossBarPhase = c;
|
||||
Cut_CellCrossBar( pCell );
|
||||
// minimize the support
|
||||
//clk2 = clock();
|
||||
Cut_CellSuppMin( pCell );
|
||||
//p->timeSupp += clock() - clk2;
|
||||
// canonicize
|
||||
//clk2 = clock();
|
||||
pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
|
||||
//p->timeCanon += clock() - clk2;
|
||||
|
||||
// add to the table
|
||||
//clk2 = clock();
|
||||
p->nTotal++;
|
||||
if ( Cut_CellTableLookup( p, pCell ) ) // already exists
|
||||
Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
|
||||
else
|
||||
{
|
||||
p->nGood++;
|
||||
p->nVarCounts[pCell->nVars]++;
|
||||
|
||||
for ( i = 0; i < (int)pCell->nVars-1; i++ )
|
||||
{
|
||||
if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric
|
||||
continue;
|
||||
// i and i+1 can be symmetric
|
||||
// find the end of this group
|
||||
for ( j = i+1; j < (int)pCell->nVars; j++ )
|
||||
if ( pCell->Store[2*i] != pCell->Store[2*j] )
|
||||
break;
|
||||
|
||||
if ( pCell->Store[2*i] == pCell->Store[2*i+1] )
|
||||
p->nSymGroupsE[j-i]++;
|
||||
else
|
||||
p->nSymGroups[j-i]++;
|
||||
i = j - 1;
|
||||
}
|
||||
/*
|
||||
if ( pCell->nVars == 3 )
|
||||
{
|
||||
Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" );
|
||||
for ( i = 0; i < (int)pCell->nVars; i++ )
|
||||
printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
|
||||
printf( "\n" );
|
||||
}
|
||||
*/
|
||||
}
|
||||
//p->timeTable += clock() - clk2;
|
||||
}
|
||||
|
||||
printf( "VAR %d: Total = %d. Good = %d. Entry = %d. ", k, p->nTotal, p->nGood, sizeof(Cut_Cell_t) );
|
||||
PRT( "Time", clock() - clk );
|
||||
printf( "Cells: " );
|
||||
for ( i = 0; i <= 9; i++ )
|
||||
printf( "%d=%d ", i, p->nVarCounts[i] );
|
||||
printf( "\nDiffs: " );
|
||||
for ( i = 0; i <= 9; i++ )
|
||||
printf( "%d=%d ", i, p->nSymGroups[i] );
|
||||
printf( "\nEquals: " );
|
||||
for ( i = 0; i <= 9; i++ )
|
||||
printf( "%d=%d ", i, p->nSymGroupsE[i] );
|
||||
printf( "\n" );
|
||||
}
|
||||
// printf( "\n" );
|
||||
PRT( "Supp ", p->timeSupp );
|
||||
PRT( "Canon", p->timeCanon );
|
||||
PRT( "Table", p->timeTable );
|
||||
// Cut_CManStop( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Check the table.]
|
||||
|
||||
Description [Returns 1 if such a truth table already exists.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cut_CellTableLookup( Cut_CMan_t * p, Cut_Cell_t * pCell )
|
||||
{
|
||||
Cut_Cell_t ** pSlot, * pTemp;
|
||||
unsigned Hash;
|
||||
Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum( pCell->nVars ) );
|
||||
if ( !st_find_or_add( p->tTable, (char *)Hash, (char ***)&pSlot ) )
|
||||
*pSlot = NULL;
|
||||
for ( pTemp = *pSlot; pTemp; pTemp = pTemp->pNext )
|
||||
{
|
||||
if ( pTemp->nVars != pCell->nVars )
|
||||
continue;
|
||||
if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) )
|
||||
return 1;
|
||||
}
|
||||
// the entry is new
|
||||
pCell->pNext = *pSlot;
|
||||
*pSlot = pCell;
|
||||
// add it to the variable support list
|
||||
pCell->pNextVar = p->pSameVar[pCell->nVars];
|
||||
p->pSameVar[pCell->nVars] = pCell;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cut_CellSuppMin( Cut_Cell_t * pCell )
|
||||
{
|
||||
static unsigned uTemp[1<<(CUT_CELL_MVAR-5)];
|
||||
unsigned * pIn, * pOut, * pTemp;
|
||||
int i, k, Counter, Temp;
|
||||
|
||||
// go backward through the support variables and remove redundant
|
||||
for ( k = pCell->nVars - 1; k >= 0; k-- )
|
||||
if ( !Extra_TruthVarInSupport(pCell->uTruth, pCell->nVars, k) )
|
||||
{
|
||||
// shift all the variables above this one
|
||||
Counter = 0;
|
||||
pIn = pCell->uTruth; pOut = uTemp;
|
||||
for ( i = k; i < (int)pCell->nVars - 1; i++ )
|
||||
{
|
||||
Extra_TruthSwapAdjacentVars( pOut, pIn, pCell->nVars, i );
|
||||
pTemp = pIn; pIn = pOut; pOut = pTemp;
|
||||
// swap the support vars
|
||||
Temp = pCell->CanonPerm[i];
|
||||
pCell->CanonPerm[i] = pCell->CanonPerm[i+1];
|
||||
pCell->CanonPerm[i+1] = Temp;
|
||||
Counter++;
|
||||
}
|
||||
// return the function back into its place
|
||||
if ( Counter & 1 )
|
||||
Extra_TruthCopy( pOut, pIn, pCell->nVars );
|
||||
// remove one variable
|
||||
pCell->nVars--;
|
||||
// Extra_PrintBinary( stdout, pCell->uTruth, (1<<pCell->nVars) ); printf( "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cut_CellCrossBar( Cut_Cell_t * pCell )
|
||||
{
|
||||
static unsigned uTemp0[1<<(CUT_CELL_MVAR-5)];
|
||||
static unsigned uTemp1[1<<(CUT_CELL_MVAR-5)];
|
||||
Extra_TruthCopy( uTemp0, pCell->uTruth, pCell->nVars );
|
||||
Extra_TruthCopy( uTemp1, pCell->uTruth, pCell->nVars );
|
||||
if ( pCell->CanonPhase == 0 )
|
||||
{
|
||||
Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 );
|
||||
Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 );
|
||||
Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 );
|
||||
Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 );
|
||||
}
|
||||
else if ( pCell->CanonPhase == 1 )
|
||||
{
|
||||
Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar0 );
|
||||
Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 );
|
||||
Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar0 );
|
||||
Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 );
|
||||
}
|
||||
else if ( pCell->CanonPhase == 2 )
|
||||
{
|
||||
Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 );
|
||||
Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar1 );
|
||||
Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 );
|
||||
Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar1 );
|
||||
}
|
||||
else assert( 0 );
|
||||
Extra_TruthCombine( pCell->uTruth, uTemp0, uTemp1, pCell->nVars, pCell->CrossBar0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type )
|
||||
{
|
||||
int nWords = Extra_TruthWordNum( nVars );
|
||||
int i;
|
||||
|
||||
assert( Type < 22 );
|
||||
switch ( Type )
|
||||
{
|
||||
// " 0\n", // 00 const 0
|
||||
case 0:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = 0;
|
||||
return;
|
||||
// " 1\n", // 01 const 1
|
||||
case 1:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = 0xFFFFFFFF;
|
||||
return;
|
||||
// "1 1\n", // 02 a
|
||||
case 2:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = InA[i];
|
||||
return;
|
||||
// "11 1\n", // 03 ab
|
||||
case 3:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = InA[i] & InB[i];
|
||||
return;
|
||||
// "11 0\n", // 04 (ab)'
|
||||
case 4:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = ~(InA[i] & InB[i]);
|
||||
return;
|
||||
// "10 1\n01 1\n", // 05 a<+>b
|
||||
case 5:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = InA[i] ^ InB[i];
|
||||
return;
|
||||
// "111 1\n", // 06 + abc
|
||||
case 6:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = InA[i] & InB[i] & InC[i];
|
||||
return;
|
||||
// "111 0\n", // 07 (abc)'
|
||||
case 7:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = ~(InA[i] & InB[i] & InC[i]);
|
||||
return;
|
||||
// "11- 1\n1-1 1\n", // 08 + a(b+c)
|
||||
case 8:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = InA[i] & (InB[i] | InC[i]);
|
||||
return;
|
||||
// "11- 0\n1-1 0\n", // 09 (a(b+c))'
|
||||
case 9:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = ~(InA[i] & (InB[i] | InC[i]));
|
||||
return;
|
||||
// "111 1\n100 1\n010 1\n001 1\n", // 10 + a<+>b<+>c
|
||||
case 10:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = InA[i] ^ InB[i] ^ InC[i];
|
||||
return;
|
||||
// "10- 0\n1-0 0\n011 0\n", // 11 + a<+>bc
|
||||
case 11:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = InA[i] ^ (InB[i] & InC[i]);
|
||||
return;
|
||||
// "101 1\n110 1\n", // 12 + a(b<+>c)
|
||||
case 12:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = InA[i] & (InB[i] ^ InC[i]);
|
||||
return;
|
||||
// "101 0\n110 0\n", // 13 (a(b<+>c))'
|
||||
case 13:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = ~(InA[i] & (InB[i] ^ InC[i]));
|
||||
return;
|
||||
// "11- 1\n1-1 1\n-11 1\n", // 14 + ab+bc+ac
|
||||
case 14:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (InA[i] & InC[i]);
|
||||
return;
|
||||
// "111 1\n000 1\n", // 15 + abc+a'b'c'
|
||||
case 15:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = (InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i]);
|
||||
return;
|
||||
// "111 0\n000 0\n", // 16 (abc+a'b'c')'
|
||||
case 16:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = ~((InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i]));
|
||||
return;
|
||||
// "11- 1\n-11 1\n0-1 1\n", // 17 + ab+bc+a'c
|
||||
case 17:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (~InA[i] & InC[i]);
|
||||
return;
|
||||
// "011 1\n101 1\n110 1\n", // 18 + a'bc+ab'c+abc'
|
||||
case 18:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = (~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i]);
|
||||
return;
|
||||
// "011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')'
|
||||
case 19:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = ~((~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i]));
|
||||
return;
|
||||
// "100 1\n-11 1\n", // 20 + ab'c'+bc
|
||||
case 20:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = (InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i]);
|
||||
return;
|
||||
// "100 0\n-11 0\n" // 21 (ab'c'+bc)'
|
||||
case 21:
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pOut[i] = ~((InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Start the precomputation manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Cut_CMan_t * Cut_CManStart()
|
||||
{
|
||||
Cut_CMan_t * p;
|
||||
int i, k;
|
||||
// start the manager
|
||||
assert( sizeof(unsigned) == 4 );
|
||||
p = ALLOC( Cut_CMan_t, 1 );
|
||||
memset( p, 0, sizeof(Cut_CMan_t) );
|
||||
// start the table and the memory manager
|
||||
p->tTable = st_init_table(st_ptrcmp,st_ptrhash);
|
||||
p->pMem = Extra_MmFixedStart( sizeof(Cut_Cell_t) );
|
||||
// set elementary truth tables
|
||||
for ( k = 0; k < CUT_CELL_MVAR; k++ )
|
||||
for ( i = 0; i < (1<<CUT_CELL_MVAR); i++ )
|
||||
if ( i & (1 << k) )
|
||||
p->uInputs[k][i>>5] |= (1 << (i&31));
|
||||
s_pCMan = p;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cut_CManStop( Cut_CMan_t * p )
|
||||
{
|
||||
st_free_table( p->tTable );
|
||||
Extra_MmFixedStop( p->pMem, 0 );
|
||||
free( p );
|
||||
}
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cut_CellIsRunning()
|
||||
{
|
||||
return s_pCMan != NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cut_CellDumpToFile()
|
||||
{
|
||||
FILE * pFile;
|
||||
Cut_CMan_t * p = s_pCMan;
|
||||
Cut_Cell_t * pTemp;
|
||||
char * pFileName = "celllib22.txt";
|
||||
int NumUsed[10][5] = {{0}};
|
||||
int BoxUsed[22][5] = {{0}};
|
||||
int i, k, Counter;
|
||||
int clk = clock();
|
||||
|
||||
if ( p == NULL )
|
||||
{
|
||||
printf( "Cut_CellDumpToFile: Cell manager is not defined.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// count the number of cells used
|
||||
for ( k = CUT_CELL_MVAR; k >= 0; k-- )
|
||||
{
|
||||
for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
|
||||
{
|
||||
if ( pTemp->nUsed == 0 )
|
||||
NumUsed[k][0]++;
|
||||
else if ( pTemp->nUsed < 10 )
|
||||
NumUsed[k][1]++;
|
||||
else if ( pTemp->nUsed < 100 )
|
||||
NumUsed[k][2]++;
|
||||
else if ( pTemp->nUsed < 1000 )
|
||||
NumUsed[k][3]++;
|
||||
else
|
||||
NumUsed[k][4]++;
|
||||
|
||||
for ( i = 0; i < 4; i++ )
|
||||
if ( pTemp->nUsed == 0 )
|
||||
BoxUsed[ pTemp->Box[i] ][0]++;
|
||||
else if ( pTemp->nUsed < 10 )
|
||||
BoxUsed[ pTemp->Box[i] ][1]++;
|
||||
else if ( pTemp->nUsed < 100 )
|
||||
BoxUsed[ pTemp->Box[i] ][2]++;
|
||||
else if ( pTemp->nUsed < 1000 )
|
||||
BoxUsed[ pTemp->Box[i] ][3]++;
|
||||
else
|
||||
BoxUsed[ pTemp->Box[i] ][4]++;
|
||||
}
|
||||
}
|
||||
|
||||
printf( "Functions found = %10d. Functions not found = %10d.\n", p->nCellFound, p->nCellNotFound );
|
||||
for ( k = 0; k <= CUT_CELL_MVAR; k++ )
|
||||
{
|
||||
printf( "%3d : ", k );
|
||||
for ( i = 0; i < 5; i++ )
|
||||
printf( "%8d ", NumUsed[k][i] );
|
||||
printf( "\n" );
|
||||
}
|
||||
printf( "Box usage:\n" );
|
||||
for ( k = 0; k < 22; k++ )
|
||||
{
|
||||
printf( "%3d : ", k );
|
||||
for ( i = 0; i < 5; i++ )
|
||||
printf( "%8d ", BoxUsed[k][i] );
|
||||
printf( " %s", s_NP3Names[k] );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
pFile = fopen( pFileName, "w" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
printf( "Cut_CellDumpToFile: Cannout open output file.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Counter = 0;
|
||||
for ( k = 0; k <= CUT_CELL_MVAR; k++ )
|
||||
{
|
||||
for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
|
||||
if ( pTemp->nUsed > 0 )
|
||||
{
|
||||
Extra_PrintHexadecimal( pFile, pTemp->uTruth, (k <= 5? 5 : k) );
|
||||
fprintf( pFile, "\n" );
|
||||
Counter++;
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
fclose( pFile );
|
||||
|
||||
printf( "Library composed of %d functions is written into file \"%s\". ", Counter, pFileName );
|
||||
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Looks up if the given function exists in the hash table.]
|
||||
|
||||
Description [If the function exists, returns 1, meaning that it can be
|
||||
implemented using two levels of 3-input LUTs. If the function does not
|
||||
exist, return 0.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cut_CellTruthLookup( unsigned * pTruth, int nVars )
|
||||
{
|
||||
Cut_CMan_t * p = s_pCMan;
|
||||
Cut_Cell_t * pTemp;
|
||||
Cut_Cell_t Cell, * pCell = &Cell;
|
||||
unsigned Hash;
|
||||
int i;
|
||||
|
||||
// cell manager is not defined
|
||||
if ( p == NULL )
|
||||
{
|
||||
printf( "Cut_CellTruthLookup: Cell manager is not defined.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// canonicize
|
||||
memset( pCell, 0, sizeof(Cut_Cell_t) );
|
||||
pCell->nVars = nVars;
|
||||
Extra_TruthCopy( pCell->uTruth, pTruth, nVars );
|
||||
Cut_CellSuppMin( pCell );
|
||||
// set the elementary permutation
|
||||
for ( i = 0; i < (int)pCell->nVars; i++ )
|
||||
pCell->CanonPerm[i] = i;
|
||||
// canonicize
|
||||
pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
|
||||
|
||||
|
||||
// check if the cell exists
|
||||
Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum(pCell->nVars) );
|
||||
if ( st_lookup( p->tTable, (char *)Hash, (char **)&pTemp ) )
|
||||
{
|
||||
for ( ; pTemp; pTemp = pTemp->pNext )
|
||||
{
|
||||
if ( pTemp->nVars != pCell->nVars )
|
||||
continue;
|
||||
if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) )
|
||||
{
|
||||
pTemp->nUsed++;
|
||||
p->nCellFound++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
p->nCellNotFound++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,491 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [abcCut.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Network and node package.]
|
||||
|
||||
Synopsis [Interface to cut computation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: abcCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "abc.h"
|
||||
#include "cut.h"
|
||||
#include "seqInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq );
|
||||
static void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq );
|
||||
|
||||
|
||||
extern int nTotal, nGood, nEqual;
|
||||
|
||||
// temporary
|
||||
//Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk ) { return NULL; }
|
||||
Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Int_t * vAttrs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 );
|
||||
int i;
|
||||
Abc_Obj_t * pObj;
|
||||
|
||||
// Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
// Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
|
||||
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
{
|
||||
// if ( Abc_ObjIsNode(pObj) && (rand() % 4 == 0) )
|
||||
if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) && (rand() % 3 == 0) )
|
||||
Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
|
||||
}
|
||||
return vAttrs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
|
||||
{
|
||||
ProgressBar * pProgress;
|
||||
Cut_Man_t * p;
|
||||
Abc_Obj_t * pObj, * pNode;
|
||||
Vec_Ptr_t * vNodes;
|
||||
Vec_Int_t * vChoices;
|
||||
int i;
|
||||
int clk = clock();
|
||||
|
||||
extern void Abc_NtkBalanceAttach( Abc_Ntk_t * pNtk );
|
||||
extern void Abc_NtkBalanceDetach( Abc_Ntk_t * pNtk );
|
||||
|
||||
nTotal = nGood = nEqual = 0;
|
||||
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
// start the manager
|
||||
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
|
||||
p = Cut_ManStart( pParams );
|
||||
// compute node attributes if local or global cuts are requested
|
||||
if ( pParams->fGlobal || pParams->fLocal )
|
||||
{
|
||||
extern Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk );
|
||||
Cut_ManSetNodeAttrs( p, Abc_NtkGetNodeAttributes(pNtk) );
|
||||
}
|
||||
// prepare for cut dropping
|
||||
if ( pParams->fDrop )
|
||||
Cut_ManSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) );
|
||||
// set cuts for PIs
|
||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
if ( Abc_ObjFanoutNum(pObj) > 0 )
|
||||
Cut_NodeSetTriv( p, pObj->Id );
|
||||
// compute cuts for internal nodes
|
||||
vNodes = Abc_AigDfs( pNtk, 0, 1 ); // collects POs
|
||||
vChoices = Vec_IntAlloc( 100 );
|
||||
pProgress = Extra_ProgressBarStart( stdout, Vec_PtrSize(vNodes) );
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
// when we reached a CO, it is time to deallocate the cuts
|
||||
if ( Abc_ObjIsCo(pObj) )
|
||||
{
|
||||
if ( pParams->fDrop )
|
||||
Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
|
||||
continue;
|
||||
}
|
||||
// skip constant node, it has no cuts
|
||||
if ( Abc_NodeIsConst(pObj) )
|
||||
continue;
|
||||
Extra_ProgressBarUpdate( pProgress, i, NULL );
|
||||
// compute the cuts to the internal node
|
||||
Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree );
|
||||
// consider dropping the fanins cuts
|
||||
if ( pParams->fDrop )
|
||||
{
|
||||
Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
|
||||
Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId1(pObj) );
|
||||
}
|
||||
// add cuts due to choices
|
||||
if ( Abc_NodeIsAigChoice(pObj) )
|
||||
{
|
||||
Vec_IntClear( vChoices );
|
||||
for ( pNode = pObj; pNode; pNode = pNode->pData )
|
||||
Vec_IntPush( vChoices, pNode->Id );
|
||||
Cut_NodeUnionCuts( p, vChoices );
|
||||
}
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
Vec_PtrFree( vNodes );
|
||||
Vec_IntFree( vChoices );
|
||||
PRT( "Total", clock() - clk );
|
||||
//Abc_NtkPrintCuts( p, pNtk, 0 );
|
||||
// Cut_ManPrintStatsToFile( p, pNtk->pSpec, clock() - clk );
|
||||
|
||||
// temporary printout of stats
|
||||
if ( nTotal )
|
||||
printf( "Total cuts = %d. Good cuts = %d. Ratio = %5.2f\n", nTotal, nGood, ((double)nGood)/nTotal );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Cut computation using the oracle.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkCutsOracle( Abc_Ntk_t * pNtk, Cut_Oracle_t * p )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
Vec_Ptr_t * vNodes;
|
||||
int i, clk = clock();
|
||||
int fDrop = Cut_OracleReadDrop(p);
|
||||
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
|
||||
// prepare cut droppping
|
||||
if ( fDrop )
|
||||
Cut_OracleSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) );
|
||||
|
||||
// set cuts for PIs
|
||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
if ( Abc_ObjFanoutNum(pObj) > 0 )
|
||||
Cut_OracleNodeSetTriv( p, pObj->Id );
|
||||
|
||||
// compute cuts for internal nodes
|
||||
vNodes = Abc_AigDfs( pNtk, 0, 1 ); // collects POs
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
{
|
||||
// when we reached a CO, it is time to deallocate the cuts
|
||||
if ( Abc_ObjIsCo(pObj) )
|
||||
{
|
||||
if ( fDrop )
|
||||
Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
|
||||
continue;
|
||||
}
|
||||
// skip constant node, it has no cuts
|
||||
if ( Abc_NodeIsConst(pObj) )
|
||||
continue;
|
||||
// compute the cuts to the internal node
|
||||
Cut_OracleComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
|
||||
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
|
||||
// consider dropping the fanins cuts
|
||||
if ( fDrop )
|
||||
{
|
||||
Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
|
||||
Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId1(pObj) );
|
||||
}
|
||||
}
|
||||
Vec_PtrFree( vNodes );
|
||||
//PRT( "Total", clock() - clk );
|
||||
//Abc_NtkPrintCuts_( p, pNtk, 0 );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
|
||||
{
|
||||
Cut_Man_t * p;
|
||||
Abc_Obj_t * pObj, * pNode;
|
||||
int i, nIters, fStatus;
|
||||
Vec_Int_t * vChoices;
|
||||
int clk = clock();
|
||||
|
||||
assert( Abc_NtkIsSeq(pNtk) );
|
||||
assert( pParams->fSeq );
|
||||
// assert( Abc_NtkIsDfsOrdered(pNtk) );
|
||||
|
||||
// start the manager
|
||||
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
|
||||
pParams->nCutSet = Abc_NtkCutSetNodeNum( pNtk );
|
||||
p = Cut_ManStart( pParams );
|
||||
|
||||
// set cuts for the constant node and the PIs
|
||||
pObj = Abc_NtkConst1(pNtk);
|
||||
if ( Abc_ObjFanoutNum(pObj) > 0 )
|
||||
Cut_NodeSetTriv( p, pObj->Id );
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
{
|
||||
//printf( "Setting trivial cut %d.\n", pObj->Id );
|
||||
Cut_NodeSetTriv( p, pObj->Id );
|
||||
}
|
||||
// label the cutset nodes and set their number in the array
|
||||
// assign the elementary cuts to the cutset nodes
|
||||
Abc_SeqForEachCutsetNode( pNtk, pObj, i )
|
||||
{
|
||||
assert( pObj->fMarkC == 0 );
|
||||
pObj->fMarkC = 1;
|
||||
pObj->pCopy = (Abc_Obj_t *)i;
|
||||
Cut_NodeSetTriv( p, pObj->Id );
|
||||
//printf( "Setting trivial cut %d.\n", pObj->Id );
|
||||
}
|
||||
|
||||
// process the nodes
|
||||
vChoices = Vec_IntAlloc( 100 );
|
||||
for ( nIters = 0; nIters < 10; nIters++ )
|
||||
{
|
||||
//printf( "ITERATION %d:\n", nIters );
|
||||
// compute the cuts for the internal nodes
|
||||
Abc_AigForEachAnd( pNtk, pObj, i )
|
||||
{
|
||||
Abc_NodeGetCutsSeq( p, pObj, nIters==0 );
|
||||
// add cuts due to choices
|
||||
if ( Abc_NodeIsAigChoice(pObj) )
|
||||
{
|
||||
Vec_IntClear( vChoices );
|
||||
for ( pNode = pObj; pNode; pNode = pNode->pData )
|
||||
Vec_IntPush( vChoices, pNode->Id );
|
||||
Cut_NodeUnionCutsSeq( p, vChoices, (pObj->fMarkC ? (int)pObj->pCopy : -1), nIters==0 );
|
||||
}
|
||||
}
|
||||
// merge the new cuts with the old cuts
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Cut_NodeNewMergeWithOld( p, pObj->Id );
|
||||
Abc_AigForEachAnd( pNtk, pObj, i )
|
||||
Cut_NodeNewMergeWithOld( p, pObj->Id );
|
||||
// for the cutset, transfer temp cuts to new cuts
|
||||
fStatus = 0;
|
||||
Abc_SeqForEachCutsetNode( pNtk, pObj, i )
|
||||
fStatus |= Cut_NodeTempTransferToNew( p, pObj->Id, i );
|
||||
if ( fStatus == 0 )
|
||||
break;
|
||||
}
|
||||
Vec_IntFree( vChoices );
|
||||
|
||||
// if the status is not finished, transfer new to old for the cutset
|
||||
Abc_SeqForEachCutsetNode( pNtk, pObj, i )
|
||||
Cut_NodeNewMergeWithOld( p, pObj->Id );
|
||||
|
||||
// transfer the old cuts to the new positions
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
Cut_NodeOldTransferToNew( p, pObj->Id );
|
||||
|
||||
// unlabel the cutset nodes
|
||||
Abc_SeqForEachCutsetNode( pNtk, pObj, i )
|
||||
pObj->fMarkC = 0;
|
||||
if ( pParams->fVerbose )
|
||||
{
|
||||
PRT( "Total", clock() - clk );
|
||||
printf( "Converged after %d iterations.\n", nIters );
|
||||
}
|
||||
//Abc_NtkPrintCuts( p, pNtk, 1 );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
|
||||
{
|
||||
void * pList;
|
||||
if ( pList = Abc_NodeReadCuts( p, pObj ) )
|
||||
return pList;
|
||||
Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj), fDag, fTree );
|
||||
Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj), fDag, fTree );
|
||||
return Abc_NodeGetCuts( p, pObj, fDag, fTree );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int fDagNode, fTriv, TreeCode = 0;
|
||||
// assert( Abc_NtkIsStrash(pObj->pNtk) );
|
||||
assert( Abc_ObjFaninNum(pObj) == 2 );
|
||||
|
||||
|
||||
// check if the node is a DAG node
|
||||
fDagNode = (Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj));
|
||||
// increment the counter of DAG nodes
|
||||
if ( fDagNode ) Cut_ManIncrementDagNodes( p );
|
||||
// add the trivial cut if the node is a DAG node, or if we compute all cuts
|
||||
fTriv = fDagNode || !fDag;
|
||||
// check if fanins are DAG nodes
|
||||
if ( fTree )
|
||||
{
|
||||
pFanin = Abc_ObjFanin0(pObj);
|
||||
TreeCode |= (Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin));
|
||||
pFanin = Abc_ObjFanin1(pObj);
|
||||
TreeCode |= ((Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin)) << 1);
|
||||
}
|
||||
|
||||
|
||||
// changes due to the global/local cut computation
|
||||
{
|
||||
Cut_Params_t * pParams = Cut_ManReadParams(p);
|
||||
if ( pParams->fLocal )
|
||||
{
|
||||
Vec_Int_t * vNodeAttrs = Cut_ManReadNodeAttrs(p);
|
||||
fDagNode = Vec_IntEntry( vNodeAttrs, pObj->Id );
|
||||
if ( fDagNode ) Cut_ManIncrementDagNodes( p );
|
||||
// fTriv = fDagNode || !pParams->fGlobal;
|
||||
fTriv = !Vec_IntEntry( vNodeAttrs, pObj->Id );
|
||||
TreeCode = 0;
|
||||
pFanin = Abc_ObjFanin0(pObj);
|
||||
TreeCode |= Vec_IntEntry( vNodeAttrs, pFanin->Id );
|
||||
pFanin = Abc_ObjFanin1(pObj);
|
||||
TreeCode |= (Vec_IntEntry( vNodeAttrs, pFanin->Id ) << 1);
|
||||
}
|
||||
}
|
||||
return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
|
||||
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), fTriv, TreeCode );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NodeGetCutsSeq( void * p, Abc_Obj_t * pObj, int fTriv )
|
||||
{
|
||||
int CutSetNum;
|
||||
assert( Abc_NtkIsSeq(pObj->pNtk) );
|
||||
assert( Abc_ObjFaninNum(pObj) == 2 );
|
||||
fTriv = pObj->fMarkC ? 0 : fTriv;
|
||||
CutSetNum = pObj->fMarkC ? (int)pObj->pCopy : -1;
|
||||
Cut_NodeComputeCutsSeq( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
|
||||
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), Seq_ObjFaninL0(pObj), Seq_ObjFaninL1(pObj), fTriv, CutSetNum );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
return Cut_NodeReadCutsNew( p, pObj->Id );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj )
|
||||
{
|
||||
Cut_NodeFreeCuts( p, pObj->Id );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq )
|
||||
{
|
||||
Cut_Man_t * pMan = p;
|
||||
Cut_Cut_t * pList;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
printf( "Cuts of the network:\n" );
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
{
|
||||
pList = Abc_NodeReadCuts( p, pObj );
|
||||
printf( "Node %s:\n", Abc_ObjName(pObj) );
|
||||
Cut_CutPrintList( pList, fSeq );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq )
|
||||
{
|
||||
Cut_Man_t * pMan = p;
|
||||
Cut_Cut_t * pList;
|
||||
Abc_Obj_t * pObj;
|
||||
pObj = Abc_NtkObj( pNtk, 2 * Abc_NtkObjNum(pNtk) / 3 );
|
||||
pList = Abc_NodeReadCuts( p, pObj );
|
||||
printf( "Node %s:\n", Abc_ObjName(pObj) );
|
||||
Cut_CutPrintList( pList, fSeq );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -61,6 +61,8 @@ struct Cut_ParamsStruct_t_
|
|||
int fDrop; // drop cuts on the fly
|
||||
int fDag; // compute only DAG cuts
|
||||
int fTree; // compute only tree cuts
|
||||
int fGlobal; // compute only global cuts
|
||||
int fLocal; // compute only local cuts
|
||||
int fRecord; // record the cut computation flow
|
||||
int fFancy; // perform fancy computations
|
||||
int fVerbose; // the verbosiness flag
|
||||
|
|
@ -118,7 +120,10 @@ extern void Cut_ManStop( Cut_Man_t * p );
|
|||
extern void Cut_ManPrintStats( Cut_Man_t * p );
|
||||
extern void Cut_ManPrintStatsToFile( Cut_Man_t * p, char * pFileName, int TimeTotal );
|
||||
extern void Cut_ManSetFanoutCounts( Cut_Man_t * p, Vec_Int_t * vFanCounts );
|
||||
extern void Cut_ManSetNodeAttrs( Cut_Man_t * p, Vec_Int_t * vFanCounts );
|
||||
extern int Cut_ManReadVarsMax( Cut_Man_t * p );
|
||||
extern Cut_Params_t * Cut_ManReadParams( Cut_Man_t * p );
|
||||
extern Vec_Int_t * Cut_ManReadNodeAttrs( Cut_Man_t * p );
|
||||
extern void Cut_ManIncrementDagNodes( Cut_Man_t * p );
|
||||
/*=== cutNode.c ==========================================================*/
|
||||
extern Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv, int TreeCode );
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ struct Cut_ManStruct_t_
|
|||
// user preferences
|
||||
Cut_Params_t * pParams; // computation parameters
|
||||
Vec_Int_t * vFanCounts; // the array of fanout counters
|
||||
Vec_Int_t * vNodeAttrs; // node attributes (1 = global; 0 = local)
|
||||
// storage for cuts
|
||||
Vec_Ptr_t * vCutsNew; // new cuts by node ID
|
||||
Vec_Ptr_t * vCutsOld; // old cuts by node ID
|
||||
|
|
|
|||
|
|
@ -222,6 +222,22 @@ void Cut_ManSetFanoutCounts( Cut_Man_t * p, Vec_Int_t * vFanCounts )
|
|||
p->vFanCounts = vFanCounts;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cut_ManSetNodeAttrs( Cut_Man_t * p, Vec_Int_t * vNodeAttrs )
|
||||
{
|
||||
p->vNodeAttrs = vNodeAttrs;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -238,6 +254,38 @@ int Cut_ManReadVarsMax( Cut_Man_t * p )
|
|||
return p->pParams->nVarsMax;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Cut_Params_t * Cut_ManReadParams( Cut_Man_t * p )
|
||||
{
|
||||
return p->pParams;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Cut_ManReadNodeAttrs( Cut_Man_t * p )
|
||||
{
|
||||
return p->vNodeAttrs;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
|
|||
|
|
@ -204,6 +204,32 @@ static inline int Cut_CutFilterOne( Cut_Man_t * p, Cut_List_t * pSuperList, Cut_
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if the cut is local and can be removed.]
|
||||
|
||||
Description [Returns 1 if the cut is removed.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Cut_CutFilterGlobal( Cut_Man_t * p, Cut_Cut_t * pCut )
|
||||
{
|
||||
int a;
|
||||
if ( pCut->nLeaves == 1 )
|
||||
return 0;
|
||||
for ( a = 0; a < (int)pCut->nLeaves; a++ )
|
||||
if ( Vec_IntEntry( p->vNodeAttrs, pCut->pLeaves[a] ) ) // global
|
||||
return 0;
|
||||
// there is no global nodes, the cut should be removed
|
||||
p->nCutsFilter++;
|
||||
Cut_CutRecycle( p, pCut );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks containment for one cut.]
|
||||
|
|
@ -306,6 +332,14 @@ static inline int Cut_CutProcessTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( p->pParams->fGlobal )
|
||||
{
|
||||
assert( p->vNodeAttrs != NULL );
|
||||
if ( Cut_CutFilterGlobal( p, pCut ) )
|
||||
return 0;
|
||||
}
|
||||
|
||||
// compute the truth table
|
||||
if ( p->pParams->fTruth )
|
||||
Cut_TruthCompute( p, pCut, pCut0, pCut1, p->fCompl0, p->fCompl1 );
|
||||
|
|
@ -395,7 +429,7 @@ void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fC
|
|||
p->nNodeCuts++;
|
||||
}
|
||||
// get the cut lists of children
|
||||
if ( pList0 == NULL || pList1 == NULL )
|
||||
if ( pList0 == NULL || pList1 == NULL || (p->pParams->fLocal && TreeCode) )
|
||||
return;
|
||||
|
||||
// remember the old number of cuts
|
||||
|
|
|
|||
|
|
@ -617,7 +617,7 @@ void Cut_CellCrossBar( Cut_Cell_t * pCell )
|
|||
Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar1 );
|
||||
}
|
||||
else assert( 0 );
|
||||
Extra_TruthCombine( pCell->uTruth, uTemp0, uTemp1, pCell->nVars, pCell->CrossBar0 );
|
||||
Extra_TruthMux( pCell->uTruth, uTemp0, uTemp1, pCell->nVars, pCell->CrossBar0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vec.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_H__
|
||||
#define __VEC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef _WIN32
|
||||
#define inline __inline // compatible with MS VS 6.0
|
||||
#endif
|
||||
|
||||
#include "vecInt.h"
|
||||
#include "vecStr.h"
|
||||
#include "vecPtr.h"
|
||||
#include "vecVec.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,753 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vecInt.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [Resizable arrays of integers.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_INT_H__
|
||||
#define __VEC_INT_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Vec_Int_t_ Vec_Int_t;
|
||||
struct Vec_Int_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
int * pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define Vec_IntForEachEntry( vVec, Entry, i ) \
|
||||
for ( i = 0; (i < Vec_IntSize(vVec)) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_IntForEachEntryStart( vVec, Entry, i, Start ) \
|
||||
for ( i = Start; (i < Vec_IntSize(vVec)) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_IntForEachEntryStartStop( vVec, Entry, i, Start, Stop ) \
|
||||
for ( i = Start; (i < Stop) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_IntForEachEntryReverse( vVec, pEntry, i ) \
|
||||
for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_IntEntry(vVec, i)), 1); i-- )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntAlloc( int nCap )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = ALLOC( Vec_Int_t, 1 );
|
||||
if ( nCap > 0 && nCap < 16 )
|
||||
nCap = 16;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( int, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given size and cleans it.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntStart( int nSize )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = Vec_IntAlloc( nSize );
|
||||
p->nSize = nSize;
|
||||
memset( p->pArray, 0, sizeof(int) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntAllocArray( int * pArray, int nSize )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = ALLOC( Vec_Int_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = pArray;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntAllocArrayCopy( int * pArray, int nSize )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = ALLOC( Vec_Int_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = ALLOC( int, nSize );
|
||||
memcpy( p->pArray, pArray, sizeof(int) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the integer array.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntDup( Vec_Int_t * pVec )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = ALLOC( Vec_Int_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = p->nCap? ALLOC( int, p->nCap ) : NULL;
|
||||
memcpy( p->pArray, pVec->pArray, sizeof(int) * pVec->nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers the array into another vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Int_t * Vec_IntDupArray( Vec_Int_t * pVec )
|
||||
{
|
||||
Vec_Int_t * p;
|
||||
p = ALLOC( Vec_Int_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = pVec->pArray;
|
||||
pVec->nSize = 0;
|
||||
pVec->nCap = 0;
|
||||
pVec->pArray = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntFree( Vec_Int_t * p )
|
||||
{
|
||||
FREE( p->pArray );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int * Vec_IntReleaseArray( Vec_Int_t * p )
|
||||
{
|
||||
int * pArray = p->pArray;
|
||||
p->nCap = 0;
|
||||
p->nSize = 0;
|
||||
p->pArray = NULL;
|
||||
return pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int * Vec_IntArray( Vec_Int_t * p )
|
||||
{
|
||||
return p->pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntSize( Vec_Int_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntEntry( Vec_Int_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntWriteEntry( Vec_Int_t * p, int i, int Entry )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntAddToEntry( Vec_Int_t * p, int i, int Addition )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] += Addition;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntEntryLast( Vec_Int_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[p->nSize-1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Resizes the vector to the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntGrow( Vec_Int_t * p, int nCapMin )
|
||||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
p->pArray = REALLOC( int, p->pArray, nCapMin );
|
||||
assert( p->pArray );
|
||||
p->nCap = nCapMin;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntFill( Vec_Int_t * p, int nSize, int Entry )
|
||||
{
|
||||
int i;
|
||||
Vec_IntGrow( p, nSize );
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize >= nSize )
|
||||
return;
|
||||
Vec_IntGrow( p, nSize );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntShrink( Vec_Int_t * p, int nSizeNew )
|
||||
{
|
||||
assert( p->nSize >= nSizeNew );
|
||||
p->nSize = nSizeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntClear( Vec_Int_t * p )
|
||||
{
|
||||
p->nSize = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntPush( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_IntGrow( p, 16 );
|
||||
else
|
||||
Vec_IntGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntPushFirst( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_IntGrow( p, 16 );
|
||||
else
|
||||
Vec_IntGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->nSize++;
|
||||
for ( i = p->nSize - 1; i >= 1; i-- )
|
||||
p->pArray[i] = p->pArray[i-1];
|
||||
p->pArray[0] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntPushMem( Extra_MmStep_t * pMemMan, Vec_Int_t * p, int Entry )
|
||||
{
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
int * pArray;
|
||||
int i;
|
||||
|
||||
if ( p->nSize == 0 )
|
||||
p->nCap = 1;
|
||||
pArray = (int *)Extra_MmStepEntryFetch( pMemMan, p->nCap * 8 );
|
||||
// pArray = ALLOC( int, p->nCap * 2 );
|
||||
if ( p->pArray )
|
||||
{
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
pArray[i] = p->pArray[i];
|
||||
Extra_MmStepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 );
|
||||
// free( p->pArray );
|
||||
}
|
||||
p->nCap *= 2;
|
||||
p->pArray = pArray;
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts the entry while preserving the increasing order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntPushOrder( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_IntGrow( p, 16 );
|
||||
else
|
||||
Vec_IntGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->nSize++;
|
||||
for ( i = p->nSize-2; i >= 0; i-- )
|
||||
if ( p->pArray[i] > Entry )
|
||||
p->pArray[i+1] = p->pArray[i];
|
||||
else
|
||||
break;
|
||||
p->pArray[i+1] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts the entry while preserving the increasing order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntPushUniqueOrder( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return 1;
|
||||
Vec_IntPushOrder( p, Entry );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntPushUnique( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return 1;
|
||||
Vec_IntPush( p, Entry );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the last entry and removes it from the list.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntPop( Vec_Int_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[--p->nSize];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find entry.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntFind( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntRemove( Vec_Int_t * p, int Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
break;
|
||||
if ( i == p->nSize )
|
||||
return 0;
|
||||
assert( i < p->nSize );
|
||||
for ( i++; i < p->nSize; i++ )
|
||||
p->pArray[i-1] = p->pArray[i];
|
||||
p->nSize--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two integers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntSortCompare1( int * pp1, int * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two integers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntSortCompare2( int * pp1, int * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 > *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 < *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntSort( Vec_Int_t * p, int fReverse )
|
||||
{
|
||||
if ( fReverse )
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(int),
|
||||
(int (*)(const void *, const void *)) Vec_IntSortCompare2 );
|
||||
else
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(int),
|
||||
(int (*)(const void *, const void *)) Vec_IntSortCompare1 );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two integers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_IntSortCompareUnsigned( unsigned * pp1, unsigned * pp2 )
|
||||
{
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntSortUnsigned( Vec_Int_t * p )
|
||||
{
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(int),
|
||||
(int (*)(const void *, const void *)) Vec_IntSortCompareUnsigned );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,579 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vecPtr.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [Resizable arrays of generic pointers.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vecPtr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_PTR_H__
|
||||
#define __VEC_PTR_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Vec_Ptr_t_ Vec_Ptr_t;
|
||||
struct Vec_Ptr_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
void ** pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// iterators through entries
|
||||
#define Vec_PtrForEachEntry( vVec, pEntry, i ) \
|
||||
for ( i = 0; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_PtrForEachEntryStart( vVec, pEntry, i, Start ) \
|
||||
for ( i = Start; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_PtrForEachEntryStop( vVec, pEntry, i, Stop ) \
|
||||
for ( i = 0; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_PtrForEachEntryStartStop( vVec, pEntry, i, Start, Stop ) \
|
||||
for ( i = Start; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
|
||||
#define Vec_PtrForEachEntryReverse( vVec, pEntry, i ) \
|
||||
for ( i = Vec_PtrSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i-- )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrAlloc( int nCap )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = ALLOC( Vec_Ptr_t, 1 );
|
||||
if ( nCap > 0 && nCap < 8 )
|
||||
nCap = 8;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given size and cleans it.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrStart( int nSize )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = Vec_PtrAlloc( nSize );
|
||||
p->nSize = nSize;
|
||||
memset( p->pArray, 0, sizeof(void *) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrAllocArray( void ** pArray, int nSize )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = ALLOC( Vec_Ptr_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = pArray;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrAllocArrayCopy( void ** pArray, int nSize )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = ALLOC( Vec_Ptr_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = ALLOC( void *, nSize );
|
||||
memcpy( p->pArray, pArray, sizeof(void *) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the integer array.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrDup( Vec_Ptr_t * pVec )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = ALLOC( Vec_Ptr_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
|
||||
memcpy( p->pArray, pVec->pArray, sizeof(void *) * pVec->nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers the array into another vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Ptr_t * Vec_PtrDupArray( Vec_Ptr_t * pVec )
|
||||
{
|
||||
Vec_Ptr_t * p;
|
||||
p = ALLOC( Vec_Ptr_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = pVec->pArray;
|
||||
pVec->nSize = 0;
|
||||
pVec->nCap = 0;
|
||||
pVec->pArray = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Frees the vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrFree( Vec_Ptr_t * p )
|
||||
{
|
||||
FREE( p->pArray );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void ** Vec_PtrReleaseArray( Vec_Ptr_t * p )
|
||||
{
|
||||
void ** pArray = p->pArray;
|
||||
p->nCap = 0;
|
||||
p->nSize = 0;
|
||||
p->pArray = NULL;
|
||||
return pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void ** Vec_PtrArray( Vec_Ptr_t * p )
|
||||
{
|
||||
return p->pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_PtrSize( Vec_Ptr_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void * Vec_PtrEntry( Vec_Ptr_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void ** Vec_PtrEntryP( Vec_Ptr_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray + i;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrWriteEntry( Vec_Ptr_t * p, int i, void * Entry )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void * Vec_PtrEntryLast( Vec_Ptr_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[p->nSize-1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Resizes the vector to the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrGrow( Vec_Ptr_t * p, int nCapMin )
|
||||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
p->pArray = REALLOC( void *, p->pArray, nCapMin );
|
||||
p->nCap = nCapMin;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrFill( Vec_Ptr_t * p, int nSize, void * Entry )
|
||||
{
|
||||
int i;
|
||||
Vec_PtrGrow( p, nSize );
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrFillExtra( Vec_Ptr_t * p, int nSize, void * Entry )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize >= nSize )
|
||||
return;
|
||||
if ( p->nSize < 2 * nSize )
|
||||
Vec_PtrGrow( p, 2 * nSize );
|
||||
else
|
||||
Vec_PtrGrow( p, p->nSize );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrShrink( Vec_Ptr_t * p, int nSizeNew )
|
||||
{
|
||||
assert( p->nSize >= nSizeNew );
|
||||
p->nSize = nSizeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrClear( Vec_Ptr_t * p )
|
||||
{
|
||||
p->nSize = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrPush( Vec_Ptr_t * p, void * Entry )
|
||||
{
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_PtrGrow( p, 16 );
|
||||
else
|
||||
Vec_PtrGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_PtrPushUnique( Vec_Ptr_t * p, void * Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return 1;
|
||||
Vec_PtrPush( p, Entry );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the last entry and removes it from the list.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void * Vec_PtrPop( Vec_Ptr_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[--p->nSize];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find entry.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_PtrFind( Vec_Ptr_t * p, void * Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrRemove( Vec_Ptr_t * p, void * Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
break;
|
||||
assert( i < p->nSize );
|
||||
for ( i++; i < p->nSize; i++ )
|
||||
p->pArray[i-1] = p->pArray[i];
|
||||
p->nSize--;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Moves the first nItems to the end.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrReorder( Vec_Ptr_t * p, int nItems )
|
||||
{
|
||||
assert( nItems < p->nSize );
|
||||
Vec_PtrGrow( p, nItems + p->nSize );
|
||||
memmove( (char **)p->pArray + p->nSize, p->pArray, nItems * sizeof(void*) );
|
||||
memmove( p->pArray, (char **)p->pArray + nItems, p->nSize * sizeof(void*) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
|
||||
{
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(void *),
|
||||
(int (*)(const void *, const void *)) Vec_PtrSortCompare );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,510 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vecStr.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [Resizable arrays of characters.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vecStr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_STR_H__
|
||||
#define __VEC_STR_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Vec_Str_t_ Vec_Str_t;
|
||||
struct Vec_Str_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
char * pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define Vec_StrForEachEntry( vVec, Entry, i ) \
|
||||
for ( i = 0; (i < Vec_StrSize(vVec)) && (((Entry) = Vec_StrEntry(vVec, i)), 1); i++ )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrAlloc( int nCap )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
if ( nCap > 0 && nCap < 16 )
|
||||
nCap = 16;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given size and cleans it.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrStart( int nSize )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = Vec_StrAlloc( nSize );
|
||||
p->nSize = nSize;
|
||||
memset( p->pArray, 0, sizeof(char) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrAllocArray( char * pArray, int nSize )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = pArray;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the vector from an integer array of the given size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrAllocArrayCopy( char * pArray, int nSize )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = nSize;
|
||||
p->nCap = nSize;
|
||||
p->pArray = ALLOC( char, nSize );
|
||||
memcpy( p->pArray, pArray, sizeof(char) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the integer array.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrDup( Vec_Str_t * pVec )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL;
|
||||
memcpy( p->pArray, pVec->pArray, sizeof(char) * pVec->nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers the array into another vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Str_t * Vec_StrDupArray( Vec_Str_t * pVec )
|
||||
{
|
||||
Vec_Str_t * p;
|
||||
p = ALLOC( Vec_Str_t, 1 );
|
||||
p->nSize = pVec->nSize;
|
||||
p->nCap = pVec->nCap;
|
||||
p->pArray = pVec->pArray;
|
||||
pVec->nSize = 0;
|
||||
pVec->nCap = 0;
|
||||
pVec->pArray = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrFree( Vec_Str_t * p )
|
||||
{
|
||||
FREE( p->pArray );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char * Vec_StrReleaseArray( Vec_Str_t * p )
|
||||
{
|
||||
char * pArray = p->pArray;
|
||||
p->nCap = 0;
|
||||
p->nSize = 0;
|
||||
p->pArray = NULL;
|
||||
return pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char * Vec_StrArray( Vec_Str_t * p )
|
||||
{
|
||||
return p->pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_StrSize( Vec_Str_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char Vec_StrEntry( Vec_Str_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrWriteEntry( Vec_Str_t * p, int i, char Entry )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char Vec_StrEntryLast( Vec_Str_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[p->nSize-1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Resizes the vector to the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrGrow( Vec_Str_t * p, int nCapMin )
|
||||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
p->pArray = REALLOC( char, p->pArray, 2 * nCapMin );
|
||||
p->nCap = 2 * nCapMin;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Fills the vector with given number of entries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrFill( Vec_Str_t * p, int nSize, char Entry )
|
||||
{
|
||||
int i;
|
||||
Vec_StrGrow( p, nSize );
|
||||
p->nSize = nSize;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrShrink( Vec_Str_t * p, int nSizeNew )
|
||||
{
|
||||
assert( p->nSize >= nSizeNew );
|
||||
p->nSize = nSizeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrClear( Vec_Str_t * p )
|
||||
{
|
||||
p->nSize = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrPush( Vec_Str_t * p, char Entry )
|
||||
{
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Vec_StrGrow( p, 16 );
|
||||
else
|
||||
Vec_StrGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Appends the string to the char vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrAppend( Vec_Str_t * p, char * pString )
|
||||
{
|
||||
int i, nLength = strlen(pString);
|
||||
Vec_StrGrow( p, p->nSize + nLength );
|
||||
for ( i = 0; i < nLength; i++ )
|
||||
p->pArray[p->nSize + i] = pString[i];
|
||||
p->nSize += nLength;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the last entry and removes it from the list.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline char Vec_StrPop( Vec_Str_t * p )
|
||||
{
|
||||
assert( p->nSize > 0 );
|
||||
return p->pArray[--p->nSize];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two clauses.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_StrSortCompare1( char * pp1, char * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 < *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 > *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two clauses.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_StrSortCompare2( char * pp1, char * pp2 )
|
||||
{
|
||||
// for some reason commenting out lines (as shown) led to crashing of the release version
|
||||
if ( *pp1 > *pp2 )
|
||||
return -1;
|
||||
if ( *pp1 < *pp2 ) //
|
||||
return 1;
|
||||
return 0; //
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_StrSort( Vec_Str_t * p, int fReverse )
|
||||
{
|
||||
if ( fReverse )
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(char),
|
||||
(int (*)(const void *, const void *)) Vec_StrSortCompare2 );
|
||||
else
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(char),
|
||||
(int (*)(const void *, const void *)) Vec_StrSortCompare1 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [vecVec.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Resizable arrays.]
|
||||
|
||||
Synopsis [Resizable vector of resizable vectors.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: vecVec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __VEC_VEC_H__
|
||||
#define __VEC_VEC_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Vec_Vec_t_ Vec_Vec_t;
|
||||
struct Vec_Vec_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
void ** pArray;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// iterators through levels
|
||||
#define Vec_VecForEachLevel( vGlob, vVec, i ) \
|
||||
for ( i = 0; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
|
||||
#define Vec_VecForEachLevelStart( vGlob, vVec, i, LevelStart ) \
|
||||
for ( i = LevelStart; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
|
||||
#define Vec_VecForEachLevelStartStop( vGlob, vVec, i, LevelStart, LevelStop ) \
|
||||
for ( i = LevelStart; (i <= LevelStop) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
|
||||
#define Vec_VecForEachLevelReverse( vGlob, vVec, i ) \
|
||||
for ( i = Vec_VecSize(vGlob) - 1; (i >= 0) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i-- )
|
||||
|
||||
// iteratores through entries
|
||||
#define Vec_VecForEachEntry( vGlob, pEntry, i, k ) \
|
||||
for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \
|
||||
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
#define Vec_VecForEachEntryStart( vGlob, pEntry, i, k, LevelStart ) \
|
||||
for ( i = LevelStart; i < Vec_VecSize(vGlob); i++ ) \
|
||||
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
#define Vec_VecForEachEntryStartStop( vGlob, pEntry, i, k, LevelStart, LevelStop ) \
|
||||
for ( i = LevelStart; i <= LevelStop; i++ ) \
|
||||
Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
#define Vec_VecForEachEntryReverse( vGlob, pEntry, i, k ) \
|
||||
for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \
|
||||
Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
#define Vec_VecForEachEntryReverseReverse( vGlob, pEntry, i, k ) \
|
||||
for ( i = Vec_VecSize(vGlob) - 1; i >= 0; i-- ) \
|
||||
Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Vec_t * Vec_VecAlloc( int nCap )
|
||||
{
|
||||
Vec_Vec_t * p;
|
||||
p = ALLOC( Vec_Vec_t, 1 );
|
||||
if ( nCap > 0 && nCap < 8 )
|
||||
nCap = 8;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Vec_t * Vec_VecStart( int nSize )
|
||||
{
|
||||
Vec_Vec_t * p;
|
||||
int i;
|
||||
p = Vec_VecAlloc( nSize );
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
p->pArray[i] = Vec_PtrAlloc( 0 );
|
||||
p->nSize = nSize;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecExpand( Vec_Vec_t * p, int Level )
|
||||
{
|
||||
int i;
|
||||
if ( p->nSize >= Level + 1 )
|
||||
return;
|
||||
Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
|
||||
for ( i = p->nSize; i <= Level; i++ )
|
||||
p->pArray[i] = Vec_PtrAlloc( 0 );
|
||||
p->nSize = Level + 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_VecSize( Vec_Vec_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void * Vec_VecEntry( Vec_Vec_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Frees the vector.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecFree( Vec_Vec_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vVec;
|
||||
int i;
|
||||
Vec_VecForEachLevel( p, vVec, i )
|
||||
Vec_PtrFree( vVec );
|
||||
Vec_PtrFree( (Vec_Ptr_t *)p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Frees the vector of vectors.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_VecSizeSize( Vec_Vec_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vVec;
|
||||
int i, Counter = 0;
|
||||
Vec_VecForEachLevel( p, vVec, i )
|
||||
Counter += vVec->nSize;
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecClear( Vec_Vec_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vVec;
|
||||
int i;
|
||||
Vec_VecForEachLevel( p, vVec, i )
|
||||
Vec_PtrClear( vVec );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecPush( Vec_Vec_t * p, int Level, void * Entry )
|
||||
{
|
||||
if ( p->nSize < Level + 1 )
|
||||
{
|
||||
int i;
|
||||
Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
|
||||
for ( i = p->nSize; i < Level + 1; i++ )
|
||||
p->pArray[i] = Vec_PtrAlloc( 0 );
|
||||
p->nSize = Level + 1;
|
||||
}
|
||||
Vec_PtrPush( (Vec_Ptr_t*)p->pArray[Level], Entry );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_VecPushUnique( Vec_Vec_t * p, int Level, void * Entry )
|
||||
{
|
||||
if ( p->nSize < Level + 1 )
|
||||
Vec_VecPush( p, Level, Entry );
|
||||
else
|
||||
Vec_PtrPushUnique( (Vec_Ptr_t*)p->pArray[Level], Entry );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -267,7 +267,7 @@ Ivy_Obj_t * Dec_GraphToNetworkIvy( Ivy_Man_t * pMan, Dec_Graph_t * pGraph )
|
|||
{
|
||||
pAnd0 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
|
||||
pAnd1 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
|
||||
pNode->pFunc = Ivy_And( pAnd0, pAnd1 );
|
||||
pNode->pFunc = Ivy_And( pMan, pAnd0, pAnd1 );
|
||||
}
|
||||
// complement the result if necessary
|
||||
return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,241 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fraigTrans.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Adds the additive and distributive choices to the AIG.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - February 1, 2003.]
|
||||
|
||||
Revision [$Id: fraigTrans.c,v 1.1 2005/02/28 05:34:34 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fraigInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds choice nodes based on associativity.]
|
||||
|
||||
Description [Make nLimit big AND gates and add all decompositions
|
||||
to the Fraig.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fraig_ManAddChoices( Fraig_Man_t * pMan, int fVerbose, int nLimit )
|
||||
{
|
||||
// ProgressBar * pProgress;
|
||||
char Buffer[100];
|
||||
int clkTotal = clock();
|
||||
int i, nNodesBefore, nNodesAfter, nInputs, nMaxNodes;
|
||||
int /*nMaxLevel,*/ nDistributive;
|
||||
Fraig_Node_t *pNode, *pRepr;
|
||||
Fraig_Node_t *pX, *pA, *pB, *pC, /* *pD,*/ *pN, /* *pQ, *pR,*/ *pT;
|
||||
int fShortCut = 0;
|
||||
|
||||
nDistributive = 0;
|
||||
|
||||
// Fraig_ManSetApprox( pMan, 1 );
|
||||
|
||||
// NO functional reduction
|
||||
if (fShortCut) Fraig_ManSetFuncRed( pMan, 0 );
|
||||
|
||||
// First we mark critical functions i.e. compute those
|
||||
// nodes which lie on the critical path. Note that this
|
||||
// doesn't update the required times on any choice nodes
|
||||
// which are not the representatives
|
||||
/*
|
||||
nMaxLevel = Fraig_GetMaxLevel( pMan );
|
||||
for ( i = 0; i < pMan->nOutputs; i++ )
|
||||
{
|
||||
Fraig_SetNodeRequired( pMan, pMan->pOutputs[i], nMaxLevel );
|
||||
}
|
||||
*/
|
||||
nNodesBefore = Fraig_ManReadNodeNum( pMan );
|
||||
nInputs = Fraig_ManReadInputNum( pMan );
|
||||
nMaxNodes = nInputs + nLimit * ( nNodesBefore - nInputs );
|
||||
|
||||
printf ("Limit = %d, Before = %d\n", nMaxNodes, nNodesBefore );
|
||||
|
||||
if (0)
|
||||
{
|
||||
char buffer[128];
|
||||
sprintf (buffer, "test" );
|
||||
// Fraig_MappingShow( pMan, buffer );
|
||||
}
|
||||
|
||||
// pProgress = Extra_ProgressBarStart( stdout, nMaxNodes );
|
||||
Fraig_ManCheckConsistency( pMan );
|
||||
|
||||
for ( i = nInputs+1; (i < Fraig_ManReadNodeNum( pMan ))
|
||||
&& (nMaxNodes > Fraig_ManReadNodeNum( pMan )); ++i )
|
||||
{
|
||||
// if ( i == nNodesBefore )
|
||||
// break;
|
||||
|
||||
pNode = Fraig_ManReadIthNode( pMan, i );
|
||||
assert ( pNode );
|
||||
|
||||
pRepr = pNode->pRepr ? pNode->pRepr : pNode;
|
||||
//printf ("Slack: %d\n", Fraig_NodeReadSlack( pRepr ));
|
||||
|
||||
// All the new associative choices we add will have huge slack
|
||||
// since we do not redo timing, and timing doesnt handle choices
|
||||
// well anyway. However every newly added node is a choice of an
|
||||
// existing critical node, so they are considered critical.
|
||||
// if ( (Fraig_NodeReadSlack( pRepr ) > 3) && (i < nNodesBefore) )
|
||||
// continue;
|
||||
|
||||
// if ( pNode->pRepr )
|
||||
// continue;
|
||||
|
||||
// Try ((ab)c), x = ab -> (a(bc)) and (b(ac))
|
||||
pX = Fraig_NodeReadOne(pNode);
|
||||
pC = Fraig_NodeReadTwo(pNode);
|
||||
if (Fraig_NodeIsAnd(pX) && !Fraig_IsComplement(pX))
|
||||
{
|
||||
pA = Fraig_NodeReadOne(Fraig_Regular(pX));
|
||||
pB = Fraig_NodeReadTwo(Fraig_Regular(pX));
|
||||
|
||||
// pA = Fraig_NodeGetRepr( pA );
|
||||
// pB = Fraig_NodeGetRepr( pB );
|
||||
// pC = Fraig_NodeGetRepr( pC );
|
||||
|
||||
if (fShortCut)
|
||||
{
|
||||
pT = Fraig_NodeAnd(pMan, pB, pC);
|
||||
if ( !pT->pRepr )
|
||||
{
|
||||
pN = Fraig_NodeAnd(pMan, pA, pT);
|
||||
// Fraig_NodeAddChoice( pMan, pNode, pN );
|
||||
}
|
||||
}
|
||||
else
|
||||
pN = Fraig_NodeAnd(pMan, pA, Fraig_NodeAnd(pMan, pB, pC));
|
||||
// assert ( Fraig_NodesEqual(pN, pNode) );
|
||||
|
||||
|
||||
if (fShortCut)
|
||||
{
|
||||
pT = Fraig_NodeAnd(pMan, pA, pC);
|
||||
if ( !pT->pRepr )
|
||||
{
|
||||
pN = Fraig_NodeAnd(pMan, pB, pT);
|
||||
// Fraig_NodeAddChoice( pMan, pNode, pN );
|
||||
}
|
||||
}
|
||||
else
|
||||
pN = Fraig_NodeAnd(pMan, pB, Fraig_NodeAnd(pMan, pA, pC));
|
||||
// assert ( Fraig_NodesEqual(pN, pNode) );
|
||||
}
|
||||
|
||||
|
||||
// Try (a(bc)), x = bc -> ((ab)c) and ((ac)b)
|
||||
pA = Fraig_NodeReadOne(pNode);
|
||||
pX = Fraig_NodeReadTwo(pNode);
|
||||
if (Fraig_NodeIsAnd(pX) && !Fraig_IsComplement(pX))
|
||||
{
|
||||
pB = Fraig_NodeReadOne(Fraig_Regular(pX));
|
||||
pC = Fraig_NodeReadTwo(Fraig_Regular(pX));
|
||||
|
||||
// pA = Fraig_NodeGetRepr( pA );
|
||||
// pB = Fraig_NodeGetRepr( pB );
|
||||
// pC = Fraig_NodeGetRepr( pC );
|
||||
|
||||
if (fShortCut)
|
||||
{
|
||||
pT = Fraig_NodeAnd(pMan, pA, pB);
|
||||
if ( !pT->pRepr )
|
||||
{
|
||||
pN = Fraig_NodeAnd(pMan, pC, pT);
|
||||
// Fraig_NodeAddChoice( pMan, pNode, pN );
|
||||
}
|
||||
}
|
||||
else
|
||||
pN = Fraig_NodeAnd(pMan, Fraig_NodeAnd(pMan, pA, pB), pC);
|
||||
// assert ( Fraig_NodesEqual(pN, pNode) );
|
||||
|
||||
if (fShortCut)
|
||||
{
|
||||
pT = Fraig_NodeAnd(pMan, pA, pC);
|
||||
if ( !pT->pRepr )
|
||||
{
|
||||
pN = Fraig_NodeAnd(pMan, pB, pT);
|
||||
// Fraig_NodeAddChoice( pMan, pNode, pN );
|
||||
}
|
||||
}
|
||||
else
|
||||
pN = Fraig_NodeAnd(pMan, Fraig_NodeAnd(pMan, pA, pC), pB);
|
||||
// assert ( Fraig_NodesEqual(pN, pNode) );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Try distributive transform
|
||||
pQ = Fraig_NodeReadOne(pNode);
|
||||
pR = Fraig_NodeReadTwo(pNode);
|
||||
if ( (Fraig_IsComplement(pQ) && Fraig_NodeIsAnd(pQ))
|
||||
&& (Fraig_IsComplement(pR) && Fraig_NodeIsAnd(pR)) )
|
||||
{
|
||||
pA = Fraig_NodeReadOne(Fraig_Regular(pQ));
|
||||
pB = Fraig_NodeReadTwo(Fraig_Regular(pQ));
|
||||
pC = Fraig_NodeReadOne(Fraig_Regular(pR));
|
||||
pD = Fraig_NodeReadTwo(Fraig_Regular(pR));
|
||||
|
||||
// Now detect the !(xy + xz) pattern, store
|
||||
// x in pA, y in pB and z in pC and set pD = 0 to indicate
|
||||
// pattern was found
|
||||
assert (pD != 0);
|
||||
if (pA == pC) { pC = pD; pD = 0; }
|
||||
if (pA == pD) { pD = 0; }
|
||||
if (pB == pC) { pB = pA; pA = pC; pC = pD; pD = 0; }
|
||||
if (pB == pD) { pB = pA; pA = pD; pD = 0; }
|
||||
if (pD == 0)
|
||||
{
|
||||
nDistributive++;
|
||||
pN = Fraig_Not(Fraig_NodeAnd(pMan, pA,
|
||||
Fraig_NodeOr(pMan, pB, pC)));
|
||||
if (fShortCut) Fraig_NodeAddChoice( pMan, pNode, pN );
|
||||
// assert ( Fraig_NodesEqual(pN, pNode) );
|
||||
}
|
||||
}
|
||||
*/
|
||||
if ( i % 1000 == 0 )
|
||||
{
|
||||
sprintf( Buffer, "Adding choice %6d...", i - nNodesBefore );
|
||||
// Extra_ProgressBarUpdate( pProgress, i, Buffer );
|
||||
}
|
||||
}
|
||||
|
||||
// Extra_ProgressBarStop( pProgress );
|
||||
|
||||
Fraig_ManCheckConsistency( pMan );
|
||||
|
||||
nNodesAfter = Fraig_ManReadNodeNum( pMan );
|
||||
printf ( "Nodes before = %6d. Nodes with associative choices = %6d. Increase = %4.2f %%.\n",
|
||||
nNodesBefore, nNodesAfter, ((float)(nNodesAfter - nNodesBefore)) * 100.0/(nNodesBefore - nInputs) );
|
||||
printf ( "Distributive = %d\n", nDistributive );
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -134,7 +134,7 @@ void Esop_CoverWriteFile( Esop_Cube_t * pCover, char * pName, int fEsop )
|
|||
if ( Buffer[i] == '<' || Buffer[i] == '>' )
|
||||
Buffer[i] = '_';
|
||||
pFile = fopen( Buffer, "w" );
|
||||
fprintf( pFile, "# %s cover for output %s generated by ABC on %s\n", fEsop? "ESOP":"SOP", pName, Extra_TimeStamp() );
|
||||
fprintf( pFile, "# %s cover for output %s generated by ABC\n", fEsop? "ESOP":"SOP", pName );
|
||||
fprintf( pFile, ".i %d\n", pCover? pCover->nVars : 0 );
|
||||
fprintf( pFile, ".o %d\n", 1 );
|
||||
fprintf( pFile, ".p %d\n", Esop_CoverCountCubes(pCover) );
|
||||
|
|
|
|||
|
|
@ -44,23 +44,17 @@ typedef struct Ivy_Man_t_ Ivy_Man_t;
|
|||
typedef struct Ivy_Obj_t_ Ivy_Obj_t;
|
||||
typedef int Ivy_Edge_t;
|
||||
|
||||
// constant edges
|
||||
#define IVY_CONST0 1
|
||||
#define IVY_CONST1 0
|
||||
|
||||
// object types
|
||||
typedef enum {
|
||||
IVY_NONE, // 0: unused node
|
||||
IVY_NONE, // 0: non-existant object
|
||||
IVY_PI, // 1: primary input (and constant 1 node)
|
||||
IVY_PO, // 2: primary output
|
||||
IVY_ASSERT, // 3: assertion
|
||||
IVY_LATCH, // 4: sequential element
|
||||
IVY_AND, // 5: internal AND node
|
||||
IVY_EXOR, // 6: internal EXOR node
|
||||
IVY_BUF, // 7: internal buffer (temporary)
|
||||
IVY_ANDM, // 8: multi-input AND (logic network only)
|
||||
IVY_EXORM, // 9: multi-input EXOR (logic network only)
|
||||
IVY_LUT // 10: multi-input LUT (logic network only)
|
||||
IVY_AND, // 5: AND node
|
||||
IVY_EXOR, // 6: EXOR node
|
||||
IVY_BUF, // 7: buffer (temporary)
|
||||
IVY_VOID // 8: unused object
|
||||
} Ivy_Type_t;
|
||||
|
||||
// latch initial values
|
||||
|
|
@ -72,56 +66,51 @@ typedef enum {
|
|||
} Ivy_Init_t;
|
||||
|
||||
// the AIG node
|
||||
struct Ivy_Obj_t_ // 6 words
|
||||
struct Ivy_Obj_t_ // 24 bytes (32-bit) or 32 bytes (64-bit)
|
||||
{
|
||||
int Id; // integer ID
|
||||
int TravId; // traversal ID
|
||||
int Fanin0; // fanin ID
|
||||
int Fanin1; // fanin ID
|
||||
int nRefs; // reference counter
|
||||
unsigned Type : 4; // object type
|
||||
unsigned fPhase : 1; // value under 000...0 pattern
|
||||
unsigned fMarkA : 1; // multipurpose mask
|
||||
unsigned fMarkB : 1; // multipurpose mask
|
||||
unsigned fExFan : 1; // set to 1 if last fanout added is EXOR
|
||||
unsigned fComp0 : 1; // complemented attribute
|
||||
unsigned fComp1 : 1; // complemented attribute
|
||||
unsigned Init : 2; // latch initial value
|
||||
unsigned LevelR : 8; // reverse logic level
|
||||
unsigned Level : 12; // logic level
|
||||
unsigned Level : 22; // logic level
|
||||
int nRefs; // reference counter
|
||||
Ivy_Obj_t * pFanin0; // fanin
|
||||
Ivy_Obj_t * pFanin1; // fanin
|
||||
};
|
||||
|
||||
// the AIG manager
|
||||
struct Ivy_Man_t_
|
||||
{
|
||||
// AIG nodes
|
||||
int nObjs[12]; // the number of objects by type
|
||||
Vec_Ptr_t * vPis; // the array of PIs
|
||||
Vec_Ptr_t * vPos; // the array of POs
|
||||
Vec_Ptr_t * vBufs; // the array of buffers
|
||||
Vec_Ptr_t * vObjs; // the array of objects
|
||||
Ivy_Obj_t * pConst1; // the constant 1 node
|
||||
Ivy_Obj_t Ghost; // the ghost node
|
||||
// AIG node counters
|
||||
int nObjs[IVY_VOID];// the number of objects by type
|
||||
int nCreated; // the number of created objects
|
||||
int nDeleted; // the number of deleted objects
|
||||
int ObjIdNext; // the next free obj ID to assign
|
||||
int nObjsAlloc; // the allocated number of nodes
|
||||
Ivy_Obj_t * pObjs; // the array of all nodes
|
||||
Vec_Int_t * vPis; // the array of PIs
|
||||
Vec_Int_t * vPos; // the array of POs
|
||||
// stuctural hash table
|
||||
int * pTable; // structural hash table
|
||||
int nTableSize; // structural hash table size
|
||||
// various data members
|
||||
int fCatchExor; // set to 1 to detect EXORs
|
||||
int fExtended; // set to 1 in extended mode
|
||||
int nTravIds; // the traversal ID
|
||||
int nLevelMax; // the maximum level
|
||||
void * pData; // the temporary data
|
||||
Vec_Int_t * vRequired; // required times
|
||||
// truth table of the 8-LUTs
|
||||
unsigned * pMemory; // memory for truth tables
|
||||
Vec_Int_t * vTruths; // offset for truth table of each node
|
||||
// storage for the undo operation
|
||||
Vec_Int_t * vFree; // storage for all deleted entries
|
||||
Ivy_Obj_t * pUndos; // description of recently deleted nodes
|
||||
int nUndos; // the number of recently deleted nodes
|
||||
int nUndosAlloc; // the number of allocated cells
|
||||
int fRecording; // shows that recording goes on
|
||||
Vec_Ptr_t * vFanouts; // representation of the fanouts
|
||||
void * pData; // the temporary data
|
||||
void * pCopy; // the temporary data
|
||||
// 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
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -141,7 +130,9 @@ typedef struct Ivy_Store_t_ Ivy_Store_t;
|
|||
struct Ivy_Store_t_
|
||||
{
|
||||
int nCuts;
|
||||
int nCutsM;
|
||||
int nCutsMax;
|
||||
int fSatur;
|
||||
Ivy_Cut_t pCuts[IVY_CUT_LIMIT]; // storage for cuts
|
||||
};
|
||||
|
||||
|
|
@ -149,35 +140,33 @@ struct Ivy_Store_t_
|
|||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define IVY_SANDBOX_SIZE 1
|
||||
|
||||
#define IVY_MIN(a,b) (((a) < (b))? (a) : (b))
|
||||
#define IVY_MAX(a,b) (((a) > (b))? (a) : (b))
|
||||
|
||||
static inline int Ivy_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
|
||||
static inline int Ivy_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
|
||||
static inline int Ivy_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; }
|
||||
static inline void Ivy_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); }
|
||||
static inline void Ivy_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); }
|
||||
static inline int Ivy_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
|
||||
static inline int Ivy_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
|
||||
static inline int Ivy_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; }
|
||||
static inline void Ivy_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); }
|
||||
static inline void Ivy_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); }
|
||||
|
||||
static inline Ivy_Obj_t * Ivy_Regular( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned)(p) & ~01); }
|
||||
static inline Ivy_Obj_t * Ivy_Not( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned)(p) ^ 01); }
|
||||
static inline Ivy_Obj_t * Ivy_NotCond( Ivy_Obj_t * p, int c ) { return (Ivy_Obj_t *)((unsigned)(p) ^ (c)); }
|
||||
static inline int Ivy_IsComplement( Ivy_Obj_t * p ) { return (int )(((unsigned)p) & 01); }
|
||||
static inline Ivy_Obj_t * Ivy_Regular( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned)(p) & ~01); }
|
||||
static inline Ivy_Obj_t * Ivy_Not( Ivy_Obj_t * p ) { return (Ivy_Obj_t *)((unsigned)(p) ^ 01); }
|
||||
static inline Ivy_Obj_t * Ivy_NotCond( Ivy_Obj_t * p, int c ) { return (Ivy_Obj_t *)((unsigned)(p) ^ (c)); }
|
||||
static inline int Ivy_IsComplement( Ivy_Obj_t * p ) { return (int )(((unsigned)p) & 01); }
|
||||
|
||||
static inline Ivy_Obj_t * Ivy_ManConst0( Ivy_Man_t * p ) { return Ivy_Not(p->pObjs); }
|
||||
static inline Ivy_Obj_t * Ivy_ManConst1( Ivy_Man_t * p ) { return p->pObjs; }
|
||||
static inline Ivy_Obj_t * Ivy_ManGhost( Ivy_Man_t * p ) { return p->pObjs - IVY_SANDBOX_SIZE; }
|
||||
static inline Ivy_Obj_t * Ivy_ManPi( Ivy_Man_t * p, int i ) { return p->pObjs + Vec_IntEntry(p->vPis,i); }
|
||||
static inline Ivy_Obj_t * Ivy_ManPo( Ivy_Man_t * p, int i ) { return p->pObjs + Vec_IntEntry(p->vPos,i); }
|
||||
static inline Ivy_Obj_t * Ivy_ManObj( Ivy_Man_t * p, int i ) { return p->pObjs + i; }
|
||||
static inline Ivy_Obj_t * Ivy_ManConst0( Ivy_Man_t * p ) { return Ivy_Not(p->pConst1); }
|
||||
static inline Ivy_Obj_t * Ivy_ManConst1( Ivy_Man_t * p ) { return p->pConst1; }
|
||||
static inline Ivy_Obj_t * Ivy_ManGhost( Ivy_Man_t * p ) { return &p->Ghost; }
|
||||
static inline Ivy_Obj_t * Ivy_ManPi( Ivy_Man_t * p, int i ) { return (Ivy_Obj_t *)Vec_PtrEntry(p->vPis, i); }
|
||||
static inline Ivy_Obj_t * Ivy_ManPo( Ivy_Man_t * p, int i ) { return (Ivy_Obj_t *)Vec_PtrEntry(p->vPos, i); }
|
||||
static inline Ivy_Obj_t * Ivy_ManObj( Ivy_Man_t * p, int i ) { return (Ivy_Obj_t *)Vec_PtrEntry(p->vObjs, i); }
|
||||
|
||||
static inline Ivy_Edge_t Ivy_EdgeCreate( int Id, int fCompl ) { return (Id << 1) | fCompl; }
|
||||
static inline int Ivy_EdgeId( Ivy_Edge_t Edge ) { return Edge >> 1; }
|
||||
static inline int Ivy_EdgeIsComplement( Ivy_Edge_t Edge ) { return Edge & 1; }
|
||||
static inline Ivy_Edge_t Ivy_EdgeRegular( Ivy_Edge_t Edge ) { return (Edge >> 1) << 1; }
|
||||
static inline Ivy_Edge_t Ivy_EdgeNot( Ivy_Edge_t Edge ) { return Edge ^ 1; }
|
||||
static inline Ivy_Edge_t Ivy_EdgeNotCond( Ivy_Edge_t Edge, int fCond ) { return Edge ^ fCond; }
|
||||
static inline Ivy_Edge_t Ivy_EdgeCreate( int Id, int fCompl ) { return (Id << 1) | fCompl; }
|
||||
static inline int Ivy_EdgeId( Ivy_Edge_t Edge ) { return Edge >> 1; }
|
||||
static inline int Ivy_EdgeIsComplement( Ivy_Edge_t Edge ) { return Edge & 1; }
|
||||
static inline Ivy_Edge_t Ivy_EdgeRegular( Ivy_Edge_t Edge ) { return (Edge >> 1) << 1; }
|
||||
static inline Ivy_Edge_t Ivy_EdgeNot( Ivy_Edge_t Edge ) { return Edge ^ 1; }
|
||||
static inline Ivy_Edge_t Ivy_EdgeNotCond( Ivy_Edge_t Edge, int fCond ) { return Edge ^ fCond; }
|
||||
static inline Ivy_Edge_t Ivy_EdgeFromNode( Ivy_Obj_t * pNode ) { return Ivy_EdgeCreate( Ivy_Regular(pNode)->Id, Ivy_IsComplement(pNode) ); }
|
||||
static inline Ivy_Obj_t * Ivy_EdgeToNode( Ivy_Man_t * p, Ivy_Edge_t Edge ){ return Ivy_NotCond( Ivy_ManObj(p, Ivy_EdgeId(Edge)), Ivy_EdgeIsComplement(Edge) ); }
|
||||
|
||||
|
|
@ -192,13 +181,9 @@ static inline int Ivy_ManLatchNum( Ivy_Man_t * p ) { return p->nO
|
|||
static inline int Ivy_ManAndNum( Ivy_Man_t * p ) { return p->nObjs[IVY_AND]; }
|
||||
static inline int Ivy_ManExorNum( Ivy_Man_t * p ) { return p->nObjs[IVY_EXOR]; }
|
||||
static inline int Ivy_ManBufNum( Ivy_Man_t * p ) { return p->nObjs[IVY_BUF]; }
|
||||
static inline int Ivy_ManAndMultiNum( Ivy_Man_t * p ) { return p->nObjs[IVY_ANDM]; }
|
||||
static inline int Ivy_ManExorMultiNum( Ivy_Man_t * p ) { return p->nObjs[IVY_EXORM]; }
|
||||
static inline int Ivy_ManLutNum( Ivy_Man_t * p ) { return p->nObjs[IVY_LUT]; }
|
||||
static inline int Ivy_ManObjNum( Ivy_Man_t * p ) { return p->nCreated - p->nDeleted; }
|
||||
static inline int Ivy_ManObjIdNext( Ivy_Man_t * p ) { return p->ObjIdNext; }
|
||||
static inline int Ivy_ManObjAllocNum( Ivy_Man_t * p ) { return p->nObjsAlloc; }
|
||||
static inline int Ivy_ManNodeNum( Ivy_Man_t * p ) { return p->fExtended? p->nObjs[IVY_ANDM]+p->nObjs[IVY_EXORM]+p->nObjs[IVY_LUT] : p->nObjs[IVY_AND]+p->nObjs[IVY_EXOR]; }
|
||||
static inline int Ivy_ManObjIdMax( Ivy_Man_t * p ) { return Vec_PtrSize(p->vObjs)-1; }
|
||||
static inline int Ivy_ManNodeNum( Ivy_Man_t * p ) { return p->nObjs[IVY_AND]+p->nObjs[IVY_EXOR];}
|
||||
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]; }
|
||||
|
||||
|
|
@ -221,27 +206,15 @@ static inline int Ivy_ObjIsTerm( Ivy_Obj_t * pObj ) { assert( !Ivy
|
|||
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_ObjIsAndMulti( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_ANDM; }
|
||||
static inline int Ivy_ObjIsExorMulti( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_EXORM; }
|
||||
static inline int Ivy_ObjIsLut( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_LUT; }
|
||||
static inline int Ivy_ObjIsNodeExt( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type >= IVY_ANDM; }
|
||||
|
||||
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_Man_t * Ivy_ObjMan( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return *((Ivy_Man_t **)(pObj - pObj->Id - IVY_SANDBOX_SIZE - 1)); }
|
||||
static inline Ivy_Obj_t * Ivy_ObjConst0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_Not(pObj - pObj->Id); }
|
||||
static inline Ivy_Obj_t * Ivy_ObjConst1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj - pObj->Id; }
|
||||
static inline Ivy_Obj_t * Ivy_ObjGhost( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj - pObj->Id - IVY_SANDBOX_SIZE; }
|
||||
static inline Ivy_Obj_t * Ivy_ObjObj( Ivy_Obj_t * pObj, int n ) { assert( !Ivy_IsComplement(pObj) ); return pObj - pObj->Id + n; }
|
||||
static inline Ivy_Obj_t * Ivy_ObjNext( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj - pObj->Id + pObj->TravId; }
|
||||
|
||||
static inline void Ivy_ObjSetTravId( Ivy_Obj_t * pObj, int TravId ) { assert( !Ivy_IsComplement(pObj) ); pObj->TravId = TravId; }
|
||||
static inline void Ivy_ObjSetTravIdCurrent( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->TravId = Ivy_ObjMan(pObj)->nTravIds; }
|
||||
static inline void Ivy_ObjSetTravIdPrevious( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); pObj->TravId = Ivy_ObjMan(pObj)->nTravIds - 1; }
|
||||
static inline int Ivy_ObjIsTravIdCurrent( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return (int )((int)pObj->TravId == Ivy_ObjMan(pObj)->nTravIds); }
|
||||
static inline int Ivy_ObjIsTravIdPrevious( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return (int )((int)pObj->TravId == Ivy_ObjMan(pObj)->nTravIds - 1); }
|
||||
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; }
|
||||
|
|
@ -249,69 +222,53 @@ static inline int Ivy_ObjExorFanout( Ivy_Obj_t * pObj ) { assert( !Ivy
|
|||
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->Fanin0; }
|
||||
static inline int Ivy_ObjFaninId1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Fanin1; }
|
||||
static inline int Ivy_ObjFaninC0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->fComp0; }
|
||||
static inline int Ivy_ObjFaninC1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->fComp1; }
|
||||
static inline Ivy_Obj_t * Ivy_ObjFanin0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_ObjObj(pObj, pObj->Fanin0); }
|
||||
static inline Ivy_Obj_t * Ivy_ObjFanin1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_ObjObj(pObj, pObj->Fanin1); }
|
||||
static inline Ivy_Obj_t * Ivy_ObjChild0( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_NotCond( Ivy_ObjFanin0(pObj), Ivy_ObjFaninC0(pObj) ); }
|
||||
static inline Ivy_Obj_t * Ivy_ObjChild1( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return Ivy_NotCond( Ivy_ObjFanin1(pObj), Ivy_ObjFaninC1(pObj) ); }
|
||||
static inline int Ivy_ObjLevelR( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->LevelR; }
|
||||
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_ObjClean( Ivy_Obj_t * pObj ) {
|
||||
static inline void Ivy_ObjClean( Ivy_Obj_t * pObj )
|
||||
{
|
||||
int IdSaved = pObj->Id;
|
||||
memset( pObj, 0, sizeof(Ivy_Obj_t) );
|
||||
pObj->Id = IdSaved;
|
||||
}
|
||||
static inline void Ivy_ObjOverwrite( Ivy_Obj_t * pBase, Ivy_Obj_t * pData ) { int IdSaved = pBase->Id; memcpy( pBase, pData, sizeof(Ivy_Obj_t) ); pBase->Id = IdSaved; }
|
||||
static inline void Ivy_ObjOverwrite( Ivy_Obj_t * pBase, Ivy_Obj_t * pData )
|
||||
{
|
||||
int IdSaved = pBase->Id;
|
||||
memcpy( pBase, pData, sizeof(Ivy_Obj_t) );
|
||||
pBase->Id = IdSaved;
|
||||
}
|
||||
static inline int Ivy_ObjWhatFanin( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanin )
|
||||
{
|
||||
if ( Ivy_ObjFaninId0(pObj) == Ivy_ObjId(pFanin) ) return 0;
|
||||
if ( Ivy_ObjFaninId1(pObj) == Ivy_ObjId(pFanin) ) return 1;
|
||||
if ( Ivy_ObjFanin0(pObj) == pFanin ) return 0;
|
||||
if ( Ivy_ObjFanin1(pObj) == pFanin ) return 1;
|
||||
assert(0); return -1;
|
||||
}
|
||||
static inline int Ivy_ObjFanoutC( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout )
|
||||
{
|
||||
if ( Ivy_ObjFaninId0(pFanout) == Ivy_ObjId(pObj) ) return Ivy_ObjFaninC0(pObj);
|
||||
if ( Ivy_ObjFaninId1(pFanout) == Ivy_ObjId(pObj) ) return Ivy_ObjFaninC1(pObj);
|
||||
if ( Ivy_ObjFanin0(pFanout) == pObj ) return Ivy_ObjFaninC0(pObj);
|
||||
if ( Ivy_ObjFanin1(pFanout) == pObj ) return Ivy_ObjFaninC1(pObj);
|
||||
assert(0); return -1;
|
||||
}
|
||||
|
||||
// create the ghost of the new node
|
||||
static inline Ivy_Obj_t * Ivy_ObjCreateGhost( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type, Ivy_Init_t Init )
|
||||
static inline Ivy_Obj_t * Ivy_ObjCreateGhost( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type, Ivy_Init_t Init )
|
||||
{
|
||||
Ivy_Obj_t * pGhost;
|
||||
int Temp;
|
||||
pGhost = Ivy_ObjGhost(Ivy_Regular(p0));
|
||||
Ivy_Obj_t * pGhost, * pTemp;
|
||||
pGhost = Ivy_ManGhost(p);
|
||||
pGhost->Type = Type;
|
||||
pGhost->Init = Init;
|
||||
pGhost->fComp0 = Ivy_IsComplement(p0);
|
||||
pGhost->fComp1 = Ivy_IsComplement(p1);
|
||||
pGhost->Fanin0 = Ivy_ObjId(Ivy_Regular(p0));
|
||||
pGhost->Fanin1 = Ivy_ObjId(Ivy_Regular(p1));
|
||||
if ( pGhost->Fanin0 < pGhost->Fanin1 )
|
||||
{
|
||||
Temp = pGhost->Fanin0, pGhost->Fanin0 = pGhost->Fanin1, pGhost->Fanin1 = Temp;
|
||||
Temp = pGhost->fComp0, pGhost->fComp0 = pGhost->fComp1, pGhost->fComp1 = Temp;
|
||||
}
|
||||
assert( Ivy_ObjIsOneFanin(pGhost) || pGhost->Fanin0 > pGhost->Fanin1 );
|
||||
return pGhost;
|
||||
}
|
||||
|
||||
// create the ghost of the new node
|
||||
static inline Ivy_Obj_t * Ivy_ObjCreateGhost2( Ivy_Man_t * p, Ivy_Obj_t * pObjDead )
|
||||
{
|
||||
Ivy_Obj_t * pGhost;
|
||||
pGhost = Ivy_ManGhost(p);
|
||||
pGhost->Type = pObjDead->Type;
|
||||
pGhost->Init = pObjDead->Init;
|
||||
pGhost->fComp0 = pObjDead->fComp0;
|
||||
pGhost->fComp1 = pObjDead->fComp1;
|
||||
pGhost->Fanin0 = pObjDead->Fanin0;
|
||||
pGhost->Fanin1 = pObjDead->Fanin1;
|
||||
assert( Ivy_ObjIsOneFanin(pGhost) || pGhost->Fanin0 > pGhost->Fanin1 );
|
||||
pGhost->pFanin0 = p0;
|
||||
pGhost->pFanin1 = p1;
|
||||
assert( Type == IVY_PI || Ivy_ObjFanin0(pGhost) != Ivy_ObjFanin1(pGhost) );
|
||||
if ( p1 && Ivy_ObjFaninId0(pGhost) > Ivy_ObjFaninId1(pGhost) )
|
||||
pTemp = pGhost->pFanin0, pGhost->pFanin0 = pGhost->pFanin1, pGhost->pFanin1 = pTemp;
|
||||
return pGhost;
|
||||
}
|
||||
|
||||
|
|
@ -352,48 +309,58 @@ static Ivy_Init_t Ivy_InitExor( Ivy_Init_t InitA, Ivy_Init_t InitB )
|
|||
return IVY_INIT_0;
|
||||
}
|
||||
|
||||
// extended fanins
|
||||
static inline Vec_Int_t * Ivy_ObjGetFanins( Ivy_Obj_t * pObj ) { assert(Ivy_ObjMan(pObj)->fExtended); return (Vec_Int_t *)*(((int*)pObj)+2); }
|
||||
static inline void Ivy_ObjSetFanins( Ivy_Obj_t * pObj, Vec_Int_t * vFanins ) { assert(Ivy_ObjMan(pObj)->fExtended); assert(Ivy_ObjGetFanins(pObj)==NULL); *(Vec_Int_t **)(((int*)pObj)+2) = vFanins; }
|
||||
static inline void Ivy_ObjStartFanins( Ivy_Obj_t * pObj, int nFanins ) { assert(Ivy_ObjMan(pObj)->fExtended); Ivy_ObjSetFanins( pObj, Vec_IntAlloc(nFanins) ); }
|
||||
static inline void Ivy_ObjAddFanin( Ivy_Obj_t * pObj, int Fanin ) { assert(Ivy_ObjMan(pObj)->fExtended); Vec_IntPush( Ivy_ObjGetFanins(pObj), Fanin ); }
|
||||
static inline int Ivy_ObjReadFanin( Ivy_Obj_t * pObj, int i ) { assert(Ivy_ObjMan(pObj)->fExtended); return Vec_IntEntry( Ivy_ObjGetFanins(pObj), i ); }
|
||||
static inline int Ivy_ObjFaninNum( Ivy_Obj_t * pObj ) { assert(Ivy_ObjMan(pObj)->fExtended); return Vec_IntSize( Ivy_ObjGetFanins(pObj) ); }
|
||||
// internal memory manager
|
||||
static inline Ivy_Obj_t * Ivy_ManFetchMemory( Ivy_Man_t * p )
|
||||
{
|
||||
extern void Ivy_ManAddMemory( Ivy_Man_t * p );
|
||||
Ivy_Obj_t * pTemp;
|
||||
if ( p->pListFree == NULL )
|
||||
Ivy_ManAddMemory( p );
|
||||
pTemp = p->pListFree;
|
||||
p->pListFree = *((Ivy_Obj_t **)pTemp);
|
||||
memset( pTemp, 0, sizeof(Ivy_Obj_t) );
|
||||
return pTemp;
|
||||
}
|
||||
static inline void Ivy_ManRecycleMemory( Ivy_Man_t * p, Ivy_Obj_t * pEntry )
|
||||
{
|
||||
pEntry->Type = IVY_NONE; // distinquishes dead node from live node
|
||||
*((Ivy_Obj_t **)pEntry) = p->pListFree;
|
||||
p->pListFree = pEntry;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// ITERATORS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// iterator over all objects, including those currently not used
|
||||
#define Ivy_ManForEachObj( p, pObj, i ) \
|
||||
for ( i = 0, pObj = p->pObjs; i < p->ObjIdNext; i++, pObj++ )
|
||||
#define Ivy_ManForEachObjReverse( p, pObj, i ) \
|
||||
for ( i = p->ObjIdNext - 1, pObj = p->pObjs + i; i >= 0; i--, pObj-- )
|
||||
// iterator over the primary inputs
|
||||
#define Ivy_ManForEachPi( p, pObj, i ) \
|
||||
for ( i = 0; i < Vec_IntSize(p->vPis) && ((pObj) = Ivy_ManPi(p, i)); i++ )
|
||||
#define Ivy_ManForEachPi( p, pObj, i ) \
|
||||
Vec_PtrForEachEntry( p->vPis, pObj, i )
|
||||
// iterator over the primary outputs
|
||||
#define Ivy_ManForEachPo( p, pObj, i ) \
|
||||
for ( i = 0; i < Vec_IntSize(p->vPos) && ((pObj) = Ivy_ManPo(p, i)); i++ )
|
||||
#define Ivy_ManForEachPo( p, pObj, i ) \
|
||||
Vec_PtrForEachEntry( p->vPos, pObj, i )
|
||||
// iterator over all objects, including those currently not used
|
||||
#define Ivy_ManForEachObj( p, pObj, i ) \
|
||||
Vec_PtrForEachEntry( p->vObjs, pObj, i ) if ( (pObj) == NULL ) {} else
|
||||
// iterator over the combinational inputs
|
||||
#define Ivy_ManForEachCi( p, pObj, i ) \
|
||||
for ( i = 0, pObj = p->pObjs; i < p->ObjIdNext; i++, pObj++ ) \
|
||||
if ( !Ivy_ObjIsCi(pObj) ) {} else
|
||||
#define Ivy_ManForEachCi( p, pObj, i ) \
|
||||
Ivy_ManForEachObj( p, pObj, i ) if ( !Ivy_ObjIsCi(pObj) ) {} else
|
||||
// iterator over the combinational outputs
|
||||
#define Ivy_ManForEachCo( p, pObj, i ) \
|
||||
for ( i = 0, pObj = p->pObjs; i < p->ObjIdNext; i++, pObj++ ) \
|
||||
if ( !Ivy_ObjIsCo(pObj) ) {} else
|
||||
#define Ivy_ManForEachCo( p, pObj, i ) \
|
||||
Ivy_ManForEachObj( p, pObj, i ) if ( !Ivy_ObjIsCo(pObj) ) {} else
|
||||
// iterator over logic nodes (AND and EXOR gates)
|
||||
#define Ivy_ManForEachNode( p, pObj, i ) \
|
||||
for ( i = 1, pObj = p->pObjs+i; i < p->ObjIdNext; i++, pObj++ ) \
|
||||
if ( !Ivy_ObjIsNode(pObj) ) {} else
|
||||
#define Ivy_ManForEachNode( p, pObj, i ) \
|
||||
Ivy_ManForEachObj( p, pObj, i ) if ( !Ivy_ObjIsNode(pObj) ) {} else
|
||||
// iterator over logic latches
|
||||
#define Ivy_ManForEachLatch( p, pObj, i ) \
|
||||
for ( i = 1, pObj = p->pObjs+i; i < p->ObjIdNext; i++, pObj++ ) \
|
||||
if ( !Ivy_ObjIsLatch(pObj) ) {} else
|
||||
#define Ivy_ManForEachLatch( p, pObj, i ) \
|
||||
Ivy_ManForEachObj( p, pObj, i ) if ( !Ivy_ObjIsLatch(pObj) ) {} else
|
||||
// iterator over the nodes whose IDs are stored in the array
|
||||
#define Ivy_ManForEachNodeVec( p, vIds, pObj, i ) \
|
||||
#define Ivy_ManForEachNodeVec( p, vIds, pObj, i ) \
|
||||
for ( i = 0; i < Vec_IntSize(vIds) && ((pObj) = Ivy_ManObj(p, Vec_IntEntry(vIds,i))); i++ )
|
||||
// iterator over the fanouts of an object
|
||||
#define Ivy_ObjForEachFanout( p, pObj, vArray, pFanout, i ) \
|
||||
for ( i = 0, Ivy_ObjCollectFanouts(p, pObj, vArray); \
|
||||
i < Vec_PtrSize(vArray) && ((pFanout) = Vec_PtrEntry(vArray,i)); i++ )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
|
|
@ -401,19 +368,19 @@ static inline int Ivy_ObjFaninNum( Ivy_Obj_t * pObj )
|
|||
|
||||
/*=== ivyBalance.c ========================================================*/
|
||||
extern Ivy_Man_t * Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel );
|
||||
extern Ivy_Obj_t * Ivy_NodeBalanceBuildSuper( Vec_Ptr_t * vSuper, Ivy_Type_t Type, int fUpdateLevel );
|
||||
extern Ivy_Obj_t * Ivy_NodeBalanceBuildSuper( Ivy_Man_t * p, Vec_Ptr_t * vSuper, Ivy_Type_t Type, int fUpdateLevel );
|
||||
/*=== ivyCanon.c ========================================================*/
|
||||
extern Ivy_Obj_t * Ivy_CanonAnd( Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
|
||||
extern Ivy_Obj_t * Ivy_CanonExor( Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
|
||||
extern Ivy_Obj_t * Ivy_CanonLatch( Ivy_Obj_t * pObj, Ivy_Init_t Init );
|
||||
extern Ivy_Obj_t * Ivy_CanonAnd( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
|
||||
extern Ivy_Obj_t * Ivy_CanonExor( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
|
||||
extern Ivy_Obj_t * Ivy_CanonLatch( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Init_t Init );
|
||||
/*=== ivyCheck.c ========================================================*/
|
||||
extern int Ivy_ManCheck( Ivy_Man_t * p );
|
||||
/*=== ivyCut.c ==========================================================*/
|
||||
extern void Ivy_ManSeqFindCut( Ivy_Obj_t * pNode, Vec_Int_t * vFront, Vec_Int_t * vInside, int nSize );
|
||||
extern Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Obj_t * pObj, int nLeaves );
|
||||
extern void Ivy_ManSeqFindCut( Ivy_Man_t * p, Ivy_Obj_t * pNode, Vec_Int_t * vFront, Vec_Int_t * vInside, int nSize );
|
||||
extern Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves );
|
||||
/*=== ivyDfs.c ==========================================================*/
|
||||
extern Vec_Int_t * Ivy_ManDfs( Ivy_Man_t * p );
|
||||
extern Vec_Int_t * Ivy_ManDfsExt( Ivy_Man_t * p );
|
||||
extern Vec_Int_t * Ivy_ManDfsSeq( Ivy_Man_t * p, Vec_Int_t ** pvLatches );
|
||||
extern void Ivy_ManCollectCone( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone );
|
||||
extern Vec_Vec_t * Ivy_ManLevelize( Ivy_Man_t * p );
|
||||
extern Vec_Int_t * Ivy_ManRequiredLevels( Ivy_Man_t * p );
|
||||
|
|
@ -423,61 +390,76 @@ extern void Ivy_TruthDsdPrint( FILE * pFile, Vec_Int_t * vTree );
|
|||
extern unsigned Ivy_TruthDsdCompute( Vec_Int_t * vTree );
|
||||
extern void Ivy_TruthDsdComputePrint( unsigned uTruth );
|
||||
extern Ivy_Obj_t * Ivy_ManDsdConstruct( Ivy_Man_t * p, Vec_Int_t * vFront, Vec_Int_t * vTree );
|
||||
/*=== ivyFanout.c ==========================================================*/
|
||||
extern void Ivy_ManStartFanout( Ivy_Man_t * p );
|
||||
extern void Ivy_ManStopFanout( Ivy_Man_t * p );
|
||||
extern void Ivy_ObjAddFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout );
|
||||
extern void Ivy_ObjDeleteFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout );
|
||||
extern void Ivy_ObjPatchFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFanoutOld, Ivy_Obj_t * pFanoutNew );
|
||||
extern void Ivy_ObjCollectFanouts( Ivy_Man_t * p, Ivy_Obj_t * pObj, Vec_Ptr_t * vArray );
|
||||
extern Ivy_Obj_t * Ivy_ObjReadOneFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
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 );
|
||||
/*=== ivyMan.c ==========================================================*/
|
||||
extern Ivy_Man_t * Ivy_ManStart( int nPis, int nPos, int nNodesMax );
|
||||
extern Ivy_Man_t * Ivy_ManStart();
|
||||
extern void Ivy_ManStop( Ivy_Man_t * p );
|
||||
extern void Ivy_ManGrow( Ivy_Man_t * p );
|
||||
extern int Ivy_ManCleanup( Ivy_Man_t * p );
|
||||
extern int Ivy_ManPropagateBuffers( Ivy_Man_t * p );
|
||||
extern void Ivy_ManPrintStats( Ivy_Man_t * p );
|
||||
extern void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits );
|
||||
/*=== ivyMem.c ==========================================================*/
|
||||
extern void Ivy_ManStartMemory( Ivy_Man_t * p );
|
||||
extern void Ivy_ManStopMemory( Ivy_Man_t * p );
|
||||
/*=== ivyMulti.c ==========================================================*/
|
||||
extern Ivy_Obj_t * Ivy_Multi( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
|
||||
extern Ivy_Obj_t * Ivy_Multi1( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
|
||||
extern Ivy_Obj_t * Ivy_Multi_rec( Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type );
|
||||
extern Ivy_Obj_t * Ivy_MultiBalance_rec( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
|
||||
extern int Ivy_MultiPlus( Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Type_t Type, int nLimit, Vec_Ptr_t * vSol );
|
||||
extern Ivy_Obj_t * Ivy_Multi( Ivy_Man_t * p, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
|
||||
extern Ivy_Obj_t * Ivy_Multi1( Ivy_Man_t * p, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
|
||||
extern Ivy_Obj_t * Ivy_Multi_rec( Ivy_Man_t * p, Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type );
|
||||
extern Ivy_Obj_t * Ivy_MultiBalance_rec( Ivy_Man_t * p, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );
|
||||
extern int Ivy_MultiPlus( Ivy_Man_t * p, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Type_t Type, int nLimit, Vec_Ptr_t * vSol );
|
||||
/*=== ivyObj.c ==========================================================*/
|
||||
extern Ivy_Obj_t * Ivy_ObjCreate( Ivy_Obj_t * pGhost );
|
||||
extern Ivy_Obj_t * Ivy_ObjCreateExt( Ivy_Man_t * p, Ivy_Type_t Type );
|
||||
extern void Ivy_ObjConnect( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanin );
|
||||
extern void Ivy_ObjDelete( Ivy_Obj_t * pObj, int fFreeTop );
|
||||
extern void Ivy_ObjDelete_rec( Ivy_Obj_t * pObj, int fFreeTop );
|
||||
extern void Ivy_ObjReplace( Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop );
|
||||
extern void Ivy_NodeFixBufferFanins( Ivy_Obj_t * pNode );
|
||||
extern Ivy_Obj_t * Ivy_ObjCreatePi( Ivy_Man_t * p );
|
||||
extern Ivy_Obj_t * Ivy_ObjCreatePo( Ivy_Man_t * p, Ivy_Obj_t * pDriver );
|
||||
extern Ivy_Obj_t * Ivy_ObjCreate( Ivy_Man_t * p, Ivy_Obj_t * pGhost );
|
||||
extern void Ivy_ObjConnect( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFan0, Ivy_Obj_t * pFan1 );
|
||||
extern void Ivy_ObjDisconnect( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
extern void Ivy_ObjPatchFanin0( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFaninNew );
|
||||
extern void Ivy_ObjDelete( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop );
|
||||
extern void Ivy_ObjDelete_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop );
|
||||
extern void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop );
|
||||
extern void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode );
|
||||
/*=== ivyOper.c =========================================================*/
|
||||
extern Ivy_Obj_t * Ivy_Oper( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type );
|
||||
extern Ivy_Obj_t * Ivy_And( Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
|
||||
extern Ivy_Obj_t * Ivy_Or( Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
|
||||
extern Ivy_Obj_t * Ivy_Exor( Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
|
||||
extern Ivy_Obj_t * Ivy_Mux( Ivy_Obj_t * pC, Ivy_Obj_t * p1, Ivy_Obj_t * p0 );
|
||||
extern Ivy_Obj_t * Ivy_Maj( Ivy_Obj_t * pA, Ivy_Obj_t * pB, Ivy_Obj_t * pC );
|
||||
extern Ivy_Obj_t * Ivy_Miter( Vec_Ptr_t * vPairs );
|
||||
extern Ivy_Obj_t * Ivy_Oper( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type );
|
||||
extern Ivy_Obj_t * Ivy_And( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
|
||||
extern Ivy_Obj_t * Ivy_Or( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
|
||||
extern Ivy_Obj_t * Ivy_Exor( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 );
|
||||
extern Ivy_Obj_t * Ivy_Mux( Ivy_Man_t * p, Ivy_Obj_t * pC, Ivy_Obj_t * p1, Ivy_Obj_t * p0 );
|
||||
extern Ivy_Obj_t * Ivy_Maj( Ivy_Man_t * p, Ivy_Obj_t * pA, Ivy_Obj_t * pB, Ivy_Obj_t * pC );
|
||||
extern Ivy_Obj_t * Ivy_Miter( Ivy_Man_t * p, Vec_Ptr_t * vPairs );
|
||||
extern Ivy_Obj_t * Ivy_Latch( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Init_t Init );
|
||||
/*=== ivyResyn.c =========================================================*/
|
||||
extern Ivy_Man_t * Ivy_ManResyn( Ivy_Man_t * p, int fUpdateLevel );
|
||||
extern Ivy_Man_t * Ivy_ManResyn( Ivy_Man_t * p, int fUpdateLevel, int fVerbose );
|
||||
/*=== ivyRewrite.c =========================================================*/
|
||||
extern int Ivy_ManSeqRewrite( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost );
|
||||
extern int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost );
|
||||
extern int Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fVerbose );
|
||||
/*=== ivyTable.c ========================================================*/
|
||||
extern Ivy_Obj_t * Ivy_TableLookup( Ivy_Obj_t * pObj );
|
||||
extern void Ivy_TableInsert( Ivy_Obj_t * pObj );
|
||||
extern void Ivy_TableDelete( Ivy_Obj_t * pObj );
|
||||
extern void Ivy_TableUpdate( Ivy_Obj_t * pObj, int ObjIdNew );
|
||||
extern Ivy_Obj_t * Ivy_TableLookup( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
extern void Ivy_TableInsert( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
extern void Ivy_TableDelete( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
extern void Ivy_TableUpdate( Ivy_Man_t * p, Ivy_Obj_t * pObj, int ObjIdNew );
|
||||
extern int Ivy_TableCountEntries( Ivy_Man_t * p );
|
||||
extern void Ivy_TableResize( Ivy_Man_t * p );
|
||||
/*=== ivyUndo.c =========================================================*/
|
||||
extern void Ivy_ManUndoStart( Ivy_Man_t * p );
|
||||
extern void Ivy_ManUndoStop( Ivy_Man_t * p );
|
||||
extern void Ivy_ManUndoRecord( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
extern void Ivy_ManUndoPerform( Ivy_Man_t * p, Ivy_Obj_t * pRoot );
|
||||
extern void Ivy_TableProfile( Ivy_Man_t * p );
|
||||
/*=== ivyUtil.c =========================================================*/
|
||||
extern void Ivy_ManIncrementTravId( Ivy_Man_t * p );
|
||||
extern void Ivy_ManCleanTravId( Ivy_Man_t * p );
|
||||
extern unsigned * Ivy_ManCutTruth( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes, Vec_Int_t * vTruth );
|
||||
extern Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p );
|
||||
extern int Ivy_ManLevels( Ivy_Man_t * p );
|
||||
extern void Ivy_ManResetLevels( Ivy_Man_t * p );
|
||||
extern void Ivy_ObjUpdateLevel_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
extern void Ivy_ObjUpdateLevelR_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int ReqNew );
|
||||
extern int Ivy_ObjIsMuxType( Ivy_Obj_t * pObj );
|
||||
extern Ivy_Obj_t * Ivy_ObjRecognizeMux( Ivy_Obj_t * pObj, Ivy_Obj_t ** ppObjT, Ivy_Obj_t ** ppObjE );
|
||||
extern unsigned * Ivy_ManCutTruth( Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes, Vec_Int_t * vTruth );
|
||||
extern Ivy_Obj_t * Ivy_NodeRealFanin_rec( Ivy_Obj_t * pNode, int iFanin );
|
||||
extern Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p );
|
||||
extern int Ivy_ManReadLevels( Ivy_Man_t * p );
|
||||
extern Ivy_Obj_t * Ivy_ObjReal( Ivy_Obj_t * pObj );
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
static int Ivy_NodeBalance_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObj, Vec_Vec_t * vStore, int Level, int fUpdateLevel );
|
||||
static Vec_Ptr_t * Ivy_NodeBalanceCone( Ivy_Obj_t * pObj, Vec_Vec_t * vStore, int Level );
|
||||
static int Ivy_NodeBalanceFindLeft( Vec_Ptr_t * vSuper );
|
||||
static void Ivy_NodeBalancePermute( Vec_Ptr_t * vSuper, int LeftBound, int fExor );
|
||||
static void Ivy_NodeBalancePermute( Ivy_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor );
|
||||
static void Ivy_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Ivy_Obj_t * pObj );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -54,11 +54,11 @@ Ivy_Man_t * Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel )
|
|||
// clean the old manager
|
||||
Ivy_ManCleanTravId( p );
|
||||
// create the new manager
|
||||
pNew = Ivy_ManStart( Ivy_ManPiNum(p), Ivy_ManPoNum(p), Ivy_ManNodeNum(p) + 20000 );
|
||||
pNew = Ivy_ManStart();
|
||||
// map the nodes
|
||||
Ivy_ManConst1(p)->TravId = Ivy_EdgeFromNode( Ivy_ManConst1(pNew) );
|
||||
Ivy_ManForEachPi( p, pObj, i )
|
||||
pObj->TravId = Ivy_EdgeFromNode( Ivy_ManPi(pNew, i) );
|
||||
pObj->TravId = Ivy_EdgeFromNode( Ivy_ObjCreatePi(pNew) );
|
||||
// balance the AIG
|
||||
vStore = Vec_VecAlloc( 50 );
|
||||
Ivy_ManForEachPo( p, pObj, i )
|
||||
|
|
@ -66,7 +66,7 @@ Ivy_Man_t * Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel )
|
|||
pDriver = Ivy_ObjReal( Ivy_ObjChild0(pObj) );
|
||||
NewNodeId = Ivy_NodeBalance_rec( pNew, Ivy_Regular(pDriver), vStore, 0, fUpdateLevel );
|
||||
NewNodeId = Ivy_EdgeNotCond( NewNodeId, Ivy_IsComplement(pDriver) );
|
||||
Ivy_ObjConnect( Ivy_ManPo(pNew, i), Ivy_EdgeToNode(pNew, NewNodeId) );
|
||||
Ivy_ObjCreatePo( pNew, Ivy_EdgeToNode(pNew, NewNodeId) );
|
||||
}
|
||||
Vec_VecFree( vStore );
|
||||
if ( i = Ivy_ManCleanup( pNew ) )
|
||||
|
|
@ -139,11 +139,12 @@ int Ivy_NodeBalance_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld, Vec_Vec_t * vSto
|
|||
vSuper->pArray[i] = Ivy_EdgeToNode( pNew, NewNodeId );
|
||||
}
|
||||
// build the supergate
|
||||
pObjNew = Ivy_NodeBalanceBuildSuper( vSuper, Ivy_ObjType(pObjOld), fUpdateLevel );
|
||||
pObjNew = Ivy_NodeBalanceBuildSuper( pNew, vSuper, Ivy_ObjType(pObjOld), fUpdateLevel );
|
||||
vSuper->nSize = 0;
|
||||
// make sure the balanced node is not assigned
|
||||
assert( pObjOld->TravId == 0 );
|
||||
pObjOld->TravId = Ivy_EdgeFromNode( pObjNew );
|
||||
// assert( pObjOld->Level >= Ivy_Regular(pObjNew)->Level );
|
||||
return pObjOld->TravId;
|
||||
}
|
||||
|
||||
|
|
@ -158,7 +159,7 @@ int Ivy_NodeBalance_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld, Vec_Vec_t * vSto
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_NodeBalanceBuildSuper( Vec_Ptr_t * vSuper, Ivy_Type_t Type, int fUpdateLevel )
|
||||
Ivy_Obj_t * Ivy_NodeBalanceBuildSuper( Ivy_Man_t * p, Vec_Ptr_t * vSuper, Ivy_Type_t Type, int fUpdateLevel )
|
||||
{
|
||||
Ivy_Obj_t * pObj1, * pObj2;
|
||||
int LeftBound;
|
||||
|
|
@ -171,11 +172,11 @@ Ivy_Obj_t * Ivy_NodeBalanceBuildSuper( Vec_Ptr_t * vSuper, Ivy_Type_t Type, int
|
|||
// find the left bound on the node to be paired
|
||||
LeftBound = (!fUpdateLevel)? 0 : Ivy_NodeBalanceFindLeft( vSuper );
|
||||
// find the node that can be shared (if no such node, randomize choice)
|
||||
Ivy_NodeBalancePermute( vSuper, LeftBound, Type == IVY_EXOR );
|
||||
Ivy_NodeBalancePermute( p, vSuper, LeftBound, Type == IVY_EXOR );
|
||||
// pull out the last two nodes
|
||||
pObj1 = Vec_PtrPop(vSuper);
|
||||
pObj2 = Vec_PtrPop(vSuper);
|
||||
Ivy_NodeBalancePushUniqueOrderByLevel( vSuper, Ivy_Oper(pObj1, pObj2, Type) );
|
||||
Ivy_NodeBalancePushUniqueOrderByLevel( vSuper, Ivy_Oper(p, pObj1, pObj2, Type) );
|
||||
}
|
||||
return Vec_PtrEntry(vSuper, 0);
|
||||
}
|
||||
|
|
@ -314,7 +315,7 @@ int Ivy_NodeBalanceFindLeft( Vec_Ptr_t * vSuper )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_NodeBalancePermute( Vec_Ptr_t * vSuper, int LeftBound, int fExor )
|
||||
void Ivy_NodeBalancePermute( Ivy_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor )
|
||||
{
|
||||
Ivy_Obj_t * pObj1, * pObj2, * pObj3, * pGhost;
|
||||
int RightBound, i;
|
||||
|
|
@ -330,8 +331,8 @@ void Ivy_NodeBalancePermute( Vec_Ptr_t * vSuper, int LeftBound, int fExor )
|
|||
for ( i = RightBound; i >= LeftBound; i-- )
|
||||
{
|
||||
pObj3 = Vec_PtrEntry( vSuper, i );
|
||||
pGhost = Ivy_ObjCreateGhost( pObj1, pObj3, fExor? IVY_EXOR : IVY_AND, IVY_INIT_NONE );
|
||||
if ( Ivy_TableLookup( pGhost ) )
|
||||
pGhost = Ivy_ObjCreateGhost( p, pObj1, pObj3, fExor? IVY_EXOR : IVY_AND, IVY_INIT_NONE );
|
||||
if ( Ivy_TableLookup( p, pGhost ) )
|
||||
{
|
||||
if ( pObj3 == pObj2 )
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Ivy_Obj_t * Ivy_TableLookupPair_rec( Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1, int fCompl0, int fCompl1, Ivy_Type_t Type );
|
||||
static Ivy_Obj_t * Ivy_TableLookupPair_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1, int fCompl0, int fCompl1, Ivy_Type_t Type );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -41,7 +41,7 @@ static Ivy_Obj_t * Ivy_TableLookupPair_rec( Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_CanonPair_rec( Ivy_Obj_t * pGhost )
|
||||
Ivy_Obj_t * Ivy_CanonPair_rec( Ivy_Man_t * p, Ivy_Obj_t * pGhost )
|
||||
{
|
||||
Ivy_Obj_t * pResult, * pLat0, * pLat1;
|
||||
Ivy_Init_t Init, Init0, Init1;
|
||||
|
|
@ -53,9 +53,9 @@ Ivy_Obj_t * Ivy_CanonPair_rec( Ivy_Obj_t * pGhost )
|
|||
// consider the case when the pair is canonical
|
||||
if ( !Ivy_ObjIsLatch(Ivy_ObjFanin0(pGhost)) || !Ivy_ObjIsLatch(Ivy_ObjFanin1(pGhost)) )
|
||||
{
|
||||
if ( pResult = Ivy_TableLookup( pGhost ) )
|
||||
if ( pResult = Ivy_TableLookup( p, pGhost ) )
|
||||
return pResult;
|
||||
return Ivy_ObjCreate( pGhost );
|
||||
return Ivy_ObjCreate( p, pGhost );
|
||||
}
|
||||
/// remember the latches
|
||||
pLat0 = Ivy_ObjFanin0(pGhost);
|
||||
|
|
@ -64,16 +64,13 @@ Ivy_Obj_t * Ivy_CanonPair_rec( Ivy_Obj_t * pGhost )
|
|||
Type = Ivy_ObjType(pGhost);
|
||||
fCompl0 = Ivy_ObjFaninC0(pGhost);
|
||||
fCompl1 = Ivy_ObjFaninC1(pGhost);
|
||||
// modify the fanins to be latch fanins
|
||||
pGhost->Fanin0 = Ivy_ObjFaninId0(pLat0);
|
||||
pGhost->Fanin1 = Ivy_ObjFaninId0(pLat1);
|
||||
// call recursively
|
||||
pResult = Ivy_CanonPair_rec( pGhost );
|
||||
pResult = Ivy_Oper( p, Ivy_NotCond(Ivy_ObjFanin0(pLat0), fCompl0), Ivy_NotCond(Ivy_ObjFanin0(pLat1), fCompl1), Type );
|
||||
// build latch on top of this
|
||||
Init0 = Ivy_InitNotCond( Ivy_ObjInit(pLat0), fCompl0 );
|
||||
Init1 = Ivy_InitNotCond( Ivy_ObjInit(pLat1), fCompl1 );
|
||||
Init = (Type == IVY_AND)? Ivy_InitAnd(Init0, Init1) : Ivy_InitExor(Init0, Init1);
|
||||
return Ivy_CanonLatch( pResult, Init );
|
||||
return Ivy_Latch( p, pResult, Init );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -87,11 +84,11 @@ Ivy_Obj_t * Ivy_CanonPair_rec( Ivy_Obj_t * pGhost )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_CanonAnd( Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 )
|
||||
Ivy_Obj_t * Ivy_CanonAnd( Ivy_Man_t * p, Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 )
|
||||
{
|
||||
Ivy_Obj_t * pGhost, * pResult;
|
||||
pGhost = Ivy_ObjCreateGhost( pObj0, pObj1, IVY_AND, IVY_INIT_NONE );
|
||||
pResult = Ivy_CanonPair_rec( pGhost );
|
||||
pGhost = Ivy_ObjCreateGhost( p, pObj0, pObj1, IVY_AND, IVY_INIT_NONE );
|
||||
pResult = Ivy_CanonPair_rec( p, pGhost );
|
||||
return pResult;
|
||||
}
|
||||
|
||||
|
|
@ -106,14 +103,14 @@ Ivy_Obj_t * Ivy_CanonAnd( Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_CanonExor( Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 )
|
||||
Ivy_Obj_t * Ivy_CanonExor( Ivy_Man_t * p, Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 )
|
||||
{
|
||||
Ivy_Obj_t * pGhost, * pResult;
|
||||
int fCompl = Ivy_IsComplement(pObj0) ^ Ivy_IsComplement(pObj1);
|
||||
pObj0 = Ivy_Regular(pObj0);
|
||||
pObj1 = Ivy_Regular(pObj1);
|
||||
pGhost = Ivy_ObjCreateGhost( pObj0, pObj1, IVY_EXOR, IVY_INIT_NONE );
|
||||
pResult = Ivy_CanonPair_rec( pGhost );
|
||||
pGhost = Ivy_ObjCreateGhost( p, pObj0, pObj1, IVY_EXOR, IVY_INIT_NONE );
|
||||
pResult = Ivy_CanonPair_rec( p, pGhost );
|
||||
return Ivy_NotCond( pResult, fCompl );
|
||||
}
|
||||
|
||||
|
|
@ -128,15 +125,15 @@ Ivy_Obj_t * Ivy_CanonExor( Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_CanonLatch( Ivy_Obj_t * pObj, Ivy_Init_t Init )
|
||||
Ivy_Obj_t * Ivy_CanonLatch( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Init_t Init )
|
||||
{
|
||||
Ivy_Obj_t * pGhost, * pResult;
|
||||
int fCompl = Ivy_IsComplement(pObj);
|
||||
pObj = Ivy_Regular(pObj);
|
||||
pGhost = Ivy_ObjCreateGhost( pObj, Ivy_ObjConst1(pObj), IVY_LATCH, Ivy_InitNotCond(Init, fCompl) );
|
||||
pResult = Ivy_TableLookup( pGhost );
|
||||
pGhost = Ivy_ObjCreateGhost( p, pObj, NULL, IVY_LATCH, Ivy_InitNotCond(Init, fCompl) );
|
||||
pResult = Ivy_TableLookup( p, pGhost );
|
||||
if ( pResult == NULL )
|
||||
pResult = Ivy_ObjCreate( pGhost );
|
||||
pResult = Ivy_ObjCreate( p, pGhost );
|
||||
return Ivy_NotCond( pResult, fCompl );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,15 +39,18 @@
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManCheck( Ivy_Man_t * pMan )
|
||||
int Ivy_ManCheck( Ivy_Man_t * p )
|
||||
{
|
||||
Ivy_Obj_t * pObj, * pObj2;
|
||||
int i;
|
||||
Ivy_ManForEachObj( pMan, pObj, i )
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
// skip deleted nodes
|
||||
if ( Ivy_ObjIsNone(pObj) )
|
||||
continue;
|
||||
if ( Ivy_ObjId(pObj) != i )
|
||||
{
|
||||
printf( "Ivy_ManCheck: Node with ID %d is listed as number %d in the array of objects.\n", pObj->Id, i );
|
||||
return 0;
|
||||
}
|
||||
// consider the constant node and PIs
|
||||
if ( i == 0 || Ivy_ObjIsPi(pObj) )
|
||||
{
|
||||
|
|
@ -69,44 +72,54 @@ int Ivy_ManCheck( Ivy_Man_t * pMan )
|
|||
}
|
||||
if ( Ivy_ObjIsBuf(pObj) )
|
||||
{
|
||||
if ( Ivy_ObjFanin1(pObj) )
|
||||
{
|
||||
printf( "Ivy_ManCheck: The buffer with ID \"%d\" contains second fanin.\n", pObj->Id );
|
||||
return 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ( Ivy_ObjIsLatch(pObj) )
|
||||
{
|
||||
if ( Ivy_ObjFaninId1(pObj) != 0 )
|
||||
if ( Ivy_ObjFanin1(pObj) )
|
||||
{
|
||||
printf( "Ivy_ManCheck: The latch with ID \"%d\" contains second fanin.\n", pObj->Id );
|
||||
return 0;
|
||||
}
|
||||
if ( Ivy_ObjInit(pObj) == 0 )
|
||||
if ( Ivy_ObjInit(pObj) == IVY_INIT_NONE )
|
||||
{
|
||||
printf( "Ivy_ManCheck: The latch with ID \"%d\" does not have initial state.\n", pObj->Id );
|
||||
return 0;
|
||||
}
|
||||
pObj2 = Ivy_TableLookup( pObj );
|
||||
pObj2 = Ivy_TableLookup( p, pObj );
|
||||
if ( pObj2 != pObj )
|
||||
printf( "Ivy_ManCheck: Latch with ID \"%d\" is not in the structural hashing table.\n", pObj->Id );
|
||||
continue;
|
||||
}
|
||||
// consider the AND node
|
||||
if ( !Ivy_ObjFaninId0(pObj) || !Ivy_ObjFaninId1(pObj) )
|
||||
if ( !Ivy_ObjFanin0(pObj) || !Ivy_ObjFanin1(pObj) )
|
||||
{
|
||||
printf( "Ivy_ManCheck: The AIG has internal node \"%d\" with a constant fanin.\n", pObj->Id );
|
||||
printf( "Ivy_ManCheck: The AIG has internal node \"%d\" with a NULL fanin.\n", pObj->Id );
|
||||
return 0;
|
||||
}
|
||||
if ( Ivy_ObjFaninId0(pObj) <= Ivy_ObjFaninId1(pObj) )
|
||||
if ( Ivy_ObjFaninId0(pObj) >= Ivy_ObjFaninId1(pObj) )
|
||||
{
|
||||
printf( "Ivy_ManCheck: The AIG has node \"%d\" with a wrong ordering of fanins.\n", pObj->Id );
|
||||
return 0;
|
||||
}
|
||||
// if ( Ivy_ObjLevel(pObj) != Ivy_ObjLevelNew(pObj) )
|
||||
// printf( "Ivy_ManCheck: Node with ID \"%d\" has level that does not agree with the fanin levels.\n", pObj->Id );
|
||||
pObj2 = Ivy_TableLookup( pObj );
|
||||
// printf( "Ivy_ManCheck: Node with ID \"%d\" has level %d but should have level %d.\n", pObj->Id, Ivy_ObjLevel(pObj), Ivy_ObjLevelNew(pObj) );
|
||||
pObj2 = Ivy_TableLookup( p, pObj );
|
||||
if ( pObj2 != pObj )
|
||||
printf( "Ivy_ManCheck: Node with ID \"%d\" is not in the structural hashing table.\n", pObj->Id );
|
||||
if ( Ivy_ObjRefs(pObj) == 0 )
|
||||
printf( "Ivy_ManCheck: Node with ID \"%d\" has no fanouts.\n", pObj->Id );
|
||||
// check fanouts
|
||||
if ( p->vFanouts && Ivy_ObjRefs(pObj) != Ivy_ObjFanoutNum(p, pObj) )
|
||||
printf( "Ivy_ManCheck: Node with ID \"%d\" has mismatch between the number of fanouts and refs.\n", pObj->Id );
|
||||
}
|
||||
// count the number of nodes in the table
|
||||
if ( Ivy_TableCountEntries(pMan) != Ivy_ManAndNum(pMan) + Ivy_ManExorNum(pMan) + Ivy_ManLatchNum(pMan) )
|
||||
if ( Ivy_TableCountEntries(p) != Ivy_ManAndNum(p) + Ivy_ManExorNum(p) + Ivy_ManLatchNum(p) )
|
||||
{
|
||||
printf( "Ivy_ManCheck: The number of nodes in the structural hashing table is wrong.\n" );
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ printf( "%d", Counter );
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManSeqFindCut( Ivy_Obj_t * pRoot, Vec_Int_t * vFront, Vec_Int_t * vInside, int nSize )
|
||||
void Ivy_ManSeqFindCut( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Int_t * vFront, Vec_Int_t * vInside, int nSize )
|
||||
{
|
||||
assert( !Ivy_IsComplement(pRoot) );
|
||||
assert( Ivy_ObjIsNode(pRoot) );
|
||||
|
|
@ -194,7 +194,7 @@ void Ivy_ManSeqFindCut( Ivy_Obj_t * pRoot, Vec_Int_t * vFront, Vec_Int_t * vInsi
|
|||
Vec_IntPush( vInside, Ivy_LeafCreate(Ivy_ObjFaninId1(pRoot), 0) );
|
||||
|
||||
// compute the cut
|
||||
while ( Ivy_ManSeqFindCut_int( Ivy_ObjMan(pRoot), vFront, vInside, nSize ) );
|
||||
while ( Ivy_ManSeqFindCut_int( p, vFront, vInside, nSize ) );
|
||||
assert( Vec_IntSize(vFront) <= nSize );
|
||||
}
|
||||
|
||||
|
|
@ -213,7 +213,7 @@ void Ivy_ManSeqFindCut( Ivy_Obj_t * pRoot, Vec_Int_t * vFront, Vec_Int_t * vInsi
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManFindBoolCut_rec( Ivy_Obj_t * pObj, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVolume, Ivy_Obj_t * pPivot )
|
||||
int Ivy_ManFindBoolCut_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVolume, Ivy_Obj_t * pPivot )
|
||||
{
|
||||
int RetValue0, RetValue1;
|
||||
if ( pObj == pPivot )
|
||||
|
|
@ -231,15 +231,15 @@ int Ivy_ManFindBoolCut_rec( Ivy_Obj_t * pObj, Vec_Ptr_t * vLeaves, Vec_Ptr_t * v
|
|||
|
||||
if ( Ivy_ObjIsBuf(pObj) )
|
||||
{
|
||||
RetValue0 = Ivy_ManFindBoolCut_rec( Ivy_ObjFanin0(pObj), vLeaves, vVolume, pPivot );
|
||||
RetValue0 = Ivy_ManFindBoolCut_rec( p, Ivy_ObjFanin0(pObj), vLeaves, vVolume, pPivot );
|
||||
if ( !RetValue0 )
|
||||
return 0;
|
||||
Vec_PtrPushUnique( vVolume, pObj );
|
||||
return 1;
|
||||
}
|
||||
assert( Ivy_ObjIsNode(pObj) );
|
||||
RetValue0 = Ivy_ManFindBoolCut_rec( Ivy_ObjFanin0(pObj), vLeaves, vVolume, pPivot );
|
||||
RetValue1 = Ivy_ManFindBoolCut_rec( Ivy_ObjFanin1(pObj), vLeaves, vVolume, pPivot );
|
||||
RetValue0 = Ivy_ManFindBoolCut_rec( p, Ivy_ObjFanin0(pObj), vLeaves, vVolume, pPivot );
|
||||
RetValue1 = Ivy_ManFindBoolCut_rec( p, Ivy_ObjFanin1(pObj), vLeaves, vVolume, pPivot );
|
||||
if ( !RetValue0 && !RetValue1 )
|
||||
return 0;
|
||||
// add new leaves
|
||||
|
|
@ -296,7 +296,7 @@ int Ivy_ManFindBoolCutCost( Ivy_Obj_t * pObj )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManFindBoolCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vVolume, Vec_Ptr_t * vLeaves )
|
||||
int Ivy_ManFindBoolCut( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vVolume, Vec_Ptr_t * vLeaves )
|
||||
{
|
||||
Ivy_Obj_t * pObj, * pFaninC, * pFanin0, * pFanin1, * pPivot;
|
||||
int RetValue, LevelLimit, Lev, k;
|
||||
|
|
@ -405,7 +405,7 @@ int Ivy_ManFindBoolCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vVolu
|
|||
// cut exists, collect all the nodes on the shortest path to the pivot
|
||||
Vec_PtrClear( vLeaves );
|
||||
Vec_PtrClear( vVolume );
|
||||
RetValue = Ivy_ManFindBoolCut_rec( pRoot, vLeaves, vVolume, pPivot );
|
||||
RetValue = Ivy_ManFindBoolCut_rec( p, pRoot, vLeaves, vVolume, pPivot );
|
||||
assert( RetValue == 1 );
|
||||
// unmark the nodes on the frontier (including the pivot)
|
||||
Vec_PtrForEachEntry( vFront, pObj, k )
|
||||
|
|
@ -481,7 +481,7 @@ void Ivy_ManTestCutsBool( Ivy_Man_t * p )
|
|||
}
|
||||
if ( Ivy_ObjIsExor(pObj) )
|
||||
printf( "x" );
|
||||
RetValue = Ivy_ManFindBoolCut( pObj, vFront, vVolume, vLeaves );
|
||||
RetValue = Ivy_ManFindBoolCut( p, pObj, vFront, vVolume, vLeaves );
|
||||
if ( RetValue == 0 )
|
||||
printf( "- " );
|
||||
else
|
||||
|
|
@ -783,11 +783,11 @@ void Ivy_NodePrintCuts( Ivy_Store_t * pCutStore )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Obj_t * pObj, int nLeaves )
|
||||
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 = Ivy_ObjMan(pObj);
|
||||
Ivy_Man_t * pMan = p;
|
||||
Ivy_Obj_t * pLeaf;
|
||||
int i, k;
|
||||
|
||||
|
|
@ -815,7 +815,7 @@ Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Obj_t * pObj, int nLeaves )
|
|||
continue;
|
||||
for ( k = 0; k < pCut->nSize; k++ )
|
||||
{
|
||||
pLeaf = Ivy_ObjObj( pObj, pCut->pArray[k] );
|
||||
pLeaf = Ivy_ManObj( p, pCut->pArray[k] );
|
||||
if ( Ivy_ObjIsCi(pLeaf) )
|
||||
continue;
|
||||
*pCutNew = *pCut;
|
||||
|
|
@ -859,7 +859,7 @@ void Ivy_ManTestCutsAll( Ivy_Man_t * p )
|
|||
{
|
||||
if ( !Ivy_ObjIsNode(pObj) )
|
||||
continue;
|
||||
nCutsCut = Ivy_NodeFindCutsAll( pObj, 4 )->nCuts;
|
||||
nCutsCut = Ivy_NodeFindCutsAll( p, pObj, 5 )->nCuts;
|
||||
nCutsTotal += nCutsCut;
|
||||
nNodeOver += (nCutsCut == IVY_CUT_LIMIT);
|
||||
nNodeTotal++;
|
||||
|
|
|
|||
|
|
@ -69,17 +69,14 @@ Vec_Int_t * Ivy_ManDfs( Ivy_Man_t * p )
|
|||
Vec_Int_t * vNodes;
|
||||
Ivy_Obj_t * pObj;
|
||||
int i;
|
||||
assert( Ivy_ManLatchNum(p) == 0 );
|
||||
// make sure the nodes are not marked
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
assert( !pObj->fMarkA && !pObj->fMarkB );
|
||||
// collect the nodes
|
||||
vNodes = Vec_IntAlloc( Ivy_ManNodeNum(p) );
|
||||
if ( Ivy_ManLatchNum(p) > 0 )
|
||||
Ivy_ManForEachCo( p, pObj, i )
|
||||
Ivy_ManDfs_rec( Ivy_ObjFanin0(pObj), vNodes );
|
||||
else
|
||||
Ivy_ManForEachPo( p, pObj, i )
|
||||
Ivy_ManDfs_rec( Ivy_ObjFanin0(pObj), vNodes );
|
||||
Ivy_ManForEachPo( p, pObj, i )
|
||||
Ivy_ManDfs_rec( Ivy_ObjFanin0(pObj), vNodes );
|
||||
// unmark the collected nodes
|
||||
Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
|
||||
Ivy_ObjClearMarkA(pObj);
|
||||
|
|
@ -90,7 +87,7 @@ Vec_Int_t * Ivy_ManDfs( Ivy_Man_t * p )
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects nodes in the DFS order.]
|
||||
Synopsis [Collects AND/EXOR nodes in the DFS order from CIs to COs.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -99,52 +96,31 @@ Vec_Int_t * Ivy_ManDfs( Ivy_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManDfsExt_rec( Ivy_Obj_t * pObj, Vec_Int_t * vNodes )
|
||||
Vec_Int_t * Ivy_ManDfsSeq( Ivy_Man_t * p, Vec_Int_t ** pvLatches )
|
||||
{
|
||||
Vec_Int_t * vFanins;
|
||||
int i, Fanin;
|
||||
if ( !Ivy_ObjIsNodeExt(pObj) || Ivy_ObjIsMarkA(pObj) )
|
||||
return;
|
||||
// mark the node as visited
|
||||
Ivy_ObjSetMarkA(pObj);
|
||||
// traverse the fanins
|
||||
vFanins = Ivy_ObjGetFanins( pObj );
|
||||
Vec_IntForEachEntry( vFanins, Fanin, i )
|
||||
Ivy_ManDfsExt_rec( Ivy_ObjObj(pObj, Ivy_EdgeId(Fanin)), vNodes );
|
||||
// add the node
|
||||
Vec_IntPush( vNodes, pObj->Id );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects nodes in the DFS order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Ivy_ManDfsExt( Ivy_Man_t * p )
|
||||
{
|
||||
Vec_Int_t * vNodes;
|
||||
Ivy_Obj_t * pObj, * pFanin;
|
||||
Vec_Int_t * vNodes, * vLatches;
|
||||
Ivy_Obj_t * pObj;
|
||||
int i;
|
||||
assert( p->fExtended );
|
||||
assert( Ivy_ManLatchNum(p) == 0 );
|
||||
// make sure network does not have buffers
|
||||
vNodes = Vec_IntAlloc( 10 );
|
||||
assert( Ivy_ManLatchNum(p) > 0 );
|
||||
// make sure the nodes are not marked
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
assert( !pObj->fMarkA && !pObj->fMarkB );
|
||||
// collect the latches
|
||||
vLatches = Vec_IntAlloc( Ivy_ManLatchNum(p) );
|
||||
Ivy_ManForEachLatch( p, pObj, i )
|
||||
Vec_IntPush( vLatches, pObj->Id );
|
||||
// collect the nodes
|
||||
vNodes = Vec_IntAlloc( Ivy_ManNodeNum(p) );
|
||||
Ivy_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
pFanin = Ivy_ManObj( p, Ivy_EdgeId( Ivy_ObjReadFanin(pObj,0) ) );
|
||||
Ivy_ManDfsExt_rec( pFanin, vNodes );
|
||||
}
|
||||
Ivy_ManDfs_rec( Ivy_ObjFanin0(pObj), vNodes );
|
||||
Ivy_ManForEachNodeVec( p, vLatches, pObj, i )
|
||||
Ivy_ManDfs_rec( Ivy_ObjFanin0(pObj), vNodes );
|
||||
// unmark the collected nodes
|
||||
Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
|
||||
Ivy_ObjClearMarkA(pObj);
|
||||
// make sure network does not have dangling nodes
|
||||
// the network may have dangling nodes if some fanins of ESOPs do not appear in cubes
|
||||
// assert( p->nNodes == Vec_PtrSize(vNodes) );
|
||||
assert( Vec_IntSize(vNodes) == Ivy_ManNodeNum(p) + Ivy_ManBufNum(p) );
|
||||
*pvLatches = vLatches;
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
|
|
@ -249,7 +225,7 @@ Vec_Int_t * Ivy_ManRequiredLevels( Ivy_Man_t * p )
|
|||
int i, k, Level, LevelMax;
|
||||
assert( p->vRequired == NULL );
|
||||
// start the required times
|
||||
vLevelsR = Vec_IntStart( Ivy_ManObjIdNext(p) );
|
||||
vLevelsR = Vec_IntStart( Ivy_ManObjIdMax(p) + 1 );
|
||||
// iterate through the nodes in the reverse order
|
||||
vNodes = Ivy_ManLevelize( p );
|
||||
Vec_VecForEachEntryReverseReverse( vNodes, pObj, i, k )
|
||||
|
|
@ -262,7 +238,7 @@ Vec_Int_t * Ivy_ManRequiredLevels( Ivy_Man_t * p )
|
|||
}
|
||||
Vec_VecFree( vNodes );
|
||||
// convert it into the required times
|
||||
LevelMax = Ivy_ManReadLevels( p );
|
||||
LevelMax = Ivy_ManLevels( p );
|
||||
//printf( "max %5d\n",LevelMax );
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -608,7 +608,7 @@ Ivy_Obj_t * Ivy_ManDsdConstruct_rec( Ivy_Man_t * p, Vec_Int_t * vFront, int iNod
|
|||
|
||||
// Ivy_MultiEval( pNodes, Node.nFans, Node.Type == IVY_DEC_AND ? IVY_AND : IVY_EXOR );
|
||||
|
||||
pResult = Ivy_Multi( pNodes, Node.nFans, Node.Type == IVY_DEC_AND ? IVY_AND : IVY_EXOR );
|
||||
pResult = Ivy_Multi( p, pNodes, Node.nFans, Node.Type == IVY_DEC_AND ? IVY_AND : IVY_EXOR );
|
||||
return Ivy_NotCond( pResult, Node.fCompl );
|
||||
}
|
||||
assert( Node.fCompl == 0 );
|
||||
|
|
@ -626,9 +626,9 @@ Ivy_Obj_t * Ivy_ManDsdConstruct_rec( Ivy_Man_t * p, Vec_Int_t * vFront, int iNod
|
|||
pNodes[1] = Ivy_NotCond( pNodes[1], (Var1 & 1) );
|
||||
pNodes[2] = Ivy_NotCond( pNodes[2], (Var0 & 1) );
|
||||
if ( Node.Type == IVY_DEC_MUX )
|
||||
return Ivy_Mux( pNodes[0], pNodes[1], pNodes[2] );
|
||||
return Ivy_Mux( p, pNodes[0], pNodes[1], pNodes[2] );
|
||||
else
|
||||
return Ivy_Maj( pNodes[0], pNodes[1], pNodes[2] );
|
||||
return Ivy_Maj( p, pNodes[0], pNodes[1], pNodes[2] );
|
||||
}
|
||||
assert( 0 );
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,317 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ivyFanout.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [And-Inverter Graph package.]
|
||||
|
||||
Synopsis [Representation of the fanouts.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: ivyFanout.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "ivy.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline int Ivy_FanoutIsArray( void * p ) { return (int )(((unsigned)p) & 01); }
|
||||
static inline Vec_Ptr_t * Ivy_FanoutGetArray( void * p ) { assert( Ivy_FanoutIsArray(p) ); return (Vec_Ptr_t *)((unsigned)(p) & ~01); }
|
||||
static inline Vec_Ptr_t * Ivy_FanoutSetArray( void * p ) { assert( !Ivy_FanoutIsArray(p) ); return (Vec_Ptr_t *)((unsigned)(p) ^ 01); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts the fanout representation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManStartFanout( Ivy_Man_t * p )
|
||||
{
|
||||
Ivy_Obj_t * pObj;
|
||||
int i;
|
||||
assert( p->vFanouts == NULL );
|
||||
p->vFanouts = Vec_PtrStart( Ivy_ManObjIdMax(p) + 1000 );
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( Ivy_ObjFanin0(pObj) )
|
||||
Ivy_ObjAddFanout( p, Ivy_ObjFanin0(pObj), pObj );
|
||||
if ( Ivy_ObjFanin1(pObj) )
|
||||
Ivy_ObjAddFanout( p, Ivy_ObjFanin1(pObj), pObj );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the fanout representation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManStopFanout( Ivy_Man_t * p )
|
||||
{
|
||||
void * pTemp;
|
||||
int i;
|
||||
assert( p->vFanouts != NULL );
|
||||
Vec_PtrForEachEntry( p->vFanouts, pTemp, i )
|
||||
if ( Ivy_FanoutIsArray(pTemp) )
|
||||
Vec_PtrFree( Ivy_FanoutGetArray(pTemp) );
|
||||
Vec_PtrFree( p->vFanouts );
|
||||
p->vFanouts = NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Add the fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjAddFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
void ** ppSpot;
|
||||
assert( p->vFanouts != NULL );
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
// extend the fanout array if needed
|
||||
Vec_PtrFillExtra( p->vFanouts, pObj->Id + 1, NULL );
|
||||
// get the pointer to the place where fanouts are stored
|
||||
ppSpot = Vec_PtrEntryP( p->vFanouts, pObj->Id );
|
||||
// consider several cases
|
||||
if ( *ppSpot == NULL ) // no fanout - add one fanout
|
||||
*ppSpot = pFanout;
|
||||
else if ( Ivy_FanoutIsArray(*ppSpot) ) // array of fanouts - add one fanout
|
||||
{
|
||||
vNodes = Ivy_FanoutGetArray(*ppSpot);
|
||||
Vec_PtrPush( vNodes, pFanout );
|
||||
}
|
||||
else // only one fanout - create array and put both fanouts into the array
|
||||
{
|
||||
vNodes = Vec_PtrAlloc( 4 );
|
||||
Vec_PtrPush( vNodes, *ppSpot );
|
||||
Vec_PtrPush( vNodes, pFanout );
|
||||
*ppSpot = Ivy_FanoutSetArray( vNodes );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Removes the fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjDeleteFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFanout )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
void ** ppSpot;
|
||||
assert( p->vFanouts != NULL );
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
// extend the fanout array if needed
|
||||
Vec_PtrFillExtra( p->vFanouts, pObj->Id + 1, NULL );
|
||||
ppSpot = Vec_PtrEntryP( p->vFanouts, pObj->Id );
|
||||
if ( *ppSpot == NULL ) // no fanout - should not happen
|
||||
{
|
||||
assert( 0 );
|
||||
}
|
||||
else if ( Ivy_FanoutIsArray(*ppSpot) ) // the array of fanouts - delete the fanout
|
||||
{
|
||||
vNodes = Ivy_FanoutGetArray(*ppSpot);
|
||||
Vec_PtrRemove( vNodes, pFanout );
|
||||
}
|
||||
else // only one fanout - delete the fanout
|
||||
{
|
||||
assert( *ppSpot == pFanout );
|
||||
*ppSpot = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Replaces the fanout of pOld to be pFanoutNew.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjPatchFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFanoutOld, Ivy_Obj_t * pFanoutNew )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
void ** ppSpot;
|
||||
int Index;
|
||||
assert( p->vFanouts != NULL );
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
// extend the fanout array if needed
|
||||
Vec_PtrFillExtra( p->vFanouts, pObj->Id + 1, NULL );
|
||||
ppSpot = Vec_PtrEntryP( p->vFanouts, pObj->Id );
|
||||
if ( *ppSpot == NULL ) // no fanout - should not happen
|
||||
{
|
||||
assert( 0 );
|
||||
}
|
||||
else if ( Ivy_FanoutIsArray(*ppSpot) ) // the array of fanouts - find and replace the fanout
|
||||
{
|
||||
vNodes = Ivy_FanoutGetArray(*ppSpot);
|
||||
Index = Vec_PtrFind( vNodes, pFanoutOld );
|
||||
assert( Index >= 0 );
|
||||
Vec_PtrWriteEntry( vNodes, Index, pFanoutNew );
|
||||
}
|
||||
else // only one fanout - delete the fanout
|
||||
{
|
||||
assert( *ppSpot == pFanoutOld );
|
||||
*ppSpot = pFanoutNew;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts iteration through the fanouts.]
|
||||
|
||||
Description [Copies the currently available fanouts into the array.]
|
||||
|
||||
SideEffects [Can be used while the fanouts are being removed.]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjCollectFanouts( Ivy_Man_t * p, Ivy_Obj_t * pObj, Vec_Ptr_t * vArray )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Ivy_Obj_t * pTemp;
|
||||
int i;
|
||||
assert( p->vFanouts != NULL );
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
// extend the fanout array if needed
|
||||
Vec_PtrFillExtra( p->vFanouts, pObj->Id + 1, NULL );
|
||||
vNodes = Vec_PtrEntry( p->vFanouts, pObj->Id );
|
||||
// clean the resulting array
|
||||
Vec_PtrClear( vArray );
|
||||
if ( vNodes == NULL ) // no fanout - nothing to do
|
||||
{
|
||||
}
|
||||
else if ( Ivy_FanoutIsArray(vNodes) ) // the array of fanouts - copy fanouts
|
||||
{
|
||||
vNodes = Ivy_FanoutGetArray(vNodes);
|
||||
Vec_PtrForEachEntry( vNodes, pTemp, i )
|
||||
Vec_PtrPush( vArray, pTemp );
|
||||
}
|
||||
else // only one fanout - add the fanout
|
||||
Vec_PtrPush( vArray, vNodes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads one fanout.]
|
||||
|
||||
Description [Returns fanout if there is only one fanout.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_ObjReadOneFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
assert( p->vFanouts != NULL );
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
// extend the fanout array if needed
|
||||
Vec_PtrFillExtra( p->vFanouts, pObj->Id + 1, NULL );
|
||||
vNodes = Vec_PtrEntry( p->vFanouts, pObj->Id );
|
||||
// clean the resulting array
|
||||
if ( vNodes && !Ivy_FanoutIsArray(vNodes) ) // only one fanout - return
|
||||
return (Ivy_Obj_t *)vNodes;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads one fanout.]
|
||||
|
||||
Description [Returns fanout if there is only one fanout.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_ObjReadFirstFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
assert( p->vFanouts != NULL );
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
// extend the fanout array if needed
|
||||
Vec_PtrFillExtra( p->vFanouts, pObj->Id + 1, NULL );
|
||||
vNodes = Vec_PtrEntry( p->vFanouts, pObj->Id );
|
||||
// clean the resulting array
|
||||
if ( vNodes == NULL )
|
||||
return NULL;
|
||||
if ( !Ivy_FanoutIsArray(vNodes) ) // only one fanout - return
|
||||
return (Ivy_Obj_t *)vNodes;
|
||||
return Vec_PtrEntry( Ivy_FanoutGetArray(vNodes), 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads one fanout.]
|
||||
|
||||
Description [Returns fanout if there is only one fanout.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ObjFanoutNum( Ivy_Man_t * p, Ivy_Obj_t * pObj )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
assert( p->vFanouts != NULL );
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
// extend the fanout array if needed
|
||||
Vec_PtrFillExtra( p->vFanouts, pObj->Id + 1, NULL );
|
||||
vNodes = Vec_PtrEntry( p->vFanouts, pObj->Id );
|
||||
// clean the resulting array
|
||||
if ( vNodes == NULL )
|
||||
return 0;
|
||||
if ( !Ivy_FanoutIsArray(vNodes) ) // only one fanout - return
|
||||
return 1;
|
||||
return Vec_PtrSize( Ivy_FanoutGetArray(vNodes) );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,241 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ivyIsop.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [And-Inverter Graph package.]
|
||||
|
||||
Synopsis [Computing irredundant SOP using truth table.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: ivyIsop.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "ivy.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Ivy_Sop_t_ Ivy_Sop_t;
|
||||
struct Ivy_Sop_t_
|
||||
{
|
||||
unsigned * pCubes;
|
||||
int nCubes;
|
||||
};
|
||||
|
||||
static Mem_Flex_t * s_Man = NULL;
|
||||
|
||||
static unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t * pcRes );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_TruthManStart()
|
||||
{
|
||||
s_Man = Mem_FlexStart();
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_TruthManStop()
|
||||
{
|
||||
Mem_FlexStop( s_Man, 0 );
|
||||
s_Man = NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Ivy_TruthIsop( unsigned * uTruth, int nVars )
|
||||
{
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes ISOP for 5 variables or less.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned * Ivy_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Ivy_Sop_t * pcRes )
|
||||
{
|
||||
Ivy_Sop_t cRes0, cRes1, cRes2;
|
||||
Ivy_Sop_t * pcRes0 = &cRes0, * pcRes1 = &cRes1, * pcRes2 = &cRes2;
|
||||
unsigned * puRes0, * puRes1, * puRes2;
|
||||
unsigned * puOn0, * puOn1, * puOnDc0, * puOnDc1, * pTemp0, * pTemp1;
|
||||
int i, k, Var, nWords;
|
||||
assert( nVars > 5 );
|
||||
assert( Extra_TruthIsImply( puOn, puOnDc, nVars ) );
|
||||
if ( Extra_TruthIsConst0( puOn, nVars ) )
|
||||
{
|
||||
pcRes->nCubes = 0;
|
||||
pcRes->pCubes = NULL;
|
||||
return puOn;
|
||||
}
|
||||
if ( Extra_TruthIsConst1( puOnDc, nVars ) )
|
||||
{
|
||||
pcRes->nCubes = 1;
|
||||
pcRes->pCubes = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 );
|
||||
pcRes->pCubes[0] = 0;
|
||||
return puOnDc;
|
||||
}
|
||||
// find the topmost var
|
||||
for ( Var = nVars-1; Var >= 0; Var-- )
|
||||
if ( Extra_TruthVarInSupport( puOn, nVars, Var ) ||
|
||||
Extra_TruthVarInSupport( puOnDc, nVars, Var ) )
|
||||
break;
|
||||
assert( Var >= 0 );
|
||||
if ( Var < 5 )
|
||||
{
|
||||
unsigned * puRes = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 );
|
||||
*puRes = Ivy_TruthIsop5_rec( puOn[0], puOnDc[0], Var + 1, pcRes );
|
||||
return puRes;
|
||||
}
|
||||
nWords = Extra_TruthWordNum( Var+1 );
|
||||
// cofactor
|
||||
puOn0 = puOn;
|
||||
puOn1 = puOn + nWords;
|
||||
puOnDc0 = puOnDc;
|
||||
puOnDc1 = puOnDc + nWords;
|
||||
// intermediate copies
|
||||
pTemp0 = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 * nWords );
|
||||
pTemp1 = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 * nWords );
|
||||
// solve for cofactors
|
||||
Extra_TruthSharp( pTemp0, puOn0, puOnDc1, Var + 1 );
|
||||
puRes0 = Ivy_TruthIsop5_rec( pTemp0, uOnDc0, Var-1, pcRes0 );
|
||||
Extra_TruthSharp( pTemp0, puOn1, puOnDc0, Var + 1 );
|
||||
puRes1 = Ivy_TruthIsop5_rec( pTemp1, uOnDc1, Var-1, pcRes1 );
|
||||
Extra_TruthSharp( pTemp0, puOn0, puRes0, Var + 1 );
|
||||
Extra_TruthSharp( pTemp1, puOn1, puRes1, Var + 1 );
|
||||
Extra_TruthOr( pTemp0, pTemp0, pTemp1, Var + 1 );
|
||||
Extra_TruthAnd( pTemp1, puOnDc0, puOnDc1, Var + 1 );
|
||||
puRes2 = Ivy_TruthIsop5_rec( pTemp0, pTemp1, Var-1, pcRes2 );
|
||||
// create the resulting cover
|
||||
pcRes->nCubes = pcRes0->nCubes + pcRes1->nCubes + pcRes2->nCubes;
|
||||
pcRes->pCubes = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 * pcRes->nCubes );
|
||||
k = 0;
|
||||
for ( i = 0; i < pcRes0->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes0->pCubes[i] | (1 << ((Var<<1)+1));
|
||||
for ( i = 0; i < pcRes1->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes1->pCubes[i] | (1 << ((Var<<1)+0));
|
||||
for ( i = 0; i < pcRes1->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes2->pCubes[i];
|
||||
assert( k == pcRes->nCubes );
|
||||
// create the resulting truth table
|
||||
Extra_TruthSharp( pTemp0, Var, uRes0, uRes1, Var + 1 );
|
||||
Extra_TruthOr( pTemp0, pTemp0, uRes2, Var + 1 );
|
||||
return pTemp0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes ISOP for 5 variables or less.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t * pcRes )
|
||||
{
|
||||
unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
|
||||
Ivy_Sop_t cRes0, cRes1, cRes2;
|
||||
Ivy_Sop_t * pcRes0 = &cRes0, * pcRes1 = &cRes1, * pcRes2 = &cRes2;
|
||||
unsigned uRes0, uRes1, uRes2;
|
||||
unsigned uOn0, uOn1, uOnDc0, uOnDc1;
|
||||
int i, k, Var;
|
||||
assert( nVars <= 5 );
|
||||
assert( uOn & ~uOnDc == 0 );
|
||||
if ( Extra_TruthIsConst0( uOn == 0 )
|
||||
{
|
||||
pcRes->nCubes = 0;
|
||||
pcRes->pCubes = NULL;
|
||||
return 0;
|
||||
}
|
||||
if ( uOnDc == 0xFFFFFFFF )
|
||||
{
|
||||
pcRes->nCubes = 1;
|
||||
pcRes->pCubes = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 );
|
||||
pcRes->pCubes[0] = 0;
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
// find the topmost var
|
||||
for ( Var = nVars-1; Var >= 0; Var-- )
|
||||
if ( Extra_TruthVarInSupport( &uOn, 5, Var ) ||
|
||||
Extra_TruthVarInSupport( &uOnDc, 5, Var ) )
|
||||
break;
|
||||
assert( Var >= 0 );
|
||||
// cofactor
|
||||
uOn0 = uOn1 = uOn;
|
||||
uOnDc0 = uOnDc1 = uOnDc;
|
||||
Extra_TruthCofactor0( &uOn0, 5, Var );
|
||||
Extra_TruthCofactor1( &uOn1, 5, Var );
|
||||
Extra_TruthCofactor0( &uOnDc0, 5, Var );
|
||||
Extra_TruthCofactor1( &uOnDc1, 5, Var );
|
||||
// solve for cofactors
|
||||
uRes0 = Ivy_TruthIsop5_rec( uOn0 & ~uOnDc1, uOnDc0, Var-1, pcRes0 );
|
||||
uRes1 = Ivy_TruthIsop5_rec( uOn1 & ~uOnDc0, uOnDc1, Var-1, pcRes1 );
|
||||
uRes2 = Ivy_TruthIsop5_rec( (uOn0 & ~uRes0) | (uOn1 & ~uRes1), uOnDc0 & uOnDc1, Var-1, pcRes2 );
|
||||
// create the resulting cover
|
||||
pcRes->nCubes = pcRes0->nCubes + pcRes1->nCubes + pcRes2->nCubes;
|
||||
pcRes->pCubes = (unsigned *)Mem_FlexEntryFetch( s_Man, 4 * pcRes->nCubes );
|
||||
k = 0;
|
||||
for ( i = 0; i < pcRes0->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes0->pCubes[i] | (1 << ((Var<<1)+1));
|
||||
for ( i = 0; i < pcRes1->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes1->pCubes[i] | (1 << ((Var<<1)+0));
|
||||
for ( i = 0; i < pcRes1->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes2->pCubes[i];
|
||||
assert( k == pcRes->nCubes );
|
||||
return (uRes0 & ~uMasks[Var]) | (uRes1 & uMasks[Var]) | uRes2;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -39,53 +39,32 @@
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Man_t * Ivy_ManStart( int nPis, int nPos, int nNodesMax )
|
||||
Ivy_Man_t * Ivy_ManStart()
|
||||
{
|
||||
Ivy_Man_t * p;
|
||||
Ivy_Obj_t * pObj;
|
||||
int i, nTotalSize;
|
||||
// start the manager
|
||||
p = ALLOC( Ivy_Man_t, 1 );
|
||||
memset( p, 0, sizeof(Ivy_Man_t) );
|
||||
// perform initializations
|
||||
p->Ghost.Id = -1;
|
||||
p->nTravIds = 1;
|
||||
p->fCatchExor = 1;
|
||||
// AIG nodes
|
||||
p->nObjsAlloc = 1 + nPis + nPos + nNodesMax;
|
||||
// p->nObjsAlloc += (p->nObjsAlloc & 1); // make it even
|
||||
nTotalSize = p->nObjsAlloc + IVY_SANDBOX_SIZE + 1;
|
||||
p->pObjs = ALLOC( Ivy_Obj_t, nTotalSize );
|
||||
memset( p->pObjs, 0, sizeof(Ivy_Obj_t) * nTotalSize );
|
||||
// temporary storage for deleted entries
|
||||
p->vFree = Vec_IntAlloc( 100 );
|
||||
// set the node IDs
|
||||
for ( i = 0, pObj = p->pObjs; i < nTotalSize; i++, pObj++ )
|
||||
pObj->Id = i - IVY_SANDBOX_SIZE - 1;
|
||||
// remember the manager in the first entry
|
||||
*((Ivy_Man_t **)p->pObjs) = p;
|
||||
p->pObjs += IVY_SANDBOX_SIZE + 1;
|
||||
// allocate arrays for nodes
|
||||
p->vPis = Vec_PtrAlloc( 100 );
|
||||
p->vPos = Vec_PtrAlloc( 100 );
|
||||
p->vBufs = Vec_PtrAlloc( 100 );
|
||||
p->vObjs = Vec_PtrAlloc( 100 );
|
||||
// prepare the internal memory manager
|
||||
Ivy_ManStartMemory( p );
|
||||
// create the constant node
|
||||
p->pConst1 = Ivy_ManFetchMemory( p );
|
||||
p->pConst1->fPhase = 1;
|
||||
Vec_PtrPush( p->vObjs, p->pConst1 );
|
||||
p->nCreated = 1;
|
||||
p->ObjIdNext = 1;
|
||||
Ivy_ManConst1(p)->fPhase = 1;
|
||||
// create PIs
|
||||
pObj = Ivy_ManGhost(p);
|
||||
pObj->Type = IVY_PI;
|
||||
p->vPis = Vec_IntAlloc( 100 );
|
||||
for ( i = 0; i < nPis; i++ )
|
||||
Ivy_ObjCreate( pObj );
|
||||
// create POs
|
||||
pObj->Type = IVY_PO;
|
||||
p->vPos = Vec_IntAlloc( 100 );
|
||||
for ( i = 0; i < nPos; i++ )
|
||||
Ivy_ObjCreate( pObj );
|
||||
// start the table
|
||||
p->nTableSize = p->nObjsAlloc*5/2+13;
|
||||
p->nTableSize = 10007;
|
||||
p->pTable = ALLOC( int, p->nTableSize );
|
||||
memset( p->pTable, 0, sizeof(int) * p->nTableSize );
|
||||
// allocate undo storage
|
||||
p->nUndosAlloc = 100;
|
||||
p->pUndos = ALLOC( Ivy_Obj_t, p->nUndosAlloc );
|
||||
memset( p->pUndos, 0, sizeof(Ivy_Obj_t) * p->nUndosAlloc );
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
@ -102,50 +81,18 @@ Ivy_Man_t * Ivy_ManStart( int nPis, int nPos, int nNodesMax )
|
|||
***********************************************************************/
|
||||
void Ivy_ManStop( Ivy_Man_t * p )
|
||||
{
|
||||
if ( p->fExtended )
|
||||
{
|
||||
Ivy_Obj_t * pObj;
|
||||
int i;
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
if ( Ivy_ObjGetFanins(pObj) )
|
||||
Vec_IntFree( Ivy_ObjGetFanins(pObj) );
|
||||
}
|
||||
if ( p->vFree ) Vec_IntFree( p->vFree );
|
||||
if ( p->vTruths ) Vec_IntFree( p->vTruths );
|
||||
if ( p->vPis ) Vec_IntFree( p->vPis );
|
||||
if ( p->vPos ) Vec_IntFree( p->vPos );
|
||||
FREE( p->pMemory );
|
||||
free( p->pObjs - IVY_SANDBOX_SIZE - 1 );
|
||||
// Ivy_TableProfile( p );
|
||||
if ( p->vFanouts ) Ivy_ManStopFanout( p );
|
||||
if ( p->vChunks ) Ivy_ManStopMemory( p );
|
||||
if ( p->vRequired ) Vec_IntFree( p->vRequired );
|
||||
if ( p->vPis ) Vec_PtrFree( p->vPis );
|
||||
if ( p->vPos ) Vec_PtrFree( p->vPos );
|
||||
if ( p->vBufs ) Vec_PtrFree( p->vBufs );
|
||||
if ( p->vObjs ) Vec_PtrFree( p->vObjs );
|
||||
free( p->pTable );
|
||||
free( p->pUndos );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of dangling nodes removed.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManGrow( Ivy_Man_t * p )
|
||||
{
|
||||
int i;
|
||||
assert( p->ObjIdNext == p->nObjsAlloc );
|
||||
if ( p->ObjIdNext != p->nObjsAlloc )
|
||||
return;
|
||||
// printf( "Ivy_ObjCreate(): Reallocing the node array.\n" );
|
||||
p->nObjsAlloc = 2 * p->nObjsAlloc;
|
||||
p->pObjs = REALLOC( Ivy_Obj_t, p->pObjs - IVY_SANDBOX_SIZE - 1, p->nObjsAlloc + IVY_SANDBOX_SIZE + 1 ) + IVY_SANDBOX_SIZE + 1;
|
||||
memset( p->pObjs + p->ObjIdNext, 0, sizeof(Ivy_Obj_t) * p->nObjsAlloc / 2 );
|
||||
for ( i = p->nObjsAlloc / 2; i < p->nObjsAlloc; i++ )
|
||||
Ivy_ManObj( p, i )->Id = i;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of dangling nodes removed.]
|
||||
|
|
@ -164,10 +111,36 @@ int Ivy_ManCleanup( Ivy_Man_t * p )
|
|||
nNodesOld = Ivy_ManNodeNum(p);
|
||||
Ivy_ManForEachNode( p, pNode, i )
|
||||
if ( Ivy_ObjRefs(pNode) == 0 )
|
||||
Ivy_ObjDelete_rec( pNode, 1 );
|
||||
Ivy_ObjDelete_rec( p, pNode, 1 );
|
||||
return nNodesOld - Ivy_ManNodeNum(p);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of dangling nodes removed.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManPropagateBuffers( Ivy_Man_t * p )
|
||||
{
|
||||
Ivy_Obj_t * pNode;
|
||||
int nSteps;
|
||||
for ( nSteps = 0; Vec_PtrSize(p->vBufs) > 0; nSteps++ )
|
||||
{
|
||||
pNode = Vec_PtrEntryLast(p->vBufs);
|
||||
while ( Ivy_ObjIsBuf(pNode) )
|
||||
pNode = Ivy_ObjReadFirstFanout( p, pNode );
|
||||
Ivy_NodeFixBufferFanins( p, pNode );
|
||||
}
|
||||
// printf( "Number of steps = %d\n", nSteps );
|
||||
return nSteps;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the AIG manager.]
|
||||
|
|
@ -182,26 +155,73 @@ int Ivy_ManCleanup( Ivy_Man_t * p )
|
|||
void Ivy_ManPrintStats( Ivy_Man_t * p )
|
||||
{
|
||||
printf( "PI/PO = %d/%d ", Ivy_ManPiNum(p), Ivy_ManPoNum(p) );
|
||||
if ( p->fExtended )
|
||||
{
|
||||
printf( "Am = %d. ", Ivy_ManAndMultiNum(p) );
|
||||
printf( "Xm = %d. ", Ivy_ManExorMultiNum(p) );
|
||||
printf( "Lut = %d. ", Ivy_ManLutNum(p) );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "A = %d. ", Ivy_ManAndNum(p) );
|
||||
printf( "X = %d. ", Ivy_ManExorNum(p) );
|
||||
printf( "B = %4d. ", Ivy_ManBufNum(p) );
|
||||
}
|
||||
// printf( "MaxID = %d. ", p->ObjIdNext-1 );
|
||||
// printf( "All = %d. ", p->nObjsAlloc );
|
||||
printf( "Cre = %d. ", p->nCreated );
|
||||
printf( "Del = %d. ", p->nDeleted );
|
||||
printf( "Lev = %d. ", Ivy_ManReadLevels(p) );
|
||||
printf( "A = %d. ", Ivy_ManAndNum(p) );
|
||||
printf( "L = %d. ", Ivy_ManLatchNum(p) );
|
||||
// printf( "X = %d. ", Ivy_ManExorNum(p) );
|
||||
printf( "B = %d. ", Ivy_ManBufNum(p) );
|
||||
printf( "MaxID = %d. ", Ivy_ManObjIdMax(p) );
|
||||
// printf( "Cre = %d. ", p->nCreated );
|
||||
// printf( "Del = %d. ", p->nDeleted );
|
||||
printf( "Lev = %d. ", Ivy_ManLatchNum(p)? -1 : Ivy_ManLevels(p) );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts a combinational AIG manager into a sequential one.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches, int * pInits )
|
||||
{
|
||||
Ivy_Obj_t * pObj, * pLatch;
|
||||
Ivy_Init_t Init;
|
||||
int i;
|
||||
if ( nLatches == 0 )
|
||||
return;
|
||||
assert( nLatches < Ivy_ManPiNum(p) && nLatches < Ivy_ManPoNum(p) );
|
||||
assert( Ivy_ManPiNum(p) == Vec_PtrSize(p->vPis) );
|
||||
assert( Ivy_ManPoNum(p) == Vec_PtrSize(p->vPos) );
|
||||
assert( Vec_PtrSize( p->vBufs ) == 0 );
|
||||
// create fanouts
|
||||
if ( p->vFanouts == NULL )
|
||||
Ivy_ManStartFanout( p );
|
||||
// collect the POs to be converted into latches
|
||||
for ( i = 0; i < nLatches; i++ )
|
||||
{
|
||||
// get the latch value
|
||||
Init = pInits? pInits[i] : IVY_INIT_0;
|
||||
// create latch
|
||||
pObj = Ivy_ManPo( p, Ivy_ManPoNum(p) - nLatches + i );
|
||||
pLatch = Ivy_Latch( p, Ivy_ObjChild0(pObj), Init );
|
||||
Ivy_ObjDisconnect( p, pObj );
|
||||
// convert the corresponding PI to a buffer and connect it to the latch
|
||||
pObj = Ivy_ManPi( p, Ivy_ManPiNum(p) - nLatches + i );
|
||||
pObj->Type = IVY_BUF;
|
||||
Ivy_ObjConnect( p, pObj, pLatch, NULL );
|
||||
// save the buffer
|
||||
Vec_PtrPush( p->vBufs, pObj );
|
||||
}
|
||||
// shrink the arrays
|
||||
Vec_PtrShrink( p->vPis, Ivy_ManPiNum(p) - nLatches );
|
||||
Vec_PtrShrink( p->vPos, Ivy_ManPoNum(p) - nLatches );
|
||||
// update the counters of different objects
|
||||
p->nObjs[IVY_PI] -= nLatches;
|
||||
p->nObjs[IVY_PO] -= nLatches;
|
||||
p->nObjs[IVY_BUF] += nLatches;
|
||||
p->nDeleted -= 2 * nLatches;
|
||||
// perform hashing by propagating the buffers
|
||||
Ivy_ManPropagateBuffers( p );
|
||||
// check the resulting network
|
||||
if ( !Ivy_ManCheck(p) )
|
||||
printf( "Ivy_ManMakeSeq(): The check has failed.\n" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -0,0 +1,115 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ivyMem.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [And-Inverter Graph package.]
|
||||
|
||||
Synopsis [Memory management for the AIG nodes.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: ivyMem.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "ivy.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// memory management
|
||||
#define IVY_PAGE_SIZE 12 // page size containing 2^IVY_PAGE_SIZE nodes
|
||||
#define IVY_PAGE_MASK 4095 // page bitmask (2^IVY_PAGE_SIZE)-1
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts the internal memory manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManStartMemory( Ivy_Man_t * p )
|
||||
{
|
||||
p->vChunks = Vec_PtrAlloc( 128 );
|
||||
p->vPages = Vec_PtrAlloc( 128 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the internal memory manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManStopMemory( Ivy_Man_t * p )
|
||||
{
|
||||
void * pMemory;
|
||||
int i;
|
||||
Vec_PtrForEachEntry( p->vChunks, pMemory, i )
|
||||
free( pMemory );
|
||||
Vec_PtrFree( p->vChunks );
|
||||
Vec_PtrFree( p->vPages );
|
||||
p->pListFree = NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates additional memory for the nodes.]
|
||||
|
||||
Description [Allocates IVY_PAGE_SIZE nodes. Aligns memory by 32 bytes.
|
||||
Records the pointer to the AIG manager in the -1 entry.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManAddMemory( Ivy_Man_t * p )
|
||||
{
|
||||
char * pMemory;
|
||||
int i, nBytes;
|
||||
assert( sizeof(Ivy_Obj_t) <= 32 );
|
||||
assert( p->pListFree == NULL );
|
||||
assert( (Ivy_ManObjNum(p) & IVY_PAGE_MASK) == 0 );
|
||||
// allocate new memory page
|
||||
nBytes = sizeof(Ivy_Obj_t) * (1<<IVY_PAGE_SIZE) + 32;
|
||||
pMemory = ALLOC( char, nBytes );
|
||||
Vec_PtrPush( p->vChunks, pMemory );
|
||||
// align memory at the 32-byte boundary
|
||||
pMemory = pMemory + 32 - (((int)pMemory) & 31);
|
||||
// remember the manager in the first entry
|
||||
Vec_PtrPush( p->vPages, pMemory );
|
||||
// break the memory down into nodes
|
||||
p->pListFree = (Ivy_Obj_t *)pMemory;
|
||||
for ( i = 1; i <= IVY_PAGE_MASK; i++ )
|
||||
{
|
||||
*((char **)pMemory) = pMemory + sizeof(Ivy_Obj_t);
|
||||
pMemory += sizeof(Ivy_Obj_t);
|
||||
}
|
||||
*((char **)pMemory) = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -34,8 +34,8 @@ struct Ivy_Eva_t_
|
|||
int Weight; // the number of covered nodes
|
||||
};
|
||||
|
||||
static void Ivy_MultiPrint( Ivy_Eva_t * pEvals, int nLeaves, int nEvals );
|
||||
static int Ivy_MultiCover( Ivy_Eva_t * pEvals, int nLeaves, int nEvals, int nLimit, Vec_Ptr_t * vSols );
|
||||
static void Ivy_MultiPrint( Ivy_Man_t * p, Ivy_Eva_t * pEvals, int nLeaves, int nEvals );
|
||||
static int Ivy_MultiCover( Ivy_Man_t * p, Ivy_Eva_t * pEvals, int nLeaves, int nEvals, int nLimit, Vec_Ptr_t * vSols );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -52,7 +52,7 @@ static int Ivy_MultiCover( Ivy_Eva_t * pEvals, int nLeaves, int nEvals, int nLim
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_MultiPlus( Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Type_t Type, int nLimit, Vec_Ptr_t * vSols )
|
||||
int Ivy_MultiPlus( Ivy_Man_t * p, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Type_t Type, int nLimit, Vec_Ptr_t * vSols )
|
||||
{
|
||||
static Ivy_Eva_t pEvals[IVY_EVAL_LIMIT];
|
||||
Ivy_Eva_t * pEval, * pFan0, * pFan1;
|
||||
|
|
@ -122,7 +122,7 @@ int Ivy_MultiPlus( Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Type_t Type, int
|
|||
{
|
||||
pFan0 = pEvals + i;
|
||||
pFan1 = pEvals + k;
|
||||
pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pFan0->pArg, pFan1->pArg, Type, IVY_INIT_NONE));
|
||||
pTemp = Ivy_TableLookup(p, Ivy_ObjCreateGhost(p, pFan0->pArg, pFan1->pArg, Type, IVY_INIT_NONE));
|
||||
// skip nodes in the cone
|
||||
if ( pTemp == NULL || pTemp->fMarkB )
|
||||
continue;
|
||||
|
|
@ -149,7 +149,7 @@ int Ivy_MultiPlus( Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Type_t Type, int
|
|||
Outside:
|
||||
|
||||
// Ivy_MultiPrint( pEvals, nLeaves, nEvals );
|
||||
if ( !Ivy_MultiCover( pEvals, nLeaves, nEvals, nLimit, vSols ) )
|
||||
if ( !Ivy_MultiCover( p, pEvals, nLeaves, nEvals, nLimit, vSols ) )
|
||||
return 0;
|
||||
assert( Vec_PtrSize( vSols ) > 0 );
|
||||
return 1;
|
||||
|
|
@ -166,7 +166,7 @@ Outside:
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_MultiPrint( Ivy_Eva_t * pEvals, int nLeaves, int nEvals )
|
||||
void Ivy_MultiPrint( Ivy_Man_t * p, Ivy_Eva_t * pEvals, int nLeaves, int nEvals )
|
||||
{
|
||||
Ivy_Eva_t * pEval;
|
||||
int i, k;
|
||||
|
|
@ -215,7 +215,7 @@ static inline int Ivy_MultiWeight( unsigned uMask, int nMaskOnes, unsigned uFoun
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_MultiCover( Ivy_Eva_t * pEvals, int nLeaves, int nEvals, int nLimit, Vec_Ptr_t * vSols )
|
||||
int Ivy_MultiCover( Ivy_Man_t * p, Ivy_Eva_t * pEvals, int nLeaves, int nEvals, int nLimit, Vec_Ptr_t * vSols )
|
||||
{
|
||||
int fVerbose = 0;
|
||||
Ivy_Eva_t * pEval, * pEvalBest;
|
||||
|
|
@ -294,6 +294,45 @@ int Ivy_MultiCover( Ivy_Eva_t * pEvals, int nLeaves, int nEvals, int nLimit, Vec
|
|||
}
|
||||
}
|
||||
|
||||
/**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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -39,36 +39,54 @@
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_ObjCreate( Ivy_Obj_t * pGhost )
|
||||
Ivy_Obj_t * Ivy_ObjCreatePi( Ivy_Man_t * p )
|
||||
{
|
||||
return Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, NULL, NULL, IVY_PI, IVY_INIT_NONE) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create the new node assuming it does not exist.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_ObjCreatePo( Ivy_Man_t * p, Ivy_Obj_t * pDriver )
|
||||
{
|
||||
return Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, pDriver, NULL, IVY_PO, IVY_INIT_NONE) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create the new node assuming it does not exist.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_ObjCreate( Ivy_Man_t * p, Ivy_Obj_t * pGhost )
|
||||
{
|
||||
Ivy_Man_t * p = Ivy_ObjMan(pGhost);
|
||||
Ivy_Obj_t * pObj;
|
||||
assert( !Ivy_IsComplement(pGhost) );
|
||||
assert( Ivy_ObjIsGhost(pGhost) );
|
||||
|
||||
assert( Ivy_TableLookup(pGhost) == NULL );
|
||||
|
||||
// realloc the node array
|
||||
if ( p->ObjIdNext == p->nObjsAlloc )
|
||||
{
|
||||
printf( "AIG manager is being resized. In the current release, it is not allowed!\n" );
|
||||
Ivy_ManGrow( p );
|
||||
pGhost = Ivy_ManGhost( p );
|
||||
}
|
||||
assert( Ivy_TableLookup(p, pGhost) == NULL );
|
||||
// get memory for the new object
|
||||
if ( Vec_IntSize(p->vFree) > 0 )
|
||||
pObj = p->pObjs + Vec_IntPop(p->vFree);
|
||||
else
|
||||
pObj = p->pObjs + p->ObjIdNext++;
|
||||
assert( pObj->Id == pObj - p->pObjs );
|
||||
pObj = Ivy_ManFetchMemory( p );
|
||||
assert( Ivy_ObjIsNone(pObj) );
|
||||
pObj->Id = Vec_PtrSize(p->vObjs);
|
||||
Vec_PtrPush( p->vObjs, pObj );
|
||||
// add basic info (fanins, compls, type, init)
|
||||
Ivy_ObjOverwrite( pObj, pGhost );
|
||||
// increment references of the fanins
|
||||
Ivy_ObjRefsInc( Ivy_ObjFanin0(pObj) );
|
||||
Ivy_ObjRefsInc( Ivy_ObjFanin1(pObj) );
|
||||
// add the node to the structural hash table
|
||||
Ivy_TableInsert( pObj );
|
||||
pObj->Type = pGhost->Type;
|
||||
pObj->Init = pGhost->Init;
|
||||
// add connections
|
||||
Ivy_ObjConnect( p, pObj, pGhost->pFanin0, pGhost->pFanin1 );
|
||||
// compute level
|
||||
if ( Ivy_ObjIsNode(pObj) )
|
||||
pObj->Level = Ivy_ObjLevelNew(pObj);
|
||||
|
|
@ -86,44 +104,19 @@ Ivy_Obj_t * Ivy_ObjCreate( Ivy_Obj_t * pGhost )
|
|||
}
|
||||
// add PIs/POs to the arrays
|
||||
if ( Ivy_ObjIsPi(pObj) )
|
||||
Vec_IntPush( p->vPis, pObj->Id );
|
||||
Vec_PtrPush( p->vPis, pObj );
|
||||
else if ( Ivy_ObjIsPo(pObj) )
|
||||
Vec_IntPush( p->vPos, pObj->Id );
|
||||
Vec_PtrPush( p->vPos, pObj );
|
||||
// else if ( Ivy_ObjIsBuf(pObj) )
|
||||
// Vec_PtrPush( p->vBufs, pObj );
|
||||
if ( p->vRequired && Vec_IntSize(p->vRequired) <= pObj->Id )
|
||||
Vec_IntFillExtra( p->vRequired, 2 * Vec_IntSize(p->vRequired), 1000000 );
|
||||
// update node counters of the manager
|
||||
p->nObjs[Ivy_ObjType(pObj)]++;
|
||||
p->nCreated++;
|
||||
return pObj;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create the new node assuming it does not exist.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_ObjCreateExt( Ivy_Man_t * p, Ivy_Type_t Type )
|
||||
{
|
||||
Ivy_Obj_t * pObj;
|
||||
assert( Type == IVY_ANDM || Type == IVY_EXORM || Type == IVY_LUT );
|
||||
// realloc the node array
|
||||
if ( p->ObjIdNext == p->nObjsAlloc )
|
||||
Ivy_ManGrow( p );
|
||||
// create the new node
|
||||
pObj = p->pObjs + p->ObjIdNext;
|
||||
assert( pObj->Id == p->ObjIdNext );
|
||||
p->ObjIdNext++;
|
||||
pObj->Type = Type;
|
||||
// update node counters of the manager
|
||||
p->nObjs[Type]++;
|
||||
p->nCreated++;
|
||||
return pObj;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Connect the object to the fanin.]
|
||||
|
|
@ -135,18 +128,94 @@ Ivy_Obj_t * Ivy_ObjCreateExt( Ivy_Man_t * p, Ivy_Type_t Type )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjConnect( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanin )
|
||||
void Ivy_ObjConnect( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFan0, Ivy_Obj_t * pFan1 )
|
||||
{
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
assert( Ivy_ObjIsOneFanin(pObj) );
|
||||
assert( Ivy_ObjFaninId0(pObj) == 0 );
|
||||
assert( Ivy_ObjIsPi(pObj) || Ivy_ObjIsOneFanin(pObj) || pFan1 != NULL );
|
||||
// add the first fanin
|
||||
pObj->fComp0 = Ivy_IsComplement(pFanin);
|
||||
pObj->Fanin0 = Ivy_Regular(pFanin)->Id;
|
||||
// increment references of the fanins
|
||||
Ivy_ObjRefsInc( Ivy_ObjFanin0(pObj) );
|
||||
pObj->pFanin0 = pFan0;
|
||||
pObj->pFanin1 = pFan1;
|
||||
// increment references of the fanins and add their fanouts
|
||||
if ( Ivy_ObjFanin0(pObj) != NULL )
|
||||
{
|
||||
Ivy_ObjRefsInc( Ivy_ObjFanin0(pObj) );
|
||||
if ( p->vFanouts )
|
||||
Ivy_ObjAddFanout( p, Ivy_ObjFanin0(pObj), pObj );
|
||||
}
|
||||
if ( Ivy_ObjFanin1(pObj) != NULL )
|
||||
{
|
||||
Ivy_ObjRefsInc( Ivy_ObjFanin1(pObj) );
|
||||
if ( p->vFanouts )
|
||||
Ivy_ObjAddFanout( p, Ivy_ObjFanin1(pObj), pObj );
|
||||
}
|
||||
// add the node to the structural hash table
|
||||
Ivy_TableInsert( pObj );
|
||||
Ivy_TableInsert( p, pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Connect the object to the fanin.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjDisconnect( Ivy_Man_t * p, Ivy_Obj_t * pObj )
|
||||
{
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
assert( Ivy_ObjIsPi(pObj) || Ivy_ObjIsOneFanin(pObj) || Ivy_ObjFanin1(pObj) != NULL );
|
||||
// remove connections
|
||||
if ( Ivy_ObjFanin0(pObj) != NULL )
|
||||
{
|
||||
Ivy_ObjRefsDec(Ivy_ObjFanin0(pObj));
|
||||
if ( p->vFanouts )
|
||||
Ivy_ObjDeleteFanout( p, Ivy_ObjFanin0(pObj), pObj );
|
||||
}
|
||||
if ( Ivy_ObjFanin1(pObj) != NULL )
|
||||
{
|
||||
Ivy_ObjRefsDec(Ivy_ObjFanin1(pObj));
|
||||
if ( p->vFanouts )
|
||||
Ivy_ObjDeleteFanout( p, Ivy_ObjFanin1(pObj), pObj );
|
||||
}
|
||||
// remove the node from the structural hash table
|
||||
Ivy_TableDelete( p, pObj );
|
||||
// add the first fanin
|
||||
pObj->pFanin0 = NULL;
|
||||
pObj->pFanin1 = NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Replaces the first fanin of the node by the new fanin.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjPatchFanin0( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFaninNew )
|
||||
{
|
||||
Ivy_Obj_t * pFaninOld;
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
pFaninOld = Ivy_ObjFanin0(pObj);
|
||||
// decrement ref and remove fanout
|
||||
Ivy_ObjRefsDec( pFaninOld );
|
||||
if ( p->vFanouts )
|
||||
Ivy_ObjDeleteFanout( p, pFaninOld, pObj );
|
||||
// increment ref and add fanout
|
||||
Ivy_ObjRefsInc( Ivy_Regular(pFaninNew) );
|
||||
if ( p->vFanouts )
|
||||
Ivy_ObjAddFanout( p, Ivy_Regular(pFaninNew), pObj );
|
||||
// update the fanin
|
||||
pObj->pFanin0 = pFaninNew;
|
||||
// get rid of old fanin
|
||||
if ( !Ivy_ObjIsPi(pFaninOld) && Ivy_ObjRefs(pFaninOld) == 0 )
|
||||
Ivy_ObjDelete_rec( p, pFaninOld, 1 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -160,33 +229,35 @@ void Ivy_ObjConnect( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanin )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjDelete( Ivy_Obj_t * pObj, int fFreeTop )
|
||||
void Ivy_ObjDelete( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop )
|
||||
{
|
||||
Ivy_Man_t * p;
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
assert( Ivy_ObjRefs(pObj) == 0 );
|
||||
// remove connections
|
||||
Ivy_ObjRefsDec(Ivy_ObjFanin0(pObj));
|
||||
Ivy_ObjRefsDec(Ivy_ObjFanin1(pObj));
|
||||
// remove the node from the structural hash table
|
||||
Ivy_TableDelete( pObj );
|
||||
assert( Ivy_ObjRefs(pObj) == 0 || !fFreeTop );
|
||||
// update node counters of the manager
|
||||
p = Ivy_ObjMan(pObj);
|
||||
p->nObjs[pObj->Type]--;
|
||||
p->nDeleted++;
|
||||
// remove connections
|
||||
Ivy_ObjDisconnect( p, pObj );
|
||||
// remove PIs/POs from the arrays
|
||||
if ( Ivy_ObjIsPi(pObj) )
|
||||
Vec_IntRemove( p->vPis, pObj->Id );
|
||||
Vec_PtrRemove( p->vPis, pObj );
|
||||
else if ( Ivy_ObjIsPo(pObj) )
|
||||
Vec_IntRemove( p->vPos, pObj->Id );
|
||||
// recorde the deleted node
|
||||
if ( p->fRecording )
|
||||
Ivy_ManUndoRecord( p, pObj );
|
||||
// clean the node's memory
|
||||
Ivy_ObjClean( pObj );
|
||||
// remember the entry
|
||||
Vec_PtrRemove( p->vPos, pObj );
|
||||
else if ( p->vFanouts && Ivy_ObjIsBuf(pObj) )
|
||||
Vec_PtrRemove( p->vBufs, pObj );
|
||||
// clean and recycle the entry
|
||||
if ( fFreeTop )
|
||||
Vec_IntPush( p->vFree, pObj->Id );
|
||||
{
|
||||
// free the node
|
||||
Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL );
|
||||
Ivy_ManRecycleMemory( p, pObj );
|
||||
}
|
||||
else
|
||||
{
|
||||
int nRefsOld = pObj->nRefs;
|
||||
Ivy_ObjClean( pObj );
|
||||
pObj->nRefs = nRefsOld;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -200,20 +271,20 @@ void Ivy_ObjDelete( Ivy_Obj_t * pObj, int fFreeTop )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjDelete_rec( Ivy_Obj_t * pObj, int fFreeTop )
|
||||
void Ivy_ObjDelete_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop )
|
||||
{
|
||||
Ivy_Obj_t * pFanin0, * pFanin1;
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
assert( !Ivy_ObjIsPo(pObj) && !Ivy_ObjIsNone(pObj) );
|
||||
assert( !Ivy_ObjIsNone(pObj) );
|
||||
if ( Ivy_ObjIsConst1(pObj) || Ivy_ObjIsPi(pObj) )
|
||||
return;
|
||||
pFanin0 = Ivy_ObjFanin0(pObj);
|
||||
pFanin1 = Ivy_ObjFanin1(pObj);
|
||||
Ivy_ObjDelete( pObj, fFreeTop );
|
||||
if ( !Ivy_ObjIsNone(pFanin0) && Ivy_ObjRefs(pFanin0) == 0 )
|
||||
Ivy_ObjDelete_rec( pFanin0, 1 );
|
||||
if ( !Ivy_ObjIsNone(pFanin1) && Ivy_ObjRefs(pFanin1) == 0 )
|
||||
Ivy_ObjDelete_rec( pFanin1, 1 );
|
||||
Ivy_ObjDelete( p, pObj, fFreeTop );
|
||||
if ( pFanin0 && !Ivy_ObjIsNone(pFanin0) && Ivy_ObjRefs(pFanin0) == 0 )
|
||||
Ivy_ObjDelete_rec( p, pFanin0, 1 );
|
||||
if ( pFanin1 && !Ivy_ObjIsNone(pFanin1) && Ivy_ObjRefs(pFanin1) == 0 )
|
||||
Ivy_ObjDelete_rec( p, pFanin1, 1 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -229,66 +300,61 @@ void Ivy_ObjDelete_rec( Ivy_Obj_t * pObj, int fFreeTop )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjReplace( Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop )
|
||||
void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop )
|
||||
{
|
||||
int nRefsOld;
|
||||
// the object to be replaced cannot be complemented
|
||||
assert( !Ivy_IsComplement(pObjOld) );
|
||||
// the object to be replaced cannot be a terminal
|
||||
assert( Ivy_ObjIsNone(pObjOld) || !Ivy_ObjIsTerm(pObjOld) );
|
||||
assert( Ivy_ObjIsNone(pObjOld) || !Ivy_ObjIsPi(pObjOld) );
|
||||
// the object to be used cannot be a PO or assert
|
||||
assert( !Ivy_ObjIsPo(Ivy_Regular(pObjNew)) );
|
||||
assert( !Ivy_ObjIsBuf(Ivy_Regular(pObjNew)) );
|
||||
// the object cannot be the same
|
||||
assert( pObjOld != Ivy_Regular(pObjNew) );
|
||||
// if the new object is complemented or already used, add the buffer
|
||||
if ( Ivy_IsComplement(pObjNew) || Ivy_ObjRefs(pObjNew) > 0 || Ivy_ObjIsPi(pObjNew) || Ivy_ObjIsConst1(pObjNew) )
|
||||
pObjNew = Ivy_ObjCreate( Ivy_ObjCreateGhost(pObjNew, Ivy_ObjConst1(pObjOld), IVY_BUF, IVY_INIT_NONE) );
|
||||
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) );
|
||||
// remember the reference counter
|
||||
nRefsOld = pObjOld->nRefs;
|
||||
pObjOld->nRefs = 0;
|
||||
// if the new node's arrival time is different, recursively update arrival time of the fanouts
|
||||
if ( p->vFanouts && !Ivy_ObjIsBuf(pObjNew) && pObjOld->Level != pObjNew->Level )
|
||||
{
|
||||
assert( Ivy_ObjIsNode(pObjOld) );
|
||||
pObjOld->Level = pObjNew->Level;
|
||||
Ivy_ObjUpdateLevel_rec( p, pObjOld );
|
||||
}
|
||||
// if the new node's required time has changed, recursively update required time of the fanins
|
||||
if ( p->vRequired )
|
||||
{
|
||||
int ReqNew = Vec_IntEntry(p->vRequired, pObjOld->Id);
|
||||
if ( ReqNew < Vec_IntEntry(p->vRequired, pObjNew->Id) )
|
||||
{
|
||||
Vec_IntWriteEntry( p->vRequired, pObjNew->Id, ReqNew );
|
||||
Ivy_ObjUpdateLevelR_rec( p, pObjNew, ReqNew );
|
||||
}
|
||||
}
|
||||
// delete the old object
|
||||
if ( fDeleteOld )
|
||||
Ivy_ObjDelete_rec( pObjOld, fFreeTop );
|
||||
Ivy_ObjDelete_rec( p, pObjOld, fFreeTop );
|
||||
// transfer the old object
|
||||
assert( Ivy_ObjRefs(pObjNew) == 0 );
|
||||
nRefsOld = pObjOld->nRefs;
|
||||
Ivy_ObjOverwrite( pObjOld, pObjNew );
|
||||
pObjOld->nRefs = nRefsOld;
|
||||
// patch the fanout of the fanins
|
||||
if ( p->vFanouts )
|
||||
{
|
||||
Ivy_ObjPatchFanout( p, Ivy_ObjFanin0(pObjOld), pObjNew, pObjOld );
|
||||
if ( Ivy_ObjFanin1(pObjOld) )
|
||||
Ivy_ObjPatchFanout( p, Ivy_ObjFanin1(pObjOld), pObjNew, pObjOld );
|
||||
}
|
||||
// update the hash table
|
||||
Ivy_TableUpdate( pObjNew, pObjOld->Id );
|
||||
// create the object that was taken over by pObjOld
|
||||
Ivy_ObjClean( pObjNew );
|
||||
// remember the entry
|
||||
Vec_IntPush( Ivy_ObjMan(pObjOld)->vFree, pObjNew->Id );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the first real fanins (not a buffer/inverter).]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_NodeRealFanin_rec( Ivy_Obj_t * pNode, int iFanin )
|
||||
{
|
||||
if ( iFanin == 0 )
|
||||
{
|
||||
if ( Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) )
|
||||
return Ivy_NotCond( Ivy_NodeRealFanin_rec(Ivy_ObjFanin0(pNode), 0), Ivy_ObjFaninC0(pNode) );
|
||||
else
|
||||
return Ivy_ObjChild0(pNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) )
|
||||
return Ivy_NotCond( Ivy_NodeRealFanin_rec(Ivy_ObjFanin1(pNode), 0), Ivy_ObjFaninC1(pNode) );
|
||||
else
|
||||
return Ivy_ObjChild1(pNode);
|
||||
}
|
||||
Ivy_TableUpdate( p, pObjNew, pObjOld->Id );
|
||||
// recycle the object that was taken over by pObjOld
|
||||
Vec_PtrWriteEntry( p->vObjs, pObjNew->Id, NULL );
|
||||
Ivy_ManRecycleMemory( p, pObjNew );
|
||||
// if the new node is the buffer propagate it
|
||||
if ( p->vFanouts && Ivy_ObjIsBuf(pObjOld) )
|
||||
Vec_PtrPush( p->vBufs, pObjOld );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -304,19 +370,31 @@ Ivy_Obj_t * Ivy_NodeRealFanin_rec( Ivy_Obj_t * pNode, int iFanin )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_NodeFixBufferFanins( Ivy_Obj_t * pNode )
|
||||
void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode )
|
||||
{
|
||||
Ivy_Obj_t * pFanReal0, * pFanReal1, * pResult;
|
||||
assert( Ivy_ObjIsNode(pNode) );
|
||||
if ( Ivy_ObjIsPo(pNode) )
|
||||
{
|
||||
if ( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) )
|
||||
return;
|
||||
pFanReal0 = Ivy_ObjReal( Ivy_ObjChild0(pNode) );
|
||||
Ivy_ObjPatchFanin0( p, pNode, pFanReal0 );
|
||||
return;
|
||||
}
|
||||
if ( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) && !Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) )
|
||||
return;
|
||||
// get the real fanins
|
||||
pFanReal0 = Ivy_NodeRealFanin_rec( pNode, 0 );
|
||||
pFanReal1 = Ivy_NodeRealFanin_rec( pNode, 1 );
|
||||
pFanReal0 = Ivy_ObjReal( Ivy_ObjChild0(pNode) );
|
||||
pFanReal1 = Ivy_ObjReal( Ivy_ObjChild1(pNode) );
|
||||
// get the new node
|
||||
pResult = Ivy_Oper( pFanReal0, pFanReal1, Ivy_ObjType(pNode) );
|
||||
if ( Ivy_ObjIsNode(pNode) )
|
||||
pResult = Ivy_Oper( p, pFanReal0, pFanReal1, Ivy_ObjType(pNode) );
|
||||
else if ( Ivy_ObjIsLatch(pNode) )
|
||||
pResult = Ivy_Latch( p, pFanReal0, Ivy_ObjInit(pNode) );
|
||||
else
|
||||
assert( 0 );
|
||||
// perform the replacement
|
||||
Ivy_ObjReplace( pNode, pResult, 1, 0 );
|
||||
Ivy_ObjReplace( p, pNode, pResult, 1, 0 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -57,12 +57,12 @@ static inline int Ivy_ObjIsExorType( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Obj_t *
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Oper( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type )
|
||||
Ivy_Obj_t * Ivy_Oper( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type )
|
||||
{
|
||||
if ( Type == IVY_AND )
|
||||
return Ivy_And( p0, p1 );
|
||||
return Ivy_And( p, p0, p1 );
|
||||
if ( Type == IVY_EXOR )
|
||||
return Ivy_Exor( p0, p1 );
|
||||
return Ivy_Exor( p, p0, p1 );
|
||||
assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -78,23 +78,22 @@ Ivy_Obj_t * Ivy_Oper( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_And( Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
|
||||
Ivy_Obj_t * Ivy_And( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
|
||||
{
|
||||
Ivy_Obj_t * pConst1 = Ivy_ObjConst1(Ivy_Regular(p0));
|
||||
// Ivy_Obj_t * pFan0, * pFan1;
|
||||
// check trivial cases
|
||||
if ( p0 == p1 )
|
||||
return p0;
|
||||
if ( p0 == Ivy_Not(p1) )
|
||||
return Ivy_Not(pConst1);
|
||||
if ( Ivy_Regular(p0) == pConst1 )
|
||||
return p0 == pConst1 ? p1 : Ivy_Not(pConst1);
|
||||
if ( Ivy_Regular(p1) == pConst1 )
|
||||
return p1 == pConst1 ? p0 : Ivy_Not(pConst1);
|
||||
return Ivy_Not(p->pConst1);
|
||||
if ( Ivy_Regular(p0) == p->pConst1 )
|
||||
return p0 == p->pConst1 ? p1 : Ivy_Not(p->pConst1);
|
||||
if ( Ivy_Regular(p1) == p->pConst1 )
|
||||
return p1 == p->pConst1 ? p0 : Ivy_Not(p->pConst1);
|
||||
// check if it can be an EXOR gate
|
||||
// if ( Ivy_ObjIsExorType( p0, p1, &pFan0, &pFan1 ) )
|
||||
// return Ivy_CanonExor( pFan0, pFan1 );
|
||||
return Ivy_CanonAnd( p0, p1 );
|
||||
return Ivy_CanonAnd( p, p0, p1 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -108,36 +107,22 @@ Ivy_Obj_t * Ivy_And( Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Exor( Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
|
||||
Ivy_Obj_t * Ivy_Exor( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
|
||||
{
|
||||
Ivy_Obj_t * pConst1 = Ivy_ObjConst1(Ivy_Regular(p0));
|
||||
/*
|
||||
// check trivial cases
|
||||
if ( p0 == p1 )
|
||||
return Ivy_Not(pConst1);
|
||||
return Ivy_Not(p->pConst1);
|
||||
if ( p0 == Ivy_Not(p1) )
|
||||
return pConst1;
|
||||
if ( Ivy_Regular(p0) == pConst1 )
|
||||
return Ivy_NotCond( p1, p0 == pConst1 );
|
||||
if ( Ivy_Regular(p1) == pConst1 )
|
||||
return Ivy_NotCond( p0, p1 == pConst1 );
|
||||
return p->pConst1;
|
||||
if ( Ivy_Regular(p0) == p->pConst1 )
|
||||
return Ivy_NotCond( p1, p0 == p->pConst1 );
|
||||
if ( Ivy_Regular(p1) == p->pConst1 )
|
||||
return Ivy_NotCond( p0, p1 == p->pConst1 );
|
||||
// check the table
|
||||
return Ivy_CanonExor( p0, p1 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs canonicization step.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Latch( Ivy_Obj_t * pObj, Ivy_Init_t Init )
|
||||
{
|
||||
return Ivy_CanonLatch( pObj, Init );
|
||||
return Ivy_CanonExor( p, p0, p1 );
|
||||
*/
|
||||
return Ivy_Or( p, Ivy_And(p, p0, Ivy_Not(p1)), Ivy_And(p, Ivy_Not(p0), p1) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -151,9 +136,9 @@ Ivy_Obj_t * Ivy_Latch( Ivy_Obj_t * pObj, Ivy_Init_t Init )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Or( Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
|
||||
Ivy_Obj_t * Ivy_Or( Ivy_Man_t * p, Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
|
||||
{
|
||||
return Ivy_Not( Ivy_And( Ivy_Not(p0), Ivy_Not(p1) ) );
|
||||
return Ivy_Not( Ivy_And( p, Ivy_Not(p0), Ivy_Not(p1) ) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -167,43 +152,42 @@ Ivy_Obj_t * Ivy_Or( Ivy_Obj_t * p0, Ivy_Obj_t * p1 )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Mux( Ivy_Obj_t * pC, Ivy_Obj_t * p1, Ivy_Obj_t * p0 )
|
||||
Ivy_Obj_t * Ivy_Mux( Ivy_Man_t * p, Ivy_Obj_t * pC, Ivy_Obj_t * p1, Ivy_Obj_t * p0 )
|
||||
{
|
||||
Ivy_Obj_t * pConst1 = Ivy_ObjConst1(Ivy_Regular(p0));
|
||||
Ivy_Obj_t * pTempA1, * pTempA2, * pTempB1, * pTempB2, * pTemp;
|
||||
int Count0, Count1;
|
||||
// consider trivial cases
|
||||
if ( p0 == Ivy_Not(p1) )
|
||||
return Ivy_Exor( pC, p0 );
|
||||
return Ivy_Exor( p, pC, p0 );
|
||||
// other cases can be added
|
||||
// implement the first MUX (F = C * x1 + C' * x0)
|
||||
pTempA1 = Ivy_TableLookup( Ivy_ObjCreateGhost(pC, p1, IVY_AND, IVY_INIT_NONE) );
|
||||
pTempA2 = Ivy_TableLookup( Ivy_ObjCreateGhost(Ivy_Not(pC), p0, IVY_AND, IVY_INIT_NONE) );
|
||||
pTempA1 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, pC, p1, IVY_AND, IVY_INIT_NONE) );
|
||||
pTempA2 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Not(pC), p0, IVY_AND, IVY_INIT_NONE) );
|
||||
if ( pTempA1 && pTempA2 )
|
||||
{
|
||||
pTemp = Ivy_TableLookup( Ivy_ObjCreateGhost(Ivy_Not(pTempA1), Ivy_Not(pTempA2), IVY_AND, IVY_INIT_NONE) );
|
||||
pTemp = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Not(pTempA1), Ivy_Not(pTempA2), IVY_AND, IVY_INIT_NONE) );
|
||||
if ( pTemp ) return Ivy_Not(pTemp);
|
||||
}
|
||||
Count0 = (pTempA1 != NULL) + (pTempA2 != NULL);
|
||||
// implement the second MUX (F' = C * x1' + C' * x0')
|
||||
pTempB1 = Ivy_TableLookup( Ivy_ObjCreateGhost(pC, Ivy_Not(p1), IVY_AND, IVY_INIT_NONE) );
|
||||
pTempB2 = Ivy_TableLookup( Ivy_ObjCreateGhost(Ivy_Not(pC), Ivy_Not(p0), IVY_AND, IVY_INIT_NONE) );
|
||||
pTempB1 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, pC, Ivy_Not(p1), IVY_AND, IVY_INIT_NONE) );
|
||||
pTempB2 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Not(pC), Ivy_Not(p0), IVY_AND, IVY_INIT_NONE) );
|
||||
if ( pTempB1 && pTempB2 )
|
||||
{
|
||||
pTemp = Ivy_TableLookup( Ivy_ObjCreateGhost(Ivy_Not(pTempB1), Ivy_Not(pTempB2), IVY_AND, IVY_INIT_NONE) );
|
||||
pTemp = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Not(pTempB1), Ivy_Not(pTempB2), IVY_AND, IVY_INIT_NONE) );
|
||||
if ( pTemp ) return pTemp;
|
||||
}
|
||||
Count1 = (pTempB1 != NULL) + (pTempB2 != NULL);
|
||||
// compare and decide which one to implement
|
||||
if ( Count0 >= Count1 )
|
||||
{
|
||||
pTempA1 = pTempA1? pTempA1 : Ivy_And(pC, p1);
|
||||
pTempA2 = pTempA2? pTempA2 : Ivy_And(Ivy_Not(pC), p0);
|
||||
return Ivy_Or( pTempA1, pTempA2 );
|
||||
pTempA1 = pTempA1? pTempA1 : Ivy_And(p, pC, p1);
|
||||
pTempA2 = pTempA2? pTempA2 : Ivy_And(p, Ivy_Not(pC), p0);
|
||||
return Ivy_Or( p, pTempA1, pTempA2 );
|
||||
}
|
||||
pTempB1 = pTempB1? pTempB1 : Ivy_And(pC, Ivy_Not(p1));
|
||||
pTempB2 = pTempB2? pTempB2 : Ivy_And(Ivy_Not(pC), Ivy_Not(p0));
|
||||
return Ivy_Not( Ivy_Or( pTempB1, pTempB2 ) );
|
||||
pTempB1 = pTempB1? pTempB1 : Ivy_And(p, pC, Ivy_Not(p1));
|
||||
pTempB2 = pTempB2? pTempB2 : Ivy_And(p, Ivy_Not(pC), Ivy_Not(p0));
|
||||
return Ivy_Not( Ivy_Or( p, pTempB1, pTempB2 ) );
|
||||
|
||||
// return Ivy_Or( Ivy_And(pC, p1), Ivy_And(Ivy_Not(pC), p0) );
|
||||
}
|
||||
|
|
@ -219,9 +203,9 @@ Ivy_Obj_t * Ivy_Mux( Ivy_Obj_t * pC, Ivy_Obj_t * p1, Ivy_Obj_t * p0 )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Maj( Ivy_Obj_t * pA, Ivy_Obj_t * pB, Ivy_Obj_t * pC )
|
||||
Ivy_Obj_t * Ivy_Maj( Ivy_Man_t * p, Ivy_Obj_t * pA, Ivy_Obj_t * pB, Ivy_Obj_t * pC )
|
||||
{
|
||||
return Ivy_Or( Ivy_Or(Ivy_And(pA, pB), Ivy_And(pA, pC)), Ivy_And(pB, pC) );
|
||||
return Ivy_Or( p, Ivy_Or(p, Ivy_And(p, pA, pB), Ivy_And(p, pA, pC)), Ivy_And(p, pB, pC) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -235,16 +219,32 @@ Ivy_Obj_t * Ivy_Maj( Ivy_Obj_t * pA, Ivy_Obj_t * pB, Ivy_Obj_t * pC )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Miter( Vec_Ptr_t * vPairs )
|
||||
Ivy_Obj_t * Ivy_Miter( Ivy_Man_t * p, Vec_Ptr_t * vPairs )
|
||||
{
|
||||
int i;
|
||||
assert( vPairs->nSize > 0 );
|
||||
assert( vPairs->nSize % 2 == 0 );
|
||||
// go through the cubes of the node's SOP
|
||||
for ( i = 0; i < vPairs->nSize; i += 2 )
|
||||
vPairs->pArray[i/2] = Ivy_Not( Ivy_Exor( vPairs->pArray[i], vPairs->pArray[i+1] ) );
|
||||
vPairs->pArray[i/2] = Ivy_Not( Ivy_Exor( p, vPairs->pArray[i], vPairs->pArray[i+1] ) );
|
||||
vPairs->nSize = vPairs->nSize/2;
|
||||
return Ivy_Not( Ivy_Multi_rec( (Ivy_Obj_t **)vPairs->pArray, vPairs->nSize, IVY_AND ) );
|
||||
return Ivy_Not( Ivy_Multi_rec( p, (Ivy_Obj_t **)vPairs->pArray, vPairs->nSize, IVY_AND ) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs canonicization step.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_Latch( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Init_t Init )
|
||||
{
|
||||
return Ivy_CanonLatch( p, pObj, Init );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -39,50 +39,59 @@
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Man_t * Ivy_ManResyn( Ivy_Man_t * pMan, int fUpdateLevel )
|
||||
Ivy_Man_t * Ivy_ManResyn( Ivy_Man_t * pMan, int fUpdateLevel, int fVerbose )
|
||||
{
|
||||
int clk, fVerbose = 0;
|
||||
int clk;
|
||||
Ivy_Man_t * pTemp;
|
||||
|
||||
if ( fVerbose ) { printf( "Original:\n" ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
|
||||
clk = clock();
|
||||
pMan = Ivy_ManBalance( pMan, fUpdateLevel );
|
||||
if ( fVerbose ) { printf( "\n" ); }
|
||||
if ( fVerbose ) { PRT( "Balance", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
|
||||
// Ivy_ManRewriteAlg( pMan, fUpdateLevel, 0 );
|
||||
clk = clock();
|
||||
Ivy_ManRewritePre( pMan, fUpdateLevel, 0, 0 );
|
||||
if ( fVerbose ) { printf( "\n" ); }
|
||||
if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
|
||||
clk = clock();
|
||||
pMan = Ivy_ManBalance( pTemp = pMan, fUpdateLevel );
|
||||
Ivy_ManStop( pTemp );
|
||||
if ( fVerbose ) { PRT( "Balance", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
|
||||
// Ivy_ManRewriteAlg( pMan, fUpdateLevel, 1 );
|
||||
clk = clock();
|
||||
if ( fVerbose ) Ivy_ManRewritePre( pMan, fUpdateLevel, 1, 0 );
|
||||
if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
|
||||
clk = clock();
|
||||
pMan = Ivy_ManBalance( pTemp = pMan, fUpdateLevel );
|
||||
Ivy_ManStop( pTemp );
|
||||
if ( fVerbose ) { printf( "\n" ); }
|
||||
if ( fVerbose ) { PRT( "Balance", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
|
||||
// Ivy_ManRewriteAlg( pMan, fUpdateLevel, 1 );
|
||||
clk = clock();
|
||||
Ivy_ManRewritePre( pMan, fUpdateLevel, 1, 0 );
|
||||
if ( fVerbose ) { printf( "\n" ); }
|
||||
if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
|
||||
clk = clock();
|
||||
pMan = Ivy_ManBalance( pTemp = pMan, fUpdateLevel );
|
||||
Ivy_ManStop( pTemp );
|
||||
if ( fVerbose ) { printf( "\n" ); }
|
||||
if ( fVerbose ) { PRT( "Balance", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
|
||||
// Ivy_ManRewriteAlg( pMan, fUpdateLevel, 1 );
|
||||
clk = clock();
|
||||
Ivy_ManRewritePre( pMan, fUpdateLevel, 1, 0 );
|
||||
if ( fVerbose ) { printf( "\n" ); }
|
||||
if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
|
||||
clk = clock();
|
||||
pMan = Ivy_ManBalance( pTemp = pMan, fUpdateLevel );
|
||||
Ivy_ManStop( pTemp );
|
||||
if ( fVerbose ) { printf( "\n" ); }
|
||||
if ( fVerbose ) { PRT( "Balance", clock() - clk ); }
|
||||
if ( fVerbose ) Ivy_ManPrintStats( pMan );
|
||||
return pMan;
|
||||
|
|
|
|||
|
|
@ -1,365 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ivyRewrite.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [And-Inverter Graph package.]
|
||||
|
||||
Synopsis [AIG rewriting.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: ivyRewrite.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "ivy.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static unsigned Ivy_ManSeqFindTruth( Ivy_Obj_t * pNode, Vec_Int_t * vFront );
|
||||
static void Ivy_ManSeqCollectCone( Ivy_Obj_t * pNode, Vec_Int_t * vCone );
|
||||
static int Ivy_ManSeqGetCost( Ivy_Man_t * p, Vec_Int_t * vCone );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs Boolean rewriting of sequential AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManSeqRewrite( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost )
|
||||
{
|
||||
Vec_Int_t * vNodes, * vFront, * vInside, * vTree;
|
||||
Ivy_Obj_t * pNode, * pNodeNew, * pTemp;
|
||||
int i, k, nCostOld, nCostInt, nCostInt2, nCostNew, RetValue, Entry, nRefsSaved, nInputs;
|
||||
int clk, clkCut = 0, clkTru = 0, clkDsd = 0, clkUpd = 0, clkStart = clock();
|
||||
unsigned uTruth;
|
||||
|
||||
nInputs = 4;
|
||||
vTree = Vec_IntAlloc( 8 );
|
||||
vFront = Vec_IntAlloc( 8 );
|
||||
vInside = Vec_IntAlloc( 50 );
|
||||
vNodes = Ivy_ManDfs( p );
|
||||
Ivy_ManForEachNodeVec( p, vNodes, pNode, i )
|
||||
{
|
||||
if ( Ivy_ObjIsBuf(pNode) )
|
||||
continue;
|
||||
// fix the fanin buffer problem
|
||||
Ivy_NodeFixBufferFanins( pNode );
|
||||
if ( Ivy_ObjIsBuf(pNode) )
|
||||
continue;
|
||||
|
||||
// find one sequential cut rooted at this node
|
||||
clk = clock();
|
||||
Ivy_ManSeqFindCut( pNode, vFront, vInside, nInputs );
|
||||
clkCut += clock() - clk;
|
||||
// compute the truth table of the cut
|
||||
clk = clock();
|
||||
uTruth = Ivy_ManSeqFindTruth( pNode, vFront );
|
||||
clkTru += clock() - clk;
|
||||
// decompose the truth table
|
||||
clk = clock();
|
||||
RetValue = Ivy_TruthDsd( uTruth, vTree );
|
||||
clkDsd += clock() - clk;
|
||||
if ( !RetValue )
|
||||
continue; // DSD does not exist
|
||||
// Ivy_TruthDsdPrint( stdout, vTree );
|
||||
|
||||
clk = clock();
|
||||
// remember the cost of the current network
|
||||
nCostOld = Ivy_ManGetCost(p);
|
||||
// increment references of the cut variables
|
||||
Vec_IntForEachEntry( vFront, Entry, k )
|
||||
{
|
||||
pTemp = Ivy_ManObj(p, Ivy_LeafId(Entry));
|
||||
Ivy_ObjRefsInc( pTemp );
|
||||
}
|
||||
// dereference and record undo
|
||||
nRefsSaved = pNode->nRefs; pNode->nRefs = 0;
|
||||
Ivy_ManUndoStart( p );
|
||||
Ivy_ObjDelete_rec( pNode, 0 );
|
||||
Ivy_ManUndoStop( p );
|
||||
pNode->nRefs = nRefsSaved;
|
||||
|
||||
// get the intermediate cost
|
||||
nCostInt = Ivy_ManGetCost(p);
|
||||
|
||||
// printf( "Removed by dereferencing = %d.\n", nCostOld - nCostInt );
|
||||
|
||||
// construct the new logic cone
|
||||
pNodeNew = Ivy_ManDsdConstruct( p, vFront, vTree );
|
||||
// remember the cost
|
||||
nCostNew = Ivy_ManGetCost(p);
|
||||
|
||||
// printf( "Added by dereferencing = %d.\n", nCostInt - nCostNew );
|
||||
// nCostNew = nCostNew;
|
||||
|
||||
/*
|
||||
if ( Ivy_Regular(pNodeNew)->nRefs == 0 )
|
||||
Ivy_ObjDelete_rec( Ivy_Regular(pNodeNew), 1 );
|
||||
// get the intermediate cost
|
||||
nCostInt2 = Ivy_ManGetCost(p);
|
||||
assert( nCostInt == nCostInt2 );
|
||||
|
||||
Ivy_ManUndoPerform( p, pNode );
|
||||
pNode->nRefs = nRefsSaved;
|
||||
|
||||
Vec_IntForEachEntry( vFront, Entry, k )
|
||||
{
|
||||
// pTemp = Ivy_ManObj(p, Ivy_LeafId(Entry));
|
||||
pTemp = Ivy_ManObj(p, Entry);
|
||||
Ivy_ObjRefsDec( pTemp );
|
||||
}
|
||||
clkUpd += clock() - clk;
|
||||
continue;
|
||||
*/
|
||||
|
||||
// detect the case when they are exactly the same
|
||||
// if ( pNodeNew == pNode )
|
||||
// continue;
|
||||
|
||||
// compare the costs
|
||||
if ( nCostOld > nCostNew || nCostOld == nCostNew && fUseZeroCost )
|
||||
{ // accept the change
|
||||
// printf( "NODES GAINED = %d\n", nCostOld - nCostNew );
|
||||
|
||||
Ivy_ObjReplace( pNode, pNodeNew, 0, 1 );
|
||||
pNode->nRefs = nRefsSaved;
|
||||
}
|
||||
else
|
||||
{ // reject change
|
||||
// printf( "Rejected\n" );
|
||||
|
||||
if ( Ivy_Regular(pNodeNew)->nRefs == 0 )
|
||||
Ivy_ObjDelete_rec( Ivy_Regular(pNodeNew), 1 );
|
||||
|
||||
// get the intermediate cost
|
||||
nCostInt2 = Ivy_ManGetCost(p);
|
||||
assert( nCostInt == nCostInt2 );
|
||||
|
||||
// reconstruct the old node
|
||||
Ivy_ManUndoPerform( p, pNode );
|
||||
pNode->nRefs = nRefsSaved;
|
||||
}
|
||||
// decrement references of the cut variables
|
||||
Vec_IntForEachEntry( vFront, Entry, k )
|
||||
{
|
||||
// pTemp = Ivy_ManObj(p, Ivy_LeafId(Entry));
|
||||
pTemp = Ivy_ManObj(p, Entry);
|
||||
if ( Ivy_ObjIsNone(pTemp) )
|
||||
continue;
|
||||
Ivy_ObjRefsDec( pTemp );
|
||||
if ( Ivy_ObjRefs(pTemp) == 0 )
|
||||
Ivy_ObjDelete_rec( pTemp, 1 );
|
||||
}
|
||||
|
||||
clkUpd += clock() - clk;
|
||||
}
|
||||
|
||||
PRT( "Cut ", clkCut );
|
||||
PRT( "Truth ", clkTru );
|
||||
PRT( "DSD ", clkDsd );
|
||||
PRT( "Update ", clkUpd );
|
||||
PRT( "TOTAL ", clock() - clkStart );
|
||||
|
||||
Vec_IntFree( vTree );
|
||||
Vec_IntFree( vFront );
|
||||
Vec_IntFree( vInside );
|
||||
Vec_IntFree( vNodes );
|
||||
|
||||
if ( !Ivy_ManCheck(p) )
|
||||
{
|
||||
printf( "Ivy_ManSeqRewrite(): The check has failed.\n" );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the truth table of the sequential cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Ivy_ManSeqFindTruth_rec( Ivy_Man_t * p, unsigned Node, Vec_Int_t * vFront )
|
||||
{
|
||||
static unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
|
||||
unsigned uTruth0, uTruth1;
|
||||
Ivy_Obj_t * pNode;
|
||||
int nLatches, Number;
|
||||
// consider the case of a constant
|
||||
if ( Node == 0 )
|
||||
return ~((unsigned)0);
|
||||
// try to find this node in the frontier
|
||||
Number = Vec_IntFind( vFront, Node );
|
||||
if ( Number >= 0 )
|
||||
return uMasks[Number];
|
||||
// get the node
|
||||
pNode = Ivy_ManObj( p, Ivy_LeafId(Node) );
|
||||
assert( !Ivy_ObjIsPi(pNode) && !Ivy_ObjIsConst1(pNode) );
|
||||
// get the number of latches
|
||||
nLatches = Ivy_LeafLat(Node) + Ivy_ObjIsLatch(pNode);
|
||||
// expand the first fanin
|
||||
uTruth0 = Ivy_ManSeqFindTruth_rec( p, Ivy_LeafCreate(Ivy_ObjFaninId0(pNode), nLatches), vFront );
|
||||
if ( Ivy_ObjFaninC0(pNode) )
|
||||
uTruth0 = ~uTruth0;
|
||||
// quit if this is the one fanin node
|
||||
if ( Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) )
|
||||
return uTruth0;
|
||||
assert( Ivy_ObjIsNode(pNode) );
|
||||
// expand the second fanin
|
||||
uTruth1 = Ivy_ManSeqFindTruth_rec( p, Ivy_LeafCreate(Ivy_ObjFaninId1(pNode), nLatches), vFront );
|
||||
if ( Ivy_ObjFaninC1(pNode) )
|
||||
uTruth1 = ~uTruth1;
|
||||
// return the truth table
|
||||
return Ivy_ObjIsAnd(pNode)? uTruth0 & uTruth1 : uTruth0 ^ uTruth1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the truth table of the sequential cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Ivy_ManSeqFindTruth( Ivy_Obj_t * pNode, Vec_Int_t * vFront )
|
||||
{
|
||||
assert( Ivy_ObjIsNode(pNode) );
|
||||
return Ivy_ManSeqFindTruth_rec( Ivy_ObjMan(pNode), Ivy_LeafCreate(pNode->Id, 0), vFront );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively dereferences the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManSeqDeref_rec( Ivy_Obj_t * pNode, Vec_Int_t * vCone )
|
||||
{
|
||||
Ivy_Obj_t * pFan;
|
||||
assert( !Ivy_IsComplement(pNode) );
|
||||
assert( !Ivy_ObjIsNone(pNode) );
|
||||
if ( Ivy_ObjIsPi(pNode) )
|
||||
return;
|
||||
// deref the first fanin
|
||||
pFan = Ivy_ObjFanin0(pNode);
|
||||
Ivy_ObjRefsDec( pFan );
|
||||
if ( Ivy_ObjRefs( pFan ) == 0 )
|
||||
Ivy_ManSeqDeref_rec( pFan, vCone );
|
||||
// deref the second fanin
|
||||
pFan = Ivy_ObjFanin1(pNode);
|
||||
Ivy_ObjRefsDec( pFan );
|
||||
if ( Ivy_ObjRefs( pFan ) == 0 )
|
||||
Ivy_ManSeqDeref_rec( pFan, vCone );
|
||||
// save the node
|
||||
Vec_IntPush( vCone, pNode->Id );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively references the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManSeqRef_rec( Ivy_Obj_t * pNode )
|
||||
{
|
||||
Ivy_Obj_t * pFan;
|
||||
assert( !Ivy_IsComplement(pNode) );
|
||||
assert( !Ivy_ObjIsNone(pNode) );
|
||||
if ( Ivy_ObjIsPi(pNode) )
|
||||
return;
|
||||
// ref the first fanin
|
||||
pFan = Ivy_ObjFanin0(pNode);
|
||||
if ( Ivy_ObjRefs( pFan ) == 0 )
|
||||
Ivy_ManSeqRef_rec( pFan );
|
||||
Ivy_ObjRefsInc( pFan );
|
||||
// ref the second fanin
|
||||
pFan = Ivy_ObjFanin1(pNode);
|
||||
if ( Ivy_ObjRefs( pFan ) == 0 )
|
||||
Ivy_ManSeqRef_rec( pFan );
|
||||
Ivy_ObjRefsInc( pFan );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect MFFC of the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManSeqCollectCone( Ivy_Obj_t * pNode, Vec_Int_t * vCone )
|
||||
{
|
||||
Vec_IntClear( vCone );
|
||||
Ivy_ManSeqDeref_rec( pNode, vCone );
|
||||
Ivy_ManSeqRef_rec( pNode );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cost of the logic cone.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManSeqGetCost( Ivy_Man_t * p, Vec_Int_t * vCone )
|
||||
{
|
||||
Ivy_Obj_t * pObj;
|
||||
int i, Cost = 0;
|
||||
Ivy_ManForEachNodeVec( p, vCone, pObj, i )
|
||||
{
|
||||
if ( Ivy_ObjIsAnd(pObj) )
|
||||
Cost += 1;
|
||||
else if ( Ivy_ObjIsExor(pObj) )
|
||||
Cost += 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -27,13 +27,13 @@
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static unsigned Ivy_NodeGetTruth( Ivy_Obj_t * pObj, int * pNums, int nNums );
|
||||
static int Ivy_NodeMffcLabel( Ivy_Obj_t * pObj );
|
||||
static int Rwt_NodeRewrite( Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel, int fUseZeroCost );
|
||||
static Dec_Graph_t * Rwt_CutEvaluate( Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut,
|
||||
static int Ivy_NodeMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
static int Ivy_NodeRewrite( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel, int fUseZeroCost );
|
||||
static Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut,
|
||||
Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth );
|
||||
|
||||
static int Ivy_GraphToNetworkCount( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax );
|
||||
static void Ivy_GraphUpdateNetwork( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
|
||||
static int Ivy_GraphToNetworkCount( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax );
|
||||
static void Ivy_GraphUpdateNetwork( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -58,29 +58,30 @@ int Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fV
|
|||
int clk, clkStart = clock();
|
||||
// start the rewriting manager
|
||||
pManRwt = Rwt_ManStart( 0 );
|
||||
p->pData = pManRwt;
|
||||
if ( pManRwt == NULL )
|
||||
return 0;
|
||||
return 0;
|
||||
// create fanouts
|
||||
if ( fUpdateLevel && p->vFanouts == NULL )
|
||||
Ivy_ManStartFanout( p );
|
||||
// compute the reverse levels if level update is requested
|
||||
if ( fUpdateLevel )
|
||||
Ivy_ManRequiredLevels( p );
|
||||
// set the number of levels
|
||||
// p->nLevelMax = Ivy_ManLevels( p );
|
||||
// resynthesize each node once
|
||||
nNodes = Ivy_ManObjIdNext( p );
|
||||
Ivy_ManForEachObj( p, pNode, i )
|
||||
nNodes = Ivy_ManObjIdMax(p);
|
||||
Ivy_ManForEachNode( p, pNode, i )
|
||||
{
|
||||
if ( !Ivy_ObjIsNode(pNode) )
|
||||
continue;
|
||||
// fix the fanin buffer problem
|
||||
Ivy_NodeFixBufferFanins( pNode );
|
||||
Ivy_NodeFixBufferFanins( p, pNode );
|
||||
if ( Ivy_ObjIsBuf(pNode) )
|
||||
continue;
|
||||
// stop if all nodes have been tried once
|
||||
if ( i >= nNodes )
|
||||
if ( i > nNodes )
|
||||
break;
|
||||
// skip the nodes with many fanouts
|
||||
// if ( Ivy_ObjRefs(pNode) > 1000 )
|
||||
// continue;
|
||||
// for each cut, try to resynthesize it
|
||||
nGain = Rwt_NodeRewrite( pManRwt, pNode, fUpdateLevel, fUseZeroCost );
|
||||
nGain = Ivy_NodeRewrite( p, pManRwt, pNode, fUpdateLevel, fUseZeroCost );
|
||||
if ( nGain > 0 || nGain == 0 && fUseZeroCost )
|
||||
{
|
||||
Dec_Graph_t * pGraph = Rwt_ManReadDecs(pManRwt);
|
||||
|
|
@ -104,7 +105,7 @@ int Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fV
|
|||
// complement the FF if needed
|
||||
clk = clock();
|
||||
if ( fCompl ) Dec_GraphComplement( pGraph );
|
||||
Ivy_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain );
|
||||
Ivy_GraphUpdateNetwork( p, pNode, pGraph, fUpdateLevel, nGain );
|
||||
if ( fCompl ) Dec_GraphComplement( pGraph );
|
||||
Rwt_ManAddTimeUpdate( pManRwt, clock() - clk );
|
||||
}
|
||||
|
|
@ -115,9 +116,12 @@ Rwt_ManAddTimeTotal( pManRwt, clock() - clkStart );
|
|||
Rwt_ManPrintStats( pManRwt );
|
||||
// delete the managers
|
||||
Rwt_ManStop( pManRwt );
|
||||
p->pData = NULL;
|
||||
// fix the levels
|
||||
if ( fUpdateLevel )
|
||||
Vec_IntFree( p->vRequired ), p->vRequired = NULL;
|
||||
// else
|
||||
// Ivy_ManResetLevels( p );
|
||||
// check
|
||||
if ( i = Ivy_ManCleanup(p) )
|
||||
printf( "Cleanup after rewriting removed %d dangling nodes.\n", i );
|
||||
|
|
@ -144,7 +148,7 @@ Rwt_ManAddTimeTotal( pManRwt, clock() - clkStart );
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Rwt_NodeRewrite( Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel, int fUseZeroCost )
|
||||
int Ivy_NodeRewrite( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel, int fUseZeroCost )
|
||||
{
|
||||
int fVeryVerbose = 0;
|
||||
Dec_Graph_t * pGraph;
|
||||
|
|
@ -159,10 +163,10 @@ int Rwt_NodeRewrite( Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel, int fUs
|
|||
|
||||
p->nNodesConsidered++;
|
||||
// get the required times
|
||||
Required = fUpdateLevel? Vec_IntEntry( Ivy_ObjMan(pNode)->vRequired, pNode->Id ) : 1000000;
|
||||
Required = fUpdateLevel? Vec_IntEntry( pMan->vRequired, pNode->Id ) : 1000000;
|
||||
// get the node's cuts
|
||||
clk = clock();
|
||||
pStore = Ivy_NodeFindCutsAll( pNode, 5 );
|
||||
pStore = Ivy_NodeFindCutsAll( pMan, pNode, 5 );
|
||||
p->timeCut += clock() - clk;
|
||||
|
||||
// go through the cuts
|
||||
|
|
@ -175,14 +179,10 @@ clk = clock();
|
|||
continue;
|
||||
// skip the cuts with buffers
|
||||
for ( i = 0; i < (int)pCut->nSize; i++ )
|
||||
if ( Ivy_ObjIsBuf( Ivy_ObjObj(pNode, pCut->pArray[i]) ) )
|
||||
if ( Ivy_ObjIsBuf( Ivy_ManObj(pMan, pCut->pArray[i]) ) )
|
||||
break;
|
||||
if ( i != pCut->nSize )
|
||||
continue;
|
||||
|
||||
// if ( pNode->Id == 82 )
|
||||
// Ivy_NodePrintCut( pCut );
|
||||
|
||||
// get the fanin permutation
|
||||
clk2 = clock();
|
||||
uTruth = 0xFFFF & Ivy_NodeGetTruth( pNode, pCut->pArray, pCut->nSize ); // truth table
|
||||
|
|
@ -194,7 +194,7 @@ p->timeTruth += clock() - clk2;
|
|||
Vec_PtrFill( p->vFaninsCur, (int)pCut->nSize, 0 );
|
||||
for ( i = 0; i < (int)pCut->nSize; i++ )
|
||||
{
|
||||
pFanin = Ivy_ObjObj( pNode, pCut->pArray[pPerm[i]] );
|
||||
pFanin = Ivy_ManObj( pMan, pCut->pArray[pPerm[i]] );
|
||||
assert( Ivy_ObjIsNode(pFanin) || Ivy_ObjIsCi(pFanin) );
|
||||
pFanin = Ivy_NotCond(pFanin, ((uPhase & (1<<i)) > 0) );
|
||||
Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin );
|
||||
|
|
@ -210,8 +210,8 @@ clk2 = clock();
|
|||
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
|
||||
Ivy_ObjRefsInc( Ivy_Regular(pFanin) );
|
||||
// label MFFC with current ID
|
||||
Ivy_ManIncrementTravId( Ivy_ObjMan(pNode) );
|
||||
nNodesSaved = Ivy_NodeMffcLabel( pNode );
|
||||
Ivy_ManIncrementTravId( pMan );
|
||||
nNodesSaved = Ivy_NodeMffcLabel( pMan, pNode );
|
||||
// unmark the fanin boundary
|
||||
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
|
||||
Ivy_ObjRefsDec( Ivy_Regular(pFanin) );
|
||||
|
|
@ -219,7 +219,7 @@ p->timeMffc += clock() - clk2;
|
|||
|
||||
// evaluate the cut
|
||||
clk2 = clock();
|
||||
pGraph = Rwt_CutEvaluate( p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur, uTruth );
|
||||
pGraph = Rwt_CutEvaluate( pMan, p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur, uTruth );
|
||||
p->timeEval += clock() - clk2;
|
||||
|
||||
// check if the cut is better than the current best one
|
||||
|
|
@ -301,13 +301,13 @@ p->timeRes += clock() - clk;
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_NodeRefDeref( Ivy_Obj_t * pNode, int fReference, int fLabel )
|
||||
int Ivy_NodeRefDeref( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fReference, int fLabel )
|
||||
{
|
||||
Ivy_Obj_t * pNode0, * pNode1;
|
||||
int Counter;
|
||||
// label visited nodes
|
||||
if ( fLabel )
|
||||
Ivy_ObjSetTravIdCurrent( pNode );
|
||||
Ivy_ObjSetTravIdCurrent( p, pNode );
|
||||
// skip the CI
|
||||
if ( Ivy_ObjIsCi(pNode) )
|
||||
return 0;
|
||||
|
|
@ -319,18 +319,18 @@ int Ivy_NodeRefDeref( Ivy_Obj_t * pNode, int fReference, int fLabel )
|
|||
if ( fReference )
|
||||
{
|
||||
if ( pNode0->nRefs++ == 0 )
|
||||
Counter += Ivy_NodeRefDeref( pNode0, fReference, fLabel );
|
||||
if ( Ivy_ObjIsNode(pNode) && pNode1->nRefs++ == 0 )
|
||||
Counter += Ivy_NodeRefDeref( pNode1, fReference, fLabel );
|
||||
Counter += Ivy_NodeRefDeref( p, pNode0, fReference, fLabel );
|
||||
if ( pNode1 && pNode1->nRefs++ == 0 )
|
||||
Counter += Ivy_NodeRefDeref( p, pNode1, fReference, fLabel );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( pNode0->nRefs > 0 );
|
||||
assert( pNode1->nRefs > 0 );
|
||||
assert( pNode1 == NULL || pNode1->nRefs > 0 );
|
||||
if ( --pNode0->nRefs == 0 )
|
||||
Counter += Ivy_NodeRefDeref( pNode0, fReference, fLabel );
|
||||
if ( Ivy_ObjIsNode(pNode) && --pNode1->nRefs == 0 )
|
||||
Counter += Ivy_NodeRefDeref( pNode1, fReference, fLabel );
|
||||
Counter += Ivy_NodeRefDeref( p, pNode0, fReference, fLabel );
|
||||
if ( pNode1 && --pNode1->nRefs == 0 )
|
||||
Counter += Ivy_NodeRefDeref( p, pNode1, fReference, fLabel );
|
||||
}
|
||||
return Counter;
|
||||
}
|
||||
|
|
@ -346,13 +346,13 @@ int Ivy_NodeRefDeref( Ivy_Obj_t * pNode, int fReference, int fLabel )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_NodeMffcLabel( Ivy_Obj_t * pNode )
|
||||
int Ivy_NodeMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pNode )
|
||||
{
|
||||
int nConeSize1, nConeSize2;
|
||||
assert( !Ivy_IsComplement( pNode ) );
|
||||
assert( Ivy_ObjIsNode( pNode ) );
|
||||
nConeSize1 = Ivy_NodeRefDeref( pNode, 0, 1 ); // dereference
|
||||
nConeSize2 = Ivy_NodeRefDeref( pNode, 1, 0 ); // reference
|
||||
nConeSize1 = Ivy_NodeRefDeref( p, pNode, 0, 1 ); // dereference
|
||||
nConeSize2 = Ivy_NodeRefDeref( p, pNode, 1, 0 ); // reference
|
||||
assert( nConeSize1 == nConeSize2 );
|
||||
assert( nConeSize1 > 0 );
|
||||
return nConeSize1;
|
||||
|
|
@ -418,7 +418,7 @@ unsigned Ivy_NodeGetTruth( Ivy_Obj_t * pObj, int * pNums, int nNums )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dec_Graph_t * Rwt_CutEvaluate( Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth )
|
||||
Dec_Graph_t * Rwt_CutEvaluate( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth )
|
||||
{
|
||||
Vec_Ptr_t * vSubgraphs;
|
||||
Dec_Graph_t * pGraphBest, * pGraphCur;
|
||||
|
|
@ -437,7 +437,7 @@ Dec_Graph_t * Rwt_CutEvaluate( Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCu
|
|||
Vec_PtrForEachEntry( vFaninsCur, pFanin, k )
|
||||
Dec_GraphNode(pGraphCur, k)->pFunc = pFanin;
|
||||
// detect how many unlabeled nodes will be reused
|
||||
nNodesAdded = Ivy_GraphToNetworkCount( pRoot, pGraphCur, nNodesSaved, LevelMax );
|
||||
nNodesAdded = Ivy_GraphToNetworkCount( pMan, pRoot, pGraphCur, nNodesSaved, LevelMax );
|
||||
if ( nNodesAdded == -1 )
|
||||
continue;
|
||||
assert( nNodesSaved >= nNodesAdded );
|
||||
|
|
@ -469,7 +469,7 @@ Dec_Graph_t * Rwt_CutEvaluate( Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCu
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_GraphToNetworkCount( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax )
|
||||
int Ivy_GraphToNetworkCount( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax )
|
||||
{
|
||||
Dec_Node_t * pNode, * pNode0, * pNode1;
|
||||
Ivy_Obj_t * pAnd, * pAnd0, * pAnd1;
|
||||
|
|
@ -495,7 +495,7 @@ int Ivy_GraphToNetworkCount( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMa
|
|||
// if they are both present, find the resulting node
|
||||
pAnd0 = Ivy_NotCond( pAnd0, pNode->eEdge0.fCompl );
|
||||
pAnd1 = Ivy_NotCond( pAnd1, pNode->eEdge1.fCompl );
|
||||
pAnd = Ivy_TableLookup( Ivy_ObjCreateGhost(pAnd0, pAnd1, IVY_AND, IVY_INIT_NONE) );
|
||||
pAnd = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, pAnd0, pAnd1, IVY_AND, IVY_INIT_NONE) );
|
||||
// return -1 if the node is the same as the original root
|
||||
if ( Ivy_Regular(pAnd) == pRoot )
|
||||
return -1;
|
||||
|
|
@ -503,7 +503,7 @@ int Ivy_GraphToNetworkCount( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMa
|
|||
else
|
||||
pAnd = NULL;
|
||||
// count the number of added nodes
|
||||
if ( pAnd == NULL || Ivy_ObjIsTravIdCurrent(Ivy_Regular(pAnd)) )
|
||||
if ( pAnd == NULL || Ivy_ObjIsTravIdCurrent(p, Ivy_Regular(pAnd)) )
|
||||
{
|
||||
if ( ++Counter > NodeMax )
|
||||
return -1;
|
||||
|
|
@ -512,7 +512,7 @@ int Ivy_GraphToNetworkCount( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMa
|
|||
LevelNew = 1 + RWT_MAX( pNode0->Level, pNode1->Level );
|
||||
if ( pAnd )
|
||||
{
|
||||
if ( Ivy_Regular(pAnd) == Ivy_ObjConst1(pRoot) )
|
||||
if ( Ivy_Regular(pAnd) == p->pConst1 )
|
||||
LevelNew = 0;
|
||||
else if ( Ivy_Regular(pAnd) == Ivy_Regular(pAnd0) )
|
||||
LevelNew = (int)Ivy_Regular(pAnd0)->Level;
|
||||
|
|
@ -541,14 +541,14 @@ int Ivy_GraphToNetworkCount( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMa
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_GraphToNetwork( Ivy_Man_t * pMan, Dec_Graph_t * pGraph )
|
||||
Ivy_Obj_t * Ivy_GraphToNetwork( Ivy_Man_t * p, Dec_Graph_t * pGraph )
|
||||
{
|
||||
Ivy_Obj_t * pAnd0, * pAnd1;
|
||||
Dec_Node_t * pNode;
|
||||
int i;
|
||||
// check for constant function
|
||||
if ( Dec_GraphIsConst(pGraph) )
|
||||
return Ivy_NotCond( Ivy_ManConst1(pMan), Dec_GraphIsComplement(pGraph) );
|
||||
return Ivy_NotCond( Ivy_ManConst1(p), Dec_GraphIsComplement(pGraph) );
|
||||
// check for a literal
|
||||
if ( Dec_GraphIsVar(pGraph) )
|
||||
return Ivy_NotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) );
|
||||
|
|
@ -557,7 +557,7 @@ Ivy_Obj_t * Ivy_GraphToNetwork( Ivy_Man_t * pMan, Dec_Graph_t * pGraph )
|
|||
{
|
||||
pAnd0 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
|
||||
pAnd1 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
|
||||
pNode->pFunc = Ivy_And( pAnd0, pAnd1 );
|
||||
pNode->pFunc = Ivy_And( p, pAnd0, pAnd1 );
|
||||
}
|
||||
// complement the result if necessary
|
||||
return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) );
|
||||
|
|
@ -574,18 +574,96 @@ Ivy_Obj_t * Ivy_GraphToNetwork( Ivy_Man_t * pMan, Dec_Graph_t * pGraph )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_GraphUpdateNetwork( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain )
|
||||
void Ivy_GraphUpdateNetwork( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain )
|
||||
{
|
||||
Ivy_Obj_t * pRootNew;
|
||||
int nNodesNew, nNodesOld;
|
||||
nNodesOld = Ivy_ManNodeNum(Ivy_ObjMan(pRoot));
|
||||
int nNodesNew, nNodesOld, Required;
|
||||
Required = fUpdateLevel? Vec_IntEntry( p->vRequired, pRoot->Id ) : 1000000;
|
||||
nNodesOld = Ivy_ManNodeNum(p);
|
||||
// create the new structure of nodes
|
||||
pRootNew = Ivy_GraphToNetwork( Ivy_ObjMan(pRoot), pGraph );
|
||||
pRootNew = Ivy_GraphToNetwork( p, pGraph );
|
||||
assert( (int)Ivy_Regular(pRootNew)->Level <= Required );
|
||||
// if ( Ivy_Regular(pRootNew)->Level == Required )
|
||||
// printf( "Difference %d.\n", Ivy_Regular(pRootNew)->Level - Required );
|
||||
// remove the old nodes
|
||||
// Ivy_AigReplace( pMan->pManFunc, pRoot, pRootNew, fUpdateLevel );
|
||||
Ivy_ObjReplace( pRoot, pRootNew, 1, 0 );
|
||||
/*
|
||||
if ( Ivy_IsComplement(pRootNew) )
|
||||
printf( "c" );
|
||||
else
|
||||
printf( "d" );
|
||||
if ( Ivy_ObjRefs(Ivy_Regular(pRootNew)) > 0 )
|
||||
printf( "%d", Ivy_ObjRefs(Ivy_Regular(pRootNew)) );
|
||||
printf( " " );
|
||||
*/
|
||||
Ivy_ObjReplace( p, pRoot, pRootNew, 1, 0 );
|
||||
// compare the gains
|
||||
nNodesNew = Ivy_ManNodeNum(Ivy_ObjMan(pRoot));
|
||||
nNodesNew = Ivy_ManNodeNum(p);
|
||||
assert( nGain <= nNodesOld - nNodesNew );
|
||||
// propagate the buffer
|
||||
Ivy_ManPropagateBuffers( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Replaces MFFC of the node by the new factored form.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_GraphUpdateNetwork3( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain )
|
||||
{
|
||||
Ivy_Obj_t * pRootNew, * pFanin;
|
||||
int nNodesNew, nNodesOld, i, nRefsOld;
|
||||
nNodesOld = Ivy_ManNodeNum(p);
|
||||
|
||||
//printf( "Before = %d. ", Ivy_ManNodeNum(p) );
|
||||
// mark the cut
|
||||
Vec_PtrForEachEntry( ((Rwt_Man_t *)p->pData)->vFanins, pFanin, i )
|
||||
Ivy_ObjRefsInc( Ivy_Regular(pFanin) );
|
||||
// deref the old cone
|
||||
nRefsOld = pRoot->nRefs;
|
||||
pRoot->nRefs = 0;
|
||||
Ivy_ObjDelete_rec( p, pRoot, 0 );
|
||||
pRoot->nRefs = nRefsOld;
|
||||
// unmark the cut
|
||||
Vec_PtrForEachEntry( ((Rwt_Man_t *)p->pData)->vFanins, pFanin, i )
|
||||
Ivy_ObjRefsDec( Ivy_Regular(pFanin) );
|
||||
//printf( "Deref = %d. ", Ivy_ManNodeNum(p) );
|
||||
|
||||
// create the new structure of nodes
|
||||
pRootNew = Ivy_GraphToNetwork( p, pGraph );
|
||||
//printf( "Create = %d. ", Ivy_ManNodeNum(p) );
|
||||
// remove the old nodes
|
||||
// Ivy_AigReplace( pMan->pManFunc, pRoot, pRootNew, fUpdateLevel );
|
||||
/*
|
||||
if ( Ivy_IsComplement(pRootNew) )
|
||||
printf( "c" );
|
||||
else
|
||||
printf( "d" );
|
||||
if ( Ivy_ObjRefs(Ivy_Regular(pRootNew)) > 0 )
|
||||
printf( "%d", Ivy_ObjRefs(Ivy_Regular(pRootNew)) );
|
||||
printf( " " );
|
||||
*/
|
||||
Ivy_ObjReplace( p, pRoot, pRootNew, 0, 0 );
|
||||
//printf( "Replace = %d. ", Ivy_ManNodeNum(p) );
|
||||
|
||||
// delete remaining dangling nodes
|
||||
Vec_PtrForEachEntry( ((Rwt_Man_t *)p->pData)->vFanins, pFanin, i )
|
||||
{
|
||||
pFanin = Ivy_Regular(pFanin);
|
||||
if ( !Ivy_ObjIsNone(pFanin) && Ivy_ObjRefs(pFanin) == 0 )
|
||||
Ivy_ObjDelete_rec( p, pFanin, 1 );
|
||||
}
|
||||
//printf( "Deref = %d. ", Ivy_ManNodeNum(p) );
|
||||
//printf( "\n" );
|
||||
|
||||
// compare the gains
|
||||
nNodesNew = Ivy_ManNodeNum(p);
|
||||
assert( nGain <= nNodesOld - nNodesNew );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,13 +24,15 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline int Ivy_CutHashValue( int NodeId ) { return 1 << (NodeId % 31); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts a combinational AIG manager into a sequential one.]
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -39,59 +41,378 @@
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManMakeSeq( Ivy_Man_t * p, int nLatches )
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives new cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_CutDeriveNew( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 )
|
||||
{
|
||||
Vec_Int_t * vNodes;
|
||||
Ivy_Obj_t * pObj, * pObjNew, * pFan0, * pFan1;
|
||||
int i, fChanges;
|
||||
assert( nLatches < Ivy_ManPiNum(p) && nLatches < Ivy_ManPoNum(p) );
|
||||
// change POs into buffers
|
||||
assert( Ivy_ManPoNum(p) == Vec_IntSize(p->vPos) );
|
||||
for ( i = Ivy_ManPoNum(p) - nLatches; i < Vec_IntSize(p->vPos); i++ )
|
||||
unsigned uHash = 0;
|
||||
int i, k;
|
||||
assert( pCut->nSize > 0 );
|
||||
assert( IdNew0 < IdNew1 );
|
||||
for ( i = k = 0; i < pCut->nSize; i++ )
|
||||
{
|
||||
pObj = Ivy_ManPo(p, i);
|
||||
pObj->Type = IVY_BUF;
|
||||
}
|
||||
// change PIs into latches and connect them to the corresponding POs
|
||||
assert( Ivy_ManPiNum(p) == Vec_IntSize(p->vPis) );
|
||||
for ( i = Ivy_ManPiNum(p) - nLatches; i < Vec_IntSize(p->vPis); i++ )
|
||||
{
|
||||
pObj = Ivy_ManPi(p, i);
|
||||
pObj->Type = IVY_LATCH;
|
||||
Ivy_ObjConnect( pObj, Ivy_ManPo(p, Ivy_ManPoNum(p) - Ivy_ManPiNum(p)) );
|
||||
}
|
||||
// shrink the array
|
||||
Vec_IntShrink( p->vPis, Ivy_ManPiNum(p) - nLatches );
|
||||
Vec_IntShrink( p->vPos, Ivy_ManPoNum(p) - nLatches );
|
||||
// update the counters of different objects
|
||||
p->nObjs[IVY_PI] -= nLatches;
|
||||
p->nObjs[IVY_PO] -= nLatches;
|
||||
p->nObjs[IVY_BUF] += nLatches;
|
||||
p->nObjs[IVY_LATCH] += nLatches;
|
||||
// perform structural hashing while there are changes
|
||||
fChanges = 1;
|
||||
while ( fChanges )
|
||||
{
|
||||
fChanges = 0;
|
||||
vNodes = Ivy_ManDfs( p );
|
||||
Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
|
||||
if ( pCut->pArray[i] == IdOld )
|
||||
continue;
|
||||
if ( IdNew0 >= 0 )
|
||||
{
|
||||
if ( Ivy_ObjIsBuf(pObj) )
|
||||
continue;
|
||||
pFan0 = Ivy_NodeRealFanin_rec( pObj, 0 );
|
||||
pFan1 = Ivy_NodeRealFanin_rec( pObj, 1 );
|
||||
if ( Ivy_ObjIsAnd(pObj) )
|
||||
pObjNew = Ivy_And(pFan0, pFan1);
|
||||
else if ( Ivy_ObjIsExor(pObj) )
|
||||
pObjNew = Ivy_Exor(pFan0, pFan1);
|
||||
else assert( 0 );
|
||||
if ( pObjNew == pObj )
|
||||
continue;
|
||||
Ivy_ObjReplace( pObj, pObjNew, 1, 1 );
|
||||
fChanges = 1;
|
||||
if ( IdNew0 <= pCut->pArray[i] )
|
||||
{
|
||||
if ( IdNew0 < pCut->pArray[i] )
|
||||
{
|
||||
if ( k == pCut->nSizeMax )
|
||||
return 0;
|
||||
pCutNew->pArray[ k++ ] = IdNew0;
|
||||
uHash |= Ivy_CutHashValue( IdNew0 );
|
||||
}
|
||||
IdNew0 = -1;
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vNodes );
|
||||
if ( IdNew1 >= 0 )
|
||||
{
|
||||
if ( IdNew1 <= pCut->pArray[i] )
|
||||
{
|
||||
if ( IdNew1 < pCut->pArray[i] )
|
||||
{
|
||||
if ( k == pCut->nSizeMax )
|
||||
return 0;
|
||||
pCutNew->pArray[ k++ ] = IdNew1;
|
||||
uHash |= Ivy_CutHashValue( IdNew1 );
|
||||
}
|
||||
IdNew1 = -1;
|
||||
}
|
||||
}
|
||||
if ( k == pCut->nSizeMax )
|
||||
return 0;
|
||||
pCutNew->pArray[ k++ ] = pCut->pArray[i];
|
||||
uHash |= Ivy_CutHashValue( pCut->pArray[i] );
|
||||
}
|
||||
if ( IdNew0 >= 0 )
|
||||
{
|
||||
if ( k == pCut->nSizeMax )
|
||||
return 0;
|
||||
pCutNew->pArray[ k++ ] = IdNew0;
|
||||
uHash |= Ivy_CutHashValue( IdNew0 );
|
||||
}
|
||||
if ( IdNew1 >= 0 )
|
||||
{
|
||||
if ( k == pCut->nSizeMax )
|
||||
return 0;
|
||||
pCutNew->pArray[ k++ ] = IdNew1;
|
||||
uHash |= Ivy_CutHashValue( IdNew1 );
|
||||
}
|
||||
pCutNew->nSize = k;
|
||||
pCutNew->uHash = uHash;
|
||||
assert( pCutNew->nSize <= pCut->nSizeMax );
|
||||
for ( i = 1; i < pCutNew->nSize; i++ )
|
||||
assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if pDom is contained in pCut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_CutCheckDominance( Ivy_Cut_t * pDom, Ivy_Cut_t * pCut )
|
||||
{
|
||||
int i, k;
|
||||
for ( i = 0; i < pDom->nSize; i++ )
|
||||
{
|
||||
assert( i==0 || pDom->pArray[i-1] < pDom->pArray[i] );
|
||||
for ( k = 0; k < pCut->nSize; k++ )
|
||||
if ( pDom->pArray[i] == pCut->pArray[k] )
|
||||
break;
|
||||
if ( k == pCut->nSize ) // node i in pDom is not contained in pCut
|
||||
return 0;
|
||||
}
|
||||
// every node in pDom is contained in pCut
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Check if the cut exists.]
|
||||
|
||||
Description [Returns 1 if the cut exists.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_CutFindOrAddFilter( Ivy_Store_t * pCutStore, Ivy_Cut_t * pCutNew )
|
||||
{
|
||||
Ivy_Cut_t * pCut;
|
||||
int i, k;
|
||||
assert( pCutNew->uHash );
|
||||
// try to find the cut
|
||||
for ( i = 0; i < pCutStore->nCuts; i++ )
|
||||
{
|
||||
pCut = pCutStore->pCuts + i;
|
||||
if ( pCut->nSize == 0 )
|
||||
continue;
|
||||
if ( pCut->nSize == pCutNew->nSize )
|
||||
{
|
||||
if ( pCut->uHash == pCutNew->uHash )
|
||||
{
|
||||
for ( k = 0; k < pCutNew->nSize; k++ )
|
||||
if ( pCut->pArray[k] != pCutNew->pArray[k] )
|
||||
break;
|
||||
if ( k == pCutNew->nSize )
|
||||
return 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ( pCut->nSize < pCutNew->nSize )
|
||||
{
|
||||
// skip the non-contained cuts
|
||||
if ( (pCut->uHash & pCutNew->uHash) != pCut->uHash )
|
||||
continue;
|
||||
// check containment seriously
|
||||
if ( Ivy_CutCheckDominance( pCut, pCutNew ) )
|
||||
return 1;
|
||||
continue;
|
||||
}
|
||||
// check potential containment of other cut
|
||||
|
||||
// skip the non-contained cuts
|
||||
if ( (pCut->uHash & pCutNew->uHash) != pCutNew->uHash )
|
||||
continue;
|
||||
// check containment seriously
|
||||
if ( Ivy_CutCheckDominance( pCutNew, pCut ) )
|
||||
{
|
||||
// remove the current cut
|
||||
pCut->nSize = 0;
|
||||
}
|
||||
}
|
||||
assert( pCutStore->nCuts < pCutStore->nCutsMax );
|
||||
// add the cut
|
||||
pCut = pCutStore->pCuts + pCutStore->nCuts++;
|
||||
*pCut = *pCutNew;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compresses the cut representation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_CutCompactAll( Ivy_Store_t * pCutStore )
|
||||
{
|
||||
Ivy_Cut_t * pCut;
|
||||
int i, k;
|
||||
pCutStore->nCutsM = 0;
|
||||
for ( i = k = 0; i < pCutStore->nCuts; i++ )
|
||||
{
|
||||
pCut = pCutStore->pCuts + i;
|
||||
if ( pCut->nSize == 0 )
|
||||
continue;
|
||||
if ( pCut->nSize < pCut->nSizeMax )
|
||||
pCutStore->nCutsM++;
|
||||
pCutStore->pCuts[k++] = *pCut;
|
||||
}
|
||||
pCutStore->nCuts = k;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Print the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_CutPrintForNode( Ivy_Cut_t * pCut )
|
||||
{
|
||||
int i;
|
||||
assert( pCut->nSize > 0 );
|
||||
printf( "%d : {", pCut->nSize );
|
||||
for ( i = 0; i < pCut->nSize; i++ )
|
||||
printf( " %d", pCut->pArray[i] );
|
||||
printf( " }\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_CutPrintForNodes( Ivy_Store_t * pCutStore )
|
||||
{
|
||||
int i;
|
||||
printf( "Node %d\n", pCutStore->pCuts[0].pArray[0] );
|
||||
for ( i = 0; i < pCutStore->nCuts; i++ )
|
||||
Ivy_CutPrintForNode( pCutStore->pCuts + i );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_CutReadLeaf( Ivy_Obj_t * pFanin )
|
||||
{
|
||||
assert( !Ivy_IsComplement(pFanin) );
|
||||
if ( !Ivy_ObjIsLatch(pFanin) )
|
||||
return Ivy_LeafCreate( pFanin->Id, 0 );
|
||||
return 1 + Ivy_CutReadLeaf( Ivy_ObjFanin0(pFanin) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Store_t * Ivy_CutComputeForNode( 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, Temp, nLats, iLeaf0, iLeaf1;
|
||||
|
||||
assert( nLeaves <= IVY_CUT_INPUT );
|
||||
|
||||
// start the structure
|
||||
pCutStore->nCuts = 0;
|
||||
pCutStore->nCutsMax = IVY_CUT_LIMIT;
|
||||
// start the trivial cut
|
||||
pCutNew->uHash = 0;
|
||||
pCutNew->nSize = 1;
|
||||
pCutNew->nSizeMax = nLeaves;
|
||||
pCutNew->pArray[0] = Ivy_LeafCreate( pObj->Id, 0 );
|
||||
pCutNew->uHash = Ivy_CutHashValue( pCutNew->pArray[0] );
|
||||
// add the trivial cut
|
||||
pCutStore->pCuts[pCutStore->nCuts++] = *pCutNew;
|
||||
assert( pCutStore->nCuts == 1 );
|
||||
|
||||
// explore the cuts
|
||||
for ( i = 0; i < pCutStore->nCuts; i++ )
|
||||
{
|
||||
// expand this cut
|
||||
pCut = pCutStore->pCuts + i;
|
||||
if ( pCut->nSize == 0 )
|
||||
continue;
|
||||
for ( k = 0; k < pCut->nSize; k++ )
|
||||
{
|
||||
pLeaf = Ivy_ManObj( p, Ivy_LeafId(pCut->pArray[k]) );
|
||||
if ( Ivy_ObjIsCi(pLeaf) )
|
||||
continue;
|
||||
assert( Ivy_ObjIsNode(pLeaf) );
|
||||
nLats = Ivy_LeafLat(pCut->pArray[k]);
|
||||
// get the fanins fanins
|
||||
iLeaf0 = nLats + Ivy_CutReadLeaf( Ivy_ObjFanin0(pLeaf) );
|
||||
iLeaf1 = nLats + Ivy_CutReadLeaf( Ivy_ObjFanin1(pLeaf) );
|
||||
if ( iLeaf0 > iLeaf1 )
|
||||
Temp = iLeaf0, iLeaf0 = iLeaf1, iLeaf1 = Temp;
|
||||
// create the new cut
|
||||
if ( !Ivy_CutDeriveNew( pCut, pCutNew, pCut->pArray[k], iLeaf0, iLeaf1 ) )
|
||||
continue;
|
||||
// add the cut
|
||||
Ivy_CutFindOrAddFilter( pCutStore, pCutNew );
|
||||
if ( pCutStore->nCuts == IVY_CUT_LIMIT )
|
||||
break;
|
||||
}
|
||||
if ( pCutStore->nCuts == IVY_CUT_LIMIT )
|
||||
break;
|
||||
}
|
||||
if ( pCutStore->nCuts == IVY_CUT_LIMIT )
|
||||
pCutStore->fSatur = 1;
|
||||
else
|
||||
pCutStore->fSatur = 0;
|
||||
// printf( "%d ", pCutStore->nCuts );
|
||||
Ivy_CutCompactAll( pCutStore );
|
||||
// printf( "%d \n", pCutStore->nCuts );
|
||||
// Ivy_CutPrintForNodes( pCutStore );
|
||||
return pCutStore;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_CutComputeAll( Ivy_Man_t * p, int nInputs )
|
||||
{
|
||||
Ivy_Store_t * pStore;
|
||||
Ivy_Obj_t * pObj;
|
||||
int i, nCutsTotal, nCutsTotalM, nNodeTotal, nNodeOver;
|
||||
int clk = clock();
|
||||
if ( nInputs > IVY_CUT_INPUT )
|
||||
{
|
||||
printf( "Cannot compute cuts for more than %d inputs.\n", IVY_CUT_INPUT );
|
||||
return;
|
||||
}
|
||||
nNodeTotal = nNodeOver = 0;
|
||||
nCutsTotal = nCutsTotalM = -Ivy_ManNodeNum(p);
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( !Ivy_ObjIsNode(pObj) )
|
||||
continue;
|
||||
pStore = Ivy_CutComputeForNode( p, pObj, nInputs );
|
||||
nCutsTotal += pStore->nCuts;
|
||||
nCutsTotalM += pStore->nCutsM;
|
||||
nNodeOver += pStore->fSatur;
|
||||
nNodeTotal++;
|
||||
}
|
||||
printf( "All = %6d. Minus = %6d. Triv = %6d. Node = %6d. Satur = %6d. ",
|
||||
nCutsTotal, nCutsTotalM, Ivy_ManPiNum(p) + Ivy_ManNodeNum(p), nNodeTotal, nNodeOver );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
Date [Ver. 1.0. Started - May 11, 2006. ]
|
||||
|
||||
Revision [$Id: ivyTable.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
|
|
@ -37,22 +37,23 @@ static unsigned Ivy_Hash( Ivy_Obj_t * pObj, int TableSize )
|
|||
}
|
||||
|
||||
// returns the place where this node is stored (or should be stored)
|
||||
static int * Ivy_TableFind( Ivy_Obj_t * pObj )
|
||||
static int * Ivy_TableFind( Ivy_Man_t * p, Ivy_Obj_t * pObj )
|
||||
{
|
||||
Ivy_Man_t * p;
|
||||
int i;
|
||||
assert( Ivy_ObjIsHash(pObj) );
|
||||
p = Ivy_ObjMan(pObj);
|
||||
for ( i = Ivy_Hash(pObj, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize )
|
||||
if ( p->pTable[i] == pObj->Id )
|
||||
break;
|
||||
return p->pTable + i;
|
||||
}
|
||||
|
||||
static void Ivy_TableResize( Ivy_Man_t * p );
|
||||
static unsigned int Cudd_PrimeAig( unsigned int p );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if node with the given attributes is in the hash table.]
|
||||
|
|
@ -64,27 +65,25 @@ static int * Ivy_TableFind( Ivy_Obj_t * pObj )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Obj_t * Ivy_TableLookup( Ivy_Obj_t * pObj )
|
||||
Ivy_Obj_t * Ivy_TableLookup( Ivy_Man_t * p, Ivy_Obj_t * pObj )
|
||||
{
|
||||
Ivy_Man_t * p;
|
||||
Ivy_Obj_t * pEntry;
|
||||
int i;
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
if ( !Ivy_ObjIsHash(pObj) )
|
||||
return NULL;
|
||||
assert( Ivy_ObjIsLatch(pObj) || Ivy_ObjFaninId0(pObj) > 0 );
|
||||
assert( Ivy_ObjFaninId0(pObj) == 0 || Ivy_ObjFaninId0(pObj) > Ivy_ObjFaninId1(pObj) );
|
||||
p = Ivy_ObjMan(pObj);
|
||||
assert( Ivy_ObjFaninId1(pObj) == 0 || Ivy_ObjFaninId0(pObj) < Ivy_ObjFaninId1(pObj) );
|
||||
// if ( Ivy_ObjFanin0(pObj)->nRefs == 0 || (!Ivy_ObjIsLatch(pObj) && Ivy_ObjFanin1(pObj)->nRefs == 0) )
|
||||
// return NULL;
|
||||
for ( i = Ivy_Hash(pObj, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize )
|
||||
{
|
||||
pEntry = Ivy_ObjObj( pObj, p->pTable[i] );
|
||||
if ( Ivy_ObjFaninId0(pEntry) == Ivy_ObjFaninId0(pObj) &&
|
||||
Ivy_ObjFaninId1(pEntry) == Ivy_ObjFaninId1(pObj) &&
|
||||
Ivy_ObjFaninC0(pEntry) == Ivy_ObjFaninC0(pObj) &&
|
||||
Ivy_ObjFaninC1(pEntry) == Ivy_ObjFaninC1(pObj) &&
|
||||
pEntry = Ivy_ManObj( p, p->pTable[i] );
|
||||
if ( Ivy_ObjChild0(pEntry) == Ivy_ObjChild0(pObj) &&
|
||||
Ivy_ObjChild1(pEntry) == Ivy_ObjChild1(pObj) &&
|
||||
Ivy_ObjInit(pEntry) == Ivy_ObjInit(pObj) &&
|
||||
Ivy_ObjType(pEntry) == Ivy_ObjType(pObj) )
|
||||
return Ivy_ObjObj( pObj, p->pTable[i] );
|
||||
return pEntry;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -100,13 +99,18 @@ Ivy_Obj_t * Ivy_TableLookup( Ivy_Obj_t * pObj )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_TableInsert( Ivy_Obj_t * pObj )
|
||||
void Ivy_TableInsert( Ivy_Man_t * p, Ivy_Obj_t * pObj )
|
||||
{
|
||||
int * pPlace;
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
if ( !Ivy_ObjIsHash(pObj) )
|
||||
return;
|
||||
pPlace = Ivy_TableFind( pObj );
|
||||
if ( (pObj->Id & 63) == 0 )
|
||||
{
|
||||
if ( p->nTableSize < 2 * Ivy_ManHashObjNum(p) )
|
||||
Ivy_TableResize( p );
|
||||
}
|
||||
pPlace = Ivy_TableFind( p, pObj );
|
||||
assert( *pPlace == 0 );
|
||||
*pPlace = pObj->Id;
|
||||
}
|
||||
|
|
@ -122,25 +126,23 @@ void Ivy_TableInsert( Ivy_Obj_t * pObj )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_TableDelete( Ivy_Obj_t * pObj )
|
||||
void Ivy_TableDelete( Ivy_Man_t * p, Ivy_Obj_t * pObj )
|
||||
{
|
||||
Ivy_Man_t * p;
|
||||
Ivy_Obj_t * pEntry;
|
||||
int i, * pPlace;
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
if ( !Ivy_ObjIsHash(pObj) )
|
||||
return;
|
||||
pPlace = Ivy_TableFind( pObj );
|
||||
pPlace = Ivy_TableFind( p, pObj );
|
||||
assert( *pPlace == pObj->Id ); // node should be in the table
|
||||
*pPlace = 0;
|
||||
// rehash the adjacent entries
|
||||
p = Ivy_ObjMan(pObj);
|
||||
i = pPlace - p->pTable;
|
||||
for ( i = (i+1) % p->nTableSize; p->pTable[i]; i = (i+1) % p->nTableSize )
|
||||
{
|
||||
pEntry = Ivy_ObjObj( pObj, p->pTable[i] );
|
||||
pEntry = Ivy_ManObj( p, p->pTable[i] );
|
||||
p->pTable[i] = 0;
|
||||
Ivy_TableInsert( pEntry );
|
||||
Ivy_TableInsert( p, pEntry );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -157,13 +159,13 @@ void Ivy_TableDelete( Ivy_Obj_t * pObj )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_TableUpdate( Ivy_Obj_t * pObj, int ObjIdNew )
|
||||
void Ivy_TableUpdate( Ivy_Man_t * p, Ivy_Obj_t * pObj, int ObjIdNew )
|
||||
{
|
||||
int * pPlace;
|
||||
assert( !Ivy_IsComplement(pObj) );
|
||||
if ( !Ivy_ObjIsHash(pObj) )
|
||||
return;
|
||||
pPlace = Ivy_TableFind( pObj );
|
||||
pPlace = Ivy_TableFind( p, pObj );
|
||||
assert( *pPlace == pObj->Id ); // node should be in the table
|
||||
*pPlace = ObjIdNew;
|
||||
}
|
||||
|
|
@ -202,13 +204,12 @@ void Ivy_TableResize( Ivy_Man_t * p )
|
|||
{
|
||||
int * pTableOld, * pPlace;
|
||||
int nTableSizeOld, Counter, e, clk;
|
||||
assert( 0 );
|
||||
clk = clock();
|
||||
// save the old table
|
||||
pTableOld = p->pTable;
|
||||
nTableSizeOld = p->nTableSize;
|
||||
// get the new table
|
||||
p->nTableSize = p->nObjsAlloc*5/2+13;
|
||||
p->nTableSize = Cudd_PrimeAig( 5 * Ivy_ManHashObjNum(p) );
|
||||
p->pTable = ALLOC( int, p->nTableSize );
|
||||
memset( p->pTable, 0, sizeof(int) * p->nTableSize );
|
||||
// rehash the entries from the old table
|
||||
|
|
@ -219,17 +220,79 @@ clk = clock();
|
|||
continue;
|
||||
Counter++;
|
||||
// get the place where this entry goes in the table table
|
||||
pPlace = Ivy_TableFind( Ivy_ManObj(p, pTableOld[e]) );
|
||||
pPlace = Ivy_TableFind( p, Ivy_ManObj(p, pTableOld[e]) );
|
||||
assert( *pPlace == 0 ); // should not be in the table
|
||||
*pPlace = pTableOld[e];
|
||||
}
|
||||
assert( Counter == Ivy_ManHashObjNum(p) );
|
||||
// printf( "Increasing the structural table size from %6d to %6d. ", p->nTableSize, nTableSizeNew );
|
||||
// printf( "Increasing the structural table size from %6d to %6d. ", nTableSizeOld, p->nTableSize );
|
||||
// PRT( "Time", clock() - clk );
|
||||
// replace the table and the parameters
|
||||
free( p->pTable );
|
||||
free( pTableOld );
|
||||
}
|
||||
|
||||
/**Function********************************************************************
|
||||
|
||||
Synopsis [Profiles the hash table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
******************************************************************************/
|
||||
void Ivy_TableProfile( Ivy_Man_t * p )
|
||||
{
|
||||
int i, Counter = 0;
|
||||
for ( i = 0; i < p->nTableSize; i++ )
|
||||
{
|
||||
if ( p->pTable[i] )
|
||||
Counter++;
|
||||
else if ( Counter )
|
||||
{
|
||||
printf( "%d ", Counter );
|
||||
Counter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function********************************************************************
|
||||
|
||||
Synopsis [Returns the next prime >= p.]
|
||||
|
||||
Description [Copied from CUDD, for stand-aloneness.]
|
||||
|
||||
SideEffects [None]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
******************************************************************************/
|
||||
unsigned int Cudd_PrimeAig( unsigned int p)
|
||||
{
|
||||
int i,pn;
|
||||
|
||||
p--;
|
||||
do {
|
||||
p++;
|
||||
if (p&1) {
|
||||
pn = 1;
|
||||
i = 3;
|
||||
while ((unsigned) (i * i) <= p) {
|
||||
if (p % i == 0) {
|
||||
pn = 0;
|
||||
break;
|
||||
}
|
||||
i += 2;
|
||||
}
|
||||
} else {
|
||||
pn = 0;
|
||||
}
|
||||
} while (!pn);
|
||||
return(p);
|
||||
|
||||
} /* end of Cudd_Prime */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -1,165 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ivyUndo.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [And-Inverter Graph package.]
|
||||
|
||||
Synopsis [Recording the results of recent deletion of logic cone.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: ivyUndo.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "ivy.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManUndoStart( Ivy_Man_t * p )
|
||||
{
|
||||
p->fRecording = 1;
|
||||
p->nUndos = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManUndoStop( Ivy_Man_t * p )
|
||||
{
|
||||
p->fRecording = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManUndoRecord( Ivy_Man_t * p, Ivy_Obj_t * pObj )
|
||||
{
|
||||
Ivy_Obj_t * pObjUndo;
|
||||
if ( p->nUndos >= p->nUndosAlloc )
|
||||
{
|
||||
printf( "Ivy_ManUndoRecord(): Not enough memory for undo.\n" );
|
||||
return;
|
||||
}
|
||||
pObjUndo = p->pUndos + p->nUndos++;
|
||||
// required data for Ivy_ObjCreateGhost()
|
||||
pObjUndo->Type = pObj->Type;
|
||||
pObjUndo->Init = pObj->Init;
|
||||
pObjUndo->Fanin0 = pObj->Fanin0;
|
||||
pObjUndo->Fanin1 = pObj->Fanin1;
|
||||
pObjUndo->fComp0 = pObj->fComp0;
|
||||
pObjUndo->fComp1 = pObj->fComp1;
|
||||
// additional data
|
||||
pObjUndo->Id = pObj->Id;
|
||||
pObjUndo->nRefs = pObj->nRefs;
|
||||
pObjUndo->Level = pObj->Level;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Vec_IntPutLast( Vec_Int_t * vFree, int Last )
|
||||
{
|
||||
int Place, i;
|
||||
// find the entry
|
||||
Place = Vec_IntFind( vFree, Last );
|
||||
if ( Place == -1 )
|
||||
return 0;
|
||||
// shift entries by one
|
||||
assert( vFree->pArray[Place] == Last );
|
||||
for ( i = Place; i < Vec_IntSize(vFree) - 1; i++ )
|
||||
vFree->pArray[i] = vFree->pArray[i+1];
|
||||
// put the entry in the end
|
||||
vFree->pArray[i] = Last;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManUndoPerform( Ivy_Man_t * p, Ivy_Obj_t * pRoot )
|
||||
{
|
||||
Ivy_Obj_t * pObjUndo, * pObjNew;
|
||||
int i;
|
||||
assert( p->nUndos > 0 );
|
||||
assert( p->fRecording == 0 );
|
||||
for ( i = p->nUndos - 1; i >= 0; i-- )
|
||||
{
|
||||
// get the undo object
|
||||
pObjUndo = p->pUndos + i;
|
||||
// if this is the last object
|
||||
if ( i == 0 )
|
||||
Vec_IntPush( p->vFree, pRoot->Id );
|
||||
else
|
||||
Vec_IntPutLast( p->vFree, pObjUndo->Id );
|
||||
// create the new object
|
||||
pObjNew = Ivy_ObjCreate( Ivy_ObjCreateGhost2( p, pObjUndo) );
|
||||
pObjNew->nRefs = pObjUndo->nRefs;
|
||||
pObjNew->Level = pObjUndo->Level;
|
||||
// make sure the object is created in the same place as before
|
||||
assert( pObjNew->Id == pObjUndo->Id );
|
||||
}
|
||||
p->nUndos = 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -66,6 +66,333 @@ void Ivy_ManCleanTravId( Ivy_Man_t * p )
|
|||
pObj->TravId = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes truth table of the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManCollectCut_rec( Ivy_Man_t * p, Ivy_Obj_t * pNode, Vec_Int_t * vNodes )
|
||||
{
|
||||
if ( pNode->fMarkA )
|
||||
return;
|
||||
pNode->fMarkA = 1;
|
||||
assert( Ivy_ObjIsAnd(pNode) || Ivy_ObjIsExor(pNode) );
|
||||
Ivy_ManCollectCut_rec( p, Ivy_ObjFanin0(pNode), vNodes );
|
||||
Ivy_ManCollectCut_rec( p, Ivy_ObjFanin1(pNode), vNodes );
|
||||
Vec_IntPush( vNodes, pNode->Id );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes truth table of the cut.]
|
||||
|
||||
Description [Does not modify the array of leaves. Uses array vTruth to store
|
||||
temporary truth tables. The returned pointer should be used immediately.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManCollectCut( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes )
|
||||
{
|
||||
int i, Leaf;
|
||||
// collect and mark the leaves
|
||||
Vec_IntClear( vNodes );
|
||||
Vec_IntForEachEntry( vLeaves, Leaf, i )
|
||||
{
|
||||
Vec_IntPush( vNodes, Leaf );
|
||||
Ivy_ManObj(p, Leaf)->fMarkA = 1;
|
||||
}
|
||||
// collect and mark the nodes
|
||||
Ivy_ManCollectCut_rec( p, pRoot, vNodes );
|
||||
// clean the nodes
|
||||
Vec_IntForEachEntry( vNodes, Leaf, i )
|
||||
Ivy_ManObj(p, Leaf)->fMarkA = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the pointer to the truth table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned * Ivy_ObjGetTruthStore( int ObjNum, Vec_Int_t * vTruth )
|
||||
{
|
||||
return ((unsigned *)Vec_IntArray(vTruth)) + 8 * ObjNum;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes truth table of the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManCutTruthOne( Ivy_Man_t * p, Ivy_Obj_t * pNode, Vec_Int_t * vTruth, int nWords )
|
||||
{
|
||||
unsigned * pTruth, * pTruth0, * pTruth1;
|
||||
int i;
|
||||
pTruth = Ivy_ObjGetTruthStore( pNode->TravId, vTruth );
|
||||
pTruth0 = Ivy_ObjGetTruthStore( Ivy_ObjFanin0(pNode)->TravId, vTruth );
|
||||
pTruth1 = Ivy_ObjGetTruthStore( Ivy_ObjFanin1(pNode)->TravId, vTruth );
|
||||
if ( Ivy_ObjIsExor(pNode) )
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] = pTruth0[i] ^ pTruth1[i];
|
||||
else if ( !Ivy_ObjFaninC0(pNode) && !Ivy_ObjFaninC1(pNode) )
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] = pTruth0[i] & pTruth1[i];
|
||||
else if ( !Ivy_ObjFaninC0(pNode) && Ivy_ObjFaninC1(pNode) )
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] = pTruth0[i] & ~pTruth1[i];
|
||||
else if ( Ivy_ObjFaninC0(pNode) && !Ivy_ObjFaninC1(pNode) )
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] = ~pTruth0[i] & pTruth1[i];
|
||||
else // if ( Ivy_ObjFaninC0(pNode) && Ivy_ObjFaninC1(pNode) )
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] = ~pTruth0[i] & ~pTruth1[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes truth table of the cut.]
|
||||
|
||||
Description [Does not modify the array of leaves. Uses array vTruth to store
|
||||
temporary truth tables. The returned pointer should be used immediately.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned * Ivy_ManCutTruth( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes, Vec_Int_t * vTruth )
|
||||
{
|
||||
static unsigned uTruths[8][8] = { // elementary truth tables
|
||||
{ 0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA },
|
||||
{ 0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC },
|
||||
{ 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 },
|
||||
{ 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 },
|
||||
{ 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 },
|
||||
{ 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF },
|
||||
{ 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF },
|
||||
{ 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF }
|
||||
};
|
||||
int i, Leaf;
|
||||
// collect the cut
|
||||
Ivy_ManCollectCut( p, pRoot, vLeaves, vNodes );
|
||||
// set the node numbers
|
||||
Vec_IntForEachEntry( vNodes, Leaf, i )
|
||||
Ivy_ManObj(p, Leaf)->TravId = i;
|
||||
// alloc enough memory
|
||||
Vec_IntClear( vTruth );
|
||||
Vec_IntGrow( vTruth, 8 * Vec_IntSize(vNodes) );
|
||||
// set the elementary truth tables
|
||||
Vec_IntForEachEntry( vLeaves, Leaf, i )
|
||||
memcpy( Ivy_ObjGetTruthStore(i, vTruth), uTruths[i], 8 * sizeof(unsigned) );
|
||||
// compute truths for other nodes
|
||||
Vec_IntForEachEntryStart( vNodes, Leaf, i, Vec_IntSize(vLeaves) )
|
||||
Ivy_ManCutTruthOne( p, Ivy_ManObj(p, Leaf), vTruth, 8 );
|
||||
return Ivy_ObjGetTruthStore( pRoot->TravId, vTruth );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect the latches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p )
|
||||
{
|
||||
Vec_Int_t * vLatches;
|
||||
Ivy_Obj_t * pObj;
|
||||
int i;
|
||||
vLatches = Vec_IntAlloc( Ivy_ManLatchNum(p) );
|
||||
Ivy_ManForEachLatch( p, pObj, i )
|
||||
Vec_IntPush( vLatches, pObj->Id );
|
||||
return vLatches;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect the latches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManLevels( Ivy_Man_t * p )
|
||||
{
|
||||
Ivy_Obj_t * pObj;
|
||||
int i, LevelMax = 0;
|
||||
Ivy_ManForEachPo( p, pObj, i )
|
||||
LevelMax = IVY_MAX( LevelMax, (int)Ivy_ObjFanin0(pObj)->Level );
|
||||
return LevelMax;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect the latches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManResetLevels_rec( Ivy_Obj_t * pObj )
|
||||
{
|
||||
if ( pObj->Level || Ivy_ObjIsCi(pObj) )
|
||||
return pObj->Level;
|
||||
if ( Ivy_ObjIsBuf(pObj) )
|
||||
return pObj->Level = Ivy_ManResetLevels_rec( Ivy_ObjFanin0(pObj) );
|
||||
assert( Ivy_ObjIsNode(pObj) );
|
||||
Ivy_ManResetLevels_rec( Ivy_ObjFanin0(pObj) );
|
||||
Ivy_ManResetLevels_rec( Ivy_ObjFanin1(pObj) );
|
||||
return pObj->Level = Ivy_ObjLevelNew( pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect the latches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManResetLevels( Ivy_Man_t * p )
|
||||
{
|
||||
Ivy_Obj_t * pObj;
|
||||
int i;
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
pObj->Level = 0;
|
||||
Ivy_ManForEachPo( p, pObj, i )
|
||||
Ivy_ManResetLevels_rec( Ivy_ObjFanin0(pObj) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively updates fanout levels.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjUpdateLevel_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj )
|
||||
{
|
||||
Ivy_Obj_t * pFanout;
|
||||
Vec_Ptr_t * vFanouts;
|
||||
int i, LevelNew;
|
||||
assert( p->vFanouts );
|
||||
assert( Ivy_ObjIsNode(pObj) );
|
||||
vFanouts = Vec_PtrAlloc( 10 );
|
||||
Ivy_ObjForEachFanout( p, pObj, vFanouts, pFanout, i )
|
||||
{
|
||||
if ( Ivy_ObjIsCo(pFanout) )
|
||||
{
|
||||
// assert( (int)Ivy_ObjFanin0(pFanout)->Level <= p->nLevelMax );
|
||||
continue;
|
||||
}
|
||||
LevelNew = Ivy_ObjLevelNew( pFanout );
|
||||
if ( (int)pFanout->Level == LevelNew )
|
||||
continue;
|
||||
pFanout->Level = LevelNew;
|
||||
Ivy_ObjUpdateLevel_rec( p, pFanout );
|
||||
}
|
||||
Vec_PtrFree( vFanouts );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compute the new required level.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ObjLevelRNew( Ivy_Man_t * p, Ivy_Obj_t * pObj )
|
||||
{
|
||||
Ivy_Obj_t * pFanout;
|
||||
Vec_Ptr_t * vFanouts;
|
||||
int i, Required, LevelNew = 1000000;
|
||||
assert( p->vFanouts && p->vRequired );
|
||||
vFanouts = Vec_PtrAlloc( 10 );
|
||||
Ivy_ObjForEachFanout( p, pObj, vFanouts, pFanout, i )
|
||||
{
|
||||
Required = Vec_IntEntry(p->vRequired, pFanout->Id);
|
||||
LevelNew = IVY_MIN( LevelNew, Required );
|
||||
}
|
||||
Vec_PtrFree( vFanouts );
|
||||
return LevelNew - 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively updates fanout levels.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjUpdateLevelR_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int ReqNew )
|
||||
{
|
||||
Ivy_Obj_t * pFanin;
|
||||
if ( Ivy_ObjIsConst1(pObj) || Ivy_ObjIsCi(pObj) )
|
||||
return;
|
||||
assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj) );
|
||||
// process the first fanin
|
||||
pFanin = Ivy_ObjFanin0(pObj);
|
||||
if ( Vec_IntEntry(p->vRequired, pFanin->Id) > ReqNew - 1 )
|
||||
{
|
||||
Vec_IntWriteEntry( p->vRequired, pFanin->Id, ReqNew - 1 );
|
||||
Ivy_ObjUpdateLevelR_rec( p, pFanin, ReqNew - 1 );
|
||||
}
|
||||
if ( Ivy_ObjIsBuf(pObj) )
|
||||
return;
|
||||
// process the second fanin
|
||||
pFanin = Ivy_ObjFanin1(pObj);
|
||||
if ( Vec_IntEntry(p->vRequired, pFanin->Id) > ReqNew - 1 )
|
||||
{
|
||||
Vec_IntWriteEntry( p->vRequired, pFanin->Id, ReqNew - 1 );
|
||||
Ivy_ObjUpdateLevelR_rec( p, pFanin, ReqNew - 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.]
|
||||
|
|
@ -196,195 +523,6 @@ Ivy_Obj_t * Ivy_ObjRecognizeMux( Ivy_Obj_t * pNode, Ivy_Obj_t ** ppNodeT, Ivy_Ob
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes truth table of the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManCollectCut_rec( Ivy_Obj_t * pNode, Vec_Int_t * vNodes )
|
||||
{
|
||||
if ( pNode->fMarkA )
|
||||
return;
|
||||
pNode->fMarkA = 1;
|
||||
assert( Ivy_ObjIsAnd(pNode) || Ivy_ObjIsExor(pNode) );
|
||||
Ivy_ManCollectCut_rec( Ivy_ObjFanin0(pNode), vNodes );
|
||||
Ivy_ManCollectCut_rec( Ivy_ObjFanin1(pNode), vNodes );
|
||||
Vec_IntPush( vNodes, pNode->Id );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes truth table of the cut.]
|
||||
|
||||
Description [Does not modify the array of leaves. Uses array vTruth to store
|
||||
temporary truth tables. The returned pointer should be used immediately.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManCollectCut( Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes )
|
||||
{
|
||||
int i, Leaf;
|
||||
// collect and mark the leaves
|
||||
Vec_IntClear( vNodes );
|
||||
Vec_IntForEachEntry( vLeaves, Leaf, i )
|
||||
{
|
||||
Vec_IntPush( vNodes, Leaf );
|
||||
Ivy_ObjObj(pRoot, Leaf)->fMarkA = 1;
|
||||
}
|
||||
// collect and mark the nodes
|
||||
Ivy_ManCollectCut_rec( pRoot, vNodes );
|
||||
// clean the nodes
|
||||
Vec_IntForEachEntry( vNodes, Leaf, i )
|
||||
Ivy_ObjObj(pRoot, Leaf)->fMarkA = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the pointer to the truth table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned * Ivy_ObjGetTruthStore( int ObjNum, Vec_Int_t * vTruth )
|
||||
{
|
||||
return ((unsigned *)Vec_IntArray(vTruth)) + 8 * ObjNum;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes truth table of the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManCutTruthOne( Ivy_Obj_t * pNode, Vec_Int_t * vTruth, int nWords )
|
||||
{
|
||||
unsigned * pTruth, * pTruth0, * pTruth1;
|
||||
int i;
|
||||
pTruth = Ivy_ObjGetTruthStore( pNode->TravId, vTruth );
|
||||
pTruth0 = Ivy_ObjGetTruthStore( Ivy_ObjFanin0(pNode)->TravId, vTruth );
|
||||
pTruth1 = Ivy_ObjGetTruthStore( Ivy_ObjFanin1(pNode)->TravId, vTruth );
|
||||
if ( Ivy_ObjIsExor(pNode) )
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] = pTruth0[i] ^ pTruth1[i];
|
||||
else if ( !Ivy_ObjFaninC0(pNode) && !Ivy_ObjFaninC1(pNode) )
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] = pTruth0[i] & pTruth1[i];
|
||||
else if ( !Ivy_ObjFaninC0(pNode) && Ivy_ObjFaninC1(pNode) )
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] = pTruth0[i] & ~pTruth1[i];
|
||||
else if ( Ivy_ObjFaninC0(pNode) && !Ivy_ObjFaninC1(pNode) )
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] = ~pTruth0[i] & pTruth1[i];
|
||||
else // if ( Ivy_ObjFaninC0(pNode) && Ivy_ObjFaninC1(pNode) )
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
pTruth[i] = ~pTruth0[i] & ~pTruth1[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes truth table of the cut.]
|
||||
|
||||
Description [Does not modify the array of leaves. Uses array vTruth to store
|
||||
temporary truth tables. The returned pointer should be used immediately.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned * Ivy_ManCutTruth( Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes, Vec_Int_t * vTruth )
|
||||
{
|
||||
static unsigned uTruths[8][8] = { // elementary truth tables
|
||||
{ 0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA },
|
||||
{ 0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC },
|
||||
{ 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 },
|
||||
{ 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 },
|
||||
{ 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 },
|
||||
{ 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF },
|
||||
{ 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF },
|
||||
{ 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF }
|
||||
};
|
||||
int i, Leaf;
|
||||
// collect the cut
|
||||
Ivy_ManCollectCut( pRoot, vLeaves, vNodes );
|
||||
// set the node numbers
|
||||
Vec_IntForEachEntry( vNodes, Leaf, i )
|
||||
Ivy_ObjObj(pRoot, Leaf)->TravId = i;
|
||||
// alloc enough memory
|
||||
Vec_IntClear( vTruth );
|
||||
Vec_IntGrow( vTruth, 8 * Vec_IntSize(vNodes) );
|
||||
// set the elementary truth tables
|
||||
Vec_IntForEachEntry( vLeaves, Leaf, i )
|
||||
memcpy( Ivy_ObjGetTruthStore(i, vTruth), uTruths[i], 8 * sizeof(unsigned) );
|
||||
// compute truths for other nodes
|
||||
Vec_IntForEachEntryStart( vNodes, Leaf, i, Vec_IntSize(vLeaves) )
|
||||
Ivy_ManCutTruthOne( Ivy_ObjObj(pRoot, Leaf), vTruth, 8 );
|
||||
return Ivy_ObjGetTruthStore( pRoot->TravId, vTruth );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect the latches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p )
|
||||
{
|
||||
Vec_Int_t * vLatches;
|
||||
Ivy_Obj_t * pObj;
|
||||
int i;
|
||||
vLatches = Vec_IntAlloc( Ivy_ManLatchNum(p) );
|
||||
Ivy_ManForEachLatch( p, pObj, i )
|
||||
Vec_IntPush( vLatches, pObj->Id );
|
||||
return vLatches;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect the latches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ManReadLevels( Ivy_Man_t * p )
|
||||
{
|
||||
Ivy_Obj_t * pObj;
|
||||
int i, LevelMax = 0;
|
||||
Ivy_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
pObj = Ivy_ObjFanin0(pObj);
|
||||
LevelMax = IVY_MAX( LevelMax, (int)pObj->Level );
|
||||
}
|
||||
return LevelMax;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the real fanin.]
|
||||
|
|
@ -399,185 +537,12 @@ int Ivy_ManReadLevels( Ivy_Man_t * p )
|
|||
Ivy_Obj_t * Ivy_ObjReal( Ivy_Obj_t * pObj )
|
||||
{
|
||||
Ivy_Obj_t * pFanin;
|
||||
if ( !Ivy_ObjIsBuf( Ivy_Regular(pObj) ) )
|
||||
if ( pObj == NULL || !Ivy_ObjIsBuf( Ivy_Regular(pObj) ) )
|
||||
return pObj;
|
||||
pFanin = Ivy_ObjReal( Ivy_ObjChild0(Ivy_Regular(pObj)) );
|
||||
return Ivy_NotCond( pFanin, Ivy_IsComplement(pObj) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if the cube has exactly one 1.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_TruthHasOneOne( unsigned uCube )
|
||||
{
|
||||
return (uCube & (uCube - 1)) == 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if two cubes are distance-1.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_TruthCubesDist1( unsigned uCube1, unsigned uCube2 )
|
||||
{
|
||||
unsigned uTemp = uCube1 | uCube2;
|
||||
return Ivy_TruthHasOneOne( (uTemp >> 1) & uTemp & 0x55555555 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if two cubes differ in only one literal.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Ivy_TruthCubesDiff1( unsigned uCube1, unsigned uCube2 )
|
||||
{
|
||||
unsigned uTemp = uCube1 ^ uCube2;
|
||||
return Ivy_TruthHasOneOne( ((uTemp >> 1) | uTemp) & 0x55555555 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Combines two distance 1 cubes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline unsigned Ivy_TruthCubesMerge( unsigned uCube1, unsigned uCube2 )
|
||||
{
|
||||
unsigned uTemp;
|
||||
uTemp = uCube1 | uCube2;
|
||||
uTemp &= (uTemp >> 1) & 0x55555555;
|
||||
assert( Ivy_TruthHasOneOne(uTemp) );
|
||||
uTemp |= (uTemp << 1);
|
||||
return (uCube1 | uCube2) ^ uTemp;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Estimates the number of AIG nodes in the truth table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_TruthEstimateNodes( unsigned * pTruth, int nVars )
|
||||
{
|
||||
static unsigned short uResult[256];
|
||||
static unsigned short uCover[81*81];
|
||||
static char pVarCount[81*81];
|
||||
int nMints, uCube, uCubeNew, i, k, c, nCubes, nRes, Counter;
|
||||
assert( nVars <= 8 );
|
||||
// create the cover
|
||||
nCubes = 0;
|
||||
nMints = (1 << nVars);
|
||||
for ( i = 0; i < nMints; i++ )
|
||||
if ( pTruth[i/32] & (1 << (i & 31)) )
|
||||
{
|
||||
uCube = 0;
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
if ( i & (1 << k) )
|
||||
uCube |= (1 << ((k<<1)+1));
|
||||
else
|
||||
uCube |= (1 << ((k<<1)+0));
|
||||
uCover[nCubes] = uCube;
|
||||
pVarCount[nCubes] = nVars;
|
||||
nCubes++;
|
||||
// Extra_PrintBinary( stdout, &uCube, 8 ); printf( "\n" );
|
||||
}
|
||||
assert( nCubes <= 256 );
|
||||
// reduce the cover by building larger cubes
|
||||
for ( i = 1; i < nCubes; i++ )
|
||||
for ( k = 0; k < i; k++ )
|
||||
if ( pVarCount[i] && pVarCount[i] == pVarCount[k] && Ivy_TruthCubesDist1(uCover[i], uCover[k]) )
|
||||
{
|
||||
uCubeNew = Ivy_TruthCubesMerge(uCover[i], uCover[k]);
|
||||
for ( c = i; c < nCubes; c++ )
|
||||
if ( uCubeNew == uCover[c] )
|
||||
break;
|
||||
if ( c != nCubes )
|
||||
continue;
|
||||
uCover[nCubes] = uCubeNew;
|
||||
pVarCount[nCubes] = pVarCount[i] - 1;
|
||||
nCubes++;
|
||||
assert( nCubes < 81*81 );
|
||||
// Extra_PrintBinary( stdout, &uCubeNew, 8 ); printf( "\n" );
|
||||
// c = c;
|
||||
}
|
||||
// compact the cover
|
||||
nRes = 0;
|
||||
for ( i = nCubes -1; i >= 0; i-- )
|
||||
{
|
||||
for ( k = 0; k < nRes; k++ )
|
||||
if ( (uCover[i] & uResult[k]) == uResult[k] )
|
||||
break;
|
||||
if ( k != nRes )
|
||||
continue;
|
||||
uResult[nRes++] = uCover[i];
|
||||
}
|
||||
// count the number of literals
|
||||
Counter = 0;
|
||||
for ( i = 0; i < nRes; i++ )
|
||||
{
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
if ( uResult[i] & (3 << (k<<1)) )
|
||||
Counter++;
|
||||
}
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Tests the cover procedure.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_TruthEstimateNodesTest()
|
||||
{
|
||||
unsigned uTruth[8];
|
||||
int i;
|
||||
for ( i = 0; i < 8; i++ )
|
||||
uTruth[i] = ~(unsigned)0;
|
||||
uTruth[3] ^= (1 << 13);
|
||||
// uTruth[4] = 0xFFFFF;
|
||||
// uTruth[0] = 0xFF;
|
||||
// uTruth[0] ^= (1 << 3);
|
||||
printf( "Number = %d.\n", Ivy_TruthEstimateNodes(uTruth, 8) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ SRC += src/temp/ivy/ivyBalance.c \
|
|||
src/temp/ivy/ivyCut.c \
|
||||
src/temp/ivy/ivyDfs.c \
|
||||
src/temp/ivy/ivyDsd.c \
|
||||
src/temp/ivy/ivyFanout.c \
|
||||
src/temp/ivy/ivyMan.c \
|
||||
src/temp/ivy/ivyMem.c \
|
||||
src/temp/ivy/ivyMulti.c \
|
||||
src/temp/ivy/ivyObj.c \
|
||||
src/temp/ivy/ivyOper.c \
|
||||
|
|
@ -12,5 +14,4 @@ SRC += src/temp/ivy/ivyBalance.c \
|
|||
src/temp/ivy/ivyRwrPre.c \
|
||||
src/temp/ivy/ivySeq.c \
|
||||
src/temp/ivy/ivyTable.c \
|
||||
src/temp/ivy/ivyUndo.c \
|
||||
src/temp/ivy/ivyUtil.c
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
SRC += src/temp/player/playerAbc.c \
|
||||
src/temp/player/playerBuild.c \
|
||||
SRC += src/temp/player/playerToAbc.c \
|
||||
src/temp/player/playerCore.c \
|
||||
src/temp/player/playerMan.c \
|
||||
src/temp/player/playerUtil.c
|
||||
|
|
|
|||
|
|
@ -78,27 +78,17 @@ struct Pla_Man_t_
|
|||
|
||||
#define PLA_EMPTY ((Esop_Cube_t *)1)
|
||||
|
||||
static inline Pla_Man_t * Ivy_ObjPlaMan( Ivy_Obj_t * pObj ) { return (Pla_Man_t *)Ivy_ObjMan(pObj)->pData; }
|
||||
static inline Pla_Obj_t * Ivy_ObjPlaStr( Ivy_Obj_t * pObj ) { return Ivy_ObjPlaMan(pObj)->pPlaStrs + pObj->Id; }
|
||||
|
||||
static inline unsigned * Ivy_ObjGetTruth( Ivy_Obj_t * pObj )
|
||||
{
|
||||
Ivy_Man_t * p = Ivy_ObjMan(pObj);
|
||||
int Offset = Vec_IntEntry( p->vTruths, pObj->Id );
|
||||
return Offset < 0 ? NULL : p->pMemory + Offset;
|
||||
|
||||
}
|
||||
static inline Pla_Man_t * Ivy_ObjPlaMan( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { return (Pla_Man_t *)p->pData; }
|
||||
static inline Pla_Obj_t * Ivy_ObjPlaStr( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { return ((Pla_Man_t *)p->pData)->pPlaStrs + pObj->Id; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== playerAbc.c ==============================================================*/
|
||||
/*=== playerToAbc.c ==============================================================*/
|
||||
extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nFaninMax, int fVerbose );
|
||||
/*=== playerBuild.c ============================================================*/
|
||||
extern Ivy_Man_t * Pla_ManToAig( Ivy_Man_t * p );
|
||||
/*=== playerCore.c =============================================================*/
|
||||
extern Ivy_Man_t * Pla_ManDecompose( Ivy_Man_t * p, int nLutMax, int nPlaMax, int fVerbose );
|
||||
extern Pla_Man_t * Pla_ManDecompose( Ivy_Man_t * p, int nLutMax, int nPlaMax, int fVerbose );
|
||||
/*=== playerMan.c ==============================================================*/
|
||||
extern Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * p, int nLutMax, int nPlaMax );
|
||||
extern void Pla_ManFree( Pla_Man_t * p );
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * p );
|
|||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Gives the current ABC network to PLAyer for processing.]
|
||||
|
|
@ -65,7 +67,7 @@ void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose )
|
|||
if ( fUseRewriting )
|
||||
{
|
||||
// simplify
|
||||
pMan = Ivy_ManResyn( pManExt = pMan, 1 );
|
||||
pMan = Ivy_ManResyn( pManExt = pMan, 1, 0 );
|
||||
Ivy_ManStop( pManExt );
|
||||
if ( fVerbose )
|
||||
Ivy_ManPrintStats( pMan );
|
||||
|
|
@ -217,6 +219,7 @@ Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan )
|
|||
return pNtkNew;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ static int Pla_ManToAigLutFuncs( Ivy_Man_t * pNew, Ivy_Man_t * pOld );
|
|||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs the AIG manager (IVY) for the network after mapping.]
|
||||
|
|
@ -93,7 +95,7 @@ Ivy_Obj_t * Pla_ManToAig_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld )
|
|||
return Ivy_ManObj( pNew, pObjOld->TravId );
|
||||
assert( Ivy_ObjIsAnd(pObjOld) || Ivy_ObjIsExor(pObjOld) );
|
||||
// get the support and the cover
|
||||
pStr = Ivy_ObjPlaStr( pObjOld );
|
||||
pStr = Ivy_ObjPlaStr( pNew, pObjOld );
|
||||
if ( Vec_IntSize( &pStr->vSupp[0] ) <= p->nLutMax )
|
||||
{
|
||||
vSupp = &pStr->vSupp[0];
|
||||
|
|
@ -246,10 +248,10 @@ int Pla_ManToAigLutFuncs( Ivy_Man_t * pNew, Ivy_Man_t * pOld )
|
|||
if ( !Ivy_ObjIsLut(pObjNew) )
|
||||
continue;
|
||||
pObjOld = Ivy_ManObj( pOld, pObjNew->TravId );
|
||||
vSupp = Ivy_ObjPlaStr(pObjOld)->vSupp;
|
||||
vSupp = Ivy_ObjPlaStr(pNew, pObjOld)->vSupp;
|
||||
assert( Vec_IntSize(vSupp) <= 8 );
|
||||
pTruth = Ivy_ObjGetTruth( pObjNew );
|
||||
pComputed = Ivy_ManCutTruth( pObjOld, vSupp, vNodes, vTemp );
|
||||
pComputed = Ivy_ManCutTruth( pNew, pObjOld, vSupp, vNodes, vTemp );
|
||||
// check if the truth table is constant 0
|
||||
for ( k = 0; k < 8; k++ )
|
||||
if ( pComputed[k] )
|
||||
|
|
@ -272,6 +274,8 @@ int Pla_ManToAigLutFuncs( Ivy_Man_t * pNew, Ivy_Man_t * pOld )
|
|||
return Counter;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -44,10 +44,9 @@ static void Pla_NodeGetSuppsAndCovers( Pla_Man_t * p, Ivy_Obj_t * pObj, int Leve
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Man_t * Pla_ManDecompose( Ivy_Man_t * pAig, int nLutMax, int nPlaMax, int fVerbose )
|
||||
Pla_Man_t * Pla_ManDecompose( Ivy_Man_t * pAig, int nLutMax, int nPlaMax, int fVerbose )
|
||||
{
|
||||
Pla_Man_t * p;
|
||||
Ivy_Man_t * pAigNew;
|
||||
p = Pla_ManAlloc( pAig, nLutMax, nPlaMax );
|
||||
if ( !Pla_ManDecomposeInt( p ) )
|
||||
{
|
||||
|
|
@ -55,12 +54,7 @@ Ivy_Man_t * Pla_ManDecompose( Ivy_Man_t * pAig, int nLutMax, int nPlaMax, int fV
|
|||
Pla_ManFree( p );
|
||||
return NULL;
|
||||
}
|
||||
pAigNew = Pla_ManToAig( pAig );
|
||||
// if ( fVerbose )
|
||||
// printf( "PLA stats: Both = %6d. Pla = %6d. Lut = %6d. Total = %6d. Deref = %6d.\n",
|
||||
// p->nNodesBoth, p->nNodesPla, p->nNodesLut, p->nNodes, p->nNodesDeref );
|
||||
Pla_ManFree( p );
|
||||
return pAigNew;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -84,7 +78,7 @@ int Pla_ManDecomposeInt( Pla_Man_t * p )
|
|||
// prepare the PI structures
|
||||
Ivy_ManForEachPi( pAig, pObj, i )
|
||||
{
|
||||
pStr = Ivy_ObjPlaStr( pObj );
|
||||
pStr = Ivy_ObjPlaStr( pAig, pObj );
|
||||
pStr->fFixed = 1;
|
||||
pStr->Depth = 0;
|
||||
pStr->nRefs = (unsigned)pObj->nRefs;
|
||||
|
|
@ -142,9 +136,9 @@ int Pla_ManDecomposeNode( Pla_Man_t * p, Ivy_Obj_t * pObj )
|
|||
p->nNodes++;
|
||||
|
||||
// get the structures
|
||||
pStr = Ivy_ObjPlaStr( pObj );
|
||||
pStr0 = Ivy_ObjPlaStr( Ivy_ObjFanin0( pObj ) );
|
||||
pStr1 = Ivy_ObjPlaStr( Ivy_ObjFanin1( pObj ) );
|
||||
pStr = Ivy_ObjPlaStr( p->pManAig, pObj );
|
||||
pStr0 = Ivy_ObjPlaStr( p->pManAig, Ivy_ObjFanin0( pObj ) );
|
||||
pStr1 = Ivy_ObjPlaStr( p->pManAig, Ivy_ObjFanin1( pObj ) );
|
||||
vSupp0 = &pStr->vSupp[0];
|
||||
vSupp1 = &pStr->vSupp[1];
|
||||
pStr->pCover[0] = PLA_EMPTY;
|
||||
|
|
@ -263,9 +257,9 @@ void Pla_NodeGetSuppsAndCovers( Pla_Man_t * p, Ivy_Obj_t * pObj, int Level,
|
|||
pFan0 = Ivy_ObjFanin0( pObj );
|
||||
pFan1 = Ivy_ObjFanin1( pObj );
|
||||
// get the structures
|
||||
pStr = Ivy_ObjPlaStr( pObj );
|
||||
pStr0 = Ivy_ObjPlaStr( pFan0 );
|
||||
pStr1 = Ivy_ObjPlaStr( pFan1 );
|
||||
pStr = Ivy_ObjPlaStr( p->pManAig, pObj );
|
||||
pStr0 = Ivy_ObjPlaStr( p->pManAig, pFan0 );
|
||||
pStr1 = Ivy_ObjPlaStr( p->pManAig, pFan1 );
|
||||
// make sure the fanins are processed
|
||||
assert( Ivy_ObjIsPi(pFan0) || pStr0->Depth > 0 );
|
||||
assert( Ivy_ObjIsPi(pFan1) || pStr1->Depth > 0 );
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * pAig, int nLutMax, int nPlaMax )
|
|||
pMan->vTriv0 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv0, -1 );
|
||||
pMan->vTriv1 = Vec_IntAlloc( 1 ); Vec_IntPush( pMan->vTriv1, -1 );
|
||||
// allocate memory for object structures
|
||||
pMan->pPlaStrs = ALLOC( Pla_Obj_t, sizeof(Pla_Obj_t) * Ivy_ManObjIdNext(pAig) );
|
||||
memset( pMan->pPlaStrs, 0, sizeof(Pla_Obj_t) * Ivy_ManObjIdNext(pAig) );
|
||||
pMan->pPlaStrs = ALLOC( Pla_Obj_t, sizeof(Pla_Obj_t) * (Ivy_ManObjIdMax(pAig)+1) );
|
||||
memset( pMan->pPlaStrs, 0, sizeof(Pla_Obj_t) * (Ivy_ManObjIdMax(pAig)+1) );
|
||||
// create the cube manager
|
||||
pMan->pManMin = Esop_ManAlloc( nPlaMax );
|
||||
// save the resulting manager
|
||||
|
|
@ -90,7 +90,7 @@ void Pla_ManFree( Pla_Man_t * p )
|
|||
Vec_IntFree( p->vComTo1 );
|
||||
Vec_IntFree( p->vPairs0 );
|
||||
Vec_IntFree( p->vPairs1 );
|
||||
for ( i = 0, pStr = p->pPlaStrs; i < Ivy_ManObjIdNext(p->pManAig); i++, pStr++ )
|
||||
for ( i = 0, pStr = p->pPlaStrs; i <= Ivy_ManObjIdMax(p->pManAig); i++, pStr++ )
|
||||
FREE( pStr->vSupp[0].pArray ), FREE( pStr->vSupp[1].pArray );
|
||||
free( p->pPlaStrs );
|
||||
free( p );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,316 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [playerToAbc.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [PLAyer decomposition package.]
|
||||
|
||||
Synopsis [Bridge between ABC and PLAyer.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 20, 2006.]
|
||||
|
||||
Revision [$Id: playerToAbc.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "player.h"
|
||||
#include "abc.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * p );
|
||||
static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p );
|
||||
static Abc_Obj_t * Ivy_ManToAbc_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Pla_Man_t * p, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp );
|
||||
static Abc_Obj_t * Ivy_ManToAigCube( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Esop_Cube_t * pCube, Vec_Int_t * vSupp );
|
||||
|
||||
static inline void Abc_ObjSetIvy2Abc( Ivy_Man_t * p, int IvyId, Abc_Obj_t * pObjAbc ) { assert(Vec_PtrEntry(p->pCopy, IvyId) == NULL); assert(!Abc_ObjIsComplement(pObjAbc)); Vec_PtrWriteEntry( p->pCopy, IvyId, pObjAbc ); }
|
||||
static inline Abc_Obj_t * Abc_ObjGetIvy2Abc( Ivy_Man_t * p, int IvyId ) { return Vec_PtrEntry( p->pCopy, IvyId ); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Gives the current ABC network to PLAyer for processing.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose )
|
||||
{
|
||||
int fUseRewriting = 1;
|
||||
Pla_Man_t * p;
|
||||
Ivy_Man_t * pMan, * pManExt;
|
||||
Abc_Ntk_t * pNtkAig;
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
return NULL;
|
||||
// convert to the new AIG manager
|
||||
pMan = Ivy_ManFromAbc( pNtk );
|
||||
// check the correctness of conversion
|
||||
if ( !Ivy_ManCheck( pMan ) )
|
||||
{
|
||||
printf( "Abc_NtkPlayer: Internal AIG check has failed.\n" );
|
||||
Ivy_ManStop( pMan );
|
||||
return NULL;
|
||||
}
|
||||
if ( fVerbose )
|
||||
Ivy_ManPrintStats( pMan );
|
||||
if ( fUseRewriting )
|
||||
{
|
||||
// simplify
|
||||
pMan = Ivy_ManResyn( pManExt = pMan, 1, 0 );
|
||||
Ivy_ManStop( pManExt );
|
||||
if ( fVerbose )
|
||||
Ivy_ManPrintStats( pMan );
|
||||
}
|
||||
// perform decomposition/mapping into PLAs/LUTs
|
||||
p = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose );
|
||||
// convert from the extended AIG manager into an SOP network
|
||||
pNtkAig = Ivy_ManToAbc( pNtk, pMan, p );
|
||||
Pla_ManFree( p );
|
||||
Ivy_ManStop( pMan );
|
||||
// chech the resulting network
|
||||
if ( !Abc_NtkCheck( pNtkAig ) )
|
||||
{
|
||||
printf( "Abc_NtkPlayer: The network check has failed.\n" );
|
||||
Abc_NtkDelete( pNtkAig );
|
||||
return NULL;
|
||||
}
|
||||
return pNtkAig;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts from strashed AIG in ABC into strash AIG in IVY.]
|
||||
|
||||
Description [Assumes DFS ordering of nodes in the AIG of ABC.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_Man_t * Ivy_ManFromAbc( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Ivy_Man_t * pMan;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
// create the manager
|
||||
pMan = Ivy_ManStart();
|
||||
// create the PIs
|
||||
Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)Ivy_ManConst1(pMan);
|
||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
pObj->pCopy = (Abc_Obj_t *)Ivy_ObjCreatePi(pMan);
|
||||
// perform the conversion of the internal nodes
|
||||
Abc_AigForEachAnd( pNtk, pObj, i )
|
||||
pObj->pCopy = (Abc_Obj_t *)Ivy_And( pMan, (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj), (Ivy_Obj_t *)Abc_ObjChild1Copy(pObj) );
|
||||
// create the POs
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
Ivy_ObjCreatePo( pMan, (Ivy_Obj_t *)Abc_ObjChild0Copy(pObj) );
|
||||
Ivy_ManCleanup( pMan );
|
||||
return pMan;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs the ABD network after mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Abc_Obj_t * pObjAbc, * pObj;
|
||||
Ivy_Obj_t * pObjIvy;
|
||||
Vec_Int_t * vNodes, * vTemp;
|
||||
int i;
|
||||
// start mapping from Ivy into Abc
|
||||
pMan->pCopy = Vec_PtrStart( Ivy_ManObjIdMax(pMan) + 1 );
|
||||
// start the new ABC network
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
|
||||
// transfer the pointers to the basic nodes
|
||||
Abc_ObjSetIvy2Abc( pMan, Ivy_ManConst1(pMan)->Id, Abc_NtkConst1(pNtkNew) );
|
||||
Abc_NtkForEachCi( pNtkNew, pObjAbc, i )
|
||||
Abc_ObjSetIvy2Abc( pMan, Ivy_ManPi(pMan, i)->Id, pObjAbc );
|
||||
// recursively construct the network
|
||||
vNodes = Vec_IntAlloc( 100 );
|
||||
vTemp = Vec_IntAlloc( 100 );
|
||||
Ivy_ManForEachPo( pMan, pObjIvy, i )
|
||||
{
|
||||
// get the new ABC node corresponding to the old fanin of the PO in IVY
|
||||
pObjAbc = Ivy_ManToAbc_rec( pNtkNew, pMan, p, Ivy_ObjFanin0(pObjIvy), vNodes, vTemp );
|
||||
if ( Ivy_ObjFaninC0(pObjIvy) ) // complement
|
||||
{
|
||||
if ( Abc_ObjIsCi(pObjAbc) )
|
||||
pObjAbc = Abc_NodeCreateInv( pNtkNew, pObjAbc );
|
||||
else
|
||||
{
|
||||
// clone the node
|
||||
pObj = Abc_NodeClone( pObjAbc );
|
||||
// set complemented functions
|
||||
pObj->pData = Abc_SopRegister( pNtkNew->pManFunc, pObjAbc->pData );
|
||||
Abc_SopComplement(pObj->pData);
|
||||
// return the new node
|
||||
pObjAbc = pObj;
|
||||
}
|
||||
assert( Abc_SopGetVarNum(pObjAbc->pData) == Abc_ObjFaninNum(pObjAbc) );
|
||||
}
|
||||
Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), pObjAbc );
|
||||
}
|
||||
Vec_IntFree( vTemp );
|
||||
Vec_IntFree( vNodes );
|
||||
Vec_PtrFree( pMan->pCopy );
|
||||
pMan->pCopy = NULL;
|
||||
// remove dangling nodes
|
||||
// Abc_NtkForEachNode( pNtkNew, pObjAbc, i )
|
||||
// if ( Abc_ObjFanoutNum(pObjAbc) == 0 )
|
||||
// Abc_NtkDeleteObj(pObjAbc);
|
||||
Abc_NtkCleanup( pNtkNew, 0 );
|
||||
// fix CIs feeding directly into COs
|
||||
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively construct the new node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Ivy_ManToAbc_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Pla_Man_t * p, Ivy_Obj_t * pObjIvy, Vec_Int_t * vNodes, Vec_Int_t * vTemp )
|
||||
{
|
||||
Vec_Int_t * vSupp;
|
||||
Esop_Cube_t * pCover, * pCube;
|
||||
Abc_Obj_t * pObjAbc, * pFaninAbc;
|
||||
Pla_Obj_t * pStr;
|
||||
int Entry, nCubes, i;
|
||||
unsigned * puTruth;
|
||||
// skip the node if it is a constant or already processed
|
||||
pObjAbc = Abc_ObjGetIvy2Abc( pMan, pObjIvy->Id );
|
||||
if ( pObjAbc )
|
||||
return pObjAbc;
|
||||
assert( Ivy_ObjIsAnd(pObjIvy) || Ivy_ObjIsExor(pObjIvy) );
|
||||
// get the support and the cover
|
||||
pStr = Ivy_ObjPlaStr( pMan, pObjIvy );
|
||||
if ( Vec_IntSize( &pStr->vSupp[0] ) <= p->nLutMax )
|
||||
{
|
||||
vSupp = &pStr->vSupp[0];
|
||||
pCover = PLA_EMPTY;
|
||||
}
|
||||
else
|
||||
{
|
||||
vSupp = &pStr->vSupp[1];
|
||||
pCover = pStr->pCover[1];
|
||||
assert( pCover != PLA_EMPTY );
|
||||
}
|
||||
// create new node and its fanins
|
||||
Vec_IntForEachEntry( vSupp, Entry, i )
|
||||
Ivy_ManToAbc_rec( pNtkNew, pMan, p, Ivy_ManObj(pMan, Entry), vNodes, vTemp );
|
||||
// consider the case of a LUT
|
||||
if ( pCover == PLA_EMPTY )
|
||||
{
|
||||
pObjAbc = Abc_NtkCreateNode( pNtkNew );
|
||||
Vec_IntForEachEntry( vSupp, Entry, i )
|
||||
Abc_ObjAddFanin( pObjAbc, Abc_ObjGetIvy2Abc(pMan, Entry) );
|
||||
// check if the truth table is constant 0
|
||||
puTruth = Ivy_ManCutTruth( pMan, pObjIvy, vSupp, vNodes, vTemp );
|
||||
for ( i = 0; i < 8; i++ )
|
||||
if ( puTruth[i] )
|
||||
break;
|
||||
// create constant 0 node
|
||||
if ( i == 8 )
|
||||
{
|
||||
pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Vec_IntSize(vSupp), NULL );
|
||||
pObjAbc = Abc_NodeCreateConst0( pNtkNew );
|
||||
}
|
||||
else
|
||||
pObjAbc->pData = Abc_SopCreateFromTruth( pNtkNew->pManFunc, Vec_IntSize(vSupp), puTruth );
|
||||
}
|
||||
else
|
||||
{
|
||||
// for each cube, construct the node
|
||||
nCubes = Esop_CoverCountCubes( pCover );
|
||||
if ( nCubes == 0 )
|
||||
pObjAbc = Abc_NodeCreateConst0( pNtkNew );
|
||||
else if ( nCubes == 1 )
|
||||
pObjAbc = Ivy_ManToAigCube( pNtkNew, pMan, pObjIvy, pCover, vSupp );
|
||||
else
|
||||
{
|
||||
pObjAbc = Abc_NtkCreateNode( pNtkNew );
|
||||
Esop_CoverForEachCube( pCover, pCube )
|
||||
{
|
||||
pFaninAbc = Ivy_ManToAigCube( pNtkNew, pMan, pObjIvy, pCube, vSupp );
|
||||
Abc_ObjAddFanin( pObjAbc, pFaninAbc );
|
||||
}
|
||||
pObjAbc->pData = Abc_SopCreateXorSpecial( pNtkNew->pManFunc, Abc_ObjFaninNum(pObjAbc) );
|
||||
}
|
||||
}
|
||||
Abc_ObjSetIvy2Abc( pMan, pObjIvy->Id, pObjAbc );
|
||||
return pObjAbc;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the decomposed network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Ivy_ManToAigCube( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj_t * pObjIvy, Esop_Cube_t * pCube, Vec_Int_t * vSupp )
|
||||
{
|
||||
int pCompls[PLAYER_FANIN_LIMIT];
|
||||
Abc_Obj_t * pObjAbc, * pFaninAbc;
|
||||
int i, k, Value;
|
||||
// if tautology cube, create constant 1 node
|
||||
if ( pCube->nLits == 0 )
|
||||
return Abc_NodeCreateConst1(pNtkNew);
|
||||
// create AND node
|
||||
pObjAbc = Abc_NtkCreateNode( pNtkNew );
|
||||
for ( i = k = 0; i < (int)pCube->nVars; i++ )
|
||||
{
|
||||
Value = Esop_CubeGetVar( pCube, i );
|
||||
assert( Value != 0 );
|
||||
if ( Value == 3 )
|
||||
continue;
|
||||
pFaninAbc = Abc_ObjGetIvy2Abc( pMan, Vec_IntEntry(vSupp, i) );
|
||||
pFaninAbc = Abc_ObjNotCond( pFaninAbc, Value==1 );
|
||||
Abc_ObjAddFanin( pObjAbc, Abc_ObjRegular(pFaninAbc) );
|
||||
pCompls[k++] = Abc_ObjIsComplement(pFaninAbc);
|
||||
}
|
||||
pObjAbc->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, Abc_ObjFaninNum(pObjAbc), pCompls );
|
||||
assert( Abc_ObjFaninNum(pObjAbc) == (int)pCube->nLits );
|
||||
return pObjAbc;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -281,6 +281,8 @@ Esop_Cube_t * Pla_ManExorTwoCovers( Pla_Man_t * p, Esop_Cube_t * pCover0, Esop_C
|
|||
return pCover;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes area/delay of the mapping.]
|
||||
|
|
@ -342,6 +344,8 @@ void Pla_ManComputeStats( Ivy_Man_t * p, Vec_Int_t * vNodes )
|
|||
printf( "Area = %d. Delay = %d.\n", Area, Delay );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -64,10 +64,10 @@ void Rwt_ManGlobalStart()
|
|||
***********************************************************************/
|
||||
void Rwt_ManGlobalStop()
|
||||
{
|
||||
if ( s_puCanons == NULL ) free( s_puCanons );
|
||||
if ( s_pPhases == NULL ) free( s_pPhases );
|
||||
if ( s_pPerms == NULL ) free( s_pPerms );
|
||||
if ( s_pMap == NULL ) free( s_pMap );
|
||||
FREE( s_puCanons );
|
||||
FREE( s_pPhases );
|
||||
FREE( s_pPerms );
|
||||
FREE( s_pMap );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -278,6 +278,23 @@ static inline int Vec_IntEntry( Vec_Int_t * p, int i )
|
|||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int * Vec_IntEntryP( Vec_Int_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray + i;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -385,7 +402,10 @@ static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Entry )
|
|||
int i;
|
||||
if ( p->nSize >= nSize )
|
||||
return;
|
||||
Vec_IntGrow( p, nSize );
|
||||
if ( p->nSize < 2 * nSize )
|
||||
Vec_IntGrow( p, 2 * nSize );
|
||||
else
|
||||
Vec_IntGrow( p, p->nSize );
|
||||
for ( i = p->nSize; i < nSize; i++ )
|
||||
p->pArray[i] = Entry;
|
||||
p->nSize = nSize;
|
||||
|
|
|
|||
Loading…
Reference in New Issue