mirror of https://github.com/YosysHQ/abc.git
Merge pull request #511 from wjrforcyber/rd_inv
Feat(rd_inv): Simple inv redis framework.
This commit is contained in:
commit
4c08da846a
|
|
@ -443,6 +443,10 @@ SOURCE=.\src\base\abci\abcResub.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\src\base\abci\abcRmInverters.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\src\base\abci\abcRewrite.c
|
SOURCE=.\src\base\abci\abcRewrite.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,7 @@ struct Abc_Obj_t_ // 48/72 bytes (32-bits/64-bits)
|
||||||
unsigned Level : 20; // the level of the node
|
unsigned Level : 20; // the level of the node
|
||||||
Vec_Int_t vFanins; // the array of fanins
|
Vec_Int_t vFanins; // the array of fanins
|
||||||
Vec_Int_t vFanouts; // the array of fanouts
|
Vec_Int_t vFanouts; // the array of fanouts
|
||||||
|
void * pDataComp;
|
||||||
union { void * pData; // the network specific data
|
union { void * pData; // the network specific data
|
||||||
int iData; }; // (SOP, BDD, gate, equiv class, etc)
|
int iData; }; // (SOP, BDD, gate, equiv class, etc)
|
||||||
union { void * pTemp; // temporary store for user's data
|
union { void * pTemp; // temporary store for user's data
|
||||||
|
|
@ -620,6 +621,7 @@ extern ABC_DLL float Abc_NtkDelayTraceLut( Abc_Ntk_t * pNtk, int fU
|
||||||
/*=== abcDfs.c ==========================================================*/
|
/*=== abcDfs.c ==========================================================*/
|
||||||
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk, int fCollectAll );
|
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk, int fCollectAll );
|
||||||
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfs2( Abc_Ntk_t * pNtk );
|
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfs2( Abc_Ntk_t * pNtk );
|
||||||
|
extern ABC_DLL void Abc_NtkDfsSup_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Vec_Ptr_t * vSup, int iVerbose);
|
||||||
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfsNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
|
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfsNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
|
||||||
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfsReverse( Abc_Ntk_t * pNtk );
|
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfsReverse( Abc_Ntk_t * pNtk );
|
||||||
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfsReverseNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
|
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfsReverseNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
|
||||||
|
|
@ -885,6 +887,8 @@ extern ABC_DLL int Abc_NodeRef_rec( Abc_Obj_t * pNode );
|
||||||
extern ABC_DLL int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nMinSaved, int nConeSizeMax, int fUpdateLevel, int fUseZeros, int fUseDcs, int fVerbose );
|
extern ABC_DLL int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nMinSaved, int nConeSizeMax, int fUpdateLevel, int fUseZeros, int fUseDcs, int fVerbose );
|
||||||
/*=== abcRewrite.c ==========================================================*/
|
/*=== abcRewrite.c ==========================================================*/
|
||||||
extern ABC_DLL int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable );
|
extern ABC_DLL int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable );
|
||||||
|
/*=== abcRmInverters.c ======================================================*/
|
||||||
|
extern ABC_DLL void Abc_NtkRmInverter(Abc_Ntk_t * pNtk, int iVerbose);
|
||||||
/*=== abcSat.c ==========================================================*/
|
/*=== abcSat.c ==========================================================*/
|
||||||
extern ABC_DLL int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int fVerbose, ABC_INT64_T * pNumConfs, ABC_INT64_T * pNumInspects );
|
extern ABC_DLL int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int fVerbose, ABC_INT64_T * pNumConfs, ABC_INT64_T * pNumInspects );
|
||||||
extern ABC_DLL void * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fAllPrimes );
|
extern ABC_DLL void * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fAllPrimes );
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include "abc.h"
|
#include "abc.h"
|
||||||
|
#include "misc/vec/vecPtr.h"
|
||||||
#include "proof/cec/cec.h"
|
#include "proof/cec/cec.h"
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_START
|
ABC_NAMESPACE_IMPL_START
|
||||||
|
|
@ -137,6 +138,101 @@ Vec_Ptr_t * Abc_NtkDfs2( Abc_Ntk_t * pNtk )
|
||||||
return vNodes;
|
return vNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Collect support nodes bounded internal nodes.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkDfsSup_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Vec_Ptr_t * vSup, int iVerbose)
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pFanin;
|
||||||
|
int i;
|
||||||
|
assert( !Abc_ObjIsNet(pNode) );
|
||||||
|
if ( Abc_NodeIsTravIdCurrent( pNode ) )
|
||||||
|
return;
|
||||||
|
Abc_NodeSetTravIdCurrent( pNode );
|
||||||
|
if ( Abc_ObjIsCi(pNode) || Abc_ObjIsCo(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsConst(pNode)) )
|
||||||
|
return;
|
||||||
|
if( Vec_PtrFind(vSup, pNode) >= 0 )
|
||||||
|
{
|
||||||
|
if(iVerbose)
|
||||||
|
{
|
||||||
|
printf("Encountered vSup Node: %s\n", Abc_ObjName(pNode));
|
||||||
|
printf("Whose fanins are:\n");
|
||||||
|
printf(" Fanin0: %s", Abc_ObjName(Abc_ObjFanin0(pNode)));
|
||||||
|
printf(" %d on comp\n", pNode->fCompl0);
|
||||||
|
printf(" Fanin1: %s", Abc_ObjName(Abc_ObjFanin1(pNode)));
|
||||||
|
printf(" %d on comp\n", pNode->fCompl1);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert( Abc_ObjIsNode( pNode ) );
|
||||||
|
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||||
|
{
|
||||||
|
if(iVerbose)
|
||||||
|
{
|
||||||
|
printf(" Node %s Fanin %d: ", Abc_ObjName(pNode), i);
|
||||||
|
printf("%s", Abc_ObjName(pFanin));
|
||||||
|
printf(" %d on comp\n", i == 0 ? pNode->fCompl0 : pNode->fCompl1);
|
||||||
|
}
|
||||||
|
Abc_NtkDfsSup_rec( Abc_ObjFanin0Ntk(pFanin), vNodes, vSup, iVerbose);
|
||||||
|
}
|
||||||
|
Vec_PtrPush( vNodes, pNode );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis []
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkDfsInvSup_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSup, int * countFlip)
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pFanin;
|
||||||
|
int i;
|
||||||
|
assert( !Abc_ObjIsNet(pNode) );
|
||||||
|
if ( Abc_NodeIsTravIdCurrent( pNode ) )
|
||||||
|
return;
|
||||||
|
Abc_NodeSetTravIdCurrent( pNode );
|
||||||
|
if ( Abc_ObjIsCi(pNode) || Abc_ObjIsCo(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsConst(pNode)) )
|
||||||
|
return;
|
||||||
|
if( Vec_PtrFind(vSup, pNode) >= 0 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert( Abc_ObjIsNode( pNode ) || Abc_ObjIsBox( pNode ) );
|
||||||
|
|
||||||
|
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||||
|
{
|
||||||
|
if(Vec_PtrFind(vSup, pFanin) >= 0)
|
||||||
|
{
|
||||||
|
if(i == 0)
|
||||||
|
{
|
||||||
|
printf("Flipping edge on Node %s %d (Phase = %d)\n", Abc_ObjName(pNode), i, pFanin->fPhase );
|
||||||
|
pNode->fCompl0 ^= 1;
|
||||||
|
}
|
||||||
|
else if(i == 1)
|
||||||
|
{
|
||||||
|
printf("Flipping edge on Node %s %d (Phase = %d)\n", Abc_ObjName(pNode),i , pFanin->fPhase);
|
||||||
|
pNode->fCompl1 ^= 1;
|
||||||
|
}
|
||||||
|
*countFlip = *countFlip + 1;
|
||||||
|
}
|
||||||
|
Abc_NtkDfsInvSup_rec( Abc_ObjFanin0Ntk(pFanin), vSup, countFlip );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis [Returns the DFS ordered array of logic nodes.]
|
Synopsis [Returns the DFS ordered array of logic nodes.]
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,7 @@ static int Abc_CommandRunEco ( Abc_Frame_t * pAbc, int argc, cha
|
||||||
static int Abc_CommandRunGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandRunGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Abc_CommandRunScript ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandRunScript ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Abc_CommandRunTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandRunTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
|
static int Abc_CommandRmInverter ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
|
|
||||||
static int Abc_CommandRewrite ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandRewrite ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
static int Abc_CommandRefactor ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
static int Abc_CommandRefactor ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||||
|
|
@ -1008,6 +1009,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
||||||
Cmd_CommandAdd( pAbc, "Synthesis", "resub_unate", Abc_CommandResubUnate, 1 );
|
Cmd_CommandAdd( pAbc, "Synthesis", "resub_unate", Abc_CommandResubUnate, 1 );
|
||||||
Cmd_CommandAdd( pAbc, "Synthesis", "resub_core", Abc_CommandResubCore, 1 );
|
Cmd_CommandAdd( pAbc, "Synthesis", "resub_core", Abc_CommandResubCore, 1 );
|
||||||
Cmd_CommandAdd( pAbc, "Synthesis", "resub_check", Abc_CommandResubCheck, 0 );
|
Cmd_CommandAdd( pAbc, "Synthesis", "resub_check", Abc_CommandResubCheck, 0 );
|
||||||
|
Cmd_CommandAdd( pAbc, "Synthesis", "rd_inv", Abc_CommandRmInverter, 1 );
|
||||||
// Cmd_CommandAdd( pAbc, "Synthesis", "rr", Abc_CommandRr, 1 );
|
// Cmd_CommandAdd( pAbc, "Synthesis", "rr", Abc_CommandRr, 1 );
|
||||||
Cmd_CommandAdd( pAbc, "Synthesis", "cascade", Abc_CommandCascade, 1 );
|
Cmd_CommandAdd( pAbc, "Synthesis", "cascade", Abc_CommandCascade, 1 );
|
||||||
Cmd_CommandAdd( pAbc, "Synthesis", "lutcasdec", Abc_CommandLutCasDec, 1 );
|
Cmd_CommandAdd( pAbc, "Synthesis", "lutcasdec", Abc_CommandLutCasDec, 1 );
|
||||||
|
|
@ -7995,7 +7997,58 @@ usage:
|
||||||
|
|
||||||
Synopsis []
|
Synopsis []
|
||||||
|
|
||||||
Description [Orchestration synthesis]
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int Abc_CommandRmInverter( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
|
{
|
||||||
|
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
|
||||||
|
Extra_UtilGetoptReset();
|
||||||
|
int iVerbose = 0;
|
||||||
|
int c;
|
||||||
|
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
|
||||||
|
{
|
||||||
|
switch ( c )
|
||||||
|
{
|
||||||
|
case 'v':
|
||||||
|
iVerbose ^= 1;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
goto usage;
|
||||||
|
default:
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( pNtk == NULL )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "Empty network.\n" );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ( !Abc_NtkHasAig(pNtk) || !Abc_NtkIsStrash(pNtk) )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "This command only works on AIG network.\n" );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
Abc_NtkRmInverter(pNtk, iVerbose);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
usage:
|
||||||
|
Abc_Print( -2, "usage: rd_inv\n" );
|
||||||
|
Abc_Print( -2, "\t redistribute inverters on self-dual and self-anti-dual functions in network\n" );
|
||||||
|
Abc_Print( -2, "\t-v : verbose output\n");
|
||||||
|
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis []
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
SideEffects []
|
SideEffects []
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,853 @@
|
||||||
|
/**CFile****************************************************************
|
||||||
|
|
||||||
|
FileName [abcRmInverters.c]
|
||||||
|
|
||||||
|
SystemName [ABC: Logic synthesis and verification system.]
|
||||||
|
|
||||||
|
PackageName [Network and node package.]
|
||||||
|
|
||||||
|
Synopsis [Remove/Redistribute inverted edges on AIG nodes.]
|
||||||
|
|
||||||
|
Author [Jingren Wang]
|
||||||
|
|
||||||
|
Affiliation [HKUST(GZ)]
|
||||||
|
|
||||||
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||||
|
|
||||||
|
Revision [$Id: abcRmInverters.c,v 1.00 2005/06/20 00:00:00 jingren Exp $]
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "aig/aig/aig.h"
|
||||||
|
#include "base/abc/abc.h"
|
||||||
|
#include "misc/util/abc_global.h"
|
||||||
|
#include "misc/vec/vecInt.h"
|
||||||
|
#include "misc/vec/vecPtr.h"
|
||||||
|
#include "opt/cut/cut.h"
|
||||||
|
|
||||||
|
ABC_NAMESPACE_IMPL_START
|
||||||
|
|
||||||
|
#define RDINV_SIM_SIZE 100
|
||||||
|
|
||||||
|
static unsigned int uMask[] = { 0x1, 0x3, 0xF, 0xFF, 0xFFFF, 0xFFFFFFFF };
|
||||||
|
|
||||||
|
extern void Abc_NtkMarkCriticalNodes( Abc_Ntk_t * pNtk );
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Collect cut leaves into a Vec_Ptr.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
static inline Vec_Ptr_t * Abc_RdInvCollectCutLeaves( Abc_Ntk_t * pNtk, Cut_Cut_t * pCut )
|
||||||
|
{
|
||||||
|
Vec_Ptr_t * vLeaves = Vec_PtrAlloc( pCut->nLeaves );
|
||||||
|
for ( int li = 0; li < pCut->nLeaves; li++ )
|
||||||
|
Vec_PtrPush( vLeaves, Abc_NtkObj(pNtk, Cut_CutReadLeaves(pCut)[li]) );
|
||||||
|
return vLeaves;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Detect if function is self-dual.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int AbcRmInvHasSelfDual( unsigned int uTruth, int fPhaseOri, unsigned int uTruthFlipped, int fPhaseFlipped, unsigned int uMsk )
|
||||||
|
{
|
||||||
|
return (uTruth == uTruthFlipped && (fPhaseOri ^ fPhaseFlipped) == 1) ||
|
||||||
|
(uTruth == (~uTruthFlipped & uMsk) && fPhaseOri == fPhaseFlipped);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Detect if function is self-anti-dual.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int AbcRmInvHasSelfAntiDual( unsigned int uTruth, int fPhaseOri, unsigned int uTruthFlipped, int fPhaseFlipped, unsigned int uMsk )
|
||||||
|
{
|
||||||
|
return (uTruth == uTruthFlipped && fPhaseOri == fPhaseFlipped) ||
|
||||||
|
(uTruth == (~uTruthFlipped & uMsk) && (fPhaseOri ^ fPhaseFlipped) == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Collect MFFC with support variables and internal nodes.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso [abcMffc.c]
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NodeMffcConeSuppCollect( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp, int iVerbose )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pObj;
|
||||||
|
int i;
|
||||||
|
Abc_NodeDeref_rec( pNode );
|
||||||
|
Abc_NodeMffcConeSupp( pNode, vCone, vSupp );
|
||||||
|
Abc_NodeRef_rec( pNode );
|
||||||
|
if ( iVerbose )
|
||||||
|
{
|
||||||
|
printf( "Node = %6s : Supp = %3d Cone = %3d (",
|
||||||
|
Abc_ObjName(pNode), Vec_PtrSize(vSupp), Vec_PtrSize(vCone) );
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vCone, pObj, i )
|
||||||
|
printf( " %s", Abc_ObjName(pObj) );
|
||||||
|
printf( " )\n" );
|
||||||
|
printf("vSupp = (");
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vSupp, pObj, i )
|
||||||
|
printf( " %s", Abc_ObjName(pObj) );
|
||||||
|
printf( " )\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Get inverter count on support variables for self-anti-dual case.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkRmInverterCountInvRatioSelfAntiDual( Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp, int * nLocalInv, int * nLocalInvOnCritical, int * nLocalNonInvOnCritical, int * nLocalSup )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pObj, * pFanin;
|
||||||
|
int i_cone, i_fanin;
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vCone, pObj, i_cone )
|
||||||
|
{
|
||||||
|
Abc_ObjForEachFanin( pObj, pFanin, i_fanin )
|
||||||
|
{
|
||||||
|
if ( Vec_PtrFind(vSupp, pFanin) < 0 )
|
||||||
|
continue;
|
||||||
|
if ( (i_fanin == 0 && pObj->fCompl0) || (i_fanin == 1 && pObj->fCompl1) )
|
||||||
|
(*nLocalInv)++;
|
||||||
|
if ( (i_fanin == 0 && pObj->fCompl0 && pFanin->fMarkA) || (i_fanin == 1 && pObj->fCompl1 && pFanin->fMarkA) )
|
||||||
|
(*nLocalInvOnCritical)++;
|
||||||
|
if ( (i_fanin == 0 && !pObj->fCompl0 && pFanin->fMarkA) || (i_fanin == 1 && !pObj->fCompl1 && pFanin->fMarkA) )
|
||||||
|
(*nLocalNonInvOnCritical)++;
|
||||||
|
(*nLocalSup)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Get inverter count on support variables for self-dual case.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkRmInverterCountInvRatioSelfDual( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp, int * nLocalInv, int * nLocalInvOnCritical, int * nLocalNonInvOnCritical, int * nLocalSup )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pFanout;
|
||||||
|
int i;
|
||||||
|
Abc_NtkRmInverterCountInvRatioSelfAntiDual( vCone, vSupp, nLocalInv, nLocalInvOnCritical, nLocalNonInvOnCritical, nLocalSup );
|
||||||
|
Abc_ObjForEachFanout( pNode, pFanout, i )
|
||||||
|
{
|
||||||
|
int fCompl = (Abc_ObjFanin0(pFanout) == pNode) ? pFanout->fCompl0 : pFanout->fCompl1;
|
||||||
|
*nLocalInv += fCompl;
|
||||||
|
int fIsCritical = (Abc_ObjFanin0(pFanout) == pNode)
|
||||||
|
? (Abc_ObjFanin0(pFanout)->fMarkA == 1)
|
||||||
|
: (Abc_ObjFanin1(pFanout)->fMarkA == 1);
|
||||||
|
if ( fCompl && fIsCritical )
|
||||||
|
(*nLocalInvOnCritical)++;
|
||||||
|
else if ( !fCompl && fIsCritical )
|
||||||
|
(*nLocalNonInvOnCritical)++;
|
||||||
|
(*nLocalSup)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Flip inverters on self-anti-dual function.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkRmInverterFlipInvSelfAntiDual( Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pObj, * pFanin;
|
||||||
|
int i_cone, i_fanin;
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vCone, pObj, i_cone )
|
||||||
|
{
|
||||||
|
Abc_ObjForEachFanin( pObj, pFanin, i_fanin )
|
||||||
|
{
|
||||||
|
if ( Vec_PtrFind(vSupp, pFanin) < 0 )
|
||||||
|
continue;
|
||||||
|
if ( i_fanin == 0 )
|
||||||
|
pObj->fCompl0 ^= 1;
|
||||||
|
else if ( i_fanin == 1 )
|
||||||
|
pObj->fCompl1 ^= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Flip inverters on self-dual function.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkRmInverterFlipInvSelfDual( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, Vec_Ptr_t * vSupp )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pFanout;
|
||||||
|
int i;
|
||||||
|
Abc_NtkRmInverterFlipInvSelfAntiDual( vCone, vSupp );
|
||||||
|
Abc_ObjForEachFanout( pNode, pFanout, i )
|
||||||
|
{
|
||||||
|
Abc_ObjFanin0(pFanout) == pNode ? (pFanout->fCompl0 ^= 1) : (pFanout->fCompl1 ^= 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Simulate AIG nodes and compute truth tables.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_ManResubSimulateComp( Vec_Ptr_t * vDivs, int nLeaves, Vec_Ptr_t * vSims, int nLeavesMax, int nWords )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pObj;
|
||||||
|
unsigned * puData0, * puData1, * puData;
|
||||||
|
int i, k;
|
||||||
|
assert( Vec_PtrSize(vDivs) - nLeaves <= Vec_PtrSize(vSims) - nLeavesMax );
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vDivs, pObj, i )
|
||||||
|
{
|
||||||
|
if ( i < nLeaves )
|
||||||
|
{
|
||||||
|
pObj->pDataComp = Vec_PtrEntry( vSims, i );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pObj->pDataComp = Vec_PtrEntry( vSims, i - nLeaves + nLeavesMax );
|
||||||
|
puData = (unsigned *)pObj->pDataComp;
|
||||||
|
puData0 = (unsigned *)Abc_ObjFanin0(pObj)->pDataComp;
|
||||||
|
puData1 = (unsigned *)Abc_ObjFanin1(pObj)->pDataComp;
|
||||||
|
if ( Abc_ObjFaninC0(pObj) && Abc_ObjFaninC1(pObj) )
|
||||||
|
for ( k = 0; k < nWords; k++ )
|
||||||
|
puData[k] = ~puData0[k] & ~puData1[k];
|
||||||
|
else if ( Abc_ObjFaninC0(pObj) )
|
||||||
|
for ( k = 0; k < nWords; k++ )
|
||||||
|
puData[k] = ~puData0[k] & puData1[k];
|
||||||
|
else if ( Abc_ObjFaninC1(pObj) )
|
||||||
|
for ( k = 0; k < nWords; k++ )
|
||||||
|
puData[k] = puData0[k] & ~puData1[k];
|
||||||
|
else
|
||||||
|
for ( k = 0; k < nWords; k++ )
|
||||||
|
puData[k] = puData0[k] & puData1[k];
|
||||||
|
}
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vDivs, pObj, i )
|
||||||
|
{
|
||||||
|
puData = (unsigned *)pObj->pDataComp;
|
||||||
|
pObj->fPhase = (puData[0] & 1);
|
||||||
|
if ( pObj->fPhase )
|
||||||
|
for ( k = 0; k < nWords; k++ )
|
||||||
|
puData[k] = ~puData[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Clean pDataComp on cone nodes.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkCleanDataComp( Vec_Ptr_t * vCone )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pObj;
|
||||||
|
int i;
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vCone, pObj, i )
|
||||||
|
pObj->pDataComp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Simulate a cut to extract truth + phase for one polarity.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void AbcRmInvSimCuts( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Cut_Cut_t * pCut, int nMaxLeaves, unsigned int * uNodeVal, int * fPhaseFlipped, unsigned int * pInfo, Vec_Ptr_t * vSims )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pObj;
|
||||||
|
int nVar = pCut->nLeaves;
|
||||||
|
int nBits = (1 << nVar);
|
||||||
|
int nWords = (nBits <= 32) ? 1 : (nBits / 32);
|
||||||
|
|
||||||
|
Vec_Ptr_t * vCone = Vec_PtrAlloc( pCut->nLeaves + 16 );
|
||||||
|
Vec_Ptr_t * vSup = Vec_PtrAlloc( pCut->nLeaves );
|
||||||
|
for ( int li = 0; li < pCut->nLeaves; li++ )
|
||||||
|
{
|
||||||
|
pObj = Abc_NtkObj( pNtk, Cut_CutReadLeaves(pCut)[li] );
|
||||||
|
Vec_PtrPush( vSup, pObj );
|
||||||
|
Vec_PtrPush( vCone, pObj );
|
||||||
|
}
|
||||||
|
assert( Vec_PtrSize(vSup) == pCut->nLeaves );
|
||||||
|
|
||||||
|
Abc_NtkIncrementTravId( pNtk );
|
||||||
|
Abc_NtkDfsSup_rec( pNode, vCone, vSup, 0 );
|
||||||
|
assert( Vec_PtrSize(vCone) > pCut->nLeaves );
|
||||||
|
|
||||||
|
Vec_Int_t * vPh = Vec_IntAlloc( Vec_PtrSize(vCone) );
|
||||||
|
Abc_Obj_t * pEntry;
|
||||||
|
int iPh;
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vCone, pEntry, iPh )
|
||||||
|
Vec_IntPush( vPh, pEntry->fPhase );
|
||||||
|
|
||||||
|
Abc_ManResubSimulateComp( vCone, nVar, vSims, nMaxLeaves, nWords );
|
||||||
|
unsigned int uNode = (*((unsigned int *)(pNode->pDataComp)));
|
||||||
|
*uNodeVal = uNode & uMask[nVar];
|
||||||
|
*fPhaseFlipped = pNode->fPhase;
|
||||||
|
|
||||||
|
Abc_NtkCleanDataComp( vCone );
|
||||||
|
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vCone, pEntry, iPh )
|
||||||
|
pEntry->fPhase = Vec_IntEntry( vPh, iPh );
|
||||||
|
|
||||||
|
Vec_IntFree( vPh );
|
||||||
|
Vec_PtrFree( vCone );
|
||||||
|
Vec_PtrFree( vSup );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Compute original and flipped truth/phase pair for a cut.]
|
||||||
|
|
||||||
|
Description [Allocates and frees simulation arrays internally.
|
||||||
|
Returns 1 on success, 0 if cut is too large.]
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
static void Abc_RdInvComputeTruthPair( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Cut_Cut_t * pCut,
|
||||||
|
unsigned * uTruthOri, int * fPhaseOri,
|
||||||
|
unsigned * uTruthFlipped, int * fPhaseFlipped )
|
||||||
|
{
|
||||||
|
int nVar = pCut->nLeaves;
|
||||||
|
int nBits = (1 << nVar);
|
||||||
|
int nWords = (nBits <= 32) ? 1 : (nBits / 32);
|
||||||
|
int in, k;
|
||||||
|
|
||||||
|
Vec_Ptr_t * vSims = Vec_PtrAlloc( RDINV_SIM_SIZE );
|
||||||
|
unsigned int *pInfo = ABC_ALLOC( unsigned, nWords * (RDINV_SIM_SIZE + 1) );
|
||||||
|
for ( in = 0; in < RDINV_SIM_SIZE; in++ )
|
||||||
|
Vec_PtrPush( vSims, pInfo + in * nWords );
|
||||||
|
|
||||||
|
for ( k = 0; k < nVar; k++ )
|
||||||
|
{
|
||||||
|
unsigned * pData = (unsigned *)vSims->pArray[k];
|
||||||
|
Abc_InfoClear( pData, nWords );
|
||||||
|
for ( in = 0; in < nBits; in++ )
|
||||||
|
if ( in & (1 << k) )
|
||||||
|
pData[in >> 5] |= (1 << (in & 31));
|
||||||
|
}
|
||||||
|
AbcRmInvSimCuts( pNtk, pNode, pCut, 5, uTruthOri, fPhaseOri, pInfo, vSims );
|
||||||
|
Vec_PtrFree( vSims );
|
||||||
|
ABC_FREE( pInfo );
|
||||||
|
|
||||||
|
vSims = Vec_PtrAlloc( RDINV_SIM_SIZE );
|
||||||
|
pInfo = ABC_ALLOC( unsigned, nWords * (RDINV_SIM_SIZE + 1) );
|
||||||
|
for ( in = 0; in < RDINV_SIM_SIZE; in++ )
|
||||||
|
Vec_PtrPush( vSims, pInfo + in * nWords );
|
||||||
|
|
||||||
|
for ( k = 0; k < nVar; k++ )
|
||||||
|
{
|
||||||
|
unsigned * pData = (unsigned *)vSims->pArray[k];
|
||||||
|
Abc_InfoClear( pData, nWords );
|
||||||
|
for ( in = 0; in < nBits; in++ )
|
||||||
|
if ( !(in & (1 << k)) )
|
||||||
|
pData[in >> 5] |= (1 << (in & 31));
|
||||||
|
}
|
||||||
|
AbcRmInvSimCuts( pNtk, pNode, pCut, 5, uTruthFlipped, fPhaseFlipped, pInfo, vSims );
|
||||||
|
Vec_PtrFree( vSims );
|
||||||
|
ABC_FREE( pInfo );
|
||||||
|
|
||||||
|
assert( (*uTruthOri & uMask[nVar]) == *uTruthOri );
|
||||||
|
assert( (*uTruthFlipped & uMask[nVar]) == *uTruthFlipped );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Check if cut is self-dual.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int Abc_NtkRmInvCutIsSelfDual( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Cut_Cut_t * pCut )
|
||||||
|
{
|
||||||
|
unsigned uTruthOri, uTruthFlipped;
|
||||||
|
int fPhaseOri, fPhaseFlipped;
|
||||||
|
Abc_RdInvComputeTruthPair( pNtk, pNode, pCut, &uTruthOri, &fPhaseOri, &uTruthFlipped, &fPhaseFlipped );
|
||||||
|
return AbcRmInvHasSelfDual( uTruthOri, fPhaseOri, uTruthFlipped, fPhaseFlipped, uMask[pCut->nLeaves] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Check if cut is self-anti-dual.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int Abc_NtkRmInvCutIsSelfAntiDual( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Cut_Cut_t * pCut )
|
||||||
|
{
|
||||||
|
unsigned uTruthOri, uTruthFlipped;
|
||||||
|
int fPhaseOri, fPhaseFlipped;
|
||||||
|
Abc_RdInvComputeTruthPair( pNtk, pNode, pCut, &uTruthOri, &fPhaseOri, &uTruthFlipped, &fPhaseFlipped );
|
||||||
|
return AbcRmInvHasSelfAntiDual( uTruthOri, fPhaseOri, uTruthFlipped, fPhaseFlipped, uMask[pCut->nLeaves] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Get valid cuts of self-dual and self-anti-dual.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void AbcRmInvAvaCuts( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Cut_Man_t * pCutMan, Vec_Ptr_t * vASDCuts, Vec_Ptr_t * vASADCuts, int iVerbose )
|
||||||
|
{
|
||||||
|
int nCuts = 0;
|
||||||
|
Vec_Ptr_t * vCutsPreSD = Vec_PtrAlloc( 16 );
|
||||||
|
Vec_Ptr_t * vCutsPreSAD = Vec_PtrAlloc( 16 );
|
||||||
|
Cut_Cut_t * pCut;
|
||||||
|
pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pCutMan, pNode, 0, 1 );
|
||||||
|
if ( pCut == NULL )
|
||||||
|
{
|
||||||
|
printf("Warning: Abc_NodeGetCutsRecursive returned NULL for node %d\n", Abc_ObjId(pNode));
|
||||||
|
Vec_PtrFree( vCutsPreSD );
|
||||||
|
Vec_PtrFree( vCutsPreSAD );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
|
||||||
|
{
|
||||||
|
if ( Abc_NtkRmInvCutIsSelfDual(pNtk, pNode, pCut) )
|
||||||
|
Vec_PtrPush( vCutsPreSD, pCut );
|
||||||
|
if ( Abc_NtkRmInvCutIsSelfAntiDual(pNtk, pNode, pCut) )
|
||||||
|
Vec_PtrPush( vCutsPreSAD, pCut );
|
||||||
|
nCuts++;
|
||||||
|
}
|
||||||
|
Vec_PtrCopy( vASADCuts, vCutsPreSAD );
|
||||||
|
Vec_PtrCopy( vASDCuts, vCutsPreSD );
|
||||||
|
if ( iVerbose )
|
||||||
|
{
|
||||||
|
printf(" %d cuts have been found and processed.\n", nCuts);
|
||||||
|
printf(" Retrieved %d(%d) of cuts in self-anti-dual and %d(%d) of cuts in self-dual.\n",
|
||||||
|
Vec_PtrSize(vASADCuts), Vec_PtrSize(vCutsPreSAD),
|
||||||
|
Vec_PtrSize(vASDCuts), Vec_PtrSize(vCutsPreSD));
|
||||||
|
}
|
||||||
|
Vec_PtrFree( vCutsPreSD );
|
||||||
|
Vec_PtrFree( vCutsPreSAD );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Show cut structure for verbose output.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_RmInvShowCutStructure( Abc_Ntk_t * pNtk, Abc_Obj_t * pRoot, Cut_Cut_t * pCut )
|
||||||
|
{
|
||||||
|
Vec_Ptr_t * vCone = Vec_PtrAlloc( pCut->nLeaves + 16 );
|
||||||
|
Vec_Ptr_t * vSup = Abc_RdInvCollectCutLeaves( pNtk, pCut );
|
||||||
|
int li;
|
||||||
|
for ( li = 0; li < pCut->nLeaves; li++ )
|
||||||
|
Vec_PtrPush( vCone, Abc_NtkObj(pNtk, Cut_CutReadLeaves(pCut)[li]) );
|
||||||
|
Abc_NtkIncrementTravId( pNtk );
|
||||||
|
Abc_NtkDfsSup_rec( pRoot, vCone, vSup, 1 );
|
||||||
|
Vec_PtrFree( vSup );
|
||||||
|
Vec_PtrFree( vCone );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Retrieve max level slack.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void AbcRmInvFetchMaxLSlack( Abc_Ntk_t * pNtk, int * iLSM )
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
Abc_Obj_t * pNode;
|
||||||
|
Vec_Int_t * vLS = Vec_IntAlloc( Abc_NtkNodeNum(pNtk) );
|
||||||
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
|
{
|
||||||
|
int item = Abc_ObjRequiredLevel(pNode) - pNode->Level;
|
||||||
|
Vec_IntPush( vLS, item );
|
||||||
|
}
|
||||||
|
Vec_IntSort( vLS, 1 );
|
||||||
|
assert( Vec_IntEntry(vLS, 0) >= Vec_IntEntry(vLS, Vec_IntSize(vLS) - 1) );
|
||||||
|
*iLSM = Vec_IntEntry( vLS, 0 );
|
||||||
|
Vec_IntFree( vLS );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*********************************************************
|
||||||
|
|
||||||
|
Synopsis [Retrieve critical and near-critical edges count.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void AbcRmInvCollectNCE( Abc_Ntk_t * pNtk, int iThreshold, int * iCount )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pNode, * pFanin, * pPo;
|
||||||
|
int i, j, k;
|
||||||
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
|
{
|
||||||
|
if ( Abc_ObjRequiredLevel(pNode) - pNode->Level <= iThreshold )
|
||||||
|
{
|
||||||
|
Abc_ObjForEachFanin( pNode, pFanin, j )
|
||||||
|
{
|
||||||
|
*iCount += (j == 0) ? pNode->fCompl0 : pNode->fCompl1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Abc_NtkForEachPo( pNtk, pPo, k )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pNodeToPo = Abc_ObjFanin0(pPo);
|
||||||
|
if ( pPo->fCompl0 && Abc_ObjIsNode(pNodeToPo) && (Abc_ObjRequiredLevel(pNodeToPo) - pNodeToPo->Level <= iThreshold) )
|
||||||
|
(*iCount)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Use markB to record level slack, markA for critical flag.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkMarkCriticalNodesScale( Abc_Ntk_t * pNtk )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pNode;
|
||||||
|
int i, Counter = 0;
|
||||||
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
|
{
|
||||||
|
if ( Abc_ObjRequiredLevel(pNode) - pNode->Level <= 1 )
|
||||||
|
{
|
||||||
|
pNode->fMarkA = 1;
|
||||||
|
pNode->fMarkB = Abc_ObjRequiredLevel(pNode) - pNode->Level;
|
||||||
|
Counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf( "The number of nodes on the critical paths = %6d (%5.2f %%)\n", Counter, 100.0 * Counter / Abc_NtkNodeNum(pNtk) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Record sum of slack with inverted edges.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkCollectInvRelatedSlack( Abc_Ntk_t * pNtk, int * invSlack )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pNode, * pFanin;
|
||||||
|
int i, j;
|
||||||
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
|
{
|
||||||
|
Abc_ObjForEachFanin( pNode, pFanin, j )
|
||||||
|
{
|
||||||
|
if ( j == 0 && pNode->fCompl0 == 1 )
|
||||||
|
(*invSlack) += pFanin->fMarkB;
|
||||||
|
if ( j == 1 && pNode->fCompl1 == 1 )
|
||||||
|
(*invSlack) += pFanin->fMarkB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Process cuts: evaluate gain condition and flip if beneficial.]
|
||||||
|
|
||||||
|
Description [Shared logic for self-anti-dual and self-dual cut processing.
|
||||||
|
fIsSelfDual=0 treats SAD; fIsSelfDual=1 treats SD.]
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
static void Abc_RdInvProcessCuts( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode,
|
||||||
|
Vec_Ptr_t * vCone, Vec_Ptr_t * vCuts, int fIsSelfDual,
|
||||||
|
int * nCountCritical, int * nCountNonCritical, int * nCount, int iVerbose )
|
||||||
|
{
|
||||||
|
Cut_Cut_t * pCut;
|
||||||
|
int i;
|
||||||
|
Vec_PtrForEachEntry( Cut_Cut_t *, vCuts, pCut, i )
|
||||||
|
{
|
||||||
|
int nLocalInv = 0;
|
||||||
|
int nLocalSup = 0;
|
||||||
|
int nLocalInvOnCritical = 0;
|
||||||
|
int nLocalNonInvOnCritical = 0;
|
||||||
|
|
||||||
|
Vec_Ptr_t * vSupCuts = Abc_RdInvCollectCutLeaves( pNtk, pCut );
|
||||||
|
|
||||||
|
if ( fIsSelfDual )
|
||||||
|
Abc_NtkRmInverterCountInvRatioSelfDual( pNode, vCone, vSupCuts, &nLocalInv, &nLocalInvOnCritical, &nLocalNonInvOnCritical, &nLocalSup );
|
||||||
|
else
|
||||||
|
Abc_NtkRmInverterCountInvRatioSelfAntiDual( vCone, vSupCuts, &nLocalInv, &nLocalInvOnCritical, &nLocalNonInvOnCritical, &nLocalSup );
|
||||||
|
|
||||||
|
int fCheckCritical = (nLocalInvOnCritical > nLocalNonInvOnCritical);
|
||||||
|
int fCheckNonCritical = (nLocalInvOnCritical == 0 && nLocalNonInvOnCritical == 0 && nLocalSup > 0 && (float)nLocalInv / nLocalSup >= 0.5);
|
||||||
|
|
||||||
|
if ( fCheckCritical || fCheckNonCritical )
|
||||||
|
{
|
||||||
|
if ( fCheckCritical )
|
||||||
|
(*nCountCritical)++;
|
||||||
|
if ( fCheckNonCritical )
|
||||||
|
(*nCountNonCritical)++;
|
||||||
|
|
||||||
|
if ( iVerbose )
|
||||||
|
Abc_RmInvShowCutStructure( pNtk, pNode, pCut );
|
||||||
|
|
||||||
|
if ( fIsSelfDual )
|
||||||
|
Abc_NtkRmInverterFlipInvSelfDual( pNode, vCone, vSupCuts );
|
||||||
|
else
|
||||||
|
Abc_NtkRmInverterFlipInvSelfAntiDual( vCone, vSupCuts );
|
||||||
|
|
||||||
|
(*nCount)++;
|
||||||
|
}
|
||||||
|
Vec_PtrFree( vSupCuts );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Gain-based inverter removal.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
void Abc_NtkRmInverter( Abc_Ntk_t * pNtk, int iVerbose )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Abc_Obj_t * pNode, * pObj;
|
||||||
|
|
||||||
|
if ( !Abc_NtkIsStrash(pNtk) )
|
||||||
|
{
|
||||||
|
printf("Error: Abc_NtkRmInverter requires a strashed AIG network.\n");
|
||||||
|
printf("Current network type: %d\n", pNtk->ntkType);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( iVerbose )
|
||||||
|
{
|
||||||
|
printf("Processing strashed AIG network with %d nodes, %d PIs, %d POs\n",
|
||||||
|
Abc_NtkNodeNum(pNtk), Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk));
|
||||||
|
printf("Network level: %d\n", Abc_NtkLevel(pNtk));
|
||||||
|
}
|
||||||
|
|
||||||
|
Abc_NtkStartReverseLevels( pNtk, 0 );
|
||||||
|
Abc_NtkMarkCriticalNodesScale( pNtk );
|
||||||
|
|
||||||
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
|
{
|
||||||
|
if ( Abc_AigNodeIsChoice(pNode) )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pCurTempNode = (Abc_Obj_t *)pNode->pData;
|
||||||
|
while ( pCurTempNode != NULL )
|
||||||
|
{
|
||||||
|
pCurTempNode->fMarkA = 1;
|
||||||
|
pCurTempNode->fMarkB = pNode->fMarkB;
|
||||||
|
pCurTempNode = (Abc_Obj_t *)pCurTempNode->pData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int iNCEBefore = 0;
|
||||||
|
int iNCEAfter = 0;
|
||||||
|
int invSlackBefore = 0;
|
||||||
|
int invSlackAfter = 0;
|
||||||
|
int iLSM = 0;
|
||||||
|
AbcRmInvFetchMaxLSlack( pNtk, &iLSM );
|
||||||
|
int iThreshold = iLSM;
|
||||||
|
AbcRmInvCollectNCE( pNtk, iThreshold, &iNCEBefore );
|
||||||
|
Abc_NtkCollectInvRelatedSlack( pNtk, &invSlackBefore );
|
||||||
|
|
||||||
|
int nCountCriticalSAD = 0;
|
||||||
|
int nCountNonCriticalSAD = 0;
|
||||||
|
int nCountSAD = 0;
|
||||||
|
int nCountCriticalSD = 0;
|
||||||
|
int nCountNonCriticalSD = 0;
|
||||||
|
int nCountSD = 0;
|
||||||
|
int nTotalNodes = Abc_NtkNodeNum(pNtk);
|
||||||
|
int nProcessed = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
Cut_Man_t * pCutMan;
|
||||||
|
Cut_Params_t Params, * pParams = &Params;
|
||||||
|
memset( pParams, 0, sizeof(Cut_Params_t) );
|
||||||
|
pParams->nVarsMax = 5;
|
||||||
|
pParams->nKeepMax = 250;
|
||||||
|
pParams->fTruth = 1;
|
||||||
|
pParams->fFilter = 1;
|
||||||
|
pParams->fSeq = 0;
|
||||||
|
pParams->fLocal = 0;
|
||||||
|
pParams->fGlobal = 0;
|
||||||
|
pParams->fTree = 1;
|
||||||
|
pParams->fDrop = 0;
|
||||||
|
pParams->fVerbose = 1;
|
||||||
|
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
|
||||||
|
pCutMan = Cut_ManStart( pParams );
|
||||||
|
|
||||||
|
int j_ci;
|
||||||
|
Abc_NtkForEachCi( pNtk, pObj, j_ci )
|
||||||
|
if ( Abc_ObjFanoutNum(pObj) > 0 )
|
||||||
|
Cut_NodeSetTriv( pCutMan, pObj->Id );
|
||||||
|
|
||||||
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
|
{
|
||||||
|
if ( Abc_ObjFanoutNum(pNode) == 1 && pNode->pData != NULL )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Vec_Ptr_t * vCone = Vec_PtrAlloc( 16 );
|
||||||
|
Vec_Ptr_t * vSupp = Vec_PtrAlloc( 16 );
|
||||||
|
|
||||||
|
if ( iVerbose )
|
||||||
|
printf("\n\n\n");
|
||||||
|
|
||||||
|
Abc_NodeMffcConeSuppCollect( pNode, vCone, vSupp, iVerbose );
|
||||||
|
|
||||||
|
int i_sup;
|
||||||
|
Vec_PtrForEachEntryReverse( Abc_Obj_t *, vSupp, pObj, i_sup )
|
||||||
|
Vec_PtrInsert( vCone, 0, pObj );
|
||||||
|
|
||||||
|
if ( iVerbose )
|
||||||
|
printf("Support var size %d, internal node size %d\n", Vec_PtrSize(vSupp), Vec_PtrSize(vCone));
|
||||||
|
|
||||||
|
Vec_Ptr_t * vASDCuts = Vec_PtrAlloc( 16 );
|
||||||
|
Vec_Ptr_t * vASADCuts = Vec_PtrAlloc( 16 );
|
||||||
|
|
||||||
|
AbcRmInvAvaCuts( pNtk, pNode, pCutMan, vASDCuts, vASADCuts, iVerbose );
|
||||||
|
|
||||||
|
int nSADBefore = nCountSAD;
|
||||||
|
Abc_RdInvProcessCuts( pNtk, pNode, vCone, vASADCuts, 0,
|
||||||
|
&nCountCriticalSAD, &nCountNonCriticalSAD, &nCountSAD, iVerbose );
|
||||||
|
|
||||||
|
int nSDBefore = nCountSD;
|
||||||
|
Abc_RdInvProcessCuts( pNtk, pNode, vCone, vASDCuts, 1,
|
||||||
|
&nCountCriticalSD, &nCountNonCriticalSD, &nCountSD, iVerbose );
|
||||||
|
|
||||||
|
if ( nCountSAD > nSADBefore || nCountSD > nSDBefore )
|
||||||
|
nProcessed++;
|
||||||
|
|
||||||
|
Vec_PtrFree( vASADCuts );
|
||||||
|
Vec_PtrFree( vASDCuts );
|
||||||
|
Vec_PtrFree( vCone );
|
||||||
|
Vec_PtrFree( vSupp );
|
||||||
|
}
|
||||||
|
Cut_ManStop( pCutMan );
|
||||||
|
}
|
||||||
|
|
||||||
|
AbcRmInvCollectNCE( pNtk, iThreshold, &iNCEAfter );
|
||||||
|
Abc_NtkCollectInvRelatedSlack( pNtk, &invSlackAfter );
|
||||||
|
|
||||||
|
if ( iVerbose )
|
||||||
|
{
|
||||||
|
printf("=====Statistics about invNum with Threshold %d=====\n", iThreshold);
|
||||||
|
printf("Before %d After %d Gain %d \n", iNCEBefore, iNCEAfter, iNCEBefore - iNCEAfter);
|
||||||
|
if ( iNCEAfter > 0 || iNCEBefore > 0 )
|
||||||
|
printf("=====Statistics about edges that ease on slack=====\n"
|
||||||
|
"Ease Gain %f \n", (float)invSlackAfter / (iNCEAfter ? iNCEAfter : 1) - (float)invSlackBefore / (iNCEBefore ? iNCEBefore : 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
Abc_NtkStopReverseLevels( pNtk );
|
||||||
|
Abc_NtkCleanMarkAB( pNtk );
|
||||||
|
|
||||||
|
assert( nCountCriticalSAD + nCountNonCriticalSAD == nCountSAD );
|
||||||
|
assert( nCountCriticalSD + nCountNonCriticalSD == nCountSD );
|
||||||
|
|
||||||
|
printf("Total %d self-anti-dual functions", nCountSAD);
|
||||||
|
if ( nCountSAD > 0 )
|
||||||
|
printf(", Critical(%f), Non-critical(%f)", (float)nCountCriticalSAD / nCountSAD, (float)nCountNonCriticalSAD / nCountSAD);
|
||||||
|
printf(" / %d self-dual are modified", nCountSD);
|
||||||
|
if ( nCountSD > 0 )
|
||||||
|
printf(", Critical(%f), Non-critical(%f)", (float)nCountCriticalSD / nCountSD, (float)nCountNonCriticalSD / nCountSD);
|
||||||
|
printf(". Total process rate %f\n", nTotalNodes > 0 ? (float)nProcessed / nTotalNodes : 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
ABC_NAMESPACE_IMPL_END
|
||||||
|
|
@ -49,6 +49,7 @@ SRC += src/base/abci/abc.c \
|
||||||
src/base/abci/abcProve.c \
|
src/base/abci/abcProve.c \
|
||||||
src/base/abci/abcQbf.c \
|
src/base/abci/abcQbf.c \
|
||||||
src/base/abci/abcQuant.c \
|
src/base/abci/abcQuant.c \
|
||||||
|
src/base/abci/abcRmInverters.c \
|
||||||
src/base/abci/abcRec3.c \
|
src/base/abci/abcRec3.c \
|
||||||
src/base/abci/abcReconv.c \
|
src/base/abci/abcReconv.c \
|
||||||
src/base/abci/abcReach.c \
|
src/base/abci/abcReach.c \
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue