diff options
Diffstat (limited to 'src/map/fpga')
-rw-r--r-- | src/map/fpga/fpga.c | 72 | ||||
-rw-r--r-- | src/map/fpga/fpga.h | 41 | ||||
-rw-r--r-- | src/map/fpga/fpgaCore.c | 49 | ||||
-rw-r--r-- | src/map/fpga/fpgaCreate.c | 13 | ||||
-rw-r--r-- | src/map/fpga/fpgaCut.c | 54 | ||||
-rw-r--r-- | src/map/fpga/fpgaCutUtils.c | 10 | ||||
-rw-r--r-- | src/map/fpga/fpgaFanout.c | 2 | ||||
-rw-r--r-- | src/map/fpga/fpgaGENERIC.c | 2 | ||||
-rw-r--r-- | src/map/fpga/fpgaInt.h | 42 | ||||
-rw-r--r-- | src/map/fpga/fpgaLib.c | 91 | ||||
-rw-r--r-- | src/map/fpga/fpgaMatch.c | 40 | ||||
-rw-r--r-- | src/map/fpga/fpgaSwitch.c | 6 | ||||
-rw-r--r-- | src/map/fpga/fpgaTime.c | 69 | ||||
-rw-r--r-- | src/map/fpga/fpgaTruth.c | 61 | ||||
-rw-r--r-- | src/map/fpga/fpgaUtils.c | 53 | ||||
-rw-r--r-- | src/map/fpga/fpgaVec.c | 2 |
16 files changed, 485 insertions, 122 deletions
diff --git a/src/map/fpga/fpga.c b/src/map/fpga/fpga.c index 3d2ca913..40423f4f 100644 --- a/src/map/fpga/fpga.c +++ b/src/map/fpga/fpga.c @@ -39,7 +39,7 @@ static int Fpga_CommandPrintLibrary( Abc_Frame_t * pAbc, int argc, char **argv ) */ //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -56,8 +56,11 @@ static int Fpga_CommandPrintLibrary( Abc_Frame_t * pAbc, int argc, char **argv ) void Fpga_Init( Abc_Frame_t * pAbc ) { // set the default library - //Fpga_LutLib_t s_LutLib = { "lutlib", 6, {0,1,2,4,8,16,32}, {0,1,2,3,4,5,6} }; - Fpga_LutLib_t s_LutLib = { "lutlib", 5, {0,1,1,1,1,1}, {0,1,1,1,1,1} }; + //Fpga_LutLib_t s_LutLib = { "lutlib", 6, 0, {0,1,2,4,8,16,32}, {{0},{1},{2},{3},{4},{5},{6}} }; +// Fpga_LutLib_t s_LutLib = { "lutlib", 5, 0, {0,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1}} }; + Fpga_LutLib_t s_LutLib = { "lutlib", 4, 0, {0,1,1,1,1}, {{0},{1},{1},{1},{1}} }; + //Fpga_LutLib_t s_LutLib = { "lutlib", 3, 0, {0,1,1,1}, {{0},{1},{1},{1}} }; + Abc_FrameSetLibLut( Fpga_LutLibDup(&s_LutLib) ); Cmd_CommandAdd( pAbc, "FPGA mapping", "read_lut", Fpga_CommandReadLibrary, 0 ); @@ -77,7 +80,7 @@ void Fpga_Init( Abc_Frame_t * pAbc ) ***********************************************************************/ void Fpga_End() { - Fpga_LutLibFree( Abc_FrameReadLibLut(Abc_FrameGetGlobalFrame()) ); + Fpga_LutLibFree( Abc_FrameReadLibLut() ); } @@ -102,14 +105,14 @@ int Fpga_CommandReadLibrary( Abc_Frame_t * pAbc, int argc, char **argv ) int fVerbose; int c; - pNet = Abc_FrameReadNet(pAbc); + pNet = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); // set the defaults fVerbose = 1; - util_getopt_reset(); - while ( (c = util_getopt(argc, argv, "vh")) != EOF ) + Extra_UtilGetoptReset(); + while ( (c = Extra_UtilGetopt(argc, argv, "vh")) != EOF ) { switch (c) { @@ -125,13 +128,13 @@ int Fpga_CommandReadLibrary( Abc_Frame_t * pAbc, int argc, char **argv ) } - if ( argc != util_optind + 1 ) + if ( argc != globalUtilOptind + 1 ) { goto usage; } // get the input file name - FileName = argv[util_optind]; + FileName = argv[globalUtilOptind]; if ( (pFile = fopen( FileName, "r" )) == NULL ) { fprintf( pErr, "Cannot open input file \"%s\". ", FileName ); @@ -192,14 +195,14 @@ int Fpga_CommandPrintLibrary( Abc_Frame_t * pAbc, int argc, char **argv ) int fVerbose; int c; - pNet = Abc_FrameReadNet(pAbc); + pNet = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); // set the defaults fVerbose = 1; - util_getopt_reset(); - while ( (c = util_getopt(argc, argv, "vh")) != EOF ) + Extra_UtilGetoptReset(); + while ( (c = Extra_UtilGetopt(argc, argv, "vh")) != EOF ) { switch (c) { @@ -215,13 +218,13 @@ int Fpga_CommandPrintLibrary( Abc_Frame_t * pAbc, int argc, char **argv ) } - if ( argc != util_optind ) + if ( argc != globalUtilOptind ) { goto usage; } // set the new network - Fpga_LutLibPrint( Abc_FrameReadLibLut(Abc_FrameGetGlobalFrame()) ); + Fpga_LutLibPrint( Abc_FrameReadLibLut() ); return 0; usage: @@ -232,6 +235,47 @@ usage: return 1; /* error exit */ } +/**Function************************************************************* + + Synopsis [Sets simple LUT library.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fpga_SetSimpleLutLib( int nLutSize ) +{ + Fpga_LutLib_t s_LutLib10= { "lutlib",10, 0, {0,1,1,1,1,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1},{1},{1},{1},{1}} }; + Fpga_LutLib_t s_LutLib9 = { "lutlib", 9, 0, {0,1,1,1,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1},{1},{1},{1}} }; + Fpga_LutLib_t s_LutLib8 = { "lutlib", 8, 0, {0,1,1,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1},{1},{1}} }; + Fpga_LutLib_t s_LutLib7 = { "lutlib", 7, 0, {0,1,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1},{1}} }; + Fpga_LutLib_t s_LutLib6 = { "lutlib", 6, 0, {0,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1}} }; + Fpga_LutLib_t s_LutLib5 = { "lutlib", 5, 0, {0,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1}} }; + Fpga_LutLib_t s_LutLib4 = { "lutlib", 4, 0, {0,1,1,1,1}, {{0},{1},{1},{1},{1}} }; + Fpga_LutLib_t s_LutLib3 = { "lutlib", 3, 0, {0,1,1,1}, {{0},{1},{1},{1}} }; + Fpga_LutLib_t * pLutLib; + assert( nLutSize >= 3 && nLutSize <= 10 ); + switch ( nLutSize ) + { + case 3: pLutLib = &s_LutLib3; break; + case 4: pLutLib = &s_LutLib4; break; + case 5: pLutLib = &s_LutLib5; break; + case 6: pLutLib = &s_LutLib6; break; + case 7: pLutLib = &s_LutLib7; break; + case 8: pLutLib = &s_LutLib8; break; + case 9: pLutLib = &s_LutLib9; break; + case 10: pLutLib = &s_LutLib10; break; + default: pLutLib = NULL; break; + } + if ( pLutLib == NULL ) + return; + Fpga_LutLibFree( Abc_FrameReadLibLut() ); + Abc_FrameSetLibLut( Fpga_LutLibDup(pLutLib) ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/map/fpga/fpga.h b/src/map/fpga/fpga.h index 19241a74..708cf385 100644 --- a/src/map/fpga/fpga.h +++ b/src/map/fpga/fpga.h @@ -19,6 +19,10 @@ #ifndef __FPGA_H__ #define __FPGA_H__ +#ifdef __cplusplus +extern "C" { +#endif + //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -28,7 +32,7 @@ //////////////////////////////////////////////////////////////////////// // the maximum size of LUTs used for mapping -#define FPGA_MAX_LUTSIZE 10 +#define FPGA_MAX_LUTSIZE 32 //////////////////////////////////////////////////////////////////////// /// STRUCTURE DEFINITIONS /// @@ -45,20 +49,20 @@ typedef struct Fpga_LutLibStruct_t_ Fpga_LutLib_t; //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// MACRO DEFITIONS /// +/// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -#define Fpga_IsComplement(p) (((int)((long) (p) & 01))) -#define Fpga_Regular(p) ((Fpga_Node_t *)((unsigned)(p) & ~01)) -#define Fpga_Not(p) ((Fpga_Node_t *)((long)(p) ^ 01)) -#define Fpga_NotCond(p,c) ((Fpga_Node_t *)((long)(p) ^ (c))) +#define Fpga_IsComplement(p) (((int)((unsigned long) (p) & 01))) +#define Fpga_Regular(p) ((Fpga_Node_t *)((unsigned long)(p) & ~01)) +#define Fpga_Not(p) ((Fpga_Node_t *)((unsigned long)(p) ^ 01)) +#define Fpga_NotCond(p,c) ((Fpga_Node_t *)((unsigned long)(p) ^ (c))) #define Fpga_Ref(p) #define Fpga_Deref(p) #define Fpga_RecursiveDeref(p,c) //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /*=== fpgaCreate.c =============================================================*/ @@ -74,7 +78,9 @@ extern Fpga_Node_t ** Fpga_ManReadOutputs( Fpga_Man_t * p ); extern Fpga_Node_t * Fpga_ManReadConst1 ( Fpga_Man_t * p ); extern float * Fpga_ManReadInputArrivals( Fpga_Man_t * p ); extern int Fpga_ManReadVerbose( Fpga_Man_t * p ); +extern int Fpga_ManReadVarMax( Fpga_Man_t * p ); extern float * Fpga_ManReadLutAreas( Fpga_Man_t * p ); +extern Fpga_NodeVec_t* Fpga_ManReadMapping( Fpga_Man_t * p ); extern void Fpga_ManSetTimeToMap( Fpga_Man_t * p, int Time ); extern void Fpga_ManSetTimeToNet( Fpga_Man_t * p, int Time ); extern void Fpga_ManSetTimeTotal( Fpga_Man_t * p, int Time ); @@ -92,13 +98,16 @@ extern void Fpga_ManSetChoiceNodeNum( Fpga_Man_t * p, int nChoiceNode extern void Fpga_ManSetChoiceNum( Fpga_Man_t * p, int nChoices ); extern void Fpga_ManSetVerbose( Fpga_Man_t * p, int fVerbose ); extern void Fpga_ManSetSwitching( Fpga_Man_t * p, int fSwitching ); +extern void Fpga_ManSetLatchPaths( Fpga_Man_t * p, int fLatchPaths ); extern void Fpga_ManSetLatchNum( Fpga_Man_t * p, int nLatches ); +extern void Fpga_ManSetDelayTarget( Fpga_Man_t * p, float DelayTarget ); extern void Fpga_ManSetName( Fpga_Man_t * p, char * pFileName ); extern int Fpga_LibReadLutMax( Fpga_LutLib_t * pLib ); extern char * Fpga_NodeReadData0( Fpga_Node_t * p ); extern Fpga_Node_t * Fpga_NodeReadData1( Fpga_Node_t * p ); +extern int Fpga_NodeReadRefs( Fpga_Node_t * p ); extern int Fpga_NodeReadNum( Fpga_Node_t * p ); extern int Fpga_NodeReadLevel( Fpga_Node_t * p ); extern Fpga_Cut_t * Fpga_NodeReadCuts( Fpga_Node_t * p ); @@ -134,23 +143,33 @@ extern int Fpga_Mapping( Fpga_Man_t * p ); /*=== fpgaCut.c ===============================================================*/ extern void Fpga_MappingCreatePiCuts( Fpga_Man_t * p ); extern void Fpga_CutsCleanSign( Fpga_Man_t * pMan ); +extern void Fpga_CutsCleanRoot( Fpga_Man_t * pMan ); /*=== fpgaCutUtils.c =============================================================*/ extern void Fpga_CutCreateFromNode( Fpga_Man_t * p, int iRoot, int * pLeaves, int nLeaves ); extern void Fpga_MappingSetUsedCuts( Fpga_Man_t * p ); -/*=== fpgaFraig.c =============================================================*/ -extern Fpga_Man_t * Fpga_ManDupFraig( Fraig_Man_t * pManFraig ); -extern Fpga_Man_t * Fpga_ManBalanceFraig( Fraig_Man_t * pManFraig, int * pInputArrivals ); /*=== fpgaLib.c =============================================================*/ extern Fpga_LutLib_t * Fpga_LutLibDup( Fpga_LutLib_t * p ); +extern int Fpga_LutLibReadVarMax( Fpga_LutLib_t * p ); +extern float * Fpga_LutLibReadLutAreas( Fpga_LutLib_t * p ); +extern float * Fpga_LutLibReadLutDelays( Fpga_LutLib_t * p ); +extern float Fpga_LutLibReadLutArea( Fpga_LutLib_t * p, int Size ); +extern float Fpga_LutLibReadLutDelay( Fpga_LutLib_t * p, int Size ); /*=== fpgaTruth.c =============================================================*/ extern void * Fpga_TruthsCutBdd( void * dd, Fpga_Cut_t * pCut ); +extern int Fpga_CutVolume( Fpga_Cut_t * pCut ); /*=== fpgaUtil.c =============================================================*/ extern int Fpga_ManCheckConsistency( Fpga_Man_t * p ); extern void Fpga_ManCleanData0( Fpga_Man_t * pMan ); extern Fpga_NodeVec_t * Fpga_CollectNodeTfo( Fpga_Man_t * pMan, Fpga_Node_t * pNode ); +/*=== fpga.c =============================================================*/ +extern void Fpga_SetSimpleLutLib( int nLutSize ); + +#ifdef __cplusplus +} +#endif +#endif //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -#endif diff --git a/src/map/fpga/fpgaCore.c b/src/map/fpga/fpgaCore.c index 9ca65379..634a8eb1 100644 --- a/src/map/fpga/fpgaCore.c +++ b/src/map/fpga/fpgaCore.c @@ -24,8 +24,12 @@ static int Fpga_MappingPostProcess( Fpga_Man_t * p ); +extern int s_MappingTime; +extern int s_MappingMem; + + //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -46,7 +50,7 @@ static int Fpga_MappingPostProcess( Fpga_Man_t * p ); int Fpga_Mapping( Fpga_Man_t * p ) { int clk, clkTotal = clock(); - + // collect the nodes reachable from POs in the DFS order (including the choices) p->vAnds = Fpga_MappingDfs( p, 1 ); Fpga_ManReportChoices( p ); // recomputes levels @@ -64,19 +68,23 @@ int Fpga_Mapping( Fpga_Man_t * p ) p->timeMatch = clock() - clk; // perform area recovery - if ( p->fAreaRecovery ) - { - clk = clock(); - if ( !Fpga_MappingPostProcess( p ) ) - return 0; - p->timeRecover = clock() - clk; - } + clk = clock(); + if ( !Fpga_MappingPostProcess( p ) ) + return 0; + p->timeRecover = clock() - clk; //PRT( "Total mapping time", clock() - clkTotal ); + s_MappingTime = clock() - clkTotal; + s_MappingMem = Fpga_CutCountAll(p) * (sizeof(Fpga_Cut_t) - sizeof(int) * (FPGA_MAX_LEAVES - p->nVarsMax)); + // print the AI-graph used for mapping //Fpga_ManShow( p, "test" ); +// if ( p->fVerbose ) +// Fpga_MappingPrintOutputArrivals( p ); if ( p->fVerbose ) - Fpga_MappingPrintOutputArrivals( p ); + { + PRT( "Total time", clock() - clkTotal ); + } return 1; } @@ -88,7 +96,7 @@ int Fpga_Mapping( Fpga_Man_t * p ) It iterates the loop, in which the required times are computed and the mapping is updated. It is conceptually similar to the paper: V. Manohararajah, S. D. Brown, Z. G. Vranesic, Heuristics for area - minimization in LUT-based FGPA technology mapping. Proc. IWLS '04.] + minimization in LUT-based FPGA technology mapping. Proc. IWLS '04.] SideEffects [] @@ -97,12 +105,15 @@ int Fpga_Mapping( Fpga_Man_t * p ) ***********************************************************************/ int Fpga_MappingPostProcess( Fpga_Man_t * p ) { - int fShowSwitching = 1; + int fShowSwitching = 0; int fRecoverAreaFlow = 1; int fRecoverArea = 1; float aAreaTotalCur, aAreaTotalCur2; int Iter, clk; +//if ( p->fVerbose ) +// printf( "Best clock period = %5.2f\n", Fpga_TimeComputeArrivalMax(p) ); + // compute area, set references, and collect nodes used in the mapping Iter = 1; aAreaTotalCur = Fpga_MappingSetRefsAndArea( p ); @@ -111,14 +122,20 @@ if ( p->fVerbose ) printf( "Iteration %dD : Area = %8.1f ", Iter++, aAreaTotalCur ); if ( fShowSwitching ) printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) ); +else +printf( "Delay = %5.2f ", Fpga_TimeComputeArrivalMax(p) ); + PRT( "Time", p->timeMatch ); } + if ( !p->fAreaRecovery ) + return 1; + if ( fRecoverAreaFlow ) { clk = clock(); // compute the required times and the fanouts - Fpga_TimeComputeRequiredGlobal( p ); + Fpga_TimeComputeRequiredGlobal( p, 1 ); // remap topologically Fpga_MappingMatches( p, 0 ); // get the resulting area @@ -131,6 +148,8 @@ if ( p->fVerbose ) printf( "Iteration %dF : Area = %8.1f ", Iter++, aAreaTotalCur ); if ( fShowSwitching ) printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) ); +else +printf( "Delay = %5.2f ", Fpga_TimeComputeArrivalMax(p) ); PRT( "Time", clock() - clk ); } } @@ -143,7 +162,7 @@ PRT( "Time", clock() - clk ); { clk = clock(); // compute the required times and the fanouts - Fpga_TimeComputeRequiredGlobal( p ); + Fpga_TimeComputeRequiredGlobal( p, 0 ); // remap topologically if ( p->fSwitching ) Fpga_MappingMatchesSwitch( p ); @@ -156,6 +175,8 @@ if ( p->fVerbose ) printf( "Iteration %d%s : Area = %8.1f ", Iter++, (p->fSwitching?"S":"A"), aAreaTotalCur ); if ( fShowSwitching ) printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) ); +else +printf( "Delay = %5.2f ", Fpga_TimeComputeArrivalMax(p) ); PRT( "Time", clock() - clk ); } } diff --git a/src/map/fpga/fpgaCreate.c b/src/map/fpga/fpgaCreate.c index b7bfa3c5..be71d74e 100644 --- a/src/map/fpga/fpgaCreate.c +++ b/src/map/fpga/fpgaCreate.c @@ -31,7 +31,7 @@ static Fpga_Node_t * Fpga_TableLookup( Fpga_Man_t * p, Fpga_Node_t * p1, Fpga_ static inline unsigned Fpga_HashKey2( Fpga_Node_t * p0, Fpga_Node_t * p1, int TableSize ) { return ((unsigned)(p0) + (unsigned)(p1) * 12582917) % TableSize; } //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -52,7 +52,9 @@ Fpga_Node_t ** Fpga_ManReadOutputs( Fpga_Man_t * p ) { retu Fpga_Node_t * Fpga_ManReadConst1 ( Fpga_Man_t * p ) { return p->pConst1; } float * Fpga_ManReadInputArrivals( Fpga_Man_t * p ) { return p->pInputArrivals;} int Fpga_ManReadVerbose( Fpga_Man_t * p ) { return p->fVerbose; } +int Fpga_ManReadVarMax( Fpga_Man_t * p ) { return p->pLutLib->LutMax; } float * Fpga_ManReadLutAreas( Fpga_Man_t * p ) { return p->pLutLib->pLutAreas; } +Fpga_NodeVec_t* Fpga_ManReadMapping( Fpga_Man_t * p ) { return p->vMapping; } void Fpga_ManSetTimeToMap( Fpga_Man_t * p, int Time ) { p->timeToMap = Time; } void Fpga_ManSetTimeToNet( Fpga_Man_t * p, int Time ) { p->timeToNet = Time; } void Fpga_ManSetTimeTotal( Fpga_Man_t * p, int Time ) { p->timeTotal = Time; } @@ -66,7 +68,9 @@ void Fpga_ManSetChoiceNodeNum( Fpga_Man_t * p, int nChoiceNodes ) { p void Fpga_ManSetChoiceNum( Fpga_Man_t * p, int nChoices ) { p->nChoices = nChoices; } void Fpga_ManSetVerbose( Fpga_Man_t * p, int fVerbose ) { p->fVerbose = fVerbose; } void Fpga_ManSetSwitching( Fpga_Man_t * p, int fSwitching ) { p->fSwitching = fSwitching; } +void Fpga_ManSetLatchPaths( Fpga_Man_t * p, int fLatchPaths ) { p->fLatchPaths = fLatchPaths; } void Fpga_ManSetLatchNum( Fpga_Man_t * p, int nLatches ) { p->nLatches = nLatches; } +void Fpga_ManSetDelayTarget( Fpga_Man_t * p, float DelayTarget ) { p->DelayTarget = DelayTarget; } void Fpga_ManSetName( Fpga_Man_t * p, char * pFileName ) { p->pFileName = pFileName; } /**Function************************************************************* @@ -95,6 +99,7 @@ int Fpga_LibReadLutMax( Fpga_LutLib_t * pLib ) { return pLib->LutMa ***********************************************************************/ char * Fpga_NodeReadData0( Fpga_Node_t * p ) { return p->pData0; } Fpga_Node_t * Fpga_NodeReadData1( Fpga_Node_t * p ) { return p->pLevel; } +int Fpga_NodeReadRefs( Fpga_Node_t * p ) { return p->nRefs; } int Fpga_NodeReadNum( Fpga_Node_t * p ) { return p->Num; } int Fpga_NodeReadLevel( Fpga_Node_t * p ) { return Fpga_Regular(p)->Level; } Fpga_Cut_t * Fpga_NodeReadCuts( Fpga_Node_t * p ) { return p->pCuts; } @@ -164,7 +169,7 @@ Fpga_Man_t * Fpga_ManCreate( int nInputs, int nOutputs, int fVerbose ) // start the manager p = ALLOC( Fpga_Man_t, 1 ); memset( p, 0, sizeof(Fpga_Man_t) ); - p->pLutLib = Abc_FrameReadLibLut(Abc_FrameGetGlobalFrame()); + p->pLutLib = Abc_FrameReadLibLut(); p->nVarsMax = p->pLutLib->LutMax; p->fVerbose = fVerbose; p->fAreaRecovery = 1; @@ -223,8 +228,8 @@ void Fpga_ManFree( Fpga_Man_t * p ) Fpga_NodeVecFree( p->vAnds ); if ( p->vNodesAll ) Fpga_NodeVecFree( p->vNodesAll ); - Extra_MmFixedStop( p->mmNodes, 0 ); - Extra_MmFixedStop( p->mmCuts, 0 ); + Extra_MmFixedStop( p->mmNodes ); + Extra_MmFixedStop( p->mmCuts ); FREE( p->ppOutputNames ); FREE( p->pInputArrivals ); FREE( p->pInputs ); diff --git a/src/map/fpga/fpgaCut.c b/src/map/fpga/fpgaCut.c index 5b5fbe69..ce688179 100644 --- a/src/map/fpga/fpgaCut.c +++ b/src/map/fpga/fpgaCut.c @@ -35,9 +35,11 @@ struct Fpga_CutTableStrutct_t }; // the largest number of cuts considered -#define FPGA_CUTS_MAX_COMPUTE 500 +//#define FPGA_CUTS_MAX_COMPUTE 500 +#define FPGA_CUTS_MAX_COMPUTE 2000 // the largest number of cuts used -#define FPGA_CUTS_MAX_USE 200 +//#define FPGA_CUTS_MAX_USE 200 +#define FPGA_CUTS_MAX_USE 1000 // primes used to compute the hash key static int s_HashPrimes[10] = { 109, 499, 557, 619, 631, 709, 797, 881, 907, 991 }; @@ -95,7 +97,7 @@ static Fpga_Cut_t * Fpga_CutArray2List( Fpga_Cut_t ** pArray, int nCuts ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -128,9 +130,10 @@ void Fpga_MappingCuts( Fpga_Man_t * p ) Fpga_CutTable_t * pTable; Fpga_Node_t * pNode; int nCuts, nNodes, i; + int clk = clock(); // set the elementary cuts for the PI variables - assert( p->nVarsMax > 1 && p->nVarsMax < 7 ); + assert( p->nVarsMax > 1 && p->nVarsMax < 11 ); Fpga_MappingCreatePiCuts( p ); // compute the cuts for the internal nodes @@ -152,8 +155,9 @@ void Fpga_MappingCuts( Fpga_Man_t * p ) if ( p->fVerbose ) { nCuts = Fpga_CutCountAll(p); - printf( "Nodes = %6d. Total %d-feasible cuts = %d. Cuts per node = %.1f.\n", + printf( "Nodes = %6d. Total %d-cuts = %d. Cuts per node = %.1f. ", p->nNodes, p->nVarsMax, nCuts, ((float)nCuts)/p->nNodes ); + PRT( "Time", clock() - clk ); } // print the cuts for the first primary output @@ -245,7 +249,7 @@ Fpga_Cut_t * Fpga_CutCompute( Fpga_Man_t * p, Fpga_CutTable_t * pTable, Fpga_Nod // set at the node pNode->pCuts = pCut; // remove the dominated cuts - Fpga_CutFilter( p, pNode ); +// Fpga_CutFilter( p, pNode ); // set the phase correctly if ( pNode->pRepr && Fpga_NodeComparePhase(pNode, pNode->pRepr) ) { @@ -347,8 +351,8 @@ void Fpga_CutFilter( Fpga_Man_t * p, Fpga_Node_t * pNode ) Fpga_Cut_t * Fpga_CutMergeLists( Fpga_Man_t * p, Fpga_CutTable_t * pTable, Fpga_Cut_t * pList1, Fpga_Cut_t * pList2, int fComp1, int fComp2, int fPivot1, int fPivot2 ) { - Fpga_Node_t * ppNodes[6]; - Fpga_Cut_t * pListNew, ** ppListNew, * pLists[7] = { NULL }; + Fpga_Node_t * ppNodes[FPGA_MAX_LEAVES]; + Fpga_Cut_t * pListNew, ** ppListNew, * pLists[FPGA_MAX_LEAVES+1] = { NULL }; Fpga_Cut_t * pCut, * pPrev, * pTemp1, * pTemp2; int nNodes, Counter, i; Fpga_Cut_t ** ppArray1, ** ppArray2, ** ppArray3; @@ -532,8 +536,8 @@ QUITS : Fpga_Cut_t * Fpga_CutMergeLists2( Fpga_Man_t * p, Fpga_CutTable_t * pTable, Fpga_Cut_t * pList1, Fpga_Cut_t * pList2, int fComp1, int fComp2, int fPivot1, int fPivot2 ) { - Fpga_Node_t * ppNodes[6]; - Fpga_Cut_t * pListNew, ** ppListNew, * pLists[7] = { NULL }; + Fpga_Node_t * ppNodes[FPGA_MAX_LEAVES]; + Fpga_Cut_t * pListNew, ** ppListNew, * pLists[FPGA_MAX_LEAVES+1] = { NULL }; Fpga_Cut_t * pCut, * pPrev, * pTemp1, * pTemp2; int nNodes, Counter, i; @@ -682,7 +686,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]; @@ -767,7 +772,10 @@ int Fpga_CutCountAll( Fpga_Man_t * pMan ) for ( pNode = pMan->pBins[i]; pNode; pNode = pNode->pNext ) for ( pCut = pNode->pCuts; pCut; pCut = pCut->pNext ) if ( pCut->nLeaves > 1 ) // skip the elementary cuts + { +// Fpga_CutVolume( pCut ); nCuts++; + } return nCuts; } @@ -794,6 +802,28 @@ void Fpga_CutsCleanSign( Fpga_Man_t * pMan ) pCut->uSign = 0; } +/**Function************************************************************* + + Synopsis [Clean the signatures.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fpga_CutsCleanRoot( Fpga_Man_t * pMan ) +{ + Fpga_Node_t * pNode; + Fpga_Cut_t * pCut; + int i; + for ( i = 0; i < pMan->nBins; i++ ) + for ( pNode = pMan->pBins[i]; pNode; pNode = pNode->pNext ) + for ( pCut = pNode->pCuts; pCut; pCut = pCut->pNext ) + pCut->pRoot = NULL; +} + /**Function************************************************************* @@ -1079,7 +1109,7 @@ Fpga_Cut_t * Fpga_CutSortCuts( Fpga_Man_t * pMan, Fpga_CutTable_t * p, Fpga_Cut_ nCuts = Fpga_CutList2Array( p->pCuts1, pList ); assert( nCuts <= FPGA_CUTS_MAX_COMPUTE ); // sort the cuts - qsort( (void *)p->pCuts1, nCuts, sizeof(Fpga_Cut_t *), + qsort( (void *)p->pCuts1, nCuts, sizeof(void *), (int (*)(const void *, const void *)) Fpga_CutSortCutsCompare ); // move them back into the list if ( nCuts > FPGA_CUTS_MAX_USE - 1 ) diff --git a/src/map/fpga/fpgaCutUtils.c b/src/map/fpga/fpgaCutUtils.c index 2419cac4..e60a1dee 100644 --- a/src/map/fpga/fpgaCutUtils.c +++ b/src/map/fpga/fpgaCutUtils.c @@ -23,7 +23,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -290,7 +290,9 @@ void Fpga_CutGetParameters( Fpga_Man_t * pMan, Fpga_Cut_t * pCut ) // pCut->aFlow += pFaninCut->aFlow / pCut->ppLeaves[i]->nRefs; pCut->aFlow += pFaninCut->aFlow / pCut->ppLeaves[i]->aEstFanouts; } - pCut->tArrival += pMan->pLutLib->pLutDelays[pCut->nLeaves]; + // use the first pin to compute the delay of the LUT + // (this mapper does not support the variable pin delay model) + pCut->tArrival += pMan->pLutLib->pLutDelays[pCut->nLeaves][0]; } @@ -338,7 +340,7 @@ float Fpga_CutGetAreaRefed( Fpga_Man_t * pMan, Fpga_Cut_t * pCut ) return 0; aResult = Fpga_CutDeref( pMan, NULL, pCut, 0 ); aResult2 = Fpga_CutRef( pMan, NULL, pCut, 0 ); - assert( aResult == aResult2 ); + assert( Fpga_FloatEqual( pMan, aResult, aResult2 ) ); return aResult; } @@ -360,7 +362,7 @@ float Fpga_CutGetAreaDerefed( Fpga_Man_t * pMan, Fpga_Cut_t * pCut ) return 0; aResult2 = Fpga_CutRef( pMan, NULL, pCut, 0 ); aResult = Fpga_CutDeref( pMan, NULL, pCut, 0 ); - assert( aResult == aResult2 ); + assert( Fpga_FloatEqual( pMan, aResult, aResult2 ) ); return aResult; } diff --git a/src/map/fpga/fpgaFanout.c b/src/map/fpga/fpgaFanout.c index 0a34ff43..c28a8799 100644 --- a/src/map/fpga/fpgaFanout.c +++ b/src/map/fpga/fpgaFanout.c @@ -25,7 +25,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* diff --git a/src/map/fpga/fpgaGENERIC.c b/src/map/fpga/fpgaGENERIC.c index f272c1b8..4483c215 100644 --- a/src/map/fpga/fpgaGENERIC.c +++ b/src/map/fpga/fpgaGENERIC.c @@ -23,7 +23,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* diff --git a/src/map/fpga/fpgaInt.h b/src/map/fpga/fpgaInt.h index ec6057a7..c01d1e3d 100644 --- a/src/map/fpga/fpgaInt.h +++ b/src/map/fpga/fpgaInt.h @@ -28,7 +28,6 @@ #include <stdlib.h> #include <string.h> #include "extra.h" -#include "fraig.h" #include "fpga.h" //////////////////////////////////////////////////////////////////////// @@ -39,7 +38,7 @@ //#define FPGA_ALLOCATE_FANOUT 1 //////////////////////////////////////////////////////////////////////// -/// MACRO DEFITIONS /// +/// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// #ifdef _WIN32 @@ -68,16 +67,16 @@ #define FPGA_SEQ_SIGN(p) (1 << (((unsigned)p)%31)); // internal macros to work with cuts -#define Fpga_CutIsComplement(p) (((int)((long) (p) & 01))) -#define Fpga_CutRegular(p) ((Fpga_Cut_t *)((unsigned)(p) & ~01)) -#define Fpga_CutNot(p) ((Fpga_Cut_t *)((long)(p) ^ 01)) -#define Fpga_CutNotCond(p,c) ((Fpga_Cut_t *)((long)(p) ^ (c))) +#define Fpga_CutIsComplement(p) (((int)((unsigned long) (p) & 01))) +#define Fpga_CutRegular(p) ((Fpga_Cut_t *)((unsigned long)(p) & ~01)) +#define Fpga_CutNot(p) ((Fpga_Cut_t *)((unsigned long)(p) ^ 01)) +#define Fpga_CutNotCond(p,c) ((Fpga_Cut_t *)((unsigned long)(p) ^ (c))) // the cut nodes -#define Fpga_SeqIsComplement( p ) (((int)((long) (p) & 01))) -#define Fpga_SeqRegular( p ) ((Fpga_Node_t *)((unsigned)(p) & ~015)) -#define Fpga_SeqIndex( p ) ((((unsigned)(p)) >> 1) & 07) -#define Fpga_SeqIndexCreate( p, Ind ) (((unsigned)(p)) | (1 << (((unsigned)(Ind)) & 07))) +#define Fpga_SeqIsComplement( p ) (((int)((unsigned long) (p) & 01))) +#define Fpga_SeqRegular( p ) ((Fpga_Node_t *)((unsigned long)(p) & ~015)) +#define Fpga_SeqIndex( p ) ((((unsigned long)(p)) >> 1) & 07) +#define Fpga_SeqIndexCreate( p, Ind ) (((unsigned long)(p)) | (1 << (((unsigned)(Ind)) & 07))) // internal macros for referencing of nodes #define Fpga_NodeReadRef(p) ((Fpga_Regular(p))->nRefs) @@ -123,7 +122,9 @@ struct Fpga_ManStruct_t_ int fAreaRecovery; // the flag to use area flow as the first parameter int fVerbose; // the verbosiness flag int fSwitching; // minimize the switching activity (instead of area) - int nTravIds; + int fLatchPaths; // optimize latch paths for delay, other paths for area + int nTravIds; // the counter of traversal IDs + float DelayTarget; // the target required times // support of choice nodes int nChoiceNodes; // the number of choice nodes @@ -170,8 +171,9 @@ struct Fpga_LutLibStruct_t_ { char * pName; // the name of the LUT library int LutMax; // the maximum LUT size + int fVarPinDelays; // set to 1 if variable pin delays are specified float pLutAreas[FPGA_MAX_LUTSIZE+1]; // the areas of LUTs - float pLutDelays[FPGA_MAX_LUTSIZE+1];// the delays of LUTs + float pLutDelays[FPGA_MAX_LUTSIZE+1][FPGA_MAX_LUTSIZE+1];// the delays of LUTs }; // the mapping node @@ -182,8 +184,8 @@ struct Fpga_NodeStruct_t_ Fpga_Node_t * pLevel; // the next node in the linked list by level int Num; // the unique number of this node int NumA; // the unique number of this node - short Num2; // the temporary number of this node - short nRefs; // the number of references (fanouts) of the given node + int Num2; // the temporary number of this node + int nRefs; // the number of references (fanouts) of the given node unsigned fMark0 : 1; // the mark used for traversals unsigned fMark1 : 1; // the mark used for traversals unsigned fInv : 1; // the complemented attribute for the equivalent nodes @@ -276,12 +278,16 @@ struct Fpga_NodeVecStruct_t_ pFanout = pFanout2, \ pFanout2 = Fpga_NodeReadNextFanout(pNode, pFanout) ) +static inline Fpga_FloatMoreThan( Fpga_Man_t * p, float Arg1, float Arg2 ) { return Arg1 > Arg2 + p->fEpsilon; } +static inline Fpga_FloatLessThan( Fpga_Man_t * p, float Arg1, float Arg2 ) { return Arg1 < Arg2 - p->fEpsilon; } +static inline Fpga_FloatEqual( Fpga_Man_t * p, float Arg1, float Arg2 ) { return Arg1 > Arg2 - p->fEpsilon && Arg1 < Arg2 + p->fEpsilon; } + //////////////////////////////////////////////////////////////////////// /// GLOBAL VARIABLES /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /*=== fpgaCut.c ===============================================================*/ @@ -331,7 +337,7 @@ extern float Fpga_MappingGetSwitching( Fpga_Man_t * pMan, Fpga_NodeV extern float Fpga_TimeCutComputeArrival( Fpga_Man_t * pMan, Fpga_Cut_t * pCut ); extern float Fpga_TimeCutComputeArrival_rec( Fpga_Man_t * pMan, Fpga_Cut_t * pCut ); extern float Fpga_TimeComputeArrivalMax( Fpga_Man_t * p ); -extern void Fpga_TimeComputeRequiredGlobal( Fpga_Man_t * p ); +extern void Fpga_TimeComputeRequiredGlobal( Fpga_Man_t * p, int fFirstTime ); extern void Fpga_TimeComputeRequired( Fpga_Man_t * p, float fRequired ); extern void Fpga_TimePropagateRequired( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes ); extern void Fpga_TimePropagateArrival( Fpga_Man_t * p ); @@ -375,8 +381,8 @@ extern void Fpga_MappingSetChoiceLevels( Fpga_Man_t * pMan ); /*=== CUDD package.c ===============================================================*/ extern unsigned int Cudd_Prime( unsigned int p ); +#endif + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// - -#endif diff --git a/src/map/fpga/fpgaLib.c b/src/map/fpga/fpgaLib.c index 9fd8e281..b1bb4cdc 100644 --- a/src/map/fpga/fpgaLib.c +++ b/src/map/fpga/fpgaLib.c @@ -23,11 +23,26 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* + Synopsis [APIs to access LUT library.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fpga_LutLibReadVarMax( Fpga_LutLib_t * p ) { return p->LutMax; } +float * Fpga_LutLibReadLutAreas( Fpga_LutLib_t * p ) { return p->pLutAreas; } +float Fpga_LutLibReadLutArea( Fpga_LutLib_t * p, int Size ) { assert( Size <= p->LutMax ); return p->pLutAreas[Size]; } + +/**Function************************************************************* + Synopsis [Reads the description of LUTs from the LUT library file.] Description [] @@ -42,7 +57,7 @@ Fpga_LutLib_t * Fpga_LutLibCreate( char * FileName, int fVerbose ) char pBuffer[1000], * pToken; Fpga_LutLib_t * p; FILE * pFile; - int i; + int i, k; pFile = fopen( FileName, "r" ); if ( pFile == NULL ) @@ -53,7 +68,7 @@ Fpga_LutLib_t * Fpga_LutLibCreate( char * FileName, int fVerbose ) p = ALLOC( Fpga_LutLib_t, 1 ); memset( p, 0, sizeof(Fpga_LutLib_t) ); - p->pName = util_strsav( FileName ); + p->pName = Extra_UtilStrsav( FileName ); i = 1; while ( fgets( pBuffer, 1000, pFile ) != NULL ) @@ -70,25 +85,66 @@ Fpga_LutLib_t * Fpga_LutLibCreate( char * FileName, int fVerbose ) return NULL; } + // read area pToken = strtok( NULL, " \t\n" ); p->pLutAreas[i] = (float)atof(pToken); - pToken = strtok( NULL, " \t\n" ); - p->pLutDelays[i] = (float)atof(pToken); + // read delays + k = 0; + while ( pToken = strtok( NULL, " \t\n" ) ) + p->pLutDelays[i][k++] = (float)atof(pToken); + + // check for out-of-bound + if ( k > i ) + { + printf( "LUT %d has too many pins (%d). Max allowed is %d.\n", i, k, i ); + return NULL; + } + + // check if var delays are specifies + if ( k > 1 ) + p->fVarPinDelays = 1; if ( i == FPGA_MAX_LUTSIZE ) { printf( "Skipping LUTs of size more than %d.\n", i ); - break; + return NULL; } i++; } p->LutMax = i-1; + if ( p->LutMax > FPGA_MAX_LEAVES ) { p->LutMax = FPGA_MAX_LEAVES; - printf( "Warning: LUTs with more than %d input will not be used.\n", FPGA_MAX_LEAVES ); + printf( "Warning: LUTs with more than %d inputs will not be used.\n", FPGA_MAX_LEAVES ); } + + // check the library + if ( p->fVarPinDelays ) + { + for ( i = 1; i <= p->LutMax; i++ ) + for ( k = 0; k < i; k++ ) + { + if ( p->pLutDelays[i][k] <= 0.0 ) + printf( "Warning: Pin %d of LUT %d has delay %f. Pin delays should be non-negative numbers. Technology mapping may not work correctly.\n", + k, i, p->pLutDelays[i][k] ); + if ( k && p->pLutDelays[i][k-1] > p->pLutDelays[i][k] ) + printf( "Warning: Pin %d of LUT %d has delay %f. Pin %d of LUT %d has delay %f. Pin delays should be in non-decreasing order. Technology mapping may not work correctly.\n", + k-1, i, p->pLutDelays[i][k-1], + k, i, p->pLutDelays[i][k] ); + } + } + else + { + for ( i = 1; i <= p->LutMax; i++ ) + { + if ( p->pLutDelays[i][0] <= 0.0 ) + printf( "Warning: LUT %d has delay %f. Pin delays should be non-negative numbers. Technology mapping may not work correctly.\n", + k, i, p->pLutDelays[i][0] ); + } + } + return p; } @@ -108,7 +164,7 @@ Fpga_LutLib_t * Fpga_LutLibDup( Fpga_LutLib_t * p ) Fpga_LutLib_t * pNew; pNew = ALLOC( Fpga_LutLib_t, 1 ); *pNew = *p; - pNew->pName = util_strsav( pNew->pName ); + pNew->pName = Extra_UtilStrsav( pNew->pName ); return pNew; } @@ -145,11 +201,22 @@ void Fpga_LutLibFree( Fpga_LutLib_t * pLutLib ) ***********************************************************************/ void Fpga_LutLibPrint( Fpga_LutLib_t * pLutLib ) { - int i; + int i, k; printf( "# The area/delay of k-variable LUTs:\n" ); printf( "# k area delay\n" ); - for ( i = 1; i <= pLutLib->LutMax; i++ ) - printf( "%d %7.2f %7.2f\n", i, pLutLib->pLutAreas[i], pLutLib->pLutDelays[i] ); + if ( pLutLib->fVarPinDelays ) + { + for ( i = 1; i <= pLutLib->LutMax; i++ ) + { + printf( "%d %7.2f ", i, pLutLib->pLutAreas[i] ); + for ( k = 0; k < i; k++ ) + printf( " %7.2f", pLutLib->pLutDelays[i][k] ); + printf( "\n" ); + } + } + else + for ( i = 1; i <= pLutLib->LutMax; i++ ) + printf( "%d %7.2f %7.2f\n", i, pLutLib->pLutAreas[i], pLutLib->pLutDelays[i][0] ); } /**Function************************************************************* @@ -169,7 +236,7 @@ int Fpga_LutLibDelaysAreDiscrete( Fpga_LutLib_t * pLutLib ) int i; for ( i = 1; i <= pLutLib->LutMax; i++ ) { - Delay = pLutLib->pLutDelays[i]; + Delay = pLutLib->pLutDelays[i][0]; if ( ((float)((int)Delay)) != Delay ) return 0; } diff --git a/src/map/fpga/fpgaMatch.c b/src/map/fpga/fpgaMatch.c index 20444209..73fa1258 100644 --- a/src/map/fpga/fpgaMatch.c +++ b/src/map/fpga/fpgaMatch.c @@ -30,7 +30,7 @@ static Fpga_Cut_t * Fpga_MappingAreaWithoutNode( Fpga_Man_t * p, Fpga_Node_t * p static int Fpga_MappingMatchesAreaArray( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -87,6 +87,18 @@ int Fpga_MappingMatches( Fpga_Man_t * p, int fDelayOriented ) Extra_ProgressBarUpdate( pProgress, i, "Matches ..." ); } Extra_ProgressBarStop( pProgress ); +/* + if ( !fDelayOriented ) + { + float Area = 0.0; + for ( i = 0; i < p->nOutputs; i++ ) + { + printf( "%5.2f ", Fpga_Regular(p->pOutputs[i])->pCutBest->aFlow ); + Area += Fpga_Regular(p->pOutputs[i])->pCutBest->aFlow; + } + printf( "\nTotal = %5.2f\n", Area ); + } +*/ return 1; } @@ -128,7 +140,7 @@ clk = clock(); Fpga_CutGetParameters( p, pCut ); //p->time2 += clock() - clk; // drop the cut if it does not meet the required times - if ( pCut->tArrival > pNode->tRequired ) + if ( Fpga_FloatMoreThan(p, pCut->tArrival, pNode->tRequired) ) continue; // if no cut is assigned, use the current one if ( pNode->pCutBest == NULL ) @@ -140,11 +152,11 @@ clk = clock(); // (1) delay oriented mapping (first traversal), delay first, area-flow as a tie-breaker // (2) area recovery (subsequent traversals), area-flow first, delay as a tie-breaker if ( (fDelayOriented && - (pNode->pCutBest->tArrival > pCut->tArrival || - pNode->pCutBest->tArrival == pCut->tArrival && pNode->pCutBest->aFlow > pCut->aFlow)) || + (Fpga_FloatMoreThan(p, pNode->pCutBest->tArrival, pCut->tArrival) || + Fpga_FloatEqual(p, pNode->pCutBest->tArrival, pCut->tArrival) && Fpga_FloatMoreThan(p, pNode->pCutBest->aFlow, pCut->aFlow) )) || (!fDelayOriented && - (pNode->pCutBest->aFlow > pCut->aFlow || - pNode->pCutBest->aFlow == pCut->aFlow && pNode->pCutBest->tArrival > pCut->tArrival)) ) + (Fpga_FloatMoreThan(p, pNode->pCutBest->aFlow, pCut->aFlow) || + Fpga_FloatEqual(p, pNode->pCutBest->aFlow, pCut->aFlow) && Fpga_FloatMoreThan(p, pNode->pCutBest->tArrival, pCut->tArrival))) ) { pNode->pCutBest = pCut; } @@ -277,7 +289,7 @@ clk = clock(); pCut->tArrival = Fpga_TimeCutComputeArrival( p, pCut ); //p->time2 += clock() - clk; // drop the cut if it does not meet the required times - if ( pCut->tArrival > pNode->tRequired ) + if ( Fpga_FloatMoreThan( p, pCut->tArrival, pNode->tRequired ) ) continue; // get the area of this cut pCut->aFlow = Fpga_CutGetAreaDerefed( p, pCut ); @@ -288,8 +300,8 @@ clk = clock(); continue; } // choose the best cut as follows: exact area first, delay as a tie-breaker - if ( pNode->pCutBest->aFlow > pCut->aFlow || - pNode->pCutBest->aFlow == pCut->aFlow && pNode->pCutBest->tArrival > pCut->tArrival ) + if ( Fpga_FloatMoreThan(p, pNode->pCutBest->aFlow, pCut->aFlow) || + Fpga_FloatEqual(p, pNode->pCutBest->aFlow, pCut->aFlow) && Fpga_FloatMoreThan(p, pNode->pCutBest->tArrival, pCut->tArrival) ) { pNode->pCutBest = pCut; } @@ -311,7 +323,7 @@ clk = clock(); if ( pNode->nRefs ) { pNode->pCutBest->aFlow = Fpga_CutRef( p, pNode, pNode->pCutBest, 0 ); - assert( pNode->pCutBest->aFlow <= aAreaCutBest ); +// assert( pNode->pCutBest->aFlow <= aAreaCutBest ); // assert( pNode->tRequired < FPGA_FLOAT_LARGE ); } return 1; @@ -398,7 +410,7 @@ clk = clock(); pCut->tArrival = Fpga_TimeCutComputeArrival( p, pCut ); //p->time2 += clock() - clk; // drop the cut if it does not meet the required times - if ( pCut->tArrival > pNode->tRequired ) + if ( Fpga_FloatMoreThan( p, pCut->tArrival, pNode->tRequired ) ) continue; // get the area of this cut pCut->aFlow = Fpga_CutGetSwitchDerefed( p, pNode, pCut ); @@ -409,8 +421,8 @@ clk = clock(); continue; } // choose the best cut as follows: exact area first, delay as a tie-breaker - if ( pNode->pCutBest->aFlow > pCut->aFlow || - pNode->pCutBest->aFlow == pCut->aFlow && pNode->pCutBest->tArrival > pCut->tArrival ) + if ( Fpga_FloatMoreThan(p, pNode->pCutBest->aFlow, pCut->aFlow) || + Fpga_FloatEqual(p, pNode->pCutBest->aFlow, pCut->aFlow) && Fpga_FloatMoreThan(p, pNode->pCutBest->tArrival, pCut->tArrival) ) { pNode->pCutBest = pCut; } @@ -501,7 +513,7 @@ void Fpga_Experiment( Fpga_Man_t * p ) AreaBefore = pNode->pCutBest->aFlow; pNode->pCutBest->aFlow = FPGA_FLOAT_LARGE; - Fpga_TimeComputeRequiredGlobal( p ); + Fpga_TimeComputeRequiredGlobal( p, 0 ); vNodesTfo = Fpga_CollectNodeTfo( p, pNode ); if ( Fpga_MappingMatchesAreaArray( p, vNodesTfo ) == 0 ) diff --git a/src/map/fpga/fpgaSwitch.c b/src/map/fpga/fpgaSwitch.c index 8cc77990..5e881959 100644 --- a/src/map/fpga/fpgaSwitch.c +++ b/src/map/fpga/fpgaSwitch.c @@ -23,7 +23,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**function************************************************************* @@ -139,8 +139,8 @@ float Fpga_MappingGetSwitching( Fpga_Man_t * pMan, Fpga_NodeVec_t * vMapping ) } // add buffer for each CO driven by a CI for ( i = 0; i < pMan->nOutputs; i++ ) - if ( Fpga_NodeIsVar(pMan->pOutputs[i]) && !Fpga_IsComplement(pMan->pOutputs[i]) ) - Switch += pMan->pOutputs[i]->Switching; + if ( Fpga_NodeIsVar(Fpga_Regular(pMan->pOutputs[i])) && !Fpga_IsComplement(pMan->pOutputs[i]) ) + Switch += Fpga_Regular(pMan->pOutputs[i])->Switching; return Switch; } diff --git a/src/map/fpga/fpgaTime.c b/src/map/fpga/fpgaTime.c index 6cbe16f9..879cad4d 100644 --- a/src/map/fpga/fpgaTime.c +++ b/src/map/fpga/fpgaTime.c @@ -23,7 +23,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -46,7 +46,7 @@ float Fpga_TimeCutComputeArrival( Fpga_Man_t * pMan, Fpga_Cut_t * pCut ) for ( i = 0; i < pCut->nLeaves; i++ ) if ( tArrival < pCut->ppLeaves[i]->pCutBest->tArrival ) tArrival = pCut->ppLeaves[i]->pCutBest->tArrival; - tArrival += pMan->pLutLib->pLutDelays[pCut->nLeaves]; + tArrival += pMan->pLutLib->pLutDelays[pCut->nLeaves][0]; return tArrival; } @@ -87,13 +87,34 @@ float Fpga_TimeComputeArrivalMax( Fpga_Man_t * p ) { float fRequired; int i; + if ( p->fLatchPaths && p->nLatches == 0 ) + { + printf( "Delay optimization of latch path is not performed because there is no latches.\n" ); + p->fLatchPaths = 0; + } // get the critical PO arrival time fRequired = -FPGA_FLOAT_LARGE; - for ( i = 0; i < p->nOutputs; i++ ) + if ( p->fLatchPaths ) { - if ( Fpga_NodeIsConst(p->pOutputs[i]) ) - continue; - fRequired = FPGA_MAX( fRequired, Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival ); + for ( i = p->nOutputs - p->nLatches; i < p->nOutputs; i++ ) + { + if ( Fpga_NodeIsConst(p->pOutputs[i]) ) + continue; + fRequired = FPGA_MAX( fRequired, Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival ); +// printf( " %5.1f", Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival ); + } +// printf( "Required latches = %5.1f\n", fRequired ); + } + else + { + for ( i = 0; i < p->nOutputs; i++ ) + { + if ( Fpga_NodeIsConst(p->pOutputs[i]) ) + continue; + fRequired = FPGA_MAX( fRequired, Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival ); +// printf( " %5.1f", Fpga_Regular(p->pOutputs[i])->pCutBest->tArrival ); + } +// printf( "Required outputs = %5.1f\n", fRequired ); } return fRequired; } @@ -109,9 +130,24 @@ float Fpga_TimeComputeArrivalMax( Fpga_Man_t * p ) SeeAlso [] ***********************************************************************/ -void Fpga_TimeComputeRequiredGlobal( Fpga_Man_t * p ) +void Fpga_TimeComputeRequiredGlobal( Fpga_Man_t * p, int fFirstTime ) { p->fRequiredGlo = Fpga_TimeComputeArrivalMax( p ); + // update the required times according to the target + if ( p->DelayTarget != -1 ) + { + if ( p->fRequiredGlo > p->DelayTarget + p->fEpsilon ) + { + if ( fFirstTime ) + printf( "Cannot meet the target required times (%4.2f). Mapping continues anyway.\n", p->DelayTarget ); + } + else if ( p->fRequiredGlo < p->DelayTarget - p->fEpsilon ) + { + if ( fFirstTime ) + printf( "Relaxing the required times from (%4.2f) to the target (%4.2f).\n", p->fRequiredGlo, p->DelayTarget ); + p->fRequiredGlo = p->DelayTarget; + } + } Fpga_TimeComputeRequired( p, p->fRequiredGlo ); } @@ -133,10 +169,23 @@ void Fpga_TimeComputeRequired( Fpga_Man_t * p, float fRequired ) for ( i = 0; i < p->vAnds->nSize; i++ ) p->vAnds->pArray[i]->tRequired = FPGA_FLOAT_LARGE; // set the required times for the POs - for ( i = 0; i < p->nOutputs; i++ ) - Fpga_Regular(p->pOutputs[i])->tRequired = fRequired; + if ( p->fLatchPaths ) + for ( i = p->nOutputs - p->nLatches; i < p->nOutputs; i++ ) + Fpga_Regular(p->pOutputs[i])->tRequired = fRequired; + else + for ( i = 0; i < p->nOutputs; i++ ) + Fpga_Regular(p->pOutputs[i])->tRequired = fRequired; // collect nodes reachable from POs in the DFS order through the best cuts Fpga_TimePropagateRequired( p, p->vMapping ); +/* + { + int Counter = 0; + for ( i = 0; i < p->vAnds->nSize; i++ ) + if ( p->vAnds->pArray[i]->tRequired > FPGA_FLOAT_LARGE - 100 ) + Counter++; + printf( "The number of nodes with large required times = %d.\n", Counter ); + } +*/ } /**Function************************************************************* @@ -167,7 +216,7 @@ void Fpga_TimePropagateRequired( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes ) if ( !Fpga_NodeIsAnd(pNode) ) continue; // get the required time for children - fRequired = pNode->tRequired - p->pLutLib->pLutDelays[pNode->pCutBest->nLeaves]; + fRequired = pNode->tRequired - p->pLutLib->pLutDelays[pNode->pCutBest->nLeaves][0]; // update the required time of the children for ( i = 0; i < pNode->pCutBest->nLeaves; i++ ) { diff --git a/src/map/fpga/fpgaTruth.c b/src/map/fpga/fpgaTruth.c index 17c6385c..e3eb487f 100644 --- a/src/map/fpga/fpgaTruth.c +++ b/src/map/fpga/fpgaTruth.c @@ -24,7 +24,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -94,12 +94,71 @@ void * Fpga_TruthsCutBdd( void * dd, Fpga_Cut_t * pCut ) Cudd_RecursiveDeref( dd, (DdNode*)pCut->uSign ); pCut->uSign = 0; } +// printf( "%d ", vVisited->nSize ); Fpga_NodeVecFree( vVisited ); Cudd_Deref( bFunc ); return bFunc; } +/**Function************************************************************* + + Synopsis [Recursively derives the truth table for the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fpga_CutVolume_rec( Fpga_Cut_t * pCut, Fpga_NodeVec_t * vVisited ) +{ + assert( !Fpga_IsComplement(pCut) ); + if ( pCut->fMark ) + return; + pCut->fMark = 1; + Fpga_CutVolume_rec( Fpga_CutRegular(pCut->pOne), vVisited ); + Fpga_CutVolume_rec( Fpga_CutRegular(pCut->pTwo), vVisited ); + Fpga_NodeVecPush( vVisited, (Fpga_Node_t *)pCut ); +} + +/**Function************************************************************* + + Synopsis [Derives the truth table for one cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fpga_CutVolume( Fpga_Cut_t * pCut ) +{ + Fpga_NodeVec_t * vVisited; + int Volume, i; + assert( pCut->nLeaves > 1 ); + // set the leaf variables + for ( i = 0; i < pCut->nLeaves; i++ ) + pCut->ppLeaves[i]->pCuts->fMark = 1; + // recursively compute the function + vVisited = Fpga_NodeVecAlloc( 10 ); + Fpga_CutVolume_rec( pCut, vVisited ); + // clean the marks + for ( i = 0; i < pCut->nLeaves; i++ ) + pCut->ppLeaves[i]->pCuts->fMark = 0; + for ( i = 0; i < vVisited->nSize; i++ ) + { + pCut = (Fpga_Cut_t *)vVisited->pArray[i]; + pCut->fMark = 0; + } + Volume = vVisited->nSize; + printf( "%d ", Volume ); + Fpga_NodeVecFree( vVisited ); + return Volume; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/map/fpga/fpgaUtils.c b/src/map/fpga/fpgaUtils.c index db0f9623..b951fd8f 100644 --- a/src/map/fpga/fpgaUtils.c +++ b/src/map/fpga/fpgaUtils.c @@ -30,10 +30,11 @@ static int Fpga_MappingCompareOutputDelay( Fpga_Node_t ** ppNode1, Fpga_Node_t static void Fpga_MappingFindLatest( Fpga_Man_t * p, int * pNodes, int nNodesMax ); static void Fpga_DfsLim_rec( Fpga_Node_t * pNode, int Level, Fpga_NodeVec_t * vNodes ); static int Fpga_CollectNodeTfo_rec( Fpga_Node_t * pNode, Fpga_Node_t * pPivot, Fpga_NodeVec_t * vVisited, Fpga_NodeVec_t * vTfo ); +static Fpga_NodeVec_t * Fpga_MappingOrderCosByLevel( Fpga_Man_t * pMan ); static Fpga_Man_t * s_pMan = NULL; //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -50,9 +51,11 @@ static Fpga_Man_t * s_pMan = NULL; ***********************************************************************/ Fpga_NodeVec_t * Fpga_MappingDfs( Fpga_Man_t * pMan, int fCollectEquiv ) { - Fpga_NodeVec_t * vNodes; + Fpga_NodeVec_t * vNodes;//, * vNodesCo; Fpga_Node_t * pNode; int i; + // collect the CO nodes by level +// vNodesCo = Fpga_MappingOrderCosByLevel( pMan ); // start the array vNodes = Fpga_NodeVecAlloc( 100 ); // collect the PIs @@ -65,10 +68,15 @@ Fpga_NodeVec_t * Fpga_MappingDfs( Fpga_Man_t * pMan, int fCollectEquiv ) // perform the traversal for ( i = 0; i < pMan->nOutputs; i++ ) Fpga_MappingDfs_rec( Fpga_Regular(pMan->pOutputs[i]), vNodes, fCollectEquiv ); +// for ( i = vNodesCo->nSize - 1; i >= 0 ; i-- ) +// for ( pNode = vNodesCo->pArray[i]; pNode; pNode = (Fpga_Node_t *)pNode->pData0 ) +// Fpga_MappingDfs_rec( pNode, vNodes, fCollectEquiv ); + // clean the node marks for ( i = 0; i < vNodes->nSize; i++ ) vNodes->pArray[i]->fMark0 = 0; // for ( i = 0; i < pMan->nOutputs; i++ ) // Fpga_MappingUnmark_rec( Fpga_Regular(pMan->pOutputs[i]) ); +// Fpga_NodeVecFree( vNodesCo ); return vNodes; } @@ -930,6 +938,47 @@ void Fpga_ManReportChoices( Fpga_Man_t * pMan ) */ } +/**Function************************************************************* + + Synopsis [Returns the array of CO nodes sorted by level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Fpga_NodeVec_t * Fpga_MappingOrderCosByLevel( Fpga_Man_t * pMan ) +{ + Fpga_Node_t * pNode; + Fpga_NodeVec_t * vNodes; + int i, nLevels; + // get the largest level of a CO + nLevels = Fpga_MappingMaxLevel( pMan ); + // allocate the array of nodes + vNodes = Fpga_NodeVecAlloc( nLevels + 1 ); + for ( i = 0; i <= nLevels; i++ ) + Fpga_NodeVecPush( vNodes, NULL ); + // clean the marks + for ( i = 0; i < pMan->nOutputs; i++ ) + Fpga_Regular(pMan->pOutputs[i])->fMark0 = 0; + // put the nodes into the structure + for ( i = 0; i < pMan->nOutputs; i++ ) + { + pNode = Fpga_Regular(pMan->pOutputs[i]); + if ( pNode->fMark0 ) + continue; + pNode->fMark0 = 1; + pNode->pData0 = (char *)Fpga_NodeVecReadEntry( vNodes, pNode->Level ); + Fpga_NodeVecWriteEntry( vNodes, pNode->Level, pNode ); + } + for ( i = 0; i < pMan->nOutputs; i++ ) + Fpga_Regular(pMan->pOutputs[i])->fMark0 = 0; + return vNodes; + +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/map/fpga/fpgaVec.c b/src/map/fpga/fpgaVec.c index a8c6b983..70a4a7ac 100644 --- a/src/map/fpga/fpgaVec.c +++ b/src/map/fpga/fpgaVec.c @@ -25,7 +25,7 @@ static int Fpga_NodeVecCompareLevels( Fpga_Node_t ** pp1, Fpga_Node_t ** pp2 ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFITIONS /// +/// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* |