abc/src/base/abc/abcNtk.c

714 lines
22 KiB
C

/**CFile****************************************************************
FileName [abcNtk.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Network creation/duplication/deletion procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcNtk.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "abcInt.h"
#include "main.h"
#include "mio.h"
#include "seqInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Creates a new Ntk.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func )
{
Abc_Ntk_t * pNtk;
pNtk = ALLOC( Abc_Ntk_t, 1 );
memset( pNtk, 0, sizeof(Abc_Ntk_t) );
pNtk->ntkType = Type;
pNtk->ntkFunc = Func;
// start the object storage
pNtk->vObjs = Vec_PtrAlloc( 100 );
pNtk->vLats = Vec_PtrAlloc( 100 );
pNtk->vCutSet = Vec_PtrAlloc( 100 );
pNtk->vCis = Vec_PtrAlloc( 100 );
pNtk->vCos = Vec_PtrAlloc( 100 );
pNtk->vPtrTemp = Vec_PtrAlloc( 100 );
pNtk->vIntTemp = Vec_IntAlloc( 100 );
pNtk->vStrTemp = Vec_StrAlloc( 100 );
// start the hash table
pNtk->tName2Net = stmm_init_table(strcmp, stmm_strhash);
pNtk->tObj2Name = stmm_init_table(stmm_ptrcmp, stmm_ptrhash);
// start the memory managers
pNtk->pMmNames = Extra_MmFlexStart();
pNtk->pMmObj = Extra_MmFixedStart( sizeof(Abc_Obj_t) );
pNtk->pMmStep = Extra_MmStepStart( ABC_NUM_STEPS );
// get ready to assign the first Obj ID
pNtk->nTravIds = 1;
// start the functionality manager
if ( Abc_NtkHasSop(pNtk) )
pNtk->pManFunc = Extra_MmFlexStart();
else if ( Abc_NtkHasBdd(pNtk) )
pNtk->pManFunc = Cudd_Init( 20, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
else if ( Abc_NtkHasAig(pNtk) )
{
if ( Abc_NtkIsStrash(pNtk) )
pNtk->pManFunc = Abc_AigAlloc( pNtk );
else
pNtk->pManFunc = Seq_Create( pNtk );
}
else if ( Abc_NtkHasMapping(pNtk) )
pNtk->pManFunc = Abc_FrameReadLibGen();
else
assert( 0 );
// allocate constant node
if ( !Abc_NtkIsNetlist(pNtk) )
{
Abc_NodeCreateConst1( pNtk );
// do not count this node towards the total number of nodes
pNtk->nNodes -= 1;
}
else
Vec_PtrPush( pNtk->vObjs, NULL );
return pNtk;
}
/**Function*************************************************************
Synopsis [Starts a new network using existing network as a model.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func )
{
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pObjNew;
int i;
if ( pNtk == NULL )
return NULL;
// start the network
pNtkNew = Abc_NtkAlloc( Type, Func );
// duplicate the name and the spec
pNtkNew->pName = util_strsav(pNtk->pName);
pNtkNew->pSpec = util_strsav(pNtk->pSpec);
// clean the node copy fields
Abc_NtkForEachNode( pNtk, pObj, i )
pObj->pCopy = NULL;
// map the constant nodes
if ( Abc_NtkConst1(pNtk) )
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
// clone the PIs/POs/latches
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NtkDupObj(pNtkNew, pObj);
Abc_NtkForEachPo( pNtk, pObj, i )
Abc_NtkDupObj(pNtkNew, pObj);
Abc_NtkForEachLatch( pNtk, pObj, i )
{
pObjNew = Abc_NtkDupObj(pNtkNew, pObj);
Vec_PtrPush( pNtkNew->vCis, pObjNew );
Vec_PtrPush( pNtkNew->vCos, pObjNew );
}
// transfer the names
Abc_NtkDupCioNamesTable( pNtk, pNtkNew );
Abc_ManTimeDup( pNtk, pNtkNew );
// check that the CI/CO/latches are copied correctly
assert( Abc_NtkCiNum(pNtk) == Abc_NtkCiNum(pNtkNew) );
assert( Abc_NtkCoNum(pNtk) == Abc_NtkCoNum(pNtkNew) );
assert( Abc_NtkLatchNum(pNtk) == Abc_NtkLatchNum(pNtkNew) );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Finalizes the network using the existing network as a model.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
{
Abc_Obj_t * pObj, * pDriver, * pDriverNew;
int i;
// set the COs of the strashed network
Abc_NtkForEachCo( pNtk, pObj, i )
{
pDriver = Abc_ObjFanin0Ntk( Abc_ObjFanin0(pObj) );
pDriverNew = Abc_ObjNotCond(pDriver->pCopy, Abc_ObjFaninC0(pObj));
Abc_ObjAddFanin( pObj->pCopy, pDriverNew );
}
}
/**Function*************************************************************
Synopsis [Finalizes the network using the existing network as a model.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFinalizeRegular( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
{
Abc_Obj_t * pObj, * pDriver, * pDriverNew;
int i;
// set the COs of the strashed network
Abc_NtkForEachCo( pNtk, pObj, i )
{
pDriver = Abc_ObjFanin0Ntk( Abc_ObjFanin0(pObj) );
pDriverNew = pDriver->pCopy;
Abc_ObjAddFanin( pObj->pCopy, pDriverNew );
}
}
/**Function*************************************************************
Synopsis [Finalizes the network adding latches to CI/CO lists and creates their names.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFinalizeLatches( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pLatch;
int i;
// set the COs of the strashed network
Abc_NtkForEachLatch( pNtk, pLatch, i )
{
Vec_PtrPush( pNtk->vCis, pLatch );
Vec_PtrPush( pNtk->vCos, pLatch );
Abc_NtkLogicStoreName( pLatch, Abc_ObjNameSuffix(pLatch, "L") );
}
}
/**Function*************************************************************
Synopsis [Starts a new network using existing network as a model.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkStartRead( char * pName )
{
Abc_Ntk_t * pNtkNew;
// allocate the empty network
pNtkNew = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP );
// set the specs
pNtkNew->pName = util_strsav( Extra_FileNameGeneric(pName) );
pNtkNew->pSpec = util_strsav( Extra_FileNameGeneric(pName) );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Finalizes the network using the existing network as a model.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pLatch;
int i;
assert( Abc_NtkIsNetlist(pNtk) );
// fix the net drivers
Abc_NtkFixNonDrivenNets( pNtk );
// create the names table
Abc_NtkCreateCioNamesTable( pNtk );
// add latches to the CI/CO arrays
Abc_NtkForEachLatch( pNtk, pLatch, i )
{
Vec_PtrPush( pNtk->vCis, pLatch );
Vec_PtrPush( pNtk->vCos, pLatch );
}
}
/**Function*************************************************************
Synopsis [Duplicate the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pFanin;
int i, k;
if ( pNtk == NULL )
return NULL;
// start the network
pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
// copy the internal nodes
if ( Abc_NtkIsStrash(pNtk) )
{
// copy the AND gates
Abc_AigForEachAnd( pNtk, pObj, i )
pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
// relink the choice nodes
Abc_AigForEachAnd( pNtk, pObj, i )
if ( pObj->pData )
pObj->pCopy->pData = ((Abc_Obj_t *)pObj->pData)->pCopy;
// relink the CO nodes
Abc_NtkForEachCo( pNtk, pObj, i )
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) );
// get the number of nodes before and after
if ( Abc_NtkNodeNum(pNtk) != Abc_NtkNodeNum(pNtkNew) )
printf( "Warning: Structural hashing during duplication reduced %d nodes (this is a minor bug).\n",
Abc_NtkNodeNum(pNtk) - Abc_NtkNodeNum(pNtkNew) );
}
else if ( Abc_NtkIsSeq(pNtk) )
{
// start the storage for initial states
Seq_Resize( pNtkNew->pManFunc, Abc_NtkObjNumMax(pNtk) );
// copy the nodes
Abc_NtkForEachObj( pNtk, pObj, i )
if ( pObj->pCopy == NULL )
{
Abc_NtkDupObj(pNtkNew, pObj);
pObj->pCopy->Level = pObj->Level;
pObj->pCopy->fPhase = pObj->fPhase;
}
// connect the nodes
Abc_NtkForEachObj( pNtk, pObj, i )
{
Abc_ObjForEachFanin( pObj, pFanin, k )
{
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
if ( Abc_ObjFaninC(pObj, k) )
Abc_ObjSetFaninC( pObj->pCopy, k );
if ( Seq_ObjFaninL(pObj, k) )
Seq_NodeDupLats( pObj->pCopy, pObj, k );
}
}
// relink the choice nodes
Abc_AigForEachAnd( pNtk, pObj, i )
if ( pObj->pData )
pObj->pCopy->pData = ((Abc_Obj_t *)pObj->pData)->pCopy;
// copy the cutset
Abc_SeqForEachCutsetNode( pNtk, pObj, i )
Vec_PtrPush( pNtkNew->vCutSet, pObj->pCopy );
}
else
{
// duplicate the nets and nodes (CIs/COs/latches already dupped)
Abc_NtkForEachObj( pNtk, pObj, i )
if ( pObj->pCopy == NULL )
Abc_NtkDupObj(pNtkNew, pObj);
// reconnect all objects (no need to transfer attributes on edges)
Abc_NtkForEachObj( pNtk, pObj, i )
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
}
// duplicate the EXDC Ntk
if ( pNtk->pExdc )
pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Creates the network composed of one output.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkCreateOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAllCis )
{
Vec_Ptr_t * vNodes;
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pFanin;
char Buffer[1000];
int i, k;
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) );
assert( Abc_ObjIsCo(pNode) );
// start the network
pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc );
// set the name
sprintf( Buffer, "%s_%s", pNtk->pName, Abc_ObjName(pNode) );
pNtkNew->pName = util_strsav(Buffer);
// establish connection between the constant nodes
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
// collect the nodes in the TFI of the output (mark the TFI)
vNodes = Abc_NtkDfsNodes( pNtk, &pNode, 1 );
// create the PIs
Abc_NtkForEachCi( pNtk, pObj, i )
{
if ( fUseAllCis || Abc_NodeIsTravIdCurrent(pObj) ) // TravId is set by DFS
{
pObj->pCopy = Abc_NtkCreatePi(pNtkNew);
Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) );
}
}
// copy the nodes
Vec_PtrForEachEntry( vNodes, pObj, i )
{
// if it is an AIG, add to the hash table
if ( Abc_NtkIsStrash(pNtk) )
{
pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
}
else
{
Abc_NtkDupObj( pNtkNew, pObj );
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
}
}
Vec_PtrFree( vNodes );
// add the PO corresponding to this output
pNode->pCopy = Abc_NtkCreatePo( pNtkNew );
Abc_ObjAddFanin( pNode->pCopy, Abc_ObjFanin0(pNode)->pCopy );
Abc_NtkLogicStoreName( pNode->pCopy, Abc_ObjName(pNode) );
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkCreateOutput(): Network check has failed.\n" );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Creates the miter composed of one multi-output cone.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * vValues )
{
Vec_Ptr_t * vNodes;
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pFinal, * pOther, * pNodePo;
int i;
assert( Abc_NtkIsLogic(pNtk) );
// start the network
Abc_NtkCleanCopy( pNtk );
pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG );
pNtkNew->pName = util_strsav(pNtk->pName);
// collect the nodes in the TFI of the output
vNodes = Abc_NtkDfsNodes( pNtk, (Abc_Obj_t **)vRoots->pArray, vRoots->nSize );
// create the PIs
Abc_NtkForEachCi( pNtk, pObj, i )
{
pObj->pCopy = Abc_NtkCreatePi(pNtkNew);
Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) );
}
// copy the nodes
Vec_PtrForEachEntry( vNodes, pObj, i )
pObj->pCopy = Abc_NodeStrash( pNtkNew, pObj );
Vec_PtrFree( vNodes );
// add the PO
pFinal = Abc_NtkConst1( pNtkNew );
Vec_PtrForEachEntry( vRoots, pObj, i )
{
if ( Abc_ObjIsCo(pObj) )
pOther = Abc_ObjFanin0(pObj)->pCopy;
else
pOther = pObj->pCopy;
if ( Vec_IntEntry(vValues, i) == 0 )
pOther = Abc_ObjNot(pOther);
pFinal = Abc_AigAnd( pNtkNew->pManFunc, pFinal, pOther );
}
// add the PO corresponding to this output
pNodePo = Abc_NtkCreatePo( pNtkNew );
Abc_ObjAddFanin( pNodePo, pFinal );
Abc_NtkLogicStoreName( pNodePo, "miter" );
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkCreateCone(): Network check has failed.\n" );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Creates the network composed of one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkCreateFromNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode )
{
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pFanin, * pNodePo;
int i;
// start the network
pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc );
pNtkNew->pName = util_strsav(Abc_ObjName(pNode));
// add the PIs corresponding to the fanins of the node
Abc_ObjForEachFanin( pNode, pFanin, i )
{
pFanin->pCopy = Abc_NtkCreatePi( pNtkNew );
Abc_NtkLogicStoreName( pFanin->pCopy, Abc_ObjName(pFanin) );
}
// duplicate and connect the node
pNode->pCopy = Abc_NtkDupObj( pNtkNew, pNode );
Abc_ObjForEachFanin( pNode, pFanin, i )
Abc_ObjAddFanin( pNode->pCopy, pFanin->pCopy );
// create the only PO
pNodePo = Abc_NtkCreatePo( pNtkNew );
Abc_ObjAddFanin( pNodePo, pNode->pCopy );
Abc_NtkLogicStoreName( pNodePo, Abc_ObjName(pNode) );
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkCreateFromNode(): Network check has failed.\n" );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Creates the network composed of one node with the given SOP.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkCreateWithNode( char * pSop )
{
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pFanin, * pNode, * pNodePo;
Vec_Ptr_t * vNames;
int i, nVars;
// start the network
pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP );
pNtkNew->pName = util_strsav("ex");
// create PIs
Vec_PtrPush( pNtkNew->vObjs, NULL );
nVars = Abc_SopGetVarNum( pSop );
vNames = Abc_NodeGetFakeNames( nVars );
for ( i = 0; i < nVars; i++ )
Abc_NtkLogicStoreName( Abc_NtkCreatePi(pNtkNew), Vec_PtrEntry(vNames, i) );
Abc_NodeFreeNames( vNames );
// create the node, add PIs as fanins, set the function
pNode = Abc_NtkCreateNode( pNtkNew );
Abc_NtkForEachPi( pNtkNew, pFanin, i )
Abc_ObjAddFanin( pNode, pFanin );
pNode->pData = Abc_SopRegister( pNtkNew->pManFunc, pSop );
// create the only PO
pNodePo = Abc_NtkCreatePo(pNtkNew);
Abc_ObjAddFanin( pNodePo, pNode );
Abc_NtkLogicStoreName( pNodePo, "F" );
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkCreateWithNode(): Network check has failed.\n" );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Deletes the Ntk.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkDelete( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int TotalMemory, i;
int LargePiece = (4 << ABC_NUM_STEPS);
if ( pNtk == NULL )
return;
// make sure all the marks are clean
Abc_NtkForEachObj( pNtk, pObj, i )
{
// free large fanout arrays
if ( pObj->vFanouts.nCap * 4 > LargePiece )
FREE( pObj->vFanouts.pArray );
// these flags should be always zero
// if this is not true, something is wrong somewhere
assert( pObj->fMarkA == 0 );
assert( pObj->fMarkB == 0 );
assert( pObj->fMarkC == 0 );
}
// dereference the BDDs
if ( Abc_NtkHasBdd(pNtk) )
Abc_NtkForEachNode( pNtk, pObj, i )
Cudd_RecursiveDeref( pNtk->pManFunc, pObj->pData );
FREE( pNtk->pName );
FREE( pNtk->pSpec );
// copy the EXDC Ntk
if ( pNtk->pExdc )
Abc_NtkDelete( pNtk->pExdc );
// free the arrays
Vec_PtrFree( pNtk->vCis );
Vec_PtrFree( pNtk->vCos );
Vec_PtrFree( pNtk->vObjs );
Vec_PtrFree( pNtk->vLats );
Vec_PtrFree( pNtk->vCutSet );
Vec_PtrFree( pNtk->vPtrTemp );
Vec_IntFree( pNtk->vIntTemp );
Vec_StrFree( pNtk->vStrTemp );
if ( pNtk->pModel ) free( pNtk->pModel );
// free the hash table of Obj name into Obj ID
stmm_free_table( pNtk->tName2Net );
stmm_free_table( pNtk->tObj2Name );
TotalMemory = 0;
TotalMemory += Extra_MmFlexReadMemUsage(pNtk->pMmNames);
TotalMemory += Extra_MmFixedReadMemUsage(pNtk->pMmObj);
TotalMemory += Extra_MmStepReadMemUsage(pNtk->pMmStep);
// fprintf( stdout, "The total memory allocated internally by the network = %0.2f Mb.\n", ((double)TotalMemory)/(1<<20) );
// free the storage
Extra_MmFlexStop ( pNtk->pMmNames, 0 );
Extra_MmFixedStop( pNtk->pMmObj, 0 );
Extra_MmStepStop ( pNtk->pMmStep, 0 );
// free the timing manager
if ( pNtk->pManTime )
Abc_ManTimeStop( pNtk->pManTime );
// start the functionality manager
if ( Abc_NtkHasSop(pNtk) )
Extra_MmFlexStop( pNtk->pManFunc, 0 );
else if ( Abc_NtkHasBdd(pNtk) )
Extra_StopManager( pNtk->pManFunc );
else if ( Abc_NtkHasAig(pNtk) )
{
if ( Abc_NtkIsStrash(pNtk) )
Abc_AigFree( pNtk->pManFunc );
else
Seq_Delete( pNtk->pManFunc );
}
else if ( !Abc_NtkHasMapping(pNtk) )
assert( 0 );
free( pNtk );
}
/**Function*************************************************************
Synopsis [Reads the verilog file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vNets;
Abc_Obj_t * pNet, * pNode;
int i;
// check for non-driven nets
vNets = Vec_PtrAlloc( 100 );
Abc_NtkForEachNet( pNtk, pNet, i )
{
if ( Abc_ObjFaninNum(pNet) > 0 )
continue;
// add the constant 0 driver
pNode = Abc_NtkCreateNode( pNtk );
// set the constant function
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, " 0\n") );
// add the fanout net
Abc_ObjAddFanin( pNet, pNode );
// add the net to those for which the warning will be printed
Vec_PtrPush( vNets, pNet->pData );
}
// print the warning
if ( vNets->nSize > 0 )
{
printf( "Constant-zero drivers were added to %d non-driven nets:\n", vNets->nSize );
for ( i = 0; i < vNets->nSize; i++ )
{
if ( i == 0 )
printf( "%s", vNets->pArray[i] );
else if ( i == 1 )
printf( ", %s", vNets->pArray[i] );
else if ( i == 2 )
{
printf( ", %s, etc.", vNets->pArray[i] );
break;
}
}
printf( "\n" );
}
Vec_PtrFree( vNets );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////