diff --git a/src/spicelib/analysis/cluster.c b/src/spicelib/analysis/cluster.c new file mode 100755 index 000000000..d2c090a93 --- /dev/null +++ b/src/spicelib/analysis/cluster.c @@ -0,0 +1,426 @@ +/* Spice hooks */ +#include +#ifdef CLUSTER +#include +#include "cluster.h" +#include +#include + +/* Misc stuff */ +#include +#include + +/*Network stuff*/ +#include +#include +#include +#include +#include + + +struct input_pipe { + /*the names of the local and remote nodes*/ + char remote[32]; + char local[32]; + int fd; + FILE *stream; + /* the data recieved */ + double time; + double data; + /*resistance of this link*/ + double res; + /* The value controled */ + double *currentPtr; + /*The output it is linked to*/ + struct output_pipe *link; + struct input_pipe *next; +}; + +struct output_pipe { + int fd; + FILE *stream; + /*the names of the local and remote nodes*/ + char local[32]; + char remote[32]; + /* The index of the local node value in the ckt->CKTrhsOld array */ + int outIndex; + /*Last values sent*/ + double time,data; + struct input_pipe *link; + struct output_pipe *next; +}; + +static double lastTimeSent=0; + +static int time_sock=0; +static FILE *time_outfile=NULL; +static FILE *time_infile=NULL; + +static struct input_pipe* input_pipes=NULL; +static struct output_pipe* output_pipes=NULL; + +/* sets up deamon which waits for connections + *and sets up input pipes as it recieves them */ +static void *start_listener(void *); + +/* Setup the output pipes*/ +static int setup_output(CKTcircuit *ckt); +static int setup_input(CKTcircuit *ckt); +static int setup_time(); + +int CLUsetup(CKTcircuit *ckt){ + pthread_t tid; + struct input_pipe *curr; + int i, connections=0; + GENmodel *mod; + GENinstance *inst; + + /* count the number of connections expected */ + i = INPtypelook("Isource"); + for(mod = (GENmodel *)ckt->CKThead[i]; + mod != NULL; + mod = mod->GENnextModel) + for (inst = mod->GENinstances; + inst != NULL; + inst = inst->GENnextInstance) + if(strncmp("ipcx",inst->GENname,4) == 0) + connections++; + + /* allocate the input connections */ + for(i=0;inext = input_pipes; + else + curr->next = NULL; + input_pipes = curr; + } + + pthread_create(&tid,NULL,start_listener,(void *)&connections); + setup_output(ckt); + pthread_join(tid,NULL); + setup_input(ckt); + setup_time(); + return 0; +} + +#include "../devices/isrc/isrcdefs.h" +/*Connect to remote machine and find the data*/ +static int setup_output(CKTcircuit *ckt){ + int type; + GENmodel *mod; + GENinstance *inst; + char hostname[64]; + + lastTimeSent = 0; + type = INPtypelook("Isource"); + + for(mod = (GENmodel *)ckt->CKThead[type]; + mod != NULL; + mod = mod->GENnextModel) + + for (inst = mod->GENinstances; + inst != NULL; + inst = inst->GENnextInstance) + + if(strncmp("ipcx",inst->GENname,4) == 0){ + ISRCinstance *isrc = (ISRCinstance *)inst; + CKTnode *node; + struct output_pipe *curr; + struct sockaddr_in address; + struct hostent *host=NULL; + int sock,nodeNum,i; + + /*Create the struct*/ + curr = (struct output_pipe *)tmalloc(sizeof(struct output_pipe)); + if(output_pipes) + curr->next = output_pipes; + else + curr->next = NULL; + output_pipes = curr; + + /* The node names */ + strcpy(curr->local,CKTnodName(ckt,isrc->ISRCnegNode));/*weird*/ + strcpy(curr->remote,isrc->ISRCname); + + /* extract remote node number */ + nodeNum = /*Xcoord*/(curr->remote[4] - '0') * CLUSTER_WIDTH + + /*Ycoord*/(curr->remote[9] - '0'); + sprintf(hostname,"n%d."DOMAIN_NAME,nodeNum); + + /* network stuff */ + host = gethostbyname(hostname); + if(!host){ + printf("Host not found in setup_output\n"); + exit(0); + } + + if((sock = socket(PF_INET,SOCK_STREAM,0)) < 0){ + printf("Socket open in setup_output\n"); + exit(0); + } + + address.sin_family = AF_INET; + address.sin_port = htons(PORT); + memcpy(&address.sin_addr,host->h_addr_list[0], + sizeof(address.sin_addr)); + + printf("connecting to %s ...... ",hostname); + fflush(stdout); + + while(connect(sock,(struct sockaddr *)&address,sizeof(address))){ + usleep(500);/*wait for the sever to start*/ + } + + printf("connected\n"); + + curr->fd = sock; + + /* send stuff */ + /* buffer */ + i = (strlen(curr->remote) + strlen(curr->local) + 2)*sizeof(char); + setsockopt(sock,SOL_SOCKET,SO_SNDBUF,&i,sizeof(i)); + + curr->stream = fdopen(curr->fd,"w"); + + fwrite(curr->remote,sizeof(char),strlen(curr->remote),curr->stream); + fputc('\0',curr->stream); + fwrite(curr->local,sizeof(char),strlen(curr->local),curr->stream); + fputc('\0',curr->stream); + fflush(curr->stream); + + /* buffer, what is done per time point */ + i = sizeof(double)*2; + setsockopt(sock,SOL_SOCKET,SO_SNDBUF,&i,sizeof(i)); + + /* find the index in ckt->rhsOld which contains the local node */ + i = 0; + for(node = ckt->CKTnodes->next;node;node = node->next){ + i++; + if(strcmp(node->name,curr->local)==0){ + curr->outIndex = i; + goto next; + } + } + printf("Local node %s not found\n",curr->local); + exit(0); + next: + + } + return 0; +} + +/*Processes the connections recieved by start_listener*/ +static int setup_input(CKTcircuit *ckt){ + int type; + GENmodel *mod; + GENinstance *inst; + struct input_pipe *input; + type = INPtypelook("Isource"); + + for(input = input_pipes;input;input = input->next){ + int i; + + input->stream = fdopen(input->fd,"r"); + + /*Get the local and remote node names*/ + i=0; + do { + while(fread(&input->local[i],sizeof(char),1,input->stream) != 1); + }while(input->local[i++] != '\0'); + + i=0; + do { + while(fread(&input->remote[i],sizeof(char),1,input->stream) != 1); + }while(input->remote[i++] != '\0'); + + /* initilise */ + input->time = -1; + + /*Find the Isource to control*/ + for(mod = (GENmodel *)ckt->CKThead[type]; + mod != NULL; + mod = mod->GENnextModel) + + for (inst = mod->GENinstances; + inst != NULL; + inst = inst->GENnextInstance) + + if(strcmp(input->remote,&inst->GENname[11]) == 0){ + + ISRCinstance *isrc = (ISRCinstance *)inst; + input->res = isrc->ISRCdcValue; + isrc->ISRCdcValue = 0; + input->currentPtr = &isrc->ISRCdcValue; + goto next; + } + /* We get here if no Isource matches */ + printf("Current source %s not found\n",input->remote); + exit(0); + + next: + + /* Now find the corresponding output */ + { + struct output_pipe *output; + for(output = output_pipes;output;output = output->next) + if(strcmp(&input->local[11],output->local)==0){ + input->link = output; + output->link = input; + goto next2; + } + printf("Parent to %s not found\n",&input->local[11]); + exit(0); + next2: + } + } + return 0; +} + +/* This starts a server and waits for connections, number given by argument*/ +static void *start_listener(void *v){ + int *connections = (int *)v; + int count=0; + struct sockaddr_in address; + int sock, conn,i; + size_t addrLength = sizeof(struct sockaddr_in); + struct input_pipe *curr; + + if((sock = socket(PF_INET,SOCK_STREAM,0)) < 0){ + printf("socket in start_listener\n"); + exit(0); + } + + /* Allow reuse of the socket */ + i = 1; + setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i)); + + /* port, inferface ..*/ + address.sin_family = AF_INET; + address.sin_port = htons(PORT); + memset(&address.sin_addr,0,sizeof(address.sin_addr)); + + if(bind(sock, (struct sockaddr *)&address,sizeof(address))){ + printf("bind in start_listener\n"); + exit(0); + } + if(listen(sock,5)){ + printf("listen in start_listener\n"); + exit(0); + } + + /* Loop till recieved all connections */ + curr = input_pipes; + while (count < *connections){ + if((conn = accept(sock, (struct sockaddr *)&address,&addrLength)) < 0){ + printf("accept in start_listener\n"); + exit(0); + } + + curr->fd = conn; + /* will fill rest of structure later in setup_input*/ + count ++; + curr = curr->next; + } + + close(sock); + + return NULL; +} + +/*Writes data to remote computer*/ +int CLUoutput(CKTcircuit *ckt){ + struct output_pipe *output; + lastTimeSent = ckt->CKTtime; + for(output = output_pipes; + output; + output = output->next){ + output->time = ckt->CKTtime; + output->data = ckt->CKTrhsOld[output->outIndex]; + fwrite(&output->time,sizeof(double),1,output->stream); + fwrite(&output->data, + sizeof(double),1,output->stream); + fflush(output->stream); + } + return 0; +} + +/*Maniputates the local circuit based on the links*/ +int CLUinput(CKTcircuit *ckt){ + struct input_pipe *input; + double tmp; + for(input= input_pipes;input;input = input->next){ + /*recieve data till we get a good time point*/ + while (input->time < lastTimeSent){ + while(fread(&input->time, sizeof(double), 1, input->stream) != 1){} + while(fread(&input->data, sizeof(double), 1, input->stream) != 1){} + } + tmp = (input->link->data - input->data) / input->res; + + /*dampen out large currents*/ + if(tmp > 0) + *input->currentPtr = 0.2 * (1 - exp(-tmp/0.2)); + else + *input->currentPtr = -0.2 * (1 - exp(tmp/0.2)); + + /*GND is the posNode, local node is the negNode*/ + } + return 0; +} + +static int setup_time(){ + struct sockaddr_in address; + struct hostent *host=NULL; + char *hostname = TIME_HOST; + int sock,i; + + /* network stuff */ + host = gethostbyname(hostname); + if(!host){ + printf("Host not found in setup_time\n"); + exit(0); + } + if((sock = socket(PF_INET,SOCK_STREAM,0)) < 0){ + printf("Socket open in setup_time\n"); + exit(0); + } + + i = sizeof(double)*2; + setsockopt(sock,SOL_SOCKET,SO_SNDBUF ,&i,sizeof(i)); + + address.sin_family = AF_INET; + address.sin_port = htons(TIME_PORT); + memcpy(&address.sin_addr,host->h_addr_list[0], + sizeof(address.sin_addr)); + + + while(connect(sock,(struct sockaddr *)&address,sizeof(address))){ + usleep(500);/*wait for the sever to start*/ + } + time_sock=sock; + time_outfile=fdopen(sock,"w"); + time_infile=fdopen(sock,"r"); + + return 0; +} + + +int CLUsync(double time,double *delta, int error){ + double tmp; + if(error) + tmp = *delta * (-1); + else + tmp = *delta; + fwrite(&time,sizeof(double),1,time_outfile); + fwrite(&tmp,sizeof(double),1,time_outfile); + fflush(time_outfile); + while(fread(&tmp,sizeof(double),1,time_infile) != 1); + if(tmp < 0){ + *delta = -tmp; + return 0; + } else { + *delta = tmp; + return 1; + } +} +#endif diff --git a/src/spicelib/parser/inp2p.c b/src/spicelib/parser/inp2p.c new file mode 100644 index 000000000..72e12341b --- /dev/null +++ b/src/spicelib/parser/inp2p.c @@ -0,0 +1,131 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void +INP2P(ckt,tab,current) + void *ckt; + INPtables *tab; + card *current; + +{ + +int mytype; /* the type we determine cpls are */ +int type; /* the type the model says it is */ +char *line; /* the part of the current line left to parse */ +char *name, *tempname; /* the cpl's name */ +char *model; /* the name of the cpl's model */ +char **nname1; /* the first node's name */ +char **nname2; /* the second node's name */ +char *ground; +void **node1; /* the first node's node pointer */ +void **node2; /* the second node's node pointer */ +void *groundnode; +int error; /* error code temporary */ +int error1; /* secondary error code temporary */ +INPmodel *thismodel; /* pointer to model structure describing our model */ +void *mdfast; /* pointer to the actual model */ +void *fast; /* pointer to the actual instance */ +IFvalue ptemp; /* a value structure to package cpl into */ +IFuid uid; /* uid for default model */ +double lenval = 0; +int lenvalgiven = 0; +int num, i; + + mytype = INPtypelook("CplLines"); + if(mytype < 0 ) { + LITERR("Device type CplLines not supported by this binary\n") + return; + } + line = current->line; + INPgetTok(&line,&name,1); + INPinsert(&name,tab); + /* num = (int) INPevaluate(&line,&error1,1); */ + num = 0; + + /* first pass to determine the dimension */ + while (*line != '\0') { + INPgetTok(&line, &tempname,1); + if (strcmp(tempname, "len") == 0) break; + num ++; + } + num = (num - 2) / 2; + line = current->line; + INPgetTok(&line,&name,1); + + nname1 = (char **) malloc(num * sizeof(char *)); + nname2 = (char **) malloc(num * sizeof(char *)); + node1 = (void **) malloc(num * sizeof(void *)); + node2 = (void **) malloc(num * sizeof(void *)); + + + for (i = 0; i < num; i++) { + INPgetNetTok(&line,&(nname1[i]),1); + INPtermInsert(ckt,&(nname1[i]),tab,&(node1[i])); + } + INPgetTok(&line,&ground,1); + INPtermInsert(ckt,&ground,tab,&groundnode); + for (i = 0; i < num; i++) { + INPgetNetTok(&line,&(nname2[i]),1); + INPtermInsert(ckt,&(nname2[i]),tab,&(node2[i])); + } + INPgetTok(&line,&ground,1); + INPtermInsert(ckt,&ground,tab,&groundnode); + + INPgetTok(&line,&model,1); + if (strcmp(model, "len") == 0) { + lenval = INPevaluate(&line,&error1,1); + lenvalgiven = 1; + INPgetTok(&line,&model,1); + } + if(*model) { /* token isn't null */ + INPinsert(&model,tab); + thismodel = (INPmodel *)NULL; + current->error = INPgetMod(ckt,model,&thismodel,tab); + if(thismodel != NULL) { + if(mytype != thismodel->INPmodType) { + LITERR("incorrect model type") + return; + } + mdfast = thismodel->INPmodfast; + type = thismodel->INPmodType; + } else { + type = mytype; + if(!tab->defPmod) { + /* create default P model */ + IFnewUid(ckt,&uid,(IFuid)NULL,"P",UID_MODEL,(void**)NULL); + IFC(newModel, (ckt,type,&(tab->defPmod),uid)) + } + mdfast = tab->defPmod; + } + IFC(newInstance,(ckt,mdfast,&fast,name)) + } else { + LITERR("model name is not found") + return; + } + + /* IFC(bindNode,(ckt,fast,1,fakename)) */ + + ptemp.iValue = num; + GCA(INPpName,("dimension", &ptemp,ckt,type,fast)) + ptemp.v.vec.sVec = nname1; + GCA(INPpName,("pos_nodes", &ptemp,ckt,type,fast)) + ptemp.v.vec.sVec = nname2; + GCA(INPpName,("neg_nodes", &ptemp,ckt,type,fast)) + if (error1 == 0 && lenvalgiven) { + ptemp.rValue = lenval; + GCA(INPpName,("length",&ptemp,ckt,type,fast)) + } + + return; +} diff --git a/src/spicelib/parser/inp2y.c b/src/spicelib/parser/inp2y.c new file mode 100644 index 000000000..3eb63a176 --- /dev/null +++ b/src/spicelib/parser/inp2y.c @@ -0,0 +1,236 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void +INP2Y(ckt,tab,current) + void *ckt; + INPtables *tab; + card *current; + +{ +/* parse a txl card */ +/* Yxxxx node1 node2 name */ + +int mytype; /* the type to determine txl */ +int mytype2; /* the type to determine cpl */ +int type; /* the type the model says it is */ +char *line; /* the part of the current line left to parse */ +char *name; /* the resistor's name */ +char *buf; /* temporary buffer for parsing */ +char *model; /* the name of the resistor's model */ +char *nname1; /* the first node's name */ +char *nname2; /* the second node's name */ +char rname1[10], rname2[10], rname3[10]; +char cname1[10], cname2[10], cname3[10], cname4[10]; +char *internal1, *internal2; +char *ground1, *ground2; +void *node1; /* the first node's node pointer */ +void *node2; /* the second node's node pointer */ +void *gnode1, *gnode2, *inode1, *inode2; +int error; /* error code temporary */ +int error1; /* secondary error code temporary */ +INPmodel *thismodel; /* pointer to model structure describing our model */ +void *mdfast; /* pointer to the actual model */ +void *fast; /* pointer to the actual instance */ +void *mdfast2, *mdfast3, *mdfast4, *mdfast5, *mdfast6; +void *fast2, *fast3, *fast4, *fast5, *fast6; +IFuid uid; /* uid for default model */ +GENinstance *txl; +IFvalue ptemp; /* a value structure to package into */ +double lval=0, rval=0, cval=0, lenval=0; +int lenvalgiven = 0; + + mytype = INPtypelook("TransLine"); + mytype2 = INPtypelook("CplLines"); + + if(mytype < 0 ) { + LITERR("Device type TransLine not supported by this binary\n") + return; + } + line = current->line; + INPgetTok(&line,&name,1); + INPinsert(&name,tab); + INPgetNetTok(&line,&nname1,1); + INPtermInsert(ckt,&nname1,tab,&node1); + INPgetNetTok(&line,&ground1,1); + INPtermInsert(ckt,&ground1,tab,&gnode1); + INPgetNetTok(&line,&nname2,1); + INPtermInsert(ckt,&nname2,tab,&node2); + INPgetNetTok(&line,&ground2,1); + INPtermInsert(ckt,&ground2,tab,&gnode2); + + INPgetTok(&line,&model,1); + if (strcmp(model, "len") == 0) { + lenval = INPevaluate(&line,&error1,1); + lenvalgiven = 1; + INPgetTok(&line,&model,1); + } + if(*model) { /* token isn't null */ + INPinsert(&model,tab); + thismodel = (INPmodel *)NULL; + current->error = INPgetMod(ckt,model,&thismodel,tab); + if(thismodel != NULL) { + if (thismodel->INPmodType == mytype2) { + INP2P(ckt,tab,current); + return; + } + else if (mytype != thismodel->INPmodType) { + LITERR("incorrect model type") + return; + } + line = thismodel->INPmodLine->line; + INPgetTok(&line,&buf,1); /* throw out .model */ + INPgetTok(&line,&buf,1); /* throw out model name */ + INPgetTok(&line,&buf,1); /* throw out txl */ + INPgetTok(&line,&buf,1); + while (*line != '\0') { + if (*buf == 'R' || *buf == 'r') { + INPgetTok(&line,&buf,1); + rval = atof(buf); + } + if ((strcmp(buf,"L") == 0) || (strcmp(buf,"l") == 0)) { + INPgetTok(&line,&buf,1); + lval = atof(buf); + } + if ((strcmp(buf,"C") == 0) || (strcmp(buf,"c") == 0)) { + INPgetTok(&line,&buf,1); + cval = atof(buf); + } + if (lenvalgiven == 0) { + if (strcmp(buf,"length")== 0) { + INPgetTok(&line,&buf,1); + lenval = atof(buf); + } + } + INPgetTok(&line,&buf,1); + } + if (lenval && rval && lval && rval/lval > 1.6e10) { + /* use 3-pi model */ + rval = 3.0 / (rval * lenval); + cval = cval * lenval / 6.0; + + type = INPtypelook("Resistor"); + + /* resistor between node1 and internal1 */ + internal1 = (char *) malloc (10); + strcpy(internal1, "txlnd1"); + INPtermInsert(ckt, &internal1, tab, &inode1); + if(!tab->defRmod) { + /* create default R model */ + IFnewUid(ckt,&uid,(IFuid)NULL,"R",UID_MODEL,(void**)NULL); + IFC(newModel, (ckt,type,&(tab->defRmod),uid)) + } + mdfast = tab->defRmod; + strcpy(rname1, "txlres1"); + IFC(newInstance,(ckt,mdfast,&fast,rname1)) + IFC(bindNode,(ckt,fast,1,node1)) + IFC(bindNode,(ckt,fast,2,inode1)) + ptemp.rValue = rval; + GCA(INPpName,("resistance",&ptemp,ckt,type,fast)) + + /* resistor between internal1 and internal2 */ + internal2 = (char *) malloc (10); + strcpy(internal2, "txlnd2"); + INPtermInsert(ckt, &internal2, tab, &inode2); + strcpy(rname2, "txlres2"); + mdfast2 = tab->defRmod; + IFC(newInstance,(ckt,mdfast2,&fast2,rname2)) + IFC(bindNode,(ckt,fast2,1,inode1)) + IFC(bindNode,(ckt,fast2,2,inode2)) + ptemp.rValue = rval; + GCA(INPpName,("resistance",&ptemp,ckt,type,fast2)) + + /* resistor between internal2 and node2 */ + strcpy(rname3, "txlres3"); + mdfast3 = tab->defRmod; + IFC(newInstance,(ckt,mdfast3,&fast3,rname3)) + IFC(bindNode,(ckt,fast3,1,inode2)) + IFC(bindNode,(ckt,fast3,2,node2)) + ptemp.rValue = rval; + GCA(INPpName,("resistance",&ptemp,ckt,type,fast3)) + + /* capacitor on node1 */ + type = INPtypelook("Capacitor"); + if(!tab->defCmod) { + IFnewUid(ckt,&uid,(IFuid)NULL,"C",UID_MODEL,(void**)NULL); + IFC(newModel,(ckt,type,&(tab->defCmod),uid)) + } + mdfast4 = tab->defCmod; + strcpy(cname1, "txlcap1"); + IFC(newInstance,(ckt,mdfast4,&fast4,cname1)) + IFC(bindNode,(ckt,fast4,1,node1)) + IFC(bindNode,(ckt,fast4,2,gnode1)) + ptemp.rValue = cval; + GCA(INPpName,("capacitance",&ptemp,ckt,type,fast4)) + + /* capacitor on internal1 */ + strcpy(cname2, "txlcap2"); + mdfast4 = tab->defCmod; + IFC(newInstance,(ckt,mdfast4,&fast4,cname2)) + IFC(bindNode,(ckt,fast4,1,inode1)) + IFC(bindNode,(ckt,fast4,2,gnode1)) + ptemp.rValue = cval * 2; + GCA(INPpName,("capacitance",&ptemp,ckt,type,fast4)) + + /* capacitor on internal2 */ + strcpy(cname3, "txlcap3"); + mdfast5 = tab->defCmod; + IFC(newInstance,(ckt,mdfast5,&fast5,cname3)) + IFC(bindNode,(ckt,fast5,1,inode2)) + IFC(bindNode,(ckt,fast5,2,gnode1)) + ptemp.rValue = cval * 2; + GCA(INPpName,("capacitance",&ptemp,ckt,type,fast5)) + + /* capacitor on node2 */ + strcpy(cname4, "txlcap4"); + mdfast6 = tab->defCmod; + IFC(newInstance,(ckt,mdfast6,&fast6,cname4)) + IFC(bindNode,(ckt,fast6,1,node2)) + IFC(bindNode,(ckt,fast6,2,gnode1)) + ptemp.rValue = cval; + GCA(INPpName,("capacitance",&ptemp,ckt,type,fast6)) + return; + + } + + /* use regular txl model */ + mdfast = thismodel->INPmodfast; + type = thismodel->INPmodType; + } else { + type = mytype; + if(!tab->defYmod) { + /* create default Y model */ + IFnewUid(ckt,&uid,(IFuid)NULL,"Y",UID_MODEL,(void**)NULL); + IFC(newModel, (ckt,type,&(tab->defYmod),uid)) + } + mdfast = tab->defYmod; + } + IFC(newInstance,(ckt,mdfast,&fast,name)) + } else { + LITERR("model name is not found") + return; + } + + if (error1 == 0 && lenvalgiven) { + ptemp.rValue = lenval; + GCA(INPpName,("length",&ptemp,ckt,type,fast)) + } + + IFC(bindNode,(ckt,fast,1,node1)) + IFC(bindNode,(ckt,fast,2,node2)) + + txl = (GENinstance *)fast; + + return; +}