/src/base/abc/abcUtil.c
C | 2935 lines | 1741 code | 122 blank | 1072 comment | 313 complexity | aac5066405751703941b7c80364bff0e MD5 | raw file
Possible License(s): BSD-3-Clause
Large files files are truncated, but you can click here to view the full file
- /**CFile****************************************************************
- FileName [abcUtil.c]
- SystemName [ABC: Logic synthesis and verification system.]
- PackageName [Network and node package.]
- Synopsis [Various utilities.]
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
- Date [Ver. 1.0. Started - June 20, 2005.]
- Revision [$Id: abcUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
- ***********************************************************************/
- #include "abc.h"
- #include "base/main/main.h"
- #include "map/mio/mio.h"
- #include "bool/dec/dec.h"
- #include "opt/fxu/fxu.h"
-
- #ifdef ABC_USE_CUDD
- #include "bdd/extrab/extraBdd.h"
- #endif
- ABC_NAMESPACE_IMPL_START
- ////////////////////////////////////////////////////////////////////////
- /// DECLARATIONS ///
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- /// FUNCTION DEFINITIONS ///
- ////////////////////////////////////////////////////////////////////////
- /**Function*************************************************************
- Synopsis [Frees one attribute manager.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void * Abc_NtkAttrFree( Abc_Ntk_t * pNtk, int Attr, int fFreeMan )
- {
- void * pUserMan;
- Vec_Att_t * pAttrMan;
- pAttrMan = (Vec_Att_t *)Vec_PtrEntry( pNtk->vAttrs, Attr );
- Vec_PtrWriteEntry( pNtk->vAttrs, Attr, NULL );
- pUserMan = Vec_AttFree( pAttrMan, fFreeMan );
- return pUserMan;
- }
- /**Function*************************************************************
- Synopsis [Order CI/COs.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void Abc_NtkOrderCisCos( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pObj, * pTerm;
- int i, k;
- Vec_PtrClear( pNtk->vCis );
- Vec_PtrClear( pNtk->vCos );
- Abc_NtkForEachPi( pNtk, pObj, i )
- Vec_PtrPush( pNtk->vCis, pObj );
- Abc_NtkForEachPo( pNtk, pObj, i )
- Vec_PtrPush( pNtk->vCos, pObj );
- Abc_NtkForEachBox( pNtk, pObj, i )
- {
- if ( Abc_ObjIsLatch(pObj) )
- continue;
- Abc_ObjForEachFanin( pObj, pTerm, k )
- Vec_PtrPush( pNtk->vCos, pTerm );
- Abc_ObjForEachFanout( pObj, pTerm, k )
- Vec_PtrPush( pNtk->vCis, pTerm );
- }
- Abc_NtkForEachBox( pNtk, pObj, i )
- {
- if ( !Abc_ObjIsLatch(pObj) )
- continue;
- Abc_ObjForEachFanin( pObj, pTerm, k )
- Vec_PtrPush( pNtk->vCos, pTerm );
- Abc_ObjForEachFanout( pObj, pTerm, k )
- Vec_PtrPush( pNtk->vCis, pTerm );
- }
- }
- /**Function*************************************************************
- Synopsis [Reads the number of cubes of the node.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pNode;
- int i, nCubes = 0;
- assert( Abc_NtkHasSop(pNtk) );
- Abc_NtkForEachNode( pNtk, pNode, i )
- {
- if ( Abc_NodeIsConst(pNode) )
- continue;
- assert( pNode->pData );
- nCubes += Abc_SopGetCubeNum( (char *)pNode->pData );
- }
- return nCubes;
- }
- /**Function*************************************************************
- Synopsis [Reads the number of cubes of the node.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkGetCubePairNum( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pNode;
- int i;
- word nCubes, nCubePairs = 0;
- assert( Abc_NtkHasSop(pNtk) );
- Abc_NtkForEachNode( pNtk, pNode, i )
- {
- if ( Abc_NodeIsConst(pNode) )
- continue;
- assert( pNode->pData );
- nCubes = (word)Abc_SopGetCubeNum( (char *)pNode->pData );
- if ( nCubes > 1 )
- nCubePairs += nCubes * (nCubes - 1) / 2;
- }
- return (int)(nCubePairs > (1<<30) ? (1<<30) : nCubePairs);
- }
- /**Function*************************************************************
- Synopsis [Reads the number of literals in the SOPs of the nodes.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkGetLitNum( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pNode;
- int i, nLits = 0;
- assert( Abc_NtkHasSop(pNtk) );
- Abc_NtkForEachNode( pNtk, pNode, i )
- {
- assert( pNode->pData );
- nLits += Abc_SopGetLitNum( (char *)pNode->pData );
- }
- return nLits;
- }
- /**Function*************************************************************
- Synopsis [Counts the number of literals in the factored forms.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkGetLitFactNum( Abc_Ntk_t * pNtk )
- {
- Dec_Graph_t * pFactor;
- Abc_Obj_t * pNode;
- int nNodes, i;
- assert( Abc_NtkHasSop(pNtk) );
- nNodes = 0;
- Abc_NtkForEachNode( pNtk, pNode, i )
- {
- if ( Abc_NodeIsConst(pNode) )
- continue;
- pFactor = Dec_Factor( (char *)pNode->pData );
- nNodes += 1 + Dec_GraphNodeNum(pFactor);
- Dec_GraphFree( pFactor );
- }
- return nNodes;
- }
- /**Function*************************************************************
- Synopsis [Counts the number of nodes with more than 1 reference.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkGetMultiRefNum( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pNode;
- int nNodes, i;
- assert( Abc_NtkIsStrash(pNtk) );
- nNodes = 0;
- Abc_NtkForEachNode( pNtk, pNode, i )
- nNodes += (int)(Abc_ObjFanoutNum(pNode) > 1);
- return nNodes;
- }
- /**Function*************************************************************
- Synopsis [Reads the number of BDD nodes.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk )
- {
- int nNodes = 0;
- #ifdef ABC_USE_CUDD
- Abc_Obj_t * pNode;
- int i;
- assert( Abc_NtkIsBddLogic(pNtk) );
- Abc_NtkForEachNode( pNtk, pNode, i )
- {
- assert( pNode->pData );
- if ( Abc_ObjFaninNum(pNode) < 2 )
- continue;
- nNodes += pNode->pData? -1 + Cudd_DagSize( (DdNode *)pNode->pData ) : 0;
- }
- #endif
- return nNodes;
- }
- /**Function*************************************************************
- Synopsis [Reads the number of BDD nodes.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkGetAigNodeNum( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pNode;
- int i, nNodes = 0;
- assert( Abc_NtkIsAigLogic(pNtk) );
- Abc_NtkForEachNode( pNtk, pNode, i )
- {
- assert( pNode->pData );
- if ( Abc_ObjFaninNum(pNode) < 2 )
- continue;
- //printf( "%d ", Hop_DagSize( pNode->pData ) );
- nNodes += pNode->pData? Hop_DagSize( (Hop_Obj_t *)pNode->pData ) : 0;
- }
- return nNodes;
- }
- /**Function*************************************************************
- Synopsis [Reads the number of BDD nodes.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkGetClauseNum( Abc_Ntk_t * pNtk )
- {
- int nClauses = 0;
- #ifdef ABC_USE_CUDD
- extern int Abc_CountZddCubes( DdManager * dd, DdNode * zCover );
- Abc_Obj_t * pNode;
- DdNode * bCover, * zCover, * bFunc;
- DdManager * dd = (DdManager *)pNtk->pManFunc;
- int i;
- assert( Abc_NtkIsBddLogic(pNtk) );
- Abc_NtkForEachNode( pNtk, pNode, i )
- {
- assert( pNode->pData );
- bFunc = (DdNode *)pNode->pData;
- bCover = Cudd_zddIsop( dd, bFunc, bFunc, &zCover );
- Cudd_Ref( bCover );
- Cudd_Ref( zCover );
- nClauses += Abc_CountZddCubes( dd, zCover );
- Cudd_RecursiveDeref( dd, bCover );
- Cudd_RecursiveDerefZdd( dd, zCover );
- bCover = Cudd_zddIsop( dd, Cudd_Not(bFunc), Cudd_Not(bFunc), &zCover );
- Cudd_Ref( bCover );
- Cudd_Ref( zCover );
- nClauses += Abc_CountZddCubes( dd, zCover );
- Cudd_RecursiveDeref( dd, bCover );
- Cudd_RecursiveDerefZdd( dd, zCover );
- }
- #endif
- return nClauses;
- }
- /**Function*************************************************************
- Synopsis [Computes the area of the mapped circuit.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- double Abc_NtkGetMappedArea( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pObj;
- double TotalArea;
- int i;
- assert( Abc_NtkHasMapping(pNtk) );
- TotalArea = 0.0;
- Abc_NtkForEachNode( pNtk, pObj, i )
- {
- if ( Abc_ObjIsBarBuf(pObj) )
- continue;
- // assert( pObj->pData );
- if ( pObj->pData == NULL )
- {
- printf( "Node without mapping is encountered.\n" );
- continue;
- }
- TotalArea += Mio_GateReadArea( (Mio_Gate_t *)pObj->pData );
- // assuming that twin gates follow each other
- if ( Abc_NtkFetchTwinNode(pObj) )
- i++;
- }
- return TotalArea;
- }
- /**Function*************************************************************
- Synopsis [Counts the number of exors.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkGetExorNum( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pNode;
- int i, Counter = 0;
- Abc_NtkForEachNode( pNtk, pNode, i )
- Counter += pNode->fExor;
- return Counter;
- }
-
- /**Function*************************************************************
-
- Synopsis [Counts the number of exors.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
- ***********************************************************************/
- int Abc_NtkGetMuxNum( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pNode;
- int i, Counter = 0;
- Abc_NtkForEachNode( pNtk, pNode, i )
- Counter += Abc_NodeIsMuxType(pNode);
- return Counter;
- }
-
- /**Function*************************************************************
-
- Synopsis [Counts the number of exors.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
- ***********************************************************************/
- int Abc_NtkGetBufNum( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pNode;
- int i, Counter = 0;
- Abc_NtkForEachNode( pNtk, pNode, i )
- Counter += (Abc_ObjFaninNum(pNode) == 1);
- return Counter;
- }
-
- /**Function*************************************************************
-
- Synopsis [Counts the number of exors.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
- ***********************************************************************/
- int Abc_NtkGetLargeNodeNum( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pNode;
- int i, Counter = 0;
- Abc_NtkForEachNode( pNtk, pNode, i )
- Counter += (Abc_ObjFaninNum(pNode) > 1);
- return Counter;
- }
- /**Function*************************************************************
- Synopsis [Returns 1 if it is an AIG with choice nodes.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkGetChoiceNum( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pNode;
- int i, Counter;
- if ( !Abc_NtkIsStrash(pNtk) )
- return 0;
- Counter = 0;
- Abc_NtkForEachNode( pNtk, pNode, i )
- Counter += Abc_AigNodeIsChoice( pNode );
- return Counter;
- }
- /**Function*************************************************************
- Synopsis [Reads the maximum number of fanins.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pNode;
- int i, nFaninsMax = 0;
- Abc_NtkForEachNode( pNtk, pNode, i )
- {
- if ( nFaninsMax < Abc_ObjFaninNum(pNode) )
- nFaninsMax = Abc_ObjFaninNum(pNode);
- }
- return nFaninsMax;
- }
- int Abc_NtkGetFanoutMax( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pNode;
- int i, nFaninsMax = 0;
- Abc_NtkForEachNode( pNtk, pNode, i )
- {
- if ( nFaninsMax < Abc_ObjFanoutNum(pNode) )
- nFaninsMax = Abc_ObjFanoutNum(pNode);
- }
- return nFaninsMax;
- }
- /**Function*************************************************************
- Synopsis [Reads the total number of all fanins.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkGetTotalFanins( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pNode;
- int i, nFanins = 0;
- Abc_NtkForEachNode( pNtk, pNode, i )
- nFanins += Abc_ObjFaninNum(pNode);
- return nFanins;
- }
- /**Function*************************************************************
- Synopsis [Cleans the copy field of all objects.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pObj;
- int i;
- Abc_NtkForEachObj( pNtk, pObj, i )
- pObj->pCopy = NULL;
- }
- void Abc_NtkCleanCopy_rec( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pObj;
- int i;
- Abc_NtkCleanCopy( pNtk );
- Abc_NtkForEachBox( pNtk, pObj, i )
- Abc_NtkCleanCopy_rec( Abc_ObjModel(pObj) );
- }
- /**Function*************************************************************
- Synopsis [Cleans the copy field of all objects.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void Abc_NtkCleanData( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pObj;
- int i;
- Abc_NtkForEachObj( pNtk, pObj, i )
- pObj->pData = NULL;
- }
- /**Function*************************************************************
- Synopsis [Cleans the copy field of all objects.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void Abc_NtkFillTemp( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pObj;
- int i;
- Abc_NtkForEachObj( pNtk, pObj, i )
- pObj->iTemp = -1;
- }
- /**Function*************************************************************
- Synopsis [Counts the number of nodes having non-trivial copies.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkCountCopy( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pObj;
- int i, Counter = 0;
- Abc_NtkForEachObj( pNtk, pObj, i )
- {
- if ( Abc_ObjIsNode(pObj) )
- Counter += (pObj->pCopy != NULL);
- }
- return Counter;
- }
- /**Function*************************************************************
- Synopsis [Saves copy field of the objects.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- Vec_Ptr_t * Abc_NtkSaveCopy( Abc_Ntk_t * pNtk )
- {
- Vec_Ptr_t * vCopies;
- Abc_Obj_t * pObj;
- int i;
- vCopies = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) );
- Abc_NtkForEachObj( pNtk, pObj, i )
- Vec_PtrWriteEntry( vCopies, i, pObj->pCopy );
- return vCopies;
- }
- /**Function*************************************************************
- Synopsis [Loads copy field of the objects.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void Abc_NtkLoadCopy( Abc_Ntk_t * pNtk, Vec_Ptr_t * vCopies )
- {
- Abc_Obj_t * pObj;
- int i;
- Abc_NtkForEachObj( pNtk, pObj, i )
- pObj->pCopy = (Abc_Obj_t *)Vec_PtrEntry( vCopies, i );
- }
- /**Function*************************************************************
- Synopsis [Cleans the copy field of all objects.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void Abc_NtkCleanNext( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pObj;
- int i;
- Abc_NtkForEachObj( pNtk, pObj, i )
- pObj->pNext = NULL;
- }
- void Abc_NtkCleanNext_rec( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pObj;
- int i;
- Abc_NtkCleanNext( pNtk );
- Abc_NtkForEachBox( pNtk, pObj, i )
- Abc_NtkCleanNext_rec( Abc_ObjModel(pObj) );
- }
- /**Function*************************************************************
- Synopsis [Cleans the copy field of all objects.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void Abc_NtkCleanMarkA( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pObj;
- int i;
- Abc_NtkForEachObj( pNtk, pObj, i )
- pObj->fMarkA = 0;
- }
- /**Function*************************************************************
- Synopsis [Cleans the copy field of all objects.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void Abc_NtkCleanMarkB( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pObj;
- int i;
- Abc_NtkForEachObj( pNtk, pObj, i )
- pObj->fMarkB = 0;
- }
- /**Function*************************************************************
- Synopsis [Cleans the copy field of all objects.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void Abc_NtkCleanMarkC( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pObj;
- int i;
- Abc_NtkForEachObj( pNtk, pObj, i )
- pObj->fMarkC = 0;
- }
- /**Function*************************************************************
- Synopsis [Cleans the copy field of all objects.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void Abc_NtkCleanMarkAB( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pObj;
- int i;
- Abc_NtkForEachObj( pNtk, pObj, i )
- pObj->fMarkA = pObj->fMarkB = 0;
- }
- /**Function*************************************************************
- Synopsis [Cleans the copy field of all objects.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void Abc_NtkCleanMarkABC( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pObj;
- int i;
- Abc_NtkForEachObj( pNtk, pObj, i )
- pObj->fMarkA = pObj->fMarkB = pObj->fMarkC = 0;
- }
- /**Function*************************************************************
- Synopsis [Returns the index of the given fanin.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NodeFindFanin( Abc_Obj_t * pNode, Abc_Obj_t * pFanin )
- {
- Abc_Obj_t * pThis;
- int i;
- Abc_ObjForEachFanin( pNode, pThis, i )
- if ( pThis == pFanin )
- return i;
- return -1;
- }
- /**Function*************************************************************
- Synopsis [Checks if the internal node has CO fanout.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- Abc_Obj_t * Abc_NodeFindCoFanout( Abc_Obj_t * pNode )
- {
- Abc_Obj_t * pFanout;
- int i;
- Abc_ObjForEachFanout( pNode, pFanout, i )
- if ( Abc_ObjIsCo(pFanout) )
- return pFanout;
- return NULL;
- }
- /**Function*************************************************************
- Synopsis [Checks if the internal node has CO fanout.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- Abc_Obj_t * Abc_NodeFindNonCoFanout( Abc_Obj_t * pNode )
- {
- Abc_Obj_t * pFanout;
- int i;
- Abc_ObjForEachFanout( pNode, pFanout, i )
- if ( !Abc_ObjIsCo(pFanout) )
- return pFanout;
- return NULL;
- }
- /**Function*************************************************************
- Synopsis [Checks if the internal node has CO drivers with the same name.]
- Description [Checks if the internal node can borrow its name from CO fanouts.
- This is possible if all COs with non-complemented fanin edge pointing to this
- node have the same name.]
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode )
- {
- Abc_Obj_t * pFanout, * pFanoutCo;
- int i;
- pFanoutCo = NULL;
- Abc_ObjForEachFanout( pNode, pFanout, i )
- {
- if ( !Abc_ObjIsCo(pFanout) )
- continue;
- if ( Abc_ObjFaninC0(pFanout) )
- continue;
- if ( pFanoutCo == NULL )
- {
- assert( Abc_ObjFaninNum(pFanout) == 1 );
- assert( Abc_ObjFanin0(pFanout) == pNode );
- pFanoutCo = pFanout;
- continue;
- }
- if ( strcmp( Abc_ObjName(pFanoutCo), Abc_ObjName(pFanout) ) ) // they have diff names
- return NULL;
- }
- return pFanoutCo;
- }
- /**Function*************************************************************
- Synopsis [Fixes the CO driver problem.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void Abc_NtkFixCoDriverProblem( Abc_Obj_t * pDriver, Abc_Obj_t * pNodeCo, int fDuplicate )
- {
- Abc_Ntk_t * pNtk = pDriver->pNtk;
- Abc_Obj_t * pDriverNew, * pFanin;
- int k;
- if ( fDuplicate && !Abc_ObjIsCi(pDriver) )
- {
- pDriverNew = Abc_NtkDupObj( pNtk, pDriver, 0 );
- Abc_ObjForEachFanin( pDriver, pFanin, k )
- Abc_ObjAddFanin( pDriverNew, pFanin );
- if ( Abc_ObjFaninC0(pNodeCo) )
- {
- // change polarity of the duplicated driver
- Abc_NodeComplement( pDriverNew );
- Abc_ObjXorFaninC( pNodeCo, 0 );
- }
- }
- else
- {
- // add inverters and buffers when necessary
- if ( Abc_ObjFaninC0(pNodeCo) )
- {
- pDriverNew = Abc_NtkCreateNodeInv( pNtk, pDriver );
- Abc_ObjXorFaninC( pNodeCo, 0 );
- }
- else
- pDriverNew = Abc_NtkCreateNodeBuf( pNtk, pDriver );
- }
- // update the fanin of the PO node
- Abc_ObjPatchFanin( pNodeCo, pDriver, pDriverNew );
- assert( Abc_ObjFanoutNum(pDriverNew) == 1 );
- // remove the old driver if it dangles
- // (this happens when the duplicated driver had only one complemented fanout)
- if ( Abc_ObjFanoutNum(pDriver) == 0 )
- Abc_NtkDeleteObj( pDriver );
- }
- /**Function*************************************************************
- Synopsis [Returns 1 if COs of a logic network are simple.]
- Description [The COs of a logic network are simple under three conditions:
- (1) The edge from CO to its driver is not complemented.
- (2) If CI is a driver of a CO, they have the same name.]
- (3) If two COs share the same driver, they have the same name.]
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pNode, * pDriver;
- int i;
- assert( Abc_NtkIsLogic(pNtk) );
- Abc_NtkIncrementTravId( pNtk );
- Abc_NtkForEachCo( pNtk, pNode, i )
- {
- // if the driver is complemented, this is an error
- pDriver = Abc_ObjFanin0(pNode);
- if ( Abc_ObjFaninC0(pNode) )
- return 0;
- // if the driver is a CI and has different name, this is an error
- if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) )
- return 0;
- // if the driver is visited for the first time, remember the CO name
- if ( !Abc_NodeIsTravIdCurrent(pDriver) )
- {
- pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode);
- Abc_NodeSetTravIdCurrent(pDriver);
- continue;
- }
- // the driver has second CO - if they have different name, this is an error
- if ( strcmp((char *)pDriver->pNext, Abc_ObjName(pNode)) ) // diff names
- return 0;
- }
- return 1;
- }
- /**Function*************************************************************
- Synopsis [Transforms the network to have simple COs.]
- Description [The COs of a logic network are simple under three conditions:
- (1) The edge from CO to its driver is not complemented.
- (2) If CI is a driver of a CO, they have the same name.]
- (3) If two COs share the same driver, they have the same name.
- In some cases, such as FPGA mapping, we prevent the increase in delay
- by duplicating the driver nodes, rather than adding invs/bufs.]
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkLogicMakeSimpleCos2( Abc_Ntk_t * pNtk, int fDuplicate )
- {
- Abc_Obj_t * pNode, * pDriver;
- int i, nDupGates = 0;
- assert( Abc_NtkIsLogic(pNtk) );
- Abc_NtkIncrementTravId( pNtk );
- Abc_NtkForEachCo( pNtk, pNode, i )
- {
- // if the driver is complemented, this is an error
- pDriver = Abc_ObjFanin0(pNode);
- if ( Abc_ObjFaninC0(pNode) )
- {
- Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
- nDupGates++;
- continue;
- }
- // if the driver is a CI and has different name, this is an error
- if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) )
- {
- Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
- nDupGates++;
- continue;
- }
- // if the driver is visited for the first time, remember the CO name
- if ( !Abc_NodeIsTravIdCurrent(pDriver) )
- {
- pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode);
- Abc_NodeSetTravIdCurrent(pDriver);
- continue;
- }
- // the driver has second CO - if they have different name, this is an error
- if ( strcmp((char *)pDriver->pNext, Abc_ObjName(pNode)) ) // diff names
- {
- Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
- nDupGates++;
- continue;
- }
- }
- assert( Abc_NtkLogicHasSimpleCos(pNtk) );
- return nDupGates;
- }
-
- /**Function*************************************************************
-
- Synopsis [Transforms the network to have simple COs.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
- ***********************************************************************/
- void Abc_NtkLogicMakeSimpleCosTest( Abc_Ntk_t * pNtk, int fDuplicate )
- {
- int nObjs = Abc_NtkObjNumMax(pNtk);
- unsigned * pType = ABC_CALLOC( unsigned, nObjs );
- Abc_Obj_t * pNode;
- int i, Counts[4] = {0}, Consts[2] = {0}, Inputs[2] = {0};
- // collect info
- Abc_NtkForEachCo( pNtk, pNode, i )
- {
- if ( Abc_ObjFaninId0(pNode) == 0 )
- Consts[Abc_ObjFaninC0(pNode)]++;
- if ( Abc_ObjIsCi(Abc_ObjFanin0(pNode)) )
- Inputs[Abc_ObjFaninC0(pNode)]++;
- pType[Abc_ObjFaninId0(pNode)] |= (1 << Abc_ObjFaninC0(pNode));
- }
- // count the numbers
- for ( i = 0; i < nObjs; i++ )
- Counts[pType[i]]++;
- for ( i = 0; i < 4; i++ )
- printf( "%d = %d ", i, Counts[i] );
- for ( i = 0; i < 2; i++ )
- printf( "c%d = %d ", i, Consts[i] );
- for ( i = 0; i < 2; i++ )
- printf( "i%d = %d ", i, Inputs[i] );
- printf( "\n" );
- ABC_FREE( pType );
- }
- /**Function*************************************************************
- Synopsis [Transforms the network to have simple COs.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate )
- {
- Vec_Ptr_t * vDrivers, * vCoTerms;
- Abc_Obj_t * pNode, * pDriver, * pDriverNew, * pFanin;
- int i, k, LevelMax, nTotal = 0;
- assert( Abc_NtkIsLogic(pNtk) );
- LevelMax = Abc_NtkLevel(pNtk);
- // Abc_NtkLogicMakeSimpleCosTest( pNtk, fDuplicate );
-
- // fix constant drivers
- Abc_NtkForEachCo( pNtk, pNode, i )
- {
- pDriver = Abc_ObjFanin0(pNode);
- if ( !Abc_NodeIsConst(pDriver) )
- continue;
- pDriverNew = (Abc_ObjFaninC0(pNode) == Abc_NodeIsConst0(pDriver)) ? Abc_NtkCreateNodeConst1(pNtk) : Abc_NtkCreateNodeConst0(pNtk);
- if ( Abc_ObjFaninC0(pNode) )
- Abc_ObjXorFaninC( pNode, 0 );
- Abc_ObjPatchFanin( pNode, pDriver, pDriverNew );
- if ( Abc_ObjFanoutNum(pDriver) == 0 )
- Abc_NtkDeleteObj( pDriver );
- }
- // collect drivers pointed by complemented edges
- vDrivers = Vec_PtrAlloc( 100 );
- Abc_NtkIncrementTravId( pNtk );
- Abc_NtkForEachCo( pNtk, pNode, i )
- {
- if ( !Abc_ObjFaninC0(pNode) )
- continue;
- pDriver = Abc_ObjFanin0(pNode);
- if ( Abc_NodeIsTravIdCurrent(pDriver) )
- continue;
- Abc_NodeSetTravIdCurrent(pDriver);
- Vec_PtrPush( vDrivers, pDriver );
- }
- // fix complemented drivers
- if ( Vec_PtrSize(vDrivers) > 0 )
- {
- int nDupGates = 0, nDupInvs = 0, nDupChange = 0;
- Vec_Ptr_t * vFanouts = Vec_PtrAlloc( 100 );
- Vec_PtrForEachEntry( Abc_Obj_t *, vDrivers, pDriver, i )
- {
- int fHasDir = 0, fHasInv = 0, fHasOther = 0;
- Abc_ObjForEachFanout( pDriver, pNode, k )
- {
- if ( !Abc_ObjIsCo(pNode) )
- {
- assert( !Abc_ObjFaninC0(pNode) );
- fHasOther = 1;
- continue;
- }
- if ( Abc_ObjFaninC0(pNode) )
- fHasInv = 1;
- else //if ( Abc_ObjFaninC0(pNode) )
- fHasDir = 1;
- }
- assert( fHasInv );
- if ( Abc_ObjIsCi(pDriver) || fHasDir || (fHasOther && Abc_NtkHasMapping(pNtk)) ) // cannot change
- {
- // duplicate if critical
- if ( fDuplicate && Abc_ObjIsNode(pDriver) && Abc_ObjLevel(pDriver) == LevelMax )
- {
- pDriverNew = Abc_NtkDupObj( pNtk, pDriver, 0 );
- Abc_ObjForEachFanin( pDriver, pFanin, k )
- Abc_ObjAddFanin( pDriverNew, pFanin );
- Abc_NodeComplement( pDriverNew );
- nDupGates++;
- }
- else // add inverter
- {
- pDriverNew = Abc_NtkCreateNodeInv( pNtk, pDriver );
- nDupInvs++;
- }
- // collect CO fanouts to be redirected to the new node
- Vec_PtrClear( vFanouts );
- Abc_ObjForEachFanout( pDriver, pNode, k )
- if ( Abc_ObjIsCo(pNode) && Abc_ObjFaninC0(pNode) )
- Vec_PtrPush( vFanouts, pNode );
- assert( Vec_PtrSize(vFanouts) > 0 );
- Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pNode, k )
- {
- Abc_ObjXorFaninC( pNode, 0 );
- Abc_ObjPatchFanin( pNode, pDriver, pDriverNew );
- assert( Abc_ObjIsCi(pDriver) || Abc_ObjFanoutNum(pDriver) > 0 );
- }
- }
- else // can change
- {
- // change polarity of the driver
- assert( Abc_ObjIsNode(pDriver) );
- Abc_NodeComplement( pDriver );
- Abc_ObjForEachFanout( pDriver, pNode, k )
- {
- if ( Abc_ObjIsCo(pNode) )
- {
- assert( Abc_ObjFaninC0(pNode) );
- Abc_ObjXorFaninC( pNode, 0 );
- }
- else if ( Abc_ObjIsNode(pNode) )
- Abc_NodeComplementInput( pNode, pDriver );
- else assert( 0 );
- }
- nDupChange++;
- }
- }
- Vec_PtrFree( vFanouts );
- // printf( "Resolving inverted CO drivers: Invs = %d. Dups = %d. Changes = %d.\n",
- // nDupInvs, nDupGates, nDupChange );
- nTotal += nDupInvs + nDupGates;
- }
- Vec_PtrFree( vDrivers );
- // collect COs that needs fixing by adding buffers or duplicating
- vCoTerms = Vec_PtrAlloc( 100 );
- Abc_NtkIncrementTravId( pNtk );
- Abc_NtkForEachCo( pNtk, pNode, i )
- {
- // if the driver is a CI and has different name, this is an error
- pDriver = Abc_ObjFanin0(pNode);
- if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) )
- {
- Vec_PtrPush( vCoTerms, pNode );
- continue;
- }
- // if the driver is visited for the first time, remember the CO name
- if ( !Abc_NodeIsTravIdCurrent(pDriver) )
- {
- pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode);
- Abc_NodeSetTravIdCurrent(pDriver);
- continue;
- }
- // the driver has second CO - if they have different name, this is an error
- if ( strcmp((char *)pDriver->pNext, Abc_ObjName(pNode)) ) // diff names
- {
- Vec_PtrPush( vCoTerms, pNode );
- continue;
- }
- }
- // fix duplication problem
- if ( Vec_PtrSize(vCoTerms) > 0 )
- {
- int nDupBufs = 0, nDupGates = 0;
- Vec_PtrForEachEntry( Abc_Obj_t *, vCoTerms, pNode, i )
- {
- pDriver = Abc_ObjFanin0(pNode);
- // duplicate if critical
- if ( fDuplicate && Abc_ObjIsNode(pDriver) && (Abc_NtkHasMapping(pNtk) || Abc_ObjLevel(pDriver) == LevelMax) )
- {
- pDriverNew = Abc_NtkDupObj( pNtk, pDriver, 0 );
- Abc_ObjForEachFanin( pDriver, pFanin, k )
- Abc_ObjAddFanin( pDriverNew, pFanin );
- nDupGates++;
- }
- else // add buffer
- {
- pDriverNew = Abc_NtkCreateNodeBuf( pNtk, pDriver );
- Abc_ObjAssignName( pDriverNew, Abc_ObjName(pDriver), "_buf" );
- nDupBufs++;
- }
- // swing the PO
- Abc_ObjPatchFanin( pNode, pDriver, pDriverNew );
- assert( Abc_ObjIsCi(pDriver) || Abc_ObjFanoutNum(pDriver) > 0 );
- }
- // printf( "Resolving shared CO drivers: Bufs = %d. Dups = %d.\n", nDupBufs, nDupGates );
- nTotal += nDupBufs + nDupGates;
- }
- Vec_PtrFree( vCoTerms );
- return nTotal;
- }
- /**Function*************************************************************
- Synopsis [Inserts a new node in the order by levels.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void Abc_VecObjPushUniqueOrderByLevel( Vec_Ptr_t * p, Abc_Obj_t * pNode )
- {
- Abc_Obj_t * pNode1, * pNode2;
- int i;
- if ( Vec_PtrPushUnique(p, pNode) )
- return;
- // find the p of the node
- for ( i = p->nSize-1; i > 0; i-- )
- {
- pNode1 = (Abc_Obj_t *)p->pArray[i ];
- pNode2 = (Abc_Obj_t *)p->pArray[i-1];
- if ( Abc_ObjRegular(pNode1)->Level <= Abc_ObjRegular(pNode2)->Level )
- break;
- p->pArray[i ] = pNode2;
- p->pArray[i-1] = pNode1;
- }
- }
- /**Function*************************************************************
- Synopsis [Returns 1 if the node is the root of EXOR/NEXOR.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NodeIsExorType( Abc_Obj_t * pNode )
- {
- Abc_Obj_t * pNode0, * pNode1;
- // check that the node is regular
- assert( !Abc_ObjIsComplement(pNode) );
- // if the node is not AND, this is not EXOR
- if ( !Abc_AigNodeIsAnd(pNode) )
- return 0;
- // if the children are not complemented, this is not EXOR
- if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) )
- return 0;
- // get children
- pNode0 = Abc_ObjFanin0(pNode);
- pNode1 = Abc_ObjFanin1(pNode);
- // if the children are not ANDs, this is not EXOR
- if ( Abc_ObjFaninNum(pNode0) != 2 || Abc_ObjFaninNum(pNode1) != 2 )
- return 0;
- // this is AIG, which means the fanins should be ordered
- assert( Abc_ObjFaninId0(pNode0) != Abc_ObjFaninId1(pNode1) ||
- Abc_ObjFaninId0(pNode1) != Abc_ObjFaninId1(pNode0) );
- // if grand children are not the same, this is not EXOR
- if ( Abc_ObjFaninId0(pNode0) != Abc_ObjFaninId0(pNode1) ||
- Abc_ObjFaninId1(pNode0) != Abc_ObjFaninId1(pNode1) )
- return 0;
- // finally, if the complemented edges are matched, this is not EXOR
- if ( Abc_ObjFaninC0(pNode0) == Abc_ObjFaninC0(pNode1) ||
- Abc_ObjFaninC1(pNode0) == Abc_ObjFaninC1(pNode1) )
- return 0;
- return 1;
- }
- /**Function*************************************************************
- Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NodeIsMuxType( Abc_Obj_t * pNode )
- {
- Abc_Obj_t * pNode0, * pNode1;
- // check that the node is regular
- assert( !Abc_ObjIsComplement(pNode) );
- // if the node is not AND, this is not MUX
- if ( !Abc_AigNodeIsAnd(pNode) )
- return 0;
- // if the children are not complemented, this is not MUX
- if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) )
- return 0;
- // get children
- pNode0 = Abc_ObjFanin0(pNode);
- pNode1 = Abc_ObjFanin1(pNode);
- // if the children are not ANDs, this is not MUX
- if ( !Abc_AigNodeIsAnd(pNode0) || !Abc_AigNodeIsAnd(pNode1) )
- return 0;
- // otherwise the node is MUX iff it has a pair of equal grandchildren with opposite polarity
- return (Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC0(pNode1))) ||
- (Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC1(pNode1))) ||
- (Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC0(pNode1))) ||
- (Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC1(pNode1)));
- }
- /**Function*************************************************************
- Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkCountMuxes( Abc_Ntk_t * pNtk )
- {
- Abc_Obj_t * pNode;
- int i;
- int Counter = 0;
- Abc_NtkForEachNode( pNtk, pNode, i )
- Counter += Abc_NodeIsMuxType( pNode );
- return Counter;
- }
- /**Function*************************************************************
- Synopsis [Returns 1 if the node is the control type of the MUX.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NodeIsMuxControlType( Abc_Obj_t * pNode )
- {
- Abc_Obj_t * pNode0, * pNode1;
- // check that the node is regular
- assert( !Abc_ObjIsComplement(pNode) );
- // skip the node that do not have two fanouts
- if ( Abc_ObjFanoutNum(pNode) != 2 )
- return 0;
- // get the fanouts
- pNode0 = Abc_ObjFanout( pNode, 0 );
- pNode1 = Abc_ObjFanout( pNode, 1 );
- // if they have more than one fanout, we are not interested
- if ( Abc_ObjFanoutNum(pNode0) != 1 || Abc_ObjFanoutNum(pNode1) != 1 )
- return 0;
- // if the fanouts have the same fanout, this is MUX or EXOR (or a redundant gate (CA)(CB))
- return Abc_ObjFanout0(pNode0) == Abc_ObjFanout0(pNode1);
- }
- /**Function*************************************************************
- Synopsis [Recognizes what nodes are control and data inputs of a MUX.]
- Description [If the node is a MUX, returns the control variable C.
- Assigns nodes T and E to be the then and else variables of the MUX.
- Node C is never complemented. Nodes T and E can be complemented.
- This function also recognizes EXOR/NEXOR gates as MUXes.]
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- Abc_Obj_t * Abc_NodeRecognizeMux( Abc_Obj_t * pNode, Abc_Obj_t ** ppNodeT, Abc_Obj_t ** ppNodeE )
- {
- Abc_Obj_t * pNode0, * pNode1;
- assert( !Abc_ObjIsComplement(pNode) );
- assert( Abc_NodeIsMuxType(pNode) );
- // get children
- pNode0 = Abc_ObjFanin0(pNode);
- pNode1 = Abc_ObjFanin1(pNode);
- // find the control variable
- // if ( pNode1->p1 == Fraig_Not(pNode2->p1) )
- if ( Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC0(pNode1)) )
- {
- // if ( Fraig_IsComplement(pNode1->p1) )
- if ( Abc_ObjFaninC0(pNode0) )
- { // pNode2->p1 is positive phase of C
- *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
- *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
- return Abc_ObjChild0(pNode1);//pNode2->p1;
- }
- else
- { // pNode1->p1 is positive phase of C
- *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
- *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
- return Abc_ObjChild0(pNode0);//pNode1->p1;
- }
- }
- // else if ( pNode1->p1 == Fraig_Not(pNode2->p2) )
- else if ( Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC1(pNode1)) )
- {
- // if ( Fraig_IsComplement(pNode1->p1) )
- if ( Abc_ObjFaninC0(pNode0) )
- { // pNode2->p2 is positive phase of C
- *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
- *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
- return Abc_ObjChild1(pNode1);//pNode2->p2;
- }
- else
- { // pNode1->p1 is positive phase of C
- *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
- *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
- return Abc_ObjChild0(pNode0);//pNode1->p1;
- }
- }
- // else if ( pNode1->p2 == Fraig_Not(pNode2->p1) )
- else if ( Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC0(pNode1)) )
- {
- // if ( Fraig_IsComplement(pNode1->p2) )
- if ( Abc_ObjFaninC1(pNode0) )
- { // pNode2->p1 is positive phase of C
- *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
- *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
- return Abc_ObjChild0(pNode1);//pNode2->p1;
- }
- else
- { // pNode1->p2 is positive phase of C
- *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
- *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
- return Abc_ObjChild1(pNode0);//pNode1->p2;
- }
- }
- // else if ( pNode1->p2 == Fraig_Not(pNode2->p2) )
- else if ( Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC1(pNode1)) )
- {
- // if ( Fraig_IsComplement(pNode1->p2) )
- if ( Abc_ObjFaninC1(pNode0) )
- { // pNode2->p2 is positive phase of C
- *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
- *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
- return Abc_ObjChild1(pNode1);//pNode2->p2;
- }
- else
- { // pNode1->p2 is positive phase of C
- *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
- *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
- return Abc_ObjChild1(pNode0);//pNode1->p2;
- }
- }
- assert( 0 ); // this is not MUX
- return NULL;
- }
- /**Function*************************************************************
- Synopsis [Prepares two network for a two-argument command similar to "verify".]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NtkPrepareTwoNtks( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc,
- Abc_Ntk_t ** ppNtk1, Abc_Ntk_t ** ppNtk2, int * pfDelete1, int * pfDelete2 )
- {
- int fCheck = 1;
- FILE * pFile;
- Abc_Ntk_t * pNtk1, * pNtk2, * pNtkTemp;
- int util_optind = 0;
- *pfDelete1 = 0;
- *pfDelete2 = 0;
- if ( argc == util_optind )
- { // use the spec
- if ( pNtk == NULL )
- {
- fprintf( pErr, "Empty current network.\n" );
- return 0;
- }
- if ( pNtk->pSpec == NULL )
- {
- fprintf( pErr, "The external spec is not given.\n" );
- return 0;
- }
- pFile = fopen( pNtk->pSpec, "r" );
- if ( pFile == NULL )
- {
- fprintf( pErr, "Cannot open the external spec file \"%s\".\n", pNtk->pSpec );
- return 0;
- }
- else
- fclose( pFile );
- pNtk1 = Abc_NtkDup(pNtk);
- pNtk2 = Io_Read( pNtk->pSpec, Io_ReadFileType(pNtk->pSpec), fCheck, 0 );
- if ( pNtk2 == NULL )
- return 0;
- *pfDelete1 = 1;
- *pfDelete2 = 1;
- }
- else if ( argc == util_optind + 1 )
- {
- if ( pNtk == NULL )
- {
- fprintf( pErr, "Empty current network.\n" );
- return 0;
- }
- pNtk1 = Abc_NtkDup(pNtk);
- pNtk2 = Io_Read( argv[util_optind], Io_ReadFileType(argv[util_optind]), fCheck, 0 );
- if ( pNtk2 == NULL )
- return 0;
- *pfDelete1 = 1;
- *pfDelete2 = 1;
- }
- else if ( argc == util_optind + 2 )
- {
- pNtk1 = Io_Read( argv[util_optind], Io_ReadFileType(argv[util_optind]), fCheck, 0 );
- if ( pNtk1 == NULL )
- return 0;
- pNtk2 = Io_Read( argv[util_optind+1], Io_ReadFileType(argv[util_optind+1]), fCheck, 0 );
- if ( pNtk2 == NULL )
- {
- Abc_NtkDelete( pNtk1 );
- return 0;
- }
- *pfDelete1 = 1;
- *pfDelete2 = 1;
- }
- else
- {
- fprintf( pErr, "Wrong number of arguments.\n" );
- return 0;
- }
- // make sure the networks are strashed
- if ( !Abc_NtkIsStrash(pNtk1) )
- {
- pNtkTemp = Abc_NtkStrash( pNtk1, 0, 1, 0 );
- if ( *pfDelete1 )
- Abc_NtkDelete( pNtk1 );
- pNtk1 = pNtkTemp;
- *pfDelete1 = 1;
- }
- if ( !Abc_NtkIsStrash(pNtk2) )
- {
- pNtkTemp = Abc_NtkStrash( pNtk2, 0, 1, 0 );
- if ( *pfDelete2 )
- Abc_NtkDelete( pNtk2 );
- pNtk2 = pNtkTemp;
- *pfDelete2 = 1;
- }
- *ppNtk1 = pNtk1;
- *ppNtk2 = pNtk2;
- return 1;
- }
- /**Function*************************************************************
- Synopsis [Returns 1 if it is an AIG with choice nodes.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void Abc_NodeCollectFanins( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
- {
- Abc_Obj_t * pFanin;
- int i;
- Vec_PtrClear(vNodes);
- Abc_ObjForEachFanin( pNode, pFanin, i )
- Vec_PtrPush( vNodes, pFanin );
- }
- /**Function*************************************************************
- Synopsis [Returns 1 if it is an AIG with choice nodes.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- void Abc_NodeCollectFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
- {
- Abc_Obj_t * pFanout;
- int i;
- Vec_PtrClear(vNodes);
- Abc_ObjForEachFanout( pNode, pFanout, i )
- Vec_PtrPush( vNodes, pFanout );
- }
- /**Function*************************************************************
- Synopsis [Collects all latches in the network.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- Vec_Ptr_t * Abc_NtkCollectLatches( Abc_Ntk_t * pNtk )
- {
- Vec_Ptr_t * vLatches;
- Abc_Obj_t * pObj;
- int i;
- vLatches = Vec_PtrAlloc( 10 );
- Abc_NtkForEachObj( pNtk, pObj, i )
- Vec_PtrPush( vLatches, pObj );
- return vLatches;
- }
- /**Function*************************************************************
- Synopsis [Procedure used for sorting the nodes in increasing order of levels.]
- Description []
-
- SideEffects []
- SeeAlso []
- ***********************************************************************/
- int Abc_NodeCompareLevelsIncrease( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
- {
- int Diff = Abc_ObjRegular(*pp1)->Level - Abc_ObjRegular(*pp2)->Level;
- if ( Diff < 0 )
- return -1;
- if ( Diff > 0 )
- return 1;
- Diff = Abc_ObjRegular(*pp1)->Id - Abc_ObjRegular(*pp2)->Id;
- if ( Diff < 0 )
- return -1;
- if ( Diff > 0 )
- return 1;
- return 0;
- }
- /**Function*************************************************************
- Syno…
Large files files are truncated, but you can click here to view the full file