blob: 098456998a283784b5b27c6c33c438e7c3146a1b [file] [log] [blame]
/**CFile****************************************************************
FileName [ioReadDsd.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Command processing package.]
Synopsis [Procedure to read network from file.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ioReadDsd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ioAbc.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Finds the end of the part.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Io_ReadDsdFindEnd( char * pCur )
{
char * pEnd;
int nParts = 0;
assert( *pCur == '(' );
for ( pEnd = pCur; *pEnd; pEnd++ )
{
if ( *pEnd == '(' )
nParts++;
else if ( *pEnd == ')' )
nParts--;
if ( nParts == 0 )
return pEnd;
}
return NULL;
}
/**Function*************************************************************
Synopsis [Splits the formula into parts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Io_ReadDsdStrSplit( char * pCur, char * pParts[], int * pTypeXor )
{
int fAnd = 0, fXor = 0, fPri = 0, nParts = 0;
assert( *pCur );
// process the parts
while ( 1 )
{
// save the current part
pParts[nParts++] = pCur;
// skip the complement
if ( *pCur == '!' )
pCur++;
// skip var
if ( *pCur >= 'a' && *pCur <= 'z' )
pCur++;
else
{
// skip hex truth table
while ( (*pCur >= '0' && *pCur <= '9') || (*pCur >= 'A' && *pCur <= 'F') )
pCur++;
// process parentheses
if ( *pCur != '(' )
{
printf( "Cannot find the opening parenthesis.\n" );
break;
}
// find the corresponding closing parenthesis
pCur = Io_ReadDsdFindEnd( pCur );
if ( pCur == NULL )
{
printf( "Cannot find the closing parenthesis.\n" );
break;
}
pCur++;
}
// check the end
if ( *pCur == 0 )
break;
// check symbol
if ( *pCur != '*' && *pCur != '+' && *pCur != ',' )
{
printf( "Wrong separating symbol.\n" );
break;
}
// remember the symbol
fAnd |= (*pCur == '*');
fXor |= (*pCur == '+');
fPri |= (*pCur == ',');
*pCur++ = 0;
}
// check separating symbols
if ( fAnd + fXor + fPri > 1 )
{
printf( "Different types of separating symbol ennPartsed.\n" );
return 0;
}
*pTypeXor = fXor;
return nParts;
}
/**Function*************************************************************
Synopsis [Recursively parses the formula.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Io_ReadDsd_rec( Abc_Ntk_t * pNtk, char * pCur, char * pSop )
{
Abc_Obj_t * pObj, * pFanin;
char * pEnd, * pParts[32];
int i, nParts, TypeExor;
// consider complemented formula
if ( *pCur == '!' )
{
pObj = Io_ReadDsd_rec( pNtk, pCur + 1, NULL );
return Abc_NtkCreateNodeInv( pNtk, pObj );
}
if ( *pCur == '(' )
{
assert( pCur[strlen(pCur)-1] == ')' );
pCur[strlen(pCur)-1] = 0;
nParts = Io_ReadDsdStrSplit( pCur+1, pParts, &TypeExor );
if ( nParts == 0 )
{
Abc_NtkDelete( pNtk );
return NULL;
}
pObj = Abc_NtkCreateNode( pNtk );
if ( pSop )
{
// for ( i = nParts - 1; i >= 0; i-- )
for ( i = 0; i < nParts; i++ )
{
pFanin = Io_ReadDsd_rec( pNtk, pParts[i], NULL );
if ( pFanin == NULL )
return NULL;
Abc_ObjAddFanin( pObj, pFanin );
}
}
else
{
for ( i = 0; i < nParts; i++ )
{
pFanin = Io_ReadDsd_rec( pNtk, pParts[i], NULL );
if ( pFanin == NULL )
return NULL;
Abc_ObjAddFanin( pObj, pFanin );
}
}
if ( pSop )
pObj->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, pSop );
else if ( TypeExor )
pObj->pData = Abc_SopCreateXorSpecial( (Mem_Flex_t *)pNtk->pManFunc, nParts );
else
pObj->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtk->pManFunc, nParts, NULL );
return pObj;
}
if ( *pCur >= 'a' && *pCur <= 'z' )
{
assert( *(pCur+1) == 0 );
return Abc_NtkPi( pNtk, *pCur - 'a' );
}
// skip hex truth table
pEnd = pCur;
while ( (*pEnd >= '0' && *pEnd <= '9') || (*pEnd >= 'A' && *pEnd <= 'F') )
pEnd++;
if ( *pEnd != '(' )
{
printf( "Cannot find the end of hexidecimal truth table.\n" );
return NULL;
}
// parse the truth table
*pEnd = 0;
pSop = Abc_SopFromTruthHex( pCur );
*pEnd = '(';
pObj = Io_ReadDsd_rec( pNtk, pEnd, pSop );
ABC_FREE( pSop );
return pObj;
}
/**Function*************************************************************
Synopsis [Derives the DSD network of the formula.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Io_ReadDsd( char * pForm )
{
Abc_Ntk_t * pNtk;
Abc_Obj_t * pObj, * pTop;
Vec_Ptr_t * vNames;
char * pCur, * pFormCopy;
int i, nInputs;
// count the number of elementary variables
nInputs = 0;
for ( pCur = pForm; *pCur; pCur++ )
if ( *pCur >= 'a' && *pCur <= 'z' )
nInputs = Abc_MaxInt( nInputs, *pCur - 'a' );
nInputs++;
// create the network
pNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
pNtk->pName = Extra_UtilStrsav( "dsd" );
// create PIs
vNames = Abc_NodeGetFakeNames( nInputs );
for ( i = 0; i < nInputs; i++ )
Abc_ObjAssignName( Abc_NtkCreatePi(pNtk), (char *)Vec_PtrEntry(vNames, i), NULL );
Abc_NodeFreeNames( vNames );
// transform the formula by inserting parentheses
// this transforms strings like PRIME(a,b,cd) into (PRIME((a),(b),(cd)))
pCur = pFormCopy = ABC_ALLOC( char, 3 * strlen(pForm) + 10 );
*pCur++ = '(';
for ( ; *pForm; pForm++ )
if ( *pForm == '(' )
{
*pCur++ = '(';
*pCur++ = '(';
}
else if ( *pForm == ')' )
{
*pCur++ = ')';
*pCur++ = ')';
}
else if ( *pForm == ',' )
{
*pCur++ = ')';
*pCur++ = ',';
*pCur++ = '(';
}
else
*pCur++ = *pForm;
*pCur++ = ')';
*pCur = 0;
// parse the formula
pObj = Io_ReadDsd_rec( pNtk, pFormCopy, NULL );
ABC_FREE( pFormCopy );
if ( pObj == NULL )
return NULL;
// create output
pTop = Abc_NtkCreatePo(pNtk);
Abc_ObjAssignName( pTop, "F", NULL );
Abc_ObjAddFanin( pTop, pObj );
// create the only PO
if ( !Abc_NtkCheck( pNtk ) )
{
fprintf( stdout, "Io_ReadDsd(): Network check has failed.\n" );
Abc_NtkDelete( pNtk );
return NULL;
}
return pNtk;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END