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