diff --git a/src/xspice/Makefile.am b/src/xspice/Makefile.am index 975cbba93..f0a6d4d96 100755 --- a/src/xspice/Makefile.am +++ b/src/xspice/Makefile.am @@ -1,7 +1,4 @@ # Process this file with automake -CFLAGS = -g -O2 -Wall -CC = gcc -COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) EXTRA_DIST = README @@ -11,10 +8,5 @@ EXTRA_DIST = README SUBDIRS = mif cm enh evt ipc idn cmpp icm -INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir) - MAINTAINERCLEANFILES = Makefile.in -all: xspice.o -xspice.o: - $(COMPILE) -c xspice.c diff --git a/src/xspice/cm/Makefile.am b/src/xspice/cm/Makefile.am index 41bcc96fe..1ed131250 100755 --- a/src/xspice/cm/Makefile.am +++ b/src/xspice/cm/Makefile.am @@ -8,7 +8,8 @@ libcmxsp_a_SOURCES = \ cm.c \ cmevt.c \ cmmeters.c \ -cmutil.c +cmutil.c \ +cmexport.c diff --git a/src/xspice/cm/cmexport.c b/src/xspice/cm/cmexport.c new file mode 100755 index 000000000..397b979d0 --- /dev/null +++ b/src/xspice/cm/cmexport.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include + + +/*how annoying!, needed for structure below*/ +static void *tcalloc(size_t a, size_t b){ + return tmalloc(a*b); +} + +static void *empty(void){ + return NULL; +} + +struct coreInfo_t coreInfo = +{ + MIF_INP2A, + MIFgetMod, + MIFgetValue, + MIFsetup, + (int (*)(GENmodel *, CKTcircuit *))empty, + MIFload, + MIFmParam, + MIFask, + MIFmAsk, + MIFtrunc, + MIFconvTest, + MIFdelete, + MIFmDelete, + MIFdestroy, + MIFgettok, + MIFget_token, + MIFget_cntl_src_type, + MIFcopy, + cm_climit_fcn, + cm_smooth_corner, + cm_smooth_discontinuity, + cm_smooth_pwl, + cm_analog_ramp_factor, + cm_analog_alloc, + cm_analog_get_ptr, + cm_analog_integrate, + cm_analog_converge, + cm_analog_set_temp_bkpt, + cm_analog_set_perm_bkpt, + cm_analog_not_converged, + cm_analog_auto_partial, + cm_event_alloc, + cm_event_get_ptr, + cm_event_queue, + cm_message_get_errmsg, + cm_message_send, + cm_netlist_get_c, + cm_netlist_get_l, + cm_complex_set, + cm_complex_add, + cm_complex_subtract, + cm_complex_multiply, + cm_complex_divide, + (FILE *(*)(void))empty, + (FILE *(*)(void))empty, + (FILE *(*)(void))empty, +#ifndef HAVE_LIBGC + tmalloc, + tcalloc, + trealloc, + txfree, + (char *(*)(int))tmalloc, + (char *(*)(char *,int))trealloc, + (void (*)(char *))txfree +#else + GC_malloc, + tcalloc, + GC_realloc, + (void (*)(void *))empty, + (char *(*)(int))GC_malloc, + (char *(*)(char *,int))GC_realloc, + (void (*)(char *))empty +#endif +}; diff --git a/src/xspice/enh/enhtrans.c b/src/xspice/enh/enhtrans.c index 53cca2d49..a8153aceb 100755 --- a/src/xspice/enh/enhtrans.c +++ b/src/xspice/enh/enhtrans.c @@ -400,28 +400,41 @@ static char *two2three_translate( /* Write input nets/sources */ if((type == 'e') || (type == 'g') || - (type == 'E') || (type == 'G')) - sprintf(*inst_card + strlen(*inst_card), "%%vd [ "); - else - sprintf(*inst_card + strlen(*inst_card), "%%vnam [ "); + (type == 'E') || (type == 'G')) { /* These input port types are vector & need a [. */ + if (dim > 1) { + sprintf(*inst_card + strlen(*inst_card), "%%vd [ "); + } + else { + sprintf(*inst_card + strlen(*inst_card), "%%vd [ "); /* need something different? */ + } + } + else /* This input port type is scalar */ + sprintf(*inst_card + strlen(*inst_card), "%%vnam [ "); + for(i = 0; i < num_conns; i++) sprintf(*inst_card + strlen(*inst_card), "%s ", in_conn[i]); - sprintf(*inst_card + strlen(*inst_card), "] "); + + if (dim > 1) { + sprintf(*inst_card + strlen(*inst_card), "] "); + } + else { + sprintf(*inst_card + strlen(*inst_card), "] "); /* need something different? */ + } /* Write output nets */ if((type == 'e') || (type == 'h') || (type == 'E') || (type == 'H')) - sprintf(*inst_card + strlen(*inst_card), "%%vd [ "); + sprintf(*inst_card + strlen(*inst_card), "%%vd ( "); else - sprintf(*inst_card + strlen(*inst_card), "%%id [ "); + sprintf(*inst_card + strlen(*inst_card), "%%id ( "); for(i = 0; i < 2; i++) sprintf(*inst_card + strlen(*inst_card), "%s ", out_conn[i]); - sprintf(*inst_card + strlen(*inst_card), "] "); + sprintf(*inst_card + strlen(*inst_card), ") "); /* Write model name */ diff --git a/src/xspice/ipc/ipc.c b/src/xspice/ipc/ipc.c index 03be29fb3..b802092d3 100755 --- a/src/xspice/ipc/ipc.c +++ b/src/xspice/ipc/ipc.c @@ -71,9 +71,7 @@ SUMMARY #ifndef NDEBUG #include #endif -#include /* Specific to BSD - Use sys/fcntl.h for sys5 */ #include -#include #include #include diff --git a/src/xspice/mif/mif_inp2.c b/src/xspice/mif/mif_inp2.c index b85ef0947..518ca5e25 100755 --- a/src/xspice/mif/mif_inp2.c +++ b/src/xspice/mif/mif_inp2.c @@ -120,6 +120,32 @@ connection information is filled-in on the instance structure, and error checks are performed. */ +/*--------------- Quick summary of algorithm ----------------------- + +1. Get the spice card. Place card string into variable 'line'. +2. Get the name of the instance and add it to the symbol table +3. Locate the last token on the line and assign it to variable 'model' +4. Locate the model from pass 1. If it hasn't been processed yet, + allocate structure in ckt for it, process the parameters, and return a + pointer to its structure in 'thismodel' +5. Get model type. +6. Create a new instance structure in ckt for this instance. +------ Process the connections: here's where it gets interesting. ----- +7. Reset 'line'. Then read instance name again to go over it. +8. Read initial token. +9 Start loop through port tokens: +10. If token is a %, then read next token to get port type + and save this port type. Otherwise, use default port type. +11. Check if connection is null. If so, iterate to next conn. +12. Get next token. Depending upon token type (scalar or array) do + the following: + -- Scalar: Process it, then continue loop. + -- Array: Loop through all tokens until ] is found & process tokens. + Then continue outer loop over port tokens. +13. After looping through connection tokens, do error checks. + At this point, nothing should be left in 'line' + +-------------------------------------------------------------------------*/ void MIF_INP2A(ckt,tab,current) @@ -164,20 +190,18 @@ card *current; /* the card we are to parse */ #endif /* get the line text from the card struct */ - line = current->line; /* get the name of the instance and add it to the symbol table */ - name = MIFgettok(&line); INPinsert(&name, tab); - /* locate the last token on the line and put it into "model" */ - + /* locate the last token on the line (i.e. model name) and put it into "model" */ while(*line != '\0') model = MIFgettok(&line); + /* make sure the model name was there. */ if(model == NULL) { LITERR("Missing model on A type device"); return; @@ -186,39 +210,26 @@ card *current; /* the card we are to parse */ /* Locate model from pass 1. If it hasn't been processed yet, */ /* allocate a structure in ckt for it, process its parameters */ /* and return a pointer to its structure in 'thismodel' */ - current->error = MIFgetMod(ckt, model, &thismodel, tab); - if(current->error) { return; } -#ifdef TRACE - /* SDB debug statement */ - printf("In MIF_INP2A, after tokenizing, name = %s, model = %s\n", - name, model); -#endif - - /* get the integer index into the DEVices data array for this */ /* model */ - type = thismodel->INPmodType; - if((type >= DEVmaxnum) || DEVicesfl[type] == 0) { LITERR("Invalid model type for A type device"); return; } /* create a new structure for this instance in ckt */ - mdfast = thismodel->INPmodfast; IFC(newInstance, (ckt, mdfast,(void **)&fast, name)) /* initialize the code model specific elements of the inst struct */ - MIFinit_inst(mdfast, fast); @@ -226,46 +237,86 @@ card *current; /* the card we are to parse */ /* Process the connections */ /* *********************** */ - /* get the line text from the card struct */ - /* skipping over the name of the instance */ - /* and reading the first token following */ - + /* reset 'line', and then read instance name again. */ line = current->line; - MIFgettok(&line); - next_token = MIFget_token(&line,&next_token_type); + MIFgettok(&line); /* read instance name again . . . .*/ + + /* OK -- now &line points to the first token after + the instance name and we are ready to process the connections + (netnames) + */ - /* loop through the fixed number of connections expected */ + /* now get next token. It should be either a % token, + a [, or a connection (netname) which might be 'null'. + */ + next_token = MIFget_token(&line,&next_token_type); + /* When we enter the loop, next_token holds the first thing *after* the instance name. + Upon each iteration, we start the iteration with next_token holding + the next *unprocessed* token. + The loop proceeds through the fixed number of connections expected, as defined in the + DEVices struct. + */ for(i = 0; i < DEVices[type]->DEVpublic.num_conn; i++) { - /* there better be at least one more token besides the model name */ + /* Check that the line is not finished yet. */ if(*line == '\0') { - LITERR("Missing connections on A device"); + LITERR("Encountered end of line before all connections were found in model."); return; } + /* At this point, we have one of three possibilities: + 1. next_token holds a %, and &line points to either the port type identifier (id, vd, etc) + 2. next_token holds a netname and &line points to the thing *after* the first netname. + 3. next_token holds a [ indicating the start of an array of ports. + */ + /* prepare a pointer for fast access to info about this connection */ conn_info = &(DEVices[type]->DEVpublic.conn[i]); - /* get the default port type for this connection */ - def_port_type = conn_info->default_port_type; - def_port_type_str = conn_info->default_type; + /* Now if we had a % token, get actual info about connection type. + Otherwise use default info */ + if(next_token_type == MIF_PERCENT_TOK) { /* we found a % */ + /* get the port type identifier and check it for validity */ + next_token = MIFget_token(&line,&next_token_type); + /* Note that MIFget_port_type eats the next token and advances the token pointer in line */ + MIFget_port_type(ckt, + tab, + current, + &line, + &next_token, + &next_token_type, + &def_port_type, + &def_port_type_str, + conn_info, + &status); + if(status == MIF_ERROR) + return; + } + else { /* use the default port type for this connection */ + def_port_type = conn_info->default_port_type; + def_port_type_str = conn_info->default_type; + } + + /* At this point, next_token should be either a [ char, or should hold + the the first connection (netname) + */ /* set analog and event_driven flags on instance and model */ - if((def_port_type == MIF_DIGITAL) || (def_port_type == MIF_USER_DEFINED)) { - fast->event_driven = MIF_TRUE; - mdfast->event_driven = MIF_TRUE; + if((def_port_type == MIF_DIGITAL) || + (def_port_type == MIF_USER_DEFINED)) { + fast->event_driven = MIF_TRUE; + mdfast->event_driven = MIF_TRUE; } else { - fast->analog = MIF_TRUE; - mdfast->analog = MIF_TRUE; + fast->analog = MIF_TRUE; + mdfast->analog = MIF_TRUE; } - /* check for a null connection and continue to next connection if found */ + /* check for a null connection and continue to next connection if found */ if(next_token_type == MIF_NULL_TOK) { - /* make sure null is allowed */ if(! conn_info->null_allowed) { LITERR("NULL connection found where not allowed"); @@ -278,29 +329,32 @@ card *current; /* the card we are to parse */ /* eat the null token and continue to next connection */ next_token = MIFget_token(&line,&next_token_type); - continue; + continue; /* iterate */ } else { /* set the null flag to false */ fast->conn[i]->is_null = MIF_FALSE; } - /* process connection as appropriate for scalar or array */ + /* ===== process connection as appropriate for scalar or array ====== */ if(! conn_info->is_array) { /* a scalar connection - the simpler case */ - - /* do a couple of error checks */ + /* If we get to there, next_token should hold a netname in the port netlist. */ + /* First, do a couple of error checks */ if(next_token_type == MIF_LARRAY_TOK) { LITERR("ERROR - Scalar connection expected, [ found"); + printf("ERROR - Scalar connection expected, [ found. Returning . . ."); return; } if(next_token_type == MIF_RARRAY_TOK) { LITERR("ERROR - Unexpected ]"); + printf("ERROR - Unexpected ]. Returning . . ."); return; } /* If all OK, get the port data into the instance struct */ /* allocating the port member of the instance struct as needed */ + /* Note that MIFget_port eats next_token, and advances the &line pointer.. */ MIFget_port(ckt, tab, current, @@ -319,57 +373,38 @@ card *current; /* the card we are to parse */ return; fast->conn[i]->size = 1; - } - else { /* the connection is an array - much to be done ... */ - - /* get the leading port type for the array if any */ - /* it will distribute across all ports inside the braces */ - /* overriding the default type in the interface spec */ - if(next_token_type == MIF_PERCENT_TOK) { + /* when we leave here, next_token should hold the next, unprocessed netname */ - /* get the port type identifier and check it for validity */ - next_token = MIFget_token(&line,&next_token_type); - MIFget_port_type(ckt, - tab, - current, - &line, - &next_token, - &next_token_type, - &def_port_type, - &def_port_type_str, - conn_info, - &status); - if(status == MIF_ERROR) - return; - } - - /* check for required leading array delim character and eat it if found */ + } + else { /* ====== the connection is an array - much to be done ... ====== */ + /* At this point, the next_token should be a [ */ + /* check for required leading array delim character [ and eat it if found */ if(next_token_type != MIF_LARRAY_TOK) { LITERR("Missing [, an array connection was expected"); + printf("Missing [, an array connection was expected. Returning . . ."); return; } - else + else /* eat the [ */ next_token = MIFget_token(&line,&next_token_type); - /* get and process ports until ] is encountered */ - + /*------ get and process ports until ] is encountered ------*/ for(j = 0; (next_token_type != MIF_RARRAY_TOK) && (*line != '\0'); - j++) { + j++) { /* First, do some error checks */ - /* check for required leading array delim character */ if(next_token_type == MIF_LARRAY_TOK) { LITERR("ERROR - Unexpected [ - Arrays of arrays not allowed"); + printf("ERROR - Unexpected [ - Arrays of arrays not allowed. Returning . . ."); return; } /* If all OK, get the port nodes into the instance struct */ /* allocating the port member of the instance struct as needed */ - + /* Note that MIFget_port eats next_token and advances &line by one. */ MIFget_port(ckt, tab, current, @@ -386,16 +421,18 @@ card *current; /* the card we are to parse */ if(status == MIF_ERROR) return; - } + } /*------ end of for loop until ] is encountered ------*/ + + /* At this point, next_token should hold the next token after the + port netnames. This token should be a ]. */ - /* make sure we exited because the end of the array connection */ - /* was reached. If so, eat the closing array delimiter */ + /* make sure we exited because the end of the array connection + was reached. + */ if(*line == '\0') { LITERR("Missing ] in array connection"); return; } - else - next_token = MIFget_token(&line,&next_token_type); /* record the number of ports found for this connection */ if(j < 1) { @@ -404,12 +441,20 @@ card *current; /* the card we are to parse */ } fast->conn[i]->size = j; - } /* array connection processing */ + /* At this point, the next time we get_token, we should get a % or a net name. + We'll do that now, since when we enter the loop, we expect next_token + to hold the next unprocessed token. + */ + next_token = MIFget_token(&line,&next_token_type); + + } /* ====== array connection processing ====== */ /* be careful about putting stuff here, there is a 'continue' used */ /* in the processing of NULL connections above */ - } /* for number of connections */ + /* At this point, next_token should hold the next unprocessed token. */ + + } /******* for number of connections *******/ /* *********************** */ @@ -418,8 +463,12 @@ card *current; /* the card we are to parse */ /* check for too many connections */ - if(*line != '\0') { - LITERR("Too many connections"); + /* At this point, we should have eaten all the net connections, and left + next_token holding the model name. &line should be empty. + */ + + if(strcmp(next_token, model) != 0) { + LITERR("Too many connections -- expecting model name but encountered other tokens."); return; } @@ -477,9 +526,11 @@ card *current; /* the card we are to parse */ } } } + } + /* ********************************************************************* */ @@ -586,7 +637,17 @@ static void MIFinit_inst( /* MIFget_port_type -This function gets the port type identifier and checks it for validity. +This function gets the port type identifier and checks it for validity. It also +replaces false default information in conn_info with the real info based upon +the discovered port type string. + +When we call it, we expect that the next token type (sent from above) +should be the port type (MIF_STRING_TOK type). That is, we should be sitting right +on the def of the port type (i.e. %vnam, %vd, %id, etc.) Note that the parser +should have stripped the % already. + +Upon return, this fcn should leave next_token holding the token *after* the +port type (i.e. the thing after vnam, v, vd, id, etc). */ @@ -643,8 +704,22 @@ MIFget_port_type( LITERR("Port type is invalid"); *status = MIF_ERROR; } - else - *status = MIF_OK; + else { + + /* Fix by SDB so that the netlist parser uses the actual nature + of the port instead of the default state to decide if it is an array. */ + /* + if ( (*port_type == MIF_DIFF_VOLTAGE) || + (*port_type == MIF_DIFF_CURRENT) || + (*port_type == MIF_DIFF_CONDUCTANCE) || + (*port_type == MIF_DIFF_RESISTANCE) ) { + conn_info->is_array = 1; + } + */ + + *status = MIF_OK; + } + } @@ -658,6 +733,13 @@ MIFget_port This function processes a port being parsed, either single ended, or both connections of a differential. + +When we call this fcn, next_token should be the *first* netname in the port +net list. Depending upon the type of port, this fcn should eat the appropriate +number of net tokens. + +When we leave this fcn, next_token should hold the next token after the last +netname processed. */ @@ -687,27 +769,6 @@ MIFget_port( char *node; - /* get the leading port type if any */ - - if(*next_token_type == MIF_PERCENT_TOK) { - - /* get the port type identifier and check it for validity */ - *next_token = MIFget_token(line, next_token_type); - MIFget_port_type(ckt, - tab, - current, - line, - next_token, - next_token_type, - &def_port_type, - &def_port_type_str, - conn_info, - status); - - if(*status == MIF_ERROR) { - return; - } - } /* allocate space in the instance data struct for this port */ if(port_num == 0) { @@ -853,8 +914,8 @@ MIFget_port( case MIF_CONDUCTANCE: case MIF_RESISTANCE: /* These are single ended types, so default other node to ground */ - // This don't work dickhead, INPtermInsert tries to FREE(&node) K.A. Feb 27, 2000 - // which was not allocted + // This don't work dickhead, INPtermInsert tries to FREE(&node) K.A. Feb 27, 2000 + // which was not allocted node = (char*)malloc(2);// added by K.A. march 5th 2000 *node = '0'; // added by K.A. March 5th 2000