v1.7: 优化了stuck-at模型,但还是存在BUG
This commit is contained in:
parent
90a85d9119
commit
5ba2dbde89
26
b01.test
26
b01.test
@ -1,26 +0,0 @@
|
|||||||
* Name of circuit: experiment/benchmark/b01.bench
|
|
||||||
* Primary inputs :
|
|
||||||
LINE1 LINE2 OVERFLW_REG STATO_REG_2_ STATO_REG_1_ STATO_REG_0_ OUTP_REG
|
|
||||||
|
|
||||||
* Primary outputs:
|
|
||||||
U34 __new_OUT1_OVERFLW_REG U45 U36 U35 U44 __new_OUT1_OUTP_REG
|
|
||||||
|
|
||||||
|
|
||||||
* Test patterns and fault free responses:
|
|
||||||
|
|
||||||
1: 0000001 0000101
|
|
||||||
2: 0101100 0000010
|
|
||||||
3: 1100110 1010000
|
|
||||||
4: 1101100 0001100
|
|
||||||
5: 1100010 0010100
|
|
||||||
6: 0101110 0001100
|
|
||||||
7: 0001010 0011010
|
|
||||||
8: 0001000 0001010
|
|
||||||
9: 0010000 0100100
|
|
||||||
10: 0001100 0000000
|
|
||||||
11: 0000010 0001000
|
|
||||||
12: 0000100 0011000
|
|
||||||
13: 1000110 1000110
|
|
||||||
14: 0101000 0010100
|
|
||||||
15: 1001000 0010100
|
|
||||||
16: 1100000 0010000
|
|
@ -6,6 +6,7 @@ set(CMAKE_CXX_STANDARD 17)
|
|||||||
|
|
||||||
# 设置编译器优化选项
|
# 设置编译器优化选项
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Ofast -march=native -flto -static")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Ofast -march=native -flto -static")
|
||||||
|
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -static")
|
||||||
|
|
||||||
# 设置源文件和头文件的路径
|
# 设置源文件和头文件的路径
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR} SOURCES)
|
aux_source_directory(${PROJECT_SOURCE_DIR} SOURCES)
|
||||||
|
124
src/circuit.cpp
124
src/circuit.cpp
@ -23,6 +23,8 @@ void LUTCircuit::print() {
|
|||||||
}
|
}
|
||||||
printf(")\n");
|
printf(")\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for(LUT* lut : luts) {
|
for(LUT* lut : luts) {
|
||||||
|
|
||||||
printf("[v:%d vs:%d fd0:%d fd1:%d] ", lut->value, lut->vsat, lut->fd[0], lut->fd[1]);
|
printf("[v:%d vs:%d fd0:%d fd1:%d] ", lut->value, lut->vsat, lut->fd[0], lut->fd[1]);
|
||||||
@ -39,6 +41,10 @@ void LUTCircuit::print() {
|
|||||||
printf("total gate: %d\n", total_gate);
|
printf("total gate: %d\n", total_gate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LUTCircuit* Circuit::build_lut_circuit() {
|
LUTCircuit* Circuit::build_lut_circuit() {
|
||||||
|
|
||||||
LUTCircuit* C = new LUTCircuit();
|
LUTCircuit* C = new LUTCircuit();
|
||||||
@ -125,8 +131,10 @@ LUTCircuit* Circuit::build_lut_circuit() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for(LUT* lut : C->luts) {
|
for(LUT* lut : C->luts) {
|
||||||
for(Gate* g : lut->inner_gates) {
|
for(int i=0; i<lut->inner_gates.size(); i++) {
|
||||||
|
Gate *g = lut->inner_gates[i];
|
||||||
g->parent_lut = lut;
|
g->parent_lut = lut;
|
||||||
|
g->id_in_lut = lut->fanins.size() + i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,6 +153,77 @@ LUTCircuit* Circuit::build_lut_circuit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Circuit::insert_lines_for_stem() {
|
||||||
|
|
||||||
|
for(int j=0; j<gates.size(); j++) {
|
||||||
|
|
||||||
|
Gate* g = gates[j];
|
||||||
|
|
||||||
|
if(g->type == Gate::LINE) break;
|
||||||
|
|
||||||
|
g->is_stem = g->isPO ? g->fanouts.size() >= 1 : g->fanouts.size() >= 2;
|
||||||
|
if(!g->is_stem) continue;
|
||||||
|
|
||||||
|
if(g->isPO) {
|
||||||
|
Gate* line = new Gate();
|
||||||
|
line->name = g->name + "_line_PO";
|
||||||
|
line->type = Gate::LINE;
|
||||||
|
line->isPI = false;
|
||||||
|
line->isPO = true;
|
||||||
|
line->is_stem = false;
|
||||||
|
|
||||||
|
line->fanins.push_back(g);
|
||||||
|
g->fanouts.push_back(line);
|
||||||
|
|
||||||
|
g->isPO = false;
|
||||||
|
POs.erase(std::find(POs.begin(), POs.end(), g));
|
||||||
|
POs.push_back(line);
|
||||||
|
|
||||||
|
gates.push_back(line);
|
||||||
|
name2gate.insert(std::make_pair(line->name, line));
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(">>>> now: %s\n", g->name.c_str());
|
||||||
|
|
||||||
|
printf("outs: [ ");
|
||||||
|
for(Gate* out :g->fanouts){
|
||||||
|
printf("%s ", out->name.c_str());
|
||||||
|
}
|
||||||
|
printf("]\n");
|
||||||
|
|
||||||
|
for(int i=0; i<g->fanouts.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());
|
||||||
|
|
||||||
|
Gate* line = new Gate();
|
||||||
|
line->name = g->name + "_line_" + out->name;
|
||||||
|
line->type = Gate::LINE;
|
||||||
|
line->isPI = false;
|
||||||
|
line->isPO = false;
|
||||||
|
|
||||||
|
line->fanins.push_back(g);
|
||||||
|
line->fanouts.push_back(out);
|
||||||
|
|
||||||
|
out->fanins.erase(std::find(out->fanins.begin(), out->fanins.end(), g));
|
||||||
|
out->fanins.push_back(line);
|
||||||
|
|
||||||
|
g->fanouts.erase(std::find(g->fanouts.begin(), g->fanouts.end(), out));
|
||||||
|
g->fanouts.push_back(line);
|
||||||
|
|
||||||
|
gates.push_back(line);
|
||||||
|
name2gate.insert(std::make_pair(line->name, line));
|
||||||
|
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void Circuit::init_avg_dist() {
|
void Circuit::init_avg_dist() {
|
||||||
|
|
||||||
int *now_dist = new int[gates.size() + 1] { 0 };
|
int *now_dist = new int[gates.size() + 1] { 0 };
|
||||||
@ -152,6 +231,8 @@ void Circuit::init_avg_dist() {
|
|||||||
int *total_cnt = new int[gates.size() + 1] { 0 };
|
int *total_cnt = new int[gates.size() + 1] { 0 };
|
||||||
// int *topo_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) {
|
for(Gate* po : POs) {
|
||||||
// memset(topo_cnt, 0, sizeof(int) * (gates.size() + 1));
|
// memset(topo_cnt, 0, sizeof(int) * (gates.size() + 1));
|
||||||
// memset(now_dist, 0x3f, sizeof(int) * (gates.size() + 1));
|
// memset(now_dist, 0x3f, sizeof(int) * (gates.size() + 1));
|
||||||
@ -182,15 +263,24 @@ void Circuit::init_avg_dist() {
|
|||||||
q.push(in);
|
q.push(in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// printf("dist: %d\n", total_dist[name2gate["G132"]->id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Gate* g : gates) {
|
for(Gate* g : gates) {
|
||||||
// printf("gate: %s total: %d cnt: %d\n", g->name.c_str(), total_dist[g->id], total_cnt[g->id]);
|
|
||||||
|
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);
|
assert(total_cnt[g->id] > 0);
|
||||||
|
|
||||||
g->avg_dist = total_dist[g->id] / total_cnt[g->id];
|
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->id)
|
||||||
if(!g->isPO) assert(g->avg_dist > 0);
|
if(!g->isPO) assert(g->avg_dist > 0);
|
||||||
}
|
}
|
||||||
@ -255,4 +345,34 @@ void Circuit::init_topo_index() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::sort(gates.begin(), gates.end(), [](Gate* a, Gate* b) {
|
||||||
|
return a->id < b->id;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Circuit::print() {
|
||||||
|
|
||||||
|
printf("PIs: ( ");
|
||||||
|
for(Gate* gate : PIs) {
|
||||||
|
printf("%s ", gate->name.c_str());
|
||||||
|
}
|
||||||
|
printf(")\n");
|
||||||
|
|
||||||
|
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]);
|
||||||
|
for(Gate* in : g->fanins) {
|
||||||
|
printf("%s ", in->name.c_str());
|
||||||
|
}
|
||||||
|
printf(")\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("POs: ( ");
|
||||||
|
for(Gate* gate : POs) {
|
||||||
|
printf("%s ", gate->name.c_str());
|
||||||
|
}
|
||||||
|
printf(")\n");
|
||||||
|
}
|
@ -7,6 +7,32 @@ using ll = long long;
|
|||||||
|
|
||||||
namespace atpg_ls {
|
namespace atpg_ls {
|
||||||
|
|
||||||
|
struct TMP_FAULT {
|
||||||
|
/* data */
|
||||||
|
Gate *g;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
int stuck_at;
|
||||||
|
int is_stem;
|
||||||
|
int is_PO;
|
||||||
|
|
||||||
|
friend bool operator < (const TMP_FAULT &lhs, const TMP_FAULT &rhs) {
|
||||||
|
if(lhs.name != rhs.name) {
|
||||||
|
return lhs.name < rhs.name;
|
||||||
|
}
|
||||||
|
if(lhs.stuck_at != rhs.stuck_at) {
|
||||||
|
return lhs.stuck_at < rhs.stuck_at;
|
||||||
|
}
|
||||||
|
if(lhs.is_stem != rhs.is_stem) {
|
||||||
|
return lhs.is_stem < rhs.is_stem;
|
||||||
|
}
|
||||||
|
if(lhs.is_PO != rhs.is_PO) {
|
||||||
|
return lhs.is_PO < rhs.is_PO;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class Simulator;
|
class Simulator;
|
||||||
class Circuit;
|
class Circuit;
|
||||||
|
|
||||||
@ -50,6 +76,10 @@ std::vector<Gate*> rtopo_gates;
|
|||||||
std::unordered_map<std::string, Gate*> name2gate;
|
std::unordered_map<std::string, Gate*> name2gate;
|
||||||
|
|
||||||
void parse_from_file(const char *filename);
|
void parse_from_file(const char *filename);
|
||||||
|
void insert_lines_for_stem();
|
||||||
|
|
||||||
|
void print();
|
||||||
|
|
||||||
LUTCircuit* build_lut_circuit();
|
LUTCircuit* build_lut_circuit();
|
||||||
|
|
||||||
void init_topo_index();
|
void init_topo_index();
|
||||||
|
17
src/gate.cpp
17
src/gate.cpp
@ -14,6 +14,8 @@ int Gate::cal_propagate_len(bool x) {
|
|||||||
return fpl[x];
|
return fpl[x];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::queue<Gate*> q;
|
||||||
|
|
||||||
for(Gate* out : fanouts) {
|
for(Gate* out : fanouts) {
|
||||||
if(!out->is_detected(this)) continue;
|
if(!out->is_detected(this)) continue;
|
||||||
fpl[!value] = std::max(fpl[!value], out->fault_propagated_len[!out->value] + 1);
|
fpl[!value] = std::max(fpl[!value], out->fault_propagated_len[!out->value] + 1);
|
||||||
@ -66,6 +68,8 @@ int Gate::cal_value() {
|
|||||||
case NOT:
|
case NOT:
|
||||||
res = !fanins[0]->value;
|
res = !fanins[0]->value;
|
||||||
break;
|
break;
|
||||||
|
case LINE:
|
||||||
|
// pass through
|
||||||
case BUF:
|
case BUF:
|
||||||
res = fanins[0]->value;
|
res = fanins[0]->value;
|
||||||
break;
|
break;
|
||||||
@ -116,4 +120,17 @@ int Gate::cal_value() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Gate::lut_get_value() {
|
||||||
|
return parent_lut->fault_table[id_in_lut][parent_lut->input_var<<1|parent_lut->value].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Gate::lut_get_fault(int *fd, int *fpl) {
|
||||||
|
LUT::FaultInfo &info = parent_lut->fault_table[id_in_lut][parent_lut->input_var<<1|parent_lut->value];
|
||||||
|
fd[0] = info.fd[0] && parent_lut->fd[!parent_lut->value];
|
||||||
|
fd[1] = info.fd[1] && parent_lut->fd[!parent_lut->value];
|
||||||
|
fpl[0] = info.fpl[0] + info.fd[0] * parent_lut->fpl[!parent_lut->value];
|
||||||
|
fpl[1] = info.fpl[1] + info.fd[1] * parent_lut->fpl[!parent_lut->value];
|
||||||
}
|
}
|
@ -21,7 +21,7 @@ public:
|
|||||||
int level;
|
int level;
|
||||||
int rtopo;
|
int rtopo;
|
||||||
std::string name;
|
std::string name;
|
||||||
enum Type { AND, NAND, OR, NOR, XOR, XNOR, NOT, BUF, INPUT } type;
|
enum Type { AND, NAND, OR, NOR, XOR, XNOR, NOT, BUF, INPUT, LINE } type;
|
||||||
int value;
|
int value;
|
||||||
bool isPI;
|
bool isPI;
|
||||||
bool isPO;
|
bool isPO;
|
||||||
@ -50,7 +50,11 @@ public:
|
|||||||
LUT* parent_lut;
|
LUT* parent_lut;
|
||||||
int id_in_lut;
|
int id_in_lut;
|
||||||
|
|
||||||
|
int is_stem;
|
||||||
|
|
||||||
|
int lut_get_value();
|
||||||
|
void lut_get_fault(int *fd, int *fpl);
|
||||||
|
|
||||||
// ( partical ) score
|
// ( partical ) score
|
||||||
|
|
||||||
// score(x) = for y in neibor(x) { ~V_x,V_y make - ~V_x,V_y break }
|
// score(x) = for y in neibor(x) { ~V_x,V_y make - ~V_x,V_y break }
|
||||||
|
128
src/ls.cpp
128
src/ls.cpp
@ -146,27 +146,105 @@ void LUTCircuit::ls_main() {
|
|||||||
num_total_fault = num_undetected_fault = num_gates * 2;
|
num_total_fault = num_undetected_fault = num_gates * 2;
|
||||||
|
|
||||||
printf("staring local search ...\n");
|
printf("staring local search ...\n");
|
||||||
|
|
||||||
|
std::queue<TMP_FAULT> faults;
|
||||||
|
|
||||||
std::queue<std::pair<Gate*, int>> faults;
|
for(Gate* g : C->gates) {
|
||||||
for(LUT* lut : luts) {
|
|
||||||
for(Gate* g : lut->inner_gates) {
|
std::string name = g->name;
|
||||||
if(g->fanouts.size() == 1 && (g->fanouts[0]->type == Gate::Type::BUF || g->fanouts[0]->type == Gate::Type::NOT)) {
|
// if(name.find("_") != std::string::npos) {
|
||||||
printf("sat delete: %s\n", g->name.c_str());
|
// name = name.substr(0, name.find("_"));
|
||||||
|
// }
|
||||||
|
|
||||||
|
if(g->is_stem) {
|
||||||
|
printf("stem: %s\n", name.c_str());
|
||||||
|
faults.push(TMP_FAULT{g, name, 0, 1, 0});
|
||||||
|
faults.push(TMP_FAULT{g, name, 1, 1, 0});
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if(g->isPO) {
|
||||||
|
printf("out: %s\n", name.c_str());
|
||||||
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
faults.push(std::make_pair(g, 0));
|
|
||||||
faults.push(std::make_pair(g, 1));
|
assert(g->fanouts.size() == 1);
|
||||||
|
Gate *fanout = g->fanouts[0];
|
||||||
|
|
||||||
|
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(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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("fault-size: %d\n", faults.size());
|
||||||
|
|
||||||
|
std::vector<TMP_FAULT> t_faults;
|
||||||
|
std::set<TMP_FAULT> t_verify_set;
|
||||||
|
|
||||||
|
while(!faults.empty()) {
|
||||||
|
TMP_FAULT f = faults.front();
|
||||||
|
faults.pop();
|
||||||
|
|
||||||
|
assert(t_verify_set.count(f) == 0);
|
||||||
|
|
||||||
|
t_faults.push_back(f);
|
||||||
|
t_verify_set.insert(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(TMP_FAULT &f : t_faults) {
|
||||||
|
faults.push(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// std::sort(t_faults.begin(), t_faults.end(), [](const TMP_FAULT &a, const TMP_FAULT &b) {
|
||||||
|
// int ta = std::atoi(a.g->name.substr(1).c_str());
|
||||||
|
// int tb = std::atoi(b.g->name.substr(1).c_str());
|
||||||
|
// return ta < tb;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// for(auto &f : t_faults) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
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(TMP_FAULT &f : t_faults) {
|
||||||
|
|
||||||
|
// printf("!! Fault: %s stuck-at: %d is_stem: %d is_po: %d\n", f.g->name.c_str(), f.stuck_at, f.is_stem, f.is_PO);
|
||||||
|
|
||||||
|
// std::vector<int> input_vector;
|
||||||
|
// bool detected = sat_atpg(f, input_vector);
|
||||||
|
|
||||||
|
// printf(">> Fault: %s stuck-at: %d is_stem: %d is_po: %d detected: %d\n", f.g->name.c_str(), f.stuck_at, f.is_stem, f.is_PO, detected);
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// exit(0);
|
||||||
|
|
||||||
auto start = std::chrono::high_resolution_clock::now();
|
auto start = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
// int cnt = 0;
|
||||||
|
|
||||||
while(!faults.empty()) {
|
while(!faults.empty()) {
|
||||||
|
|
||||||
while(!faults.empty()) {
|
while(!faults.empty()) {
|
||||||
auto [g, stuck_at] = faults.front();
|
TMP_FAULT f = faults.front();
|
||||||
if(fault_detected[g->id-1][stuck_at]) {
|
if(fault_detected[f.g->id-1][f.stuck_at]) {
|
||||||
faults.pop();
|
faults.pop();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -176,14 +254,17 @@ void LUTCircuit::ls_main() {
|
|||||||
|
|
||||||
ls_random_sol();
|
ls_random_sol();
|
||||||
|
|
||||||
auto [g, stuck_at] = faults.front(); faults.pop();
|
TMP_FAULT f = faults.front(); faults.pop();
|
||||||
|
Gate* g = f.g;
|
||||||
|
int stuck_at = f.stuck_at;
|
||||||
|
|
||||||
printf("start with fault: %s SA%d\t", g->name.c_str(), stuck_at);
|
printf("start with fault: %s SA%d\t", g->name.c_str(), stuck_at);
|
||||||
|
|
||||||
std::vector<int> inputs;
|
std::vector<int> inputs;
|
||||||
|
|
||||||
printf("verify ...");
|
printf("verify ...");
|
||||||
|
|
||||||
int res1 = sat_atpg(g->name.c_str(), stuck_at, inputs);
|
int res1 = sat_atpg(f, inputs);
|
||||||
|
|
||||||
if(res1 == 0) {
|
if(res1 == 0) {
|
||||||
printf(" unsat!\n");
|
printf(" unsat!\n");
|
||||||
@ -196,13 +277,24 @@ void LUTCircuit::ls_main() {
|
|||||||
PIs[i]->value = inputs[i];
|
PIs[i]->value = inputs[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("sim: %s %d\n", g->name.c_str(), stuck_at);
|
||||||
|
for(int i=0; i<inputs.size(); i++) {
|
||||||
|
printf("%d ", inputs[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
int score;
|
int score;
|
||||||
simulator->simulate(PIs, score, fault_detected);
|
simulator->simulate(PIs, score, fault_detected);
|
||||||
|
|
||||||
|
if(g->name == "G6") {
|
||||||
|
simulator->print();
|
||||||
|
}
|
||||||
|
|
||||||
if(simulator->name2gate[g->name]->fault_detected[stuck_at]) {
|
if(simulator->name2gate[g->name]->fault_detected[stuck_at]) {
|
||||||
printf(" successful!\n");
|
printf(" successful!\n");
|
||||||
} else {
|
} else {
|
||||||
printf(" failed!\n");
|
printf(" failed!\n");
|
||||||
|
// exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(LUT* lut : luts) {
|
for(LUT* lut : luts) {
|
||||||
@ -218,7 +310,8 @@ void LUTCircuit::ls_main() {
|
|||||||
int res = simulator->verify(this, fault_detected);
|
int res = simulator->verify(this, fault_detected);
|
||||||
assert(res == 1);
|
assert(res == 1);
|
||||||
|
|
||||||
assert(simulator->name2gate[g->name]->fault_detected[stuck_at]);
|
// printf("g: %s\n", g->name.c_str());
|
||||||
|
// assert(simulator->name2gate[g->name]->fault_detected[stuck_at]);
|
||||||
|
|
||||||
int num_fault = 0;
|
int num_fault = 0;
|
||||||
|
|
||||||
@ -244,7 +337,8 @@ void LUTCircuit::ls_main() {
|
|||||||
|
|
||||||
auto end = std::chrono::high_resolution_clock::now();
|
auto end = std::chrono::high_resolution_clock::now();
|
||||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(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)num_detected_fault / num_total_fault * 100, num_pattern, num_fault, num_undetected_fault, (double)duration/1000);
|
||||||
|
|
||||||
// break;
|
// break;
|
||||||
@ -277,6 +371,8 @@ void LUTCircuit::ls_gen_sol(Gate* target, int stuck_at) {
|
|||||||
// printf("dert_fault_propagated_weight: %.2f\n", pick->score_fault_propagated_weight);
|
// printf("dert_fault_propagated_weight: %.2f\n", pick->score_fault_propagated_weight);
|
||||||
// printf("dert_up_cost: %.2f\n", pick->score_fault_update_cost);
|
// printf("dert_up_cost: %.2f\n", pick->score_fault_update_cost);
|
||||||
|
|
||||||
|
int last = simulator->name2gate[target->name]->fault_detected[stuck_at];
|
||||||
|
|
||||||
ls_flip(pick);
|
ls_flip(pick);
|
||||||
|
|
||||||
// double t2 = check();
|
// double t2 = check();
|
||||||
@ -285,8 +381,9 @@ void LUTCircuit::ls_gen_sol(Gate* target, int stuck_at) {
|
|||||||
if(pick->isPI) {
|
if(pick->isPI) {
|
||||||
int score;
|
int score;
|
||||||
simulator->simulate(PIs, score, fault_detected);
|
simulator->simulate(PIs, score, fault_detected);
|
||||||
if(!simulator->name2gate[target->name]->fault_detected[stuck_at]) {
|
if(simulator->name2gate[target->name]->fault_detected[stuck_at] != last) {
|
||||||
ls_flip(pick);
|
ls_flip(pick);
|
||||||
|
pick->CC = 0;
|
||||||
}
|
}
|
||||||
// printf("step: %d fd: %d\n", step, score);
|
// printf("step: %d fd: %d\n", step, score);
|
||||||
}
|
}
|
||||||
@ -360,7 +457,6 @@ void LUTCircuit::ls_random_sol() {
|
|||||||
lut->vunat_cost = OPT(vsat_inc) * 100;
|
lut->vunat_cost = OPT(vsat_inc) * 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
lut->is_good_var = 0;
|
|
||||||
lut->CC = 1;
|
lut->CC = 1;
|
||||||
for(Gate* g : lut->inner_gates) {
|
for(Gate* g : lut->inner_gates) {
|
||||||
|
|
||||||
|
40
src/lut.cpp
40
src/lut.cpp
@ -12,7 +12,7 @@ void LUT::flip_value() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LUT::cal_fault_info(int *fd, int* fpl, int test) {
|
void LUT::cal_fault_info(int *fd, int* fpl) {
|
||||||
|
|
||||||
fd[0] = fd[1] = fpl[0] = fpl[1] = 0;
|
fd[0] = fd[1] = fpl[0] = fpl[1] = 0;
|
||||||
if(isPO) {
|
if(isPO) {
|
||||||
@ -22,7 +22,7 @@ void LUT::cal_fault_info(int *fd, int* fpl, int test) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(auto&[out, id] : fanouts_with_id) {
|
for(auto&[out, id] : fanouts_with_id) {
|
||||||
// if(!out->vsat) continue;
|
if(!out->vsat) continue;
|
||||||
|
|
||||||
FaultInfo &info = out->fault_table[id][out->input_var << 1 | out->value];
|
FaultInfo &info = out->fault_table[id][out->input_var << 1 | out->value];
|
||||||
|
|
||||||
@ -39,14 +39,36 @@ void LUT::cal_fault_info(int *fd, int* fpl, int test) {
|
|||||||
|
|
||||||
fpl[0] = std::max(fpl[0], t_fpl[0]);
|
fpl[0] = std::max(fpl[0], t_fpl[0]);
|
||||||
fpl[1] = std::max(fpl[1], t_fpl[1]);
|
fpl[1] = std::max(fpl[1], t_fpl[1]);
|
||||||
|
|
||||||
// if(test) {
|
|
||||||
// assert(out->value_table[out->input_var] == out->value);
|
|
||||||
// printf("recal: %s out: %s [fd0:%d fd1:%d fpl0:%d fpl1:%d] [ifd_0:%d ifd_1:%d ifpl0:%d ifpl1:%d]\n", name, out->name,
|
|
||||||
// out->fd[0], out->fd[1], out->fpl[0], out->fpl[1]
|
|
||||||
// , info.fd[0], info.fd[1], info.fpl[0], info.fpl[1]);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// std::vector<Gate*> reigon;
|
||||||
|
|
||||||
|
// std::priority_queue<std::pair<Gate*, int>, std::vector<std::pair<Gate*, int>>,
|
||||||
|
// std::function<bool(const std::pair<Gate*, int>&, const std::pair<Gate*, int>&)>> pq([](const std::pair<Gate*, int>& p1, const std::pair<Gate*, int>& 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() {
|
int LUT::cal_value() {
|
||||||
|
@ -50,17 +50,18 @@ public:
|
|||||||
void init_lookup_table();
|
void init_lookup_table();
|
||||||
|
|
||||||
// local search
|
// local search
|
||||||
|
|
||||||
bool vsat;
|
bool vsat;
|
||||||
int vunat_cost;
|
int vunat_cost;
|
||||||
bool uptag;
|
bool uptag;
|
||||||
int up_cost;
|
int up_cost;
|
||||||
int fd[2];
|
int fd[2];
|
||||||
int fpl[2];
|
int fpl[2];
|
||||||
int is_good_var;
|
// int is_good_var;
|
||||||
int CC;
|
int CC;
|
||||||
|
|
||||||
int cal_value();
|
int cal_value();
|
||||||
void cal_fault_info(int *t_fd, int *t_fpl, int test = 0);
|
void cal_fault_info(int *t_fd, int *t_fpl);
|
||||||
void get_fault_info(Gate *gate, int *t_fd, int *t_fpl);
|
void get_fault_info(Gate *gate, int *t_fd, int *t_fpl);
|
||||||
|
|
||||||
// score
|
// score
|
||||||
|
25
src/main.cpp
25
src/main.cpp
@ -13,16 +13,41 @@ int main(int argc, char *argv[]) {
|
|||||||
srand(OPT(seed));
|
srand(OPT(seed));
|
||||||
|
|
||||||
Circuit *circuit = new Circuit();
|
Circuit *circuit = new Circuit();
|
||||||
|
|
||||||
Simulator* simulator = new Simulator();
|
Simulator* simulator = new Simulator();
|
||||||
|
|
||||||
printf("parsing file %s ...\n", OPT(instance).c_str());
|
printf("parsing file %s ...\n", OPT(instance).c_str());
|
||||||
circuit->parse_from_file(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->parse_from_file(OPT(instance).c_str());
|
||||||
|
simulator->insert_lines_for_stem();
|
||||||
|
|
||||||
circuit->init_topo_index();
|
circuit->init_topo_index();
|
||||||
simulator->init_topo_index();
|
simulator->init_topo_index();
|
||||||
|
|
||||||
|
|
||||||
circuit->init_avg_dist();
|
circuit->init_avg_dist();
|
||||||
|
|
||||||
|
circuit->print();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* D算法/电路 - 200000F = 时间优势好 (123) -> F -> (5,6)
|
||||||
|
* SAT - 200000F * avg(N) (1011) (1010)
|
||||||
|
*
|
||||||
|
* primary input 电路的输入
|
||||||
|
* gate input 单个门的输入
|
||||||
|
*
|
||||||
|
* (F0)
|
||||||
|
* PIs assignment (10101010101010) -> (F0)
|
||||||
|
*
|
||||||
|
* (10101010101010) inital sol
|
||||||
|
* LOCAL + F0
|
||||||
|
*
|
||||||
|
* (SAT + LS)
|
||||||
|
**/
|
||||||
sat_atpg_init(OPT(instance).c_str());
|
sat_atpg_init(OPT(instance).c_str());
|
||||||
|
|
||||||
// circuit->
|
// circuit->
|
||||||
|
|
||||||
printf("building lut circuit ...\n");
|
printf("building lut circuit ...\n");
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
CircuitGraph *graph;
|
CircuitGraph *graph;
|
||||||
Iscas89Parser *parser;
|
Iscas89Parser *parser;
|
||||||
FaultManager *fault_manager;
|
FaultManager *fault_manager;
|
||||||
@ -24,16 +23,13 @@ FaultCnfMaker *fault_cnf_maker;
|
|||||||
std::unique_ptr<SatSolver> solver;
|
std::unique_ptr<SatSolver> solver;
|
||||||
ProxyCnf *proxy;
|
ProxyCnf *proxy;
|
||||||
|
|
||||||
std::map<std::string, Fault> fault_map;
|
std::map<TMP_FAULT, Fault> fault_map;
|
||||||
|
|
||||||
bool sat_atpg(const char* name, int stuck_at, std::vector<int> &input_vector) {
|
bool sat_atpg(const TMP_FAULT &fal, std::vector<int> &input_vector) {
|
||||||
|
|
||||||
if(fault_map.count(std::string(name)) == 0) {
|
assert(fault_map.count(fal) != 0);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Fault f = fault_map[std::string(name)];
|
Fault f = fault_map[fal];
|
||||||
f.stuck_at = stuck_at;
|
|
||||||
|
|
||||||
fault_cnf_maker->make_fault(f, *proxy);
|
fault_cnf_maker->make_fault(f, *proxy);
|
||||||
|
|
||||||
@ -85,22 +81,42 @@ void sat_atpg_init(const char* file) {
|
|||||||
|
|
||||||
proxy = new ProxyCnf(*solver);
|
proxy = new ProxyCnf(*solver);
|
||||||
|
|
||||||
|
int sz = 0;
|
||||||
|
|
||||||
while(fault_manager->has_faults_left()) {
|
while(fault_manager->has_faults_left()) {
|
||||||
Fault f = fault_manager->next_fault();
|
Fault f = fault_manager->next_fault();
|
||||||
|
|
||||||
// printf("Fault: %s stuck-at: %d is_stem: %d is_po: %d\n", f.line->name.c_str(), f.stuck_at, f.is_stem, f.is_primary_output);
|
sz++;
|
||||||
|
|
||||||
if(f.is_stem) {
|
if(f.is_stem || (f.line->source == nullptr && f.line->destinations.size() == 1)) {
|
||||||
if(fault_map.count(f.line->name)) {
|
|
||||||
Fault& g = fault_map[f.line->name];
|
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());
|
||||||
f.stuck_at = g.stuck_at;
|
TMP_FAULT tf = TMP_FAULT{nullptr, f.line->name, f.stuck_at, f.is_stem, f.is_primary_output};
|
||||||
assert(f == g);
|
assert(fault_map.count(tf) == 0);
|
||||||
|
fault_map[tf] = f;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
if(f.is_primary_output) {
|
||||||
|
name = f.line->name + "_line_PO";
|
||||||
} else {
|
} else {
|
||||||
printf(">> Fault: %s stuck-at: %d is_stem: %d is_po: %d\n", f.line->name.c_str(), f.stuck_at, f.is_stem, f.is_primary_output);
|
name = f.line->name + "_line_" + f.connection.gate->get_output()->name;
|
||||||
fault_map[f.line->name] = f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
fault_map[tf] = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// printf(">> Fault: %s stuck-at: %d is_stem: %d is_po: %d\n", f.line->name.c_str(), f.stuck_at, f.is_stem, f.is_primary_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("tg-pro fault-size: %d table-size: %d\n", sz, fault_map.size());
|
||||||
|
|
||||||
|
assert(sz == fault_map.size());
|
||||||
// exit(0);
|
// exit(0);
|
||||||
}
|
}
|
@ -2,5 +2,7 @@
|
|||||||
|
|
||||||
#include "circuit.h"
|
#include "circuit.h"
|
||||||
|
|
||||||
bool sat_atpg(const char* name, int stuck_at, std::vector<int> &input_vector);
|
using atpg_ls::TMP_FAULT;
|
||||||
|
|
||||||
|
bool sat_atpg(const TMP_FAULT &fal, std::vector<int> &input_vector);
|
||||||
void sat_atpg_init(const char* file);
|
void sat_atpg_init(const char* file);
|
@ -18,7 +18,7 @@ int Simulator::verify(LUTCircuit *lut_circuit, int** fault_detected) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(LUT* lut : lut_circuit->rtopo_luts) {
|
for(LUT* lut : lut_circuit->rtopo_luts) {
|
||||||
lut->cal_fault_info(lut->fd, lut->fpl, 1);
|
lut->cal_fault_info(lut->fd, lut->fpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
// lut_circuit->print();
|
// lut_circuit->print();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user