/**Function************************************************************* Synopsis [Insert the last Lat on the edge.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Seq_NodeInsertLast( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init ) { Seq_Lat_t * pLat, * pRing, * pPrev; pRing = Seq_NodeGetRing( pObj, Edge ); pLat = Seq_NodeCreateLat( pObj ); if ( pRing == NULL ) { Seq_LatSetPrev( pLat, pLat ); Seq_LatSetNext( pLat, pLat ); Seq_NodeSetRing( pObj, Edge, pLat ); } else { pPrev = Seq_LatPrev( pRing ); Seq_LatSetPrev( pLat, pPrev ); Seq_LatSetNext( pPrev, pLat ); Seq_LatSetPrev( pRing, pLat ); Seq_LatSetNext( pLat, pRing ); } Seq_LatSetInit( pLat, Init ); Seq_ObjAddFaninL( pObj, Edge, 1 ); }
/**Function************************************************************* Synopsis [Insert the first Lat on the edge.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Seq_NodeInsertFirst( Abc_Obj_t * pObj, int Edge, Abc_InitType_t Init ) { Seq_Lat_t * pLat, * pRing, * pPrev; pRing = Seq_NodeGetRing( pObj, Edge ); pLat = Seq_NodeCreateLat( pObj ); if ( pRing == NULL ) { Seq_LatSetPrev( pLat, pLat ); Seq_LatSetNext( pLat, pLat ); Seq_NodeSetRing( pObj, Edge, pLat ); } else { pPrev = Seq_LatPrev( pRing ); Seq_LatSetPrev( pLat, pPrev ); Seq_LatSetNext( pPrev, pLat ); Seq_LatSetPrev( pRing, pLat ); Seq_LatSetNext( pLat, pRing ); Seq_NodeSetRing( pObj, Edge, pLat ); // rotate the ring to make pLat the first } Seq_LatSetInit( pLat, Init ); Seq_ObjAddFaninL( pObj, Edge, 1 ); assert( pLat->pLatch == NULL ); }
/**Function************************************************************* Synopsis [Maps virtual latches into real latches.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Obj_t * Seq_NtkShareLatches_rec( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj, Seq_Lat_t * pRing, int nLatch, stmm_table * tLatchMap ) { Abc_Obj_t * pLatch, * pFanin; Abc_InitType_t Init; unsigned Key; if ( nLatch == 0 ) return pObj; assert( pRing->pLatch == NULL ); // get the latch on the previous level pFanin = Seq_NtkShareLatches_rec( pNtk, pObj, Seq_LatNext(pRing), nLatch - 1, tLatchMap ); // get the initial state Init = Seq_LatInit( pRing ); // check if the latch with this initial state exists Key = Seq_NtkShareLatchesKey( pFanin, Init ); if ( stmm_lookup( tLatchMap, (char *)Key, (char **)&pLatch ) ) return pRing->pLatch = pLatch; // does not exist if ( Init != ABC_INIT_DC ) { // check if the don't-care exists Key = Seq_NtkShareLatchesKey( pFanin, ABC_INIT_DC ); if ( stmm_lookup( tLatchMap, (char *)Key, (char **)&pLatch ) ) // yes { // update the table stmm_delete( tLatchMap, (char **)&Key, (char **)&pLatch ); Key = Seq_NtkShareLatchesKey( pFanin, Init ); stmm_insert( tLatchMap, (char *)Key, (char *)pLatch ); // change don't-care to the given value pLatch->pData = (void *)Init; return pRing->pLatch = pLatch; } // add the latch with this value pLatch = Abc_NtkCreateLatch( pNtk ); pLatch->pData = (void *)Init; Abc_ObjAddFanin( pLatch, pFanin ); // add it to the table Key = Seq_NtkShareLatchesKey( pFanin, Init ); stmm_insert( tLatchMap, (char *)Key, (char *)pLatch ); return pRing->pLatch = pLatch; } // the init value is the don't-care // check if care values exist Key = Seq_NtkShareLatchesKey( pFanin, ABC_INIT_ZERO ); if ( stmm_lookup( tLatchMap, (char *)Key, (char **)&pLatch ) ) { Seq_LatSetInit( pRing, ABC_INIT_ZERO ); return pRing->pLatch = pLatch; } Key = Seq_NtkShareLatchesKey( pFanin, ABC_INIT_ONE ); if ( stmm_lookup( tLatchMap, (char *)Key, (char **)&pLatch ) ) { Seq_LatSetInit( pRing, ABC_INIT_ONE ); return pRing->pLatch = pLatch; } // create the don't-care latch pLatch = Abc_NtkCreateLatch( pNtk ); pLatch->pData = (void *)ABC_INIT_DC; Abc_ObjAddFanin( pLatch, pFanin ); // add it to the table Key = Seq_NtkShareLatchesKey( pFanin, ABC_INIT_DC ); stmm_insert( tLatchMap, (char *)Key, (char *)pLatch ); return pRing->pLatch = pLatch; }