source: vis_dev/vis-2.3/src/io/ioWriteBlifIo.c @ 40

Last change on this file since 40 was 14, checked in by cecile, 13 years ago

vis2.3

File size: 37.4 KB
Line 
1/**CFile***********************************************************************
2
3  FileName    [ ioWriteBlifIo.c ]
4
5  PackageName [ io ]
6
7  Synopsis    [ This file contains blifmv -> blif write routines that handle
8                the functionality of files IO.]
9
10  Description [ Routines for writing determinized, encoded tables to a file
11                as requested by the write_blif command. All file IO routines
12                are contained in this file. ]
13
14  SeeAlso     [ ioReadBlifmv.c, ioWriteBlif.c, ioWriteBlifUtil.c]
15
16  Author      [ Sunil P. Khatri ]
17
18  Copyright   [Copyright (c) 1994-1996 The Regents of the Univ. of California.
19  All rights reserved.
20
21  Permission is hereby granted, without written agreement and without license
22  or royalty fees, to use, copy, modify, and distribute this software and its
23  documentation for any purpose, provided that the above copyright notice and
24  the following two paragraphs appear in all copies of this software.
25
26  IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
27  DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
28  OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
29  CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31  THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
32  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
33  FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN
34  "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE
35  MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.]
36
37******************************************************************************/
38
39#include "ioInt.h"
40
41static char rcsid[] UNUSED = "$Id: ioWriteBlifIo.c,v 1.13 2005/05/14 02:15:22 fabio Exp $";
42
43/*---------------------------------------------------------------------------*/
44/* Macro declarations                                                        */
45/*---------------------------------------------------------------------------*/
46
47
48
49/**AutomaticStart*************************************************************/
50
51/*---------------------------------------------------------------------------*/
52/* Static function prototypes                                                */
53/*---------------------------------------------------------------------------*/
54
55static void _IoEncodeWriteVariable(Var_Variable_t *var, FILE *encFp, int varIsOutput, st_table *encOutputsStTable, st_table *encInputsStTable);
56static void _IoEncodeWriteVariableSpecial(Var_Variable_t *var, FILE *encFp, int varIsOutput, st_table *encOutputsStTable, st_table *encInputsStTable);
57
58/**AutomaticEnd***************************************************************/
59
60
61/*---------------------------------------------------------------------------*/
62/* Definition of exported functions                                          */
63/*---------------------------------------------------------------------------*/
64
65
66/*---------------------------------------------------------------------------*/
67/* Definition of internal functions                                          */
68/*---------------------------------------------------------------------------*/
69
70   
71/**Function***********************************************************
72
73  Synopsis      [ Writes out mv->binary encoding tables  for relevant variables]
74
75  Description   [ ]
76
77  SideEffects   [ ]
78
79  SeeAlso       [  ]
80************************************************************************/
81void
82IoEncWriteMvToBinTables(
83  Hrc_Node_t *hnode, 
84  FILE *encFp, 
85  st_table *encOutputsStTable, 
86  st_table *encInputsStTable,
87  int combinationalOnly
88  )
89{
90  int i;
91  Var_Variable_t *var;
92  st_generator *gen;
93  char *childname;
94  Hrc_Node_t *childnode;
95 
96  /* latch IOs encoding tables not handled here */
97  /* if a PI or SO drives a latch, then in the combinational case, this
98     PI is not encoded (since the (mv) latch will be reinstated after
99     sis optimization. In the non-comvinational case ("wl" or "wl -l")
100     every PI and SO is encoded.
101  */
102  if(combinationalOnly){
103    Hrc_NodeForEachFormalInput(hnode, i, var){
104      if(!((Var_VariableReadNumFanoutTables(var) == 0))){
105        _IoEncodeWriteVariable(var, encFp, 0, encOutputsStTable, encInputsStTable);
106      }
107    }
108    Hrc_NodeForEachChild(hnode, gen, childname, childnode){
109      Hrc_NodeForEachActualOutput(childnode, i, var){
110        if(!((Var_VariableReadNumFanoutTables(var) == 0))){
111          _IoEncodeWriteVariable(var, encFp, 0, encOutputsStTable, encInputsStTable);
112        }
113      }
114    }
115  }
116  else{
117    Hrc_NodeForEachFormalInput(hnode, i, var){
118      _IoEncodeWriteVariable(var, encFp, 0, encOutputsStTable, encInputsStTable);
119    }
120    Hrc_NodeForEachChild(hnode, gen, childname, childnode){
121      Hrc_NodeForEachActualOutput(childnode, i, var){
122        _IoEncodeWriteVariable(var, encFp, 0, encOutputsStTable, encInputsStTable);
123      }
124    }
125  }
126}
127
128/**Function***********************************************************
129
130  Synopsis      [ Writes out binary->mv  decoding tables  for relevant variables]
131
132  Description   [ ]
133
134  SideEffects   [ ]
135
136  SeeAlso       [  ]
137************************************************************************/
138void
139IoEncWriteBinToMvTables(
140  Hrc_Node_t *hnode, 
141  FILE *encFp, 
142  st_table *encOutputsStTable, 
143  st_table *encInputsStTable,
144  int combinationalOnly,
145  int makeLatchIOsPOs
146  )
147{
148  int i;
149  Var_Variable_t *var;
150  st_generator *gen;
151  char *childname;
152  Hrc_Node_t *childnode;
153
154  /* latch IOs encoding tables not handled here */
155  /* if a PO or SI is driven by a latch, then in the combinational case, this
156     var is not encoded (since the (mv) latch will be reinstated after
157     sis optimization. In case of "wl -l" the same applies, since we are sure
158     to be able to reinstate teh mv latch after sis optimization. However, in "wl"
159     every PI and SO is encoded since we are not sure  that mv latches can be
160     reinstated after sis optimization. Similarly, if teh PO or SI is a PI/SO 
161     then no encoding is needed in all cases (comb or non-comb)
162  */
163  /*  if(combinationalOnly || makeLatchIOsPOs){ */
164  /* The above line was changed since "wl -l" now writes out latches such that
165     they drive a buffer node. As a result, even if a PO or SI is driven by the
166     latch, the PO/SI needs bin-mv tables
167  */
168  if(combinationalOnly){ 
169    Hrc_NodeForEachFormalOutput(hnode, i, var){
170      if(!((Var_VariableTestIsSO(var) || Var_VariableTestIsPI(var) ||
171            Var_VariableTestIsPS(var)))){
172        _IoEncodeWriteVariable(var, encFp, 1, encOutputsStTable, encInputsStTable);
173      }
174    }
175    Hrc_NodeForEachChild(hnode, gen, childname, childnode){
176      Hrc_NodeForEachActualInput(childnode, i, var){
177        if(!((Var_VariableTestIsSO(var) || Var_VariableTestIsPI(var) ||
178              Var_VariableTestIsPS(var)))){
179          _IoEncodeWriteVariable(var, encFp, 1, encOutputsStTable, encInputsStTable);
180        }
181      }
182    }
183  }
184  else{
185    Hrc_NodeForEachFormalOutput(hnode, i, var){
186      if(!((Var_VariableTestIsSO(var) || Var_VariableTestIsPI(var)))){
187        _IoEncodeWriteVariable(var, encFp, 1, encOutputsStTable, encInputsStTable);
188      }
189    }
190    Hrc_NodeForEachChild(hnode, gen, childname, childnode){
191      Hrc_NodeForEachActualInput(childnode, i, var){
192        if(!((Var_VariableTestIsSO(var) || Var_VariableTestIsPI(var)))){
193          _IoEncodeWriteVariable(var, encFp, 1, encOutputsStTable, encInputsStTable);
194        }
195      }
196    }
197  }
198}
199
200/**Function***********************************************************
201
202  Synopsis      [ Writes out .input line for blif file]
203
204  Description   [ ]
205
206  SideEffects   [ ]
207
208  SeeAlso       [  ]
209************************************************************************/
210 int
211IoBlifWriteInputs(
212  Hrc_Node_t *hnode, 
213  FILE *fp, 
214  st_table *blifInputsStTable,
215  int combinationalOnly,
216  int makeLatchIOsPOs
217  )
218{
219  int i, j, k, numVal, numEncBits, numInputsWritten;
220  Tbl_Table_t *table;
221  st_generator *gen;
222  Var_Variable_t *var;
223  char *name, *dupName, *varName;
224  boolean test;
225 
226  numInputsWritten = 0;
227  fprintf(fp,".inputs ");     
228  Hrc_NodeForEachNameTable(hnode, i, table){
229    Tbl_TableForEachInputVar(table, k, var){
230      if(combinationalOnly){
231        test = Var_VariableTestIsPS(var) || Var_VariableTestIsSO(var) || Var_VariableTestIsPI(var);
232      }
233      else{
234        test = Var_VariableTestIsSO(var) || Var_VariableTestIsPI(var);
235      }
236      if(test){
237        name = Var_VariableReadName(var);
238        numVal = Var_VariableReadNumValues(var);
239        numEncBits = IoNumEncBits(numVal);
240        for(j=0; j<numEncBits; j++){
241          dupName = ALLOC(char, strlen(name) + IoNumDigits(numEncBits) + 2);
242          sprintf(dupName, "%s%d", name, j);
243          if(!st_is_member(blifInputsStTable, (char *)dupName)){
244            fprintf(fp,"%s ",dupName);
245            numInputsWritten++;
246            st_insert(blifInputsStTable, (char *)dupName, (char *)1);
247          }
248          else{
249            FREE(dupName);
250          }
251        }
252      }
253    }
254  }
255  if(!combinationalOnly){
256    Hrc_NodeForEachVariable(hnode, gen, varName, var){
257      if(Var_VariableTestIsPI(var)){
258        name = Var_VariableReadName(var);
259        numVal = Var_VariableReadNumValues(var);
260        numEncBits = IoNumEncBits(numVal);
261        for(j=0; j<numEncBits; j++){
262          dupName = ALLOC(char, strlen(name) + IoNumDigits(numEncBits) + 2);
263          sprintf(dupName, "%s%d", name, j);
264          if(!st_is_member(blifInputsStTable, (char *)dupName)){
265            fprintf(fp,"%s ",dupName);
266            numInputsWritten++;
267            st_insert(blifInputsStTable, (char *)dupName, (char *)1);
268          }
269          else{
270            FREE(dupName);
271          }
272        }
273      }
274    }
275  }
276  return numInputsWritten;
277}
278
279
280/**Function***********************************************************
281
282  Synopsis      [ Writes out .output line for blif file]
283
284  Description   [ ]
285
286  SideEffects   [ ]
287
288  SeeAlso       [  ]
289************************************************************************/
290 int
291IoBlifWriteOutputs(
292  Hrc_Node_t *hnode, 
293  FILE *fp,
294  st_table *blifOutputsStTable,
295  int combinationalOnly,
296  int makeLatchIOsPOs
297  )
298{
299  int i, j, k, numVal, numEncBits, numOutputsWritten;
300  Tbl_Table_t *table;
301  st_generator *gen;
302  Var_Variable_t *var;
303  char *name, *dupName, *varName;
304  boolean test;
305
306  numOutputsWritten = 0;
307  fprintf(fp,"\n.outputs "); 
308  Hrc_NodeForEachNameTable(hnode, i, table){
309    Tbl_TableForEachOutputVar(table, k, var){
310      if(combinationalOnly){
311        test = Var_VariableTestIsNS(var) || Var_VariableTestIsSI(var) || Var_VariableTestIsPO(var);
312      }
313      else{
314        test = Var_VariableTestIsSI(var) || Var_VariableTestIsPO(var);
315      }
316      if(test){
317        name = Var_VariableReadName(var);
318        numVal = Var_VariableReadNumValues(var);
319        numEncBits = IoNumEncBits(numVal);
320        for(j=0; j<numEncBits; j++){
321          dupName = ALLOC(char, strlen(name) + IoNumDigits(numEncBits) + 2);
322          sprintf(dupName, "%s%d", name, j);
323          if(!st_is_member(blifOutputsStTable, (char *)dupName)){
324            fprintf(fp,"%s ",dupName);
325            numOutputsWritten++;
326            st_insert(blifOutputsStTable, (char *)dupName, (char *)1);
327          }
328          else{
329            FREE(dupName);
330          }
331        }
332      }
333    }
334  }
335  if(!combinationalOnly){
336    Hrc_NodeForEachVariable(hnode, gen, varName, var){
337      if(Var_VariableTestIsPO(var) && Var_VariableTestIsPS(var)){
338        name = Var_VariableReadName(var);
339        numVal = Var_VariableReadNumValues(var);
340        numEncBits = IoNumEncBits(numVal);
341        for(j=0; j<numEncBits; j++){
342          dupName = ALLOC(char, strlen(name) + IoNumDigits(numEncBits) + 2);
343          sprintf(dupName, "%s%d", name, j);
344          if(!st_is_member(blifOutputsStTable, (char *)dupName)){
345            fprintf(fp,"%s ",dupName);
346            numOutputsWritten++;
347            st_insert(blifOutputsStTable, (char *)dupName, (char *)1);
348          }
349          else{
350            FREE(dupName);
351          }
352        }
353      }
354    }
355  }
356  fprintf(fp,"\n");
357  return numOutputsWritten;
358}
359
360/**Function********************************************************************
361
362  Synopsis    [Writes out latches to the blif file]
363
364  Description [ ]
365
366  SideEffects []
367
368  SeeAlso     []
369
370******************************************************************************/
371void
372IoWriteLatches(
373   Hrc_Node_t *hnode,
374   FILE *fp,         
375   FILE *encFp,
376   st_table *printedMvsStTable,       
377   st_table *blifOutputsStTable,               
378   st_table *blifInputsStTable,
379   st_table *encOutputsStTable,       
380   st_table *encInputsStTable,
381   int combinationalOnly,
382   int makeLatchIOsPOs,
383   int verbosity
384   )
385{
386  Hrc_Latch_t *latch;
387  st_generator *gen;
388  char *varName, *latchName, *inputVarName, *outputVarName;
389  char *latchInName, *latchOutName, *dupName;
390  Var_Variable_t *outputVar, *inputVar, *var;
391  Tbl_Table_t *resetTable;
392  boolean test;
393  int i, j, index, tempResetValue, resetValue, numEncBits, numVal;
394  st_table *encodedResetVarsStTable;
395
396    mdd_manager *mddMgr;
397    Ntk_Node_t *ntkLatch, *ntkCombInput, *latchResetNtkNode;
398    Ntk_Network_t *network;
399    st_table *tableOfLeaves;
400    array_t *singletonArrayOfRoots, *singletonMvfArray;
401    Mvf_Function_t *mvf;
402    lsGen listGen;
403    Hrc_Manager_t *HrcMgr;
404
405  /* stuff for doing reset table constantness check. Needs to do a "flt -b", "ord"
406     and create a leaves table for mvf computation later.
407  */
408  mddMgr = mdd_init_empty();
409  bdd_dynamic_reordering(mddMgr, BDD_REORDER_SIFT,BDD_REORDER_VERBOSITY_DEFAULT);
410
411  HrcMgr = Hrc_NodeReadManager(hnode);
412  Hrc_ManagerSetCurrentNode(HrcMgr, hnode);
413 
414  network = Ntk_HrcNodeConvertToNetwork(hnode, TRUE, (lsList) NULL);
415  Ord_NetworkOrderVariables(network, Ord_RootsByDefault_c, Ord_NodesByDefault_c, 0, Ord_InputAndLatch_c, Ord_Unassigned_c, (lsList) NULL, 0);
416  tableOfLeaves = st_init_table(st_ptrcmp, st_ptrhash);
417  Ntk_NetworkForEachCombInput(network, listGen, ntkCombInput) {
418    st_insert(tableOfLeaves, (char *)ntkCombInput, (char *) (long) (-1) );
419  }
420
421  encodedResetVarsStTable = st_init_table(strcmp, st_strhash);
422  Hrc_NodeForEachLatch(hnode, gen, latchName, latch){
423    inputVar = Hrc_LatchReadInput(latch);
424    outputVar = Hrc_LatchReadOutput(latch);
425    inputVarName = Var_VariableReadName(inputVar);
426    outputVarName = Var_VariableReadName(outputVar);
427    resetTable = Hrc_LatchReadResetTable(latch);
428   
429    IoMvCheckPrint(encFp,inputVar,printedMvsStTable);
430    /* if makeLatchIOsPOs, then the .mv statement should have "_bufin" appended to the
431       variable names */
432    if(makeLatchIOsPOs){
433      IoMvCheckPrintSpecial(encFp,outputVar,printedMvsStTable);
434    }
435    else{
436      IoMvCheckPrint(encFp,outputVar,printedMvsStTable);
437    }
438         
439   
440    /* Write bin2mv table for input var if needed */
441    /* if makeLatchIOsPOs, then the test for writing the bin2mv table should not include
442       a check to see if the var is a PS. This was previously required, since in hte case
443       where a latchOutput drove a latchInput, we wanted to reinstate both mv latches after
444       read_blif, and so didnt need any enc/dec tables. However, if makeLatchIOsPOs, then we
445       will insert a buffer after latches, so enc/dec tables _will_ be needed.
446    */
447    if(makeLatchIOsPOs){
448      if(!IoVarIsHnodePIO(hnode, inputVar)){
449        if(!st_is_member(encodedResetVarsStTable, (char *)Var_VariableReadName(inputVar))){
450          _IoEncodeWriteVariable(inputVar, encFp, 1, encOutputsStTable, encInputsStTable);
451          st_insert(encodedResetVarsStTable, (char *)Var_VariableReadName(inputVar), (char *)1);
452        }
453      }
454    }
455    else{     
456      if(!IoVarIsHnodePIO(hnode, inputVar) && !Var_VariableTestIsPS(inputVar)){
457        if(!st_is_member(encodedResetVarsStTable, (char *)Var_VariableReadName(inputVar))){
458          _IoEncodeWriteVariable(inputVar, encFp, 1, encOutputsStTable, encInputsStTable);
459          st_insert(encodedResetVarsStTable, (char *)Var_VariableReadName(inputVar), (char *)1);
460        }
461      }
462    }
463   
464    /* Write mv2bin table for output var if needed */
465    /* if makeLatchIOsPOs, then the enc tables should have "_bufin" appended to the
466       names. This is a hack, and I dont insert this name in the table since it does
467       not correspond to a real name in the hrc node.
468    */
469    if(makeLatchIOsPOs){
470      _IoEncodeWriteVariableSpecial(outputVar, encFp, 0, encOutputsStTable, encInputsStTable); 
471    }
472    else{     
473      if(!(Var_VariableReadNumFanoutTables(outputVar) == 0)){
474        if(!st_is_member(encodedResetVarsStTable, (char *)Var_VariableReadName(outputVar))){
475          _IoEncodeWriteVariable(outputVar, encFp, 0, encOutputsStTable, encInputsStTable);   
476          st_insert(encodedResetVarsStTable, (char *)Var_VariableReadName(outputVar), (char *)1);
477        }
478      }
479    }
480    /* Write latch IOs as POs if the "-l" option was used */
481    if(makeLatchIOsPOs){
482      /*
483         first deal with inputVar - check if it has been printed to
484         blif file in binary form, by looking up blifInputsStTable
485      */
486      numVal = Var_VariableReadNumValues(inputVar);
487      numEncBits = IoNumEncBits(numVal);
488      for(j=0; j<numEncBits; j++){
489        dupName = ALLOC(char, strlen(inputVarName) + IoNumDigits(numEncBits) + 2);
490        sprintf(dupName, "%s%d", inputVarName, j);
491        if(!st_is_member(blifInputsStTable, (char *)dupName)){
492          fprintf(fp,".outputs %s\n",dupName);
493          st_insert(blifInputsStTable, (char *)dupName, (char *)1);
494        }
495        else{
496          FREE(dupName);
497        }
498      }
499      /*
500         next deal with outputVar - check if it has been printed to
501         blif file in binary form, by looking up blifOutputsStTable
502      */
503      numVal = Var_VariableReadNumValues(outputVar);
504      numEncBits = IoNumEncBits(numVal);
505      for(j=0; j<numEncBits; j++){
506        dupName = ALLOC(char, strlen(outputVarName) + IoNumDigits(numEncBits) + 2);
507        sprintf(dupName, "%s%d", outputVarName, j);
508        if(!st_is_member(blifOutputsStTable, (char *)dupName)){
509          fprintf(fp,".outputs %s\n",dupName);
510          st_insert(blifOutputsStTable, (char *)dupName, (char *)1);
511        }
512        else{
513          FREE(dupName);
514        }
515      }
516    }
517
518    /* handle reset tables (all cases "wl -c", "wl -l", and "wl")*/
519    Tbl_TableForEachInputVar(resetTable, index, var){
520      if(!IoVarIsHnodePIO(hnode, var)){
521        IoMvCheckPrint(encFp, var,printedMvsStTable);
522      }
523      /* dont encode if (comb&ps) or (makeLatchIOsPOs&ps) */
524      /*      if(!((combinationalOnly || makeLatchIOsPOs) && Var_VariableTestIsPS(var))){ */
525      /* since we insert a buffer after each latch whenever makeLatchIOsPOs, there will
526         be a need for a bin2mv table for the latch output var. Previously, it was assumed
527         that when the mv latch will replace the bin latches, there will be no need for a
528         bin2mv table since the mv latch was directly driving the reset table.
529      */
530      if(!(combinationalOnly && Var_VariableTestIsPS(var))){ 
531        /* if var is a PI or SO, then mv->bin tables exist for it, so dont
532           make bin->mv tables since the mv variable will exist anyway
533        */
534        if(!Var_VariableTestIsPI(var) && !Var_VariableTestIsSO(var)){
535          if(!st_is_member(encodedResetVarsStTable, (char *)Var_VariableReadName(var))){
536            _IoEncodeWriteVariable(var, encFp, 1, encOutputsStTable, encInputsStTable);
537            st_insert(encodedResetVarsStTable, (char *)Var_VariableReadName(var), (char *)1);
538          }
539        }
540      }
541      /*
542         if we are doing "wl -c" and there is a resetTable input var
543         which is also a PS which does not have fanout tbls, then this
544         variable will not be encoded and listed in the blif file.
545         Hence such a variable should not be encoded and listed in teh
546         blif file as a PO, since it will have no driving tables.
547      */
548      if(!(combinationalOnly && Var_VariableTestIsPS(var) && 
549         (Var_VariableReadNumFanoutTables(var) == 0))){
550        /*
551           write encoded vars as outputs after checking that they havent
552           already been written as outputs or inputs to the blif file
553        */
554        varName = Var_VariableReadName(var);
555        numVal = Var_VariableReadNumValues(var);
556        numEncBits = IoNumEncBits(numVal);
557        for(j=0; j<numEncBits; j++){
558          dupName = ALLOC(char, strlen(varName) + IoNumDigits(numEncBits) + 2);
559          sprintf(dupName, "%s%d", varName, j);
560          if(!st_is_member(blifInputsStTable, (char *)dupName) && !st_is_member(blifOutputsStTable, (char *)dupName)){
561            fprintf(fp,".outputs %s\n",dupName);
562            st_insert(blifOutputsStTable, (char *)dupName, (char *)1);
563          }
564          else{
565            FREE(dupName);
566          }
567        }
568      }
569    }
570  }
571
572  /* write latch stmts to blif file */
573  Hrc_NodeForEachLatch(hnode, gen, latchName, latch){
574    inputVar = Hrc_LatchReadInput(latch);
575    outputVar = Hrc_LatchReadOutput(latch);
576    inputVarName = Var_VariableReadName(inputVar);
577    outputVarName = Var_VariableReadName(outputVar);
578    resetTable = Hrc_LatchReadResetTable(latch);
579    /* write out mv latches to enc file, they are needed even if we are
580       writing only combinational part of the network */
581    /* if makeLatchIOsPOs, then append "_bufin" to the output name, since latch
582       outputs are buffered. Also, reset table should reflect this new name.
583    */
584    if(makeLatchIOsPOs){
585      (void)fprintf(encFp, ".latch %s %s_bufin \n", inputVarName, outputVarName);           
586      Tbl_TableWriteBlifMvToFileSpecial(resetTable, 1, encFp);
587    }
588    else{
589      (void)fprintf(encFp, ".latch %s %s \n", inputVarName, outputVarName);         
590      Tbl_TableWriteBlifMvToFile(resetTable, 1, encFp);
591    }     
592   
593    /* determine value of reset table - whether const, or not */
594    if(!combinationalOnly){     
595      ntkLatch = Ntk_NetworkFindNodeByName(network, latchName);
596      assert(Ntk_NodeTestIsLatch(ntkLatch));
597      latchResetNtkNode = Ntk_LatchReadInitialInput(ntkLatch);
598      singletonArrayOfRoots = array_alloc(Ntk_Node_t *, 0);
599      array_insert_last(Ntk_Node_t *, singletonArrayOfRoots, latchResetNtkNode);
600      singletonMvfArray = Ntm_NetworkBuildMvfs(network, singletonArrayOfRoots, tableOfLeaves, NIL(mdd_t));
601      mvf = array_fetch(Mvf_Function_t *, singletonMvfArray, 0);
602      array_free(singletonMvfArray);
603      array_free(singletonArrayOfRoots);
604      test = Mvf_FunctionTestIsConstant(mvf, &resetValue);
605      Mvf_FunctionFree(mvf);
606      if(verbosity > 1){
607        (void)fprintf(stdout, "Reset table is: \n");               
608        Tbl_TableWriteBlifMvToFile(resetTable, 0, stdout);
609      }
610      if(verbosity > 0){
611        (void)fprintf(stdout, "Reset table constantness test result was %d\n", test);         
612      }
613      if(test == FALSE){
614        resetValue = VIS_INFINITY;
615      }
616      if(verbosity > 0){
617        fprintf(stdout, "Reset value %d\n", resetValue);
618      }
619     
620      /* write latches to blif file */
621      numEncBits = IoNumEncBits(Var_VariableReadNumValues(inputVar));
622      if(resetValue == VIS_INFINITY){
623        for(i = 0; i < numEncBits; i++){
624          resetValue = 2;
625          latchInName = ALLOC(char, strlen(inputVarName) + IoNumDigits(numEncBits) + 2);
626          latchOutName = ALLOC(char, strlen(outputVarName) + IoNumDigits(numEncBits) + 10); 
627          sprintf(latchInName, "%s%d", inputVarName, i);
628          /* if makelatchIOsPOs, then latch drives buffer input, and buffer needs to be
629             be written to the blif file too
630          */
631          if(makeLatchIOsPOs){
632            sprintf(latchOutName, "%s_bufin%d", outputVarName, i);
633          }
634          else{
635            sprintf(latchOutName, "%s%d", outputVarName, i);
636          }
637          (void)fprintf(fp, ".latch %s %s %d\n", latchInName, latchOutName, resetValue);
638          if(makeLatchIOsPOs){
639            (void)fprintf(fp, ".names %s %s%d\n", latchOutName, outputVarName, i);
640            (void)fprintf(fp, "1 1\n");
641          }
642          FREE(latchInName);
643          FREE(latchOutName);
644        }
645      }
646      else{
647        tempResetValue = resetValue;
648        for(i = numEncBits - 1; i >= 0; i--){
649          if(((int)(tempResetValue / pow((double) 2, (double) i))) == 1){
650            resetValue = 1;
651            tempResetValue = tempResetValue - (int)pow((double)2,(double)i);       
652          }
653          else{
654            resetValue = 0;
655          }
656          latchInName = ALLOC(char, strlen(inputVarName) + IoNumDigits(numEncBits) + 2);
657          latchOutName = ALLOC(char, strlen(outputVarName) + IoNumDigits(numEncBits) + 10); 
658          sprintf(latchInName, "%s%d", inputVarName, i);
659          /* if makelatchIOsPOs, then latch drives buffer input, and buffer needs to be
660             be written to the blif file too.
661          */
662          if(makeLatchIOsPOs){
663            sprintf(latchOutName, "%s_bufin%d", outputVarName, i);
664          }
665          else{
666            sprintf(latchOutName, "%s%d", outputVarName, i);
667          }         
668          (void)fprintf(fp, ".latch %s %s %d\n", latchInName, latchOutName, resetValue);
669          if(makeLatchIOsPOs){
670            (void)fprintf(fp, ".names %s %s%d\n", latchOutName, outputVarName, i);
671            (void)fprintf(fp, "1 1\n");
672          }
673          FREE(latchInName);
674          FREE(latchOutName);
675        }
676      }
677    }
678  }
679  st_free_table(encodedResetVarsStTable);
680  st_free_table(tableOfLeaves);
681  Ntk_NetworkFree(network);
682  mdd_quit(mddMgr);
683}
684
685
686/**Function********************************************************************
687
688  Synopsis    [Prints the .mv declaration of a variable, to file, if it is not in the
689               st_table variables already printed]
690
691  Description []
692
693  SideEffects []
694
695  SeeAlso     []
696
697******************************************************************************/
698void
699IoMvCheckPrint(
700   FILE *fp, 
701   Var_Variable_t *var,
702   st_table *printedMvsStTable
703  )
704{
705    char *varname, *tmpName;
706
707    tmpName = Var_VariableReadName(var);
708    varname = ALLOC(char, strlen(tmpName) + 2);
709    sprintf(varname, "%s", tmpName);
710    if(!st_is_member(printedMvsStTable, (char *)varname)){
711        st_insert(printedMvsStTable, (char *)varname, (char *)1);
712        IoMvPrint(fp, var);
713    }
714    else{
715        FREE(varname);
716    }
717}
718
719/**Function********************************************************************
720
721  Synopsis    [Prints the .mv declaration of a variable, to file, if it is not in the
722               st_table variables already printed. Appends a special string "_bufin"
723               at the end of the name.]
724
725  Description []
726
727  SideEffects []
728
729  SeeAlso     []
730
731******************************************************************************/
732void
733IoMvCheckPrintSpecial(
734   FILE *fp, 
735   Var_Variable_t *var,
736   st_table *printedMvsStTable
737  )
738{
739    char *varname, *tmpName;
740
741    tmpName = Var_VariableReadName(var);
742    varname = ALLOC(char, strlen(tmpName) + 10);
743    sprintf(varname, "%s_bufin", tmpName);
744    if(!st_is_member(printedMvsStTable, (char *)varname)){
745        st_insert(printedMvsStTable, (char *)varname, (char *)1);
746        IoMvPrintSpecial(fp, var);
747    }
748    else{
749        FREE(varname);
750    }
751}
752
753   
754/**Function********************************************************************
755
756  Synopsis    [Writes a blifmv value, in expanded form, into binTable]
757
758  Description [Writes the binary value corresponding to "value" in the binTable
759               starting from the rootRow, rootCol entry. The values are repeated
760               "entryRepetitionCount" times]
761
762  SideEffects []
763
764  SeeAlso     []
765
766******************************************************************************/
767 int
768IoWriteExpandedValueToBinTable( 
769   Tbl_Table_t *binTable,
770   int rootRow,
771   int rootCol,
772   IoBinRangeEntry_t *binRangeEntry,
773   int entryRepetitionCount,
774   int numBits,
775   int output
776   )
777{
778    int i, j, row, value, numDash, end;
779    Tbl_Entry_t *entry;
780
781    numDash = IoLog(binRangeEntry->runLength);
782    end = IoLog(binRangeEntry->skipLength);
783    value = binRangeEntry->startValue;
784    for(j = numBits - 1; j >= 0; j--){
785      row = rootRow;
786        if((j < end) || (j >= numDash + end)){
787            if(((int)(value / pow((double) 2, (double) j))) == 1){
788                for(i = 0; i < entryRepetitionCount; i++){
789                    entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
790                    Tbl_EntrySetValue(entry, 1, 1);
791                    Tbl_TableSetEntry(binTable, entry, row++, rootCol+j, output);
792                }
793                value -= (int)pow((double)2,(double)j);
794            }
795            else{
796                for(i = 0; i < entryRepetitionCount; i++){
797                    entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
798                    Tbl_EntrySetValue(entry, 0, 0);
799                    Tbl_TableSetEntry(binTable, entry, row++, rootCol+j, output);
800                }
801            }
802        }
803        else{
804            for(i = 0; i < entryRepetitionCount; i++){
805                entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
806                Tbl_EntrySetValue(entry, 0, 1);
807                Tbl_TableSetEntry(binTable, entry, row++, rootCol+j, output);
808            }
809        }
810    }
811    return 0;
812}
813
814
815/**Function********************************************************************
816
817  Synopsis    [Writes out tables in binTblArray to a named blif file]
818
819  Description [Writes out binary tables in the binTblArray to
820               blif file pointed to by fp]
821
822  SideEffects []
823
824  SeeAlso     []
825
826******************************************************************************/
827void
828IoWriteBinTablesToFile( 
829   IoBlifInfo_t *blifInfo                             
830   )
831{
832    int i, colnum, rownum, value, hasZeroRows;
833    Tbl_Table_t *table;
834    Var_Variable_t *outputVar, *dupOutputVar;
835    char *outputVarName;
836    Tbl_Entry_t *entry;
837    Tbl_Range_t *range;
838    lsGen gen;
839
840    for(i = 0; i < array_n(blifInfo->binTblArray); i++){
841        table = array_fetch(Tbl_Table_t *, blifInfo->binTblArray, i);
842   /* if table has zero rows, print it as ".names <var>" */
843        hasZeroRows = 1;
844        Tbl_TableForEachOutputEntry(table, colnum, rownum, entry){
845            Tbl_EntryForEachValue(entry, value, gen, range){
846                if(value == 1){
847                    hasZeroRows = 0;
848                }
849            }
850        }
851        if(hasZeroRows){
852            outputVar = Tbl_TableReadIndexVar(table, 0, 1);
853            table = Tbl_TableAlloc();
854            outputVarName = Var_VariableReadName(outputVar);
855            dupOutputVar = Var_VariableAlloc(NIL(Hrc_Node_t), outputVarName);
856            (void)Tbl_TableAddColumn(table, dupOutputVar, 1);
857            Tbl_TableWriteBlifToFile(table, blifInfo->BlifFp); 
858            Tbl_TableFree(table);
859            Var_VariableFree(dupOutputVar);
860        }
861        else{
862            Tbl_TableWriteBlifToFile(table, blifInfo->BlifFp); 
863        }
864    }
865}
866
867
868/*---------------------------------------------------------------------------*/
869/* Definition of static functions                                            */
870/*---------------------------------------------------------------------------*/
871
872
873/**Function********************************************************************
874
875  Synopsis    [Encodes individual variable based on its ranges, and writes to the file called
876               "encoding"]
877
878  Description []
879
880  SideEffects [Program state is not changed]
881
882  SeeAlso     []
883
884******************************************************************************/
885static void
886_IoEncodeWriteVariable(
887   Var_Variable_t *var,
888   FILE *encFp,               
889   int varIsOutput,
890   st_table *encOutputsStTable, 
891   st_table *encInputsStTable
892   )
893{
894    int j, i, tempI, range, numEncBits, rownum, varIsInput;
895    Tbl_Table_t *encTable;
896    char *varname, *dupName;
897    Var_Variable_t *encVar;
898    Tbl_Entry_t *entry;
899    array_t *varArray;
900
901    if(varIsOutput == 1){
902        varIsInput = 0;
903    }
904    else{
905        varIsInput = 1;
906    }
907
908    if(varIsOutput){
909        if(st_is_member(encOutputsStTable, (char *)var)){
910            return;
911        }
912        else{
913            st_insert(encOutputsStTable, (char *) var, (char *) 1);
914        }
915    }
916    else{
917        if(st_is_member(encInputsStTable, (char *)var)){
918            return;
919        }
920        else{
921            st_insert(encInputsStTable, (char *) var, (char *) 1);
922        }
923    }
924           
925
926        /* declare encoding input vars based on range. These are associated
927           with their encoding table. These have names <var>0, <var>1, ...  */
928
929    varArray = array_alloc(Var_Variable_t *, 0);
930    range = Var_VariableReadNumValues(var);
931    numEncBits = IoNumEncBits(range);
932    /* create encoding table */
933    encTable = Tbl_TableAlloc();
934    varname = Var_VariableReadName(var);
935    for(i=0; i<numEncBits; i++){
936        dupName = ALLOC(char, strlen(varname) + IoNumDigits(numEncBits) + 2);
937        sprintf(dupName, "%s%d", varname, i);
938        encVar = Var_VariableAlloc(NIL(Hrc_Node_t), dupName);
939        FREE(dupName);
940        array_insert_last(Var_Variable_t *, varArray, encVar);
941        (void) Tbl_TableAddColumn(encTable, encVar, varIsInput);
942    }
943
944        /* declare output var for the encoding table. It is called <var>     */
945
946    (void) Tbl_TableAddColumn(encTable, var, varIsOutput);
947   
948        /* fill in entries of the variable encoding table. Assign codes based on
949           the variable's index. Nothing fancy here...                        */
950
951    for(i=0; i<range; i++){   
952        tempI = i;
953        rownum = Tbl_TableAddRow(encTable);
954        for(j = numEncBits - 1; j >= 0; j--){
955            if(((int)(tempI / pow((double) 2, (double) j))) == 1){
956                entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
957                Tbl_EntrySetValue(entry, 1, 1);
958                Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
959                tempI = tempI - (int)pow((double)2,(double)j);
960            }
961            else{
962                entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
963                Tbl_EntrySetValue(entry, 0, 0);
964                Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
965            }
966        }
967        entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
968        Tbl_EntrySetValue(entry, i, i);
969        Tbl_TableSetEntry(encTable, entry, rownum, 0, varIsOutput);
970    }
971    /* make sure not inc specced if var is output */
972    if(varIsOutput){
973        for(i = range; i < ((int) pow((double)2, (double)numEncBits)); i++){
974            tempI = i;
975            rownum = Tbl_TableAddRow(encTable);
976            for(j = numEncBits - 1; j >= 0; j--){
977                if(((int)(tempI / pow((double) 2, (double) j))) == 1){
978                    entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
979                    Tbl_EntrySetValue(entry, 1, 1);
980                    Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
981                    tempI = tempI - (int)pow((double)2,(double)j);
982                }
983                else{
984                    entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
985                    Tbl_EntrySetValue(entry, 0, 0);
986                    Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
987                }
988            }
989            entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
990            Tbl_EntrySetValue(entry, 0, 0);
991            Tbl_TableSetEntry(encTable, entry, rownum, 0, varIsOutput);
992        }
993    }
994   
995   
996    /* store the var, var number, and its table in the encTblArray. */
997   
998    Tbl_TableWriteBlifMvToFile(encTable, 0, encFp);
999    Tbl_TableFree(encTable);
1000
1001    for(i=0; i < array_n(varArray); i++){
1002        Var_VariableFree(array_fetch(Var_Variable_t *, varArray, i));
1003    }
1004    array_free(varArray);
1005
1006}
1007
1008
1009
1010/**Function********************************************************************
1011
1012  Synopsis    [Encodes individual variable based on its ranges. Variable name has
1013               the string "_bufin" appended to it.]
1014
1015  Description []
1016
1017  SideEffects [Program state is not changed]
1018
1019  SeeAlso     []
1020
1021******************************************************************************/
1022static void
1023_IoEncodeWriteVariableSpecial(
1024   Var_Variable_t *var,
1025   FILE *encFp,               
1026   int varIsOutput,
1027   st_table *encOutputsStTable, 
1028   st_table *encInputsStTable
1029   )
1030{
1031    int j, i, tempI, range, numEncBits, rownum, varIsInput;
1032    Tbl_Table_t *encTable;
1033    char *varname, *dupName;
1034    Var_Variable_t *encVar, *outVar;
1035    Tbl_Entry_t *entry;
1036    array_t *varArray, *symValArray;
1037
1038    if(varIsOutput == 1){
1039        varIsInput = 0;
1040    }
1041    else{
1042        varIsInput = 1;
1043    }
1044
1045    if(varIsOutput){
1046        if(st_is_member(encOutputsStTable, (char *)var)){
1047            return;
1048        }
1049        else{
1050            st_insert(encOutputsStTable, (char *) var, (char *) 1);
1051        }
1052    }
1053    else{
1054        if(st_is_member(encInputsStTable, (char *)var)){
1055            return;
1056        }
1057        else{
1058            st_insert(encInputsStTable, (char *) var, (char *) 1);
1059        }
1060    }
1061           
1062
1063        /* declare encoding input vars based on range. These are associated
1064           with their encoding table. These have names <var>0, <var>1, ...  */
1065
1066    varArray = array_alloc(Var_Variable_t *, 0);
1067    range = Var_VariableReadNumValues(var);
1068    numEncBits = IoNumEncBits(range);
1069    /* create encoding table */
1070    encTable = Tbl_TableAlloc();
1071    varname = Var_VariableReadName(var);
1072    for(i=0; i<numEncBits; i++){
1073        dupName = ALLOC(char, strlen(varname) + IoNumDigits(numEncBits) + 10);
1074        sprintf(dupName, "%s_bufin%d", varname, i);
1075        encVar = Var_VariableAlloc(NIL(Hrc_Node_t), dupName);
1076        FREE(dupName);
1077        array_insert_last(Var_Variable_t *, varArray, encVar);
1078        (void) Tbl_TableAddColumn(encTable, encVar, varIsInput);
1079    }
1080
1081        /* declare output var for the encoding table. It is called <var>_bufin     */
1082
1083    varname = Var_VariableReadName(var);
1084    dupName = ALLOC(char, strlen(varname) + 10);   
1085    sprintf(dupName, "%s_bufin", varname);
1086    outVar = Var_VariableAlloc(NIL(Hrc_Node_t), dupName);
1087    array_insert_last(Var_Variable_t *, varArray, outVar);
1088    FREE(dupName);
1089    if(Var_VariableTestIsSymbolic(var)){
1090      symValArray = array_alloc(char *, 0);
1091      for(i = 0; i < range; i++){
1092        array_insert_last(char *, symValArray, Var_VariableReadSymbolicValueFromIndex(var, i));
1093      }
1094      Var_VariableAddRangeInfo(outVar, range, symValArray);
1095      array_free(symValArray);
1096    }
1097    else{
1098      if(range > 2){
1099        Var_VariableExpandRange(outVar, range);
1100      }
1101    }
1102    (void) Tbl_TableAddColumn(encTable, outVar, varIsOutput);
1103
1104
1105        /* fill in entries of the variable encoding table. Assign codes based on
1106           the variable's index. Nothing fancy here...                        */
1107
1108    for(i=0; i<range; i++){   
1109        tempI = i;
1110        rownum = Tbl_TableAddRow(encTable);
1111        for(j = numEncBits - 1; j >= 0; j--){
1112            if(((int)(tempI / pow((double) 2, (double) j))) == 1){
1113                entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
1114                Tbl_EntrySetValue(entry, 1, 1);
1115                Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
1116                tempI = tempI - (int)pow((double)2,(double)j);
1117            }
1118            else{
1119                entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
1120                Tbl_EntrySetValue(entry, 0, 0);
1121                Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
1122            }
1123        }
1124        entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
1125        Tbl_EntrySetValue(entry, i, i);
1126        Tbl_TableSetEntry(encTable, entry, rownum, 0, varIsOutput);
1127    }
1128    /* make sure not inc specced if var is output */
1129    if(varIsOutput){
1130        for(i = range; i < ((int) pow((double)2, (double)numEncBits)); i++){
1131            tempI = i;
1132            rownum = Tbl_TableAddRow(encTable);
1133            for(j = numEncBits - 1; j >= 0; j--){
1134                if(((int)(tempI / pow((double) 2, (double) j))) == 1){
1135                    entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
1136                    Tbl_EntrySetValue(entry, 1, 1);
1137                    Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
1138                    tempI = tempI - (int)pow((double)2,(double)j);
1139                }
1140                else{
1141                    entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
1142                    Tbl_EntrySetValue(entry, 0, 0);
1143                    Tbl_TableSetEntry(encTable, entry, rownum, j, varIsInput);
1144                }
1145            }
1146            entry = Tbl_EntryAlloc(Tbl_EntryNormal_c);
1147            Tbl_EntrySetValue(entry, 0, 0);
1148            Tbl_TableSetEntry(encTable, entry, rownum, 0, varIsOutput);
1149        }
1150    }
1151   
1152   
1153    /* store the var, var number, and its table in the encTblArray. */
1154   
1155    Tbl_TableWriteBlifMvToFile(encTable, 0, encFp);
1156    Tbl_TableFree(encTable);
1157
1158    for(i=0; i < array_n(varArray); i++){
1159        Var_VariableFree(array_fetch(Var_Variable_t *, varArray, i));
1160    }
1161    array_free(varArray);
1162
1163}
Note: See TracBrowser for help on using the repository browser.