Download: netlist4.zip
See
circuit.h
#pragma once #include <assert.h> #include <string> using namespace std; class eObj { public: string name; eObj() { } eObj(string str) { name=str; } eObj(const char *str) { name=str; } }; class eNode: public eObj { public: double value; bool defined; static const double high, low; eNode(): value(0), defined(false) { } eNode(string str): value(0), defined(false), eObj(str) { } double &v() { return value; } bool isDefined() { return defined; } bool isHigh() { return value<low; } bool isLow() { return value>high; } char getLogic() { if (!defined) return 'X'; if (isLow()) return '0'; else if (isHigh()) return '1'; else return 'X'; } void set(double v) { defined = true; value = v; } }; class eDevice: public eObj { public: string *nodes; int *ndx; double x, y; double orientation; double value; eDevice() { }; eDevice(int n); virtual ~eDevice(); virtual int getNodeCount() const = 0; virtual string getType() const = 0; virtual string codeString() const = 0; virtual int getCode() const = 0; // virtual int eval(eNode *nodes[]) { printf("inside eDevice\n"); return 0; } // virtual void draw(CDC &dc) const = 0; void parse(string tok[], int ntokens); void parse_value(string tok); }; class Resistor: public eDevice { public: Resistor(): eDevice(2) { } int getNodeCount() const { return 2; } string getType() const { return "resistor"; } string codeString() const { return code(); } static char * code() { return "R"; } int getCode() const { return *(int *)code(); } // void draw(CDC &dc) const; }; class Capacitor: public eDevice { public: Capacitor(): eDevice(2) { } int getNodeCount() const { return 2; } string getType() const { return "capacitor"; } string codeString() const { return code(); } static char * code() { return "C"; } int getCode() const { return *(int *)code(); } // void draw(CDC &dc) const; }; class Inductor: public eDevice { public: Inductor(): eDevice(2) { } int getNodeCount() const { return 2; } string getType() const { return "inductor"; } string codeString() const { return code(); } static char * code() { return "L"; } int getCode() const { return *(int *)code(); } // void draw(CDC &dc) const; }; class CurrentSource: public eDevice { public: CurrentSource(): eDevice(2) { } int getNodeCount() const { return 2; } string getType()const { return "current source"; } string codeString() const { return code(); } static char * code() { return "I"; } int getCode() const { return *(int *)code(); } // void draw(CDC &dc) const; }; class VoltageSource: public eDevice { public: VoltageSource(): eDevice(2) { } int getNodeCount() const { return 2; } string getType() const { return "voltage source"; } string codeString() const { return code(); } static char *code() { return "V"; } int getCode() const { return *(int *)code(); } }; class VCCS: public eDevice { public: VCCS(): eDevice(4) { } int getNodeCount() const { return 4; } string getType() const { return "voltage-controlled current source (G)"; } string codeString() const { return code(); } static char *code() { return "VCCS"; } int getCode() const { return *(int *)code(); } }; class eCircuit: public eObj { public: eNode **nodes; int maxnodes, ncount; eDevice **devices; int maxdevs, ndevices; static const int BLOCKSIZE; eCircuit() { create(BLOCKSIZE,BLOCKSIZE); } ~eCircuit(); void create(int node_count, int device_count); void clear(); void read(FILE *in); void list_nodes(); void list_devices(); void build_node_list(); eDevice *doAnalog(string type); eDevice *doDigital(string type); int add_device(eDevice *pdev); int add_node(string str); eNode *find_node(string str); void sysbuild(); // void draw(CDC &dc); // logic simulation int cycles; //void reset(); void reset_nodes(); int eval(); int run(); };
circuit.cpp
//#include "stdafx.h" #include <stdlib.h> #include <iostream> #include "circuit.h" using namespace std; char *strtrm(char *str, char delimiter); char *strtoken(char* &inp, char delimiter); const double eNode::high = 0.7; const double eNode::low = 0.3; const int eCircuit::BLOCKSIZE = 8; eDevice::eDevice(int n) { nodes = new string[n]; ndx = new int[n]; value = 0.0; x = y = orientation = 0.0; } eDevice::~eDevice() { if (nodes) delete [] nodes; nodes = 0; } const string suffix("afpnumkKMGT"); const double scales[] = {1e-18, 1e-15, 1e-12, 1e-9, 1e-6, 1e-3, 1e3, 1e3, 1e6, 1e9, 1e12}; void eDevice::parse_value(string tok) { char c=0; sscanf_s(tok.c_str(),"%lg%c",&value,&c); if (c) { size_t pos = suffix.find(c); if (pos>=0) value *= scales[pos]; } } void eDevice::parse(string tok[], int ntokens) { int n = getNodeCount(); assert(ntokens>n+1); name = tok[1]; for (int j=0; j<n; j++) { nodes[j] = tok[2+j]; } n += 2; // logic may not have value!! but would have location if (ntokens<n) return; if (tok[n][0]!='[') parse_value(tok[n++]); if (ntokens<n) return; x = y = orientation = 0; if (tok[n][0]=='[') { char c=0; sscanf_s(tok[n++].c_str()+1,"%lg",&x); if (ntokens<n) return; sscanf_s(tok[n++].c_str(),"%lg%c",&y,&c); if (c==']') return; else if (ntokens<n) return; else sscanf_s(tok[n++].c_str(),"%lg",&orientation); } } void eCircuit::create(int n_nodes,int n_devices) { maxnodes = n_nodes; maxdevs = n_devices; nodes = new eNode *[maxnodes]; devices = new eDevice *[maxdevs]; ncount = ndevices = 0; } void eCircuit::clear() { int i; for (i=0; i<ncount; i++) delete nodes[i]; for (i=0; i<ndevices; i++) delete devices[i]; ncount = ndevices = 0; } eCircuit::~eCircuit() { clear(); if (nodes) delete [] nodes; if (devices) delete [] devices; } eDevice *eCircuit::doAnalog(string type) { if (type==Resistor::code()) return new Resistor(); if (type==CurrentSource::code()) return new CurrentSource(); if (type==VoltageSource::code()) return new VoltageSource(); if (type==Capacitor::code()) return new Capacitor(); if (type==Inductor::code()) return new Inductor(); if (type==VCCS::code()) return new VCCS(); return 0; } void eCircuit::read(FILE *in) { char buf[512]; char *inp, *token; bool done = false; int lines = 0; clear(); while (!done) { fgets(buf,511,in); if (feof(in)) return; lines++; strtrm(buf,'\n'); // terminate at newline character printf("%2d: %s\n",lines, buf); strtrm(buf,'%'); // terminate at comment character int ntokens=0; inp = buf; string tok[16]; while ((token=strtoken(inp,' '))!=0) { tok[ntokens++] = token; //printf("token %d: %s\n",n,token); } if (ntokens==0) continue; eDevice *dp; dp = doAnalog(tok[0]); //if (!dp) dp = doDigital(tok[0]); if (!dp) { printf("unrecognized device: %s\n",tok[0].c_str()); continue; } dp->parse(tok,ntokens); add_device(dp); } } int eCircuit::add_device(eDevice *pdev) { if (ndevices>=maxdevs) { maxdevs+= BLOCKSIZE; eDevice **tmp = new eDevice *[maxdevs]; for (int i=0; i<ndevices; i++) tmp[i] = devices[i]; delete [] devices; devices = tmp; } devices[ndevices] = pdev; return ndevices++; } eNode * eCircuit::find_node(string str) { for (int i=0; i<ncount; i++) { if (nodes[i]->name==str) return nodes[i]; } return 0; } int eCircuit::add_node(string str) { int i; if (str=="0") return -1; // ground (reference) node for (i=0; i<ncount; i++) { if (nodes[i]->name==str) return i; } if (ncount>=maxnodes) { maxnodes += BLOCKSIZE; eNode **tmp = new eNode *[maxnodes]; for (i=0; i<ncount; i++) tmp[i] = nodes[i]; delete [] nodes; nodes = tmp; } eNode *node = new eNode(str); nodes[ncount] = node; return ncount++; } void eCircuit::build_node_list() { int i, j, n; for (i=0; i<ndevices; i++) { eDevice &dev = *devices[i]; n = dev.getNodeCount(); string s = dev.getType(); for (j=0; j<n; j++) dev.ndx[j] = add_node(dev.nodes[j]); } } void eCircuit::list_nodes() { for (int i=0; i<ncount; i++) { cout << i << " " << nodes[i]->name << endl; } } void eCircuit::list_devices() { for (int i=0; i<ndevices; i++) { eDevice &dev = *devices[i]; string s = dev.codeString() + " " + dev.name + " nodes "; printf("%s",s.c_str()); for (int j=0; j<dev.getNodeCount(); j++) //printf("%s ",dev.nodes[j].c_str()); printf("%d ",dev.ndx[j]); printf("\tvalue %g",dev.value); if (dev.x || dev.y) printf(" loc[%g %g]",dev.x,dev.y); if (dev.orientation) printf(" rotate %g\n",dev.orientation); else printf("\n"); } }
Maintained by John Loomis, updated Wed Feb 21 17:43:43 2007