150 lines
4.3 KiB
C++
150 lines
4.3 KiB
C++
#include "circuit.h"
|
|
|
|
const char* GateName[4] = {"XOR", "MAJ", "AND", "OR"};
|
|
CircuitGate* Gates;
|
|
std::vector<int> 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<int> 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<int> 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<int> 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);
|
|
}
|
|
} |