This commit is contained in:
YuhangQ 2023-11-11 04:20:22 +00:00
parent 7a9f51f50e
commit 9fdc584fe6
66 changed files with 1776 additions and 1276 deletions

0
.gitignore vendored Normal file → Executable file
View File

0
.vscode/c_cpp_properties.json vendored Normal file → Executable file
View File

0
.vscode/launch.json vendored Normal file → Executable file
View File

3
.vscode/settings.json vendored Normal file → Executable file
View File

@ -90,6 +90,7 @@
"csignal": "cpp",
"strstream": "cpp",
"codecvt": "cpp",
"cfenv": "cpp"
"cfenv": "cpp",
"*.ipp": "cpp"
}
}

0
.vscode/tasks.json vendored Normal file → Executable file
View File

0
CMakeLists.txt Normal file → Executable file
View File

0
README.md Normal file → Executable file
View File

0
benchmark/b01.bench Normal file → Executable file
View File

0
benchmark/b03.bench Normal file → Executable file
View File

0
benchmark/b04.bench Normal file → Executable file
View File

0
benchmark/b06.bench Normal file → Executable file
View File

0
benchmark/b07.bench Normal file → Executable file
View File

0
benchmark/b08.bench Normal file → Executable file
View File

0
benchmark/b09.bench Normal file → Executable file
View File

0
benchmark/b10.bench Normal file → Executable file
View File

0
benchmark/b11.bench Normal file → Executable file
View File

0
benchmark/b12.bench Normal file → Executable file
View File

0
benchmark/b13.bench Normal file → Executable file
View File

0
benchmark/b17.bench Normal file → Executable file
View File

0
benchmark/b20.bench Normal file → Executable file
View File

0
benchmark/b21.bench Normal file → Executable file
View File

0
benchmark/b22.bench Normal file → Executable file
View File

0
benchmark/c1355.bench Normal file → Executable file
View File

0
benchmark/c17.bench Normal file → Executable file
View File

0
benchmark/c1908.bench Normal file → Executable file
View File

0
benchmark/c2670.bench Normal file → Executable file
View File

0
benchmark/c3540.bench Normal file → Executable file
View File

0
benchmark/c432.bench Normal file → Executable file
View File

0
benchmark/c499.bench Normal file → Executable file
View File

0
benchmark/c5315.bench Normal file → Executable file
View File

0
benchmark/c6288.bench Normal file → Executable file
View File

0
benchmark/c7552.bench Normal file → Executable file
View File

0
benchmark/c880.bench Normal file → Executable file
View File

0
report/atalanta_b10000_iscas85.txt Normal file → Executable file
View File

0
report/atalanta_b1000_itc99.txt Normal file → Executable file
View File

0
report/atalanta_b20_itc99.txt Normal file → Executable file
View File

0
report/atalanta_itc99.txt Normal file → Executable file
View File

0
report/atpg-ls-动态增量-仿真.txt Normal file → Executable file
View File

0
report/atpg-ls-动态增量.txt Normal file → Executable file
View File

0
report/atpg-ls.txt Normal file → Executable file
View File

0
report/tgpro_iscas85.txt Normal file → Executable file
View File

0
report/tgpro_itc99.txt Normal file → Executable file
View File

0
report/tgpro_itc99_cutoff1000.txt Normal file → Executable file
View File

0
src/CMakeLists.txt Normal file → Executable file
View File

16
src/checker.cpp Normal file → Executable file
View File

