| /**CFile**************************************************************** |
| |
| FileName [sfmNtk.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [SAT-based optimization using internal don't-cares.] |
| |
| Synopsis [Logic network.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: sfmNtk.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "sfmInt.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Sfm_CheckConsistency( Vec_Wec_t * vFanins, int nPis, int nPos, Vec_Str_t * vFixed ) |
| { |
| Vec_Int_t * vArray; |
| int i, k, Fanin; |
| // check entries |
| Vec_WecForEachLevel( vFanins, vArray, i ) |
| { |
| // PIs have no fanins |
| if ( i < nPis ) |
| assert( Vec_IntSize(vArray) == 0 && Vec_StrEntry(vFixed, i) == (char)0 ); |
| // nodes are in a topo order; POs cannot be fanins |
| Vec_IntForEachEntry( vArray, Fanin, k ) |
| // assert( Fanin < i && Fanin + nPos < Vec_WecSize(vFanins) ); |
| assert( Fanin + nPos < Vec_WecSize(vFanins) ); |
| // POs have one fanout |
| if ( i + nPos >= Vec_WecSize(vFanins) ) |
| assert( Vec_IntSize(vArray) == 1 && Vec_StrEntry(vFixed, i) == (char)0 ); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Sfm_CreateFanout( Vec_Wec_t * vFanins, Vec_Wec_t * vFanouts ) |
| { |
| Vec_Int_t * vArray; |
| int i, k, Fanin; |
| // count fanouts |
| Vec_WecInit( vFanouts, Vec_WecSize(vFanins) ); |
| Vec_WecForEachLevel( vFanins, vArray, i ) |
| Vec_IntForEachEntry( vArray, Fanin, k ) |
| Vec_WecEntry( vFanouts, Fanin )->nSize++; |
| // allocate fanins |
| Vec_WecForEachLevel( vFanouts, vArray, i ) |
| { |
| k = vArray->nSize; vArray->nSize = 0; |
| Vec_IntGrow( vArray, k ); |
| } |
| // add fanouts |
| Vec_WecForEachLevel( vFanins, vArray, i ) |
| Vec_IntForEachEntry( vArray, Fanin, k ) |
| Vec_IntPush( Vec_WecEntry( vFanouts, Fanin ), i ); |
| // verify |
| Vec_WecForEachLevel( vFanouts, vArray, i ) |
| assert( Vec_IntSize(vArray) == Vec_IntCap(vArray) ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline int Sfm_ObjLevelNew( Vec_Int_t * vArray, Vec_Int_t * vLevels, int fAddLevel ) |
| { |
| int k, Fanin, Level = 0; |
| Vec_IntForEachEntry( vArray, Fanin, k ) |
| Level = Abc_MaxInt( Level, Vec_IntEntry(vLevels, Fanin) ); |
| return Level + fAddLevel; |
| } |
| void Sfm_CreateLevel( Vec_Wec_t * vFanins, Vec_Int_t * vLevels, Vec_Str_t * vEmpty ) |
| { |
| Vec_Int_t * vArray; |
| int i; |
| assert( Vec_IntSize(vLevels) == 0 ); |
| Vec_IntFill( vLevels, Vec_WecSize(vFanins), 0 ); |
| Vec_WecForEachLevel( vFanins, vArray, i ) |
| Vec_IntWriteEntry( vLevels, i, Sfm_ObjLevelNew(vArray, vLevels, Sfm_ObjAddsLevelArray(vEmpty, i)) ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline int Sfm_ObjLevelNewR( Vec_Int_t * vArray, Vec_Int_t * vLevelsR, int fAddLevel ) |
| { |
| int k, Fanout, LevelR = 0; |
| Vec_IntForEachEntry( vArray, Fanout, k ) |
| LevelR = Abc_MaxInt( LevelR, Vec_IntEntry(vLevelsR, Fanout) ); |
| return LevelR + fAddLevel; |
| } |
| void Sfm_CreateLevelR( Vec_Wec_t * vFanouts, Vec_Int_t * vLevelsR, Vec_Str_t * vEmpty ) |
| { |
| Vec_Int_t * vArray; |
| int i; |
| assert( Vec_IntSize(vLevelsR) == 0 ); |
| Vec_IntFill( vLevelsR, Vec_WecSize(vFanouts), 0 ); |
| Vec_WecForEachLevelReverse( vFanouts, vArray, i ) |
| Vec_IntWriteEntry( vLevelsR, i, Sfm_ObjLevelNewR(vArray, vLevelsR, Sfm_ObjAddsLevelArray(vEmpty, i)) ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Sfm_Ntk_t * Sfm_NtkConstruct( Vec_Wec_t * vFanins, int nPis, int nPos, Vec_Str_t * vFixed, Vec_Str_t * vEmpty, Vec_Wrd_t * vTruths ) |
| { |
| Sfm_Ntk_t * p; |
| Sfm_CheckConsistency( vFanins, nPis, nPos, vFixed ); |
| p = ABC_CALLOC( Sfm_Ntk_t, 1 ); |
| p->nObjs = Vec_WecSize( vFanins ); |
| p->nPis = nPis; |
| p->nPos = nPos; |
| p->nNodes = p->nObjs - p->nPis - p->nPos; |
| // user data |
| p->vFixed = vFixed; |
| p->vEmpty = vEmpty; |
| p->vTruths = vTruths; |
| p->vFanins = *vFanins; |
| ABC_FREE( vFanins ); |
| // attributes |
| Sfm_CreateFanout( &p->vFanins, &p->vFanouts ); |
| Sfm_CreateLevel( &p->vFanins, &p->vLevels, vEmpty ); |
| Sfm_CreateLevelR( &p->vFanouts, &p->vLevelsR, vEmpty ); |
| Vec_IntFill( &p->vCounts, p->nObjs, 0 ); |
| Vec_IntFill( &p->vTravIds, p->nObjs, 0 ); |
| Vec_IntFill( &p->vTravIds2, p->nObjs, 0 ); |
| Vec_IntFill( &p->vId2Var, 2*p->nObjs, -1 ); |
| Vec_IntFill( &p->vVar2Id, 2*p->nObjs, -1 ); |
| p->vCover = Vec_IntAlloc( 1 << 16 ); |
| p->vCnfs = Sfm_CreateCnf( p ); |
| return p; |
| } |
| void Sfm_NtkPrepare( Sfm_Ntk_t * p ) |
| { |
| p->nLevelMax = Vec_IntFindMax(&p->vLevels) + p->pPars->nGrowthLevel; |
| p->vNodes = Vec_IntAlloc( 1000 ); |
| p->vDivs = Vec_IntAlloc( 100 ); |
| p->vRoots = Vec_IntAlloc( 1000 ); |
| p->vTfo = Vec_IntAlloc( 1000 ); |
| p->vDivCexes = Vec_WrdStart( p->pPars->nWinSizeMax ); |
| p->vOrder = Vec_IntAlloc( 100 ); |
| p->vDivVars = Vec_IntAlloc( 100 ); |
| p->vDivIds = Vec_IntAlloc( 1000 ); |
| p->vLits = Vec_IntAlloc( 100 ); |
| p->vValues = Vec_IntAlloc( 100 ); |
| p->vClauses = Vec_WecAlloc( 100 ); |
| p->vFaninMap = Vec_IntAlloc( 10 ); |
| p->pSat = sat_solver_new(); |
| sat_solver_setnvars( p->pSat, p->pPars->nWinSizeMax ); |
| } |
| void Sfm_NtkFree( Sfm_Ntk_t * p ) |
| { |
| // user data |
| Vec_StrFree( p->vFixed ); |
| Vec_StrFreeP( &p->vEmpty ); |
| Vec_WrdFree( p->vTruths ); |
| Vec_WecErase( &p->vFanins ); |
| // attributes |
| Vec_WecErase( &p->vFanouts ); |
| ABC_FREE( p->vLevels.pArray ); |
| ABC_FREE( p->vLevelsR.pArray ); |
| ABC_FREE( p->vCounts.pArray ); |
| ABC_FREE( p->vTravIds.pArray ); |
| ABC_FREE( p->vTravIds2.pArray ); |
| ABC_FREE( p->vId2Var.pArray ); |
| ABC_FREE( p->vVar2Id.pArray ); |
| Vec_WecFree( p->vCnfs ); |
| Vec_IntFree( p->vCover ); |
| // other data |
| Vec_IntFreeP( &p->vNodes ); |
| Vec_IntFreeP( &p->vDivs ); |
| Vec_IntFreeP( &p->vRoots ); |
| Vec_IntFreeP( &p->vTfo ); |
| Vec_WrdFreeP( &p->vDivCexes ); |
| Vec_IntFreeP( &p->vOrder ); |
| Vec_IntFreeP( &p->vDivVars ); |
| Vec_IntFreeP( &p->vDivIds ); |
| Vec_IntFreeP( &p->vLits ); |
| Vec_IntFreeP( &p->vValues ); |
| Vec_WecFreeP( &p->vClauses ); |
| Vec_IntFreeP( &p->vFaninMap ); |
| if ( p->pSat ) sat_solver_delete( p->pSat ); |
| ABC_FREE( p ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Performs resubstitution for the node.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Sfm_NtkRemoveFanin( Sfm_Ntk_t * p, int iNode, int iFanin ) |
| { |
| int RetValue; |
| assert( Sfm_ObjIsNode(p, iNode) ); |
| assert( !Sfm_ObjIsPo(p, iFanin) ); |
| RetValue = Vec_IntRemove( Sfm_ObjFiArray(p, iNode), iFanin ); |
| assert( RetValue ); |
| RetValue = Vec_IntRemove( Sfm_ObjFoArray(p, iFanin), iNode ); |
| assert( RetValue ); |
| } |
| void Sfm_NtkAddFanin( Sfm_Ntk_t * p, int iNode, int iFanin ) |
| { |
| if ( iFanin < 0 ) |
| return; |
| assert( Sfm_ObjIsNode(p, iNode) ); |
| assert( !Sfm_ObjIsPo(p, iFanin) ); |
| assert( Vec_IntFind( Sfm_ObjFiArray(p, iNode), iFanin ) == -1 ); |
| assert( Vec_IntFind( Sfm_ObjFoArray(p, iFanin), iNode ) == -1 ); |
| Vec_IntPush( Sfm_ObjFiArray(p, iNode), iFanin ); |
| Vec_IntPush( Sfm_ObjFoArray(p, iFanin), iNode ); |
| } |
| void Sfm_NtkDeleteObj_rec( Sfm_Ntk_t * p, int iNode ) |
| { |
| int i, iFanin; |
| if ( Sfm_ObjFanoutNum(p, iNode) > 0 || Sfm_ObjIsPi(p, iNode) || Sfm_ObjIsFixed(p, iNode) ) |
| return; |
| assert( Sfm_ObjIsNode(p, iNode) ); |
| Sfm_ObjForEachFanin( p, iNode, iFanin, i ) |
| { |
| int RetValue = Vec_IntRemove( Sfm_ObjFoArray(p, iFanin), iNode ); assert( RetValue ); |
| Sfm_NtkDeleteObj_rec( p, iFanin ); |
| } |
| Vec_IntClear( Sfm_ObjFiArray(p, iNode) ); |
| Vec_WrdWriteEntry( p->vTruths, iNode, (word)0 ); |
| } |
| void Sfm_NtkUpdateLevel_rec( Sfm_Ntk_t * p, int iNode ) |
| { |
| int i, iFanout; |
| int LevelNew = Sfm_ObjLevelNew( Sfm_ObjFiArray(p, iNode), &p->vLevels, Sfm_ObjAddsLevel(p, iNode) ); |
| if ( LevelNew == Sfm_ObjLevel(p, iNode) ) |
| return; |
| Sfm_ObjSetLevel( p, iNode, LevelNew ); |
| Sfm_ObjForEachFanout( p, iNode, iFanout, i ) |
| Sfm_NtkUpdateLevel_rec( p, iFanout ); |
| } |
| void Sfm_NtkUpdateLevelR_rec( Sfm_Ntk_t * p, int iNode ) |
| { |
| int i, iFanin; |
| int LevelNew = Sfm_ObjLevelNewR( Sfm_ObjFoArray(p, iNode), &p->vLevelsR, Sfm_ObjAddsLevel(p, iNode) ); |
| if ( LevelNew == Sfm_ObjLevelR(p, iNode) ) |
| return; |
| Sfm_ObjSetLevelR( p, iNode, LevelNew ); |
| Sfm_ObjForEachFanin( p, iNode, iFanin, i ) |
| Sfm_NtkUpdateLevelR_rec( p, iFanin ); |
| } |
| void Sfm_NtkUpdate( Sfm_Ntk_t * p, int iNode, int f, int iFaninNew, word uTruth ) |
| { |
| int iFanin = Sfm_ObjFanin( p, iNode, f ); |
| assert( Sfm_ObjIsNode(p, iNode) ); |
| assert( iFanin != iFaninNew ); |
| if ( uTruth == 0 || ~uTruth == 0 ) |
| { |
| Sfm_ObjForEachFanin( p, iNode, iFanin, f ) |
| { |
| int RetValue = Vec_IntRemove( Sfm_ObjFoArray(p, iFanin), iNode ); assert( RetValue ); |
| Sfm_NtkDeleteObj_rec( p, iFanin ); |
| } |
| Vec_IntClear( Sfm_ObjFiArray(p, iNode) ); |
| } |
| else |
| { |
| // replace old fanin by new fanin |
| Sfm_NtkRemoveFanin( p, iNode, iFanin ); |
| Sfm_NtkAddFanin( p, iNode, iFaninNew ); |
| // recursively remove MFFC |
| Sfm_NtkDeleteObj_rec( p, iFanin ); |
| } |
| // update logic level |
| Sfm_NtkUpdateLevel_rec( p, iNode ); |
| if ( iFaninNew != -1 ) |
| Sfm_NtkUpdateLevelR_rec( p, iFaninNew ); |
| if ( Sfm_ObjFanoutNum(p, iFanin) > 0 ) |
| Sfm_NtkUpdateLevelR_rec( p, iFanin ); |
| // update truth table |
| Vec_WrdWriteEntry( p->vTruths, iNode, uTruth ); |
| Sfm_TruthToCnf( uTruth, Sfm_ObjFaninNum(p, iNode), p->vCover, (Vec_Str_t *)Vec_WecEntry(p->vCnfs, iNode) ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Public APIs of this network.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Vec_Int_t * Sfm_NodeReadFanins( Sfm_Ntk_t * p, int i ) |
| { |
| return Vec_WecEntry( &p->vFanins, i ); |
| } |
| word * Sfm_NodeReadTruth( Sfm_Ntk_t * p, int i ) |
| { |
| return Vec_WrdEntryP( p->vTruths, i ); |
| } |
| int Sfm_NodeReadFixed( Sfm_Ntk_t * p, int i ) |
| { |
| return (int)Vec_StrEntry( p->vFixed, i ); |
| } |
| int Sfm_NodeReadUsed( Sfm_Ntk_t * p, int i ) |
| { |
| return (Sfm_ObjFaninNum(p, i) > 0) || (Sfm_ObjFanoutNum(p, i) > 0); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |