summaryrefslogtreecommitdiffstats
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/fpga/fpga.c4
-rw-r--r--src/map/fpga/fpga.h5
-rw-r--r--src/map/fpga/fpgaCreate.c2
-rw-r--r--src/map/fpga/fpgaCut.c2
-rw-r--r--src/map/fpga/fpgaLib.c17
-rw-r--r--src/map/mapper/mapper.c2
-rw-r--r--src/map/mapper/mapperCreate.c4
-rw-r--r--src/map/mapper/mapperCut.c2
-rw-r--r--src/map/mio/mio.c6
-rw-r--r--src/map/pga/module.make4
-rw-r--r--src/map/pga/pga.h72
-rw-r--r--src/map/pga/pgaCore.c152
-rw-r--r--src/map/pga/pgaInt.h132
-rw-r--r--src/map/pga/pgaMan.c180
-rw-r--r--src/map/pga/pgaMatch.c378
-rw-r--r--src/map/pga/pgaUtil.c320
16 files changed, 1271 insertions, 11 deletions
diff --git a/src/map/fpga/fpga.c b/src/map/fpga/fpga.c
index 3d2ca913..9c56f6af 100644
--- a/src/map/fpga/fpga.c
+++ b/src/map/fpga/fpga.c
@@ -77,7 +77,7 @@ void Fpga_Init( Abc_Frame_t * pAbc )
***********************************************************************/
void Fpga_End()
{
- Fpga_LutLibFree( Abc_FrameReadLibLut(Abc_FrameGetGlobalFrame()) );
+ Fpga_LutLibFree( Abc_FrameReadLibLut() );
}
@@ -221,7 +221,7 @@ int Fpga_CommandPrintLibrary( Abc_Frame_t * pAbc, int argc, char **argv )
}
// set the new network
- Fpga_LutLibPrint( Abc_FrameReadLibLut(Abc_FrameGetGlobalFrame()) );
+ Fpga_LutLibPrint( Abc_FrameReadLibLut() );
return 0;
usage:
diff --git a/src/map/fpga/fpga.h b/src/map/fpga/fpga.h
index 19241a74..04894d23 100644
--- a/src/map/fpga/fpga.h
+++ b/src/map/fpga/fpga.h
@@ -142,6 +142,11 @@ 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 );
/*=== fpgaUtil.c =============================================================*/
diff --git a/src/map/fpga/fpgaCreate.c b/src/map/fpga/fpgaCreate.c
index b7bfa3c5..c7acf974 100644
--- a/src/map/fpga/fpgaCreate.c
+++ b/src/map/fpga/fpgaCreate.c
@@ -164,7 +164,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;
diff --git a/src/map/fpga/fpgaCut.c b/src/map/fpga/fpgaCut.c
index 5b5fbe69..f9afa581 100644
--- a/src/map/fpga/fpgaCut.c
+++ b/src/map/fpga/fpgaCut.c
@@ -245,7 +245,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) )
{
diff --git a/src/map/fpga/fpgaLib.c b/src/map/fpga/fpgaLib.c
index 9fd8e281..eb0b5c93 100644
--- a/src/map/fpga/fpgaLib.c
+++ b/src/map/fpga/fpgaLib.c
@@ -28,6 +28,23 @@
/**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_LutLibReadLutDelays( Fpga_LutLib_t * p ) { return p->pLutDelays; }
+float Fpga_LutLibReadLutArea( Fpga_LutLib_t * p, int Size ) { assert( Size <= p->LutMax ); return p->pLutAreas[Size]; }
+float Fpga_LutLibReadLutDelay( Fpga_LutLib_t * p, int Size ) { assert( Size <= p->LutMax ); return p->pLutDelays[Size]; }
+
+/**Function*************************************************************
+
Synopsis [Reads the description of LUTs from the LUT library file.]
Description []
diff --git a/src/map/mapper/mapper.c b/src/map/mapper/mapper.c
index e59fa4a3..3cfd159f 100644
--- a/src/map/mapper/mapper.c
+++ b/src/map/mapper/mapper.c
@@ -61,7 +61,7 @@ void Map_Init( Abc_Frame_t * pAbc )
void Map_End()
{
// Map_SuperLibFree( s_pSuperLib );
- Map_SuperLibFree( Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()) );
+ Map_SuperLibFree( Abc_FrameReadLibSuper() );
}
diff --git a/src/map/mapper/mapperCreate.c b/src/map/mapper/mapperCreate.c
index 31fbf0ea..3dee7f7e 100644
--- a/src/map/mapper/mapperCreate.c
+++ b/src/map/mapper/mapperCreate.c
@@ -183,7 +183,7 @@ Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose )
int i;
// derive the supergate library
- if ( Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()) == NULL )
+ if ( Abc_FrameReadLibSuper() == NULL )
{
printf( "The supergate library is not specified. Use \"read_library\" or \"read_super\".\n" );
return NULL;
@@ -192,7 +192,7 @@ Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose )
// start the manager
p = ALLOC( Map_Man_t, 1 );
memset( p, 0, sizeof(Map_Man_t) );
- p->pSuperLib = Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame());
+ p->pSuperLib = Abc_FrameReadLibSuper();
p->nVarsMax = p->pSuperLib->nVarsMax;
p->fVerbose = fVerbose;
p->fEpsilon = (float)0.001;
diff --git a/src/map/mapper/mapperCut.c b/src/map/mapper/mapperCut.c
index b5ce4018..514d9da8 100644
--- a/src/map/mapper/mapperCut.c
+++ b/src/map/mapper/mapperCut.c
@@ -208,7 +208,7 @@ Map_Cut_t * Map_CutCompute( Map_Man_t * p, Map_CutTable_t * pTable, Map_Node_t *
// set at the node
pNode->pCuts = pCut;
// remove the dominated cuts
-// Map_CutFilter( p, pNode );
+ Map_CutFilter( p, pNode );
// set the phase correctly
if ( pNode->pRepr && Map_NodeComparePhase(pNode, pNode->pRepr) )
{
diff --git a/src/map/mio/mio.c b/src/map/mio/mio.c
index bb6dbba1..569bcceb 100644
--- a/src/map/mio/mio.c
+++ b/src/map/mio/mio.c
@@ -108,7 +108,7 @@ void Mio_Init( Abc_Frame_t * pAbc )
void Mio_End()
{
// Mio_LibraryDelete( s_pLib );
- Mio_LibraryDelete( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) );
+ Mio_LibraryDelete( Abc_FrameReadLibGen() );
}
@@ -181,7 +181,7 @@ int Mio_CommandReadLibrary( Abc_Frame_t * pAbc, int argc, char **argv )
return 1;
}
// free the current superlib because it depends on the old Mio library
- if ( Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()) )
+ if ( Abc_FrameReadLibSuper() )
{
extern void Map_SuperLibFree( Map_SuperLib_t * p );
// Map_SuperLibFree( s_pSuperLib );
@@ -252,7 +252,7 @@ int Mio_CommandPrintLibrary( Abc_Frame_t * pAbc, int argc, char **argv )
}
// set the new network
- Mio_WriteLibrary( stdout, Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()), 0 );
+ Mio_WriteLibrary( stdout, Abc_FrameReadLibGen(), 0 );
return 0;
usage:
diff --git a/src/map/pga/module.make b/src/map/pga/module.make
new file mode 100644
index 00000000..2a45327e
--- /dev/null
+++ b/src/map/pga/module.make
@@ -0,0 +1,4 @@
+SRC += src/map/pga/pgaCore.c \
+ src/map/pga/pgaMan.c \
+ src/map/pga/pgaMatch.c \
+ src/map/pga/pgaUtil.c
diff --git a/src/map/pga/pga.h b/src/map/pga/pga.h
new file mode 100644
index 00000000..5575e0ce
--- /dev/null
+++ b/src/map/pga/pga.h
@@ -0,0 +1,72 @@
+/**CFile****************************************************************
+
+ FileName [pga.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [FPGA mapper.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: pga.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __PGA_H__
+#define __PGA_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Pga_ManStruct_t_ Pga_Man_t;
+typedef struct Pga_ParamsStruct_t_ Pga_Params_t;
+
+struct Pga_ParamsStruct_t_
+{
+ // data for mapping
+ Abc_Ntk_t * pNtk; // the network to be mapped
+ Fpga_LutLib_t * pLutLib; // the LUT library
+ float * pSwitching; // switching activity for each node
+ // mapping parameters
+ int fDropCuts; // enables cut dropping
+ int fAreaFlow; // enables area flow minimization
+ int fArea; // enables area minimization
+ int fSwitching; // enables switching activity minimization
+ int fVerbose; // enables verbose output
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== pgaApi.c ==========================================================*/
+extern Vec_Ptr_t * Pga_DoMapping( Pga_Man_t * p );
+/*=== pgaMan.c ==========================================================*/
+extern Pga_Man_t * Pga_ManStart( Pga_Params_t * pParams );
+extern void Pga_ManStop( Pga_Man_t * p );
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/src/map/pga/pgaCore.c b/src/map/pga/pgaCore.c
new file mode 100644
index 00000000..09a9d218
--- /dev/null
+++ b/src/map/pga/pgaCore.c
@@ -0,0 +1,152 @@
+/**CFile****************************************************************
+
+ FileName [pgaCore.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [FPGA mapper.]
+
+ Synopsis [External APIs of the FPGA manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: pgaCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "pgaInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Pga_MappingInitCis( Pga_Man_t * p );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs technology mapping for the given object graph.]
+
+ Description [The object graph is stored in the mapping manager.
+ First, all the AND-nodes, which fanout into the POs, are collected
+ in the DFS fashion. Next, three steps are performed: the k-feasible
+ cuts are computed for each node, the truth tables are computed for
+ each cut, and the delay-optimal matches are assigned for each node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Pga_DoMapping( Pga_Man_t * p )
+{
+ int fShowSwitching = 0;
+ float aAreaTotalCur;
+ int Iter, clk, clkTotal = clock();
+
+ // assign the arrival times of the PIs
+ Pga_MappingInitCis( p );
+
+ // map the AIG for delay
+clk = clock();
+ Pga_MappingMatches( p, 0 );
+p->timeDelay = clock() - clk;
+
+ // compute area, set references, and collect nodes used in the mapping
+ Iter = 1;
+ aAreaTotalCur = Pga_MappingSetRefsAndArea( p );
+if ( p->pParams->fVerbose )
+{
+printf( "Iteration %dD : Area = %8.1f ", Iter++, aAreaTotalCur );
+if ( fShowSwitching )
+printf( "Switch = %8.1f ", Pga_MappingGetSwitching(p) );
+PRT( "Time", p->timeDelay );
+}
+
+ if ( p->pParams->fAreaFlow )
+ {
+clk = clock();
+ // compute the required times and the fanouts
+ Pga_MappingComputeRequired( p );
+ // remap topologically
+ Pga_MappingMatches( p, 1 );
+p->timeAreaFlow = clock() - clk;
+ // get the resulting area
+ aAreaTotalCur = Pga_MappingSetRefsAndArea( p );
+ // note that here we do not update the reference counter
+ // for some reason, this works better on benchmarks
+if ( p->pParams->fVerbose )
+{
+printf( "Iteration %dF : Area = %8.1f ", Iter++, aAreaTotalCur );
+if ( fShowSwitching )
+printf( "Switch = %8.1f ", Pga_MappingGetSwitching(p) );
+PRT( "Time", p->timeAreaFlow );
+}
+ }
+
+ if ( p->pParams->fArea )
+ {
+clk = clock();
+ // compute the required times and the fanouts
+ Pga_MappingComputeRequired( p );
+ // remap topologically
+ if ( p->pParams->fSwitching )
+ Pga_MappingMatches( p, 3 );
+ else
+ Pga_MappingMatches( p, 2 );
+p->timeArea = clock() - clk;
+ // get the resulting area
+ aAreaTotalCur = Pga_MappingSetRefsAndArea( p );
+if ( p->pParams->fVerbose )
+{
+printf( "Iteration %d%s : Area = %8.1f ", Iter++, (p->pParams->fSwitching?"S":"A"), aAreaTotalCur );
+if ( fShowSwitching )
+printf( "Switch = %8.1f ", Pga_MappingGetSwitching(p) );
+PRT( "Time", p->timeArea );
+}
+ }
+ p->AreaGlobal = aAreaTotalCur;
+
+ if ( p->pParams->fVerbose )
+ Pga_MappingPrintOutputArrivals( p );
+
+ // return the mapping
+ return Pga_MappingResults( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Initializes the CI node arrival times.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Pga_MappingInitCis( Pga_Man_t * p )
+{
+ Pga_Node_t * pNode;
+ float * pCiArrs;
+ int i;
+ // get the CI arrival times
+ pCiArrs = Abc_NtkGetCiArrivalFloats( p->pParams->pNtk );
+ // assign the arrival times of the PIs
+ Pga_ManForEachCi( p, pNode, i )
+ pNode->Match.Delay = pCiArrs[i];
+ free( pCiArrs );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/map/pga/pgaInt.h b/src/map/pga/pgaInt.h
new file mode 100644
index 00000000..27355459
--- /dev/null
+++ b/src/map/pga/pgaInt.h
@@ -0,0 +1,132 @@
+/**CFile****************************************************************
+
+ FileName [pgaInt.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [FPGA mapper.]
+
+ Synopsis [Internal declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: pgaInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __PGA_INT_H__
+#define __PGA_INT_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include "abc.h"
+#include "fraig.h"
+#include "fpga.h"
+#include "cut.h"
+#include "pga.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Pga_NodeStruct_t_ Pga_Node_t;
+typedef struct Pga_MatchStruct_t_ Pga_Match_t;
+
+struct Pga_ManStruct_t_
+{
+ // mapping parameters
+ Pga_Params_t * pParams; // input data
+ // mapping structures
+ Pga_Node_t * pMemory; // the memory for all mapping structures
+ Vec_Ptr_t * vStructs; // mapping structures one-to-one with ABC nodes
+ Vec_Ptr_t * vOrdering; // mapping nodes ordered by level
+ // k-feasible cuts
+ int nVarsMax; // the "k" of k-feasible cuts
+ Cut_Man_t * pManCut; // the cut manager
+ // LUT library
+ float * pLutDelays; // the delay of the LUTs
+ float * pLutAreas; // the areas of the LUTs
+ float Epsilon;
+ // global parameters
+ float AreaGlobal; // the total area of this mapping
+ float ArrivalGlobal; // the largest delay of any path
+ float RequiredGlobal;// the global required time (may be different from largest delay)
+ float RequiredUser; // the required time given by the user
+ // runtime stats
+ int timeToMap; // the time to start the mapper
+ int timeCuts; // the time to compute the cuts
+ int timeDelay; // the time to compute delay
+ int timeAreaFlow; // the time to perform area flow optimization
+ int timeArea; // the time to perform area flow optimization
+ int timeToNet; // the time to transform back to network
+ int timeTotal; // the total time
+ int time1; // temporary
+ int time2; // temporary
+};
+
+struct Pga_MatchStruct_t_
+{
+ Cut_Cut_t * pCut; // the best cut
+ float Delay; // the arrival time of this cut
+ float Area; // the area of this cut
+};
+
+struct Pga_NodeStruct_t_
+{
+ int Id; // ID of the node
+ int nRefs; // the number of references
+ float EstRefs; // the estimated reference counter
+ float Required; // the required time
+ float Switching; // the switching activity
+ Pga_Match_t Match; // the best match at the node
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline Pga_Node_t * Pga_Node( Pga_Man_t * p, int Id ) { return p->vStructs->pArray[Id]; }
+
+// iterator through the CIs
+#define Pga_ManForEachCi( p, pCi, i ) \
+ for ( i = 0; (i < Abc_NtkCiNum(p->pParams->pNtk)) && (((pCi) = Pga_Node(p, Abc_NtkCi(p->pParams->pNtk,i)->Id)), 1); i++ )
+// iterator through the CO derivers
+#define Pga_ManForEachCoDriver( p, pCo, i ) \
+ for ( i = 0; (i < Abc_NtkCoNum(p->pParams->pNtk)) && (((pCo) = Pga_Node(p, Abc_ObjFaninId0(Abc_NtkCo(p->pParams->pNtk,i)))), 1); i++ )
+// iterators through the CIs and internal nodes
+#define Pga_ManForEachObjDirect( p, pNode, i ) \
+ Vec_PtrForEachEntry( p->vOrdering, pNode, i )
+#define Pga_ManForEachObjReverse( p, pNode, i ) \
+ Vec_PtrForEachEntryReverse( p->vOrdering, pNode, i )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== pgaMatch.c ==========================================================*/
+extern void Pga_MappingMatches( Pga_Man_t * p, int Mode );
+/*=== pgaUtil.c ==========================================================*/
+extern Vec_Ptr_t * Pga_MappingResults( Pga_Man_t * p );
+extern float Pga_TimeComputeArrivalMax( Pga_Man_t * p );
+extern void Pga_MappingComputeRequired( Pga_Man_t * p );
+extern float Pga_MappingSetRefsAndArea( Pga_Man_t * p );
+extern float Pga_MappingGetSwitching( Pga_Man_t * p );
+extern void Pga_MappingPrintOutputArrivals( Pga_Man_t * p );
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/src/map/pga/pgaMan.c b/src/map/pga/pgaMan.c
new file mode 100644
index 00000000..d7573ecf
--- /dev/null
+++ b/src/map/pga/pgaMan.c
@@ -0,0 +1,180 @@
+/**CFile****************************************************************
+
+ FileName [pgaMan.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [FPGA mapper.]
+
+ Synopsis [Mapping manager.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: pgaMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "pgaInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Cut_Man_t * Pga_ManStartCutMan( Pga_Params_t * pParamsPga );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Starts the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Pga_Man_t * Pga_ManStart( Pga_Params_t * pParams )
+{
+ Pga_Man_t * p;
+ Pga_Node_t * pNode;
+ Cut_Man_t * pManCut;
+ Abc_Ntk_t * pNtk;
+ Abc_Obj_t * pObj;
+ int i, Counter;
+ int clk = clock();
+
+ // make sure the network is given
+ pNtk = pParams->pNtk;
+ if ( pNtk == NULL )
+ {
+ printf( "Network is not specified.\n" );
+ return NULL;
+ }
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ printf( "Mapping can only be applied to an AIG.\n" );
+ return NULL;
+ }
+ // the cut manager if given should be in sinc
+ pManCut = pNtk->pManCut;
+ if ( pManCut && Cut_ManReadVarsMax(pManCut) != Fpga_LutLibReadVarMax(pParams->pLutLib) )
+ {
+ printf( "The precomputed cuts have different size.\n" );
+ return NULL;
+ }
+ // make sure the nodes are in the topological order
+ if ( !Abc_NtkIsDfsOrdered(pNtk) )
+ {
+ printf( "The nodes of the network are not DFS ordered.\n" );
+// Abc_NtkReassignIds( pNtk );
+ return NULL;
+ }
+ // make sure there are no dangling nodes (unless they are choices)
+
+ // start the mapping manager
+ p = ALLOC( Pga_Man_t, 1 );
+ memset( p, 0, sizeof(Pga_Man_t) );
+ p->pParams = pParams;
+ p->nVarsMax = Fpga_LutLibReadVarMax(pParams->pLutLib);
+ p->pManCut = pManCut? pManCut : Pga_ManStartCutMan(pParams);
+ p->vOrdering = Abc_AigGetLevelizedOrder(pNtk, 0); // what happens with dangling nodes???
+ p->pLutAreas = Fpga_LutLibReadLutAreas(pParams->pLutLib);
+ p->pLutDelays = Fpga_LutLibReadLutDelays(pParams->pLutLib);
+ p->Epsilon = (float)0.00001;
+
+ // allocate mapping structures
+ p->pMemory = ALLOC( Pga_Node_t, Abc_NtkObjNum(pNtk) );
+ memset( p->pMemory, 0, sizeof(Pga_Node_t) * Abc_NtkObjNum(pNtk) );
+ p->vStructs = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) );
+ Counter = 0;
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ {
+ pNode = p->pMemory + Counter++;
+ pNode->Id = pObj->Id;
+ pNode->nRefs = pObj->vFanouts.nSize;
+ pNode->Required = ABC_INFINITY;
+ pNode->Match.Area = ABC_INFINITY;
+ // skip secondary nodes
+ if ( Abc_ObjFanoutNum(pObj) == 0 )
+ continue;
+ Vec_PtrWriteEntry( p->vStructs, pObj->Id, pNode );
+ }
+ assert( Counter == Abc_NtkObjNum(pNtk) );
+ // update order to depend on mapping nodes
+ Vec_PtrForEachEntry( p->vOrdering, pObj, i )
+ Vec_PtrWriteEntry( p->vOrdering, i, Pga_Node(p,pObj->Id) );
+p->timeToMap = clock() - clk;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Pga_ManStop( Pga_Man_t * p )
+{
+ Cut_ManStop( p->pManCut );
+ Vec_PtrFree( p->vOrdering );
+ Vec_PtrFree( p->vStructs );
+ free( p->pMemory );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts the cut manager for FPGA mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cut_Man_t * Pga_ManStartCutMan( Pga_Params_t * pParamsPga )
+{
+ static Cut_Params_t Params, * pParams = &Params;
+ Abc_Ntk_t * pNtk = pParamsPga->pNtk;
+ Cut_Man_t * pManCut;
+ Abc_Obj_t * pObj;
+ int i;
+ // start the cut manager
+ memset( pParams, 0, sizeof(Cut_Params_t) );
+ pParams->nVarsMax = Fpga_LutLibReadVarMax(pParamsPga->pLutLib); // max cut size
+ pParams->nKeepMax = 250; // the max number of cuts kept at a node
+ pParams->fTruth = 0; // compute truth tables
+ pParams->fFilter = 1; // filter dominated cuts
+ pParams->fSeq = 0; // compute sequential cuts
+ pParams->fDrop = pParamsPga->fDropCuts; // drop cuts on the fly
+ pParams->fVerbose = 0; // the verbosiness flag
+ pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
+ pManCut = Cut_ManStart( pParams );
+ if ( pParams->fDrop )
+ Cut_ManSetFanoutCounts( pManCut, Abc_NtkFanoutCounts(pNtk) );
+ // set cuts for PIs
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ if ( Abc_ObjFanoutNum(pObj) > 0 )
+ Cut_NodeSetTriv( pManCut, pObj->Id );
+ return pManCut;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/map/pga/pgaMatch.c b/src/map/pga/pgaMatch.c
new file mode 100644
index 00000000..f9f6b5c4
--- /dev/null
+++ b/src/map/pga/pgaMatch.c
@@ -0,0 +1,378 @@
+/**CFile****************************************************************
+
+ FileName [pgaMatch.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [FPGA mapper.]
+
+ Synopsis [Mapping procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: pgaMatch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "pgaInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static char * s_Modes[4] = { "Delay", "Flow", "Area", "Switch" };
+
+static int Pga_MappingMatchNode( Pga_Man_t * p, int NodeId, Cut_Cut_t * pList, int Mode );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs mapping for delay, area-flow, area, switching.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Pga_MappingMatches( Pga_Man_t * p, int Mode )
+{
+ ProgressBar * pProgress;
+ Abc_Ntk_t * pNtk;
+ Abc_Obj_t * pObj;
+ Cut_Cut_t * pList;
+ int i, clk;
+
+ assert( Mode >= 0 && Mode <= 2 );
+
+ // match LUTs with nodes in the topological order
+ pNtk = p->pParams->pNtk;
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ {
+ // skip the CIs
+ if ( Abc_ObjIsCi(pObj) )
+ continue;
+ // when we reached a CO, it is time to deallocate the cuts
+ if ( Abc_ObjIsCo(pObj) )
+ {
+ if ( p->pParams->fDropCuts )
+ Cut_NodeTryDroppingCuts( p->pManCut, Abc_ObjFaninId0(pObj) );
+ continue;
+ }
+ // skip constant node, it has no cuts
+ if ( Abc_NodeIsConst(pObj) )
+ continue;
+ // get the cuts
+clk = clock();
+ pList = Abc_NodeGetCutsRecursive( p->pManCut, pObj );
+p->timeCuts += clock() - clk;
+ // match the node
+ Pga_MappingMatchNode( p, pObj->Id, pList, Mode );
+ Extra_ProgressBarUpdate( pProgress, i, s_Modes[Mode] );
+ }
+ Extra_ProgressBarStop( pProgress );
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes the match of the cut.]
+
+ Description [Returns 1 if feasible.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline float Pga_CutGetArrival( Pga_Man_t * p, Cut_Cut_t * pCut )
+{
+ float DelayCur, DelayWorst;
+ unsigned i;
+ assert( pCut->nLeaves > 1 );
+ DelayWorst = -ABC_INFINITY;
+ for ( i = 0; i < pCut->nLeaves; i++ )
+ {
+ DelayCur = Pga_Node(p, pCut->pLeaves[i])->Match.Delay;
+ if ( DelayWorst < DelayCur )
+ DelayWorst = DelayCur;
+ }
+ DelayWorst += p->pLutDelays[pCut->nLeaves];
+ return DelayWorst;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the match of the cut.]
+
+ Description [Returns 1 if feasible.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline float Pga_CutGetAreaFlow( Pga_Man_t * p, Cut_Cut_t * pCut )
+{
+ float Flow;
+ Pga_Node_t * pNode;
+ unsigned i;
+ assert( pCut->nLeaves > 1 );
+ Flow = p->pLutAreas[pCut->nLeaves];
+ for ( i = 0; i < pCut->nLeaves; i++ )
+ {
+ pNode = Pga_Node(p, pCut->pLeaves[i]);
+ assert( pNode->EstRefs > 0 );
+ Flow += pNode->Match.Area / pNode->EstRefs;
+ }
+ return Flow;
+}
+
+/**function*************************************************************
+
+ synopsis [References the cut.]
+
+ description [This procedure is similar to the procedure NodeReclaim.]
+
+ sideeffects []
+
+ seealso []
+
+***********************************************************************/
+float Pga_CutRef( Pga_Man_t * p, Pga_Node_t * pNode, Cut_Cut_t * pCut )
+{
+ Pga_Node_t * pFanin;
+ float aArea;
+ unsigned i;
+ // start the area of this cut
+ aArea = p->pLutAreas[pCut->nLeaves];
+ // go through the children
+ for ( i = 0; i < pCut->nLeaves; i++ )
+ {
+ pFanin = Pga_Node(p, pCut->pLeaves[i]);
+ assert( pFanin->nRefs >= 0 );
+ if ( pFanin->nRefs++ > 0 )
+ continue;
+ if ( pFanin->Match.pCut == NULL )
+ continue;
+ aArea += Pga_CutRef( p, pFanin, pFanin->Match.pCut );
+ }
+ return aArea;
+}
+
+/**function*************************************************************
+
+ synopsis [Dereferences the cut.]
+
+ description [This procedure is similar to the procedure NodeRecusiveDeref.]
+
+ sideeffects []
+
+ seealso []
+
+***********************************************************************/
+float Pga_CutDeref( Pga_Man_t * p, Pga_Node_t * pNode, Cut_Cut_t * pCut )
+{
+ Pga_Node_t * pFanin;
+ float aArea;
+ unsigned i;
+ // start the area of this cut
+ aArea = p->pLutAreas[pCut->nLeaves];
+ // go through the children
+ for ( i = 0; i < pCut->nLeaves; i++ )
+ {
+ pFanin = Pga_Node(p, pCut->pLeaves[i]);
+ assert( pFanin->nRefs > 0 );
+ if ( --pFanin->nRefs > 0 )
+ continue;
+ if ( pFanin->Match.pCut == NULL )
+ continue;
+ aArea += Pga_CutDeref( p, pFanin, pFanin->Match.pCut );
+ }
+ return aArea;
+}
+
+/**function*************************************************************
+
+ synopsis [Computes the exact area associated with the cut.]
+
+ description [Assumes that the cut is deferenced.]
+
+ sideeffects []
+
+ seealso []
+
+***********************************************************************/
+static inline float Pga_CutGetAreaDerefed( Pga_Man_t * p, Pga_Node_t * pNode, Cut_Cut_t * pCut )
+{
+ float aResult, aResult2;
+ assert( pCut->nLeaves > 1 );
+ aResult2 = Pga_CutRef( p, pNode, pCut );
+ aResult = Pga_CutDeref( p, pNode, pCut );
+ assert( aResult == aResult2 );
+ return aResult;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes the match of the cut.]
+
+ Description [Returns 1 if feasible.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Pga_MappingMatchCut( Pga_Man_t * p, Pga_Node_t * pNode, Cut_Cut_t * pCut, int Mode, Pga_Match_t * pMatch )
+{
+ // compute the arrival time of the cut and its area flow
+ pMatch->Delay = Pga_CutGetArrival( p, pCut );
+ // drop the cut if it does not meet the required times
+ if ( pMatch->Delay > pNode->Required + p->Epsilon )
+ return 0;
+ // get the second parameter
+ if ( Mode == 0 || Mode == 1 )
+ pMatch->Area = Pga_CutGetAreaFlow( p, pCut );
+ else if ( Mode == 2 )
+ pMatch->Area = Pga_CutGetAreaDerefed( p, pNode, pCut );
+// else if ( Mode == 3 )
+// pMatch->Area = Pga_CutGetSwitching( p, pNode, pCut );
+ // if no cut is assigned, use the current one
+ pMatch->pCut = pCut;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compares two matches.]
+
+ Description [Returns 1 if the second match is better.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Pga_MappingCompareMatches( Pga_Man_t * p, Pga_Match_t * pMatchBest, Pga_Match_t * pMatchCur, int Mode )
+{
+ if ( pMatchBest->pCut == NULL )
+ return 1;
+ if ( Mode == 0 )
+ {
+ // compare delays
+ if ( pMatchBest->Delay < pMatchCur->Delay - p->Epsilon )
+ return 0;
+ if ( pMatchBest->Delay > pMatchCur->Delay + p->Epsilon )
+ return 1;
+ // compare areas
+ if ( pMatchBest->Area < pMatchCur->Area - p->Epsilon )
+ return 0;
+ if ( pMatchBest->Area > pMatchCur->Area + p->Epsilon )
+ return 1;
+ // if equal, do not update
+ return 0;
+ }
+ else
+ {
+ // compare areas
+ if ( pMatchBest->Area < pMatchCur->Area - p->Epsilon )
+ return 0;
+ if ( pMatchBest->Area > pMatchCur->Area + p->Epsilon )
+ return 1;
+ // compare delays
+ if ( pMatchBest->Delay < pMatchCur->Delay - p->Epsilon )
+ return 0;
+ if ( pMatchBest->Delay > pMatchCur->Delay + p->Epsilon )
+ return 1;
+ // if equal, do not update
+ return 0;
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes the best matching for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Pga_MappingMatchNode( Pga_Man_t * p, int NodeId, Cut_Cut_t * pList, int Mode )
+{
+ Pga_Match_t MatchCur, * pMatchCur = &MatchCur;
+ Pga_Match_t MatchBest, * pMatchBest = &MatchBest;
+ Pga_Node_t * pNode;
+ Cut_Cut_t * pCut;
+
+ // get the mapping node
+ pNode = Pga_Node( p, NodeId );
+
+ // prepare for mapping
+ if ( Mode == 0 )
+ pNode->EstRefs = (float)pNode->nRefs;
+ else if ( Mode == 1 )
+ pNode->EstRefs = (float)((2.0 * pNode->EstRefs + pNode->nRefs) / 3.0);
+ else if ( Mode == 2 && pNode->nRefs > 0 )
+ Pga_CutDeref( p, pNode, pNode->Match.pCut );
+// else if ( Mode == 3 && pNode->nRefs > 0 )
+// Pga_CutDerefSwitch( p, pNode, pNode->Match.pCut );
+
+ // start the best match
+ pMatchBest->pCut = NULL;
+
+ // go through the other cuts
+ assert( pList->pNext );
+ for ( pCut = pList->pNext; pCut; pCut = pCut->pNext )
+ {
+ // compute match for this cut
+ if ( !Pga_MappingMatchCut( p, pNode, pCut, Mode, pMatchCur ) )
+ continue;
+ // compare matches
+ if ( !Pga_MappingCompareMatches( p, pMatchBest, pMatchCur, Mode ) )
+ continue;
+ // the best match should be updated
+ *pMatchBest = *pMatchCur;
+ }
+
+ // make sure the match is found
+ if ( pMatchBest->pCut != NULL )
+ pNode->Match = *pMatchBest;
+ else
+ {
+ assert( 0 );
+// Pga_MappingMatchCut( p, pNode, pCut, Mode, pNode->Match );
+ }
+
+ // reference the best cut
+ if ( Mode == 2 && pNode->nRefs > 0 )
+ Pga_CutRef( p, pNode, pNode->Match.pCut );
+// else if ( Mode == 3 && pNode->nRefs > 0 )
+// Pga_CutRefSwitch( p, pNode, pNode->Match.pCut );
+ return 1;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/map/pga/pgaUtil.c b/src/map/pga/pgaUtil.c
new file mode 100644
index 00000000..73f3d381
--- /dev/null
+++ b/src/map/pga/pgaUtil.c
@@ -0,0 +1,320 @@
+/**CFile****************************************************************
+
+ FileName [pgaUtil.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [FPGA mapper.]
+
+ Synopsis [Verious utilities.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: pgaUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "pgaInt.h"
+
+#define PGA_CO_LIST_SIZE 5
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Returns the results of mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Pga_MappingResults( Pga_Man_t * p )
+{
+ Vec_Ptr_t * vResult;
+ Pga_Node_t * pNode;
+ int i;
+ vResult = Vec_PtrAlloc( 1000 );
+ Pga_ManForEachObjDirect( p, pNode, i )
+ {
+ // skip the CIs and nodes not used in the mapping
+ if ( !pNode->Match.pCut || !pNode->nRefs )
+ continue;
+ pNode->Match.pCut->uSign = pNode->Id;
+ Vec_PtrPush( vResult, pNode->Match.pCut );
+ }
+ return vResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the maximum arrival times.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Pga_TimeComputeArrivalMax( Pga_Man_t * p )
+{
+ Pga_Node_t * pNode;
+ float ArrivalMax;
+ int i;
+ ArrivalMax = -ABC_INFINITY;
+ Pga_ManForEachCoDriver( p, pNode, i )
+ ArrivalMax = ABC_MAX( ArrivalMax, pNode->Match.Delay );
+ return ArrivalMax;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes required times of all nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Pga_MappingComputeRequired( Pga_Man_t * p )
+{
+ Pga_Node_t * pNode, * pFanin;
+ Cut_Cut_t * pCutBest;
+ float RequiredNew;
+ int i, k;
+ // clean the required times of all nodes
+ Pga_ManForEachObjDirect( p, pNode, i )
+ pNode->Required = ABC_INFINITY;
+ // get the global required times
+ p->AreaGlobal = Pga_TimeComputeArrivalMax( p );
+ p->RequiredGlobal = ABC_MAX( p->AreaGlobal, p->RequiredUser );
+ // set the global required times of the CO drivers
+ Pga_ManForEachCoDriver( p, pNode, i )
+ pNode->Required = p->RequiredGlobal;
+ // propagate the required times in the reverse topological order
+ Pga_ManForEachObjReverse( p, pNode, i )
+ {
+ // skip the CIs and nodes not used in the mapping
+ if ( !pNode->Match.pCut || !pNode->nRefs )
+ continue;
+ // get the required time for children
+ pCutBest = pNode->Match.pCut;
+ RequiredNew = pNode->Required - p->pLutDelays[pCutBest->nLeaves];
+ // update the required time of the children
+ for ( k = 0; k < (int)pCutBest->nLeaves; k++ )
+ {
+ pFanin = Pga_Node( p, pCutBest->pLeaves[k] );
+ pFanin->Required = ABC_MIN( pFanin->Required, RequiredNew );
+ }
+ }
+ // check that the required times does not contradict the arrival times
+ Pga_ManForEachObjDirect( p, pNode, i )
+ assert( !pNode->Match.pCut || pNode->Match.Delay < pNode->Required + p->Epsilon );
+
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets references and computes area for the current mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Pga_MappingSetRefsAndArea( Pga_Man_t * p )
+{
+ Pga_Node_t * pNode, * pFanin;
+ Cut_Cut_t * pCutBest;
+ float AreaTotal;
+ int i, k;
+ // clean all the references
+ Pga_ManForEachObjDirect( p, pNode, i )
+ pNode->nRefs = 0;
+ // set the references of the CO drivers
+ Pga_ManForEachCoDriver( p, pNode, i )
+ pNode->nRefs++;
+ // go through the nodes in the reverse order
+ AreaTotal = 0.0;
+ Pga_ManForEachObjReverse( p, pNode, i )
+ {
+ // skip the CIs and nodes not used in the mapping
+ if ( !pNode->Match.pCut || !pNode->nRefs )
+ continue;
+ // increate the reference count of the children
+ pCutBest = pNode->Match.pCut;
+ AreaTotal += p->pLutAreas[pCutBest->nLeaves];
+ // update the required time of the children
+ for ( k = 0; k < (int)pCutBest->nLeaves; k++ )
+ {
+ pFanin = Pga_Node( p, pCutBest->pLeaves[k] );
+ pFanin->nRefs++;
+ }
+ }
+ return AreaTotal;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes switching activity of the mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Pga_MappingGetSwitching( Pga_Man_t * p )
+{
+ float Switching;
+ Pga_Node_t * pNode;
+ int i;
+ Switching = 0;
+ Pga_ManForEachObjDirect( p, pNode, i )
+ {
+ // skip the CIs and nodes not used in the mapping
+ if ( !pNode->Match.pCut || !pNode->nRefs )
+ continue;
+ Switching += pNode->Switching;
+ }
+ return Switching;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compares the outputs by their arrival times.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Pga_MappingCompareOutputDelay( Pga_Node_t ** ppNode1, Pga_Node_t ** ppNode2 )
+{
+ Pga_Node_t * pNode1 = *ppNode1;
+ Pga_Node_t * pNode2 = *ppNode2;
+ float Arrival1 = pNode1->Match.Delay;
+ float Arrival2 = pNode2->Match.Delay;
+ if ( Arrival1 < Arrival2 )
+ return -1;
+ if ( Arrival1 > Arrival2 )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds given number of latest arriving COs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Pga_MappingFindLatest( Pga_Man_t * p, int * pNodes, int nNodesMax )
+{
+ Pga_Node_t * pNodeI, * pNodeK;
+ Abc_Obj_t * pObjCo;
+ int nNodes, i, k, v;
+ assert( Abc_NtkCoNum(p->pParams->pNtk) >= nNodesMax );
+ pNodes[0] = 0;
+ nNodes = 1;
+// for ( i = 1; i < p->nOutputs; i++ )
+ Pga_ManForEachCoDriver( p, pNodeI, i )
+ {
+ for ( k = nNodes - 1; k >= 0; k-- )
+ {
+ pObjCo = Abc_NtkCo( p->pParams->pNtk, pNodes[k] );
+ pNodeK = Pga_Node( p, Abc_ObjFaninId0(pObjCo) );
+ if ( Pga_MappingCompareOutputDelay( &pNodeK, &pNodeI ) >= 0 )
+ break;
+ }
+ if ( k == nNodesMax - 1 )
+ continue;
+ if ( nNodes < nNodesMax )
+ nNodes++;
+ for ( v = nNodes - 1; v > k+1; v-- )
+ pNodes[v] = pNodes[v-1];
+ pNodes[k+1] = i;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints a bunch of latest arriving outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Pga_MappingPrintOutputArrivals( Pga_Man_t * p )
+{
+ int pSorted[PGA_CO_LIST_SIZE];
+ Abc_Ntk_t * pNtk = p->pParams->pNtk;
+ Abc_Obj_t * pObjCo;
+ Pga_Node_t * pNode;
+ int Limit, MaxNameSize, i;
+
+ // determine the number of nodes to print
+ Limit = (Abc_NtkCoNum(pNtk) < PGA_CO_LIST_SIZE)? Abc_NtkCoNum(pNtk) : PGA_CO_LIST_SIZE;
+
+ // determine the order
+ Pga_MappingFindLatest( p, pSorted, Limit );
+
+ // determine max size of the node's name
+ MaxNameSize = 0;
+ for ( i = 0; i < Limit; i++ )
+ {
+ pObjCo = Abc_NtkCo( pNtk, pSorted[i] );
+ if ( MaxNameSize < (int)strlen( Abc_ObjName(pObjCo) ) )
+ MaxNameSize = strlen( Abc_ObjName(pObjCo) );
+ }
+
+ // print the latest outputs
+ for ( i = 0; i < Limit; i++ )
+ {
+ // get the i-th latest output
+ pObjCo = Abc_NtkCo( pNtk, pSorted[i] );
+ pNode = Pga_Node( p, pObjCo->Id );
+ // print out the best arrival time
+ printf( "Output %-*s : ", MaxNameSize + 3, Abc_ObjName(pObjCo) );
+ printf( "Delay = %8.2f ", (double)pNode->Match.Delay );
+ if ( Abc_ObjFaninC0(pObjCo) )
+ printf( "NEG" );
+ else
+ printf( "POS" );
+ printf( "\n" );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+