mirror of https://github.com/YosysHQ/abc.git
Integrating barrier buffers into the mapper.
This commit is contained in:
parent
f6eb5262a3
commit
6f17c44e91
|
|
@ -610,6 +610,7 @@ extern ABC_DLL int Abc_NtkIsDfsOrdered( Abc_Ntk_t * pNtk );
|
|||
extern ABC_DLL Vec_Ptr_t * Abc_NtkSupport( Abc_Ntk_t * pNtk );
|
||||
extern ABC_DLL Vec_Ptr_t * Abc_NtkNodeSupport( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
|
||||
extern ABC_DLL Vec_Ptr_t * Abc_AigDfs( Abc_Ntk_t * pNtk, int fCollectAll, int fCollectCos );
|
||||
extern ABC_DLL Vec_Ptr_t * Abc_AigDfsMap( Abc_Ntk_t * pNtk );
|
||||
extern ABC_DLL Vec_Vec_t * Abc_DfsLevelized( Abc_Obj_t * pNode, int fTfi );
|
||||
extern ABC_DLL Vec_Vec_t * Abc_NtkLevelize( Abc_Ntk_t * pNtk );
|
||||
extern ABC_DLL int Abc_NtkLevel( Abc_Ntk_t * pNtk );
|
||||
|
|
|
|||
|
|
@ -311,6 +311,70 @@ Abc_Ntk_t * Abc_NtkFromBarBufs( Abc_Ntk_t * pNtkBase, Abc_Ntk_t * pNtk )
|
|||
return pNtkNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect nodes in the barbuf-friendly order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkToBarBufsCollect_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
if ( Abc_NodeIsTravIdCurrent( pObj ) )
|
||||
return;
|
||||
Abc_NodeSetTravIdCurrent( pObj );
|
||||
assert( Abc_ObjIsNode(pObj) );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
Abc_NtkToBarBufsCollect_rec( pFanin, vNodes );
|
||||
Vec_PtrPush( vNodes, pObj );
|
||||
}
|
||||
Vec_Ptr_t * Abc_NtkToBarBufsCollect( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
assert( Abc_NtkIsLogic(pNtk) );
|
||||
assert( pNtk->nBarBufs > 0 );
|
||||
assert( pNtk->nBarBufs == Abc_NtkLatchNum(pNtk) );
|
||||
vNodes = Vec_PtrAlloc( Abc_NtkObjNum(pNtk) );
|
||||
Abc_NtkIncrementTravId( pNtk );
|
||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
{
|
||||
if ( i >= Abc_NtkCiNum(pNtk) - pNtk->nBarBufs )
|
||||
break;
|
||||
Vec_PtrPush( vNodes, pObj );
|
||||
Abc_NodeSetTravIdCurrent( pObj );
|
||||
}
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
{
|
||||
if ( i < Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
|
||||
continue;
|
||||
Abc_NtkToBarBufsCollect_rec( Abc_ObjFanin0(pObj), vNodes );
|
||||
Vec_PtrPush( vNodes, pObj );
|
||||
Vec_PtrPush( vNodes, Abc_ObjFanout0(pObj) );
|
||||
Vec_PtrPush( vNodes, Abc_ObjFanout0(Abc_ObjFanout0(pObj)) );
|
||||
Abc_NodeSetTravIdCurrent( pObj );
|
||||
Abc_NodeSetTravIdCurrent( Abc_ObjFanout0(pObj) );
|
||||
Abc_NodeSetTravIdCurrent( Abc_ObjFanout0(Abc_ObjFanout0(pObj)) );
|
||||
}
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
{
|
||||
if ( i >= Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
|
||||
break;
|
||||
Abc_NtkToBarBufsCollect_rec( Abc_ObjFanin0(pObj), vNodes );
|
||||
Vec_PtrPush( vNodes, pObj );
|
||||
Abc_NodeSetTravIdCurrent( pObj );
|
||||
}
|
||||
assert( Vec_PtrSize(vNodes) == Abc_NtkObjNum(pNtk) );
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -946,6 +946,50 @@ Vec_Ptr_t * Abc_AigDfs( Abc_Ntk_t * pNtk, int fCollectAll, int fCollectCos )
|
|||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the DFS ordered array of logic nodes.]
|
||||
|
||||
Description [Collects only the internal nodes, leaving out CIs/COs.
|
||||
However it marks both CIs and COs with the current TravId.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Abc_AigDfsMap( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pNode;
|
||||
int i;
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
// set the traversal ID
|
||||
Abc_NtkIncrementTravId( pNtk );
|
||||
// start the array of nodes
|
||||
vNodes = Vec_PtrAlloc( 100 );
|
||||
// collect cones of barbufs
|
||||
Abc_NtkForEachCo( pNtk, pNode, i )
|
||||
{
|
||||
if ( i < Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
|
||||
continue;
|
||||
Abc_AigDfs_rec( Abc_ObjFanin0(pNode), vNodes );
|
||||
Abc_NodeSetTravIdCurrent( pNode );
|
||||
// collect latch as a placeholder
|
||||
assert( Abc_ObjIsLatch(Abc_ObjFanout0(pNode)) );
|
||||
Vec_PtrPush( vNodes, Abc_ObjFanout0(pNode) );
|
||||
}
|
||||
// collect nodes of real POs
|
||||
Abc_NtkForEachCo( pNtk, pNode, i )
|
||||
{
|
||||
if ( i >= Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
|
||||
break;
|
||||
Abc_AigDfs_rec( Abc_ObjFanin0(pNode), vNodes );
|
||||
assert( Abc_ObjIsPo(pNode) );
|
||||
Abc_NodeSetTravIdCurrent( pNode );
|
||||
}
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ static Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRec
|
|||
static Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk );
|
||||
static Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
|
||||
static Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
|
||||
static Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis );
|
||||
|
||||
static Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk );
|
||||
static void Abc_NodeSuperChoice( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode );
|
||||
|
|
@ -219,7 +218,6 @@ Map_Time_t * Abc_NtkMapCopyCoRequired( Abc_Ntk_t * pNtk, Abc_Time_t * ppTimes )
|
|||
Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, float * pSwitching, int fVerbose )
|
||||
{
|
||||
Map_Man_t * pMan;
|
||||
ProgressBar * pProgress;
|
||||
Map_Node_t * pNodeMap;
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pNode, * pFanin, * pPrev;
|
||||
|
|
@ -228,7 +226,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
|
|||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
|
||||
// start the mapping manager and set its parameters
|
||||
pMan = Map_ManCreate( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk), Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk), fVerbose );
|
||||
pMan = Map_ManCreate( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk) - pNtk->nBarBufs, Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk) - pNtk->nBarBufs, fVerbose );
|
||||
if ( pMan == NULL )
|
||||
return NULL;
|
||||
Map_ManSetAreaRecovery( pMan, fRecovery );
|
||||
|
|
@ -242,6 +240,8 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
|
|||
Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan);
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
{
|
||||
if ( i == Abc_NtkCiNum(pNtk) - pNtk->nBarBufs )
|
||||
break;
|
||||
pNodeMap = Map_ManReadInputs(pMan)[i];
|
||||
pNode->pCopy = (Abc_Obj_t *)pNodeMap;
|
||||
if ( pSwitching )
|
||||
|
|
@ -249,11 +249,17 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
|
|||
}
|
||||
|
||||
// load the AIG into the mapper
|
||||
vNodes = Abc_AigDfs( pNtk, 0, 0 );
|
||||
pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
|
||||
vNodes = Abc_AigDfsMap( pNtk );
|
||||
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
|
||||
{
|
||||
Extra_ProgressBarUpdate( pProgress, i, NULL );
|
||||
if ( Abc_ObjIsLatch(pNode) )
|
||||
{
|
||||
pFanin = Abc_ObjFanin0(pNode);
|
||||
pNodeMap = Map_NodeBuf( pMan, Map_NotCond( Abc_ObjFanin0(pFanin)->pCopy, (int)Abc_ObjFaninC0(pFanin) ) );
|
||||
Abc_ObjFanout0(pNode)->pCopy = (Abc_Obj_t *)pNodeMap;
|
||||
continue;
|
||||
}
|
||||
assert( Abc_ObjIsNode(pNode) );
|
||||
// add the node to the mapper
|
||||
pNodeMap = Map_NodeAnd( pMan,
|
||||
Map_NotCond( Abc_ObjFanin0(pNode)->pCopy, (int)Abc_ObjFaninC0(pNode) ),
|
||||
|
|
@ -271,12 +277,16 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
|
|||
Map_NodeSetRepr( (Map_Node_t *)pFanin->pCopy, (Map_Node_t *)pNode->pCopy );
|
||||
}
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
assert( Map_ManReadBufNum(pMan) == pNtk->nBarBufs );
|
||||
Vec_PtrFree( vNodes );
|
||||
|
||||
// set the primary outputs in the required phase
|
||||
Abc_NtkForEachCo( pNtk, pNode, i )
|
||||
{
|
||||
if ( i == Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
|
||||
break;
|
||||
Map_ManReadOutputs(pMan)[i] = Map_NotCond( (Map_Node_t *)Abc_ObjFanin0(pNode)->pCopy, (int)Abc_ObjFaninC0(pNode) );
|
||||
}
|
||||
return pMan;
|
||||
}
|
||||
|
||||
|
|
@ -290,144 +300,6 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
|
|||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
ProgressBar * pProgress;
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Map_Node_t * pNodeMap;
|
||||
Abc_Obj_t * pNode, * pNodeNew;
|
||||
int i, nDupGates;
|
||||
// create the new network
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_MAP );
|
||||
// make the mapper point to the new network
|
||||
Map_ManCleanData( pMan );
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy );
|
||||
// assign the mapping of the required phase to the POs
|
||||
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
|
||||
Abc_NtkForEachCo( pNtk, pNode, i )
|
||||
{
|
||||
Extra_ProgressBarUpdate( pProgress, i, NULL );
|
||||
pNodeMap = Map_ManReadOutputs(pMan)[i];
|
||||
pNodeNew = Abc_NodeFromMap_rec( pNtkNew, Map_Regular(pNodeMap), !Map_IsComplement(pNodeMap) );
|
||||
assert( !Abc_ObjIsComplement(pNodeNew) );
|
||||
Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
// decouple the PO driver nodes to reduce the number of levels
|
||||
nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
|
||||
// if ( nDupGates && Map_ManReadVerbose(pMan) )
|
||||
// printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs the nodes corrresponding to one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase )
|
||||
{
|
||||
Abc_Obj_t * pNodeNew, * pNodeInv;
|
||||
|
||||
// check the case of constant node
|
||||
if ( Map_NodeIsConst(pNodeMap) )
|
||||
{
|
||||
pNodeNew = fPhase? Abc_NtkCreateNodeConst1(pNtkNew) : Abc_NtkCreateNodeConst0(pNtkNew);
|
||||
if ( pNodeNew->pData == NULL )
|
||||
printf( "Error creating mapped network: Library does not have a constant %d gate.\n", fPhase );
|
||||
return pNodeNew;
|
||||
}
|
||||
|
||||
// check if the phase is already implemented
|
||||
pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
|
||||
if ( pNodeNew )
|
||||
return pNodeNew;
|
||||
|
||||
// implement the node if the best cut is assigned
|
||||
if ( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL )
|
||||
return Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, fPhase );
|
||||
|
||||
// if the cut is not assigned, implement the node
|
||||
assert( Map_NodeReadCutBest(pNodeMap, !fPhase) != NULL || Map_NodeIsConst(pNodeMap) );
|
||||
pNodeNew = Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, !fPhase );
|
||||
|
||||
// add the inverter
|
||||
pNodeInv = Abc_NtkCreateNode( pNtkNew );
|
||||
Abc_ObjAddFanin( pNodeInv, pNodeNew );
|
||||
pNodeInv->pData = Mio_LibraryReadInv(Map_ManReadGenLib(Map_NodeReadMan(pNodeMap)));
|
||||
|
||||
// set the inverter
|
||||
Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeInv );
|
||||
return pNodeInv;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs the nodes corrresponding to one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase )
|
||||
{
|
||||
Abc_Obj_t * pNodePIs[10];
|
||||
Abc_Obj_t * pNodeNew;
|
||||
Map_Node_t ** ppLeaves;
|
||||
Map_Cut_t * pCutBest;
|
||||
Map_Super_t * pSuperBest;
|
||||
unsigned uPhaseBest;
|
||||
int i, fInvPin, nLeaves;
|
||||
|
||||
// make sure the node can be implemented in this phase
|
||||
assert( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL || Map_NodeIsConst(pNodeMap) );
|
||||
// check if the phase is already implemented
|
||||
pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
|
||||
if ( pNodeNew )
|
||||
return pNodeNew;
|
||||
|
||||
// get the information about the best cut
|
||||
pCutBest = Map_NodeReadCutBest( pNodeMap, fPhase );
|
||||
pSuperBest = Map_CutReadSuperBest( pCutBest, fPhase );
|
||||
uPhaseBest = Map_CutReadPhaseBest( pCutBest, fPhase );
|
||||
nLeaves = Map_CutReadLeavesNum( pCutBest );
|
||||
ppLeaves = Map_CutReadLeaves( pCutBest );
|
||||
|
||||
// collect the PI nodes
|
||||
for ( i = 0; i < nLeaves; i++ )
|
||||
{
|
||||
fInvPin = ((uPhaseBest & (1 << i)) > 0);
|
||||
pNodePIs[i] = Abc_NodeFromMap_rec( pNtkNew, ppLeaves[i], !fInvPin );
|
||||
assert( pNodePIs[i] != NULL );
|
||||
}
|
||||
|
||||
// implement the supergate
|
||||
pNodeNew = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, pSuperBest, pNodePIs, nLeaves );
|
||||
Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeNew );
|
||||
return pNodeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs the nodes corrresponding to one supergate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis )
|
||||
{
|
||||
|
|
@ -473,10 +345,126 @@ Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap
|
|||
pNodeNew->pData = pRoot;
|
||||
return pNodeNew;
|
||||
}
|
||||
Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase )
|
||||
{
|
||||
Abc_Obj_t * pNodePIs[10];
|
||||
Abc_Obj_t * pNodeNew;
|
||||
Map_Node_t ** ppLeaves;
|
||||
Map_Cut_t * pCutBest;
|
||||
Map_Super_t * pSuperBest;
|
||||
unsigned uPhaseBest;
|
||||
int i, fInvPin, nLeaves;
|
||||
|
||||
// make sure the node can be implemented in this phase
|
||||
assert( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL || Map_NodeIsConst(pNodeMap) );
|
||||
// check if the phase is already implemented
|
||||
pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
|
||||
if ( pNodeNew )
|
||||
return pNodeNew;
|
||||
|
||||
// get the information about the best cut
|
||||
pCutBest = Map_NodeReadCutBest( pNodeMap, fPhase );
|
||||
pSuperBest = Map_CutReadSuperBest( pCutBest, fPhase );
|
||||
uPhaseBest = Map_CutReadPhaseBest( pCutBest, fPhase );
|
||||
nLeaves = Map_CutReadLeavesNum( pCutBest );
|
||||
ppLeaves = Map_CutReadLeaves( pCutBest );
|
||||
|
||||
// collect the PI nodes
|
||||
for ( i = 0; i < nLeaves; i++ )
|
||||
{
|
||||
fInvPin = ((uPhaseBest & (1 << i)) > 0);
|
||||
pNodePIs[i] = Abc_NodeFromMap_rec( pNtkNew, ppLeaves[i], !fInvPin );
|
||||
assert( pNodePIs[i] != NULL );
|
||||
}
|
||||
|
||||
// implement the supergate
|
||||
pNodeNew = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, pSuperBest, pNodePIs, nLeaves );
|
||||
Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeNew );
|
||||
return pNodeNew;
|
||||
}
|
||||
Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase )
|
||||
{
|
||||
Abc_Obj_t * pNodeNew, * pNodeInv;
|
||||
|
||||
// check the case of constant node
|
||||
if ( Map_NodeIsConst(pNodeMap) )
|
||||
{
|
||||
pNodeNew = fPhase? Abc_NtkCreateNodeConst1(pNtkNew) : Abc_NtkCreateNodeConst0(pNtkNew);
|
||||
if ( pNodeNew->pData == NULL )
|
||||
printf( "Error creating mapped network: Library does not have a constant %d gate.\n", fPhase );
|
||||
return pNodeNew;
|
||||
}
|
||||
|
||||
// check if the phase is already implemented
|
||||
pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
|
||||
if ( pNodeNew )
|
||||
return pNodeNew;
|
||||
|
||||
// implement the node if the best cut is assigned
|
||||
if ( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL )
|
||||
return Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, fPhase );
|
||||
|
||||
// if the cut is not assigned, implement the node
|
||||
assert( Map_NodeReadCutBest(pNodeMap, !fPhase) != NULL || Map_NodeIsConst(pNodeMap) );
|
||||
pNodeNew = Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, !fPhase );
|
||||
|
||||
// add the inverter
|
||||
pNodeInv = Abc_NtkCreateNode( pNtkNew );
|
||||
Abc_ObjAddFanin( pNodeInv, pNodeNew );
|
||||
pNodeInv->pData = Mio_LibraryReadInv(Map_ManReadGenLib(Map_NodeReadMan(pNodeMap)));
|
||||
|
||||
// set the inverter
|
||||
Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeInv );
|
||||
return pNodeInv;
|
||||
}
|
||||
Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Map_Node_t * pNodeMap;
|
||||
Abc_Obj_t * pNode, * pNodeNew;
|
||||
int i, nDupGates;
|
||||
assert( Map_ManReadBufNum(pMan) == pNtk->nBarBufs );
|
||||
// create the new network
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_MAP );
|
||||
// make the mapper point to the new network
|
||||
Map_ManCleanData( pMan );
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
{
|
||||
if ( i >= Abc_NtkCiNum(pNtk) - pNtk->nBarBufs )
|
||||
break;
|
||||
Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy );
|
||||
}
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
{
|
||||
if ( i < Abc_NtkCiNum(pNtk) - pNtk->nBarBufs )
|
||||
continue;
|
||||
Map_NodeSetData( Map_ManReadBufs(pMan)[i - (Abc_NtkCiNum(pNtk) - pNtk->nBarBufs)], 1, (char *)pNode->pCopy );
|
||||
}
|
||||
// assign the mapping of the required phase to the POs
|
||||
Abc_NtkForEachCo( pNtk, pNode, i )
|
||||
{
|
||||
if ( i < Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
|
||||
continue;
|
||||
pNodeMap = Map_ManReadBufDriver( pMan, i - (Abc_NtkCoNum(pNtk) - pNtk->nBarBufs) );
|
||||
pNodeNew = Abc_NodeFromMap_rec( pNtkNew, Map_Regular(pNodeMap), !Map_IsComplement(pNodeMap) );
|
||||
assert( !Abc_ObjIsComplement(pNodeNew) );
|
||||
Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
|
||||
}
|
||||
Abc_NtkForEachCo( pNtk, pNode, i )
|
||||
{
|
||||
if ( i >= Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
|
||||
break;
|
||||
pNodeMap = Map_ManReadOutputs(pMan)[i];
|
||||
pNodeNew = Abc_NodeFromMap_rec( pNtkNew, Map_Regular(pNodeMap), !Map_IsComplement(pNodeMap) );
|
||||
assert( !Abc_ObjIsComplement(pNodeNew) );
|
||||
Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
|
||||
}
|
||||
// decouple the PO driver nodes to reduce the number of levels
|
||||
nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
|
||||
// if ( nDupGates && Map_ManReadVerbose(pMan) )
|
||||
// printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -82,8 +82,11 @@ extern void Map_ManPrintTimeStats( Map_Man_t * p );
|
|||
extern void Map_ManPrintStatsToFile( char * pName, float Area, float Delay, abctime Time );
|
||||
extern int Map_ManReadInputNum( Map_Man_t * p );
|
||||
extern int Map_ManReadOutputNum( Map_Man_t * p );
|
||||
extern int Map_ManReadBufNum( Map_Man_t * p );
|
||||
extern Map_Node_t ** Map_ManReadInputs ( Map_Man_t * p );
|
||||
extern Map_Node_t ** Map_ManReadOutputs( Map_Man_t * p );
|
||||
extern Map_Node_t ** Map_ManReadBufs( Map_Man_t * p );
|
||||
extern Map_Node_t * Map_ManReadBufDriver( Map_Man_t * p, int i );
|
||||
extern Map_Node_t * Map_ManReadConst1 ( Map_Man_t * p );
|
||||
extern Map_Time_t * Map_ManReadInputArrivals( Map_Man_t * p );
|
||||
extern Mio_Library_t * Map_ManReadGenLib ( Map_Man_t * p );
|
||||
|
|
@ -121,6 +124,7 @@ 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 );
|
||||
extern int Map_NodeIsBuf( Map_Node_t * p );
|
||||
extern int Map_NodeIsAnd( Map_Node_t * p );
|
||||
extern int Map_NodeComparePhase( Map_Node_t * p1, Map_Node_t * p2 );
|
||||
|
||||
|
|
@ -150,9 +154,7 @@ extern Map_Time_t Map_SuperLibReadDelayInv( Map_SuperLib_t * p );
|
|||
extern int Map_SuperLibReadVarsMax( Map_SuperLib_t * p );
|
||||
|
||||
extern Map_Node_t * Map_NodeAnd( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 );
|
||||
extern Map_Node_t * Map_NodeOr( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 );
|
||||
extern Map_Node_t * Map_NodeExor( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 );
|
||||
extern Map_Node_t * Map_NodeMux( Map_Man_t * p, Map_Node_t * pNode, Map_Node_t * pNodeT, Map_Node_t * pNodeE );
|
||||
extern Map_Node_t * Map_NodeBuf( Map_Man_t * p, Map_Node_t * p1 );
|
||||
extern void Map_NodeSetChoice( Map_Man_t * pMan, Map_Node_t * pNodeOld, Map_Node_t * pNodeNew );
|
||||
|
||||
/*=== resmCanon.c =============================================================*/
|
||||
|
|
|
|||
|
|
@ -57,8 +57,6 @@ int Map_Mapping( Map_Man_t * p )
|
|||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// perform pre-mapping computations
|
||||
// collect the nodes reachable from POs in the DFS order (including the choices)
|
||||
p->vAnds = Map_MappingDfs( p, 1 );
|
||||
if ( p->fVerbose )
|
||||
Map_MappingReportChoices( p );
|
||||
Map_MappingSetChoiceLevels( p ); // should always be called before mapping!
|
||||
|
|
@ -84,12 +82,12 @@ int Map_Mapping( Map_Man_t * p )
|
|||
p->timeMatch = Abc_Clock() - clk;
|
||||
// compute the references and collect the nodes used in the mapping
|
||||
Map_MappingSetRefs( p );
|
||||
p->AreaBase = Map_MappingGetArea( p, p->vMapping );
|
||||
p->AreaBase = Map_MappingGetArea( p );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "Delay : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
fShowSwitching? "Switch" : "Delay",
|
||||
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
|
||||
fShowSwitching? Map_MappingGetSwitching(p) : p->fRequiredGlo,
|
||||
Map_MappingGetAreaFlow(p), p->AreaBase, 0.0 );
|
||||
ABC_PRT( "Time", p->timeMatch );
|
||||
}
|
||||
|
|
@ -114,12 +112,12 @@ ABC_PRT( "Time", p->timeMatch );
|
|||
Map_MappingMatches( p );
|
||||
// compute the references and collect the nodes used in the mapping
|
||||
Map_MappingSetRefs( p );
|
||||
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
|
||||
p->AreaFinal = Map_MappingGetArea( p );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "AreaFlow : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
fShowSwitching? "Switch" : "Delay",
|
||||
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
|
||||
fShowSwitching? Map_MappingGetSwitching(p) : p->fRequiredGlo,
|
||||
Map_MappingGetAreaFlow(p), p->AreaFinal,
|
||||
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
|
||||
ABC_PRT( "Time", Abc_Clock() - clk );
|
||||
|
|
@ -140,12 +138,12 @@ ABC_PRT( "Time", Abc_Clock() - clk );
|
|||
Map_MappingMatches( p );
|
||||
// compute the references and collect the nodes used in the mapping
|
||||
Map_MappingSetRefs( p );
|
||||
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
|
||||
p->AreaFinal = Map_MappingGetArea( p );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "Area : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
fShowSwitching? "Switch" : "Delay",
|
||||
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
|
||||
fShowSwitching? Map_MappingGetSwitching(p) : p->fRequiredGlo,
|
||||
0.0, p->AreaFinal,
|
||||
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
|
||||
ABC_PRT( "Time", Abc_Clock() - clk );
|
||||
|
|
@ -166,12 +164,12 @@ ABC_PRT( "Time", Abc_Clock() - clk );
|
|||
Map_MappingMatches( p );
|
||||
// compute the references and collect the nodes used in the mapping
|
||||
Map_MappingSetRefs( p );
|
||||
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
|
||||
p->AreaFinal = Map_MappingGetArea( p );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "Area : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
fShowSwitching? "Switch" : "Delay",
|
||||
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
|
||||
fShowSwitching? Map_MappingGetSwitching(p) : p->fRequiredGlo,
|
||||
0.0, p->AreaFinal,
|
||||
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
|
||||
ABC_PRT( "Time", Abc_Clock() - clk );
|
||||
|
|
@ -192,12 +190,12 @@ ABC_PRT( "Time", Abc_Clock() - clk );
|
|||
Map_MappingMatches( p );
|
||||
// compute the references and collect the nodes used in the mapping
|
||||
Map_MappingSetRefs( p );
|
||||
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
|
||||
p->AreaFinal = Map_MappingGetArea( p );
|
||||
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,
|
||||
fShowSwitching? Map_MappingGetSwitching(p) : p->fRequiredGlo,
|
||||
0.0, p->AreaFinal,
|
||||
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
|
||||
ABC_PRT( "Time", Abc_Clock() - clk );
|
||||
|
|
@ -210,12 +208,12 @@ ABC_PRT( "Time", Abc_Clock() - clk );
|
|||
Map_MappingMatches( p );
|
||||
// compute the references and collect the nodes used in the mapping
|
||||
Map_MappingSetRefs( p );
|
||||
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
|
||||
p->AreaFinal = Map_MappingGetArea( p );
|
||||
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,
|
||||
fShowSwitching? Map_MappingGetSwitching(p) : p->fRequiredGlo,
|
||||
0.0, p->AreaFinal,
|
||||
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
|
||||
ABC_PRT( "Time", Abc_Clock() - clk );
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
static void Map_TableCreate( Map_Man_t * p );
|
||||
static void Map_TableResize( Map_Man_t * p );
|
||||
static Map_Node_t * Map_TableLookup( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 );
|
||||
|
||||
// hash key for the structural hash table
|
||||
static inline unsigned Map_HashKey2( Map_Node_t * p0, Map_Node_t * p1, int TableSize ) { return (unsigned)(((ABC_PTRUINT_T)(p0) + (ABC_PTRUINT_T)(p1) * 12582917) % TableSize); }
|
||||
|
|
@ -49,8 +48,11 @@ static inline unsigned Map_HashKey2( Map_Node_t * p0, Map_Node_t * p1, int Table
|
|||
***********************************************************************/
|
||||
int Map_ManReadInputNum( Map_Man_t * p ) { return p->nInputs; }
|
||||
int Map_ManReadOutputNum( Map_Man_t * p ) { return p->nOutputs; }
|
||||
int Map_ManReadBufNum( Map_Man_t * p ) { return Map_NodeVecReadSize(p->vMapBufs); }
|
||||
Map_Node_t ** Map_ManReadInputs ( Map_Man_t * p ) { return p->pInputs; }
|
||||
Map_Node_t ** Map_ManReadOutputs( Map_Man_t * p ) { return p->pOutputs; }
|
||||
Map_Node_t ** Map_ManReadBufs( Map_Man_t * p ) { return Map_NodeVecReadArray(p->vMapBufs); }
|
||||
Map_Node_t * Map_ManReadBufDriver( Map_Man_t * p, int i ) { return Map_ManReadBufs(p)[i]->p1; }
|
||||
Map_Node_t * Map_ManReadConst1 ( Map_Man_t * p ) { return p->pConst1; }
|
||||
Map_Time_t * Map_ManReadInputArrivals( Map_Man_t * p ) { return p->pInputArrivals; }
|
||||
Map_Time_t * Map_ManReadOutputRequireds( Map_Man_t * p ) { return p->pOutputRequireds; }
|
||||
|
|
@ -109,7 +111,8 @@ void Map_NodeSetSwitching( Map_Node_t * p, float Switching ) { p-
|
|||
***********************************************************************/
|
||||
int Map_NodeIsConst( Map_Node_t * p ) { return (Map_Regular(p))->Num == -1; }
|
||||
int Map_NodeIsVar( Map_Node_t * p ) { return (Map_Regular(p))->p1 == NULL && (Map_Regular(p))->Num >= 0; }
|
||||
int Map_NodeIsAnd( Map_Node_t * p ) { return (Map_Regular(p))->p1 != NULL; }
|
||||
int Map_NodeIsBuf( Map_Node_t * p ) { return (Map_Regular(p))->p1 != NULL && (Map_Regular(p))->p2 == NULL; }
|
||||
int Map_NodeIsAnd( Map_Node_t * p ) { return (Map_Regular(p))->p1 != NULL && (Map_Regular(p))->p2 != NULL; }
|
||||
int Map_NodeComparePhase( Map_Node_t * p1, Map_Node_t * p2 ) { assert( !Map_IsComplement(p1) ); assert( !Map_IsComplement(p2) ); return p1->fInv ^ p2->fInv; }
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -214,9 +217,8 @@ Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose )
|
|||
p->nNodes = -1;
|
||||
// create the constant node
|
||||
p->pConst1 = Map_NodeCreate( p, NULL, NULL );
|
||||
p->vNodesAll = Map_NodeVecAlloc( 100 );
|
||||
p->vNodesTemp = Map_NodeVecAlloc( 100 );
|
||||
p->vMapping = Map_NodeVecAlloc( 100 );
|
||||
p->vMapObjs = Map_NodeVecAlloc( 100 );
|
||||
p->vMapBufs = Map_NodeVecAlloc( 100 );
|
||||
p->vVisited = Map_NodeVecAlloc( 100 );
|
||||
|
||||
// create the PI nodes
|
||||
|
|
@ -246,19 +248,12 @@ Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose )
|
|||
void Map_ManFree( Map_Man_t * p )
|
||||
{
|
||||
// int i;
|
||||
// for ( i = 0; i < p->vNodesAll->nSize; i++ )
|
||||
// Map_NodeVecFree( p->vNodesAll->pArray[i]->vFanouts );
|
||||
// for ( i = 0; i < p->vMapObjs->nSize; i++ )
|
||||
// Map_NodeVecFree( p->vMapObjs->pArray[i]->vFanouts );
|
||||
// Map_NodeVecFree( p->pConst1->vFanouts );
|
||||
if ( p->vAnds )
|
||||
Map_NodeVecFree( p->vAnds );
|
||||
if ( p->vNodesAll )
|
||||
Map_NodeVecFree( p->vNodesAll );
|
||||
if ( p->vNodesTemp )
|
||||
Map_NodeVecFree( p->vNodesTemp );
|
||||
if ( p->vMapping )
|
||||
Map_NodeVecFree( p->vMapping );
|
||||
if ( p->vVisited )
|
||||
Map_NodeVecFree( p->vVisited );
|
||||
Map_NodeVecFree( p->vMapObjs );
|
||||
Map_NodeVecFree( p->vMapBufs );
|
||||
Map_NodeVecFree( p->vVisited );
|
||||
if ( p->uCanons ) ABC_FREE( p->uCanons );
|
||||
if ( p->uPhases ) ABC_FREE( p->uPhases );
|
||||
if ( p->pCounters ) ABC_FREE( p->pCounters );
|
||||
|
|
@ -291,10 +286,10 @@ void Map_ManCreateNodeDelays( Map_Man_t * p, int LogFan )
|
|||
Map_Node_t * pNode;
|
||||
int k;
|
||||
assert( p->pNodeDelays == NULL );
|
||||
p->pNodeDelays = ABC_CALLOC( float, p->vNodesAll->nSize );
|
||||
for ( k = 0; k < p->vNodesAll->nSize; k++ )
|
||||
p->pNodeDelays = ABC_CALLOC( float, p->vMapObjs->nSize );
|
||||
for ( k = 0; k < p->vMapObjs->nSize; k++ )
|
||||
{
|
||||
pNode = p->vNodesAll->pArray[k];
|
||||
pNode = p->vMapObjs->pArray[k];
|
||||
if ( pNode->nRefs == 0 )
|
||||
continue;
|
||||
p->pNodeDelays[k] = 0.014426 * LogFan * p->pSuperLib->tDelayInv.Worst * log( (double)pNode->nRefs ); // 1.4426 = 1/ln(2)
|
||||
|
|
@ -383,7 +378,7 @@ Map_Node_t * Map_NodeCreate( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 )
|
|||
// pNode->vFanouts = Map_NodeVecAlloc( 5 );
|
||||
// store this node in the internal array
|
||||
if ( pNode->Num >= 0 )
|
||||
Map_NodeVecPush( p->vNodesAll, pNode );
|
||||
Map_NodeVecPush( p->vMapObjs, pNode );
|
||||
else
|
||||
pNode->fInv = 1;
|
||||
// set the level of this node
|
||||
|
|
@ -392,10 +387,20 @@ Map_Node_t * Map_NodeCreate( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 )
|
|||
#ifdef MAP_ALLOCATE_FANOUT
|
||||
// create the fanout info
|
||||
Map_NodeAddFaninFanout( Map_Regular(p1), pNode );
|
||||
if ( p2 )
|
||||
Map_NodeAddFaninFanout( Map_Regular(p2), pNode );
|
||||
#endif
|
||||
pNode->Level = 1 + MAP_MAX(Map_Regular(pNode->p1)->Level, Map_Regular(pNode->p2)->Level);
|
||||
pNode->fInv = Map_NodeIsSimComplement(p1) & Map_NodeIsSimComplement(p2);
|
||||
|
||||
if ( p2 )
|
||||
{
|
||||
pNode->Level = 1 + MAP_MAX(Map_Regular(pNode->p1)->Level, Map_Regular(pNode->p2)->Level);
|
||||
pNode->fInv = Map_NodeIsSimComplement(p1) & Map_NodeIsSimComplement(p2);
|
||||
}
|
||||
else
|
||||
{
|
||||
pNode->Level = Map_Regular(pNode->p1)->Level;
|
||||
pNode->fInv = Map_NodeIsSimComplement(p1);
|
||||
}
|
||||
}
|
||||
// reference the inputs (will be used to compute the number of fanouts)
|
||||
if ( p1 ) Map_NodeRef(p1);
|
||||
|
|
@ -439,7 +444,7 @@ void Map_TableCreate( Map_Man_t * pMan )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Node_t * Map_TableLookup( Map_Man_t * pMan, Map_Node_t * p1, Map_Node_t * p2 )
|
||||
Map_Node_t * Map_NodeAnd( Map_Man_t * pMan, Map_Node_t * p1, Map_Node_t * p2 )
|
||||
{
|
||||
Map_Node_t * pEnt;
|
||||
unsigned Key;
|
||||
|
|
@ -544,68 +549,13 @@ clk = Abc_Clock();
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Node_t * Map_NodeAnd( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 )
|
||||
Map_Node_t * Map_NodeBuf( Map_Man_t * p, Map_Node_t * p1 )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
pNode = Map_TableLookup( p, p1, p2 );
|
||||
Map_Node_t * pNode = Map_NodeCreate( p, p1, NULL );
|
||||
Map_NodeVecPush( p->vMapBufs, pNode );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Node_t * Map_NodeOr( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
pNode = Map_Not( Map_TableLookup( p, Map_Not(p1), Map_Not(p2) ) );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Node_t * Map_NodeExor( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 )
|
||||
{
|
||||
return Map_NodeMux( p, p1, Map_Not(p2), p2 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Node_t * Map_NodeMux( Map_Man_t * p, Map_Node_t * pC, Map_Node_t * pT, Map_Node_t * pE )
|
||||
{
|
||||
Map_Node_t * pAnd1, * pAnd2, * pRes;
|
||||
pAnd1 = Map_TableLookup( p, pC, pT );
|
||||
pAnd2 = Map_TableLookup( p, Map_Not(pC), pE );
|
||||
pRes = Map_NodeOr( p, pAnd1, pAnd2 );
|
||||
return pRes;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets the node to be equivalent to the given one.]
|
||||
|
|
|
|||
|
|
@ -86,6 +86,51 @@ static unsigned Map_CutComputeTruth( Map_Man_t * p, Map_Cut_t * pCut, Ma
|
|||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts all the cuts.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_MappingCountAllCuts( Map_Man_t * pMan )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
Map_Cut_t * pCut;
|
||||
int i, nCuts;
|
||||
// int nCuts55 = 0, nCuts5x = 0, nCuts4x = 0, nCuts3x = 0;
|
||||
// int pCounts[7] = {0};
|
||||
nCuts = 0;
|
||||
for ( i = 0; i < pMan->nBins; i++ )
|
||||
for ( pNode = pMan->pBins[i]; pNode; pNode = pNode->pNext )
|
||||
for ( pCut = pNode->pCuts; pCut; pCut = pCut->pNext )
|
||||
if ( pCut->nLeaves > 1 ) // skip the elementary cuts
|
||||
{
|
||||
nCuts++;
|
||||
/*
|
||||
if ( Map_CutRegular(pCut->pOne)->nLeaves == 5 && Map_CutRegular(pCut->pTwo)->nLeaves == 5 )
|
||||
nCuts55++;
|
||||
if ( Map_CutRegular(pCut->pOne)->nLeaves == 5 || Map_CutRegular(pCut->pTwo)->nLeaves == 5 )
|
||||
nCuts5x++;
|
||||
else if ( Map_CutRegular(pCut->pOne)->nLeaves == 4 || Map_CutRegular(pCut->pTwo)->nLeaves == 4 )
|
||||
nCuts4x++;
|
||||
else if ( Map_CutRegular(pCut->pOne)->nLeaves == 3 || Map_CutRegular(pCut->pTwo)->nLeaves == 3 )
|
||||
nCuts3x++;
|
||||
*/
|
||||
// pCounts[ Map_CutRegular(pCut->pOne)->nLeaves ]++;
|
||||
// pCounts[ Map_CutRegular(pCut->pTwo)->nLeaves ]++;
|
||||
}
|
||||
// printf( "Total cuts = %6d. 55 = %6d. 5x = %6d. 4x = %6d. 3x = %6d.\n", nCuts, nCuts55, nCuts5x, nCuts4x, nCuts3x );
|
||||
|
||||
// printf( "Total cuts = %6d. 6= %6d. 5= %6d. 4= %6d. 3= %6d. 2= %6d. 1= %6d.\n",
|
||||
// nCuts, pCounts[6], pCounts[5], pCounts[4], pCounts[3], pCounts[2], pCounts[1] );
|
||||
return nCuts;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cuts for each node in the object graph.]
|
||||
|
|
@ -110,39 +155,44 @@ static unsigned Map_CutComputeTruth( Map_Man_t * p, Map_Cut_t * pCut, Ma
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MappingCutsInput( Map_Man_t * p, Map_Node_t * pNode )
|
||||
{
|
||||
Map_Cut_t * pCut;
|
||||
assert( Map_NodeIsVar(pNode) || Map_NodeIsBuf(pNode) );
|
||||
pCut = Map_CutAlloc( p );
|
||||
pCut->nLeaves = 1;
|
||||
pCut->ppLeaves[0] = pNode;
|
||||
pNode->pCuts = pCut;
|
||||
pNode->pCutBest[0] = NULL; // negative polarity is not mapped
|
||||
pNode->pCutBest[1] = pCut; // positive polarity is a trivial cut
|
||||
pCut->uTruth = 0xAAAAAAAA; // the first variable "1010"
|
||||
pCut->M[0].AreaFlow = 0.0;
|
||||
pCut->M[1].AreaFlow = 0.0;
|
||||
}
|
||||
void Map_MappingCuts( Map_Man_t * p )
|
||||
{
|
||||
ProgressBar * pProgress;
|
||||
Map_CutTable_t * pTable;
|
||||
Map_Node_t * pNode;
|
||||
Map_Cut_t * pCut;
|
||||
int nCuts, nNodes, i;
|
||||
abctime clk = Abc_Clock();
|
||||
// set the elementary cuts for the PI variables
|
||||
assert( p->nVarsMax > 1 && p->nVarsMax < 7 );
|
||||
for ( i = 0; i < p->nInputs; i++ )
|
||||
{
|
||||
pCut = Map_CutAlloc( p );
|
||||
pCut->nLeaves = 1;
|
||||
pCut->ppLeaves[0] = p->pInputs[i];
|
||||
p->pInputs[i]->pCuts = pCut;
|
||||
p->pInputs[i]->pCutBest[0] = NULL; // negative polarity is not mapped
|
||||
p->pInputs[i]->pCutBest[1] = pCut; // positive polarity is a trivial cut
|
||||
pCut->uTruth = 0xAAAAAAAA; // the first variable "10101010"
|
||||
pCut->M[0].AreaFlow = 0.0;
|
||||
pCut->M[1].AreaFlow = 0.0;
|
||||
}
|
||||
Map_MappingCutsInput( p, p->pInputs[i] );
|
||||
|
||||
// compute the cuts for the internal nodes
|
||||
nNodes = p->vAnds->nSize;
|
||||
nNodes = p->vMapObjs->nSize;
|
||||
pProgress = Extra_ProgressBarStart( stdout, nNodes );
|
||||
pTable = Map_CutTableStart( p );
|
||||
for ( i = 0; i < nNodes; i++ )
|
||||
{
|
||||
pNode = p->vAnds->pArray[i];
|
||||
if ( !Map_NodeIsAnd( pNode ) )
|
||||
continue;
|
||||
Map_CutCompute( p, pTable, pNode );
|
||||
pNode = p->vMapObjs->pArray[i];
|
||||
if ( Map_NodeIsBuf(pNode) )
|
||||
Map_MappingCutsInput( p, pNode );
|
||||
else if ( Map_NodeIsAnd(pNode) )
|
||||
Map_CutCompute( p, pTable, pNode );
|
||||
else continue;
|
||||
Extra_ProgressBarUpdate( pProgress, i, "Cuts ..." );
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
|
|
@ -679,51 +729,6 @@ int Map_CutBelongsToList( Map_Cut_t * pList, Map_Node_t * ppNodes[], int nNodes
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts all the cuts.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_MappingCountAllCuts( Map_Man_t * pMan )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
Map_Cut_t * pCut;
|
||||
int i, nCuts;
|
||||
// int nCuts55 = 0, nCuts5x = 0, nCuts4x = 0, nCuts3x = 0;
|
||||
// int pCounts[7] = {0};
|
||||
nCuts = 0;
|
||||
for ( i = 0; i < pMan->nBins; i++ )
|
||||
for ( pNode = pMan->pBins[i]; pNode; pNode = pNode->pNext )
|
||||
for ( pCut = pNode->pCuts; pCut; pCut = pCut->pNext )
|
||||
if ( pCut->nLeaves > 1 ) // skip the elementary cuts
|
||||
{
|
||||
nCuts++;
|
||||
/*
|
||||
if ( Map_CutRegular(pCut->pOne)->nLeaves == 5 && Map_CutRegular(pCut->pTwo)->nLeaves == 5 )
|
||||
nCuts55++;
|
||||
if ( Map_CutRegular(pCut->pOne)->nLeaves == 5 || Map_CutRegular(pCut->pTwo)->nLeaves == 5 )
|
||||
nCuts5x++;
|
||||
else if ( Map_CutRegular(pCut->pOne)->nLeaves == 4 || Map_CutRegular(pCut->pTwo)->nLeaves == 4 )
|
||||
nCuts4x++;
|
||||
else if ( Map_CutRegular(pCut->pOne)->nLeaves == 3 || Map_CutRegular(pCut->pTwo)->nLeaves == 3 )
|
||||
nCuts3x++;
|
||||
*/
|
||||
// pCounts[ Map_CutRegular(pCut->pOne)->nLeaves ]++;
|
||||
// pCounts[ Map_CutRegular(pCut->pTwo)->nLeaves ]++;
|
||||
}
|
||||
// printf( "Total cuts = %6d. 55 = %6d. 5x = %6d. 4x = %6d. 3x = %6d.\n", nCuts, nCuts55, nCuts5x, nCuts4x, nCuts3x );
|
||||
|
||||
// printf( "Total cuts = %6d. 6= %6d. 5= %6d. 4= %6d. 3= %6d. 2= %6d. 1= %6d.\n",
|
||||
// nCuts, pCounts[6], pCounts[5], pCounts[4], pCounts[3], pCounts[2], pCounts[1] );
|
||||
return nCuts;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -98,10 +98,8 @@ struct Map_ManStruct_t_
|
|||
int nOutputs; // the number of outputs
|
||||
int nNodes; // the total number of nodes
|
||||
Map_Node_t * pConst1; // the constant 1 node
|
||||
Map_NodeVec_t * vAnds; // the array of nodes in the DFS order
|
||||
Map_NodeVec_t * vNodesAll; // the array of all nodes
|
||||
Map_NodeVec_t * vNodesTemp; // the array of all nodes
|
||||
Map_NodeVec_t * vMapping; // the array of internal nodes used in the mapping
|
||||
Map_NodeVec_t * vMapObjs; // the array of all nodes
|
||||
Map_NodeVec_t * vMapBufs; // the array of all nodes
|
||||
float * pNodeDelays; // the array of node delays
|
||||
|
||||
// info about the original circuit
|
||||
|
|
@ -358,10 +356,6 @@ struct Map_HashEntryStruct_t_
|
|||
/*=== mapperCanon.c =============================================================*/
|
||||
/*=== mapperCut.c ===============================================================*/
|
||||
extern void Map_MappingCuts( Map_Man_t * p );
|
||||
extern int Map_MappingCountAllCuts( Map_Man_t * p );
|
||||
/*=== mapperCutDcs.c ===============================================================*/
|
||||
extern void Map_ComputeDcs( Map_Man_t * p );
|
||||
extern unsigned Map_ComputeIsop_rec( Map_Man_t * p, unsigned uF, unsigned uFD, int iVar, int nVars, int fDir );
|
||||
/*=== mapperCutUtils.c ===============================================================*/
|
||||
extern Map_Cut_t * Map_CutAlloc( Map_Man_t * p );
|
||||
extern void Map_CutFree( Map_Man_t * p, Map_Cut_t * pCut );
|
||||
|
|
@ -383,17 +377,7 @@ extern Map_SuperLib_t * Map_SuperLibCreate( Mio_Library_t * pGenlib, Vec_Str_t
|
|||
extern void Map_SuperLibFree( Map_SuperLib_t * p );
|
||||
/*=== mapperMatch.c ===============================================================*/
|
||||
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 );
|
||||
extern void Map_MappingEstimateRefsInit( Map_Man_t * p );
|
||||
extern void Map_MappingEstimateRefs( Map_Man_t * p );
|
||||
extern float Map_CutGetAreaFlow( Map_Cut_t * pCut, int fPhase );
|
||||
|
|
@ -402,9 +386,12 @@ extern float Map_CutGetAreaDerefed( Map_Cut_t * pCut, int fPhase );
|
|||
extern float Map_CutRef( Map_Cut_t * pCut, int fPhase );
|
||||
extern float Map_CutDeref( Map_Cut_t * pCut, int fPhase );
|
||||
extern void Map_MappingSetRefs( Map_Man_t * pMan );
|
||||
extern float Map_MappingGetArea( Map_Man_t * pMan, Map_NodeVec_t * vMapping );
|
||||
/*=== mapperShow.c =============================================================*/
|
||||
extern void Map_MappingShow( Map_Man_t * pMan, char * pFileName );
|
||||
extern float Map_MappingGetArea( Map_Man_t * pMan );
|
||||
/*=== mapperSwitch.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 );
|
||||
/*=== mapperTree.c ===============================================================*/
|
||||
extern int Map_LibraryDeriveGateInfo( Map_SuperLib_t * pLib, st__table * tExcludeGate );
|
||||
extern int Map_LibraryReadFileTreeStr( Map_SuperLib_t * pLib, Mio_Library_t * pGenlib, Vec_Str_t * vStr, char * pFileName );
|
||||
|
|
@ -423,13 +410,8 @@ extern void Map_SuperTableSortSupergates( Map_HashTable_t * p, int
|
|||
extern void Map_SuperTableSortSupergatesByDelay( Map_HashTable_t * p, int nSupersMax );
|
||||
/*=== mapperTime.c =============================================================*/
|
||||
extern float Map_TimeCutComputeArrival( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, float tWorstCaseLimit );
|
||||
extern void Map_TimeCutComputeArrival_rec( Map_Cut_t * pCut, int fPhase );
|
||||
extern float Map_TimeComputeArrivalMax( Map_Man_t * p );
|
||||
extern void Map_TimeComputeRequiredGlobal( Map_Man_t * p );
|
||||
extern void Map_TimeComputeRequired( Map_Man_t * p, float fRequired );
|
||||
extern float Map_TimeNodeFanoutDelay( Map_Node_t * pNode, int fPhase );
|
||||
extern float Map_TimeCutFanoutDelay( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase );
|
||||
extern float Map_TimeMatchWithInverter( Map_Man_t * p, Map_Match_t * pMatch );
|
||||
/*=== mapperTruth.c ===============================================================*/
|
||||
extern void Map_MappingTruths( Map_Man_t * pMan );
|
||||
extern int Map_TruthsCutDontCare( Map_Man_t * pMan, Map_Cut_t * pCut, unsigned * uTruthDc );
|
||||
|
|
@ -437,11 +419,6 @@ extern int Map_TruthCountOnes( unsigned * uTruth, int nLeaves );
|
|||
extern int Map_TruthDetectTwoFirst( unsigned * uTruth, int nLeaves );
|
||||
/*=== mapperUtils.c ===============================================================*/
|
||||
extern Map_NodeVec_t * Map_MappingDfs( Map_Man_t * pMan, int fCollectEquiv );
|
||||
extern Map_NodeVec_t * Map_MappingDfsNodes( Map_Man_t * pMan, Map_Node_t ** ppNodes, int nNodes, int fEquiv );
|
||||
|
||||
extern void Map_MappingDfsMarked1_rec( Map_Node_t * pNode, Map_NodeVec_t * vNodes, int fFirst );
|
||||
extern void Map_MappingDfsMarked2_rec( Map_Node_t * pNode, Map_NodeVec_t * vNodes, Map_NodeVec_t * vBoundary, int fFirst );
|
||||
|
||||
extern int Map_MappingCountLevels( Map_Man_t * pMan );
|
||||
extern void Map_MappingUnmark( Map_Man_t * pMan );
|
||||
extern void Map_MappingMark_rec( Map_Node_t * pNode );
|
||||
|
|
@ -464,6 +441,7 @@ extern void Map_MappingReportChoices( Map_Man_t * pMan );
|
|||
/*=== mapperVec.c =============================================================*/
|
||||
extern Map_NodeVec_t * Map_NodeVecAlloc( int nCap );
|
||||
extern void Map_NodeVecFree( Map_NodeVec_t * p );
|
||||
extern Map_NodeVec_t * Map_NodeVecDup( Map_NodeVec_t * p );
|
||||
extern Map_Node_t ** Map_NodeVecReadArray( Map_NodeVec_t * p );
|
||||
extern int Map_NodeVecReadSize( Map_NodeVec_t * p );
|
||||
extern void Map_NodeVecGrow( Map_NodeVec_t * p, int nCapMin );
|
||||
|
|
|
|||
|
|
@ -36,100 +36,188 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase );
|
||||
static int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, float fWorstLimit );
|
||||
|
||||
static void Map_MappingSetPiArrivalTimes( Map_Man_t * p );
|
||||
static void Map_NodeTryDroppingOnePhase( Map_Man_t * p, Map_Node_t * pNode );
|
||||
static void Map_NodeTransferArrivalTimes( Map_Man_t * p, Map_Node_t * pNode );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the best matches of the nodes.]
|
||||
Synopsis [Cleans the match.]
|
||||
|
||||
Description [Uses parameter p->fMappingMode to decide how to assign
|
||||
the matches for both polarities of the node. While the matches are
|
||||
being assigned, one of them may turn out to be better than the other
|
||||
(in terms of delay, for example). In this case, the worse match can
|
||||
be permanently dropped, and the corresponding pointer set to NULL.]
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_MappingMatches( Map_Man_t * p )
|
||||
void Map_MatchClean( Map_Match_t * pMatch )
|
||||
{
|
||||
ProgressBar * pProgress;
|
||||
Map_Node_t * pNode;
|
||||
int i;
|
||||
memset( pMatch, 0, sizeof(Map_Match_t) );
|
||||
pMatch->AreaFlow = MAP_FLOAT_LARGE; // unassigned
|
||||
pMatch->tArrive.Rise = MAP_FLOAT_LARGE; // unassigned
|
||||
pMatch->tArrive.Fall = MAP_FLOAT_LARGE; // unassigned
|
||||
pMatch->tArrive.Worst = MAP_FLOAT_LARGE; // unassigned
|
||||
}
|
||||
|
||||
assert( p->fMappingMode >= 0 && p->fMappingMode <= 4 );
|
||||
/**Function*************************************************************
|
||||
|
||||
// use the externally given PI arrival times
|
||||
if ( p->fMappingMode == 0 )
|
||||
Map_MappingSetPiArrivalTimes( p );
|
||||
Synopsis [Compares two matches.]
|
||||
|
||||
// estimate the fanouts
|
||||
if ( p->fMappingMode == 0 )
|
||||
Map_MappingEstimateRefsInit( p );
|
||||
else if ( p->fMappingMode == 1 )
|
||||
Map_MappingEstimateRefs( p );
|
||||
Description [Returns 1 if the second match is better. Otherwise returns 0.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
// the PI cuts are matched in the cut computation package
|
||||
// in the loop below we match the internal nodes
|
||||
pProgress = Extra_ProgressBarStart( stdout, p->vAnds->nSize );
|
||||
for ( i = 0; i < p->vAnds->nSize; i++ )
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_MatchCompare( Map_Man_t * pMan, Map_Match_t * pM1, Map_Match_t * pM2, int fDoingArea )
|
||||
{
|
||||
if ( !fDoingArea )
|
||||
{
|
||||
// skip primary inputs and secondary nodes if mapping with choices
|
||||
pNode = p->vAnds->pArray[i];
|
||||
if ( !Map_NodeIsAnd( pNode ) || pNode->pRepr )
|
||||
continue;
|
||||
|
||||
// make sure that at least one non-trival cut is present
|
||||
if ( pNode->pCuts->pNext == NULL )
|
||||
{
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
printf( "\nError: A node in the mapping graph does not have feasible cuts.\n" );
|
||||
// compare the arrival times
|
||||
if ( pM1->tArrive.Worst < pM2->tArrive.Worst - pMan->fEpsilon )
|
||||
return 0;
|
||||
}
|
||||
|
||||
// match negative phase
|
||||
if ( !Map_MatchNodePhase( p, pNode, 0 ) )
|
||||
{
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
if ( pM1->tArrive.Worst > pM2->tArrive.Worst + pMan->fEpsilon )
|
||||
return 1;
|
||||
// compare the areas or area flows
|
||||
if ( pM1->AreaFlow < pM2->AreaFlow - pMan->fEpsilon )
|
||||
return 0;
|
||||
}
|
||||
// match positive phase
|
||||
if ( !Map_MatchNodePhase( p, pNode, 1 ) )
|
||||
{
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
if ( pM1->AreaFlow > pM2->AreaFlow + pMan->fEpsilon )
|
||||
return 1;
|
||||
// compare the fanout limits
|
||||
if ( pM1->pSuperBest->nFanLimit > pM2->pSuperBest->nFanLimit )
|
||||
return 0;
|
||||
}
|
||||
|
||||
// make sure that at least one phase is mapped
|
||||
if ( pNode->pCutBest[0] == NULL && pNode->pCutBest[1] == NULL )
|
||||
{
|
||||
printf( "\nError: Could not match both phases of AIG node %d.\n", pNode->Num );
|
||||
printf( "Please make sure that the supergate library has equivalents of AND2 or NAND2.\n" );
|
||||
printf( "If such supergates exist in the library, report a bug.\n" );
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
if ( pM1->pSuperBest->nFanLimit < pM2->pSuperBest->nFanLimit )
|
||||
return 1;
|
||||
// compare the number of leaves
|
||||
if ( pM1->pSuperBest->nFanins < pM2->pSuperBest->nFanins )
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if both phases are assigned, check if one of them can be dropped
|
||||
Map_NodeTryDroppingOnePhase( p, pNode );
|
||||
// set the arrival times of the node using the best cuts
|
||||
Map_NodeTransferArrivalTimes( p, pNode );
|
||||
|
||||
// update the progress bar
|
||||
Extra_ProgressBarUpdate( pProgress, i, "Matches ..." );
|
||||
if ( pM1->pSuperBest->nFanins > pM2->pSuperBest->nFanins )
|
||||
return 1;
|
||||
// otherwise prefer the old cut
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// compare the areas or area flows
|
||||
if ( pM1->AreaFlow < pM2->AreaFlow - pMan->fEpsilon )
|
||||
return 0;
|
||||
if ( pM1->AreaFlow > pM2->AreaFlow + pMan->fEpsilon )
|
||||
return 1;
|
||||
// compare the arrival times
|
||||
if ( pM1->tArrive.Worst < pM2->tArrive.Worst - pMan->fEpsilon )
|
||||
return 0;
|
||||
if ( pM1->tArrive.Worst > pM2->tArrive.Worst + pMan->fEpsilon )
|
||||
return 1;
|
||||
// compare the fanout limits
|
||||
if ( pM1->pSuperBest->nFanLimit > pM2->pSuperBest->nFanLimit )
|
||||
return 0;
|
||||
if ( pM1->pSuperBest->nFanLimit < pM2->pSuperBest->nFanLimit )
|
||||
return 1;
|
||||
// compare the number of leaves
|
||||
if ( pM1->pSuperBest->nFanins < pM2->pSuperBest->nFanins )
|
||||
return 0;
|
||||
if ( pM1->pSuperBest->nFanins > pM2->pSuperBest->nFanins )
|
||||
return 1;
|
||||
// otherwise prefer the old cut
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find the best matching of the cut.]
|
||||
|
||||
Description [The parameters: the node (pNode), the cut (pCut), the phase to be matched
|
||||
(fPhase), and the upper bound on the arrival times of the cut (fWorstLimit). This
|
||||
procedure goes through the matching supergates up to the phase assignment, and selects the
|
||||
best supergate, which will be used to map the cut. As a result of calling this procedure
|
||||
the matching information is written into pMatch.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, float fWorstLimit )
|
||||
{
|
||||
Map_Match_t MatchBest, * pMatch = pCut->M + fPhase;
|
||||
Map_Super_t * pSuper;
|
||||
int i, Counter;
|
||||
|
||||
// save the current match of the cut
|
||||
MatchBest = *pMatch;
|
||||
// go through the supergates
|
||||
for ( pSuper = pMatch->pSupers, Counter = 0; pSuper; pSuper = pSuper->pNext, Counter++ )
|
||||
{
|
||||
p->nMatches++;
|
||||
// this is an attempt to reduce the runtime of matching and area
|
||||
// at the cost of rare and very minor increase in delay
|
||||
// (the supergates are sorted by increasing area)
|
||||
if ( Counter == 30 )
|
||||
break;
|
||||
|
||||
// go through different phases of the given match and supergate
|
||||
pMatch->pSuperBest = pSuper;
|
||||
for ( i = 0; i < (int)pSuper->nPhases; i++ )
|
||||
{
|
||||
p->nPhases++;
|
||||
// find the overall phase of this match
|
||||
pMatch->uPhaseBest = pMatch->uPhase ^ pSuper->uPhases[i];
|
||||
if ( p->fMappingMode == 0 )
|
||||
{
|
||||
// get the arrival time
|
||||
Map_TimeCutComputeArrival( pNode, pCut, fPhase, fWorstLimit );
|
||||
// skip the cut if the arrival times exceed the required times
|
||||
if ( pMatch->tArrive.Worst > fWorstLimit + p->fEpsilon )
|
||||
continue;
|
||||
// get the area (area flow)
|
||||
pMatch->AreaFlow = Map_CutGetAreaFlow( pCut, fPhase );
|
||||
}
|
||||
else
|
||||
{
|
||||
// get the area (area flow)
|
||||
if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
|
||||
pMatch->AreaFlow = Map_CutGetAreaDerefed( pCut, fPhase );
|
||||
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 )
|
||||
continue;
|
||||
// get the arrival time
|
||||
Map_TimeCutComputeArrival( pNode, pCut, fPhase, fWorstLimit );
|
||||
// skip the cut if the arrival times exceed the required times
|
||||
if ( pMatch->tArrive.Worst > fWorstLimit + p->fEpsilon )
|
||||
continue;
|
||||
}
|
||||
|
||||
// if the cut is non-trivial, compare it
|
||||
if ( Map_MatchCompare( p, &MatchBest, pMatch, p->fMappingMode ) )
|
||||
{
|
||||
MatchBest = *pMatch;
|
||||
// if we are mapping for delay, the worst-case limit should be reduced
|
||||
if ( p->fMappingMode == 0 )
|
||||
fWorstLimit = MatchBest.tArrive.Worst;
|
||||
}
|
||||
}
|
||||
}
|
||||
// set the best match
|
||||
*pMatch = MatchBest;
|
||||
|
||||
// recompute the arrival time and area (area flow) of this cut
|
||||
if ( pMatch->pSuperBest )
|
||||
{
|
||||
Map_TimeCutComputeArrival( pNode, pCut, fPhase, MAP_FLOAT_LARGE );
|
||||
if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
|
||||
pMatch->AreaFlow = Map_CutGetAreaDerefed( pCut, fPhase );
|
||||
else if ( p->fMappingMode == 4 )
|
||||
pMatch->AreaFlow = Map_SwitchCutGetDerefed( pNode, pCut, fPhase );
|
||||
else
|
||||
pMatch->AreaFlow = Map_CutGetAreaFlow( pCut, fPhase );
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -249,187 +337,6 @@ int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase )
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find the best matching of the cut.]
|
||||
|
||||
Description [The parameters: the node (pNode), the cut (pCut), the phase to be matched
|
||||
(fPhase), and the upper bound on the arrival times of the cut (fWorstLimit). This
|
||||
procedure goes through the matching supergates up to the phase assignment, and selects the
|
||||
best supergate, which will be used to map the cut. As a result of calling this procedure
|
||||
the matching information is written into pMatch.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, float fWorstLimit )
|
||||
{
|
||||
Map_Match_t MatchBest, * pMatch = pCut->M + fPhase;
|
||||
Map_Super_t * pSuper;
|
||||
int i, Counter;
|
||||
|
||||
// save the current match of the cut
|
||||
MatchBest = *pMatch;
|
||||
// go through the supergates
|
||||
for ( pSuper = pMatch->pSupers, Counter = 0; pSuper; pSuper = pSuper->pNext, Counter++ )
|
||||
{
|
||||
p->nMatches++;
|
||||
// this is an attempt to reduce the runtime of matching and area
|
||||
// at the cost of rare and very minor increase in delay
|
||||
// (the supergates are sorted by increasing area)
|
||||
if ( Counter == 30 )
|
||||
break;
|
||||
|
||||
// go through different phases of the given match and supergate
|
||||
pMatch->pSuperBest = pSuper;
|
||||
for ( i = 0; i < (int)pSuper->nPhases; i++ )
|
||||
{
|
||||
p->nPhases++;
|
||||
// find the overall phase of this match
|
||||
pMatch->uPhaseBest = pMatch->uPhase ^ pSuper->uPhases[i];
|
||||
if ( p->fMappingMode == 0 )
|
||||
{
|
||||
// get the arrival time
|
||||
Map_TimeCutComputeArrival( pNode, pCut, fPhase, fWorstLimit );
|
||||
// skip the cut if the arrival times exceed the required times
|
||||
if ( pMatch->tArrive.Worst > fWorstLimit + p->fEpsilon )
|
||||
continue;
|
||||
// get the area (area flow)
|
||||
pMatch->AreaFlow = Map_CutGetAreaFlow( pCut, fPhase );
|
||||
}
|
||||
else
|
||||
{
|
||||
// get the area (area flow)
|
||||
if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
|
||||
pMatch->AreaFlow = Map_CutGetAreaDerefed( pCut, fPhase );
|
||||
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 )
|
||||
continue;
|
||||
// get the arrival time
|
||||
Map_TimeCutComputeArrival( pNode, pCut, fPhase, fWorstLimit );
|
||||
// skip the cut if the arrival times exceed the required times
|
||||
if ( pMatch->tArrive.Worst > fWorstLimit + p->fEpsilon )
|
||||
continue;
|
||||
}
|
||||
|
||||
// if the cut is non-trivial, compare it
|
||||
if ( Map_MatchCompare( p, &MatchBest, pMatch, p->fMappingMode ) )
|
||||
{
|
||||
MatchBest = *pMatch;
|
||||
// if we are mapping for delay, the worst-case limit should be reduced
|
||||
if ( p->fMappingMode == 0 )
|
||||
fWorstLimit = MatchBest.tArrive.Worst;
|
||||
}
|
||||
}
|
||||
}
|
||||
// set the best match
|
||||
*pMatch = MatchBest;
|
||||
|
||||
// recompute the arrival time and area (area flow) of this cut
|
||||
if ( pMatch->pSuperBest )
|
||||
{
|
||||
Map_TimeCutComputeArrival( pNode, pCut, fPhase, MAP_FLOAT_LARGE );
|
||||
if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
|
||||
pMatch->AreaFlow = Map_CutGetAreaDerefed( pCut, fPhase );
|
||||
else if ( p->fMappingMode == 4 )
|
||||
pMatch->AreaFlow = Map_SwitchCutGetDerefed( pNode, pCut, fPhase );
|
||||
else
|
||||
pMatch->AreaFlow = Map_CutGetAreaFlow( pCut, fPhase );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Cleans the match.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MatchClean( Map_Match_t * pMatch )
|
||||
{
|
||||
memset( pMatch, 0, sizeof(Map_Match_t) );
|
||||
pMatch->AreaFlow = MAP_FLOAT_LARGE; // unassigned
|
||||
pMatch->tArrive.Rise = MAP_FLOAT_LARGE; // unassigned
|
||||
pMatch->tArrive.Fall = MAP_FLOAT_LARGE; // unassigned
|
||||
pMatch->tArrive.Worst = MAP_FLOAT_LARGE; // unassigned
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compares two matches.]
|
||||
|
||||
Description [Returns 1 if the second match is better. Otherwise returns 0.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_MatchCompare( Map_Man_t * pMan, Map_Match_t * pM1, Map_Match_t * pM2, int fDoingArea )
|
||||
{
|
||||
if ( !fDoingArea )
|
||||
{
|
||||
// compare the arrival times
|
||||
if ( pM1->tArrive.Worst < pM2->tArrive.Worst - pMan->fEpsilon )
|
||||
return 0;
|
||||
if ( pM1->tArrive.Worst > pM2->tArrive.Worst + pMan->fEpsilon )
|
||||
return 1;
|
||||
// compare the areas or area flows
|
||||
if ( pM1->AreaFlow < pM2->AreaFlow - pMan->fEpsilon )
|
||||
return 0;
|
||||
if ( pM1->AreaFlow > pM2->AreaFlow + pMan->fEpsilon )
|
||||
return 1;
|
||||
// compare the fanout limits
|
||||
if ( pM1->pSuperBest->nFanLimit > pM2->pSuperBest->nFanLimit )
|
||||
return 0;
|
||||
if ( pM1->pSuperBest->nFanLimit < pM2->pSuperBest->nFanLimit )
|
||||
return 1;
|
||||
// compare the number of leaves
|
||||
if ( pM1->pSuperBest->nFanins < pM2->pSuperBest->nFanins )
|
||||
return 0;
|
||||
if ( pM1->pSuperBest->nFanins > pM2->pSuperBest->nFanins )
|
||||
return 1;
|
||||
// otherwise prefer the old cut
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// compare the areas or area flows
|
||||
if ( pM1->AreaFlow < pM2->AreaFlow - pMan->fEpsilon )
|
||||
return 0;
|
||||
if ( pM1->AreaFlow > pM2->AreaFlow + pMan->fEpsilon )
|
||||
return 1;
|
||||
// compare the arrival times
|
||||
if ( pM1->tArrive.Worst < pM2->tArrive.Worst - pMan->fEpsilon )
|
||||
return 0;
|
||||
if ( pM1->tArrive.Worst > pM2->tArrive.Worst + pMan->fEpsilon )
|
||||
return 1;
|
||||
// compare the fanout limits
|
||||
if ( pM1->pSuperBest->nFanLimit > pM2->pSuperBest->nFanLimit )
|
||||
return 0;
|
||||
if ( pM1->pSuperBest->nFanLimit < pM2->pSuperBest->nFanLimit )
|
||||
return 1;
|
||||
// compare the number of leaves
|
||||
if ( pM1->pSuperBest->nFanins < pM2->pSuperBest->nFanins )
|
||||
return 0;
|
||||
if ( pM1->pSuperBest->nFanins > pM2->pSuperBest->nFanins )
|
||||
return 1;
|
||||
// otherwise prefer the old cut
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets the PI arrival times.]
|
||||
|
|
@ -460,6 +367,25 @@ void Map_MappingSetPiArrivalTimes( Map_Man_t * p )
|
|||
}
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Computes the exact area associated with the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_TimeMatchWithInverter( Map_Man_t * p, Map_Match_t * pMatch )
|
||||
{
|
||||
Map_Time_t tArrInv;
|
||||
tArrInv.Fall = pMatch->tArrive.Rise + p->pSuperLib->tDelayInv.Fall;
|
||||
tArrInv.Rise = pMatch->tArrive.Fall + p->pSuperLib->tDelayInv.Rise;
|
||||
tArrInv.Worst = MAP_MAX( tArrInv.Rise, tArrInv.Fall );
|
||||
return tArrInv.Worst;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -609,6 +535,100 @@ void Map_NodeTransferArrivalTimes( Map_Man_t * p, Map_Node_t * pNode )
|
|||
assert( pNode->tArrival[1].Fall < pNode->tRequired[1].Fall + p->fEpsilon );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the best matches of the nodes.]
|
||||
|
||||
Description [Uses parameter p->fMappingMode to decide how to assign
|
||||
the matches for both polarities of the node. While the matches are
|
||||
being assigned, one of them may turn out to be better than the other
|
||||
(in terms of delay, for example). In this case, the worse match can
|
||||
be permanently dropped, and the corresponding pointer set to NULL.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_MappingMatches( Map_Man_t * p )
|
||||
{
|
||||
ProgressBar * pProgress;
|
||||
Map_Node_t * pNode;
|
||||
int i;
|
||||
|
||||
assert( p->fMappingMode >= 0 && p->fMappingMode <= 4 );
|
||||
|
||||
// use the externally given PI arrival times
|
||||
if ( p->fMappingMode == 0 )
|
||||
Map_MappingSetPiArrivalTimes( p );
|
||||
|
||||
// estimate the fanouts
|
||||
if ( p->fMappingMode == 0 )
|
||||
Map_MappingEstimateRefsInit( p );
|
||||
else if ( p->fMappingMode == 1 )
|
||||
Map_MappingEstimateRefs( p );
|
||||
|
||||
// the PI cuts are matched in the cut computation package
|
||||
// in the loop below we match the internal nodes
|
||||
pProgress = Extra_ProgressBarStart( stdout, p->vMapObjs->nSize );
|
||||
for ( i = 0; i < p->vMapObjs->nSize; i++ )
|
||||
{
|
||||
pNode = p->vMapObjs->pArray[i];
|
||||
if ( Map_NodeIsBuf(pNode) )
|
||||
{
|
||||
assert( pNode->p2 == NULL );
|
||||
pNode->tArrival[0] = Map_Regular(pNode->p1)->tArrival[ Map_IsComplement(pNode->p1)];
|
||||
pNode->tArrival[1] = Map_Regular(pNode->p1)->tArrival[!Map_IsComplement(pNode->p1)];
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip primary inputs and secondary nodes if mapping with choices
|
||||
if ( !Map_NodeIsAnd( pNode ) || pNode->pRepr )
|
||||
continue;
|
||||
|
||||
// make sure that at least one non-trival cut is present
|
||||
if ( pNode->pCuts->pNext == NULL )
|
||||
{
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
printf( "\nError: A node in the mapping graph does not have feasible cuts.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// match negative phase
|
||||
if ( !Map_MatchNodePhase( p, pNode, 0 ) )
|
||||
{
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
return 0;
|
||||
}
|
||||
// match positive phase
|
||||
if ( !Map_MatchNodePhase( p, pNode, 1 ) )
|
||||
{
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// make sure that at least one phase is mapped
|
||||
if ( pNode->pCutBest[0] == NULL && pNode->pCutBest[1] == NULL )
|
||||
{
|
||||
printf( "\nError: Could not match both phases of AIG node %d.\n", pNode->Num );
|
||||
printf( "Please make sure that the supergate library has equivalents of AND2 or NAND2.\n" );
|
||||
printf( "If such supergates exist in the library, report a bug.\n" );
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if both phases are assigned, check if one of them can be dropped
|
||||
Map_NodeTryDroppingOnePhase( p, pNode );
|
||||
// set the arrival times of the node using the best cuts
|
||||
Map_NodeTransferArrivalTimes( p, pNode );
|
||||
|
||||
// update the progress bar
|
||||
Extra_ProgressBarUpdate( pProgress, i, "Matches ..." );
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -25,11 +25,6 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Map_NodeIncRefPhaseAct( Map_Node_t * pNode, int fPhase );
|
||||
static int Map_NodeDecRefPhaseAct( Map_Node_t * pNode, int fPhase );
|
||||
static float Map_CutRefDeref( Map_Cut_t * pCut, int fPhase, int fReference );
|
||||
static void Map_MappingSetRefs_rec( Map_Man_t * pMan, Map_Node_t * pNode, Map_Node_t ** ppStore );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -132,9 +127,9 @@ void Map_MappingEstimateRefsInit( Map_Man_t * p )
|
|||
{
|
||||
Map_Node_t * pNode;
|
||||
int i;
|
||||
for ( i = 0; i < p->vAnds->nSize; i++ )
|
||||
for ( i = 0; i < p->vMapObjs->nSize; i++ )
|
||||
{
|
||||
pNode = p->vAnds->pArray[i];
|
||||
pNode = p->vMapObjs->pArray[i];
|
||||
// pNode->nRefEst[0] = pNode->nRefEst[1] = ((float)pNode->nRefs)*(float)2.0;
|
||||
pNode->nRefEst[0] = pNode->nRefEst[1] = pNode->nRefEst[2] = ((float)pNode->nRefs);
|
||||
}
|
||||
|
|
@ -157,9 +152,9 @@ void Map_MappingEstimateRefs( Map_Man_t * p )
|
|||
{
|
||||
Map_Node_t * pNode;
|
||||
int i;
|
||||
for ( i = 0; i < p->vAnds->nSize; i++ )
|
||||
for ( i = 0; i < p->vMapObjs->nSize; i++ )
|
||||
{
|
||||
pNode = p->vAnds->pArray[i];
|
||||
pNode = p->vMapObjs->pArray[i];
|
||||
// pNode->nRefEst[0] = (float)((2.0 * pNode->nRefEst[0] + 1.0 * pNode->nRefAct[0]) / 3.0);
|
||||
// pNode->nRefEst[1] = (float)((2.0 * pNode->nRefEst[1] + 1.0 * pNode->nRefAct[1]) / 3.0);
|
||||
// pNode->nRefEst[2] = (float)((2.0 * pNode->nRefEst[2] + 1.0 * pNode->nRefAct[2]) / 3.0);
|
||||
|
|
@ -169,10 +164,6 @@ void Map_MappingEstimateRefs( Map_Man_t * p )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Computes the area flow of the cut.]
|
||||
|
|
@ -223,79 +214,6 @@ float Map_CutGetAreaFlow( Map_Cut_t * pCut, int fPhase )
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Computes the exact area associated with the cut.]
|
||||
|
||||
description [Assumes that the cut is referenced.]
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_CutGetAreaRefed( Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
float aResult, aResult2;
|
||||
aResult2 = Map_CutRefDeref( pCut, fPhase, 0 ); // dereference
|
||||
aResult = Map_CutRefDeref( pCut, fPhase, 1 ); // reference
|
||||
// assert( aResult == aResult2 );
|
||||
return aResult;
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Computes the exact area associated with the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_CutGetAreaDerefed( Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
float aResult, aResult2;
|
||||
aResult2 = Map_CutRefDeref( pCut, fPhase, 1 ); // reference
|
||||
aResult = Map_CutRefDeref( pCut, fPhase, 0 ); // dereference
|
||||
// assert( aResult == aResult2 );
|
||||
return aResult;
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [References the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_CutRef( Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
return Map_CutRefDeref( pCut, fPhase, 1 ); // reference
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Dereferences the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_CutDeref( Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
return Map_CutRefDeref( pCut, fPhase, 0 ); // dereference
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [References or dereferences the cut.]
|
||||
|
|
@ -396,7 +314,77 @@ float Map_CutRefDeref( Map_Cut_t * pCut, int fPhase, int fReference )
|
|||
return aArea;
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Computes the exact area associated with the cut.]
|
||||
|
||||
description [Assumes that the cut is referenced.]
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_CutGetAreaRefed( Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
float aResult, aResult2;
|
||||
aResult2 = Map_CutRefDeref( pCut, fPhase, 0 ); // dereference
|
||||
aResult = Map_CutRefDeref( pCut, fPhase, 1 ); // reference
|
||||
// assert( aResult == aResult2 );
|
||||
return aResult;
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Computes the exact area associated with the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_CutGetAreaDerefed( Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
float aResult, aResult2;
|
||||
aResult2 = Map_CutRefDeref( pCut, fPhase, 1 ); // reference
|
||||
aResult = Map_CutRefDeref( pCut, fPhase, 0 ); // dereference
|
||||
// assert( aResult == aResult2 );
|
||||
return aResult;
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [References the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_CutRef( Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
return Map_CutRefDeref( pCut, fPhase, 1 ); // reference
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Dereferences the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_CutDeref( Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
return Map_CutRefDeref( pCut, fPhase, 0 ); // dereference
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -412,82 +400,29 @@ float Map_CutRefDeref( Map_Cut_t * pCut, int fPhase, int fReference )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MappingSetRefs( Map_Man_t * pMan )
|
||||
{
|
||||
Map_Node_t * pNode, ** ppStore;
|
||||
int i, fPhase, LevelMax;
|
||||
|
||||
// clean all references
|
||||
for ( i = 0; i < pMan->vNodesAll->nSize; i++ )
|
||||
{
|
||||
pNode = pMan->vNodesAll->pArray[i];
|
||||
pNode->nRefAct[0] = 0;
|
||||
pNode->nRefAct[1] = 0;
|
||||
pNode->nRefAct[2] = 0;
|
||||
}
|
||||
|
||||
// find the largest level of a node
|
||||
LevelMax = 0;
|
||||
for ( i = 0; i < pMan->nOutputs; i++ )
|
||||
if ( LevelMax < (int)Map_Regular(pMan->pOutputs[i])->Level )
|
||||
LevelMax = Map_Regular(pMan->pOutputs[i])->Level;
|
||||
|
||||
// allocate place to store the nodes
|
||||
ppStore = ABC_ALLOC( Map_Node_t *, LevelMax + 1 );
|
||||
memset( ppStore, 0, sizeof(Map_Node_t *) * (LevelMax + 1) );
|
||||
|
||||
// visit nodes reachable from POs in the DFS order through the best cuts
|
||||
for ( i = 0; i < pMan->nOutputs; i++ )
|
||||
{
|
||||
pNode = pMan->pOutputs[i];
|
||||
fPhase = !Map_IsComplement(pNode);
|
||||
if ( !Map_NodeIsConst(pNode) )
|
||||
Map_MappingSetRefs_rec( pMan, pNode, ppStore );
|
||||
}
|
||||
|
||||
// reconnect the nodes in reverse topological order
|
||||
pMan->vMapping->nSize = 0;
|
||||
for ( i = LevelMax; i >= 0; i-- )
|
||||
for ( pNode = ppStore[i]; pNode; pNode = (Map_Node_t *)pNode->pData0 )
|
||||
Map_NodeVecPush( pMan->vMapping, pNode );
|
||||
ABC_FREE( ppStore );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively computes the DFS ordering of the nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MappingSetRefs_rec( Map_Man_t * pMan, Map_Node_t * pNode, Map_Node_t ** ppStore )
|
||||
void Map_MappingSetRefs_rec( Map_Man_t * pMan, Map_Node_t * pNode )
|
||||
{
|
||||
Map_Cut_t * pCut;
|
||||
Map_Node_t * pNodeR;
|
||||
unsigned uPhase;
|
||||
int i, fPhase, fInvPin;
|
||||
|
||||
// get the regular node and its phase
|
||||
pNodeR = Map_Regular(pNode);
|
||||
fPhase = !Map_IsComplement(pNode);
|
||||
|
||||
// add the node to the list of all visited nodes
|
||||
if ( pNodeR->nRefAct[2]++ == 0 )
|
||||
// Map_NodeVecPush( pMan->vMapping, pNodeR );
|
||||
pNodeR->pData0 = (char *)ppStore[pNodeR->Level], ppStore[pNodeR->Level] = pNodeR;
|
||||
|
||||
pNodeR->nRefAct[2]++;
|
||||
// quit if the node was already visited in this phase
|
||||
if ( pNodeR->nRefAct[fPhase]++ )
|
||||
return;
|
||||
|
||||
// quit if this is a PI node
|
||||
if ( Map_NodeIsVar(pNodeR) )
|
||||
return;
|
||||
|
||||
// propagate through buffer
|
||||
if ( Map_NodeIsBuf(pNodeR) )
|
||||
{
|
||||
Map_MappingSetRefs_rec( pMan, Map_NotCond(pNodeR->p1, Map_IsComplement(pNode)) );
|
||||
return;
|
||||
}
|
||||
assert( Map_NodeIsAnd(pNode) );
|
||||
// get the cut implementing this or opposite polarity
|
||||
pCut = pNodeR->pCutBest[fPhase];
|
||||
if ( pCut == NULL )
|
||||
|
|
@ -495,13 +430,32 @@ void Map_MappingSetRefs_rec( Map_Man_t * pMan, Map_Node_t * pNode, Map_Node_t **
|
|||
fPhase = !fPhase;
|
||||
pCut = pNodeR->pCutBest[fPhase];
|
||||
}
|
||||
|
||||
// visit the transitive fanin
|
||||
uPhase = pCut->M[fPhase].uPhaseBest;
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
{
|
||||
fInvPin = ((uPhase & (1 << i)) > 0);
|
||||
Map_MappingSetRefs_rec( pMan, Map_NotCond(pCut->ppLeaves[i], fInvPin), ppStore );
|
||||
Map_MappingSetRefs_rec( pMan, Map_NotCond(pCut->ppLeaves[i], fInvPin) );
|
||||
}
|
||||
}
|
||||
void Map_MappingSetRefs( Map_Man_t * pMan )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
int i;
|
||||
// clean all references
|
||||
for ( i = 0; i < pMan->vMapObjs->nSize; i++ )
|
||||
{
|
||||
pNode = pMan->vMapObjs->pArray[i];
|
||||
pNode->nRefAct[0] = 0;
|
||||
pNode->nRefAct[1] = 0;
|
||||
pNode->nRefAct[2] = 0;
|
||||
}
|
||||
// visit nodes reachable from POs in the DFS order through the best cuts
|
||||
for ( i = 0; i < pMan->nOutputs; i++ )
|
||||
{
|
||||
pNode = pMan->pOutputs[i];
|
||||
if ( !Map_NodeIsConst(pNode) )
|
||||
Map_MappingSetRefs_rec( pMan, pNode );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -517,15 +471,18 @@ void Map_MappingSetRefs_rec( Map_Man_t * pMan, Map_Node_t * pNode, Map_Node_t **
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_MappingGetArea( Map_Man_t * pMan, Map_NodeVec_t * vMapping )
|
||||
float Map_MappingGetArea( Map_Man_t * pMan )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
float Area;
|
||||
float Area = 0.0;
|
||||
int i;
|
||||
Area = 0.0;
|
||||
for ( i = 0; i < vMapping->nSize; i++ )
|
||||
for ( i = 0; i < pMan->vMapObjs->nSize; i++ )
|
||||
{
|
||||
pNode = vMapping->pArray[i];
|
||||
pNode = pMan->vMapObjs->pArray[i];
|
||||
if ( pNode->nRefAct[2] == 0 )
|
||||
continue;
|
||||
if ( Map_NodeIsBuf(pNode) )
|
||||
continue;
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -184,15 +184,16 @@ float Map_SwitchCutRefDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, i
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_MappingGetSwitching( Map_Man_t * pMan, Map_NodeVec_t * vMapping )
|
||||
float Map_MappingGetSwitching( Map_Man_t * pMan )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
float Switch;
|
||||
float Switch = 0.0;
|
||||
int i;
|
||||
Switch = 0.0;
|
||||
for ( i = 0; i < vMapping->nSize; i++ )
|
||||
for ( i = 0; i < pMan->vMapObjs->nSize; i++ )
|
||||
{
|
||||
pNode = vMapping->pArray[i];
|
||||
pNode = pMan->vMapObjs->pArray[i];
|
||||
if ( pNode->nRefAct[2] == 0 )
|
||||
continue;
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -20,63 +20,40 @@
|
|||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Map_TimePropagateRequired( Map_Man_t * p, Map_NodeVec_t * vNodes );
|
||||
static void Map_TimePropagateRequiredPhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase );
|
||||
static float Map_MatchComputeReqTimes( Map_Cut_t * pCut, int fPhase, Map_Time_t * ptArrRes );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Computes the exact area associated with the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_TimeMatchWithInverter( Map_Man_t * p, Map_Match_t * pMatch )
|
||||
{
|
||||
Map_Time_t tArrInv;
|
||||
tArrInv.Fall = pMatch->tArrive.Rise + p->pSuperLib->tDelayInv.Fall;
|
||||
tArrInv.Rise = pMatch->tArrive.Fall + p->pSuperLib->tDelayInv.Rise;
|
||||
tArrInv.Worst = MAP_MAX( tArrInv.Rise, tArrInv.Fall );
|
||||
return tArrInv.Worst;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the arrival times of the cut recursively.]
|
||||
Synopsis [Computes the maximum arrival times.]
|
||||
|
||||
Description [When computing the arrival time for the previously unused
|
||||
cuts, their arrival time may be incorrect because their fanins have
|
||||
incorrect arrival time. This procedure is called to fix this problem.]
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TimeCutComputeArrival_rec( Map_Cut_t * pCut, int fPhase )
|
||||
float Map_TimeComputeArrivalMax( Map_Man_t * p )
|
||||
{
|
||||
int i, fPhaseLeaf;
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
float tReqMax, tReq;
|
||||
int i, fPhase;
|
||||
// get the critical PO arrival time
|
||||
tReqMax = -MAP_FLOAT_LARGE;
|
||||
for ( i = 0; i < p->nOutputs; i++ )
|
||||
{
|
||||
fPhaseLeaf = Map_CutGetLeafPhase( pCut, fPhase, i );
|
||||
if ( pCut->ppLeaves[i]->nRefAct[fPhaseLeaf] > 0 )
|
||||
if ( Map_NodeIsConst(p->pOutputs[i]) )
|
||||
continue;
|
||||
Map_TimeCutComputeArrival_rec( pCut->ppLeaves[i]->pCutBest[fPhaseLeaf], fPhaseLeaf );
|
||||
fPhase = !Map_IsComplement(p->pOutputs[i]);
|
||||
tReq = Map_Regular(p->pOutputs[i])->tArrival[fPhase].Worst;
|
||||
tReqMax = MAP_MAX( tReqMax, tReq );
|
||||
}
|
||||
Map_TimeCutComputeArrival( NULL, pCut, fPhase, MAP_FLOAT_LARGE );
|
||||
return tReqMax;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -160,217 +137,7 @@ float Map_TimeCutComputeArrival( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhas
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the maximum arrival times.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_TimeComputeArrivalMax( Map_Man_t * p )
|
||||
{
|
||||
float tReqMax, tReq;
|
||||
int i, fPhase;
|
||||
// get the critical PO arrival time
|
||||
tReqMax = -MAP_FLOAT_LARGE;
|
||||
for ( i = 0; i < p->nOutputs; i++ )
|
||||
{
|
||||
if ( Map_NodeIsConst(p->pOutputs[i]) )
|
||||
continue;
|
||||
fPhase = !Map_IsComplement(p->pOutputs[i]);
|
||||
tReq = Map_Regular(p->pOutputs[i])->tArrival[fPhase].Worst;
|
||||
tReqMax = MAP_MAX( tReqMax, tReq );
|
||||
}
|
||||
return tReqMax;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the required times of all nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TimeComputeRequiredGlobal( Map_Man_t * p )
|
||||
{
|
||||
p->fRequiredGlo = Map_TimeComputeArrivalMax( p );
|
||||
// update the required times according to the target
|
||||
if ( p->DelayTarget != -1 )
|
||||
{
|
||||
if ( p->fRequiredGlo > p->DelayTarget + p->fEpsilon )
|
||||
{
|
||||
if ( p->fMappingMode == 1 )
|
||||
printf( "Cannot meet the target required times (%4.2f). Continue anyway.\n", p->DelayTarget );
|
||||
}
|
||||
else if ( p->fRequiredGlo < p->DelayTarget - p->fEpsilon )
|
||||
{
|
||||
if ( p->fMappingMode == 1 && p->fVerbose )
|
||||
printf( "Relaxing the required times from (%4.2f) to the target (%4.2f).\n", p->fRequiredGlo, p->DelayTarget );
|
||||
p->fRequiredGlo = p->DelayTarget;
|
||||
}
|
||||
}
|
||||
Map_TimeComputeRequired( p, p->fRequiredGlo );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the required times of all nodes.]
|
||||
|
||||
Description [This procedure assumes that the nodes used in the mapping
|
||||
are collected in p->vMapping.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TimeComputeRequired( Map_Man_t * p, float fRequired )
|
||||
{
|
||||
Map_Time_t * ptTime, * ptTimeA;
|
||||
int fPhase, i;
|
||||
|
||||
// clean the required times
|
||||
for ( i = 0; i < p->vAnds->nSize; i++ )
|
||||
{
|
||||
p->vAnds->pArray[i]->tRequired[0].Rise = MAP_FLOAT_LARGE;
|
||||
p->vAnds->pArray[i]->tRequired[0].Fall = MAP_FLOAT_LARGE;
|
||||
p->vAnds->pArray[i]->tRequired[0].Worst = MAP_FLOAT_LARGE;
|
||||
p->vAnds->pArray[i]->tRequired[1].Rise = MAP_FLOAT_LARGE;
|
||||
p->vAnds->pArray[i]->tRequired[1].Fall = MAP_FLOAT_LARGE;
|
||||
p->vAnds->pArray[i]->tRequired[1].Worst = MAP_FLOAT_LARGE;
|
||||
}
|
||||
|
||||
// set the required times for the POs
|
||||
for ( i = 0; i < p->nOutputs; i++ )
|
||||
{
|
||||
fPhase = !Map_IsComplement(p->pOutputs[i]);
|
||||
ptTime = Map_Regular(p->pOutputs[i])->tRequired + fPhase;
|
||||
ptTimeA = Map_Regular(p->pOutputs[i])->tArrival + fPhase;
|
||||
|
||||
// if external required time can be achieved, use it
|
||||
if ( p->pOutputRequireds && p->pOutputRequireds[i].Worst > 0 && ptTimeA->Worst <= p->pOutputRequireds[i].Worst )//&& p->pOutputRequireds[i].Worst <= fRequired )
|
||||
ptTime->Rise = ptTime->Fall = ptTime->Worst = p->pOutputRequireds[i].Worst;
|
||||
// if external required cannot be achieved, set the earliest possible arrival time
|
||||
else if ( p->pOutputRequireds && p->pOutputRequireds[i].Worst > 0 && ptTimeA->Worst > p->pOutputRequireds[i].Worst )
|
||||
ptTime->Rise = ptTime->Fall = ptTime->Worst = ptTimeA->Worst;
|
||||
// otherwise, set the global required time
|
||||
else
|
||||
ptTime->Rise = ptTime->Fall = ptTime->Worst = fRequired;
|
||||
}
|
||||
|
||||
// sorts the nodes in the decreasing order of levels
|
||||
// this puts the nodes in reverse topological order
|
||||
// Map_MappingSortByLevel( p, p->vMapping );
|
||||
// the array is already sorted by construction in Map_MappingSetRefs()
|
||||
|
||||
Map_TimePropagateRequired( p, p->vMapping );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the required times of the given nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TimePropagateRequired( Map_Man_t * p, Map_NodeVec_t * vNodes )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
Map_Time_t tReqOutTest, * ptReqOutTest = &tReqOutTest;
|
||||
Map_Time_t * ptReqIn, * ptReqOut;
|
||||
int fPhase, k;
|
||||
|
||||
// go through the nodes in the reverse topological order
|
||||
for ( k = 0; k < vNodes->nSize; k++ )
|
||||
{
|
||||
pNode = vNodes->pArray[k];
|
||||
|
||||
// this computation works for regular nodes only
|
||||
assert( !Map_IsComplement(pNode) );
|
||||
// at least one phase should be mapped
|
||||
assert( pNode->pCutBest[0] != NULL || pNode->pCutBest[1] != NULL );
|
||||
// the node should be used in the currently assigned mapping
|
||||
assert( pNode->nRefAct[0] > 0 || pNode->nRefAct[1] > 0 );
|
||||
|
||||
// if one of the cuts is not given, project the required times from the other cut
|
||||
if ( pNode->pCutBest[0] == NULL || pNode->pCutBest[1] == NULL )
|
||||
{
|
||||
// assert( 0 );
|
||||
// get the missing phase
|
||||
fPhase = (pNode->pCutBest[1] == NULL);
|
||||
// check if the missing phase is needed in the mapping
|
||||
if ( pNode->nRefAct[fPhase] > 0 )
|
||||
{
|
||||
// get the pointers to the required times of the missing phase
|
||||
ptReqOut = pNode->tRequired + fPhase;
|
||||
// assert( ptReqOut->Fall < MAP_FLOAT_LARGE );
|
||||
// get the pointers to the required times of the present phase
|
||||
ptReqIn = pNode->tRequired + !fPhase;
|
||||
// propagate the required times from the missing phase to the present phase
|
||||
// tArrInv.Fall = pMatch->tArrive.Rise + p->pSuperLib->tDelayInv.Fall;
|
||||
// tArrInv.Rise = pMatch->tArrive.Fall + p->pSuperLib->tDelayInv.Rise;
|
||||
ptReqIn->Fall = MAP_MIN( ptReqIn->Fall, ptReqOut->Rise - p->pSuperLib->tDelayInv.Rise );
|
||||
ptReqIn->Rise = MAP_MIN( ptReqIn->Rise, ptReqOut->Fall - p->pSuperLib->tDelayInv.Fall );
|
||||
}
|
||||
}
|
||||
|
||||
// finalize the worst case computation
|
||||
pNode->tRequired[0].Worst = MAP_MIN( pNode->tRequired[0].Fall, pNode->tRequired[0].Rise );
|
||||
pNode->tRequired[1].Worst = MAP_MIN( pNode->tRequired[1].Fall, pNode->tRequired[1].Rise );
|
||||
|
||||
// skip the PIs
|
||||
if ( !Map_NodeIsAnd(pNode) )
|
||||
continue;
|
||||
|
||||
// propagate required times of different phases of the node
|
||||
// the ordering of phases does not matter since they are mapped independently
|
||||
if ( pNode->pCutBest[0] && pNode->tRequired[0].Worst < MAP_FLOAT_LARGE )
|
||||
Map_TimePropagateRequiredPhase( p, pNode, 0 );
|
||||
if ( pNode->pCutBest[1] && pNode->tRequired[1].Worst < MAP_FLOAT_LARGE )
|
||||
Map_TimePropagateRequiredPhase( p, pNode, 1 );
|
||||
}
|
||||
|
||||
// in the end, we verify the required times
|
||||
// for this, we compute the arrival times of the outputs of each phase
|
||||
// of the supergates using the fanins' required times as the fanins' arrival times
|
||||
// the resulting arrival time of the supergate should be less than the actual required time
|
||||
for ( k = 0; k < vNodes->nSize; k++ )
|
||||
{
|
||||
pNode = vNodes->pArray[k];
|
||||
if ( !Map_NodeIsAnd(pNode) )
|
||||
continue;
|
||||
// verify that the required times are propagated correctly
|
||||
// if ( pNode->pCutBest[0] && (pNode->nRefAct[0] > 0 || pNode->pCutBest[1] == NULL) )
|
||||
if ( pNode->pCutBest[0] && pNode->tRequired[0].Worst < MAP_FLOAT_LARGE/2 )
|
||||
{
|
||||
Map_MatchComputeReqTimes( pNode->pCutBest[0], 0, ptReqOutTest );
|
||||
// assert( ptReqOutTest->Rise < pNode->tRequired[0].Rise + p->fEpsilon );
|
||||
// assert( ptReqOutTest->Fall < pNode->tRequired[0].Fall + p->fEpsilon );
|
||||
}
|
||||
// if ( pNode->pCutBest[1] && (pNode->nRefAct[1] > 0 || pNode->pCutBest[0] == NULL) )
|
||||
if ( pNode->pCutBest[1] && pNode->tRequired[1].Worst < MAP_FLOAT_LARGE/2 )
|
||||
{
|
||||
Map_MatchComputeReqTimes( pNode->pCutBest[1], 1, ptReqOutTest );
|
||||
// assert( ptReqOutTest->Rise < pNode->tRequired[1].Rise + p->fEpsilon );
|
||||
// assert( ptReqOutTest->Fall < pNode->tRequired[1].Fall + p->fEpsilon );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the required times of the given nodes.]
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -446,20 +213,6 @@ void Map_TimePropagateRequiredPhase( Map_Man_t * p, Map_Node_t * pNode, int fPha
|
|||
assert( pNode->tArrival[fPhase].Rise < ptReqOut->Rise + p->fEpsilon );
|
||||
assert( pNode->tArrival[fPhase].Fall < ptReqOut->Fall + p->fEpsilon );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the arrival times of the cut.]
|
||||
|
||||
Description [Computes the arrival times of the cut if it is implemented using
|
||||
the given supergate with the given phase. Uses the constraint-type specification
|
||||
of rise/fall arrival times.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_MatchComputeReqTimes( Map_Cut_t * pCut, int fPhase, Map_Time_t * ptArrRes )
|
||||
{
|
||||
Map_Time_t * ptArrIn;
|
||||
|
|
@ -518,6 +271,164 @@ float Map_MatchComputeReqTimes( Map_Cut_t * pCut, int fPhase, Map_Time_t * ptArr
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the required times of all nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TimePropagateRequired( Map_Man_t * p )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
Map_Time_t tReqOutTest, * ptReqOutTest = &tReqOutTest;
|
||||
Map_Time_t * ptReqIn, * ptReqOut;
|
||||
int fPhase, k;
|
||||
|
||||
// go through the nodes in the reverse topological order
|
||||
for ( k = p->vMapObjs->nSize - 1; k >= 0; k-- )
|
||||
{
|
||||
pNode = p->vMapObjs->pArray[k];
|
||||
if ( pNode->nRefAct[2] == 0 )
|
||||
continue;
|
||||
|
||||
// propagate required times through the buffer
|
||||
if ( Map_NodeIsBuf(pNode) )
|
||||
{
|
||||
assert( pNode->p2 == NULL );
|
||||
Map_Regular(pNode->p1)->tRequired[ Map_IsComplement(pNode->p1)] = pNode->tRequired[0];
|
||||
Map_Regular(pNode->p1)->tRequired[!Map_IsComplement(pNode->p1)] = pNode->tRequired[1];
|
||||
continue;
|
||||
}
|
||||
|
||||
// this computation works for regular nodes only
|
||||
assert( !Map_IsComplement(pNode) );
|
||||
// at least one phase should be mapped
|
||||
assert( pNode->pCutBest[0] != NULL || pNode->pCutBest[1] != NULL );
|
||||
// the node should be used in the currently assigned mapping
|
||||
assert( pNode->nRefAct[0] > 0 || pNode->nRefAct[1] > 0 );
|
||||
|
||||
// if one of the cuts is not given, project the required times from the other cut
|
||||
if ( pNode->pCutBest[0] == NULL || pNode->pCutBest[1] == NULL )
|
||||
{
|
||||
// assert( 0 );
|
||||
// get the missing phase
|
||||
fPhase = (pNode->pCutBest[1] == NULL);
|
||||
// check if the missing phase is needed in the mapping
|
||||
if ( pNode->nRefAct[fPhase] > 0 )
|
||||
{
|
||||
// get the pointers to the required times of the missing phase
|
||||
ptReqOut = pNode->tRequired + fPhase;
|
||||
// assert( ptReqOut->Fall < MAP_FLOAT_LARGE );
|
||||
// get the pointers to the required times of the present phase
|
||||
ptReqIn = pNode->tRequired + !fPhase;
|
||||
// propagate the required times from the missing phase to the present phase
|
||||
// tArrInv.Fall = pMatch->tArrive.Rise + p->pSuperLib->tDelayInv.Fall;
|
||||
// tArrInv.Rise = pMatch->tArrive.Fall + p->pSuperLib->tDelayInv.Rise;
|
||||
ptReqIn->Fall = MAP_MIN( ptReqIn->Fall, ptReqOut->Rise - p->pSuperLib->tDelayInv.Rise );
|
||||
ptReqIn->Rise = MAP_MIN( ptReqIn->Rise, ptReqOut->Fall - p->pSuperLib->tDelayInv.Fall );
|
||||
}
|
||||
}
|
||||
|
||||
// finalize the worst case computation
|
||||
pNode->tRequired[0].Worst = MAP_MIN( pNode->tRequired[0].Fall, pNode->tRequired[0].Rise );
|
||||
pNode->tRequired[1].Worst = MAP_MIN( pNode->tRequired[1].Fall, pNode->tRequired[1].Rise );
|
||||
|
||||
// skip the PIs
|
||||
if ( !Map_NodeIsAnd(pNode) )
|
||||
continue;
|
||||
|
||||
// propagate required times of different phases of the node
|
||||
// the ordering of phases does not matter since they are mapped independently
|
||||
if ( pNode->pCutBest[0] && pNode->tRequired[0].Worst < MAP_FLOAT_LARGE )
|
||||
Map_TimePropagateRequiredPhase( p, pNode, 0 );
|
||||
if ( pNode->pCutBest[1] && pNode->tRequired[1].Worst < MAP_FLOAT_LARGE )
|
||||
Map_TimePropagateRequiredPhase( p, pNode, 1 );
|
||||
}
|
||||
|
||||
// in the end, we verify the required times
|
||||
// for this, we compute the arrival times of the outputs of each phase
|
||||
// of the supergates using the fanins' required times as the fanins' arrival times
|
||||
// the resulting arrival time of the supergate should be less than the actual required time
|
||||
for ( k = p->vMapObjs->nSize - 1; k >= 0; k-- )
|
||||
{
|
||||
pNode = p->vMapObjs->pArray[k];
|
||||
if ( pNode->nRefAct[2] == 0 )
|
||||
continue;
|
||||
if ( !Map_NodeIsAnd(pNode) )
|
||||
continue;
|
||||
// verify that the required times are propagated correctly
|
||||
// if ( pNode->pCutBest[0] && (pNode->nRefAct[0] > 0 || pNode->pCutBest[1] == NULL) )
|
||||
if ( pNode->pCutBest[0] && pNode->tRequired[0].Worst < MAP_FLOAT_LARGE/2 )
|
||||
{
|
||||
Map_MatchComputeReqTimes( pNode->pCutBest[0], 0, ptReqOutTest );
|
||||
// assert( ptReqOutTest->Rise < pNode->tRequired[0].Rise + p->fEpsilon );
|
||||
// assert( ptReqOutTest->Fall < pNode->tRequired[0].Fall + p->fEpsilon );
|
||||
}
|
||||
// if ( pNode->pCutBest[1] && (pNode->nRefAct[1] > 0 || pNode->pCutBest[0] == NULL) )
|
||||
if ( pNode->pCutBest[1] && pNode->tRequired[1].Worst < MAP_FLOAT_LARGE/2 )
|
||||
{
|
||||
Map_MatchComputeReqTimes( pNode->pCutBest[1], 1, ptReqOutTest );
|
||||
// assert( ptReqOutTest->Rise < pNode->tRequired[1].Rise + p->fEpsilon );
|
||||
// assert( ptReqOutTest->Fall < pNode->tRequired[1].Fall + p->fEpsilon );
|
||||
}
|
||||
}
|
||||
}
|
||||
void Map_TimeComputeRequiredGlobal( Map_Man_t * p )
|
||||
{
|
||||
Map_Time_t * ptTime, * ptTimeA;
|
||||
int fPhase, i;
|
||||
// update the required times according to the target
|
||||
p->fRequiredGlo = Map_TimeComputeArrivalMax( p );
|
||||
if ( p->DelayTarget != -1 )
|
||||
{
|
||||
if ( p->fRequiredGlo > p->DelayTarget + p->fEpsilon )
|
||||
{
|
||||
if ( p->fMappingMode == 1 )
|
||||
printf( "Cannot meet the target required times (%4.2f). Continue anyway.\n", p->DelayTarget );
|
||||
}
|
||||
else if ( p->fRequiredGlo < p->DelayTarget - p->fEpsilon )
|
||||
{
|
||||
if ( p->fMappingMode == 1 && p->fVerbose )
|
||||
printf( "Relaxing the required times from (%4.2f) to the target (%4.2f).\n", p->fRequiredGlo, p->DelayTarget );
|
||||
p->fRequiredGlo = p->DelayTarget;
|
||||
}
|
||||
}
|
||||
// clean the required times
|
||||
for ( i = 0; i < p->vMapObjs->nSize; i++ )
|
||||
{
|
||||
p->vMapObjs->pArray[i]->tRequired[0].Rise = MAP_FLOAT_LARGE;
|
||||
p->vMapObjs->pArray[i]->tRequired[0].Fall = MAP_FLOAT_LARGE;
|
||||
p->vMapObjs->pArray[i]->tRequired[0].Worst = MAP_FLOAT_LARGE;
|
||||
p->vMapObjs->pArray[i]->tRequired[1].Rise = MAP_FLOAT_LARGE;
|
||||
p->vMapObjs->pArray[i]->tRequired[1].Fall = MAP_FLOAT_LARGE;
|
||||
p->vMapObjs->pArray[i]->tRequired[1].Worst = MAP_FLOAT_LARGE;
|
||||
}
|
||||
// set the required times for the POs
|
||||
for ( i = 0; i < p->nOutputs; i++ )
|
||||
{
|
||||
fPhase = !Map_IsComplement(p->pOutputs[i]);
|
||||
ptTime = Map_Regular(p->pOutputs[i])->tRequired + fPhase;
|
||||
ptTimeA = Map_Regular(p->pOutputs[i])->tArrival + fPhase;
|
||||
|
||||
// if external required time can be achieved, use it
|
||||
if ( p->pOutputRequireds && p->pOutputRequireds[i].Worst > 0 && ptTimeA->Worst <= p->pOutputRequireds[i].Worst )//&& p->pOutputRequireds[i].Worst <= p->fRequiredGlo )
|
||||
ptTime->Rise = ptTime->Fall = ptTime->Worst = p->pOutputRequireds[i].Worst;
|
||||
// if external required cannot be achieved, set the earliest possible arrival time
|
||||
else if ( p->pOutputRequireds && p->pOutputRequireds[i].Worst > 0 && ptTimeA->Worst > p->pOutputRequireds[i].Worst )
|
||||
ptTime->Rise = ptTime->Fall = ptTime->Worst = ptTimeA->Worst;
|
||||
// otherwise, set the global required time
|
||||
else
|
||||
ptTime->Rise = ptTime->Fall = ptTime->Worst = p->fRequiredGlo;
|
||||
}
|
||||
// visit nodes in the reverse topological order
|
||||
Map_TimePropagateRequired( p );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -51,11 +51,11 @@ void Map_MappingTruths( Map_Man_t * pMan )
|
|||
Map_Cut_t * pCut;
|
||||
int nNodes, i;
|
||||
// compute the cuts for the POs
|
||||
nNodes = pMan->vAnds->nSize;
|
||||
nNodes = pMan->vMapObjs->nSize;
|
||||
pProgress = Extra_ProgressBarStart( stdout, nNodes );
|
||||
for ( i = 0; i < nNodes; i++ )
|
||||
{
|
||||
pNode = pMan->vAnds->pArray[i];
|
||||
pNode = pMan->vMapObjs->pArray[i];
|
||||
if ( !Map_NodeIsAnd( pNode ) )
|
||||
continue;
|
||||
assert( pNode->pCuts );
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
#define MAP_CO_LIST_SIZE 5
|
||||
|
||||
static void Map_MappingDfs_rec( Map_Node_t * pNode, Map_NodeVec_t * vNodes, int fCollectEquiv );
|
||||
static int Map_MappingCountLevels_rec( Map_Node_t * pNode );
|
||||
static float Map_MappingSetRefsAndArea_rec( Map_Man_t * pMan, Map_Node_t * pNode );
|
||||
static float Map_MappingSetRefsAndSwitch_rec( Map_Man_t * pMan, Map_Node_t * pNode );
|
||||
|
|
@ -37,15 +36,12 @@ static float Map_MappingArea_rec( Map_Man_t * pMan, Map_Node_t * pNode, Map_Node
|
|||
static int Map_MappingCompareOutputDelay( Map_Node_t ** ppNode1, Map_Node_t ** ppNode2 );
|
||||
static void Map_MappingFindLatest( Map_Man_t * p, int * pNodes, int nNodesMax );
|
||||
static unsigned Map_MappingExpandTruth_rec( unsigned uTruth, int nVars );
|
||||
static void Map_MappingGetChoiceLevels( Map_Man_t * pMan, Map_Node_t * p1, Map_Node_t * p2, int * pMin, int * pMax );
|
||||
static float Map_MappingGetChoiceVolumes( Map_Man_t * pMan, Map_Node_t * p1, Map_Node_t * p2 );
|
||||
static int Map_MappingCountUsedNodes( Map_Man_t * pMan, int fChoices );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the DFS ordering of the nodes.]
|
||||
|
|
@ -56,56 +52,6 @@ static int Map_MappingCountUsedNodes( Map_Man_t * pMan, int fChoices );
|
|||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_NodeVec_t * Map_MappingDfs( Map_Man_t * pMan, int fCollectEquiv )
|
||||
{
|
||||
Map_NodeVec_t * vNodes;
|
||||
int i;
|
||||
// perform the traversal
|
||||
vNodes = Map_NodeVecAlloc( 100 );
|
||||
for ( i = 0; i < pMan->nOutputs; i++ )
|
||||
Map_MappingDfs_rec( Map_Regular(pMan->pOutputs[i]), vNodes, fCollectEquiv );
|
||||
for ( i = 0; i < vNodes->nSize; i++ )
|
||||
vNodes->pArray[i]->fMark0 = 0;
|
||||
// for ( i = 0; i < pMan->nOutputs; i++ )
|
||||
// Map_MappingUnmark_rec( Map_Regular(pMan->pOutputs[i]) );
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the DFS ordering of the nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_NodeVec_t * Map_MappingDfsNodes( Map_Man_t * pMan, Map_Node_t ** ppCuts, int nNodes, int fEquiv )
|
||||
{
|
||||
Map_NodeVec_t * vNodes;
|
||||
int i;
|
||||
// perform the traversal
|
||||
vNodes = Map_NodeVecAlloc( 200 );
|
||||
for ( i = 0; i < nNodes; i++ )
|
||||
Map_MappingDfs_rec( ppCuts[i], vNodes, fEquiv );
|
||||
for ( i = 0; i < vNodes->nSize; i++ )
|
||||
vNodes->pArray[i]->fMark0 = 0;
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively computes the DFS ordering of the nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MappingDfs_rec( Map_Node_t * pNode, Map_NodeVec_t * vNodes, int fCollectEquiv )
|
||||
{
|
||||
|
|
@ -128,144 +74,21 @@ void Map_MappingDfs_rec( Map_Node_t * pNode, Map_NodeVec_t * vNodes, int fCollec
|
|||
// add the node to the list
|
||||
Map_NodeVecPush( vNodes, pNode );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively computes the DFS ordering of the nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MappingDfsMarked1_rec( Map_Node_t * pNode, Map_NodeVec_t * vNodes, int fFirst )
|
||||
Map_NodeVec_t * Map_MappingDfs( Map_Man_t * pMan, int fCollectEquiv )
|
||||
{
|
||||
assert( !Map_IsComplement(pNode) );
|
||||
if ( pNode->fMark0 )
|
||||
return;
|
||||
// visit the transitive fanin
|
||||
if ( Map_NodeIsAnd(pNode) )
|
||||
{
|
||||
Map_MappingDfsMarked1_rec( Map_Regular(pNode->p1), vNodes, 0 );
|
||||
Map_MappingDfsMarked1_rec( Map_Regular(pNode->p2), vNodes, 0 );
|
||||
}
|
||||
// visit the equivalent nodes
|
||||
if ( !fFirst && pNode->pNextE )
|
||||
Map_MappingDfsMarked1_rec( pNode->pNextE, vNodes, 0 );
|
||||
// make sure the node is not visited through the equivalent nodes
|
||||
assert( pNode->fMark0 == 0 );
|
||||
// mark the node as visited
|
||||
pNode->fMark0 = 1;
|
||||
// add the node to the list
|
||||
Map_NodeVecPush( vNodes, pNode );
|
||||
Map_NodeVec_t * vNodes;
|
||||
int i;
|
||||
// perform the traversal
|
||||
vNodes = Map_NodeVecAlloc( 100 );
|
||||
for ( i = 0; i < pMan->nOutputs; i++ )
|
||||
Map_MappingDfs_rec( Map_Regular(pMan->pOutputs[i]), vNodes, fCollectEquiv );
|
||||
for ( i = 0; i < vNodes->nSize; i++ )
|
||||
vNodes->pArray[i]->fMark0 = 0;
|
||||
// for ( i = 0; i < pMan->nOutputs; i++ )
|
||||
// Map_MappingUnmark_rec( Map_Regular(pMan->pOutputs[i]) );
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively computes the DFS ordering of the nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MappingDfsMarked2_rec( Map_Node_t * pNode, Map_NodeVec_t * vNodes, Map_NodeVec_t * vBoundary, int fFirst )
|
||||
{
|
||||
assert( !Map_IsComplement(pNode) );
|
||||
if ( pNode->fMark1 )
|
||||
return;
|
||||
if ( pNode->fMark0 || Map_NodeIsVar(pNode) )
|
||||
{
|
||||
pNode->fMark1 = 1;
|
||||
Map_NodeVecPush(vBoundary, pNode);
|
||||
return;
|
||||
}
|
||||
// visit the transitive fanin
|
||||
if ( Map_NodeIsAnd(pNode) )
|
||||
{
|
||||
Map_MappingDfsMarked2_rec( Map_Regular(pNode->p1), vNodes, vBoundary, 0 );
|
||||
Map_MappingDfsMarked2_rec( Map_Regular(pNode->p2), vNodes, vBoundary, 0 );
|
||||
}
|
||||
// visit the equivalent nodes
|
||||
if ( !fFirst && pNode->pNextE )
|
||||
Map_MappingDfsMarked2_rec( pNode->pNextE, vNodes, vBoundary, 0 );
|
||||
// make sure the node is not visited through the equivalent nodes
|
||||
assert( pNode->fMark1 == 0 );
|
||||
// mark the node as visited
|
||||
pNode->fMark1 = 1;
|
||||
// add the node to the list
|
||||
Map_NodeVecPush( vNodes, pNode );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively computes the DFS ordering of the nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MappingDfsMarked3_rec( Map_Node_t * pNode, Map_NodeVec_t * vNodes )
|
||||
{
|
||||
assert( !Map_IsComplement(pNode) );
|
||||
if ( pNode->fMark0 )
|
||||
return;
|
||||
// visit the transitive fanin
|
||||
if ( Map_NodeIsAnd(pNode) )
|
||||
{
|
||||
Map_MappingDfsMarked3_rec( Map_Regular(pNode->p1), vNodes );
|
||||
Map_MappingDfsMarked3_rec( Map_Regular(pNode->p2), vNodes );
|
||||
}
|
||||
// make sure the node is not visited through the equivalent nodes
|
||||
assert( pNode->fMark0 == 0 );
|
||||
// mark the node as visited
|
||||
pNode->fMark0 = 1;
|
||||
// add the node to the list
|
||||
Map_NodeVecPush( vNodes, pNode );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively computes the DFS ordering of the nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MappingDfsMarked4_rec( Map_Node_t * pNode, Map_NodeVec_t * vNodes )
|
||||
{
|
||||
assert( !Map_IsComplement(pNode) );
|
||||
if ( pNode->fMark1 )
|
||||
return;
|
||||
// visit the transitive fanin
|
||||
if ( Map_NodeIsAnd(pNode) )
|
||||
{
|
||||
Map_MappingDfsMarked4_rec( Map_Regular(pNode->p1), vNodes );
|
||||
Map_MappingDfsMarked4_rec( Map_Regular(pNode->p2), vNodes );
|
||||
}
|
||||
// make sure the node is not visited through the equivalent nodes
|
||||
assert( pNode->fMark1 == 0 );
|
||||
// mark the node as visited
|
||||
pNode->fMark1 = 1;
|
||||
// add the node to the list
|
||||
Map_NodeVecPush( vNodes, pNode );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the number of logic levels not counting PIs/POs.]
|
||||
|
|
@ -829,8 +652,8 @@ int Map_MappingCountDoubles( Map_Man_t * pMan, Map_NodeVec_t * vNodes )
|
|||
void Map_ManCleanData( Map_Man_t * p )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->vNodesAll->nSize; i++ )
|
||||
p->vNodesAll->pArray[i]->pData0 = p->vNodesAll->pArray[i]->pData1 = 0;
|
||||
for ( i = 0; i < p->vMapObjs->nSize; i++ )
|
||||
p->vMapObjs->pArray[i]->pData0 = p->vMapObjs->pArray[i]->pData1 = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -892,10 +715,10 @@ float Map_MappingComputeDelayWithFanouts( Map_Man_t * p )
|
|||
Map_Node_t * pNode;
|
||||
float Result;
|
||||
int i;
|
||||
for ( i = 0; i < p->vAnds->nSize; i++ )
|
||||
for ( i = 0; i < p->vMapObjs->nSize; i++ )
|
||||
{
|
||||
// skip primary inputs
|
||||
pNode = p->vAnds->pArray[i];
|
||||
pNode = p->vMapObjs->pArray[i];
|
||||
if ( !Map_NodeIsAnd( pNode ) )
|
||||
continue;
|
||||
// skip a secondary node
|
||||
|
|
@ -1031,9 +854,9 @@ void Map_MappingReportChoices( Map_Man_t * pMan )
|
|||
|
||||
// report statistics about choices
|
||||
nChoiceNodes = nChoices = 0;
|
||||
for ( i = 0; i < pMan->vAnds->nSize; i++ )
|
||||
for ( i = 0; i < pMan->vMapObjs->nSize; i++ )
|
||||
{
|
||||
pNode = pMan->vAnds->pArray[i];
|
||||
pNode = pMan->vMapObjs->pArray[i];
|
||||
if ( pNode->pRepr == NULL && pNode->pNextE != NULL )
|
||||
{ // this is a choice node = the primary node that has equivalent nodes
|
||||
nChoiceNodes++;
|
||||
|
|
@ -1045,89 +868,6 @@ void Map_MappingReportChoices( Map_Man_t * pMan )
|
|||
printf( "Choice stats: Choice nodes = %d. Total choices = %d.\n", nChoiceNodes, nChoices );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the maximum and minimum levels of the choice nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MappingGetChoiceLevels( Map_Man_t * pMan, Map_Node_t * p1, Map_Node_t * p2, int * pMin, int * pMax )
|
||||
{
|
||||
Map_NodeVec_t * vNodes;
|
||||
Map_NodeVec_t * vBoundary;
|
||||
Map_Node_t * pNode;
|
||||
int i, Min, Max;
|
||||
|
||||
vNodes = Map_NodeVecAlloc( 100 );
|
||||
vBoundary = Map_NodeVecAlloc( 100 );
|
||||
Map_MappingDfsMarked1_rec( p1, vNodes, 1 );
|
||||
Map_MappingDfsMarked2_rec( p2, vNodes, vBoundary, 1 );
|
||||
// clean the marks
|
||||
Min = 100000;
|
||||
Max = -100000;
|
||||
for ( i = 0; i < vBoundary->nSize; i++ )
|
||||
{
|
||||
pNode = vBoundary->pArray[i];
|
||||
if ( Min > (int)pNode->Level )
|
||||
Min = pNode->Level;
|
||||
if ( Max < (int)pNode->Level )
|
||||
Max = pNode->Level;
|
||||
}
|
||||
Map_NodeVecFree( vBoundary );
|
||||
for ( i = 0; i < vNodes->nSize; i++ )
|
||||
{
|
||||
pNode = vNodes->pArray[i];
|
||||
pNode->fMark0 = pNode->fMark1 = 0;
|
||||
}
|
||||
Map_NodeVecFree( vNodes );
|
||||
*pMin = Min;
|
||||
*pMax = Max;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_MappingGetChoiceVolumes( Map_Man_t * pMan, Map_Node_t * p1, Map_Node_t * p2 )
|
||||
{
|
||||
Map_NodeVec_t * vNodes;
|
||||
Map_Node_t * pNode;
|
||||
int i, nVolumeTotal, nVolumeUnique;
|
||||
|
||||
vNodes = Map_NodeVecAlloc( 100 );
|
||||
Map_MappingDfsMarked3_rec( p1, vNodes );
|
||||
Map_MappingDfsMarked4_rec( p2, vNodes );
|
||||
// clean the marks
|
||||
nVolumeTotal = nVolumeUnique = 0;
|
||||
for ( i = 0; i < vNodes->nSize; i++ )
|
||||
{
|
||||
pNode = vNodes->pArray[i];
|
||||
if ( !Map_NodeIsAnd(pNode) )
|
||||
continue;
|
||||
nVolumeTotal++;
|
||||
if ( pNode->fMark0 ^ pNode->fMark1 )
|
||||
nVolumeUnique++;
|
||||
pNode->fMark0 = pNode->fMark1 = 0;
|
||||
}
|
||||
Map_NodeVecFree( vNodes );
|
||||
// return ((float)nVolumeUnique)/nVolumeTotal;
|
||||
return (float)nVolumeUnique;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the maximum and minimum levels of the choice nodes.]
|
||||
|
|
|
|||
|
|
@ -67,10 +67,31 @@ Map_NodeVec_t * Map_NodeVecAlloc( int nCap )
|
|||
***********************************************************************/
|
||||
void Map_NodeVecFree( Map_NodeVec_t * p )
|
||||
{
|
||||
if ( p == NULL )
|
||||
return;
|
||||
ABC_FREE( p->pArray );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_NodeVec_t * Map_NodeVecDup( Map_NodeVec_t * p )
|
||||
{
|
||||
Map_NodeVec_t * pNew = Map_NodeVecAlloc( p->nSize );
|
||||
memcpy( pNew->pArray, p->pArray, sizeof(int) * p->nSize );
|
||||
pNew->nSize = p->nSize;
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
|
|||
Loading…
Reference in New Issue