summaryrefslogtreecommitdiffstats
path: root/src/aig/gia/giaIf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/aig/gia/giaIf.c')
-rw-r--r--src/aig/gia/giaIf.c529
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
+