atpg-ls/circuit.cpp

83 lines
2.1 KiB
C++

#include "circuit.h"
#include <queue>
#include <unordered_map>
void Circuit::cal_topo_index() {
int topo = 1;
std::queue<Gate*> q;
std::unordered_map<Gate*, int> ins;
for(Gate* gate : gates) {
ins[gate] = gate->inputs.size();
}
for(auto in : PIs) {
in->topo = topo++;
q.push(in);
}
while(!q.empty()) {
Gate* g = q.front(); q.pop();
for(Gate* out : g->outputs) {
ins[out]--;
if(ins[out] == 0) {
out->topo = topo++;
q.push(out);
}
}
}
}
int Circuit::cal_gate_value(const Gate* &gate) {
int res;
switch(gate->type) {
case Gate::NOT:
res = !gate->inputs[0]->value;
break;
case Gate::BUF:
res = gate->inputs[0]->value;
break;
case Gate::AND:
res = gate->inputs[0]->value;
for(int i=1; i<gate->inputs.size(); i++) {
res &= gate->inputs[i]->value;
}
break;
case Gate::NAND:
res = gate->inputs[0]->value;
for(int i=1; i<gate->inputs.size(); i++) {
res &= gate->inputs[i]->value;
}
res = !res;
break;
case Gate::OR:
res = gate->inputs[0]->value;
for(int i=1; i<gate->inputs.size(); i++) {
res |= gate->inputs[i]->value;
}
break;
case Gate::NOR:
res = gate->inputs[0]->value;
for(int i=1; i<gate->inputs.size(); i++) {
res |= gate->inputs[i]->value;
}
res = !res;
break;
case Gate::XOR:
res = gate->inputs[0]->value;
for(int i=1; i<gate->inputs.size(); i++) {
res ^= gate->inputs[i]->value;
}
break;
case Gate::XNOR:
res = gate->inputs[0]->value;
for(int i=1; i<gate->inputs.size(); i++) {
res ^= gate->inputs[i]->value;
}
res = !res;
break;
}
return res;
}