From 9fdc584fe67a0b0bf72cf3d6e0ebcef1ca28698c Mon Sep 17 00:00:00 2001 From: YuhangQ Date: Sat, 11 Nov 2023 04:20:22 +0000 Subject: [PATCH] newc --- .gitignore | 0 .vscode/c_cpp_properties.json | 0 .vscode/launch.json | 0 .vscode/settings.json | 3 +- .vscode/tasks.json | 0 CMakeLists.txt | 0 README.md | 0 benchmark/b01.bench | 0 benchmark/b03.bench | 0 benchmark/b04.bench | 0 benchmark/b06.bench | 0 benchmark/b07.bench | 0 benchmark/b08.bench | 0 benchmark/b09.bench | 0 benchmark/b10.bench | 0 benchmark/b11.bench | 0 benchmark/b12.bench | 0 benchmark/b13.bench | 0 benchmark/b17.bench | 0 benchmark/b20.bench | 0 benchmark/b21.bench | 0 benchmark/b22.bench | 0 benchmark/c1355.bench | 0 benchmark/c17.bench | 0 benchmark/c1908.bench | 0 benchmark/c2670.bench | 0 benchmark/c3540.bench | 0 benchmark/c432.bench | 0 benchmark/c499.bench | 0 benchmark/c5315.bench | 0 benchmark/c6288.bench | 0 benchmark/c7552.bench | 0 benchmark/c880.bench | 0 report/atalanta_b10000_iscas85.txt | 0 report/atalanta_b1000_itc99.txt | 0 report/atalanta_b20_itc99.txt | 0 report/atalanta_itc99.txt | 0 report/atpg-ls-动态增量-仿真.txt | 0 report/atpg-ls-动态增量.txt | 0 report/atpg-ls.txt | 0 report/tgpro_iscas85.txt | 0 report/tgpro_itc99.txt | 0 report/tgpro_itc99_cutoff1000.txt | 0 src/CMakeLists.txt | 0 src/checker.cpp | 16 +- src/checker.h | 4 +- src/circuit.cpp | 500 ++++++------- src/circuit.h | 68 +- src/cmdline.h | 0 src/fault.h | 15 + src/gate.cpp | 2 + src/gate.h | 31 +- src/ls.cpp | 770 ++++++++------------ src/lut.cpp | 205 ------ src/lut.h | 78 -- src/main.cpp | 26 +- src/paras.cpp | 0 src/paras.h | 0 src/parse.cpp | 0 src/pattern.h | 2 +- src/sat_atpg.cpp | 5 +- src/sat_atpg.h | 0 src/score.cpp | 143 +--- src/simulator.cpp | 94 +-- src/simulator.h | 4 +- test.txt | 1086 ++++++++++++++++++++++++++++ 66 files changed, 1776 insertions(+), 1276 deletions(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 .vscode/c_cpp_properties.json mode change 100644 => 100755 .vscode/launch.json mode change 100644 => 100755 .vscode/settings.json mode change 100644 => 100755 .vscode/tasks.json mode change 100644 => 100755 CMakeLists.txt mode change 100644 => 100755 README.md mode change 100644 => 100755 benchmark/b01.bench mode change 100644 => 100755 benchmark/b03.bench mode change 100644 => 100755 benchmark/b04.bench mode change 100644 => 100755 benchmark/b06.bench mode change 100644 => 100755 benchmark/b07.bench mode change 100644 => 100755 benchmark/b08.bench mode change 100644 => 100755 benchmark/b09.bench mode change 100644 => 100755 benchmark/b10.bench mode change 100644 => 100755 benchmark/b11.bench mode change 100644 => 100755 benchmark/b12.bench mode change 100644 => 100755 benchmark/b13.bench mode change 100644 => 100755 benchmark/b17.bench mode change 100644 => 100755 benchmark/b20.bench mode change 100644 => 100755 benchmark/b21.bench mode change 100644 => 100755 benchmark/b22.bench mode change 100644 => 100755 benchmark/c1355.bench mode change 100644 => 100755 benchmark/c17.bench mode change 100644 => 100755 benchmark/c1908.bench mode change 100644 => 100755 benchmark/c2670.bench mode change 100644 => 100755 benchmark/c3540.bench mode change 100644 => 100755 benchmark/c432.bench mode change 100644 => 100755 benchmark/c499.bench mode change 100644 => 100755 benchmark/c5315.bench mode change 100644 => 100755 benchmark/c6288.bench mode change 100644 => 100755 benchmark/c7552.bench mode change 100644 => 100755 benchmark/c880.bench mode change 100644 => 100755 report/atalanta_b10000_iscas85.txt mode change 100644 => 100755 report/atalanta_b1000_itc99.txt mode change 100644 => 100755 report/atalanta_b20_itc99.txt mode change 100644 => 100755 report/atalanta_itc99.txt mode change 100644 => 100755 report/atpg-ls-动态增量-仿真.txt mode change 100644 => 100755 report/atpg-ls-动态增量.txt mode change 100644 => 100755 report/atpg-ls.txt mode change 100644 => 100755 report/tgpro_iscas85.txt mode change 100644 => 100755 report/tgpro_itc99.txt mode change 100644 => 100755 report/tgpro_itc99_cutoff1000.txt mode change 100644 => 100755 src/CMakeLists.txt mode change 100644 => 100755 src/checker.cpp mode change 100644 => 100755 src/checker.h mode change 100644 => 100755 src/circuit.cpp mode change 100644 => 100755 src/circuit.h mode change 100644 => 100755 src/cmdline.h mode change 100644 => 100755 src/fault.h mode change 100644 => 100755 src/gate.cpp mode change 100644 => 100755 src/gate.h mode change 100644 => 100755 src/ls.cpp delete mode 100644 src/lut.cpp delete mode 100644 src/lut.h mode change 100644 => 100755 src/main.cpp mode change 100644 => 100755 src/paras.cpp mode change 100644 => 100755 src/paras.h mode change 100644 => 100755 src/parse.cpp mode change 100644 => 100755 src/pattern.h mode change 100644 => 100755 src/sat_atpg.cpp mode change 100644 => 100755 src/sat_atpg.h mode change 100644 => 100755 src/score.cpp mode change 100644 => 100755 src/simulator.cpp mode change 100644 => 100755 src/simulator.h create mode 100755 test.txt diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json old mode 100644 new mode 100755 diff --git a/.vscode/launch.json b/.vscode/launch.json old mode 100644 new mode 100755 diff --git a/.vscode/settings.json b/.vscode/settings.json old mode 100644 new mode 100755 index 6b25936..269d781 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -90,6 +90,7 @@ "csignal": "cpp", "strstream": "cpp", "codecvt": "cpp", - "cfenv": "cpp" + "cfenv": "cpp", + "*.ipp": "cpp" } } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json old mode 100644 new mode 100755 diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/benchmark/b01.bench b/benchmark/b01.bench old mode 100644 new mode 100755 diff --git a/benchmark/b03.bench b/benchmark/b03.bench old mode 100644 new mode 100755 diff --git a/benchmark/b04.bench b/benchmark/b04.bench old mode 100644 new mode 100755 diff --git a/benchmark/b06.bench b/benchmark/b06.bench old mode 100644 new mode 100755 diff --git a/benchmark/b07.bench b/benchmark/b07.bench old mode 100644 new mode 100755 diff --git a/benchmark/b08.bench b/benchmark/b08.bench old mode 100644 new mode 100755 diff --git a/benchmark/b09.bench b/benchmark/b09.bench old mode 100644 new mode 100755 diff --git a/benchmark/b10.bench b/benchmark/b10.bench old mode 100644 new mode 100755 diff --git a/benchmark/b11.bench b/benchmark/b11.bench old mode 100644 new mode 100755 diff --git a/benchmark/b12.bench b/benchmark/b12.bench old mode 100644 new mode 100755 diff --git a/benchmark/b13.bench b/benchmark/b13.bench old mode 100644 new mode 100755 diff --git a/benchmark/b17.bench b/benchmark/b17.bench old mode 100644 new mode 100755 diff --git a/benchmark/b20.bench b/benchmark/b20.bench old mode 100644 new mode 100755 diff --git a/benchmark/b21.bench b/benchmark/b21.bench old mode 100644 new mode 100755 diff --git a/benchmark/b22.bench b/benchmark/b22.bench old mode 100644 new mode 100755 diff --git a/benchmark/c1355.bench b/benchmark/c1355.bench old mode 100644 new mode 100755 diff --git a/benchmark/c17.bench b/benchmark/c17.bench old mode 100644 new mode 100755 diff --git a/benchmark/c1908.bench b/benchmark/c1908.bench old mode 100644 new mode 100755 diff --git a/benchmark/c2670.bench b/benchmark/c2670.bench old mode 100644 new mode 100755 diff --git a/benchmark/c3540.bench b/benchmark/c3540.bench old mode 100644 new mode 100755 diff --git a/benchmark/c432.bench b/benchmark/c432.bench old mode 100644 new mode 100755 diff --git a/benchmark/c499.bench b/benchmark/c499.bench old mode 100644 new mode 100755 diff --git a/benchmark/c5315.bench b/benchmark/c5315.bench old mode 100644 new mode 100755 diff --git a/benchmark/c6288.bench b/benchmark/c6288.bench old mode 100644 new mode 100755 diff --git a/benchmark/c7552.bench b/benchmark/c7552.bench old mode 100644 new mode 100755 diff --git a/benchmark/c880.bench b/benchmark/c880.bench old mode 100644 new mode 100755 diff --git a/report/atalanta_b10000_iscas85.txt b/report/atalanta_b10000_iscas85.txt old mode 100644 new mode 100755 diff --git a/report/atalanta_b1000_itc99.txt b/report/atalanta_b1000_itc99.txt old mode 100644 new mode 100755 diff --git a/report/atalanta_b20_itc99.txt b/report/atalanta_b20_itc99.txt old mode 100644 new mode 100755 diff --git a/report/atalanta_itc99.txt b/report/atalanta_itc99.txt old mode 100644 new mode 100755 diff --git a/report/atpg-ls-动态增量-仿真.txt b/report/atpg-ls-动态增量-仿真.txt old mode 100644 new mode 100755 diff --git a/report/atpg-ls-动态增量.txt b/report/atpg-ls-动态增量.txt old mode 100644 new mode 100755 diff --git a/report/atpg-ls.txt b/report/atpg-ls.txt old mode 100644 new mode 100755 diff --git a/report/tgpro_iscas85.txt b/report/tgpro_iscas85.txt old mode 100644 new mode 100755 diff --git a/report/tgpro_itc99.txt b/report/tgpro_itc99.txt old mode 100644 new mode 100755 diff --git a/report/tgpro_itc99_cutoff1000.txt b/report/tgpro_itc99_cutoff1000.txt old mode 100644 new mode 100755 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/src/checker.cpp b/src/checker.cpp old mode 100644 new mode 100755 index b40fe1a..6ffefe3 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -8,7 +8,7 @@ namespace atpg_ls { Circuit *right_circuit; Circuit *wrong_circuit; -int check_fault(const Pattern &p, const TMP_FAULT &f) { +int check_fault(const Pattern &p, const Fault &f) { for(int i=0; iPIs[i]->value = p.input_vector[i]; wrong_circuit->PIs[i]->value = p.input_vector[i]; @@ -19,7 +19,7 @@ int check_fault(const Pattern &p, const TMP_FAULT &f) { } for(Gate* gate : wrong_circuit->gates) { - if(gate->name == f.g->name) { + if(gate->name == f.gate->name) { gate->value = f.stuck_at; continue; } @@ -34,14 +34,14 @@ int check_fault(const Pattern &p, const TMP_FAULT &f) { return false; } -int final_check(const std::set &faults, const std::vector &patterns) { +int final_check(const std::set &faults, const std::vector &patterns) { - std::set detected_faults; + std::set detected_faults; for(auto &p : patterns) { for(auto &f : p.detected_faults) { - printf("checking fault %s %d ... ", f.g->name.c_str(), f.stuck_at); + // printf("checking fault %s %d ... ", f.g->name.c_str(), f.stuck_at); assert(faults.count(f)); assert(detected_faults.count(f) == 0); @@ -56,16 +56,16 @@ int final_check(const std::set &faults, const std::vector &p int detected = check_fault(p, f); if(detected) { - printf("detected\n"); + // printf("detected\n"); detected_faults.insert(f); } else { - printf("undetected\n"); + // printf("undetected\n"); assert(false); } } } - printf("final coverage: %d/%d(%.2f) pattern: %d\n", detected_faults.size(), faults.size(), (double)detected_faults.size()/faults.size(), patterns.size()); + printf("final coverage: (%.2f)%d/%d pattern: %d\n", (double)detected_faults.size()/faults.size() * 100,detected_faults.size(), faults.size(), , patterns.size()); return 1; } diff --git a/src/checker.h b/src/checker.h old mode 100644 new mode 100755 index 517f000..ff3869c --- a/src/checker.h +++ b/src/checker.h @@ -8,8 +8,8 @@ namespace atpg_ls { -int check_fault(const Pattern &p, const TMP_FAULT &f); -int final_check(const std::set &faults, const std::vector &patterns); +int check_fault(const Pattern &p, const Fault &f); +int final_check(const std::set &faults, const std::vector &patterns); void init_final_checker(); }; diff --git a/src/circuit.cpp b/src/circuit.cpp old mode 100644 new mode 100755 index 52ce829..fb6f191 --- a/src/circuit.cpp +++ b/src/circuit.cpp @@ -1,159 +1,230 @@ #include #include +#include #include "circuit.h" +#include "simulator.h" #include "paras.h" using namespace atpg_ls; -void LUTCircuit::print() { - - std::set st; - - int total_gate = 0; - - printf("PIs: ( "); - for(LUT* lut : PIs) { - printf("%s ", lut->gate->name.c_str()); - } - printf(")\n"); - printf("POs: ( "); - for(LUT* lut : POs) { - printf("%s ", lut->gate->name.c_str()); - } - printf(")\n"); - - - - for(LUT* lut : luts) { - - printf("[v:%d vs:%d fd0:%d fd1:%d] ", lut->value, lut->vsat, lut->fd[0], lut->fd[1]); - printf("lut: %s inputs: ( ", lut->gate->name.c_str()); - - total_gate += lut->inner_gates.size(); - - for(LUT* in : lut->fanins) { - printf("%s ", in->gate->name.c_str()); - } - printf(")\n"); - } - - printf("total gate: %d\n", total_gate); +std::string gen_name() { + static int i = 0; + return "E" + std::to_string(++i); } +Gate* create_not_gate(Gate* gate) { + Gate* not_gate = new Gate(); + not_gate->name = gen_name(); + not_gate->is_extra_gate = 1; + not_gate->type = Gate::NOT; + not_gate->fanins.push_back(gate); + gate->fanouts.push_back(not_gate); + return not_gate; +} +void Circuit::rebuild_atpg_circuit() { + int sz = gates.size(); + assert(sz == simulator->gates.size()); + for(Gate* gate : rtopo_gates) { -LUTCircuit* Circuit::build_lut_circuit() { + // 对于 PO 直接可以输出 SA0 = value 和 SA1 = NOT(value) + if(gate->isPO) { + Gate* extra_gate0 = new Gate(); + extra_gate0->type = Gate::BUF; + extra_gate0->fanins.push_back(gate); + gate->fanouts.push_back(extra_gate0); + extra_gate0->is_extra_gate = 1; + gates.push_back(extra_gate0); + extra_gate0->name = "SA0_" + gate->name; - LUTCircuit* C = new LUTCircuit(); - C->C = this; + Gate* extra_gate1 = new Gate(); + extra_gate1->type = Gate::NOT; + extra_gate1->fanins.push_back(gate); + gate->fanouts.push_back(extra_gate1); + extra_gate1->is_extra_gate = 1; + gates.push_back(extra_gate1); + extra_gate1->name = "SA1_" + gate->name; - std::unordered_map gate2LUT; + // gate->isPO = false; - std::queue q; - std::set done; - - for(Gate* gate : gates) { - // assert fanouts >= 2 - if(gate->fanouts.size() >= 2 || gate->isPI || (gate->isPO && gate->fanouts.size() == 0)) { - q.push(gate); - done.insert(gate); + gate->stuck_at_gate[0] = extra_gate0; + gate->stuck_at_gate[1] = extra_gate1; + continue; } - } - while(!q.empty()) { - Gate* gate = q.front(); - q.pop(); + // create a gate for SA_i - LUT* lut = new LUT(gate, C); - - gate2LUT[gate] = lut; - - // printf("size: %d lut: %s inputs: ( ", lut->inner_gates.size(), lut->gate->name.c_str()); - // for(Gate* in : lut->__gate_fanins) { - // printf("%s ", in->name.c_str()); - // } - // printf(") ["); + std::vector or_inputs; - // for(Gate* inner : lut->inner_gates) { - // printf("%s ", inner->name.c_str()); - // } - // printf("]\n"); + for(Gate *out : gate->fanouts) { - for(Gate* in : lut->__gate_fanins) { - if(in->fanouts.size() < 2 && !in->isPI && done.count(in) == 0) { - done.insert(in); - q.push(in); + if(out->is_extra_gate) continue; + + // if the fault SA(!out->value) can be detected + Gate* out_detected = new Gate(); + out_detected->name = gen_name(); + out_detected->is_extra_gate = 1; + out_detected->type = Gate::OR; + out_detected->fanins.push_back(out->stuck_at_gate[0]); + out_detected->fanins.push_back(out->stuck_at_gate[1]); + + assert(out->stuck_at_gate[0]); + assert(out->stuck_at_gate[1]); + + out->stuck_at_gate[0]->fanouts.push_back(out_detected); + out->stuck_at_gate[1]->fanouts.push_back(out_detected); + + gates.push_back(out_detected); + + if(out->type == Gate::XOR || out->type == Gate::XNOR || out->type == Gate::NOT || out->type == Gate::BUF || out->type == Gate::LINE) { + or_inputs.push_back(out_detected); + continue; + } + + Gate *extra_gate = new Gate(); + extra_gate->is_extra_gate = 1; + extra_gate->type = Gate::AND; + extra_gate->name = gen_name(); + gates.push_back(extra_gate); + + + for(Gate *in_of_out : out->fanins) { + if(in_of_out == gate) continue; + + if(out->type == Gate::AND || out->type == Gate::NAND) { + + in_of_out->fanouts.push_back(extra_gate); + extra_gate->fanins.push_back(in_of_out); + + } else if(out->type == Gate::OR || out->type == Gate::NOR) { + + Gate* not_gate = create_not_gate(in_of_out); + not_gate->name = gen_name(); + gates.push_back(not_gate); + not_gate->fanouts.push_back(extra_gate); + extra_gate->fanins.push_back(not_gate); + + } else { + assert(0); + } + } + + extra_gate->fanins.push_back(out_detected); + out_detected->fanouts.push_back(extra_gate); + + or_inputs.push_back(extra_gate); + } + + Gate* or_gate; + if(or_inputs.size() == 1) { + or_gate = or_inputs[0]; + } else { + or_gate = new Gate(); + gates.push_back(or_gate); + or_gate->name = gen_name(); + or_gate->is_extra_gate = 1; + or_gate->type = Gate::OR; + for(Gate* in : or_inputs) { + or_gate->fanins.push_back(in); + in->fanouts.push_back(or_gate); } } - C->luts.push_back(lut); + Gate* p_sa0 = new Gate(); + gates.push_back(p_sa0); + p_sa0->is_extra_gate = 1; + p_sa0->type = Gate::AND; + p_sa0->fanins.push_back(or_gate); + p_sa0->fanins.push_back(gate); + or_gate->fanouts.push_back(p_sa0); + gate->fanouts.push_back(p_sa0); + + Gate* p_sa1 = new Gate(); + gates.push_back(p_sa1); + p_sa1->is_extra_gate = 1; + p_sa1->type = Gate::AND; + p_sa1->fanins.push_back(or_gate); + or_gate->fanouts.push_back(p_sa1); + + Gate* not_gate = create_not_gate(gate); + not_gate->name = gen_name(); + gates.push_back(not_gate); + + p_sa1->fanins.push_back(not_gate); + not_gate->fanouts.push_back(p_sa1); + + gate->stuck_at_gate[0] = p_sa0; + gate->stuck_at_gate[1] = p_sa1; + + p_sa0->name = "SA0_" + gate->name; + p_sa1->name = "SA1_" + gate->name; } - for(LUT* lut : C->luts) { + // for(Gate* po : POs) { + // po->isPO = false; + // } + // POs.clear(); - lut->name = lut->gate->name.c_str(); + for(Gate* g : gates) { + if(g->is_extra_gate) continue; + assert(g->stuck_at_gate[0]); + assert(g->stuck_at_gate[1]); - std::sort(lut->inner_gates.begin(), lut->inner_gates.end(), [](Gate* a, Gate* b) { - return a->id < b->id; - }); + g->stuck_at_gate[0]->isPO = 1; + g->stuck_at_gate[1]->isPO = 1; - for(Gate* in : lut->__gate_fanins) { - assert(gate2LUT.count(in) > 0); - - lut->fanins.push_back(gate2LUT[in]); - gate2LUT[in]->fanouts.push_back(lut); - } + POs.push_back(g->stuck_at_gate[0]); + POs.push_back(g->stuck_at_gate[1]); - if(lut->isPI) { - C->PIs.push_back(lut); - lut->isPI = 1; - } - if(lut->isPO) { - C->POs.push_back(lut); - lut->isPO = 1; + } + + init_topo_index(); + + for(Gate* pi : PIs) { + pi->value = rand() % 2; + } + + for(Gate* g : gates) { + g->value = g->cal_value(); + } + + for(Gate* g : rtopo_gates) { + if(g->is_extra_gate) continue; + + g->fault_detected[0] = g->cal_fault_detected(0); + g->fault_detected[1] = g->cal_fault_detected(1); + + assert(g->fault_detected[0] == g->stuck_at_gate[0]->value); + assert(g->fault_detected[1] == g->stuck_at_gate[1]->value); + } + + for(Gate* g : gates) { + if(g->is_extra_gate) continue; + original_gates.push_back(g); + } + + for(int i=0; iindex = i; + simulator->name2gate[original_gates[i]->name]->index = i; + } + + std::vector t_POs; + + for(Gate* po : POs) { + if(po->is_extra_gate) { + t_POs.push_back(po); } } - for(LUT* lut : C->luts) { - C->rtopo_luts.push_back(lut); - } - - std::sort(C->luts.begin(), C->luts.end(), [](LUT* a, LUT* b) { - return a->gate->id < b->gate->id; - }); - - std::sort(C->rtopo_luts.begin(), C->rtopo_luts.end(), [](LUT* a, LUT* b) { - return a->gate->rtopo < b->gate->rtopo; - }); - - for(LUT* lut : C->luts) { - for(int i=0; iinner_gates.size(); i++) { - Gate *g = lut->inner_gates[i]; - g->parent_lut = lut; - g->id_in_lut = lut->fanins.size() + i; - } - } - - for(LUT* lut : C->luts) { - for(int i=0; ifanins.size(); i++) { - LUT* in = lut->fanins[i]; - in->fanouts_with_id.push_back(std::make_pair(lut, i)); - } - } - - for(LUT* lut : C->luts) { - assert(lut->fanouts.size() == lut->fanouts_with_id.size()); - } - - return C; + POs = t_POs; + assert(original_gates.size() * 2 == POs.size()); + assert(original_gates.size() == sz); } - - void Circuit::insert_lines_for_stem() { for(int j=0; jname, line)); } - printf(">>>> now: %s\n", g->name.c_str()); + // printf(">>>> now: %s\n", g->name.c_str()); - printf("outs: [ "); - for(Gate* out :g->fanouts){ - printf("%s ", out->name.c_str()); - } - printf("]\n"); + // printf("outs: [ "); + // for(Gate* out :g->fanouts){ + // printf("%s ", out->name.c_str()); + // } + // printf("]\n"); for(int i=0; ifanouts.size(); i++) { Gate* out = g->fanouts[i]; if(out->type == Gate::LINE) break; - printf(" g_name: %s outname: %s\n", g->name.c_str(), out->name.c_str()); + // printf(" g_name: %s outname: %s\n", g->name.c_str(), out->name.c_str()); Gate* line = new Gate(); line->name = g->name + "_line_" + out->name; line->type = Gate::LINE; line->isPI = false; line->isPO = false; + line->is_stem = false; line->fanins.push_back(g); line->fanouts.push_back(out); @@ -224,72 +296,6 @@ void Circuit::insert_lines_for_stem() { } -void Circuit::init_avg_dist() { - - int *now_dist = new int[gates.size() + 1] { 0 }; - int *total_dist = new int[gates.size() + 1] { 0 }; - int *total_cnt = new int[gates.size() + 1] { 0 }; - // int *topo_cnt = new int[gates.size() + 1] { 0 }; - - // memset(total_dist, 0, sizeof(int) * (gates.size() + 1)); - - for(Gate* po : POs) { - // memset(topo_cnt, 0, sizeof(int) * (gates.size() + 1)); - // memset(now_dist, 0x3f, sizeof(int) * (gates.size() + 1)); - for(Gate* g : gates) { - if(g->isPO) { - now_dist[g->id] = 0; - } else { - now_dist[g->id] = 0x3f3f3f3f; - } - } - - // printf(">> po: %s\n", po->name.c_str()); - - std::queue q; - q.push(po); - - while(!q.empty()) { - Gate* u = q.front(); q.pop(); - - total_dist[u->id] += now_dist[u->id]; - total_cnt[u->id] ++; - - // printf("now: %s\n", u->name.c_str()); - - for(Gate* in : u->fanins) { - if(now_dist[u->id] + 1 < now_dist[in->id]) { - now_dist[in->id] = now_dist[u->id] + 1; - q.push(in); - } - } - - // printf("dist: %d\n", total_dist[name2gate["G132"]->id]); - } - } - - for(Gate* g : gates) { - - if(total_cnt[g->id] <= 0) { - printf("ERROR: gate: %s total: %d cnt: %d\n", g->name.c_str(), total_dist[g->id], total_cnt[g->id]); - exit(-1); - } - - assert(total_cnt[g->id] > 0); - - g->avg_dist = total_dist[g->id] / total_cnt[g->id]; - - printf("ERROR: gate: %s total: %d cnt: %d\n", g->name.c_str(), total_dist[g->id], total_cnt[g->id]); - - // if(g->id) - if(!g->isPO) assert(g->avg_dist > 0); - } - - delete [] now_dist; - delete [] total_dist; - delete [] total_cnt; -} - void Circuit::init_topo_index() { int topo = 1; std::queue q; @@ -315,6 +321,8 @@ void Circuit::init_topo_index() { } } + rtopo_gates.clear(); + // 计算反向拓扑序 topo = 1; std::unordered_map outs; @@ -346,6 +354,8 @@ void Circuit::init_topo_index() { } } + assert(gates.size() == rtopo_gates.size()); + std::sort(gates.begin(), gates.end(), [](Gate* a, Gate* b) { return a->id < b->id; }); @@ -362,8 +372,14 @@ void Circuit::print() { const char *name[10] = {"AND", "NAND", "OR", "NOR", "XOR", "XNOR", "NOT", "BUF", "INPUT", "LINE"}; + + for(Gate* g : gates) { - printf("[sa0: %d sa1: %d v: %d vsat: %d] %s = %s (",g->fault_detected[0], g->fault_detected[1], g->value, g->cal_value() == g->value, g->name.c_str(), name[g->type]); + std::string out_name = "unknown"; + if(g->name != "") { + out_name = g->name; + } + printf("[sa0: %d sa1: %d v: %d vsat: %d] %s = %s (",g->fault_detected[0], g->fault_detected[1], g->value, g->cal_value() == g->value, out_name.c_str(), name[g->type]); for(Gate* in : g->fanins) { printf("%s ", in->name.c_str()); } @@ -377,76 +393,64 @@ void Circuit::print() { printf(")\n"); } -double LUTCircuit::check() { - // static bool init = 0; - // static std::unordered_set dt; - printf("checking circuit ...\n"); +void Circuit::init_faults() { - double score_value_unsatisfied_cost = 0; - double score_fault_detected_weight = 0; - double score_fault_propagated_weight = 0; - double score_fault_update_cost = 0; - int unsatisfied_lut = 0; + int sz = gates.size(); + assert(sz == simulator->gates.size()); + for(int i=0; iname == simulator->gates[i]->name); + simulator->gates[i]->ori_gate = gates[i]; + gates[i]->sim_gate = simulator->gates[i]; + } - for(LUT* lut : luts) { - assert(lut->vsat == (lut->value == lut->cal_value())); + std::vector faults; - if(!lut->vsat) { - score_value_unsatisfied_cost += lut->vunat_cost; - unsatisfied_lut++; - // printf("vunsat: %s\n", lut->name); - } + for(Gate* g : gates) { - if(lut->uptag) { - score_fault_update_cost += lut->up_cost; + std::string name = g->name; + + if(g->is_stem) { + faults.push_back(TMP_FAULT{g, name, 0, 1, 0}); + faults.push_back(TMP_FAULT{g, name, 1, 1, 0}); } else { - int t_fd[2], t_fpl[2]; - lut->cal_fault_info(t_fd, t_fpl); - assert(t_fd[0] == lut->fd[0]); - assert(t_fd[1] == lut->fd[1]); - assert(t_fpl[0] == lut->fpl[0]); - assert(t_fpl[1] == lut->fpl[1]); - } - int input = 0; - for(int i=0; ifanins.size(); i++) { - input |= (lut->fanins[i]->value << i); - } - input <<= 1; - input |= lut->value; + if(g->isPO) { + faults.push_back(TMP_FAULT{g, name, 0, g->type != Gate::LINE, g->type == Gate::LINE}); + faults.push_back(TMP_FAULT{g, name, 1, g->type != Gate::LINE, g->type == Gate::LINE}); + continue; + } - for(int i=lut->fanins.size(); ifanins.size()+lut->inner_gates.size(); i++) { - LUT::FaultInfo &info = lut->fault_table[i][input]; - Gate* g = lut->inner_gates[i-lut->fanins.size()]; - - int t_fd[2], t_fpl[2]; - t_fd[0] = info.fd[0] && lut->fd[!lut->value]; - t_fd[1] = info.fd[1] && lut->fd[!lut->value]; - t_fpl[0] = info.fpl[0] + info.fd[0] * lut->fpl[!lut->value]; - t_fpl[1] = info.fpl[1] + info.fd[1] * lut->fpl[!lut->value]; + assert(g->fanouts.size() == 1); - score_fault_detected_weight += t_fd[0] * g->fault_detected_weight[0]; - score_fault_detected_weight += t_fd[1] * g->fault_detected_weight[1]; + Gate *fanout = g->fanouts[0]; - if(!g->isPO) { - score_fault_propagated_weight += (double)t_fpl[0] / g->avg_dist * g->fault_detected_weight[0]; - score_fault_propagated_weight += (double)t_fpl[1] / g->avg_dist * g->fault_detected_weight[1]; + int stem = (!g->isPI) && (g->type != Gate::LINE); + + if(fanout->type == Gate::Type::BUF || fanout->type == Gate::Type::NOT) { + continue; + } else if(fanout->type == Gate::Type::XOR || fanout->type == Gate::Type::XNOR) { + faults.push_back(TMP_FAULT{g, name, 0, stem, 0}); + faults.push_back(TMP_FAULT{g, name, 1, stem, 0}); + } else if(fanout->type == Gate::Type::NAND || fanout->type == Gate::Type::AND) { + faults.push_back(TMP_FAULT{g, name, 1, stem, 0}); + } else if(fanout->type == Gate::Type::NOR || fanout->type == Gate::Type::OR) { + faults.push_back(TMP_FAULT{g, name, 0, stem, 0}); + } else { + assert(false); } } } - printf("=====================================\n"); - printf("unsat_lut: %d\n", unsatisfied_lut); - printf("score_value_unsatisfied_cost: %.2f\n", score_value_unsatisfied_cost); - printf("score_fault_detected_weight: %.2f\n", score_fault_detected_weight); - printf("score_fault_propagated_weight: %.2f\n", score_fault_propagated_weight); - printf("score_fault_update_cost: %.2f\n", score_fault_update_cost); - - double score = - score_value_unsatisfied_cost + score_fault_detected_weight + score_fault_propagated_weight - score_fault_update_cost; + printf("fault-size: %d\n", faults.size()); - printf("score: %d\n", score); + for(TMP_FAULT &f : faults) { + mp[Fault{f.g, f.stuck_at}] = f; + this->faults.insert(Fault{f.g, f.stuck_at}); + } - return score; + this->unknown_faults = this->faults; + + assert(faults.size() == mp.size()); } \ No newline at end of file diff --git a/src/circuit.h b/src/circuit.h old mode 100644 new mode 100755 index 5951cd0..c55354f --- a/src/circuit.h +++ b/src/circuit.h @@ -1,44 +1,15 @@ #pragma once #include "fault.h" -#include "lut.h" + +#include +#include using ll = long long; namespace atpg_ls { class Simulator; -class Circuit; - -class LUTCircuit { -public: -std::vector PIs; -std::vector POs; -std::vector luts; -std::vector rtopo_luts; - -int** fault_detected; - -void print(); - -// local search -void ls_update(std::vector &unsat); -LUT* ls_pick(); -void ls_flip(LUT *lut); -void ls_main(); -void ls_init(); -void ls_random_sol(); -void ls_gen_sol(const TMP_FAULT &target); - -// checker -double check(); - -Simulator *simulator; -Circuit *C; - -int step; - -}; class Circuit { public: @@ -46,18 +17,45 @@ std::vector PIs; std::vector POs; std::vector gates; std::vector rtopo_gates; +std::vector original_gates; + +// std::vector test; std::unordered_map name2gate; void parse_from_file(const char *filename); void insert_lines_for_stem(); +void rebuild_atpg_circuit(); +void init_faults(); +int cal_circuit_score(); void print(); -LUTCircuit* build_lut_circuit(); - void init_topo_index(); -void init_avg_dist(); + +// atpg info + +std::set detected_faults; +std::set undetected_faults; +std::set unknown_faults; +std::set faults; + +std::map mp; + +void ls_update(); +Gate* ls_pick(); +void ls_flip(Gate *gate); +void ls_main(); +void ls_init(); +void ls_random_sol(); +void ls_gen_sol(const Fault &f); + +// checker +double check(); + +// simulator + +Simulator *simulator; }; diff --git a/src/cmdline.h b/src/cmdline.h old mode 100644 new mode 100755 diff --git a/src/fault.h b/src/fault.h old mode 100644 new mode 100755 index 2a88829..9a3a84a --- a/src/fault.h +++ b/src/fault.h @@ -4,6 +4,21 @@ namespace atpg_ls { +struct Fault { + Gate* gate; + int stuck_at; + + friend bool operator < (const Fault &lhs, const Fault &rhs) { + if(lhs.gate != rhs.gate) { + return lhs.gate < rhs.gate; + } + if(lhs.stuck_at != rhs.stuck_at) { + return lhs.stuck_at < rhs.stuck_at; + } + return false; + } +}; + struct TMP_FAULT { /* data */ Gate *g; diff --git a/src/gate.cpp b/src/gate.cpp old mode 100644 new mode 100755 index 081e636..734039b --- a/src/gate.cpp +++ b/src/gate.cpp @@ -15,6 +15,7 @@ int Gate::cal_propagate_len(bool x) { } for(Gate* out : fanouts) { + if(out->is_extra_gate) continue; if(!out->is_detected(this)) continue; fpl[!value] = std::max(fpl[!value], out->fault_propagated_len[!out->value] + 1); } @@ -45,6 +46,7 @@ bool Gate::cal_fault_detected(bool x) { for(Gate* out : fanouts) { if(!out->is_propagated()) continue; if(out->cal_value() != out->value) continue; + if(out->is_extra_gate) continue; this->value = !this->value; bool detect = (out->cal_value() != out->value); diff --git a/src/gate.h b/src/gate.h old mode 100644 new mode 100755 index 1b85eb1..68656ba --- a/src/gate.h +++ b/src/gate.h @@ -17,9 +17,19 @@ public: // gate basic info + Gate() { + is_extra_gate = 0; + sim_gate = 0; + ori_gate = 0; + isPI = 0; + isPO = 0; + } + int id; int level; int rtopo; + int index; + std::string name; enum Type { AND, NAND, OR, NOR, XOR, XNOR, NOT, BUF, INPUT, LINE } type; int value; @@ -28,6 +38,15 @@ public: std::vector fanouts; std::vector fanins; std::vector reigon; + + int weight; + + bool is_extra_gate; + Gate* stuck_at_gate[2]; + + int v_sat; + int unsat_cost; + int is_good_var; int avg_dist; @@ -41,18 +60,24 @@ public: int cal_value(); + int score; + void cal_score(); + bool cal_fault_detected(bool x); bool is_detected(Gate* one_of_input); int cal_propagate_len(bool x); - LUT* parent_lut; - int id_in_lut; - int is_stem; void cal_fault_info(int fd[2], int fpl[2]); + + int CC; + + // for simulate; + Gate* ori_gate; + Gate* sim_gate; // ( partical ) score diff --git a/src/ls.cpp b/src/ls.cpp old mode 100644 new mode 100755 index e4541e2..b4cfb31 --- a/src/ls.cpp +++ b/src/ls.cpp @@ -12,279 +12,325 @@ using namespace atpg_ls; -LUT* LUTCircuit::ls_pick() { +std::set unjust_gates; - LUT* pick = nullptr; - - // 采样 - for(int i=0; iCC) continue; - lut->cal_score(); - if(lut->score <= 0) continue; - if(pick == nullptr || lut->score > pick->score) { - pick = lut; +// score > 0 && CC = 1; +std::vector good_gates; + +int Circuit::cal_circuit_score() { + int score = 0; + + for(Gate* g : gates) { + if(g->value == 1) { + score += g->weight; + } + + assert(g->v_sat == (g->value == g->cal_value())); + + if(!g->v_sat) { + score -= g->unsat_cost; + } + + if(g->v_sat) { + assert(unjust_gates.count(g) == 0); + } else { + assert(unjust_gates.count(g)); } } - if(pick != nullptr) { - return pick; + return score; +} + +void Circuit::ls_init() { + unjust_gates.clear(); + good_gates.clear(); +} + +void Circuit::ls_random_sol() { + for(Gate* gate : gates) { + gate->value = rand() % 2; + } + for(Gate* gate : gates) { + gate->v_sat = (gate->value == gate->cal_value()); + gate->weight = 0; + gate->CC = 1; + gate->unsat_cost = 1; + gate->is_good_var = 0; } - std::vector unsat; + for(Fault f : unknown_faults) { + Gate* g_sai = f.gate->stuck_at_gate[f.stuck_at]; + assert(g_sai != nullptr); + g_sai->weight = 1; + } +} - // 动态加权 - ls_update(unsat); +Gate* Circuit::ls_pick() { + Gate* pick = nullptr; - if(unsat.size() == 0) return nullptr; + if(!good_gates.empty()) { + pick = good_gates[rand() % good_gates.size()]; + if(pick->score > 0 && pick->CC) { + return pick; + } else { + std::vector tmp = good_gates; + good_gates.clear(); + for(Gate* gate : tmp) { + if(gate->score > 0 && gate->CC == 1) { + good_gates.push_back(gate); + } else { + gate->is_good_var = 0; + } + } - pick = unsat[rand() % unsat.size()]; - - if(pick->fanins.size() == 0) { - return pick; + if(!good_gates.empty()) { + pick = good_gates[rand() % good_gates.size()]; + return pick; + } + } } - if(rand() % 10000 < 3000) { - return pick->fanins[rand() % pick->fanins.size()]; + ls_update(); + + std::vector uj; + uj.insert(uj.end(), unjust_gates.begin(), unjust_gates.end()); + + if(!unjust_gates.empty()) { + pick = uj[rand() % uj.size()]; + + if(rand() % 10000 <= 0.7 * 10000) { + return pick->fanins[rand() % pick->fanins.size()]; + } else { + return pick; + } } + + pick = gates[rand() % gates.size()]; + return pick; } -void LUTCircuit::ls_flip(LUT *lut) { +void Circuit::ls_flip(Gate *gate) { + // for(Gate* g : gates) { + // int old = g->score; + // g->cal_score(); + // assert(old == g->score); + // } - lut->CC = 0; - lut->uptag = 0; - lut->flip_value(); - if(!lut->isPI) lut->vsat = !lut->vsat; + gate->value ^= 1; + gate->CC = 0; + gate->is_good_var = 0; - for(LUT* out : lut->fanouts) { - out->CC = 1; - out->vsat = (out->cal_value() == out->value); - } + if(!gate->isPI) { - lut->cal_fault_info(lut->fd, lut->fpl); + gate->v_sat ^= 1; + assert(gate->v_sat == (gate->value == gate->cal_value())); + // printf("test: %d %d\n", gate->v_sat, (gate->value == gate->cal_value())); - for(LUT* r : lut->reigon) { - r->CC = 1; - int t_fd[2], t_fpl[2]; - r->cal_fault_info(t_fd, t_fpl); - - if(t_fd[0] != r->fd[0] || t_fd[1] != r->fd[1] || t_fpl[0] != r->fpl[0] || t_fpl[1] != r->fpl[1]) { - r->uptag = 1; - } - } -} - -void LUTCircuit::ls_update(std::vector &unsat) { - - if(rand() % 10000 <= OPT(sp) * 10000) { - - for(LUT* lut : luts) { - if(lut->vsat) { - if(lut->vunat_cost - OPT(vsat_inc) >= 1) { - lut->vunat_cost -= OPT(vsat_inc); - } - } - if(!lut->vsat) { - unsat.push_back(lut); - } - if(!lut->uptag) { - if(lut->up_cost - OPT(up_inc) >= 1) { - lut->up_cost -= OPT(up_inc); - } - } - for(int i=lut->fanins.size(); ifanins.size()+lut->inner_gates.size(); i++) { - Gate* g = lut->inner_gates[i-lut->fanins.size()]; - LUT::FaultInfo &fi = lut->fault_table[i][lut->input_var]; - if(fi.fd[0] && g->fault_detected_weight[0] - OPT(fw_inc) >= 1) { - g->fault_detected_weight[0] -= OPT(fw_inc); - } - if(fi.fd[1] && g->fault_detected_weight[1] - OPT(fw_inc) >= 1) { - g->fault_detected_weight[1] -= OPT(fw_inc); - } - if(fi.fd[0] && g->fault_propagated_weight[0] - OPT(fw_inc) >= 1) { - g->fault_propagated_weight[0] -= OPT(fw_inc); - } - if(fi.fd[1] && g->fault_propagated_weight[1] + OPT(fw_inc) >= 1) { - g->fault_propagated_weight[1] -= OPT(fw_inc); - } - } - } - - } else { - - for(LUT* lut : luts) { - if(!lut->vsat) { - - // printf("ocost: %d add: %d\n", lut->vunat_cost); - if(lut->vunat_cost + OPT(vsat_inc) > OPT(vsat_max)) { - lut->vunat_cost = OPT(vsat_max); - } else { - lut->vunat_cost += OPT(vsat_inc); - } - // printf("cost: %d add: %d\n", lut->vunat_cost, OPT(vsat_inc)); - - // for(LUT* out : lut->fanouts) { - // if(out->vunat_cost -= OPT(vsat_inc) > 1) { - // out->vunat_cost -= OPT(vsat_inc); - // } else { - // out->vunat_cost = 1; - // } - // } - - unsat.push_back(lut); - } - if(lut->uptag) { - if(lut->up_cost + OPT(up_inc) > OPT(up_max)) { - lut->up_cost = OPT(up_max); - } else { - lut->up_cost += OPT(up_inc); - } - } - for(int i=lut->fanins.size(); ifanins.size()+lut->inner_gates.size(); i++) { - Gate* g = lut->inner_gates[i-lut->fanins.size()]; - LUT::FaultInfo &fi = lut->fault_table[i][lut->input_var]; - if(!fi.fd[0] && g->fault_detected_weight[0] > 0 && g->fault_detected_weight[0] + OPT(fw_inc) <= OPT(fw_max)) { - g->fault_detected_weight[0] += OPT(fw_inc); - } - if(!fi.fd[1] && g->fault_detected_weight[1] > 0 && g->fault_detected_weight[1] + OPT(fw_inc) <= OPT(fw_max)) { - g->fault_detected_weight[1] += OPT(fw_inc); - } - if(!fi.fd[0] && g->fault_propagated_weight[0] > 0 && g->fault_propagated_weight[0] + OPT(fw_inc) <= OPT(fw_max)) { - g->fault_propagated_weight[0] += OPT(fw_inc); - } - if(!fi.fd[1] && g->fault_propagated_weight[0] > 0 && g->fault_propagated_weight[1] + OPT(fw_inc) <= OPT(fw_max)) { - g->fault_propagated_weight[1] += OPT(fw_inc); - } - } - } - } -} - -void LUTCircuit::ls_main() { - - printf("====== local search start ======\n"); - - printf("initing lookup table ...\n"); - ls_init(); - - printf("ganerating fault info ...\n"); - - int num_gates = 0; - int num_total_fault = 0; - int num_detected_fault = 0; - int num_undetected_fault = 0; - int num_pattern = 0; - - for(LUT* lut : luts) { - num_gates += lut->inner_gates.size(); - } - assert(num_gates == C->gates.size()); - fault_detected = new int*[num_gates]; - for(int i=0; i faults; - - for(Gate* g : C->gates) { - - std::string name = g->name; - - if(g->is_stem) { - faults.push(TMP_FAULT{g, name, 0, 1, 0}); - faults.push(TMP_FAULT{g, name, 1, 1, 0}); + if(gate->v_sat) { + unjust_gates.erase(gate); } else { + unjust_gates.insert(gate); + } + } - if(g->isPO) { - faults.push(TMP_FAULT{g, name, 0, g->type != Gate::LINE, g->type == Gate::LINE}); - faults.push(TMP_FAULT{g, name, 1, g->type != Gate::LINE, g->type == Gate::LINE}); - continue; - } + for(Gate* in : gate->fanins) { + in->cal_score(); + in->CC = 1; + if(!in->is_good_var && in->score > 0) { + in->is_good_var = 1; + good_gates.push_back(in); + } + } - assert(g->fanouts.size() == 1); - Gate *fanout = g->fanouts[0]; + for(Gate* out : gate->fanouts) { - int stem = (!g->isPI) && (g->type != Gate::LINE); + if(out->v_sat && (out->value != out->cal_value())) { + out->v_sat = 0; + unjust_gates.insert(out); + } + if(!out->v_sat && (out->value == out->cal_value())) { + out->v_sat = 1; + unjust_gates.erase(out); + } - if(fanout->type == Gate::Type::BUF || fanout->type == Gate::Type::NOT) { - continue; - } else if(fanout->type == Gate::Type::XOR || fanout->type == Gate::Type::XNOR) { - faults.push(TMP_FAULT{g, name, 0, stem, 0}); - faults.push(TMP_FAULT{g, name, 1, stem, 0}); - } else if(fanout->type == Gate::Type::NAND || fanout->type == Gate::Type::AND) { - faults.push(TMP_FAULT{g, name, 1, stem, 0}); - } else if(fanout->type == Gate::Type::NOR || fanout->type == Gate::Type::OR) { - faults.push(TMP_FAULT{g, name, 0, stem, 0}); - } else { - assert(false); + out->cal_score(); + out->CC = 1; + if(!out->is_good_var && out->score > 0) { + out->is_good_var = 1; + good_gates.push_back(out); + } + + for(Gate* in : out->fanins) { + if(in == gate) continue; + in->CC = 1; + in->cal_score(); + if(!in->is_good_var && in->score > 0) { + in->is_good_var = 1; + good_gates.push_back(in); } } } - printf("fault-size: %d\n", faults.size()); + gate->cal_score(); +} - std::vector t_faults; - std::set t_verify_set; +void Circuit::ls_update() { - while(!faults.empty()) { - TMP_FAULT f = faults.front(); - faults.pop(); + std::set reigon; - assert(t_verify_set.count(f) == 0); + for(Gate* g : unjust_gates) { + g->unsat_cost += OPT(vsat_inc); - t_faults.push_back(f); - t_verify_set.insert(f); + for(Gate* in : g->fanins) { + reigon.insert(in); + } + for(Gate* out : g->fanouts) { + reigon.insert(out); + for(Gate* in : out->fanins) { + reigon.insert(in); + } + } } - std::map, std::pair> mp; - - for(TMP_FAULT &f : t_faults) { - faults.push(f); - mp[std::make_pair(f.g->name, f.stuck_at)] = std::make_pair(f.is_stem, f.is_PO); + for(Fault f : unknown_faults) { + Gate* g = f.gate->stuck_at_gate[f.stuck_at]; + assert(g != nullptr); + g->weight += OPT(fw_inc) * 100; + for(Gate* in : g->fanins) { + reigon.insert(in); + } + for(Gate* out : g->fanouts) { + reigon.insert(out); + for(Gate* in : out->fanins) { + reigon.insert(in); + } + } } - printf("fault-size: %d\n", t_faults.size()); - printf("verify-size: %d\n", t_verify_set.size()); - assert(t_faults.size() == t_verify_set.size()); + for(Gate* g : reigon) { + g->cal_score(); + if(!g->is_good_var && g->score > 0 && g->CC) { + g->is_good_var = 1; + good_gates.push_back(g); + } + } +} - std::vector patterns; +void Circuit::ls_gen_sol(const Fault &f) { + + std::vector best_sol; + int best_score = -1; + simulator->simulate(PIs, best_score, unknown_faults); + for(Gate* gate : PIs) { + best_sol.push_back(gate->value); + } + + for(Gate* gate : gates) { + gate->value = gate->cal_value(); + gate->v_sat = 1; + gate->CC = 1; + gate->is_good_var = 0; + } + + for(Gate* gate : gates) { + gate->cal_score(); + if(gate->score > 0) { + gate->is_good_var = 1; + good_gates.push_back(gate); + } + } + + + for(int step=0; stepcal_score(); + int delta = pick->score; + // printf("flip: %s score: %d\n", pick->name.c_str(), delta); + + ls_flip(pick); + + // int score2 = cal_circuit_score(); + + // printf("score: %d %d %d\n", score1, score2, delta); + // assert((score2 - score1) == delta); + + if(pick->isPI) { + + Pattern p; + for(Gate* gate : PIs) { + p.input_vector.push_back(gate->value); + } + + int res = check_fault(p, f); + + if(!res) { + ls_flip(pick); + pick->CC = 0; + } else { + + printf("succsss-flip-pi: %s\n", pick->name.c_str()); + int score; + simulator->simulate(PIs, score, unknown_faults); + if(score > best_score) { + printf("update_best_score: %d\n", best_score); + best_score = score; + best_sol.clear(); + for(Gate* gate : PIs) { + p.input_vector.push_back(gate->value); + } + } + } + } + } + + // printf("====== test end\n"); + // exit(0); + + assert(best_score != -1); + + for(int i=0; ivalue = best_sol[i]; + } +} + +void Circuit::ls_main() { auto start = std::chrono::high_resolution_clock::now(); - while(!faults.empty()) { + printf("====== local search start ======\n"); - while(!faults.empty()) { - TMP_FAULT f = faults.front(); - if(fault_detected[f.g->id-1][f.stuck_at]) { - faults.pop(); - } else { - break; - } - } + std::vector patterns; - if(faults.empty()) break; + while(!unknown_faults.empty()) { + + Fault f = *unknown_faults.begin(); unknown_faults.erase(unknown_faults.begin()); + + ls_init(); ls_random_sol(); - TMP_FAULT f = faults.front(); faults.pop(); - Gate* g = f.g; + Gate* g = f.gate; int stuck_at = f.stuck_at; printf("start with fault: %s SA%d\t", g->name.c_str(), stuck_at); - std::vector inputs; - printf("verify ..."); - int res1 = sat_atpg(f, inputs); + std::vector inputs; + + int res1 = sat_atpg(mp[f], inputs); if(res1 == 0) { printf(" unsat!\n"); + undetected_faults.insert(f); continue; } @@ -296,295 +342,65 @@ void LUTCircuit::ls_main() { PIs[i]->value = inputs[i]; } - printf("sim: %s %d\n", g->name.c_str(), stuck_at); - for(int i=0; iinput_var = 0; - for(int i=0; ifanins.size(); i++) { - LUT* in = lut->fanins[i]; - lut->input_var |= (in->value << i); - } - } - ls_gen_sol(f); int score; - simulator->simulate(PIs, score, fault_detected); + simulator->simulate(PIs, score, unknown_faults); Pattern pattern; - for(LUT* lut : PIs) { - pattern.input_vector.push_back(lut->value); + for(Gate* g : PIs) { + pattern.input_vector.push_back(g->value); } assert(check_fault(pattern, f)); - simulator->name2gate[g->name]->fault_detected[stuck_at] = 1; - assert(fault_detected[g->id-1][stuck_at] == 0); + detected_faults.insert(f); + pattern.detected_faults.push_back(f); - int num_fault = 0; + int num_fault = 1; - // check if real detected - for(Gate* g : simulator->gates) { - for(int i=0; i<=1; i++) { - if(g->fault_detected[i] && !fault_detected[g->id-1][i]) { - fault_detected[g->id-1][i] = 1; + std::vector remove_faults; - if(mp.count(std::make_pair(g->name, i))) { - auto [is_tem, is_PO] = mp[std::make_pair(g->name, i)]; + for(Fault f : unknown_faults) { - TMP_FAULT f = TMP_FAULT{g, g->name, i, is_tem, is_PO}; + Gate* gate = f.gate; + int stuck_at = f.stuck_at; - int res = check_fault(pattern, f); - if(!res) { - printf("fault: %s SA%d is not real detected!\n", g->name.c_str(), i); - fault_detected[g->id-1][i] = 0; - } else { - pattern.detected_faults.push_back(f); - } - } + assert(gate->sim_gate != nullptr); - if(fault_detected[g->id-1][i]) { - num_detected_fault++; - num_undetected_fault--; - num_fault++; - } + if(gate->sim_gate->fault_detected[stuck_at]) { + + int res = check_fault(pattern, f); + + if(!res) { + printf("fault: %s SA%d is not real detected!\n", gate->name.c_str(), stuck_at); + } else { + pattern.detected_faults.push_back(f); + num_fault++; + detected_faults.insert(f); + remove_faults.push_back(f); } } } - patterns.push_back(pattern); - assert(num_fault > 0); - - if(num_fault > 0) { - num_pattern++; + for(Fault f : remove_faults) { + unknown_faults.erase(f); } + patterns.push_back(pattern); + auto end = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast(end - start).count(); - // cnt++; - printf("Cover: %.2f%% pattern: %d new_detected: %d undected: %d time: %.2fs\n", (double)num_detected_fault / num_total_fault * 100, num_pattern, num_fault, num_undetected_fault, (double)duration/1000); + printf("Cover: %.2f%% pattern: %d new_detected: %d undected: %d time: %.2fs\n", (double)detected_faults.size() / faults.size() * 100, patterns.size(), num_fault, unknown_faults.size(), (double)duration/1000); - // break; - } - - for(int i=0; igates[i]->name.c_str()); - } - if(fault_detected[i][1] == 0) { - printf("undetected: %s SA1\n", simulator->gates[i]->name.c_str()); - } } printf("====== local search end ======\n"); - final_check(t_verify_set, patterns); + final_check(faults, patterns); auto end = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast(end - start).count(); std::cout << "Execution time: " << duration << " milliseconds" << std::endl; -} - -void LUTCircuit::ls_gen_sol(const TMP_FAULT &target) { - - std::vector best_sol; - int best_score = -1; - simulator->simulate(PIs, best_score, fault_detected); - for(LUT* lut : PIs) { - best_sol.push_back(lut->value); - } - - for(int step=0; stepcal_score(); - - // double t1 = check(); - - // printf(">>>>>>>>>>>>>\n"); - // printf("dert_score: %.2f\n", pick->score); - // printf("dert_unsat_cost: %.2f\n", pick->score_value_unsatisfied_cost); - // printf("dert_fault_detected_weight: %.2f\n", pick->score_fault_detected_weight); - // printf("dert_fault_propagated_weight: %.2f\n", pick->score_fault_propagated_weight); - // printf("dert_up_cost: %.2f\n", pick->score_fault_update_cost); - - ls_flip(pick); - - // double t2 = check(); - // assert(((t2 - t1) - pick->score) < 1e-6); - - - if(pick->isPI) { - - // printf("step: %d score: %d\n", step, score); - - Pattern p; - for(LUT* lut : PIs) { - p.input_vector.push_back(lut->value); - } - int res = check_fault(p, target); - - if(!res) { - ls_flip(pick); - pick->CC = 0; - } else { - int score; - simulator->simulate(PIs, score, fault_detected); - if(score > best_score) { - best_score = score; - best_sol.clear(); - for(LUT* lut : PIs) { - best_sol.push_back(lut->value); - } - } - } - } - } - - assert(best_score != -1); - - for(int i=0; ivalue = best_sol[i]; - } - - for(LUT* lut : luts) { - lut->input_var = 0; - for(int i=0; ifanins.size(); i++) { - LUT* in = lut->fanins[i]; - lut->input_var |= (in->value << i); - } - lut->value = lut->cal_value(); - lut->vsat = 1; - } - - for(LUT* lut : rtopo_luts) { - lut->cal_fault_info(lut->fd, lut->fpl); - } -} - - -void LUTCircuit::ls_init() { - for(LUT* lut : luts) { - static int cnt = 0; - printf("[%d/%d]\n", ++cnt, luts.size()); - lut->init_lookup_table(); - } - - for(LUT* lut : luts) { - for(LUT* out :lut->fanouts) { - for(int i=0; ifanins.size(); i++) { - if(out->fanins[i] == lut) { - lut->fault_info.push_back(out->fault_table[i]); - } - } - } - } - - for(LUT* lut : luts) { - std::set t_reigon; - for(LUT* out : lut->fanouts) { - for(LUT* in : out->fanins) { - t_reigon.insert(in); - } - } - for(LUT* in : lut->fanins) { - t_reigon.insert(in); - } - t_reigon.erase(lut); - for(LUT* r : t_reigon) { - lut->reigon.push_back(r); - } - } - - for(LUT* lut : luts) { - std::set t_reigon; - for(LUT* r: lut->reigon) { - t_reigon.insert(r); - for(LUT* out2 : r->fanouts) { - t_reigon.insert(out2); - for(LUT* in2 : out2->fanins) { - t_reigon.insert(in2); - } - } - } - for(LUT* r : lut->fanouts) { - t_reigon.insert(r); - } - for(LUT* r : t_reigon) { - lut->update_reigon.push_back(r); - } - } -} - -void LUTCircuit::ls_random_sol() { - - step = 0; - - std::vector t_focus; - - for(LUT* lut : luts) { - lut->up_cost = 1; - - lut->vunat_cost = 1; - if(lut->isPI) { - lut->vunat_cost = OPT(vsat_inc) * 100; - } - - lut->CC = 1; - for(Gate* g : lut->inner_gates) { - - g->fault_detected_weight[0] = !fault_detected[g->id-1][0]; - g->fault_detected_weight[1] = !fault_detected[g->id-1][1]; - - if(g->fault_detected_weight[0]) { - t_focus.push_back(&g->fault_detected_weight[0]); - } - - if(g->fault_detected_weight[1]) { - t_focus.push_back(&g->fault_detected_weight[1]); - } - - g->fault_propagated_weight[0] = !fault_detected[g->id-1][0]; - g->fault_propagated_weight[1] = !fault_detected[g->id-1][1]; - } - } - - int *tw = t_focus[rand()%t_focus.size()]; - *tw = 100000; - - for(LUT* lut : luts) { - lut->uptag = 0; - lut->value = rand() % 2; - } - - for(LUT* lut : luts) { - lut->input_var = 0; - for(int i=0; ifanins.size(); i++) { - LUT* in = lut->fanins[i]; - lut->input_var |= (in->value << i); - } - } - - for(LUT* lut : luts) { - lut->vsat = (lut->value == lut->cal_value()); - } - - for(LUT* lut : rtopo_luts) { - lut->cal_fault_info(lut->fd, lut->fpl); - } - - for(LUT* lut : luts) { - lut->cal_score(); - } } \ No newline at end of file diff --git a/src/lut.cpp b/src/lut.cpp deleted file mode 100644 index f1d4283..0000000 --- a/src/lut.cpp +++ /dev/null @@ -1,205 +0,0 @@ -#include - -#include "lut.h" -#include "paras.h" - -using namespace atpg_ls; - -void LUT::flip_value() { - value ^= 1; - for(auto&[out, id] : fanouts_with_id) { - out->input_var ^= (1 << id); - } -} - -void LUT::cal_fault_info(int *fd, int* fpl) { - - fd[0] = fd[1] = fpl[0] = fpl[1] = 0; - if(isPO) { - fd[!value] = 1; - fd[value] = 0; - return; - } - - for(auto&[out, id] : fanouts_with_id) { - if(!out->vsat) continue; - - FaultInfo &info = out->fault_table[id][out->input_var << 1 | out->value]; - - int t_fd[2], t_fpl[2]; - - t_fd[0] = info.fd[0] && out->fd[!out->value]; - t_fd[1] = info.fd[1] && out->fd[!out->value]; - - t_fpl[0] = info.fpl[0] + info.fd[0] * out->fpl[!out->value]; - t_fpl[1] = info.fpl[1] + info.fd[1] * out->fpl[!out->value]; - - fd[0] |= t_fd[0]; - fd[1] |= t_fd[1]; - - fpl[0] = std::max(fpl[0], t_fpl[0]); - fpl[1] = std::max(fpl[1], t_fpl[1]); - } - - // std::vector reigon; - - // std::priority_queue, std::vector>, - // std::function&, const std::pair&)>> pq([](const std::pair& p1, const std::pair& p2) { - // return p1.first->id < p2.first->id; - // }); - - // for(Gate* out : gate->fanouts) { - // if(!out->vsat) continue; - // pq.push(std::make_pair(out, 0)); - // } - - // pq.push(std::make_pair(gate, 0)); - - // while(!q.empty()) { - // auto [now, level] = q.front(); q.pop(); - - // for(Gate* out : now->fanouts) { - // if(!out->is_detected(now)) continue; - - // if(level + 1 < OPT(lut)) { - // q.push(std::make_pair(out, level + 1)); - // } - // } - - - // } - -} - -int LUT::cal_value() { - if(isPI) return value; - return value_table[input_var]; -} - -LUT::LUT(Gate *gate, LUTCircuit *circuit):gate(gate), value(gate->value), name(gate->name.c_str()) { - - C = circuit; - - isPI = gate->isPI; - isPO = gate->isPO; - - inner_gates.push_back(gate); - - std::set fanins; - - for(Gate* g : gate->fanins) { - fanins.insert(g); - } - - while(true) { - - std::vector candidates; - for(Gate* fanin : fanins) { - if(fanin->fanouts.size() >= 2) continue; - if(fanin->isPI) continue; - - int add = 0; - for(Gate* in : fanin->fanins) { - if(fanins.count(in) == 0) { - add++; - } - } - - if(fanins.size() - 1 + add <= OPT(lut)) { - candidates.push_back(fanin); - } - } - - if(candidates.size() == 0) break; - - Gate* random_gate = candidates[rand()%candidates.size()]; - - inner_gates.push_back(random_gate); - fanins.erase(random_gate); - - for(Gate* in : random_gate->fanins) { - fanins.insert(in); - } - } - - for(Gate* in : fanins) { - __gate_fanins.push_back(in); - } -} - - -void LUT::init_lookup_table() { - value_table = new int[1 << fanins.size()]; - fault_table = new FaultInfo *[fanins.size() + inner_gates.size()]; - for (int i = 0; i < (fanins.size() + inner_gates.size()); i++) { - fault_table[i] = new FaultInfo[1 << (fanins.size() + 1)]; - } - - std::unordered_map gate2index; - - for(int i=0; igate] = i; - } - for(int i=0; igate->value = (i >> j) & 1; - } - for (Gate *g : inner_gates) { - g->value = g->cal_value(); - } - - assert(inner_gates[inner_gates.size() - 1] == gate); - - value_table[i] = gate->value; - - for(gate->value=0; gate->value<=1; gate->value++) { - - for(auto&[g, index] : gate2index) { - g->fault_detected[0] = g->fault_detected[1] = 0; - g->fault_propagated_len[0] = g->fault_propagated_len[1] = 0; - } - - gate->fault_detected[!gate->value] = 1; - gate->fault_detected[gate->value] = 0; - gate->fault_propagated_len[0] = 0; - gate->fault_propagated_len[1] = 0; - - std::queue q; - q.push(gate); - - while(!q.empty()) { - Gate *now = q.front(); q.pop(); - - FaultInfo *info = &fault_table[gate2index[now]][(i<<1)|gate->value]; - info->fd[0] = now->fault_detected[0]; - info->fd[1] = now->fault_detected[1]; - info->fpl[0] = now->fault_propagated_len[0]; - info->fpl[1] = now->fault_propagated_len[1]; - info->value = now->value; - - // if(now->name == "new_n22_") { - // printf("Gate: %s value: %d inputs: [ ", now->name.c_str(), now->value); - // for(Gate *in : now->fanins) { - // printf("%s ", in->name.c_str()); - // } - // printf("]\n"); - // } - - for(Gate *in : now->fanins) { - if(gate2index.count(in) == 0) continue; - - if(now->is_detected(in)) { - in->fault_detected[!in->value] = std::max(in->fault_detected[!in->value], now->fault_detected[!now->value]); - in->fault_propagated_len[!in->value] = std::max(in->fault_propagated_len[!in->value], now->fault_propagated_len[!now->value] + 1); - } - - q.push(in); - } - } - } - } -} diff --git a/src/lut.h b/src/lut.h deleted file mode 100644 index 47c4800..0000000 --- a/src/lut.h +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once - -#include "gate.h" - -namespace atpg_ls { - -class LUTCircuit; - -class LUT { -public: - LUT(Gate *gate, LUTCircuit *circuit); - - LUTCircuit *C; - - Gate *gate; - - bool isPI, isPO; - - uint32_t input_var; - - std::vector fanins; - - std::vector fanouts; - std::vector> fanouts_with_id; - - std::vector reigon; - std::vector update_reigon; - - std::vector inner_gates; - - std::vector __gate_fanins; - - std::unordered_map input_id; - - int &value; - void flip_value(); - - const char *name; - - int *value_table; - - struct FaultInfo { - int fd[2]; - int fpl[2]; - int value; - } **fault_table; - - std::vector fault_info; - - void init_lookup_table(); - - // local search - - bool vsat; - int vunat_cost; - bool uptag; - int up_cost; - int fd[2]; - int fpl[2]; - // int is_good_var; - int CC; - - int cal_value(); - void cal_fault_info(int *t_fd, int *t_fpl); - void get_fault_info(Gate *gate, int *t_fd, int *t_fpl); - - // score - double score; - double score_value_unsatisfied_cost; - double score_fault_detected_weight; - double score_fault_propagated_weight; - double score_fault_update_cost; - - void cal_score(); - void cal_update(); -}; - -} diff --git a/src/main.cpp b/src/main.cpp old mode 100644 new mode 100755 index 4e227e4..3275fd6 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,19 +18,18 @@ int main(int argc, char *argv[]) { Simulator* simulator = new Simulator(); printf("parsing file %s ...\n", OPT(instance).c_str()); - circuit->parse_from_file(OPT(instance).c_str()); - circuit->insert_lines_for_stem(); simulator->parse_from_file(OPT(instance).c_str()); simulator->insert_lines_for_stem(); - - circuit->init_topo_index(); simulator->init_topo_index(); - - circuit->init_avg_dist(); + circuit->parse_from_file(OPT(instance).c_str()); + circuit->insert_lines_for_stem(); + circuit->init_topo_index(); - circuit->print(); + circuit->simulator = simulator; + circuit->init_faults(); + circuit->rebuild_atpg_circuit(); init_final_checker(); @@ -54,17 +53,16 @@ int main(int argc, char *argv[]) { // circuit-> printf("building lut circuit ...\n"); - LUTCircuit *C = circuit->build_lut_circuit(); - C->simulator = simulator; + printf("====== Circuit Statistics ====== \n"); - printf("PI:\t%ld\n", circuit->PIs.size()); - printf("PO:\t%ld\n", circuit->POs.size()); - printf("Gate:\t%ld\n", circuit->gates.size()); - printf("LUT:\t%ld\n", C->luts.size()); + printf("PIs:\t%ld\n", circuit->PIs.size()); + printf("POs:\t%ld\n", circuit->POs.size()); + printf("ori-Gate:\t%ld\n", circuit->original_gates.size()); + printf("new-Gate:\t%ld\n", circuit->gates.size()); printf("================================ \n"); - C->ls_main(); + circuit->ls_main(); return 0; } diff --git a/src/paras.cpp b/src/paras.cpp old mode 100644 new mode 100755 diff --git a/src/paras.h b/src/paras.h old mode 100644 new mode 100755 diff --git a/src/parse.cpp b/src/parse.cpp old mode 100644 new mode 100755 diff --git a/src/pattern.h b/src/pattern.h old mode 100644 new mode 100755 index 6101901..344602f --- a/src/pattern.h +++ b/src/pattern.h @@ -10,7 +10,7 @@ class Pattern { public: std::vector input_vector; - std::vector detected_faults; + std::vector detected_faults; }; diff --git a/src/sat_atpg.cpp b/src/sat_atpg.cpp old mode 100644 new mode 100755 index ba07630..1b091ba --- a/src/sat_atpg.cpp +++ b/src/sat_atpg.cpp @@ -27,6 +27,7 @@ std::map fault_map; bool sat_atpg(const TMP_FAULT &fal, std::vector &input_vector) { + // printf(">?> Fault: %s stuck-at: %d is_stem: %d is_po: %d\n", fal.name.c_str(), fal.stuck_at, fal.is_stem, fal.is_PO); assert(fault_map.count(fal) != 0); Fault f = fault_map[fal]; @@ -90,7 +91,7 @@ void sat_atpg_init(const char* file) { if(f.is_stem || (f.line->source == nullptr && f.line->destinations.size() == 1)) { - printf("Fault: %s stuck-at: %d is_stem: %d is_po: %d dest: %d\n", f.line->name.c_str(), f.stuck_at, f.is_stem, f.is_primary_output, f.line->destinations.size()); + // printf("Fault: %s stuck-at: %d is_stem: %d is_po: %d dest: %d\n", f.line->name.c_str(), f.stuck_at, f.is_stem, f.is_primary_output, f.line->destinations.size()); TMP_FAULT tf = TMP_FAULT{nullptr, f.line->name, f.stuck_at, f.is_stem, f.is_primary_output}; assert(fault_map.count(tf) == 0); fault_map[tf] = f; @@ -105,7 +106,7 @@ void sat_atpg_init(const char* file) { name = f.line->name + "_line_" + f.connection.gate->get_output()->name; } - printf("Fault: %s stuck-at: %d is_stem: %d is_po: %d dest: %d\n", name.c_str(), f.stuck_at, f.is_stem, f.is_primary_output, f.line->destinations.size()); + // printf("Fault: %s stuck-at: %d is_stem: %d is_po: %d dest: %d\n", name.c_str(), f.stuck_at, f.is_stem, f.is_primary_output, f.line->destinations.size()); TMP_FAULT tf = TMP_FAULT{nullptr, name, f.stuck_at, f.is_stem, f.is_primary_output}; assert(fault_map.count(tf) == 0); diff --git a/src/sat_atpg.h b/src/sat_atpg.h old mode 100644 new mode 100755 diff --git a/src/score.cpp b/src/score.cpp old mode 100644 new mode 100755 index 1b223ab..8f2d56f --- a/src/score.cpp +++ b/src/score.cpp @@ -1,141 +1,34 @@ -#include "lut.h" #include "circuit.h" using namespace atpg_ls; -void LUT::cal_score() { - +void Gate::cal_score() { score = 0; - score_value_unsatisfied_cost = 0; - score_fault_detected_weight = 0; - score_fault_propagated_weight = 0; - score_fault_update_cost = 0; - // value = !value; - this->flip_value(); - - if(uptag) { - score_fault_update_cost -= up_cost; + if(value == 1) { + score -= weight; + } else { + score += weight; } - - // value sat score - + if(!isPI) { - if(vsat) score_value_unsatisfied_cost += vunat_cost; - else score_value_unsatisfied_cost -= vunat_cost; - vsat = !vsat; - } - - for(LUT* out : fanouts) { - if(!out->vsat && out->cal_value() == out->value) { - score_value_unsatisfied_cost -= out->vunat_cost; - out->vsat = 1; - } - if(out->vsat && out->cal_value() != out->value){ - score_value_unsatisfied_cost += out->vunat_cost; - out->vsat = 0; + if(v_sat) { + score -= unsat_cost; + } else { + score += unsat_cost; } } - int old_fd[2], old_fpl[2]; - old_fd[0] = fd[0]; - old_fd[1] = fd[1]; - old_fpl[0] = fpl[0]; - old_fpl[1] = fpl[1]; + value ^= 1; - // fault detected score - - cal_fault_info(fd, fpl); - - // printf("fd: %d %d %d %d\n", fd[0], fd[1], old_fd[0], old_fd[1]); - - for(auto&[out, id] : fanouts_with_id) { - uint32_t in1 = out->input_var, in2 = out->input_var; - in1 ^= (1 << id); - - in1 = (in1 << 1) | out->value; - in2 = (in2 << 1) | out->value; - - for(int i=out->fanins.size(); ifanins.size()+out->inner_gates.size(); i++) { - Gate* g = out->inner_gates[i-out->fanins.size()]; - - int t_fd1[2], t_fpl1[2]; - int t_fd2[2], t_fpl2[2]; - - t_fd1[0] = out->fault_table[i][in1].fd[0] && out->fd[!out->value]; - t_fd1[1] = out->fault_table[i][in1].fd[1] && out->fd[!out->value]; - - t_fd2[0] = out->fault_table[i][in2].fd[0] && out->fd[!out->value]; - t_fd2[1] = out->fault_table[i][in2].fd[1] && out->fd[!out->value]; - - t_fpl1[0] = out->fault_table[i][in1].fpl[0] + out->fault_table[i][in1].fd[0] * out->fpl[!out->value]; - t_fpl1[1] = out->fault_table[i][in1].fpl[1] + out->fault_table[i][in1].fd[1] * out->fpl[!out->value]; - - t_fpl2[0] = out->fault_table[i][in2].fpl[0] + out->fault_table[i][in2].fd[0] * out->fpl[!out->value]; - t_fpl2[1] = out->fault_table[i][in2].fpl[1] + out->fault_table[i][in2].fd[1] * out->fpl[!out->value]; - - score_fault_detected_weight += (t_fd2[0] - t_fd1[0]) * g->fault_detected_weight[0]; - score_fault_detected_weight += (t_fd2[1] - t_fd1[1]) * g->fault_detected_weight[1]; - - if(!g->isPO) { - score_fault_propagated_weight += (double)(t_fpl2[0] - t_fpl1[0]) / g->avg_dist * g->fault_detected_weight[0]; - score_fault_propagated_weight += (double)(t_fpl2[1] - t_fpl1[1]) / g->avg_dist * g->fault_detected_weight[1]; - } + for(Gate* out : fanouts) { + if(out->v_sat && (out->value != out->cal_value())) { + score -= out->unsat_cost; + } + if(!out->v_sat && (out->value == out->cal_value())) { + score += out->unsat_cost; } } - int in1 = this->input_var, in2 = this->input_var; - in1 = (in1 << 1) | !value; - in2 = (in2 << 1) | value; - - for(int i=fanins.size(); ifault_detected_weight[0]; - score_fault_detected_weight += (t_fd2[1] - t_fd1[1]) * g->fault_detected_weight[1]; - - if(!g->isPO) { - score_fault_propagated_weight += (double)(t_fpl2[0] - t_fpl1[0]) / g->avg_dist * g->fault_detected_weight[0]; - score_fault_propagated_weight += (double)(t_fpl2[1] - t_fpl1[1]) / g->avg_dist * g->fault_detected_weight[1]; - } - } - - // update cost score - for(LUT* r : reigon) { - int t_fd[2], t_fpl[2]; - r->cal_fault_info(t_fd, t_fpl); - if(t_fd[0] == r->fd[0] && t_fd[1] == r->fd[1] && t_fpl[0] == r->fpl[0] && t_fpl[1] == r->fpl[1]) continue; - if(!r->uptag) { - score_fault_update_cost += r->up_cost; - } - } - - this->flip_value(); - if(!isPI) vsat = !vsat; - - fd[0] = old_fd[0]; - fd[1] = old_fd[1]; - fpl[0] = old_fpl[0]; - fpl[1] = old_fpl[1]; - - for(LUT* out : fanouts) { - out->vsat = ( out->cal_value() == out->value ); - } - - score = - score_value_unsatisfied_cost + score_fault_detected_weight + score_fault_propagated_weight - score_fault_update_cost; + value ^= 1; } \ No newline at end of file diff --git a/src/simulator.cpp b/src/simulator.cpp old mode 100644 new mode 100755 index ad95b01..7945732 --- a/src/simulator.cpp +++ b/src/simulator.cpp @@ -2,86 +2,30 @@ using namespace atpg_ls; -int Simulator::verify(LUTCircuit *lut_circuit, int** fault_detected) { +// int Simulator::verify(Circuit *circuit, int** fault_detected) { - // lut_circuit->check(); +// // lut_circuit->check(); - // for(LUT* lut : lut_circuit->PIs) { - // printf("PI: %s = %d\n", lut->name, lut->value); - // } +// // for(LUT* lut : lut_circuit->PIs) { +// // printf("PI: %s = %d\n", lut->name, lut->value); +// // } - int score; - simulate(lut_circuit->PIs, score, fault_detected); +// int score; +// simulate(circuit->PIs, score, fault_detected); - for(LUT* lut : lut_circuit->luts) { - assert(lut->value == lut->cal_value()); - } +// for(Gate* gate : circuit->gates) { +// assert(gate->value == gate->cal_value()); +// } - for(LUT* lut : lut_circuit->rtopo_luts) { - lut->cal_fault_info(lut->fd, lut->fpl); - } +// std::unordered_map id2gate; +// for(Gate* gate : gates) { +// id2gate[gate->id] = gate; +// } - // lut_circuit->print(); +// return 1; +// } - std::unordered_map id2gate; - for(Gate* gate : gates) { - id2gate[gate->id] = gate; - } - - for(LUT* lut : lut_circuit->luts) { - - int input_var = 0; - for(int i=0; ifanins.size(); i++) { - LUT* l = lut->fanins[i]; - input_var |= l->value << i; - } - - assert(input_var == lut->input_var); - - if(!lut->isPI) assert(lut->value_table[lut->input_var] == lut->value); - - // printf(">> LUT: %s\n", lut->name); - - // assert(lut->fd[0] == id2gate[lut->gate->id]->fault_detected[0]); - // assert(lut->fd[1] == id2gate[lut->gate->id]->fault_detected[1]); - // assert(lut->fpl[0] == id2gate[lut->gate->id]->fault_propagated_len[0]); - // assert(lut->fpl[1] == id2gate[lut->gate->id]->fault_propagated_len[1]); - - for(int i=lut->fanins.size(); ifanins.size()+lut->inner_gates.size(); i++) { - - LUT::FaultInfo &info = lut->fault_table[i][(lut->input_var<<1)|lut->value]; - - Gate* g = lut->inner_gates[i-lut->fanins.size()]; - - int t_fd[2], t_fpl[2]; - t_fd[0] = info.fd[0] && lut->fd[!lut->value]; - t_fd[1] = info.fd[1] && lut->fd[!lut->value]; - t_fpl[0] = info.fpl[0] + info.fd[0] * lut->fpl[!lut->value]; - t_fpl[1] = info.fpl[1] + info.fd[1] * lut->fpl[!lut->value]; - - Gate* sim_g = id2gate[g->id]; - assert(g->name == sim_g->name); - - // if(g->name == "new_n32_" || g->name == "new_n33_") { - // printf("Gate: %s value: %d %d\n", g->name.c_str(), info.value, sim_g->value); - // printf("l_fd[0]: %d, l_fd[1]: %d, l_fpl[0]: %d, l_fpl[1]: %d\n", lut->fd[0], lut->fd[1], lut->fpl[0], lut->fpl[1]); - // printf("i_fd[0]: %d, i_fd[1]: %d, i_fpl[0]: %d, i_fpl[1]: %d\n", info.fd[0], info.fd[1], info.fpl[0], info.fpl[1]); - // printf("t_fd[0]: %d, t_fd[1]: %d, t_fpl[0]: %d, t_fpl[1]: %d\n", t_fd[0], t_fd[1], t_fpl[0], t_fpl[1]); - // printf("s_fd[0]: %d, s_fd[1]: %d, s_fpl[0]: %d, s_fpl[1]: %d\n\n", sim_g->fault_detected[0], sim_g->fault_detected[1], sim_g->fault_propagated_len[0], sim_g->fault_propagated_len[1]); - // } - - assert(info.value == sim_g->value); - assert(t_fd[0] == sim_g->fault_detected[0]); - assert(t_fd[1] == sim_g->fault_detected[1]); - // assert(t_fpl[0] == sim_g->fault_propagated_len[0]); - // assert(t_fpl[1] == sim_g->fault_propagated_len[1]); - } - } - - return 1; -} - -void Simulator::simulate(std::vector &inputs, int &score, int** fault_detected) { +void Simulator::simulate(std::vector &inputs, int &score, std::set &unknown_faults) { assert(inputs.size() == this->PIs.size()); @@ -103,10 +47,10 @@ void Simulator::simulate(std::vector &inputs, int &score, int** fault_dete score = 0; for(auto gate : gates) { - if(gate->fault_detected[0] && !fault_detected[gate->id-1][0]) { + if(gate->fault_detected[0] && unknown_faults.count(Fault{gate->ori_gate, 0})) { score++; } - if(gate->fault_detected[1] && !fault_detected[gate->id-1][1]) { + if(gate->fault_detected[1] && unknown_faults.count(Fault{gate->ori_gate, 1})) { score++; } } diff --git a/src/simulator.h b/src/simulator.h old mode 100644 new mode 100755 index b03acea..de0b5b8 --- a/src/simulator.h +++ b/src/simulator.h @@ -6,8 +6,8 @@ namespace atpg_ls { class Simulator : public Circuit { public: - void simulate(std::vector &inputs, int &score, int** fault_detected); - int verify(LUTCircuit *lut_circuit, int** fault_detected); + void simulate(std::vector &inputs, int &score, std::set &unknown_faults); + // int verify(Circuit *circuit, int** fault_detected); }; } \ No newline at end of file diff --git a/test.txt b/test.txt new file mode 100755 index 0000000..d5c9d2a --- /dev/null +++ b/test.txt @@ -0,0 +1,1086 @@ +-- Configuring done (0.1s) +-- Generating done (0.0s) +-- Build files have been written to: /pub/netdisk1/qianyh/atpg-ls/build +[ 20%] Built target cadical06w +[ 25%] Built target cadical_sat +[ 30%] Built target sat_solver +[ 51%] Built target atpg_backend +[ 56%] Built target atpgSat +[ 71%] Built target tests +[ 74%] Building CXX object src/CMakeFiles/atpg.dir/ls.cpp.o +[ 76%] Linking CXX executable atpg +[100%] Built target atpg +======================== +parsing file benchmark/b01.bench ... +fault-size: 118 +tg-pro fault-size: 118 table-size: 118 +building lut circuit ... +====== Circuit Statistics ====== +PIs: 7 +POs: 212 +ori-Gate: 106 +new-Gate: 645 +================================ +====== local search start ====== +start with fault: G1_line_G9 SA0 verify ...sat ! +flip: E231 score: -2 +flip: SA1_G4_line_G36 score: 2 +flip: SA1_G33_line_G43 score: 1 +flip: SA1_G37 score: 2 +flip: SA1_G34 score: 2 +flip: SA1_G20 score: 1 +flip: SA1_G29_line_G41 score: 1 +flip: SA1_G12 score: 2 +flip: SA1_G45 score: 2 +flip: SA1_G15_line_G27 score: 1 +flip: SA1_G20_line_G43 score: 1 +flip: SA1_G24 score: 2 +flip: SA1_G23_line_G31 score: 1 +flip: SA1_G14_line_G24 score: 1 +flip: SA1_G4_line_G35 score: 2 +flip: SA1_G16 score: 2 +flip: SA1_G9 score: 2 +flip: SA1_G25 score: 2 +flip: SA1_G6_line_G22 score: 1 +flip: SA1_G11_line_G21 score: 1 +flip: SA1_G18_line_G28 score: 1 +flip: E270 score: 1 +flip: SA0_G32 score: 2 +flip: SA0_G46 score: 2 +flip: E262 score: 1 +flip: SA1_G1_line_G19 score: 2 +flip: SA1_G14 score: 2 +flip: SA1_G13_line_G23 score: 1 +flip: SA1_G8 score: 1 +flip: SA1_G4_line_G32 score: 2 +flip: SA1_G6_line_G23 score: 1 +flip: SA1_G41 score: 2 +flip: E423 score: 1 +flip: E424 score: 1 +flip: SA1_G5_line_G28 score: 1 +flip: E221 score: 1 +flip: SA1_G29 score: 2 +flip: SA1_G14_line_G36 score: 2 +flip: SA1_G9_line_G35 score: 2 +flip: SA1_G13_line_G44 score: 1 +flip: SA0_G20 score: 2 +flip: SA1_G20_line_G30 score: 1 +flip: E414 score: 1 +flip: E193 score: 1 +flip: SA1_G42 score: 2 +flip: SA0_G49 score: 2 +flip: SA1_G10 score: 2 +flip: SA1_G2_line_G17 score: 1 +flip: SA1_G25_line_G35 score: 2 +flip: E408 score: 1 +flip: SA1_G15 score: 2 +flip: SA1_G4_line_G21 score: 1 +flip: SA1_G25_line_G34 score: 1 +flip: SA1_G1_line_G11 score: 1 +flip: E393 score: 1 +flip: SA1_G48 score: 2 +flip: SA1_G11_line_G34 score: 1 +flip: SA1_G5_line_G23 score: 1 +flip: SA1_G47 score: 2 +flip: E343 score: 1 +flip: SA0_G2_line_G9 score: 1 +flip: SA1_G11_line_G31 score: 1 +flip: SA1_G14_line_G39 score: 1 +flip: SA0_G23_line_PO score: 2 +flip: SA1_G13_line_G39 score: 1 +flip: SA1_G25_line_G32 score: 2 +flip: SA1_G11_line_G22 score: 1 +flip: SA0_G23 score: 2 +flip: SA1_G13 score: 1 +flip: SA1_G4_line_G37 score: 1 +flip: SA1_G33_line_G42 score: 1 +flip: E223 score: 1 +flip: E353 score: 1 +flip: SA0_G13 score: 2 +flip: SA1_G15_line_G25 score: 1 +flip: SA1_G33 score: 1 +flip: SA0_G18 score: 2 +flip: SA0_G33 score: 2 +flip: E406 score: 1 +flip: E398 score: 1 +flip: SA1_G15_line_G30 score: 1 +flip: SA1_G11_line_G24 score: 1 +flip: SA1_G9_line_G26 score: 2 +flip: SA1_G15_line_G26 score: 2 +flip: E349 score: 1 +flip: E412 score: 1 +flip: E401 score: 1 +flip: SA1_G40 score: 1 +flip: SA1_G2_line_G11 score: 1 +flip: E415 score: 1 +flip: SA1_G27 score: 2 +flip: E400 score: 1 +flip: G33 score: -4 +flip: SA1_G17 score: 2 +flip: E315 score: 1 +flip: E314 score: 2 +flip: E174 score: 1 +flip: E313 score: 2 +flip: E178 score: 1 +flip: E347 score: 1 +flip: E187 score: 1 +flip: E249 score: 1 +flip: E325 score: 1 +flip: E14 score: 1 +flip: E336 score: 1 +flip: E257 score: 1 +flip: E311 score: 2 +flip: E330 score: 1 +flip: E168 score: 1 +flip: E102 score: 1 +flip: E164 score: 1 +flip: E191 score: 1 +flip: E281 score: 1 +flip: E46 score: 1 +flip: SA1_G22 score: 2 +flip: E227 score: 1 +flip: E329 score: 1 +flip: SA1_G31 score: 2 +flip: SA1_G11 score: 2 +flip: E258 score: 3 +flip: E103 score: 1 +flip: E18 score: 1 +flip: E94 score: 1 +flip: E138 score: 1 +flip: E130 score: 1 +flip: E256 score: 2 +flip: E324 score: 1 +flip: E253 score: 1 +flip: E241 score: 1 +flip: E140 score: 1 +flip: E418 score: 1 +flip: E279 score: 2 +flip: E306 score: 1 +flip: SA1_G30 score: 2 +flip: E120 score: 1 +flip: E340 score: 1 +flip: E80 score: 1 +flip: E226 score: 1 +flip: E362 score: 1 +flip: E206 score: 1 +flip: E197 score: 1 +flip: E280 score: 2 +flip: E134 score: 1 +flip: E88 score: 1 +flip: E238 score: 1 +flip: SA1_G28 score: 2 +flip: E282 score: 3 +flip: E108 score: 1 +flip: E326 score: 1 +flip: E245 score: 1 +flip: E98 score: 1 +flip: SA1_G44 score: 2 +flip: E232 score: 1 +flip: E307 score: 1 +flip: E10 score: 1 +flip: E143 score: 1 +flip: SA1_G43 score: 2 +flip: E87 score: 1 +flip: E312 score: 2 +flip: E167 score: 1 +flip: E50 score: 1 +flip: E361 score: 2 +flip: E357 score: 1 +flip: SA1_G21 score: 2 +flip: E144 score: 1 +flip: SA0_G11 score: 4 +flip: E302 score: 1 +flip: E107 score: 2 +flip: E188 score: 2 +flip: E84 score: 1 +flip: E83 score: 1 +flip: E209 score: 1 +flip: E285 score: 1 +flip: E316 score: 2 +flip: E163 score: 1 +flip: E189 score: 3 +flip: E202 score: 1 +flip: E273 score: 1 +flip: E139 score: 1 +flip: E201 score: 2 +flip: E205 score: 2 +flip: E234 score: 1 +flip: SA0_G25_line_G34 score: 1 +flip: E377 score: 1 +flip: E191 score: 1 +flip: G33 score: 2 +flip: G1_line_G19 score: -2 +flip: G25_line_G34 score: 1 +flip: G47 score: 1 +flip: E318 score: 1 +flip: E119 score: 1 +flip: SA0_G4_line_G13 score: 1 +flip: G34 score: 1 +flip: SA0_G25_line_G33 score: 1 +flip: SA0_G25_line_G34 score: 1 +flip: G46 score: 1 +flip: E348 score: 1 +flip: G12 score: 1 +flip: SA0_G1_line_G19 score: 1 +flip: SA0_G34 score: 1 +flip: E240 score: 1 +flip: E179 score: 1 +flip: SA0_G11_line_G20 score: 1 +flip: SA0_G1_line_G8 score: 1 +flip: E310 score: 1 +flip: G48 score: 1 +flip: E76 score: 1 +flip: E342 score: 1 +flip: G23_line_PO score: 1 +flip: E391 score: 1 +flip: SA1_G39 score: 4 +flip: G23 score: 1 +flip: E123 score: 1 +flip: G49 score: 1 +flip: E111 score: 1 +flip: E183 score: 1 +flip: G16 score: 1 +flip: E115 score: 1 +flip: E358 score: -2 +flip: E88 score: 1 +flip: E180 score: 1 +flip: G42 score: 1 +flip: G1_line_G19 score: 3 +flip: E360 score: 3 +flip: G45 score: 2 +flip: E164 score: 1 +flip: G5_line_G28 score: 1 +flip: SA0_G45 score: 1 +flip: SA0_G42 score: 1 +flip: E84 score: 1 +flip: E196 score: 1 +flip: SA0_G4_line_G21 score: 1 +flip: E184 score: 1 +flip: E186 score: 3 +flip: E330 score: 1 +flip: SA0_G1_line_G19 score: 1 +flip: SA0_G1_line_G11 score: 1 +flip: SA0_G11_line_G21 score: 1 +flip: E166 score: 1 +flip: E182 score: 3 +flip: G2_line_G17 score: 1 +flip: E332 score: 1 +flip: G4_line_G32 score: 0 +flip: G21 score: 1 +flip: G25_line_G32 score: 1 +flip: G3 score: 1 +flip: SA0_G25_line_G32 score: 1 +flip: E140 score: 1 +flip: SA0_G21 score: 1 +flip: G20 score: 1 +flip: SA0_G34 score: 1 +flip: SA0_G4_line_G32 score: 1 +flip: G7 score: 1 +flip: G18 score: 1 +flip: G37 score: 1 +flip: SA0_G7 score: 1 +flip: G32 score: 3 +flip: G41 score: 1 +flip: E340 score: 1 +flip: G33_line_G42 score: 2 +flip: G33 score: 3 +flip: SA0_G33_line_G42 score: 1 +flip: G25 score: 4 +flip: G24 score: 2 +flip: SA0_G37 score: 1 +flip: SA0_G41 score: 1 +flip: SA0_G3 score: 1 +flip: SA0_G24 score: 1 +flip: G32_line_G40 score: 2 +flip: G25_line_G35 score: 1 +flip: G9_line_G35 score: 1 +flip: SA0_G9_line_G35 score: 1 +flip: G9 score: 1 +flip: G9_line_G26 score: 2 +flip: SA0_G25_line_G35 score: 1 +flip: SA0_G9_line_G26 score: 1 +flip: G15_line_G26 score: 1 +flip: SA0_G15_line_G26 score: 1 +flip: G4_line_G35 score: 2 +flip: E142 score: 3 +flip: SA0_G4_line_G35 score: 1 +flip: G21 score: -3 +flip: E12 score: 1 +flip: G9_line_G18 score: 2 +flip: G32_line_G41 score: 1 +flip: G29 score: 1 +flip: E3 score: 1 +flip: SA1_G3 score: 1 +flip: E80 score: 1 +flip: G25_line_G33 score: 1 +flip: E82 score: 2 +flip: E8 score: 1 +flip: SA0_G32_line_G40 score: 1 +flip: G15 score: 2 +flip: G23 score: 2 +flip: G45 score: 2 +flip: E48 score: 1 +flip: SA0_G32_line_G41 score: 1 +flip: G13 score: 1 +flip: E274 score: 1 +flip: SA0_G21 score: 1 +flip: E6 score: 1 +flip: E196 score: 5 +flip: G35 score: 1 +flip: G23_line_PO score: 2 +flip: E265 score: 1 +flip: SA0_G33_line_G42 score: 1 +flip: SA0_G35 score: 1 +flip: SA1_G7 score: 1 +flip: SA0_G25_line_G33 score: 1 +flip: E50 score: 3 +flip: E278 score: 1 +flip: E342 score: 1 +flip: G27 score: 1 +flip: E290 score: 1 +flip: E19 score: 1 +flip: E154 score: 1 +flip: E176 score: 1 +flip: G26 score: 2 +flip: E191 score: 1 +flip: G40 score: 1 +flip: E172 score: 1 +flip: G18_line_G27 score: 1 +flip: E92 score: 1 +flip: E31 score: 1 +flip: G36 score: 3 +flip: SA0_G9_line_G18 score: 1 +flip: SA0_G36 score: 1 +flip: G10 score: 1 +flip: SA0_G18_line_G27 score: 1 +flip: E26 score: 1 +flip: E148 score: 1 +flip: E304 score: 1 +flip: G4_line_G36 score: 3 +flip: E260 score: 1 +flip: E100 score: 1 +flip: E150 score: 6 +flip: G4 score: 2 +flip: G20 score: 1 +flip: E260 score: 5 +flip: E28 score: 1 +flip: E96 score: 1 +flip: G19 score: 1 +flip: SA0_G10 score: 1 +flip: SA0_G26 score: 1 +flip: SA0_G29_line_G41 score: 1 +flip: E243 score: 1 +flip: SA1_G9_line_G18 score: 2 +flip: E162 score: 1 +flip: SA0_G31 score: 1 +flip: SA0_G4_line_G36 score: 1 +flip: E30 score: 5 +flip: G14_line_G36 score: 4 +flip: E300 score: 1 +flip: SA0_G27 score: 1 +flip: E16 score: 1 +flip: G14 score: 3 +flip: E160 score: 6 +flip: G1_line_G11 score: 1 +flip: SA0_G1_line_G11 score: 1 +flip: G2_line_G11 score: 1 +flip: SA0_G19 score: 1 +flip: SA0_G2_line_G11 score: 1 +flip: G2 score: 1 +flip: SA0_G2 score: 14 +flip: G2 score: 3 +flip: SA0_G14_line_G36 score: 1 +flip: G13_line_G23 score: 1 +flip: E38 score: 1 +flip: E40 score: 1 +flip: G13 score: 3 +flip: E63 score: 1 +flip: E338 score: 1 +flip: G6_line_G23 score: 4 +flip: G5_line_G23 score: 7 +flip: G15_line_G25 score: 1 +flip: E42 score: 6 +flip: SA0_G13_line_G23 score: 1 +flip: G49 score: 1 +flip: G5 score: 2 +flip: G46 score: 1 +flip: E156 score: 1 +flip: G5_line_G28 score: 1 +flip: G15_line_G30 score: 1 +flip: G2_line_G17 score: 1 +flip: E166 score: 1 +flip: SA0_G5 score: 16 +flip: E214 score: 1 +flip: E168 score: 1 +flip: E72 score: 1 +flip: SA0_G15_line_G27 score: 1 +flip: SA0_G4_line_G37 score: 1 +flip: E390 score: 1 +flip: E74 score: 7 +flip: E220 score: 1 +flip: SA0_G5_line_G23 score: 1 +flip: E200 score: 1 +flip: E70 score: 1 +flip: G29 score: 2 +flip: E164 score: 3 +flip: E326 score: 1 +flip: G18_line_G28 score: 6 +flip: SA0_G6_line_G23 score: 1 +flip: E291 score: 1 +flip: E198 score: 7 +flip: SA0_G1_line_G19 score: 1 +flip: G42 score: 1 +flip: E8 score: 1 +flip: E216 score: 7 +flip: E170 score: 1 +flip: G15_line_G27 score: 1 +flip: G19 score: 1 +flip: SA0_G15_line_G27 score: 1 +flip: E332 score: 1 +flip: G23 score: 2 +flip: E388 score: 7 +flip: E18 score: 3 +flip: E273 score: 3 +flip: SA1_G25_line_G33 score: 1 +flip: SA0_G44 score: 1 +flip: E330 score: 3 +flip: G23_line_PO score: 2 +flip: G8 score: 1 +flip: E291 score: 1 +flip: E342 score: 1 +flip: E12 score: 1 +flip: G24 score: 2 +flip: E328 score: 1 +flip: SA0_G24 score: 1 +flip: SA0_G19 score: 1 +flip: E212 score: -1 +flip: G2_line_G11 score: 1 +flip: G1_line_G9 score: 1 +flip: E362 score: 1 +flip: G23_line_G31 score: 1 +flip: G12 score: 1 +flip: G46 score: 1 +flip: SA0_G23_line_G31 score: 1 +flip: E132 score: 1 +flip: E128 score: 1 +flip: E218 score: 1 +flip: E210 score: 7 +flip: G16 score: 1 +flip: G33_line_G43 score: 1 +flip: SA0_G2_line_G11 score: 1 +flip: E84 score: 10 +flip: G14_line_G24 score: 1 +flip: E136 score: 1 +flip: E90 score: 1 +flip: E62 score: 1 +flip: SA0_G18_line_G27 score: 1 +flip: G4_line_G35 score: 1 +flip: E384 score: 1 +flip: E94 score: 4 +flip: E60 score: 8 +flip: G6_line_G15 score: 1 +flip: E96 score: 1 +flip: SA0_G11_line_G22 score: 1 +flip: G38 score: 1 +flip: SA0_G6_line_G15 score: 1 +flip: E100 score: 1 +flip: E158 score: 1 +flip: E10 score: 1 +flip: E8 score: 3 +flip: SA0_G24 score: 1 +flip: E387 score: -1 +flip: E358 score: 1 +flip: G4_line_G21 score: 1 +flip: E196 score: 1 +flip: G6 score: 1 +flip: G7 score: 1 +flip: G14_line_G39 score: 1 +flip: G6_line_G24 score: 1 +flip: G2_line_G10 score: 1 +flip: SA0_G7 score: 1 +flip: E202 score: 1 +flip: SA0_G1_line_G9 score: 1 +flip: G11_line_G21 score: 3 +flip: E247 score: 1 +flip: E392 score: 1 +flip: G3 score: 1 +flip: E104 score: 1 +flip: E251 score: 1 +flip: G1 score: 1 +flip: E6 score: 1 +flip: SA0_G11_line_G21 score: 1 +flip: SA0_G11_line_G31 score: 1 +flip: E374 score: 1 +flip: E52 score: 2 +flip: E255 score: 1 +flip: E126 score: 1 +flip: G5_line_G14 score: 1 +flip: SA0_G4_line_G21 score: 1 +flip: SA0_G5_line_G14 score: 1 +flip: G25 score: 1 +flip: SA0_G3 score: 1 +flip: SA0_G2_line_G10 score: 1 +flip: G4 score: 2 +flip: G47 score: 1 +flip: SA0_G6 score: 22 +flip: E54 score: 1 +flip: E347 score: 2 +flip: SA1_G7 score: 1 +flip: E3 score: 1 +flip: E106 score: 9 +flip: E421 score: 1 +flip: E124 score: 9 +flip: G11 score: 2 +flip: G31 score: 8 +flip: G11_line_G22 score: 1 +flip: E370 score: 1 +flip: E19 score: 4 +flip: G6_line_G22 score: 1 +flip: SA0_G11_line_G22 score: 1 +flip: SA1_G6_line_G15 score: 1 +flip: SA0_G6_line_G22 score: 1 +flip: SA1_G3 score: 1 +flip: SA0_G31 score: 1 +flip: E31 score: 4 +flip: G4_line_G35 score: -9 +flip: E371 score: 1 +flip: E366 score: 1 +flip: E96 score: 1 +flip: E120 score: 1 +flip: G4 score: 15 +flip: E382 score: 1 +flip: E362 score: 1 +flip: E94 score: 4 +flip: G11 score: 2 +flip: E100 score: 1 +flip: G4_line_G35 score: 1 +flip: G1_line_G11 score: 4 +flip: G48 score: 1 +flip: E110 score: 1 +flip: SA1_G2_line_G10 score: 1 +flip: G4 score: 5 +flip: E360 score: 4 +flip: E24 score: 1 +flip: E94 score: 4 +flip: G44 score: 6 +flip: G5 score: 3 +flip: E268 score: 1 +flip: SA1_G5_line_G14 score: 1 +flip: SA0_G44 score: 1 +flip: E318 score: 6 +flip: E428 score: 1 +flip: SA0_G35 score: 1 +flip: E152 score: -2 +flip: E365 score: 1 +flip: G20_line_G30 score: 1 +flip: G8 score: 1 +flip: G4_line_G32 score: 1 +flip: E204 score: 1 +flip: E208 score: 1 +flip: E303 score: 2 +flip: G5_line_G25 score: 1 +flip: G11_line_G22 score: 1 +flip: E300 score: 3 +flip: E304 score: 4 +flip: E384 score: 1 +flip: SA0_G32_line_G41 score: 1 +flip: E328 score: 1 +flip: E411 score: 1 +flip: SA0_G4_line_G32 score: 1 +flip: G29_line_G41 score: 1 +flip: SA0_G29_line_G41 score: 1 +flip: G41 score: 1 +flip: E303 score: 4 +flip: SA0_G41 score: 1 +flip: E387 score: 8 +flip: E48 score: 1 +flip: SA0_G5_line_G25 score: 1 +flip: SA0_G11_line_G22 score: 1 +flip: E326 score: 3 +flip: G20 score: 4 +flip: SA0_G45 score: 1 +flip: E46 score: 2 +flip: E50 score: 5 +flip: E260 score: 1 +flip: E36 score: 1 +flip: SA0_G36 score: 1 +flip: E122 score: -1 +flip: G4_line_G21 score: 1 +flip: E182 score: 3 +flip: G4_line_G36 score: 1 +flip: E100 score: 1 +flip: E180 score: 6 +flip: E96 score: 1 +flip: G22 score: 1 +flip: E128 score: 3 +flip: G38 score: 1 +flip: G25 score: 3 +flip: G15_line_G25 score: 4 +flip: E134 score: 6 +flip: G2 score: 1 +flip: E158 score: 1 +flip: E347 score: 9 +flip: G5_line_G28 score: 1 +flip: E167 score: 2 +flip: SA0_G15_line_G25 score: 1 +flip: SA0_G5_line_G28 score: 1 +flip: E136 score: 3 +flip: E118 score: 1 +flip: G27 score: 2 +flip: E156 score: 4 +flip: E116 score: 11 +flip: SA0_G27 score: 1 +flip: E282 score: -3 +flip: E130 score: 1 +flip: E128 score: 3 +flip: SA0_G27 score: 1 +flip: G4_line_G37 score: 1 +flip: G19 score: 1 +flip: E298 score: 1 +flip: E291 score: 1 +flip: SA0_G19 score: 1 +flip: E63 score: 7 +flip: SA0_G4_line_G37 score: 1 +flip: E253 score: -8 +flip: G11_line_G20 score: 1 +flip: SA0_G11_line_G20 score: 1 +flip: E252 score: 6 +flip: E68 score: 1 +flip: E310 score: 1 +flip: G9_line_G35 score: 1 +flip: SA0_G9_line_G35 score: 1 +flip: SA0_G13_line_G23 score: 1 +flip: SA0_G26 score: 1 +flip: SA1_G13_line_G23 score: -27 +flip: E330 score: 1 +flip: E96 score: 1 +flip: SA0_G9_line_G35 score: 1 +flip: G9 score: 2 +flip: SA0_G13_line_G23 score: 1 +flip: G1_line_G9 score: 9 +flip: G2_line_G17 score: 1 +flip: G11_line_G21 score: 1 +flip: E302 score: 1 +flip: E324 score: 2 +flip: E332 score: 1 +flip: G11_line_G31 score: 1 +flip: E180 score: 4 +flip: G20_line_G43 score: 1 +flip: E386 score: 1 +flip: SA0_G20_line_G43 score: 1 +flip: SA0_G11_line_G31 score: 1 +flip: E287 score: 1 +flip: SA1_G13_line_G23 score: 25 +flip: G17 score: 1 +flip: E294 score: 1 +flip: E374 score: 2 +flip: E87 score: 2 +flip: SA0_G13_line_G23 score: 1 +flip: SA0_G11_line_G21 score: 1 +flip: E292 score: 13 +flip: G28 score: 1 +flip: E370 score: 2 +flip: SA0_G4_line_G21 score: 1 +flip: E371 score: 6 +flip: E300 score: 6 +flip: E186 score: 3 +flip: E66 score: 1 +flip: G13_line_G39 score: 1 +flip: G13 score: 5 +flip: E282 score: 21 +flip: SA0_G4_line_G32 score: 1 +flip: G2 score: 17 +flip: E98 score: 5 +flip: G22 score: 3 +flip: SA0_G22 score: 1 +flip: G11_line_G22 score: 2 +flip: SA0_G11_line_G22 score: 1 +flip: E291 score: 5 +flip: E64 score: 13 +flip: E206 score: 2 +flip: G13_line_G44 score: 3 +flip: E140 score: 3 +flip: SA0_G34 score: 1 +flip: SA0_G13_line_G44 score: 1 +flip: SA0_G6_line_G22 score: 1 +flip: E142 score: 10 +flip: E204 score: -1 +flip: SA1_G11_line_G20 score: 1 +flip: E310 score: 1 +flip: G2_line_G10 score: 1 +flip: E108 score: 1 +flip: G2 score: 4 +flip: G15 score: 2 +flip: E202 score: 5 +flip: E296 score: 1 +flip: E182 score: 1 +flip: E418 score: 3 +flip: SA0_G23_line_G31 score: 1 +flip: SA0_G20_line_G30 score: 1 +flip: G15_line_G30 score: 3 +flip: G40 score: 1 +flip: SA0_G19 score: 1 +flip: E382 score: 1 +flip: E160 score: 1 +flip: SA0_G15_line_G30 score: 1 +flip: SA1_G2_line_G10 score: 1 +flip: E162 score: 1 +flip: SA0_G2_line_G10 score: 1 +flip: SA1_G23 score: -26 +flip: G49 score: 1 +flip: G4_line_G37 score: 1 +flip: G45 score: 8 +flip: SA0_G45 score: 1 +flip: E44 score: 2 +flip: G28 score: 3 +flip: SA0_G4_line_G37 score: 1 +flip: G5_line_G28 score: 2 +flip: E68 score: 1 +flip: G12 score: 1 +flip: SA0_G5_line_G28 score: 1 +flip: E70 score: 9 +flip: E167 score: 6 +flip: SA0_G41 score: 1 +flip: G16 score: 1 +flip: G7 score: 1 +flip: E146 score: 1 +flip: SA0_G26 score: 1 +flip: E284 score: 1 +flip: G4_line_G13 score: 1 +flip: SA0_G4_line_G13 score: 1 +flip: SA0_G28 score: 1 +flip: SA0_G7 score: 1 +flip: E6 score: 1 +flip: SA1_G7 score: 1 +flip: E348 score: 1 +flip: G3 score: 1 +flip: E3 score: 1 +flip: SA1_G3 score: 1 +flip: SA0_G3 score: 1 +flip: E120 score: -4 +flip: E122 score: 6 +flip: E309 score: 1 +flip: G43 score: 1 +flip: SA0_G13_line_G39 score: 1 +flip: G14_line_G39 score: 2 +flip: G6_line_G15 score: 1 +flip: G14 score: 3 +flip: E22 score: 1 +flip: E20 score: 16 +flip: G31 score: 2 +flip: SA0_G14_line_G39 score: 1 +flip: SA0_G31 score: 1 +flip: E421 score: 1 +flip: E226 score: 4 +flip: SA1_G6_line_G15 score: 1 +flip: SA0_G6_line_G15 score: 1 +flip: SA1_G13 score: -35 +flip: G15_line_G30 score: 1 +flip: E112 score: 1 +flip: G47 score: 1 +flip: G29_line_G41 score: 1 +flip: SA0_G29_line_G41 score: 1 +flip: E74 score: 1 +flip: SA1_G4_line_G13 score: 1 +flip: E348 score: 1 +flip: SA0_G15_line_G30 score: 1 +flip: E114 score: 18 +flip: G2_line_G17 score: 1 +flip: E332 score: 1 +flip: E326 score: 1 +flip: SA0_G30 score: 1 +flip: E330 score: 3 +flip: G8 score: 1 +flip: E328 score: 1 +flip: G1_line_G8 score: 1 +flip: SA0_G1_line_G8 score: 1 +flip: E391 score: 1 +flip: G29_line_G41 score: 0 +flip: SA0_G29_line_G41 score: 1 +flip: E390 score: 1 +flip: G32_line_G40 score: 1 +flip: E379 score: 1 +flip: G5_line_G14 score: 1 +flip: SA0_G32_line_G40 score: 1 +flip: G9_line_G18 score: 1 +flip: E274 score: 1 +flip: E240 score: 1 +flip: SA1_G32_line_G40 score: 1 +flip: SA0_G9_line_G18 score: 2 +flip: E274 score: 1 +flip: E290 score: 1 +flip: E268 score: 1 +flip: SA1_G5_line_G14 score: 1 +flip: SA0_G5_line_G14 score: 1 +flip: SA1_G9_line_G18 score: 1 +flip: SA1_G49 score: -35 +flip: G5 score: 2 +flip: G43 score: 1 +flip: E411 score: 13 +flip: G11 score: 3 +flip: G20_line_G43 score: 3 +flip: E252 score: 1 +flip: E32 score: 1 +flip: E253 score: 6 +flip: SA0_G13_line_G23 score: 1 +flip: E30 score: 1 +flip: E318 score: 21 +flip: G15_line_G30 score: 1 +flip: SA0_G43 score: 1 +flip: E24 score: 1 +flip: SA0_G39 score: 1 +flip: G20_line_G30 score: 1 +flip: E26 score: 14 +flip: E255 score: 11 +flip: SA1_G23 score: 34 +flip: E34 score: 19 +flip: SA0_G20_line_G43 score: 1 +flip: SA0_G15_line_G30 score: 1 +flip: SA1_G1_line_G8 score: 1 +flip: E87 score: 7 +flip: E196 score: 7 +flip: SA0_G20_line_G30 score: 1 +flip: E391 score: 1 +flip: SA0_G35 score: 1 +flip: E388 score: -6 +flip: G15_line_G26 score: 1 +flip: G48 score: 1 +flip: E172 score: 21 +flip: E178 score: 4 +flip: SA0_G15_line_G25 score: 1 +flip: E388 score: 4 +flip: SA0_G15_line_G25 score: 1 +flip: E390 score: 1 +flip: G13_line_G39 score: -5 +flip: G11_line_G34 score: 1 +flip: G11_line_G24 score: 1 +flip: E230 score: 1 +flip: G20_line_G30 score: 1 +flip: E58 score: 1 +flip: G29_line_G41 score: 1 +flip: G22 score: 3 +flip: E152 score: 1 +flip: G34 score: 1 +flip: SA0_G22 score: 1 +flip: G44 score: 5 +flip: E35 score: 1 +flip: E56 score: 23 +flip: G14_line_G24 score: 7 +flip: SA0_G29_line_G41 score: 1 +flip: SA0_G20_line_G30 score: 1 +flip: SA0_G34 score: 1 +flip: G17 score: 1 +flip: E154 score: 16 +flip: G13_line_G39 score: 2 +flip: E295 score: 1 +flip: SA0_G14_line_G24 score: 1 +flip: SA0_G32_line_G41 score: 1 +flip: E228 score: 22 +flip: E144 score: 1 +flip: SA0_G44 score: 1 +flip: SA0_G17 score: 1 +flip: G30 score: 1 +flip: SA0_G13_line_G44 score: 1 +flip: G13_line_G39 score: 5 +flip: G14_line_G39 score: 1 +flip: SA0_G13_line_G39 score: 1 +flip: SA0_G14_line_G39 score: 1 +flip: SA0_G30 score: 1 +flip: G25 score: -11 +flip: G25_line_G34 score: 6 +flip: E150 score: 1 +flip: G2_line_G10 score: 1 +flip: G32_line_G41 score: 2 +flip: SA0_G25_line_G34 score: 1 +flip: G5 score: 3 +flip: G15_line_G25 score: 6 +flip: E148 score: 1 +flip: E384 score: 2 +flip: G2 score: 13 +flip: E382 score: 1 +flip: SA0_G29_line_G41 score: 1 +flip: G15_line_G27 score: 1 +flip: E217 score: 1 +flip: SA0_G5_line_G25 score: 1 +flip: SA0_G15_line_G27 score: 1 +flip: SA0_G32_line_G41 score: 1 +flip: SA0_G15_line_G25 score: 1 +flip: SA0_G2_line_G10 score: 1 +flip: SA1_G2_line_G10 score: 1 +flip: E8 score: -5 +flip: SA0_G24 score: 1 +flip: E234 score: 1 +flip: E10 score: 16 +flip: G6 score: 1 +flip: G11_line_G34 score: 1 +flip: G32 score: 1 +flip: E428 score: 14 +flip: G6 score: 5 +flip: SA0_G11_line_G34 score: 1 +flip: E278 score: 23 +flip: G14 score: -17 +flip: G4_line_G13 score: 1 +flip: E226 score: 16 +flip: E347 score: 1 +flip: G14_line_G24 score: 10 +flip: G9_line_G26 score: 1 +flip: E200 score: 1 +flip: SA0_G9_line_G26 score: 1 +flip: SA0_G14_line_G24 score: 1 +flip: G5_line_G14 score: 8 +flip: E268 score: 1 +flip: E175 score: 2 +flip: G18_line_G27 score: 1 +flip: SA0_G5_line_G14 score: 1 +flip: E220 score: 2 +flip: E218 score: 18 +flip: G6_line_G15 score: 1 +flip: E421 score: 1 +flip: SA0_G6_line_G15 score: 1 +flip: G25_line_G33 score: 1 +flip: SA0_G25_line_G33 score: 2 +flip: G17 score: 1 +flip: SA1_G6_line_G15 score: 1 +flip: E295 score: 4 +flip: SA0_G4_line_G13 score: 2 +flip: E217 score: 5 +flip: SA0_G17 score: 1 +flip: SA1_G5_line_G14 score: 1 +flip: G46 score: 18 +flip: G12 score: 1 +flip: E42 score: 1 +flip: G3 score: 1 +flip: SA0_G3 score: 1 +flip: G16 score: 1 +flip: G18 score: 2 +flip: E243 score: 1 +flip: E204 score: 1 +flip: G7 score: 1 +flip: G11_line_G34 score: 1 +flip: SA0_G7 score: 1 +flip: SA0_G11_line_G34 score: 1 +flip: E124 score: 1 +flip: E3 score: 1 +flip: SA1_G3 score: 1 +flip: E232 score: 3 +flip: SA0_G25_line_G34 score: 1 +flip: E265 score: 25 +flip: SA1_G25_line_G33 score: 2 +flip: E309 score: 1 +flip: SA1_G4_line_G13 score: 2 +flip: E6 score: 1 +flip: SA1_G7 score: 1 +flip: E55 score: -1 +flip: G18_line_G28 score: 1 +flip: G32 score: 1 +flip: G5_line_G28 score: 5 +flip: E170 score: 1 +flip: E168 score: 26 +flip: SA0_G5_line_G28 score: 1 +flip: G1_line_G8 score: 1 +flip: SA0_G1_line_G8 score: 2 +flip: G4_line_G21 score: 1 +flip: SA0_G4_line_G21 score: 1 +flip: G26 score: 2 +flip: G11_line_G24 score: 1 +flip: G37 score: 10 +flip: SA0_G11_line_G24 score: 1 +flip: SA0_G37 score: 1 +flip: E72 score: 3 +flip: E184 score: 4 +flip: G28 score: 5 +flip: E15 score: 2 +flip: G11_line_G21 score: 1 +flip: E186 score: 7 +flip: SA0_G26 score: 1 +flip: SA0_G4_line_G37 score: 1 +flip: SA0_G11_line_G21 score: 1 +flip: SA0_G28 score: 1 +flip: E184 score: 12 +flip: E326 score: -8 +flip: G2_line_G17 score: 8 +flip: G18_line_G28 score: 2 +flip: E116 score: 1 +flip: SA0_G2_line_G17 score: 1 +flip: G38 score: 1 +flip: E14 score: 1 +flip: E166 score: 1 +flip: E159 score: 6 +flip: E328 score: 15 +flip: E175 score: 1 +flip: SA0_G18_line_G28 score: 1 +flip: E379 score: 1 +flip: SA0_G38 score: 1 +flip: G2 score: 41 +flip: SA0_G8 score: 1 +flip: E176 score: 2 +flip: E178 score: 21 +flip: SA0_G15_line_G26 score: 1 +flip: SA1_G1_line_G8 score: 2 +flip: E15 score: 0 +flip: E16 score: 2 +flip: G29_line_G38 score: 1 +flip: E18 score: 23 +flip: G11_line_G24 score: 1 +flip: SA0_G42 score: 1 +flip: SA0_G11_line_G24 score: 1 +flip: G20_line_G43 score: 1 +flip: E88 score: 2 +flip: SA0_G33_line_G43 score: 1 +flip: SA0_G20_line_G43 score: 1 +flip: E90 score: 28 +flip: G39 score: -11 +flip: E86 score: 1 +flip: G47 score: 13 +flip: SA0_G29_line_G38 score: 1 +flip: E269 score: 1 +flip: G43 score: 13 +flip: SA0_G39 score: 1 +flip: G22 score: 1 +flip: E28 score: 4 +flip: E118 score: 9 +flip: G13_line_G39 score: 1 +flip: E124 score: 3 +flip: G30 score: 1 +flip: G18 score: 1 +flip: E237 score: 1 +flip: SA0_G43 score: 1 +flip: E120 score: 2 +flip: G35 score: 9 +flip: SA0_G35 score: 1 +flip: SA0_G31 score: 1 +flip: E122 score: 9 +flip: SA0_G30 score: 1 +flip: G11_line_G34 score: -6 +flip: E235 score: 1 +flip: G2_line_G11 score: 1 +flip: E358 score: 4 +flip: SA0_G2_line_G11 score: 1 +flip: G18_line_G27 score: 2 +flip: E232 score: 3 +flip: E234 score: 6 +flip: E216 score: 1 +flip: G21 score: 1 +flip: E180 score: 1 +flip: SA0_G11_line_G34 score: 1 +flip: SA0_G21 score: 1 +flip: SA0_G18_line_G27 score: 1 +flip: E360 score: 23 +flip: G2 score: 56 +flip: E80 score: 3 +flip: SA0_G33_line_G42 score: 1 +flip: SA0_G1_line_G11 score: 1 +flip: G2_line_G10 score: 1 +flip: E82 score: 27 +flip: SA0_G25_line_G34 score: 1 +flip: G2 score: 24 +flip: E382 score: 1 +flip: SA1_G2_line_G10 score: 1 +flip: G33_line_G42 score: 1 +flip: SA0_G2_line_G10 score: 1 +flip: SA0_G33_line_G42 score: 1 +flip: E386 score: -5 +flip: E384 score: 18 +flip: G15_line_G25 score: 1 +flip: SA0_G5_line_G25 score: 1 +====== test end