diff options
Diffstat (limited to 'src/aig/gia/giaIf.c')
-rw-r--r-- | src/aig/gia/giaIf.c | 529 |
1 files changed, 529 insertions, 0 deletions
diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c new file mode 100644 index 00000000..a06a6024 --- /dev/null +++ b/src/aig/gia/giaIf.c @@ -0,0 +1,529 @@ +/**CFile**************************************************************** + + FileName [giaMap.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Manipulation of mapping associated with the AIG.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaMap.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "aig.h" +#include "if.h" +#include "dar.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Load the network into FPGA manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetIfParsDefault( If_Par_t * pPars ) +{ +// extern void * Abc_FrameReadLibLut(); + // set defaults + memset( pPars, 0, sizeof(If_Par_t) ); + // user-controlable paramters +// pPars->nLutSize = -1; + pPars->nLutSize = 6; + pPars->nCutsMax = 8; + pPars->nFlowIters = 1; + pPars->nAreaIters = 2; + pPars->DelayTarget = -1; + pPars->Epsilon = (float)0.005; + pPars->fPreprocess = 1; + pPars->fArea = 0; + pPars->fFancy = 0; + pPars->fExpRed = 1; //// + pPars->fLatchPaths = 0; + pPars->fEdge = 1; + pPars->fPower = 0; + pPars->fCutMin = 0; + pPars->fSeqMap = 0; + pPars->fVerbose = 0; + // internal parameters + pPars->fTruth = 0; + pPars->nLatches = 0; + pPars->fLiftLeaves = 0; +// pPars->pLutLib = Abc_FrameReadLibLut(); + pPars->pLutLib = NULL; + pPars->pTimesArr = NULL; + pPars->pTimesArr = NULL; + pPars->pFuncCost = NULL; +} + +/**Function************************************************************* + + Synopsis [Load the network into FPGA manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +If_Man_t * Gia_ManToIf( Gia_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf ) +{ +// extern Vec_Int_t * SGia_ManComputeSwitchProbs( Gia_Man_t * p, int nFrames, int nPref, int fProbOne ); +// Vec_Int_t * vSwitching = NULL, * vSwitching2 = NULL; +// float * pSwitching, * pSwitching2; + If_Man_t * pIfMan; + If_Obj_t * pIfObj; + Gia_Obj_t * pNode; + int i, clk = clock(); + Gia_ManLevelNum( p ); +// assert( p->pReprs == NULL ); +/* + // set the number of registers (switch activity will be combinational) + Gia_ManSetRegNum( p, 0 ); + if ( pPars->fPower ) + { + vSwitching = SGia_ManComputeSwitchProbs( p, 48, 16, 0 ); + if ( pPars->fVerbose ) + { + ABC_PRT( "Computing switching activity", clock() - clk ); + } + pSwitching = (float *)vSwitching->pArray; + vSwitching2 = Vec_IntStart( Gia_ManObjNumMax(p) ); + pSwitching2 = (float *)vSwitching2->pArray; + } +*/ + // start the mapping manager and set its parameters + pIfMan = If_ManStart( pPars ); +// pIfMan->vSwitching = vSwitching2; + // load the AIG into the mapper + Gia_ManCreateRefs( p ); + Gia_ManForEachObj( p, pNode, i ) + { + if ( Gia_ObjIsAnd(pNode) ) + pIfObj = If_ManCreateAnd( pIfMan, + If_NotCond( (If_Obj_t *)Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ), + If_NotCond( (If_Obj_t *)Vec_PtrEntry(vAigToIf, Gia_ObjFaninId1(pNode, i)), Gia_ObjFaninC1(pNode) ) ); + else if ( Gia_ObjIsCi(pNode) ) + { + pIfObj = If_ManCreateCi( pIfMan ); + If_ObjSetLevel( pIfObj, Gia_ObjLevel(p,pNode) ); +// Abc_Print( 1, "pi=%d ", pIfObj->Level ); + if ( pIfMan->nLevelMax < (int)pIfObj->Level ) + pIfMan->nLevelMax = (int)pIfObj->Level; + } + else if ( Gia_ObjIsCo(pNode) ) + { + pIfObj = If_ManCreateCo( pIfMan, If_NotCond( (If_Obj_t *)Vec_PtrEntry(vAigToIf, Gia_ObjFaninId0(pNode, i)), Gia_ObjFaninC0(pNode) ) ); +// Abc_Print( 1, "po=%d ", pIfObj->Level ); + } + else if ( Gia_ObjIsConst0(pNode) ) + pIfObj = If_Not(If_ManConst1( pIfMan )); + else // add the node to the mapper + assert( 0 ); + // save the result + assert( Vec_PtrEntry(vAigToIf, i) == NULL ); + Vec_PtrWriteEntry( vAigToIf, i, pIfObj ); +// if ( vSwitching2 ) +// pSwitching2[pIfObj->Id] = pSwitching[pNode->Id]; + // set up the choice node +/* +// if ( p->pReprs && p->pNexts && Gia_ObjIsHead( p, i ) ) + if ( p->pNexts && Gia_ObjNext(p, i) && Gia_ObjRefsId(p, i) ) + { + int iPrev, iFanin; + pIfMan->nChoices++; + for ( iPrev = i, iFanin = Gia_ObjNext(p, i); iFanin; iPrev = iFanin, iFanin = Gia_ObjNext(p, iFanin) ) + If_ObjSetChoice( Vec_PtrEntry(vAigToIf,iPrev), Vec_PtrEntry(vAigToIf,iFanin) ); + If_ManCreateChoice( pIfMan, Vec_PtrEntry(vAigToIf,i) ); + } +*/ +/* // set up the choice node + if ( Gia_ObjIsChoice( p, pNode ) ) + { + pIfMan->nChoices++; + for ( pPrev = pNode, pFanin = Gia_ObjEquiv(p, pNode); pFanin; pPrev = pFanin, pFanin = Gia_ObjEquiv(p, pFanin) ) + If_ObjSetChoice( pPrev->pData, pFanin->pData ); + If_ManCreateChoice( pIfMan, pNode->pData ); + } +// assert( If_ObjLevel(pIfObj) == Gia_ObjLevel(pNode) ); +*/ + } +// if ( vSwitching ) +// Vec_IntFree( vSwitching ); + return pIfMan; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Gia_ManFromIf( If_Man_t * pIfMan, Gia_Man_t * p, Vec_Ptr_t * vAigToIf ) +{ + int * pMapping, iOffset; + Vec_Ptr_t * vIfToAig; + Gia_Obj_t * pObj, * pObjRepr; + If_Obj_t * pIfObj; + If_Cut_t * pCutBest; + int i, k, j, nLeaves, * ppLeaves; + int nItems = 0; + assert( Gia_ManCiNum(p) == If_ManCiNum(pIfMan) ); + assert( Gia_ManCoNum(p) == If_ManCoNum(pIfMan) ); + assert( Gia_ManAndNum(p) == If_ManAndNum(pIfMan) ); + // create mapping of IF to AIG + vIfToAig = Vec_PtrStart( If_ManObjNum(pIfMan) ); + Gia_ManForEachObj( p, pObj, i ) + { + pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i ); + Vec_PtrWriteEntry( vIfToAig, pIfObj->Id, pObj ); + if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 ) + continue; + nItems += 2 + If_CutLeaveNum( If_ObjCutBest(pIfObj) ); + } + // construct the network + pMapping = ABC_CALLOC( int, Gia_ManObjNum(p) + nItems ); + iOffset = Gia_ManObjNum(p); + Gia_ManForEachObj( p, pObj, i ) + { + pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i ); + if ( !Gia_ObjIsAnd(pObj) || pIfObj->nRefs == 0 ) + continue; + pCutBest = If_ObjCutBest( pIfObj ); + nLeaves = If_CutLeaveNum( pCutBest ); + ppLeaves = If_CutLeaves( pCutBest ); + // create node + k = iOffset; + pMapping[k++] = nLeaves; + for ( j = 0; j < nLeaves; j++ ) + { + pObjRepr = (Gia_Obj_t *)Vec_PtrEntry( vIfToAig, ppLeaves[j] ); + pMapping[k++] = Gia_ObjId( p, pObjRepr ); + } + pMapping[k++] = i; + pMapping[i] = iOffset; + iOffset = k; + } + assert( iOffset <= Gia_ManObjNum(p) + nItems ); + Vec_PtrFree( vIfToAig ); +// pNtk->pManTime = Tim_ManDup( pIfMan->pManTim, 0 ); + return pMapping; +} + +/**Function************************************************************* + + Synopsis [Interface with the FPGA mapping package.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_MappingIf( Gia_Man_t * p, If_Par_t * pPars ) +{ + If_Man_t * pIfMan; + Vec_Ptr_t * vAigToIf; + // set the arrival times + pPars->pTimesArr = ABC_ALLOC( float, Gia_ManCiNum(p) ); + memset( pPars->pTimesArr, 0, sizeof(float) * Gia_ManCiNum(p) ); + // translate into the mapper + vAigToIf = Vec_PtrStart( Gia_ManObjNum(p) ); + pIfMan = Gia_ManToIf( p, pPars, vAigToIf ); + if ( pIfMan == NULL ) + return 0; +// pIfMan->pManTim = Tim_ManDup( pManTime, 0 ); + if ( !If_ManPerformMapping( pIfMan ) ) + { + If_ManStop( pIfMan ); + return 0; + } + // transform the result of mapping into the new network + ABC_FREE( p->pMapping ); + p->pMapping = Gia_ManFromIf( pIfMan, p, vAigToIf ); +// if ( pPars->fBidec && pPars->nLutSize <= 8 ) +// Gia_ManBidecResyn( pNtk, 0 ); + If_ManStop( pIfMan ); + Vec_PtrFree( vAigToIf ); + return 1; +} + + +/**Function************************************************************* + + Synopsis [Prints mapping statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintMappingStats( Gia_Man_t * p ) +{ + int * pLevels; + int i, k, iFan, nLutSize = 0, nLuts = 0, nFanins = 0, LevelMax = 0; + if ( !p->pMapping ) + return; + pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachLut( p, i ) + { + nLuts++; + nFanins += Gia_ObjLutSize(p, i); + nLutSize = ABC_MAX( nLutSize, Gia_ObjLutSize(p, i) ); + Gia_LutForEachFanin( p, i, iFan, k ) + pLevels[i] = ABC_MAX( pLevels[i], pLevels[iFan] ); + pLevels[i]++; + LevelMax = ABC_MAX( LevelMax, pLevels[i] ); + } + ABC_FREE( pLevels ); + Abc_Print( 1, "mapping (K=%d) : ", nLutSize ); + Abc_Print( 1, "lut =%7d ", nLuts ); + Abc_Print( 1, "edge =%8d ", nFanins ); + Abc_Print( 1, "lev =%5d ", LevelMax ); + Abc_Print( 1, "mem =%5.2f Mb", 4.0*(Gia_ManObjNum(p) + 2*nLuts + nFanins)/(1<<20) ); + Abc_Print( 1, "\n" ); +} + +/**Function************************************************************* + + Synopsis [Prints mapping statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManLutFaninCount( Gia_Man_t * p ) +{ + int i, Counter = 0; + Gia_ManForEachLut( p, i ) + Counter += Gia_ObjLutSize(p, i); + return Counter; +} + +/**Function************************************************************* + + Synopsis [Prints mapping statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManLutSizeMax( Gia_Man_t * p ) +{ + int i, nSizeMax = -1; + Gia_ManForEachLut( p, i ) + nSizeMax = ABC_MAX( nSizeMax, Gia_ObjLutSize(p, i) ); + return nSizeMax; +} + +/**Function************************************************************* + + Synopsis [Prints mapping statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManLutNum( Gia_Man_t * p ) +{ + int i, Counter = 0; + Gia_ManForEachLut( p, i ) + Counter ++; + return Counter; +} + +/**Function************************************************************* + + Synopsis [Prints mapping statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManLutLevel( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, k, iFan, Level; + int * pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachLut( p, i ) + { + Level = 0; + Gia_LutForEachFanin( p, i, iFan, k ) + if ( Level < pLevels[iFan] ) + Level = pLevels[iFan]; + pLevels[i] = Level + 1; + } + Level = 0; + Gia_ManForEachCo( p, pObj, k ) + if ( Level < pLevels[Gia_ObjFaninId0p(p, pObj)] ) + Level = pLevels[Gia_ObjFaninId0p(p, pObj)]; + ABC_FREE( pLevels ); + return Level; +} + +/**Function************************************************************* + + Synopsis [Assigns levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSetRefsMapped( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, k, iFan; + ABC_FREE( p->pRefs ); + p->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ObjRefInc( p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachLut( p, i ) + Gia_LutForEachFanin( p, i, iFan, k ) + Gia_ObjRefInc( p, Gia_ManObj(p, iFan) ); +} + +/**Function************************************************************* + + Synopsis [Prints NPN class statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManPrintNpnClasses( Gia_Man_t * p ) +{ + extern char ** Kit_DsdNpn4ClassNames(); + char ** pNames = Kit_DsdNpn4ClassNames(); + Vec_Int_t * vLeaves, * vTruth, * vVisited; + int * pLutClass, ClassCounts[222] = {0}; + int i, k, iFan, Class, OtherClasses, OtherClasses2, nTotal, Counter, Counter2; + unsigned * pTruth; + assert( p->pMapping != NULL ); + assert( Gia_ManLutSizeMax( p ) <= 4 ); + vLeaves = Vec_IntAlloc( 100 ); + vVisited = Vec_IntAlloc( 100 ); + vTruth = Vec_IntAlloc( (1<<16) ); + pLutClass = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManCleanTruth( p ); + Gia_ManForEachLut( p, i ) + { + if ( Gia_ObjLutSize(p,i) > 4 ) + continue; + Vec_IntClear( vLeaves ); + Gia_LutForEachFanin( p, i, iFan, k ) + Vec_IntPush( vLeaves, iFan ); + for ( ; k < 4; k++ ) + Vec_IntPush( vLeaves, 0 ); + pTruth = Gia_ManConvertAigToTruth( p, Gia_ManObj(p, i), vLeaves, vTruth, vVisited ); + Class = Dar_LibReturnClass( *pTruth ); + ClassCounts[ Class ]++; + pLutClass[i] = Class; + } + Vec_IntFree( vLeaves ); + Vec_IntFree( vTruth ); + Vec_IntFree( vVisited ); + Vec_IntFreeP( &p->vTruths ); + nTotal = 0; + for ( i = 0; i < 222; i++ ) + nTotal += ClassCounts[i]; + Abc_Print( 1, "NPN CLASS STATISTICS (for %d LUT4 present in the current mapping):\n", nTotal ); + OtherClasses = 0; + for ( i = 0; i < 222; i++ ) + { + if ( ClassCounts[i] == 0 ) + continue; + if ( 100.0 * ClassCounts[i] / (nTotal+1) < 0.1 ) // do not show anything below 0.1 percent + continue; + OtherClasses += ClassCounts[i]; + Abc_Print( 1, "Class %3d : Count = %6d (%7.2f %%) %s\n", + i, ClassCounts[i], 100.0 * ClassCounts[i] / (nTotal+1), pNames[i] ); + } + OtherClasses = nTotal - OtherClasses; + Abc_Print( 1, "Other : Count = %6d (%7.2f %%)\n", + OtherClasses, 100.0 * OtherClasses / (nTotal+1) ); + // count the number of LUTs that have MUX function and two fanins with MUX functions + OtherClasses = OtherClasses2 = 0; + ABC_FREE( p->pRefs ); + Gia_ManSetRefsMapped( p ); + Gia_ManForEachLut( p, i ) + { + if ( pLutClass[i] != 109 ) + continue; + Counter = Counter2 = 0; + Gia_LutForEachFanin( p, i, iFan, k ) + { + Counter += (pLutClass[iFan] == 109); + Counter2 += (pLutClass[iFan] == 109) && (Gia_ObjRefsId(p, iFan) == 1); + } + OtherClasses += (Counter > 1); + OtherClasses2 += (Counter2 > 1); +// Abc_Print( 1, "%d -- ", pLutClass[i] ); +// Gia_LutForEachFanin( p, i, iFan, k ) +// Abc_Print( 1, "%d ", pLutClass[iFan] ); +// Abc_Print( 1, "\n" ); + } + ABC_FREE( p->pRefs ); + Abc_Print( 1, "Approximate number of 4:1 MUX structures: All = %6d (%7.2f %%) MFFC = %6d (%7.2f %%)\n", + OtherClasses, 100.0 * OtherClasses / (nTotal+1), + OtherClasses2, 100.0 * OtherClasses2 / (nTotal+1) ); + ABC_FREE( pLutClass ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + |