📄 cfunc.mod
字号:
} } else { /* obtain next_state value */ if ( states->num_inputs == j ) { /* skip the "->" token */ } else { /* convert to a floating point number... */ cnv_get_spice_value(token,&number); states->next_state[i] = number; } } } } i++; } s = temp; } } return 0;} /*==============================================================================FUNCTION cm_d_state()AUTHORS 17 Jun 1991 Jeffrey P. MurrayMODIFICATIONS 20 Aug 1991 Jeffrey P. Murray 30 Sep 1991 Jeffrey P. MurraySUMMARY This function implements the d_state code model.INTERFACES FILE ROUTINE CALLED CMmacros.h cm_message_send(); CMevt.c void *cm_event_alloc() void *cm_event_get_ptr()RETURNED VALUE Returns inputs and outputs via ARGS structure.GLOBAL VARIABLES NONENON-STANDARD FEATURES NONE==============================================================================*//*=== CM_D_STATE ROUTINE ==============*//************************************************* The following is the model for the ** digital state machine for the ** ATESSE Version 2.0 system. ** ** Created 7/17/91 ** Last Modified 8/20/91 J.P.Murray *************************************************/void cm_d_state(ARGS) { int i, /* generic loop counter index */ j, /* generic loop counter index */ err=0, /* integer for storage of error status */ test; /* testing integer */ State_Table_t *states, /* pointer to base address structure for all state arrays. *states contains the pointers to state[], bits[], input[] and next_state[] arrays. These arrays are allocated using calloc, so they do not take up rotational storage space...only the *states structure does this. */ *states_old; FILE *state_file; /* pointer to the state.in input vector file */ Digital_t in, /* storage for each input bit */ out; /* storage for each output bit */ Digital_State_t *clk, /* storage for clock value */ *clk_old, /* previous clock value */ *reset, /* current reset value */ *reset_old; /* previous reset value */ char temp[MAX_STRING_SIZE], /* holding string variable for testing input from state.in */ *s; /* main string variable */ char *open_error = "\n***ERROR***\nD_STATE: failed to open state file.\n"; char *loading_error = "\n***ERROR***\nD_STATE: state file was not read successfully. \nThe most common cause of this problem is a\ntrailing blank line in the state.in file \n"; char *index_error = "\n***ERROR***\nD_STATE: An error exists in the ordering of states values\n in the states->state[] array. This is usually caused \nby non-contiguous state definitions in the state.in file \n"; char buf[100]; /****** Setup required state variables ******/ if(INIT) { /* initial pass */ /*** open file and count the number of vectors in it ***/ state_file = fopen( PARAM(state_file), "r"); /* increment counter if not a comment until EOF reached... */ i = 0; s = temp; if (state_file!=NULL) while ( fgets(s,MAX_STRING_SIZE,state_file) != NULL) { if ( '*' != s[0] ) { while(isspace(*s) || (*s == '*')) (s)++; if ( *s != '\0' ) i++; } s = temp; } /*** allocate storage for *states... ***/ states = states_old = (State_Table_t *) cm_event_alloc(0,sizeof(State_Table_t)); /* Store depth value */ states->depth = i; /* Retrieve widths for bits[] and inputs[] */ states->num_inputs = PORT_SIZE(in); states->num_outputs = PORT_SIZE(out); /* assign storage for arrays to pointers in states table */ states->state = (int *) calloc(states->depth + 1,sizeof(int)); states->bits = (short *) calloc((states->num_outputs * states->depth / 4 + 1),sizeof(short)); states->inputs = (short *) calloc((states->num_inputs * states->depth / 8 + 1),sizeof(short)); states->next_state = (int *) calloc(states->depth + 1,sizeof(int)); /* Initialize *state, *bits, *inputs & *next_state to zero */ for (i=0; i<states->depth; i++) { states->state[i] = 0; states->next_state[i] = 0; } for (i=0; i<(test=(states->num_outputs * states->depth)/4); i++) states->bits[i] = 0; for (i=0; i<(test=(states->num_inputs * states->depth)/8); i++) states->inputs[i] = 0; /*** allocate storage for *clk, *clk_old, *reset & *reset_old... ***/ clk = clk_old = (Digital_State_t *) cm_event_alloc(1,sizeof(Digital_State_t)); reset = reset_old = (Digital_State_t *) cm_event_alloc(2,sizeof(Digital_State_t)); states = states_old = (State_Table_t *) cm_event_get_ptr(0,0); clk = clk_old = (Digital_State_t *) cm_event_get_ptr(1,0); reset = reset_old = (Digital_State_t *) cm_event_get_ptr(2,0); /*** Send file pointer and the four storage pointers ***/ /*** to "cm_read_state_file()". This will return after ***/ /*** reading the contents of state.in, and if no ***/ /*** errors have occurred, the "*state" and "*bits" ***/ /*** "*inputs", and "*next_state" vectors will be loaded ***/ /*** and the num_inputs, num_outputs and depth ***/ /*** values supplied. ***/ if (state_file) { rewind(state_file); err = cm_read_state_file(state_file,states); } else { err = 1; } if (err) { /* problem occurred in load...send error msg. */ cm_message_send(loading_error); /* Reset arrays to zero */ for (i=0; i<states->depth; i++) { states->state[i] = 0; states->next_state[i] = 0; } for (i=0; i<(test=(states->num_outputs * states->depth)/4); i++) states->bits[i] = 0; for (i=0; i<(test=(states->num_inputs * states->depth)/8); i++) states->inputs[i] = 0; return; } /* close state_file */ if (state_file) fclose(state_file); /* declare load values */ // for (i=0; i<states->num_outputs; i++) { for (i=0; i<states->num_inputs; i++) { LOAD(in[i]) = PARAM(input_load); } LOAD(clk) = PARAM(clk_load); LOAD(reset) = PARAM(reset_load); } else { /**** Retrieve previous values ****/ states = (State_Table_t *) cm_event_get_ptr(0,0); states_old = (State_Table_t *) cm_event_get_ptr(0,1); // Copy storage *states = *states_old; clk = (Digital_State_t *) cm_event_get_ptr(1,0); clk_old = (Digital_State_t *) cm_event_get_ptr(1,1); reset = (Digital_State_t *) cm_event_get_ptr(2,0); reset_old = (Digital_State_t *) cm_event_get_ptr(2,1); } /******* Determine analysis type and output appropriate values *******/ if ( 0.0 == TIME ) { /****** DC analysis...output w/o delays ******/ /* set current state to default */ states->current_state = PARAM(reset_state); /* set indices for this state */ err = cm_set_indices(states); if ( err == TRUE ) { cm_message_send(index_error); return; } /* Output new values... */ for (i=0; i<states->num_outputs; i++) { /* retrieve output value */ cm_get_bits_value(states,states->index0,i,&out); OUTPUT_STATE(out[i]) = out.state; OUTPUT_STRENGTH(out[i]) = out.strength; } } else { /****** Transient Analysis ******/ /*** load current input values if reset is not connected, set to zero... ***/ *clk = INPUT_STATE(clk); if ( PORT_NULL(reset) ) { *reset = *reset_old = ZERO; } else { *reset = INPUT_STATE(reset); } /***** Find input that has changed... *****/ /**** Test reset value for change ****/ if ( *reset != *reset_old ) { /* either reset or reset release */ switch ( *reset ) { case ONE: states->current_state = PARAM(reset_state); /* set indices for this state */ err = cm_set_indices(states); if ( err == TRUE ) { cm_message_send(index_error); return; } /* Output new values... */ for (i=0; i<states->num_outputs; i++) { /* retrieve output value */ cm_get_bits_value(states,states->index0,i,&out); OUTPUT_STATE(out[i]) = out.state; OUTPUT_STRENGTH(out[i]) = out.strength; OUTPUT_DELAY(out[i]) = PARAM(reset_delay); } break; case ZERO: case UNKNOWN: /* output remains at current value */ for (i=0; i<states->num_outputs; i++) { OUTPUT_CHANGED(out[i]) = FALSE; } break; } } else { if ( ONE != *reset ) { /**** model is not held to reset value ****/ /**** Test clk value for change ****/ if (*clk != *clk_old) { /* clock or clock release */ switch ( *clk ) { case ONE: /** active edge...need to find out if a match **/ /** exists between the current inputs and **/ /** any of the inputs which drive the state **/ /** machine to the next state...if so, we **/ /** will need to retrieve that state value, **/ /** and set the new index boundaries... **/ /* for each of the entries for the current_state... */ for (i=states->index0; i<=states->indexN; i++) { /* first set err to zero... */ err = 0; /* for each bit of the inputs value for this entry...*/ for (j=0; j<states->num_inputs; j++) { /* retrieve the current input bit... */ in.state = INPUT_STATE(in[j]); /* ...& compare to the corresponding inputs[i] value. */ err = cm_compare_to_inputs(states,i,j,in.state); /* break if comparison was no-good... */ if ( 0 != err ) break; } /* if the comparison of the entire input word was good, break out of this loop too... */ if ( 0 == err ) break; } /* if err == 0, then a match was found...otherwise, we will not change states... */ if ( 0 == err ) { /* use "i" to retrieve the next state value: store this into current_state... */ states->current_state = states->next_state[i]; /* set indices for this new state */ err = cm_set_indices(states); if ( err == TRUE ) { cm_message_send(index_error); return; } /* Output new values... */ for (i=0; i<states->num_outputs; i++) { /* retrieve output value */ cm_get_bits_value(states,states->index0,i,&out); OUTPUT_STATE(out[i]) = out.state; OUTPUT_STRENGTH(out[i]) = out.strength; OUTPUT_DELAY(out[i]) = PARAM(clk_delay); } } else { /* no change in state or in output */ for (i=0; i<states->num_outputs; i++) { OUTPUT_CHANGED(out[i]) = FALSE; } } break; case ZERO: case UNKNOWN: /* no change in state or in output */ for (i=0; i<states->num_outputs; i++) { OUTPUT_CHANGED(out[i]) = FALSE; } break; } } else { /* input value must have changed... return previous output value. */ for (i=0; i<states->num_outputs; i++) { OUTPUT_CHANGED(out[i]) = FALSE; } } } else { /* Reset is active... return previous output values. */ for (i=0; i<states->num_outputs; i++) { OUTPUT_CHANGED(out[i]) = FALSE; } } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -