diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/base/abc/abcNtk.c | 1 | ||||
-rw-r--r-- | src/base/abci/abc.c | 14 | ||||
-rw-r--r-- | src/base/abci/abcFpgaFast.c | 79 | ||||
-rw-r--r-- | src/base/abci/abcIvy.c | 2 | ||||
-rw-r--r-- | src/base/abci/abcPrint.c | 13 | ||||
-rw-r--r-- | src/base/abci/abcTiming.c | 2 | ||||
-rw-r--r-- | src/map/fpga/fpga.c | 18 | ||||
-rw-r--r-- | src/map/fpga/fpgaCore.c | 7 | ||||
-rw-r--r-- | src/map/fpga/fpgaCut.c | 16 | ||||
-rw-r--r-- | src/map/fpga/fpgaInt.h | 2 | ||||
-rw-r--r-- | src/temp/ivy/ivy.h | 5 | ||||
-rw-r--r-- | src/temp/ivy/ivyFastMap.c | 1088 | ||||
-rw-r--r-- | src/temp/ivy/ivyIsop.c | 2 | ||||
-rw-r--r-- | src/temp/ivy/module.make | 1 | ||||
-rw-r--r-- | src/temp/player/module.make | 1 | ||||
-rw-r--r-- | src/temp/player/player.h | 5 | ||||
-rw-r--r-- | src/temp/player/playerFast.c | 367 | ||||
-rw-r--r-- | src/temp/player/playerToAbc.c | 11 |
18 files changed, 1229 insertions, 405 deletions
diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c index d7283d55..215e80ec 100644 --- a/src/base/abc/abcNtk.c +++ b/src/base/abc/abcNtk.c @@ -705,6 +705,7 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk ) Vec_PtrFree( pNtk->vCutSet ); Vec_PtrFree( pNtk->vBoxes ); Vec_FltFree( pNtk->vSkews ); + if ( pNtk->vLevelsR ) Vec_IntFree( pNtk->vLevelsR ); if ( pNtk->pModel ) free( pNtk->pModel ); TotalMemory = 0; TotalMemory += pNtk->pMmObj? Extra_MmFixedReadMemUsage(pNtk->pMmObj) : 0; diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 0f20e4d8..4154fe53 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -4736,11 +4736,11 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv ) pErr = Abc_FrameReadErr(pAbc); // set defaults - nLutMax = 8; + nLutMax = 6; nPlaMax = 128; RankCost = 96000; fFastMode = 1; - fRewriting = 1; + fRewriting = 0; fSynthesis = 0; fVerbose = 1; Extra_UtilGetoptReset(); @@ -4811,7 +4811,7 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } - if ( nLutMax < 2 || nLutMax > 8 || nPlaMax < 8 || nPlaMax > 128 ) + if ( nLutMax < 2 || nLutMax > 12 || nPlaMax < 8 || nPlaMax > 128 ) { fprintf( pErr, "Incorrect LUT/PLA parameters.\n" ); return 1; @@ -4819,8 +4819,8 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv ) // run the command // pNtkRes = Abc_NtkXyz( pNtk, nPlaMax, 1, 0, fInvs, fVerbose ); -// pNtkRes = Abc_NtkPlayer( pNtk, nLutMax, nPlaMax, RankCost, fFastMode, fRewriting, fSynthesis, fVerbose ); - pNtkRes = NULL; + pNtkRes = Abc_NtkPlayer( pNtk, nLutMax, nPlaMax, RankCost, fFastMode, fRewriting, fSynthesis, fVerbose ); +// pNtkRes = NULL; if ( pNtkRes == NULL ) { fprintf( pErr, "Command has failed.\n" ); @@ -6495,7 +6495,7 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) } // create the new LUT library - if ( nLutSize >= 3 && nLutSize <= 6 ) + if ( nLutSize >= 3 && nLutSize <= 10 ) Fpga_SetSimpleLutLib( nLutSize ); /* else @@ -6560,7 +6560,7 @@ usage: fprintf( pErr, "\t-p : optimizes power by minimizing switching activity [default = %s]\n", fSwitching? "yes": "no" ); fprintf( pErr, "\t-l : optimizes latch paths for delay, other paths for area [default = %s]\n", fLatchPaths? "yes": "no" ); fprintf( pErr, "\t-D float : sets the required time for the mapping [default = %s]\n", Buffer ); - fprintf( pErr, "\t-K num : the number of LUT inputs [default = %s]%s\n", LutSize, (nLutSize == -1 ? " (type \"print_lut\")" : "") ); + fprintf( pErr, "\t-K num : the number of LUT inputs (2 < num < 11) [default = %s]%s\n", LutSize, (nLutSize == -1 ? " (type \"print_lut\")" : "") ); fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pErr, "\t-h : prints the command usage\n"); return 1; diff --git a/src/base/abci/abcFpgaFast.c b/src/base/abci/abcFpgaFast.c new file mode 100644 index 00000000..2d5813c7 --- /dev/null +++ b/src/base/abci/abcFpgaFast.c @@ -0,0 +1,79 @@ +/**CFile**************************************************************** + + FileName [abcFpgaFast.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Fast FPGA mapper.] + + Author [Sungmin Cho] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcFpgaFast.c,v 1.00 2006/09/02 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs fast FPGA mapping of the network.] + + Description [Takes the AIG to be mapped, the LUT size, and verbosity + flag. Produces the new network by fast FPGA mapping of the current + network. If the current network in ABC in not an AIG, the user should + run command "strash" to make sure that the current network into an AIG + before calling this procedure.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkFpgaFast( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose ) +{ + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObj; + int i; + + // make sure the network is an AIG + assert( Abc_NtkIsStrash(pNtk) ); + + // iterate over the nodes in the network + Abc_NtkForEachNode( pNtk, pObj, i ) + { + } + + // create the new network after mapping + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_BDD ); + + // here we need to create nodes of the new network + + // make sure that the final network passes the test + if ( pNtkNew != NULL && !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkFastMap: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcIvy.c b/src/base/abci/abcIvy.c index dae5408d..9793a4e2 100644 --- a/src/base/abci/abcIvy.c +++ b/src/base/abci/abcIvy.c @@ -383,7 +383,7 @@ Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk ) // Ivy_ManRequiredLevels( pMan ); -// Pla_ManFastLutMap( pMan, 8 ); +// Ivy_FastMapPerform( pMan, 8 ); Ivy_ManStop( pMan ); return NULL; diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c index 81059a0f..c7e2acc0 100644 --- a/src/base/abci/abcPrint.c +++ b/src/base/abci/abcPrint.c @@ -31,6 +31,9 @@ //extern int s_TotalNodes = 0; //extern int s_TotalChanges = 0; +int s_MappingTime = 0; +int s_MappingMem = 0; + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -141,18 +144,20 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored ) } */ -/* + // print the statistic into a file { FILE * pTable; - pTable = fopen( "fpga_stats.txt", "a+" ); + pTable = fopen( "fpga/fpga_stats.txt", "a+" ); fprintf( pTable, "%s ", pNtk->pName ); + fprintf( pTable, "%d ", Abc_NtkGetLevelNum(pNtk) ); fprintf( pTable, "%d ", Abc_NtkNodeNum(pNtk) ); - fprintf( pTable, "%d ", Abc_AigGetLevelNum(pNtk) ); + fprintf( pTable, "%.2f ", (float)(s_MappingMem)/(float)(1<<20) ); + fprintf( pTable, "%.2f", (float)(s_MappingTime)/(float)(CLOCKS_PER_SEC) ); fprintf( pTable, "\n" ); fclose( pTable ); } -*/ + /* // print the statistic into a file diff --git a/src/base/abci/abcTiming.c b/src/base/abci/abcTiming.c index 8364b783..af06436f 100644 --- a/src/base/abci/abcTiming.c +++ b/src/base/abci/abcTiming.c @@ -646,7 +646,7 @@ void Abc_NtkStartReverseLevels( Abc_Ntk_t * pNtk ) Vec_Ptr_t * vNodes; Abc_Obj_t * pObj, * pFanout; int i, k, nLevelsCur; - assert( Abc_NtkIsStrash(pNtk) ); +// assert( Abc_NtkIsStrash(pNtk) ); // remember the maximum number of direct levels // pNtk->LevelMax = Abc_AigGetLevelNum(pNtk); pNtk->LevelMax = Abc_NtkGetLevelNum(pNtk); diff --git a/src/map/fpga/fpga.c b/src/map/fpga/fpga.c index be817713..d04c9910 100644 --- a/src/map/fpga/fpga.c +++ b/src/map/fpga/fpga.c @@ -248,18 +248,26 @@ usage: ***********************************************************************/ void Fpga_SetSimpleLutLib( int nLutSize ) { + Fpga_LutLib_t s_LutLib10= { "lutlib",10, {0,1,1,1,1,1,1,1,1,1,1}, {0,1,1,1,1,1,1,1,1,1,1} }; + Fpga_LutLib_t s_LutLib9 = { "lutlib", 9, {0,1,1,1,1,1,1,1,1,1}, {0,1,1,1,1,1,1,1,1,1} }; + Fpga_LutLib_t s_LutLib8 = { "lutlib", 8, {0,1,1,1,1,1,1,1,1}, {0,1,1,1,1,1,1,1,1} }; + Fpga_LutLib_t s_LutLib7 = { "lutlib", 7, {0,1,1,1,1,1,1,1}, {0,1,1,1,1,1,1,1} }; Fpga_LutLib_t s_LutLib6 = { "lutlib", 6, {0,1,1,1,1,1,1}, {0,1,1,1,1,1,1} }; Fpga_LutLib_t s_LutLib5 = { "lutlib", 5, {0,1,1,1,1,1}, {0,1,1,1,1,1} }; Fpga_LutLib_t s_LutLib4 = { "lutlib", 4, {0,1,1,1,1}, {0,1,1,1,1} }; Fpga_LutLib_t s_LutLib3 = { "lutlib", 3, {0,1,1,1}, {0,1,1,1} }; Fpga_LutLib_t * pLutLib; - assert( nLutSize >= 3 && nLutSize <= 6 ); + assert( nLutSize >= 3 && nLutSize <= 10 ); switch ( nLutSize ) { - case 3: pLutLib = &s_LutLib3; break; - case 4: pLutLib = &s_LutLib4; break; - case 5: pLutLib = &s_LutLib5; break; - case 6: pLutLib = &s_LutLib6; break; + case 3: pLutLib = &s_LutLib3; break; + case 4: pLutLib = &s_LutLib4; break; + case 5: pLutLib = &s_LutLib5; break; + case 6: pLutLib = &s_LutLib6; break; + case 7: pLutLib = &s_LutLib7; break; + case 8: pLutLib = &s_LutLib8; break; + case 9: pLutLib = &s_LutLib9; break; + case 10: pLutLib = &s_LutLib10; break; default: pLutLib = NULL; break; } if ( pLutLib == NULL ) diff --git a/src/map/fpga/fpgaCore.c b/src/map/fpga/fpgaCore.c index fbf33816..56facf20 100644 --- a/src/map/fpga/fpgaCore.c +++ b/src/map/fpga/fpgaCore.c @@ -24,6 +24,10 @@ static int Fpga_MappingPostProcess( Fpga_Man_t * p ); +extern int s_MappingTime; +extern int s_MappingMem; + + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -70,6 +74,9 @@ int Fpga_Mapping( Fpga_Man_t * p ) p->timeRecover = clock() - clk; //PRT( "Total mapping time", clock() - clkTotal ); + s_MappingTime = clock() - clkTotal; + s_MappingMem = Fpga_CutCountAll(p) * (sizeof(Fpga_Cut_t) - sizeof(int) * (FPGA_MAX_LEAVES - p->nVarsMax)); + // print the AI-graph used for mapping //Fpga_ManShow( p, "test" ); if ( p->fVerbose ) diff --git a/src/map/fpga/fpgaCut.c b/src/map/fpga/fpgaCut.c index 01562708..3bb5feb4 100644 --- a/src/map/fpga/fpgaCut.c +++ b/src/map/fpga/fpgaCut.c @@ -35,9 +35,11 @@ struct Fpga_CutTableStrutct_t }; // the largest number of cuts considered -#define FPGA_CUTS_MAX_COMPUTE 500 +//#define FPGA_CUTS_MAX_COMPUTE 500 +#define FPGA_CUTS_MAX_COMPUTE 2000 // the largest number of cuts used -#define FPGA_CUTS_MAX_USE 200 +//#define FPGA_CUTS_MAX_USE 200 +#define FPGA_CUTS_MAX_USE 1000 // primes used to compute the hash key static int s_HashPrimes[10] = { 109, 499, 557, 619, 631, 709, 797, 881, 907, 991 }; @@ -130,7 +132,7 @@ void Fpga_MappingCuts( Fpga_Man_t * p ) int nCuts, nNodes, i; // set the elementary cuts for the PI variables - assert( p->nVarsMax > 1 && p->nVarsMax < 7 ); + assert( p->nVarsMax > 1 && p->nVarsMax < 11 ); Fpga_MappingCreatePiCuts( p ); // compute the cuts for the internal nodes @@ -347,8 +349,8 @@ void Fpga_CutFilter( Fpga_Man_t * p, Fpga_Node_t * pNode ) Fpga_Cut_t * Fpga_CutMergeLists( Fpga_Man_t * p, Fpga_CutTable_t * pTable, Fpga_Cut_t * pList1, Fpga_Cut_t * pList2, int fComp1, int fComp2, int fPivot1, int fPivot2 ) { - Fpga_Node_t * ppNodes[6]; - Fpga_Cut_t * pListNew, ** ppListNew, * pLists[7] = { NULL }; + Fpga_Node_t * ppNodes[FPGA_MAX_LEAVES]; + Fpga_Cut_t * pListNew, ** ppListNew, * pLists[FPGA_MAX_LEAVES+1] = { NULL }; Fpga_Cut_t * pCut, * pPrev, * pTemp1, * pTemp2; int nNodes, Counter, i; Fpga_Cut_t ** ppArray1, ** ppArray2, ** ppArray3; @@ -532,8 +534,8 @@ QUITS : Fpga_Cut_t * Fpga_CutMergeLists2( Fpga_Man_t * p, Fpga_CutTable_t * pTable, Fpga_Cut_t * pList1, Fpga_Cut_t * pList2, int fComp1, int fComp2, int fPivot1, int fPivot2 ) { - Fpga_Node_t * ppNodes[6]; - Fpga_Cut_t * pListNew, ** ppListNew, * pLists[7] = { NULL }; + Fpga_Node_t * ppNodes[FPGA_MAX_LEAVES]; + Fpga_Cut_t * pListNew, ** ppListNew, * pLists[FPGA_MAX_LEAVES+1] = { NULL }; Fpga_Cut_t * pCut, * pPrev, * pTemp1, * pTemp2; int nNodes, Counter, i; diff --git a/src/map/fpga/fpgaInt.h b/src/map/fpga/fpgaInt.h index 74ab321c..60f18080 100644 --- a/src/map/fpga/fpgaInt.h +++ b/src/map/fpga/fpgaInt.h @@ -46,7 +46,7 @@ #endif // the maximum number of cut leaves (currently does not work for 7) -#define FPGA_MAX_LEAVES 6 +#define FPGA_MAX_LEAVES 10 // the bit masks #define FPGA_MASK(n) ((~((unsigned)0)) >> (32-(n))) diff --git a/src/temp/ivy/ivy.h b/src/temp/ivy/ivy.h index fcf58cb4..864d5e8c 100644 --- a/src/temp/ivy/ivy.h +++ b/src/temp/ivy/ivy.h @@ -425,6 +425,11 @@ extern void Ivy_ObjPatchFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_ extern void Ivy_ObjCollectFanouts( Ivy_Man_t * p, Ivy_Obj_t * pObj, Vec_Ptr_t * vArray ); extern Ivy_Obj_t * Ivy_ObjReadFirstFanout( Ivy_Man_t * p, Ivy_Obj_t * pObj ); extern int Ivy_ObjFanoutNum( Ivy_Man_t * p, Ivy_Obj_t * pObj ); +/*=== ivyFastMap.c =============================================================*/ +extern void Ivy_FastMapPerform( Ivy_Man_t * pAig, int nLimit ); +extern void Ivy_FastMapStop( Ivy_Man_t * pAig ); +extern void Ivy_FastMapReadSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Int_t * vLeaves ); +extern void Ivy_FastMapReverseLevel( Ivy_Man_t * pAig ); /*=== ivyHaig.c ==========================================================*/ extern void Ivy_ManHaigStart( Ivy_Man_t * p, int fVerbose ); extern void Ivy_ManHaigTrasfer( Ivy_Man_t * p, Ivy_Man_t * pNew ); diff --git a/src/temp/ivy/ivyFastMap.c b/src/temp/ivy/ivyFastMap.c new file mode 100644 index 00000000..1d74fd13 --- /dev/null +++ b/src/temp/ivy/ivyFastMap.c @@ -0,0 +1,1088 @@ +/**CFile**************************************************************** + + FileName [ivyFastMap.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [Fast FPGA mapping.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - May 11, 2006.] + + Revision [$Id: ivyFastMap.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define IVY_INFINITY 10000 + +typedef struct Ivy_SuppMan_t_ Ivy_SuppMan_t; +struct Ivy_SuppMan_t_ +{ + int nLimit; // the limit on the number of inputs + int nObjs; // the number of entries + int nSize; // size of each entry in bytes + char * pMem; // memory allocated + Vec_Vec_t * vLuts; // the array of nodes used in the mapping +}; + +typedef struct Ivy_Supp_t_ Ivy_Supp_t; +struct Ivy_Supp_t_ +{ + char nSize; // the number of support nodes + char fMark; // multipurpose mask + char fMark2; // multipurpose mask + char fMark3; // multipurpose mask + int nRefs; // the number of references + short Delay; // the delay of the node + short DelayR; // the reverse delay of the node + int pArray[0]; // the support nodes +}; + +static inline Ivy_Supp_t * Ivy_ObjSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) +{ + return (Ivy_Supp_t *)(((Ivy_SuppMan_t*)pAig->pData)->pMem + pObj->Id * ((Ivy_SuppMan_t*)pAig->pData)->nSize); +} +static inline Ivy_Supp_t * Ivy_ObjSuppStart( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) +{ + Ivy_Supp_t * pSupp; + pSupp = Ivy_ObjSupp( pAig, pObj ); + pSupp->fMark = 0; + pSupp->Delay = 0; + pSupp->nSize = 1; + pSupp->pArray[0] = pObj->Id; + return pSupp; +} + +static int Ivy_FastMapPrint( Ivy_Man_t * pAig, int Time ); +static int Ivy_FastMapDelay( Ivy_Man_t * pAig ); +static int Ivy_FastMapArea( Ivy_Man_t * pAig ); +static void Ivy_FastMapNode( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit ); +static int Ivy_FastMapMerge( Ivy_Supp_t * pSupp0, Ivy_Supp_t * pSupp1, Ivy_Supp_t * pSupp, int nLimit ); +static void Ivy_FastMapRequired( Ivy_Man_t * pAig, int Delay ); +static void Ivy_FastMapRecover( Ivy_Man_t * pAig, int nLimit ); +static int Ivy_FastMapNodeDelay( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ); +static int Ivy_FastMapNodeAreaRefed( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ); +static int Ivy_FastMapNodeAreaDerefed( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ); +static void Ivy_FastMapNodeRecover( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront, Vec_Ptr_t * vFrontOld ); + + +extern int s_MappingTime; +extern int s_MappingMem; + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs fast K-LUT mapping of the AIG.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_FastMapPerform( Ivy_Man_t * pAig, int nLimit ) +{ + Ivy_SuppMan_t * pMan; + Ivy_Obj_t * pObj; + int i, Delay, clk, clkTotal = clock(); + // start the memory for supports + pMan = ALLOC( Ivy_SuppMan_t, 1 ); + memset( pMan, 0, sizeof(Ivy_SuppMan_t) ); + pMan->nLimit = nLimit; + pMan->nObjs = Ivy_ManObjIdMax(pAig) + 1; + pMan->nSize = sizeof(Ivy_Supp_t) + nLimit * sizeof(int); + pMan->pMem = (char *)malloc( pMan->nObjs * pMan->nSize ); + pMan->vLuts = Vec_VecAlloc( 100 ); + pAig->pData = pMan; +clk = clock(); + // set the PI mapping + Ivy_ObjSuppStart( pAig, Ivy_ManConst1(pAig) ); + Ivy_ManForEachPi( pAig, pObj, i ) + Ivy_ObjSuppStart( pAig, pObj ); + // iterate through all nodes in the topological order + Ivy_ManForEachNode( pAig, pObj, i ) + Ivy_FastMapNode( pAig, pObj, nLimit ); + // find the best arrival time and area + printf( "Delay oriented mapping: " ); + Delay = Ivy_FastMapPrint( pAig, clock() - clk ); + + // perform area recovery +clk = clock(); + Ivy_FastMapRequired( pAig, Delay ); +// PRT( "Required time computation", clock() - clk ); + + // remap the nodes + Ivy_FastMapRecover( pAig, nLimit ); + printf( "Area recovery : " ); + Delay = Ivy_FastMapPrint( pAig, clock() - clk ); + + // perform area recovery +clk = clock(); + Ivy_FastMapRequired( pAig, Delay ); +// PRT( "Required time computation", clock() - clk ); + + // remap the nodes + Ivy_FastMapRecover( pAig, nLimit ); + printf( "Area recovery : " ); + Delay = Ivy_FastMapPrint( pAig, clock() - clk ); + + s_MappingTime = clock() - clkTotal; + s_MappingMem = pMan->nObjs * pMan->nSize; +} + +/**Function************************************************************* + + Synopsis [Cleans memory used for decomposition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_FastMapStop( Ivy_Man_t * pAig ) +{ + Ivy_SuppMan_t * p = pAig->pData; + Vec_VecFree( p->vLuts ); + free( p->pMem ); + free( p ); + pAig->pData = NULL; +} + +/**Function************************************************************* + + Synopsis [Prints statistics.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_FastMapPrint( Ivy_Man_t * pAig, int Time ) +{ + int Delay, Area; + Delay = Ivy_FastMapDelay( pAig ); + Area = Ivy_FastMapArea( pAig ); + printf( "Delay = %3d. Area = %6d. ", Delay, Area ); + PRT( "Time", Time ); + return Delay; +} + +/**Function************************************************************* + + Synopsis [Computes delay after LUT mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_FastMapDelay( Ivy_Man_t * pAig ) +{ + Ivy_Supp_t * pSupp; + Ivy_Obj_t * pObj; + int i, DelayMax = 0; + Ivy_ManForEachPo( pAig, pObj, i ) + { + pObj = Ivy_ObjFanin0(pObj); + if ( !Ivy_ObjIsNode(pObj) ) + continue; + pSupp = Ivy_ObjSupp( pAig, pObj ); + if ( DelayMax < pSupp->Delay ) + DelayMax = pSupp->Delay; + } + return DelayMax; +} + +/**Function************************************************************* + + Synopsis [Computes area after mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_FastMapArea_rec( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Vec_t * vLuts ) +{ + Ivy_Supp_t * pSupp; + int i, Counter; + pSupp = Ivy_ObjSupp( pAig, pObj ); + // skip visited nodes and PIs + if ( pSupp->fMark || pSupp->nSize == 1 ) + return 0; + pSupp->fMark = 1; + // compute the area of this node + Counter = 0; + for ( i = 0; i < pSupp->nSize; i++ ) + Counter += Ivy_FastMapArea_rec( pAig, Ivy_ManObj(pAig, pSupp->pArray[i]), vLuts ); + // add the node to the array of LUTs + Vec_VecPush( vLuts, pSupp->Delay, pObj ); + return 1 + Counter; +} + +/**Function************************************************************* + + Synopsis [Computes area after mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_FastMapArea( Ivy_Man_t * pAig ) +{ + Vec_Vec_t * vLuts; + Ivy_Obj_t * pObj; + int i, Counter = 0; + // get the array to store the nodes + vLuts = ((Ivy_SuppMan_t *)pAig->pData)->vLuts; + Vec_VecClear( vLuts ); + // explore starting from each node + Ivy_ManForEachPo( pAig, pObj, i ) + Counter += Ivy_FastMapArea_rec( pAig, Ivy_ObjFanin0(pObj), vLuts ); + // clean the marks + Ivy_ManForEachNode( pAig, pObj, i ) + Ivy_ObjSupp( pAig, pObj )->fMark = 0; + return Counter; +} + +/**Function************************************************************* + + Synopsis [Performs fast mapping for one node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_FastMapNode( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit ) +{ + Ivy_Supp_t * pSupp0, * pSupp1, * pSupp; + int RetValue; + assert( Ivy_ObjIsNode(pObj) ); + // get the supports + pSupp0 = Ivy_ObjSupp( pAig, Ivy_ObjFanin0(pObj) ); + pSupp1 = Ivy_ObjSupp( pAig, Ivy_ObjFanin1(pObj) ); + pSupp = Ivy_ObjSupp( pAig, pObj ); + pSupp->fMark = 0; + // get the delays + if ( pSupp0->Delay == pSupp1->Delay ) + pSupp->Delay = (pSupp0->Delay == 0) ? pSupp0->Delay + 1: pSupp0->Delay; + else if ( pSupp0->Delay > pSupp1->Delay ) + { + pSupp->Delay = pSupp0->Delay; + pSupp1 = Ivy_ObjSupp( pAig, Ivy_ManConst1(pAig) ); + pSupp1->pArray[0] = Ivy_ObjFaninId1(pObj); + } + else // if ( pSupp0->Delay < pSupp1->Delay ) + { + pSupp->Delay = pSupp1->Delay; + pSupp0 = Ivy_ObjSupp( pAig, Ivy_ManConst1(pAig) ); + pSupp0->pArray[0] = Ivy_ObjFaninId0(pObj); + } + // merge the cuts + if ( pSupp0->nSize < pSupp1->nSize ) + RetValue = Ivy_FastMapMerge( pSupp1, pSupp0, pSupp, nLimit ); + else + RetValue = Ivy_FastMapMerge( pSupp0, pSupp1, pSupp, nLimit ); + if ( !RetValue ) + { + pSupp->Delay++; + pSupp->nSize = 2; + pSupp->pArray[0] = Ivy_ObjFaninId0(pObj); + pSupp->pArray[1] = Ivy_ObjFaninId1(pObj); + } + assert( pSupp->Delay > 0 ); +} + +/**Function************************************************************* + + Synopsis [Merges two supports] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_FastMapMerge( Ivy_Supp_t * pSupp0, Ivy_Supp_t * pSupp1, Ivy_Supp_t * pSupp, int nLimit ) +{ + int i, k, c; + assert( pSupp0->nSize >= pSupp1->nSize ); + // the case of the largest cut sizes + if ( pSupp0->nSize == nLimit && pSupp1->nSize == nLimit ) + { + for ( i = 0; i < pSupp0->nSize; i++ ) + if ( pSupp0->pArray[i] != pSupp1->pArray[i] ) + return 0; + for ( i = 0; i < pSupp0->nSize; i++ ) + pSupp->pArray[i] = pSupp0->pArray[i]; + pSupp->nSize = pSupp0->nSize; + return 1; + } + // the case when one of the cuts is the largest + if ( pSupp0->nSize == nLimit ) + { + for ( i = 0; i < pSupp1->nSize; i++ ) + { + for ( k = pSupp0->nSize - 1; k >= 0; k-- ) + if ( pSupp0->pArray[k] == pSupp1->pArray[i] ) + break; + if ( k == -1 ) // did not find + return 0; + } + for ( i = 0; i < pSupp0->nSize; i++ ) + pSupp->pArray[i] = pSupp0->pArray[i]; + pSupp->nSize = pSupp0->nSize; + return 1; + } + + // compare two cuts with different numbers + i = k = 0; + for ( c = 0; c < nLimit; c++ ) + { + if ( k == pSupp1->nSize ) + { + if ( i == pSupp0->nSize ) + { + pSupp->nSize = c; + return 1; + } + pSupp->pArray[c] = pSupp0->pArray[i++]; + continue; + } + if ( i == pSupp0->nSize ) + { + if ( k == pSupp1->nSize ) + { + pSupp->nSize = c; + return 1; + } + pSupp->pArray[c] = pSupp1->pArray[k++]; + continue; + } + if ( pSupp0->pArray[i] < pSupp1->pArray[k] ) + { + pSupp->pArray[c] = pSupp0->pArray[i++]; + continue; + } + if ( pSupp0->pArray[i] > pSupp1->pArray[k] ) + { + pSupp->pArray[c] = pSupp1->pArray[k++]; + continue; + } + pSupp->pArray[c] = pSupp0->pArray[i++]; + k++; + } + if ( i < pSupp0->nSize || k < pSupp1->nSize ) + return 0; + pSupp->nSize = c; + return 1; +} + +/**Function************************************************************* + + Synopsis [Creates integer vector with the support of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_FastMapReadSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Int_t * vLeaves ) +{ + Ivy_Supp_t * pSupp; + pSupp = Ivy_ObjSupp( pAig, pObj ); + vLeaves->nCap = 8; + vLeaves->nSize = pSupp->nSize; + vLeaves->pArray = pSupp->pArray; +} + +/**Function************************************************************* + + Synopsis [Computes the required times for each node.] + + Description [Sets reference counters for each node.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_FastMapRequired( Ivy_Man_t * pAig, int Delay ) +{ + Vec_Vec_t * vLuts; + Vec_Ptr_t * vNodes; + Ivy_Obj_t * pObj; + Ivy_Supp_t * pSupp, * pSuppF; + int i, k, c; + // clean the required times + Ivy_ManForEachPi( pAig, pObj, i ) + { + pSupp = Ivy_ObjSupp( pAig, pObj ); + pSupp->DelayR = IVY_INFINITY; + pSupp->nRefs = 0; + } + Ivy_ManForEachNode( pAig, pObj, i ) + { + pSupp = Ivy_ObjSupp( pAig, pObj ); + pSupp->DelayR = IVY_INFINITY; + pSupp->nRefs = 0; + } + // set the required times of the POs + Ivy_ManForEachPo( pAig, pObj, i ) + { + pSupp = Ivy_ObjSupp( pAig, Ivy_ObjFanin0(pObj) ); + pSupp->DelayR = Delay; + pSupp->nRefs++; + } + // get the levelized nodes used in the mapping + vLuts = ((Ivy_SuppMan_t *)pAig->pData)->vLuts; + // propagate the required times + Vec_VecForEachLevelReverse( vLuts, vNodes, i ) + Vec_PtrForEachEntry( vNodes, pObj, k ) + { + pSupp = Ivy_ObjSupp( pAig, pObj ); + assert( pSupp->nRefs > 0 ); + for ( c = 0; c < pSupp->nSize; c++ ) + { + pSuppF = Ivy_ObjSupp( pAig, Ivy_ManObj(pAig, pSupp->pArray[c]) ); + pSuppF->DelayR = IVY_MIN( pSuppF->DelayR, pSupp->DelayR - 1 ); + pSuppF->nRefs++; + } + } +/* + // print out some of the required times + Ivy_ManForEachPi( pAig, pObj, i ) + { + pSupp = Ivy_ObjSupp( pAig, pObj ); + printf( "%d ", pSupp->DelayR ); + } + printf( "\n" ); +*/ +} + +/**Function************************************************************* + + Synopsis [Performs area recovery for each node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_FastMapRecover( Ivy_Man_t * pAig, int nLimit ) +{ + Vec_Ptr_t * vFront, * vFrontOld; + Ivy_Obj_t * pObj; + int i; + vFront = Vec_PtrAlloc( nLimit ); + vFrontOld = Vec_PtrAlloc( nLimit ); + Ivy_ManCleanTravId( pAig ); + // iterate through all nodes in the topological order + Ivy_ManForEachNode( pAig, pObj, i ) + Ivy_FastMapNodeRecover( pAig, pObj, nLimit, vFront, vFrontOld ); + Vec_PtrFree( vFrontOld ); + Vec_PtrFree( vFront ); +} + +/**Function************************************************************* + + Synopsis [Computes the delay of the cut rooted at this node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_FastMapNodeDelay( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) +{ + Ivy_Supp_t * pSupp, * pSuppF; + int c, Delay = 0; + pSupp = Ivy_ObjSupp( pAig, pObj ); + for ( c = 0; c < pSupp->nSize; c++ ) + { + pSuppF = Ivy_ObjSupp( pAig, Ivy_ManObj(pAig, pSupp->pArray[c]) ); + Delay = IVY_MAX( Delay, pSuppF->Delay ); + } + return 1 + Delay; +} + + +/**function************************************************************* + + synopsis [References the cut.] + + description [This procedure is similar to the procedure NodeReclaim.] + + sideeffects [] + + seealso [] + +***********************************************************************/ +int Ivy_FastMapNodeRef( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) +{ + Ivy_Supp_t * pSupp, * pSuppF; + Ivy_Obj_t * pNodeChild; + int aArea, i; + // start the area of this cut + aArea = 1; + // go through the children + pSupp = Ivy_ObjSupp( pAig, pObj ); + assert( pSupp->nSize > 1 ); + for ( i = 0; i < pSupp->nSize; i++ ) + { + pNodeChild = Ivy_ManObj(pAig, pSupp->pArray[i]); + pSuppF = Ivy_ObjSupp( pAig, pNodeChild ); + assert( pSuppF->nRefs >= 0 ); + if ( pSuppF->nRefs++ > 0 ) + continue; + if ( pSuppF->nSize == 1 ) + continue; + aArea += Ivy_FastMapNodeRef( pAig, pNodeChild ); + } + return aArea; +} + +/**function************************************************************* + + synopsis [Dereferences the cut.] + + description [This procedure is similar to the procedure NodeRecusiveDeref.] + + sideeffects [] + + seealso [] + +***********************************************************************/ +int Ivy_FastMapNodeDeref( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) +{ + Ivy_Supp_t * pSupp, * pSuppF; + Ivy_Obj_t * pNodeChild; + int aArea, i; + // start the area of this cut + aArea = 1; + // go through the children + pSupp = Ivy_ObjSupp( pAig, pObj ); + assert( pSupp->nSize > 1 ); + for ( i = 0; i < pSupp->nSize; i++ ) + { + pNodeChild = Ivy_ManObj(pAig, pSupp->pArray[i]); + pSuppF = Ivy_ObjSupp( pAig, pNodeChild ); + assert( pSuppF->nRefs > 0 ); + if ( --pSuppF->nRefs > 0 ) + continue; + if ( pSuppF->nSize == 1 ) + continue; + aArea += Ivy_FastMapNodeDeref( pAig, pNodeChild ); + } + return aArea; +} + +/**function************************************************************* + + synopsis [Computes the exact area associated with the cut.] + + description [] + + sideeffects [] + + seealso [] + +***********************************************************************/ +int Ivy_FastMapNodeAreaRefed( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) +{ + Ivy_Supp_t * pSupp; + int aResult, aResult2; + if ( Ivy_ObjIsCi(pObj) ) + return 0; + assert( Ivy_ObjIsNode(pObj) ); + pSupp = Ivy_ObjSupp( pAig, pObj ); + assert( pSupp->nRefs > 0 ); + aResult = Ivy_FastMapNodeDeref( pAig, pObj ); + aResult2 = Ivy_FastMapNodeRef( pAig, pObj ); + assert( aResult == aResult2 ); + return aResult; +} + +/**function************************************************************* + + synopsis [Computes the exact area associated with the cut.] + + description [] + + sideeffects [] + + seealso [] + +***********************************************************************/ +int Ivy_FastMapNodeAreaDerefed( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) +{ + Ivy_Supp_t * pSupp; + int aResult, aResult2; + if ( Ivy_ObjIsCi(pObj) ) + return 0; + assert( Ivy_ObjIsNode(pObj) ); + pSupp = Ivy_ObjSupp( pAig, pObj ); + assert( pSupp->nRefs == 0 ); + aResult2 = Ivy_FastMapNodeRef( pAig, pObj ); + aResult = Ivy_FastMapNodeDeref( pAig, pObj ); + assert( aResult == aResult2 ); + return aResult; +} + + + + +/**Function************************************************************* + + Synopsis [Counts the number of nodes with no external fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_FastMapCutCost( Ivy_Man_t * pAig, Vec_Ptr_t * vFront ) +{ + Ivy_Supp_t * pSuppF; + Ivy_Obj_t * pFanin; + int i, Counter = 0; + Vec_PtrForEachEntry( vFront, pFanin, i ) + { + pSuppF = Ivy_ObjSupp( pAig, pFanin ); + if ( pSuppF->nRefs == 1 ) + Counter++; + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [Performs area recovery for each node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_FastMapMark_rec( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) +{ + if ( Ivy_ObjIsTravIdCurrent(pAig, pObj) ) + return; + assert( Ivy_ObjIsNode(pObj) ); + Ivy_FastMapMark_rec( pAig, Ivy_ObjFanin0(pObj) ); + Ivy_FastMapMark_rec( pAig, Ivy_ObjFanin1(pObj) ); + Ivy_ObjSetTravIdCurrent(pAig, pObj); +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the number of fanins will grow.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_FastMapNodeWillGrow( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) +{ + Ivy_Obj_t * pFanin0, * pFanin1; + assert( Ivy_ObjIsNode(pObj) ); + pFanin0 = Ivy_ObjFanin0(pObj); + pFanin1 = Ivy_ObjFanin1(pObj); + return !Ivy_ObjIsTravIdCurrent(pAig, pFanin0) && !Ivy_ObjIsTravIdCurrent(pAig, pFanin1); +} + +/**Function************************************************************* + + Synopsis [Returns the increase in the number of fanins with no external refs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_FastMapNodeFaninCost( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) +{ + Ivy_Supp_t * pSuppF; + Ivy_Obj_t * pFanin; + int Counter = 0; + assert( Ivy_ObjIsNode(pObj) ); + // check if the node has external refs + pSuppF = Ivy_ObjSupp( pAig, pObj ); + if ( pSuppF->nRefs == 1 ) + Counter--; + // increment the number of fanins without external refs + pFanin = Ivy_ObjFanin0(pObj); + pSuppF = Ivy_ObjSupp( pAig, pFanin ); + if ( !Ivy_ObjIsTravIdCurrent(pAig, pFanin) && pSuppF->nRefs == 1 ) + Counter++; + // increment the number of fanins without external refs + pFanin = Ivy_ObjFanin1(pObj); + pSuppF = Ivy_ObjSupp( pAig, pFanin ); + if ( !Ivy_ObjIsTravIdCurrent(pAig, pFanin) && pSuppF->nRefs == 1 ) + Counter++; + return Counter; +} + +/**Function************************************************************* + + Synopsis [Updates the frontier.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_FastMapNodeFaninUpdate( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Ptr_t * vFront ) +{ + Ivy_Obj_t * pFanin; + assert( Ivy_ObjIsNode(pObj) ); + Vec_PtrRemove( vFront, pObj ); + pFanin = Ivy_ObjFanin0(pObj); + if ( !Ivy_ObjIsTravIdCurrent(pAig, pFanin) ) + { + Ivy_ObjSetTravIdCurrent(pAig, pFanin); + Vec_PtrPush( vFront, pFanin ); + } + pFanin = Ivy_ObjFanin1(pObj); + if ( !Ivy_ObjIsTravIdCurrent(pAig, pFanin) ) + { + Ivy_ObjSetTravIdCurrent(pAig, pFanin); + Vec_PtrPush( vFront, pFanin ); + } +} + +/**Function************************************************************* + + Synopsis [Compacts the number of external refs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_FastMapNodeFaninCompact0( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront ) +{ + Ivy_Obj_t * pFanin; + int i; + Vec_PtrForEachEntry( vFront, pFanin, i ) + { + if ( Ivy_ObjIsCi(pFanin) ) + continue; + if ( Ivy_FastMapNodeWillGrow(pAig, pFanin) ) + continue; + if ( Ivy_FastMapNodeFaninCost(pAig, pFanin) <= 0 ) + { + Ivy_FastMapNodeFaninUpdate( pAig, pFanin, vFront ); + return 1; + } + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Compacts the number of external refs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_FastMapNodeFaninCompact1( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront ) +{ + Ivy_Obj_t * pFanin; + int i; + Vec_PtrForEachEntry( vFront, pFanin, i ) + { + if ( Ivy_ObjIsCi(pFanin) ) + continue; + if ( Ivy_FastMapNodeFaninCost(pAig, pFanin) < 0 ) + { + Ivy_FastMapNodeFaninUpdate( pAig, pFanin, vFront ); + return 1; + } + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Compacts the number of external refs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_FastMapNodeFaninCompact2( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront ) +{ + Ivy_Obj_t * pFanin; + int i; + Vec_PtrForEachEntry( vFront, pFanin, i ) + { + if ( Ivy_ObjIsCi(pFanin) ) + continue; + if ( Ivy_FastMapNodeFaninCost(pAig, pFanin) <= 0 ) + { + Ivy_FastMapNodeFaninUpdate( pAig, pFanin, vFront ); + return 1; + } + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Compacts the number of external refs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ivy_FastMapNodeFaninCompact_int( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront ) +{ + if ( Ivy_FastMapNodeFaninCompact0(pAig, pObj, nLimit, vFront) ) + return 1; + if ( Vec_PtrSize(vFront) < nLimit && Ivy_FastMapNodeFaninCompact1(pAig, pObj, nLimit, vFront) ) + return 1; + if ( Vec_PtrSize(vFront) < nLimit && Ivy_FastMapNodeFaninCompact2(pAig, pObj, nLimit, vFront) ) + return 1; + assert( Vec_PtrSize(vFront) <= nLimit ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Compacts the number of external refs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_FastMapNodeFaninCompact( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront ) +{ + while ( Ivy_FastMapNodeFaninCompact_int( pAig, pObj, nLimit, vFront ) ); +} + +/**Function************************************************************* + + Synopsis [Prepares node mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_FastMapNodePrepare( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront, Vec_Ptr_t * vFrontOld ) +{ + Ivy_Supp_t * pSupp; + Ivy_Obj_t * pFanin; + int i; + pSupp = Ivy_ObjSupp( pAig, pObj ); + // expand the cut downwards from the given place + Vec_PtrClear( vFront ); + Vec_PtrClear( vFrontOld ); + Ivy_ManIncrementTravId( pAig ); + for ( i = 0; i < pSupp->nSize; i++ ) + { + pFanin = Ivy_ManObj(pAig, pSupp->pArray[i]); + Vec_PtrPush( vFront, pFanin ); + Vec_PtrPush( vFrontOld, pFanin ); + Ivy_ObjSetTravIdCurrent( pAig, pFanin ); + } + // mark the nodes in the cone + Ivy_FastMapMark_rec( pAig, pObj ); +} + +/**Function************************************************************* + + Synopsis [Updates the frontier.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_FastMapNodeUpdate( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Ptr_t * vFront ) +{ + Ivy_Supp_t * pSupp; + Ivy_Obj_t * pFanin; + int i; + pSupp = Ivy_ObjSupp( pAig, pObj ); + // deref node's cut + Ivy_FastMapNodeDeref( pAig, pObj ); + // update the node's cut + pSupp->nSize = Vec_PtrSize(vFront); + Vec_PtrForEachEntry( vFront, pFanin, i ) + pSupp->pArray[i] = pFanin->Id; + // ref the new cut + Ivy_FastMapNodeRef( pAig, pObj ); +} + +/**Function************************************************************* + + Synopsis [Performs area recovery for each node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_FastMapNodeRecover2( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront, Vec_Ptr_t * vFrontOld ) +{ + Ivy_Supp_t * pSupp; + int CostBef, CostAft; + int AreaBef, AreaAft; + pSupp = Ivy_ObjSupp( pAig, pObj ); +// if ( pSupp->nRefs == 0 ) +// return; + if ( pSupp->nRefs == 0 ) + AreaBef = Ivy_FastMapNodeAreaDerefed( pAig, pObj ); + else + AreaBef = Ivy_FastMapNodeAreaRefed( pAig, pObj ); + // get the area + if ( AreaBef == 1 ) + return; + + if ( pSupp->nRefs == 0 ) + { + pSupp->nRefs = 1000000; + Ivy_FastMapNodeRef( pAig, pObj ); + } + // the cut is non-trivial + Ivy_FastMapNodePrepare( pAig, pObj, nLimit, vFront, vFrontOld ); + // iteratively modify the cut + CostBef = Ivy_FastMapCutCost( pAig, vFront ); + Ivy_FastMapNodeFaninCompact( pAig, pObj, nLimit, vFront ); + CostAft = Ivy_FastMapCutCost( pAig, vFront ); + assert( CostBef >= CostAft ); + // update the node + Ivy_FastMapNodeUpdate( pAig, pObj, vFront ); + // get the new area + AreaAft = Ivy_FastMapNodeAreaRefed( pAig, pObj ); + if ( AreaAft > AreaBef ) + { + Ivy_FastMapNodeUpdate( pAig, pObj, vFrontOld ); + AreaAft = Ivy_FastMapNodeAreaRefed( pAig, pObj ); + assert( AreaAft == AreaBef ); + } + if ( pSupp->nRefs == 1000000 ) + { + pSupp->nRefs = 0; + Ivy_FastMapNodeDeref( pAig, pObj ); + } +} + +/**Function************************************************************* + + Synopsis [Performs area recovery for each node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_FastMapNodeRecover( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit, Vec_Ptr_t * vFront, Vec_Ptr_t * vFrontOld ) +{ + Ivy_Supp_t * pSupp; + int CostBef, CostAft; + int AreaBef, AreaAft; + pSupp = Ivy_ObjSupp( pAig, pObj ); + if ( pSupp->nRefs == 0 ) + return; + // get the area + AreaBef = Ivy_FastMapNodeAreaRefed( pAig, pObj ); + if ( AreaBef == 1 ) + return; + // the cut is non-trivial + Ivy_FastMapNodePrepare( pAig, pObj, nLimit, vFront, vFrontOld ); + // iteratively modify the cut + CostBef = Ivy_FastMapCutCost( pAig, vFront ); + Ivy_FastMapNodeFaninCompact( pAig, pObj, nLimit, vFront ); + CostAft = Ivy_FastMapCutCost( pAig, vFront ); + assert( CostBef >= CostAft ); + // update the node + Ivy_FastMapNodeUpdate( pAig, pObj, vFront ); + // get the new area + AreaAft = Ivy_FastMapNodeAreaRefed( pAig, pObj ); + if ( AreaAft > AreaBef ) + { + Ivy_FastMapNodeUpdate( pAig, pObj, vFrontOld ); + AreaAft = Ivy_FastMapNodeAreaRefed( pAig, pObj ); + assert( AreaAft == AreaBef ); + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyIsop.c b/src/temp/ivy/ivyIsop.c index 1a4fce25..1887eb6a 100644 --- a/src/temp/ivy/ivyIsop.c +++ b/src/temp/ivy/ivyIsop.c @@ -26,7 +26,7 @@ //////////////////////////////////////////////////////////////////////// // ISOP computation fails if intermediate memory usage exceed this limit -#define IVY_ISOP_MEM_LIMIT 4096 +#define IVY_ISOP_MEM_LIMIT 16*4096 // intermediate ISOP representation typedef struct Ivy_Sop_t_ Ivy_Sop_t; diff --git a/src/temp/ivy/module.make b/src/temp/ivy/module.make index c208c8ee..05409745 100644 --- a/src/temp/ivy/module.make +++ b/src/temp/ivy/module.make @@ -5,6 +5,7 @@ SRC += src/temp/ivy/ivyBalance.c \ src/temp/ivy/ivyDfs.c \ src/temp/ivy/ivyDsd.c \ src/temp/ivy/ivyFanout.c \ + src/temp/ivy/ivyFastMap.c \ src/temp/ivy/ivyIsop.c \ src/temp/ivy/ivyMan.c \ src/temp/ivy/ivyMem.c \ diff --git a/src/temp/player/module.make b/src/temp/player/module.make index 37e236bb..5185f56e 100644 --- a/src/temp/player/module.make +++ b/src/temp/player/module.make @@ -1,5 +1,4 @@ SRC += src/temp/player/playerToAbc.c \ - src/temp/player/playerFast.c \ src/temp/player/playerCore.c \ src/temp/player/playerMan.c \ src/temp/player/playerUtil.c diff --git a/src/temp/player/player.h b/src/temp/player/player.h index 0213683f..a4ee5650 100644 --- a/src/temp/player/player.h +++ b/src/temp/player/player.h @@ -89,11 +89,6 @@ static inline Pla_Obj_t * Ivy_ObjPlaStr( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { extern void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int fFastMode, int fRewriting, int fSynthesis, int fVerbose ); /*=== playerCore.c =============================================================*/ extern Pla_Man_t * Pla_ManDecompose( Ivy_Man_t * p, int nLutMax, int nPlaMax, int fVerbose ); -/*=== playerFast.c =============================================================*/ -extern void Pla_ManFastLutMap( Ivy_Man_t * pAig, int nLimit ); -extern void Pla_ManFastLutMapStop( Ivy_Man_t * pAig ); -extern void Pla_ManFastLutMapReadSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Int_t * vLeaves ); -extern void Pla_ManFastLutMapReverseLevel( Ivy_Man_t * pAig ); /*=== playerMan.c ==============================================================*/ extern Pla_Man_t * Pla_ManAlloc( Ivy_Man_t * p, int nLutMax, int nPlaMax ); extern void Pla_ManFree( Pla_Man_t * p ); diff --git a/src/temp/player/playerFast.c b/src/temp/player/playerFast.c deleted file mode 100644 index c8edc1db..00000000 --- a/src/temp/player/playerFast.c +++ /dev/null @@ -1,367 +0,0 @@ -/**CFile**************************************************************** - - FileName [playerFast.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [PLA decomposition package.] - - Synopsis [Fast 8-LUT mapper.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - May 11, 2006.] - - Revision [$Id: playerFast.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "player.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Ivy_SuppMan_t_ Ivy_SuppMan_t; -struct Ivy_SuppMan_t_ -{ - int nLimit; // the limit on the number of inputs - int nObjs; // the number of entries - int nSize; // size of each entry in bytes - char * pMem; // memory allocated -}; - -typedef struct Ivy_Supp_t_ Ivy_Supp_t; -struct Ivy_Supp_t_ -{ - char nSize; // the number of support nodes - char fMark; // the node was processed for area counting - short Delay; // the delay of the node - int pArray[0]; // the support nodes -}; - -static inline Ivy_Supp_t * Ivy_ObjSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) -{ - return (Ivy_Supp_t *)(((Ivy_SuppMan_t*)pAig->pData)->pMem + pObj->Id * ((Ivy_SuppMan_t*)pAig->pData)->nSize); -} -static inline Ivy_Supp_t * Ivy_ObjSuppStart( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) -{ - Ivy_Supp_t * pSupp; - pSupp = Ivy_ObjSupp( pAig, pObj ); - pSupp->fMark = 0; - pSupp->Delay = 0; - pSupp->nSize = 1; - pSupp->pArray[0] = pObj->Id; - return pSupp; -} - -static int Pla_ManFastLutMapDelay( Ivy_Man_t * pAig ); -static int Pla_ManFastLutMapArea( Ivy_Man_t * pAig ); -static void Pla_ManFastLutMapNode( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit ); -static int Pla_ManFastLutMapMerge( Ivy_Supp_t * pSupp0, Ivy_Supp_t * pSupp1, Ivy_Supp_t * pSupp, int nLimit ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs fast K-LUT mapping of the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Pla_ManFastLutMap( Ivy_Man_t * pAig, int nLimit ) -{ - Ivy_SuppMan_t * pMan; - Ivy_Obj_t * pObj; - int i, Delay, Area; - int clk = clock(), clk2; - // start the memory for supports - pMan = ALLOC( Ivy_SuppMan_t, 1 ); - memset( pMan, 0, sizeof(Ivy_SuppMan_t) ); - pMan->nLimit = nLimit; - pMan->nObjs = Ivy_ManObjIdMax(pAig) + 1; - pMan->nSize = sizeof(Ivy_Supp_t) + nLimit * sizeof(int); - pMan->pMem = (char *)malloc( pMan->nObjs * pMan->nSize ); - pAig->pData = pMan; -clk2 = clock(); - // set the PI mapping - Ivy_ObjSuppStart( pAig, Ivy_ManConst1(pAig) ); - Ivy_ManForEachPi( pAig, pObj, i ) - Ivy_ObjSuppStart( pAig, pObj ); - // iterate through all nodes in the topological order - Ivy_ManForEachNode( pAig, pObj, i ) - Pla_ManFastLutMapNode( pAig, pObj, nLimit ); - // find the best arrival time and area - Delay = Pla_ManFastLutMapDelay( pAig ); - Area = Pla_ManFastLutMapArea( pAig ); -clk2 = clock() - clk2; - // print the report - printf( "LUT levels = %3d. LUT number = %6d. ", Delay, Area ); - PRT( "Mapping time", clk2 ); -// PRT( "Total", clock() - clk ); -// Pla_ManFastLutMapStop( pAig ); -} - -/**Function************************************************************* - - Synopsis [Cleans memory used for decomposition.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Pla_ManFastLutMapStop( Ivy_Man_t * pAig ) -{ - free( ((Ivy_SuppMan_t*)pAig->pData)->pMem ); - free( pAig->pData ); - pAig->pData = NULL; -} - -/**Function************************************************************* - - Synopsis [Computes delay after LUT mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Pla_ManFastLutMapDelay( Ivy_Man_t * pAig ) -{ - Ivy_Supp_t * pSupp; - Ivy_Obj_t * pObj; - int i, DelayMax = 0; - Ivy_ManForEachPo( pAig, pObj, i ) - { - pObj = Ivy_ObjFanin0(pObj); - if ( !Ivy_ObjIsNode(pObj) ) - continue; - pSupp = Ivy_ObjSupp( pAig, pObj ); - if ( DelayMax < pSupp->Delay ) - DelayMax = pSupp->Delay; - } - return DelayMax; -} - -/**Function************************************************************* - - Synopsis [Computes area after mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Pla_ManFastLutMapArea_rec( Ivy_Man_t * pAig, Ivy_Obj_t * pObj ) -{ - Ivy_Supp_t * pSupp; - int i, Counter; - pSupp = Ivy_ObjSupp( pAig, pObj ); - // skip visited nodes and PIs - if ( pSupp->fMark || pSupp->nSize == 1 ) - return 0; - pSupp->fMark = 1; - // compute the area of this node - Counter = 0; - for ( i = 0; i < pSupp->nSize; i++ ) - Counter += Pla_ManFastLutMapArea_rec( pAig, Ivy_ManObj(pAig, pSupp->pArray[i]) ); - return 1 + Counter; -} - -/**Function************************************************************* - - Synopsis [Computes area after mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Pla_ManFastLutMapArea( Ivy_Man_t * pAig ) -{ - Ivy_Obj_t * pObj; - int i, Counter = 0; - Ivy_ManForEachPo( pAig, pObj, i ) - Counter += Pla_ManFastLutMapArea_rec( pAig, Ivy_ObjFanin0(pObj) ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [Performs fast mapping for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Pla_ManFastLutMapNode( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, int nLimit ) -{ - Ivy_Supp_t * pSupp0, * pSupp1, * pSupp; - int RetValue; - assert( Ivy_ObjIsNode(pObj) ); - // get the supports - pSupp0 = Ivy_ObjSupp( pAig, Ivy_ObjFanin0(pObj) ); - pSupp1 = Ivy_ObjSupp( pAig, Ivy_ObjFanin1(pObj) ); - pSupp = Ivy_ObjSupp( pAig, pObj ); - pSupp->fMark = 0; - // get the delays - if ( pSupp0->Delay == pSupp1->Delay ) - pSupp->Delay = (pSupp0->Delay == 0) ? pSupp0->Delay + 1: pSupp0->Delay; - else if ( pSupp0->Delay > pSupp1->Delay ) - { - pSupp->Delay = pSupp0->Delay; - pSupp1 = Ivy_ObjSupp( pAig, Ivy_ManConst1(pAig) ); - pSupp1->pArray[0] = Ivy_ObjFaninId1(pObj); - } - else // if ( pSupp0->Delay < pSupp1->Delay ) - { - pSupp->Delay = pSupp1->Delay; - pSupp0 = Ivy_ObjSupp( pAig, Ivy_ManConst1(pAig) ); - pSupp0->pArray[0] = Ivy_ObjFaninId0(pObj); - } - // merge the cuts - if ( pSupp0->nSize < pSupp1->nSize ) - RetValue = Pla_ManFastLutMapMerge( pSupp1, pSupp0, pSupp, nLimit ); - else - RetValue = Pla_ManFastLutMapMerge( pSupp0, pSupp1, pSupp, nLimit ); - if ( !RetValue ) - { - pSupp->Delay++; - pSupp->nSize = 2; - pSupp->pArray[0] = Ivy_ObjFaninId0(pObj); - pSupp->pArray[1] = Ivy_ObjFaninId1(pObj); - } - assert( pSupp->Delay > 0 ); -} - -/**Function************************************************************* - - Synopsis [Merges two supports] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Pla_ManFastLutMapMerge( Ivy_Supp_t * pSupp0, Ivy_Supp_t * pSupp1, Ivy_Supp_t * pSupp, int nLimit ) -{ - int i, k, c; - assert( pSupp0->nSize >= pSupp1->nSize ); - // the case of the largest cut sizes - if ( pSupp0->nSize == nLimit && pSupp1->nSize == nLimit ) - { - for ( i = 0; i < pSupp0->nSize; i++ ) - if ( pSupp0->pArray[i] != pSupp1->pArray[i] ) - return 0; - for ( i = 0; i < pSupp0->nSize; i++ ) - pSupp->pArray[i] = pSupp0->pArray[i]; - pSupp->nSize = pSupp0->nSize; - return 1; - } - // the case when one of the cuts is the largest - if ( pSupp0->nSize == nLimit ) - { - for ( i = 0; i < pSupp1->nSize; i++ ) - { - for ( k = pSupp0->nSize - 1; k >= 0; k-- ) - if ( pSupp0->pArray[k] == pSupp1->pArray[i] ) - break; - if ( k == -1 ) // did not find - return 0; - } - for ( i = 0; i < pSupp0->nSize; i++ ) - pSupp->pArray[i] = pSupp0->pArray[i]; - pSupp->nSize = pSupp0->nSize; - return 1; - } - - // compare two cuts with different numbers - i = k = 0; - for ( c = 0; c < nLimit; c++ ) - { - if ( k == pSupp1->nSize ) - { - if ( i == pSupp0->nSize ) - { - pSupp->nSize = c; - return 1; - } - pSupp->pArray[c] = pSupp0->pArray[i++]; - continue; - } - if ( i == pSupp0->nSize ) - { - if ( k == pSupp1->nSize ) - { - pSupp->nSize = c; - return 1; - } - pSupp->pArray[c] = pSupp1->pArray[k++]; - continue; - } - if ( pSupp0->pArray[i] < pSupp1->pArray[k] ) - { - pSupp->pArray[c] = pSupp0->pArray[i++]; - continue; - } - if ( pSupp0->pArray[i] > pSupp1->pArray[k] ) - { - pSupp->pArray[c] = pSupp1->pArray[k++]; - continue; - } - pSupp->pArray[c] = pSupp0->pArray[i++]; - k++; - } - if ( i < pSupp0->nSize || k < pSupp1->nSize ) - return 0; - pSupp->nSize = c; - return 1; -} - -/**Function************************************************************* - - Synopsis [Creates integer vector with the support of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Pla_ManFastLutMapReadSupp( Ivy_Man_t * pAig, Ivy_Obj_t * pObj, Vec_Int_t * vLeaves ) -{ - Ivy_Supp_t * pSupp; - pSupp = Ivy_ObjSupp( pAig, pObj ); - vLeaves->nCap = 8; - vLeaves->nSize = pSupp->nSize; - vLeaves->pArray = pSupp->pArray; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/temp/player/playerToAbc.c b/src/temp/player/playerToAbc.c index d53ad291..e06eca28 100644 --- a/src/temp/player/playerToAbc.c +++ b/src/temp/player/playerToAbc.c @@ -88,13 +88,14 @@ void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int f if ( fFastMode ) { // perform mapping into LUTs - Pla_ManFastLutMap( pMan, nLutMax ); + Ivy_FastMapPerform( pMan, nLutMax ); // convert from the extended AIG manager into an SOP network pNtkNew = Ivy_ManToAbc( pNtk, pMan, NULL, fFastMode ); - Pla_ManFastLutMapStop( pMan ); + Ivy_FastMapStop( pMan ); } else { + assert( nLutMax >= 2 && nLutMax <= 8 ); // perform decomposition/mapping into PLAs/LUTs p = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose ); // convert from the extended AIG manager into an SOP network @@ -109,7 +110,7 @@ void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int RankCost, int f Abc_NtkDelete( pNtkNew ); return NULL; } - Abc_NtkPlayerCost( pNtkNew, RankCost, fVerbose ); +// Abc_NtkPlayerCost( pNtkNew, RankCost, fVerbose ); return pNtkNew; } @@ -168,7 +169,7 @@ Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtk, Ivy_Man_t * pMan, Pla_Man_t * p, int // start the new ABC network pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); // transfer the pointers to the basic nodes - Abc_ObjSetIvy2Abc( pMan, Ivy_ManConst1(pMan)->Id, Abc_AigConst1(pNtkNew) ); + Abc_ObjSetIvy2Abc( pMan, Ivy_ManConst1(pMan)->Id, Abc_NodeCreateConst1(pNtkNew) ); Abc_NtkForEachCi( pNtkNew, pObjAbc, i ) Abc_ObjSetIvy2Abc( pMan, Ivy_ManPi(pMan, i)->Id, pObjAbc ); // recursively construct the network @@ -370,7 +371,7 @@ Abc_Obj_t * Ivy_ManToAbcFast_rec( Abc_Ntk_t * pNtkNew, Ivy_Man_t * pMan, Ivy_Obj return pObjAbc; assert( Ivy_ObjIsAnd(pObjIvy) || Ivy_ObjIsExor(pObjIvy) ); // get the support of K-LUT - Pla_ManFastLutMapReadSupp( pMan, pObjIvy, vSupp ); + Ivy_FastMapReadSupp( pMan, pObjIvy, vSupp ); // create new ABC node and its fanins pObjAbc = Abc_NtkCreateNode( pNtkNew ); Vec_IntForEachEntry( vSupp, Entry, i ) |