/**Function************************************************************* Synopsis [Derives the local AIG for the cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Nwk_NodeIfToHop( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj ) { If_Cut_t * pCut; Hop_Obj_t * gFunc; If_Obj_t * pLeaf; int i; // get the best cut pCut = If_ObjCutBest(pIfObj); assert( pCut->nLeaves > 1 ); // set the leaf variables If_CutForEachLeaf( pIfMan, pCut, pLeaf, i ) If_CutSetData( If_ObjCutBest(pLeaf), Hop_IthVar(pHopMan, i) ); // recursively compute the function while collecting visited cuts Vec_PtrClear( pIfMan->vTemp ); gFunc = Nwk_NodeIfToHop2_rec( pHopMan, pIfMan, pIfObj, pIfMan->vTemp ); if ( gFunc == (void *)1 ) { printf( "Nwk_NodeIfToHop(): Computing local AIG has failed.\n" ); return NULL; } // printf( "%d ", Vec_PtrSize(p->vTemp) ); // clean the cuts If_CutForEachLeaf( pIfMan, pCut, pLeaf, i ) If_CutSetData( If_ObjCutBest(pLeaf), NULL ); Vec_PtrForEachEntry( If_Cut_t *, pIfMan->vTemp, pCut, i ) If_CutSetData( pCut, NULL ); return gFunc; }
/**Function************************************************************* Synopsis [Computes area flow.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ float If_CutFlow( If_Man_t * p, If_Cut_t * pCut ) { If_Obj_t * pLeaf; float Flow; int i; assert( p->pPars->fSeqMap || pCut->nLeaves > 1 ); Flow = If_CutLutArea(p, pCut); if (wiremap) Flow += pCut->nLeaves*0.01; // janders If_CutForEachLeaf( p, pCut, pLeaf, i ) { if ( pLeaf->nRefs == 0 ) { Flow += If_ObjCutBest(pLeaf)->Area; if (wiremap) Flow += 0.01*If_ObjCutBest(pLeaf)->nLeaves; // janders } else if ( p->pPars->fSeqMap ) // seq Flow += If_ObjCutBest(pLeaf)->Area / pLeaf->nRefs; else { assert( pLeaf->EstRefs > p->fEpsilon ); Flow += If_ObjCutBest(pLeaf)->Area / pLeaf->EstRefs; if (wiremap) Flow += (0.01*If_ObjCutBest(pLeaf)->nLeaves / pLeaf->EstRefs); // janders } } return Flow; }
// postprocess the mapping //Abc_Print( 1, "Itereation %d: \n", nIter ); If_ManForEachNode( p, pObj, i ) { // update the LValues stored separately if ( If_ObjLValue(pObj) < If_ObjCutBest(pObj)->Delay - p->fEpsilon ) { If_ObjSetLValue( pObj, If_ObjCutBest(pObj)->Delay ); fChange = 1; } //Abc_Print( 1, "%d ", (int)If_ObjLValue(pObj) ); // reset the visit counters assert( pObj->nVisits == 0 ); pObj->nVisits = pObj->nVisitsCopy; }
int If_ManNodeShapeMap( If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Int_t * vShape ) { If_Cut_t * pCut; If_Obj_t * pLeaf; int i, iRes; // get the best cut pCut = If_ObjCutBest(pIfObj); assert( pCut->nLeaves > 1 ); // set the leaf variables If_CutForEachLeaf( pIfMan, pCut, pLeaf, i ) { assert( If_CutDataInt( If_ObjCutBest(pLeaf) ) == 0 ); If_CutSetDataInt( If_ObjCutBest(pLeaf), 1 ); }
/**Function************************************************************* Synopsis [Recursively derives local AIG for the cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int If_ManNodeShapeMap_rec( If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Ptr_t * vVisited, Vec_Int_t * vShape ) { If_Cut_t * pCut; If_Obj_t * pTemp; int i, iFunc0, iFunc1; // get the best cut pCut = If_ObjCutBest(pIfObj); // if the cut is visited, return the result if ( If_CutDataInt(pCut) ) return If_CutDataInt(pCut); // mark the node as visited Vec_PtrPush( vVisited, pCut ); // insert the worst case If_CutSetDataInt( pCut, ~0 ); // skip in case of primary input if ( If_ObjIsCi(pIfObj) ) return If_CutDataInt(pCut); // compute the functions of the children for ( i = 0, pTemp = pIfObj; pTemp; pTemp = pTemp->pEquiv, i++ ) { iFunc0 = If_ManNodeShapeMap_rec( pIfMan, pTemp->pFanin0, vVisited, vShape ); if ( iFunc0 == ~0 ) continue; iFunc1 = If_ManNodeShapeMap_rec( pIfMan, pTemp->pFanin1, vVisited, vShape ); if ( iFunc1 == ~0 ) continue; // both branches are solved Vec_IntPush( vShape, pIfObj->Id ); Vec_IntPush( vShape, pTemp->Id ); If_CutSetDataInt( pCut, 1 ); break; } return If_CutDataInt(pCut); }
/**Function************************************************************* Synopsis [Sets all the cut data to NULL.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void If_ManCleanCutData( If_Man_t * p ) { If_Obj_t * pObj; int i; If_ManForEachObj( p, pObj, i ) If_CutSetData( If_ObjCutBest(pObj), NULL ); }
/**Function************************************************************* Synopsis [Recursively derives the local AIG for the cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Hop_Obj_t * Nwk_NodeIfToHop2_rec( Hop_Man_t * pHopMan, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Ptr_t * vVisited ) { If_Cut_t * pCut; If_Obj_t * pTemp; Hop_Obj_t * gFunc, * gFunc0, * gFunc1; // get the best cut pCut = If_ObjCutBest(pIfObj); // if the cut is visited, return the result if ( If_CutData(pCut) ) return (Hop_Obj_t *)If_CutData(pCut); // mark the node as visited Vec_PtrPush( vVisited, pCut ); // insert the worst case If_CutSetData( pCut, (void *)1 ); // skip in case of primary input if ( If_ObjIsCi(pIfObj) ) return (Hop_Obj_t *)If_CutData(pCut); // compute the functions of the children for ( pTemp = pIfObj; pTemp; pTemp = pTemp->pEquiv ) { gFunc0 = Nwk_NodeIfToHop2_rec( pHopMan, pIfMan, pTemp->pFanin0, vVisited ); if ( gFunc0 == (void *)1 ) continue; gFunc1 = Nwk_NodeIfToHop2_rec( pHopMan, pIfMan, pTemp->pFanin1, vVisited ); if ( gFunc1 == (void *)1 ) continue; // both branches are solved gFunc = Hop_And( pHopMan, Hop_NotCond(gFunc0, pTemp->fCompl0), Hop_NotCond(gFunc1, pTemp->fCompl1) ); if ( pTemp->fPhase != pIfObj->fPhase ) gFunc = Hop_Not(gFunc); If_CutSetData( pCut, gFunc ); break; } return (Hop_Obj_t *)If_CutData(pCut); }
/**Function************************************************************* Synopsis [Computes delay.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ float If_CutDelay( If_Man_t * p, If_Cut_t * pCut ) { static int pPinPerm[IF_MAX_LUTSIZE]; static float pPinDelays[IF_MAX_LUTSIZE]; If_Obj_t * pLeaf; float Delay, DelayCur; float * pLutDelays; int i, Shift; assert( p->pPars->fSeqMap || pCut->nLeaves > 1 ); Delay = -IF_FLOAT_LARGE; if ( p->pPars->pLutLib ) { assert( !p->pPars->fLiftLeaves ); pLutDelays = p->pPars->pLutLib->pLutDelays[pCut->nLeaves]; if ( p->pPars->pLutLib->fVarPinDelays ) { // compute the delay using sorted pins If_CutSortInputPins( p, pCut, pPinPerm, pPinDelays ); for ( i = 0; i < (int)pCut->nLeaves; i++ ) { DelayCur = pPinDelays[pPinPerm[i]] + pLutDelays[i]; Delay = IF_MAX( Delay, DelayCur ); } } else { If_CutForEachLeaf( p, pCut, pLeaf, i ) { DelayCur = If_ObjCutBest(pLeaf)->Delay + pLutDelays[0]; Delay = IF_MAX( Delay, DelayCur ); } }
/**Function************************************************************* Synopsis [Prints one cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void If_CutPrintTiming( If_Man_t * p, If_Cut_t * pCut ) { If_Obj_t * pLeaf; unsigned i; Abc_Print( 1, "{" ); If_CutForEachLeaf( p, pCut, pLeaf, i ) Abc_Print( 1, " %d(%.2f/%.2f)", pLeaf->Id, If_ObjCutBest(pLeaf)->Delay, pLeaf->Required ); Abc_Print( 1, " }\n" ); }
/**Function************************************************************* Synopsis [Computes area flow.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ float If_CutPowerFlow( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot ) { If_Obj_t * pLeaf; float * pSwitching = (float *)p->vSwitching->pArray; float Power = 0; int i; assert( p->pPars->fSeqMap || pCut->nLeaves > 1 ); If_CutForEachLeaf( p, pCut, pLeaf, i ) { Power += pSwitching[pLeaf->Id]; if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) ) Power += If_ObjCutBest(pLeaf)->Power; else if ( p->pPars->fSeqMap ) // seq Power += If_ObjCutBest(pLeaf)->Power / pLeaf->nRefs; else { assert( pLeaf->EstRefs > p->fEpsilon ); Power += If_ObjCutBest(pLeaf)->Power / pLeaf->EstRefs; } }
/**Function************************************************************* Synopsis [Computes area flow.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ float If_CutEdgeFlow( If_Man_t * p, If_Cut_t * pCut ) { If_Obj_t * pLeaf; float Flow; int i; assert( p->pPars->fSeqMap || pCut->nLeaves > 1 ); Flow = pCut->nLeaves; If_CutForEachLeaf( p, pCut, pLeaf, i ) { if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) ) Flow += If_ObjCutBest(pLeaf)->Edge; else if ( p->pPars->fSeqMap ) // seq Flow += If_ObjCutBest(pLeaf)->Edge / pLeaf->nRefs; else { assert( pLeaf->EstRefs > p->fEpsilon ); Flow += If_ObjCutBest(pLeaf)->Edge / pLeaf->EstRefs; } } return Flow; }
/**Function************************************************************* Synopsis [Computes area of the first level.] Description [The cut need to be derefed.] SideEffects [] SeeAlso [] ***********************************************************************/ float If_CutDeref( If_Man_t * p, If_Cut_t * pCut, int nLevels ) { If_Obj_t * pLeaf; float Area; int i; Area = If_CutLutArea(p, pCut); If_CutForEachLeaf( p, pCut, pLeaf, i ) { assert( pLeaf->nRefs > 0 ); if ( --pLeaf->nRefs > 0 || !If_ObjIsAnd(pLeaf) || nLevels == 1 ) continue; Area += If_CutDeref( p, If_ObjCutBest(pLeaf), nLevels - 1 ); }
void If_ObjConePrint( If_Man_t * pIfMan, If_Obj_t * pIfObj ) { If_Cut_t * pCut; If_Obj_t * pLeaf; int i; Vec_PtrClear( pIfMan->vTemp ); If_ObjConePrint_rec( pIfMan, pIfObj, pIfMan->vTemp ); Vec_PtrForEachEntry( If_Cut_t *, pIfMan->vTemp, pCut, i ) If_CutSetDataInt( pCut, 0 ); // print the leaf variables printf( "Cut " ); pCut = If_ObjCutBest(pIfObj); If_CutForEachLeaf( pIfMan, pCut, pLeaf, i ) printf( "%d ", pLeaf->Id ); printf( "\n" ); }
/**Function************************************************************* Synopsis [Prepares node mapping.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void If_ManImproveNodePrepare( If_Man_t * p, If_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront, Vec_Ptr_t * vFrontOld, Vec_Ptr_t * vVisited ) { If_Cut_t * pCut; If_Obj_t * pLeaf; int i; Vec_PtrClear( vFront ); Vec_PtrClear( vFrontOld ); Vec_PtrClear( vVisited ); // expand the cut downwards from the given place pCut = If_ObjCutBest(pObj); If_CutForEachLeaf( p, pCut, pLeaf, i ) { Vec_PtrPush( vFront, pLeaf ); Vec_PtrPush( vFrontOld, pLeaf ); Vec_PtrPush( vVisited, pLeaf ); pLeaf->fMark = 1; }
/**Function************************************************************* Synopsis [Performs area recovery for each node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void If_ManImproveNodeExpand( If_Man_t * p, If_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront, Vec_Ptr_t * vFrontOld, Vec_Ptr_t * vVisited ) { If_Obj_t * pFanin; If_Cut_t * pCut; int CostBef, CostAft, i; float DelayOld, AreaBef, AreaAft; pCut = If_ObjCutBest(pObj); pCut->Delay = If_CutDelay( p, pObj, pCut ); assert( pCut->Delay <= pObj->Required + p->fEpsilon ); if ( pObj->nRefs == 0 ) return; // get the delay DelayOld = pCut->Delay; // get the area AreaBef = If_CutAreaRefed( p, pCut ); // if ( AreaBef == 1 ) // return; // the cut is non-trivial If_ManImproveNodePrepare( p, pObj, nLimit, vFront, vFrontOld, vVisited ); // iteratively modify the cut If_CutAreaDeref( p, pCut ); CostBef = If_ManImproveCutCost( p, vFront ); If_ManImproveNodeFaninCompact( p, pObj, nLimit, vFront, vVisited ); CostAft = If_ManImproveCutCost( p, vFront ); If_CutAreaRef( p, pCut ); assert( CostBef >= CostAft ); // clean up Vec_PtrForEachEntry( If_Obj_t *, vVisited, pFanin, i ) pFanin->fMark = 0; // update the node If_ManImproveNodeUpdate( p, pObj, vFront ); pCut->Delay = If_CutDelay( p, pObj, pCut ); // get the new area AreaAft = If_CutAreaRefed( p, pCut ); if ( AreaAft > AreaBef || pCut->Delay > pObj->Required + p->fEpsilon ) { If_ManImproveNodeUpdate( p, pObj, vFrontOld ); AreaAft = If_CutAreaRefed( p, pCut ); assert( AreaAft == AreaBef ); pCut->Delay = DelayOld; } }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Prints the logic cone with choices.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void If_ObjConePrint_rec( If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Ptr_t * vVisited ) { If_Cut_t * pCut; pCut = If_ObjCutBest(pIfObj); if ( If_CutDataInt(pCut) ) return; Vec_PtrPush( vVisited, pCut ); // insert the worst case If_CutSetDataInt( pCut, ~0 ); // skip in case of primary input if ( If_ObjIsCi(pIfObj) ) return; // compute the functions of the children if ( pIfObj->pEquiv ) If_ObjConePrint_rec( pIfMan, pIfObj->pEquiv, vVisited ); If_ObjConePrint_rec( pIfMan, pIfObj->pFanin0, vVisited ); If_ObjConePrint_rec( pIfMan, pIfObj->pFanin1, vVisited ); printf( "%5d = %5d & %5d | %5d\n", pIfObj->Id, pIfObj->pFanin0->Id, pIfObj->pFanin1->Id, pIfObj->pEquiv ? pIfObj->pEquiv->Id : 0 ); }
// pNtk->nLatches = Aig_ManRegNum(p); // pNtk->nTruePis = Nwk_ManCiNum(pNtk) - pNtk->nLatches; // pNtk->nTruePos = Nwk_ManCoNum(pNtk) - pNtk->nLatches; Aig_ManForEachObj( p, pObj, i ) { pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i ); if ( pIfObj->nRefs == 0 && !If_ObjIsTerm(pIfObj) ) continue; if ( Aig_ObjIsNode(pObj) ) { pCutBest = If_ObjCutBest( pIfObj ); nLeaves = If_CutLeaveNum( pCutBest ); ppLeaves = If_CutLeaves( pCutBest ); // create node pObjNew = Nwk_ManCreateNode( pNtk, nLeaves, pIfObj->nRefs ); for ( k = 0; k < nLeaves; k++ ) { pObjRepr = (Aig_Obj_t *)Vec_PtrEntry( vIfToAig, ppLeaves[k] ); Nwk_ObjAddFanin( pObjNew, (Nwk_Obj_t *)pObjRepr->pData ); } // get the functionality pObjNew->pFunc = Nwk_NodeIfToHop( pNtk->pManHop, pIfMan, pIfObj ); } else if ( Aig_ObjIsCi(pObj) ) pObjNew = Nwk_ManCreateCi( pNtk, pIfObj->nRefs ); else if ( Aig_ObjIsCo(pObj) ) { pObjNew = Nwk_ManCreateCo( pNtk ); pObjNew->fInvert = Aig_ObjFaninC0(pObj); Nwk_ObjAddFanin( pObjNew, (Nwk_Obj_t *)Aig_ObjFanin0(pObj)->pData ); //printf( "%d ", pObjNew->Id ); } else if ( Aig_ObjIsConst1(pObj) ) { pObjNew = Nwk_ManCreateNode( pNtk, 0, pIfObj->nRefs ); pObjNew->pFunc = Hop_ManConst1( pNtk->pManHop ); } else assert( 0 ); pObj->pData = pObjNew; }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Returns internal nodes used in the mapping.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Llb_AigMap( Aig_Man_t * pAig, int nLutSize, int nLutMin ) { extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); extern If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars ); extern void Gia_ManSetIfParsDefault( If_Par_t * pPars ); If_Par_t Pars, * pPars = &Pars; If_Man_t * pIfMan; If_Obj_t * pAnd; Abc_Ntk_t * pNtk; Abc_Obj_t * pNode; Vec_Int_t * vNodes; Aig_Obj_t * pObj; int i; // create ABC network pNtk = Abc_NtkFromAigPhase( pAig ); assert( Abc_NtkIsStrash(pNtk) ); // derive mapping parameters Gia_ManSetIfParsDefault( pPars ); pPars->nLutSize = nLutSize; // get timing information pPars->pTimesArr = Abc_NtkGetCiArrivalFloats(pNtk); pPars->pTimesReq = NULL; // perform LUT mapping pIfMan = Abc_NtkToIf( pNtk, pPars ); if ( pIfMan == NULL ) { Abc_NtkDelete( pNtk ); return NULL; } if ( !If_ManPerformMapping( pIfMan ) ) { Abc_NtkDelete( pNtk ); If_ManStop( pIfMan ); return NULL; } // mark nodes in the AIG used in the mapping Aig_ManCleanMarkA( pAig ); Aig_ManForEachNode( pAig, pObj, i ) { pNode = (Abc_Obj_t *)pObj->pData; if ( pNode == NULL ) continue; pAnd = (If_Obj_t *)pNode->pCopy; if ( pAnd == NULL ) continue; if ( pAnd->nRefs > 0 && (int)If_ObjCutBest(pAnd)->nLeaves >= nLutMin ) pObj->fMarkA = 1; }