blob: 7ece5838744dfd117848ae8136ea2b47431ba411 [file] [log] [blame]
/**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