/**CFile**************************************************************** FileName [dauArray.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [DAG-aware unmapping.] Synopsis [Array representation of DSD.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: dauArray.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "dauInt.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// typedef struct Dau_Dsd_t_ Dau_Dsd_t; struct Dau_Dsd_t_ { unsigned iVar : 5; // variable unsigned nFans : 5; // fanin count unsigned Depth : 5; // tree depth unsigned Offset : 5; // the diff between this and other node unsigned Data : 5; // user data unsigned Type : 3; // node type unsigned fCompl : 1; // the complemented attribute unsigned fUnused : 1; // this vertice is unused }; static inline void Dau_DsdClean( Dau_Dsd_t * p ) { *((int *)p) = 0; } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// int Dau_DsdCountAnd( Dau_Dsd_t * p ) { int Count, Costs[7] = {0, 0, 0, 1, 3, 3, 3}; for ( Count = 0; p->Type; p++ ) Count += Costs[p->Type]; return Count; } /* void Dau_DsdMark( Dau_Dsd_t * p, int nSize, int * pMarks ) { int pStore[DAU_MAX_VAR] = {0}; Dau_Dsd_t * q; if ( p->Type == DAU_DSD_CONST || p->Type == DAU_DSD_VAR ) return; for ( q = p + nSize - 1; q >= p; q-- ) { if ( q->Type == DAU_DSD_VAR ) pStore[q->Depth] += pMarks[q->iVar]; else { q->Data = pStore[q->Depth+1]; pStore[q->Depth+1] = 0; pStore[q->Depth] += (q->Data == q->nFans); } } } */ 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; } void Dau_DsdPrint( Dau_Dsd_t * p ) { char OpenType[7] = {0, 0, 0, '(', '[', '<', '{'}; char CloseType[7] = {0, 0, 0, ')', ']', '>', '}'}; char pTypes[DAU_MAX_VAR]; int d, pVisits[DAU_MAX_VAR]; if ( p->Type == DAU_DSD_CONST0 ) { printf( "%d\n", p->fCompl ); return; } pVisits[0] = 1; for ( d = 0; p->Type; p++ ) { if ( p->fCompl ) printf( "!" ); if ( p->Type == DAU_DSD_VAR ) { printf( "%c", 'a' + p->iVar ); while ( d > 0 && --pVisits[d] == 0 ) printf( "%c", pTypes[d--] ); } else { pVisits[++d] = p->nFans; printf( "%c", OpenType[p->Type] ); printf( "%c", 'a' + p->Data ); printf( "%d", p->Depth ); pTypes[d] = CloseType[p->Type]; } } assert( d == 0 ); printf( "\n" ); } void Dau_DsdDepth( Dau_Dsd_t * p ) { int d, pVisits[DAU_MAX_VAR]; if ( p->Type == DAU_DSD_CONST0 ) return; pVisits[0] = 1; for ( d = 0; p->Type; p++ ) { p->Depth = d; if ( p->Type == DAU_DSD_VAR ) while ( d > 0 && --pVisits[d] == 0 ) d--; else pVisits[++d] = p->nFans; } assert( d == 0 ); } void Dau_DsdRemoveUseless( Dau_Dsd_t * p ) { Dau_Dsd_t * q = p, * pLevel[DAU_MAX_VAR]; int d, fChange = 0, pVisits[DAU_MAX_VAR]; if ( p->Type == DAU_DSD_CONST0 ) return; pVisits[0] = 1; for ( d = 0; p->Type; p++ ) { p->Depth = d; if ( p->Type == DAU_DSD_VAR ) while ( d > 0 && --pVisits[d] == 0 ) d--; else { if ( d > 0 && (pLevel[d-1]->Type == DAU_DSD_XOR && p->Type == DAU_DSD_XOR || pLevel[d-1]->Type == DAU_DSD_AND && p->Type == DAU_DSD_AND && !p->fCompl) ) { pLevel[d-1]->nFans += p->nFans - 1; pVisits[d] += p->nFans - 1; p->fUnused = 1; fChange = 1; } else { pLevel[d++] = p; pVisits[d] = p->nFans; } } } assert( d == 0 ); // compact if ( fChange ) { for ( p = q; p->Type; p++ ) if ( !p->fUnused ) *q++ = *p; Dau_DsdClean( q ); } } void Dau_DsdTest22() { Dau_Dsd_t pStore[2 * DAU_MAX_VAR]; // char * pDsd = "[(ab)c(f!(he))]"; // char * pDsd = "[(abd)cf(f!{she})]"; char * pDsd = "[(abd)[cf](f(sg(he)))]"; // char * pDsd = "[(ab)[cf]]"; int i, nSize = Dau_DsdConstruct( pDsd, pStore ); // Dau_DsdDepth( pStore ); Dau_DsdPrint( pStore ); Dau_DsdRemoveUseless( pStore ); Dau_DsdPrint( pStore ); i = 0; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END