Third batch of added files.
This commit is contained in:
parent
758bedc716
commit
f1c81d40f7
|
|
@ -0,0 +1,426 @@
|
|||
/* Spice hooks */
|
||||
#include <ngspice.h>
|
||||
#ifdef CLUSTER
|
||||
#include <inpdefs.h>
|
||||
#include "cluster.h"
|
||||
#include <cktdefs.h>
|
||||
#include <gendefs.h>
|
||||
|
||||
/* Misc stuff */
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
/*Network stuff*/
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
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;i<connections;i++) {
|
||||
curr = (struct input_pipe *)tmalloc(sizeof(struct input_pipe));
|
||||
if(input_pipes)
|
||||
curr->next = 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
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
/**********
|
||||
Copyright 1992 Regents of the University of California. All rights
|
||||
reserved.
|
||||
Author: 1992 Charles Hough
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#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;
|
||||
}
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
/**********
|
||||
Copyright 1992 Regents of the University of California. All rights
|
||||
reserved.
|
||||
Author: 1992 Charles Hough
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#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;
|
||||
}
|
||||
Loading…
Reference in New Issue