@ -8,7 +8,7 @@ namespace atpg_ls {
Circuit *right_circuit;
Circuit *wrong_circuit;
int check_fault(const Pattern &p, const TMP_FAULT &f) {
int check_fault(const Pattern &p, const Fault &f) {
for(int i=0; i<p.input_vector.size(); i++) {
right_circuit->PIs[i]->value = p.input_vector[i];
wrong_circuit->PIs[i]->value = p.input_vector[i];
@ -19,7 +19,7 @@ int check_fault(const Pattern &p, const TMP_FAULT &f) {
}
for(Gate* gate : wrong_circuit->gates) {
if(gate->name == f.g->name) {
if(gate->name == f.gate->name) {
gate->value = f.stuck_at;
continue;
}
@ -34,14 +34,14 @@ int check_fault(const Pattern &p, const TMP_FAULT &f) {
return false;
}
int final_check(const std::set<TMP_FAULT> &faults, const std::vector<Pattern> &patterns) {
int final_check(const std::set<Fault> &faults, const std::vector<Pattern> &patterns) {
std::set<TMP_FAULT> detected_faults;
std::set<Fault> detected_faults;
for(auto &p : patterns) {
for(auto &f : p.detected_faults) {
printf("checking fault %s %d ... ", f.g->name.c_str(), f.stuck_at);
// printf("checking fault %s %d ... ", f.g->name.c_str(), f.stuck_at);
assert(faults.count(f));
assert(detected_faults.count(f) == 0);
@ -56,16 +56,16 @@ int final_check(const std::set<TMP_FAULT> &faults, const std::vector<Pattern> &p
int detected = check_fault(p, f);
if(detected) {
printf("detected\n");
// printf("detected\n");
detected_faults.insert(f);
} else {
printf("undetected\n");
// printf("undetected\n");
assert(false);
}
}
}
printf("final coverage: %d/%d(%.2f) pattern: %d\n", detected_faults.size(), faults.size(), (double)detected_faults.size()/faults.size(), patterns.size());
printf("final coverage: (%.2f)%d/%d pattern: %d\n", (double)detected_faults.size()/faults.size() * 100,detected_faults.size(), faults.size(), , patterns.size());
return 1;
}

4
src/checker.h Normal file → Executable file
View File

@ -8,8 +8,8 @@
namespace atpg_ls {
int check_fault(const Pattern &p, const TMP_FAULT &f);
int final_check(const std::set<TMP_FAULT> &faults, const std::vector<Pattern> &patterns);
int check_fault(const Pattern &p, const Fault &f);
int final_check(const std::set<Fault> &faults, const std::vector<Pattern> &patterns);
void init_final_checker();
};

500
src/circuit.cpp Normal file → Executable file
View File

@ -1,159 +1,230 @@
#include <set>
#include <assert.h>
#include <unordered_map>
#include "circuit.h"
#include "simulator.h"
#include "paras.h"
using namespace atpg_ls;
void LUTCircuit::print() {
std::set<Gate*> st;
int total_gate = 0;
printf("PIs: ( ");
for(LUT* lut : PIs) {
printf("%s ", lut->gate->name.c_str());
}
printf(")\n");
printf("POs: ( ");
for(LUT* lut : POs) {
printf("%s ", lut->gate->name.c_str());
}
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]);
printf("lut: %s inputs: ( ", lut->gate->name.c_str());
total_gate += lut->inner_gates.size();
for(LUT* in : lut->fanins) {
printf("%s ", in->gate->name.c_str());
}
printf(")\n");
}
printf("total gate: %d\n", total_gate);
std::string gen_name() {
static int i = 0;
return "E" + std::to_string(++i);
}
Gate* create_not_gate(Gate* gate) {
Gate* not_gate = new Gate();
not_gate->name = gen_name();
not_gate->is_extra_gate = 1;
not_gate->type = Gate::NOT;
not_gate->fanins.push_back(gate);
gate->fanouts.push_back(not_gate);
return not_gate;
}
void Circuit::rebuild_atpg_circuit() {
int sz = gates.size();
assert(sz == simulator->gates.size());
for(Gate* gate : rtopo_gates) {
LUTCircuit* Circuit::build_lut_circuit() {
// 对于 PO 直接可以输出 SA0 = value 和 SA1 = NOT(value)
if(gate->isPO) {
Gate* extra_gate0 = new Gate();
extra_gate0->type = Gate::BUF;
extra_gate0->fanins.push_back(gate);
gate->fanouts.push_back(extra_gate0);
extra_gate0->is_extra_gate = 1;
gates.push_back(extra_gate0);
extra_gate0->name = "SA0_" + gate->name;
LUTCircuit* C = new LUTCircuit();
C->C = this;
Gate* extra_gate1 = new Gate();
extra_gate1->type = Gate::NOT;
extra_gate1->fanins.push_back(gate);
gate->fanouts.push_back(extra_gate1);
extra_gate1->is_extra_gate = 1;
gates.push_back(extra_gate1);
extra_gate1->name = "SA1_" + gate->name;
std::unordered_map<Gate*, LUT*> gate2LUT;
// gate->isPO = false;
std::queue<Gate*> q;
std::set<Gate*> done;
for(Gate* gate : gates) {
// assert fanouts >= 2
if(gate->fanouts.size() >= 2 || gate->isPI || (gate->isPO && gate->fanouts.size() == 0)) {
q.push(gate);
done.insert(gate);
gate->stuck_at_gate[0] = extra_gate0;
gate->stuck_at_gate[1] = extra_gate1;
continue;
}
}
while(!q.empty()) {
Gate* gate = q.front();
q.pop();
// create a gate for SA_i
LUT* lut = new LUT(gate, C);
gate2LUT[gate] = lut;
// printf("size: %d lut: %s inputs: ( ", lut->inner_gates.size(), lut->gate->name.c_str());
// for(Gate* in : lut->__gate_fanins) {
// printf("%s ", in->name.c_str());
// }
// printf(") [");
std::vector<Gate*> or_inputs;
// for(Gate* inner : lut->inner_gates) {
// printf("%s ", inner->name.c_str());
// }
// printf("]\n");
for(Gate *out : gate->fanouts) {
for(Gate* in : lut->__gate_fanins) {
if(in->fanouts.size() < 2 && !in->isPI && done.count(in) == 0) {
done.insert(in);
q.push(in);
if(out->is_extra_gate) continue;
// if the fault SA(!out->value) can be detected
Gate* out_detected = new Gate();
out_detected->name = gen_name();
out_detected->is_extra_gate = 1;
out_detected->type = Gate::OR;
out_detected->fanins.push_back(out->stuck_at_gate[0]);
out_detected->fanins.push_back(out->stuck_at_gate[1]);
assert(out->stuck_at_gate[0]);
assert(out->stuck_at_gate[1]);
out->stuck_at_gate[0]->fanouts.push_back(out_detected);
out->stuck_at_gate[1]->fanouts.push_back(out_detected);
gates.push_back(out_detected);
if(out->type == Gate::XOR || out->type == Gate::XNOR || out->type == Gate::NOT || out->type == Gate::BUF || out->type == Gate::LINE) {
or_inputs.push_back(out_detected);
continue;
}
Gate *extra_gate = new Gate();
extra_gate->is_extra_gate = 1;
extra_gate->type = Gate::AND;
extra_gate->name = gen_name();
gates.push_back(extra_gate);
for(Gate *in_of_out : out->fanins) {
if(in_of_out == gate) continue;
if(out->type == Gate::AND || out->type == Gate::NAND) {
in_of_out->fanouts.push_back(extra_gate);
extra_gate->fanins.push_back(in_of_out);
} else if(out->type == Gate::OR || out->type == Gate::NOR) {
Gate* not_gate = create_not_gate(in_of_out);
not_gate->name = gen_name();
gates.push_back(not_gate);
not_gate->fanouts.push_back(extra_gate);
extra_gate->fanins.push_back(not_gate);
} else {
assert(0);
}
}
extra_gate->fanins.push_back(out_detected);
out_detected->fanouts.push_back(extra_gate);
or_inputs.push_back(extra_gate);
}
Gate* or_gate;
if(or_inputs.size() == 1) {
or_gate = or_inputs[0];
} else {
or_gate = new Gate();
gates.push_back(or_gate);
or_gate->name = gen_name();
or_gate->is_extra_gate = 1;
or_gate->type = Gate::OR;
for(Gate* in : or_inputs) {
or_gate->fanins.push_back(in);
in->fanouts.push_back(or_gate);
}
}
C->luts.push_back(lut);
Gate* p_sa0 = new Gate();
gates.push_back(p_sa0);
p_sa0->is_extra_gate = 1;
p_sa0->type = Gate::AND;
p_sa0->fanins.push_back(or_gate);
p_sa0->fanins.push_back(gate);
or_gate->fanouts.push_back(p_sa0);
gate->fanouts.push_back(p_sa0);
Gate* p_sa1 = new Gate();
gates.push_back(p_sa1);
p_sa1->is_extra_gate = 1;
p_sa1->type = Gate::AND;
p_sa1->fanins.push_back(or_gate);
or_gate->fanouts.push_back(p_sa1);
Gate* not_gate = create_not_gate(gate);
not_gate->name = gen_name();
gates.push_back(not_gate);
p_sa1->fanins.push_back(not_gate);
not_gate->fanouts.push_back(p_sa1);
gate->stuck_at_gate[0] = p_sa0;
gate->stuck_at_gate[1] = p_sa1;
p_sa0->name = "SA0_" + gate->name;
p_sa1->name = "SA1_" + gate->name;
}
for(LUT* lut : C->luts) {
// for(Gate* po : POs) {
// po->isPO = false;
// }
// POs.clear();
lut->name = lut->gate->name.c_str();
for(Gate* g : gates) {
if(g->is_extra_gate) continue;
assert(g->stuck_at_gate[0]);
assert(g->stuck_at_gate[1]);
std::sort(lut->inner_gates.begin(), lut->inner_gates.end(), [](Gate* a, Gate* b) {
return a->id < b->id;
});
g->stuck_at_gate[0]->isPO = 1;
g->stuck_at_gate[1]->isPO = 1;
for(Gate* in : lut->__gate_fanins) {
assert(gate2LUT.count(in) > 0);
lut->fanins.push_back(gate2LUT[in]);
gate2LUT[in]->fanouts.push_back(lut);
}
POs.push_back(g->stuck_at_gate[0]);
POs.push_back(g->stuck_at_gate[1]);
if(lut->isPI) {
C->PIs.push_back(lut);
lut->isPI = 1;
}
if(lut->isPO) {
C->POs.push_back(lut);
lut->isPO = 1;
}
init_topo_index();
for(Gate* pi : PIs) {
pi->value = rand() % 2;
}
for(Gate* g : gates) {
g->value = g->cal_value();
}
for(Gate* g : rtopo_gates) {
if(g->is_extra_gate) continue;
g->fault_detected[0] = g->cal_fault_detected(0);
g->fault_detected[1] = g->cal_fault_detected(1);
assert(g->fault_detected[0] == g->stuck_at_gate[0]->value);
assert(g->fault_detected[1] == g->stuck_at_gate[1]->value);
}
for(Gate* g : gates) {
if(g->is_extra_gate) continue;
original_gates.push_back(g);
}
for(int i=0; i<original_gates.size(); i++) {
original_gates[i]->index = i;
simulator->name2gate[original_gates[i]->name]->index = i;
}
std::vector<Gate*> t_POs;
for(Gate* po : POs) {
if(po->is_extra_gate) {
t_POs.push_back(po);
}
}
for(LUT* lut : C->luts) {
C->rtopo_luts.push_back(lut);
}
std::sort(C->luts.begin(), C->luts.end(), [](LUT* a, LUT* b) {
return a->gate->id < b->gate->id;
});
std::sort(C->rtopo_luts.begin(), C->rtopo_luts.end(), [](LUT* a, LUT* b) {
return a->gate->rtopo < b->gate->rtopo;
});
for(LUT* lut : C->luts) {
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;
}
}
for(LUT* lut : C->luts) {
for(int i=0; i<lut->fanins.size(); i++) {
LUT* in = lut->fanins[i];
in->fanouts_with_id.push_back(std::make_pair(lut, i));
}
}
for(LUT* lut : C->luts) {
assert(lut->fanouts.size() == lut->fanouts_with_id.size());
}
return C;
POs = t_POs;
assert(original_gates.size() * 2 == POs.size());
assert(original_gates.size() == sz);
}
void Circuit::insert_lines_for_stem() {
for(int j=0; j<gates.size(); j++) {
@ -184,26 +255,27 @@ void Circuit::insert_lines_for_stem() {
name2gate.insert(std::make_pair(line->name, line));
}
printf(">>>> now: %s\n", g->name.c_str());
// printf(">>>> now: %s\n", g->name.c_str());
printf("outs: [ ");
for(Gate* out :g->fanouts){
printf("%s ", out->name.c_str());
}
printf("]\n");
// 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());
// 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->is_stem = false;
line->fanins.push_back(g);
line->fanouts.push_back(out);
@ -224,72 +296,6 @@ void Circuit::insert_lines_for_stem() {
}
void Circuit::init_avg_dist() {
int *now_dist = new int[gates.size() + 1] { 0 };
int *total_dist = new int[gates.size() + 1] { 0 };
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));
for(Gate* g : gates) {
if(g->isPO) {
now_dist[g->id] = 0;
} else {
now_dist[g->id] = 0x3f3f3f3f;
}
}
// printf(">> po: %s\n", po->name.c_str());
std::queue<Gate*> q;
q.push(po);
while(!q.empty()) {
Gate* u = q.front(); q.pop();
total_dist[u->id] += now_dist[u->id];
total_cnt[u->id] ++;
// printf("now: %s\n", u->name.c_str());
for(Gate* in : u->fanins) {
if(now_dist[u->id] + 1 < now_dist[in->id]) {
now_dist[in->id] = now_dist[u->id] + 1;
q.push(in);
}
}
// printf("dist: %d\n", total_dist[name2gate["G132"]->id]);
}
}
for(Gate* g : gates) {
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);
}
delete [] now_dist;
delete [] total_dist;
delete [] total_cnt;
}
void Circuit::init_topo_index() {
int topo = 1;
std::queue<Gate*> q;
@ -315,6 +321,8 @@ void Circuit::init_topo_index() {
}
}
rtopo_gates.clear();
// 计算反向拓扑序
topo = 1;
std::unordered_map<Gate*, int> outs;
@ -346,6 +354,8 @@ void Circuit::init_topo_index() {
}
}
assert(gates.size() == rtopo_gates.size());
std::sort(gates.begin(), gates.end(), [](Gate* a, Gate* b) {
return a->id < b->id;
});
@ -362,8 +372,14 @@ void Circuit::print() {
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]);
std::string out_name = "unknown";
if(g->name != "") {
out_name = g->name;
}
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, out_name.c_str(), name[g->type]);
for(Gate* in : g->fanins) {
printf("%s ", in->name.c_str());
}
@ -377,76 +393,64 @@ void Circuit::print() {
printf(")\n");
}
double LUTCircuit::check() {
// static bool init = 0;
// static std::unordered_set<Gate*> dt;
printf("checking circuit ...\n");
void Circuit::init_faults() {
double score_value_unsatisfied_cost = 0;
double score_fault_detected_weight = 0;
double score_fault_propagated_weight = 0;
double score_fault_update_cost = 0;
int unsatisfied_lut = 0;
int sz = gates.size();
assert(sz == simulator->gates.size());
for(int i=0; i<sz; i++) {
assert(gates[i]->name == simulator->gates[i]->name);
simulator->gates[i]->ori_gate = gates[i];
gates[i]->sim_gate = simulator->gates[i];
}
for(LUT* lut : luts) {
assert(lut->vsat == (lut->value == lut->cal_value()));
std::vector<TMP_FAULT> faults;
if(!lut->vsat) {
score_value_unsatisfied_cost += lut->vunat_cost;
unsatisfied_lut++;
// printf("vunsat: %s\n", lut->name);
}
for(Gate* g : gates) {
if(lut->uptag) {
score_fault_update_cost += lut->up_cost;
std::string name = g->name;
if(g->is_stem) {
faults.push_back(TMP_FAULT{g, name, 0, 1, 0});
faults.push_back(TMP_FAULT{g, name, 1, 1, 0});
} else {
int t_fd[2], t_fpl[2];
lut->cal_fault_info(t_fd, t_fpl);
assert(t_fd[0] == lut->fd[0]);
assert(t_fd[1] == lut->fd[1]);
assert(t_fpl[0] == lut->fpl[0]);
assert(t_fpl[1] == lut->fpl[1]);
}
int input = 0;
for(int i=0; i<lut->fanins.size(); i++) {
input |= (lut->fanins[i]->value << i);
}
input <<= 1;
input |= lut->value;
if(g->isPO) {
faults.push_back(TMP_FAULT{g, name, 0, g->type != Gate::LINE, g->type == Gate::LINE});
faults.push_back(TMP_FAULT{g, name, 1, g->type != Gate::LINE, g->type == Gate::LINE});
continue;
}
for(int i=lut->fanins.size(); i<lut->fanins.size()+lut->inner_gates.size(); i++) {
LUT::FaultInfo &info = lut->fault_table[i][input];
Gate* g = lut->inner_gates[i-lut->fanins.size()];
int t_fd[2], t_fpl[2];
t_fd[0] = info.fd[0] && lut->fd[!lut->value];
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];
assert(g->fanouts.size() == 1);
score_fault_detected_weight += t_fd[0] * g->fault_detected_weight[0];
score_fault_detected_weight += t_fd[1] * g->fault_detected_weight[1];
Gate *fanout = g->fanouts[0];
if(!g->isPO) {
score_fault_propagated_weight += (double)t_fpl[0] / g->avg_dist * g->fault_detected_weight[0];
score_fault_propagated_weight += (double)t_fpl[1] / g->avg_dist * g->fault_detected_weight[1];
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_back(TMP_FAULT{g, name, 0, stem, 0});
faults.push_back(TMP_FAULT{g, name, 1, stem, 0});
} else if(fanout->type == Gate::Type::NAND || fanout->type == Gate::Type::AND) {
faults.push_back(TMP_FAULT{g, name, 1, stem, 0});
} else if(fanout->type == Gate::Type::NOR || fanout->type == Gate::Type::OR) {
faults.push_back(TMP_FAULT{g, name, 0, stem, 0});
} else {
assert(false);
}
}
}
printf("=====================================\n");
printf("unsat_lut: %d\n", unsatisfied_lut);
printf("score_value_unsatisfied_cost: %.2f\n", score_value_unsatisfied_cost);
printf("score_fault_detected_weight: %.2f\n", score_fault_detected_weight);
printf("score_fault_propagated_weight: %.2f\n", score_fault_propagated_weight);
printf("score_fault_update_cost: %.2f\n", score_fault_update_cost);
double score = - score_value_unsatisfied_cost + score_fault_detected_weight + score_fault_propagated_weight - score_fault_update_cost;
printf("fault-size: %d\n", faults.size());
printf("score: %d\n", score);
for(TMP_FAULT &f : faults) {
mp[Fault{f.g, f.stuck_at}] = f;
this->faults.insert(Fault{f.g, f.stuck_at});
}
return score;
this->unknown_faults = this->faults;
assert(faults.size() == mp.size());
}

68
src/circuit.h Normal file → Executable file
View File

@ -1,44 +1,15 @@
#pragma once
#include "fault.h"
#include "lut.h"
#include <map>
#include <set>
using ll = long long;
namespace atpg_ls {
class Simulator;
class Circuit;
class LUTCircuit {
public:
std::vector<LUT*> PIs;
std::vector<LUT*> POs;
std::vector<LUT*> luts;
std::vector<LUT*> rtopo_luts;
int** fault_detected;
void print();
// local search
void ls_update(std::vector<LUT*> &unsat);
LUT* ls_pick();
void ls_flip(LUT *lut);
void ls_main();
void ls_init();
void ls_random_sol();
void ls_gen_sol(const TMP_FAULT &target);
// checker
double check();
Simulator *simulator;
Circuit *C;
int step;
};
class Circuit {
public:
@ -46,18 +17,45 @@ std::vector<Gate*> PIs;
std::vector<Gate*> POs;
std::vector<Gate*> gates;
std::vector<Gate*> rtopo_gates;
std::vector<Gate*> original_gates;
// std::vector<Gate*> test;
std::unordered_map<std::string, Gate*> name2gate;
void parse_from_file(const char *filename);
void insert_lines_for_stem();
void rebuild_atpg_circuit();
void init_faults();
int cal_circuit_score();
void print();
LUTCircuit* build_lut_circuit();
void init_topo_index();
void init_avg_dist();
// atpg info
std::set<Fault> detected_faults;
std::set<Fault> undetected_faults;
std::set<Fault> unknown_faults;
std::set<Fault> faults;
std::map<Fault, TMP_FAULT> mp;
void ls_update();
Gate* ls_pick();
void ls_flip(Gate *gate);
void ls_main();
void ls_init();
void ls_random_sol();
void ls_gen_sol(const Fault &f);
// checker
double check();
// simulator
Simulator *simulator;
};

0
src/cmdline.h Normal file → Executable file
View File

15
src/fault.h Normal file → Executable file
View File

@ -4,6 +4,21 @@
namespace atpg_ls {
struct Fault {
Gate* gate;
int stuck_at;
friend bool operator < (const Fault &lhs, const Fault &rhs) {
if(lhs.gate != rhs.gate) {
return lhs.gate < rhs.gate;
}
if(lhs.stuck_at != rhs.stuck_at) {
return lhs.stuck_at < rhs.stuck_at;
}
return false;
}
};
struct TMP_FAULT {
/* data */
Gate *g;

2
src/gate.cpp Normal file → Executable file
View File

@ -15,6 +15,7 @@ int Gate::cal_propagate_len(bool x) {
}
for(Gate* out : fanouts) {
if(out->is_extra_gate) continue;
if(!out->is_detected(this)) continue;
fpl[!value] = std::max(fpl[!value], out->fault_propagated_len[!out->value] + 1);
}
@ -45,6 +46,7 @@ bool Gate::cal_fault_detected(bool x) {
for(Gate* out : fanouts) {
if(!out->is_propagated()) continue;
if(out->cal_value() != out->value) continue;
if(out->is_extra_gate) continue;
this->value = !this->value;
bool detect = (out->cal_value() != out->value);

31
src/gate.h Normal file → Executable file
View File

@ -17,9 +17,19 @@ public:
// gate basic info
Gate() {
is_extra_gate = 0;
sim_gate = 0;
ori_gate = 0;
isPI = 0;
isPO = 0;
}
int id;
int level;
int rtopo;
int index;
std::string name;
enum Type { AND, NAND, OR, NOR, XOR, XNOR, NOT, BUF, INPUT, LINE } type;
int value;
@ -28,6 +38,15 @@ public:
std::vector<Gate*> fanouts;
std::vector<Gate*> fanins;
std::vector<Gate*> reigon;
int weight;
bool is_extra_gate;
Gate* stuck_at_gate[2];
int v_sat;
int unsat_cost;
int is_good_var;
int avg_dist;
@ -41,18 +60,24 @@ public:
int cal_value();
int score;
void cal_score();
bool cal_fault_detected(bool x);
bool is_detected(Gate* one_of_input);
int cal_propagate_len(bool x);
LUT* parent_lut;
int id_in_lut;
int is_stem;
void cal_fault_info(int fd[2], int fpl[2]);
int CC;
// for simulate;
Gate* ori_gate;
Gate* sim_gate;
// ( partical ) score

770
src/ls.cpp Normal file → Executable file
View File

@ -12,279 +12,325 @@
using namespace atpg_ls;
LUT* LUTCircuit::ls_pick() {
std::set<Gate*> unjust_gates;
LUT* pick = nullptr;
// 采样
for(int i=0; i<OPT(t); i++) {
LUT* lut = luts[rand() % luts.size()];
if(!lut->CC) continue;
lut->cal_score();
if(lut->score <= 0) continue;
if(pick == nullptr || lut->score > pick->score) {
pick = lut;
// score > 0 && CC = 1;
std::vector<Gate*> good_gates;
int Circuit::cal_circuit_score() {
int score = 0;
for(Gate* g : gates) {
if(g->value == 1) {
score += g->weight;
}
assert(g->v_sat == (g->value == g->cal_value()));
if(!g->v_sat) {
score -= g->unsat_cost;
}
if(g->v_sat) {
assert(unjust_gates.count(g) == 0);
} else {
assert(unjust_gates.count(g));
}
}
if(pick != nullptr) {
return pick;
return score;
}
void Circuit::ls_init() {
unjust_gates.clear();
good_gates.clear();
}
void Circuit::ls_random_sol() {
for(Gate* gate : gates) {
gate->value = rand() % 2;
}
for(Gate* gate : gates) {
gate->v_sat = (gate->value == gate->cal_value());
gate->weight = 0;
gate->CC = 1;
gate->unsat_cost = 1;
gate->is_good_var = 0;
}
std::vector<LUT*> unsat;
for(Fault f : unknown_faults) {
Gate* g_sai = f.gate->stuck_at_gate[f.stuck_at];
assert(g_sai != nullptr);
g_sai->weight = 1;
}
}
// 动态加权
ls_update(unsat);
Gate* Circuit::ls_pick() {
Gate* pick = nullptr;
if(unsat.size() == 0) return nullptr;
if(!good_gates.empty()) {
pick = good_gates[rand() % good_gates.size()];
if(pick->score > 0 && pick->CC) {
return pick;
} else {
std::vector<Gate*> tmp = good_gates;
good_gates.clear();
for(Gate* gate : tmp) {
if(gate->score > 0 && gate->CC == 1) {
good_gates.push_back(gate);
} else {
gate->is_good_var = 0;
}
}
pick = unsat[rand() % unsat.size()];
if(pick->fanins.size() == 0) {
return pick;
if(!good_gates.empty()) {
pick = good_gates[rand() % good_gates.size()];
return pick;
}
}
}
if(rand() % 10000 < 3000) {
return pick->fanins[rand() % pick->fanins.size()];
ls_update();
std::vector<Gate*> uj;
uj.insert(uj.end(), unjust_gates.begin(), unjust_gates.end());
if(!unjust_gates.empty()) {
pick = uj[rand() % uj.size()];
if(rand() % 10000 <= 0.7 * 10000) {
return pick->fanins[rand() % pick->fanins.size()];
} else {
return pick;
}
}
pick = gates[rand() % gates.size()];
return pick;
}
void LUTCircuit::ls_flip(LUT *lut) {
void Circuit::ls_flip(Gate *gate) {
// for(Gate* g : gates) {
// int old = g->score;
// g->cal_score();
// assert(old == g->score);
// }
lut->CC = 0;
lut->uptag = 0;
lut->flip_value();
if(!lut->isPI) lut->vsat = !lut->vsat;
gate->value ^= 1;
gate->CC = 0;
gate->is_good_var = 0;
for(LUT* out : lut->fanouts) {
out->CC = 1;
out->vsat = (out->cal_value() == out->value);
}
if(!gate->isPI) {
lut->cal_fault_info(lut->fd, lut->fpl);
gate->v_sat ^= 1;
assert(gate->v_sat == (gate->value == gate->cal_value()));
// printf("test: %d %d\n", gate->v_sat, (gate->value == gate->cal_value()));
for(LUT* r : lut->reigon) {
r->CC = 1;
int t_fd[2], t_fpl[2];
r->cal_fault_info(t_fd, t_fpl);
if(t_fd[0] != r->fd[0] || t_fd[1] != r->fd[1] || t_fpl[0] != r->fpl[0] || t_fpl[1] != r->fpl[1]) {
r->uptag = 1;
}
}
}
void LUTCircuit::ls_update(std::vector<LUT*> &unsat) {
if(rand() % 10000 <= OPT(sp) * 10000) {
for(LUT* lut : luts) {
if(lut->vsat) {
if(lut->vunat_cost - OPT(vsat_inc) >= 1) {
lut->vunat_cost -= OPT(vsat_inc);
}
}
if(!lut->vsat) {
unsat.push_back(lut);
}
if(!lut->uptag) {
if(lut->up_cost - OPT(up_inc) >= 1) {
lut->up_cost -= OPT(up_inc);
}
}
for(int i=lut->fanins.size(); i<lut->fanins.size()+lut->inner_gates.size(); i++) {
Gate* g = lut->inner_gates[i-lut->fanins.size()];
LUT::FaultInfo &fi = lut->fault_table[i][lut->input_var];
if(fi.fd[0] && g->fault_detected_weight[0] - OPT(fw_inc) >= 1) {
g->fault_detected_weight[0] -= OPT(fw_inc);
}
if(fi.fd[1] && g->fault_detected_weight[1] - OPT(fw_inc) >= 1) {
g->fault_detected_weight[1] -= OPT(fw_inc);
}
if(fi.fd[0] && g->fault_propagated_weight[0] - OPT(fw_inc) >= 1) {
g->fault_propagated_weight[0] -= OPT(fw_inc);
}
if(fi.fd[1] && g->fault_propagated_weight[1] + OPT(fw_inc) >= 1) {
g->fault_propagated_weight[1] -= OPT(fw_inc);
}
}
}
} else {
for(LUT* lut : luts) {
if(!lut->vsat) {
// printf("ocost: %d add: %d\n", lut->vunat_cost);
if(lut->vunat_cost + OPT(vsat_inc) > OPT(vsat_max)) {
lut->vunat_cost = OPT(vsat_max);
} else {
lut->vunat_cost += OPT(vsat_inc);
}
// printf("cost: %d add: %d\n", lut->vunat_cost, OPT(vsat_inc));
// for(LUT* out : lut->fanouts) {
// if(out->vunat_cost -= OPT(vsat_inc) > 1) {
// out->vunat_cost -= OPT(vsat_inc);
// } else {
// out->vunat_cost = 1;
// }
// }
unsat.push_back(lut);
}
if(lut->uptag) {
if(lut->up_cost + OPT(up_inc) > OPT(up_max)) {
lut->up_cost = OPT(up_max);
} else {
lut->up_cost += OPT(up_inc);
}
}
for(int i=lut->fanins.size(); i<lut->fanins.size()+lut->inner_gates.size(); i++) {
Gate* g = lut->inner_gates[i-lut->fanins.size()];
LUT::FaultInfo &fi = lut->fault_table[i][lut->input_var];
if(!fi.fd[0] && g->fault_detected_weight[0] > 0 && g->fault_detected_weight[0] + OPT(fw_inc) <= OPT(fw_max)) {
g->fault_detected_weight[0] += OPT(fw_inc);
}
if(!fi.fd[1] && g->fault_detected_weight[1] > 0 && g->fault_detected_weight[1] + OPT(fw_inc) <= OPT(fw_max)) {
g->fault_detected_weight[1] += OPT(fw_inc);
}
if(!fi.fd[0] && g->fault_propagated_weight[0] > 0 && g->fault_propagated_weight[0] + OPT(fw_inc) <= OPT(fw_max)) {
g->fault_propagated_weight[0] += OPT(fw_inc);
}
if(!fi.fd[1] && g->fault_propagated_weight[0] > 0 && g->fault_propagated_weight[1] + OPT(fw_inc) <= OPT(fw_max)) {
g->fault_propagated_weight[1] += OPT(fw_inc);
}
}
}
}
}
void LUTCircuit::ls_main() {
printf("====== local search start ======\n");
printf("initing lookup table ...\n");
ls_init();
printf("ganerating fault info ...\n");
int num_gates = 0;
int num_total_fault = 0;
int num_detected_fault = 0;
int num_undetected_fault = 0;
int num_pattern = 0;
for(LUT* lut : luts) {
num_gates += lut->inner_gates.size();
}
assert(num_gates == C->gates.size());
fault_detected = new int*[num_gates];
for(int i=0; i<num_gates; i++) {
fault_detected[i] = new int[2];
fault_detected[i][0] = fault_detected[i][1] = 0;
}
num_total_fault = num_undetected_fault = num_gates * 2;
printf("staring local search ...\n");
std::queue<TMP_FAULT> faults;
for(Gate* g : C->gates) {
std::string name = g->name;
if(g->is_stem) {
faults.push(TMP_FAULT{g, name, 0, 1, 0});
faults.push(TMP_FAULT{g, name, 1, 1, 0});
if(gate->v_sat) {
unjust_gates.erase(gate);
} else {
unjust_gates.insert(gate);
}
}
if(g->isPO) {
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;
}
for(Gate* in : gate->fanins) {
in->cal_score();
in->CC = 1;
if(!in->is_good_var && in->score > 0) {
in->is_good_var = 1;
good_gates.push_back(in);
}
}
assert(g->fanouts.size() == 1);
Gate *fanout = g->fanouts[0];
for(Gate* out : gate->fanouts) {
int stem = (!g->isPI) && (g->type != Gate::LINE);
if(out->v_sat && (out->value != out->cal_value())) {
out->v_sat = 0;
unjust_gates.insert(out);
}
if(!out->v_sat && (out->value == out->cal_value())) {
out->v_sat = 1;
unjust_gates.erase(out);
}
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);
out->cal_score();
out->CC = 1;
if(!out->is_good_var && out->score > 0) {
out->is_good_var = 1;
good_gates.push_back(out);
}
for(Gate* in : out->fanins) {
if(in == gate) continue;
in->CC = 1;
in->cal_score();
if(!in->is_good_var && in->score > 0) {
in->is_good_var = 1;
good_gates.push_back(in);
}
}
}
printf("fault-size: %d\n", faults.size());
gate->cal_score();
}
std::vector<TMP_FAULT> t_faults;
std::set<TMP_FAULT> t_verify_set;
void Circuit::ls_update() {
while(!faults.empty()) {
TMP_FAULT f = faults.front();
faults.pop();
std::set<Gate*> reigon;
assert(t_verify_set.count(f) == 0);
for(Gate* g : unjust_gates) {
g->unsat_cost += OPT(vsat_inc);
t_faults.push_back(f);
t_verify_set.insert(f);
for(Gate* in : g->fanins) {
reigon.insert(in);
}
for(Gate* out : g->fanouts) {
reigon.insert(out);
for(Gate* in : out->fanins) {
reigon.insert(in);
}
}
}
std::map<std::pair<std::string, int>, std::pair<int, int>> mp;
for(TMP_FAULT &f : t_faults) {
faults.push(f);
mp[std::make_pair(f.g->name, f.stuck_at)] = std::make_pair(f.is_stem, f.is_PO);
for(Fault f : unknown_faults) {
Gate* g = f.gate->stuck_at_gate[f.stuck_at];
assert(g != nullptr);
g->weight += OPT(fw_inc) * 100;
for(Gate* in : g->fanins) {
reigon.insert(in);
}
for(Gate* out : g->fanouts) {
reigon.insert(out);
for(Gate* in : out->fanins) {
reigon.insert(in);
}
}
}
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(Gate* g : reigon) {
g->cal_score();
if(!g->is_good_var && g->score > 0 && g->CC) {
g->is_good_var = 1;
good_gates.push_back(g);
}
}
}
std::vector<Pattern> patterns;
void Circuit::ls_gen_sol(const Fault &f) {
std::vector<int> best_sol;
int best_score = -1;
simulator->simulate(PIs, best_score, unknown_faults);
for(Gate* gate : PIs) {
best_sol.push_back(gate->value);
}
for(Gate* gate : gates) {
gate->value = gate->cal_value();
gate->v_sat = 1;
gate->CC = 1;
gate->is_good_var = 0;
}
for(Gate* gate : gates) {
gate->cal_score();
if(gate->score > 0) {
gate->is_good_var = 1;
good_gates.push_back(gate);
}
}
for(int step=0; step<OPT(max_step_coeff)*original_gates.size(); step++) {
// assert(unjust_gates.size() == 0);
// printf("step: %d\n", step);
Gate* pick = ls_pick();
// int score1 = cal_circuit_score();
pick->cal_score();
int delta = pick->score;
// printf("flip: %s score: %d\n", pick->name.c_str(), delta);
ls_flip(pick);
// int score2 = cal_circuit_score();
// printf("score: %d %d %d\n", score1, score2, delta);
// assert((score2 - score1) == delta);
if(pick->isPI) {
Pattern p;
for(Gate* gate : PIs) {
p.input_vector.push_back(gate->value);
}
int res = check_fault(p, f);
if(!res) {
ls_flip(pick);
pick->CC = 0;
} else {
printf("succsss-flip-pi: %s\n", pick->name.c_str());
int score;
simulator->simulate(PIs, score, unknown_faults);
if(score > best_score) {
printf("update_best_score: %d\n", best_score);
best_score = score;
best_sol.clear();
for(Gate* gate : PIs) {
p.input_vector.push_back(gate->value);
}
}
}
}
}
// printf("====== test end\n");
// exit(0);
assert(best_score != -1);
for(int i=0; i<PIs.size(); i++) {
PIs[i]->value = best_sol[i];
}
}
void Circuit::ls_main() {
auto start = std::chrono::high_resolution_clock::now();
while(!faults.empty()) {
printf("====== local search start ======\n");
while(!faults.empty()) {
TMP_FAULT f = faults.front();
if(fault_detected[f.g->id-1][f.stuck_at]) {
faults.pop();
} else {
break;
}
}
std::vector<Pattern> patterns;
if(faults.empty()) break;
while(!unknown_faults.empty()) {
Fault f = *unknown_faults.begin(); unknown_faults.erase(unknown_faults.begin());
ls_init();
ls_random_sol();
TMP_FAULT f = faults.front(); faults.pop();
Gate* g = f.g;
Gate* g = f.gate;
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(f, inputs);
std::vector<int> inputs;
int res1 = sat_atpg(mp[f], inputs);
if(res1 == 0) {
printf(" unsat!\n");
undetected_faults.insert(f);
continue;
}
@ -296,295 +342,65 @@ 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");
for(LUT* lut : luts) {
lut->input_var = 0;
for(int i=0; i<lut->fanins.size(); i++) {
LUT* in = lut->fanins[i];
lut->input_var |= (in->value << i);
}
}
ls_gen_sol(f);
int score;
simulator->simulate(PIs, score, fault_detected);
simulator->simulate(PIs, score, unknown_faults);
Pattern pattern;
for(LUT* lut : PIs) {
pattern.input_vector.push_back(lut->value);
for(Gate* g : PIs) {
pattern.input_vector.push_back(g->value);
}
assert(check_fault(pattern, f));
simulator->name2gate[g->name]->fault_detected[stuck_at] = 1;
assert(fault_detected[g->id-1][stuck_at] == 0);
detected_faults.insert(f);
pattern.detected_faults.push_back(f);
int num_fault = 0;
int num_fault = 1;
// check if real detected
for(Gate* g : simulator->gates) {
for(int i=0; i<=1; i++) {
if(g->fault_detected[i] && !fault_detected[g->id-1][i]) {
fault_detected[g->id-1][i] = 1;
std::vector<Fault> remove_faults;
if(mp.count(std::make_pair(g->name, i))) {
auto [is_tem, is_PO] = mp[std::make_pair(g->name, i)];
for(Fault f : unknown_faults) {
TMP_FAULT f = TMP_FAULT{g, g->name, i, is_tem, is_PO};
Gate* gate = f.gate;
int stuck_at = f.stuck_at;
int res = check_fault(pattern, f);
if(!res) {
printf("fault: %s SA%d is not real detected!\n", g->name.c_str(), i);
fault_detected[g->id-1][i] = 0;
} else {
pattern.detected_faults.push_back(f);
}
}
assert(gate->sim_gate != nullptr);
if(fault_detected[g->id-1][i]) {
num_detected_fault++;
num_undetected_fault--;
num_fault++;
}
if(gate->sim_gate->fault_detected[stuck_at]) {
int res = check_fault(pattern, f);
if(!res) {
printf("fault: %s SA%d is not real detected!\n", gate->name.c_str(), stuck_at);
} else {
pattern.detected_faults.push_back(f);
num_fault++;
detected_faults.insert(f);
remove_faults.push_back(f);
}
}
}
patterns.push_back(pattern);
assert(num_fault > 0);
if(num_fault > 0) {
num_pattern++;
for(Fault f : remove_faults) {
unknown_faults.erase(f);
}
patterns.push_back(pattern);
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);
printf("Cover: %.2f%% pattern: %d new_detected: %d undected: %d time: %.2fs\n", (double)detected_faults.size() / faults.size() * 100, patterns.size(), num_fault, unknown_faults.size(), (double)duration/1000);
// break;
}
for(int i=0; i<num_gates; i++) {
if(fault_detected[i][0] == 0) {
printf("undetected: %s SA0\n", simulator->gates[i]->name.c_str());
}
if(fault_detected[i][1] == 0) {
printf("undetected: %s SA1\n", simulator->gates[i]->name.c_str());
}
}
printf("====== local search end ======\n");
final_check(t_verify_set, patterns);
final_check(faults, patterns);
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cout << "Execution time: " << duration << " milliseconds" << std::endl;
}
void LUTCircuit::ls_gen_sol(const TMP_FAULT &target) {
std::vector<int> best_sol;
int best_score = -1;
simulator->simulate(PIs, best_score, fault_detected);
for(LUT* lut : PIs) {
best_sol.push_back(lut->value);
}
for(int step=0; step<OPT(max_step_coeff)*luts.size(); step++) {
// printf("step: %d\n", step);
LUT* pick = ls_pick();
if(pick == nullptr) {
pick = luts[rand() % luts.size()];
}
// pick->cal_score();
// double t1 = check();
// printf(">>>>>>>>>>>>>\n");
// printf("dert_score: %.2f\n", pick->score);
// printf("dert_unsat_cost: %.2f\n", pick->score_value_unsatisfied_cost);
// printf("dert_fault_detected_weight: %.2f\n", pick->score_fault_detected_weight);
// printf("dert_fault_propagated_weight: %.2f\n", pick->score_fault_propagated_weight);
// printf("dert_up_cost: %.2f\n", pick->score_fault_update_cost);
ls_flip(pick);
// double t2 = check();
// assert(((t2 - t1) - pick->score) < 1e-6);
if(pick->isPI) {
// printf("step: %d score: %d\n", step, score);
Pattern p;
for(LUT* lut : PIs) {
p.input_vector.push_back(lut->value);
}
int res = check_fault(p, target);
if(!res) {
ls_flip(pick);
pick->CC = 0;
} else {
int score;
simulator->simulate(PIs, score, fault_detected);
if(score > best_score) {
best_score = score;
best_sol.clear();
for(LUT* lut : PIs) {
best_sol.push_back(lut->value);
}
}
}
}
}
assert(best_score != -1);
for(int i=0; i<PIs.size(); i++) {
PIs[i]->value = best_sol[i];
}
for(LUT* lut : luts) {
lut->input_var = 0;
for(int i=0; i<lut->fanins.size(); i++) {
LUT* in = lut->fanins[i];
lut->input_var |= (in->value << i);
}
lut->value = lut->cal_value();
lut->vsat = 1;
}
for(LUT* lut : rtopo_luts) {
lut->cal_fault_info(lut->fd, lut->fpl);
}
}
void LUTCircuit::ls_init() {
for(LUT* lut : luts) {
static int cnt = 0;
printf("[%d/%d]\n", ++cnt, luts.size());
lut->init_lookup_table();
}
for(LUT* lut : luts) {
for(LUT* out :lut->fanouts) {
for(int i=0; i<out->fanins.size(); i++) {
if(out->fanins[i] == lut) {
lut->fault_info.push_back(out->fault_table[i]);
}
}
}
}
for(LUT* lut : luts) {
std::set<LUT*> t_reigon;
for(LUT* out : lut->fanouts) {
for(LUT* in : out->fanins) {
t_reigon.insert(in);
}
}
for(LUT* in : lut->fanins) {
t_reigon.insert(in);
}
t_reigon.erase(lut);
for(LUT* r : t_reigon) {
lut->reigon.push_back(r);
}
}
for(LUT* lut : luts) {
std::set<LUT*> t_reigon;
for(LUT* r: lut->reigon) {
t_reigon.insert(r);
for(LUT* out2 : r->fanouts) {
t_reigon.insert(out2);
for(LUT* in2 : out2->fanins) {
t_reigon.insert(in2);
}
}
}
for(LUT* r : lut->fanouts) {
t_reigon.insert(r);
}
for(LUT* r : t_reigon) {
lut->update_reigon.push_back(r);
}
}
}
void LUTCircuit::ls_random_sol() {
step = 0;
std::vector<int*> t_focus;
for(LUT* lut : luts) {
lut->up_cost = 1;
lut->vunat_cost = 1;
if(lut->isPI) {
lut->vunat_cost = OPT(vsat_inc) * 100;
}
lut->CC = 1;
for(Gate* g : lut->inner_gates) {
g->fault_detected_weight[0] = !fault_detected[g->id-1][0];
g->fault_detected_weight[1] = !fault_detected[g->id-1][1];
if(g->fault_detected_weight[0]) {
t_focus.push_back(&g->fault_detected_weight[0]);
}
if(g->fault_detected_weight[1]) {
t_focus.push_back(&g->fault_detected_weight[1]);
}
g->fault_propagated_weight[0] = !fault_detected[g->id-1][0];
g->fault_propagated_weight[1] = !fault_detected[g->id-1][1];
}
}
int *tw = t_focus[rand()%t_focus.size()];
*tw = 100000;
for(LUT* lut : luts) {
lut->uptag = 0;
lut->value = rand() % 2;
}
for(LUT* lut : luts) {
lut->input_var = 0;
for(int i=0; i<lut->fanins.size(); i++) {
LUT* in = lut->fanins[i];
lut->input_var |= (in->value << i);
}
}
for(LUT* lut : luts) {
lut->vsat = (lut->value == lut->cal_value());
}
for(LUT* lut : rtopo_luts) {
lut->cal_fault_info(lut->fd, lut->fpl);
}
for(LUT* lut : luts) {
lut->cal_score();
}
}

View File

@ -1,205 +0,0 @@
#include <set>
#include "lut.h"
#include "paras.h"
using namespace atpg_ls;
void LUT::flip_value() {
value ^= 1;
for(auto&[out, id] : fanouts_with_id) {
out->input_var ^= (1 << id);
}
}
void LUT::cal_fault_info(int *fd, int* fpl) {
fd[0] = fd[1] = fpl[0] = fpl[1] = 0;
if(isPO) {
fd[!value] = 1;
fd[value] = 0;
return;
}
for(auto&[out, id] : fanouts_with_id) {
if(!out->vsat) continue;
FaultInfo &info = out->fault_table[id][out->input_var << 1 | out->value];
int t_fd[2], t_fpl[2];
t_fd[0] = info.fd[0] && out->fd[!out->value];
t_fd[1] = info.fd[1] && out->fd[!out->value];
t_fpl[0] = info.fpl[0] + info.fd[0] * out->fpl[!out->value];
t_fpl[1] = info.fpl[1] + info.fd[1] * out->fpl[!out->value];
fd[0] |= t_fd[0];
fd[1] |= t_fd[1];
fpl[0] = std::max(fpl[0], t_fpl[0]);
fpl[1] = std::max(fpl[1], t_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() {
if(isPI) return value;
return value_table[input_var];
}
LUT::LUT(Gate *gate, LUTCircuit *circuit):gate(gate), value(gate->value), name(gate->name.c_str()) {
C = circuit;
isPI = gate->isPI;
isPO = gate->isPO;
inner_gates.push_back(gate);
std::set<Gate*> fanins;
for(Gate* g : gate->fanins) {
fanins.insert(g);
}
while(true) {
std::vector<Gate*> candidates;
for(Gate* fanin : fanins) {
if(fanin->fanouts.size() >= 2) continue;
if(fanin->isPI) continue;
int add = 0;
for(Gate* in : fanin->fanins) {
if(fanins.count(in) == 0) {
add++;
}
}
if(fanins.size() - 1 + add <= OPT(lut)) {
candidates.push_back(fanin);
}
}
if(candidates.size() == 0) break;
Gate* random_gate = candidates[rand()%candidates.size()];
inner_gates.push_back(random_gate);
fanins.erase(random_gate);
for(Gate* in : random_gate->fanins) {
fanins.insert(in);
}
}
for(Gate* in : fanins) {
__gate_fanins.push_back(in);
}
}
void LUT::init_lookup_table() {
value_table = new int[1 << fanins.size()];
fault_table = new FaultInfo *[fanins.size() + inner_gates.size()];
for (int i = 0; i < (fanins.size() + inner_gates.size()); i++) {
fault_table[i] = new FaultInfo[1 << (fanins.size() + 1)];
}
std::unordered_map<Gate*, int> gate2index;
for(int i=0; i<fanins.size(); i++) {
gate2index[fanins[i]->gate] = i;
}
for(int i=0; i<inner_gates.size(); i++) {
gate2index[inner_gates[i]] = i + fanins.size();
}
for (int i = 0; i < (1 << fanins.size()); i++) {
for (int j = 0; j < fanins.size(); j++) {
fanins[j]->gate->value = (i >> j) & 1;
}
for (Gate *g : inner_gates) {
g->value = g->cal_value();
}
assert(inner_gates[inner_gates.size() - 1] == gate);
value_table[i] = gate->value;
for(gate->value=0; gate->value<=1; gate->value++) {
for(auto&[g, index] : gate2index) {
g->fault_detected[0] = g->fault_detected[1] = 0;
g->fault_propagated_len[0] = g->fault_propagated_len[1] = 0;
}
gate->fault_detected[!gate->value] = 1;
gate->fault_detected[gate->value] = 0;
gate->fault_propagated_len[0] = 0;
gate->fault_propagated_len[1] = 0;
std::queue<Gate*> q;
q.push(gate);
while(!q.empty()) {
Gate *now = q.front(); q.pop();
FaultInfo *info = &fault_table[gate2index[now]][(i<<1)|gate->value];
info->fd[0] = now->fault_detected[0];
info->fd[1] = now->fault_detected[1];
info->fpl[0] = now->fault_propagated_len[0];
info->fpl[1] = now->fault_propagated_len[1];
info->value = now->value;
// if(now->name == "new_n22_") {
// printf("Gate: %s value: %d inputs: [ ", now->name.c_str(), now->value);
// for(Gate *in : now->fanins) {
// printf("%s ", in->name.c_str());
// }
// printf("]\n");
// }
for(Gate *in : now->fanins) {
if(gate2index.count(in) == 0) continue;
if(now->is_detected(in)) {
in->fault_detected[!in->value] = std::max(in->fault_detected[!in->value], now->fault_detected[!now->value]);
in->fault_propagated_len[!in->value] = std::max(in->fault_propagated_len[!in->value], now->fault_propagated_len[!now->value] + 1);
}
q.push(in);
}
}
}
}
}

View File

@ -1,78 +0,0 @@
#pragma once
#include "gate.h"
namespace atpg_ls {
class LUTCircuit;
class LUT {
public:
LUT(Gate *gate, LUTCircuit *circuit);
LUTCircuit *C;
Gate *gate;
bool isPI, isPO;
uint32_t input_var;
std::vector<LUT *> fanins;
std::vector<LUT *> fanouts;
std::vector<std::pair<LUT*, int>> fanouts_with_id;
std::vector<LUT *> reigon;
std::vector<LUT *> update_reigon;
std::vector<Gate *> inner_gates;
std::vector<Gate *> __gate_fanins;
std::unordered_map<Gate *, int> input_id;
int &value;
void flip_value();
const char *name;
int *value_table;
struct FaultInfo {
int fd[2];
int fpl[2];
int value;
} **fault_table;
std::vector<FaultInfo *> fault_info;
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 CC;
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
double score;
double score_value_unsatisfied_cost;
double score_fault_detected_weight;
double score_fault_propagated_weight;
double score_fault_update_cost;
void cal_score();
void cal_update();
};
}

26
src/main.cpp Normal file → Executable file
View File

@ -18,19 +18,18 @@ int main(int argc, char *argv[]) {
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->parse_from_file(OPT(instance).c_str());
circuit->insert_lines_for_stem();
circuit->init_topo_index();
circuit->print();
circuit->simulator = simulator;
circuit->init_faults();
circuit->rebuild_atpg_circuit();
init_final_checker();
@ -54,17 +53,16 @@ int main(int argc, char *argv[]) {
// circuit->
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());
printf("PO:\t%ld\n", circuit->POs.size());
printf("Gate:\t%ld\n", circuit->gates.size());
printf("LUT:\t%ld\n", C->luts.size());
printf("PIs:\t%ld\n", circuit->PIs.size());
printf("POs:\t%ld\n", circuit->POs.size());
printf("ori-Gate:\t%ld\n", circuit->original_gates.size());
printf("new-Gate:\t%ld\n", circuit->gates.size());
printf("================================ \n");
C->ls_main();
circuit->ls_main();
return 0;
}

0
src/paras.cpp Normal file → Executable file
View File

0
src/paras.h Normal file → Executable file
View File

0
src/parse.cpp Normal file → Executable file
View File

2
src/pattern.h Normal file → Executable file
View File

@ -10,7 +10,7 @@ class Pattern {
public:
std::vector<int> input_vector;
std::vector<TMP_FAULT> detected_faults;
std::vector<Fault> detected_faults;
};

5
src/sat_atpg.cpp Normal file → Executable file
View File

@ -27,6 +27,7 @@ std::map<TMP_FAULT, Fault> fault_map;
bool sat_atpg(const TMP_FAULT &fal, std::vector<int> &input_vector) {
// printf(">?> Fault: %s stuck-at: %d is_stem: %d is_po: %d\n", fal.name.c_str(), fal.stuck_at, fal.is_stem, fal.is_PO);
assert(fault_map.count(fal) != 0);
Fault f = fault_map[fal];
@ -90,7 +91,7 @@ void sat_atpg_init(const char* file) {
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());
// 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;
@ -105,7 +106,7 @@ void sat_atpg_init(const char* file) {
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());
// 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);

0
src/sat_atpg.h Normal file → Executable file
View File

143
src/score.cpp Normal file → Executable file
View File

@ -1,141 +1,34 @@
#include "lut.h"
#include "circuit.h"
using namespace atpg_ls;
void LUT::cal_score() {
void Gate::cal_score() {
score = 0;
score_value_unsatisfied_cost = 0;
score_fault_detected_weight = 0;
score_fault_propagated_weight = 0;
score_fault_update_cost = 0;
// value = !value;
this->flip_value();
if(uptag) {
score_fault_update_cost -= up_cost;
if(value == 1) {
score -= weight;
} else {
score += weight;
}
// value sat score
if(!isPI) {
if(vsat) score_value_unsatisfied_cost += vunat_cost;
else score_value_unsatisfied_cost -= vunat_cost;
vsat = !vsat;
}
for(LUT* out : fanouts) {
if(!out->vsat && out->cal_value() == out->value) {
score_value_unsatisfied_cost -= out->vunat_cost;
out->vsat = 1;
}
if(out->vsat && out->cal_value() != out->value){
score_value_unsatisfied_cost += out->vunat_cost;
out->vsat = 0;
if(v_sat) {
score -= unsat_cost;
} else {
score += unsat_cost;
}
}
int old_fd[2], old_fpl[2];
old_fd[0] = fd[0];
old_fd[1] = fd[1];
old_fpl[0] = fpl[0];
old_fpl[1] = fpl[1];
value ^= 1;
// fault detected score
cal_fault_info(fd, fpl);
// printf("fd: %d %d %d %d\n", fd[0], fd[1], old_fd[0], old_fd[1]);
for(auto&[out, id] : fanouts_with_id) {
uint32_t in1 = out->input_var, in2 = out->input_var;
in1 ^= (1 << id);
in1 = (in1 << 1) | out->value;
in2 = (in2 << 1) | out->value;
for(int i=out->fanins.size(); i<out->fanins.size()+out->inner_gates.size(); i++) {
Gate* g = out->inner_gates[i-out->fanins.size()];
int t_fd1[2], t_fpl1[2];
int t_fd2[2], t_fpl2[2];
t_fd1[0] = out->fault_table[i][in1].fd[0] && out->fd[!out->value];
t_fd1[1] = out->fault_table[i][in1].fd[1] && out->fd[!out->value];
t_fd2[0] = out->fault_table[i][in2].fd[0] && out->fd[!out->value];
t_fd2[1] = out->fault_table[i][in2].fd[1] && out->fd[!out->value];
t_fpl1[0] = out->fault_table[i][in1].fpl[0] + out->fault_table[i][in1].fd[0] * out->fpl[!out->value];
t_fpl1[1] = out->fault_table[i][in1].fpl[1] + out->fault_table[i][in1].fd[1] * out->fpl[!out->value];
t_fpl2[0] = out->fault_table[i][in2].fpl[0] + out->fault_table[i][in2].fd[0] * out->fpl[!out->value];
t_fpl2[1] = out->fault_table[i][in2].fpl[1] + out->fault_table[i][in2].fd[1] * out->fpl[!out->value];
score_fault_detected_weight += (t_fd2[0] - t_fd1[0]) * g->fault_detected_weight[0];
score_fault_detected_weight += (t_fd2[1] - t_fd1[1]) * g->fault_detected_weight[1];
if(!g->isPO) {
score_fault_propagated_weight += (double)(t_fpl2[0] - t_fpl1[0]) / g->avg_dist * g->fault_detected_weight[0];
score_fault_propagated_weight += (double)(t_fpl2[1] - t_fpl1[1]) / g->avg_dist * g->fault_detected_weight[1];
}
for(Gate* out : fanouts) {
if(out->v_sat && (out->value != out->cal_value())) {
score -= out->unsat_cost;
}
if(!out->v_sat && (out->value == out->cal_value())) {
score += out->unsat_cost;
}
}
int in1 = this->input_var, in2 = this->input_var;
in1 = (in1 << 1) | !value;
in2 = (in2 << 1) | value;
for(int i=fanins.size(); i<fanins.size()+inner_gates.size(); i++) {
Gate* g = inner_gates[i-fanins.size()];
int t_fd1[2], t_fpl1[2];
int t_fd2[2], t_fpl2[2];
t_fd1[0] = fault_table[i][in1].fd[0] && old_fd[value];
t_fd1[1] = fault_table[i][in1].fd[1] && old_fd[value];
t_fd2[0] = fault_table[i][in2].fd[0] && fd[!value];
t_fd2[1] = fault_table[i][in2].fd[1] && fd[!value];
t_fpl1[0] = fault_table[i][in1].fpl[0] + fault_table[i][in1].fd[0] * old_fpl[value];
t_fpl1[1] = fault_table[i][in1].fpl[1] + fault_table[i][in1].fd[1] * old_fpl[value];
t_fpl2[0] = fault_table[i][in2].fpl[0] + fault_table[i][in2].fd[0] * fpl[!value];
t_fpl2[1] = fault_table[i][in2].fpl[1] + fault_table[i][in2].fd[1] * fpl[!value];
score_fault_detected_weight += (t_fd2[0] - t_fd1[0]) * g->fault_detected_weight[0];
score_fault_detected_weight += (t_fd2[1] - t_fd1[1]) * g->fault_detected_weight[1];
if(!g->isPO) {
score_fault_propagated_weight += (double)(t_fpl2[0] - t_fpl1[0]) / g->avg_dist * g->fault_detected_weight[0];
score_fault_propagated_weight += (double)(t_fpl2[1] - t_fpl1[1]) / g->avg_dist * g->fault_detected_weight[1];
}
}
// update cost score
for(LUT* r : reigon) {
int t_fd[2], t_fpl[2];
r->cal_fault_info(t_fd, t_fpl);
if(t_fd[0] == r->fd[0] && t_fd[1] == r->fd[1] && t_fpl[0] == r->fpl[0] && t_fpl[1] == r->fpl[1]) continue;
if(!r->uptag) {
score_fault_update_cost += r->up_cost;
}
}
this->flip_value();
if(!isPI) vsat = !vsat;
fd[0] = old_fd[0];
fd[1] = old_fd[1];
fpl[0] = old_fpl[0];
fpl[1] = old_fpl[1];
for(LUT* out : fanouts) {
out->vsat = ( out->cal_value() == out->value );
}
score = - score_value_unsatisfied_cost + score_fault_detected_weight + score_fault_propagated_weight - score_fault_update_cost;
value ^= 1;
}

94
src/simulator.cpp Normal file → Executable file
View File

@ -2,86 +2,30 @@
using namespace atpg_ls;
int Simulator::verify(LUTCircuit *lut_circuit, int** fault_detected) {
// int Simulator::verify(Circuit *circuit, int** fault_detected) {
// lut_circuit->check();
// // lut_circuit->check();
// for(LUT* lut : lut_circuit->PIs) {
// printf("PI: %s = %d\n", lut->name, lut->value);
// }
// // for(LUT* lut : lut_circuit->PIs) {
// // printf("PI: %s = %d\n", lut->name, lut->value);
// // }
int score;
simulate(lut_circuit->PIs, score, fault_detected);
// int score;
// simulate(circuit->PIs, score, fault_detected);
for(LUT* lut : lut_circuit->luts) {
assert(lut->value == lut->cal_value());
}
// for(Gate* gate : circuit->gates) {
// assert(gate->value == gate->cal_value());
// }
for(LUT* lut : lut_circuit->rtopo_luts) {
lut->cal_fault_info(lut->fd, lut->fpl);
}
// std::unordered_map<int, Gate*> id2gate;
// for(Gate* gate : gates) {
// id2gate[gate->id] = gate;
// }
// lut_circuit->print();
// return 1;
// }
std::unordered_map<int, Gate*> id2gate;
for(Gate* gate : gates) {
id2gate[gate->id] = gate;
}
for(LUT* lut : lut_circuit->luts) {
int input_var = 0;
for(int i=0; i<lut->fanins.size(); i++) {
LUT* l = lut->fanins[i];
input_var |= l->value << i;
}
assert(input_var == lut->input_var);
if(!lut->isPI) assert(lut->value_table[lut->input_var] == lut->value);
// printf(">> LUT: %s\n", lut->name);
// assert(lut->fd[0] == id2gate[lut->gate->id]->fault_detected[0]);
// assert(lut->fd[1] == id2gate[lut->gate->id]->fault_detected[1]);
// assert(lut->fpl[0] == id2gate[lut->gate->id]->fault_propagated_len[0]);
// assert(lut->fpl[1] == id2gate[lut->gate->id]->fault_propagated_len[1]);
for(int i=lut->fanins.size(); i<lut->fanins.size()+lut->inner_gates.size(); i++) {
LUT::FaultInfo &info = lut->fault_table[i][(lut->input_var<<1)|lut->value];
Gate* g = lut->inner_gates[i-lut->fanins.size()];
int t_fd[2], t_fpl[2];
t_fd[0] = info.fd[0] && lut->fd[!lut->value];
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];
Gate* sim_g = id2gate[g->id];
assert(g->name == sim_g->name);
// if(g->name == "new_n32_" || g->name == "new_n33_") {
// printf("Gate: %s value: %d %d\n", g->name.c_str(), info.value, sim_g->value);
// printf("l_fd[0]: %d, l_fd[1]: %d, l_fpl[0]: %d, l_fpl[1]: %d\n", lut->fd[0], lut->fd[1], lut->fpl[0], lut->fpl[1]);
// printf("i_fd[0]: %d, i_fd[1]: %d, i_fpl[0]: %d, i_fpl[1]: %d\n", info.fd[0], info.fd[1], info.fpl[0], info.fpl[1]);
// printf("t_fd[0]: %d, t_fd[1]: %d, t_fpl[0]: %d, t_fpl[1]: %d\n", t_fd[0], t_fd[1], t_fpl[0], t_fpl[1]);
// printf("s_fd[0]: %d, s_fd[1]: %d, s_fpl[0]: %d, s_fpl[1]: %d\n\n", sim_g->fault_detected[0], sim_g->fault_detected[1], sim_g->fault_propagated_len[0], sim_g->fault_propagated_len[1]);
// }
assert(info.value == sim_g->value);
assert(t_fd[0] == sim_g->fault_detected[0]);
assert(t_fd[1] == sim_g->fault_detected[1]);
// assert(t_fpl[0] == sim_g->fault_propagated_len[0]);
// assert(t_fpl[1] == sim_g->fault_propagated_len[1]);
}
}
return 1;
}
void Simulator::simulate(std::vector<LUT*> &inputs, int &score, int** fault_detected) {
void Simulator::simulate(std::vector<Gate*> &inputs, int &score, std::set<Fault> &unknown_faults) {
assert(inputs.size() == this->PIs.size());
@ -103,10 +47,10 @@ void Simulator::simulate(std::vector<LUT*> &inputs, int &score, int** fault_dete
score = 0;
for(auto gate : gates) {
if(gate->fault_detected[0] && !fault_detected[gate->id-1][0]) {
if(gate->fault_detected[0] && unknown_faults.count(Fault{gate->ori_gate, 0})) {
score++;
}
if(gate->fault_detected[1] && !fault_detected[gate->id-1][1]) {
if(gate->fault_detected[1] && unknown_faults.count(Fault{gate->ori_gate, 1})) {
score++;
}
}

4
src/simulator.h Normal file → Executable file
View File

@ -6,8 +6,8 @@ namespace atpg_ls {
class Simulator : public Circuit {
public:
void simulate(std::vector<LUT*> &inputs, int &score, int** fault_detected);
int verify(LUTCircuit *lut_circuit, int** fault_detected);
void simulate(std::vector<Gate*> &inputs, int &score, std::set<Fault> &unknown_faults);
// int verify(Circuit *circuit, int** fault_detected);
};
}

1086
test.txt Executable file

File diff suppressed because it is too large Load Diff