summaryrefslogtreecommitdiffstats
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/fpga/fpga.h2
-rw-r--r--src/map/fpga/fpgaCore.c41
-rw-r--r--src/map/fpga/fpgaCreate.c2
-rw-r--r--src/map/fpga/fpgaCutUtils.c103
-rw-r--r--src/map/fpga/fpgaInt.h17
-rw-r--r--src/map/fpga/fpgaMatch.c2
-rw-r--r--src/map/fpga/fpgaSwitch.c176
-rw-r--r--src/map/fpga/fpgaUtils.c37
-rw-r--r--src/map/fpga/module.make1
-rw-r--r--src/map/mapper/mapper.h2
-rw-r--r--src/map/mapper/mapperCore.c83
-rw-r--r--src/map/mapper/mapperCreate.c6
-rw-r--r--src/map/mapper/mapperInt.h8
-rw-r--r--src/map/mapper/mapperLib.c1
-rw-r--r--src/map/mapper/mapperMatch.c34
-rw-r--r--src/map/mapper/mapperRefs.c9
-rw-r--r--src/map/mapper/mapperSwitch.c243
-rw-r--r--src/map/mapper/module.make1
-rw-r--r--src/map/mio/mio.h1
-rw-r--r--src/map/mio/mioApi.c17
20 files changed, 581 insertions, 205 deletions
diff --git a/src/map/fpga/fpga.h b/src/map/fpga/fpga.h
index 9dad1670..19241a74 100644
--- a/src/map/fpga/fpga.h
+++ b/src/map/fpga/fpga.h
@@ -91,6 +91,7 @@ extern void Fpga_ManSetFanoutViolations( Fpga_Man_t * p, int nVio );
extern void Fpga_ManSetChoiceNodeNum( Fpga_Man_t * p, int nChoiceNodes );
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_ManSetLatchNum( Fpga_Man_t * p, int nLatches );
extern void Fpga_ManSetName( Fpga_Man_t * p, char * pFileName );
@@ -110,6 +111,7 @@ extern void Fpga_NodeSetData1( Fpga_Node_t * p, Fpga_Node_t * pNode )
extern void Fpga_NodeSetArrival( Fpga_Node_t * p, float Time );
extern void Fpga_NodeSetNextE( Fpga_Node_t * p, Fpga_Node_t * pNextE );
extern void Fpga_NodeSetRepr( Fpga_Node_t * p, Fpga_Node_t * pRepr );
+extern void Fpga_NodeSetSwitching( Fpga_Node_t * p, float Switching );
extern int Fpga_NodeIsConst( Fpga_Node_t * p );
extern int Fpga_NodeIsVar( Fpga_Node_t * p );
diff --git a/src/map/fpga/fpgaCore.c b/src/map/fpga/fpgaCore.c
index 0fc90228..95b9ca49 100644
--- a/src/map/fpga/fpgaCore.c
+++ b/src/map/fpga/fpgaCore.c
@@ -97,22 +97,26 @@ int Fpga_Mapping( Fpga_Man_t * p )
***********************************************************************/
int Fpga_MappingPostProcess( Fpga_Man_t * p )
{
- float aAreaTotalPrev, aAreaTotalCur, aAreaTotalCur2;
+ int fShowSwitching = 0;
+ int fRecoverAreaFlow = 1;
+ int fRecoverArea = 1;
+ float aAreaTotalCur, aAreaTotalCur2;
int Iter, clk;
// compute area, set references, and collect nodes used in the mapping
+ Iter = 1;
aAreaTotalCur = Fpga_MappingSetRefsAndArea( p );
if ( p->fVerbose )
{
-printf( "Iteration %dD : Area = %11.1f ", 0, aAreaTotalCur );
+printf( "Iteration %dD : Area = %8.1f ", Iter++, aAreaTotalCur );
+if ( fShowSwitching )
+printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) );
PRT( "Time", p->timeMatch );
}
- Iter = 1;
- do {
+ if ( fRecoverAreaFlow )
+ {
clk = clock();
- // save the previous area flow
- aAreaTotalPrev = aAreaTotalCur;
// compute the required times and the fanouts
Fpga_TimeComputeRequiredGlobal( p );
// remap topologically
@@ -124,33 +128,38 @@ clk = clock();
// for some reason, this works better on benchmarks
if ( p->fVerbose )
{
-printf( "Iteration %dF : Area = %11.1f ", Iter++, aAreaTotalCur );
+printf( "Iteration %dF : Area = %8.1f ", Iter++, aAreaTotalCur );
+if ( fShowSwitching )
+printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) );
PRT( "Time", clock() - clk );
}
- // quit if this iteration reduced area flow by less than 1%
- } while ( aAreaTotalPrev > 1.02 * aAreaTotalCur );
+ }
// update reference counters
aAreaTotalCur2 = Fpga_MappingSetRefsAndArea( p );
assert( aAreaTotalCur == aAreaTotalCur2 );
- do {
+ if ( fRecoverArea )
+ {
clk = clock();
- // save the previous area flow
- aAreaTotalPrev = aAreaTotalCur;
// compute the required times and the fanouts
Fpga_TimeComputeRequiredGlobal( p );
// remap topologically
- Fpga_MappingMatchesArea( p );
+ if ( p->fSwitching )
+ Fpga_MappingMatchesSwitch( p );
+ else
+ Fpga_MappingMatchesArea( p );
// get the resulting area
aAreaTotalCur = Fpga_MappingSetRefsAndArea( p );
if ( p->fVerbose )
{
-printf( "Iteration %dA : Area = %11.1f ", Iter++, aAreaTotalCur );
+printf( "Iteration %d%s : Area = %8.1f ", Iter++, (p->fSwitching?"S":"A"), aAreaTotalCur );
+if ( fShowSwitching )
+printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) );
PRT( "Time", clock() - clk );
}
- // quit if this iteration reduced area flow by less than 1%
- } while ( aAreaTotalPrev > 1.02 * aAreaTotalCur );
+ }
+
p->fAreaGlo = aAreaTotalCur;
return 1;
}
diff --git a/src/map/fpga/fpgaCreate.c b/src/map/fpga/fpgaCreate.c
index f3abbedb..b7bfa3c5 100644
--- a/src/map/fpga/fpgaCreate.c
+++ b/src/map/fpga/fpgaCreate.c
@@ -65,6 +65,7 @@ void Fpga_ManSetTimeLimit( Fpga_Man_t * p, float TimeLimit ) { p
void Fpga_ManSetChoiceNodeNum( Fpga_Man_t * p, int nChoiceNodes ) { p->nChoiceNodes = nChoiceNodes; }
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_ManSetLatchNum( Fpga_Man_t * p, int nLatches ) { p->nLatches = nLatches; }
void Fpga_ManSetName( Fpga_Man_t * p, char * pFileName ) { p->pFileName = pFileName; }
@@ -104,6 +105,7 @@ void Fpga_NodeSetData0( Fpga_Node_t * p, char * pData ) { p->
void Fpga_NodeSetData1( Fpga_Node_t * p, Fpga_Node_t * pNode ) { p->pLevel = pNode; }
void Fpga_NodeSetNextE( Fpga_Node_t * p, Fpga_Node_t * pNextE ) { p->pNextE = pNextE; }
void Fpga_NodeSetRepr( Fpga_Node_t * p, Fpga_Node_t * pRepr ) { p->pRepr = pRepr; }
+void Fpga_NodeSetSwitching( Fpga_Node_t * p, float Switching ) { p->Switching = Switching; }
/**Function*************************************************************
diff --git a/src/map/fpga/fpgaCutUtils.c b/src/map/fpga/fpgaCutUtils.c
index abe703a2..2419cac4 100644
--- a/src/map/fpga/fpgaCutUtils.c
+++ b/src/map/fpga/fpgaCutUtils.c
@@ -439,109 +439,6 @@ float Fpga_CutDeref( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut,
}
-
-/**function*************************************************************
-
- synopsis [Computes the exact area associated with the cut.]
-
- description []
-
- sideeffects []
-
- seealso []
-
-***********************************************************************/
-float Fpga_CutGetSwitchDerefed( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut )
-{
- float aResult, aResult2;
- if ( pCut->nLeaves == 1 )
- return 0;
- aResult2 = Fpga_CutRefSwitch( pMan, pNode, pCut, 0 );
- aResult = Fpga_CutDerefSwitch( pMan, pNode, pCut, 0 );
-// assert( aResult == aResult2 );
- return aResult;
-}
-
-/**function*************************************************************
-
- synopsis [References the cut.]
-
- description [This procedure is similar to the procedure NodeReclaim.]
-
- sideeffects []
-
- seealso []
-
-***********************************************************************/
-float Fpga_CutRefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts )
-{
- Fpga_Node_t * pNodeChild;
- float aArea;
- int i;
-
- // deref the fanouts
-// if ( fFanouts )
-// Fpga_CutInsertFanouts( pMan, pNode, pCut );
-
- // start the area of this cut
- aArea = pNode->SwitchProb;
- // go through the children
- for ( i = 0; i < pCut->nLeaves; i++ )
- {
- pNodeChild = pCut->ppLeaves[i];
- assert( pNodeChild->nRefs >= 0 );
- if ( pNodeChild->nRefs++ > 0 )
- continue;
- if ( !Fpga_NodeIsAnd(pNodeChild) )
- {
- aArea += pNodeChild->SwitchProb;
- continue;
- }
- aArea += Fpga_CutRefSwitch( pMan, pNodeChild, pNodeChild->pCutBest, fFanouts );
- }
- return aArea;
-}
-
-/**function*************************************************************
-
- synopsis [Dereferences the cut.]
-
- description [This procedure is similar to the procedure NodeRecusiveDeref.]
-
- sideeffects []
-
- seealso []
-
-***********************************************************************/
-float Fpga_CutDerefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts )
-{
- Fpga_Node_t * pNodeChild;
- float aArea;
- int i;
-
- // deref the fanouts
-// if ( fFanouts )
-// Fpga_CutRemoveFanouts( pMan, pNode, pCut );
-
- // start the area of this cut
- aArea = pNode->SwitchProb;
- // go through the children
- for ( i = 0; i < pCut->nLeaves; i++ )
- {
- pNodeChild = pCut->ppLeaves[i];
- assert( pNodeChild->nRefs > 0 );
- if ( --pNodeChild->nRefs > 0 )
- continue;
- if ( !Fpga_NodeIsAnd(pNodeChild) )
- {
- aArea += pNodeChild->SwitchProb;
- continue;
- }
- aArea += Fpga_CutDerefSwitch( pMan, pNodeChild, pNodeChild->pCutBest, fFanouts );
- }
- return aArea;
-}
-
/**Function*************************************************************
Synopsis [Sets the used cuts to be the currently selected ones.]
diff --git a/src/map/fpga/fpgaInt.h b/src/map/fpga/fpgaInt.h
index 95203378..ec6057a7 100644
--- a/src/map/fpga/fpgaInt.h
+++ b/src/map/fpga/fpgaInt.h
@@ -120,12 +120,9 @@ struct Fpga_ManStruct_t_
// mapping parameters
int nVarsMax; // the max number of variables
-// int fTree; // the flag to enable tree mapping
-// int fPower; // the flag to enable power optimization
int fAreaRecovery; // the flag to use area flow as the first parameter
int fVerbose; // the verbosiness flag
-// int fRefCount; // enables reference counting
-// int fSequential; // use sequential mapping
+ int fSwitching; // minimize the switching activity (instead of area)
int nTravIds;
// support of choice nodes
@@ -137,7 +134,6 @@ struct Fpga_ManStruct_t_
// the supergate library
Fpga_LutLib_t * pLutLib; // the current LUT library
-// unsigned uTruths[6][2]; // the elementary truth tables
// the memory managers
Extra_MmFixed_t * mmNodes; // the memory manager for nodes
@@ -215,7 +211,7 @@ struct Fpga_NodeStruct_t_
// the delay information
float tRequired; // the best area flow
float aEstFanouts; // the fanout estimation
- float SwitchProb; // the probability of switching
+ float Switching; // the probability of switching
int LValue; // the l-value of the node
short nLatches1; // the number of latches on the first edge
short nLatches2; // the number of latches on the second edge
@@ -308,9 +304,6 @@ extern float Fpga_CutGetAreaRefed( Fpga_Man_t * pMan, Fpga_Cut_t * p
extern float Fpga_CutGetAreaDerefed( Fpga_Man_t * pMan, Fpga_Cut_t * pCut );
extern float Fpga_CutRef( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts );
extern float Fpga_CutDeref( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts );
-extern float Fpga_CutGetSwitchDerefed( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut );
-extern float Fpga_CutRefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts );
-extern float Fpga_CutDerefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts );
extern float Fpga_CutGetAreaFlow( Fpga_Man_t * pMan, Fpga_Cut_t * pCut );
extern void Fpga_CutGetParameters( Fpga_Man_t * pMan, Fpga_Cut_t * pCut );
/*=== fraigFanout.c =============================================================*/
@@ -329,6 +322,11 @@ extern int Fpga_MappingMatchesSwitch( Fpga_Man_t * p );
/*=== fpgaShow.c =============================================================*/
extern void Fpga_MappingShow( Fpga_Man_t * pMan, char * pFileName );
extern void Fpga_MappingShowNodes( Fpga_Man_t * pMan, Fpga_Node_t ** ppRoots, int nRoots, char * pFileName );
+/*=== fpgaSwitch.c =============================================================*/
+extern float Fpga_CutGetSwitchDerefed( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut );
+extern float Fpga_CutRefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts );
+extern float Fpga_CutDerefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts );
+extern float Fpga_MappingGetSwitching( Fpga_Man_t * pMan, Fpga_NodeVec_t * vMapping );
/*=== fpgaTime.c ===============================================================*/
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 );
@@ -370,7 +368,6 @@ extern void Fpga_MappingSetupMask( unsigned uMask[], int nVarsMax )
extern void Fpga_MappingSortByLevel( Fpga_Man_t * pMan, Fpga_NodeVec_t * vNodes, int fIncreasing );
extern Fpga_NodeVec_t * Fpga_DfsLim( Fpga_Man_t * pMan, Fpga_Node_t * pNode, int nLevels );
extern Fpga_NodeVec_t * Fpga_MappingLevelize( Fpga_Man_t * pMan, Fpga_NodeVec_t * vNodes );
-extern float Fpga_MappingPrintSwitching( Fpga_Man_t * pMan );
extern int Fpga_MappingMaxLevel( Fpga_Man_t * pMan );
extern void Fpga_ManReportChoices( Fpga_Man_t * pMan );
extern void Fpga_MappingSetChoiceLevels( Fpga_Man_t * pMan );
diff --git a/src/map/fpga/fpgaMatch.c b/src/map/fpga/fpgaMatch.c
index 63ee682d..20444209 100644
--- a/src/map/fpga/fpgaMatch.c
+++ b/src/map/fpga/fpgaMatch.c
@@ -432,7 +432,7 @@ clk = clock();
if ( pNode->nRefs )
{
pNode->pCutBest->aFlow = Fpga_CutRefSwitch( p, pNode, pNode->pCutBest, 0 );
- assert( pNode->pCutBest->aFlow <= aAreaCutBest );
+ assert( pNode->pCutBest->aFlow <= aAreaCutBest + 0.001 );
// assert( pNode->tRequired < FPGA_FLOAT_LARGE );
}
return 1;
diff --git a/src/map/fpga/fpgaSwitch.c b/src/map/fpga/fpgaSwitch.c
new file mode 100644
index 00000000..0d2ec3fc
--- /dev/null
+++ b/src/map/fpga/fpgaSwitch.c
@@ -0,0 +1,176 @@
+/**CFile****************************************************************
+
+ FileName [fpgaSwitch.c]
+
+ PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
+
+ Synopsis [Generic technology mapping engine.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 8, 2003.]
+
+ Revision [$Id: fpgaSwitch.h,v 1.0 2003/09/08 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "fpgaInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static float Fpga_CutGetSwitching( Fpga_Cut_t * pCut );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**function*************************************************************
+
+ synopsis [Computes the exact area associated with the cut.]
+
+ description []
+
+ sideeffects []
+
+ seealso []
+
+***********************************************************************/
+float Fpga_CutGetSwitchDerefed( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut )
+{
+ float aResult, aResult2;
+ aResult2 = Fpga_CutRefSwitch( pMan, pNode, pCut, 0 );
+ aResult = Fpga_CutDerefSwitch( pMan, pNode, pCut, 0 );
+// assert( aResult == aResult2 );
+ return aResult;
+}
+
+/**function*************************************************************
+
+ synopsis [References the cut.]
+
+ description [This procedure is similar to the procedure NodeReclaim.]
+
+ sideeffects []
+
+ seealso []
+
+***********************************************************************/
+float Fpga_CutRefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts )
+{
+ Fpga_Node_t * pNodeChild;
+ float aArea;
+ int i;
+ if ( pCut->nLeaves == 1 )
+ return 0;
+ // start the area of this cut
+ aArea = Fpga_CutGetSwitching( pCut );
+ // go through the children
+ for ( i = 0; i < pCut->nLeaves; i++ )
+ {
+ pNodeChild = pCut->ppLeaves[i];
+ assert( pNodeChild->nRefs >= 0 );
+ if ( pNodeChild->nRefs++ > 0 )
+ continue;
+ aArea += Fpga_CutRefSwitch( pMan, pNodeChild, pNodeChild->pCutBest, fFanouts );
+ }
+ return aArea;
+}
+
+/**function*************************************************************
+
+ synopsis [Dereferences the cut.]
+
+ description [This procedure is similar to the procedure NodeRecusiveDeref.]
+
+ sideeffects []
+
+ seealso []
+
+***********************************************************************/
+float Fpga_CutDerefSwitch( Fpga_Man_t * pMan, Fpga_Node_t * pNode, Fpga_Cut_t * pCut, int fFanouts )
+{
+ Fpga_Node_t * pNodeChild;
+ float aArea;
+ int i;
+ if ( pCut->nLeaves == 1 )
+ return 0;
+ // start the area of this cut
+ aArea = Fpga_CutGetSwitching( pCut );
+ // go through the children
+ for ( i = 0; i < pCut->nLeaves; i++ )
+ {
+ pNodeChild = pCut->ppLeaves[i];
+ assert( pNodeChild->nRefs > 0 );
+ if ( --pNodeChild->nRefs > 0 )
+ continue;
+ aArea += Fpga_CutDerefSwitch( pMan, pNodeChild, pNodeChild->pCutBest, fFanouts );
+ }
+ return aArea;
+}
+
+/**function*************************************************************
+
+ synopsis [Computes the exact area associated with the cut.]
+
+ description []
+
+ sideeffects []
+
+ seealso []
+
+***********************************************************************/
+float Fpga_CutGetSwitching( Fpga_Cut_t * pCut )
+{
+ float Result;
+ int i;
+ Result = 0.0;
+ for ( i = 0; i < pCut->nLeaves; i++ )
+ Result += pCut->ppLeaves[i]->Switching;
+ return Result;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the array of mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Fpga_MappingGetSwitching( Fpga_Man_t * pMan, Fpga_NodeVec_t * vMapping )
+{
+ Fpga_Node_t * pNode;
+ float Switch;
+ int i;
+ Switch = 0.0;
+ for ( i = 0; i < vMapping->nSize; i++ )
+ {
+ pNode = vMapping->pArray[i];
+ if ( !Fpga_NodeIsAnd(pNode) )
+ continue;
+ // at least one phase has the best cut assigned
+ assert( pNode->pCutBest != NULL );
+ // at least one phase is used in the mapping
+ assert( pNode->nRefs > 0 );
+ // compute the array due to the supergate
+ Switch += pNode->Switching;
+ }
+ // 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;
+ return Switch;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/map/fpga/fpgaUtils.c b/src/map/fpga/fpgaUtils.c
index 89ef13dc..3ea1f2f1 100644
--- a/src/map/fpga/fpgaUtils.c
+++ b/src/map/fpga/fpgaUtils.c
@@ -779,43 +779,6 @@ Fpga_NodeVec_t * Fpga_MappingLevelize( Fpga_Man_t * pMan, Fpga_NodeVec_t * vNode
}
return vLevels;
}
-/**Function*************************************************************
-
- Synopsis [Prints the switching activity changes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-float Fpga_MappingPrintSwitching( Fpga_Man_t * p )
-{
- Fpga_Node_t * pNode;
- float SwitchTotal = 0.0;
- int nNodes = 0;
- int i;
- for ( i = 0; i < p->vNodesAll->nSize; i++ )
- {
- // skip primary inputs
- pNode = p->vNodesAll->pArray[i];
-// if ( !Fpga_NodeIsAnd( pNode ) )
-// continue;
- // skip a secondary node
- if ( pNode->pRepr )
- continue;
- // count the switching nodes
- if ( pNode->nRefs > 0 )
- {
- SwitchTotal += pNode->SwitchProb;
- nNodes++;
- }
- }
- if ( p->fVerbose )
- printf( "Total switching = %10.2f. Average switching = %6.4f.\n", SwitchTotal, SwitchTotal/nNodes );
- return SwitchTotal;
-}
/**Function*************************************************************
diff --git a/src/map/fpga/module.make b/src/map/fpga/module.make
index 409e4b54..cc3a6573 100644
--- a/src/map/fpga/module.make
+++ b/src/map/fpga/module.make
@@ -6,6 +6,7 @@ SRC += src/map/fpga/fpga.c \
src/map/fpga/fpgaFanout.c \
src/map/fpga/fpgaLib.c \
src/map/fpga/fpgaMatch.c \
+ src/map/fpga/fpgaSwitch.c \
src/map/fpga/fpgaTime.c \
src/map/fpga/fpgaTruth.c \
src/map/fpga/fpgaUtils.c \
diff --git a/src/map/mapper/mapper.h b/src/map/mapper/mapper.h
index 1322cdfa..c3f1ce81 100644
--- a/src/map/mapper/mapper.h
+++ b/src/map/mapper/mapper.h
@@ -101,6 +101,7 @@ extern void Map_ManSetFanoutViolations( Map_Man_t * p, int nVio );
extern void Map_ManSetChoiceNodeNum( Map_Man_t * p, int nChoiceNodes );
extern void Map_ManSetChoiceNum( Map_Man_t * p, int nChoices );
extern void Map_ManSetVerbose( Map_Man_t * p, int fVerbose );
+extern void Map_ManSetSwitching( Map_Man_t * p, int fSwitching );
extern Map_Man_t * Map_NodeReadMan( Map_Node_t * p );
extern char * Map_NodeReadData( Map_Node_t * p, int fPhase );
@@ -113,6 +114,7 @@ extern Map_Node_t * Map_NodeReadTwo( Map_Node_t * p );
extern void Map_NodeSetData( Map_Node_t * p, int fPhase, char * pData );
extern void Map_NodeSetNextE( Map_Node_t * p, Map_Node_t * pNextE );
extern void Map_NodeSetRepr( Map_Node_t * p, Map_Node_t * pRepr );
+extern void Map_NodeSetSwitching( Map_Node_t * p, float Switching );
extern int Map_NodeIsConst( Map_Node_t * p );
extern int Map_NodeIsVar( Map_Node_t * p );
diff --git a/src/map/mapper/mapperCore.c b/src/map/mapper/mapperCore.c
index 16cbfd5c..629ba59d 100644
--- a/src/map/mapper/mapperCore.c
+++ b/src/map/mapper/mapperCore.c
@@ -46,9 +46,10 @@
***********************************************************************/
int Map_Mapping( Map_Man_t * p )
{
+ int fShowSwitching = 0;
int fUseAreaFlow = 1;
- int fUseExactArea = 1;
- int fUseExactAreaWithPhase = 1;
+ int fUseExactArea = !p->fSwitching;
+ int fUseExactAreaWithPhase = !p->fSwitching;
int clk;
//////////////////////////////////////////////////////////////////////
@@ -83,8 +84,10 @@ int Map_Mapping( Map_Man_t * p )
p->AreaBase = Map_MappingGetArea( p, p->vMapping );
if ( p->fVerbose )
{
-printf( "Delay : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
- p->fRequiredGlo, Map_MappingGetAreaFlow(p), p->AreaBase, 0.0 );
+printf( "Delay : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
+ fShowSwitching? "Switch" : "Delay",
+ fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
+ Map_MappingGetAreaFlow(p), p->AreaBase, 0.0 );
PRT( "Time", p->timeMatch );
}
//////////////////////////////////////////////////////////////////////
@@ -97,7 +100,7 @@ PRT( "Time", p->timeMatch );
clk = clock();
if ( fUseAreaFlow )
{
- // compute the required times and the fanouts
+ // compute the required times
Map_TimeComputeRequiredGlobal( p );
// recover area flow
p->fMappingMode = 1;
@@ -107,8 +110,10 @@ PRT( "Time", p->timeMatch );
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
if ( p->fVerbose )
{
-printf( "AreaFlow : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
- p->fRequiredGlo, Map_MappingGetAreaFlow(p), p->AreaFinal,
+printf( "AreaFlow : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
+ fShowSwitching? "Switch" : "Delay",
+ fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
+ Map_MappingGetAreaFlow(p), p->AreaFinal,
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
PRT( "Time", clock() - clk );
}
@@ -121,9 +126,9 @@ PRT( "Time", clock() - clk );
clk = clock();
if ( fUseExactArea )
{
- // compute the required times and the fanouts
+ // compute the required times
Map_TimeComputeRequiredGlobal( p );
- // recover area flow
+ // recover area
p->fMappingMode = 2;
Map_MappingMatches( p );
// compute the references and collect the nodes used in the mapping
@@ -131,8 +136,10 @@ PRT( "Time", clock() - clk );
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
if ( p->fVerbose )
{
-printf( "Area : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
- p->fRequiredGlo, 0.0, p->AreaFinal,
+printf( "Area : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
+ fShowSwitching? "Switch" : "Delay",
+ fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
+ 0.0, p->AreaFinal,
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
PRT( "Time", clock() - clk );
}
@@ -145,9 +152,9 @@ PRT( "Time", clock() - clk );
clk = clock();
if ( fUseExactAreaWithPhase )
{
- // compute the required times and the fanouts
+ // compute the required times
Map_TimeComputeRequiredGlobal( p );
- // recover area flow
+ // recover area
p->fMappingMode = 3;
Map_MappingMatches( p );
// compute the references and collect the nodes used in the mapping
@@ -155,8 +162,54 @@ PRT( "Time", clock() - clk );
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
if ( p->fVerbose )
{
-printf( "Area : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
- p->fRequiredGlo, 0.0, p->AreaFinal,
+printf( "Area : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
+ fShowSwitching? "Switch" : "Delay",
+ fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
+ 0.0, p->AreaFinal,
+ 100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
+PRT( "Time", clock() - clk );
+}
+ }
+ p->timeArea += clock() - clk;
+ //////////////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ // perform area recovery using exact area
+ clk = clock();
+ if ( p->fSwitching )
+ {
+ // compute the required times
+ Map_TimeComputeRequiredGlobal( p );
+ // recover switching activity
+ p->fMappingMode = 4;
+ Map_MappingMatches( p );
+ // compute the references and collect the nodes used in the mapping
+ Map_MappingSetRefs( p );
+ p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
+if ( p->fVerbose )
+{
+printf( "Switching: %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
+ fShowSwitching? "Switch" : "Delay",
+ fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
+ 0.0, p->AreaFinal,
+ 100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
+PRT( "Time", clock() - clk );
+}
+
+ // compute the required times
+ Map_TimeComputeRequiredGlobal( p );
+ // recover switching activity
+ p->fMappingMode = 4;
+ Map_MappingMatches( p );
+ // compute the references and collect the nodes used in the mapping
+ Map_MappingSetRefs( p );
+ p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
+if ( p->fVerbose )
+{
+printf( "Switching: %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
+ fShowSwitching? "Switch" : "Delay",
+ fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
+ 0.0, p->AreaFinal,
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
PRT( "Time", clock() - clk );
}
diff --git a/src/map/mapper/mapperCreate.c b/src/map/mapper/mapperCreate.c
index 738d099c..31fbf0ea 100644
--- a/src/map/mapper/mapperCreate.c
+++ b/src/map/mapper/mapperCreate.c
@@ -69,6 +69,7 @@ void Map_ManSetFanoutViolations( Map_Man_t * p, int nVio ) { p->nFa
void Map_ManSetChoiceNodeNum( Map_Man_t * p, int nChoiceNodes ) { p->nChoiceNodes = nChoiceNodes; }
void Map_ManSetChoiceNum( Map_Man_t * p, int nChoices ) { p->nChoices = nChoices; }
void Map_ManSetVerbose( Map_Man_t * p, int fVerbose ) { p->fVerbose = fVerbose; }
+void Map_ManSetSwitching( Map_Man_t * p, int fSwitching ) { p->fSwitching = fSwitching; }
/**Function*************************************************************
@@ -90,8 +91,9 @@ Map_Cut_t * Map_NodeReadCutBest( Map_Node_t * p, int fPhase ) { return p
Map_Node_t * Map_NodeReadOne( Map_Node_t * p ) { return p->p1; }
Map_Node_t * Map_NodeReadTwo( Map_Node_t * p ) { return p->p2; }
void Map_NodeSetData( Map_Node_t * p, int fPhase, char * pData ) { if (fPhase) p->pData1 = pData; else p->pData0 = pData; }
-void Map_NodeSetNextE( Map_Node_t * p, Map_Node_t * pNextE ) { p->pNextE = pNextE; }
-void Map_NodeSetRepr( Map_Node_t * p, Map_Node_t * pRepr ) { p->pRepr = pRepr; }
+void Map_NodeSetNextE( Map_Node_t * p, Map_Node_t * pNextE ) { p->pNextE = pNextE; }
+void Map_NodeSetRepr( Map_Node_t * p, Map_Node_t * pRepr ) { p->pRepr = pRepr; }
+void Map_NodeSetSwitching( Map_Node_t * p, float Switching ) { p->Switching = Switching; }
/**Function*************************************************************
diff --git a/src/map/mapper/mapperInt.h b/src/map/mapper/mapperInt.h
index 7d63a804..0acca56c 100644
--- a/src/map/mapper/mapperInt.h
+++ b/src/map/mapper/mapperInt.h
@@ -117,6 +117,7 @@ struct Map_ManStruct_t_
bool fObeyFanoutLimits;// Should mapper try to obey fanout limits or not
float DelayTarget; // the required times set by the user
int nTravIds; // the traversal counter
+ bool fSwitching; // Should mapper try to obey fanout limits or not
// the supergate library
Map_SuperLib_t * pSuperLib; // the current supergate library
@@ -184,6 +185,7 @@ struct Map_SuperLibStruct_t_
Mio_Gate_t * pGateInv; // the pointer to the intertor gate
Map_Time_t tDelayInv; // the delay of the inverter
float AreaInv; // the area of the inverter
+ float AreaBuf; // the area of the buffer
Map_Super_t * pSuperInv; // the supergate representing the inverter
// the memory manager for the internal table
@@ -210,6 +212,7 @@ struct Map_NodeStruct_t_
unsigned NumTemp:10; // the level of the given node
int nRefAct[3]; // estimated fanout for current covering phase, neg and pos and sum
float nRefEst[3]; // actual fanout for previous covering phase, neg and pos and sum
+ float Switching; // the probability of switching
// connectivity
Map_Node_t * p1; // the first child
@@ -378,6 +381,11 @@ extern int Map_MappingMatches( Map_Man_t * p );
extern float Map_MappingCombinePhases( Map_Man_t * p );
extern void Map_MatchClean( Map_Match_t * pMatch );
extern int Map_MatchCompare( Map_Man_t * pMan, Map_Match_t * pM1, Map_Match_t * pM2, int fDoingArea );
+/*=== mapperPower.c =============================================================*/
+extern float Map_SwitchCutGetDerefed( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase );
+extern float Map_SwitchCutRef( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase );
+extern float Map_SwitchCutDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase );
+extern float Map_MappingGetSwitching( Map_Man_t * pMan, Map_NodeVec_t * vMapping );
/*=== mapperRefs.c =============================================================*/
extern int Map_NodeReadRefPhaseAct( Map_Node_t * pNode, int fPhase );
extern float Map_NodeReadRefPhaseEst( Map_Node_t * pNode, int fPhase );
diff --git a/src/map/mapper/mapperLib.c b/src/map/mapper/mapperLib.c
index f9b280fe..5fea1f00 100644
--- a/src/map/mapper/mapperLib.c
+++ b/src/map/mapper/mapperLib.c
@@ -102,6 +102,7 @@ if ( fVerbose ) {
p->tDelayInv.Fall = Mio_LibraryReadDelayInvFall( p->pGenlib );
p->tDelayInv.Worst = MAP_MAX( p->tDelayInv.Rise, p->tDelayInv.Fall );
p->AreaInv = Mio_LibraryReadAreaInv( p->pGenlib );
+ p->AreaBuf = Mio_LibraryReadAreaBuf( p->pGenlib );
// assign the interver supergate
p->pSuperInv = (Map_Super_t *)Extra_MmFixedEntryFetch( p->mmSupers );
diff --git a/src/map/mapper/mapperMatch.c b/src/map/mapper/mapperMatch.c
index 5b72311c..ddb9ebb7 100644
--- a/src/map/mapper/mapperMatch.c
+++ b/src/map/mapper/mapperMatch.c
@@ -65,7 +65,7 @@ int Map_MappingMatches( Map_Man_t * p )
Map_Node_t * pNode;
int i;
- assert( p->fMappingMode >= 0 && p->fMappingMode <= 3 );
+ assert( p->fMappingMode >= 0 && p->fMappingMode <= 4 );
// use the externally given PI arrival times
if ( p->fMappingMode == 0 )
@@ -158,7 +158,7 @@ int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase )
// recompute the exact area of the current best match
// because the exact area of the fanins may have changed
// as a result of remapping fanins in the topological order
- if ( p->fMappingMode >= 2 )
+ if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
{
pMatch = pCutBest->M + fPhase;
if ( pNode->nRefAct[fPhase] > 0 ||
@@ -167,6 +167,15 @@ int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase )
else
pMatch->AreaFlow = Area1 = Map_CutGetAreaDerefed( pCutBest, fPhase );
}
+ else if ( p->fMappingMode == 4 )
+ {
+ pMatch = pCutBest->M + fPhase;
+ if ( pNode->nRefAct[fPhase] > 0 ||
+ (pNode->pCutBest[!fPhase] == NULL && pNode->nRefAct[!fPhase] > 0) )
+ pMatch->AreaFlow = Area1 = Map_SwitchCutDeref( pNode, pCutBest, fPhase );
+ else
+ pMatch->AreaFlow = Area1 = Map_SwitchCutGetDerefed( pNode, pCutBest, fPhase );
+ }
// save the old mapping
if ( pCutBest )
@@ -210,7 +219,12 @@ int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase )
(pNode->nRefAct[fPhase] > 0 ||
(pNode->pCutBest[!fPhase] == NULL && pNode->nRefAct[!fPhase] > 0)) )
{
- Area2 = Map_CutRef( pNode->pCutBest[fPhase], fPhase );
+ if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
+ Area2 = Map_CutRef( pNode->pCutBest[fPhase], fPhase );
+ else if ( p->fMappingMode == 4 )
+ Area2 = Map_SwitchCutRef( pNode, pNode->pCutBest[fPhase], fPhase );
+ else
+ assert( 0 );
assert( Area2 < Area1 + p->fEpsilon );
}
@@ -273,9 +287,11 @@ int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int f
else
{
// get the area (area flow)
- if ( p->fMappingMode >= 2 )
+ if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
pMatch->AreaFlow = Map_CutGetAreaDerefed( pCut, fPhase );
- else
+ else if ( p->fMappingMode == 4 )
+ pMatch->AreaFlow = Map_SwitchCutGetDerefed( pNode, pCut, fPhase );
+ else
pMatch->AreaFlow = Map_CutGetAreaFlow( pCut, fPhase );
// skip if the cut is too large
if ( pMatch->AreaFlow > MatchBest.AreaFlow + p->fEpsilon )
@@ -304,9 +320,11 @@ int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int f
if ( pMatch->pSuperBest )
{
Map_TimeCutComputeArrival( pNode, pCut, fPhase, MAP_FLOAT_LARGE );
- if ( p->fMappingMode >= 2 )
+ if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
pMatch->AreaFlow = Map_CutGetAreaDerefed( pCut, fPhase );
- else
+ else if ( p->fMappingMode == 4 )
+ pMatch->AreaFlow = Map_SwitchCutGetDerefed( pNode, pCut, fPhase );
+ else
pMatch->AreaFlow = Map_CutGetAreaFlow( pCut, fPhase );
}
return 1;
@@ -482,7 +500,7 @@ void Map_NodeTryDroppingOnePhase( Map_Man_t * p, Map_Node_t * pNode )
fUsePhase0 = (pNode->tRequired[1].Worst > tWorst1Using0 + 3*p->pSuperLib->tDelayInv.Worst + p->fEpsilon);
fUsePhase1 = (pNode->tRequired[0].Worst > tWorst0Using1 + 3*p->pSuperLib->tDelayInv.Worst + p->fEpsilon);
}
- else if ( p->fMappingMode == 3 )
+ else if ( p->fMappingMode == 3 || p->fMappingMode == 4 )
{
fUsePhase0 = (pNode->tRequired[1].Worst > tWorst1Using0 + p->fEpsilon);
fUsePhase1 = (pNode->tRequired[0].Worst > tWorst0Using1 + p->fEpsilon);
diff --git a/src/map/mapper/mapperRefs.c b/src/map/mapper/mapperRefs.c
index e74bab9a..e4adadae 100644
--- a/src/map/mapper/mapperRefs.c
+++ b/src/map/mapper/mapperRefs.c
@@ -279,7 +279,7 @@ float Map_CutRef( Map_Cut_t * pCut, int fPhase )
/**function*************************************************************
- synopsis [References the cut.]
+ synopsis [Dereferences the cut.]
description []
@@ -298,8 +298,7 @@ float Map_CutDeref( Map_Cut_t * pCut, int fPhase )
synopsis [References or dereferences the cut.]
description [This reference part is similar to Cudd_NodeReclaim().
- The dereference part is similar to Cudd_RecursiveDeref(). The
- area of the inverter is not counted.]
+ The dereference part is similar to Cudd_RecursiveDeref().]
sideeffects []
@@ -543,10 +542,10 @@ float Map_MappingGetArea( Map_Man_t * pMan, Map_NodeVec_t * vMapping )
(pNode->pCutBest[1] == NULL && pNode->nRefAct[1] > 0) )
Area += pMan->pSuperLib->AreaInv;
}
- // add two inverters for each PO buffer
+ // add buffer for each CO driven by a CI
for ( i = 0; i < pMan->nOutputs; i++ )
if ( Map_NodeIsVar(pMan->pOutputs[i]) && !Map_IsComplement(pMan->pOutputs[i]) )
- Area += 2 * pMan->pSuperLib->AreaInv;
+ Area += pMan->pSuperLib->AreaBuf;
return Area;
}
diff --git a/src/map/mapper/mapperSwitch.c b/src/map/mapper/mapperSwitch.c
new file mode 100644
index 00000000..02f38396
--- /dev/null
+++ b/src/map/mapper/mapperSwitch.c
@@ -0,0 +1,243 @@
+/**CFile****************************************************************
+
+ FileName [mapperSwitch.c]
+
+ PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
+
+ Synopsis [Generic technology mapping engine.]
+
+ Author [MVSIS Group]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 8, 2003.]
+
+ Revision [$Id: mapperSwitch.h,v 1.0 2003/09/08 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "mapperInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static float Map_SwitchCutRefDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, int fReference );
+static float Map_CutGetSwitching( Map_Cut_t * pCut );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**function*************************************************************
+
+ synopsis [Computes the exact area associated with the cut.]
+
+ description []
+
+ sideeffects []
+
+ seealso []
+
+***********************************************************************/
+float Map_SwitchCutGetDerefed( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase )
+{
+ float aResult, aResult2;
+// assert( pNode->Switching > 0 );
+ aResult2 = Map_SwitchCutRefDeref( pNode, pCut, fPhase, 1 ); // reference
+ aResult = Map_SwitchCutRefDeref( pNode, pCut, fPhase, 0 ); // dereference
+// assert( aResult == aResult2 );
+ return aResult;
+}
+
+/**function*************************************************************
+
+ synopsis [References the cut.]
+
+ description []
+
+ sideeffects []
+
+ seealso []
+
+***********************************************************************/
+float Map_SwitchCutRef( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase )
+{
+ return Map_SwitchCutRefDeref( pNode, pCut, fPhase, 1 ); // reference
+}
+
+/**function*************************************************************
+
+ synopsis [References the cut.]
+
+ description []
+
+ sideeffects []
+
+ seealso []
+
+***********************************************************************/
+float Map_SwitchCutDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase )
+{
+ return Map_SwitchCutRefDeref( pNode, pCut, fPhase, 0 ); // dereference
+}
+
+/**function*************************************************************
+
+ synopsis [References or dereferences the cut.]
+
+ description [This reference part is similar to Cudd_NodeReclaim().
+ The dereference part is similar to Cudd_RecursiveDeref().]
+
+ sideeffects []
+
+ seealso []
+
+***********************************************************************/
+float Map_SwitchCutRefDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, int fReference )
+{
+ Map_Node_t * pNodeChild;
+ Map_Cut_t * pCutChild;
+ float aSwitchActivity;
+ int i, fPhaseChild;
+ // consider the elementary variable
+ if ( pCut->nLeaves == 1 )
+ return 0;
+ // start the area of this cut
+ aSwitchActivity = Map_CutGetSwitching( pCut );
+ // go through the children
+ assert( pCut->M[fPhase].pSuperBest );
+ for ( i = 0; i < pCut->nLeaves; i++ )
+ {
+ pNodeChild = pCut->ppLeaves[i];
+ fPhaseChild = Map_CutGetLeafPhase( pCut, fPhase, i );
+ // get the reference counter of the child
+
+ if ( fReference )
+ {
+ if ( pNodeChild->pCutBest[0] && pNodeChild->pCutBest[1] ) // both phases are present
+ {
+ // if this phase of the node is referenced, there is no recursive call
+ pNodeChild->nRefAct[2]++;
+ if ( pNodeChild->nRefAct[fPhaseChild]++ > 0 )
+ continue;
+ }
+ else // only one phase is present
+ {
+ // inverter should be added if the phase
+ // (a) has no reference and (b) is implemented using other phase
+ if ( pNodeChild->nRefAct[fPhaseChild]++ == 0 && pNodeChild->pCutBest[fPhaseChild] == NULL )
+ aSwitchActivity += pNodeChild->Switching;
+ // if the node is referenced, there is no recursive call
+ if ( pNodeChild->nRefAct[2]++ > 0 )
+ continue;
+ }
+ }
+ else
+ {
+ if ( pNodeChild->pCutBest[0] && pNodeChild->pCutBest[1] ) // both phases are present
+ {
+ // if this phase of the node is referenced, there is no recursive call
+ --pNodeChild->nRefAct[2];
+ if ( --pNodeChild->nRefAct[fPhaseChild] > 0 )
+ continue;
+ }
+ else // only one phase is present
+ {
+ // inverter should be added if the phase
+ // (a) has no reference and (b) is implemented using other phase
+ if ( --pNodeChild->nRefAct[fPhaseChild] == 0 && pNodeChild->pCutBest[fPhaseChild] == NULL )
+ aSwitchActivity += pNodeChild->Switching;
+ // if the node is referenced, there is no recursive call
+ if ( --pNodeChild->nRefAct[2] > 0 )
+ continue;
+ }
+ assert( pNodeChild->nRefAct[fPhaseChild] >= 0 );
+ }
+
+ // get the child cut
+ pCutChild = pNodeChild->pCutBest[fPhaseChild];
+ // if the child does not have this phase mapped, take the opposite phase
+ if ( pCutChild == NULL )
+ {
+ fPhaseChild = !fPhaseChild;
+ pCutChild = pNodeChild->pCutBest[fPhaseChild];
+ }
+ // reference and compute area recursively
+ aSwitchActivity += Map_SwitchCutRefDeref( pNodeChild, pCutChild, fPhaseChild, fReference );
+ }
+ return aSwitchActivity;
+}
+
+/**function*************************************************************
+
+ synopsis [Computes the exact area associated with the cut.]
+
+ description []
+
+ sideeffects []
+
+ seealso []
+
+***********************************************************************/
+float Map_CutGetSwitching( Map_Cut_t * pCut )
+{
+ float Result;
+ int i;
+ Result = 0.0;
+ for ( i = 0; i < pCut->nLeaves; i++ )
+ Result += pCut->ppLeaves[i]->Switching;
+ return Result;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the array of mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Map_MappingGetSwitching( Map_Man_t * pMan, Map_NodeVec_t * vMapping )
+{
+ Map_Node_t * pNode;
+ float Switch;
+ int i;
+ Switch = 0.0;
+ for ( i = 0; i < vMapping->nSize; i++ )
+ {
+ pNode = vMapping->pArray[i];
+ // at least one phase has the best cut assigned
+ assert( pNode->pCutBest[0] != NULL || pNode->pCutBest[1] != NULL );
+ // at least one phase is used in the mapping
+ assert( pNode->nRefAct[0] > 0 || pNode->nRefAct[1] > 0 );
+ // compute the array due to the supergate
+ if ( Map_NodeIsAnd(pNode) )
+ {
+ // count switching of the negative phase
+ if ( pNode->pCutBest[0] && (pNode->nRefAct[0] > 0 || pNode->pCutBest[1] == NULL) )
+ Switch += pNode->Switching;
+ // count switching of the positive phase
+ if ( pNode->pCutBest[1] && (pNode->nRefAct[1] > 0 || pNode->pCutBest[0] == NULL) )
+ Switch += pNode->Switching;
+ }
+ // count switching of the interver if we need to implement one phase with another phase
+ if ( (pNode->pCutBest[0] == NULL && pNode->nRefAct[0] > 0) ||
+ (pNode->pCutBest[1] == NULL && pNode->nRefAct[1] > 0) )
+ Switch += pNode->Switching;
+ }
+ // add buffer for each CO driven by a CI
+ for ( i = 0; i < pMan->nOutputs; i++ )
+ if ( Map_NodeIsVar(pMan->pOutputs[i]) && !Map_IsComplement(pMan->pOutputs[i]) )
+ Switch += pMan->pOutputs[i]->Switching;
+ return Switch;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/map/mapper/module.make b/src/map/mapper/module.make
index 1d3b8867..bd6447d8 100644
--- a/src/map/mapper/module.make
+++ b/src/map/mapper/module.make
@@ -9,6 +9,7 @@ SRC += src/map/mapper/mapper.c \
src/map/mapper/mapperMatch.c \
src/map/mapper/mapperRefs.c \
src/map/mapper/mapperSuper.c \
+ src/map/mapper/mapperSwitch.c \
src/map/mapper/mapperTable.c \
src/map/mapper/mapperTime.c \
src/map/mapper/mapperTree.c \
diff --git a/src/map/mio/mio.h b/src/map/mio/mio.h
index 3347bba8..f9f4973d 100644
--- a/src/map/mio/mio.h
+++ b/src/map/mio/mio.h
@@ -90,6 +90,7 @@ extern float Mio_LibraryReadDelayNand2Rise( Mio_Library_t * pLib );
extern float Mio_LibraryReadDelayNand2Fall( Mio_Library_t * pLib );
extern float Mio_LibraryReadDelayNand2Max( Mio_Library_t * pLib );
extern float Mio_LibraryReadAreaInv ( Mio_Library_t * pLib );
+extern float Mio_LibraryReadAreaBuf ( Mio_Library_t * pLib );
extern float Mio_LibraryReadAreaNand2 ( Mio_Library_t * pLib );
extern char * Mio_GateReadName ( Mio_Gate_t * pGate );
extern char * Mio_GateReadOutName ( Mio_Gate_t * pGate );
diff --git a/src/map/mio/mioApi.c b/src/map/mio/mioApi.c
index 50d60fe9..a39c6288 100644
--- a/src/map/mio/mioApi.c
+++ b/src/map/mio/mioApi.c
@@ -46,14 +46,15 @@ Mio_Gate_t * Mio_LibraryReadInv ( Mio_Library_t * pLib ) { retur
Mio_Gate_t * Mio_LibraryReadConst0 ( Mio_Library_t * pLib ) { return pLib->pGate0; }
Mio_Gate_t * Mio_LibraryReadConst1 ( Mio_Library_t * pLib ) { return pLib->pGate1; }
Mio_Gate_t * Mio_LibraryReadNand2 ( Mio_Library_t * pLib ) { return pLib->pGateNand2; }
-float Mio_LibraryReadDelayInvRise ( Mio_Library_t * pLib ) { return (float)pLib->pGateInv->pPins->dDelayBlockRise; }
-float Mio_LibraryReadDelayInvFall ( Mio_Library_t * pLib ) { return (float)pLib->pGateInv->pPins->dDelayBlockFall; }
-float Mio_LibraryReadDelayInvMax ( Mio_Library_t * pLib ) { return (float)pLib->pGateInv->pPins->dDelayBlockMax; }
-float Mio_LibraryReadDelayNand2Rise( Mio_Library_t * pLib ) { return (float)pLib->pGateNand2->pPins->dDelayBlockRise; }
-float Mio_LibraryReadDelayNand2Fall( Mio_Library_t * pLib ) { return (float)pLib->pGateNand2->pPins->dDelayBlockFall; }
-float Mio_LibraryReadDelayNand2Max ( Mio_Library_t * pLib ) { return (float)pLib->pGateNand2->pPins->dDelayBlockMax; }
-float Mio_LibraryReadAreaInv ( Mio_Library_t * pLib ) { return (float)pLib->pGateInv->dArea; }
-float Mio_LibraryReadAreaNand2 ( Mio_Library_t * pLib ) { return (float)pLib->pGateNand2->dArea; }
+float Mio_LibraryReadDelayInvRise ( Mio_Library_t * pLib ) { return (float)(pLib->pGateInv? pLib->pGateInv->pPins->dDelayBlockRise : 0.0); }
+float Mio_LibraryReadDelayInvFall ( Mio_Library_t * pLib ) { return (float)(pLib->pGateInv? pLib->pGateInv->pPins->dDelayBlockFall : 0.0); }
+float Mio_LibraryReadDelayInvMax ( Mio_Library_t * pLib ) { return (float)(pLib->pGateInv? pLib->pGateInv->pPins->dDelayBlockMax : 0.0); }
+float Mio_LibraryReadDelayNand2Rise( Mio_Library_t * pLib ) { return (float)(pLib->pGateNand2? pLib->pGateNand2->pPins->dDelayBlockRise : 0.0); }
+float Mio_LibraryReadDelayNand2Fall( Mio_Library_t * pLib ) { return (float)(pLib->pGateNand2? pLib->pGateNand2->pPins->dDelayBlockFall : 0.0); }
+float Mio_LibraryReadDelayNand2Max ( Mio_Library_t * pLib ) { return (float)(pLib->pGateNand2? pLib->pGateNand2->pPins->dDelayBlockMax : 0.0); }
+float Mio_LibraryReadAreaInv ( Mio_Library_t * pLib ) { return (float)(pLib->pGateInv? pLib->pGateInv->dArea : 0.0); }
+float Mio_LibraryReadAreaBuf ( Mio_Library_t * pLib ) { return (float)(pLib->pGateBuf? pLib->pGateBuf->dArea : 0.0); }
+float Mio_LibraryReadAreaNand2 ( Mio_Library_t * pLib ) { return (float)(pLib->pGateNand2? pLib->pGateNand2->dArea : 0.0); }
/**Function*************************************************************