source: vis_dev/vis-2.3/src/sim/simIo.c @ 99

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

vis2.3

File size: 32.1 KB
RevLine 
[14]1/**CFile***********************************************************************
2
3  FileName    [simIo.c]
4
5  PackageName [sim]
6
7  Synopsis    [Routines to read and write simulation vectors.]
8
9  Author      [Shaker Sarwary, Tom Shiple and Rajeev Ranjan]
10
11  Copyright   [Copyright (c) 1994-1996 The Regents of the Univ. of California.
12  All rights reserved.
13
14  Permission is hereby granted, without written agreement and without license
15  or royalty fees, to use, copy, modify, and distribute this software and its
16  documentation for any purpose, provided that the above copyright notice and
17  the following two paragraphs appear in all copies of this software.
18
19  IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
20  DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
21  OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
22  CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
24  THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
25  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
26  FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN
27  "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE
28  MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.]
29
30******************************************************************************/
31#include "simInt.h"
32
33static char rcsid[] UNUSED = "$Id: simIo.c,v 1.5 2005/05/10 15:50:43 hhkim Exp $";
34
35/*---------------------------------------------------------------------------*/
36/* Constant declarations                                                     */
37/*---------------------------------------------------------------------------*/
38
39/*
40 * Maximum permissible length of a line in the simulation file.
41 */
42#define MAX_LINE_LENGTH 500000
43
44
45/**AutomaticStart*************************************************************/
46
47/*---------------------------------------------------------------------------*/
48/* Static function prototypes                                                */
49/*---------------------------------------------------------------------------*/
50
51static array_t * SimObtainInputsArray(Sim_Sim_t * sim);
52static void FreeArrays(array_t *array1, array_t *array2, array_t *array3, array_t *array4);
53static array_t * BufferBuildInputsNodeArray(char * buffer, Ntk_Network_t * network);
54static array_t * BufferBuildLatchesNodeArray(char * buffer, Ntk_Network_t * network);
55static array_t * BufferBuildOutputsNodeArray(char * buffer, Ntk_Network_t * network);
56static array_t * BufferBuildValuesArray(char * buffer, array_t * nodesArray);
57static void SimAddVector(Sim_Sim_t * sim, array_t * vector);
58static void BufferSkipWhiteSpace(char * buffer, int * position);
59static char * BufferObtainStringAtPosition(char * buffer, int * position);
60static void PrintValue(array_t *nodesArray, array_t *vector, int vectorIndex, int strSize, FILE *file);
61
62/**AutomaticEnd***************************************************************/
63
64
65/*---------------------------------------------------------------------------*/
66/* Definition of exported functions                                          */
67/*---------------------------------------------------------------------------*/
68
69/**Function********************************************************************
70
71  Synopsis    [Print the simulation vectors contained in a SimSimStruct.]
72
73  Description [Print the simulation vectors contained in a SimSimStruct. If
74  printMode is 0, then only vectors are printed, else the header is also
75  printed(.inputs, .outputs ...). printInputsFlag,
76  printPseudoInputsFlag, printOutputsFlag, and printStatesFlag control
77  the printing of primary inputs, pseudo inputs, primary outputs and
78  state variables respectively. A value of 1 of these flags indicate
79  printing is enabled, and value 0 indicates otherwise.  This function writes
80  warnings into error_string. The printed file is accepted as input file in sim.]
81
82  SideEffects []
83
84******************************************************************************/
85void
86Sim_SimPrint(
87  Sim_Sim_t       * sim,
88  FILE            * of,
89  boolean         printMode,
90  int             printInputsFlag,
91  int             printOutputsFlag,
92  int             printPseudoInputsFlag,
93  int             printStatesFlag
94  )
95
96{
97  int             i, j;
98  char           *str;
99  array_t        *vector = NIL(array_t);
100  array_t        *formatArray;
101  Ntk_Node_t     *node;
102  Var_Variable_t *var;
103  int             index;
104  int             strSize     = 0;
105  int             numNodes    = array_n(sim->nodesArray); 
106  int             inputWidth  = sim->currentStateHead;
107
108  if(sim->verbose) {
109    (void) printf("Printing %d vectors...\n", array_n(sim->vectorArray));
110  }
111 
112  formatArray = SimSimInitDataFormat(sim);
113 
114  if (printMode) {
115    (void) fprintf(of, "# %s\n", Vm_VisReadVersion());
116    (void) fprintf(of, "# Network: %s\n", Ntk_NetworkReadName(sim->network));
117
118    if (sim->inputFile != NIL(char)) {
119      (void) fprintf(of, "# Input Vectors File: %s\n", sim->inputFile);
120    }
121    else {
122      (void) fprintf(of, "# Simulation vectors have been randomly generated\n");
123    }
124    (void) fprintf(of, "\n\n");
125    (void) fprintf(of, ".inputs  ");
126    for (i = 0; i < inputWidth; i++) {
127      node = array_fetch(Ntk_Node_t *, sim->nodesArray, i);
128      (void) fprintf(of, "%s ", Ntk_NodeReadName(node));
129    }
130    (void) fprintf(of, "\n");
131    (void) fprintf(of, ".latches ");
132    for (i = sim->currentStateHead; i < sim->internalPartitionHead; i++) {
133      node = array_fetch(Ntk_Node_t *, sim->nodesArray, i);
134      (void) fprintf(of, "%s ", Ntk_NodeReadName(node));
135    }
136    (void) fprintf(of, "\n");
137
138    (void) fprintf(of, ".outputs ");
139    for (i = sim->outputHead; i < numNodes; i++) {
140      node = array_fetch(Ntk_Node_t *, sim->nodesArray, i);
141      (void) fprintf(of, "%s ", Ntk_NodeReadName(node));
142    }
143    (void) fprintf(of, "\n");
144
145    /* Reset State is the current state of the first vector */
146    (void) fprintf(of, ".initial ");
147    vector = array_fetch(array_t *, sim->vectorArray, 0);
148    for (i = sim->currentStateHead; i < sim->internalPartitionHead; i++) {
149      if(i >= array_n(vector)) {/* If currentState is not specified '*' is printed */
150        (void) fprintf(of, "* ");
151      }
152      else {
153        node = array_fetch(Ntk_Node_t *, sim->nodesArray, i);
154        var = Ntk_NodeReadVariable(node);
155        index = array_fetch(int, vector, i);
156        if (Var_VariableTestIsSymbolic(var)) {
157          (void) fprintf(of, "%s ", Var_VariableReadSymbolicValueFromIndex(var, index));
158        }
159        else { /* Binary or enumerative type */
160          str = SimInteger2ASCII(index);
161          (void) fprintf(of, "%s ", str);
162          FREE(str);
163        }
164      }
165    }
166   
167    (void) fprintf(of, "\n\n.start_vectors");
168
169    (void) fprintf(of, "\n\n");
170
171    /*
172     * Print the order of variables for which values
173     * are printed in the next lines.
174     */
175   
176    (void) fprintf(of, "# ");
177    /*
178     * If either printInputsFlag or printPseudoInputsFlag is zero, we
179     * cannot use the output as the input for simulation. Print a
180     * warning message regarding that.
181     */
182    if ((printInputsFlag == 0) || (printPseudoInputsFlag == 0)){
183      (void) fprintf(vis_stderr,"Warning - print flag of some inputs is set to zero.\n");
184      (void) fprintf(vis_stderr,"Hence the output file you specified cannot be used as an input\n");
185      (void) fprintf(vis_stderr,"file for a subsequent simulation run.\n");
186    }
187     
188    if (printInputsFlag || printPseudoInputsFlag){
189      for (i = 0; i < inputWidth; i++) {
190        node = array_fetch(Ntk_Node_t *, sim->nodesArray, i);
191        if (Ntk_NodeTestIsPrimaryInput(node)){
192          if (printInputsFlag){
193            (void) fprintf(of, "%s ", Ntk_NodeReadName(node));
194          }
195        }
196        else{
197          if (printPseudoInputsFlag){
198            (void) fprintf(of, "%s ", Ntk_NodeReadName(node));
199          }
200        }
201      }
202      (void) fprintf(of, "; ");
203    }
204   
205    if (printStatesFlag) {
206      for (i = sim->currentStateHead; i < sim->internalPartitionHead; i++) {
207        node = array_fetch(Ntk_Node_t *, sim->nodesArray, i);
208        (void) fprintf(of, "%s ", Ntk_NodeReadName(node));
209      }
210      (void) fprintf(of, "; ");     
211    }
212    if (printOutputsFlag){
213      for (i = sim->outputHead; i < numNodes; i++) {
214        node = array_fetch(Ntk_Node_t *, sim->nodesArray, i);
215        (void) fprintf(of, "%s ", Ntk_NodeReadName(node));
216      }
217      (void) fprintf(of, "\n\n");
218    }
219  }
220 
221  for (i = 0; i < array_n(sim->vectorArray); i++) {
222    vector = array_fetch(array_t *, sim->vectorArray, i);
223    if ((printInputsFlag) || (printPseudoInputsFlag)){
224      for (j = 0; j < sim->currentStateHead; j++) {
225        strSize = array_fetch(int, formatArray, j);
226        node = array_fetch(Ntk_Node_t *, sim->nodesArray, j);
227        if (Ntk_NodeTestIsPrimaryInput(node)){
228          if(printInputsFlag){
229            PrintValue(sim->nodesArray, vector, j, strSize, of);
230          }
231        }
232        else {
233          if (printPseudoInputsFlag){
234            PrintValue(sim->nodesArray, vector, j, strSize, of);
235          }
236        }
237      }
238    }
239    if (printStatesFlag){
240      (void) fprintf(of,"; ");
241      for (j = sim->currentStateHead; j < sim->internalPartitionHead; j++){
242        strSize = array_fetch(int, formatArray, j);
243        node = array_fetch(Ntk_Node_t *, sim->nodesArray, j);
244        PrintValue(sim->nodesArray, vector, j, strSize, of);
245      }
246    }
247    if (printOutputsFlag){
248      (void) fprintf(of,"; ");
249      for (j = sim->outputHead; j < numNodes; j++){
250        strSize = array_fetch(int, formatArray, j);
251        node = array_fetch(Ntk_Node_t *, sim->nodesArray, j);
252        PrintValue(sim->nodesArray, vector, j, strSize, of);
253      }
254    }
255    (void) fprintf(of, "\n");
256  }
257  if (printStatesFlag){
258    /*
259     * Need to print the final state on a separate line.
260     */
261    (void) fprintf(of,"# Final State : ");
262    for (j = sim->currentStateHead; j < sim->internalPartitionHead; j++){
263      strSize = array_fetch(int, formatArray, j);
264      node = array_fetch(Ntk_Node_t *, sim->nodesArray, j);
265      PrintValue(sim->nodesArray, vector, j, strSize, of);
266    }
267    (void) fprintf(of, "\n");
268  }
269  array_free(formatArray);
270}
271
272
273
274/**Function********************************************************************
275
276  Synopsis [Parses the header of the simulation vectors file containing
277  declarations, and builds a SimSimStruct.]
278
279  Description [Parses the header of the simulation vectors file containing
280  declarations, and builds a SimSimStruct. nodeToMvfTable providing MDDs of
281  primary outputs and next-state functions is also built. verbose is here for
282  initialization of sim structure. The header of a simulation-vectors file
283  contains .inputs, .latches, .outputs, and .initial fields. If a variable is
284  found for which there doesn't exist a corresponding node in the network, or
285  a value is found that does not belong to the domain of its specific
286  variable, then an error message is written in error_string, the allocated
287  memory is freed, and the function returns NULL. The simulation file must
288  contain each category of declaration in a line(Two ".inputs" is not allowed
289  in the same file). initial-state declaration must be written after the
290  latches declaration. The function returns the initialized sim structure.]
291
292  SideEffects []
293
294******************************************************************************/
295Sim_Sim_t *
296Sim_FileParseDeclaration(
297  Ntk_Network_t * network,
298  FILE          * fp,
299  char          * inputFile,
300  boolean         verbose)
301{
302  int            i;
303  Ntk_Node_t    *node;
304  char           buffer[MAX_LINE_LENGTH];
305  char          *buffer2;
306  int            currentStateHead;
307  int            internalPartitionHead;
308  int            nextStateHead;
309  int            outputHead;
310  st_table      *nodeToMvfTable;
311  array_t       *nodesArray;
312  int            lineNumber              = 0;
313  array_t       *inputsArray             = NIL(array_t);
314  array_t       *latchesArray            = NIL(array_t);
315  array_t       *internalPartitionArray  = NIL(array_t);
316  array_t       *outputsArray            = NIL(array_t);
317  array_t       *initState               = NIL(array_t);
318  Sim_Sim_t     *sim                     = NIL(Sim_Sim_t);
319  graph_t       *partition;
320  vertex_t      *vertex;
321  array_t       *dfsarray;
322
323  internalPartitionArray = array_alloc(Ntk_Node_t *, 0);
324
325  /* Add internal partition nodes */
326  partition = Part_NetworkReadPartition(network);
327  dfsarray = g_dfs(partition);
328  for(i=0; i< array_n(dfsarray); i++){
329    vertex = array_fetch(vertex_t *, dfsarray, i);
330    node = Ntk_NetworkFindNodeByName(network, Part_VertexReadName(vertex));
331    if(!(Ntk_NodeTestIsCombInput(node) || Ntk_NodeTestIsCombOutput(node))){
332      array_insert_last(Ntk_Node_t *, internalPartitionArray, node);
333    }
334  }
335  array_free(dfsarray);
336
337  while (fgets(buffer, MAX_LINE_LENGTH -1, fp) != NULL) {
338    int position = 0;
339    lineNumber++;
340
341    /* Every line must end by '\n' */
342    if (buffer[strlen(buffer) -1] != '\n') {
343      SimAppendErrorMsg("Simulate: Line ",
344                       SimInteger2ASCII(lineNumber), "istoolong!\n");
345      FreeArrays(inputsArray, latchesArray, outputsArray, internalPartitionArray);
346      return(sim);
347    }
348   
349 
350    /* Eliminate spaces */
351    BufferSkipWhiteSpace(buffer, &position);
352    /* buffer2 will contain buffer without space in the begining */
353    buffer2 = buffer + position;
354    /* Avoid comment and empty lines */
355    if (buffer[position] != '#' && buffer[position] != '\n') {
356      if (!strncmp(buffer2, ".inputs", 7)) {
357        inputsArray = BufferBuildInputsNodeArray(buffer2 + 7, network);
358        if (inputsArray == NIL(array_t)) {
359          SimAppendErrorMsg("Simulate: Error line ",
360                           SimInteger2ASCII(lineNumber), ".\n");
361          FreeArrays(inputsArray, latchesArray, outputsArray, internalPartitionArray);
362          return(sim);
363        }
364      }
365      else if (!strncmp(buffer2, ".latches", 8)) {
366        latchesArray = BufferBuildLatchesNodeArray(buffer2 + 8, network);
367        if (latchesArray == NIL(array_t)) {
368          SimAppendErrorMsg("Simulate: Error line ",
369                           SimInteger2ASCII(lineNumber), ".\n");
370          FreeArrays(inputsArray, latchesArray, outputsArray, internalPartitionArray);
371          return(sim);
372        }
373      }
374      else if (!strncmp(buffer2, ".outputs", 8)) {
375        outputsArray = BufferBuildOutputsNodeArray(buffer2 + 8, network);
376        if (outputsArray == NIL(array_t)) {
377          SimAppendErrorMsg("Simulate: Error line ", SimInteger2ASCII(lineNumber),
378                           ".\n");
379          FreeArrays(inputsArray, latchesArray, outputsArray, internalPartitionArray);
380          return(sim);
381        }
382      }
383      else if (!strncmp(buffer2, ".initial", 8)) {
384        /* Error if latches are not  already read before initial-state */
385        if (latchesArray == NIL(array_t)) {
386          error_append("Simulate: Latches must be declared before initial state declaration.\n");
387          FreeArrays(inputsArray, latchesArray, outputsArray, internalPartitionArray);
388          return(sim);
389        }
390        initState = BufferBuildValuesArray(buffer2 + 8, latchesArray);
391        if (initState == NIL(array_t)) {
392          SimAppendErrorMsg("Simulate: Error line ",
393                           SimInteger2ASCII(lineNumber), ".\n");
394          FreeArrays(inputsArray, latchesArray, outputsArray, internalPartitionArray);
395          return(sim);
396        }
397      }
398      else if (!strncmp(buffer2, ".start_vectors", 14)) {
399        /* Verification of the declarations */
400        if (inputsArray == NIL(array_t)) {
401          error_append("Simulate: Input file is missing inputs declaration.\n");
402          FreeArrays(inputsArray, latchesArray, outputsArray, internalPartitionArray);
403          return(sim);
404        }
405         
406        currentStateHead = array_n(inputsArray);
407         
408        nodesArray = array_dup(inputsArray);
409        array_free(inputsArray);
410        inputsArray = NIL(array_t);
411        if(latchesArray == NIL(array_t)) {
412          /* Verify if actually there is no latch in the network */
413          if (Ntk_NetworkReadNumLatches(network) > 0) {
414            error_append("Simulate: Input file is missing latches declaration.\n");
415            FreeArrays(inputsArray, latchesArray, outputsArray, internalPartitionArray);
416            return(0);
417          }
418          else {
419            internalPartitionHead = currentStateHead;
420            nextStateHead = internalPartitionHead + array_n(internalPartitionArray);
421            outputHead = nextStateHead;
422          }
423        }
424        else {
425          internalPartitionHead = currentStateHead + array_n(latchesArray);
426          nextStateHead = internalPartitionHead + array_n(internalPartitionArray);
427          outputHead = nextStateHead + array_n(latchesArray);
428          /* Add current states node */
429          array_append(nodesArray, latchesArray);
430          array_append(nodesArray, internalPartitionArray);
431          array_free(internalPartitionArray);
432          /* Add next state node as data-input of current-state node */
433          for(i = 0; i < array_n(latchesArray); i++) {
434            node = array_fetch(Ntk_Node_t *, latchesArray, i);
435            node = Ntk_LatchReadDataInput(node);
436            array_insert_last(Ntk_Node_t *, nodesArray, node);
437          }
438          array_free(latchesArray);
439        }
440        if (outputsArray != NIL(array_t)) {
441          array_append(nodesArray, outputsArray);
442          array_free(outputsArray);
443        }
444        /* Building nodeToMvfTable */
445        nodeToMvfTable = Sim_NetworkBuildNodeToMvfTable(network, nodesArray,
446                                                       internalPartitionHead,
447                                                       nextStateHead);
448        sim = Sim_SimCreate(network, nodeToMvfTable, inputFile, lineNumber,
449                            nodesArray, currentStateHead, internalPartitionHead, 
450                            nextStateHead, outputHead, initState, NULL, verbose);
451
452        return(sim); /* Normal end */
453      }
454     
455      /* Unknown string in the declaration part */
456      else {
457        SimAppendErrorMsg("Simulate: Syntax error in the declaration line: ",
458                         SimInteger2ASCII(lineNumber),
459                         " or missing .start_vectors statement.\n") ;
460        FreeArrays(inputsArray, latchesArray, outputsArray, internalPartitionArray);
461        return(sim);
462      }
463    }
464  }
465  array_free(internalPartitionArray);
466  return(sim); 
467}
468
469/**Function********************************************************************
470
471  Synopsis    [Parses the vectors of a simulation vectors file.]
472
473  Description [Parses the vectors of a simulation vectors file. This function
474  should be called after Sim_FileParseDeclaration. Reads lines from first line
475  after ".start_vectors" statement. Fills the vectorArray field of sim. If
476  this field is already set, it will be lost. Only "num" vectors are read(even
477  if the number of vectors in the file is greater than this number). If num is
478  0, then all vectors in the file are read.  If value is found that does not
479  belong to the domain of its specific variable, then an error message is
480  written in error_string, and the function returns 0. The function returns 1
481  if it normally ends and no EOF is detected. It returns 2 otherwise(normal
482  end and EOF).]
483
484  SideEffects []
485
486  SeeAlso     [Sim_FileParseDeclaration, Sim_SimReset]
487
488******************************************************************************/
489int
490Sim_FileParseVectors(
491  FILE      * fp,
492  Sim_Sim_t  * sim,
493  int         num)
494{
495  char           buffer[MAX_LINE_LENGTH];
496  char          *buffer2;
497  array_t       *vectorArray;
498  int            numberVector            = 0;
499  array_t       *inputsArray             = SimObtainInputsArray(sim);
500
501  sim->vectorArray = array_alloc(array_t *, 0);
502 
503  while (fgets(buffer, MAX_LINE_LENGTH -1, fp) != NULL) {
504    int position = 0;
505    (sim->lineNumber)++;
506
507    /* Every line must end by '\n' */
508    if (buffer[strlen(buffer) -1] != '\n') {
509      SimAppendErrorMsg("Simulate: Line ", SimInteger2ASCII(sim->lineNumber),
510                       " is too long!\n");
511      array_free(inputsArray);
512      return(0);
513    }
514   
515    /* Eliminate spaces */
516    BufferSkipWhiteSpace(buffer, &position);
517    /* buffer2 will contain buffer without space in the begining */
518    buffer2 = buffer + position;
519    /* Avoid comment and empty lines */
520    if (buffer[position] != '#' && buffer[position] != '\n') {
521      /* Read only "num" vectors */
522      if (numberVector >= num && num != 0) {
523        array_free(inputsArray);
524        return(1); /* Normal end before EOF */
525      }
526      vectorArray = BufferBuildValuesArray(buffer2, inputsArray);
527      if (vectorArray == NIL(array_t)) {
528        SimAppendErrorMsg("Simulate: Error line ",
529                         SimInteger2ASCII(sim->lineNumber), ".\n");
530        array_free(inputsArray);
531        return(0);
532      }
533      numberVector++;
534      SimAddVector(sim, vectorArray);
535    }
536  }
537  array_free(inputsArray);
538  return(2); /* End of file */
539}
540
541/*---------------------------------------------------------------------------*/
542/* Definition of internal functions                                          */
543/*---------------------------------------------------------------------------*/
544
545/*---------------------------------------------------------------------------*/
546/* Definition of static functions                                            */
547/*---------------------------------------------------------------------------*/
548/**Function********************************************************************
549
550  Synopsis    [Returns a new array containing the input nodes.]
551
552  Description [Returns a new array containing the input nodes. If there is no
553  inputs node in sim structure, then an empty array is returned.]
554 
555  SideEffects []
556
557******************************************************************************/
558static array_t *
559SimObtainInputsArray(
560  Sim_Sim_t * sim)
561{
562  int          i;
563  Ntk_Node_t * node;
564  array_t    * inputsArray = array_alloc(Ntk_Node_t *, 0);
565
566  for (i = 0; i < sim->currentStateHead; i++) {
567    node = array_fetch(Ntk_Node_t *, sim->nodesArray, i);
568    array_insert_last(Ntk_Node_t *, inputsArray, node);
569  }
570  return(inputsArray);
571}
572
573/**Function********************************************************************
574
575  Synopsis    [Frees arrays.]
576
577  Description [Frees array. Verifies if array is non NULL.]
578 
579  SideEffects []
580
581******************************************************************************/
582static void
583FreeArrays(
584  array_t *array1,
585  array_t *array2,
586  array_t *array3,
587  array_t *array4)
588{
589  if (array1 != NIL(array_t)) {
590    array_free(array1);
591  }
592  if (array2 != NIL(array_t)) {
593    array_free(array2);
594  }
595  if (array3 != NIL(array_t)) {
596    array_free(array3);
597  }
598  if (array4 != NIL(array_t)) {
599    array_free(array4);
600  }
601}
602 
603
604/**Function********************************************************************
605
606  Synopsis    [Builds an array of nodes corresponding to the name of inputs
607  read in the buffer.]
608
609  Description [Builds an array of nodes corresponding to the name of inputs
610  read in the buffer. If the name does not correspond to any input node in the
611  network, or the number of values is not correct, then an error message is
612  written in error_string, and NULL is returned.]
613 
614  SideEffects []
615
616******************************************************************************/
617static array_t *
618BufferBuildInputsNodeArray(
619  char * buffer,
620  Ntk_Network_t * network)
621{
622  char       *str;
623  Ntk_Node_t *node;
624  int         position = 0;
625  array_t    *array    = array_alloc(Ntk_Node_t *, 0);
626   
627  while((str = BufferObtainStringAtPosition(buffer, &position)) != NULL) {
628    node = Ntk_NetworkFindNodeByActualName(network, str);
629    if (node == NIL(Ntk_Node_t) || !Ntk_NodeTestIsInput(node)) {
630      SimAppendErrorMsg("Simulate: ", str, " is not a valid input name.\n");
631      array_free(array);
632      FREE(str);
633      return(NIL(array_t));
634    }
635    FREE(str);
636    array_insert_last(Ntk_Node_t *, array, node);
637  }
638  /* Verification of number of values */
639  if (array_n(array) != Ntk_NetworkReadNumInputs(network)) {
640    error_append("Simulate: All inputs and pseudo-inputs must be specified.\n");
641    array_free(array);
642    return(NIL(array_t));
643  }
644  return(array);
645}
646
647
648/**Function********************************************************************
649
650  Synopsis    [Builds an array of nodes corresponding to the name of latches
651  read in the buffer.]
652
653  Description [Builds an array of nodes corresponding to the name of latches
654  read in the buffer. If the name does not correspond to any latch node in the
655  network, or the number of values is not correct, then an error message is
656  written in error_string, and NULL is returned.]
657 
658  SideEffects []
659
660******************************************************************************/
661static array_t *
662BufferBuildLatchesNodeArray(
663  char * buffer,
664  Ntk_Network_t * network)
665{
666  char       *str;
667  Ntk_Node_t *node;
668  int         position = 0;
669  array_t    *array    = array_alloc(Ntk_Node_t *, 0);
670   
671  while ((str = BufferObtainStringAtPosition(buffer, &position)) != NULL) {
672    node = Ntk_NetworkFindNodeByActualName(network, str);
673    if (node == NIL(Ntk_Node_t) || !Ntk_NodeTestIsLatch(node)) {
674      SimAppendErrorMsg("Simulate: ", str, " is not a valid latch name\n");
675      array_free(array);
676      FREE(str);
677      return(NIL(array_t));
678    }
679    FREE(str);
680    array_insert_last(Ntk_Node_t *, array, node);
681  }
682  /* Verification of number of items */
683  if (array_n(array) != Ntk_NetworkReadNumLatches(network)) {
684    error_append("Simulate: All latches must be specified.\n");
685    array_free(array);
686    return(NIL(array_t));
687  }
688  return(array);
689}
690
691/**Function********************************************************************
692
693  Synopsis    [Builds an array of nodes corresponding to the name of outputs
694  read in the buffer.]
695
696  Description [Builds an array of nodes corresponding to the name of outputs
697  read in the buffer. If the name does not correspond to any output node in the
698  network, then an error message is written in error_string, and NULL is
699  returned. The number of outputs may be incomplete.]
700 
701  SideEffects []
702
703******************************************************************************/
704static array_t *
705BufferBuildOutputsNodeArray(
706  char * buffer,
707  Ntk_Network_t * network)
708{
709  char       *str;
710  Ntk_Node_t *node;
711  int         position = 0;
712  array_t    *array    = array_alloc(Ntk_Node_t *, 0);
713   
714  while((str = BufferObtainStringAtPosition(buffer, &position)) != NULL) {
715    node = Ntk_NetworkFindNodeByActualName(network, str);
716    if (node == NIL(Ntk_Node_t) || !Ntk_NodeTestIsPrimaryOutput(node)) {
717      SimAppendErrorMsg("Simulate: ", str, " is not a valid output name\n");
718      FREE(str);
719      array_free(array);
720      return(NIL(array_t));
721    }
722    FREE(str);
723    array_insert_last(Ntk_Node_t *, array, node);
724  }
725  return(array);
726}
727
728/**Function********************************************************************
729
730  Synopsis    [Builds an array of integers representing the code of strings
731  contained in the buffer.]
732
733  Description [Builds an array of integers representing the code of strings
734  contained in the buffer. The code is 1 or 0, if the value is equal "1" or
735  "0" and the variable is a binary variable. For a symbolic variable it is
736  equal to the index of the value of the variable. The code is equal to the
737  value of a variable if the variable has an enumerative type. If a wrong
738  value is detected, then an error message is written in error_string and NULL
739  is returned. This function verifies also if the number of values is equal to
740  the number of nodes in the nodesArray. If it is not, it returns NULL.]
741 
742  SideEffects []
743
744******************************************************************************/
745static array_t *
746BufferBuildValuesArray(
747  char * buffer,
748  array_t * nodesArray)
749{
750  char       *str;
751  Ntk_Node_t *node;
752  int         index;
753  int         i         = 0;
754  int         arraySize = array_n(nodesArray);
755  int         position  = 0;
756  array_t    *array     = array_alloc(int, 0);
757   
758  while((str = BufferObtainStringAtPosition(buffer, &position)) != NULL) {
759    if (i >= arraySize) {
760      SimAppendErrorMsg("Simulate: Too many values(", str, " invalid value).\n");
761      array_free(array);
762      FREE(str);
763      return(NIL(array_t));
764    } 
765    node = array_fetch(Ntk_Node_t *, nodesArray, i);
766    i++;
767    index = SimNodeReadValueCode(node, str);
768    if (index == -1) {
769      SimAppendErrorMsg("Simulate: ", str, ": invalid value.\n");
770      array_free(array);
771      FREE(str);
772      return(NIL(array_t));
773    }
774
775    FREE(str);
776    array_insert_last(int, array, index);
777  }
778 
779  /* Verification of number of items */
780  if (array_n(array) != array_n(nodesArray)) {
781    error_append("Simulate: incomplete number of values.\n");
782    array_free(array);
783    return(NIL(array_t));
784  }
785  return(array);
786}
787
788
789/**Function********************************************************************
790
791  Synopsis    [Add a vector to the array of vectors of a sim.]
792
793  Description [Add a vector to the array of vectors of a sim. It is an error
794  to call this function with a NULL sim or a sim that does not have a vectors
795  array.]
796 
797  SideEffects []
798
799******************************************************************************/
800static void
801SimAddVector(
802  Sim_Sim_t * sim,
803  array_t * vector)
804{
805  array_insert_last(array_t *, sim->vectorArray, vector);
806}
807
808/**Function********************************************************************
809
810  Synopsis    [skip over white space in a string.]
811
812  Description [skip over white space in a string. set position to the first
813  character different from ' ' and '\t'.]
814 
815  SideEffects []
816
817******************************************************************************/
818static void
819BufferSkipWhiteSpace(
820  char * buffer,
821  int * position)
822{
823  for (; buffer[*position] == ' ' || buffer[*position] == '\t'; (*position)++);
824}
825
826/**Function********************************************************************
827
828  Synopsis    [Returns a string read in a buffer at the given position.]
829
830  Description [Returns a string read in a buffer at the given position. The
831  end of string is detected by ' ', '\t', ';' or '\n'. Eliminates the Space in
832  the begining of the buffer. Returns NULL if an empty string has been found
833  before ';' or '\n'.]
834 
835  SideEffects []
836
837******************************************************************************/
838static char *
839BufferObtainStringAtPosition(
840  char * buffer,
841  int * position)
842{
843  char *str;
844  int   strPosition;
845  int   len;
846 
847  /* Traverse Space */
848  BufferSkipWhiteSpace(buffer, position);
849
850  strPosition = *position;
851  for (;buffer[*position] != ' ' && buffer[*position] != '\t' &&
852            buffer[*position] != ';'  && buffer[*position] != '\n'; (*position)++);
853
854  if (strPosition == *position) {
855    return(NIL(char));
856  }
857  len = *position - strPosition + 1;
858  str = ALLOC(char, len);
859  strncpy(str, buffer + strPosition, len - 1);
860  str[len-1] = '\0';
861  return(str);
862}
863
864/**Function********************************************************************
865
866  Synopsis    [Prints the value of a particular variable for a given
867  simulation vector.]
868
869  Description [Prints the value of a particular variable for a given
870  simulation vector. The variable is obtained from the node at the
871  vectorIndex position of the nodesArray. The value is obtained from
872  the vectorIndex position of the vector. strSize is used for
873  formatting. If the number of elements in the vector is less than the
874  vectorIndex, a * is printed instead.]
875
876  SideEffects []
877
878******************************************************************************/
879static void
880PrintValue(array_t *nodesArray, array_t *vector, int vectorIndex,
881           int strSize, FILE *file)
882{
883  int index;
884  Var_Variable_t *var;
885  char *str;
886  Ntk_Node_t *node;
887 
888  if (array_n(vector) > vectorIndex) {
889    node = array_fetch(Ntk_Node_t *, nodesArray, vectorIndex);
890    var = Ntk_NodeReadVariable(node);
891    index = array_fetch(int, vector, vectorIndex);
892    if (Var_VariableTestIsSymbolic(var)) {
893      SimStringPrint(file, Var_VariableReadSymbolicValueFromIndex(var, index),
894                     strSize);
895    }
896    else { /* Binary or enumerative type */
897      str = SimInteger2ASCII(index);
898      SimStringPrint(file, str, strSize);
899      FREE(str);
900    }
901  }
902  else {
903    error_append("Warning: Value is missing in vector.\n");
904    SimStringPrint(file, "*", strSize);
905  }
906}
Note: See TracBrowser for help on using the repository browser.