diff options
Diffstat (limited to 'src/aig/ntl/ntlInsert.c')
-rw-r--r-- | src/aig/ntl/ntlInsert.c | 185 |
1 files changed, 184 insertions, 1 deletions
diff --git a/src/aig/ntl/ntlInsert.c b/src/aig/ntl/ntlInsert.c index eb967bdc..750eb8f7 100644 --- a/src/aig/ntl/ntlInsert.c +++ b/src/aig/ntl/ntlInsert.c @@ -290,6 +290,190 @@ void Ntl_ManFindDriver( Ntl_Man_t * p, char * pName ) SeeAlso [] ***********************************************************************/ +Ntl_Man_t * Ntl_ManInsertNtk2( Ntl_Man_t * p, Nwk_Man_t * pNtk ) +{ + int fWriteConstants = 1; + char Buffer[1000]; + Vec_Ptr_t * vObjs; + Vec_Int_t * vTruth; + Vec_Int_t * vCover; + Ntl_Mod_t * pRoot; + Ntl_Obj_t * pNode; + Ntl_Net_t * pNet, * pNetCo; + Nwk_Obj_t * pObj, * pFanin; + int i, k, nDigits; + unsigned * pTruth; + assert( Vec_PtrSize(p->vCis) == Nwk_ManCiNum(pNtk) ); + assert( Vec_PtrSize(p->vCos) == Nwk_ManCoNum(pNtk) ); + p = Ntl_ManStartFrom( p ); + pRoot = Ntl_ManRootModel( p ); + assert( Ntl_ModelNodeNum(pRoot) == 0 ); + // set the correspondence between the PI/PO nodes + Ntl_ManForEachCiNet( p, pNet, i ) + Nwk_ManCi( pNtk, i )->pCopy = pNet; + // create a new node for each LUT + vTruth = Vec_IntAlloc( 1 << 16 ); + vCover = Vec_IntAlloc( 1 << 16 ); + nDigits = Aig_Base10Log( Nwk_ManNodeNum(pNtk) ); + // go through the nodes in the topological order + vObjs = Nwk_ManDfs( pNtk ); + Vec_PtrForEachEntry( vObjs, pObj, i ) + { + if ( !Nwk_ObjIsNode(pObj) ) + continue; +/* + if ( fWriteConstants && Nwk_ObjFaninNum(pObj) == 0 ) + { + pObj->pCopy = NULL; + continue; + } +*/ + // skip constant drivers if they only drive COs + if ( fWriteConstants && Nwk_ObjFaninNum(pObj) == 0 ) + { + Nwk_Obj_t * pFanout; + int i; + Nwk_ObjForEachFanout( pObj, pFanout, i ) + if ( Nwk_ObjIsNode(pFanout) ) + break; + if ( i == Nwk_ObjFanoutNum(pObj) ) + { + pObj->pCopy = NULL; + continue; + } + } + + pNode = Ntl_ModelCreateNode( pRoot, Nwk_ObjFaninNum(pObj) ); + pTruth = Hop_ManConvertAigToTruth( pNtk->pManHop, Hop_Regular(pObj->pFunc), Nwk_ObjFaninNum(pObj), vTruth, 0 ); + if ( Hop_IsComplement(pObj->pFunc) ) + Kit_TruthNot( pTruth, pTruth, Nwk_ObjFaninNum(pObj) ); + if ( !Kit_TruthIsConst0(pTruth, Nwk_ObjFaninNum(pObj)) && !Kit_TruthIsConst1(pTruth, Nwk_ObjFaninNum(pObj)) ) + { + Nwk_ObjForEachFanin( pObj, pFanin, k ) + { + pNet = pFanin->pCopy; + if ( pNet == NULL ) + { + printf( "Ntl_ManInsertNtk(): Internal error: Net not found.\n" ); + return 0; + } + Ntl_ObjSetFanin( pNode, pNet, k ); + } + } + else if ( Kit_TruthIsConst0(pTruth, Nwk_ObjFaninNum(pObj)) ) + { + pObj->pFunc = Hop_ManConst0(pNtk->pManHop); + pNode->nFanins = 0; + } + else if ( Kit_TruthIsConst1(pTruth, Nwk_ObjFaninNum(pObj)) ) + { + pObj->pFunc = Hop_ManConst1(pNtk->pManHop); + pNode->nFanins = 0; + } + pNode->pSop = Kit_PlaFromTruth( p->pMemSops, pTruth, Nwk_ObjFaninNum(pObj), vCover ); + sprintf( Buffer, "lut%0*d", nDigits, i ); + if ( (pNet = Ntl_ModelFindNet( pRoot, Buffer )) ) + { + printf( "Ntl_ManInsertNtk(): Internal error: Intermediate net name is not unique.\n" ); + return 0; + } + pNet = Ntl_ModelFindOrCreateNet( pRoot, Buffer ); + if ( !Ntl_ModelSetNetDriver( pNode, pNet ) ) + { + printf( "Ntl_ManInsertNtk(): Internal error: Net has more than one fanin.\n" ); + return 0; + } + pObj->pCopy = pNet; + } + Vec_PtrFree( vObjs ); + Vec_IntFree( vCover ); + Vec_IntFree( vTruth ); + // mark the nets driving special boxes + if ( p->pNalR ) + p->pNalR( p ); + // mark CIs and outputs of the registers + Ntl_ManForEachCiNet( p, pNetCo, i ) + pNetCo->fMark = 1; + // update the CO pointers + Ntl_ManForEachCoNet( p, pNetCo, i ) + { + if ( pNetCo->fMark ) + continue; + pNetCo->fMark = 1; + // get the corresponding PO and its driver + pObj = Nwk_ManCo( pNtk, i ); + pFanin = Nwk_ObjFanin0( pObj ); + // get the net driving this PO + pNet = pFanin->pCopy; + if ( pNet == NULL ) // constant net + { + assert( fWriteConstants ); + pNode = Ntl_ModelCreateNode( pRoot, 0 ); + pNode->pSop = pObj->fInvert? Ntl_ManStoreSop( p->pMemSops, " 0\n" ) : Ntl_ManStoreSop( p->pMemSops, " 1\n" ); + } + else + if ( Nwk_ObjFanoutNum(pFanin) == 1 && Ntl_ObjIsNode(pNet->pDriver) && !pNet->fMark2 ) + { + pNode = pNet->pDriver; + if ( !Ntl_ModelClearNetDriver( pNode, pNet ) ) + { + printf( "Ntl_ManInsertNtk(): Internal error! Net already has no driver.\n" ); + return NULL; + } + // remove this net + Ntl_ModelDeleteNet( pRoot, pNet ); + Vec_PtrWriteEntry( pRoot->vNets, pNet->NetId, NULL ); + // update node's function + if ( pObj->fInvert ) + Kit_PlaComplement( pNode->pSop ); + } + else + { +/* + if ( fWriteConstants && Ntl_ObjFaninNum(pNet->pDriver) == 0 ) + { + pNode = Ntl_ModelCreateNode( pRoot, 0 ); + pNode->pSop = pObj->fInvert? Ntl_ManStoreSop( p->pMemSops, " 0\n" ) : Ntl_ManStoreSop( p->pMemSops, " 1\n" ); + } + else +*/ + { +// assert( Ntl_ObjFaninNum(pNet->pDriver) != 0 ); + pNode = Ntl_ModelCreateNode( pRoot, 1 ); + pNode->pSop = pObj->fInvert? Ntl_ManStoreSop( p->pMemSops, "0 1\n" ) : Ntl_ManStoreSop( p->pMemSops, "1 1\n" ); + Ntl_ObjSetFanin( pNode, pNet, 0 ); + } + } + // update the CO driver net + assert( pNetCo->pDriver == NULL ); + if ( !Ntl_ModelSetNetDriver( pNode, pNetCo ) ) + { + printf( "Ntl_ManInsertNtk(): Internal error: PO net has more than one fanin.\n" ); + return NULL; + } + } + // clean CI/CO marks + Ntl_ManUnmarkCiCoNets( p ); + if ( !Ntl_ManCheck( p ) ) + { + printf( "Ntl_ManInsertNtk: The check has failed for design %s.\n", p->pName ); + return NULL; + } + return p; +} + + +/**Function************************************************************* + + Synopsis [Inserts the given mapping into the netlist.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ Ntl_Man_t * Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk ) { char Buffer[1000]; @@ -418,7 +602,6 @@ Ntl_Man_t * Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk ) return p; } - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// |