VIS

src/io/ioWriteBlifUtil.c

Go to the documentation of this file.
00001 
00039 #include "ioInt.h"
00040 
00041 static char rcsid[] UNUSED = "$Id: ioWriteBlifUtil.c,v 1.12 2005/05/14 02:15:22 fabio Exp $";
00042 
00043 /*---------------------------------------------------------------------------*/
00044 /* Macro declarations                                                        */
00045 /*---------------------------------------------------------------------------*/
00046 
00047 
00050 /*---------------------------------------------------------------------------*/
00051 /* Static function prototypes                                                */
00052 /*---------------------------------------------------------------------------*/
00053 
00054 static void _IoWriteEntryToTable(Tbl_Entry_t *entry, Tbl_Table_t *table, int row, int col, int output);
00055 static void _IoWriteValueToTable(int value, Tbl_Table_t *table, int row, int col, int output);
00056 static Tbl_Table_t *_IoTableRemoveEqualsContruct(Tbl_Table_t *origBlifmvTable, array_t *freeVarArray, int verbosity);
00057 static void _IoVarEncEntryFree(IoVarEncEntry_t *varEnc);
00058 static int _IoNumValues(int colnum, array_t *numValuesArray);
00059 static Tbl_Entry_t *_IoCreateBinRange(array_t *mvEntryBinRanges, Tbl_Entry_t *entry, int numBits, int runLength, int skipLength);
00060 static boolean _IoEntryCheckRange(Tbl_Entry_t *entry, int startValue, int runLength, int skipLength);
00061 static Tbl_Entry_t *_IoAddBinRange(array_t *mvEntryBinRanges, Tbl_Entry_t *entry, int startValue, int runLength, int skipLength);
00062 
00066 /*---------------------------------------------------------------------------*/
00067 /* Definition of exported functions                                          */
00068 /*---------------------------------------------------------------------------*/
00069 
00070 
00071 /*---------------------------------------------------------------------------*/
00072 /* Definition of internal functions                                          */
00073 /*---------------------------------------------------------------------------*/
00074 
00075 
00087 Tbl_Table_t *
00088 IoMakeSingleOutputTable(
00089   Tbl_Table_t *table,
00090   int outputNum
00091   )
00092 {
00093     Tbl_Table_t * tableDup;
00094     int i, j, numRows, numCols;
00095     Tbl_Entry_t *newEntry, *entry, *parentVarEntry;
00096     Var_Variable_t *var;
00097     
00098     tableDup = Tbl_TableAlloc();
00099     numRows = Tbl_TableReadNumRows(table);
00100     numCols = Tbl_TableReadNumInputs(table);
00101     
00102     Tbl_TableForEachInputVar(table,i,var){
00103         Tbl_TableAddColumn(tableDup,var,0);
00104     }
00105     
00106     var = Tbl_TableReadIndexVar(table,outputNum,1);
00107     Tbl_TableAddColumn(tableDup,var,1);
00108     
00109     entry = Tbl_TableDefaultReadEntry(table,outputNum);
00110     if (entry != NIL(Tbl_Entry_t)){
00111         if(Tbl_EntryReadType(entry) != Tbl_EntryNormal_c){
00112             var = Tbl_EntryReadVar(table, entry);
00113             j = Tbl_TableReadVarIndex(table, var, 1);
00114             parentVarEntry = Tbl_TableDefaultReadEntry(table, j);
00115             newEntry = Tbl_EntryDup(parentVarEntry);
00116         }
00117         else{
00118             newEntry = Tbl_EntryDup(entry);
00119         }
00120     }
00121     else {
00122         newEntry = NIL(Tbl_Entry_t);
00123     }
00124     (void) Tbl_TableDefaultSetEntry(tableDup,newEntry,0);
00125     
00126     for(i = 0; i < numRows; i++){
00127         (void) Tbl_TableAddRow(tableDup);
00128         for(j = 0; j < numCols; j++){
00129             entry = Tbl_TableReadEntry(table, i, j, 0);
00130             newEntry = Tbl_EntryDup(entry);
00131             Tbl_TableSetEntry(tableDup, newEntry, i, j, 0);
00132         }
00133         entry = Tbl_TableReadEntry(table, i, outputNum, 1);
00134         newEntry = Tbl_EntryDup(entry);
00135         Tbl_TableSetEntry(tableDup, newEntry, i, 0, 1);
00136     }
00137     return tableDup;
00138 }
00139 
00140 
00141 
00155 boolean
00156 IoOutputExpansionRequired(
00157   Tbl_Table_t *table
00158   )
00159 {
00160     int numRows, numOutputs, i, colnum, parentVarIndex;
00161     Tbl_Entry_t *entry;
00162     Var_Variable_t *parentVar;
00163 
00164     /* previously used to find out the estimated size of the resulting binary 
00165        table (in number of entries) and return TRUE if this number was greater
00166        than 250. Removed this check, and now return TRUE if the table is multi-
00167        output. This is at the cost of potentially increasing runtime.
00168     */
00169     /* if any of the output entries has an =var where var is another output
00170        variable, then output splitting is not done */
00171 
00172     numRows = Tbl_TableReadNumRows(table);
00173     numOutputs = Tbl_TableReadNumOutputs(table);
00174 
00175     for(i = 0; i < numRows; i++){
00176         for(colnum = 0; colnum < numOutputs; colnum++){
00177             entry = Tbl_TableReadEntry(table, i, colnum, 1);
00178             if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){
00179                 parentVar = Tbl_EntryReadVar(table, entry);
00180                 parentVarIndex = Tbl_TableReadVarIndex(table, parentVar, 0);
00181                 if(parentVarIndex == -1){
00182                   fprintf(vis_stderr, "Output entry mimics another output with an '=' construct - error\n");
00183                   assert(parentVarIndex != -1);
00184                 }
00185             }
00186         }
00187     }
00188     if(numOutputs > 1){
00189       return TRUE;
00190     }
00191     return FALSE;
00192 }
00193     
00205 void
00206 IoInitBlifInfo(
00207    IoBlifInfo_t *blifInfo, 
00208    Tbl_Table_t *origBlifmvTable,
00209    FILE *fp,
00210    FILE *encFp,
00211    int verbosity
00212    )
00213 {
00214     blifInfo->varArray = array_alloc(Var_Variable_t *, 0);
00215     blifInfo->blifmvTable = _IoTableRemoveEqualsContruct(origBlifmvTable, blifInfo->varArray, verbosity);
00216     blifInfo->binTable = Tbl_TableAlloc();
00217     blifInfo->inputEncTblArray = array_alloc(IoVarEncEntry_t *, 0);
00218     blifInfo->outputEncTblArray = array_alloc(IoVarEncEntry_t *, 0);
00219     blifInfo->dcTblArray = array_alloc(Tbl_Table_t *, 0);
00220     blifInfo->verbosity = verbosity;
00221     blifInfo->pseudoinputFlag = FALSE;
00222     blifInfo->BlifFp = fp;
00223     blifInfo->EncFp = encFp;
00224 }
00225 
00226 
00238 void
00239 IoFreeBlifInfo(
00240    IoBlifInfo_t *blifInfo
00241    )
00242 {
00243     int i;
00244 
00245     Tbl_TableFree(blifInfo->blifmvTable);
00246     Tbl_TableFree(blifInfo->binTable); 
00247 
00248     for(i=0; i < array_n(blifInfo->inputEncTblArray); i++){
00249         _IoVarEncEntryFree(array_fetch(IoVarEncEntry_t *, blifInfo->inputEncTblArray, i));
00250     }
00251     array_free(blifInfo->inputEncTblArray);
00252 
00253     for(i=0; i < array_n(blifInfo->outputEncTblArray); i++){
00254         _IoVarEncEntryFree(array_fetch(IoVarEncEntry_t *, blifInfo->outputEncTblArray, i));
00255     }
00256     array_free(blifInfo->outputEncTblArray);
00257 
00258     for(i=0; i < array_n(blifInfo->varArray); i++){
00259         Var_VariableFree(array_fetch(Var_Variable_t *, blifInfo->varArray, i));
00260     }
00261     array_free(blifInfo->varArray);
00262 
00263     for(i=0; i < array_n(blifInfo->binTblArray); i++){
00264         Tbl_TableFree(array_fetch(Tbl_Table_t *, blifInfo->binTblArray, i));
00265     }
00266     array_free(blifInfo->binTblArray);
00267 
00268     for(i=0; i < array_n(blifInfo->dcTblArray); i++){
00269         Tbl_TableFree(array_fetch(Tbl_Table_t *, blifInfo->dcTblArray, i));
00270     }
00271     array_free(blifInfo->dcTblArray);
00272     FREE(blifInfo);
00273       
00274 }
00275 
00276 
00288 boolean         
00289 IoVarIsHnodePIO(
00290   Hrc_Node_t *hnode, 
00291   Var_Variable_t *var
00292   )
00293 {
00294     boolean test;
00295     
00296     test = FALSE;
00297     if(Var_VariableTestIsPO(var) || Var_VariableTestIsPI(var) || Var_VariableTestIsSO(var) || Var_VariableTestIsSI(var)){
00298         test = TRUE;
00299     }
00300     return test;
00301 }
00302 
00303 
00315 void
00316 IoEncodeVariable(
00317    IoBlifInfo_t *blifInfo,
00318    Var_Variable_t *var,
00319    int varNum,           
00320    int output
00321    )
00322 {
00323     int range, numEncBits;
00324     IoVarEncEntry_t *varEncEntry;
00325 
00326     range = Var_VariableReadNumValues(var);
00327     numEncBits = IoNumEncBits(range);
00328     
00329     varEncEntry = ALLOC(IoVarEncEntry_t, 1);
00330     varEncEntry->variable = Var_VariableDup(var, NIL(Hrc_Node_t));
00331     varEncEntry->index = varNum;
00332     varEncEntry->numEncBits = numEncBits;
00333     if(output == 1){
00334         array_insert_last(IoVarEncEntry_t *, blifInfo->outputEncTblArray, varEncEntry);
00335     }
00336     else{
00337         array_insert_last(IoVarEncEntry_t *, blifInfo->inputEncTblArray, varEncEntry);
00338     }
00339 
00340 }
00341 
00342 
00354 int
00355 IoNumEncBits(
00356    int n
00357    )
00358 {
00359     int i=0;
00360     int j=1;
00361 
00362     if (n<2){
00363         return 1;
00364     }
00365     else{
00366         while (j < n){
00367             j = j * 2;
00368             i++;
00369         }
00370     }
00371     return i;
00372 
00373 }
00374 
00386 int 
00387 IoNumDigits(
00388    int n
00389    )
00390 {
00391     double j;
00392     
00393     j = log10((double) n) + 1;
00394     return ((int) j);
00395 }
00396 
00408 int
00409 IoLog(
00410    int n
00411    )
00412 {
00413     int i=0;
00414     int j=1;
00415 
00416     while (j < n){
00417         j = j * 2;
00418         i++;
00419     }
00420     return i;
00421 }
00422 
00423 
00435 IoVarEncEntry_t *
00436 IoFindSmallestCode( 
00437    IoBlifInfo_t *blifInfo
00438    )
00439 {
00440     int i, smallestCode, index;
00441     IoVarEncEntry_t *varEnc;
00442 
00443     index = -1;
00444     smallestCode = VIS_INFINITY;
00445     for(i = 0; i < array_n(blifInfo->inputEncTblArray); i++){
00446         varEnc = array_fetch(IoVarEncEntry_t *, blifInfo->inputEncTblArray, i);
00447         if((Var_VariableReadNumValues(varEnc->variable)) < smallestCode){
00448             smallestCode = Var_VariableReadNumValues(varEnc->variable);
00449             index = i;
00450         }
00451     }
00452     
00453     assert(index != -1);
00454     varEnc = array_fetch(IoVarEncEntry_t *, blifInfo->inputEncTblArray, index);
00455     return varEnc;
00456 
00457 }
00458 
00473 void
00474 IoIncreaseCodeSize(
00475   IoVarEncEntry_t *varEnc, 
00476   int numValues,
00477   int verbosity           
00478   )
00479 {
00480     int temp1, temp2, range, numAddedPseudovars, numExpand;
00481 
00482     range = Var_VariableReadNumValues(varEnc->variable);
00483     numAddedPseudovars = IoNumEncBits(numValues);
00484     temp1 = ((int) pow((double) 2, (double)numAddedPseudovars)) - 1;
00485     temp2 = (int) pow((double) 2, (double)varEnc->numEncBits);
00486     numExpand = (temp1 * temp2) + range;
00487     if(verbosity > 2){
00488         (void)fprintf(stdout, "New Number of Values for the variable = %d\n", numExpand);
00489     }
00490     Var_VariableExpandRange(varEnc->variable, numExpand);
00491         
00492 
00493 }
00494 
00495 
00507 void
00508 IoChangeBlifmvTableRows(
00509    IoBlifInfo_t *blifInfo,               
00510    IoVarEncEntry_t *varEnc, 
00511    int row1,
00512    int row2
00513   )
00514 {
00515     int numCurrentBits, i, numRows, colnum, tempCol, reqdColnum;
00516     Tbl_Entry_t *entry;
00517     char *varname, *dupName;
00518     Var_Variable_t *newVar;
00519     IoVarEncEntry_t *tempVarEnc;
00520 
00521     /* add a new column to bin table */
00522     numCurrentBits = varEnc->numEncBits;
00523     varname = Var_VariableReadName(varEnc->variable);
00524     dupName = ALLOC(char, strlen(varname) + IoNumDigits(numCurrentBits) + 2);
00525     sprintf(dupName, "%s%d", varname, numCurrentBits);
00526     newVar = Var_VariableAlloc(NIL(Hrc_Node_t), dupName);
00527     FREE(dupName);
00528     array_insert_last(Var_Variable_t *, blifInfo->varArray, newVar);
00529     colnum = Tbl_TableAddColumn(blifInfo->binTable, newVar, 0);
00530     numRows = Tbl_TableReadNumRows(blifInfo->binTable);
00531     for(i = 0; i < numRows; i++){
00532         entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00533         if(i == row1){
00534             Tbl_EntrySetValue(entry, 0, 0);
00535         }
00536         if(i == row2){
00537             Tbl_EntrySetValue(entry, 1, 1);
00538         }
00539         if((i != row1) && (i != row2)){
00540             Tbl_EntrySetValue(entry, 0, 1);
00541         }
00542         Tbl_TableSetEntry(blifInfo->binTable, entry, i, colnum - 1, 0);
00543     }
00544     tempCol = 0;
00545     reqdColnum = -1;
00546     for(i = 0; i < array_n(blifInfo->inputEncTblArray); i++){
00547         tempVarEnc = array_fetch(IoVarEncEntry_t *, blifInfo->inputEncTblArray, i);
00548         if(tempVarEnc == varEnc){
00549             reqdColnum = tempCol + varEnc->numEncBits;
00550         }
00551         tempCol += tempVarEnc->numEncBits;
00552     }
00553     colnum--;    
00554     assert(reqdColnum != -1);
00555     while(reqdColnum < colnum){
00556         Tbl_TableSwapColumns(blifInfo->binTable, colnum, colnum - 1, 0);
00557         colnum--;
00558     }
00559 }
00560 
00561 
00573 void
00574 IoChangeBlifmvTableEntries(
00575    IoBlifInfo_t *blifInfo,
00576    int rownum,
00577    int numValues,
00578    IoVarEncEntry_t *varEnc, 
00579    array_t *MvOutputArray
00580   )
00581 {
00582     int i, j, k, newrownum, colnum, inputColnumToChange, value, offset;
00583     int numInputs, numOutputs, entryRepetitionCount, numCycles, numNewBits, maxValue, numOldBits;
00584     Tbl_Entry_t *entry, *dupEntry;
00585     lsGen gen;
00586     Tbl_Range_t *range;
00587 
00588     numInputs = Tbl_TableReadNumInputs(blifInfo->blifmvTable);
00589     numOutputs = Tbl_TableReadNumOutputs(blifInfo->blifmvTable);
00590     numNewBits = IoNumEncBits(numValues);
00591     numOldBits = varEnc->numEncBits;
00592     maxValue = (int) pow((double) 2, (double)(numNewBits + numOldBits));
00593 
00594     inputColnumToChange = varEnc->index;
00595     for(i = 0; i < Tbl_TableReadNumRows(blifInfo->blifmvTable); i++){
00596         if (i != rownum){
00597             entry = Tbl_TableReadEntry(blifInfo->blifmvTable, i, inputColnumToChange, 0);
00598             dupEntry = Tbl_EntryDup(entry);
00599             offset = (int) pow((double) 2, (double)varEnc->numEncBits);
00600             Tbl_EntryForEachValue(entry, value, gen, range){
00601                 for(j = value ; j < maxValue; j = j + offset){
00602                     Tbl_EntrySetValue(dupEntry, j, j);
00603                 }
00604             }
00605             Tbl_TableSetEntry(blifInfo->blifmvTable, dupEntry, i, inputColnumToChange, 0);
00606         }
00607     }
00608     newrownum = -1;
00609     for(i = 0; i < numValues; i++){
00610  
00611          /* add a row, and duplicate all entries of the original row except for 
00612             the one that needs a new entry (because of the new code). This entry
00613             gets code = oldCode + i * (2^numCurrentEncBits)      */
00614 
00615         newrownum = Tbl_TableAddRow(blifInfo->blifmvTable);
00616         assert(newrownum != -1);
00617         for(colnum = 0; colnum < numInputs; colnum++){
00618             entry = Tbl_TableReadEntry(blifInfo->blifmvTable, rownum, colnum, 0);
00619             if(colnum != inputColnumToChange){
00620                 dupEntry = Tbl_EntryDup(entry);
00621                 Tbl_TableSetEntry(blifInfo->blifmvTable, dupEntry, newrownum, colnum, 0);
00622             }
00623             else{
00624                 dupEntry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00625                 offset = i * ((int) pow((double) 2, (double) varEnc->numEncBits));
00626                 Tbl_EntryForEachValue(entry, value, gen, range){
00627                     Tbl_EntrySetValue(dupEntry, value + offset, value + offset);
00628                 }
00629                 Tbl_TableSetEntry(blifInfo->blifmvTable, dupEntry, newrownum, colnum, 0);
00630             }
00631         }
00632     }
00633 
00634     /* This section singleton-izes the output entries of the new row. 
00635        Multiple outputs are accounted for. If more than one output has 
00636        non-singleton entries, they are all singleton-ized. Finally,
00637        the original row is deleted...                                       */ 
00638     
00639     entryRepetitionCount = numValues;
00640     numCycles = 1;
00641     newrownum++;
00642     
00643     for(colnum = 0; colnum < numOutputs; colnum++){
00644         newrownum = newrownum - numValues;
00645         numCycles *= _IoNumValues(colnum, MvOutputArray);
00646         entryRepetitionCount /= array_fetch(int, MvOutputArray, colnum);
00647         entry = Tbl_TableReadEntry(blifInfo->blifmvTable, rownum, colnum, 1);
00648         for(j = 0; j < numCycles; j++){
00649             Tbl_EntryForEachValue(entry, value, gen, range){
00650                 for(k = 0; k < entryRepetitionCount; k++){
00651                     dupEntry = Tbl_EntryAlloc(Tbl_EntryNormal_c);                       
00652                     Tbl_EntrySetValue(dupEntry, value, value);       
00653                     Tbl_TableSetEntry(blifInfo->blifmvTable, dupEntry, newrownum++, colnum, 1);
00654                 }
00655             }
00656         }
00657     }
00658     blifInfo->blifmvTable = Tbl_TableRowDelete(blifInfo->blifmvTable, rownum, blifInfo->varArray); 
00659 }
00660 
00661 
00673 void
00674 IoChangeEncTableEntries(
00675    IoBlifInfo_t *blifInfo,               
00676    st_table *blifInputsStTable,
00677    IoVarEncEntry_t *varEnc, 
00678    int numValues
00679   )
00680 {
00681     int numOrigBits, numAddedBits, i;
00682     char *varname, *dupName;
00683     
00684     numAddedBits = IoNumEncBits(numValues);
00685     numOrigBits = varEnc->numEncBits;
00686 
00687     varname = Var_VariableReadName(varEnc->variable);
00688     for(i=0; i<numAddedBits; i++){
00689         dupName = ALLOC(char, strlen(varname) + IoNumDigits(numAddedBits + numOrigBits)+ 2);
00690         sprintf(dupName, "%s%d", varname, i + numOrigBits);
00691         if(!st_is_member(blifInputsStTable, (char *)dupName)){
00692             (void)fprintf(blifInfo->BlifFp, ".inputs %s\n", dupName);
00693             if(blifInfo->pseudoinputFlag == FALSE){
00694                 (void)fprintf(blifInfo->EncFp, ".table %s\n", dupName);
00695                 (void)fprintf(blifInfo->EncFp, "-\n");
00696             }
00697             st_insert(blifInputsStTable, (char *)dupName, (char *)1);
00698         }
00699         else{
00700             FREE(dupName);
00701         }
00702     }
00703     varEnc->numEncBits += numAddedBits;
00704 
00705 }
00706 
00707 
00708 
00709 
00721 void
00722 IoInvertBinTableOutput(
00723    IoBlifInfo_t * blifInfo,
00724    int colnumToInvert
00725    )
00726 {
00727     int i;
00728     char *name, *newname;
00729     Var_Variable_t *var;
00730     
00731     var = Tbl_TableReadIndexVar(blifInfo->binTable, colnumToInvert, 1);
00732     name = Var_VariableReadName(var);
00733     newname = ALLOC(char, strlen(name) + 4);
00734     sprintf(newname, "%s_b", name);
00735     (void)fprintf(blifInfo->BlifFp, ".names %s %s\n", newname, name);
00736     (void)fprintf(blifInfo->BlifFp, "0 1\n");
00737     Var_VariableChangeName(var, newname);
00738     FREE(newname);
00739     for(i = 0; i < Tbl_TableReadNumRows(blifInfo->binTable); i++){
00740         Tbl_TableComplementEntry(blifInfo->binTable, i, colnumToInvert, 1);
00741     }
00742 }
00743 
00744 
00759 array_t *
00760 IoMakeBinaryRangesArray(
00761    Tbl_Entry_t *entry,
00762    int colnum,
00763    IoBlifInfo_t *blifInfo                      
00764    )
00765 {
00766     array_t *mvEntryBinRanges;
00767     int i, j, numBits, runLength, skipLength;
00768     
00769     mvEntryBinRanges = array_alloc(IoBinRangeEntry_t *, 0);
00770     numBits = IoNumBinVars(colnum + 1, blifInfo->inputEncTblArray);
00771     for(i = numBits; i > 0; i--){
00772         for(j = 0; j < numBits; j++){
00773             runLength = (int) pow((double) 2, (double) i);
00774             skipLength = (int) pow((double) 2, (double) j);
00775             if((runLength * skipLength) <= (int) pow((double) 2, (double) numBits)){
00776 /*              fprintf(stdout, "run %d, skip %d\n", runLength, skipLength); */
00777                 entry = _IoCreateBinRange(mvEntryBinRanges, entry, numBits, runLength, skipLength);
00778             }
00779         }
00780     }
00781     entry = _IoCreateBinRange(mvEntryBinRanges, entry, numBits, 1, 1);      
00782     assert(Tbl_EntryReadNumValues(entry) == 0);
00783     Tbl_EntryFree(entry);
00784     return mvEntryBinRanges;
00785 }
00786 
00787 
00799 int
00800 IoNumValuesFromBinRangesArray( 
00801    int colnum,
00802    array_t *binRangesArray
00803    )
00804 {
00805     array_t *mvEntryBinRanges;
00806 
00807     if(colnum == 0){
00808         return 1;
00809     }
00810     else{
00811         mvEntryBinRanges = array_fetch(array_t *, binRangesArray, colnum - 1);
00812         return(array_n(mvEntryBinRanges));
00813     }
00814 }
00815 
00816 
00828 int
00829 IoNumBinVars( 
00830    int colnum,
00831    array_t *encTblArray
00832    )
00833 {
00834     IoVarEncEntry_t *varEnc;
00835     
00836     if(colnum == 0){
00837         return 0;
00838     }
00839     else{
00840         varEnc = array_fetch(IoVarEncEntry_t *, encTblArray, colnum-1);
00841         return(varEnc->numEncBits);
00842     }
00843 }
00844 
00845     
00846 /*---------------------------------------------------------------------------*/
00847 /* Definition of static functions                                            */
00848 /*---------------------------------------------------------------------------*/
00849 
00850 
00862 static void
00863 _IoWriteEntryToTable(
00864    Tbl_Entry_t *entry, 
00865    Tbl_Table_t *table, 
00866    int row, 
00867    int col, 
00868    int output
00869 )
00870 {
00871     Tbl_Entry_t *dupEntry;
00872     
00873     dupEntry = Tbl_EntryDup(entry);
00874     Tbl_TableSetEntry(table, dupEntry, row, col, output);
00875 }
00876 
00877 
00889 static void
00890 _IoWriteValueToTable(
00891    int value, 
00892    Tbl_Table_t *table, 
00893    int row, 
00894    int col, 
00895    int output
00896 )
00897 {
00898     Tbl_Entry_t *entry;
00899     
00900     entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
00901     Tbl_EntrySetValue(entry, value, value);
00902     Tbl_TableSetEntry(table, entry, row, col, output);
00903 }
00904 
00916 static Tbl_Table_t *
00917 _IoTableRemoveEqualsContruct(
00918    Tbl_Table_t *origBlifmvTable,
00919    array_t *freeVarArray,
00920    int verbosity
00921    )
00922 {
00923     Tbl_Table_t *resultTable;
00924     int numRows, numInputs, numOutputs, numRowsAfterExpansion, i, j, k, colnum, rownum, currRow, value;
00925     int parentVarnumValues, parentVarIndex, rootRow, entryRepetitionCount ;
00926     st_table *parentsStTable;
00927     Tbl_Entry_t *entry, *parentVarEntry, *dupEntry;
00928     Var_Variable_t *parentVar, *var;
00929     boolean parentVarIsOutput, rowContainsEqualEntries, insertedI;
00930     st_generator *gen;
00931     Tbl_Range_t *range;
00932     lsGen listgen;
00933     array_t *rowDeleteArray;
00934     char *dummy;
00935 
00936     resultTable = Tbl_TableHardDup(origBlifmvTable);
00937     /* remove "="s in original defaults table*/
00938     for(i = 0; i < Tbl_TableReadNumOutputs(resultTable); i++){
00939         entry = Tbl_TableDefaultReadEntry(resultTable, i);
00940         if(entry != NIL(Tbl_Entry_t)){
00941             if(Tbl_EntryReadType(entry) != Tbl_EntryNormal_c){
00942                 var = Tbl_EntryReadVar(resultTable, entry);
00943                 j = Tbl_TableReadVarIndex(resultTable, var, 1);
00944                 parentVarEntry = Tbl_TableDefaultReadEntry(resultTable, j);
00945                 dupEntry = Tbl_EntryDup(parentVarEntry);
00946                 Tbl_TableDefaultSetEntry(resultTable, dupEntry, i);
00947                 Tbl_EntryFree(entry);
00948             }
00949         }
00950     }
00951 
00952     /* first expand all rows with "=" constructs, in the same table */
00953     numRows = Tbl_TableReadNumRows(resultTable);
00954     numInputs = Tbl_TableReadNumInputs(resultTable);
00955     numOutputs = Tbl_TableReadNumOutputs(resultTable);
00956     rootRow = numRows;
00957 
00958     for(i = 0; i < numRows; i++){
00959         numRowsAfterExpansion = 1;
00960         rowContainsEqualEntries = FALSE;        
00961         parentsStTable = st_init_table(st_ptrcmp, st_ptrhash);
00962 
00963         /* find variables that are parent variables, ie variables 'var' that
00964            have =var references in that row of the table    */
00965         for(colnum = 0; colnum < numInputs; colnum++){
00966             entry = Tbl_TableReadEntry(resultTable, i, colnum, 0);
00967             if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){
00968                 rowContainsEqualEntries = TRUE;
00969                 parentVar = Tbl_EntryReadVar(resultTable, entry);
00970                 st_insert(parentsStTable, (char *) parentVar, (char *) 1);
00971             }
00972         }
00973         for(colnum = 0; colnum < numOutputs; colnum++){
00974             entry = Tbl_TableReadEntry(resultTable, i, colnum, 1);
00975             if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){
00976                 rowContainsEqualEntries = TRUE;
00977                 parentVar = Tbl_EntryReadVar(resultTable, entry);
00978                 st_insert(parentsStTable, (char *) parentVar, (char *) 1);
00979             }
00980         }
00981         if(rowContainsEqualEntries == FALSE){
00982             st_free_table(parentsStTable);
00983             continue;
00984         }
00985         
00986         /* find the number of rows after expansion */
00987         st_foreach_item(parentsStTable, gen, &parentVar, &dummy){
00988             parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 0);
00989             if(parentVarIndex != -1){
00990                 parentVarIsOutput = 0;
00991             }
00992             else{
00993                 parentVarIsOutput = 1;
00994                 parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 1);              
00995             }
00996             parentVarEntry = Tbl_TableReadEntry(resultTable, i, parentVarIndex, parentVarIsOutput);
00997             numRowsAfterExpansion *= Tbl_EntryReadNumValues(parentVarEntry);
00998         }
00999 
01000         /* write out expanded form of this row */
01001         for(j = 0; j < numRowsAfterExpansion; j++){
01002             Tbl_TableAddRow(resultTable);
01003         }
01004         /* expand parent variables first */
01005         entryRepetitionCount = numRowsAfterExpansion;
01006         st_foreach_item(parentsStTable, gen, &parentVar, &dummy){
01007             parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 0);
01008             if(parentVarIndex != -1){
01009                 parentVarIsOutput = 0;
01010             }
01011             else{
01012                 parentVarIsOutput = 1;
01013                 parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 1);              
01014             }
01015             parentVarEntry = Tbl_TableReadEntry(resultTable, i, parentVarIndex,
01016                                                   parentVarIsOutput);
01017             parentVarnumValues = Tbl_EntryReadNumValues(parentVarEntry);
01018             currRow = rootRow;
01019             entryRepetitionCount = entryRepetitionCount / parentVarnumValues;
01020             while(currRow < rootRow + numRowsAfterExpansion){
01021                 Tbl_EntryForEachValue(parentVarEntry, value, listgen, range){       
01022                     for(k = 0; k < entryRepetitionCount; k++){
01023                         _IoWriteValueToTable(value, resultTable, currRow, parentVarIndex,
01024                                             parentVarIsOutput);
01025                         currRow++;
01026                     }
01027                 }
01028             }
01029         }
01030 
01031         /* next expand variables that reference parent vars */
01032         for(colnum = 0; colnum < numInputs; colnum++){
01033             entry = Tbl_TableReadEntry(resultTable, i, colnum, 0);
01034             if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){
01035                 parentVar = Tbl_EntryReadVar(resultTable, entry);
01036                 parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 0);
01037                 if(parentVarIndex != -1){
01038                     parentVarIsOutput = 0;
01039                 }
01040                 else{
01041                     parentVarIsOutput = 1;
01042                     parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 1);          
01043                 }
01044                 parentVarEntry = Tbl_TableReadEntry(resultTable, i, parentVarIndex,
01045                                                       parentVarIsOutput);
01046                 for(k = rootRow; k < rootRow + numRowsAfterExpansion; k++){
01047                     entry = Tbl_TableReadEntry(resultTable, k, parentVarIndex,
01048                                                parentVarIsOutput);          
01049                     _IoWriteEntryToTable(entry, resultTable, k, colnum, 0);
01050                 }
01051             }
01052             else{
01053                 if(!st_is_member(parentsStTable, (char *) Tbl_TableReadIndexVar(resultTable,
01054                                                                                   colnum, 0))){
01055                     for(k = rootRow; k < rootRow + numRowsAfterExpansion; k++){
01056                         _IoWriteEntryToTable(entry, resultTable, k, colnum, 0);
01057                     }
01058                 }
01059             }
01060         }
01061         for(colnum = 0; colnum < numOutputs; colnum++){
01062             entry = Tbl_TableReadEntry(resultTable, i, colnum, 1);
01063             if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){
01064                 parentVar = Tbl_EntryReadVar(resultTable, entry);
01065                 parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 0);
01066                 if(parentVarIndex != -1){
01067                     parentVarIsOutput = 0;
01068                 }
01069                 else{
01070                     parentVarIsOutput = 1;
01071                     parentVarIndex = Tbl_TableReadVarIndex(resultTable, parentVar, 1);          
01072                 }
01073                 parentVarEntry = Tbl_TableReadEntry(resultTable, i, parentVarIndex,
01074                                                       parentVarIsOutput);
01075                 for(k = rootRow; k < rootRow + numRowsAfterExpansion; k++){
01076                     entry = Tbl_TableReadEntry(resultTable, k, parentVarIndex,
01077                                                parentVarIsOutput);          
01078                     _IoWriteEntryToTable(entry, resultTable, k, colnum, 1);
01079                 }
01080             }
01081             else{
01082                 if(!st_is_member(parentsStTable, (char *) Tbl_TableReadIndexVar(resultTable,
01083                                                                                   colnum, 1))){
01084                     for(k = rootRow; k < rootRow + numRowsAfterExpansion; k++){
01085                         _IoWriteEntryToTable(entry, resultTable, k, colnum, 1);
01086                     }
01087                 }
01088             }
01089         }
01090         rootRow += numRowsAfterExpansion;
01091         st_free_table(parentsStTable);
01092     }
01093     
01094     
01095     /* now delete rows with "=" constructs */
01096     rowDeleteArray = array_alloc(int, 0);
01097     for(i = 0; i < numRows; i++){
01098         insertedI = FALSE;
01099         for(colnum = 0; colnum < numInputs; colnum++){
01100             entry = Tbl_TableReadEntry(resultTable, i, colnum, 0);
01101             if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){
01102                 if(!insertedI){
01103                     array_insert_last(int, rowDeleteArray, i);
01104                     insertedI = TRUE;
01105                 }
01106             }
01107         }
01108         for(colnum = 0; colnum < numOutputs; colnum++){
01109             entry = Tbl_TableReadEntry(resultTable, i, colnum, 1);
01110             if(Tbl_EntryReadType(entry) == Tbl_EntryEqual_c){
01111                 if(!insertedI){
01112                     array_insert_last(int, rowDeleteArray, i);
01113                     insertedI = TRUE;
01114                 }
01115             }
01116         }
01117     }
01118     /* array of vars that are to be freed. Since these are called with 
01119       a NIL(Hrc_Node_t), they need to be freed separately, and kept track 
01120       of
01121     */
01122     for(i = 0; i < array_n(rowDeleteArray); i++){
01123         rownum = array_fetch(int, rowDeleteArray, i) - i;
01124         resultTable = Tbl_TableRowDelete(resultTable, rownum, freeVarArray); 
01125     }
01126     array_free(rowDeleteArray);
01127 
01128 
01129     if(verbosity > 1){
01130         (void)fprintf(stdout, "Blifmv Table after = removal is\n");
01131         Tbl_TableWriteBlifMvToFile(resultTable, 0, stdout);
01132     }
01133     return resultTable;
01134 
01135 }
01136         
01137 
01149 static void
01150 _IoVarEncEntryFree(
01151   IoVarEncEntry_t *varEnc
01152   )
01153 {
01154     Var_VariableFree(varEnc->variable);
01155     free(varEnc);
01156 }
01157 
01158 
01171 static boolean
01172 _IoEntryCheckRange(
01173  Tbl_Entry_t *entry,
01174  int startValue,
01175  int runLength,
01176  int skipLength
01177  )
01178 {
01179     boolean startFound;
01180     int value, i;
01181     lsGen gen;
01182     Tbl_Range_t *range;
01183 
01184     startFound = FALSE;
01185     i = 1;
01186     Tbl_EntryForEachValue(entry, value, gen, range){
01187         if(value == startValue){
01188             startFound = TRUE;
01189         }
01190         if((!startFound) && (value > startValue)){
01191             lsFinish(gen);
01192             return FALSE;
01193         }
01194         if(value == startValue + (i * skipLength)){
01195             i++;
01196         }
01197         if(value > startValue + (i * skipLength)){
01198             lsFinish(gen);
01199             return FALSE;
01200         }
01201         if(i == runLength){
01202             lsFinish(gen);
01203             return TRUE;
01204         }
01205     }
01206     return FALSE;
01207 }
01208 
01209 
01225 static Tbl_Entry_t *
01226 _IoCreateBinRange(
01227    array_t *mvEntryBinRanges,
01228    Tbl_Entry_t *entry,
01229    int numBits,          
01230    int runLength,             
01231    int skipLength
01232    )             
01233 {
01234     int i, j, bitPos, tempI, numDash, end, numStartValues, startValue;
01235     array_t *freeBitsArray;
01236 
01237     numDash = IoLog(runLength);
01238     end = IoLog(skipLength);
01239     freeBitsArray = array_alloc(int, 0);
01240     for(i = 0; i < numBits; i++){
01241         if(i < end){
01242             array_insert_last(int, freeBitsArray, i);
01243         }
01244         if(i >= end + numDash){
01245             array_insert_last(int, freeBitsArray, i);
01246         }
01247     }
01248     numStartValues = (int) pow((double) 2, (double) array_n(freeBitsArray));
01249     for(i = 0; i < numStartValues; i++){
01250         startValue = 0;
01251         tempI = i;
01252         for(j = array_n(freeBitsArray) - 1; j >= 0; j--){
01253             if(tempI >= (int) pow((double) 2, (double) j)){
01254                 bitPos = array_fetch(int, freeBitsArray, j);
01255                 startValue += (int) pow((double) 2, (double) bitPos);
01256                 tempI -= (int) pow((double) 2, (double) j);
01257             }
01258         } 
01259 /*      fprintf(stdout, "trying start %d, run %d, skip %d\n", startValue, runLength, skipLength); */
01260         if(_IoEntryCheckRange(entry, startValue, runLength, skipLength)){
01261             entry = _IoAddBinRange(mvEntryBinRanges, entry, startValue, runLength, skipLength);
01262         }
01263     }
01264     array_free(freeBitsArray);
01265     return entry;
01266 }
01267 
01279 static Tbl_Entry_t *
01280 _IoAddBinRange(
01281    array_t *mvEntryBinRanges,
01282    Tbl_Entry_t *entry,
01283    int startValue,
01284    int runLength,             
01285    int skipLength
01286    )
01287 {
01288     IoBinRangeEntry_t *binRangeEntry;
01289     int i, value;
01290     Tbl_Entry_t *newEntry;
01291     lsGen gen;
01292     Tbl_Range_t *range;
01293     
01294     binRangeEntry = ALLOC(IoBinRangeEntry_t, 1);
01295     binRangeEntry->startValue = startValue;
01296     binRangeEntry->runLength = runLength;
01297     binRangeEntry->skipLength = skipLength;
01298     array_insert_last(IoBinRangeEntry_t *, mvEntryBinRanges, binRangeEntry);
01299     newEntry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
01300     i = 0;
01301     Tbl_EntryForEachValue(entry, value, gen, range){
01302         if((value == startValue + (i * skipLength)) && (i < runLength)){
01303             i++;
01304         }
01305         else{
01306             Tbl_EntrySetValue(newEntry, value, value);
01307         }
01308     }
01309     Tbl_EntryFree(entry);
01310     return newEntry;
01311 }
01312 
01313 
01325 static int
01326 _IoNumValues(
01327   int colnum,
01328   array_t *numValuesArray
01329   )
01330 {
01331     if(colnum == 0){
01332         return 1;
01333     }
01334     else{
01335         return(array_fetch(int, numValuesArray, colnum - 1));
01336     }
01337 }
01338                
01339