mirror of https://github.com/YosysHQ/abc.git
239 lines
7.3 KiB
C
239 lines
7.3 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [cnfUtil.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: cnfUtil.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, references, and nodes used in the mapping.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Aig_ManScanMapping_rec( Cnf_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vMapped )
|
|
{
|
|
Aig_Obj_t * pLeaf;
|
|
Dar_Cut_t * pCutBest;
|
|
int aArea, i;
|
|
if ( pObj->nRefs++ || Aig_ObjIsPi(pObj) || Aig_ObjIsConst1(pObj) )
|
|
return 0;
|
|
assert( Aig_ObjIsAnd(pObj) );
|
|
// collect the node first to derive pre-order
|
|
if ( vMapped )
|
|
Vec_PtrPush( vMapped, pObj );
|
|
// visit the transitive fanin of the selected cut
|
|
if ( pObj->fMarkB )
|
|
{
|
|
Vec_Ptr_t * vSuper = Vec_PtrAlloc( 100 );
|
|
Aig_ObjCollectSuper( pObj, vSuper );
|
|
aArea = Vec_PtrSize(vSuper) + 1;
|
|
Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pLeaf, i )
|
|
aArea += Aig_ManScanMapping_rec( p, Aig_Regular(pLeaf), vMapped );
|
|
Vec_PtrFree( vSuper );
|
|
////////////////////////////
|
|
pObj->fMarkB = 1;
|
|
}
|
|
else
|
|
{
|
|
pCutBest = Dar_ObjBestCut( pObj );
|
|
aArea = Cnf_CutSopCost( p, pCutBest );
|
|
Dar_CutForEachLeaf( p->pManAig, pCutBest, pLeaf, i )
|
|
aArea += Aig_ManScanMapping_rec( p, pLeaf, vMapped );
|
|
}
|
|
return aArea;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes area, references, and nodes used in the mapping.]
|
|
|
|
Description [Collects the nodes in reverse topological order.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Vec_Ptr_t * Aig_ManScanMapping( Cnf_Man_t * p, int fCollect )
|
|
{
|
|
Vec_Ptr_t * vMapped = NULL;
|
|
Aig_Obj_t * pObj;
|
|
int i;
|
|
// clean all references
|
|
Aig_ManForEachObj( p->pManAig, pObj, i )
|
|
pObj->nRefs = 0;
|
|
// allocate the array
|
|
if ( fCollect )
|
|
vMapped = Vec_PtrAlloc( 1000 );
|
|
// collect nodes reachable from POs in the DFS order through the best cuts
|
|
p->aArea = 0;
|
|
Aig_ManForEachPo( p->pManAig, pObj, i )
|
|
p->aArea += Aig_ManScanMapping_rec( p, Aig_ObjFanin0(pObj), vMapped );
|
|
// printf( "Variables = %6d. Clauses = %8d.\n", vMapped? Vec_PtrSize(vMapped) + Aig_ManPiNum(p->pManAig) + 1 : 0, p->aArea + 2 );
|
|
return vMapped;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes area, references, and nodes used in the mapping.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Cnf_ManScanMapping_rec( Cnf_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vMapped, int fPreorder )
|
|
{
|
|
Aig_Obj_t * pLeaf;
|
|
Cnf_Cut_t * pCutBest;
|
|
int aArea, i;
|
|
if ( pObj->nRefs++ || Aig_ObjIsPi(pObj) || Aig_ObjIsConst1(pObj) )
|
|
return 0;
|
|
assert( Aig_ObjIsAnd(pObj) );
|
|
assert( pObj->pData != NULL );
|
|
// add the node to the mapping
|
|
if ( vMapped && fPreorder )
|
|
Vec_PtrPush( vMapped, pObj );
|
|
// visit the transitive fanin of the selected cut
|
|
if ( pObj->fMarkB )
|
|
{
|
|
Vec_Ptr_t * vSuper = Vec_PtrAlloc( 100 );
|
|
Aig_ObjCollectSuper( pObj, vSuper );
|
|
aArea = Vec_PtrSize(vSuper) + 1;
|
|
Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pLeaf, i )
|
|
aArea += Cnf_ManScanMapping_rec( p, Aig_Regular(pLeaf), vMapped, fPreorder );
|
|
Vec_PtrFree( vSuper );
|
|
////////////////////////////
|
|
pObj->fMarkB = 1;
|
|
}
|
|
else
|
|
{
|
|
pCutBest = (Cnf_Cut_t *)pObj->pData;
|
|
// assert( pCutBest->nFanins > 0 );
|
|
assert( pCutBest->Cost < 127 );
|
|
aArea = pCutBest->Cost;
|
|
Cnf_CutForEachLeaf( p->pManAig, pCutBest, pLeaf, i )
|
|
aArea += Cnf_ManScanMapping_rec( p, pLeaf, vMapped, fPreorder );
|
|
}
|
|
// add the node to the mapping
|
|
if ( vMapped && !fPreorder )
|
|
Vec_PtrPush( vMapped, pObj );
|
|
return aArea;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes area, references, and nodes used in the mapping.]
|
|
|
|
Description [Collects the nodes in reverse topological order.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Vec_Ptr_t * Cnf_ManScanMapping( Cnf_Man_t * p, int fCollect, int fPreorder )
|
|
{
|
|
Vec_Ptr_t * vMapped = NULL;
|
|
Aig_Obj_t * pObj;
|
|
int i;
|
|
// clean all references
|
|
Aig_ManForEachObj( p->pManAig, pObj, i )
|
|
pObj->nRefs = 0;
|
|
// allocate the array
|
|
if ( fCollect )
|
|
vMapped = Vec_PtrAlloc( 1000 );
|
|
// collect nodes reachable from POs in the DFS order through the best cuts
|
|
p->aArea = 0;
|
|
Aig_ManForEachPo( p->pManAig, pObj, i )
|
|
p->aArea += Cnf_ManScanMapping_rec( p, Aig_ObjFanin0(pObj), vMapped, fPreorder );
|
|
// printf( "Variables = %6d. Clauses = %8d.\n", vMapped? Vec_PtrSize(vMapped) + Aig_ManPiNum(p->pManAig) + 1 : 0, p->aArea + 2 );
|
|
return vMapped;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the array of CI IDs.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Vec_Int_t * Cnf_DataCollectCiSatNums( Cnf_Dat_t * pCnf, Aig_Man_t * p )
|
|
{
|
|
Vec_Int_t * vCiIds;
|
|
Aig_Obj_t * pObj;
|
|
int i;
|
|
vCiIds = Vec_IntAlloc( Aig_ManPiNum(p) );
|
|
Aig_ManForEachPi( p, pObj, i )
|
|
Vec_IntPush( vCiIds, pCnf->pVarNums[pObj->Id] );
|
|
return vCiIds;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the array of CI IDs.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Vec_Int_t * Cnf_DataCollectCoSatNums( Cnf_Dat_t * pCnf, Aig_Man_t * p )
|
|
{
|
|
Vec_Int_t * vCoIds;
|
|
Aig_Obj_t * pObj;
|
|
int i;
|
|
vCoIds = Vec_IntAlloc( Aig_ManPoNum(p) );
|
|
Aig_ManForEachPo( p, pObj, i )
|
|
Vec_IntPush( vCoIds, pCnf->pVarNums[pObj->Id] );
|
|
return vCoIds;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|