summaryrefslogtreecommitdiffstats
path: root/src/map/fpga
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/fpga')
-rw-r--r--src/map/fpga/fpga.c72
-rw-r--r--src/map/fpga/fpga.h41
-rw-r--r--src/map/fpga/fpgaCore.c49
-rw-r--r--src/map/fpga/fpgaCreate.c13
-rw-r--r--src/map/fpga/fpgaCut.c54
-rw-r--r--src/map/fpga/fpgaCutUtils.c10
-rw-r--r--src/map/fpga/fpgaFanout.c2
-rw-r--r--src/map/fpga/fpgaGENERIC.c2
-rw-r--r--src/map/fpga/fpgaInt.h42
-rw-r--r--src/map/fpga/fpgaLib.c91
-rw-r--r--src/map/fpga/fpgaMatch.c40
-rw-r--r--src/map/fpga/fpgaSwitch.c6
-rw-r--r--src/map/fpga/fpgaTime.c69
-rw-r--r--src/map/fpga/fpgaTruth.c61
-rw-r--r--src/map/fpga/fpgaUtils.c53
-rw-r--r--src/map/fpga/fpgaVec.c2
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*************************************************************