Logic Gates

See:

circuit
gates.h
gates.cpp

Devices:

inverter
buffer
and
nand
or
nor
xor
xnor
gates.h

gates.h


// gates.h

#pragma once
#include "circuit.h"

class Inverter: public eDevice
{
public:
	Inverter(): eDevice(2) { }
	int getNodeCount() const { return 2; }
	string getType() const { return "inverter"; }
	static const string code;
	string codeString() const { return code; }
	int eval(eNode *nodes[]);
};

class Buffer: public eDevice
{
public:
	Buffer(): eDevice(2) { }
	int getNodeCount() const { return 2; }
	string getType() const { return "buffer"; }
	static const string code;
	string codeString() const { return code; }
	//int eval();
};


class And: public eDevice
{
public:
	And(): eDevice(3) { }
	int getNodeCount() const { return 3; }
	string getType() const { return "and"; }
	static const string code;
	string codeString() const { return code; }
	int eval(eNode *nodes[]);
};

class Nand: public eDevice
{
public:
	Nand(): eDevice(3) { }
	int getNodeCount() const { return 3; }
	string getType() const { return "nand"; }
	static const string code;
	string codeString() const { return code; }
	int eval(eNode *nodes[]);
};

class Or: public eDevice
{
public:
	Or(): eDevice(3) { }
	int getNodeCount() const { return 3; }
	string getType() const { return "or"; }
	static const string code;
	string codeString() const { return code; }
	int eval(eNode *nodes[]);
};

class Nor: public eDevice
{
public:
	Nor(): eDevice(3) { }
	int getNodeCount() const { return 3; }
	string getType() const { return "nor"; }
	static const string code;
	string codeString() const { return code; }
	int eval(eNode *nodes[]);
};

class Xor: public eDevice
{
public:
	Xor(): eDevice(3) { }
	int getNodeCount() const { return 3; }
	string getType() const { return "xor"; }
	static const string code;
	string codeString() const { return code; }
	int eval(eNode *nodes[]);
};

class Xnor: public eDevice
{
public:
	Xnor(): eDevice(3) { }
	int getNodeCount() const { return 3; }
	string getType() const { return "xnor"; }
	static const string code;
	string codeString() const { return code; }
	int eval(eNode *nodes[]);
};


gates.cpp


// gates.cpp
#include "stdafx.h"
#include <math.h>
#include "gates.h"

const string Inverter::code = "INV";
const string Buffer::code = "BUF";
const string And::code = "AND";
const string Nand::code = "NAND";
const string Or::code = "OR";
const string Nor::code = "NOR";
const string Xor::code = "XOR";
const string Xnor::code = "XNOR";

eDevice *eCircuit::doDigital(string type)
{
	if (type==Inverter::code) return new Inverter();
	if (type==Buffer::code) return new Buffer();
	if (type==And::code) return new And();
	if (type==Nand::code) return new Nand();
	if (type==Or::code) return new Or();
	if (type==Nor::code) return new Nor();
	if (type==Xor::code) return new Xor();
	if (type==Xnor::code) return new Xnor();
	return 0;
}

int Inverter::eval(eNode *nodes[])
{
	eNode *inp = nodes[ndx[0]];
	eNode *oup = nodes[ndx[1]];
	if (!inp->isDefined()) return 1;
	double value = 0.5;
	if (inp->value<eNode::low) value = 1.0;
	else if (inp->value>eNode::high) value = 0.0;
	oup->set(value);
	return 0;
}

void eCircuit::reset_nodes()
{
	for (int i=0; i<ncount; i++) {
		eNode *node = nodes[i];
		node->defined = false;
	}
}

int eCircuit::eval()
{
	int count = 0;
	eDevice *dev;
	for (int i=0; i<ndevices; i++) {
		dev = devices[i];
		count += dev->eval(nodes);
	}
	return count;
}

int eCircuit::run()
{
	int count, prev_count;
	
	prev_count = count = eval();
	cycles=1;
	while (count) {
		count = eval();
		cycles++;
		if (count == prev_count) break;
		prev_count = count;
	}
	return count;
}


int aoi(eNode *arg[3], int in, int out)
{
	bool defined = true;
	double result = (out? 0: 1);
	eNode *node;
	for (int i=1; i<3; i++) {
		node = arg[i];
		if (!node->isDefined()) defined = false;
		else if (fabs(node->value-in)<0.2) {
			result = out;
			defined = true;
			break;
		}
	}
	if (!defined) return 1;
	arg[0]->set(result);
	return 0;
}

int And::eval(eNode *nodes[])
{
	eNode *arg[3];
	for (int i=0; i<3; i++) arg[i] = nodes[ndx[i]];
	return aoi(arg,0,0);
}

int Nand::eval(eNode *nodes[])
{
	eNode *arg[3];
	for (int i=0; i<3; i++) arg[i] = nodes[ndx[i]];
	return aoi(arg,0,1);
}
int Or::eval(eNode *nodes[])
{
	eNode *arg[3];
	for (int i=0; i<3; i++) arg[i] = nodes[ndx[i]];
	return aoi(arg,1,1);
}
int Nor::eval(eNode *nodes[])
{
	eNode *arg[3];
	for (int i=0; i<3; i++) arg[i] = nodes[ndx[i]];
	return aoi(arg,1,0);
}

int Xor::eval(eNode *nodes[])
{
	eNode *arg[3];
	for (int i=0; i<3; i++) arg[i] = nodes[ndx[i]];
	if (!arg[1]->isDefined() || !arg[2]->isDefined()) return 1;
	if (arg[1]->isLow() && arg[2]->isLow()) arg[0]->set(0.0);
	else if (arg[1]->isHigh() && arg[2]->isHigh()) arg[0]->set(0.0);
	else arg[0]->set(1.0);
	return 0;
}
int Xnor::eval(eNode *nodes[])
{
	eNode *arg[3];
	for (int i=0; i<3; i++) arg[i] = nodes[ndx[i]];
	if (!arg[1]->isDefined() || !arg[2]->isDefined()) return 1;
	if (arg[1]->isLow() && arg[2]->isLow()) arg[0]->set(1.0);
	else if (arg[1]->isHigh() && arg[2]->isHigh()) arg[0]->set(1.0);
	else arg[0]->set(0.0);
	return 0;
}


Maintained by John Loomis, updated Wed Feb 14 10:45:51 2007