atpg-ls/gate.cpp
2023-05-05 02:40:33 +00:00

111 lines
2.6 KiB
C++

#include "circuit.h"
#include "assert.h"
int Gate::cal_propagate_len(bool x) {
int fpl[2];
fpl[0] = fpl[1] = 0;
for(Gate* out : outputs) {
if(!out->is_detected(this)) continue;
fpl[!value] = std::max(fpl[!value], out->fault_propagate_len[!out->value] + 1);
}
return fpl[x];
}
bool Gate::is_detected(Gate* one_of_input) {
one_of_input->value = !one_of_input->value;
bool detect = cal_value() != value;
one_of_input->value = !one_of_input->value;
return (cal_value() == value) && detect;
}
bool Gate::is_propagated() {
return sa[0] || sa[1];
}
bool Gate::cal_sa(bool x) {
if(isPO) {
if(x == 0) return value;
else return !value;
}
bool sa0 = 0;
bool sa1 = 0;
for(Gate* out : outputs) {
if(!out->is_propagated()) continue;
if(out->cal_value() != out->value) continue;
this->value = !this->value;
bool detect = out->cal_value() != out->value;
this->value = !this->value;
if(!detect) continue;
sa0 |= this->value;
sa1 |= !this->value;
}
if(x == 0) return sa0;
else return sa1;
}
int Gate::cal_value() {
int res;
switch(type) {
case NOT:
res = !inputs[0]->value;
break;
case BUF:
res = inputs[0]->value;
break;
case AND:
res = inputs[0]->value;
for(int i=1; i<inputs.size(); i++) {
res &= inputs[i]->value;
}
break;
case NAND:
res = inputs[0]->value;
for(int i=1; i<inputs.size(); i++) {
res &= inputs[i]->value;
}
res = !res;
break;
case OR:
res = inputs[0]->value;
for(int i=1; i<inputs.size(); i++) {
res |= inputs[i]->value;
}
break;
case NOR:
res = inputs[0]->value;
for(int i=1; i<inputs.size(); i++) {
res |= inputs[i]->value;
}
res = !res;
break;
case XOR:
res = inputs[0]->value;
for(int i=1; i<inputs.size(); i++) {
res ^= inputs[i]->value;
}
break;
case XNOR:
res = inputs[0]->value;
for(int i=1; i<inputs.size(); i++) {
res ^= inputs[i]->value;
}
res = !res;
break;
case INPUT:
res = value;
break;
default:
assert(false);
break;
}
return res;
}