From 33012d9530c40817e1fc5230b3e663f7690b2e94 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 4 Sep 2005 08:01:00 -0700 Subject: Version abc50904 --- src/map/fpga/fpga.h | 2 + src/map/fpga/fpgaCore.c | 41 ++++--- src/map/fpga/fpgaCreate.c | 2 + src/map/fpga/fpgaCutUtils.c | 103 ------------------ src/map/fpga/fpgaInt.h | 17 ++- src/map/fpga/fpgaMatch.c | 2 +- src/map/fpga/fpgaSwitch.c | 176 ++++++++++++++++++++++++++++++ src/map/fpga/fpgaUtils.c | 37 ------- src/map/fpga/module.make | 1 + src/map/mapper/mapper.h | 2 + src/map/mapper/mapperCore.c | 83 ++++++++++++--- src/map/mapper/mapperCreate.c | 6 +- src/map/mapper/mapperInt.h | 8 ++ src/map/mapper/mapperLib.c | 1 + src/map/mapper/mapperMatch.c | 34 ++++-- src/map/mapper/mapperRefs.c | 9 +- src/map/mapper/mapperSwitch.c | 243 ++++++++++++++++++++++++++++++++++++++++++ src/map/mapper/module.make | 1 + src/map/mio/mio.h | 1 + src/map/mio/mioApi.c | 17 +-- 20 files changed, 581 insertions(+), 205 deletions(-) create mode 100644 src/map/fpga/fpgaSwitch.c create mode 100644 src/map/mapper/mapperSwitch.c (limited to 'src/map') 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************************************************************* -- cgit v1.2.3