ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Create the new node assuming it does not exist.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Ivy_Obj_t * Ivy_ObjCreatePi( Ivy_Man_t * p ) { return Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, NULL, NULL, IVY_PI, IVY_INIT_NONE) ); }
/**Function************************************************************* Synopsis [Implements ITE operation.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Ivy_Obj_t * Ivy_Mux( Ivy_Man_t * p, Ivy_Obj_t * pC, Ivy_Obj_t * p1, Ivy_Obj_t * p0 ) { Ivy_Obj_t * pTempA1, * pTempA2, * pTempB1, * pTempB2, * pTemp; int Count0, Count1; // consider trivial cases if ( p0 == Ivy_Not(p1) ) return Ivy_Exor( p, pC, p0 ); // other cases can be added // implement the first MUX (F = C * x1 + C' * x0) pTempA1 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, pC, p1, IVY_AND, IVY_INIT_NONE) ); pTempA2 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Not(pC), p0, IVY_AND, IVY_INIT_NONE) ); if ( pTempA1 && pTempA2 ) { pTemp = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Not(pTempA1), Ivy_Not(pTempA2), IVY_AND, IVY_INIT_NONE) ); if ( pTemp ) return Ivy_Not(pTemp); } Count0 = (pTempA1 != NULL) + (pTempA2 != NULL); // implement the second MUX (F' = C * x1' + C' * x0') pTempB1 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, pC, Ivy_Not(p1), IVY_AND, IVY_INIT_NONE) ); pTempB2 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Not(pC), Ivy_Not(p0), IVY_AND, IVY_INIT_NONE) ); if ( pTempB1 && pTempB2 ) { pTemp = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Not(pTempB1), Ivy_Not(pTempB2), IVY_AND, IVY_INIT_NONE) ); if ( pTemp ) return pTemp; } Count1 = (pTempB1 != NULL) + (pTempB2 != NULL); // compare and decide which one to implement if ( Count0 >= Count1 ) { pTempA1 = pTempA1? pTempA1 : Ivy_And(p, pC, p1); pTempA2 = pTempA2? pTempA2 : Ivy_And(p, Ivy_Not(pC), p0); return Ivy_Or( p, pTempA1, pTempA2 ); } pTempB1 = pTempB1? pTempB1 : Ivy_And(p, pC, Ivy_Not(p1)); pTempB2 = pTempB2? pTempB2 : Ivy_And(p, Ivy_Not(pC), Ivy_Not(p0)); return Ivy_Not( Ivy_Or( p, pTempB1, pTempB2 ) ); // return Ivy_Or( Ivy_And(pC, p1), Ivy_And(Ivy_Not(pC), p0) ); }
/**Function************************************************************* Synopsis [Create the new node assuming it does not exist.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Ivy_Obj_t * Ivy_ObjCreatePo( Ivy_Man_t * p, Ivy_Obj_t * pDriver ) { return Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, pDriver, NULL, IVY_PO, IVY_INIT_NONE) ); }
/**Function************************************************************* Synopsis [Replaces one object by another.] Description [Both objects are currently in the manager. The new object (pObjNew) should be used instead of the old object (pObjOld). If the new object is complemented or used, the buffer is added.] SideEffects [] SeeAlso [] ***********************************************************************/ void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop, int fUpdateLevel ) { int nRefsOld;//, clk; // the object to be replaced cannot be complemented assert( !Ivy_IsComplement(pObjOld) ); // the object to be replaced cannot be a terminal assert( Ivy_ObjIsNone(pObjOld) || !Ivy_ObjIsPi(pObjOld) ); // the object to be used cannot be a PO or assert assert( !Ivy_ObjIsBuf(Ivy_Regular(pObjNew)) ); // the object cannot be the same assert( pObjOld != Ivy_Regular(pObjNew) ); //printf( "Replacing %d by %d.\n", Ivy_Regular(pObjOld)->Id, Ivy_Regular(pObjNew)->Id ); // if HAIG is defined, create the choice node if ( p->pHaig ) { // if ( pObjOld->Id == 31 ) // { // Ivy_ManShow( p, 0 ); // Ivy_ManShow( p->pHaig, 1 ); // } Ivy_ManHaigCreateChoice( p, pObjOld, pObjNew ); } // if the new object is complemented or already used, add the buffer if ( Ivy_IsComplement(pObjNew) || Ivy_ObjIsLatch(pObjNew) || Ivy_ObjRefs(pObjNew) > 0 || Ivy_ObjIsPi(pObjNew) || Ivy_ObjIsConst1(pObjNew) ) pObjNew = Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, pObjNew, NULL, IVY_BUF, IVY_INIT_NONE) ); assert( !Ivy_IsComplement(pObjNew) ); if ( fUpdateLevel ) { //clk = clock(); // if the new node's arrival time is different, recursively update arrival time of the fanouts if ( p->fFanout && !Ivy_ObjIsBuf(pObjNew) && pObjOld->Level != pObjNew->Level ) { assert( Ivy_ObjIsNode(pObjOld) ); pObjOld->Level = pObjNew->Level; Ivy_ObjUpdateLevel_rec( p, pObjOld ); } //p->time1 += clock() - clk; // if the new node's required time has changed, recursively update required time of the fanins //clk = clock(); if ( p->vRequired ) { int ReqNew = Vec_IntEntry(p->vRequired, pObjOld->Id); if ( ReqNew < Vec_IntEntry(p->vRequired, pObjNew->Id) ) { Vec_IntWriteEntry( p->vRequired, pObjNew->Id, ReqNew ); Ivy_ObjUpdateLevelR_rec( p, pObjNew, ReqNew ); } } //p->time2 += clock() - clk; } // delete the old object if ( fDeleteOld ) Ivy_ObjDelete_rec( p, pObjOld, fFreeTop ); // make sure object is not pointing to itself assert( Ivy_ObjFanin0(pObjNew) == NULL || pObjOld != Ivy_ObjFanin0(pObjNew) ); assert( Ivy_ObjFanin1(pObjNew) == NULL || pObjOld != Ivy_ObjFanin1(pObjNew) ); // make sure the old node has no fanin fanout pointers if ( p->fFanout ) { assert( pObjOld->pFanout != NULL ); assert( pObjNew->pFanout == NULL ); pObjNew->pFanout = pObjOld->pFanout; } // transfer the old object assert( Ivy_ObjRefs(pObjNew) == 0 ); nRefsOld = pObjOld->nRefs; Ivy_ObjOverwrite( pObjOld, pObjNew ); pObjOld->nRefs = nRefsOld; // patch the fanout of the fanins if ( p->fFanout ) { Ivy_ObjPatchFanout( p, Ivy_ObjFanin0(pObjOld), pObjNew, pObjOld ); if ( Ivy_ObjFanin1(pObjOld) ) Ivy_ObjPatchFanout( p, Ivy_ObjFanin1(pObjOld), pObjNew, pObjOld ); } // update the hash table Ivy_TableUpdate( p, pObjNew, pObjOld->Id ); // recycle the object that was taken over by pObjOld Vec_PtrWriteEntry( p->vObjs, pObjNew->Id, NULL ); Ivy_ManRecycleMemory( p, pObjNew ); // if the new node is the buffer propagate it if ( p->fFanout && Ivy_ObjIsBuf(pObjOld) ) Vec_PtrPush( p->vBufs, pObjOld ); // Ivy_ManCheckFanouts( p ); // printf( "\n" ); /* if ( p->pHaig ) { int x; Ivy_ManShow( p, 0, NULL ); Ivy_ManShow( p->pHaig, 1, NULL ); x = 0; } */ // if ( Ivy_ManCheckFanoutNums(p) ) // { // int x = 0; // } }