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((Mio_Library_t *)Abc_FrameReadLibGen()); // set the inverter Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeInv ); return pNodeInv; }
/**Function************************************************************* Synopsis [Verify one useful property.] Description [This procedure verifies one useful property. After the FRAIG construction with choice nodes is over, each primary node should have fanins that are primary nodes. The primary nodes is the one that does not have pNode->pRepr set to point to another node.] SideEffects [] SeeAlso [] ***********************************************************************/ int Map_ManCheckConsistency( Map_Man_t * p ) { Map_Node_t * pNode; Map_NodeVec_t * pVec; int i; pVec = Map_MappingDfs( p, 0 ); for ( i = 0; i < pVec->nSize; i++ ) { pNode = pVec->pArray[i]; if ( Map_NodeIsVar(pNode) ) { if ( pNode->pRepr ) printf( "Primary input %d is a secondary node.\n", pNode->Num ); } else if ( Map_NodeIsConst(pNode) ) { if ( pNode->pRepr ) printf( "Constant 1 %d is a secondary node.\n", pNode->Num ); } else { if ( pNode->pRepr ) printf( "Internal node %d is a secondary node.\n", pNode->Num ); if ( Map_Regular(pNode->p1)->pRepr ) printf( "Internal node %d has first fanin that is a secondary node.\n", pNode->Num ); if ( Map_Regular(pNode->p2)->pRepr ) printf( "Internal node %d has second fanin that is a secondary node.\n", pNode->Num ); } } Map_NodeVecFree( pVec ); return 1; }
/**Function************************************************************* Synopsis [Looks up the AND2 node in the unique table.] Description [This procedure implements one-level hashing. All the nodes are hashed by their children. If the node with the same children was already created, it is returned by the call to this procedure. If it does not exist, this procedure creates a new node with these children. ] SideEffects [] SeeAlso [] ***********************************************************************/ Map_Node_t * Map_TableLookup( Map_Man_t * pMan, Map_Node_t * p1, Map_Node_t * p2 ) { Map_Node_t * pEnt; unsigned Key; if ( p1 == p2 ) return p1; if ( p1 == Map_Not(p2) ) return Map_Not(pMan->pConst1); if ( Map_NodeIsConst(p1) ) { if ( p1 == pMan->pConst1 ) return p2; return Map_Not(pMan->pConst1); } if ( Map_NodeIsConst(p2) ) { if ( p2 == pMan->pConst1 ) return p1; return Map_Not(pMan->pConst1); } if ( Map_Regular(p1)->Num > Map_Regular(p2)->Num ) pEnt = p1, p1 = p2, p2 = pEnt; Key = Map_HashKey2( p1, p2, pMan->nBins ); for ( pEnt = pMan->pBins[Key]; pEnt; pEnt = pEnt->pNext ) if ( pEnt->p1 == p1 && pEnt->p2 == p2 ) return pEnt; // resize the table if ( pMan->nNodes >= 2 * pMan->nBins ) { Map_TableResize( pMan ); Key = Map_HashKey2( p1, p2, pMan->nBins ); } // create the new node pEnt = Map_NodeCreate( pMan, p1, p2 ); // add the node to the corresponding linked list in the table pEnt->pNext = pMan->pBins[Key]; pMan->pBins[Key] = pEnt; return pEnt; }
void Map_MappingSetRefs( Map_Man_t * pMan ) { Map_Node_t * pNode; int i; if ( pMan->fUseProfile ) Mio_LibraryCleanProfile2( pMan->pSuperLib->pGenlib ); // 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 ); } }
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_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**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; }