104 lines
2.5 KiB
C++
104 lines
2.5 KiB
C++
#include "circuit.h"
|
|
|
|
#include "assert.h"
|
|
|
|
|
|
void Gate::recal_propagate_len(int fpl[2]) {
|
|
fpl[0] = fpl[1] = 0;
|
|
for(Gate* out : fan_outs) {
|
|
if(!out->is_detected(this)) continue;
|
|
fpl[!value] = std::max(fpl[!value], out->fault_propagate_length[!out->value] + 1);
|
|
}
|
|
}
|
|
|
|
bool Gate::is_detected(Gate* one_of_input) {
|
|
one_of_input->value = !one_of_input->value;
|
|
bool detect = (recal_value() != value);
|
|
one_of_input->value = !one_of_input->value;
|
|
return (recal_value() == value) && detect;
|
|
}
|
|
|
|
void Gate::recal_fault(bool fd[2]) {
|
|
|
|
if(po) {
|
|
fd[!value] = true;
|
|
fd[value] = false;
|
|
return;
|
|
}
|
|
|
|
fd[0] = fd[1] = 0;
|
|
|
|
for(Gate* out : fan_outs) {
|
|
if(!out->propagate) continue;
|
|
|
|
if(out->recal_value() != out->value) continue;
|
|
|
|
this->value = !this->value;
|
|
bool detect = (out->recal_value() != out->value);
|
|
this->value = !this->value;
|
|
if(!detect) continue;
|
|
|
|
fd[0] |= this->value;
|
|
fd[1] |= !this->value;
|
|
}
|
|
return;
|
|
}
|
|
|
|
int Gate::recal_value() {
|
|
int res;
|
|
|
|
switch(type) {
|
|
case NOT:
|
|
res = !fan_ins[0]->value;
|
|
break;
|
|
case BUF:
|
|
res = fan_ins[0]->value;
|
|
break;
|
|
case AND:
|
|
res = fan_ins[0]->value;
|
|
for(int i=1; i<fan_ins.size(); i++) {
|
|
res &= fan_ins[i]->value;
|
|
}
|
|
break;
|
|
case NAND:
|
|
res = fan_ins[0]->value;
|
|
for(int i=1; i<fan_ins.size(); i++) {
|
|
res &= fan_ins[i]->value;
|
|
}
|
|
res = !res;
|
|
break;
|
|
case OR:
|
|
res = fan_ins[0]->value;
|
|
for(int i=1; i<fan_ins.size(); i++) {
|
|
res |= fan_ins[i]->value;
|
|
}
|
|
break;
|
|
case NOR:
|
|
res = fan_ins[0]->value;
|
|
for(int i=1; i<fan_ins.size(); i++) {
|
|
res |= fan_ins[i]->value;
|
|
}
|
|
res = !res;
|
|
break;
|
|
case XOR:
|
|
res = fan_ins[0]->value;
|
|
for(int i=1; i<fan_ins.size(); i++) {
|
|
res ^= fan_ins[i]->value;
|
|
}
|
|
break;
|
|
case XNOR:
|
|
res = fan_ins[0]->value;
|
|
for(int i=1; i<fan_ins.size(); i++) {
|
|
res ^= fan_ins[i]->value;
|
|
}
|
|
res = !res;
|
|
break;
|
|
case INPUT:
|
|
res = value;
|
|
break;
|
|
default:
|
|
assert(false);
|
|
break;
|
|
}
|
|
return res;
|
|
} |