Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /******************************************************
- **Group: 15
- **Semester: January 2018
- ** Student info:
- ** 1. Lim Wei Sean , 1702106, 3E
- ** 2.
- *******************************************************/
- /******************************************************
- Pre-processor Directives
- *******************************************************/
- #include <iostream>
- #include <algorithm>
- #include <fstream>
- #include <string>
- #include <vector>
- #include <map>
- #define vect vector
- #define boolmap map<string, bool>
- #define gatemap map<string, Gate*>
- #define inputmap map<string, int>
- #define TT map<string, string>
- #define toupper(a) transform(a.begin(), a.end(), a.begin(), toupper)
- #define tolower(a) transform(a.begin(), a.end(), a.begin(), tolower)
- using namespace std;
- /******************************************************
- Global Functions
- *******************************************************/
- vect<string> CSVExtract(string str) {
- str = str.substr(str.find_first_not_of(" \t\n,"), str.find_last_not_of(" \t\n,") - str.find_first_not_of(" \t\n,") + 1); //to strip spaces on the sides
- size_t begin = 0;
- size_t end = str.find_first_of(",", begin);
- vect<string> returnVect;
- while (1) {
- string extract = str.substr(begin, end - begin);
- returnVect.push_back(extract);
- if (end == string::npos) break;
- begin = str.find_first_not_of(" \t,", end + 1);
- end = str.find_first_of(",", begin);
- }
- return returnVect;
- }
- /******************************************************
- Class Definitions
- *******************************************************/
- class Circuit;
- class Gate {
- protected:
- Circuit * circuit;
- string type, name;
- int in_max, out_max, not_connect_out;
- vect<string> in_list;
- vect<int> out_list;
- vect<bool> out_connect;
- public:
- Gate(Circuit* _circuit, string _name, string _type, int _in_max, int _out_max) {
- circuit = _circuit;
- name = _name;
- type = _type;
- in_max = _in_max;
- out_max = _out_max;
- not_connect_out = _out_max;
- for (int i = 0; i < in_max; i++) {
- in_list.push_back("");
- }
- for (int i = 0; i < out_max; i++) {
- out_list.push_back(-2);
- out_connect.push_back(0);
- }
- }
- virtual vect<int> compute() = 0;
- virtual void setInputs(int in_pin, string path) {
- if (in_pin < in_max) {
- in_list[in_pin] = path;
- }
- else {
- cout << "Input pin index out of range." << endl;
- cout << "Gate Name: " << name << endl;
- cout << "Gate in_max: " << in_max << endl;
- cout << "Gate out_max: " << out_max << endl;
- cout << "Exiting..." << endl;
- getchar();
- exit(0);
- }
- }
- int getOutputVal(Circuit* cir, string str);
- vect<int> getOutList() {
- return out_list;
- }
- vect<bool> getOutConnect() {
- return out_connect;
- }
- string operator^(const int _pin) {
- return ("O" + to_string(0) + " = " + to_string(this->out_list[_pin]));
- }
- friend ostream& operator<<(ostream& os, const Gate& G);
- };
- class OR : public Gate {
- public:
- OR(Circuit* _circuit, string _name, int _in_max) : Gate(_circuit, _name, "OR", _in_max, 1) {
- cout << "################################################################" << endl;
- cout << "# Register Gate:" << endl;
- cout << "# Gate Name: " << name << endl;
- cout << "# Gate Type: " << type << endl;
- cout << "# in_max: " << in_max << endl;
- cout << "# out_max: " << out_max << endl;
- cout << "################################################################" << endl;
- }
- vect<int> compute() {
- cout << "Computing " << name << endl;
- out_list[0] = -2;
- if (in_list[0] == "") return out_list;
- out_list[0] = getOutputVal(circuit, in_list[0]);
- for (int i = 1; i < in_max; i++) {
- if (in_list[i] == "") {
- out_list[0] = -2;
- return out_list;
- }
- int _temp_val = getOutputVal(circuit, in_list[i]);
- out_list[0] = out_list[0] | getOutputVal(circuit, in_list[i]);
- }
- return out_list;
- }
- };
- class AND : public Gate {
- public:
- AND(Circuit* _circuit, string _name, int _in_max) : Gate(_circuit, _name, "AND", _in_max, 1) {
- cout << "################################################################" << endl;
- cout << "# Register Gate:" << endl;
- cout << "# Gate Name: " << name << endl;
- cout << "# Gate Type: " << type << endl;
- cout << "# in_max: " << in_max << endl;
- cout << "# out_max: " << out_max << endl;
- cout << "################################################################" << endl;
- }
- vect<int> compute() {
- cout << "Computing " << name << endl;
- out_list[0] = -2;
- if (in_list[0] == "") return out_list;
- out_list[0] = getOutputVal(circuit, in_list[0]);
- for (int i = 1; i < in_max; i++) {
- if (in_list[i] == "") {
- out_list[0] = -2;
- return out_list;
- }
- int _temp_val = getOutputVal(circuit, in_list[i]);
- out_list[0] = out_list[0] & getOutputVal(circuit, in_list[i]);
- }
- return out_list;
- }
- };
- class NOT : public Gate {
- public:
- NOT(Circuit* _circuit, string _name) : Gate(_circuit, _name, "NOT", 1, 1) {
- cout << "################################################################" << endl;
- cout << "# Register Gate:" << endl;
- cout << "# Gate Name: " << name << endl;
- cout << "# Gate Type: " << type << endl;
- cout << "# in_max: " << in_max << endl;
- cout << "# out_max: " << out_max << endl;
- cout << "################################################################" << endl;
- }
- vect<int> compute() {
- cout << "Computing " << name << endl;
- out_list[0] = -2;
- if (in_list[0] == "") return out_list;
- out_list[0] = !(getOutputVal(circuit, in_list[0]));
- return out_list;
- }
- };
- class NOR : public Gate {
- public:
- NOR(Circuit* _circuit, string _name, int _in_max) : Gate(_circuit, _name, "NOR", _in_max, 1) {
- cout << "################################################################" << endl;
- cout << "# Register Gate:" << endl;
- cout << "# Gate Name: " << name << endl;
- cout << "# Gate Type: " << type << endl;
- cout << "# in_max: " << in_max << endl;
- cout << "# out_max: " << out_max << endl;
- cout << "################################################################" << endl;
- }
- vect<int> compute() {
- cout << "Computing " << name << endl;
- out_list[0] = -2;
- if (in_list[0] == "") return out_list;
- out_list[0] = getOutputVal(circuit, in_list[0]);
- for (int i = 1; i < in_max; i++) {
- if (in_list[i] == "") {
- out_list[0] = -2;
- return out_list;
- }
- int _temp_val = getOutputVal(circuit, in_list[i]);
- out_list[0] = out_list[0] | getOutputVal(circuit, in_list[i]);
- }
- out_list[0] = !(out_list[0]);
- return out_list;
- }
- };
- class NAND : public Gate {
- public:
- NAND(Circuit* _circuit, string _name, int _in_max) : Gate(_circuit, _name, "NAND", _in_max, 1) {
- cout << "################################################################" << endl;
- cout << "# Register Gate:" << endl;
- cout << "# Gate Name: " << name << endl;
- cout << "# Gate Type: " << type << endl;
- cout << "# in_max: " << in_max << endl;
- cout << "# out_max: " << out_max << endl;
- cout << "################################################################" << endl;
- }
- vect<int> compute() {
- cout << "Computing " << name << endl;
- out_list[0] = -2;
- if (in_list[0] == "") return out_list;
- out_list[0] = getOutputVal(circuit, in_list[0]);
- for (int i = 1; i < in_max; i++) {
- if (in_list[i] == "") {
- out_list[0] = -2;
- return out_list;
- }
- int _temp_val = getOutputVal(circuit, in_list[i]);
- out_list[0] = out_list[0] & getOutputVal(circuit, in_list[i]);
- }
- out_list[0] = !(out_list[0]);
- return out_list;
- }
- };
- class XOR : public Gate {
- public:
- XOR(Circuit* _circuit, string _name, int _in_max) : Gate(_circuit, _name, "XOR", _in_max, 1) {
- cout << "################################################################" << endl;
- cout << "# Register Gate:" << endl;
- cout << "# Gate Name: " << name << endl;
- cout << "# Gate Type: " << type << endl;
- cout << "# in_max: " << in_max << endl;
- cout << "# out_max: " << out_max << endl;
- cout << "################################################################" << endl;
- }
- vect<int> compute() {
- cout << "Computing " << name << endl;
- out_list[0] = -2;
- if (in_list[0] == "") return out_list;
- out_list[0] = getOutputVal(circuit, in_list[0]);
- for (int i = 1; i < in_max; i++) {
- if (in_list[i] == "") {
- out_list[0] = -2;
- return out_list;
- }
- int _temp_val = getOutputVal(circuit, in_list[i]);
- out_list[0] = out_list[0] ^ getOutputVal(circuit, in_list[i]);
- }
- return out_list;
- }
- };
- class DFF : public Gate {
- //in_list[0] == D, in_list[1] == CLK, out_list[0] == Q
- int memory;
- public:
- DFF(Circuit* _circuit, string _name, int _memory) : Gate(_circuit, _name, "DFF", 2, 1) {
- if (_memory == 1 || _memory == 0)memory = _memory; //default memory
- else {
- cout << "Invalid memory data!" << endl;
- getchar();
- exit(0);
- }
- cout << "################################################################" << endl;
- cout << "# Register Gate:" << endl;
- cout << "# Gate Name: " << name << endl;
- cout << "# Gate Type: " << type << endl;
- cout << "# in_max: " << in_max << endl;
- cout << "# out_max: " << out_max << endl;
- cout << "# memory: " << memory << endl;
- cout << "################################################################" << endl;
- }
- vect<int> compute() {
- cout << "Computing " << name << endl;
- out_list[0] = -2;
- if (in_list[0] == "" || in_list[1] == "") return out_list;
- int D = getOutputVal(circuit, in_list[0]);
- int CLK = getOutputVal(circuit, in_list[1]);
- if (CLK == 0) {
- out_list[0] = memory;
- }
- else {
- memory = D;
- out_list[0] = D;
- }
- return out_list;
- }
- };
- class TFF : public Gate {
- //in_list[0] == T, in_list[1] == CLK, out_list[0] == Q
- int memory;
- public:
- TFF(Circuit* _circuit, string _name, int _memory) : Gate(_circuit, _name, "TFF", 2, 1) {
- if (_memory == 1 || _memory == 0)memory = _memory; //default memory
- else {
- cout << "Invalid memory data!" << endl;
- getchar();
- exit(0);
- }
- cout << "################################################################" << endl;
- cout << "# Register Gate:" << endl;
- cout << "# Gate Name: " << name << endl;
- cout << "# Gate Type: " << type << endl;
- cout << "# in_max: " << in_max << endl;
- cout << "# out_max: " << out_max << endl;
- cout << "# memory: " << memory << endl;
- cout << "################################################################" << endl;
- }
- vect<int> compute() {
- cout << "Computing " << name << endl;
- out_list[0] = -2;
- if (in_list[0] == "" || in_list[1] == "") return out_list;
- int T = getOutputVal(circuit, in_list[0]);
- int CLK = getOutputVal(circuit, in_list[1]);
- if (CLK == 0) {
- out_list[0] = memory;
- }
- else {
- if (T == 1) {
- memory = !(memory);
- out_list[0] = memory;
- }
- else out_list[0] = memory;
- }
- return out_list;
- }
- };
- class Other : public Gate {
- TT truth_table;
- public:
- Other(Circuit* _circuit, string _name, int _in_max, int _out_max, string path) : Gate(_circuit, _name, path, _in_max, _out_max) {
- //construct Truth Table
- //read truth table from path
- tolower(path);//change path to lowercase letters
- fstream _TT(path + ".csv", ios::in);
- if (_TT.is_open()) {
- cout << "Reading the Truth Table from " << path + ".csv" << "..." << endl;
- int cnt = 0;
- string input;
- while (_TT.peek() != EOF) {
- getline(_TT, input);
- if (cnt == 0) {//match the number of input and output with in_max and out_max
- }
- if (cnt > 0) { // skip the header in the file
- vect<string> _input = CSVExtract(input);//extract the CSV data
- int _temp = 0;
- for (auto const& a : _input) {//validate input
- if (atoi(a.c_str()) != 0 && atoi(a.c_str()) != 1) {
- cout << "There is an invalid input value in " << path << endl;
- cout << "Exiting..." << endl;
- getchar();
- exit(0);
- }
- _temp++;
- }
- string _in = "";
- string _out = "";
- for (int i = in_max; i > 0; i--) {
- _in += _input[in_max - i];
- if (i != 1)_in += ",";
- }
- for (int i = out_max; i > 0; i--) {
- _out += _input[out_max + in_max - i];
- if (i != 1)_out += ",";
- }
- truth_table[_in] = _out;
- }
- cnt++;
- }
- }
- else {
- cout << path + ".csv" << " not found. Exiting..." << endl;
- getchar();
- exit(0);
- }
- _TT.close();
- //print details
- cout << "################################################################" << endl;
- cout << "# Register Gate:" << endl;
- cout << "# Gate Name: " << name << endl;
- cout << "# Gate Type: " << type << endl;
- cout << "# in_max: " << in_max << endl;
- cout << "# out_max: " << out_max << endl;
- cout << "# Truth Table: " << path << endl;
- cout << "################################################################" << endl;
- }
- vect<int> compute() {
- cout << "Computing " << name << endl;
- string _in = "";
- string _out = "";
- int cnt = 0;
- for (auto const& a : in_list) {
- if (a == "") return vect<int>(out_max, -2);
- _in += to_string(getOutputVal(circuit, a));
- if (cnt != in_max - 1)_in += ",";
- cnt++;
- }
- try {
- _out = truth_table.at(_in);
- vect<string> extract = CSVExtract(_out);
- for (int i = 0; i < extract.size(); i++) {
- int num = atoi(extract.at(i).c_str());
- out_list[i] = num;
- }
- }
- catch (const out_of_range& oor) {
- cout << oor.what() << endl << "Exiting..." << endl;
- getchar();
- exit(0);
- }
- return out_list;
- }
- };
- class Circuit {
- private:
- string filenames[4];//gates, inputs, connections, outputs
- gatemap gates;
- boolmap check;//1 if gate is compute
- boolmap out_check;//1 if all output of gate is connected
- inputmap inputs;
- public:
- Circuit(string _gate_file, string _input_file, string _connection_file, string _output_file) {
- filenames[0] = _gate_file + ".csv";
- filenames[1] = _input_file + ".csv";
- filenames[2] = _connection_file + ".csv";
- filenames[3] = _output_file + ".txt";
- }
- friend int Gate::getOutputVal(Circuit* cir, string str);
- void getOut(string filepath) {
- //open output file
- fstream outputFile(filepath, ios::out);
- if (outputFile.is_open()) {
- cout << "Writing to " << filepath << "..." << endl;
- for (auto const& x : out_check) {
- if (x.second == 0) {
- Gate* _gate = gates[x.first];
- for (int b = 0; b < _gate->getOutConnect().size(); b++) {
- if (_gate->getOutConnect()[b] == 0) {
- outputFile << *_gate << ": " << (*_gate ^ b) << endl;
- }
- }
- }
- }
- }
- else {
- cout << filepath << " not found. Exiting..." << endl;
- getchar();
- exit(0);
- }
- outputFile.close();
- }
- bool terminator() {
- for (auto const& a : check) {
- if (a.second == 0) {
- return true;
- }
- else {
- return false;
- }
- }
- }
- void init_gate(string filepath) {
- fstream gateFile(filepath, ios::in);
- if (gateFile.is_open()) {
- cout << "Reading the gates..." << endl;
- int cnt = 0;
- string input;
- while (gateFile.peek() != EOF) {
- getline(gateFile, input);
- if (cnt > 0) { // skip the header in the file
- vect<string> _input = CSVExtract(input);//extract the CSV data
- toupper(_input[0]);
- Circuit* self = this;
- if (_input[0] == "OR") {
- if (atoi(_input[3].c_str()) != 1) cout << "Only one output is valid for OR gate." << endl << "Setting: out_max = 1" << endl;
- //create object
- OR* _gate = new OR(self, _input[1], atoi(_input[2].c_str()));
- //append to gates
- gates[_input[1]] = _gate;
- //append to check
- check[_input[1]] = 0;
- //append to out_check
- out_check[_input[1]] = 0;
- }
- else if (_input[0] == "AND") {
- if (atoi(_input[3].c_str()) != 1) cout << "Only one output is valid for AND gate." << endl << "Setting: out_max = 1" << endl;
- //create object
- AND* _gate = new AND(self, _input[1], atoi(_input[2].c_str()));
- //append to gates
- gates[_input[1]] = _gate;
- //append to check
- check[_input[1]] = 0;
- //append to out_check
- out_check[_input[1]] = 0;
- }
- else if (_input[0] == "NOT") {
- if (atoi(_input[2].c_str()) != 1 || atoi(_input[3].c_str()) != 1) cout << "Only one input and output is valid for NOT gate." << endl << "Setting: in_max = 1, out_max = 1" << endl;
- //create object
- NOT* _gate = new NOT(self, _input[1]);
- //append to gates
- gates[_input[1]] = _gate;
- //append to check
- check[_input[1]] = 0;
- //append to out_check
- out_check[_input[1]] = 0;
- }
- else if (_input[0] == "NOR") {
- if (atoi(_input[3].c_str()) != 1) cout << "Only one output is valid for NOR gate." << endl << "Setting: out_max = 1" << endl;
- //create object
- NOR* _gate = new NOR(self, _input[1], atoi(_input[2].c_str()));
- //append to gates
- gates[_input[1]] = _gate;
- //append to check
- check[_input[1]] = 0;
- //append to out_check
- out_check[_input[1]] = 0;
- }
- else if (_input[0] == "NAND") {
- if (atoi(_input[3].c_str()) != 1) cout << "Only one output is valid for NAND gate." << endl << "Setting: out_max = 1" << endl;
- //create object
- NAND* _gate = new NAND(self, _input[1], atoi(_input[2].c_str()));
- //append to gates
- gates[_input[1]] = _gate;
- //append to check
- check[_input[1]] = 0;
- //append to out_check
- out_check[_input[1]] = 0;
- }
- else if (_input[0] == "XOR") {
- if (atoi(_input[3].c_str()) != 1) cout << "Only one output is valid for XOR gate." << endl << "Setting: out_max = 1" << endl;
- //create object
- XOR* _gate = new XOR(self, _input[1], atoi(_input[2].c_str()));
- //append to gates
- gates[_input[1]] = _gate;
- //append to check
- check[_input[1]] = 0;
- //append to out_check
- out_check[_input[1]] = 0;
- }
- else if (_input[0] == "DFF") {
- if (_input[4] != "0" && _input[4] != "1") {
- cout << "Unidentified memory!" << endl << "Setting: memory = 0";
- _input[4] = "0";
- }
- if (atoi(_input[2].c_str()) != 2 || atoi(_input[3].c_str()) != 1) cout << "Only 2 inputs and one output is valid for DFF gate." << endl << "Setting: in_max = 2, out_max = 1" << endl;
- //create object
- DFF* _gate = new DFF(self, _input[1], atoi(_input[4].c_str()));
- //append to gates
- gates[_input[1]] = _gate;
- //append to check
- check[_input[1]] = 0;
- //append to out_check
- out_check[_input[1]] = 0;
- }
- else if (_input[0] == "TFF") {
- if (_input[4] != "0" && _input[4] != "1") {
- cout << "Unidentified memory!" << endl << "Setting: memory = 0";
- _input[4] = "0";
- }
- if (atoi(_input[2].c_str()) != 2 || atoi(_input[3].c_str()) != 1) cout << "Only 2 inputs and one output is valid for TFF gate." << endl << "Setting: in_max = 2, out_max = 1" << endl;
- //create object
- TFF* _gate = new TFF(self, _input[1], atoi(_input[4].c_str()));
- //append to gates
- gates[_input[1]] = _gate;
- //append to check
- check[_input[1]] = 0;
- //append to out_check
- out_check[_input[1]] = 0;
- }
- else {
- //create object
- toupper(_input[0]);
- string _path = _input[0];
- Other* _gate = new Other(self, _input[1], atoi(_input[2].c_str()), atoi(_input[3].c_str()), _path);
- //append to gates
- gates[_input[1]] = _gate;
- //append to check
- check[_input[1]] = 0;
- //append to out_check
- out_check[_input[1]] = 0;
- }
- }
- cnt++;
- }
- }
- else {
- cout << filepath << " not found. Exiting..." << endl;
- getchar();
- exit(0);
- }
- gateFile.close();
- }
- void init_ext_input(string filepath) {
- fstream inputFile(filepath, ios::in);
- if (inputFile.is_open()) {
- cout << "Reading the inputs..." << endl;
- int cnt = 0;
- string input;
- while (inputFile.peek() != EOF) {
- getline(inputFile, input);
- if (cnt > 0) { // skip the header in the file
- vect<string> _input = CSVExtract(input);//extract the CSV data
- if (_input[1] != "0" && _input[1] != "1") { //Validate input value
- cout << "Invalid input value" << endl;
- getchar();
- exit(0);
- }
- inputs[_input[0]] = atoi(_input[1].c_str());
- }
- cnt++;
- }
- }
- else {
- cout << filepath << " not found. Exiting..." << endl;
- getchar();
- exit(0);
- }
- inputFile.close();
- }
- void init_connection(string filepath) {
- fstream connectionFile(filepath, ios::in);
- if (connectionFile.is_open()) {
- cout << "Reading the connections..." << endl;
- int cnt = 0;
- string input;
- while (connectionFile.peek() != EOF) {
- getline(connectionFile, input);
- if (cnt > 0) { // skip the header in the file
- vect<string> _input = CSVExtract(input);//extract the CSV data
- try { gates.at(_input[0]); }
- catch (const out_of_range& oor) {
- cout << oor.what() << endl << "Exiting..." << endl;
- getchar();
- connectionFile.close();
- exit(0);
- }
- gates.at(_input[0])->setInputs(atoi(_input[1].c_str()), _input[2]);
- }
- cnt++;
- }
- }
- else {
- cout << filepath << " not found. Exiting..." << endl;
- getchar();
- exit(0);
- }
- connectionFile.close();
- }
- void compute() {//for lazy API users
- init_gate(filenames[0]);
- init_ext_input(filenames[1]);
- init_connection(filenames[2]);
- while (terminator()) {
- for (auto const& a : check) {
- if (a.second == 0) {
- for (auto const& b : gates[a.first]->compute()) {
- if (b == -2) {
- cout << "Insufficient connection data!" << endl;
- cout << "Gate name: " << a.first << endl;
- cout << "Exiting..." << endl;
- getchar();
- exit(0);
- }
- else {
- check[a.first] = 1;
- }
- }
- }
- }
- }
- getOut(filenames[3]);
- cout << "Circuit computation done." << endl;
- cout << "Data collected in " << filenames[3] << endl;
- }
- };
- /******************************************************
- Friend Functions & Operator Overloading
- *******************************************************/
- int Gate::getOutputVal(Circuit* cir, string str) {
- //str = "Gate_name Output_pin"
- string split = " ";
- size_t center = str.find_first_of(split);
- string gate_input_name, output_pin;
- int output_value;
- if (center == string::npos) {
- gate_input_name = str;
- output_value = cir->inputs[gate_input_name];
- }
- else {
- gate_input_name = str.substr(0, center);
- output_pin = str.substr(center + 1);
- output_value = cir->gates[gate_input_name]->out_list[atoi(output_pin.c_str())];
- if (cir->gates[gate_input_name]->out_connect[atoi(output_pin.c_str())] == 0) {
- cir->gates[gate_input_name]->out_connect[atoi(output_pin.c_str())] = 1;
- int _state = --cir->gates[gate_input_name]->not_connect_out;
- if (_state == 0)cir->out_check[gate_input_name] = 0;
- }
- if (output_value == -2) {
- output_value = cir->gates[gate_input_name]->compute()[atoi(output_pin.c_str())];
- if (output_value != -2) {
- cir->check[gate_input_name] = 1;
- }
- else {
- cout << "Insufficient connection data!" << endl;
- cout << "Gate name: " << gate_input_name << endl;
- cout << "Exiting..." << endl;
- getchar();
- exit(0);
- }
- }
- }
- return output_value;
- }
- ostream& operator<<(ostream& os, const Gate& G) {
- os << G.type + ", " + G.name;
- return os;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement