#include #include using namespace std; #include "gates.h" #include "wires.h" #include "strutils.h" #include "linkset.h" #include "simplemap.h" WireFactory * Gate::ourWireFactory = new WireFactory(); Wire* Gate::WireByNumber(int num) { Wire * w = ourWireFactory->GetWire(num); return w; } ostream& operator << (ostream& out, const Gate& g) { out << g.tostring(); return out; } void Connect(Wire * w1, Wire * w2) { if (w1 != 0 && w2 != 0) { Connector * con = new Connector(w1,w2); } } int Inverter::ourCount = 0; Inverter::Inverter(Wire* in, Wire* out, const string& name) : myIn(in), myOut(out), myName(name), myNumber(ourCount) { ourCount++; in->AddGate(this); } Inverter::Inverter(const string& name) : myIn(ourWireFactory->MakeWire(name)), myOut(ourWireFactory->MakeWire(name)), myName(name), myNumber(ourCount) { ourCount++; myIn->AddGate(this); } void Inverter::Act( ) { myOut->SetSignal(! myIn->GetSignal()); } string Inverter::tostring() const { return "inv (" + ::tostring(myNumber) + ") " + myName; } Gate * Inverter::clone() { return new Inverter(myName); } string Inverter::deepString() const { ostringstream out; out << *this << "\n\tin" << *myIn << "\tout" << *myOut; out << "\n----"; return out.str(); } Connector::Connector(Wire * in, Wire * out) : myIn(in), myOut(out) { in->AddGate(this); } void Connector::Act() { myOut->SetSignal(myIn->GetSignal()); } string Connector::tostring() const { return "connector " + myIn->tostring() + " to " + myOut->tostring(); } Gate * Connector::clone() { return new Connector(myIn,myOut); } NMGate::NMGate(int number, const string& name) : myNumber(number), myName(name) { } void NMGate::Init(const tvector& in, const tvector& out) { myIns = in; myOuts = out; int k; for(k=0; k < in.size(); k++) { in[k]->AddGate(this); } } string NMGate::deepString() const { ostringstream out; out << *this << "\n\tin "; int k; for(k=0; k < myIns.size(); k++) { out << *myIns[k] << " "; } out << "\tout "; for(k=0; k < myOuts.size(); k++) { out << *myOuts[k] << " "; } out << "\n----"; return out.str(); } int AndGate::ourCount = 0; AndGate::AndGate(Wire * in, Wire* in2, Wire * out, const string& name) : NMGate(ourCount, name) { tvector ins(2), outs(1); ins[0] = in; ins[1] = in2; outs[0] = out; NMGate::Init(ins,outs); ourCount++; } AndGate::AndGate(const string& name) : NMGate(ourCount,name) { tvector ins(2), outs(1); ins[0] = ourWireFactory->MakeWire(myName); ins[1] = ourWireFactory->MakeWire(myName); outs[0] = ourWireFactory->MakeWire(myName); NMGate::Init(ins,outs); ourCount++; } Gate * AndGate::clone() { return new AndGate(myName); } void AndGate::Act( ) { myOuts[0]->SetSignal(myIns[0]->GetSignal() && myIns[1]->GetSignal()); } string AndGate::tostring() const { return "and (" + ::tostring(myNumber) + ") " + myName; } int OrGate::ourCount = 0; OrGate::OrGate(Wire * in, Wire* in2, Wire * out, const string& name) : NMGate(ourCount, name) { tvector ins(2), outs(1); ins[0] = in; ins[1] = in2; outs[0] = out; NMGate::Init(ins,outs); ourCount++; } OrGate::OrGate(const string& name) : NMGate(ourCount,name) { tvector ins(2), outs(1); ins[0] = ourWireFactory->MakeWire(myName); ins[1] = ourWireFactory->MakeWire(myName); outs[0] = ourWireFactory->MakeWire(myName); NMGate::Init(ins,outs); ourCount++; } void OrGate::Act( ) { myOuts[0]->SetSignal(myIns[0]->GetSignal() || myIns[1]->GetSignal()); } string OrGate::tostring() const { return "or (" + ::tostring(myNumber) + ") " + myName; } Gate * OrGate::clone() { return new OrGate(myName); } CompositeGate::CompositeGate() : NMGate(0, "composite") { } string CompositeGate::tostring() const { ostringstream result; result << "composite: " << myGates.size() << " gates, "; result << InCount() << " in wires, " << OutCount() << " out wires"; return result.str(); } string CompositeGate::deepString() const { ostringstream out; int k; out << *this << "\nall-in\t"; for(k=0; k < InCount(); k++) { out << *InWire(k) << " "; } out << "\nall-out\t"; for(k=0; k < OutCount(); k++) { out << *OutWire(k) << " "; } out << endl; for(k=0; k < myGates.size(); k++) { out << "\t" << myGates[k]->deepString() << endl; } out << "------"; return out.str(); } void CompositeGate::Act() { // nothing to do } void CompositeGate::AddIn(Wire * w) { myIns.push_back(w); w->AddGate(this); } void CompositeGate::AddOut(Wire * w) { myOuts.push_back(w); } void CompositeGate::AddGate(Gate * g) { myGates.push_back(g); } int CompositeGate::CountWires() const { LinkSet wires; int j,k, gCount = myGates.size(); for(j=0; j < gCount; j++) { Gate * g = myGates[j]; for(k=0; k < g->InCount(); k++) { wires.insert(g->InWire(k)); } for(k=0; k < g->OutCount(); k++) { wires.insert(g->OutWire(k)); } } for(j=0; j < InCount(); j++) { wires.insert(InWire(j)); } for(j=0; j < OutCount(); j++) { wires.insert(OutWire(j)); } return wires.size(); } Gate * CompositeGate::clone() { LinkSet wires; CompositeGate * copy = new CompositeGate(); SimpleMap map; int j,k, gCount = myGates.size(); for(j=0; j < gCount; j++) { Gate * g = myGates[j]->clone(); for(k=0; k < myGates[j]->InCount(); k++) { Wire * w = myGates[j]->InWire(k); if (! wires.contains(w)) { wires.insert(w); map.insert(w,g->InWire(k)); } else { Connect(map.getValue(w),g->InWire(k)); } } for(k=0; k < myGates[j]->OutCount();k++) { Wire * w = myGates[j]->OutWire(k); if (! wires.contains(w)) { wires.insert(w); map.insert(w,g->OutWire(k)); } else { Connect(g->OutWire(k),map.getValue(w)); } } copy->AddGate(g); } for(j=0; j < InCount(); j++) { Wire * w = InWire(j); if (! wires.contains(w)) { wires.insert(w); map.insert(w,ourWireFactory->MakeWire("clone"+w->tostring())); } } for(j=0; j < OutCount(); j++) { Wire * w = OutWire(j); if (! wires.contains(w)) { wires.insert(w); map.insert(w,ourWireFactory->MakeWire("clone"+w->tostring())); } } //cout << "found " << wires.size() << " different wires " << endl; for(k=0; k < InCount(); k++) { if (! wires.contains(InWire(k))) { cout << InWire(k)->tostring() << " not found" << endl; continue; } copy->AddIn(map.getValue(InWire(k))); } for(k=0; k < OutCount(); k++) { copy->AddOut(map.getValue(OutWire(k))); } LinkSetIterator wit(wires); for(wit.Init(); wit.HasMore(); wit.Next()) { Wire * from = wit.Current(); ConnectorIterator conit(from); for(conit.Init(); conit.HasMore(); conit.Next()) { Wire * to = conit.Current()->OutWire(0); if (wires.contains(to)) { Connect(map.getValue(from),map.getValue(to)); } } } return copy; } void GateTester::Test(Gate * gate) { int inputs = gate->InCount(); int outputs = gate->OutCount(); int limit = 1 << inputs; // 2^# inputs int j,k; cout << "testing " << gate->tostring() << endl; cout << "-----" << endl; for(k=0; k < limit; k++) { for(j=0; j < inputs; j++) { if ( ((k >> j) & 1) == 1) { gate->InWire(j)->SetSignal(true); cout << "1 "; } else { gate->InWire(j)->SetSignal(false); cout << "0 "; } } cout << "\t : \t"; for(j=0; j < outputs;j++) { cout << (gate->OutWire(j)->GetSignal() ? "1 " : "0 "); } cout << endl; } cout << "------" << endl; } Probe::Probe(Wire * w) : myWire(w) { myWire->AddGate(this); } void Probe::Act() { cout << *myWire << "\t signal= " << myWire->GetSignal() << endl; } string Probe::tostring() const { return "probe " + myWire->tostring(); }