blob: 9c62212dfbcd66445b8e5682c392230c90542770 [file] [log] [blame]
/**CFile****************************************************************
FileName [mioForm.c]
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
Synopsis [Parsing equestion formula.]
Author [MVSIS Group]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 8, 2003.]
Revision [$Id: mioForm.c,v 1.4 2004/06/28 14:20:25 alanmi Exp $]
***********************************************************************/
#include "mioInt.h"
#include "bdd/parse/parse.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// these symbols (and no other) can appear in the formulas
#define MIO_SYMB_AND '*'
#define MIO_SYMB_AND2 '&'
#define MIO_SYMB_OR '+'
#define MIO_SYMB_OR2 '|'
#define MIO_SYMB_XOR '^'
#define MIO_SYMB_NOT '!'
#define MIO_SYMB_AFTNOT '\''
#define MIO_SYMB_OPEN '('
#define MIO_SYMB_CLOSE ')'
static int Mio_GateParseFormula( Mio_Gate_t * pGate );
static int Mio_GateCollectNames( char * pFormula, char * pPinNames[] );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Deriving the functionality of the gates.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Mio_LibraryParseFormulas( Mio_Library_t * pLib )
{
Mio_Gate_t * pGate;
// count the gates
pLib->nGates = 0;
Mio_LibraryForEachGate( pLib, pGate )
pLib->nGates++;
// start a temporary BDD manager
pLib->dd = Cudd_Init( 20, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
// introduce ZDD variables
Cudd_zddVarsFromBddVars( pLib->dd, 2 );
// for each gate, derive its function
Mio_LibraryForEachGate( pLib, pGate )
if ( Mio_GateParseFormula( pGate ) )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis [Registers the cube string with the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Mio_SopRegister( Mem_Flex_t * pMan, char * pName )
{
char * pRegName;
if ( pName == NULL ) return NULL;
pRegName = Mem_FlexEntryFetch( pMan, strlen(pName) + 1 );
strcpy( pRegName, pName );
return pRegName;
}
/**Function*************************************************************
Synopsis [Deriving the functionality of the gates.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Mio_GateParseFormula( Mio_Gate_t * pGate )
{
extern char * Abc_ConvertBddToSop( Mem_Flex_t * pMan, DdManager * dd, DdNode * bFuncOn, DdNode * bFuncOnDc, int nFanins, int fAllPrimes, Vec_Str_t * vCube, int fMode );
DdManager * dd = pGate->pLib->dd;
char * pPinNames[100];
char * pPinNamesCopy[100];
Mio_Pin_t * pPin, ** ppPin;
int nPins, iPin, i;
// set the maximum delay of the gate; count pins
pGate->dDelayMax = 0.0;
nPins = 0;
Mio_GateForEachPin( pGate, pPin )
{
// set the maximum delay of the gate
if ( pGate->dDelayMax < pPin->dDelayBlockMax )
pGate->dDelayMax = pPin->dDelayBlockMax;
// count the pin
nPins++;
}
// check for the gate with const function
if ( nPins == 0 )
{
if ( strcmp( pGate->pForm, MIO_STRING_CONST0 ) == 0 )
{
pGate->bFunc = b0;
pGate->pSop = Mio_SopRegister( (Mem_Flex_t *)pGate->pLib->pMmFlex, " 0\n" );
pGate->pLib->pGate0 = pGate;
}
else if ( strcmp( pGate->pForm, MIO_STRING_CONST1 ) == 0 )
{
pGate->bFunc = b1;
pGate->pSop = Mio_SopRegister( (Mem_Flex_t *)pGate->pLib->pMmFlex, " 1\n" );
pGate->pLib->pGate1 = pGate;
}
else
{
printf( "Cannot parse formula \"%s\" of gate \"%s\".\n", pGate->pForm, pGate->pName );
return 1;
}
Cudd_Ref( pGate->bFunc );
return 0;
}
// collect the names as they appear in the formula
nPins = Mio_GateCollectNames( pGate->pForm, pPinNames );
if ( nPins == 0 )
{
printf( "Cannot read formula \"%s\" of gate \"%s\".\n", pGate->pForm, pGate->pName );
return 1;
}
// set the number of inputs
pGate->nInputs = nPins;
// consider the case when all the pins have identical pin info
if ( strcmp( pGate->pPins->pName, "*" ) == 0 )
{
// get the topmost (generic) pin
pPin = pGate->pPins;
ABC_FREE( pPin->pName );
// create individual pins from the generic pin
ppPin = &pPin->pNext;
for ( i = 1; i < nPins; i++ )
{
// get the new pin
*ppPin = Mio_PinDup( pPin );
// set its name
(*ppPin)->pName = pPinNames[i];
// prepare the next place in the list
ppPin = &((*ppPin)->pNext);
}
*ppPin = NULL;
// set the name of the topmost pin
pPin->pName = pPinNames[0];
}
else
{
// reorder the variable names to appear the save way as the pins
iPin = 0;
Mio_GateForEachPin( pGate, pPin )
{
// find the pin with the name pPin->pName
for ( i = 0; i < nPins; i++ )
{
if ( pPinNames[i] && strcmp( pPinNames[i], pPin->pName ) == 0 )
{
// free pPinNames[i] because it is already available as pPin->pName
// setting pPinNames[i] to NULL is useful to make sure that
// this name is not assigned to two pins in the list
ABC_FREE( pPinNames[i] );
pPinNamesCopy[iPin++] = pPin->pName;
break;
}
if ( i == nPins )
{
printf( "Cannot find pin name \"%s\" in the formula \"%s\" of gate \"%s\".\n",
pPin->pName, pGate->pForm, pGate->pName );
return 1;
}
}
}
// check for the remaining names
for ( i = 0; i < nPins; i++ )
if ( pPinNames[i] )
{
printf( "Name \"%s\" appears in the formula \"%s\" of gate \"%s\" but there is no such pin.\n",
pPinNames[i], pGate->pForm, pGate->pName );
return 1;
}
// copy the names back
memcpy( pPinNames, pPinNamesCopy, nPins * sizeof(char *) );
}
// expand the manager if necessary
if ( dd->size < nPins )
{
Cudd_Quit( dd );
dd = Cudd_Init( nPins + 10, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
Cudd_zddVarsFromBddVars( dd, 2 );
}
// derive the formula as the BDD
pGate->bFunc = Parse_FormulaParser( stdout, pGate->pForm, nPins, 0, pPinNames, dd, dd->vars );
if ( pGate->bFunc == NULL )
return 1;
Cudd_Ref( pGate->bFunc );
// derive the cover (SOP)
pGate->pSop = Abc_ConvertBddToSop( pGate->pLib->pMmFlex, dd, pGate->bFunc, pGate->bFunc, nPins, 0, pGate->pLib->vCube, -1 );
// derive the truth table
if ( pGate->nInputs <= 6 )
pGate->uTruth = Mio_DeriveTruthTable6( pGate );
return 0;
}
/**Function*************************************************************
Synopsis [Collect the pin names in the formula.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Mio_GateCollectNames( char * pFormula, char * pPinNames[] )
{
char Buffer[1000];
char * pTemp;
int nPins, i;
// save the formula as it was
strcpy( Buffer, pFormula );
// remove the non-name symbols
for ( pTemp = Buffer; *pTemp; pTemp++ )
if ( *pTemp == MIO_SYMB_AND || *pTemp == MIO_SYMB_AND2 ||
*pTemp == MIO_SYMB_OR || *pTemp == MIO_SYMB_OR2 ||
*pTemp == MIO_SYMB_XOR ||
*pTemp == MIO_SYMB_NOT || *pTemp == MIO_SYMB_AFTNOT ||
*pTemp == MIO_SYMB_OPEN || *pTemp == MIO_SYMB_CLOSE )
*pTemp = ' ';
// save the names
nPins = 0;
pTemp = strtok( Buffer, " " );
while ( pTemp )
{
for ( i = 0; i < nPins; i++ )
if ( strcmp( pTemp, pPinNames[i] ) == 0 )
break;
if ( i == nPins )
{ // cannot find this name; save it
pPinNames[nPins++] = Abc_UtilStrsav(pTemp);
}
// get the next name
pTemp = strtok( NULL, " " );
}
return nPins;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END