Commit 94726c98 by Alan Mishchenko

Other changes to enable new features in the mapper (bug fix).

parent b9dea5d6
...@@ -183,6 +183,9 @@ struct Abc_Ntk_t_ ...@@ -183,6 +183,9 @@ struct Abc_Ntk_t_
int nObjs; // the number of live objs int nObjs; // the number of live objs
int nConstrs; // the number of constraints int nConstrs; // the number of constraints
int nRealPos; // the number of real POs int nRealPos; // the number of real POs
float nRealDelay; // temporary mapping data
float nRealLuts; // temporary mapping data
float nRealArea; // temporary mapping data
// the backup network and the step number // the backup network and the step number
Abc_Ntk_t * pNetBackup; // the pointer to the previous backup network Abc_Ntk_t * pNetBackup; // the pointer to the previous backup network
int iStep; // the generation number for the given network int iStep; // the generation number for the given network
...@@ -852,7 +855,9 @@ extern ABC_DLL Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels ...@@ -852,7 +855,9 @@ extern ABC_DLL Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels
/*=== abcSweep.c ==========================================================*/ /*=== abcSweep.c ==========================================================*/
extern ABC_DLL int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose ); extern ABC_DLL int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose );
extern ABC_DLL int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose ); extern ABC_DLL int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose );
extern ABC_DLL int Abc_NtkCleanupNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, int fVerbose );
extern ABC_DLL int Abc_NtkCleanupSeq( Abc_Ntk_t * pNtk, int fLatchSweep, int fAutoSweep, int fVerbose ); extern ABC_DLL int Abc_NtkCleanupSeq( Abc_Ntk_t * pNtk, int fLatchSweep, int fAutoSweep, int fVerbose );
extern ABC_DLL int Abc_NtkSweepBufsInvs( Abc_Ntk_t * pNtk, int fVerbose );
/*=== abcTiming.c ==========================================================*/ /*=== abcTiming.c ==========================================================*/
extern ABC_DLL Abc_Time_t * Abc_NodeReadArrival( Abc_Obj_t * pNode ); extern ABC_DLL Abc_Time_t * Abc_NodeReadArrival( Abc_Obj_t * pNode );
extern ABC_DLL Abc_Time_t * Abc_NodeReadRequired( Abc_Obj_t * pNode ); extern ABC_DLL Abc_Time_t * Abc_NodeReadRequired( Abc_Obj_t * pNode );
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
***********************************************************************/ ***********************************************************************/
#include "abc.h" #include "abc.h"
#include "main.h"
//#include "seq.h" //#include "seq.h"
ABC_NAMESPACE_IMPL_START ABC_NAMESPACE_IMPL_START
...@@ -152,6 +153,7 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk ) ...@@ -152,6 +153,7 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk )
assert( Abc_NtkIsLogic(pNtk) ); assert( Abc_NtkIsLogic(pNtk) );
// remove dangling nodes // remove dangling nodes
if ( pNtk->vRealNodes == NULL )
Abc_NtkCleanup( pNtk, 0 ); Abc_NtkCleanup( pNtk, 0 );
// make sure the CO names are unique // make sure the CO names are unique
...@@ -162,6 +164,7 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk ) ...@@ -162,6 +164,7 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk )
// assert( Abc_NtkLogicHasSimpleCos(pNtk) ); // assert( Abc_NtkLogicHasSimpleCos(pNtk) );
if ( !Abc_NtkLogicHasSimpleCos(pNtk) ) if ( !Abc_NtkLogicHasSimpleCos(pNtk) )
{ {
if ( !Abc_FrameReadFlag("silentmode") )
printf( "Abc_NtkLogicToNetlist() warning: The network is converted to have simple COs.\n" ); printf( "Abc_NtkLogicToNetlist() warning: The network is converted to have simple COs.\n" );
Abc_NtkLogicMakeSimpleCos( pNtk, 0 ); Abc_NtkLogicMakeSimpleCos( pNtk, 0 );
} }
...@@ -226,6 +229,7 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk ) ...@@ -226,6 +229,7 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk )
pNtkNew->vRealNodes = Vec_IntAlloc( Vec_IntSize(pNtk->vRealNodes) ); pNtkNew->vRealNodes = Vec_IntAlloc( Vec_IntSize(pNtk->vRealNodes) );
Abc_NtkForEachObjVec( pNtk->vRealNodes, pNtk, pObj, i ) Abc_NtkForEachObjVec( pNtk->vRealNodes, pNtk, pObj, i )
Vec_IntPush( pNtkNew->vRealNodes, Abc_ObjId(pObj->pCopy) ); Vec_IntPush( pNtkNew->vRealNodes, Abc_ObjId(pObj->pCopy) );
assert( Vec_IntSize(pNtk->vRealNodes) == Vec_IntSize(pNtkNew->vRealNodes) );
} }
// duplicate EXDC // duplicate EXDC
......
...@@ -111,6 +111,9 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_ ...@@ -111,6 +111,9 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_
pNtkNew = Abc_NtkAlloc( Type, Func, 1 ); pNtkNew = Abc_NtkAlloc( Type, Func, 1 );
pNtkNew->nConstrs = pNtk->nConstrs; pNtkNew->nConstrs = pNtk->nConstrs;
pNtkNew->nRealPos = pNtk->nRealPos; pNtkNew->nRealPos = pNtk->nRealPos;
pNtkNew->nRealDelay = pNtk->nRealDelay;
pNtkNew->nRealLuts = pNtk->nRealLuts;
pNtkNew->nRealArea = pNtk->nRealArea;
pNtkNew->vRealPos = pNtk->vRealPos ? Vec_VecDup( pNtk->vRealPos ) : NULL; pNtkNew->vRealPos = pNtk->vRealPos ? Vec_VecDup( pNtk->vRealPos ) : NULL;
// duplicate the name and the spec // duplicate the name and the spec
pNtkNew->pName = Extra_UtilStrsav(pNtk->pName); pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
...@@ -166,6 +169,9 @@ Abc_Ntk_t * Abc_NtkStartFromNoLatches( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc ...@@ -166,6 +169,9 @@ Abc_Ntk_t * Abc_NtkStartFromNoLatches( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc
pNtkNew = Abc_NtkAlloc( Type, Func, 1 ); pNtkNew = Abc_NtkAlloc( Type, Func, 1 );
pNtkNew->nConstrs = pNtk->nConstrs; pNtkNew->nConstrs = pNtk->nConstrs;
pNtkNew->nRealPos = pNtk->nRealPos; pNtkNew->nRealPos = pNtk->nRealPos;
pNtkNew->nRealDelay = pNtk->nRealDelay;
pNtkNew->nRealLuts = pNtk->nRealLuts;
pNtkNew->nRealArea = pNtk->nRealArea;
pNtkNew->vRealPos = pNtk->vRealPos ? Vec_VecDup( pNtk->vRealPos ) : NULL; pNtkNew->vRealPos = pNtk->vRealPos ? Vec_VecDup( pNtk->vRealPos ) : NULL;
// duplicate the name and the spec // duplicate the name and the spec
pNtkNew->pName = Extra_UtilStrsav(pNtk->pName); pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
...@@ -357,6 +363,15 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk ) ...@@ -357,6 +363,15 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
Abc_ObjForEachFanin( pObj, pFanin, k ) Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
} }
// remap the real nodess
if ( pNtk->vRealNodes )
{
assert( pNtkNew->vRealNodes == NULL );
pNtkNew->vRealNodes = Vec_IntAlloc( Vec_IntSize(pNtk->vRealNodes) );
Abc_NtkForEachObjVec( pNtk->vRealNodes, pNtk, pObj, i )
Vec_IntPush( pNtkNew->vRealNodes, Abc_ObjId(pObj->pCopy) );
assert( Vec_IntSize(pNtk->vRealNodes) == Vec_IntSize(pNtkNew->vRealNodes) );
}
// duplicate the EXDC Ntk // duplicate the EXDC Ntk
if ( pNtk->pExdc ) if ( pNtk->pExdc )
pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc ); pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
......
...@@ -3342,13 +3342,21 @@ int Abc_CommandSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -3342,13 +3342,21 @@ int Abc_CommandSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
{ {
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
int c; int c;
int fSingle = 0;
int fVerbose = 0;
// set defaults // set defaults
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "svh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
case 's':
fSingle ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
case 'h': case 'h':
goto usage; goto usage;
default: default:
...@@ -3367,12 +3375,17 @@ int Abc_CommandSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -3367,12 +3375,17 @@ int Abc_CommandSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1; return 1;
} }
// modify the current network // modify the current network
Abc_NtkSweep( pNtk, 0 ); if ( fSingle )
Abc_NtkSweepBufsInvs( pNtk, fVerbose );
else
Abc_NtkSweep( pNtk, fVerbose );
return 0; return 0;
usage: usage:
Abc_Print( -2, "usage: sweep [-h]\n" ); Abc_Print( -2, "usage: sweep [-svh]\n" );
Abc_Print( -2, "\t removes dangling nodes; propagates constant, buffers, inverters\n" ); Abc_Print( -2, "\t removes dangling nodes; propagates constant, buffers, inverters\n" );
Abc_Print( -2, "\t-s : toggle sweeping buffers/inverters only [default = %s]\n", fSingle? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\t-h : print the command usage\n");
return 1; return 1;
} }
...@@ -13150,6 +13163,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -13150,6 +13163,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
// enable truth table computation if choices are selected // enable truth table computation if choices are selected
if ( (c = Abc_NtkGetChoiceNum( pNtk )) ) if ( (c = Abc_NtkGetChoiceNum( pNtk )) )
{ {
if ( !Abc_FrameReadFlag("silentmode") )
Abc_Print( 0, "Performing LUT mapping with %d choices.\n", c ); Abc_Print( 0, "Performing LUT mapping with %d choices.\n", c );
pPars->fExpRed = 0; pPars->fExpRed = 0;
} }
...@@ -13243,6 +13257,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -13243,6 +13257,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Balancing before FPGA mapping has failed.\n" ); Abc_Print( -1, "Balancing before FPGA mapping has failed.\n" );
return 1; return 1;
} }
if ( !Abc_FrameReadFlag("silentmode") )
Abc_Print( 1, "The network was strashed and balanced before FPGA mapping.\n" ); Abc_Print( 1, "The network was strashed and balanced before FPGA mapping.\n" );
// get the new network // get the new network
pNtkRes = Abc_NtkIf( pNtk, pPars ); pNtkRes = Abc_NtkIf( pNtk, pPars );
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
***********************************************************************/ ***********************************************************************/
#include "abc.h" #include "abc.h"
#include "main.h"
#include "if.h" #include "if.h"
#include "kit.h" #include "kit.h"
#include "aig.h" #include "aig.h"
...@@ -332,7 +333,7 @@ Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk ) ...@@ -332,7 +333,7 @@ Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk )
Abc_NtkBddReorder( pNtkNew, 0 ); Abc_NtkBddReorder( pNtkNew, 0 );
// decouple the PO driver nodes to reduce the number of levels // decouple the PO driver nodes to reduce the number of levels
nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, !pIfMan->pPars->fUseBuffs ); nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, !pIfMan->pPars->fUseBuffs );
if ( nDupGates && pIfMan->pPars->fVerbose ) if ( nDupGates && pIfMan->pPars->fVerbose && !Abc_FrameReadFlag("silentmode") )
{ {
if ( pIfMan->pPars->fUseBuffs ) if ( pIfMan->pPars->fUseBuffs )
printf( "Added %d buffers/inverters to decouple the CO drivers.\n", nDupGates ); printf( "Added %d buffers/inverters to decouple the CO drivers.\n", nDupGates );
...@@ -812,15 +813,18 @@ void Abc_NtkCollectPoDrivers( If_Man_t * p, Abc_Ntk_t * pNtk ) ...@@ -812,15 +813,18 @@ void Abc_NtkCollectPoDrivers( If_Man_t * p, Abc_Ntk_t * pNtk )
int i, g, nGroups; int i, g, nGroups;
if ( pNtk->nRealPos == 0 ) if ( pNtk->nRealPos == 0 )
{ {
if ( !Abc_FrameReadFlag("silentmode") )
printf( "PO drivers are not defined.\n" ); printf( "PO drivers are not defined.\n" );
return; return;
} }
if ( (Abc_NtkPoNum(pNtk) - pNtk->nRealPos) % 5 != 0 ) if ( (Abc_NtkPoNum(pNtk) - pNtk->nRealPos) % 5 != 0 )
{ {
if ( !Abc_FrameReadFlag("silentmode") )
printf( "PO drivers are not divisible by 5.\n" ); printf( "PO drivers are not divisible by 5.\n" );
return; return;
} }
nGroups = (Abc_NtkPoNum(pNtk) - pNtk->nRealPos) / 5; nGroups = (Abc_NtkPoNum(pNtk) - pNtk->nRealPos) / 5;
if ( !Abc_FrameReadFlag("silentmode") )
printf( "Processing %d groups of PO drivers.\n", nGroups ); printf( "Processing %d groups of PO drivers.\n", nGroups );
// mark the drivers (0 a 1 b 2 c 3 s 4 c) // mark the drivers (0 a 1 b 2 c 3 s 4 c)
assert( p->pDriverCuts == NULL ); assert( p->pDriverCuts == NULL );
...@@ -987,6 +991,8 @@ void Abc_NtkFreePoDrivers( If_Man_t * p, Abc_Ntk_t * pNtk ) ...@@ -987,6 +991,8 @@ void Abc_NtkFreePoDrivers( If_Man_t * p, Abc_Ntk_t * pNtk )
int i; int i;
if ( p->pDriverCuts == NULL ) if ( p->pDriverCuts == NULL )
return; return;
pNtk->nRealDelay = p->RequiredGlo;
if ( !Abc_FrameReadFlag("silentmode") )
printf( "Actual delay after mapping = %.2f\n", p->RequiredGlo ); printf( "Actual delay after mapping = %.2f\n", p->RequiredGlo );
assert( Abc_NtkPoNum(pNtk) == If_ManCoNum(p) - Abc_NtkLatchNum(pNtk) ); assert( Abc_NtkPoNum(pNtk) == If_ManCoNum(p) - Abc_NtkLatchNum(pNtk) );
// print the cut sizes of the drivers // print the cut sizes of the drivers
...@@ -1080,6 +1086,7 @@ void Abc_NtkRecreatePoDrivers( If_Man_t * p, Abc_Ntk_t * pNtkNew ) ...@@ -1080,6 +1086,7 @@ void Abc_NtkRecreatePoDrivers( If_Man_t * p, Abc_Ntk_t * pNtkNew )
float RealLutArea; float RealLutArea;
if ( pNtkNew->vRealPos == NULL ) if ( pNtkNew->vRealPos == NULL )
{ {
if ( !Abc_FrameReadFlag("silentmode") )
printf( "Missing key information.\n" ); printf( "Missing key information.\n" );
return; return;
} }
...@@ -1088,7 +1095,7 @@ void Abc_NtkRecreatePoDrivers( If_Man_t * p, Abc_Ntk_t * pNtkNew ) ...@@ -1088,7 +1095,7 @@ void Abc_NtkRecreatePoDrivers( If_Man_t * p, Abc_Ntk_t * pNtkNew )
// create drivers // create drivers
vDrivers = Vec_PtrStart( pNtkNew->nRealPos ); vDrivers = Vec_PtrStart( pNtkNew->nRealPos );
vDriverInvs = Vec_IntStart( pNtkNew->nRealPos ); vDriverInvs = Vec_IntStart( pNtkNew->nRealPos );
pNtkNew->vRealNodes = Vec_IntAlloc( pNtkNew->nRealPos ); pNtkNew->vRealNodes = Vec_IntAlloc( Abc_NtkPoNum(pNtkNew) - pNtkNew->nRealPos );
for ( i = pNtkNew->nRealPos; i < Abc_NtkPoNum(pNtkNew); i++ ) for ( i = pNtkNew->nRealPos; i < Abc_NtkPoNum(pNtkNew); i++ )
{ {
pObj = Abc_NtkPo( pNtkNew, i ); pObj = Abc_NtkPo( pNtkNew, i );
...@@ -1130,12 +1137,16 @@ void Abc_NtkRecreatePoDrivers( If_Man_t * p, Abc_Ntk_t * pNtkNew ) ...@@ -1130,12 +1137,16 @@ void Abc_NtkRecreatePoDrivers( If_Man_t * p, Abc_Ntk_t * pNtkNew )
Vec_PtrPush( vFanins, pExor ); Vec_PtrPush( vFanins, pExor );
Vec_PtrPush( vFanins, (Abc_Obj_t *)Vec_PtrEntry(vDrivers, numPo+2) ); Vec_PtrPush( vFanins, (Abc_Obj_t *)Vec_PtrEntry(vDrivers, numPo+2) );
pNode = Abc_NtkCreateNodeExor( pNtkNew, vFanins ); pNode = Abc_NtkCreateNodeExor( pNtkNew, vFanins );
// update pointers
Vec_PtrWriteEntry( vDriversNew, numPo+3, pNode ); Vec_PtrWriteEntry( vDriversNew, numPo+3, pNode );
Vec_IntWriteEntry( pNtkNew->vRealNodes, numPo+3 - pNtkNew->nRealPos, Abc_ObjId(pNode) );
// create MUX // create MUX
pNode = Abc_NtkCreateNodeMux( pNtkNew, pExor, pNode = Abc_NtkCreateNodeMux( pNtkNew, pExor,
(Abc_Obj_t *)Vec_PtrEntry(vDrivers, numPo+2), (Abc_Obj_t *)Vec_PtrEntry(vDrivers, numPo+2),
(Abc_Obj_t *)Vec_PtrEntry(vDrivers, numPo+(fCompl ? 0 : 1)) ); (Abc_Obj_t *)Vec_PtrEntry(vDrivers, numPo+(fCompl ? 0 : 1)) );
// update pointers
Vec_PtrWriteEntry( vDriversNew, numPo+4, pNode ); Vec_PtrWriteEntry( vDriversNew, numPo+4, pNode );
Vec_IntWriteEntry( pNtkNew->vRealNodes, numPo+4 - pNtkNew->nRealPos, Abc_ObjId(pNode) );
} }
} }
Vec_PtrFree( vFanins ); Vec_PtrFree( vFanins );
...@@ -1147,15 +1158,31 @@ void Abc_NtkRecreatePoDrivers( If_Man_t * p, Abc_Ntk_t * pNtkNew ) ...@@ -1147,15 +1158,31 @@ void Abc_NtkRecreatePoDrivers( If_Man_t * p, Abc_Ntk_t * pNtkNew )
{ {
pObj = Abc_NtkPo( pNtkNew, numPo+3 ); pObj = Abc_NtkPo( pNtkNew, numPo+3 );
Vec_IntWriteEntry( vNodeMap, Abc_ObjId( Abc_ObjFanin0(pObj) ), numPo+3 ); Vec_IntWriteEntry( vNodeMap, Abc_ObjId( Abc_ObjFanin0(pObj) ), numPo+3 );
// update the PO pointer
// if ( Abc_ObjFaninC0(pObj) )
// Abc_ObjXorFaninC( pObj, 0 );
// Abc_ObjPatchFanin( pObj, Abc_ObjFanin0(pObj), Vec_PtrEntry(vDriversNew, numPo+3) );
pObj = Abc_NtkPo( pNtkNew, numPo+4 ); pObj = Abc_NtkPo( pNtkNew, numPo+4 );
Vec_IntWriteEntry( vNodeMap, Abc_ObjId( Abc_ObjFanin0(pObj) ), numPo+4 ); Vec_IntWriteEntry( vNodeMap, Abc_ObjId( Abc_ObjFanin0(pObj) ), numPo+4 );
// update the PO pointer
// if ( Abc_ObjFaninC0(pObj) )
// Abc_ObjXorFaninC( pObj, 0 );
// Abc_ObjPatchFanin( pObj, Abc_ObjFanin0(pObj), Vec_PtrEntry(vDriversNew, numPo+4) );
} }
// replace logic // replace logic
Abc_NtkForEachObj( pNtkNew, pObj, i ) Abc_NtkForEachObj( pNtkNew, pObj, i )
{ {
// if ( Abc_ObjIsPo(pObj) )
// continue;
Abc_ObjForEachFanin( pObj, pFanin, k ) Abc_ObjForEachFanin( pObj, pFanin, k )
{ {
if ( !Abc_ObjIsNode(pFanin) || Abc_ObjFaninNum(pFanin) == 0 )
continue;
numPo = Vec_IntEntry( vNodeMap, Abc_ObjId(pFanin) ); numPo = Vec_IntEntry( vNodeMap, Abc_ObjId(pFanin) );
if ( numPo == ~0 ) if ( numPo == ~0 )
continue; continue;
...@@ -1171,14 +1198,24 @@ void Abc_NtkRecreatePoDrivers( If_Man_t * p, Abc_Ntk_t * pNtkNew ) ...@@ -1171,14 +1198,24 @@ void Abc_NtkRecreatePoDrivers( If_Man_t * p, Abc_Ntk_t * pNtkNew )
Abc_ObjPatchFanin( pObj, pFanin, pFaninNew ); Abc_ObjPatchFanin( pObj, pFanin, pFaninNew );
} }
} }
// sweep
Abc_NtkCleanupNodes( pNtkNew, vDriversNew, 0 );
// make sure that all vDriversNew are still present
{
Abc_Obj_t * pObj;
int i;
Vec_PtrForEachEntry( Abc_Obj_t *, vDriversNew, pObj, i )
if ( pObj && Abc_ObjIsNone(pObj) )
assert( 0 );
}
Vec_PtrFree( vDrivers ); Vec_PtrFree( vDrivers );
Vec_PtrFree( vDriversNew ); Vec_PtrFree( vDriversNew );
Vec_IntFree( vNodeMap ); Vec_IntFree( vNodeMap );
Vec_IntFree( vDriverInvs ); Vec_IntFree( vDriverInvs );
// sweep
Abc_NtkCleanup( pNtkNew, 0 );
// count non-trivial LUTs nodes // count non-trivial LUTs nodes
nRealLuts = -2 * Vec_VecSizeSize(pNtkNew->vRealPos); nRealLuts = -2 * Vec_VecSizeSize(pNtkNew->vRealPos);
RealLutArea = -(p->pPars->pLutLib ? p->pPars->pLutLib->pLutAreas[2] + p->pPars->pLutLib->pLutAreas[3] : 2.0) * Vec_VecSizeSize(pNtkNew->vRealPos); RealLutArea = -(p->pPars->pLutLib ? p->pPars->pLutLib->pLutAreas[2] + p->pPars->pLutLib->pLutAreas[3] : 2.0) * Vec_VecSizeSize(pNtkNew->vRealPos);
...@@ -1188,7 +1225,10 @@ void Abc_NtkRecreatePoDrivers( If_Man_t * p, Abc_Ntk_t * pNtkNew ) ...@@ -1188,7 +1225,10 @@ void Abc_NtkRecreatePoDrivers( If_Man_t * p, Abc_Ntk_t * pNtkNew )
nRealLuts++; nRealLuts++;
RealLutArea += p->pPars->pLutLib->pLutAreas[Abc_ObjFaninNum(pNode)]; RealLutArea += p->pPars->pLutLib->pLutAreas[Abc_ObjFaninNum(pNode)];
} }
if ( !Abc_FrameReadFlag("silentmode") )
printf( "The number of real LUTs = %d. Real LUT area = %.2f.\n", nRealLuts, RealLutArea ); printf( "The number of real LUTs = %d. Real LUT area = %.2f.\n", nRealLuts, RealLutArea );
pNtkNew->nRealLuts = nRealLuts;
pNtkNew->nRealArea = RealLutArea;
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -490,6 +490,40 @@ int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose ) ...@@ -490,6 +490,40 @@ int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Removes dangling nodes.]
Description [Returns the number of nodes removed.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkCleanupNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, int fVerbose )
{
Vec_Ptr_t * vNodes, * vStarts;
Abc_Obj_t * pObj;
int i, Counter;
assert( Abc_NtkIsLogic(pNtk) );
// collect starting nodes into one array
vStarts = Vec_PtrAlloc( 1000 );
Abc_NtkForEachCo( pNtk, pObj, i )
Vec_PtrPush( vStarts, pObj );
Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i )
if ( pObj )
Vec_PtrPush( vStarts, pObj );
// mark the nodes reachable from the POs
vNodes = Abc_NtkDfsNodes( pNtk, (Abc_Obj_t **)Vec_PtrArray(vStarts), Vec_PtrSize(vStarts) );
Vec_PtrFree( vStarts );
Counter = Abc_NtkReduceNodes( pNtk, vNodes );
if ( fVerbose )
printf( "Cleanup removed %d dangling nodes.\n", Counter );
Vec_PtrFree( vNodes );
return Counter;
}
/**Function*************************************************************
Synopsis [Preserves the nodes collected in the array.] Synopsis [Preserves the nodes collected in the array.]
Description [Returns the number of nodes removed.] Description [Returns the number of nodes removed.]
...@@ -945,6 +979,80 @@ int Abc_NtkCleanupSeq( Abc_Ntk_t * pNtk, int fLatchSweep, int fAutoSweep, int fV ...@@ -945,6 +979,80 @@ int Abc_NtkCleanupSeq( Abc_Ntk_t * pNtk, int fLatchSweep, int fAutoSweep, int fV
return 1; return 1;
} }
/**Function*************************************************************
Synopsis [Sweep to remove buffers and inverters.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkSweepBufsInvs( Abc_Ntk_t * pNtk, int fVerbose )
{
Hop_Man_t * pMan;
Abc_Obj_t * pObj, * pFanin;
int i, k, fChanges = 1, Counter = 0;
assert( Abc_NtkIsLogic(pNtk) );
// convert network to BDD representation
if ( !Abc_NtkToAig(pNtk) )
{
fprintf( stdout, "Converting to SOP has failed.\n" );
return 1;
}
// get AIG manager
pMan = (Hop_Man_t *)pNtk->pManFunc;
// label selected nodes
Abc_NtkIncrementTravId( pNtk );
if ( pNtk->vRealNodes )
{
Abc_Obj_t * pObj;
assert( Vec_IntSize(pNtk->vRealNodes) == Abc_NtkPoNum(pNtk) - pNtk->nRealPos );
Abc_NtkForEachObjVec( pNtk->vRealNodes, pNtk, pObj, i )
Abc_NodeSetTravIdCurrent( pObj );
}
// iterate till no improvement
while ( fChanges )
{
fChanges = 0;
Abc_NtkForEachObj( pNtk, pObj, i )
{
Abc_ObjForEachFanin( pObj, pFanin, k )
{
// do not eliminate marked fanins
if ( Abc_NodeIsTravIdCurrent(pFanin) )
continue;
// do not eliminate constant nodes
if ( !Abc_ObjIsNode(pFanin) || Abc_ObjFaninNum(pFanin) != 1 )
continue;
// do not eliminate inverters into COs
if ( Abc_ObjIsCo(pObj) && Abc_NodeIsInv(pFanin) )
continue;
// do not eliminate buffers connecting PIs and POs
// if ( Abc_ObjIsCo(pObj) && Abc_ObjIsCi(Abc_ObjFanin0(pFanin)) )
// continue;
fChanges = 1;
Counter++;
// update function of the node
if ( Abc_NodeIsInv(pFanin) )
pObj->pData = Hop_Compose( pMan, (Hop_Obj_t *)pObj->pData, Hop_Not(Hop_IthVar(pMan, k)), k );
// update the fanin
Abc_ObjPatchFanin( pObj, pFanin, Abc_ObjFanin0(pFanin) );
if ( Abc_ObjFanoutNum(pFanin) == 0 )
Abc_NtkDeleteObj(pFanin);
}
}
}
if ( fVerbose )
printf( "Removed %d single input nodes.\n", Counter );
return Counter;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
......
...@@ -387,8 +387,10 @@ void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches ) ...@@ -387,8 +387,10 @@ void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
if ( pNtk->vRealNodes ) if ( pNtk->vRealNodes )
{ {
Abc_Obj_t * pObj; Abc_Obj_t * pObj;
int Num1 = Vec_IntSize(pNtk->vRealNodes);
int Num2 = Abc_NtkPoNum(pNtk)-pNtk->nRealPos;
fprintf( pFile, "\n\n" ); fprintf( pFile, "\n\n" );
assert( pNtk->nRealPos >= 0 ); assert( Vec_IntSize(pNtk->vRealNodes) == Abc_NtkPoNum(pNtk)-pNtk->nRealPos );
Abc_NtkForEachObjVec( pNtk->vRealNodes, pNtk, pObj, i ) Abc_NtkForEachObjVec( pNtk->vRealNodes, pNtk, pObj, i )
fprintf( pFile, "#INFO %s %s\n", fprintf( pFile, "#INFO %s %s\n",
Abc_ObjName(Abc_ObjFanin0(Abc_NtkPo(pNtk, pNtk->nRealPos+i))), Abc_ObjName(Abc_ObjFanin0(Abc_NtkPo(pNtk, pNtk->nRealPos+i))),
......
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