radec/src/Simulation.cpp

210 lines
4.7 KiB
C++
Raw Normal View History

#include "Simulation.h"
2017-04-24 21:09:38 -04:00
#include <iostream>
#include <iomanip>
bool Simulation::parseCircuit(string fileName)
{
ifstream in;
in.open(fileName + ".txt");
if (in.fail()) {
cerr << endl << fileName << ".txt could not be opened :(";
2017-04-23 20:15:12 -04:00
return false;
}
string tmpString, tmpType;
int tmp1, tmp2, tmp3;
Wire *tmpWire;
Gate *tmpGate;
2017-04-23 20:15:12 -04:00
// get rid of first line
getline(in, tmpString);
while (true) {
if (!(in >> tmpType)) break;
if (!(in >> tmpString)) break;
if (!(in >> tmp1)) break;
2017-04-24 19:36:08 -04:00
if (tmpType == "INPUT" || tmpType == "OUTPUT") {
tmpWire = findWire(tmp1);
tmpWire->convertToIO(tmpString);
}
else if (tmpType == "NOT") {
in >> tmp2;
tmpGate = new NotGate(getDelay(tmpString), findWire(tmp1),
findWire(tmp2));
// push gate onto Simulation gates vector
gates.push_back(tmpGate);
// also push gate onto input wire's gate vector
findWire(tmp1)->addGate(tmpGate);
}
else if (tmpType == "AND") {
in >> tmp2;
in >> tmp3;
tmpGate = new AndGate(getDelay(tmpString), findWire(tmp1), findWire(tmp2),
findWire(tmp3));
gates.push_back(tmpGate);
findWire(tmp1)->addGate(tmpGate);
findWire(tmp2)->addGate(tmpGate);
}
else if (tmpType == "NAND") {
in >> tmp2;
in >> tmp3;
tmpGate = new NandGate(getDelay(tmpString), findWire(tmp1),
findWire(tmp2), findWire(tmp3));
gates.push_back(tmpGate);
findWire(tmp1)->addGate(tmpGate);
findWire(tmp2)->addGate(tmpGate);
}
else if (tmpType == "OR") {
in >> tmp2;
in >> tmp3;
tmpGate = new OrGate(getDelay(tmpString), findWire(tmp1), findWire(tmp2),
findWire(tmp3));
gates.push_back(tmpGate);
findWire(tmp1)->addGate(tmpGate);
findWire(tmp2)->addGate(tmpGate);
}
else if (tmpType == "XOR") {
in >> tmp2;
in >> tmp3;
tmpGate = new XorGate(getDelay(tmpString), findWire(tmp1), findWire(tmp2),
findWire(tmp3));
gates.push_back(tmpGate);
findWire(tmp1)->addGate(tmpGate);
findWire(tmp2)->addGate(tmpGate);
}
else if (tmpType == "NOR") {
in >> tmp2;
in >> tmp3;
tmpGate = new NorGate(getDelay(tmpString), findWire(tmp1), findWire(tmp2),
findWire(tmp3));
gates.push_back(tmpGate);
findWire(tmp1)->addGate(tmpGate);
findWire(tmp2)->addGate(tmpGate);
}
else if (tmpType == "XNOR") {
in >> tmp2;
in >> tmp3;
tmpGate = new XnorGate(getDelay(tmpString), findWire(tmp1), findWire(tmp2),
findWire(tmp3));
gates.push_back(tmpGate);
findWire(tmp1)->addGate(tmpGate);
findWire(tmp2)->addGate(tmpGate);
}
}
2017-04-23 20:15:12 -04:00
return true;
}
2017-04-23 20:43:08 -04:00
bool Simulation::parseVector(string fileName) {
2017-04-23 20:15:12 -04:00
ifstream in;
in.open(fileName + "_v.txt");
if (in.fail()) {
cerr << endl << fileName << "_v.txt could not be opened :(";
return false;
}
string tmpString;
int timeInt, valInt;
2017-04-24 22:14:00 -04:00
Wire *tmpWire = nullptr;
2017-04-23 20:15:12 -04:00
// get rid of first line
getline(in, tmpString);
while(true) {
if (!(in >> tmpString)) break;
if (!(in >> tmpString)) break;
2017-04-25 09:08:16 -04:00
if (!(in >> timeInt)) break;
if (!(in >> valInt)) break;
2017-04-23 20:15:12 -04:00
for(auto i = wires.begin(); i != wires.end(); ++i) {
2017-04-23 20:44:45 -04:00
if((**i).getName() == tmpString) {
2017-04-23 20:43:08 -04:00
tmpWire = *i;
2017-04-23 20:15:12 -04:00
}
}
e.push(Event(valInt, timeInt, tmpWire));
2017-04-23 20:15:12 -04:00
}
}
2017-04-24 20:14:22 -04:00
void Simulation::simulate() {
// loop through event queue
while(!e.empty()) {
bool changed;
2017-04-24 20:14:22 -04:00
Wire * output;
Event tmpEvent = e.top();
output = tmpEvent.getOutput();
changed = output->doesChange(tmpEvent.getValue(), tmpEvent.getTime());
2017-04-24 20:14:22 -04:00
// if the wire value changes, evaluate gates
if(changed && !(tmpEvent.getTime() > 60)) {
2017-04-24 20:14:22 -04:00
Gate * tmpGate;
Event gateEvent(-1, -1, nullptr);
2017-04-24 20:14:22 -04:00
int index = 0;
2017-04-24 22:14:00 -04:00
while(true){
2017-04-24 20:14:22 -04:00
tmpGate = output->getGate(index++);
2017-04-24 22:14:00 -04:00
if (tmpGate != nullptr) {
gateEvent = tmpGate->evaluate(tmpEvent.getTime());
e.push(gateEvent);
2017-04-24 22:14:00 -04:00
}
else {
break;
}
}
2017-04-24 20:14:22 -04:00
}
output->setValue(tmpEvent.getValue(), tmpEvent.getTime());
e.pop();
2017-04-24 20:14:22 -04:00
}
}
void Simulation::print()
{
2017-04-24 21:09:38 -04:00
int lastTime = 0;
int tmpTime = 0;
// iterate through wires, finding wire with last event time
2017-04-24 20:24:39 -04:00
for(auto i = wires.begin(); i != wires.end(); ++i) {
if((**i).getLast() > lastTime) {
lastTime = (**i).getLast();
2017-04-24 21:09:38 -04:00
}
}
// now iterate through wires, printing each of them
for(auto i = wires.begin(); i != wires.end(); ++i) {
(**i).setLast(lastTime);
2017-04-24 22:14:00 -04:00
cout << **i;
2017-04-24 20:24:39 -04:00
}
2017-04-24 21:09:38 -04:00
int t = 0;
2017-04-24 23:06:26 -04:00
cout << setw(10) << "TIME ";
2017-04-24 21:09:38 -04:00
while(t <= 60 && t <= lastTime) {
2017-04-24 23:06:26 -04:00
cout << setw(5) << left << t;
2017-04-24 21:09:38 -04:00
t += 5;
}
}
Wire * Simulation::findWire(int n)
{
for (auto i = wires.begin(); i != wires.end(); ++i) {
if (n == (**i).getNumber()) return *i;
}
2017-04-24 19:36:08 -04:00
// if wire does not exist, create it, instantiating as an intermediary wire
Wire * tmpWire = new Wire(n, false);
wires.push_back(tmpWire);
return tmpWire;
}
int Simulation::getDelay(string d)
{
d.resize(d.size() - 2);
return atoi(d.c_str());
}