diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2014-03-23 16:52:40 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2014-03-23 16:52:40 -0700 |
commit | 6f17c44e9167f810d6f7f03582f2f132464115d5 (patch) | |
tree | dd3205f236474b69407e1e7b0118f4ef4567c9ac /src/base | |
parent | f6eb5262a3176a97f4063f1c49a7d56545fcd53e (diff) | |
download | abc-6f17c44e9167f810d6f7f03582f2f132464115d5.tar.gz abc-6f17c44e9167f810d6f7f03582f2f132464115d5.tar.bz2 abc-6f17c44e9167f810d6f7f03582f2f132464115d5.zip |
Integrating barrier buffers into the mapper.
Diffstat (limited to 'src/base')
-rw-r--r-- | src/base/abc/abc.h | 1 | ||||
-rw-r--r-- | src/base/abc/abcBarBuf.c | 64 | ||||
-rw-r--r-- | src/base/abc/abcDfs.c | 44 | ||||
-rw-r--r-- | src/base/abci/abcMap.c | 264 |
4 files changed, 235 insertions, 138 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index f5e6a694..ad74c2a7 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -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 ); diff --git a/src/base/abc/abcBarBuf.c b/src/base/abc/abcBarBuf.c index 927c718f..7c95b8d3 100644 --- a/src/base/abc/abcBarBuf.c +++ b/src/base/abc/abcBarBuf.c @@ -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 /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcDfs.c b/src/base/abc/abcDfs.c index 9a483f18..7eac765d 100644 --- a/src/base/abc/abcDfs.c +++ b/src/base/abc/abcDfs.c @@ -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************************************************************* diff --git a/src/base/abci/abcMap.c b/src/base/abci/abcMap.c index ea99938e..282a3de6 100644 --- a/src/base/abci/abcMap.c +++ b/src/base/abci/abcMap.c @@ -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; } @@ -291,95 +301,50 @@ 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 ) +Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis ) { - 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 ) + Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen(); + Mio_Gate_t * pRoot; + Map_Super_t ** ppFanins; + Abc_Obj_t * pNodeNew, * pNodeFanin; + int nFanins, Number, i; + + // get the parameters of the supergate + pRoot = Map_SuperReadRoot(pSuper); + if ( pRoot == NULL ) { - 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 ); + Number = Map_SuperReadNum(pSuper); + if ( Number < nNodePis ) + { + return pNodePis[Number]; + } + else + { +// assert( 0 ); + /* It might happen that a super gate with 5 inputs is constructed that + * actually depends only on the first four variables; i.e the fifth is a + * don't care -- in that case we connect constant node for the fifth + * (since the cut only has 4 variables). An interesting question is what + * if the first variable (and not the fifth one is the redundant one; + * can that happen?) */ + return Abc_NtkCreateNodeConst0(pNtkNew); + } } - 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; + pRoot = Mio_LibraryReadGateByName( pLib, Mio_GateReadName(pRoot), NULL ); - // check the case of constant node - if ( Map_NodeIsConst(pNodeMap) ) + // get information about the fanins of the supergate + nFanins = Map_SuperReadFaninNum( pSuper ); + ppFanins = Map_SuperReadFanins( pSuper ); + // create a new node with these fanins + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + for ( i = 0; i < nFanins; i++ ) { - 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; + pNodeFanin = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, ppFanins[i], pNodePis, nNodePis ); + Abc_ObjAddFanin( pNodeNew, pNodeFanin ); } - - // 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; + pNodeNew->pData = pRoot; + return pNodeNew; } - -/**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]; @@ -417,67 +382,90 @@ Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap 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; -/**Function************************************************************* + // 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; + } - Synopsis [Constructs the nodes corrresponding to one supergate.] + // check if the phase is already implemented + pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase ); + if ( pNodeNew ) + return pNodeNew; - Description [] - - SideEffects [] + // implement the node if the best cut is assigned + if ( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL ) + return Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, fPhase ); - SeeAlso [] + // 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 ); -***********************************************************************/ -Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis ) -{ - Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen(); - Mio_Gate_t * pRoot; - Map_Super_t ** ppFanins; - Abc_Obj_t * pNodeNew, * pNodeFanin; - int nFanins, Number, i; + // add the inverter + pNodeInv = Abc_NtkCreateNode( pNtkNew ); + Abc_ObjAddFanin( pNodeInv, pNodeNew ); + pNodeInv->pData = Mio_LibraryReadInv(Map_ManReadGenLib(Map_NodeReadMan(pNodeMap))); - // get the parameters of the supergate - pRoot = Map_SuperReadRoot(pSuper); - if ( pRoot == NULL ) + // 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 ) { - Number = Map_SuperReadNum(pSuper); - if ( Number < nNodePis ) - { - return pNodePis[Number]; - } - else - { -// assert( 0 ); - /* It might happen that a super gate with 5 inputs is constructed that - * actually depends only on the first four variables; i.e the fifth is a - * don't care -- in that case we connect constant node for the fifth - * (since the cut only has 4 variables). An interesting question is what - * if the first variable (and not the fifth one is the redundant one; - * can that happen?) */ - return Abc_NtkCreateNodeConst0(pNtkNew); - } + if ( i >= Abc_NtkCiNum(pNtk) - pNtk->nBarBufs ) + break; + Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy ); } - pRoot = Mio_LibraryReadGateByName( pLib, Mio_GateReadName(pRoot), NULL ); - - // get information about the fanins of the supergate - nFanins = Map_SuperReadFaninNum( pSuper ); - ppFanins = Map_SuperReadFanins( pSuper ); - // create a new node with these fanins - pNodeNew = Abc_NtkCreateNode( pNtkNew ); - for ( i = 0; i < nFanins; i++ ) + Abc_NtkForEachCi( pNtk, pNode, i ) { - pNodeFanin = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, ppFanins[i], pNodePis, nNodePis ); - Abc_ObjAddFanin( pNodeNew, pNodeFanin ); + if ( i < Abc_NtkCiNum(pNtk) - pNtk->nBarBufs ) + continue; + Map_NodeSetData( Map_ManReadBufs(pMan)[i - (Abc_NtkCiNum(pNtk) - pNtk->nBarBufs)], 1, (char *)pNode->pCopy ); } - pNodeNew->pData = pRoot; - return pNodeNew; + // 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************************************************************* Synopsis [Interface with the mapping package.] |