void Gia_ManMarkSeqGiaWithBoxes( Gia_Man_t * p, int fSeq ) { // CI order: real PIs + flop outputs + box outputs // CO order: box inputs + real POs + flop inputs Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime; Vec_Int_t * vRoots; Gia_Obj_t * pObj; int nRealCis = Tim_ManPiNum(pManTime); int nRealCos = Tim_ManPoNum(pManTime); int i, nRegs = fSeq ? Gia_ManRegBoxNum(p) : 0; assert( Gia_ManRegNum(p) == 0 ); assert( Gia_ManBoxNum(p) > 0 ); // mark the terminals Gia_ManIncrementTravId( p ); Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); for ( i = 0; i < nRealCis - nRegs; i++ ) Gia_ObjSetTravIdCurrent( p, Gia_ManPi(p, i) ); // collect flops reachable from the POs vRoots = Vec_IntAlloc( Gia_ManRegBoxNum(p) ); for ( i = Gia_ManPoNum(p) - nRealCos; i < Gia_ManPoNum(p) - nRegs; i++ ) { Gia_ObjSetTravIdCurrent( p, Gia_ManPo(p, i) ); Gia_ManMarkSeqGiaWithBoxes_rec( p, Gia_ObjFanin0(Gia_ManPo(p, i)), vRoots ); } // collect flops reachable from roots if ( fSeq ) { Gia_ManForEachObjVec( vRoots, p, pObj, i ) { assert( Gia_ObjIsCo(pObj) ); Gia_ObjSetTravIdCurrent( p, pObj ); Gia_ManMarkSeqGiaWithBoxes_rec( p, Gia_ObjFanin0(pObj), vRoots ); } //printf( "Explored %d flops\n", Vec_IntSize(vRoots) ); }
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 [Find the ordering of AIG objects.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Gia_ManOrderWithBoxes_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vNodes ) { if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return 0; Gia_ObjSetTravIdCurrent(p, pObj); if ( Gia_ObjIsCi(pObj) ) { p->iData2 = Gia_ObjCioId(pObj); return 1; } assert( Gia_ObjIsAnd(pObj) ); if ( Gia_ObjIsBuf(pObj) ) { if ( Gia_ManOrderWithBoxes_rec( p, Gia_ObjFanin0(pObj), vNodes ) ) return 1; Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); return 0; } if ( Gia_ObjSibl(p, Gia_ObjId(p, pObj)) ) if ( Gia_ManOrderWithBoxes_rec( p, Gia_ObjSiblObj(p, Gia_ObjId(p, pObj)), vNodes ) ) return 1; if ( Gia_ManOrderWithBoxes_rec( p, Gia_ObjFanin0(pObj), vNodes ) ) return 1; if ( Gia_ManOrderWithBoxes_rec( p, Gia_ObjFanin1(pObj), vNodes ) ) return 1; Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); return 0; }
Gia_Man_t * Gia_ManDomDerive( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vSupp, int nVars ) { Gia_Man_t * pNew, * pTemp; int nMints = 1 << nVars; int i, m, iResLit; assert( nVars >= 0 && nVars <= 5 ); pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Gia_ManConst0(p)->Value = 0; Gia_ManHashAlloc( pNew ); for ( i = 0; i < Vec_IntSize(vSupp); i++ ) Gia_ManAppendCi(pNew); for ( m = 0; m < nMints; m++ ) { Gia_Obj_t * pObj; Gia_ManIncrementTravId( p ); Gia_ManForEachObjVec( vSupp, p, pObj, i ) { if ( i < nVars ) pObj->Value = (m >> i) & 1; else pObj->Value = Gia_ObjToLit(pNew, Gia_ManCi(pNew, i)); Gia_ObjSetTravIdCurrent( p, pObj ); } iResLit = Gia_ManDomDerive_rec( pNew, p, pRoot ); Gia_ManAppendCo( pNew, iResLit ); }
void Gia_ManPrintTents( Gia_Man_t * p ) { Vec_Int_t * vObjs; Gia_Obj_t * pObj; int t, i, iObjId, nSizePrev, nSizeCurr; assert( Gia_ManPoNum(p) > 0 ); vObjs = Vec_IntAlloc( 100 ); // save constant class Gia_ManIncrementTravId( p ); Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); Vec_IntPush( vObjs, 0 ); // create starting root nSizePrev = Vec_IntSize(vObjs); Gia_ManForEachPo( p, pObj, i ) Gia_ManPrintTents_rec( p, pObj, vObjs ); // build tents printf( "Tents: " ); for ( t = 1; nSizePrev < Vec_IntSize(vObjs); t++ ) { nSizeCurr = Vec_IntSize(vObjs); Vec_IntForEachEntryStartStop( vObjs, iObjId, i, nSizePrev, nSizeCurr ) if ( Gia_ObjIsRo(p, Gia_ManObj(p, iObjId)) ) Gia_ManPrintTents_rec( p, Gia_ObjRoToRi(p, Gia_ManObj(p, iObjId)), vObjs ); printf( "%d=%d ", t, nSizeCurr - nSizePrev ); nSizePrev = nSizeCurr; } printf( " Unused=%d\n", Gia_ManObjNum(p) - Vec_IntSize(vObjs) ); Vec_IntFree( vObjs ); // the remaining objects are PIs without fanout // Gia_ManForEachObj( p, pObj, i ) // if ( !Gia_ObjIsTravIdCurrent(p, pObj) ) // Gia_ObjPrint( p, pObj ); }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Gia_ManDomDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pNode ) { if ( Gia_ObjIsTravIdCurrent(p, pNode) ) return pNode->Value; Gia_ObjSetTravIdCurrent(p, pNode); assert( Gia_ObjIsAnd(pNode) ); Gia_ManDomDerive_rec( pNew, p, Gia_ObjFanin0(pNode) ); Gia_ManDomDerive_rec( pNew, p, Gia_ObjFanin1(pNode) ); return pNode->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pNode), Gia_ObjFanin1Copy(pNode) ); }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static void Gia_ManExtract_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vObjIds ) { if ( !Gia_ObjIsAnd(pObj) ) return; if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return; Gia_ObjSetTravIdCurrent(p, pObj); Gia_ManExtract_rec( p, Gia_ObjFanin0(pObj), vObjIds ); Gia_ManExtract_rec( p, Gia_ObjFanin1(pObj), vObjIds ); Vec_IntPush( vObjIds, Gia_ObjId(p, pObj) ); }
/**Function************************************************************* Synopsis [Duplicates AIG for unrolling.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManPrintTents_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vObjs ) { if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return; Gia_ObjSetTravIdCurrent(p, pObj); Vec_IntPush( vObjs, Gia_ObjId(p, pObj) ); if ( Gia_ObjIsCi(pObj) ) return; Gia_ManPrintTents_rec( p, Gia_ObjFanin0(pObj), vObjs ); if ( Gia_ObjIsAnd(pObj) ) Gia_ManPrintTents_rec( p, Gia_ObjFanin1(pObj), vObjs ); }
/**Function************************************************************* Synopsis [Counts the support size of the node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManCollectAnds_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vNodes ) { if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return; Gia_ObjSetTravIdCurrent(p, pObj); if ( Gia_ObjIsCi(pObj) ) return; assert( Gia_ObjIsAnd(pObj) ); Gia_ManCollectAnds_rec( p, Gia_ObjFanin0(pObj), vNodes ); Gia_ManCollectAnds_rec( p, Gia_ObjFanin1(pObj), vNodes ); Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); }
/**Function************************************************************* Synopsis [Marks with current trav ROs reachable from Const0 and PIs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManMarkAutonomous( Gia_Man_t * p ) { Gia_Obj_t * pObj; int i; Gia_ManCleanMark0( p ); Gia_ManIncrementTravId( p ); Gia_ManForEachRo( p, pObj, i ) Gia_ManMarkAutonomous_rec( p, pObj ); Gia_ManIncrementTravId( p ); Gia_ManForEachRo( p, pObj, i ) if ( pObj->fMark0 ) Gia_ObjSetTravIdCurrent( p, pObj ); Gia_ManCleanMark0( p ); }
static inline void Gia_NodeCollect_rec( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSupp, Vec_Int_t * vSuppRefs ) { if ( Gia_ObjIsTravIdCurrent(p, pNode) ) return; Gia_ObjSetTravIdCurrent(p, pNode); if ( Gia_ObjRefNum(p, pNode) || Gia_ObjIsCi(pNode) ) { Vec_IntPush( vSupp, Gia_ObjId(p, pNode) ); Vec_IntPush( vSuppRefs, Gia_ObjRefNum(p, pNode) ); return; } assert( Gia_ObjIsAnd(pNode) ); Gia_NodeCollect_rec( p, Gia_ObjFanin0(pNode), vSupp, vSuppRefs ); Gia_NodeCollect_rec( p, Gia_ObjFanin1(pNode), vSupp, vSuppRefs ); }
word Gia_ObjComputeTruthTable6( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp, Vec_Wrd_t * vTruths ) { Gia_Obj_t * pLeaf; int i; assert( Vec_IntSize(vSupp) <= 6 ); assert( Gia_ObjIsAnd(pObj) ); assert( !pObj->fMark0 ); Vec_WrdClear( vTruths ); Gia_ManIncrementTravId( p ); Gia_ManForEachObjVec( vSupp, p, pLeaf, i ) { assert( pLeaf->fMark0 || Gia_ObjIsRo(p, pLeaf) ); pLeaf->Value = Vec_WrdSize(vTruths); Vec_WrdPush( vTruths, s_Truth6[i] ); Gia_ObjSetTravIdCurrent(p, pLeaf); }
/**Function************************************************************* Synopsis [Collects support nodes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManCollectCis( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vSupp ) { Gia_Obj_t * pObj; int i; Vec_IntClear( vSupp ); Gia_ManIncrementTravId( p ); Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); for ( i = 0; i < nNodes; i++ ) { pObj = Gia_ManObj( p, pNodes[i] ); if ( Gia_ObjIsCo(pObj) ) Gia_ManCollectCis_rec( p, Gia_ObjFanin0(pObj), vSupp ); else Gia_ManCollectCis_rec( p, pObj, vSupp ); } }
/**Function************************************************************* Synopsis [Computes truth table up to 6 inputs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ObjComputeTruthTable6_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Wrd_t * vTruths ) { word uTruth0, uTruth1; if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return; Gia_ObjSetTravIdCurrent(p, pObj); assert( !pObj->fMark0 ); assert( Gia_ObjIsAnd(pObj) ); Gia_ObjComputeTruthTable6_rec( p, Gia_ObjFanin0(pObj), vTruths ); Gia_ObjComputeTruthTable6_rec( p, Gia_ObjFanin1(pObj), vTruths ); uTruth0 = Vec_WrdEntry( vTruths, Gia_ObjFanin0(pObj)->Value ); uTruth0 = Gia_ObjFaninC0(pObj) ? ~uTruth0 : uTruth0; uTruth1 = Vec_WrdEntry( vTruths, Gia_ObjFanin1(pObj)->Value ); uTruth1 = Gia_ObjFaninC1(pObj) ? ~uTruth1 : uTruth1; pObj->Value = Vec_WrdSize(vTruths); Vec_WrdPush( vTruths, uTruth0 & uTruth1 ); }
/**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 }
/**Function************************************************************* Synopsis [Collects support nodes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Gia_ManCollectNodesCis( Gia_Man_t * p, int * pNodes, int nNodes ) { Vec_Int_t * vNodes; Gia_Obj_t * pObj; int i; vNodes = Vec_IntAlloc( 10000 ); Gia_ManIncrementTravId( p ); Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); for ( i = 0; i < nNodes; i++ ) { pObj = Gia_ManObj( p, pNodes[i] ); if ( Gia_ObjIsCo(pObj) ) Gia_ManCollectNodesCis_rec( p, Gia_ObjFanin0(pObj), vNodes ); else Gia_ManCollectNodesCis_rec( p, pObj, vNodes ); } return vNodes; }
int Ssc_GiaSimulatePattern_rec( Ssc_Man_t * p, Gia_Obj_t * pObj ) { int Res0, Res1; if ( Gia_ObjIsTravIdCurrent(p->pAig, pObj) ) return pObj->fMark0; Gia_ObjSetTravIdCurrent(p->pAig, pObj); if ( ~pObj->Value ) // mapping into FRAIG exists - simulate FRAIG { Res0 = Ssc_GiaSimulatePatternFraig_rec( p, Abc_Lit2Var(pObj->Value) ); pObj->fMark0 = Res0 ^ Abc_LitIsCompl(pObj->Value); } else // mapping into FRAIG does not exist - simulate AIG { Res0 = Ssc_GiaSimulatePattern_rec( p, Gia_ObjFanin0(pObj) ); Res1 = Ssc_GiaSimulatePattern_rec( p, Gia_ObjFanin1(pObj) ); pObj->fMark0 = (Res0 ^ Gia_ObjFaninC0(pObj)) & (Res1 ^ Gia_ObjFaninC1(pObj)); } return pObj->fMark0; }
/**Function************************************************************* Synopsis [Performs UNSAT-core-based refinement.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Rnm_ManRefineCollect_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vVisited, Vec_Int_t * vFlops ) { Vec_Int_t * vLeaves; Gia_Obj_t * pFanin; int k; if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return; Gia_ObjSetTravIdCurrent(p, pObj); if ( Gia_ObjIsCi(pObj) ) { if ( Gia_ObjIsRo(p, pObj) ) Vec_IntPush( vFlops, Gia_ObjId(p, pObj) ); return; } assert( Gia_ObjIsAnd(pObj) ); vLeaves = Ga2_ObjLeaves( p, pObj ); Gia_ManForEachObjVec( vLeaves, p, pFanin, k ) Rnm_ManRefineCollect_rec( p, pFanin, vVisited, vFlops ); Vec_IntPush( vVisited, Gia_ObjId(p, pObj) ); }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Marks objects reachables from Const0 and PIs/ Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Gia_ManMarkAutonomous_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return pObj->fMark0; Gia_ObjSetTravIdCurrent(p, pObj); assert( pObj->fMark0 == 0 ); if ( Gia_ObjIsPi(p, pObj) || Gia_ObjIsConst0(pObj) ) return pObj->fMark0 = 1; if ( Gia_ObjIsCo(pObj) ) return pObj->fMark0 = Gia_ManMarkAutonomous_rec( p, Gia_ObjFanin0(pObj) ); if ( Gia_ObjIsCi(pObj) ) return pObj->fMark0 = Gia_ManMarkAutonomous_rec( p, Gia_ObjRoToRi(p, pObj) ); assert( Gia_ObjIsAnd(pObj) ); if ( Gia_ManMarkAutonomous_rec( p, Gia_ObjFanin0(pObj) ) ) return pObj->fMark0 = 1; return pObj->fMark0 = Gia_ManMarkAutonomous_rec( p, Gia_ObjFanin1(pObj) ); }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Counts the support size of the node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManCollectCis_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp ) { if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return; Gia_ObjSetTravIdCurrent(p, pObj); if ( Gia_ObjIsCi(pObj) ) { Vec_IntPush( vSupp, Gia_ObjId(p, pObj) ); return; } assert( Gia_ObjIsAnd(pObj) ); Gia_ManCollectCis_rec( p, Gia_ObjFanin0(pObj), vSupp ); Gia_ManCollectCis_rec( p, Gia_ObjFanin1(pObj), vSupp ); }
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; }