/**CFile**************************************************************** FileName [mapperTruth.c] PackageName [MVSIS 1.3: Multi-valued logic synthesis system.] Synopsis [Generic technology mapping engine.] Author [MVSIS Group] Affiliation [UC Berkeley] Date [Ver. 2.0. Started - June 1, 2004.] Revision [$Id: mapperTruth.c,v 1.8 2005/01/23 06:59:45 alanmi Exp $] ***********************************************************************/ #include "mapperInt.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// static void Map_TruthsCut( Map_Man_t * pMan, Map_Cut_t * pCut ); extern void Map_TruthsCutOne( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] ); static void Map_CutsCollect_rec( Map_Cut_t * pCut, Map_NodeVec_t * vVisited ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Derives truth tables for each cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Map_MappingTruths( Map_Man_t * pMan ) { ProgressBar * pProgress; Map_Node_t * pNode; Map_Cut_t * pCut; int nNodes, i; // compute the cuts for the POs nNodes = pMan->vMapObjs->nSize; pProgress = Extra_ProgressBarStart( stdout, nNodes ); for ( i = 0; i < nNodes; i++ ) { pNode = pMan->vMapObjs->pArray[i]; if ( !Map_NodeIsAnd( pNode ) ) continue; assert( pNode->pCuts ); assert( pNode->pCuts->nLeaves == 1 ); // match the simple cut pNode->pCuts->M[0].uPhase = 0; pNode->pCuts->M[0].pSupers = pMan->pSuperLib->pSuperInv; pNode->pCuts->M[0].uPhaseBest = 0; pNode->pCuts->M[0].pSuperBest = pMan->pSuperLib->pSuperInv; pNode->pCuts->M[1].uPhase = 0; pNode->pCuts->M[1].pSupers = pMan->pSuperLib->pSuperInv; pNode->pCuts->M[1].uPhaseBest = 1; pNode->pCuts->M[1].pSuperBest = pMan->pSuperLib->pSuperInv; // match the rest of the cuts for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext ) Map_TruthsCut( pMan, pCut ); Extra_ProgressBarUpdate( pProgress, i, "Tables ..." ); } Extra_ProgressBarStop( pProgress ); } /**Function************************************************************* Synopsis [Derives the truth table for one cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut ) { // unsigned uCanon1, uCanon2; unsigned uTruth[2], uCanon[2]; unsigned char uPhases[16]; unsigned * uCanon2; char * pPhases2; int fUseFast = 1; int fUseSlow = 0; int fUseRec = 0; // this does not work for Solaris extern int Map_CanonCompute( int nVarsMax, int nVarsReal, unsigned * pt, unsigned ** pptRes, char ** ppfRes ); // generally speaking, 1-input cut can be matched into a wire! if ( pCut->nLeaves == 1 ) return; /* if ( p->nVarsMax == 5 ) { uTruth[0] = pCut->uTruth; uTruth[1] = pCut->uTruth; } else */ Map_TruthsCutOne( p, pCut, uTruth ); // compute the canonical form for the positive phase if ( fUseFast ) Map_CanonComputeFast( p, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); else if ( fUseSlow ) Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); else if ( fUseRec ) { // Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); Extra_TruthCanonFastN( p->nVarsMax, pCut->nLeaves, uTruth, &uCanon2, &pPhases2 ); /* if ( uCanon[0] != uCanon2[0] || uPhases[0] != pPhases2[0] ) { int k = 0; Map_CanonCompute( p->nVarsMax, pCut->nLeaves, uTruth, &uCanon2, &pPhases2 ); } */ uCanon[0] = uCanon2[0]; uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0]; uPhases[0] = pPhases2[0]; } else Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon ); pCut->M[1].uPhase = uPhases[0]; p->nCanons++; //uCanon1 = uCanon[0] & 0xFFFF; // compute the canonical form for the negative phase uTruth[0] = ~uTruth[0]; uTruth[1] = ~uTruth[1]; if ( fUseFast ) Map_CanonComputeFast( p, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); else if ( fUseSlow ) Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); else if ( fUseRec ) { // Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); Extra_TruthCanonFastN( p->nVarsMax, pCut->nLeaves, uTruth, &uCanon2, &pPhases2 ); /* if ( uCanon[0] != uCanon2[0] || uPhases[0] != pPhases2[0] ) { int k = 0; Map_CanonCompute( p->nVarsMax, pCut->nLeaves, uTruth, &uCanon2, &pPhases2 ); } */ uCanon[0] = uCanon2[0]; uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0]; uPhases[0] = pPhases2[0]; } else Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon ); pCut->M[0].uPhase = uPhases[0]; p->nCanons++; //uCanon2 = uCanon[0] & 0xFFFF; //assert( p->nVarsMax == 4 ); //Rwt_Man4ExploreCount( uCanon1 < uCanon2 ? uCanon1 : uCanon2 ); // restore the truth table uTruth[0] = ~uTruth[0]; uTruth[1] = ~uTruth[1]; } /**Function************************************************************* Synopsis [Computes the truth table of one cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Map_TruthsCutOne( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] ) { unsigned uTruth1[2], uTruth2[2]; Map_Cut_t * pTemp = NULL; // Suppress "might be used uninitialized" int i; // mark the cut leaves for ( i = 0; i < pCut->nLeaves; i++ ) { pTemp = pCut->ppLeaves[i]->pCuts; pTemp->fMark = 1; pTemp->M[0].uPhaseBest = p->uTruths[i][0]; pTemp->M[1].uPhaseBest = p->uTruths[i][1]; } assert( pCut->fMark == 0 ); // collect the cuts in the cut cone p->vVisited->nSize = 0; Map_CutsCollect_rec( pCut, p->vVisited ); assert( p->vVisited->nSize > 0 ); pCut->nVolume = p->vVisited->nSize; // compute the tables and unmark for ( i = 0; i < pCut->nLeaves; i++ ) { pTemp = pCut->ppLeaves[i]->pCuts; pTemp->fMark = 0; } for ( i = 0; i < p->vVisited->nSize; i++ ) { // get the cut pTemp = (Map_Cut_t *)p->vVisited->pArray[i]; pTemp->fMark = 0; // get truth table of the first branch if ( Map_CutIsComplement(pTemp->pOne) ) { uTruth1[0] = ~Map_CutRegular(pTemp->pOne)->M[0].uPhaseBest; uTruth1[1] = ~Map_CutRegular(pTemp->pOne)->M[1].uPhaseBest; } else { uTruth1[0] = Map_CutRegular(pTemp->pOne)->M[0].uPhaseBest; uTruth1[1] = Map_CutRegular(pTemp->pOne)->M[1].uPhaseBest; } // get truth table of the second branch if ( Map_CutIsComplement(pTemp->pTwo) ) { uTruth2[0] = ~Map_CutRegular(pTemp->pTwo)->M[0].uPhaseBest; uTruth2[1] = ~Map_CutRegular(pTemp->pTwo)->M[1].uPhaseBest; } else { uTruth2[0] = Map_CutRegular(pTemp->pTwo)->M[0].uPhaseBest; uTruth2[1] = Map_CutRegular(pTemp->pTwo)->M[1].uPhaseBest; } // get the truth table of the output if ( !pTemp->Phase ) { pTemp->M[0].uPhaseBest = uTruth1[0] & uTruth2[0]; pTemp->M[1].uPhaseBest = uTruth1[1] & uTruth2[1]; } else { pTemp->M[0].uPhaseBest = ~(uTruth1[0] & uTruth2[0]); pTemp->M[1].uPhaseBest = ~(uTruth1[1] & uTruth2[1]); } } uTruth[0] = pTemp->M[0].uPhaseBest; uTruth[1] = pTemp->M[1].uPhaseBest; } /**Function************************************************************* Synopsis [Recursively collect the cuts.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Map_CutsCollect_rec( Map_Cut_t * pCut, Map_NodeVec_t * vVisited ) { if ( pCut->fMark ) return; Map_CutsCollect_rec( Map_CutRegular(pCut->pOne), vVisited ); Map_CutsCollect_rec( Map_CutRegular(pCut->pTwo), vVisited ); assert( pCut->fMark == 0 ); pCut->fMark = 1; Map_NodeVecPush( vVisited, (Map_Node_t *)pCut ); } /* { unsigned * uCanon2; char * pPhases2; Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); Map_CanonCompute( p->nVarsMax, pCut->nLeaves, uTruth, &uCanon2, &pPhases2 ); if ( uCanon2[0] != uCanon[0] ) { int v = 0; Map_CanonCompute( p->nVarsMax, pCut->nLeaves, uTruth, &uCanon2, &pPhases2 ); Map_CanonComputeFast( p, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon ); } // else // { // printf( "Correct.\n" ); // } } */ //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END