mirror of https://github.com/YosysHQ/abc.git
314 lines
8.3 KiB
C
314 lines
8.3 KiB
C
/**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
|
|
|