Commit aab0c478 by Alan Mishchenko

Version abc60909

parent c5c9e37a
......@@ -2050,6 +2050,10 @@ SOURCE=.\src\temp\ivy\ivyFanout.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\ivy\ivyFastMap.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\ivy\ivyHaig.c
# End Source File
# Begin Source File
......@@ -2114,10 +2118,6 @@ SOURCE=.\src\temp\player\playerCore.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\player\playerFast.c
# End Source File
# Begin Source File
SOURCE=.\src\temp\player\playerMan.c
# End Source File
# Begin Source File
......
......@@ -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;
......
......@@ -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;
......
/**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 ///
////////////////////////////////////////////////////////////////////////
......@@ -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;
......
......@@ -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
......
......@@ -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);
......
......@@ -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 )
......
......@@ -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 )
......
......@@ -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;
......
......@@ -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)))
......
......@@ -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 );
......
/**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 ///
////////////////////////////////////////////////////////////////////////
......@@ -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;
......
......@@ -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 \
......
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
......@@ -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 );
......
/**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 ///
////////////////////////////////////////////////////////////////////////
......@@ -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 )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment