diff --git a/atpg b/atpg index b11a201..f104823 100755 Binary files a/atpg and b/atpg differ diff --git a/circuit.h b/circuit.h index e8c48ed..019e7e0 100644 --- a/circuit.h +++ b/circuit.h @@ -19,8 +19,6 @@ public: bool isPI; bool isPO; - std::unordered_map> sa_by_out; - std::vector pre_stems; std::vector suc_stems; @@ -29,6 +27,7 @@ public: bool is_propagated(); int cal_value(); + bool cal_sa(bool x); }; class Fault { diff --git a/gate.cpp b/gate.cpp index f5be4bd..c12ffe1 100644 --- a/gate.cpp +++ b/gate.cpp @@ -6,6 +6,32 @@ 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; diff --git a/ls.cpp b/ls.cpp index b34a949..938d250 100644 --- a/ls.cpp +++ b/ls.cpp @@ -402,12 +402,32 @@ void Circuit::ls_block_recal(Gate* stem) { stem_satisfied[stem->id] = true; stem_total_weight -= stem_weight[stem->id]; stem_total_cnt += 1; + + for(Gate* pre : stem->pre_stems) { + if(flip_need_update[pre->id]) continue; + + flip_need_update[pre->id] = true; + flip_update_queue.push_back(pre); + + flip_total_weight += flip_weight[pre->id]; + flip_total_cnt += 1; + } } if(stem->cal_value() != stem->value && stem_satisfied[stem->id]) { stem_satisfied[stem->id] = false; stem_total_weight += stem_weight[stem->id]; stem_total_cnt -= 1; + + for(Gate* pre : stem->pre_stems) { + if(flip_need_update[pre->id]) continue; + + flip_need_update[pre->id] = true; + flip_update_queue.push_back(pre); + + flip_total_weight += flip_weight[pre->id]; + flip_total_cnt += 1; + } } } @@ -417,27 +437,14 @@ void Circuit::ls_block_recal(Gate* stem) { used[g] = false; - bool right_value = (g->cal_value() == g->value); for(Gate* in : g->inputs) { - in->value = !in->value; - bool input_detected = (g->cal_value() != g->value); - in->value = !in->value; - - bool sa0 = right_value && input_detected && g->sa[!g->value] && in->value; - bool sa1 = right_value && input_detected && g->sa[!g->value] && !in->value; - - in->sa_by_out[g] = std::make_pair(sa0, sa1); bool old_sa[2]; old_sa[0] = in->sa[0]; old_sa[1] = in->sa[1]; - in->sa[0] = in->sa[1] = 0; - for(Gate* out : in->outputs) { - auto &p = in->sa_by_out[out]; - in->sa[0] |= p.first; - in->sa[1] |= p.second; - } + in->sa[0] = in->cal_sa(0); + in->sa[1] = in->cal_sa(1); if(in->stem && !in->isPI && (in->sa[0] != old_sa[0] || in->sa[1] != old_sa[1])) {