2017-04-20 12:41:43 -04:00
|
|
|
#include "Simulation.h"
|
2017-04-24 21:09:38 -04:00
|
|
|
#include <iostream>
|
|
|
|
#include <iomanip>
|
2017-04-20 12:41:43 -04:00
|
|
|
|
2017-04-20 13:01:04 -04:00
|
|
|
bool Simulation::parseCircuit(string fileName)
|
2017-04-20 12:41:43 -04:00
|
|
|
{
|
|
|
|
ifstream in;
|
2017-04-20 13:01:04 -04:00
|
|
|
in.open(fileName + ".txt");
|
2017-04-20 12:41:43 -04:00
|
|
|
if (in.fail()) {
|
|
|
|
cerr << endl << fileName << ".txt could not be opened :(";
|
2017-04-23 20:15:12 -04:00
|
|
|
return false;
|
2017-04-20 12:41:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
string tmpString, tmpType;
|
|
|
|
int tmp1, tmp2, tmp3;
|
2017-04-23 19:29:29 -04:00
|
|
|
Wire *tmpWire;
|
|
|
|
Gate *tmpGate;
|
2017-04-23 20:15:12 -04:00
|
|
|
|
|
|
|
// get rid of first line
|
2017-04-20 12:41:43 -04:00
|
|
|
getline(in, tmpString);
|
|
|
|
|
|
|
|
while (!in.eof()) {
|
2017-04-20 13:01:04 -04:00
|
|
|
in >> tmpType;
|
|
|
|
in >> tmpString;
|
|
|
|
in >> tmp1;
|
2017-04-20 12:41:43 -04:00
|
|
|
|
2017-04-24 19:36:08 -04:00
|
|
|
if (tmpType == "INPUT" || tmpType == "OUTPUT") {
|
|
|
|
tmpWire = findWire(tmp1);
|
|
|
|
tmpWire->convertToIO(tmpString);
|
2017-04-20 12:41:43 -04:00
|
|
|
}
|
|
|
|
else if (tmpType == "NOT") {
|
2017-04-20 13:01:04 -04:00
|
|
|
in >> tmp2;
|
2017-04-23 19:29:29 -04:00
|
|
|
tmpGate = new NotGate(getDelay(tmpString), findWire(tmp1),
|
2017-04-20 12:41:43 -04:00
|
|
|
findWire(tmp2));
|
|
|
|
gates.push_back(tmpGate);
|
|
|
|
}
|
|
|
|
else if (tmpType == "AND") {
|
2017-04-20 13:01:04 -04:00
|
|
|
in >> tmp2;
|
|
|
|
in >> tmp3;
|
2017-04-23 19:29:29 -04:00
|
|
|
tmpGate = new AndGate(getDelay(tmpString), findWire(tmp1), findWire(tmp2),
|
2017-04-20 12:41:43 -04:00
|
|
|
findWire(tmp3));
|
|
|
|
gates.push_back(tmpGate);
|
|
|
|
}
|
|
|
|
else if (tmpType == "NAND") {
|
2017-04-20 13:01:04 -04:00
|
|
|
in >> tmp2;
|
|
|
|
in >> tmp3;
|
2017-04-23 19:29:29 -04:00
|
|
|
tmpGate = new NandGate(getDelay(tmpString), findWire(tmp1),
|
2017-04-20 12:41:43 -04:00
|
|
|
findWire(tmp2), findWire(tmp3));
|
|
|
|
gates.push_back(tmpGate);
|
|
|
|
}
|
|
|
|
else if (tmpType == "OR") {
|
2017-04-20 13:01:04 -04:00
|
|
|
in >> tmp2;
|
|
|
|
in >> tmp3;
|
2017-04-23 19:29:29 -04:00
|
|
|
tmpGate = new OrGate(getDelay(tmpString), findWire(tmp1), findWire(tmp2),
|
2017-04-20 12:41:43 -04:00
|
|
|
findWire(tmp3));
|
|
|
|
gates.push_back(tmpGate);
|
|
|
|
}
|
|
|
|
else if (tmpType == "XOR") {
|
2017-04-20 13:01:04 -04:00
|
|
|
in >> tmp2;
|
|
|
|
in >> tmp3;
|
2017-04-23 19:29:29 -04:00
|
|
|
tmpGate = new XorGate(getDelay(tmpString), findWire(tmp1), findWire(tmp2),
|
2017-04-20 12:41:43 -04:00
|
|
|
findWire(tmp3));
|
|
|
|
gates.push_back(tmpGate);
|
|
|
|
}
|
|
|
|
else if (tmpType == "NOR") {
|
2017-04-20 13:01:04 -04:00
|
|
|
in >> tmp2;
|
|
|
|
in >> tmp3;
|
2017-04-23 19:29:29 -04:00
|
|
|
tmpGate = new NorGate(getDelay(tmpString), findWire(tmp1), findWire(tmp2),
|
2017-04-20 12:41:43 -04:00
|
|
|
findWire(tmp3));
|
|
|
|
gates.push_back(tmpGate);
|
|
|
|
}
|
|
|
|
else if (tmpType == "XNOR") {
|
2017-04-20 13:01:04 -04:00
|
|
|
in >> tmp2;
|
|
|
|
in >> tmp3;
|
2017-04-23 19:29:29 -04:00
|
|
|
tmpGate = new XnorGate(getDelay(tmpString), findWire(tmp1), findWire(tmp2),
|
2017-04-20 12:41:43 -04:00
|
|
|
findWire(tmp3));
|
|
|
|
gates.push_back(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(!in.eof()) {
|
|
|
|
in >> tmpString;
|
|
|
|
in >> tmpString;
|
|
|
|
in >> timeInt;
|
|
|
|
in >> valInt;
|
|
|
|
|
|
|
|
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(eventNum++, valInt, timeInt, tmpWire));
|
|
|
|
}
|
2017-04-20 12:41:43 -04:00
|
|
|
}
|
|
|
|
|
2017-04-24 20:14:22 -04:00
|
|
|
void Simulation::simulate() {
|
|
|
|
// loop through event queue
|
|
|
|
while(!e.empty()) {
|
|
|
|
bool doesChange;
|
|
|
|
Wire * output;
|
|
|
|
|
|
|
|
Event tmpEvent = e.top();
|
|
|
|
e.pop();
|
|
|
|
|
|
|
|
output = tmpEvent.getOutput();
|
|
|
|
doesChange = output->setValue(tmpEvent.getValue(), tmpEvent.getTime());
|
|
|
|
|
|
|
|
// if the wire value changes, evaluate gates
|
|
|
|
if(doesChange) {
|
|
|
|
Gate * tmpGate;
|
|
|
|
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) {
|
|
|
|
e.push(tmpGate->evaluate(tmpEvent.getTime()));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-04-24 20:14:22 -04:00
|
|
|
}
|
|
|
|
}
|
2017-04-20 12:41:43 -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) {
|
2017-04-24 21:15:16 -04:00
|
|
|
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) {
|
2017-04-24 21:15:16 -04:00
|
|
|
(**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;
|
|
|
|
cout << setw(10) << "TIME";
|
|
|
|
while(t <= 60 && t <= lastTime) {
|
2017-04-24 22:14:00 -04:00
|
|
|
cout << setw(5) << t;
|
2017-04-24 21:09:38 -04:00
|
|
|
t += 5;
|
|
|
|
}
|
2017-04-20 12:41:43 -04:00
|
|
|
}
|
2017-04-20 13:01:04 -04:00
|
|
|
|
2017-04-23 19:29:29 -04:00
|
|
|
Wire * Simulation::findWire(int n)
|
2017-04-20 13:01:04 -04:00
|
|
|
{
|
|
|
|
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;
|
2017-04-20 13:01:04 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
int Simulation::getDelay(string d)
|
|
|
|
{
|
|
|
|
d.resize(d.size() - 2);
|
|
|
|
return atoi(d.c_str());
|
|
|
|
}
|