Abc_NtkForEachObj( pNtk, pObj, i ) { // skip constants, PIs, and latches if ( Abc_ObjFaninNum(pObj) == 0 || Abc_ObjIsLatch(pObj) ) continue; // process the first fanin Vec_IntClear( vInitValues ); pFaninNew = Abc_NodeAigToSeq( pObj->pCopy, pObj, 0, vInitValues ); Abc_ObjAddFanin( pObj->pCopy, pFaninNew ); // store the initial values Vec_IntForEachEntry( vInitValues, Init, k ) Seq_NodeInsertFirst( pObj->pCopy, 0, Init ); // skip single-input nodes if ( Abc_ObjFaninNum(pObj) == 1 ) continue; // process the second fanin Vec_IntClear( vInitValues ); pFaninNew = Abc_NodeAigToSeq( pObj->pCopy, pObj, 1, vInitValues ); Abc_ObjAddFanin( pObj->pCopy, pFaninNew ); // store the initial values Vec_IntForEachEntry( vInitValues, Init, k ) Seq_NodeInsertFirst( pObj->pCopy, 1, Init ); }
/**Function************************************************************* Synopsis [Transforms the node to take fanout sharing into account.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Seq_NodeShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr_t * vNodes ) { Vec_Int_t * vNums = Seq_ObjLNums( pNode ); Vec_Ptr_t * vInits = Seq_NodeLats( pNode ); Abc_Obj_t * pFanout, * pBuffer; Abc_InitType_t Type, InitNew; int i; // collect the fanouts that satisfy the property (have initial value Init or DC) InitNew = ABC_INIT_DC; Vec_PtrClear( vNodes ); Abc_ObjForEachFanout( pNode, pFanout, i ) { if ( Seq_ObjFanoutL(pNode, pFanout) == 0 ) continue; Type = Seq_NodeGetInitLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) ); if ( Type == Init ) InitNew = Init; if ( Type == Init || Type == ABC_INIT_DC ) { Vec_PtrPush( vNodes, pFanout ); Seq_NodeDeleteLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) ); } } // create the new buffer pBuffer = Abc_NtkCreateNode( pNode->pNtk ); Abc_ObjAddFanin( pBuffer, pNode ); // grow storage for initial states Vec_PtrGrow( vInits, 2 * pBuffer->Id + 2 ); for ( i = Vec_PtrSize(vInits); i < 2 * (int)pBuffer->Id + 2; i++ ) Vec_PtrPush( vInits, NULL ); // grow storage for numbers of latches Vec_IntGrow( vNums, 2 * pBuffer->Id + 2 ); for ( i = Vec_IntSize(vNums); i < 2 * (int)pBuffer->Id + 2; i++ ) Vec_IntPush( vNums, 0 ); // insert the new latch Seq_NodeInsertFirst( pBuffer, 0, InitNew ); // redirect the fanouts Vec_PtrForEachEntry( vNodes, pFanout, i ) Abc_ObjPatchFanin( pFanout, pNode, pBuffer ); }
/**Function************************************************************* Synopsis [Retimes node backward by one latch.] Description [Constructs the problem for initial state computation. Returns 1 if the conflict is found.] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_ObjRetimeBackward( Abc_Obj_t * pObj, Abc_Ntk_t * pNtkNew, stmm_table * tTable, Vec_Int_t * vValues ) { Abc_Obj_t * pFanout; Abc_InitType_t Init, Value; Seq_RetEdge_t RetEdge; Abc_Obj_t * pNodeNew, * pFanoutNew, * pBuffer; int i, Edge, fMet0, fMet1, fMetN; // make sure the node can be retimed assert( Seq_ObjFanoutLMin(pObj) > 0 ); // get the fanout values fMet0 = fMet1 = fMetN = 0; Abc_ObjForEachFanout( pObj, pFanout, i ) { if ( Abc_ObjFaninId0(pFanout) == pObj->Id ) { Init = Seq_NodeGetInitLast( pFanout, 0 ); if ( Init == ABC_INIT_ZERO ) fMet0 = 1; else if ( Init == ABC_INIT_ONE ) fMet1 = 1; else if ( Init == ABC_INIT_NONE ) fMetN = 1; } if ( Abc_ObjFaninId1(pFanout) == pObj->Id ) { Init = Seq_NodeGetInitLast( pFanout, 1 ); if ( Init == ABC_INIT_ZERO ) fMet0 = 1; else if ( Init == ABC_INIT_ONE ) fMet1 = 1; else if ( Init == ABC_INIT_NONE ) fMetN = 1; } } // consider the case when all fanout latches have don't-care values // the new values on the fanin edges will be don't-cares if ( !fMet0 && !fMet1 && !fMetN ) { // make sure the label is clean Abc_ObjForEachFanout( pObj, pFanout, i ) assert( pFanout->fMarkC == 0 ); // update the fanout edges Abc_ObjForEachFanout( pObj, pFanout, i ) { if ( pFanout->fMarkC ) continue; pFanout->fMarkC = 1; if ( Abc_ObjFaninId0(pFanout) == pObj->Id ) Seq_NodeDeleteLast( pFanout, 0 ); if ( Abc_ObjFaninId1(pFanout) == pObj->Id ) Seq_NodeDeleteLast( pFanout, 1 ); } // clean the label Abc_ObjForEachFanout( pObj, pFanout, i ) pFanout->fMarkC = 0; // update the fanin edges Abc_ObjRetimeBackwardUpdateEdge( pObj, 0, tTable ); Abc_ObjRetimeBackwardUpdateEdge( pObj, 1, tTable ); Seq_NodeInsertFirst( pObj, 0, ABC_INIT_DC ); Seq_NodeInsertFirst( pObj, 1, ABC_INIT_DC ); return 0; }