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 | |
parent | da5e0785dfb98335bd49a13bf9e86e736fb931be (diff) | |
download | abc-6ad22b4d3b0446652919d95b15fefb374bddfac0.tar.gz abc-6ad22b4d3b0446652919d95b15fefb374bddfac0.tar.bz2 abc-6ad22b4d3b0446652919d95b15fefb374bddfac0.zip |
Version abc61122
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/fpga/fpga.h | 2 | ||||
-rw-r--r-- | src/map/fpga/fpgaCut.c | 3 | ||||
-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 | ||||
-rw-r--r-- | src/map/pga/module.make | 4 | ||||
-rw-r--r-- | src/map/pga/pga.h | 80 | ||||
-rw-r--r-- | src/map/pga/pgaCore.c | 152 | ||||
-rw-r--r-- | src/map/pga/pgaInt.h | 132 | ||||
-rw-r--r-- | src/map/pga/pgaMan.c | 180 | ||||
-rw-r--r-- | src/map/pga/pgaMatch.c | 378 | ||||
-rw-r--r-- | src/map/pga/pgaUtil.c | 320 |
17 files changed, 1273 insertions, 1248 deletions
diff --git a/src/map/fpga/fpga.h b/src/map/fpga/fpga.h index d89f6dc9..188420b1 100644 --- a/src/map/fpga/fpga.h +++ b/src/map/fpga/fpga.h @@ -32,7 +32,7 @@ extern "C" { //////////////////////////////////////////////////////////////////////// // the maximum size of LUTs used for mapping -#define FPGA_MAX_LUTSIZE 10 +#define FPGA_MAX_LUTSIZE 32 //////////////////////////////////////////////////////////////////////// /// STRUCTURE DEFINITIONS /// diff --git a/src/map/fpga/fpgaCut.c b/src/map/fpga/fpgaCut.c index 3bb5feb4..c2aba4a3 100644 --- a/src/map/fpga/fpgaCut.c +++ b/src/map/fpga/fpgaCut.c @@ -684,7 +684,8 @@ int Fpga_CutMergeTwo( Fpga_Cut_t * pCut1, Fpga_Cut_t * pCut2, Fpga_Node_t * ppNo { min = i; for ( k = i+1; k < nTotal; k++ ) - if ( ppNodes[k] < ppNodes[min] ) +// if ( ppNodes[k] < ppNodes[min] ) // reported bug fix (non-determinism!) + if ( ppNodes[k]->Num < ppNodes[min]->Num ) min = k; pNodeTemp = ppNodes[i]; ppNodes[i] = ppNodes[min]; 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 diff --git a/src/map/pga/module.make b/src/map/pga/module.make deleted file mode 100644 index 2a45327e..00000000 --- a/src/map/pga/module.make +++ /dev/null @@ -1,4 +0,0 @@ -SRC += src/map/pga/pgaCore.c \ - src/map/pga/pgaMan.c \ - src/map/pga/pgaMatch.c \ - src/map/pga/pgaUtil.c diff --git a/src/map/pga/pga.h b/src/map/pga/pga.h deleted file mode 100644 index 4b2a9df4..00000000 --- a/src/map/pga/pga.h +++ /dev/null @@ -1,80 +0,0 @@ -/**CFile**************************************************************** - - FileName [pga.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [FPGA mapper.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: pga.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __PGA_H__ -#define __PGA_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Pga_ManStruct_t_ Pga_Man_t; -typedef struct Pga_ParamsStruct_t_ Pga_Params_t; - -struct Pga_ParamsStruct_t_ -{ - // data for mapping - Abc_Ntk_t * pNtk; // the network to be mapped - Fpga_LutLib_t * pLutLib; // the LUT library - float * pSwitching; // switching activity for each node - // mapping parameters - int fDropCuts; // enables cut dropping - int fAreaFlow; // enables area flow minimization - int fArea; // enables area minimization - int fSwitching; // enables switching activity minimization - int fVerbose; // enables verbose output -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== pgaApi.c ==========================================================*/ -extern Vec_Ptr_t * Pga_DoMapping( Pga_Man_t * p ); -/*=== pgaMan.c ==========================================================*/ -extern Pga_Man_t * Pga_ManStart( Pga_Params_t * pParams ); -extern void Pga_ManStop( Pga_Man_t * p ); - -#ifdef __cplusplus -} -#endif - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/map/pga/pgaCore.c b/src/map/pga/pgaCore.c deleted file mode 100644 index 240c24fd..00000000 --- a/src/map/pga/pgaCore.c +++ /dev/null @@ -1,152 +0,0 @@ -/**CFile**************************************************************** - - FileName [pgaCore.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [FPGA mapper.] - - Synopsis [External APIs of the FPGA manager.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: pgaCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "pgaInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Pga_MappingInitCis( Pga_Man_t * p ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs technology mapping for the given object graph.] - - Description [The object graph is stored in the mapping manager. - First, all the AND-nodes, which fanout into the POs, are collected - in the DFS fashion. Next, three steps are performed: the k-feasible - cuts are computed for each node, the truth tables are computed for - each cut, and the delay-optimal matches are assigned for each node.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Pga_DoMapping( Pga_Man_t * p ) -{ - int fShowSwitching = 0; - float aAreaTotalCur; - int Iter, clk, clkTotal = clock(); - - // assign the arrival times of the PIs - Pga_MappingInitCis( p ); - - // map the AIG for delay -clk = clock(); - Pga_MappingMatches( p, 0 ); -p->timeDelay = clock() - clk; - - // compute area, set references, and collect nodes used in the mapping - Iter = 1; - aAreaTotalCur = Pga_MappingSetRefsAndArea( p ); -if ( p->pParams->fVerbose ) -{ -printf( "Iteration %dD : Area = %8.1f ", Iter++, aAreaTotalCur ); -if ( fShowSwitching ) -printf( "Switch = %8.1f ", Pga_MappingGetSwitching(p) ); -PRT( "Time", p->timeDelay ); -} - - if ( p->pParams->fAreaFlow ) - { -clk = clock(); - // compute the required times and the fanouts - Pga_MappingComputeRequired( p ); - // remap topologically - Pga_MappingMatches( p, 1 ); -p->timeAreaFlow = clock() - clk; - // get the resulting area - aAreaTotalCur = Pga_MappingSetRefsAndArea( p ); - // note that here we do not update the reference counter - // for some reason, this works better on benchmarks -if ( p->pParams->fVerbose ) -{ -printf( "Iteration %dF : Area = %8.1f ", Iter++, aAreaTotalCur ); -if ( fShowSwitching ) -printf( "Switch = %8.1f ", Pga_MappingGetSwitching(p) ); -PRT( "Time", p->timeAreaFlow ); -} - } - - if ( p->pParams->fArea ) - { -clk = clock(); - // compute the required times and the fanouts - Pga_MappingComputeRequired( p ); - // remap topologically - if ( p->pParams->fSwitching ) - Pga_MappingMatches( p, 3 ); - else - Pga_MappingMatches( p, 2 ); -p->timeArea = clock() - clk; - // get the resulting area - aAreaTotalCur = Pga_MappingSetRefsAndArea( p ); -if ( p->pParams->fVerbose ) -{ -printf( "Iteration %d%s : Area = %8.1f ", Iter++, (p->pParams->fSwitching?"S":"A"), aAreaTotalCur ); -if ( fShowSwitching ) -printf( "Switch = %8.1f ", Pga_MappingGetSwitching(p) ); -PRT( "Time", p->timeArea ); -} - } - p->AreaGlobal = aAreaTotalCur; - - if ( p->pParams->fVerbose ) - Pga_MappingPrintOutputArrivals( p ); - - // return the mapping - return Pga_MappingResults( p ); -} - -/**Function************************************************************* - - Synopsis [Initializes the CI node arrival times.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Pga_MappingInitCis( Pga_Man_t * p ) -{ - Pga_Node_t * pNode; - float * pCiArrs; - int i; - // get the CI arrival times - pCiArrs = Abc_NtkGetCiArrivalFloats( p->pParams->pNtk ); - // assign the arrival times of the PIs - Pga_ManForEachCi( p, pNode, i ) - pNode->Match.Delay = pCiArrs[i]; - free( pCiArrs ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/map/pga/pgaInt.h b/src/map/pga/pgaInt.h deleted file mode 100644 index da9aa9a9..00000000 --- a/src/map/pga/pgaInt.h +++ /dev/null @@ -1,132 +0,0 @@ -/**CFile**************************************************************** - - FileName [pgaInt.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [FPGA mapper.] - - Synopsis [Internal declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: pgaInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __PGA_INT_H__ -#define __PGA_INT_H__ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include <stdio.h> -#include "abc.h" -#include "fraig.h" -#include "fpga.h" -#include "cut.h" -#include "pga.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Pga_NodeStruct_t_ Pga_Node_t; -typedef struct Pga_MatchStruct_t_ Pga_Match_t; - -struct Pga_ManStruct_t_ -{ - // mapping parameters - Pga_Params_t * pParams; // input data - // mapping structures - Pga_Node_t * pMemory; // the memory for all mapping structures - Vec_Ptr_t * vStructs; // mapping structures one-to-one with ABC nodes - Vec_Ptr_t * vOrdering; // mapping nodes ordered by level - // k-feasible cuts - int nVarsMax; // the "k" of k-feasible cuts - Cut_Man_t * pManCut; // the cut manager - // LUT library - float * pLutDelays; // the delay of the LUTs - float * pLutAreas; // the areas of the LUTs - float Epsilon; - // global parameters - float AreaGlobal; // the total area of this mapping - float ArrivalGlobal; // the largest delay of any path - float RequiredGlobal;// the global required time (may be different from largest delay) - float RequiredUser; // the required time given by the user - // runtime stats - int timeToMap; // the time to start the mapper - int timeCuts; // the time to compute the cuts - int timeDelay; // the time to compute delay - int timeAreaFlow; // the time to perform area flow optimization - int timeArea; // the time to perform area flow optimization - int timeToNet; // the time to transform back to network - int timeTotal; // the total time - int time1; // temporary - int time2; // temporary -}; - -struct Pga_MatchStruct_t_ -{ - Cut_Cut_t * pCut; // the best cut - float Delay; // the arrival time of this cut - float Area; // the area of this cut -}; - -struct Pga_NodeStruct_t_ -{ - int Id; // ID of the node - int nRefs; // the number of references - float EstRefs; // the estimated reference counter - float Required; // the required time - float Switching; // the switching activity - Pga_Match_t Match; // the best match at the node -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -static inline Pga_Node_t * Pga_Node( Pga_Man_t * p, int Id ) { return p->vStructs->pArray[Id]; } - -// iterator through the CIs -#define Pga_ManForEachCi( p, pCi, i ) \ - for ( i = 0; (i < Abc_NtkCiNum(p->pParams->pNtk)) && (((pCi) = Pga_Node(p, Abc_NtkCi(p->pParams->pNtk,i)->Id)), 1); i++ ) -// iterator through the CO derivers -#define Pga_ManForEachCoDriver( p, pCo, i ) \ - for ( i = 0; (i < Abc_NtkCoNum(p->pParams->pNtk)) && (((pCo) = Pga_Node(p, Abc_ObjFaninId0(Abc_NtkCo(p->pParams->pNtk,i)))), 1); i++ ) -// iterators through the CIs and internal nodes -#define Pga_ManForEachObjDirect( p, pNode, i ) \ - Vec_PtrForEachEntry( p->vOrdering, pNode, i ) -#define Pga_ManForEachObjReverse( p, pNode, i ) \ - Vec_PtrForEachEntryReverse( p->vOrdering, pNode, i ) - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== pgaMatch.c ==========================================================*/ -extern void Pga_MappingMatches( Pga_Man_t * p, int Mode ); -/*=== pgaUtil.c ==========================================================*/ -extern Vec_Ptr_t * Pga_MappingResults( Pga_Man_t * p ); -extern float Pga_TimeComputeArrivalMax( Pga_Man_t * p ); -extern void Pga_MappingComputeRequired( Pga_Man_t * p ); -extern float Pga_MappingSetRefsAndArea( Pga_Man_t * p ); -extern float Pga_MappingGetSwitching( Pga_Man_t * p ); -extern void Pga_MappingPrintOutputArrivals( Pga_Man_t * p ); - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/map/pga/pgaMan.c b/src/map/pga/pgaMan.c deleted file mode 100644 index 4ecc2ca7..00000000 --- a/src/map/pga/pgaMan.c +++ /dev/null @@ -1,180 +0,0 @@ -/**CFile**************************************************************** - - FileName [pgaMan.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [FPGA mapper.] - - Synopsis [Mapping manager.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: pgaMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "pgaInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static Cut_Man_t * Pga_ManStartCutMan( Pga_Params_t * pParamsPga ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Starts the manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Pga_Man_t * Pga_ManStart( Pga_Params_t * pParams ) -{ - Pga_Man_t * p; - Pga_Node_t * pNode; - Cut_Man_t * pManCut; - Abc_Ntk_t * pNtk; - Abc_Obj_t * pObj; - int i, Counter; - int clk = clock(); - - // make sure the network is given - pNtk = pParams->pNtk; - if ( pNtk == NULL ) - { - printf( "Network is not specified.\n" ); - return NULL; - } - if ( !Abc_NtkIsStrash(pNtk) ) - { - printf( "Mapping can only be applied to an AIG.\n" ); - return NULL; - } - // the cut manager if given should be in sinc - pManCut = pNtk->pManCut; - if ( pManCut && Cut_ManReadVarsMax(pManCut) != Fpga_LutLibReadVarMax(pParams->pLutLib) ) - { - printf( "The precomputed cuts have different size.\n" ); - return NULL; - } - // make sure the nodes are in the topological order - if ( !Abc_NtkIsDfsOrdered(pNtk) ) - { - printf( "The nodes of the network are not DFS ordered.\n" ); -// Abc_NtkReassignIds( pNtk ); - return NULL; - } - // make sure there are no dangling nodes (unless they are choices) - - // start the mapping manager - p = ALLOC( Pga_Man_t, 1 ); - memset( p, 0, sizeof(Pga_Man_t) ); - p->pParams = pParams; - p->nVarsMax = Fpga_LutLibReadVarMax(pParams->pLutLib); - p->pManCut = pManCut? pManCut : Pga_ManStartCutMan(pParams); - p->vOrdering = Abc_AigGetLevelizedOrder(pNtk, 0); // what happens with dangling nodes??? - p->pLutAreas = Fpga_LutLibReadLutAreas(pParams->pLutLib); - p->pLutDelays = Fpga_LutLibReadLutDelays(pParams->pLutLib); - p->Epsilon = (float)0.00001; - - // allocate mapping structures - p->pMemory = ALLOC( Pga_Node_t, Abc_NtkObjNum(pNtk) ); - memset( p->pMemory, 0, sizeof(Pga_Node_t) * Abc_NtkObjNum(pNtk) ); - p->vStructs = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) ); - Counter = 0; - Abc_NtkForEachObj( pNtk, pObj, i ) - { - pNode = p->pMemory + Counter++; - pNode->Id = pObj->Id; - pNode->nRefs = pObj->vFanouts.nSize; - pNode->Required = ABC_INFINITY; - pNode->Match.Area = ABC_INFINITY; - // skip secondary nodes - if ( Abc_ObjFanoutNum(pObj) == 0 ) - continue; - Vec_PtrWriteEntry( p->vStructs, pObj->Id, pNode ); - } - assert( Counter == Abc_NtkObjNum(pNtk) ); - // update order to depend on mapping nodes - Vec_PtrForEachEntry( p->vOrdering, pObj, i ) - Vec_PtrWriteEntry( p->vOrdering, i, Pga_Node(p,pObj->Id) ); -p->timeToMap = clock() - clk; - return p; -} - -/**Function************************************************************* - - Synopsis [Stops the manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Pga_ManStop( Pga_Man_t * p ) -{ - Cut_ManStop( p->pManCut ); - Vec_PtrFree( p->vOrdering ); - Vec_PtrFree( p->vStructs ); - free( p->pMemory ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Starts the cut manager for FPGA mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Man_t * Pga_ManStartCutMan( Pga_Params_t * pParamsPga ) -{ - static Cut_Params_t Params, * pParams = &Params; - Abc_Ntk_t * pNtk = pParamsPga->pNtk; - Cut_Man_t * pManCut; - Abc_Obj_t * pObj; - int i; - // start the cut manager - memset( pParams, 0, sizeof(Cut_Params_t) ); - pParams->nVarsMax = Fpga_LutLibReadVarMax(pParamsPga->pLutLib); // max cut size - pParams->nKeepMax = 250; // the max number of cuts kept at a node - pParams->fTruth = 0; // compute truth tables - pParams->fFilter = 1; // filter dominated cuts - pParams->fSeq = 0; // compute sequential cuts - pParams->fDrop = pParamsPga->fDropCuts; // drop cuts on the fly - pParams->fVerbose = 0; // the verbosiness flag - pParams->nIdsMax = Abc_NtkObjNumMax( pNtk ); - pManCut = Cut_ManStart( pParams ); - if ( pParams->fDrop ) - Cut_ManSetFanoutCounts( pManCut, Abc_NtkFanoutCounts(pNtk) ); - // set cuts for PIs - Abc_NtkForEachCi( pNtk, pObj, i ) - if ( Abc_ObjFanoutNum(pObj) > 0 ) - Cut_NodeSetTriv( pManCut, pObj->Id ); - return pManCut; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/map/pga/pgaMatch.c b/src/map/pga/pgaMatch.c deleted file mode 100644 index 186fbf64..00000000 --- a/src/map/pga/pgaMatch.c +++ /dev/null @@ -1,378 +0,0 @@ -/**CFile**************************************************************** - - FileName [pgaMatch.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [FPGA mapper.] - - Synopsis [Mapping procedures.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: pgaMatch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "pgaInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static char * s_Modes[4] = { "Delay", "Flow", "Area", "Switch" }; - -static int Pga_MappingMatchNode( Pga_Man_t * p, int NodeId, Cut_Cut_t * pList, int Mode ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs mapping for delay, area-flow, area, switching.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Pga_MappingMatches( Pga_Man_t * p, int Mode ) -{ - ProgressBar * pProgress; - Abc_Ntk_t * pNtk; - Abc_Obj_t * pObj; - Cut_Cut_t * pList; - int i, clk; - - assert( Mode >= 0 && Mode <= 2 ); - - // match LUTs with nodes in the topological order - pNtk = p->pParams->pNtk; - pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) ); - Abc_NtkForEachObj( pNtk, pObj, i ) - { - // skip the CIs - if ( Abc_ObjIsCi(pObj) ) - continue; - // when we reached a CO, it is time to deallocate the cuts - if ( Abc_ObjIsCo(pObj) ) - { - if ( p->pParams->fDropCuts ) - Cut_NodeTryDroppingCuts( p->pManCut, Abc_ObjFaninId0(pObj) ); - continue; - } - // skip constant node, it has no cuts -// if ( Abc_NodeIsConst(pObj) ) -// continue; - // get the cuts -clk = clock(); - pList = Abc_NodeGetCutsRecursive( p->pManCut, pObj, 0, 0 ); -p->timeCuts += clock() - clk; - // match the node - Pga_MappingMatchNode( p, pObj->Id, pList, Mode ); - Extra_ProgressBarUpdate( pProgress, i, s_Modes[Mode] ); - } - Extra_ProgressBarStop( pProgress ); -} - - - - -/**Function************************************************************* - - Synopsis [Computes the match of the cut.] - - Description [Returns 1 if feasible.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline float Pga_CutGetArrival( Pga_Man_t * p, Cut_Cut_t * pCut ) -{ - float DelayCur, DelayWorst; - unsigned i; - assert( pCut->nLeaves > 1 ); - DelayWorst = -ABC_INFINITY; - for ( i = 0; i < pCut->nLeaves; i++ ) - { - DelayCur = Pga_Node(p, pCut->pLeaves[i])->Match.Delay; - if ( DelayWorst < DelayCur ) - DelayWorst = DelayCur; - } - DelayWorst += p->pLutDelays[pCut->nLeaves]; - return DelayWorst; -} - -/**Function************************************************************* - - Synopsis [Computes the match of the cut.] - - Description [Returns 1 if feasible.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline float Pga_CutGetAreaFlow( Pga_Man_t * p, Cut_Cut_t * pCut ) -{ - float Flow; - Pga_Node_t * pNode; - unsigned i; - assert( pCut->nLeaves > 1 ); - Flow = p->pLutAreas[pCut->nLeaves]; - for ( i = 0; i < pCut->nLeaves; i++ ) - { - pNode = Pga_Node(p, pCut->pLeaves[i]); - assert( pNode->EstRefs > 0 ); - Flow += pNode->Match.Area / pNode->EstRefs; - } - return Flow; -} - -/**function************************************************************* - - synopsis [References the cut.] - - description [This procedure is similar to the procedure NodeReclaim.] - - sideeffects [] - - seealso [] - -***********************************************************************/ -float Pga_CutRef( Pga_Man_t * p, Pga_Node_t * pNode, Cut_Cut_t * pCut ) -{ - Pga_Node_t * pFanin; - float aArea; - unsigned i; - // start the area of this cut - aArea = p->pLutAreas[pCut->nLeaves]; - // go through the children - for ( i = 0; i < pCut->nLeaves; i++ ) - { - pFanin = Pga_Node(p, pCut->pLeaves[i]); - assert( pFanin->nRefs >= 0 ); - if ( pFanin->nRefs++ > 0 ) - continue; - if ( pFanin->Match.pCut == NULL ) - continue; - aArea += Pga_CutRef( p, pFanin, pFanin->Match.pCut ); - } - return aArea; -} - -/**function************************************************************* - - synopsis [Dereferences the cut.] - - description [This procedure is similar to the procedure NodeRecusiveDeref.] - - sideeffects [] - - seealso [] - -***********************************************************************/ -float Pga_CutDeref( Pga_Man_t * p, Pga_Node_t * pNode, Cut_Cut_t * pCut ) -{ - Pga_Node_t * pFanin; - float aArea; - unsigned i; - // start the area of this cut - aArea = p->pLutAreas[pCut->nLeaves]; - // go through the children - for ( i = 0; i < pCut->nLeaves; i++ ) - { - pFanin = Pga_Node(p, pCut->pLeaves[i]); - assert( pFanin->nRefs > 0 ); - if ( --pFanin->nRefs > 0 ) - continue; - if ( pFanin->Match.pCut == NULL ) - continue; - aArea += Pga_CutDeref( p, pFanin, pFanin->Match.pCut ); - } - return aArea; -} - -/**function************************************************************* - - synopsis [Computes the exact area associated with the cut.] - - description [Assumes that the cut is deferenced.] - - sideeffects [] - - seealso [] - -***********************************************************************/ -static inline float Pga_CutGetAreaDerefed( Pga_Man_t * p, Pga_Node_t * pNode, Cut_Cut_t * pCut ) -{ - float aResult, aResult2; - assert( pCut->nLeaves > 1 ); - aResult2 = Pga_CutRef( p, pNode, pCut ); - aResult = Pga_CutDeref( p, pNode, pCut ); - assert( aResult == aResult2 ); - return aResult; -} - - - -/**Function************************************************************* - - Synopsis [Computes the match of the cut.] - - Description [Returns 1 if feasible.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Pga_MappingMatchCut( Pga_Man_t * p, Pga_Node_t * pNode, Cut_Cut_t * pCut, int Mode, Pga_Match_t * pMatch ) -{ - // compute the arrival time of the cut and its area flow - pMatch->Delay = Pga_CutGetArrival( p, pCut ); - // drop the cut if it does not meet the required times - if ( pMatch->Delay > pNode->Required + p->Epsilon ) - return 0; - // get the second parameter - if ( Mode == 0 || Mode == 1 ) - pMatch->Area = Pga_CutGetAreaFlow( p, pCut ); - else if ( Mode == 2 ) - pMatch->Area = Pga_CutGetAreaDerefed( p, pNode, pCut ); -// else if ( Mode == 3 ) -// pMatch->Area = Pga_CutGetSwitching( p, pNode, pCut ); - // if no cut is assigned, use the current one - pMatch->pCut = pCut; - return 1; -} - -/**Function************************************************************* - - Synopsis [Compares two matches.] - - Description [Returns 1 if the second match is better.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Pga_MappingCompareMatches( Pga_Man_t * p, Pga_Match_t * pMatchBest, Pga_Match_t * pMatchCur, int Mode ) -{ - if ( pMatchBest->pCut == NULL ) - return 1; - if ( Mode == 0 ) - { - // compare delays - if ( pMatchBest->Delay < pMatchCur->Delay - p->Epsilon ) - return 0; - if ( pMatchBest->Delay > pMatchCur->Delay + p->Epsilon ) - return 1; - // compare areas - if ( pMatchBest->Area < pMatchCur->Area - p->Epsilon ) - return 0; - if ( pMatchBest->Area > pMatchCur->Area + p->Epsilon ) - return 1; - // if equal, do not update - return 0; - } - else - { - // compare areas - if ( pMatchBest->Area < pMatchCur->Area - p->Epsilon ) - return 0; - if ( pMatchBest->Area > pMatchCur->Area + p->Epsilon ) - return 1; - // compare delays - if ( pMatchBest->Delay < pMatchCur->Delay - p->Epsilon ) - return 0; - if ( pMatchBest->Delay > pMatchCur->Delay + p->Epsilon ) - return 1; - // if equal, do not update - return 0; - } -} - - -/**Function************************************************************* - - Synopsis [Computes the best matching for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Pga_MappingMatchNode( Pga_Man_t * p, int NodeId, Cut_Cut_t * pList, int Mode ) -{ - Pga_Match_t MatchCur, * pMatchCur = &MatchCur; - Pga_Match_t MatchBest, * pMatchBest = &MatchBest; - Pga_Node_t * pNode; - Cut_Cut_t * pCut; - - // get the mapping node - pNode = Pga_Node( p, NodeId ); - - // prepare for mapping - if ( Mode == 0 ) - pNode->EstRefs = (float)pNode->nRefs; - else if ( Mode == 1 ) - pNode->EstRefs = (float)((2.0 * pNode->EstRefs + pNode->nRefs) / 3.0); - else if ( Mode == 2 && pNode->nRefs > 0 ) - Pga_CutDeref( p, pNode, pNode->Match.pCut ); -// else if ( Mode == 3 && pNode->nRefs > 0 ) -// Pga_CutDerefSwitch( p, pNode, pNode->Match.pCut ); - - // start the best match - pMatchBest->pCut = NULL; - - // go through the other cuts - assert( pList->pNext ); - for ( pCut = pList->pNext; pCut; pCut = pCut->pNext ) - { - // compute match for this cut - if ( !Pga_MappingMatchCut( p, pNode, pCut, Mode, pMatchCur ) ) - continue; - // compare matches - if ( !Pga_MappingCompareMatches( p, pMatchBest, pMatchCur, Mode ) ) - continue; - // the best match should be updated - *pMatchBest = *pMatchCur; - } - - // make sure the match is found - if ( pMatchBest->pCut != NULL ) - pNode->Match = *pMatchBest; - else - { - assert( 0 ); -// Pga_MappingMatchCut( p, pNode, pCut, Mode, pNode->Match ); - } - - // reference the best cut - if ( Mode == 2 && pNode->nRefs > 0 ) - Pga_CutRef( p, pNode, pNode->Match.pCut ); -// else if ( Mode == 3 && pNode->nRefs > 0 ) -// Pga_CutRefSwitch( p, pNode, pNode->Match.pCut ); - return 1; -} - - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/map/pga/pgaUtil.c b/src/map/pga/pgaUtil.c deleted file mode 100644 index c79e3515..00000000 --- a/src/map/pga/pgaUtil.c +++ /dev/null @@ -1,320 +0,0 @@ -/**CFile**************************************************************** - - FileName [pgaUtil.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [FPGA mapper.] - - Synopsis [Verious utilities.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: pgaUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "pgaInt.h" - -#define PGA_CO_LIST_SIZE 5 - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Returns the results of mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Pga_MappingResults( Pga_Man_t * p ) -{ - Vec_Ptr_t * vResult; - Pga_Node_t * pNode; - int i; - vResult = Vec_PtrAlloc( 1000 ); - Pga_ManForEachObjDirect( p, pNode, i ) - { - // skip the CIs and nodes not used in the mapping - if ( !pNode->Match.pCut || !pNode->nRefs ) - continue; - pNode->Match.pCut->uSign = pNode->Id; - Vec_PtrPush( vResult, pNode->Match.pCut ); - } - return vResult; -} - -/**Function************************************************************* - - Synopsis [Computes the maximum arrival times.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -float Pga_TimeComputeArrivalMax( Pga_Man_t * p ) -{ - Pga_Node_t * pNode; - float ArrivalMax; - int i; - ArrivalMax = -ABC_INFINITY; - Pga_ManForEachCoDriver( p, pNode, i ) - ArrivalMax = ABC_MAX( ArrivalMax, pNode->Match.Delay ); - return ArrivalMax; -} - - -/**Function************************************************************* - - Synopsis [Computes required times of all nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Pga_MappingComputeRequired( Pga_Man_t * p ) -{ - Pga_Node_t * pNode, * pFanin; - Cut_Cut_t * pCutBest; - float RequiredNew; - int i, k; - // clean the required times of all nodes - Pga_ManForEachObjDirect( p, pNode, i ) - pNode->Required = ABC_INFINITY; - // get the global required times - p->AreaGlobal = Pga_TimeComputeArrivalMax( p ); - p->RequiredGlobal = ABC_MAX( p->AreaGlobal, p->RequiredUser ); - // set the global required times of the CO drivers - Pga_ManForEachCoDriver( p, pNode, i ) - pNode->Required = p->RequiredGlobal; - // propagate the required times in the reverse topological order - Pga_ManForEachObjReverse( p, pNode, i ) - { - // skip the CIs and nodes not used in the mapping - if ( !pNode->Match.pCut || !pNode->nRefs ) - continue; - // get the required time for children - pCutBest = pNode->Match.pCut; - RequiredNew = pNode->Required - p->pLutDelays[pCutBest->nLeaves]; - // update the required time of the children - for ( k = 0; k < (int)pCutBest->nLeaves; k++ ) - { - pFanin = Pga_Node( p, pCutBest->pLeaves[k] ); - pFanin->Required = ABC_MIN( pFanin->Required, RequiredNew ); - } - } - // check that the required times does not contradict the arrival times - Pga_ManForEachObjDirect( p, pNode, i ) - assert( !pNode->Match.pCut || pNode->Match.Delay < pNode->Required + p->Epsilon ); - -} - -/**Function************************************************************* - - Synopsis [Sets references and computes area for the current mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -float Pga_MappingSetRefsAndArea( Pga_Man_t * p ) -{ - Pga_Node_t * pNode, * pFanin; - Cut_Cut_t * pCutBest; - float AreaTotal; - int i, k; - // clean all the references - Pga_ManForEachObjDirect( p, pNode, i ) - pNode->nRefs = 0; - // set the references of the CO drivers - Pga_ManForEachCoDriver( p, pNode, i ) - pNode->nRefs++; - // go through the nodes in the reverse order - AreaTotal = 0.0; - Pga_ManForEachObjReverse( p, pNode, i ) - { - // skip the CIs and nodes not used in the mapping - if ( !pNode->Match.pCut || !pNode->nRefs ) - continue; - // increate the reference count of the children - pCutBest = pNode->Match.pCut; - AreaTotal += p->pLutAreas[pCutBest->nLeaves]; - // update the required time of the children - for ( k = 0; k < (int)pCutBest->nLeaves; k++ ) - { - pFanin = Pga_Node( p, pCutBest->pLeaves[k] ); - pFanin->nRefs++; - } - } - return AreaTotal; -} - -/**Function************************************************************* - - Synopsis [Computes switching activity of the mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -float Pga_MappingGetSwitching( Pga_Man_t * p ) -{ - float Switching; - Pga_Node_t * pNode; - int i; - Switching = 0; - Pga_ManForEachObjDirect( p, pNode, i ) - { - // skip the CIs and nodes not used in the mapping - if ( !pNode->Match.pCut || !pNode->nRefs ) - continue; - Switching += pNode->Switching; - } - return Switching; -} - -/**Function************************************************************* - - Synopsis [Compares the outputs by their arrival times.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Pga_MappingCompareOutputDelay( Pga_Node_t ** ppNode1, Pga_Node_t ** ppNode2 ) -{ - Pga_Node_t * pNode1 = *ppNode1; - Pga_Node_t * pNode2 = *ppNode2; - float Arrival1 = pNode1->Match.Delay; - float Arrival2 = pNode2->Match.Delay; - if ( Arrival1 < Arrival2 ) - return -1; - if ( Arrival1 > Arrival2 ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Finds given number of latest arriving COs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Pga_MappingFindLatest( Pga_Man_t * p, int * pNodes, int nNodesMax ) -{ - Pga_Node_t * pNodeI, * pNodeK; - Abc_Obj_t * pObjCo; - int nNodes, i, k, v; - assert( Abc_NtkCoNum(p->pParams->pNtk) >= nNodesMax ); - pNodes[0] = 0; - nNodes = 1; -// for ( i = 1; i < p->nOutputs; i++ ) - Pga_ManForEachCoDriver( p, pNodeI, i ) - { - for ( k = nNodes - 1; k >= 0; k-- ) - { - pObjCo = Abc_NtkCo( p->pParams->pNtk, pNodes[k] ); - pNodeK = Pga_Node( p, Abc_ObjFaninId0(pObjCo) ); - if ( Pga_MappingCompareOutputDelay( &pNodeK, &pNodeI ) >= 0 ) - break; - } - if ( k == nNodesMax - 1 ) - continue; - if ( nNodes < nNodesMax ) - nNodes++; - for ( v = nNodes - 1; v > k+1; v-- ) - pNodes[v] = pNodes[v-1]; - pNodes[k+1] = i; - } -} - -/**Function************************************************************* - - Synopsis [Prints a bunch of latest arriving outputs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Pga_MappingPrintOutputArrivals( Pga_Man_t * p ) -{ - int pSorted[PGA_CO_LIST_SIZE]; - Abc_Ntk_t * pNtk = p->pParams->pNtk; - Abc_Obj_t * pObjCo; - Pga_Node_t * pNode; - int Limit, MaxNameSize, i; - - // determine the number of nodes to print - Limit = (Abc_NtkCoNum(pNtk) < PGA_CO_LIST_SIZE)? Abc_NtkCoNum(pNtk) : PGA_CO_LIST_SIZE; - - // determine the order - Pga_MappingFindLatest( p, pSorted, Limit ); - - // determine max size of the node's name - MaxNameSize = 0; - for ( i = 0; i < Limit; i++ ) - { - pObjCo = Abc_NtkCo( pNtk, pSorted[i] ); - if ( MaxNameSize < (int)strlen( Abc_ObjName(pObjCo) ) ) - MaxNameSize = strlen( Abc_ObjName(pObjCo) ); - } - - // print the latest outputs - for ( i = 0; i < Limit; i++ ) - { - // get the i-th latest output - pObjCo = Abc_NtkCo( pNtk, pSorted[i] ); - pNode = Pga_Node( p, pObjCo->Id ); - // print out the best arrival time - printf( "Output %-*s : ", MaxNameSize + 3, Abc_ObjName(pObjCo) ); - printf( "Delay = %8.2f ", (double)pNode->Match.Delay ); - if ( Abc_ObjFaninC0(pObjCo) ) - printf( "NEG" ); - else - printf( "POS" ); - printf( "\n" ); - } -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - |