atpg-ls/circuit.cpp
2023-02-16 18:51:31 +08:00

98 lines
2.3 KiB
C++

#include "circuit.h"
#include <queue>
#include <unordered_map>
void Circuit::init_stems() {
for(auto& gate: gates) {
if(gate->outputs.size() >= 2) {
stems.push_back(gate);
}
}
for(auto &gate : PIs) {
stems.push_back(gate);
}
}
void Circuit::init_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;
}