1/*.......1.........2.........3.........4.........5.........6.........7.........8
2================================================================================
3
4FILE d_state/cfunc.mod
5
6Public Domain
7
8Georgia Tech Research Corporation
9Atlanta, Georgia 30332
10PROJECT A-8503-405
11
12
13AUTHORS
14
15    6 June 1991     Jeffrey P. Murray
16
17
18MODIFICATIONS
19
20    30 Sept 1991    Jeffrey P. Murray
21
22
23SUMMARY
24
25    This file contains the model-specific routines used to
26    functionally describe the <model_name> code model.
27
28
29INTERFACES
30
31    FILE                 ROUTINE CALLED
32
33    CMmacros.h           cm_message_send();
34
35    CMevt.c              void *cm_event_alloc()
36                         void *cm_event_get_ptr()
37
38
39
40REFERENCED FILES
41
42    Inputs from and outputs to ARGS structure.
43
44
45NON-STANDARD FEATURES
46
47    NONE
48
49===============================================================================*/
50
51/*=== INCLUDE FILES ====================*/
52
53#include <stdio.h>
54#include <ctype.h>
55#include <math.h>
56#include <string.h>
57#include <stdlib.h>
58
59
60
61/*=== CONSTANTS ========================*/
62
63#define MAX_STRING_SIZE 200
64
65#define HEADER 1
66#define CONTINUATION 2
67
68#define OK 0
69#define FAIL 1
70
71
72
73
74/*=== MACROS ===========================*/
75
76
77
78
79/*=== LOCAL VARIABLES & TYPEDEFS =======*/
80
81typedef struct {
82    int current_state,  /* current state of the machine (similar to
83                           current state of the union, current state
84                           of the economy, etc. etc. 8-)                */
85               index0,  /* actual word number (0 to depth-1) in which the
86                           first line of the current_state definition
87                           may be found.                                */
88               indexN,  /* word number (0 to depth-1) of the final curren_state
89                           definition line...if a state is defined in only one
90                           line, index0 and indexN will be equal.       */
91          num_outputs,  /* width of bits[] table...equal to size of
92                           out port                               */
93           num_inputs,  /* width of inputs[] table...equal to size of
94                           in port                                */
95                depth,  /* depth of table...equal to size of
96                           current_state & next_state arrays,
97                           and to the total number of vectors
98                           retrieved from the
99                           state.in file.                               */
100               *state,  /* integer array holding the state
101                           index values...note that each state will
102                           have at least one and as many as 2^N
103                           "words" assigned to it, where N = number
104                           of input lines to the state machine.         */
105          *next_state;  /* integer array holding the next state
106                           to jump to given the input values
107                           held by the inputs[] array...note that each
108                           state will have at least one and as many as 2^N
109                           "words" assigned to it, where N = number
110                           of input lines to the state machine.         */
111
112
113    short   *bits,  /* the storage array for the
114                       output bit representations...
115                       this will have size equal to
116                       (width * depth)/4, since one
117                       short will hold four 12-state
118                       bit descriptions.                */
119          *inputs;  /* the storage array for the
120                       input bit representations...
121                       this will have size equal to
122                       (width * depth)/8, since one
123                       short will hold eight 3-state
124                       bit descriptions.                */
125} State_Table_t;
126
127
128
129
130
131
132
133
134/* Type definition for each possible token returned. */
135typedef enum token_type_s {CNV_NO_TOK,CNV_STRING_TOK} Cnv_Token_Type_t;
136
137
138
139
140
141
142typedef char line_t[82]; /* A SPICE size line. <= 80 characters plus '\n\0' */
143
144
145
146
147
148
149
150/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
151
152
153
154
155
156
157/*==============================================================================
158
159FUNCTION *CNVgettok()
160
161AUTHORS
162
163    13 Jun 1991     Jeffrey P. Murray
164
165MODIFICATIONS
166
167     8 Aug 1991     Jeffrey P. Murray
168    30 Sep 1991     Jeffrey P. Murray
169
170SUMMARY
171
172    This function obtains the next token from an input stream.
173
174INTERFACES
175
176    FILE                 ROUTINE CALLED
177
178    N/A                  N/A
179
180RETURNED VALUE
181
182    Returns a string value representing the next token.
183
184GLOBAL VARIABLES
185
186    NONE
187
188NON-STANDARD FEATURES
189
190    NONE
191
192==============================================================================*/
193
194
195/*=== Static CNVgettok ROUTINE ================*/
196/*
197Get the next token from the input string.  The input string pointer
198is advanced to the following token and the token from the input
199string is copied to malloced storage and a pointer to that storage
200is returned.  The original input string is undisturbed.
201*/
202
203static char  *CNVgettok(char **s)
204
205{
206
207    char    *buf;       /* temporary storage to copy token into */
208    /*char    *temp;*/      /* temporary storage to copy token into */
209    char    *ret_str;   /* storage for returned string */
210
211    int     i;
212
213    /* allocate space big enough for the whole string */
214
215    buf = (char *) malloc(strlen(*s) + 1);
216
217    /* skip over any white space */
218
219    while(isspace_c(**s) || (**s == '=') ||
220          (**s == '(') || (**s == ')') || (**s == ','))
221          (*s)++;
222
223    /* isolate the next token */
224
225    switch(**s) {
226
227    case '\0':           /* End of string found */
228        if(buf) free(buf);
229        return(NULL);
230
231
232    default:             /* Otherwise, we are dealing with a    */
233                         /* string representation of a number   */
234                         /* or a mess o' characters.            */
235        i = 0;
236        while( (**s != '\0') &&
237               (! ( isspace_c(**s) || (**s == '=') ||
238                    (**s == '(') || (**s == ')') ||
239                    (**s == ',')
240             ) )  ) {
241            buf[i] = **s;
242            i++;
243            (*s)++;
244        }
245        buf[i] = '\0';
246        break;
247    }
248
249    /* skip over white space up to next token */
250
251    while(isspace_c(**s) || (**s == '=') ||
252          (**s == '(') || (**s == ')') || (**s == ','))
253          (*s)++;
254
255    /* make a copy using only the space needed by the string length */
256
257
258    ret_str = (char *) malloc(strlen(buf) + 1);
259    ret_str = strcpy(ret_str,buf);
260
261    if(buf) free(buf);
262
263    return(ret_str);
264}
265
266
267/*==============================================================================
268
269FUNCTION *CNVget_token()
270
271AUTHORS
272
273    13 Jun 1991     Jeffrey P. Murray
274
275MODIFICATIONS
276
277     8 Aug 1991     Jeffrey P. Murray
278    30 Sep 1991     Jeffrey P. Murray
279
280SUMMARY
281
282    This function obtains the next token from an input stream.
283
284INTERFACES
285
286    FILE                 ROUTINE CALLED
287
288    N/A                  N/A
289
290RETURNED VALUE
291
292    Returns a string value representing the next token. Uses
293    *CNVget_tok.
294
295GLOBAL VARIABLES
296
297    NONE
298
299NON-STANDARD FEATURES
300
301    NONE
302
303==============================================================================*/
304
305/*=== Static CNVget_token ROUTINE =============*/
306/*
307Get the next token from the input string together with its type.
308The input string pointer
309is advanced to the following token and the token from the input
310string is copied to malloced storage and a pointer to that storage
311is returned.  The original input string is undisturbed.
312*/
313
314static char  *CNVget_token(char **s, Cnv_Token_Type_t *type)
315
316{
317
318    char    *ret_str;   /* storage for returned string */
319
320    /* get the token from the input line */
321
322    ret_str = CNVgettok(s);
323
324
325    /* if no next token, return */
326
327    if(ret_str == NULL) {
328        *type = CNV_NO_TOK;
329        return(NULL);
330    }
331
332    /* else, determine and return token type */
333
334    switch(*ret_str) {
335
336    default:
337        *type = CNV_STRING_TOK;
338        break;
339
340    }
341
342    return(ret_str);
343}
344
345
346
347
348/*==============================================================================
349
350FUNCTION cnv_get_spice_value()
351
352AUTHORS
353
354    ???             Bill Kuhn
355
356MODIFICATIONS
357
358    30 Sep 1991     Jeffrey P. Murray
359
360SUMMARY
361
362    This function takes as input a string token from a SPICE
363    deck and returns a floating point equivalent value.
364
365INTERFACES
366
367    FILE                 ROUTINE CALLED
368
369    N/A                  N/A
370
371RETURNED VALUE
372
373    Returns the floating point value in pointer *p_value. Also
374    returns an integer representing successful completion.
375
376GLOBAL VARIABLES
377
378    NONE
379
380NON-STANDARD FEATURES
381
382    NONE
383
384==============================================================================*/
385
386/*=== Static CNV_get_spice_value ROUTINE =============*/
387
388/*
389   Function takes as input a string token from a SPICE
390deck and returns a floating point equivalent value.
391*/
392
393
394static int cnv_get_spice_value(
395char    *str,        /* IN - The value text e.g. 1.2K */
396double  *p_value )   /* OUT - The numerical value     */
397{
398
399
400    /* the following were "int4" devices - jpm */
401    size_t len;
402    size_t i;
403    int    n_matched;
404
405    line_t  val_str;
406
407    /*char    *suffix;*/
408    char    c = ' ';
409    char    c1;
410
411    double  scale_factor;
412    double  value;
413
414
415    /* Scan the input string looking for an alpha character that is not  */
416    /* 'e' or 'E'.  Such a character is assumed to be an engineering     */
417    /* suffix as defined in the Spice 2G.6 user's manual.                */
418
419    len = strlen(str);
420    if( len > (sizeof(val_str) - 1))
421        len = sizeof(val_str) - 1;
422
423    for(i = 0; i < len; i++) {
424        c = str[i];
425        if( isalpha_c(c) && (c != 'E') && (c != 'e') )
426            break;
427        else if( isspace_c(c) )
428            break;
429        else
430            val_str[i] = c;
431    }
432    val_str[i] = '\0';
433
434
435    /* Determine the scale factor */
436
437    if( (i >= len) || (! isalpha_c(c)) )
438        scale_factor = 1.0;
439    else {
440
441        if(islower_c(c))
442            c = tolower_c(c);
443
444        switch(c) {
445
446        case 't':
447            scale_factor = 1.0e12;
448            break;
449
450        case 'g':
451            scale_factor = 1.0e9;
452            break;
453
454        case 'k':
455            scale_factor = 1.0e3;
456            break;
457
458        case 'u':
459            scale_factor = 1.0e-6;
460            break;
461
462        case 'n':
463            scale_factor = 1.0e-9;
464            break;
465
466        case 'p':
467            scale_factor = 1.0e-12;
468            break;
469
470        case 'f':
471            scale_factor = 1.0e-15;
472            break;
473
474        case 'm':
475            i++;
476            if(i >= len) {
477                scale_factor = 1.0e-3;
478                break;
479            }
480            c1 = str[i];
481            if(! isalpha_c(c1)) {
482                scale_factor = 1.0e-3;
483                break;
484            }
485            if(islower_c(c1))
486                c1 = toupper_c(c1);
487            if(c1 == 'E')
488                scale_factor = 1.0e6;
489            else if(c1 == 'I')
490                scale_factor = 25.4e-6;
491            else
492                scale_factor = 1.0e-3;
493            break;
494
495        default:
496            scale_factor = 1.0;
497        }
498    }
499
500    /* Convert the numeric portion to a float and multiply by the */
501    /* scale factor.                                              */
502
503    n_matched = sscanf(val_str,"%le",&value);
504
505    if(n_matched < 1) {
506        *p_value = 0.0;
507        return(FAIL);
508    }
509
510    *p_value = value * scale_factor;
511    return(OK);
512}
513
514
515/*==============================================================================
516
517FUNCTION cm_inputs_mask_and_retrieve()
518
519AUTHORS
520
521    23 Jul 1991     Jeffrey P. Murray
522
523MODIFICATIONS
524
525    30 Sep 1991     Jeffrey P. Murray
526
527SUMMARY
528
529    Masks off and retrieves a two-bit value from a short
530    integer word passed to the function, using an offset value.
531    This effectively handles retrieval of eight two-bit values
532    from a single short integer space in order to conserve memory.
533
534INTERFACES
535
536    FILE                 ROUTINE CALLED
537
538    N/A                  N/A
539
540
541RETURNED VALUE
542
543    Returns a Digital_t value.
544
545GLOBAL VARIABLES
546
547    NONE
548
549NON-STANDARD FEATURES
550
551    NONE
552
553==============================================================================*/
554
555/*=== Static CM_INPUTS_MASK_AND_RETRIEVE ROUTINE ===*/
556
557/**************************************************
558*      The following routine masks and retrieves  *
559*   the value passed to it by the out value       *
560*   by masking the appropriate bits in the        *
561*   base integer. The particular bit affected     *
562*   is determined by the bit_offset value.        *
563*                                                 *
564*   Created 7/23/91               J.P.Murray      *
565**************************************************/
566
567static Digital_State_t cm_inputs_mask_and_retrieve(short base, int bit_offset)
568{
569
570
571    int value;    /* the hexadecimal value of the masked bit  */
572
573
574    value = 0x0003 & (base >> (bit_offset * 2));
575
576
577    switch (value) {
578    case 0:  return ZERO;
579    case 1:  return ONE;
580    default: return UNKNOWN;
581    }
582
583}
584
585
586/*==============================================================================
587
588FUNCTION cm_set_indices()
589
590AUTHORS
591
592    23 Jul 1991     Jeffrey P. Murray
593
594MODIFICATIONS
595
596    30 Sep 1991     Jeffrey P. Murray
597
598SUMMARY
599
600    The following routine retrieves the current_state value
601    from the *states structure. It then searches the entire
602    state[] array to determine the index0 and indexN values
603    corresponding to the first and last entries in the
604    state[] array for the current state.
605
606INTERFACES
607
608    FILE                 ROUTINE CALLED
609
610    N/A                  N/A
611
612
613RETURNED VALUE
614
615    Returns a status int value.
616
617GLOBAL VARIABLES
618
619    NONE
620
621NON-STANDARD FEATURES
622
623    NONE
624
625==============================================================================*/
626
627/*=== Static CM_SET_INDICES ROUTINE ===*/
628
629/************************************************
630*      The following routine retrieves the      *
631*   current_state value from the *states        *
632*   structure. It then searches the entire      *
633*   state[] array to determine the index0 and   *
634*   indexN values corresponding to the first    *
635*   and last entries in the state[] array for   *
636*   the current state.                          *
637*                                               *
638*   Created 7/23/91               J.P. Murray   *
639************************************************/
640
641
642static int cm_set_indices(State_Table_t *states)
643{
644    int         i,  /* indexing variable */
645       index0_set,  /* flag for index0   */
646       indexN_set;  /* flag for index1   */
647
648
649    states->index0 = 0;
650    states->indexN = 0;
651    index0_set = 0;
652    indexN_set = 0;
653
654
655    for (i=0; i< states->depth; i++) { /* loop through all states */
656
657        if ( states->state[i] == states->current_state ) {
658            /* states match... */
659
660            /* if not already set, set index0... */
661            if ( 0 == index0_set ) {
662                states->index0 = i;
663                states->indexN = i;
664                index0_set = 1;
665            }
666
667            if ( 1 < (i - states->indexN) ) {
668                /* ERROR!! This means that a state match was
669                   found in a nonn-contiguous portion of the
670                   state.in file...this is not allowed! */
671                return TRUE;
672            }
673            else {
674                /* update indexN. */
675                states->indexN = i;
676            }
677        }
678    }
679    return FALSE;
680}
681
682
683/*==============================================================================
684
685FUNCTION cm_compare_to_inputs()
686
687AUTHORS
688
689    23 Jul 1991     Jeffrey P. Murray
690
691MODIFICATIONS
692
693    30 Sep 1991     Jeffrey P. Murray
694
695SUMMARY
696
697    The following routine retrieves the
698    the inputs[] bit value pointed to by
699    the word_num and bit_num integers, compares
700    this value with the "in" state value, and
701    returns a "0" if they match, and a "1" if
702    they do not match.
703
704INTERFACES
705
706    FILE                 ROUTINE CALLED
707
708    N/A                  N/A
709
710
711RETURNED VALUE
712
713    Returns a status int value.
714
715GLOBAL VARIABLES
716
717    NONE
718
719NON-STANDARD FEATURES
720
721    NONE
722
723==============================================================================*/
724
725/*=== Static CM_COMPARE_TO_INPUTS ROUTINE ===*/
726
727/************************************************
728*      The following routine retrieves the      *
729*   the inputs[] bit value pointed to by        *
730*   the word_num and bit_num integers, compares *
731*   this value with the "in" state value, and   *
732*   returns a "0" if they match, and a "1" if   *
733*   they do not match.                          *
734*                                               *
735*   Created 7/23/91               J.P.Murray    *
736************************************************/
737
738
739static int cm_compare_to_inputs(State_Table_t *states,int index,int bit_number, Digital_State_t in)
740{
741    int      int1,      /* temp storage variable    */
742        bit_index,      /* bits base address at which word bits will
743                           be found */
744       bit_offset;      /* offset from ram base address at which bit[0]
745                           of the required word can be found    */
746
747    short    base;      /* variable to hold current base integer for
748                           comparison purposes. */
749
750    Digital_State_t     out;      /* output variable for state retrieved   */
751
752
753    /* obtain offset value from index, word_width & bit_number */
754    int1 = index * states->num_inputs + bit_number;
755
756    bit_index = int1 >> 3;
757    bit_offset = int1 & 7;
758
759    /* retrieve entire base_address bits integer... */
760    base = states->inputs[bit_index];
761
762    /* for each offset, mask off the bits and determine values */
763
764    out = cm_inputs_mask_and_retrieve(base, bit_offset);
765
766    if ( out == in ) {  /* bit matches */
767        return 0;
768    }
769    else
770    if ( out == UNKNOWN ) {     /* bit compared to is a "don't care" */
771        return 0;
772    }
773    else {                    /* no match */
774        return 1;
775    }
776}
777
778
779/*==============================================================================
780
781FUNCTION cm_inputs_mask_and_store()
782
783AUTHORS
784
785    22 Jul 1991     Jeffrey P. Murray
786
787MODIFICATIONS
788
789    30 Sep 1991     Jeffrey P. Murray
790
791SUMMARY
792
793    The following routine masks and stores
794    the value passed to it by the out value
795    by masking the appropriate bits in the
796    base integer. The particular bit affected
797    is determined by the bit_offset value.
798    This routine stores to the inputs[] array.
799
800
801INTERFACES
802
803    FILE                 ROUTINE CALLED
804
805    N/A                  N/A
806
807
808RETURNED VALUE
809
810    Returns a status int value.
811
812GLOBAL VARIABLES
813
814    NONE
815
816NON-STANDARD FEATURES
817
818    NONE
819
820==============================================================================*/
821
822/*=== Static CM_INPUTS_MASK_AND_STORE ROUTINE ===*/
823
824/************************************************
825*      The following routine masks and stores   *
826*   the value passed to it by the out value     *
827*   by masking the appropriate bits in the      *
828*   base integer. The particular bit affected   *
829*   is determined by the bit_offset value.      *
830*   This routine stores to the inputs[] array.  *
831*                                               *
832*   Created 7/22/91                             *
833*   Last Modified 7/22/91         J.P.Murray    *
834************************************************/
835
836static void cm_inputs_mask_and_store(short *base,int bit_offset,int bit_value)
837{
838    *base &= (short)  ~ (0x0003 << (bit_offset * 2));
839    *base |= (short) (bit_value << (bit_offset * 2));
840}
841
842
843
844
845/*==============================================================================
846
847FUNCTION cm_store_inputs_value()
848
849AUTHORS
850
851    23 Jul 1991     Jeffrey P. Murray
852
853MODIFICATIONS
854
855    30 Sep 1991     Jeffrey P. Murray
856
857SUMMARY
858
859    The following routine retrieves four-bit
860    data from short integer array "bits". The
861    integers are assumed to be at least two
862    bytes each, so each will hold four four-
863    bit values.
864
865
866
867INTERFACES
868
869    FILE                 ROUTINE CALLED
870
871    N/A                  N/A
872
873
874RETURNED VALUE
875
876    NONE
877
878GLOBAL VARIABLES
879
880    NONE
881
882NON-STANDARD FEATURES
883
884    NONE
885
886==============================================================================*/
887
888/*=== Static CM_STORE_INPUTS_VALUE ROUTINE ===*/
889
890/************************************************
891*      The following routine retrieves four-bit *
892*   data from short integer array "bits". The   *
893*   integers are assumed to be at least two     *
894*   bytes each, so each will hold four four-    *
895*   bit values.                                 *
896*                                               *
897*   Created 7/23/91               J.P.Murray    *
898************************************************/
899
900static void cm_store_inputs_value(State_Table_t *states,int index, int bit_number,
901                                int in_val)
902
903{
904    int       /*err,*/      /* error index value    */
905             int1,      /* temp storage variable    */
906        bit_index,      /* bits base address at which word bits will
907                           be found */
908       bit_offset;      /* offset from ram base address at which bit[0]
909                           of the required word can be found    */
910
911    short    base;      /* variable to hold current base integer for
912                           comparison purposes. */
913
914
915
916    /* obtain offset value from word_number, word_width &
917       bit_number */
918    int1 = index * states->num_inputs + bit_number;
919
920    bit_index = int1 >> 3;
921    bit_offset = int1 & 7;
922
923    /* retrieve entire base_address bits integer... */
924    base = states->inputs[bit_index];
925
926    /* for each offset, mask off the bits and store values */
927    cm_inputs_mask_and_store(&base,bit_offset,in_val);
928
929    /* store modified base value */
930    states->inputs[bit_index] = base;
931}
932
933
934/*==============================================================================
935
936FUNCTION cm_bits_mask_and_store()
937
938AUTHORS
939
940    22 Jul 1991     Jeffrey P. Murray
941
942MODIFICATIONS
943
944    30 Sep 1991     Jeffrey P. Murray
945
946SUMMARY
947
948      The following routine masks and stores
949   the value passed to it by the out value
950   by masking the appropriate bits in the
951   base integer. The particular bit affected
952   is determined by the bit_offset value.
953   This routine stores to the bits[] array.
954
955
956INTERFACES
957
958    FILE                 ROUTINE CALLED
959
960    N/A                  N/A
961
962
963RETURNED VALUE
964
965    Returns a status integer.
966
967GLOBAL VARIABLES
968
969    NONE
970
971NON-STANDARD FEATURES
972
973    NONE
974
975==============================================================================*/
976
977
978/*=== Static CM_BITS_MASK_AND_STORE ROUTINE ===*/
979
980/************************************************
981*      The following routine masks and stores   *
982*   the value passed to it by the out value     *
983*   by masking the appropriate bits in the      *
984*   base integer. The particular bit affected   *
985*   is determined by the bit_offset value.      *
986*   This routine stores to the bits[] array.    *
987*                                               *
988*   Created 7/22/91                             *
989*   Last Modified 7/22/91         J.P.Murray    *
990************************************************/
991
992static void cm_bits_mask_and_store(short *base,int bit_offset,int bit_value)
993{
994    *base &= (short)  ~ (0x000f << (bit_offset * 4));
995    *base |= (short) (bit_value << (bit_offset * 4));
996}
997
998
999
1000
1001/*==============================================================================
1002
1003FUNCTION cm_bits_mask_and_retrieve()
1004
1005AUTHORS
1006
1007    22 Jul 1991     Jeffrey P. Murray
1008
1009MODIFICATIONS
1010
1011    30 Sep 1991     Jeffrey P. Murray
1012
1013SUMMARY
1014
1015    The following routine masks and retrieves
1016    the value passed to it by the out value
1017    by masking the appropriate bits in the
1018    base integer. The particular bit affected
1019    is determined by the bit_offset value.
1020
1021
1022
1023INTERFACES
1024
1025    FILE                 ROUTINE CALLED
1026
1027    N/A                  N/A
1028
1029
1030RETURNED VALUE
1031
1032    NONE
1033
1034GLOBAL VARIABLES
1035
1036    NONE
1037
1038NON-STANDARD FEATURES
1039
1040    NONE
1041
1042==============================================================================*/
1043
1044/*=== Static CM_BITS_MASK_AND_RETRIEVE ROUTINE ===*/
1045
1046/**************************************************
1047*      The following routine masks and retrieves  *
1048*   the value passed to it by the out value       *
1049*   by masking the appropriate bits in the        *
1050*   base integer. The particular bit affected     *
1051*   is determined by the ram_offset value.        *
1052*                                                 *
1053*   Created 7/22/91                               *
1054*   Last Modified 7/22/91         J.P.Murray      *
1055**************************************************/
1056
1057static void cm_bits_mask_and_retrieve(short base,int bit_offset,Digital_t *out)
1058{
1059
1060
1061    int value;    /* the hexadecimal value of the masked bit  */
1062
1063    value = 0x000f & (base >> (bit_offset * 4));
1064
1065
1066    switch (value) {
1067
1068    case 0: out->state = ZERO;
1069            out->strength = STRONG;
1070            break;
1071
1072    case 1: out->state = ONE;
1073            out->strength = STRONG;
1074            break;
1075
1076    case 2: out->state = UNKNOWN;
1077            out->strength = STRONG;
1078            break;
1079
1080    case 3: out->state = ZERO;
1081            out->strength = RESISTIVE;
1082            break;
1083
1084    case 4: out->state = ONE;
1085            out->strength = RESISTIVE;
1086            break;
1087
1088    case 5: out->state = UNKNOWN;
1089            out->strength = RESISTIVE;
1090            break;
1091
1092    case 6: out->state = ZERO;
1093            out->strength = HI_IMPEDANCE;
1094            break;
1095
1096    case 7: out->state = ONE;
1097            out->strength = HI_IMPEDANCE;
1098            break;
1099
1100    case 8: out->state = UNKNOWN;
1101            out->strength = HI_IMPEDANCE;
1102            break;
1103
1104    case 9: out->state = ZERO;
1105            out->strength = UNDETERMINED;
1106            break;
1107
1108    case 10: out->state = ONE;
1109            out->strength = UNDETERMINED;
1110            break;
1111
1112    case 11: out->state = UNKNOWN;
1113            out->strength = UNDETERMINED;
1114            break;
1115    }
1116}
1117
1118
1119/*==============================================================================
1120
1121FUNCTION cm_get_bits_value()
1122
1123AUTHORS
1124
1125    22 Jul 1991     Jeffrey P. Murray
1126
1127MODIFICATIONS
1128
1129    23 Jul 1991     Jeffrey P. Murray
1130    30 Sep 1991     Jeffrey P. Murray
1131
1132SUMMARY
1133
1134    The following routine retrieves four-bit
1135    data from short integer array "bits". The
1136    integers are assumed to be at least two
1137    bytes each, so each will hold four four-
1138    bit values.
1139
1140
1141
1142INTERFACES
1143
1144    FILE                 ROUTINE CALLED
1145
1146    N/A                  N/A
1147
1148
1149RETURNED VALUE
1150
1151    NONE
1152
1153GLOBAL VARIABLES
1154
1155    NONE
1156
1157NON-STANDARD FEATURES
1158
1159    NONE
1160
1161==============================================================================*/
1162
1163/*=== Static CM_GET_BITS_VALUE ROUTINE ===*/
1164
1165/************************************************
1166*      The following routine retrieves four-bit *
1167*   data from short integer array "bits". The   *
1168*   integers are assumed to be at least two     *
1169*   bytes each, so each will hold four four-    *
1170*   bit values.                                 *
1171*                                               *
1172*   Created 7/22/91                             *
1173*   Last Modified 7/23/91         J.P.Murray    *
1174************************************************/
1175
1176static void cm_get_bits_value(State_Table_t *states,int index, int bit_number,
1177                              Digital_t *out)
1178
1179{
1180    int       /*err,*/      /* error index value    */
1181             int1,      /* temp storage variable    */
1182        bit_index,      /* bits base address at which word bits will
1183                           be found */
1184       bit_offset;      /* offset from ram base address at which bit[0]
1185                           of the required word can be found    */
1186
1187    short    base;      /* variable to hold current base integer for
1188                           comparison purposes. */
1189
1190
1191
1192    /* obtain offset value from index, word_width & bit_number */
1193    int1 = index * states->num_outputs + bit_number;
1194
1195    bit_index = int1 >> 2;
1196    bit_offset = int1 & 3;
1197
1198    /* retrieve entire base_address bits integer... */
1199    base = states->bits[bit_index];
1200
1201    /* for each offset, mask off the bits and determine values */
1202
1203    cm_bits_mask_and_retrieve(base,bit_offset,out);
1204
1205}
1206
1207
1208
1209/*==============================================================================
1210
1211FUNCTION cm_store_bits_value()
1212
1213AUTHORS
1214
1215    23 Jul 1991     Jeffrey P. Murray
1216
1217MODIFICATIONS
1218
1219    30 Sep 1991     Jeffrey P. Murray
1220
1221SUMMARY
1222
1223       The following routine retrieves four-bit
1224    data from short integer array "bits". The
1225    integers are assumed to be at least two
1226    bytes each, so each will hold four four-
1227    bit values.
1228
1229
1230
1231INTERFACES
1232
1233    FILE                 ROUTINE CALLED
1234
1235    N/A                  N/A
1236
1237
1238RETURNED VALUE
1239
1240    NONE
1241
1242GLOBAL VARIABLES
1243
1244    NONE
1245
1246NON-STANDARD FEATURES
1247
1248    NONE
1249
1250==============================================================================*/
1251
1252/*=== Static CM_STORE_BITS_VALUE ROUTINE ===*/
1253
1254/************************************************
1255*      The following routine retrieves four-bit *
1256*   data from short integer array "bits". The   *
1257*   integers are assumed to be at least two     *
1258*   bytes each, so each will hold four four-    *
1259*   bit values.                                 *
1260*                                               *
1261*   Created 7/23/91                             *
1262*   Last Modified 7/23/91         J.P.Murray    *
1263************************************************/
1264
1265static void cm_store_bits_value(State_Table_t *states,int index, int bit_number,
1266                                int in_val)
1267
1268{
1269    int       /*err,*/      /* error index value    */
1270             int1,      /* temp storage variable    */
1271        bit_index,      /* bits base address at which word bits will
1272                           be found */
1273       bit_offset;      /* offset from ram base address at which bit[0]
1274                           of the required word can be found    */
1275
1276    short    base;      /* variable to hold current base integer for
1277                           comparison purposes. */
1278
1279
1280
1281    /* obtain offset value from word_number, word_width &
1282       bit_number */
1283    int1 = index * states->num_outputs + bit_number;
1284
1285    bit_index = int1 >> 2;
1286    bit_offset = int1 & 3;
1287
1288    /* retrieve entire base_address bits integer... */
1289    base = states->bits[bit_index];
1290
1291    /* for each offset, mask off the bits and store values */
1292    cm_bits_mask_and_store(&base,bit_offset,in_val);
1293
1294    /* store modified base value */
1295    states->bits[bit_index] = base;
1296}
1297
1298
1299
1300/*==============================================================================
1301
1302FUNCTION cm_read_state_file()
1303
1304AUTHORS
1305
1306    15 Jul 1991     Jeffrey P. Murray
1307
1308MODIFICATIONS
1309
1310    23 Jul 1991     Jeffrey P. Murray
1311    30 Sep 1991     Jeffrey P. Murray
1312
1313SUMMARY
1314
1315       The following routine reads the file
1316    *state_file, parses the file, and stores
1317    the values found there into the *state,
1318    *bits, *inputs and *next_state arrays.
1319
1320
1321
1322INTERFACES
1323
1324    FILE                 ROUTINE CALLED
1325
1326    N/A                  N/A
1327
1328
1329RETURNED VALUE
1330
1331    Returns a status integer value.
1332
1333GLOBAL VARIABLES
1334
1335    NONE
1336
1337NON-STANDARD FEATURES
1338
1339    NONE
1340
1341==============================================================================*/
1342
1343/*=== Static CM_READ_STATE_FILE ROUTINE ===*/
1344
1345
1346/**************************************************
1347*      The following routine reads the file       *
1348*   *state_file, parses the file, and stores      *
1349*   the values found there into the *state,       *
1350*   *bits, *inputs and *next_state arrays.        *
1351*                                                 *
1352*   Created 7/15/91                               *
1353*   Last Modified 7/23/91         J.P.Murray      *
1354**************************************************/
1355
1356static int cm_read_state_file(FILE *state_file,State_Table_t *states)
1357{
1358    int         i,  /* indexing variable    */
1359                j,  /* indexing variable    */
1360       num_tokens,  /* number of tokens in a given string    */
1361        /*bit_index,*/  /* index to which bits[] integer we are accessing   */
1362       /*bit_offset,*/  /* index to which bit within the current bits[]
1363                       integer we are accessing   */
1364      string_type;  /* integer holding value corresponding to the
1365                       type of input string obtained:
1366                           1 = HEADER => State Header string
1367                           2 = CONTINUATION => a continuation line...
1368                                               values of state and
1369                                               bits must be retreived from
1370                                               the previous string. */
1371             /*int1;*/  /* temporary holding variable   */
1372
1373
1374    Cnv_Token_Type_t type;  /* variable for testing token type returned.    */
1375
1376
1377    char   temp[MAX_STRING_SIZE],   /* holding string variable for testing
1378                                       input from state.in */
1379                              *s,   /* main string variable */
1380                   *base_address,   /* storage location for base address
1381                                       of string.   */
1382                          *token;   /* a particular token from the string   */
1383
1384
1385    double                number;   /* holding variable for timepoint values */
1386
1387    short              bit_value=0;   /* holding variable for value read from
1388                                       state.in file which needs to be stored */
1389                            /*base;*/   /* holding variable for existing
1390                                       non-masked bits[] integer  */
1391	if (!state_file) {
1392		return 2;
1393	}
1394
1395    i = 0;
1396    s = temp;
1397    while ( fgets(s,MAX_STRING_SIZE,state_file) != NULL) {
1398        /* Test this string to see if it is whitespace... */
1399
1400        base_address = s;
1401        while(isspace_c(*s) || (*s == '*'))
1402              (s)++;
1403        if ( *s != '\0' ) {     /* This is not a blank line, so process... */
1404            s = base_address;
1405
1406            if ( '*' != s[0] ) {
1407
1408                /* Count up total number of tokens including \0... */
1409                j = 0;
1410                type = CNV_STRING_TOK;
1411                while ( type != CNV_NO_TOK ) {
1412                    token = CNVget_token(&s, &type);
1413                    j++;
1414                }
1415                num_tokens = (j-1);
1416
1417                /* Test the type of entry this number of
1418                   tokens represents. Valid types are:
1419
1420                        a. State Header with state, bits, inputs
1421                           and next_state entries...total tokens
1422                           equals num_inputs + num_outputs + 3
1423                           (e.g. "5 0s 0s 0s 0 0 -> 6").
1424
1425                        b. State continuation line with inputs
1426                           and next_state only...total tokens
1427                           equals num_inputs + 2.
1428                           (e.g. "           0 1 -> 7").
1429                */
1430
1431                if ( (3 + states->num_inputs + states->num_outputs) ==
1432                      num_tokens) {
1433                    string_type = HEADER;
1434                }
1435                else {
1436                    if ( (2 + states->num_inputs) == num_tokens) {
1437                        string_type = CONTINUATION;
1438                    }
1439                    else { /* Number of tokens is incorrect */
1440                        return 1;
1441                    }
1442                }
1443
1444                /* reset s to beginning... */
1445                s = base_address;
1446
1447                /** Retrieve each token, analyze, and       **/
1448                /** store the state, bits, inputs &         **/
1449                /** next_state information.                 **/
1450
1451                if ( HEADER == string_type ) { /**** header type loop ****/
1452
1453                    for (j=0; j<(states->num_inputs + states->num_outputs
1454                                 + 3); j++) {
1455
1456                        token = CNVget_token(&s, &type);
1457
1458
1459                        if ( 0 == j ) { /* obtain state value... */
1460
1461                            /* convert to a floating point number... */
1462                            cnv_get_spice_value(token,&number);
1463
1464                            states->state[i] = (int) number;
1465
1466
1467                        }
1468                        else { /* obtain each bit value & set bits entry    */
1469
1470                            if ( states->num_outputs >= j ) {
1471
1472                                /* preset this bit location */
1473                                bit_value = 12;
1474
1475                                if (0 == strcmp(token,"0s")) bit_value = 0;
1476                                if (0 == strcmp(token,"1s")) bit_value = 1;
1477                                if (0 == strcmp(token,"Us")) bit_value = 2;
1478                                if (0 == strcmp(token,"0r")) bit_value = 3;
1479                                if (0 == strcmp(token,"1r")) bit_value = 4;
1480                                if (0 == strcmp(token,"Ur")) bit_value = 5;
1481                                if (0 == strcmp(token,"0z")) bit_value = 6;
1482                                if (0 == strcmp(token,"1z")) bit_value = 7;
1483                                if (0 == strcmp(token,"Uz")) bit_value = 8;
1484                                if (0 == strcmp(token,"0u")) bit_value = 9;
1485                                if (0 == strcmp(token,"1u")) bit_value = 10;
1486                                if (0 == strcmp(token,"Uu")) bit_value = 11;
1487
1488                                /* if this bit was not recognized, return with an error  */
1489                                if (12 == bit_value) {
1490                                    return 1;
1491                                }
1492                                else { /* need to store this value in the bits[] array */
1493
1494                                    cm_store_bits_value(states,i,(j-1),bit_value);
1495
1496
1497                                }
1498                            }
1499                            else { /* obtain inputs info... */
1500
1501                                if ( (states->num_outputs + states->num_inputs)
1502                                     >= j ) {
1503
1504                                    /* preset this bit location */
1505                                    bit_value = 3;
1506
1507                                    if (0 == strcmp(token,"0")) bit_value = 0;
1508                                    if (0 == strcmp(token,"1")) bit_value = 1;
1509                                    if (0 == strcmp(token,"x")) bit_value = 2;
1510                                    if (0 == strcmp(token,"X")) bit_value = 2;
1511
1512                                    /* if this bit was not recognized, return with an error  */
1513                                    if (3 == bit_value) {
1514                                        return 1;
1515                                    }
1516                                    else { /* need to store this value in the inputs[] array */
1517
1518                                        cm_store_inputs_value(states,i,(j-1-states->num_outputs),bit_value);
1519
1520                                    }
1521                                }
1522                                else { /* obtain next_state value */
1523
1524                                    if ( (1 + states->num_outputs + states->num_inputs)
1525                                         == j ) {
1526                                        /* skip the "->" token */
1527                                    }
1528                                    else {
1529
1530                                        /* convert to a floating point number... */
1531                                        cnv_get_spice_value(token,&number);
1532
1533                                        states->next_state[i] = (int) number;
1534                                    }
1535                                }
1536                            }
1537                        }
1538                    }
1539                }
1540                else { /**** continuation type loop ****/
1541
1542                    /* set state value to previous state value */
1543                    states->state[i] = states->state[i-1];
1544
1545                    /* set bits values to previous bits values */
1546                    for (j=0; j<states->num_outputs; j++) {
1547
1548                        /*** Retrieve the previous bit value ***?
1549                        cm_get_bits_value(*states,i,j,&out);
1550
1551                        switch (out.state) {
1552
1553                        case ZERO:
1554                            switch (out.strength) {
1555
1556                            case STRONG:
1557                                bit_value = 0;
1558                                break;
1559
1560                            case RESISTIVE:
1561                                bit_value = 3;
1562                                break;
1563
1564                            case HI_IMPEDANCE:
1565                                bit_value = 6;
1566                                break;
1567
1568                            case UNDETERMINED:
1569                                bit_value = 9;
1570                                break;
1571                            }
1572                            break;
1573
1574                        case ONE:
1575                            switch (out.strength) {
1576
1577                            case STRONG:
1578                                bit_value = 1;
1579                                break;
1580
1581                            case RESISTIVE:
1582                                bit_value = 4;
1583                                break;
1584
1585                            case HI_IMPEDANCE:
1586                                bit_value = 7;
1587                                break;
1588
1589                            case UNDETERMINED:
1590                                bit_value = 10;
1591                                break;
1592                            }
1593                            break;
1594
1595                        case UNKNOWN:
1596                            switch (out.strength) {
1597
1598                            case STRONG:
1599                                bit_value = 2;
1600                                break;
1601
1602                            case RESISTIVE:
1603                                bit_value = 5;
1604                                break;
1605
1606                            case HI_IMPEDANCE:
1607                                bit_value = 8;
1608                                break;
1609
1610                            case UNDETERMINED:
1611                                bit_value = 11;
1612                                break;
1613                            }
1614                            break;
1615
1616                        }
1617*/
1618
1619                        /*** Store this bit value ***/
1620
1621                        cm_store_bits_value(states,i,j,bit_value);
1622
1623                    }
1624
1625                    for (j=0; j<(2 + states->num_inputs); j++) {
1626
1627                        token = CNVget_token(&s, &type);
1628
1629
1630                        if ( j < states->num_inputs ) {
1631
1632                            /* preset this bit location */
1633                            bit_value = 3;
1634
1635                            if (0 == strcmp(token,"0")) bit_value = 0;
1636                            if (0 == strcmp(token,"1")) bit_value = 1;
1637                            if (0 == strcmp(token,"x")) bit_value = 2;
1638                            if (0 == strcmp(token,"X")) bit_value = 2;
1639
1640                            /* if this bit was not recognized, return with an error  */
1641                            if (3 == bit_value) {
1642                                return 1;
1643                            }
1644                            else { /* need to store this value in the inputs[] array */
1645
1646                                cm_store_inputs_value(states,i,j,bit_value);
1647
1648                            }
1649                        }
1650                        else { /* obtain next_state value */
1651
1652                            if ( states->num_inputs == j ) {
1653                                /* skip the "->" token */
1654                            }
1655                            else {
1656
1657                                /* convert to a floating point number... */
1658                                cnv_get_spice_value(token,&number);
1659
1660                                states->next_state[i] = (int) number;
1661                            }
1662                        }
1663                    }
1664
1665                }
1666                i++;
1667            }
1668            s = temp;
1669        }
1670    }
1671    return 0;
1672}
1673
1674
1675
1676
1677
1678/*==============================================================================
1679
1680FUNCTION cm_d_state()
1681
1682AUTHORS
1683
1684    17 Jun 1991     Jeffrey P. Murray
1685
1686MODIFICATIONS
1687
1688    20 Aug 1991     Jeffrey P. Murray
1689    30 Sep 1991     Jeffrey P. Murray
1690
1691SUMMARY
1692
1693    This function implements the d_state code model.
1694
1695INTERFACES
1696
1697    FILE                 ROUTINE CALLED
1698
1699    CMmacros.h           cm_message_send();
1700
1701    CMevt.c              void *cm_event_alloc()
1702                         void *cm_event_get_ptr()
1703
1704RETURNED VALUE
1705
1706    Returns inputs and outputs via ARGS structure.
1707
1708GLOBAL VARIABLES
1709
1710    NONE
1711
1712NON-STANDARD FEATURES
1713
1714    NONE
1715
1716==============================================================================*/
1717
1718/*=== CM_D_STATE ROUTINE ==============*/
1719
1720/************************************************
1721*      The following is the model for the       *
1722*   digital state machine for the               *
1723*   ATESSE Version 2.0 system.                  *
1724*                                               *
1725*   Created 7/17/91                             *
1726*   Last Modified 8/20/91         J.P.Murray    *
1727************************************************/
1728
1729
1730void cm_d_state(ARGS)
1731{
1732    int                    i,   /* generic loop counter index */
1733                           j,   /* generic loop counter index */
1734                         err=0,   /* integer for storage of error status  */
1735                        test;   /* testing integer  */
1736
1737    State_Table_t    *states,   /* pointer to base address structure
1738                                   for all state arrays. *states
1739                                   contains the pointers to
1740                                   state[], bits[], input[]
1741                                   and next_state[] arrays. These
1742                                   arrays are allocated using
1743                                   calloc, so they do not take up
1744                                   rotational storage space...only
1745                                   the *states structure does this. */
1746                     *states_old;
1747    FILE         *state_file;   /* pointer to the state.in input
1748                                   vector file */
1749
1750    Digital_t                 in,   /* storage for each input bit */
1751                             out;   /* storage for each output bit */
1752
1753    Digital_State_t         *clk,   /* storage for clock value  */
1754                        *clk_old,   /* previous clock value     */
1755                          *reset,   /* current reset value  */
1756                      *reset_old;   /* previous reset value  */
1757
1758
1759
1760    char   temp[MAX_STRING_SIZE],   /* holding string variable for testing
1761                                       input from state.in */
1762                              *s;   /* main string variable */
1763
1764    char *open_error = "\nERROR\n  D_STATE: failed to open state file.\n";
1765
1766    char *loading_error = "\nERROR\n  D_STATE: state file was not read successfully. \n  The most common cause of this problem is a\n  trailing blank line in the state.in file \n";
1767
1768    char *index_error = "\nERROR\n  D_STATE: An error exists in the ordering of states values\n  in the states->state[] array. This is usually caused \n  by non-contiguous state definitions in the state.in file \n";
1769/*    char buf[100];*/
1770
1771
1772
1773
1774
1775    /****** Setup required state variables ******/
1776
1777    if(INIT) {  /* initial pass */
1778
1779
1780        /*** open file and count the number of vectors in it ***/
1781        state_file = fopen_with_path( PARAM(state_file), "r");
1782
1783        /* increment counter if not a comment until EOF reached... */
1784        i = 0;
1785        s = temp;
1786        if (state_file!=NULL)
1787            while ( fgets(s,MAX_STRING_SIZE,state_file) != NULL) {
1788                if ( '*' != s[0] ) {
1789                    while(isspace_c(*s) || (*s == '*'))
1790                        (s)++;
1791                    if ( *s != '\0' ) i++;
1792                }
1793                s = temp;
1794            }
1795
1796        /*** allocate storage for *states... ***/
1797
1798        cm_event_alloc(0,sizeof(State_Table_t));
1799        states = states_old = (State_Table_t *) cm_event_get_ptr(0,0);
1800
1801        /* Store depth value */
1802        states->depth = i;
1803
1804        /* Retrieve widths for bits[] and inputs[] */
1805        states->num_inputs = PORT_SIZE(in);
1806        states->num_outputs = PORT_SIZE(out);
1807
1808
1809        /* assign storage for arrays to pointers in states table    */
1810        states->state = (int *) calloc((size_t) (states->depth + 1), sizeof(int));
1811        states->bits = (short *) calloc((size_t) (states->num_outputs * states->depth / 4 + 1), sizeof(short));
1812        states->inputs = (short *) calloc((size_t) (states->num_inputs * states->depth / 8 + 1), sizeof(short));
1813        states->next_state = (int *) calloc((size_t) (states->depth + 1), sizeof(int));
1814
1815
1816        /* Initialize *state, *bits, *inputs & *next_state to zero  */
1817        for (i=0; i<states->depth; i++) {
1818            states->state[i] = 0;
1819            states->next_state[i] = 0;
1820        }
1821        for (i=0; i<(test=(states->num_outputs * states->depth)/4); i++) states->bits[i] = 0;
1822        for (i=0; i<(test=(states->num_inputs * states->depth)/8); i++) states->inputs[i] = 0;
1823
1824
1825
1826        /*** allocate storage for *clk, *clk_old, *reset & *reset_old... ***/
1827        cm_event_alloc(1,sizeof(Digital_State_t));
1828
1829        cm_event_alloc(2,sizeof(Digital_State_t));
1830
1831        /* fetch states again, it might have moved per realloc */
1832        states = states_old = (State_Table_t *) cm_event_get_ptr(0,0);
1833        clk = clk_old = (Digital_State_t *) cm_event_get_ptr(1,0);
1834        reset = reset_old = (Digital_State_t *) cm_event_get_ptr(2,0);
1835
1836        /*** Send file pointer and the four storage pointers      ***/
1837        /*** to "cm_read_state_file()". This will return after    ***/
1838        /*** reading the contents of state.in, and if no          ***/
1839        /*** errors have occurred, the "*state" and "*bits"       ***/
1840        /*** "*inputs", and "*next_state" vectors will be loaded  ***/
1841        /*** and the num_inputs, num_outputs and depth            ***/
1842        /*** values supplied.                                     ***/
1843
1844        if (state_file) {
1845            rewind(state_file);
1846            err = cm_read_state_file(state_file,states);
1847        } else {
1848            err = 2;
1849        }
1850
1851        if (err == 1) /* problem occurred in load...send error msg. */
1852            cm_message_send(loading_error);
1853        else if (err == 2)  /* problem opening the state file...send error msg. */
1854            cm_message_send(open_error);
1855
1856        if (err > 0) {
1857            /* Reset arrays to zero */
1858            for (i=0; i<states->depth; i++) {
1859                states->state[i] = 0;
1860                states->next_state[i] = 0;
1861            }
1862            for (i=0; i<(test=(states->num_outputs * states->depth)/4); i++) states->bits[i] = 0;
1863            for (i=0; i<(test=(states->num_inputs * states->depth)/8); i++) states->inputs[i] = 0;
1864
1865            return;
1866        }
1867
1868        /* close state_file */
1869        if (state_file)
1870            fclose(state_file);
1871
1872
1873        /* declare load values */
1874
1875        // for (i=0; i<states->num_outputs; i++) {
1876        for (i=0; i<states->num_inputs; i++) {
1877            LOAD(in[i]) = PARAM(input_load);
1878        }
1879
1880        LOAD(clk) = PARAM(clk_load);
1881
1882        if ( !PORT_NULL(reset) ) {
1883            LOAD(reset) = PARAM(reset_load);
1884        }
1885
1886    }
1887    else {  /**** Retrieve previous values ****/
1888
1889        states = (State_Table_t *) cm_event_get_ptr(0,0);
1890		states_old = (State_Table_t *) cm_event_get_ptr(0,1);
1891		// Copy storage
1892		*states = *states_old;
1893
1894        clk = (Digital_State_t *) cm_event_get_ptr(1,0);
1895        clk_old = (Digital_State_t *) cm_event_get_ptr(1,1);
1896
1897        reset = (Digital_State_t *) cm_event_get_ptr(2,0);
1898        reset_old = (Digital_State_t *) cm_event_get_ptr(2,1);
1899
1900    }
1901
1902
1903
1904    /******* Determine analysis type and output appropriate values *******/
1905
1906    if ( 0.0 == TIME ) {   /****** DC analysis...output w/o delays ******/
1907
1908        /* set current state to default */
1909        states->current_state = PARAM(reset_state);
1910
1911        /* set indices for this state   */
1912        err = cm_set_indices(states);
1913        if ( err == TRUE ) {
1914            cm_message_send(index_error);
1915            return;
1916        }
1917
1918
1919        /* Output new values... */
1920        for (i=0; i<states->num_outputs; i++) {
1921
1922            /* retrieve output value */
1923            cm_get_bits_value(states,states->index0,i,&out);
1924
1925            OUTPUT_STATE(out[i]) = out.state;
1926            OUTPUT_STRENGTH(out[i]) = out.strength;
1927        }
1928    }
1929
1930    else {      /****** Transient Analysis ******/
1931
1932        /*** load current input values if reset
1933             is not connected, set to zero... ***/
1934        *clk = INPUT_STATE(clk);
1935
1936        if ( PORT_NULL(reset) ) {
1937            *reset = *reset_old = ZERO;
1938        }
1939        else {
1940            *reset = INPUT_STATE(reset);
1941        }
1942
1943
1944
1945        /***** Find input that has changed... *****/
1946
1947        /**** Test reset value for change ****/
1948        if ( *reset != *reset_old ) { /* either reset or reset release */
1949            switch ( *reset ) {
1950
1951            case ONE:
1952                states->current_state = PARAM(reset_state);
1953
1954                /* set indices for this state   */
1955                err = cm_set_indices(states);
1956                if ( err == TRUE ) {
1957                    cm_message_send(index_error);
1958                    return;
1959                }
1960
1961                /* Output new values... */
1962                for (i=0; i<states->num_outputs; i++) {
1963
1964                    /* retrieve output value */
1965                    cm_get_bits_value(states,states->index0,i,&out);
1966
1967                    OUTPUT_STATE(out[i]) = out.state;
1968                    OUTPUT_STRENGTH(out[i]) = out.strength;
1969                    OUTPUT_DELAY(out[i]) = PARAM(reset_delay);
1970                }
1971                break;
1972
1973            case ZERO:
1974            case UNKNOWN:
1975                /* output remains at current value */
1976                for (i=0; i<states->num_outputs; i++) {
1977                    OUTPUT_CHANGED(out[i]) = FALSE;
1978                }
1979                break;
1980
1981            }
1982        }
1983        else {
1984
1985            if ( ONE != *reset ) {
1986                /**** model is not held to reset value ****/
1987                /**** Test clk value for change ****/
1988                if (*clk != *clk_old) { /* clock or clock release */
1989                    switch ( *clk ) {
1990
1991                    case ONE:
1992
1993                        /** active edge...need to find out if a match   **/
1994                        /**   exists between the current inputs and     **/
1995                        /**   any of the inputs which drive the state   **/
1996                        /**   machine to the next state...if so, we     **/
1997                        /**   will need to retrieve that state value,   **/
1998                        /**   and set the new index boundaries...       **/
1999
2000                        /* for each of the entries for the current_state... */
2001                        for (i=states->index0; i<=states->indexN; i++) {
2002
2003                            /* first set err to zero... */
2004                            err = 0;
2005
2006                            /* for each bit of the inputs value for this
2007                               entry...*/
2008                            for (j=0; j<states->num_inputs; j++) {
2009
2010                                /* retrieve the current input bit... */
2011                                in.state = INPUT_STATE(in[j]);
2012
2013                                /* ...& compare to the corresponding
2014                                   inputs[i] value. */
2015                                err = cm_compare_to_inputs(states,i,j,in.state);
2016
2017                                /* break if comparison was no-good... */
2018                                if ( 0 != err ) break;
2019
2020                            }
2021
2022                            /* if the comparison of the entire input
2023                               word was good, break out of this loop too... */
2024                            if ( 0 == err ) break;
2025                        }
2026
2027                        /* if err == 0, then a match was found...otherwise,
2028                           we will not change states... */
2029
2030                        if ( 0 == err ) {
2031
2032                            /* use "i" to retrieve the next state value:
2033                               store this into current_state... */
2034                            states->current_state = states->next_state[i];
2035
2036                            /* set indices for this new state   */
2037                            err = cm_set_indices(states);
2038                            if ( err == TRUE ) {
2039                                cm_message_send(index_error);
2040                                return;
2041                            }
2042
2043                            /* Output new values... */
2044                            for (i=0; i<states->num_outputs; i++) {
2045
2046                                /* retrieve output value */
2047                                cm_get_bits_value(states,states->index0,i,&out);
2048
2049                                OUTPUT_STATE(out[i]) = out.state;
2050                                OUTPUT_STRENGTH(out[i]) = out.strength;
2051                                OUTPUT_DELAY(out[i]) = PARAM(clk_delay);
2052                            }
2053
2054                        }
2055                        else { /* no change in state or in output */
2056
2057                            for (i=0; i<states->num_outputs; i++) {
2058                                OUTPUT_CHANGED(out[i]) = FALSE;
2059                            }
2060
2061                        }
2062
2063                        break;
2064
2065                    case ZERO:
2066                    case UNKNOWN:
2067
2068                        /* no change in state or in output */
2069                        for (i=0; i<states->num_outputs; i++) {
2070                            OUTPUT_CHANGED(out[i]) = FALSE;
2071                        }
2072
2073                        break;
2074                    }
2075                }
2076                else {   /* input value must have changed...
2077                            return previous output value.    */
2078
2079                    for (i=0; i<states->num_outputs; i++) {
2080                        OUTPUT_CHANGED(out[i]) = FALSE;
2081                    }
2082                }
2083            }
2084            else {   /* Reset is active...
2085                        return previous output values.    */
2086
2087                for (i=0; i<states->num_outputs; i++) {
2088                    OUTPUT_CHANGED(out[i]) = FALSE;
2089                }
2090
2091            }
2092        }
2093    }
2094}
2095
2096
2097
2098