#include "circuit.h" #include #include #include #include #include void line2tokens(const std::string &line, std::vector &tokens) { std::string token; for(char c : line) { if(c == ' ' || c == '\t' || c == '\r' || c == '\n') continue; if(c == '=' || c == ',' || c == '(' || c == ')') { if(!token.size()) continue; tokens.push_back(token); token.clear(); token += c; tokens.push_back(token); token.clear(); } else { token += c; } } if(token.size()) { tokens.push_back(token); } } void Circuit::parse_from_file(const char *filename) { std::ifstream file(filename); if(!file.is_open()) { printf("Error while reading %s\n", filename); exit(1); } // buf 10MB file.rdbuf()->pubsetbuf(0, 10 * 1024 * 1024); std::vector bufPO; std::string line; while(std::getline(file, line)) { if(line[0] == '#') continue; if(line == "\r" || line == "") continue; std::vector tokens; line2tokens(line, tokens); // std::cout << line << std::endl; // std::cout << "tokens: "; // for(auto &token : tokens) { // std::cout << "$" << token << "$ "; // } // std::cout << std::endl; // gate if(tokens.size() >= 6 && tokens[1] == "=" && tokens[3] == "(" && tokens.back() == ")") { std::vector ins; for(int i=4; iname = tokens[0]; gate->propagate = false; gate->stem = false; gate->pi = false; gate->po = false; for(auto &in : ins) { if(!name2gate.count(in)) { printf("Error while reading file: gate %s used before defination.\n", in.c_str()); exit(1); } auto in_gate = name2gate[in]; gate->inputs.push_back(in_gate); in_gate->outputs.push_back(gate); } if(tokens[2] == "AND") { gate->type = Gate::AND; } else if(tokens[2] == "NAND") { gate->type = Gate::NAND; } else if(tokens[2] == "OR") { gate->type = Gate::OR; } else if(tokens[2] == "NOR") { gate->type = Gate::NOR; } else if(tokens[2] == "XOR") { gate->type = Gate::XOR; } else if(tokens[2] == "XNOR") { gate->type = Gate::XNOR; } else if(tokens[2] == "NOT") { gate->type = Gate::NOT; } else if(tokens[2] == "BUFF") { gate->type = Gate::BUF; } else if(tokens[2] == "BUF") { gate->type = Gate::BUF; } else { printf("Error while reading file: %s is not a valid gate.\n", tokens[2].c_str()); exit(1); } name2gate.insert(std::make_pair(gate->name, gate)); gates.push_back(gate); } // input else if(tokens.size() == 4 && tokens[0] == "INPUT" && tokens[1] == "(" && tokens[3] == ")") { Gate* gate = new Gate(); gate->name = tokens[2]; gate->type = Gate::INPUT; gate->propagate = false; gate->stem = true; gate->pi = true; gate->po = false; name2gate.insert(std::make_pair(gate->name, gate)); gates.push_back(gate); PIs.push_back(gate); } // gate else if(tokens.size() == 4 && tokens[0] == "OUTPUT" && tokens[1] == "(" && tokens[3] == ")") { bufPO.push_back(tokens[2]); } // invalid line else { printf("Error while reading line: %s\n", line.c_str()); exit(1); } } // handle PO for(auto& po_name : bufPO) { if(!name2gate.count(po_name)) { printf("Error while reading file: po %s is not a exist gate.\n", po_name.c_str()); exit(1); } Gate* po = name2gate[po_name]; po->po = true; po->stem = true; POs.push_back(po); } }