#include "circuit.h" const char* GateName[4] = {"XOR", "MAJ", "AND", "OR"}; CircuitGate* Gates; std::vector circuit_inputs; int circuit_output; void read_verilog_from_file(const char *filename) { using namespace std; ifstream file(filename); cmatch m; string line; // skip I/Os getline(file, line); //cout << "inputs: " << endl; getline(file, line); while(regex_search(line.c_str(), m, regex("[x|y]\\d+"))) { //cout << atoi(m.str(0).substr(1).c_str()) << " "; circuit_inputs.push_back(atoi(m.str(0).substr(1).c_str()) + 1); line = m.suffix().str(); } //cout << endl; // skip outputs; getline(file, line); int maxvar = 0; // all wires //cout << "wires: " << endl; getline(file, line); while(regex_search(line.c_str(), m, regex("n\\d+"))) { string wire = m.str(0); //cout << wire << " "; maxvar = max(maxvar, std::atoi(wire.substr(1).c_str())); line = m.suffix().str(); } //cout << endl; assert(maxvar); //cout << "maxvar: " << maxvar + 1 << endl; // allcate for global gates table Gates = new CircuitGate[maxvar + 2]; while(true) { getline(file, line); if(line == "endmodule") break; //cout << line << endl; std::vector vars; string copy = line; while(regex_search(copy.c_str(), m, regex("~?[xyn]\\d+"))) { string str = m.str(0); int sign = 1; if(str[0] == '~') { sign = -1; str = str.substr(1); } // remove x , y or n str = str.substr(1); vars.push_back(sign * (atoi(str.c_str()) + 1)); copy = m.suffix().str(); } int id = vars[0]; vars.erase(vars.begin()); CircuitGate &gate = Gates[id]; if(regex_match(line.c_str(), m, regex(" assign ~?[xyn]\\d+ = ~?[xyn]\\d+ (& ~?[xyn]\\d+)+ ;"))) { //cout << "MATCH AND: " ; gate.type = AND; gate.inputs.insert(gate.inputs.end(), vars.begin(), vars.end()); } else if(regex_match(line.c_str(), m, regex(" assign ~?[xyn]\\d+ = ~?[xyn]\\d+ (\\^ ~?[xyn]\\d+)+ (\\^ 1\\'b0)+ ;"))) { //cout << "MATCH XOR: " ; gate.type = XOR; gate.inputs.insert(gate.inputs.end(), vars.begin(), vars.end()); } else if(regex_match(line.c_str(), m, regex(" assign ~?[xyn]\\d+ = ~?[xyn]\\d+ (\\| ~?[xyn]\\d+)+ ;"))) { //cout << "MATCH OR: " ; gate.type = OR; gate.inputs.insert(gate.inputs.end(), vars.begin(), vars.end()); } else if(regex_match(line.c_str(), m, regex(" assign ~?y\\d+ = ~?[xyn]\\d+ ;"))) { //cout << "MATCH OUTPUT: " ; circuit_output = vars[0]; } else { //cout << "MATCH MAJ: " ; set tmp; for(auto& var : vars) tmp.insert(var); assert(tmp.size() == 3); gate.type = MAJ; gate.inputs.insert(gate.inputs.end(), tmp.begin(), tmp.end()); } // for(auto& var : vars) { // cout << var << " "; // } // cout << endl; } recalulate_fanouts(); calulate_topo_index(); } void calulate_topo_index() { int topo_count[circuit_output + 1]; memset(topo_count, 0, sizeof(topo_count)); std::queue q; int cnt = 0; for(auto& in : circuit_inputs) { Gates[in].topo_index = ++cnt; q.push(in); } while(!q.empty()) { int u = q.front(); q.pop(); for(auto &fanout : Gates[u].fanouts) { topo_count[fanout]++; if(topo_count[fanout] == Gates[fanout].inputs.size()) { Gates[fanout].topo_index = ++cnt; q.push(fanout); } } } } void recalulate_fanouts() { for(int i=1; i<=circuit_output; i++) { Gates[i].fanouts.clear(); } for(int i=1; i<=circuit_output; i++) { for(int in : Gates[i].inputs) { Gates[abs(in)].fanouts.push_back(i); } } } void print_circuit_structure() { for(int i=1; i<=circuit_output; i++) { printf(" Gate %d = %s (", i, GateName[Gates[i].type]); for(auto& in : Gates[i].inputs) { printf(" %d", in); } printf(" ) topo: %d \n", Gates[i].topo_index); } }