summaryrefslogtreecommitdiffstats
path: root/src/map/if
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2006-11-22 08:01:00 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2006-11-22 08:01:00 -0800
commit6ad22b4d3b0446652919d95b15fefb374bddfac0 (patch)
treeeb525005c9827e844464c4e787c5907c7edc1d5c /src/map/if
parentda5e0785dfb98335bd49a13bf9e86e736fb931be (diff)
downloadabc-6ad22b4d3b0446652919d95b15fefb374bddfac0.tar.gz
abc-6ad22b4d3b0446652919d95b15fefb374bddfac0.tar.bz2
abc-6ad22b4d3b0446652919d95b15fefb374bddfac0.zip
Version abc61122
Diffstat (limited to 'src/map/if')
-rw-r--r--src/map/if/if.h255
-rw-r--r--src/map/if/ifCore.c47
-rw-r--r--src/map/if/ifCut.c47
-rw-r--r--src/map/if/ifMan.c250
-rw-r--r--src/map/if/ifMap.c391
-rw-r--r--src/map/if/ifUtil.c229
-rw-r--r--src/map/if/if_.c47
-rw-r--r--src/map/if/module.make4
8 files changed, 1270 insertions, 0 deletions
diff --git a/src/map/if/if.h b/src/map/if/if.h
new file mode 100644
index 00000000..04e1541e
--- /dev/null
+++ b/src/map/if/if.h
@@ -0,0 +1,255 @@
+/**CFile****************************************************************
+
+ FileName [if.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [FPGA mapping based on priority cuts.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - November 21, 2006.]
+
+ Revision [$Id: if.h,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __IF_H__
+#define __IF_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+#include "vec.h"
+#include "mem.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+// the maximum size of LUTs used for mapping (should be the same as FPGA_MAX_LUTSIZE defined in "fpga.h"!!!)
+#define IF_MAX_LUTSIZE 32
+
+// object types
+typedef enum {
+ IF_NONE, // 0: non-existent object
+ IF_CONST1, // 1: constant 1
+ IF_PI, // 2: primary input
+ IF_PO, // 3: primary output
+ IF_AND, // 4: AND node
+ IF_BI, // 5: box input
+ IF_BO, // 6: box output
+ IF_BOX, // 7: box
+ IF_VOID // 8: unused object
+} Hop_Type_t;
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct If_Par_t_ If_Par_t;
+typedef struct If_Lib_t_ If_Lib_t;
+typedef struct If_Man_t_ If_Man_t;
+typedef struct If_Obj_t_ If_Obj_t;
+typedef struct If_Cut_t_ If_Cut_t;
+
+// parameters
+struct If_Par_t_
+{
+ int Mode; // the mapping mode
+ int nLutSize; // the LUT size
+ If_Lib_t * pLutLib; // the LUT library
+ int nCutsMax; // the max number of cuts
+ int fVerbose; // the verbosity flag
+ int fSeq; // sequential mapping
+ int fLatchPaths; // reset timing on latch paths
+ int nLatches; // the number of latches
+ float DelayTarget; // delay target
+ float * pTimesArr; // arrival times
+ float * pTimesReq; // required times
+};
+
+// the LUT library
+struct If_Lib_t_
+{
+ char * pName; // the name of the LUT library
+ int LutMax; // the maximum LUT size
+ float pLutAreas[IF_MAX_LUTSIZE+1]; // the areas of LUTs
+ float pLutDelays[IF_MAX_LUTSIZE+1];// the delays of LUTs
+};
+
+// manager
+struct If_Man_t_
+{
+ // mapping parameters
+ If_Par_t * pPars;
+ // mapping nodes
+ If_Obj_t * pConst1; // the constant 1 node
+ Vec_Ptr_t * vPis; // the primary inputs
+ Vec_Ptr_t * vPos; // the primary outputs
+ Vec_Ptr_t * vObjs; // all objects
+ Vec_Ptr_t * vMapped; // objects used in the mapping
+ Vec_Ptr_t * vTemp; // temporary array
+ int nObjs[IF_VOID];// the number of objects by type
+ // various data
+ int nLevelMax; // the max number of AIG levels
+ float fEpsilon; // epsilon used for comparison
+ float RequiredGlo; // global required times
+ float AreaGlo; // global area
+ // memory management
+ Mem_Fixed_t * pMem; // memory manager
+ int nEntrySize; // the size of the entry
+ int nEntryBase; // the size of the entry minus cut leaf arrays
+ // temporary cut storage
+ int nCuts; // the number of cuts used
+ If_Cut_t ** ppCuts; // the storage space for cuts
+};
+
+// priority cut
+struct If_Cut_t_
+{
+ float Delay; // the delay of the cut
+ float Flow; // the area flow of the cut
+ float Area; // the area of the cut
+ If_Cut_t * pOne; // the parent cut
+ If_Cut_t * pTwo; // the parent cut
+ char fCompl0; // the complemented attribute
+ char fCompl1; // the complemented attribute
+ char Phase; // the complemented attribute
+ char nLeaves; // the number of leaves
+ int * pLeaves; // the array of fanins
+};
+
+// node extension
+struct If_Obj_t_
+{
+ unsigned Type : 4; // object
+ unsigned fCompl0 : 1; // complemented attribute
+ unsigned fCompl1 : 1; // complemented attribute
+ unsigned fPhase : 1; // phase of the node
+ unsigned fMark : 1; // multipurpose mark
+ unsigned Level : 24; // logic level of the node
+ int Id; // integer ID
+ int nRefs; // the number of references
+ short nCuts; // the number of cuts
+ short iCut; // the number of the best cut
+ If_Obj_t * pFanin0; // the first fanin
+ If_Obj_t * pFanin1; // the second fanin
+ If_Obj_t * pEquiv; // the choice node
+ float EstRefs; // estimated reference counter
+ float Required; // required time of the onde
+ void * pCopy; // used for duplication
+ If_Cut_t Cuts[0]; // the cuts of the node
+};
+
+static inline If_Obj_t * If_ManConst1( If_Man_t * p ) { return p->pConst1; }
+static inline If_Obj_t * If_ManPi( If_Man_t * p, int i ) { return (If_Obj_t *)Vec_PtrEntry( p->vPis, i ); }
+static inline If_Obj_t * If_ManPo( If_Man_t * p, int i ) { return (If_Obj_t *)Vec_PtrEntry( p->vPos, i ); }
+static inline If_Obj_t * If_ManObj( If_Man_t * p, int i ) { return (If_Obj_t *)Vec_PtrEntry( p->vObjs, i ); }
+static inline If_Cut_t * If_ManCut( If_Man_t * p, int i ) { return p->ppCuts[i]; }
+
+static inline int If_ObjIsConst1( If_Obj_t * pObj ) { return pObj->Type == IF_CONST1; }
+static inline int If_ObjIsPi( If_Obj_t * pObj ) { return pObj->Type == IF_PI; }
+static inline int If_ObjIsPo( If_Obj_t * pObj ) { return pObj->Type == IF_PO; }
+static inline int If_ObjIsAnd( If_Obj_t * pObj ) { return pObj->Type == IF_AND; }
+static inline int If_ObjIsBi( If_Obj_t * pObj ) { return pObj->Type == IF_BI; }
+static inline int If_ObjIsBo( If_Obj_t * pObj ) { return pObj->Type == IF_BO; }
+static inline int If_ObjIsBox( If_Obj_t * pObj ) { return pObj->Type == IF_BOX; }
+
+static inline If_Obj_t * If_ObjFanin0( If_Obj_t * pObj ) { return pObj->pFanin0; }
+static inline If_Obj_t * If_ObjFanin1( If_Obj_t * pObj ) { return pObj->pFanin1; }
+static inline int If_ObjFaninC0( If_Obj_t * pObj ) { return pObj->fCompl0; }
+static inline int If_ObjFaninC1( If_Obj_t * pObj ) { return pObj->fCompl1; }
+static inline void * If_ObjCopy( If_Obj_t * pObj ) { return pObj->pCopy; }
+static inline void If_ObjSetCopy( If_Obj_t * pObj, void * pCopy ) { pObj->pCopy = pCopy; }
+static inline void If_ObjSetChoice( If_Obj_t * pObj, If_Obj_t * pEqu ) { pObj->pEquiv = pEqu; }
+
+static inline If_Cut_t * If_ObjCut( If_Obj_t * pObj, int iCut ) { return pObj->Cuts + iCut; }
+static inline If_Cut_t * If_ObjCutTriv( If_Obj_t * pObj ) { return pObj->Cuts; }
+static inline If_Cut_t * If_ObjCutBest( If_Obj_t * pObj ) { return pObj->Cuts + pObj->iCut; }
+
+static inline void * If_CutData( If_Cut_t * pCut ) { return *(void **)pCut; }
+static inline void If_CutSetData( If_Cut_t * pCut, void * pData ) { *(void **)pCut = pData; }
+
+static inline float If_CutLutDelay( If_Man_t * p, If_Cut_t * pCut ) { return p->pPars->pLutLib? p->pPars->pLutLib->pLutDelays[pCut->nLeaves] : (float)1.0; }
+static inline float If_CutLutArea( If_Man_t * p, If_Cut_t * pCut ) { return p->pPars->pLutLib? p->pPars->pLutLib->pLutAreas[pCut->nLeaves] : (float)1.0; }
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define IF_MIN(a,b) (((a) < (b))? (a) : (b))
+#define IF_MAX(a,b) (((a) > (b))? (a) : (b))
+
+// the small and large numbers (min/max float are 1.17e-38/3.40e+38)
+#define IF_FLOAT_LARGE ((float)1.0e+20)
+#define IF_FLOAT_SMALL ((float)1.0e-20)
+#define IF_INT_LARGE (10000000)
+
+// iterator over the primary inputs
+#define If_ManForEachPi( p, pObj, i ) \
+ Vec_PtrForEachEntry( p->vPis, pObj, i )
+// iterator over the primary outputs
+#define If_ManForEachPo( p, pObj, i ) \
+ Vec_PtrForEachEntry( p->vPos, pObj, i )
+// iterator over the latches
+#define If_ManForEachLatch( p, pObj, i ) \
+ Vec_PtrForEachEntryStart( p->vPos, pObj, i, p->pPars->nLatches )
+// iterator over all objects, including those currently not used
+#define If_ManForEachObj( p, pObj, i ) \
+ Vec_PtrForEachEntry( p->vObjs, pObj, i )
+// iterator over logic nodes (AND and EXOR gates)
+#define If_ManForEachNode( p, pObj, i ) \
+ If_ManForEachObj( p, pObj, i ) if ( pObj->Type != IF_AND ) {} else
+// iterator over cuts of the node
+#define If_ObjForEachCut( pObj, pCut, i ) \
+ for ( i = 0; (i < (int)(pObj)->nCuts) && ((pCut) = (pObj)->Cuts + i); i++ )
+// iterator over cuts of the node
+#define If_ObjForEachCutStart( pObj, pCut, i, Start ) \
+ for ( i = Start; (i < (int)(pObj)->nCuts) && ((pCut) = (pObj)->Cuts + i); i++ )
+// iterator leaves of the cut
+#define If_CutForEachLeaf( p, pCut, pLeaf, i ) \
+ for ( i = 0; (i < (int)(pCut)->nLeaves) && ((pLeaf) = If_ManObj(p, (pCut)->pLeaves[i])); i++ )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== ifMan.c ==========================================================*/
+extern If_Man_t * If_ManStart( If_Par_t * pPars );
+extern void If_ManStop( If_Man_t * p );
+extern If_Obj_t * If_ManCreatePi( If_Man_t * p );
+extern If_Obj_t * If_ManCreatePo( If_Man_t * p, If_Obj_t * pDriver, int fCompl0 );
+extern If_Obj_t * If_ManCreateAnd( If_Man_t * p, If_Obj_t * pFan0, int fCompl0, If_Obj_t * pFan1, int fCompl1 );
+/*=== ifMap.c ==========================================================*/
+extern int If_ManPerformMapping( If_Man_t * p );
+/*=== ifUtil.c ==========================================================*/
+extern float If_ManDelayMax( If_Man_t * p );
+extern void If_ManCleanNodeCopy( If_Man_t * p );
+extern void If_ManCleanCutData( If_Man_t * p );
+extern float If_ManScanMapping( If_Man_t * p );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/map/if/ifCore.c b/src/map/if/ifCore.c
new file mode 100644
index 00000000..4d7e92d0
--- /dev/null
+++ b/src/map/if/ifCore.c
@@ -0,0 +1,47 @@
+/**CFile****************************************************************
+
+ FileName [ifCore.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [FPGA mapping based on priority cuts.]
+
+ Synopsis [The central part of the mapper.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - November 21, 2006.]
+
+ Revision [$Id: ifCore.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "if.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/map/if/ifCut.c b/src/map/if/ifCut.c
new file mode 100644
index 00000000..0318e5e5
--- /dev/null
+++ b/src/map/if/ifCut.c
@@ -0,0 +1,47 @@
+/**CFile****************************************************************
+
+ FileName [ifCut.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [FPGA mapping based on priority cuts.]
+
+ Synopsis [Cut computation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - November 21, 2006.]
+
+ Revision [$Id: ifCut.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "if.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/map/if/ifMan.c b/src/map/if/ifMan.c
new file mode 100644
index 00000000..616c5cf6
--- /dev/null
+++ b/src/map/if/ifMan.c
@@ -0,0 +1,250 @@
+/**CFile****************************************************************
+
+ FileName [ifMan.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [FPGA mapping based on priority cuts.]
+
+ Synopsis [Mapping manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - November 21, 2006.]
+
+ Revision [$Id: ifMan.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "if.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static If_Obj_t * If_ManSetupObj( If_Man_t * p );
+static If_Cut_t ** If_ManSetupCuts( If_Man_t * p );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Starts the AIG manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+If_Man_t * If_ManStart( If_Par_t * pPars )
+{
+ If_Man_t * p;
+ // start the manager
+ p = ALLOC( If_Man_t, 1 );
+ memset( p, 0, sizeof(If_Man_t) );
+ p->pPars = pPars;
+ p->fEpsilon = (float)0.001;
+ // allocate arrays for nodes
+ p->vPis = Vec_PtrAlloc( 100 );
+ p->vPos = Vec_PtrAlloc( 100 );
+ p->vObjs = Vec_PtrAlloc( 100 );
+ p->vMapped = Vec_PtrAlloc( 100 );
+ p->vTemp = Vec_PtrAlloc( 100 );
+ // prepare the memory manager
+ p->nEntrySize = sizeof(If_Obj_t) + p->pPars->nCutsMax * (sizeof(If_Cut_t) + sizeof(int) * p->pPars->nLutSize);
+ p->nEntryBase = sizeof(If_Obj_t) + p->pPars->nCutsMax * (sizeof(If_Cut_t));
+ p->pMem = Mem_FixedStart( p->nEntrySize );
+ // create the constant node
+ p->pConst1 = If_ManSetupObj( p );
+ p->pConst1->Type = IF_CONST1;
+ p->pConst1->fPhase = 1;
+ // create temporary cuts
+ p->ppCuts = If_ManSetupCuts( p );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void If_ManStop( If_Man_t * p )
+{
+ If_Cut_t * pTemp;
+ int i;
+ Vec_PtrFree( p->vPis );
+ Vec_PtrFree( p->vPos );
+ Vec_PtrFree( p->vObjs );
+ Vec_PtrFree( p->vMapped );
+ Vec_PtrFree( p->vTemp );
+ Mem_FixedStop( p->pMem, 0 );
+ // free pars memory
+ if ( p->pPars->pTimesArr )
+ FREE( p->pPars->pTimesArr );
+ if ( p->pPars->pTimesReq )
+ FREE( p->pPars->pTimesReq );
+ // free temporary cut memory
+ pTemp = p->ppCuts[0];
+ for ( i = 1; i < p->pPars->nCutsMax * p->pPars->nCutsMax; i++ )
+ if ( pTemp > p->ppCuts[i] )
+ pTemp = p->ppCuts[i];
+ free( pTemp );
+ free( p->ppCuts );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates primary input.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+If_Obj_t * If_ManCreatePi( If_Man_t * p )
+{
+ If_Obj_t * pObj;
+ pObj = If_ManSetupObj( p );
+ pObj->Type = IF_PI;
+ Vec_PtrPush( p->vPis, pObj );
+ p->nObjs[IF_PI]++;
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates primary output with the given driver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+If_Obj_t * If_ManCreatePo( If_Man_t * p, If_Obj_t * pDriver, int fCompl0 )
+{
+ If_Obj_t * pObj;
+ pObj = If_ManSetupObj( p );
+ pObj->Type = IF_PO;
+ pObj->fCompl0 = fCompl0;
+ Vec_PtrPush( p->vPos, pObj );
+ pObj->pFanin0 = pDriver; pDriver->nRefs++;
+ p->nObjs[IF_PO]++;
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create the new node assuming it does not exist.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+If_Obj_t * If_ManCreateAnd( If_Man_t * p, If_Obj_t * pFan0, int fCompl0, If_Obj_t * pFan1, int fCompl1 )
+{
+ If_Obj_t * pObj;
+ // get memory for the new object
+ pObj = If_ManSetupObj( p );
+ pObj->Type = IF_AND;
+ pObj->fCompl0 = fCompl0;
+ pObj->fCompl1 = fCompl1;
+ pObj->pFanin0 = pFan0; pFan0->nRefs++;
+ pObj->pFanin1 = pFan1; pFan1->nRefs++;
+ pObj->fPhase = (fCompl0? !pFan0->fPhase : pFan0->fPhase) & (fCompl1? !pFan1->fPhase : pFan1->fPhase);
+ pObj->Level = 1 + IF_MAX( pFan0->Level, pFan1->Level );
+ if ( p->nLevelMax < (int)pObj->Level )
+ p->nLevelMax = (int)pObj->Level;
+ p->nObjs[IF_AND]++;
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares memory for the node with cuts.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+If_Obj_t * If_ManSetupObj( If_Man_t * p )
+{
+ If_Obj_t * pObj;
+ int i, * pArrays;
+ // get memory for the object
+ pObj = (If_Obj_t *)Mem_FixedEntryFetch( p->pMem );
+ memset( pObj, 0, p->nEntryBase );
+ // organize memory
+ pArrays = (int *)((char *)pObj + p->nEntryBase);
+ for ( i = 0; i < p->pPars->nCutsMax; i++ )
+ pObj->Cuts[i].pLeaves = pArrays + i * p->pPars->nLutSize;
+ // assign ID and save
+ pObj->Id = Vec_PtrSize(p->vObjs);
+ Vec_PtrPush( p->vObjs, pObj );
+ // assign elementary cut
+ pObj->nCuts = 1;
+ pObj->Cuts[0].nLeaves = 1;
+ pObj->Cuts[0].pLeaves[0] = pObj->Id;
+ pObj->iCut = 0;
+ // set the required times
+ pObj->Required = IF_FLOAT_LARGE;
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares memory for additional cuts of the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+If_Cut_t ** If_ManSetupCuts( If_Man_t * p )
+{
+ If_Cut_t ** pCutStore;
+ int * pArrays, nCutSize, nCutsTotal, i;
+ nCutsTotal = p->pPars->nCutsMax * p->pPars->nCutsMax;
+ nCutSize = sizeof(If_Cut_t) + sizeof(int) * p->pPars->nLutSize;
+ pCutStore = (If_Cut_t **)ALLOC( If_Cut_t *, (nCutsTotal + 1) );
+ memset( pCutStore, 0, sizeof(If_Cut_t *) * (nCutsTotal + 1) );
+ pCutStore[0] = (If_Cut_t *)ALLOC( char, nCutSize * nCutsTotal );
+ memset( pCutStore[0], 0, nCutSize * nCutsTotal );
+ for ( i = 1; i < nCutsTotal; i++ )
+ pCutStore[i] = (If_Cut_t *)((char *)pCutStore[0] + sizeof(If_Cut_t) * i);
+ pArrays = (int *)((char *)pCutStore[0] + sizeof(If_Cut_t) * nCutsTotal);
+ for ( i = 0; i < nCutsTotal; i++ )
+ pCutStore[i]->pLeaves = pArrays + i * p->pPars->nLutSize;
+ return pCutStore;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/map/if/ifMap.c b/src/map/if/ifMap.c
new file mode 100644
index 00000000..5f2c4133
--- /dev/null
+++ b/src/map/if/ifMap.c
@@ -0,0 +1,391 @@
+/**CFile****************************************************************
+
+ FileName [ifMap.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [FPGA mapping based on priority cuts.]
+
+ Synopsis [Mapping procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - November 21, 2006.]
+
+ Revision [$Id: ifMap.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "if.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the object for FPGA mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int If_CutMerge( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC, int nLimit )
+{
+ int i, k, c;
+ assert( pC0->nLeaves >= pC1->nLeaves );
+ // the case of the largest cut sizes
+ if ( pC0->nLeaves == nLimit && pC1->nLeaves == nLimit )
+ {
+ for ( i = 0; i < pC0->nLeaves; i++ )
+ if ( pC0->pLeaves[i] != pC1->pLeaves[i] )
+ return 0;
+ for ( i = 0; i < pC0->nLeaves; i++ )
+ pC->pLeaves[i] = pC0->pLeaves[i];
+ pC->nLeaves = pC0->nLeaves;
+ return 1;
+ }
+ // the case when one of the cuts is the largest
+ if ( pC0->nLeaves == nLimit )
+ {
+ for ( i = 0; i < pC1->nLeaves; i++ )
+ {
+ for ( k = pC0->nLeaves - 1; k >= 0; k-- )
+ if ( pC0->pLeaves[k] == pC1->pLeaves[i] )
+ break;
+ if ( k == -1 ) // did not find
+ return 0;
+ }
+ for ( i = 0; i < pC0->nLeaves; i++ )
+ pC->pLeaves[i] = pC0->pLeaves[i];
+ pC->nLeaves = pC0->nLeaves;
+ return 1;
+ }
+
+ // compare two cuts with different numbers
+ i = k = 0;
+ for ( c = 0; c < nLimit; c++ )
+ {
+ if ( k == pC1->nLeaves )
+ {
+ if ( i == pC0->nLeaves )
+ {
+ pC->nLeaves = c;
+ return 1;
+ }
+ pC->pLeaves[c] = pC0->pLeaves[i++];
+ continue;
+ }
+ if ( i == pC0->nLeaves )
+ {
+ if ( k == pC1->nLeaves )
+ {
+ pC->nLeaves = c;
+ return 1;
+ }
+ pC->pLeaves[c] = pC1->pLeaves[k++];
+ continue;
+ }
+ if ( pC0->pLeaves[i] < pC1->pLeaves[k] )
+ {
+ pC->pLeaves[c] = pC0->pLeaves[i++];
+ continue;
+ }
+ if ( pC0->pLeaves[i] > pC1->pLeaves[k] )
+ {
+ pC->pLeaves[c] = pC1->pLeaves[k++];
+ continue;
+ }
+ pC->pLeaves[c] = pC0->pLeaves[i++];
+ k++;
+ }
+ if ( i < pC0->nLeaves || k < pC1->nLeaves )
+ return 0;
+ pC->nLeaves = c;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the object for FPGA mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int If_CutCompareDelay( If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
+{
+ If_Cut_t * pC0 = *ppC0;
+ If_Cut_t * pC1 = *ppC1;
+ if ( pC0->Delay < pC1->Delay )
+ return -1;
+ if ( pC0->Delay > pC1->Delay )
+ return 1;
+ if ( pC0->nLeaves < pC1->nLeaves )
+ return -1;
+ if ( pC0->nLeaves > pC1->nLeaves )
+ return 1;
+ if ( pC0->Flow < pC1->Flow )
+ return -1;
+ if ( pC0->Flow > pC1->Flow )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the object for FPGA mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int If_CutCompareArea( If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
+{
+ If_Cut_t * pC0 = *ppC0;
+ If_Cut_t * pC1 = *ppC1;
+ if ( pC0->Flow < pC1->Flow )
+ return -1;
+ if ( pC0->Flow > pC1->Flow )
+ return 1;
+ if ( pC0->nLeaves < pC1->nLeaves )
+ return -1;
+ if ( pC0->nLeaves > pC1->nLeaves )
+ return 1;
+ if ( pC0->Delay < pC1->Delay )
+ return -1;
+ if ( pC0->Delay > pC1->Delay )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes delay.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float If_CutDelay( If_Man_t * p, If_Cut_t * pCut )
+{
+ If_Obj_t * pLeaf;
+ float Delay;
+ int i;
+ Delay = -IF_FLOAT_LARGE;
+ If_CutForEachLeaf( p, pCut, pLeaf, i )
+ Delay = IF_MAX( Delay, If_ObjCutBest(pLeaf)->Delay );
+ return Delay + If_CutLutDelay(p, pCut);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes area flow.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float If_CutFlow( If_Man_t * p, If_Cut_t * pCut )
+{
+ If_Obj_t * pLeaf;
+ float Flow;
+ int i;
+ Flow = If_CutLutArea(p, pCut);
+ If_CutForEachLeaf( p, pCut, pLeaf, i )
+ Flow += If_ObjCutBest(pLeaf)->Flow / pLeaf->EstRefs;
+ return Flow;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes area of the first level.]
+
+ Description [The cut need to be derefed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float If_CutArea1( If_Man_t * p, If_Cut_t * pCut )
+{
+ If_Obj_t * pLeaf;
+ float Area;
+ int i;
+ Area = If_CutLutArea(p, pCut);
+ If_CutForEachLeaf( p, pCut, pLeaf, i )
+ if ( pLeaf->nRefs == 0 )
+ Area += If_CutLutArea(p, If_ObjCutBest(pLeaf));
+ return Area;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes area of the first level.]
+
+ Description [The cut need to be derefed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void If_CutRef1( If_Man_t * p, If_Cut_t * pCut )
+{
+ If_Obj_t * pLeaf;
+ int i;
+ If_CutForEachLeaf( p, pCut, pLeaf, i )
+ pLeaf->nRefs++;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes area of the first level.]
+
+ Description [The cut need to be derefed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void If_CutDeref1( If_Man_t * p, If_Cut_t * pCut )
+{
+ If_Obj_t * pLeaf;
+ int i;
+ If_CutForEachLeaf( p, pCut, pLeaf, i )
+ pLeaf->nRefs--;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes area of the first level.]
+
+ Description [The cut need to be derefed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void If_CutCopy( If_Cut_t * pCutDest, If_Cut_t * pCutSrc )
+{
+ int * pArray;
+ pArray = pCutDest->pLeaves;
+ *pCutDest = *pCutSrc;
+ pCutDest->pLeaves = pArray;
+ memcpy( pCutDest->pLeaves, pCutSrc->pLeaves, sizeof(int) * pCutSrc->nLeaves );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds the best cut.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj )
+{
+ If_Cut_t * pCut0, * pCut1, * pCut;
+ int i, k;
+ // create cross-product of the cuts
+ p->nCuts = 0;
+ pCut = p->ppCuts[0];
+ If_ObjForEachCut( pObj->pFanin0, pCut0, i )
+ If_ObjForEachCut( pObj->pFanin1, pCut1, k )
+ {
+ if ( pCut0->nLeaves < pCut1->nLeaves )
+ {
+ if ( !If_CutMerge( pCut1, pCut0, pCut, p->pPars->nLutSize ) )
+ continue;
+ }
+ else
+ {
+ if ( !If_CutMerge( pCut0, pCut1, pCut, p->pPars->nLutSize ) )
+ continue;
+ }
+ // the cuts have been successfully merged
+ pCut->pOne = pCut0; pCut->fCompl0 = pObj->fCompl0;
+ pCut->pTwo = pCut1; pCut->fCompl1 = pObj->fCompl1;
+// pCut->Phase = ...
+ pCut->Delay = If_CutDelay( p, pCut );
+ pCut->Flow = If_CutFlow( p, pCut );
+ // prepare room for the next cut
+ pCut = p->ppCuts[++p->nCuts];
+ }
+ // sort the cuts
+ if ( p->pPars->Mode == 1 ) // delay
+ qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareDelay );
+ else
+ qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareArea );
+ // take the first
+ pObj->nCuts = IF_MIN( p->nCuts + 1, p->pPars->nCutsMax );
+ If_ObjForEachCutStart( pObj, pCut, i, 1 )
+ If_CutCopy( pCut, p->ppCuts[i-1] );
+ pObj->iCut = 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Maps the nodes for delay.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int If_ManPerformMapping( If_Man_t * p )
+{
+ If_Obj_t * pObj;
+ float DelayBest;
+ int i, clk = clock();
+ // set arrival times and trivial cuts at const 1 and PIs
+ If_ManConst1(p)->Cuts[0].Delay = 0.0;
+ If_ManForEachPi( p, pObj, i )
+ pObj->Cuts[0].Delay = p->pPars->pTimesArr[i];
+ // set the initial fanout estimates
+ If_ManForEachObj( p, pObj, i )
+ pObj->EstRefs = (float)pObj->nRefs;
+ // map the internal nodes
+ If_ManForEachNode( p, pObj, i )
+ If_ObjPerformMapping( p, pObj );
+ // get the best arrival time of the POs
+ DelayBest = If_ManDelayMax(p);
+ printf( "Best delay = %d. ", (int)DelayBest );
+ PRT( "Time", clock() - clk );
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/map/if/ifUtil.c b/src/map/if/ifUtil.c
new file mode 100644
index 00000000..1144fa3f
--- /dev/null
+++ b/src/map/if/ifUtil.c
@@ -0,0 +1,229 @@
+/**CFile****************************************************************
+
+ FileName [ifUtil.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [FPGA mapping based on priority cuts.]
+
+ Synopsis [Various utilities.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - November 21, 2006.]
+
+ Revision [$Id: ifUtil.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "if.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Returns the max delay of the POs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float If_ManDelayMax( If_Man_t * p )
+{
+ If_Obj_t * pObj;
+ float DelayBest;
+ int i;
+ DelayBest = -IF_FLOAT_LARGE;
+ If_ManForEachPo( p, pObj, i )
+ if ( DelayBest < If_ObjCutBest( If_ObjFanin0(pObj) )->Delay )
+ DelayBest = If_ObjCutBest( If_ObjFanin0(pObj) )->Delay;
+ return DelayBest;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets all the node copy to NULL.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void If_ManCleanNodeCopy( If_Man_t * p )
+{
+ If_Obj_t * pObj;
+ int i;
+ If_ManForEachObj( p, pObj, i )
+ If_ObjSetCopy( pObj, NULL );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets all the cut data to NULL.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void If_ManCleanCutData( If_Man_t * p )
+{
+ If_Obj_t * pObj;
+ If_Cut_t * pCut;
+ int i, k;
+ If_ManForEachObj( p, pObj, i )
+ If_ObjForEachCut( pObj, pCut, k )
+ If_CutSetData( pCut, NULL );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes area, references, and nodes used in the mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float If_ManScanMapping_rec( If_Man_t * p, If_Obj_t * pObj, If_Obj_t ** ppStore )
+{
+ If_Obj_t * pLeaf;
+ If_Cut_t * pCutBest;
+ float aArea;
+ int i;
+ if ( pObj->nRefs++ || If_ObjIsPi(pObj) || If_ObjIsConst1(pObj) )
+ return 0.0;
+ // store the node in the structure by level
+ assert( If_ObjIsAnd(pObj) );
+ pObj->pCopy = (char *)ppStore[pObj->Level];
+ ppStore[pObj->Level] = pObj;
+ // visit the transitive fanin of the selected cut
+ pCutBest = If_ObjCutBest(pObj);
+ aArea = If_CutLutArea( p, pCutBest );
+ If_CutForEachLeaf( p, pCutBest, pLeaf, i )
+ aArea += If_ManScanMapping_rec( p, pLeaf, ppStore );
+ return aArea;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes area, references, and nodes used in the mapping.]
+
+ Description [Collects the nodes in reverse topological order in array
+ p->vMapping.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float If_ManScanMapping( If_Man_t * p )
+{
+ If_Obj_t * pObj, ** ppStore;
+ float aArea;
+ int i;
+ // clean all references
+ If_ManForEachObj( p, pObj, i )
+ {
+ pObj->Required = IF_FLOAT_LARGE;
+ pObj->nRefs = 0;
+ }
+ // allocate place to store the nodes
+ ppStore = ALLOC( If_Obj_t *, p->nLevelMax + 1 );
+ memset( ppStore, 0, sizeof(If_Obj_t *) * (p->nLevelMax + 1) );
+ // collect nodes reachable from POs in the DFS order through the best cuts
+ aArea = 0;
+ If_ManForEachPo( p, pObj, i )
+ aArea += If_ManScanMapping_rec( p, If_ObjFanin0(pObj), ppStore );
+ // reconnect the nodes in reverse topological order
+ Vec_PtrClear( p->vMapped );
+ for ( i = p->nLevelMax; i >= 0; i-- )
+ for ( pObj = ppStore[i]; pObj; pObj = pObj->pCopy )
+ Vec_PtrPush( p->vMapped, pObj );
+ free( ppStore );
+ return aArea;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the required times of all nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void If_ManComputeRequired( If_Man_t * p, int fFirstTime )
+{
+ If_Obj_t * pObj, * pLeaf;
+ If_Cut_t * pCutBest;
+ float Required;
+ int i, k;
+ // compute area, clean required times, collect nodes used in the mapping
+ p->AreaGlo = If_ManScanMapping( p );
+ // get the global required times
+ p->RequiredGlo = If_ManDelayMax( p );
+ // update the required times according to the target
+ if ( p->pPars->DelayTarget != -1 )
+ {
+ if ( p->RequiredGlo > p->pPars->DelayTarget + p->fEpsilon )
+ {
+ if ( fFirstTime )
+ printf( "Cannot meet the target required times (%4.2f). Mapping continues anyway.\n", p->pPars->DelayTarget );
+ }
+ else if ( p->RequiredGlo < p->pPars->DelayTarget - p->fEpsilon )
+ {
+ if ( fFirstTime )
+ printf( "Relaxing the required times from (%4.2f) to the target (%4.2f).\n", p->RequiredGlo, p->pPars->DelayTarget );
+ p->RequiredGlo = p->pPars->DelayTarget;
+ }
+ }
+ // set the required times for the POs
+ if ( p->pPars->fLatchPaths )
+ {
+ If_ManForEachLatch( p, pObj, i )
+ If_ObjFanin0(pObj)->Required = p->RequiredGlo;
+ }
+ else
+ {
+ If_ManForEachPo( p, pObj, i )
+ If_ObjFanin0(pObj)->Required = p->RequiredGlo;
+ }
+ // go through the nodes in the reverse topological order
+ Vec_PtrForEachEntry( p->vMapped, pObj, k )
+ {
+ // get the best cut of the node
+ pCutBest = If_ObjCutBest(pObj);
+ // get the required times for the leaves of the cut
+ Required = pObj->Required - If_CutLutDelay( p, pCutBest );
+ // update the required time of the leaves
+ If_CutForEachLeaf( p, pCutBest, pLeaf, i )
+ pLeaf->Required = IF_MIN( pLeaf->Required, Required );
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/map/if/if_.c b/src/map/if/if_.c
new file mode 100644
index 00000000..d2960077
--- /dev/null
+++ b/src/map/if/if_.c
@@ -0,0 +1,47 @@
+/**CFile****************************************************************
+
+ FileName [if_.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [FPGA mapping based on priority cuts.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - November 21, 2006.]
+
+ Revision [$Id: if_.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "if.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/map/if/module.make b/src/map/if/module.make
new file mode 100644
index 00000000..be044da2
--- /dev/null
+++ b/src/map/if/module.make
@@ -0,0 +1,4 @@
+SRC += src/map/if/ifCore.c \
+ src/map/if/ifMan.c \
+ src/map/if/ifMap.c \
+ src/map/if/ifUtil.c