VIS
|
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 }