2007-04-28 17:01:00 +02:00
|
|
|
/**CFile****************************************************************
|
|
|
|
|
|
|
|
|
|
FileName [darCore.c]
|
|
|
|
|
|
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
|
|
|
|
|
|
PackageName [DAG-aware AIG rewriting.]
|
|
|
|
|
|
|
|
|
|
Synopsis [Core of the rewriting package.]
|
|
|
|
|
|
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
|
|
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
|
|
|
|
|
|
Date [Ver. 1.0. Started - April 28, 2007.]
|
|
|
|
|
|
|
|
|
|
Revision [$Id: darCore.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
2007-07-12 17:01:00 +02:00
|
|
|
#include "darInt.h"
|
2007-04-28 17:01:00 +02:00
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// DECLARATIONS ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// FUNCTION DEFINITIONS ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2007-07-12 17:01:00 +02:00
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Returns the structure with default assignment of parameters.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
2007-07-23 17:01:00 +02:00
|
|
|
void Dar_ManDefaultRwrParams( Dar_RwrPar_t * pPars )
|
2007-07-12 17:01:00 +02:00
|
|
|
{
|
2007-07-23 17:01:00 +02:00
|
|
|
memset( pPars, 0, sizeof(Dar_RwrPar_t) );
|
2007-07-31 17:01:00 +02:00
|
|
|
pPars->nCutsMax = 8; // 8
|
2007-07-23 17:01:00 +02:00
|
|
|
pPars->nSubgMax = 5; // 5 is a "magic number"
|
2007-07-26 17:01:00 +02:00
|
|
|
pPars->fFanout = 1;
|
2007-07-23 17:01:00 +02:00
|
|
|
pPars->fUpdateLevel = 0;
|
|
|
|
|
pPars->fUseZeros = 0;
|
|
|
|
|
pPars->fVerbose = 0;
|
|
|
|
|
pPars->fVeryVerbose = 0;
|
2007-07-12 17:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
2007-04-28 17:01:00 +02:00
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis []
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
2007-07-23 17:01:00 +02:00
|
|
|
int Dar_ManRewrite( Aig_Man_t * pAig, Dar_RwrPar_t * pPars )
|
2007-04-28 17:01:00 +02:00
|
|
|
{
|
2007-07-12 17:01:00 +02:00
|
|
|
Dar_Man_t * p;
|
2007-09-06 17:01:00 +02:00
|
|
|
Bar_Progress_t * pProgress;
|
2007-07-12 17:01:00 +02:00
|
|
|
Dar_Cut_t * pCut;
|
|
|
|
|
Aig_Obj_t * pObj, * pObjNew;
|
2007-04-28 17:01:00 +02:00
|
|
|
int i, k, nNodesOld, nNodeBefore, nNodeAfter, Required;
|
2007-06-24 17:01:00 +02:00
|
|
|
int clk = 0, clkStart;
|
2007-07-14 17:01:00 +02:00
|
|
|
// prepare the library
|
|
|
|
|
Dar_LibPrepare( pPars->nSubgMax );
|
2007-07-12 17:01:00 +02:00
|
|
|
// create rewriting manager
|
|
|
|
|
p = Dar_ManStart( pAig, pPars );
|
2007-04-28 17:01:00 +02:00
|
|
|
// remove dangling nodes
|
2007-07-12 17:01:00 +02:00
|
|
|
Aig_ManCleanup( pAig );
|
2007-07-14 17:01:00 +02:00
|
|
|
// if updating levels is requested, start fanout and timing
|
2007-07-26 17:01:00 +02:00
|
|
|
if ( p->pPars->fFanout )
|
|
|
|
|
Aig_ManFanoutStart( pAig );
|
2007-07-14 17:01:00 +02:00
|
|
|
if ( p->pPars->fUpdateLevel )
|
|
|
|
|
Aig_ManStartReverseLevels( pAig, 0 );
|
2007-04-28 17:01:00 +02:00
|
|
|
// set elementary cuts for the PIs
|
2007-07-14 17:01:00 +02:00
|
|
|
Dar_ManCutsStart( p );
|
2007-04-28 17:01:00 +02:00
|
|
|
// resynthesize each node once
|
2007-06-24 17:01:00 +02:00
|
|
|
clkStart = clock();
|
2007-07-12 17:01:00 +02:00
|
|
|
p->nNodesInit = Aig_ManNodeNum(pAig);
|
|
|
|
|
nNodesOld = Vec_PtrSize( pAig->vObjs );
|
2007-07-26 17:01:00 +02:00
|
|
|
|
2007-09-06 17:01:00 +02:00
|
|
|
pProgress = Bar_ProgressStart( stdout, nNodesOld );
|
2007-07-12 17:01:00 +02:00
|
|
|
Aig_ManForEachObj( pAig, pObj, i )
|
2007-09-06 17:01:00 +02:00
|
|
|
// pProgress = Bar_ProgressStart( stdout, 100 );
|
2007-07-26 17:01:00 +02:00
|
|
|
// Aig_ManOrderStart( pAig );
|
|
|
|
|
// Aig_ManForEachNodeInOrder( pAig, pObj )
|
2007-04-28 17:01:00 +02:00
|
|
|
{
|
2007-09-06 17:01:00 +02:00
|
|
|
// Bar_ProgressUpdate( pProgress, 100*pAig->nAndPrev/pAig->nAndTotal, NULL );
|
2007-07-26 17:01:00 +02:00
|
|
|
|
2007-09-06 17:01:00 +02:00
|
|
|
Bar_ProgressUpdate( pProgress, i, NULL );
|
2007-07-12 17:01:00 +02:00
|
|
|
if ( !Aig_ObjIsNode(pObj) )
|
2007-04-28 17:01:00 +02:00
|
|
|
continue;
|
|
|
|
|
if ( i > nNodesOld )
|
|
|
|
|
break;
|
2007-07-26 17:01:00 +02:00
|
|
|
|
2007-07-14 17:01:00 +02:00
|
|
|
// consider freeing the cuts
|
|
|
|
|
// if ( (i & 0xFFF) == 0 && Aig_MmFixedReadMemUsage(p->pMemCuts)/(1<<20) > 100 )
|
|
|
|
|
// Dar_ManCutsStart( p );
|
|
|
|
|
|
2007-04-28 17:01:00 +02:00
|
|
|
// compute cuts for the node
|
2007-07-26 17:01:00 +02:00
|
|
|
p->nNodesTried++;
|
2007-06-24 17:01:00 +02:00
|
|
|
clk = clock();
|
2007-07-12 17:01:00 +02:00
|
|
|
Dar_ObjComputeCuts_rec( p, pObj );
|
2007-06-24 17:01:00 +02:00
|
|
|
p->timeCuts += clock() - clk;
|
2007-07-12 17:01:00 +02:00
|
|
|
|
|
|
|
|
// check if there is a trivial cut
|
|
|
|
|
Dar_ObjForEachCut( pObj, pCut, k )
|
2007-07-14 17:01:00 +02:00
|
|
|
if ( pCut->nLeaves == 0 || (pCut->nLeaves == 1 && pCut->pLeaves[0] != pObj->Id && Aig_ManObj(p->pAig, pCut->pLeaves[0])) )
|
2007-07-12 17:01:00 +02:00
|
|
|
break;
|
|
|
|
|
if ( k < (int)pObj->nCuts )
|
2007-06-24 17:01:00 +02:00
|
|
|
{
|
2007-07-12 17:01:00 +02:00
|
|
|
assert( pCut->nLeaves < 2 );
|
|
|
|
|
if ( pCut->nLeaves == 0 ) // replace by constant
|
2007-06-24 17:01:00 +02:00
|
|
|
{
|
2007-07-12 17:01:00 +02:00
|
|
|
assert( pCut->uTruth == 0 || pCut->uTruth == 0xFFFF );
|
|
|
|
|
pObjNew = Aig_NotCond( Aig_ManConst1(p->pAig), pCut->uTruth==0 );
|
2007-06-24 17:01:00 +02:00
|
|
|
}
|
2007-07-12 17:01:00 +02:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
assert( pCut->uTruth == 0xAAAA || pCut->uTruth == 0x5555 );
|
|
|
|
|
pObjNew = Aig_NotCond( Aig_ManObj(p->pAig, pCut->pLeaves[0]), pCut->uTruth==0x5555 );
|
|
|
|
|
}
|
|
|
|
|
// remove the old cuts
|
|
|
|
|
Dar_ObjSetCuts( pObj, NULL );
|
2007-07-14 17:01:00 +02:00
|
|
|
// replace the node
|
|
|
|
|
Aig_ObjReplace( pAig, pObj, pObjNew, 1, p->pPars->fUpdateLevel );
|
2007-07-12 17:01:00 +02:00
|
|
|
continue;
|
2007-06-24 17:01:00 +02:00
|
|
|
}
|
2007-07-12 17:01:00 +02:00
|
|
|
|
|
|
|
|
// evaluate the cuts
|
|
|
|
|
p->GainBest = -1;
|
2007-07-23 17:01:00 +02:00
|
|
|
Required = pAig->vLevelR? Aig_ObjRequiredLevel(pAig, pObj) : AIG_INFINITY;
|
2007-07-12 17:01:00 +02:00
|
|
|
Dar_ObjForEachCut( pObj, pCut, k )
|
|
|
|
|
Dar_LibEval( p, pObj, pCut, Required );
|
2007-04-28 17:01:00 +02:00
|
|
|
// check the best gain
|
2007-07-14 17:01:00 +02:00
|
|
|
if ( !(p->GainBest > 0 || (p->GainBest == 0 && p->pPars->fUseZeros)) )
|
2007-07-26 17:01:00 +02:00
|
|
|
{
|
|
|
|
|
// Aig_ObjOrderAdvance( pAig );
|
2007-04-28 17:01:00 +02:00
|
|
|
continue;
|
2007-07-26 17:01:00 +02:00
|
|
|
}
|
2007-07-14 17:01:00 +02:00
|
|
|
// remove the old cuts
|
|
|
|
|
Dar_ObjSetCuts( pObj, NULL );
|
2007-04-28 17:01:00 +02:00
|
|
|
// if we end up here, a rewriting step is accepted
|
2007-07-12 17:01:00 +02:00
|
|
|
nNodeBefore = Aig_ManNodeNum( pAig );
|
2007-07-31 17:01:00 +02:00
|
|
|
pObjNew = Dar_LibBuildBest( p ); // pObjNew can be complemented!
|
|
|
|
|
pObjNew = Aig_NotCond( pObjNew, Aig_ObjPhaseReal(pObjNew) ^ pObj->fPhase );
|
2007-07-12 17:01:00 +02:00
|
|
|
assert( (int)Aig_Regular(pObjNew)->Level <= Required );
|
2007-06-24 17:01:00 +02:00
|
|
|
// replace the node
|
2007-07-14 17:01:00 +02:00
|
|
|
Aig_ObjReplace( pAig, pObj, pObjNew, 1, p->pPars->fUpdateLevel );
|
2007-04-28 17:01:00 +02:00
|
|
|
// compare the gains
|
2007-07-12 17:01:00 +02:00
|
|
|
nNodeAfter = Aig_ManNodeNum( pAig );
|
2007-06-24 17:01:00 +02:00
|
|
|
assert( p->GainBest <= nNodeBefore - nNodeAfter );
|
|
|
|
|
// count gains of this class
|
|
|
|
|
p->ClassGains[p->ClassBest] += nNodeBefore - nNodeAfter;
|
2007-04-28 17:01:00 +02:00
|
|
|
}
|
2007-07-26 17:01:00 +02:00
|
|
|
// Aig_ManOrderStop( pAig );
|
|
|
|
|
|
2007-06-24 17:01:00 +02:00
|
|
|
p->timeTotal = clock() - clkStart;
|
|
|
|
|
p->timeOther = p->timeTotal - p->timeCuts - p->timeEval;
|
|
|
|
|
|
2007-09-06 17:01:00 +02:00
|
|
|
Bar_ProgressStop( pProgress );
|
2007-07-12 17:01:00 +02:00
|
|
|
p->nCutMemUsed = Aig_MmFixedReadMemUsage(p->pMemCuts)/(1<<20);
|
2007-04-28 17:01:00 +02:00
|
|
|
Dar_ManCutsFree( p );
|
|
|
|
|
// put the nodes into the DFS order and reassign their IDs
|
2007-07-12 17:01:00 +02:00
|
|
|
// Aig_NtkReassignIds( p );
|
2007-04-28 17:01:00 +02:00
|
|
|
// fix the levels
|
2007-07-26 17:01:00 +02:00
|
|
|
// Aig_ManVerifyLevel( pAig );
|
|
|
|
|
if ( p->pPars->fFanout )
|
|
|
|
|
Aig_ManFanoutStop( pAig );
|
2007-07-14 17:01:00 +02:00
|
|
|
if ( p->pPars->fUpdateLevel )
|
2007-07-26 17:01:00 +02:00
|
|
|
{
|
|
|
|
|
// Aig_ManVerifyReverseLevel( pAig );
|
2007-07-14 17:01:00 +02:00
|
|
|
Aig_ManStopReverseLevels( pAig );
|
2007-07-26 17:01:00 +02:00
|
|
|
}
|
2007-07-14 17:01:00 +02:00
|
|
|
// stop the rewriting manager
|
|
|
|
|
Dar_ManStop( p );
|
2007-07-31 17:01:00 +02:00
|
|
|
Aig_ManCheckPhase( pAig );
|
2007-04-28 17:01:00 +02:00
|
|
|
// check
|
2007-07-12 17:01:00 +02:00
|
|
|
if ( !Aig_ManCheck( pAig ) )
|
2007-04-28 17:01:00 +02:00
|
|
|
{
|
2007-07-12 17:01:00 +02:00
|
|
|
printf( "Aig_ManRewrite: The network check has failed.\n" );
|
2007-04-28 17:01:00 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2007-06-24 17:01:00 +02:00
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis []
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
2007-07-26 17:01:00 +02:00
|
|
|
Aig_MmFixed_t * Dar_ManComputeCuts( Aig_Man_t * pAig, int nCutsMax )
|
2007-06-24 17:01:00 +02:00
|
|
|
{
|
2007-07-12 17:01:00 +02:00
|
|
|
Dar_Man_t * p;
|
2007-07-26 17:01:00 +02:00
|
|
|
Dar_RwrPar_t Pars, * pPars = &Pars;
|
2007-07-12 17:01:00 +02:00
|
|
|
Aig_Obj_t * pObj;
|
|
|
|
|
Aig_MmFixed_t * pMemCuts;
|
2007-07-31 17:01:00 +02:00
|
|
|
int i, nNodes, clk = 0, clkStart = clock();
|
2007-06-24 17:01:00 +02:00
|
|
|
// remove dangling nodes
|
2007-07-31 17:01:00 +02:00
|
|
|
if ( nNodes = Aig_ManCleanup( pAig ) )
|
|
|
|
|
{
|
|
|
|
|
// printf( "Removing %d nodes.\n", nNodes );
|
|
|
|
|
}
|
2007-07-26 17:01:00 +02:00
|
|
|
// create default parameters
|
|
|
|
|
Dar_ManDefaultRwrParams( pPars );
|
|
|
|
|
pPars->nCutsMax = nCutsMax;
|
|
|
|
|
// create rewriting manager
|
|
|
|
|
p = Dar_ManStart( pAig, pPars );
|
2007-06-24 17:01:00 +02:00
|
|
|
// set elementary cuts for the PIs
|
2007-07-14 17:01:00 +02:00
|
|
|
Dar_ManCutsStart( p );
|
2007-06-24 17:01:00 +02:00
|
|
|
// compute cuts for each nodes in the topological order
|
2007-07-26 17:01:00 +02:00
|
|
|
Aig_ManForEachNode( pAig, pObj, i )
|
2007-06-24 17:01:00 +02:00
|
|
|
Dar_ObjComputeCuts( p, pObj );
|
|
|
|
|
// free the cuts
|
2007-07-12 17:01:00 +02:00
|
|
|
pMemCuts = p->pMemCuts;
|
|
|
|
|
p->pMemCuts = NULL;
|
2007-06-24 17:01:00 +02:00
|
|
|
// Dar_ManCutsFree( p );
|
2007-07-12 17:01:00 +02:00
|
|
|
// stop the rewriting manager
|
|
|
|
|
Dar_ManStop( p );
|
|
|
|
|
return pMemCuts;
|
2007-06-24 17:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
2007-06-08 17:01:00 +02:00
|
|
|
|
|
|
|
|
|
2007-04-28 17:01:00 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// END OF FILE ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|