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