diff --git a/atpg b/atpg index c9a2e34..3f678d4 100755 Binary files a/atpg and b/atpg differ diff --git a/circuit.cpp b/circuit.cpp index a90dd60..9b8f3ea 100644 --- a/circuit.cpp +++ b/circuit.cpp @@ -77,8 +77,32 @@ void Circuit::print_gates() { bool Circuit::is_valid_circuit() { + + ll flip_total_weight = 0; + ll stem_total_weight = 0; + ll fault_total_weight = 0; + + //printf("flip: %d, stem: %d, fault:%d\n", flip_total_weight, stem_total_weight, fault_total_weight); + + for(Gate* g : gates) { + if(flip_need_update[g->id]) { + flip_total_weight += flip_weight[g->id]; + } + + if(g->stem) { + stem_total_weight += (g->cal_value() == g->value); + } + + if(g->sa[0]) { + fault_total_weight += fault_weight[g->id][0]; + } + + if(g->sa[1]) { + fault_total_weight += fault_weight[g->id][1]; + } + // 检查门的赋值情况 if(!g->stem && g->cal_value() != g->value) { return false; @@ -118,5 +142,11 @@ bool Circuit::is_valid_circuit() { } + if(this->flip_total_weight != flip_total_weight || this->stem_total_weight != stem_total_weight || this->fault_total_weight != fault_total_weight) { + printf("CIRCUIT CHECK FAILED!\n"); + printf("[wrong] flip: %d, stem: %d, fault:%d\n", this->flip_total_weight, this->stem_total_weight, this->fault_total_weight); + printf("[right] flip: %d, stem: %d, fault:%d\n", flip_total_weight, stem_total_weight, fault_total_weight); + } + return true; } \ No newline at end of file diff --git a/circuit.h b/circuit.h index 0527fb3..03a8c10 100644 --- a/circuit.h +++ b/circuit.h @@ -80,6 +80,10 @@ int** fault_detected; void ls_init_circuit(); void ls_init_weight(const std::vector &faults); void ls_init_data_structs(); -void ls_flip(Gate* stem); +void ls_block_recal(Gate* stem); + +void ls_flip(Gate* stem); +void ls_update(Gate* stem); +int ls_score(Gate* stem); }; \ No newline at end of file diff --git a/gate.cpp b/gate.cpp index ad35d75..f5be4bd 100644 --- a/gate.cpp +++ b/gate.cpp @@ -55,6 +55,9 @@ int Gate::cal_value() { } res = !res; break; + case INPUT: + res = value; + break; default: assert(false); break; diff --git a/ls.cpp b/ls.cpp index 4423e17..9fdab6d 100644 --- a/ls.cpp +++ b/ls.cpp @@ -29,20 +29,57 @@ bool cmp(Gate* a, Gate *b) { return a->id > b->id; } + void Circuit::ls_flip(Gate* stem) { + stem->value = !stem->value; + ls_block_recal(stem); +} +void Circuit::ls_update(Gate* stem) { + ls_block_recal(stem); +} +int Circuit::ls_score(Gate* stem) { + + ls_flip(stem); + + int score = -flip_total_weight + stem_total_weight + fault_total_weight; + + ls_flip(stem); + + return score; +} + +void Circuit::ls_block_recal(Gate* stem) { if(flip_need_update[stem->id]) { flip_need_update[stem->id] = false; flip_total_weight -= flip_weight[stem->id]; } + if(stem->cal_value() == stem->value && !stem_satisfied[stem->id]){ + stem_satisfied[stem->id] = true; + stem_total_weight += stem_weight[stem->id]; + } + + if(stem->cal_value() != stem->value && stem_satisfied[stem->id]) { + stem_satisfied[stem->id] = false; + stem_total_weight -= stem_weight[stem->id]; + } + //printf("flip: %s\n", stem->name.c_str()); //stem->value = !stem->value; if(stem->isPO) { - stem->sa[!stem->value] = true; - stem->sa[stem->value] = false; + + if(stem->sa[!stem->value] == false) { + fault_total_weight += fault_weight[stem->id][!stem->value]; + stem->sa[!stem->value] = true; + } + + if(stem->sa[stem->value] == true) { + fault_total_weight -= fault_weight[stem->id][stem->value]; + stem->sa[stem->value] = false; + } } std::queue q; @@ -73,6 +110,16 @@ void Circuit::ls_flip(Gate* stem) { for(Gate* stem : suc_stems) { q.push(stem); + + if(stem->cal_value() == stem->value && !stem_satisfied[stem->id]){ + stem_satisfied[stem->id] = true; + stem_total_weight += stem_weight[stem->id]; + } + + if(stem->cal_value() != stem->value && stem_satisfied[stem->id]) { + stem_satisfied[stem->id] = false; + stem_total_weight -= stem_weight[stem->id]; + } } while(!q.empty()) { @@ -124,6 +171,22 @@ void Circuit::ls_flip(Gate* stem) { } } + if(old_sa[0] != in->sa[0]) { + if(in->sa[0]) { + fault_total_weight += fault_weight[in->id][0]; + } else { + fault_total_weight -= fault_weight[in->id][0]; + } + } + + if(old_sa[1] != in->sa[1]) { + if(in->sa[1]) { + fault_total_weight += fault_weight[in->id][1]; + } else { + fault_total_weight -= fault_weight[in->id][1]; + } + } + //printf("gate: %s -> %s rv: %d id: %d p:%d sa0: %d sa1: %d\n", in->name.c_str(), g->name.c_str(), right_value, input_detected, g->is_propagated(), in->sa[0], in->sa[1]); if(!in->stem && !used[in]) { @@ -156,14 +219,16 @@ void Circuit::ls_init_circuit() { } for(int i=stems.size()-1; i>=0; i--) { - ls_flip(stems[i]); + ls_update(stems[i]); } while(!flip_update_queue.empty()) { Gate* g = flip_update_queue.back(); flip_update_queue.pop_back(); + if(!flip_need_update[g->id]) continue; flip_need_update[g->id] = false; - ls_flip(g); + flip_total_weight -= flip_weight[g->id]; + ls_update(g); } } @@ -187,6 +252,9 @@ void Circuit::ls_init_data_structs() { } } else { + flip_total_weight = 0; + stem_total_weight = 0; + fault_total_weight = 0; for(int i=0; iis_valid_circuit()); - - return 0; } \ No newline at end of file diff --git a/makefile b/makefile index 79aab05..ae4c441 100644 --- a/makefile +++ b/makefile @@ -7,7 +7,7 @@ #编译工具用g++,以同时支持C和C++程序,以及二者的混合编译 CC=g++ -CPPFLAGS=-O3 -std=c++17 +CPPFLAGS=-O3 -std=c++17 -g #使用$(winldcard *.c)来获取工作目录下的所有.c文件的列表 #sources:=main.cpp command.c