/**Function************************************************************* Synopsis [Creates local copy.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline void Dau_DsdMergeCopy( char * pDsd, int fCompl, char * pRes ) { if ( fCompl && pDsd[0] == '!' ) fCompl = 0, pDsd++; if ( Dau_DsdIsConst(pDsd) ) // constant pRes[0] = (fCompl ? (char)((int)pDsd[0] ^ 1) : pDsd[0]), pRes[1] = 0; else sprintf( pRes, "%s%s", fCompl ? "!" : "", pDsd ); }
/**Function************************************************************* Synopsis [Performs merging of two DSD formulas.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ char * Dau_DsdMerge( char * pDsd0i, int * pPerm0, char * pDsd1i, int * pPerm1, int fCompl0, int fCompl1, int nVars ) { int fVerbose = 0; int fCheck = 0; static int Counter = 0; static char pRes[DAU_MAX_STR]; char pDsd0[DAU_MAX_STR]; char pDsd1[DAU_MAX_STR]; int pMatches0[DAU_MAX_STR]; int pMatches1[DAU_MAX_STR]; int pVarPres[DAU_MAX_VAR]; int pOld2New[DAU_MAX_VAR]; int pNew2Old[DAU_MAX_VAR]; int pStatus0[DAU_MAX_STR]; int pStatus1[DAU_MAX_STR]; int pMatches[DAU_MAX_STR]; int nVarsShared, nVarsTotal; Dau_Sto_t S, * pS = &S; word * pTruth, * pt = NULL, * pt0 = NULL, * pt1 = NULL; word pParts[3][DAU_MAX_WORD]; int Status; abctime clk = Abc_Clock(); Counter++; // create local copies Dau_DsdMergeCopy( pDsd0i, fCompl0, pDsd0 ); Dau_DsdMergeCopy( pDsd1i, fCompl1, pDsd1 ); if ( fVerbose ) printf( "\nAfter copying:\n" ); if ( fVerbose ) printf( "%s\n", pDsd0 ); if ( fVerbose ) printf( "%s\n", pDsd1 ); // handle constants if ( Dau_DsdIsConst(pDsd0) || Dau_DsdIsConst(pDsd1) ) { if ( Dau_DsdIsConst0(pDsd0) ) strcpy( pRes, pDsd0 ); else if ( Dau_DsdIsConst1(pDsd0) ) strcpy( pRes, pDsd1 ); else if ( Dau_DsdIsConst0(pDsd1) ) strcpy( pRes, pDsd1 ); else if ( Dau_DsdIsConst1(pDsd1) ) strcpy( pRes, pDsd0 ); else assert( 0 ); return pRes; } // compute matches Dau_DsdMergeMatches( pDsd0, pMatches0 ); Dau_DsdMergeMatches( pDsd1, pMatches1 ); // implement permutation Dau_DsdMergeReplace( pDsd0, pMatches0, pPerm0 ); Dau_DsdMergeReplace( pDsd1, pMatches1, pPerm1 ); if ( fVerbose ) printf( "After replacement:\n" ); if ( fVerbose ) printf( "%s\n", pDsd0 ); if ( fVerbose ) printf( "%s\n", pDsd1 ); if ( fCheck ) { pt0 = Dau_DsdToTruth( pDsd0, nVars ); Abc_TtCopy( pParts[0], pt0, Abc_TtWordNum(nVars), 0 ); } if ( fCheck ) { pt1 = Dau_DsdToTruth( pDsd1, nVars ); Abc_TtCopy( pParts[1], pt1, Abc_TtWordNum(nVars), 0 ); Abc_TtAnd( pParts[2], pParts[0], pParts[1], Abc_TtWordNum(nVars), 0 ); } // find shared varaiables nVarsShared = Dau_DsdMergeFindShared(pDsd0, pDsd1, pMatches0, pMatches1, pVarPres); if ( nVarsShared == 0 ) { sprintf( pRes, "(%s%s)", pDsd0, pDsd1 ); if ( fVerbose ) printf( "Disjoint:\n" ); if ( fVerbose ) printf( "%s\n", pRes ); Dau_DsdMergeMatches( pRes, pMatches ); Dau_DsdRemoveBraces( pRes, pMatches ); Dau_DsdNormalize( pRes ); if ( fVerbose ) printf( "Normalized:\n" ); if ( fVerbose ) printf( "%s\n", pRes ); s_TimeComp[0] += Abc_Clock() - clk; return pRes; } s_TimeComp[3] += Abc_Clock() - clk; // create variable mapping nVarsTotal = Dau_DsdMergeCreateMaps( pVarPres, nVarsShared, pOld2New, pNew2Old ); // perform variable replacement Dau_DsdMergeReplace( pDsd0, pMatches0, pOld2New ); Dau_DsdMergeReplace( pDsd1, pMatches1, pOld2New ); // find uniqueness status Dau_DsdMergeStatus( pDsd0, pMatches0, nVarsShared, pStatus0 ); Dau_DsdMergeStatus( pDsd1, pMatches1, nVarsShared, pStatus1 ); if ( fVerbose ) printf( "Individual status:\n" ); if ( fVerbose ) Dau_DsdMergePrintWithStatus( pDsd0, pStatus0 ); if ( fVerbose ) Dau_DsdMergePrintWithStatus( pDsd1, pStatus1 ); // prepare storage Dau_DsdMergeStoreClean( pS, nVarsShared ); // perform substitutions Dau_DsdMergeStoreCleanOutput( pS ); Dau_DsdMergeSubstitute( pS, pDsd0, pMatches0, pStatus0 ); strcpy( pDsd0, pS->pOutput ); if ( fVerbose ) printf( "Substitutions:\n" ); if ( fVerbose ) printf( "%s\n", pDsd0 ); // perform substitutions Dau_DsdMergeStoreCleanOutput( pS ); Dau_DsdMergeSubstitute( pS, pDsd1, pMatches1, pStatus1 ); strcpy( pDsd1, pS->pOutput ); if ( fVerbose ) printf( "%s\n", pDsd1 ); if ( fVerbose ) Dau_DsdMergeStorePrintDefs( pS ); // create new function // assert( nVarsTotal <= 6 ); sprintf( pS->pOutput, "(%s%s)", pDsd0, pDsd1 ); pTruth = Dau_DsdToTruth( pS->pOutput, nVarsTotal ); Status = Dau_DsdDecompose( pTruth, nVarsTotal, 0, 1, pS->pOutput ); //printf( "%d ", Status ); if ( Status == -1 ) // did not find 1-step DSD return NULL; // if ( Status > 6 ) // non-DSD part is too large // return NULL; if ( Dau_DsdIsConst(pS->pOutput) ) { strcpy( pRes, pS->pOutput ); return pRes; } if ( fVerbose ) printf( "Decomposition:\n" ); if ( fVerbose ) printf( "%s\n", pS->pOutput ); // substitute definitions Dau_DsdMergeMatches( pS->pOutput, pMatches ); Dau_DsdMergeInlineDefinitions( pS->pOutput, pMatches, pS, pRes, nVarsShared ); if ( fVerbose ) printf( "Inlining:\n" ); if ( fVerbose ) printf( "%s\n", pRes ); // perform variable replacement Dau_DsdMergeMatches( pRes, pMatches ); Dau_DsdMergeReplace( pRes, pMatches, pNew2Old ); Dau_DsdRemoveBraces( pRes, pMatches ); if ( fVerbose ) printf( "Replaced:\n" ); if ( fVerbose ) printf( "%s\n", pRes ); Dau_DsdNormalize( pRes ); if ( fVerbose ) printf( "Normalized:\n" ); if ( fVerbose ) printf( "%s\n", pRes ); if ( fCheck ) { pt = Dau_DsdToTruth( pRes, nVars ); if ( !Abc_TtEqual( pParts[2], pt, Abc_TtWordNum(nVars) ) ) printf( "Dau_DsdMerge(): Verification failed!\n" ); } if ( Status == 0 ) s_TimeComp[1] += Abc_Clock() - clk; else s_TimeComp[2] += Abc_Clock() - clk; return pRes; }
int Dau_DsdConstruct( char * pDsd, Dau_Dsd_t * pStore ) { Dau_Dsd_t * pLevel[DAU_MAX_VAR]; Dau_Dsd_t * q = pStore; int d = -1, fCompl = 0; if ( Dau_DsdIsConst(pDsd) ) { Dau_DsdClean( q ); q->Type = DAU_DSD_CONST0; q->fCompl = Dau_DsdIsConst1(pDsd); return 1; } for ( --q; *pDsd; pDsd++ ) { if ( *pDsd == '!' ) { fCompl ^= 1; continue; } if ( *pDsd == ')' || *pDsd == ']' || *pDsd == '>' || *pDsd == '}' ) { assert( fCompl == 0 ); if ( --d >= 0 ) { pLevel[d]->nFans++; if ( pLevel[d]->Data > pLevel[d+1]->Data ) pLevel[d]->Data = pLevel[d+1]->Data; } continue; } Dau_DsdClean( ++q ); q->Data = 31; q->fCompl = fCompl; fCompl = 0; if ( *pDsd >= 'a' && *pDsd <= 'z' ) { q->Type = DAU_DSD_VAR; q->iVar = *pDsd - 'a'; q->Depth = d + 1; if ( d >= 0 ) { pLevel[d]->nFans++; if ( pLevel[d]->Data > q->iVar ) pLevel[d]->Data = q->iVar; } continue; } if ( *pDsd == '(' ) q->Type = DAU_DSD_AND; else if ( *pDsd == '[' ) q->Type = DAU_DSD_XOR; else if ( *pDsd == '<' ) q->Type = DAU_DSD_MUX; else if ( *pDsd == '{' ) q->Type = DAU_DSD_PRIME; else assert( 0 ); pLevel[++d] = q; q->Depth = d; } assert( d == -1 ); Dau_DsdClean( ++q ); return q - pStore; }