VIS

src/io/ioWriteBlif.c

Go to the documentation of this file.
00001 
00038 #include "ioInt.h"
00039 
00040 static char rcsid[] UNUSED = "$Id: ioWriteBlif.c,v 1.14 2005/04/29 14:23:29 fabio Exp $";
00041 
00042 /*---------------------------------------------------------------------------*/
00043 /* Constant declarations                                                     */
00044 /*---------------------------------------------------------------------------*/
00045 #define MAX_NUMBER_BDD_VARS 500
00046 
00047 /*---------------------------------------------------------------------------*/
00048 /* Macro declarations                                                        */
00049 /*---------------------------------------------------------------------------*/
00050 
00051 
00052 
00055 /*---------------------------------------------------------------------------*/
00056 /* Static function prototypes                                                */
00057 /*---------------------------------------------------------------------------*/
00058 
00059 static int _IoTableWriteBlif(Io_Encoding_Type_t encodingType, Hrc_Node_t *hnode, Tbl_Table_t *origBlifmvTable, st_table *blifInputsStTable, FILE *fp, FILE *encFp, int verbosity);
00060 static int _IoMakeInitialEncodings(IoBlifInfo_t *blifInfo, Hrc_Node_t *hnode);
00061 static void _IoDeterminizeEncodeOutputPart(IoBlifInfo_t *blifInfo, st_table *blifInputsStTable);
00062 static void _IoDeterminizeEncodeRows(IoBlifInfo_t *blifInfo, st_table *blifInputsStTable);
00063 static void _IoMakeDcTables(IoBlifInfo_t *blifInfo);
00064 static void _IoMakeBinTable(IoBlifInfo_t *blifInfo);
00065 static int _IoCheckHnodeTreeIsBooleanAndDeterministic(mdd_manager **mddMgr, Hrc_Node_t *hnode, st_table *modelTable, boolean *pSymVarsPresent, int verbosity);
00066 static int _IoCheckHnodeVarsAreBoolean(Hrc_Node_t *hnode, boolean *pSymVarsPresent);
00067 static int _IoCheckHnodeLatchResetIsConstant(Hrc_Node_t *hnode);
00068 static int _IoCheckHnodeTablesAreDeterministic(mdd_manager **mddMgr, Hrc_Node_t *hnode);
00069 static void _MddManagerResetIfNecessary(mdd_manager **mddMgr);
00070 static void _IoHnodeWriteBlifRecursively(Io_Encoding_Type_t encodingType, Hrc_Node_t *hnode, st_table *modelTable, FILE *fp, FILE *encFp, int verbosity);
00071 static int _IoHnodeWriteBlifRecursivelyStep(Io_Encoding_Type_t encodingType, Hrc_Node_t *hnode, FILE *fp, FILE *encFp, int verbosity);
00072 static int _IoCheckHnodeIsBooleanAndDeterministic(mdd_manager **mddMgr, Hrc_Node_t *hnode, boolean *pSymVarsPresent);
00073 static int _IoCheckPseudoinputIsPO(Tbl_Table_t *table);
00074 
00078 /*---------------------------------------------------------------------------*/
00079 /* Definition of exported functions                                          */
00080 /*---------------------------------------------------------------------------*/
00081 
00107 int
00108 Io_HnodeWriteBlifTotal(
00109     Io_Encoding_Type_t encodingType,
00110     Hrc_Node_t *hnode, 
00111     FILE *fp, 
00112     int verbosity)
00113 {
00114   st_table *modelTable;
00115   Hrc_Manager_t *manager;
00116   mdd_manager *mddMgr;
00117   FILE *encFp;
00118   boolean symVarsPresent;
00119   
00120   manager = Hrc_NodeReadManager(hnode);
00121   modelTable = st_init_table(st_ptrcmp, st_ptrhash);
00122   mddMgr = mdd_init_empty();
00123   bdd_dynamic_reordering(mddMgr, BDD_REORDER_SIFT, BDD_REORDER_VERBOSITY_DEFAULT);
00124   symVarsPresent = FALSE;
00125 
00126   /* check that the node and all its children are boolean and deterministic. */
00127   if(_IoCheckHnodeTreeIsBooleanAndDeterministic(&mddMgr, hnode, modelTable, &symVarsPresent, verbosity)){
00128     mdd_quit(mddMgr);
00129     st_free_table(modelTable);
00130     return 1;
00131   }
00132   if(verbosity > 0){
00133     fprintf(vis_stderr, "Done with hierarcy checks\n");
00134   }
00135   
00136   if(symVarsPresent == TRUE){
00137     fprintf(vis_stderr, "Warning - some variables in the hierarchy are symbolic\n");
00138   }
00139   
00140   st_free_table(modelTable);
00141   modelTable = st_init_table(st_ptrcmp, st_ptrhash);  
00142   encFp = Cmd_FileOpen("/dev/null", "w", NIL(char *), 1);
00143 
00144   _IoHnodeWriteBlifRecursively(encodingType, hnode, modelTable, fp, encFp, verbosity);
00145   Hrc_ManagerSetCurrentNode(manager, hnode);
00146 
00147   st_free_table(modelTable);
00148   mdd_quit(mddMgr);
00149   return 0;
00150 }
00151     
00152 
00184 int
00185 Io_HnodeWriteBlif(
00186     Io_Encoding_Type_t encodingType,
00187     Hrc_Node_t *hnode,
00188     FILE *fp,
00189     FILE *encFp,
00190     int verbosity,
00191     int combinationalOnly,
00192     int makeLatchIOsPOs)
00193 {
00194     Tbl_Table_t *table, *singleOutputTable;
00195     Tbl_Entry_t *entry;
00196     int i, j, k, numVal, numInputs, numOutputs;
00197     Var_Variable_t *var, *actualVar, *outputVar;
00198     char *name, *instanceName, *modelName, *newModelName;
00199     st_generator *gen;
00200     st_table *blifInputsStTable, *blifOutputsStTable, *printedMvsStTable;
00201     st_table *encOutputsStTable, *encInputsStTable;
00202     Hrc_Node_t *subcktHnode;
00203     Hrc_Model_t *model, *subcktModel;
00204     Hrc_Subckt_t *subckt;
00205     Hrc_Manager_t *manager;
00206     array_t *subcktActualInputVars, *subcktActualOutputVars;
00207    
00208 
00209     Hrc_NodeForEachNameTable(hnode, i, table){
00210       if(_IoCheckPseudoinputIsPO(table)){
00211         fprintf(stdout, "Hnode contains a pseudoinput which is also a primary output - quitting\n");
00212         return 1;
00213       }
00214       for(j = 0; j < Tbl_TableReadNumOutputs(table); j++){
00215         entry = Tbl_TableDefaultReadEntry(table, j);
00216         if(entry != NIL(Tbl_Entry_t)){
00217           if(Tbl_EntryReadType(entry) == Tbl_EntryNormal_c){
00218             if(Tbl_EntryReadNumValues(entry) > 1){
00219               outputVar = Tbl_TableReadIndexVar(table, j, 1);
00220               (void)fprintf(stdout, "The table with %s as an output has non-singleton default values - quitting\n", Var_VariableReadName(outputVar));
00221               return 1;
00222             }
00223           }
00224           else{
00225             var = Tbl_EntryReadVar(table, entry);
00226             k = Tbl_TableReadVarIndex(table, var, 1);
00227             if(k<0){
00228               outputVar = Tbl_TableReadIndexVar(table, j, 1);         
00229               (void)fprintf(stdout, "Output %s has a default value that refers to an input variable - quitting\n", Var_VariableReadName(outputVar));
00230               return 1;
00231             }
00232           }
00233         }
00234       }
00235     }
00236 
00237     printedMvsStTable = st_init_table(strcmp, st_strhash);
00238 
00239     if(!(combinationalOnly || makeLatchIOsPOs)){
00240       fprintf(encFp,"# This encoding file and the blif file that was written out with it cannot\n");           
00241       fprintf(encFp,"# currently be read back into VIS. If you would like to read the blif and\n");           
00242       fprintf(encFp,"# encoding files back into VIS, then use the 'write_blif -l' or\n");
00243       fprintf(encFp,"#'write_blif -c' options.\n");
00244     }
00245 
00246   /* .model */
00247     modelName = Hrc_NodeReadModelName(hnode);
00248     manager = Hrc_NodeReadManager(hnode);
00249     model = Hrc_ManagerFindModelByName(manager, modelName);
00250     newModelName = ALLOC(char, strlen(modelName) + 256);
00251     i = 0;
00252     sprintf(newModelName, "%s[%d]", modelName, i);
00253 
00254     while(Hrc_ManagerFindModelByName(manager, newModelName) != NIL(Hrc_Model_t)){
00255         i++;
00256         sprintf(newModelName, "%s[%d]", modelName, i);
00257     }
00258     (void)fprintf(encFp,".model %s\n",newModelName);
00259     FREE(newModelName);
00260     /* .inputs line of enc file*/
00261     if (Hrc_NodeReadNumFormalInputs(hnode) != 0){
00262         (void)fprintf(encFp,".inputs ");
00263         Hrc_NodeForEachFormalInput(hnode,i,var){
00264             (void)fprintf(encFp,"%s ",Var_VariableReadName(var));
00265         }
00266         (void)fprintf(encFp,"\n");
00267     }
00268     
00269     /* .outputs line of enc file*/
00270     if (Hrc_NodeReadNumFormalOutputs(hnode) != 0){
00271         (void)fprintf(encFp,".outputs ");
00272         Hrc_NodeForEachFormalOutput(hnode,i,var){
00273             (void)fprintf(encFp,"%s ",Var_VariableReadName(var));
00274         }
00275         (void)fprintf(encFp,"\n");
00276     }
00277     
00278     /* .mv for primary inputs, printed to enc file*/
00279     Hrc_NodeForEachFormalInput(hnode,i,var){
00280         IoMvCheckPrint(encFp,var,printedMvsStTable);
00281     }
00282     /* .mv for primary outputs, printed to enc file*/
00283     Hrc_NodeForEachFormalOutput(hnode,i,var){
00284         IoMvCheckPrint(encFp,var,printedMvsStTable);
00285     }
00286     
00287     /* .subckt stuff */
00288     Hrc_ModelForEachSubckt(model,gen,instanceName,subckt){
00289         subcktModel = Hrc_SubcktReadModel(subckt);
00290         subcktHnode = Hrc_ModelReadMasterNode(subcktModel);
00291         subcktActualInputVars = Hrc_SubcktReadActualInputVars(subckt);
00292         subcktActualOutputVars = Hrc_SubcktReadActualOutputVars(subckt);
00293         
00294         /* .mv for subckt inputs */
00295         for (i=0; i < array_n(subcktActualInputVars); i++){
00296             var = array_fetch(Var_Variable_t *,subcktActualInputVars,i);
00297             IoMvCheckPrint(encFp,var,printedMvsStTable);
00298         }
00299 
00300         /* .mv for subckt outputs */
00301         for (i=0; i < array_n(subcktActualOutputVars); i++){
00302             var = array_fetch(Var_Variable_t *,subcktActualOutputVars,i);
00303             IoMvCheckPrint(encFp,var,printedMvsStTable);
00304         }
00305 
00306         /* .subckt declarations */
00307         (void)fprintf(encFp,".subckt %s %s ",
00308                       Hrc_ModelReadName(subcktModel), Hrc_SubcktReadInstanceName(subckt));
00309         Hrc_NodeForEachFormalInput(subcktHnode,i,var){
00310             actualVar = array_fetch(Var_Variable_t *,subcktActualInputVars,i);
00311             (void)fprintf(encFp,"%s = %s ",Var_VariableReadName(var),Var_VariableReadName(actualVar)); 
00312         }   
00313         Hrc_NodeForEachFormalOutput(subcktHnode,i,var){
00314             actualVar = array_fetch(Var_Variable_t *,subcktActualOutputVars,i);
00315             (void)fprintf(encFp,"%s = %s ",Var_VariableReadName(var),Var_VariableReadName(actualVar)); 
00316         }   
00317         (void)fprintf(encFp,"\n");
00318     }
00319 
00320     encOutputsStTable = st_init_table(st_ptrcmp, st_ptrhash);
00321     encInputsStTable = st_init_table(st_ptrcmp, st_ptrhash);
00322     blifInputsStTable = st_init_table(strcmp, st_strhash);
00323     blifOutputsStTable = st_init_table(strcmp, st_strhash);
00324 
00325     /* encoding tables to .enc file */
00326     IoEncWriteMvToBinTables(hnode, encFp, encOutputsStTable, encInputsStTable, combinationalOnly);
00327 
00328     /* decoding tables to .enc file */
00329     IoEncWriteBinToMvTables(hnode, encFp, encOutputsStTable, encInputsStTable, combinationalOnly, makeLatchIOsPOs);
00330 
00331     /* if write_blif called without -c or -l options, then print a warning saying
00332        that the files cant be read back into vis..
00333     */
00334     if(!(combinationalOnly || makeLatchIOsPOs)){
00335       fprintf(fp,"# This blif file and the encoding file that was written out with it cannot\n");           
00336       fprintf(fp,"# currently be read back into VIS. If you would like to read the blif and\n");           
00337       fprintf(fp,"# encoding files back into VIS, then use the 'write_blif -l' or\n");
00338       fprintf(fp,"#'write_blif -c' options.\n");
00339     }
00340     
00341     /* .inputs declarations for blif file */
00342     fprintf(fp,".model %s\n",modelName );     
00343     numInputs = IoBlifWriteInputs(hnode, fp, blifInputsStTable, combinationalOnly, makeLatchIOsPOs);
00344 
00345     /* .outputs declarations for blif file */
00346     numOutputs = IoBlifWriteOutputs(hnode, fp, blifOutputsStTable, combinationalOnly, makeLatchIOsPOs);
00347 
00348     if((numInputs == 0) && (numOutputs != 0)){
00349       fprintf(vis_stderr, "Warning: Blif file has zero inputs\n");
00350     }
00351     if((numOutputs == 0) && (numInputs != 0)){
00352       fprintf(vis_stderr, "Warning: Blif file has zero outputs\n");
00353     }
00354     if((numInputs == 0) && (numOutputs == 0)){
00355       fprintf(vis_stderr, "Warning: Blif file has zero inputs and zero outputs\n");
00356     }
00357 
00358     /* .latch declarations for blif file */
00359     IoWriteLatches(hnode, fp, encFp, printedMvsStTable, blifOutputsStTable, blifInputsStTable, encOutputsStTable, encInputsStTable, combinationalOnly, makeLatchIOsPOs, verbosity);
00360     Hrc_NodeForEachNameTable(hnode, i, table){
00361         if((Tbl_TableReadNumInputs(table) == 0) && (Tbl_TableReadNumOutputs(table) > 1)){
00362             (void)fprintf(stdout, "Warning: ");
00363             Tbl_TableForEachOutputVar(table, j, var){
00364                 (void)fprintf(stdout, "%s, ", Var_VariableReadName(var));
00365             }
00366             (void)fprintf(stdout, "assumed to be pseudoinputs\n");
00367             Tbl_TableForEachOutputVar(table, j, var){
00368                 singleOutputTable = Tbl_TableAlloc();
00369                 Tbl_TableAddColumn(singleOutputTable, var, 1);
00370                 (void) Tbl_TableAddRow(singleOutputTable);
00371                 entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00372                 numVal = Var_VariableReadNumValues(var);
00373                 Tbl_EntrySetValue(entry, 0, numVal - 1);
00374                 Tbl_TableSetEntry(singleOutputTable, entry, 0, 0, 1);
00375                 _IoTableWriteBlif(encodingType, hnode, singleOutputTable, blifInputsStTable, fp, encFp,
00376                                   verbosity);
00377                 Tbl_TableFree(singleOutputTable);
00378             }
00379         }
00380         else{
00381           if(IoOutputExpansionRequired(table)){
00382             if(verbosity > 0){
00383               (void)fprintf(stdout, "Splitting into Single Output Table before Processing\n");
00384             }
00385             for(j = 0; j < Tbl_TableReadNumOutputs(table); j++){
00386               singleOutputTable = IoMakeSingleOutputTable(table, j);
00387               _IoTableWriteBlif(encodingType, hnode, singleOutputTable, blifInputsStTable, fp, encFp,
00388                                 verbosity);
00389               Tbl_TableFree(singleOutputTable);
00390             }
00391           }
00392           else{
00393             if(!((Tbl_TableReadNumInputs(table) == 0) && (Tbl_TableReadNumOutputs(table) > 1))){
00394               _IoTableWriteBlif(encodingType, hnode, table, blifInputsStTable, fp, encFp,
00395                                 verbosity);
00396             }
00397           }
00398         }
00399     }
00400     st_foreach_item_int(blifInputsStTable, gen, &name, &i){
00401         FREE(name);
00402     }
00403     st_free_table(blifInputsStTable);
00404     st_foreach_item_int(blifOutputsStTable, gen, &name, &i){
00405         FREE(name);
00406     }
00407     st_free_table(blifOutputsStTable);
00408     st_free_table(encInputsStTable);
00409     st_free_table(encOutputsStTable);
00410     st_foreach_item_int(printedMvsStTable, gen, &name, &i){
00411         FREE(name);
00412     }
00413     st_free_table(printedMvsStTable);
00414     /* printing an empty .exdc network keeps sis from sweeping away the
00415        dummy buffers that latch outputs are made to drive as a result of the 
00416        "write_blif -l" cmd. The dummy buffers were added because if they were 
00417        not present, sis would introduce buffers whenever latch outputs drive POs
00418        directly (in the "xdc" command), ruining the name correspondence required 
00419        for read_blif to work and reinstate mv latches.
00420     */
00421     fprintf(fp,".exdc\n");
00422     fprintf(fp,".end\n");
00423     if(encFp != stdout){
00424       (void) fclose(encFp);
00425     }
00426     return 0;
00427 }
00428 
00429 
00430 /*---------------------------------------------------------------------------*/
00431 /* Definition of internal functions                                          */
00432 /*---------------------------------------------------------------------------*/
00433 
00434     
00435 /*---------------------------------------------------------------------------*/
00436 /* Definition of static functions                                            */
00437 /*---------------------------------------------------------------------------*/
00438 
00439 
00453 static int
00454 _IoTableWriteBlif(
00455     Io_Encoding_Type_t encodingType,
00456     Hrc_Node_t *hnode,           
00457     Tbl_Table_t *origBlifmvTable,
00458     st_table *blifInputsStTable,
00459     FILE *fp,
00460     FILE *encFp,
00461     int verbosity )
00462 {
00463     IoBlifInfo_t *blifInfo;
00464 
00465     blifInfo = ALLOC(IoBlifInfo_t, 1);
00466     if(verbosity > 1){
00467         (void)fprintf(stdout, "Original Blifmv Table :\n");
00468         Tbl_TableWriteBlifMvToFile(origBlifmvTable, 0, stdout);
00469     }
00470     IoInitBlifInfo(blifInfo, origBlifmvTable, fp, encFp, verbosity);
00471     if(encodingType == SIMPLE){
00472         if(_IoMakeInitialEncodings(blifInfo, hnode)){
00473             blifInfo->binTblArray = array_alloc(Tbl_Table_t *, 0);
00474             IoFreeBlifInfo(blifInfo);
00475             return 0;
00476         }
00477         _IoDeterminizeEncodeOutputPart(blifInfo, blifInputsStTable);
00478         _IoMakeBinTable(blifInfo);
00479         if(blifInfo->verbosity > 0){
00480             (void)fprintf(stdout, "Done with Output Singletonization\n");
00481         }
00482         if(blifInfo->verbosity > 1){
00483             (void)fprintf(stdout, "Final Blifmv Table After Output Singletonization:\n");
00484             Tbl_TableWriteBlifMvToFile(blifInfo->blifmvTable, 0, stdout);    
00485             (void)fprintf(stdout, "Bin Table After Output Singletonization:\n");
00486             Tbl_TableWriteBlifMvToFile(blifInfo->binTable, 0, stdout);    
00487         }
00488         _IoDeterminizeEncodeRows(blifInfo, blifInputsStTable);     
00489         if(blifInfo->verbosity > 0){
00490             (void)fprintf(stdout, "Done with Row Intersection and Determinization\n");
00491         }
00492         if(blifInfo->verbosity > 1){
00493             (void)fprintf(stdout, "Final Bin Table After Determinization \n");
00494             Tbl_TableWriteBlifMvToFile(blifInfo->binTable, 0, stdout);    
00495         }
00496         _IoMakeDcTables(blifInfo);
00497         blifInfo->binTblArray = Tbl_TableSplit(blifInfo->binTable);
00498         IoWriteBinTablesToFile(blifInfo);
00499         IoFreeBlifInfo(blifInfo);
00500         return 0;
00501     }
00502     else{
00503         (void)fprintf(vis_stderr, "This encoding strategy has not been implemented yet\n");
00504         return 1;
00505     }
00506 }
00507   
00508 
00521 static int
00522 _IoMakeInitialEncodings(
00523    IoBlifInfo_t *blifInfo,
00524    Hrc_Node_t *hnode                   
00525    )
00526 {
00527     Var_Variable_t *var, *origVar;
00528     int i, colnum, numRows, numValues, varRange, value, numEncBits;
00529     char *name, *varname, *dupName;
00530     Tbl_Entry_t *entry, *newEntry, *defEntry, *newDefEntry;
00531     lsGen gen;
00532     Tbl_Range_t *range;
00533     Tbl_Table_t *table, *origTable;
00534 
00535     if(Tbl_TableReadNumInputs(blifInfo->blifmvTable) == 0){
00536         value = -1;
00537         if(Tbl_TableReadNumRows(blifInfo->blifmvTable) != 0){
00538           entry = Tbl_TableReadEntry(blifInfo->blifmvTable, 0, 0, 1);
00539           numValues = Tbl_EntryReadNumValues(entry);
00540         }
00541         else{
00542           entry = Tbl_TableDefaultReadEntry(blifInfo->blifmvTable, 0);
00543           numValues = Tbl_EntryReadNumValues(entry);
00544         }
00545         origTable = Tbl_TableHardDup(blifInfo->blifmvTable);
00546 
00547         if(Tbl_TableReadNumRows(blifInfo->blifmvTable) <= 1){
00548             if(numValues == 1){
00549             /* not a pseudoinput */
00550                 Tbl_EntryForEachValue(entry, value, gen, range);
00551                 assert(value != -1);
00552                 var = Tbl_TableReadIndexVar(blifInfo->blifmvTable, 0, 1);
00553                 varRange = Var_VariableReadNumValues(var);
00554                 numEncBits = IoNumEncBits(varRange);
00555                 varname = Var_VariableReadName(var);
00556                 for(i = numEncBits - 1; i >= 0; i--){
00557                     dupName = ALLOC(char, strlen(varname) + IoNumDigits(numEncBits) + 2);
00558                     sprintf(dupName, "%s%d", varname, i);
00559                     (void)fprintf(blifInfo->BlifFp, ".names %s\n", dupName);
00560                     FREE(dupName);
00561                     if(value > (int) pow((double) 2, (double) i)){
00562                         (void)fprintf(blifInfo->BlifFp, "1\n");
00563                         value -= (int) pow((double) 2, (double) i);
00564                     }
00565                     else{
00566                         (void)fprintf(blifInfo->BlifFp, "0\n");
00567                     }
00568                 }
00569                 Tbl_TableFree(origTable);
00570                 return 1;
00571             }
00572             else{
00573                 /* is a pseudoinput! */
00574                 /* make it look like a table with many rows, and singleton output entries per row */
00575                 table = Tbl_TableAlloc();
00576 
00577                 Tbl_TableForEachOutputVar(blifInfo->blifmvTable, i, var){
00578                     Tbl_TableAddColumn(table, var, 1);
00579                 }
00580                 Tbl_TableForEachDefaultEntry(blifInfo->blifmvTable, defEntry, i) {
00581                     if (defEntry != NIL(Tbl_Entry_t)) {
00582                         newDefEntry = Tbl_EntryDup(defEntry);
00583                     }
00584                     else {
00585                         newDefEntry = NIL(Tbl_Entry_t);
00586                     }
00587                     (void) Tbl_TableDefaultSetEntry(table, newDefEntry, i);
00588                 }
00589                 Tbl_EntryForEachValue(entry, value, gen, range){
00590                     i = Tbl_TableAddRow(table);
00591                     newEntry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00592                     Tbl_EntrySetValue(newEntry, value, value);
00593                     Tbl_TableSetEntry(table, newEntry, i, 0, 1);
00594                 }
00595                 Tbl_TableFree(blifInfo->blifmvTable);
00596                 blifInfo->blifmvTable = table;
00597             }
00598         }
00599         /* it is a pseudoinput, and has been singletonized wrt outputs */
00600         if(Tbl_TableReadNumRows(blifInfo->blifmvTable) > 1){
00601             name = ALLOC(char, 256);
00602             i = 0;
00603             sprintf(name, "[%d]", i);
00604             while(!(Hrc_NodeFindVariableByName(hnode, name) == NULL)){  
00605                 i++;
00606                 sprintf(name, "[%d]", i);
00607             }
00608             
00609             blifInfo->pseudoinputFlag = TRUE;
00610             var = Var_VariableAlloc(hnode, name);
00611             Tbl_TableAddColumn(blifInfo->blifmvTable, var, 0);
00612             (void)fprintf(blifInfo->BlifFp, ".inputs %s0\n", name);
00613             origVar = Tbl_TableReadIndexVar(origTable, 0, 1);
00614             IoMvPrint(blifInfo->EncFp, origVar);
00615             Tbl_TableWriteBlifMvToFile(origTable, 0, blifInfo->EncFp);    
00616             Tbl_TableFree(origTable);
00617             numRows = Tbl_TableReadNumRows(blifInfo->blifmvTable);
00618             for(i = 0; i < numRows; i++){
00619                 if(i % 2 == 1){
00620                     entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00621                     Tbl_EntrySetValue(entry, 1, 1);
00622                     Tbl_TableSetEntry(blifInfo->blifmvTable, entry, i, 0, 0);
00623                 }
00624                 else{
00625                     entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00626                     Tbl_EntrySetValue(entry, 0, 0);
00627                     Tbl_TableSetEntry(blifInfo->blifmvTable, entry, i, 0, 0);
00628                 }
00629             }
00630             FREE(name);
00631         }
00632     }
00633 
00634     Tbl_TableForEachInputVar(blifInfo->blifmvTable, colnum, var){
00635         IoEncodeVariable(blifInfo, var, colnum, 0);
00636     }
00637 
00638     Tbl_TableForEachOutputVar(blifInfo->blifmvTable, colnum, var){
00639         IoEncodeVariable(blifInfo, var, colnum, 1);
00640     }
00641     return 0;
00642 }
00643 
00644 
00659 static void
00660 _IoDeterminizeEncodeOutputPart( 
00661    IoBlifInfo_t *blifInfo,
00662    st_table *blifInputsStTable
00663    )
00664 {
00665     Tbl_Entry_t *entry;
00666     int numValues, i, j, numRows, numOutputs;
00667     IoVarEncEntry_t *varEnc;
00668     array_t *MvOutputArray;
00669 
00670     numRows = Tbl_TableReadNumRows(blifInfo->blifmvTable);
00671     numOutputs = Tbl_TableReadNumOutputs(blifInfo->blifmvTable);
00672     for(i = 0; i < numRows; i++){
00673         MvOutputArray = array_alloc(int, 0);
00674         numValues = 1;
00675         for(j = 0; j < numOutputs; j++){
00676             entry = Tbl_TableReadEntry(blifInfo->blifmvTable, i, j, 1);
00677             numValues *= Tbl_EntryReadNumValues(entry);
00678             array_insert_last(int, MvOutputArray, Tbl_EntryReadNumValues(entry));
00679         }
00680         if(numValues > 1){
00681             varEnc = IoFindSmallestCode(blifInfo);
00682             if(blifInfo->verbosity > 2){
00683                 (void)fprintf(stdout, "Singletonizing Outputs in Row %d\n", i);
00684                 (void)fprintf(stdout, "Best Variable is %s\n", Var_VariableReadName(varEnc->variable));
00685             }
00686             IoIncreaseCodeSize(varEnc, numValues, blifInfo->verbosity);
00687             IoChangeBlifmvTableEntries(blifInfo, i, numValues, varEnc, MvOutputArray);
00688             IoChangeEncTableEntries(blifInfo, blifInputsStTable, varEnc, numValues);
00689             i = -1;
00690             array_free(MvOutputArray);
00691             
00692             if(blifInfo->verbosity > 2){
00693                 (void)fprintf(stdout, "Blifmv Table After Output Singletonization\n");
00694                 Tbl_TableWriteBlifMvToFile(blifInfo->blifmvTable, 0, stdout);    
00695             }
00696         }
00697         else{
00698             array_free(MvOutputArray);
00699         }
00700     }
00701 }
00702 
00703 
00718 static void
00719 _IoDeterminizeEncodeRows( 
00720    IoBlifInfo_t *blifInfo,
00721    st_table *blifInputsStTable
00722    )
00723 {
00724     int i, j, k, numRows, numOutputs, numInputs, mvValue;
00725     boolean rowsIntersect;
00726     IoVarEncEntry_t *varEnc;
00727     char *pseudoInputName, *realPseudoInputName;
00728     Var_Variable_t *outvar, *var, *origVar;
00729     Tbl_Entry_t *entry;
00730     
00731     
00732     numRows = Tbl_TableReadNumRows(blifInfo->binTable);
00733     for(i = 0; i < numRows; i++){
00734         for(j = i + 1; j < numRows; j++){       
00735             if(blifInfo->verbosity > 2){
00736                 (void)fprintf(stdout, "Intersecting Rows %d and %d \n", i, j);
00737             }
00738             rowsIntersect = Tbl_RowInputIntersect(blifInfo->binTable, i, j); 
00739             if(rowsIntersect == 1){  
00740                 if(blifInfo->verbosity > 2){
00741                     (void)fprintf(stdout, "Input Intersection non-null\n");
00742                 }
00743                 if(!Tbl_RowOutputIntersect(blifInfo->binTable, i, j)){
00744                     varEnc = IoFindSmallestCode(blifInfo);
00745                     if(blifInfo->verbosity > 2){
00746                         (void)fprintf(stdout, "Output Intersection null\n");
00747                         (void)fprintf(stdout, "Best Variable is %s\n", Var_VariableReadName(varEnc->variable));
00748 
00749                     }
00750                     IoIncreaseCodeSize(varEnc, 2, blifInfo->verbosity); 
00751                     IoChangeBlifmvTableRows(blifInfo, varEnc, i, j);
00752                     IoChangeEncTableEntries(blifInfo, blifInputsStTable, varEnc, 2); 
00753                     
00754                     if(blifInfo->verbosity > 2){
00755                         (void)fprintf(stdout, "Bin Table After Row Overlap elimination \n");
00756                         Tbl_TableWriteBlifMvToFile(blifInfo->binTable, 0, stdout);    
00757                     }
00758                 }
00759             }
00760         }
00761     }
00762     if(blifInfo->pseudoinputFlag == TRUE){
00763         /* pseudoinput cant have .def construct */
00764         outvar = Tbl_TableReadIndexVar(blifInfo->binTable, 0, 1);
00765         pseudoInputName = Var_VariableReadName(outvar);
00766         realPseudoInputName = ALLOC(char, strlen(pseudoInputName) + 2);
00767         sprintf(realPseudoInputName, "%s", pseudoInputName);
00768         realPseudoInputName[strlen(pseudoInputName) - 1] = '\0';
00769         numOutputs = Tbl_TableReadNumOutputs(blifInfo->binTable);
00770         numInputs = Tbl_TableReadNumInputs(blifInfo->binTable);
00771         for(i = 0; i < numInputs; i++){
00772             (void)fprintf(blifInfo->EncFp, ".table %s ->", realPseudoInputName);
00773             var = Tbl_TableReadIndexVar(blifInfo->binTable, i, 0);
00774             (void)fprintf(blifInfo->EncFp, "%s\n", Var_VariableReadName(var));          
00775             (void)fprintf(blifInfo->EncFp, ".default 0\n");
00776             for(j = 0; j < numRows; j++){
00777                 mvValue = 0;
00778                 for(k = 0; k < numOutputs; k++){
00779                     entry = Tbl_TableReadEntry(blifInfo->binTable, j, k, 1);
00780                     if(Tbl_EntryCheckRange(entry, 1, 1)){
00781                         mvValue += (int) pow((double)2, (double) k);
00782                     }
00783                 }
00784                 origVar = Tbl_TableReadIndexVar(blifInfo->blifmvTable, 0, 1);
00785                 if(Var_VariableTestIsSymbolic(origVar)){
00786                     (void)fprintf(blifInfo->EncFp, "%s ",
00787                                   Var_VariableReadSymbolicValueFromIndex(origVar, mvValue));                
00788                 }
00789                 else{
00790                     (void)fprintf(blifInfo->EncFp, "%d ", mvValue);
00791                 }
00792 
00793                 entry = Tbl_TableReadEntry(blifInfo->binTable, j, i, 0);
00794                 if(Tbl_EntryCheckRange(entry, 1, 1)){
00795                     (void)fprintf(blifInfo->EncFp, "%d\n", 1);
00796                 }
00797                 else{ 
00798                     if(Tbl_EntryCheckRange(entry, 0, 0)){
00799                         (void)fprintf(blifInfo->EncFp, "%d\n", 0);
00800                     }
00801                     else{
00802                         (void)fprintf(blifInfo->EncFp, "-\n");
00803                     }
00804                 }
00805             }
00806         }
00807         FREE(realPseudoInputName);
00808     }
00809 }
00810 
00811 
00824 static void
00825 _IoMakeDcTables( 
00826    IoBlifInfo_t *blifInfo
00827    )
00828 {
00829 }
00830 
00831 
00832 
00844 static void
00845 _IoMakeBinTable( 
00846   IoBlifInfo_t *blifInfo
00847   )
00848 {
00849     int i, j, k, m, n, colnum, numRowsAfterExpansion, numEncBits;
00850     int rootCol, rootRow, entryRepetitionCount, numCycles, value, numBits, currRow;
00851     int numOutputs, numRows, numInputs, defValue, varRange;
00852     Tbl_Entry_t *entry, *workingEntry;
00853     array_t *binRangesArray, *mvEntryBinRanges;
00854     IoVarEncEntry_t *varEnc;
00855     char *varname, *dupName;
00856     Var_Variable_t *var;
00857     lsGen gen, gen2;
00858     Tbl_Range_t *range, *range2;
00859     IoBinRangeEntry_t *binRangeEntry;
00860     
00861     
00862     /* initialize the binTable, defining input vars etc   */
00863     
00864     numRows = Tbl_TableReadNumRows(blifInfo->blifmvTable);
00865     numInputs = Tbl_TableReadNumInputs(blifInfo->blifmvTable);
00866     numOutputs = Tbl_TableReadNumOutputs(blifInfo->blifmvTable);
00867     for(j = 0; j < Tbl_TableReadNumInputs(blifInfo->blifmvTable); j++){
00868         varEnc = array_fetch(IoVarEncEntry_t *, blifInfo->inputEncTblArray, j);
00869         numEncBits = varEnc->numEncBits;
00870         for(k = 0; k < numEncBits ; k++){
00871             varname = Var_VariableReadName(varEnc->variable);
00872             dupName = ALLOC(char, strlen(varname) + IoNumDigits(numEncBits) + 2);
00873             sprintf(dupName, "%s%d", varname, k);
00874             var = Var_VariableAlloc(NIL(Hrc_Node_t), dupName);
00875             FREE(dupName);
00876             array_insert_last(Var_Variable_t *, blifInfo->varArray, var);
00877             colnum = Tbl_TableAddColumn(blifInfo->binTable, var, 0);
00878         }
00879     }
00880     
00881     for(j = 0; j < Tbl_TableReadNumOutputs(blifInfo->blifmvTable); j++){
00882         varEnc = array_fetch(IoVarEncEntry_t *, blifInfo->outputEncTblArray, j);
00883         numEncBits = varEnc->numEncBits;
00884         for(k = 0; k < numEncBits ; k++){
00885             varname = Var_VariableReadName(varEnc->variable);
00886             dupName = ALLOC(char, strlen(varname) + IoNumDigits(numEncBits) + 2);
00887             sprintf(dupName, "%s%d", varname, k);
00888             var = Var_VariableAlloc(NIL(Hrc_Node_t), dupName);
00889             FREE(dupName);
00890             array_insert_last(Var_Variable_t *, blifInfo->varArray, var);
00891             colnum = Tbl_TableAddColumn(blifInfo->binTable, var, 1);
00892         }
00893     }
00894     
00895     
00896 /*
00897     fprintf(stdout, "\n");    
00898 */
00899     for(i = 0; i < numRows; i++){
00900         
00901         /* make temp array of number of values for each input var  */
00902         numRowsAfterExpansion = 1;
00903         binRangesArray = array_alloc(array_t *, 0);
00904         
00905         for(colnum = 0; colnum < numInputs; colnum++){
00906             entry = Tbl_TableReadEntry(blifInfo->blifmvTable, i, colnum, 0);
00907             workingEntry = Tbl_EntryDup(entry);
00908             mvEntryBinRanges = IoMakeBinaryRangesArray(workingEntry, colnum, blifInfo);
00909             numRowsAfterExpansion *= array_n(mvEntryBinRanges);
00910             array_insert_last(array_t *, binRangesArray, mvEntryBinRanges); 
00911         }
00912 
00913 /*
00914         for(j = 0; j < array_n(binRangesArray); j++){
00915             mvEntryBinRanges = array_fetch(array_t *, binRangesArray, j);
00916             for(k = 0; k < array_n(mvEntryBinRanges); k++){
00917                 binRangeEntry = array_fetch(IoBinRangeEntry_t *, mvEntryBinRanges, k);
00918                 fprintf(stdout, "start %d\t runlen%d\t skip %d\n", binRangeEntry->startValue, binRangeEntry->runLength, binRangeEntry->skipLength);
00919             }
00920             (void)fprintf(stdout, "\n");
00921         }
00922         fprintf(stdout, "numRowsAfterExpansion %d\n", numRowsAfterExpansion);
00923 
00924 */
00925         /* add numRowsAfterExpansion rows to binTable */
00926         
00927         rootCol = 0;
00928         rootRow = Tbl_TableReadNumRows(blifInfo->binTable);
00929         for(j = 0; j < numRowsAfterExpansion; j++){
00930             Tbl_TableAddRow(blifInfo->binTable);
00931         }
00932 
00933         /* write out binary encoded variable values for the determinized, encoded blifmvTable
00934            (input parts) */
00935 
00936         entryRepetitionCount = numRowsAfterExpansion;
00937         m = 0;
00938         numCycles = 1;
00939 
00940         for(colnum = 0; colnum < numInputs; colnum++){
00941             mvEntryBinRanges = array_fetch(array_t *, binRangesArray, colnum);
00942             currRow = rootRow;
00943             rootCol += IoNumBinVars(colnum, blifInfo->inputEncTblArray);
00944             entryRepetitionCount = entryRepetitionCount / array_n(array_fetch(array_t *, binRangesArray, m));
00945             numCycles *= IoNumValuesFromBinRangesArray(colnum, binRangesArray);
00946             numBits = IoNumBinVars(colnum + 1, blifInfo->inputEncTblArray);
00947             for(k=0; k<numCycles; k++){
00948                 for(n = 0; n < array_n(mvEntryBinRanges); n++){
00949                     binRangeEntry = array_fetch(IoBinRangeEntry_t *, mvEntryBinRanges, n);
00950                     IoWriteExpandedValueToBinTable(blifInfo->binTable, currRow, rootCol, binRangeEntry, entryRepetitionCount, numBits, 0);
00951                     currRow = currRow + entryRepetitionCount;
00952                 }
00953             }
00954             m++;
00955         }
00956 
00957         /* write out binary encoded variable values for the determinized, encoded blifmvTable
00958            (output parts) */
00959 
00960         rootCol = 0;
00961 
00962         for(colnum = 0; colnum < numOutputs; colnum++){
00963             entry = Tbl_TableReadEntry(blifInfo->blifmvTable, i, colnum, 1);
00964             rootCol += IoNumBinVars(colnum, blifInfo->outputEncTblArray);
00965             numBits = IoNumBinVars(colnum + 1, blifInfo->outputEncTblArray);
00966             Tbl_EntryForEachValue(entry, value, gen, range){
00967                 binRangeEntry = ALLOC(IoBinRangeEntry_t, 1);
00968                 binRangeEntry->startValue = value;
00969                 binRangeEntry->runLength = 1;
00970                 binRangeEntry->skipLength = 1;
00971                 IoWriteExpandedValueToBinTable(blifInfo->binTable, rootRow, rootCol, binRangeEntry, numRowsAfterExpansion, numBits, 1);
00972                 FREE(binRangeEntry);
00973             }
00974         }
00975         for(j = 0; j < array_n(binRangesArray); j++){
00976             mvEntryBinRanges = array_fetch(array_t *, binRangesArray, j);
00977             for(n = 0; n < array_n(mvEntryBinRanges); n++){
00978                 binRangeEntry = array_fetch(IoBinRangeEntry_t *, mvEntryBinRanges, n);
00979                 FREE(binRangeEntry);
00980             }
00981             array_free(mvEntryBinRanges);
00982         }
00983         array_free(binRangesArray);
00984     }
00985     
00986     rootCol = 0;
00987     Tbl_TableForEachOutputVar(blifInfo->blifmvTable, colnum, var){
00988         entry = Tbl_TableDefaultReadEntry(blifInfo->blifmvTable, colnum);
00989         if(entry != NIL(Tbl_Entry_t)){
00990             varRange = Var_VariableReadNumValues(var);
00991             numEncBits = IoNumEncBits(varRange);
00992             defValue = -1;
00993             Tbl_EntryForEachValue(entry, value, gen2, range2){
00994                 defValue = value;
00995                 assert(defValue != -1);
00996             }
00997             for(j = numEncBits - 1; j >= 0; j--){
00998                 if(((int)(defValue / pow((double) 2, (double) j))) == 1){
00999                     IoInvertBinTableOutput(blifInfo, rootCol + j);
01000                     defValue = defValue - (int)pow((double)2,(double)j);
01001                 }
01002             }
01003             rootCol += numEncBits;
01004         }
01005     }
01006 }
01007 
01008 
01021 static int
01022 _IoCheckHnodeTreeIsBooleanAndDeterministic(
01023   mdd_manager **mddMgr,                                
01024   Hrc_Node_t *hnode, 
01025   st_table *modelTable,
01026   boolean *pSymVarsPresent,
01027   int verbosity
01028   )
01029 {
01030   char *modelName, *childName;
01031   Hrc_Model_t *model;
01032   st_generator *stGen;
01033   Hrc_Manager_t *manager;  
01034   Hrc_Node_t *childNode;
01035 
01036   manager = Hrc_NodeReadManager(hnode);
01037   /* enter current model in modelTable */
01038   modelName = Hrc_NodeReadModelName(hnode);
01039   model = Hrc_ManagerFindModelByName(manager, modelName);
01040   if(st_is_member(modelTable, (char *) model)){
01041     return 0;
01042   }
01043   else{
01044     st_insert(modelTable, (char *)model, (char *) (long) (-1));
01045   }
01046   
01047   if(_IoCheckHnodeIsBooleanAndDeterministic(mddMgr, hnode, pSymVarsPresent)){
01048     if(verbosity > 1){
01049       fprintf(vis_stderr, "Model %s is NOT boolean and deterministic\n", modelName);
01050     }
01051     return 1;
01052   }
01053   if(verbosity > 1){
01054     fprintf(vis_stderr, "Model %s is boolean and deterministic\n", modelName);
01055   }
01056   Hrc_NodeForEachChild(hnode, stGen, childName, childNode){
01057     if(_IoCheckHnodeTreeIsBooleanAndDeterministic(mddMgr, childNode, modelTable, pSymVarsPresent, verbosity)){
01058       st_free_gen(stGen);
01059       return 1;
01060     }
01061   }
01062   return 0;
01063 }
01064 
01065 
01077 static int
01078 _IoCheckHnodeIsBooleanAndDeterministic(
01079   mdd_manager **mddMgr,                                
01080   Hrc_Node_t *hnode,
01081   boolean *pSymVarsPresent
01082   )
01083 {
01084   
01085   /* check that variables of all models are boolean */
01086   if(_IoCheckHnodeVarsAreBoolean(hnode, pSymVarsPresent)){
01087     return 1;
01088   }
01089 
01090   /* check that latch resets of all models are either 0/1/2 */
01091   if(_IoCheckHnodeLatchResetIsConstant(hnode)){
01092     return 1;
01093   }
01094 
01095   /* check that tables of all models are deterministic */
01096   if(_IoCheckHnodeTablesAreDeterministic(mddMgr, hnode)){
01097     return 1;
01098   }
01099 
01100   return 0;
01101 }
01102 
01114 static int
01115 _IoCheckHnodeVarsAreBoolean(
01116   Hrc_Node_t *hnode,
01117   boolean *pSymVarsPresent
01118   )
01119 {
01120   st_generator *stGen;
01121   char *varName;
01122   Var_Variable_t *var;
01123   
01124   Hrc_NodeForEachVariable(hnode, stGen, varName, var){
01125     if(Var_VariableReadNumValues(var) > 2){
01126       fprintf(vis_stderr, "Variable %s is not boolean - quitting.\n", varName);      
01127       st_free_gen(stGen);
01128       return 1;
01129     }
01130     if(Var_VariableTestIsSymbolic(var)){
01131       *pSymVarsPresent = TRUE;
01132     }
01133   }
01134   return 0;
01135 }
01136 
01137 
01149 static int
01150 _IoCheckHnodeLatchResetIsConstant(
01151   Hrc_Node_t *hnode 
01152   )
01153 {
01154   st_generator *stGen;
01155   char *latchName;
01156   Hrc_Latch_t *latch;
01157   boolean test;
01158   Tbl_Table_t *table, *resetTable;
01159   Tbl_Entry_t *entry;
01160   Var_Variable_t *var, *parentVar;
01161   int i, j;
01162 
01163   Hrc_NodeForEachLatch(hnode, stGen, latchName, latch){
01164     resetTable = Hrc_LatchReadResetTable(latch);
01165     test = Tbl_TableTestIsConstant(resetTable, 0);
01166     /*
01167       Tbl_TableTestIsConstant gives 0 result for reset tables of
01168       the type .reset a ->b; - =a; where a is a constant defined 
01169       in another table. So check for this case as well. 
01170       */
01171     if(test == FALSE){
01172       if(Tbl_TableReadNumRows(resetTable) == 1){
01173         entry = Tbl_TableReadEntry(resetTable, 0, 0, 1);
01174         if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){
01175           parentVar = Tbl_EntryReadVar(resetTable, entry);
01176           Hrc_NodeForEachNameTable(hnode, i, table){
01177             Tbl_TableForEachOutputVar(table, j, var){
01178               if(var == parentVar){
01179                 test = Tbl_TableTestIsConstant(table, j);
01180               }
01181             }
01182           }
01183         }
01184       }
01185     }
01186     if (test == FALSE){
01187       fprintf(vis_stderr, "Latch %s has a non-constant reset value - quitting.\n", latchName);
01188       st_free_gen(stGen);
01189       return 1;
01190     }
01191   }
01192   return 0;
01193 }
01194 
01206 static int
01207 _IoCheckHnodeTablesAreDeterministic(
01208   mdd_manager **mddMgr,                             
01209   Hrc_Node_t *hnode 
01210   )
01211 {
01212   int i, j, k, index, colNum, offset, numInputs;
01213   Tbl_Table_t *table;
01214   Var_Variable_t *inputVar, *outputVar, *var;
01215   Mvf_Function_t *faninMvf, *outMvf;
01216   array_t *faninMvfArray;
01217   array_t *mvarValues;
01218   Tbl_Entry_t *entry;
01219 
01220 
01221   /* note that reset tables are not handled here */
01222   Hrc_NodeForEachNameTable(hnode, i, table){
01223     Tbl_TableForEachOutputVar(table, index, outputVar){
01224 
01225       faninMvfArray = array_alloc(Mvf_Function_t *, 0);
01226       mvarValues = array_alloc(int, 0);
01227       
01228       /* Create MDD variables for the table inputs. */
01229       Tbl_TableForEachInputVar(table, colNum, inputVar) {
01230         array_insert_last(int, mvarValues, Var_VariableReadNumValues(inputVar));
01231       }
01232       offset = array_n(mdd_ret_mvar_list(*mddMgr));  /* number of existing mvars */
01233       mdd_create_variables(*mddMgr, mvarValues, NIL(array_t), NIL(array_t));
01234       array_free(mvarValues);
01235       
01236       /*
01237        * Construct an MVF for each table input. The MVF for column j is the MVF
01238        * for MDD variable j.
01239        */
01240       
01241       numInputs = Tbl_TableReadNumInputs(table );
01242       for (j = 0; j < numInputs; j++) {
01243         faninMvf = Mvf_FunctionCreateFromVariable(*mddMgr, (j + offset));
01244         array_insert_last(Mvf_Function_t *, faninMvfArray, faninMvf);
01245       }
01246       
01247       /* Compute the MVF of the output indexed by index. */
01248       outMvf = Tbl_TableBuildMvfFromFanins(table, index, faninMvfArray, *mddMgr);
01249       Mvf_FunctionArrayFree(faninMvfArray);
01250       
01251       /*
01252        * If the function is a non-deterministic constant, or it has some
01253        * inputs, and is non-deterministic, then fail
01254        */
01255       if((numInputs > 0) && !Mvf_FunctionTestIsDeterministic(outMvf)){
01256         (void) fprintf(vis_stderr, "Table %s is non-deterministic - quitting\n", Var_VariableReadName(outputVar));
01257         Mvf_FunctionFree(outMvf);
01258         return 1;
01259       }
01260       if(Mvf_FunctionTestIsNonDeterministicConstant(outMvf)){
01261         (void) fprintf(vis_stderr, "Table %s is a non-deterministic constant - quitting\n", Var_VariableReadName(outputVar));
01262         Mvf_FunctionFree(outMvf);
01263         return 1;
01264       }
01265       if (!Mvf_FunctionTestIsCompletelySpecified(outMvf)) {
01266         (void) fprintf(vis_stderr, "Table %s is not completely specified - quitting\n", Var_VariableReadName(outputVar));
01267         Mvf_FunctionFree(outMvf);
01268         return 1; 
01269       } 
01270       Mvf_FunctionFree(outMvf);
01271       _MddManagerResetIfNecessary(mddMgr);
01272 
01273     }
01274   }
01275 
01276   Hrc_NodeForEachNameTable(hnode, i, table){
01277     for(j = 0; j < Tbl_TableReadNumOutputs(table); j++){
01278       entry = Tbl_TableDefaultReadEntry(table, j);
01279       if(entry != NIL(Tbl_Entry_t)){
01280         if(Tbl_EntryReadType(entry) == Tbl_EntryNormal_c){
01281           if(Tbl_EntryReadNumValues(entry) > 1){
01282             outputVar = Tbl_TableReadIndexVar(table, j, 1);
01283             (void)fprintf(stdout, "The table with %s as an output has non-singleton default values - quitting\n", Var_VariableReadName(outputVar));
01284             return 1;
01285           }
01286         }
01287         else{
01288           var = Tbl_EntryReadVar(table, entry);
01289           k = Tbl_TableReadVarIndex(table, var, 1);
01290           if(k<0){
01291             outputVar = Tbl_TableReadIndexVar(table, j, 1);
01292             (void)fprintf(stdout, "Output %s has a default value that refers to an input variable - quitting\n", Var_VariableReadName(outputVar));
01293             return 1;
01294           }
01295         }
01296       }
01297     }
01298   }
01299   return 0;
01300 }
01301 
01302 
01317 static void
01318 _MddManagerResetIfNecessary(
01319   mdd_manager **mddMgr)
01320 {
01321   if (bdd_num_vars(*mddMgr) > MAX_NUMBER_BDD_VARS) {
01322     mdd_quit(*mddMgr);
01323     *mddMgr = mdd_init_empty();
01324   }
01325 }
01326 
01327 
01328 
01339 static void
01340 _IoHnodeWriteBlifRecursively(
01341    Io_Encoding_Type_t encodingType,
01342    Hrc_Node_t *hnode,
01343    st_table *modelTable, 
01344    FILE *fp,
01345    FILE *encFp,
01346    int verbosity
01347   )
01348 {
01349   char *modelName, *childName;
01350   Hrc_Model_t *model;
01351   Hrc_Manager_t *manager;  
01352   st_generator *stGen;
01353   Hrc_Node_t *childNode;
01354 
01355   manager = Hrc_NodeReadManager(hnode);
01356   /* enter current model in modelTable */
01357   modelName = Hrc_NodeReadModelName(hnode);
01358   model = Hrc_ManagerFindModelByName(manager, modelName);
01359   if(st_is_member(modelTable, (char *) model)){
01360     return;
01361   }
01362   else{
01363     st_insert(modelTable, (char *)model, (char *) (long) (-1));
01364   }
01365 
01366   _IoHnodeWriteBlifRecursivelyStep(encodingType, hnode, fp, encFp, verbosity);  
01367   Hrc_NodeForEachChild(hnode, stGen, childName, childNode){
01368     _IoHnodeWriteBlifRecursively(encodingType, childNode, modelTable, fp, encFp, verbosity);
01369   }
01370   return;
01371 }
01372 
01373 
01386 static int
01387 _IoHnodeWriteBlifRecursivelyStep(
01388     Io_Encoding_Type_t encodingType,
01389     Hrc_Node_t *hnode,
01390     FILE *fp,
01391     FILE *encFp,
01392     int verbosity)
01393 {
01394     Tbl_Table_t *table, *singleOutputTable;
01395     int i, j;
01396     Var_Variable_t *var, *actualVar;
01397     char *name, *instanceName, *modelName;
01398     st_generator *gen;
01399     st_table *blifInputsStTable, *blifOutputsStTable, *printedMvsStTable;
01400     st_table *encOutputsStTable, *encInputsStTable;
01401     Hrc_Node_t *subcktHnode;
01402     Hrc_Model_t *model, *subcktModel;
01403     Hrc_Subckt_t *subckt;
01404     Hrc_Manager_t *manager;
01405     array_t *subcktActualInputVars, *subcktActualOutputVars;
01406 
01407 
01408     printedMvsStTable = st_init_table(strcmp, st_strhash);
01409 
01410   /* .model */
01411     modelName = Hrc_NodeReadModelName(hnode);
01412     manager = Hrc_NodeReadManager(hnode);
01413     model = Hrc_ManagerFindModelByName(manager, modelName);
01414     (void)fprintf(fp,".model %s\n", modelName);
01415 
01416     /* .inputs line of blif file*/
01417     if (Hrc_NodeReadNumFormalInputs(hnode) != 0){
01418         (void)fprintf(fp,".inputs ");
01419         Hrc_NodeForEachFormalInput(hnode,i,var){
01420             (void)fprintf(fp,"%s0 ",Var_VariableReadName(var));
01421         }
01422         (void)fprintf(fp,"\n");
01423     }
01424     
01425     /* .outputs line of blif file*/
01426     if (Hrc_NodeReadNumFormalOutputs(hnode) != 0){
01427         (void)fprintf(fp,".outputs ");
01428         Hrc_NodeForEachFormalOutput(hnode,i,var){
01429             (void)fprintf(fp,"%s0 ",Var_VariableReadName(var));
01430         }
01431         (void)fprintf(fp,"\n");
01432     }
01433     
01434     /* .subckt stuff */
01435     Hrc_ModelForEachSubckt(model,gen,instanceName,subckt){
01436       subcktModel = Hrc_SubcktReadModel(subckt);
01437       subcktHnode = Hrc_ModelReadMasterNode(subcktModel);
01438       subcktActualInputVars = Hrc_SubcktReadActualInputVars(subckt);
01439       subcktActualOutputVars = Hrc_SubcktReadActualOutputVars(subckt);
01440       
01441       /* .subckt declarations */
01442       (void)fprintf(fp,".subckt %s ",
01443                     Hrc_ModelReadName(subcktModel));
01444       Hrc_NodeForEachFormalInput(subcktHnode,i,var){
01445         actualVar = array_fetch(Var_Variable_t *,subcktActualInputVars,i);
01446         (void)fprintf(fp,"%s0=%s0 ",Var_VariableReadName(var),Var_VariableReadName(actualVar)); 
01447       }   
01448       Hrc_NodeForEachFormalOutput(subcktHnode,i,var){
01449         actualVar = array_fetch(Var_Variable_t *,subcktActualOutputVars,i);
01450         (void)fprintf(fp,"%s0=%s0 ",Var_VariableReadName(var),Var_VariableReadName(actualVar)); 
01451       }   
01452       (void)fprintf(fp,"\n");
01453     }
01454 
01455     encOutputsStTable = st_init_table(st_ptrcmp, st_ptrhash);
01456     encInputsStTable = st_init_table(st_ptrcmp, st_ptrhash);
01457     blifInputsStTable = st_init_table(strcmp, st_strhash);
01458     blifOutputsStTable = st_init_table(strcmp, st_strhash);
01459 
01460     /* .latch declarations for blif file */
01461     IoWriteLatches(hnode, fp, encFp, printedMvsStTable, blifOutputsStTable, blifInputsStTable, encOutputsStTable, encInputsStTable, 0, 0, verbosity);
01462     Hrc_NodeForEachNameTable(hnode, i, table){
01463         if(IoOutputExpansionRequired(table)){
01464             if(verbosity > 0){
01465                 (void)fprintf(stdout, "Splitting into Single Output Table before Processing\n");
01466             }
01467             for(j = 0; j < Tbl_TableReadNumOutputs(table); j++){
01468                 singleOutputTable = IoMakeSingleOutputTable(table, j);
01469                 _IoTableWriteBlif(encodingType, hnode, singleOutputTable, blifInputsStTable, fp, encFp,
01470                                   verbosity);
01471                 Tbl_TableFree(singleOutputTable);
01472             }
01473         }
01474         else{
01475             if(!((Tbl_TableReadNumInputs(table) == 0) && (Tbl_TableReadNumOutputs(table) > 1))){
01476                 _IoTableWriteBlif(encodingType, hnode, table, blifInputsStTable, fp, encFp,
01477                                   verbosity);
01478             }
01479         }
01480     }
01481     st_foreach_item_int(blifInputsStTable, gen, &name, &i){
01482         FREE(name);
01483     }
01484     st_foreach_item_int(blifOutputsStTable, gen, &name, &i){
01485         FREE(name);
01486     }
01487     st_free_table(blifInputsStTable);
01488     st_free_table(blifOutputsStTable);
01489     st_free_table(encInputsStTable);
01490     st_free_table(encOutputsStTable);
01491     st_foreach_item_int(printedMvsStTable, gen, &name, &i){
01492         FREE(name);
01493     }
01494     st_free_table(printedMvsStTable);
01495     fprintf(fp,".end\n");
01496     return 1;
01497 }
01498 
01499 
01500 
01513 static int
01514 _IoCheckPseudoinputIsPO(
01515    Tbl_Table_t *table)
01516 {
01517   int j;
01518   Var_Variable_t *var = NIL(Var_Variable_t); /* to suppress warning */
01519   Tbl_Entry_t *entry;
01520   int numValues;
01521     
01522   if((Tbl_TableReadNumInputs(table) == 0) && (Tbl_TableReadNumOutputs(table) > 1)){
01523     /* assume all are pseudoinputs */
01524     Tbl_TableForEachOutputVar(table, j, var){
01525       if(Var_VariableTestIsPO(var)){
01526         return 1;
01527       }
01528     }
01529   }
01530 
01531   if(Tbl_TableReadNumInputs(table) == 0){
01532     if(Tbl_TableReadNumRows(table) != 0){
01533       entry = Tbl_TableReadEntry(table, 0, 0, 1);
01534       numValues = Tbl_EntryReadNumValues(entry);
01535     }
01536     else{
01537       entry = Tbl_TableDefaultReadEntry(table, 0);
01538       numValues = Tbl_EntryReadNumValues(entry);
01539     }
01540 
01541     Tbl_TableForEachOutputVar(table, j, var);
01542     if(Tbl_TableReadNumRows(table) <= 1){
01543       if(numValues > 1){
01544         if(Var_VariableTestIsPO(var)){
01545           return 1;
01546         }
01547       }
01548     }
01549     else{
01550       if(Var_VariableTestIsPO(var)){      
01551         return 1;
01552       }
01553     }
01554   }
01555 
01556   return 0;
01557 }