/**CFile*********************************************************************** FileName [ioParse.c] PackageName [io] Synopsis [Functions used in parsing BLIF-MV files.] Description [] SeeAlso [] Author [Yuji Kukimoto, Rajeev Ranjan, Huey-Yih Wang] Copyright [Copyright (c) 1994-1996 The Regents of the Univ. of California. All rights reserved. Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that the above copyright notice and the following two paragraphs appear in all copies of this software. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.] ******************************************************************************/ #include "ioInt.h" static char rcsid[] UNUSED = "$Id: ioParse.c,v 1.4 2002/08/16 17:35:01 fabio Exp $"; /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Type declarations */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Stucture declarations */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Variable declarations */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ /**AutomaticStart*************************************************************/ /*---------------------------------------------------------------------------*/ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ static void _IoParserAddSubckt(array_t **subcktArray, char *modelName, char *instanceName, array_t *formalNameArray, array_t *actualNameArray); static int _IoIOProcess(Hrc_Node_t *hnode, char *name, int type); static IoPTable_t * _IoPTableCreate(array_t *inputArray, array_t *outputArray, array_t *defaultArray, array_t *symCubeArray); static void _IoPTableFree(IoPTable_t *pTable); /**AutomaticEnd***************************************************************/ /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Definition of internal functions */ /*---------------------------------------------------------------------------*/ /**Function******************************************************************** Synopsis [Finds or allocate a variable by name in a hnode.] Description [Finds a variable by name in a hnode. If success, returns a pointer to the variable. Otherwise allocates a new variable and return a pointer to the variable..] SideEffects [] SeeAlso [Var_VariableFree] ******************************************************************************/ Var_Variable_t * IoVariableFindOrAllocByName( Hrc_Node_t *hnode, char *name) { Var_Variable_t *var; if ((var = Hrc_NodeFindVariableByName(hnode,name)) != NIL(Var_Variable_t)){ return var; } var = Var_VariableAlloc(hnode,name); return var; } /**Function******************************************************************** Synopsis [Converts a character string to the integer.] Description [Converts a character string to the positive integer. Returns -1 if the string does not represent an integer.] SideEffects [] SeeAlso [] ******************************************************************************/ int IoAtoi(char *string) { char *s; for (s=string; *s!='\0'; s++) { if (isdigit((int) *s)==0){ return -1; } } return atoi(string); } /**Function******************************************************************** Synopsis [Frees an array of strings.] Description [Frees an array of strings. Strings themselves are also freed.] SideEffects [] SeeAlso [] ******************************************************************************/ void IoStringArrayFree(array_t *array) { int i; char *symbol; for (i=0; i < array_n(array); i++) { symbol = array_fetch(char *, array, i); FREE(symbol); } array_free(array); } /**Function******************************************************************** Synopsis [Insert a character string to an array.] Description [Insert a character string to an array. The string is not copied. Note that the first argument is not a pointer to an array, but a pointer to a pointer to an array.] SideEffects [] SeeAlso [] ******************************************************************************/ void IoNameInsertInArray(array_t **arrayPtrPtr, char *name) { if (*arrayPtrPtr == NIL(array_t)){ *arrayPtrPtr = array_alloc(char *, 0); } array_insert_last(char *, *arrayPtrPtr, name); } /**Function******************************************************************** Synopsis [Inserts a IoSymValue_t structure to an array.] Description [Inserts a IoSymValue_t structure to an array. Note that the first argument is a pointer to a pointer to the array.] SideEffects [] SeeAlso [] ******************************************************************************/ void IoSymValueInsertInArray(array_t **arrayPtrPtr, IoSymValue_t *value) { if (*arrayPtrPtr == NIL(array_t)){ *arrayPtrPtr = array_alloc(IoSymValue_t *, 0); } array_insert_last(IoSymValue_t *, *arrayPtrPtr, value); } /**Function******************************************************************** Synopsis [Inserts a SymCube(an array of IoSymValue_t) to an array.] Description [] SideEffects [] SeeAlso [] ******************************************************************************/ void IoSymCubeInsertInArray(array_t **arrayPtrPtr, array_t *symCube) { if (*arrayPtrPtr == NIL(array_t)){ *arrayPtrPtr = array_alloc(array_t *, 0); } array_insert_last(array_t *, *arrayPtrPtr, symCube); } /**Function******************************************************************** Synopsis [Reads in .inputs constructs.] Description [Reads in .inputs constructs. Returns 1 if success. 0 otherwise.] SideEffects [] SeeAlso [] ******************************************************************************/ boolean IoInputProcess( Hrc_Node_t *hnode, char *name) { return _IoIOProcess(hnode, name, 0); } /**Function******************************************************************** Synopsis [Reads in .outputs constructs.] Description [Reads in .outputs constructs. Returns 1 if success. 0 otherwise.] SideEffects [] SeeAlso [] ******************************************************************************/ boolean IoOutputProcess( Hrc_Node_t *hnode, char *name) { return _IoIOProcess(hnode, name, 1); } /**Function******************************************************************** Synopsis [Reads in .mv constructs.] Description [Reads in .mv constructs. Returns 1 if success. 0 otherwise.] SideEffects [] SeeAlso [] ******************************************************************************/ boolean IoMvProcess( Hrc_Model_t *model, Hrc_Node_t *hnode, array_t *varNames, int range, array_t *symValues) { int i; char *varName; Var_Variable_t *var; if (range == -1) { error_append("Invalid .mv specification of "); error_append(array_fetch(char *,varNames,0)); error_append(" in model "); error_append(Hrc_ModelReadName(model)); error_append("\n- Range should be an integer.\n"); return 0; } for (i=0; i < array_n(varNames); i++){ varName = array_fetch(char *,varNames,i); if ((var = Hrc_NodeFindVariableByName(hnode,varName)) != NIL(Var_Variable_t)) { if (Var_VariableAddRangeInfo(var,range,symValues) == 0){ error_append("Invalid .mv specification of "); error_append(varName); error_append(" in model "); error_append(Hrc_ModelReadName(model)); error_append("\n- You are trying to redefine the above variable.\n"); return 0; } } else { var = Var_VariableAlloc(hnode,varName); (void)Var_VariableAddRangeInfo(var,range,symValues); } } return 1; } /**Function******************************************************************** Synopsis [Reads in .latch constructs.] Description [Reads in .latch constructs. Returns 1 if success. 0 otherwise.] SideEffects [] SeeAlso [] ******************************************************************************/ boolean IoLatchProcess( Hrc_Model_t *model, Hrc_Node_t *hnode, char *latchInput, char *latchOutput) { Var_Variable_t *varIn, *varOut; varIn = IoVariableFindOrAllocByName(hnode,latchInput); varOut = IoVariableFindOrAllocByName(hnode,latchOutput); if (varIn == NIL(Var_Variable_t) || varOut == NIL(Var_Variable_t)){ return 0; } if ((Hrc_LatchCreate(model,varIn,varOut)) == NIL(Hrc_Latch_t)){ return 0; } (void)Var_VariableSetNS(varIn); /* a latch can have only one fanin */ if (Var_VariableSetPS(varOut) == 0){ error_append("Variable "); error_append(latchOutput); error_append(" are fed by more than one latch\n"); return 0; } return 1; } /**Function******************************************************************** Synopsis [Reads in .table constructs.] Description [Reads in .table constructs. Returns 1 if success. 0 otherwise.] SideEffects [] SeeAlso [] ******************************************************************************/ boolean IoTableProcess( Hrc_Model_t *model, Hrc_Node_t *hnode, array_t *inputArray, array_t *outputArray, array_t *defaultArray, array_t *symCubeArray) { IoPTable_t *pTable; Tbl_Table_t *table; pTable = _IoPTableCreate(inputArray,outputArray,defaultArray,symCubeArray); if ((table = IoPTableTransformToTable(model, hnode, pTable)) == NIL(Tbl_Table_t)){ _IoPTableFree(pTable); return 0; } _IoPTableFree(pTable); Hrc_ModelAddNameTable(model,table); return 1; } /**Function******************************************************************** Synopsis [Reads in .reset constructs.] Description [Reads in .reset constructs. Returns 1 if success. 0 otherwise.] SideEffects [] SeeAlso [] ******************************************************************************/ boolean IoResetProcess( array_t **resetArray, Hrc_Model_t *model, Hrc_Node_t *hnode, array_t *inputArray, array_t *outputArray, array_t *defaultArray, array_t *symCubeArray) { IoPTable_t *pTable; Tbl_Table_t *table; pTable = _IoPTableCreate(inputArray,outputArray,defaultArray,symCubeArray); if ((table = IoPTableTransformToTable(model,hnode,pTable)) == NIL(Tbl_Table_t)){ _IoPTableFree(pTable); return 0; } _IoPTableFree(pTable); if (*resetArray == NIL(array_t)){ *resetArray = array_alloc(Tbl_Table_t *,0); } array_insert_last(Tbl_Table_t *,*resetArray,table); return 1; } /**Function******************************************************************** Synopsis [Reads in .subckt constructs.] Description [Reads in .subckt constructs. Returns 1 if success. 0 otherwise.] SideEffects [] SeeAlso [] ******************************************************************************/ boolean IoSubcktProcess( array_t **subcktArray, Hrc_Model_t *model, Hrc_Node_t *hnode, char *modelName, char *instanceName, array_t *formalNameArray, array_t *actualNameArray) { int i; char *actual; Var_Variable_t *var; for (i=0; i < array_n(actualNameArray); i++){ actual = array_fetch(char *,actualNameArray,i); var = IoVariableFindOrAllocByName(hnode,actual); if (var == NIL(Var_Variable_t)){ error_append("Problem in defining variable "); error_append(actual); error_append(" found in subckt "); error_append(instanceName); error_append(" in model "); error_append(Hrc_ModelReadName(model)); error_append("\n"); return 0; } } _IoParserAddSubckt(subcktArray,modelName,instanceName,formalNameArray,actualNameArray); return 1; } /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ /**Function******************************************************************** Synopsis [Add subckt information to the data structure where the parser maintains all the subckt data.] Description [] SideEffects [] SeeAlso [] ******************************************************************************/ static void _IoParserAddSubckt( array_t **subcktArray, char *modelName, char *instanceName, array_t *formalNameArray, array_t *actualNameArray) { IoSubckt_t *subckt; subckt = ALLOC(IoSubckt_t,1); subckt->modelName = modelName; subckt->instanceName = instanceName; subckt->formalNameArray = formalNameArray; subckt->actualNameArray = actualNameArray; if (*subcktArray == NIL(array_t)){ *subcktArray = array_alloc(IoSubckt_t *,0); } array_insert_last(IoSubckt_t *, *subcktArray, subckt); } /**Function******************************************************************** Synopsis [Process .inputs and .outputs construct.] Description [Process .inputs and .outputs construct. Returns 1 if success. Otherwise returns 0.] SideEffects [] SeeAlso [] ******************************************************************************/ static int _IoIOProcess( Hrc_Node_t *hnode, char *name, int type) { Var_Variable_t *var; if (Hrc_NodeFindVariableByName(hnode, name) != NIL(Var_Variable_t)) { error_append("Variable "); error_append(name); error_append(" is tried to be set to PI and PO in model "); error_append(Hrc_NodeReadModelName(hnode)); error_append("\n"); return 0; } var = Var_VariableAlloc(hnode,name); switch(type){ case 0: /* PI */ Hrc_NodeAddFormalInput(hnode,var); /* the following is now a part of Hrc_NodeAddFormalInput */ /*(void)Var_VariableSetPI(var);*/ break; case 1: /* PO */ Hrc_NodeAddFormalOutput(hnode,var); /* the following is now a part of Hrc_NodeAddFormalOutput */ /*(void)Var_VariableSetPO(var);*/ break; default: fail("Strange argument is given to variable type in IOProcess\n"); } return 1; } /**Function******************************************************************** Synopsis [Allocates a temporary data structure for parsing tables.] Description [] SideEffects [] SeeAlso [] ******************************************************************************/ static IoPTable_t * _IoPTableCreate( array_t *inputArray, array_t *outputArray, array_t *defaultArray, array_t *symCubeArray) { IoPTable_t *pTable; pTable = ALLOC(IoPTable_t,1); if (inputArray == NIL(array_t)){ pTable->inputs = array_alloc(char *,0); } else { pTable->inputs = inputArray; } assert(outputArray != NIL(array_t)); pTable->outputs = outputArray; pTable->defaultOutput = defaultArray; pTable->cubes = symCubeArray; return pTable; } /**Function******************************************************************** Synopsis [Frees a temporary data structure for parsing the tables.] Description [] SideEffects [] SeeAlso [] ******************************************************************************/ static void _IoPTableFree(IoPTable_t *pTable) { int i; array_t *symValueArray; IoStringArrayFree(pTable->inputs); IoStringArrayFree(pTable->outputs); if (pTable->defaultOutput != NIL(array_t)){ IoSymValueArrayFree(pTable->defaultOutput); } if (pTable->cubes != NIL(array_t)){ for (i=0; i < array_n(pTable->cubes); i++){ symValueArray = array_fetch(array_t *,pTable->cubes,i); IoSymValueArrayFree(symValueArray); } array_free(pTable->cubes); } FREE(pTable); }