| /**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 |
| |