/**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