ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Converts pNode->pData gates into array of SC_Lit gate IDs and back.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_SclMioGates2SclGates( SC_Lib * pLib, Abc_Ntk_t * p ) { Abc_Obj_t * pObj; int i, gateId, bufferId; // find buffer if ( Mio_LibraryReadBuf((Mio_Library_t *)p->pManFunc) == NULL ) { printf( "Cannot find buffer in the current library. Quitting.\n" ); return; } bufferId = Abc_SclCellFind( pLib, Mio_GateReadName(Mio_LibraryReadBuf((Mio_Library_t *)p->pManFunc)) ); assert( bufferId >= 0 ); // remap cells assert( p->vGates == NULL ); p->vGates = Vec_IntStartFull( Abc_NtkObjNumMax(p) ); Abc_NtkForEachNodeNotBarBuf1( p, pObj, i ) { gateId = Abc_SclCellFind( pLib, Mio_GateReadName((Mio_Gate_t *)pObj->pData) ); assert( gateId >= 0 ); Vec_IntWriteEntry( p->vGates, i, gateId ); }
/**Function************************************************************* Synopsis [Replaces a fanin of the node.] Description [The node is pObj. An old fanin of this node (pFaninOld) has to be replaced by a new fanin (pFaninNew). Assumes that the node and the old fanin are not complemented. The new fanin can be complemented. In this case, the polarity of the new fanin will change, compared to the polarity of the old fanin.] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_ObjPatchFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFaninOld, Abc_Obj_t * pFaninNew ) { Abc_Obj_t * pFaninNewR = Abc_ObjRegular(pFaninNew); int iFanin;//, nLats;//, fCompl; assert( !Abc_ObjIsComplement(pObj) ); assert( !Abc_ObjIsComplement(pFaninOld) ); assert( pFaninOld != pFaninNewR ); // assert( pObj != pFaninOld ); // assert( pObj != pFaninNewR ); assert( pObj->pNtk == pFaninOld->pNtk ); assert( pObj->pNtk == pFaninNewR->pNtk ); if ( (iFanin = Vec_IntFind( &pObj->vFanins, pFaninOld->Id )) == -1 ) { printf( "Node %s is not among", Abc_ObjName(pFaninOld) ); printf( " the fanins of node %s...\n", Abc_ObjName(pObj) ); return; } // remember the attributes of the old fanin // fCompl = Abc_ObjFaninC(pObj, iFanin); // replace the old fanin entry by the new fanin entry (removes attributes) Vec_IntWriteEntry( &pObj->vFanins, iFanin, pFaninNewR->Id ); // set the attributes of the new fanin // if ( fCompl ^ Abc_ObjIsComplement(pFaninNew) ) // Abc_ObjSetFaninC( pObj, iFanin ); if ( Abc_ObjIsComplement(pFaninNew) ) Abc_ObjXorFaninC( pObj, iFanin ); // if ( Abc_NtkIsSeq(pObj->pNtk) && (nLats = Seq_ObjFaninL(pObj, iFanin)) ) // Seq_ObjSetFaninL( pObj, iFanin, nLats ); // update the fanout of the fanin if ( !Vec_IntRemove( &pFaninOld->vFanouts, pObj->Id ) ) { printf( "Node %s is not among", Abc_ObjName(pObj) ); printf( " the fanouts of its old fanin %s...\n", Abc_ObjName(pFaninOld) ); // return; } Vec_IntPushMem( pObj->pNtk->pMmStep, &pFaninNewR->vFanouts, pObj->Id ); }
void Wlc_WriteTables( FILE * pFile, Wlc_Ntk_t * p ) { Vec_Int_t * vNodes; Wlc_Obj_t * pObj, * pFanin; word * pTable; int i; if ( p->vTables == NULL || Vec_PtrSize(p->vTables) == 0 ) return; // map tables into their nodes vNodes = Vec_IntStart( Vec_PtrSize(p->vTables) ); Wlc_NtkForEachObj( p, pObj, i ) if ( pObj->Type == WLC_OBJ_TABLE ) Vec_IntWriteEntry( vNodes, Wlc_ObjTableId(pObj), i ); // write tables Vec_PtrForEachEntry( word *, p->vTables, pTable, i ) { pObj = Wlc_NtkObj( p, Vec_IntEntry(vNodes, i) ); assert( pObj->Type == WLC_OBJ_TABLE ); pFanin = Wlc_ObjFanin0( p, pObj ); Wlc_WriteTableOne( pFile, Wlc_ObjRange(pFanin), Wlc_ObjRange(pObj), pTable, i ); } Vec_IntFree( vNodes ); }
/**Function************************************************************* Synopsis [For each cut, returns PIs that can be quantified.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Ptr_t * Llb_ManCutMap( Aig_Man_t * p, Vec_Ptr_t * vResult, Vec_Ptr_t * vSupps ) { int fShowMatrix = 1; Vec_Ptr_t * vMaps, * vOne; Vec_Int_t * vMap, * vPrev, * vNext; Aig_Obj_t * pObj; int * piFirst, * piLast; int i, k, CounterPlus, CounterMinus, Counter; vMaps = Vec_PtrAlloc( 100 ); Vec_PtrForEachEntry( Vec_Ptr_t *, vResult, vOne, i ) { vMap = Vec_IntStart( Aig_ManObjNumMax(p) ); Vec_PtrForEachEntry( Aig_Obj_t *, vOne, pObj, k ) { if ( !Saig_ObjIsPi(p, pObj) ) Vec_IntWriteEntry( vMap, pObj->Id, 1 ); // else //printf( "*" ); //printf( "%d ", pObj->Id ); } Vec_PtrPush( vMaps, vMap ); //printf( "\n" ); }
/**Function************************************************************* Synopsis [Create mapping of node IDs of pNtk into equiv classes of pMiter.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Abc_NtkDressMapClasses( Aig_Man_t * pMiter, Abc_Ntk_t * pNtk ) { Vec_Int_t * vId2Lit; Abc_Obj_t * pObj, * pAnd; Aig_Obj_t * pObjMan, * pObjMiter, * pObjRepr; int i; vId2Lit = Vec_IntAlloc( 0 ); Vec_IntFill( vId2Lit, Abc_NtkObjNumMax(pNtk), -1 ); Abc_NtkForEachNode( pNtk, pObj, i ) { // get the pointer to the miter node corresponding to pObj if ( (pAnd = Abc_ObjRegular(pObj->pCopy)) && Abc_ObjType(pAnd) != ABC_OBJ_NONE && // strashed node is present and legal (pObjMan = Aig_Regular((Aig_Obj_t *)pAnd->pCopy)) && Aig_ObjType(pObjMan) != AIG_OBJ_NONE && // AIG node is present and legal (pObjMiter = Aig_Regular((Aig_Obj_t *)pObjMan->pData)) && Aig_ObjType(pObjMiter) != AIG_OBJ_NONE ) // miter node is present and legal { // get the representative of the miter node pObjRepr = Aig_ObjRepr( pMiter, pObjMiter ); pObjRepr = pObjRepr? pObjRepr : pObjMiter; // map pObj (whose ID is i) into the repr node ID (i.e. equiv class) Vec_IntWriteEntry( vId2Lit, i, Aig_ObjId(pObjRepr) ); } } return vId2Lit; }
/**Function************************************************************* Synopsis [Performs induction by unrolling timeframes backward.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fUnique, int fUniqueAll, int fGetCex, int fVerbose, int fVeryVerbose ) { sat_solver * pSat; Aig_Man_t * pAigPart; Cnf_Dat_t * pCnfPart; Vec_Int_t * vTopVarNums, * vState, * vTopVarIds = NULL; Vec_Ptr_t * vTop, * vBot; Aig_Obj_t * pObjPi, * pObjPiCopy, * pObjPo; int i, k, f, clk, Lits[2], status, RetValue, nSatVarNum, nConfPrev; int nOldSize, iReg, iLast, fAdded, nConstrs = 0, nClauses = 0; assert( fUnique == 0 || fUniqueAll == 0 ); assert( Saig_ManPoNum(p) == 1 ); Aig_ManSetPioNumbers( p ); // start the top by including the PO vBot = Vec_PtrAlloc( 100 ); vTop = Vec_PtrAlloc( 100 ); vState = Vec_IntAlloc( 1000 ); Vec_PtrPush( vTop, Aig_ManPo(p, 0) ); // start the array of CNF variables vTopVarNums = Vec_IntAlloc( 100 ); // start the solver pSat = sat_solver_new(); sat_solver_setnvars( pSat, 1000 ); // iterate backward unrolling RetValue = -1; nSatVarNum = 0; if ( fVerbose ) printf( "Induction parameters: FramesMax = %5d. ConflictMax = %6d.\n", nFramesMax, nConfMax ); for ( f = 0; ; f++ ) { if ( f > 0 ) { Aig_ManStop( pAigPart ); Cnf_DataFree( pCnfPart ); } clk = clock(); // get the bottom Aig_SupportNodes( p, (Aig_Obj_t **)Vec_PtrArray(vTop), Vec_PtrSize(vTop), vBot ); // derive AIG for the part between top and bottom pAigPart = Aig_ManDupSimpleDfsPart( p, vBot, vTop ); // convert it into CNF pCnfPart = Cnf_Derive( pAigPart, Aig_ManPoNum(pAigPart) ); Cnf_DataLift( pCnfPart, nSatVarNum ); nSatVarNum += pCnfPart->nVars; nClauses += pCnfPart->nClauses; // remember top frame var IDs if ( fGetCex && vTopVarIds == NULL ) { vTopVarIds = Vec_IntStartFull( Aig_ManPiNum(p) ); Aig_ManForEachPi( p, pObjPi, i ) { if ( pObjPi->pData == NULL ) continue; pObjPiCopy = (Aig_Obj_t *)pObjPi->pData; assert( Aig_ObjIsPi(pObjPiCopy) ); if ( Saig_ObjIsPi(p, pObjPi) ) Vec_IntWriteEntry( vTopVarIds, Aig_ObjPioNum(pObjPi) + Saig_ManRegNum(p), pCnfPart->pVarNums[Aig_ObjId(pObjPiCopy)] ); else if ( Saig_ObjIsLo(p, pObjPi) ) Vec_IntWriteEntry( vTopVarIds, Aig_ObjPioNum(pObjPi) - Saig_ManPiNum(p), pCnfPart->pVarNums[Aig_ObjId(pObjPiCopy)] ); else assert( 0 ); } } // stitch variables of top and bot assert( Aig_ManPoNum(pAigPart)-1 == Vec_IntSize(vTopVarNums) ); Aig_ManForEachPo( pAigPart, pObjPo, i ) { if ( i == 0 ) { // do not perform inductive strengthening // if ( f > 0 ) // continue; // add topmost literal Lits[0] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], f>0 ); if ( !sat_solver_addclause( pSat, Lits, Lits+1 ) ) assert( 0 ); nClauses++; continue; } Lits[0] = toLitCond( Vec_IntEntry(vTopVarNums, i-1), 0 ); Lits[1] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], 1 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); Lits[0] = toLitCond( Vec_IntEntry(vTopVarNums, i-1), 1 ); Lits[1] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], 0 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); nClauses += 2; } // add CNF to the SAT solver for ( i = 0; i < pCnfPart->nClauses; i++ ) if ( !sat_solver_addclause( pSat, pCnfPart->pClauses[i], pCnfPart->pClauses[i+1] ) ) break; if ( i < pCnfPart->nClauses ) { // printf( "SAT solver became UNSAT after adding clauses.\n" ); RetValue = 1; break; } // create new set of POs to derive new top Vec_PtrClear( vTop ); Vec_PtrPush( vTop, Aig_ManPo(p, 0) ); Vec_IntClear( vTopVarNums ); nOldSize = Vec_IntSize(vState); Vec_IntFillExtra( vState, nOldSize + Aig_ManRegNum(p), -1 ); Vec_PtrForEachEntry( Aig_Obj_t *, vBot, pObjPi, i ) { assert( Aig_ObjIsPi(pObjPi) ); if ( Saig_ObjIsLo(p, pObjPi) ) { pObjPiCopy = (Aig_Obj_t *)pObjPi->pData; assert( pObjPiCopy != NULL ); Vec_PtrPush( vTop, Saig_ObjLoToLi(p, pObjPi) ); Vec_IntPush( vTopVarNums, pCnfPart->pVarNums[pObjPiCopy->Id] ); iReg = pObjPi->PioNum - Saig_ManPiNum(p); assert( iReg >= 0 && iReg < Aig_ManRegNum(p) ); Vec_IntWriteEntry( vState, nOldSize+iReg, pCnfPart->pVarNums[pObjPiCopy->Id] ); } }
static inline void Gia_ObjEdgeClean( int iObj, Vec_Int_t * vEdge1, Vec_Int_t * vEdge2 ) { Vec_IntWriteEntry( vEdge1, iObj, 0 ); Vec_IntWriteEntry( vEdge2, iObj, 0 ); }
static inline void Kf_ObjSetCuts( Kf_Man_t * p, int i, Vec_Int_t * vVec ) { Vec_IntWriteEntry(&p->vCuts, i, Vec_SetAppend(&p->pMem, Vec_IntArray(vVec), Vec_IntSize(vVec))); }
static inline void Gia_ObjSetDom( Gia_Man_t * p, Gia_Obj_t * pObj, int d ) { Vec_IntWriteEntry(p->vDoms, Gia_ObjId(p, pObj), d); }
/**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; // } }
Vec_IntForEachEntry( vSigs, NameId, i ) { assert( Vec_IntEntry(vMap, NameId) != -1 ); Vec_IntWriteEntry( vSigs, i++, Vec_IntEntry(vMap, NameId) ); }
Psr_NtkForEachPo( pNtkBox, NameId, i ) { assert( Vec_IntEntry(vMap, NameId) == -1 ); Vec_IntWriteEntry( vMap, NameId, Psr_NtkPiNum(pNtkBox) + i + 1 ); // +1 to keep 1st form input non-zero }
static inline void Sfm_ObjSetTravIdCurrent2( Sfm_Ntk_t * p, int Id ) { Vec_IntWriteEntry( &p->vTravIds2, Id, p->nTravIds2 ); }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ /* Vec_Int_t * Gia_WriteDotAigMarks( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds ) { int i; Vec_Int_t * vMarks = Vec_IntStart( Gia_ManObjNum(p) ); for ( i = 0; i < Vec_IntSize(vHadds)/2; i++ ) { Vec_IntWriteEntry( vMarks, Vec_IntEntry(vHadds, 2*i+0), Abc_Var2Lit(i+1, 0) ); Vec_IntWriteEntry( vMarks, Vec_IntEntry(vHadds, 2*i+1), Abc_Var2Lit(i+1, 0) ); } for ( i = 0; i < Vec_IntSize(vFadds)/5; i++ ) { Vec_IntWriteEntry( vMarks, Vec_IntEntry(vFadds, 5*i+3), Abc_Var2Lit(i+1, 1) ); Vec_IntWriteEntry( vMarks, Vec_IntEntry(vFadds, 5*i+4), Abc_Var2Lit(i+1, 1) ); } return vMarks; } int Gia_WriteDotAigLevel_rec( Gia_Man_t * p, Vec_Int_t * vMarks, Vec_Int_t * vFadds, Vec_Int_t * vHadds, int Id, Vec_Int_t * vLevel ) { int Level = Vec_IntEntry(vLevel, Id), Mark = Vec_IntEntry(vMarks, Id); if ( Level || Mark == -1 ) return Level; if ( Mark == 0 ) { Gia_Obj_t * pObj = Gia_ManObj( p, Id ); int Level0 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId0(pObj, Id), vLevel ); int Level1 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId1(pObj, Id), vLevel ); Level = Abc_MaxInt(Level0, Level1) + 1; Vec_IntWriteEntry( vLevel, Id, Level ); Vec_IntWriteEntry( vMarks, Id, -1 ); } else if ( Abc_LitIsCompl(Mark) ) // FA { int i, * pFanins = Vec_IntEntryP( vFadds, 5*(Abc_Lit2Var(Mark)-1) ); assert( pFanins[3] == Id || pFanins[4] == Id ); for ( i = 0; i < 3; i++ ) Level = Abc_MaxInt( Level, Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, pFanins[i], vLevel ) ); Vec_IntWriteEntry( vLevel, pFanins[3], Level+1 ); Vec_IntWriteEntry( vLevel, pFanins[4], Level+1 ); } else // HA { int * pFanins = Vec_IntEntryP( vHadds, 2*(Abc_Lit2Var(Mark)-1) ); Gia_Obj_t * pObj = Gia_ManObj( p, pFanins[1] ); int Level0 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId0(pObj, Id), vLevel ); int Level1 = Gia_WriteDotAigLevel_rec( p, vMarks, vFadds, vHadds, Gia_ObjFaninId1(pObj, Id), vLevel ); assert( pFanins[0] == Id || pFanins[1] == Id ); Level = Abc_MaxInt(Level0, Level1) + 1; Vec_IntWriteEntry( vLevel, pFanins[0], Level ); Vec_IntWriteEntry( vLevel, pFanins[1], Level ); } return Level; } int Gia_WriteDotAigLevel( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds, Vec_Int_t ** pvMarks, Vec_Int_t ** pvLevel ) { Vec_Int_t * vMarks = Gia_WriteDotAigMarks( p, vFadds, vHadds ); Vec_Int_t * vLevel = Vec_IntStart( Gia_ManObjNum(p) ); int i, Id, Level = 0; Vec_IntWriteEntry( vMarks, 0, -1 ); Gia_ManForEachCiId( p, Id, i ) Vec_IntWriteEntry( vMarks, Id, -1 ); Gia_ManForEachCoDriverId( p, Id, i ) Level = Abc_MaxInt( Level, Gia_WriteDotAigLevel_rec(p, vMarks, vFadds, vHadds, Id, vLevel) ); Gia_ManForEachCoId( p, Id, i ) Vec_IntWriteEntry( vMarks, Id, -1 ); *pvMarks = vMarks; *pvLevel = vLevel; return Level; } */ int Gia_WriteDotAigLevel( Gia_Man_t * p, Vec_Int_t * vFadds, Vec_Int_t * vHadds, Vec_Int_t * vRecord, Vec_Int_t ** pvLevel, Vec_Int_t ** pvMarks, Vec_Int_t ** pvRemap ) { Vec_Int_t * vLevel = Vec_IntStart( Gia_ManObjNum(p) ); Vec_Int_t * vMarks = Vec_IntStart( Gia_ManObjNum(p) ); Vec_Int_t * vRemap = Vec_IntStartNatural( Gia_ManObjNum(p) ); int i, k, Id, Entry, LevelMax = 0; Vec_IntWriteEntry( vMarks, 0, -1 ); Gia_ManForEachCiId( p, Id, i ) Vec_IntWriteEntry( vMarks, Id, -1 ); Gia_ManForEachCoId( p, Id, i ) Vec_IntWriteEntry( vMarks, Id, -1 ); Vec_IntForEachEntry( vRecord, Entry, i ) { int Level = 0; int Node = Abc_Lit2Var2(Entry); int Attr = Abc_Lit2Att2(Entry); if ( Attr == 2 ) { int * pFanins = Vec_IntEntryP( vFadds, 5*Node ); for ( k = 0; k < 3; k++ ) Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, pFanins[k]) ); Vec_IntWriteEntry( vLevel, pFanins[3], Level+1 ); Vec_IntWriteEntry( vLevel, pFanins[4], Level+1 ); Vec_IntWriteEntry( vMarks, pFanins[4], Entry ); Vec_IntWriteEntry( vRemap, pFanins[3], pFanins[4] ); //printf( "Making FA output %d.\n", pFanins[4] ); } else if ( Attr == 1 ) { int * pFanins = Vec_IntEntryP( vHadds, 2*Node ); Gia_Obj_t * pObj = Gia_ManObj( p, pFanins[1] ); int pFaninsIn[2] = { Gia_ObjFaninId0(pObj, pFanins[1]), Gia_ObjFaninId1(pObj, pFanins[1]) }; for ( k = 0; k < 2; k++ ) Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, pFaninsIn[k]) ); Vec_IntWriteEntry( vLevel, pFanins[0], Level+1 ); Vec_IntWriteEntry( vLevel, pFanins[1], Level+1 ); Vec_IntWriteEntry( vMarks, pFanins[1], Entry ); Vec_IntWriteEntry( vRemap, pFanins[0], pFanins[1] ); //printf( "Making HA output %d.\n", pFanins[1] ); } else // if ( Attr == 3 || Attr == 0 ) { Gia_Obj_t * pObj = Gia_ManObj( p, Node ); int pFaninsIn[2] = { Gia_ObjFaninId0(pObj, Node), Gia_ObjFaninId1(pObj, Node) }; for ( k = 0; k < 2; k++ ) Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, pFaninsIn[k]) ); Vec_IntWriteEntry( vLevel, Node, Level+1 ); Vec_IntWriteEntry( vMarks, Node, -1 ); //printf( "Making node %d.\n", Node ); } LevelMax = Abc_MaxInt( LevelMax, Level+1 ); }
/**Function************************************************************* Synopsis [Performs AIG shrinking using the current mapping.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManMapShrink4( Gia_Man_t * p, int fKeepLevel, int fVerbose ) { Vec_Int_t * vLeaves, * vTruth, * vVisited, * vLeavesBest; Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj, * pFanin; unsigned * pTruth; int i, k, iFan; abctime clk = Abc_Clock(); // int ClassCounts[222] = {0}; int * pLutClass, Counter = 0; assert( p->pMapping != NULL ); if ( Gia_ManLutSizeMax( p ) > 4 ) { printf( "Resynthesis is not performed when nodes have more than 4 inputs.\n" ); return NULL; } pLutClass = ABC_CALLOC( int, Gia_ManObjNum(p) ); vLeaves = Vec_IntAlloc( 0 ); vTruth = Vec_IntAlloc( (1<<16) ); vVisited = Vec_IntAlloc( 0 ); vLeavesBest = Vec_IntAlloc( 4 ); // prepare the library Dar_LibPrepare( 5 ); // clean the old manager Gia_ManCleanTruth( p ); Gia_ManSetPhase( p ); Gia_ManFillValue( p ); Gia_ManConst0(p)->Value = 0; // start the new manager pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Gia_ManHashAlloc( pNew ); Gia_ManCleanLevels( pNew, Gia_ManObjNum(p) ); Gia_ManForEachObj1( p, pObj, i ) { if ( Gia_ObjIsCi(pObj) ) { pObj->Value = Gia_ManAppendCi( pNew ); if ( p->vLevels ) Gia_ObjSetLevel( pNew, Gia_ObjFromLit(pNew, Gia_ObjValue(pObj)), Gia_ObjLevel(p, pObj) ); } else if ( Gia_ObjIsCo(pObj) ) { pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); } else if ( Gia_ObjIsLut(p, i) ) { Counter++; // collect leaves of this gate Vec_IntClear( vLeaves ); Gia_LutForEachFanin( p, i, iFan, k ) Vec_IntPush( vLeaves, iFan ); for ( ; k < 4; k++ ) Vec_IntPush( vLeaves, 0 ); //.compute the truth table pTruth = Gia_ManConvertAigToTruth( p, pObj, vLeaves, vTruth, vVisited ); // change from node IDs to their literals Gia_ManForEachObjVec( vLeaves, p, pFanin, k ) { assert( Gia_ObjValue(pFanin) != ~0 ); Vec_IntWriteEntry( vLeaves, k, Gia_ObjValue(pFanin) ); } // derive new structre if ( Gia_ManTruthIsConst0(pTruth, Vec_IntSize(vLeaves)) ) pObj->Value = 0; else if ( Gia_ManTruthIsConst1(pTruth, Vec_IntSize(vLeaves)) ) pObj->Value = 1; else { pObj->Value = Dar_LibEvalBuild( pNew, vLeaves, 0xffff & *pTruth, fKeepLevel, vLeavesBest ); pObj->Value = Abc_LitNotCond( pObj->Value, Gia_ObjPhaseRealLit(pNew, pObj->Value) ^ pObj->fPhase ); } } }