📄 gates.cpp
字号:
#include <iostream>
#include <sstream>
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<Wire *>& in, const tvector<Wire *>& 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<Wire *> 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<Wire *> 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<Wire *> 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<Wire *> 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<Wire *> 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<Wire *> wires;
CompositeGate * copy = new CompositeGate();
SimpleMap<Wire *, Wire *> 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<Wire *> 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();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -