abc/src/base/abci/abcRewrite.c

421 lines
12 KiB
C
Raw Normal View History

2005-08-07 17:01:00 +02:00
/**CFile****************************************************************
2005-09-05 17:01:00 +02:00
FileName [abcRewrite.c]
2005-08-07 17:01:00 +02:00
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
2005-09-05 17:01:00 +02:00
Synopsis [Technology-independent resynthesis of the AIG based on DAG aware rewriting.]
2005-08-07 17:01:00 +02:00
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
2005-09-05 17:01:00 +02:00
Revision [$Id: abcRewrite.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
2005-08-07 17:01:00 +02:00
***********************************************************************/
2012-01-21 13:30:10 +01:00
#include "src/base/abc/abc.h"
#include "src/opt/rwr/rwr.h"
#include "src/bool/dec/dec.h"
2005-08-07 17:01:00 +02:00
2010-11-01 09:35:04 +01:00
ABC_NAMESPACE_IMPL_START
2005-09-05 17:01:00 +02:00
/*
The ideas realized in this package are inspired by the paper:
Per Bjesse, Arne Boralv, "DAG-aware circuit compression for
formal verification", Proc. ICCAD 2004, pp. 42-49.
*/
2005-08-07 17:01:00 +02:00
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
2008-01-31 05:01:00 +01:00
static Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk );
2005-08-27 17:01:00 +02:00
static void Abc_NodePrintCuts( Abc_Obj_t * pNode );
2008-01-31 05:01:00 +01:00
static void Abc_ManShowCutCone( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves );
extern void Abc_PlaceBegin( Abc_Ntk_t * pNtk );
extern void Abc_PlaceEnd( Abc_Ntk_t * pNtk );
extern void Abc_PlaceUpdate( Vec_Ptr_t * vAddedCells, Vec_Ptr_t * vUpdatedNets );
2007-02-16 17:01:00 +01:00
2005-08-07 17:01:00 +02:00
////////////////////////////////////////////////////////////////////////
2008-01-31 05:01:00 +01:00
/// FUNCTION DEFINITIONS ///
2005-08-07 17:01:00 +02:00
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
2005-08-17 17:01:00 +02:00
Synopsis [Performs incremental rewriting of the AIG.]
2005-08-07 17:01:00 +02:00
2005-08-17 17:01:00 +02:00
Description []
2005-08-07 17:01:00 +02:00
SideEffects []
SeeAlso []
***********************************************************************/
2008-01-31 05:01:00 +01:00
int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable )
2005-08-07 17:01:00 +02:00
{
2010-11-01 09:35:04 +01:00
extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
2005-08-07 17:01:00 +02:00
ProgressBar * pProgress;
2005-08-27 17:01:00 +02:00
Cut_Man_t * pManCut;
Rwr_Man_t * pManRwr;
2005-08-07 17:01:00 +02:00
Abc_Obj_t * pNode;
2008-07-02 17:01:00 +02:00
// Vec_Ptr_t * vAddedCells = NULL, * vUpdatedNets = NULL;
2008-01-31 05:01:00 +01:00
Dec_Graph_t * pGraph;
int i, nNodes, nGain, fCompl;
2005-08-27 17:01:00 +02:00
int clk, clkStart = clock();
2005-08-07 17:01:00 +02:00
2005-08-29 17:01:00 +02:00
assert( Abc_NtkIsStrash(pNtk) );
2005-09-01 17:01:00 +02:00
// cleanup the AIG
2010-11-01 09:35:04 +01:00
Abc_AigCleanup((Abc_Aig_t *)pNtk->pManFunc);
2008-01-31 05:01:00 +01:00
/*
{
Vec_Vec_t * vParts;
vParts = Abc_NtkPartitionSmart( pNtk, 50, 1 );
Vec_VecFree( vParts );
}
*/
// start placement package
// if ( fPlaceEnable )
// {
// Abc_PlaceBegin( pNtk );
// vAddedCells = Abc_AigUpdateStart( pNtk->pManFunc, &vUpdatedNets );
// }
2005-08-17 17:01:00 +02:00
// start the rewriting manager
2005-08-27 17:01:00 +02:00
pManRwr = Rwr_ManStart( 0 );
if ( pManRwr == NULL )
2005-08-19 17:01:00 +02:00
return 0;
2008-01-31 05:01:00 +01:00
// compute the reverse levels if level update is requested
if ( fUpdateLevel )
Abc_NtkStartReverseLevels( pNtk, 0 );
2005-08-27 17:01:00 +02:00
// start the cut manager
clk = clock();
2008-01-31 05:01:00 +01:00
pManCut = Abc_NtkStartCutManForRewrite( pNtk );
2005-08-27 17:01:00 +02:00
Rwr_ManAddTimeCuts( pManRwr, clock() - clk );
pNtk->pManCut = pManCut;
2005-08-07 17:01:00 +02:00
2008-01-31 05:01:00 +01:00
if ( fVeryVerbose )
Rwr_ScoresClean( pManRwr );
2005-08-17 17:01:00 +02:00
// resynthesize each node once
2008-01-31 05:01:00 +01:00
pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk);
2005-08-17 17:01:00 +02:00
nNodes = Abc_NtkObjNumMax(pNtk);
pProgress = Extra_ProgressBarStart( stdout, nNodes );
2005-08-07 17:01:00 +02:00
Abc_NtkForEachNode( pNtk, pNode, i )
{
2005-08-24 17:01:00 +02:00
Extra_ProgressBarUpdate( pProgress, i, NULL );
// stop if all nodes have been tried once
if ( i >= nNodes )
break;
2008-01-31 05:01:00 +01:00
// skip persistant nodes
if ( Abc_NodeIsPersistant(pNode) )
2006-06-11 17:01:00 +02:00
continue;
2005-09-05 17:01:00 +02:00
// skip the nodes with many fanouts
if ( Abc_ObjFanoutNum(pNode) > 1000 )
continue;
2008-01-31 05:01:00 +01:00
2005-08-17 17:01:00 +02:00
// for each cut, try to resynthesize it
2008-01-31 05:01:00 +01:00
nGain = Rwr_NodeRewrite( pManRwr, pManCut, pNode, fUpdateLevel, fUseZeros, fPlaceEnable );
2008-07-02 17:01:00 +02:00
if ( !(nGain > 0 || (nGain == 0 && fUseZeros)) )
2008-01-31 05:01:00 +01:00
continue;
// if we end up here, a rewriting step is accepted
// get hold of the new subgraph to be added to the AIG
2010-11-01 09:35:04 +01:00
pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr);
2008-01-31 05:01:00 +01:00
fCompl = Rwr_ManReadCompl(pManRwr);
// reset the array of the changed nodes
if ( fPlaceEnable )
2010-11-01 09:35:04 +01:00
Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc );
2008-01-31 05:01:00 +01:00
// complement the FF if needed
if ( fCompl ) Dec_GraphComplement( pGraph );
clk = clock();
Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain );
Rwr_ManAddTimeUpdate( pManRwr, clock() - clk );
if ( fCompl ) Dec_GraphComplement( pGraph );
// use the array of changed nodes to update placement
// if ( fPlaceEnable )
// Abc_PlaceUpdate( vAddedCells, vUpdatedNets );
2005-08-07 17:01:00 +02:00
}
Extra_ProgressBarStop( pProgress );
2005-08-27 17:01:00 +02:00
Rwr_ManAddTimeTotal( pManRwr, clock() - clkStart );
// print stats
2008-01-31 05:01:00 +01:00
pManRwr->nNodesEnd = Abc_NtkNodeNum(pNtk);
2005-08-27 17:01:00 +02:00
if ( fVerbose )
Rwr_ManPrintStats( pManRwr );
2008-01-31 05:01:00 +01:00
// Rwr_ManPrintStatsFile( pManRwr );
if ( fVeryVerbose )
Rwr_ScoresReport( pManRwr );
2005-08-27 17:01:00 +02:00
// delete the managers
Rwr_ManStop( pManRwr );
Cut_ManStop( pManCut );
pNtk->pManCut = NULL;
2008-01-31 05:01:00 +01:00
// start placement package
// if ( fPlaceEnable )
// {
// Abc_PlaceEnd( pNtk );
// Abc_AigUpdateStop( pNtk->pManFunc );
// }
// put the nodes into the DFS order and reassign their IDs
{
// int clk = clock();
Abc_NtkReassignIds( pNtk );
2009-02-15 17:01:00 +01:00
// ABC_PRT( "time", clock() - clk );
2008-01-31 05:01:00 +01:00
}
// Abc_AigCheckFaninOrder( pNtk->pManFunc );
// fix the levels
if ( fUpdateLevel )
Abc_NtkStopReverseLevels( pNtk );
else
Abc_NtkLevel( pNtk );
2005-08-07 17:01:00 +02:00
// check
2005-09-05 17:01:00 +02:00
if ( !Abc_NtkCheck( pNtk ) )
2005-08-07 17:01:00 +02:00
{
2005-08-17 17:01:00 +02:00
printf( "Abc_NtkRewrite: The network check has failed.\n" );
2005-08-07 17:01:00 +02:00
return 0;
}
return 1;
}
2005-08-27 17:01:00 +02:00
/**Function*************************************************************
Synopsis [Starts the cut manager for rewriting.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
2008-01-31 05:01:00 +01:00
Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk )
2005-08-27 17:01:00 +02:00
{
static Cut_Params_t Params, * pParams = &Params;
Cut_Man_t * pManCut;
Abc_Obj_t * pObj;
int i;
// start the cut manager
memset( pParams, 0, sizeof(Cut_Params_t) );
pParams->nVarsMax = 4; // the max cut size ("k" of the k-feasible cuts)
pParams->nKeepMax = 250; // the max number of cuts kept at a node
pParams->fTruth = 1; // compute truth tables
2008-01-31 05:01:00 +01:00
pParams->fFilter = 1; // filter dominated cuts
2005-08-27 17:01:00 +02:00
pParams->fSeq = 0; // compute sequential cuts
2008-01-31 05:01:00 +01:00
pParams->fDrop = 0; // drop cuts on the fly
2005-08-27 17:01:00 +02:00
pParams->fVerbose = 0; // the verbosiness flag
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
pManCut = Cut_ManStart( pParams );
if ( pParams->fDrop )
Cut_ManSetFanoutCounts( pManCut, Abc_NtkFanoutCounts(pNtk) );
// set cuts for PIs
Abc_NtkForEachCi( pNtk, pObj, i )
if ( Abc_ObjFanoutNum(pObj) > 0 )
Cut_NodeSetTriv( pManCut, pObj->Id );
return pManCut;
}
/**Function*************************************************************
Synopsis [Prints the cuts at the nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NodePrintCuts( Abc_Obj_t * pNode )
{
2008-01-31 05:01:00 +01:00
Vec_Ptr_t * vCuts;
2005-08-27 17:01:00 +02:00
Cut_Cut_t * pCut;
2008-01-31 05:01:00 +01:00
int k;
2005-08-27 17:01:00 +02:00
printf( "\nNode %s\n", Abc_ObjName(pNode) );
2008-01-31 05:01:00 +01:00
vCuts = (Vec_Ptr_t *)pNode->pCopy;
2010-11-01 09:35:04 +01:00
Vec_PtrForEachEntry( Cut_Cut_t *, vCuts, pCut, k )
2005-08-27 17:01:00 +02:00
{
2008-01-31 05:01:00 +01:00
Extra_PrintBinary( stdout, (unsigned *)&pCut->uSign, 16 );
2005-08-27 17:01:00 +02:00
printf( " " );
2008-01-31 05:01:00 +01:00
Cut_CutPrint( pCut, 0 );
2005-08-27 17:01:00 +02:00
printf( "\n" );
}
}
2008-01-31 05:01:00 +01:00
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ManRewritePrintDivs( Vec_Ptr_t * vDivs, int nLeaves )
{
Abc_Obj_t * pFanin, * pNode, * pRoot;
int i, k;
2010-11-01 09:35:04 +01:00
pRoot = (Abc_Obj_t *)Vec_PtrEntryLast(vDivs);
2008-01-31 05:01:00 +01:00
// print the nodes
2010-11-01 09:35:04 +01:00
Vec_PtrForEachEntry( Abc_Obj_t *, vDivs, pNode, i )
2008-01-31 05:01:00 +01:00
{
if ( i < nLeaves )
{
printf( "%6d : %c\n", pNode->Id, 'a'+i );
continue;
}
printf( "%6d : %2d = ", pNode->Id, i );
// find the first fanin
2010-11-01 09:35:04 +01:00
Vec_PtrForEachEntry( Abc_Obj_t *, vDivs, pFanin, k )
2008-01-31 05:01:00 +01:00
if ( Abc_ObjFanin0(pNode) == pFanin )
break;
if ( k < nLeaves )
printf( "%c", 'a' + k );
else
printf( "%d", k );
printf( "%s ", Abc_ObjFaninC0(pNode)? "\'" : "" );
// find the second fanin
2010-11-01 09:35:04 +01:00
Vec_PtrForEachEntry( Abc_Obj_t *, vDivs, pFanin, k )
2008-01-31 05:01:00 +01:00
if ( Abc_ObjFanin1(pNode) == pFanin )
break;
if ( k < nLeaves )
printf( "%c", 'a' + k );
else
printf( "%d", k );
printf( "%s ", Abc_ObjFaninC1(pNode)? "\'" : "" );
if ( pNode == pRoot )
printf( " root" );
printf( "\n" );
}
printf( "\n" );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ManShowCutCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vDivs )
{
if ( Abc_NodeIsTravIdCurrent(pNode) )
return;
Abc_NodeSetTravIdCurrent(pNode);
Abc_ManShowCutCone_rec( Abc_ObjFanin0(pNode), vDivs );
Abc_ManShowCutCone_rec( Abc_ObjFanin1(pNode), vDivs );
Vec_PtrPush( vDivs, pNode );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ManShowCutCone( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves )
{
Abc_Ntk_t * pNtk = pNode->pNtk;
Abc_Obj_t * pObj;
Vec_Ptr_t * vDivs;
int i;
vDivs = Vec_PtrAlloc( 100 );
Abc_NtkIncrementTravId( pNtk );
2010-11-01 09:35:04 +01:00
Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pObj, i )
2008-01-31 05:01:00 +01:00
{
Abc_NodeSetTravIdCurrent( Abc_ObjRegular(pObj) );
Vec_PtrPush( vDivs, Abc_ObjRegular(pObj) );
}
Abc_ManShowCutCone_rec( pNode, vDivs );
Abc_ManRewritePrintDivs( vDivs, Vec_PtrSize(vLeaves) );
Vec_PtrFree( vDivs );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_RwrExpWithCut_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, int fUseA )
{
if ( Vec_PtrFind(vLeaves, pNode) >= 0 || Vec_PtrFind(vLeaves, Abc_ObjNot(pNode)) >= 0 )
{
if ( fUseA )
Abc_ObjRegular(pNode)->fMarkA = 1;
else
Abc_ObjRegular(pNode)->fMarkB = 1;
return;
}
assert( Abc_ObjIsNode(pNode) );
Abc_RwrExpWithCut_rec( Abc_ObjFanin0(pNode), vLeaves, fUseA );
Abc_RwrExpWithCut_rec( Abc_ObjFanin1(pNode), vLeaves, fUseA );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_RwrExpWithCut( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves )
{
Abc_Obj_t * pObj;
int i, CountA, CountB;
Abc_RwrExpWithCut_rec( Abc_ObjFanin0(pNode), vLeaves, 1 );
Abc_RwrExpWithCut_rec( Abc_ObjFanin1(pNode), vLeaves, 0 );
CountA = CountB = 0;
2010-11-01 09:35:04 +01:00
Vec_PtrForEachEntry( Abc_Obj_t *, vLeaves, pObj, i )
2008-01-31 05:01:00 +01:00
{
CountA += Abc_ObjRegular(pObj)->fMarkA;
CountB += Abc_ObjRegular(pObj)->fMarkB;
Abc_ObjRegular(pObj)->fMarkA = 0;
Abc_ObjRegular(pObj)->fMarkB = 0;
}
printf( "(%d,%d:%d) ", CountA, CountB, CountA+CountB-Vec_PtrSize(vLeaves) );
}
2005-08-07 17:01:00 +02:00
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
2010-11-01 09:35:04 +01:00
ABC_NAMESPACE_IMPL_END