blob: a6345471720f74b2b771ac1d0fc8beb36f79cf2a [file] [log] [blame]
/**CFile****************************************************************
FileName [cnfMap.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [AIG-to-CNF conversion.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: cnfMap.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "cnf.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes area flow of the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cnf_CutAssignAreaFlow( Cnf_Man_t * p, Dar_Cut_t * pCut, int * pAreaFlows )
{
Aig_Obj_t * pLeaf;
int i;
pCut->Value = 0;
// pCut->uSign = 100 * Cnf_CutSopCost( p, pCut );
pCut->uSign = 10 * Cnf_CutSopCost( p, pCut );
Dar_CutForEachLeaf( p->pManAig, pCut, pLeaf, i )
{
pCut->Value += pLeaf->nRefs;
if ( !Aig_ObjIsNode(pLeaf) )
continue;
assert( pLeaf->nRefs > 0 );
pCut->uSign += pAreaFlows[pLeaf->Id] / (pLeaf->nRefs? pLeaf->nRefs : 1);
}
}
/**Function*************************************************************
Synopsis [Computes area flow of the supergate.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Cnf_CutSuperAreaFlow( Vec_Ptr_t * vSuper, int * pAreaFlows )
{
Aig_Obj_t * pLeaf;
int i, nAreaFlow;
nAreaFlow = 100 * (Vec_PtrSize(vSuper) + 1);
Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pLeaf, i )
{
pLeaf = Aig_Regular(pLeaf);
if ( !Aig_ObjIsNode(pLeaf) )
continue;
assert( pLeaf->nRefs > 0 );
nAreaFlow += pAreaFlows[pLeaf->Id] / (pLeaf->nRefs? pLeaf->nRefs : 1);
}
return nAreaFlow;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cnf_DeriveMapping( Cnf_Man_t * p )
{
Vec_Ptr_t * vSuper;
Aig_Obj_t * pObj;
Dar_Cut_t * pCut, * pCutBest;
int i, k, AreaFlow, * pAreaFlows;
// allocate area flows
pAreaFlows = ABC_ALLOC( int, Aig_ManObjNumMax(p->pManAig) );
memset( pAreaFlows, 0, sizeof(int) * Aig_ManObjNumMax(p->pManAig) );
// visit the nodes in the topological order and update their best cuts
vSuper = Vec_PtrAlloc( 100 );
Aig_ManForEachNode( p->pManAig, pObj, i )
{
// go through the cuts
pCutBest = NULL;
Dar_ObjForEachCut( pObj, pCut, k )
{
pCut->fBest = 0;
if ( k == 0 )
continue;
Cnf_CutAssignAreaFlow( p, pCut, pAreaFlows );
if ( pCutBest == NULL || pCutBest->uSign > pCut->uSign ||
(pCutBest->uSign == pCut->uSign && pCutBest->Value < pCut->Value) )
pCutBest = pCut;
}
// check the big cut
// Aig_ObjCollectSuper( pObj, vSuper );
// get the area flow of this cut
// AreaFlow = Cnf_CutSuperAreaFlow( vSuper, pAreaFlows );
AreaFlow = ABC_INFINITY;
if ( AreaFlow >= (int)pCutBest->uSign )
{
pAreaFlows[pObj->Id] = pCutBest->uSign;
pCutBest->fBest = 1;
}
else
{
pAreaFlows[pObj->Id] = AreaFlow;
pObj->fMarkB = 1; // mark the special node
}
}
Vec_PtrFree( vSuper );
ABC_FREE( pAreaFlows );
/*
// compute the area of mapping
AreaFlow = 0;
Aig_ManForEachCo( p->pManAig, pObj, i )
AreaFlow += Dar_ObjBestCut(Aig_ObjFanin0(pObj))->uSign / 100 / Aig_ObjFanin0(pObj)->nRefs;
printf( "Area of the network = %d.\n", AreaFlow );
*/
}
#if 0
/**Function*************************************************************
Synopsis [Computes area of the first level.]
Description [The cut need to be derefed.]
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_CutDeref( Aig_Man_t * p, Dar_Cut_t * pCut )
{
Aig_Obj_t * pLeaf;
int i;
Dar_CutForEachLeaf( p, pCut, pLeaf, i )
{
assert( pLeaf->nRefs > 0 );
if ( --pLeaf->nRefs > 0 || !Aig_ObjIsAnd(pLeaf) )
continue;
Aig_CutDeref( p, Aig_ObjBestCut(pLeaf) );
}
}
/**Function*************************************************************
Synopsis [Computes area of the first level.]
Description [The cut need to be derefed.]
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_CutRef( Aig_Man_t * p, Dar_Cut_t * pCut )
{
Aig_Obj_t * pLeaf;
int i, Area = pCut->Value;
Dar_CutForEachLeaf( p, pCut, pLeaf, i )
{
assert( pLeaf->nRefs >= 0 );
if ( pLeaf->nRefs++ > 0 || !Aig_ObjIsAnd(pLeaf) )
continue;
Area += Aig_CutRef( p, Aig_ObjBestCut(pLeaf) );
}
return Area;
}
/**Function*************************************************************
Synopsis [Computes exact area of the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Cnf_CutArea( Aig_Man_t * p, Dar_Cut_t * pCut )
{
int Area;
Area = Aig_CutRef( p, pCut );
Aig_CutDeref( p, pCut );
return Area;
}
/**Function*************************************************************
Synopsis [Returns 1 if the second cut is better.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Cnf_CutCompare( Dar_Cut_t * pC0, Dar_Cut_t * pC1 )
{
if ( pC0->Area < pC1->Area - 0.0001 )
return -1;
if ( pC0->Area > pC1->Area + 0.0001 ) // smaller area flow is better
return 1;
// if ( pC0->NoRefs < pC1->NoRefs )
// return -1;
// if ( pC0->NoRefs > pC1->NoRefs ) // fewer non-referenced fanins is better
// return 1;
// if ( pC0->FanRefs / pC0->nLeaves > pC1->FanRefs / pC1->nLeaves )
// return -1;
// if ( pC0->FanRefs / pC0->nLeaves < pC1->FanRefs / pC1->nLeaves )
// return 1; // larger average fanin ref-counter is better
// return 0;
return 1;
}
/**Function*************************************************************
Synopsis [Returns the cut with the smallest area flow.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Cut_t * Cnf_ObjFindBestCut( Aig_Obj_t * pObj )
{
Dar_Cut_t * pCut, * pCutBest;
int i;
pCutBest = NULL;
Dar_ObjForEachCut( pObj, pCut, i )
if ( pCutBest == NULL || Cnf_CutCompare(pCutBest, pCut) == 1 )
pCutBest = pCut;
return pCutBest;
}
/**Function*************************************************************
Synopsis [Computes area flow of the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cnf_CutAssignArea( Cnf_Man_t * p, Dar_Cut_t * pCut )
{
Aig_Obj_t * pLeaf;
int i;
pCut->Area = (float)pCut->Cost;
pCut->NoRefs = 0;
pCut->FanRefs = 0;
Dar_CutForEachLeaf( p->pManAig, pCut, pLeaf, i )
{
if ( !Aig_ObjIsNode(pLeaf) )
continue;
if ( pLeaf->nRefs == 0 )
{
pCut->Area += Aig_ObjBestCut(pLeaf)->Cost;
pCut->NoRefs++;
}
else
{
if ( pCut->FanRefs + pLeaf->nRefs > 15 )
pCut->FanRefs = 15;
else
pCut->FanRefs += pLeaf->nRefs;
}
}
}
/**Function*************************************************************
Synopsis [Performs one round of "area recovery" using exact local area.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Cnf_ManMapForCnf( Cnf_Man_t * p )
{
Aig_Obj_t * pObj;
Dar_Cut_t * pCut, * pCutBest;
int i, k;
// visit the nodes in the topological order and update their best cuts
Aig_ManForEachNode( p->pManAig, pObj, i )
{
// find the old best cut
pCutBest = Aig_ObjBestCut(pObj);
Dar_ObjClearBestCut(pCutBest);
// if the node is used, dereference its cut
if ( pObj->nRefs )
Aig_CutDeref( p->pManAig, pCutBest );
// evaluate the cuts of this node
Dar_ObjForEachCut( pObj, pCut, k )
// Cnf_CutAssignAreaFlow( p, pCut );
pCut->Area = (float)Cnf_CutArea( p->pManAig, pCut );
// find the new best cut
pCutBest = Cnf_ObjFindBestCut(pObj);
Dar_ObjSetBestCut( pCutBest );
// if the node is used, reference its cut
if ( pObj->nRefs )
Aig_CutRef( p->pManAig, pCutBest );
}
return 1;
}
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END