circuit

Download: netlist4.zip

See

circuit.h
circuit.cpp
sysbuild.cpp

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