diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d800466 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.0) + +project(atpg) +set(CMAKE_CXX_STANDARD 17) + +# 设置编译器优化选项 +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g") + +# 设置源文件和头文件的路径 +aux_source_directory(${PROJECT_SOURCE_DIR}/src SOURCES) +set(INCLUDES ${PROJECT_SOURCE_DIR}/src) + +message(${SOURCES}) + +# 生成可执行文件 +add_executable(${PROJECT_NAME} ${SOURCES}) + +# 添加头文件 +include_directories(${INCLUDES}) \ No newline at end of file diff --git a/atpg b/atpg index c5de327..f635b36 100755 Binary files a/atpg and b/atpg differ diff --git a/crun b/crun index bb6112f..0c478b2 100755 --- a/crun +++ b/crun @@ -10,6 +10,6 @@ if [ $? -ne 0 ]; then else clear echo "========================" - time ./atpg -i $1 --lut 4 + time ./atpg -i $1 --lut 8 fi diff --git a/src/checker.cpp b/src/checker.cpp index f6b7ed4..ff647db 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -13,11 +13,16 @@ int LUTCircuit::check() { int score_fault_detected_weight = 0; int score_fault_propagated_weight = 0; int score_fault_update_cost = 0; + int unsatisfied_lut = 0; for(LUT* lut : luts) { assert(lut->vsat == (lut->value == lut->cal_value())); - if(!lut->vsat) score_value_unsatisfied_cost += lut->vunat_cost; + if(!lut->vsat) { + score_value_unsatisfied_cost += lut->vunat_cost; + unsatisfied_lut++; + // printf("vunsat: %s\n", lut->name); + } if(lut->uptag) { score_fault_update_cost += lut->up_cost; @@ -46,20 +51,6 @@ int LUTCircuit::check() { 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]; - - // if(lut->gate->name == "new_n546_") { - // printf("new_n546_: %d %d %d %d\n", t_fd[0], t_fd[1], t_fpl[0], t_fpl[1]); - // } - - // if(t_fd[0] || t_fd[1]) { - // printf("find: %s\n", g->name.c_str()); - // } - - // printf("%10s - %10s fd %d %d fpl %d %d\n", lut->gate->name.c_str(), g->name.c_str(), t_fd[0], t_fd[1], t_fpl[0], t_fpl[1]); - - // if(g->name == "new_n549_") { - // printf("new_n549_: %d %d %d %d fa: %s\n", t_fd[0], t_fd[1], t_fpl[0], t_fpl[1], lut->gate->name.c_str()); - // } score_fault_detected_weight += t_fd[0] * g->fault_detected_weight[0]; score_fault_detected_weight += t_fd[1] * g->fault_detected_weight[1]; @@ -69,6 +60,7 @@ int LUTCircuit::check() { } } + printf("unsat_lut: %d\n", unsatisfied_lut); printf("score_value_unsatisfied_cost: %d\n", score_value_unsatisfied_cost); printf("score_fault_detected_weight: %d\n", score_fault_detected_weight); printf("score_fault_propagated_weight: %d\n", score_fault_propagated_weight); diff --git a/src/circuit.cpp b/src/circuit.cpp index 62a4b47..06ec2ee 100644 --- a/src/circuit.cpp +++ b/src/circuit.cpp @@ -60,7 +60,7 @@ LUTCircuit* Circuit::build_lut_circuit() { Gate* gate = q.front(); q.pop(); - LUT* lut = new LUT(gate); + LUT* lut = new LUT(gate, C); gate2LUT[gate] = lut; diff --git a/src/circuit.h b/src/circuit.h index dd513f3..eb5dd62 100644 --- a/src/circuit.h +++ b/src/circuit.h @@ -5,6 +5,8 @@ using ll = long long; +class Simulator; + class LUTCircuit { public: std::vector PIs; @@ -12,12 +14,16 @@ std::vector POs; std::vector luts; std::vector rtopo_luts; +int step; + void print(); +std::vector good_luts; + // local search void ls_update(); -void ls_pick(); +LUT* ls_pick(); void ls_flip(LUT *lut); void ls_main(); @@ -25,6 +31,9 @@ void ls_main(); int check(); + +Simulator *simulator; + }; class Circuit { diff --git a/src/ls.cpp b/src/ls.cpp index fc5f5e5..9ea4fa0 100644 --- a/src/ls.cpp +++ b/src/ls.cpp @@ -1,6 +1,69 @@ #include #include "circuit.h" +#include "paras.h" +#include "simulator.h" + +LUT* LUTCircuit::ls_pick() { + + LUT* pick = nullptr; + + // for(LUT* lut : luts) { + // if(!lut->vsat) return lut; + // } + + // assert(false); + + if(rand() % 10000 <= OPT(brk_sp) * 10000) { + printf("BREAK!!!!!\n"); + pick = luts[rand() % luts.size()]; + return pick; + } + + if(good_luts.size() > 0) { + pick = good_luts[rand() % good_luts.size()]; + if(pick->score <= 0 || pick->tabu > step) { + pick = nullptr; + for(int i=0; iscore <= 0 || good_luts[i]->tabu > step) { + good_luts[i]->is_good_var = 0; + good_luts[i] = good_luts.back(); + good_luts.pop_back(); + i--; + } + } + + if(good_luts.size() > 0) { + pick = good_luts[rand() % good_luts.size()]; + assert(pick->score > 0 && pick->tabu <= step); + } + } + } + + if(pick == nullptr) { + printf("UPDATE!!!!!\n"); + ls_update(); + + std::vector t; + + for(LUT* lut : luts) { + if(!lut->vsat) { + t.push_back(lut); + } + } + + pick = t[rand() % t.size()]; + + // pick = luts[rand() % luts.size()]; + + assert(pick != nullptr); + + } else { + printf("GOOD_VAR!!!!!\n"); + } + + return pick; +} void LUTCircuit::ls_flip(LUT *lut) { @@ -8,6 +71,8 @@ void LUTCircuit::ls_flip(LUT *lut) { lut->value = !lut->value; if(!lut->isPI) lut->vsat = !lut->vsat; + lut->tabu = lut->vunat_cost + step; + for(LUT* out : lut->fanouts) { out->vsat = (out->cal_value() == out->value); } @@ -35,6 +100,24 @@ void LUTCircuit::ls_flip(LUT *lut) { } } +void LUTCircuit::ls_update() { + + std::unordered_set need_up; + + for(LUT* lut : luts) { + if(!lut->vsat) { + lut->vunat_cost += OPT(vsat_inc); + need_up.insert(lut); + need_up.insert(lut->fanins.begin(), lut->fanins.end()); + } + } + + for(LUT* lut : need_up) { + lut->cal_score(); + } + +} + void LUTCircuit::ls_main() { printf("====== local search start ======\n"); @@ -86,14 +169,21 @@ void LUTCircuit::ls_main() { for(LUT* r : t_reigon) { lut->update_reigon.push_back(r); } - printf("rg: %d %d\n", lut->reigon.size(), lut->update_reigon.size()); + // printf("rg: %d %d\n", lut->reigon.size(), lut->update_reigon.size()); } printf("generating initial solution ...\n"); for(LUT* lut : luts) { lut->up_cost = 1; + lut->vunat_cost = 1; + if(lut->isPI) { + lut->vunat_cost = OPT(vsat_inc) * 100; + } + + lut->is_good_var = 0; + lut->tabu = 0; for(Gate* g : lut->inner_gates) { g->fault_detected_weight[0] = g->fault_detected_weight[1] = 1; g->fault_propagated_weight[0] = g->fault_propagated_weight[1] = 1; @@ -119,12 +209,14 @@ void LUTCircuit::ls_main() { lut->cal_score(); } + step = 0; + print(); int seed = time(0); srand(1689658115); - int T = 10000; + int T = 100000; while(T--) { if(T % 1000 == 0) { @@ -135,23 +227,43 @@ void LUTCircuit::ls_main() { // print(); - LUT* pick = luts[rand() % luts.size()]; + LUT* pick = ls_pick(); // pick->cal_score(); - // printf(">>>> flip: %s\n", pick->name); + printf(">>>> flip: %s\n", pick->name); // int s = pick->score; - // printf("##### score: %d seed: %d\n", pick->score, seed); - // printf("vusat_cost: %d fdw: %d fplw: %d up: %d\n", pick->score_value_unsatisfied_cost, pick->score_fault_detected_weight, pick->score_fault_propagated_weight, pick->score_fault_update_cost); + printf("##### score: %d seed: %d\n", pick->score, seed); + printf("vusat_cost: %d fdw: %d fplw: %d up: %d\n", pick->score_value_unsatisfied_cost, pick->score_fault_detected_weight, pick->score_fault_propagated_weight, pick->score_fault_update_cost); + + int score; + simulator->simulate(PIs, score); + printf("score: %d\n", score); ls_flip(pick); // int t2 = check(); + check(); + + int cnt = 0; + for(LUT* lut : luts) { + if(!lut->vsat) cnt++; + } + printf("unsat: %d\n", cnt); // print(); // assert(s == (t2 - t1)); + step++; + + for(LUT *lut : luts) { + if(!lut->is_good_var && lut->score > 0 && lut->tabu <= step) { + lut->is_good_var = 1; + good_luts.push_back(lut); + } + } + } // print(); // exit(0); diff --git a/src/lut.cpp b/src/lut.cpp index bba8053..14e2b8e 100644 --- a/src/lut.cpp +++ b/src/lut.cpp @@ -60,7 +60,9 @@ int LUT::cal_value() { return value_table[input]; } -LUT::LUT(Gate *gate):gate(gate), value(gate->value), name(gate->name.c_str()) { +LUT::LUT(Gate *gate, LUTCircuit *circuit):gate(gate), value(gate->value), name(gate->name.c_str()) { + + C = circuit; isPI = gate->isPI; isPO = gate->isPO; diff --git a/src/lut.h b/src/lut.h index 98432a8..cbc8535 100644 --- a/src/lut.h +++ b/src/lut.h @@ -1,66 +1,70 @@ +#pragma once + +class LUTCircuit; + #include "gate.h" class LUT { public: + LUT(Gate *gate, LUTCircuit *circuit); - LUT(Gate *gate); + LUTCircuit *C; - Gate* gate; + Gate *gate; - bool isPI, isPO; + bool isPI, isPO; - std::vector fanins; + std::vector fanins; - std::vector fanouts; + std::vector fanouts; - std::vector reigon; - std::vector update_reigon; + std::vector reigon; + std::vector update_reigon; - std::vector add_update_to_this; + std::vector add_update_to_this; - std::vector inner_gates; + std::vector inner_gates; - std::vector __gate_fanins; + std::vector __gate_fanins; - std::unordered_map input_id; + std::unordered_map input_id; - int& value; - const char* name; + int &value; + const char *name; - int *value_table; + int *value_table; - struct FaultInfo { - int fd[2]; - int fpl[2]; - } **fault_table; - - std::vector fault_info; - - std::unordered_set update_luts; - - void init_lookup_table(); - - // local search - - bool vsat, vunat_cost; - bool uptag, up_cost; + struct FaultInfo { int fd[2]; int fpl[2]; + } **fault_table; - 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); + std::vector fault_info; - // score - int score; - int score_value_unsatisfied_cost; - int score_fault_detected_weight; - int score_fault_propagated_weight; - int score_fault_update_cost; + std::unordered_set update_luts; - void cal_score(); - void cal_update(); - + void init_lookup_table(); + + // local search + + bool vsat, vunat_cost; + bool uptag, up_cost; + int fd[2]; + int fpl[2]; + int is_good_var; + int tabu; + + 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 + int score; + int score_value_unsatisfied_cost; + int score_fault_detected_weight; + int score_fault_propagated_weight; + int score_fault_update_cost; + + void cal_score(); + void cal_update(); }; - - diff --git a/src/main.cpp b/src/main.cpp index 5ab0245..c085a7b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,5 @@ #include "circuit.h" +#include "simulator.h" #include "paras.h" int main(int argc, char *argv[]) { @@ -9,13 +10,17 @@ int main(int argc, char *argv[]) { srand(19260817); Circuit *circuit = new Circuit(); + Simulator* simulator = new Simulator(); printf("parsing file %s ...\n", OPT(instance).c_str()); circuit->parse_from_file(OPT(instance).c_str()); + simulator->parse_from_file(OPT(instance).c_str()); circuit->init_topo_index(); + simulator->init_topo_index(); 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()); diff --git a/src/paras.h b/src/paras.h index e8a462a..dcb0fe9 100644 --- a/src/paras.h +++ b/src/paras.h @@ -7,7 +7,10 @@ // name, type, short-name,must-need, default ,low, high, comments #define PARAS \ - PARA( lut , int , '\0' , false , 8 , 0 , 16 , "max input numbers of LUT") + PARA( lut , int , '\0' , false , 8 , 0 , 16 , "max input numbers of LUT") \ + PARA( sp , double , '\0' , false , 0.01 , 0 , 1 , "max input numbers of LUT") \ + PARA( vsat_inc , int , '\0' , false , 20 , 0 , 16 , "max input numbers of LUT") \ + PARA( brk_sp , double , '\0' , false , 0.05 , 0 , 1 , "max input numbers of LUT") // name, short-name, must-need, default, comments #define STR_PARAS \ diff --git a/src/parse.cpp b/src/parse.cpp index 6de1483..5e3451b 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -76,7 +76,6 @@ void Circuit::parse_from_file(const char *filename) { gate->isPI = false; gate->isPO = false; - for(auto &in : ins) { if(!name2gate.count(in)) { printf("Error while reading file: gate %s used before defination.\n", in.c_str()); diff --git a/src/score.cpp b/src/score.cpp index 5510cef..d51e35d 100644 --- a/src/score.cpp +++ b/src/score.cpp @@ -1,6 +1,5 @@ #include "lut.h" - - +#include "circuit.h" void LUT::cal_update() { @@ -55,6 +54,11 @@ void LUT::cal_update() { } score = - score_value_unsatisfied_cost + score_fault_detected_weight + score_fault_propagated_weight - score_fault_update_cost; + + if(!is_good_var && score > 0 && tabu <= C->step) { + is_good_var = 1; + C->good_luts.push_back(this); + } } void LUT::cal_score() { @@ -206,4 +210,9 @@ void LUT::cal_score() { } score = - score_value_unsatisfied_cost + score_fault_detected_weight + score_fault_propagated_weight - score_fault_update_cost; + + if(!is_good_var && score > 0 && tabu <= C->step) { + is_good_var = 1; + C->good_luts.push_back(this); + } } \ No newline at end of file diff --git a/src/simulator.cpp b/src/simulator.cpp index e69de29..d8d1b8d 100644 --- a/src/simulator.cpp +++ b/src/simulator.cpp @@ -0,0 +1,27 @@ +#include "simulator.h" + +void Simulator::simulate(std::vector &inputs, int &score) { + + assert(inputs.size() == this->PIs.size()); + + for(int i=0; ivalue = inputs[i]->value; + } + + for(auto gate : gates) { + gate->cal_value(); + } + + for(auto gate : rtopo_gates) { + gate->fault_detected[0] = gate->cal_fault_detected(0); + gate->fault_detected[1] = gate->cal_fault_detected(1); + } + + score = 0; + + for(auto gate : gates) { + if(gate->fault_detected[0] || gate->fault_detected[1]) { + score++; + } + } +} \ No newline at end of file diff --git a/src/simulator.h b/src/simulator.h new file mode 100644 index 0000000..2d3ad85 --- /dev/null +++ b/src/simulator.h @@ -0,0 +1,8 @@ +#pragma once + +#include "circuit.h" + +class Simulator : public Circuit { +public: + void simulate(std::vector &inputs, int &score); +}; \ No newline at end of file