diff --git a/atpg b/atpg index 2ad58e5..dd5ffcb 100755 Binary files a/atpg and b/atpg differ diff --git a/circuit.h b/circuit.h index 6861c88..011261b 100644 --- a/circuit.h +++ b/circuit.h @@ -80,18 +80,18 @@ void init_stems(); // local search // shared info -static const int STEM_INC = 10; +static const int STEM_INC = 2; static const int STEM_COST_MAX = 1e9; static ll stem_total_cost; static int stem_falsified_cnt; -static const int PROPAGATE_INC = 10; +static const int PROPAGATE_INC = 2; static const int PROPAGATE_COST_MAX = 1e9; static ll propagate_total_cost; static int propagate_falsified_cnt; static const int FAULT_INC = 1; -static const int FAULT_COST_MAX = 20; +static const int FAULT_COST_MAX = 1e9; static ll fault_total_cost; static int fault_falsified_cnt; @@ -116,4 +116,8 @@ void ls_update(Gate* stem); ll ls_pick_score(Gate* stem, bool value, bool propagate); ll ls_score(); + + +// simulator +int** simulate(); }; \ No newline at end of file diff --git a/ls.cpp b/ls.cpp index 05df9ef..94e733a 100644 --- a/ls.cpp +++ b/ls.cpp @@ -28,6 +28,19 @@ bool Circuit::local_search(std::unordered_set &faults) { ls_update_weight(); picked_stem = ls_pick_falsified_var(value, propagate); printf("[UP] propagate: %lld, stem: %lld, fault:%lld. propagate_cnt: %d, stem_cnt: %d, fault_cnt:%d\n", propagate_total_cost, stem_total_cost, fault_total_cost, propagate_falsified_cnt, stem_falsified_cnt, fault_falsified_cnt); + + int** sa = simulate(); + int cnt = 0; + static int max_cnt = 0; + + for(Fault* f : faults) { + if(sa[f->gate->id][f->type]) { + cnt++; + } + } + max_cnt = std::max(max_cnt, cnt); + + printf("[SOL] detect-faults: %d max-faults: %d\n", cnt, max_cnt); } else { // printf("pick: %s value: %d propagate: %d\n", picked_stem->name.c_str(), value, propagate); // printf("[LS] propagate: %lld, stem: %lld, fault:%lld. propagate_cnt: %d, stem_cnt: %d, fault_cnt:%d\n", propagate_total_cost, stem_total_cost, fault_total_cost, propagate_falsified_cnt, stem_falsified_cnt, fault_falsified_cnt); diff --git a/simulator.cpp b/simulator.cpp new file mode 100644 index 0000000..5fd4cad --- /dev/null +++ b/simulator.cpp @@ -0,0 +1,150 @@ +#include "circuit.h" + +#include +#include + +int cal_value(Gate *g, int *value) { + int res; + + switch(g->type) { + case Gate::NOT: + res = !value[g->inputs[0]->id]; + break; + case Gate::BUF: + res = value[g->inputs[0]->id]; + break; + case Gate::AND: + res = value[g->inputs[0]->id]; + for(int i=1; iinputs.size(); i++) { + res &= value[g->inputs[i]->id]; + } + break; + case Gate::NAND: + res = value[g->inputs[0]->id]; + for(int i=1; iinputs.size(); i++) { + res &= value[g->inputs[i]->id]; + } + res = !res; + break; + case Gate::OR: + res = value[g->inputs[0]->id]; + for(int i=1; iinputs.size(); i++) { + res |= value[g->inputs[i]->id]; + } + break; + case Gate::NOR: + res = value[g->inputs[0]->id]; + for(int i=1; iinputs.size(); i++) { + res |= value[g->inputs[i]->id]; + } + res = !res; + break; + case Gate::XOR: + res = value[g->inputs[0]->id]; + for(int i=1; iinputs.size(); i++) { + res ^= value[g->inputs[i]->id]; + } + break; + case Gate::XNOR: + res = value[g->inputs[0]->id]; + for(int i=1; iinputs.size(); i++) { + res ^= value[g->inputs[i]->id]; + } + res = !res; + break; + case Gate::INPUT: + res = value[g->id]; + break; + default: + assert(false); + break; + } + return res; +} + +bool cal_sa(Gate* g, bool x, int** sa, int *value) { + if(g->po) { + if(x == 0) return value[g->id]; + else return !value[g->id]; + } + + bool sa0 = 0; + bool sa1 = 0; + + for(Gate* out : g->outputs) { + if(!sa[out->id][0] && !sa[out->id][1]) continue; + + if(cal_value(out, value) != value[out->id]) continue; + + value[g->id] = !value[g->id]; + bool detect = cal_value(out, value) != value[out->id]; + value[g->id] = !value[g->id]; + if(!detect) continue; + + sa0 |= value[g->id]; + sa1 |= !value[g->id]; + } + if(x == 0) return sa0; + else return sa1; +} + + +int** Circuit::simulate() { + + static bool init = false; + static int** sa = nullptr; + static int* value = nullptr; + + if(!init) { + const int MAXN = gates.size() + 1; + init = true; + sa = new int*[MAXN]; + for(int i=0; iid] = pi->value; + } + + for(Gate *g : gates) { + if(g->pi) continue; + value[g->id] = cal_value(g, value); + } + + for(Gate *g : gates) { + assert(value[g->id] == cal_value(g, value)); + } + + std::queue q; + std::unordered_map topo; + + // init PO + for(Gate* po : POs) { + sa[po->id][!value[po->id]] = 1; + sa[po->id][value[po->id]] = 0; + q.push(po); + } + + while(!q.empty()) { + Gate* g = q.front(); + q.pop(); + for(Gate* in : g->inputs) { + if(++topo[in] == in->outputs.size()) { + sa[in->id][0] = cal_sa(in, 0, sa, value); + sa[in->id][1] = cal_sa(in, 1, sa, value); + q.push(in); + } + } + } + + for(Gate* g : gates) { + assert(sa[g->id][0] == cal_sa(g, 0, sa, value)); + assert(sa[g->id][1] == cal_sa(g, 1, sa, value)); + } + + return sa; +} \ No newline at end of file