VIS

src/io/ioWriteBlifIo.c

Go to the documentation of this file.
00001 
00039 #include "ioInt.h"
00040 
00041 static char rcsid[] UNUSED = "$Id: ioWriteBlifIo.c,v 1.13 2005/05/14 02:15:22 fabio Exp $";
00042 
00043 /*---------------------------------------------------------------------------*/
00044 /* Macro declarations                                                        */
00045 /*---------------------------------------------------------------------------*/
00046 
00047 
00048 
00051 /*---------------------------------------------------------------------------*/
00052 /* Static function prototypes                                                */
00053 /*---------------------------------------------------------------------------*/
00054 
00055 static void _IoEncodeWriteVariable(Var_Variable_t *var, FILE *encFp, int varIsOutput, st_table *encOutputsStTable, st_table *encInputsStTable);
00056 static void _IoEncodeWriteVariableSpecial(Var_Variable_t *var, FILE *encFp, int varIsOutput, st_table *encOutputsStTable, st_table *encInputsStTable);
00057 
00061 /*---------------------------------------------------------------------------*/
00062 /* Definition of exported functions                                          */
00063 /*---------------------------------------------------------------------------*/
00064 
00065 
00066 /*---------------------------------------------------------------------------*/
00067 /* Definition of internal functions                                          */
00068 /*---------------------------------------------------------------------------*/
00069 
00070     
00081 void
00082 IoEncWriteMvToBinTables(
00083   Hrc_Node_t *hnode, 
00084   FILE *encFp, 
00085   st_table *encOutputsStTable, 
00086   st_table *encInputsStTable,
00087   int combinationalOnly
00088   )
00089 {
00090   int i;
00091   Var_Variable_t *var;
00092   st_generator *gen;
00093   char *childname;
00094   Hrc_Node_t *childnode;
00095   
00096   /* latch IOs encoding tables not handled here */
00097   /* if a PI or SO drives a latch, then in the combinational case, this
00098      PI is not encoded (since the (mv) latch will be reinstated after
00099      sis optimization. In the non-comvinational case ("wl" or "wl -l")
00100      every PI and SO is encoded. 
00101   */
00102   if(combinationalOnly){
00103     Hrc_NodeForEachFormalInput(hnode, i, var){
00104       if(!((Var_VariableReadNumFanoutTables(var) == 0))){
00105         _IoEncodeWriteVariable(var, encFp, 0, encOutputsStTable, encInputsStTable);
00106       }
00107     }
00108     Hrc_NodeForEachChild(hnode, gen, childname, childnode){
00109       Hrc_NodeForEachActualOutput(childnode, i, var){
00110         if(!((Var_VariableReadNumFanoutTables(var) == 0))){
00111           _IoEncodeWriteVariable(var, encFp, 0, encOutputsStTable, encInputsStTable);
00112         }
00113       }
00114     }
00115   }
00116   else{
00117     Hrc_NodeForEachFormalInput(hnode, i, var){
00118       _IoEncodeWriteVariable(var, encFp, 0, encOutputsStTable, encInputsStTable);
00119     }
00120     Hrc_NodeForEachChild(hnode, gen, childname, childnode){
00121       Hrc_NodeForEachActualOutput(childnode, i, var){
00122         _IoEncodeWriteVariable(var, encFp, 0, encOutputsStTable, encInputsStTable);
00123       }
00124     }
00125   }
00126 }
00127 
00138 void
00139 IoEncWriteBinToMvTables(
00140   Hrc_Node_t *hnode, 
00141   FILE *encFp, 
00142   st_table *encOutputsStTable, 
00143   st_table *encInputsStTable,
00144   int combinationalOnly,
00145   int makeLatchIOsPOs
00146   )
00147 {
00148   int i;
00149   Var_Variable_t *var;
00150   st_generator *gen;
00151   char *childname;
00152   Hrc_Node_t *childnode;
00153 
00154   /* latch IOs encoding tables not handled here */
00155   /* if a PO or SI is driven by a latch, then in the combinational case, this
00156      var is not encoded (since the (mv) latch will be reinstated after
00157      sis optimization. In case of "wl -l" the same applies, since we are sure
00158      to be able to reinstate teh mv latch after sis optimization. However, in "wl" 
00159      every PI and SO is encoded since we are not sure  that mv latches can be 
00160      reinstated after sis optimization. Similarly, if teh PO or SI is a PI/SO  
00161      then no encoding is needed in all cases (comb or non-comb)
00162   */
00163   /*  if(combinationalOnly || makeLatchIOsPOs){ */
00164   /* The above line was changed since "wl -l" now writes out latches such that
00165      they drive a buffer node. As a result, even if a PO or SI is driven by the 
00166      latch, the PO/SI needs bin-mv tables 
00167   */
00168   if(combinationalOnly){ 
00169     Hrc_NodeForEachFormalOutput(hnode, i, var){
00170       if(!((Var_VariableTestIsSO(var) || Var_VariableTestIsPI(var) ||
00171             Var_VariableTestIsPS(var)))){
00172         _IoEncodeWriteVariable(var, encFp, 1, encOutputsStTable, encInputsStTable);
00173       }
00174     }
00175     Hrc_NodeForEachChild(hnode, gen, childname, childnode){
00176       Hrc_NodeForEachActualInput(childnode, i, var){
00177         if(!((Var_VariableTestIsSO(var) || Var_VariableTestIsPI(var) ||
00178               Var_VariableTestIsPS(var)))){
00179           _IoEncodeWriteVariable(var, encFp, 1, encOutputsStTable, encInputsStTable);
00180         }
00181       }
00182     }
00183   }
00184   else{
00185     Hrc_NodeForEachFormalOutput(hnode, i, var){
00186       if(!((Var_VariableTestIsSO(var) || Var_VariableTestIsPI(var)))){
00187         _IoEncodeWriteVariable(var, encFp, 1, encOutputsStTable, encInputsStTable);
00188       }
00189     }
00190     Hrc_NodeForEachChild(hnode, gen, childname, childnode){
00191       Hrc_NodeForEachActualInput(childnode, i, var){
00192         if(!((Var_VariableTestIsSO(var) || Var_VariableTestIsPI(var)))){
00193           _IoEncodeWriteVariable(var, encFp, 1, encOutputsStTable, encInputsStTable);
00194         }
00195       }
00196     }
00197   }
00198 }
00199 
00210  int
00211 IoBlifWriteInputs(
00212   Hrc_Node_t *hnode, 
00213   FILE *fp, 
00214   st_table *blifInputsStTable,
00215   int combinationalOnly,
00216   int makeLatchIOsPOs
00217   )
00218 {
00219   int i, j, k, numVal, numEncBits, numInputsWritten;
00220   Tbl_Table_t *table;
00221   st_generator *gen;
00222   Var_Variable_t *var;
00223   char *name, *dupName, *varName;
00224   boolean test;
00225   
00226   numInputsWritten = 0;
00227   fprintf(fp,".inputs ");     
00228   Hrc_NodeForEachNameTable(hnode, i, table){
00229     Tbl_TableForEachInputVar(table, k, var){
00230       if(combinationalOnly){
00231         test = Var_VariableTestIsPS(var) || Var_VariableTestIsSO(var) || Var_VariableTestIsPI(var);
00232       }
00233       else{
00234         test = Var_VariableTestIsSO(var) || Var_VariableTestIsPI(var);
00235       }
00236       if(test){
00237         name = Var_VariableReadName(var);
00238         numVal = Var_VariableReadNumValues(var);
00239         numEncBits = IoNumEncBits(numVal);
00240         for(j=0; j<numEncBits; j++){
00241           dupName = ALLOC(char, strlen(name) + IoNumDigits(numEncBits) + 2);
00242           sprintf(dupName, "%s%d", name, j);
00243           if(!st_is_member(blifInputsStTable, (char *)dupName)){
00244             fprintf(fp,"%s ",dupName);
00245             numInputsWritten++;
00246             st_insert(blifInputsStTable, (char *)dupName, (char *)1);
00247           }
00248           else{
00249             FREE(dupName);
00250           }
00251         }
00252       }
00253     }
00254   }
00255   if(!combinationalOnly){
00256     Hrc_NodeForEachVariable(hnode, gen, varName, var){
00257       if(Var_VariableTestIsPI(var)){
00258         name = Var_VariableReadName(var);
00259         numVal = Var_VariableReadNumValues(var);
00260         numEncBits = IoNumEncBits(numVal);
00261         for(j=0; j<numEncBits; j++){
00262           dupName = ALLOC(char, strlen(name) + IoNumDigits(numEncBits) + 2);
00263           sprintf(dupName, "%s%d", name, j);
00264           if(!st_is_member(blifInputsStTable, (char *)dupName)){
00265             fprintf(fp,"%s ",dupName);
00266             numInputsWritten++;
00267             st_insert(blifInputsStTable, (char *)dupName, (char *)1);
00268           }
00269           else{
00270             FREE(dupName);
00271           }
00272         }
00273       }
00274     }
00275   }
00276   return numInputsWritten;
00277 }
00278 
00279 
00290  int
00291 IoBlifWriteOutputs(
00292   Hrc_Node_t *hnode, 
00293   FILE *fp,
00294   st_table *blifOutputsStTable,
00295   int combinationalOnly,
00296   int makeLatchIOsPOs
00297   )
00298 {
00299   int i, j, k, numVal, numEncBits, numOutputsWritten;
00300   Tbl_Table_t *table;
00301   st_generator *gen;
00302   Var_Variable_t *var;
00303   char *name, *dupName, *varName;
00304   boolean test;
00305 
00306   numOutputsWritten = 0;
00307   fprintf(fp,"\n.outputs "); 
00308   Hrc_NodeForEachNameTable(hnode, i, table){
00309     Tbl_TableForEachOutputVar(table, k, var){
00310       if(combinationalOnly){
00311         test = Var_VariableTestIsNS(var) || Var_VariableTestIsSI(var) || Var_VariableTestIsPO(var);
00312       }
00313       else{
00314         test = Var_VariableTestIsSI(var) || Var_VariableTestIsPO(var);
00315       }
00316       if(test){
00317         name = Var_VariableReadName(var);
00318         numVal = Var_VariableReadNumValues(var);
00319         numEncBits = IoNumEncBits(numVal);
00320         for(j=0; j<numEncBits; j++){
00321           dupName = ALLOC(char, strlen(name) + IoNumDigits(numEncBits) + 2);
00322           sprintf(dupName, "%s%d", name, j);
00323           if(!st_is_member(blifOutputsStTable, (char *)dupName)){
00324             fprintf(fp,"%s ",dupName);
00325             numOutputsWritten++;
00326             st_insert(blifOutputsStTable, (char *)dupName, (char *)1);
00327           }
00328           else{
00329             FREE(dupName);
00330           }
00331         }
00332       }
00333     }
00334   }
00335   if(!combinationalOnly){
00336     Hrc_NodeForEachVariable(hnode, gen, varName, var){
00337       if(Var_VariableTestIsPO(var) && Var_VariableTestIsPS(var)){
00338         name = Var_VariableReadName(var);
00339         numVal = Var_VariableReadNumValues(var);
00340         numEncBits = IoNumEncBits(numVal);
00341         for(j=0; j<numEncBits; j++){
00342           dupName = ALLOC(char, strlen(name) + IoNumDigits(numEncBits) + 2);
00343           sprintf(dupName, "%s%d", name, j);
00344           if(!st_is_member(blifOutputsStTable, (char *)dupName)){
00345             fprintf(fp,"%s ",dupName);
00346             numOutputsWritten++;
00347             st_insert(blifOutputsStTable, (char *)dupName, (char *)1);
00348           }
00349           else{
00350             FREE(dupName);
00351           }
00352         }
00353       }
00354     }
00355   }
00356   fprintf(fp,"\n");
00357   return numOutputsWritten;
00358 }
00359 
00371 void
00372 IoWriteLatches(
00373    Hrc_Node_t *hnode,
00374    FILE *fp,          
00375    FILE *encFp,
00376    st_table *printedMvsStTable,        
00377    st_table *blifOutputsStTable,               
00378    st_table *blifInputsStTable,
00379    st_table *encOutputsStTable,        
00380    st_table *encInputsStTable,
00381    int combinationalOnly,
00382    int makeLatchIOsPOs,
00383    int verbosity
00384    )
00385 {
00386   Hrc_Latch_t *latch;
00387   st_generator *gen;
00388   char *varName, *latchName, *inputVarName, *outputVarName;
00389   char *latchInName, *latchOutName, *dupName;
00390   Var_Variable_t *outputVar, *inputVar, *var;
00391   Tbl_Table_t *resetTable;
00392   boolean test;
00393   int i, j, index, tempResetValue, resetValue, numEncBits, numVal;
00394   st_table *encodedResetVarsStTable;
00395 
00396     mdd_manager *mddMgr;
00397     Ntk_Node_t *ntkLatch, *ntkCombInput, *latchResetNtkNode;
00398     Ntk_Network_t *network;
00399     st_table *tableOfLeaves;
00400     array_t *singletonArrayOfRoots, *singletonMvfArray;
00401     Mvf_Function_t *mvf;
00402     lsGen listGen;
00403     Hrc_Manager_t *HrcMgr;
00404 
00405   /* stuff for doing reset table constantness check. Needs to do a "flt -b", "ord"
00406      and create a leaves table for mvf computation later.
00407   */
00408   mddMgr = mdd_init_empty();
00409   bdd_dynamic_reordering(mddMgr, BDD_REORDER_SIFT,BDD_REORDER_VERBOSITY_DEFAULT);
00410 
00411   HrcMgr = Hrc_NodeReadManager(hnode);
00412   Hrc_ManagerSetCurrentNode(HrcMgr, hnode);
00413   
00414   network = Ntk_HrcNodeConvertToNetwork(hnode, TRUE, (lsList) NULL);
00415   Ord_NetworkOrderVariables(network, Ord_RootsByDefault_c, Ord_NodesByDefault_c, 0, Ord_InputAndLatch_c, Ord_Unassigned_c, (lsList) NULL, 0);
00416   tableOfLeaves = st_init_table(st_ptrcmp, st_ptrhash);
00417   Ntk_NetworkForEachCombInput(network, listGen, ntkCombInput) {
00418     st_insert(tableOfLeaves, (char *)ntkCombInput, (char *) (long) (-1) );
00419   }
00420 
00421   encodedResetVarsStTable = st_init_table(strcmp, st_strhash);
00422   Hrc_NodeForEachLatch(hnode, gen, latchName, latch){
00423     inputVar = Hrc_LatchReadInput(latch);
00424     outputVar = Hrc_LatchReadOutput(latch);
00425     inputVarName = Var_VariableReadName(inputVar);
00426     outputVarName = Var_VariableReadName(outputVar);
00427     resetTable = Hrc_LatchReadResetTable(latch);
00428     
00429     IoMvCheckPrint(encFp,inputVar,printedMvsStTable);
00430     /* if makeLatchIOsPOs, then the .mv statement should have "_bufin" appended to the 
00431        variable names */
00432     if(makeLatchIOsPOs){
00433       IoMvCheckPrintSpecial(encFp,outputVar,printedMvsStTable);
00434     }
00435     else{
00436       IoMvCheckPrint(encFp,outputVar,printedMvsStTable);
00437     }
00438           
00439     
00440     /* Write bin2mv table for input var if needed */
00441     /* if makeLatchIOsPOs, then the test for writing the bin2mv table should not include 
00442        a check to see if the var is a PS. This was previously required, since in hte case
00443        where a latchOutput drove a latchInput, we wanted to reinstate both mv latches after
00444        read_blif, and so didnt need any enc/dec tables. However, if makeLatchIOsPOs, then we
00445        will insert a buffer after latches, so enc/dec tables _will_ be needed. 
00446     */
00447     if(makeLatchIOsPOs){
00448       if(!IoVarIsHnodePIO(hnode, inputVar)){
00449         if(!st_is_member(encodedResetVarsStTable, (char *)Var_VariableReadName(inputVar))){
00450           _IoEncodeWriteVariable(inputVar, encFp, 1, encOutputsStTable, encInputsStTable);
00451           st_insert(encodedResetVarsStTable, (char *)Var_VariableReadName(inputVar), (char *)1);
00452         }
00453       }
00454     }
00455     else{      
00456       if(!IoVarIsHnodePIO(hnode, inputVar) && !Var_VariableTestIsPS(inputVar)){
00457         if(!st_is_member(encodedResetVarsStTable, (char *)Var_VariableReadName(inputVar))){
00458           _IoEncodeWriteVariable(inputVar, encFp, 1, encOutputsStTable, encInputsStTable);
00459           st_insert(encodedResetVarsStTable, (char *)Var_VariableReadName(inputVar), (char *)1);
00460         }
00461       }
00462     }
00463     
00464     /* Write mv2bin table for output var if needed */
00465     /* if makeLatchIOsPOs, then the enc tables should have "_bufin" appended to the 
00466        names. This is a hack, and I dont insert this name in the table since it does
00467        not correspond to a real name in the hrc node.
00468     */
00469     if(makeLatchIOsPOs){
00470       _IoEncodeWriteVariableSpecial(outputVar, encFp, 0, encOutputsStTable, encInputsStTable);  
00471     }
00472     else{      
00473       if(!(Var_VariableReadNumFanoutTables(outputVar) == 0)){
00474         if(!st_is_member(encodedResetVarsStTable, (char *)Var_VariableReadName(outputVar))){
00475           _IoEncodeWriteVariable(outputVar, encFp, 0, encOutputsStTable, encInputsStTable);    
00476           st_insert(encodedResetVarsStTable, (char *)Var_VariableReadName(outputVar), (char *)1);
00477         }
00478       }
00479     }
00480     /* Write latch IOs as POs if the "-l" option was used */
00481     if(makeLatchIOsPOs){
00482       /* 
00483          first deal with inputVar - check if it has been printed to 
00484          blif file in binary form, by looking up blifInputsStTable
00485       */
00486       numVal = Var_VariableReadNumValues(inputVar);
00487       numEncBits = IoNumEncBits(numVal);
00488       for(j=0; j<numEncBits; j++){
00489         dupName = ALLOC(char, strlen(inputVarName) + IoNumDigits(numEncBits) + 2);
00490         sprintf(dupName, "%s%d", inputVarName, j);
00491         if(!st_is_member(blifInputsStTable, (char *)dupName)){
00492           fprintf(fp,".outputs %s\n",dupName);
00493           st_insert(blifInputsStTable, (char *)dupName, (char *)1);
00494         }
00495         else{
00496           FREE(dupName);
00497         }
00498       }
00499       /* 
00500          next deal with outputVar - check if it has been printed to 
00501          blif file in binary form, by looking up blifOutputsStTable
00502       */
00503       numVal = Var_VariableReadNumValues(outputVar);
00504       numEncBits = IoNumEncBits(numVal);
00505       for(j=0; j<numEncBits; j++){
00506         dupName = ALLOC(char, strlen(outputVarName) + IoNumDigits(numEncBits) + 2);
00507         sprintf(dupName, "%s%d", outputVarName, j);
00508         if(!st_is_member(blifOutputsStTable, (char *)dupName)){
00509           fprintf(fp,".outputs %s\n",dupName);
00510           st_insert(blifOutputsStTable, (char *)dupName, (char *)1);
00511         }
00512         else{
00513           FREE(dupName);
00514         }
00515       }
00516     }
00517 
00518     /* handle reset tables (all cases "wl -c", "wl -l", and "wl")*/
00519     Tbl_TableForEachInputVar(resetTable, index, var){
00520       if(!IoVarIsHnodePIO(hnode, var)){
00521         IoMvCheckPrint(encFp, var,printedMvsStTable);
00522       }
00523       /* dont encode if (comb&ps) or (makeLatchIOsPOs&ps) */
00524       /*      if(!((combinationalOnly || makeLatchIOsPOs) && Var_VariableTestIsPS(var))){ */
00525       /* since we insert a buffer after each latch whenever makeLatchIOsPOs, there will
00526          be a need for a bin2mv table for the latch output var. Previously, it was assumed
00527          that when the mv latch will replace the bin latches, there will be no need for a
00528          bin2mv table since the mv latch was directly driving the reset table.
00529       */
00530       if(!(combinationalOnly && Var_VariableTestIsPS(var))){ 
00531         /* if var is a PI or SO, then mv->bin tables exist for it, so dont 
00532            make bin->mv tables since the mv variable will exist anyway 
00533         */
00534         if(!Var_VariableTestIsPI(var) && !Var_VariableTestIsSO(var)){
00535           if(!st_is_member(encodedResetVarsStTable, (char *)Var_VariableReadName(var))){
00536             _IoEncodeWriteVariable(var, encFp, 1, encOutputsStTable, encInputsStTable);
00537             st_insert(encodedResetVarsStTable, (char *)Var_VariableReadName(var), (char *)1);
00538           }
00539         }
00540       }
00541       /*
00542          if we are doing "wl -c" and there is a resetTable input var
00543          which is also a PS which does not have fanout tbls, then this 
00544          variable will not be encoded and listed in the blif file.
00545          Hence such a variable should not be encoded and listed in teh 
00546          blif file as a PO, since it will have no driving tables.
00547       */
00548       if(!(combinationalOnly && Var_VariableTestIsPS(var) && 
00549          (Var_VariableReadNumFanoutTables(var) == 0))){
00550         /* 
00551            write encoded vars as outputs after checking that they havent 
00552            already been written as outputs or inputs to the blif file
00553         */
00554         varName = Var_VariableReadName(var);
00555         numVal = Var_VariableReadNumValues(var);
00556         numEncBits = IoNumEncBits(numVal);
00557         for(j=0; j<numEncBits; j++){
00558           dupName = ALLOC(char, strlen(varName) + IoNumDigits(numEncBits) + 2);
00559           sprintf(dupName, "%s%d", varName, j);
00560           if(!st_is_member(blifInputsStTable, (char *)dupName) && !st_is_member(blifOutputsStTable, (char *)dupName)){
00561             fprintf(fp,".outputs %s\n",dupName);
00562             st_insert(blifOutputsStTable, (char *)dupName, (char *)1);
00563           }
00564           else{
00565             FREE(dupName);
00566           }
00567         }
00568       }
00569     }
00570   }
00571 
00572   /* write latch stmts to blif file */
00573   Hrc_NodeForEachLatch(hnode, gen, latchName, latch){
00574     inputVar = Hrc_LatchReadInput(latch);
00575     outputVar = Hrc_LatchReadOutput(latch);
00576     inputVarName = Var_VariableReadName(inputVar);
00577     outputVarName = Var_VariableReadName(outputVar);
00578     resetTable = Hrc_LatchReadResetTable(latch);
00579     /* write out mv latches to enc file, they are needed even if we are 
00580        writing only combinational part of the network */
00581     /* if makeLatchIOsPOs, then append "_bufin" to the output name, since latch 
00582        outputs are buffered. Also, reset table should reflect this new name.
00583     */
00584     if(makeLatchIOsPOs){
00585       (void)fprintf(encFp, ".latch %s %s_bufin \n", inputVarName, outputVarName);           
00586       Tbl_TableWriteBlifMvToFileSpecial(resetTable, 1, encFp);
00587     }
00588     else{
00589       (void)fprintf(encFp, ".latch %s %s \n", inputVarName, outputVarName);         
00590       Tbl_TableWriteBlifMvToFile(resetTable, 1, encFp);
00591     }      
00592     
00593     /* determine value of reset table - whether const, or not */
00594     if(!combinationalOnly){      
00595       ntkLatch = Ntk_NetworkFindNodeByName(network, latchName);
00596       assert(Ntk_NodeTestIsLatch(ntkLatch));
00597       latchResetNtkNode = Ntk_LatchReadInitialInput(ntkLatch);
00598       singletonArrayOfRoots = array_alloc(Ntk_Node_t *, 0);
00599       array_insert_last(Ntk_Node_t *, singletonArrayOfRoots, latchResetNtkNode);
00600       singletonMvfArray = Ntm_NetworkBuildMvfs(network, singletonArrayOfRoots, tableOfLeaves, NIL(mdd_t));
00601       mvf = array_fetch(Mvf_Function_t *, singletonMvfArray, 0);
00602       array_free(singletonMvfArray);
00603       array_free(singletonArrayOfRoots);
00604       test = Mvf_FunctionTestIsConstant(mvf, &resetValue);
00605       Mvf_FunctionFree(mvf);
00606       if(verbosity > 1){
00607         (void)fprintf(stdout, "Reset table is: \n");                
00608         Tbl_TableWriteBlifMvToFile(resetTable, 0, stdout);
00609       }
00610       if(verbosity > 0){
00611         (void)fprintf(stdout, "Reset table constantness test result was %d\n", test);          
00612       }
00613       if(test == FALSE){
00614         resetValue = VIS_INFINITY;
00615       }
00616       if(verbosity > 0){
00617         fprintf(stdout, "Reset value %d\n", resetValue);
00618       }
00619       
00620       /* write latches to blif file */
00621       numEncBits = IoNumEncBits(Var_VariableReadNumValues(inputVar));
00622       if(resetValue == VIS_INFINITY){
00623         for(i = 0; i < numEncBits; i++){
00624           resetValue = 2;
00625           latchInName = ALLOC(char, strlen(inputVarName) + IoNumDigits(numEncBits) + 2);
00626           latchOutName = ALLOC(char, strlen(outputVarName) + IoNumDigits(numEncBits) + 10); 
00627           sprintf(latchInName, "%s%d", inputVarName, i);
00628           /* if makelatchIOsPOs, then latch drives buffer input, and buffer needs to be 
00629              be written to the blif file too
00630           */
00631           if(makeLatchIOsPOs){
00632             sprintf(latchOutName, "%s_bufin%d", outputVarName, i);
00633           }
00634           else{
00635             sprintf(latchOutName, "%s%d", outputVarName, i);
00636           }
00637           (void)fprintf(fp, ".latch %s %s %d\n", latchInName, latchOutName, resetValue);
00638           if(makeLatchIOsPOs){
00639             (void)fprintf(fp, ".names %s %s%d\n", latchOutName, outputVarName, i);
00640             (void)fprintf(fp, "1 1\n");
00641           }
00642           FREE(latchInName);
00643           FREE(latchOutName);
00644         }
00645       }
00646       else{
00647         tempResetValue = resetValue;
00648         for(i = numEncBits - 1; i >= 0; i--){
00649           if(((int)(tempResetValue / pow((double) 2, (double) i))) == 1){
00650             resetValue = 1;
00651             tempResetValue = tempResetValue - (int)pow((double)2,(double)i);        
00652           }
00653           else{
00654             resetValue = 0;
00655           }
00656           latchInName = ALLOC(char, strlen(inputVarName) + IoNumDigits(numEncBits) + 2);
00657           latchOutName = ALLOC(char, strlen(outputVarName) + IoNumDigits(numEncBits) + 10); 
00658           sprintf(latchInName, "%s%d", inputVarName, i);
00659           /* if makelatchIOsPOs, then latch drives buffer input, and buffer needs to be 
00660              be written to the blif file too.
00661           */
00662           if(makeLatchIOsPOs){
00663             sprintf(latchOutName, "%s_bufin%d", outputVarName, i);
00664           }
00665           else{
00666             sprintf(latchOutName, "%s%d", outputVarName, i);
00667           }         
00668           (void)fprintf(fp, ".latch %s %s %d\n", latchInName, latchOutName, resetValue);
00669           if(makeLatchIOsPOs){
00670             (void)fprintf(fp, ".names %s %s%d\n", latchOutName, outputVarName, i);
00671             (void)fprintf(fp, "1 1\n");
00672           }
00673           FREE(latchInName);
00674           FREE(latchOutName);
00675         }
00676       }
00677     }
00678   }
00679   st_free_table(encodedResetVarsStTable);
00680   st_free_table(tableOfLeaves);
00681   Ntk_NetworkFree(network);
00682   mdd_quit(mddMgr);
00683 }
00684 
00685 
00698 void
00699 IoMvCheckPrint(
00700    FILE *fp, 
00701    Var_Variable_t *var,
00702    st_table *printedMvsStTable
00703   )
00704 {
00705     char *varname, *tmpName;
00706 
00707     tmpName = Var_VariableReadName(var);
00708     varname = ALLOC(char, strlen(tmpName) + 2);
00709     sprintf(varname, "%s", tmpName);
00710     if(!st_is_member(printedMvsStTable, (char *)varname)){
00711         st_insert(printedMvsStTable, (char *)varname, (char *)1);
00712         IoMvPrint(fp, var);
00713     }
00714     else{
00715         FREE(varname);
00716     }
00717 }
00718 
00732 void
00733 IoMvCheckPrintSpecial(
00734    FILE *fp, 
00735    Var_Variable_t *var,
00736    st_table *printedMvsStTable
00737   )
00738 {
00739     char *varname, *tmpName;
00740 
00741     tmpName = Var_VariableReadName(var);
00742     varname = ALLOC(char, strlen(tmpName) + 10);
00743     sprintf(varname, "%s_bufin", tmpName);
00744     if(!st_is_member(printedMvsStTable, (char *)varname)){
00745         st_insert(printedMvsStTable, (char *)varname, (char *)1);
00746         IoMvPrintSpecial(fp, var);
00747     }
00748     else{
00749         FREE(varname);
00750     }
00751 }
00752 
00753     
00767  int
00768 IoWriteExpandedValueToBinTable( 
00769    Tbl_Table_t *binTable,
00770    int rootRow,
00771    int rootCol,
00772    IoBinRangeEntry_t *binRangeEntry,
00773    int entryRepetitionCount,
00774    int numBits,
00775    int output
00776    )
00777 {
00778     int i, j, row, value, numDash, end;
00779     Tbl_Entry_t *entry;
00780 
00781     numDash = IoLog(binRangeEntry->runLength);
00782     end = IoLog(binRangeEntry->skipLength);
00783     value = binRangeEntry->startValue;
00784     for(j = numBits - 1; j >= 0; j--){
00785       row = rootRow;
00786         if((j < end) || (j >= numDash + end)){
00787             if(((int)(value / pow((double) 2, (double) j))) == 1){
00788                 for(i = 0; i < entryRepetitionCount; i++){
00789                     entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00790                     Tbl_EntrySetValue(entry, 1, 1);
00791                     Tbl_TableSetEntry(binTable, entry, row++, rootCol+j, output);
00792                 }
00793                 value -= (int)pow((double)2,(double)j);
00794             }
00795             else{
00796                 for(i = 0; i < entryRepetitionCount; i++){
00797                     entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00798                     Tbl_EntrySetValue(entry, 0, 0);
00799                     Tbl_TableSetEntry(binTable, entry, row++, rootCol+j, output);
00800                 }
00801             }
00802         }
00803         else{
00804             for(i = 0; i < entryRepetitionCount; i++){
00805                 entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00806                 Tbl_EntrySetValue(entry, 0, 1);
00807                 Tbl_TableSetEntry(binTable, entry, row++, rootCol+j, output);
00808             }
00809         }
00810     }
00811     return 0;
00812 }
00813 
00814 
00827 void
00828 IoWriteBinTablesToFile( 
00829    IoBlifInfo_t *blifInfo                             
00830    )
00831 {
00832     int i, colnum, rownum, value, hasZeroRows;
00833     Tbl_Table_t *table;
00834     Var_Variable_t *outputVar, *dupOutputVar;
00835     char *outputVarName;
00836     Tbl_Entry_t *entry;
00837     Tbl_Range_t *range;
00838     lsGen gen;
00839 
00840     for(i = 0; i < array_n(blifInfo->binTblArray); i++){
00841         table = array_fetch(Tbl_Table_t *, blifInfo->binTblArray, i);
00842    /* if table has zero rows, print it as ".names <var>" */
00843         hasZeroRows = 1;
00844         Tbl_TableForEachOutputEntry(table, colnum, rownum, entry){
00845             Tbl_EntryForEachValue(entry, value, gen, range){
00846                 if(value == 1){
00847                     hasZeroRows = 0;
00848                 }
00849             }
00850         }
00851         if(hasZeroRows){
00852             outputVar = Tbl_TableReadIndexVar(table, 0, 1);
00853             table = Tbl_TableAlloc();
00854             outputVarName = Var_VariableReadName(outputVar);
00855             dupOutputVar = Var_VariableAlloc(NIL(Hrc_Node_t), outputVarName);
00856             (void)Tbl_TableAddColumn(table, dupOutputVar, 1);
00857             Tbl_TableWriteBlifToFile(table, blifInfo->BlifFp); 
00858             Tbl_TableFree(table);
00859             Var_VariableFree(dupOutputVar);
00860         }
00861         else{
00862             Tbl_TableWriteBlifToFile(table, blifInfo->BlifFp); 
00863         }
00864     }
00865 }
00866 
00867 
00868 /*---------------------------------------------------------------------------*/
00869 /* Definition of static functions                                            */
00870 /*---------------------------------------------------------------------------*/
00871 
00872 
00885 static void
00886 _IoEncodeWriteVariable(
00887    Var_Variable_t *var,
00888    FILE *encFp,               
00889    int varIsOutput,
00890    st_table *encOutputsStTable, 
00891    st_table *encInputsStTable
00892    )
00893 {
00894     int j, i, tempI, range, numEncBits, rownum, varIsInput;
00895     Tbl_Table_t *encTable;
00896     char *varname, *dupName;
00897     Var_Variable_t *encVar;
00898     Tbl_Entry_t *entry;
00899     array_t *varArray;
00900 
00901     if(varIsOutput == 1){
00902         varIsInput = 0;
00903     }
00904     else{
00905         varIsInput = 1;
00906     }
00907 
00908     if(varIsOutput){
00909         if(st_is_member(encOutputsStTable, (char *)var)){
00910             return;
00911         }
00912         else{
00913             st_insert(encOutputsStTable, (char *) var, (char *) 1);
00914         }
00915     }
00916     else{
00917         if(st_is_member(encInputsStTable, (char *)var)){
00918             return;
00919         }
00920         else{
00921             st_insert(encInputsStTable, (char *) var, (char *) 1);
00922         }
00923     }
00924             
00925 
00926         /* declare encoding input vars based on range. These are associated
00927            with their encoding table. These have names <var>0, <var>1, ...  */
00928 
00929     varArray = array_alloc(Var_Variable_t *, 0);
00930     range = Var_VariableReadNumValues(var);
00931     numEncBits = IoNumEncBits(range);
00932     /* create encoding table */
00933     encTable = Tbl_TableAlloc();
00934     varname = Var_VariableReadName(var);
00935     for(i=0; i<numEncBits; i++){
00936         dupName = ALLOC(char, strlen(varname) + IoNumDigits(numEncBits) + 2);
00937         sprintf(dupName, "%s%d", varname, i);
00938         encVar = Var_VariableAlloc(NIL(Hrc_Node_t), dupName);
00939         FREE(dupName);
00940         array_insert_last(Var_Variable_t *, varArray, encVar);
00941         (void) Tbl_TableAddColumn(encTable, encVar, varIsInput);
00942     }
00943 
00944         /* declare output var for the encoding table. It is called <var>     */
00945 
00946     (void) Tbl_TableAddColumn(encTable, var, varIsOutput);
00947     
00948         /* fill in entries of the variable encoding table. Assign codes based on 
00949            the variable's index. Nothing fancy here...                        */
00950 
00951     for(i=0; i<range; i++){    
00952         tempI = i;
00953         rownum = Tbl_TableAddRow(encTable);
00954         for(j = numEncBits - 1; j >= 0; j--){
00955             if(((int)(tempI / pow((double) 2, (double) j))) == 1){
00956                 entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00957                 Tbl_EntrySetValue(entry, 1, 1);
00958                 Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
00959                 tempI = tempI - (int)pow((double)2,(double)j);
00960             }
00961             else{
00962                 entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00963                 Tbl_EntrySetValue(entry, 0, 0);
00964                 Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
00965             }
00966         }
00967         entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00968         Tbl_EntrySetValue(entry, i, i);
00969         Tbl_TableSetEntry(encTable, entry, rownum, 0, varIsOutput);
00970     }
00971     /* make sure not inc specced if var is output */
00972     if(varIsOutput){
00973         for(i = range; i < ((int) pow((double)2, (double)numEncBits)); i++){
00974             tempI = i;
00975             rownum = Tbl_TableAddRow(encTable);
00976             for(j = numEncBits - 1; j >= 0; j--){
00977                 if(((int)(tempI / pow((double) 2, (double) j))) == 1){
00978                     entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00979                     Tbl_EntrySetValue(entry, 1, 1);
00980                     Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
00981                     tempI = tempI - (int)pow((double)2,(double)j);
00982                 }
00983                 else{
00984                     entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00985                     Tbl_EntrySetValue(entry, 0, 0);
00986                     Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
00987                 }
00988             }
00989             entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00990             Tbl_EntrySetValue(entry, 0, 0);
00991             Tbl_TableSetEntry(encTable, entry, rownum, 0, varIsOutput);
00992         }
00993     }
00994     
00995     
00996     /* store the var, var number, and its table in the encTblArray. */
00997     
00998     Tbl_TableWriteBlifMvToFile(encTable, 0, encFp);
00999     Tbl_TableFree(encTable);
01000 
01001     for(i=0; i < array_n(varArray); i++){
01002         Var_VariableFree(array_fetch(Var_Variable_t *, varArray, i));
01003     }
01004     array_free(varArray);
01005 
01006 }
01007 
01008 
01009 
01022 static void
01023 _IoEncodeWriteVariableSpecial(
01024    Var_Variable_t *var,
01025    FILE *encFp,               
01026    int varIsOutput,
01027    st_table *encOutputsStTable, 
01028    st_table *encInputsStTable
01029    )
01030 {
01031     int j, i, tempI, range, numEncBits, rownum, varIsInput;
01032     Tbl_Table_t *encTable;
01033     char *varname, *dupName;
01034     Var_Variable_t *encVar, *outVar;
01035     Tbl_Entry_t *entry;
01036     array_t *varArray, *symValArray;
01037 
01038     if(varIsOutput == 1){
01039         varIsInput = 0;
01040     }
01041     else{
01042         varIsInput = 1;
01043     }
01044 
01045     if(varIsOutput){
01046         if(st_is_member(encOutputsStTable, (char *)var)){
01047             return;
01048         }
01049         else{
01050             st_insert(encOutputsStTable, (char *) var, (char *) 1);
01051         }
01052     }
01053     else{
01054         if(st_is_member(encInputsStTable, (char *)var)){
01055             return;
01056         }
01057         else{
01058             st_insert(encInputsStTable, (char *) var, (char *) 1);
01059         }
01060     }
01061             
01062 
01063         /* declare encoding input vars based on range. These are associated
01064            with their encoding table. These have names <var>0, <var>1, ...  */
01065 
01066     varArray = array_alloc(Var_Variable_t *, 0);
01067     range = Var_VariableReadNumValues(var);
01068     numEncBits = IoNumEncBits(range);
01069     /* create encoding table */
01070     encTable = Tbl_TableAlloc();
01071     varname = Var_VariableReadName(var);
01072     for(i=0; i<numEncBits; i++){
01073         dupName = ALLOC(char, strlen(varname) + IoNumDigits(numEncBits) + 10);
01074         sprintf(dupName, "%s_bufin%d", varname, i);
01075         encVar = Var_VariableAlloc(NIL(Hrc_Node_t), dupName);
01076         FREE(dupName);
01077         array_insert_last(Var_Variable_t *, varArray, encVar);
01078         (void) Tbl_TableAddColumn(encTable, encVar, varIsInput);
01079     }
01080 
01081         /* declare output var for the encoding table. It is called <var>_bufin     */
01082 
01083     varname = Var_VariableReadName(var);
01084     dupName = ALLOC(char, strlen(varname) + 10);    
01085     sprintf(dupName, "%s_bufin", varname);
01086     outVar = Var_VariableAlloc(NIL(Hrc_Node_t), dupName);
01087     array_insert_last(Var_Variable_t *, varArray, outVar);
01088     FREE(dupName);
01089     if(Var_VariableTestIsSymbolic(var)){
01090       symValArray = array_alloc(char *, 0);
01091       for(i = 0; i < range; i++){
01092         array_insert_last(char *, symValArray, Var_VariableReadSymbolicValueFromIndex(var, i));
01093       }
01094       Var_VariableAddRangeInfo(outVar, range, symValArray);
01095       array_free(symValArray);
01096     }
01097     else{
01098       if(range > 2){
01099         Var_VariableExpandRange(outVar, range);
01100       }
01101     }
01102     (void) Tbl_TableAddColumn(encTable, outVar, varIsOutput);
01103 
01104 
01105         /* fill in entries of the variable encoding table. Assign codes based on 
01106            the variable's index. Nothing fancy here...                        */
01107 
01108     for(i=0; i<range; i++){    
01109         tempI = i;
01110         rownum = Tbl_TableAddRow(encTable);
01111         for(j = numEncBits - 1; j >= 0; j--){
01112             if(((int)(tempI / pow((double) 2, (double) j))) == 1){
01113                 entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
01114                 Tbl_EntrySetValue(entry, 1, 1);
01115                 Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
01116                 tempI = tempI - (int)pow((double)2,(double)j);
01117             }
01118             else{
01119                 entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
01120                 Tbl_EntrySetValue(entry, 0, 0);
01121                 Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
01122             }
01123         }
01124         entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
01125         Tbl_EntrySetValue(entry, i, i);
01126         Tbl_TableSetEntry(encTable, entry, rownum, 0, varIsOutput);
01127     }
01128     /* make sure not inc specced if var is output */
01129     if(varIsOutput){
01130         for(i = range; i < ((int) pow((double)2, (double)numEncBits)); i++){
01131             tempI = i;
01132             rownum = Tbl_TableAddRow(encTable);
01133             for(j = numEncBits - 1; j >= 0; j--){
01134                 if(((int)(tempI / pow((double) 2, (double) j))) == 1){
01135                     entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
01136                     Tbl_EntrySetValue(entry, 1, 1);
01137                     Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
01138                     tempI = tempI - (int)pow((double)2,(double)j);
01139                 }
01140                 else{
01141                     entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
01142                     Tbl_EntrySetValue(entry, 0, 0);
01143                     Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
01144                 }
01145             }
01146             entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
01147             Tbl_EntrySetValue(entry, 0, 0);
01148             Tbl_TableSetEntry(encTable, entry, rownum, 0, varIsOutput);
01149         }
01150     }
01151     
01152     
01153     /* store the var, var number, and its table in the encTblArray. */
01154     
01155     Tbl_TableWriteBlifMvToFile(encTable, 0, encFp);
01156     Tbl_TableFree(encTable);
01157 
01158     for(i=0; i < array_n(varArray); i++){
01159         Var_VariableFree(array_fetch(Var_Variable_t *, varArray, i));
01160     }
01161     array_free(varArray);
01162 
01163 }