Commit 9093ca53 by Alan Mishchenko

Version abc50824

parent d01b1a0e
......@@ -109,6 +109,10 @@ SOURCE=.\src\base\abc\abcAttach.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abc\abcBalance.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abc\abcCheck.c
# End Source File
# Begin Source File
......
No preview for this file type
......@@ -3,6 +3,7 @@ alias clp collapse
alias esd ext_seq_dcs
alias f fraig
alias fs fraig_sweep
alias ft fraig_trust
alias mu renode -m
alias pf print_factor
alias pfan print_fanio
......@@ -20,6 +21,7 @@ alias rsup read_super mcnc5_old.super
alias rlib read_library
alias rw rewrite
alias rf refactor
alias rfz refactor -z
alias sa set autoexec ps
alias so source -x
alias st strash
......
......@@ -1414,9 +1414,10 @@ int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv )
int c;
int nNodeSizeMax;
int nConeSizeMax;
bool fUseZeros;
bool fUseDcs;
bool fVerbose;
extern int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool fUseDcs, bool fVerbose );
extern int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool fUseZeros, bool fUseDcs, bool fVerbose );
pNtk = Abc_FrameReadNet(pAbc);
pOut = Abc_FrameReadOut(pAbc);
......@@ -1424,11 +1425,12 @@ int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults
nNodeSizeMax = 10;
nConeSizeMax = 10;
nConeSizeMax = 16;
fUseZeros = 0;
fUseDcs = 0;
fVerbose = 0;
fVerbose = 1;
util_getopt_reset();
while ( ( c = util_getopt( argc, argv, "NCdvh" ) ) != EOF )
while ( ( c = util_getopt( argc, argv, "NCzdvh" ) ) != EOF )
{
switch ( c )
{
......@@ -1454,6 +1456,9 @@ int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( nConeSizeMax < 0 )
goto usage;
break;
case 'z':
fUseZeros ^= 1;
break;
case 'd':
fUseDcs ^= 1;
break;
......@@ -1483,8 +1488,14 @@ int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
if ( fUseDcs && nNodeSizeMax >= nConeSizeMax )
{
fprintf( pErr, "For don't-care to work, containing cone should be larger than collapsed node.\n" );
return 1;
}
// modify the current network
if ( !Abc_NtkRefactor( pNtk, nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose ) )
if ( !Abc_NtkRefactor( pNtk, nNodeSizeMax, nConeSizeMax, fUseZeros, fUseDcs, fVerbose ) )
{
fprintf( pErr, "Refactoring has failed.\n" );
return 1;
......@@ -1492,11 +1503,12 @@ int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
fprintf( pErr, "usage: refactor [-N num] [-C num] [-dvh]\n" );
fprintf( pErr, "usage: refactor [-N num] [-C num] [-zdvh]\n" );
fprintf( pErr, "\t performs technology-independent refactoring of the AIG\n" );
fprintf( pErr, "\t-N num : the max support of the collapsed node [default = %d]\n", nNodeSizeMax );
fprintf( pErr, "\t-C num : the max support of the containing cone [default = %d]\n", nConeSizeMax );
fprintf( pErr, "\t-d : toggle use of don't-cares [default = %s]\n", fUseDcs? "yes": "no" );
fprintf( pErr, "\t-z : toggle using zero-cost replacements [default = %s]\n", fUseZeros? "yes": "no" );
fprintf( pErr, "\t-d : toggle using don't-cares [default = %s]\n", fUseDcs? "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;
......
......@@ -101,6 +101,7 @@ struct Abc_Time_t_
struct Abc_Obj_t_ // 12 words
{
// high-level information
Abc_Ntk_t * pNtk; // the host network
unsigned Type : 4; // the object type
unsigned fExor : 1; // marks AIG node that is a root of EXOR
unsigned Id : 27; // the ID of the object
......@@ -115,7 +116,6 @@ struct Abc_Obj_t_ // 12 words
Vec_Fan_t vFanins; // the array of fanins
Vec_Fan_t vFanouts; // the array of fanouts
// miscellaneous
Abc_Ntk_t * pNtk; // the host network
void * pData; // the network specific data (SOP, BDD, gate, equiv class, etc)
Abc_Obj_t * pNext; // the next pointer in the hash table
Abc_Obj_t * pCopy; // the copy of this object
......@@ -381,6 +381,7 @@ extern void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Ab
extern void Abc_AigDeleteNode( Abc_Aig_t * pMan, Abc_Obj_t * pOld );
extern bool Abc_AigNodeHasComplFanoutEdge( Abc_Obj_t * pNode );
extern bool Abc_AigNodeHasComplFanoutEdgeTrav( Abc_Obj_t * pNode );
extern void Abc_AigPrintNode( Abc_Obj_t * pNode );
/*=== abcAttach.c ==========================================================*/
extern int Abc_NtkAttach( Abc_Ntk_t * pNtk );
/*=== abcCheck.c ==========================================================*/
......@@ -495,12 +496,15 @@ extern void Abc_NodePrintLevel( FILE * pFile, Abc_Obj_t * pNode );
/*=== abcReconv.c ==========================================================*/
extern Abc_ManCut_t * Abc_NtkManCutStart( int nNodeSizeMax, int nConeSizeMax );
extern void Abc_NtkManCutStop( Abc_ManCut_t * p );
extern Vec_Ptr_t * Abc_NodeFindCut( Abc_ManCut_t * p, Abc_Obj_t * pRoot );
extern Vec_Ptr_t * Abc_NtkManCutReadLeaves( Abc_ManCut_t * p );
extern Vec_Ptr_t * Abc_NodeFindCut( Abc_ManCut_t * p, Abc_Obj_t * pRoot, bool fContain );
extern DdNode * Abc_NodeConeBdd( DdManager * dd, DdNode ** pbVars, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, Vec_Ptr_t * vVisited );
extern DdNode * Abc_NodeConeDcs( DdManager * dd, DdNode ** pbVarsX, DdNode ** pbVarsY, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, Vec_Ptr_t * vVisited );
extern void Abc_NodeCollectTfoCands( Abc_Ntk_t * pNtk, Abc_Obj_t * pRoot, Vec_Ptr_t * vFanins, int LevelMax, Vec_Vec_t * vLevels, Vec_Ptr_t * vResult );
/*=== abcRefs.c ==========================================================*/
extern int Abc_NodeMffcSize( Abc_Obj_t * pNode );
extern int Abc_NodeMffcLabel( Abc_Obj_t * pNode );
extern Vec_Ptr_t * Abc_NodeMffcCollect( Abc_Obj_t * pNode );
extern void Abc_NodeUpdate( Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, Vec_Int_t * vForm, int nGain );
/*=== abcRenode.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple );
......@@ -531,21 +535,22 @@ extern int Abc_SopGetCubeNum( char * pSop );
extern int Abc_SopGetLitNum( char * pSop );
extern int Abc_SopGetVarNum( char * pSop );
extern int Abc_SopGetPhase( char * pSop );
extern int Abc_SopGetIthCareLit( char * pSop, int i );
extern void Abc_SopComplement( char * pSop );
extern bool Abc_SopIsComplement( char * pSop );
extern bool Abc_SopIsConst0( char * pSop );
extern bool Abc_SopIsConst1( char * pSop );
extern bool Abc_SopIsBuf( char * pSop );
extern bool Abc_SopIsInv( char * pSop );
extern bool Abc_SopIsAndType( char * pSop );
extern bool Abc_SopIsOrType( char * pSop );
extern int Abc_SopGetIthCareLit( char * pSop, int i );
extern void Abc_SopComplement( char * pSop );
extern bool Abc_SopCheck( char * pSop, int nFanins );
extern void Abc_SopWriteCnf( FILE * pFile, char * pClauses, Vec_Int_t * vVars );
extern void Abc_SopAddCnfToSolver( solver * pSat, char * pClauses, Vec_Int_t * vVars, Vec_Int_t * vTemp );
/*=== abcStrash.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes );
extern Abc_Obj_t * Abc_NodeStrashDec( Abc_Aig_t * pMan, Vec_Ptr_t * vFanins, Vec_Int_t * vForm );
extern int Abc_NodeStrashDecCount( Abc_Aig_t * pMan, Vec_Ptr_t * vFanins, Vec_Int_t * vForm, Vec_Int_t * vLevels, int NodeMax, int LevelMax );
extern int Abc_NodeStrashDecCount( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, Vec_Ptr_t * vFanins, Vec_Int_t * vForm, Vec_Int_t * vLevels, int NodeMax, int LevelMax );
extern int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 );
extern Abc_Ntk_t * Abc_NtkBalance( Abc_Ntk_t * pNtk, bool fDuplicate );
/*=== abcSweep.c ==========================================================*/
......
/**CFile****************************************************************
FileName [abcBalance.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Performs global balancing of the AIG by the number of levels.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcBalance.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplicate );
static Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, bool fDuplicate );
static Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, int fDuplicate );
static int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Balances the AIG network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkBalance( Abc_Ntk_t * pNtk, bool fDuplicate )
{
int fCheck = 1;
Abc_Ntk_t * pNtkAig;
assert( Abc_NtkIsAig(pNtk) );
// perform balancing
pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_AIG );
Abc_NtkBalancePerform( pNtk, pNtkAig, fDuplicate );
Abc_NtkFinalize( pNtk, pNtkAig );
// make sure everything is okay
if ( fCheck && !Abc_NtkCheck( pNtkAig ) )
{
printf( "Abc_NtkBalance: The network check has failed.\n" );
Abc_NtkDelete( pNtkAig );
return NULL;
}
return pNtkAig;
}
/**Function*************************************************************
Synopsis [Balances the AIG network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplicate )
{
int fCheck = 1;
ProgressBar * pProgress;
Abc_Obj_t * pNode, * pDriver;
int i;
// copy the constant node
Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkAig->pManFunc);
// set the level of PIs of AIG according to the arrival times of the old network
Abc_NtkSetNodeLevelsArrival( pNtk );
// perform balancing of POs
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
Abc_NtkForEachCo( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
// strash the driver node
pDriver = Abc_ObjFanin0(pNode);
Abc_NodeBalance_rec( pNtkAig, pDriver, fDuplicate );
}
Extra_ProgressBarStop( pProgress );
}
/**Function*************************************************************
Synopsis [Rebalances the multi-input node rooted at pNodeOld.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, bool fDuplicate )
{
Abc_Aig_t * pMan = pNtkNew->pManFunc;
Abc_Obj_t * pNodeNew, * pNode1, * pNode2;
Vec_Ptr_t * vSuper;
int i;
assert( !Abc_ObjIsComplement(pNodeOld) );
// return if the result if known
if ( pNodeOld->pCopy )
return pNodeOld->pCopy;
assert( Abc_ObjIsNode(pNodeOld) );
// get the implication supergate
vSuper = Abc_NodeBalanceCone( pNodeOld, fDuplicate );
if ( vSuper->nSize == 0 )
{ // it means that the supergate contains two nodes in the opposite polarity
Vec_PtrFree( vSuper );
pNodeOld->pCopy = Abc_ObjNot(Abc_AigConst1(pMan));
return pNodeOld->pCopy;
}
// for each old node, derive the new well-balanced node
for ( i = 0; i < vSuper->nSize; i++ )
{
pNodeNew = Abc_NodeBalance_rec( pNtkNew, Abc_ObjRegular(vSuper->pArray[i]), fDuplicate );
vSuper->pArray[i] = Abc_ObjNotCond( pNodeNew, Abc_ObjIsComplement(vSuper->pArray[i]) );
}
// sort the new nodes by level in the decreasing order
Vec_PtrSort( vSuper, Abc_NodeCompareLevelsDecrease );
// balance the nodes
assert( vSuper->nSize > 1 );
while ( vSuper->nSize > 1 )
{
pNode1 = Vec_PtrPop(vSuper);
pNode2 = Vec_PtrPop(vSuper);
Abc_VecObjPushUniqueOrderByLevel( vSuper, Abc_AigAnd(pMan, pNode1, pNode2) );
}
// make sure the balanced node is not assigned
assert( pNodeOld->pCopy == NULL );
// mark the old node with the new node
pNodeOld->pCopy = vSuper->pArray[0];
Vec_PtrFree( vSuper );
return pNodeOld->pCopy;
}
/**Function*************************************************************
Synopsis [Collects the nodes in the cone delimited by fMarkA==1.]
Description [Returns -1 if the AND-cone has the same node in both polarities.
Returns 1 if the AND-cone has the same node in the same polarity. Returns 0
if the AND-cone has no repeated nodes.]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, int fDuplicate )
{
Vec_Ptr_t * vNodes;
int RetValue, i;
assert( !Abc_ObjIsComplement(pNode) );
vNodes = Vec_PtrAlloc( 4 );
RetValue = Abc_NodeBalanceCone_rec( pNode, vNodes, 1, fDuplicate );
assert( vNodes->nSize > 0 );
for ( i = 0; i < vNodes->nSize; i++ )
Abc_ObjRegular((Abc_Obj_t *)vNodes->pArray[i])->fMarkB = 0;
if ( RetValue == -1 )
vNodes->nSize = 0;
return vNodes;
}
/**Function*************************************************************
Synopsis [Collects the nodes in the cone delimited by fMarkA==1.]
Description [Returns -1 if the AND-cone has the same node in both polarities.
Returns 1 if the AND-cone has the same node in the same polarity. Returns 0
if the AND-cone has no repeated nodes.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate )
{
int RetValue1, RetValue2, i;
// check if the node is visited
if ( Abc_ObjRegular(pNode)->fMarkB )
{
// check if the node occurs in the same polarity
for ( i = 0; i < vSuper->nSize; i++ )
if ( vSuper->pArray[i] == pNode )
return 1;
// check if the node is present in the opposite polarity
for ( i = 0; i < vSuper->nSize; i++ )
if ( vSuper->pArray[i] == Abc_ObjNot(pNode) )
return -1;
assert( 0 );
return 0;
}
// if the new node is complemented or a PI, another gate begins
if ( !fFirst && (Abc_ObjIsComplement(pNode) || !Abc_ObjIsNode(pNode) || !fDuplicate && (Abc_ObjFanoutNum(pNode) > 1)) )
{
Vec_PtrPush( vSuper, pNode );
Abc_ObjRegular(pNode)->fMarkB = 1;
return 0;
}
assert( !Abc_ObjIsComplement(pNode) );
assert( Abc_ObjIsNode(pNode) );
// go through the branches
RetValue1 = Abc_NodeBalanceCone_rec( Abc_ObjChild0(pNode), vSuper, 0, fDuplicate );
RetValue2 = Abc_NodeBalanceCone_rec( Abc_ObjChild1(pNode), vSuper, 0, fDuplicate );
if ( RetValue1 == -1 || RetValue2 == -1 )
return -1;
// return 1 if at least one branch has a duplicate
return RetValue1 || RetValue2;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -504,7 +504,9 @@ Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type )
***********************************************************************/
void Abc_ObjRecycle( Abc_Obj_t * pObj )
{
Extra_MmFixedEntryRecycle( pObj->pNtk->pMmObj, (char *)pObj );
Abc_Ntk_t * pNtk = pObj->pNtk;
memset( pObj, 0, sizeof(Abc_Obj_t) );
Extra_MmFixedEntryRecycle( pNtk->pMmObj, (char *)pObj );
}
/**Function*************************************************************
......
......@@ -205,7 +205,10 @@ char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFun
{
Vec_StrFill( vCube, nFanins, '-' );
Vec_StrPush( vCube, '\0' );
pSop = Extra_MmFlexEntryFetch( pMan, nFanins + 4 );
if ( pMan )
pSop = Extra_MmFlexEntryFetch( pMan, nFanins + 4 );
else
pSop = ALLOC( char, nFanins + 4 );
if ( bFuncOn == Cudd_ReadLogicZero(dd) )
sprintf( pSop, "%s 0\n", vCube->pArray );
else
......@@ -249,7 +252,7 @@ char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFun
}
else if ( fMode == 0 )
{
// get the ZDD of the positive polarity
// get the ZDD of the negative polarity
bCover = Cudd_zddIsop( dd, Cudd_Not(bFuncOnDc), Cudd_Not(bFuncOn), &zCover );
Cudd_Ref( zCover );
Cudd_Ref( bCover );
......
......@@ -73,9 +73,11 @@ char * Abc_NtkRegisterNamePlus( Abc_Ntk_t * pNtk, char * pName, char * pSuffix )
/**Function*************************************************************
Synopsis [Gets the long name of the node.]
Synopsis [Gets the long name of the object.]
Description [This name is the output net's name.]
Description [The temporary name is stored in a static buffer inside this
procedure. It is important that the name is used before the function is
called again!]
SideEffects []
......
......@@ -24,7 +24,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fReference, bool fLabel );
static int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fReference, bool fLabel, Vec_Ptr_t * vNodes );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
......@@ -48,8 +48,8 @@ int Abc_NodeMffcSize( Abc_Obj_t * pNode )
assert( Abc_ObjIsNode( pNode ) );
if ( Abc_ObjFaninNum(pNode) == 0 )
return 0;
nConeSize1 = Abc_NodeRefDeref( pNode, 0, 0 ); // dereference
nConeSize2 = Abc_NodeRefDeref( pNode, 1, 0 ); // reference
nConeSize1 = Abc_NodeRefDeref( pNode, 0, 0, NULL ); // dereference
nConeSize2 = Abc_NodeRefDeref( pNode, 1, 0, NULL ); // reference
assert( nConeSize1 == nConeSize2 );
assert( nConeSize1 > 0 );
return nConeSize1;
......@@ -57,7 +57,7 @@ int Abc_NodeMffcSize( Abc_Obj_t * pNode )
/**Function*************************************************************
Synopsis [Lavels MFFC with the current traversal ID.]
Synopsis [Labels MFFC with the current traversal ID.]
Description []
......@@ -73,8 +73,8 @@ int Abc_NodeMffcLabel( Abc_Obj_t * pNode )
assert( Abc_ObjIsNode( pNode ) );
if ( Abc_ObjFaninNum(pNode) == 0 )
return 0;
nConeSize1 = Abc_NodeRefDeref( pNode, 0, 0 ); // dereference
nConeSize2 = Abc_NodeRefDeref( pNode, 1, 1 ); // reference
nConeSize1 = Abc_NodeRefDeref( pNode, 0, 1, NULL ); // dereference
nConeSize2 = Abc_NodeRefDeref( pNode, 1, 0, NULL ); // reference
assert( nConeSize1 == nConeSize2 );
assert( nConeSize1 > 0 );
return nConeSize1;
......@@ -82,6 +82,33 @@ int Abc_NodeMffcLabel( Abc_Obj_t * pNode )
/**Function*************************************************************
Synopsis [Collects the nodes in MFFC in the topological order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NodeMffcCollect( Abc_Obj_t * pNode )
{
Vec_Ptr_t * vNodes;
int nConeSize1, nConeSize2;
assert( !Abc_ObjIsComplement( pNode ) );
assert( Abc_ObjIsNode( pNode ) );
vNodes = Vec_PtrAlloc( 8 );
if ( Abc_ObjFaninNum(pNode) == 0 )
return vNodes;
nConeSize1 = Abc_NodeRefDeref( pNode, 0, 0, vNodes ); // dereference
nConeSize2 = Abc_NodeRefDeref( pNode, 1, 0, NULL ); // reference
assert( nConeSize1 == nConeSize2 );
assert( nConeSize1 > 0 );
return vNodes;
}
/**Function*************************************************************
Synopsis [References/references the node and returns MFFC size.]
Description []
......@@ -91,39 +118,48 @@ int Abc_NodeMffcLabel( Abc_Obj_t * pNode )
SeeAlso []
***********************************************************************/
int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fReference, bool fLabel )
int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fReference, bool fLabel, Vec_Ptr_t * vNodes )
{
Abc_Obj_t * pNode0, * pNode1;
int Counter;
// label visited nodes
if ( fLabel )
{
Abc_NodeSetTravIdCurrent( pNode );
//printf( "Labeling " ); Abc_AigPrintNode( pNode );
}
// collect visited nodes
if ( vNodes )
Vec_PtrPush( vNodes, pNode );
// skip the CI
if ( Abc_ObjIsCi(pNode) )
return 0;
// process the internal node
pNode0 = Abc_ObjFanin( pNode, 0 );
pNode1 = Abc_ObjFanin( pNode, 1 );
Counter = 1;
if ( fReference )
{
if ( pNode0->vFanouts.nSize++ == 0 )
Counter += Abc_NodeRefDeref( pNode0, fReference, fLabel );
Counter += Abc_NodeRefDeref( pNode0, fReference, fLabel, vNodes );
if ( pNode1->vFanouts.nSize++ == 0 )
Counter += Abc_NodeRefDeref( pNode1, fReference, fLabel );
Counter += Abc_NodeRefDeref( pNode1, fReference, fLabel, vNodes );
}
else
{
assert( pNode0->vFanouts.nSize > 0 );
assert( pNode1->vFanouts.nSize > 0 );
if ( --pNode0->vFanouts.nSize == 0 )
Counter += Abc_NodeRefDeref( pNode0, fReference, fLabel );
Counter += Abc_NodeRefDeref( pNode0, fReference, fLabel, vNodes );
if ( --pNode1->vFanouts.nSize == 0 )
Counter += Abc_NodeRefDeref( pNode1, fReference, fLabel );
Counter += Abc_NodeRefDeref( pNode1, fReference, fLabel, vNodes );
}
return Counter;
}
/**Function*************************************************************
Synopsis [Replaces MFFC of the node by the new factored.]
Synopsis [Replaces MFFC of the node by the new factored form.]
Description []
......@@ -138,7 +174,7 @@ void Abc_NodeUpdate( Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, Vec_Int_t * vForm,
int nNodesNew, nNodesOld;
nNodesOld = Abc_NtkNodeNum(pNode->pNtk);
// create the new structure of nodes
assert( Vec_PtrSize(vFanins) < Vec_IntSize(vForm) );
assert( vForm->nSize == 1 || Vec_PtrSize(vFanins) < Vec_IntSize(vForm) );
pNodeNew = Abc_NodeStrashDec( pNode->pNtk->pManFunc, vFanins, vForm );
// remove the old nodes
Abc_AigReplace( pNode->pNtk->pManFunc, pNode, pNodeNew );
......
......@@ -60,13 +60,16 @@ int Abc_NtkRewrite( Abc_Ntk_t * pNtk )
pProgress = Extra_ProgressBarStart( stdout, nNodes );
Abc_NtkForEachNode( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, nNodes, NULL );
Extra_ProgressBarUpdate( pProgress, i, NULL );
// stop if all nodes have been tried once
if ( i >= nNodes )
break;
// skip the constant node
if ( Abc_NodeIsConst(pNode) )
continue;
// for each cut, try to resynthesize it
if ( (nGain = Rwr_NodeRewrite( p, pNode )) >= 0 )
Abc_NodeUpdate( pNode, Rwr_ManReadFanins(p), Rwr_ManReadDecs(p), nGain );
// check the improvement
if ( i == nNodes )
break;
}
Extra_ProgressBarStop( pProgress );
// delete the manager
......
......@@ -355,6 +355,82 @@ int Abc_SopGetPhase( char * pSop )
/**Function*************************************************************
Synopsis [Returns the i-th literal of the cover.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_SopGetIthCareLit( char * pSop, int i )
{
char * pCube;
int nVars, c;
nVars = Abc_SopGetVarNum( pSop );
for ( c = 0; ; c++ )
{
// get the cube
pCube = pSop + c * (nVars + 3);
if ( *pCube == 0 )
break;
// get the literal
if ( pCube[i] != '-' )
return pCube[i] - '0';
}
return -1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_SopComplement( char * pSop )
{
char * pCur;
for ( pCur = pSop; *pCur; pCur++ )
if ( *pCur == '\n' )
{
if ( *(pCur - 1) == '0' )
*(pCur - 1) = '1';
else if ( *(pCur - 1) == '1' )
*(pCur - 1) = '0';
else
assert( 0 );
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
bool Abc_SopIsComplement( char * pSop )
{
char * pCur;
for ( pCur = pSop; *pCur; pCur++ )
if ( *pCur == '\n' )
return (int)(*(pCur - 1) == '0');
assert( 0 );
return 0;
}
/**Function*************************************************************
Synopsis [Checks if the cover is constant 0.]
Description []
......@@ -481,61 +557,6 @@ bool Abc_SopIsOrType( char * pSop )
/**Function*************************************************************
Synopsis [Returns the i-th literal of the cover.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_SopGetIthCareLit( char * pSop, int i )
{
char * pCube;
int nVars, c;
nVars = Abc_SopGetVarNum( pSop );
for ( c = 0; ; c++ )
{
// get the cube
pCube = pSop + c * (nVars + 3);
if ( *pCube == 0 )
break;
// get the literal
if ( pCube[i] != '-' )
return pCube[i] - '0';
}
return -1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_SopComplement( char * pSop )
{
char * pCur;
for ( pCur = pSop; *pCur; pCur++ )
if ( *pCur == '\n' )
{
if ( *(pCur - 1) == '0' )
*(pCur - 1) = '1';
else if ( *(pCur - 1) == '1' )
*(pCur - 1) = '0';
else
assert( 0 );
}
}
/**Function*************************************************************
Synopsis []
Description []
......
......@@ -82,7 +82,7 @@ Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p )
ProgressBar * pProgress;
Vec_Ptr_t * vTokens;
Abc_Ntk_t * pNtk;
Abc_Obj_t * pTerm, * pNode;
Abc_Obj_t * pTermPi, * pTermPo, * pNode;
Vec_Str_t ** ppSops;
char Buffer[100];
int nInputs = -1, nOutputs = -1, nProducts = -1;
......@@ -169,13 +169,16 @@ Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p )
// create the PO drivers and add them
// start the SOP covers
ppSops = ALLOC( Vec_Str_t *, nOutputs );
Abc_NtkForEachPo( pNtk, pTerm, i )
Abc_NtkForEachPo( pNtk, pTermPo, i )
{
ppSops[i] = Vec_StrAlloc( 100 );
// create the node
pNode = Abc_NtkCreateNode(pNtk);
for ( k = 0; k < nInputs; k++ )
Abc_ObjAddFanin( pNode, Abc_NtkPi(pNtk,k) );
Abc_ObjAddFanin( Abc_ObjFanout0(pTerm), pNode );
// connect the node to the PO net
Abc_ObjAddFanin( Abc_ObjFanin0Ntk(pTermPo), pNode );
// connect the node to the PI nets
Abc_NtkForEachPi( pNtk, pTermPi, k )
Abc_ObjAddFanin( pNode, Abc_ObjFanout0Ntk(pTermPi) );
}
}
// read the cubes
......@@ -219,9 +222,9 @@ Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p )
nCubes, nProducts );
// add the SOP covers
Abc_NtkForEachPo( pNtk, pTerm, i )
Abc_NtkForEachPo( pNtk, pTermPo, i )
{
pNode = Abc_ObjFanin0Ntk(pTerm);
pNode = Abc_ObjFanin0Ntk( Abc_ObjFanin0(pTermPo) );
if ( ppSops[i]->nSize == 0 )
{
Abc_ObjRemoveFanins(pNode);
......
......@@ -22,9 +22,12 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define FPGA_CO_LIST_SIZE 5
static void Fpga_MappingDfs_rec( Fpga_Node_t * pNode, Fpga_NodeVec_t * vNodes, int fCollectEquiv );
static void Fpga_MappingDfsCuts_rec( Fpga_Node_t * pNode, Fpga_NodeVec_t * vNodes );
static int Fpga_MappingCompareOutputDelay( int * pOut1, int * pOut2 );
static int Fpga_MappingCompareOutputDelay( Fpga_Node_t ** ppNode1, Fpga_Node_t ** ppNode2 );
static void Fpga_MappingFindLatest( Fpga_Man_t * p, int * pNodes, int nNodesMax );
static void Fpga_DfsLim_rec( Fpga_Node_t * pNode, int Level, Fpga_NodeVec_t * vNodes );
static int Fpga_CollectNodeTfo_rec( Fpga_Node_t * pNode, Fpga_Node_t * pPivot, Fpga_NodeVec_t * vVisited, Fpga_NodeVec_t * vTfo );
static Fpga_Man_t * s_pMan = NULL;
......@@ -321,6 +324,62 @@ float Fpga_MappingSetRefsAndArea( Fpga_Man_t * pMan )
/**Function*************************************************************
Synopsis [Compares the outputs by their arrival times.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fpga_MappingCompareOutputDelay( Fpga_Node_t ** ppNode1, Fpga_Node_t ** ppNode2 )
{
Fpga_Node_t * pNode1 = Fpga_Regular(*ppNode1);
Fpga_Node_t * pNode2 = Fpga_Regular(*ppNode2);
float Arrival1 = pNode1->pCutBest? pNode1->pCutBest->tArrival : 0;
float Arrival2 = pNode2->pCutBest? pNode2->pCutBest->tArrival : 0;
if ( Arrival1 < Arrival2 )
return -1;
if ( Arrival1 > Arrival2 )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis [Finds given number of latest arriving COs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fpga_MappingFindLatest( Fpga_Man_t * p, int * pNodes, int nNodesMax )
{
int nNodes, i, k, v;
assert( p->nOutputs >= nNodesMax );
pNodes[0] = 0;
nNodes = 1;
for ( i = 1; i < p->nOutputs; i++ )
{
for ( k = nNodes - 1; k >= 0; k-- )
if ( Fpga_MappingCompareOutputDelay( &p->pOutputs[pNodes[k]], &p->pOutputs[i] ) >= 0 )
break;
if ( k == nNodesMax - 1 )
continue;
if ( nNodes < nNodesMax )
nNodes++;
for ( v = nNodes - 1; v > k+1; v-- )
pNodes[v] = pNodes[v-1];
pNodes[k+1] = i;
}
}
/**Function*************************************************************
Synopsis [Prints a bunch of latest arriving outputs.]
Description []
......@@ -333,22 +392,17 @@ float Fpga_MappingSetRefsAndArea( Fpga_Man_t * pMan )
void Fpga_MappingPrintOutputArrivals( Fpga_Man_t * p )
{
Fpga_Node_t * pNode;
int pSorted[FPGA_CO_LIST_SIZE];
int fCompl, Limit, MaxNameSize, i;
int * pSorted;
// sort outputs by arrival time
s_pMan = p;
pSorted = ALLOC( int, p->nOutputs );
for ( i = 0; i < p->nOutputs; i++ )
pSorted[i] = i;
qsort( (void *)pSorted, p->nOutputs, sizeof(int),
(int (*)(const void *, const void *)) Fpga_MappingCompareOutputDelay );
assert( Fpga_MappingCompareOutputDelay( pSorted, pSorted + p->nOutputs - 1 ) <= 0 );
s_pMan = NULL;
// determine the number of nodes to print
Limit = (p->nOutputs > FPGA_CO_LIST_SIZE)? FPGA_CO_LIST_SIZE : p->nOutputs;
// determine the order
Fpga_MappingFindLatest( p, pSorted, Limit );
// determine max size of the node's name
MaxNameSize = 0;
Limit = (p->nOutputs > 5)? 5 : p->nOutputs;
for ( i = 0; i < Limit; i++ )
if ( MaxNameSize < (int)strlen(p->ppOutputNames[pSorted[i]]) )
MaxNameSize = strlen(p->ppOutputNames[pSorted[i]]);
......@@ -368,32 +422,8 @@ void Fpga_MappingPrintOutputArrivals( Fpga_Man_t * p )
printf( "POS" );
printf( "\n" );
}
free( pSorted );
}
/**Function*************************************************************
Synopsis [Compares the outputs by their arrival times.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fpga_MappingCompareOutputDelay( int * pOut1, int * pOut2 )
{
Fpga_Node_t * pNode1 = Fpga_Regular(s_pMan->pOutputs[*pOut1]);
Fpga_Node_t * pNode2 = Fpga_Regular(s_pMan->pOutputs[*pOut2]);
float pTime1 = pNode1->pCutBest? pNode1->pCutBest->tArrival : 0;
float pTime2 = pNode2->pCutBest? pNode2->pCutBest->tArrival : 0;
if ( pTime1 > pTime2 )
return -1;
if ( pTime1 < pTime2 )
return 1;
return 0;
}
/**Function*************************************************************
......
......@@ -22,6 +22,8 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define MAP_CO_LIST_SIZE 5
static void Map_MappingDfs_rec( Map_Node_t * pNode, Map_NodeVec_t * vNodes, int fCollectEquiv );
static int Map_MappingCountLevels_rec( Map_Node_t * pNode );
static float Map_MappingSetRefsAndArea_rec( Map_Man_t * pMan, Map_Node_t * pNode );
......@@ -29,7 +31,8 @@ static float Map_MappingSetRefsAndSwitch_rec( Map_Man_t * pMan, Map_Node_t * pNo
static float Map_MappingSetRefsAndWire_rec( Map_Man_t * pMan, Map_Node_t * pNode );
static void Map_MappingDfsCuts_rec( Map_Node_t * pNode, Map_NodeVec_t * vNodes );
static float Map_MappingArea_rec( Map_Man_t * pMan, Map_Node_t * pNode, Map_NodeVec_t * vNodes );
static int Map_MappingCompareOutputDelay( int * pOut1, int * pOut2 );
static int Map_MappingCompareOutputDelay( Map_Node_t ** ppNode1, Map_Node_t ** ppNode2 );
static void Map_MappingFindLatest( Map_Man_t * p, int * pNodes, int nNodesMax );
static unsigned Map_MappingExpandTruth_rec( unsigned uTruth, int nVars );
static void Map_MappingGetChoiceLevels( Map_Man_t * pMan, Map_Node_t * p1, Map_Node_t * p2, int * pMin, int * pMax );
static float Map_MappingGetChoiceVolumes( Map_Man_t * pMan, Map_Node_t * p1, Map_Node_t * p2 );
......@@ -391,6 +394,64 @@ void Map_MappingMark_rec( Map_Node_t * pNode )
/**Function*************************************************************
Synopsis [Compares the outputs by their arrival times.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Map_MappingCompareOutputDelay( Map_Node_t ** ppNode1, Map_Node_t ** ppNode2 )
{
Map_Node_t * pNode1 = Map_Regular(*ppNode1);
Map_Node_t * pNode2 = Map_Regular(*ppNode2);
int fPhase1 = !Map_IsComplement(*ppNode1);
int fPhase2 = !Map_IsComplement(*ppNode2);
float Arrival1 = pNode1->tArrival[fPhase1].Worst;
float Arrival2 = pNode2->tArrival[fPhase2].Worst;
if ( Arrival1 < Arrival2 )
return -1;
if ( Arrival1 > Arrival2 )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis [Finds given number of latest arriving COs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Map_MappingFindLatest( Map_Man_t * p, int * pNodes, int nNodesMax )
{
int nNodes, i, k, v;
assert( p->nOutputs >= nNodesMax );
pNodes[0] = 0;
nNodes = 1;
for ( i = 1; i < p->nOutputs; i++ )
{
for ( k = nNodes - 1; k >= 0; k-- )
if ( Map_MappingCompareOutputDelay( &p->pOutputs[pNodes[k]], &p->pOutputs[i] ) >= 0 )
break;
if ( k == nNodesMax - 1 )
continue;
if ( nNodes < nNodesMax )
nNodes++;
for ( v = nNodes - 1; v > k+1; v-- )
pNodes[v] = pNodes[v-1];
pNodes[k+1] = i;
}
}
/**Function*************************************************************
Synopsis [Prints a bunch of latest arriving outputs.]
Description []
......@@ -402,30 +463,20 @@ void Map_MappingMark_rec( Map_Node_t * pNode )
***********************************************************************/
void Map_MappingPrintOutputArrivals( Map_Man_t * p )
{
int pSorted[MAP_CO_LIST_SIZE];
Map_Time_t * pTimes;
Map_Node_t * pNode;
int fPhase, Limit, i;
int nOutputs, MaxNameSize;
int * pSorted;
int MaxNameSize;
// sort outputs by arrival time
s_pMan = p;
pSorted = ALLOC( int, p->nOutputs );
nOutputs = 0;
for ( i = 0; i < p->nOutputs; i++ )
{
if ( Map_NodeIsConst(p->pOutputs[i]) )
continue;
pSorted[nOutputs++] = i;
}
qsort( (void *)pSorted, nOutputs, sizeof(int),
(int (*)(const void *, const void *)) Map_MappingCompareOutputDelay );
assert( Map_MappingCompareOutputDelay( pSorted, pSorted + nOutputs - 1 ) <= 0 );
s_pMan = NULL;
// determine the number of nodes to print
Limit = (p->nOutputs > MAP_CO_LIST_SIZE)? MAP_CO_LIST_SIZE : p->nOutputs;
// determine the order
Map_MappingFindLatest( p, pSorted, Limit );
// determine max size of the node's name
MaxNameSize = 0;
Limit = (nOutputs > 5)? 5 : nOutputs;
for ( i = 0; i < Limit; i++ )
if ( MaxNameSize < (int)strlen(p->ppOutputNames[pSorted[i]]) )
MaxNameSize = strlen(p->ppOutputNames[pSorted[i]]);
......@@ -443,33 +494,6 @@ void Map_MappingPrintOutputArrivals( Map_Man_t * p )
printf( "%s", fPhase? "POS" : "NEG" );
printf( "\n" );
}
free( pSorted );
}
/**Function*************************************************************
Synopsis [Compares the outputs by their arrival times.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Map_MappingCompareOutputDelay( int * pOut1, int * pOut2 )
{
Map_Node_t * pNode1 = Map_Regular(s_pMan->pOutputs[*pOut1]);
Map_Node_t * pNode2 = Map_Regular(s_pMan->pOutputs[*pOut2]);
int fPhase1 = (pNode1 == s_pMan->pOutputs[*pOut1]);
int fPhase2 = (pNode2 == s_pMan->pOutputs[*pOut2]);
float Arrival1 = pNode1->tArrival[fPhase1].Worst;
float Arrival2 = pNode2->tArrival[fPhase2].Worst;
if ( Arrival1 > Arrival2 )
return -1;
if ( Arrival1 < Arrival2 )
return 1;
return 0;
}
/**Function*************************************************************
......
......@@ -109,7 +109,7 @@ Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Rwr_Cut_t * pCut,
vFanins->nSize = pCut->nLeaves;
vFanins->pArray = pCut->ppLeaves;
// detect how many unlabeled nodes will be reused
GainCur = Abc_NodeStrashDecCount( pRoot->pNtk->pManFunc, vFanins, (Vec_Int_t *)pNode->pNext,
GainCur = Abc_NodeStrashDecCount( pRoot->pNtk->pManFunc, pRoot, vFanins, (Vec_Int_t *)pNode->pNext,
p->vLevNums, NodeMax, LevelMax );
if ( GainBest < GainCur )
{
......
......@@ -320,8 +320,8 @@ Ft_Node_t * Ft_FactorTrivialTree_rec( Vec_Int_t * vForm, Ft_Node_t ** ppNodes, i
return ppNodes[0];
// split the nodes into two parts
nNodes1 = nNodes/2;
nNodes2 = nNodes - nNodes1;
nNodes2 = nNodes/2;
nNodes1 = nNodes - nNodes2;
// recursively construct the tree for the parts
pNode1 = Ft_FactorTrivialTree_rec( vForm, ppNodes, nNodes1, fAnd );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment