ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Mark GIA nodes that feed into POs.] Description [Returns the array of classes of remaining registers.] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManMarkSeqGiaWithBoxes_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vRoots ) { Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime; int i, iBox, nBoxIns, nBoxOuts, iShift, nRealCis; if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return; Gia_ObjSetTravIdCurrent(p, pObj); if ( Gia_ObjIsAnd(pObj) ) { Gia_ManMarkSeqGiaWithBoxes_rec( p, Gia_ObjFanin0(pObj), vRoots ); Gia_ManMarkSeqGiaWithBoxes_rec( p, Gia_ObjFanin1(pObj), vRoots ); return; } assert( Gia_ObjIsCi(pObj) ); nRealCis = Tim_ManPiNum(pManTime); if ( Gia_ObjCioId(pObj) < nRealCis ) { int nRegs = Gia_ManRegBoxNum(p); int iFlop = Gia_ObjCioId(pObj) - (nRealCis - nRegs); assert( iFlop >= 0 && iFlop < nRegs ); pObj = Gia_ManCo( p, Gia_ManPoNum(p) - nRegs + iFlop ); Vec_IntPush( vRoots, Gia_ObjId(p, pObj) ); return; } // get the box iBox = Tim_ManBoxForCi( pManTime, Gia_ObjCioId(pObj) ); nBoxIns = Tim_ManBoxInputNum(pManTime, iBox); nBoxOuts = Tim_ManBoxOutputNum(pManTime, iBox); // mark all outputs iShift = Tim_ManBoxOutputFirst(pManTime, iBox); for ( i = 0; i < nBoxOuts; i++ ) Gia_ObjSetTravIdCurrent(p, Gia_ManCi(p, iShift + i)); // traverse from inputs iShift = Tim_ManBoxInputFirst(pManTime, iBox); for ( i = 0; i < nBoxIns; i++ ) Gia_ObjSetTravIdCurrent(p, Gia_ManCo(p, iShift + i)); for ( i = 0; i < nBoxIns; i++ ) Gia_ManMarkSeqGiaWithBoxes_rec( p, Gia_ObjFanin0(Gia_ManCo(p, iShift + i)), vRoots ); }
/**Function************************************************************* Synopsis [Computes partitioning of registers.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManRegCreatePart( Gia_Man_t * p, Vec_Int_t * vPart, int * pnCountPis, int * pnCountRegs, int ** ppMapBack ) { Gia_Man_t * pNew; Gia_Obj_t * pObj; Vec_Int_t * vNodes, * vRoots; int i, iOut, nCountPis, nCountRegs; int * pMapBack; // collect/mark nodes/PIs in the DFS order from the roots Gia_ManIncrementTravId( p ); vRoots = Vec_IntAlloc( Vec_IntSize(vPart) ); Vec_IntForEachEntry( vPart, iOut, i ) Vec_IntPush( vRoots, Gia_ObjId(p, Gia_ManCo(p, Gia_ManPoNum(p)+iOut)) ); vNodes = Gia_ManCollectNodesCis( p, Vec_IntArray(vRoots), Vec_IntSize(vRoots) ); Vec_IntFree( vRoots ); // unmark register outputs Vec_IntForEachEntry( vPart, iOut, i ) Gia_ObjSetTravIdPrevious( p, Gia_ManCi(p, Gia_ManPiNum(p)+iOut) ); // count pure PIs nCountPis = nCountRegs = 0; Gia_ManForEachPi( p, pObj, i ) nCountPis += Gia_ObjIsTravIdCurrent(p, pObj); // count outputs of other registers Gia_ManForEachRo( p, pObj, i ) nCountRegs += Gia_ObjIsTravIdCurrent(p, pObj); // should be !Gia_... ??? if ( pnCountPis ) *pnCountPis = nCountPis; if ( pnCountRegs ) *pnCountRegs = nCountRegs; // clean old manager Gia_ManFillValue(p); Gia_ManConst0(p)->Value = 0; // create the new manager pNew = Gia_ManStart( Vec_IntSize(vNodes) ); // create the PIs Gia_ManForEachCi( p, pObj, i ) if ( Gia_ObjIsTravIdCurrent(p, pObj) ) pObj->Value = Gia_ManAppendCi(pNew); // add variables for the register outputs // create fake POs to hold the register outputs Vec_IntForEachEntry( vPart, iOut, i ) { pObj = Gia_ManCi(p, Gia_ManPiNum(p)+iOut); pObj->Value = Gia_ManAppendCi(pNew); Gia_ManAppendCo( pNew, pObj->Value ); Gia_ObjSetTravIdCurrent( p, pObj ); // added }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Computes miter for ECO with given root node and fanins.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Bmc_EcoMiter( Gia_Man_t * pGold, Gia_Man_t * pOld, Vec_Int_t * vFans ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pRoot = Gia_ObjFanin0( Gia_ManPo(pOld, Gia_ManPoNum(pOld)-1) ); // fanin of the last PO Gia_Obj_t * pObj; int i, NewPi, Miter; assert( Gia_ManCiNum(pGold) == Gia_ManCiNum(pOld) ); assert( Gia_ManCoNum(pGold) == Gia_ManCoNum(pOld) - 1 ); assert( Gia_ObjIsAnd(pRoot) ); // create the miter pNew = Gia_ManStart( 3 * Gia_ManObjNum(pGold) ); pNew->pName = Abc_UtilStrsav( pGold->pName ); Gia_ManHashAlloc( pNew ); // copy gold Gia_ManConst0(pGold)->Value = 0; Gia_ManForEachCi( pGold, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); NewPi = Gia_ManAppendCi( pNew ); Gia_ManForEachAnd( pGold, pObj, i ) pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( pGold, pObj, i ) pObj->Value = Gia_ObjFanin0Copy( pObj ); // create onset Gia_ManConst0(pOld)->Value = 0; Gia_ManForEachCi( pOld, pObj, i ) pObj->Value = Gia_ManCi(pGold, i)->Value; Gia_ManForEachAnd( pOld, pObj, i ) if ( pObj == pRoot ) pObj->Value = NewPi; else pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( pOld, pObj, i ) pObj->Value = Gia_ObjFanin0Copy( pObj ); Gia_ManForEachCo( pGold, pObj, i ) Gia_ManAppendCo( pNew, Gia_ManHashXor(pNew, pObj->Value, Gia_ManCo(pOld, i)->Value) ); // create offset Gia_ManForEachAnd( pOld, pObj, i ) if ( pObj == pRoot ) pObj->Value = Abc_LitNot(NewPi); else pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( pOld, pObj, i ) pObj->Value = Gia_ObjFanin0Copy( pObj ); Miter = 0; Gia_ManForEachCo( pGold, pObj, i ) Miter = Gia_ManHashOr( pNew, Miter, Gia_ManHashXor(pNew, pObj->Value, Gia_ManCo(pOld, i)->Value) ); Gia_ManAppendCo( pNew, Miter ); // add outputs for the nodes Gia_ManForEachObjVec( vFans, pOld, pObj, i ) Gia_ManAppendCo( pNew, pObj->Value ); // cleanup pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); assert( Gia_ManPiNum(pNew) == Gia_ManCiNum(pGold) + 1 ); assert( Gia_ManPoNum(pNew) == Gia_ManCoNum(pGold) + 1 + Vec_IntSize(vFans) ); return pNew; }
// add real POs for the registers Vec_IntForEachEntry( vPart, iOut, i ) { pObj = Gia_ManCo( p, Gia_ManPoNum(p)+iOut ); Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); }
Vec_Int_t * Gia_ManOrderWithBoxes( Gia_Man_t * p ) { Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime; Vec_Int_t * vNodes; Gia_Obj_t * pObj; int i, k, curCi, curCo; assert( pManTime != NULL ); assert( Gia_ManIsNormalized( p ) ); // start trav IDs Gia_ManIncrementTravId( p ); // start the array vNodes = Vec_IntAlloc( Gia_ManObjNum(p) ); // include constant Vec_IntPush( vNodes, 0 ); Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); // include primary inputs for ( i = 0; i < Tim_ManPiNum(pManTime); i++ ) { pObj = Gia_ManCi( p, i ); Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); Gia_ObjSetTravIdCurrent( p, pObj ); assert( Gia_ObjId(p, pObj) == i+1 ); } // for each box, include box nodes curCi = Tim_ManPiNum(pManTime); curCo = 0; for ( i = 0; i < Tim_ManBoxNum(pManTime); i++ ) { // add internal nodes for ( k = 0; k < Tim_ManBoxInputNum(pManTime, i); k++ ) { pObj = Gia_ManCo( p, curCo + k ); if ( Gia_ManOrderWithBoxes_rec( p, Gia_ObjFanin0(pObj), vNodes ) ) { int iCiNum = p->iData2; int iBoxNum = Tim_ManBoxFindFromCiNum( pManTime, iCiNum ); printf( "The command has to terminate. Boxes are not in a topological order.\n" ); printf( "The following information may help debugging (numbers are 0-based):\n" ); printf( "Input %d of BoxA %d (1stCI = %d; 1stCO = %d) has TFI with CI %d,\n", k, i, Tim_ManBoxOutputFirst(pManTime, i), Tim_ManBoxInputFirst(pManTime, i), iCiNum ); printf( "which corresponds to output %d of BoxB %d (1stCI = %d; 1stCO = %d).\n", iCiNum - Tim_ManBoxOutputFirst(pManTime, iBoxNum), iBoxNum, Tim_ManBoxOutputFirst(pManTime, iBoxNum), Tim_ManBoxInputFirst(pManTime, iBoxNum) ); printf( "In a correct topological order, BoxB should precede BoxA.\n" ); Vec_IntFree( vNodes ); p->iData2 = 0; return NULL; } } // add POs corresponding to box inputs for ( k = 0; k < Tim_ManBoxInputNum(pManTime, i); k++ ) { pObj = Gia_ManCo( p, curCo + k ); Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); } curCo += Tim_ManBoxInputNum(pManTime, i); // add PIs corresponding to box outputs for ( k = 0; k < Tim_ManBoxOutputNum(pManTime, i); k++ ) { pObj = Gia_ManCi( p, curCi + k ); Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); Gia_ObjSetTravIdCurrent( p, pObj ); } curCi += Tim_ManBoxOutputNum(pManTime, i); } // add remaining nodes for ( i = Tim_ManCoNum(pManTime) - Tim_ManPoNum(pManTime); i < Tim_ManCoNum(pManTime); i++ ) { pObj = Gia_ManCo( p, i ); Gia_ManOrderWithBoxes_rec( p, Gia_ObjFanin0(pObj), vNodes ); } // add POs for ( i = Tim_ManCoNum(pManTime) - Tim_ManPoNum(pManTime); i < Tim_ManCoNum(pManTime); i++ ) { pObj = Gia_ManCo( p, i ); Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); } curCo += Tim_ManPoNum(pManTime); // verify counts assert( curCi == Gia_ManCiNum(p) ); assert( curCo == Gia_ManCoNum(p) ); //assert( Vec_IntSize(vNodes) == Gia_ManObjNum(p) ); return vNodes; }