diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2006-11-22 08:01:00 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2006-11-22 08:01:00 -0800 |
commit | 6ad22b4d3b0446652919d95b15fefb374bddfac0 (patch) | |
tree | eb525005c9827e844464c4e787c5907c7edc1d5c /src/map/if | |
parent | da5e0785dfb98335bd49a13bf9e86e736fb931be (diff) | |
download | abc-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.h | 255 | ||||
-rw-r--r-- | src/map/if/ifCore.c | 47 | ||||
-rw-r--r-- | src/map/if/ifCut.c | 47 | ||||
-rw-r--r-- | src/map/if/ifMan.c | 250 | ||||
-rw-r--r-- | src/map/if/ifMap.c | 391 | ||||
-rw-r--r-- | src/map/if/ifUtil.c | 229 | ||||
-rw-r--r-- | src/map/if/if_.c | 47 | ||||
-rw-r--r-- | src/map/if/module.make | 4 |
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 |