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