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} -O0 -g -static")
|
||||
|
||||
# 设置源文件和头文件的路径
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR} SOURCES)
|
||||
|
124
src/circuit.cpp
124
src/circuit.cpp
@ -23,6 +23,8 @@ void LUTCircuit::print() {
|
||||
}
|
||||
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]);
|
||||
@ -39,6 +41,10 @@ void LUTCircuit::print() {
|
||||
printf("total gate: %d\n", total_gate);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LUTCircuit* Circuit::build_lut_circuit() {
|
||||
|
||||
LUTCircuit* C = new LUTCircuit();
|
||||
@ -125,8 +131,10 @@ LUTCircuit* Circuit::build_lut_circuit() {
|
||||
});
|
||||
|
||||
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->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() {
|
||||
|
||||
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 *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));
|
||||
@ -182,15 +263,24 @@ void Circuit::init_avg_dist() {
|
||||
q.push(in);
|
||||
}
|
||||
}
|
||||
|
||||
// printf("dist: %d\n", total_dist[name2gate["G132"]->id]);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
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 Circuit;
|
||||
|
||||
@ -50,6 +76,10 @@ std::vector<Gate*> rtopo_gates;
|
||||
std::unordered_map<std::string, Gate*> name2gate;
|
||||
|
||||
void parse_from_file(const char *filename);
|
||||
void insert_lines_for_stem();
|
||||
|
||||
void print();
|
||||
|
||||
LUTCircuit* build_lut_circuit();
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
std::queue<Gate*> q;
|
||||
|
||||
for(Gate* out : fanouts) {
|
||||
if(!out->is_detected(this)) continue;
|
||||
fpl[!value] = std::max(fpl[!value], out->fault_propagated_len[!out->value] + 1);
|
||||
@ -66,6 +68,8 @@ int Gate::cal_value() {
|
||||
case NOT:
|
||||
res = !fanins[0]->value;
|
||||
break;
|
||||
case LINE:
|
||||
// pass through
|
||||
case BUF:
|
||||
res = fanins[0]->value;
|
||||
break;
|
||||
@ -116,4 +120,17 @@ int Gate::cal_value() {
|
||||
break;
|
||||
}
|
||||
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 rtopo;
|
||||
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;
|
||||
bool isPI;
|
||||
bool isPO;
|
||||
@ -50,7 +50,11 @@ public:
|
||||
LUT* parent_lut;
|
||||
int id_in_lut;
|
||||
|
||||
int is_stem;
|
||||
|
||||
int lut_get_value();
|
||||
void lut_get_fault(int *fd, int *fpl);
|
||||
|
||||
// ( partical ) score
|
||||
|
||||
// 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;
|
||||
|
||||
printf("staring local search ...\n");
|
||||
|
||||
std::queue<TMP_FAULT> faults;
|
||||
|
||||
std::queue<std::pair<Gate*, int>> faults;
|
||||
for(LUT* lut : luts) {
|
||||
for(Gate* g : lut->inner_gates) {
|
||||
if(g->fanouts.size() == 1 && (g->fanouts[0]->type == Gate::Type::BUF || g->fanouts[0]->type == Gate::Type::NOT)) {
|
||||
printf("sat delete: %s\n", g->name.c_str());
|
||||
for(Gate* g : C->gates) {
|
||||
|
||||
std::string name = g->name;
|
||||
// if(name.find("_") != std::string::npos) {
|
||||
// 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;
|
||||
}
|
||||
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();
|
||||
|
||||
// int cnt = 0;
|
||||
|
||||
while(!faults.empty()) {
|
||||
|
||||
while(!faults.empty()) {
|
||||
auto [g, stuck_at] = faults.front();
|
||||
if(fault_detected[g->id-1][stuck_at]) {
|
||||
faults.pop();
|
||||
TMP_FAULT f = faults.front();
|
||||
if(fault_detected[f.g->id-1][f.stuck_at]) {
|
||||
faults.pop();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -176,14 +254,17 @@ void LUTCircuit::ls_main() {
|
||||
|
||||
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);
|
||||
|
||||
std::vector<int> inputs;
|
||||
|
||||
printf("verify ...");
|
||||
|
||||
int res1 = sat_atpg(g->name.c_str(), stuck_at, inputs);
|
||||
int res1 = sat_atpg(f, inputs);
|
||||
|
||||
if(res1 == 0) {
|
||||
printf(" unsat!\n");
|
||||
@ -196,13 +277,24 @@ void LUTCircuit::ls_main() {
|
||||
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;
|
||||
simulator->simulate(PIs, score, fault_detected);
|
||||
|
||||
if(g->name == "G6") {
|
||||
simulator->print();
|
||||
}
|
||||
|
||||
if(simulator->name2gate[g->name]->fault_detected[stuck_at]) {
|
||||
printf(" successful!\n");
|
||||
} else {
|
||||
printf(" failed!\n");
|
||||
// exit(-1);
|
||||
}
|
||||
|
||||
for(LUT* lut : luts) {
|
||||
@ -218,7 +310,8 @@ void LUTCircuit::ls_main() {
|
||||
int res = simulator->verify(this, fault_detected);
|
||||
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;
|
||||
|
||||
@ -244,7 +337,8 @@ void LUTCircuit::ls_main() {
|
||||
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
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);
|
||||
|
||||
// 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_up_cost: %.2f\n", pick->score_fault_update_cost);
|
||||
|
||||
int last = simulator->name2gate[target->name]->fault_detected[stuck_at];
|
||||
|
||||
ls_flip(pick);
|
||||
|
||||
// double t2 = check();
|
||||
@ -285,8 +381,9 @@ void LUTCircuit::ls_gen_sol(Gate* target, int stuck_at) {
|
||||
if(pick->isPI) {
|
||||
int score;
|
||||
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);
|
||||
pick->CC = 0;
|
||||
}
|
||||
// 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->is_good_var = 0;
|
||||
lut->CC = 1;
|
||||
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;
|
||||
if(isPO) {
|
||||
@ -22,7 +22,7 @@ void LUT::cal_fault_info(int *fd, int* fpl, int test) {
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
@ -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[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() {
|
||||
|
@ -50,17 +50,18 @@ public:
|
||||
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 is_good_var;
|
||||
int CC;
|
||||
|
||||
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);
|
||||
|
||||
// score
|
||||
|
25
src/main.cpp
25
src/main.cpp
@ -13,16 +13,41 @@ int main(int argc, char *argv[]) {
|
||||
srand(OPT(seed));
|
||||
|
||||
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());
|
||||
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->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());
|
||||
|
||||
// circuit->
|
||||
|
||||
printf("building lut circuit ...\n");
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
|
||||
CircuitGraph *graph;
|
||||
Iscas89Parser *parser;
|
||||
FaultManager *fault_manager;
|
||||
@ -24,16 +23,13 @@ FaultCnfMaker *fault_cnf_maker;
|
||||
std::unique_ptr<SatSolver> solver;
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
assert(fault_map.count(fal) != 0);
|
||||
|
||||
Fault f = fault_map[std::string(name)];
|
||||
f.stuck_at = stuck_at;
|
||||
Fault f = fault_map[fal];
|
||||
|
||||
fault_cnf_maker->make_fault(f, *proxy);
|
||||
|
||||
@ -85,22 +81,42 @@ void sat_atpg_init(const char* file) {
|
||||
|
||||
proxy = new ProxyCnf(*solver);
|
||||
|
||||
int sz = 0;
|
||||
|
||||
while(fault_manager->has_faults_left()) {
|
||||
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(fault_map.count(f.line->name)) {
|
||||
Fault& g = fault_map[f.line->name];
|
||||
f.stuck_at = g.stuck_at;
|
||||
assert(f == g);
|
||||
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());
|
||||
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;
|
||||
|
||||
} else {
|
||||
|
||||
std::string name;
|
||||
|
||||
if(f.is_primary_output) {
|
||||
name = f.line->name + "_line_PO";
|
||||
} 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);
|
||||
fault_map[f.line->name] = f;
|
||||
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());
|
||||
|
||||
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);
|
||||
}
|
@ -2,5 +2,7 @@
|
||||
|
||||
#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);
|
@ -18,7 +18,7 @@ int Simulator::verify(LUTCircuit *lut_circuit, int** fault_detected) {
|
||||
}
|
||||
|
||||
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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user