/**Function************************************************************* Synopsis [Retimes node forward by one latch.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_ObjRetimeForward( Abc_Obj_t * pObj ) { Abc_Obj_t * pFanout; int Init0, Init1, Init, i; assert( Abc_ObjFaninNum(pObj) == 2 ); assert( Seq_ObjFaninL0(pObj) >= 1 ); assert( Seq_ObjFaninL1(pObj) >= 1 ); // remove the init values from the fanins Init0 = Seq_NodeDeleteFirst( pObj, 0 ); Init1 = Seq_NodeDeleteFirst( pObj, 1 ); assert( Init0 != ABC_INIT_NONE ); assert( Init1 != ABC_INIT_NONE ); // take into account the complements in the node if ( Abc_ObjFaninC0(pObj) ) { if ( Init0 == ABC_INIT_ZERO ) Init0 = ABC_INIT_ONE; else if ( Init0 == ABC_INIT_ONE ) Init0 = ABC_INIT_ZERO; } if ( Abc_ObjFaninC1(pObj) ) { if ( Init1 == ABC_INIT_ZERO ) Init1 = ABC_INIT_ONE; else if ( Init1 == ABC_INIT_ONE ) Init1 = ABC_INIT_ZERO; } // compute the value at the output of the node if ( Init0 == ABC_INIT_ZERO || Init1 == ABC_INIT_ZERO ) Init = ABC_INIT_ZERO; else if ( Init0 == ABC_INIT_ONE && Init1 == ABC_INIT_ONE ) Init = ABC_INIT_ONE; else Init = ABC_INIT_DC; // make sure the label is clean Abc_ObjForEachFanout( pObj, pFanout, i ) assert( pFanout->fMarkC == 0 ); // add the init values to the fanouts Abc_ObjForEachFanout( pObj, pFanout, i ) { if ( pFanout->fMarkC ) continue; pFanout->fMarkC = 1; if ( Abc_ObjFaninId0(pFanout) != Abc_ObjFaninId1(pFanout) ) Seq_NodeInsertLast( pFanout, Abc_ObjFanoutEdgeNum(pObj, pFanout), Init ); else { assert( Abc_ObjFanin0(pFanout) == pObj ); Seq_NodeInsertLast( pFanout, 0, Init ); Seq_NodeInsertLast( pFanout, 1, Init ); } } // clean the label Abc_ObjForEachFanout( pObj, pFanout, i ) pFanout->fMarkC = 0; }
/**Function************************************************************* Synopsis [Insert the last Lat on the edge.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Seq_NodeDupLats( Abc_Obj_t * pObjNew, Abc_Obj_t * pObj, int Edge ) { Seq_Lat_t * pRing, * pLat; int i, nLatches; pRing = Seq_NodeGetRing( pObj, Edge ); if ( pRing == NULL ) return; nLatches = Seq_NodeCountLats( pObj, Edge ); for ( i = 0, pLat = pRing; i < nLatches; i++, pLat = pLat->pNext ) Seq_NodeInsertLast( pObjNew, Edge, Seq_LatInit(pLat) ); }