atpg-ls/gate.cpp

104 lines
2.5 KiB
C++
Raw Permalink Normal View History

2023-02-19 19:42:50 +08:00
#include "circuit.h"
#include "assert.h"
2023-03-06 11:05:30 +00:00
2023-03-13 05:44:49 +00:00
void Gate::recal_propagate_len(int fpl[2]) {
2023-03-06 11:05:30 +00:00
fpl[0] = fpl[1] = 0;
2023-03-13 05:44:49 +00:00
for(Gate* out : fan_outs) {
2023-03-06 11:05:30 +00:00
if(!out->is_detected(this)) continue;
2023-03-13 05:44:49 +00:00
fpl[!value] = std::max(fpl[!value], out->fault_propagate_length[!out->value] + 1);
2023-03-06 11:05:30 +00:00
}
}
bool Gate::is_detected(Gate* one_of_input) {
one_of_input->value = !one_of_input->value;
2023-03-13 05:44:49 +00:00
bool detect = (recal_value() != value);
2023-03-06 11:05:30 +00:00
one_of_input->value = !one_of_input->value;
2023-03-13 05:44:49 +00:00
return (recal_value() == value) && detect;
2023-03-06 11:05:30 +00:00
}
2023-03-13 05:44:49 +00:00
void Gate::recal_fault(bool fd[2]) {
2023-02-19 19:42:50 +08:00
2023-03-13 05:44:49 +00:00
if(po) {
fd[!value] = true;
fd[value] = false;
return;
2023-03-02 08:17:53 +00:00
}
2023-03-13 05:44:49 +00:00
fd[0] = fd[1] = 0;
2023-03-02 08:17:53 +00:00
2023-03-13 05:44:49 +00:00
for(Gate* out : fan_outs) {
if(!out->propagate) continue;
2023-03-02 08:17:53 +00:00
2023-03-13 05:44:49 +00:00
if(out->recal_value() != out->value) continue;
2023-03-02 08:17:53 +00:00
this->value = !this->value;
2023-03-13 05:44:49 +00:00
bool detect = (out->recal_value() != out->value);
2023-03-02 08:17:53 +00:00
this->value = !this->value;
if(!detect) continue;
2023-03-13 05:44:49 +00:00
fd[0] |= this->value;
fd[1] |= !this->value;
2023-03-02 08:17:53 +00:00
}
2023-03-13 05:44:49 +00:00
return;
2023-03-02 08:17:53 +00:00
}
2023-03-13 05:44:49 +00:00
int Gate::recal_value() {
2023-02-19 19:42:50 +08:00
int res;
switch(type) {
case NOT:
2023-03-13 05:44:49 +00:00
res = !fan_ins[0]->value;
2023-02-19 19:42:50 +08:00
break;
case BUF:
2023-03-13 05:44:49 +00:00
res = fan_ins[0]->value;
2023-02-19 19:42:50 +08:00
break;
case AND:
2023-03-13 05:44:49 +00:00
res = fan_ins[0]->value;
for(int i=1; i<fan_ins.size(); i++) {
res &= fan_ins[i]->value;
2023-02-19 19:42:50 +08:00
}
break;
case NAND:
2023-03-13 05:44:49 +00:00
res = fan_ins[0]->value;
for(int i=1; i<fan_ins.size(); i++) {
res &= fan_ins[i]->value;
2023-02-19 19:42:50 +08:00
}
res = !res;
break;
case OR:
2023-03-13 05:44:49 +00:00
res = fan_ins[0]->value;
for(int i=1; i<fan_ins.size(); i++) {
res |= fan_ins[i]->value;
2023-02-19 19:42:50 +08:00
}
break;
case NOR:
2023-03-13 05:44:49 +00:00
res = fan_ins[0]->value;
for(int i=1; i<fan_ins.size(); i++) {
res |= fan_ins[i]->value;
2023-02-19 19:42:50 +08:00
}
res = !res;
break;
case XOR:
2023-03-13 05:44:49 +00:00
res = fan_ins[0]->value;
for(int i=1; i<fan_ins.size(); i++) {
res ^= fan_ins[i]->value;
2023-02-19 19:42:50 +08:00
}
break;
case XNOR:
2023-03-13 05:44:49 +00:00
res = fan_ins[0]->value;
for(int i=1; i<fan_ins.size(); i++) {
res ^= fan_ins[i]->value;
2023-02-19 19:42:50 +08:00
}
res = !res;
break;
2023-02-20 14:41:19 +08:00
case INPUT:
res = value;
break;
2023-02-19 19:42:50 +08:00
default:
assert(false);
break;
}
return res;
}